meltwater / served

A C++11 RESTful web server library
MIT License
710 stars 174 forks source link

Cannot set multiple cookies because set-header overwrites set-cookie #67

Open ArthoPacini opened 4 years ago

ArthoPacini commented 4 years ago

Hi,

The Set-Cookie HTTP response header is used to send cookies from the server to the user agent, so the user agent can send them back to the server later.

The only way to set headers in served is to use the function set_header() from the request object, like so

res.set_header("Set-Cookie","foo=1");

this way, when the client get the response from the request, it gets the Cookie "foo" with a value of 1

The problem is that, in a specific request, the server may set two or more cookies, like foo=1 and bar=2,

but running

res.set_header("Set-Cookie","foo=1"); res.set_header("Set-Cookie","bar=2");

actually only sends the last key-value pair bar=2, because the request class is using a std::unordered_map<std::string, std::string> header_list

so the last value overwrites the first

also it seems that passing two cookies into one Set-Cookie is not supported on Chrome, so

res.set_header("Set-Cookie","foo=1; bar=2"); or res.set_header("Set-Cookie","foo=1, bar=2");

does not work

kiyoMatsui commented 4 years ago

Hehe... there may be a naughty trick here where we can set that header_list to a std::multimap type (this is in request.hpp not response.hpp)... it seems to pass the tests. I'll make a pull request but there may be issues with it that i'm not seeing. The maintainers will either giveth or taketh away. If you want to do this yourself go into src/served/response.cpp and change the last set_header function line to "_headers.emplace(std::make_pair(mut_header, header_pair(header, value)));" in src/served/response.hpp change the map into a std::multimap. Hopefully it doesn't break anything :).

Basically now if you do :

res.set_header("Set-Cookie","foo=1"); res.set_header("Set-Cookie","bar=2");

you will see both Set-Cookie headers