aboutsummaryrefslogtreecommitdiff
path: root/common/js/src/main/scala/http/XhrBackend.scala
blob: 3a791c1c3956994be63fbe3ae2b50a158cb796e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package triad
package http

import org.scalajs.dom.{ErrorEvent, Event, XMLHttpRequest}

import scala.concurrent.{Future, Promise, TimeoutException}
import scala.scalajs.js
import scala.scalajs.js.typedarray.{ArrayBuffer, Int8Array}

trait XhrBackend extends Backend {

  def send(request: Request): Future[Response] = {
    val promise = Promise[Response]
    val xhr = new XMLHttpRequest()

    xhr.open(request.method, request.url)
    xhr.responseType = "arraybuffer"
    for ((name, value) <- request.headers) {
      xhr.setRequestHeader(name, value)
    }

    xhr.send(js.Array(request.body: _*))

    xhr.onload = (e: Event) => {
      val body: Array[Byte] = if (!js.isUndefined(xhr.response)) {
        val buffer = new Int8Array(xhr.response.asInstanceOf[ArrayBuffer])
        buffer.toArray
      } else {
        Array.empty[Byte]
      }

      val response = Response(
        xhr.status,
        Map.empty,
        body
      )
      promise.success(response)
    }

    xhr.onerror = (e: ErrorEvent) => {
      promise.failure(new RuntimeException(s"XHR error: ${e.message}"))
    }
    xhr.ontimeout = (e: Event) => {
      promise.failure(
        new TimeoutException(s"Request timed out: ${xhr.statusText}"))
    }

    promise.future
  }

}