Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/downloader/httpChannel.cxx

Go to the documentation of this file.
00001 // Filename: httpChannel.cxx
00002 // Created by:  drose (24Sep02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "httpChannel.h"
00020 #include "httpClient.h"
00021 #include "bioStream.h"
00022 #include "chunkedStream.h"
00023 #include "identityStream.h"
00024 #include "config_downloader.h"
00025 #include "clockObject.h"
00026 #include "buffer.h"  // for Ramfile
00027 
00028 #ifdef HAVE_SSL
00029 #ifdef REPORT_OPENSSL_ERRORS
00030 #include <openssl/err.h>
00031 #endif
00032 
00033 TypeHandle HTTPChannel::_type_handle;
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: HTTPChannel::Constructor
00037 //       Access: Private
00038 //  Description: 
00039 ////////////////////////////////////////////////////////////////////
00040 HTTPChannel::
00041 HTTPChannel(HTTPClient *client) :
00042   _client(client)
00043 {
00044   _persistent_connection = false;
00045   _connect_timeout = connect_timeout;
00046   _http_timeout = http_timeout;
00047   _blocking_connect = false;
00048   _download_throttle = false;
00049   _max_bytes_per_second = downloader_byte_rate;
00050   _seconds_per_update = downloader_frequency;
00051   _max_updates_per_second = 1.0f / _seconds_per_update;
00052   _bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
00053   _nonblocking = false;
00054   _want_ssl = false;
00055   _proxy_serves_document = false;
00056   _first_byte = 0;
00057   _last_byte = 0;
00058   _read_index = 0;
00059   _file_size = 0;
00060   _bytes_downloaded = 0;
00061   _bytes_requested = 0;
00062   _status_code = 0;
00063   _status_string = string();
00064   _response_type = RT_none;
00065   _proxy = _client->get_proxy();
00066   _http_version = _client->get_http_version();
00067   _http_version_string = _client->get_http_version_string();
00068   _state = S_new;
00069   _done_state = S_new;
00070   _started_download = false;
00071   _sent_so_far = 0;
00072   _proxy_tunnel = false;
00073   _body_stream = NULL;
00074   _sbio = NULL;
00075   _last_status_code = 0;
00076   _last_run_time = 0.0f;
00077   _download_to_ramfile = NULL;
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: HTTPChannel::Destructor
00082 //       Access: Public, Virtual
00083 //  Description: 
00084 ////////////////////////////////////////////////////////////////////
00085 HTTPChannel::
00086 ~HTTPChannel() {
00087   close_connection();
00088   reset_download_to();
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: HTTPChannel::get_file_system
00093 //       Access: Published, Virtual
00094 //  Description: Returns the VirtualFileSystem this file is associated
00095 //               with.
00096 ////////////////////////////////////////////////////////////////////
00097 VirtualFileSystem *HTTPChannel::
00098 get_file_system() const {
00099   return NULL;
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: HTTPChannel::get_filename
00104 //       Access: Published, Virtual
00105 //  Description: Returns the full pathname to this file within the
00106 //               virtual file system.
00107 ////////////////////////////////////////////////////////////////////
00108 Filename HTTPChannel::
00109 get_filename() const {
00110   return Filename();
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: HTTPChannel::is_regular_file
00115 //       Access: Published, Virtual
00116 //  Description: Returns true if this file represents a regular file
00117 //               (and read_file() may be called), false otherwise.
00118 ////////////////////////////////////////////////////////////////////
00119 bool HTTPChannel::
00120 is_regular_file() const {
00121   return is_valid();
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: HTTPChannel::will_close_connection
00126 //       Access: Public
00127 //  Description: Returns true if the server has indicated it will
00128 //               close the connection after this document has been
00129 //               read, or false if it will remain open (and future
00130 //               documents may be requested on the same connection).
00131 ////////////////////////////////////////////////////////////////////
00132 bool HTTPChannel::
00133 will_close_connection() const {
00134   if (get_http_version() < HTTPEnum::HV_11) {
00135     // pre-HTTP 1.1 always closes.
00136     return true;
00137   }
00138 
00139   string connection = get_header_value("Connection");
00140   if (downcase(connection) == "close") {
00141     // The server says it will close.
00142     return true;
00143   }
00144 
00145   // Assume the server will keep it open.
00146   return false;
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: HTTPChannel::open_read_file
00151 //       Access: Public, Virtual
00152 //  Description: Opens the document for reading.  Returns a newly
00153 //               allocated istream on success (which you should
00154 //               eventually delete when you are done reading).
00155 //               Returns NULL on failure.  This may only be called
00156 //               once for a particular HTTPChannel.
00157 ////////////////////////////////////////////////////////////////////
00158 istream *HTTPChannel::
00159 open_read_file() const {
00160   return ((HTTPChannel *)this)->read_body();
00161 }
00162 
00163 ////////////////////////////////////////////////////////////////////
00164 //     Function: HTTPChannel::get_header_value
00165 //       Access: Published
00166 //  Description: Returns the HTML header value associated with the
00167 //               indicated key, or empty string if the key was not
00168 //               defined in the message returned by the server.
00169 ////////////////////////////////////////////////////////////////////
00170 string HTTPChannel::
00171 get_header_value(const string &key) const {
00172   Headers::const_iterator hi = _headers.find(downcase(key));
00173   if (hi != _headers.end()) {
00174     return (*hi).second;
00175   }
00176   return string();
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: HTTPChannel::write_headers
00181 //       Access: Published
00182 //  Description: Outputs a list of all headers defined by the server
00183 //               to the indicated output stream.
00184 ////////////////////////////////////////////////////////////////////
00185 void HTTPChannel::
00186 write_headers(ostream &out) const {
00187   Headers::const_iterator hi;
00188   for (hi = _headers.begin(); hi != _headers.end(); ++hi) {
00189     out << (*hi).first << ": " << (*hi).second << "\n";
00190   }
00191 }
00192 
00193 ////////////////////////////////////////////////////////////////////
00194 //     Function: HTTPChannel::run
00195 //       Access: Published
00196 //  Description: This must be called from time to time when
00197 //               non-blocking I/O is in use.  It checks for data
00198 //               coming in on the socket and writes data out to the
00199 //               socket when possible, and does whatever processing is
00200 //               required towards completing the current task.
00201 //
00202 //               The return value is true if the task is still pending
00203 //               (and run() will need to be called again in the
00204 //               future), or false if the current task is complete.
00205 ////////////////////////////////////////////////////////////////////
00206 bool HTTPChannel::
00207 run() {
00208   if (_state == _done_state || _state == S_failure) {
00209     clear_extra_headers();
00210     if (!reached_done_state()) {
00211       return false;
00212     }
00213   }
00214 
00215   if (_started_download) {
00216     if (_nonblocking && _download_throttle) {
00217       double now = ClockObject::get_global_clock()->get_real_time();
00218       double elapsed = now - _last_run_time;
00219       if (elapsed < _seconds_per_update) {
00220         // Come back later.
00221         return true;
00222       }
00223       int num_potential_updates = (int)(elapsed / _seconds_per_update);
00224       _last_run_time = now;
00225       _bytes_requested += _bytes_per_update * num_potential_updates;
00226       if (downloader_cat.is_spam()) {
00227         downloader_cat.spam()
00228           << "elapsed = " << elapsed << " num_potential_updates = " 
00229           << num_potential_updates << " bytes_requested = " 
00230           << _bytes_requested << "\n";
00231       }
00232     }
00233     switch (_download_dest) {
00234     case DD_none:
00235       return false;  // We're done.
00236 
00237     case DD_file:
00238       return run_download_to_file();
00239 
00240     case DD_ram:
00241       return run_download_to_ram();
00242     }
00243   }
00244 
00245   if (downloader_cat.is_spam()) {
00246     downloader_cat.spam()
00247       << "begin run(), _state = " << (int)_state << ", _done_state = "
00248       << (int)_done_state << "\n";
00249   }
00250 
00251   if (_state == _done_state) {
00252     return reached_done_state();
00253   }
00254 
00255   bool repeat_later;
00256   do {
00257     if (_bio.is_null()) {
00258       if (_connect_count > http_max_connect_count) {
00259         // Too many connection attempts, just give up.  We should
00260         // never trigger this failsafe, since the code in each
00261         // individual case has similar logic to prevent more than two
00262         // consecutive lost connections.
00263         downloader_cat.warning()
00264           << "Too many lost connections, giving up.\n";
00265         _state = S_failure;
00266         return false;
00267       }
00268 
00269       // No connection.  Attempt to establish one.
00270       _proxy = _client->get_proxy();
00271       
00272       if (_proxy.empty()) {
00273         _bio = new BioPtr(_request.get_url());
00274       } else {
00275         _bio = new BioPtr(_proxy);
00276       }
00277       _source = new BioStreamPtr(new BioStream(_bio));
00278       if (_nonblocking) {
00279         BIO_set_nbio(*_bio, 1);
00280       }
00281 
00282       if (_connect_count > 0) {
00283         downloader_cat.info()
00284           << "Reconnecting to " << _bio->get_server_name() << ":" 
00285           << _bio->get_port() << "\n";
00286       }
00287       
00288       _state = S_connecting;
00289       _started_connecting_time = 
00290         ClockObject::get_global_clock()->get_real_time();
00291       _connect_count++;
00292     }
00293 
00294     if (downloader_cat.is_spam()) {
00295       downloader_cat.spam()
00296         << "continue run(), _state = " << (int)_state << "\n";
00297     }
00298 
00299     switch (_state) {
00300     case S_connecting:
00301       repeat_later = run_connecting();
00302       break;
00303       
00304     case S_connecting_wait:
00305       repeat_later = run_connecting_wait();
00306       break;
00307       
00308     case S_proxy_ready:
00309       repeat_later = run_proxy_ready();
00310       break;
00311       
00312     case S_proxy_request_sent:
00313       repeat_later = run_proxy_request_sent();
00314       break;
00315       
00316     case S_proxy_reading_header:
00317       repeat_later = run_proxy_reading_header();
00318       break;
00319       
00320     case S_setup_ssl:
00321       repeat_later = run_setup_ssl();
00322       break;
00323       
00324     case S_ssl_handshake:
00325       repeat_later = run_ssl_handshake();
00326       break;
00327       
00328     case S_ready:
00329       repeat_later = run_ready();
00330       break;
00331       
00332     case S_request_sent:
00333       repeat_later = run_request_sent();
00334       break;
00335       
00336     case S_reading_header:
00337       repeat_later = run_reading_header();
00338       break;
00339       
00340     case S_read_header:
00341       repeat_later = run_read_header();
00342       break;
00343       
00344     case S_begin_body:
00345       repeat_later = run_begin_body();
00346       break;
00347       
00348     case S_reading_body:
00349       repeat_later = run_reading_body();
00350       break;
00351 
00352     case S_read_body:
00353       repeat_later = run_read_body();
00354       break;
00355 
00356     case S_read_trailer:
00357       repeat_later = run_read_trailer();
00358       break;
00359       
00360     default:
00361       downloader_cat.warning()
00362         << "Unhandled state " << (int)_state << "\n";
00363       return false;
00364     }
00365 
00366     if (_state == _done_state || _state == S_failure) {
00367       clear_extra_headers();
00368       // We've reached our terminal state.
00369       return reached_done_state();
00370     }
00371   } while (!repeat_later || _bio.is_null());
00372 
00373   if (downloader_cat.is_spam()) {
00374     downloader_cat.spam()
00375       << "later run(), _state = " << (int)_state
00376       << ", _done_state = " << (int)_done_state << "\n";
00377   }
00378   return true;
00379 }
00380 
00381 ////////////////////////////////////////////////////////////////////
00382 //     Function: HTTPChannel::read_body
00383 //       Access: Published
00384 //  Description: Returns a newly-allocated istream suitable for
00385 //               reading the body of the document.  This may only be
00386 //               called immediately after a call to get_document() or
00387 //               post_form(), or after a call to run() has returned
00388 //               false.
00389 //
00390 //               The user is responsible for deleting the returned
00391 //               istream later.
00392 ////////////////////////////////////////////////////////////////////
00393 ISocketStream *HTTPChannel::
00394 read_body() {
00395   if ((_state != S_read_header && _state != S_begin_body) || _source.is_null()) {
00396     return NULL;
00397   }
00398 
00399   string transfer_coding = downcase(get_header_value("Transfer-Encoding"));
00400   string content_length = get_header_value("Content-Length");
00401 
00402   ISocketStream *result;
00403   if (transfer_coding == "chunked") {
00404     // "chunked" transfer encoding.  This means we will have to decode
00405     // the length of the file as we read it in chunks.  The
00406     // IChunkedStream does this.
00407     _file_size = 0;
00408     _state = S_reading_body;
00409     _read_index++;
00410     result = new IChunkedStream(_source, (HTTPChannel *)this);
00411 
00412   } else {
00413     // If the transfer encoding is anything else, assume "identity".
00414     // This is just the literal characters following the header, up
00415     // until _file_size bytes have been read (if content-length was
00416     // specified), or till end of file otherwise.
00417     _state = S_reading_body;
00418     _read_index++;
00419     result = new IIdentityStream(_source, (HTTPChannel *)this, 
00420                                  !content_length.empty(), _file_size);
00421   }
00422 
00423   return result;
00424 }
00425 
00426 ////////////////////////////////////////////////////////////////////
00427 //     Function: HTTPChannel::download_to_file
00428 //       Access: Published
00429 //  Description: Specifies the name of a file to download the
00430 //               resulting document to.  This should be called
00431 //               immediately after get_document() or
00432 //               begin_get_document() or related functions.
00433 //
00434 //               In the case of the blocking I/O methods like
00435 //               get_document(), this function will download the
00436 //               entire document to the file and return true if it was
00437 //               successfully downloaded, false otherwise.
00438 //
00439 //               In the case of non-blocking I/O methods like
00440 //               begin_get_document(), this function simply indicates an
00441 //               intention to download to the indicated file.  It
00442 //               returns true if the file can be opened for writing,
00443 //               false otherwise, but the contents will not be
00444 //               completely downloaded until run() has returned false.
00445 //               At this time, it is possible that a communications
00446 //               error will have left a partial file, so
00447 //               is_download_complete() may be called to test this.
00448 //
00449 //               If subdocument_resumes is true and the document in
00450 //               question was previously requested as a subdocument
00451 //               (i.e. get_subdocument() with a first_byte value
00452 //               greater than zero), this will automatically seek to
00453 //               the appropriate byte within the file for writing the
00454 //               output.  In this case, the file must already exist
00455 //               and must have at least first_byte bytes in it.  If
00456 //               subdocument_resumes is false, a subdocument will
00457 //               always be downloaded beginning at the first byte of
00458 //               the file.
00459 ////////////////////////////////////////////////////////////////////
00460 bool HTTPChannel::
00461 download_to_file(const Filename &filename, bool subdocument_resumes) {
00462   reset_download_to();
00463   _download_to_filename = filename;
00464   _download_to_filename.set_binary();
00465   _download_to_file.close();
00466   _download_to_file.clear();
00467 
00468   _subdocument_resumes = (subdocument_resumes && _first_byte != 0);
00469 
00470   if (!_download_to_filename.open_write(_download_to_file, !_subdocument_resumes)) {
00471     downloader_cat.info()
00472       << "Could not open " << _download_to_filename << " for writing.\n";
00473     return false;
00474   }
00475 
00476   _download_dest = DD_file;
00477   if (!reset_download_position()) {
00478     reset_download_to();
00479     return false;
00480   }
00481 
00482   if (_nonblocking) {
00483     // In nonblocking mode, we can't start the download yet; that will
00484     // be done later as run() is called.
00485     return true;
00486   }
00487 
00488   // In normal, blocking mode, go ahead and do the download.
00489   run();
00490   return is_download_complete();
00491 }
00492 
00493 ////////////////////////////////////////////////////////////////////
00494 //     Function: HTTPChannel::download_to_ram
00495 //       Access: Published
00496 //  Description: Specifies a Ramfile object to download the
00497 //               resulting document to.  This should be called
00498 //               immediately after get_document() or
00499 //               begin_get_document() or related functions.
00500 //
00501 //               In the case of the blocking I/O methods like
00502 //               get_document(), this function will download the
00503 //               entire document to the Ramfile and return true if it
00504 //               was successfully downloaded, false otherwise.
00505 //
00506 //               In the case of non-blocking I/O methods like
00507 //               begin_get_document(), this function simply indicates an
00508 //               intention to download to the indicated Ramfile.  It
00509 //               returns true if the file can be opened for writing,
00510 //               false otherwise, but the contents will not be
00511 //               completely downloaded until run() has returned false.
00512 //               At this time, it is possible that a communications
00513 //               error will have left a partial file, so
00514 //               is_download_complete() may be called to test this.
00515 //
00516 //               If subdocument_resumes is true and the document in
00517 //               question was previously requested as a subdocument
00518 //               (i.e. get_subdocument() with a first_byte value
00519 //               greater than zero), this will automatically seek to
00520 //               the appropriate byte within the Ramfile for writing
00521 //               the output.  In this case, the Ramfile must already
00522 //               have at least first_byte bytes in it.
00523 ////////////////////////////////////////////////////////////////////
00524 bool HTTPChannel::
00525 download_to_ram(Ramfile *ramfile, bool subdocument_resumes) {
00526   nassertr(ramfile != (Ramfile *)NULL, false);
00527   reset_download_to();
00528   ramfile->_pos = 0;
00529   _download_to_ramfile = ramfile;
00530   _download_dest = DD_ram;
00531   _subdocument_resumes = (subdocument_resumes && _first_byte != 0);
00532 
00533   if (!reset_download_position()) {
00534     reset_download_to();
00535     return false;
00536   }
00537 
00538   if (_nonblocking) {
00539     // In nonblocking mode, we can't start the download yet; that will
00540     // be done later as run() is called.
00541     return true;
00542   }
00543 
00544   // In normal, blocking mode, go ahead and do the download.
00545   run();
00546   return is_download_complete();
00547 }
00548 
00549 ////////////////////////////////////////////////////////////////////
00550 //     Function: HTTPChannel::get_connection
00551 //       Access: Published
00552 //  Description: Returns the connection that was established via a
00553 //               previous call to connect_to() or begin_connect_to(),
00554 //               or NULL if the connection attempt failed or if those
00555 //               methods have not recently been called.
00556 //
00557 //               This stream has been allocated from the free store.
00558 //               It is the user's responsibility to delete this
00559 //               pointer when finished with it.
00560 ////////////////////////////////////////////////////////////////////
00561 SocketStream *HTTPChannel::
00562 get_connection() {
00563   if (!is_connection_ready()) {
00564     return NULL;
00565   }
00566 
00567   BioStream *stream = _source->get_stream();
00568   _source->set_stream(NULL);
00569 
00570   // We're now passing ownership of the connection to the user.
00571   reset_to_new();
00572 
00573   return stream;
00574 }
00575 
00576 ////////////////////////////////////////////////////////////////////
00577 //     Function: HTTPChannel::downcase
00578 //       Access: Public, Static
00579 //  Description: Returns the input string with all uppercase letters
00580 //               converted to lowercase.
00581 ////////////////////////////////////////////////////////////////////
00582 string HTTPChannel::
00583 downcase(const string &s) {
00584   string result;
00585   result.reserve(s.size());
00586   string::const_iterator p;
00587   for (p = s.begin(); p != s.end(); ++p) {
00588     result += tolower(*p);
00589   }
00590   return result;
00591 }
00592 
00593 ////////////////////////////////////////////////////////////////////
00594 //     Function: HTTPChannel::reached_done_state
00595 //       Access: Private
00596 //  Description: Called by run() after it reaches the done state, this
00597 //               simply checks to see if a download was requested, and
00598 //               begins the download if it has been.
00599 ////////////////////////////////////////////////////////////////////
00600 bool HTTPChannel::
00601 reached_done_state() {
00602   if (downloader_cat.is_spam()) {
00603     downloader_cat.spam()
00604       << "terminating run(), _state = " << (int)_state
00605       << ", _done_state = " << (int)_done_state << "\n";
00606   }
00607 
00608   if (_state == S_failure || _download_dest == DD_none) {
00609     // All done.
00610     return false;
00611     
00612   } else {
00613     // Oops, we have to download the body now.
00614     _body_stream = read_body();
00615     if (_body_stream == (ISocketStream *)NULL) {
00616       if (downloader_cat.is_debug()) {
00617         downloader_cat.debug()
00618           << "Unable to download body.\n";
00619       }
00620       return false;
00621     } else {
00622       _started_download = true;
00623       _last_run_time = ClockObject::get_global_clock()->get_real_time();
00624       return true;
00625     }
00626   }
00627 }
00628   
00629 ////////////////////////////////////////////////////////////////////
00630 //     Function: HTTPChannel::run_connecting
00631 //       Access: Private
00632 //  Description: In this state, we have not yet established a
00633 //               network connection to the server (or proxy).
00634 ////////////////////////////////////////////////////////////////////
00635 bool HTTPChannel::
00636 run_connecting() {
00637   _status_code = 0;
00638   _status_string = string();
00639   if (BIO_do_connect(*_bio) <= 0) {
00640     if (BIO_should_retry(*_bio)) {
00641       _state = S_connecting_wait;
00642       return false;
00643     }
00644     downloader_cat.info()
00645       << "Could not connect to " << _bio->get_server_name() << ":" 
00646       << _bio->get_port() << "\n";
00647 #ifdef REPORT_OPENSSL_ERRORS
00648     ERR_print_errors_fp(stderr);
00649 #endif
00650     _state = S_failure;
00651     return false;
00652   }
00653 
00654   if (downloader_cat.is_debug()) {
00655     downloader_cat.debug()
00656       << "Connected to " << _bio->get_server_name() << ":" 
00657       << _bio->get_port() << "\n";
00658   }
00659 
00660   if (!_proxy.empty()) {
00661     _state = S_proxy_ready;
00662 
00663   } else {
00664     _state = _want_ssl ? S_setup_ssl : S_ready;
00665   }
00666   return false;
00667 }
00668 
00669 ////////////////////////////////////////////////////////////////////
00670 //     Function: HTTPChannel::run_connecting_wait
00671 //       Access: Private
00672 //  Description: Here we have begun to establish a nonblocking
00673 //               connection, but we got a come-back-later message, so
00674 //               we are waiting for the socket to finish connecting.
00675 ////////////////////////////////////////////////////////////////////
00676 bool HTTPChannel::
00677 run_connecting_wait() {
00678   int fd = -1;
00679   BIO_get_fd(*_bio, &fd);
00680   if (fd < 0) {
00681     downloader_cat.warning()
00682       << "nonblocking socket BIO has no file descriptor.\n";
00683     _state = S_failure;
00684     return false;
00685   }
00686 
00687   if (downloader_cat.is_debug()) {
00688     downloader_cat.debug()
00689       << "waiting to connect to " << _request.get_url().get_server_and_port() << ".\n";
00690   }
00691   fd_set wset;
00692   FD_ZERO(&wset);
00693   FD_SET(fd, &wset);
00694   struct timeval tv;
00695   if (get_blocking_connect()) {
00696     // Since we'll be blocking on this connect, fill in the timeout
00697     // into the structure.
00698     tv.tv_sec = (int)_connect_timeout;
00699     tv.tv_usec = (int)((_connect_timeout - tv.tv_sec) * 1000000.0);
00700   } else {
00701     // We won't block on this connect, so select() for 0 time.
00702     tv.tv_sec = 0;
00703     tv.tv_usec = 0;
00704   }
00705   int errcode = select(fd + 1, NULL, &wset, NULL, &tv);
00706   if (errcode < 0) {
00707     downloader_cat.warning()
00708       << "Error in select.\n";
00709     _state = S_failure;
00710     return false;
00711   }
00712   
00713   if (errcode == 0) {
00714     // Nothing's happened so far; come back later.
00715     if (get_blocking_connect() ||
00716         (ClockObject::get_global_clock()->get_real_time() - 
00717          _started_connecting_time > get_connect_timeout())) {
00718       // Time to give up.
00719       downloader_cat.info()
00720         << "Timeout connecting to " 
00721         << _request.get_url().get_server_and_port() << ".\n";
00722       _state = S_failure;
00723       return false;
00724     }
00725     return true;
00726   }
00727   
00728   // The socket is now ready for writing.
00729   _state = S_connecting;
00730   return false;
00731 }
00732 
00733 
00734 ////////////////////////////////////////////////////////////////////
00735 //     Function: HTTPChannel::run_proxy_ready
00736 //       Access: Private
00737 //  Description: This state is reached only after first establishing a
00738 //               connection to the proxy, if a proxy is in use.
00739 //
00740 //               In the normal http mode, this state immediately
00741 //               transitions to S_ready, but in some cases (like
00742 //               https-over-proxy) we need to send a special message
00743 //               directly to the proxy that is separate from the http
00744 //               request we will send to the server.
00745 ////////////////////////////////////////////////////////////////////
00746 bool HTTPChannel::
00747 run_proxy_ready() {
00748   // If there's a request to be sent to the proxy, send it now.
00749   if (!_proxy_request_text.empty()) {
00750     if (!http_send(_proxy_request_text)) {
00751       return true;
00752     }
00753     
00754     // All done sending request.
00755     _state = S_proxy_request_sent;
00756 
00757   } else {
00758     _state = S_ready;
00759   }
00760   return false;
00761 }
00762 
00763 ////////////////////////////////////////////////////////////////////
00764 //     Function: HTTPChannel::run_proxy_request_sent
00765 //       Access: Private
00766 //  Description: This state is reached only after we have sent a
00767 //               special message to the proxy and we are waiting for
00768 //               the proxy's response.  It is not used in the normal
00769 //               http-over-proxy case, which does not require a
00770 //               special message to the proxy.
00771 ////////////////////////////////////////////////////////////////////
00772 bool HTTPChannel::
00773 run_proxy_request_sent() {
00774   // Wait for the first line to come back from the server.
00775   string line;
00776   if (!http_getline(line)) {
00777     if (_bio.is_null()) {
00778       // Huh, the proxy hung up on us as soon as we tried to connect.
00779       if (_response_type == RT_hangup) {
00780         // This was our second immediate hangup in a row.  Give up.
00781         _state = S_failure;
00782         
00783       } else {
00784         // Try again, once.
00785         _response_type = RT_hangup;
00786       }
00787     }
00788     return true;
00789   }
00790 
00791   if (!parse_http_response(line)) {
00792     return false;
00793   }
00794 
00795   _state = S_proxy_reading_header;
00796   _current_field_name = string();
00797   _current_field_value = string();
00798   _headers.clear();
00799   _file_size = 0;
00800   return false;
00801 }
00802 
00803 ////////////////////////////////////////////////////////////////////
00804 //     Function: HTTPChannel::run_proxy_reading_header
00805 //       Access: Private
00806 //  Description: In this state we are reading the header lines from
00807 //               the proxy's response to our special message.
00808 ////////////////////////////////////////////////////////////////////
00809 bool HTTPChannel::
00810 run_proxy_reading_header() {
00811   if (parse_http_header()) {
00812     return true;
00813   }
00814 
00815   _redirect = get_header_value("Location");
00816   // We can take the proxy's word for it that this is the actual URL
00817   // for the redirect.
00818 
00819   _server_response_has_no_body = 
00820     (get_status_code() / 100 == 1 ||
00821      get_status_code() == 204 ||
00822      get_status_code() == 304);
00823 
00824   int last_status = _last_status_code;
00825   _last_status_code = get_status_code();
00826 
00827   if (get_status_code() == 407 && last_status != 407 && !_proxy.empty()) {
00828     // 407: not authorized to proxy.  Try to get the authorization.
00829     string authenticate_request = get_header_value("Proxy-Authenticate");
00830     _proxy_auth = _client->generate_auth(_proxy, true, authenticate_request);
00831     if (_proxy_auth != (HTTPAuthorization *)NULL) {
00832       _proxy_realm = _proxy_auth->get_realm();
00833       _proxy_username = _client->select_username(_proxy, true, _proxy_realm);
00834       if (!_proxy_username.empty()) {
00835         make_proxy_request_text();
00836 
00837         // Roll the state forward to force a new request.
00838         _state = S_begin_body;
00839         return false;
00840       }
00841     }
00842   }
00843 
00844   if (!is_valid()) {
00845     // Proxy wouldn't open connection.
00846 
00847     // Change some of the status codes a proxy might return to
00848     // differentiate them from similar status codes the destination
00849     // server might have returned.
00850     if (get_status_code() != 407) {
00851       _status_code += 1000;
00852     }
00853 
00854     _state = S_failure;
00855     return false;
00856   }
00857 
00858   // Now we have a tunnel opened through the proxy.
00859   _proxy_tunnel = true;
00860   make_request_text();
00861 
00862   _state = _want_ssl ? S_setup_ssl : S_ready;
00863   return false;
00864 }
00865 
00866 ////////////////////////////////////////////////////////////////////
00867 //     Function: HTTPChannel::run_setup_ssl
00868 //       Access: Private
00869 //  Description: This state begins elevating our existing, unsecure
00870 //               connection to a secure, SSL connection.
00871 ////////////////////////////////////////////////////////////////////
00872 bool HTTPChannel::
00873 run_setup_ssl() {
00874   _sbio = BIO_new_ssl(_client->get_ssl_ctx(), true);
00875   BIO_push(_sbio, *_bio);
00876 
00877   if (downloader_cat.is_debug()) {
00878     downloader_cat.debug()
00879       << "performing SSL handshake\n";
00880   }
00881   _state = S_ssl_handshake;
00882   return false;
00883 }
00884 
00885 ////////////////////////////////////////////////////////////////////
00886 //     Function: HTTPChannel::run_ssl_handshake
00887 //       Access: Private
00888 //  Description: This state performs the SSL handshake with the
00889 //               server, and also verifies the server's identity when
00890 //               the handshake has successfully completed.
00891 ////////////////////////////////////////////////////////////////////
00892 bool HTTPChannel::
00893 run_ssl_handshake() {
00894   if (BIO_do_handshake(_sbio) <= 0) {
00895     if (BIO_should_retry(_sbio)) {
00896       return true;
00897     }
00898     downloader_cat.info()
00899       << "Could not establish SSL handshake with " 
00900       << _request.get_url().get_server_and_port() << "\n";
00901 #ifdef REPORT_OPENSSL_ERRORS
00902     ERR_print_errors_fp(stderr);
00903 #endif
00904     // It seems to be an error to free sbio at this point; perhaps
00905     // it's already been freed?
00906     _state = S_failure;
00907     return false;
00908   }
00909 
00910   SSL *ssl;
00911   BIO_get_ssl(_sbio, &ssl);
00912   nassertr(ssl != (SSL *)NULL, false);
00913 
00914   if (!_nonblocking) {
00915     SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
00916   }
00917 
00918   // Now that we've made an SSL handshake, we can use the SSL bio to
00919   // do all of our communication henceforth.
00920   _bio->set_bio(_sbio);
00921   _sbio = NULL;
00922 
00923   // Now verify the server is who we expect it to be.
00924   long verify_result = SSL_get_verify_result(ssl);
00925   if (verify_result == X509_V_ERR_CERT_HAS_EXPIRED) {
00926     downloader_cat.info()
00927       << "Expired certificate from " << _request.get_url().get_server_and_port() << "\n";
00928     if (_client->get_verify_ssl() == HTTPClient::VS_normal) {
00929       _state = S_failure;
00930       return false;
00931     }
00932 
00933   } else if (verify_result == X509_V_ERR_CERT_NOT_YET_VALID) {
00934     downloader_cat.info()
00935       << "Premature certificate from " << _request.get_url().get_server_and_port() << "\n";
00936     if (_client->get_verify_ssl() == HTTPClient::VS_normal) {
00937       _state = S_failure;
00938       return false;
00939     }
00940 
00941   } else if (verify_result != X509_V_OK) {
00942     downloader_cat.info()
00943       << "Unable to verify identity of " << _request.get_url().get_server_and_port()
00944       << ", verify error code " << verify_result << "\n";
00945     if (_client->get_verify_ssl() != HTTPClient::VS_no_verify) {
00946       _state = S_failure;
00947       return false;
00948     }
00949   }
00950 
00951   X509 *cert = SSL_get_peer_certificate(ssl);
00952   if (cert == (X509 *)NULL) {
00953     downloader_cat.info()
00954       << "No certificate was presented by server.\n";
00955     if (_client->get_verify_ssl() != HTTPClient::VS_no_verify ||
00956         !_client->_expected_servers.empty()) {
00957       _state = S_failure;
00958       return false;
00959     }
00960 
00961   } else {
00962     if (downloader_cat.is_debug()) {
00963       downloader_cat.debug()
00964         << "Received certificate from server:\n" << flush;
00965       X509_print_fp(stderr, cert);
00966       fflush(stderr);
00967     }
00968 
00969     X509_NAME *subject = X509_get_subject_name(cert);
00970 
00971     if (downloader_cat.is_debug()) {
00972       string org_name = get_x509_name_component(subject, NID_organizationName);
00973       string org_unit_name = get_x509_name_component(subject, NID_organizationalUnitName);
00974       string common_name = get_x509_name_component(subject, NID_commonName);
00975       
00976       downloader_cat.debug()
00977         << "Server is " << common_name << " from " << org_unit_name
00978         << " / " << org_name << "\n";
00979     }
00980 
00981     if (_client->get_verify_ssl() != HTTPClient::VS_no_verify) {
00982       // Check that the server is someone we expected to be talking
00983       // to.
00984       if (!verify_server(subject)) {
00985         downloader_cat.info()
00986           << "Server does not match any expected server.\n";
00987         _state = S_failure;
00988         return false;
00989       }
00990     }
00991       
00992     X509_free(cert);
00993   }
00994 
00995   _state = S_ready;
00996   return false;
00997 }
00998 
00999 ////////////////////////////////////////////////////////////////////
01000 //     Function: HTTPChannel::run_ready
01001 //       Access: Private
01002 //  Description: This is the main "ready" state.  In this state, we
01003 //               have established a (possibly secure) connection to
01004 //               the server (or proxy), and the server (or proxy) is
01005 //               idle and waiting for us to send a request.
01006 //
01007 //               If persistent_connection is true, we will generally
01008 //               come back to this state after finishing each request
01009 //               on a given connection.
01010 ////////////////////////////////////////////////////////////////////
01011 bool HTTPChannel::
01012 run_ready() {
01013   // If there's a request to be sent upstream, send it now.
01014   if (!_request_text.empty()) {
01015    if (!http_send(_request_text)) {
01016       return true;
01017     }
01018   }
01019     
01020   // All done sending request.
01021   _state = S_request_sent;
01022   _sent_request_time = ClockObject::get_global_clock()->get_real_time();
01023   return false;
01024 }
01025 
01026 ////////////////////////////////////////////////////////////////////
01027 //     Function: HTTPChannel::run_request_sent
01028 //       Access: Private
01029 //  Description: In this state we have sent our request to the server
01030 //               (or proxy) and we are waiting for a response.
01031 ////////////////////////////////////////////////////////////////////
01032 bool HTTPChannel::
01033 run_request_sent() {
01034   // Wait for the first line to come back from the server.
01035   string line;
01036   if (!http_getline(line)) {
01037     if (_bio.is_null()) {
01038       // Huh, the server hung up on us as soon as we tried to connect.
01039       if (_response_type == RT_hangup) {
01040         // This was our second immediate hangup in a row.  Give up.
01041         _state = S_failure;
01042         
01043       } else {
01044         // Try again, once.
01045         _response_type = RT_hangup;
01046       }
01047 
01048     } else if (ClockObject::get_global_clock()->get_real_time() -
01049                _sent_request_time > get_http_timeout()) {
01050       // Time to give up.
01051       downloader_cat.info()
01052         << "Timeout waiting for " << _request.get_url().get_server_and_port() << ".\n";
01053       _state = S_failure;
01054     }
01055 
01056     return true;
01057   }
01058 
01059   if (!parse_http_response(line)) {
01060     // Not an HTTP response.  _state is already set appropriately.
01061     return false;
01062   }
01063 
01064   _state = S_reading_header;
01065   _current_field_name = string();
01066   _current_field_value = string();
01067   _headers.clear();
01068   _file_size = 0;
01069   return false;
01070 }
01071 
01072 ////////////////////////////////////////////////////////////////////
01073 //     Function: HTTPChannel::run_reading_header
01074 //       Access: Private
01075 //  Description: In this state we have received the first response to
01076 //               our request from the server (or proxy) and we are
01077 //               reading the set of header lines preceding the
01078 //               requested document.
01079 ////////////////////////////////////////////////////////////////////
01080 bool HTTPChannel::
01081 run_reading_header() {
01082   if (parse_http_header()) {
01083     if (_bio.is_null()) {
01084       downloader_cat.info()
01085         << "Connection lost while reading HTTP response.\n";
01086       if (_response_type == RT_http_hangup) {
01087         // This was our second hangup in a row.  Give up.
01088         _state = S_failure;
01089         
01090       } else {
01091         // Try again, once.
01092         _response_type = RT_http_hangup;
01093       }
01094 
01095     } else if (ClockObject::get_global_clock()->get_real_time() -
01096                _sent_request_time > get_http_timeout()) {
01097       // Time to give up.
01098       downloader_cat.info()
01099         << "Timeout waiting for " << _request.get_url().get_server_and_port() << ".\n";
01100       _state = S_failure;
01101     }
01102     return true;
01103   }
01104   _response_type = RT_http_complete;
01105 
01106   // Ok, we've established an HTTP connection to the server.  Our
01107   // extra send headers have done their job; clear them for next time.
01108   clear_extra_headers();
01109 
01110   _server_response_has_no_body = 
01111     (get_status_code() / 100 == 1 ||
01112      get_status_code() == 204 ||
01113      get_status_code() == 304 || 
01114      _method == HTTPEnum::M_head);
01115 
01116   // Look for key properties in the header fields.
01117   if (get_status_code() == 206) {
01118     string content_range = get_header_value("Content-Range");
01119     if (content_range.empty()) {
01120       downloader_cat.warning()
01121         << "Got 206 response without Content-Range header!\n";
01122       _state = S_failure;
01123       return false;
01124 
01125     } else {
01126       if (!parse_content_range(content_range)) {
01127         downloader_cat.warning()
01128           << "Couldn't parse Content-Range: " << content_range << "\n";
01129         _state = S_failure;
01130         return false;
01131       }
01132     }
01133 
01134   } else {
01135     _first_byte = 0;
01136     _last_byte = 0;
01137   }
01138 
01139   // Set the _document_spec to reflect what we just retrieved.
01140   _document_spec = DocumentSpec(_request.get_url());
01141   string tag = get_header_value("ETag");
01142   if (!tag.empty()) {
01143     _document_spec.set_tag(HTTPEntityTag(tag));
01144   }
01145   string date = get_header_value("Last-Modified");
01146   if (!date.empty()) {
01147     _document_spec.set_date(HTTPDate(date));
01148   }
01149 
01150   // In case we've got a download in effect, reset the download
01151   // position to match our starting byte.
01152   if (!reset_download_position()) {
01153     _state = S_failure;
01154     return false;
01155   }
01156 
01157   _file_size = 0;
01158   string content_length = get_header_value("Content-Length");
01159   if (!content_length.empty()) {
01160     _file_size = atoi(content_length.c_str());
01161 
01162   } else if (get_status_code() == 206) {
01163     // Well, we didn't get a content-length from the server, but we
01164     // can infer the number of bytes based on the range we're given.
01165     _file_size = _last_byte - _first_byte + 1;
01166   }
01167   _redirect = get_header_value("Location");
01168 
01169   // The server might have given us just a filename for the redirect.
01170   // In that case, it's relative to the same server.
01171   if (_redirect.has_path() && !_redirect.has_authority()) {
01172     _redirect.set_scheme(_document_spec.get_url().get_scheme());
01173     _redirect.set_authority(_document_spec.get_url().get_authority());
01174   }
01175 
01176   _state = S_read_header;
01177 
01178   if (_server_response_has_no_body && will_close_connection()) {
01179     // If the server said it will close the connection, we should
01180     // close it too.
01181     close_connection();
01182   }
01183 
01184   // Handle automatic retries and redirects.
01185   int last_status = _last_status_code;
01186   _last_status_code = get_status_code();
01187 
01188   if (get_status_code() == 407 && last_status != 407 && !_proxy.empty()) {
01189     // 407: not authorized to proxy.  Try to get the authorization.
01190     string authenticate_request = get_header_value("Proxy-Authenticate");
01191     _proxy_auth = 
01192       _client->generate_auth(_proxy, true, authenticate_request);
01193     if (_proxy_auth != (HTTPAuthorization *)NULL) {
01194       _proxy_realm = _proxy_auth->get_realm();
01195       _proxy_username = _client->select_username(_proxy, true, _proxy_realm);
01196       if (!_proxy_username.empty()) {
01197         make_request_text();
01198 
01199         // Roll the state forward to force a new request.
01200         _state = S_begin_body;
01201         return false;
01202       }
01203     }
01204   }
01205 
01206   if (get_status_code() == 401 && last_status != 401) {
01207     // 401: not authorized to remote server.  Try to get the authorization.
01208     string authenticate_request = get_header_value("WWW-Authenticate");
01209     _www_auth = _client->generate_auth(_request.get_url(), false, authenticate_request);
01210     if (_www_auth != (HTTPAuthorization *)NULL) {
01211       _www_realm = _www_auth->get_realm();
01212       _www_username = _client->select_username(_request.get_url(), false, _www_realm);
01213       if (!_www_username.empty()) {
01214         make_request_text();
01215       
01216         // Roll the state forward to force a new request.
01217         _state = S_begin_body;
01218         return false;
01219       }
01220     }
01221   }
01222 
01223   if ((get_status_code() / 100) == 3 && get_status_code() != 305) {
01224     // Redirect.  Should we handle it automatically?
01225     if (!get_redirect().empty() && (_method == HTTPEnum::M_get || 
01226                                     _method == HTTPEnum::M_head)) {
01227       // Sure!
01228       URLSpec new_url = get_redirect();
01229       if (!_redirect_trail.insert(new_url).second) {
01230         downloader_cat.warning()
01231           << "cycle detected in redirect to " << new_url << "\n";
01232         
01233       } else {
01234         if (downloader_cat.is_debug()) {
01235           downloader_cat.debug()
01236             << "following redirect to " << new_url << "\n";
01237         }
01238         if (_request.get_url().has_username()) {
01239           new_url.set_username(_request.get_url().get_username());
01240         }
01241         reset_url(_request.get_url(), new_url);
01242         _request.set_url(new_url);
01243         make_header();
01244         make_request_text();
01245 
01246         // Roll the state forward to force a new request.
01247         _state = S_begin_body;
01248         return false;
01249       }
01250     }
01251   }
01252 
01253   return false;
01254 }
01255 
01256 ////////////////////////////////////////////////////////////////////
01257 //     Function: HTTPChannel::run_read_header
01258 //       Access: Private
01259 //  Description: In this state we have completely read the header
01260 //               lines returned by the server (or proxy) in response
01261 //               to our request.  This state represents the normal
01262 //               stopping point of a call to get_document(), etc.;
01263 //               further reads will return the body of the request,
01264 //               the requested document.
01265 //
01266 //               Normally run_read_header() is not called unless the
01267 //               user has elected not to read the returned document
01268 //               himself.  In fact, the state itself only exists so we
01269 //               can make a distinction between S_read_header and
01270 //               S_begin_body, where S_read_header is safe to return
01271 //               to the user and S_begin_body means we need to start
01272 //               skipping the document.
01273 ////////////////////////////////////////////////////////////////////
01274 bool HTTPChannel::
01275 run_read_header() {
01276   _state = S_begin_body;
01277   return false;
01278 }
01279 
01280 ////////////////////////////////////////////////////////////////////
01281 //     Function: HTTPChannel::run_begin_body
01282 //       Access: Private
01283 //  Description: This state begins to skip over the body in
01284 //               preparation for making a new request.
01285 ////////////////////////////////////////////////////////////////////
01286 bool HTTPChannel::
01287 run_begin_body() {
01288   if (will_close_connection()) {
01289     // If the socket will close anyway, no point in skipping past the
01290     // previous body; just reset.
01291     reset_to_new();
01292     return false;
01293   }
01294 
01295   if (_server_response_has_no_body) {
01296     // We have already "read" the nonexistent body.
01297     _state = S_read_trailer;
01298 
01299   } else if (_file_size > 8192) {
01300     // If we know the size of the body we are about to skip and it's
01301     // too large (and here we arbitrarily say 8KB is too large), then
01302     // don't bother skipping it--just drop the connection and get a
01303     // new one.
01304     if (downloader_cat.is_debug()) {
01305       downloader_cat.debug()
01306         << "Dropping connection rather than skipping past " << _file_size
01307         << " bytes.\n";
01308     }
01309     reset_to_new();
01310 
01311   } else {
01312     nassertr(_body_stream == NULL, false);
01313     _body_stream = read_body();
01314     if (_body_stream == (ISocketStream *)NULL) {
01315       if (downloader_cat.is_debug()) {
01316         downloader_cat.debug()
01317           << "Unable to skip body.\n";
01318       }
01319       reset_to_new();
01320       
01321     } else {
01322       _state = S_reading_body;
01323     }
01324   }
01325 
01326   return false;
01327 }
01328 
01329 ////////////////////////////////////////////////////////////////////
01330 //     Function: HTTPChannel::run_reading_body
01331 //       Access: Private
01332 //  Description: In this state we are in the process of reading the
01333 //               response's body.  We will only come to this function
01334 //               if the user did not choose to read the entire body
01335 //               himself (by calling read_body(), for instance, or
01336 //               open_read_file()).
01337 //
01338 //               In this case we should skip past the body to reset
01339 //               the connection for making a new request.
01340 ////////////////////////////////////////////////////////////////////
01341 bool HTTPChannel::
01342 run_reading_body() {
01343   if (will_close_connection()) {
01344     // If the socket will close anyway, no point in skipping past the
01345     // previous body; just reset.
01346     reset_to_new();
01347     return false;
01348   }
01349 
01350   // Skip the body we've already started.
01351   if (_body_stream == NULL) {
01352     // Whoops, we're not in skip-body mode.  Better reset.
01353     reset_to_new();
01354     return false;
01355   }
01356 
01357   string line;
01358   getline(*_body_stream, line);
01359   while (!_body_stream->fail() && !_body_stream->eof()) {
01360     if (downloader_cat.is_spam()) {
01361       downloader_cat.spam() << "skip: " << line << "\n";
01362     }
01363     getline(*_body_stream, line);
01364   }
01365 
01366   if (!_body_stream->is_closed()) {
01367     // There's more to come later.
01368     return true;
01369   }
01370 
01371   delete _body_stream;
01372   _body_stream = NULL;
01373 
01374   // This should have been set by the _body_stream finishing.
01375   nassertr(_state != S_reading_body, false);
01376   return false;
01377 }
01378 
01379 ////////////////////////////////////////////////////////////////////
01380 //     Function: HTTPChannel::run_read_body
01381 //       Access: Private
01382 //  Description: In this state we have completely read (or skipped
01383 //               over) the body of the response.  We should continue
01384 //               skipping past the trailer following the body.
01385 //
01386 //               Not all bodies come with trailers; in particular, the
01387 //               "identity" transfer encoding does not include a
01388 //               trailer.  It is therefore the responsibility of the
01389 //               IdentityStreamBuf or ChunkedStreamBuf to set the
01390 //               state appropriately to either S_read_body or
01391 //               S_read_trailer following the completion of the body.
01392 ////////////////////////////////////////////////////////////////////
01393 bool HTTPChannel::
01394 run_read_body() {
01395   if (will_close_connection()) {
01396     // If the socket will close anyway, no point in skipping past the
01397     // previous body; just reset.
01398     reset_to_new();
01399     return false;
01400   }
01401   // Skip the trailer following the recently-read body.
01402 
01403   string line;
01404   if (!http_getline(line)) {
01405     return true;
01406   }
01407   while (!line.empty()) {
01408     if (!http_getline(line)) {
01409       return true;
01410     }
01411   }
01412 
01413   _state = S_read_trailer;
01414   return false;
01415 }
01416 
01417 ////////////////////////////////////////////////////////////////////
01418 //     Function: HTTPChannel::run_read_trailer
01419 //       Access: Private
01420 //  Description: In this state we have completely read the body and
01421 //               the trailer.  This state is simply a pass-through
01422 //               back to S_ready.
01423 ////////////////////////////////////////////////////////////////////
01424 bool HTTPChannel::
01425 run_read_trailer() {
01426   if (will_close_connection()) {
01427     // If the socket will close anyway, no point in skipping past the
01428     // previous body; just reset.
01429     reset_to_new();
01430     return false;
01431   }
01432 
01433   if (!_proxy.empty() && !_proxy_tunnel) {
01434     _state = S_proxy_ready;
01435   } else {
01436     _state = S_ready;
01437   }
01438   return false;
01439 }
01440 
01441 ////////////////////////////////////////////////////////////////////
01442 //     Function: HTTPChannel::run_download_to_file
01443 //       Access: Private
01444 //  Description: After the headers, etc. have been read, this streams
01445 //               the download to the named file.
01446 ////////////////////////////////////////////////////////////////////
01447 bool HTTPChannel::
01448 run_download_to_file() {
01449   nassertr(_body_stream != (ISocketStream *)NULL, false);
01450 
01451   bool do_throttle = _nonblocking && _download_throttle;
01452   int count = 0;
01453 
01454   int ch = _body_stream->get();
01455   nassertr(_body_stream != (ISocketStream *)NULL, false);
01456   while (!_body_stream->eof() && !_body_stream->fail()) {
01457     _download_to_file.put(ch);
01458     _bytes_downloaded++;
01459     if (do_throttle && (++count >= _bytes_per_update)) {
01460       // That's enough for now.
01461       return true;
01462     }
01463 
01464     ch = _body_stream->get();
01465     nassertr(_body_stream != (ISocketStream *)NULL, false);
01466   }
01467 
01468   if (_download_to_file.fail()) {
01469     downloader_cat.warning()
01470       << "Error writing to " << _download_to_filename << "\n";
01471     _state = S_failure;
01472     _download_to_file.close();
01473     return false;
01474   }
01475 
01476   if (_body_stream->is_closed()) {
01477     // Done.
01478     _download_to_file.close();
01479     return false;
01480   } else {
01481     // More to come.
01482     return true;
01483   }
01484 }
01485 
01486 ////////////////////////////////////////////////////////////////////
01487 //     Function: HTTPChannel::run_download_to_ram
01488 //       Access: Private
01489 //  Description: After the headers, etc. have been read, this streams
01490 //               the download to the specified Ramfile object.
01491 ////////////////////////////////////////////////////////////////////
01492 bool HTTPChannel::
01493 run_download_to_ram() {
01494   nassertr(_body_stream != (ISocketStream *)NULL, false);
01495   nassertr(_download_to_ramfile != (Ramfile *)NULL, false);
01496 
01497   bool do_throttle = _nonblocking && _download_throttle;
01498   int count = 0;
01499 
01500   int ch = _body_stream->get();
01501   nassertr(_body_stream != (ISocketStream *)NULL, false);
01502   while (!_body_stream->eof() && !_body_stream->fail()) {
01503     _download_to_ramfile->_data += (char)ch;
01504     _bytes_downloaded++;
01505     if (do_throttle && (++count >= _bytes_per_update)) {
01506       // That's enough for now.
01507       return true;
01508     }
01509 
01510     ch = _body_stream->get();
01511     nassertr(_body_stream != (ISocketStream *)NULL, false);
01512   }
01513 
01514   if (_body_stream->is_closed()) {
01515     // Done.
01516     return false;
01517   } else {
01518     // More to come.
01519     return true;
01520   }
01521 }
01522 
01523 
01524 ////////////////////////////////////////////////////////////////////
01525 //     Function: HTTPChannel::begin_request
01526 //       Access: Private
01527 //  Description: Begins a new document request to the server, throwing
01528 //               away whatever request was currently pending if
01529 //               necessary.
01530 ////////////////////////////////////////////////////////////////////
01531 void HTTPChannel::
01532 begin_request(HTTPEnum::Method method, const DocumentSpec &url,
01533               const string &body, bool nonblocking, 
01534               size_t first_byte, size_t last_byte) {
01535   reset_for_new_request();
01536 
01537   // Changing the proxy, or the nonblocking state, is grounds for
01538   // dropping the old connection, if any.
01539   if (_proxy != _client->get_proxy()) {
01540     _proxy = _client->get_proxy();
01541     reset_to_new();
01542   }
01543 
01544   if (_nonblocking != nonblocking) {
01545     _nonblocking = nonblocking;
01546     reset_to_new();
01547   }
01548 
01549   reset_url(_request.get_url(), url.get_url());
01550   _request = url;
01551   _document_spec = DocumentSpec();
01552   _method = method;
01553   _body = body;
01554 
01555   // An https-style request means we'll need to establish an SSL
01556   // connection.
01557   _want_ssl = (_request.get_url().get_scheme() == "https");
01558 
01559   // If we have a proxy, we'll be asking the proxy to hand us the
01560   // document--except when we also have https, in which case we'll be
01561   // tunnelling through the proxy to talk to the server directly.
01562   _proxy_serves_document = (!_proxy.empty() && !_want_ssl);
01563 
01564   _first_byte = first_byte;
01565   _last_byte = last_byte;
01566   _connect_count = 0;
01567 
01568   make_header();
01569   make_request_text();
01570 
01571   if (!_proxy.empty() && (_want_ssl || _method == HTTPEnum::M_connect)) {
01572     // Maybe we need to tunnel through the proxy to connect to the
01573     // server directly.  We need this for HTTPS, or if the user
01574     // requested a direct connection somewhere.
01575     ostringstream request;
01576     request 
01577       << "CONNECT " << _request.get_url().get_server_and_port()
01578       << " " << _client->get_http_version_string() << "\r\n";
01579     if (_client->get_http_version() >= HTTPEnum::HV_11) {
01580       request 
01581         << "Host: " << _request.get_url().get_server() << "\r\n";
01582     }
01583     _proxy_header = request.str();
01584     make_proxy_request_text();
01585 
01586   } else {
01587     _proxy_header = string();
01588     _proxy_request_text = string();
01589   }
01590 
01591   // Also, reset from whatever previous request might still be pending.
01592   if (_state == S_failure || (_state < S_read_header && _state != S_ready)) {
01593     reset_to_new();
01594 
01595   } else if (_state == S_read_header) {
01596     // Roll one step forwards to start skipping past the previous
01597     // body.
01598     _state = S_begin_body;
01599   }
01600 
01601   _done_state = (_method == HTTPEnum::M_connect) ? S_ready : S_read_header;
01602 }
01603 
01604 ////////////////////////////////////////////////////////////////////
01605 //     Function: HTTPChannel::reset_for_new_request
01606 //       Access: Private
01607 //  Description: Resets the internal state variables in preparation
01608 //               for beginning a new request.
01609 ////////////////////////////////////////////////////////////////////
01610 void HTTPChannel::
01611 reset_for_new_request() {
01612   reset_download_to();
01613   _last_status_code = 0;
01614   _response_type = RT_none;
01615   _redirect_trail.clear();
01616   _bytes_downloaded = 0;
01617   _bytes_requested = 0;
01618 }
01619 
01620 ////////////////////////////////////////////////////////////////////
01621 //     Function: HTTPChannel::finished_body
01622 //       Access: Private
01623 //  Description: This is called by the body reading
01624 //               classes--ChunkedStreamBuf and IdentityStreamBuf--when
01625 //               they have finished reading the body.  It advances the
01626 //               state appropriately.
01627 //
01628 //               has_trailer should be set true if the body type has
01629 //               an associated trailer which should be read or
01630 //               skipped, or false if there is no trailer.
01631 ////////////////////////////////////////////////////////////////////
01632 void HTTPChannel::
01633 finished_body(bool has_trailer) {
01634   if (will_close_connection() && _download_dest == DD_none) {
01635     reset_to_new();
01636 
01637   } else {
01638     if (has_trailer) {
01639       _state = HTTPChannel::S_read_body;
01640     } else {
01641       _state = HTTPChannel::S_read_trailer;
01642     }
01643   }
01644 }
01645 
01646 ////////////////////////////////////////////////////////////////////
01647 //     Function: HTTPChannel::reset_download_position
01648 //       Access: Private
01649 //  Description: If a download has been requested, seeks within the
01650 //               download file to the appropriate first_byte position,
01651 //               so that downloaded bytes will be written to the
01652 //               appropriate point within the file.  Returns true if
01653 //               the starting position is valid, false otherwise.
01654 ////////////////////////////////////////////////////////////////////
01655 bool HTTPChannel::
01656 reset_download_position() {
01657   if (_subdocument_resumes) {
01658     if (_download_dest == DD_file) {
01659       // Windows doesn't complain if you try to seek past the end of
01660       // file--it happily appends enough zero bytes to make the
01661       // difference.  Blecch.  That means we need to get the file size
01662       // first to check it ourselves.
01663       _download_to_file.seekp(0, ios::end);
01664       if (_first_byte > (size_t)_download_to_file.tellp()) {
01665         downloader_cat.info()
01666           << "Invalid starting position of byte " << _first_byte << " within "
01667           << _download_to_filename << " (which has " 
01668           << _download_to_file.tellp() << " bytes)\n";
01669         _download_to_file.close();
01670         return false;
01671       }
01672       
01673       _download_to_file.seekp(_first_byte);
01674       
01675     } else if (_download_dest == DD_ram) {
01676       if (_first_byte > _download_to_ramfile->_data.length()) {
01677         downloader_cat.info()
01678           << "Invalid starting position of byte " << _first_byte 
01679           << " within Ramfile (which has " 
01680           << _download_to_ramfile->_data.length() << " bytes)\n";
01681         return false;
01682       }
01683 
01684       if (_first_byte == 0) {
01685         _download_to_ramfile->_data = string();
01686       } else {
01687         _download_to_ramfile->_data = 
01688           _download_to_ramfile->_data.substr(0, _first_byte);
01689       }
01690     }
01691 
01692   } else {
01693     // If _subdocument_resumes is false, we should be sure to reset to
01694     // the beginning of the file, regardless of the value of
01695     // _first_byte.
01696     if (_download_dest == DD_file) {
01697       _download_to_file.seekp(0);
01698     } else if (_download_dest == DD_ram) {
01699       _download_to_ramfile->_data = string();
01700     }
01701   }
01702 
01703   return true;
01704 }
01705 
01706 
01707 ////////////////////////////////////////////////////////////////////
01708 //     Function: HTTPChannel::http_getline
01709 //       Access: Private
01710 //  Description: Reads a single line from the server's reply.  Returns
01711 //               true if the line is successfully retrieved, or false
01712 //               if a complete line has not yet been received or if
01713 //               the connection has been closed.
01714 ////////////////////////////////////////////////////////////////////
01715 bool HTTPChannel::
01716 http_getline(string &str) {
01717   nassertr(!_source.is_null(), false);
01718   int ch = (*_source)->get();
01719   while (!(*_source)->eof() && !(*_source)->fail()) {
01720     switch (ch) {
01721     case '\n':
01722       // end-of-line character, we're done.
01723       str = _working_getline;
01724       _working_getline = string();
01725       {
01726         // Trim trailing whitespace.  We're not required to do this per the
01727         // HTTP spec, but let's be generous.
01728         size_t p = str.length();
01729         while (p > 0 && isspace(str[p - 1])) {
01730           --p;
01731         }
01732         str = str.substr(0, p);
01733       }
01734       if (downloader_cat.is_spam()) {
01735         downloader_cat.spam() << "recv: " << str << "\n";
01736       }
01737       return true;
01738 
01739     case '\r':
01740       // Ignore CR characters.
01741       break;
01742 
01743     default:
01744       _working_getline += (char)ch;
01745     }
01746     ch = (*_source)->get();
01747   }
01748 
01749   check_socket();
01750   return false;
01751 }
01752 
01753 ////////////////////////////////////////////////////////////////////
01754 //     Function: HTTPChannel::http_send
01755 //       Access: Private
01756 //  Description: Sends a series of lines to the server.  Returns true
01757 //               if the buffer is fully sent, or false if some of it
01758 //               remains.  If this returns false, the function must be
01759 //               called again later, passing in the exact same string,
01760 //               until the return value is true.
01761 ////////////////////////////////////////////////////////////////////
01762 bool HTTPChannel::
01763 http_send(const string &str) {
01764   nassertr(str.length() > _sent_so_far, true);
01765 
01766   // Use the underlying BIO to write to the server, instead of the
01767   // BIOStream, which would insist on blocking (and might furthermore
01768   // delay the send due to collect-tcp mode being enabled).
01769   size_t bytes_to_send = str.length() - _sent_so_far;
01770   int write_count =
01771     BIO_write(*_bio, str.data() + _sent_so_far, bytes_to_send);
01772     
01773   if (write_count <= 0) {
01774     if (BIO_should_retry(*_bio)) {
01775       // Temporary failure: the pipe is full.  Wait till later.
01776       return false;
01777     }
01778     // Oops, the connection has been closed!
01779     if (downloader_cat.is_debug()) {
01780       downloader_cat.debug()
01781         << "Lost connection to server unexpectedly during write.\n";
01782     }
01783     reset_to_new();
01784     return false;
01785   }
01786   
01787 #ifndef NDEBUG
01788   if (downloader_cat.is_spam()) {
01789     show_send(str.substr(0, write_count));
01790   }
01791 #endif
01792   
01793   if (write_count < (int)bytes_to_send) {
01794     _sent_so_far += write_count;
01795     return false;
01796   }
01797 
01798   // Buffer completely sent.
01799   _sent_so_far = 0;
01800   return true;
01801 }
01802 
01803 ////////////////////////////////////////////////////////////////////
01804 //     Function: HTTPChannel::parse_http_response
01805 //       Access: Private
01806 //  Description: Parses the first line sent back from an HTTP server
01807 //               or proxy and stores the result in _status_code and
01808 //               _http_version, etc.  Returns true on success, false
01809 //               on invalid response.
01810 ////////////////////////////////////////////////////////////////////
01811 bool HTTPChannel::
01812 parse_http_response(const string &line) {
01813   // The first line back should include the HTTP version and the
01814   // result code.
01815   if (line.length() < 5 || line.substr(0, 5) != string("HTTP/")) {
01816     // Not an HTTP response.
01817     _status_code = 0;
01818     _status_string = "Not an HTTP response";
01819     if (_response_type == RT_non_http) {
01820       // This was our second non-HTTP response in a row.  Give up.
01821       _state = S_failure;
01822 
01823     } else {
01824       // Maybe we were just in some bad state.  Drop the connection
01825       // and try again, once.
01826       reset_to_new();
01827       _response_type = RT_non_http;
01828     }
01829     return false;
01830   }
01831 
01832   // Split out the first line into its three components.
01833   size_t p = 5;
01834   while (p < line.length() && !isspace(line[p])) {
01835     p++;
01836   }
01837   _http_version_string = line.substr(0, p);
01838   _http_version = HTTPClient::parse_http_version_string(_http_version_string);
01839 
01840   while (p < line.length() && isspace(line[p])) {
01841     p++;
01842   }
01843   size_t q = p;
01844   while (q < line.length() && !isspace(line[q])) {
01845     q++;
01846   }
01847   string status_code = line.substr(p, q - p);
01848   _status_code = atoi(status_code.c_str());
01849 
01850   while (q < line.length() && isspace(line[q])) {
01851     q++;
01852   }
01853   _status_string = line.substr(q, line.length() - q);
01854 
01855   return true;
01856 }
01857 
01858 ////////////////////////////////////////////////////////////////////
01859 //     Function: HTTPChannel::parse_http_header
01860 //       Access: Private
01861 //  Description: Reads the series of header lines from the server and
01862 //               stores them in _headers.  Returns true if there is
01863 //               more to read, false when done.
01864 ////////////////////////////////////////////////////////////////////
01865 bool HTTPChannel::
01866 parse_http_header() {
01867   string line;
01868   if (!http_getline(line)) {
01869     return true;
01870   }
01871 
01872   while (!line.empty()) {
01873     if (isspace(line[0])) {
01874       // If the line begins with a space, that continues the previous
01875       // field.
01876       size_t p = 0;
01877       while (p < line.length() && isspace(line[p])) {
01878         p++;
01879       }
01880       _current_field_value += line.substr(p - 1);
01881 
01882     } else {
01883       // If the line does not begin with a space, that defines a new
01884       // field.
01885       if (!_current_field_name.empty()) {
01886         store_header_field(_current_field_name, _current_field_value);
01887         _current_field_value = string();
01888       }
01889 
01890       size_t colon = line.find(':');
01891       if (colon != string::npos) {
01892         _current_field_name = downcase(line.substr(0, colon));
01893         size_t p = colon + 1;
01894         while (p < line.length() && isspace(line[p])) {
01895           p++;
01896         }
01897         _current_field_value = line.substr(p);
01898       }
01899     }
01900 
01901     if (!http_getline(line)) {
01902       return true;
01903     }
01904   }
01905 
01906   // After reading an empty line, we're done with the headers.
01907   if (!_current_field_name.empty()) {
01908     store_header_field(_current_field_name, _current_field_value);
01909     _current_field_value = string();
01910   }
01911 
01912   return false;
01913 }
01914 
01915 ////////////////////////////////////////////////////////////////////
01916 //     Function: HTTPChannel::parse_content_range
01917 //       Access: Private
01918 //  Description: Interprets the "Content-Range" header in the reply,
01919 //               and fills in _first_byte and _last_byte appropriately
01920 //               if the header response can be understood.
01921 ////////////////////////////////////////////////////////////////////
01922 bool HTTPChannel::
01923 parse_content_range(const string &content_range) {
01924   // First, get the units indication.
01925   size_t p = 0;
01926   while (p < content_range.length() && !isspace(content_range[p])) {
01927     p++;
01928   }
01929 
01930   string units = content_range.substr(0, p);
01931   while (p < content_range.length() && isspace(content_range[p])) {
01932     p++;
01933   }
01934 
01935   if (units == "bytes") {
01936     const char *c_str = content_range.c_str();
01937     char *endptr;
01938     if (p < content_range.length() && isdigit(content_range[p])) {
01939       long first_byte = strtol(c_str + p, &endptr, 10);
01940       p = endptr - c_str;
01941       if (p < content_range.length() && content_range[p] == '-') {
01942         p++;
01943         if (p < content_range.length() && isdigit(content_range[p])) {
01944           long last_byte = strtol(c_str + p, &endptr, 10);
01945           p = endptr - c_str;
01946           
01947           if (last_byte >= first_byte) {
01948             _first_byte = first_byte;
01949             _last_byte = last_byte;
01950             return true;
01951           }
01952         }
01953       }
01954     }
01955   }
01956     
01957   // Invalid or unhandled response.
01958   return false;
01959 }
01960 
01961 
01962 ////////////////////////////////////////////////////////////////////
01963 //     Function: HTTPChannel::check_socket
01964 //       Access: Private
01965 //  Description: Checks whether the connection to the server has been
01966 //               closed after a failed read.  If it has, issues a
01967 //               warning and calls reset_to_new().
01968 ////////////////////////////////////////////////////////////////////
01969 void HTTPChannel::
01970 check_socket() {
01971   nassertv(!_source.is_null());
01972   if ((*_source)->is_closed()) {
01973     if (downloader_cat.is_debug()) {
01974       downloader_cat.debug()
01975         << "Lost connection to server unexpectedly during read.\n";
01976     }
01977     reset_to_new();
01978   }
01979 }
01980 
01981 ////////////////////////////////////////////////////////////////////
01982 //     Function: HTTPChannel::verify_server
01983 //       Access: Private
01984 //  Description: Returns true if the indicated server matches one of
01985 //               our expected servers (or the list of expected servers
01986 //               is empty), or false if it does not match any of our
01987 //               expected servers.
01988 ////////////////////////////////////////////////////////////////////
01989 bool HTTPChannel::
01990 verify_server(X509_NAME *subject) const {
01991   if (_client->_expected_servers.empty()) {
01992     if (downloader_cat.is_debug()) {
01993       downloader_cat.debug()
01994         << "No expected servers on list; allowing any https connection.\n";
01995     }
01996     return true;
01997   }
01998 
01999   if (downloader_cat.is_debug()) {
02000     downloader_cat.debug() << "checking server: " << flush;
02001     X509_NAME_print_ex_fp(stderr, subject, 0, 0);
02002     fflush(stderr);
02003     downloader_cat.debug(false) << "\n";
02004   }
02005 
02006   HTTPClient::ExpectedServers::const_iterator ei;
02007   for (ei = _client->_expected_servers.begin();
02008        ei != _client->_expected_servers.end();
02009        ++ei) {
02010     X509_NAME *expected_name = (*ei);
02011     if (x509_name_subset(expected_name, subject)) {
02012       if (downloader_cat.is_debug()) {
02013         downloader_cat.debug()
02014           << "Match found!\n";
02015       }
02016       return true;
02017     }
02018   }
02019 
02020   // None of the lines matched.
02021   if (downloader_cat.is_debug()) {
02022     downloader_cat.debug()
02023       << "No match found against any of the following expected servers:\n";
02024 
02025     for (ei = _client->_expected_servers.begin();
02026          ei != _client->_expected_servers.end();
02027          ++ei) {
02028       X509_NAME *expected_name = (*ei);
02029       X509_NAME_print_ex_fp(stderr, expected_name, 0, 0);
02030       fputs("\n", stderr);
02031     }
02032     fflush(stderr);      
02033   }
02034   
02035   return false;
02036 }
02037 
02038 /*
02039    Certificate verify error codes:
02040 
02041 0 X509_V_OK: ok
02042 
02043     the operation was successful.
02044 
02045 2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate
02046 
02047     the issuer certificate could not be found: this occurs if the
02048     issuer certificate of an untrusted certificate cannot be found.
02049 
02050 3 X509_V_ERR_UNABLE_TO_GET_CRL unable to get certificate CRL
02051 
02052     the CRL of a certificate could not be found. Unused.
02053 
02054 4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt
02055 certificate's signature
02056 
02057     the certificate signature could not be decrypted. This means that
02058     the actual signature value could not be determined rather than it
02059     not matching the expected value, this is only meaningful for RSA
02060     keys.
02061 
02062 5 X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature
02063 
02064     the CRL signature could not be decrypted: this means that the
02065     actual signature value could not be determined rather than it not
02066     matching the expected value. Unused.
02067 
02068 6 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode
02069 issuer public key
02070 
02071     the public key in the certificate SubjectPublicKeyInfo could not
02072     be read.
02073 
02074 7 X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure
02075 
02076     the signature of the certificate is invalid.
02077 
02078 8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure
02079 
02080     the signature of the certificate is invalid. Unused.
02081 
02082 9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid
02083 
02084     the certificate is not yet valid: the notBefore date is after the
02085     current time.
02086 
02087 10 X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired
02088 
02089     the certificate has expired: that is the notAfter date is before
02090     the current time.
02091 
02092 11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid
02093 
02094     the CRL is not yet valid. Unused.
02095 
02096 12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired
02097 
02098     the CRL has expired. Unused.
02099 
02100 13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in
02101 certificate's notBefore field
02102 
02103     the certificate notBefore field contains an invalid time.
02104 
02105 14 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in
02106 certificate's notAfter field
02107 
02108     the certificate notAfter field contains an invalid time.
02109 
02110 15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's
02111 lastUpdate field
02112 
02113     the CRL lastUpdate field contains an invalid time. Unused.
02114 
02115 16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's
02116 nextUpdate field
02117 
02118     the CRL nextUpdate field contains an invalid time. Unused.
02119 
02120 17 X509_V_ERR_OUT_OF_MEM: out of memory
02121 
02122     an error occurred trying to allocate memory. This should never
02123     happen.
02124 
02125 18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate
02126 
02127     the passed certificate is self signed and the same certificate
02128     cannot be found in the list of trusted certificates.
02129 
02130 19 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in
02131 certificate chain
02132 
02133     the certificate chain could be built up using the untrusted
02134     certificates but the root could not be found locally.
02135 
02136 20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local
02137 issuer certificate
02138 
02139     the issuer certificate of a locally looked up certificate could
02140     not be found. This normally means the list of trusted certificates
02141     is not complete.
02142 
02143 21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the
02144 first certificate
02145 
02146     no signatures could be verified because the chain contains only
02147     one certificate and it is not self signed.
02148 
02149 22 X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long
02150 
02151     the certificate chain length is greater than the supplied maximum
02152     depth. Unused.
02153 
02154 23 X509_V_ERR_CERT_REVOKED: certificate revoked
02155 
02156     the certificate has been revoked. Unused.
02157 
02158 24 X509_V_ERR_INVALID_CA: invalid CA certificate
02159 
02160     a CA certificate is invalid. Either it is not a CA or its
02161     extensions are not consistent with the supplied purpose.
02162 
02163 25 X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded
02164 
02165     the basicConstraints pathlength parameter has been exceeded.
02166 
02167 26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose
02168 
02169     the supplied certificate cannot be used for the specified purpose.
02170 
02171 27 X509_V_ERR_CERT_UNTRUSTED: certificate not trusted
02172 
02173     the root CA is not marked as trusted for the specified purpose.
02174 
02175 28 X509_V_ERR_CERT_REJECTED: certificate rejected
02176 
02177     the root CA is marked to reject the specified purpose.
02178 
02179 29 X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch
02180 
02181     the current candidate issuer certificate was rejected because its
02182     subject name did not match the issuer name of the current
02183     certificate. Only displayed when the -issuer_checks option is set.
02184 
02185 30 X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier
02186 mismatch
02187 
02188     the current candidate issuer certificate was rejected because its
02189     subject key identifier was present and did not match the authority
02190     key identifier current certificate. Only displayed when the
02191     -issuer_checks option is set.
02192 
02193 31 X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial
02194 number mismatch
02195 
02196     the current candidate issuer certificate was rejected because its
02197     issuer name and serial number was present and did not match the
02198     authority key identifier of the current certificate. Only
02199     displayed when the -issuer_checks option is set.
02200 
02201 32 X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include
02202 certificate signing
02203 
02204     the current candidate issuer certificate was rejected because its
02205     keyUsage extension does not permit certificate signing.
02206 
02207 50 X509_V_ERR_APPLICATION_VERIFICATION: application verification failure
02208 
02209     an application specific error. Unused.
02210 
02211 */
02212 
02213 ////////////////////////////////////////////////////////////////////
02214 //     Function: HTTPChannel::get_x509_name_component
02215 //       Access: Private, Static
02216 //  Description: Returns the indicated component of the X509 name as a
02217 //               string, if defined, or empty string if it is not.
02218 ////////////////////////////////////////////////////////////////////
02219 string HTTPChannel::
02220 get_x509_name_component(X509_NAME *name, int nid) {
02221   ASN1_OBJECT *obj = OBJ_nid2obj(nid);
02222 
02223   if (obj == NULL) {
02224     // Unknown nid.  See openssl/objects.h.
02225     return string();
02226   }
02227 
02228   int i = X509_NAME_get_index_by_OBJ(name, obj, -1);
02229   if (i < 0) {
02230     return string();
02231   }
02232 
02233   ASN1_STRING *data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
02234   return string((char *)data->data, data->length);  
02235 }
02236 
02237 ////////////////////////////////////////////////////////////////////
02238 //     Function: HTTPChannel::x509_name_subset
02239 //       Access: Private, Static
02240 //  Description: Returns true if name_a is a subset of name_b: each
02241 //               property of name_a is defined in name_b, and the
02242 //               defined value is equivalent to that of name_a.
02243 ////////////////////////////////////////////////////////////////////
02244 bool HTTPChannel::
02245 x509_name_subset(X509_NAME *name_a, X509_NAME *name_b) {
02246   int count_a = X509_NAME_entry_count(name_a);
02247   for (int ai = 0; ai < count_a; ai++) {
02248     X509_NAME_ENTRY *na = X509_NAME_get_entry(name_a, ai);
02249 
02250     int bi = X509_NAME_get_index_by_OBJ(name_b, na->object, -1);
02251     if (bi < 0) {
02252       // This entry in name_a is not defined in name_b.
02253       return false;
02254     }
02255 
02256     X509_NAME_ENTRY *nb = X509_NAME_get_entry(name_b, bi);
02257     if (na->value->length != nb->value->length ||
02258         memcmp(na->value->data, nb->value->data, na->value->length) != 0) {
02259       // This entry in name_a doesn't match that of name_b.
02260       return false;
02261     }
02262   }
02263   return true;
02264 }
02265 
02266 ////////////////////////////////////////////////////////////////////
02267 //     Function: HTTPChannel::make_header
02268 //       Access: Private
02269 //  Description: Formats the appropriate GET or POST (or whatever)
02270 //               request to send to the server, based on the current
02271 //               _method, _document_spec, _body, and _proxy settings.
02272 ////////////////////////////////////////////////////////////////////
02273 void HTTPChannel::
02274 make_header() {
02275   _proxy_auth = _client->select_auth(_proxy, true, _proxy_realm);
02276   _proxy_username = string();
02277   if (_proxy_auth != (HTTPAuthorization *)NULL) {
02278     _proxy_realm = _proxy_auth->get_realm();
02279     _proxy_username = _client->select_username(_proxy, true, _proxy_realm);
02280   }
02281 
02282   if (_method == HTTPEnum::M_connect) {
02283     // This method doesn't require an HTTP header at all; we'll just
02284     // open a plain connection.  (Except when we're using a proxy; but
02285     // in that case, it's the proxy_header we'll need, not the regular
02286     // HTTP header.)
02287     _header = string();
02288     return;
02289   }
02290 
02291   _www_auth = _client->select_auth(_request.get_url(), false, _www_realm);
02292   _www_username = string();
02293   if (_www_auth != (HTTPAuthorization *)NULL) {
02294     _www_realm = _www_auth->get_realm();
02295     _www_username = _client->select_username(_request.get_url(), false, _www_realm);
02296   }
02297 
02298   string request_path;
02299   if (_proxy_serves_document) {
02300     // If we'll be asking the proxy for the document, we need its full
02301     // URL--but we omit the username, which is information just for us.
02302     URLSpec url_no_username = _request.get_url();
02303     url_no_username.set_username(string());
02304     request_path = url_no_username.get_url();
02305 
02306   } else {
02307     // If we'll be asking the server directly for the document, we
02308     // just want its path relative to the server.
02309     request_path = _request.get_url().get_path();
02310   }
02311 
02312   // HTTP syntax always requires something in the request path.  If it
02313   // is empty, put in a star as a placeholder (OPTIONS, for instance,
02314   // uses this).
02315   if (request_path.empty()) {
02316     request_path = "*";
02317   }
02318 
02319   ostringstream stream;
02320 
02321   stream 
02322     << _method << " " << request_path << " " 
02323     << _client->get_http_version_string() << "\r\n";
02324 
02325   if (_client->get_http_version() >= HTTPEnum::HV_11) {
02326     stream 
02327       << "Host: " << _request.get_url().get_server() << "\r\n";
02328     if (!get_persistent_connection()) {
02329       stream
02330         << "Connection: close\r\n";
02331     }
02332   }
02333 
02334   if (_last_byte != 0) {
02335     stream 
02336       << "Range: bytes=" << _first_byte << "-" << _last_byte << "\r\n";
02337 
02338   } else if (_first_byte != 0) {
02339     stream 
02340       << "Range: bytes=" << _first_byte << "-\r\n";
02341   }
02342 
02343   switch (_request.get_request_mode()) {
02344   case DocumentSpec::RM_any:
02345     // No particular request; give us any document that matches the
02346     // URL.  
02347     if (_first_byte != 0) {
02348       // Unless we're requesting a subrange, in which case if the
02349       // exact document matches, retrieve the subrange indicated;
02350       // otherwise, retrieve the entire document.
02351       if (_request.has_tag()) {
02352         stream
02353           << "If-Range: " << _request.get_tag().get_string() << "\r\n";
02354       } else if (_request.has_date()) {
02355         stream
02356           << "If-Range: " << _request.get_date().get_string() << "\r\n";
02357       }
02358     }
02359     break;
02360 
02361   case DocumentSpec::RM_equal:
02362     // Give us only this particular version of the document, or
02363     // nothing.
02364     if (_request.has_tag()) {
02365       stream
02366         << "If-Match: " << _request.get_tag().get_string() << "\r\n";
02367     }
02368     if (_request.has_date()) {
02369       stream
02370         << "If-Unmodified-Since: " << _request.get_date().get_string()
02371         << "\r\n";
02372     }
02373     break;
02374 
02375   case DocumentSpec::RM_newer:
02376     // Give us anything newer than this document, or nothing.
02377     if (_request.has_tag()) {
02378       stream
02379         << "If-None-Match: " << _request.get_tag().get_string() << "\r\n";
02380     }
02381     if (_request.has_date()) {
02382       stream
02383         << "If-Modified-Since: " << _request.get_date().get_string()
02384         << "\r\n";
02385     }
02386     break;
02387 
02388   case DocumentSpec::RM_equal_or_newer:
02389     // Just don't give us anything older.
02390     if (_request.has_date()) {
02391       // This is a little unreliable: we ask for any document that's
02392       // been modified since one second before our last-modified-date.
02393       // Who knows whether the server will honor this properly.
02394       stream
02395         << "If-Modified-Since: " << (_request.get_date() - 1).get_string()
02396         << "\r\n";
02397     }
02398     break;
02399   }
02400 
02401   switch (_request.get_cache_control()) {
02402   case DocumentSpec::CC_allow_cache:
02403     // Normal, caching behavior.
02404     break;
02405 
02406   case DocumentSpec::CC_revalidate:
02407     // Request the server to revalidate its cache before returning it.
02408     stream
02409       << "Cache-Control: max-age=0\r\n";
02410     break;
02411 
02412   case DocumentSpec::CC_no_cache:
02413     // Request the server to get a fresh copy regardless of its cache.
02414     stream
02415       << "Cache-Control: no-cache\r\n"
02416       << "Pragma: no-cache\r\n";
02417     break;
02418   }
02419 
02420   if (!_body.empty()) {
02421     stream
02422       << "Content-Type: application/x-www-form-urlencoded\r\n"
02423       << "Content-Length: " << _body.length() << "\r\n";
02424   }
02425 
02426   _header = stream.str();
02427 }
02428 
02429 ////////////////////////////////////////////////////////////////////
02430 //     Function: HTTPChannel::make_proxy_request_text
02431 //       Access: Private
02432 //  Description: Builds the _proxy_request_text string.  This is a
02433 //               special request that will be sent directly to the
02434 //               proxy prior to the request tailored for the server.
02435 //               Generally this is used to open a tunnelling
02436 //               connection for https-over-proxy.
02437 ////////////////////////////////////////////////////////////////////
02438 void HTTPChannel::
02439 make_proxy_request_text() {
02440   _proxy_request_text = _proxy_header;
02441 
02442   if (_proxy_auth != (HTTPAuthorization *)NULL && !_proxy_username.empty()) {
02443     _proxy_request_text += "Proxy-Authorization: ";
02444     _proxy_request_text += 
02445       _proxy_auth->generate(HTTPEnum::M_connect, _request.get_url().get_server_and_port(),
02446                             _proxy_username, _body);
02447     _proxy_request_text += "\r\n";
02448   }
02449     
02450   _proxy_request_text += "\r\n";
02451 }
02452 
02453 ////////////////////////////////////////////////////////////////////
02454 //     Function: HTTPChannel::make_request_text
02455 //       Access: Private
02456 //  Description: Builds the _request_text string.  This is the
02457 //               specific request that will be sent to the server this
02458 //               pass, based on the current header and body.
02459 ////////////////////////////////////////////////////////////////////
02460 void HTTPChannel::
02461 make_request_text() {
02462   _request_text = _header;
02463 
02464   if (!_proxy.empty() && !_proxy_tunnel &&
02465       _proxy_auth != (HTTPAuthorization *)NULL && !_proxy_username.empty()) {
02466     _request_text += "Proxy-Authorization: ";
02467     _request_text += 
02468       _proxy_auth->generate(_method, _request.get_url().get_url(), _proxy_username, _body);
02469     _request_text += "\r\n";
02470   }
02471 
02472   if (_www_auth != (HTTPAuthorization *)NULL && !_www_username.empty()) {
02473     string authorization = 
02474     _request_text += "Authorization: ";
02475     _request_text +=
02476       _www_auth->generate(_method, _request.get_url().get_path(), _www_username, _body);
02477     _request_text += "\r\n";
02478   }
02479 
02480   _request_text += _send_extra_headers;
02481   _request_text += "\r\n";
02482   _request_text += _body;
02483 }
02484   
02485 ////////////////////////////////////////////////////////////////////
02486 //     Function: HTTPChannel::reset_url
02487 //       Access: Private
02488 //  Description: Redirects the next connection to the indicated URL
02489 //               (from the previous URL).  This resets the socket if
02490 //               necessary when we are about to switch servers.
02491 ////////////////////////////////////////////////////////////////////
02492 void HTTPChannel::
02493 reset_url(const URLSpec &old_url, const URLSpec &new_url) {
02494   // If we change between http and https, we have to reset the
02495   // connection regardless of proxy.  Otherwise, we have to drop the
02496   // connection if the server or port changes, unless we're
02497   // communicating through a proxy.
02498 
02499   if (new_url.get_scheme() != old_url.get_scheme() ||
02500       (_proxy.empty() && (new_url.get_server() != old_url.get_server() || 
02501                           new_url.get_port() != old_url.get_port()))) {
02502     reset_to_new();
02503   }
02504 }
02505 
02506 ////////////////////////////////////////////////////////////////////
02507 //     Function: HTTPChannel::store_header_field
02508 //       Access: Private
02509 //  Description: Stores a single name: value pair in the header list,
02510 //               or appends the value to the end of the existing
02511 //               value, if the header has been repeated.
02512 ////////////////////////////////////////////////////////////////////
02513 void HTTPChannel::
02514 store_header_field(const string &field_name, const string &field_value) {
02515   pair<Headers::iterator, bool> insert_result =
02516     _headers.insert(Headers::value_type(field_name, field_value));
02517 
02518   if (!insert_result.second) {
02519     // It didn't insert; thus, the field already existed.  Append the
02520     // new value.
02521     Headers::iterator hi = insert_result.first;
02522     (*hi).second += ", ";
02523     (*hi).second += field_value;
02524   }
02525 }
02526 
02527 #ifndef NDEBUG
02528 ////////////////////////////////////////////////////////////////////
02529 //     Function: HTTPChannel::show_send
02530 //       Access: Private, Static
02531 //  Description: Writes the outgoing message, one line at a time, to
02532 //               the debugging log.
02533 ////////////////////////////////////////////////////////////////////
02534 void HTTPChannel::
02535 show_send(const string &message) {
02536   size_t start = 0;
02537   size_t newline = message.find('\n', start);
02538   while (newline != string::npos) {
02539     // Assume every \n is preceded by a \r.
02540     downloader_cat.spam()
02541       << "send: " << message.substr(start, newline - start - 1) << "\n";
02542     start = newline + 1;
02543     newline = message.find('\n', start);
02544   }
02545 
02546   if (start < message.length()) {
02547     downloader_cat.spam()
02548       << "send: " << message.substr(start) << " (no newline)\n";
02549   }
02550 }
02551 #endif   // NDEBUG
02552 
02553 ////////////////////////////////////////////////////////////////////
02554 //     Function: HTTPChannel::reset_download_to
02555 //       Access: Private
02556 //  Description: Resets the indication of how the document will be
02557 //               downloaded.  This must be re-specified after each
02558 //               get_document() (or related) call.
02559 ////////////////////////////////////////////////////////////////////
02560 void HTTPChannel::
02561 reset_download_to() {
02562   _started_download = false;
02563   _download_to_file.close();
02564   _download_to_ramfile = (Ramfile *)NULL;
02565   _download_dest = DD_none;
02566 }
02567 
02568 ////////////////////////////////////////////////////////////////////
02569 //     Function: HTTPChannel::reset_to_new
02570 //       Access: Private
02571 //  Description: Closes the connection and resets the state to S_new.
02572 ////////////////////////////////////////////////////////////////////
02573 void HTTPChannel::
02574 reset_to_new() {
02575   close_connection();
02576   _state = S_new;
02577 }
02578 
02579 ////////////////////////////////////////////////////////////////////
02580 //     Function: HTTPChannel::close_connection
02581 //       Access: Private
02582 //  Description: Closes the connection but leaves the _state
02583 //               unchanged.
02584 ////////////////////////////////////////////////////////////////////
02585 void HTTPChannel::
02586 close_connection() {
02587   if (_body_stream != (ISocketStream *)NULL) {
02588     delete _body_stream;
02589     _body_stream = (ISocketStream *)NULL;
02590   }
02591   _source.clear();
02592   _bio.clear();
02593   _working_getline = string();
02594   _sent_so_far = 0;
02595   _proxy_tunnel = false;
02596   _read_index++;
02597 }
02598 
02599 #endif  // HAVE_SSL

Generated on Fri May 2 00:36:48 2003 for Panda by doxygen1.3