Panda3D

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