2023-02-10 09:13:30 +00:00
|
|
|
use io;
|
2023-02-10 13:09:23 +00:00
|
|
|
use os;
|
2023-02-10 09:13:30 +00:00
|
|
|
|
|
|
|
// Stores state related to an HTTP response.
|
|
|
|
export type response = struct {
|
2023-02-10 13:09:23 +00:00
|
|
|
// HTTP protocol version (major, minor)
|
|
|
|
version: (uint, uint),
|
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.
|
2023-02-10 13:09:23 +00:00
|
|
|
body: nullable *reader,
|
2023-02-10 09:13:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Frees state associated with an HTTP [[response]].
|
|
|
|
export fn response_finish(resp: *response) void = {
|
|
|
|
header_free(&resp.header);
|
2023-02-10 13:09:23 +00:00
|
|
|
free(resp.reason);
|
|
|
|
};
|
|
|
|
|
|
|
|
export type reader = struct {
|
|
|
|
vtable: io::stream,
|
|
|
|
conn: io::handle,
|
|
|
|
buffer: [os::BUFSIZ]u8,
|
|
|
|
pending: size,
|
|
|
|
};
|
|
|
|
|
|
|
|
const reader_vtable = io::vtable {
|
|
|
|
reader = &reader_read,
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
fn reader_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
|
|
|
|
let rd = s: *reader;
|
|
|
|
if (rd.pending == 0) {
|
|
|
|
match (io::read(rd.conn, rd.buffer)?) {
|
|
|
|
case let n: size =>
|
|
|
|
rd.pending = n;
|
|
|
|
case io::EOF =>
|
|
|
|
return io::EOF;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let n = len(buf);
|
|
|
|
if (n > rd.pending) {
|
|
|
|
n = rd.pending;
|
|
|
|
};
|
|
|
|
buf[..n] = rd.buffer[..n];
|
|
|
|
rd.buffer[..len(rd.buffer) - n] = rd.buffer[n..];
|
|
|
|
rd.pending -= n;
|
|
|
|
return n;
|
2023-02-10 09:13:30 +00:00
|
|
|
};
|