1
Fork 0
hare-http/net/http/response.ha

64 lines
1.4 KiB
Hare
Raw Permalink Normal View History

2023-02-10 09:13:30 +00:00
use io;
use os;
use fmt;
use strconv;
export type version = (uint, uint);
2023-02-10 09:13:30 +00:00
// Stores state related to an HTTP response.
export type response = struct {
// HTTP protocol version (major, minor)
version: version,
2023-02-10 09:13:30 +00:00
// The HTTP status for this request as an integer.
status: uint,
// The HTTP status reason phrase.
reason: str,
// The HTTP headers provided by the server.
header: header,
// The response body, if any.
body: nullable *io::stream,
2023-02-10 09:13:30 +00:00
};
// Frees state associated with an HTTP [[response]]. If the response has a
// non-null body, the user must call [[io::close]] prior to calling this
// function.
2023-02-10 09:13:30 +00:00
export fn response_finish(resp: *response) void = {
header_free(&resp.header);
free(resp.reason);
free(resp.body);
2023-02-10 09:13:30 +00:00
};
export fn response_write(
rw: io::handle,
status: uint,
body: (void | io::handle),
header: (str, str)...
) (void | io::error) = {
fmt::fprintfln(rw, "HTTP/1.1 {} {}", status, status_reason(status))?;
let header = header_dup(&header);
defer header_free(&header);
match (body) {
case void => void;
case let body: io::handle =>
match (io::tell(body)) {
case io::error => void;
case let off: io::off =>
header_add(&header, "Content-Length", strconv::i64tos(off));
io::seek(body, 0, io::whence::SET)!;
body = &io::limitreader(body, off: size);
};
};
write_header(rw, &header)?;
fmt::fprintln(rw)!;
match (body) {
case void => void;
case let body: io::handle =>
io::copy(rw, body)!;
};
};