| OLD | NEW | 
| (Empty) |  | 
 |    1 package org.adblockplus.brazil; | 
 |    2  | 
 |    3 import java.io.IOException; | 
 |    4 import java.io.InputStream; | 
 |    5 import java.io.OutputStream; | 
 |    6 import java.net.InetAddress; | 
 |    7 import java.net.Socket; | 
 |    8 import java.util.Properties; | 
 |    9  | 
 |   10 import sunlabs.brazil.server.Handler; | 
 |   11 import sunlabs.brazil.server.Request; | 
 |   12 import sunlabs.brazil.server.Server; | 
 |   13 import sunlabs.brazil.util.MatchString; | 
 |   14  | 
 |   15 /** | 
 |   16  * <code>RequestHandler</code> implements a SSL tunnel. | 
 |   17  *  | 
 |   18  * The following configuration parameters are used to initialize this | 
 |   19  * <code>Handler</code>: | 
 |   20  * <dl class=props> | 
 |   21  *  | 
 |   22  * <dt>prefix, suffix, glob, match | 
 |   23  * <dd>Specify the URL that triggers this handler. (See {@link MatchString}). | 
 |   24  * <dt>auth | 
 |   25  * <dd>The value of the proxy-authenticate header (if any) sent to the upstream | 
 |   26  * proxy | 
 |   27  * <dt>proxyHost | 
 |   28  * <dd>If specified, the name of the upstream proxy | 
 |   29  * <dt>proxyPort | 
 |   30  * <dd>The upstream proxy port, if a proxyHost is specified (defaults to 80) | 
 |   31  *  | 
 |   32  * </dl> | 
 |   33  *  | 
 |   34  * A sample set of configuration parameters illustrating how to use this | 
 |   35  * handler follows: | 
 |   36  *  | 
 |   37  * <pre> | 
 |   38  * handler=https | 
 |   39  * https.class=org.adblockplus.brazil.SSLConnectionHandler | 
 |   40  * </pre> | 
 |   41  *  | 
 |   42  * See the description under {@link sunlabs.brazil.server.Handler#respond | 
 |   43  * respond} for a more detailed explanation. | 
 |   44  *  | 
 |   45  * Original source by Jochen Luell, PAW (http://paw-project.sourceforge.net/) | 
 |   46  */ | 
 |   47  | 
 |   48 public class SSLConnectionHandler implements Handler | 
 |   49 { | 
 |   50         public static final String PROXY_HOST = "proxyHost"; | 
 |   51         public static final String PROXY_PORT = "proxyPort"; | 
 |   52         public static final String AUTH = "auth"; | 
 |   53  | 
 |   54         private String prefix; | 
 |   55  | 
 |   56         private String proxyHost; | 
 |   57         private int proxyPort = 80; | 
 |   58         private String auth; | 
 |   59  | 
 |   60         @Override | 
 |   61         public boolean init(Server server, String prefix) | 
 |   62         { | 
 |   63                 this.prefix = prefix; | 
 |   64  | 
 |   65                 Properties props = server.props; | 
 |   66  | 
 |   67                 proxyHost = props.getProperty(prefix + PROXY_HOST); | 
 |   68  | 
 |   69                 String s = props.getProperty(prefix + PROXY_PORT); | 
 |   70                 try | 
 |   71                 { | 
 |   72                         proxyPort = Integer.decode(s).intValue(); | 
 |   73                 } | 
 |   74                 catch (Exception e) | 
 |   75                 { | 
 |   76                 } | 
 |   77  | 
 |   78                 auth = props.getProperty(prefix + AUTH); | 
 |   79  | 
 |   80                 return true; | 
 |   81         } | 
 |   82  | 
 |   83         @Override | 
 |   84         public boolean respond(Request request) throws IOException | 
 |   85         { | 
 |   86                 if (!request.method.equals("CONNECT")) | 
 |   87                         return false; | 
 |   88  | 
 |   89                 request.log(Server.LOG_LOG, prefix, "SSL connection to " + reque
     st.url); | 
 |   90  | 
 |   91                 String host = null; | 
 |   92                 int port = 0; | 
 |   93  | 
 |   94                 Socket serverSocket; | 
 |   95                 try | 
 |   96                 { | 
 |   97                         if (proxyHost != null) | 
 |   98                         { | 
 |   99                                 host = proxyHost; | 
 |  100                                 port = proxyPort; | 
 |  101                                 if (auth != null) | 
 |  102                                 { | 
 |  103                                         request.headers.add("Proxy-Authorization
     ", auth); | 
 |  104                                 } | 
 |  105                         } | 
 |  106                         else | 
 |  107                         { | 
 |  108                                 int c = request.url.indexOf(':'); | 
 |  109                                 host = request.url.substring(0, c); | 
 |  110                                 port = Integer.parseInt(request.url.substring(c+
     1)); | 
 |  111                         } | 
 |  112  | 
 |  113                         // Connect to server or upstream proxy | 
 |  114                         InetAddress addr = InetAddress.getByName(host); | 
 |  115                         serverSocket = new Socket(addr, port); | 
 |  116                 } | 
 |  117                 catch (Exception e) | 
 |  118                 { | 
 |  119                         request.sendError(500, "SSL connection failure"); | 
 |  120                         return true; | 
 |  121                 } | 
 |  122  | 
 |  123                 try | 
 |  124                 { | 
 |  125                         if (proxyHost != null) | 
 |  126                         { | 
 |  127                                 // Forward request to upstream proxy | 
 |  128                                 OutputStream out = serverSocket.getOutputStream(
     ); | 
 |  129                                 out.write((request.method + " " + request.url + 
     " " + request.protocol + "\r\n").getBytes()); | 
 |  130                                 request.headers.print(out); | 
 |  131                                 out.write("\r\n".getBytes()); | 
 |  132                                 out.flush(); | 
 |  133                         } | 
 |  134                         else | 
 |  135                         { | 
 |  136                                 // Send response to client | 
 |  137                                 OutputStream out = request.sock.getOutputStream(
     ); | 
 |  138                                 out.write((request.protocol + " 200 Connection e
     stablished\r\n\r\n").getBytes()); | 
 |  139                                 out.flush(); | 
 |  140                         } | 
 |  141  | 
 |  142                         // Start bi-directional data transfer | 
 |  143                         ConnectionHandler client = new ConnectionHandler(request
     .sock, serverSocket); | 
 |  144                         ConnectionHandler server = new ConnectionHandler(serverS
     ocket, request.sock); | 
 |  145                         client.start(); | 
 |  146                         server.start(); | 
 |  147  | 
 |  148                         // Wait for connections to close | 
 |  149                         client.join(); | 
 |  150                         server.join(); | 
 |  151                 } | 
 |  152                 catch (InterruptedException e) | 
 |  153                 { | 
 |  154                     request.log(Server.LOG_ERROR, prefix, "Data exchange error: 
     " + e.getMessage()); | 
 |  155                 } | 
 |  156  | 
 |  157                 // Close connection | 
 |  158                 serverSocket.close(); | 
 |  159                 request.log(Server.LOG_LOG, prefix, "SSL connection closed"); | 
 |  160  | 
 |  161                 return true; | 
 |  162         } | 
 |  163  | 
 |  164         private class ConnectionHandler extends Thread | 
 |  165         { | 
 |  166                 private InputStream in; | 
 |  167                 private OutputStream out; | 
 |  168  | 
 |  169                 ConnectionHandler(Socket sin, Socket sout) throws IOException | 
 |  170                 { | 
 |  171                         in = sin.getInputStream(); | 
 |  172                         out = sout.getOutputStream(); | 
 |  173                 } | 
 |  174  | 
 |  175                 @Override | 
 |  176                 public void run() | 
 |  177                 { | 
 |  178                         byte[] buf = new byte[4096]; | 
 |  179                         int count; | 
 |  180  | 
 |  181                         try | 
 |  182                         { | 
 |  183                                 while ((count = in.read(buf, 0, buf.length)) != 
     -1) | 
 |  184                                 { | 
 |  185                                         out.write(buf, 0, count); | 
 |  186                                 } | 
 |  187                                 out.flush(); | 
 |  188                         } | 
 |  189                         catch (IOException e) | 
 |  190                         { | 
 |  191                                 e.printStackTrace(); | 
 |  192                         } | 
 |  193                 } | 
 |  194         } | 
 |  195 } | 
| OLD | NEW |