aip-0.1.1: src/Data/Aviation/Aip/HttpRequest.hs
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Aviation.Aip.HttpRequest(
aipRequestGet
, aipRequestPost
, aipRequestMethod
, doRequest
, doRequest'
, doGetRequest
, doPostRequest
, requestAipContents
, downloadHref
) where
import Control.Category((.))
import Control.Applicative(pure)
import Control.Lens
import Control.Monad.IO.Class(liftIO)
import Network.HTTP(HandleStream, getAuth, openStream, host, normalizeRequest, defaultNormalizeRequestOptions, close)
import qualified Data.ByteString.Lazy as LazyByteString(writeFile)
import Control.Monad.Trans.Except(ExceptT(ExceptT))
import Data.Aviation.Aip.AipCon(AipCon(AipCon))
import Data.Aviation.Aip.AipContents
import Data.Aviation.Aip.Log(aiplog)
import Data.Aviation.Aip.ConnErrorHttp4xx(ConnErrorHttp4xx(IsConnError, Http4xx))
import Data.Aviation.Aip.Href(Href(Href), windows_replace)
import Data.Aviation.Aip.PerHref(PerHref(PerHref))
import Data.Bool(Bool(True), bool)
import Data.Either(Either(Left, Right))
import Data.Eq(Eq((==)))
import Data.Function(($))
import Data.Functor((<$>))
import Data.List(isPrefixOf, dropWhile)
import Data.Maybe(Maybe(Just))
import Data.Semigroup(Semigroup((<>)))
import Data.String(String)
import Network.HTTP(HStream, Request, RequestMethod(GET, POST), mkRequest, setRequestBody, simpleHTTP, simpleHTTP_, rspCode, rspBody)
import Network.BufferType(BufferType)
import Network.URI(URI(URI), URIAuth(URIAuth))
import Prelude(Show(show))
import System.Directory(createDirectoryIfMissing)
import System.FilePath(FilePath, splitFileName, isPathSeparator, (</>))
aipRequestGet ::
BufferType ty =>
Href
-> String
-> Request ty
aipRequestGet =
aipRequestMethod GET
aipRequestPost ::
BufferType ty =>
Href
-> String
-> Request ty
aipRequestPost =
aipRequestMethod POST
aipRequestMethod ::
BufferType ty =>
RequestMethod
-> Href
-> String
-> Request ty
aipRequestMethod m (Href s) z =
let s' = bool ("/aip/" <> s) s ("/aip/" `isPrefixOf` s)
in mkRequest m (URI "http:" (Just (URIAuth "" "www.airservicesaustralia.com" "")) s' z "")
doRequest ::
HStream a =>
Request a
-> AipCon a
doRequest r =
AipCon . pure .
ExceptT $
do x <- simpleHTTP r
pure $
case x of
Left e ->
Left (IsConnError e)
Right c ->
let (r1, r2, r3) = rspCode c
in if r1 == 4 then
Left (Http4xx r2 r3)
else
Right (rspBody c)
doRequest' ::
HStream a =>
Request a
-> HandleStream a
-> AipCon a
doRequest' r h =
AipCon . pure .
ExceptT $
do x <- simpleHTTP_ h r
pure $
case x of
Left e ->
Left (IsConnError e)
Right c ->
let (r1, r2, r3) = rspCode c
in if r1 == 4 then
Left (Http4xx r2 r3)
else
Right (rspBody c)
doGetRequest ::
HStream a =>
Href
-> String
-> AipCon a
doGetRequest s z =
doRequest (aipRequestGet s z)
doPostRequest ::
HStream a =>
Href
-> String
-> AipCon a
doPostRequest s z =
doRequest (aipRequestPost s z)
requestAipContents ::
AipCon AipContents
requestAipContents =
let path = "aip.asp"
query = "?pg=10"
r = setRequestBody
(aipRequestPost (Href path) query)
("application/x-www-form-urlencoded", "Submit=I+Agree&check=1")
in AipContents path query <$> doRequest r
downloadHref ::
PerHref AipCon FilePath
downloadHref =
PerHref $ \hf _ d' _ ->
do let q = aipRequestGet hf ""
aiplog ("making request for aip document " <> show q)
auth <- getAuth q
aiplog ("making request for aip document with auth " <> show auth)
c <- liftIO $ openStream (host auth) 80
r <- doRequest' (normalizeRequest defaultNormalizeRequestOptions q) c
let (j, k) = splitFileName (hf ^. _Wrapped)
let ot = d' </> dropWhile isPathSeparator j
aiplog ("output directory for aip document " <> ot)
do liftIO $ createDirectoryIfMissing True ot
let otw = ot </> windows_replace k
aiplog ("writing aip document " <> otw)
liftIO $ LazyByteString.writeFile otw r
liftIO $ close c
pure otw