| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2014 Eyeo GmbH | 3  * Copyright (C) 2006-2014 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 23 import java.net.InetSocketAddress; | 23 import java.net.InetSocketAddress; | 
| 24 import java.net.Socket; | 24 import java.net.Socket; | 
| 25 | 25 | 
| 26 import sunlabs.brazil.server.Request; | 26 import sunlabs.brazil.server.Request; | 
| 27 import sunlabs.brazil.server.Server; | 27 import sunlabs.brazil.server.Server; | 
| 28 import sunlabs.brazil.util.MatchString; | 28 import sunlabs.brazil.util.MatchString; | 
| 29 | 29 | 
| 30 /** | 30 /** | 
| 31  * <code>RequestHandler</code> implements a SSL tunnel. | 31  * <code>RequestHandler</code> implements a SSL tunnel. | 
| 32  * | 32  * | 
| 33  * The following configuration parameters are used to initialize this | 33  * The following configuration parameters are used to initialize this <code>Hand
     ler</code>: | 
| 34  * <code>Handler</code>: |  | 
| 35  * <dl class=props> | 34  * <dl class=props> | 
| 36  * | 35  * | 
| 37  * <dt>prefix, suffix, glob, match | 36  * <dt>prefix, suffix, glob, match | 
| 38  * <dd>Specify the URL that triggers this handler. (See {@link MatchString}). | 37  * <dd>Specify the URL that triggers this handler. (See {@link MatchString}). | 
| 39  * <dt>auth | 38  * <dt>auth | 
| 40  * <dd>The value of the proxy-authenticate header (if any) sent to the upstream | 39  * <dd>The value of the proxy-authenticate header (if any) sent to the upstream 
     proxy | 
| 41  * proxy |  | 
| 42  * <dt>proxyHost | 40  * <dt>proxyHost | 
| 43  * <dd>If specified, the name of the upstream proxy | 41  * <dd>If specified, the name of the upstream proxy | 
| 44  * <dt>proxyPort | 42  * <dt>proxyPort | 
| 45  * <dd>The upstream proxy port, if a proxyHost is specified (defaults to 80) | 43  * <dd>The upstream proxy port, if a proxyHost is specified (defaults to 80) | 
| 46  * | 44  * | 
| 47  * </dl> | 45  * </dl> | 
| 48  * | 46  * | 
| 49  * A sample set of configuration parameters illustrating how to use this | 47  * A sample set of configuration parameters illustrating how to use this handler
      follows: | 
| 50  * handler follows: |  | 
| 51  * | 48  * | 
| 52  * <pre> | 49  * <pre> | 
| 53  * handler=https | 50  * handler=https | 
| 54  * https.class=org.adblockplus.brazil.SSLConnectionHandler | 51  * https.class=org.adblockplus.brazil.SSLConnectionHandler | 
| 55  * </pre> | 52  * </pre> | 
| 56  * | 53  * | 
| 57  * See the description under {@link sunlabs.brazil.server.Handler#respond | 54  * See the description under {@link sunlabs.brazil.server.Handler#respond | 
| 58  * respond} for a more detailed explanation. | 55  * respond} for a more detailed explanation. | 
| 59  * | 56  *j | 
| 60  * Original source by Jochen Luell, PAW (http://paw-project.sourceforge.net/) | 57  * Original source by Jochen Luell, PAW (http://paw-project.sourceforge.net/) | 
| 61  */ | 58  */ | 
| 62 | 59 | 
| 63 public class SSLConnectionHandler extends BaseRequestHandler | 60 public class SSLConnectionHandler extends BaseRequestHandler | 
| 64 { | 61 { | 
| 65   @Override | 62   @Override | 
| 66   public boolean respond(Request request) throws IOException | 63   public boolean respond(final Request request) throws IOException | 
| 67   { | 64   { | 
| 68     if (!request.method.equals("CONNECT")) | 65     if (!request.method.equals("CONNECT")) | 
| 69       return false; | 66       return false; | 
| 70 | 67 | 
| 71     request.log(Server.LOG_LOG, prefix, "SSL connection to " + request.url); | 68     request.log(Server.LOG_LOG, prefix, "SSL connection to " + request.url); | 
| 72 | 69 | 
| 73     String host = null; | 70     String host = null; | 
| 74     int port = 0; | 71     int port = 0; | 
| 75 | 72 | 
| 76     Socket serverSocket; | 73     Socket serverSocket; | 
| 77     try | 74     try | 
| 78     { | 75     { | 
| 79       if (proxyHost != null) | 76       if (proxyHost != null) | 
| 80       { | 77       { | 
| 81         host = proxyHost; | 78         host = proxyHost; | 
| 82         port = proxyPort; | 79         port = proxyPort; | 
| 83         if (auth != null) | 80         if (auth != null) | 
| 84         { | 81         { | 
| 85           request.headers.add("Proxy-Authorization", auth); | 82           request.headers.add("Proxy-Authorization", auth); | 
| 86         } | 83         } | 
| 87       } | 84       } | 
| 88       else | 85       else | 
| 89       { | 86       { | 
| 90         int c = request.url.indexOf(':'); | 87         final int c = request.url.indexOf(':'); | 
| 91         host = request.url.substring(0, c); | 88         host = request.url.substring(0, c); | 
| 92         port = Integer.parseInt(request.url.substring(c + 1)); | 89         port = Integer.parseInt(request.url.substring(c + 1)); | 
| 93       } | 90       } | 
| 94 | 91 | 
| 95       // Connect to server or upstream proxy | 92       // Connect to server or upstream proxy | 
| 96       serverSocket = new Socket(); | 93       serverSocket = new Socket(); | 
| 97       serverSocket.setKeepAlive(true); | 94       serverSocket.setKeepAlive(true); | 
| 98       serverSocket.connect(new InetSocketAddress(host, port)); | 95       serverSocket.connect(new InetSocketAddress(host, port)); | 
| 99     } | 96     } | 
| 100     catch (Exception e) | 97     catch (final Exception e) | 
| 101     { | 98     { | 
| 102       request.sendError(500, "SSL connection failure"); | 99       request.sendError(500, "SSL connection failure"); | 
| 103       return true; | 100       return true; | 
| 104     } | 101     } | 
| 105 | 102 | 
| 106     try | 103     try | 
| 107     { | 104     { | 
| 108       if (proxyHost != null) | 105       if (proxyHost != null) | 
| 109       { | 106       { | 
| 110         // Forward request to upstream proxy | 107         // Forward request to upstream proxy | 
| 111         OutputStream out = serverSocket.getOutputStream(); | 108         final OutputStream out = serverSocket.getOutputStream(); | 
| 112         out.write((request.method + " " + request.url + " " + request.protocol +
      "\r\n").getBytes()); | 109         out.write((request.method + " " + request.url + " " + request.protocol +
      "\r\n").getBytes()); | 
| 113         request.headers.print(out); | 110         request.headers.print(out); | 
| 114         out.write("\r\n".getBytes()); | 111         out.write("\r\n".getBytes()); | 
| 115         out.flush(); | 112         out.flush(); | 
| 116       } | 113       } | 
| 117       else | 114       else | 
| 118       { | 115       { | 
| 119         // Send response to client | 116         // Send response to client | 
| 120         OutputStream out = request.sock.getOutputStream(); | 117         final OutputStream out = request.sock.getOutputStream(); | 
| 121         out.write((request.protocol + " 200 Connection established\r\n\r\n").get
     Bytes()); | 118         out.write((request.protocol + " 200 Connection established\r\n\r\n").get
     Bytes()); | 
| 122         out.flush(); | 119         out.flush(); | 
| 123       } | 120       } | 
| 124 | 121 | 
| 125       // Start bi-directional data transfer | 122       // Start bi-directional data transfer | 
| 126       ConnectionHandler client = new ConnectionHandler(request.sock, serverSocke
     t); | 123       final ConnectionHandler client = new ConnectionHandler(request.sock, serve
     rSocket); | 
| 127       ConnectionHandler server = new ConnectionHandler(serverSocket, request.soc
     k); | 124       final ConnectionHandler server = new ConnectionHandler(serverSocket, reque
     st.sock); | 
| 128       client.start(); | 125       client.start(); | 
| 129       server.start(); | 126       server.start(); | 
| 130 | 127 | 
| 131       // Wait for connections to close | 128       // Wait for connections to close | 
| 132       client.join(); | 129       client.join(); | 
| 133       server.join(); | 130       server.join(); | 
| 134     } | 131     } | 
| 135     catch (InterruptedException e) | 132     catch (final InterruptedException e) | 
| 136     { | 133     { | 
| 137       request.log(Server.LOG_ERROR, prefix, "Data exchange error: " + e.getMessa
     ge()); | 134       request.log(Server.LOG_ERROR, prefix, "Data exchange error: " + e.getMessa
     ge()); | 
| 138     } | 135     } | 
| 139 | 136 | 
| 140     // Close connection | 137     // Close connection | 
| 141     serverSocket.close(); | 138     serverSocket.close(); | 
| 142     request.log(Server.LOG_LOG, prefix, "SSL connection closed"); | 139     request.log(Server.LOG_LOG, prefix, "SSL connection closed"); | 
| 143 | 140 | 
| 144     return true; | 141     return true; | 
| 145   } | 142   } | 
| 146 | 143 | 
| 147   private class ConnectionHandler extends Thread | 144   private class ConnectionHandler extends Thread | 
| 148   { | 145   { | 
| 149     private InputStream in; | 146     private final InputStream in; | 
| 150     private OutputStream out; | 147     private final OutputStream out; | 
| 151 | 148 | 
| 152     ConnectionHandler(Socket sin, Socket sout) throws IOException | 149     ConnectionHandler(final Socket sin, final Socket sout) throws IOException | 
| 153     { | 150     { | 
| 154       in = sin.getInputStream(); | 151       in = sin.getInputStream(); | 
| 155       out = sout.getOutputStream(); | 152       out = sout.getOutputStream(); | 
| 156     } | 153     } | 
| 157 | 154 | 
| 158     @Override | 155     @Override | 
| 159     public void run() | 156     public void run() | 
| 160     { | 157     { | 
| 161       byte[] buf = new byte[4096]; | 158       final byte[] buf = new byte[4096]; | 
| 162       int count; | 159       int count; | 
| 163 | 160 | 
| 164       try | 161       try | 
| 165       { | 162       { | 
| 166         while ((count = in.read(buf, 0, buf.length)) != -1) | 163         while ((count = in.read(buf, 0, buf.length)) != -1) | 
| 167         { | 164         { | 
| 168           out.write(buf, 0, count); | 165           out.write(buf, 0, count); | 
| 169         } | 166         } | 
| 170         out.flush(); | 167         out.flush(); | 
| 171       } | 168       } | 
| 172       catch (IOException e) | 169       catch (final IOException e) | 
| 173       { | 170       { | 
| 174         e.printStackTrace(); | 171         e.printStackTrace(); | 
| 175       } | 172       } | 
| 176     } | 173     } | 
| 177   } | 174   } | 
| 178 } | 175 } | 
| OLD | NEW | 
|---|