From: Daniel Gruno Date: Thu, 20 Feb 2014 11:54:27 +0000 (+0000) Subject: mod_lua: Backport setcookie changes. PR 56128 X-Git-Tag: 2.4.8~93 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f40cc3cab226c8d7ec3bd1d16cf9d5f1ae8daa28;p=apache mod_lua: Backport setcookie changes. PR 56128 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1570162 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 383040f5ba..bc1bdc2103 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,10 @@ Changes with Apache 2.4.8 *) mod_remoteip: Use the correct IP addresses to populate the proxy_ips field. PR 55972. [Mike Rumph] + *) 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 9d2628eb52..609b01673c 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -1963,27 +1963,101 @@ 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 : ""); - apr_table_add(r->headers_out, "Set-Cookie", out); + + /* Create path segment */ + if (path != NULL && strlen(path) > 0) { + strpath = apr_psprintf(r->pool, "Path=\"%s\";", path); + } + + /* Create domain segment */ + if (domain != NULL && 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->err_headers_out, "Set-Cookie", out); return 0; }