@@ -18,6 +18,7 @@ def each[T](it: EffektAsyncIterator[T]): Unit / emit[T] = {
18
18
// Types
19
19
// -----
20
20
21
+ /// HTTP-style Protocol for requests to send.
21
22
type Protocol { HTTP(); HTTPS() }
22
23
def show(p: Protocol): String = p match {
23
24
case HTTP() => "http"
@@ -27,22 +28,33 @@ def defaultPort(p: Protocol): Int = p match {
27
28
case HTTP() => 80
28
29
case HTTPS() => 443
29
30
}
31
+
32
+ /// HTTP request method
30
33
type Method { GET(); POST() }
31
34
def show(m: Method): String = m match {
32
35
case GET() => "GET"
33
36
case POST() => "POST"
34
37
}
35
38
/// Interface to build HTTP requests.
36
39
///
37
- /// Each of method, hostname, path, port, and protocol must be called at least once!
40
+ /// Each of method, hostname, path, and protocol must be called at least once!
41
+ /// See `uri` for a simple way to fill those.
38
42
interface RequestBuilder {
43
+ /// HTTP request method to use
39
44
def method(method: Method): Unit
45
+ /// (optional) user authentication to use, e.g. user:letmein
40
46
def auth(authStr: String): Unit
47
+ /// hostname of the request, e.g. effekt-lang.org
41
48
def hostname(host: String): Unit
49
+ /// path of the request, e.g. /index.html
42
50
def path(path: String): Unit
51
+ /// port to use, defaults to the standard port of the protocol
43
52
def port(port: Int): Unit
53
+ /// Protocol to use, e.g. HTTP(), HTTPS()
44
54
def protocol(proto: Protocol): Unit
55
+ /// Add the given request header
45
56
def header(key: String, value: String): Unit
57
+ /// Write to the body of the request. May only be called once.
46
58
def body{ writer: => Unit / emit[Byte] }: Unit
47
59
}
48
60
/// Interface returned by HTTP requests.
@@ -279,6 +291,7 @@ namespace jsWeb {
279
291
}
280
292
}
281
293
294
+ /// Sets the values in the `RequestBuilder` from a given URI string.
282
295
def uri(uri: String): Unit / { RequestBuilder, Exception[WrongFormat] } = {
283
296
stringBuffer{
284
297
try parseURI(uri) with URIBuilder {
@@ -300,12 +313,24 @@ def uri(uri: String): Unit / { RequestBuilder, Exception[WrongFormat] } = {
300
313
}
301
314
}
302
315
316
+ def defaultHeaders(): Unit / RequestBuilder = {
317
+ if(internal::backend() != "js-web"){
318
+ do header("user-agent", "Effekt script / Script written in the Effekt language")
319
+ }
320
+ // TODO should we add more?
321
+ }
322
+
303
323
namespace internal {
304
324
extern pure def backend(): String =
305
325
jsNode { "js-node" }
306
326
jsWeb { "js-web" }
307
327
}
308
328
329
+ /// Make a HTTP(S) request on the backend-specific implementation,
330
+ /// then pass the response to the second block parameter to process.
331
+ ///
332
+ /// The Request body is buffered, the response is streaming (as far
333
+ /// as the backend implementation allows).
309
334
def request[R]{ body: => Unit / RequestBuilder }{ res: {ResponseReader} => R }: R / Exception[RequestError] = internal::backend() match {
310
335
case "js-node" => jsNode::request{body}{res}
311
336
case "js-web" => jsWeb::request{body}{res}
@@ -319,10 +344,7 @@ namespace example {
319
344
with def res = request{
320
345
do method(GET())
321
346
uri("https://effekt-lang.org/")
322
- //do hostname("effekt-lang.org")
323
- //do header("user-agent", "Effekt/script") // dont use this on js-web
324
- //do path("/")
325
- // do port(443) // optional
347
+ defaultHeaders()
326
348
}
327
349
if(res.status() == 200){
328
350
println("OK")
0 commit comments