diff --git a/CHANGELOG b/CHANGELOG
index c6a54f4f2..cf6c51982 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
# Nmap Changelog ($Id$); -*-text-*-
+o [NSE][GH#934] The HTTP response object has a new member, version, which
+ contains the HTTP protocol version string returned by the server, e.g. "1.1".
+ [nnposter]
+
o [NSE] openwebnet-discovery retrieves device identifying information and
number of connected devices running on openwebnet protocol. [Rewanth Cool]
diff --git a/nselib/http.lua b/nselib/http.lua
index c2361543d..8b275b82a 100644
--- a/nselib/http.lua
+++ b/nselib/http.lua
@@ -13,6 +13,7 @@
-- These functions return a table of values, including:
-- * status-line - 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.
-- * status - The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
+-- * version - HTTP protocol version string, as stated in the status line. Example: "1.1"
-- * header - An associative array representing the header. Keys are all lowercase, and standard headers, such as 'date', 'content-length', etc. will typically be present.
-- * rawheader - A numbered array of the headers, exactly as the server sent them. While header['content-type'] might be 'text/html', rawheader[3] might be 'Content-type: text/html'.
-- * cookies - A numbered array of the cookies the server sent. Each cookie is a table with the following keys: name, value, path, domain, and expires.
@@ -54,6 +55,7 @@
-- The response to each function is typically a table with the following keys:
-- * status-line: 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.
-- * status: The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
+-- * version: HTTP protocol version string, as stated in the status line. Example: "1.1"
-- * header: A table of header values, where the keys are lowercase and the values are exactly what the server sent
-- * rawheader: A list of header values as "name: value" strings, in the exact format and order that the server sent them
-- * cookies: A list of cookies that the server is sending. Each cookie is a table containing the keys name, value, and path. This table can be sent to the server in subsequent responses in the options table to any function (see below).
@@ -567,7 +569,6 @@ end
-- 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
local transfer_encoding
local content_length
local err
@@ -594,9 +595,6 @@ local function recv_body(s, response, method, partial)
end
end
- -- 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 @@ local function recv_body(s, response, method, partial)
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)
else
return "", partial
@@ -657,7 +655,7 @@ local function recv_body(s, response, method, partial)
return recv_all(s, partial)
end
--- 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 @@ local function parse_status_line(status_line, response)
if not version then
return nil, string.format("Error parsing status-line %q.", status_line)
end
- -- 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)