hoauth2-0.2.4: src/Network/OAuth2/HTTP/HttpClient.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
-- | A simple http client for request OAuth2 tokens and several utils.
module Network.OAuth2.HTTP.HttpClient where
import Control.Applicative ((<$>))
import Control.Exception
import Control.Monad.Trans (liftIO)
import Control.Monad (liftM)
import Data.Aeson
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Network.HTTP.Conduit
import Network.HTTP.Types (renderSimpleQuery)
import qualified Network.HTTP.Types as HT
import Network.OAuth2.OAuth2
--------------------------------------------------
-- | Request (via POST method) "Access Token".
--
-- FIXME: what if @requestAccessToken'@ return error?
--
requestAccessToken :: OAuth2 -- ^ OAuth Data
-> BS.ByteString -- ^ Authentication code gained after authorization
-> IO (Maybe AccessToken) -- ^ Access Token
requestAccessToken oa code = decode <$> doSimplePostRequest (accessTokenUrl oa code)
-- | Request the "Refresh Token".
--
refreshAccessToken :: OAuth2
-> BS.ByteString -- ^ refresh token gained after authorization
-> IO (Maybe AccessToken)
refreshAccessToken oa rtoken = decode <$> doSimplePostRequest (refreshAccessTokenUrl oa rtoken)
--------------------------------------------------
-- | Conduct post request.
--
doSimplePostRequest :: (URI, PostBody) -- ^ The URI and request body for fetching token.
-> IO BSL.ByteString -- ^ Response as ByteString
doSimplePostRequest (uri, body) = doPostRequst (bsToS uri) body >>= handleResponse
-- | Conduct post request and return response as JSON.
--
doJSONPostRequest :: FromJSON a
=> (URI, PostBody) -- ^ The URI and request body for fetching token.
-> IO (Maybe a) -- ^ Response as ByteString
doJSONPostRequest (uri, body) = doPostRequst (bsToS uri) body
>>= liftM decode . handleResponse
-- | Conduct GET request.
--
doSimpleGetRequest :: String -- ^ URL
-> IO (Response BSL.ByteString) -- ^ Response as ByteString
doSimpleGetRequest url = liftIO $ withManager $ \man -> do
req' <- liftIO $ parseUrl url
httpLbs req' man
-- | Conduct GET request and return response as JSON.
--
doJSONGetRequest :: FromJSON a
=> String -- ^ Full URL
-> IO (Maybe a) -- ^ Response as ByteString
doJSONGetRequest url = doGetRequest url []
>>= liftM decode . handleResponse
--liftIO $ withManager $ \man -> do
-- req' <- liftIO $ parseUrl url
-- httpLbs req' man
--------------------------------------------------
-- conduit http request
--------------------------------------------------
-- | Conduct GET request with given URL by append extra parameters provided.
--
doGetRequest :: String -- ^ URL
-> [(BS.ByteString, BS.ByteString)] -- ^ Extra Parameters
-> IO (Response BSL.ByteString) -- ^ Response
doGetRequest url pm = liftIO $ withManager $ \man -> do
req' <- parseUrl $ url ++ bsToS (renderSimpleQuery True pm)
httpLbs req' man
-- | Conduct POST request with given URL with post body data.
--
doPostRequst :: String -- ^ URL
-> [(BS.ByteString, BS.ByteString)] -- ^ Data to Post Body
-> IO (Response BSL.ByteString) -- ^ Response
doPostRequst url body = liftIO $ withManager $ \man -> do
req' <- parseUrl url
httpLbs (urlEncodedBody body req') man
--------------------------------------------------
handleResponse :: Response BSL.ByteString -> IO BSL.ByteString
handleResponse rsp = if (HT.statusCode . responseStatus) rsp == 200
then return (responseBody rsp)
else throwIO . OAuthException $
"Gaining token failed: " ++ BSL.unpack (responseBody rsp)
bsToS :: BS.ByteString -> String
bsToS = T.unpack . T.decodeUtf8
--else BSL.putStrLn "Error rsp" >> return "ERROR"
-- TODO: Control.Exception.try
-- result <- liftIO $ Control.Exception.try $ runResourceT $ httpLbs request man