diff options
Diffstat (limited to 'kioslave/http/http.h')
-rw-r--r-- | kioslave/http/http.h | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/kioslave/http/http.h b/kioslave/http/http.h new file mode 100644 index 000000000..ea2e68a8a --- /dev/null +++ b/kioslave/http/http.h @@ -0,0 +1,577 @@ +/* + Copyright (C) 2000,2001 Dawit Alemayehu <adawit@kde.org> + Copyright (C) 2000,2001 Waldo Bastian <bastian@kde.org> + Copyright (C) 2000,2001 George Staikos <staikos@kde.org> + Copyright (C) 2001,2002 Hamish Rodda <rodda@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HTTP_H_ +#define HTTP_H_ + + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <stdio.h> +#include <time.h> + +#include <qptrlist.h> +#include <qstrlist.h> +#include <qstringlist.h> + +#include <kurl.h> +#include "kio/tcpslavebase.h" +#include "kio/http.h" + +class DCOPClient; +class QDomElement; +class QDomNodeList; + +namespace KIO { + class AuthInfo; +} + +class HTTPProtocol : public QObject, public KIO::TCPSlaveBase +{ + Q_OBJECT +public: + HTTPProtocol( const QCString &protocol, const QCString &pool, + const QCString &app ); + virtual ~HTTPProtocol(); + + /** HTTP version **/ + enum HTTP_REV {HTTP_None, HTTP_Unknown, HTTP_10, HTTP_11, SHOUTCAST}; + + /** Authorization method used **/ + enum HTTP_AUTH {AUTH_None, AUTH_Basic, AUTH_NTLM, AUTH_Digest, AUTH_Negotiate}; + + /** HTTP / DAV method **/ + // Removed to interfaces/kio/http.h + //enum HTTP_METHOD {HTTP_GET, HTTP_PUT, HTTP_POST, HTTP_HEAD, HTTP_DELETE, + // HTTP_OPTIONS, DAV_PROPFIND, DAV_PROPPATCH, DAV_MKCOL, + // DAV_COPY, DAV_MOVE, DAV_LOCK, DAV_UNLOCK, DAV_SEARCH }; + + /** State of the current Connection **/ + struct HTTPState + { + HTTPState () + { + port = 0; + doProxy = false; + } + + QString hostname; + QString encoded_hostname; + short unsigned int port; + QString user; + QString passwd; + bool doProxy; + }; + + /** DAV-specific request elements for the current connection **/ + struct DAVRequest + { + DAVRequest () + { + overwrite = false; + depth = 0; + } + + QString desturl; + bool overwrite; + int depth; + }; + + /** The request for the current connection **/ + struct HTTPRequest + { + HTTPRequest () + { + port = 0; + method = KIO::HTTP_UNKNOWN; + offset = 0; + doProxy = false; + allowCompressedPage = false; + disablePassDlg = false; + bNoAuth = false; + bUseCache = false; + bCachedRead = false; + bCachedWrite = false; + fcache = 0; + bMustRevalidate = false; + cacheExpireDateOffset = 0; + bErrorPage = false; + bUseCookiejar = false; + expireDate = 0; + creationDate = 0; + } + + QString hostname; + QString encoded_hostname; + short unsigned int port; + QString user; + QString passwd; + QString path; + QString query; + KIO::HTTP_METHOD method; + KIO::CacheControl cache; + KIO::filesize_t offset; + bool doProxy; + KURL url; + QString window; // Window Id this request is related to. + QString referrer; + QString charsets; + QString languages; + bool allowCompressedPage; + bool disablePassDlg; + QString userAgent; + QString id; + DAVRequest davData; + + bool bNoAuth; // Do not authenticate + + // Cache related + QString cef; // Cache Entry File belonging to this URL. + bool bUseCache; // Whether the cache is active + bool bCachedRead; // Whether the file is to be read from m_fcache. + bool bCachedWrite; // Whether the file is to be written to m_fcache. + FILE* fcache; // File stream of a cache entry + QString etag; // ETag header. + QString lastModified; // Last modified. + bool bMustRevalidate; // Cache entry is expired. + long cacheExpireDateOffset; // Position in the cache entry where the + // 16 byte expire date is stored. + time_t expireDate; // Date when the cache entry will expire + time_t creationDate; // Date when the cache entry was created + QString strCharset; // Charset + + // Indicates whether an error-page or error-msg should is preferred. + bool bErrorPage; + + // Cookie flags + bool bUseCookiejar; + enum { CookiesAuto, CookiesManual, CookiesNone } cookieMode; + }; + + struct DigestAuthInfo + { + QCString nc; + QCString qop; + QCString realm; + QCString nonce; + QCString method; + QCString cnonce; + QCString username; + QCString password; + QStrList digestURI; + QCString algorithm; + QCString entityBody; + }; + +//---------------------- Re-implemented methods ---------------- + virtual void setHost(const QString& host, int port, const QString& user, + const QString& pass); + + virtual void slave_status(); + + virtual void get( const KURL& url ); + virtual void put( const KURL& url, int permissions, bool overwrite, + bool resume ); + +//----------------- Re-implemented methods for WebDAV ----------- + virtual void listDir( const KURL& url ); + virtual void mkdir( const KURL& url, int permissions ); + + virtual void rename( const KURL& src, const KURL& dest, bool overwrite ); + virtual void copy( const KURL& src, const KURL& dest, int permissions, bool overwrite ); + virtual void del( const KURL& url, bool isfile ); + + // ask the host whether it supports WebDAV & cache this info + bool davHostOk(); + + // send generic DAV request + void davGeneric( const KURL& url, KIO::HTTP_METHOD method ); + + // Send requests to lock and unlock resources + void davLock( const KURL& url, const QString& scope, + const QString& type, const QString& owner ); + void davUnlock( const KURL& url ); + + // Calls httpClose() and finished() + void davFinished(); + + // Handle error conditions + QString davError( int code = -1, QString url = QString::null ); +//---------------------------- End WebDAV ----------------------- + + /** + * Special commands supported by this slave : + * 1 - HTTP POST + * 2 - Cache has been updated + * 3 - SSL Certificate Cache has been updated + * 4 - HTTP multi get + * 5 - DAV LOCK (see + * 6 - DAV UNLOCK README.webdav) + */ + virtual void special( const QByteArray &data ); + + virtual void mimetype( const KURL& url); + + virtual void stat( const KURL& url ); + + virtual void reparseConfiguration(); + + virtual void closeConnection(); // Forced close of connection + + void post( const KURL& url ); + void multiGet(const QByteArray &data); + bool checkRequestURL( const KURL& ); + void cacheUpdate( const KURL &url, bool nocache, time_t expireDate); + + void httpError(); // Generate error message based on response code + + bool isOffline(const KURL &url); // Check network status + +protected slots: + void slotData(const QByteArray &); + void error( int _errid, const QString &_text ); + +protected: + int readChunked(); // Read a chunk + int readLimited(); // Read maximum m_iSize bytes. + int readUnlimited(); // Read as much as possible. + + /** + * A "smart" wrapper around write that will use SSL_write or + * write(2) depending on whether you've got an SSL connection or not. + * The only shortcomming is that it uses the "global" file handles and + * soforth. So you can't really use this on individual files/sockets. + */ + ssize_t write(const void *buf, size_t nbytes); + + /** + * Another "smart" wrapper, this time around read that will + * use SSL_read or read(2) depending on whether you've got an + * SSL connection or not. + */ + ssize_t read (void *b, size_t nbytes); + + char *gets (char *str, int size); + + void setRewindMarker(); + void rewind(); + + /** + * Add an encoding on to the appropriate stack this + * is nececesary because transfer encodings and + * content encodings must be handled separately. + */ + void addEncoding(QString, QStringList &); + + void configAuth( char *, bool ); + + bool httpOpen(); // Open transfer + void httpClose(bool keepAlive); // Close transfer + + bool httpOpenConnection(); // Open connection + void httpCloseConnection(); // Close connection + void httpCheckConnection(); // Check whether to keep connection. + + void forwardHttpResponseHeader(); + + bool readHeader(); + + bool sendBody(); + + // where dataInternal == true, the content is to be made available + // to an internal function. + bool readBody( bool dataInternal = false ); + + /** + * Performs a WebDAV stat or list + */ + void davSetRequest( const QCString& requestXML ); + void davStatList( const KURL& url, bool stat = true ); + void davParsePropstats( const QDomNodeList& propstats, KIO::UDSEntry& entry ); + void davParseActiveLocks( const QDomNodeList& activeLocks, + uint& lockCount ); + + /** + * Parses a date & time string + */ + long parseDateTime( const QString& input, const QString& type ); + + /** + * Returns the error code from a "HTTP/1.1 code Code Name" string + */ + int codeFromResponse( const QString& response ); + + /** + * Extracts locks from metadata + * Returns the appropriate If: header + */ + QString davProcessLocks(); + + /** + * Send a cookie to the cookiejar + */ + void addCookies( const QString &url, const QCString &cookieHeader); + + /** + * Look for cookies in the cookiejar + */ + QString findCookies( const QString &url); + + /** + * Do a cache lookup for the current url. (m_state.url) + * + * @param readWrite If true, file is opened read/write. + * If false, file is opened read-only. + * + * @return a file stream open for reading and at the start of + * the header section when the Cache entry exists and is valid. + * 0 if no cache entry could be found, or if the entry is not + * valid (any more). + */ + FILE *checkCacheEntry(bool readWrite = false); + + /** + * Create a cache entry for the current url. (m_state.url) + * + * Set the contents type of the cache entry to 'mimetype'. + */ + void createCacheEntry(const QString &mimetype, time_t expireDate); + + /** + * Write data to cache. + * + * Write 'nbytes' from 'buffer' to the Cache Entry File + */ + void writeCacheEntry( const char *buffer, int nbytes); + + /** + * Close cache entry + */ + void closeCacheEntry(); + + /** + * Update expire time of current cache entry. + */ + void updateExpireDate(time_t expireDate, bool updateCreationDate=false); + + /** + * Quick check whether the cache needs cleaning. + */ + void cleanCache(); + + /** + * Performs a GET HTTP request. + */ + // where dataInternal == true, the content is to be made available + // to an internal function. + void retrieveContent( bool dataInternal = false ); + + /** + * Performs a HEAD HTTP request. + */ + bool retrieveHeader(bool close_connection = true); + + /** + * Resets any per session settings. + */ + void resetSessionSettings(); + + /** + * Resets settings related to parsing a response. + */ + void resetResponseSettings(); + + /** + * Resets any per connection settings. These are different from + * per-session settings in that they must be invalidates every time + * a request is made, e.g. a retry to re-send the header to the + * server, as compared to only when a new request arrives. + */ + void resetConnectionSettings(); + + /** + * Returns any pre-cached proxy authentication info + * info in HTTP header format. + */ + QString proxyAuthenticationHeader(); + + /** + * Retrieves authorization info from cache or user. + */ + bool getAuthorization(); + + /** + * Saves valid authorization info in the cache daemon. + */ + void saveAuthorization(); + + /** + * Creates the entity-header for Basic authentication. + */ + QString createBasicAuth( bool isForProxy = false ); + + /** + * Creates the entity-header for Digest authentication. + */ + QString createDigestAuth( bool isForProxy = false ); + + /** + * Creates the entity-header for NTLM authentication. + */ + QString createNTLMAuth( bool isForProxy = false ); + + /** + * Creates the entity-header for Negotiate authentication. + */ + QString createNegotiateAuth(); + + /** + * create GSS error string + */ + QCString gssError( int major_status, int minor_status ); + + /** + * Calcualtes the message digest response based on RFC 2617. + */ + void calculateResponse( DigestAuthInfo &info, QCString &Response ); + + /** + * Prompts the user for authorization retry. + */ + bool retryPrompt(); + + /** + * Creates authorization prompt info. + */ + void promptInfo( KIO::AuthInfo& info ); + +protected: + HTTPState m_state; + HTTPRequest m_request; + QPtrList<HTTPRequest> m_requestQueue; + + bool m_bBusy; // Busy handling request queue. + bool m_bEOF; + bool m_bEOD; + +//--- Settings related to a single response only + QStringList m_responseHeader; // All headers + KURL m_redirectLocation; + bool m_bRedirect; // Indicates current request is a redirection + + // Processing related + bool m_bChunked; // Chunked tranfer encoding + KIO::filesize_t m_iSize; // Expected size of message + KIO::filesize_t m_iBytesLeft; // # of bytes left to receive in this message. + KIO::filesize_t m_iContentLeft; // # of content bytes left + QByteArray m_bufReceive; // Receive buffer + bool m_dataInternal; // Data is for internal consumption + char m_lineBuf[1024]; + char m_rewindBuf[8192]; + size_t m_rewindCount; + char *m_linePtr; + size_t m_lineCount; + char *m_lineBufUnget; + char *m_linePtrUnget; + size_t m_lineCountUnget; + + // Mimetype determination + bool m_cpMimeBuffer; + QByteArray m_mimeTypeBuffer; + + // Language/Encoding related + QStringList m_qTransferEncodings; + QStringList m_qContentEncodings; + QString m_sContentMD5; + QString m_strMimeType; + + +//--- WebDAV + // Data structure to hold data which will be passed to an internal func. + QByteArray m_bufWebDavData; + QStringList m_davCapabilities; + + bool m_davHostOk; + bool m_davHostUnsupported; +//---------- + + // Holds the POST data so it won't get lost on if we + // happend to get a 401/407 response when submitting, + // a form. + QByteArray m_bufPOST; + + // Cache related + int m_maxCacheAge; // Maximum age of a cache entry. + long m_maxCacheSize; // Maximum cache size in Kb. + QString m_strCacheDir; // Location of the cache. + + + +//--- Proxy related members + bool m_bUseProxy; + bool m_bNeedTunnel; // Whether we need to make a SSL tunnel + bool m_bIsTunneled; // Whether we have an active SSL tunnel + bool m_bProxyAuthValid; + int m_iProxyPort; + KURL m_proxyURL; + QString m_strProxyRealm; + + // Operation mode + QCString m_protocol; + + // Authentication + QString m_strRealm; + QString m_strAuthorization; + QString m_strProxyAuthorization; + HTTP_AUTH Authentication; + HTTP_AUTH ProxyAuthentication; + bool m_bUnauthorized; + short unsigned int m_iProxyAuthCount; + short unsigned int m_iWWWAuthCount; + + // First request on a connection + bool m_bFirstRequest; + + // Persistent connections + bool m_bKeepAlive; + int m_keepAliveTimeout; // Timeout in seconds. + + // Persistent proxy connections + bool m_bPersistentProxyConnection; + + + // Indicates whether there was some connection error. + bool m_bError; + + // Previous and current response codes + unsigned int m_responseCode; + unsigned int m_prevResponseCode; + + // Values that determine the remote connection timeouts. + int m_proxyConnTimeout; + int m_remoteConnTimeout; + int m_remoteRespTimeout; + + int m_pid; +}; +#endif |