Struct Response

Source
pub struct Response {
    pub status: Status,
    pub data: ResponseBody,
    pub headers: Headers,
    pub reason: Option<String>,
    pub flag: ResponseFlag,
}
Expand description

Http Response

Fieldsยง

ยงstatus: Status

Response status code

ยงdata: ResponseBody

Response Data. Can be either a Static Vec<u8> or a Stream (impl Read)

ยงheaders: Headers

List of response headers. This does not contain the default headers.

ยงreason: Option<String>

Response reason phrase. If this is None, the reason phrase will be automatically generated based on the status code.

ยงflag: ResponseFlag

Response Flags:

  • Close: Set the Connection header to close and will close the connection after the response is sent.
  • End: End the connection without sending a response

Implementationsยง

Sourceยง

impl Response

Source

pub fn new() -> Self

Create a new Blank Response

Default data is as follows

  • Status: 200
  • Data: OK
  • Headers: Vec::new()
ยงExample
Response::new();
Examples found in repository?
examples/middle_bench.rs (line 26)
23fn main() {
24    set_log_level(Level::Debug);
25    let mut server = Server::<()>::new([127, 0, 0, 1], 8080);
26    server.route(Method::ANY, "**", |_req| Response::new());
27
28    Middleware1.attach(&mut server);
29    Middleware2.attach(&mut server);
30    Middleware3.attach(&mut server);
31    Middleware4.attach(&mut server);
32    Middleware5.attach(&mut server);
33
34    server.start().unwrap();
35}
More examples
Hide additional examples
examples/basic/trace.rs (line 54)
41    fn exec(&self) {
42        // Set the log level to Trace (shows some helpful information during startup)
43        // The default is Level::Error
44        set_log_level(Level::Trace);
45        trace!(Level::Trace, "Setting log level to Trace");
46        trace!(Level::Error, "Example error message");
47
48        // Create a new Server instance on localhost port 8080
49        let mut server = Server::<()>::new("localhost", 8080);
50
51        server.route(Method::GET, "/", |req| {
52            // The default log level is Level::Trace so this will be logged
53            trace!("Request from {}", req.address.ip());
54            Response::new()
55        });
56
57        server.start().unwrap();
58    }
examples/basic/middleware.rs (line 60)
54    fn exec(&self) {
55        // Create a new Server instance on localhost port 8080
56        let mut server = Server::<()>::new("localhost", 8080);
57
58        // Define a basic route
59        server.route(Method::GET, "/", |_req| {
60            Response::new().text("Hello World!").content(Content::TXT)
61        });
62
63        // Here is where we will attach our Middleware to the Server
64        // This is super easy
65        Log.attach(&mut server);
66
67        // You can now goto http://localhost:8080 you should see that the request is printed to the console
68        // It should look something like this: `[127.0.0.1] GET `
69
70        // Start the server
71        // This will block the current thread
72        server.start().unwrap();
73    }
examples/basic/state.rs (line 31)
24    fn exec(&self) {
25        // Create a server on localhost port 8080 with a state of App
26        let mut server = Server::<App>::new("localhost", 8080).state(App::default());
27
28        // Add catch all route that takes in state and the request
29        server.stateful_route(Method::ANY, "**", |sta, _req| {
30            // Respond with and increment request count
31            Response::new().text(sta.count.fetch_add(1, Ordering::Relaxed))
32        });
33
34        // Start the server
35        // This will block the current thread
36        // Because there is a stateful route, this will panic if no state is set
37        server.start().unwrap();
38
39        // Now go to http://localhost:8080
40        // You should see the request count increment each time you refresh
41    }
examples/basic/threading.rs (line 30)
24    fn exec(&self) {
25        // Create a new Server instance on localhost port 8080
26        let mut server = Server::<()>::new("localhost", 8080);
27
28        // Define a handler for GET "/"
29        server.route(Method::GET, "/", |_req| {
30            Response::new()
31                // hopefully the ThreadId.as_u64 method will become stable
32                // until then im stuck with this mess for the example
33                // It just gets the thread ID to show the user what thread is handling the request
34                .text(format!(
35                    "Hello from thread number {:#?}!",
36                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
37                        - 1
38                ))
39                .content(Content::TXT)
40        });
41
42        // Start the server with 8 threads
43        // This will block the current thread
44        server.start_threaded(8).unwrap();
45
46        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
47    }
examples/basic/path_prams.rs (line 31)
16    fn exec(&self) {
17        // Create a new Server instance on localhost port 8080
18        let mut server: Server = Server::<()>::new("localhost", 8081);
19
20        // Define a handler for GET "/greet/{name}"
21        // This will handel requests with anything where the {name} is
22        // This includes "/greet/bob", "/greet/fin"
23        server.route(Method::GET, "/greet/{name}", |req| {
24            // Get name path param
25            let name = req.param("name").unwrap();
26
27            // Make a nice Message to send
28            let message = format!("Hello, {}", name);
29
30            // Send Response
31            Response::new().text(message).content(Content::TXT)
32        });
33
34        // Define a greet route for Darren because he is very cool
35        // This will take priority over the other route as it is defined after
36        server.route(Method::GET, "/greet/Darren/", |_req| {
37            Response::new().text("Hello, Darren. You are very cool")
38        });
39
40        // Start the server
41        // This will block the current thread
42        server.start().unwrap();
43    }
Source

pub fn end() -> Self

Creates a new Default Response with the End flag set.

Source

pub fn status(self, code: impl Into<Status>) -> Self

Add a status code to a Response. This accepts Status as well as a u16.

ยงExample
// Create Response
Response::new().status(Status::Ok);
Examples found in repository?
examples/basic/serve_file.rs (line 34)
19    fn exec(&self) {
20        // Create a new Server instance on localhost port 8080
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            // Try to open a file
26            match File::open("examples/basic/data/index.html") {
27                // If its found send it as response
28                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
29                // This is more efficient than reading the whole file into memory and then sending it
30                Ok(content) => Response::new().stream(content).content(Content::HTML),
31
32                // If the file is not found, send a 404 response
33                Err(_) => Response::new()
34                    .status(Status::NotFound)
35                    .text("Not Found :/")
36                    .content(Content::TXT),
37            }
38        });
39
40        // View the file at http://localhost:8080
41
42        // Start the server
43        // This will block the current thread
44        server.start().unwrap();
45    }
More examples
Hide additional examples
examples/basic/routing.rs (line 32)
22    fn exec(&self) {
23        // Create a new Server instance on localhost port 8080
24        let mut server: Server = Server::<()>::new("localhost", 8080);
25
26        // Define 404 page
27        // This route will run for all requests but because any other route
28        // will take priority it will only run when no other route is defined.
29        /* PRIO 0 */
30        server.route(Method::ANY, "**", |_req| {
31            Response::new()
32                .status(Status::NotFound)
33                .text("The page you are looking for does not exist :/")
34                .content(Content::TXT)
35        });
36
37        // Define a route
38        // As this is defined last, it will take a higher priority
39        /* PRIO 1 */
40        server.route(Method::GET, "/", |_req| {
41            Response::new().text("Hello World!").content(Content::TXT)
42        });
43
44        // Now goto http://localhost:8080/ and you should see "Hello World"
45        // But if you go to http://localhost:8080/somthing-else you should see the 404 page
46
47        // Start the server
48        // This will block the current thread
49        server.start().unwrap();
50    }
examples/basic/rate_limit.rs (line 38)
15    fn exec(&self) {
16        // Create a new Server instance on localhost port 8080
17        let mut server = Server::<()>::new("localhost", 8080);
18
19        // Define a handler for GET "/"
20        server.route(Method::GET, "/", |_req| {
21            Response::new().text("Hello World!").content(Content::TXT)
22        });
23
24        // For this example, we'll limit requests to 1 every 2 seconds
25
26        // Make a new Ratelimater
27        // Default Limit is 10
28        // Default Timeout is 60 sec
29        RateLimiter::new()
30            // Override the Limit to 1
31            .limit(1)
32            // Override the timeout to 2
33            .timeout(2)
34            // Override the Handler
35            .handler(Box::new(|_req| {
36                Some(
37                    Response::new()
38                        .status(Status::TooManyRequests)
39                        .text("AHHHH!!! Too Many Requests")
40                        .content(Content::TXT),
41                )
42            }))
43            // Attach to the server
44            .attach(&mut server);
45
46        // Now if you goto http://localhost:8080/ and reload a bunch of times,
47        // you'll see the rate limiter kicking in.
48
49        // Start the server
50        // This will block the current thread
51        server.start().unwrap();
52    }
examples/basic/error_handling.rs (line 40)
20    fn exec(&self) {
21        // Create a new Server instance on localhost port 8080
22        let mut server = Server::<()>::new("localhost", 8080);
23
24        // Define a route that will panic
25        server.route(Method::GET, "/panic", |_req| panic!("This is a panic!"));
26
27        // Give the server a main page
28        server.route(Method::GET, "/", |_req| {
29            Response::new()
30                .text(r#"<a href="/panic">PANIC</a>"#)
31                .content(Content::HTML)
32        });
33
34        // You can optionally define a custom error handler
35        // This can be defined anywhere in the server and will take affect for all routes
36        // Its like a normal route, but it will only be called if the route panics
37        let errors = AtomicUsize::new(1);
38        server.error_handler(move |_state, _req, err| {
39            Response::new()
40                .status(Status::InternalServerError)
41                .text(format!(
42                    "<h1>Internal Server Error #{}</h1><br>Panicked at '{}'",
43                    errors.fetch_add(1, Ordering::Relaxed),
44                    err
45                ))
46                .content(Content::HTML)
47        });
48
49        // You can now goto http://localhost:8080/panic
50        // This will cause the route to panic and return a 500 error
51
52        // Start the server
53        // This will block the current thread
54        server.start().unwrap();
55    }
examples/basic/serve_static.rs (line 37)
17    fn exec(&self) {
18        // Create a new Server instance on localhost port 8080
19        let mut server = Server::<()>::new("localhost", 8080);
20
21        // Make a new static file server with a path
22        extension::ServeStatic::new(STATIC_DIR)
23            // The middleware priority is by most recently defined.
24            // The middleware function takes 3 parameters: the request, the response, and weather the file was loaded successfully.
25            // In your middleware you can modify the response and the bool.
26            .middleware(|req, res, _suc| {
27                // Print path served
28                println!("Served: {}", req.path);
29                // Return none to not mess with response
30                // Or in this case add a header and pass through the success value
31                res.headers.push(Header::new("X-Static", "true"));
32            })
33            // Function that runs when no file is found to serve
34            // This will run before middleware
35            .not_found(|_req, _dis| {
36                Response::new()
37                    .status(Status::NotFound)
38                    .text("Page Not Found!")
39            })
40            // Add an extra mime type to the server
41            // It has a lot already
42            .mime_type("key", "value")
43            // Set serve path
44            .path(STATIC_PATH)
45            // Attach the middleware to the server
46            .attach(&mut server);
47
48        // View the file at http://localhost:8080
49        // You should also see a favicon in the browser tab
50
51        // Start the server
52        // This will block the current thread
53        server.start().unwrap();
54    }
examples/basic/basic.rs (line 28)
17    fn exec(&self) {
18        // Create a new Server instance on localhost port 8080
19        // The type parameter is for a server wide state, which we don't need yet so we use ()
20        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            Response::new()
26                // By default the status is 200 (OK)
27                // You can also define it yourself with the status method
28                .status(Status::Ok)
29                // By default the reason phrase is derived from the status
30                // But you can also define it yourself with the reason method
31                .reason("OK!")
32                // Although is is named `text` it takes any type that implements Display
33                // So for example numbers, or a serde_json::Value will work
34                .text("Hi :P")
35                // You can also add headers
36                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
37                // (this is not the proper way to use the Date header, but it works for this example)
38                .header(HeaderType::Date, "today")
39                // Now we will set the content type to text/plain; charset=utf-8
40                // The content method just adds a Content-Type header
41                .content(Content::TXT)
42        });
43
44        // Start the server in single threaded mode
45        // This will block the current thread
46        server.start().unwrap();
47
48        // Now navigate to http://localhost:8080 in your browser
49        // You should see "Hi :P"
50    }
Source

pub fn reason(self, reason: impl AsRef<str>) -> Self

Manually set the Reason Phrase. If this is not set, it will be inferred from the status code. Non standard status codes will have a reason phrase of โ€œOKโ€.

// Create Response
let response = Response::new()
    .status(Status::Ok)
    .reason("Hello");
Examples found in repository?
examples/basic/basic.rs (line 31)
17    fn exec(&self) {
18        // Create a new Server instance on localhost port 8080
19        // The type parameter is for a server wide state, which we don't need yet so we use ()
20        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            Response::new()
26                // By default the status is 200 (OK)
27                // You can also define it yourself with the status method
28                .status(Status::Ok)
29                // By default the reason phrase is derived from the status
30                // But you can also define it yourself with the reason method
31                .reason("OK!")
32                // Although is is named `text` it takes any type that implements Display
33                // So for example numbers, or a serde_json::Value will work
34                .text("Hi :P")
35                // You can also add headers
36                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
37                // (this is not the proper way to use the Date header, but it works for this example)
38                .header(HeaderType::Date, "today")
39                // Now we will set the content type to text/plain; charset=utf-8
40                // The content method just adds a Content-Type header
41                .content(Content::TXT)
42        });
43
44        // Start the server in single threaded mode
45        // This will block the current thread
46        server.start().unwrap();
47
48        // Now navigate to http://localhost:8080 in your browser
49        // You should see "Hi :P"
50    }
Source

pub fn text(self, text: impl Display) -> Self

Add text as data to a Response. Will accept any type that implements Display, such as String, str, i32, serde_json::Value, etc. This response type is considered static and will be sent in one go, not chunked.

ยงExample
// Create Response
let response = Response::new()
   .text("Hello from afire!");
Examples found in repository?
examples/basic/middleware.rs (line 60)
54    fn exec(&self) {
55        // Create a new Server instance on localhost port 8080
56        let mut server = Server::<()>::new("localhost", 8080);
57
58        // Define a basic route
59        server.route(Method::GET, "/", |_req| {
60            Response::new().text("Hello World!").content(Content::TXT)
61        });
62
63        // Here is where we will attach our Middleware to the Server
64        // This is super easy
65        Log.attach(&mut server);
66
67        // You can now goto http://localhost:8080 you should see that the request is printed to the console
68        // It should look something like this: `[127.0.0.1] GET `
69
70        // Start the server
71        // This will block the current thread
72        server.start().unwrap();
73    }
More examples
Hide additional examples
examples/basic/state.rs (line 31)
24    fn exec(&self) {
25        // Create a server on localhost port 8080 with a state of App
26        let mut server = Server::<App>::new("localhost", 8080).state(App::default());
27
28        // Add catch all route that takes in state and the request
29        server.stateful_route(Method::ANY, "**", |sta, _req| {
30            // Respond with and increment request count
31            Response::new().text(sta.count.fetch_add(1, Ordering::Relaxed))
32        });
33
34        // Start the server
35        // This will block the current thread
36        // Because there is a stateful route, this will panic if no state is set
37        server.start().unwrap();
38
39        // Now go to http://localhost:8080
40        // You should see the request count increment each time you refresh
41    }
examples/basic/threading.rs (lines 34-38)
24    fn exec(&self) {
25        // Create a new Server instance on localhost port 8080
26        let mut server = Server::<()>::new("localhost", 8080);
27
28        // Define a handler for GET "/"
29        server.route(Method::GET, "/", |_req| {
30            Response::new()
31                // hopefully the ThreadId.as_u64 method will become stable
32                // until then im stuck with this mess for the example
33                // It just gets the thread ID to show the user what thread is handling the request
34                .text(format!(
35                    "Hello from thread number {:#?}!",
36                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
37                        - 1
38                ))
39                .content(Content::TXT)
40        });
41
42        // Start the server with 8 threads
43        // This will block the current thread
44        server.start_threaded(8).unwrap();
45
46        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
47    }
examples/basic/path_prams.rs (line 31)
16    fn exec(&self) {
17        // Create a new Server instance on localhost port 8080
18        let mut server: Server = Server::<()>::new("localhost", 8081);
19
20        // Define a handler for GET "/greet/{name}"
21        // This will handel requests with anything where the {name} is
22        // This includes "/greet/bob", "/greet/fin"
23        server.route(Method::GET, "/greet/{name}", |req| {
24            // Get name path param
25            let name = req.param("name").unwrap();
26
27            // Make a nice Message to send
28            let message = format!("Hello, {}", name);
29
30            // Send Response
31            Response::new().text(message).content(Content::TXT)
32        });
33
34        // Define a greet route for Darren because he is very cool
35        // This will take priority over the other route as it is defined after
36        server.route(Method::GET, "/greet/Darren/", |_req| {
37            Response::new().text("Hello, Darren. You are very cool")
38        });
39
40        // Start the server
41        // This will block the current thread
42        server.start().unwrap();
43    }
examples/basic/serve_file.rs (line 35)
19    fn exec(&self) {
20        // Create a new Server instance on localhost port 8080
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            // Try to open a file
26            match File::open("examples/basic/data/index.html") {
27                // If its found send it as response
28                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
29                // This is more efficient than reading the whole file into memory and then sending it
30                Ok(content) => Response::new().stream(content).content(Content::HTML),
31
32                // If the file is not found, send a 404 response
33                Err(_) => Response::new()
34                    .status(Status::NotFound)
35                    .text("Not Found :/")
36                    .content(Content::TXT),
37            }
38        });
39
40        // View the file at http://localhost:8080
41
42        // Start the server
43        // This will block the current thread
44        server.start().unwrap();
45    }
examples/basic/routing.rs (line 33)
22    fn exec(&self) {
23        // Create a new Server instance on localhost port 8080
24        let mut server: Server = Server::<()>::new("localhost", 8080);
25
26        // Define 404 page
27        // This route will run for all requests but because any other route
28        // will take priority it will only run when no other route is defined.
29        /* PRIO 0 */
30        server.route(Method::ANY, "**", |_req| {
31            Response::new()
32                .status(Status::NotFound)
33                .text("The page you are looking for does not exist :/")
34                .content(Content::TXT)
35        });
36
37        // Define a route
38        // As this is defined last, it will take a higher priority
39        /* PRIO 1 */
40        server.route(Method::GET, "/", |_req| {
41            Response::new().text("Hello World!").content(Content::TXT)
42        });
43
44        // Now goto http://localhost:8080/ and you should see "Hello World"
45        // But if you go to http://localhost:8080/somthing-else you should see the 404 page
46
47        // Start the server
48        // This will block the current thread
49        server.start().unwrap();
50    }
Source

pub fn bytes(self, bytes: &[u8]) -> Self

Add raw bytes as data to a Response. This response type is considered static and will be sent in one go, not chunked.

ยงExample
// Create Response
let response = Response::new()
  .bytes(&[79, 75]); // Bytes for "OK"
Source

pub fn stream(self, stream: impl Read + Send + 'static) -> Self

Add a stream as data to a Response. This response type is considered dynamic and will be streamed to the client in chunks using Transfer-Encoding: chunked.

ยงExample
const PATH: &str = "path/to/file.txt";
let mut server = Server::<()>::new("localhost", 8080);

server.route(Method::GET, "/download-stream", |_| {
    let stream = File::open(PATH).unwrap();
    Response::new().stream(stream)
});
Examples found in repository?
examples/basic/serve_file.rs (line 30)
19    fn exec(&self) {
20        // Create a new Server instance on localhost port 8080
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            // Try to open a file
26            match File::open("examples/basic/data/index.html") {
27                // If its found send it as response
28                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
29                // This is more efficient than reading the whole file into memory and then sending it
30                Ok(content) => Response::new().stream(content).content(Content::HTML),
31
32                // If the file is not found, send a 404 response
33                Err(_) => Response::new()
34                    .status(Status::NotFound)
35                    .text("Not Found :/")
36                    .content(Content::TXT),
37            }
38        });
39
40        // View the file at http://localhost:8080
41
42        // Start the server
43        // This will block the current thread
44        server.start().unwrap();
45    }
Source

pub fn header(self, key: impl Into<HeaderType>, value: impl AsRef<str>) -> Self

Add a Header to a Response. Will accept any type that implements AsRef<str>, so String, str, &str, etc.

ยงExample
// Create Response
let response = Response::new()
   .header("Test-Header", "Test-Value");
Examples found in repository?
examples/basic/basic.rs (line 38)
17    fn exec(&self) {
18        // Create a new Server instance on localhost port 8080
19        // The type parameter is for a server wide state, which we don't need yet so we use ()
20        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            Response::new()
26                // By default the status is 200 (OK)
27                // You can also define it yourself with the status method
28                .status(Status::Ok)
29                // By default the reason phrase is derived from the status
30                // But you can also define it yourself with the reason method
31                .reason("OK!")
32                // Although is is named `text` it takes any type that implements Display
33                // So for example numbers, or a serde_json::Value will work
34                .text("Hi :P")
35                // You can also add headers
36                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
37                // (this is not the proper way to use the Date header, but it works for this example)
38                .header(HeaderType::Date, "today")
39                // Now we will set the content type to text/plain; charset=utf-8
40                // The content method just adds a Content-Type header
41                .content(Content::TXT)
42        });
43
44        // Start the server in single threaded mode
45        // This will block the current thread
46        server.start().unwrap();
47
48        // Now navigate to http://localhost:8080 in your browser
49        // You should see "Hi :P"
50    }
More examples
Hide additional examples
examples/basic/data.rs (line 55)
18    fn exec(&self) {
19        // Create a new Server instance on localhost port 8080
20        let mut server = Server::<()>::new(Ipv4Addr::LOCALHOST, 8080);
21
22        // Define a route to handel query string
23        // This will try to find a name value pair in the query string
24        server.route(Method::GET, "/", |req| {
25            // Format the response text
26            let text = format!(
27                "<h1>Hello, {}!</h1>",
28                // Get the query value of name and default to "Nobody" if not found
29                req.query.get("name").unwrap_or("Nobody")
30            );
31
32            Response::new().text(text).content(Content::HTML)
33        });
34
35        // Define another route
36        // This time to handle form data
37        server.route(Method::POST, "/form", |req| {
38            // The body of requests is not part of the req.query
39            // Instead it is part of the req.body but as a string
40            // We will need to parse it get it as a query
41            let body_data = Query::from_body(&String::from_utf8_lossy(&req.body));
42
43            let name = body_data.get("name").unwrap_or("Nobody");
44            let text = format!("<h1>Hello, {}</h1>", name);
45
46            // Create a new response, with the following default data
47            // - Status: 200
48            // - Data: OK
49            // - Headers: []
50            Response::new()
51                // Set the response body to be text
52                .text(text)
53                // Set the `Content-Type` header to be `text/html`
54                // Note: This could also be set with the Response::content method
55                .header(HeaderType::ContentType, "text/html")
56        });
57
58        // Define webpage with form
59        // The form data will be post to /form on submit
60        server.route(Method::GET, "/form", |_req| {
61            let page = r#"<form method="post">
62            <label for="name">Name:</label>
63            <input type="text" id="name" name="name"><br><br>
64            <input type="submit" value="Submit">
65      </form>"#;
66
67            Response::new().text(page).content(Content::HTML)
68        });
69
70        // Define a page with path params
71        server.route(Method::GET, "/greet/{name}", |req| {
72            // As this route would ever run without all the path params being filled
73            // It is safe to unwrap if the name is in the path
74            let data = format!("<h1>Hello, {}</h1>", req.param("name").unwrap());
75
76            Response::new().text(data).content(Content::HTML)
77        });
78
79        // You can now goto http://localhost:8080?name=John and should see "Hello, John"
80        // If you goto http://localhost:8080/form and submit the form you should see "Hello, {NAME}"
81        // Also goto http://localhost:8080/greet/John and you should see "Hello, John"
82
83        // Start the server
84        // This will block the current thread
85        server.start().unwrap();
86    }
examples/application_quote_book.rs (line 71)
34fn main() {
35    set_log_level(Level::Trace);
36    let app = App::new(PathBuf::from("quotes.txt"));
37    app.load();
38
39    let mut server = Server::new(Ipv4Addr::LOCALHOST, 8080).state(app);
40
41    // Route to serve the homepage (page that has add quote form)
42    server.route(Method::GET, "/", |_| {
43        Response::new()
44            .text(String::new() + HEADER + HOME)
45            .content(Content::HTML)
46    });
47
48    // Route to handle creating new quotes.
49    // After successful creation the user will be redirected to the new quotes page.
50    server.stateful_route(Method::POST, "/api/new", |app, req| {
51        let form = Query::from_body(&String::from_utf8_lossy(&req.body));
52        let name =
53            url::decode(form.get("author").expect("No author supplied")).expect("Invalid author");
54        let body =
55            url::decode(form.get("quote").expect("No quote supplied")).expect("Invalid quote");
56
57        let quote = Quote {
58            name,
59            value: body,
60            date: now(),
61        };
62        let mut quotes = app.quotes.write().unwrap();
63        let id = quotes.len();
64        quotes.insert(id.to_string(), quote);
65        drop(quotes);
66        trace!(Level::Trace, "Added new quote #{id}");
67
68        app.save();
69        Response::new()
70            .status(Status::SeeOther)
71            .header(HeaderType::Location, format!("/quote/{id}"))
72            .text("Redirecting to quote page.")
73    });
74
75    server.stateful_route(Method::GET, "/quote/{id}", |app, req| {
76        let id = req.param("id").unwrap();
77        if id == "undefined" {
78            return Response::new();
79        }
80
81        let id = id.parse::<usize>().expect("ID is not a valid integer");
82        let quotes = app.quotes.read().unwrap();
83        if id >= quotes.len() {
84            return Response::new()
85                .status(Status::NotFound)
86                .text(format!("No quote with the id {id} was found."));
87        }
88
89        let quote = quotes.get(&id.to_string()).unwrap();
90        Response::new().content(Content::HTML).text(
91            String::new()
92                + HEADER
93                + &QUOTE
94                    .replace("{QUOTE}", &quote.value)
95                    .replace("{AUTHOR}", &quote.name)
96                    .replace("{TIME}", &imp_date(quote.date)),
97        )
98    });
99
100    server.stateful_route(Method::GET, "/quotes", |app, _req| {
101        let mut out = String::from(HEADER);
102        out.push_str("<ul>");
103        for i in app.quotes.read().unwrap().iter() {
104            out.push_str(&format!(
105                "<li><a href=\"/quote/{}\">\"{}\" - {}</a></li>\n",
106                i.0, i.1.name, i.1.value
107            ));
108        }
109
110        Response::new().text(out + "</ul>").content(Content::HTML)
111    });
112
113    // Note: In a production application you may want to multithread the server with the Server::start_threaded method.
114    server.start().unwrap();
115}
examples/application_paste_bin.rs (line 69)
21fn main() {
22    // Create Server
23    let mut server = Server::new("localhost", 8080).state(RwLock::new(Vec::new()));
24
25    // New paste interface
26    server.route(Method::GET, "/", |_req| {
27        Response::new().content(Content::HTML).text(
28            r#"
29        <form action="/new-form" method="post">
30        <input type="text" name="name" id="name" placeholder="Title">
31        
32        <br />
33        <textarea id="body" name="body" rows="5" cols="33"></textarea>
34        <input type="submit" value="Submit" />
35    </form>
36    "#,
37        )
38    });
39
40    // New paste API handler
41    server.stateful_route(Method::POST, "/new", move |app, req| {
42        // Make sure paste data isn't too long
43        if req.body.len() > DATA_LIMIT {
44            return Response::new()
45                .status(Status::NotFound)
46                .text("Data too big!");
47        }
48
49        // Get the data as string
50        let body_str = String::from_utf8_lossy(&req.body).to_string();
51
52        // Get the name from the Name header
53        let name = req.headers.get("Name").unwrap_or("Untitled");
54
55        let paste = Paste {
56            name: name.to_owned(),
57            body: body_str,
58            time: Instant::now(),
59        };
60
61        // Push this paste to the pastes vector
62        let mut pastes = app.write().unwrap();
63        let id = pastes.len();
64        pastes.push(paste);
65
66        // Send Redirect response
67        Response::new()
68            .status(Status::MovedPermanently)
69            .header(HeaderType::Location, format!("/p/{id}"))
70            .text(format!("Redirecting to /p/{id}."))
71    });
72
73    // New paste form handler
74    server.stateful_route(Method::POST, "/new-form", |app, req| {
75        // Get data from response
76        let query = Query::from_body(String::from_utf8_lossy(&req.body).borrow());
77        let name = url::decode(query.get("name").unwrap_or("Untitled")).expect("Invalid name");
78        let body = url::decode(query.get("body").expect("No body supplied")).expect("Invalid body");
79
80        // Make sure paste data isn't too long
81        if body.len() > DATA_LIMIT {
82            return Response::new()
83                .status(Status::NotFound)
84                .text("Data too big!");
85        }
86
87        let paste = Paste {
88            name,
89            body,
90            time: Instant::now(),
91        };
92
93        // Push this paste to the pastes vector
94        let mut pastes = app.write().unwrap();
95        let id = pastes.len();
96        pastes.push(paste);
97
98        // Send Redirect response
99        Response::new()
100            .status(Status::MovedPermanently)
101            .text("Ok")
102            .header(HeaderType::Location, format!("/p/{}", id))
103    });
104
105    // Get pate handler
106    server.stateful_route(Method::GET, "/p/{id}", move |app, req| {
107        // Get is from path param
108        let id = req.param("id").unwrap().parse::<usize>().unwrap();
109
110        // Get the paste by id
111        let paste = &app.read().unwrap()[id];
112
113        // Send paste
114        Response::new().text(&paste.body)
115    });
116
117    // View all pastes
118    server.stateful_route(Method::GET, "/pastes", move |app, _req| {
119        // Starter HTML
120        let mut out = String::from(
121            r#"<a href="/">New Paste</a><meta charset="UTF-8"><table><tr><th>Name</th><th>Date</th><th>Link</th></tr>"#,
122        );
123
124        // Add a table row for each paste
125        for (i, e) in app.read().unwrap().iter().enumerate() {
126            out.push_str(&format!(
127                "<tr><td>{}</td><td>{}</td><td><a href=\"/p/{}\">๐Ÿ”—</a></td></tr>",
128                e.name,
129                fmt_relative_time(e.time.elapsed().as_secs()),
130                i
131            ));
132        }
133
134        // Send HTML
135        Response::new()
136            .text(format!("{}</table>", out))
137            .content(Content::HTML)
138    });
139
140    server.start().unwrap();
141}
Source

pub fn headers(self, headers: &[Header]) -> Self

Add a list of Headers to a Response. Only accepts a slice of Headers.

ยงExample
// Create Response
let response = Response::new()
    .headers(&[
        Header::new("Content-Type", "text/html"),
        Header::new("Test-Header", "Test-Value")
    ]);
Examples found in repository?
examples/basic/header.rs (line 53)
14    fn exec(&self) {
15        // Create a new Server instance on localhost port 8080
16        let mut server = Server::<()>::new("localhost", 8080)
17            // Define server wide default headers
18            // These will be send with every response
19            // If the same header is defined in the route it will be put before the default header
20            // Although it is not guaranteed to be the one picked by the client it usually is
21            // At the bottom of this file is a representation of the order of the headers
22            .default_header("X-Server-Header", "This is a server wide header")
23            // You can also use the HeaderType enum to define a header type
24            // This is also true with the .header method on the Response struct
25            .default_header(HeaderType::Server, "afire");
26
27        // Define a route to redirect to another website
28        server.route(Method::GET, "/", |_req| {
29            // Because this is all bout headers I have put the header vector here
30            let headers = vec![
31                // Tell the client what type of data we are sending
32                afire::Header::new(HeaderType::ContentType, "text/html"),
33                // Tell the client to redirect to another website
34                afire::Header::new(HeaderType::Location, "https://connorcode.com"),
35                // Custom header
36                afire::Header::new("X-Custom-Header", "This is a custom header"),
37            ];
38
39            // Define response body
40            // In this case this should only be seen if the client doesn't support redirects for some reason
41            let text = "<a href=\"https://connorcode.com\">connorcode</a>";
42
43            // The response code of 308 tells the client to redirect to the location specified in the header
44            // There are other response codes you can use too
45            // 301 -> Moved Permanently
46            // 302 -> Found
47            // 303 -> See Other
48            // 307 -> Temporary Redirect
49            // 308 -> Permanent Redirect
50            Response::new()
51                .status(Status::PermanentRedirect)
52                .text(text)
53                .headers(&headers)
54        });
55
56        // Now to define a route to handle client headers
57        // This will just echo the headers back to the client
58        server.route(Method::GET, "/headers", |req| {
59            // Get the headers from the request and make a html string
60            let body = req
61                .headers
62                .iter()
63                .fold(String::new(), |old, new| old + &format!("{:?}<br />", new));
64
65            // Create a response with the headers
66            Response::new().text(body).content(Content::HTML)
67        });
68
69        // You can now goto http://localhost:8080 you should see a redirect to https://connorcode.com
70        // And you can goto http://localhost:8080/headers to see the headers your client sent to the server
71
72        // Start the server
73        // This will block the current thread
74        server.start().unwrap();
75    }
Source

pub fn close(self) -> Self

Will set the Connection: close header on the Response. Then it will close the connection after the Response has been sent.

ยงExample
// Create Response
let response = Response::new()
  .text("goodbye!")
  .close();
Source

pub fn cookie(self, cookie: SetCookie) -> Self

Add a cookie to a response. The SetCookie will be converted to a Header and added to the Response.

ยงExample
// Create Response and add cookie
let response = Response::new()
    .cookie(SetCookie::new("name", "value"))
    .cookie(SetCookie::new("name2", "value2"));
Examples found in repository?
examples/basic/cookie.rs (line 60)
17    fn exec(&self) {
18        // Create a new Server instance on localhost port 8080
19        let mut server = Server::<()>::new([127, 0, 0, 1], 8080);
20
21        // Define a route to show request cookies as a table
22        server.route(Method::GET, "/", |req| {
23            // Return all cookies in a *messy* html table
24            let mut html = String::new();
25            html.push_str("<style>table, th, td {border:1px solid black;}</style>");
26            html.push_str("<table>");
27            html.push_str("<tr><th>Name</th><th>Value</th></tr>");
28            for cookie in &*req.cookies {
29                html.push_str("<tr><td>");
30                html.push_str(&cookie.name);
31                html.push_str("</td><td>");
32                html.push_str(&cookie.value);
33                html.push_str("</td></tr>");
34            }
35            html.push_str("</table>");
36
37            Response::new().text(html).content(Content::HTML)
38        });
39
40        // Set a cookie defined in the Query
41        server.route(Method::GET, "/set", |req| {
42            // Create a new cookie
43            let cookie = SetCookie::new(
44                req.query.get("name").unwrap_or("test"),
45                req.query.get("value").unwrap_or("test"),
46            )
47            // Set some options
48            .max_age(60 * 60)
49            .path("/");
50
51            let body = format!(
52                "Set Cookie '{}' to '{}'",
53                cookie.cookie.name, cookie.cookie.value
54            );
55
56            // Set the cookie
57            Response::new()
58                .text(body)
59                .content(Content::HTML)
60                .cookie(cookie)
61        });
62
63        // Now goto http://localhost:8080/set?name=hello&value=world
64        // Then goto http://localhost:8080/ and you should see a table with the cookie
65
66        // Start the server in single threaded mode
67        // This will block the current thread
68        server.start().unwrap();
69    }
Source

pub fn cookies(self, cookie: &[SetCookie]) -> Self

Add a list of cookies to a response.

ยงExample
// Create Response and add cookie
let response = Response::new()
    .cookies(&[
        SetCookie::new("name", "value"),
        SetCookie::new("name2", "value2")
    ]);
Source

pub fn content(self, content_type: Content<'_>) -> Self

Set a Content Type on a Response with a Content enum. This will add a Content-Type header to the Response.

ยงExample
// Create Response and type
let response = Response::new()
    .content(Content::HTML);
Examples found in repository?
examples/basic/middleware.rs (line 60)
54    fn exec(&self) {
55        // Create a new Server instance on localhost port 8080
56        let mut server = Server::<()>::new("localhost", 8080);
57
58        // Define a basic route
59        server.route(Method::GET, "/", |_req| {
60            Response::new().text("Hello World!").content(Content::TXT)
61        });
62
63        // Here is where we will attach our Middleware to the Server
64        // This is super easy
65        Log.attach(&mut server);
66
67        // You can now goto http://localhost:8080 you should see that the request is printed to the console
68        // It should look something like this: `[127.0.0.1] GET `
69
70        // Start the server
71        // This will block the current thread
72        server.start().unwrap();
73    }
More examples
Hide additional examples
examples/basic/threading.rs (line 39)
24    fn exec(&self) {
25        // Create a new Server instance on localhost port 8080
26        let mut server = Server::<()>::new("localhost", 8080);
27
28        // Define a handler for GET "/"
29        server.route(Method::GET, "/", |_req| {
30            Response::new()
31                // hopefully the ThreadId.as_u64 method will become stable
32                // until then im stuck with this mess for the example
33                // It just gets the thread ID to show the user what thread is handling the request
34                .text(format!(
35                    "Hello from thread number {:#?}!",
36                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
37                        - 1
38                ))
39                .content(Content::TXT)
40        });
41
42        // Start the server with 8 threads
43        // This will block the current thread
44        server.start_threaded(8).unwrap();
45
46        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
47    }
examples/basic/path_prams.rs (line 31)
16    fn exec(&self) {
17        // Create a new Server instance on localhost port 8080
18        let mut server: Server = Server::<()>::new("localhost", 8081);
19
20        // Define a handler for GET "/greet/{name}"
21        // This will handel requests with anything where the {name} is
22        // This includes "/greet/bob", "/greet/fin"
23        server.route(Method::GET, "/greet/{name}", |req| {
24            // Get name path param
25            let name = req.param("name").unwrap();
26
27            // Make a nice Message to send
28            let message = format!("Hello, {}", name);
29
30            // Send Response
31            Response::new().text(message).content(Content::TXT)
32        });
33
34        // Define a greet route for Darren because he is very cool
35        // This will take priority over the other route as it is defined after
36        server.route(Method::GET, "/greet/Darren/", |_req| {
37            Response::new().text("Hello, Darren. You are very cool")
38        });
39
40        // Start the server
41        // This will block the current thread
42        server.start().unwrap();
43    }
examples/basic/serve_file.rs (line 30)
19    fn exec(&self) {
20        // Create a new Server instance on localhost port 8080
21        let mut server = Server::<()>::new("localhost", 8080);
22
23        // Define a handler for GET "/"
24        server.route(Method::GET, "/", |_req| {
25            // Try to open a file
26            match File::open("examples/basic/data/index.html") {
27                // If its found send it as response
28                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
29                // This is more efficient than reading the whole file into memory and then sending it
30                Ok(content) => Response::new().stream(content).content(Content::HTML),
31
32                // If the file is not found, send a 404 response
33                Err(_) => Response::new()
34                    .status(Status::NotFound)
35                    .text("Not Found :/")
36                    .content(Content::TXT),
37            }
38        });
39
40        // View the file at http://localhost:8080
41
42        // Start the server
43        // This will block the current thread
44        server.start().unwrap();
45    }
examples/basic/routing.rs (line 34)
22    fn exec(&self) {
23        // Create a new Server instance on localhost port 8080
24        let mut server: Server = Server::<()>::new("localhost", 8080);
25
26        // Define 404 page
27        // This route will run for all requests but because any other route
28        // will take priority it will only run when no other route is defined.
29        /* PRIO 0 */
30        server.route(Method::ANY, "**", |_req| {
31            Response::new()
32                .status(Status::NotFound)
33                .text("The page you are looking for does not exist :/")
34                .content(Content::TXT)
35        });
36
37        // Define a route
38        // As this is defined last, it will take a higher priority
39        /* PRIO 1 */
40        server.route(Method::GET, "/", |_req| {
41            Response::new().text("Hello World!").content(Content::TXT)
42        });
43
44        // Now goto http://localhost:8080/ and you should see "Hello World"
45        // But if you go to http://localhost:8080/somthing-else you should see the 404 page
46
47        // Start the server
48        // This will block the current thread
49        server.start().unwrap();
50    }
examples/basic/rate_limit.rs (line 21)
15    fn exec(&self) {
16        // Create a new Server instance on localhost port 8080
17        let mut server = Server::<()>::new("localhost", 8080);
18
19        // Define a handler for GET "/"
20        server.route(Method::GET, "/", |_req| {
21            Response::new().text("Hello World!").content(Content::TXT)
22        });
23
24        // For this example, we'll limit requests to 1 every 2 seconds
25
26        // Make a new Ratelimater
27        // Default Limit is 10
28        // Default Timeout is 60 sec
29        RateLimiter::new()
30            // Override the Limit to 1
31            .limit(1)
32            // Override the timeout to 2
33            .timeout(2)
34            // Override the Handler
35            .handler(Box::new(|_req| {
36                Some(
37                    Response::new()
38                        .status(Status::TooManyRequests)
39                        .text("AHHHH!!! Too Many Requests")
40                        .content(Content::TXT),
41                )
42            }))
43            // Attach to the server
44            .attach(&mut server);
45
46        // Now if you goto http://localhost:8080/ and reload a bunch of times,
47        // you'll see the rate limiter kicking in.
48
49        // Start the server
50        // This will block the current thread
51        server.start().unwrap();
52    }
Source

pub fn modifier(self, modifier: impl Fn(Response) -> Response) -> Self

Lets you modify the Response with a function before it is sent to the client. This can be used to have middleware that modifies the Response on specific routes.

Source

pub fn write( &mut self, stream: Arc<Mutex<TcpStream>>, default_headers: &[Header], ) -> Result<()>

Writes a Response to a TcpStream. Will take care of adding default headers and closing the connection if needed.

Trait Implementationsยง

Sourceยง

impl Debug for Response

Sourceยง

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Sourceยง

impl Default for Response

Sourceยง

fn default() -> Response

Returns the โ€œdefault valueโ€ for a type. Read more

Auto Trait Implementationsยง

Blanket Implementationsยง

Sourceยง

impl<T> Any for T
where T: 'static + ?Sized,

Sourceยง

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Sourceยง

impl<T> Borrow<T> for T
where T: ?Sized,

Sourceยง

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Sourceยง

impl<T> BorrowMut<T> for T
where T: ?Sized,

Sourceยง

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Sourceยง

impl<T> From<T> for T

Sourceยง

fn from(t: T) -> T

Returns the argument unchanged.

Sourceยง

impl<T, U> Into<U> for T
where U: From<T>,

Sourceยง

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Sourceยง

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Sourceยง

type Error = Infallible

The type returned in the event of a conversion error.
Sourceยง

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Sourceยง

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Sourceยง

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Sourceยง

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.