Skip to content

Instantly share code, notes, and snippets.

@mwotton
Created July 25, 2013 06:01
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mwotton/6077238 to your computer and use it in GitHub Desktop.
Save mwotton/6077238 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedStrings #-}
import qualified Network.HTTP.Conduit as H
import Control.Exception
import Web.Scotty
import System.Environment
import System.IO
import System.Directory
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as BS
main :: IO ()
main = do
port <- getEnv "PORT"
cachedir <- getEnv "cachedir"
scotty (read port) $ do
get "/:domain/favicon.ico" $ do
domain <- param "domain"
let filename = cachedir ++ "/" ++ domain
liftIO (proxy domain filename)
header "Content-Disposition" "binary/data"
file filename
proxy :: String -> String -> IO ()
proxy domain filename = do
exists <- doesFileExist filename
when (not exists) fetch
where fetch = handle handler $ H.simpleHttp url >>= BS.writeFile filename
url = "http://" ++ domain ++ "/favicon.ico"
handler :: SomeException -> IO ()
handler e = hPutStrLn stderr (show e)
@mwotton
Copy link
Author

mwotton commented Jul 29, 2013

This requires GHC HEAD.

weighttp -n 1000000 -c 100 -t 4 -k localhost:3001/google.com/favicon.ico

to warm it up, then

weighttp -n 10000000 -c 100 -t 4 -k localhost:3001/google.com/favicon.ico

for the actual test (4 threads simulating 25 concurrent connections apiece)

node: 44019 req/s
haskell: 112398 req/s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment