- preprocessHeader req
- where
- setStatus :: StatusCode -> STM ()
- setStatus !status
- = updateItr itr itrResponse
- $! \ res -> res {
- resStatus = status
- }
-
- completeAuthority :: Request -> STM ()
- completeAuthority !req
- = when (uriAuthority (reqURI req) == Nothing)
- $ if reqVersion req == HttpVersion 1 0 then
- -- HTTP/1.0 なので Config から補完
- do let conf = itrConfig itr
- host = cnfServerHost conf
- port = itrLocalPort itr
- portStr
- = case port of
- 80 -> ""
- n -> ':' : show n
- updateAuthority host (C8.pack portStr)
- else
- case getHeader (C8.pack "Host") req of
- Just str -> let (host, portStr) = parseHost str
- in updateAuthority host portStr
- Nothing -> setStatus BadRequest
-
-
- parseHost :: Strict.ByteString -> (Strict.ByteString, Strict.ByteString)
- parseHost = C8.break (== ':')
-
-
- updateAuthority :: Strict.ByteString -> Strict.ByteString -> STM ()
- updateAuthority !host !portStr
- = updateItr itr itrRequest
- $! \ (Just req) -> Just req {
- reqURI = let uri = reqURI req
- in uri {
- uriAuthority = Just URIAuth {
- uriUserInfo = ""
- , uriRegName = C8.unpack host
- , uriPort = C8.unpack portStr
- }
- }
- }
-
-
- preprocessHeader :: Request -> STM ()
- preprocessHeader !req
- = do case getHeader (C8.pack "Expect") req of
- Nothing -> return ()
- Just value -> if value `noCaseEq` C8.pack "100-continue" then
- writeItr itr itrExpectedContinue True
- else
- setStatus ExpectationFailed
-
- case getHeader (C8.pack "Transfer-Encoding") req of
- Nothing -> return ()
- Just value -> unless (value `noCaseEq` C8.pack "identity")
- $ if value `noCaseEq` C8.pack "chunked" then
- writeItr itr itrRequestIsChunked True
- else
- setStatus NotImplemented
-
- case getHeader (C8.pack "Content-Length") req of
- Nothing -> return ()
- Just value -> if C8.all isDigit value then
- do let Just (len, _) = C8.readInt value
- writeItr itr itrReqChunkLength $ Just len
- writeItr itr itrReqChunkRemaining $ Just len
- else
- setStatus BadRequest
-
- case getHeader (C8.pack "Connection") req of
- Nothing -> return ()
- Just value -> when (value `noCaseEq` C8.pack "close")
- $ writeItr itr itrWillClose True
+ preprocessHeader itr req
+
+setStatus ∷ Interaction → StatusCode → STM ()
+setStatus (Interaction {..}) sc
+ = do res ← readTVar itrResponse
+ let res' = res {
+ resStatus = sc
+ }
+ writeTVar itrResponse res'
+
+completeAuthority ∷ Interaction → Request → STM ()
+completeAuthority itr@(Interaction {..}) req
+ = when (isNothing $ uriAuthority $ reqURI req)
+ $ if reqVersion req == HttpVersion 1 0 then
+ -- HTTP/1.0 なので Config から補完
+ do let host = cnfServerHost itrConfig
+ portStr = case itrLocalPort of
+ 80 → ""
+ n → ':' : show n
+ updateAuthority host $ A.unsafeFromString portStr
+ else
+ case getHeader "Host" req of
+ Just str → let (host, portStr) = parseHost str
+ in
+ updateAuthority host portStr
+ Nothing → setStatus itr BadRequest
+
+parseHost ∷ Ascii → (Text, Ascii)
+parseHost = C8.break (≡ ':')
+
+updateAuthority ∷ Text → Ascii → STM ()
+updateAuthority host portStr
+ = do Just req ← readTVar itrRequest
+ let uri = reqURI req
+ uri' = uri {
+ uriAuthority = Just URIAuth {
+ uriUserInfo = ""
+ , uriRegName = T.unpack host
+ , uriPort = A.toString portStr
+ }
+ }
+ req' = req { reqURI = uri' }
+ writeTVar itrRequest $ Just req'
+
+preprocessHeader ∷ Interaction → Request → STM ()
+preprocessHeader (Interaction {..}) req
+ = do case getCIHeader "Expect" req of
+ Nothing → return ()
+ Just value → if value ≡ "100-continue" then
+ writeTVar itrExpectedContinue True
+ else
+ setStatus ExpectationFailed
+
+ case getCIHeader "Transfer-Encoding" req of
+ Nothing → return ()
+ Just value → unless (value ≡ "identity")
+ $ if value ≡ "chunked" then
+ writeTVar itrRequestIsChunked True
+ else
+ setStatus NotImplemented
+
+ case getHeader "Content-Length" req of
+ Nothing → return ()
+ Just value → if C8.all isDigit value then
+ do let Just (len, _) = C8.readInt value
+ writeTVar itrReqChunkLength $ Just len
+ writeTVar itrReqChunkRemaining $ Just len
+ else
+ setStatus BadRequest
+
+ case getCIHeader "Connection" req of
+ Nothing → return ()
+ Just value → when (value ≡ "close")
+ $ writeTVar itrWillClose True