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(
""");
114 return (scheme.startsWith(QLatin1String(
"http"))
115 || scheme == QLatin1String(
"socks"));
126extern "C" int KDE_EXPORT
kdemain(
int argc,
char **argv )
128 QCoreApplication app( argc, argv );
134 fprintf(stderr,
"Usage: kio_http protocol domain-socket1 domain-socket2\n");
147 return QString::fromLatin1(value.constData(), value.size());
153 if (originURL == QLatin1String(
"true"))
156 KUrl url ( originURL );
159 QString a = url.host();
166 QStringList la = a.
split(QLatin1Char(
'.'), QString::SkipEmptyParts);
167 QStringList lb = b.split(QLatin1Char(
'.'), QString::SkipEmptyParts);
169 if (qMin(la.count(), lb.count()) < 2) {
173 while(la.count() > 2)
175 while(lb.count() > 2)
186 QString sanitizedHeaders;
187 const QStringList headers = _header.split(QRegExp(QLatin1String(
"[\r\n]")));
189 for(QStringList::ConstIterator it = headers.begin(); it != headers.end(); ++it)
193 if (!(*it).contains(QLatin1Char(
':')) ||
194 (*it).startsWith(QLatin1String(
"host"), Qt::CaseInsensitive) ||
195 (*it).startsWith(QLatin1String(
"proxy-authorization"), Qt::CaseInsensitive) ||
196 (*it).startsWith(QLatin1String(
"via"), Qt::CaseInsensitive))
199 sanitizedHeaders += (*it);
200 sanitizedHeaders += QLatin1String(
"\r\n");
202 sanitizedHeaders.chop(2);
204 return sanitizedHeaders;
210 if (
config->readEntry(
"no-spoof-check",
false)) {
214 if (request.
url.
user().isEmpty()) {
219 if (
config->readEntry(QLatin1String(
"cached-www-auth"),
false)) {
223 const QString userName =
config->readEntry(QLatin1String(
"LastSpoofedUserName"), QString());
250 if (responseCode >= 100 && responseCode < 200) {
253 switch (responseCode) {
259 Q_ASSERT(method != HTTP_HEAD);
269 return method != HTTP_HEAD;
274 return p ==
"https" || p ==
"webdavs";
279 return u.isValid() && u.
hasHost();
293 device =
new QBuffer;
295 if (!device->open(QIODevice::ReadWrite))
309 if (type == QLatin1String(
"dateTime.tz") ) {
311 }
else if (type == QLatin1String(
"dateTime.rfc1123")) {
332 kDebug(7113) <<
"item:" <<
name <<
", mimeType:" << mimeType;
334 if (mimeType.isEmpty() && type != S_IFDIR) {
336 if (mime && !mime->isDefault()) {
337 kDebug(7113) <<
"Setting" << mime->name() <<
"as guessed mime type for" <<
name;
345 const QString protocol(url->
protocol());
346 if (protocol == QLatin1String(
"webdavs")) {
348 }
else if (protocol == QLatin1String(
"webdav")) {
392 case DAV_UNSUBSCRIBE:
393 return "UNSUBSCRIBE";
413 if (!dt.
time().second()) {
414 ret.append(QLatin1String(
":00"));
416 ret.append(QLatin1String(
" GMT"));
422 return (responseCode == 401) || (responseCode == 407);
425#define NO_SIZE ((KIO::filesize_t) -1)
428#define STRTOLL strtoll
430#define STRTOLL strtol
438 const QByteArray &app )
457 connect(
socket(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
477 TCPSlaveBase::reparseConfiguration();
531 kDebug(7113) <<
"ssl_was_in_use =" <<
metaData(QLatin1String(
"ssl_was_in_use"));
540 if (refUrl.isValid()) {
542 QString protocol = refUrl.
protocol();
543 if (protocol.startsWith(QLatin1String(
"webdav"))) {
544 protocol.replace(0, 6, QLatin1String(
"http"));
548 if (protocol.startsWith(QLatin1String(
"http"))) {
566 QString resumeOffset =
metaData(QLatin1String(
"resume"));
567 if (!resumeOffset.isEmpty()) {
573 QString resumeEndOffset =
metaData(QLatin1String(
"resume_until"));
574 if (!resumeEndOffset.isEmpty()) {
619 const QString& user,
const QString& pass )
628 if (host.indexOf(QLatin1Char(
':')) == -1) {
631 int pos = host.indexOf(QLatin1Char(
'%'));
657 if (u.host().isEmpty()) {
662 if (u.
path().isEmpty()) {
664 newUrl.
setPath(QLatin1String(
"/"));
687 if (dataInternal || !status) {
765 QString statSide =
metaData(QLatin1String(
"statSide"));
766 if (statSide != QLatin1String(
"source"))
813 QString query =
metaData(QLatin1String(
"davSearchQuery"));
814 if ( !query.isEmpty() )
816 QByteArray request =
"<?xml version=\"1.0\"?>\r\n";
817 request.append(
"<D:searchrequest xmlns:D=\"DAV:\">\r\n" );
818 request.append( query.toUtf8() );
819 request.append(
"</D:searchrequest>\r\n" );
825 request =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
826 "<D:propfind xmlns:D=\"DAV:\">";
829 if (
hasMetaData(QLatin1String(
"davRequestResponse")) )
830 request +=
metaData(QLatin1String(
"davRequestResponse")).toUtf8();
833 request +=
"<D:prop>"
835 "<D:getcontentlength/>"
838 "<D:getcontentlanguage/>"
839 "<D:getcontenttype/>"
840 "<D:getlastmodified/>"
847 request +=
"</D:propfind>";
871 QDomDocument multiResponse;
874 bool hasResponse =
false;
878 for ( QDomNode n = multiResponse.documentElement().firstChild();
879 !n.isNull(); n = n.nextSibling()) {
880 QDomElement thisResponse = n.toElement();
881 if (thisResponse.isNull())
886 QDomElement href = thisResponse.namedItem(QLatin1String(
"href")).toElement();
887 if ( !href.isNull() ) {
890 QString urlStr = QUrl::fromPercentEncoding(href.text().toUtf8());
896 KUrl thisURL ( urlStr, encoding );
898 KUrl thisURL( urlStr );
901 if ( thisURL.isValid() ) {
906 name = QLatin1Char(
'.');
911 QDomNodeList propstats = thisResponse.elementsByTagName(QLatin1String(
"propstat"));
926 kDebug(7113) <<
"Error: no URL contained in response to PROPFIND on" << url;
930 if (
stat || !hasResponse ) {
962 const int firstSpace = response.indexOf( QLatin1Char(
' ') );
963 const int secondSpace = response.indexOf( QLatin1Char(
' '), firstSpace + 1 );
964 return response.mid( firstSpace + 1, secondSpace - firstSpace - 1 ).toInt();
970 bool foundExecutable =
false;
971 bool isDirectory =
false;
973 uint supportedLockCount = 0;
975 for (
int i = 0; i < propstats.count(); i++)
977 QDomElement propstat = propstats.item(i).toElement();
979 QDomElement status = propstat.namedItem(QLatin1String(
"status")).toElement();
980 if ( status.isNull() )
983 kDebug(7113) <<
"Error, no status code in this propstat";
991 kDebug(7113) <<
"Got status code" << code <<
"(this may mean that some properties are unavailable)";
995 QDomElement prop = propstat.namedItem( QLatin1String(
"prop") ).toElement();
998 kDebug(7113) <<
"Error: no prop segment in this propstat.";
1002 if (
hasMetaData( QLatin1String(
"davRequestResponse") ) )
1005 doc.appendChild(prop);
1009 for ( QDomNode n = prop.firstChild(); !n.isNull(); n = n.nextSibling() )
1011 QDomElement
property = n.toElement();
1012 if (property.isNull())
1015 if ( property.namespaceURI() != QLatin1String(
"DAV:") )
1021 if ( property.tagName() == QLatin1String(
"creationdate") )
1026 else if ( property.tagName() == QLatin1String(
"getcontentlength") )
1031 else if ( property.tagName() == QLatin1String(
"displayname") )
1034 setMetaData( QLatin1String(
"davDisplayName"), property.text() );
1036 else if ( property.tagName() == QLatin1String(
"source") )
1039 QDomElement source =
property.namedItem( QLatin1String(
"link") ).toElement()
1040 .namedItem( QLatin1String(
"dst") ).toElement();
1041 if ( !source.isNull() )
1042 setMetaData( QLatin1String(
"davSource"), source.text() );
1044 else if ( property.tagName() == QLatin1String(
"getcontentlanguage") )
1047 setMetaData( QLatin1String(
"davContentLanguage"), property.text() );
1049 else if ( property.tagName() == QLatin1String(
"getcontenttype") )
1054 if ( property.text() == QLatin1String(
"httpd/unix-directory") )
1063 else if ( property.tagName() == QLatin1String(
"executable") )
1066 if ( property.text() == QLatin1String(
"T") )
1067 foundExecutable =
true;
1070 else if ( property.tagName() == QLatin1String(
"getlastmodified") )
1075 else if ( property.tagName() == QLatin1String(
"getetag") )
1078 setMetaData( QLatin1String(
"davEntityTag"), property.text() );
1080 else if ( property.tagName() == QLatin1String(
"supportedlock") )
1083 for ( QDomNode n2 = property.firstChild(); !n2.isNull(); n2 = n2.nextSibling() )
1085 QDomElement lockEntry = n2.toElement();
1086 if ( lockEntry.tagName() == QLatin1String(
"lockentry") )
1088 QDomElement lockScope = lockEntry.namedItem( QLatin1String(
"lockscope") ).toElement();
1089 QDomElement lockType = lockEntry.namedItem( QLatin1String(
"locktype") ).toElement();
1090 if ( !lockScope.isNull() && !lockType.isNull() )
1093 supportedLockCount++;
1094 const QString lockCountStr = QString::number(supportedLockCount);
1095 const QString scope = lockScope.firstChild().toElement().tagName();
1096 const QString type = lockType.firstChild().toElement().tagName();
1098 setMetaData( QLatin1String(
"davSupportedLockScope") + lockCountStr, scope );
1099 setMetaData( QLatin1String(
"davSupportedLockType") + lockCountStr, type );
1104 else if ( property.tagName() == QLatin1String(
"lockdiscovery") )
1107 davParseActiveLocks( property.elementsByTagName( QLatin1String(
"activelock") ), lockCount );
1109 else if ( property.tagName() == QLatin1String(
"resourcetype") )
1112 if ( !property.namedItem( QLatin1String(
"collection") ).toElement().isNull() )
1120 kDebug(7113) <<
"Found unknown webdav property:" <<
property.tagName();
1125 setMetaData( QLatin1String(
"davLockCount"), QString::number(lockCount) );
1126 setMetaData( QLatin1String(
"davSupportedLockCount"), QString::number(supportedLockCount) );
1130 if ( foundExecutable || isDirectory )
1140 if ( !isDirectory && !
mimeType.isEmpty() )
1149 for (
int i = 0; i < activeLocks.count(); i++ )
1151 const QDomElement activeLock = activeLocks.item(i).toElement();
1155 const QDomElement lockScope = activeLock.namedItem( QLatin1String(
"lockscope") ).toElement();
1156 const QDomElement lockType = activeLock.namedItem( QLatin1String(
"locktype") ).toElement();
1157 const QDomElement lockDepth = activeLock.namedItem( QLatin1String(
"depth") ).toElement();
1159 const QDomElement lockOwner = activeLock.namedItem( QLatin1String(
"owner") ).toElement();
1160 const QDomElement lockTimeout = activeLock.namedItem( QLatin1String(
"timeout") ).toElement();
1161 const QDomElement lockToken = activeLock.namedItem( QLatin1String(
"locktoken") ).toElement();
1163 if ( !lockScope.isNull() && !lockType.isNull() && !lockDepth.isNull() )
1167 const QString lockCountStr = QString::number(lockCount);
1168 const QString scope = lockScope.firstChild().toElement().tagName();
1169 const QString type = lockType.firstChild().toElement().tagName();
1170 const QString depth = lockDepth.text();
1172 setMetaData( QLatin1String(
"davLockScope") + lockCountStr, scope );
1173 setMetaData( QLatin1String(
"davLockType") + lockCountStr, type );
1174 setMetaData( QLatin1String(
"davLockDepth") + lockCountStr, depth );
1176 if ( !lockOwner.isNull() )
1177 setMetaData( QLatin1String(
"davLockOwner") + lockCountStr, lockOwner.text() );
1179 if ( !lockTimeout.isNull() )
1180 setMetaData( QLatin1String(
"davLockTimeout") + lockCountStr, lockTimeout.text() );
1182 if ( !lockToken.isNull() )
1184 QDomElement tokenVal = lockScope.namedItem( QLatin1String(
"href") ).toElement();
1185 if ( !tokenVal.isNull() )
1186 setMetaData( QLatin1String(
"davLockToken") + lockCountStr, tokenVal.text() );
1194 if (
hasMetaData( QLatin1String(
"davLockCount") ) )
1196 QString response = QLatin1String(
"If:");
1197 int numLocks =
metaData( QLatin1String(
"davLockCount") ).toInt();
1198 bool bracketsOpen =
false;
1199 for (
int i = 0; i < numLocks; i++ )
1201 const QString countStr = QString::number(i);
1202 if (
hasMetaData( QLatin1String(
"davLockToken") + countStr ) )
1204 if (
hasMetaData( QLatin1String(
"davLockURL") + countStr ) )
1208 response += QLatin1Char(
')');
1209 bracketsOpen =
false;
1211 response += QLatin1String(
" <") +
metaData( QLatin1String(
"davLockURL") + countStr ) + QLatin1Char(
'>');
1214 if ( !bracketsOpen )
1216 response += QLatin1String(
" (");
1217 bracketsOpen =
true;
1221 response += QLatin1Char(
' ');
1224 if (
hasMetaData( QLatin1String(
"davLockNot") + countStr ) )
1225 response += QLatin1String(
"Not ");
1227 response += QLatin1Char(
'<') +
metaData( QLatin1String(
"davLockToken") + countStr ) + QLatin1Char(
'>');
1232 response += QLatin1Char(
')');
1234 response += QLatin1String(
"\r\n");
1254 kDebug(7113) <<
" false";
1277 if (
ok && verNo > 0 && verNo < 3)
1280 kDebug(7113) <<
"Server supports DAV version" << verNo;
1331 const QString tmp (
metaData(QLatin1String(
"cache")));
1368 kDebug(7113) << src <<
"->" << dest;
1371 const bool isDestinationLocal = dest.
isLocalFile();
1373 if (isSourceLocal && !isDestinationLocal) {
1383 KUrl newDest (dest);
1405 kDebug(7113) << src <<
"->" << dest;
1493 const QString& type,
const QString& owner )
1506 QDomDocument lockReq;
1508 QDomElement lockInfo = lockReq.createElementNS( QLatin1String(
"DAV:"), QLatin1String(
"lockinfo") );
1509 lockReq.appendChild( lockInfo );
1511 QDomElement lockScope = lockReq.createElement( QLatin1String(
"lockscope") );
1512 lockInfo.appendChild( lockScope );
1514 lockScope.appendChild( lockReq.createElement( scope ) );
1516 QDomElement lockType = lockReq.createElement( QLatin1String(
"locktype") );
1517 lockInfo.appendChild( lockType );
1519 lockType.appendChild( lockReq.createElement( type ) );
1521 if ( !owner.isNull() ) {
1522 QDomElement ownerElement = lockReq.createElement( QLatin1String(
"owner") );
1523 lockReq.appendChild( ownerElement );
1525 QDomElement ownerHref = lockReq.createElement( QLatin1String(
"href") );
1526 ownerElement.appendChild( ownerHref );
1528 ownerHref.appendChild( lockReq.createTextNode( owner ) );
1538 QDomDocument multiResponse;
1541 QDomElement prop = multiResponse.documentElement().namedItem( QLatin1String(
"prop") ).toElement();
1543 QDomElement lockdiscovery = prop.namedItem( QLatin1String(
"lockdiscovery") ).toElement();
1546 davParseActiveLocks( lockdiscovery.elementsByTagName( QLatin1String(
"activelock") ), lockCount );
1548 setMetaData( QLatin1String(
"davLockCount"), QString::number( lockCount ) );
1578 bool callError =
false;
1588 if ( !url.isNull() )
1591 QString action, errorString;
1595 QString ow =
i18n(
"Otherwise, the request would have succeeded." );
1599 action =
i18nc(
"request type",
"retrieve property values" );
1602 action =
i18nc(
"request type",
"set property values" );
1605 action =
i18nc(
"request type",
"create the requested folder" );
1608 action =
i18nc(
"request type",
"copy the specified file or folder" );
1611 action =
i18nc(
"request type",
"move the specified file or folder" );
1614 action =
i18nc(
"request type",
"search in the specified folder" );
1617 action =
i18nc(
"request type",
"lock the specified file or folder" );
1620 action =
i18nc(
"request type",
"unlock the specified file or folder" );
1623 action =
i18nc(
"request type",
"delete the specified file or folder" );
1626 action =
i18nc(
"request type",
"query the server's capabilities" );
1629 action =
i18nc(
"request type",
"retrieve the contents of the specified file or folder" );
1632 action =
i18nc(
"request type",
"run a report in the specified folder" );
1643 errorString =
i18nc(
"%1: code, %2: request type",
"An unexpected error (%1) occurred "
1644 "while attempting to %2.", code, action);
1651 errorString =
i18n(
"The server does not support the WebDAV protocol.");
1665 QDomDocument multiResponse;
1669 QDomElement multistatus = multiResponse.documentElement().namedItem( QLatin1String(
"multistatus") ).toElement();
1671 QDomNodeList responses = multistatus.elementsByTagName( QLatin1String(
"response") );
1673 for (
int i = 0; i < responses.count(); i++)
1678 QDomElement response = responses.item(i).toElement();
1679 QDomElement code = response.namedItem( QLatin1String(
"status") ).toElement();
1681 if ( !code.isNull() )
1684 QDomElement href = response.namedItem( QLatin1String(
"href") ).toElement();
1685 if ( !href.isNull() )
1686 errUrl = href.text();
1687 errors <<
davError( errCode, errUrl );
1692 errorString =
i18nc(
"%1: request type, %2: url",
1693 "An error occurred while attempting to %1, %2. A "
1694 "summary of the reasons is below.", action, url );
1696 errorString += QLatin1String(
"<ul>");
1698 Q_FOREACH(
const QString&
error, errors)
1699 errorString += QLatin1String(
"<li>") +
error + QLatin1String(
"</li>");
1701 errorString += QLatin1String(
"</ul>");
1707 errorString =
i18nc(
"%1: request type",
"Access was denied while attempting to %1.", action );
1720 errorString =
i18n(
"A resource cannot be created at the destination "
1721 "until one or more intermediate collections (folders) "
1722 "have been created.");
1728 errorString =
i18n(
"The server was unable to maintain the liveness of "
1729 "the properties listed in the propertybehavior XML "
1730 "element or you attempted to overwrite a file while "
1731 "requesting that files are not overwritten. %1",
1736 errorString =
i18n(
"The requested lock could not be granted. %1", ow );
1742 errorString =
i18n(
"The server does not support the request type of the body.");
1747 errorString =
i18nc(
"%1: request type",
"Unable to %1 because the resource is locked.", action );
1751 errorString =
i18n(
"This action was prevented by another error.");
1757 errorString =
i18nc(
"%1: request type",
"Unable to %1 because the destination server refuses "
1758 "to accept the file or folder.", action );
1764 errorString =
i18n(
"The destination resource does not have sufficient space "
1765 "to record the state of the resource after the execution "
1776 error( errorCode, errorString );
1784 Q_ASSERT(errorString);
1787 errorString->clear();
1799 Q_ASSERT(errorString);
1803 errorString->clear();
1805 switch (responseCode) {
1814 && (responseCode < 200 || responseCode > 400)
1815 && responseCode != 404) {
1817 *errorString =
i18n(
"The resource cannot be deleted." );
1826 Q_ASSERT(errorString);
1830 const QString action (
i18nc(
"request type",
"upload %1", request.
url.
prettyUrl()));
1832 switch (responseCode) {
1839 *errorString =
i18nc(
"%1: request type",
"Access was denied while attempting to %1.", action );
1845 *errorString =
i18n(
"A resource cannot be created at the destination "
1846 "until one or more intermediate collections (folders) "
1847 "have been created.");
1853 *errorString =
i18nc(
"%1: request type",
"Unable to %1 because the resource is locked.", action );
1859 *errorString =
i18nc(
"%1: request type",
"Unable to %1 because the destination server refuses "
1860 "to accept the file or folder.", action );
1866 *errorString =
i18n(
"The destination resource does not have sufficient space "
1867 "to record the state of the resource after the execution "
1876 && (responseCode < 200 || responseCode > 400)
1877 && responseCode != 404) {
1879 *errorString =
i18nc(
"%1: response code, %2: request type",
1880 "An unexpected error (%1) occurred while attempting to %2.",
1881 responseCode, action);
1889 QString errorString;
1911 error( errorCode, errorString );
1924 kWarning(7113) <<
"called twice during one request, something is probably wrong.";
1937 Solid::Networking::Status status = Solid::Networking::status();
1939 kDebug(7113) <<
"networkstatus:" << status;
1942 return status == Solid::Networking::Unconnected;
1947 QDataStream stream(
data);
1959 for (
unsigned i = 0; i < n; ++i) {
1974 QString tmp =
metaData(QLatin1String(
"cache"));
1989 while (it.hasNext()) {
2001 while (it.hasNext()) {
2018 setMetaData(QLatin1String(
"request-id"), QString::number(requestId++));
2038 const char* buf =
static_cast<const char*
>(_buf);
2039 while (sent < nbytes)
2066 for (
size_t i = 0; i < size; i++) {
2077 size_t bytesRead = 0;
2080 bytesRead = qMin((
int)size, bufSize);
2082 for (
size_t i = 0; i < bytesRead; i++) {
2083 buf[i] =
m_unreadBuf.constData()[bufSize - i - 1];
2094 if (bytesRead < size) {
2100 bytesRead += rawRead;
2111 Q_ASSERT(numNewlines >=1 && numNewlines <= 2);
2115 int step = qMin((
int)
sizeof(mybuf),
end - pos);
2124 for (
size_t i = 0; i < bufferFill ; ++i, ++pos) {
2127 buf[pos] = mybuf[i];
2132 if (buf[pos] ==
'\n') {
2133 bool found = numNewlines == 1;
2136 found = ((pos >= 1 && buf[pos - 1] ==
'\n') ||
2137 (pos >= 2 && buf[pos - 2] ==
'\n' && buf[pos - 1] ==
'\r'));
2141 unread(&mybuf[i], bufferFill - i);
2154 if (previous.host() != now.host() || previous.port() != now.port()) {
2157 if (previous.
user().isEmpty() && previous.
pass().isEmpty()) {
2173 if (url != QLatin1String(
"DIRECT")) {
2197 int connectError = 0;
2198 QString errorString;
2207 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
2212 if (proxyUrl == QLatin1String(
"DIRECT")) {
2213 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
2215 if (connectError == 0) {
2223 const KUrl url(proxyUrl);
2224 const QString proxyScheme(url.
protocol());
2227 errorString = url.
url();
2228 badProxyUrls << url;
2232 QNetworkProxy::ProxyType proxyType = QNetworkProxy::NoProxy;
2233 if (proxyScheme == QLatin1String(
"socks")) {
2234 proxyType = QNetworkProxy::Socks5Proxy;
2236 proxyType = QNetworkProxy::HttpProxy;
2239 kDebug(7113) <<
"Connecting to proxy: address=" << proxyUrl <<
"type=" << proxyType;
2241 if (proxyType == QNetworkProxy::NoProxy) {
2242 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
2243 connectError =
connectToHost(url.host(), url.port(), &errorString);
2244 if (connectError == 0) {
2246 kDebug(7113) <<
"Connected to proxy: host=" << url.host() <<
"port=" << url.port();
2252 kDebug(7113) <<
"Failed to connect to proxy:" << proxyUrl;
2253 badProxyUrls << url;
2256 QNetworkProxy proxy(proxyType, url.host(), url.port(), url.
user(), url.
pass());
2257 QNetworkProxy::setApplicationProxy(proxy);
2259 if (connectError == 0) {
2260 kDebug(7113) <<
"Tunneling thru proxy: host=" << url.host() <<
"port=" << url.port();
2266 kDebug(7113) <<
"Failed to connect to proxy:" << proxyUrl;
2267 badProxyUrls << url;
2268 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
2273 if (!badProxyUrls.isEmpty()) {
2278 if (connectError != 0) {
2279 error(connectError, errorString);
2309 bool openForReading =
false;
2313 if (!openForReading && (isCacheOnly || offline)) {
2315 *cacheHasPage =
false;
2318 }
else if (offline) {
2325 if (openForReading) {
2327 *cacheHasPage =
true;
2332 *cacheHasPage =
false;
2345 if (protocol.startsWith(QLatin1String(
"webdav"))) {
2346 protocol.replace(0, qstrlen(
"webdav"), QLatin1String(
"http"));
2403 kDebug(7113) <<
"Couldn't connect, oopsie!";
2415 bool hasBodyData =
false;
2416 bool hasDavData =
false;
2428 bool cacheHasPage =
false;
2430 kDebug(7113) <<
"cacheHasPage =" << cacheHasPage;
2431 return cacheHasPage;
2433 if (!cacheHasPage) {
2450 davHeader = QLatin1String(
"Depth: ");
2453 kDebug(7113) <<
"Reading DAV depth from metadata:" <<
metaData( QLatin1String(
"davDepth") );
2454 davHeader +=
metaData( QLatin1String(
"davDepth") );
2459 davHeader += QLatin1String(
"infinity");
2463 davHeader += QLatin1String(
"\r\n");
2475 davHeader += QLatin1String(
"\r\nDepth: infinity\r\nOverwrite: ");
2477 davHeader += QLatin1String(
"\r\n");
2480 davHeader = QLatin1String(
"Timeout: ");
2486 davHeader += QLatin1String(
"Infinite");
2488 davHeader += QLatin1String(
"Seconds-") + QString::number(
timeout);
2490 davHeader += QLatin1String(
"\r\n");
2494 davHeader = QLatin1String(
"Lock-token: ") +
metaData(QLatin1String(
"davLockToken")) + QLatin1String(
"\r\n");
2501 case DAV_UNSUBSCRIBE:
2517 header += QLatin1String(
"\r\n");
2524 header += QLatin1String(
"Proxy-Connection: ");
2526 header += QLatin1String(
"Connection: ");
2529 header += QLatin1String(
"keep-alive\r\n");
2531 header += QLatin1String(
"close\r\n");
2536 header += QLatin1String(
"User-Agent: ");
2538 header += QLatin1String(
"\r\n");
2543 header += QLatin1String(
"Referer: ");
2545 header += QLatin1String(
"\r\n");
2550 header += QLatin1String(
"Range: bytes=");
2552 header += QLatin1Char(
'-');
2554 header += QLatin1String(
"\r\n");
2560 header += QLatin1String(
"Range: bytes=");
2562 header += QLatin1String(
"-\r\n");
2569 header += QLatin1String(
"Pragma: no-cache\r\n");
2570 header += QLatin1String(
"Cache-control: no-cache\r\n");
2574 kDebug(7113) <<
"needs validation, performing conditional get.";
2581 header += QLatin1String(
"If-Modified-Since: ") + httpDate + QLatin1String(
"\r\n");
2586 header += QLatin1String(
"Accept: ");
2587 const QString acceptHeader =
metaData(QLatin1String(
"accept"));
2588 if (!acceptHeader.isEmpty())
2592 header += QLatin1String(
"\r\n");
2595 header += QLatin1String(
"Accept-Encoding: gzip, deflate, x-gzip, x-deflate\r\n");
2604 const QString cookieMode =
metaData(QLatin1String(
"cookies")).toLower();
2606 if (cookieMode == QLatin1String(
"none"))
2610 else if (cookieMode == QLatin1String(
"manual"))
2613 cookieStr =
metaData(QLatin1String(
"setcookies"));
2622 if (!cookieStr.isEmpty())
2623 header += cookieStr + QLatin1String(
"\r\n");
2625 const QString customHeader =
metaData( QLatin1String(
"customHTTPHeader") );
2626 if (!customHeader.isEmpty())
2629 header += QLatin1String(
"\r\n");
2632 const QString contentType =
metaData(QLatin1String(
"content-type"));
2633 if (!contentType.isEmpty())
2635 if (!contentType.startsWith(QLatin1String(
"content-type"), Qt::CaseInsensitive))
2636 header += QLatin1String(
"Content-Type: ");
2638 header += QLatin1String(
"\r\n");
2643 header += QLatin1String(
"DNT: 1\r\n");
2656 davHeader +=
metaData(QLatin1String(
"davHeader"));
2660 davHeader += QLatin1String(
"Content-Type: text/xml; charset=utf-8\r\n");
2667 kDebug(7103) <<
"============ Sending Header:";
2668 Q_FOREACH (
const QString &s,
header.split(QLatin1String(
"\r\n"), QString::SkipEmptyParts)) {
2674 if (!hasBodyData && !hasDavData)
2675 header += QLatin1String(
"\r\n");
2684 const QByteArray headerBytes =
header.toLatin1();
2685 ssize_t
written =
write(headerBytes.constData(), headerBytes.length());
2686 bool sendOk = (
written == (ssize_t) headerBytes.length());
2690 <<
" -- intended to write" << headerBytes.length()
2691 <<
"bytes but wrote" << (int)
written <<
".";
2701 kDebug(7113) <<
"sendOk == false. Connection broken !"
2702 <<
" -- intended to write" << headerBytes.length()
2703 <<
"bytes but wrote" << (int)
written <<
".";
2708 kDebug(7113) <<
"sent it!";
2711 if (hasBodyData || hasDavData)
2727 if (forwardImmediately)
2739 const QString
header = str.trimmed();
2740 if (
header.startsWith(QLatin1String(
"content-type:"), Qt::CaseInsensitive)) {
2741 int pos =
header.indexOf(QLatin1String(
"charset="), Qt::CaseInsensitive);
2743 const QString charset =
header.mid(pos + 8).toLower();
2747 }
else if (
header.startsWith(QLatin1String(
"content-language:"), Qt::CaseInsensitive)) {
2748 const QString language =
header.mid(17).trimmed().toLower();
2749 setMetaData(QLatin1String(
"content-language"), language);
2750 }
else if (
header.startsWith(QLatin1String(
"content-disposition:"), Qt::CaseInsensitive)) {
2777 if (
m_mimeType == QLatin1String(
"application/x-targz"))
2778 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2779 else if (
m_mimeType == QLatin1String(
"image/x-png"))
2783 else if (
m_mimeType == QLatin1String(
"audio/microsoft-wave"))
2785 else if (
m_mimeType == QLatin1String(
"image/x-ms-bmp"))
2789 else if (
m_mimeType == QLatin1String(
"application/pkix-cert") ||
2790 m_mimeType == QLatin1String(
"application/binary-certificate")) {
2791 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2795 else if (
m_mimeType == QLatin1String(
"application/x-gzip")) {
2798 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2800 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2805 else if(
m_mimeType == QLatin1String(
"application/x-xz")) {
2808 m_mimeType = QLatin1String(
"application/x-xz-compressed-tar");
2813 else if ((
m_mimeType == QLatin1String(
"text/plain")) || (
m_mimeType == QLatin1String(
"application/octet-stream"))) {
2815 if (ext == QLatin1String(
"BZ2"))
2816 m_mimeType = QLatin1String(
"application/x-bzip");
2817 else if (ext == QLatin1String(
"PEM"))
2818 m_mimeType = QLatin1String(
"application/x-x509-ca-cert");
2819 else if (ext == QLatin1String(
"SWF"))
2820 m_mimeType = QLatin1String(
"application/x-shockwave-flash");
2821 else if (ext == QLatin1String(
"PLS"))
2823 else if (ext == QLatin1String(
"WMV"))
2824 m_mimeType = QLatin1String(
"video/x-ms-wmv");
2825 else if (ext == QLatin1String(
"WEBM"))
2827 else if (ext == QLatin1String(
"DEB"))
2828 m_mimeType = QLatin1String(
"application/x-deb");
2842 if (
m_mimeType == QLatin1String(
"application/x-tar")) {
2844 m_mimeType = QLatin1String(
"application/x-compressed-tar");
2845 }
else if (
m_mimeType == QLatin1String(
"application/postscript")) {
2849 m_mimeType = QLatin1String(
"application/x-gzpostscript");
2854 m_mimeType != QLatin1String(
"application/x-compressed-tar") &&
2855 m_mimeType != QLatin1String(
"application/x-tgz") &&
2856 m_mimeType != QLatin1String(
"application/x-targz") &&
2857 m_mimeType != QLatin1String(
"application/x-gzip"))) {
2861 m_mimeType = QLatin1String(
"application/x-gzip");
2873 m_mimeType = QLatin1String(
"application/x-bzip");
2880static bool consume(
const char input[],
int *pos,
int end,
const char *term)
2884 if (idx + (
int)strlen(term) >=
end) {
2888 if (strncasecmp(&input[idx], term, strlen(term)) == 0) {
2889 *pos = idx + strlen(term);
2913 bool upgradeRequired =
false;
2917 bool noHeadersFound =
false;
2922 static const int maxHeaderSize = 128 * 1024;
2924 char buffer[maxHeaderSize];
2926 bool bCanResume =
false;
2929 kDebug(7113) <<
"No connection.";
2939 kDebug(7113) <<
"Got socket error:" <<
socket()->errorString();
2948 if (!foundDelimiter && bufPos < maxHeaderSize) {
2949 kDebug(7113) <<
"EOF while waiting for header start.";
2966 kDebug(7113) <<
"Connection broken !";
2970 if (!foundDelimiter) {
2975 kDebug(7103) <<
"============ Received Status Response:";
2976 kDebug(7103) << QByteArray(buffer, bufPos).trimmed();
2981 if (idx != bufPos && buffer[idx] ==
'<') {
2982 kDebug(7103) <<
"No valid HTTP header found! Document starts with XML/HTML tag";
2988 noHeadersFound =
true;
2995 if (
consume(buffer, &idx, bufPos,
"ICY ")) {
2998 }
else if (
consume(buffer, &idx, bufPos,
"HTTP/")) {
2999 if (
consume(buffer, &idx, bufPos,
"1.0")) {
3002 }
else if (
consume(buffer, &idx, bufPos,
"1.1")) {
3007 if (httpRev ==
HTTP_None && bufPos != 0) {
3010 kDebug(7113) <<
"DO NOT WANT." << bufPos;
3018 noHeadersFound =
true;
3029 if (idx != bufPos) {
3046 i18nc(
"@info Security check on url being accessed",
3047 "<p>You are about to log in to the site \"%1\" "
3048 "with the username \"%2\", but the website "
3049 "does not require authentication. "
3050 "This may be an attempt to trick you.</p>"
3051 "<p>Is \"%1\" the site you want to visit?</p>",
3053 i18nc(
"@title:window",
"Confirm Website Access"));
3080 upgradeRequired =
true;
3102 setMetaData(QLatin1String(
"permanent-redirect"), QLatin1String(
"true"));
3106 setMetaData(QLatin1String(
"redirect-to-get"), QLatin1String(
"true"));
3111 setMetaData(QLatin1String(
"redirect-to-get"), QLatin1String(
"true"));
3115 setMetaData(QLatin1String(
"permanent-redirect"), QLatin1String(
"true"));
3150 bool authRequiresAnotherRoundtrip =
false;
3153 if (!noHeadersFound) {
3158 kDebug(7113) <<
"wasAuthError=" << wasAuthError <<
"isAuthError=" << isAuthError
3159 <<
"sameAuthError=" << sameAuthError;
3171 kDebug(7113) <<
" -- full response:" << endl << QByteArray(buffer, bufPos).trimmed();
3174 Q_ASSERT(foundDelimiter);
3181 tokenizer.
tokenize(idx,
sizeof(buffer));
3186 if (tIt.
hasNext() && tIt.
next().toLower().startsWith(
"none")) {
3190 tIt = tokenizer.iterator(
"keep-alive");
3192 QByteArray ka = tIt.
next().trimmed().toLower();
3193 if (ka.startsWith(
"timeout=")) {
3194 int ka_timeout = ka.mid(qstrlen(
"timeout=")).trimmed().toInt();
3206 tIt = tokenizer.iterator(
"content-length");
3211 tIt = tokenizer.iterator(
"content-location");
3218 QString mediaAttribute;
3219 tIt = tokenizer.iterator(
"content-type");
3225 if (
m_mimeType.startsWith(QLatin1Char(
'"'))) {
3237 Q_FOREACH (
const QByteArray &statement, l) {
3238 const int index = statement.indexOf(
'=');
3240 mediaAttribute =
toQString(statement.mid(0, index));
3242 mediaAttribute =
toQString(statement.mid(0, index));
3243 mediaValue =
toQString(statement.mid(index+1));
3245 mediaAttribute = mediaAttribute.trimmed();
3246 mediaValue = mediaValue.trimmed();
3248 bool quoted =
false;
3249 if (mediaValue.startsWith(QLatin1Char(
'"'))) {
3251 mediaValue.remove(0, 1);
3254 if (mediaValue.endsWith(QLatin1Char(
'"'))) {
3258 kDebug (7113) <<
"Encoding-type:" << mediaAttribute <<
"=" << mediaValue;
3260 if (mediaAttribute == QLatin1String(
"charset")) {
3261 mediaValue = mediaValue.toLower();
3263 setMetaData(QLatin1String(
"charset"), mediaValue);
3265 setMetaData(QLatin1String(
"media-") + mediaAttribute, mediaValue);
3267 setMetaData(QLatin1String(
"media-") + mediaAttribute + QLatin1String(
"-kio-quoted"),
3268 QLatin1String(
"true"));
3275 tIt = tokenizer.iterator(
"content-encoding");
3293 tIt = tokenizer.iterator(
"content-disposition");
3297 tIt = tokenizer.iterator(
"content-language");
3300 if (!language.isEmpty()) {
3301 setMetaData(QLatin1String(
"content-language"), language);
3305 tIt = tokenizer.iterator(
"proxy-connection");
3307 QByteArray pc = tIt.
next().toLower();
3308 if (pc.startsWith(
"close")) {
3310 }
else if (pc.startsWith(
"keep-alive")) {
3315 tIt = tokenizer.iterator(
"link");
3318 QStringList
link =
toQString(tIt.
next()).split(QLatin1Char(
';'), QString::SkipEmptyParts);
3319 if (
link.count() == 2) {
3320 QString rel =
link[1].trimmed();
3321 if (rel.startsWith(QLatin1String(
"rel=\""))) {
3322 rel = rel.mid(5, rel.length() - 6);
3323 if (rel.toLower() == QLatin1String(
"pageservices")) {
3325 QString url =
link[0].remove(QRegExp(QLatin1String(
"[<>]"))).trimmed();
3332 tIt = tokenizer.iterator(
"p3p");
3335 QStringList policyrefs, compact;
3338 .split(QLatin1Char(
'='), QString::SkipEmptyParts);
3339 if (policy.count() == 2) {
3340 if (policy[0].toLower() == QLatin1String(
"policyref")) {
3341 policyrefs << policy[1].remove(QRegExp(QLatin1String(
"[\")\']"))).trimmed();
3342 }
else if (policy[0].toLower() == QLatin1String(
"cp")) {
3346 const QString s = policy[1].remove(QRegExp(QLatin1String(
"[\")\']")));
3347 const QStringList cps = s.split(QLatin1Char(
' '), QString::SkipEmptyParts);
3352 if (!policyrefs.isEmpty()) {
3353 setMetaData(QLatin1String(
"PrivacyPolicy"), policyrefs.join(QLatin1String(
"\n")));
3355 if (!compact.isEmpty()) {
3356 setMetaData(QLatin1String(
"PrivacyCompactPolicy"), compact.join(QLatin1String(
"\n")));
3363 tIt = tokenizer.iterator(
"connection");
3365 QByteArray connection = tIt.
next().toLower();
3367 if (connection.startsWith(
"close")) {
3369 }
else if (connection.startsWith(
"keep-alive")) {
3373 if (connection.startsWith(
"upgrade")) {
3376 upgradeRequired =
true;
3377 }
else if (upgradeRequired) {
3383 tIt = tokenizer.iterator(
"transfer-encoding");
3392 tIt = tokenizer.iterator(
"content-md5");
3399 tIt = tokenizer.iterator(
"dav");
3408 QStringList upgradeOffers;
3409 tIt = tokenizer.iterator(
"upgrade");
3413 upgradeOffers = offered.split(QRegExp(QLatin1String(
"[ \n,\r\t]")), QString::SkipEmptyParts);
3415 Q_FOREACH (
const QString &opt, upgradeOffers) {
3416 if (opt == QLatin1String(
"TLS/1.0")) {
3417 if (!
startSsl() && upgradeRequired) {
3421 }
else if (opt == QLatin1String(
"HTTP/1.1")) {
3423 }
else if (upgradeRequired) {
3431 QByteArray cookieStr;
3432 tIt = tokenizer.iterator(
"set-cookie");
3434 cookieStr +=
"Set-Cookie: ";
3435 cookieStr += tIt.
next();
3438 if (!cookieStr.isEmpty()) {
3443 cookieStr =
"Cross-Domain\n" + cookieStr;
3448 setMetaData(QLatin1String(
"setcookies"), QString::fromUtf8(cookieStr));
3456 kDebug(7113) <<
"cont; returning to mark try_again";
3462 kDebug(7113) <<
"Ignoring keep-alive: otherwise unable to determine response body length.";
3477 authRequiresAnotherRoundtrip =
false;
3480 QString locationStr;
3482 tIt = tokenizer.iterator(
"location");
3484 locationStr = QString::fromUtf8(tIt.
next().trimmed());
3487 if (!locationStr.isEmpty())
3514 if(u.
protocol() == QLatin1String(
"http")){
3516 }
else if(u.
protocol() == QLatin1String(
"https")){
3556 kDebug(7113) <<
"Reading resource from cache even though the cache plan is not "
3557 "UseCached; the server is probably sending wrong expiry information.";
3567 int nextLinePos = 0;
3568 int prevLinePos = 0;
3569 bool haveMore =
true;
3571 haveMore =
nextLine(buffer, &nextLinePos, bufPos);
3572 int prevLineEnd = nextLinePos;
3573 while (buffer[prevLineEnd - 1] ==
'\r' || buffer[prevLineEnd - 1] ==
'\n') {
3578 prevLineEnd - prevLinePos));
3579 prevLinePos = nextLinePos;
3606 return !authRequiresAnotherRoundtrip;
3614 while (i != parameters.constEnd()) {
3615 setMetaData(QLatin1String(
"content-disposition-") + i.key(), i.value());
3616 kDebug(7113) <<
"Content-Disposition:" << i.key() <<
"=" << i.value();
3623 QString encoding = _encoding.trimmed().toLower();
3625 if (encoding == QLatin1String(
"identity")) {
3627 }
else if (encoding == QLatin1String(
"8bit")) {
3630 }
else if (encoding == QLatin1String(
"chunked")) {
3635 }
else if ((encoding == QLatin1String(
"x-gzip")) || (encoding == QLatin1String(
"gzip"))) {
3636 encs.append(QLatin1String(
"gzip"));
3637 }
else if ((encoding == QLatin1String(
"x-bzip2")) || (encoding == QLatin1String(
"bzip2"))) {
3638 encs.append(QLatin1String(
"bzip2"));
3639 }
else if ((encoding == QLatin1String(
"x-deflate")) || (encoding == QLatin1String(
"deflate"))) {
3640 encs.append(QLatin1String(
"deflate"));
3642 kDebug(7113) <<
"Unknown encoding encountered. "
3643 <<
"Please write code. Encoding =" << encoding;
3661 const qint64 currentDate = QDateTime::currentMSecsSinceEpoch()/1000;
3676 qint64 dateHeader = -1;
3677 tIt = tokenizer.iterator(
"date");
3683 qint64 ageHeader = 0;
3684 tIt = tokenizer.iterator(
"age");
3686 ageHeader = tIt.
next().toLongLong();
3690 if (dateHeader != -1) {
3692 }
else if (ageHeader) {
3699 bool hasCacheDirective =
false;
3703 qint64 maxAgeHeader = 0;
3704 tIt = tokenizer.iterator(
"cache-control");
3706 QByteArray cacheStr = tIt.
next().toLower();
3707 if (cacheStr.startsWith(
"no-cache") || cacheStr.startsWith(
"no-store")) {
3710 hasCacheDirective =
true;
3711 }
else if (cacheStr.startsWith(
"max-age=")) {
3712 QByteArray ba = cacheStr.mid(qstrlen(
"max-age=")).trimmed();
3714 maxAgeHeader = ba.toLongLong(&
ok);
3716 hasCacheDirective =
true;
3721 qint64 expiresHeader = -1;
3722 tIt = tokenizer.iterator(
"expires");
3725 kDebug(7113) <<
"parsed expire date from 'expires' header:" << tIt.
current();
3730 }
else if (expiresHeader != -1) {
3739 expAge = qMin(expAge, qint64(3600 * 24));
3752 tIt = tokenizer.iterator(
"etag");
3757 kDebug(7103) <<
"304 Not Modified but new entity tag - I don't think this is legal HTTP.";
3762 tIt = tokenizer.iterator(
"warning");
3770 tIt = tokenizer.iterator(
"pragma");
3772 if (tIt.
next().toLower().startsWith(
"no-cache")) {
3774 hasCacheDirective =
true;
3779 tIt = tokenizer.iterator(
"refresh");
3786 if (
m_mimeType.startsWith(QLatin1String(
"text/")) && (
m_mimeType != QLatin1String(
"text/css")) &&
3787 (
m_mimeType != QLatin1String(
"text/x-javascript")) && !hasCacheDirective) {
3798 kDebug(7113) <<
"Cache needs validation";
3800 kDebug(7113) <<
"...was revalidated by response code but not by updated expire times. "
3801 "We're going to set the expire date to 60 seconds in the future...";
3807 kDebug(7113) <<
"this proxy or server apparently sends bogus expiry information.";
3824 kDebug(7113) <<
"This webserver is confused about the cacheability of the data it sends.";
3838 if (!cachingAllowed) {
3839 setMetaData(QLatin1String(
"no-cache"), QLatin1String(
"true"));
3840 setMetaData(QLatin1String(
"expire-date"), QLatin1String(
"1"));
3847 setMetaData(QLatin1String(
"cache-creation-date"), tmp);
3856 QByteArray cLength (
"Content-Length: ");
3857 cLength += QByteArray::number(size);
3858 cLength +=
"\r\n\r\n";
3860 kDebug(7113) <<
"sending cached data (size=" << size <<
")";
3863 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3865 kDebug( 7113 ) <<
"Connection broken when sending "
3878 const QByteArray buffer =
m_POSTbuf->read(65536);
3879 const ssize_t bytesSent =
write(buffer.data(), buffer.size());
3880 if (bytesSent !=
static_cast<ssize_t
>(buffer.size())) {
3881 kDebug(7113) <<
"Connection broken when sending message body: ("
3887 totalBytesSent += bytesSent;
3915 QByteArray cLength (
"Content-Length: ");
3917 cLength +=
"\r\n\r\n";
3919 kDebug(7113) << cLength.trimmed();
3922 bool sendOk = (
write(cLength.data(), cLength.size()) == (ssize_t) cLength.size());
3932 kDebug(7113) <<
"Connection broken while sending POST content size to" <<
m_request.
url.host();
3951 const int bytesRead =
readData(buffer);
3954 if (bytesRead == 0) {
3960 if (bytesRead < 0) {
3974 if (
write(buffer.data(), bytesRead) ==
static_cast<ssize_t
>(bytesRead)) {
3975 bytesSent += bytesRead;
3980 kDebug(7113) <<
"Connection broken while sending POST content to" <<
m_request.
url.host();
3990 kDebug(7113) <<
"keepAlive =" << keepAlive;
4006 QDataStream stream( &
data, QIODevice::WriteOnly );
4065 QDataStream stream(
data);
4073 stream >> url >> size;
4082 stream >> url >> no_cache >> expireDate;
4088 QFile::remove(filename);
4108 QString scope, type, owner;
4109 stream >> url >> scope >> type >> owner;
4110 davLock( url, scope, type, owner );
4125 stream >> url >> method >> size;
4126 davGeneric( url, (KIO::HTTP_METHOD) method, size );
4155 if (foundCrLf && bufPos == 2) {
4162 kDebug(7113) <<
"Failed to read chunk header.";
4165 Q_ASSERT(bufPos > 2);
4168 if (nextChunkSize < 0)
4170 kDebug(7113) <<
"Negative chunk size";
4187 int trashBufPos = 2;
4190 if (trashBufPos > 3) {
4192 for (
int i = 0; i < 3; i++) {
4200 kDebug(7113) <<
"Failed to read chunk trailer.";
4212 return bytesReceived;
4230 if (bytesReceived <= 0)
4234 return bytesReceived;
4241 kDebug(7113) <<
"Unbounded datastream on a Keep-alive connection!";
4281 kDebug(7113) <<
"Determining mime-type from content...";
4295 if( mime && !mime->isDefault() )
4376 if ( !dataInternal ) {
4387 kDebug(7113) <<
"reading data from cache...";
4399 if (!dataInternal) {
4406 if (!dataInternal) {
4434 QObject::connect(&chain, SIGNAL(
output(QByteArray)),
4437 QObject::connect(&chain, SIGNAL(
error(QString)),
4444 if ( enc == QLatin1String(
"gzip") )
4446 else if ( enc == QLatin1String(
"deflate") )
4474 if ( enc == QLatin1String(
"gzip") )
4476 else if ( enc == QLatin1String(
"deflate") )
4495 if (bytesReceived == -1)
4505 kDebug(7113) <<
"bytesReceived==-1 sz=" << (int)sz
4506 <<
" Connection broken !";
4513 if (bytesReceived > 0)
4524 sz += bytesReceived;
4547 QString calculatedMD5 = md5Filter->
md5();
4550 kWarning(7113) <<
"MD5 checksum MISMATCH! Expected:"
4559 if (!dataInternal && sz <= 1)
4572 data( QByteArray() );
4608 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4609 (void)kcookiejar.call( QDBus::NoBlock, QLatin1String(
"addCookies"), url,
4610 cookieHeader, windowId );
4616 QDBusInterface kcookiejar( QLatin1String(
"org.kde.kded"), QLatin1String(
"/modules/kcookiejar"), QLatin1String(
"org.kde.KCookieServer") );
4617 QDBusReply<QString> reply = kcookiejar.call( QLatin1String(
"findCookies"), url, windowId );
4619 if ( !reply.isValid() )
4621 kWarning(7113) <<
"Can't communicate with kded_kcookiejar!";
4650 qint64 currentDate = QDateTime::currentMSecsSinceEpoch()/1000;
4663struct BinaryCacheFileHeader
4670 qint64 lastModifiedDate;
4675 static const int size = 36;
4687 BinaryCacheFileHeader
header;
4688 quint32 commandCode;
4696 QDataStream stream(&ret, QIODevice::WriteOnly);
4697 stream << quint8(
'A');
4698 stream << quint8(
'\n');
4699 stream << quint8(0);
4700 stream << quint8(0);
4702 stream << fileUseCount;
4703 stream << servedDate;
4704 stream << lastModifiedDate;
4705 stream << expireDate;
4707 stream << bytesCached;
4708 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size);
4716 return byte == value;
4725 if (d.size() != BinaryCacheFileHeader::size) {
4728 QDataStream stream(d);
4729 stream.setVersion(QDataStream::Qt_4_5);
4740 stream >> fileUseCount;
4741 stream >> servedDate;
4742 stream >> lastModifiedDate;
4743 stream >> expireDate;
4744 stream >> bytesCached;
4762 ret.setPassword(QString());
4763 ret.setFragment(QString());
4769 static const char linefeed =
'\n';
4771 dev->write(&linefeed, 1);
4778 Q_ASSERT(file->openMode() & QIODevice::WriteOnly);
4780 file->seek(BinaryCacheFileHeader::size);
4794 if (line->isEmpty() || !line->endsWith(
'\n')) {
4806 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4810 if (
storableUrl(desiredUrl).toEncoded() != readBuf) {
4811 kDebug(7103) <<
"You have witnessed a very improbable hash collision!";
4825 Q_ASSERT(file->openMode() == QIODevice::ReadOnly);
4831 qint64 oldPos = file->pos();
4832 file->seek(BinaryCacheFileHeader::size);
4835 Q_ASSERT(file->pos() == oldPos);
4844 if (
ok && !readBuf.isEmpty()) {
4855 QCryptographicHash hash(QCryptographicHash::Sha1);
4857 return toQString(hash.result().toHex());
4863 if (!
filePath.endsWith(QLatin1Char(
'/'))) {
4877 kDebug(7113) <<
"File unexpectedly open; old file is" << file->fileName()
4878 <<
"new name is" << filename;
4879 Q_ASSERT(file->fileName() == filename);
4882 file =
new QFile(filename);
4883 if (file->open(QIODevice::ReadOnly)) {
4884 QByteArray
header = file->read(BinaryCacheFileHeader::size);
4886 kDebug(7103) <<
"Cache file header is invalid.";
4896 if (!file->isOpen()) {
4914 Q_ASSERT(!qobject_cast<QTemporaryFile *>(file));
4915 Q_ASSERT((file->openMode() & QIODevice::WriteOnly) == 0);
4916 Q_ASSERT(file->fileName() == filename);
4917 kDebug(7113) <<
"deleting expired cache entry and recreating.";
4925 file->open(QIODevice::WriteOnly);
4931 if ((file->openMode() & QIODevice::WriteOnly) == 0) {
4932 kDebug(7113) <<
"Could not open file for writing:" << file->fileName()
4933 <<
"due to error" << file->error();
4944 QDataStream stream(&ret, QIODevice::WriteOnly);
4945 stream.setVersion(QDataStream::Qt_4_5);
4947 stream.skipRawData(BinaryCacheFileHeader::size);
4949 stream << quint32(cmd);
4951 QString fileName = cacheTag.
file->fileName();
4952 int basenameStart = fileName.lastIndexOf(QLatin1Char(
'/')) + 1;
4954 stream.writeRawData(baseName.constData(), baseName.size());
4956 Q_ASSERT(ret.size() == BinaryCacheFileHeader::size +
sizeof(quint32) +
s_hashedUrlNibbles);
4972 QByteArray ccCommand;
4975 if (file->openMode() & QIODevice::WriteOnly) {
4985 QString oldName = tempFile->fileName();
4986 QString newName = oldName;
4987 int basenameStart = newName.lastIndexOf(QLatin1Char(
'/')) + 1;
4990 kDebug(7113) <<
"Renaming temporary file" << oldName <<
"to" << newName;
4993 tempFile->setAutoRemove(
false);
4997 if (!QFile::rename(oldName, newName)) {
5000 kDebug(7113) <<
"Renaming temporary file failed, deleting it instead.";
5001 QFile::remove(oldName);
5008 }
else if (file->openMode() == QIODevice::ReadOnly) {
5009 Q_ASSERT(!tempFile);
5015 if (!ccCommand.isEmpty()) {
5023 Q_ASSERT(command.size() == BinaryCacheFileHeader::size +
s_hashedUrlNibbles +
sizeof(quint32));
5026 if (attempts == 2) {
5040 kDebug(7113) <<
"Could not connect to cache cleaner, not updating stats of this cache file.";
5050 if (ret.isEmpty()) {
5067 kDebug(7113) <<
"Caching disabled because content size is too big.";
5123 const int bytesRead =
readData(buffer);
5125 if (bytesRead < 0) {
5130 if (bytesRead == 0) {
5134 m_POSTbuf->write(buffer.constData(), buffer.size());
5163 const QByteArray cachedChallenge =
config()->
readEntry(
"www-auth-challenge", QByteArray());
5164 if (!cachedChallenge.isEmpty()) {
5167 kDebug(7113) <<
"creating www authentcation header from cached info";
5186 const QByteArray cachedChallenge =
config()->
readEntry(
"proxy-auth-challenge", QByteArray());
5187 if (!cachedChallenge.isEmpty()) {
5190 kDebug(7113) <<
"creating proxy authentcation header from cached info";
5200 ret +=
"Authorization: ";
5205 ret +=
"Proxy-Authorization: ";
5215 case QNetworkProxy::DefaultProxy:
5217 case QNetworkProxy::Socks5Proxy:
5218 return QLatin1String(
"socks");
5219 case QNetworkProxy::NoProxy:
5221 case QNetworkProxy::HttpProxy:
5222 case QNetworkProxy::HttpCachingProxy:
5223 case QNetworkProxy::FtpCachingProxy:
5228 return QLatin1String(
"http");
5233 kDebug(7113) <<
"realm:" << authenticator->realm() <<
"user:" << authenticator->user();
5244 info.
username = authenticator->user();
5252 if (!haveCachedCredentials || retryAuth) {
5258 info.
prompt =
i18n(
"You need to supply a username and a password for "
5259 "the proxy server listed below before you are allowed "
5260 "to access any sites.");
5265 const QString errMsg ((retryAuth ?
i18n(
"Proxy Authentication Failed.") : QString()));
5268 kDebug(7113) <<
"looks like the user canceled proxy authentication.";
5275 authenticator->setUser(info.
username);
5276 authenticator->setPassword(info.
password);
5277 authenticator->setOption(QLatin1String(
"keepalive"), info.
keepPassword);
5292 kDebug(7113) <<
"Saving authenticator";
5314 bool alreadyCached =
false;
5330 if (auth && (!auth->
realm().isEmpty() || !alreadyCached)) {
5333 setMetaData(QLatin1String(
"{internal~currenthost}cached-www-auth"), QLatin1String(
"true"));
5339 setMetaData(QLatin1String(
"{internal~allhosts}cached-proxy-auth"), QLatin1String(
"true"));
5365 authTokens = tokenizer->iterator(
"www-authenticate").all();
5368 authinfo.
prompt =
i18n(
"You need to supply a username and a "
5369 "password to access this site.");
5375 Q_ASSERT(QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy);
5377 authTokens = tokenizer->iterator(
"proxy-authenticate").all();
5380 authinfo.
prompt =
i18n(
"You need to supply a username and a password for "
5381 "the proxy server listed below before you are allowed "
5382 "to access any sites." );
5386 bool authRequiresAnotherRoundtrip =
false;
5391 if (!authTokens.isEmpty()) {
5393 authRequiresAnotherRoundtrip =
true;
5397 if ((*auth)->wasFinalStage()) {
5399 i18n(
"Authentication Failed.") :
5400 i18n(
"Proxy Authentication Failed."));
5408 QMutableListIterator<QByteArray> it (authTokens);
5409 const QByteArray authScheme ((*auth)->scheme().trimmed());
5410 while (it.hasNext()) {
5411 if (qstrnicmp(authScheme.constData(), it.next().constData(), authScheme.length()) != 0) {
5418try_next_auth_scheme:
5421 const QByteArray authScheme ((*auth)->scheme().trimmed());
5422 if (qstrnicmp(authScheme.constData(), bestOffer.constData(), authScheme.length()) != 0) {
5434 kDebug(7113) <<
"Trying authentication scheme:" << (*auth)->scheme();
5439 QString username, password;
5440 bool generateAuthHeader =
true;
5441 if ((*auth)->needCredentials()) {
5452 if (authinfo.
realmValue.isEmpty() && !(*auth)->supportsPathMatching())
5453 authinfo.
realmValue = QLatin1String((*auth)->scheme());
5458 const KUrl reqUrl = authinfo.
url;
5461 authinfo.
url = reqUrl;
5467 generateAuthHeader =
false;
5468 authRequiresAnotherRoundtrip =
false;
5472 kDebug(7113) <<
"looks like the user canceled the authentication dialog";
5482 if (generateAuthHeader) {
5483 (*auth)->generateResponse(username, password);
5484 (*auth)->setCachePasswordEnabled(authinfo.
keepPassword);
5486 kDebug(7113) <<
"isError=" << (*auth)->isError()
5487 <<
"needCredentials=" << (*auth)->needCredentials()
5488 <<
"forceKeepAlive=" << (*auth)->forceKeepAlive()
5489 <<
"forceDisconnect=" << (*auth)->forceDisconnect();
5491 if ((*auth)->isError()) {
5492 authTokens.removeOne(bestOffer);
5493 if (!authTokens.isEmpty()) {
5494 goto try_next_auth_scheme;
5499 authRequiresAnotherRoundtrip =
false;
5502 }
else if ((*auth)->forceKeepAlive()) {
5505 }
else if ((*auth)->forceDisconnect()) {
5512 authRequiresAnotherRoundtrip =
false;
5519 return authRequiresAnotherRoundtrip;
5524 kDebug(7113) << src <<
"->" << dest;
5545 if (!
m_POSTbuf->open(QFile::ReadOnly)) {
5558 const QByteArray request (
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
5559 "<D:propfind xmlns:D=\"DAV:\"><D:prop>"
5561 "<D:getcontentlength/>"
5564 "</D:prop></D:propfind>");
void addFilter(HTTPFilterBase *filter)
void slotInput(const QByteArray &d)
QAuthenticator * m_socketProxyAuth
void httpClose(bool keepAlive)
Close transfer.
bool maybeSetRequestUrl(const KUrl &)
void fixupResponseMimetype()
fix common mimetype errors by webservers.
QString davError(int code=-1, const QString &url=QString())
void cacheParseResponseHeader(const HeaderTokenizer &tokenizer)
bool handleAuthenticationHeader(const HeaderTokenizer *tokenizer)
Handles HTTP authentication.
long m_maxCacheSize
Maximum cache size in Kb.
bool readBody(bool dataInternal=false)
This function is our "receive" function.
void addEncoding(const QString &, QStringList &)
Add an encoding on to the appropriate stack this is nececesary because transfer encodings and content...
virtual void setHost(const QString &host, quint16 port, const QString &user, const QString &pass)
bool isOffline()
Check network status.
bool proceedUntilResponseHeader()
Ensure we are connected, send our query, and get the response header.
void httpCloseConnection()
Close connection.
virtual void put(const KUrl &url, int _mode, KIO::JobFlags flags)
bool httpShouldCloseConnection()
Check whether to keep or close the connection.
QString formatRequestUri() const
bool davStatDestination()
Stats a remote DAV file and returns true if it exists.
QByteArray m_mimeTypeBuffer
QStringList m_transferEncodings
bool sendHttpError()
Generate and send error message based on response code.
KAbstractHttpAuthentication * m_proxyAuth
QByteArray m_webDavDataBuf
bool readResponseHeader()
This function will read in the return header from the server.
void davLock(const KUrl &url, const QString &scope, const QString &type, const QString &owner)
QStringList m_responseHeaders
All headers.
int readLimited()
Read maximum m_iSize bytes.
virtual void copy(const KUrl &src, const KUrl &dest, int _permissions, KIO::JobFlags flags)
QString findCookies(const QString &url)
Look for cookies in the cookiejar.
bool retrieveAllData()
Returns true on successful retrieval of all content data.
quint16 defaultPort() const
void slotFilterError(const QString &text)
HTTPProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
bool readDelimitedText(char *buf, int *idx, int end, int numNewlines)
bool cacheFileReadTextHeader2()
load the rest of the text fields
QLocalSocket m_cacheCleanerConnection
Connection to the cache cleaner process.
void resetResponseParsing()
Resets variables related to parsing a response.
int m_maxCacheAge
Maximum age of a cache entry in seconds.
void addCookies(const QString &url, const QByteArray &cookieHeader)
Send a cookie to the cookiejar.
virtual void del(const KUrl &url, bool _isfile)
bool cacheFileOpenWrite()
KIO::filesize_t m_iContentLeft
int readUnlimited()
Read as much as possible.
bool sendErrorPageNotification()
Call SlaveBase::errorPage() and remember that we've called it.
int readChunked()
Read a chunk.
void saveProxyAuthenticationForSocket()
int codeFromResponse(const QString &response)
Returns the error code from a "HTTP/1.1 code Code Name" string.
void resetSessionSettings()
Resets any per session settings.
virtual void slave_status()
QString m_strCacheDir
Location of the cache.
void davUnlock(const KUrl &url)
virtual void closeConnection()
Forced close of connection.
void cacheFileWriteTextHeader()
void davGeneric(const KUrl &url, KIO::HTTP_METHOD method, qint64 size=-1)
void post(const KUrl &url, qint64 size=-1)
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 slotData(const QByteArray &)
void fixupResponseContentEncoding()
fix common content-encoding errors by webservers.
QByteArray m_receiveBuf
Receive buffer.
QByteArray cacheFileReadPayload(int maxLength)
virtual void listDir(const KUrl &url)
void davSetRequest(const QByteArray &requestXML)
Performs a WebDAV stat or list.
bool m_isChunked
Chunked transfer encoding.
void unread(char *buf, size_t size)
void davParsePropstats(const QDomNodeList &propstats, KIO::UDSEntry &entry)
bool m_isRedirection
Indicates current request is a redirection.
bool cacheFileReadTextHeader1(const KUrl &desiredUrl)
check URL to guard against hash collisions, and load the etag for validation
void resetConnectionSettings()
Resets any per connection settings.
bool m_dataInternal
Data is for internal consumption.
void setCacheabilityMetadata(bool cachingAllowed)
QString davProcessLocks()
Extracts locks from metadata Returns the appropriate If: header.
virtual void mimetype(const KUrl &url)
void copyPut(const KUrl &src, const KUrl &dest, KIO::JobFlags flags)
Handles file -> webdav put requests.
void parseContentDisposition(const QString &disposition)
QStringList m_contentEncodings
void multiGet(const QByteArray &data)
void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *)
virtual void stat(const KUrl &url)
KIO::filesize_t m_iBytesLeft
void proceedUntilResponseContent(bool dataInternal=false)
Do everything proceedUntilResponseHeader does, and also get the response body.
void forwardHttpResponseHeader(bool forwardImmediately=true)
virtual void mkdir(const KUrl &url, int _permissions)
virtual void get(const KUrl &url)
bool parseHeaderFromCache()
KIO::filesize_t m_iPostDataSize
QString authenticationHeader()
create HTTP authentications response(s), if any
void saveAuthenticationData()
Saves HTTP authentication data.
void sendCacheCleanerCommand(const QByteArray &command)
QString cacheFilePathFromUrl(const KUrl &url) const
bool m_isBusy
Busy handling request queue.
bool m_isLoadingErrorPage
QList< HTTPRequest > m_requestQueue
void error(int errid, const QString &text)
virtual void reparseConfiguration()
void davStatList(const KUrl &url, bool stat=true)
size_t readBuffered(char *buf, size_t size, bool unlimited=true)
KAbstractHttpAuthentication * m_wwwAuth
bool sendQuery()
This function is responsible for opening up the connection to the remote HTTP server and sending the ...
bool m_davHostUnsupported
void davParseActiveLocks(const QDomNodeList &activeLocks, uint &lockCount)
virtual void rename(const KUrl &src, const KUrl &dest, KIO::JobFlags flags)
virtual void special(const QByteArray &data)
Special commands supported by this slave : 1 - HTTP POST 2 - Cache has been updated 3 - SSL Certifica...
void cachePostData(const QByteArray &)
Caches the POST data in a temporary buffer.
void clearPostDataBuffer()
Clears the POST data buffer.
void cacheFileWritePayload(const QByteArray &d)
KIO::filesize_t m_iSize
Expected size of message.
QStringList m_davCapabilities
bool satisfyRequestFromCache(bool *cacheHasPage)
Return true if the request is already "done", false otherwise.
bool httpOpenConnection()
Open connection.
static QByteArray bestOffer(const QList< QByteArray > &offers)
Choose the best authentication mechanism from the offered ones.
virtual void fillKioAuthInfo(KIO::AuthInfo *ai) const =0
KIO compatible data to find cached credentials.
virtual void generateResponse(const QString &user, const QString &password)=0
what to do in response to challenge
QByteArray headerFragment() const
insert this into the next request header after "Authorization: " or "Proxy-Authorization: "
QString realm() const
Returns the realm sent by the server.
virtual void setChallenge(const QByteArray &c, const KUrl &resource, const QByteArray &httpMethod)
initiate authentication with challenge string (from HTTP header)
static KAbstractHttpAuthentication * newAuth(const QByteArray &offer, KConfigGroup *config=0)
Returns authentication object instance appropriate for offer.
QString readPathEntry(const char *key, const QString &aDefault) const
QString readEntry(const char *key, const char *aDefault=0) const
QString toString(const QString &format) const
QDateTime dateTime() const
static KDateTime fromString(const QString &string, const QString &format, const KTimeZones *zones=0, bool offsetIfAmbiguous=true)
void setTime_t(qint64 seconds)
void mimeType(const QString &_type)
QString metaData(const QString &key) const
void sendAndKeepMetaData()
void infoMessage(const QString &msg)
void processedSize(KIO::filesize_t _bytes)
void setTimeoutSpecialCommand(int timeout, const QByteArray &data=QByteArray())
void slaveStatus(const QString &host, bool connected)
bool cacheAuthentication(const AuthInfo &info)
int messageBox(const QString &text, MessageBoxType type, const QString &caption=QString(), const QString &buttonYes=i18n("&Yes"), const QString &buttonNo=i18n("&No"), const QString &dontAskAgainName=QString())
void written(KIO::filesize_t _bytes)
void redirection(const KUrl &_url)
void error(int _errid, const QString &_text)
bool hasMetaData(const QString &key) const
void statEntry(const UDSEntry &_entry)
bool openPasswordDialog(KIO::AuthInfo &info, const QString &errorMsg=QString())
KRemoteEncoding * remoteEncoding()
int readData(QByteArray &buffer)
void data(const QByteArray &data)
void listEntry(const UDSEntry &_entry, bool ready)
void totalSize(KIO::filesize_t _bytes)
MetaData mIncomingMetaData
bool checkCachedAuthentication(AuthInfo &info)
void setMetaData(const QString &key, const QString &value)
ssize_t write(const char *data, ssize_t len)
void disconnectFromHost()
int connectToHost(const QString &host, quint16 port, QString *errorString=0)
QIODevice * socket() const
bool waitForResponse(int t)
ssize_t read(char *data, ssize_t len)
QString stringValue(uint field) const
long long numberValue(uint field, long long defaultValue=0) const
void insert(uint field, const QString &value)
static Ptr findByNameAndContent(const QString &name, const QByteArray &data, mode_t mode=0, int *accuracy=0)
static Ptr findByUrl(const KUrl &url, mode_t mode=0, bool is_local_file=false, bool fast_mode=false, int *accuracy=0)
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value)
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
void adjustPath(AdjustPathOption trailing)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
void setProtocol(const QString &proto)
static List split(const KUrl &_url)
void setPath(const QString &path)
void setQuery(const QString &query)
void setRef(const QString &fragment)
void setEncodedPathAndQuery(const QString &_txt)
void setPass(const QString &pass)
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
static QString decode_string(const QString &str)
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
void setUser(const QString &user)
QByteArray current() const
void output(QList< Action > actions, QHash< QString, QString > domain)
static bool supportedProxyScheme(const QString &scheme)
static void changeProtocolToHttp(KUrl *url)
static bool compareByte(QDataStream *stream, quint8 value)
static void updateUDSEntryMimeType(UDSEntry *entry)
static bool isEncryptedHttpVariety(const QByteArray &p)
static QString filenameFromUrl(const KUrl &url)
static bool isValidProxy(const KUrl &u)
static const int s_hashedUrlBits
static void writeLine(QIODevice *dev, const QByteArray &line)
static QString formatHttpDate(qint64 date)
static int httpPutError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
static qint64 toTime_t(const QString &value, KDateTime::TimeFormat format)
static QString sanitizeCustomHTTPHeader(const QString &_header)
static qint64 parseDateTime(const QString &input, const QString &type)
static bool consume(const char input[], int *pos, int end, const char *term)
static QString protocolForProxyType(QNetworkProxy::ProxyType type)
static bool isCompatibleNextUrl(const KUrl &previous, const KUrl &now)
static bool isAuthenticationRequired(int responseCode)
int kdemain(int argc, char **argv)
static KUrl storableUrl(const KUrl &url)
static bool canHaveResponseBody(int responseCode, KIO::HTTP_METHOD method)
static bool isCrossDomainRequest(const QString &fqdn, const QString &originURL)
static int httpGenericError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
static bool isPotentialSpoofingAttack(const HTTPProtocol::HTTPRequest &request, const KConfigGroup *config)
static bool readLineChecked(QIODevice *dev, QByteArray *line)
static const int s_hashedUrlBytes
static QString htmlEscape(const QString &plain)
static bool supportedProxyScheme(const QString &scheme)
static QByteArray makeCacheCleanerCommand(const HTTPProtocol::CacheTag &cacheTag, CacheCleanerCommandCode cmd)
static QIODevice * createPostBufferDeviceFor(KIO::filesize_t size)
static int httpDelError(const HTTPProtocol::HTTPRequest &request, QString *errorString)
static bool isHttpProxy(const KUrl &u)
static QString toQString(const QByteArray &value)
@ CreateFileNotificationCommand
static const int s_MaxInMemPostBufSize
static const int s_hashedUrlNibbles
static const char version[]
static QString filePath(const QString &baseName)
#define DEFAULT_KEEP_ALIVE_TIMEOUT
#define DEFAULT_CACHE_EXPIRE
#define DEFAULT_CACHE_CONTROL
#define DEFAULT_MIME_TYPE
#define DEFAULT_MAX_CACHE_AGE
#define DEFAULT_MAX_CACHE_SIZE
#define DEFAULT_PARTIAL_CHARSET_HEADER
#define DEFAULT_ACCEPT_HEADER
#define DEFAULT_LANGUAGE_HEADER
#define DEFAULT_RESPONSE_TIMEOUT
#define DEFAULT_HTTPS_PORT
#define DEFAULT_HTTP_PORT
KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, const KAutostart::StartPhase &aDefault)
QString i18n(const char *text)
QString i18nc(const char *ctxt, const char *text)
KSharedConfigPtr config()
CopyJob * trash(const KUrl &src, JobFlags flags=DefaultFlags)
QString convertSize(KIO::filesize_t size)
CopyJob * link(const KUrl &src, const KUrl &destDir, JobFlags flags=DefaultFlags)
ERR_CANNOT_OPEN_FOR_READING
QString number(KIO::filesize_t size)
KIO::CacheControl parseCacheControl(const QString &cacheControl)
const char * name(StandardAction id)
bool isUtf8(const char *str)
static void skipSpace(const char input[], int *pos, int end)
static QMap< QString, QString > contentDispositionParser(const QString &disposition)
static bool nextLine(const char input[], int *pos, int end)
bool deserialize(const QByteArray &)
CachePlan plan(int maxCacheAge) const
QByteArray serialize() const
The request for the current connection.
QByteArray methodString() const
bool allowTransferCompression
QByteArray sentMethodString
KIO::filesize_t endoffset
bool doNotWWWAuthenticate
enum HTTPProtocol::HTTPRequest::@1 cookieMode
unsigned int responseCode
unsigned int prevResponseCode
QString methodStringOverride
bool doNotProxyAuthenticate
void initFrom(const HTTPRequest &request)
void updateCredentials(const HTTPRequest &request)