summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-03-30 13:14:19 -0700
committerAndreas Huber <andih@google.com>2010-03-30 13:21:12 -0700
commit08f00853886c0d26e087c23da3e24df5d36d3674 (patch)
tree506869c86ae5b9b41449f76eeb61a206fa39d442
parent65997f022fa3f557ba864ecc99a1aa33df54c2db (diff)
downloadframeworks_av-08f00853886c0d26e087c23da3e24df5d36d3674.zip
frameworks_av-08f00853886c0d26e087c23da3e24df5d36d3674.tar.gz
frameworks_av-08f00853886c0d26e087c23da3e24df5d36d3674.tar.bz2
Timeout on socket recv calls after 5secs, retry connection also if server unexpectedly closed the connection on its end and we know that there should've been more data available.
Change-Id: I749859dae28356080fe72ba035719754e7339c7f related-to-bug: 2492187
-rw-r--r--media/libstagefright/HTTPDataSource.cpp3
-rw-r--r--media/libstagefright/HTTPStream.cpp36
2 files changed, 35 insertions, 4 deletions
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp
index 00af8a3..61ffa8d 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 3aad72c..1e06f03 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 <utils/Log.h>
+
#include "include/HTTPStream.h"
#include <sys/socket.h>
@@ -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;
}