}
public synchronized InputStream getInputStream() throws IOException {
if (!doInput) {
throw new ProtocolException("Cannot read from URLConnection"
+ " if doInput=false (call setDoInput(true))");
}
if (rememberedException != null) {
if (rememberedException instanceof RuntimeException)
throw new RuntimeException(rememberedException);
else {
throw getChainedException((IOException)rememberedException);
}
}
if (inputStream != null) {
return inputStream;
}
if (streaming() ) {
if (strOutputStream == null) {
getOutputStream();
}
/* make sure stream is closed */
strOutputStream.close ();
if (!strOutputStream.writtenOK()) {
throw new IOException ("Incomplete output stream");
}
}
int redirects = 0;
int respCode = 0;
int cl = -1;
AuthenticationInfo serverAuthentication = null;
AuthenticationInfo proxyAuthentication = null;
AuthenticationHeader srvHdr = null;
// If the user has set either of these headers then do not remove them
isUserServerAuth = requests.getKey("Authorization") != -1;
isUserProxyAuth = requests.getKey("Proxy-Authorization") != -1;
try {
do {
if (!checkReuseConnection())
connect();
if (cachedInputStream != null) {
return cachedInputStream;
}
// Check if URL should be metered
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, method);
if (meteredInput) {
pi = new ProgressSource(url, method);
pi.beginTracking();
}
/* REMIND: This exists to fix the HttpsURLConnection subclass.
* Hotjava needs to run on JDK1.1FCS. Do proper fix once a
* proper solution for SSL can be found.
*/
ps = (PrintStream)http.getOutputStream();
if (!streaming()) {
writeRequests();
}
http.parseHTTP(responses, pi, this);
if(logger.isLoggable(Level.FINEST)) {
logger.fine(responses.toString());
}
inputStream = http.getInputStream();
respCode = getResponseCode();
if (respCode == HTTP_PROXY_AUTH) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (
RETRY_MSG1, HTTP_PROXY_AUTH);
}
// changes: add a 3rd parameter to the constructor of
// AuthenticationHeader, so that NegotiateAuthentication.
// isSupported can be tested.
// The other 2 appearances of "new AuthenticationHeader" is
// altered in similar ways.
AuthenticationHeader authhdr = new AuthenticationHeader (
"Proxy-Authenticate", responses, http.getProxyHostUsed()
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
resetProxyAuthentication(proxyAuthentication, authhdr);
if (proxyAuthentication != null) {
redirects++;
disconnectInternal();
continue;
}
} else {
/* in this case, only one header field will be present */
String raw = responses.findValue ("Proxy-Authenticate");
reset ();
if (!proxyAuthentication.setHeaders(this,
authhdr.headerParser(), raw)) {
disconnectInternal();
throw new IOException ("Authentication failure");
}
if (serverAuthentication != null && srvHdr != null &&
!serverAuthentication.setHeaders(this,
srvHdr.headerParser(), raw)) {
disconnectInternal ();
throw new IOException ("Authentication failure");
}
authObj = null;
doingNTLMp2ndStage = false;
continue;
}
}
// cache proxy authentication info
if (proxyAuthentication != null) {
// cache auth info on success, domain header not relevant.
proxyAuthentication.addToCache();
}
if (respCode == HTTP_UNAUTHORIZED) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (
RETRY_MSG2, HTTP_UNAUTHORIZED);
}
srvHdr = new AuthenticationHeader (
"WWW-Authenticate", responses, url.getHost().toLowerCase()
);
String raw = srvHdr.raw();
if (!doingNTLM2ndStage) {
if ((serverAuthentication != null)&&
!(serverAuthentication instanceof NTLMAuthentication)) {
if (serverAuthentication.isAuthorizationStale (raw)) {
/* we can retry with the current credentials */
disconnectInternal();
redirects++;
requests.set(serverAuthentication.getHeaderName(),
serverAuthentication.getHeaderValue(url, method));
currentServerCredentials = serverAuthentication;
setCookieHeader();
continue;
} else {
serverAuthentication.removeFromCache();
}
}
serverAuthentication = getServerAuthentication(srvHdr);
currentServerCredentials = serverAuthentication;
if (serverAuthentication != null) {
disconnectInternal();
redirects++; // don't let things loop ad nauseum
setCookieHeader();
continue;
}
} else {
reset ();
/* header not used for ntlm */
if (!serverAuthentication.setHeaders(this, null, raw)) {
disconnectInternal();
throw new IOException ("Authentication failure");
}
doingNTLM2ndStage = false;
authObj = null;
setCookieHeader();
continue;
}
}
// cache server authentication info
if (serverAuthentication != null) {
// cache auth info on success
if (!(serverAuthentication instanceof DigestAuthentication) ||
(domain == null)) {
if (serverAuthentication instanceof BasicAuthentication) {
// check if the path is shorter than the existing entry
String npath = AuthenticationInfo.reducePath (url.getPath());
String opath = serverAuthentication.path;
if (!opath.startsWith (npath) || npath.length() >= opath.length()) {
/* npath is longer, there must be a common root */
npath = BasicAuthentication.getRootPath (opath, npath);
}
// remove the entry and create a new one
BasicAuthentication a =
(BasicAuthentication) serverAuthentication.clone();
serverAuthentication.removeFromCache();
a.path = npath;
serverAuthentication = a;
}
serverAuthentication.addToCache();
} else {
// what we cache is based on the domain list in the request
DigestAuthentication srv = (DigestAuthentication)
serverAuthentication;
StringTokenizer tok = new StringTokenizer (domain," ");
String realm = srv.realm;
PasswordAuthentication pw = srv.pw;
digestparams = srv.params;
while (tok.hasMoreTokens()) {
String path = tok.nextToken();
try {
/* path could be an abs_path or a complete URI */
URL u = new URL (url, path);
DigestAuthentication d = new DigestAuthentication (
false, u, realm, "Digest", pw, digestparams);
d.addToCache ();
} catch (Exception e) {}
}
}
}
// some flags should be reset to its initialized form so that
// even after a redirect the necessary checks can still be
// preformed.
//serverAuthentication = null;
doingNTLMp2ndStage = false;
doingNTLM2ndStage = false;
if (!isUserServerAuth)
requests.remove("Authorization");
if (!isUserProxyAuth)
requests.remove("Proxy-Authorization");
if (respCode == HTTP_OK) {
checkResponseCredentials (false);
} else {
needToCheck = false;
}
// a flag need to clean
needToCheck = true;
if (followRedirect()) {
/* if we should follow a redirect, then the followRedirects()
* method will disconnect() and re-connect us to the new
* location
*/
redirects++;
// redirecting HTTP response may have set cookie, so
// need to re-generate request header
setCookieHeader();
continue;
}
try {
cl = Integer.parseInt(responses.findValue("content-length"));
} catch (Exception exc) { };
if (method.equals("HEAD") || cl == 0 ||
respCode == HTTP_NOT_MODIFIED ||
respCode == HTTP_NO_CONTENT) {
if (pi != null) {
pi.finishTracking();
pi = null;
}
http.finished();
http = null;
inputStream = new EmptyInputStream();
connected = false;
}
if (respCode == 200 || respCode == 203 || respCode == 206 ||
respCode == 300 || respCode == 301 || respCode == 410) {
if (cacheHandler != null && getUseCaches()) {
// give cache a chance to save response in cache
URI uri = ParseUtil.toURI(url);
if (uri != null) {
URLConnection uconn = this;
if ("https".equalsIgnoreCase(uri.getScheme())) {
try {
// use reflection to get to the public
// HttpsURLConnection instance saved in
// DelegateHttpsURLConnection
uconn = (URLConnection)this.getClass().getField("httpsURLConnection").get(this);
} catch (IllegalAccessException iae) {
// ignored; use 'this'
} catch (NoSuchFieldException nsfe) {
// ignored; use 'this'
}
}
CacheRequest cacheRequest =
cacheHandler.put(uri, uconn);
if (cacheRequest != null && http != null) {
http.setCacheRequest(cacheRequest);
inputStream = new HttpInputStream(inputStream, cacheRequest);
}
}
}
}
if (!(inputStream instanceof HttpInputStream)) {
inputStream = new HttpInputStream(inputStream);
}
if (respCode >= 400) {
if (respCode == 404 || respCode == 410) {
throw new FileNotFoundException(url.toString());
} else {
throw new java.io.IOException("Server returned HTTP" +
" response code: " + respCode + " for URL: " +
url.toString());
}
}
poster = null;
strOutputStream = null;
return inputStream;
} while (redirects < maxRedirects);
throw new ProtocolException("Server redirected too many " +
" times ("+ redirects + ")");
} catch (RuntimeException e) {
disconnectInternal();
rememberedException = e;
throw e;