-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)
-