+getMethod :: Resource Method
+getMethod = do itr <- ask
+ return $ reqMethod $ fromJust $ itrRequest itr
+
+
+getHeader :: String -> Resource (Maybe String)
+getHeader name = do itr <- ask
+ return $ H.getHeader name $ fromJust $ itrRequest itr
+
+
+{- ExaminingRequest 時に使用するアクション群 -}
+
+foundEntity :: Bool -> String -> ClockTime -> Resource ()
+foundEntity isWeak token timeStamp
+ = do driftTo ExaminingRequest
+
+ method <- getMethod
+ when (method == GET || method == HEAD)
+ $ setHeader' "Last-Modified" $ formatHTTPDateTime timeStamp
+ foundETag isWeak token
+
+ driftTo GettingBody
+
+
+foundETag :: Bool -> String -> Resource ()
+foundETag isWeak token
+ = do driftTo ExaminingRequest
+
+ let tag = mkETag isWeak token
+
+ method <- getMethod
+ when (method == GET || method == HEAD)
+ $ setHeader' "ETag" $ show tag
+
+ -- If-Match があればそれを見る。
+ ifMatch <- getHeader "If-Match"
+ case ifMatch of
+ Nothing -> return ()
+ Just "*" -> return ()
+ Just list -> case parseStr eTagListP list of
+ (Success tags, _)
+ -- tags の中に一致するものが無ければ
+ -- PreconditionFailed で終了。
+ -> when (not $ any (== tag) tags)
+ $ abort PreconditionFailed [] ("The entity tag doesn't match: " ++ list)
+ _ -> abort BadRequest [] ("Unparsable If-Match: " ++ fromJust ifMatch)
+
+ let statusForNoneMatch = if method == GET || method == HEAD then
+ NotModified
+ else
+ PreconditionFailed
+
+ -- If-None-Match があればそれを見る。
+ ifNoneMatch <- getHeader "If-None-Match"
+ case ifNoneMatch of
+ Nothing -> return ()
+ Just "*" -> abort statusForNoneMatch [] ("The entity tag matches: *")
+ Just list -> case parseStr eTagListP list of
+ (Success tags, _)
+ -> when (any (== tag) tags)
+ $ abort statusForNoneMatch [] ("The entity tag matches: " ++ list)
+ _ -> abort BadRequest [] ("Unparsable If-None-Match: " ++ list)
+
+ driftTo GettingBody
+
+
+foundTimeStamp :: ClockTime -> Resource ()
+foundTimeStamp timeStamp
+ = do driftTo ExaminingRequest
+
+ method <- getMethod
+ when (method == GET || method == HEAD)
+ $ setHeader' "Last-Modified" $ formatHTTPDateTime timeStamp
+
+ let statusForIfModSince = if method == GET || method == HEAD then
+ NotModified
+ else
+ PreconditionFailed
+
+ -- If-Modified-Since があればそれを見る。
+ ifModSince <- getHeader "If-Modified-Since"
+ case ifModSince of
+ Just str -> case parseHTTPDateTime str of
+ Just lastTime
+ -> when (timeStamp <= lastTime)
+ $ abort statusForIfModSince [] ("The entity has not been modified since " ++ str)
+ Nothing
+ -> return () -- 不正な時刻は無視
+ Nothing -> return ()
+
+ -- If-Unmodified-Since があればそれを見る。
+ ifUnmodSince <- getHeader "If-Unmodified-Since"
+ case ifUnmodSince of
+ Just str -> case parseHTTPDateTime str of
+ Just lastTime
+ -> when (timeStamp > lastTime)
+ $ abort PreconditionFailed [] ("The entity has not been modified since " ++ str)
+ Nothing
+ -> return () -- 不正な時刻は無視
+ Nothing -> return ()
+
+ driftTo GettingBody
+
+
+foundNoEntity :: Maybe String -> Resource ()
+foundNoEntity msgM
+ = do driftTo ExaminingRequest
+
+ let msg = fromMaybe "The requested entity was not found in this server." msgM
+
+ method <- getMethod
+ when (method /= PUT)
+ $ abort NotFound [] msg
+
+ -- エンティティが存在しないと云ふ事は、"*" も含めたどのやうな
+ -- If-Match: 條件も滿たさない。
+ ifMatch <- getHeader "If-Match"
+ when (ifMatch /= Nothing)
+ $ abort PreconditionFailed [] msg
+
+ driftTo GettingBody
+
+
+{- GettingBody 時に使用するアクション群 -}