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 + -
显示快捷键?