Commit 1c9549ea authored by ROOL's avatar ROOL 🤖
Browse files

Fix for race condition fetching headers

Detail:
  There was an assumption that if the recv() in http_read_more_header() returned an error, the subsequent recv() in http_reading_response() would also return the same error. However, if callbacks were allowed to run in between and data arrived from the server, the 2nd recv() can return data.
  In turn, this caused the statemachine to believe it was now reading the body, and forced AcornHTTP to invent a fake header for the client - when neither situation was true.
  Change the logic so that EWOULDBLOCK keeps the state machine in reading mode, other errors (or closed connection) stop as before.

  Unrelated - header.c corrects grammar, start.c uses boolean initialiser.
Admin:
  Submission for TCP/IP bounty.

Version 1.03. Tagged as 'HTTP-1_03'
parent 698b6caf
/* (1.02)
/* (1.03)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.02
#define Module_MajorVersion_CMHG 1.03
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 31 Mar 2019
#define Module_Date_CMHG 06 Apr 2019
#define Module_MajorVersion "1.02"
#define Module_Version 102
#define Module_MajorVersion "1.03"
#define Module_Version 103
#define Module_MinorVersion ""
#define Module_Date "31 Mar 2019"
#define Module_Date "06 Apr 2019"
#define Module_ApplicationDate "31-Mar-19"
#define Module_ApplicationDate "06-Apr-19"
#define Module_ComponentName "HTTP"
#define Module_ComponentPath "apache/RiscOS/Sources/Networking/Fetchers/HTTP"
#define Module_FullVersion "1.02"
#define Module_HelpVersion "1.02 (31 Mar 2019)"
#define Module_LibraryVersionInfo "1:2"
#define Module_FullVersion "1.03"
#define Module_HelpVersion "1.03 (06 Apr 2019)"
#define Module_LibraryVersionInfo "1:3"
......@@ -473,7 +473,7 @@ int parse_http_header(char *const buffer, int buflen, Session *ses, _kernel_swi_
ses->read_status = 200;
ses->server_code = 200;
http_add_header(&ses->headers, "HTTP/1.0", "200 " Module_Title " guessing OK");
http_add_header(&ses->headers, "Warning", "99 Server didn't sent any headers");
http_add_header(&ses->headers, "Warning", "99 Server didn't send any headers");
http_add_header(&ses->headers, "Content-Type", "text/html");
http_add_header(&ses->headers, "Warning", "14 Content-type header added");
http_process_all_response_headers(ses, r);
......
......@@ -127,11 +127,13 @@ static int http_read_more_header(_kernel_swi_regs *r, Session *ses)
space = ses->bufsize;
dataread = ses->op->s_recv(ses->sd, ses->buffer, space, MSG_PEEK);
/* Right. We only need to cope with this situation as the later code
* for the body reader will pick up the same situation when it attempts
* the socketread call in a moment.
*/
if (dataread <= 0) return 1;
if (dataread <= 0) {
if (errno == EWOULDBLOCK) {
http_set_return(r, status_READING_REPLY, r->r[4], -2, ses);
return 0; /* Nothing yet, try again */
}
return 1; /* Connection closed, or some other error */
}
#ifdef TRACE
protocol_debug("receiving_header: peeking at data (had %d, got %d more):\n", ses->bufptr, dataread);
......
......@@ -750,7 +750,7 @@ static Session *http_new_session(_kernel_swi_regs *r)
ses->bufptr = 0;
ses->read_status = 0;
ses->bufsize = 0;
ses->donehead = 0;
ses->donehead = FALSE;
ses->compression = compression_NONE;
ses->chunking = 0;
ses->chunk_bytes = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment