Esempio n. 1
0
  protected Response request(HttpMethod method) throws IOException {
    int statusCode;
    String body;

    try {
      statusCode = client.executeMethod(method);
      if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY
          || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
        method.releaseConnection();

        HttpMethod postMethod = redirectMethod((PostMethod) method);
        statusCode = client.executeMethod(postMethod);
        method = postMethod;
      }
      if (statusCode == HttpStatus.SC_NO_CONTENT) {
        body = "";
      } else {
        body = new String(method.getResponseBody(), "utf-8");
      }
      logger.debug("Remote Control replied with '" + statusCode + " / '" + body + "'");
      return new Response(statusCode, body, method.getResponseHeaders());
    } finally {
      method.releaseConnection();
    }
  }
Esempio n. 2
0
  protected void populateResponse(
      Exchange exchange,
      HttpMethod method,
      Message in,
      HeaderFilterStrategy strategy,
      int responseCode)
      throws IOException, ClassNotFoundException {
    // We just make the out message is not create when extractResponseBody throws exception,
    Object response = extractResponseBody(method, exchange);
    Message answer = exchange.getOut();

    answer.setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
    answer.setBody(response);

    // propagate HTTP response headers
    Header[] headers = method.getResponseHeaders();
    for (Header header : headers) {
      String name = header.getName();
      String value = header.getValue();
      if (name.toLowerCase().equals("content-type")) {
        name = Exchange.CONTENT_TYPE;
        exchange.setProperty(Exchange.CHARSET_NAME, IOHelper.getCharsetNameFromContentType(value));
      }

      // use http helper to extract parameter value as it may contain multiple values
      Object extracted = HttpHelper.extractHttpParameterValue(value);
      if (strategy != null && !strategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
        HttpHelper.appendHeader(answer.getHeaders(), name, extracted);
      }
    }

    // preserve headers from in by copying any non existing headers
    // to avoid overriding existing headers with old values
    MessageHelper.copyHeaders(exchange.getIn(), answer, false);
  }
 void copyProxyReponse(HttpMethod proxyResponse, HttpServletResponse response) throws IOException {
   copyProxyHeaders(proxyResponse.getResponseHeaders(), response);
   response.setContentLength(getResponseContentLength(proxyResponse));
   copy(proxyResponse.getResponseBodyAsStream(), response.getOutputStream());
   if (proxyResponse.getStatusLine() != null) {
     int statCode = proxyResponse.getStatusCode();
     response.setStatus(statCode);
   }
 }
Esempio n. 4
0
 private String getHttpResponseHeader(HttpMethod method) {
   StringBuilder strHeader = new StringBuilder();
   Header[] headers = method.getResponseHeaders();
   for (Header header : headers) {
     String name = header.getName();
     String value = header.getValue();
     strHeader.append(name + "=" + value + ";");
   }
   return strHeader.toString();
 }
 void changeSpacingInterval(HttpMethod httpMethod) {
   Header[] spacingIntervalHeaders = httpMethod.getResponseHeaders(Constants.SPACING_INTERVAL);
   if (spacingIntervalHeaders.length >= 1) {
     try {
       diamondConfigure.setPollingIntervalTime(
           Integer.parseInt(spacingIntervalHeaders[0].getValue()));
     } catch (RuntimeException e) {
       log.error("�����´μ��ʱ��ʧ��", e);
     }
   }
 }
Esempio n. 6
0
  public Response httpRequest(HttpMethod method, Boolean WithTokenHeader, String token)
      throws WeiboException {
    InetAddress ipaddr;
    int responseCode = -1;
    try {
      ipaddr = InetAddress.getLocalHost();
      List<Header> headers = new ArrayList<Header>();
      if (WithTokenHeader) {
        if (token == null) {
          throw new IllegalStateException("Oauth2 token is not set!");
        }
        headers.add(new Header("Authorization", "OAuth2 " + token));
        headers.add(new Header("API-RemoteIP", ipaddr.getHostAddress()));
        client.getHostConfiguration().getParams().setParameter("http.default-headers", headers);
        for (Header hd : headers) {
          log(hd.getName() + ": " + hd.getValue());
        }
      }

      method
          .getParams()
          .setParameter(
              HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
      client.executeMethod(method);
      Header[] resHeader = method.getResponseHeaders();
      responseCode = method.getStatusCode();
      log("Response:");
      log("https StatusCode:" + String.valueOf(responseCode));

      for (Header header : resHeader) {
        log(header.getName() + ":" + header.getValue());
      }
      Response response = new Response();
      response.setResponseAsString(method.getResponseBodyAsString());
      log(response.toString() + "\n");

      if (responseCode != OK) {
        try {
          throw new WeiboException(
              getCause(responseCode), response.asJSONObject(), method.getStatusCode());
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }
      return response;

    } catch (IOException ioe) {
      throw new WeiboException(ioe.getMessage(), ioe, responseCode);
    } finally {
      method.releaseConnection();
    }
  }
 private HTTPClientResponseResolver createResponseResolver(
     final HttpMethod httpMethod, final Status status, final Header[] headers) {
   try {
     when(httpMethod.getStatusLine())
         .thenReturn(
             new org.apache.commons.httpclient.StatusLine(
                 String.format("HTTP/1.1 %s %s\r\n", status.getCode(), status.getName())));
   } catch (HttpException e) {
     throw new RuntimeException(e);
   }
   when(httpMethod.getStatusCode()).thenReturn(status.getCode());
   when(httpMethod.getResponseHeaders()).thenReturn(headers);
   return new TestableHTTPClientResponseResolver(httpMethod);
 }
 protected void retrieveResponseHeaders(HttpMethod method) {
   for (Header header : method.getResponseHeaders()) {
     String name = header.getName();
     String value = header.getValue();
     if (responseHeaders.containsKey(name)) {
       List<String> values = responseHeaders.get(name);
       values.add(value);
     } else {
       List<String> values = new ArrayList<String>();
       values.add(value);
       responseHeaders.put(name, values);
     }
   }
 }
Esempio n. 9
0
  protected <T> void processOnResponses(HttpMethod httpMethod, HttpInvocation<T> httpInvocation)
      throws Exception {
    int statusCode = httpMethod.getStatusCode();
    httpInvocation.onResponseStatus(statusCode);

    Header[] responseHeaders = httpMethod.getResponseHeaders();
    if (ArrayUtils.isNotEmpty(responseHeaders)) {
      for (Header header : responseHeaders) {
        httpInvocation.onResponseHeader(header.getName(), header.getValue());
      }
    }

    httpInvocation.onResponseBody(httpMethod.getResponseBodyAsStream());
  }
  public int getResponseContentLength(HttpMethod httpMethod) {
    Header[] headers = httpMethod.getResponseHeaders("Content-Length");
    if (headers.length == 0) {
      return -1;
    }

    for (int i = headers.length - 1; i >= 0; i--) {
      Header header = headers[i];
      try {
        return Integer.parseInt(header.getValue());
      } catch (NumberFormatException e) {

      }
      // See if we can have better luck with another header, if present
    }
    return -1;
  }
Esempio n. 11
0
  protected Exception populateHttpOperationFailedException(
      Exchange exchange, HttpMethod method, int responseCode)
      throws IOException, ClassNotFoundException {
    Exception answer;

    String uri = method.getURI().toString();
    String statusText =
        method.getStatusLine() != null ? method.getStatusLine().getReasonPhrase() : null;
    Map<String, String> headers = extractResponseHeaders(method.getResponseHeaders());

    Object responseBody = extractResponseBody(method, exchange);
    if (transferException && responseBody != null && responseBody instanceof Exception) {
      // if the response was a serialized exception then use that
      return (Exception) responseBody;
    }

    // make a defensive copy of the response body in the exception so its detached from the cache
    String copy = null;
    if (responseBody != null) {
      copy =
          exchange.getContext().getTypeConverter().convertTo(String.class, exchange, responseBody);
    }

    if (responseCode >= 300 && responseCode < 400) {
      String redirectLocation;
      Header locationHeader = method.getResponseHeader("location");
      if (locationHeader != null) {
        redirectLocation = locationHeader.getValue();
        answer =
            new HttpOperationFailedException(
                uri, responseCode, statusText, redirectLocation, headers, copy);
      } else {
        // no redirect location
        answer =
            new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
      }
    } else {
      // internal server error (error code 500)
      answer = new HttpOperationFailedException(uri, responseCode, statusText, null, headers, copy);
    }

    return answer;
  }
Esempio n. 12
0
  /**
   * Allows to send a GET request to the path passed using the http client
   *
   * @param path the path on which the request should be sent
   */
  public void sendGetRequest(final String path) throws Exception {
    String fullpath = path;
    if (path.startsWith("/")) fullpath = baseUrl + path;
    log.info("Sending GET request to " + fullpath);

    final HttpMethod method = new GetMethod(fullpath);
    try {
      for (final Map.Entry<String, String> header : requestHeaders.entrySet())
        method.setRequestHeader(header.getKey(), header.getValue());
      final int statusCode = httpClient.executeMethod(method);
      response =
          new ResponseWrapper(
              method.getResponseBodyAsString(), method.getResponseHeaders(), statusCode);
    } catch (final IOException e) {
      log.error(e.getMessage(), e);
      throw e;
    } finally {
      method.releaseConnection();
    }
  }
Esempio n. 13
0
  /**
   * Executes the {@link HttpMethod} passed in and sends the proxy response back to the client via
   * the given {@link HttpServletResponse}
   *
   * @param httpMethodProxyRequest An object representing the proxy request to be made
   * @param httpServletResponse An object by which we can send the proxied response back to the
   *     client
   * @throws IOException Can be thrown by the {@link HttpClient}.executeMethod
   * @throws ServletException Can be thrown to indicate that another error has occurred
   */
  private void executeProxyRequest(
      HttpMethod httpMethodProxyRequest,
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse)
      throws IOException, ServletException {
    // Create a default HttpClient
    HttpClient httpClient = new HttpClient();
    httpMethodProxyRequest.setFollowRedirects(false);
    // Execute the request
    int intProxyResponseCode = httpClient.executeMethod(httpMethodProxyRequest);

    // Check if the proxy response is a redirect
    // The following code is adapted from org.tigris.noodle.filters.CheckForRedirect
    // Hooray for open source software
    if (intProxyResponseCode >= HttpServletResponse.SC_MULTIPLE_CHOICES /* 300 */
        && intProxyResponseCode < HttpServletResponse.SC_NOT_MODIFIED /* 304 */) {
      String stringStatusCode = Integer.toString(intProxyResponseCode);
      String stringLocation =
          httpMethodProxyRequest.getResponseHeader(STRING_LOCATION_HEADER).getValue();
      if (stringLocation == null) {
        throw new ServletException(
            "Recieved status code: "
                + stringStatusCode
                + " but no "
                + STRING_LOCATION_HEADER
                + " header was found in the response");
      }
      // Modify the redirect to go to this proxy servlet rather that the proxied host
      String stringMyHostName = httpServletRequest.getServerName();
      if (httpServletRequest.getServerPort() != 80) {
        stringMyHostName += ":" + httpServletRequest.getServerPort();
      }
      stringMyHostName += httpServletRequest.getContextPath();
      httpServletResponse.sendRedirect(
          stringLocation.replace(getProxyHostAndPort() + this.getProxyPath(), stringMyHostName));
      return;
    } else if (intProxyResponseCode == HttpServletResponse.SC_NOT_MODIFIED) {
      // 304 needs special handling.  See:
      // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
      // We get a 304 whenever passed an 'If-Modified-Since'
      // header and the data on disk has not changed; server
      // responds w/ a 304 saying I'm not going to send the
      // body because the file has not changed.
      httpServletResponse.setIntHeader(STRING_CONTENT_LENGTH_HEADER_NAME, 0);
      httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
      return;
    }

    // Pass the response code back to the client
    httpServletResponse.setStatus(intProxyResponseCode);

    // Pass response headers back to the client
    Header[] headerArrayResponse = httpMethodProxyRequest.getResponseHeaders();
    for (Header header : headerArrayResponse) {
      httpServletResponse.setHeader(header.getName(), header.getValue());
    }

    // Send the content to the client
    InputStream inputStreamProxyResponse = httpMethodProxyRequest.getResponseBodyAsStream();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStreamProxyResponse);
    OutputStream outputStreamClientResponse = httpServletResponse.getOutputStream();
    int intNextByte;
    while ((intNextByte = bufferedInputStream.read()) != -1) {
      outputStreamClientResponse.write(intNextByte);
    }
  }
 /** Get all response headers. */
 public Header[] getResponseHeaders() {
   return m_method.getResponseHeaders();
 }
  protected byte[] URLtoByteArray(
      String location,
      Http.Method method,
      Map<String, String> headers,
      Cookie[] cookies,
      Http.Auth auth,
      Http.Body body,
      List<Http.FilePart> fileParts,
      Map<String, String> parts,
      Http.Response response,
      boolean followRedirects)
      throws IOException {

    byte[] bytes = null;

    HttpMethod httpMethod = null;
    HttpState httpState = null;

    try {
      _cookies.set(null);

      if (location == null) {
        return null;
      } else if (!location.startsWith(Http.HTTP_WITH_SLASH)
          && !location.startsWith(Http.HTTPS_WITH_SLASH)) {

        location = Http.HTTP_WITH_SLASH + location;
      }

      HostConfiguration hostConfiguration = getHostConfiguration(location);

      HttpClient httpClient = getClient(hostConfiguration);

      if (method.equals(Http.Method.POST) || method.equals(Http.Method.PUT)) {

        if (method.equals(Http.Method.POST)) {
          httpMethod = new PostMethod(location);
        } else {
          httpMethod = new PutMethod(location);
        }

        if (body != null) {
          RequestEntity requestEntity =
              new StringRequestEntity(body.getContent(), body.getContentType(), body.getCharset());

          EntityEnclosingMethod entityEnclosingMethod = (EntityEnclosingMethod) httpMethod;

          entityEnclosingMethod.setRequestEntity(requestEntity);
        } else if (method.equals(Http.Method.POST)) {
          PostMethod postMethod = (PostMethod) httpMethod;

          processPostMethod(postMethod, fileParts, parts);
        }
      } else if (method.equals(Http.Method.DELETE)) {
        httpMethod = new DeleteMethod(location);
      } else if (method.equals(Http.Method.HEAD)) {
        httpMethod = new HeadMethod(location);
      } else {
        httpMethod = new GetMethod(location);
      }

      if (headers != null) {
        for (Map.Entry<String, String> header : headers.entrySet()) {
          httpMethod.addRequestHeader(header.getKey(), header.getValue());
        }
      }

      if ((method.equals(Http.Method.POST) || method.equals(Http.Method.PUT))
          && ((body != null)
              || ((fileParts != null) && !fileParts.isEmpty())
                  | ((parts != null) && !parts.isEmpty()))) {
      } else if (!hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
        httpMethod.addRequestHeader(
            HttpHeaders.CONTENT_TYPE, ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED);
      }

      if (!hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
        httpMethod.addRequestHeader(HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
      }

      httpState = new HttpState();

      if ((cookies != null) && (cookies.length > 0)) {
        org.apache.commons.httpclient.Cookie[] commonsCookies = toCommonsCookies(cookies);

        httpState.addCookies(commonsCookies);

        HttpMethodParams httpMethodParams = httpMethod.getParams();

        httpMethodParams.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
      }

      if (auth != null) {
        httpMethod.setDoAuthentication(true);

        httpState.setCredentials(
            new AuthScope(auth.getHost(), auth.getPort(), auth.getRealm()),
            new UsernamePasswordCredentials(auth.getUsername(), auth.getPassword()));
      }

      proxifyState(httpState, hostConfiguration);

      httpClient.executeMethod(hostConfiguration, httpMethod, httpState);

      Header locationHeader = httpMethod.getResponseHeader("location");

      if ((locationHeader != null) && !locationHeader.equals(location)) {
        String redirect = locationHeader.getValue();

        if (followRedirects) {
          return URLtoByteArray(
              redirect,
              Http.Method.GET,
              headers,
              cookies,
              auth,
              body,
              fileParts,
              parts,
              response,
              followRedirects);
        } else {
          response.setRedirect(redirect);
        }
      }

      InputStream inputStream = httpMethod.getResponseBodyAsStream();

      if (inputStream != null) {
        Header contentLength = httpMethod.getResponseHeader(HttpHeaders.CONTENT_LENGTH);

        if (contentLength != null) {
          response.setContentLength(GetterUtil.getInteger(contentLength.getValue()));
        }

        Header contentType = httpMethod.getResponseHeader(HttpHeaders.CONTENT_TYPE);

        if (contentType != null) {
          response.setContentType(contentType.getValue());
        }

        bytes = FileUtil.getBytes(inputStream);
      }

      for (Header header : httpMethod.getResponseHeaders()) {
        response.addHeader(header.getName(), header.getValue());
      }

      return bytes;
    } finally {
      try {
        if (httpState != null) {
          _cookies.set(toServletCookies(httpState.getCookies()));
        }
      } catch (Exception e) {
        _log.error(e, e);
      }

      try {
        if (httpMethod != null) {
          httpMethod.releaseConnection();
        }
      } catch (Exception e) {
        _log.error(e, e);
      }
    }
  }
  /**
   * 执行Http请求
   *
   * @param request
   * @return
   */
  public HttpResponse execute(HttpRequest request) {
    HttpClient httpclient = new HttpClient(connectionManager);

    // 设置连接超时
    int connectionTimeout = defaultConnectionTimeout;
    if (request.getConnectionTimeout() > 0) {
      connectionTimeout = request.getConnectionTimeout();
    }
    httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);

    // 设置回应超时
    int soTimeout = defaultSoTimeout;
    if (request.getTimeout() > 0) {
      soTimeout = request.getTimeout();
    }
    httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);

    // 设置等待ConnectionManager释放connection的时间
    httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);

    String charset = request.getCharset();
    charset = charset == null ? DEFAULT_CHARSET : charset;
    HttpMethod method = null;

    if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
      method = new GetMethod(request.getUrl());
      method.getParams().setCredentialCharset(charset);

      // parseNotifyConfig会保证使用GET方法时,request一定使用QueryString
      method.setQueryString(request.getQueryString());
    } else {
      method = new PostMethod(request.getUrl());
      ((PostMethod) method).addParameters(request.getParameters());
      method.addRequestHeader(
          "Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);
    }

    // 设置Http Header中的User-Agent属性
    method.addRequestHeader("User-Agent", "Mozilla/4.0");
    HttpResponse response = new HttpResponse();

    try {
      httpclient.executeMethod(method);
      if (request.getResultType().equals(HttpResultType.STRING)) {
        response.setStringResult(method.getResponseBodyAsString());
      } else if (request.getResultType().equals(HttpResultType.BYTES)) {
        response.setByteResult(method.getResponseBody());
      }
      response.setResponseHeaders(method.getResponseHeaders());
    } catch (UnknownHostException ex) {

      return null;
    } catch (IOException ex) {

      return null;
    } catch (Exception ex) {

      return null;
    } finally {
      method.releaseConnection();
    }
    return response;
  }
  /**
   * 执行Http请求
   *
   * @param request 请求数据
   * @param strParaFileName 文件类型的参数名
   * @param strFilePath 文件路径
   * @return
   * @throws HttpException, IOException
   */
  public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath)
      throws HttpException, IOException {
    HttpClient httpclient = new HttpClient(connectionManager);

    // 设置连接超时
    int connectionTimeout = defaultConnectionTimeout;
    if (request.getConnectionTimeout() > 0) {
      connectionTimeout = request.getConnectionTimeout();
    }
    httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);

    // 设置回应超时
    int soTimeout = defaultSoTimeout;
    if (request.getTimeout() > 0) {
      soTimeout = request.getTimeout();
    }
    httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);

    // 设置等待ConnectionManager释放connection的时间
    httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);

    String charset = request.getCharset();
    charset = charset == null ? DEFAULT_CHARSET : charset;
    HttpMethod method = null;

    // get模式且不带上传文件
    if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
      method = new GetMethod(request.getUrl());
      method.getParams().setCredentialCharset(charset);

      // parseNotifyConfig会保证使用GET方法时,request一定使用QueryString
      method.setQueryString(request.getQueryString());
    } else if (strParaFileName.equals("") && strFilePath.equals("")) {
      // post模式且不带上传文件
      method = new PostMethod(request.getUrl());
      ((PostMethod) method).addParameters(request.getParameters());
      method.addRequestHeader(
          "Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);
    } else {
      // post模式且带上传文件
      method = new PostMethod(request.getUrl());
      List<Part> parts = new ArrayList<Part>();
      for (int i = 0; i < request.getParameters().length; i++) {
        parts.add(
            new StringPart(
                request.getParameters()[i].getName(),
                request.getParameters()[i].getValue(),
                charset));
      }
      // 增加文件参数,strParaFileName是参数名,使用本地文件
      parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath))));

      // 设置请求体
      ((PostMethod) method)
          .setRequestEntity(
              new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams()));
    }

    // 设置Http Header中的User-Agent属性
    method.addRequestHeader("User-Agent", "Mozilla/4.0");
    HttpResponse response = new HttpResponse();

    try {
      httpclient.executeMethod(method);
      if (request.getResultType().equals(HttpResultType.STRING)) {
        response.setStringResult(method.getResponseBodyAsString());
      } else if (request.getResultType().equals(HttpResultType.BYTES)) {
        response.setByteResult(method.getResponseBody());
      }
      response.setResponseHeaders(method.getResponseHeaders());
    } catch (UnknownHostException ex) {

      return null;
    } catch (IOException ex) {

      return null;
    } catch (Exception ex) {

      return null;
    } finally {
      method.releaseConnection();
    }
    return response;
  }
Esempio n. 18
0
  /**
   * Executes the {@link HttpMethod} passed in and sends the proxy response back to the client via
   * the given {@link HttpServletResponse}.
   *
   * @param httpMethodProxyRequest An object representing the proxy request to be made
   * @param httpServletResponse An object by which we can send the proxied response back to the
   *     client
   * @throws IOException Can be thrown by the {@link HttpClient}.executeMethod
   * @throws ServletException Can be thrown to indicate that another error has occurred
   */
  private void executeProxyRequest(
      HttpMethod httpMethodProxyRequest,
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse)
      throws IOException, ServletException {
    // Create a default HttpClient
    HttpClient httpClient;
    httpClient = createClientWithLogin();
    httpMethodProxyRequest.setFollowRedirects(false);

    // Execute the request
    int intProxyResponseCode = httpClient.executeMethod(httpMethodProxyRequest);
    //        String response = httpMethodProxyRequest.getResponseBodyAsString();

    // Check if the proxy response is a redirect
    // The following code is adapted from org.tigris.noodle.filters.CheckForRedirect
    // Hooray for open source software
    if (intProxyResponseCode >= HttpServletResponse.SC_MULTIPLE_CHOICES /* 300 */
        && intProxyResponseCode < HttpServletResponse.SC_NOT_MODIFIED /* 304 */) {
      String stringStatusCode = Integer.toString(intProxyResponseCode);
      String stringLocation = httpMethodProxyRequest.getResponseHeader(HEADER_LOCATION).getValue();
      if (stringLocation == null) {
        throw new ServletException(
            "Received status code: "
                + stringStatusCode
                + " but no "
                + HEADER_LOCATION
                + " header was found in the response");
      }
      // Modify the redirect to go to this proxy servlet rather that the proxied host
      String stringMyHostName = httpServletRequest.getServerName();
      if (httpServletRequest.getServerPort() != 80) {
        stringMyHostName += ":" + httpServletRequest.getServerPort();
      }
      stringMyHostName += httpServletRequest.getContextPath();
      if (followRedirects) {
        httpServletResponse.sendRedirect(
            stringLocation.replace(getProxyHostAndPort() + proxyPath, stringMyHostName));
        return;
      }
    } else if (intProxyResponseCode == HttpServletResponse.SC_NOT_MODIFIED) {
      // 304 needs special handling. See:
      // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
      // We get a 304 whenever passed an 'If-Modified-Since'
      // header and the data on disk has not changed; server
      // responds w/ a 304 saying I'm not going to send the
      // body because the file has not changed.
      httpServletResponse.setIntHeader(HEADER_CONTENT_LENGTH, 0);
      httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
      return;
    }

    // Pass the response code back to the client
    httpServletResponse.setStatus(intProxyResponseCode);

    // Pass response headers back to the client
    Header[] headerArrayResponse = httpMethodProxyRequest.getResponseHeaders();
    for (Header header : headerArrayResponse) {
      if (header.getName().equals("Transfer-Encoding") && header.getValue().equals("chunked")
          || header.getName().equals("Content-Encoding") && header.getValue().equals("gzip")) {
        // proxy servlet does not support chunked encoding
      } else {
        httpServletResponse.setHeader(header.getName(), header.getValue());
      }
    }

    List<Header> responseHeaders = Arrays.asList(headerArrayResponse);

    // FIXME We should handle both String and bytes response in the same way:
    String response = null;
    byte[] bodyBytes = null;

    if (isBodyParameterGzipped(responseHeaders)) {
      LOGGER.trace("GZipped: true");
      if (!followRedirects && intProxyResponseCode == HttpServletResponse.SC_MOVED_TEMPORARILY) {
        response = httpMethodProxyRequest.getResponseHeader(HEADER_LOCATION).getValue();
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        intProxyResponseCode = HttpServletResponse.SC_OK;
        httpServletResponse.setHeader(HEADER_LOCATION, response);
        httpServletResponse.setContentLength(response.length());
      } else {
        bodyBytes = ungzip(httpMethodProxyRequest.getResponseBody());
        httpServletResponse.setContentLength(bodyBytes.length);
      }
    }

    if (httpServletResponse.getContentType() != null
        && httpServletResponse.getContentType().contains("text")) {
      LOGGER.trace("Received status code: {} Response: {}", intProxyResponseCode, response);
    } else {
      LOGGER.trace("Received status code: {} [Response is not textual]", intProxyResponseCode);
    }

    // Send the content to the client
    if (response != null) {
      httpServletResponse.getWriter().write(response);
    } else if (bodyBytes != null) {
      httpServletResponse.getOutputStream().write(bodyBytes);
    } else {
      IOUtils.copy(
          httpMethodProxyRequest.getResponseBodyAsStream(), httpServletResponse.getOutputStream());
    }
  }