From 5ed3e104738f54ace4f2c4921726c349d46777d9 Mon Sep 17 00:00:00 2001 From: Daniel Gruno Date: Tue, 11 Feb 2014 22:45:32 +0000 Subject: [PATCH] mod_lua: Upgrade r:setcookie to accept a table of arguments, and add domain, path and HttpOnly to the list of options available for setting. PR 56128 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1567430 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 6 ++- docs/manual/mod/mod_lua.xml | 18 ++++++- modules/lua/lua_request.c | 96 ++++++++++++++++++++++++++++++++----- 3 files changed, 106 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index f432db8081..d7537b5e3a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 - + + *) mod_lua: Update r:setcookie() to accept a table of options and add domain, + path and httponly to the list of options available to set. + PR 56128 [Edward Lu , Daniel Gruno] + *) mod_lua: Fix r:setcookie() to add, rather than replace, the Set-Cookie header. PR56105 [Kevin J Walters , Edward Lu ] diff --git a/docs/manual/mod/mod_lua.xml b/docs/manual/mod/mod_lua.xml index 1b5d1ba30d..4d26b8c5db 100644 --- a/docs/manual/mod/mod_lua.xml +++ b/docs/manual/mod/mod_lua.xml @@ -972,8 +972,22 @@ r:getcookie(key) -- Gets a HTTP cookie -r:setcookie(key, value, secure, expires) -- Sets a HTTP cookie, for instance: -r:setcookie("foo", "bar and stuff", false, os.time() + 86400) +r:setcookie{ + key = [key], + value = [value], + expires = [expiry], + secure = [boolean], + httponly = [boolean], + path = [path], + domain = [domain] +} -- Sets a HTTP cookie, for instance: + +r:setcookie{ + key = "cookie1", + value = "HDHfa9eyffh396rt", + expires = os.time() + 86400, + secure = true +} diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c index 0c19cef351..43de56241d 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -1967,26 +1967,100 @@ static int lua_get_cookie(lua_State *L) static int lua_set_cookie(lua_State *L) { - const char *key, *value, *out, *strexpires; - int secure, expires; + const char *key, *value, *out, *path = "", *domain = ""; + const char *strexpires = "", *strdomain = "", *strpath = ""; + int secure = 0, expires = 0, httponly = 0; char cdate[APR_RFC822_DATE_LEN+1]; apr_status_t rv; request_rec *r = ap_lua_check_request_rec(L, 1); - key = luaL_checkstring(L, 2); - value = luaL_checkstring(L, 3); - secure = 0; - if (lua_isboolean(L, 4)) { - secure = lua_toboolean(L, 4); + + /* New >= 2.4.8 method: */ + if (lua_istable(L, 2)) { + + /* key */ + lua_pushstring(L, "key"); + lua_gettable(L, -2); + key = luaL_checkstring(L, -1); + lua_pop(L, 1); + + /* value */ + lua_pushstring(L, "value"); + lua_gettable(L, -2); + value = luaL_checkstring(L, -1); + lua_pop(L, 1); + + /* expiry */ + lua_pushstring(L, "expires"); + lua_gettable(L, -2); + expires = luaL_optint(L, -1, 0); + lua_pop(L, 1); + + /* secure */ + lua_pushstring(L, "secure"); + lua_gettable(L, -2); + if (lua_isboolean(L, -1)) { + secure = lua_toboolean(L, -1); + } + lua_pop(L, 1); + + /* httponly */ + lua_pushstring(L, "httponly"); + lua_gettable(L, -2); + if (lua_isboolean(L, -1)) { + httponly = lua_toboolean(L, -1); + } + lua_pop(L, 1); + + /* path */ + lua_pushstring(L, "path"); + lua_gettable(L, -2); + path = luaL_optstring(L, -1, "/"); + lua_pop(L, 1); + + /* domain */ + lua_pushstring(L, "domain"); + lua_gettable(L, -2); + domain = luaL_optstring(L, -1, ""); + lua_pop(L, 1); } - expires = luaL_optinteger(L, 5, 0); - strexpires = ""; + /* Old <= 2.4.7 method: */ + else { + key = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + secure = 0; + if (lua_isboolean(L, 4)) { + secure = lua_toboolean(L, 4); + } + expires = luaL_optinteger(L, 5, 0); + } + + /* Calculate expiry if set */ if (expires > 0) { rv = apr_rfc822_date(cdate, apr_time_from_sec(expires)); if (rv == APR_SUCCESS) { - strexpires = apr_psprintf(r->pool, "Expires=%s", cdate); + strexpires = apr_psprintf(r->pool, "Expires=\"%s\";", cdate); } } - out = apr_psprintf(r->pool, "%s=%s; %s %s", key, value, secure ? "Secure;" : "", expires ? strexpires : ""); + + /* Create path segment */ + if (path && strlen(path) > 0) { + strpath = apr_psprintf(r->pool, "Path=\"%s\";", path); + } + + /* Create domain segment */ + if (domain && strlen(domain) > 0) { + /* Domain does NOT like quotes in most browsers, so let's avoid that */ + strdomain = apr_psprintf(r->pool, "Domain=%s;", domain); + } + + /* Create the header */ + out = apr_psprintf(r->pool, "%s=%s; %s %s %s %s %s", key, value, + secure ? "Secure;" : "", + expires ? strexpires : "", + httponly ? "HttpOnly;" : "", + strlen(strdomain) ? strdomain : "", + strlen(strpath) ? strpath : ""); + apr_table_add(r->headers_out, "Set-Cookie", out); return 0; }