/** * Parse the headers sent from the server. * * @param headers gives up the HeaderGroup IMPORTANT: as this is called from network thread, can't * call native directly */ public void headers(Headers headers) { if (Config.LOGV) Log.v(LOGTAG, "LoadListener.headers"); if (mCancelled) return; mHeaders = headers; mMimeType = ""; mEncoding = ""; ArrayList<String> cookies = headers.getSetCookie(); for (int i = 0; i < cookies.size(); ++i) { CookieManager.getInstance().setCookie(mUri, cookies.get(i)); } long contentLength = headers.getContentLength(); if (contentLength != Headers.NO_CONTENT_LENGTH) { mContentLength = contentLength; } else { mContentLength = 0; } String contentType = headers.getContentType(); if (contentType != null) { parseContentTypeHeader(contentType); // If we have one of "generic" MIME types, try to deduce // the right MIME type from the file extension (if any): if (mMimeType.equalsIgnoreCase("text/plain") || mMimeType.equalsIgnoreCase("application/octet-stream")) { String newMimeType = guessMimeTypeFromExtension(); if (newMimeType != null) { mMimeType = newMimeType; } } else if (mMimeType.equalsIgnoreCase("text/vnd.wap.wml")) { // As we don't support wml, render it as plain text mMimeType = "text/plain"; } else { // XXX: Until the servers send us either correct xhtml or // text/html, treat application/xhtml+xml as text/html. // It seems that xhtml+xml and vnd.wap.xhtml+xml mime // subtypes are used interchangeably. So treat them the same. if (mMimeType.equalsIgnoreCase("application/xhtml+xml") || mMimeType.equals("application/vnd.wap.xhtml+xml")) { mMimeType = "text/html"; } } } else { /* Often when servers respond with 304 Not Modified or a Redirect, then they don't specify a MIMEType. When this occurs, the function below is called. In the case of 304 Not Modified, the cached headers are used rather than the headers that are returned from the server. */ guessMimeType(); } // is it an authentication request? boolean mustAuthenticate = (mStatusCode == HTTP_AUTH || mStatusCode == HTTP_PROXY_AUTH); // is it a proxy authentication request? boolean isProxyAuthRequest = (mStatusCode == HTTP_PROXY_AUTH); // is this authentication request due to a failed attempt to // authenticate ealier? mAuthFailed = false; // if we tried to authenticate ourselves last time if (mAuthHeader != null) { // we failed, if we must to authenticate again now and // we have a proxy-ness match mAuthFailed = (mustAuthenticate && isProxyAuthRequest == mAuthHeader.isProxy()); // if we did NOT fail and last authentication request was a // proxy-authentication request if (!mAuthFailed && mAuthHeader.isProxy()) { Network network = Network.getInstance(mContext); // if we have a valid proxy set if (network.isValidProxySet()) { /* The proxy credentials can be read in the WebCore thread */ synchronized (network) { // save authentication credentials for pre-emptive proxy // authentication network.setProxyUsername(mAuthHeader.getUsername()); network.setProxyPassword(mAuthHeader.getPassword()); } } } } // it is only here that we can reset the last mAuthHeader object // (if existed) and start a new one!!! mAuthHeader = null; if (mustAuthenticate) { if (mStatusCode == HTTP_AUTH) { mAuthHeader = parseAuthHeader(headers.getWwwAuthenticate()); } else { mAuthHeader = parseAuthHeader(headers.getProxyAuthenticate()); // if successfully parsed the header if (mAuthHeader != null) { // mark the auth-header object as a proxy mAuthHeader.setProxy(); } } } // Only create a cache file if the server has responded positively. if ((mStatusCode == HTTP_OK || mStatusCode == HTTP_FOUND || mStatusCode == HTTP_MOVED_PERMANENTLY || mStatusCode == HTTP_TEMPORARY_REDIRECT) && mNativeLoader != 0) { // Content arriving from a StreamLoader (eg File, Cache or Data) // will not be cached as they have the header: // cache-control: no-store mCacheResult = CacheManager.createCacheFile(mUrl, mStatusCode, headers, mMimeType, false); if (mCacheResult != null) { mCacheResult.encoding = mEncoding; } } sendMessageInternal(obtainMessage(MSG_CONTENT_HEADERS)); }