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:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user