00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 <zlib.h>
00035 #include <time.h>
00036
00037 #include <QtCore/QByteRef>
00038 #include <QtCore/QList>
00039 #include <QtCore/QStringList>
00040
00041 #include <kurl.h>
00042 #include "kio/tcpslavebase.h"
00043 #include "kio/http.h"
00044
00045
00046 #include "parsinghelpers.h"
00047
00048 #include "httpauthentication.h"
00049
00050 class QDomNodeList;
00051
00052 namespace KIO {
00053 class AuthInfo;
00054 }
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 struct CacheTag
00085 {
00086 CacheTag()
00087 {
00088 useCache = false;
00089 readFromCache = false;
00090 writeToCache = false;
00091 isExpired = false;
00092 bytesCached = 0;
00093 gzs = 0;
00094 expireDateOffset = 0;
00095 expireDate = 0;
00096 creationDate = 0;
00097 }
00098
00099 KIO::CacheControl policy;
00100 bool useCache;
00101 bool readFromCache;
00102 bool writeToCache;
00103 bool isExpired;
00104 long bytesCached;
00105 QString etag;
00106 QString file;
00107 gzFile gzs;
00108 QString lastModified;
00109 long expireDateOffset;
00110
00111 time_t expireDate;
00112 time_t creationDate;
00113 QString charset;
00114 };
00115
00117 struct HTTPRequest
00118 {
00119 HTTPRequest ()
00120 {
00121 method = KIO::HTTP_UNKNOWN;
00122 offset = 0;
00123 endoffset = 0;
00124 allowTransferCompression = false;
00125 disablePassDialog = false;
00126 doNotAuthenticate = false;
00127 preferErrorPage = false;
00128 useCookieJar = false;
00129 }
00130
00131 KUrl url;
00132 QString encoded_hostname;
00133
00134 bool isKeepAlive;
00135 int keepAliveTimeout;
00136
00137 KIO::HTTP_METHOD method;
00138 KIO::filesize_t offset;
00139 KIO::filesize_t endoffset;
00140 QString windowId;
00141
00142 QString referrer;
00143 QString charsets;
00144 QString languages;
00145 QString userAgent;
00146
00147 unsigned int responseCode;
00148 unsigned int prevResponseCode;
00149
00150 QString id;
00151 DAVRequest davData;
00152 KUrl proxyUrl;
00153 bool isPersistentProxyConnection;
00154 bool allowTransferCompression;
00155 bool disablePassDialog;
00156 bool doNotAuthenticate;
00157
00158 bool preferErrorPage;
00159
00160
00161 bool useCookieJar;
00162
00163 enum { CookiesAuto, CookiesManual, CookiesNone } cookieMode;
00164
00165 CacheTag cacheTag;
00166 };
00167
00169 struct HTTPServerState
00170 {
00171 HTTPServerState()
00172 {
00173 isKeepAlive = false;
00174 isPersistentProxyConnection = false;
00175 }
00176
00177 void initFrom(const HTTPRequest &request)
00178 {
00179 url = request.url;
00180 encoded_hostname = request.encoded_hostname;
00181 isKeepAlive = request.isKeepAlive;
00182 proxyUrl = request.proxyUrl;
00183 isPersistentProxyConnection = request.isPersistentProxyConnection;
00184 }
00185
00186 void clear()
00187 {
00188 url.clear();
00189 encoded_hostname.clear();
00190 proxyUrl.clear();
00191 isKeepAlive = false;
00192 isPersistentProxyConnection = false;
00193 }
00194
00195 KUrl url;
00196 QString encoded_hostname;
00197 KUrl proxyUrl;
00198 bool isKeepAlive;
00199 bool isPersistentProxyConnection;
00200 };
00201
00202
00203 virtual void setHost(const QString& host, quint16 port, const QString& user,
00204 const QString& pass);
00205
00206 virtual void slave_status();
00207
00208 virtual void get( const KUrl& url );
00209 virtual void put( const KUrl& url, int _mode, KIO::JobFlags flags );
00210
00211
00212 virtual void listDir( const KUrl& url );
00213 virtual void mkdir( const KUrl& url, int _permissions );
00214
00215 virtual void rename( const KUrl& src, const KUrl& dest, KIO::JobFlags flags );
00216 virtual void copy( const KUrl& src, const KUrl& dest, int _permissions, KIO::JobFlags flags );
00217 virtual void del( const KUrl& url, bool _isfile );
00218
00219
00220 bool davHostOk();
00221
00222
00223 void davGeneric( const KUrl& url, KIO::HTTP_METHOD method );
00224
00225
00226 void davLock( const KUrl& url, const QString& scope,
00227 const QString& type, const QString& owner );
00228 void davUnlock( const KUrl& url );
00229
00230
00231 void davFinished();
00232
00233
00234 QString davError( int code = -1, const QString &url = QString() );
00235
00236
00246 virtual void special( const QByteArray &data );
00247
00248 virtual void mimetype( const KUrl& url);
00249
00250 virtual void stat( const KUrl& url );
00251
00252 virtual void reparseConfiguration();
00253
00254 virtual void closeConnection();
00255
00256 void post( const KUrl& url );
00257 void multiGet(const QByteArray &data);
00258 bool maybeSetRequestUrl(const KUrl &);
00259 void cacheUpdate( const KUrl &url, bool nocache, time_t expireDate);
00260
00261 void httpError();
00262
00263 bool isOffline(const KUrl &url);
00264
00265 protected Q_SLOTS:
00266 void slotData(const QByteArray &);
00267 void error(int errid, const QString &text);
00268 void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *);
00269 void saveProxyAuthenticationForSocket();
00270
00271 protected:
00272 int readChunked();
00273 int readLimited();
00274 int readUnlimited();
00275
00280 ssize_t write(const void *buf, size_t nbytes);
00281
00287 void addEncoding(const QString &, QStringList &);
00288
00289
00290
00291
00292
00293
00294
00295 bool satisfyRequestFromCache(bool *success);
00296 QString formatRequestUri() const;
00297
00298 QString authenticationHeader();
00299 bool sendQuery();
00300
00301 void httpClose(bool keepAlive);
00302 bool httpOpenConnection();
00303 void httpCloseConnection();
00304 bool httpShouldCloseConnection();
00305
00306 void forwardHttpResponseHeader();
00307
00308
00309 void fixupResponseMimetype();
00310 bool readResponseHeader();
00311 bool readHeaderFromCache();
00312 void parseContentDisposition(const QString &disposition);
00313
00314 bool sendBody();
00315
00316
00317
00318 bool readBody( bool dataInternal = false );
00319
00323 void davSetRequest( const QByteArray& requestXML );
00324 void davStatList( const KUrl& url, bool stat = true );
00325 void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry );
00326 void davParseActiveLocks( const QDomNodeList& activeLocks,
00327 uint& lockCount );
00328
00332 long parseDateTime( const QString& input, const QString& type );
00333
00337 int codeFromResponse( const QString& response );
00338
00343 QString davProcessLocks();
00344
00348 void addCookies( const QString &url, const QByteArray &cookieHeader);
00349
00353 QString findCookies( const QString &url);
00354
00366 gzFile checkCacheEntry(bool readWrite = false);
00367
00373 void createCacheEntry(const QString &mimetype, time_t expireDate);
00374
00380 void writeCacheEntry( const char *buffer, int nbytes);
00381
00385 void closeCacheEntry();
00386
00390 void updateExpireDate(time_t expireDate, bool updateCreationDate=false);
00391
00395 void cleanCache();
00396
00402
00403
00404 void proceedUntilResponseContent( bool dataInternal = false );
00405
00409 bool proceedUntilResponseHeader();
00410
00414 void resetSessionSettings();
00415
00419 void resetResponseParsing();
00420
00427 void resetConnectionSettings();
00428
00432 QString createNegotiateAuth();
00433
00437 QByteArray gssError( int major_status, int minor_status );
00438
00442 void fillPromptInfo(KIO::AuthInfo *info);
00443
00444 protected:
00445 HTTPServerState m_server;
00446 HTTPRequest m_request;
00447 QList<HTTPRequest> m_requestQueue;
00448 quint16 m_defaultPort;
00449
00450
00451 KIO::filesize_t m_iSize;
00452 KIO::filesize_t m_iBytesLeft;
00453 KIO::filesize_t m_iContentLeft;
00454 QByteArray m_receiveBuf;
00455 bool m_dataInternal;
00456 bool m_isChunked;
00457
00458 bool m_isBusy;
00459 bool m_isEOF;
00460 bool m_isEOD;
00461
00462
00463 bool m_isFirstRequest;
00464
00465
00466 bool m_isRedirection;
00467 QStringList m_responseHeaders;
00468
00469
00470
00471 QStringList m_transferEncodings;
00472 QStringList m_contentEncodings;
00473 QString m_contentMD5;
00474 QString m_mimeType;
00475
00476
00477
00478
00479 QByteArray m_webDavDataBuf;
00480 QStringList m_davCapabilities;
00481
00482 bool m_davHostOk;
00483 bool m_davHostUnsupported;
00484
00485
00486
00487 bool m_cpMimeBuffer;
00488 QByteArray m_mimeTypeBuffer;
00489
00490
00491
00492
00493
00494 QByteArray m_POSTbuf;
00495
00496
00497 int m_maxCacheAge;
00498 long m_maxCacheSize;
00499 QString m_strCacheDir;
00500
00501
00502
00503
00504
00505 QByteArray m_protocol;
00506
00507
00508
00509 #if 0
00510 struct AuthState
00511 {
00512 AUTH_SCHEME scheme;
00513 QString realm;
00514 QString authorization;
00515 int authCount;
00516 };
00517 #endif
00518
00519 KAbstractHttpAuthentication *m_wwwAuth;
00520 KAbstractHttpAuthentication *m_proxyAuth;
00521
00522 QAuthenticator *m_socketProxyAuth;
00523
00524
00525 bool m_isError;
00526
00527
00528 int m_remoteRespTimeout;
00529
00530
00531 QByteArray m_unreadBuf;
00532 void clearUnreadBuffer();
00533 void unread(char *buf, size_t size);
00534 size_t readBuffered(char *buf, size_t size);
00535 bool readDelimitedText(char *buf, int *idx, int end, int numNewlines);
00536 };
00537 #endif