@@ -10,37 +10,38 @@ module Hyper.Node.Server
1010 ) where
1111
1212import Prelude
13- import Data.HTTP.Method as Method
14- import Data.Int as Int
15- import Data.StrMap as StrMap
16- import Node.Buffer as Buffer
17- import Node.HTTP as HTTP
18- import Node.Stream as Stream
13+
1914import Control.IxMonad (ipure , (:*>), (:>>=))
20- import Control.Monad.Aff (Aff , launchAff , makeAff , runAff )
21- import Control.Monad.Aff.AVar (putVar , takeVar , modifyVar , makeVar' , AVAR , makeVar )
15+ import Control.Monad.Aff (Aff , launchAff , launchAff_ , makeAff , nonCanceler , runAff_ )
16+ import Control.Monad.Aff.AVar (AVAR , makeEmptyVar , makeVar , putVar , takeVar )
2217import Control.Monad.Aff.Class (class MonadAff , liftAff )
2318import Control.Monad.Eff (Eff )
2419import Control.Monad.Eff.Class (class MonadEff , liftEff )
2520import Control.Monad.Eff.Exception (EXCEPTION , catchException , error )
2621import Control.Monad.Error.Class (throwError )
2722import Data.Either (Either (..), either )
23+ import Data.HTTP.Method as Method
24+ import Data.Int as Int
2825import Data.Lazy (defer )
2926import Data.Maybe (Maybe (..))
3027import Data.Newtype (unwrap )
28+ import Data.StrMap as StrMap
3129import Data.Tuple (Tuple (..))
3230import Hyper.Conn (Conn )
3331import Hyper.Middleware (Middleware , evalMiddleware , lift' )
3432import Hyper.Middleware.Class (getConn , modifyConn )
35- import Hyper.Node.Server.Options as Hyper.Node.Server.Options
3633import Hyper.Node.Server.Options (Options )
34+ import Hyper.Node.Server.Options as Hyper.Node.Server.Options
3735import Hyper.Request (class ReadableBody , class Request , class StreamableBody , RequestData , parseUrl , readBody )
3836import Hyper.Response (class ResponseWritable , class Response , ResponseEnded , StatusLineOpen )
3937import Hyper.Status (Status (..))
4038import Node.Buffer (BUFFER , Buffer )
39+ import Node.Buffer as Buffer
4140import Node.Encoding (Encoding (..))
4241import Node.HTTP (HTTP )
42+ import Node.HTTP as HTTP
4343import Node.Stream (Stream , Writable )
44+ import Node.Stream as Stream
4445
4546
4647data HttpRequest
@@ -62,15 +63,17 @@ newtype NodeResponse m e
6263writeString :: forall m e . MonadAff e m => Encoding -> String -> NodeResponse m e
6364writeString enc str = NodeResponse $ \w -> liftAff (makeAff (writeAsAff w))
6465 where
65- writeAsAff w fail succeed =
66- Stream .writeString w enc str (succeed unit) >>=
66+ writeAsAff w k = do
67+ Stream .writeString w enc str (k (pure unit) ) >>=
6768 if _
68- then succeed unit
69- else fail (error " Failed to write string to response" )
69+ then k (pure unit)
70+ else k (throwError (error " Failed to write string to response" ))
71+ pure nonCanceler
7072
7173write :: forall m e . MonadAff e m => Buffer -> NodeResponse m e
7274write buffer = NodeResponse $ \w ->
73- liftAff (makeAff (\fail succeed -> void $ Stream .write w buffer (succeed unit)))
75+ liftAff (makeAff (\k -> Stream .write w buffer (k (pure unit))
76+ *> pure nonCanceler))
7477
7578instance stringNodeResponse :: (MonadAff e m ) => ResponseWritable (NodeResponse m e ) m String where
7679 toResponse = ipure <<< writeString UTF8
@@ -92,8 +95,8 @@ readBodyAsBuffer
9295 -> Aff (http :: HTTP , avar :: AVAR , buffer :: BUFFER | e ) Buffer
9396readBodyAsBuffer (HttpRequest request _) = do
9497 let stream = HTTP .requestAsStream request
95- bodyResult <- makeVar
96- chunks <- makeVar' []
98+ bodyResult <- makeEmptyVar
99+ chunks <- makeVar []
97100 fillResult <- liftEff $
98101 catchException (pure <<< Left ) (Right <$> fillBody stream chunks bodyResult)
99102 -- Await the body, or an error.
@@ -104,16 +107,19 @@ readBodyAsBuffer (HttpRequest request _) = do
104107 fillBody stream chunks bodyResult = do
105108 -- Append all chunks to the body buffer.
106109 Stream .onData stream \chunk ->
107- void (launchAff (modifyVar (_ <> [chunk]) chunks))
110+ let modification = do
111+ v <- takeVar chunks
112+ putVar (v <> [chunk]) chunks
113+ in void (launchAff modification)
108114 -- Complete with `Left` on error.
109115 Stream .onError stream $
110- void <<< launchAff <<< putVar bodyResult <<< Left
116+ launchAff_ <<< flip putVar bodyResult <<< Left
111117 -- Complete with `Right` on successful "end" event.
112118 Stream .onEnd stream $ void $ launchAff $
113119 takeVar chunks
114120 >>= concat'
115121 >>= (pure <<< Right )
116- >>= putVar bodyResult
122+ >>= flip putVar bodyResult
117123 concat' = liftEff <<< Buffer .concat
118124
119125instance readableBodyHttpRequestString :: (Monad m , MonadAff (http :: HTTP , avar :: AVAR , buffer :: BUFFER | e ) m )
@@ -250,7 +256,14 @@ runServer' options components runM middleware = do
250256 , response : HttpResponse response
251257 , components : components
252258 }
253- in conn # evalMiddleware middleware # runM # runAff options .onRequestError (const $ pure unit ) # void
259+ callback =
260+ case _ of
261+ Left err -> options .onRequestError err
262+ Right _ -> pure unit
263+ in conn
264+ # evalMiddleware middleware
265+ # runM
266+ # runAff_ callback
254267
255268runServer
256269 :: forall e c c' .
0 commit comments