Well, this is embarrassing. Please disregard my previous email. I should learn to read the RFC *before* submitting proposals.
--Myles On Tue, Jan 31, 2012 at 6:37 PM, Myles C. Maxfield <myles.maxfi...@gmail.com > wrote: > Here are my initial ideas about supporting cookies. Note that I'm using > Chrome for ideas since it's open source. > > - Network/HTTP/Conduit/Cookies.hs file > - Exporting the following symbols: > - type StuffedCookie = SetCookie > - A regular SetCookie can have Nothing for its Domain and Path > attributes. A StuffedCookie has to have these fields set. > - type CookieJar = [StuffedCookie] > - Chrome's cookie jar is implemented as (the C++ equivalent of) > Map W.Ascii StuffedCookie. The key is the "eTLD+1" of the domain, so > lookups for all cookies for a given domain are fast. > - I think I'll stay with just a list of StuffedCookies just to > keep it simple. Perhaps a later revision can implement the faster > map. > - getRelevantCookies :: Request m -> CookieJar -> UTCTime -> > (CookieJar, Cookies) > - Gets all the cookies from the cookie jar that should be set > for the given Request. > - The time argument is whatever "now" is (it's pulled out of the > function so the function can remain pure and easily testable) > - The function will also remove expired cookies from the cookie > jar (given what "now" is) and return the filtered cookie jar > - putRelevantCookies :: Request m -> CookieJar -> [StuffedCookie] > -> CookieJar > - Insert cookies from a server response into the cookie jar. > - The first argument is only used for checking to see which > cookies are valid (which cookies match the requested domain, etc, so > site1.com can't set a cookie for site2.com) > - stuffCookie :: Request m -> SetCookie -> StuffedCookie > - If the SetCookie's fields are Nothing, fill them in given the > Request from which it originated > - getCookies :: Response a -> ([SetCookie], Response a) > - Pull cookies out of a server response. Return the response > with the Set-Cookie headers filtered out > - putCookies :: Request a -> Cookies -> Request a > - A wrapper around renderCookies. Inserts some cookies into a > request. > - Doesn't overwrite cookies that are already set in the request > - These functions will be exported from Network.HTTP.Conduit as > well, so callers can use them to re-implement redirection chains > - I won't implement a cookie filtering function (like what > Network.Browser has) > - If you want to have arbitrary handling of cookies, re-implement > redirection following. It's not very difficult if you use the API > provided, > and the 'http' function is open source so you can use that as a > reference. > - I will implement the functions according to RFC 6265 > - I will also need to write the following functions. Should they also > be exported? > - canonicalizeDomain :: W.Ascii -> W.Ascii > - turns "..a.b.c..d.com..." to "a.b.c.d.com" > - Technically necessary for domain matching (Chrome does it) > - Perhaps unnecessary for a first pass? Perhaps we can trust > users for now? > - domainMatches :: W.Ascii -> W.Ascii -> Maybe W.Ascii > - Does the first domain match against the second domain? > - If so, return the prefix of the first that isn't in the second > - pathMatches :: W.Ascii -> W.Ascii -> Bool > - Do the paths match? > - In order to implement domain matching, I have to have knowledge > of the Public Suffix > List<http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat> > so > I know that sub1.sub2.pvt.k12.wy.us can set a cookie for > sub2.pvt.k12.wy.us but not for k12.wy.us (because pvt.k12.wy.us is a > "suffix"). There are a variety of ways to implement this. > - As far as I can tell, Chrome does it by using a script (which a > human periodically runs) which parses the list at creates a .cc file > that > is included in the build. > - I might be wrong about the execution of the script; it might > be a build step. If it is a build step, however, it is suspicious > that a > build target would try to download a file... > - Any more elegant ideas? > > Feedback on any/all of the above would be very helpful before I go off > into the weeds on this project. > > Thanks, > Myles C. Maxfield > > On Sat, Jan 28, 2012 at 8:17 PM, Michael Snoyman <mich...@snoyman.com>wrote: > >> Thanks, looks great! I've merged it into the Github tree. >> >> On Sat, Jan 28, 2012 at 8:36 PM, Myles C. Maxfield >> <myles.maxfi...@gmail.com> wrote: >> > Ah, yes, you're completely right. I completely agree that moving the >> > function into the Maybe monad increases readability. This kind of >> function >> > is what the Maybe monad was designed for. >> > >> > Here is a revised patch. >> > >> > >> > On Sat, Jan 28, 2012 at 8:28 AM, Michael Snoyman <mich...@snoyman.com> >> > wrote: >> >> >> >> On Sat, Jan 28, 2012 at 1:20 AM, Myles C. Maxfield >> >> <myles.maxfi...@gmail.com> wrote: >> >> > the fromJust should never fail, beceause of the guard statement: >> >> > >> >> > | 300 <= code && code < 400 && isJust l'' && isJust l' = Just $ >> req >> >> > >> >> > Because of the order of the && operators, it will only evaluate >> fromJust >> >> > after it makes sure that the argument isJust. That function in >> >> > particular >> >> > shouldn't throw any exceptions - it should only return Nothing. >> >> > >> >> > Knowing that, I don't quite think I understand what your concern is. >> Can >> >> > you >> >> > elaborate? >> >> >> >> You're right, but I had to squint really hard to prove to myself that >> >> you're right. That's the kind of code that could easily be broken in >> >> future updates by an unwitting maintainer (e.g., me). To protect the >> >> world from me, I'd prefer if the code didn't have the fromJust. This >> >> might be a good place to leverage the Monad instance of Maybe. >> >> >> >> Michael >> > >> > >> > >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe