Skip to content

Commit

Permalink
fix(alf_serializer) always ensure mimeType is a string
Browse files Browse the repository at this point in the history
If a request or response have multiple Content-Type headers, this make
sure the latest one is returned, so mimeType is guaranteed to be a
string, and not an array.

Fix for #584
  • Loading branch information
thibaultcha committed Oct 15, 2015
1 parent 8e2ac68 commit 731e203
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 2 deletions.
24 changes: 22 additions & 2 deletions kong/plugins/log-serializers/alf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ local function dic_to_array(hash, fn)
end
end

--- Get a header from nginx's headers
-- Make sure that is multiple headers of a same name are present,
-- we only want the last one. Also include a default value if
-- no header is present.
-- @param `headers` ngx's request or response headers table.
-- @param `name` Name of the desired header to retrieve.
-- @param `default` String returned in case no header is found.
-- @return `header` The header value (a string) or the default, or nil.
local function get_header(headers, name, default)
local val = headers[name]
if val ~= nil then
if type(val) == "table" then
val = val[#val]
end
return val
end

return default
end

local _M = {}

-- Serialize `ngx` into one ALF entry.
Expand Down Expand Up @@ -112,8 +132,8 @@ function _M.serialize_entry(ngx)
local alf_res_headers_size = string.len(res_headers_str)

-- mimeType, defaulting to "application/octet-stream"
local alf_req_mimeType = req_headers["Content-Type"] and req_headers["Content-Type"] or "application/octet-stream"
local alf_res_mimeType = res_headers["Content-Type"] and res_headers["Content-Type"] or "application/octet-stream"
local alf_req_mimeType = get_header(req_headers, "Content-Type", "application/octet-stream")
local alf_res_mimeType = get_header(res_headers, "Content-Type", "application/octet-stream")

return {
startedDateTime = os.date("!%Y-%m-%dT%TZ", alf_started_at),
Expand Down
5 changes: 5 additions & 0 deletions spec/plugins/mashape-analytics/alf_serializer_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ describe("ALF serializer", function()
assert.are.sameEntry(fixtures.MULTIPLE_UPSTREAMS.ENTRY, entry)
assert.equal(60468, entry.timings.wait)
end)

it("should return the last header if two are present for mimeType", function()
local entry = ALFSerializer.serialize_entry(fixtures.MULTIPLE_HEADERS.NGX_STUB)
assert.are.sameEntry(fixtures.MULTIPLE_HEADERS.ENTRY, entry)
end)
end)

describe("#new_alf()", function ()
Expand Down
94 changes: 94 additions & 0 deletions spec/plugins/mashape-analytics/fixtures/requests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,99 @@ return {
wait = 60468
}
}
},
["MULTIPLE_HEADERS"] = {
["NGX_STUB"] = {
req = {
start_time = function() return 1432844571.623 end,
get_method = function() return "GET" end,
http_version = function() return 1.1 end,
get_headers = function() return {["Accept"] = "/*/", ["Host"] = "mockbin.com", ["Content-Type"] = {"application/json", "application/www-form-urlencoded"}} end,
get_uri_args = function() return {["hello"] = "world", ["foo"] = "bar"} end
},
resp = {
get_headers = function() return {["Connection"] = "close", ["Content-Type"] = {"application/json", "application/www-form-urlencoded"}, ["Content-Length"] = "934"} end
},
status = 200,
var = {
scheme = "http",
host = "mockbin.com",
request_uri = "/request",
request_length = 123,
body_bytes_sent = 934,
remote_addr = "127.0.0.1",
upstream_response_time = "0.391"
},
ctx = {
proxy_started_at = 1432844571719,
proxy_ended_at = 143284457211,
analytics = {
req_body = "hello=world&hello=earth",
res_body = "{\"message\":\"response body\"}",
req_post_args = {["hello"] = {"world", "earth"}},
response_received = 143284457211
}
}
},
["ENTRY"] = {
cache = {},
request = {
bodySize = 23,
cookies = {EMPTY_ARRAY_PLACEHOLDER},
headers = {
{name = "Accept", value = "/*/"},
{name = "Host", value = "mockbin.com"},
{name = "Content-Type", value = "application/json"},
{name = "Content-Type", value = "application/www-form-urlencoded"}
},
headersSize = 95,
httpVersion = "HTTP/1.1",
method = "GET",
postData = {
mimeType = "application/www-form-urlencoded",
params = {
{name = "hello", value = "world"},
{name = "hello", value = "earth"}
},
text = "hello=world&hello=earth"
},
queryString = {
{name = "foo", value = "bar"},
{name = "hello", value = "world"}
},
url = "http://mockbin.com/request"
},
response = {
bodySize = 934,
content = {
mimeType = "application/www-form-urlencoded",
size = 934,
text = "{\"message\":\"response body\"}"
},
cookies = {EMPTY_ARRAY_PLACEHOLDER},
headers = {
{name = "Content-Length", value = "934"},
{name = "Content-Type", value = "application/json"},
{name = "Content-Type", value = "application/www-form-urlencoded"},
{name = "Connection", value = "close"}
},
headersSize = 103,
httpVersion = "",
redirectURL = "",
status = 200,
statusText = ""
},
startedDateTime = "2015-05-28T20:22:51Z",
time = 487,
timings = {
blocked = -1,
connect = -1,
dns = -1,
receive = 0,
send = 96,
ssl = -1,
wait = 391
}
}
}
}

0 comments on commit 731e203

Please # to comment.