Hi all,
This patch fixes HttpStateData::readReply to retry read from server in
the case of EINPROGRESS, EAGAIN or similar errors
This bug mostly affects SSL bumped connections. The
HttpStateData::readReply will not retry read from server in the case of
an EINPROGRESS or similar comm errors and the connection will hang,
until the timeout handler called.
The Comm::ReadNow method, used inside HttpStateData::readReply, call
ignoreErrno function to test if the comm error should be ignored and in
this case return Comm::INPROGRESS value.
In this case we need to set flags.do_next_read to true to force
HttpStateData::maybeReadVirginBody() method retry read.
This is a Measurement Factory project
Fix HttpStateData::readReply to retry read from server in the case of EINPROGRESS, EAGAIN or similar errors
This bug mostly affects SSL bumped connections.
The HttpStateData::readReply will not retry read from server in the case of an
EINPROGRESS or similar comm errors and the connection will hang, until the
timeout handler called.
The Comm::ReadNow method calls ignoreErrno function to test if the comm error
should be ignored and in this case return Comm::INPROGRESS value.
In this case we need to set flags.do_next_read to true to force
HttpStateData::maybeReadVirginBody() method retry read.
This is a Measurement Factory project
=== modified file 'src/http.cc'
--- src/http.cc 2015-03-28 13:20:21 +0000
+++ src/http.cc 2015-04-06 14:26:11 +0000
@@ -1175,40 +1175,41 @@
assert(entry->mem_obj);
/* read ahead limit */
/* Perhaps these two calls should both live in MemObject */
AsyncCall::Pointer nilCall;
if (!entry->mem_obj->readAheadPolicyCanRead()) {
entry->mem_obj->delayRead(DeferredRead(readDelayed, this, CommRead(io.conn, NULL, 0, nilCall)));
return;
}
/* delay id limit */
entry->mem_obj->mostBytesAllowed().delayRead(DeferredRead(readDelayed, this, CommRead(io.conn, NULL, 0, nilCall)));
return;
}
#endif
switch (Comm::ReadNow(rd, inBuf)) {
case Comm::INPROGRESS:
if (inBuf.isEmpty())
debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
+ flags.do_next_read = true;
maybeReadVirginBody();
return;
case Comm::OK:
{
payloadSeen += rd.size;
#if USE_DELAY_POOLS
DelayId delayId = entry->mem_obj->mostBytesAllowed();
delayId.bytesIn(rd.size);
#endif
kb_incr(&(statCounter.server.all.kbytes_in), rd.size);
kb_incr(&(statCounter.server.http.kbytes_in), rd.size);
++ IOStats.Http.reads;
int bin = 0;
for (int clen = rd.size - 1; clen; ++bin)
clen >>= 1;
++ IOStats.Http.read_hist[bin];
@@ -1217,50 +1218,45 @@
const timeval &sent = request->hier.peer_http_request_sent;
if (sent.tv_sec)
tvSub(request->hier.peer_response_time, sent, current_time);
else
request->hier.peer_response_time.tv_sec = -1;
}
/* Continue to process previously read data */
break;
case Comm::ENDFILE: // close detected by 0-byte read
eof = 1;
flags.do_next_read = false;
/* Continue to process previously read data */
break;
// case Comm::COMM_ERROR:
default: // no other flags should ever occur
debugs(11, 2, io.conn << ": read failure: " << xstrerr(rd.xerrno));
-
- if (ignoreErrno(rd.xerrno)) {
- flags.do_next_read = true;
- } else {
- ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scBadGateway, fwd->request);
- err->xerrno = rd.xerrno;
- fwd->fail(err);
- flags.do_next_read = false;
- io.conn->close();
- }
+ ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scBadGateway, fwd->request);
+ err->xerrno = rd.xerrno;
+ fwd->fail(err);
+ flags.do_next_read = false;
+ io.conn->close();
return;
}
/* Process next response from buffer */
processReply();
}
/// processes the already read and buffered response data, possibly after
/// waiting for asynchronous 1xx control message processing
void
HttpStateData::processReply()
{
if (flags.handling1xx) { // we came back after handling a 1xx response
debugs(11, 5, HERE << "done with 1xx handling");
flags.handling1xx = false;
Must(!flags.headers_parsed);
}
_______________________________________________
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev