1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.apache.commons.httpclient.server;
31
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.InterruptedIOException;
35 import java.io.OutputStream;
36 import java.net.Socket;
37
38 import org.apache.commons.httpclient.Header;
39 import org.apache.commons.httpclient.HttpStatus;
40 import org.apache.commons.httpclient.HttpVersion;
41
42 /***
43 * This request handler can handle the CONNECT method. It does nothing for any
44 * other HTTP methods.
45 *
46 * @author Ortwin Glueck
47 */
48 public class TransparentProxyRequestHandler implements HttpRequestHandler {
49
50
51
52
53
54
55 public boolean processRequest(
56 final SimpleHttpServerConnection conn,
57 final SimpleRequest request) throws IOException
58 {
59
60 RequestLine line = request.getRequestLine();
61 HttpVersion ver = line.getHttpVersion();
62 String method = line.getMethod();
63 if (!"CONNECT".equalsIgnoreCase(method)) {
64 return false;
65 }
66 Socket targetSocket = null;
67 try {
68 targetSocket = connect(line.getUri());
69 } catch (IOException e) {
70 SimpleResponse response = new SimpleResponse();
71 response.setStatusLine(ver, HttpStatus.SC_NOT_FOUND);
72 response.setHeader(new Header("Server", "test proxy"));
73 response.setBodyString("Cannot connect to " + line.getUri());
74 conn.writeResponse(response);
75 return true;
76 }
77 SimpleResponse response = new SimpleResponse();
78 response.setHeader(new Header("Server", "test proxy"));
79 response.setStatusLine(ver, HttpStatus.SC_OK, "Connection established");
80 conn.writeResponse(response);
81
82 SimpleHttpServerConnection target = new SimpleHttpServerConnection(targetSocket);
83 pump(conn, target);
84 return true;
85 }
86
87 private void pump(final SimpleHttpServerConnection source, final SimpleHttpServerConnection target)
88 throws IOException {
89
90 source.setSocketTimeout(100);
91 target.setSocketTimeout(100);
92
93 InputStream sourceIn = source.getInputStream();
94 OutputStream sourceOut = source.getOutputStream();
95 InputStream targetIn = target.getInputStream();
96 OutputStream targetOut = target.getOutputStream();
97
98 byte[] tmp = new byte[1024];
99 int l;
100 for (;;) {
101 if (!source.isOpen() || !target.isOpen()) {
102 break;
103 }
104 try {
105 l = sourceIn.read(tmp);
106 if (l == -1) {
107 break;
108 }
109 targetOut.write(tmp, 0, l);
110 } catch (InterruptedIOException ignore) {
111 if (Thread.interrupted()) {
112 break;
113 }
114 }
115 try {
116 l = targetIn.read(tmp);
117 if (l == -1) {
118 break;
119 }
120 sourceOut.write(tmp, 0, l);
121 } catch (InterruptedIOException ignore) {
122 if (Thread.interrupted()) {
123 break;
124 }
125 }
126 }
127 }
128
129 private static Socket connect(final String host) throws IOException {
130 String hostname = null;
131 int port;
132 int i = host.indexOf(':');
133 if (i != -1) {
134 hostname = host.substring(0, i);
135 try {
136 port = Integer.parseInt(host.substring(i + 1));
137 } catch (NumberFormatException ex) {
138 throw new IOException("Invalid host address: " + host);
139 }
140 } else {
141 hostname = host;
142 port = 80;
143 }
144 return new Socket(hostname, port);
145 }
146
147 }