[Haskell-cafe] Network.HTTP+ByteStrings Interface--Or: How to shepherd handles and go with the flow at the same time?

haskell at list.mightyreason.com haskell at list.mightyreason.com
Wed May 23 18:21:47 EDT 2007


I am uncertain about all the issues here, but....

Why do you need to convert Socket to Handle?

I have no clue if this code I pasted below works but it does compile:

> import Network.Socket
> import Data.ByteString.Base as Base
> 
> -- 'recvBSFrom' gets a strict ByteString from a socket.
> -- createAndTrim' was not quite documented, so I looked at
> -- http://darcs.haskell.org/packages/base/Data/ByteString/Base.hs
> recvBSFrom :: Socket -> Int -> IO (ByteString,SockAddr)
> recvBSFrom sock nbytes =
>   Base.createAndTrim' nbytes $ \ptr -> do
>     (len,sockaddr) <- recvBufFrom sock ptr nbytes
>     -- maybe check if len is (-1) ?
>     return (0,len,sockaddr)

I was not sure how recvBufFrom handles errors, so if recvBufFrom might return a
len of (-1) then the above will need to detect this.  (This looks like it might
happen for non-blocking sockets).

The above was modeled after recvfrom, reproduced below from source
at http://darcs.haskell.org/packages/network/Network/Socket.hsc

> recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
> recvFrom sock nbytes =
>   allocaBytes nbytes $ \ptr -> do
>     (len, sockaddr) <- recvBufFrom sock ptr nbytes
>     str <- peekCStringLen (ptr, len)
>     return (str, len, sockaddr)

If you can figure out how to defer the calls to recvBSFrom properly then you can
make Lazy ByteStrings as well.  One would need to understand how to set the
socket to non-blocking (?) and mimic the hGetContentsN code from
http://darcs.haskell.org/packages/base/Data/ByteString/Lazy.hs

If this hypothetical 'socketGetContentsAsLazyByteString' also creating a
newEmptyMVar then it could return a (tryPutMVar m ()) action to allow the
consumer of the lazy string to signal to the deferred reading process (which
periodically calls (isEmptyMVar m)) that it should close the socket or at least
stop trying to read from it.  That way there is no _need_ to 'seq' your way to
the end of the lazy bytestring to cause it to close.

-- 
Chris



More information about the Haskell-Cafe mailing list