Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:aualin:kde
kdelibs3
httpslave-r3-kdelibs-3.5.7.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File httpslave-r3-kdelibs-3.5.7.diff of Package kdelibs3
--- kdelibs-3.5.7/kparts/browserrun.cpp.orig 2006-05-22 20:14:22.000000000 +0200 +++ kdelibs-3.5.7/kparts/browserrun.cpp 2007-06-01 22:48:57.000000000 +0200 @@ -138,9 +138,25 @@ job = KIO::http_post( m_strURL, m_args.postData, false ); job->addMetaData( "content-type", m_args.contentType() ); } - else + else { job = KIO::get(m_strURL, m_args.reload, false); + // Check if this is part of a frame + static const QString true_str("TRUE"); + KIO::MetaData::iterator it = m_args.metaData().find("main_frame_request"); + bool toplevel = ((it == m_args.metaData().end()) || (it.data() == true_str)); + //const QString res = (it == m_args.metaData().end() ? "TRUE" : it.data()); + //kdDebug(1000) << "main_frame_request=" << res << " " << toplevel << endl; + if (!toplevel) + KIO::Scheduler::scheduleJob(job); + } + +// KIO::MetaData::iterator cd = m_args.metaData().find("cross-domain"); +// KIO::MetaData::iterator rf = m_args.metaData().find("referrer"); +// kdDebug(1000) << "cross-domain=" << (cd == m_args.metaData().end() ? "<none>" : cd.data()) +// << " referrer=" << (rf == m_args.metaData().end() ? "<none>" : rf.data()) +// << "\n"; + if ( m_bRemoveReferrer ) m_args.metaData().remove("referrer"); --- kdelibs-3.5.7/kioslave/http/http.h.orig 2007-01-15 12:34:07.000000000 +0100 +++ kdelibs-3.5.7/kioslave/http/http.h 2007-06-01 22:48:57.000000000 +0200 @@ -104,6 +104,7 @@ { port = 0; method = KIO::HTTP_UNKNOWN; + cache = DEFAULT_CACHE_CONTROL; offset = 0; doProxy = false; allowCompressedPage = false; @@ -112,13 +113,17 @@ bUseCache = false; bCachedRead = false; bCachedWrite = false; + bIsNoCache = false; + magicID = 0; fcache = 0; + bCacheIsNew = false; bMustRevalidate = false; cacheExpireDateOffset = 0; bErrorPage = false; bUseCookiejar = false; expireDate = 0; creationDate = 0; + redir = 0; } QString hostname; @@ -150,9 +155,13 @@ bool bUseCache; // Whether the cache is active bool bCachedRead; // Whether the file is to be read from m_fcache. bool bCachedWrite; // Whether the file is to be written to m_fcache. + bool bIsNoCache; // Whether the file should be cached according to server + bool bCacheIsNew; // if the file in fcache is newly created + long magicID; // Unique random number assigned to a http object FILE* fcache; // File stream of a cache entry QString etag; // ETag header. QString lastModified; // Last modified. + QCString redir; // Redirection Url. Empty if no redirection bool bMustRevalidate; // Cache entry is expired. long cacheExpireDateOffset; // Position in the cache entry where the // 16 byte expire date is stored. @@ -286,7 +295,7 @@ void configAuth( char *, bool ); bool httpOpen(); // Open transfer - void httpClose(bool keepAlive); // Close transfer + void httpClose(bool keepAlive, bool incomplete); // Close transfer bool httpOpenConnection(); // Open connection void httpCloseConnection(); // Close connection @@ -355,7 +364,7 @@ * * Set the contents type of the cache entry to 'mimetype'. */ - void createCacheEntry(const QString &mimetype, time_t expireDate); + void createCacheEntry(const QString &mimetype, time_t expireDate, time_t creationDate); /** * Write data to cache. @@ -372,7 +381,7 @@ /** * Update expire time of current cache entry. */ - void updateExpireDate(time_t expireDate, bool updateCreationDate=false); + void updateExpireDate(time_t expireDate, bool updateCreationDate=false, bool no_cache=false); /** * Quick check whether the cache needs cleaning. @@ -465,6 +474,10 @@ */ void promptInfo( KIO::AuthInfo& info ); +private: + bool handleRedirection(); + KIO::CacheControl getCacheControl(); + protected: HTTPState m_state; HTTPRequest m_request; --- kdelibs-3.5.7/kioslave/http/http.cc.orig 2007-05-14 09:52:34.000000000 +0200 +++ kdelibs-3.5.7/kioslave/http/http.cc 2007-06-01 22:48:57.000000000 +0200 @@ -91,6 +91,8 @@ using namespace KIO; +static const bool bOfflineCaching = true; + extern "C" { KDE_EXPORT int kdemain(int argc, char **argv); } @@ -107,6 +109,8 @@ exit(-1); } + srand(time(0)); //seed random number generator + HTTPProtocol slave(argv[1], argv[2], argv[3]); slave.dispatchLoop(); return 0; @@ -225,7 +229,7 @@ HTTPProtocol::~HTTPProtocol() { - httpClose(false); + httpClose(false, true); } void HTTPProtocol::reparseConfiguration() @@ -298,6 +302,7 @@ m_request.bUseCookiejar = config()->readBoolEntry("Cookies"); m_request.bUseCache = config()->readBoolEntry("UseCache", true); + //kdDebug(7103) << "(" << m_pid << ") config says UseCache=" << m_request.bUseCache << endl; m_request.bErrorPage = config()->readBoolEntry("errorPage", true); m_request.bNoAuth = config()->readBoolEntry("no-auth"); m_strCacheDir = config()->readPathEntry("CacheDir"); @@ -309,9 +314,14 @@ << metaData ("ssl_was_in_use") << endl; m_request.referrer = QString::null; + + QString domain = metaData("cross-domain"); + if ( config()->readBoolEntry("SendReferrer", true) && - (m_protocol == "https" || m_protocol == "webdavs" || - metaData ("ssl_was_in_use") != "TRUE" ) ) + (m_protocol == "https" || m_protocol == "webdavs" || metaData ("ssl_was_in_use") != "TRUE" ) && + !domain.isEmpty() && + (config()->readBoolEntry("SendReferrerAcrossDomains", false) || + !isCrossDomainRequest(m_request.url.host(), domain) ) ) { KURL referrerURL ( metaData("referrer") ); if (referrerURL.isValid()) @@ -331,8 +341,12 @@ referrerURL.setPass(QString::null); m_request.referrer = referrerURL.url(); } + } } + kdDebug() << "(" << m_pid << ") referrer='" << m_request.referrer << "' domain='" << domain + << "' url.host()='" << m_request.url.host() << " real-referrer=" << metaData("referrer") + << "'\n"; if ( config()->readBoolEntry("SendLanguageSettings", true) ) { @@ -493,7 +507,7 @@ void HTTPProtocol::retrieveContent( bool dataInternal /* = false */ ) { - kdDebug (7113) << "(" << m_pid << ") HTTPProtocol::retrieveContent " << endl; + kdDebug (7113) << "(" << m_pid << ") HTTPProtocol::retrieveContent keepAlive=" << m_bKeepAlive << endl; if ( !retrieveHeader( false ) ) { if ( m_bError ) @@ -505,7 +519,7 @@ return; } - httpClose(m_bKeepAlive); + httpClose(m_bKeepAlive, false); // if data is required internally, don't finish, // it is processed before we finish() @@ -590,7 +604,7 @@ if ( close_connection ) { - httpClose(m_bKeepAlive); + httpClose(m_bKeepAlive, true); finished(); } @@ -1200,7 +1214,7 @@ void HTTPProtocol::davFinished() { // TODO: Check with the DAV extension developers - httpClose(m_bKeepAlive); + httpClose(m_bKeepAlive, false); finished(); } @@ -1228,7 +1242,7 @@ void HTTPProtocol::get( const KURL& url ) { - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::get " << url.url() + kdDebug(7103) << "(" << m_pid << ") HTTPProtocol::get " << url.url() << endl; if ( !checkRequestURL( url ) ) @@ -1237,12 +1251,13 @@ m_request.method = HTTP_GET; m_request.path = url.path(); m_request.query = url.query(); + m_request.cache = getCacheControl(); - QString tmp = metaData("cache"); - if (!tmp.isEmpty()) - m_request.cache = parseCacheControl(tmp); - else - m_request.cache = DEFAULT_CACHE_CONTROL; + kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::get " + << " cross-domain=" << metaData("cross-domain") + << " cache=" << getCacheControlString(m_request.cache) + << " url=" << url.url() + << endl; m_request.passwd = url.pass(); m_request.user = url.user(); @@ -1307,7 +1322,7 @@ kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::put responseCode = " << m_responseCode << endl; - httpClose(false); // Always close connection. + httpClose(false, true); // Always close connection. if ( (m_responseCode >= 200) && (m_responseCode < 300) ) finished(); @@ -1845,11 +1860,7 @@ m_request.method = HTTP_GET; m_request.path = url.path(); m_request.query = url.query(); - QString tmp = metaData("cache"); - if (!tmp.isEmpty()) - m_request.cache = parseCacheControl(tmp); - else - m_request.cache = DEFAULT_CACHE_CONTROL; + m_request.cache = getCacheControl(); m_request.passwd = url.pass(); m_request.user = url.user(); @@ -2157,7 +2168,7 @@ */ bool HTTPProtocol::httpOpen() { - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpOpen" << endl; + kdDebug(7103) << "(" << m_pid << ") HTTPProtocol::httpOpen cacheControl=" << getCacheControlString(m_request.cache) << endl; // Cannot have an https request without the m_bIsSSL being set! This can // only happen if TCPSlaveBase::InitializeSSL() function failed in which it @@ -2175,9 +2186,11 @@ m_request.expireDate = 0; m_request.creationDate = 0; + kdDebug(7103) << "(" << m_pid << ") bUseCache=" << m_request.bUseCache << "\n"; if (m_request.bUseCache) { m_request.fcache = checkCacheEntry( ); + //kdDebug(7103) << "(" << m_pid << ") fcache=" << m_request.fcache << endl; bool bCacheOnly = (m_request.cache == KIO::CC_CacheOnly); bool bOffline = isOffline(m_request.doProxy ? m_proxyURL : m_request.url); @@ -2588,6 +2601,7 @@ } } +#if 0 kdDebug(7103) << "(" << m_pid << ") ============ Sending Header:" << endl; QStringList headerOutput = QStringList::split("\r\n", header); @@ -2595,7 +2609,11 @@ for (; it != headerOutput.end(); it++) kdDebug(7103) << "(" << m_pid << ") " << (*it) << endl; - +#else + kdDebug(7103) << "(" << m_pid << ") ==== Sending Header: " + << header.section("\r\n", 0, 0) + << " cacheControl=" << getCacheControlString(m_request.cache) << "\n"; +#endif if ( !moreData && !davData) header += "\r\n"; /* end header */ @@ -2668,6 +2686,11 @@ if (m_request.bCachedRead) { m_responseHeader << "HTTP-CACHE"; + + if (!m_request.redir.isEmpty()) { + forwardHttpResponseHeader(); + return handleRedirection(); + } else { // Read header from cache... char buffer[4097]; if (!fgets(buffer, 4096, m_request.fcache) ) @@ -2702,12 +2725,14 @@ setMetaData("expire-date", tmp); tmp.setNum(m_request.creationDate); setMetaData("cache-creation-date", tmp); + tmp.setNum(m_request.magicID); + setMetaData("magicID", tmp); mimeType(m_strMimeType); forwardHttpResponseHeader(); return true; } + } - QCString locationStr; // In case we get a redirect. QCString cookieStr; // In case we get a cookie. QString dispositionType; // In case we get a Content-Disposition type @@ -2728,6 +2753,8 @@ m_request.etag = QString::null; m_request.lastModified = QString::null; m_request.strCharset = QString::null; + m_request.redir = 0; // We cache redirection headers too + m_request.bIsNoCache = false; // whether the server request not to cache time_t dateHeader = 0; time_t expireDate = 0; // 0 = no info, 1 = already expired, > 1 = actual date @@ -2794,6 +2821,10 @@ HTTP_REV httpRev = HTTP_None; int headerSize = 0; + m_request.magicID = rand(); + setMetaData("magicID", QString("%1").arg(m_request.magicID)); + kdDebug(7113) << "(" << m_pid << ") Setting magicID to " << m_request.magicID << endl; + do { // strip off \r and \n if we have them @@ -2805,7 +2836,7 @@ // if there was only a newline then continue if (!len) { - kdDebug(7103) << "(" << m_pid << ") --empty--" << endl; + //kdDebug(7103) << "(" << m_pid << ") --empty--" << endl; continue; } @@ -2817,8 +2848,6 @@ // top of the reponse... noHeader = false; - kdDebug(7103) << "(" << m_pid << ") \"" << buffer << "\"" << endl; - // Save broken servers from damnation!! char* buf = buffer; while( *buf == ' ' ) @@ -2841,6 +2870,7 @@ // Store the the headers so they can be passed to the // calling application later m_responseHeader << QString::fromLatin1(buf); + //kdDebug(7103) << "(" << m_pid << ") " << buf << endl; if ((strncasecmp(buf, "HTTP", 4) == 0) || (strncasecmp(buf, "ICY ", 4) == 0)) // Shoutcast support @@ -2892,11 +2922,12 @@ else { error(ERR_INTERNAL_SERVER, m_request.url.url()); + m_request.bCachedWrite = false; // Don't put in cache return false; } + // Some servers send a 'HTTP 404 not found' but send the data anyway, so + // caching is not turned off } - m_request.bCachedWrite = false; // Don't put in cache - mayCache = false; } // Unauthorized access else if (m_responseCode == 401 || m_responseCode == 407) @@ -2932,16 +2963,16 @@ else { error(ERR_DOES_NOT_EXIST, m_request.url.url()); + m_request.bCachedWrite = false; // Don't put in cache return false; } - m_request.bCachedWrite = false; // Don't put in cache - mayCache = false; + // Some servers send a 'HTTP 404 not found' but send the data anyway, so + // caching is not turned off } else if (m_responseCode == 307) { // 307 Temporary Redirect - m_request.bCachedWrite = false; // Don't put in cache - mayCache = false; + // Handle as any other redirection, i.e. create redirection cache entry } else if (m_responseCode == 304) { @@ -2976,8 +3007,7 @@ // 2616 sections 10.3.[2/3/4/8] m_request.method = HTTP_GET; // Force a GET } - m_request.bCachedWrite = false; // Don't put in cache - mayCache = false; + // Handle as any other redirection, i.e. create redirection cache entry } else if ( m_responseCode == 207 ) // Multi-status (for WebDav) { @@ -3020,6 +3050,14 @@ if (strncasecmp(trimLead(buf + 14), "none", 4) == 0) bCanResume = false; } + // Old-style persistent connection + else if (httpRev == HTTP_10 && strncasecmp(buf, "Connection:", 11) == 0) { + QString option = QString::fromLatin1(trimLead(buf+12)).stripWhiteSpace().lower(); + if (option == "keep-alive") { + m_bKeepAlive = true; + m_keepAliveTimeout = 10; // Some default timeout + } + } // Keep Alive else if (strncasecmp(buf, "Keep-Alive:", 11) == 0) { QStringList options = QStringList::split(',', @@ -3047,11 +3085,13 @@ QString cacheControl = (*it).stripWhiteSpace(); if (strncasecmp(cacheControl.latin1(), "no-cache", 8) == 0) { + m_request.bIsNoCache = true; m_request.bCachedWrite = false; // Don't put in cache mayCache = false; } else if (strncasecmp(cacheControl.latin1(), "no-store", 8) == 0) { + m_request.bIsNoCache = true; m_request.bCachedWrite = false; // Don't put in cache mayCache = false; } @@ -3161,6 +3201,7 @@ QCString pragma = QCString(trimLead(buf+7)).stripWhiteSpace().lower(); if (pragma == "no-cache") { + m_request.bIsNoCache = true; m_request.bCachedWrite = false; // Don't put in cache mayCache = false; hasCacheDirective = true; @@ -3169,7 +3210,10 @@ // The deprecated Refresh Response else if (strncasecmp(buf,"Refresh:", 8) == 0) { + m_request.bIsNoCache = true; + m_request.bCachedWrite = false; // Don't put in cache mayCache = false; // Do not cache page as it defeats purpose of Refresh tag! + hasCacheDirective = true; setMetaData( "http-refresh", QString::fromLatin1(trimLead(buf+8)).stripWhiteSpace() ); } @@ -3177,7 +3221,7 @@ 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(); + m_request.redir = QCString(trimLead(buf+9)).stripWhiteSpace(); } // Check for cookies @@ -3484,12 +3528,24 @@ } // DONE receiving the header! + + if (bOfflineCaching && m_request.bIsNoCache) { + // Override server's idea which things to cache + m_request.bCachedWrite = true; // put in cache anyway + mayCache = true; + } + kdDebug(7113) << "(" << m_pid << ")" << " offlineCaching=" << bOfflineCaching + << " hasCacheDirective=" << hasCacheDirective + << " bIsNoCache=" << m_request.bIsNoCache + << " bCachedWrite=" << m_request.bCachedWrite + << " mayCache=" << mayCache << endl; + if (!cookieStr.isEmpty()) { if ((m_request.cookieMode == HTTPRequest::CookiesAuto) && m_request.bUseCookiejar) { // Give cookies to the cookiejar. - QString domain = config()->readEntry("cross-domain"); + QString domain = metaData("cross-domain"); if (!domain.isEmpty() && isCrossDomainRequest(m_request.url.host(), domain)) cookieStr = "Cross-Domain\n" + cookieStr; addCookies( m_request.url.url(), cookieStr ); @@ -3579,55 +3635,8 @@ m_bUnauthorized = false; } - // We need to do a redirect - if (!locationStr.isEmpty()) - { - KURL u(m_request.url, locationStr); - if(!u.isValid()) - { - error(ERR_MALFORMED_URL, u.url()); + if (!handleRedirection()) return false; - } - if ((u.protocol() != "http") && (u.protocol() != "https") && - (u.protocol() != "ftp") && (u.protocol() != "webdav") && - (u.protocol() != "webdavs")) - { - redirection(u); - error(ERR_ACCESS_DENIED, u.url()); - return false; - } - - // preserve #ref: (bug 124654) - // if we were at http://host/resource1#ref, we sent a GET for "/resource1" - // if we got redirected to http://host/resource2, then we have to re-add - // the fragment: - if (m_request.url.hasRef() && !u.hasRef() && - (m_request.url.host() == u.host()) && - (m_request.url.protocol() == u.protocol())) - u.setRef(m_request.url.ref()); - - m_bRedirect = true; - m_redirectLocation = u; - - if (!m_request.id.isEmpty()) - { - sendMetaData(); - } - - kdDebug(7113) << "(" << m_pid << ") request.url: " << m_request.url.url() - << endl << "LocationStr: " << locationStr.data() << endl; - - kdDebug(7113) << "(" << m_pid << ") Requesting redirection to: " << u.url() - << endl; - - // If we're redirected to a http:// url, remember that we're doing webdav... - if (m_protocol == "webdav" || m_protocol == "webdavs") - u.setProtocol(m_protocol); - - redirection(u); - m_request.bCachedWrite = false; // Turn off caching on re-direction (DA) - mayCache = false; - } // Inform the job that we can indeed resume... if ( bCanResume && m_request.offset ) @@ -3638,16 +3647,15 @@ // We don't cache certain text objects if (m_strMimeType.startsWith("text/") && (m_strMimeType != "text/css") && - (m_strMimeType != "text/x-javascript") && - !hasCacheDirective) + (m_strMimeType != "text/x-javascript")) { // Do not cache secure pages or pages // originating from password protected sites // unless the webserver explicitly allows it. if ( m_bIsSSL || (Authentication != AUTH_None) ) { - m_request.bCachedWrite = false; - mayCache = false; + mayCache = hasCacheDirective && !m_request.bIsNoCache; + m_request.bCachedWrite = mayCache; // trust webserver whether to cache or not } } @@ -3792,6 +3800,7 @@ if (!m_request.lastModified.isEmpty()) setMetaData("modified", m_request.lastModified); + time_t creationDate = time(0); if (!mayCache) { setMetaData("no-cache", "true"); @@ -3802,13 +3811,13 @@ QString tmp; tmp.setNum(expireDate); setMetaData("expire-date", tmp); - tmp.setNum(time(0)); // Cache entry will be created shortly. + tmp.setNum(creationDate); setMetaData("cache-creation-date", tmp); } // Let the app know about the mime-type iff this is not // a redirection and the mime-type string is not empty. - if (locationStr.isEmpty() && (!m_strMimeType.isEmpty() || + if (m_request.redir.isEmpty() && (!m_strMimeType.isEmpty() || m_request.method == HTTP_HEAD)) { kdDebug(7113) << "(" << m_pid << ") Emitting mimetype " << m_strMimeType << endl; @@ -3823,18 +3832,24 @@ // Do we want to cache this request? if (m_request.bUseCache) { - ::unlink( QFile::encodeName(m_request.cef)); - if ( m_request.bCachedWrite && !m_strMimeType.isEmpty() ) + if ( m_request.bCachedWrite ) { // Check... - createCacheEntry(m_strMimeType, expireDate); // Create a cache entry + Q_ASSERT(m_request.fcache == 0); + //kdDebug(7103) << "(" << m_pid << ") overwriting cache entry " << m_request.cef + // << " m_request.cache=" << getCacheControlString(m_request.cache) << endl; + createCacheEntry(m_strMimeType, expireDate, creationDate); // Create a cache entry if (!m_request.fcache) { m_request.bCachedWrite = false; // Error creating cache entry. - kdDebug(7113) << "(" << m_pid << ") Error creating cache entry for " << m_request.url.url()<<"!\n"; + kdDebug(7103) << "(" << m_pid << ") Error creating cache entry for " << m_request.url.url()<<"!\n"; } m_request.expireDate = expireDate; + m_request.creationDate = creationDate; m_maxCacheSize = config()->readNumEntry("MaxCacheSize", DEFAULT_MAX_CACHE_SIZE) / 2; + } else { + //kdDebug(7103) << "(" << m_pid << ") readHeader: m_strMimeType=" << m_strMimeType + // << " m_request.bCachedWrite=" << m_request.bCachedWrite << endl; } } @@ -3875,6 +3890,66 @@ } } +bool HTTPProtocol::handleRedirection() { + if (!m_request.redir.isEmpty()) + { + KURL u(m_request.url, m_request.redir); + if(!u.isValid()) + { + error(ERR_MALFORMED_URL, u.url()); + return false; + } + if ((u.protocol() != "http") && (u.protocol() != "https") && + (u.protocol() != "ftp") && (u.protocol() != "webdav") && + (u.protocol() != "webdavs")) + { + redirection(u); + error(ERR_ACCESS_DENIED, u.url()); + return false; + } + + // preserve #ref: (bug 124654) + // if we were at http://host/resource1#ref, we sent a GET for "/resource1" + // if we got redirected to http://host/resource2, then we have to re-add + // the fragment: + if (m_request.url.hasRef() && !u.hasRef() && + (m_request.url.host() == u.host()) && + (m_request.url.protocol() == u.protocol())) + u.setRef(m_request.url.ref()); + + m_bRedirect = true; + m_redirectLocation = u; + + if (!m_request.id.isEmpty()) + sendMetaData(); + + kdDebug(7113) << "(" << m_pid << ") request.url: " << m_request.url.url() + << endl << "LocationStr: " << m_request.redir.data() << endl; + + kdDebug(7113) << "(" << m_pid << ") Requesting redirection to: " << u.url() + << endl; + + // If we're redirected to a http:// url, remember that we're doing webdav... + if (m_protocol == "webdav" || m_protocol == "webdavs") + u.setProtocol(m_protocol); + + redirection(u); + // do NOT turn off caching. Redirection headers are cached too. Useful for + // true offline browsing. + //m_request.bCachedWrite = false; // Turn off caching on re-direction (DA) + //mayCache = false; + } + return true; +} + +KIO::CacheControl HTTPProtocol::getCacheControl() { + QString tmp = metaData("cache"); + if (!tmp.isEmpty()) + return KIO::parseCacheControl(tmp); + else + return DEFAULT_CACHE_CONTROL; +} + bool HTTPProtocol::sendBody() { int result=-1; @@ -3950,18 +4025,36 @@ return true; } -void HTTPProtocol::httpClose( bool keepAlive ) +void HTTPProtocol::httpClose( bool keepAlive, bool incomplete ) { - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpClose" << endl; + kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpClose keepAlive=" << keepAlive << endl; if (m_request.fcache) { + if (m_request.bCacheIsNew) { + bool ok = true; + char buffer[401]; + + kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpClose: cache-cleanup, closing " + << m_request.cef << endl; + + // We want a cache entry no matter what + if (incomplete) { + kdDebug(7103) << "(" << m_pid << ") HTTPProtocol::httpClose: incomplete transfer, setting as no-cache "; + fseek(m_request.fcache, 0, SEEK_SET); + + if (ok && !fgets(buffer, 400, m_request.fcache)) + ok = false; + if (ok && !fgets(buffer, 400, m_request.fcache)) + ok = false; + + if (ok) + fputs("no-cache\n", m_request.fcache); + } + closeCacheEntry(); + } else { fclose(m_request.fcache); m_request.fcache = 0; - if (m_request.bCachedWrite) - { - QString filename = m_request.cef + ".new"; - ::unlink( QFile::encodeName(filename) ); } } @@ -3977,7 +4070,7 @@ else if (m_keepAliveTimeout > 2*DEFAULT_KEEP_ALIVE_TIMEOUT) m_keepAliveTimeout = 2*DEFAULT_KEEP_ALIVE_TIMEOUT; - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpClose: keep alive (" << m_keepAliveTimeout << ")" << endl; + //kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::httpClose: keep alive (" << m_keepAliveTimeout << ")" << endl; QByteArray data; QDataStream stream( data, IO_WriteOnly ); stream << int(99); // special: Close connection @@ -4015,7 +4108,7 @@ void HTTPProtocol::mimetype( const KURL& url ) { - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::mimetype: " + kdDebug(7103) << "(" << m_pid << ") HTTPProtocol::mimetype: " << url.prettyURL() << endl; if ( !checkRequestURL( url ) ) @@ -4024,18 +4117,18 @@ m_request.method = HTTP_HEAD; m_request.path = url.path(); m_request.query = url.query(); - m_request.cache = CC_Cache; + m_request.cache = getCacheControl(); m_request.doProxy = m_bUseProxy; retrieveHeader(); - kdDebug(7113) << "(" << m_pid << ") http: mimetype = " << m_strMimeType + kdDebug(7103) << "(" << m_pid << ") http: mimetype = " << m_strMimeType << endl; } void HTTPProtocol::special( const QByteArray &data ) { - kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::special" << endl; + //kdDebug(7113) << "(" << m_pid << ") HTTPProtocol::special" << endl; int tmp; QDataStream stream(data, IO_ReadOnly); @@ -4262,7 +4355,9 @@ if ( m_request.bCachedWrite ) { - createCacheEntry( m_strMimeType, m_request.expireDate ); + if (m_request.fcache) + fclose(m_request.fcache); + createCacheEntry( m_strMimeType, m_request.expireDate, m_request.creationDate ); if (!m_request.fcache) m_request.bCachedWrite = false; } @@ -4536,7 +4631,7 @@ void HTTPProtocol::error( int _err, const QString &_text ) { - httpClose(false); + httpClose(false, true); if (!m_request.id.isEmpty()) { @@ -4615,22 +4710,29 @@ m_request.path = url.path(); m_request.query = url.query(); - m_request.cache = CC_Reload; m_request.doProxy = m_bUseProxy; + if (!bOfflineCaching) { if (no_cache) { + m_request.cache = CC_Reload; m_request.fcache = checkCacheEntry( ); if (m_request.fcache) { + QCString fname = QFile::encodeName(m_request.cef); fclose(m_request.fcache); m_request.fcache = 0; - ::unlink( QFile::encodeName(m_request.cef) ); + kdDebug(7103) << "(" << m_pid << ") cacheUpdate: no_cache requested, removing " + << fname << endl; + ::unlink(fname); } } else { - updateExpireDate( expireDate ); + updateExpireDate( expireDate, false); + } + } else { + updateExpireDate( expireDate, false, no_cache); } finished(); } @@ -4641,6 +4743,7 @@ FILE* HTTPProtocol::checkCacheEntry( bool readWrite) { + static const bool v = true; const QChar separator = '_'; QString CEF = m_request.path; @@ -4689,26 +4792,42 @@ m_request.cef = CEF; const char *mode = (readWrite ? "r+" : "r"); - - FILE *fs = fopen( QFile::encodeName(CEF), mode); // Open for reading and writing - if (!fs) + #ifdef DCCE + #error DCCE already defined + #endif + #define DCCE if (v) kdDebug(7103) << "(" << m_pid << ") checkCacheEntry " << url + + QCString fname = QFile::encodeName(CEF); + QString url( m_request.url.url() ); + //DCCE << " rw=" << readWrite << endl; + FILE *fs = fopen(fname, mode); // Open for reading and writing + if (!fs) { + DCCE << " open failed" << endl; return 0; + } + m_request.bCacheIsNew = false; char buffer[401]; bool ok = true; + bool keepCacheFile = false; // To be able to painlessly switch to offline browsing again // CacheRevision - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; - if (ok && (strcmp(buffer, CACHE_REVISION) != 0)) + DCCE << " error reading revision" << endl; + } + if (ok && (strcmp(buffer, CACHE_REVISION) != 0)) { ok = false; - + DCCE << " old/wrong revision" << endl; + } time_t date; time_t currentDate = time(0); // URL - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + DCCE << " error reading URL" << endl; + } if (ok) { int l = strlen(buffer); @@ -4717,35 +4836,74 @@ if (m_request.url.url() != buffer) { ok = false; // Hash collision + DCCE << " hash collision" << endl; + } + } + + // No cache + if (ok && (!fgets(buffer, 400, fs))) { + ok = false; + DCCE << " error reading no-cache" << endl; + } + if (ok) + { + m_request.bIsNoCache = !strncmp(buffer, "no-cache", 6); } + + // Magic random number + if (ok && (!fgets(buffer, 400, fs))) { + ok = false; + DCCE << " error reading magic random number" << endl; + } + if (ok) { + m_request.magicID = strtol(buffer, 0, 10); } // Creation Date - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + DCCE << " error reading creation date" << endl; + } if (ok) { date = (time_t) strtoul(buffer, 0, 10); m_request.creationDate = date; if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge)) { + if (m_request.bIsNoCache) { + DCCE << " creationdate old and no-cache" << endl; + keepCacheFile = true; + ok = false; // Dont validate no-cache entries + } else { m_request.bMustRevalidate = true; m_request.expireDate = currentDate; } } + } // Expiration Date m_request.cacheExpireDateOffset = ftell(fs); - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { + DCCE << " error reading expiration date" << endl; ok = false; + } if (ok) { + if (m_request.bIsNoCache && (m_request.cache != CC_CacheOnly)) + { + DCCE << " CC_Cache and no-cache" << endl; + keepCacheFile = true; + ok = false; // pretend to not have cache entry + } else + { + // CC_Cache: no expiration date + if (m_request.cache == CC_Verify) { date = (time_t) strtoul(buffer, 0, 10); + // After the expire date we need to revalidate. - if (!date || difftime(currentDate, date) >= 0) - m_request.bMustRevalidate = true; + m_request.bMustRevalidate = (!date || difftime(currentDate, date) >= 0); m_request.expireDate = date; } else if (m_request.cache == CC_Refresh) @@ -4754,32 +4912,62 @@ m_request.expireDate = currentDate; } } + } // ETag - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + DCCE << " error reading ETag" << endl; + } if (ok) { m_request.etag = QString(buffer).stripWhiteSpace(); } // Last-Modified - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + DCCE << " error reading last modified" << endl; + } if (ok) { m_request.lastModified = QString(buffer).stripWhiteSpace(); } + // Redirection + if (ok && (!fgets(buffer, 400, fs))) { + ok = false; + DCCE << " error reading redirection" << endl; + } if (ok) + { + m_request.redir = QCString(buffer).stripWhiteSpace(); + + // use only cache for redirections if cache policy is "use cache" + if (!m_request.redir.isEmpty() && (m_request.cache != CC_CacheOnly)) { + DCCE << " reload of redirection" << endl; + keepCacheFile = true; + ok = false; + } + } + + // Mimetype and Charset follows, but are proced in readHeader() + + if (ok) { + DCCE << " exists no-cache=" << m_request.bIsNoCache << endl; return fs; + } fclose(fs); - unlink( QFile::encodeName(CEF)); + if (keepCacheFile) return 0; + DCCE << " old/corrupt -- removing" << endl; + unlink( fname ); + return 0; + #undef DCCE } -void HTTPProtocol::updateExpireDate(time_t expireDate, bool updateCreationDate) +void HTTPProtocol::updateExpireDate(time_t expireDate, bool updateCreationDate, bool no_cache) { bool ok = true; @@ -4795,8 +4983,15 @@ ok = false; if (ok && !fgets(buffer, 400, fs)) ok = false; - long cacheCreationDateOffset = ftell(fs); - if (ok && !fgets(buffer, 400, fs)) + + fputs(no_cache ? "no-cache" : "cache ", fs); + fputc('\n', fs); // no-cache + + if (ok && !fgets(buffer, 400, fs)) // MagicID + ok = false; + + off_t cacheCreationDateOffset = ftell(fs); + if (ok && !fgets(buffer, 400, fs)) // creation date ok = false; creationDate = strtoul(buffer, 0, 10); if (!creationDate) @@ -4837,7 +5032,7 @@ } } -void HTTPProtocol::createCacheEntry( const QString &mimetype, time_t expireDate) +void HTTPProtocol::createCacheEntry( const QString &mimetype, time_t expireDate, time_t creationDate) { QString dir = m_request.cef; int p = dir.findRev('/'); @@ -4851,21 +5046,31 @@ // kdDebug( 7103 ) << "creating new cache entry: " << filename << endl; - m_request.fcache = fopen( QFile::encodeName(filename), "w"); + QCString cfilename = QFile::encodeName(filename); + m_request.fcache = fopen(cfilename , "w"); if (!m_request.fcache) { - kdWarning(7113) << "(" << m_pid << ")createCacheEntry: opening " << filename << " failed." << endl; + kdWarning(7103) << "(" << m_pid << ") createCacheEntry: opening " << cfilename << " failed." << endl; return; // Error. } + m_request.bCacheIsNew = true; + kdDebug(7103) << "(" << m_pid << ") createCacheEntry: creating file " << cfilename << endl; fputs(CACHE_REVISION, m_request.fcache); // Revision fputs(m_request.url.url().latin1(), m_request.fcache); // Url fputc('\n', m_request.fcache); + fputs(m_request.bIsNoCache ? "no-cache" : "cache ", m_request.fcache); // no-cache + fputc('\n', m_request.fcache); + + QString magic; + magic.setNum(m_request.magicID); // magicID + fputs(magic.latin1(), m_request.fcache); + fputc('\n', m_request.fcache); + QString date; - m_request.creationDate = time(0); - date.setNum( m_request.creationDate ); + date.setNum( creationDate ); date = date.leftJustify(16); fputs(date.latin1(), m_request.fcache); // Creation date fputc('\n', m_request.fcache); @@ -4883,6 +5088,11 @@ fputs(m_request.lastModified.latin1(), m_request.fcache); // Last modified fputc('\n', m_request.fcache); + if (!m_request.redir.isEmpty()) // Redirection + fputs(m_request.redir, m_request.fcache); + fputc('\n', m_request.fcache); + + if (!mimetype.isEmpty()) fputs(mimetype.latin1(), m_request.fcache); // Mimetype fputc('\n', m_request.fcache); @@ -4900,7 +5110,7 @@ { if (fwrite( buffer, nbytes, 1, m_request.fcache) != 1) { - kdWarning(7113) << "(" << m_pid << ") writeCacheEntry: writing " << nbytes << " bytes failed." << endl; + kdWarning(7103) << "(" << m_pid << ") writeCacheEntry: writing " << nbytes << " bytes failed." << endl; fclose(m_request.fcache); m_request.fcache = 0; QString filename = m_request.cef + ".new"; @@ -4910,7 +5120,7 @@ long file_pos = ftell( m_request.fcache ) / 1024; if ( file_pos > m_maxCacheSize ) { - kdDebug(7113) << "writeCacheEntry: File size reaches " << file_pos + kdDebug(7103) << "writeCacheEntry: File size reaches " << file_pos << "Kb, exceeds cache limits. (" << m_maxCacheSize << "Kb)" << endl; fclose(m_request.fcache); m_request.fcache = 0; @@ -4930,12 +5140,12 @@ if (::rename( QFile::encodeName(filename), QFile::encodeName(m_request.cef)) == 0) return; // Success - kdWarning(7113) << "(" << m_pid << ") closeCacheEntry: error renaming " + kdWarning(7103) << "(" << m_pid << ") closeCacheEntry: error renaming " << "cache entry. (" << filename << " -> " << m_request.cef << ")" << endl; } - kdWarning(7113) << "(" << m_pid << ") closeCacheEntry: error closing cache " + kdWarning(7103) << "(" << m_pid << ") closeCacheEntry: error closing cache " << "entry. (" << filename<< ")" << endl; } --- kdelibs-3.5.7/kioslave/http/http_cache_cleaner.cpp.orig 2005-09-10 10:26:41.000000000 +0200 +++ kdelibs-3.5.7/kioslave/http/http_cache_cleaner.cpp 2007-06-01 22:48:57.000000000 +0200 @@ -39,6 +39,7 @@ #include <kstandarddirs.h> #include <dcopclient.h> #include <kprotocolmanager.h> +#include <kio/http_slave_defaults.h> #include <unistd.h> @@ -78,11 +79,12 @@ // !START OF SYNC! // Keep the following in sync with the cache code in http.cc -#define CACHE_REVISION "7\n" +//#define CACHE_REVISION "7\n" // Included from header file FileInfo *readEntry( const QString &filename) { QCString CEF = QFile::encodeName(filename); + QCString url; FILE *fs = fopen( CEF.data(), "r"); if (!fs) return 0; @@ -91,34 +93,60 @@ bool ok = true; // CacheRevision - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; - if (ok && (strcmp(buffer, CACHE_REVISION) != 0)) + kdDebug() << appName << ": Error reading cache revision" << endl; + } + if (ok && (strcmp(buffer, CACHE_REVISION) != 0)) { ok = false; + kdDebug() << appName << ": old cache entry found" << endl; + } // Full URL - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + kdDebug() << appName << ": Error reading URL" << endl; + } + if (ok) { + url = QCString(buffer).stripWhiteSpace(); + } time_t creationDate; int age =0; + // No-cache + if (ok && (!fgets(buffer, 400, fs))) { + ok = false; + kdDebug() << appName << ": Error reading no-cache info" << endl; + } + + // MagicID + if (ok && (!fgets(buffer, 400, fs))) { + ok = false; + kdDebug() << appName << ": Error reading magic id" << endl; + } + // Creation Date - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + kdDebug() << appName << ": Error reading creation date" << endl; + } if (ok) { creationDate = (time_t) strtoul(buffer, 0, 10); age = (int) difftime(currentDate, creationDate); if ( m_maxCacheAge && ( age > m_maxCacheAge)) { + kdDebug() << appName << ": cache entry too old " << url << endl; ok = false; // Expired } } // Expiration Date - if (ok && (!fgets(buffer, 400, fs))) + if (ok && (!fgets(buffer, 400, fs))) { ok = false; + kdDebug() << appName << ": Error reading expiration date" << endl; + } if (ok) { //WABA: It seems I slightly misunderstood the meaning of "Expire:" header. @@ -130,23 +158,15 @@ #endif } - // ETag - if (ok && (!fgets(buffer, 400, fs))) + // Read ETag, Last-Modified, Redir, MimeType and Charset to check cache-entry integrity + for (int i=0; ok && i!=5; ++i) { + static const char *what[] = { "ETag", "Last-Modified", "redirection", "mimetype", "charset" }; + if (!fgets(buffer, 400, fs)) { ok = false; - if (ok) - { - // Ignore ETag + kdDebug() << appName << ": error reading " << what[i] << endl; } - - // Last-Modified - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - // Ignore Last-Modified } - fclose(fs); if (ok) { @@ -155,6 +175,7 @@ return info; } + kdDebug() << appName << ": removing cache file " << CEF << endl; unlink( CEF.data()); return 0; } --- kdelibs-3.5.7/kio/kio/scheduler.cpp.orig 2005-10-10 17:05:42.000000000 +0200 +++ kdelibs-3.5.7/kio/kio/scheduler.cpp 2007-06-01 22:48:57.000000000 +0200 @@ -200,7 +200,7 @@ void Scheduler::_doJob(SimpleJob *job) { JobData *jobData = new JobData; jobData->protocol = KProtocolManager::slaveProtocol(job->url(), jobData->proxy); -// kdDebug(7006) << "Scheduler::_doJob protocol=" << jobData->protocol << endl; + //kdDebug(7006) << "Scheduler::_doJob protocol=" << jobData->protocol << " url=" << job->url() << endl; if (job->command() == CMD_GET) { jobData->checkOnHold = checkOnHold; @@ -224,15 +224,22 @@ return; } QString protocol = jobData->protocol; -// kdDebug(7006) << "Scheduler::_scheduleJob protocol=" << protocol << endl; + //kdDebug(7006) << "Scheduler::_scheduleJob protocol=" << protocol << " url=" << job->url() << endl; ProtocolInfo *protInfo = protInfoDict->get(protocol); + + // These HACK s start to annoy me. The kio subsysten deserves a redesign + if (slaveOnHold && job->url() == urlOnHold) { + // put "holded" urls next to run. Allows holded jobs to be scheduleJob()ed. + protInfo->joblist.prepend(job); + } else { protInfo->joblist.append(job); + } slaveTimer.start(0, true); } void Scheduler::_cancelJob(SimpleJob *job) { -// kdDebug(7006) << "Scheduler: canceling job " << job << endl; + //kdDebug(7006) << "Scheduler: canceling job=" << job->url() << " slave=" << slave << endl; Slave *slave = job->slave(); if ( !slave ) { @@ -389,22 +396,29 @@ } } + //kdDebug(7006) << "startJobScheduled: job=" << job->url() + // << " active-slaves=" << protInfo->activeSlaves.count() << " idle=" << idleSlaves->count() << endl; if (!slave) { -// kdDebug(7006) << "No slaves available" << endl; -// kdDebug(7006) << " -- active: " << protInfo->activeSlaves.count() << endl; + //kdDebug(7006) << "No slaves available\n"; return false; } + // Check if the returned slave is already in the active list. This can happen if a slave is put on-hold. + if (protInfo->activeSlaves.findRef(slave) == -1) { protInfo->activeSlaves.append(slave); - idleSlaves->removeRef(slave); - protInfo->joblist.removeRef(job); + bool found = idleSlaves->removeRef(slave); Q_ASSERT(found); + } else { + kdDebug(7006) << "startJobScheduled: HOLDed slave still in active slave list\n"; + } + bool found = protInfo->joblist.removeRef(job); Q_ASSERT(found); // kdDebug(7006) << "scheduler: job started " << job << endl; - JobData *jobData = extraJobData->find(job); setupSlave(slave, job->url(), jobData->protocol, jobData->proxy, newSlave); job->start(slave); + //kdDebug(7006) << "startJobScheduled: running job=" << job->url() + // << " active-slaves=" << protInfo->activeSlaves.count() << " idle=" << idleSlaves->count() << endl; slaveTimer.start(0, true); return true; @@ -439,11 +453,19 @@ if (!slave) return false; - idleSlaves->removeRef(slave); -// kdDebug(7006) << "scheduler: job started " << job << endl; + // Check if the returned slave is already in the active list. This can happen if a slave is put on-hold. + if (protInfo->activeSlaves.findRef(slave) == -1) { + protInfo->activeSlaves.append(slave); + bool found = idleSlaves->removeRef(slave); Q_ASSERT(found); + } else { + kdDebug(7006) << "startJobDirect: HOLDed slave still in active slave list\n"; + } setupSlave(slave, job->url(), protocol, jobData->proxy, newSlave); job->start(slave); + //kdDebug(7006) << "startJobDirect: running job=" << job->url() + // << " active-slaves=" << protInfo->activeSlaves.count() << " idle=" << idleSlaves->count() + // << " slave=" << job->slave() << endl; return true; } @@ -512,6 +534,7 @@ // kdDebug(7006) << "bCanReuse = " << bCanReuse << endl; if (bCanReuse) { + //kdDebug(7006) << "job->url=" << job->url() << " onHold=" << urlOnHold << endl; if (job->url() == urlOnHold) { kdDebug(7006) << "HOLD: Reusing held slave for " << urlOnHold.prettyURL() << endl; @@ -579,7 +602,11 @@ ProtocolInfo *protInfo = protInfoDict->get(jobData->protocol); delete jobData; slave->disconnect(job); - protInfo->activeSlaves.removeRef(slave); + bool found = protInfo->activeSlaves.removeRef(slave); + Q_ASSERT(found); + //kdDebug(7006) << "Scheduler::_jobFinished url=" << job->url() + // << " active-slaves=" << protInfo->activeSlaves.count() << " idle=" << idleSlaves->count() << endl; + if (slave->isAlive()) { JobList *list = coSlaves.find(slave); @@ -609,15 +636,17 @@ void Scheduler::slotSlaveDied(KIO::Slave *slave) { + //kdDebug(7006) << "slave=" << slave << " died" << endl; assert(!slave->isAlive()); ProtocolInfo *protInfo = protInfoDict->get(slave->slaveProtocol()); - protInfo->activeSlaves.removeRef(slave); + bool found = protInfo->activeSlaves.removeRef(slave); if (slave == slaveOnHold) { slaveOnHold = 0; urlOnHold = KURL(); } - idleSlaves->removeRef(slave); + found ^= idleSlaves->removeRef(slave); + Q_ASSERT(found); JobList *list = coSlaves.find(slave); if (list) { @@ -640,8 +669,8 @@ // kdDebug(7006) << "Removing idle slave: " << slave->slaveProtocol() << " " << slave->host() << endl; Slave *removeSlave = slave; slave = idleSlaves->next(); - idleSlaves->removeRef(removeSlave); - slaveList->removeRef(removeSlave); + bool found = idleSlaves->removeRef(removeSlave); Q_ASSERT(found); + found = slaveList->removeRef(removeSlave); Q_ASSERT(found); removeSlave->connection()->close(); removeSlave->deref(); } @@ -708,7 +737,7 @@ } if (!slave) return 0; // Error - idleSlaves->removeRef(slave); + bool found = idleSlaves->removeRef(slave); Q_ASSERT(found); setupSlave(slave, url, protocol, proxy, true, &config); --- kdelibs-3.5.7/kio/kio/http_slave_defaults.h.orig 2005-10-10 17:05:42.000000000 +0200 +++ kdelibs-3.5.7/kio/kio/http_slave_defaults.h 2007-06-01 22:48:57.000000000 +0200 @@ -28,7 +28,7 @@ #define DEFAULT_CACHE_EXPIRE 3*60 // 3 MINS #define DEFAULT_CLEAN_CACHE_INTERVAL 30*60 // 30 MINS #define DEFAULT_CACHE_CONTROL KIO::CC_Refresh // Verify with remote -#define CACHE_REVISION "7\n" // Cache version +#define CACHE_REVISION "8\n" // Cache version // DEFAULT USER AGENT KEY - ENABLES OS NAME #define DEFAULT_USER_AGENT_KEYS "o" // Show OS --- kdelibs-3.5.7/kio/kio/job.cpp.orig 2007-05-14 09:52:35.000000000 +0200 +++ kdelibs-3.5.7/kio/kio/job.cpp 2007-06-01 22:48:57.000000000 +0200 @@ -979,8 +979,8 @@ // happens (unpacking+repacking) staticData.truncate(0); m_incomingMetaData.clear(); - if (queryMetaData("cache") != "reload") - addMetaData("cache","refresh"); + //if (queryMetaData("cache") != "reload") // !!! Why is it necessary to change cache-policy? + // addMetaData("cache","refresh"); m_suspended = false; m_url = m_redirectionURL; m_redirectionURL = KURL(); @@ -1022,6 +1022,7 @@ // Return slave to the scheduler slaveDone(); Scheduler::doJob(this); + Scheduler::scheduleJob(this); // HACK: We cannot tell if the job was originally scheduled or not } } --- kdelibs-3.5.7/khtml/misc/loader.cpp.orig 2007-05-14 09:52:40.000000000 +0200 +++ kdelibs-3.5.7/khtml/misc/loader.cpp 2007-06-01 22:48:58.000000000 +0200 @@ -59,6 +59,7 @@ #include <kapplication.h> #include <kio/job.h> #include <kio/jobclasses.h> +#include <kprotocolmanager.h> #include <kglobal.h> #include <kimageio.h> #include <kcharsets.h> @@ -227,7 +228,7 @@ } CachedCSSStyleSheet::CachedCSSStyleSheet(const DOMString &url, const QString &stylesheet_data) - : CachedObject(url, CSSStyleSheet, KIO::CC_Verify, stylesheet_data.length()) + : CachedObject(url, CSSStyleSheet, KProtocolManager::cacheControl(), stylesheet_data.length()) { m_loading = false; m_status = Persistent; @@ -334,7 +335,7 @@ } CachedScript::CachedScript(const DOMString &url, const QString &script_data) - : CachedObject(url, Script, KIO::CC_Verify, script_data.length()) + : CachedObject(url, Script, KProtocolManager::cacheControl(), script_data.length()) { m_loading = false; m_status = Persistent; @@ -943,7 +944,7 @@ DocLoader::DocLoader(KHTMLPart* part, DocumentImpl* doc) { - m_cachePolicy = KIO::CC_Verify; + m_cachePolicy = KProtocolManager::cacheControl(); m_expireDate = 0; m_creationDate = time(0); m_bautoloadImages = true; @@ -1424,7 +1425,7 @@ template<typename CachedObjectType, enum CachedObject::Type CachedType> CachedObjectType* Cache::requestObject( DocLoader* dl, const KURL& kurl, const char* accept ) { - KIO::CacheControl cachePolicy = dl ? dl->cachePolicy() : KIO::CC_Verify; + KIO::CacheControl cachePolicy = dl ? dl->cachePolicy() : KProtocolManager::cacheControl(); QString url = kurl.url(); CachedObject* o = cache->find(url); --- kdelibs-3.5.7/khtml/kmultipart/kmultipart.cpp.orig 2005-10-10 17:06:03.000000000 +0200 +++ kdelibs-3.5.7/khtml/kmultipart/kmultipart.cpp 2007-06-01 22:48:58.000000000 +0200 @@ -24,6 +24,7 @@ #include <kmimetype.h> #include <klocale.h> #include <kio/job.h> +#include <scheduler.h> #include <qfile.h> #include <ktempfile.h> #include <kmessagebox.h> @@ -164,6 +165,7 @@ // I get "HOLD: Reusing held slave for <url>", and the old data m_job = KIO::get( url, args.reload, false ); + KIO::Scheduler::scheduleJob(static_cast<KIO::SimpleJob *>(m_job)); // See comment in khtml_part.cpp emit started( 0 /*m_job*/ ); // don't pass the job, it would interfer with our own infoMessage --- kdelibs-3.5.7/khtml/java/kjavadownloader.cpp.orig 2005-10-10 17:06:12.000000000 +0200 +++ kdelibs-3.5.7/khtml/java/kjavadownloader.cpp 2007-06-01 22:48:58.000000000 +0200 @@ -25,6 +25,7 @@ #include <kurl.h> #include <kio/job.h> #include <kio/jobclasses.h> +#include <scheduler.h> #include <kdebug.h> #include <qfile.h> @@ -80,6 +81,7 @@ d->url = new KURL( url ); d->job = KIO::get( *d->url, false, false ); + KIO::Scheduler::scheduleJob(d->job); // See comment in khtml_part.cpp d->job->addMetaData("PropagateHttpHeader", "true"); connect( d->job, SIGNAL(data( KIO::Job*, const QByteArray& )), this, SLOT(slotData( KIO::Job*, const QByteArray& )) ); --- kdelibs-3.5.7/khtml/khtml_part.h.orig 2006-07-22 10:16:50.000000000 +0200 +++ kdelibs-3.5.7/khtml/khtml_part.h 2007-06-01 22:48:58.000000000 +0200 @@ -1593,6 +1593,13 @@ void clear(); + /** + * @internal if configured, sets date and the random number generation + * of the Javascript interpreter to fixed values. This ensures the same + * output of javascript-code whenever the same HTML page is displayed. + */ + void ensureDeterministicJS(); + bool scheduleScript( const DOM::Node &n, const QString& script); QVariant crossFrameExecuteScript(const QString& target, const QString& script); --- kdelibs-3.5.7/khtml/khtmlpart_p.h.orig 2006-07-22 10:16:50.000000000 +0200 +++ kdelibs-3.5.7/khtml/khtmlpart_p.h 2007-06-01 22:48:58.000000000 +0200 @@ -36,6 +36,7 @@ #ifndef KHTML_NO_WALLET #include <kwallet.h> #endif +#include <kprotocolmanager.h> #include <qguardedptr.h> #include <qmap.h> @@ -198,7 +199,7 @@ m_job = 0L; m_bComplete = true; m_bLoadEventEmitted = true; - m_cachePolicy = KIO::CC_Verify; + m_cachePolicy = KProtocolManager::cacheControl();; m_manager = 0L; m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings()); m_bClearing = false; @@ -224,6 +225,8 @@ m_javaContext = 0; #endif m_cacheId = 0; + m_magicID = 0; + m_cacheCreationDate = 0; m_frameNameId = 1; m_restored = false; @@ -323,6 +326,8 @@ QString m_encoding; QString m_sheetUsed; long m_cacheId; + long m_magicID; + time_t m_cacheCreationDate; QString scheduledScript; DOM::Node scheduledScriptNode; --- kdelibs-3.5.7/khtml/khtml_part.cpp.orig 2007-05-14 09:52:40.000000000 +0200 +++ kdelibs-3.5.7/khtml/khtml_part.cpp 2007-06-01 22:48:58.000000000 +0200 @@ -46,6 +46,7 @@ #include "rendering/render_layer.h" #include "misc/htmlhashes.h" #include "misc/loader.h" +#include "ecma/kjs_binding.h" #include "xml/dom2_eventsimpl.h" #include "xml/dom2_rangeimpl.h" #include "xml/xml_tokenizer.h" @@ -77,6 +78,7 @@ #include <kstringhandler.h> #include <kio/job.h> #include <kio/global.h> +#include <scheduler.h> #include <kio/netaccess.h> #include <kprotocolmanager.h> #include <kdebug.h> @@ -697,12 +699,16 @@ if (d->m_restored) { + kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL restoring " << m_url.url() << endl; args.metaData().insert("referrer", d->m_pageReferrer); + d->m_cachePolicy = KProtocolManager::cacheControl(); + if (d->m_cachePolicy != KIO::CC_CacheOnly) d->m_cachePolicy = KIO::CC_Cache; } - else if (args.reload) + else if (args.reload) { + kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL forced reload " << m_url.url() << endl; d->m_cachePolicy = KIO::CC_Reload; - else + } else d->m_cachePolicy = KProtocolManager::cacheControl(); if ( args.doPost() && (m_url.protocol().startsWith("http")) ) @@ -713,6 +719,14 @@ else { d->m_job = KIO::get( m_url, false, false ); + // Avoid many parallel http-connections if browsing on a low-bandwidth line, like dial-up. + // People with high-bandwidth can increase the maxInstances= entry in the http.protocol file + // to have more than one http-connection + if (parentPart() != 0) { + KIO::Scheduler::scheduleJob(d->m_job); + } else + kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL reading top url=" << m_url.url() << endl; + d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy)); } @@ -1579,9 +1593,6 @@ begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset ); d->m_job->resume(); - if (d->m_cachePolicy == KIO::CC_Refresh) - d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify); - else d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy); d->m_workingURL = KURL(); @@ -1590,8 +1601,10 @@ // When the first data arrives, the metadata has just been made available d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers"); - time_t cacheCreationDate = d->m_job->queryMetaData("cache-creation-date").toLong(); - d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate); + d->m_cacheCreationDate = d->m_job->queryMetaData("cache-creation-date").toLong(); + d->m_magicID = d->m_job->queryMetaData("magicID").toLong(); + d->m_doc->docLoader()->setCacheCreationDate(d->m_cacheCreationDate); + ensureDeterministicJS(); d->m_pageServices = d->m_job->queryMetaData("PageServices"); d->m_pageReferrer = d->m_job->queryMetaData("referrer"); @@ -1681,6 +1694,7 @@ d->m_encoding = saveEncoding; d->m_pageReferrer = savePageReferrer; d->m_cacheId = saveCacheId; + ensureDeterministicJS(); d->m_workingURL = KURL(); } @@ -1696,6 +1710,28 @@ } } +void KHTMLPart::ensureDeterministicJS() { +#if 0 // Disabled for the moment + kdDebug(6050) << "using magicID=" << d->m_magicID << " cache-creation-date=" << d->m_cacheCreationDate << endl; + + KJSProxy *proxy; + if (true && ((proxy=jScript()) != 0)) { + KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); + if (d->m_cacheCreationDate) { + // Because only ~10 bits of 32 bits of the magicID are used to fill up + // the milliseconds, it should be hard to detect a correlation between + // the date and the random numbers + // Problematic are those cases where magicID is 0 which happens if + // the script file doesn't come through the http slave + double fixedDate = (double)d->m_cacheCreationDate * 1000.0 + (double)(d->m_magicID % 1000); + interpreter->setFixedDate(fixedDate); + } + if (d->m_magicID) + interpreter->mathSRand(d->m_magicID); + } +#endif +} + void KHTMLPart::showError( KIO::Job* job ) { kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete @@ -3267,7 +3303,7 @@ if ( res == KFind::NoMatch ) // i.e. we're done { - kdDebug() << "No more matches." << endl; + //kdDebug() << "No more matches." << endl; if ( !(options & FindNoPopups) && d->m_find->shouldRestart() ) { //kdDebug(6050) << "Restarting" << endl; @@ -3283,7 +3319,7 @@ d->m_find->resetCounts(); slotClearSelection(); } - kdDebug() << "Dialog closed." << endl; + //kdDebug() << "Dialog closed." << endl; } return res == KFind::Match; @@ -3944,13 +3980,13 @@ args.frameName = target; - args.metaData().insert("main_frame_request", - parentPart() == 0 ? "TRUE":"FALSE"); + args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE":"FALSE"); args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip); args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert); args.metaData().insert("PropagateHttpHeader", "true"); args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE"); args.metaData().insert("ssl_activate_warnings", "TRUE"); + args.metaData().insert("cross-domain", toplevelURL().url()); if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" ) { @@ -4303,7 +4339,7 @@ bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName, const QStringList ¶ms, bool isIFrame ) { - //kdDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )" << endl; + kdDebug( 6050 ) << "khtml: requestFrame( ..., " << url << ", " << frameName << " )" << endl; FrameIt it = d->m_frames.find( frameName ); if ( it == d->m_frames.end() ) { @@ -4316,6 +4352,7 @@ (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame; (*it)->m_frame = frame; (*it)->m_params = params; + //(*it)->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload); // Support for <frame src="javascript:string"> if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) @@ -4398,8 +4435,7 @@ child->m_args.metaData().insert("PropagateHttpHeader", "true"); child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip); child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert); - child->m_args.metaData().insert("main_frame_request", - parentPart() == 0 ? "TRUE":"FALSE"); + child->m_args.metaData().insert("main_frame_request", "FALSE"); child->m_args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE"); child->m_args.metaData().insert("ssl_activate_warnings", "TRUE"); @@ -4410,7 +4446,7 @@ args.serviceType = QString::fromLatin1( "text/html" ); if ( args.serviceType.isEmpty() ) { - kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl; + kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << " parent=" << parentPart() << endl; child->m_run = new KHTMLRun( this, child, url, child->m_args, true ); d->m_bComplete = false; // ensures we stop it in checkCompleted... return false; @@ -4833,6 +4869,7 @@ parentPart() == 0 ? "TRUE":"FALSE"); args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE"); args.metaData().insert("ssl_activate_warnings", "TRUE"); + args.metaData().insert("cross-domain", toplevelURL().url()); //WABA: When we post a form we should treat it as the main url //the request should never be considered cross-domain //args.metaData().insert("cross-domain", toplevelURL().url()); @@ -4976,6 +5013,7 @@ QString mimetype = QString::fromLatin1( "text/html" ); args.metaData()["referrer"] = referrer; + args.metaData()["cross-domain"] = toplevelURL().url(); if (!linkUrl.isEmpty()) // over a link { @@ -5372,8 +5410,8 @@ focusNodeNumber = -1; stream << focusNodeNumber; - // Save the doc's cache id. - stream << d->m_cacheId; + // Save the doc's cache id, creation date and magicID + stream << d->m_cacheId << d->m_cacheCreationDate << d->m_magicID; // Save the state of the document (Most notably the state of any forms) QStringList docState; @@ -5459,7 +5497,7 @@ stream >> d->m_focusNodeNumber; d->m_focusNodeRestored = false; - stream >> d->m_cacheId; + stream >> d->m_cacheId >> d->m_cacheCreationDate >> d->m_magicID; stream >> encoding >> sheetUsed >> docState;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor