1
Fork 0
hare-http/net/http/do.ha
Drew DeVault 859c8dc06e net::http::do: place buffer on stack
We can afford 4K of stack space
2023-02-10 10:27:14 +01:00

55 lines
1.3 KiB
Hare

use bufio;
use fmt;
use io;
use net::dial;
use net::uri;
use net;
use os;
type context = struct {
conn: io::handle,
file: bufio::bufstream,
buf: [os::BUFSIZ]u8,
};
// Performs an HTTP [[request]] with the given [[client]]. The request is
// performed synchronously; this function blocks until the server has returned
// the response status and all HTTP headers associated with the response.
export fn do(client: *client, req: *request) (response | error) = {
let ctx = context { ... };
assert(req.target.scheme == "http"); // TODO: https
const conn = dial::dial_uri("tcp", req.target)?;
ctx.file = bufio::buffered(conn, [], ctx.buf);
bufio::setflush(&ctx.file, []);
fmt::fprintf(&ctx.file, "{} ", req.method)?;
// TODO: Support other request-targets than origin-form
let target = uri_origin_form(req.target);
uri::fmt(&ctx.file, &target)?;
fmt::fprintf(&ctx.file, " HTTP/1.1\r\n")?;
// TODO: Handle Content-Length and Transfer-Encoding chunked/gzip
// properly
write_header(&ctx.file, &req.header)?;
fmt::fprintf(&ctx.file, "\r\n")?;
bufio::flush(&ctx.file)?;
match (req.body) {
case void =>
yield;
case let body: io::handle =>
// Copy to conn directly so we can use sendfile(2) if
// appropriate
io::copy(conn, body)?;
};
// TODO: Parse resposne
return response {
body = conn,
...
};
};