httpurlconnection.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,596 行 · 第 1/4 页
JAVA
1,596 行
/* * @(#)HttpURLConnection.java 1.86 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program 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 * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package sun.net.www.protocol.http;import java.net.URL;import java.net.URLConnection;import java.net.ProtocolException;import java.net.PasswordAuthentication;import java.net.Authenticator;import java.net.InetAddress;import java.net.UnknownHostException;import java.net.SocketTimeoutException;import java.io.*;import java.util.Date;import java.util.Map;import java.util.Locale;import java.util.StringTokenizer;import sun.net.*;import sun.net.www.*;import sun.net.www.http.HttpClient;import sun.net.www.http.PosterOutputStream;import sun.net.www.http.ChunkedInputStream;import java.text.SimpleDateFormat;import java.util.TimeZone;import java.net.MalformedURLException;/** * A class to represent an HTTP connection to a remote object. */public class HttpURLConnection extends java.net.HttpURLConnection { static final String version; public static final String userAgent; /* max # of allowed re-directs */ static final int defaultmaxRedirects = 20; static final int maxRedirects; /* Not all servers support the (Proxy)-Authentication-Info headers. * By default, we don't require them to be sent */ static final boolean validateProxy; static final boolean validateServer; static { maxRedirects = ((Integer)java.security.AccessController.doPrivileged( new sun.security.action.GetIntegerAction("http.maxRedirects", defaultmaxRedirects))).intValue(); version = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.version")); String agent = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("http.agent")); if (agent == null) { agent = "Java/"+version; } else { agent = agent + " Java/"+version; } userAgent = agent; validateProxy = ((Boolean)java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction( "http.auth.digest.validateProxy"))).booleanValue(); validateServer = ((Boolean)java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction( "http.auth.digest.validateServer"))).booleanValue(); } static final String httpVersion = "HTTP/1.1"; static final String acceptString = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"; // the following http request headers should NOT have their values // returned for security reasons. private static final String[] EXCLUDE_HEADERS = { "Proxy-Authorization", "Authorization" }; protected HttpClient http; protected Handler handler; /* output stream to server */ protected PrintStream ps = null; /* We only have a single static authenticator for now. * For backwards compatibility with JDK 1.1. Should be * eliminated for JDK 2.0. */ private static HttpAuthenticator defaultAuth; /* all the headers we send * NOTE: do *NOT* dump out the content of 'requests' in the * output or stacktrace since it may contain security-sensitive * headers such as those defined in EXCLUDE_HEADERS. */ private MessageHeader requests; /* The following two fields are only used with Digest Authentication */ String domain; /* The list of authentication domains */ DigestAuthentication.Parameters digestparams; /* Current credentials in use */ AuthenticationInfo currentProxyCredentials = null; AuthenticationInfo currentServerCredentials = null; boolean needToCheck = true; private boolean doingNTLM2ndStage = false; /* doing the 2nd stage of an NTLM server authentication */ private boolean doingNTLMp2ndStage = false; /* doing the 2nd stage of an NTLM proxy authentication */ Object authObj; /* Progress entry */ protected ProgressEntry pe; /* all the response headers we get back */ private MessageHeader responses; /* the stream _from_ the server */ private InputStream inputStream = null; /* post stream _to_ the server, if any */ private PosterOutputStream poster = null; /* Indicates if the std. request headers have been set in requests. */ private boolean setRequests=false; /* Indicates whether a request has already failed or not */ private boolean failedOnce=false; /* Remembered Exception, we will throw it again if somebody calls getInputStream after disconnect */ private Exception rememberedException = null; /* If we decide we want to reuse a client, we put it here */ private HttpClient reuseClient = null; /* * privileged request password authentication * */ private static PasswordAuthentication privilegedRequestPasswordAuthentication( final String host, final InetAddress addr, final int port, final String protocol, final String prompt, final String scheme) { return (PasswordAuthentication) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return Authenticator.requestPasswordAuthentication( host, addr, port, protocol, prompt, scheme); } }); } /* * checks the validity of http message header and throws * IllegalArgumentException if invalid. */ private void checkMessageHeader(String key, String value) { char LF = '\n'; int index = key.indexOf(LF); if (index != -1) { throw new IllegalArgumentException( "Illegal character(s) in message header field: " + key); } else { if (value == null) { return; } index = value.indexOf(LF); while (index != -1) { index++; if (index < value.length()) { char c = value.charAt(index); if ((c==' ') || (c=='\t')) { // ok, check the next occurrence index = value.indexOf(LF, index); continue; } } throw new IllegalArgumentException( "Illegal character(s) in message header value: " + value); } } } /* adds the standard key/val pairs to reqests if necessary & write to * given PrintStream */ private void writeRequests() throws IOException { /* print all message headers in the MessageHeader * onto the wire - all the ones we've set and any * others that have been set */ if (!setRequests) { /* We're very particular about the order in which we * set the request headers here. The order should not * matter, but some careless CGI programs have been * written to expect a very particular order of the * standard headers. To name names, the order in which * Navigator3.0 sends them. In particular, we make *sure* * to send Content-type: <> and Content-length:<> second * to last and last, respectively, in the case of a POST * request. */ if (!failedOnce) requests.prepend(method + " " + http.getURLFile()+" " + httpVersion, null); if (!getUseCaches()) { requests.setIfNotSet ("Cache-Control", "no-cache"); requests.setIfNotSet ("Pragma", "no-cache"); } requests.setIfNotSet("User-Agent", userAgent); int port = url.getPort(); String host = url.getHost(); if (port != -1 && port != 80) { host += ":" + String.valueOf(port); } requests.setIfNotSet("Host", host); requests.setIfNotSet("Accept", acceptString); /* * For HTTP/1.1 the default behavior is to keep connections alive. * However, we may be talking to a 1.0 server so we should set * keep-alive just in case, except if we have encountered an error * or if keep alive is disabled via a system property */ // Try keep-alive only on first attempt if (!failedOnce && http.getHttpKeepAliveSet()) { if (http.usingProxy) { requests.setIfNotSet("Proxy-Connection", "keep-alive"); } else { requests.setIfNotSet("Connection", "keep-alive"); } } // send any pre-emptive authentication if (http.usingProxy) { setPreemptiveProxyAuthentication(requests); } // Set modified since if necessary long modTime = getIfModifiedSince(); if (modTime != 0 ) { Date date = new Date(modTime); //use the preferred date format according to RFC 2068(HTTP1.1), // RFC 822 and RFC 1123 SimpleDateFormat fo = new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); fo.setTimeZone(TimeZone.getTimeZone("GMT")); requests.setIfNotSet("If-Modified-Since", fo.format(date)); } // check for preemptive authorization AuthenticationInfo sauth = AuthenticationInfo.getServerAuth(url); if (sauth != null && sauth.supportsPreemptiveAuthorization() ) { // Sets "Authorization" requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method)); currentServerCredentials = sauth; } if (poster != null) { /* add Content-Length & POST/PUT data */ synchronized (poster) { /* close it, so no more data can be added */ poster.close(); if (!method.equals("PUT")) { String type = "application/x-www-form-urlencoded"; requests.setIfNotSet("Content-Type", type); } requests.set("Content-Length", String.valueOf(poster.size())); } } setRequests=true; } http.writeRequests(requests, poster); if (ps.checkError()) { String proxyHost = http.getProxyHostUsed(); int proxyPort = http.getProxyPortUsed(); disconnectInternal(); if (failedOnce) { throw new IOException("Error writing to server"); } else { // try once more failedOnce=true; if (proxyHost != null) { setProxiedClient(url, proxyHost, proxyPort); } else { setNewClient (url); } ps = (PrintStream) http.getOutputStream(); connected=true; responses = new MessageHeader(); setRequests=false; writeRequests(); } } } /** * Create a new HttpClient object, bypassing the cache of * HTTP client objects/connections. * * @param url the URL being accessed */ protected void setNewClient (URL url) throws IOException { setNewClient(url, false); } /** * Obtain a HttpsClient object. Use the cached copy if specified. * * @param url the URL being accessed * @param useCache whether the cached connection should be used * if present */ protected void setNewClient (URL url, boolean useCache) throws IOException { http = HttpClient.New(url, useCache); } /** * Create a new HttpClient object, set up so that it uses * per-instance proxying to the given HTTP proxy. This * bypasses the cache of HTTP client objects/connections. * * @param url the URL being accessed * @param proxyHost the proxy host to use * @param proxyPort the proxy port to use */ protected void setProxiedClient (URL url, String proxyHost, int proxyPort) throws IOException { setProxiedClient(url, proxyHost, proxyPort, false); } /** * Obtain a HttpClient object, set up so that it uses per-instance * proxying to the given HTTP proxy. Use the cached copy of HTTP * client objects/connections if specified. * * @param url the URL being accessed * @param proxyHost the proxy host to use * @param proxyPort the proxy port to use * @param useCache whether the cached connection should be used * if present */ protected void setProxiedClient (URL url, String proxyHost, int proxyPort, boolean useCache) throws IOException { proxiedConnect(url, proxyHost, proxyPort, useCache); } protected void proxiedConnect(URL url, String proxyHost, int proxyPort, boolean useCache) throws IOException { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkConnect(proxyHost, proxyPort); } http = HttpClient.New (url, proxyHost, proxyPort, useCache); } protected HttpURLConnection(URL u, Handler handler) throws IOException { super(u); requests = new MessageHeader(); responses = new MessageHeader();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?