use io; use os; use fmt; use strconv; export type version = (uint, uint); // Stores state related to an HTTP response. export type response = struct { // HTTP protocol version (major, minor) version: version, // The HTTP status for this request as an integer. status: uint, // The HTTP status reason phrase. reason: str, // The HTTP headers provided by the server. header: header, // The response body, if any. body: nullable *io::stream, }; // Frees state associated with an HTTP [[response]]. If the response has a // non-null body, the user must call [[io::close]] prior to calling this // function. export fn response_finish(resp: *response) void = { header_free(&resp.header); free(resp.reason); free(resp.body); }; export fn response_write( rw: io::handle, status: uint, body: (void | io::handle), header: (str, str)... ) (void | io::error) = { fmt::fprintfln(rw, "HTTP/1.1 {} {}", status, status_reason(status))?; let header = header_dup(&header); defer header_free(&header); match (body) { case void => void; case let body: io::handle => match (io::tell(body)) { case io::error => void; case let off: io::off => header_add(&header, "Content-Length", strconv::i64tos(off)); io::seek(body, 0, io::whence::SET)!; body = &io::limitreader(body, off: size); }; }; write_header(rw, &header)?; fmt::fprintln(rw)!; match (body) { case void => void; case let body: io::handle => io::copy(rw, body)!; }; };