on master help sign in
Handle the expect header (#40)
commit60c2fb6fe1c572e608cccaa24e60a70790d2a25b authorMichael Snoyman <michael@snoyman.com> dateWed 1 Feb 2012, 20:23 (15 years ago) parent1a0457a
1 file changed+25−8
warp/Network/Wai/Handler/Warp.hs+25−8
warp/Network/Wai/Handler/Warp.hs+25−8
@@ -280,7 +280,7 @@ serveConnection settings th onException port app conn remoteHost' =
280280 serveConnection'' fromClient
281281
282282 serveConnection'' fromClient = do
283− env <- parseRequest port remoteHost' fromClient
283+ env <- parseRequest conn port remoteHost' fromClient
284284 case settingsIntercept settings env of
285285 Nothing -> do
286286 -- Let the application run for as long as it wants
@@ -297,12 +297,12 @@ serveConnection settings th onException port app conn remoteHost' =
297297 liftIO $ T.pause th
298298 intercept fromClient conn
299299
300−parseRequest :: Port -> SockAddr
300+parseRequest :: Connection -> Port -> SockAddr
301301 -> C.BufferedSource IO S.ByteString
302302 -> ResourceT IO Request
303−parseRequest port remoteHost' src = do
303+parseRequest conn port remoteHost' src = do
304304 headers' <- src C.$$ takeHeaders
305− parseRequest' port headers' remoteHost' src
305+ parseRequest' conn port headers' remoteHost' src
306306
307307-- FIXME come up with good values here
308308bytesPerRead, maxTotalHeaderLength :: Int
@@ -318,20 +318,37 @@ data InvalidRequest =
318318 deriving (Show, Typeable, Eq)
319319instance Exception InvalidRequest
320320
321+handleExpect :: Connection
322+ -> H.HttpVersion
323+ -> ([H.Header] -> [H.Header])
324+ -> [H.Header]
325+ -> IO [H.Header]
326+handleExpect _ _ front [] = return $ front []
327+handleExpect conn hv front (("expect", "100-continue"):rest) = do
328+ connSendAll conn $
329+ if hv == H.http11
330+ then "HTTP/1.1 100 Continue\r\n\r\n"
331+ else "HTTP/1.0 100 Continue\r\n\r\n"
332+ return $ front rest
333+handleExpect conn hv front (x:xs) = handleExpect conn hv (front . (x:)) xs
334+
321335-- | Parse a set of header lines and body into a 'Request'.
322−parseRequest' :: Port
336+parseRequest' :: Connection
337+ -> Port
323338 -> [ByteString]
324339 -> SockAddr
325340 -> C.BufferedSource IO S.ByteString
326341 -> ResourceT IO Request
327−parseRequest' _ [] _ _ = throwIO $ NotEnoughLines []
328−parseRequest' port (firstLine:otherLines) remoteHost' src = do
342+parseRequest' _ _ [] _ _ = throwIO $ NotEnoughLines []
343+parseRequest' conn port (firstLine:otherLines) remoteHost' src = do
329344 (method, rpath', gets, httpversion) <- parseFirst firstLine
330345 let (host',rpath)
331346 | S.null rpath' = ("", "/")
332347 | "http://" `S.isPrefixOf` rpath' = S.breakByte 47 $ S.drop 7 rpath'
333348 | otherwise = ("", rpath')
334− let heads = map parseHeaderNoAttr otherLines
349+ heads <- liftIO
350+ $ handleExpect conn httpversion id
351+ (map parseHeaderNoAttr otherLines)
335352 let host = fromMaybe host' $ lookup "host" heads
336353 let len0 =
337354 case lookup "content-length" heads of