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 class QDomNodeList;
00049
00050 namespace KIO {
00051 class AuthInfo;
00052 }
00053
00054 class HTTPProtocol : public QObject, public KIO::TCPSlaveBase
00055 {
00056 Q_OBJECT
00057 public:
00058 HTTPProtocol( const QByteArray &protocol, const QByteArray &pool,
00059 const QByteArray &app );
00060 virtual ~HTTPProtocol();
00061
00063 enum HTTP_REV {HTTP_None, HTTP_Unknown, HTTP_10, HTTP_11, SHOUTCAST};
00064
00066 enum AUTH_SCHEME {AUTH_None, AUTH_Basic, AUTH_NTLM, AUTH_Digest, AUTH_Negotiate};
00067
00069 struct HTTPState
00070 {
00071 HTTPState ()
00072 {
00073 port = 0;
00074 }
00075
00076 QString hostname;
00077 QString encoded_hostname;
00078 short unsigned int port;
00079 QString user;
00080 QString passwd;
00081 };
00082
00084 struct DAVRequest
00085 {
00086 DAVRequest ()
00087 {
00088 overwrite = false;
00089 depth = 0;
00090 }
00091
00092 QString desturl;
00093 bool overwrite;
00094 int depth;
00095 };
00096
00097 struct CacheTag
00098 {
00099 CacheTag()
00100 {
00101 useCache = false;
00102 readFromCache = false;
00103 writeToCache = false;
00104 isExpired = false;
00105 bytesCached = 0;
00106 gzs = 0;
00107 expireDateOffset = 0;
00108 expireDate = 0;
00109 creationDate = 0;
00110 }
00111
00112 KIO::CacheControl policy;
00113 bool useCache;
00114 bool readFromCache;
00115 bool writeToCache;
00116 bool isExpired;
00117 long bytesCached;
00118 QString etag;
00119 QString file;
00120 gzFile gzs;
00121 QString lastModified;
00122 long expireDateOffset;
00123
00124 time_t expireDate;
00125 time_t creationDate;
00126 QString charset;
00127 };
00128
00130 struct HTTPRequest
00131 {
00132 HTTPRequest ()
00133 {
00134 method = KIO::HTTP_UNKNOWN;
00135 offset = 0;
00136 endoffset = 0;
00137 allowTransferCompression = false;
00138 disablePassDialog = false;
00139 doNotAuthenticate = false;
00140 preferErrorPage = false;
00141 useCookieJar = false;
00142 }
00143
00144 KUrl url;
00145 QString encoded_hostname;
00146
00147 bool isKeepAlive;
00148 int keepAliveTimeout;
00149
00150 KIO::HTTP_METHOD method;
00151 KIO::filesize_t offset;
00152 KIO::filesize_t endoffset;
00153 QString windowId;
00154
00155 QString referrer;
00156 QString charsets;
00157 QString languages;
00158 QString userAgent;
00159
00160 unsigned int responseCode;
00161 unsigned int prevResponseCode;
00162
00163 QString id;
00164 DAVRequest davData;
00165 KUrl proxyUrl;
00166 bool isPersistentProxyConnection;
00167 bool allowTransferCompression;
00168 bool disablePassDialog;
00169 bool doNotAuthenticate;
00170
00171 bool preferErrorPage;
00172
00173
00174 bool useCookieJar;
00175
00176 enum { CookiesAuto, CookiesManual, CookiesNone } cookieMode;
00177
00178 CacheTag cacheTag;
00179 };
00180
00181
00182
00183 struct PrevRequest
00184 {
00185 PrevRequest()
00186 {
00187 isKeepAlive = false;
00188 isPersistentProxyConnection = false;
00189 }
00190 void initFrom(const HTTPRequest &request)
00191 {
00192 url = request.url;
00193 isKeepAlive = request.isKeepAlive;
00194 proxyUrl = request.proxyUrl;
00195 isPersistentProxyConnection = request.isPersistentProxyConnection;
00196 }
00197 KUrl url;
00198 bool isKeepAlive;
00199 KUrl proxyUrl;
00200 bool isPersistentProxyConnection;
00201 };
00202
00203 PrevRequest m_prevRequest;
00204
00205 struct DigestAuthInfo
00206 {
00207 QByteArray nc;
00208 QByteArray qop;
00209 QByteArray realm;
00210 QByteArray nonce;
00211 QByteArray method;
00212 QByteArray cnonce;
00213 QByteArray username;
00214 QByteArray password;
00215 KUrl::List digestURIs;
00216 QByteArray algorithm;
00217 QByteArray entityBody;
00218 };
00219
00220
00221 virtual void setHost(const QString& host, quint16 port, const QString& user,
00222 const QString& pass);
00223
00224 virtual void slave_status();
00225
00226 virtual void get( const KUrl& url );
00227 virtual void put( const KUrl& url, int _mode, KIO::JobFlags flags );
00228
00229
00230 virtual void listDir( const KUrl& url );
00231 virtual void mkdir( const KUrl& url, int _permissions );
00232
00233 virtual void rename( const KUrl& src, const KUrl& dest, KIO::JobFlags flags );
00234 virtual void copy( const KUrl& src, const KUrl& dest, int _permissions, KIO::JobFlags flags );
00235 virtual void del( const KUrl& url, bool _isfile );
00236
00237
00238 bool davHostOk();
00239
00240
00241 void davGeneric( const KUrl& url, KIO::HTTP_METHOD method );
00242
00243
00244 void davLock( const KUrl& url, const QString& scope,
00245 const QString& type, const QString& owner );
00246 void davUnlock( const KUrl& url );
00247
00248
00249 void davFinished();
00250
00251
00252 QString davError( int code = -1, const QString &url = QString() );
00253
00254
00264 virtual void special( const QByteArray &data );
00265
00266 virtual void mimetype( const KUrl& url);
00267
00268 virtual void stat( const KUrl& url );
00269
00270 virtual void reparseConfiguration();
00271
00272 virtual void closeConnection();
00273
00274 void post( const KUrl& url );
00275 void multiGet(const QByteArray &data);
00276 bool maybeSetRequestUrl(const KUrl &);
00277 void cacheUpdate( const KUrl &url, bool nocache, time_t expireDate);
00278
00279 void httpError();
00280
00281 bool isOffline(const KUrl &url);
00282
00283 protected Q_SLOTS:
00284 void slotData(const QByteArray &);
00285 void error(int errid, const QString &text);
00286 void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *);
00287 void saveProxyAuthenticationForSocket();
00288
00289 protected:
00290 int readChunked();
00291 int readLimited();
00292 int readUnlimited();
00293
00298 ssize_t write(const void *buf, size_t nbytes);
00299
00305 void addEncoding(const QString &, QStringList &);
00306
00307 void configAuth(const QList<QByteArray> &headerLine, bool isProxyAuth);
00308
00309
00310
00311
00312
00313
00314 bool satisfyRequestFromCache(bool *success);
00315 QString formatRequestUri() const;
00316 QString wwwAuthenticationHeader();
00317 bool sendQuery();
00318
00319 void httpClose(bool keepAlive);
00320 bool httpOpenConnection();
00321 void httpCloseConnection();
00322 bool httpShouldCloseConnection();
00323
00324 void forwardHttpResponseHeader();
00325
00326
00327 void fixupResponseMimetype();
00328 bool readResponseHeader();
00329 bool readHeaderFromCache();
00330 void parseContentDisposition(const QString &disposition);
00331
00332 bool sendBody();
00333
00334
00335
00336 bool readBody( bool dataInternal = false );
00337
00341 void davSetRequest( const QByteArray& requestXML );
00342 void davStatList( const KUrl& url, bool stat = true );
00343 void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry );
00344 void davParseActiveLocks( const QDomNodeList& activeLocks,
00345 uint& lockCount );
00346
00350 long parseDateTime( const QString& input, const QString& type );
00351
00355 int codeFromResponse( const QString& response );
00356
00361 QString davProcessLocks();
00362
00366 void addCookies( const QString &url, const QByteArray &cookieHeader);
00367
00371 QString findCookies( const QString &url);
00372
00384 gzFile checkCacheEntry(bool readWrite = false);
00385
00391 void createCacheEntry(const QString &mimetype, time_t expireDate);
00392
00398 void writeCacheEntry( const char *buffer, int nbytes);
00399
00403 void closeCacheEntry();
00404
00408 void updateExpireDate(time_t expireDate, bool updateCreationDate=false);
00409
00413 void cleanCache();
00414
00420
00421
00422 void proceedUntilResponseContent( bool dataInternal = false );
00423
00427 bool proceedUntilResponseHeader();
00428
00432 void resetSessionSettings();
00433
00437 void resetResponseParsing();
00438
00445 void resetConnectionSettings();
00446
00451 QString proxyAuthenticationHeader();
00452
00456 bool getAuthorization();
00457
00461 void saveAuthorization(bool isForProxy);
00462
00466 QString createBasicAuth( bool isForProxy = false );
00467
00471 QString createDigestAuth( bool isForProxy = false );
00472
00476 QString createNTLMAuth( bool isForProxy = false );
00477
00481 QString createNegotiateAuth();
00482
00486 QByteArray gssError( int major_status, int minor_status );
00487
00491 void calculateResponse( DigestAuthInfo &info, QByteArray &Response );
00492
00496 bool retryPrompt();
00497
00501 void fillPromptInfo(KIO::AuthInfo *info);
00502
00503 protected:
00504 HTTPState m_state;
00505 HTTPRequest m_request;
00506 QList<HTTPRequest> m_requestQueue;
00507 quint16 m_defaultPort;
00508
00509
00510 KIO::filesize_t m_iSize;
00511 KIO::filesize_t m_iBytesLeft;
00512 KIO::filesize_t m_iContentLeft;
00513 QByteArray m_receiveBuf;
00514 bool m_dataInternal;
00515 bool m_isChunked;
00516
00517 bool m_isBusy;
00518 bool m_isEOF;
00519 bool m_isEOD;
00520
00521
00522 bool m_isFirstRequest;
00523
00524
00525 bool m_isRedirection;
00526 QStringList m_responseHeaders;
00527
00528
00529
00530 QStringList m_transferEncodings;
00531 QStringList m_contentEncodings;
00532 QString m_contentMD5;
00533 QString m_mimeType;
00534
00535
00536
00537
00538 QByteArray m_webDavDataBuf;
00539 QStringList m_davCapabilities;
00540
00541 bool m_davHostOk;
00542 bool m_davHostUnsupported;
00543
00544
00545
00546 bool m_cpMimeBuffer;
00547 QByteArray m_mimeTypeBuffer;
00548
00549
00550
00551
00552
00553 QByteArray m_POSTbuf;
00554
00555
00556 int m_maxCacheAge;
00557 long m_maxCacheSize;
00558 QString m_strCacheDir;
00559
00560
00561
00562
00563
00564 QByteArray m_protocol;
00565
00566
00567 bool m_isUnauthorized;
00568
00569
00570
00571
00572 struct AuthState
00573 {
00574 AUTH_SCHEME scheme;
00575 QString realm;
00576 QString authorization;
00577 int authCount;
00578 };
00579
00580 AuthState m_auth;
00581 AuthState m_proxyAuth;
00582
00583
00584 bool m_isError;
00585
00586
00587 int m_remoteRespTimeout;
00588
00589
00590 QByteArray m_unreadBuf;
00591 void clearUnreadBuffer();
00592 void unread(char *buf, size_t size);
00593 size_t readBuffered(char *buf, size_t size);
00594 bool readDelimitedText(char *buf, int *idx, int end, int numNewlines);
00595 };
00596 #endif