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