Java HTTP proxy servlet (with Spring)

10 years ago

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; 
        } 
      } 
    }