You know when you just need a streaming http proxy servlet and you just can't find one? Well try this:
HttpProxyServlet.java
package org.adrianwalker.servlet.proxy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public final class HttpProxyServlet extends HttpServlet {
private URL url;
private HttpClient proxy;
@Override
public void init(final ServletConfig config) throws ServletException {
super.init(config);
try {
url = new URL(config.getInitParameter("url"));
} catch (MalformedURLException me) {
throw new ServletException("Proxy URL is invalid", me);
}
proxy = new HttpClient();
proxy.getHostConfiguration().setHost(url.getHost());
}
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
Map<String, String[]> requestParameters = request.getParameterMap();
StringBuilder query = new StringBuilder();
for (String name : requestParameters.keySet()) {
for (String value : requestParameters.get(name)) {
if (query.length() == 0) {
query.append("?");
} else {
query.append("&");
}
name = URLEncoder.encode(name, "UTF-8");
value = URLEncoder.encode(value, "UTF-8");
query.append(String.format("&%s=%s", name, value));
}
}
String uri = String.format("%s%s", url.toString(), query.toString());
GetMethod proxyMethod = new GetMethod(uri);
proxy.executeMethod(proxyMethod);
write(proxyMethod.getResponseBodyAsStream(), response.getOutputStream());
}
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
Map<String, String[]> requestParameters = request.getParameterMap();
String uri = url.toString();
PostMethod proxyMethod = new PostMethod(uri);
for (String name : requestParameters.keySet()) {
for (String value : requestParameters.get(name)) {
proxyMethod.addParameter(name, value);
}
}
proxy.executeMethod(proxyMethod);
write(proxyMethod.getResponseBodyAsStream(), response.getOutputStream());
}
private void write(final InputStream inputStream, final OutputStream outputStream) throws IOException {
int b;
while ((b = inputStream.read()) != -1) {
outputStream.write(b);
}
outputStream.flush();
}
@Override
public String getServletInfo() {
return "Http Proxy Servlet";
}
}
This class makes use of the Jakarta Commons HttpClient to forward requests to a configurable url and streams back the response.
A sample project using this servlet is available for download below. The servlet acts as a proxy for a google search, returning the search results page. The proxied url is configurable in the web applications web.xml file. The project builds a war and uses the jetty plugin so you can test the code.
Run the project with 'mvn clean install jetty:run-war' and point your brower at http://localhost:8080/http-proxy-servlet
Source Code
- Java Maven Project - HttpProxyServlet.zip