Skip to content

Commit dc2e4a8

Browse files
some documentation, define default ports
1 parent d9167d3 commit dc2e4a8

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

libraries/common/io/requests.effekt

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,18 @@ def show(p: Protocol): String = p match {
2222
case HTTP() => "http"
2323
case HTTPS() => "https"
2424
}
25+
def defaultPort(p: Protocol): Int = p match {
26+
case HTTP() => 80
27+
case HTTPS() => 443
28+
}
2529
type Method { GET(); POST() }
2630
def show(m: Method): String = m match {
2731
case GET() => "GET"
2832
case POST() => "POST"
2933
}
34+
/// Interface to build HTTP requests.
35+
///
36+
/// Each of method, hostname, path, port, and protocol must be called at least once!
3037
interface RequestBuilder {
3138
def method(method: Method): Unit
3239
def hostname(host: String): Unit
@@ -36,19 +43,28 @@ interface RequestBuilder {
3643
def header(key: String, value: String): Unit
3744
def body{ writer: => Unit / emit[Byte] }: Unit
3845
}
46+
/// Interface returned by HTTP requests.
3947
interface ResponseReader {
48+
/// Gets the response HTTP status code
4049
def status(): Int
50+
51+
/// Returns the body of the response by emitting Bytes
52+
/// May be called at most once.
4153
def body(): Unit / emit[Byte]
54+
55+
/// Get the specified HTTP header, key should be lower-case
4256
def getHeader(key: String): Option[String]
57+
4358
//def headers(): Unit / emit[(String, String)]
4459
}
4560

4661
record RequestError()
47-
4862
// Backend-specific implementations
4963
// --------------------------------
5064

5165
namespace js {
66+
// Async iterators in JS
67+
// ---------------------
5268
extern type AsyncIterator[T]
5369
extern type IterableResult[T]
5470
extern io def nextPromise[T](it: AsyncIterator[T]): Promise[IterableResult[T]] =
@@ -70,13 +86,14 @@ namespace js {
7086
do emit(r.unsafeValue())
7187
}
7288
}
73-
// broken if we resolve a promise inside
89+
// broken if we resolve a promise inside, see issue #1016
7490
// extern def makeAsyncIterator[T](next: => Promise[IterableResult[T]] at {io, async, global}): AsyncIterator[T] =
7591
// js """{ next: () => $effekt.runToplevel((ks,k) => ${next}(ks, k)) }"""
7692

7793
// Native Byte Buffers
7894
// -------------------
7995
extern type NativeBytes
96+
// jsNode "Buffer"
8097
extern pure def length(n: NativeBytes): Int =
8198
js "${n}.length"
8299
extern pure def get(n: NativeBytes, x: Int): Byte =
@@ -116,6 +133,8 @@ namespace js {
116133
js "${obj}[${key}] = ${value};"
117134
extern io def set(obj: JsObj, key1: String, key2: String, value: Any): Unit =
118135
js "${obj}[${key1}][${key2}] = ${value};"
136+
extern io def isSet(obj: JsObj, key: String): Bool =
137+
js "${obj}[${key}] !== undefined"
119138
}
120139

121140
namespace jsNode {
@@ -182,6 +201,7 @@ namespace jsNode {
182201
def protocol(p) = resume(protocol = p)
183202
def body() = resume{ {wr} => reqBody = collectBytes{ wr } }
184203
}
204+
if(not(options.js::isSet("port"))) { options.js::set("port", protocol.defaultPort()) }
185205
val res = protocol match {
186206
case HTTP() => runHTTP(options, reqBody)
187207
case HTTPS() => runHTTPS(options, reqBody)
@@ -230,17 +250,17 @@ namespace jsWeb {
230250
var protocol = HTTPS()
231251
var hostname = ""
232252
var path = "/"
233-
var port = 443
253+
var port = None()
234254
try body() with RequestBuilder {
235255
def method(m) = resume(options.js::set("method", m.show))
236256
def hostname(n) = resume(hostname = n)
237257
def path(p) = resume(path = p)
238-
def port(p) = resume(port = p)
258+
def port(p) = resume(port = Some(p))
239259
def header(k, v) = resume(options.js::set("headers", k, v))
240260
def protocol(p) = resume(protocol = p)
241261
def body() = resume{ {wr} => options.js::set("body", collectBytes{wr}) }
242262
}
243-
val url = s"${protocol.show}://${hostname}:${port.show}${path}"
263+
val url = s"${protocol.show}://${hostname}:${port.getOrElse{ protocol.defaultPort }.show}${path}"
244264
val res = run(url, options)
245265
if(res.isError) { println(res.genericShow); do raise(RequestError(), "Request failed") }
246266

@@ -273,7 +293,7 @@ namespace example {
273293
do hostname("effekt-lang.org")
274294
//do header("user-agent", "Effekt/script") // dont use this on js-web
275295
do path("/")
276-
do port(443)
296+
// do port(443) // optional
277297
}
278298
if(res.status() == 200){
279299
println("OK")

0 commit comments

Comments
 (0)