[Haskell-cafe] a tiny HTTP server.. that doesn't work

Corey O'Connor coreyoconnor at gmail.com
Mon Oct 21 20:34:53 UTC 2013


I attempted to write a tiny HTTP server using only Haskell Platform
packages:

* https://github.com/coreyoconnor/tiny-http-hp

Which works... Unless the threaded runtime is used.

When compiled using the threaded runtime and run with +RTS -N this server
fails to reply correctly to ~3% of requests. The expectation is that the
reply will be exactly the request body. However, 3% of the time the HTTP
request fails to be parsed due to an "ErrorClosed"

The server then executes:

* https://github.com/coreyoconnor/tiny-http-hp/blob/master/TinyHttp.hs#L23

which responds to the client. The client receives the response correctly
most of the time.

My current hypothesis is that some aspect of lazy IO is not playing nice.
The connection is being closed before the request can be completely parsed.

Is this correct? What am I missing?

I know there are other HTTP server packages that could be used. However,
the exercise was to build a HTTP server using only Haskell Platform
packages.

Below is the main body of the code:

main = withSocketsDo $ do
    http_socket <- listenOn $ PortNumber 9090
    dispatch_on_accept http_socket $ either handle_failed_request
handle_valid_request
    sClose http_socket

handle_failed_request failure = return $ Response (4,0,0) "Bad
Request" [mkHeader HdrConnection "close"]
                                                  (encodeUtf8 $ pack $
show failure)

handle_valid_request request = do
    let request_body = rqBody request
    return $ Response (2,0,0) "OK" [mkHeader HdrConnection "close"]
                      (encodeUtf8 $ pack $ show request_body)

dispatch_on_accept http_socket handler = forever $ accept http_socket
>>= forkIO . httpHandler . fst
    where
        httpHandler client_socket = bracket (socketConnection "client"
0 client_socket)
                                            Network.HTTP.close
                                            client_interact
        client_interact :: HandleStream BS.ByteString -> IO ()
        client_interact byte_stream = receiveHTTP byte_stream >>=
handler >>= respondHTTP byte_stream


-Corey O'Connor
coreyoconnor at gmail.com
http://corebotllc.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20131021/f3f6fc97/attachment.html>


More information about the Haskell-Cafe mailing list