httpconnection.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 858 行 · 第 1/2 页

JAVA
858
字号
    Reaper reaper;    /**     * Private constructor to ensure singleton.     */    private Pool()    {    }    /**     * Tests for a matching connection.     *     * @param c connection to match.     * @param h the host name.     * @param p the port.     * @param sec true if using https.     *     * @return true if c matches h, p, and sec.     */    private static boolean matches(HTTPConnection c,                                   String h, int p, boolean sec)    {      return h.equals(c.hostname) && (p == c.port) && (sec == c.secure);    }    /**     * Get a pooled HTTPConnection.  If there is an existing idle     * connection to the requested server it is returned.  Otherwise a     * new connection is created.     *     * @param host the name of the host to connect to     * @param port the port on the host to connect to     * @param secure whether to use a secure connection     *     * @return the HTTPConnection.     */    synchronized HTTPConnection get(String host,                                    int port,                                    boolean secure)    {      String ttl =        SystemProperties.getProperty("classpath.net.http.keepAliveTTL");      connectionTTL = (ttl != null && ttl.length() > 0) ?        1000 * Math.max(1, Integer.parseInt(ttl)) : 10000;      String mc = SystemProperties.getProperty("http.maxConnections");      maxConnections = (mc != null && mc.length() > 0) ?        Math.max(Integer.parseInt(mc), 1) : 5;      if (maxConnections < 1)        maxConnections =  1;      HTTPConnection c = null;            ListIterator it = connectionPool.listIterator(0);      while (it.hasNext())        {          HTTPConnection cc = (HTTPConnection)it.next();          if (matches(cc, host, port, secure))            {              c = cc;              it.remove();              break;            }        }      if (c == null)        {          c = new HTTPConnection(host, port, secure);          c.setPool(this);        }      return c;    }    /**     * Put an idle HTTPConnection back into the pool.  If this causes     * the pool to be come too large, the oldest connection is removed     * and closed.     *     */    synchronized void put(HTTPConnection c)    {      c.timeLastUsed = System.currentTimeMillis();      connectionPool.addLast(c);      // maxConnections must always be >= 1      while (connectionPool.size() >= maxConnections)        removeOldest();      if (connectionTTL > 0 && null == reaper) {        // If there is a connectionTTL, then the reaper has removed        // any stale connections, so we don't have to check for stale        // now.  We do have to start a reaper though, as there is not        // one running now.        reaper = new Reaper();        Thread t = new Thread(reaper, "HTTPConnection.Reaper");        t.setDaemon(true);        t.start();      }    }    /**     * Remove the oldest connection from the pool and close it.     */    void removeOldest()    {      HTTPConnection cx = (HTTPConnection)connectionPool.removeFirst();      try        {          cx.closeConnection();        }      catch (IOException ioe)        {          // Ignore it.  We are just cleaning up.        }    }  }    /**   * The number of times this HTTPConnection has be used via keep-alive.   */  int useCount;  /**   * If this HTTPConnection is in the pool, the time it was put there.   */  long timeLastUsed;  /**   * Set the connection pool that this HTTPConnection is a member of.   * If left unset or set to null, it will not be a member of any pool   * and will not be a candidate for reuse.   *   * @param p the pool.   */  void setPool(Pool p)  {    pool = p;  }  /**   * Signal that this HTTPConnection is no longer needed and can be   * returned to the connection pool.   *   */  void release()  {    if (pool != null)      {        useCount++;        pool.put(this);              }    else      {        // If there is no pool, just close.        try          {            closeConnection();          }        catch (IOException ioe)          {            // Ignore it.  We are just cleaning up.          }      }  }  /**   * Creates a new request using this connection.   * @param method the HTTP method to invoke   * @param path the URI-escaped RFC2396 <code>abs_path</code> with   * optional query part   */  public Request newRequest(String method, String path)  {    if (method == null || method.length() == 0)      {        throw new IllegalArgumentException("method must have non-zero length");      }    if (path == null || path.length() == 0)      {        path = "/";      }    Request ret = new Request(this, method, path);    if ((secure && port != HTTPS_PORT) ||        (!secure && port != HTTP_PORT))      {        ret.setHeader("Host", hostname + ":" + port);      }    else      {        ret.setHeader("Host", hostname);      }    ret.setHeader("User-Agent", userAgent);    ret.setHeader("Connection", "keep-alive");    ret.setHeader("Accept-Encoding",                  "chunked;q=1.0, gzip;q=0.9, deflate;q=0.8, " +                  "identity;q=0.6, *;q=0");    if (cookieManager != null)      {        Cookie[] cookies = cookieManager.getCookies(hostname, secure, path);        if (cookies != null && cookies.length > 0)          {            StringBuilder buf = new StringBuilder();            buf.append("$Version=1");            for (int i = 0; i < cookies.length; i++)              {                buf.append(',');                buf.append(' ');                buf.append(cookies[i].toString());              }            ret.setHeader("Cookie", buf.toString());          }      }    return ret;  }  /**   * Closes this connection.   */  public void close()    throws IOException  {    closeConnection();  }  /**   * Retrieves the socket associated with this connection.   * This creates the socket if necessary.   */  protected synchronized Socket getSocket()    throws IOException  {    if (socket == null)      {        String connectHostname = hostname;        int connectPort = port;        if (isUsingProxy())          {            connectHostname = proxyHostname;            connectPort = proxyPort;          }        socket = new Socket();        InetSocketAddress address =          new InetSocketAddress(connectHostname, connectPort);        if (connectionTimeout > 0)          {            socket.connect(address, connectionTimeout);          }        else          {            socket.connect(address);          }        if (timeout > 0)          {            socket.setSoTimeout(timeout);          }        if (secure)          {            try              {                SSLSocketFactory factory = getSSLSocketFactory();                SSLSocket ss =                  (SSLSocket) factory.createSocket(socket, connectHostname,                                                   connectPort, true);                String[] protocols = { "TLSv1", "SSLv3" };                ss.setEnabledProtocols(protocols);                ss.setUseClientMode(true);                synchronized (handshakeCompletedListeners)                  {                    if (!handshakeCompletedListeners.isEmpty())                      {                        for (Iterator i =                             handshakeCompletedListeners.iterator();                             i.hasNext(); )                          {                            HandshakeCompletedListener l =                              (HandshakeCompletedListener) i.next();                            ss.addHandshakeCompletedListener(l);                          }                      }                  }                ss.startHandshake();                socket = ss;              }            catch (GeneralSecurityException e)              {                throw new IOException(e.getMessage());              }          }        in = socket.getInputStream();        in = new BufferedInputStream(in);        out = socket.getOutputStream();        out = new BufferedOutputStream(out);      }    return socket;  }  SSLSocketFactory getSSLSocketFactory()    throws GeneralSecurityException  {    if (sslSocketFactory == null)      {        TrustManager tm = new EmptyX509TrustManager();        SSLContext context = SSLContext.getInstance("SSL");        TrustManager[] trust = new TrustManager[] { tm };        context.init(null, trust, null);        sslSocketFactory = context.getSocketFactory();      }    return sslSocketFactory;  }  void setSSLSocketFactory(SSLSocketFactory factory)  {    sslSocketFactory = factory;  }  protected synchronized InputStream getInputStream()    throws IOException  {    if (socket == null)      {        getSocket();      }    return in;  }  protected synchronized OutputStream getOutputStream()    throws IOException  {    if (socket == null)      {        getSocket();      }    return out;  }  /**   * Closes the underlying socket, if any.   */  protected synchronized void closeConnection()    throws IOException  {    if (socket != null)      {        try          {            socket.close();          }        finally          {            socket = null;          }      }  }  /**   * Returns a URI representing the connection.   * This does not include any request path component.   */  protected String getURI()  {    StringBuilder buf = new StringBuilder();    buf.append(secure ? "https://" : "http://");    buf.append(hostname);    if (secure)      {        if (port != HTTPConnection.HTTPS_PORT)          {            buf.append(':');            buf.append(port);          }      }    else      {        if (port != HTTPConnection.HTTP_PORT)          {            buf.append(':');            buf.append(port);          }      }    return buf.toString();  }  /**   * Get the number of times the specified nonce has been seen by this   * connection.   */  int getNonceCount(String nonce)  {    if (nonceCounts == null)      {        return 0;      }    return((Integer) nonceCounts.get(nonce)).intValue();  }  /**   * Increment the number of times the specified nonce has been seen.   */  void incrementNonce(String nonce)  {    int current = getNonceCount(nonce);    if (nonceCounts == null)      {        nonceCounts = new HashMap();      }    nonceCounts.put(nonce, new Integer(current + 1));  }  // -- Events --    void addHandshakeCompletedListener(HandshakeCompletedListener l)  {    synchronized (handshakeCompletedListeners)      {        handshakeCompletedListeners.add(l);      }  }  void removeHandshakeCompletedListener(HandshakeCompletedListener l)  {    synchronized (handshakeCompletedListeners)      {        handshakeCompletedListeners.remove(l);      }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?