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 doNotAuthenticate = false; 00136 preferErrorPage = false; 00137 useCookieJar = false; 00138 } 00139 00140 QByteArray methodString() const; 00141 00142 KUrl url; 00143 QString encoded_hostname; //### can be calculated on-the-fly 00144 // Persistent connections 00145 bool isKeepAlive; 00146 int keepAliveTimeout; // Timeout in seconds. 00147 00148 KIO::HTTP_METHOD method; 00149 QString methodStringOverride; // Overrides method if non-empty. 00150 KIO::filesize_t offset; 00151 KIO::filesize_t endoffset; 00152 QString windowId; // Window Id this request is related to. 00153 // Header fields 00154 QString referrer; 00155 QString charsets; 00156 QString languages; 00157 QString userAgent; 00158 // Previous and current response codes 00159 unsigned int responseCode; 00160 unsigned int prevResponseCode; 00161 // Miscellaneous 00162 QString id; 00163 DAVRequest davData; 00164 KUrl redirectUrl; 00165 KUrl proxyUrl; 00166 QStringList proxyUrls; 00167 00168 bool isPersistentProxyConnection; 00169 bool allowTransferCompression; 00170 bool disablePassDialog; 00171 bool doNotAuthenticate; 00172 // Indicates whether an error page or error message is preferred. 00173 bool preferErrorPage; 00174 00175 // Use the cookie jar (or pass cookies to the application as metadata instead) 00176 bool useCookieJar; 00177 // Cookie flags 00178 enum { CookiesAuto, CookiesManual, CookiesNone } cookieMode; 00179 00180 CacheTag cacheTag; 00181 }; 00182 00184 struct HTTPServerState 00185 { 00186 HTTPServerState() 00187 { 00188 isKeepAlive = false; 00189 isPersistentProxyConnection = false; 00190 } 00191 00192 void initFrom(const HTTPRequest &request) 00193 { 00194 url = request.url; 00195 encoded_hostname = request.encoded_hostname; 00196 isKeepAlive = request.isKeepAlive; 00197 proxyUrl = request.proxyUrl; 00198 isPersistentProxyConnection = request.isPersistentProxyConnection; 00199 } 00200 00201 void updateCredentials(const HTTPRequest &request) 00202 { 00203 if (url.host() == request.url.host() && url.port() == request.url.port()) { 00204 url.setUserName(request.url.userName()); 00205 url.setPassword(request.url.password()); 00206 } 00207 if (proxyUrl.host() == request.proxyUrl.host() && 00208 proxyUrl.port() == request.proxyUrl.port()) { 00209 proxyUrl.setUserName(request.proxyUrl.userName()); 00210 proxyUrl.setPassword(request.proxyUrl.password()); 00211 } 00212 } 00213 00214 void clear() 00215 { 00216 url.clear(); 00217 encoded_hostname.clear(); 00218 proxyUrl.clear(); 00219 isKeepAlive = false; 00220 isPersistentProxyConnection = false; 00221 } 00222 00223 KUrl url; 00224 QString encoded_hostname; 00225 KUrl proxyUrl; 00226 bool isKeepAlive; 00227 bool isPersistentProxyConnection; 00228 }; 00229 00230 //---------------------- Re-implemented methods ---------------- 00231 virtual void setHost(const QString& host, quint16 port, const QString& user, 00232 const QString& pass); 00233 00234 virtual void slave_status(); 00235 00236 virtual void get( const KUrl& url ); 00237 virtual void put( const KUrl& url, int _mode, KIO::JobFlags flags ); 00238 00239 //----------------- Re-implemented methods for WebDAV ----------- 00240 virtual void listDir( const KUrl& url ); 00241 virtual void mkdir( const KUrl& url, int _permissions ); 00242 00243 virtual void rename( const KUrl& src, const KUrl& dest, KIO::JobFlags flags ); 00244 virtual void copy( const KUrl& src, const KUrl& dest, int _permissions, KIO::JobFlags flags ); 00245 virtual void del( const KUrl& url, bool _isfile ); 00246 00247 // ask the host whether it supports WebDAV & cache this info 00248 bool davHostOk(); 00249 00250 // send generic DAV request 00251 void davGeneric( const KUrl& url, KIO::HTTP_METHOD method, qint64 size = -1 ); 00252 00253 // Send requests to lock and unlock resources 00254 void davLock( const KUrl& url, const QString& scope, 00255 const QString& type, const QString& owner ); 00256 void davUnlock( const KUrl& url ); 00257 00258 // Calls httpClose() and finished() 00259 void davFinished(); 00260 00261 // Handle error conditions 00262 QString davError( int code = -1, const QString &url = QString() ); 00263 //---------------------------- End WebDAV ----------------------- 00264 00274 virtual void special( const QByteArray &data ); 00275 00276 virtual void mimetype( const KUrl& url); 00277 00278 virtual void stat( const KUrl& url ); 00279 00280 virtual void reparseConfiguration(); 00281 00285 virtual void closeConnection(); 00286 00287 void post( const KUrl& url, qint64 size = -1 ); 00288 void multiGet(const QByteArray &data); 00289 bool maybeSetRequestUrl(const KUrl &); 00290 00294 bool sendHttpError(); 00295 00299 bool sendErrorPageNotification(); 00300 00304 bool isOffline(); 00305 00306 protected Q_SLOTS: 00307 void slotData(const QByteArray &); 00308 void slotFilterError(const QString &text); 00309 void error(int errid, const QString &text); 00310 void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *); 00311 void saveProxyAuthenticationForSocket(); 00312 00313 protected: 00314 int readChunked(); 00315 int readLimited(); 00316 int readUnlimited(); 00317 00322 ssize_t write(const void *buf, size_t nbytes); 00323 using SlaveBase::write; 00324 00330 void addEncoding(const QString &, QStringList &); 00331 00332 quint16 defaultPort() const; 00333 00334 // The methods between here and sendQuery() are helpers for sendQuery(). 00335 00341 bool satisfyRequestFromCache(bool *cacheHasPage); 00342 QString formatRequestUri() const; 00346 QString authenticationHeader(); 00347 bool sendQuery(); 00348 00352 void httpClose(bool keepAlive); 00356 bool httpOpenConnection(); 00360 void httpCloseConnection(); 00364 bool httpShouldCloseConnection(); 00365 00366 void forwardHttpResponseHeader(bool forwardImmediately = true); 00367 00373 void fixupResponseMimetype(); 00379 void fixupResponseContentEncoding(); 00380 00381 bool readResponseHeader(); 00382 bool parseHeaderFromCache(); 00383 void parseContentDisposition(const QString &disposition); 00384 00385 bool sendBody(); 00386 bool sendCachedBody(); 00387 00388 // where dataInternal == true, the content is to be made available 00389 // to an internal function. 00390 bool readBody( bool dataInternal = false ); 00391 00395 void davSetRequest( const QByteArray& requestXML ); 00396 void davStatList( const KUrl& url, bool stat = true ); 00397 void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry ); 00398 void davParseActiveLocks( const QDomNodeList& activeLocks, 00399 uint& lockCount ); 00400 00404 long parseDateTime( const QString& input, const QString& type ); 00405 00409 int codeFromResponse( const QString& response ); 00410 00415 QString davProcessLocks(); 00416 00420 void addCookies( const QString &url, const QByteArray &cookieHeader); 00421 00425 QString findCookies( const QString &url); 00426 00427 void cacheParseResponseHeader(const HeaderTokenizer &tokenizer); 00428 00429 QString cacheFilePathFromUrl(const KUrl &url) const; 00430 bool cacheFileOpenRead(); 00431 bool cacheFileOpenWrite(); 00432 void cacheFileClose(); 00433 void sendCacheCleanerCommand(const QByteArray &command); 00434 00435 QByteArray cacheFileReadPayload(int maxLength); 00436 void cacheFileWritePayload(const QByteArray &d); 00437 void cacheFileWriteTextHeader(); 00441 bool cacheFileReadTextHeader1(const KUrl &desiredUrl); 00445 bool cacheFileReadTextHeader2(); 00446 void setCacheabilityMetadata(bool cachingAllowed); 00447 00456 void proceedUntilResponseContent( bool dataInternal = false ); 00457 00461 bool proceedUntilResponseHeader(); 00462 00466 void resetSessionSettings(); 00467 00471 void resetResponseParsing(); 00472 00479 void resetConnectionSettings(); 00480 00487 void cachePostData(const QByteArray&); 00488 00495 void clearPostDataBuffer(); 00496 00500 bool retrieveAllData(); 00501 00505 void saveAuthenticationData(); 00506 00510 bool handleAuthenticationHeader(const HeaderTokenizer* tokenizer); 00511 00512 protected: 00513 HTTPServerState m_server; 00514 HTTPRequest m_request; 00515 QList<HTTPRequest> m_requestQueue; 00516 00517 // Processing related 00518 KIO::filesize_t m_iSize; 00519 KIO::filesize_t m_iPostDataSize; 00520 KIO::filesize_t m_iBytesLeft; 00521 KIO::filesize_t m_iContentLeft; 00522 QByteArray m_receiveBuf; 00523 bool m_dataInternal; 00524 bool m_isChunked; 00525 00526 bool m_isBusy; 00527 bool m_isEOF; 00528 bool m_isEOD; 00529 00530 //--- Settings related to a single response only 00531 bool m_isRedirection; 00532 QStringList m_responseHeaders; 00533 00534 00535 // Language/Encoding related 00536 QStringList m_transferEncodings; 00537 QStringList m_contentEncodings; 00538 QString m_contentMD5; 00539 QString m_mimeType; // TODO QByteArray? 00540 00541 00542 //--- WebDAV 00543 // Data structure to hold data which will be passed to an internal func. 00544 QByteArray m_webDavDataBuf; 00545 QStringList m_davCapabilities; 00546 00547 bool m_davHostOk; 00548 bool m_davHostUnsupported; 00549 //---------- 00550 00551 // Mimetype determination 00552 bool m_cpMimeBuffer; 00553 QByteArray m_mimeTypeBuffer; 00554 00555 00556 // Holds the POST data so it won't get lost on if we 00557 // happend to get a 401/407 response when submitting 00558 // a form. 00559 QIODevice* m_POSTbuf; 00560 00561 // Cache related 00562 int m_maxCacheAge; 00563 long m_maxCacheSize; 00564 QString m_strCacheDir; 00565 QLocalSocket m_cacheCleanerConnection; 00566 00567 // Operation mode 00568 QByteArray m_protocol; 00569 00570 KAbstractHttpAuthentication *m_wwwAuth; 00571 KAbstractHttpAuthentication *m_proxyAuth; 00572 // For proxy auth when it's handled by the Qt/KDE socket classes 00573 QAuthenticator *m_socketProxyAuth; 00574 00575 // Indicates whether there was some error. 00576 int m_iError; 00577 // Whether we are loading an error page (we should close the connection afterwards) 00578 bool m_isLoadingErrorPage; 00579 00580 // Values that determine the remote connection timeouts. 00581 int m_remoteRespTimeout; 00582 00583 QByteArray m_unreadBuf; 00584 void clearUnreadBuffer(); 00585 void unread(char *buf, size_t size); 00586 size_t readBuffered(char *buf, size_t size, bool unlimited = true); 00587 bool readDelimitedText(char *buf, int *idx, int end, int numNewlines); 00588 }; 00589 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 18:44:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 18:44:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.