Open3
Reading "Real World HTTP" in Rust
Http の勉強のため「Real World HTTP 第2版」を購入した。サンプルコードは Go で書かれているが、Rust で書いてみる。
第1章のシンプルなエコーサーバー。
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
fn main() {
let port = ":18888";
let listener =
TcpListener::bind(format!("127.0.0.1{}", port)).expect("Failed to bind connection");
eprintln!("Listening to... {}", listener.local_addr().unwrap());
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_connection(stream);
}
}
fn handle_connection(mut stream: TcpStream) {
let mut buffer = [0; 1024];
let _size = stream.read(&mut buffer).unwrap();
let req = String::from_utf8_lossy(&buffer);
eprintln!("{}", req);
let response = "HTTP/1.1 200 OK\r\n\r\n<html><body>hello</body></html>";
let _size = stream
.write(response.as_bytes())
.expect("Failed to write to stream");
stream.flush().expect("Failed to flush");
}
標準ライブラリ TcpListener
TcpSteram
をそのまま扱うのでも勉強になりそうだが、lightweight なライブラリを探してみたら tiny_http という crate があった。こんな感じで書ける。
/// Simple echo server using `tiny_http` crate
use tiny_http::{Response, Server};
fn main() {
let addr = "0.0.0.0:18888";
let server = Server::http(addr).expect("Failed to initiate server");
for req in server.incoming_requests() {
println!(
"{:?} {:?} {:?}",
req.http_version(),
req.method(),
req.url()
);
for header in req.headers() {
println!("{} {}", header.field, header.value);
}
let res = Response::from_string("Hello");
req.respond(res).unwrap();
}
}