1 //
2 // HtHTTP.h
3 //
4 // HtHTTP: Class for HTTP messaging (derived from Transport)
5 //
6 // Gabriele Bartolini - Prato - Italia
7 // started: 03.05.1999
8 //
9 // ////////////////////////////////////////////////////////////
10 //
11 // The HtHTTP class should provide (as I hope) an interface for
12 // retrieving document on the Web. It derives from Transport class.
13 //
14 // It should be HTTP/1.1 compatible.
15 //
16 // It also let us take advantage of persitent connections use,
17 // and optimize request times (specially if directed to the same
18 // server).
19 //
20 // HtHTTP use another class to store the response returned by the
21 // remote server.
22 //
23 // Now cookies management is enabled.
24 //
25 ///////
26 //
27 // Part of the ht://Dig package   <http://www.htdig.org/>
28 // Copyright (c) 1995-2004 The ht://Dig Group
29 // For copyright details, see the file COPYING in your distribution
30 // or the GNU Library General Public License (LGPL) version 2 or later
31 // <http://www.gnu.org/copyleft/lgpl.html>
32 //
33 // $Id: HtHTTP.h,v 1.15 2004/05/28 13:15:23 lha Exp $
34 //
35 
36 #ifndef _HTHTTP_H
37 #define _HTHTTP_H
38 
39 #ifdef HAVE_CONFIG_H
40 #include "htconfig.h"
41 #endif /* HAVE_CONFIG_H */
42 
43 #include "Transport.h"
44 
45 // Cookie support
46 #include "HtCookie.h"
47 #include "HtCookieJar.h"
48 
49 #include "URL.h"
50 #include "htString.h"
51 
52 // for HtHTTP::ShowStatistics#ifdef HAVE_STD
53 #ifdef HAVE_STD
54 #include <iostream>
55 #ifdef HAVE_NAMESPACES
56 using namespace std;
57 #endif
58 #else
59 #include <iostream.h>
60 #endif /* HAVE_STD */
61 
62 // In advance declarations
63 
64 class HtHTTP;
65 
66 
67 class HtHTTP_Response : public Transport_Response
68 {
69 
70    friend class HtHTTP;    // declaring friendship
71 
72    public:
73 ///////
74    //    Construction / Destruction
75 ///////
76 
77       HtHTTP_Response();
78       ~HtHTTP_Response();
79 
80 
81 ///////
82    //    Interface
83 ///////
84 
85    	 // Reset
86 	 void Reset();
87 
88 	 // Get the HTTP version
GetVersion()89    	 const String &GetVersion() const { return _version; }
90 
91 	 // Get the Transfer-encoding
GetTransferEncoding()92    	 const String &GetTransferEncoding() const
93             { return _transfer_encoding; }
94 
95 	 // Get server info
GetServer()96    	 const String &GetServer() const { return _server; }
97 
98 	 // Get Connection info
GetConnectionInfo()99    	 const String &GetConnectionInfo() const { return _hdrconnection; }
100 
101 	 // Get Content language
GetContentLanguage()102    	 const String &GetContentLanguage() const { return _content_language; }
103 
104 
105    protected:
106 
107    // Status line information
108 
109    	 String	   _version;	          // HTTP Version
110 
111    // Other header information
112 
113 	 String    _transfer_encoding;    // Transfer-encoding
114    	 String	   _server;	          // Server string returned
115    	 String	   _hdrconnection;	  // Connection header
116 	 String    _content_language;     // Content-language
117 
118 };
119 
120 
121 
122 class HtHTTP : public Transport
123 {
124 private:
HtHTTP()125    HtHTTP() {}    // Declared private - avoids default constructor to be created
126       	          // in some cases by the compiler.
127 public:
128 
129 ///////
130    //    Construction/Destruction
131 ///////
132 
133     HtHTTP(Connection&);
134     virtual ~HtHTTP() = 0;
135 
136    // Information about the method to be used in the request
137 
138    enum Request_Method
139    {
140    	 Method_GET,
141 	 Method_HEAD
142    };
143 
144 
145 
146 ///////
147    //    Sends an HTTP request message
148 ///////
149 
150    // manages a Transport request (method inherited from Transport class)
151    virtual DocStatus Request ();
152 
153    // Sends a request message for HTTP
154    virtual DocStatus HTTPRequest ();
155 
156 
157 ///////
158    //    Control of member the variables
159 ///////
160 
161  ///////
162     //    Set the Request Method
163  ///////
164 
SetRequestMethod(Request_Method rm)165    void SetRequestMethod (Request_Method rm) { _Method = rm; }
GetRequestMethod()166    Request_Method GetRequestMethod() { return _Method; }
167 
168 
169  ///////
170     //    Interface for resource retrieving
171  ///////
172 
173    // Set and get the document to be retrieved
SetRequestURL(const URL & u)174    void SetRequestURL(const URL &u) { _url = u;}
GetRequestURL()175    URL GetRequestURL () { return _url;}
176 
177 
178    // Set and get the referring URL
SetRefererURL(const URL & u)179    void SetRefererURL (const URL& u) { _referer = u;}
GetRefererURL()180    URL GetRefererURL () { return _referer;}
181 
182    // Set and get the accept-language string
SetAcceptLanguage(const String & al)183    void SetAcceptLanguage (const String& al) { _accept_language = al; }
GetAcceptLanguage()184    URL GetAcceptLanguage () { return _accept_language; }
185 
186    // Info for multiple requests (static)
187    // Get the User agent string
SetRequestUserAgent(const String & s)188    static void SetRequestUserAgent (const String &s) { _user_agent=s; }
GetRequestUserAgent()189    static const String &GetRequestUserAgent() { return _user_agent; }
190 
191    // Set (Basic) Authentication Credentials
192    virtual void SetCredentials (const String& s);
193 
194    // Set (Basic) Authentication Credentials for the HTTP Proxy
195    virtual void SetProxyCredentials (const String& s);
196 
197  ///////
198     //    Interface for the HTTP Response
199  ///////
200 
201    // We have a valid response only if the status code is not equal to
202    // initialization value
203 
GetResponse()204    Transport_Response *GetResponse()
205    {
206       if (_response._status_code != -1)
207          return &_response;
208       else return 0;}
209 
210 
211    // Get the document status
GetDocumentStatus()212    virtual DocStatus GetDocumentStatus()
213       { return GetDocumentStatus (_response); }
214 
215    // It's a static method
216    static DocStatus GetDocumentStatus(HtHTTP_Response &);
217 
218 
219 
220 ///////
221    //    Persistent connection choices interface
222 ///////
223 
224    // Is allowed
isPersistentConnectionAllowed()225    bool isPersistentConnectionAllowed() {return _persistent_connection_allowed;}
226 
227    // Is possible
isPersistentConnectionPossible()228    bool isPersistentConnectionPossible() {return _persistent_connection_possible;}
229 
230    // Check if a persistent connection is possible depending on the HTTP response
231    void CheckPersistentConnection(HtHTTP_Response &);
232 
233    // Is Up (is both allowed and permitted by the server too)
isPersistentConnectionUp()234    bool isPersistentConnectionUp()
235    	    { return isConnected() && isPersistentConnectionAllowed() &&
236    	       	   isPersistentConnectionPossible(); }
237 
238    // Allow Persistent Connection
AllowPersistentConnection()239    void AllowPersistentConnection() { _persistent_connection_allowed=true; }
240 
241    // Disable Persistent Connection
DisablePersistentConnection()242    void DisablePersistentConnection() { _persistent_connection_allowed=false; }
243 
244    // Allow Cookies
AllowCookies()245    void AllowCookies() { _send_cookies=true; }
246 
247    // Disable Persistent Connection
DisableCookies()248    void DisableCookies() { _send_cookies=false; }
249 
250 
251 ///////
252    // 	 Set the cookie manager class (that is to say the class)
253 ///////
254 
255    // It's set only if not done before
SetCookieJar(HtCookieJar * cj)256    static void SetCookieJar(HtCookieJar *cj) { _cookie_jar = cj; }
257 
258 
259 ///////
260    // 	 Manage statistics
261 ///////
262 
GetTotSeconds()263    static int GetTotSeconds () { return _tot_seconds; }
264 
GetTotRequests()265    static int GetTotRequests () { return _tot_requests; }
266 
GetTotBytes()267    static int GetTotBytes () { return _tot_bytes; }
268 
GetAverageRequestTime()269    static double GetAverageRequestTime ()
270    	 { return _tot_seconds?( ((double) _tot_seconds) / _tot_requests) : 0; }
271 
GetAverageSpeed()272    static float GetAverageSpeed ()
273    	 { return _tot_bytes?( ((double) _tot_bytes) / _tot_seconds) : 0; }
274 
ResetStatistics()275    static void ResetStatistics ()
276    	 { _tot_seconds=0; _tot_requests=0; _tot_bytes=0;}
277 
278    // Show stats
279    static ostream &ShowStatistics (ostream &out);
280 
281 
282 
283 ///////
284    //    Set the _head_before_get option
285    //    make a request to be made up of a HEAD call and then,
286    //    if necessary, a GET call
287 ///////
288 
EnableHeadBeforeGet()289    static void EnableHeadBeforeGet() { _head_before_get = true; }
DisableHeadBeforeGet()290    static void DisableHeadBeforeGet() { _head_before_get = false; }
291 
HeadBeforeGet()292    static bool HeadBeforeGet() { return _head_before_get; }
293 
294 
295 ///////
296    //    Set the controller for the parsing check. That is to say
297    //    that External function that checks if a document is parsable or not.
298    //    CanBeParsed static attribute should point to a function
299    //    that returns an int value, given a char * containing the content-type.
300 ///////
301 
SetParsingController(int (* f)(char *))302    static void SetParsingController (int (*f)(char*)) { CanBeParsed = f; }
303 
304 protected:
305 
306 ///////
307    //    Member attributes
308 ///////
309 
310    Request_Method    _Method;
311 
312    ///////
313       //    Http single Request information (Member attributes)
314    ///////
315 
316    int      	_bytes_read;        // Bytes read
317    URL		_url;               // URL to retrieve
318    URL		_referer;	    // Referring URL
319 
320    String      _accept_language;    // accept-language directive
321 
322    ///////
323       //    Http multiple Request information
324    ///////
325 
326    static String   	_user_agent;  	   // User agent
327 
328 
329 
330    ///////
331       //    Http Response information
332    ///////
333 
334    HtHTTP_Response	 _response; 	 // Object where response
335    	       	   	       	   	 // information will be stored into
336 
337 
338    ///////
339       //    Allow or not a persistent connection (user choice)
340    ///////
341 
342    bool _persistent_connection_allowed;
343 
344 
345    ///////
346       //    Is a persistent connection possible (with this http server)?
347    ///////
348 
349    bool _persistent_connection_possible;
350 
351    ///////
352       //    Are cookies enabled?
353    ///////
354 
355    bool _send_cookies;
356 
357    ///////
358       //    Option that, if set to true, make a request to be made up
359       //    of a HEAD call and then, if necessary, a GET call
360    ///////
361 
362    static bool _head_before_get;
363 
364 ///////
365    //    Manager of the body reading
366 ///////
367 
368    int (HtHTTP::*_readbody) ();
369 
370 
371 ///////
372    //    Enum
373 ///////
374 
375    // Information about the status of a connection
376 
377    enum ConnectionStatus
378    {
379    	 Connection_ok,
380 	 Connection_already_up,
381    	 Connection_open_failed,
382    	 Connection_no_server,
383    	 Connection_no_port,
384    	 Connection_failed
385    };
386 
387 
388 ///////
389    //    Protected Services or method (Hidden by outside)
390 ///////
391 
392 
393    ///////
394       //    Establish the connection
395    ///////
396 
397    ConnectionStatus EstablishConnection ();
398 
399 
400    ///////
401       //    Set the string of the command containing the request
402    ///////
403 
404    void SetRequestCommand(String &);
405 
406 
407    ///////
408       //    Parse the header returned by the server
409    ///////
410 
411    int ParseHeader();
412 
413    ///////
414       //    Check if a document is parsable looking the content-type info
415    ///////
416 
417    static bool isParsable(const char *);
418 
419    ///////
420       //    Read the body returned by the server
421    ///////
422 
SetBodyReadingController(int (HtHTTP::* f)())423    void SetBodyReadingController (int (HtHTTP::*f)()) { _readbody = f; }
424    int ReadBody();
425    int ReadChunkedBody();  // Read the body of a chunked encoded-response
426 
427 
428    // Finish the request and return a DocStatus value;
429 
430    DocStatus FinishRequest (DocStatus);
431 
432 
433 ///////
434    //    Static attributes and methods
435 ///////
436 
437    // Unique cookie Jar
438    static HtCookieJar *_cookie_jar;  // Jar containing all of the cookies
439 
440    static int  _tot_seconds;  	 // Requests last (in seconds)
441    static int  _tot_requests; 	 // Number of requests
442    static int  _tot_bytes;    	 // Number of bytes read
443 
444    // This is a pointer to function that check if a ContentType
445    // is parsable or less.
446 
447    static int (*CanBeParsed) (char *);
448 
449 };
450 
451 #endif
452 
453