29 #define QT_NO_CAST_FROM_ASCII
43 #include <QtXml/qdom.h>
44 #include <QtCore/QFile>
45 #include <QtCore/QRegExp>
46 #include <QtCore/QDate>
47 #include <QtCore/QBuffer>
48 #include <QtCore/QIODevice>
49 #include <QtDBus/QtDBus>
50 #include <QtNetwork/QAuthenticator>
51 #include <QtNetwork/QNetworkProxy>
52 #include <QtNetwork/QTcpSocket>
74 #include <solid/networking.h>
94 rich.reserve(
int(plain.length() * 1.1));
95 for (
int i = 0; i < plain.length(); ++i) {
96 if (plain.at(i) == QLatin1Char(
'<'))
97 rich += QLatin1String(
"<");
98 else if (plain.at(i) == QLatin1Char(
'>'))
99 rich += QLatin1String(
">");
100 else if (plain.at(i) == QLatin1Char(
'&'))
101 rich += QLatin1String(
"&");
102 else if (plain.at(i) == QLatin1Char(
'"'))
103 rich += QLatin1String(
""");
113 return (scheme.startsWith(QLatin1String(
"http"), Qt::CaseInsensitive)
114 || scheme == QLatin1String(
"socks"));
127 QCoreApplication app( argc, argv );
133 fprintf(stderr,
"Usage: kio_http protocol domain-socket1 domain-socket2\n");
138 slave.dispatchLoop();
146 return QString::fromLatin1(value.constData(), value.size());
152 if (originURL == QLatin1String(
"true"))
155 KUrl url ( originURL );
165 QStringList la = a.split(QLatin1Char(
'.'), QString::SkipEmptyParts);
166 QStringList lb = b.split(QLatin1Char(
'.'), QString::SkipEmptyParts);
168 if (qMin(la.count(), lb.count()) < 2) {
172 while(la.count() > 2)
174 while(lb.count() > 2)
186 const QStringList headers = _header.split(QRegExp(QLatin1String(
"[\r\n]")));
188 for(QStringList::ConstIterator it = headers.begin(); it != headers.end(); ++it)
192 if (!(*it).contains(QLatin1Char(
':')) ||
193 (*it).startsWith(QLatin1String(
"host"), Qt::CaseInsensitive) ||
194 (*it).startsWith(QLatin1String(
"proxy-authorization"), Qt::CaseInsensitive) ||
195 (*it).startsWith(QLatin1String(
"via"), Qt::CaseInsensitive))
198 sanitizedHeaders += (*it);
199 sanitizedHeaders += QLatin1String(
"\r\n");
201 sanitizedHeaders.chop(2);
203 return sanitizedHeaders;
209 if (config->
readEntry(
"no-spoof-check",
false)) {
213 if (request.
url.
user().isEmpty()) {
218 if (config->
readEntry(QLatin1String(
"cached-www-auth"),
false)) {
249 if (responseCode >= 100 && responseCode < 200) {
252 switch (responseCode) {
258 Q_ASSERT(method != HTTP_HEAD);
268 return method != HTTP_HEAD;
273 return p ==
"https" || p ==
"webdavs";
278 return u.isValid() && u.
hasHost();
292 device =
new QBuffer;
294 if (!device->open(QIODevice::ReadWrite))
302 if (!methodStringOverride.isEmpty())
303 return (methodStringOverride + QLatin1Char(
' ')).toLatin1();
336 case DAV_UNSUBSCRIBE:
337 return "UNSUBSCRIBE ";
357 if (!dt.
time().second()) {
358 ret.append(QLatin1String(
":00"));
360 ret.append(QLatin1String(
" GMT"));
366 return (responseCode == 401) || (responseCode == 407);
369 #define NO_SIZE ((KIO::filesize_t) -1)
372 #define STRTOLL strtoll
374 #define STRTOLL strtol
382 const QByteArray &app )
390 , m_protocol(protocol)
393 , m_socketProxyAuth(0)
395 , m_isLoadingErrorPage(false)
397 , m_iEOFRetryCount(0)
401 connect(
socket(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
421 TCPSlaveBase::reparseConfiguration();
449 setMetaData(QLatin1String(
"request-id"),
m_request.
id);
464 const bool noAuth =
config()->readEntry(
"no-auth",
false);
474 kDebug(7113) <<
"ssl_was_in_use =" << metaData(QLatin1String(
"ssl_was_in_use"));
482 KUrl refUrl(metaData(QLatin1String(
"referrer")));
483 if (refUrl.isValid()) {
486 if (protocol.startsWith(QLatin1String(
"webdav"))) {
487 protocol.replace(0, 6, QLatin1String(
"http"));
491 if (protocol.startsWith(QLatin1String(
"http"))) {
497 if (
config()->readEntry(
"SendLanguageSettings",
true)) {
509 QString resumeOffset = metaData(QLatin1String(
"resume"));
510 if (!resumeOffset.isEmpty()) {
516 QString resumeEndOffset = metaData(QLatin1String(
"resume_until"));
517 if (!resumeEndOffset.isEmpty()) {
525 m_request.
id = metaData(QLatin1String(
"request-id"));
571 if (host.indexOf(QLatin1Char(
':')) == -1) {
574 int pos = host.indexOf(QLatin1Char(
'%'));
600 if (u.host().isEmpty()) {
605 if (u.
path().isEmpty()) {
607 newUrl.
setPath(QLatin1String(
"/"));
630 if (dataInternal || !status) {
689 setMetaData(QLatin1String(
"content-type"),
m_mimeType);
707 QString statSide = metaData(QLatin1String(
"statSide"));
708 if (statSide != QLatin1String(
"source"))
755 QString query = metaData(QLatin1String(
"davSearchQuery"));
756 if ( !query.isEmpty() )
758 QByteArray request =
"<?xml version=\"1.0\"?>\r\n";
759 request.append(
"<D:searchrequest xmlns:D=\"DAV:\">\r\n" );
760 request.append( query.toUtf8() );
761 request.append(
"</D:searchrequest>\r\n" );
767 request =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
768 "<D:propfind xmlns:D=\"DAV:\">";
771 if ( hasMetaData(QLatin1String(
"davRequestResponse")) )
772 request += metaData(QLatin1String(
"davRequestResponse")).toUtf8();
775 request +=
"<D:prop>"
777 "<D:getcontentlength/>"
780 "<D:getcontentlanguage/>"
781 "<D:getcontenttype/>"
782 "<D:getlastmodified/>"
789 request +=
"</D:propfind>";
803 infoMessage(QLatin1String(
""));
813 QDomDocument multiResponse;
816 bool hasResponse =
false;
820 for ( QDomNode n = multiResponse.documentElement().firstChild();
821 !n.isNull(); n = n.nextSibling()) {
822 QDomElement thisResponse = n.toElement();
823 if (thisResponse.isNull())
828 QDomElement href = thisResponse.namedItem(QLatin1String(
"href")).toElement();
829 if ( !href.isNull() ) {
832 QString urlStr = QUrl::fromPercentEncoding(href.text().toUtf8());
833 #if 0 // qt4/kde4 say: it's all utf8...
834 int encoding = remoteEncoding()->encodingMib();
838 KUrl thisURL ( urlStr, encoding );
840 KUrl thisURL( urlStr );
843 if ( thisURL.isValid() ) {
848 name = QLatin1Char(
'.');
853 QDomNodeList propstats = thisResponse.elementsByTagName(QLatin1String(
"propstat"));
863 KMimeType::Ptr mime = KMimeType::findByUrl(thisURL.
fileName(), 0,
false,
true, &accuracy);
864 if (mime && !mime->isDefault() && accuracy == 100) {
865 kDebug(7113) <<
"Setting" << mime->name() <<
"as guessed mime type for" << thisURL.
fileName();
877 listEntry( entry,
false );
879 kDebug(7113) <<
"Error: no URL contained in response to PROPFIND on" << url;
883 if ( stat || !hasResponse ) {
888 listEntry( entry,
true );
915 const int firstSpace = response.indexOf( QLatin1Char(
' ') );
916 const int secondSpace = response.indexOf( QLatin1Char(
' '), firstSpace + 1 );
917 return response.mid( firstSpace + 1, secondSpace - firstSpace - 1 ).toInt();
923 bool foundExecutable =
false;
924 bool isDirectory =
false;
926 uint supportedLockCount = 0;
928 for (
int i = 0; i < propstats.count(); i++)
930 QDomElement propstat = propstats.item(i).toElement();
932 QDomElement status = propstat.namedItem(QLatin1String(
"status")).toElement();
933 if ( status.isNull() )
936 kDebug(7113) <<
"Error, no status code in this propstat";
944 kDebug(7113) <<
"Got status code" << code <<
"(this may mean that some properties are unavailable)";
948 QDomElement prop = propstat.namedItem( QLatin1String(
"prop") ).toElement();
951 kDebug(7113) <<
"Error: no prop segment in this propstat.";
955 if ( hasMetaData( QLatin1String(
"davRequestResponse") ) )
958 doc.appendChild(prop);
962 for ( QDomNode n = prop.firstChild(); !n.isNull(); n = n.nextSibling() )
964 QDomElement
property = n.toElement();
965 if (property.isNull())
968 if ( property.namespaceURI() != QLatin1String(
"DAV:") )
974 if ( property.tagName() == QLatin1String(
"creationdate") )
979 else if ( property.tagName() == QLatin1String(
"getcontentlength") )
984 else if ( property.tagName() == QLatin1String(
"displayname") )
987 setMetaData( QLatin1String(
"davDisplayName"), property.text() );
989 else if ( property.tagName() == QLatin1String(
"source") )
992 QDomElement source =
property.namedItem( QLatin1String(
"link") ).toElement()
993 .namedItem( QLatin1String(
"dst") ).toElement();
994 if ( !source.isNull() )
995 setMetaData( QLatin1String(
"davSource"), source.text() );
997 else if ( property.tagName() == QLatin1String(
"getcontentlanguage") )
1000 setMetaData( QLatin1String(
"davContentLanguage"), property.text() );
1002 else if ( property.tagName() == QLatin1String(
"getcontenttype") )
1007 if ( property.text() == QLatin1String(
"httpd/unix-directory") )
1013 mimeType =
property.text();
1016 else if ( property.tagName() == QLatin1String(
"executable") )
1019 if ( property.text() == QLatin1String(
"T") )
1020 foundExecutable =
true;
1023 else if ( property.tagName() == QLatin1String(
"getlastmodified") )
1028 else if ( property.tagName() == QLatin1String(
"getetag") )
1031 setMetaData( QLatin1String(
"davEntityTag"), property.text() );
1033 else if ( property.tagName() == QLatin1String(
"supportedlock") )
1036 for ( QDomNode n2 = property.firstChild(); !n2.isNull(); n2 = n2.nextSibling() )
1038 QDomElement lockEntry = n2.toElement();
1039 if ( lockEntry.tagName() == QLatin1String(
"lockentry") )
1041 QDomElement lockScope = lockEntry.namedItem( QLatin1String(
"lockscope") ).toElement();
1042 QDomElement lockType = lockEntry.namedItem( QLatin1String(
"locktype") ).toElement();
1043 if ( !lockScope.isNull() && !lockType.isNull() )
1046 supportedLockCount++;
1047 const QString lockCountStr = QString::number(supportedLockCount);
1048 const QString scope = lockScope.firstChild().toElement().tagName();
1049 const QString type = lockType.firstChild().toElement().tagName();
1051 setMetaData( QLatin1String(
"davSupportedLockScope") + lockCountStr, scope );
1052 setMetaData( QLatin1String(
"davSupportedLockType") + lockCountStr, type );
1057 else if ( property.tagName() == QLatin1String(
"lockdiscovery") )
1060 davParseActiveLocks( property.elementsByTagName( QLatin1String(
"activelock") ), lockCount );
1062 else if ( property.tagName() == QLatin1String(
"resourcetype") )
1065 if ( !property.namedItem( QLatin1String(
"collection") ).toElement().isNull() )
1073 kDebug(7113) <<
"Found unknown webdav property:" <<
property.tagName();
1078 setMetaData( QLatin1String(
"davLockCount"), QString::number(lockCount) );
1079 setMetaData( QLatin1String(
"davSupportedLockCount"), QString::number(supportedLockCount) );
1083 if ( foundExecutable || isDirectory )
1093 if ( !isDirectory && !mimeType.isEmpty() )
1102 for (
int i = 0; i < activeLocks.count(); i++ )
1104 const QDomElement activeLock = activeLocks.item(i).toElement();
1108 const QDomElement lockScope = activeLock.namedItem( QLatin1String(
"lockscope") ).toElement();
1109 const QDomElement lockType = activeLock.namedItem( QLatin1String(
"locktype") ).toElement();
1110 const QDomElement lockDepth = activeLock.namedItem( QLatin1String(
"depth") ).toElement();
1112 const QDomElement lockOwner = activeLock.namedItem( QLatin1String(
"owner") ).toElement();
1113 const QDomElement lockTimeout = activeLock.namedItem( QLatin1String(
"timeout") ).toElement();
1114 const QDomElement lockToken = activeLock.namedItem( QLatin1String(
"locktoken") ).toElement();
1116 if ( !lockScope.isNull() && !lockType.isNull() && !lockDepth.isNull() )
1120 const QString lockCountStr = QString::number(lockCount);
1121 const QString scope = lockScope.firstChild().toElement().tagName();
1122 const QString type = lockType.firstChild().toElement().tagName();
1123 const QString depth = lockDepth.text();
1125 setMetaData( QLatin1String(
"davLockScope") + lockCountStr, scope );
1126 setMetaData( QLatin1String(
"davLockType") + lockCountStr, type );
1127 setMetaData( QLatin1String(
"davLockDepth") + lockCountStr, depth );
1129 if ( !lockOwner.isNull() )
1130 setMetaData( QLatin1String(
"davLockOwner") + lockCountStr, lockOwner.text() );
1132 if ( !lockTimeout.isNull() )
1133 setMetaData( QLatin1String(
"davLockTimeout") + lockCountStr, lockTimeout.text() );
1135 if ( !lockToken.isNull() )
1137 QDomElement tokenVal = lockScope.namedItem( QLatin1String(
"href") ).toElement();
1138 if ( !tokenVal.isNull() )
1139 setMetaData( QLatin1String(
"davLockToken") + lockCountStr, tokenVal.text() );
1147 if ( type == QLatin1String(
"dateTime.tz") )
1151 else if ( type == QLatin1String(
"dateTime.rfc1123") )
1166 if ( hasMetaData( QLatin1String(
"davLockCount") ) )
1168 QString response = QLatin1String(
"If:");
1169 int numLocks = metaData( QLatin1String(
"davLockCount") ).toInt();
1170 bool bracketsOpen =
false;
1171 for (
int i = 0; i < numLocks; i++ )
1173 const QString countStr = QString::number(i);
1174 if ( hasMetaData( QLatin1String(
"davLockToken") + countStr ) )
1176 if ( hasMetaData( QLatin1String(
"davLockURL") + countStr ) )
1180 response += QLatin1Char(
')');
1181 bracketsOpen =
false;
1183 response += QLatin1String(
" <") + metaData( QLatin1String(
"davLockURL") + countStr ) + QLatin1Char(
'>');
1186 if ( !bracketsOpen )
1188 response += QLatin1String(
" (");
1189 bracketsOpen =
true;
1193 response += QLatin1Char(
' ');
1196 if ( hasMetaData( QLatin1String(
"davLockNot") + countStr ) )
1197 response += QLatin1String(
"Not ");
1199 response += QLatin1Char(
'<') + metaData( QLatin1String(
"davLockToken") + countStr ) + QLatin1Char(
'>');
1204 response += QLatin1Char(
')');
1206 response += QLatin1String(
"\r\n");
1226 kDebug(7113) <<
" false";
1249 if (ok && verNo > 0 && verNo < 3)
1252 kDebug(7113) <<
"Server supports DAV version" << verNo;
1304 QString tmp(metaData(QLatin1String(
"cache")));
1329 const QByteArray request (
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1330 "<D:propfind xmlns:D=\"DAV:\"><D:prop>"
1332 "<D:getcontentlength/>"
1335 "</D:prop></D:propfind>");
1371 kDebug(7113) << src <<
"->" << dest;
1378 KUrl newDest = dest;
1379 if (newDest.
protocol() == QLatin1String(
"webdavs"))
1381 else if (newDest.
protocol() == QLatin1String(
"webdav"))
1401 kDebug(7113) << src <<
"->" << dest;
1408 KUrl newDest = dest;
1409 if (newDest.
protocol() == QLatin1String(
"webdavs"))
1411 else if (newDest.
protocol() == QLatin1String(
"webdav"))
1505 QDomDocument lockReq;
1507 QDomElement lockInfo = lockReq.createElementNS( QLatin1String(
"DAV:"), QLatin1String(
"lockinfo") );
1508 lockReq.appendChild( lockInfo );
1510 QDomElement lockScope = lockReq.createElement( QLatin1String(
"lockscope") );
1511 lockInfo.appendChild( lockScope );
1513 lockScope.appendChild( lockReq.createElement( scope ) );
1515 QDomElement lockType = lockReq.createElement( QLatin1String(
"locktype") );
1516 lockInfo.appendChild( lockType );
1518 lockType.appendChild( lockReq.createElement( type ) );
1520 if ( !owner.isNull() ) {
1521 QDomElement ownerElement = lockReq.createElement( QLatin1String(
"owner") );
1522 lockReq.appendChild( ownerElement );
1524 QDomElement ownerHref = lockReq.createElement( QLatin1String(
"href") );
1525 ownerElement.appendChild( ownerHref );
1527 ownerHref.appendChild( lockReq.createTextNode( owner ) );
1537 QDomDocument multiResponse;
1540 QDomElement prop = multiResponse.documentElement().namedItem( QLatin1String(
"prop") ).toElement();
1542 QDomElement lockdiscovery = prop.namedItem( QLatin1String(
"lockdiscovery") ).toElement();
1545 davParseActiveLocks( lockdiscovery.elementsByTagName( QLatin1String(
"activelock") ), lockCount );
1547 setMetaData( QLatin1String(
"davLockCount"), QString::number( lockCount ) );
1577 bool callError =
false;
1587 if ( !url.isNull() )
1594 QString ow =
i18n(
"Otherwise, the request would have succeeded." );
1598 action =
i18nc(
"request type",
"retrieve property values" );
1601 action =
i18nc(
"request type",
"set property values" );
1604 action =
i18nc(
"request type",
"create the requested folder" );
1607 action =
i18nc(
"request type",
"copy the specified file or folder" );
1610 action =
i18nc(
"request type",
"move the specified file or folder" );
1613 action =
i18nc(
"request type",
"search in the specified folder" );
1616 action =
i18nc(
"request type",
"lock the specified file or folder" );
1619 action =
i18nc(
"request type",
"unlock the specified file or folder" );
1622 action =
i18nc(
"request type",
"delete the specified file or folder" );
1625 action =
i18nc(
"request type",
"query the server's capabilities" );
1628 action =
i18nc(
"request type",
"retrieve the contents of the specified file or folder" );
1631 action =
i18nc(
"request type",
"run a report in the specified folder" );
1642 errorString =
i18nc(
"%1: code, %2: request type",
"An unexpected error (%1) occurred "
1643 "while attempting to %2.", code, action);
1650 errorString =
i18n(
"The server does not support the WebDAV protocol.");
1664 QDomDocument multiResponse;
1668 QDomElement multistatus = multiResponse.documentElement().namedItem( QLatin1String(
"multistatus") ).toElement();
1670 QDomNodeList responses = multistatus.elementsByTagName( QLatin1String(
"response") );
1672 for (
int i = 0; i < responses.count(); i++)
1677 QDomElement response = responses.item(i).toElement();
1678 QDomElement code = response.namedItem( QLatin1String(
"status") ).toElement();
1680 if ( !code.isNull() )
1683 QDomElement href = response.namedItem( QLatin1String(
"href") ).toElement();
1684 if ( !href.isNull() )
1685 errUrl = href.text();
1686 errors <<
davError( errCode, errUrl );
1691 errorString =
i18nc(
"%1: request type, %2: url",
1692 "An error occurred while attempting to %1, %2. A "
1693 "summary of the reasons is below.", action, url );
1695 errorString += QLatin1String(
"<ul>");
1698 errorString += QLatin1String(
"<li>") + error + QLatin1String(
"</li>");
1700 errorString += QLatin1String(
"</ul>");
1706 errorString =
i18nc(
"%1: request type",
"Access was denied while attempting to %1.", action );
1719 errorString =
i18n(
"A resource cannot be created at the destination "
1720 "until one or more intermediate collections (folders) "
1721 "have been created.");
1727 errorString =
i18n(
"The server was unable to maintain the liveness of "
1728 "the properties listed in the propertybehavior XML "
1729 "element or you attempted to overwrite a file while "
1730 "requesting that files are not overwritten. %1",
1735 errorString =
i18n(
"The requested lock could not be granted. %1", ow );
1741 errorString =
i18n(
"The server does not support the request type of the body.");
1746 errorString =
i18nc(
"%1: request type",
"Unable to %1 because the resource is locked.", action );
1750 errorString =
i18n(
"This action was prevented by another error.");
1756 errorString =
i18nc(
"%1: request type",
"Unable to %1 because the destination server refuses "
1757 "to accept the file or folder.", action );
1763 errorString =
i18n(
"The destination resource does not have sufficient space "
1764 "to record the state of the resource after the execution "
1775 error( errorCode, errorString );
1783 Q_ASSERT(errorString);
1786 errorString->clear();
1798 Q_ASSERT(errorString);
1802 errorString->clear();
1804 switch (responseCode) {
1813 && (responseCode < 200 || responseCode > 400)
1814 && responseCode != 404) {
1816 *errorString =
i18n(
"The resource cannot be deleted." );
1825 Q_ASSERT(errorString);
1831 switch (responseCode) {
1838 *errorString =
i18nc(
"%1: request type",
"Access was denied while attempting to %1.", action );
1844 *errorString =
i18n(
"A resource cannot be created at the destination "
1845 "until one or more intermediate collections (folders) "
1846 "have been created.");
1852 *errorString =
i18nc(
"%1: request type",
"Unable to %1 because the resource is locked.", action );
1858 *errorString =
i18nc(
"%1: request type",
"Unable to %1 because the destination server refuses "
1859 "to accept the file or folder.", action );
1865 *errorString =
i18n(
"The destination resource does not have sufficient space "
1866 "to record the state of the resource after the execution "
1875 && (responseCode < 200 || responseCode > 400)
1876 && responseCode != 404) {
1878 *errorString =
i18nc(
"%1: response code, %2: request type",
1879 "An unexpected error (%1) occurred while attempting to %2.",
1880 responseCode, action);
1907 infoMessage(QLatin1String(
""));
1910 error( errorCode, errorString );
1923 kWarning(7113) <<
"called twice during one request, something is probably wrong.";
1926 SlaveBase::errorPage();
1936 Solid::Networking::Status status = Solid::Networking::status();
1938 kDebug(7113) <<
"networkstatus:" << status;
1941 return status == Solid::Networking::Unconnected;
1946 QDataStream stream(data);
1958 for (
unsigned i = 0; i < n; ++i) {
1960 stream >> url >> mIncomingMetaData;
1973 QString tmp = metaData(QLatin1String(
"cache"));
1988 while (it.hasNext()) {
2000 while (it.hasNext()) {
2017 setMetaData(QLatin1String(
"request-id"), QString::number(requestId++));
2018 sendAndKeepMetaData();
2037 const char* buf =
static_cast<const char*
>(_buf);
2038 while (sent < nbytes)
2040 int n = TCPSlaveBase::write(buf + sent, nbytes - sent);
2065 for (
size_t i = 0; i < size; i++) {
2076 size_t bytesRead = 0;
2079 bytesRead = qMin((
int)size, bufSize);
2081 for (
size_t i = 0; i < bytesRead; i++) {
2082 buf[i] =
m_unreadBuf.constData()[bufSize - i - 1];
2093 if (bytesRead < size) {
2094 int rawRead = TCPSlaveBase::read(buf + bytesRead, size - bytesRead);
2099 bytesRead += rawRead;
2110 Q_ASSERT(numNewlines >=1 && numNewlines <= 2);
2113 while (pos < end && !
m_isEOF) {
2114 int step = qMin((
int)
sizeof(mybuf), end - pos);
2123 for (
size_t i = 0; i < bufferFill ; ++i, ++pos) {
2126 buf[pos] = mybuf[i];
2131 if (buf[pos] ==
'\n') {
2132 bool found = numNewlines == 1;
2135 found = ((pos >= 1 && buf[pos - 1] ==
'\n') ||
2136 (pos >= 2 && buf[pos - 2] ==
'\n' && buf[pos - 1] ==
'\r'));
2140 unread(&mybuf[i], bufferFill - i);
2153 if (previous.host() != now.host() || previous.port() != now.port()) {
2156 if (previous.
user().isEmpty() && previous.
pass().isEmpty()) {
2172 if (url != QLatin1String(
"DIRECT")) {
2191 disconnect(
socket(), SIGNAL(connected()),
2196 int connectError = 0;
2210 const KUrl url (proxyUrl);
2215 errorString = url.
url();
2219 const bool isDirectConnect = (proxyUrl == QLatin1String(
"DIRECT"));
2220 QNetworkProxy::ProxyType proxyType = QNetworkProxy::NoProxy;
2221 if (url.
protocol() == QLatin1String(
"socks")) {
2222 proxyType = QNetworkProxy::Socks5Proxy;
2223 }
else if (!isDirectConnect &&
isAutoSsl()) {
2224 proxyType = QNetworkProxy::HttpProxy;
2227 kDebug(7113) <<
"Connecting to proxy: address=" << proxyUrl <<
"type=" << proxyType;
2229 if (proxyType == QNetworkProxy::NoProxy) {
2232 if (isDirectConnect) {
2236 connectError =
connectToHost(url.host(), url.port(), &errorString);
2237 if (connectError == 0) {
2239 kDebug(7113) <<
"Connected to proxy: host=" << url.host() <<
"port=" << url.port();
2243 kDebug(7113) <<
"Failed to connect to proxy:" << proxyUrl;
2244 badProxyUrls << url;
2247 if (connectError == 0) {
2251 QNetworkProxy proxy (proxyType, url.host(), url.port(), url.
user(), url.
pass());
2252 QNetworkProxy::setApplicationProxy(proxy);
2254 if (connectError == 0) {
2255 kDebug(7113) <<
"Tunneling thru proxy: host=" << url.host() <<
"port=" << url.port();
2260 kDebug(7113) <<
"Failed to connect to proxy:" << proxyUrl;
2261 badProxyUrls << url;
2262 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
2267 if (!badProxyUrls.isEmpty()) {
2272 if (connectError != 0) {
2273 error (connectError, errorString);
2303 bool openForReading =
false;
2307 if (!openForReading && (isCacheOnly || offline)) {
2309 *cacheHasPage =
false;
2312 }
else if (offline) {
2319 if (openForReading) {
2321 *cacheHasPage =
true;
2326 *cacheHasPage =
false;
2339 if (protocol.startsWith(QLatin1String(
"webdav"))) {
2340 protocol.replace(0, qstrlen(
"webdav"), QLatin1String(
"http"));
2397 kDebug(7113) <<
"Couldn't connect, oopsie!";
2409 bool hasBodyData =
false;
2410 bool hasDavData =
false;
2420 bool cacheHasPage =
false;
2422 kDebug(7113) <<
"cacheHasPage =" << cacheHasPage;
2423 return cacheHasPage;
2425 if (!cacheHasPage) {
2442 davHeader = QLatin1String(
"Depth: ");
2443 if ( hasMetaData( QLatin1String(
"davDepth") ) )
2445 kDebug(7113) <<
"Reading DAV depth from metadata:" << metaData( QLatin1String(
"davDepth") );
2446 davHeader += metaData( QLatin1String(
"davDepth") );
2451 davHeader += QLatin1String(
"infinity");
2455 davHeader += QLatin1String(
"\r\n");
2467 davHeader += QLatin1String(
"\r\nDepth: infinity\r\nOverwrite: ");
2469 davHeader += QLatin1String(
"\r\n");
2472 davHeader = QLatin1String(
"Timeout: ");
2475 if ( hasMetaData( QLatin1String(
"davTimeout") ) )
2476 timeout = metaData( QLatin1String(
"davTimeout") ).toUInt();
2478 davHeader += QLatin1String(
"Infinite");
2480 davHeader += QLatin1String(
"Seconds-") + QString::number(timeout);
2482 davHeader += QLatin1String(
"\r\n");
2486 davHeader = QLatin1String(
"Lock-token: ") + metaData(QLatin1String(
"davLockToken")) + QLatin1String(
"\r\n");
2493 case DAV_UNSUBSCRIBE:
2507 header += QLatin1Char(
':') + QString::number(
m_request.
url.port());
2509 header += QLatin1String(
"\r\n");
2516 header += QLatin1String(
"Proxy-Connection: ");
2518 header += QLatin1String(
"Connection: ");
2521 header += QLatin1String(
"keep-alive\r\n");
2523 header += QLatin1String(
"close\r\n");
2528 header += QLatin1String(
"User-Agent: ");
2530 header += QLatin1String(
"\r\n");
2535 header += QLatin1String(
"Referer: ");
2537 header += QLatin1String(
"\r\n");
2542 header += QLatin1String(
"Range: bytes=");
2544 header += QLatin1Char(
'-');
2546 header += QLatin1String(
"\r\n");
2552 header += QLatin1String(
"Range: bytes=");
2554 header += QLatin1String(
"-\r\n");
2561 header += QLatin1String(
"Pragma: no-cache\r\n");
2562 header += QLatin1String(
"Cache-control: no-cache\r\n");
2566 kDebug(7113) <<
"needs validation, performing conditional get.";
2573 header += QLatin1String(
"If-Modified-Since: ") + httpDate + QLatin1String(
"\r\n");
2574 setMetaData(QLatin1String(
"modified"), httpDate);
2578 header += QLatin1String(
"Accept: ");
2579 const QString acceptHeader = metaData(QLatin1String(
"accept"));
2580 if (!acceptHeader.isEmpty())
2581 header += acceptHeader;
2584 header += QLatin1String(
"\r\n");
2587 header += QLatin1String(
"Accept-Encoding: gzip, deflate, x-gzip, x-deflate\r\n");
2590 header += QLatin1String(
"Accept-Charset: ") +
m_request.
charsets + QLatin1String(
"\r\n");
2593 header += QLatin1String(
"Accept-Language: ") +
m_request.
languages + QLatin1String(
"\r\n");
2596 const QString cookieMode = metaData(QLatin1String(
"cookies")).toLower();
2598 if (cookieMode == QLatin1String(
"none"))
2602 else if (cookieMode == QLatin1String(
"manual"))
2605 cookieStr = metaData(QLatin1String(
"setcookies"));
2614 if (!cookieStr.isEmpty())
2615 header += cookieStr + QLatin1String(
"\r\n");
2617 const QString customHeader = metaData( QLatin1String(
"customHTTPHeader") );
2618 if (!customHeader.isEmpty())
2621 header += QLatin1String(
"\r\n");
2624 const QString contentType = metaData(QLatin1String(
"content-type"));
2625 if (!contentType.isEmpty())
2627 if (!contentType.startsWith(QLatin1String(
"content-type"), Qt::CaseInsensitive))
2628 header += QLatin1String(
"Content-Type: ");
2629 header += contentType;
2630 header += QLatin1String(
"\r\n");
2635 header += QLatin1String(
"DNT: 1\r\n");
2648 davHeader += metaData(QLatin1String(
"davHeader"));
2652 davHeader += QLatin1String(
"Content-Type: text/xml; charset=utf-8\r\n");
2655 header += davHeader;
2659 kDebug(7103) <<
"============ Sending Header:";
2660 Q_FOREACH (
const QString &s, header.split(QLatin1String(
"\r\n"), QString::SkipEmptyParts)) {
2666 if (!hasBodyData && !hasDavData)
2667 header += QLatin1String(
"\r\n");
2676 const QByteArray headerBytes = header.toLatin1();
2677 ssize_t written =
write(headerBytes.constData(), headerBytes.length());
2678 bool sendOk = (written == (ssize_t) headerBytes.length());
2682 <<
" -- intended to write" << header.length()
2683 <<
"bytes but wrote" << (int)written <<
".";
2693 kDebug(7113) <<
"sendOk == false. Connection broken !"
2694 <<
" -- intended to write" << header.length()
2695 <<
"bytes but wrote" << (int)written <<
".";
2700 kDebug(7113) <<
"sent it!";
2703 if (hasBodyData || hasDavData)
2706 infoMessage(
i18n(
"%1 contacted. Waiting for reply...",
m_request.
url.host()));
2719 if (forwardImmediately)
2732 if (header.startsWith(QLatin1String(
"content-type:"), Qt::CaseInsensitive)) {
2733 int pos = header.indexOf(QLatin1String(
"charset="), Qt::CaseInsensitive);
2735 const QString charset = header.mid(pos + 8).toLower();
2737 setMetaData(QLatin1String(
"charset"), charset);
2739 }
else if (header.startsWith(QLatin1String(
"content-language:"), Qt::CaseInsensitive)) {
2740 const QString language = header.mid(17).trimmed().toLower();
2741 setMetaData(QLatin1String(
"content-language"), language);
2742 }
else if (header.startsWith(QLatin1String(
"content-disposition:"), Qt::CaseInsensitive)) {
2769 if (
m_mimeType == QLatin1String(
"application/x-targz"))
2770 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2771 else if (
m_mimeType == QLatin1String(
"image/x-png"))
2775 else if (
m_mimeType == QLatin1String(
"audio/microsoft-wave"))
2777 else if (
m_mimeType == QLatin1String(
"image/x-ms-bmp"))
2781 else if (
m_mimeType == QLatin1String(
"application/pkix-cert") ||
2782 m_mimeType == QLatin1String(
"application/binary-certificate")) {
2783 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2787 else if (
m_mimeType == QLatin1String(
"application/x-gzip")) {
2790 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2792 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2797 else if(
m_mimeType == QLatin1String(
"application/x-xz")) {
2800 m_mimeType = QLatin1String(
"application/x-xz-compressed-tar");
2805 else if ((
m_mimeType == QLatin1String(
"text/plain")) || (
m_mimeType == QLatin1String(
"application/octet-stream"))) {
2807 if (ext == QLatin1String(
"BZ2"))
2808 m_mimeType = QLatin1String(
"application/x-bzip");
2809 else if (ext == QLatin1String(
"PEM"))
2810 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2811 else if (ext == QLatin1String(
"SWF"))
2812 m_mimeType = QLatin1String(
"application/x-shockwave-flash");
2813 else if (ext == QLatin1String(
"PLS"))
2815 else if (ext == QLatin1String(
"WMV"))
2816 m_mimeType = QLatin1String(
"video/x-ms-wmv");
2817 else if (ext == QLatin1String(
"WEBM"))
2819 else if (ext == QLatin1String(
"DEB"))
2820 m_mimeType = QLatin1String(
"application/x-deb");
2834 if (
m_mimeType == QLatin1String(
"application/x-tar")) {
2836 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2837 }
else if (
m_mimeType == QLatin1String(
"application/postscript")) {
2841 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2846 m_mimeType != QLatin1String(
"application/x-compressed-tar") &&
2847 m_mimeType != QLatin1String(
"application/x-tgz") &&
2848 m_mimeType != QLatin1String(
"application/x-targz") &&
2849 m_mimeType != QLatin1String(
"application/x-gzip"))) {
2853 m_mimeType = QLatin1String(
"application/x-gzip");
2865 m_mimeType = QLatin1String(
"application/x-bzip");
2872 static bool consume(
const char input[],
int *pos,
int end,
const char *term)
2876 if (idx + (
int)strlen(term) >= end) {
2880 if (strncasecmp(&input[idx], term, strlen(term)) == 0) {
2881 *pos = idx + strlen(term);
2905 bool upgradeRequired =
false;
2909 bool noHeadersFound =
false;
2914 static const int maxHeaderSize = 128 * 1024;
2916 char buffer[maxHeaderSize];
2918 bool bCanResume =
false;
2921 kDebug(7113) <<
"No connection.";
2931 kDebug(7113) <<
"Got socket error:" <<
socket()->errorString();
2940 if (!foundDelimiter && bufPos < maxHeaderSize) {
2941 kDebug(7113) <<
"EOF while waiting for header start.";
2958 kDebug(7113) <<
"Connection broken !";
2962 if (!foundDelimiter) {
2967 kDebug(7103) <<
"============ Received Status Response:";
2968 kDebug(7103) << QByteArray(buffer, bufPos).trimmed();
2973 if (idx != bufPos && buffer[idx] ==
'<') {
2974 kDebug(7103) <<
"No valid HTTP header found! Document starts with XML/HTML tag";
2980 noHeadersFound =
true;
2987 if (
consume(buffer, &idx, bufPos,
"ICY ")) {
2990 }
else if (
consume(buffer, &idx, bufPos,
"HTTP/")) {
2991 if (
consume(buffer, &idx, bufPos,
"1.0")) {
2994 }
else if (
consume(buffer, &idx, bufPos,
"1.1")) {
2999 if (httpRev ==
HTTP_None && bufPos != 0) {
3002 kDebug(7113) <<
"DO NOT WANT." << bufPos;
3010 noHeadersFound =
true;
3021 if (idx != bufPos) {
3037 messageBox(WarningYesNo,
3038 i18nc(
"@info Security check on url being accessed",
3039 "<p>You are about to log in to the site \"%1\" "
3040 "with the username \"%2\", but the website "
3041 "does not require authentication. "
3042 "This may be an attempt to trick you.</p>"
3043 "<p>Is \"%1\" the site you want to visit?</p>",
3045 i18nc(
"@title:window",
"Confirm Website Access"));
3050 setMetaData(QLatin1String(
"{internal~currenthost}LastSpoofedUserName"),
m_request.
url.
user());
3074 upgradeRequired =
true;
3088 setMetaData(QLatin1String(
"permanent-redirect"), QLatin1String(
"true"));
3122 infoMessage(
i18n(
"Server processing request, please wait..." ) );
3130 bool authRequiresAnotherRoundtrip =
false;
3133 if (!noHeadersFound) {
3138 kDebug(7113) <<
"wasAuthError=" << wasAuthError <<
"isAuthError=" << isAuthError
3139 <<
"sameAuthError=" << sameAuthError;
3151 kDebug(7113) <<
" -- full response:" << endl << QByteArray(buffer, bufPos).trimmed();
3154 Q_ASSERT(foundDelimiter);
3161 tokenizer.
tokenize(idx,
sizeof(buffer));
3166 if (tIt.
hasNext() && tIt.
next().toLower().startsWith(
"none")) {
3170 tIt = tokenizer.iterator(
"keep-alive");
3172 QByteArray ka = tIt.
next().trimmed().toLower();
3173 if (ka.startsWith(
"timeout=")) {
3174 int ka_timeout = ka.mid(qstrlen(
"timeout=")).trimmed().toInt();
3186 tIt = tokenizer.iterator(
"content-length");
3191 tIt = tokenizer.iterator(
"content-location");
3193 setMetaData(QLatin1String(
"content-location"),
toQString(tIt.
next().trimmed()));
3199 tIt = tokenizer.iterator(
"content-type");
3205 if (
m_mimeType.startsWith(QLatin1Char(
'"'))) {
3217 Q_FOREACH (
const QByteArray &statement, l) {
3218 const int index = statement.indexOf(
'=');
3220 mediaAttribute =
toQString(statement.mid(0, index));
3222 mediaAttribute =
toQString(statement.mid(0, index));
3223 mediaValue =
toQString(statement.mid(index+1));
3225 mediaAttribute = mediaAttribute.trimmed();
3226 mediaValue = mediaValue.trimmed();
3228 bool quoted =
false;
3229 if (mediaValue.startsWith(QLatin1Char(
'"'))) {
3231 mediaValue.remove(0, 1);
3234 if (mediaValue.endsWith(QLatin1Char(
'"'))) {
3238 kDebug (7113) <<
"Encoding-type:" << mediaAttribute <<
"=" << mediaValue;
3240 if (mediaAttribute == QLatin1String(
"charset")) {
3241 mediaValue = mediaValue.toLower();
3243 setMetaData(QLatin1String(
"charset"), mediaValue);
3245 setMetaData(QLatin1String(
"media-") + mediaAttribute, mediaValue);
3247 setMetaData(QLatin1String(
"media-") + mediaAttribute + QLatin1String(
"-kio-quoted"),
3248 QLatin1String(
"true"));
3255 tIt = tokenizer.iterator(
"content-encoding");
3273 tIt = tokenizer.iterator(
"content-disposition");
3277 tIt = tokenizer.iterator(
"content-language");
3280 if (!language.isEmpty()) {
3281 setMetaData(QLatin1String(
"content-language"), language);
3285 tIt = tokenizer.iterator(
"proxy-connection");
3287 QByteArray pc = tIt.
next().toLower();
3288 if (pc.startsWith(
"close")) {
3290 }
else if (pc.startsWith(
"keep-alive")) {
3295 tIt = tokenizer.iterator(
"link");
3299 if (link.count() == 2) {
3300 QString rel = link[1].trimmed();
3301 if (rel.startsWith(QLatin1String(
"rel=\""))) {
3302 rel = rel.mid(5, rel.length() - 6);
3303 if (rel.toLower() == QLatin1String(
"pageservices")) {
3305 QString url = link[0].remove(QRegExp(QLatin1String(
"[<>]"))).trimmed();
3306 setMetaData(QLatin1String(
"PageServices"), url);
3312 tIt = tokenizer.iterator(
"p3p");
3318 .split(QLatin1Char(
'='), QString::SkipEmptyParts);
3319 if (policy.count() == 2) {
3320 if (policy[0].toLower() == QLatin1String(
"policyref")) {
3321 policyrefs << policy[1].remove(QRegExp(QLatin1String(
"[\")\']"))).trimmed();
3322 }
else if (policy[0].toLower() == QLatin1String(
"cp")) {
3326 const QString s = policy[1].remove(QRegExp(QLatin1String(
"[\")\']")));
3327 const QStringList cps = s.split(QLatin1Char(
' '), QString::SkipEmptyParts);
3332 if (!policyrefs.isEmpty()) {
3333 setMetaData(QLatin1String(
"PrivacyPolicy"), policyrefs.join(QLatin1String(
"\n")));
3335 if (!compact.isEmpty()) {
3336 setMetaData(QLatin1String(
"PrivacyCompactPolicy"), compact.join(QLatin1String(
"\n")));
3343 tIt = tokenizer.iterator(
"connection");
3345 QByteArray connection = tIt.
next().toLower();
3347 if (connection.startsWith(
"close")) {
3349 }
else if (connection.startsWith(
"keep-alive")) {
3353 if (connection.startsWith(
"upgrade")) {
3356 upgradeRequired =
true;
3357 }
else if (upgradeRequired) {
3363 tIt = tokenizer.iterator(
"transfer-encoding");
3372 tIt = tokenizer.iterator(
"content-md5");
3379 tIt = tokenizer.iterator(
"dav");
3389 tIt = tokenizer.iterator(
"upgrade");
3393 upgradeOffers = offered.split(QRegExp(QLatin1String(
"[ \n,\r\t]")), QString::SkipEmptyParts);
3395 Q_FOREACH (
const QString &opt, upgradeOffers) {
3396 if (opt == QLatin1String(
"TLS/1.0")) {
3397 if (!
startSsl() && upgradeRequired) {
3401 }
else if (opt == QLatin1String(
"HTTP/1.1")) {
3403 }
else if (upgradeRequired) {
3411 QByteArray cookieStr;
3412 tIt = tokenizer.iterator(
"set-cookie");
3414 cookieStr +=
"Set-Cookie: ";
3415 cookieStr += tIt.
next();
3418 if (!cookieStr.isEmpty()) {
3423 cookieStr =
"Cross-Domain\n" + cookieStr;
3428 setMetaData(QLatin1String(
"setcookies"), QString::fromUtf8(cookieStr));
3436 kDebug(7113) <<
"cont; returning to mark try_again";
3442 kDebug(7113) <<
"Ignoring keep-alive: otherwise unable to determine response body length.";
3457 authRequiresAnotherRoundtrip =
false;
3462 tIt = tokenizer.iterator(
"location");
3464 locationStr = QString::fromUtf8(tIt.
next().trimmed());
3467 if (!locationStr.isEmpty())
3494 if(u.
protocol() == QLatin1String(
"http")){
3496 }
else if(u.
protocol() == QLatin1String(
"https")){
3536 kDebug(7113) <<
"Reading resource from cache even though the cache plan is not "
3537 "UseCached; the server is probably sending wrong expiry information.";
3547 int nextLinePos = 0;
3548 int prevLinePos = 0;
3549 bool haveMore =
true;
3551 haveMore =
nextLine(buffer, &nextLinePos, bufPos);
3552 int prevLineEnd = nextLinePos;
3553 while (buffer[prevLineEnd - 1] ==
'\r' || buffer[prevLineEnd - 1] ==
'\n') {
3558 prevLineEnd - prevLinePos));
3559 prevLinePos = nextLinePos;
3586 return !authRequiresAnotherRoundtrip;
3594 while (i != parameters.constEnd()) {
3595 setMetaData(QLatin1String(
"content-disposition-") + i.key(), i.value());
3596 kDebug(7113) <<
"Content-Disposition:" << i.key() <<
"=" << i.value();
3603 QString encoding = _encoding.trimmed().toLower();
3605 if (encoding == QLatin1String(
"identity")) {
3607 }
else if (encoding == QLatin1String(
"8bit")) {
3610 }
else if (encoding == QLatin1String(
"chunked")) {
3615 }
else if ((encoding == QLatin1String(
"x-gzip")) || (encoding == QLatin1String(
"gzip"))) {
3616 encs.append(QLatin1String(
"gzip"));
3617 }
else if ((encoding == QLatin1String(
"x-bzip2")) || (encoding == QLatin1String(
"bzip2"))) {
3618 encs.append(QLatin1String(
"bzip2"));
3619 }
else if ((encoding == QLatin1String(
"x-deflate")) || (encoding == QLatin1String(
"deflate"))) {
3620 encs.append(QLatin1String(
"deflate"));
3622 kDebug(7113) <<
"Unknown encoding encountered. "
3623 <<
"Please write code. Encoding =" << encoding;
3642 const qint64 currentDate = time(0);
3659 tIt = tokenizer.iterator(
"date");
3666 tIt = tokenizer.iterator(
"age");
3668 ageHeader = tIt.
next().toLongLong();
3672 if (dateHeader != -1) {
3674 }
else if (ageHeader) {
3681 bool hasCacheDirective =
false;
3686 tIt = tokenizer.iterator(
"cache-control");
3688 QByteArray cacheStr = tIt.
next().toLower();
3689 if (cacheStr.startsWith(
"no-cache") || cacheStr.startsWith(
"no-store")) {
3692 hasCacheDirective =
true;
3693 }
else if (cacheStr.startsWith(
"max-age=")) {
3694 QByteArray ba = cacheStr.mid(qstrlen(
"max-age=")).trimmed();
3696 maxAgeHeader = ba.toLongLong(&ok);
3698 hasCacheDirective =
true;
3703 qint64 expiresHeader = -1;
3704 tIt = tokenizer.iterator(
"expires");
3707 kDebug(7113) <<
"parsed expire date from 'expires' header:" << tIt.
current();
3712 }
else if (expiresHeader != -1) {
3721 expAge = qMin(expAge,
qint64(3600 * 24));
3734 tIt = tokenizer.iterator(
"etag");
3739 kDebug(7103) <<
"304 Not Modified but new entity tag - I don't think this is legal HTTP.";
3744 tIt = tokenizer.iterator(
"warning");
3752 tIt = tokenizer.iterator(
"pragma");
3754 if (tIt.
next().toLower().startsWith(
"no-cache")) {
3756 hasCacheDirective =
true;
3761 tIt = tokenizer.iterator(
"refresh");
3764 setMetaData(QLatin1String(
"http-refresh"),
toQString(tIt.
next().trimmed()));
3768 if (
m_mimeType.startsWith(QLatin1String(
"text/")) && (
m_mimeType != QLatin1String(
"text/css")) &&
3769 (
m_mimeType != QLatin1String(
"text/x-javascript")) && !hasCacheDirective) {
3780 kDebug(7113) <<
"Cache needs validation";
3782 kDebug(7113) <<
"...was revalidated by response code but not by updated expire times. "
3783 "We're going to set the expire date to 60 seconds in the future...";
3789 kDebug(7113) <<
"this proxy or server apparently sends bogus expiry information.";
3806 kDebug(7113) <<
"This webserver is confused about the cacheability of the data it sends.";
3820 if (!cachingAllowed) {
3821 setMetaData(QLatin1String(
"no-cache"), QLatin1String(
"true"));
3822 setMetaData(QLatin1String(
"expire-date"), QLatin1String(
"1"));
3826 setMetaData(QLatin1String(
"expire-date"), tmp);
3829 setMetaData(QLatin1String(
"cache-creation-date"), tmp);
3837 QByteArray cLength (
"Content-Length: ");
3838 cLength += QByteArray::number(
m_POSTbuf->size());
3839 cLength +=
"\r\n\r\n";
3841 kDebug(7113) <<
"sending cached data (size=" <<
m_POSTbuf->size() <<
")";
3844 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3846 kDebug( 7113 ) <<
"Connection broken when sending "
3858 sendOk = (
write(buffer.data(), buffer.size()) == (ssize_t) buffer.size());
3860 kDebug(7113) <<
"Connection broken when sending message body: ("
3891 QByteArray cLength (
"Content-Length: ");
3893 cLength +=
"\r\n\r\n";
3895 kDebug(7113) << cLength.trimmed();
3898 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3908 kDebug(7113) <<
"Connection broken while sending POST content size to" <<
m_request.
url.host();
3927 const int bytesRead = readData(buffer);
3930 if (bytesRead == 0) {
3936 if (bytesRead < 0) {
3950 if (
write(buffer.data(), bytesRead) == static_cast<ssize_t>(bytesRead)) {
3951 bytesSent += bytesRead;
3952 processedSize(bytesSent);
3956 kDebug(7113) <<
"Connection broken while sending POST content to" <<
m_request.
url.host();
3966 kDebug(7113) <<
"keepAlive =" << keepAlive;
3982 QDataStream stream( &data, QIODevice::WriteOnly );
4004 setTimeoutSpecialCommand(-1);
4041 QDataStream stream(data);
4049 stream >> url >> size;
4058 stream >> url >> no_cache >> expireDate;
4064 QFile::remove(filename);
4085 stream >> url >> scope >> type >> owner;
4086 davLock( url, scope, type, owner );
4101 stream >> url >> method >> size;
4102 davGeneric( url, (KIO::HTTP_METHOD) method, size );
4131 if (foundCrLf && bufPos == 2) {
4138 kDebug(7113) <<
"Failed to read chunk header.";
4141 Q_ASSERT(bufPos > 2);
4144 if (nextChunkSize < 0)
4146 kDebug(7113) <<
"Negative chunk size";
4163 int trashBufPos = 2;
4166 if (trashBufPos > 3) {
4168 for (
int i = 0; i < 3; i++) {
4169 trash[i] = trash[trashBufPos - 3 + i];
4176 kDebug(7113) <<
"Failed to read chunk trailer.";
4188 return bytesReceived;
4206 if (bytesReceived <= 0)
4210 return bytesReceived;
4217 kDebug(7113) <<
"Unbounded datastream on a Keep-alive connection!";
4257 kDebug(7113) <<
"Determining mime-type from content...";
4271 if( mime && !mime->isDefault() )
4352 if ( !dataInternal ) {
4363 kDebug(7113) <<
"reading data from cache...";
4375 if (!dataInternal) {
4382 if (!dataInternal) {
4410 QObject::connect(&chain, SIGNAL(
output(QByteArray)),
4420 if ( enc == QLatin1String(
"gzip") )
4422 else if ( enc == QLatin1String(
"deflate") )
4450 if ( enc == QLatin1String(
"gzip") )
4452 else if ( enc == QLatin1String(
"deflate") )
4471 if (bytesReceived == -1)
4481 kDebug(7113) <<
"bytesReceived==-1 sz=" << (int)sz
4482 <<
" Connection broken !";
4489 if (bytesReceived > 0)
4500 sz += bytesReceived;
4502 processedSize( sz );
4526 kWarning(7113) <<
"MD5 checksum MISMATCH! Expected:"
4535 if (!dataInternal && sz <= 1)
4548 data( QByteArray() );
4576 SlaveBase::error( _err, _text );
4584 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4585 (void)kcookiejar.call( QDBus::NoBlock, QLatin1String(
"addCookies"), url,
4586 cookieHeader, windowId );
4592 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4593 QDBusReply<QString> reply = kcookiejar.call( QLatin1String(
"findCookies"), url, windowId );
4595 if ( !reply.isValid() )
4597 kWarning(7113) <<
"Can't communicate with kded_kcookiejar!";
4626 time_t currentDate = time(0);
4639 struct BinaryCacheFileHeader
4651 static const int size = 36;
4663 BinaryCacheFileHeader
header;
4672 QDataStream stream(&ret, QIODevice::WriteOnly);
4673 stream << quint8(
'A');
4674 stream << quint8(
'\n');
4675 stream << quint8(0);
4676 stream << quint8(0);
4678 stream << fileUseCount;
4681 stream <<
qint64(servedDate);
4682 stream << qint64(lastModifiedDate);
4683 stream << qint64(expireDate);
4685 stream << bytesCached;
4686 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size);
4695 return byte == value;
4698 static bool readTime(QDataStream *stream, time_t *time)
4702 *time =
static_cast<time_t
>(intTime);
4705 return check == intTime;
4714 if (d.size() != BinaryCacheFileHeader::size) {
4717 QDataStream stream(d);
4718 stream.setVersion(QDataStream::Qt_4_5);
4729 stream >> fileUseCount;
4732 ok = ok &&
readTime(&stream, &servedDate);
4733 ok = ok &&
readTime(&stream, &lastModifiedDate);
4734 ok = ok &&
readTime(&stream, &expireDate);
4739 stream >> bytesCached;
4764 static const char linefeed =
'\n';
4766 dev->write(&linefeed, 1);
4773 Q_ASSERT(file->openMode() & QIODevice::WriteOnly);
4775 file->seek(BinaryCacheFileHeader::size);
4789 if (line->isEmpty() || !line->endsWith(
'\n')) {
4801 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4805 if (
storableUrl(desiredUrl).toEncoded() != readBuf) {
4806 kDebug(7103) <<
"You have witnessed a very improbable hash collision!";
4820 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4826 qint64 oldPos = file->pos();
4827 file->seek(BinaryCacheFileHeader::size);
4830 Q_ASSERT(file->pos() == oldPos);
4839 if (ok && !readBuf.isEmpty()) {
4850 QCryptographicHash hash(QCryptographicHash::Sha1);
4852 return toQString(hash.result().toHex());
4858 if (!filePath.endsWith(QLatin1Char(
'/'))) {
4859 filePath.append(QLatin1Char(
'/'));
4872 kDebug(7113) <<
"File unexpectedly open; old file is" << file->fileName()
4873 <<
"new name is" << filename;
4874 Q_ASSERT(file->fileName() == filename);
4877 file =
new QFile(filename);
4878 if (file->open(QIODevice::ReadOnly)) {
4879 QByteArray
header = file->read(BinaryCacheFileHeader::size);
4881 kDebug(7103) <<
"Cache file header is invalid.";
4891 if (!file->isOpen()) {
4909 Q_ASSERT(!qobject_cast<QTemporaryFile *>(file));
4910 Q_ASSERT((file->openMode() & QIODevice::WriteOnly) == 0);
4911 Q_ASSERT(file->fileName() == filename);
4912 kDebug(7113) <<
"deleting expired cache entry and recreating.";
4920 file->open(QIODevice::WriteOnly);
4926 if ((file->openMode() & QIODevice::WriteOnly) == 0) {
4927 kDebug(7113) <<
"Could not open file for writing:" << file->fileName()
4928 <<
"due to error" << file->error();
4939 QDataStream stream(&ret, QIODevice::WriteOnly);
4940 stream.setVersion(QDataStream::Qt_4_5);
4942 stream.skipRawData(BinaryCacheFileHeader::size);
4947 int basenameStart = fileName.lastIndexOf(QLatin1Char(
'/')) + 1;
4949 stream.writeRawData(baseName.constData(), baseName.size());
4951 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size +
sizeof(quint32) +
s_hashedUrlNibbles);
4967 QByteArray ccCommand;
4970 if (file->openMode() & QIODevice::WriteOnly) {
4976 tempFile->write(header);
4980 QString oldName = tempFile->fileName();
4982 int basenameStart = newName.lastIndexOf(QLatin1Char(
'/')) + 1;
4985 kDebug(7113) <<
"Renaming temporary file" << oldName <<
"to" << newName;
4988 tempFile->setAutoRemove(
false);
4992 if (!QFile::rename(oldName, newName)) {
4995 kDebug(7113) <<
"Renaming temporary file failed, deleting it instead.";
4996 QFile::remove(oldName);
5003 }
else if (file->openMode() == QIODevice::ReadOnly) {
5004 Q_ASSERT(!tempFile);
5010 if (!ccCommand.isEmpty()) {
5021 if (attempts == 2) {
5035 kDebug(7113) <<
"Could not connect to cache cleaner, not updating stats of this cache file.";
5045 if (ret.isEmpty()) {
5062 kDebug(7113) <<
"Caching disabled because content size is too big.";
5092 m_POSTbuf->write (data.constData(), data.size());
5118 const int bytesRead = readData(buffer);
5120 if (bytesRead < 0) {
5125 if (bytesRead == 0) {
5129 m_POSTbuf->write(buffer.constData(), buffer.size());
5157 if (useCachedAuth && checkCachedAuthentication(authinfo)) {
5158 const QByteArray cachedChallenge =
config()->readEntry(
"www-auth-challenge", QByteArray());
5159 if (!cachedChallenge.isEmpty()) {
5162 kDebug(7113) <<
"creating www authentcation header from cached info";
5180 if (checkCachedAuthentication(authinfo)) {
5181 const QByteArray cachedChallenge =
config()->readEntry(
"proxy-auth-challenge", QByteArray());
5182 if (!cachedChallenge.isEmpty()) {
5185 kDebug(7113) <<
"creating proxy authentcation header from cached info";
5195 ret +=
"Authorization: ";
5200 ret +=
"Proxy-Authorization: ";
5210 case QNetworkProxy::DefaultProxy:
5212 case QNetworkProxy::Socks5Proxy:
5213 return QLatin1String(
"socks");
5214 case QNetworkProxy::NoProxy:
5216 case QNetworkProxy::HttpProxy:
5217 case QNetworkProxy::HttpCachingProxy:
5218 case QNetworkProxy::FtpCachingProxy:
5223 return QLatin1String(
"http");
5228 kDebug(7113) <<
"realm:" << authenticator->realm() <<
"user:" << authenticator->user();
5239 info.
username = authenticator->user();
5242 const bool haveCachedCredentials = checkCachedAuthentication(info);
5247 if (!haveCachedCredentials || retryAuth) {
5250 connect(
socket(), SIGNAL(connected()),
5253 info.
prompt =
i18n(
"You need to supply a username and a password for "
5254 "the proxy server listed below before you are allowed "
5255 "to access any sites.");
5260 const QString errMsg ((retryAuth ?
i18n(
"Proxy Authentication Failed.") :
QString()));
5262 if (!openPasswordDialog(info, errMsg)) {
5263 kDebug(7113) <<
"looks like the user canceled proxy authentication.";
5270 authenticator->setUser(info.
username);
5271 authenticator->setPassword(info.
password);
5272 authenticator->setOption(QLatin1String(
"keepalive"), info.
keepPassword);
5287 kDebug(7113) <<
"Saving authenticator";
5288 disconnect(
socket(), SIGNAL(connected()),
5300 cacheAuthentication(a);
5309 bool alreadyCached =
false;
5314 alreadyCached =
config()->readEntry(
"cached-www-auth",
false);
5318 alreadyCached =
config()->readEntry(
"cached-proxy-auth",
false);
5325 if (auth && (!auth->
realm().isEmpty() || !alreadyCached)) {
5328 setMetaData(QLatin1String(
"{internal~currenthost}cached-www-auth"), QLatin1String(
"true"));
5330 setMetaData(QLatin1String(
"{internal~currenthost}www-auth-realm"), authinfo.
realmValue);
5332 setMetaData(QLatin1String(
"{internal~currenthost}www-auth-challenge"), authinfo.
digestInfo);
5334 setMetaData(QLatin1String(
"{internal~allhosts}cached-proxy-auth"), QLatin1String(
"true"));
5336 setMetaData(QLatin1String(
"{internal~allhosts}proxy-auth-realm"), authinfo.
realmValue);
5338 setMetaData(QLatin1String(
"{internal~allhosts}proxy-auth-challenge"), authinfo.
digestInfo);
5344 cacheAuthentication(authinfo);
5360 authTokens = tokenizer->iterator(
"www-authenticate").all();
5363 authinfo.
prompt =
i18n(
"You need to supply a username and a "
5364 "password to access this site.");
5370 Q_ASSERT(QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy);
5372 authTokens = tokenizer->iterator(
"proxy-authenticate").all();
5375 authinfo.
prompt =
i18n(
"You need to supply a username and a password for "
5376 "the proxy server listed below before you are allowed "
5377 "to access any sites." );
5381 bool authRequiresAnotherRoundtrip =
false;
5386 if (!authTokens.isEmpty()) {
5388 authRequiresAnotherRoundtrip =
true;
5392 if ((*auth)->wasFinalStage()) {
5394 i18n(
"Authentication Failed.") :
5395 i18n(
"Proxy Authentication Failed."));
5403 QMutableListIterator<QByteArray> it (authTokens);
5404 const QByteArray authScheme ((*auth)->scheme().trimmed());
5405 while (it.hasNext()) {
5406 if (qstrnicmp(authScheme.constData(), it.next().constData(), authScheme.length()) != 0) {
5413 try_next_auth_scheme:
5416 const QByteArray authScheme ((*auth)->scheme().trimmed());
5417 if (qstrnicmp(authScheme.constData(), bestOffer.constData(), authScheme.length()) != 0) {
5429 kDebug(7113) <<
"Trying authentication scheme:" << (*auth)->scheme();
5435 bool generateAuthHeader =
true;
5436 if ((*auth)->needCredentials()) {
5447 if (authinfo.
realmValue.isEmpty() && !(*auth)->supportsPathMatching())
5448 authinfo.
realmValue = QLatin1String((*auth)->scheme());
5453 const KUrl reqUrl = authinfo.
url;
5454 if (!errorMsg.isEmpty() || !checkCachedAuthentication(authinfo)) {
5456 authinfo.
url = reqUrl;
5461 if (!openPasswordDialog(authinfo, errorMsg)) {
5462 generateAuthHeader =
false;
5463 authRequiresAnotherRoundtrip =
false;
5467 kDebug(7113) <<
"looks like the user canceled the authentication dialog";
5477 if (generateAuthHeader) {
5478 (*auth)->generateResponse(username, password);
5479 (*auth)->setCachePasswordEnabled(authinfo.
keepPassword);
5481 kDebug(7113) <<
"isError=" << (*auth)->isError()
5482 <<
"needCredentials=" << (*auth)->needCredentials()
5483 <<
"forceKeepAlive=" << (*auth)->forceKeepAlive()
5484 <<
"forceDisconnect=" << (*auth)->forceDisconnect();
5486 if ((*auth)->isError()) {
5487 authTokens.removeOne(bestOffer);
5488 if (!authTokens.isEmpty()) {
5489 goto try_next_auth_scheme;
5492 authRequiresAnotherRoundtrip =
false;
5495 }
else if ((*auth)->forceKeepAlive()) {
5498 }
else if ((*auth)->forceDisconnect()) {
5505 authRequiresAnotherRoundtrip =
false;
5512 return authRequiresAnotherRoundtrip;
#define DEFAULT_RESPONSE_TIMEOUT
#define DEFAULT_KEEP_ALIVE_TIMEOUT
void cachePostData(const QByteArray &)
Caches the POST data in a temporary buffer.
static KAbstractHttpAuthentication * newAuth(const QByteArray &offer, KConfigGroup *config=0)
Returns authentication object instance appropriate for offer.
QString i18n(const char *text)
quint16 defaultPort() const
void adjustPath(AdjustPathOption trailing)
bool m_davHostUnsupported
void davStatList(const KUrl &url, bool stat=true)
void cacheParseResponseHeader(const HeaderTokenizer &tokenizer)
KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, const KAutostart::StartPhase &aDefault)
void fixupResponseMimetype()
fix common mimetype errors by webservers.
QString findCookies(const QString &url)
Look for cookies in the cookiejar.
QByteArray methodString() const
int readLimited()
Read maximum m_iSize bytes.
virtual void mkdir(const KUrl &url, int _permissions)
bool sendErrorPageNotification()
Call SlaveBase::errorPage() and remember that we've called it.
void parseContentDisposition(const QString &disposition)
bool cacheFileOpenWrite()
void slotInput(const QByteArray &d)
void saveAuthenticationData()
Saves HTTP authentication data.
static int httpDelError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
static QString decode_string(const QString &str)
static bool nextLine(const char input[], int *pos, int end)
#define DEFAULT_HTTP_PORT
virtual void copy(const KUrl &src, const KUrl &dest, int _permissions, KIO::JobFlags flags)
bool m_isChunked
Chunked transfer encoding.
void setCacheabilityMetadata(bool cachingAllowed)
void insert(uint field, const QString &value)
long m_maxCacheSize
Maximum cache size in Kb.
bool readResponseHeader()
This function will read in the return header from the server.
bool sendQuery()
This function is responsible for opening up the connection to the remote HTTP server and sending the ...
static bool readTime(QDataStream *stream, time_t *time)
void httpCloseConnection()
Close connection.
bool m_isRedirection
Indicates current request is a redirection.
bool readDelimitedText(char *buf, int *idx, int end, int numNewlines)
QString m_strCacheDir
Location of the cache.
const char * name(StandardAction id)
QLocalSocket m_cacheCleanerConnection
Connection to the cache cleaner process.
static KDateTime fromString(const QString &string, TimeFormat format=ISODate, bool *negZero=0)
The request for the current connection.
void setRef(const QString &fragment)
QByteArray cacheFileReadPayload(int maxLength)
static bool supportedProxyScheme(const QString &scheme)
void setEncodedPathAndQuery(const QString &_txt)
QString toString(const QString &format) const
static bool isEncryptedHttpVariety(const QByteArray &p)
static bool isHttpProxy(const KUrl &u)
KIO::filesize_t m_iPostDataSize
virtual void closeConnection()
Forced close of connection.
QString cacheFilePathFromUrl(const KUrl &url) const
#define DEFAULT_MAX_CACHE_SIZE
bool maybeSetRequestUrl(const KUrl &)
QByteArray m_receiveBuf
Receive buffer.
CachePlan plan(time_t maxCacheAge) const
bool connectToHost(const QString &protocol, const QString &host, quint16 port)
static bool canHaveResponseBody(int responseCode, KIO::HTTP_METHOD method)
virtual void get(const KUrl &url)
#define DEFAULT_CACHE_EXPIRE
QString methodStringOverride
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void davSetRequest(const QByteArray &requestXML)
Performs a WebDAV stat or list.
static KUrl storableUrl(const KUrl &url)
bool isOffline()
Check network status.
void setQuery(const QString &query)
KIO::filesize_t m_iBytesLeft
of bytes left to receive in this message.
QString i18nc(const char *ctxt, const char *text)
KSharedConfigPtr config()
void error(int errid, const QString &text)
#define DEFAULT_MIME_TYPE
void setPath(const QString &path)
virtual void put(const KUrl &url, int _mode, KIO::JobFlags flags)
unsigned int responseCode
static QString formatHttpDate(qint64 date)
int kdemain(int argc, char **argv)
static bool isCompatibleNextUrl(const KUrl &previous, const KUrl &now)
static QIODevice * createPostBufferDeviceFor(KIO::filesize_t size)
void setUser(const QString &user)
virtual void listDir(const KUrl &url)
void setTime_t(qint64 seconds)
bool sendHttpError()
Generate and send error message based on response code.
bool deserialize(const QByteArray &)
virtual void fillKioAuthInfo(KIO::AuthInfo *ai) const =0
KIO compatible data to find cached credentials.
QByteArray m_webDavDataBuf
QStringList m_responseHeaders
All headers.
int readUnlimited()
Read as much as possible.
void setProtocol(const QString &proto)
static QString sanitizeCustomHTTPHeader(const QString &_header)
QStringList m_contentEncodings
bool m_isLoadingErrorPage
long parseDateTime(const QString &input, const QString &type)
Parses a date & time string.
static const int s_hashedUrlBits
static bool readLineChecked(QIODevice *dev, QByteArray *line)
int codeFromResponse(const QString &response)
Returns the error code from a "HTTP/1.1 code Code Name" string.
static QString filePath(const QString &baseName)
QString authenticationHeader()
create HTTP authentications response(s), if any
bool httpShouldCloseConnection()
Check whether to keep or close the connection.
#define DEFAULT_PARTIAL_CHARSET_HEADER
long long numberValue(uint field, long long defaultValue=0) const
QList< HTTPRequest > m_requestQueue
void multiGet(const QByteArray &data)
bool isUtf8(const char *str)
void output(QList< Action > actions, QHash< QString, QString > domain)
bool m_isBusy
Busy handling request queue.
static const int s_hashedUrlBytes
virtual void mimetype(const KUrl &url)
QAuthenticator * m_socketProxyAuth
bool satisfyRequestFromCache(bool *cacheHasPage)
Return true if the request is already "done", false otherwise.
virtual void setHost(const QString &host, quint16 port, const QString &user, const QString &pass)
void updateCredentials(const HTTPRequest &request)
KAbstractHttpAuthentication * m_wwwAuth
KIO::filesize_t endoffset
bool doNotWWWAuthenticate
static bool compareByte(QDataStream *stream, quint8 value)
void post(const KUrl &url, qint64 size=-1)
static QByteArray bestOffer(const QList< QByteArray > &offers)
Choose the best authentication mechanism from the offered ones.
void setPass(const QString &pass)
void fixupResponseContentEncoding()
fix common content-encoding errors by webservers.
bool parseHeaderFromCache()
enum HTTPProtocol::HTTPRequest::@1 cookieMode
QString stringValue(uint field) const
void davLock(const KUrl &url, const QString &scope, const QString &type, const QString &owner)
void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value)
static bool isValidProxy(const KUrl &u)
void resetResponseParsing()
Resets variables related to parsing a response.
void davGeneric(const KUrl &url, KIO::HTTP_METHOD method, qint64 size=-1)
#define DEFAULT_MAX_CACHE_AGE
static void skipSpace(const char input[], int *pos, int end)
CopyJob * link(const KUrl &src, const KUrl &destDir, JobFlags flags=DefaultFlags)
QByteArray headerFragment() const
insert this into the next request header after "Authorization: " or "Proxy-Authorization: " ...
void davUnlock(const KUrl &url)
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
int readChunked()
Read a chunk.
HTTPProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
void disconnectFromHost()
void cacheFileWriteTextHeader()
void slotData(const QByteArray &)
virtual void generateResponse(const QString &user, const QString &password)=0
what to do in response to challenge
QByteArray current() const
bool proceedUntilResponseHeader()
Ensure we are connected, send our query, and get the response header.
KIO::CacheControl parseCacheControl(const QString &cacheControl)
static QString protocolForProxyType(QNetworkProxy::ProxyType type)
#define DEFAULT_HTTPS_PORT
static int httpPutError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
static const int s_hashedUrlNibbles
virtual void reparseConfiguration()
virtual void setChallenge(const QByteArray &c, const KUrl &resource, const QByteArray &httpMethod)
initiate authentication with challenge string (from HTTP header)
static int httpGenericError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
bool retrieveAllData()
Returns true on successful retrieval of all content data.
QIODevice * socket() const
KIO::filesize_t m_iContentLeft
of content bytes left
void forwardHttpResponseHeader(bool forwardImmediately=true)
void resetSessionSettings()
Resets any per session settings.
void httpClose(bool keepAlive)
Close transfer.
QByteArray serialize() const
virtual void slave_status()
#define DEFAULT_LANGUAGE_HEADER
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
bool handleAuthenticationHeader(const HeaderTokenizer *tokenizer)
Handles HTTP authentication.
void clearPostDataBuffer()
Clears the POST data buffer.
static QMap< QString, QString > contentDispositionParser(const QString &disposition)
bool readBody(bool dataInternal=false)
This function is our "receive" function.
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
unsigned int prevResponseCode
#define DEFAULT_ACCEPT_HEADER
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
void resetConnectionSettings()
Resets any per connection settings.
bool cacheFileReadTextHeader2()
load the rest of the text fields
bool cacheFileReadTextHeader1(const KUrl &desiredUrl)
check URL to guard against hash collisions, and load the etag for validation
static const int s_MaxInMemPostBufSize
virtual void rename(const KUrl &src, const KUrl &dest, KIO::JobFlags flags)
bool allowTransferCompression
void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *)
bool httpOpenConnection()
Open connection.
QStringList m_davCapabilities
void davParseActiveLocks(const QDomNodeList &activeLocks, uint &lockCount)
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void addFilter(HTTPFilterBase *filter)
static QString toQString(const QByteArray &value)
void saveProxyAuthenticationForSocket()
ssize_t write(const void *buf, size_t nbytes)
A thin wrapper around TCPSlaveBase::write() that will retry writing as long as no error occurs...
void unread(char *buf, size_t size)
QString formatRequestUri() const
virtual void stat(const KUrl &url)
static QString htmlEscape(const QString &plain)
virtual void del(const KUrl &url, bool _isfile)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QString davProcessLocks()
Extracts locks from metadata Returns the appropriate If: header.
virtual void special(const QByteArray &data)
Special commands supported by this slave : 1 - HTTP POST 2 - Cache has been updated 3 - SSL Certifica...
static QByteArray makeCacheCleanerCommand(const HTTPProtocol::CacheTag &cacheTag, CacheCleanerCommandCode cmd)
static QString filenameFromUrl(const KUrl &url)
QByteArray m_mimeTypeBuffer
static void writeLine(QIODevice *dev, const QByteArray &line)
void davParsePropstats(const QDomNodeList &propstats, KIO::UDSEntry &entry)
size_t readBuffered(char *buf, size_t size, bool unlimited=true)
QString convertSize(KIO::filesize_t size)
#define DEFAULT_CACHE_CONTROL
static bool isPotentialSpoofingAttack(const HTTPProtocol::HTTPRequest &request, const KConfigGroup *config)
void addEncoding(const QString &, QStringList &)
Add an encoding on to the appropriate stack this is nececesary because transfer encodings and content...
void addCookies(const QString &url, const QByteArray &cookieHeader)
Send a cookie to the cookiejar.
static bool isCrossDomainRequest(const QString &fqdn, const QString &originURL)
static bool consume(const char input[], int *pos, int end, const char *term)
void sendCacheCleanerCommand(const QByteArray &command)
KIO::filesize_t m_iSize
Expected size of message.
T readEntry(const QString &key, const T &aDefault) const
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
static bool isAuthenticationRequired(int responseCode)
CopyJob * trash(const KUrl &src, JobFlags flags=DefaultFlags)
void initFrom(const HTTPRequest &request)
QString realm() const
Returns the realm sent by the server.
void cacheFileWritePayload(const QByteArray &d)
KAbstractHttpAuthentication * m_proxyAuth
bool m_dataInternal
Data is for internal consumption.
bool waitForResponse(int t)
void proceedUntilResponseContent(bool dataInternal=false)
Do everything proceedUntilResponseHeader does, and also get the response body.
QString number(KIO::filesize_t size)
QStringList m_transferEncodings
bool doNotProxyAuthenticate
int m_maxCacheAge
Maximum age of a cache entry in seconds.
void slotFilterError(const QString &text)
QString davError(int code=-1, const QString &url=QString())