{-# LANGUAGE FlexibleInstances #-}
module Thrift.Transport.HttpClient
( module Thrift.Transport
, HttpClient (..)
, openHttpClient
) where
import Thrift.Transport
import Thrift.Transport.IOBuffer
import Network.URI
import Network.HTTP hiding (port, host)
import Data.Maybe (fromJust)
import Data.Monoid (mempty)
import Control.Exception (throw)
import qualified Data.ByteString.Lazy as LBS
data HttpClient =
HttpClient {
hstream :: HandleStream LBS.ByteString,
uri :: URI,
writeBuffer :: WriteBuffer,
readBuffer :: ReadBuffer
}
uriAuth :: URI -> URIAuth
uriAuth = fromJust . uriAuthority
host :: URI -> String
host = uriRegName . uriAuth
port :: URI -> Int
port uri_ =
if portStr == mempty then
httpPort
else
read portStr
where
portStr = dropWhile (== ':') $ uriPort $ uriAuth uri_
httpPort = 80
openHttpClient :: URI -> IO HttpClient
openHttpClient uri_ = do
stream <- openTCPConnection (host uri_) (port uri_)
wbuf <- newWriteBuffer
rbuf <- newReadBuffer
return $ HttpClient stream uri_ wbuf rbuf
instance Transport HttpClient where
tClose = close . hstream
tPeek = peekBuf . readBuffer
tRead = readBuf . readBuffer
tWrite = writeBuf . writeBuffer
tFlush hclient = do
body <- flushBuf $ writeBuffer hclient
let request = Request {
rqURI = uri hclient,
rqHeaders = [
mkHeader HdrContentType "application/x-thrift",
mkHeader HdrContentLength $ show $ LBS.length body],
rqMethod = POST,
rqBody = body
}
res <- sendHTTP (hstream hclient) request
case res of
Right response ->
fillBuf (readBuffer hclient) (rspBody response)
Left _ ->
throw $ TransportExn "THttpConnection: HTTP failure from server" TE_UNKNOWN
return ()
tIsOpen _ = return True