Created
April 22, 2024 03:27
-
-
Save kujirahand/ecaed8ba83176ed9a3ca438382130997 to your computer and use it in GitHub Desktop.
RustでHTTPサーバを実装しよう
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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