Skip to content

Commit 7fb5af4

Browse files
Copilotdsmiley
andcommitted
Address additional code review feedback
- Extracted query parsing logic to parseQueryParams method in URITemplateProxyServlet - Changed extractHost from private to protected in ProxyServlet to expose for subclasses - Inlined extractHost call in URITemplateProxyServlet (removed intermediate variable) - Simplified RequestInfoServlet to use transferTo() instead of manual buffer copying - Simplified testRedirect to use replaceTargetServlet helper method - Improved replaceTargetServlet to use delegating servlet pattern (no server restart needed) Co-authored-by: dsmiley <377295+dsmiley@users.noreply.github.com>
1 parent 9627bc5 commit 7fb5af4

File tree

3 files changed

+53
-56
lines changed

3 files changed

+53
-56
lines changed

src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ protected void initTarget() throws ServletException {
223223
/**
224224
* Extract host:port from URI
225225
*/
226-
private String extractHost(URI uri) {
226+
protected String extractHost(URI uri) {
227227
String host = uri.getHost();
228228
int port = uri.getPort();
229229
if (port == -1) {

src/main/java/org/mitre/dsmiley/httpproxy/URITemplateProxyServlet.java

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,7 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se
9191
queryString = queryString.substring(0, hash);
9292
}
9393

94-
LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
95-
if (requestQueryString != null && !requestQueryString.isEmpty()) {
96-
// Parse query string manually
97-
String[] pairs = requestQueryString.split("&");
98-
for (String pair : pairs) {
99-
int idx = pair.indexOf("=");
100-
if (idx > 0) {
101-
String key = URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8);
102-
String value = URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8);
103-
params.put(key, value);
104-
} else if (idx == 0) {
105-
// Ignore malformed parameter
106-
} else {
107-
// Parameter without value
108-
String key = URLDecoder.decode(pair, StandardCharsets.UTF_8);
109-
params.put(key, "");
110-
}
111-
}
112-
}
94+
LinkedHashMap<String, String> params = parseQueryParams(requestQueryString);
11395

11496
//Now rewrite the URL
11597
StringBuffer urlBuf = new StringBuffer();//note: StringBuilder isn't supported by Matcher
@@ -131,8 +113,7 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se
131113
} catch (Exception e) {
132114
throw new ServletException("Rewritten targetUri is invalid: " + newTargetUri,e);
133115
}
134-
String targetHost = extractHost(targetUriObj);
135-
servletRequest.setAttribute(ATTR_TARGET_HOST, targetHost);
116+
servletRequest.setAttribute(ATTR_TARGET_HOST, extractHost(targetUriObj));
136117

137118
//Determine the new query string based on removing the used names
138119
StringBuilder newQueryBuf = new StringBuilder(queryString.length());
@@ -154,14 +135,28 @@ protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest
154135
}
155136

156137
/**
157-
* Extract host:port from URI (helper method)
138+
* Parse query string into a map of key-value pairs
158139
*/
159-
private String extractHost(URI uri) {
160-
String host = uri.getHost();
161-
int port = uri.getPort();
162-
if (port == -1) {
163-
return host;
140+
private LinkedHashMap<String, String> parseQueryParams(String requestQueryString) {
141+
LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
142+
if (requestQueryString != null && !requestQueryString.isEmpty()) {
143+
// Parse query string manually
144+
String[] pairs = requestQueryString.split("&");
145+
for (String pair : pairs) {
146+
int idx = pair.indexOf("=");
147+
if (idx > 0) {
148+
String key = URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8);
149+
String value = URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8);
150+
params.put(key, value);
151+
} else if (idx == 0) {
152+
// Ignore malformed parameter
153+
} else {
154+
// Parameter without value
155+
String key = URLDecoder.decode(pair, StandardCharsets.UTF_8);
156+
params.put(key, "");
157+
}
158+
}
164159
}
165-
return host + ":" + port;
160+
return params;
166161
}
167162
}

src/test/java/org/mitre/dsmiley/httpproxy/ProxyServletTest.java

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public class ProxyServletTest
7171
*/
7272
protected Server targetServer;
7373
protected int targetServerPort;
74+
protected DelegatingServlet delegatingServlet;
7475

7576
/** From Meterware httpunit. */
7677
protected ServletRunner servletRunner;
@@ -84,11 +85,12 @@ public class ProxyServletTest
8485

8586
@Before
8687
public void setUp() throws Exception {
87-
// Start Jetty server as target
88+
// Start Jetty server as target with a delegating servlet that can be updated
8889
targetServer = new Server(0);
8990
ServletHandler handler = new ServletHandler();
9091
targetServer.setHandler(handler);
91-
handler.addServletWithMapping(RequestInfoServlet.class, "/targetPath/*");
92+
delegatingServlet = new DelegatingServlet(new RequestInfoServlet());
93+
handler.addServletWithMapping(new ServletHolder(delegatingServlet), "/targetPath/*");
9294
targetServer.start();
9395
targetServerPort = ((ServerConnector) targetServer.getConnectors()[0]).getLocalPort();
9496

@@ -106,16 +108,30 @@ public void setUp() throws Exception {
106108
}
107109

108110
/**
109-
* Helper to restart target server with a custom servlet
111+
* Helper to replace the target servlet handler without restarting the server
110112
*/
111-
protected void replaceTargetServlet(HttpServlet servlet) throws Exception {
112-
targetServer.stop();
113-
targetServer = new Server(targetServerPort);
114-
ServletHandler handler = new ServletHandler();
115-
targetServer.setHandler(handler);
116-
ServletHolder holder = new ServletHolder(servlet);
117-
handler.addServletWithMapping(holder, "/targetPath/*");
118-
targetServer.start();
113+
protected void replaceTargetServlet(HttpServlet servlet) {
114+
delegatingServlet.setDelegate(servlet);
115+
}
116+
117+
/**
118+
* Delegating servlet that can have its delegate updated at runtime
119+
*/
120+
protected static class DelegatingServlet extends HttpServlet {
121+
private HttpServlet delegate;
122+
123+
public DelegatingServlet(HttpServlet delegate) {
124+
this.delegate = delegate;
125+
}
126+
127+
public void setDelegate(HttpServlet delegate) {
128+
this.delegate = delegate;
129+
}
130+
131+
@Override
132+
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
133+
delegate.service(req, resp);
134+
}
119135
}
120136

121137
protected void setUpServlet(Properties servletProps) {
@@ -175,14 +191,7 @@ public void testPost() throws Exception {
175191
public void testRedirect() throws Exception {
176192
final String COOKIE_SET_HEADER = "Set-Cookie";
177193

178-
// Stop the target server and restart with redirect servlet
179-
targetServer.stop();
180-
targetServer = new Server(targetServerPort);
181-
ServletHandler handler = new ServletHandler();
182-
targetServer.setHandler(handler);
183-
184-
// Add a redirect servlet
185-
ServletHolder redirectHolder = new ServletHolder(new HttpServlet() {
194+
replaceTargetServlet(new HttpServlet() {
186195
@Override
187196
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
188197
String targetHeader = request.getHeader("xxTarget");
@@ -193,8 +202,6 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
193202
}
194203
}
195204
});
196-
handler.addServletWithMapping(redirectHolder, "/targetPath/*");
197-
targetServer.start();
198205

199206
GetMethodWebRequest request = makeGetMethodRequest(sourceBaseUri + "/%64%69%72%2F");
200207
assertRedirect(request, "/dummy", "/dummy");//TODO represents a bug to fix
@@ -733,12 +740,7 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
733740
pw.flush();//done with pw now
734741

735742
// Copy request body
736-
InputStream is = request.getInputStream();
737-
byte[] buffer = new byte[8192];
738-
int bytesRead;
739-
while ((bytesRead = is.read(buffer)) != -1) {
740-
baos.write(buffer, 0, bytesRead);
741-
}
743+
request.getInputStream().transferTo(baos);
742744

743745
response.setStatus(200);
744746
response.setHeader("X-Reason", "TESTREASON");

0 commit comments

Comments
 (0)