Thread: [Cppcms-users] The role of cookie path
Brought to you by:
artyom-beilis
From: CN <cn...@fa...> - 2016-07-08 10:24:50
|
Server configuration follows: "session":{ "location":"client", "cookies":{ "prefix":"prefix" //"path":"/" }, } Browser shows that the path of every cookie is set to "/" by session().set("name","value"). So far so good. This is server debugging code: for(auto const &c : request().cookies()) BOOSTER_DEBUG("COOKIES") << c.first << ":" << c.second.path(); BOOSTER_DEBUG("mc") << session().is_set("my_cookie"); Client requests for URL "http://localhost/normal" and above server code writes the following log as expected except for one thing - cookie.path() returning empty string: 2016-07-08 17:35:31; COOKIES, debug: prefix: 2016-07-08 17:35:31; COOKIES, debug: prefix_c1: 2016-07-08 17:35:31; COOKIES, debug: prefix_my_cookie: 2016-07-08 17:35:31; mc, debug: 1 Question: Is it by design that cookie.path() returns empty string here? Now, after client gets the page from "http://localhost/normal", it calls this javascript: window.location.replace("http://localhost/special"); the same above server code now writes these log: 2016-07-08 17:35:31; COOKIES, debug: prefix: 2016-07-08 17:35:31; COOKIES, debug: prefix_c1: 2016-07-08 17:35:31; COOKIES, debug: prefix_my_cookie: 2016-07-08 17:35:31; mc, debug: 0 indicating that cookie "my_cookie" is not set. I am puzzled by the behavior of cookies - request().cookies() indicates that cookie "my_cookie" exists but session().is_set("my_cookie") says it doesn't. How can it be so? Is the empty cookie.path() making the trouble? Best Regards, CN -- http://www.fastmail.com - A fast, anti-spam email service. |
From: Artyom B. <art...@gm...> - 2016-07-09 12:02:43
|
Browser does not send path information about cookies it sends to server in HTTP headers, actually it only sends cookie name and value - not domain, expiration, path or other parameters. Only server does. That is why you don't get this information in request().cookies() - server just does not have one. Artyom On Fri, Jul 8, 2016 at 1:24 PM, CN <cn...@fa...> wrote: > Server configuration follows: > > "session":{ > "location":"client", > "cookies":{ > "prefix":"prefix" > //"path":"/" > }, > } > > Browser shows that the path of every cookie is set to "/" by > session().set("name","value"). So far so good. > > This is server debugging code: > > for(auto const &c : request().cookies()) > BOOSTER_DEBUG("COOKIES") << c.first << ":" << c.second.path(); > BOOSTER_DEBUG("mc") << session().is_set("my_cookie"); > > Client requests for URL "http://localhost/normal" and above server code > writes the following log as expected except for one thing - > cookie.path() returning empty string: > > 2016-07-08 17:35:31; COOKIES, debug: prefix: > 2016-07-08 17:35:31; COOKIES, debug: prefix_c1: > 2016-07-08 17:35:31; COOKIES, debug: prefix_my_cookie: > 2016-07-08 17:35:31; mc, debug: 1 > > Question: Is it by design that cookie.path() returns empty string here? > > Now, after client gets the page from "http://localhost/normal", it calls > this javascript: > > window.location.replace("http://localhost/special"); > > the same above server code now writes these log: > > 2016-07-08 17:35:31; COOKIES, debug: prefix: > 2016-07-08 17:35:31; COOKIES, debug: prefix_c1: > 2016-07-08 17:35:31; COOKIES, debug: prefix_my_cookie: > 2016-07-08 17:35:31; mc, debug: 0 > > indicating that cookie "my_cookie" is not set. > I am puzzled by the behavior of cookies - > request().cookies() indicates that cookie "my_cookie" exists > but session().is_set("my_cookie") says it doesn't. > How can it be so? > Is the empty cookie.path() making the trouble? > > Best Regards, > CN > > -- > http://www.fastmail.com - A fast, anti-spam email service. > > > ------------------------------------------------------------------------------ > Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San > Francisco, CA to explore cutting-edge tech and listen to tech luminaries > present their vision of the future. This family event has something for > everyone, including kids. Get more information and register today. > http://sdm.link/attshape > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: CN <cn...@fa...> - 2016-07-09 16:34:36
|
On Sat, Jul 9, 2016, at 08:02 PM, Artyom Beilis wrote: > Browser does not send path information about cookies it sends to > server in HTTP headers, actually it only sends cookie name and value - > not domain, expiration, path or other parameters. Only server does. > That is why you don't get this information in request().cookies() - > server just does not have one. Thank for answering my first question! After client gets the page from "http://localhost/normal", it calls this javascript: window.location.replace("http://localhost/special"); Upon receiving the request, server shows that request().cookies() holds item "prefix_my_cookie". On the other hand, session().is_set("my_cookie") returns false. Why server denies the existence of cookie "my_cookie"? Best Regards, CN -- http://www.fastmail.com - mmm... Fastmail... |
From: Artyom B. <art...@gm...> - 2016-07-09 18:23:30
|
Session values are not stored in various cookies but rather in the single session cookie defined by prefix. Note: you can expose values from server side to client using session().expose feature and the value will be transferred to the client but the session would never use it as it isn't secure only the data stored withing CppCMS session/and its cookie will be used regardless the other cookies defined. session().is_set(...) looks into the session not the various cookies. Artyom On Sat, Jul 9, 2016 at 7:34 PM, CN <cn...@fa...> wrote: > On Sat, Jul 9, 2016, at 08:02 PM, Artyom Beilis wrote: >> Browser does not send path information about cookies it sends to >> server in HTTP headers, actually it only sends cookie name and value - >> not domain, expiration, path or other parameters. Only server does. >> That is why you don't get this information in request().cookies() - >> server just does not have one. > > Thank for answering my first question! > > After client gets the page from "http://localhost/normal", it calls this > javascript: > > window.location.replace("http://localhost/special"); > > Upon receiving the request, server shows that request().cookies() holds > item "prefix_my_cookie". On the other hand, > session().is_set("my_cookie") returns false. > > Why server denies the existence of cookie "my_cookie"? > > Best Regards, > CN > > -- > http://www.fastmail.com - mmm... Fastmail... > > > ------------------------------------------------------------------------------ > Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San > Francisco, CA to explore cutting-edge tech and listen to tech luminaries > present their vision of the future. This family event has something for > everyone, including kids. Get more information and register today. > http://sdm.link/attshape > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: CN <cn...@fa...> - 2016-07-10 05:37:16
|
On Sun, Jul 10, 2016, at 02:23 AM, Artyom Beilis wrote: > Session values are not stored in various cookies but rather in the > single session cookie defined by prefix. > > Note: you can expose values from server side to client using > session().expose feature and the value will be transferred > to the client but the session would never use it as it isn't secure > only the data stored withing CppCMS session/and its cookie > will be used regardless the other cookies defined. > > session().is_set(...) looks into the session not the various cookies. Many thanks for the explanation! I am still stuck by the original problem. It happens in the following order: - I manually navigate browser to URL "http://localhost/normal". - Browser sends over all cookies to server. - Server receives the request and recognizes all cookies encrypted in prefix: session().is_set("my_cookie"); returns true (So far so good. As everyone else has already experienced - server has correctly processed such requests countless number of times without problem.) - Server responds with the page. - Client gets the page from "http://localhost/normal". - I manually manipulate the page through browser and cause this javascript to be called: window.location.replace("http://localhost/special"); (I do this in order to download a static file from "http://localhost/special" without navigating away the current page.) - Server receives the request for "http://localhost/special" along with the cookie encrypted in prefix same as the one it was requested for page "http://localhost/normal". However, session().is_set("my_cookie"); returns false this time! I can not figure out why server recognizes all the sent in cookies when it is requested for "http://localhost/normal", but it denies all the sent in cookies when it is requested for "http://localhost/special" by client javascript call window.location.replace(). Any idea? Please! Best Regards, CN -- http://www.fastmail.com - mmm... Fastmail... |
From: Artyom B. <art...@gm...> - 2016-07-11 14:07:36
|
I see, does it happend with server side session storage? Can you track all the requests using browser debugger and see what is transferred in each request. What you are telling me is quite strage. Artyom > - Server responds with the page. > > - Client gets the page from "http://localhost/normal". > > - I manually manipulate the page through browser and cause this > javascript to be called: > window.location.replace("http://localhost/special"); > (I do this in order to download a static file from > "http://localhost/special" without navigating away the current page.) > > - Server receives the request for "http://localhost/special" along with > the cookie encrypted in prefix same as the one it was requested for page > "http://localhost/normal". However, > session().is_set("my_cookie"); > returns false this time! > > I can not figure out why server recognizes all the sent in cookies when > it is requested for "http://localhost/normal", but it denies all the > sent in cookies when it is requested for "http://localhost/special" by > client javascript call window.location.replace(). > > Any idea? Please! > > Best Regards, > CN > > -- > http://www.fastmail.com - mmm... Fastmail... > > > ------------------------------------------------------------------------------ > Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San > Francisco, CA to explore cutting-edge tech and listen to tech luminaries > present their vision of the future. This family event has something for > everyone, including kids. Get more information and register today. > http://sdm.link/attshape > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: augustin <aug...@ov...> - 2016-07-12 04:32:04
|
On Sunday, July 10, 2016 01:37:09 PM CN wrote: > I can not figure out why server recognizes all the sent in cookies when > it is requested for "http://localhost/normal", but it denies all the > sent in cookies when it is requested for "http://localhost/special" by > client javascript call window.location.replace(). I don't understand. Does setting window.location.replace() causes a GET request to be sent to the server? Or do you have an AJAX call of some sort in your javascript? In any case, you must make sure that the cookies are sent. My guess is that it's nothing to do with the URL, but with the way the request to the server is generated. If the browser directly requests http://localhost/special, the cookies would be set, won't it? Just shooting in the dark, in the hope that it may shed some light in the situation. augustin. . |
From: CN <cn...@fa...> - 2016-07-12 17:31:52
|
On Tue, Jul 12, 2016, at 12:15 PM, augustin wrote: > I don't understand. > Does setting window.location.replace() causes a GET request to be sent to > the > server? Yes. This is the question I asked in SO: http://stackoverflow.com/questions/38245088/open-a-download-window-and-send-cookies-without-navigating-away-from-the-page > Or do you have an AJAX call of some sort in your javascript? window.location.replace() is called after HTML <input> is clicked roughly looks like this: i_am_clicked:function(e){ window.location.replace("/special"); } It is not called from AJAX. > > In any case, you must make sure that the cookies are sent. Server log shows that it does receives the cookie that comes with prefix. That cookie string is exactly the same as that hold by browsers. > My guess is that it's nothing to do with the URL, but with the way the > request > to the server is generated. The request from client in question has one thing different from others - it is initiated by javascript call window.location.replace() or its flavors, while other "valid" requests are initiated by human mouse clicks. > If the browser directly requests http://localhost/special, the cookies > would > be set, won't it? I think that server confirms that too according to this server code: for(auto const &c : request().cookies()) BOOSTER_DEBUG("COOKIES") << c.first << ":" << c.second.path() << "==>" << c.second.value(); Cookie value associated with key "prefix" is written to log. > Just shooting in the dark, in the hope that it may shed some light in the > situation. Best Regards, CN -- http://www.fastmail.com - Same, same, but different... |
From: CN <cn...@fa...> - 2016-07-12 17:13:23
|
On Mon, Jul 11, 2016, at 10:07 PM, Artyom Beilis wrote: > I see, > > does it happend with server side session storage? No. I have been always using only client side storage. This is the complete and real server configuration parameter "session": "session":{ "location":"client", "expire":"renew", "timeout":2592000, "cookies":{ "prefix":"prefix" }, "client":{ "hmac":"sha512", "hmac_key":"(redacted)", "cbc":"aes192", "cbc_key":"(redacted)" } }, > Can you track all the requests using browser debugger and see what is > transferred in each request. Yes, browser development tool shows only one "network" entry. Although I feel the information it reveals is not quite useful, they are as follows: 1 requests 168 B transferred Name:http://localhost:82/da/1/t4_722/f3/1/f2/2009-10-28%2000%3A00%3A00%2B08/f1/1 Type:document Initiator:82/script/download.html Size:168 B Time:7 ms Here are the real URL's sent from client to server: URL "/normal" is redacted from this real URL: <a href="/crud/6108" target="_blank"></a> window.location.replace("/special") is redacted from this real javascript: window.location.replace("/da/1/t4_722/f3/1/f2/2009-10-28%2000%3A00%3A00%2B08/f1/1"); The following two server codes void normal_page::main(std::string url) { //"url" holds "normal". for(auto const &c : request().cookies()) BOOSTER_DEBUG("COOKIES") << c.first << "==>" << c.second.value(); BOOSTER_DEBUG("1 is logged") << request().is_set("my_cookie"); } void download::main(std::string url) { //"url" holds "special". for(auto const &c : request().cookies()) BOOSTER_DEBUG("COOKIES") << c.first << "==>" << c.second.value(); BOOSTER_DEBUG("0 is logged") << request().is_set("my_cookie"); } and browser development tool all show the following same real cookie "prefix": CO5HS8grAi6Oa6qAqt97ZN2lIS8DDuI2OihXBV_YI-60u6zi9dbmdHb-w1XljS0HYDPlAD8AF_z2yJm2-1O0kWNtYrnxgGBGsZ8Oh0rXusajLV8-d2IK4x7mpVAedpzOcYhuuRDsHMcfdC0sXJvdTTSPy2_Q5bC9qPYzCn_kHLM90CdnqkkV_u41KpUK3XC-cm5XL82VPVKZL9UcI_Bm81-AWlP-lp-9R5HKBnfVr8FVN9-U20Y7L73wA0WFPEzEF > What you are telling me is quite strage. > I am not sure if this helps.. int main(int argc,char **argv){ ... s.applications_pool().mount(cppcms::create_pool<normal_page>(),cppcms::mount_point(cppcms::mount_point::match_path_info,"^/(?:crud)/(\\d+)",1),cppcms::app::synchronous); s.applications_pool().mount(cppcms::create_pool<download>(),cppcms::mount_point("/da/(.+)",1),cppcms::app::asynchronous); ... } window.location.replace() is called from the page requested from URL "/crud/6108". As I mentioned earlier in this thread, (1) Server recognizes all incoming cookies when it receives various requests manually sent from user's mouse clicks on buttons in the page requested from URL "/crud/6108". (2) Server denies the existence of incoming cookies only when the requested URL is initiated by javascript call window.location.replace(). Both Chrome and Firefox are treated by server in the same way. (3) Regardless of which initiation method from client, server prints the same signed and encrypted cookie value named "prefix". Best Regards, CN -- http://www.fastmail.com - The way an email service should be |
From: Artyom B. <art...@gm...> - 2016-07-13 06:14:51
|
> I am not sure if this helps.. > > int main(int argc,char **argv){ > ... > s.applications_pool().mount(cppcms::create_pool<normal_page>(),cppcms::mount_point(cppcms::mount_point::match_path_info,"^/(?:crud)/(\\d+)",1),cppcms::app::synchronous); > > s.applications_pool().mount(cppcms::create_pool<download>(),cppcms::mount_point("/da/(.+)",1),cppcms::app::asynchronous); > ... > } > This is the clue. The asynchronous application does not load session information by default - because some session backends can be blocking and may lock the entire event loop. So in async app you first need to call session().load() and than use it. Artyom P.S.: Please open a feature request so to improve the behavior. I noticed several times that it was causing issues for too many users |
From: CN <cn...@fa...> - 2016-07-13 15:17:16
|
> This is the clue. > > The asynchronous application does not load session information by > default - because some session backends can be blocking and may lock > the entire event loop. > So in async app you first need to call session().load() and than use it. You are my savior again! I repeatedly reminded myself of not falling into this trap, but eventually I made the same mistake this time again. Off topic: I should have passed cppcms::app::synchronous as argument to cppcms::service::applications_pool()::mount() instead. Somehow the code ends up passing asynchronous argument. This is the apparent negative side effect of bad copy-and-paste coding habit. > Artyom > > P.S.: Please open a feature request so to improve the behavior. I > noticed several times that it was causing issues for too many users I will do it as soon as SF is back on line. Best Regards, CN -- http://www.fastmail.com - The way an email service should be |