So if `pipes-http` is built on top of `http-client` the glue code would be incredibly small, so it would probably not be worth abstracting over this.

To summarize this for people who are not familiar with the `http-client` API, the relevant parts are the `RequestBodyStreamChunked` constructor that you use to build `Request`s:

https://hackage.haskell.org/package/http-client-0.2.1.1/docs/Network-HTTP-Client.html#v:RequestBodyStream

... and the `brRead` accessor for the `BodyReader` you get from a `Response`:

https://hackage.haskell.org/package/http-client-0.2.1.1/docs/Network-HTTP-Client.html#v:brRead

The `RequestBodyStreamChunked` constructor expects an argument of type:

    (IO ByteString -> IO ()) -> IO ()

It's a little bit confusing if you're not familiar with continuations, but it basically means that you need to provide the `Request` with an `IO ByteString` action that outputs request chunks and returns an empty bytestring to denote stream termination.

The equivalent `pipes` abstraction is a `Producer ByteString IO ()`, and here's the code to convert a `Producer` to the necessary format that `http-client` expects:

    import Data.ByteString (ByteString, empty)
    import Data.IORef (newIORef, readIORef, writeIORef)
    import Pipes

convert :: Producer ByteString IO () -> (IO ByteString -> IO ()) -> IO ()
    convert p0 k = do
        ioref <- newIORef p0
        let readAction :: IO ByteString
            readAction = do
                p <- readIORef ioref
                x <- next p
                case x of
                    Left   ()      -> do
                        writeIORef ioref (return ())
                        return empty
                    Right (bs, p') -> do
                        writeIORef ioref p'
                        return bs
        k readAction

Note that this is very similar to how `draw` from `pipes-parse` works, except storing the `Producer` in an `IORef` instead of a `StateT` monad.

Interfacing with the `BodyReader` is also easy since it just returns an `IO ByteString` action, which we can convert back to a `Producer`:

    import Control.Monad (unless)
    import Data.ByteString (ByteString)
    import qualified Data.ByteString as B
    import Pipes

    convert :: IO ByteString -> Producer ByteString IO ()
    convert io = go
      where
        go = do
            bs <- lift io
            unless (B.null bs) $ do
                yield bs
                go

So that's pretty much the entirety of the conversion. I'd probably dress it up a little bit and create the `pipes` analogs of `http-conduit`'s `http`, `requestBodySource`, and `requestBodySourceChunked` functions:

http://hackage.haskell.org/package/http-conduit-2.0.0.4/docs/Network-HTTP-Conduit.html#v:http

http://hackage.haskell.org/package/http-conduit-2.0.0.4/docs/Network-HTTP-Conduit.html#v:requestBodySource

http://hackage.haskell.org/package/http-conduit-2.0.0.4/docs/Network-HTTP-Conduit.html#v:requestBodySourceChunked

... but that's about it.

The only reason I raised this topic is not because the wrapper is difficult (it's not), but just to see if anybody had objections to `http-client` (i.e. API, technical issues, security, or performance). Judging from the responses it seems that most people would be happy with building this on top of `http-client` and `http-client-tls` so I will write up a quick skeleton.

On 01/28/2014 05:41 PM, Pierre R wrote:
Is it possible to provide a sane "pipes-http-client API" that would work whatever the underline implementation is ?

Then make one that works choosing the easiest path possible. At that point anyone can try to beat the underline implementation using other facilities (whether it is based on `http-streams`, `pipes`, `conduit` or a mix of them).

Is the Haskell module system to weak for this ?



--
You received this message because you are subscribed to the Google Groups "Haskell Pipes" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].

--
You received this message because you are subscribed to the Google Groups "Haskell 
Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].

Reply via email to