]> gitweb @ CieloNegro.org - Lucu.git/blobdiff - Network/HTTP/Lucu/Resource.hs
Fixed many bugs...
[Lucu.git] / Network / HTTP / Lucu / Resource.hs
index c75421378c89dd1c5eb6b25b5fea31cf354ce5a5..d0454c4c630d047a419f335a37ecfeb1c64211cb 100644 (file)
@@ -137,7 +137,6 @@ module Network.HTTP.Lucu.Resource
     , driftTo -- private
     )
     where
-import Blaze.ByteString.Builder (Builder)
 import qualified Blaze.ByteString.Builder.ByteString as BB
 import Control.Applicative
 import Control.Concurrent.STM
@@ -154,7 +153,6 @@ import Data.Foldable (toList)
 import Data.List
 import qualified Data.Map as M
 import Data.Maybe
-import Data.Monoid
 import Data.Monoid.Unicode
 import Data.Sequence (Seq)
 import Data.Text (Text)
@@ -166,7 +164,6 @@ import Network.HTTP.Lucu.Abortion
 import Network.HTTP.Lucu.Authorization
 import Network.HTTP.Lucu.Config
 import Network.HTTP.Lucu.ContentCoding
-import Network.HTTP.Lucu.DefaultPage
 import Network.HTTP.Lucu.ETag
 import qualified Network.HTTP.Lucu.Headers as H
 import Network.HTTP.Lucu.HttpVersion
@@ -607,7 +604,7 @@ input ∷ Int → Resource Lazy.ByteString
 input limit
     = do driftTo GettingBody
          itr     ← getInteraction
-         chunk   ← if reqHasBody $ fromJust $ itrRequest itr then
+         chunk   ← if reqMustHaveBody $ fromJust $ itrRequest itr then
                        askForInput itr
                    else
                        do driftTo DecidingHeader
@@ -675,7 +672,7 @@ inputChunk ∷ Int → Resource Lazy.ByteString
 inputChunk limit
     = do driftTo GettingBody
          itr     ← getInteraction
-         chunk   ← if reqHasBody $ fromJust $ itrRequest itr then
+         chunk   ← if reqMustHaveBody $ fromJust $ itrRequest itr then
                        askForInput itr
                    else
                        do driftTo DecidingHeader
@@ -815,6 +812,8 @@ setHeader' name value
                 $ do res ← readTVar $ itrResponse itr
                      let res' = H.setHeader name value res
                      writeTVar (itrResponse itr) res'
+                     when (name ≡ "Content-Type")
+                         $ writeTVar (itrResponseHasCType itr) True
 
 -- | Computation of @'redirect' code uri@ sets the response status to
 -- @code@ and \"Location\" header to @uri@. The @code@ must satisfy
@@ -834,8 +833,8 @@ redirect code uri
 -- | Computation of @'setContentType' mType@ sets the response header
 -- \"Content-Type\" to @mType@.
 setContentType ∷ MIMEType → Resource ()
-setContentType
-    = setHeader "Content-Type" ∘ A.fromAsciiBuilder ∘ printMIMEType
+{-# INLINE setContentType #-}
+setContentType = setHeader "Content-Type" ∘ A.fromAsciiBuilder ∘ printMIMEType
 
 -- | Computation of @'setLocation' uri@ sets the response header
 -- \"Location\" to @uri@.
@@ -875,6 +874,9 @@ setWWWAuthenticate challenge
 -- | Write a 'Lazy.ByteString' to the response body, and then transit
 -- to the /Done/ state. It is safe to apply 'output' to an infinite
 -- string, such as the lazy stream of \/dev\/random.
+--
+-- Note that you must first set the \"Content-Type\" response header
+-- before applying this function. See: 'setContentType'
 output ∷ Lazy.ByteString → Resource ()
 {-# INLINE output #-}
 output str = outputChunk str *> driftTo Done
@@ -882,33 +884,19 @@ output str = outputChunk str *> driftTo Done
 -- | Write a 'Lazy.ByteString' to the response body. This action can
 -- be repeated as many times as you want. It is safe to apply
 -- 'outputChunk' to an infinite string.
+--
+-- Note that you must first set the \"Content-Type\" response header
+-- before applying this function. See: 'setContentType'
 outputChunk ∷ Lazy.ByteString → Resource ()
 outputChunk str
     = do driftTo DecidingBody
          itr ← getInteraction
          liftIO $ atomically
-                $ do putTMVar (itrBodyToSend itr) (BB.fromLazyByteString str)
-                     unless (Lazy.null str)
-                         $ writeTVar (itrSentNoBodySoFar itr) False
-
-{-
-
-  [GettingBody からそれ以降の状態に遷移する時]
-  
-  body を讀み終へてゐなければ、殘りの body を讀み捨てる。
-
-
-  [DecidingHeader からそれ以降の状態に遷移する時]
-
-  postprocess する。
-
-
-  [Done に遷移する時]
-
-  bodyIsNull が False ならば何もしない。True だった場合は出力補完す
-  る。
-
--}
+                $ do hasCType ← readTVar $ itrResponseHasCType itr
+                     unless hasCType
+                         $ abortSTM InternalServerError []
+                         $ Just "outputChunk: Content-Type has not been set."
+                     putTMVar (itrBodyToSend itr) (BB.fromLazyByteString str)
 
 driftTo ∷ InteractionState → Resource ()
 driftTo newState
@@ -926,7 +914,7 @@ driftTo newState
     where
       throwStateError ∷ Monad m ⇒ InteractionState → InteractionState → m a
       throwStateError Done DecidingBody
-          = fail "It makes no sense to output something after finishing to output."
+          = fail "It makes no sense to output something after finishing outputs."
       throwStateError old new
           = fail ("state error: " ⧺ show old ⧺ " ==> " ⧺ show new)
 
@@ -935,9 +923,5 @@ driftTo newState
           = writeTVar itrReqBodyWasteAll True
       drift itr DecidingHeader _
           = postprocess itr
-      drift itr@(Interaction {..}) _ Done
-          = do bodyIsNull ← readTVar itrSentNoBodySoFar
-               when bodyIsNull
-                   $ writeDefaultPage itr
       drift _ _ _
           = return ()