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 void setLoadingErrorPage();
00263
00264 bool isOffline(const KUrl &url);
00265
00266 protected Q_SLOTS:
00267 void slotData(const QByteArray &);
00268 void slotFilterError(const QString &text);
00269 void error(int errid, const QString &text);
00270 void proxyAuthenticationForSocket(const QNetworkProxy &, QAuthenticator *);
00271 void saveProxyAuthenticationForSocket();
00272
00273 protected:
00274 int readChunked();
00275 int readLimited();
00276 int readUnlimited();
00277
00282 ssize_t write(const void *buf, size_t nbytes);
00283
00289 void addEncoding(const QString &, QStringList &);
00290
00291 quint16 defaultPort() const;
00292
00293
00294
00295
00296
00297 bool satisfyRequestFromCache(bool *success);
00298 QString formatRequestUri() const;
00299
00300 QString authenticationHeader();
00301 bool sendQuery();
00302
00303 void httpClose(bool keepAlive);
00304 bool httpOpenConnection();
00305 void httpCloseConnection();
00306 bool httpShouldCloseConnection();
00307
00308 void forwardHttpResponseHeader();
00309
00310
00311 void fixupResponseMimetype();
00312 bool readResponseHeader();
00313 bool readHeaderFromCache();
00314 void parseContentDisposition(const QString &disposition);
00315
00316 bool sendBody();
00317
00318
00319
00320 bool readBody( bool dataInternal = false );
00321
00325 void davSetRequest( const QByteArray& requestXML );
00326 void davStatList( const KUrl& url, bool stat = true );
00327 void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry );
00328 void davParseActiveLocks( const QDomNodeList& activeLocks,
00329 uint& lockCount );
00330
00334 long parseDateTime( const QString& input, const QString& type );
00335
00339 int codeFromResponse( const QString& response );
00340
00345 QString davProcessLocks();
00346
00350 void addCookies( const QString &url, const QByteArray &cookieHeader);
00351
00355 QString findCookies( const QString &url);
00356
00368 gzFile checkCacheEntry(bool readWrite = false);
00369
00375 void createCacheEntry(const QString &mimetype, time_t expireDate);
00376
00382 void writeCacheEntry( const char *buffer, int nbytes);
00383
00387 void closeCacheEntry();
00388
00392 void updateExpireDate(time_t expireDate, bool updateCreationDate=false);
00393
00397 void cleanCache();
00398
00404
00405
00406 void proceedUntilResponseContent( bool dataInternal = false );
00407
00411 bool proceedUntilResponseHeader();
00412
00416 void resetSessionSettings();
00417
00421 void resetResponseParsing();
00422
00429 void resetConnectionSettings();
00430
00434 QString createNegotiateAuth();
00435
00439 QByteArray gssError( int major_status, int minor_status );
00440
00444 void fillPromptInfo(KIO::AuthInfo *info);
00445
00446 protected:
00447 HTTPServerState m_server;
00448 HTTPRequest m_request;
00449 QList<HTTPRequest> m_requestQueue;
00450
00451
00452 KIO::filesize_t m_iSize;
00453 KIO::filesize_t m_iBytesLeft;
00454 KIO::filesize_t m_iContentLeft;
00455 QByteArray m_receiveBuf;
00456 bool m_dataInternal;
00457 bool m_isChunked;
00458
00459 bool m_isBusy;
00460 bool m_isEOF;
00461 bool m_isEOD;
00462
00463
00464 bool m_isFirstRequest;
00465
00466
00467 bool m_isRedirection;
00468 QStringList m_responseHeaders;
00469
00470
00471
00472 QStringList m_transferEncodings;
00473 QStringList m_contentEncodings;
00474 QString m_contentMD5;
00475 QString m_mimeType;
00476
00477
00478
00479
00480 QByteArray m_webDavDataBuf;
00481 QStringList m_davCapabilities;
00482
00483 bool m_davHostOk;
00484 bool m_davHostUnsupported;
00485
00486
00487
00488 bool m_cpMimeBuffer;
00489 QByteArray m_mimeTypeBuffer;
00490
00491
00492
00493
00494
00495 QByteArray m_POSTbuf;
00496
00497
00498 int m_maxCacheAge;
00499 long m_maxCacheSize;
00500 QString m_strCacheDir;
00501
00502
00503 QByteArray m_protocol;
00504
00505 KAbstractHttpAuthentication *m_wwwAuth;
00506 KAbstractHttpAuthentication *m_proxyAuth;
00507
00508 QAuthenticator *m_socketProxyAuth;
00509
00510
00511 bool m_isError;
00512
00513 bool m_isLoadingErrorPage;
00514
00515
00516 int m_remoteRespTimeout;
00517
00518 QByteArray m_unreadBuf;
00519 void clearUnreadBuffer();
00520 void unread(char *buf, size_t size);
00521 size_t readBuffered(char *buf, size_t size);
00522 bool readDelimitedText(char *buf, int *idx, int end, int numNewlines);
00523 };
00524 #endif