@@ -22,6 +22,7 @@ module Servant.Server.Internal
22
22
, module Servant.Server.Internal.ServantErr
23
23
) where
24
24
25
+ import Control.Monad.Trans (liftIO )
25
26
import qualified Data.ByteString as B
26
27
import qualified Data.ByteString.Char8 as BC8
27
28
import qualified Data.ByteString.Lazy as BL
@@ -70,7 +71,11 @@ import Servant.Server.Internal.ServantErr
70
71
class HasServer layout context where
71
72
type ServerT layout (m :: * -> * ) :: *
72
73
73
- route :: Proxy layout -> Context context -> Delayed (Server layout ) -> Router
74
+ route ::
75
+ Proxy layout
76
+ -> Context context
77
+ -> Delayed env (Server layout )
78
+ -> Router env
74
79
75
80
type Server layout = ServerT layout Handler
76
81
@@ -92,7 +97,7 @@ instance (HasServer a context, HasServer b context) => HasServer (a :<|> b) cont
92
97
type ServerT (a :<|> b ) m = ServerT a m :<|> ServerT b m
93
98
94
99
route Proxy context server = choice (route pa context ((\ (a :<|> _) -> a) <$> server))
95
- (route pb context ((\ (_ :<|> b) -> b) <$> server))
100
+ (route pb context ((\ (_ :<|> b) -> b) <$> server))
96
101
where pa = Proxy :: Proxy a
97
102
pb = Proxy :: Proxy b
98
103
@@ -120,12 +125,12 @@ instance (KnownSymbol capture, FromHttpApiData a, HasServer sublayout context)
120
125
a -> ServerT sublayout m
121
126
122
127
route Proxy context d =
123
- DynamicRouter $ \ first ->
128
+ CaptureRouter $
124
129
route (Proxy :: Proxy sublayout )
125
130
context
126
- (addCapture d $ case parseUrlPieceMaybe first :: Maybe a of
127
- Nothing -> return $ Fail err400
128
- Just v -> return $ Route v
131
+ (addCapture d $ \ txt -> case parseUrlPieceMaybe txt :: Maybe a of
132
+ Nothing -> delayedFail err400
133
+ Just v -> return v
129
134
)
130
135
131
136
allowedMethodHead :: Method -> Request -> Bool
@@ -144,41 +149,41 @@ processMethodRouter handleA status method headers request = case handleA of
144
149
bdy = if allowedMethodHead method request then " " else body
145
150
hdrs = (hContentType, cs contentT) : (fromMaybe [] headers)
146
151
147
- methodCheck :: Method -> Request -> IO ( RouteResult () )
152
+ methodCheck :: Method -> Request -> DelayedIO ( )
148
153
methodCheck method request
149
- | allowedMethod method request = return $ Route ()
150
- | otherwise = return $ Fail err405
154
+ | allowedMethod method request = return ()
155
+ | otherwise = delayedFail err405
151
156
152
- acceptCheck :: (AllMime list ) => Proxy list -> B. ByteString -> IO ( RouteResult () )
157
+ acceptCheck :: (AllMime list ) => Proxy list -> B. ByteString -> DelayedIO ( )
153
158
acceptCheck proxy accH
154
- | canHandleAcceptH proxy (AcceptHeader accH) = return $ Route ()
155
- | otherwise = return $ FailFatal err406
159
+ | canHandleAcceptH proxy (AcceptHeader accH) = return ()
160
+ | otherwise = delayedFailFatal err406
156
161
157
162
methodRouter :: (AllCTRender ctypes a )
158
163
=> Method -> Proxy ctypes -> Status
159
- -> Delayed (Handler a )
160
- -> Router
164
+ -> Delayed env (Handler a )
165
+ -> Router env
161
166
methodRouter method proxy status action = leafRouter route'
162
167
where
163
- route' request respond =
168
+ route' env request respond =
164
169
let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
165
170
in runAction (action `addMethodCheck` methodCheck method request
166
171
`addAcceptCheck` acceptCheck proxy accH
167
- ) respond $ \ output -> do
172
+ ) env request respond $ \ output -> do
168
173
let handleA = handleAcceptH proxy (AcceptHeader accH) output
169
174
processMethodRouter handleA status method Nothing request
170
175
171
176
methodRouterHeaders :: (GetHeaders (Headers h v ), AllCTRender ctypes v )
172
177
=> Method -> Proxy ctypes -> Status
173
- -> Delayed (Handler (Headers h v ))
174
- -> Router
178
+ -> Delayed env (Handler (Headers h v ))
179
+ -> Router env
175
180
methodRouterHeaders method proxy status action = leafRouter route'
176
181
where
177
- route' request respond =
182
+ route' env request respond =
178
183
let accH = fromMaybe ct_wildcard $ lookup hAccept $ requestHeaders request
179
184
in runAction (action `addMethodCheck` methodCheck method request
180
185
`addAcceptCheck` acceptCheck proxy accH
181
- ) respond $ \ output -> do
186
+ ) env request respond $ \ output -> do
182
187
let headers = getHeaders output
183
188
handleA = handleAcceptH proxy (AcceptHeader accH) (getResponse output)
184
189
processMethodRouter handleA status method (Just headers) request
@@ -230,8 +235,8 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout context)
230
235
type ServerT (Header sym a :> sublayout ) m =
231
236
Maybe a -> ServerT sublayout m
232
237
233
- route Proxy context subserver = WithRequest $ \ request ->
234
- let mheader = parseHeaderMaybe =<< lookup str (requestHeaders request )
238
+ route Proxy context subserver =
239
+ let mheader req = parseHeaderMaybe =<< lookup str (requestHeaders req )
235
240
in route (Proxy :: Proxy sublayout ) context (passToServer subserver mheader)
236
241
where str = fromString $ symbolVal (Proxy :: Proxy sym )
237
242
@@ -262,10 +267,10 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout context)
262
267
type ServerT (QueryParam sym a :> sublayout ) m =
263
268
Maybe a -> ServerT sublayout m
264
269
265
- route Proxy context subserver = WithRequest $ \ request ->
266
- let querytext = parseQueryText $ rawQueryString request
267
- param =
268
- case lookup paramname querytext of
270
+ route Proxy context subserver =
271
+ let querytext r = parseQueryText $ rawQueryString r
272
+ param r =
273
+ case lookup paramname ( querytext r) of
269
274
Nothing -> Nothing -- param absent from the query string
270
275
Just Nothing -> Nothing -- param present with no value -> Nothing
271
276
Just (Just v) -> parseQueryParamMaybe v -- if present, we try to convert to
@@ -298,13 +303,13 @@ instance (KnownSymbol sym, FromHttpApiData a, HasServer sublayout context)
298
303
type ServerT (QueryParams sym a :> sublayout ) m =
299
304
[a ] -> ServerT sublayout m
300
305
301
- route Proxy context subserver = WithRequest $ \ request ->
302
- let querytext = parseQueryText $ rawQueryString request
306
+ route Proxy context subserver =
307
+ let querytext r = parseQueryText $ rawQueryString r
303
308
-- if sym is "foo", we look for query string parameters
304
309
-- named "foo" or "foo[]" and call parseQueryParam on the
305
310
-- corresponding values
306
- parameters = filter looksLikeParam querytext
307
- values = mapMaybe (convert . snd ) parameters
311
+ parameters r = filter looksLikeParam ( querytext r)
312
+ values r = mapMaybe (convert . snd ) ( parameters r)
308
313
in route (Proxy :: Proxy sublayout ) context (passToServer subserver values)
309
314
where paramname = cs $ symbolVal (Proxy :: Proxy sym )
310
315
looksLikeParam (name, _) = name == paramname || name == (paramname <> " []" )
@@ -329,9 +334,9 @@ instance (KnownSymbol sym, HasServer sublayout context)
329
334
type ServerT (QueryFlag sym :> sublayout ) m =
330
335
Bool -> ServerT sublayout m
331
336
332
- route Proxy context subserver = WithRequest $ \ request ->
333
- let querytext = parseQueryText $ rawQueryString request
334
- param = case lookup paramname querytext of
337
+ route Proxy context subserver =
338
+ let querytext r = parseQueryText $ rawQueryString r
339
+ param r = case lookup paramname ( querytext r) of
335
340
Just Nothing -> True -- param is there, with no value
336
341
Just (Just v) -> examine v -- param with a value
337
342
Nothing -> False -- param not in the query string
@@ -352,8 +357,8 @@ instance HasServer Raw context where
352
357
353
358
type ServerT Raw m = Application
354
359
355
- route Proxy _ rawApplication = RawRouter $ \ request respond -> do
356
- r <- runDelayed rawApplication
360
+ route Proxy _ rawApplication = RawRouter $ \ env request respond -> do
361
+ r <- runDelayed rawApplication env request
357
362
case r of
358
363
Route app -> app request (respond . Route )
359
364
Fail a -> respond $ Fail a
@@ -386,22 +391,22 @@ instance ( AllCTUnrender list a, HasServer sublayout context
386
391
type ServerT (ReqBody list a :> sublayout ) m =
387
392
a -> ServerT sublayout m
388
393
389
- route Proxy context subserver = WithRequest $ \ request ->
390
- route (Proxy :: Proxy sublayout ) context (addBodyCheck subserver ( bodyCheck request) )
394
+ route Proxy context subserver =
395
+ route (Proxy :: Proxy sublayout ) context (addBodyCheck subserver bodyCheck)
391
396
where
392
- bodyCheck request = do
397
+ bodyCheck = withRequest $ \ request -> do
393
398
-- See HTTP RFC 2616, section 7.2.1
394
399
-- http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
395
400
-- See also "W3C Internet Media Type registration, consistency of use"
396
401
-- http://www.w3.org/2001/tag/2002/0129-mime
397
402
let contentTypeH = fromMaybe " application/octet-stream"
398
403
$ lookup hContentType $ requestHeaders request
399
404
mrqbody <- handleCTypeH (Proxy :: Proxy list ) (cs contentTypeH)
400
- <$> lazyRequestBody request
405
+ <$> liftIO ( lazyRequestBody request)
401
406
case mrqbody of
402
- Nothing -> return $ FailFatal err415
403
- Just (Left e) -> return $ FailFatal err400 { errBody = cs e }
404
- Just (Right v) -> return $ Route v
407
+ Nothing -> delayedFailFatal err415
408
+ Just (Left e) -> delayedFailFatal err400 { errBody = cs e }
409
+ Just (Right v) -> return v
405
410
406
411
-- | Make sure the incoming request starts with @"/path"@, strip it and
407
412
-- pass the rest of the request path to @sublayout@.
@@ -418,28 +423,28 @@ instance (KnownSymbol path, HasServer sublayout context) => HasServer (path :> s
418
423
instance HasServer api context => HasServer (RemoteHost :> api ) context where
419
424
type ServerT (RemoteHost :> api ) m = SockAddr -> ServerT api m
420
425
421
- route Proxy context subserver = WithRequest $ \ req ->
422
- route (Proxy :: Proxy api ) context (passToServer subserver $ remoteHost req )
426
+ route Proxy context subserver =
427
+ route (Proxy :: Proxy api ) context (passToServer subserver remoteHost)
423
428
424
429
instance HasServer api context => HasServer (IsSecure :> api ) context where
425
430
type ServerT (IsSecure :> api ) m = IsSecure -> ServerT api m
426
431
427
- route Proxy context subserver = WithRequest $ \ req ->
428
- route (Proxy :: Proxy api ) context (passToServer subserver $ secure req )
432
+ route Proxy context subserver =
433
+ route (Proxy :: Proxy api ) context (passToServer subserver secure)
429
434
430
435
where secure req = if isSecure req then Secure else NotSecure
431
436
432
437
instance HasServer api context => HasServer (Vault :> api ) context where
433
438
type ServerT (Vault :> api ) m = Vault -> ServerT api m
434
439
435
- route Proxy context subserver = WithRequest $ \ req ->
436
- route (Proxy :: Proxy api ) context (passToServer subserver $ vault req )
440
+ route Proxy context subserver =
441
+ route (Proxy :: Proxy api ) context (passToServer subserver vault)
437
442
438
443
instance HasServer api context => HasServer (HttpVersion :> api ) context where
439
444
type ServerT (HttpVersion :> api ) m = HttpVersion -> ServerT api m
440
445
441
- route Proxy context subserver = WithRequest $ \ req ->
442
- route (Proxy :: Proxy api ) context (passToServer subserver $ httpVersion req )
446
+ route Proxy context subserver =
447
+ route (Proxy :: Proxy api ) context (passToServer subserver httpVersion)
443
448
444
449
-- | Basic Authentication
445
450
instance ( KnownSymbol realm
@@ -450,12 +455,12 @@ instance ( KnownSymbol realm
450
455
451
456
type ServerT (BasicAuth realm usr :> api ) m = usr -> ServerT api m
452
457
453
- route Proxy context subserver = WithRequest $ \ request ->
454
- route (Proxy :: Proxy api ) context (subserver `addAuthCheck` authCheck request )
458
+ route Proxy context subserver =
459
+ route (Proxy :: Proxy api ) context (subserver `addAuthCheck` authCheck)
455
460
where
456
461
realm = BC8. pack $ symbolVal (Proxy :: Proxy realm )
457
462
basicAuthContext = getContextEntry context
458
- authCheck req = runBasicAuth req realm basicAuthContext
463
+ authCheck = withRequest $ \ req -> runBasicAuth req realm basicAuthContext
459
464
460
465
-- * helpers
461
466
0 commit comments