📄 http.cc
字号:
// get the size of our data else if (strncasecmp(buf, "Content-length:", 15) == 0) { m_iSize = atol(trimLead(buf + 15)); } // what type of data do we have? else if (strncasecmp(buf, "Content-type:", 13) == 0) { m_strMimeType = QString::fromLatin1(trimLead(buf + 13)).stripWhiteSpace().lower(); int semicolonPos = m_strMimeType.find( ';' ); if ( semicolonPos != -1 ) { int pos = semicolonPos; while ( m_strMimeType[++pos] == ' ' ); if ( m_strMimeType.find("charset", pos, false) == pos ) { pos+=7; while( m_strMimeType[pos] == ' ' || m_strMimeType[pos] == '=' ) pos++; int end_pos = m_strMimeType.length(); if ( m_strMimeType[pos] == '"' ) { pos++; int index = end_pos-1; while ( index > pos ) { if ( m_strMimeType[index] == '"' ) break; index--; } if ( index > pos ) end_pos = index; } m_strCharset = m_strMimeType.mid( pos, end_pos ); //kdDebug(7113) << "Found charset: " << m_strCharset << endl; } m_strMimeType.truncate( semicolonPos ); } //kdDebug(7113) << "Content-type: " << m_strMimeType << endl; } // Date else if (strncasecmp(buf, "Date:", 5) == 0) { dateHeader = KRFCDate::parseDate(trimLead(buf+5)); } // Cache management else if (strncasecmp(buf, "ETag:", 5) == 0) { m_etag = trimLead(buf+5); } // Cache management else if (strncasecmp(buf, "Expires:", 8) == 0) { expireDate = KRFCDate::parseDate(trimLead(buf+8)); if (!expireDate) expireDate = 1; // Already expired } // Cache management else if (strncasecmp(buf, "Last-Modified:", 14) == 0) { m_lastModified = (QString::fromLatin1(trimLead(buf+14))).stripWhiteSpace(); } // whoops.. we received a warning else if (strncasecmp(buf, "Warning:", 8) == 0) { //Don't use warning() here, no need to bother the user. //Those warnings are mostly about caches. infoMessage(trimLead(buf + 8)); } // Cache management (HTTP 1.0) else if (strncasecmp(buf, "Pragma:", 7) == 0) { QCString pragma = QCString(trimLead(buf+7)).stripWhiteSpace().lower(); if (pragma == "no-cache") { m_bCachedWrite = false; // Don't put in cache mayCache = false; } hasCacheDirective = true; } // The deprecated Refresh Response else if (strncasecmp(buf,"Refresh:", 8) == 0) { kdDebug(7113) << buf << endl; mayCache = false; // Do not cache page as it defeats purpose of Refresh tag! setMetaData( "http-refresh", QString::fromLatin1(trimLead(buf+8)).stripWhiteSpace() ); } // In fact we should do redirection only if we got redirection code else if (strncasecmp(buf, "Location:", 9) == 0) { // Redirect only for 3xx status code, will ya! Thanks, pal! if ( m_responseCode > 299 && m_responseCode < 400 ) locationStr = QCString(trimLead(buf+9)).stripWhiteSpace(); } // Check for cookies else if (strncasecmp(buf, "Set-Cookie", 10) == 0) { cookieStr += buf; cookieStr += '\n'; } // check for direct authentication else if (strncasecmp(buf, "WWW-Authenticate:", 17) == 0) { configAuth(trimLead(buf + 17), false); } // check for proxy-based authentication else if (strncasecmp(buf, "Proxy-Authenticate:", 19) == 0) { configAuth(trimLead(buf + 19), true); } // content? else if (strncasecmp(buf, "Content-Encoding:", 17) == 0) { // A quote from RFC 2616: // " When present, its (Content-Encoding) value indicates what additional // content have been applied to the entity body, and thus what decoding // mechanism must be applied to obtain the media-type referenced by the // Content-Type header field. Content-Encoding is primarily used to allow // a document to be compressed without loosing the identity of its underlying // media type. Simply put if it is specified, this is the actual mime-type // we should use when we pull the resource !!! addEncoding(trimLead(buf + 17), m_qContentEncodings); } // Refer to RFC 2616 sec 15.5/19.5.1 and RFC 2183 else if (strncasecmp(buf, "Content-Disposition:", 20) == 0) { char* dispositionBuf = trimLead(buffer + 20); while ( *dispositionBuf ) { if ( strncasecmp( dispositionBuf, "filename", 8 ) == 0 ) { dispositionBuf += 8; while ( (dispositionBuf[0] == ' ') || (dispositionBuf[0] == '=') ) dispositionBuf++; char* bufStart = dispositionBuf; while ( dispositionBuf[0] && (dispositionBuf[0] != ';') ) dispositionBuf++; if ( dispositionBuf > bufStart ) { disposition = QString::fromLatin1( bufStart, dispositionBuf-bufStart ); break; } } else { char *bufStart = dispositionBuf; while ( dispositionBuf[0] && (dispositionBuf[0] != ';') ) dispositionBuf++; if ( dispositionBuf > bufStart ) { // Sometimes "filename=" is missing. disposition = QString::fromLatin1( bufStart, dispositionBuf-bufStart ).stripWhiteSpace(); } while ( (dispositionBuf[0] == ';') || (dispositionBuf[0] == ' ') ) dispositionBuf++; } } // Content-Dispostion is not allowed to dictate directory // path, thus we extract the filename only. if ( !disposition.isEmpty() ) { int pos = disposition.findRev( '/' ); if( pos > -1 ) disposition = disposition.mid(pos+1); kdDebug(7113) << "(" << getpid() << ") Content-Disposition: " << disposition << endl; } } // Continue only if we know that we're HTTP/1.1 else if (m_HTTPrev == HTTP_11) { // let them tell us if we should stay alive or not if (strncasecmp(buf, "Connection:", 11) == 0) { if (strncasecmp(trimLead(buf + 11), "Close", 5) == 0) { m_bKeepAlive = false; } else if (strncasecmp(trimLead(buf + 11), "Keep-Alive", 10)==0) { // Don't do persistant connections with SSL. if (!m_bIsSSL) m_bKeepAlive = true; } } // what kind of encoding do we have? transfer? else if (strncasecmp(buf, "Transfer-Encoding:", 18) == 0) { // If multiple encodings have been applied to an entity, the // transfer-codings MUST be listed in the order in which they // were applied. addEncoding(trimLead(buf + 18), m_qTransferEncodings); } // MD5 signature else if (strncasecmp(buf, "Content-MD5:", 12) == 0) { m_sContentMD5 = trimLead(buffer + 12); } } else if ( buf[0] =='<' ) { // We get XML / HTTP without a proper header put string back ungets(buf, strlen(buf)); break; } // Clear out our buffer for further use. memset(buffer, 0, sizeof(buffer)); } while (len && (gets(buffer, sizeof(buffer)-1))); // Check if we got need to error out... if ( errCode >= 0 ) { if ( errCode == 0 && (m_iSize > 0 || !m_strMimeType.isEmpty()) ) { errorPage(); } else { error(errCode, errMessage); return false; } } // If we do not support the requested authentication method... if ( (m_responseCode == 401 && Authentication == AUTH_None) || (m_responseCode == 407 && ProxyAuthentication == AUTH_None) ) { error( ERR_UNSUPPORTED_ACTION, "Unknown Authorization method!" ); return false; } // Fixup expire date for clock drift. if (expireDate && (expireDate <= dateHeader)) expireDate = 1; // Already expired. // Convert max-age into expireDate (overriding previous set expireDate) if (maxAge == 0) expireDate = 1; // Already expired. else if (maxAge > 0) { if (currentAge) maxAge -= currentAge; if (maxAge <=0) maxAge = 0; expireDate = time(0) + maxAge; } if (!expireDate) expireDate = time(0) + DEFAULT_CACHE_EXPIRE; // DONE receiving the header! if (!cookieStr.isEmpty()) { if ((m_cookieMode == CookiesAuto) && m_bUseCookiejar) { // Give cookies to the cookiejar. addCookies( m_request.url.url(), cookieStr ); } else if (m_cookieMode == CookiesManual) { // Pass cookie to application setMetaData("setcookies", cookieStr); } } if (m_bMustRevalidate) { m_bMustRevalidate = false; // Reset just in case. if (cacheValidated) { // Yippie, we can use the cached version. // Update the cache with new "Expire" headers. fclose(m_fcache); m_fcache = 0; updateExpireDate( expireDate, true ); m_fcache = checkCacheEntry( ); // Re-read cache entry if (m_fcache) { m_bCachedRead = true; return readHeader(); // Read header again, but now from cache. } else { // Where did our cache entry go??? } } else { // Validation failed. Close cache. fclose(m_fcache); m_fcache = 0; } } // We need to reread the header if we got a '100 Continue' if ( cont ) { return readHeader(); } // We need to try to login again if we failed earlier if ( m_bUnauthorized ) { if ( m_responseCode == 401 || m_responseCode == 407 ) { if ( getAuthorization() ) { http_closeConnection(); return false; // Try again. } else { if ( m_bErrorPage && (m_iSize > 0 || !m_strMimeType.isEmpty()) ) errorPage(); else error( ERR_USER_CANCELED, QString::null ); } if (m_bError) return false; // Error out // Show error page... } m_bUnauthorized = false; } // We need to do a redirect if (!locationStr.isEmpty()) { KURL u(m_request.url, locationStr); if(u.isMalformed()) { error(ERR_MALFORMED_URL, u.url()); return false; } if ((u.protocol() != "http") && (u.protocol() != "https") && (u.protocol() != "ftp")) { error(ERR_ACCESS_DENIED, u.url()); return false; } kdDebug(7113) << "(" << getpid() << ") request.url: " << m_request.url.url() << endl << "(" << getpid() << ") LocationStr: " << locationStr.data() << endl << "(" << getpid() << ") Requesting redirection to: " << u.url() << endl; redirection(u.url()); m_bCachedWrite = false; // Turn off caching on re-direction (DA) mayCache = false; } // Inform the job that we can indeed resume... if ( m_bCanResume && m_request.offset ) canResume(); // Reset the POST buffer if we do not get an authorization // request and the previous action was POST. if ( m_request.method==HTTP_POST && !m_bUnauthorized ) m_bufPOST.resize(0); // Do not cache pages originating from password // protected sites. if ( !hasCacheDirective && Authentication != AUTH_None ) { m_bCachedWrite = false; mayCache = false; } // Do not cache any text from SSL sites. if (m_bIsSSL && m_strMimeType.startsWith("text/")) { m_bCachedWrite = false; mayCache = false; } // WABA: Correct for tgz files with a gzip-encoding. // They really shouldn't put gzip in the Content-Encoding field! // Web-servers really shouldn't do this: They let Content-Size refer // to the size of the tgz file, not to the size of the tar file, // while the Content-Type refers to "tar" instead of "tgz". if (m_qContentEncodings.last() == "gzip") { if (m_strMimeType == "application/x-tar") { m_qContentEncodings.remove(m_qContentEncodings.fromLast()); m_strMimeType = QString::fromLatin1("application/x-tgz"); } else if ( m_strMimeType == "text/html" || (m_strMimeType.startsWith("text/") && m_request.url.path().right(3) != ".gz") ) { // Unzip! } else { m_qContentEncodings.remove(m_qContentEncodings.fromLast()); m_strMimeType = QString::fromLatin1("application/x-gzip"); } } // We can't handle "bzip2" encoding (yet). So if we get something with // bzip2 encoding, we change the mimetype to "application/x-bzip2". // Note for future changes: some web-servers send both "bzip2" as // encoding and "application/x-bzip2" as mimetype. That is wrong. // currently that doesn't bother us, because we remove the encoding // and set the mimetype to x-bzip2 anyway. if (m_qContentEncodings.last() == "bzip2") { m_qContentEncodings.remove(m_qContentEncodings.fromLast()); m_strMimeType = QString::fromLatin1("application/x-bzip2"); } // Convert some common mimetypes to standard KDE mimetypes if (m_strMimeType == "application/x-targz") m_strMimeType = QString::fromLatin1("application/x-tgz"); else if (m_strMimeType == "image/x-png") m_strMimeType = QString::fromLatin1("image/png"); else if (m_strMimeType == "audio/mpeg" || m_strMimeType == "audio/x-mpeg" || m_strMimeType == "audio/mp3") m_strMimeType = QString::fromLatin1("audio/x-mp3"); else if (m_strMimeType == "audio/midi") m_strMimeType = QString::fromLatin1("audio/x-midi"); // Prefer application/x-tgz over application/x-gzip else if (m_strMimeType == "application/x-gzip") { if ((m_request.url.path().right(7) == ".tar.gz") || (m_request.url.path().right(4) == ".tar")) m_strMimeType = QString::fromLatin1("application/x-tgz"); } // Some webservers say "text/plain" when they mean "application/x-bzip2" else if (m_strMimeType == "text/plain") { if (m_request.url.path().right(4) == ".bz2") m_strMimeType = QString::fromLatin1("application/x-bzip2"); }#if 0 // Even if we can't rely on content-length, it seems that we should // never get more data than content-length. Maybe less, if the // content-length refers to the unzipped data. if (!m_qContentEncodings.isEmpty()) { // If we still have content encoding we can't rely on the Content-Length. m_iSize = -1; }#endif // Set charset. Maybe charSet should be a class member, since // this method is somewhat recursive.... if ( !m_strCharset.isEmpty() ) { kdDebug(7113) << "(" << getpid() << ") Setting charset metadata to: " << m_strCharset << endl; setMetaData("charset", m_strCharset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -