]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Resource.hs
Slightly improved something...
[Rakka.git] / Rakka / Resource.hs
index a69a2242215c2603ccd6f7c79826df8d21ed21b7..adbd706d6e9d07c6eb79a3f7bec776be9064b9d4 100644 (file)
@@ -1,5 +1,6 @@
 module Rakka.Resource
     ( runIdempotentA
+    , runXmlA
     , outputXmlPage
     )
     where
@@ -11,6 +12,9 @@ import           Control.Monad.Trans
 import           Network.HTTP.Lucu
 import           Network.HTTP.Lucu.Utils
 import           Network.URI hiding (path)
+import           Rakka.Environment
+import           Rakka.Validation
+import           Text.XML.HXT.Arrow.ReadDocument
 import           Text.XML.HXT.Arrow.WriteDocument
 import           Text.XML.HXT.Arrow.XmlIOStateArrow
 import           Text.XML.HXT.DOM.TypeDefs
@@ -52,6 +56,58 @@ runIdempotentA a
          rsrc
 
 
+runXmlA :: Environment -> FilePath -> IOSArrow XmlTree (Resource c) -> Resource c
+runXmlA env schemaPath a
+    = do inputA <- getInputXmlA env schemaPath
+         [rsrc] <- liftIO $ runX ( inputA
+                                   >>>
+                                   setErrorMsgHandler False fail
+                                   >>>
+                                   a
+                                 )
+         rsrc
+
+
+-- well-formed でない時は 400 Bad Request になり、valid でない時は 422
+-- Unprocessable Entity になる。入力の型が XML でない時は 415
+-- Unsupported Media Type を返す。
+getInputXmlA :: Environment -> FilePath -> Resource (IOSArrow b XmlTree)
+getInputXmlA env schemaPath
+    = do reader    <- getInputReader
+         validator <- getValidator env schemaPath
+         return ( setErrorMsgHandler False (abort BadRequest [] . Just)
+                  >>>
+                  reader
+                  >>>
+                  setErrorMsgHandler False (abort UnprocessableEntitiy [] . Just)
+                  >>>
+                  validator
+                )
+
+
+getInputReader :: Resource (IOSArrow b XmlTree)
+getInputReader 
+    = do mimeType <- getContentType
+         case mimeType of
+           Nothing
+               -> getFailingReader BadRequest [] (Just "Missing Content-Type")
+           Just (MIMEType "text" "xml" _)
+               -> getXmlReader
+           Just (MIMEType "application" "xml" _)
+               -> getXmlReader
+           Just t
+               -> getFailingReader UnsupportedMediaType [] (Just $ "Unsupported media type: " ++ show t)
+    where
+      getXmlReader
+          = do req <- input defaultLimit
+               return $ readString [ (a_validate         , v_0)
+                                   , (a_check_namespaces , v_1)
+                                   , (a_remove_whitespace, v_0)
+                                   ] req
+      getFailingReader code headers msg
+          = return $ proc _ -> abortA -< (code, (headers, msg))
+
+
 getEntityType :: Resource MIMEType
 getEntityType
     = do uri <- getRequestURI