@@ -38,7 +38,7 @@ import Network.Wai (Application, Request, Response,
3838 requestMethod, responseLBS,
3939 strictRequestBody)
4040import Servant.API ((:<|>) (..), (:>), Capture,
41− Canonicalize, Delete, Get, Header,
41+ Delete, Get, Header,
4242 MatrixFlag, MatrixParam, MatrixParams,
4343 Patch, Post, Put, QueryFlag,
4444 QueryParam, QueryParams, Raw,
@@ -46,9 +46,12 @@ import Servant.API ((:<|>) (..), (:>), Capture,
4646import Servant.API.ContentTypes (AcceptHeader (..),
4747 AllCTRender (..),
4848 AllCTUnrender (..))
49−import Servant.API.ResponseHeaders (Headers, getResponse, getHeaders)
49+import Servant.API.ResponseHeaders (Headers, getResponse, GetHeaders,
50+ getHeaders)
5051import Servant.Common.Text (FromText, fromText)
5152
53+import Servant.Server.Internal.ServantErr
54+
5255data ReqBodyState = Uncalled
5356 | Called !B.ByteString
5457 | Done !B.ByteString
@@ -174,13 +177,11 @@ processedPathInfo r =
174177 where pinfo = parsePathInfo r
175178
176179class HasServer layout where
177− type ServerT' layout (m :: * -> *) :: *
180+ type ServerT layout (m :: * -> *) :: *
178181
179− route :: Proxy layout -> Server' layout -> RoutingApplication
182+ route :: Proxy layout -> Server layout -> RoutingApplication
180183
181−type Server layout = Server' (Canonicalize layout)
182−type Server' layout = ServerT' layout (EitherT (Int, String) IO)
183−type ServerT layout m = ServerT' (Canonicalize layout) m
184+type Server layout = ServerT layout (EitherT ServantErr IO)
184185
185186-- * Instances
186187
@@ -197,7 +198,7 @@ type ServerT layout m = ServerT' (Canonicalize layout) m
197198-- > postBook book = ...
198199instance (HasServer a, HasServer b) => HasServer (a :<|> b) where
199200
200− type ServerT' (a :<|> b) m = ServerT' a m :<|> ServerT' b m
201+ type ServerT (a :<|> b) m = ServerT a m :<|> ServerT b m
201202
202203 route Proxy (a :<|> b) request respond =
203204 route pa a request $ \mResponse ->
@@ -231,8 +232,8 @@ captured _ = fromText
231232instance (KnownSymbol capture, FromText a, HasServer sublayout)
232233 => HasServer (Capture capture a :> sublayout) where
233234
234− type ServerT' (Capture capture a :> sublayout) m =
235− a -> ServerT' sublayout m
235+ type ServerT (Capture capture a :> sublayout) m =
236+ a -> ServerT sublayout m
236237
237238 route Proxy subserver request respond = case processedPathInfo request of
238239 (first : rest)
@@ -259,16 +260,14 @@ instance (KnownSymbol capture, FromText a, HasServer sublayout)
259260-- are not met.
260261instance HasServer Delete where
261262
262− type ServerT' Delete m = m ()
263+ type ServerT Delete m = m ()
263264
264265 route Proxy action request respond
265266 | pathIsEmpty request && requestMethod request == methodDelete = do
266267 e <- runEitherT action
267268 respond $ succeedWith $ case e of
268− Right () ->
269− responseLBS status204 [] ""
270− Left (status, message) ->
271− responseLBS (mkStatus status (cs message)) [] (cs message)
269+ Right () -> responseLBS status204 [] ""
270+ Left err -> responseServantErr err
272271 | pathIsEmpty request && requestMethod request /= methodDelete =
273272 respond $ failWith WrongMethod
274273 | otherwise = respond $ failWith NotFound
@@ -292,7 +291,7 @@ instance
292291#endif
293292 ( AllCTRender ctypes a ) => HasServer (Get ctypes a) where
294293
295− type ServerT' (Get ctypes a) m = m a
294+ type ServerT (Get ctypes a) m = m a
296295
297296 route Proxy action request respond
298297 | pathIsEmpty request && requestMethod request == methodGet = do
@@ -304,8 +303,7 @@ instance
304303 Nothing -> failWith UnsupportedMediaType
305304 Just (contentT, body) -> succeedWith $
306305 responseLBS ok200 [ ("Content-Type" , cs contentT)] body
307− Left (status, message) -> succeedWith $
308− responseLBS (mkStatus status (cs message)) [] (cs message)
306+ Left err -> succeedWith $ responseServantErr err
309307 | pathIsEmpty request && requestMethod request /= methodGet =
310308 respond $ failWith WrongMethod
311309 | otherwise = respond $ failWith NotFound
@@ -317,15 +315,14 @@ instance
317315#endif
318316 HasServer (Get ctypes ()) where
319317
320− type ServerT' (Get ctypes ()) m = m ()
318+ type ServerT (Get ctypes ()) m = m ()
321319
322320 route Proxy action request respond
323321 | pathIsEmpty request && requestMethod request == methodGet = do
324322 e <- runEitherT action
325323 respond . succeedWith $ case e of
326324 Right () -> responseLBS noContent204 [] ""
327− Left (status, message) ->
328− responseLBS (mkStatus status (cs message)) [] (cs message)
325+ Left err -> responseServantErr err
329326 | pathIsEmpty request && requestMethod request /= methodGet =
330327 respond $ failWith WrongMethod
331328 | otherwise = respond $ failWith NotFound
@@ -335,9 +332,10 @@ instance
335332#if MIN_VERSION_base(4,8,0)
336333 {-# OVERLAPPING #-}
337334#endif
338− ( AllCTRender ctypes v ) => HasServer (Get ctypes (Headers h v)) where
335+ ( GetHeaders (Headers h v), AllCTRender ctypes v
336+ ) => HasServer (Get ctypes (Headers h v)) where
339337
340− type ServerT' (Get ctypes (Headers h v)) m = m (Headers h v)
338+ type ServerT (Get ctypes (Headers h v)) m = m (Headers h v)
341339
342340 route Proxy action request respond
343341 | pathIsEmpty request && requestMethod request == methodGet = do
@@ -350,8 +348,7 @@ instance
350348 Nothing -> failWith UnsupportedMediaType
351349 Just (contentT, body) -> succeedWith $
352350 responseLBS ok200 ( ("Content-Type" , cs contentT) : headers) body
353− Left (status, message) -> succeedWith $
354− responseLBS (mkStatus status (cs message)) [] (cs message)
351+ Left err -> succeedWith $ responseServantErr err
355352 | pathIsEmpty request && requestMethod request /= methodGet =
356353 respond $ failWith WrongMethod
357354 | otherwise = respond $ failWith NotFound
@@ -379,8 +376,8 @@ instance
379376instance (KnownSymbol sym, FromText a, HasServer sublayout)
380377 => HasServer (Header sym a :> sublayout) where
381378
382− type ServerT' (Header sym a :> sublayout) m =
383− Maybe a -> ServerT' sublayout m
379+ type ServerT (Header sym a :> sublayout) m =
380+ Maybe a -> ServerT sublayout m
384381
385382 route Proxy subserver request respond = do
386383 let mheader = fromText . decodeUtf8 =<< lookup str (requestHeaders request)
@@ -408,7 +405,7 @@ instance
408405 ( AllCTRender ctypes a
409406 ) => HasServer (Post ctypes a) where
410407
411− type ServerT' (Post ctypes a) m = m a
408+ type ServerT (Post ctypes a) m = m a
412409
413410 route Proxy action request respond
414411 | pathIsEmpty request && requestMethod request == methodPost = do
@@ -420,8 +417,7 @@ instance
420417 Nothing -> failWith UnsupportedMediaType
421418 Just (contentT, body) -> succeedWith $
422419 responseLBS status201 [ ("Content-Type" , cs contentT)] body
423− Left (status, message) -> succeedWith $
424− responseLBS (mkStatus status (cs message)) [] (cs message)
420+ Left err -> succeedWith $ responseServantErr err
425421 | pathIsEmpty request && requestMethod request /= methodPost =
426422 respond $ failWith WrongMethod
427423 | otherwise = respond $ failWith NotFound
@@ -432,15 +428,14 @@ instance
432428#endif
433429 HasServer (Post ctypes ()) where
434430
435− type ServerT' (Post ctypes ()) m = m ()
431+ type ServerT (Post ctypes ()) m = m ()
436432
437433 route Proxy action request respond
438434 | pathIsEmpty request && requestMethod request == methodPost = do
439435 e <- runEitherT action
440436 respond . succeedWith $ case e of
441437 Right () -> responseLBS noContent204 [] ""
442− Left (status, message) ->
443− responseLBS (mkStatus status (cs message)) [] (cs message)
438+ Left err -> responseServantErr err
444439 | pathIsEmpty request && requestMethod request /= methodPost =
445440 respond $ failWith WrongMethod
446441 | otherwise = respond $ failWith NotFound
@@ -450,9 +445,10 @@ instance
450445#if MIN_VERSION_base(4,8,0)
451446 {-# OVERLAPPING #-}
452447#endif
453− ( AllCTRender ctypes v ) => HasServer (Post ctypes (Headers h v)) where
448+ ( GetHeaders (Headers h v), AllCTRender ctypes v
449+ ) => HasServer (Post ctypes (Headers h v)) where
454450
455− type ServerT' (Post ctypes (Headers h v)) m = m (Headers h v)
451+ type ServerT (Post ctypes (Headers h v)) m = m (Headers h v)
456452
457453 route Proxy action request respond
458454 | pathIsEmpty request && requestMethod request == methodPost = do
@@ -465,8 +461,7 @@ instance
465461 Nothing -> failWith UnsupportedMediaType
466462 Just (contentT, body) -> succeedWith $
467463 responseLBS status201 ( ("Content-Type" , cs contentT) : headers) body
468− Left (status, message) -> succeedWith $
469− responseLBS (mkStatus status (cs message)) [] (cs message)
464+ Left err -> succeedWith $ responseServantErr err
470465 | pathIsEmpty request && requestMethod request /= methodPost =
471466 respond $ failWith WrongMethod
472467 | otherwise = respond $ failWith NotFound
@@ -490,7 +485,7 @@ instance
490485#endif
491486 ( AllCTRender ctypes a) => HasServer (Put ctypes a) where
492487
493− type ServerT' (Put ctypes a) m = m a
488+ type ServerT (Put ctypes a) m = m a
494489
495490 route Proxy action request respond
496491 | pathIsEmpty request && requestMethod request == methodPut = do
@@ -502,8 +497,7 @@ instance
502497 Nothing -> failWith UnsupportedMediaType
503498 Just (contentT, body) -> succeedWith $
504499 responseLBS status200 [ ("Content-Type" , cs contentT)] body
505− Left (status, message) -> succeedWith $
506− responseLBS (mkStatus status (cs message)) [] (cs message)
500+ Left err -> succeedWith $ responseServantErr err
507501 | pathIsEmpty request && requestMethod request /= methodPut =
508502 respond $ failWith WrongMethod
509503 | otherwise = respond $ failWith NotFound
@@ -514,15 +508,14 @@ instance
514508#endif
515509 HasServer (Put ctypes ()) where
516510
517− type ServerT' (Put ctypes ()) m = m ()
511+ type ServerT (Put ctypes ()) m = m ()
518512
519513 route Proxy action request respond
520514 | pathIsEmpty request && requestMethod request == methodPut = do
521515 e <- runEitherT action
522516 respond . succeedWith $ case e of
523517 Right () -> responseLBS noContent204 [] ""
524− Left (status, message) ->
525− responseLBS (mkStatus status (cs message)) [] (cs message)
518+ Left err -> responseServantErr err
526519 | pathIsEmpty request && requestMethod request /= methodPut =
527520 respond $ failWith WrongMethod
528521 | otherwise = respond $ failWith NotFound
@@ -532,9 +525,10 @@ instance
532525#if MIN_VERSION_base(4,8,0)
533526 {-# OVERLAPPING #-}
534527#endif
535− ( AllCTRender ctypes v ) => HasServer (Put ctypes (Headers h v)) where
528+ ( GetHeaders (Headers h v), AllCTRender ctypes v
529+ ) => HasServer (Put ctypes (Headers h v)) where
536530
537− type ServerT' (Put ctypes (Headers h v)) m = m (Headers h v)
531+ type ServerT (Put ctypes (Headers h v)) m = m (Headers h v)
538532
539533 route Proxy action request respond
540534 | pathIsEmpty request && requestMethod request == methodPut = do
@@ -547,8 +541,7 @@ instance
547541 Nothing -> failWith UnsupportedMediaType
548542 Just (contentT, body) -> succeedWith $
549543 responseLBS status200 ( ("Content-Type" , cs contentT) : headers) body
550− Left (status, message) -> succeedWith $
551− responseLBS (mkStatus status (cs message)) [] (cs message)
544+ Left err -> succeedWith $ responseServantErr err
552545 | pathIsEmpty request && requestMethod request /= methodPut =
553546 respond $ failWith WrongMethod
554547 | otherwise = respond $ failWith NotFound
@@ -570,7 +563,7 @@ instance
570563#endif
571564 ( AllCTRender ctypes a) => HasServer (Patch ctypes a) where
572565
573− type ServerT' (Patch ctypes a) m = m a
566+ type ServerT (Patch ctypes a) m = m a
574567
575568 route Proxy action request respond
576569 | pathIsEmpty request && requestMethod request == methodPatch = do
@@ -582,8 +575,7 @@ instance
582575 Nothing -> failWith UnsupportedMediaType
583576 Just (contentT, body) -> succeedWith $
584577 responseLBS status200 [ ("Content-Type" , cs contentT)] body
585− Left (status, message) -> succeedWith $
586− responseLBS (mkStatus status (cs message)) [] (cs message)
578+ Left err -> succeedWith $ responseServantErr err
587579 | pathIsEmpty request && requestMethod request /= methodPatch =
588580 respond $ failWith WrongMethod
589581 | otherwise = respond $ failWith NotFound
@@ -594,15 +586,14 @@ instance
594586#endif
595587 HasServer (Patch ctypes ()) where
596588
597− type ServerT' (Patch ctypes ()) m = m ()
589+ type ServerT (Patch ctypes ()) m = m ()
598590
599591 route Proxy action request respond
600592 | pathIsEmpty request && requestMethod request == methodPatch = do
601593 e <- runEitherT action
602594 respond . succeedWith $ case e of
603595 Right () -> responseLBS noContent204 [] ""
604− Left (status, message) ->
605− responseLBS (mkStatus status (cs message)) [] (cs message)
596+ Left err -> responseServantErr err
606597 | pathIsEmpty request && requestMethod request /= methodPatch =
607598 respond $ failWith WrongMethod
608599 | otherwise = respond $ failWith NotFound
@@ -612,9 +603,10 @@ instance
612603#if MIN_VERSION_base(4,8,0)
613604 {-# OVERLAPPING #-}
614605#endif
615− ( AllCTRender ctypes v ) => HasServer (Patch ctypes (Headers h v)) where
606+ ( GetHeaders (Headers h v), AllCTRender ctypes v
607+ ) => HasServer (Patch ctypes (Headers h v)) where
616608
617− type ServerT' (Patch ctypes (Headers h v)) m = m (Headers h v)
609+ type ServerT (Patch ctypes (Headers h v)) m = m (Headers h v)
618610
619611 route Proxy action request respond
620612 | pathIsEmpty request && requestMethod request == methodPatch = do
@@ -627,8 +619,7 @@ instance
627619 Nothing -> failWith UnsupportedMediaType
628620 Just (contentT, body) -> succeedWith $
629621 responseLBS status200 ( ("Content-Type" , cs contentT) : headers) body
630− Left (status, message) -> succeedWith $
631− responseLBS (mkStatus status (cs message)) [] (cs message)
622+ Left err -> succeedWith $ responseServantErr err
632623 | pathIsEmpty request && requestMethod request /= methodPatch =
633624 respond $ failWith WrongMethod
634625 | otherwise = respond $ failWith NotFound
@@ -657,8 +648,8 @@ instance
657648instance (KnownSymbol sym, FromText a, HasServer sublayout)
658649 => HasServer (QueryParam sym a :> sublayout) where
659650
660− type ServerT' (QueryParam sym a :> sublayout) m =
661− Maybe a -> ServerT' sublayout m
651+ type ServerT (QueryParam sym a :> sublayout) m =
652+ Maybe a -> ServerT sublayout m
662653
663654 route Proxy subserver request respond = do
664655 let querytext = parseQueryText $ rawQueryString request
@@ -695,8 +686,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout)
695686instance (KnownSymbol sym, FromText a, HasServer sublayout)
696687 => HasServer (QueryParams sym a :> sublayout) where
697688
698− type ServerT' (QueryParams sym a :> sublayout) m =
699− [a] -> ServerT' sublayout m
689+ type ServerT (QueryParams sym a :> sublayout) m =
690+ [a] -> ServerT sublayout m
700691
701692 route Proxy subserver request respond = do
702693 let querytext = parseQueryText $ rawQueryString request
@@ -728,8 +719,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout)
728719instance (KnownSymbol sym, HasServer sublayout)
729720 => HasServer (QueryFlag sym :> sublayout) where
730721
731− type ServerT' (QueryFlag sym :> sublayout) m =
732− Bool -> ServerT' sublayout m
722+ type ServerT (QueryFlag sym :> sublayout) m =
723+ Bool -> ServerT sublayout m
733724
734725 route Proxy subserver request respond = do
735726 let querytext = parseQueryText $ rawQueryString request
@@ -771,8 +762,8 @@ parseMatrixText = parseQueryText
771762instance (KnownSymbol sym, FromText a, HasServer sublayout)
772763 => HasServer (MatrixParam sym a :> sublayout) where
773764
774− type ServerT' (MatrixParam sym a :> sublayout) m =
775− Maybe a -> ServerT' sublayout m
765+ type ServerT (MatrixParam sym a :> sublayout) m =
766+ Maybe a -> ServerT sublayout m
776767
777768 route Proxy subserver request respond = case parsePathInfo request of
778769 (first : _)
@@ -809,8 +800,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout)
809800instance (KnownSymbol sym, FromText a, HasServer sublayout)
810801 => HasServer (MatrixParams sym a :> sublayout) where
811802
812− type ServerT' (MatrixParams sym a :> sublayout) m =
813− [a] -> ServerT' sublayout m
803+ type ServerT (MatrixParams sym a :> sublayout) m =
804+ [a] -> ServerT sublayout m
814805
815806 route Proxy subserver request respond = case parsePathInfo request of
816807 (first : _)
@@ -843,8 +834,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout)
843834instance (KnownSymbol sym, HasServer sublayout)
844835 => HasServer (MatrixFlag sym :> sublayout) where
845836
846− type ServerT' (MatrixFlag sym :> sublayout) m =
847− Bool -> ServerT' sublayout m
837+ type ServerT (MatrixFlag sym :> sublayout) m =
838+ Bool -> ServerT sublayout m
848839
849840 route Proxy subserver request respond = case parsePathInfo request of
850841 (first : _)
@@ -872,7 +863,7 @@ instance (KnownSymbol sym, HasServer sublayout)
872863-- > server = serveDirectory "/var/www/images"
873864instance HasServer Raw where
874865
875− type ServerT' Raw m = Application
866+ type ServerT Raw m = Application
876867
877868 route Proxy rawApplication request respond =
878869 rawApplication request (respond . succeedWith)
@@ -900,8 +891,8 @@ instance HasServer Raw where
900891instance ( AllCTUnrender list a, HasServer sublayout
901892 ) => HasServer (ReqBody list a :> sublayout) where
902893
903− type ServerT' (ReqBody list a :> sublayout) m =
904− a -> ServerT' sublayout m
894+ type ServerT (ReqBody list a :> sublayout) m =
895+ a -> ServerT sublayout m
905896
906897 route Proxy subserver request respond = do
907898 -- See HTTP RFC 2616, section 7.2.1
@@ -921,7 +912,7 @@ instance ( AllCTUnrender list a, HasServer sublayout
921912-- pass the rest of the request path to @sublayout@.
922913instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout) where
923914
924− type ServerT' (path :> sublayout) m = ServerT' sublayout m
915+ type ServerT (path :> sublayout) m = ServerT sublayout m
925916
926917 route Proxy subserver request respond = case processedPathInfo request of
927918 (first : rest)