Skip to content

[BUG] Embedded HTTP server (ext/http) closes connections on transient nonblocking recv errors #4282

Description

@thc1006

What

HttpServer::onSocketReadable() in ext/include/opentelemetry/ext/http/server/http_server.h treats every non-positive recv() result as a closed connection:

int received = socket.recv(buffer, sizeof(buffer));
LOG_TRACE(..., received);
if (received <= 0)
{
  handleConnectionClosed(conn);
  return;
}

For a nonblocking socket, recv() returning -1 with EWOULDBLOCK/EAGAIN is a transient condition meaning "no data available yet", not a closed connection. Only recv() == 0 is an orderly shutdown by the peer. The current code closes the connection on any transient -1, which can drop otherwise-healthy connections whenever a readable event fires without data still buffered.

Related: error code read after logging

As in the send path, the error code should be captured immediately after recv(), before LOG_TRACE can clobber errno / the Winsock last error.

Suggested fix

Distinguish the three cases and capture the error before logging:

int received  = socket.recv(...);
int recvError = (received < 0) ? socket.error() : 0;
LOG_TRACE(..., received);
if (received > 0)
{
  // append + handle
}
else if (received == 0)
{
  handleConnectionClosed(conn);   // orderly shutdown
}
else if (recvError != ErrorWouldBlock && recvError != ErrorAgain)
{
  handleConnectionClosed(conn);   // a real error; transient would-block retries on the next event
}

Found while reviewing #4280. A PR will follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions