Skip to main content

ServerConn

Struct ServerConn 

Source
pub struct ServerConn { /* private fields */ }
Expand description

The server side of one HTTP/1.1 connection: a sans-IO state machine.

The connection owns a bounded input buffer. The caller moves bytes between it and the socket: input in through feed (or read_buf + commit to read straight into the buffer), events out through poll, responses out through respond into a caller-owned Vec<u8>.

Requests are handled one at a time, in order. Keep-alive is automatic: after a response is finished the next request (possibly already buffered, when the client pipelines) is parsed on the next poll. A connection that must close (the client asked, HTTP/1.0 without keep-alive, the response was sent before the request body was read, or a parse error) reports ServerEvent::Closed once its last response is written.

Steady state allocates nothing: the input buffer and the field index are reused across requests.

§Examples

use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let mut out = Vec::new();
// Two pipelined requests in one read.
let _ = conn.feed(b"GET /a HTTP/1.1\r\nHost: x\r\n\r\nGET /b HTTP/1.1\r\nHost: x\r\n\r\n");
let mut paths = Vec::new();
loop {
    match conn.poll().unwrap() {
        ServerEvent::Request(req) => paths.push(req.path().to_string()),
        ServerEvent::RequestEnd => conn.respond(&Response::text(200, "ok"), &mut out).unwrap(),
        ServerEvent::NeedInput => break,
        other => panic!("{other:?}"),
    }
}
assert_eq!(paths, ["/a", "/b"]);

Implementations§

Source§

impl ServerConn

Source

pub fn new() -> Self

A connection with the default Limits.

§Examples
let conn = http_net::ServerConn::new();
assert!(conn.request().is_none());
Source

pub fn with_limits(limits: Limits) -> Self

A connection enforcing limits.

§Examples
use http_net::{HttpError, Limits, ServerConn};

let mut conn = ServerConn::with_limits(Limits::new().with_max_body(4));
let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 5\r\n\r\n");
assert_eq!(conn.poll().unwrap_err(), HttpError::BodyTooLarge);
Source

pub fn with_buffer(storage: Vec<u8>, limits: Limits) -> Self

A connection enforcing limits that reads into storage, for drivers that pool buffers: its capacity is used up to Limits::buffer_capacity, its contents are ignored. Give it back with into_buffer.

§Examples
use http_net::{Limits, ServerConn, ServerEvent};

let pooled: Vec<u8> = Vec::with_capacity(8192);
let mut conn = ServerConn::with_buffer(pooled, Limits::new());
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
let back = conn.into_buffer();
assert!(back.capacity() >= 8192);
Source

pub fn limits(&self) -> &Limits

The limits this connection enforces.

§Examples
assert_eq!(http_net::ServerConn::new().limits(), &http_net::Limits::new());
Source

pub fn feed(&mut self, bytes: &[u8]) -> usize

Copies as much of bytes into the input buffer as fits and returns how many bytes were taken. Fewer than bytes.len() means the buffer is full: poll until it asks for input, then feed the rest.

§Examples
let mut conn = http_net::ServerConn::new();
assert_eq!(conn.feed(b"GET / HTTP/1.1\r\n"), 16);
Source

pub fn read_buf(&mut self) -> &mut [u8] ⓘ

Spare space at the end of the input buffer, for reading from a socket without an intermediate copy. Follow with commit. It is empty only when the buffer is full of input the parser has not been asked to process yet; poll first.

§Examples
let mut conn = http_net::ServerConn::new();
let spare = conn.read_buf();
let msg = b"GET / HTTP/1.1\r\nHost: a\r\n\r\n";
spare[..msg.len()].copy_from_slice(msg);
conn.commit(msg.len());
assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::Request(_))));
Source

pub fn commit(&mut self, n: usize)

Records that n bytes were written into read_buf. An n larger than the slice read_buf returned is clamped to its length: committing bytes that were not written would hand stale buffer contents to the parser.

§Examples
let mut conn = http_net::ServerConn::new();
conn.read_buf()[0] = b'G';
conn.commit(1);
assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::NeedInput)));
Source

pub fn feed_eof(&mut self)

Records that the peer closed its sending side. A connection idle between requests then reports ServerEvent::Closed; one in the middle of a request reports HttpError::UnexpectedEof.

§Examples
let mut conn = http_net::ServerConn::new();
conn.feed_eof();
assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::Closed)));
Source

pub fn poll(&mut self) -> Result<ServerEvent<'_>, HttpError>

Advances the parser and reports what happened. Call it until it returns ServerEvent::NeedInput, ServerEvent::AwaitingResponse, ServerEvent::Upgraded, or ServerEvent::Closed.

§Errors

Any HttpError parse error. The connection is then finished: send one error response (see HttpError::status) with respond, flush, and close. It is written as an answer to a GET, or, once a HEAD request line has been read, to a HEAD, without content.

§Examples
use http_net::{HttpError, ServerConn};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n folded\r\n\r\n");
assert_eq!(conn.poll().unwrap_err(), HttpError::ObsFold);
Source

pub fn request(&self) -> Option<RequestHead<'_>>

The current request’s head, from its arrival until the poll after its response is finished (still available after an upgrade).

§Examples
use http_net::{ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"PUT /f HTTP/1.1\r\nHost: a\r\nContent-Length: 1\r\n\r\nz");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
assert_eq!(conn.request().unwrap().path(), "/f");
Source

pub fn is_upgraded(&self) -> bool

Whether a 101 Switching Protocols (or a 2xx to CONNECT) was sent and the connection now belongs to another protocol.

§Examples
assert!(!http_net::ServerConn::new().is_upgraded());
Source

pub fn remaining_input(&self) -> &[u8] ⓘ

Input that arrived after the last message this connection parsed: after ServerEvent::Upgraded, the first bytes of the new protocol.

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\nConnection: upgrade\r\nUpgrade: x\r\n\r\n\x81\x00");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
assert!(matches!(conn.poll().unwrap(), ServerEvent::RequestEnd));
conn.respond(&Response::switching_protocols("x"), &mut Vec::new()).unwrap();
assert!(matches!(conn.poll().unwrap(), ServerEvent::Upgraded));
assert_eq!(conn.remaining_input(), b"\x81\x00");
Source

pub fn respond( &mut self, response: &Response, out: &mut Vec<u8>, ) -> Result<(), HttpError>

Writes response for the current request into out.

With a full body the response is complete. With a streamed body (Response::chunked, Response::content_length) follow with send_body and end_body. After a parse error, one response may still be sent; it is marked connection: close.

§Errors
§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"HEAD / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
conn.respond(&Response::text(200, "hello"), &mut out).unwrap();
// HEAD: the length is announced, the body is not sent.
assert!(out.windows(17).any(|w| w == b"content-length: 5"));
assert!(out.ends_with(b"\r\n\r\n"));
Source

pub fn respond_with_date( &mut self, response: &Response, date: &HttpDate, out: &mut Vec<u8>, ) -> Result<(), HttpError>

As respond, adding date: <date> unless the response set its own date field. Keep a DateCache per driver thread and pass cache.update(now): the value is reformatted once per second, not once per response.

§Errors

As respond.

§Examples
use http_net::{DateCache, Response, ServerConn, ServerEvent};

let mut dates = DateCache::new();
let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
conn.respond_with_date(&Response::new(204), dates.update(784_111_777), &mut out)?;
assert!(out.windows(35).any(|w| w == b"date: Sun, 06 Nov 1994 08:49:37 GMT"));
Source

pub fn respond_head_only( &mut self, response: &Response, out: &mut Vec<u8>, ) -> Result<BodyPlan, HttpError>

As respond, but writes only the head: for a full-body response the caller then sends Response::body_bytes itself, so head and body can leave in one vectored write (write_vectored) without the body being copied into out. The returned BodyPlan says what follows:

§Errors

As respond; nothing is written on error.

§Examples
use http_net::{BodyPlan, Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET /big HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll()?, ServerEvent::RequestEnd) {}
let response = Response::new(200).body(vec![b'x'; 64 * 1024]);
let mut head = Vec::new();
let plan = conn.respond_head_only(&response, &mut head)?;
assert_eq!(plan, BodyPlan::Raw);
assert!(head.ends_with(b"content-length: 65536\r\n\r\n"));
// Send `head` and `response.body_bytes()` together, e.g. with
// `std::io::Write::write_vectored`.
assert_eq!(response.body_bytes().map(<[u8]>::len), Some(64 * 1024));
Source

pub fn send_informational( &mut self, interim: &Response, out: &mut Vec<u8>, ) -> Result<(), HttpError>

Writes an interim (1xx) response other than 100 and 101, for example 103 Early Hints with link fields, before the final response. It may be sent more than once, for any request method, at any point before the final response starts (RFC 9110 section 15.2), but never to an HTTP/1.0 client. Only the status and the fields are written; an interim response has no body and does not change the connection.

§Errors

The first error recorded by the builder; HttpError::InvalidStatus unless the status is in 102..=199; HttpError::BodyNotAllowed for a body; HttpError::InterimNotAllowed for an HTTP/1.0 request or once the final response has started; HttpError::InvalidState when there is no request (or after a parse error, an upgrade, or the end of the connection).

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
let hints = Response::new(103).header("link", "</style.css>; rel=preload; as=style");
conn.send_informational(&hints, &mut out)?;
conn.respond(&Response::text(200, "page"), &mut out)?;
assert!(out.starts_with(b"HTTP/1.1 103 Early Hints\r\nlink: </style.css>"));
Source

pub fn set_keep_alive(&mut self, keep: bool)

Stops (false) or allows (true) keep-alive. With false the current response, or the next one if it has not started, carries connection: close, and the connection ends after it: the gentlest way to shed load or to cap requests per connection. If the current response has already been written, the connection ends after it. true cannot keep open a connection the protocol requires to close (the client asked, or body bytes were left unread). A 101 or a 2xx to CONNECT hands the connection over regardless.

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
conn.set_keep_alive(false);
let mut out = Vec::new();
conn.respond(&Response::new(204), &mut out).unwrap();
assert!(out.windows(17).any(|w| w == b"connection: close"));
assert!(matches!(conn.poll().unwrap(), ServerEvent::Closed));
Source

pub fn keep_alive(&self) -> bool

Whether the connection can stay open after the current exchange, as far as is known now: keep-alive is allowed (see set_keep_alive) and neither the request, the response, nor an error requires a close.

§Examples
use http_net::{ServerConn, ServerEvent};

let mut conn = ServerConn::new();
assert!(conn.keep_alive());
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\nConnection: close\r\n\r\n");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
assert!(!conn.keep_alive());
Source

pub fn requests_served(&self) -> u64

The number of responses completed on this connection (full-body responses when written, streamed ones at end_body), so a driver can cap requests per connection.

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
assert_eq!(conn.requests_served(), 0);
conn.respond(&Response::new(204), &mut Vec::new()).unwrap();
assert_eq!(conn.requests_served(), 1);
Source

pub fn progress(&self) -> Progress

The connection’s phase, for header-read, request, and response deadlines. Progress::Head starts at the first byte of a request, so idle keep-alive time (Idle) is never counted against a request.

§Examples
use http_net::{Progress, Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 4\r\n\r\nab");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
assert!(matches!(conn.poll().unwrap(), ServerEvent::Body(_)));
assert!(matches!(conn.poll().unwrap(), ServerEvent::NeedInput));
assert_eq!(conn.progress(), Progress::Body);
let _ = conn.feed(b"cd");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
assert_eq!(conn.progress(), Progress::AwaitingResponse);
conn.respond(&Response::new(200).chunked(), &mut Vec::new()).unwrap();
assert_eq!(conn.progress(), Progress::WritingBody);
conn.end_body(&mut Vec::new()).unwrap();
assert_eq!(conn.progress(), Progress::Idle);
Source

pub fn set_report_trailers(&mut self, report: bool)

When true, a request’s trailer fields are kept (bounded by Limits::max_trailer_fields and Limits::max_trailer_bytes) and reported as ServerEvent::Trailers just before ServerEvent::RequestEnd. When false (the default) they are validated and discarded. Trailers never change how a message is framed either way.

§Examples
use http_net::{ServerConn, ServerEvent};

let mut conn = ServerConn::new();
conn.set_report_trailers(true);
let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n2\r\nhi\r\n0\r\nDigest: sha-256=x\r\n\r\n");
let mut digest = None;
loop {
    match conn.poll().unwrap() {
        ServerEvent::Trailers(t) => digest = t.clone().find(|(n, _)| n.eq_ignore_ascii_case("digest")).map(|(_, v)| v.to_vec()),
        ServerEvent::RequestEnd => break,
        _ => {}
    }
}
assert_eq!(digest.as_deref(), Some(&b"sha-256=x"[..]));
Source

pub fn reset(&mut self)

Returns the connection to its initial state for a new socket, keeping the buffer and field-index allocations (and the limits, set_report_trailers, and set_wipe settings). Everything per connection starts over: buffered input, the request in progress, keep-alive (allowed again), and the request count. With wiping on, the whole buffer is zeroed first.

§Examples
use http_net::{Progress, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\nGET /next");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
conn.reset(); // the socket closed; reuse the object for the next one
assert_eq!(conn.progress(), Progress::Idle);
assert!(conn.remaining_input().is_empty());
Source

pub fn into_buffer(self) -> Vec<u8> ⓘ

Gives the input buffer’s storage back (for a pool), wiped first when set_wipe is on.

§Examples
let conn = http_net::ServerConn::new();
assert_eq!(conn.into_buffer().capacity(), 0); // nothing was ever buffered
Source

pub fn shrink_idle(&mut self) -> bool

Frees the input buffer and the field indexes while the connection is idle between requests with nothing buffered, so thousands of idle keep-alive connections cost only their struct size. Returns whether memory was released; the next input allocates again.

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
assert!(!conn.shrink_idle()); // a request is in progress
assert!(matches!(conn.poll().unwrap(), ServerEvent::RequestEnd));
conn.respond(&Response::new(204), &mut Vec::new()).unwrap();
assert!(matches!(conn.poll().unwrap(), ServerEvent::NeedInput));
assert!(conn.shrink_idle());
Source

pub fn set_wipe(&mut self, wipe: bool)

When true, the bytes of every finished request (head, body, and framing) are zeroed before the buffer is reused, stale copies left by compaction are zeroed, and the whole buffer is zeroed on reset, into_buffer, and drop, so credentials do not linger in memory between requests. Costs a memset of each request’s bytes (about 11 ns per KiB, measured). Off by default.

§Examples
let mut conn = http_net::ServerConn::new();
conn.set_wipe(true);
Source

pub fn send_continue(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError>

Writes HTTP/1.1 100 Continue into out: the answer to RequestHead::expects_continue that tells the client to send the body.

RFC 9110 section 10.1.1 requires a server that receives Expect: 100-continue to send either this or a final response before waiting for the body; clients otherwise stall (curl for one second, some indefinitely). Call it after ServerEvent::Request, once the head has been judged acceptable.

§Errors

HttpError::InterimNotAllowed for an HTTP/1.0 request (RFC 9110 section 15.2 forbids any 1xx to an HTTP/1.0 client), once a body byte has been read or the whole body has arrived, once a response has started, or when 100 Continue was already sent for this request; HttpError::InvalidState when no request is waiting for its body (none has arrived, or the connection failed, closed, or upgraded).

§Examples
use http_net::{ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"PUT /f HTTP/1.1\r\nHost: a\r\nExpect: 100-continue\r\nContent-Length: 2\r\n\r\n");
let ServerEvent::Request(req) = conn.poll()? else { unreachable!() };
assert!(req.expects_continue());
let mut out = Vec::new();
conn.send_continue(&mut out)?;
assert_eq!(out, b"HTTP/1.1 100 Continue\r\n\r\n");
Source

pub fn send_body( &mut self, data: &[u8], out: &mut Vec<u8>, ) -> Result<(), HttpError>

Writes body bytes of a streamed response into out. For a HEAD request the bytes are dropped.

§Errors

HttpError::BodyLengthMismatch past the declared Response::content_length; HttpError::InvalidState when no streamed response is in progress.

§Examples
use http_net::{Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET /log HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
conn.respond(&Response::new(200).chunked(), &mut out).unwrap();
conn.send_body(b"line 1\n", &mut out).unwrap();
conn.end_body(&mut out).unwrap();
assert!(out.ends_with(b"7\r\nline 1\n\r\n0\r\n\r\n"));
Source

pub fn end_body(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError>

Ends a streamed response body (the last chunk for chunked encoding).

§Errors

HttpError::BodyLengthMismatch when fewer bytes than the declared length were sent; HttpError::InvalidState when no streamed response is in progress.

§Examples
use http_net::{HttpError, Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
conn.respond(&Response::new(200).content_length(3), &mut out).unwrap();
conn.send_body(b"ab", &mut out).unwrap();
assert_eq!(conn.end_body(&mut out), Err(HttpError::BodyLengthMismatch));
Source

pub fn end_body_with_trailers( &mut self, trailers: &[(&str, &[u8])], out: &mut Vec<u8>, ) -> Result<(), HttpError>

Ends a streamed chunked body with a trailer section: the last chunk, then trailers as fields. Every field is validated before anything is written.

Trailers are optional metadata a recipient may discard (RFC 9110 section 6.5), so when the body could not be chunked (an HTTP/1.0 client forced a close-delimited body) or is not sent at all (HEAD), they are dropped with it and the call still succeeds: the handler does not need to know which framing the client forced.

§Errors

HttpError::TrailerNotAllowed for a field RFC 9110 section 6.5.1 keeps out of trailers (framing, routing, authentication, request modifiers, response control, content handling: content-length, host, authorization, set-cookie, content-type, date, and the rest of the list in docs/API.md) or for a body declared with Response::content_length; the field errors of Response::header; HttpError::BodyLengthMismatch and HttpError::InvalidState as for end_body.

§Examples
use http_net::{HttpError, Response, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET /data HTTP/1.1\r\nHost: a\r\nTE: trailers\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
conn.respond(&Response::new(200).chunked(), &mut out)?;
conn.send_body(b"rows", &mut out)?;
assert_eq!(
    conn.end_body_with_trailers(&[("content-type", b"text/csv")], &mut out),
    Err(HttpError::TrailerNotAllowed)
);
conn.end_body_with_trailers(&[("server-timing", b"db;dur=53")], &mut out)?;
assert!(out.ends_with(b"4\r\nrows\r\n0\r\nserver-timing: db;dur=53\r\n\r\n"));
Source§

impl ServerConn

Source

pub fn write_head<O: Output + ?Sized>( &mut self, head: &ResponseHeadRef<'_>, date: Option<&HttpDate>, out: &mut O, ) -> Result<BodyPlan, HttpError>

Writes a response head described by borrowed data into any Output and says how to send the body. Nothing is allocated; the validation, framing fields, connection handling, and state changes are those of respond, and the bytes are the same as respond would write for the equivalent Response. date, when given and the fields set no date, is written as date: <date>.

After BodyPlan::Raw write the OutgoingBody::Full bytes yourself (for example with one vectored write of head and body); the response then counts as complete. After BodyPlan::Stream use send_body_into and end_body_into (or the Vec versions).

§Errors

As respond, with the field errors of Response::header for fields and those of Response::switching_protocols for upgrade (HttpError::InvalidHeaderValue when it is not a protocol token, HttpError::UpgradeNotOffered for h2c or a protocol the request did not offer). An upgrade on a status other than 101, or a 101 without one, is HttpError::InvalidState. Nothing is written on error.

§Examples
use http_net::{BodyPlan, OutgoingBody, ResponseHeadRef, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET /app.js HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}

let body: &[u8] = b"console.log(1)";
let fields: &[(&str, &[u8])] = &[("content-type", b"text/javascript")];
let head = ResponseHeadRef::new(200, fields, OutgoingBody::Full(body.len() as u64));
let mut out = Vec::with_capacity(256);
let plan = conn.write_head(&head, None, &mut out)?;
assert_eq!(plan, BodyPlan::Raw);
assert_eq!(out, b"HTTP/1.1 200 OK\r\ncontent-length: 14\r\ncontent-type: text/javascript\r\n\r\n");
out.extend_from_slice(body); // or one vectored write of both
Source

pub fn respond_into<O: Output + ?Sized>( &mut self, response: &Response, date: Option<&HttpDate>, out: &mut O, ) -> Result<(), HttpError>

respond into any Output, with an optional date as in respond_with_date. A full body is written after the head; a streamed one continues with send_body_into and end_body_into.

§Errors

As respond.

§Examples
use http_net::{Output, Response, ServerConn, ServerEvent};

/// A bounded output that refuses to grow past its capacity.
struct Slab { buf: [u8; 512], len: usize, overflow: bool }

impl Output for Slab {
    fn put(&mut self, bytes: &[u8]) {
        match self.buf.get_mut(self.len..self.len + bytes.len()) {
            Some(dst) => {
                dst.copy_from_slice(bytes);
                self.len += bytes.len();
            }
            None => self.overflow = true, // the owner closes the connection
        }
    }
}

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut slab = Slab { buf: [0; 512], len: 0, overflow: false };
conn.respond_into(&Response::text(200, "hi"), None, &mut slab)?;
assert!(!slab.overflow);
assert!(slab.buf[..slab.len].ends_with(b"\r\n\r\nhi"));
Source

pub fn send_body_into<O: Output + ?Sized>( &mut self, data: &[u8], out: &mut O, ) -> Result<(), HttpError>

send_body into any Output.

§Errors

As send_body.

§Examples
use http_net::{BodyPlan, OutgoingBody, ResponseHeadRef, ServerConn, ServerEvent};

let mut conn = ServerConn::new();
let _ = conn.feed(b"GET /log HTTP/1.1\r\nHost: a\r\n\r\n");
while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
let mut out = Vec::new();
let head = ResponseHeadRef::new(200, &[], OutgoingBody::Chunked);
assert_eq!(conn.write_head(&head, None, &mut out)?, BodyPlan::Stream);
conn.send_body_into(b"line\n", &mut out)?;
conn.end_body_into(&[], &mut out)?;
assert!(out.ends_with(b"5\r\nline\n\r\n0\r\n\r\n"));
Source

pub fn end_body_into<O: Output + ?Sized>( &mut self, trailers: &[(&str, &[u8])], out: &mut O, ) -> Result<(), HttpError>

Ends a streamed body into any Output, with trailers (empty for none): end_body and end_body_with_trailers in one.

§Errors

As end_body_with_trailers.

§Examples

See send_body_into.

Trait Implementations§

Source§

impl Debug for ServerConn

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ServerConn

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.