diff --git a/panda/src/downloader/bioStream.cxx b/panda/src/downloader/bioStream.cxx index a1787080d6..04a5de966c 100644 --- a/panda/src/downloader/bioStream.cxx +++ b/panda/src/downloader/bioStream.cxx @@ -104,4 +104,20 @@ close() { _buf.close(); } +//////////////////////////////////////////////////////////////////// +// Function: IBioStream::get_read_state +// Access: Public, Virtual +// Description: Returns an enum indicating how we are coming along in +// reading the document. +//////////////////////////////////////////////////////////////////// +IBioStream::ReadState IBioStream:: +get_read_state() { + // For an IBioStream, this method is meaningless, and always returns + // RS_error. + + // This method is intended for those specialized streams that scan + // through an HTTP document. + return RS_error; +} + #endif // HAVE_OPENSSL diff --git a/panda/src/downloader/bioStream.h b/panda/src/downloader/bioStream.h index 1c386856ce..43e8ec0720 100644 --- a/panda/src/downloader/bioStream.h +++ b/panda/src/downloader/bioStream.h @@ -45,6 +45,7 @@ public: virtual bool is_closed(); virtual void close(); + virtual ReadState get_read_state(); private: BioStreamBuf _buf; diff --git a/panda/src/downloader/chunkedStream.cxx b/panda/src/downloader/chunkedStream.cxx index 6e10d9d522..ba4b75f8f6 100644 --- a/panda/src/downloader/chunkedStream.cxx +++ b/panda/src/downloader/chunkedStream.cxx @@ -48,4 +48,15 @@ close() { _buf.close_read(); } +//////////////////////////////////////////////////////////////////// +// Function: IChunkedStream::get_read_state +// Access: Public, Virtual +// Description: Returns an enum indicating how we are coming along in +// reading the document. +//////////////////////////////////////////////////////////////////// +IChunkedStream::ReadState IChunkedStream:: +get_read_state() { + return _buf.get_read_state(); +} + #endif // HAVE_OPENSSL diff --git a/panda/src/downloader/chunkedStream.h b/panda/src/downloader/chunkedStream.h index 3a6b9fe2ae..c24bc074b3 100644 --- a/panda/src/downloader/chunkedStream.h +++ b/panda/src/downloader/chunkedStream.h @@ -48,6 +48,7 @@ public: virtual bool is_closed(); virtual void close(); + virtual ReadState get_read_state(); private: ChunkedStreamBuf _buf; diff --git a/panda/src/downloader/chunkedStreamBuf.I b/panda/src/downloader/chunkedStreamBuf.I index 8a24f03e5e..27d6c33e21 100644 --- a/panda/src/downloader/chunkedStreamBuf.I +++ b/panda/src/downloader/chunkedStreamBuf.I @@ -26,3 +26,13 @@ INLINE bool ChunkedStreamBuf:: is_closed() const { return (_source == (BioStreamPtr *)NULL || (*_source)->is_closed()); } + +//////////////////////////////////////////////////////////////////// +// Function: ChunkedStreamBuf::get_read_state +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ISocketStream::ReadState ChunkedStreamBuf:: +get_read_state() const { + return _read_state; +} diff --git a/panda/src/downloader/chunkedStreamBuf.cxx b/panda/src/downloader/chunkedStreamBuf.cxx index 8b46eeecaf..27e7f5ff91 100644 --- a/panda/src/downloader/chunkedStreamBuf.cxx +++ b/panda/src/downloader/chunkedStreamBuf.cxx @@ -37,6 +37,7 @@ ChunkedStreamBuf:: ChunkedStreamBuf() { _chunk_remaining = 0; _done = true; + _read_state = ISocketStream::RS_initial; #ifdef HAVE_IOSTREAM char *buf = new char[4096]; @@ -74,6 +75,7 @@ open_read(BioStreamPtr *source, HTTPChannel *doc) { nassertv(!_source.is_null()); _chunk_remaining = 0; _done = false; + _read_state = ISocketStream::RS_reading; _doc = doc; if (_doc != (HTTPChannel *)NULL) { @@ -154,9 +156,7 @@ read_chars(char *start, size_t length) { if (read_count == 0 && (*_source)->is_closed()) { // Whoops, the socket closed while we were downloading. - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->_state = HTTPChannel::S_failure; - } + _read_state = ISocketStream::RS_error; } return read_count; @@ -175,9 +175,7 @@ read_chars(char *start, size_t length) { // EOF (or data unavailable) while trying to read the chunk size. if ((*_source)->is_closed()) { // Whoops, the socket closed while we were downloading. - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->_state = HTTPChannel::S_failure; - } + _read_state = ISocketStream::RS_error; } return 0; } @@ -192,9 +190,7 @@ read_chars(char *start, size_t length) { _done = true; _doc->_file_size = _doc->_transfer_file_size; _doc->_got_file_size = true; - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->finished_body(true); - } + _read_state = ISocketStream::RS_complete; return 0; } diff --git a/panda/src/downloader/chunkedStreamBuf.h b/panda/src/downloader/chunkedStreamBuf.h index 66dec0280a..38213398d1 100644 --- a/panda/src/downloader/chunkedStreamBuf.h +++ b/panda/src/downloader/chunkedStreamBuf.h @@ -43,6 +43,7 @@ public: void close_read(); INLINE bool is_closed() const; + INLINE ISocketStream::ReadState get_read_state() const; protected: virtual int underflow(); @@ -55,6 +56,7 @@ private: size_t _chunk_remaining; bool _done; string _working_getline; + ISocketStream::ReadState _read_state; PT(HTTPChannel) _doc; int _read_index; diff --git a/panda/src/downloader/httpChannel.cxx b/panda/src/downloader/httpChannel.cxx index 29ed1aafae..8a52c99bb5 100644 --- a/panda/src/downloader/httpChannel.cxx +++ b/panda/src/downloader/httpChannel.cxx @@ -830,7 +830,6 @@ reached_done_state() { } _started_download = true; - _done_state = S_read_trailer; _last_run_time = TrueClock::get_global_ptr()->get_short_time(); return true; @@ -2097,6 +2096,17 @@ run_download_to_file() { _download_to_file.flush(); + switch (_body_stream->get_read_state()) { + case ISocketStream::RS_complete: + finished_body(false); + break; + + case ISocketStream::RS_error: + _state = HTTPChannel::S_failure; + _status_entry._status_code = HTTPChannel::SC_lost_connection; + break; + } + if (_body_stream->is_closed()) { // Done. _download_to_file.close(); @@ -2147,6 +2157,17 @@ run_download_to_ram() { count = _body_stream->gcount(); } + switch (_body_stream->get_read_state()) { + case ISocketStream::RS_complete: + finished_body(false); + break; + + case ISocketStream::RS_error: + _state = HTTPChannel::S_failure; + _status_entry._status_code = HTTPChannel::SC_lost_connection; + break; + } + if (_body_stream->is_closed()) { // Done. _started_download = false; diff --git a/panda/src/downloader/identityStream.I b/panda/src/downloader/identityStream.I index dec1f077d7..5f1896f1a0 100644 --- a/panda/src/downloader/identityStream.I +++ b/panda/src/downloader/identityStream.I @@ -48,6 +48,6 @@ INLINE IIdentityStream &IIdentityStream:: open(BioStreamPtr *source, HTTPChannel *doc, bool has_content_length, size_t content_length) { clear((ios_iostate)0); - _buf.open_read(source, doc, has_content_length, content_length); + _buf.open_read(source, has_content_length, content_length); return *this; } diff --git a/panda/src/downloader/identityStream.cxx b/panda/src/downloader/identityStream.cxx index a11c1fe501..f95e8ffa64 100644 --- a/panda/src/downloader/identityStream.cxx +++ b/panda/src/downloader/identityStream.cxx @@ -49,4 +49,15 @@ close() { _buf.close_read(); } +//////////////////////////////////////////////////////////////////// +// Function: IIdentityStream::get_read_state +// Access: Public, Virtual +// Description: Returns an enum indicating how we are coming along in +// reading the document. +//////////////////////////////////////////////////////////////////// +INLINE IIdentityStream::ReadState IIdentityStream:: +get_read_state() { + return _buf.get_read_state(); +} + #endif // HAVE_OPENSSL diff --git a/panda/src/downloader/identityStream.h b/panda/src/downloader/identityStream.h index 4b7544d4e0..5e258e2d7e 100644 --- a/panda/src/downloader/identityStream.h +++ b/panda/src/downloader/identityStream.h @@ -55,6 +55,7 @@ public: virtual bool is_closed(); virtual void close(); + virtual ReadState get_read_state(); private: IdentityStreamBuf _buf; diff --git a/panda/src/downloader/identityStreamBuf.I b/panda/src/downloader/identityStreamBuf.I index 9941c76c98..a5a087926a 100644 --- a/panda/src/downloader/identityStreamBuf.I +++ b/panda/src/downloader/identityStreamBuf.I @@ -26,3 +26,13 @@ INLINE bool IdentityStreamBuf:: is_closed() const { return (_source == (BioStreamPtr *)NULL || (*_source)->is_closed()); } + +//////////////////////////////////////////////////////////////////// +// Function: IdentityStreamBuf::get_read_state +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ISocketStream::ReadState IdentityStreamBuf:: +get_read_state() const { + return _read_state; +} diff --git a/panda/src/downloader/identityStreamBuf.cxx b/panda/src/downloader/identityStreamBuf.cxx index 1b253f56d7..651beda7b1 100644 --- a/panda/src/downloader/identityStreamBuf.cxx +++ b/panda/src/downloader/identityStreamBuf.cxx @@ -35,6 +35,7 @@ IdentityStreamBuf:: IdentityStreamBuf() { _has_content_length = true; _bytes_remaining = 0; + _read_state = ISocketStream::RS_initial; #ifdef HAVE_IOSTREAM char *buf = new char[4096]; @@ -67,16 +68,12 @@ IdentityStreamBuf:: // from the identity encoding. //////////////////////////////////////////////////////////////////// void IdentityStreamBuf:: -open_read(BioStreamPtr *source, HTTPChannel *doc, +open_read(BioStreamPtr *source, bool has_content_length, size_t content_length) { _source = source; - _doc = doc; _has_content_length = has_content_length; _bytes_remaining = content_length; - - if (_doc != (HTTPChannel *)NULL) { - _read_index = doc->_read_index; - } + _read_state = ISocketStream::RS_reading; } //////////////////////////////////////////////////////////////////// @@ -142,9 +139,7 @@ read_chars(char *start, size_t length) { if (read_count == 0) { if ((*_source)->is_closed()) { // socket closed; we're done. - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->finished_body(false); - } + _read_state = ISocketStream::RS_complete; } return 0; } @@ -162,10 +157,7 @@ read_chars(char *start, size_t length) { if (read_count == 0) { if ((*_source)->is_closed()) { // socket closed unexpectedly; problem. - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->_state = HTTPChannel::S_failure; - _doc->_status_entry._status_code = HTTPChannel::SC_lost_connection; - } + _read_state = ISocketStream::RS_error; } return 0; } @@ -173,9 +165,7 @@ read_chars(char *start, size_t length) { if (_bytes_remaining == 0) { // We're done. - if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) { - _doc->finished_body(false); - } + _read_state = ISocketStream::RS_complete; } } diff --git a/panda/src/downloader/identityStreamBuf.h b/panda/src/downloader/identityStreamBuf.h index 51cfd9067c..2d155cf0ce 100644 --- a/panda/src/downloader/identityStreamBuf.h +++ b/panda/src/downloader/identityStreamBuf.h @@ -24,9 +24,9 @@ // This module is not compiled if OpenSSL is not available. #ifdef HAVE_OPENSSL -#include "httpChannel.h" #include "bioStreamPtr.h" #include "pointerTo.h" +#include "socketStream.h" //////////////////////////////////////////////////////////////////// // Class : IdentityStreamBuf @@ -38,11 +38,12 @@ public: IdentityStreamBuf(); virtual ~IdentityStreamBuf(); - void open_read(BioStreamPtr *source, HTTPChannel *doc, + void open_read(BioStreamPtr *source, bool has_content_length, size_t content_length); void close_read(); INLINE bool is_closed() const; + INLINE ISocketStream::ReadState get_read_state() const; protected: virtual int underflow(); @@ -53,9 +54,7 @@ private: PT(BioStreamPtr) _source; bool _has_content_length; size_t _bytes_remaining; - - PT(HTTPChannel) _doc; - int _read_index; + ISocketStream::ReadState _read_state; friend class IIdentityStream; }; diff --git a/panda/src/downloader/socketStream.h b/panda/src/downloader/socketStream.h index 1485e01c5d..2e47da47fa 100644 --- a/panda/src/downloader/socketStream.h +++ b/panda/src/downloader/socketStream.h @@ -126,8 +126,16 @@ public: INLINE ISocketStream(streambuf *buf); PUBLISHED: + enum ReadState { + RS_initial, + RS_reading, + RS_complete, + RS_error, + }; + virtual bool is_closed() = 0; virtual void close() = 0; + virtual ReadState get_read_state() = 0; }; ////////////////////////////////////////////////////////////////////