private HttpMethod createProxyRequest(String targetUrl, HttpServletRequest request)
      throws IOException {
    URI targetUri;
    try {
      targetUri = new URI(uriEncode(targetUrl));
    } catch (URISyntaxException e) {
      throw new RuntimeException(e);
    }

    HttpMethod commonsHttpMethod =
        httpMethodProvider.getMethod(request.getMethod(), targetUri.toString());

    commonsHttpMethod.setFollowRedirects(false);

    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
      String headerName = headerNames.nextElement();
      Enumeration<String> headerVals = request.getHeaders(headerName);
      while (headerVals.hasMoreElements()) {
        String headerValue = headerVals.nextElement();
        headerValue = headerFilter.processRequestHeader(headerName, headerValue);
        if (headerValue != null) {
          commonsHttpMethod.addRequestHeader(new Header(headerName, headerValue));
        }
      }
    }

    return commonsHttpMethod;
  }
  @Override
  public int executeMethod(HttpMethod method) throws IOException, HttpException {
    try { // just to log
      boolean customRedirectionNeeded = false;

      try {
        method.setFollowRedirects(mFollowRedirects);
      } catch (Exception e) {
        /*
           if (mFollowRedirects)
        	Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName()
        		+ " method, custom redirection will be used if needed");
        */
        customRedirectionNeeded = mFollowRedirects;
      }

      Log_OC.d(
          TAG + " #" + mInstanceNumber, "REQUEST " + method.getName() + " " + method.getPath());

      //	        logCookiesAtRequest(method.getRequestHeaders(), "before");
      //	        logCookiesAtState("before");

      int status = super.executeMethod(method);

      if (customRedirectionNeeded) {
        status = patchRedirection(status, method);
      }

      //	        logCookiesAtRequest(method.getRequestHeaders(), "after");
      //	        logCookiesAtState("after");
      //	        logSetCookiesAtResponse(method.getResponseHeaders());

      return status;

    } catch (IOException e) {
      Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occured", e);
      throw e;
    }
  }
  /**
   * Report to deliver engines that a portlet has been uploaded
   *
   * @param contentId contentId of portlet
   */
  private void updateDeliverEngines(Integer digitalAssetId) {
    List allUrls = CmsPropertyHandler.getInternalDeliveryUrls();
    allUrls.addAll(CmsPropertyHandler.getPublicDeliveryUrls());

    Iterator urlIterator = allUrls.iterator();
    while (urlIterator.hasNext()) {
      String url = (String) urlIterator.next() + "/DeployPortlet.action";

      try {
        HttpClient client = new HttpClient();

        // establish a connection within 5 seconds
        client.setConnectionTimeout(5000);

        // set the default credentials
        HttpMethod method = new GetMethod(url);
        method.setQueryString("digitalAssetId=" + digitalAssetId);
        method.setFollowRedirects(true);

        // execute the method
        client.executeMethod(method);
        StatusLine status = method.getStatusLine();
        if (status != null && status.getStatusCode() == 200) {
          log.info("Successfully deployed portlet at " + url);
        } else {
          log.warn("Failed to deploy portlet at " + url + ": " + status);
        }

        // clean up the connection resources
        method.releaseConnection();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    /*
    Properties props = CmsPropertyHandler.getProperties();
    for (Enumeration keys = props.keys(); keys.hasMoreElements();) {
        String key = (String) keys.nextElement();
        if (key.startsWith(PORTLET_DEPLOY_PREFIX)) {
            String url = props.getProperty(key);
            try {
                HttpClient client = new HttpClient();

                //establish a connection within 5 seconds
                client.setConnectionTimeout(5000);

                //set the default credentials
                HttpMethod method = new GetMethod(url);
                method.setQueryString("digitalAssetId=" + digitalAssetId);
                method.setFollowRedirects(true);

                //execute the method
                client.executeMethod(method);
                StatusLine status = method.getStatusLine();
                if (status != null && status.getStatusCode() == 200) {
                    log.info("Successfully deployed portlet at " + url);
                } else {
                    log.warn("Failed to deploy portlet at " + url + ": " + status);
                }

                //clean up the connection resources
                method.releaseConnection();
            } catch (Throwable e) {
                log.error(e.getMessage(), e);
            }
        }
    }
    */

  }
Example #4
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);
    }
  }
  public NamedList<Object> request(final SolrRequest request, ResponseParser processor)
      throws SolrServerException, IOException {
    HttpMethod method = null;
    InputStream is = null;
    SolrParams params = request.getParams();
    Collection<ContentStream> streams = requestWriter.getContentStreams(request);
    String path = requestWriter.getPath(request);
    if (path == null || !path.startsWith("/")) {
      path = "/select";
    }

    ResponseParser parser = request.getResponseParser();
    if (parser == null) {
      parser = _parser;
    }

    // The parser 'wt=' and 'version=' params are used instead of the original params
    ModifiableSolrParams wparams = new ModifiableSolrParams();
    wparams.set(CommonParams.WT, parser.getWriterType());
    wparams.set(CommonParams.VERSION, parser.getVersion());
    if (params == null) {
      params = wparams;
    } else {
      params = new DefaultSolrParams(wparams, params);
    }

    if (_invariantParams != null) {
      params = new DefaultSolrParams(_invariantParams, params);
    }

    int tries = _maxRetries + 1;
    try {
      while (tries-- > 0) {
        // Note: since we aren't do intermittent time keeping
        // ourselves, the potential non-timeout latency could be as
        // much as tries-times (plus scheduling effects) the given
        // timeAllowed.
        try {
          if (SolrRequest.METHOD.GET == request.getMethod()) {
            if (streams != null) {
              throw new SolrException(
                  SolrException.ErrorCode.BAD_REQUEST, "GET can't send streams!");
            }
            method = new GetMethod(_baseURL + path + ClientUtils.toQueryString(params, false));
          } else if (SolrRequest.METHOD.POST == request.getMethod()) {

            String url = _baseURL + path;
            boolean isMultipart = (streams != null && streams.size() > 1);

            if (streams == null || isMultipart) {
              PostMethod post = new PostMethod(url);
              post.getParams().setContentCharset("UTF-8");
              if (!this.useMultiPartPost && !isMultipart) {
                post.addRequestHeader(
                    "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
              }

              List<Part> parts = new LinkedList<Part>();
              Iterator<String> iter = params.getParameterNamesIterator();
              while (iter.hasNext()) {
                String p = iter.next();
                String[] vals = params.getParams(p);
                if (vals != null) {
                  for (String v : vals) {
                    if (this.useMultiPartPost || isMultipart) {
                      parts.add(new StringPart(p, v, "UTF-8"));
                    } else {
                      post.addParameter(p, v);
                    }
                  }
                }
              }

              if (isMultipart) {
                int i = 0;
                for (ContentStream content : streams) {
                  final ContentStream c = content;

                  String charSet = null;
                  String transferEncoding = null;
                  parts.add(
                      new PartBase(c.getName(), c.getContentType(), charSet, transferEncoding) {
                        @Override
                        protected long lengthOfData() throws IOException {
                          return c.getSize();
                        }

                        @Override
                        protected void sendData(OutputStream out) throws IOException {
                          InputStream in = c.getStream();
                          try {
                            IOUtils.copy(in, out);
                          } finally {
                            in.close();
                          }
                        }
                      });
                }
              }
              if (parts.size() > 0) {
                post.setRequestEntity(
                    new MultipartRequestEntity(
                        parts.toArray(new Part[parts.size()]), post.getParams()));
              }

              method = post;
            }
            // It is has one stream, it is the post body, put the params in the URL
            else {
              String pstr = ClientUtils.toQueryString(params, false);
              PostMethod post = new PostMethod(url + pstr);

              // Single stream as body
              // Using a loop just to get the first one
              final ContentStream[] contentStream = new ContentStream[1];
              for (ContentStream content : streams) {
                contentStream[0] = content;
                break;
              }
              if (contentStream[0] instanceof RequestWriter.LazyContentStream) {
                post.setRequestEntity(
                    new RequestEntity() {
                      public long getContentLength() {
                        return -1;
                      }

                      public String getContentType() {
                        return contentStream[0].getContentType();
                      }

                      public boolean isRepeatable() {
                        return false;
                      }

                      public void writeRequest(OutputStream outputStream) throws IOException {
                        ((RequestWriter.LazyContentStream) contentStream[0]).writeTo(outputStream);
                      }
                    });

              } else {
                is = contentStream[0].getStream();
                post.setRequestEntity(
                    new InputStreamRequestEntity(is, contentStream[0].getContentType()));
              }
              method = post;
            }
          } else {
            throw new SolrServerException("Unsupported method: " + request.getMethod());
          }
        } catch (NoHttpResponseException r) {
          // This is generally safe to retry on
          method.releaseConnection();
          method = null;
          if (is != null) {
            is.close();
          }
          // If out of tries then just rethrow (as normal error).
          if ((tries < 1)) {
            throw r;
          }
          // log.warn( "Caught: " + r + ". Retrying..." );
        }
      }
    } catch (IOException ex) {
      throw new SolrServerException("error reading streams", ex);
    }

    method.setFollowRedirects(_followRedirects);
    method.addRequestHeader("User-Agent", AGENT);
    if (_allowCompression) {
      method.setRequestHeader(new Header("Accept-Encoding", "gzip,deflate"));
    }

    try {
      // Execute the method.
      // System.out.println( "EXECUTE:"+method.getURI() );

      int statusCode = _httpClient.executeMethod(method);
      if (statusCode != HttpStatus.SC_OK) {
        StringBuilder msg = new StringBuilder();
        msg.append(method.getStatusLine().getReasonPhrase());
        msg.append("\n\n");
        msg.append(method.getStatusText());
        msg.append("\n\n");
        msg.append("request: " + method.getURI());
        throw new SolrException(statusCode, java.net.URLDecoder.decode(msg.toString(), "UTF-8"));
      }

      // Read the contents
      String charset = "UTF-8";
      if (method instanceof HttpMethodBase) {
        charset = ((HttpMethodBase) method).getResponseCharSet();
      }
      InputStream respBody = method.getResponseBodyAsStream();
      // Jakarta Commons HTTPClient doesn't handle any
      // compression natively.  Handle gzip or deflate
      // here if applicable.
      if (_allowCompression) {
        Header contentEncodingHeader = method.getResponseHeader("Content-Encoding");
        if (contentEncodingHeader != null) {
          String contentEncoding = contentEncodingHeader.getValue();
          if (contentEncoding.contains("gzip")) {
            // log.debug( "wrapping response in GZIPInputStream" );
            respBody = new GZIPInputStream(respBody);
          } else if (contentEncoding.contains("deflate")) {
            // log.debug( "wrapping response in InflaterInputStream" );
            respBody = new InflaterInputStream(respBody);
          }
        } else {
          Header contentTypeHeader = method.getResponseHeader("Content-Type");
          if (contentTypeHeader != null) {
            String contentType = contentTypeHeader.getValue();
            if (contentType != null) {
              if (contentType.startsWith("application/x-gzip-compressed")) {
                // log.debug( "wrapping response in GZIPInputStream" );
                respBody = new GZIPInputStream(respBody);
              } else if (contentType.startsWith("application/x-deflate")) {
                // log.debug( "wrapping response in InflaterInputStream" );
                respBody = new InflaterInputStream(respBody);
              }
            }
          }
        }
      }
      return processor.processResponse(respBody, charset);
    } catch (HttpException e) {
      throw new SolrServerException(e);
    } catch (IOException e) {
      throw new SolrServerException(e);
    } finally {
      method.releaseConnection();
      if (is != null) {
        is.close();
      }
    }
  }
  @Override
  public void executeMethod(final HttpMethod method, final ClientRequest cr) {
    final Map<String, Object> props = cr.getProperties();

    method.setDoAuthentication(true);

    final HttpMethodParams methodParams = method.getParams();

    // Set the handle cookies property
    if (!cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES)) {
      methodParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
    }

    // Set the interactive and credential provider properties
    if (cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_INTERACTIVE)) {
      CredentialsProvider provider =
          (CredentialsProvider) props.get(ApacheHttpClientConfig.PROPERTY_CREDENTIALS_PROVIDER);
      if (provider == null) {
        provider = DEFAULT_CREDENTIALS_PROVIDER;
      }
      methodParams.setParameter(CredentialsProvider.PROVIDER, provider);
    } else {
      methodParams.setParameter(CredentialsProvider.PROVIDER, null);
    }

    // Set the read timeout
    final Integer readTimeout = (Integer) props.get(ApacheHttpClientConfig.PROPERTY_READ_TIMEOUT);
    if (readTimeout != null) {
      methodParams.setSoTimeout(readTimeout);
    }

    if (method instanceof EntityEnclosingMethod) {
      final EntityEnclosingMethod entMethod = (EntityEnclosingMethod) method;

      if (cr.getEntity() != null) {
        final RequestEntityWriter re = getRequestEntityWriter(cr);
        final Integer chunkedEncodingSize =
            (Integer) props.get(ApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE);
        if (chunkedEncodingSize != null) {
          // There doesn't seems to be a way to set the chunk size.
          entMethod.setContentChunked(true);

          // It is not possible for a MessageBodyWriter to modify
          // the set of headers before writing out any bytes to
          // the OutputStream
          // This makes it impossible to use the multipart
          // writer that modifies the content type to add a boundary
          // parameter
          writeOutBoundHeaders(cr.getHeaders(), method);

          // Do not buffer the request entity when chunked encoding is
          // set
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return false;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  re.writeRequestEntity(out);
                }

                @Override
                public long getContentLength() {
                  return re.getSize();
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });

        } else {
          entMethod.setContentChunked(false);

          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try {
            re.writeRequestEntity(
                new CommittingOutputStream(baos) {

                  @Override
                  protected void commit() throws IOException {
                    writeOutBoundHeaders(cr.getMetadata(), method);
                  }
                });
          } catch (IOException ex) {
            throw new ClientHandlerException(ex);
          }

          final byte[] content = baos.toByteArray();
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return true;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  out.write(content);
                }

                @Override
                public long getContentLength() {
                  return content.length;
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });
        }
      }
    } else {
      writeOutBoundHeaders(cr.getHeaders(), method);

      // Follow redirects
      method.setFollowRedirects(
          cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_FOLLOW_REDIRECTS));
    }
    try {
      httpClient.executeMethod(
          getHostConfiguration(httpClient, props), method, getHttpState(props));
    } catch (Exception e) {
      method.releaseConnection();
      throw new ClientHandlerException(e);
    }
  }
Example #7
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());
    }
  }