1
Fork 0
hare-http/net/http/transport.ha
Drew DeVault 946c985a02 Rig out transport handling, finish identity reader
New patch will implement more transports, such as chunked and gzip.
2023-02-11 11:31:07 +01:00

70 lines
1.3 KiB
Hare

use io;
use os;
export type identity_reader = struct {
vtable: io::stream,
conn: io::handle,
buffer: [os::BUFSIZ]u8,
pending: size,
length: size,
};
const identity_reader_vtable = io::vtable {
reader = &identity_read,
...
};
// Creates a new reader that reads data until the response's Content-Length is
// reached; i.e. the null Transport-Encoding.
fn new_identity_reader(
conn: io::handle,
buffer: []u8,
content_length: size,
) *io::stream = {
let rd = alloc(identity_reader {
vtable = &identity_reader_vtable,
conn = conn,
length = content_length,
...
});
rd.buffer[..len(buffer)] = buffer[..];
rd.pending = len(buffer);
return rd;
};
fn identity_read(
s: *io::stream,
buf: []u8,
) (size | io::EOF | io::error) = {
let rd = s: *identity_reader;
assert(rd.vtable == &identity_reader_vtable);
if (rd.length <= 0) {
return io::EOF;
};
if (rd.pending == 0) {
let nread = rd.length;
if (nread > len(rd.buffer)) {
nread = len(rd.buffer);
};
match (io::read(rd.conn, rd.buffer[..nread])?) {
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;
rd.length -= n;
return n;
};