Initial commit
This commit is contained in:
parent
ea1a5ceb8d
commit
a0bfaef6ba
21
cmd/http/main.ha
Normal file
21
cmd/http/main.ha
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use net::http;
|
||||||
|
use net::ip;
|
||||||
|
use net::uri;
|
||||||
|
use os;
|
||||||
|
|
||||||
|
export fn main() void = {
|
||||||
|
const req = &http::request {
|
||||||
|
method = http::GET,
|
||||||
|
target = &uri::uri {
|
||||||
|
scheme = "http",
|
||||||
|
host = ip::LOCAL_V6,
|
||||||
|
path = "/",
|
||||||
|
...
|
||||||
|
},
|
||||||
|
body = void,
|
||||||
|
...
|
||||||
|
};
|
||||||
|
http::add_header(&req.header, "User-Agent", "Hare test client");
|
||||||
|
http::add_header(&req.header, "Content-Length", "100");
|
||||||
|
http::write_header(os::stdout, &req.header)!;
|
||||||
|
};
|
8
net/http/README
Normal file
8
net/http/README
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
TODO: Flesh me out
|
||||||
|
|
||||||
|
Caveats:
|
||||||
|
|
||||||
|
- No attempt is made to validate that the input for client requests or responses
|
||||||
|
are valid according to the HTTP grammar; such cases will fail when rejected by
|
||||||
|
the other party.
|
||||||
|
- Details indicated by RFC 7230 et al as "obsolete" are not implemented
|
42
net/http/header.ha
Normal file
42
net/http/header.ha
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use io;
|
||||||
|
use fmt;
|
||||||
|
|
||||||
|
// List of HTTP headers.
|
||||||
|
export type header = [](str, str);
|
||||||
|
|
||||||
|
// Adds a given HTTP header, which may be added more than once. The provided
|
||||||
|
// name and value are borrowed from the caller. The provided header name should
|
||||||
|
// be canonicalized by the caller.
|
||||||
|
export fn add_header(head: *header, name: str, val: str) void = {
|
||||||
|
append(head, (name, val));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sets the value of a given HTTP header, removing any previous values. The
|
||||||
|
// provided name and value are borrowed from the caller. The provided header
|
||||||
|
// name should be canonicalized by the caller.
|
||||||
|
export fn set_header(head: *header, name: str, val: str) void = {
|
||||||
|
del_header(head, name);
|
||||||
|
add_header(head, name, val);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Removes an HTTP header from a list of [[header]]. If multiple headers match
|
||||||
|
// the given name, all matching headers are removed.
|
||||||
|
export fn del_header(head: *header, name: str) void = {
|
||||||
|
for (let i = 0z; i < len(head); i += 1) {
|
||||||
|
if (head[i].0 == name) {
|
||||||
|
delete(head[i]);
|
||||||
|
i -= 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Writes a list of HTTP headers to the provided I/O handle in the HTTP wire
|
||||||
|
// format.
|
||||||
|
export fn write_header(sink: io::handle, head: *header) (size | io::error) = {
|
||||||
|
let z = 0z;
|
||||||
|
for (let i = 0z; i < len(head); i += 1) {
|
||||||
|
const (name, val) = head[i];
|
||||||
|
z += fmt::fprintf(sink, "{}: {}\r\n", name, val)?;
|
||||||
|
};
|
||||||
|
return z;
|
||||||
|
};
|
|
@ -0,0 +1,20 @@
|
||||||
|
use io;
|
||||||
|
use net::uri;
|
||||||
|
|
||||||
|
// Stores state related to an HTTP request.
|
||||||
|
export type request = struct {
|
||||||
|
// HTTP request method, e.g. GET
|
||||||
|
method: str,
|
||||||
|
// Request target URI.
|
||||||
|
//
|
||||||
|
// Note that the normal constraints for [[uri::parse]] are not upheld in
|
||||||
|
// the case of a request using the origin-form (e.g. /index.html), i.e.
|
||||||
|
// the scheme field may be empty.
|
||||||
|
target: *uri::uri,
|
||||||
|
|
||||||
|
// List of HTTP request headers.
|
||||||
|
header: header,
|
||||||
|
|
||||||
|
// I/O reader for the request body.
|
||||||
|
body: (io::handle | void),
|
||||||
|
};
|
Loading…
Reference in a new issue