You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
578 lines
15 KiB
578 lines
15 KiB
/*
|
|
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
|