49 import java.util.Map; |
49 import java.util.Map; |
50 import java.util.List; |
50 import java.util.List; |
51 import java.util.Locale; |
51 import java.util.Locale; |
52 import java.util.StringTokenizer; |
52 import java.util.StringTokenizer; |
53 import java.util.Iterator; |
53 import java.util.Iterator; |
54 import java.util.logging.Level; |
|
55 import java.util.logging.Logger; |
|
56 import sun.net.*; |
54 import sun.net.*; |
57 import sun.net.www.*; |
55 import sun.net.www.*; |
58 import sun.net.www.http.HttpClient; |
56 import sun.net.www.http.HttpClient; |
59 import sun.net.www.http.PosterOutputStream; |
57 import sun.net.www.http.PosterOutputStream; |
60 import sun.net.www.http.ChunkedInputStream; |
58 import sun.net.www.http.ChunkedInputStream; |
61 import sun.net.www.http.ChunkedOutputStream; |
59 import sun.net.www.http.ChunkedOutputStream; |
|
60 import sun.net.www.http.HttpCapture; |
62 import java.text.SimpleDateFormat; |
61 import java.text.SimpleDateFormat; |
63 import java.util.TimeZone; |
62 import java.util.TimeZone; |
64 import java.net.MalformedURLException; |
63 import java.net.MalformedURLException; |
65 import java.nio.ByteBuffer; |
64 import java.nio.ByteBuffer; |
66 |
65 |
68 * A class to represent an HTTP connection to a remote object. |
67 * A class to represent an HTTP connection to a remote object. |
69 */ |
68 */ |
70 |
69 |
71 |
70 |
72 public class HttpURLConnection extends java.net.HttpURLConnection { |
71 public class HttpURLConnection extends java.net.HttpURLConnection { |
73 |
|
74 private static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); |
|
75 |
72 |
76 static String HTTP_CONNECT = "CONNECT"; |
73 static String HTTP_CONNECT = "CONNECT"; |
77 |
74 |
78 static final String version; |
75 static final String version; |
79 public static final String userAgent; |
76 public static final String userAgent; |
302 final URL url, |
299 final URL url, |
303 final RequestorType authType) { |
300 final RequestorType authType) { |
304 return java.security.AccessController.doPrivileged( |
301 return java.security.AccessController.doPrivileged( |
305 new java.security.PrivilegedAction<PasswordAuthentication>() { |
302 new java.security.PrivilegedAction<PasswordAuthentication>() { |
306 public PasswordAuthentication run() { |
303 public PasswordAuthentication run() { |
307 if (logger.isLoggable(Level.FINEST)) { |
304 if (HttpCapture.isLoggable("FINEST")) { |
308 logger.finest("Requesting Authentication: host =" + host + " url = " + url); |
305 HttpCapture.finest("Requesting Authentication: host =" + host + " url = " + url); |
309 } |
306 } |
310 PasswordAuthentication pass = Authenticator.requestPasswordAuthentication( |
307 PasswordAuthentication pass = Authenticator.requestPasswordAuthentication( |
311 host, addr, port, protocol, |
308 host, addr, port, protocol, |
312 prompt, scheme, url, authType); |
309 prompt, scheme, url, authType); |
313 if (pass != null && logger.isLoggable(Level.FINEST)) { |
310 if (HttpCapture.isLoggable("FINEST")) { |
314 logger.finest("Authentication returned: " + pass.toString()); |
311 HttpCapture.finest("Authentication returned: " + (pass != null ? pass.toString() : "null")); |
315 } |
312 } |
316 return pass; |
313 return pass; |
317 } |
314 } |
318 }); |
315 }); |
319 } |
316 } |
464 // add them to the existing request headers |
461 // add them to the existing request headers |
465 setCookieHeader(); |
462 setCookieHeader(); |
466 |
463 |
467 setRequests=true; |
464 setRequests=true; |
468 } |
465 } |
469 if (logger.isLoggable(Level.FINE)) { |
466 if (HttpCapture.isLoggable("FINE")) { |
470 logger.fine(requests.toString()); |
467 HttpCapture.fine(requests.toString()); |
471 } |
468 } |
472 http.writeRequests(requests, poster); |
469 http.writeRequests(requests, poster); |
473 if (ps.checkError()) { |
470 if (ps.checkError()) { |
474 String proxyHost = http.getProxyHostUsed(); |
471 String proxyHost = http.getProxyHostUsed(); |
475 int proxyPort = http.getProxyPortUsed(); |
472 int proxyPort = http.getProxyPortUsed(); |
721 cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS)); |
718 cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS)); |
722 if ("https".equalsIgnoreCase(uri.getScheme()) |
719 if ("https".equalsIgnoreCase(uri.getScheme()) |
723 && !(cachedResponse instanceof SecureCacheResponse)) { |
720 && !(cachedResponse instanceof SecureCacheResponse)) { |
724 cachedResponse = null; |
721 cachedResponse = null; |
725 } |
722 } |
726 if (logger.isLoggable(Level.FINEST)) { |
723 if (HttpCapture.isLoggable("FINEST")) { |
727 logger.finest("Cache Request for " + uri + " / " + getRequestMethod()); |
724 HttpCapture.finest("Cache Request for " + uri + " / " + getRequestMethod()); |
728 if (cachedResponse != null) { |
725 HttpCapture.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null")); |
729 logger.finest("From cache: "+cachedResponse.toString()); |
|
730 } |
|
731 } |
726 } |
732 if (cachedResponse != null) { |
727 if (cachedResponse != null) { |
733 cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders()); |
728 cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders()); |
734 cachedInputStream = cachedResponse.getBody(); |
729 cachedInputStream = cachedResponse.getBody(); |
735 } |
730 } |
764 return ProxySelector.getDefault(); |
759 return ProxySelector.getDefault(); |
765 } |
760 } |
766 }); |
761 }); |
767 if (sel != null) { |
762 if (sel != null) { |
768 URI uri = sun.net.www.ParseUtil.toURI(url); |
763 URI uri = sun.net.www.ParseUtil.toURI(url); |
769 if (logger.isLoggable(Level.FINEST)) { |
764 if (HttpCapture.isLoggable("FINEST")) { |
770 logger.finest("ProxySelector Request for " + uri); |
765 HttpCapture.finest("ProxySelector Request for " + uri); |
771 } |
766 } |
772 Iterator<Proxy> it = sel.select(uri).iterator(); |
767 Iterator<Proxy> it = sel.select(uri).iterator(); |
773 Proxy p; |
768 Proxy p; |
774 while (it.hasNext()) { |
769 while (it.hasNext()) { |
775 p = it.next(); |
770 p = it.next(); |
781 // make sure to construct new connection if first |
776 // make sure to construct new connection if first |
782 // attempt failed |
777 // attempt failed |
783 http = getNewHttpClient(url, p, connectTimeout, false); |
778 http = getNewHttpClient(url, p, connectTimeout, false); |
784 http.setReadTimeout(readTimeout); |
779 http.setReadTimeout(readTimeout); |
785 } |
780 } |
786 if (logger.isLoggable(Level.FINEST)) { |
781 if (HttpCapture.isLoggable("FINEST")) { |
787 if (p != null) { |
782 if (p != null) { |
788 logger.finest("Proxy used: " + p.toString()); |
783 HttpCapture.finest("Proxy used: " + p.toString()); |
789 } |
784 } |
790 } |
785 } |
791 break; |
786 break; |
792 } catch (IOException ioex) { |
787 } catch (IOException ioex) { |
793 if (p != Proxy.NO_PROXY) { |
788 if (p != Proxy.NO_PROXY) { |
1013 // remove old Cookie header before setting new one. |
1008 // remove old Cookie header before setting new one. |
1014 requests.remove("Cookie"); |
1009 requests.remove("Cookie"); |
1015 |
1010 |
1016 URI uri = ParseUtil.toURI(url); |
1011 URI uri = ParseUtil.toURI(url); |
1017 if (uri != null) { |
1012 if (uri != null) { |
1018 if (logger.isLoggable(Level.FINEST)) { |
1013 if (HttpCapture.isLoggable("FINEST")) { |
1019 logger.finest("CookieHandler request for " + uri); |
1014 HttpCapture.finest("CookieHandler request for " + uri); |
1020 } |
1015 } |
1021 Map<String, List<String>> cookies |
1016 Map<String, List<String>> cookies |
1022 = cookieHandler.get( |
1017 = cookieHandler.get( |
1023 uri, requests.getHeaders(EXCLUDE_HEADERS)); |
1018 uri, requests.getHeaders(EXCLUDE_HEADERS)); |
1024 if (!cookies.isEmpty()) { |
1019 if (!cookies.isEmpty()) { |
1025 if (logger.isLoggable(Level.FINEST)) { |
1020 if (HttpCapture.isLoggable("FINEST")) { |
1026 logger.finest("Cookies retrieved: " + cookies.toString()); |
1021 HttpCapture.finest("Cookies retrieved: " + cookies.toString()); |
1027 } |
1022 } |
1028 for (Map.Entry<String, List<String>> entry : |
1023 for (Map.Entry<String, List<String>> entry : |
1029 cookies.entrySet()) { |
1024 cookies.entrySet()) { |
1030 String key = entry.getKey(); |
1025 String key = entry.getKey(); |
1031 // ignore all entries that don't have "Cookie" |
1026 // ignore all entries that don't have "Cookie" |
1152 |
1147 |
1153 if (!streaming()) { |
1148 if (!streaming()) { |
1154 writeRequests(); |
1149 writeRequests(); |
1155 } |
1150 } |
1156 http.parseHTTP(responses, pi, this); |
1151 http.parseHTTP(responses, pi, this); |
1157 if (logger.isLoggable(Level.FINE)) { |
1152 if (HttpCapture.isLoggable("FINE")) { |
1158 logger.fine(responses.toString()); |
1153 HttpCapture.fine(responses.toString()); |
1159 } |
1154 } |
1160 inputStream = http.getInputStream(); |
1155 inputStream = http.getInputStream(); |
1161 |
1156 |
1162 respCode = getResponseCode(); |
1157 respCode = getResponseCode(); |
1163 if (respCode == HTTP_PROXY_AUTH) { |
1158 if (respCode == HTTP_PROXY_AUTH) { |
1597 // There is no need to track progress in HTTP Tunneling, |
1592 // There is no need to track progress in HTTP Tunneling, |
1598 // so ProgressSource is null. |
1593 // so ProgressSource is null. |
1599 http.parseHTTP(responses, null, this); |
1594 http.parseHTTP(responses, null, this); |
1600 |
1595 |
1601 /* Log the response to the CONNECT */ |
1596 /* Log the response to the CONNECT */ |
1602 if (logger.isLoggable(Level.FINE)) { |
1597 if (HttpCapture.isLoggable("FINE")) { |
1603 logger.fine(responses.toString()); |
1598 HttpCapture.fine(responses.toString()); |
1604 } |
1599 } |
1605 |
1600 |
1606 statusLine = responses.getValue(0); |
1601 statusLine = responses.getValue(0); |
1607 StringTokenizer st = new StringTokenizer(statusLine); |
1602 StringTokenizer st = new StringTokenizer(statusLine); |
1608 st.nextToken(); |
1603 st.nextToken(); |
1725 requests.setIfNotSet("Accept", acceptString); |
1720 requests.setIfNotSet("Accept", acceptString); |
1726 |
1721 |
1727 setPreemptiveProxyAuthentication(requests); |
1722 setPreemptiveProxyAuthentication(requests); |
1728 |
1723 |
1729 /* Log the CONNECT request */ |
1724 /* Log the CONNECT request */ |
1730 if (logger.isLoggable(Level.FINE)) { |
1725 if (HttpCapture.isLoggable("FINE")) { |
1731 logger.fine(requests.toString()); |
1726 HttpCapture.fine(requests.toString()); |
1732 } |
1727 } |
1733 |
1728 |
1734 http.writeRequests(requests, null); |
1729 http.writeRequests(requests, null); |
1735 // remove CONNECT header |
1730 // remove CONNECT header |
1736 requests.set(0, null, null); |
1731 requests.set(0, null, null); |
2000 if (!ret.setHeaders(this, p, raw)) { |
1995 if (!ret.setHeaders(this, p, raw)) { |
2001 ret = null; |
1996 ret = null; |
2002 } |
1997 } |
2003 } |
1998 } |
2004 } |
1999 } |
2005 if (logger.isLoggable(Level.FINER)) { |
2000 if (HttpCapture.isLoggable("FINER")) { |
2006 logger.finer("Server Authentication for " + authhdr.toString() +" returned " + ret.toString()); |
2001 HttpCapture.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null")); |
2007 } |
2002 } |
2008 return ret; |
2003 return ret; |
2009 } |
2004 } |
2010 |
2005 |
2011 /* inclose will be true if called from close(), in which case we |
2006 /* inclose will be true if called from close(), in which case we |
2076 } |
2071 } |
2077 disconnectInternal(); |
2072 disconnectInternal(); |
2078 if (streaming()) { |
2073 if (streaming()) { |
2079 throw new HttpRetryException (RETRY_MSG3, stat, loc); |
2074 throw new HttpRetryException (RETRY_MSG3, stat, loc); |
2080 } |
2075 } |
2081 if (logger.isLoggable(Level.FINE)) { |
2076 if (HttpCapture.isLoggable("FINE")) { |
2082 logger.fine("Redirected from " + url + " to " + locUrl); |
2077 HttpCapture.fine("Redirected from " + url + " to " + locUrl); |
2083 } |
2078 } |
2084 |
2079 |
2085 // clear out old response headers!!!! |
2080 // clear out old response headers!!!! |
2086 responses = new MessageHeader(); |
2081 responses = new MessageHeader(); |
2087 if (stat == HTTP_USE_PROXY) { |
2082 if (stat == HTTP_USE_PROXY) { |