Panda3D
Loading...
Searching...
No Matches
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 */
17INLINE HTTPClient *HTTPChannel::
18get_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 */
26INLINE bool HTTPChannel::
27is_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 */
36INLINE bool HTTPChannel::
37is_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 */
47INLINE const URLSpec &HTTPChannel::
48get_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 */
61INLINE const DocumentSpec &HTTPChannel::
62get_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 */
70INLINE HTTPEnum::HTTPVersion HTTPChannel::
71get_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 */
79INLINE const std::string &HTTPChannel::
80get_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 */
94INLINE int HTTPChannel::
95get_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 */
106INLINE const std::string &HTTPChannel::
107get_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 */
117INLINE const std::string &HTTPChannel::
118get_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 */
129INLINE const URLSpec &HTTPChannel::
130get_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 */
139INLINE int HTTPChannel::
140get_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 */
149INLINE const URLSpec &HTTPChannel::
150get_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 */
165INLINE void HTTPChannel::
166set_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 */
176INLINE bool HTTPChannel::
177get_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 */
188INLINE void HTTPChannel::
189set_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 */
200INLINE bool HTTPChannel::
201get_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 */
220INLINE void HTTPChannel::
221set_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 */
230INLINE bool HTTPChannel::
231get_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 */
243INLINE void HTTPChannel::
244set_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 */
252INLINE double HTTPChannel::
253get_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 */
269INLINE void HTTPChannel::
270set_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 */
280INLINE bool HTTPChannel::
281get_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 */
296INLINE void HTTPChannel::
297set_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 */
305INLINE double HTTPChannel::
306get_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 */
322INLINE void HTTPChannel::
323set_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 */
332INLINE size_t HTTPChannel::
333get_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 */
344INLINE void HTTPChannel::
345set_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 */
353INLINE double HTTPChannel::
354get_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 */
373INLINE void HTTPChannel::
374set_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 */
382INLINE bool HTTPChannel::
383get_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 */
392INLINE void HTTPChannel::
393set_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 */
402INLINE double HTTPChannel::
403get_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 */
412INLINE void HTTPChannel::
413set_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 */
424INLINE double HTTPChannel::
425get_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 */
433INLINE void HTTPChannel::
434set_content_type(std::string content_type) {
435 _content_type = content_type;
436}
437
438/**
439 * Returns the value of the Content-Type header.
440 */
441INLINE std::string HTTPChannel::
442get_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 */
453INLINE void HTTPChannel::
454set_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 */
467INLINE bool HTTPChannel::
468is_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 */
478INLINE size_t HTTPChannel::
479get_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 */
489INLINE size_t HTTPChannel::
490get_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 */
501INLINE size_t HTTPChannel::
502get_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 */
513INLINE size_t HTTPChannel::
514get_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 */
529INLINE void HTTPChannel::
530reset() {
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 */
546INLINE void HTTPChannel::
547preserve_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 */
556INLINE void HTTPChannel::
557clear_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 */
570INLINE void HTTPChannel::
571send_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 */
582INLINE bool HTTPChannel::
583get_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 */
597INLINE bool HTTPChannel::
598get_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 */
611INLINE bool HTTPChannel::
612get_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 */
622INLINE bool HTTPChannel::
623post_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 */
634INLINE bool HTTPChannel::
635put_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 */
645INLINE bool HTTPChannel::
646delete_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 */
657INLINE bool HTTPChannel::
658get_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 */
672INLINE bool HTTPChannel::
673connect_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 */
684INLINE bool HTTPChannel::
685get_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 */
701INLINE void HTTPChannel::
702begin_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 */
713INLINE void HTTPChannel::
714begin_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 */
723INLINE void HTTPChannel::
724begin_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 */
737INLINE void HTTPChannel::
738begin_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 */
754INLINE void HTTPChannel::
755begin_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 */
766INLINE size_t HTTPChannel::
767get_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 */
784INLINE size_t HTTPChannel::
785get_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 */
801INLINE bool HTTPChannel::
802is_download_complete() const {
803 return (_download_dest != DD_none &&
804 (_state == S_read_body || _state == S_read_trailer));
805}
806
807/**
808 *
809 */
810INLINE HTTPChannel::StatusEntry::
811StatusEntry() {
812 _status_code = SC_incomplete;
813}
A descriptor that refers to a particular version of a document.
A container for a URL, e.g.
Definition urlSpec.h:28
const std::string & get_url() const
Returns the complete URL specification.
Definition urlSpec.I:184