[Haskell-cafe] Contributing to http-conduit

Myles C. Maxfield myles.maxfield at gmail.com
Wed Jan 25 19:18:38 CET 2012

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

As for cookie handling - I think Network.Browser has a pretty elegant
solution to this. They allow a "CookieFilter" which has type of
 -> Cookie<http://hackage.haskell.org/packages/archive/HTTP/3001.0.0/doc/html/Network-Browser.html#t%3ACookie>
 -> IO<http://hackage.haskell.org/packages/archive/base/>
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?

Myles C. Maxfield

On Wed, Jan 25, 2012 at 5:10 AM, Aristid Breitkreuz <aristidb at googlemail.com
> 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" <michael at snoyman.com>:
>>  On Wed, Jan 25, 2012 at 9:01 AM, Myles C. Maxfield
>> <myles.maxfield at gmail.com> wrote:
>> > 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
>> themselves?
>> >
>> > 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 at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120125/94faa54e/attachment.htm>

More information about the Haskell-Cafe mailing list