I always wanted to build my own proxy. I'm kidding. I do have better things to do with my time. Nevertheless, a problem presented itself and here's my solution for it: An HTTP proxy Spring controller.
Currently:
Handles GET and POST methods; Guaranties the type of the response to be the one the target server sends; Supports sending POST (form) parameters; The parameter for the target url is called, interestingly enough, 'url'; Has a dependency on Spring, and Apache's HttpClient.
Here's the code, have fun:
package org.voidness.httpproxy;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URLDecoder;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.NotImplementedException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author Pedro Assuncao (assuncas@gmail.com)
* @May 26, 2009
*
*/
@Controller
public class AjaxProxyController {
@SuppressWarnings("unchecked") @RequestMapping(value = "/")
public final void proxyAjaxCall( @RequestParam(required = true, value = "url") String url, HttpServletRequest request, HttpServletResponse response) throws IOException {
// URL needs to be url
decoded url = URLDecoder.decode(url, "utf-8");
OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
HttpClient client = new HttpClient();
try {
HttpMethod method = null;
// Split this according to the type of request
if (request.getMethod().equals("GET")) {
method = new GetMethod(url);
} else if (request.getMethod().equals("POST")) {
method = new PostMethod(url);
// Set any eventual parameters that came with our original
// request (POST params, for instance)
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
((PostMethod) method).setParameter(paramName, request .getParameter(paramName));
}
} else {
throw new NotImplementedException( "This proxy only supports GET and POST methods.");
}
// Execute the method
client.executeMethod(method);
// Set the content type, as it comes from the server
Header[] headers = method.getResponseHeaders();
for (Header header : headers) {
if ("Content-Type".equalsIgnoreCase(header.getName())) {
response.setContentType(header.getValue());
}
}
// Write the body, flush and close
writer.write(method.getResponseBodyAsString());
writer.flush();
writer.close();
} catch (HttpException e) {
//log.error("Oops, something went wrong in the HTTP proxy", null, e);
writer.write(e.toString());
throw e;
} catch (IOException e) {
e.printStackTrace();
writer.write(e.toString());
throw e;
}
}
}