diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp index 00af8a34a30b1..61ffa8ddd164a 100644 --- a/media/libstagefright/HTTPDataSource.cpp +++ b/media/libstagefright/HTTPDataSource.cpp @@ -385,7 +385,8 @@ rinse_repeat: ssize_t num_bytes_received = mHttp->receive(mBuffer, contentLength); - if (num_bytes_received < 0) { + if (num_bytes_received < 0 + || (mContentLengthValid && num_bytes_received < contentLength)) { if (mNumRetriesLeft-- > 0) { disconnect(); if (connect() == OK) { diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp index 3aad72c5e47a4..1e06f03f1a4de 100644 --- a/media/libstagefright/HTTPStream.cpp +++ b/media/libstagefright/HTTPStream.cpp @@ -14,6 +14,10 @@ * limitations under the License. */ +//#define LOG_NDEBUG 0 +#define LOG_TAG "HTTPStream" +#include + #include "include/HTTPStream.h" #include @@ -146,6 +150,30 @@ status_t HTTPStream::send(const char *data) { return send(data, strlen(data)); } +static ssize_t recvWithTimeout( + int s, void *data, size_t size) { + fd_set rs, es; + FD_ZERO(&rs); + FD_ZERO(&es); + FD_SET(s, &rs); + FD_SET(s, &es); + + struct timeval tv; + tv.tv_sec = 5; // 5 sec timeout + tv.tv_usec = 0; + + int res = select(s + 1, &rs, NULL, &es, &tv); + + if (res < 0) { + return -1; + } else if (res == 0) { + errno = ETIMEDOUT; + return -1; + } + + return recv(s, data, size, 0); +} + // A certain application spawns a local webserver that sends invalid responses, // specifically it terminates header line with only a newline instead of the // CRLF (carriage-return followed by newline) required by the HTTP specs. @@ -164,7 +192,7 @@ status_t HTTPStream::receive_line(char *line, size_t size) { for (;;) { char c; - ssize_t n = recv(mSocket, &c, 1, 0); + ssize_t n = recvWithTimeout(mSocket, &c, 1); if (n < 0) { if (errno == EINTR) { continue; @@ -282,7 +310,8 @@ status_t HTTPStream::receive_header(int *http_status) { ssize_t HTTPStream::receive(void *data, size_t size) { size_t total = 0; while (total < size) { - ssize_t n = recv(mSocket, (char *)data + total, size - total, 0); + ssize_t n = recvWithTimeout( + mSocket, (char *)data + total, size - total); if (n < 0) { if (errno == EINTR) { @@ -296,7 +325,8 @@ ssize_t HTTPStream::receive(void *data, size_t size) { } else if (n == 0) { disconnect(); - LOGE("recv failed, server is gone"); + LOGE("recv failed, server is gone, total received: %d bytes", + total); return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total; }