Skip to content
Snippets Groups Projects
Unverified Commit 82453a91 authored by Julian Andres Klode's avatar Julian Andres Klode Committed by Andrej Shadura
Browse files

http: Redesign reading of pending data

Instead of reading the data early, disable the timeout for the
select() call and read the data later. Also, change Read() to
call only once to drain the buffer in such instances.

We could optimize this to call read() multiple times if there
is also pending stuff on the socket, but that it slightly more
complex and should not provide any benefits.
parent e21fa296
No related branches found
No related tags found
7 merge requests!35Merge changes from apertis/v2020-updates into apertis/v2020,!34Merge changes from apertis/v2020-security into apertis/v2020,!30Merge buster security from Apertis/v2022dev1,!27Merge changes from apertis/v2019-updates into apertis/v2019,!26Sync apertis updates,!15v2020: Backport HTTP corruption fixes,!11T7140: (Hopefully) Fix HTTP data corruption
...@@ -778,13 +778,11 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req) ...@@ -778,13 +778,11 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req)
ToFile == false)) ToFile == false))
return ResultState::TRANSIENT_ERROR; return ResultState::TRANSIENT_ERROR;
// Handle server IO // Record if we have data pending to read in the server, so that we can
if (ServerFd->HasPending() && In.ReadSpace() == true) // skip the wait in select(). This can happen if data has already been
{ // read into a methodfd's buffer - the TCP queue might be empty at that
errno = 0; // point.
if (In.Read(ServerFd) == false) bool ServerPending = ServerFd->HasPending();
return Die(Req);
}
fd_set rfds,wfds; fd_set rfds,wfds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
...@@ -816,7 +814,7 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req) ...@@ -816,7 +814,7 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req)
// Select // Select
struct timeval tv; struct timeval tv;
tv.tv_sec = TimeOut; tv.tv_sec = ServerPending ? 0 : TimeOut;
tv.tv_usec = 0; tv.tv_usec = 0;
int Res = 0; int Res = 0;
if ((Res = select(MaxFd+1,&rfds,&wfds,0,&tv)) < 0) if ((Res = select(MaxFd+1,&rfds,&wfds,0,&tv)) < 0)
...@@ -827,14 +825,14 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req) ...@@ -827,14 +825,14 @@ ResultState HttpServerState::Go(bool ToFile, RequestState &Req)
return ResultState::TRANSIENT_ERROR; return ResultState::TRANSIENT_ERROR;
} }
if (Res == 0) if (Res == 0 && not ServerPending)
{ {
_error->Error(_("Connection timed out")); _error->Error(_("Connection timed out"));
return ResultState::TRANSIENT_ERROR; return ResultState::TRANSIENT_ERROR;
} }
// Handle server IO // Handle server IO
if (ServerFd->Fd() != -1 && FD_ISSET(ServerFd->Fd(), &rfds)) if (ServerPending || (ServerFd->Fd() != -1 && FD_ISSET(ServerFd->Fd(), &rfds)))
{ {
errno = 0; errno = 0;
if (In.Read(ServerFd) == false) if (In.Read(ServerFd) == false)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment