Archived
3
0
This repository has been archived on 2025-09-02. You can view files and clone it, but cannot push or open issues or pull requests.
Files
zmp24-docs/lib/inferium/examples/start_here.rs
2025-03-06 22:23:23 +01:00

102 lines
4.5 KiB
Rust

// Hello, and welcome to inferium. A performance-oriented small HTTP library written in Rust that
// keeps you (the user) in charge.
// Let's first import some necessary things.
// In inferium - HashMaps are used to store uri parameters and headers.
use std::collections::HashMap;
// TcpStream is needed if we want to connect to the internet.
use std::net::TcpStream;
use inferium::{
// The h1 module contains all the protocol specific things for HTTP/1.(0/1).
h1::{
// ProtocolVariant contains variants with the protocol versions supported in this module:
// - HTTP/1.1
// - HTTP/1.0
ProtocolVariant,
// RequestHead contains headers and the HTTP request headline (method, path, protocol).
RequestHead,
// Response here is a wrapper for a response that can have the following:
// - Headers only
// - Headers and body (with a known length or chunked)
//
// ! The body in the response is not yet collected. It is up to you if you wish to discard
// the connection or receive and collect the response body into some structure.
//
// The same things here go for the Request object which is nearly the same except that the
// headline contains protocol and status instead.
Response,
// Sync client is a stream wrapper that helps us keep track of the open connection and
// perform request/response operations.
//
// The server equivalent is SyncServer.
SyncClient
},
// Header key contains various known header keys, but can also store arbitrary (unknown) header
// key in the OTHER variant.
HeaderKey,
Method,
// StdInet here is a stream wrapper that allows the TcpStream to be used by inferium. There is
// also a unix socket equivalent and some asynchronous io wrappers.
StdInet
};
fn main() {
// Let's first create a connection... nothing weird here.
let conn = StdInet::new(TcpStream::connect("zumepro.cz:80").unwrap());
// And a client...
let mut client = SyncClient::<StdInet>::new(conn);
// Now let's create a request to send
let to_send = RequestHead::new(
// The path here is parsed into an HTTP path object (which also supports parameters)
// I'm using HTTP/1.0 in this example as HTTP/1.1 automatically infers a compatibility with
// chunked encoding (which I'm not even trying to handle here).
Method::GET, "/".parse().unwrap(), ProtocolVariant::HTTP1_0,
HashMap::from([
// All headers are HeaderKey - HeaderValue pairs. We can parse the header value into
// the desired object.
//
// Constructing arbitrary header key is supported using the OTHER variant - however
// it's not recommended as a violation of the HTTP protocol can happen.
//
// If you really want to construct an arbitrary header key - please carefully check
// that all of the symbols are valid.
(HeaderKey::USER_AGENT, "Mozilla/5.0 (inferium)".parse().unwrap()),
(HeaderKey::HOST, "zumepro.cz".parse().unwrap()),
])
);
println!("----------> Sending\n\n{to_send}\n");
// Let's send the request - this is pretty straightforward.
client.send_request(&to_send).unwrap();
// As is receiving a response.
let response = client.receive_response().unwrap();
// Now (as we discussed earlier) - the response can have a body.
// In this example we'll try to handle a basic body with a known size.
let (header, body) = match response {
// Extracting the headers if no body is present.
Response::HeadersOnly(h) => (h, None),
// Extracting both the headers and the body if body is present.
Response::WithSizedBody((h, b)) => (h, Some(b)),
// We will not handle chunked responses in this example.
Response::WithChunkedBody((_, _)) => panic!(),
};
// inferium kindly provides a simple way to print the head of a request/response.
// It will be formatted pretty close to the actual protocol plaintext representation.
println!("----------< Received\n\n{header}\n");
// And finally... if we have a body, we'll print it.
if let Some(mut body) = body {
println!(
"----------< Body\n\n{:?}\n",
// A body is always returned in bytes. It's up to you to decode it however you see fit.
std::str::from_utf8(&mut body.recv_all().unwrap()).unwrap()
);
}
// And you're done. Come on... try to run it.
}