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); };