96 lines
2.9 KiB
Hare
96 lines
2.9 KiB
Hare
|
use io;
|
||
|
use net::uri;
|
||
|
|
||
|
export type client = struct {
|
||
|
default_header: header,
|
||
|
default_transport: transport,
|
||
|
};
|
||
|
|
||
|
// Creates a new HTTP [[client]] with the provided User-Agent string.
|
||
|
//
|
||
|
// The HTTP client implements a number of sane defaults, which may be tuned. The
|
||
|
// set of default headers is configured with [[client_default_header]], and the
|
||
|
// default transport behavior with [[client_default_transport]].
|
||
|
//
|
||
|
// TODO: Implement and document the connection pool
|
||
|
//
|
||
|
// The caller must pass the client object to [[client_finish]] to free resources
|
||
|
// associated with this client after use.
|
||
|
export fn newclient(ua: str) client = {
|
||
|
let client = client { ... };
|
||
|
header_add(&client, "User-Agent", ua);
|
||
|
return client;
|
||
|
};
|
||
|
|
||
|
// Frees resources associated with an HTTP [[client]].
|
||
|
export fn client_finish(client: *client) void = {
|
||
|
header_free(&client.default_header);
|
||
|
};
|
||
|
|
||
|
// Returns the default headers used by this HTTP client, so that the user can
|
||
|
// examine or modify the net::http defaults (such as User-Agent or
|
||
|
// Accept-Encoding), or add their own.
|
||
|
export fn client_default_header(client: *client) *header = {
|
||
|
return &client.default_header;
|
||
|
};
|
||
|
|
||
|
// Returns the default [[transport]] configuration used by this HTTP client.
|
||
|
export fn client_default_transport(client: *client) *transport = {
|
||
|
return &client.default_transport;
|
||
|
};
|
||
|
|
||
|
fn uri_origin_form(target: *uri::uri) uri::uri = {
|
||
|
let target = *target;
|
||
|
target.scheme = "";
|
||
|
target.host = "";
|
||
|
target.fragment = "";
|
||
|
target.userinfo = "";
|
||
|
target.port = 0;
|
||
|
if (target.path == "") {
|
||
|
target.path = "/";
|
||
|
};
|
||
|
return target;
|
||
|
};
|
||
|
|
||
|
// Performs a synchronous HTTP GET request with the given client.
|
||
|
export fn get(client: *client, target: *uri::uri) (response | error) = {
|
||
|
const req = new_request(client, GET, target)?;
|
||
|
defer request_finish(&req);
|
||
|
return do(client, &req);
|
||
|
};
|
||
|
|
||
|
// Performs a synchronous HTTP HEAD request with the given client.
|
||
|
export fn head(client: *client, target: *uri::uri) (response | error) = {
|
||
|
const req = new_request(client, HEAD, target)?;
|
||
|
defer request_finish(&req);
|
||
|
return do(client, &req);
|
||
|
};
|
||
|
|
||
|
// Performs a synchronous HTTP POST request with the given client.
|
||
|
//
|
||
|
// If the provided I/O handle is seekable, the Content-Length header is added
|
||
|
// automatically. Otherwise, Transfer-Encoding: chunked will be used.
|
||
|
export fn post(
|
||
|
client: *client,
|
||
|
target: *uri::uri,
|
||
|
body: io::handle,
|
||
|
) (response | error) = {
|
||
|
const req = new_request_body(client, POST, target, body)?;
|
||
|
defer request_finish(&req);
|
||
|
return do(client, &req);
|
||
|
};
|
||
|
|
||
|
// Performs a synchronous HTTP PUT request with the given client.
|
||
|
//
|
||
|
// If the provided I/O handle is seekable, the Content-Length header is added
|
||
|
// automatically. Otherwise, Transfer-Encoding: chunked will be used.
|
||
|
export fn put(
|
||
|
client: *client,
|
||
|
target: *uri::uri,
|
||
|
body: io::handle,
|
||
|
) (response | error) = {
|
||
|
const req = new_request_body(client, PUT, target, body)?;
|
||
|
defer request_finish(&req);
|
||
|
return do(client, &req);
|
||
|
};
|