use bufio; use fmt; use io; use net::dial; use net::uri; use net; use os; type context = struct { conn: io::handle, file: bufio::bufstream, buf: []u8, }; // Performs an HTTP [[request]] with the given [[client]]. The request is // performed synchronously; this function blocks until the server has returned // the response status and all HTTP headers associated with the response. export fn do(client: *client, req: *request) (response | error) = { let ctx = context { buf = alloc([0...], os::BUFSIZ), ... }; defer free(ctx.buf); const conn = dial::dial_uri("tcp", req.target)?; ctx.file = bufio::buffered(conn, [], ctx.buf); bufio::setflush(&ctx.file, []); fmt::fprintf(&ctx.file, "{} ", req.method)?; // TODO: Support other request-targets than origin-form let target = uri_origin_form(req.target); uri::fmt(&ctx.file, &target)?; fmt::fprintf(&ctx.file, " HTTP/1.1\r\n")?; // TODO: Handle Content-Length and Transfer-Encoding chunked/gzip // properly write_header(&ctx.file, &req.header)?; fmt::fprintf(&ctx.file, "\r\n")?; bufio::flush(&ctx.file)?; match (req.body) { case void => yield; case let body: io::handle => // Copy to conn directly so we can use sendfile(2) if // appropriate io::copy(conn, body)?; }; // TODO: Parse resposne return response { body = conn, ... }; };