//
// HtHTTP.h
//
// HtHTTP: Class for HTTP messaging (derived from Transport)
//
// Gabriele Bartolini - Prato - Italia
// started: 03.05.1999
//
// ////////////////////////////////////////////////////////////
//
// The HtHTTP class should provide (as I hope) an interface for
// retrieving document on the Web. It derives from Transport class.
//
// It should be HTTP/1.1 compatible.
//
// It also let us take advantage of persitent connections use,
// and optimize request times (specially if directed to the same
// server).
//
// HtHTTP use another class to store the response returned by the
// remote server.
//
// Now cookies management is enabled.
//
///////
//
// Part of the ht://Dig package
// Copyright (c) 1995-2004 The ht://Dig Group
// For copyright details, see the file COPYING in your distribution
// or the GNU Library General Public License (LGPL) version 2 or later
//
//
// $Id: HtHTTP.h,v 1.15 2004/05/28 13:15:23 lha Exp $
//
#ifndef _HTHTTP_H
#define _HTHTTP_H
#ifdef HAVE_CONFIG_H
#include "htconfig.h"
#endif /* HAVE_CONFIG_H */
#include "Transport.h"
// Cookie support
#include "HtCookie.h"
#include "HtCookieJar.h"
#include "URL.h"
#include "htString.h"
// for HtHTTP::ShowStatistics#ifdef HAVE_STD
#ifdef HAVE_STD
#include
#ifdef HAVE_NAMESPACES
using namespace std;
#endif
#else
#include
#endif /* HAVE_STD */
// In advance declarations
class HtHTTP;
class HtHTTP_Response : public Transport_Response
{
friend class HtHTTP; // declaring friendship
public:
///////
// Construction / Destruction
///////
HtHTTP_Response();
~HtHTTP_Response();
///////
// Interface
///////
// Reset
void Reset();
// Get the HTTP version
const String &GetVersion() const { return _version; }
// Get the Transfer-encoding
const String &GetTransferEncoding() const
{ return _transfer_encoding; }
// Get server info
const String &GetServer() const { return _server; }
// Get Connection info
const String &GetConnectionInfo() const { return _hdrconnection; }
// Get Content language
const String &GetContentLanguage() const { return _content_language; }
protected:
// Status line information
String _version; // HTTP Version
// Other header information
String _transfer_encoding; // Transfer-encoding
String _server; // Server string returned
String _hdrconnection; // Connection header
String _content_language; // Content-language
};
class HtHTTP : public Transport
{
private:
HtHTTP() {} // Declared private - avoids default constructor to be created
// in some cases by the compiler.
public:
///////
// Construction/Destruction
///////
HtHTTP(Connection&);
virtual ~HtHTTP() = 0;
// Information about the method to be used in the request
enum Request_Method
{
Method_GET,
Method_HEAD
};
///////
// Sends an HTTP request message
///////
// manages a Transport request (method inherited from Transport class)
virtual DocStatus Request ();
// Sends a request message for HTTP
virtual DocStatus HTTPRequest ();
///////
// Control of member the variables
///////
///////
// Set the Request Method
///////
void SetRequestMethod (Request_Method rm) { _Method = rm; }
Request_Method GetRequestMethod() { return _Method; }
///////
// Interface for resource retrieving
///////
// Set and get the document to be retrieved
void SetRequestURL(const URL &u) { _url = u;}
URL GetRequestURL () { return _url;}
// Set and get the referring URL
void SetRefererURL (const URL& u) { _referer = u;}
URL GetRefererURL () { return _referer;}
// Set and get the accept-language string
void SetAcceptLanguage (const String& al) { _accept_language = al; }
URL GetAcceptLanguage () { return _accept_language; }
// Info for multiple requests (static)
// Get the User agent string
static void SetRequestUserAgent (const String &s) { _user_agent=s; }
static const String &GetRequestUserAgent() { return _user_agent; }
// Set (Basic) Authentication Credentials
virtual void SetCredentials (const String& s);
// Set (Basic) Authentication Credentials for the HTTP Proxy
virtual void SetProxyCredentials (const String& s);
///////
// Interface for the HTTP Response
///////
// We have a valid response only if the status code is not equal to
// initialization value
Transport_Response *GetResponse()
{
if (_response._status_code != -1)
return &_response;
else return 0;}
// Get the document status
virtual DocStatus GetDocumentStatus()
{ return GetDocumentStatus (_response); }
// It's a static method
static DocStatus GetDocumentStatus(HtHTTP_Response &);
///////
// Persistent connection choices interface
///////
// Is allowed
bool isPersistentConnectionAllowed() {return _persistent_connection_allowed;}
// Is possible
bool isPersistentConnectionPossible() {return _persistent_connection_possible;}
// Check if a persistent connection is possible depending on the HTTP response
void CheckPersistentConnection(HtHTTP_Response &);
// Is Up (is both allowed and permitted by the server too)
bool isPersistentConnectionUp()
{ return isConnected() && isPersistentConnectionAllowed() &&
isPersistentConnectionPossible(); }
// Allow Persistent Connection
void AllowPersistentConnection() { _persistent_connection_allowed=true; }
// Disable Persistent Connection
void DisablePersistentConnection() { _persistent_connection_allowed=false; }
// Allow Cookies
void AllowCookies() { _send_cookies=true; }
// Disable Persistent Connection
void DisableCookies() { _send_cookies=false; }
///////
// Set the cookie manager class (that is to say the class)
///////
// It's set only if not done before
static void SetCookieJar(HtCookieJar *cj) { _cookie_jar = cj; }
///////
// Manage statistics
///////
static int GetTotSeconds () { return _tot_seconds; }
static int GetTotRequests () { return _tot_requests; }
static int GetTotBytes () { return _tot_bytes; }
static double GetAverageRequestTime ()
{ return _tot_seconds?( ((double) _tot_seconds) / _tot_requests) : 0; }
static float GetAverageSpeed ()
{ return _tot_bytes?( ((double) _tot_bytes) / _tot_seconds) : 0; }
static void ResetStatistics ()
{ _tot_seconds=0; _tot_requests=0; _tot_bytes=0;}
// Show stats
static ostream &ShowStatistics (ostream &out);
///////
// Set the _head_before_get option
// make a request to be made up of a HEAD call and then,
// if necessary, a GET call
///////
static void EnableHeadBeforeGet() { _head_before_get = true; }
static void DisableHeadBeforeGet() { _head_before_get = false; }
static bool HeadBeforeGet() { return _head_before_get; }
///////
// Set the controller for the parsing check. That is to say
// that External function that checks if a document is parsable or not.
// CanBeParsed static attribute should point to a function
// that returns an int value, given a char * containing the content-type.
///////
static void SetParsingController (int (*f)(char*)) { CanBeParsed = f; }
protected:
///////
// Member attributes
///////
Request_Method _Method;
///////
// Http single Request information (Member attributes)
///////
int _bytes_read; // Bytes read
URL _url; // URL to retrieve
URL _referer; // Referring URL
String _accept_language; // accept-language directive
///////
// Http multiple Request information
///////
static String _user_agent; // User agent
///////
// Http Response information
///////
HtHTTP_Response _response; // Object where response
// information will be stored into
///////
// Allow or not a persistent connection (user choice)
///////
bool _persistent_connection_allowed;
///////
// Is a persistent connection possible (with this http server)?
///////
bool _persistent_connection_possible;
///////
// Are cookies enabled?
///////
bool _send_cookies;
///////
// Option that, if set to true, make a request to be made up
// of a HEAD call and then, if necessary, a GET call
///////
static bool _head_before_get;
///////
// Manager of the body reading
///////
int (HtHTTP::*_readbody) ();
///////
// Enum
///////
// Information about the status of a connection
enum ConnectionStatus
{
Connection_ok,
Connection_already_up,
Connection_open_failed,
Connection_no_server,
Connection_no_port,
Connection_failed
};
///////
// Protected Services or method (Hidden by outside)
///////
///////
// Establish the connection
///////
ConnectionStatus EstablishConnection ();
///////
// Set the string of the command containing the request
///////
void SetRequestCommand(String &);
///////
// Parse the header returned by the server
///////
int ParseHeader();
///////
// Check if a document is parsable looking the content-type info
///////
static bool isParsable(const char *);
///////
// Read the body returned by the server
///////
void SetBodyReadingController (int (HtHTTP::*f)()) { _readbody = f; }
int ReadBody();
int ReadChunkedBody(); // Read the body of a chunked encoded-response
// Finish the request and return a DocStatus value;
DocStatus FinishRequest (DocStatus);
///////
// Static attributes and methods
///////
// Unique cookie Jar
static HtCookieJar *_cookie_jar; // Jar containing all of the cookies
static int _tot_seconds; // Requests last (in seconds)
static int _tot_requests; // Number of requests
static int _tot_bytes; // Number of bytes read
// This is a pointer to function that check if a ContentType
// is parsable or less.
static int (*CanBeParsed) (char *);
};
#endif