@@ -1,22 +1,28 @@
1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
4−{-# LANGUAGE OverlappingInstances #-}
5{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE PolyKinds #-}
6{-# LANGUAGE PolyKinds #-}
7{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE TypeFamilies #-}
8{-# LANGUAGE TypeFamilies #-}
9{-# LANGUAGE TypeOperators #-}
9{-# LANGUAGE TypeOperators #-}
10+#if !MIN_VERSION_base(4,8,0)
11+{-# LANGUAGE OverlappingInstances #-}
10module Servant.Server.Internal where
14module Servant.Server.Internal where
16+#if !MIN_VERSION_base(4,8,0)
12import Control.Applicative ((<$>))
17import Control.Applicative ((<$>))
18+import Data.Monoid (Monoid, mappend, mempty)
13import Control.Monad.Trans.Either (EitherT, runEitherT)
20import Control.Monad.Trans.Either (EitherT, runEitherT)
14import qualified Data.ByteString as B
21import qualified Data.ByteString as B
15import qualified Data.ByteString.Lazy as BL
22import qualified Data.ByteString.Lazy as BL
16import Data.IORef (newIORef, readIORef, writeIORef)
23import Data.IORef (newIORef, readIORef, writeIORef)
17import Data.List (unfoldr)
24import Data.List (unfoldr)
18import Data.Maybe (catMaybes, fromMaybe)
25import Data.Maybe (catMaybes, fromMaybe)
19−import Data.Monoid (Monoid, mappend, mempty)
20import Data.String (fromString)
26import Data.String (fromString)
21import Data.String.Conversions (cs, (<>))
27import Data.String.Conversions (cs, (<>))
22import Data.Text (Text)
28import Data.Text (Text)
@@ -278,10 +284,13 @@ instance HasServer Delete where
278-- If successfully returning a value, we use the type-level list, combined
284-- If successfully returning a value, we use the type-level list, combined
279-- with the request's @Accept@ header, to encode the value for you
285-- with the request's @Accept@ header, to encode the value for you
280-- (returning a status code of 200). If there was no @Accept@ header or it
286-- (returning a status code of 200). If there was no @Accept@ header or it
281−-- was @*/*@, we return encode using the first @Content-Type@ type on the
287+-- was @*\/\*@, we return encode using the first @Content-Type@ type on the
283−instance ( AllCTRender ctypes a
289+instance
290+#if MIN_VERSION_base(4,8,0)
291+ {-# OVERLAPPABLE #-}
284− ) => HasServer (Get ctypes a) where
293+ ( AllCTRender ctypes a ) => HasServer (Get ctypes a) where
286 type ServerT' (Get ctypes a) m = m a
295 type ServerT' (Get ctypes a) m = m a
@@ -290,7 +299,7 @@ instance ( AllCTRender ctypes a
290 e <- runEitherT action
299 e <- runEitherT action
291 respond $ case e of
300 respond $ case e of
292 Right output -> do
301 Right output -> do
293− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
302+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
294 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
303 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
295 Nothing -> failWith UnsupportedMediaType
304 Nothing -> failWith UnsupportedMediaType
296 Just (contentT, body) -> succeedWith $
305 Just (contentT, body) -> succeedWith $
@@ -302,8 +311,14 @@ instance ( AllCTRender ctypes a
302 | otherwise = respond $ failWith NotFound
311 | otherwise = respond $ failWith NotFound
304-- '()' ==> 204 No Content
313-- '()' ==> 204 No Content
315+#if MIN_VERSION_base(4,8,0)
305−instance HasServer (Get ctypes ()) where
318+ HasServer (Get ctypes ()) where
306 type ServerT' (Get ctypes ()) m = m ()
320 type ServerT' (Get ctypes ()) m = m ()
307 route Proxy action request respond
322 route Proxy action request respond
308 | pathIsEmpty request && requestMethod request == methodGet = do
323 | pathIsEmpty request && requestMethod request == methodGet = do
309 e <- runEitherT action
324 e <- runEitherT action
@@ -316,14 +331,20 @@ instance HasServer (Get ctypes ()) where
316 | otherwise = respond $ failWith NotFound
331 | otherwise = respond $ failWith NotFound
318-- Add response headers
333-- Add response headers
335+#if MIN_VERSION_base(4,8,0)
319−instance ( AllCTRender ctypes v ) => HasServer (Get ctypes (Headers h v)) where
338+ ( AllCTRender ctypes v ) => HasServer (Get ctypes (Headers h v)) where
320 type ServerT' (Get ctypes (Headers h v)) m = m (Headers h v)
340 type ServerT' (Get ctypes (Headers h v)) m = m (Headers h v)
321 route Proxy action request respond
342 route Proxy action request respond
322 | pathIsEmpty request && requestMethod request == methodGet = do
343 | pathIsEmpty request && requestMethod request == methodGet = do
323 e <- runEitherT action
344 e <- runEitherT action
324 respond $ case e of
345 respond $ case e of
325 Right output -> do
346 Right output -> do
326− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
347+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
327 headers = getHeaders output
348 headers = getHeaders output
328 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
349 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
329 Nothing -> failWith UnsupportedMediaType
350 Nothing -> failWith UnsupportedMediaType
@@ -378,9 +399,13 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout)
378-- If successfully returning a value, we use the type-level list, combined
399-- If successfully returning a value, we use the type-level list, combined
379-- with the request's @Accept@ header, to encode the value for you
400-- with the request's @Accept@ header, to encode the value for you
380-- (returning a status code of 201). If there was no @Accept@ header or it
401-- (returning a status code of 201). If there was no @Accept@ header or it
381−-- was @*/*@, we return encode using the first @Content-Type@ type on the
402+-- was @*\/\*@, we return encode using the first @Content-Type@ type on the
405+#if MIN_VERSION_base(4,8,0)
406+ {-# OVERLAPPABLE #-}
383−instance ( AllCTRender ctypes a
408+ ( AllCTRender ctypes a
384 ) => HasServer (Post ctypes a) where
409 ) => HasServer (Post ctypes a) where
386 type ServerT' (Post ctypes a) m = m a
411 type ServerT' (Post ctypes a) m = m a
@@ -390,7 +415,7 @@ instance ( AllCTRender ctypes a
390 e <- runEitherT action
415 e <- runEitherT action
391 respond $ case e of
416 respond $ case e of
392 Right output -> do
417 Right output -> do
393− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
418+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
394 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
419 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
395 Nothing -> failWith UnsupportedMediaType
420 Nothing -> failWith UnsupportedMediaType
396 Just (contentT, body) -> succeedWith $
421 Just (contentT, body) -> succeedWith $
@@ -401,8 +426,14 @@ instance ( AllCTRender ctypes a
401 respond $ failWith WrongMethod
426 respond $ failWith WrongMethod
402 | otherwise = respond $ failWith NotFound
427 | otherwise = respond $ failWith NotFound
430+#if MIN_VERSION_base(4,8,0)
404−instance HasServer (Post ctypes ()) where
433+ HasServer (Post ctypes ()) where
405 type ServerT' (Post ctypes ()) m = m ()
435 type ServerT' (Post ctypes ()) m = m ()
406 route Proxy action request respond
437 route Proxy action request respond
407 | pathIsEmpty request && requestMethod request == methodPost = do
438 | pathIsEmpty request && requestMethod request == methodPost = do
408 e <- runEitherT action
439 e <- runEitherT action
@@ -415,14 +446,20 @@ instance HasServer (Post ctypes ()) where
415 | otherwise = respond $ failWith NotFound
446 | otherwise = respond $ failWith NotFound
417-- Add response headers
448-- Add response headers
450+#if MIN_VERSION_base(4,8,0)
418−instance ( AllCTRender ctypes v ) => HasServer (Post ctypes (Headers h v)) where
453+ ( AllCTRender ctypes v ) => HasServer (Post ctypes (Headers h v)) where
419 type ServerT' (Post ctypes (Headers h v)) m = m (Headers h v)
455 type ServerT' (Post ctypes (Headers h v)) m = m (Headers h v)
420 route Proxy action request respond
457 route Proxy action request respond
421 | pathIsEmpty request && requestMethod request == methodPost = do
458 | pathIsEmpty request && requestMethod request == methodPost = do
422 e <- runEitherT action
459 e <- runEitherT action
423 respond $ case e of
460 respond $ case e of
424 Right output -> do
461 Right output -> do
425− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
462+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
426 headers = getHeaders output
463 headers = getHeaders output
427 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
464 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
428 Nothing -> failWith UnsupportedMediaType
465 Nothing -> failWith UnsupportedMediaType
@@ -445,10 +482,13 @@ instance ( AllCTRender ctypes v ) => HasServer (Post ctypes (Headers h v)) where
445-- If successfully returning a value, we use the type-level list, combined
482-- If successfully returning a value, we use the type-level list, combined
446-- with the request's @Accept@ header, to encode the value for you
483-- with the request's @Accept@ header, to encode the value for you
447-- (returning a status code of 200). If there was no @Accept@ header or it
484-- (returning a status code of 200). If there was no @Accept@ header or it
448−-- was @*/*@, we return encode using the first @Content-Type@ type on the
485+-- was @*\/\*@, we return encode using the first @Content-Type@ type on the
450−instance ( AllCTRender ctypes a
487+instance
488+#if MIN_VERSION_base(4,8,0)
489+ {-# OVERLAPPABLE #-}
451− ) => HasServer (Put ctypes a) where
491+ ( AllCTRender ctypes a) => HasServer (Put ctypes a) where
453 type ServerT' (Put ctypes a) m = m a
493 type ServerT' (Put ctypes a) m = m a
@@ -457,7 +497,7 @@ instance ( AllCTRender ctypes a
457 e <- runEitherT action
497 e <- runEitherT action
458 respond $ case e of
498 respond $ case e of
459 Right output -> do
499 Right output -> do
460− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
500+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
461 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
501 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
462 Nothing -> failWith UnsupportedMediaType
502 Nothing -> failWith UnsupportedMediaType
463 Just (contentT, body) -> succeedWith $
503 Just (contentT, body) -> succeedWith $
@@ -468,8 +508,14 @@ instance ( AllCTRender ctypes a
468 respond $ failWith WrongMethod
508 respond $ failWith WrongMethod
469 | otherwise = respond $ failWith NotFound
509 | otherwise = respond $ failWith NotFound
512+#if MIN_VERSION_base(4,8,0)
471−instance HasServer (Put ctypes ()) where
515+ HasServer (Put ctypes ()) where
472 type ServerT' (Put ctypes ()) m = m ()
517 type ServerT' (Put ctypes ()) m = m ()
473 route Proxy action request respond
519 route Proxy action request respond
474 | pathIsEmpty request && requestMethod request == methodPut = do
520 | pathIsEmpty request && requestMethod request == methodPut = do
475 e <- runEitherT action
521 e <- runEitherT action
@@ -482,14 +528,20 @@ instance HasServer (Put ctypes ()) where
482 | otherwise = respond $ failWith NotFound
528 | otherwise = respond $ failWith NotFound
484-- Add response headers
530-- Add response headers
532+#if MIN_VERSION_base(4,8,0)
485−instance ( AllCTRender ctypes v ) => HasServer (Put ctypes (Headers h v)) where
535+ ( AllCTRender ctypes v ) => HasServer (Put ctypes (Headers h v)) where
486 type ServerT' (Put ctypes (Headers h v)) m = m (Headers h v)
537 type ServerT' (Put ctypes (Headers h v)) m = m (Headers h v)
487 route Proxy action request respond
539 route Proxy action request respond
488 | pathIsEmpty request && requestMethod request == methodPut = do
540 | pathIsEmpty request && requestMethod request == methodPut = do
489 e <- runEitherT action
541 e <- runEitherT action
490 respond $ case e of
542 respond $ case e of
491 Right output -> do
543 Right output -> do
492− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
544+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
493 headers = getHeaders output
545 headers = getHeaders output
494 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
546 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse output) of
495 Nothing -> failWith UnsupportedMediaType
547 Nothing -> failWith UnsupportedMediaType
@@ -512,8 +564,12 @@ instance ( AllCTRender ctypes v ) => HasServer (Put ctypes (Headers h v)) where
512-- If successfully returning a value, we just require that its type has
564-- If successfully returning a value, we just require that its type has
513-- a 'ToJSON' instance and servant takes care of encoding it for you,
565-- a 'ToJSON' instance and servant takes care of encoding it for you,
514-- yielding status code 200 along the way.
566-- yielding status code 200 along the way.
515−instance ( AllCTRender ctypes a
567+instance
568+#if MIN_VERSION_base(4,8,0)
569+ {-# OVERLAPPABLE #-}
516− ) => HasServer (Patch ctypes a) where
571+ ( AllCTRender ctypes a) => HasServer (Patch ctypes a) where
517 type ServerT' (Patch ctypes a) m = m a
573 type ServerT' (Patch ctypes a) m = m a
519 route Proxy action request respond
575 route Proxy action request respond
@@ -521,7 +577,7 @@ instance ( AllCTRender ctypes a
521 e <- runEitherT action
577 e <- runEitherT action
522 respond $ case e of
578 respond $ case e of
523 Right output -> do
579 Right output -> do
524− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
580+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
525 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
581 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) output of
526 Nothing -> failWith UnsupportedMediaType
582 Nothing -> failWith UnsupportedMediaType
527 Just (contentT, body) -> succeedWith $
583 Just (contentT, body) -> succeedWith $
@@ -532,8 +588,14 @@ instance ( AllCTRender ctypes a
532 respond $ failWith WrongMethod
588 respond $ failWith WrongMethod
533 | otherwise = respond $ failWith NotFound
589 | otherwise = respond $ failWith NotFound
592+#if MIN_VERSION_base(4,8,0)
535−instance HasServer (Patch ctypes ()) where
595+ HasServer (Patch ctypes ()) where
536 type ServerT' (Patch ctypes ()) m = m ()
597 type ServerT' (Patch ctypes ()) m = m ()
537 route Proxy action request respond
599 route Proxy action request respond
538 | pathIsEmpty request && requestMethod request == methodPatch = do
600 | pathIsEmpty request && requestMethod request == methodPatch = do
539 e <- runEitherT action
601 e <- runEitherT action
@@ -546,14 +608,20 @@ instance HasServer (Patch ctypes ()) where
546 | otherwise = respond $ failWith NotFound
608 | otherwise = respond $ failWith NotFound
548-- Add response headers
610-- Add response headers
612+#if MIN_VERSION_base(4,8,0)
549−instance ( AllCTRender ctypes v ) => HasServer (Patch ctypes (Headers h v)) where
615+ ( AllCTRender ctypes v ) => HasServer (Patch ctypes (Headers h v)) where
550 type ServerT' (Patch ctypes (Headers h v)) m = m (Headers h v)
617 type ServerT' (Patch ctypes (Headers h v)) m = m (Headers h v)
551 route Proxy action request respond
619 route Proxy action request respond
552 | pathIsEmpty request && requestMethod request == methodPatch = do
620 | pathIsEmpty request && requestMethod request == methodPatch = do
553 e <- runEitherT action
621 e <- runEitherT action
554 respond $ case e of
622 respond $ case e of
555 Right outpatch -> do
623 Right outpatch -> do
556− let accH = fromMaybe "*/*" $ lookup hAccept $ requestHeaders request
624+ let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
557 headers = getHeaders outpatch
625 headers = getHeaders outpatch
558 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse outpatch) of
626 case handleAcceptH (Proxy :: Proxy ctypes) (AcceptHeader accH) (getResponse outpatch) of
559 Nothing -> failWith UnsupportedMediaType
627 Nothing -> failWith UnsupportedMediaType
@@ -864,3 +932,6 @@ instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout
864 _ -> respond $ failWith NotFound
932 _ -> respond $ failWith NotFound
866 where proxyPath = Proxy :: Proxy path
934 where proxyPath = Proxy :: Proxy path
936+ct_wildcard :: B.ByteString
937+ct_wildcard = "*" <> "/" <> "*" -- Because CPP