]> piware.de Git - learn-rust.git/blob - actix-server/src/main.rs
ae2b22315a4b3be0537a30983e835eaecf2148f1
[learn-rust.git] / actix-server / src / main.rs
1 use actix_web::{get, web, App, HttpRequest, HttpServer, Result};
2 use actix_web::http::header;
3 use actix_web::middleware::Logger;
4
5 #[get("/hello/{name}")]
6 async fn hello(params: web::Path<String>, req: HttpRequest) -> Result<String> {
7     let name = params.into_inner();
8
9     match req.headers().get(header::USER_AGENT) {
10         Some(agent) => Ok(format!("Hello {} from {}!", name, agent.to_str().unwrap())),
11         None => Ok(format!("Hello {}!", name))
12     }
13 }
14
15 #[actix_web::main]
16 async fn main() -> std::io::Result<()> {
17     env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
18
19     HttpServer::new(|| {
20         App::new()
21             .service(hello)
22             .service(actix_files::Files::new("/dir", "../static"))
23             .wrap(Logger::default())
24     })
25         .bind(("127.0.0.1", 3030))?
26         .run()
27         .await
28 }
29
30 #[cfg(test)]
31 mod tests {
32     use actix_web::{App, body, test, web};
33     use actix_web::http::{header, StatusCode};
34
35     use super::{hello};
36
37     #[actix_web::test]
38     async fn test_hello() {
39         // FIXME: duplicating the .service() call from main() here is super ugly, but it's hard to move that into a fn
40         let app = test::init_service(App::new().service(hello)).await;
41
42         // no user-agent
43         let req = test::TestRequest::get().uri("/hello/rust").to_request();
44         let res = test::call_service(&app, req).await;
45         assert!(res.status().is_success());
46         assert_eq!(body::to_bytes(res.into_body()).await.unwrap(),
47                    web::Bytes::from_static(b"Hello rust!"));
48
49         // with user-agent
50         let req = test::TestRequest::get()
51             .uri("/hello/rust")
52             .insert_header((header::USER_AGENT, "TestBrowser 0.1"))
53             .to_request();
54         let res = test::call_service(&app, req).await;
55         assert!(res.status().is_success());
56         assert_eq!(body::to_bytes(res.into_body()).await.unwrap(),
57                    web::Bytes::from_static(b"Hello rust from TestBrowser 0.1!"));
58     }
59
60     #[actix_web::test]
61     async fn test_static_dir() {
62         // FIXME: duplicating the .service() call from main() here is super ugly, but it's hard to move that into a fn
63         let app = test::init_service(App::new().service(actix_files::Files::new("/dir", "../static"))).await;
64
65         let req = test::TestRequest::get().uri("/dir/plain.txt").to_request();
66         let res = test::call_service(&app, req).await;
67         assert!(res.status().is_success());
68         assert_eq!(body::to_bytes(res.into_body()).await.unwrap(),
69                    web::Bytes::from_static(b"Hello world! This is uncompressed text.\n"));
70
71         // subdir
72         let req = test::TestRequest::get().uri("/dir/dir1/optzip.txt").to_request();
73         let res = test::call_service(&app, req).await;
74         assert!(res.status().is_success());
75         assert_eq!(body::to_bytes(res.into_body()).await.unwrap(),
76                    web::Bytes::from_static(b"This file is available uncompressed or compressed\n\
77                                              AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"));
78
79         // does not support transparent decompression
80         let req = test::TestRequest::get().uri("/dir/onlycompressed.txt").to_request();
81         let res = test::call_service(&app, req).await;
82         assert_eq!(res.status(), StatusCode::NOT_FOUND);
83     }
84 }