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