psf / requests

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

How to propagate cookie policies through posts? #5449

Open karres-illinois opened 4 years ago

karres-illinois commented 4 years ago

Hi,

I am using Python 3.8 and the latest pip updates of everything mentioned below.

I am trying to consume a very old, but active SOAP resource. I am using Zeep for the SOAP part. The SOAP service is so old that I need to set a special cookie policy to handle the fact that the old SOAP service returns obsolete set-cookie2 headers. I am new to this so there could be better ways but the first few executable lines of my code sample (at the bottom) create a dummy cookie to establish a cookie policy that should pull in the obsolete cookies.

THe dummy cookie is attached to the session and the SOAP "login" method is called. I have stepped through the execution path (most recent on top). Everything above the "transports" lines is in the your domain I think.

        merge_cookies, cookies.py:549
        prepare_request, sessions.py:441
        request, sessions.py:516
        post, sessions.py:578
        post, transports.py:61
        post_xml, transports.py:107
        send, soap.py:122
        __call__, proxy.py:40
        <module>, zeep_test.py:31

I have modified Zeep's code to send the session cookies to your "post" method in the "kwargs".

        response = self.session.post(
            address, data=message, headers=headers,
            timeout=self.operation_timeout, 
            cookies=self.session.cookies
        )

"post" calls "request" calls "prepare_request" calls "merge_cookies". That code is:

        # Merge with session cookies
        merged_cookies = merge_cookies(
            merge_cookies(RequestsCookieJar(), self.cookies), cookies)

In my case the passed in cookie is a "cookielib.CookieJar". The line:

        try:
            cookiejar.update(cookies)

is executed but the "cookielib.CookieJar" policies are NOT copied over. I don't know what to do about that. Is there a better way to set a global cookie policy?

A relevant portion of my code is:

        import requests
        from requests import Session, cookies
        from zeep import Client, Settings
        from zeep.cache import SqliteCache
        from zeep.transports import Transport
        from http.cookiejar import CookieJar, DefaultCookiePolicy

        policy = DefaultCookiePolicy(rfc2965=True)
        cj = CookieJar(policy)
        cj.set_cookie(requests.cookies.create_cookie(name="dummy", value="dummy"))

        my_session = Session()
        my_session.cookies = cj

        my_settings = Settings(strict=False)
        my_cache = SqliteCache()
        my_url = 'https://lists.mycompany.com/lists/wsdl'

        client = Client(
            my_url,
            transport=Transport(
                session=my_session,
                cache=my_cache
            ),
            settings=my_settings
        )

        response = client.service.login(email="Me",
                                        password="mememe")
nateprewitt commented 4 years ago

Hi @karres-illinois,

Thanks for bringing this up! We've known about this issue for a good while now and there's been a lot of debate about whether people actually use the Python cookie policies in their code. There's a PR from some time ago #3463 that was intended to address this that never got merged.

Given we've seen a few comments around this over the last 6 months, it may be time to revisit. I'll try to spin back up that old patch rebased onto current Requests and see if it's still an option.

sigmavirus24 commented 4 years ago

@nateprewitt it's basically a nightmare to do correctly without breaking a bunch of nonsense in the midst of it. I'm happy to pair on it at some point if you'd like.

karres-illinois commented 4 years ago

I dig that there is debate about this and that I may have a corner case. Is there any workaround you can suggest?

sigmavirus24 commented 4 years ago

I dig that there is debate about this and that I may have a corner case. Is there any workaround you can suggest?

To be clear @karres-illinois, there's no debate that you're correct about this being a thing the library should do. It's more about wiring it into the library which already does some bizarre things to act like an art project. There's a fair amount of monkey-patching that you'd have to do. It also requires the Cookie Jar class that is in this library be completely rewritten if I remember correctly.

All of that is to say "I don't recall if there's a good way to achieve what you want"

karres-illinois commented 4 years ago

Ah, thanks. I'll keep an interested eye on this over time. good luck.