Browse Source

handle servers closing encoded connections correctly

Servers who advertise that they close the connection get the 'Closes'
encoding flag, but this conflicts with servers who response with a
transfer-encoding (e.g. encoding) as it is saved in the same flag.

We have a better flag for the keep-alive (or not) of the connection
anyway, so we check this instead of the encoding.

This is in practice not much of a problem as real servers we talk to are
HTTP1.1 servers (with keep-alive) and there isn't much point in doing
chunked encoding if you are going to close anyway, but our simple
testserver stumbles over this if pressed and its a bit cleaner, too.

Git-Dch: Ignore
tags/debian/1.1.exp9
David Kalnischkies 6 years ago
parent
commit
117038bac9
2 changed files with 24 additions and 10 deletions
  1. +3
    -3
      methods/http.cc
  2. +21
    -7
      test/interactive-helper/aptwebserver.cc

+ 3
- 3
methods/http.cc View File

@@ -442,7 +442,7 @@ bool HttpServerState::RunData(FileFd * const File)
{
/* Closes encoding is used when the server did not specify a size, the
loss of the connection means we are done */
if (Encoding == Closes)
if (Persistent == false)
In.Limit(-1);
else if (JunkSize != 0)
In.Limit(JunkSize);
@@ -524,7 +524,7 @@ bool HttpServerState::Die(FileFd &File)

// See if this is because the server finished the data stream
if (In.IsLimit() == false && State != HttpServerState::Header &&
Encoding != HttpServerState::Closes)
Persistent == true)
{
Close();
if (LErrno == 0)
@@ -571,7 +571,7 @@ bool HttpServerState::Flush(FileFd * const File)
return true;
}

if (In.IsLimit() == true || Encoding == ServerState::Closes)
if (In.IsLimit() == true || Persistent == false)
return true;
}
return false;


+ 21
- 7
test/interactive-helper/aptwebserver.cc View File

@@ -598,17 +598,24 @@ static void * handleClient(void * voidclient) /*{{{*/
{
int client = *((int*)(voidclient));
std::clog << "ACCEPT client " << client << std::endl;
std::vector<std::string> messages;
bool closeConnection = false;
std::list<std::string> headers;
while (closeConnection == false && ReadMessages(client, messages))
while (closeConnection == false)
{
// if we announced a closing, do the close
if (std::find(headers.begin(), headers.end(), std::string("Connection: close")) != headers.end())
std::vector<std::string> messages;
if (ReadMessages(client, messages) == false)
break;
headers.clear();

std::list<std::string> headers;
for (std::vector<std::string>::const_iterator m = messages.begin();
m != messages.end() && closeConnection == false; ++m) {
// if we announced a closing in previous response, do the close now
if (std::find(headers.begin(), headers.end(), std::string("Connection: close")) != headers.end())
{
closeConnection = true;
break;
}
headers.clear();

std::clog << ">>> REQUEST from " << client << " >>>" << std::endl << *m
<< std::endl << "<<<<<<<<<<<<<<<<" << std::endl;
std::string filename;
@@ -760,9 +767,16 @@ static void * handleClient(void * voidclient) /*{{{*/
else
sendError(client, 404, *m, sendContent, "", headers);
}

// if we announced a closing in the last response, do the close now
if (std::find(headers.begin(), headers.end(), std::string("Connection: close")) != headers.end())
closeConnection = true;

if (_error->PendingError() == true)
break;
_error->DumpErrors(std::cerr);
messages.clear();
}
_error->DumpErrors(std::cerr);
close(client);
std::clog << "CLOSE client " << client << std::endl;
return NULL;


Loading…
Cancel
Save