From 46df5c92a86a3a72b5f415d05260acc315fe56c0 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 22 May 2012 12:23:34 +0100 Subject: [PATCH] [http] Defer processing response code until after receiving all headers Some headers can modify the meaning of the response code. For example, a WWW-Authenticate header can change the interpretation of a 401 Unauthorized response from "Access denied" to "Please authenticate". Signed-off-by: Michael Brown --- src/net/tcp/httpcore.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c index 95e132f9..27d32bfd 100644 --- a/src/net/tcp/httpcore.c +++ b/src/net/tcp/httpcore.c @@ -143,6 +143,8 @@ struct http_request { /** RX state */ enum http_rx_state rx_state; + /** Response code */ + unsigned int code; /** Received length */ size_t rx_len; /** Length remaining (or 0 if unknown) */ @@ -311,8 +313,6 @@ static int http_response_to_rc ( unsigned int response ) { */ static int http_rx_response ( struct http_request *http, char *response ) { char *spc; - unsigned int code; - int rc; DBGC ( http, "HTTP %p response \"%s\"\n", http, response ); @@ -320,13 +320,11 @@ static int http_rx_response ( struct http_request *http, char *response ) { if ( strncmp ( response, "HTTP/", 5 ) != 0 ) return -EINVAL_RESPONSE; - /* Locate and check response code */ + /* Locate and store response code */ spc = strchr ( response, ' ' ); if ( ! spc ) return -EINVAL_RESPONSE; - code = strtoul ( spc, NULL, 10 ); - if ( ( rc = http_response_to_rc ( code ) ) != 0 ) - return rc; + http->code = strtoul ( spc, NULL, 10 ); /* Move to received headers */ http->rx_state = HTTP_RX_HEADER; @@ -488,6 +486,12 @@ static int http_rx_header ( struct http_request *http, char *header ) { /* An empty header line marks the end of this phase */ if ( ! header[0] ) { empty_line_buffer ( &http->linebuf ); + + /* Handle response code */ + if ( ( rc = http_response_to_rc ( http->code ) ) != 0 ) + return rc; + + /* Move to next state */ if ( ( http->rx_state == HTTP_RX_HEADER ) && ( ! ( http->flags & HTTP_HEAD_ONLY ) ) ) { DBGC ( http, "HTTP %p start of data\n", http );