Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Created April 22, 2024 03:27
Show Gist options
  • Save kujirahand/ecaed8ba83176ed9a3ca438382130997 to your computer and use it in GitHub Desktop.
Save kujirahand/ecaed8ba83176ed9a3ca438382130997 to your computer and use it in GitHub Desktop.
RustでHTTPサーバを実装しよう
use std::io::prelude::*;
use std::net::TcpListener;
// サーバアドレスを指定
const SERVER_ADDRESS: &str = "127.0.0.1:8888";
fn main() {
// HTTPサーバを起動
println!("[HTTPサーバを起動] http://{}", SERVER_ADDRESS);
let listener = TcpListener::bind(SERVER_ADDRESS).unwrap();
// クライアントからの接続を待ち受ける
for stream in listener.incoming() {
println!("クライアントが接続しました。");
// クライアントとの通信を行う
let stream = stream.unwrap();
handle_client(stream);
}
}
fn handle_client(mut stream: std::net::TcpStream) {
// クライアントのリクエストを読み込む --- (*1)
let mut request_buf = [0; 4096];
let size = stream.read(&mut request_buf).unwrap();
let request = String::from_utf8_lossy(&request_buf);
println!("Request: {}B\n{}\n", size, request);
// リクエストを解析する --- (*2)
let request_lines: Vec<&str> = request.lines().collect();
// 一行目のリクエストを取り出してスペースで分割 --- (*3)
let request_line = request_lines[0];
let mut parts = request_line.split_whitespace();
// 結果を取り出す --- (*4)
let method = parts.next().unwrap();
let path = parts.next().unwrap();
let _version = parts.next().unwrap();
println!("Method: {}, Path: {}", method, path);
// ファイルを読み込む --- (*5)
let path = if path == "/" { "/index.html" } else { path };
let fullpath = format!("./html{}", path);
let fullpath = fullpath.replace("..", ""); // セキュリティ対策
println!("Fullpath: {}", fullpath);
// ファイルを読み込む --- (*6)
let response = std::fs::read_to_string(fullpath)
.unwrap_or("404 not found".to_string());
// レスポンスを返す --- (*7)
stream.write(b"HTTP/1.1 200 OK\r\n").unwrap();
stream.write(b"Content-Type: text/html; charset=utf-8\r\n").unwrap();
stream.write(b"\r\n").unwrap();
stream.write(response.as_bytes()).unwrap(); // 本体
stream.flush().unwrap(); // 出力
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment