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
This commit is contained in:
Andreas Huber
2010-03-30 13:14:19 -07:00
parent fef8cebcdc
commit b75d137faf
2 changed files with 35 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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;
}