Last active
February 19, 2021 06:29
-
-
Save pt2121/ba50236ba83d93b61a80f04e5878fe81 to your computer and use it in GitHub Desktop.
idris 2 http client https://idris2.readthedocs.io/en/latest/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module HttpClient | |
import Control.App | |
import Network.Socket | |
import Types | |
public export | |
interface Has [Exception IOError] e => NetworkIO e where | |
getResponse : Request -> App e String | |
public export | |
requestLine : (req : Request) -> String | |
requestLine req = | |
show req.method ++ " " ++ req.path ++ " " ++ show req.httpVersion ++ "\r\n" | |
public export | |
headers : (req : Request) -> String | |
headers req = "Host: " ++ req.host ++ "\r\nConnection: close\r\n" | |
export | |
Has [PrimIO, Exception IOError] e => NetworkIO e where | |
getResponse r = do | |
Right socket <- primIO $ socket AF_INET Stream 0 | |
| Left fail => throw $ GenericErr $ show fail | |
res <- primIO $ connect socket (Hostname r.host) r.port | |
if res /= 0 | |
then throw $ GenericErr $ "res " ++ show res | |
else do | |
Right _ <- primIO $ send socket $ requestLine r ++ headers r ++ "\r\n" | |
| Left fail => throw $ GenericErr $ show fail | |
Right result <- primIO $ recvAll socket | |
| Left fail => throw $ GenericErr "" | |
pure result | |
public export | |
request : NetworkIO e => Request -> App e String | |
request r = getResponse r |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main | |
import Control.App | |
import Control.App.Console | |
import HttpClient | |
import Types | |
reqMain : App Init () | |
reqMain = handle (request (MkRequest GET False http1_1 "www.neverssl.com" 80 "/" "")) | |
(\str => putStrLn $ "Response:\n" ++ show str) | |
(\err : IOError => putStrLn $ "Error: " ++ show err) | |
main : IO () | |
main = run reqMain |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Types | |
import Data.Strings | |
import Network.Socket | |
public export | |
data Method = GET | POST | |
export | |
Show Method where | |
show GET = "GET" | |
show POST = "POST" | |
export | |
Eq Method where | |
m1 == m2 = show m1 == show m2 | |
public export | |
record HttpVersion where | |
constructor MkHttpVersion | |
major : Int | |
minor : Int | |
export | |
Show HttpVersion where | |
show v = "HTTP/" ++ show v.major ++ "." ++ show v.minor | |
export | |
http1_0 : HttpVersion | |
http1_0 = MkHttpVersion 1 0 | |
export | |
http1_1 : HttpVersion | |
http1_1 = MkHttpVersion 1 1 | |
export | |
http2_0 : HttpVersion | |
http2_0 = MkHttpVersion 2 0 | |
public export | |
record Request where | |
constructor MkRequest | |
method : Method | |
secure : Bool | |
httpVersion : HttpVersion | |
host : String | |
port : Int | |
path : String | |
queryString : String | |
export | |
Show Request where | |
show r = unlines | |
[ "Request {" | |
, " method = " ++ show r.method | |
, " secure = " ++ show r.secure | |
, " httpVersion = " ++ show r.httpVersion | |
, " host = " ++ r.host | |
, " port = " ++ show r.port | |
, " path = " ++ r.path | |
, " queryString = " ++ r.queryString | |
, "}" | |
] | |
public export | |
record Status where | |
constructor MkStatus | |
statusCode : Int | |
statusMessage : String | |
export | |
Show Status where | |
show s = "Status { " ++ show s.statusCode ++ ", " ++ s.statusMessage ++ " }" | |
public export | |
record Response responseBody where | |
constructor MkResponse | |
status : Status | |
version : HttpVersion | |
body : responseBody | |
export | |
printResponse : (Response responseBody) | |
-> (responseBody -> String) | |
-> String | |
printResponse r f = unlines | |
[ "Response {" | |
, " status = " ++ show r.status | |
, " version = " ++ show r.version | |
, " responseBody = " ++ f r.body | |
, "}" | |
] | |
public export | |
data HttpError : Type where | |
HttpSocketError : SocketError -> HttpError | |
export | |
Show HttpError where | |
show (HttpSocketError err) = show err | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment