Skip to content

Commit

Permalink
Add option to get cookie without escaping
Browse files Browse the repository at this point in the history
Method req:cookie() implicitly unescapes cookie values. Commit adds
ability to get cookie without unescaping:

req:cookie('name', {
    raw = true
})

This change was added as a part of http v2 support in commit 'Added
ability to set and get cookie without escaping'
(42e3002) and later reverted in scope
of ticket with discard v2.

Follows up #126
Part of #134
  • Loading branch information
ligurio committed Oct 28, 2021
1 parent fe32ad5 commit 0e425b2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Add workflow that publish rockspec.
- Add editorconfig to configure indentation.
- Add luacheck integration.
- Add option to get cookie without escaping.

### Fixed

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ end
* `req:query_param(name)` - returns a single GET request parameter value.
If `name` is `nil`, returns a Lua table with all arguments.
* `req:param(name)` - any request parameter, either GET or POST.
* `req:cookie(name)` - to get a cookie in the request.
* `req:cookie(name, {raw = true})` | to get a cookie in the request. if `raw`
option was set then cookie will not be unescaped, otherwise cookie's value
will be unescaped.
* `req:stash(name[, value])` - get or set a variable "stashed"
when dispatching a route.
* `req:url_for(name, args, query)` - returns the route's exact URL.
Expand Down
8 changes: 6 additions & 2 deletions http/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,18 @@ local function setcookie(resp, cookie)
return resp
end

local function cookie(tx, cookie)
local function cookie(tx, cookie, options)
options = options or {}
if tx.headers.cookie == nil then
return nil
end
for k, v in string.gmatch(
tx.headers.cookie, "([^=,; \t]+)=([^,; \t]+)") do
if k == cookie then
return uri_unescape(v)
if not options.raw then
v = uri_unescape(v)
end
return v
end
end
return nil
Expand Down
52 changes: 28 additions & 24 deletions test/integration/http_server_requests_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -203,49 +203,53 @@ g.test_chunked_encoding = function()
t.assert_equals(r.body, 'chunkedencodingt\r\nest', 'chunked body')
end

-- Get cookie.
-- Get raw cookie value (Günter -> Günter).
g.test_get_cookie = function()
local cookie = 'Günter'
local httpd = g.httpd
httpd:route({
path = '/receive_cookie'
}, function(req)
local foo = req:cookie('foo')
local baz = req:cookie('baz')
local name = req:cookie('name', {
raw = true
})
return req:render({
text = ('foo=%s; baz=%s'):format(foo, baz)
text = ('name=%s'):format(name)
})
end)

local r = http_client.get(helpers.base_uri .. '/receive_cookie', {
headers = {
cookie = 'foo=bar; baz=feez',
cookie = 'name=' .. cookie,
}
})
t.assert_equals(r.status, 200, 'status')
t.assert_equals(r.body, 'foo=bar; baz=feez', 'body')

t.assert_equals(r.status, 200, 'response status')
t.assert_equals(r.body, 'name=' .. cookie, 'body with raw cookie')
end

-- Cookie.
g.test_set_cookie = function()
-- Get escaped cookie (G%C3%BCnter -> Günter).
g.test_get_escaped_cookie = function()
local str_escaped = 'G%C3%BCnter'
local str_non_escaped = 'Günter'
local httpd = g.httpd
httpd:route({
path = '/cookie'
path = '/receive_cookie'
}, function(req)
local resp = req:render({text = ''})
resp:setcookie({
name = 'test',
value = 'tost',
expires = '+1y',
path = '/abc'
})
resp:setcookie({
name = 'xxx',
value = 'yyy'
local name = req:cookie('name')
return req:render({
text = ('name=%s'):format(name)
})
return resp
end)
local r = http_client.get(helpers.base_uri .. '/cookie')
t.assert_equals(r.status, 200, 'status')
t.assert(r.headers['set-cookie'] ~= nil, 'header')

local r = http_client.get(helpers.base_uri .. '/receive_cookie', {
headers = {
cookie = 'name=' .. str_escaped,
}
})

t.assert_equals(r.status, 200, 'response status')
t.assert_equals(r.body, 'name=' .. str_non_escaped, 'body with escaped cookie')
end

-- Request object methods.
Expand Down

0 comments on commit 0e425b2

Please sign in to comment.