00001 // Filename: httpChannel.I 00002 // Created by: drose (24Sep02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: HTTPChannel::is_valid 00022 // Access: Published 00023 // Description: Returns true if the last-requested document was 00024 // successfully retrieved and is ready to be read, false 00025 // otherwise. 00026 //////////////////////////////////////////////////////////////////// 00027 INLINE bool HTTPChannel:: 00028 is_valid() const { 00029 return (_state != S_failure && (_status_code / 100) == 2 && 00030 (_server_response_has_no_body || !_source.is_null())); 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: HTTPChannel::is_connection_ready 00035 // Access: Published 00036 // Description: Returns true if a connection has been established to 00037 // the named server in a previous call to connect_to() 00038 // or begin_connect_to(), false otherwise. 00039 //////////////////////////////////////////////////////////////////// 00040 INLINE bool HTTPChannel:: 00041 is_connection_ready() const { 00042 return (!_source.is_null() && _state == S_ready); 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: HTTPChannel::get_url 00047 // Access: Published 00048 // Description: Returns the URL that was used to retrieve the 00049 // most recent document: whatever URL was last passed to 00050 // get_document() or get_header(). If a redirect has 00051 // transparently occurred, this will return the new, 00052 // redirected URL (the actual URL at which the document 00053 // was located). 00054 //////////////////////////////////////////////////////////////////// 00055 INLINE const URLSpec &HTTPChannel:: 00056 get_url() const { 00057 return _document_spec.get_url(); 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: HTTPChannel::get_document_spec 00062 // Access: Published 00063 // Description: Returns the DocumentSpec associated with the most 00064 // recent document. This includes its actual URL 00065 // (following redirects) along with the identity tag and 00066 // last-modified date, if supplied by the server. 00067 // 00068 // This structure may be saved and used to retrieve the 00069 // same version of the document later, or to 00070 // conditionally retrieve a newer version if it is 00071 // available. 00072 //////////////////////////////////////////////////////////////////// 00073 INLINE const DocumentSpec &HTTPChannel:: 00074 get_document_spec() const { 00075 return _document_spec; 00076 } 00077 00078 //////////////////////////////////////////////////////////////////// 00079 // Function: HTTPChannel::get_http_version 00080 // Access: Published 00081 // Description: Returns the HTTP version number returned by the 00082 // server, as one of the HTTPClient enumerated types, 00083 // e.g. HTTPClient::HV_11. 00084 //////////////////////////////////////////////////////////////////// 00085 INLINE HTTPEnum::HTTPVersion HTTPChannel:: 00086 get_http_version() const { 00087 return _http_version; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: HTTPChannel::get_http_version_string 00092 // Access: Published 00093 // Description: Returns the HTTP version number returned by the 00094 // server, formatted as a string, e.g. "HTTP/1.1". 00095 //////////////////////////////////////////////////////////////////// 00096 INLINE const string &HTTPChannel:: 00097 get_http_version_string() const { 00098 return _http_version_string; 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: HTTPChannel::get_status_code 00103 // Access: Published 00104 // Description: Returns the HTML return code from the document 00105 // retrieval request. This will be in the 200 range if 00106 // the document is successfully retrieved, or some other 00107 // value in the case of an error. 00108 // 00109 // Some proxy errors during an https-over-proxy request 00110 // would return the same status code as a different 00111 // error that occurred on the host server. To 00112 // differentiate these cases, status codes that are 00113 // returned by the proxy during the CONNECT phase 00114 // (except code 407) are incremented by 1000. 00115 //////////////////////////////////////////////////////////////////// 00116 INLINE int HTTPChannel:: 00117 get_status_code() const { 00118 return _status_code; 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: HTTPChannel::get_status_string 00123 // Access: Published 00124 // Description: Returns the string as returned by the server 00125 // describing the status code for humans. This may or 00126 // may not be meaningful. 00127 //////////////////////////////////////////////////////////////////// 00128 INLINE const string &HTTPChannel:: 00129 get_status_string() const { 00130 return _status_string; 00131 } 00132 00133 //////////////////////////////////////////////////////////////////// 00134 // Function: HTTPChannel::get_www_realm 00135 // Access: Published 00136 // Description: If the document failed to connect because of a 401 00137 // (Authorization required), this method will return the 00138 // "realm" returned by the server in which the requested 00139 // document must be authenticated. This string may be 00140 // presented to the user to request an associated 00141 // username and password (which then should be stored in 00142 // HTTPClient::set_username()). 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE const string &HTTPChannel:: 00145 get_www_realm() const { 00146 return _www_realm; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: HTTPChannel::get_proxy_realm 00151 // Access: Published 00152 // Description: If the document failed to connect because of a 407 00153 // (Proxy authorization required), this method will 00154 // return the "realm" returned by the proxy. This 00155 // string may be presented to the user to request an 00156 // associated username and password (which then should 00157 // be stored in HTTPClient::set_username()). 00158 //////////////////////////////////////////////////////////////////// 00159 INLINE const string &HTTPChannel:: 00160 get_proxy_realm() const { 00161 return _proxy_realm; 00162 } 00163 00164 //////////////////////////////////////////////////////////////////// 00165 // Function: HTTPChannel::get_redirect 00166 // Access: Published 00167 // Description: If the document failed with a redirect code (300 00168 // series), this will generally contain the new URL the 00169 // server wants us to try. In many cases, the client 00170 // will automatically follow redirects; if these are 00171 // succesful the client will return a successful code 00172 // and get_redirect() will return empty, but get_url() 00173 // will return the new, redirected URL. 00174 //////////////////////////////////////////////////////////////////// 00175 INLINE const URLSpec &HTTPChannel:: 00176 get_redirect() const { 00177 return _redirect; 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: HTTPChannel::set_persistent_connection 00182 // Access: Published 00183 // Description: Indicates whether the HTTPChannel should try to keep 00184 // the connection to the server open and reuse that 00185 // connection for multiple documents, or whether it 00186 // should close the connection and open a new one for 00187 // each request. Set this true to keep the connections 00188 // around when possible, false to recycle them. 00189 // 00190 // It makes most sense to set this false when the 00191 // HTTPChannel will be used only once to retrieve a 00192 // single document, true when you will be using the same 00193 // HTTPChannel object to retrieve multiple documents. 00194 //////////////////////////////////////////////////////////////////// 00195 INLINE void HTTPChannel:: 00196 set_persistent_connection(bool persistent_connection) { 00197 _persistent_connection = persistent_connection; 00198 } 00199 00200 //////////////////////////////////////////////////////////////////// 00201 // Function: HTTPChannel::get_persistent_connection 00202 // Access: Published 00203 // Description: Returns whether the HTTPChannel should try to keep 00204 // the connection to the server open and reuse that 00205 // connection for multiple documents, or whether it 00206 // should close the connection and open a new one for 00207 // each request. See set_persistent_connection(). 00208 //////////////////////////////////////////////////////////////////// 00209 INLINE bool HTTPChannel:: 00210 get_persistent_connection() const { 00211 return _persistent_connection; 00212 } 00213 00214 //////////////////////////////////////////////////////////////////// 00215 // Function: HTTPChannel::set_connect_timeout 00216 // Access: Published 00217 // Description: Sets the maximum length of time, in seconds, that the 00218 // channel will wait before giving up on establishing a 00219 // TCP connection. 00220 // 00221 // At present, this is used only for the nonblocking 00222 // interfaces (e.g. begin_get_document(), 00223 // begin_connect_to()), but it is used whether 00224 // set_blocking_connect() is true or false. 00225 //////////////////////////////////////////////////////////////////// 00226 INLINE void HTTPChannel:: 00227 set_connect_timeout(double connect_timeout) { 00228 _connect_timeout = connect_timeout; 00229 } 00230 00231 //////////////////////////////////////////////////////////////////// 00232 // Function: HTTPChannel::get_connect_timeout 00233 // Access: Published 00234 // Description: Returns the length of time, in seconds, to wait for a 00235 // new nonblocking socket to connect. See 00236 // set_connect_timeout(). 00237 //////////////////////////////////////////////////////////////////// 00238 INLINE double HTTPChannel:: 00239 get_connect_timeout() const { 00240 return _connect_timeout; 00241 } 00242 00243 //////////////////////////////////////////////////////////////////// 00244 // Function: HTTPChannel::set_blocking_connect 00245 // Access: Published 00246 // Description: If this flag is true, a socket connect will block 00247 // even for nonblocking I/O calls like 00248 // begin_get_document(), begin_connect_to(), etc. If 00249 // false, a socket connect will not block for 00250 // nonblocking I/O calls, but will block for blocking 00251 // I/O calls (get_document(), connect_to(), etc.). 00252 00253 // Setting this true is useful when you want to use 00254 // non-blocking I/O once you have established the 00255 // connection, but you don't want to bother with polling 00256 // for the initial connection. It's also useful when 00257 // you don't particularly care about non-blocking I/O, 00258 // but you need to respect timeouts like connect_timeout 00259 // and http_timeout. 00260 //////////////////////////////////////////////////////////////////// 00261 INLINE void HTTPChannel:: 00262 set_blocking_connect(bool blocking_connect) { 00263 _blocking_connect = blocking_connect; 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: HTTPChannel::get_blocking_connect 00268 // Access: Published 00269 // Description: If this flag is true, a socket connect will block 00270 // even for nonblocking I/O calls like 00271 // begin_get_document(), begin_connect_to(), etc. If 00272 // false, a socket connect will not block for 00273 // nonblocking I/O calls, but will block for blocking 00274 // I/O calls (get_document(), connect_to(), etc.). 00275 //////////////////////////////////////////////////////////////////// 00276 INLINE bool HTTPChannel:: 00277 get_blocking_connect() const { 00278 return _blocking_connect; 00279 } 00280 00281 //////////////////////////////////////////////////////////////////// 00282 // Function: HTTPChannel::set_http_timeout 00283 // Access: Published 00284 // Description: Sets the maximum length of time, in seconds, that the 00285 // channel will wait for the HTTP server to finish 00286 // sending its response to our request. 00287 // 00288 // The timer starts counting after the TCP connection 00289 // has been established (see set_connect_timeout(), 00290 // above) and the request has been sent. 00291 // 00292 // At present, this is used only for the nonblocking 00293 // interfaces (e.g. begin_get_document(), 00294 // begin_connect_to()), but it is used whether 00295 // set_blocking_connect() is true or false. 00296 //////////////////////////////////////////////////////////////////// 00297 INLINE void HTTPChannel:: 00298 set_http_timeout(double http_timeout) { 00299 _http_timeout = http_timeout; 00300 } 00301 00302 //////////////////////////////////////////////////////////////////// 00303 // Function: HTTPChannel::get_http_timeout 00304 // Access: Published 00305 // Description: Returns the length of time, in seconds, to wait for 00306 // the HTTP server to respond to our request. See 00307 // set_http_timeout(). 00308 //////////////////////////////////////////////////////////////////// 00309 INLINE double HTTPChannel:: 00310 get_http_timeout() const { 00311 return _http_timeout; 00312 } 00313 00314 //////////////////////////////////////////////////////////////////// 00315 // Function: HTTPChannel::set_download_throttle 00316 // Access: Published 00317 // Description: Specifies whether nonblocking downloads (via 00318 // download_to_file() or download_to_ram()) will be 00319 // limited so as not to use all available bandwidth. 00320 // 00321 // If this is true, when a download has been started on 00322 // this channel it will be invoked no more frequently 00323 // than get_max_updates_per_second(), and the total 00324 // bandwidth used by the download will be no more than 00325 // get_max_bytes_per_second(). If this is false, 00326 // downloads will proceed as fast as the server can send 00327 // the data. 00328 // 00329 // This only has effect on the nonblocking I/O methods 00330 // like begin_get_document(), etc. The blocking methods 00331 // like get_document() always use as much CPU and 00332 // bandwidth as they can get. 00333 //////////////////////////////////////////////////////////////////// 00334 INLINE void HTTPChannel:: 00335 set_download_throttle(bool download_throttle) { 00336 _download_throttle = download_throttle; 00337 } 00338 00339 //////////////////////////////////////////////////////////////////// 00340 // Function: HTTPChannel::get_download_throttle 00341 // Access: Published 00342 // Description: Returns whether the nonblocking downloads will be 00343 // bandwidth-limited. See set_download_throttle(). 00344 //////////////////////////////////////////////////////////////////// 00345 INLINE bool HTTPChannel:: 00346 get_download_throttle() const { 00347 return _download_throttle; 00348 } 00349 00350 //////////////////////////////////////////////////////////////////// 00351 // Function: HTTPChannel::set_max_bytes_per_second 00352 // Access: Published 00353 // Description: When bandwidth throttling is in effect (see 00354 // set_download_throttle()), this specifies the maximum 00355 // number of bytes per second that may be consumed by 00356 // this channel. 00357 //////////////////////////////////////////////////////////////////// 00358 INLINE void HTTPChannel:: 00359 set_max_bytes_per_second(double max_bytes_per_second) { 00360 _max_bytes_per_second = max_bytes_per_second; 00361 _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update); 00362 } 00363 00364 //////////////////////////////////////////////////////////////////// 00365 // Function: HTTPChannel::get_max_bytes_per_second 00366 // Access: Published 00367 // Description: Returns the maximum number of bytes per second that 00368 // may be consumed by this channel when 00369 // get_download_throttle() is true. 00370 //////////////////////////////////////////////////////////////////// 00371 INLINE double HTTPChannel:: 00372 get_max_bytes_per_second() const { 00373 return _max_bytes_per_second; 00374 } 00375 00376 //////////////////////////////////////////////////////////////////// 00377 // Function: HTTPChannel::set_max_updates_per_second 00378 // Access: Published 00379 // Description: When bandwidth throttling is in effect (see 00380 // set_download_throttle()), this specifies the maximum 00381 // number of times per second that run() will attempt to 00382 // do any downloading at all. 00383 //////////////////////////////////////////////////////////////////// 00384 INLINE void HTTPChannel:: 00385 set_max_updates_per_second(double max_updates_per_second) { 00386 nassertv(max_updates_per_second != 0.0f); 00387 _max_updates_per_second = max_updates_per_second; 00388 _seconds_per_update = 1.0f / _max_updates_per_second; 00389 _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update); 00390 } 00391 00392 //////////////////////////////////////////////////////////////////// 00393 // Function: HTTPChannel::get_max_updates_per_second 00394 // Access: Published 00395 // Description: Returns the maximum number of times per second that 00396 // run() will do anything at all, when 00397 // get_download_throttle() is true. 00398 //////////////////////////////////////////////////////////////////// 00399 INLINE double HTTPChannel:: 00400 get_max_updates_per_second() const { 00401 return _max_updates_per_second; 00402 } 00403 00404 //////////////////////////////////////////////////////////////////// 00405 // Function: HTTPChannel::get_file_size 00406 // Access: Published 00407 // Description: Returns the size of the file, if it is known. 00408 // Returns 0 if the file size is not known. 00409 // 00410 // If the file is dynamically generated, the size may 00411 // not be available until a read has started 00412 // (e.g. open_read_file() has been called); and even 00413 // then it may increase as more of the file is read due 00414 // to the nature of HTTP/1.1 requests which can change 00415 // their minds midstream about how much data they're 00416 // sending you. 00417 //////////////////////////////////////////////////////////////////// 00418 INLINE size_t HTTPChannel:: 00419 get_file_size() const { 00420 return _file_size; 00421 } 00422 00423 //////////////////////////////////////////////////////////////////// 00424 // Function: HTTPChannel::reset 00425 // Access: Published 00426 // Description: Stops whatever file transaction is currently in 00427 // progress, closes the connection, and resets to begin 00428 // anew. You shouldn't ever need to call this, since 00429 // the channel should be able to reset itself cleanly 00430 // between requests, but it is provided in case you are 00431 // an especially nervous type. 00432 // 00433 // Don't call this after every request unless you set 00434 // set_persistent_connection() to false, since calling 00435 // reset() rudely closes the connection regardless of 00436 // whether we have told the server we intend to keep it 00437 // open or not. 00438 //////////////////////////////////////////////////////////////////// 00439 INLINE void HTTPChannel:: 00440 reset() { 00441 reset_for_new_request(); 00442 reset_to_new(); 00443 } 00444 00445 //////////////////////////////////////////////////////////////////// 00446 // Function: HTTPChannel::clear_extra_headers 00447 // Access: Published 00448 // Description: Resets the extra headers that were previously added 00449 // via calls to send_extra_header(). 00450 //////////////////////////////////////////////////////////////////// 00451 INLINE void HTTPChannel:: 00452 clear_extra_headers() { 00453 _send_extra_headers = string(); 00454 } 00455 00456 //////////////////////////////////////////////////////////////////// 00457 // Function: HTTPChannel::send_extra_header 00458 // Access: Published 00459 // Description: Specifies an additional key: value pair that is added 00460 // into the header sent to the server with the next 00461 // request. This is passed along with no interpretation 00462 // by the HTTPChannel code. You may call this 00463 // repeatedly to append multiple headers. 00464 // 00465 // This is persistent for one request only; it must be 00466 // set again for each new request. 00467 //////////////////////////////////////////////////////////////////// 00468 INLINE void HTTPChannel:: 00469 send_extra_header(const string &key, const string &value) { 00470 _send_extra_headers += key; 00471 _send_extra_headers += ": "; 00472 _send_extra_headers += value; 00473 _send_extra_headers += "\r\n"; 00474 } 00475 00476 //////////////////////////////////////////////////////////////////// 00477 // Function: HTTPChannel::get_document 00478 // Access: Published 00479 // Description: Opens the named document for reading, if available. 00480 // Returns true if successful, false otherwise. 00481 //////////////////////////////////////////////////////////////////// 00482 INLINE bool HTTPChannel:: 00483 get_document(const DocumentSpec &url) { 00484 begin_request(HTTPEnum::M_get, url, string(), false, 0, 0); 00485 run(); 00486 return is_valid(); 00487 } 00488 00489 //////////////////////////////////////////////////////////////////// 00490 // Function: HTTPChannel::get_subdocument 00491 // Access: Published 00492 // Description: Retrieves only the specified byte range of the 00493 // indicated document. If last_byte is 0, it stands for 00494 // the last byte of the document. When a subdocument is 00495 // requested, get_file_size() and get_bytes_downloaded() 00496 // will report the number of bytes of the subdocument, 00497 // not of the complete document. 00498 //////////////////////////////////////////////////////////////////// 00499 INLINE bool HTTPChannel:: 00500 get_subdocument(const DocumentSpec &url, size_t first_byte, size_t last_byte) { 00501 begin_request(HTTPEnum::M_get, url, string(), false, first_byte, last_byte); 00502 run(); 00503 return is_valid(); 00504 } 00505 00506 //////////////////////////////////////////////////////////////////// 00507 // Function: HTTPChannel::get_header 00508 // Access: Published 00509 // Description: Like get_document(), except only the header 00510 // associated with the document is retrieved. This may 00511 // be used to test for existence of the document; it 00512 // might also return the size of the document (if the 00513 // server gives us this information). 00514 //////////////////////////////////////////////////////////////////// 00515 INLINE bool HTTPChannel:: 00516 get_header(const DocumentSpec &url) { 00517 begin_request(HTTPEnum::M_head, url, string(), false, 0, 0); 00518 run(); 00519 return is_valid(); 00520 } 00521 00522 //////////////////////////////////////////////////////////////////// 00523 // Function: HTTPChannel::post_form 00524 // Access: Published 00525 // Description: Posts form data to a particular URL and retrieves the 00526 // response. 00527 //////////////////////////////////////////////////////////////////// 00528 INLINE bool HTTPChannel:: 00529 post_form(const DocumentSpec &url, const string &body) { 00530 begin_request(HTTPEnum::M_post, url, body, false, 0, 0); 00531 run(); 00532 return is_valid(); 00533 } 00534 00535 //////////////////////////////////////////////////////////////////// 00536 // Function: HTTPChannel::put_document 00537 // Access: Published 00538 // Description: Uploads the indicated body to the server to replace 00539 // the indicated URL, if the server allows this. 00540 //////////////////////////////////////////////////////////////////// 00541 INLINE bool HTTPChannel:: 00542 put_document(const DocumentSpec &url, const string &body) { 00543 begin_request(HTTPEnum::M_put, url, body, false, 0, 0); 00544 run(); 00545 return is_valid(); 00546 } 00547 00548 //////////////////////////////////////////////////////////////////// 00549 // Function: HTTPChannel::delete_document 00550 // Access: Published 00551 // Description: Requests the server to remove the indicated URL. 00552 //////////////////////////////////////////////////////////////////// 00553 INLINE bool HTTPChannel:: 00554 delete_document(const DocumentSpec &url) { 00555 begin_request(HTTPEnum::M_delete, url, string(), false, 0, 0); 00556 run(); 00557 return is_valid(); 00558 } 00559 00560 //////////////////////////////////////////////////////////////////// 00561 // Function: HTTPChannel::get_trace 00562 // Access: Published 00563 // Description: Sends a TRACE message to the server, which should 00564 // return back the same message as the server received 00565 // it, allowing inspection of proxy hops, etc. 00566 //////////////////////////////////////////////////////////////////// 00567 INLINE bool HTTPChannel:: 00568 get_trace(const DocumentSpec &url) { 00569 begin_request(HTTPEnum::M_trace, url, string(), false, 0, 0); 00570 run(); 00571 return is_valid(); 00572 } 00573 00574 //////////////////////////////////////////////////////////////////// 00575 // Function: HTTPChannel::connect_to 00576 // Access: Published 00577 // Description: Establish a direct connection to the server and port 00578 // indicated by the URL, but do not issue any HTTP 00579 // requests. If successful, the connection may then be 00580 // taken to use for whatever purposes you like by 00581 // calling get_connection(). 00582 // 00583 // This establishes a blocking I/O socket. Also see 00584 // begin_connect_to(). 00585 //////////////////////////////////////////////////////////////////// 00586 INLINE bool HTTPChannel:: 00587 connect_to(const DocumentSpec &url) { 00588 begin_request(HTTPEnum::M_connect, url, string(), false, 0, 0); 00589 run(); 00590 return is_connection_ready(); 00591 } 00592 00593 //////////////////////////////////////////////////////////////////// 00594 // Function: HTTPChannel::get_options 00595 // Access: Published 00596 // Description: Sends an OPTIONS message to the server, which should 00597 // query the available options, possibly in relation to 00598 // a specified URL. 00599 //////////////////////////////////////////////////////////////////// 00600 INLINE bool HTTPChannel:: 00601 get_options(const DocumentSpec &url) { 00602 begin_request(HTTPEnum::M_options, url, string(), false, 0, 0); 00603 run(); 00604 return is_valid(); 00605 } 00606 00607 //////////////////////////////////////////////////////////////////// 00608 // Function: HTTPChannel::begin_get_document 00609 // Access: Published 00610 // Description: Begins a non-blocking request to retrieve a given 00611 // document. This method will return immediately, even 00612 // before a connection to the server has necessarily 00613 // been established; you must then call run() from time 00614 // to time until the return value of run() is false. 00615 // Then you may check is_valid() and get_status_code() 00616 // to determine the status of your request. 00617 // 00618 // If a previous request had been pending, that request 00619 // is discarded. 00620 //////////////////////////////////////////////////////////////////// 00621 INLINE void HTTPChannel:: 00622 begin_get_document(const DocumentSpec &url) { 00623 begin_request(HTTPEnum::M_get, url, string(), true, 0, 0); 00624 } 00625 00626 //////////////////////////////////////////////////////////////////// 00627 // Function: HTTPChannel::begin_get_subdocument 00628 // Access: Published 00629 // Description: Begins a non-blocking request to retrieve only the 00630 // specified byte range of the indicated document. If 00631 // last_byte is 0, it stands for the last byte of the 00632 // document. When a subdocument is requested, 00633 // get_file_size() and get_bytes_downloaded() will 00634 // report the number of bytes of the subdocument, not of 00635 // the complete document. 00636 //////////////////////////////////////////////////////////////////// 00637 INLINE void HTTPChannel:: 00638 begin_get_subdocument(const DocumentSpec &url, size_t first_byte, 00639 size_t last_byte) { 00640 begin_request(HTTPEnum::M_get, url, string(), true, first_byte, last_byte); 00641 } 00642 00643 //////////////////////////////////////////////////////////////////// 00644 // Function: HTTPChannel::begin_get_header 00645 // Access: Published 00646 // Description: Begins a non-blocking request to retrieve a given 00647 // header. See begin_get_document() and get_header(). 00648 //////////////////////////////////////////////////////////////////// 00649 INLINE void HTTPChannel:: 00650 begin_get_header(const DocumentSpec &url) { 00651 begin_request(HTTPEnum::M_head, url, string(), true, 0, 0); 00652 } 00653 00654 //////////////////////////////////////////////////////////////////// 00655 // Function: HTTPChannel::begin_post_form 00656 // Access: Published 00657 // Description: Posts form data to a particular URL and retrieves the 00658 // response, all using non-blocking I/O. See 00659 // begin_get_document() and post_form(). 00660 // 00661 // It is important to note that you *must* call run() 00662 // repeatedly after calling this method until run() 00663 // returns false, and you may not call any other 00664 // document posting or retrieving methods using the 00665 // HTTPChannel object in the interim, or your form data 00666 // may not get posted. 00667 //////////////////////////////////////////////////////////////////// 00668 INLINE void HTTPChannel:: 00669 begin_post_form(const DocumentSpec &url, const string &body) { 00670 begin_request(HTTPEnum::M_post, url, body, true, 0, 0); 00671 } 00672 00673 //////////////////////////////////////////////////////////////////// 00674 // Function: HTTPChannel::begin_connect_to 00675 // Access: Published 00676 // Description: Begins a non-blocking request to establish a direct 00677 // connection to the server and port indicated by the 00678 // URL. No HTTP requests will be issued beyond what is 00679 // necessary to establish the connection. When run() 00680 // has finished, you may call is_connection_ready() to 00681 // determine if the connection was successfully 00682 // established. 00683 // 00684 // If successful, the connection may then be taken to 00685 // use for whatever purposes you like by calling 00686 // get_connection(). 00687 // 00688 // This establishes a nonblocking I/O socket. Also see 00689 // connect_to(). 00690 //////////////////////////////////////////////////////////////////// 00691 INLINE void HTTPChannel:: 00692 begin_connect_to(const DocumentSpec &url) { 00693 begin_request(HTTPEnum::M_connect, url, string(), true, 0, 0); 00694 } 00695 00696 //////////////////////////////////////////////////////////////////// 00697 // Function: HTTPChannel::get_bytes_downloaded 00698 // Access: Published 00699 // Description: Returns the number of bytes downloaded during the 00700 // last (or current) download_to_file() or 00701 // download_to_ram operation(). This can be used in 00702 // conjunction with get_file_size() to report the 00703 // percent complete (but be careful, since 00704 // get_file_size() may return 0 if the server has not 00705 // told us the size of the file). 00706 //////////////////////////////////////////////////////////////////// 00707 INLINE size_t HTTPChannel:: 00708 get_bytes_downloaded() const { 00709 return _bytes_downloaded; 00710 } 00711 00712 //////////////////////////////////////////////////////////////////// 00713 // Function: HTTPChannel::get_bytes_requested 00714 // Access: Published 00715 // Description: When download throttling is in effect 00716 // (set_download_throttle() has been set to true) and 00717 // non-blocking I/O methods (like begin_get_document()) 00718 // are used, this returns the number of bytes 00719 // "requested" from the server so far: that is, the 00720 // theoretical maximum value for get_bytes_downloaded(), 00721 // if the server has been keeping up with our demand. 00722 // 00723 // If this number is less than get_bytes_downloaded(), 00724 // then the server has not been supplying bytes fast 00725 // enough to meet our own download throttle rate. 00726 // 00727 // When download throttling is not in effect, or when 00728 // the blocking I/O methods (like get_document(), etc.) 00729 // are used, this returns 0. 00730 //////////////////////////////////////////////////////////////////// 00731 INLINE size_t HTTPChannel:: 00732 get_bytes_requested() const { 00733 return _bytes_requested; 00734 } 00735 00736 //////////////////////////////////////////////////////////////////// 00737 // Function: HTTPChannel::is_download_complete 00738 // Access: Published 00739 // Description: Returns true when a download_to() or 00740 // download_to_ram() has executed and the file has been 00741 // fully downloaded. If this still returns false after 00742 // processing has completed, there was an error in 00743 // transmission. 00744 // 00745 // Note that simply testing is_download_complete() does 00746 // not prove that the requested document was succesfully 00747 // retrieved--you might have just downloaded the "404 00748 // not found" stub (for instance) that a server would 00749 // provide in response to some error condition. You 00750 // should also check is_valid() to prove that the file 00751 // you expected has been successfully retrieved. 00752 //////////////////////////////////////////////////////////////////// 00753 INLINE bool HTTPChannel:: 00754 is_download_complete() const { 00755 return (_download_dest != DD_none && 00756 (_state == S_read_body || _state == S_read_trailer)); 00757 }