@@ -26,6 +26,7 @@ import Control.Monad.Trans.Control (MonadBaseControl (..))
26
26
import Control.Monad.Trans.Except
27
27
import Data.ByteString.Builder (toLazyByteString )
28
28
import qualified Data.ByteString.Char8 as BS
29
+ import qualified Data.ByteString.Lazy as BL
29
30
import Data.CaseInsensitive
30
31
import Data.Char
31
32
import Data.Foldable (toList )
@@ -36,9 +37,11 @@ import qualified Data.Sequence as Seq
36
37
import Data.String.Conversions
37
38
import Foreign.StablePtr
38
39
import GHC.Generics
40
+ import qualified GHCJS.Buffer as Buffer
39
41
import GHCJS.Foreign.Callback
40
42
import GHCJS.Prim
41
43
import GHCJS.Types
44
+ import JavaScript.TypedArray.ArrayBuffer ( ArrayBuffer )
42
45
import JavaScript.Web.Location
43
46
import Network.HTTP.Media (renderHeader )
44
47
import Network.HTTP.Types
@@ -153,6 +156,7 @@ performXhr xhr burl request = do
153
156
154
157
openXhr xhr (cs $ requestMethod request) (toUrl burl request) True
155
158
setHeaders xhr request
159
+ js_setResponseType xhr " arraybuffer"
156
160
body <- toBody request
157
161
sendXhr xhr body
158
162
takeMVar waiter
@@ -187,6 +191,9 @@ openXhr xhr method url =
187
191
foreign import javascript unsafe " $1.open($2, $3, $4)"
188
192
js_openXhr :: JSXMLHttpRequest -> JSVal -> JSVal -> Bool -> IO ()
189
193
194
+ foreign import javascript unsafe " $1.responseType = $2;"
195
+ js_setResponseType :: JSXMLHttpRequest -> JSString -> IO ()
196
+
190
197
toUrl :: BaseUrl -> Request -> String
191
198
toUrl burl request =
192
199
let pathS = cs $ toLazyByteString $ requestPath request
@@ -217,42 +224,47 @@ setHeaders xhr request = do
217
224
foreign import javascript unsafe " $1.setRequestHeader($2, $3)"
218
225
js_setRequestHeader :: JSXMLHttpRequest -> JSVal -> JSVal -> IO ()
219
226
220
- sendXhr :: JSXMLHttpRequest -> Maybe String -> IO ()
227
+ sendXhr :: JSXMLHttpRequest -> Maybe ArrayBuffer -> IO ()
221
228
sendXhr xhr Nothing = js_sendXhr xhr
222
229
sendXhr xhr (Just body) =
223
- js_sendXhrWithBody xhr (toJSString body)
230
+ js_sendXhrWithBody xhr body
224
231
225
232
foreign import javascript unsafe " $1.send()"
226
233
js_sendXhr :: JSXMLHttpRequest -> IO ()
227
234
228
235
foreign import javascript unsafe " $1.send($2)"
229
- js_sendXhrWithBody :: JSXMLHttpRequest -> JSVal -> IO ()
236
+ js_sendXhrWithBody :: JSXMLHttpRequest -> ArrayBuffer -> IO ()
230
237
231
- toBody :: Request -> IO (Maybe String )
238
+ toBody :: Request -> IO (Maybe ArrayBuffer )
232
239
toBody request = case requestBody request of
233
240
Nothing -> return Nothing
234
- Just (a, _) -> go a
241
+ Just (a, _) -> Just <$> go a
235
242
236
243
where
237
- go :: RequestBody -> IO ( Maybe String )
244
+ go :: RequestBody -> IO ArrayBuffer
238
245
go x = case x of
239
- RequestBodyLBS x -> return $ mBody x
246
+ RequestBodyLBS x -> return $ mBody $ BL. toStrict x
240
247
RequestBodyBS x -> return $ mBody x
241
- RequestBodyBuilder _ x -> return $ mBody $ toLazyByteString x
248
+ RequestBodyBuilder _ x -> return $ mBody $ BL. toStrict $ toLazyByteString x
242
249
RequestBodyStream _ x -> mBody <$> readBody x
243
250
RequestBodyStreamChunked x -> mBody <$> readBody x
244
251
RequestBodyIO x -> x >>= go
245
252
246
- mBody :: ConvertibleStrings a String => a -> Maybe String
247
- mBody x = let y = cs x in if y == " " then Nothing else Just y
253
+ mBody :: BS. ByteString -> ArrayBuffer
254
+ mBody bs = js_bufferSlice offset len $ Buffer. getArrayBuffer buffer
255
+ where
256
+ (buffer, offset, len) = Buffer. fromByteString bs
248
257
258
+ readBody :: ((IO BS. ByteString -> IO () ) -> IO a ) -> IO BS. ByteString
249
259
readBody writer = do
250
260
m <- newIORef mempty
251
261
_ <- writer (\ bsAct -> do
252
262
bs <- bsAct
253
263
modifyIORef m (<> bs))
254
264
readIORef m
255
265
266
+ foreign import javascript unsafe " $3.slice($1, $1 + $2)"
267
+ js_bufferSlice :: Int -> Int -> ArrayBuffer -> ArrayBuffer
256
268
257
269
-- * inspecting the xhr response
258
270
@@ -266,10 +278,10 @@ toResponse xhr = do
266
278
_ -> liftIO $ do
267
279
statusText <- cs <$> getStatusText xhr
268
280
headers <- parseHeaders <$> getAllResponseHeaders xhr
269
- responseText <- cs <$> getResponseText xhr
281
+ response <- getResponse xhr
270
282
pure Response
271
283
{ responseStatusCode = mkStatus status statusText
272
- , responseBody = responseText
284
+ , responseBody = response
273
285
, responseHeaders = Seq. fromList headers
274
286
, responseHttpVersion = http11 -- this is made up
275
287
}
@@ -288,14 +300,19 @@ getAllResponseHeaders xhr =
288
300
foreign import javascript unsafe " $1.getAllResponseHeaders()"
289
301
js_getAllResponseHeaders :: JSXMLHttpRequest -> IO JSVal
290
302
291
- getResponseText :: JSXMLHttpRequest -> IO String
292
- getResponseText xhr = fromJSString <$> js_responseText xhr
293
- foreign import javascript unsafe " $1.responseText"
294
- js_responseText :: JSXMLHttpRequest -> IO JSVal
303
+ getResponse :: JSXMLHttpRequest -> IO BL. ByteString
304
+ getResponse xhr =
305
+ BL. fromStrict
306
+ . Buffer. toByteString 0 Nothing
307
+ . Buffer. createFromArrayBuffer
308
+ <$> js_response xhr
309
+
310
+ foreign import javascript unsafe " $1.response"
311
+ js_response :: JSXMLHttpRequest -> IO ArrayBuffer
295
312
296
313
parseHeaders :: String -> ResponseHeaders
297
314
parseHeaders s =
298
- ( first mk . first strip . second strip . parseHeader) <$>
315
+ first mk . first strip . second strip . parseHeader <$>
299
316
splitOn " \r\n " (cs s)
300
317
where
301
318
parseHeader :: BS. ByteString -> (BS. ByteString , BS. ByteString )
0 commit comments