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 ssize_t written =
write(header.toLatin1(), header.length());
2677 bool sendOk = (written == (ssize_t) header.length());
2681 <<
" -- intended to write" << header.length()
2682 <<
"bytes but wrote" << (int)written <<
".";
2692 kDebug(7113) <<
"sendOk == false. Connection broken !"
2693 <<
" -- intended to write" << header.length()
2694 <<
"bytes but wrote" << (int)written <<
".";
2699 kDebug(7113) <<
"sent it!";
2702 if (hasBodyData || hasDavData)
2705 infoMessage(
i18n(
"%1 contacted. Waiting for reply...",
m_request.
url.host()));
2718 if (forwardImmediately)
2731 if (header.startsWith(QLatin1String(
"content-type:"), Qt::CaseInsensitive)) {
2732 int pos = header.indexOf(QLatin1String(
"charset="), Qt::CaseInsensitive);
2734 const QString charset = header.mid(pos + 8).toLower();
2736 setMetaData(QLatin1String(
"charset"), charset);
2738 }
else if (header.startsWith(QLatin1String(
"content-language:"), Qt::CaseInsensitive)) {
2739 const QString language = header.mid(17).trimmed().toLower();
2740 setMetaData(QLatin1String(
"content-language"), language);
2741 }
else if (header.startsWith(QLatin1String(
"content-disposition:"), Qt::CaseInsensitive)) {
2768 if (
m_mimeType == QLatin1String(
"application/x-targz"))
2769 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2770 else if (
m_mimeType == QLatin1String(
"image/x-png"))
2774 else if (
m_mimeType == QLatin1String(
"audio/microsoft-wave"))
2776 else if (
m_mimeType == QLatin1String(
"image/x-ms-bmp"))
2780 else if (
m_mimeType == QLatin1String(
"application/pkix-cert") ||
2781 m_mimeType == QLatin1String(
"application/binary-certificate")) {
2782 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2786 else if (
m_mimeType == QLatin1String(
"application/x-gzip")) {
2789 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2791 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2796 else if(
m_mimeType == QLatin1String(
"application/x-xz")) {
2799 m_mimeType = QLatin1String(
"application/x-xz-compressed-tar");
2804 else if ((
m_mimeType == QLatin1String(
"text/plain")) || (
m_mimeType == QLatin1String(
"application/octet-stream"))) {
2806 if (ext == QLatin1String(
"BZ2"))
2807 m_mimeType = QLatin1String(
"application/x-bzip");
2808 else if (ext == QLatin1String(
"PEM"))
2809 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2810 else if (ext == QLatin1String(
"SWF"))
2811 m_mimeType = QLatin1String(
"application/x-shockwave-flash");
2812 else if (ext == QLatin1String(
"PLS"))
2814 else if (ext == QLatin1String(
"WMV"))
2815 m_mimeType = QLatin1String(
"video/x-ms-wmv");
2816 else if (ext == QLatin1String(
"WEBM"))
2818 else if (ext == QLatin1String(
"DEB"))
2819 m_mimeType = QLatin1String(
"application/x-deb");
2833 if (
m_mimeType == QLatin1String(
"application/x-tar")) {
2835 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2836 }
else if (
m_mimeType == QLatin1String(
"application/postscript")) {
2840 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2845 m_mimeType != QLatin1String(
"application/x-compressed-tar") &&
2846 m_mimeType != QLatin1String(
"application/x-tgz") &&
2847 m_mimeType != QLatin1String(
"application/x-targz") &&
2848 m_mimeType != QLatin1String(
"application/x-gzip"))) {
2852 m_mimeType = QLatin1String(
"application/x-gzip");
2864 m_mimeType = QLatin1String(
"application/x-bzip");
2871 static bool consume(
const char input[],
int *pos,
int end,
const char *term)
2875 if (idx + (
int)strlen(term) >= end) {
2879 if (strncasecmp(&input[idx], term, strlen(term)) == 0) {
2880 *pos = idx + strlen(term);
2904 bool upgradeRequired =
false;
2908 bool noHeadersFound =
false;
2913 static const int maxHeaderSize = 128 * 1024;
2915 char buffer[maxHeaderSize];
2917 bool bCanResume =
false;
2920 kDebug(7113) <<
"No connection.";
2930 kDebug(7113) <<
"Got socket error:" <<
socket()->errorString();
2939 if (!foundDelimiter && bufPos < maxHeaderSize) {
2940 kDebug(7113) <<
"EOF while waiting for header start.";
2957 kDebug(7113) <<
"Connection broken !";
2961 if (!foundDelimiter) {
2966 kDebug(7103) <<
"============ Received Status Response:";
2967 kDebug(7103) << QByteArray(buffer, bufPos).trimmed();
2972 if (idx != bufPos && buffer[idx] ==
'<') {
2973 kDebug(7103) <<
"No valid HTTP header found! Document starts with XML/HTML tag";
2979 noHeadersFound =
true;
2986 if (
consume(buffer, &idx, bufPos,
"ICY ")) {
2989 }
else if (
consume(buffer, &idx, bufPos,
"HTTP/")) {
2990 if (
consume(buffer, &idx, bufPos,
"1.0")) {
2993 }
else if (
consume(buffer, &idx, bufPos,
"1.1")) {
2998 if (httpRev ==
HTTP_None && bufPos != 0) {
3001 kDebug(7113) <<
"DO NOT WANT." << bufPos;
3009 noHeadersFound =
true;
3020 if (idx != bufPos) {
3036 messageBox(WarningYesNo,
3037 i18nc(
"@info Security check on url being accessed",
3038 "<p>You are about to log in to the site \"%1\" "
3039 "with the username \"%2\", but the website "
3040 "does not require authentication. "
3041 "This may be an attempt to trick you.</p>"
3042 "<p>Is \"%1\" the site you want to visit?</p>",
3044 i18nc(
"@title:window",
"Confirm Website Access"));
3049 setMetaData(QLatin1String(
"{internal~currenthost}LastSpoofedUserName"),
m_request.
url.
user());
3073 upgradeRequired =
true;
3087 setMetaData(QLatin1String(
"permanent-redirect"), QLatin1String(
"true"));
3121 infoMessage(
i18n(
"Server processing request, please wait..." ) );
3129 bool authRequiresAnotherRoundtrip =
false;
3132 if (!noHeadersFound) {
3137 kDebug(7113) <<
"wasAuthError=" << wasAuthError <<
"isAuthError=" << isAuthError
3138 <<
"sameAuthError=" << sameAuthError;
3150 kDebug(7113) <<
" -- full response:" << endl << QByteArray(buffer, bufPos).trimmed();
3153 Q_ASSERT(foundDelimiter);
3160 tokenizer.
tokenize(idx,
sizeof(buffer));
3165 if (tIt.
hasNext() && tIt.
next().toLower().startsWith(
"none")) {
3169 tIt = tokenizer.iterator(
"keep-alive");
3171 QByteArray ka = tIt.
next().trimmed().toLower();
3172 if (ka.startsWith(
"timeout=")) {
3173 int ka_timeout = ka.mid(qstrlen(
"timeout=")).trimmed().toInt();
3185 tIt = tokenizer.iterator(
"content-length");
3190 tIt = tokenizer.iterator(
"content-location");
3192 setMetaData(QLatin1String(
"content-location"),
toQString(tIt.
next().trimmed()));
3198 tIt = tokenizer.iterator(
"content-type");
3204 if (
m_mimeType.startsWith(QLatin1Char(
'"'))) {
3216 Q_FOREACH (
const QByteArray &statement, l) {
3217 const int index = statement.indexOf(
'=');
3219 mediaAttribute =
toQString(statement.mid(0, index));
3221 mediaAttribute =
toQString(statement.mid(0, index));
3222 mediaValue =
toQString(statement.mid(index+1));
3224 mediaAttribute = mediaAttribute.trimmed();
3225 mediaValue = mediaValue.trimmed();
3227 bool quoted =
false;
3228 if (mediaValue.startsWith(QLatin1Char(
'"'))) {
3230 mediaValue.remove(0, 1);
3233 if (mediaValue.endsWith(QLatin1Char(
'"'))) {
3237 kDebug (7113) <<
"Encoding-type:" << mediaAttribute <<
"=" << mediaValue;
3239 if (mediaAttribute == QLatin1String(
"charset")) {
3240 mediaValue = mediaValue.toLower();
3242 setMetaData(QLatin1String(
"charset"), mediaValue);
3244 setMetaData(QLatin1String(
"media-") + mediaAttribute, mediaValue);
3246 setMetaData(QLatin1String(
"media-") + mediaAttribute + QLatin1String(
"-kio-quoted"),
3247 QLatin1String(
"true"));
3254 tIt = tokenizer.iterator(
"content-encoding");
3272 tIt = tokenizer.iterator(
"content-disposition");
3276 tIt = tokenizer.iterator(
"content-language");
3279 if (!language.isEmpty()) {
3280 setMetaData(QLatin1String(
"content-language"), language);
3284 tIt = tokenizer.iterator(
"proxy-connection");
3286 QByteArray pc = tIt.
next().toLower();
3287 if (pc.startsWith(
"close")) {
3289 }
else if (pc.startsWith(
"keep-alive")) {
3294 tIt = tokenizer.iterator(
"link");
3298 if (link.count() == 2) {
3299 QString rel = link[1].trimmed();
3300 if (rel.startsWith(QLatin1String(
"rel=\""))) {
3301 rel = rel.mid(5, rel.length() - 6);
3302 if (rel.toLower() == QLatin1String(
"pageservices")) {
3304 QString url = link[0].remove(QRegExp(QLatin1String(
"[<>]"))).trimmed();
3305 setMetaData(QLatin1String(
"PageServices"), url);
3311 tIt = tokenizer.iterator(
"p3p");
3317 .split(QLatin1Char(
'='), QString::SkipEmptyParts);
3318 if (policy.count() == 2) {
3319 if (policy[0].toLower() == QLatin1String(
"policyref")) {
3320 policyrefs << policy[1].remove(QRegExp(QLatin1String(
"[\")\']"))).trimmed();
3321 }
else if (policy[0].toLower() == QLatin1String(
"cp")) {
3325 const QString s = policy[1].remove(QRegExp(QLatin1String(
"[\")\']")));
3326 const QStringList cps = s.split(QLatin1Char(
' '), QString::SkipEmptyParts);
3331 if (!policyrefs.isEmpty()) {
3332 setMetaData(QLatin1String(
"PrivacyPolicy"), policyrefs.join(QLatin1String(
"\n")));
3334 if (!compact.isEmpty()) {
3335 setMetaData(QLatin1String(
"PrivacyCompactPolicy"), compact.join(QLatin1String(
"\n")));
3342 tIt = tokenizer.iterator(
"connection");
3344 QByteArray connection = tIt.
next().toLower();
3346 if (connection.startsWith(
"close")) {
3348 }
else if (connection.startsWith(
"keep-alive")) {
3352 if (connection.startsWith(
"upgrade")) {
3355 upgradeRequired =
true;
3356 }
else if (upgradeRequired) {
3362 tIt = tokenizer.iterator(
"transfer-encoding");
3371 tIt = tokenizer.iterator(
"content-md5");
3378 tIt = tokenizer.iterator(
"dav");
3388 tIt = tokenizer.iterator(
"upgrade");
3392 upgradeOffers = offered.split(QRegExp(QLatin1String(
"[ \n,\r\t]")), QString::SkipEmptyParts);
3394 Q_FOREACH (
const QString &opt, upgradeOffers) {
3395 if (opt == QLatin1String(
"TLS/1.0")) {
3396 if (!
startSsl() && upgradeRequired) {
3400 }
else if (opt == QLatin1String(
"HTTP/1.1")) {
3402 }
else if (upgradeRequired) {
3410 QByteArray cookieStr;
3411 tIt = tokenizer.iterator(
"set-cookie");
3413 cookieStr +=
"Set-Cookie: ";
3414 cookieStr += tIt.
next();
3417 if (!cookieStr.isEmpty()) {
3422 cookieStr =
"Cross-Domain\n" + cookieStr;
3427 setMetaData(QLatin1String(
"setcookies"), QString::fromUtf8(cookieStr));
3435 kDebug(7113) <<
"cont; returning to mark try_again";
3441 kDebug(7113) <<
"Ignoring keep-alive: otherwise unable to determine response body length.";
3456 authRequiresAnotherRoundtrip =
false;
3461 tIt = tokenizer.iterator(
"location");
3463 locationStr = QString::fromUtf8(tIt.
next().trimmed());
3466 if (!locationStr.isEmpty())
3493 if(u.
protocol() == QLatin1String(
"http")){
3495 }
else if(u.
protocol() == QLatin1String(
"https")){
3535 kDebug(7113) <<
"Reading resource from cache even though the cache plan is not "
3536 "UseCached; the server is probably sending wrong expiry information.";
3546 int nextLinePos = 0;
3547 int prevLinePos = 0;
3548 bool haveMore =
true;
3550 haveMore =
nextLine(buffer, &nextLinePos, bufPos);
3551 int prevLineEnd = nextLinePos;
3552 while (buffer[prevLineEnd - 1] ==
'\r' || buffer[prevLineEnd - 1] ==
'\n') {
3557 prevLineEnd - prevLinePos));
3558 prevLinePos = nextLinePos;
3585 return !authRequiresAnotherRoundtrip;
3593 while (i != parameters.constEnd()) {
3594 setMetaData(QLatin1String(
"content-disposition-") + i.key(), i.value());
3595 kDebug(7113) <<
"Content-Disposition:" << i.key() <<
"=" << i.value();
3602 QString encoding = _encoding.trimmed().toLower();
3604 if (encoding == QLatin1String(
"identity")) {
3606 }
else if (encoding == QLatin1String(
"8bit")) {
3609 }
else if (encoding == QLatin1String(
"chunked")) {
3614 }
else if ((encoding == QLatin1String(
"x-gzip")) || (encoding == QLatin1String(
"gzip"))) {
3615 encs.append(QLatin1String(
"gzip"));
3616 }
else if ((encoding == QLatin1String(
"x-bzip2")) || (encoding == QLatin1String(
"bzip2"))) {
3617 encs.append(QLatin1String(
"bzip2"));
3618 }
else if ((encoding == QLatin1String(
"x-deflate")) || (encoding == QLatin1String(
"deflate"))) {
3619 encs.append(QLatin1String(
"deflate"));
3621 kDebug(7113) <<
"Unknown encoding encountered. "
3622 <<
"Please write code. Encoding =" << encoding;
3641 const qint64 currentDate = time(0);
3658 tIt = tokenizer.iterator(
"date");
3665 tIt = tokenizer.iterator(
"age");
3667 ageHeader = tIt.
next().toLongLong();
3671 if (dateHeader != -1) {
3673 }
else if (ageHeader) {
3680 bool hasCacheDirective =
false;
3685 tIt = tokenizer.iterator(
"cache-control");
3687 QByteArray cacheStr = tIt.
next().toLower();
3688 if (cacheStr.startsWith(
"no-cache") || cacheStr.startsWith(
"no-store")) {
3691 hasCacheDirective =
true;
3692 }
else if (cacheStr.startsWith(
"max-age=")) {
3693 QByteArray ba = cacheStr.mid(qstrlen(
"max-age=")).trimmed();
3695 maxAgeHeader = ba.toLongLong(&ok);
3697 hasCacheDirective =
true;
3702 qint64 expiresHeader = -1;
3703 tIt = tokenizer.iterator(
"expires");
3706 kDebug(7113) <<
"parsed expire date from 'expires' header:" << tIt.
current();
3711 }
else if (expiresHeader != -1) {
3720 expAge = qMin(expAge,
qint64(3600 * 24));
3733 tIt = tokenizer.iterator(
"etag");
3738 kDebug(7103) <<
"304 Not Modified but new entity tag - I don't think this is legal HTTP.";
3743 tIt = tokenizer.iterator(
"warning");
3751 tIt = tokenizer.iterator(
"pragma");
3753 if (tIt.
next().toLower().startsWith(
"no-cache")) {
3755 hasCacheDirective =
true;
3760 tIt = tokenizer.iterator(
"refresh");
3763 setMetaData(QLatin1String(
"http-refresh"),
toQString(tIt.
next().trimmed()));
3767 if (
m_mimeType.startsWith(QLatin1String(
"text/")) && (
m_mimeType != QLatin1String(
"text/css")) &&
3768 (
m_mimeType != QLatin1String(
"text/x-javascript")) && !hasCacheDirective) {
3779 kDebug(7113) <<
"Cache needs validation";
3781 kDebug(7113) <<
"...was revalidated by response code but not by updated expire times. "
3782 "We're going to set the expire date to 60 seconds in the future...";
3788 kDebug(7113) <<
"this proxy or server apparently sends bogus expiry information.";
3805 kDebug(7113) <<
"This webserver is confused about the cacheability of the data it sends.";
3819 if (!cachingAllowed) {
3820 setMetaData(QLatin1String(
"no-cache"), QLatin1String(
"true"));
3821 setMetaData(QLatin1String(
"expire-date"), QLatin1String(
"1"));
3825 setMetaData(QLatin1String(
"expire-date"), tmp);
3828 setMetaData(QLatin1String(
"cache-creation-date"), tmp);
3836 QByteArray cLength (
"Content-Length: ");
3837 cLength += QByteArray::number(
m_POSTbuf->size());
3838 cLength +=
"\r\n\r\n";
3840 kDebug(7113) <<
"sending cached data (size=" <<
m_POSTbuf->size() <<
")";
3843 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3845 kDebug( 7113 ) <<
"Connection broken when sending "
3857 sendOk = (
write(buffer.data(), buffer.size()) == (ssize_t) buffer.size());
3859 kDebug(7113) <<
"Connection broken when sending message body: ("
3890 QByteArray cLength (
"Content-Length: ");
3892 cLength +=
"\r\n\r\n";
3894 kDebug(7113) << cLength.trimmed();
3897 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3907 kDebug(7113) <<
"Connection broken while sending POST content size to" <<
m_request.
url.host();
3926 const int bytesRead = readData(buffer);
3929 if (bytesRead == 0) {
3935 if (bytesRead < 0) {
3949 if (
write(buffer.data(), bytesRead) == static_cast<ssize_t>(bytesRead)) {
3950 bytesSent += bytesRead;
3951 processedSize(bytesSent);
3955 kDebug(7113) <<
"Connection broken while sending POST content to" <<
m_request.
url.host();
3965 kDebug(7113) <<
"keepAlive =" << keepAlive;
3981 QDataStream stream( &data, QIODevice::WriteOnly );
4003 setTimeoutSpecialCommand(-1);
4040 QDataStream stream(data);
4048 stream >> url >> size;
4057 stream >> url >> no_cache >> expireDate;
4063 QFile::remove(filename);
4084 stream >> url >> scope >> type >> owner;
4085 davLock( url, scope, type, owner );
4100 stream >> url >> method >> size;
4101 davGeneric( url, (KIO::HTTP_METHOD) method, size );
4130 if (foundCrLf && bufPos == 2) {
4137 kDebug(7113) <<
"Failed to read chunk header.";
4140 Q_ASSERT(bufPos > 2);
4143 if (nextChunkSize < 0)
4145 kDebug(7113) <<
"Negative chunk size";
4162 int trashBufPos = 2;
4165 if (trashBufPos > 3) {
4167 for (
int i = 0; i < 3; i++) {
4168 trash[i] = trash[trashBufPos - 3 + i];
4175 kDebug(7113) <<
"Failed to read chunk trailer.";
4187 return bytesReceived;
4205 if (bytesReceived <= 0)
4209 return bytesReceived;
4216 kDebug(7113) <<
"Unbounded datastream on a Keep-alive connection!";
4256 kDebug(7113) <<
"Determining mime-type from content...";
4270 if( mime && !mime->isDefault() )
4351 if ( !dataInternal ) {
4362 kDebug(7113) <<
"reading data from cache...";
4374 if (!dataInternal) {
4381 if (!dataInternal) {
4409 QObject::connect(&chain, SIGNAL(
output(QByteArray)),
4419 if ( enc == QLatin1String(
"gzip") )
4421 else if ( enc == QLatin1String(
"deflate") )
4449 if ( enc == QLatin1String(
"gzip") )
4451 else if ( enc == QLatin1String(
"deflate") )
4470 if (bytesReceived == -1)
4480 kDebug(7113) <<
"bytesReceived==-1 sz=" << (int)sz
4481 <<
" Connection broken !";
4488 if (bytesReceived > 0)
4499 sz += bytesReceived;
4501 processedSize( sz );
4525 kWarning(7113) <<
"MD5 checksum MISMATCH! Expected:"
4534 if (!dataInternal && sz <= 1)
4547 data( QByteArray() );
4575 SlaveBase::error( _err, _text );
4583 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4584 (void)kcookiejar.call( QDBus::NoBlock, QLatin1String(
"addCookies"), url,
4585 cookieHeader, windowId );
4591 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4592 QDBusReply<QString> reply = kcookiejar.call( QLatin1String(
"findCookies"), url, windowId );
4594 if ( !reply.isValid() )
4596 kWarning(7113) <<
"Can't communicate with kded_kcookiejar!";
4625 time_t currentDate = time(0);
4638 struct BinaryCacheFileHeader
4650 static const int size = 36;
4662 BinaryCacheFileHeader
header;
4671 QDataStream stream(&ret, QIODevice::WriteOnly);
4672 stream << quint8(
'A');
4673 stream << quint8(
'\n');
4674 stream << quint8(0);
4675 stream << quint8(0);
4677 stream << fileUseCount;
4680 stream <<
qint64(servedDate);
4681 stream << qint64(lastModifiedDate);
4682 stream << qint64(expireDate);
4684 stream << bytesCached;
4685 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size);
4694 return byte == value;
4697 static bool readTime(QDataStream *stream, time_t *time)
4701 *time =
static_cast<time_t
>(intTime);
4704 return check == intTime;
4713 if (d.size() != BinaryCacheFileHeader::size) {
4716 QDataStream stream(d);
4717 stream.setVersion(QDataStream::Qt_4_5);
4728 stream >> fileUseCount;
4731 ok = ok &&
readTime(&stream, &servedDate);
4732 ok = ok &&
readTime(&stream, &lastModifiedDate);
4733 ok = ok &&
readTime(&stream, &expireDate);
4738 stream >> bytesCached;
4763 static const char linefeed =
'\n';
4765 dev->write(&linefeed, 1);
4772 Q_ASSERT(file->openMode() & QIODevice::WriteOnly);
4774 file->seek(BinaryCacheFileHeader::size);
4788 if (line->isEmpty() || !line->endsWith(
'\n')) {
4800 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4804 if (
storableUrl(desiredUrl).toEncoded() != readBuf) {
4805 kDebug(7103) <<
"You have witnessed a very improbable hash collision!";
4819 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4825 qint64 oldPos = file->pos();
4826 file->seek(BinaryCacheFileHeader::size);
4829 Q_ASSERT(file->pos() == oldPos);
4838 if (ok && !readBuf.isEmpty()) {
4849 QCryptographicHash hash(QCryptographicHash::Sha1);
4851 return toQString(hash.result().toHex());
4857 if (!filePath.endsWith(QLatin1Char(
'/'))) {
4858 filePath.append(QLatin1Char(
'/'));
4871 kDebug(7113) <<
"File unexpectedly open; old file is" << file->fileName()
4872 <<
"new name is" << filename;
4873 Q_ASSERT(file->fileName() == filename);
4876 file =
new QFile(filename);
4877 if (file->open(QIODevice::ReadOnly)) {
4878 QByteArray
header = file->read(BinaryCacheFileHeader::size);
4880 kDebug(7103) <<
"Cache file header is invalid.";
4890 if (!file->isOpen()) {
4908 Q_ASSERT(!qobject_cast<QTemporaryFile *>(file));
4909 Q_ASSERT((file->openMode() & QIODevice::WriteOnly) == 0);
4910 Q_ASSERT(file->fileName() == filename);
4911 kDebug(7113) <<
"deleting expired cache entry and recreating.";
4919 file->open(QIODevice::WriteOnly);
4925 if ((file->openMode() & QIODevice::WriteOnly) == 0) {
4926 kDebug(7113) <<
"Could not open file for writing:" << file->fileName()
4927 <<
"due to error" << file->error();
4938 QDataStream stream(&ret, QIODevice::WriteOnly);
4939 stream.setVersion(QDataStream::Qt_4_5);
4941 stream.skipRawData(BinaryCacheFileHeader::size);
4946 int basenameStart = fileName.lastIndexOf(QLatin1Char(
'/')) + 1;
4948 stream.writeRawData(baseName.constData(), baseName.size());
4950 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size +
sizeof(quint32) +
s_hashedUrlNibbles);
4966 QByteArray ccCommand;
4969 if (file->openMode() & QIODevice::WriteOnly) {
4975 tempFile->write(header);
4979 QString oldName = tempFile->fileName();
4981 int basenameStart = newName.lastIndexOf(QLatin1Char(
'/')) + 1;
4984 kDebug(7113) <<
"Renaming temporary file" << oldName <<
"to" << newName;
4987 tempFile->setAutoRemove(
false);
4991 if (!QFile::rename(oldName, newName)) {
4994 kDebug(7113) <<
"Renaming temporary file failed, deleting it instead.";
4995 QFile::remove(oldName);
5002 }
else if (file->openMode() == QIODevice::ReadOnly) {
5003 Q_ASSERT(!tempFile);
5009 if (!ccCommand.isEmpty()) {
5020 if (attempts == 2) {
5034 kDebug(7113) <<
"Could not connect to cache cleaner, not updating stats of this cache file.";
5044 if (ret.isEmpty()) {
5061 kDebug(7113) <<
"Caching disabled because content size is too big.";
5091 m_POSTbuf->write (data.constData(), data.size());
5117 const int bytesRead = readData(buffer);
5119 if (bytesRead < 0) {
5124 if (bytesRead == 0) {
5128 m_POSTbuf->write(buffer.constData(), buffer.size());
5156 if (useCachedAuth && checkCachedAuthentication(authinfo)) {
5157 const QByteArray cachedChallenge =
config()->readEntry(
"www-auth-challenge", QByteArray());
5158 if (!cachedChallenge.isEmpty()) {
5161 kDebug(7113) <<
"creating www authentcation header from cached info";
5179 if (checkCachedAuthentication(authinfo)) {
5180 const QByteArray cachedChallenge =
config()->readEntry(
"proxy-auth-challenge", QByteArray());
5181 if (!cachedChallenge.isEmpty()) {
5184 kDebug(7113) <<
"creating proxy authentcation header from cached info";
5194 ret +=
"Authorization: ";
5199 ret +=
"Proxy-Authorization: ";
5209 case QNetworkProxy::DefaultProxy:
5211 case QNetworkProxy::Socks5Proxy:
5212 return QLatin1String(
"socks");
5213 case QNetworkProxy::NoProxy:
5215 case QNetworkProxy::HttpProxy:
5216 case QNetworkProxy::HttpCachingProxy:
5217 case QNetworkProxy::FtpCachingProxy:
5222 return QLatin1String(
"http");
5227 kDebug(7113) <<
"realm:" << authenticator->realm() <<
"user:" << authenticator->user();
5238 info.
username = authenticator->user();
5241 const bool haveCachedCredentials = checkCachedAuthentication(info);
5246 if (!haveCachedCredentials || retryAuth) {
5249 connect(
socket(), SIGNAL(connected()),
5252 info.
prompt =
i18n(
"You need to supply a username and a password for "
5253 "the proxy server listed below before you are allowed "
5254 "to access any sites.");
5259 const QString errMsg ((retryAuth ?
i18n(
"Proxy Authentication Failed.") :
QString()));
5261 if (!openPasswordDialog(info, errMsg)) {
5262 kDebug(7113) <<
"looks like the user canceled proxy authentication.";
5269 authenticator->setUser(info.
username);
5270 authenticator->setPassword(info.
password);
5271 authenticator->setOption(QLatin1String(
"keepalive"), info.
keepPassword);
5286 kDebug(7113) <<
"Saving authenticator";
5287 disconnect(
socket(), SIGNAL(connected()),
5299 cacheAuthentication(a);
5308 bool alreadyCached =
false;
5313 alreadyCached =
config()->readEntry(
"cached-www-auth",
false);
5317 alreadyCached =
config()->readEntry(
"cached-proxy-auth",
false);
5324 if (auth && (!auth->
realm().isEmpty() || !alreadyCached)) {
5327 setMetaData(QLatin1String(
"{internal~currenthost}cached-www-auth"), QLatin1String(
"true"));
5329 setMetaData(QLatin1String(
"{internal~currenthost}www-auth-realm"), authinfo.
realmValue);
5331 setMetaData(QLatin1String(
"{internal~currenthost}www-auth-challenge"), authinfo.
digestInfo);
5333 setMetaData(QLatin1String(
"{internal~allhosts}cached-proxy-auth"), QLatin1String(
"true"));
5335 setMetaData(QLatin1String(
"{internal~allhosts}proxy-auth-realm"), authinfo.
realmValue);
5337 setMetaData(QLatin1String(
"{internal~allhosts}proxy-auth-challenge"), authinfo.
digestInfo);
5343 cacheAuthentication(authinfo);
5359 authTokens = tokenizer->iterator(
"www-authenticate").all();
5362 authinfo.
prompt =
i18n(
"You need to supply a username and a "
5363 "password to access this site.");
5369 Q_ASSERT(QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy);
5371 authTokens = tokenizer->iterator(
"proxy-authenticate").all();
5374 authinfo.
prompt =
i18n(
"You need to supply a username and a password for "
5375 "the proxy server listed below before you are allowed "
5376 "to access any sites." );
5380 bool authRequiresAnotherRoundtrip =
false;
5385 if (!authTokens.isEmpty()) {
5387 authRequiresAnotherRoundtrip =
true;
5391 if ((*auth)->wasFinalStage()) {
5393 i18n(
"Authentication Failed.") :
5394 i18n(
"Proxy Authentication Failed."));
5402 QMutableListIterator<QByteArray> it (authTokens);
5403 const QByteArray authScheme ((*auth)->scheme().trimmed());
5404 while (it.hasNext()) {
5405 if (qstrnicmp(authScheme.constData(), it.next().constData(), authScheme.length()) != 0) {
5412 try_next_auth_scheme:
5415 const QByteArray authScheme ((*auth)->scheme().trimmed());
5416 if (qstrnicmp(authScheme.constData(), bestOffer.constData(), authScheme.length()) != 0) {
5428 kDebug(7113) <<
"Trying authentication scheme:" << (*auth)->scheme();
5434 bool generateAuthHeader =
true;
5435 if ((*auth)->needCredentials()) {
5446 if (authinfo.
realmValue.isEmpty() && !(*auth)->supportsPathMatching())
5447 authinfo.
realmValue = QLatin1String((*auth)->scheme());
5452 const KUrl reqUrl = authinfo.
url;
5453 if (!errorMsg.isEmpty() || !checkCachedAuthentication(authinfo)) {
5455 authinfo.
url = reqUrl;
5460 if (!openPasswordDialog(authinfo, errorMsg)) {
5461 generateAuthHeader =
false;
5462 authRequiresAnotherRoundtrip =
false;
5466 kDebug(7113) <<
"looks like the user canceled the authentication dialog";
5476 if (generateAuthHeader) {
5477 (*auth)->generateResponse(username, password);
5478 (*auth)->setCachePasswordEnabled(authinfo.
keepPassword);
5480 kDebug(7113) <<
"isError=" << (*auth)->isError()
5481 <<
"needCredentials=" << (*auth)->needCredentials()
5482 <<
"forceKeepAlive=" << (*auth)->forceKeepAlive()
5483 <<
"forceDisconnect=" << (*auth)->forceDisconnect();
5485 if ((*auth)->isError()) {
5486 authTokens.removeOne(bestOffer);
5487 if (!authTokens.isEmpty()) {
5488 goto try_next_auth_scheme;
5491 authRequiresAnotherRoundtrip =
false;
5494 }
else if ((*auth)->forceKeepAlive()) {
5497 }
else if ((*auth)->forceDisconnect()) {
5504 authRequiresAnotherRoundtrip =
false;
5511 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())