Library http.lua is already parsing the status line of HTTP responses, including the HTTP protocol version. This information should be captured so that other code does not need to re-implement the version extraction.
I am proposing version as a new member of the response table. The value is a string, as extracted from the status line. A consuming code could use it as follows:
The actual patch follows:
--- a/nselib/http.lua+++ b/nselib/http.lua@@ -13,6 +13,7 @@
-- These functions return a table of values, including:
-- * <code>status-line</code> - A string representing the status, such as "HTTP/1.1 200 OK". In case of an error, a description will be provided in this line.
-- * <code>status</code> - The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
+-- * <code>version</code> - HTTP protocol version string, as stated in the status line. Example: "1.1"
-- * <code>header</code> - An associative array representing the header. Keys are all lowercase, and standard headers, such as 'date', 'content-length', etc. will typically be present.
-- * <code>rawheader</code> - A numbered array of the headers, exactly as the server sent them. While header['content-type'] might be 'text/html', rawheader might be 'Content-type: text/html'.
-- * <code>cookies</code> - A numbered array of the cookies the server sent. Each cookie is a table with the following keys: <code>name</code>, <code>value</code>, <code>path</code>, <code>domain</code>, and <code>expires</code>.
@@ -54,6 +55,7 @@
-- The response to each function is typically a table with the following keys:
-- * <code>status-line</code>: The HTTP status line; for example, "HTTP/1.1 200 OK" (note: this is followed by a newline). In case of an error, a description will be provided in this line.
-- * <code>status</code>: The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
+-- * <code>version</code>: HTTP protocol version string, as stated in the status line. Example: "1.1"
-- * <code>header</code>: A table of header values, where the keys are lowercase and the values are exactly what the server sent
-- * <code>rawheader</code>: A list of header values as "name: value" strings, in the exact format and order that the server sent them
-- * <code>cookies</code>: A list of cookies that the server is sending. Each cookie is a table containing the keys <code>name</code>, <code>value</code>, and <code>path</code>. This table can be sent to the server in subsequent responses in the <code>options</code> table to any function (see below).
@@ -567,7 +569,6 @@
-- and the status code of the response.
local function recv_body(s, response, method, partial)
local connection_close, connection_keepalive
- local version_major, version_minor
@@ -594,9 +595,6 @@
- -- The HTTP version may also affect our decisions.- version_major, version_minor = string.match(response["status-line"], "^HTTP/(%d+)%.(%d+)")-
-- See RFC 2616, section 4.4 "Message Length".
-- 1. Any response message which "MUST NOT" include a message-body (such as
@@ -610,7 +608,7 @@
if string.upper(method) == "HEAD"
or (response.status >= 100 and response.status <= 199)
or response.status == 204 or response.status == 304 then
- if connection_close or (version_major == "1" and version_minor == "0" and not connection_keepalive) then+ if connection_close or (response.version == "1.0" and not connection_keepalive) then
return recv_all(s, partial)
return "", partial
@@ -657,7 +655,7 @@
return recv_all(s, partial)
--- Sets response["status-line"] and response.status.+-- Sets response["status-line"], response.status, and response.version.
local function parse_status_line(status_line, response)
response["status-line"] = status_line
local version, status, reason_phrase = string.match(status_line,
@@ -665,7 +663,8 @@
if not version then
return nil, string.format("Error parsing status-line %q.", status_line)
- -- We don't have a use for the version or the reason_phrase; ignore them.+ -- We don't have a use for the reason_phrase; ignore it.+ response.version = version
response.status = tonumber(status)
if not response.status then
return nil, string.format("Status code is not numeric: %s", status)
Please let me know if you have any questions or concerns.
The text was updated successfully, but these errors were encountered: