Panda3D

httpChannel.I

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 }
 All Classes Functions Variables Enumerations