aesiniath / http-streams

Haskell HTTP client library for use with io-streams
https://hackage.haskell.org/package/http-streams
BSD 3-Clause "New" or "Revised" License
50 stars 48 forks source link

HTTP/2 support #132

Open bapcyk opened 1 year ago

bapcyk commented 1 year ago

The function parseStatusLine expects "HTTP/1.X" but we have already "HTTP/2". For me, I get Parse exception: not enough input, not sure the cause, but maybe this function is a problem:

parseStatusLine :: Parser (Int, ByteString)
parseStatusLine = do
    sc <- string "HTTP/1." *> satisfy version *> char ' ' *> decimal <* char ' '
    sm <- takeTill (== '\r') <* crlf
    return (sc, sm)
  where
    version c = c == '1' || c == '0'

?

istathar commented 1 year ago

I think you'll find that supporting HTTP 2.0 is a much bigger topic than just changing the parser. I'd like it very much if we could! We probably have to deal with this fairly soon.

bapcyk commented 1 year ago

@istathar Do you have idea what is the reason of the error Parse exception: not enough input? Is it really due to string "HTTP/1."?

istathar commented 1 year ago

@bapcyk The diagnostics (sic) out of attoparsec are so rubbish. I didn't know better in 2013 when I was writing this; nowadays I would optimize for comprehensible error messages over some notional and arguable idea of "performance".

Do you have a way I can see the error you're seeing (is the URL public)?

bapcyk commented 1 year ago

@bapcyk The diagnostics (sic) out of attoparsec are so rubbish. I didn't know better in 2013 when I was writing this; nowadays I would optimize for comprehensible error messages over some notional and arguable idea of "performance".

Do you have a way I can see the error you're seeing (is the URL public)?

Unfortunately the URL is not public. I saw a header like:

< HTTP/2 302
< location: https://cdn.XYZ.com/api/get/21338/serve?nva=20230202134343&token=XXXXXXXXXXXXXXXXXXXX
< x-rate-limit-duration: 1
< x-rate-limit-limit: 5.00
< x-rate-limit-request-forwarded-for: 192.168.1.101, 192.168.1.102
< x-rate-limit-request-remote-addr: 192.168.1.103:16418
< date: Fri, 03 Feb 2023 13:03:43 GMT
< content-length: 0
< via: 1.1 google
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

(curl output) and supposed that the problem maybe is in it.

istathar commented 1 year ago

Well you're right it's trying to upgrade to an HTTP/2 connection. It's a radically different protocol. We're not in a particularly good place in Haskell client-wise there (ironically, we have an excellent HTTP/2 server in the http2 package). See there, and the [separate] http2-client package. I don't know how well along either of these things are, but HTTP 2.0 is complicated. I have a feeling we'd all be better off supporting their work.

istathar commented 1 year ago

(fwiw at one site this http-streams package is handling 100 million requests [POSTs, in fact] a day no problem. So it's working fine. I just don't know what our upgrade path is)

bapcyk commented 1 year ago

Ah, well, OK then. I will switch to another package currently. Maybe to close the issue then?

istathar commented 1 year ago

Maybe to close the issue then?

Nah, leave it open. It's something we need to work out.