forked from arceos-org/arceos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rs
96 lines (83 loc) · 2.29 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! Simple HTTP server.
//!
//! Benchmark with [Apache HTTP server benchmarking tool](https://httpd.apache.org/docs/2.4/programs/ab.html):
//!
//! ```
//! ab -n 5000 -c 20 http://X.X.X.X:5555/
//! ```
#![cfg_attr(feature = "axstd", no_std)]
#![cfg_attr(feature = "axstd", no_main)]
#[macro_use]
#[cfg(feature = "axstd")]
extern crate axstd as std;
use std::io::{self, prelude::*};
use std::net::{TcpListener, TcpStream};
use std::thread;
const LOCAL_IP: &str = "0.0.0.0";
const LOCAL_PORT: u16 = 5555;
macro_rules! header {
() => {
"\
HTTP/1.1 200 OK\r\n\
Content-Type: text/html\r\n\
Content-Length: {}\r\n\
Connection: close\r\n\
\r\n\
{}"
};
}
const CONTENT: &str = r#"<html>
<head>
<title>Hello, ArceOS</title>
</head>
<body>
<center>
<h1>Hello, <a href="https://github.com/rcore-os/arceos">ArceOS</a></h1>
</center>
<hr>
<center>
<i>Powered by <a href="https://github.com/rcore-os/arceos/tree/main/apps/net/httpserver">ArceOS example HTTP server</a> v0.1.0</i>
</center>
</body>
</html>
"#;
macro_rules! info {
($($arg:tt)*) => {
match option_env!("LOG") {
Some("info") | Some("debug") | Some("trace") => {
print!("[INFO] {}\n", format_args!($($arg)*));
}
_ => {}
}
};
}
fn http_server(mut stream: TcpStream) -> io::Result<()> {
let mut buf = [0u8; 4096];
let _len = stream.read(&mut buf)?;
let response = format!(header!(), CONTENT.len(), CONTENT);
stream.write_all(response.as_bytes())?;
Ok(())
}
fn accept_loop() -> io::Result<()> {
let listener = TcpListener::bind((LOCAL_IP, LOCAL_PORT))?;
println!("listen on: http://{}/", listener.local_addr().unwrap());
let mut i = 0;
loop {
match listener.accept() {
Ok((stream, addr)) => {
info!("new client {}: {}", i, addr);
thread::spawn(move || match http_server(stream) {
Err(e) => info!("client connection error: {:?}", e),
Ok(()) => info!("client {} closed successfully", i),
});
}
Err(e) => return Err(e),
}
i += 1;
}
}
#[cfg_attr(feature = "axstd", no_mangle)]
fn main() {
println!("Hello, ArceOS HTTP server!");
accept_loop().expect("test HTTP server failed");
}