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