KIOSlave
http.h
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2000,2001 Dawit Alemayehu <adawit@kde.org> 00003 Copyright (C) 2000,2001 Waldo Bastian <bastian@kde.org> 00004 Copyright (C) 2000,2001 George Staikos <staikos@kde.org> 00005 Copyright (C) 2001,2002 Hamish Rodda <rodda@kde.org> 00006 Copyright (C) 2007 Daniel Nicoletti <mirttex@users.sourceforge.net> 00007 Copyright (C) 2008,2009 Andreas Hartmetz <ahartmetz@gmail.com> 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License as published by the Free Software Foundation; either 00012 version 2 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Library General Public License for more details. 00018 00019 You should have received a copy of the GNU Library General Public License 00020 along with this library; see the file COPYING.LIB. If not, write to 00021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00022 Boston, MA 02110-1301, USA. 00023 */ 00024 00025 #ifndef HTTP_H 00026 #define HTTP_H 00027 00028 00029 #include <sys/types.h> 00030 #include <netinet/in.h> 00031 #include <arpa/inet.h> 00032 #include <string.h> 00033 #include <stdio.h> 00034 #include <time.h> 00035 00036 #include <QtCore/QList> 00037 #include <QtCore/QStringList> 00038 #include <QtNetwork/QLocalSocket> 00039 00040 #include <kurl.h> 00041 #include "kio/tcpslavebase.h" 00042 #include "kio/http.h" 00043 00044 00045 class QDomNodeList; 00046 class QFile; 00047 class QIODevice; 00048 00049 namespace KIO { 00050 class AuthInfo; 00051 } 00052 00053 class HeaderTokenizer; 00054 class KAbstractHttpAuthentication; 00055 00056 class HTTPProtocol : public QObject, public KIO::TCPSlaveBase 00057 { 00058 Q_OBJECT 00059 public: 00060 HTTPProtocol( const QByteArray &protocol, const QByteArray &pool, 00061 const QByteArray &app ); 00062 virtual ~HTTPProtocol(); 00063 00065 enum HTTP_REV {HTTP_None, HTTP_Unknown, HTTP_10, HTTP_11, SHOUTCAST}; 00066 00068 enum AUTH_SCHEME {AUTH_None, AUTH_Basic, AUTH_NTLM, AUTH_Digest, AUTH_Negotiate}; 00069 00071 struct DAVRequest 00072 { 00073 DAVRequest () 00074 { 00075 overwrite = false; 00076 depth = 0; 00077 } 00078 00079 QString desturl; 00080 bool overwrite; 00081 int depth; 00082 }; 00083 00084 enum CacheIOMode { 00085 NoCache = 0, 00086 ReadFromCache = 1, 00087 WriteToCache = 2 00088 }; 00089 00090 struct CacheTag 00091 { 00092 CacheTag() 00093 { 00094 useCache = false; 00095 ioMode = NoCache; 00096 bytesCached = 0; 00097 file = 0; 00098 expireDate = 0; 00099 servedDate = 0; 00100 } 00101 00102 enum CachePlan { 00103 UseCached = 0, 00104 ValidateCached, 00105 IgnoreCached 00106 }; 00107 CachePlan plan(time_t maxCacheAge) const; 00108 00109 QByteArray serialize() const; 00110 bool deserialize(const QByteArray &); 00111 00112 KIO::CacheControl policy; // ### initialize in the constructor? 00113 bool useCache; // Whether the cache should be used 00114 enum CacheIOMode ioMode; // Write to cache file, read from it, or don't use it. 00115 quint32 fileUseCount; 00116 quint32 bytesCached; 00117 QString etag; // entity tag header as described in the HTTP standard. 00118 QFile *file; // file on disk - either a QTemporaryFile (write) or QFile (read) 00119 time_t servedDate; // Date when the resource was served by the origin server 00120 time_t lastModifiedDate; // Last modified. 00121 time_t expireDate; // Date when the cache entry will expire 00122 QString charset; 00123 }; 00124 00126 struct HTTPRequest 00127 { 00128 HTTPRequest () 00129 { 00130 method = KIO::HTTP_UNKNOWN; 00131 offset = 0; 00132 endoffset = 0; 00133 allowTransferCompression = false; 00134 disablePassDialog = false; 00135 doNotWWWAuthenticate = false; 00136 doNotProxyAuthenticate = false; 00137 preferErrorPage = false; 00138 useCookieJar = false; 00139 } 00140 00141 QByteArray methodString() const; 00142 00143 KUrl url; 00144 QString encoded_hostname; //### can be calculated on-the-fly 00145 // Persistent connections 00146 bool isKeepAlive; 00147 int keepAliveTimeout; // Timeout in seconds. 00148 00149 KIO::HTTP_METHOD method; 00150 QString methodStringOverride; // Overrides method if non-empty. 00151 KIO::filesize_t offset; 00152 KIO::filesize_t endoffset; 00153 QString windowId; // Window Id this request is related to. 00154 // Header fields 00155 QString referrer; 00156 QString charsets; 00157 QString languages; 00158 QString userAgent; 00159 // Previous and current response codes 00160 unsigned int responseCode; 00161 unsigned int prevResponseCode; 00162 // Miscellaneous 00163 QString id; 00164 DAVRequest davData; 00165 KUrl redirectUrl; 00166 KUrl proxyUrl; 00167 QStringList proxyUrls; 00168 00169 bool isPersistentProxyConnection; 00170 bool allowTransferCompression; 00171 bool disablePassDialog; 00172 bool doNotWWWAuthenticate; 00173 bool doNotProxyAuthenticate; 00174 // Indicates whether an error page or error message is preferred. 00175 bool preferErrorPage; 00176 00177 // Use the cookie jar (or pass cookies to the application as metadata instead) 00178 bool useCookieJar; 00179 // Cookie flags 00180 enum { CookiesAuto, CookiesManual, CookiesNone } cookieMode; 00181 00182 CacheTag cacheTag; 00183 }; 00184 00186 struct HTTPServerState 00187 { 00188 HTTPServerState() 00189 { 00190 isKeepAlive = false; 00191 isPersistentProxyConnection = false; 00192 } 00193 00194 void initFrom(const HTTPRequest &request) 00195 { 00196 url = request.url; 00197 encoded_hostname = request.encoded_hostname; 00198 isKeepAlive = request.isKeepAlive; 00199 proxyUrl = request.proxyUrl; 00200 isPersistentProxyConnection = request.isPersistentProxyConnection; 00201 } 00202 00203 void updateCredentials(const HTTPRequest &request) 00204 { 00205 if (url.host() == request.url.host() && url.port() == request.url.port()) { 00206 url.setUserName(request.url.userName()); 00207 url.setPassword(request.url.password()); 00208 } 00209 if (proxyUrl.host() == request.proxyUrl.host() && 00210 proxyUrl.port() == request.proxyUrl.port()) { 00211 proxyUrl.setUserName(request.proxyUrl.userName()); 00212 proxyUrl.setPassword(request.proxyUrl.password()); 00213 } 00214 } 00215 00216 void clear() 00217 { 00218 url.clear(); 00219 encoded_hostname.clear(); 00220 proxyUrl.clear(); 00221 isKeepAlive = false; 00222 isPersistentProxyConnection = false; 00223 } 00224 00225 KUrl url; 00226 QString encoded_hostname; 00227 KUrl proxyUrl; 00228 bool isKeepAlive; 00229 bool isPersistentProxyConnection; 00230 }; 00231 00232 //---------------------- Re-implemented methods ---------------- 00233 virtual void setHost(const QString& host, quint16 port, const QString& user, 00234 const QString& pass); 00235 00236 virtual void slave_status(); 00237 00238 virtual void get( const KUrl& url ); 00239 virtual void put( const KUrl& url, int _mode, KIO::JobFlags flags ); 00240 00241 //----------------- Re-implemented methods for WebDAV ----------- 00242 virtual void listDir( const KUrl& url ); 00243 virtual void mkdir( const KUrl& url, int _permissions ); 00244 00245 virtual void rename( const KUrl& src, const KUrl& dest, KIO::JobFlags flags ); 00246 virtual void copy( const KUrl& src, const KUrl& dest, int _permissions, KIO::JobFlags flags ); 00247 virtual void del( const KUrl& url, bool _isfile ); 00248 00249 // ask the host whether it supports WebDAV & cache this info 00250 bool davHostOk(); 00251 00252 // send generic DAV request 00253 void davGeneric( const KUrl& url, KIO::HTTP_METHOD method, qint64 size = -1 ); 00254 00255 // Send requests to lock and unlock resources 00256 void davLock( const KUrl& url, const QString& scope, 00257 const QString& type, const QString& owner ); 00258 void davUnlock( const KUrl& url ); 00259 00260 // Calls httpClose() and finished() 00261 void davFinished(); 00262 00263 // Handle error conditions 00264 QString davError( int code = -1, const QString &url = QString() ); 00265 //---------------------------- End WebDAV ----------------------- 00266 00276 virtual void special( const QByteArray &data ); 00277 00278 virtual void mimetype( const KUrl& url); 00279 00280 virtual void stat( const KUrl& url ); 00281 00282 virtual void reparseConfiguration(); 00283 00287 virtual void closeConnection(); 00288 00289 void post( const KUrl& url, qint64 size = -1 ); 00290 void multiGet(const QByteArray &data); 00291 bool maybeSetRequestUrl(const KUrl &); 00292 00296 bool sendHttpError(); 00297 00301 bool sendErrorPageNotification(); 00302 00306 bool isOffline(); 00307 00308 protected Q_SLOTS: 00309 void slotData(const QByteArray &); 00310 void slotFilterError(const QString &text); 00311 void error(int errid, const QString &text); 00312 void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *); 00313 void saveProxyAuthenticationForSocket(); 00314 00315 protected: 00316 int readChunked(); 00317 int readLimited(); 00318 int readUnlimited(); 00319 00324 ssize_t write(const void *buf, size_t nbytes); 00325 using SlaveBase::write; 00326 00332 void addEncoding(const QString &, QStringList &); 00333 00334 quint16 defaultPort() const; 00335 00336 // The methods between here and sendQuery() are helpers for sendQuery(). 00337 00343 bool satisfyRequestFromCache(bool *cacheHasPage); 00344 QString formatRequestUri() const; 00348 QString authenticationHeader(); 00349 bool sendQuery(); 00350 00354 void httpClose(bool keepAlive); 00358 bool httpOpenConnection(); 00362 void httpCloseConnection(); 00366 bool httpShouldCloseConnection(); 00367 00368 void forwardHttpResponseHeader(bool forwardImmediately = true); 00369 00375 void fixupResponseMimetype(); 00381 void fixupResponseContentEncoding(); 00382 00383 bool readResponseHeader(); 00384 bool parseHeaderFromCache(); 00385 void parseContentDisposition(const QString &disposition); 00386 00387 bool sendBody(); 00388 bool sendCachedBody(); 00389 00390 // where dataInternal == true, the content is to be made available 00391 // to an internal function. 00392 bool readBody( bool dataInternal = false ); 00393 00397 void davSetRequest( const QByteArray& requestXML ); 00398 void davStatList( const KUrl& url, bool stat = true ); 00399 void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry ); 00400 void davParseActiveLocks( const QDomNodeList& activeLocks, 00401 uint& lockCount ); 00402 00406 long parseDateTime( const QString& input, const QString& type ); 00407 00411 int codeFromResponse( const QString& response ); 00412 00417 QString davProcessLocks(); 00418 00422 void addCookies( const QString &url, const QByteArray &cookieHeader); 00423 00427 QString findCookies( const QString &url); 00428 00429 void cacheParseResponseHeader(const HeaderTokenizer &tokenizer); 00430 00431 QString cacheFilePathFromUrl(const KUrl &url) const; 00432 bool cacheFileOpenRead(); 00433 bool cacheFileOpenWrite(); 00434 void cacheFileClose(); 00435 void sendCacheCleanerCommand(const QByteArray &command); 00436 00437 QByteArray cacheFileReadPayload(int maxLength); 00438 void cacheFileWritePayload(const QByteArray &d); 00439 void cacheFileWriteTextHeader(); 00443 bool cacheFileReadTextHeader1(const KUrl &desiredUrl); 00447 bool cacheFileReadTextHeader2(); 00448 void setCacheabilityMetadata(bool cachingAllowed); 00449 00458 void proceedUntilResponseContent( bool dataInternal = false ); 00459 00463 bool proceedUntilResponseHeader(); 00464 00468 void resetSessionSettings(); 00469 00473 void resetResponseParsing(); 00474 00481 void resetConnectionSettings(); 00482 00489 void cachePostData(const QByteArray&); 00490 00497 void clearPostDataBuffer(); 00498 00502 bool retrieveAllData(); 00503 00507 void saveAuthenticationData(); 00508 00512 bool handleAuthenticationHeader(const HeaderTokenizer* tokenizer); 00513 00514 protected: 00515 HTTPServerState m_server; 00516 HTTPRequest m_request; 00517 QList<HTTPRequest> m_requestQueue; 00518 00519 // Processing related 00520 KIO::filesize_t m_iSize; 00521 KIO::filesize_t m_iPostDataSize; 00522 KIO::filesize_t m_iBytesLeft; 00523 KIO::filesize_t m_iContentLeft; 00524 QByteArray m_receiveBuf; 00525 bool m_dataInternal; 00526 bool m_isChunked; 00527 00528 bool m_isBusy; 00529 bool m_isEOF; 00530 bool m_isEOD; 00531 00532 //--- Settings related to a single response only 00533 bool m_isRedirection; 00534 QStringList m_responseHeaders; 00535 00536 00537 // Language/Encoding related 00538 QStringList m_transferEncodings; 00539 QStringList m_contentEncodings; 00540 QString m_contentMD5; 00541 QString m_mimeType; // TODO QByteArray? 00542 00543 00544 //--- WebDAV 00545 // Data structure to hold data which will be passed to an internal func. 00546 QByteArray m_webDavDataBuf; 00547 QStringList m_davCapabilities; 00548 00549 bool m_davHostOk; 00550 bool m_davHostUnsupported; 00551 //---------- 00552 00553 // Mimetype determination 00554 bool m_cpMimeBuffer; 00555 QByteArray m_mimeTypeBuffer; 00556 00557 00558 // Holds the POST data so it won't get lost on if we 00559 // happend to get a 401/407 response when submitting 00560 // a form. 00561 QIODevice* m_POSTbuf; 00562 00563 // Cache related 00564 int m_maxCacheAge; 00565 long m_maxCacheSize; 00566 QString m_strCacheDir; 00567 QLocalSocket m_cacheCleanerConnection; 00568 00569 // Operation mode 00570 QByteArray m_protocol; 00571 00572 KAbstractHttpAuthentication *m_wwwAuth; 00573 KAbstractHttpAuthentication *m_proxyAuth; 00574 // For proxy auth when it's handled by the Qt/KDE socket classes 00575 QAuthenticator *m_socketProxyAuth; 00576 00577 // Indicates whether there was some error. 00578 int m_iError; 00579 // Whether we are loading an error page (we should close the connection afterwards) 00580 bool m_isLoadingErrorPage; 00581 00582 // Values that determine the remote connection timeouts. 00583 int m_remoteRespTimeout; 00584 00585 QByteArray m_unreadBuf; 00586 void clearUnreadBuffer(); 00587 void unread(char *buf, size_t size); 00588 size_t readBuffered(char *buf, size_t size, bool unlimited = true); 00589 bool readDelimitedText(char *buf, int *idx, int end, int numNewlines); 00590 }; 00591 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:37:22 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:37:22 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.