Skip to main content

Module send

Module send 

Source
Expand description

I/O-free coroutine sending an HTTP/1.1 request and receiving its response (RFC 9112).

Serialises the request, drives the read/parse cycle through Http11ReadHeaders for the head and selects a body-reading strategy from the response headers:

StrategyTrigger
ChunkedTransfer-Encoding: chunked
Fixed-lengthContent-Length: <n>
Read-to-EOFNeither header present

§Example

use std::{io::{Read, Write}, net::TcpStream};

use io_http::{
    coroutine::*,
    rfc9110::{request::HttpRequest, send::HttpSendYield},
    rfc9112::send::Http11Send,
};
use url::Url;

let url = Url::parse("http://example.com/").unwrap();
let request = HttpRequest::get(url.clone())
    .header("Host", url.host_str().unwrap())
    .header("Connection", "close");

let mut stream = TcpStream::connect("example.com:80").unwrap();
let mut send = Http11Send::new(request);
let mut arg: Option<&[u8]> = None;
let mut buf = [0u8; 4096];

let (response, keep_alive) = loop {
    match send.resume(arg.take()) {
        HttpCoroutineState::Complete(Ok(out)) => break (out.response, out.keep_alive),
        HttpCoroutineState::Complete(Err(err)) => panic!("{err}"),
        HttpCoroutineState::Yielded(HttpSendYield::WantsRead) => {
            let n = stream.read(&mut buf).unwrap();
            arg = Some(&buf[..n]);
        }
        HttpCoroutineState::Yielded(HttpSendYield::WantsWrite(bytes)) => {
            stream.write_all(&bytes).unwrap();
        }
        HttpCoroutineState::Yielded(HttpSendYield::WantsRedirect { url, .. }) => {
            panic!("redirect to {url}");
        }
    }
};

println!("{}", *response.status);

Structs§

Http11Send
I/O-free coroutine to send an HTTP/1.1 request and receive its response.

Enums§

Http11SendError
Failure causes during the HTTP/1.1 send flow.