Panda3D
 All Classes Functions Variables Enumerations
httpChannel.I
1 // Filename: httpChannel.I
2 // Created by: drose (24Sep02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: HTTPChannel::get_client
18 // Access: Published
19 // Description: Returns the HTTPClient object that owns this channel.
20 ////////////////////////////////////////////////////////////////////
21 INLINE HTTPClient *HTTPChannel::
22 get_client() const {
23  return _client;
24 }
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: HTTPChannel::is_valid
28 // Access: Published
29 // Description: Returns true if the last-requested document was
30 // successfully retrieved and is ready to be read, false
31 // otherwise.
32 ////////////////////////////////////////////////////////////////////
33 INLINE bool HTTPChannel::
34 is_valid() const {
35  return (_state != S_failure && (get_status_code() / 100) == 2 &&
36  (_server_response_has_no_body || !_source.is_null()));
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: HTTPChannel::is_connection_ready
41 // Access: Published
42 // Description: Returns true if a connection has been established to
43 // the named server in a previous call to connect_to()
44 // or begin_connect_to(), false otherwise.
45 ////////////////////////////////////////////////////////////////////
46 INLINE bool HTTPChannel::
47 is_connection_ready() const {
48  return (!_source.is_null() && _state == S_ready);
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: HTTPChannel::get_url
53 // Access: Published
54 // Description: Returns the URL that was used to retrieve the
55 // most recent document: whatever URL was last passed to
56 // get_document() or get_header(). If a redirect has
57 // transparently occurred, this will return the new,
58 // redirected URL (the actual URL at which the document
59 // was located).
60 ////////////////////////////////////////////////////////////////////
61 INLINE const URLSpec &HTTPChannel::
62 get_url() const {
63  return _document_spec.get_url();
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: HTTPChannel::get_document_spec
68 // Access: Published
69 // Description: Returns the DocumentSpec associated with the most
70 // recent document. This includes its actual URL
71 // (following redirects) along with the identity tag and
72 // last-modified date, if supplied by the server.
73 //
74 // This structure may be saved and used to retrieve the
75 // same version of the document later, or to
76 // conditionally retrieve a newer version if it is
77 // available.
78 ////////////////////////////////////////////////////////////////////
79 INLINE const DocumentSpec &HTTPChannel::
80 get_document_spec() const {
81  return _document_spec;
82 }
83 
84 ////////////////////////////////////////////////////////////////////
85 // Function: HTTPChannel::get_http_version
86 // Access: Published
87 // Description: Returns the HTTP version number returned by the
88 // server, as one of the HTTPClient enumerated types,
89 // e.g. HTTPClient::HV_11.
90 ////////////////////////////////////////////////////////////////////
91 INLINE HTTPEnum::HTTPVersion HTTPChannel::
92 get_http_version() const {
93  return _http_version;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: HTTPChannel::get_http_version_string
98 // Access: Published
99 // Description: Returns the HTTP version number returned by the
100 // server, formatted as a string, e.g. "HTTP/1.1".
101 ////////////////////////////////////////////////////////////////////
102 INLINE const string &HTTPChannel::
103 get_http_version_string() const {
104  return _http_version_string;
105 }
106 
107 ////////////////////////////////////////////////////////////////////
108 // Function: HTTPChannel::get_status_code
109 // Access: Published
110 // Description: Returns the HTML return code from the document
111 // retrieval request. This will be in the 200 range if
112 // the document is successfully retrieved, or some other
113 // value in the case of an error.
114 //
115 // Some proxy errors during an https-over-proxy request
116 // would return the same status code as a different
117 // error that occurred on the host server. To
118 // differentiate these cases, status codes that are
119 // returned by the proxy during the CONNECT phase
120 // (except code 407) are incremented by 1000.
121 ////////////////////////////////////////////////////////////////////
122 INLINE int HTTPChannel::
123 get_status_code() const {
124  return _status_entry._status_code;
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function: HTTPChannel::get_www_realm
129 // Access: Published
130 // Description: If the document failed to connect because of a 401
131 // (Authorization required), this method will return the
132 // "realm" returned by the server in which the requested
133 // document must be authenticated. This string may be
134 // presented to the user to request an associated
135 // username and password (which then should be stored in
136 // HTTPClient::set_username()).
137 ////////////////////////////////////////////////////////////////////
138 INLINE const string &HTTPChannel::
139 get_www_realm() const {
140  return _www_realm;
141 }
142 
143 ////////////////////////////////////////////////////////////////////
144 // Function: HTTPChannel::get_proxy_realm
145 // Access: Published
146 // Description: If the document failed to connect because of a 407
147 // (Proxy authorization required), this method will
148 // return the "realm" returned by the proxy. This
149 // string may be presented to the user to request an
150 // associated username and password (which then should
151 // be stored in HTTPClient::set_username()).
152 ////////////////////////////////////////////////////////////////////
153 INLINE const string &HTTPChannel::
154 get_proxy_realm() const {
155  return _proxy_realm;
156 }
157 
158 ////////////////////////////////////////////////////////////////////
159 // Function: HTTPChannel::get_redirect
160 // Access: Published
161 // Description: If the document failed with a redirect code (300
162 // series), this will generally contain the new URL the
163 // server wants us to try. In many cases, the client
164 // will automatically follow redirects; if these are
165 // successful the client will return a successful code
166 // and get_redirect() will return empty, but get_url()
167 // will return the new, redirected URL.
168 ////////////////////////////////////////////////////////////////////
169 INLINE const URLSpec &HTTPChannel::
170 get_redirect() const {
171  return _redirect;
172 }
173 
174 ////////////////////////////////////////////////////////////////////
175 // Function: HTTPChannel::get_num_redirect_steps
176 // Access: Published
177 // Description: If the document automatically followed one or more
178 // redirects, this will return the number of redirects
179 // that were automatically followed. Use
180 // get_redirect_step() to retrieve each URL in
181 // sequence.
182 ////////////////////////////////////////////////////////////////////
183 INLINE int HTTPChannel::
184 get_num_redirect_steps() const {
185  return _redirect_trail.size();
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function: HTTPChannel::get_redirect_step
190 // Access: Published
191 // Description: Use in conjunction with get_num_redirect_steps() to
192 // extract the chain of URL's that the channel was
193 // automatically redirected through to arrive at the
194 // final document.
195 ////////////////////////////////////////////////////////////////////
196 INLINE const URLSpec &HTTPChannel::
197 get_redirect_step(int n) const {
198  nassertr(n >= 0 && n < (int)_redirect_trail.size(), _redirect_trail[0]);
199  return _redirect_trail[n];
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: HTTPChannel::set_persistent_connection
204 // Access: Published
205 // Description: Indicates whether the HTTPChannel should try to keep
206 // the connection to the server open and reuse that
207 // connection for multiple documents, or whether it
208 // should close the connection and open a new one for
209 // each request. Set this true to keep the connections
210 // around when possible, false to recycle them.
211 //
212 // It makes most sense to set this false when the
213 // HTTPChannel will be used only once to retrieve a
214 // single document, true when you will be using the same
215 // HTTPChannel object to retrieve multiple documents.
216 ////////////////////////////////////////////////////////////////////
217 INLINE void HTTPChannel::
218 set_persistent_connection(bool persistent_connection) {
219  _persistent_connection = persistent_connection;
220 }
221 
222 ////////////////////////////////////////////////////////////////////
223 // Function: HTTPChannel::get_persistent_connection
224 // Access: Published
225 // Description: Returns whether the HTTPChannel should try to keep
226 // the connection to the server open and reuse that
227 // connection for multiple documents, or whether it
228 // should close the connection and open a new one for
229 // each request. See set_persistent_connection().
230 ////////////////////////////////////////////////////////////////////
231 INLINE bool HTTPChannel::
232 get_persistent_connection() const {
233  return _persistent_connection;
234 }
235 
236 ////////////////////////////////////////////////////////////////////
237 // Function: HTTPChannel::set_allow_proxy
238 // Access: Published
239 // Description: If this is true (the normal case), the HTTPClient
240 // will be consulted for information about the proxy to
241 // be used for each connection via this HTTPChannel. If
242 // this has been set to false by the user, then all
243 // connections will be made directly, regardless of the
244 // proxy settings indicated on the HTTPClient.
245 ////////////////////////////////////////////////////////////////////
246 INLINE void HTTPChannel::
247 set_allow_proxy(bool allow_proxy) {
248  _allow_proxy = allow_proxy;
249 }
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: HTTPChannel::get_allow_proxy
253 // Access: Published
254 // Description: If this is true (the normal case), the HTTPClient
255 // will be consulted for information about the proxy to
256 // be used for each connection via this HTTPChannel. If
257 // this has been set to false by the user, then all
258 // connections will be made directly, regardless of the
259 // proxy settings indicated on the HTTPClient.
260 ////////////////////////////////////////////////////////////////////
261 INLINE bool HTTPChannel::
262 get_allow_proxy() const {
263  return _allow_proxy;
264 }
265 
266 ////////////////////////////////////////////////////////////////////
267 // Function: HTTPChannel::set_proxy_tunnel
268 // Access: Published
269 // Description: Normally, a proxy is itself asked for ordinary URL's,
270 // and the proxy decides whether to hand the client a
271 // cached version of the document or to contact the
272 // server for a fresh version. The proxy may also
273 // modify the headers and transfer encoding on the way.
274 //
275 // If this is set to true, then instead of asking for
276 // URL's from the proxy, we will ask the proxy to open a
277 // connection to the server (for instance, on port 80);
278 // if the proxy honors this request, then we contact the
279 // server directly through this connection to retrieve
280 // the document. If the proxy does not honor the
281 // connect request, then the retrieve operation fails.
282 //
283 // SSL connections (e.g. https), and connections through
284 // a Socks proxy, are always tunneled, regardless of the
285 // setting of this flag.
286 ////////////////////////////////////////////////////////////////////
287 INLINE void HTTPChannel::
288 set_proxy_tunnel(bool proxy_tunnel) {
289  _proxy_tunnel = proxy_tunnel;
290 }
291 
292 ////////////////////////////////////////////////////////////////////
293 // Function: HTTPChannel::get_proxy_tunnel
294 // Access: Published
295 // Description: Returns true if connections always tunnel through a
296 // proxy, or false (the normal case) if we allow the
297 // proxy to serve up documents. See set_proxy_tunnel().
298 ////////////////////////////////////////////////////////////////////
299 INLINE bool HTTPChannel::
300 get_proxy_tunnel() const {
301  return _proxy_tunnel;
302 }
303 
304 ////////////////////////////////////////////////////////////////////
305 // Function: HTTPChannel::set_connect_timeout
306 // Access: Published
307 // Description: Sets the maximum length of time, in seconds, that the
308 // channel will wait before giving up on establishing a
309 // TCP connection.
310 //
311 // At present, this is used only for the nonblocking
312 // interfaces (e.g. begin_get_document(),
313 // begin_connect_to()), but it is used whether
314 // set_blocking_connect() is true or false.
315 ////////////////////////////////////////////////////////////////////
316 INLINE void HTTPChannel::
317 set_connect_timeout(double connect_timeout) {
318  _connect_timeout = connect_timeout;
319 }
320 
321 ////////////////////////////////////////////////////////////////////
322 // Function: HTTPChannel::get_connect_timeout
323 // Access: Published
324 // Description: Returns the length of time, in seconds, to wait for a
325 // new nonblocking socket to connect. See
326 // set_connect_timeout().
327 ////////////////////////////////////////////////////////////////////
328 INLINE double HTTPChannel::
329 get_connect_timeout() const {
330  return _connect_timeout;
331 }
332 
333 ////////////////////////////////////////////////////////////////////
334 // Function: HTTPChannel::set_blocking_connect
335 // Access: Published
336 // Description: If this flag is true, a socket connect will block
337 // even for nonblocking I/O calls like
338 // begin_get_document(), begin_connect_to(), etc. If
339 // false, a socket connect will not block for
340 // nonblocking I/O calls, but will block for blocking
341 // I/O calls (get_document(), connect_to(), etc.).
342 //
343 // Setting this true is useful when you want to use
344 // non-blocking I/O once you have established the
345 // connection, but you don't want to bother with polling
346 // for the initial connection. It's also useful when
347 // you don't particularly care about non-blocking I/O,
348 // but you need to respect timeouts like connect_timeout
349 // and http_timeout.
350 ////////////////////////////////////////////////////////////////////
351 INLINE void HTTPChannel::
352 set_blocking_connect(bool blocking_connect) {
353  _blocking_connect = blocking_connect;
354 }
355 
356 ////////////////////////////////////////////////////////////////////
357 // Function: HTTPChannel::get_blocking_connect
358 // Access: Published
359 // Description: If this flag is true, a socket connect will block
360 // even for nonblocking I/O calls like
361 // begin_get_document(), begin_connect_to(), etc. If
362 // false, a socket connect will not block for
363 // nonblocking I/O calls, but will block for blocking
364 // I/O calls (get_document(), connect_to(), etc.).
365 ////////////////////////////////////////////////////////////////////
366 INLINE bool HTTPChannel::
367 get_blocking_connect() const {
368  return _blocking_connect;
369 }
370 
371 ////////////////////////////////////////////////////////////////////
372 // Function: HTTPChannel::set_http_timeout
373 // Access: Published
374 // Description: Sets the maximum length of time, in seconds, that the
375 // channel will wait for the HTTP server to finish
376 // sending its response to our request.
377 //
378 // The timer starts counting after the TCP connection
379 // has been established (see set_connect_timeout(),
380 // above) and the request has been sent.
381 //
382 // At present, this is used only for the nonblocking
383 // interfaces (e.g. begin_get_document(),
384 // begin_connect_to()), but it is used whether
385 // set_blocking_connect() is true or false.
386 ////////////////////////////////////////////////////////////////////
387 INLINE void HTTPChannel::
388 set_http_timeout(double http_timeout) {
389  _http_timeout = http_timeout;
390 }
391 
392 ////////////////////////////////////////////////////////////////////
393 // Function: HTTPChannel::get_http_timeout
394 // Access: Published
395 // Description: Returns the length of time, in seconds, to wait for
396 // the HTTP server to respond to our request. See
397 // set_http_timeout().
398 ////////////////////////////////////////////////////////////////////
399 INLINE double HTTPChannel::
400 get_http_timeout() const {
401  return _http_timeout;
402 }
403 
404 ////////////////////////////////////////////////////////////////////
405 // Function: HTTPChannel::set_skip_body_size
406 // Access: Published
407 // Description: Specifies the maximum number of bytes in a received
408 // (but unwanted) body that will be skipped past, in
409 // order to reset to a new request.
410 //
411 // That is, if this HTTPChannel requests a file via
412 // get_document(), but does not call download_to_ram(),
413 // download_to_file(), or open_read_body(), and instead
414 // immediately requests a new file, then the HTTPChannel
415 // has a choice whether to skip past the unwanted
416 // document, or to close the connection and open a new
417 // one. If the number of bytes to skip is more than
418 // this threshold, the connection will be closed;
419 // otherwise, the data will simply be read and
420 // discarded.
421 ////////////////////////////////////////////////////////////////////
422 INLINE void HTTPChannel::
423 set_skip_body_size(size_t skip_body_size) {
424  _skip_body_size = skip_body_size;
425 }
426 
427 ////////////////////////////////////////////////////////////////////
428 // Function: HTTPChannel::get_skip_body_size
429 // Access: Published
430 // Description: Returns the maximum number of bytes in a received
431 // (but unwanted) body that will be skipped past, in
432 // order to reset to a new request. See
433 // set_skip_body_size().
434 ////////////////////////////////////////////////////////////////////
435 INLINE size_t HTTPChannel::
436 get_skip_body_size() const {
437  return _skip_body_size;
438 }
439 
440 ////////////////////////////////////////////////////////////////////
441 // Function: HTTPChannel::set_idle_timeout
442 // Access: Published
443 // Description: Specifies the amount of time, in seconds, in which a
444 // previously-established connection is allowed to
445 // remain open and unused. If a previous connection has
446 // remained unused for at least this number of seconds,
447 // it will be closed and a new connection will be
448 // opened; otherwise, the same connection will be reused
449 // for the next request (for this particular
450 // HTTPChannel).
451 ////////////////////////////////////////////////////////////////////
452 INLINE void HTTPChannel::
453 set_idle_timeout(double idle_timeout) {
454  _idle_timeout = idle_timeout;
455 }
456 
457 ////////////////////////////////////////////////////////////////////
458 // Function: HTTPChannel::get_idle_timeout
459 // Access: Published
460 // Description: Returns the amount of time, in seconds, in which an
461 // previously-established connection is allowed to
462 // remain open and unused. See set_idle_timeout().
463 ////////////////////////////////////////////////////////////////////
464 INLINE double HTTPChannel::
465 get_idle_timeout() const {
466  return _idle_timeout;
467 }
468 
469 ////////////////////////////////////////////////////////////////////
470 // Function: HTTPChannel::set_download_throttle
471 // Access: Published
472 // Description: Specifies whether nonblocking downloads (via
473 // download_to_file() or download_to_ram()) will be
474 // limited so as not to use all available bandwidth.
475 //
476 // If this is true, when a download has been started on
477 // this channel it will be invoked no more frequently
478 // than get_max_updates_per_second(), and the total
479 // bandwidth used by the download will be no more than
480 // get_max_bytes_per_second(). If this is false,
481 // downloads will proceed as fast as the server can send
482 // the data.
483 //
484 // This only has effect on the nonblocking I/O methods
485 // like begin_get_document(), etc. The blocking methods
486 // like get_document() always use as much CPU and
487 // bandwidth as they can get.
488 ////////////////////////////////////////////////////////////////////
489 INLINE void HTTPChannel::
490 set_download_throttle(bool download_throttle) {
491  _download_throttle = download_throttle;
492 }
493 
494 ////////////////////////////////////////////////////////////////////
495 // Function: HTTPChannel::get_download_throttle
496 // Access: Published
497 // Description: Returns whether the nonblocking downloads will be
498 // bandwidth-limited. See set_download_throttle().
499 ////////////////////////////////////////////////////////////////////
500 INLINE bool HTTPChannel::
501 get_download_throttle() const {
502  return _download_throttle;
503 }
504 
505 ////////////////////////////////////////////////////////////////////
506 // Function: HTTPChannel::set_max_bytes_per_second
507 // Access: Published
508 // Description: When bandwidth throttling is in effect (see
509 // set_download_throttle()), this specifies the maximum
510 // number of bytes per second that may be consumed by
511 // this channel.
512 ////////////////////////////////////////////////////////////////////
513 INLINE void HTTPChannel::
514 set_max_bytes_per_second(double max_bytes_per_second) {
515  _max_bytes_per_second = max_bytes_per_second;
516  _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
517 }
518 
519 ////////////////////////////////////////////////////////////////////
520 // Function: HTTPChannel::get_max_bytes_per_second
521 // Access: Published
522 // Description: Returns the maximum number of bytes per second that
523 // may be consumed by this channel when
524 // get_download_throttle() is true.
525 ////////////////////////////////////////////////////////////////////
526 INLINE double HTTPChannel::
527 get_max_bytes_per_second() const {
528  return _max_bytes_per_second;
529 }
530 
531 ////////////////////////////////////////////////////////////////////
532 // Function: HTTPChannel::set_max_updates_per_second
533 // Access: Published
534 // Description: When bandwidth throttling is in effect (see
535 // set_download_throttle()), this specifies the maximum
536 // number of times per second that run() will attempt to
537 // do any downloading at all.
538 ////////////////////////////////////////////////////////////////////
539 INLINE void HTTPChannel::
540 set_max_updates_per_second(double max_updates_per_second) {
541  nassertv(max_updates_per_second != 0.0f);
542  _max_updates_per_second = max_updates_per_second;
543  _seconds_per_update = 1.0f / _max_updates_per_second;
544  _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
545 }
546 
547 ////////////////////////////////////////////////////////////////////
548 // Function: HTTPChannel::get_max_updates_per_second
549 // Access: Published
550 // Description: Returns the maximum number of times per second that
551 // run() will do anything at all, when
552 // get_download_throttle() is true.
553 ////////////////////////////////////////////////////////////////////
554 INLINE double HTTPChannel::
555 get_max_updates_per_second() const {
556  return _max_updates_per_second;
557 }
558 
559 ////////////////////////////////////////////////////////////////////
560 // Function: HTTPChannel::set_expected_file_size
561 // Access: Published
562 // Description: This may be called immediately after a call to
563 // get_document() or some related function to specify
564 // the expected size of the document we are retrieving,
565 // if we happen to know. This is used as the return
566 // value to get_file_size() only in the case that the
567 // server does not tell us the actual file size.
568 ////////////////////////////////////////////////////////////////////
569 INLINE void HTTPChannel::
570 set_expected_file_size(size_t file_size) {
571  _expected_file_size = file_size;
572  _got_expected_file_size = true;
573 }
574 
575 
576 ////////////////////////////////////////////////////////////////////
577 // Function: HTTPChannel::is_file_size_known
578 // Access: Published
579 // Description: Returns true if the size of the file we are currently
580 // retrieving was told us by the server and thus is
581 // reliably known, or false if the size reported by
582 // get_file_size() represents an educated guess
583 // (possibly as set by set_expected_file_size(), or as
584 // inferred from a chunked transfer encoding in
585 // progress).
586 ////////////////////////////////////////////////////////////////////
587 INLINE bool HTTPChannel::
588 is_file_size_known() const {
589  return _got_file_size;
590 }
591 
592 ////////////////////////////////////////////////////////////////////
593 // Function: HTTPChannel::get_first_byte_requested
594 // Access: Published
595 // Description: Returns the first byte of the file requested by the
596 // request. This will normally be 0 to indicate that
597 // the file is being requested from the beginning, but
598 // if the file was requested via a get_subdocument()
599 // call, this will contain the first_byte parameter from
600 // that call.
601 ////////////////////////////////////////////////////////////////////
602 INLINE size_t HTTPChannel::
603 get_first_byte_requested() const {
604  return _first_byte_requested;
605 }
606 
607 ////////////////////////////////////////////////////////////////////
608 // Function: HTTPChannel::get_last_byte_requested
609 // Access: Published
610 // Description: Returns the last byte of the file requested by the
611 // request. This will normally be 0 to indicate that
612 // the file is being requested to its last byte, but if
613 // the file was requested via a get_subdocument() call,
614 // this will contain the last_byte parameter from that
615 // call.
616 ////////////////////////////////////////////////////////////////////
617 INLINE size_t HTTPChannel::
618 get_last_byte_requested() const {
619  return _last_byte_requested;
620 }
621 
622 ////////////////////////////////////////////////////////////////////
623 // Function: HTTPChannel::get_first_byte_delivered
624 // Access: Published
625 // Description: Returns the first byte of the file (that will be)
626 // delivered by the server in response to the current
627 // request. Normally, this is the same as
628 // get_first_byte_requested(), but some servers will
629 // ignore a subdocument request and always return the
630 // whole file, in which case this value will be 0,
631 // regardless of what was requested to
632 // get_subdocument().
633 ////////////////////////////////////////////////////////////////////
634 INLINE size_t HTTPChannel::
635 get_first_byte_delivered() const {
636  return _first_byte_delivered;
637 }
638 
639 ////////////////////////////////////////////////////////////////////
640 // Function: HTTPChannel::get_last_byte_delivered
641 // Access: Published
642 // Description: Returns the last byte of the file (that will be)
643 // delivered by the server in response to the current
644 // request. Normally, this is the same as
645 // get_last_byte_requested(), but some servers will
646 // ignore a subdocument request and always return the
647 // whole file, in which case this value will be 0,
648 // regardless of what was requested to
649 // get_subdocument().
650 ////////////////////////////////////////////////////////////////////
651 INLINE size_t HTTPChannel::
652 get_last_byte_delivered() const {
653  return _last_byte_delivered;
654 }
655 
656 ////////////////////////////////////////////////////////////////////
657 // Function: HTTPChannel::reset
658 // Access: Published
659 // Description: Stops whatever file transaction is currently in
660 // progress, closes the connection, and resets to begin
661 // anew. You shouldn't ever need to call this, since
662 // the channel should be able to reset itself cleanly
663 // between requests, but it is provided in case you are
664 // an especially nervous type.
665 //
666 // Don't call this after every request unless you set
667 // set_persistent_connection() to false, since calling
668 // reset() rudely closes the connection regardless of
669 // whether we have told the server we intend to keep it
670 // open or not.
671 ////////////////////////////////////////////////////////////////////
672 INLINE void HTTPChannel::
673 reset() {
674  reset_for_new_request();
675  reset_to_new();
676  _status_list.clear();
677 }
678 
679 ////////////////////////////////////////////////////////////////////
680 // Function: HTTPChannel::preserve_status
681 // Access: Published
682 // Description: Preserves the previous status code (presumably a
683 // failure) from the previous connection attempt. If
684 // the subsequent connection attempt also fails, the
685 // returned status code will be the better of the
686 // previous code and the current code.
687 //
688 // This can be called to daisy-chain subsequent attempts
689 // to download the same document from different servers.
690 // After all servers have been attempted, the final
691 // status code will reflect the attempt that most nearly
692 // succeeded.
693 ////////////////////////////////////////////////////////////////////
694 INLINE void HTTPChannel::
695 preserve_status() {
696  _status_list.push_back(_status_entry);
697 }
698 
699 
700 ////////////////////////////////////////////////////////////////////
701 // Function: HTTPChannel::clear_extra_headers
702 // Access: Published
703 // Description: Resets the extra headers that were previously added
704 // via calls to send_extra_header().
705 ////////////////////////////////////////////////////////////////////
706 INLINE void HTTPChannel::
707 clear_extra_headers() {
708  _send_extra_headers = string();
709 }
710 
711 ////////////////////////////////////////////////////////////////////
712 // Function: HTTPChannel::send_extra_header
713 // Access: Published
714 // Description: Specifies an additional key: value pair that is added
715 // into the header sent to the server with the next
716 // request. This is passed along with no interpretation
717 // by the HTTPChannel code. You may call this
718 // repeatedly to append multiple headers.
719 //
720 // This is persistent for one request only; it must be
721 // set again for each new request.
722 ////////////////////////////////////////////////////////////////////
723 INLINE void HTTPChannel::
724 send_extra_header(const string &key, const string &value) {
725  _send_extra_headers += key;
726  _send_extra_headers += ": ";
727  _send_extra_headers += value;
728  _send_extra_headers += "\r\n";
729 }
730 
731 ////////////////////////////////////////////////////////////////////
732 // Function: HTTPChannel::get_document
733 // Access: Published
734 // Description: Opens the named document for reading, if available.
735 // Returns true if successful, false otherwise.
736 ////////////////////////////////////////////////////////////////////
737 INLINE bool HTTPChannel::
738 get_document(const DocumentSpec &url) {
739  begin_request(HTTPEnum::M_get, url, string(), false, 0, 0);
740  while (run()) {
741  }
742  return is_valid();
743 }
744 
745 ////////////////////////////////////////////////////////////////////
746 // Function: HTTPChannel::get_subdocument
747 // Access: Published
748 // Description: Retrieves only the specified byte range of the
749 // indicated document. If last_byte is 0, it stands for
750 // the last byte of the document. When a subdocument is
751 // requested, get_file_size() and get_bytes_downloaded()
752 // will report the number of bytes of the subdocument,
753 // not of the complete document.
754 ////////////////////////////////////////////////////////////////////
755 INLINE bool HTTPChannel::
756 get_subdocument(const DocumentSpec &url, size_t first_byte, size_t last_byte) {
757  begin_request(HTTPEnum::M_get, url, string(), false, first_byte, last_byte);
758  while (run()) {
759  }
760  return is_valid();
761 }
762 
763 ////////////////////////////////////////////////////////////////////
764 // Function: HTTPChannel::get_header
765 // Access: Published
766 // Description: Like get_document(), except only the header
767 // associated with the document is retrieved. This may
768 // be used to test for existence of the document; it
769 // might also return the size of the document (if the
770 // server gives us this information).
771 ////////////////////////////////////////////////////////////////////
772 INLINE bool HTTPChannel::
773 get_header(const DocumentSpec &url) {
774  begin_request(HTTPEnum::M_head, url, string(), false, 0, 0);
775  while (run()) {
776  }
777  return is_valid();
778 }
779 
780 ////////////////////////////////////////////////////////////////////
781 // Function: HTTPChannel::post_form
782 // Access: Published
783 // Description: Posts form data to a particular URL and retrieves the
784 // response.
785 ////////////////////////////////////////////////////////////////////
786 INLINE bool HTTPChannel::
787 post_form(const DocumentSpec &url, const string &body) {
788  begin_request(HTTPEnum::M_post, url, body, false, 0, 0);
789  while (run()) {
790  }
791  return is_valid();
792 }
793 
794 ////////////////////////////////////////////////////////////////////
795 // Function: HTTPChannel::put_document
796 // Access: Published
797 // Description: Uploads the indicated body to the server to replace
798 // the indicated URL, if the server allows this.
799 ////////////////////////////////////////////////////////////////////
800 INLINE bool HTTPChannel::
801 put_document(const DocumentSpec &url, const string &body) {
802  begin_request(HTTPEnum::M_put, url, body, false, 0, 0);
803  while (run()) {
804  }
805  return is_valid();
806 }
807 
808 ////////////////////////////////////////////////////////////////////
809 // Function: HTTPChannel::delete_document
810 // Access: Published
811 // Description: Requests the server to remove the indicated URL.
812 ////////////////////////////////////////////////////////////////////
813 INLINE bool HTTPChannel::
814 delete_document(const DocumentSpec &url) {
815  begin_request(HTTPEnum::M_delete, url, string(), false, 0, 0);
816  while (run()) {
817  }
818  return is_valid();
819 }
820 
821 ////////////////////////////////////////////////////////////////////
822 // Function: HTTPChannel::get_trace
823 // Access: Published
824 // Description: Sends a TRACE message to the server, which should
825 // return back the same message as the server received
826 // it, allowing inspection of proxy hops, etc.
827 ////////////////////////////////////////////////////////////////////
828 INLINE bool HTTPChannel::
829 get_trace(const DocumentSpec &url) {
830  begin_request(HTTPEnum::M_trace, url, string(), false, 0, 0);
831  while (run()) {
832  }
833  return is_valid();
834 }
835 
836 ////////////////////////////////////////////////////////////////////
837 // Function: HTTPChannel::connect_to
838 // Access: Published
839 // Description: Establish a direct connection to the server and port
840 // indicated by the URL, but do not issue any HTTP
841 // requests. If successful, the connection may then be
842 // taken to use for whatever purposes you like by
843 // calling get_connection().
844 //
845 // This establishes a blocking I/O socket. Also see
846 // begin_connect_to().
847 ////////////////////////////////////////////////////////////////////
848 INLINE bool HTTPChannel::
849 connect_to(const DocumentSpec &url) {
850  begin_request(HTTPEnum::M_connect, url, string(), false, 0, 0);
851  while (run()) {
852  }
853  return is_connection_ready();
854 }
855 
856 ////////////////////////////////////////////////////////////////////
857 // Function: HTTPChannel::get_options
858 // Access: Published
859 // Description: Sends an OPTIONS message to the server, which should
860 // query the available options, possibly in relation to
861 // a specified URL.
862 ////////////////////////////////////////////////////////////////////
863 INLINE bool HTTPChannel::
864 get_options(const DocumentSpec &url) {
865  begin_request(HTTPEnum::M_options, url, string(), false, 0, 0);
866  while (run()) {
867  }
868  return is_valid();
869 }
870 
871 ////////////////////////////////////////////////////////////////////
872 // Function: HTTPChannel::begin_get_document
873 // Access: Published
874 // Description: Begins a non-blocking request to retrieve a given
875 // document. This method will return immediately, even
876 // before a connection to the server has necessarily
877 // been established; you must then call run() from time
878 // to time until the return value of run() is false.
879 // Then you may check is_valid() and get_status_code()
880 // to determine the status of your request.
881 //
882 // If a previous request had been pending, that request
883 // is discarded.
884 ////////////////////////////////////////////////////////////////////
885 INLINE void HTTPChannel::
886 begin_get_document(const DocumentSpec &url) {
887  begin_request(HTTPEnum::M_get, url, string(), true, 0, 0);
888 }
889 
890 ////////////////////////////////////////////////////////////////////
891 // Function: HTTPChannel::begin_get_subdocument
892 // Access: Published
893 // Description: Begins a non-blocking request to retrieve only the
894 // specified byte range of the indicated document. If
895 // last_byte is 0, it stands for the last byte of the
896 // document. When a subdocument is requested,
897 // get_file_size() and get_bytes_downloaded() will
898 // report the number of bytes of the subdocument, not of
899 // the complete document.
900 ////////////////////////////////////////////////////////////////////
901 INLINE void HTTPChannel::
902 begin_get_subdocument(const DocumentSpec &url, size_t first_byte,
903  size_t last_byte) {
904  begin_request(HTTPEnum::M_get, url, string(), true, first_byte, last_byte);
905 }
906 
907 ////////////////////////////////////////////////////////////////////
908 // Function: HTTPChannel::begin_get_header
909 // Access: Published
910 // Description: Begins a non-blocking request to retrieve a given
911 // header. See begin_get_document() and get_header().
912 ////////////////////////////////////////////////////////////////////
913 INLINE void HTTPChannel::
914 begin_get_header(const DocumentSpec &url) {
915  begin_request(HTTPEnum::M_head, url, string(), true, 0, 0);
916 }
917 
918 ////////////////////////////////////////////////////////////////////
919 // Function: HTTPChannel::begin_post_form
920 // Access: Published
921 // Description: Posts form data to a particular URL and retrieves the
922 // response, all using non-blocking I/O. See
923 // begin_get_document() and post_form().
924 //
925 // It is important to note that you *must* call run()
926 // repeatedly after calling this method until run()
927 // returns false, and you may not call any other
928 // document posting or retrieving methods using the
929 // HTTPChannel object in the interim, or your form data
930 // may not get posted.
931 ////////////////////////////////////////////////////////////////////
932 INLINE void HTTPChannel::
933 begin_post_form(const DocumentSpec &url, const string &body) {
934  begin_request(HTTPEnum::M_post, url, body, true, 0, 0);
935 }
936 
937 ////////////////////////////////////////////////////////////////////
938 // Function: HTTPChannel::begin_connect_to
939 // Access: Published
940 // Description: Begins a non-blocking request to establish a direct
941 // connection to the server and port indicated by the
942 // URL. No HTTP requests will be issued beyond what is
943 // necessary to establish the connection. When run()
944 // has finished, you may call is_connection_ready() to
945 // determine if the connection was successfully
946 // established.
947 //
948 // If successful, the connection may then be taken to
949 // use for whatever purposes you like by calling
950 // get_connection().
951 //
952 // This establishes a nonblocking I/O socket. Also see
953 // connect_to().
954 ////////////////////////////////////////////////////////////////////
955 INLINE void HTTPChannel::
956 begin_connect_to(const DocumentSpec &url) {
957  begin_request(HTTPEnum::M_connect, url, string(), true, 0, 0);
958 }
959 
960 ////////////////////////////////////////////////////////////////////
961 // Function: HTTPChannel::get_bytes_downloaded
962 // Access: Published
963 // Description: Returns the number of bytes downloaded during the
964 // last (or current) download_to_file() or
965 // download_to_ram operation(). This can be used in
966 // conjunction with get_file_size() to report the
967 // percent complete (but be careful, since
968 // get_file_size() may return 0 if the server has not
969 // told us the size of the file).
970 ////////////////////////////////////////////////////////////////////
971 INLINE size_t HTTPChannel::
972 get_bytes_downloaded() const {
973  return _bytes_downloaded;
974 }
975 
976 ////////////////////////////////////////////////////////////////////
977 // Function: HTTPChannel::get_bytes_requested
978 // Access: Published
979 // Description: When download throttling is in effect
980 // (set_download_throttle() has been set to true) and
981 // non-blocking I/O methods (like begin_get_document())
982 // are used, this returns the number of bytes
983 // "requested" from the server so far: that is, the
984 // theoretical maximum value for get_bytes_downloaded(),
985 // if the server has been keeping up with our demand.
986 //
987 // If this number is less than get_bytes_downloaded(),
988 // then the server has not been supplying bytes fast
989 // enough to meet our own download throttle rate.
990 //
991 // When download throttling is not in effect, or when
992 // the blocking I/O methods (like get_document(), etc.)
993 // are used, this returns 0.
994 ////////////////////////////////////////////////////////////////////
995 INLINE size_t HTTPChannel::
996 get_bytes_requested() const {
997  return _bytes_requested;
998 }
999 
1000 ////////////////////////////////////////////////////////////////////
1001 // Function: HTTPChannel::is_download_complete
1002 // Access: Published
1003 // Description: Returns true when a download_to() or
1004 // download_to_ram() has executed and the file has been
1005 // fully downloaded. If this still returns false after
1006 // processing has completed, there was an error in
1007 // transmission.
1008 //
1009 // Note that simply testing is_download_complete() does
1010 // not prove that the requested document was successfully
1011 // retrieved--you might have just downloaded the "404
1012 // not found" stub (for instance) that a server would
1013 // provide in response to some error condition. You
1014 // should also check is_valid() to prove that the file
1015 // you expected has been successfully retrieved.
1016 ////////////////////////////////////////////////////////////////////
1017 INLINE bool HTTPChannel::
1018 is_download_complete() const {
1019  return (_download_dest != DD_none &&
1020  (_state == S_read_body || _state == S_read_trailer));
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////
1024 // Function: HTTPChannel::StatusEntry::Constructor
1025 // Access: Public
1026 // Description:
1027 ////////////////////////////////////////////////////////////////////
1028 INLINE HTTPChannel::StatusEntry::
1029 StatusEntry() {
1030  _status_code = SC_incomplete;
1031 }
A container for a URL, e.g.
Definition: urlSpec.h:29
const string & get_url() const
Returns the complete URL specification.
Definition: urlSpec.I:254
A descriptor that refers to a particular version of a document.
Definition: documentSpec.h:33