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

Jeremy Shaw jeremy at n-heptane.com
Mon Oct 21 20:57:07 UTC 2013


my hypothesis is that you are getting 'ErrorClosed' when calling
'sClose' because the client side has already beat you to the punch.
But that is just a hypothesis.

- jeremy

On Mon, Oct 21, 2013 at 3:34 PM, Corey O'Connor <coreyoconnor at gmail.com> wrote:
> 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/
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list