Index: kioslave/http/http.cpp =================================================================== --- kioslave/http/http.cpp (Revision 950464) +++ kioslave/http/http.cpp (Revision 950465) @@ -229,16 +229,12 @@ } +#define NO_SIZE ((KIO::filesize_t) -1) - - - -#define NO_SIZE ((KIO::filesize_t) -1) - #ifdef HAVE_STRTOLL -#define STRTOLL strtoll +#define STRTOLL strtoll #else -#define STRTOLL strtol +#define STRTOLL strtol #endif @@ -259,6 +255,7 @@ , m_proxyAuth(0) , m_socketProxyAuth(0) , m_isError(false) + , m_isLoadingErrorPage(false) , m_remoteRespTimeout(DEFAULT_RESPONSE_TIMEOUT) { reparseConfiguration(); @@ -292,6 +289,7 @@ { m_isEOF = false; m_isError = false; + m_isLoadingErrorPage = false; } void HTTPProtocol::resetResponseParsing() @@ -575,8 +573,11 @@ m_server.initFrom(m_request); } break; - } else if (m_isError) { - // Hard error, abort everything. + } else if (m_isError || m_isLoadingErrorPage) { + // Unrecoverable error, abort everything. + // Also, if we've just loaded an error page there is nothing more to do. + // In that case we abort to avoid loops; some webservers manage to send 401 and + // no authentication request. Or an auth request we don't understand. return false; } @@ -1728,6 +1729,15 @@ error( ERR_SLAVE_DEFINED, errorString ); } +void HTTPProtocol::setLoadingErrorPage() +{ + if (m_isLoadingErrorPage) { + kWarning(7113) << "called twice during one request, something is probably wrong."; + } + m_isLoadingErrorPage = true; + SlaveBase::errorPage(); +} + bool HTTPProtocol::isOffline(const KUrl &url) { const int NetWorkStatusUnknown = 1; @@ -2720,7 +2730,7 @@ ; // Ignore error } else { if (m_request.preferErrorPage) { - errorPage(); + setLoadingErrorPage(); } else { error(ERR_INTERNAL_SERVER, m_request.url.url()); return false; @@ -2743,7 +2753,7 @@ // Any other client errors // Tell that we will only get an error page here. if (m_request.preferErrorPage) { - errorPage(); + setLoadingErrorPage(); } else { error(ERR_DOES_NOT_EXIST, m_request.url.url()); return false; @@ -3303,14 +3313,14 @@ kDebug(7113) << "pointer to auth class is now" << *auth; if (!(*auth)) { if (m_request.preferErrorPage) { - errorPage(); + setLoadingErrorPage(); } else { error(ERR_UNSUPPORTED_ACTION, "Unknown Authorization method!"); return false; } } - // auth may still be null due to errorPage(). + // *auth may still be null due to setLoadingErrorPage(). if (*auth) { // remove trailing space from the method string, or digest auth will fail @@ -3357,7 +3367,7 @@ if ((*auth)->isError()) { if (m_request.preferErrorPage) { - errorPage(); + setLoadingErrorPage(); } else { error(ERR_UNSUPPORTED_ACTION, "Authorization failed!"); return false; Index: kioslave/http/http.h =================================================================== --- kioslave/http/http.h (Revision 950464) +++ kioslave/http/http.h (Revision 950465) @@ -259,6 +259,7 @@ void cacheUpdate( const KUrl &url, bool nocache, time_t expireDate); void httpError(); // Generate error message based on response code + void setLoadingErrorPage(); // Call SlaveBase::errorPage() and remember that we've called it bool isOffline(const KUrl &url); // Check network status @@ -523,6 +524,8 @@ // Indicates whether there was some connection error. bool m_isError; + // Whether we are loading an error page (we should close the connection afterwards) + bool m_isLoadingErrorPage; // Values that determine the remote connection timeouts. int m_remoteRespTimeout;