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