
Alright, that's fine. I just wanted to be explicit about the interface we'd
be providing. Taking the Request construction code out of 'http' and
putting it into its own function should be a quick change - I'll have it to
you soon. One possible wrench - The existing code copies some fields (like
the proxy) from the original request. In order to keep this functionality,
the signature would have to be:
checkRedirect :: Request m -> Response -> Maybe (Request m)
Is that okay with you? I think I'd also like to call the function something
different, perhaps 'getRedirectedRequest'. Is that okay? I'll also add an
example to the documentation about how a caller would get the redirection
chain by re-implementing redirection (by using the example in your previous
email).
As for cookie handling - I think Network.Browser has a pretty elegant
solution to this. They allow a "CookieFilter" which has type of
URIhttp://hackage.haskell.org/packages/archive/network/2.2.1.7/doc/html/Network...
-> Cookiehttp://hackage.haskell.org/packages/archive/HTTP/3001.0.0/doc/html/Network-B...
-> IOhttp://hackage.haskell.org/packages/archive/base/4.2.0.0/doc/html/System-IO....
Boolhttp://hackage.haskell.org/packages/archive/base/4.2.0.0/doc/html/Data-Bool.....
Cookies are only put in the cookie jar if the function returns True. There
is a default CookieFilter, which behaves as we would expect, but the user
can override this function. That way, if you don't want to support cookies,
you can just pass in (\ _ _ -> return False).
If we're already expecting people that want specific functionality to
re-implement the redirect-following code, this solution might be
unnecessary. Do you think that such a concept would be beneficial for
Network.HTTP.Conduit to implement?
Either way, I'll probably end up making a solution similar to your
checkRedirect function that will just allow people to take SetCookies out
of a Response and put Cookies into a Request. I'll probably also provide a
default function which converts a SetCookie into a cookie by looking up the
current time, inspecting the Request, etc. This will allow me to not have
to change the type of Request or Response - the functions I'll be writing
can deal with the raw Headers that are already in Requests and Responses.
Modifying 'http' to use these functions will be straightforward.
How does this sound to you?
Thanks,
Myles C. Maxfield
On Wed, Jan 25, 2012 at 5:10 AM, Aristid Breitkreuz wrote: The nice thing is that this way, nobody can force me to handle cookies.
;-) Might be that usage patterns emerge, which we can then codify into
functions later.
Am 25.01.2012 08:09 schrieb "Michael Snoyman" Sorry, I think I'm still a little confused about this. From the point of view of a library user, if I use the 'http' function,
but
want to know what final URL I ended up at, I would have to set
redirects to
0, call http, call checkRedirect, and recurse until checkRedirect
returns
Nothing (or a count runs out). I would be handling the recursion of
redirects myself. On one hand, this solution is lightweight and easy to implement in the
library. On the other hand, the caller has to run each individual
request
themselves, keeping track of the number of requests (so there isn't an
infinite loop). The loop is already implemented in the http function - I
think it's reasonable to modify the existing loop rather than expect the
caller to re-implement that logic. However, it's probably just as reasonable to say "if you want to know
what
URL you end up at, you have to re-implement your own
redirection-following
logic." I do agree, however, that including an (possibly long, though explicitly
bounded) [Ascii] along with every request is arbitrary, and probably
not the
best solution. Can you think of a solution which allows the caller to
know
the url chain (or possibly just the last URL - that's the important one)
without having to re-implement the redirection-following logic On Wed, Jan 25, 2012 at 9:01 AM, Myles C. Maxfield
It sounds like if you had to choose, you would rather force a caller to
re-implement redirection-following rather than include a URL chain in every Response. Is this correct? That's correct. I think knowing the final URL is a fairly arbitrary
requirement, in the same boat as wanting redirect handling without
supporting cookies. These to me fall well within the 20%: most people
won't need them, so the API should not be optimized for them. There's also the fact that [Ascii] isn't nearly enough information to
properly follow the chain. Next someone's going to want to know if a
request was GET or POST, or whether it was a permanent or temporary
redirect, or the exact text of the location header, or a million other
things involved. If someone wants this stuff, they should reimplement
the redirect logic. But I don't really see this as being such a burden. If we had the
checkRedirect function, it would look something like: myHttp req = do
let req' = req { redirectCount = 0 }
res <- http req'
case checkRedirect res of
Just req2 -> myHttp req2
Nothing -> return res I don't think that's a terrible burden. Michael _______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe