Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions lib/conncache.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,19 @@ bool Curl_cpool_conn_seems_healthy(struct connectdata *conn,
{
struct Curl_easy *admin;
bool healthy = TRUE;
bool poll_input;

DEBUGASSERT(!data->conn);
if(!CONN_INUSE(conn) && cpool_conn_maxage(data, conn, pnow)) /* too old? */
return FALSE;
if(curlx_ptimediff_ms(pnow, &conn->lastchecked) < 1000)

/* An idle, non-multiplexed connection must not be reused when it has
* input pending (RFC 9112, section 9.2), so that is polled on every
* reuse. The once a second limit only applies to the other checks. */
poll_input = !CONN_INUSE(conn) && !conn->bits.connect_only &&
!Curl_conn_is_multiplex(conn, FIRSTSOCKET) &&
!conn->scheme->run->connection_is_dead;
if(!poll_input && curlx_ptimediff_ms(pnow, &conn->lastchecked) < 1000)
return TRUE;

admin = Curl_get_admin(data);
Expand All @@ -966,8 +974,7 @@ bool Curl_cpool_conn_seems_healthy(struct connectdata *conn,
Curl_attach_connection(admin, conn, FALSE);
healthy = Curl_conn_is_alive(admin, conn, &input_pending);
Curl_detach_connection(admin);
if(healthy && input_pending &&
!CONN_INUSE(conn) && !Curl_conn_is_multiplex(conn, FIRSTSOCKET)) {
if(healthy && input_pending && poll_input) {
/* Non-multiplexed connections without attached transfers should
* not have input pending. The input might be a TLS Notify Close,
* for all we know. */
Expand Down
1 change: 1 addition & 0 deletions tests/data/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,7 @@ TESTCASES = \
test1686 \
\
test1700 \
test1701 \
test1702 \
test1703 \
test1704 \
Expand Down
75 changes: 75 additions & 0 deletions tests/data/test1701
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
HTTP
HTTP GET
DELAY
</keywords>
</info>
# Server-side
<reply>
# the first response is exactly 60 bytes so that with writedelay the server
# sends it in three 20 byte writes and the unsolicited second response only
# starts arriving after the first transfer is complete and the connection
# has been returned to the pool
<data nocheck="yes">
HTTP/1.1 200 OK
Funny-head: yesyes
Content-Length: 6

first
HTTP/1.1 200 OK
Content-Length: 6

stray
</data>
<data2>
HTTP/1.1 200 OK
Content-Length: 7

second
</data2>
<servercmd>
writedelay: 150
</servercmd>
</reply>

# Client-side
<client>
<server>
http
</server>
<name>
HTTP/1.1 idle connection with unsolicited data is not reused
</name>
# --rate 1/s starts the second request 1000 ms after the first one started,
# which is about 700 ms after the first response completed and the
# connection went back to the pool, inside the one second window where the
# pool used to skip the alive check. The stray response has fully arrived
# about 750 ms in.
<command option="no-include">
http://%HOSTIP:%HTTPPORT/%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER0002 --rate 1/s
</command>
</client>

# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*

GET /%TESTNUMBER0002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*

</protocol>
<stdout>
first
second
</stdout>
</verify>
</testcase>
Loading