from Data.Func import $, mapSt
from Text import class Text(..), instance Text String, instance + String
+import Internet.HTTP
+
import Text.JSON
import Text.URI
TIMEOUT :== Just 10000
SERVER :== "irc.freenode.net"
-doRequest :: HTTPRequest *World -> *(MaybeErrorString HTTPResponse, *World)
-doRequest req w
-# (ip,w) = lookupIPAddress server_name w
-| isNothing ip
- = (Error $ "DNS lookup for " + server_name + " failed.", w)
-# (Just ip) = ip
-# (rpt,chan,w) = connectTCP_MT TIMEOUT (ip, req.server_port) w
-| rpt == TR_Expired
- = (Error $ "Connection to " + toString ip + " timed out.", w)
-| rpt == TR_NoSuccess
- = (Error $ "Could not connect to " + server_name + ".", w)
-# (Just {sChannel,rChannel}) = chan
-# (rpt,i,sChannel,w) = send_MT TIMEOUT (toByteSeq req) sChannel w
-| rpt <> TR_Success
- = (Error $ "Could not send request to " + server_name + ".", w)
-# (rpt,resp,rChannel,w) = receive_MT TIMEOUT rChannel w
-| rpt <> TR_Success
- = (Error $ "Did not receive a reply from " + server_name + ".", w)
-# resp = 'CM'.join $ parseResponse <$> toString <$> resp
-| isNothing resp
- # w = closeChannel sChannel (closeRChannel rChannel w)
- = (Error $ "Server did not respond with HTTP.", w)
-# (resp,rChannel,w) = receiveRest (fromJust resp) rChannel w
-# w = closeChannel sChannel (closeRChannel rChannel w)
-= (resp,w)
-where
- server_name = req.server_name
- receiveRest resp chan w
- # cl = lookup "Content-Length" resp.HTTPResponse.rsp_headers
- | isNothing cl
- = (Ok resp, chan, w)
- | size resp.rsp_data >= toInt (fromJust cl)
- = (Ok resp, chan, w)
- # (rpt,newresp,chan,w) = receive_MT TIMEOUT chan w
- | rpt <> TR_Success
- = (Error $ server_name + " hung up during transmission.", chan, w)
- = receiveRest {resp & rsp_data=resp.rsp_data + toString (fromJust newresp)} chan w
-
-import StdMisc
-import StdDebug
-
-doRequestL :: HTTPRequest Int *World -> *(MaybeErrorString HTTPResponse, *World)
-doRequestL req 0 w = (Error "Maximal redirect number exceeded", w)
-doRequestL req maxRedirects w
-| not (trace_tn $ toString req) = undef
-# (er, w) = doRequest req w
-| isError er = (er, w)
-# resp = fromOk er
-| isMember resp.HTTPResponse.rsp_code [301, 302, 303, 307, 308]
- = case lookup "Location" resp.HTTPResponse.rsp_headers of
- Nothing = (Error $ "Redirect given but no Location header", w)
- Just loc = case parseURI loc of
- Nothing = (Error $ "Redirect URI couldn't be parsed", w)
- Just uri = doRequestL {req
- & server_name = maybe loc id uri.uriRegName
- , server_port = maybe 80 id uri.uriPort
- , req_path = uri.uriPath
- , req_query = maybe "" ((+++) "?") uri.uriQuery
- } (maxRedirects-1) w
-= (er, w)
-
shorten :: String *World -> (String, *World)
shorten s w
# s = if (startsWith "http://" s) s (if (startsWith "https://" s) s ("http://" + s))
# data = "type=regular&url="+urlEncode s+"&token=a"
-# (mer, w) = doRequest
+# (mer, w) = doHTTPRequest
{ newHTTPRequest
& req_method = HTTP_POST
, req_path = "/"
[("Content-Type", "application/x-www-form-urlencoded")
,("Content-Length", toString $ size data)
,("Accept", "*/*")]
- , req_data = data} w
+ , req_data = data} 10000 w
| isError mer = ("request failed: " + fromError mer, w)
# resp = fromOk mer
= (resp.rsp_data, w)
cloogle :: String *World -> (String, *World)
cloogle data w
-# (mer, w) = doRequestL
+# (mer, w) = doHTTPRequestL
{ newHTTPRequest
& req_path = "/api.php"
, req_query = "?str=" + urlEncode data
, req_headers = 'DM'.fromList [("User-Agent", "cloogle-irc")]
, server_name = "cloogle.org"
- , server_port = 80} 10 w
+ , server_port = 80} 10000 10 w
| isError mer = ("request failed: " + fromError mer, w)
# resp = fromOk mer
= case fromJSON $ fromString resp.HTTPResponse.rsp_data of