Panda3D
|
00001 // Filename: httpChannel.I 00002 // Created by: drose (24Sep02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: HTTPChannel::get_client 00018 // Access: Published 00019 // Description: Returns the HTTPClient object that owns this channel. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE HTTPClient *HTTPChannel:: 00022 get_client() const { 00023 return _client; 00024 } 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: HTTPChannel::is_valid 00028 // Access: Published 00029 // Description: Returns true if the last-requested document was 00030 // successfully retrieved and is ready to be read, false 00031 // otherwise. 00032 //////////////////////////////////////////////////////////////////// 00033 INLINE bool HTTPChannel:: 00034 is_valid() const { 00035 return (_state != S_failure && (get_status_code() / 100) == 2 && 00036 (_server_response_has_no_body || !_source.is_null())); 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: HTTPChannel::is_connection_ready 00041 // Access: Published 00042 // Description: Returns true if a connection has been established to 00043 // the named server in a previous call to connect_to() 00044 // or begin_connect_to(), false otherwise. 00045 //////////////////////////////////////////////////////////////////// 00046 INLINE bool HTTPChannel:: 00047 is_connection_ready() const { 00048 return (!_source.is_null() && _state == S_ready); 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: HTTPChannel::get_url 00053 // Access: Published 00054 // Description: Returns the URL that was used to retrieve the 00055 // most recent document: whatever URL was last passed to 00056 // get_document() or get_header(). If a redirect has 00057 // transparently occurred, this will return the new, 00058 // redirected URL (the actual URL at which the document 00059 // was located). 00060 //////////////////////////////////////////////////////////////////// 00061 INLINE const URLSpec &HTTPChannel:: 00062 get_url() const { 00063 return _document_spec.get_url(); 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: HTTPChannel::get_document_spec 00068 // Access: Published 00069 // Description: Returns the DocumentSpec associated with the most 00070 // recent document. This includes its actual URL 00071 // (following redirects) along with the identity tag and 00072 // last-modified date, if supplied by the server. 00073 // 00074 // This structure may be saved and used to retrieve the 00075 // same version of the document later, or to 00076 // conditionally retrieve a newer version if it is 00077 // available. 00078 //////////////////////////////////////////////////////////////////// 00079 INLINE const DocumentSpec &HTTPChannel:: 00080 get_document_spec() const { 00081 return _document_spec; 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function: HTTPChannel::get_http_version 00086 // Access: Published 00087 // Description: Returns the HTTP version number returned by the 00088 // server, as one of the HTTPClient enumerated types, 00089 // e.g. HTTPClient::HV_11. 00090 //////////////////////////////////////////////////////////////////// 00091 INLINE HTTPEnum::HTTPVersion HTTPChannel:: 00092 get_http_version() const { 00093 return _http_version; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function: HTTPChannel::get_http_version_string 00098 // Access: Published 00099 // Description: Returns the HTTP version number returned by the 00100 // server, formatted as a string, e.g. "HTTP/1.1". 00101 //////////////////////////////////////////////////////////////////// 00102 INLINE const string &HTTPChannel:: 00103 get_http_version_string() const { 00104 return _http_version_string; 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: HTTPChannel::get_status_code 00109 // Access: Published 00110 // Description: Returns the HTML return code from the document 00111 // retrieval request. This will be in the 200 range if 00112 // the document is successfully retrieved, or some other 00113 // value in the case of an error. 00114 // 00115 // Some proxy errors during an https-over-proxy request 00116 // would return the same status code as a different 00117 // error that occurred on the host server. To 00118 // differentiate these cases, status codes that are 00119 // returned by the proxy during the CONNECT phase 00120 // (except code 407) are incremented by 1000. 00121 //////////////////////////////////////////////////////////////////// 00122 INLINE int HTTPChannel:: 00123 get_status_code() const { 00124 return _status_entry._status_code; 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: HTTPChannel::get_www_realm 00129 // Access: Published 00130 // Description: If the document failed to connect because of a 401 00131 // (Authorization required), this method will return the 00132 // "realm" returned by the server in which the requested 00133 // document must be authenticated. This string may be 00134 // presented to the user to request an associated 00135 // username and password (which then should be stored in 00136 // HTTPClient::set_username()). 00137 //////////////////////////////////////////////////////////////////// 00138 INLINE const string &HTTPChannel:: 00139 get_www_realm() const { 00140 return _www_realm; 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: HTTPChannel::get_proxy_realm 00145 // Access: Published 00146 // Description: If the document failed to connect because of a 407 00147 // (Proxy authorization required), this method will 00148 // return the "realm" returned by the proxy. This 00149 // string may be presented to the user to request an 00150 // associated username and password (which then should 00151 // be stored in HTTPClient::set_username()). 00152 //////////////////////////////////////////////////////////////////// 00153 INLINE const string &HTTPChannel:: 00154 get_proxy_realm() const { 00155 return _proxy_realm; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: HTTPChannel::get_redirect 00160 // Access: Published 00161 // Description: If the document failed with a redirect code (300 00162 // series), this will generally contain the new URL the 00163 // server wants us to try. In many cases, the client 00164 // will automatically follow redirects; if these are 00165 // successful the client will return a successful code 00166 // and get_redirect() will return empty, but get_url() 00167 // will return the new, redirected URL. 00168 //////////////////////////////////////////////////////////////////// 00169 INLINE const URLSpec &HTTPChannel:: 00170 get_redirect() const { 00171 return _redirect; 00172 } 00173 00174 //////////////////////////////////////////////////////////////////// 00175 // Function: HTTPChannel::get_num_redirect_steps 00176 // Access: Published 00177 // Description: If the document automatically followed one or more 00178 // redirects, this will return the number of redirects 00179 // that were automatically followed. Use 00180 // get_redirect_step() to retrieve each URL in 00181 // sequence. 00182 //////////////////////////////////////////////////////////////////// 00183 INLINE int HTTPChannel:: 00184 get_num_redirect_steps() const { 00185 return _redirect_trail.size(); 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: HTTPChannel::get_redirect_step 00190 // Access: Published 00191 // Description: Use in conjunction with get_num_redirect_steps() to 00192 // extract the chain of URL's that the channel was 00193 // automatically redirected through to arrive at the 00194 // final document. 00195 //////////////////////////////////////////////////////////////////// 00196 INLINE const URLSpec &HTTPChannel:: 00197 get_redirect_step(int n) const { 00198 nassertr(n >= 0 && n < (int)_redirect_trail.size(), _redirect_trail[0]); 00199 return _redirect_trail[n]; 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: HTTPChannel::set_persistent_connection 00204 // Access: Published 00205 // Description: Indicates whether the HTTPChannel should try to keep 00206 // the connection to the server open and reuse that 00207 // connection for multiple documents, or whether it 00208 // should close the connection and open a new one for 00209 // each request. Set this true to keep the connections 00210 // around when possible, false to recycle them. 00211 // 00212 // It makes most sense to set this false when the 00213 // HTTPChannel will be used only once to retrieve a 00214 // single document, true when you will be using the same 00215 // HTTPChannel object to retrieve multiple documents. 00216 //////////////////////////////////////////////////////////////////// 00217 INLINE void HTTPChannel:: 00218 set_persistent_connection(bool persistent_connection) { 00219 _persistent_connection = persistent_connection; 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: HTTPChannel::get_persistent_connection 00224 // Access: Published 00225 // Description: Returns whether the HTTPChannel should try to keep 00226 // the connection to the server open and reuse that 00227 // connection for multiple documents, or whether it 00228 // should close the connection and open a new one for 00229 // each request. See set_persistent_connection(). 00230 //////////////////////////////////////////////////////////////////// 00231 INLINE bool HTTPChannel:: 00232 get_persistent_connection() const { 00233 return _persistent_connection; 00234 } 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: HTTPChannel::set_allow_proxy 00238 // Access: Published 00239 // Description: If this is true (the normal case), the HTTPClient 00240 // will be consulted for information about the proxy to 00241 // be used for each connection via this HTTPChannel. If 00242 // this has been set to false by the user, then all 00243 // connections will be made directly, regardless of the 00244 // proxy settings indicated on the HTTPClient. 00245 //////////////////////////////////////////////////////////////////// 00246 INLINE void HTTPChannel:: 00247 set_allow_proxy(bool allow_proxy) { 00248 _allow_proxy = allow_proxy; 00249 } 00250 00251 //////////////////////////////////////////////////////////////////// 00252 // Function: HTTPChannel::get_allow_proxy 00253 // Access: Published 00254 // Description: If this is true (the normal case), the HTTPClient 00255 // will be consulted for information about the proxy to 00256 // be used for each connection via this HTTPChannel. If 00257 // this has been set to false by the user, then all 00258 // connections will be made directly, regardless of the 00259 // proxy settings indicated on the HTTPClient. 00260 //////////////////////////////////////////////////////////////////// 00261 INLINE bool HTTPChannel:: 00262 get_allow_proxy() const { 00263 return _allow_proxy; 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: HTTPChannel::set_proxy_tunnel 00268 // Access: Published 00269 // Description: Normally, a proxy is itself asked for ordinary URL's, 00270 // and the proxy decides whether to hand the client a 00271 // cached version of the document or to contact the 00272 // server for a fresh version. The proxy may also 00273 // modify the headers and transfer encoding on the way. 00274 // 00275 // If this is set to true, then instead of asking for 00276 // URL's from the proxy, we will ask the proxy to open a 00277 // connection to the server (for instance, on port 80); 00278 // if the proxy honors this request, then we contact the 00279 // server directly through this connection to retrieve 00280 // the document. If the proxy does not honor the 00281 // connect request, then the retrieve operation fails. 00282 // 00283 // SSL connections (e.g. https), and connections through 00284 // a Socks proxy, are always tunneled, regardless of the 00285 // setting of this flag. 00286 //////////////////////////////////////////////////////////////////// 00287 INLINE void HTTPChannel:: 00288 set_proxy_tunnel(bool proxy_tunnel) { 00289 _proxy_tunnel = proxy_tunnel; 00290 } 00291 00292 //////////////////////////////////////////////////////////////////// 00293 // Function: HTTPChannel::get_proxy_tunnel 00294 // Access: Published 00295 // Description: Returns true if connections always tunnel through a 00296 // proxy, or false (the normal case) if we allow the 00297 // proxy to serve up documents. See set_proxy_tunnel(). 00298 //////////////////////////////////////////////////////////////////// 00299 INLINE bool HTTPChannel:: 00300 get_proxy_tunnel() const { 00301 return _proxy_tunnel; 00302 } 00303 00304 //////////////////////////////////////////////////////////////////// 00305 // Function: HTTPChannel::set_connect_timeout 00306 // Access: Published 00307 // Description: Sets the maximum length of time, in seconds, that the 00308 // channel will wait before giving up on establishing a 00309 // TCP connection. 00310 // 00311 // At present, this is used only for the nonblocking 00312 // interfaces (e.g. begin_get_document(), 00313 // begin_connect_to()), but it is used whether 00314 // set_blocking_connect() is true or false. 00315 //////////////////////////////////////////////////////////////////// 00316 INLINE void HTTPChannel:: 00317 set_connect_timeout(double connect_timeout) { 00318 _connect_timeout = connect_timeout; 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: HTTPChannel::get_connect_timeout 00323 // Access: Published 00324 // Description: Returns the length of time, in seconds, to wait for a 00325 // new nonblocking socket to connect. See 00326 // set_connect_timeout(). 00327 //////////////////////////////////////////////////////////////////// 00328 INLINE double HTTPChannel:: 00329 get_connect_timeout() const { 00330 return _connect_timeout; 00331 } 00332 00333 //////////////////////////////////////////////////////////////////// 00334 // Function: HTTPChannel::set_blocking_connect 00335 // Access: Published 00336 // Description: If this flag is true, a socket connect will block 00337 // even for nonblocking I/O calls like 00338 // begin_get_document(), begin_connect_to(), etc. If 00339 // false, a socket connect will not block for 00340 // nonblocking I/O calls, but will block for blocking 00341 // I/O calls (get_document(), connect_to(), etc.). 00342 // 00343 // Setting this true is useful when you want to use 00344 // non-blocking I/O once you have established the 00345 // connection, but you don't want to bother with polling 00346 // for the initial connection. It's also useful when 00347 // you don't particularly care about non-blocking I/O, 00348 // but you need to respect timeouts like connect_timeout 00349 // and http_timeout. 00350 //////////////////////////////////////////////////////////////////// 00351 INLINE void HTTPChannel:: 00352 set_blocking_connect(bool blocking_connect) { 00353 _blocking_connect = blocking_connect; 00354 } 00355 00356 //////////////////////////////////////////////////////////////////// 00357 // Function: HTTPChannel::get_blocking_connect 00358 // Access: Published 00359 // Description: If this flag is true, a socket connect will block 00360 // even for nonblocking I/O calls like 00361 // begin_get_document(), begin_connect_to(), etc. If 00362 // false, a socket connect will not block for 00363 // nonblocking I/O calls, but will block for blocking 00364 // I/O calls (get_document(), connect_to(), etc.). 00365 //////////////////////////////////////////////////////////////////// 00366 INLINE bool HTTPChannel:: 00367 get_blocking_connect() const { 00368 return _blocking_connect; 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: HTTPChannel::set_http_timeout 00373 // Access: Published 00374 // Description: Sets the maximum length of time, in seconds, that the 00375 // channel will wait for the HTTP server to finish 00376 // sending its response to our request. 00377 // 00378 // The timer starts counting after the TCP connection 00379 // has been established (see set_connect_timeout(), 00380 // above) and the request has been sent. 00381 // 00382 // At present, this is used only for the nonblocking 00383 // interfaces (e.g. begin_get_document(), 00384 // begin_connect_to()), but it is used whether 00385 // set_blocking_connect() is true or false. 00386 //////////////////////////////////////////////////////////////////// 00387 INLINE void HTTPChannel:: 00388 set_http_timeout(double http_timeout) { 00389 _http_timeout = http_timeout; 00390 } 00391 00392 //////////////////////////////////////////////////////////////////// 00393 // Function: HTTPChannel::get_http_timeout 00394 // Access: Published 00395 // Description: Returns the length of time, in seconds, to wait for 00396 // the HTTP server to respond to our request. See 00397 // set_http_timeout(). 00398 //////////////////////////////////////////////////////////////////// 00399 INLINE double HTTPChannel:: 00400 get_http_timeout() const { 00401 return _http_timeout; 00402 } 00403 00404 //////////////////////////////////////////////////////////////////// 00405 // Function: HTTPChannel::set_skip_body_size 00406 // Access: Published 00407 // Description: Specifies the maximum number of bytes in a received 00408 // (but unwanted) body that will be skipped past, in 00409 // order to reset to a new request. 00410 // 00411 // That is, if this HTTPChannel requests a file via 00412 // get_document(), but does not call download_to_ram(), 00413 // download_to_file(), or open_read_body(), and instead 00414 // immediately requests a new file, then the HTTPChannel 00415 // has a choice whether to skip past the unwanted 00416 // document, or to close the connection and open a new 00417 // one. If the number of bytes to skip is more than 00418 // this threshold, the connection will be closed; 00419 // otherwise, the data will simply be read and 00420 // discarded. 00421 //////////////////////////////////////////////////////////////////// 00422 INLINE void HTTPChannel:: 00423 set_skip_body_size(size_t skip_body_size) { 00424 _skip_body_size = skip_body_size; 00425 } 00426 00427 //////////////////////////////////////////////////////////////////// 00428 // Function: HTTPChannel::get_skip_body_size 00429 // Access: Published 00430 // Description: Returns the maximum number of bytes in a received 00431 // (but unwanted) body that will be skipped past, in 00432 // order to reset to a new request. See 00433 // set_skip_body_size(). 00434 //////////////////////////////////////////////////////////////////// 00435 INLINE size_t HTTPChannel:: 00436 get_skip_body_size() const { 00437 return _skip_body_size; 00438 } 00439 00440 //////////////////////////////////////////////////////////////////// 00441 // Function: HTTPChannel::set_idle_timeout 00442 // Access: Published 00443 // Description: Specifies the amount of time, in seconds, in which a 00444 // previously-established connection is allowed to 00445 // remain open and unused. If a previous connection has 00446 // remained unused for at least this number of seconds, 00447 // it will be closed and a new connection will be 00448 // opened; otherwise, the same connection will be reused 00449 // for the next request (for this particular 00450 // HTTPChannel). 00451 //////////////////////////////////////////////////////////////////// 00452 INLINE void HTTPChannel:: 00453 set_idle_timeout(double idle_timeout) { 00454 _idle_timeout = idle_timeout; 00455 } 00456 00457 //////////////////////////////////////////////////////////////////// 00458 // Function: HTTPChannel::get_idle_timeout 00459 // Access: Published 00460 // Description: Returns the amount of time, in seconds, in which an 00461 // previously-established connection is allowed to 00462 // remain open and unused. See set_idle_timeout(). 00463 //////////////////////////////////////////////////////////////////// 00464 INLINE double HTTPChannel:: 00465 get_idle_timeout() const { 00466 return _idle_timeout; 00467 } 00468 00469 //////////////////////////////////////////////////////////////////// 00470 // Function: HTTPChannel::set_download_throttle 00471 // Access: Published 00472 // Description: Specifies whether nonblocking downloads (via 00473 // download_to_file() or download_to_ram()) will be 00474 // limited so as not to use all available bandwidth. 00475 // 00476 // If this is true, when a download has been started on 00477 // this channel it will be invoked no more frequently 00478 // than get_max_updates_per_second(), and the total 00479 // bandwidth used by the download will be no more than 00480 // get_max_bytes_per_second(). If this is false, 00481 // downloads will proceed as fast as the server can send 00482 // the data. 00483 // 00484 // This only has effect on the nonblocking I/O methods 00485 // like begin_get_document(), etc. The blocking methods 00486 // like get_document() always use as much CPU and 00487 // bandwidth as they can get. 00488 //////////////////////////////////////////////////////////////////// 00489 INLINE void HTTPChannel:: 00490 set_download_throttle(bool download_throttle) { 00491 _download_throttle = download_throttle; 00492 } 00493 00494 //////////////////////////////////////////////////////////////////// 00495 // Function: HTTPChannel::get_download_throttle 00496 // Access: Published 00497 // Description: Returns whether the nonblocking downloads will be 00498 // bandwidth-limited. See set_download_throttle(). 00499 //////////////////////////////////////////////////////////////////// 00500 INLINE bool HTTPChannel:: 00501 get_download_throttle() const { 00502 return _download_throttle; 00503 } 00504 00505 //////////////////////////////////////////////////////////////////// 00506 // Function: HTTPChannel::set_max_bytes_per_second 00507 // Access: Published 00508 // Description: When bandwidth throttling is in effect (see 00509 // set_download_throttle()), this specifies the maximum 00510 // number of bytes per second that may be consumed by 00511 // this channel. 00512 //////////////////////////////////////////////////////////////////// 00513 INLINE void HTTPChannel:: 00514 set_max_bytes_per_second(double max_bytes_per_second) { 00515 _max_bytes_per_second = max_bytes_per_second; 00516 _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update); 00517 } 00518 00519 //////////////////////////////////////////////////////////////////// 00520 // Function: HTTPChannel::get_max_bytes_per_second 00521 // Access: Published 00522 // Description: Returns the maximum number of bytes per second that 00523 // may be consumed by this channel when 00524 // get_download_throttle() is true. 00525 //////////////////////////////////////////////////////////////////// 00526 INLINE double HTTPChannel:: 00527 get_max_bytes_per_second() const { 00528 return _max_bytes_per_second; 00529 } 00530 00531 //////////////////////////////////////////////////////////////////// 00532 // Function: HTTPChannel::set_max_updates_per_second 00533 // Access: Published 00534 // Description: When bandwidth throttling is in effect (see 00535 // set_download_throttle()), this specifies the maximum 00536 // number of times per second that run() will attempt to 00537 // do any downloading at all. 00538 //////////////////////////////////////////////////////////////////// 00539 INLINE void HTTPChannel:: 00540 set_max_updates_per_second(double max_updates_per_second) { 00541 nassertv(max_updates_per_second != 0.0f); 00542 _max_updates_per_second = max_updates_per_second; 00543 _seconds_per_update = 1.0f / _max_updates_per_second; 00544 _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update); 00545 } 00546 00547 //////////////////////////////////////////////////////////////////// 00548 // Function: HTTPChannel::get_max_updates_per_second 00549 // Access: Published 00550 // Description: Returns the maximum number of times per second that 00551 // run() will do anything at all, when 00552 // get_download_throttle() is true. 00553 //////////////////////////////////////////////////////////////////// 00554 INLINE double HTTPChannel:: 00555 get_max_updates_per_second() const { 00556 return _max_updates_per_second; 00557 } 00558 00559 //////////////////////////////////////////////////////////////////// 00560 // Function: HTTPChannel::set_expected_file_size 00561 // Access: Published 00562 // Description: This may be called immediately after a call to 00563 // get_document() or some related function to specify 00564 // the expected size of the document we are retrieving, 00565 // if we happen to know. This is used as the return 00566 // value to get_file_size() only in the case that the 00567 // server does not tell us the actual file size. 00568 //////////////////////////////////////////////////////////////////// 00569 INLINE void HTTPChannel:: 00570 set_expected_file_size(size_t file_size) { 00571 _expected_file_size = file_size; 00572 _got_expected_file_size = true; 00573 } 00574 00575 00576 //////////////////////////////////////////////////////////////////// 00577 // Function: HTTPChannel::is_file_size_known 00578 // Access: Published 00579 // Description: Returns true if the size of the file we are currently 00580 // retrieving was told us by the server and thus is 00581 // reliably known, or false if the size reported by 00582 // get_file_size() represents an educated guess 00583 // (possibly as set by set_expected_file_size(), or as 00584 // inferred from a chunked transfer encoding in 00585 // progress). 00586 //////////////////////////////////////////////////////////////////// 00587 INLINE bool HTTPChannel:: 00588 is_file_size_known() const { 00589 return _got_file_size; 00590 } 00591 00592 //////////////////////////////////////////////////////////////////// 00593 // Function: HTTPChannel::get_first_byte_requested 00594 // Access: Published 00595 // Description: Returns the first byte of the file requested by the 00596 // request. This will normally be 0 to indicate that 00597 // the file is being requested from the beginning, but 00598 // if the file was requested via a get_subdocument() 00599 // call, this will contain the first_byte parameter from 00600 // that call. 00601 //////////////////////////////////////////////////////////////////// 00602 INLINE size_t HTTPChannel:: 00603 get_first_byte_requested() const { 00604 return _first_byte_requested; 00605 } 00606 00607 //////////////////////////////////////////////////////////////////// 00608 // Function: HTTPChannel::get_last_byte_requested 00609 // Access: Published 00610 // Description: Returns the last byte of the file requested by the 00611 // request. This will normally be 0 to indicate that 00612 // the file is being requested to its last byte, but if 00613 // the file was requested via a get_subdocument() call, 00614 // this will contain the last_byte parameter from that 00615 // call. 00616 //////////////////////////////////////////////////////////////////// 00617 INLINE size_t HTTPChannel:: 00618 get_last_byte_requested() const { 00619 return _last_byte_requested; 00620 } 00621 00622 //////////////////////////////////////////////////////////////////// 00623 // Function: HTTPChannel::get_first_byte_delivered 00624 // Access: Published 00625 // Description: Returns the first byte of the file (that will be) 00626 // delivered by the server in response to the current 00627 // request. Normally, this is the same as 00628 // get_first_byte_requested(), but some servers will 00629 // ignore a subdocument request and always return the 00630 // whole file, in which case this value will be 0, 00631 // regardless of what was requested to 00632 // get_subdocument(). 00633 //////////////////////////////////////////////////////////////////// 00634 INLINE size_t HTTPChannel:: 00635 get_first_byte_delivered() const { 00636 return _first_byte_delivered; 00637 } 00638 00639 //////////////////////////////////////////////////////////////////// 00640 // Function: HTTPChannel::get_last_byte_delivered 00641 // Access: Published 00642 // Description: Returns the last byte of the file (that will be) 00643 // delivered by the server in response to the current 00644 // request. Normally, this is the same as 00645 // get_last_byte_requested(), but some servers will 00646 // ignore a subdocument request and always return the 00647 // whole file, in which case this value will be 0, 00648 // regardless of what was requested to 00649 // get_subdocument(). 00650 //////////////////////////////////////////////////////////////////// 00651 INLINE size_t HTTPChannel:: 00652 get_last_byte_delivered() const { 00653 return _last_byte_delivered; 00654 } 00655 00656 //////////////////////////////////////////////////////////////////// 00657 // Function: HTTPChannel::reset 00658 // Access: Published 00659 // Description: Stops whatever file transaction is currently in 00660 // progress, closes the connection, and resets to begin 00661 // anew. You shouldn't ever need to call this, since 00662 // the channel should be able to reset itself cleanly 00663 // between requests, but it is provided in case you are 00664 // an especially nervous type. 00665 // 00666 // Don't call this after every request unless you set 00667 // set_persistent_connection() to false, since calling 00668 // reset() rudely closes the connection regardless of 00669 // whether we have told the server we intend to keep it 00670 // open or not. 00671 //////////////////////////////////////////////////////////////////// 00672 INLINE void HTTPChannel:: 00673 reset() { 00674 reset_for_new_request(); 00675 reset_to_new(); 00676 _status_list.clear(); 00677 } 00678 00679 //////////////////////////////////////////////////////////////////// 00680 // Function: HTTPChannel::preserve_status 00681 // Access: Published 00682 // Description: Preserves the previous status code (presumably a 00683 // failure) from the previous connection attempt. If 00684 // the subsequent connection attempt also fails, the 00685 // returned status code will be the better of the 00686 // previous code and the current code. 00687 // 00688 // This can be called to daisy-chain subsequent attempts 00689 // to download the same document from different servers. 00690 // After all servers have been attempted, the final 00691 // status code will reflect the attempt that most nearly 00692 // succeeded. 00693 //////////////////////////////////////////////////////////////////// 00694 INLINE void HTTPChannel:: 00695 preserve_status() { 00696 _status_list.push_back(_status_entry); 00697 } 00698 00699 00700 //////////////////////////////////////////////////////////////////// 00701 // Function: HTTPChannel::clear_extra_headers 00702 // Access: Published 00703 // Description: Resets the extra headers that were previously added 00704 // via calls to send_extra_header(). 00705 //////////////////////////////////////////////////////////////////// 00706 INLINE void HTTPChannel:: 00707 clear_extra_headers() { 00708 _send_extra_headers = string(); 00709 } 00710 00711 //////////////////////////////////////////////////////////////////// 00712 // Function: HTTPChannel::send_extra_header 00713 // Access: Published 00714 // Description: Specifies an additional key: value pair that is added 00715 // into the header sent to the server with the next 00716 // request. This is passed along with no interpretation 00717 // by the HTTPChannel code. You may call this 00718 // repeatedly to append multiple headers. 00719 // 00720 // This is persistent for one request only; it must be 00721 // set again for each new request. 00722 //////////////////////////////////////////////////////////////////// 00723 INLINE void HTTPChannel:: 00724 send_extra_header(const string &key, const string &value) { 00725 _send_extra_headers += key; 00726 _send_extra_headers += ": "; 00727 _send_extra_headers += value; 00728 _send_extra_headers += "\r\n"; 00729 } 00730 00731 //////////////////////////////////////////////////////////////////// 00732 // Function: HTTPChannel::get_document 00733 // Access: Published 00734 // Description: Opens the named document for reading, if available. 00735 // Returns true if successful, false otherwise. 00736 //////////////////////////////////////////////////////////////////// 00737 INLINE bool HTTPChannel:: 00738 get_document(const DocumentSpec &url) { 00739 begin_request(HTTPEnum::M_get, url, string(), false, 0, 0); 00740 while (run()) { 00741 } 00742 return is_valid(); 00743 } 00744 00745 //////////////////////////////////////////////////////////////////// 00746 // Function: HTTPChannel::get_subdocument 00747 // Access: Published 00748 // Description: Retrieves only the specified byte range of the 00749 // indicated document. If last_byte is 0, it stands for 00750 // the last byte of the document. When a subdocument is 00751 // requested, get_file_size() and get_bytes_downloaded() 00752 // will report the number of bytes of the subdocument, 00753 // not of the complete document. 00754 //////////////////////////////////////////////////////////////////// 00755 INLINE bool HTTPChannel:: 00756 get_subdocument(const DocumentSpec &url, size_t first_byte, size_t last_byte) { 00757 begin_request(HTTPEnum::M_get, url, string(), false, first_byte, last_byte); 00758 while (run()) { 00759 } 00760 return is_valid(); 00761 } 00762 00763 //////////////////////////////////////////////////////////////////// 00764 // Function: HTTPChannel::get_header 00765 // Access: Published 00766 // Description: Like get_document(), except only the header 00767 // associated with the document is retrieved. This may 00768 // be used to test for existence of the document; it 00769 // might also return the size of the document (if the 00770 // server gives us this information). 00771 //////////////////////////////////////////////////////////////////// 00772 INLINE bool HTTPChannel:: 00773 get_header(const DocumentSpec &url) { 00774 begin_request(HTTPEnum::M_head, url, string(), false, 0, 0); 00775 while (run()) { 00776 } 00777 return is_valid(); 00778 } 00779 00780 //////////////////////////////////////////////////////////////////// 00781 // Function: HTTPChannel::post_form 00782 // Access: Published 00783 // Description: Posts form data to a particular URL and retrieves the 00784 // response. 00785 //////////////////////////////////////////////////////////////////// 00786 INLINE bool HTTPChannel:: 00787 post_form(const DocumentSpec &url, const string &body) { 00788 begin_request(HTTPEnum::M_post, url, body, false, 0, 0); 00789 while (run()) { 00790 } 00791 return is_valid(); 00792 } 00793 00794 //////////////////////////////////////////////////////////////////// 00795 // Function: HTTPChannel::put_document 00796 // Access: Published 00797 // Description: Uploads the indicated body to the server to replace 00798 // the indicated URL, if the server allows this. 00799 //////////////////////////////////////////////////////////////////// 00800 INLINE bool HTTPChannel:: 00801 put_document(const DocumentSpec &url, const string &body) { 00802 begin_request(HTTPEnum::M_put, url, body, false, 0, 0); 00803 while (run()) { 00804 } 00805 return is_valid(); 00806 } 00807 00808 //////////////////////////////////////////////////////////////////// 00809 // Function: HTTPChannel::delete_document 00810 // Access: Published 00811 // Description: Requests the server to remove the indicated URL. 00812 //////////////////////////////////////////////////////////////////// 00813 INLINE bool HTTPChannel:: 00814 delete_document(const DocumentSpec &url) { 00815 begin_request(HTTPEnum::M_delete, url, string(), false, 0, 0); 00816 while (run()) { 00817 } 00818 return is_valid(); 00819 } 00820 00821 //////////////////////////////////////////////////////////////////// 00822 // Function: HTTPChannel::get_trace 00823 // Access: Published 00824 // Description: Sends a TRACE message to the server, which should 00825 // return back the same message as the server received 00826 // it, allowing inspection of proxy hops, etc. 00827 //////////////////////////////////////////////////////////////////// 00828 INLINE bool HTTPChannel:: 00829 get_trace(const DocumentSpec &url) { 00830 begin_request(HTTPEnum::M_trace, url, string(), false, 0, 0); 00831 while (run()) { 00832 } 00833 return is_valid(); 00834 } 00835 00836 //////////////////////////////////////////////////////////////////// 00837 // Function: HTTPChannel::connect_to 00838 // Access: Published 00839 // Description: Establish a direct connection to the server and port 00840 // indicated by the URL, but do not issue any HTTP 00841 // requests. If successful, the connection may then be 00842 // taken to use for whatever purposes you like by 00843 // calling get_connection(). 00844 // 00845 // This establishes a blocking I/O socket. Also see 00846 // begin_connect_to(). 00847 //////////////////////////////////////////////////////////////////// 00848 INLINE bool HTTPChannel:: 00849 connect_to(const DocumentSpec &url) { 00850 begin_request(HTTPEnum::M_connect, url, string(), false, 0, 0); 00851 while (run()) { 00852 } 00853 return is_connection_ready(); 00854 } 00855 00856 //////////////////////////////////////////////////////////////////// 00857 // Function: HTTPChannel::get_options 00858 // Access: Published 00859 // Description: Sends an OPTIONS message to the server, which should 00860 // query the available options, possibly in relation to 00861 // a specified URL. 00862 //////////////////////////////////////////////////////////////////// 00863 INLINE bool HTTPChannel:: 00864 get_options(const DocumentSpec &url) { 00865 begin_request(HTTPEnum::M_options, url, string(), false, 0, 0); 00866 while (run()) { 00867 } 00868 return is_valid(); 00869 } 00870 00871 //////////////////////////////////////////////////////////////////// 00872 // Function: HTTPChannel::begin_get_document 00873 // Access: Published 00874 // Description: Begins a non-blocking request to retrieve a given 00875 // document. This method will return immediately, even 00876 // before a connection to the server has necessarily 00877 // been established; you must then call run() from time 00878 // to time until the return value of run() is false. 00879 // Then you may check is_valid() and get_status_code() 00880 // to determine the status of your request. 00881 // 00882 // If a previous request had been pending, that request 00883 // is discarded. 00884 //////////////////////////////////////////////////////////////////// 00885 INLINE void HTTPChannel:: 00886 begin_get_document(const DocumentSpec &url) { 00887 begin_request(HTTPEnum::M_get, url, string(), true, 0, 0); 00888 } 00889 00890 //////////////////////////////////////////////////////////////////// 00891 // Function: HTTPChannel::begin_get_subdocument 00892 // Access: Published 00893 // Description: Begins a non-blocking request to retrieve only the 00894 // specified byte range of the indicated document. If 00895 // last_byte is 0, it stands for the last byte of the 00896 // document. When a subdocument is requested, 00897 // get_file_size() and get_bytes_downloaded() will 00898 // report the number of bytes of the subdocument, not of 00899 // the complete document. 00900 //////////////////////////////////////////////////////////////////// 00901 INLINE void HTTPChannel:: 00902 begin_get_subdocument(const DocumentSpec &url, size_t first_byte, 00903 size_t last_byte) { 00904 begin_request(HTTPEnum::M_get, url, string(), true, first_byte, last_byte); 00905 } 00906 00907 //////////////////////////////////////////////////////////////////// 00908 // Function: HTTPChannel::begin_get_header 00909 // Access: Published 00910 // Description: Begins a non-blocking request to retrieve a given 00911 // header. See begin_get_document() and get_header(). 00912 //////////////////////////////////////////////////////////////////// 00913 INLINE void HTTPChannel:: 00914 begin_get_header(const DocumentSpec &url) { 00915 begin_request(HTTPEnum::M_head, url, string(), true, 0, 0); 00916 } 00917 00918 //////////////////////////////////////////////////////////////////// 00919 // Function: HTTPChannel::begin_post_form 00920 // Access: Published 00921 // Description: Posts form data to a particular URL and retrieves the 00922 // response, all using non-blocking I/O. See 00923 // begin_get_document() and post_form(). 00924 // 00925 // It is important to note that you *must* call run() 00926 // repeatedly after calling this method until run() 00927 // returns false, and you may not call any other 00928 // document posting or retrieving methods using the 00929 // HTTPChannel object in the interim, or your form data 00930 // may not get posted. 00931 //////////////////////////////////////////////////////////////////// 00932 INLINE void HTTPChannel:: 00933 begin_post_form(const DocumentSpec &url, const string &body) { 00934 begin_request(HTTPEnum::M_post, url, body, true, 0, 0); 00935 } 00936 00937 //////////////////////////////////////////////////////////////////// 00938 // Function: HTTPChannel::begin_connect_to 00939 // Access: Published 00940 // Description: Begins a non-blocking request to establish a direct 00941 // connection to the server and port indicated by the 00942 // URL. No HTTP requests will be issued beyond what is 00943 // necessary to establish the connection. When run() 00944 // has finished, you may call is_connection_ready() to 00945 // determine if the connection was successfully 00946 // established. 00947 // 00948 // If successful, the connection may then be taken to 00949 // use for whatever purposes you like by calling 00950 // get_connection(). 00951 // 00952 // This establishes a nonblocking I/O socket. Also see 00953 // connect_to(). 00954 //////////////////////////////////////////////////////////////////// 00955 INLINE void HTTPChannel:: 00956 begin_connect_to(const DocumentSpec &url) { 00957 begin_request(HTTPEnum::M_connect, url, string(), true, 0, 0); 00958 } 00959 00960 //////////////////////////////////////////////////////////////////// 00961 // Function: HTTPChannel::get_bytes_downloaded 00962 // Access: Published 00963 // Description: Returns the number of bytes downloaded during the 00964 // last (or current) download_to_file() or 00965 // download_to_ram operation(). This can be used in 00966 // conjunction with get_file_size() to report the 00967 // percent complete (but be careful, since 00968 // get_file_size() may return 0 if the server has not 00969 // told us the size of the file). 00970 //////////////////////////////////////////////////////////////////// 00971 INLINE size_t HTTPChannel:: 00972 get_bytes_downloaded() const { 00973 return _bytes_downloaded; 00974 } 00975 00976 //////////////////////////////////////////////////////////////////// 00977 // Function: HTTPChannel::get_bytes_requested 00978 // Access: Published 00979 // Description: When download throttling is in effect 00980 // (set_download_throttle() has been set to true) and 00981 // non-blocking I/O methods (like begin_get_document()) 00982 // are used, this returns the number of bytes 00983 // "requested" from the server so far: that is, the 00984 // theoretical maximum value for get_bytes_downloaded(), 00985 // if the server has been keeping up with our demand. 00986 // 00987 // If this number is less than get_bytes_downloaded(), 00988 // then the server has not been supplying bytes fast 00989 // enough to meet our own download throttle rate. 00990 // 00991 // When download throttling is not in effect, or when 00992 // the blocking I/O methods (like get_document(), etc.) 00993 // are used, this returns 0. 00994 //////////////////////////////////////////////////////////////////// 00995 INLINE size_t HTTPChannel:: 00996 get_bytes_requested() const { 00997 return _bytes_requested; 00998 } 00999 01000 //////////////////////////////////////////////////////////////////// 01001 // Function: HTTPChannel::is_download_complete 01002 // Access: Published 01003 // Description: Returns true when a download_to() or 01004 // download_to_ram() has executed and the file has been 01005 // fully downloaded. If this still returns false after 01006 // processing has completed, there was an error in 01007 // transmission. 01008 // 01009 // Note that simply testing is_download_complete() does 01010 // not prove that the requested document was successfully 01011 // retrieved--you might have just downloaded the "404 01012 // not found" stub (for instance) that a server would 01013 // provide in response to some error condition. You 01014 // should also check is_valid() to prove that the file 01015 // you expected has been successfully retrieved. 01016 //////////////////////////////////////////////////////////////////// 01017 INLINE bool HTTPChannel:: 01018 is_download_complete() const { 01019 return (_download_dest != DD_none && 01020 (_state == S_read_body || _state == S_read_trailer)); 01021 } 01022 01023 //////////////////////////////////////////////////////////////////// 01024 // Function: HTTPChannel::StatusEntry::Constructor 01025 // Access: Public 01026 // Description: 01027 //////////////////////////////////////////////////////////////////// 01028 INLINE HTTPChannel::StatusEntry:: 01029 StatusEntry() { 01030 _status_code = SC_incomplete; 01031 }