mrkkrp / req

An HTTP client library
Other
338 stars 40 forks source link

Working with cookies (question) #81

Open uzhas-sovka opened 4 years ago

uzhas-sovka commented 4 years ago

How can I add custom names to cookies? L.cookie_name and all other constructors from https://hackage.haskell.org/package/http-client-0.5.1/docs/Network-HTTP-Client.html data Cookie are OK, but my original cookie has

"storeId": "firefox-default"
"firstPartyDomain": ""

Truly speaking, everything works with HTTP-Client cookies only, but, as we are in Haskell domain, "it's not pure enough" (pun intended).


Mark, thanks a lot for your library, it's my second attempt to use it as a test site for my humble Haskell skills. But not everything is terrible with them only. It took maybe 5 hours of tinkering to create a working snippet of simple task "log into cite having cookies from FF". In any other language (even F#) I could do this from scratch (with zero previous knowledge) maybe for 20 minutes just copy-pasting from Stackoverflow.

I might be searching in wrong places, but it seems there is no single example of using cookies. Now I have one of my own, if you are still interested in this project, I may give it to you, you may add it to docs (after honing my terrible childish Haskell style).

mrkkrp commented 4 years ago

I am unsure what you are asking. Req allows you to use a specific CookieJar and then get it from the response. For all the manipulations you should use the functions from http-client (which I believe are pure). Would you like Req to provide a more declarative API for cookie manipulation?

In any other language (even F#) I could do this from scratch (with zero previous knowledge) maybe for 20 minutes just copy-pasting from Stackoverflow.

It hurts my heart to discover that Haskell sucks so badly even at simplest tasks. I do not understand why people use it for anything, honestly.

uzhas-sovka commented 4 years ago

Default route is obvious. 1) Google search "Haskell https", req is second link. 2) Open req. 3) Searching for cookies (I have them already). OOPS.

I understand that the main point of your library was completely different. But now it's in the wild and faced people with almost zero Haskell knowledge.

rgrover commented 4 years ago

I wish to use cookies across requests. I am aware that a CookieJar can be obtained from a response. But to merge cookies across requests, I need updateCookieJar from Network.HTTP.Client. updateCookieJar requires a Request parameter, which isn't exposed by req. It would be very helpful if req could expose the underlying Request. Thanks.

kindaro commented 4 years ago

To give a real world example: I was confronted by the need to emulate a browser state, and I ended up threading an MVar through, like this:

jar <- newMVar (mempty @CookieJar)
…
post jar … >>= \ response -> do …
…
where
  post :: MVar CookieJar -> Url 'Http -> ByteString -> IO BsResponse
  post cookieJarMVar url body = modifyMVar cookieJarMVar \ jar -> do
    response <- runReq httpConfig $ req POST url (ReqBodyBs body) (Proxy @BsResponse) (cookieJar jar)
    return (responseCookieJar response, response)

I wrapped all the methods I need like this. It works fine.

I am not sure if this package needs to incorporate this feature, but it seems to be a common use case and rolling out the wrappers takes some typing. @mrkkrp you are in the best position to judge if the code to this end should be admitted to the library, but surely at least some examples and directions may be given.

rgrover commented 4 years ago

@kindaro: Thanks. Yes, I am able to reuse the cookies returned in one response for the following request. The above is sufficient If all responses contained 'set-cookie' values for the same set of cookies. But if different responses update subsets of the cookie-jar, then cookies need to be accumulated across requests. In the case, one would need to use updateCookieJar, which requires a Request object. Unfortunately, req does not expose the underlying Request.

kindaro commented 4 years ago

Oh I see, so you have some requests that do not send back a cookie jar. At first I did not realize that.

It looks like some sort of a monad here, a hybrid between Writer and State.

mrkkrp commented 4 years ago

Am I correct that we could solve (or at least alleviate) the issue by adding a new method to the HttpResponse type class which would allow us to get the Request used to obtain the response?

hughjfchen commented 3 years ago

I think you can extract the cookieJar from response after the request and put it into a State monad. You can merge multi cookieJar across requests by getting the previous one and <> the current one because cookieJar is the instance of monoid if I remember correctly.