Skip to content

Commit

Permalink
examples: Add simple client and server examples
Browse files Browse the repository at this point in the history
  • Loading branch information
mlalic committed Jun 18, 2015
1 parent 646b597 commit 294c99d
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
75 changes: 75 additions & 0 deletions examples/client_simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! An example of usage of the `solicit::client::SimpleClient` API.
//!
//! This is a simple implementation of an HTTP/2 client, built on top of the API of `solicit::http`
//! that performs all IO in the main thread.

extern crate solicit;

use std::env;
use std::str;

use solicit::http::Response;
use solicit::http::client::CleartextConnector;
use solicit::client::SimpleClient;

fn fetch(host: &str, port: u16, paths: &[String]) -> Vec<Response> {
let mut client = SimpleClient::with_connector(CleartextConnector::with_port(host, port)).unwrap();
paths.iter().map(|path| client.get(path.as_bytes(), &[]).unwrap()).collect()
}

fn main() {
fn print_usage() {
println!("Usage: client_simple <host>[:<port>] <path> [<path>...]");
println!(
"NOTE: The example does not accept URLs, rather the host name and a list of paths");
}

let host = env::args().nth(1);
let paths: Vec<_> = env::args().skip(2).collect();

if host.is_none() || paths.is_empty() {
print_usage();
return;
}
let host = host.unwrap();
// Split off the port, if present
let parts: Vec<_> = host.split(":").collect();
if parts.len() > 2 {
println!("Invalid host!");
print_usage();
return;
}

let (host, port) = if parts.len() == 1 {
(parts[0], 80)
} else {
let port = match str::FromStr::from_str(parts[1]) {
Err(_) => {
println!("Invalid host (invalid port given)");
print_usage();
return;
},
Ok(port) => port,
};
(parts[0], port)
};

let responses = fetch(&host, port, &paths);
for (path, response) in paths.iter().zip(responses) {
println!("Request path: {}", path);

println!(" status == {}", response.status_code().unwrap());
// Dump the headers and the response body to stdout.
// They are returned as raw bytes for the user to do as they please.
// (Note: in general directly decoding assuming a utf8 encoding might not
// always work -- this is meant as a simple example that shows that the
// response is well formed.)
for header in response.headers.iter() {
println!(" {}: {}",
str::from_utf8(&header.0).unwrap(),
str::from_utf8(&header.1).unwrap());
}
println!("");
println!("{}", str::from_utf8(&response.body).unwrap());
}
}
53 changes: 53 additions & 0 deletions examples/server_simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! An example of usage of the `solicit::server::SimpleServer` API.
//!
//! It spawns a new dedicated thread for handling each new HTTP/2 connection (which corresponds to
//! a single TCP connection). Within that thread, all requests that are received are handled
//! sequentially, returning identical dummy "Hello, World!" responses.
//!
//! Only for demonstration purposes.

extern crate solicit;

use std::str;
use std::net::{TcpListener, TcpStream};
use std::thread;

use solicit::http::Response;
use solicit::server::SimpleServer;

fn main() {
fn handle_client(stream: TcpStream) {
let mut server = SimpleServer::new(stream, |req| {
println!("Received request:");
for header in req.headers.iter() {
println!(" {}: {}",
str::from_utf8(&header.0).unwrap(),
str::from_utf8(&header.1).unwrap());
}
println!("Body:\n{}", str::from_utf8(&req.body).unwrap());

// Return a dummy response for every request
Response {
headers: vec![
(b":status".to_vec(), b"200".to_vec()),
(b"x-solicit".to_vec(), b"Hello, World!".to_vec()),
],
body: req.body.to_vec(),
stream_id: req.stream_id,
}
}).unwrap();
while let Ok(_) = server.handle_next() {}
println!("Server done (client disconnected)");
}

let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
println!("Server started on 127.0.0.1:8080...");
println!("Waiting for clients...");
for stream in listener.incoming() {
let stream = stream.unwrap();
println!("New client connected!");
thread::spawn(move || {
handle_client(stream)
});
}
}

0 comments on commit 294c99d

Please sign in to comment.