Skip to content

Commit 90ee81d

Browse files
Allow setting the request body (non-streamingly)
1 parent 13768a2 commit 90ee81d

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

libraries/common/io/requests.effekt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import stream
22
import io
33
import io/error
44
import stringbuffer
5+
import bytearray
56

67
// Async iterables
78
// ---------------
@@ -33,6 +34,7 @@ interface RequestBuilder {
3334
def port(port: Int): Unit
3435
def protocol(proto: Protocol): Unit
3536
def header(key: String, value: String): Unit
37+
def body{ writer: => Unit / emit[Byte] }: Unit
3638
}
3739
interface ResponseReader {
3840
def status(): Int
@@ -123,10 +125,18 @@ namespace jsNode {
123125
"""
124126

125127
extern type NativeResponse
126-
extern async def runHTTP(obj: js::JsObj): NativeResponse =
127-
jsNode "$effekt.capture(callback => http.request(${obj}, callback).on('error', callback).end())"
128-
extern async def runHTTPS(obj: js::JsObj): NativeResponse =
129-
jsNode "$effekt.capture(callback => https.request(${obj}, callback).on('error', callback).end())"
128+
extern async def runHTTP(obj: js::JsObj, body: ByteArray): NativeResponse =
129+
jsNode """$effekt.capture(callback => {
130+
let req = http.request(${obj}, callback).on('error', callback);
131+
req.write(${body})
132+
req.end()
133+
})"""
134+
extern async def runHTTPS(obj: js::JsObj, body: ByteArray): NativeResponse =
135+
jsNode """$effekt.capture(callback => {
136+
let req = https.request(${obj}, callback).on('error', callback);
137+
req.write(${body})
138+
req.end();
139+
})"""
130140

131141
extern io def statusCode(r: NativeResponse): Int =
132142
jsNode "${r}.statusCode"
@@ -162,17 +172,19 @@ namespace jsNode {
162172
val options = js::empty()
163173
options.js::set("headers", js::empty())
164174
var protocol = HTTPS()
175+
var reqBody: ByteArray = allocate(0)
165176
try body() with RequestBuilder {
166177
def method(m) = resume(options.js::set("method", m.show))
167178
def hostname(n) = resume(options.js::set("hostname", n))
168179
def path(p) = resume(options.js::set("path", p))
169180
def port(p) = resume(options.js::set("port", p))
170181
def header(k, v) = resume(options.js::set("headers", k, v))
171182
def protocol(p) = resume(protocol = p)
183+
def body() = resume{ {wr} => reqBody = collectBytes{ wr } }
172184
}
173185
val res = protocol match {
174-
case HTTP() => runHTTP(options)
175-
case HTTPS() => runHTTPS(options)
186+
case HTTP() => runHTTP(options, reqBody)
187+
case HTTPS() => runHTTPS(options, reqBody)
176188
}
177189
if(res.isError) { println(res.genericShow); do raise(RequestError(), "Request failed") }
178190

@@ -226,6 +238,7 @@ namespace jsWeb {
226238
def port(p) = resume(port = p)
227239
def header(k, v) = resume(options.js::set("headers", k, v))
228240
def protocol(p) = resume(protocol = p)
241+
def body() = resume{ {wr} => options.js::set("body", collectBytes{wr}) }
229242
}
230243
val url = s"${protocol.show}://${hostname}:${port.show}${path}"
231244
val res = run(url, options)

0 commit comments

Comments
 (0)