Package org.xlightweb.client

Source Code of org.xlightweb.client.HttpClient

/*
*  Copyright (c) xlightweb.org, 2008 - 2009. All rights reserved.
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
* The latest copy of this software may be found on http://www.xlightweb.org/
*/
package org.xlightweb.client;

import java.io.Closeable;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.logging.Logger;

import javax.net.ssl.SSLContext;

import org.xlightweb.BodyDataSink;
import org.xlightweb.FutureResponseHandler;
import org.xlightweb.HttpRequest;
import org.xlightweb.HttpUtils;
import org.xlightweb.IFutureResponse;
import org.xlightweb.IHttpConnectHandler;
import org.xlightweb.IHttpRequest;
import org.xlightweb.IHttpRequestHandler;
import org.xlightweb.IHttpRequestHeader;
import org.xlightweb.IHttpResponse;
import org.xlightweb.IHttpResponseHandler;
import org.xlightweb.RequestHandlerChain;
import org.xlightweb.client.HttpClientConnection.ClientExchange;
import org.xlightweb.client.TransactionMonitor.Transaction;
import org.xlightweb.client.TransactionMonitor.TransactionLog;
import org.xsocket.ILifeCycle;
import org.xsocket.connection.IConnectionPool;



/**
* Higher level client-side abstraction of the client side endpoint. Internally, the HttpClient uses a pool
* of {@link HttpClientConnection} to perform the requests.  Example:
*
* <pre>
*   HttpClient httpClient = new HttpClient();
*  
*   // set some properties
*   httpClient.setFollowsRedirect(true); 
*   httpClient.setAutoHandleCookies(false);
*   // ...
*  
*   // perform a synchronous call
*   IHttpResponse response = httpClient.call(new GetRequest("http://www.gmx.com/index.html"));
*   System.out.println(response.getStatus());
*  
*   BlockingBodyDataSource bodyChannel = response.getBlockingBody();
*   System.out.println(bodyChannel.readString());
*  
*  
*   // perform an asynchronous request
*   MyResponseHandler respHdl = new MyResponseHandler();
*   httpClient.send(new HttpRequestHeader("GET", "http://www.gmx.com/index.html"), respHdl);
*  
*   //..
*  
*   httpClient.close();
* </pre> 
*
* @author grro@xlightweb.org
*/
public class HttpClient implements IHttpClientEndpoint, IConnectionPool, Closeable {
 
  private static final Logger LOG = Logger.getLogger(HttpClient.class.getName());
 
    public static final int DEFAULT_CREATION_MAX_WAIT_TIMEOUT = 60 * 1000;
 
  public static final int DEFAULT_POOLED_LIFE_TIMEOUT_MILLIS = 30 * 1000;
 
  public static final int DEFAULT_POOLED_IDLE_TIMEOUT_MILLIS = 3 * 1000;

  public static final int DEFAULT_MAX_REDIRECTS = 5;
  public static final boolean DEFAULT_TREAT_302_REDIRECT_AS_303 = false;
  public static final Long DEFAULT_RESPONSE_TIMEOUT_SEC = Long.MAX_VALUE;
 
  private int maxRedirects = DEFAULT_MAX_REDIRECTS;
  private boolean isTreat302RedirectAs303 = DEFAULT_TREAT_302_REDIRECT_AS_303;
 

  // pool
  private boolean isPooled = true;
  private final HttpClientConnectionPool pool;
 

    // auto supported handlers
    public static final boolean DEFAULT_FOLLOWS_REDIRECT = false;
    private boolean isFollowsRedirect = DEFAULT_FOLLOWS_REDIRECT;
    private final AutoRedirectHandler redirectHandler = new AutoRedirectHandler(HttpClient.this);

    public static final boolean DEFAULT_AUTOHANDLING_COOKIES = true;
    private boolean isAutohandlingCookies = DEFAULT_AUTOHANDLING_COOKIES;
    private final CookieHandler cookiesHandler = new CookieHandler();

    public static final boolean DEFAULT_PROXY_ACTIVATED = false;
    private boolean isProxyActivated = DEFAULT_PROXY_ACTIVATED;
    private final ProxyHandler proxyHandler = new ProxyHandler();

   
    public static final int DEFAULT_CACHE_SIZE = 0;
    private final CacheHandler cacheHandler = new CacheHandler(this, DEFAULT_CACHE_SIZE);
    private boolean isShowCache = false;
   
    private final RequestHandlerChain chain = new RequestHandlerChain();

 
  // the assigned session manager
  private SessionManager sessionManager = null;
 

  // statistics
  private long lastTimeRequestSentMillis = System.currentTimeMillis();

 
  // transaction monitor
  private TransactionMonitor transactionMonitor = null;
  private final TransactionLog transactionLog = new TransactionLog(0);

 
 
  /**
   * constructor
   */
  public HttpClient() {
    this(null, new IHttpRequestHandler[0]);
  }
 
 
 
  /**
   * constructor
   *
   * @param interceptors  interceptor
   */
  public HttpClient(IHttpRequestHandler... interceptors) {
    this(null, interceptors);
  }
 
 
 
  /**
   * constructor
   *
   * @param sslCtx   the ssl context to use
   */
  public HttpClient(SSLContext sslCtx) {
    this(sslCtx, new IHttpRequestHandler[0]);
  }

 
  /**
   * constructor
   *
   * @param sslCtx        the ssl context to use
   * @param interceptors  the interceptors
   */
  public HttpClient(SSLContext sslCtx, IHttpRequestHandler... interceptors) {
      if (sslCtx != null) {
      pool = new HttpClientConnectionPool(sslCtx);
    } else {
      pool = new HttpClientConnectionPool();
   
   
    setCreationMaxWaitMillis(DEFAULT_CREATION_MAX_WAIT_TIMEOUT);
    setPooledMaxIdleTimeMillis(DEFAULT_POOLED_IDLE_TIMEOUT_MILLIS);
    setPooledMaxLifeTimeMillis(DEFAULT_POOLED_LIFE_TIMEOUT_MILLIS);
   
    sessionManager = new SessionManager();
   

    proxyHandler.setSSLContext(sslCtx);
    for (IHttpRequestHandler interceptor : interceptors) {
        addInterceptor(interceptor);
    }
   
    resetChain();
    chain.onInit();
  }

 
 
 
  /**
   * adds an interceptor. Example:
   *
   * <pre>
   *  HttpClient httpClient = new HttpClient();
   * 
   *  LoadBalancerRequestInterceptor lbInterceptor = new LoadBalancerRequestInterceptor();
   *  lbInterceptor.addVirtualServer("http://customerService", "srv1:8030", "srv2:8030");
   *  httpClient.addInterceptor(lbInterceptor);
   * 
   *  // ...
   *  GetRequest request = new GetRequest("http://customerService/price?id=2336&amount=5656");
   *  IHttpResponse response = httpClient.call(request);
   *  //...
   *
   * </pre>
  
   * @param interceptor  the interceptor to add
   */
  public void addInterceptor(IHttpRequestHandler interceptor) {
      if (interceptor instanceof ILifeCycle) {
          ((ILifeCycle) interceptor).onInit();
      }
     
        if (!HttpUtils.isConnectHandlerWarningIsSuppressed() && (interceptor instanceof IHttpConnectHandler)) {
            LOG.warning("only IHttpRequestHandler is supported. The onConnect(...) method will not be called. (suppress this warning by setting system property org.xlightweb.httpConnectHandler.suppresswarning=true)");
        }
     
      chain.addLast(interceptor);
      resetChain();
  }
 
 
  private void resetChain() {
      chain.remove(cacheHandler);
      chain.remove(cookiesHandler);
      chain.remove(redirectHandler);
      chain.remove(proxyHandler);

      if (cacheHandler.getMaxCacheSizeBytes() > 0) {
          chain.addFirst(cacheHandler);
      }
     
      if (isFollowsRedirect == true) {
          chain.addFirst(redirectHandler);
      }
      
      if (isAutohandlingCookies == true) {
          chain.addFirst(cookiesHandler);
      }
      
      if (isProxyActivated) {
          chain.addLast(proxyHandler);
      }     
  }

 
 
  /**
   * sets if redirects should be followed
   * 
   * @param isFollowsRedirect true, if redirects should be followed
   */
  public void setFollowsRedirect(boolean isFollowsRedirect) {
      if (this.isFollowsRedirect == isFollowsRedirect) {
            return;
        }
       
        this.isFollowsRedirect = isFollowsRedirect;
        resetChain();
  }

 
  /**
   * returns true, if redirects should be followed
   * @return true, if redirects should be followed
   */
  public boolean getFollowsRedirect() {
      return isFollowsRedirect;
  }
 
 
  /**
   * sets if cookies should be auto handled
   *
   * @param isAutohandlingCookies true, if cookies should be auto handled
   */
  public void setAutoHandleCookies(boolean isAutohandlingCookies) {
      if (this.isAutohandlingCookies == isAutohandlingCookies) {
            return;
        }
        this.isAutohandlingCookies = isAutohandlingCookies;
        resetChain();
  }
 
 
    
    /**
     * sets the cache size (in kilo bytes)
     *
     * @param maxSizeKb the max cache size in bytes or 0 to deactivate caching
     */
    public void setCacheMaxSizeKB(int maxSizeKb) {
        cacheHandler.setMaxCacheSizeBytes(maxSizeKb * 1024);
        resetChain();
    }
   
   
    /**
     * returns the max cache size
     *
     * @return the max cache size
     */
    public int getCacheMaxSizeKB() {
        return (cacheHandler.getMaxCacheSizeBytes() / 1024);
    }
 
   
   
    /**
     * returns the cache size
     *
     * @return the cache size
     */
    public float getCacheSizeKB() {
        return ((float) cacheHandler.getCurrentCacheSizeBytes() / 1000);
    }
   
    /**
     * sets if the cache is shared between users
     *
     * @param isSharedCache true, if the cache is shared between users
     */
    public void setCacheShared(boolean isSharedCache) {
        cacheHandler.setSharedCache(isSharedCache);
    }
   
    /**
     * returns true, if the cache is shared between users
     *
     * @return true, if the cache is shared between users
     */
    public boolean isCacheShared() {
        return cacheHandler.isSharedCache();
    }
 
  /**
   * sets the proxy host to use. Example:
   *
   * <pre>
   * HttpClient httpClient = new HttpClient();
   *
   * // sets the proxy adress
   * httpClient.setProxyHost(host);
   * httpClient.setProxyPort(port);
   *
   * // set auth params (only necessary if proxy authentication is required)
   * httpClient.setProxyUser(user);
   * httpClient.setProxyPassword(pwd);
   *
   * // calling through the proxy  
   * IHttpResponse resp = httpClient.call(new GetRequest("http://www.gmx.com/");
   * // ...
   * </pre>
   *
   * @param proxyHost the proxy host or <null>
   */
  public void setProxyHost(String proxyHost) {
      proxyHandler.setProxyHost(proxyHost);
       
        if ((proxyHost != null) && (proxyHost.length() > 1)) {
            isProxyActivated = true;
        }  
        resetChain();
  }
 

  /**
   * sets the proxy port. Default is 80. For an example see {@link HttpClient#setProxyHost(String)}
   *
   * @param proxyPort the proxy port
   */
  public void setProxyPort(int proxyPort) {
      proxyHandler.setProxyPort(proxyPort);
  }

 
  /**
   * sets the secured proxy host. Example:
   *
   * <pre>
   * // SSL context has to be set to support SSL
   * HttpClient httpClient = new HttpClient(SSLContext.getDefault());
   *
   * // sets the secured proxy adress
   * httpClient.setProxySecuredHost(host);
   * httpClient.setProxySecuredPort(port);
   *
   * // calling through the proxy  
   * IHttpResponse resp = httpClient.call(new GetRequest("https://www.gmx.com/");
   * // ...
   * </pre>
   *
   * 
   *
   * @param proxyHost the secured proxy host or <null>
   */
  public void setProxySecuredHost(String proxyHost) {
        proxyHandler.setSecuredProxyHost(proxyHost);
       
        if ((proxyHost != null) && (proxyHost.length() > 1)) {
            isProxyActivated = true;
        }
        resetChain();
  }

 

  /**
   * sets the secured proxy port. Default is 443. For an example see {@link HttpClient#setProxySecuredHost(String)}
   *
   * @param proxyPort the proxy port
   */
  public void setProxySecuredPort(int proxyPort) {
      proxyHandler.setSecuredProxyPort(proxyPort);
  }

 
  /**
   * sets the user name for proxy authentification 
   * @param proxyUser  the user name
   */
  public void setProxyUser(String proxyUser) {
      proxyHandler.setProxyUser(proxyUser);
  }
 

  /**
   * sets the user password for proxy authentification 
   *  
   * @param proxyPassword the user password
   */
  public void setProxyPassword(String proxyPassword) {
      proxyHandler.setProxyPassword(proxyPassword);
  }

   
  /**
   * returns if cookies should be auto handled
   * @return true, if cookies should be auto handled
   */
  public boolean isAutohandleCookies() {
      return isAutohandlingCookies;
  }

 
  /**
   * returns the session manager
   *
   * @return the session manager
   */
  SessionManager getSessionManager() {
    return sessionManager;
  }
 
 
  /**
   * set the max redirects
   *
   * @param maxRedirects  the max redirects
   */
  public void setMaxRedirects(int maxRedirects) {
    this.maxRedirects = maxRedirects;
  }
 
 
  /**
   * get the max redirects
   *
   * @return the max redirects
   */
  public int getMaxRedirects() {
    return maxRedirects;
  }
 
 
  /**
   * sets if a 302 response should be treat as a 303 response
   * 
   * @param isTreat303RedirectAs302 true, if a 303 response should be treat a a 303 response
   */
  public void setTreat302RedirectAs303(boolean isTreat303RedirectAs302) {
    this.isTreat302RedirectAs303 = isTreat303RedirectAs302;
  }
 
 
 
  /**
   * gets if a 302 response should be treat as a 303 response
   *
   * @return true, if a 302 response should be treat as a 303 response
   */
  public boolean isTreat302RedirectAs303() {
    return isTreat302RedirectAs303;
  }
 
 
  /**
   * get the max size of the transaction log
   *
   * @return the max size of the transaction log
   */
  int getTransactionLogMaxSize() {
    return transactionLog.getMaxSize();
  }
 
 
 
  /**
   * returns the number of pending transactions
   *
   * @return the number of pending transactions
   */
  Integer getTransactionsPending() {
    if (transactionMonitor != null) {
      return transactionMonitor.getPendingTransactions();
    } else {
      return null;
    }
  }
 
 
 
  /**
   * sets the max size of the transaction log
   *
   * @param maxSize the max size of the transaction log
   */
  void setTransactionLogMaxSize(int maxSize) {
    transactionLog.setMaxSize(maxSize);
   
    if (maxSize == 0) {
      transactionMonitor = null;
    } else {
      transactionMonitor = new TransactionMonitor(transactionLog);
    }
   
    pool.setTranactionMonitor(transactionMonitor);
  }

 
  /**
   * set the worker pool which will be assigned to the connections for call back handling
   *
   * @param workerpool the worker pool
   */
  public void setWorkerpool(Executor workerpool) {
    pool.setWorkerpool(workerpool);
  }

 
  /**
   * returns the assigned worker pool
   *
   * @return  the assigned worker pool
   */
  Executor getWorkerpool() {
    return pool.getWorkerpool();
  }
 
 
  /**
   * @deprecated
   */
  public boolean isPooled() {
    return isPooled;
  }
 
 
  /**
   * @deprecated
   */
  public void setPooled(boolean isPooled) {
    if (!isPooled) {
      LOG.warning("isPooled is deprecated and will be ignored");
    }
    this.isPooled = isPooled;
  }
 
 
  /**
   * {@inheritDoc}
   */
  public void setResponseTimeoutMillis(long responseTimeoutMillis) {
    pool.setResponseTimeoutMillis(responseTimeoutMillis);
  }
 
 
  /**
   * {@inheritDoc}
   */
  public long getResponseTimeoutMillis() {
    return pool.getResponseTimeoutMillis();
  }

  /**
   * {@inheritDoc}
   */
  public final void setBodyDataReceiveTimeoutMillis(long bodyDataReceiveTimeoutMillis) {
    pool.setBodyDataReceiveTimeoutMillis(bodyDataReceiveTimeoutMillis);
  }

 

  /**
   * {@inheritDoc}
   */
  public void close() throws IOException {
    pool.close();

    chain.onDestroy();
    sessionManager.close();
    sessionManager = null;
  }
 


 
 
  /**
   * {@inheritDoc}
   */
  public boolean isOpen() {
    return pool.isOpen();
  }
 
 
  /**
   * returns a unique id
   *
   * @return the id
   */
  public String getId() {
    return Integer.toString(this.hashCode());
  }
 

  /**
   * {@inheritDoc}
   */
  public void addListener(ILifeCycle listener) {
    pool.addListener(listener);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public boolean removeListener(ILifeCycle listener) {
    return pool.removeListener(listener);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public void setPooledMaxIdleTimeMillis(int idleTimeoutMillis) {
    pool.setPooledMaxIdleTimeMillis(idleTimeoutMillis);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getPooledMaxIdleTimeMillis() {
    return pool.getPooledMaxIdleTimeMillis();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public void setPooledMaxLifeTimeMillis(int lifeTimeoutMillis) {
    pool.setPooledMaxLifeTimeMillis(lifeTimeoutMillis);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getPooledMaxLifeTimeMillis() {
    return pool.getPooledMaxLifeTimeMillis();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public long getCreationMaxWaitMillis() {
    return pool.getCreationMaxWaitMillis();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public void setCreationMaxWaitMillis(long maxWaitMillis) {
    pool.setCreationMaxWaitMillis(maxWaitMillis);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public void setMaxIdle(int maxIdle) {
    pool.setMaxIdle(maxIdle);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getMaxIdle() {
    return pool.getMaxIdle();
  }

 
 
  /**
   * {@inheritDoc}
   */
  public void setMaxActive(int maxActive) {
    pool.setMaxActive(maxActive);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getMaxActive() {
    return pool.getMaxActive();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getNumActive() {
    return pool.getNumActive();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getNumIdle() {
    return pool.getNumIdle();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  int getNumPendingGet() {
    return pool.getNumPendingGet();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getNumCreated() {
    return pool.getNumCreated();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public int getNumDestroyed() {
    return pool.getNumDestroyed();
  }
 
 
  /**
   * get the number of creation errors
   *
   * @return the number of creation errors
   */
    int getNumCreationError() {
      return pool.getNumCreationError();
    }
 
   
    /**
   * {@inheritDoc}
   */
    public int getNumTimeoutPooledMaxIdleTime() {
      return pool.getNumTimeoutPooledMaxIdleTime();
    }

    /**
   * {@inheritDoc}
   */
    public int getNumTimeoutPooledMaxLifeTime() {
      return pool.getNumTimeoutPooledMaxLifeTime();
    }
   
   
    int getNumCacheHit() {
        return cacheHandler.getCountCacheHit();
    }
  
   
    int getNumCacheMiss() {
        return cacheHandler.getCountCacheMiss();
    }
   
 
    /**
   * {@inheritDoc}
   */
  public List<String> getActiveConnectionInfos() {
    return pool.getActiveConnectionInfos();
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public List<String> getIdleConnectionInfos() {
    return pool.getIdleConnectionInfos();
  }

  boolean isCacheInfoDisplay() {
      return isShowCache;
  }
 
  void setCacheInfoDisplay(boolean isShowCache) {
      this.isShowCache = isShowCache;
  }
 
 
  List<String> getCacheInfo() {
      if (isShowCache) {
          return cacheHandler.getCacheInfo();
      } else {
          return null;
      }
    }
 
 
  /**
   * returns the transaction log
   * @return the transaction log
   */
  List<String> getTransactionInfos() {
    List<String> result = new ArrayList<String>();
    for (Transaction transaction : transactionLog.getTransactions()) {
      result.add(transaction.toString());
    }
    return result;
  }
 

   
  /**
   * {@inheritDoc}
   */
  public IHttpResponse call(IHttpRequest request) throws IOException, SocketTimeoutException {
    try {
      IFutureResponse futureResponse = send(request);
      return futureResponse.getResponse();
    } catch (InterruptedException ie) {
      throw new RuntimeException(ie);
    }
  }

 
  /**
   * {@inheritDoc}
   */ 
  public IFutureResponse send(IHttpRequest request) throws IOException, ConnectException {
        FutureResponseHandler responseHandler = new FutureResponseHandler();
        send(request, responseHandler);
       
        return responseHandler;
  }
 
 
  /**
   * {@inheritDoc}
   */
  public void send(IHttpRequest request, IHttpResponseHandler responseHandler) throws IOException, ConnectException {
    lastTimeRequestSentMillis = System.currentTimeMillis();
   
    // log trace if activated
    if (transactionMonitor != null) {
      transactionMonitor.register(request.getRequestHeader());
    }
 
    ClientExchange clientExchange = new ClientExchange(pool, sessionManager, responseHandler, request);
    chain.onRequest(clientExchange);
  }
 
 
 
 
  /**
   * {@inheritDoc}
   */
  public BodyDataSink send(IHttpRequestHeader requestHeader, int contentLength, IHttpResponseHandler responseHandler) throws IOException, ConnectException {
    requestHeader.setContentLength(contentLength);
    return sendInternal(requestHeader, responseHandler);
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  public BodyDataSink send(IHttpRequestHeader requestHeader, IHttpResponseHandler responseHandler) throws IOException, ConnectException {
    requestHeader.setTransferEncoding("chunked");
    return sendInternal(requestHeader, responseHandler);
  }
 
 
  private BodyDataSink sendInternal(IHttpRequestHeader requestHeader, IHttpResponseHandler responseHandler) throws IOException, ConnectException {
    lastTimeRequestSentMillis = System.currentTimeMillis();
   
    BodyDataSink dataSink = HttpClientConnection.newInMemoryBodyDataSink(requestHeader.getCharacterEncoding(), pool.getWorkerpool());
    IHttpRequest request = new HttpRequest(requestHeader, HttpClientConnection.getDataSourceOfInMemoryBodyDataSink(dataSink));

    send(request, responseHandler);   
    return dataSink;
  }
 
 

 
  /**
   * gets the time when the last request has been sent
   * 
   * @return the time when the last request has been sent
   */
  long getLastTimeRequestSentMillis() {
    return lastTimeRequestSentMillis;
  }
 
 
 
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(super.toString());
   
    sb.append("\r\nnumCreatedConnections " + getNumCreated());
    sb.append("\r\nnumCreationError " + getNumCreationError());
    sb.append("\r\nnumDestroyedConnections " + getNumDestroyed());
   
    List<String> active = getActiveConnectionInfos();
    if (active.isEmpty()) {
        sb.append("\r\nnumActiveConnections 0");
    } else {
        sb.append("\r\n" + active.size() + " active connections:");
        for (String connectionInfo : getActiveConnectionInfos()) {
          sb.append("\r\n " + connectionInfo);
        }
    }
   
    List<String> idle = getActiveConnectionInfos();
        if (idle.isEmpty()) {
            sb.append("\r\nnumIdleConnections 0");
        } else {
            sb.append("\r\n" + idle.size() + " idle connections:");
            for (String connectionInfo : getIdleConnectionInfos()) {
                sb.append("\r\n " + connectionInfo);
            }
        }

   
    sb.append("\r\ntransaction log:");
    for (String transactionInfo : getTransactionInfos()) {
      sb.append("\r\n " + transactionInfo);
    }
   
    return sb.toString();
 
}
TOP

Related Classes of org.xlightweb.client.HttpClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.