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 String method = line.getMethod();
62 if (!"CONNECT".equalsIgnoreCase(method)) {
63 return false;
64 }
65 Socket targetSocket = null;
66 try {
67 targetSocket = connect(line.getUri());
68 } catch (IOException e) {
69 SimpleResponse response = new SimpleResponse();
70 response.setStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_FOUND);
71 response.setHeader(new Header("Server", "test proxy"));
72 response.setBodyString("Cannot connect to " + line.getUri());
73 conn.writeResponse(response);
74 return true;
75 }
76 SimpleResponse response = new SimpleResponse();
77 response.setHeader(new Header("Server", "test proxy"));
78 response.setStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "Connection established");
79 conn.writeResponse(response);
80
81 SimpleHttpServerConnection target = new SimpleHttpServerConnection(targetSocket);
82 pump(conn, target);
83 return true;
84 }
85
86 private void pump(final SimpleHttpServerConnection source, final SimpleHttpServerConnection target)
87 throws IOException {
88
89 source.setSocketTimeout(100);
90 target.setSocketTimeout(100);
91
92 InputStream sourceIn = source.getInputStream();
93 OutputStream sourceOut = source.getOutputStream();
94 InputStream targetIn = target.getInputStream();
95 OutputStream targetOut = target.getOutputStream();
96
97 byte[] tmp = new byte[1024];
98 int l;
99 for (;;) {
100 if (!source.isOpen() || !target.isOpen()) {
101 break;
102 }
103 try {
104 l = sourceIn.read(tmp);
105 if (l == -1) {
106 break;
107 }
108 targetOut.write(tmp, 0, l);
109 } catch (InterruptedIOException ignore) {
110 if (Thread.interrupted()) {
111 break;
112 }
113 }
114 try {
115 l = targetIn.read(tmp);
116 if (l == -1) {
117 break;
118 }
119 sourceOut.write(tmp, 0, l);
120 } catch (InterruptedIOException ignore) {
121 if (Thread.interrupted()) {
122 break;
123 }
124 }
125 }
126 }
127
128 private static Socket connect(final String host) throws IOException {
129 String hostname = null;
130 int port;
131 int i = host.indexOf(':');
132 if (i != -1) {
133 hostname = host.substring(0, i);
134 try {
135 port = Integer.parseInt(host.substring(i + 1));
136 } catch (NumberFormatException ex) {
137 throw new IOException("Invalid host address: " + host);
138 }
139 } else {
140 hostname = host;
141 port = 80;
142 }
143 return new Socket(hostname, port);
144 }
145
146 }