psf / requests

A simple, yet elegant, HTTP library.
https://requests.readthedocs.io/en/latest/
Apache License 2.0
52.19k stars 9.33k forks source link

RequestsCookieJar appends ".local" to cookie from localhost #5388

Open dominickj-tdi opened 4 years ago

dominickj-tdi commented 4 years ago

When I make a request to localhost (on my development machine), Requests changes the domain from "localhost" to "localhost.local" when saving the cookie. Thus, I am unable to access the cookie if I specify the domain parameter in the get method.

My app requires me to get and set cookies on the session object as a persistence mechanism; I need to persist this cookie over more than one session in the python app.

Expected Result

I would expect the domain in RequestCookieJar to always match the domain I used to make the request.

Actual Result

If I make a request to localhost, instead I get the cookie saved to the domain "localhost.local". (Note that I cannot actually make requests to "localhost.local", they fail.) This puts me in a position where I must make requests to "localhost" but use "localhost.local" to get or set the cookie.

Reproduction Steps

>>> import requests
>>> ses = requests.Session()
>>> ses.get('http://localhost/')
<Response [200]>
>>> ses.cookies
<RequestsCookieJar[Cookie(version=0, name='PHPSESSID', value='ui1hr334bmcr1r85jlu8k3rq65', port=None, port_specified=False, domain='localhost.local', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={}, rfc2109=False)]>
>>> ses.cookies.get('PHPSESSID')
'ui1hr334bmcr1r85jlu8k3rq65'
>>> ses.cookies.get('PHPSESSID', domain='localhost')
>>> ses.cookies.get('PHPSESSID', domain='localhost.local')
'ui1hr334bmcr1r85jlu8k3rq65'

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.8"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.7.3"
  },
  "platform": {
    "release": "10",
    "system": "Windows"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.22.0"
  },
  "system_ssl": {
    "version": "101000af"
  },
  "urllib3": {
    "version": "1.25.3"
  },
  "using_pyopenssl": false
}
hodbn commented 4 years ago

Hi,

Requests uses cookielib.make_cookies to fill its RequestsCookieJar. In turn, cookielib.make_cookies uses cookielib.eff_request_host to extract the erhn. cookielib conforms to rfc2965 which states:

The term effective host name is related to host name. If a host name contains no dots, the effective host name is that name with the string .local appended to it

Therefore, unless cookielib adds support and defaults its policy to rfc6265, I think this is unavoidable :(

Do you have any ideas?

dominickj-tdi commented 4 years ago

What if we just added a line like this to RequestsCookieJar.get() and RequestCookieJar.set() then?

if '.' not in domain:
    domain += '.local'

That would be a pretty minor change that I don't imagine would cause issues for existing scripts, but would allow scripts to use host names without dots.

dominickj-tdi commented 4 years ago

Just as a note, I am using the above two lines in my own code where I call session.cookies.set() and session.cookies.get(). Everything works as expected with that workaround. But I still think it would be good to include in the main library. I'd be happy to submit a pull request if the team would be willing to merge it.