@@ -52,21 +52,23 @@ import qualified AWS.Lambda.Events.ApiGateway.ProxyResponse as HalResponse
52
52
import Control.Exception (IOException , tryJust )
53
53
import Control.Monad.IO.Class (MonadIO (.. ))
54
54
import Data.ByteString (ByteString )
55
- import qualified Data.ByteString as B
56
- import qualified Data.ByteString.Base64 as B64
55
+ import qualified Data.ByteString as ByteString
56
+ import qualified Data.ByteString.Base64 as Base64
57
57
import qualified Data.ByteString.Builder as Builder
58
58
import qualified Data.ByteString.Builder.Extra as Builder
59
- import qualified Data.ByteString.Lazy as BL
59
+ import qualified Data.ByteString.Lazy as LByteString
60
60
import qualified Data.CaseInsensitive as CI
61
61
import Data.Function ((&) )
62
+ import Data.Functor ((<&>) )
62
63
import Data.HashMap.Lazy (HashMap )
63
- import qualified Data.HashMap.Lazy as H
64
+ import qualified Data.HashMap.Lazy as HashMap
64
65
import qualified Data.IORef as IORef
65
66
import Data.List (foldl' , sort )
67
+ import Data.List.NonEmpty (NonEmpty (.. ))
66
68
import Data.Maybe (fromMaybe )
67
69
import Data.Text (Text )
68
- import qualified Data.Text as T
69
- import qualified Data.Text.Encoding as T
70
+ import qualified Data.Text as Text
71
+ import qualified Data.Text.Encoding as Text
70
72
import Data.Vault.Lazy (Key , Vault )
71
73
import qualified Data.Vault.Lazy as Vault
72
74
import Network.HTTP.Media (MediaType , matches , parseAccept , renderHeader )
@@ -160,12 +162,12 @@ runWithOptions ::
160
162
HalRequest. ProxyRequest HalRequest. NoAuthorizer ->
161
163
m HalResponse. ProxyResponse
162
164
runWithOptions opts app req = liftIO $ do
163
- waiReq <- toWaiRequest opts req
164
- responseRef <- IORef. newIORef Nothing
165
- Wai. ResponseReceived <- app waiReq $ \ waiResp ->
166
- Wai. ResponseReceived <$ IORef. writeIORef responseRef (Just waiResp)
167
- Just waiResp <- IORef. readIORef responseRef
168
- fromWaiResponse opts waiResp
165
+ waiReq <- toWaiRequest opts req
166
+ responseRef <- IORef. newIORef Nothing
167
+ Wai. ResponseReceived <- app waiReq $ \ waiResp ->
168
+ Wai. ResponseReceived <$ IORef. writeIORef responseRef (Just waiResp)
169
+ Just waiResp <- IORef. readIORef responseRef
170
+ fromWaiResponse opts waiResp
169
171
170
172
-- | Convert a WAI 'Wai.Application' into a function that can
171
173
-- be run by hal's 'AWS.Lambda.Runtime.mRuntimeWithContext'. This
@@ -222,16 +224,17 @@ toWaiRequest ::
222
224
IO Wai. Request
223
225
toWaiRequest opts req = do
224
226
let port = portNumber opts
225
- pathSegments = T. splitOn " /" . T. dropWhile (== ' /' ) $ HalRequest. path req
226
- query = sort . constructQuery $ HalRequest. multiValueQueryStringParameters req
227
+ pathSegments =
228
+ Text. splitOn " /" . Text. dropWhile (== ' /' ) $ HalRequest. path req
229
+ query =
230
+ sort . constructQuery $ HalRequest. multiValueQueryStringParameters req
227
231
hints =
228
232
NS. defaultHints
229
233
{ NS. addrFlags = [NS. AI_NUMERICHOST ],
230
- NS. addrFamily = NS. AF_INET ,
231
234
NS. addrSocketType = NS. Stream
232
235
}
233
236
sourceIp =
234
- T . unpack
237
+ Text . unpack
235
238
. HalRequest. sourceIp
236
239
. HalRequest. identity
237
240
$ HalRequest. requestContext req
@@ -243,7 +246,7 @@ toWaiRequest opts req = do
243
246
(Just @ IOException )
244
247
(NS. getAddrInfo (Just hints) (Just sourceIp) (Just $ show port))
245
248
>>= \ case
246
- Right (s : _) -> pure $ NS. addrAddress s
249
+ Right (s :| _) -> pure $ NS. addrAddress s
247
250
_ -> do
248
251
hPutStrLn stderr $
249
252
mconcat
@@ -253,53 +256,57 @@ toWaiRequest opts req = do
253
256
]
254
257
pure . NS. SockAddrInet port $ NS. tupleToHostAddress (127 , 0 , 0 , 1 )
255
258
body <- returnChunks $ HalRequest. body req
256
- let waiReq =
257
- Wai. Request
258
- { Wai. requestMethod = T. encodeUtf8 $ HalRequest. httpMethod req,
259
- Wai. httpVersion = HttpVersion 1 1 ,
260
- Wai. rawPathInfo =
261
- BL. toStrict
262
- . Builder. toLazyByteString
263
- $ encodePath pathSegments [] ,
264
- Wai. rawQueryString = case query of
265
- [] -> " "
266
- _ -> renderQuery True query,
267
- Wai. requestHeaders =
268
- sort
269
- . foldMap
270
- ( \ (hName, hValues) ->
271
- (CI. map T. encodeUtf8 hName,) . T. encodeUtf8 <$> hValues
272
- )
273
- . H. toList
274
- $ HalRequest. multiValueHeaders req,
275
- Wai. isSecure = True ,
276
- Wai. remoteHost = sourceHost,
277
- Wai. pathInfo = pathSegments,
278
- Wai. queryString = query,
279
- Wai. requestBody = body,
280
- Wai. vault = vault opts,
281
- Wai. requestBodyLength =
282
- Wai. KnownLength . fromIntegral . BL. length $ HalRequest. body req,
283
- Wai. requestHeaderHost = getHeader hHost req,
284
- Wai. requestHeaderRange = getHeader hRange req,
285
- Wai. requestHeaderReferer = getHeader hReferer req,
286
- Wai. requestHeaderUserAgent = getHeader hUserAgent req
287
- }
288
- pure waiReq
259
+ pure
260
+ Wai. Request
261
+ { Wai. requestMethod = Text. encodeUtf8 $ HalRequest. httpMethod req,
262
+ Wai. httpVersion = HttpVersion 1 1 ,
263
+ Wai. rawPathInfo =
264
+ LByteString. toStrict
265
+ . Builder. toLazyByteString
266
+ $ encodePath pathSegments [] ,
267
+ Wai. rawQueryString = case query of
268
+ [] -> " "
269
+ _ -> renderQuery True query,
270
+ Wai. requestHeaders =
271
+ sort
272
+ . foldMap
273
+ ( \ (hName, hValues) ->
274
+ hValues <&> \ hValue ->
275
+ (CI. map Text. encodeUtf8 hName, Text. encodeUtf8 hValue)
276
+ )
277
+ . HashMap. toList
278
+ $ HalRequest. multiValueHeaders req,
279
+ Wai. isSecure = True ,
280
+ Wai. remoteHost = sourceHost,
281
+ Wai. pathInfo = pathSegments,
282
+ Wai. queryString = query,
283
+ Wai. requestBody = body,
284
+ Wai. vault = vault opts,
285
+ Wai. requestBodyLength =
286
+ Wai. KnownLength
287
+ . fromIntegral
288
+ . LByteString. length
289
+ $ HalRequest. body req,
290
+ Wai. requestHeaderHost = getHeader hHost req,
291
+ Wai. requestHeaderRange = getHeader hRange req,
292
+ Wai. requestHeaderReferer = getHeader hReferer req,
293
+ Wai. requestHeaderUserAgent = getHeader hUserAgent req
294
+ }
289
295
290
- -- | Unpack a lazy 'BL.ByteString' into its chunks, and return an IO
291
- -- action which returns each chunk in sequence, and returns 'B.empty'
292
- -- forever after the bytestring is exhausted.
293
- returnChunks :: BL. ByteString -> IO (IO B. ByteString )
296
+ -- | Unpack a lazy 'LByteString.ByteString' into its chunks, and
297
+ -- return an IO action which returns each chunk in sequence, and
298
+ -- returns 'ByteString.empty' forever after the bytestring is
299
+ -- exhausted.
300
+ returnChunks :: LByteString. ByteString -> IO (IO ByteString. ByteString )
294
301
returnChunks bs = do
295
- chunkRef <- IORef. newIORef $ BL . toChunks bs
302
+ chunkRef <- IORef. newIORef $ LByteString . toChunks bs
296
303
pure . IORef. atomicModifyIORef' chunkRef $
297
304
\ case
298
305
[] -> mempty
299
306
(ch : chs) -> (chs, ch)
300
307
301
308
constructQuery :: HashMap Text [Text ] -> Query
302
- constructQuery = foldMap expandParamList . H . toList
309
+ constructQuery = foldMap expandParamList . HashMap . toList
303
310
where
304
311
expandParamList :: (Text , [Text ]) -> [QueryItem ]
305
312
expandParamList (param, values) =
@@ -309,7 +316,9 @@ constructQuery = foldMap expandParamList . H.toList
309
316
310
317
getHeader :: HeaderName -> HalRequest. ProxyRequest a -> Maybe ByteString
311
318
getHeader h =
312
- fmap T. encodeUtf8 . H. lookup (CI. map T. decodeUtf8 h) . HalRequest. headers
319
+ fmap Text. encodeUtf8
320
+ . HashMap. lookup (CI. map Text. decodeUtf8 h)
321
+ . HalRequest. headers
313
322
314
323
-- | Convert a WAI 'Wai.Response' into a hal
315
324
-- 'HalResponse.ProxyResponse'.
@@ -326,7 +335,7 @@ fromWaiResponse opts (Wai.ResponseBuilder status headers builder) =
326
335
. addHeaders headers
327
336
. HalResponse. response status
328
337
. createProxyBody opts (getContentType headers)
329
- . BL . toStrict
338
+ . LByteString . toStrict
330
339
$ Builder. toLazyByteString builder
331
340
fromWaiResponse opts (Wai. ResponseStream status headers stream) = do
332
341
builderRef <- IORef. newIORef mempty
@@ -340,19 +349,19 @@ fromWaiResponse opts (Wai.ResponseRaw _ resp) = fromWaiResponse opts resp
340
349
readFilePart :: FilePath -> Maybe Wai. FilePart -> IO ByteString
341
350
readFilePart path mPart = withFile path ReadMode $ \ h -> do
342
351
case mPart of
343
- Nothing -> B . hGetContents h
352
+ Nothing -> ByteString . hGetContents h
344
353
Just (Wai. FilePart offset count _) -> do
345
354
hSeek h AbsoluteSeek offset
346
- B . hGet h $ fromIntegral count
355
+ ByteString . hGet h $ fromIntegral count
347
356
348
357
createProxyBody :: Options -> MediaType -> ByteString -> HalResponse. ProxyBody
349
358
createProxyBody opts contentType body =
350
359
HalResponse. ProxyBody
351
- { HalResponse. contentType = T . decodeUtf8 $ renderHeader contentType,
360
+ { HalResponse. contentType = Text . decodeUtf8 $ renderHeader contentType,
352
361
HalResponse. serialized =
353
362
if isBase64Encoded
354
- then T . decodeUtf8 $ B64 . encode body
355
- else T . decodeUtf8 body,
363
+ then Text . decodeUtf8 $ Base64 . encode body
364
+ else Text . decodeUtf8 body,
356
365
HalResponse. isBase64Encoded
357
366
}
358
367
where
@@ -364,8 +373,8 @@ addHeaders headers response = foldl' addHeader response headers
364
373
where
365
374
addHeader r (hName, hValue) =
366
375
HalResponse. addHeader
367
- (T . decodeUtf8 $ CI. original hName)
368
- (T . decodeUtf8 hValue)
376
+ (Text . decodeUtf8 $ CI. original hName)
377
+ (Text . decodeUtf8 hValue)
369
378
r
370
379
371
380
-- | Try to find the content-type of a response, given the response
0 commit comments