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
31 package org.apache.commons.httpclient.server;
32
33 import java.io.IOException;
34 import java.net.UnknownHostException;
35
36 import org.apache.commons.httpclient.Header;
37 import org.apache.commons.httpclient.HttpException;
38 import org.apache.commons.httpclient.HttpStatus;
39 import org.apache.commons.httpclient.HttpVersion;
40 import org.apache.commons.httpclient.URI;
41 import org.apache.commons.httpclient.URIException;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45 /***
46 * @author Ortwin Glueck
47 * @author Oleg Kalnichevski
48 */
49 public class ProxyRequestHandler implements HttpRequestHandler {
50
51 private static final Log LOG = LogFactory.getLog(ProxyRequestHandler.class);
52
53 private SimpleConnManager connmanager = null;
54
55 public ProxyRequestHandler(final SimpleConnManager connmanager) {
56 super();
57 if (connmanager == null) {
58 throw new IllegalArgumentException("Connection manager may not be null");
59 }
60 this.connmanager = connmanager;
61 }
62
63 /***
64 * @see org.apache.commons.httpclient.server.HttpRequestHandler#processRequest(org.apache.commons.httpclient.server.SimpleHttpServerConnection)
65 */
66 public boolean processRequest(
67 final SimpleHttpServerConnection conn,
68 final SimpleRequest request) throws IOException
69 {
70 httpProxy(conn, request);
71 return true;
72 }
73
74 private void httpProxy(
75 final SimpleHttpServerConnection conn,
76 final SimpleRequest request) throws IOException {
77
78 RequestLine oldreqline = request.getRequestLine();
79 URI uri = null;
80 SimpleHost host = null;
81 try {
82 uri = new URI(oldreqline.getUri(), true);
83 host = new SimpleHost(uri.getHost(), uri.getPort());
84 } catch (URIException ex) {
85 SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
86 conn.writeResponse(response);
87 return;
88 }
89 SimpleHttpServerConnection proxyconn = null;
90 try {
91 proxyconn = this.connmanager.openConnection(host);
92 } catch (UnknownHostException e) {
93 SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_NOT_FOUND);
94 conn.writeResponse(response);
95 return;
96 }
97 try {
98 proxyconn.setSocketTimeout(0);
99
100 RequestLine newreqline = new RequestLine(
101 oldreqline.getMethod(),
102 uri.getEscapedPath(),
103 oldreqline.getHttpVersion());
104 request.setRequestLine(newreqline);
105
106 request.removeHeaders("Proxy-Authorization");
107
108 Header connheader = request.getFirstHeader("Proxy-Connection");
109 if (connheader != null) {
110 if (connheader.getValue().equalsIgnoreCase("close")) {
111 request.setHeader(new Header("Connection", "close"));
112 }
113 }
114 request.removeHeaders("Proxy-Connection");
115
116 proxyconn.writeRequest(request);
117
118 SimpleResponse response = proxyconn.readResponse();
119 if (response == null) {
120 return;
121 }
122 response.setHeader(new Header("Via", "1.1 test (Test-Proxy)"));
123 connheader = response.getFirstHeader("Connection");
124 if (connheader != null) {
125 String s = connheader.getValue();
126 if (s.equalsIgnoreCase("close")) {
127 response.setHeader(new Header("Proxy-Connection", "close"));
128 conn.setKeepAlive(false);
129 proxyconn.setKeepAlive(false);
130 response.removeHeaders("Connection");
131 }
132 if (s.equalsIgnoreCase("keep-alive")) {
133 response.setHeader(new Header("Proxy-Connection", "keep-alive"));
134 conn.setKeepAlive(true);
135 proxyconn.setKeepAlive(true);
136 response.removeHeaders("Connection");
137 }
138 } else {
139
140 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1)) {
141 conn.setKeepAlive(true);
142 proxyconn.setKeepAlive(true);
143 } else {
144 conn.setKeepAlive(false);
145 proxyconn.setKeepAlive(false);
146 }
147 }
148 if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
149
150 response.setBody(null);
151 }
152 conn.writeResponse(response);
153
154 } catch (HttpException e) {
155 SimpleResponse response = ErrorResponse.getResponse(HttpStatus.SC_BAD_REQUEST);
156 conn.writeResponse(response);
157 proxyconn.setKeepAlive(false);
158 } catch (IOException e) {
159 LOG.warn(e.getMessage());
160 proxyconn.setKeepAlive(false);
161 } finally {
162 this.connmanager.releaseConnection(host, proxyconn);
163 }
164 }
165
166 }