/**
   * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number of
   * connections.
   */
  public void testMaxConnections() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(2);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection1 = connectionManager.getConnection(host1);
    HttpConnection connection2 = connectionManager.getConnection(host2);

    try {
      // this should fail quickly since the connection has not been released
      connectionManager.getConnectionWithTimeout(host2, 100);
      fail("ConnectionPoolTimeoutException should not be available");
    } catch (ConnectionPoolTimeoutException e) {
      // this should throw an exception
    }

    // release one of the connections
    connection2.releaseConnection();
    connection2 = null;

    try {
      // there should be a connection available now
      connection2 = connectionManager.getConnectionWithTimeout(host2, 100);
    } catch (ConnectionPoolTimeoutException e) {
      e.printStackTrace();
      fail("a httpConnection should have been available: " + e);
    }
  }
  /** Tests the MultiThreadedHttpConnectionManager's ability to reclaim unused connections. */
  public void testConnectionReclaiming() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection = connectionManager.getConnection(host1);
    // now release this connection
    connection.releaseConnection();
    connection = null;

    try {
      // the connection from host1 should be reclaimed
      connection = connectionManager.getConnectionWithTimeout(host2, 100);
    } catch (ConnectTimeoutException e) {
      e.printStackTrace();
      fail("a httpConnection should have been available: " + e);
    }
  }
  public void testGetConnection() {
    MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();

    HostConfiguration hostConfiguration = new HostConfiguration();
    hostConfiguration.setHost("www.nosuchserver.com", 80, "http");

    // Create a new connection
    HttpConnection conn = mgr.getConnection(hostConfiguration);
    // Validate the connection properties
    assertEquals("Host", "www.nosuchserver.com", conn.getHost());
    assertEquals("Port", 80, conn.getPort());
    // Release the connection
    mgr.releaseConnection(conn);

    // Create a new connection
    hostConfiguration.setHost("www.nosuchserver.com", -1, "https");
    conn = mgr.getConnection(hostConfiguration);
    // Validate the connection properties
    assertEquals("Host", "www.nosuchserver.com", conn.getHost());
    assertEquals("Port", 443, conn.getPort());
    // Release the connection
    mgr.releaseConnection(conn);

    // Create a new connection
    hostConfiguration.setHost("www.nowhere.org", 8080, "http");
    conn = mgr.getConnection(hostConfiguration);
    // Validate the connection properties
    assertEquals("Host", "www.nowhere.org", conn.getHost());
    assertEquals("Port", 8080, conn.getPort());
    // Release the connection
    mgr.releaseConnection(conn);
  }
Esempio n. 4
0
  /**
   * Obtem a timeline publica. Nao necessita de autenticacao, basicamente é um GET na URL
   * http://twitter.com/statuses/public_timeline.xml
   */
  public String getPublicTimeline() throws Exception {
    HttpClient client = new HttpClient();

    // get para obter a timeline publica
    GetMethod get = new GetMethod("/statuses/public_timeline.xml");

    // Criando o host, para onde sera enviada a requisicao
    HostConfiguration host = client.getHostConfiguration();
    host.setHost(new URI("http://twitter.com"));

    // executando o get na url de timeline publica do twitter
    client.executeMethod(host, get);

    // obtendo a resposta
    return get.getResponseBodyAsString();
  }
  public void testHostReusePreference() {

    final MultiThreadedHttpConnectionManager connectionManager =
        new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    final HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    final HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection = connectionManager.getConnection(host1);

    GetConnectionThread getHost1 = new GetConnectionThread(host1, connectionManager, 200);
    GetConnectionThread getHost2 = new GetConnectionThread(host2, connectionManager, 200);

    getHost2.start();
    getHost1.start();

    // give the threads some time to startup
    try {
      Thread.sleep(100);
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    }

    // after the connection to host1 is released it should be given to getHost1
    connection.releaseConnection();
    connection = null;

    try {
      getHost1.join();
      getHost2.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    assertNotSame(
        "Connection should have been given to someone",
        getHost1.getConnection(),
        getHost2.getConnection());
    assertNotNull("Connection should have been given to host1", getHost1.getConnection());
    assertNull("Connection should NOT have been given to host2", getHost2.getConnection());
  }
  public void testTimeout() {
    MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
    mgr.getParams().setDefaultMaxConnectionsPerHost(2);

    try {
      HostConfiguration hostConfig = new HostConfiguration();
      hostConfig.setHost("www.nosuchserver.com", 80, "http");

      HttpConnection conn1 = mgr.getConnection(hostConfig);
      HttpConnection conn2 = mgr.getConnection(hostConfig);

      HttpConnection conn3 = mgr.getConnectionWithTimeout(hostConfig, 1000);
      fail("Expected an HttpException.");

    } catch (ConnectTimeoutException e) {
      // Expected result
    }
  }
  /**
   * Tests that {@link MultiThreadedHttpConnectionManager#shutdown()} closes all resources and makes
   * the connection manger unusable.
   */
  public void testShutdown() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    // hold on to the only connection
    HttpConnection connection = connectionManager.getConnection(host1);

    // wait for a connection on another thread
    GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
    getConn.start();

    connectionManager.shutdown();

    // now release this connection, this should close the connection, but have no other effect
    connection.releaseConnection();
    connection = null;

    try {
      getConn.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    // this thread should have caught an exception without getting a connection
    assertNull("Not connection should have been checked out", getConn.getConnection());
    assertNotNull("There should have been an exception", getConn.getException());

    try {
      connectionManager.getConnection(host1);
      fail("An exception should have occurred");
    } catch (Exception e) {
      // this is expected
    }
  }
  protected void initHttpClient() {
    if (MockServer.isTestMode()) {
      return;
    }
    HostConfiguration hostConfiguration = new HostConfiguration();
    hostConfiguration.setHost(
        diamondConfigure.getDomainNameList().get(this.domainNamePos.get()),
        diamondConfigure.getPort());

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.closeIdleConnections(diamondConfigure.getPollingIntervalTime() * 10);

    HttpConnectionManagerParams params = new HttpConnectionManagerParams();
    params.setStaleCheckingEnabled(diamondConfigure.isConnectionStaleCheckingEnabled());
    params.setMaxConnectionsPerHost(hostConfiguration, diamondConfigure.getMaxHostConnections());
    params.setMaxTotalConnections(diamondConfigure.getMaxTotalConnections());
    params.setConnectionTimeout(diamondConfigure.getConnectionTimeout());
    params.setSoTimeout(60 * 1000);

    connectionManager.setParams(params);
    httpClient = new HttpClient(connectionManager);
    httpClient.setHostConfiguration(hostConfiguration);
  }
Esempio n. 9
0
 /**
  * Creates a new HTTP connection for the given host configuration.
  *
  * @param hostConfiguration the host/proxy/protocol to use
  */
 public HttpConnection(HostConfiguration hostConfiguration) {
   this(
       hostConfiguration.getProxyHost(),
       hostConfiguration.getProxyPort(),
       hostConfiguration.getHost(),
       hostConfiguration.getPort(),
       hostConfiguration.getProtocol());
   this.localAddress = hostConfiguration.getLocalAddress();
 }
  public void testHostConfiguration() {

    HostConfiguration hc1 = new HostConfiguration();
    hc1.setHost("http", 80, "http");

    HostConfiguration hc2 = new HostConfiguration();
    hc2.setHost("http", 80, "http");

    assertTrue(hc1.equals(hc2));
    assertTrue(hc2.equals(hc1));
  }
  /**
   * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number of
   * connections per host.
   */
  public void testMaxConnectionsPerHost() throws Exception {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(100);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HostConfiguration host3 = new HostConfiguration();
    host3.setHost("host3", -1, "http");

    connectionManager.getParams().setMaxConnectionsPerHost(host1, 3);
    connectionManager.getParams().setMaxConnectionsPerHost(host2, 2);

    // Host1
    HttpConnection connection1 = connectionManager.getConnectionWithTimeout(host1, 1000);
    HttpConnection connection2 = connectionManager.getConnectionWithTimeout(host1, 1000);
    HttpConnection connection3 = connectionManager.getConnectionWithTimeout(host1, 1000);
    try {
      // this should fail quickly since the connection has not been released
      connectionManager.getConnectionWithTimeout(host1, 100);
      fail("ConnectionPoolTimeoutException should not be available");
    } catch (ConnectionPoolTimeoutException e) {
      // expected
    }

    // Host2
    connection1 = connectionManager.getConnectionWithTimeout(host2, 1000);
    connection2 = connectionManager.getConnectionWithTimeout(host2, 1000);
    try {
      // this should fail quickly since the connection has not been released
      connectionManager.getConnectionWithTimeout(host2, 100);
      fail("ConnectionPoolTimeoutException should not be available");
    } catch (ConnectionPoolTimeoutException e) {
      // expected
    }

    // Host3 (should use the default per host value)
    connection1 = connectionManager.getConnectionWithTimeout(host3, 1000);
    try {
      // this should fail quickly since the connection has not been released
      connectionManager.getConnectionWithTimeout(host3, 100);
      fail("ConnectionPoolTimeoutException should not be available");
    } catch (ConnectionPoolTimeoutException e) {
      // expected
    }
  }
  public HttpConnection getConnection(HostConfiguration hostConfiguration) {

    // make sure the host and proxy are correct for this connection
    // close it and set the values if they are not
    if (!hostConfiguration.hostEquals(connection) || !hostConfiguration.proxyEquals(connection)) {

      if (connection.isOpen()) {
        connection.close();
      }

      connection.setHost(hostConfiguration.getHost());
      connection.setPort(hostConfiguration.getPort());
      connection.setProtocol(hostConfiguration.getProtocol());
      connection.setLocalAddress(hostConfiguration.getLocalAddress());

      connection.setProxyHost(hostConfiguration.getProxyHost());
      connection.setProxyPort(hostConfiguration.getProxyPort());
    } else {
      finishLastResponse(connection);
    }

    connectionReleased = false;
    return connection;
  }
Esempio n. 13
0
  /**
   * @param since last modified time to use
   * @param req
   * @param url if null, ignored
   * @param redirCount number of redirs we've done
   */
  public static HttpData getDataOnce(
      HttpServletRequest req,
      HttpServletResponse res,
      long since,
      String surl,
      int redirCount,
      int timeout)
      throws IOException, HttpException, DataSourceException, MalformedURLException {

    HttpMethodBase request = null;
    HostConfiguration hcfg = new HostConfiguration();

    /*
      [todo hqm 2006-02-01] Anyone know why this code was here? It is setting
      the mime type to something which just confuses the DHTML parser.

      if (res != null) {
        res.setContentType("application/x-www-form-urlencoded;charset=UTF-8");
        }
    */

    try {

      // TODO: [2002-01-09 bloch] cope with cache-control
      // response headers (no-store, no-cache, must-revalidate,
      // proxy-revalidate).

      if (surl == null) {
        surl = getURL(req);
      }
      if (surl == null || surl.equals("")) {
        throw new MalformedURLException(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="url is empty or null"
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-312"));
      }

      String reqType = "";
      String headers = "";

      if (req != null) {
        reqType = req.getParameter("reqtype");
        headers = req.getParameter("headers");
      }

      boolean isPost = false;
      mLogger.debug("reqtype = " + reqType);

      if (reqType != null && reqType.equals("POST")) {
        request = new LZPostMethod();
        request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        isPost = true;
        mLogger.debug("setting POST req method");
      } else if (reqType != null && reqType.equals("PUT")) {
        request = new LZPutMethod();
        // todo [hqm 2007] treat PUT like POST?
        isPost = true;
        mLogger.debug("setting PUT req method");
      } else if (reqType != null && reqType.equals("DELETE")) {
        request = new LZDeleteMethod();
        mLogger.debug("setting DELETE req method");
      } else {
        mLogger.debug("setting GET (default) req method");
        request = new LZGetMethod();
      }

      request.setHttp11(mUseHttp11);

      // Proxy the request headers
      if (req != null) {
        LZHttpUtils.proxyRequestHeaders(req, request);
      }

      // Set headers from query string
      if (headers != null && headers.length() > 0) {
        StringTokenizer st = new StringTokenizer(headers, "\n");
        while (st.hasMoreTokens()) {
          String h = st.nextToken();
          int i = h.indexOf(":");
          if (i > -1) {
            String n = h.substring(0, i);
            String v = h.substring(i + 2, h.length());
            request.setRequestHeader(n, v);
            mLogger.debug(
                /* (non-Javadoc)
                 * @i18n.test
                 * @org-mes="setting header " + p[0] + "=" + p[1]
                 */
                org.openlaszlo.i18n.LaszloMessages.getMessage(
                    HTTPDataSource.class.getName(), "051018-359", new Object[] {n, v}));
          }
        }
      }

      mLogger.debug("Parsing url");
      URI uri = LZHttpUtils.newURI(surl);
      try {
        hcfg.setHost(uri);
      } catch (Exception e) {
        throw new MalformedURLException(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="can't form uri from " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-376", new Object[] {surl}));
      }

      // This gets us the url-encoded (escaped) path and query string
      String path = uri.getEscapedPath();
      String query = uri.getEscapedQuery();
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="encoded path:  " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-389", new Object[] {path}));
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="encoded query: " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-397", new Object[] {query}));

      // This call takes a decoded (unescaped) path
      request.setPath(path);

      boolean hasQuery = (query != null && query.length() > 0);

      String rawcontent = null;
      // Newer rawpost protocol puts lzpostbody as a separate
      // top level query arg in the request.
      rawcontent = req.getParameter("lzpostbody");

      if (isPost) {
        // Older rawpost protocol put the "lzpostbody" arg
        // embedded in the "url" args's query args
        if (rawcontent == null && hasQuery) {
          rawcontent = findQueryArg("lzpostbody", query);
        }
        if (rawcontent != null) {
          // Get the unescaped query string
          ((EntityEnclosingMethod) request).setRequestBody(rawcontent);
        } else if (hasQuery) {
          StringTokenizer st = new StringTokenizer(query, "&");
          while (st.hasMoreTokens()) {
            String it = st.nextToken();
            int i = it.indexOf("=");
            if (i > 0) {
              String n = it.substring(0, i);
              String v = it.substring(i + 1, it.length());
              // POST encodes values during request
              ((PostMethod) request).addParameter(n, URLDecoder.decode(v, "UTF-8"));
            } else {
              mLogger.warn(
                  /* (non-Javadoc)
                   * @i18n.test
                   * @org-mes="ignoring bad token (missing '=' char) in query string: " + p[0]
                   */
                  org.openlaszlo.i18n.LaszloMessages.getMessage(
                      HTTPDataSource.class.getName(), "051018-429", new Object[] {it}));
            }
          }
        }
      } else {
        // This call takes an encoded (escaped) query string
        request.setQueryString(query);
      }

      // Put in the If-Modified-Since headers
      if (since != -1) {
        String lms = LZHttpUtils.getDateString(since);
        request.setRequestHeader(LZHttpUtils.IF_MODIFIED_SINCE, lms);
        mLogger.debug(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="proxying lms: " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-450", new Object[] {lms}));
      }

      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="setting up http client"
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-460"));
      HttpClient htc = null;
      if (mConnectionMgr != null) {
        htc = new HttpClient(mConnectionMgr);
      } else {
        htc = new HttpClient();
      }

      htc.setHostConfiguration(hcfg);

      // This is the data timeout
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="timeout set to " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-478", new Object[] {new Integer(timeout)}));
      htc.setTimeout(timeout);

      // Set connection timeout the same
      htc.setConnectionTimeout(mConnectionTimeout);

      // Set timeout for getting a connection
      htc.setHttpConnectionFactoryTimeout(mConnectionPoolTimeout);

      // TODO: [2003-03-05 bloch] this should be more configurable (per app?)
      if (!isPost) {
        request.setFollowRedirects(mFollowRedirects > 0);
      }

      long t1 = System.currentTimeMillis();
      mLogger.debug("starting remote request");
      int rc = htc.executeMethod(hcfg, request);
      String status = HttpStatus.getStatusText(rc);
      if (status == null) {
        status = "" + rc;
      }
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="remote response status: " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-504", new Object[] {status}));

      HttpData data = null;
      if (isRedirect(rc) && mFollowRedirects > redirCount) {
        String loc = request.getResponseHeader("Location").toString();
        String hostURI = loc.substring(loc.indexOf(": ") + 2, loc.length());
        mLogger.info(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="Following URL from redirect: " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-517", new Object[] {hostURI}));
        long t2 = System.currentTimeMillis();
        if (timeout > 0) {
          timeout -= (t2 - t1);
          if (timeout < 0) {
            throw new InterruptedIOException(
                /* (non-Javadoc)
                 * @i18n.test
                 * @org-mes=p[0] + " timed out after redirecting to " + p[1]
                 */
                org.openlaszlo.i18n.LaszloMessages.getMessage(
                    HTTPDataSource.class.getName(), "051018-529", new Object[] {surl, loc}));
          }
        }

        data = getDataOnce(req, res, since, hostURI, redirCount++, timeout);
      } else {
        data = new HttpData(request, rc);
      }

      if (req != null && res != null) {
        // proxy response headers
        LZHttpUtils.proxyResponseHeaders(request, res, req.isSecure());
      }

      return data;

    } catch (ConnectTimeoutException ce) {
      // Transduce to an InterrupedIOException, since lps takes these to be timeouts.
      if (request != null) {
        request.releaseConnection();
      }
      throw new InterruptedIOException(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="connecting to " + p[0] + ":" + p[1] + " timed out beyond " + p[2] + " msecs."
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(),
              "051018-557",
              new Object[] {
                hcfg.getHost(), new Integer(hcfg.getPort()), new Integer(mConnectionTimeout)
              }));
    } catch (HttpRecoverableException hre) {
      if (request != null) {
        request.releaseConnection();
      }
      throw hre;
    } catch (HttpException e) {
      if (request != null) {
        request.releaseConnection();
      }
      throw e;
    } catch (IOException ie) {
      if (request != null) {
        request.releaseConnection();
      }
      throw ie;
    } catch (RuntimeException e) {
      if (request != null) {
        request.releaseConnection();
      }
      throw e;
    }
  }
Esempio n. 14
0
  /**
   * Process the redirect response.
   *
   * @return <code>true</code> if the redirect was successful
   */
  private boolean processRedirectResponse(final HttpMethod method) throws RedirectException {
    // get the location header to find out where to redirect to
    Header locationHeader = method.getResponseHeader("location");
    if (locationHeader == null) {
      // got a redirect response, but no location header
      LOG.error("Received redirect response " + method.getStatusCode() + " but no location header");
      return false;
    }
    String location = locationHeader.getValue();
    if (LOG.isDebugEnabled()) {
      LOG.debug("Redirect requested to location '" + location + "'");
    }

    // rfc2616 demands the location value be a complete URI
    // Location       = "Location" ":" absoluteURI
    URI redirectUri = null;
    URI currentUri = null;

    try {
      currentUri =
          new URI(
              this.conn.getProtocol().getScheme(),
              null,
              this.conn.getHost(),
              this.conn.getPort(),
              method.getPath());

      String charset = method.getParams().getUriCharset();
      redirectUri = new URI(location, true, charset);

      if (redirectUri.isRelativeURI()) {
        if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
          LOG.warn("Relative redirect location '" + location + "' not allowed");
          return false;
        } else {
          // location is incomplete, use current values for defaults
          LOG.debug("Redirect URI is not absolute - parsing as relative");
          redirectUri = new URI(currentUri, redirectUri);
        }
      } else {
        // Reset the default params
        method.getParams().setDefaults(this.params);
      }
      method.setURI(redirectUri);
      hostConfiguration.setHost(redirectUri);
    } catch (URIException ex) {
      throw new InvalidRedirectLocationException(
          "Invalid redirect location: " + location, location, ex);
    }

    if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
      if (this.redirectLocations == null) {
        this.redirectLocations = new HashSet();
      }
      this.redirectLocations.add(currentUri);
      try {
        if (redirectUri.hasQuery()) {
          redirectUri.setQuery(null);
        }
      } catch (URIException e) {
        // Should never happen
        return false;
      }

      if (this.redirectLocations.contains(redirectUri)) {
        throw new CircularRedirectException("Circular redirect to '" + redirectUri + "'");
      }
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Redirecting from '"
              + currentUri.getEscapedURI()
              + "' to '"
              + redirectUri.getEscapedURI());
    }
    // And finally invalidate the actual authentication scheme
    method.getHostAuthState().invalidate();
    return true;
  }
Esempio n. 15
0
  /**
   * Executes the method associated with this method director.
   *
   * @throws IOException
   * @throws HttpException
   */
  public void executeMethod(final HttpMethod method) throws IOException, HttpException {
    if (method == null) {
      throw new IllegalArgumentException("Method may not be null");
    }
    // Link all parameter collections to form the hierarchy:
    // Global -> HttpClient -> HostConfiguration -> HttpMethod
    this.hostConfiguration.getParams().setDefaults(this.params);
    method.getParams().setDefaults(this.hostConfiguration.getParams());

    // Generate default request headers
    Collection defaults =
        (Collection) this.hostConfiguration.getParams().getParameter(HostParams.DEFAULT_HEADERS);
    if (defaults != null) {
      Iterator i = defaults.iterator();
      while (i.hasNext()) {
        method.addRequestHeader((Header) i.next());
      }
    }

    try {
      int maxRedirects = this.params.getIntParameter(HttpClientParams.MAX_REDIRECTS, 100);

      for (int redirectCount = 0; ; ) {

        // make sure the connection we have is appropriate
        if (this.conn != null && !hostConfiguration.hostEquals(this.conn)) {
          this.conn.setLocked(false);
          this.conn.releaseConnection();
          this.conn = null;
        }

        // get a connection, if we need one
        if (this.conn == null) {
          this.conn =
              connectionManager.getConnectionWithTimeout(
                  hostConfiguration, this.params.getConnectionManagerTimeout());
          this.conn.setLocked(true);
          if (this.params.isAuthenticationPreemptive() || this.state.isAuthenticationPreemptive()) {
            LOG.debug("Preemptively sending default basic credentials");
            method.getHostAuthState().setPreemptive();
            method.getHostAuthState().setAuthAttempted(true);
            if (this.conn.isProxied() && !this.conn.isSecure()) {
              method.getProxyAuthState().setPreemptive();
              method.getProxyAuthState().setAuthAttempted(true);
            }
          }
        }
        authenticate(method);
        executeWithRetry(method);
        if (this.connectMethod != null) {
          fakeResponse(method);
          break;
        }

        boolean retry = false;
        if (isRedirectNeeded(method)) {
          if (processRedirectResponse(method)) {
            retry = true;
            ++redirectCount;
            if (redirectCount >= maxRedirects) {
              LOG.error("Narrowly avoided an infinite loop in execute");
              throw new RedirectException("Maximum redirects (" + maxRedirects + ") exceeded");
            }
            if (LOG.isDebugEnabled()) {
              LOG.debug("Execute redirect " + redirectCount + " of " + maxRedirects);
            }
          }
        }
        if (isAuthenticationNeeded(method)) {
          if (processAuthenticationResponse(method)) {
            LOG.debug("Retry authentication");
            retry = true;
          }
        }
        if (!retry) {
          break;
        }
        // retry - close previous stream.  Caution - this causes
        // responseBodyConsumed to be called, which may also close the
        // connection.
        if (method.getResponseBodyAsStream() != null) {
          method.getResponseBodyAsStream().close();
        }
      } // end of retry loop
    } finally {
      if (this.conn != null) {
        this.conn.setLocked(false);
      }
      // If the response has been fully processed, return the connection
      // to the pool.  Use this flag, rather than other tests (like
      // responseStream == null), as subclasses, might reset the stream,
      // for example, reading the entire response into a file and then
      // setting the file as the stream.
      if ((releaseConnection || method.getResponseBodyAsStream() == null) && this.conn != null) {
        this.conn.releaseConnection();
      }
    }
  }