-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setcookie should overwrite cookie header with same info #18169
Comments
But is this argument ever valid elsewhere? We can't change language semantics because of buggy 3rd party code.
Not really, only in applications that send the same cookie over and over again. The rest would be slower due to the buffering and scanning existing cookies. And we shouldn't optimize for buggy code. Anyway, I don't work much on the HTTP part of PHP, maybe @bukka has opinions. |
This is already happening in PHP anyway -
|
@kkmuffme This buffers all headers, but not just cookies. Presumably, we would not want to scan through all headers and especially not parse them just to find out whether some cookie was already set. But yes, maybe buffering wasn't the best choice of words. |
In some kind this is happening already when using
Because it's much slower (= have to parse all headers) and also not easily possible without either causing side-effects or not breaking other things/having a guarantee that it runs bc |
Essentially what is happening now: except that instead of overwriting the whole Set-Cookie, only if it's essentially the same cookie |
As @iluuu1994 pointed out, this would be a bit more expensive because you would need to extract just name, path and domain and use only that for comparison. So I think we would need a special list for that. I can see the use case (especially in some CMS environments where the cookie addition happens from multiple plugins / libs) but it should not be a default because for many users that control cookie addition, this is not a problem and we would just add an unnecessary overhead. So I think it should be the same like for Also I just read https://datatracker.ietf.org/doc/html/rfc6265#section-5.3 (point 11) and there is a minor semantical difference:
As I understand it the part about http-only-flag might mean a slight change - should not be really a problem in reality but it is minor change IMHO. In this I consider that the storage would first store cookie that is first defined and then process the duplicate. With your replace the non http-only would simple overwrite unless we would implent this sort of logic as well. It might be worth to handle it as well though but it would need some testing if browser really behave like specified. In any case it shows that extra parameter would be probably more convenient. But not sure how helpful this would be because it would require to add the parameter to all calls. Maybe INI would be an option but considering some other discussion I don't think it will get much support. |
I think it will be quite hard to find a clear consensus on this so it might be necessary to go through RFC. |
Or at least have discussion on internals where everyone is fine with the proposed solution |
Personally if we iron out the semantic difference - meaning there won't be any, then I wouldn't have a problem with INI, because it's more perf tweak that works in some case but doesn't work elsewhere. But as I said, it might not be popular. |
Could store the cookie name as a separate list and if same cookie name set again set it to a value of true. Then only if we have duplicate cookies, deduplicate immediately before the headers get sent, bc that way it only needs to happen once (basically what is possible with But I agree: it's important that the performance impact is negligibly small for unaffected requests.
Many users have no idea that they suffer from that problem and misconfigure their servers. If you google |
Description
setcookie() currently just adds another HTTP header (= like calling
header( 'Set-Cookie: ...', false );
in all cases.This means if the same cookie (= functionaly identical, e.g. same name+path+domain+...) is set multiple times (e.g. different value/expiration or also for whatever reason same value/expiration) it will just add another Set-Cookie header.
Since HTTP headers cannot be compressed* or compression happens upstream, this causes significant performance downsides:
upstream needs to allocate larger buffers (nginx
fastcgi_buffer
) that exceed 1 or 2 memory pages for the odd request that has this issue, leading to significantly higher memory consumption just for the rare request that has this issue. e.g. only 0.0001% of requests send headers that exceed 4k (one memory page). Those requests send headers with an average size of 12k and a maximum of 16k.This means that a buffer size of 16k has to be allocated, which means that if we can serve up to 100000 requests simultaneously (= 2000 pages that each contain ~50 js/css/images) that's more than 1GB of memory unnecessarily allocated/wasted just to ensure that the 1 request that has this issue to not cause
upstream sent too big header while reading response header from upstream
the overall page load can take significantly longer - e.g. HTTP headers are 6k and compressed page is 6k (assuming the page is served from a PHP page cache to ignore any other effects). If the set-cookie headers are deduplicated it's HTTP headers 0.5k + 6k effectively reducing the overall page load time by almost 50% in this example:
While it's true that in many cases, these duplicate setcookie calls indicate an issue in the application, it's often outside of the scope (= 3rd party dependencies causing it or people not being aware of this issue at all in the first place) of the application.
This change could result in a significant performance gain (= time until the first part of the document is loaded) for all PHP applications on pages where they set cookies.
*in http2/3 they can, but it's practically not supported or implemented anywhere and that's unlikely to change
The text was updated successfully, but these errors were encountered: