requests icon indicating copy to clipboard operation
requests copied to clipboard

comma in case: join multiple Set-Cookie Headers

Open jake491 opened this issue 8 years ago • 5 comments

Many web-apps send cookie in multiple Set-Cookie headers, one header for one cookie. Requests joins this headers in one big header separate by comma.

From same webapp to requests.get

Set-Cookie: ASP.NET_SessionId=token1; path=/; HttpOnly
Set-Cookie: Cookie1=token2; path=/ecp
Set-Cookie: X-BEResource=WIN-RBFR0BDA7V7.testlab.net~1; path=/ecp/15.0.516.30; HttpOnly
Set-Cookie: X-BackEndCookie=token3; expires=Mon, 03-Apr-2017 12:25:07 GMT; path=/ecp; HttpOnly

In requests: resp.headers this look like

Set-Cookie: ASP.NET_SessionId=token1; path=/; HttpOnly,    
  Cookie1=token2; path=/ecp, 
  X-BEResource=WIN-RBFR0BDA7V7.testlab.net~1; path=/ecp/15.0.516.30; HttpOnly, 
  X-BackEndCookie=token3; expires=Thu, 06-Apr-2017 08:27:22 GMT; path=/ecp; HttpOnly

Firefox, IE, Chrome invalid interpreted this cookies because separater is comma but in field EXPIRES comma separate day and date.

Principal problem in modification traffic. In my opinion then server send multiple headers lib must return multiple headers

jake491 avatar Apr 07 '17 10:04 jake491

Requests makes no promises about leaving headers in the form they are received from the server. Right now, I highly recommend you use the cookiejar Requests uses to store cookies rather than extracting them from the headers: we correctly insert them in there.

Longer term, we should probably add a fix to exclude the Set-Cookie header from joining in this way.

Lukasa avatar Apr 07 '17 10:04 Lukasa

This has bitten us and cost us quite a few hours. I'd like to vote to leave Set-Cookie intact. Why does requests fiddle with the headers anyways? Is there some good reason for it? IMHO it only complicates things for everybody. What am I missing? Thanks for your good work!

daniel-kun avatar Mar 19 '20 10:03 daniel-kun

Hi, there is a way to parse headers correctly with https://github.com/Ousret/kiss-headers requests won't be able to change their representation for headers any time soon.

Ousret avatar Apr 16 '20 20:04 Ousret

In order to access the unmerged header lines, use the underlying urllib3 response object (HTTPResponse):

resp = requests.get('https://myurl.com')
print(resp.raw.headers.items())

Yields (for example):

[('Cache-Control', 'no-store, no-cache, must-revalidate'),
 ('Cache-Control', 'post-check=0, pre-check=0'),
 ('Cache-Control', 'no-cache="set-cookie"'),
 ('Content-Type', 'text/html; charset=utf-8'),
 ('Date', 'Tue, 22 Feb 2022 08:12:47 GMT'),
 ('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT'),
 ('Last-Modified', 'Tue, 22 Feb 2022 08:12:47 GMT'),
 ('Pragma', 'no-cache'),
 ('Server', 'Apache/2.4.27 (Amazon) PHP/5.6.35'),
 ('Set-Cookie', 'PHPSESSID=q0br22iudsfjjkshfakl54076m1; path=/; HttpOnly'),
 ('Set-Cookie', 'lan=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=mydomain.com'),
 ...]

apeschar avatar Feb 22 '22 08:02 apeschar

In my case, I had to do response.raw.headers, adding .items() at the end returns an empty HTTPHeaderDictItemView.

andrewhong04 avatar May 14 '23 21:05 andrewhong04