am 0bca99e9: am 8899186b: Merge "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." into froyo
Merge commit '0bca99e987420a63ebd509093cbde015399d8522' into kraken * commit '0bca99e987420a63ebd509093cbde015399d8522': 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.
This commit is contained in:
@@ -385,7 +385,8 @@ rinse_repeat:
|
|||||||
|
|
||||||
ssize_t num_bytes_received = mHttp->receive(mBuffer, contentLength);
|
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) {
|
if (mNumRetriesLeft-- > 0) {
|
||||||
disconnect();
|
disconnect();
|
||||||
if (connect() == OK) {
|
if (connect() == OK) {
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "HTTPStream"
|
||||||
|
#include <utils/Log.h>
|
||||||
|
|
||||||
#include "include/HTTPStream.h"
|
#include "include/HTTPStream.h"
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -146,6 +150,30 @@ status_t HTTPStream::send(const char *data) {
|
|||||||
return send(data, strlen(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,
|
// A certain application spawns a local webserver that sends invalid responses,
|
||||||
// specifically it terminates header line with only a newline instead of the
|
// specifically it terminates header line with only a newline instead of the
|
||||||
// CRLF (carriage-return followed by newline) required by the HTTP specs.
|
// 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 (;;) {
|
for (;;) {
|
||||||
char c;
|
char c;
|
||||||
ssize_t n = recv(mSocket, &c, 1, 0);
|
ssize_t n = recvWithTimeout(mSocket, &c, 1);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
continue;
|
continue;
|
||||||
@@ -282,7 +310,8 @@ status_t HTTPStream::receive_header(int *http_status) {
|
|||||||
ssize_t HTTPStream::receive(void *data, size_t size) {
|
ssize_t HTTPStream::receive(void *data, size_t size) {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
while (total < size) {
|
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 (n < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
@@ -296,7 +325,8 @@ ssize_t HTTPStream::receive(void *data, size_t size) {
|
|||||||
} else if (n == 0) {
|
} else if (n == 0) {
|
||||||
disconnect();
|
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;
|
return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user