Changeset f3d573c


Ignore:
Timestamp:
Mar 25, 2015 12:10:14 PM (6 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
188bd6d, ac902ba
Parents:
9e18c7e
Message:

i2ptunnel HTTP client: Replace all getBytes() calls
with a Writer or getBytes("UTF-8") for efficiency and to
avoid encoding issues.
Store strings as strings, not bytes.
Catch IOEs to prevent cascading error pages.
Minor cleanups

Location:
apps/i2ptunnel/java/src/net/i2p/i2ptunnel
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java

    r9e18c7e rf3d573c  
    329329                    // only update the stats if we did something
    330330                    double ratio = compressed/expanded;
    331                     _context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio), 0);
    332                     _context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed, 0);
    333                     _context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded, 0);
     331                    _context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio));
     332                    _context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed);
     333                    _context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded);
    334334                }
    335335            }
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java

    r9e18c7e rf3d573c  
    6060    public static final String AUTH_REALM = "I2P SSL Proxy";
    6161
    62     private final static byte[] ERR_BAD_PROTOCOL =
    63         ("HTTP/1.1 405 Bad Method\r\n"+
     62    private final static String ERR_BAD_PROTOCOL =
     63         "HTTP/1.1 405 Bad Method\r\n"+
    6464         "Content-Type: text/html; charset=iso-8859-1\r\n"+
    6565         "Cache-control: no-cache\r\n"+
     
    6767         "<html><body><H1>I2P ERROR: METHOD NOT ALLOWED</H1>"+
    6868         "The request uses a bad protocol. "+
    69          "The Connect Proxy supports CONNECT requests ONLY. Other methods such as GET are not allowed - Maybe you wanted the HTTP Proxy?.<BR>")
    70         .getBytes();
     69         "The Connect Proxy supports CONNECT requests ONLY. Other methods such as GET are not allowed - Maybe you wanted the HTTP Proxy?.<BR>";
    7170   
    72     private final static byte[] ERR_LOCALHOST =
    73         ("HTTP/1.1 403 Access Denied\r\n"+
     71    private final static String ERR_LOCALHOST =
     72         "HTTP/1.1 403 Access Denied\r\n"+
    7473         "Content-Type: text/html; charset=iso-8859-1\r\n"+
    7574         "Cache-control: no-cache\r\n"+
    7675         "\r\n"+
    7776         "<html><body><H1>I2P ERROR: REQUEST DENIED</H1>"+
    78          "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>")
    79         .getBytes();
     77         "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>";
    8078   
    8179    /**
     
    274272            Destination clientDest = _context.namingService().lookup(destination);
    275273            if (clientDest == null) {
    276                 byte[] header;
     274                String header;
    277275                if (usingWWWProxy)
    278276                    header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
     
    290288                data = newRequest.toString().getBytes("ISO-8859-1");
    291289            else
    292                 response = SUCCESS_RESPONSE;
     290                response = SUCCESS_RESPONSE.getBytes("UTF-8");
    293291            OnTimeout onTimeout = new OnTimeout(s, s.getOutputStream(), targetRequest, usingWWWProxy, currentProxy, requestId);
    294292            Thread t = new I2PTunnelRunner(s, i2ps, sockLock, data, response, mySockets, onTimeout);
     
    312310    }
    313311
    314     private static void writeErrorMessage(byte[] errMessage, OutputStream out) throws IOException {
     312    private static void writeErrorMessage(String errMessage, OutputStream out) throws IOException {
    315313        if (out == null)
    316314            return;
    317         out.write(errMessage);
     315        out.write(errMessage.getBytes("UTF-8"));
    318316        writeFooter(out);
    319317    }
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java

    r9e18c7e rf3d573c  
    44package net.i2p.i2ptunnel;
    55
     6import java.io.BufferedWriter;
    67import java.io.IOException;
    78import java.io.InputStream;
    89import java.io.OutputStream;
     10import java.io.OutputStreamWriter;
     11import java.io.Writer;
    912import java.net.Socket;
    1013import java.net.SocketException;
     
    8588     *  These are backups if the xxx.ht error page is missing.
    8689     */
    87     private final static byte[] ERR_REQUEST_DENIED =
    88                                 ("HTTP/1.1 403 Access Denied\r\n" +
     90    private final static String ERR_REQUEST_DENIED =
     91            "HTTP/1.1 403 Access Denied\r\n" +
    8992            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    9093            "Cache-control: no-cache\r\n" +
    9194            "\r\n" +
    9295            "<html><body><H1>I2P ERROR: REQUEST DENIED</H1>" +
    93             "You attempted to connect to a non-I2P website or location.<BR>").getBytes();
     96            "You attempted to connect to a non-I2P website or location.<BR>";
    9497
    9598    /*****
     
    106109    .getBytes();
    107110     *****/
    108     private final static byte[] ERR_NO_OUTPROXY =
    109                                 ("HTTP/1.1 503 Service Unavailable\r\n" +
     111    private final static String ERR_NO_OUTPROXY =
     112            "HTTP/1.1 503 Service Unavailable\r\n" +
    110113            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    111114            "Cache-control: no-cache\r\n" +
     
    113116            "<html><body><H1>I2P ERROR: No outproxy found</H1>" +
    114117            "Your request was for a site outside of I2P, but you have no " +
    115             "HTTP outproxy configured.  Please configure an outproxy in I2PTunnel").getBytes();
    116 
    117     private final static byte[] ERR_AHELPER_CONFLICT =
    118                                 ("HTTP/1.1 409 Conflict\r\n" +
     118            "HTTP outproxy configured.  Please configure an outproxy in I2PTunnel";
     119
     120    private final static String ERR_AHELPER_CONFLICT =
     121            "HTTP/1.1 409 Conflict\r\n" +
    119122            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    120123            "Cache-control: no-cache\r\n" +
     
    128131            "and either discarding the addresshelper link, " +
    129132            "discarding the host entry from your host database, " +
    130             "or naming one of them differently.<p>").getBytes();
    131 
    132     private final static byte[] ERR_AHELPER_NOTFOUND =
    133                                 ("HTTP/1.1 404 Not Found\r\n" +
     133            "or naming one of them differently.<p>";
     134
     135    private final static String ERR_AHELPER_NOTFOUND =
     136            "HTTP/1.1 404 Not Found\r\n" +
    134137            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    135138            "Cache-control: no-cache\r\n" +
     
    138141            "The helper key you put for i2paddresshelper= is not resolvable. " +
    139142            "It seems to be garbage data, or a mistyped b32. Check your URL " +
    140             "to try and fix the helper key to be either a b32 or a base64.").getBytes();
    141 
    142     private final static byte[] ERR_AHELPER_NEW =
    143                                 ("HTTP/1.1 409 New Address\r\n" +
     143            "to try and fix the helper key to be either a b32 or a base64.";
     144
     145    private final static String ERR_AHELPER_NEW =
     146            "HTTP/1.1 409 New Address\r\n" +
    144147            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    145148            "Cache-control: no-cache\r\n" +
     
    149152            "You may either save the destination for this host name to your address book, or remember it only until your router restarts. " +
    150153            "If you save it to your address book, you will not see this message again. " +
    151             "If you do not wish to visit this host, click the \"back\" button on your browser.").getBytes();
    152 
    153     private final static byte[] ERR_BAD_PROTOCOL =
    154                                 ("HTTP/1.1 403 Bad Protocol\r\n" +
     154            "If you do not wish to visit this host, click the \"back\" button on your browser.";
     155
     156    private final static String ERR_BAD_PROTOCOL =
     157            "HTTP/1.1 403 Bad Protocol\r\n" +
    155158            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    156159            "Cache-control: no-cache\r\n" +
     
    158161            "<html><body><H1>I2P ERROR: NON-HTTP PROTOCOL</H1>" +
    159162            "The request uses a bad protocol. " +
    160             "The I2P HTTP Proxy supports HTTP and HTTPS requests only. Other protocols such as FTP are not allowed.<BR>").getBytes();
    161 
    162     private final static byte[] ERR_BAD_URI =
    163                                 ("HTTP/1.1 403 Bad URI\r\n" +
     163            "The I2P HTTP Proxy supports HTTP and HTTPS requests only. Other protocols such as FTP are not allowed.<BR>";
     164
     165    private final static String ERR_BAD_URI =
     166            "HTTP/1.1 403 Bad URI\r\n" +
    164167            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    165168            "Cache-control: no-cache\r\n" +
     
    167170            "<html><body><H1>I2P ERROR: INVALID REQUEST URI</H1>" +
    168171            "The request URI is invalid, and probably contains illegal characters. " +
    169             "If you clicked e.g. a forum link, check the end of the URI for any characters the browser has mistakenly added on.<BR>").getBytes();
    170 
    171     private final static byte[] ERR_LOCALHOST =
    172                                 ("HTTP/1.1 403 Access Denied\r\n" +
     172            "If you clicked e.g. a forum link, check the end of the URI for any characters the browser has mistakenly added on.<BR>";
     173
     174    private final static String ERR_LOCALHOST =
     175            "HTTP/1.1 403 Access Denied\r\n" +
    173176            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    174177            "Cache-control: no-cache\r\n" +
    175178            "\r\n" +
    176179            "<html><body><H1>I2P ERROR: REQUEST DENIED</H1>" +
    177             "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>").getBytes();
    178 
    179     private final static byte[] ERR_INTERNAL_SSL =
    180                                 ("HTTP/1.1 403 SSL Rejected\r\n" +
     180            "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>";
     181
     182    private final static String ERR_INTERNAL_SSL =
     183            "HTTP/1.1 403 SSL Rejected\r\n" +
    181184            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    182185            "Cache-control: no-cache\r\n" +
     
    184187            "<html><body><H1>I2P ERROR: SSL to I2P address rejected</H1>" +
    185188            "SSL for to .i2p addresses denied by configuration." +
    186             "You may change the configuration in I2PTunnel").getBytes();
     189            "You may change the configuration in I2PTunnel";
    187190
    188191    /**
     
    465468                            _log.warn(getPrefix(requestId) + "Bad request [" + request + "]", use);
    466469                        }
    467                         out.write(getErrorPage("baduri", ERR_BAD_URI));
    468                         writeFooter(out);
    469                         reader.drain();
    470                         s.close();
     470                        try {
     471                            out.write(getErrorPage("baduri", ERR_BAD_URI).getBytes("UTF-8"));
     472                            writeFooter(out);
     473                            reader.drain();
     474                        } catch (IOException ioe) {
     475                            // ignore
     476                        } finally {
     477                            closeSocket(s);
     478                        }
    471479                        return;
    472480                    }
     
    597605                                                _log.warn(getPrefix(requestId) + "Could not find destination for " + ahelperKey);
    598606                                            }
    599                                             byte[] header = getErrorPage("ahelper-notfound", ERR_AHELPER_NOTFOUND);
    600                                             out.write(header);
    601                                             out.write(("<p>" + _("This seems to be a bad destination:") + " " + ahelperKey + " " + _("i2paddresshelper cannot help you with a destination like that!") + "</p>").getBytes("UTF-8"));
    602                                             writeFooter(out);
    603                                             // XXX: should closeSocket(s) be in a finally block?
    604                                             closeSocket(s);
     607                                            String header = getErrorPage("ahelper-notfound", ERR_AHELPER_NOTFOUND);
     608                                            try {
     609                                                out.write(header.getBytes("UTF-8"));
     610                                                out.write(("<p>" + _("This seems to be a bad destination:") + " " + ahelperKey + " " +
     611                                                           _("i2paddresshelper cannot help you with a destination like that!") +
     612                                                           "</p>").getBytes("UTF-8"));
     613                                                writeFooter(out);
     614                                                // XXX: should closeSocket(s) be in a finally block?
     615                                            } catch (IOException ioe) {
     616                                                // ignore
     617                                            } finally {
     618                                                closeSocket(s);
     619                                            }
    605620                                            return;
    606621                                        }
     
    646661                            // Did addresshelper key conflict?
    647662                            if(ahelperConflict) {
     663                               try {
    648664                                    // convert ahelperKey to b32
    649665                                    String alias = getHostName(ahelperKey);
    650666                                    if(alias.equals("i2p")) {
    651667                                        // bad ahelperKey
    652                                         byte[] header = getErrorPage("dnfb", ERR_DESTINATION_UNKNOWN);
     668                                        String header = getErrorPage("dnfb", ERR_DESTINATION_UNKNOWN);
    653669                                        writeErrorMessage(header, out, targetRequest, false, destination);
    654670                                    } else {
     
    664680                                        }
    665681                                        String conflictURL = conflictURI.toASCIIString();
    666                                         byte[] header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
    667                                         out.write(header);
    668                                         out.write(_("To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, click <a href=\"{1}\">here</a>.", trustedURL, conflictURL).getBytes("UTF-8"));
    669                                         out.write(("</p></div>").getBytes());
     682                                        String header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
     683                                        out.write(header.getBytes("UTF-8"));
     684                                        out.write(_("To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, click <a href=\"{1}\">here</a>.",
     685                                                    trustedURL, conflictURL).getBytes("UTF-8"));
     686                                        out.write("</p></div>".getBytes("UTF-8"));
    670687                                        writeFooter(out);
     688                                    }
     689                                    reader.drain();
     690                                } catch (IOException ioe) {
     691                                    // ignore
     692                                } finally {
     693                                    closeSocket(s);
    671694                                }
    672                                 reader.drain();
    673                                 s.close();
    674695                                return;
    675696                            }
     
    701722                            host.startsWith("192.168.") || host.equals("[::1]")) {
    702723                        // if somebody is trying to get to 192.168.example.com, oh well
    703                         out.write(getErrorPage("localhost", ERR_LOCALHOST));
    704                         writeFooter(out);
    705                         reader.drain();
    706                         s.close();
     724                        try {
     725                            out.write(getErrorPage("localhost", ERR_LOCALHOST).getBytes("UTF-8"));
     726                            writeFooter(out);
     727                            reader.drain();
     728                            s.close();
     729                        } catch (IOException ioe) {
     730                            // ignore
     731                        } finally {
     732                            closeSocket(s);
     733                        }
    707734                        return;
    708735                    } else if(host.contains(".") || host.startsWith("[")) {
     
    749776                                }
    750777                                l.log("No outproxy found for the request.");
    751                                 out.write(getErrorPage("noproxy", ERR_NO_OUTPROXY));
    752                                 writeFooter(out);
    753                                 reader.drain();
    754                                 s.close();
     778                                try {
     779                                    out.write(getErrorPage("noproxy", ERR_NO_OUTPROXY).getBytes("UTF-8"));
     780                                    writeFooter(out);
     781                                    reader.drain();
     782                                } catch (IOException ioe) {
     783                                    // ignore
     784                                } finally {
     785                                    closeSocket(s);
     786                                }
    755787                                return;
    756788                            }
     
    770802                            _log.warn("NODOTS, NOI2P: " + request);
    771803                        }
    772                         out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
    773                         writeFooter(out);
    774                         reader.drain();
    775                         s.close();
     804                        try {
     805                            out.write(getErrorPage("denied", ERR_REQUEST_DENIED).getBytes("UTF-8"));
     806                            writeFooter(out);
     807                            reader.drain();
     808                        } catch (IOException ioe) {
     809                            // ignore
     810                        } finally {
     811                            closeSocket(s);
     812                        }
    776813                        return;
    777814                    }   // end host name processing
     
    899936                        }
    900937                        if(user != null && pw != null) {
    901                             newRequest.append("Proxy-Authorization: Basic ").append(Base64.encode((user + ':' + pw).getBytes(), true)) // true = use standard alphabet
     938                            newRequest.append("Proxy-Authorization: Basic ")
     939                                    .append(Base64.encode((user + ':' + pw).getBytes("UTF-8"), true)) // true = use standard alphabet
    902940                                    .append("\r\n");
    903941                        }
     
    916954            if(method == null || (destination == null && !usingInternalOutproxy)) {
    917955                //l.log("No HTTP method found in the request.");
    918                 if (protocol != null && "http".equals(protocol.toLowerCase(Locale.US))) {
    919                     out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
    920                 } else {
    921                     out.write(getErrorPage("protocol", ERR_BAD_PROTOCOL));
    922                 }
    923                 writeFooter(out);
    924                 s.close();
     956                try {
     957                    if (protocol != null && "http".equals(protocol.toLowerCase(Locale.US))) {
     958                        out.write(getErrorPage("denied", ERR_REQUEST_DENIED).getBytes("UTF-8"));
     959                    } else {
     960                        out.write(getErrorPage("protocol", ERR_BAD_PROTOCOL).getBytes("UTF-8"));
     961                    }
     962                    writeFooter(out);
     963                } catch (IOException ioe) {
     964                    // ignore
     965                } finally {
     966                    closeSocket(s);
     967                }
    925968                return;
    926969            }
     
    940983                    }
    941984                }
    942                 out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes());
    943                 writeFooter(out);
    944                 s.close();
     985                try {
     986                    out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes("UTF-8"));
     987                    writeFooter(out);
     988                } catch (IOException ioe) {
     989                    // ignore
     990                } finally {
     991                    closeSocket(s);
     992                }
    945993                return;
    946994            }
     
    948996            // Serve local proxy files (images, css linked from error pages)
    949997            // Ignore all the headers
    950             if(usingInternalServer) {
    951                 // disable the add form if address helper is disabled
    952                 if(internalPath.equals("/add") &&
    953                         Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_DISABLE_HELPER))) {
    954                     out.write(ERR_HELPER_DISABLED);
    955                 } else {
    956                     LocalHTTPServer.serveLocalFile(out, method, internalPath, internalRawQuery, _proxyNonce);
    957                 }
    958                 s.close();
     998            if (usingInternalServer) {
     999                try {
     1000                    // disable the add form if address helper is disabled
     1001                    if(internalPath.equals("/add") &&
     1002                            Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_DISABLE_HELPER))) {
     1003                        out.write(ERR_HELPER_DISABLED.getBytes("UTF-8"));
     1004                    } else {
     1005                        LocalHTTPServer.serveLocalFile(out, method, internalPath, internalRawQuery, _proxyNonce);
     1006                    }
     1007                } catch (IOException ioe) {
     1008                    // ignore
     1009                } finally {
     1010                    closeSocket(s);
     1011                }
    9591012                return;
    9601013            }
     
    9681021                if (method.toUpperCase(Locale.US).equals("CONNECT")) {
    9691022                    data = null;
    970                     response = SUCCESS_RESPONSE;
     1023                    response = SUCCESS_RESPONSE.getBytes("UTF-8");
    9711024                } else {
    9721025                    data = newRequest.toString().getBytes("ISO-8859-1");
     
    9941047                        _log.warn(getPrefix(requestId) + "Could not find destination for " + addressHelper);
    9951048                    }
    996                     byte[] header = getErrorPage("ahelper-notfound", ERR_AHELPER_NOTFOUND);
    997                     writeErrorMessage(header, out, targetRequest, false, destination);
    998                     s.close();
     1049                    String header = getErrorPage("ahelper-notfound", ERR_AHELPER_NOTFOUND);
     1050                    try {
     1051                        writeErrorMessage(header, out, targetRequest, false, destination);
     1052                    } catch (IOException ioe) {
     1053                        // ignore
     1054                    } finally {
     1055                        closeSocket(s);
     1056                    }
    9991057                    return;
    10001058                }
     
    10261084                    _log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
    10271085                }
    1028                 byte[] header;
     1086                String header;
    10291087                String jumpServers = null;
    10301088                String extraMessage = null;
     
    10431101                    }
    10441102                }
    1045                 writeErrorMessage(header, extraMessage, out, targetRequest, usingWWWProxy, destination, jumpServers);
    1046                 s.close();
     1103                try {
     1104                    writeErrorMessage(header, extraMessage, out, targetRequest, usingWWWProxy, destination, jumpServers);
     1105                } catch (IOException ioe) {
     1106                    // ignore
     1107                } finally {
     1108                    closeSocket(s);
     1109                }
    10471110                return;
    10481111            }
     
    10511114                !usingWWWProxy &&
    10521115                !Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_INTERNAL_SSL))) {
    1053                 writeErrorMessage(ERR_INTERNAL_SSL, out, targetRequest, false, destination);
    1054                 s.close();
     1116                try {
     1117                    writeErrorMessage(ERR_INTERNAL_SSL, out, targetRequest, false, destination);
     1118                } catch (IOException ioe) {
     1119                    // ignore
     1120                } finally {
     1121                    closeSocket(s);
     1122                }
    10551123                if (_log.shouldLog(Log.WARN))
    10561124                    _log.warn("SSL to i2p destinations denied by configuration: " + targetRequest);
     
    10641132                    (userAgent == null || !userAgent.startsWith("Wget")) &&
    10651133                    !Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_DISABLE_HELPER))) {
    1066                 writeHelperSaveForm(out, destination, ahelperKey, targetRequest, referer);
    1067                 s.close();
     1134                try {
     1135                    writeHelperSaveForm(out, destination, ahelperKey, targetRequest, referer);
     1136                } catch (IOException ioe) {
     1137                    // ignore
     1138                } finally {
     1139                    closeSocket(s);
     1140                }
    10681141                return;
    10691142            }
     
    10781151                    _log.debug("Auto redirecting to " + uri);
    10791152                }
    1080                 out.write(("HTTP/1.1 301 Address Helper Accepted\r\n" +
     1153                try {
     1154                    out.write(("HTTP/1.1 301 Address Helper Accepted\r\n" +
    10811155                        "Location: " + uri + "\r\n" +
    10821156                        "\r\n").getBytes("UTF-8"));
    1083                 s.close();
     1157                } catch (IOException ioe) {
     1158                    // ignore
     1159                } finally {
     1160                    closeSocket(s);
     1161                }
    10841162                return;
    10851163            }
     
    11041182                } else {
    11051183                    data = null;
    1106                     response = SUCCESS_RESPONSE;
     1184                    response = SUCCESS_RESPONSE.getBytes("UTF-8");
    11071185                }
    11081186                t = new I2PTunnelRunner(s, i2ps, sockLock, data, response, mySockets, onTimeout);
     
    11581236
    11591237    /** @since 0.8.7 */
    1160     private void writeHelperSaveForm(OutputStream out, String destination, String ahelperKey,
     1238    private void writeHelperSaveForm(OutputStream outs, String destination, String ahelperKey,
    11611239                                     String targetRequest, String referer) throws IOException {
    1162         if(out == null) {
     1240        if(outs == null)
    11631241            return;
    1164         }
    1165         byte[] header = getErrorPage("ahelper-new", ERR_AHELPER_NEW);
     1242        Writer out = new BufferedWriter(new OutputStreamWriter(outs, "UTF-8"));
     1243        String header = getErrorPage("ahelper-new", ERR_AHELPER_NEW);
    11661244        out.write(header);
    1167         out.write(("<table><tr><td class=\"mediumtags\" align=\"right\">" + _("Host") +
    1168                 "</td><td class=\"mediumtags\">" + destination + "</td></tr>\n").getBytes());
     1245        out.write("<table><tr><td class=\"mediumtags\" align=\"right\">" + _("Host") +
     1246                "</td><td class=\"mediumtags\">" + destination + "</td></tr>\n");
    11691247        try {
    11701248            String b32 = Base32.encode(SHA256Generator.getInstance().calculateHash(Base64.decode(ahelperKey)).getData());
    1171             out.write(("<tr><td class=\"mediumtags\" align=\"right\">" + _("Base 32") + "</td>" +
    1172                     "<td><a href=\"http://" + b32 + ".b32.i2p/\">" + b32 + ".b32.i2p</a></td></tr>").getBytes());
     1249            out.write("<tr><td class=\"mediumtags\" align=\"right\">" + _("Base 32") + "</td>" +
     1250                    "<td><a href=\"http://" + b32 + ".b32.i2p/\">" + b32 + ".b32.i2p</a></td></tr>");
    11731251        } catch(Exception e) {
    11741252        }
    1175         out.write(("<tr><td class=\"mediumtags\" align=\"right\">" + _("Destination") + "</td><td>" +
     1253        out.write("<tr><td class=\"mediumtags\" align=\"right\">" + _("Destination") + "</td><td>" +
    11761254                "<textarea rows=\"1\" style=\"height: 4em; min-width: 0; min-height: 0;\" cols=\"70\" wrap=\"off\" readonly=\"readonly\" >" +
    11771255                ahelperKey + "</textarea></td></tr></table>\n" +
     
    11841262                "<input type=\"hidden\" name=\"dest\" value=\"" + ahelperKey + "\">\n" +
    11851263                "<input type=\"hidden\" name=\"nonce\" value=\"" + _proxyNonce + "\">\n" +
    1186                 "<button type=\"submit\" class=\"accept\" name=\"router\" value=\"router\">" + _("Save {0} to router address book and continue to website", destination) + "</button><br>\n").getBytes("UTF-8"));
     1264                "<button type=\"submit\" class=\"accept\" name=\"router\" value=\"router\">" +
     1265                _("Save {0} to router address book and continue to website", destination) + "</button><br>\n");
    11871266        if(_context.namingService().getName().equals("BlockfileNamingService")) {
    11881267            // only blockfile supports multiple books
    1189             out.write(("<br><button type=\"submit\" name=\"master\" value=\"master\">" + _("Save {0} to master address book and continue to website", destination) + "</button><br>\n").getBytes("UTF-8"));
    1190             out.write(("<button type=\"submit\" name=\"private\" value=\"private\">" + _("Save {0} to private address book and continue to website", destination) + "</button>\n").getBytes("UTF-8"));
     1268            out.write("<br><button type=\"submit\" name=\"master\" value=\"master\">" + _("Save {0} to master address book and continue to website", destination) + "</button><br>\n");
     1269            out.write("<button type=\"submit\" name=\"private\" value=\"private\">" + _("Save {0} to private address book and continue to website", destination) + "</button>\n");
    11911270        }
    11921271        // Firefox (and others?) don't send referer to meta refresh target, which is
    11931272        // what the jump servers use, so this isn't that useful.
    11941273        if (referer != null)
    1195             out.write(("<input type=\"hidden\" name=\"referer\" value=\"" + referer + "\">\n").getBytes("UTF-8"));
    1196         out.write(("<input type=\"hidden\" name=\"url\" value=\"" + targetRequest + "\">\n" +
    1197                 "</form></div></div>").getBytes());
     1274            out.write("<input type=\"hidden\" name=\"referer\" value=\"" + referer + "\">\n");
     1275        out.write("<input type=\"hidden\" name=\"url\" value=\"" + targetRequest + "\">\n" +
     1276                "</form></div></div>");
    11981277        writeFooter(out);
    11991278    }
     
    12971376    }
    12981377
    1299     private final static byte[] ERR_HELPER_DISABLED =
    1300                                 ("HTTP/1.1 403 Disabled\r\n" +
     1378    private final static String ERR_HELPER_DISABLED =
     1379            "HTTP/1.1 403 Disabled\r\n" +
    13011380            "Content-Type: text/plain\r\n" +
    13021381            "\r\n" +
    1303             "Address helpers disabled").getBytes();
     1382            "Address helpers disabled";
    13041383
    13051384    /**
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java

    r9e18c7e rf3d573c  
    44package net.i2p.i2ptunnel;
    55
     6import java.io.BufferedWriter;
    67import java.io.File;
    78import java.io.FileInputStream;
    89import java.io.IOException;
    910import java.io.OutputStream;
     11import java.io.OutputStreamWriter;
    1012import java.io.Reader;
    1113import java.io.UnsupportedEncodingException;
     14import java.io.Writer;
    1215import java.net.Socket;
    1316import java.net.URI;
     
    7275    protected final List<String> _proxyList;
    7376
    74     protected final static byte[] ERR_NO_OUTPROXY =
    75         ("HTTP/1.1 503 Service Unavailable\r\n"+
     77    protected final static String ERR_NO_OUTPROXY =
     78         "HTTP/1.1 503 Service Unavailable\r\n"+
    7679         "Content-Type: text/html; charset=iso-8859-1\r\n"+
    7780         "Cache-control: no-cache\r\n"+
     
    7982         "<html><body><H1>I2P ERROR: No outproxy found</H1>"+
    8083         "Your request was for a site outside of I2P, but you have no "+
    81          "HTTP outproxy configured.  Please configure an outproxy in I2PTunnel")
    82          .getBytes();
     84         "HTTP outproxy configured.  Please configure an outproxy in I2PTunnel";
    8385   
    84     protected final static byte[] ERR_DESTINATION_UNKNOWN =
    85                                 ("HTTP/1.1 503 Service Unavailable\r\n" +
     86    protected final static String ERR_DESTINATION_UNKNOWN =
     87            "HTTP/1.1 503 Service Unavailable\r\n" +
    8688            "Content-Type: text/html; charset=iso-8859-1\r\n" +
    8789            "Cache-control: no-cache\r\n" +
     
    9294            "bad. The host (or the WWW proxy, if you're using one) could also " +
    9395            "be temporarily offline.  You may want to <b>retry</b>.  " +
    94             "Could not find the following Destination:<BR><BR><div>").getBytes();
    95 
    96     protected final static byte[] SUCCESS_RESPONSE =
    97         ("HTTP/1.1 200 Connection Established\r\n"+
     96            "Could not find the following Destination:<BR><BR><div>";
     97
     98    protected final static String SUCCESS_RESPONSE =
     99        "HTTP/1.1 200 Connection Established\r\n"+
    98100         "Proxy-agent: I2P\r\n"+
    99          "\r\n")
    100         .getBytes();
     101         "\r\n";
    101102
    102103    private final byte[] _proxyNonce;
     
    485486     *  @since 0.9.4 moved from I2PTunnelHTTPClient
    486487     */
    487     protected byte[] getErrorPage(String base, byte[] backup) {
     488    protected String getErrorPage(String base, String backup) {
    488489        return getErrorPage(_context, base, backup);
    489490    }
     
    500501     *  @since 0.9.4 moved from I2PTunnelHTTPClient
    501502     */
    502     protected static byte[] getErrorPage(I2PAppContext ctx, String base, byte[] backup) {
     503    protected static String getErrorPage(I2PAppContext ctx, String base, String backup) {
    503504        File errorDir = new File(ctx.getBaseDir(), "docs");
    504505        File file = new File(errorDir, base + "-header.ht");
     
    516517     *  @since 0.9.4 moved from I2PTunnelHTTPClient
    517518     */
    518     private static byte[] readFile(I2PAppContext ctx, File file) throws IOException {
     519    private static String readFile(I2PAppContext ctx, File file) throws IOException {
    519520        Reader reader = null;
    520521        char[] buf = new char[512];
     
    526527                out.append(buf, 0, len);
    527528            }
    528             return out.toString().getBytes("UTF-8");
     529            return out.toString();
    529530        } finally {
    530531            try {
     
    579580        if (out == null)
    580581            return;
    581         byte[] header;
     582        String header;
    582583        if (usingWWWProxy)
    583584            header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
     
    613614            error = usingWWWProxy ? "dnfp" : "dnf";
    614615        }
    615         byte[] header = getErrorPage(error, ERR_DESTINATION_UNKNOWN);
     616        String header = getErrorPage(error, ERR_DESTINATION_UNKNOWN);
    616617        String message = ise != null ? ise.getLocalizedMessage() : "unknown error";
    617618        try {
     
    624625     *  @since 0.9.14
    625626     */
    626     protected void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
     627    protected void writeErrorMessage(String errMessage, OutputStream out, String targetRequest,
    627628                                     boolean usingWWWProxy, String wwwProxy) throws IOException {
    628629        writeErrorMessage(errMessage, null, out, targetRequest, usingWWWProxy, wwwProxy, null);
     
    634635     *  @since 0.9.14 moved from subclasses
    635636     */
    636     protected void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
     637    protected void writeErrorMessage(String errMessage, OutputStream out, String targetRequest,
    637638                                     boolean usingWWWProxy, String wwwProxy, String jumpServers) throws IOException {
    638639        writeErrorMessage(errMessage, null, out, targetRequest, usingWWWProxy, wwwProxy, jumpServers);
     
    644645     *  @since 0.9.14
    645646     */
    646     protected void writeErrorMessage(byte[] errMessage, String extraMessage,
     647    protected void writeErrorMessage(String errMessage, String extraMessage,
    647648                                     OutputStream out, String targetRequest,
    648649                                     boolean usingWWWProxy, String wwwProxy) throws IOException {
     
    655656     *  @since 0.9.14
    656657     */
    657     protected void writeErrorMessage(byte[] errMessage, String extraMessage,
    658                                      OutputStream out, String targetRequest,
     658    protected void writeErrorMessage(String errMessage, String extraMessage,
     659                                     OutputStream outs, String targetRequest,
    659660                                     boolean usingWWWProxy, String wwwProxy,
    660661                                     String jumpServers) throws IOException {
    661         if (out == null)
     662        if (outs == null)
    662663            return;
     664        Writer out = new BufferedWriter(new OutputStreamWriter(outs, "UTF-8"));
    663665        out.write(errMessage);
    664666        if (targetRequest != null) {
    665667            String uri = targetRequest.replace("&", "&amp;");
    666             out.write("<a href=\"".getBytes());
    667             out.write(uri.getBytes());
    668             out.write("\">".getBytes());
    669             out.write(uri.getBytes());
    670             out.write("</a>".getBytes());
     668            out.write("<a href=\"");
     669            out.write(uri);
     670            out.write("\">");
     671            out.write(uri);
     672            out.write("</a>");
    671673            if (usingWWWProxy) {
    672                 out.write(("<br><br><b>").getBytes());
    673                 out.write(_("HTTP Outproxy").getBytes("UTF-8"));
    674                 out.write((":</b> " + wwwProxy).getBytes());
     674                out.write("<br><br><b>");
     675                out.write(_("HTTP Outproxy"));
     676                out.write(":</b> " + wwwProxy);
    675677            }
    676678            if (extraMessage != null) {
    677                 out.write(("<br><br><b>" + DataHelper.escapeHTML(extraMessage) + "</b>").getBytes());
     679                out.write("<br><br><b>" + DataHelper.escapeHTML(extraMessage) + "</b>");
    678680            }
    679681            if (jumpServers != null && jumpServers.length() > 0) {
     
    709711                    if (first) {
    710712                        first = false;
    711                         out.write("<br><br><h3>".getBytes());
    712                         out.write(_("Click a link below for an address helper from a jump service").getBytes("UTF-8"));
    713                         out.write("</h3>\n".getBytes());
     713                        out.write("<br><br><h3>");
     714                        out.write(_("Click a link below for an address helper from a jump service"));
     715                        out.write("</h3>\n");
    714716                    } else {
    715                         out.write("<br>".getBytes());
     717                        out.write("<br>");
    716718                    }
    717                     out.write("<a href=\"".getBytes());
    718                     out.write(jurl.getBytes());
    719                     out.write(uri.getBytes());
    720                     out.write("\">".getBytes());
     719                    out.write("<a href=\"");
     720                    out.write(jurl);
     721                    out.write(uri);
     722                    out.write("\">");
    721723                    // Translators: parameter is a host name
    722                     out.write(_("{0} jump service", jumphost).getBytes());
    723                     out.write("</a>\n".getBytes());
     724                    out.write(_("{0} jump service", jumphost));
     725                    out.write("</a>\n");
    724726                }
    725727            }
    726728        }
    727         out.write("</div>".getBytes());
     729        out.write("</div>");
    728730        writeFooter(out);
    729731    }
     
    736738     */
    737739    public static void writeFooter(OutputStream out) throws IOException {
     740        out.write(getFooter().getBytes("UTF-8"));
     741        out.flush();
     742    }
     743
     744    /**
     745     *  Flushes.
     746     *
     747     *  Public only for LocalHTTPServer, not for general use
     748     *  @since 0.9.19
     749     */
     750    public static void writeFooter(Writer out) throws IOException {
     751        out.write(getFooter());
     752        out.flush();
     753    }
     754
     755    private static String getFooter() {
    738756        // The css is hiding this div for now, but we'll keep it here anyway
    739757        // Tag the strings below for translation if we unhide it.
    740         out.write("<div class=\"proxyfooter\"><p><i>I2P HTTP Proxy Server<br>Generated on: ".getBytes());
    741         out.write(new Date().toString().getBytes());
    742         out.write("</i></div></body></html>\n".getBytes());
    743         out.flush();
     758        StringBuilder buf = new StringBuilder(128);
     759        buf.append("<div class=\"proxyfooter\"><p><i>I2P HTTP Proxy Server<br>Generated on: ")
     760           .append(new Date().toString())
     761           .append("</i></div></body></html>\n");
     762        return buf.toString();
    744763    }
    745764
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java

    r9e18c7e rf3d573c  
    328328            long afterHandle = getTunnel().getContext().clock().now();
    329329            long timeToHandle = afterHandle - afterAccept;
    330             getTunnel().getContext().statManager().addRateData("i2ptunnel.httpserver.blockingHandleTime", timeToHandle, 0);
     330            getTunnel().getContext().statManager().addRateData("i2ptunnel.httpserver.blockingHandleTime", timeToHandle);
    331331            if ( (timeToHandle > 1000) && (_log.shouldLog(Log.WARN)) )
    332332                _log.warn("Took a while to handle the request for " + remoteHost + ':' + remotePort +
     
    697697        }
    698698        if (trimmed > 0)
    699             ctx.statManager().addRateData("i2ptunnel.httpNullWorkaround", trimmed, 0);
     699            ctx.statManager().addRateData("i2ptunnel.httpNullWorkaround", trimmed);
    700700       
    701701        int i = 0;
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java

    r9e18c7e rf3d573c  
    984984     */
    985985    public List<String> clearMessages() {
    986         List<String> rv = null;
     986        List<String> rv;
    987987        synchronized (_messages) {
    988988            rv = new ArrayList<String>(_messages);
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java

    r9e18c7e rf3d573c  
    3434public abstract class LocalHTTPServer {
    3535
    36     private final static byte[] ERR_404 =
    37         ("HTTP/1.1 404 Not Found\r\n"+
     36    private final static String ERR_404 =
     37         "HTTP/1.1 404 Not Found\r\n"+
    3838         "Content-Type: text/plain\r\n"+
    3939         "\r\n"+
    40          "HTTP Proxy local file not found")
    41         .getBytes();
    42 
    43     private final static byte[] ERR_ADD =
    44         ("HTTP/1.1 409 Bad\r\n"+
     40         "HTTP Proxy local file not found";
     41
     42    private final static String ERR_ADD =
     43         "HTTP/1.1 409 Bad\r\n"+
    4544         "Content-Type: text/plain\r\n"+
    4645         "\r\n"+
    47          "Add to addressbook failed - bad parameters")
    48         .getBytes();
     46         "Add to addressbook failed - bad parameters";
    4947
    5048    /**
     
    7068     *  @param query raw (encoded), may be null
    7169     */
    72     public static void serveLocalFile(OutputStream out, String method, String targetRequest, String query, String proxyNonce) {
     70    public static void serveLocalFile(OutputStream out, String method, String targetRequest,
     71                                      String query, String proxyNonce) throws IOException {
    7372        //System.err.println("targetRequest: \"" + targetRequest + "\"");
    7473        // a home page message for the curious...
    7574        if (targetRequest.equals("/")) {
    76             try {
    77                 out.write(("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nCache-Control: max-age=86400\r\n\r\nI2P HTTP proxy OK").getBytes());
    78                 out.flush();
    79             } catch (IOException ioe) {}
     75            out.write(("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nCache-Control: max-age=86400\r\n\r\nI2P HTTP proxy OK").getBytes("UTF-8"));
     76            out.flush();
    8077            return;
    8178        }
     
    105102                    type = "image/jpeg";
    106103                else type = "text/html";
    107                 try {
    108                     out.write("HTTP/1.1 200 OK\r\nContent-Type: ".getBytes());
    109                     out.write(type.getBytes());
    110                     out.write("\r\nCache-Control: max-age=86400\r\n\r\n".getBytes());
    111                     FileUtil.readFile(filename, themesDir.getAbsolutePath(), out);
    112                 } catch (IOException ioe) {}
     104                out.write("HTTP/1.1 200 OK\r\nContent-Type: ".getBytes("UTF-8"));
     105                out.write(type.getBytes("UTF-8"));
     106                out.write("\r\nCache-Control: max-age=86400\r\n\r\n".getBytes("UTF-8"));
     107                FileUtil.readFile(filename, themesDir.getAbsolutePath(), out);
    113108                return;
    114109            }
     
    154149            //System.err.println("nonce        : \"" + nonce         + "\"");
    155150            if (proxyNonce.equals(nonce) && url != null && host != null && dest != null) {
    156                 try {
    157                     NamingService ns = I2PAppContext.getGlobalContext().namingService();
    158                     Properties nsOptions = new Properties();
    159                     nsOptions.setProperty("list", book);
    160                     if (referer != null && referer.startsWith("http")) {
    161                         String from = "<a href=\"" + referer + "\">" + referer + "</a>";
    162                         nsOptions.setProperty("s", _("Added via address helper from {0}", from));
    163                     } else {
    164                         nsOptions.setProperty("s", _("Added via address helper"));
    165                     }
    166                     boolean success = ns.put(host, dest, nsOptions);
    167                     writeRedirectPage(out, success, host, book, url);
    168                     return;
    169                 } catch (IOException ioe) {}
    170             }
    171             try {
    172                 out.write(ERR_ADD);
    173                 out.flush();
    174             } catch (IOException ioe) {}
    175             return;
    176         }
    177         try {
    178             out.write(ERR_404);
    179             out.flush();
    180         } catch (IOException ioe) {}
     151                NamingService ns = I2PAppContext.getGlobalContext().namingService();
     152                Properties nsOptions = new Properties();
     153                nsOptions.setProperty("list", book);
     154                if (referer != null && referer.startsWith("http")) {
     155                    String from = "<a href=\"" + referer + "\">" + referer + "</a>";
     156                    nsOptions.setProperty("s", _("Added via address helper from {0}", from));
     157                } else {
     158                    nsOptions.setProperty("s", _("Added via address helper"));
     159                }
     160                boolean success = ns.put(host, dest, nsOptions);
     161                writeRedirectPage(out, success, host, book, url);
     162                return;
     163            }
     164            out.write(ERR_ADD.getBytes("UTF-8"));
     165        } else {
     166            out.write(ERR_404.getBytes("UTF-8"));
     167        }
     168        out.flush();
    181169    }
    182170
Note: See TracChangeset for help on using the changeset viewer.