Struct afire::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)
23
24
25
26
27
28
29
30
31
32
33
34
35
fn main() {
    set_log_level(Level::Debug);
    let mut server = Server::<()>::new([127, 0, 0, 1], 8080);
    server.route(Method::ANY, "**", |_req| Response::new());

    Middleware1.attach(&mut server);
    Middleware2.attach(&mut server);
    Middleware3.attach(&mut server);
    Middleware4.attach(&mut server);
    Middleware5.attach(&mut server);

    server.start().unwrap();
}
More examples
Hide additional examples
examples/basic/trace.rs (line 54)
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    fn exec(&self) {
        // Set the log level to Trace (shows some helpful information during startup)
        // The default is Level::Error
        set_log_level(Level::Trace);
        trace!(Level::Trace, "Setting log level to Trace");
        trace!(Level::Error, "Example error message");

        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        server.route(Method::GET, "/", |req| {
            // The default log level is Level::Trace so this will be logged
            trace!("Request from {}", req.address.ip());
            Response::new()
        });

        server.start().unwrap();
    }
examples/basic/middleware.rs (line 60)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a basic route
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Here is where we will attach our Middleware to the Server
        // This is super easy
        Log.attach(&mut server);

        // You can now goto http://localhost:8080 you should see that the request is printed to the console
        // It should look something like this: `[127.0.0.1] GET `

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/state.rs (line 31)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    fn exec(&self) {
        // Create a server on localhost port 8080 with a state of App
        let mut server = Server::<App>::new("localhost", 8080).state(App::default());

        // Add catch all route that takes in state and the request
        server.stateful_route(Method::ANY, "**", |sta, _req| {
            // Respond with and increment request count
            Response::new().text(sta.count.fetch_add(1, Ordering::Relaxed))
        });

        // Start the server
        // This will block the current thread
        // Because there is a stateful route, this will panic if no state is set
        server.start().unwrap();

        // Now go to http://localhost:8080
        // You should see the request count increment each time you refresh
    }
examples/basic/threading.rs (line 30)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // hopefully the ThreadId.as_u64 method will become stable
                // until then im stuck with this mess for the example
                // It just gets the thread ID to show the user what thread is handling the request
                .text(format!(
                    "Hello from thread number {:#?}!",
                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
                        - 1
                ))
                .content(Content::TXT)
        });

        // Start the server with 8 threads
        // This will block the current thread
        server.start_threaded(8).unwrap();

        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
    }
examples/basic/path_prams.rs (line 31)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8081);

        // Define a handler for GET "/greet/{name}"
        // This will handel requests with anything where the {name} is
        // This includes "/greet/bob", "/greet/fin"
        server.route(Method::GET, "/greet/{name}", |req| {
            // Get name path param
            let name = req.param("name").unwrap();

            // Make a nice Message to send
            let message = format!("Hello, {}", name);

            // Send Response
            Response::new().text(message).content(Content::TXT)
        });

        // Define a greet route for Darren because he is very cool
        // This will take priority over the other route as it is defined after
        server.route(Method::GET, "/greet/Darren/", |_req| {
            Response::new().text("Hello, Darren. You are very cool")
        });

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            // Try to open a file
            match File::open("examples/basic/data/index.html") {
                // If its found send it as response
                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
                // This is more efficient than reading the whole file into memory and then sending it
                Ok(content) => Response::new().stream(content).content(Content::HTML),

                // If the file is not found, send a 404 response
                Err(_) => Response::new()
                    .status(Status::NotFound)
                    .text("Not Found :/")
                    .content(Content::TXT),
            }
        });

        // View the file at http://localhost:8080

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
More examples
Hide additional examples
examples/basic/routing.rs (line 32)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8080);

        // Define 404 page
        // This route will run for all requests but because any other route
        // will take priority it will only run when no other route is defined.
        /* PRIO 0 */
        server.route(Method::ANY, "**", |_req| {
            Response::new()
                .status(Status::NotFound)
                .text("The page you are looking for does not exist :/")
                .content(Content::TXT)
        });

        // Define a route
        // As this is defined last, it will take a higher priority
        /* PRIO 1 */
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Now goto http://localhost:8080/ and you should see "Hello World"
        // But if you go to http://localhost:8080/somthing-else you should see the 404 page

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/rate_limit.rs (line 38)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // For this example, we'll limit requests to 1 every 2 seconds

        // Make a new Ratelimater
        // Default Limit is 10
        // Default Timeout is 60 sec
        RateLimiter::new()
            // Override the Limit to 1
            .limit(1)
            // Override the timeout to 2
            .timeout(2)
            // Override the Handler
            .handler(Box::new(|_req| {
                Some(
                    Response::new()
                        .status(Status::TooManyRequests)
                        .text("AHHHH!!! Too Many Requests")
                        .content(Content::TXT),
                )
            }))
            // Attach to the server
            .attach(&mut server);

        // Now if you goto http://localhost:8080/ and reload a bunch of times,
        // you'll see the rate limiter kicking in.

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/error_handling.rs (line 40)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a route that will panic
        server.route(Method::GET, "/panic", |_req| panic!("This is a panic!"));

        // Give the server a main page
        server.route(Method::GET, "/", |_req| {
            Response::new()
                .text(r#"<a href="/panic">PANIC</a>"#)
                .content(Content::HTML)
        });

        // You can optionally define a custom error handler
        // This can be defined anywhere in the server and will take affect for all routes
        // Its like a normal route, but it will only be called if the route panics
        let errors = AtomicUsize::new(1);
        server.error_handler(move |_state, _req, err| {
            Response::new()
                .status(Status::InternalServerError)
                .text(format!(
                    "<h1>Internal Server Error #{}</h1><br>Panicked at '{}'",
                    errors.fetch_add(1, Ordering::Relaxed),
                    err
                ))
                .content(Content::HTML)
        });

        // You can now goto http://localhost:8080/panic
        // This will cause the route to panic and return a 500 error

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/serve_static.rs (line 37)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Make a new static file server with a path
        extension::ServeStatic::new(STATIC_DIR)
            // The middleware priority is by most recently defined.
            // The middleware function takes 3 parameters: the request, the response, and weather the file was loaded successfully.
            // In your middleware you can modify the response and the bool.
            .middleware(|req, res, _suc| {
                // Print path served
                println!("Served: {}", req.path);
                // Return none to not mess with response
                // Or in this case add a header and pass through the success value
                res.headers.push(Header::new("X-Static", "true"));
            })
            // Function that runs when no file is found to serve
            // This will run before middleware
            .not_found(|_req, _dis| {
                Response::new()
                    .status(Status::NotFound)
                    .text("Page Not Found!")
            })
            // Add an extra mime type to the server
            // It has a lot already
            .mime_type("key", "value")
            // Set serve path
            .path(STATIC_PATH)
            // Attach the middleware to the server
            .attach(&mut server);

        // View the file at http://localhost:8080
        // You should also see a favicon in the browser tab

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/basic.rs (line 28)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        // The type parameter is for a server wide state, which we don't need yet so we use ()
        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // By default the status is 200 (OK)
                // You can also define it yourself with the status method
                .status(Status::Ok)
                // By default the reason phrase is derived from the status
                // But you can also define it yourself with the reason method
                .reason("OK!")
                // Although is is named `text` it takes any type that implements Display
                // So for example numbers, or a serde_json::Value will work
                .text("Hi :P")
                // You can also add headers
                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
                // (this is not the proper way to use the Date header, but it works for this example)
                .header(HeaderType::Date, "today")
                // Now we will set the content type to text/plain; charset=utf-8
                // The content method just adds a Content-Type header
                .content(Content::TXT)
        });

        // Start the server in single threaded mode
        // This will block the current thread
        server.start().unwrap();

        // Now navigate to http://localhost:8080 in your browser
        // You should see "Hi :P"
    }
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        // The type parameter is for a server wide state, which we don't need yet so we use ()
        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // By default the status is 200 (OK)
                // You can also define it yourself with the status method
                .status(Status::Ok)
                // By default the reason phrase is derived from the status
                // But you can also define it yourself with the reason method
                .reason("OK!")
                // Although is is named `text` it takes any type that implements Display
                // So for example numbers, or a serde_json::Value will work
                .text("Hi :P")
                // You can also add headers
                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
                // (this is not the proper way to use the Date header, but it works for this example)
                .header(HeaderType::Date, "today")
                // Now we will set the content type to text/plain; charset=utf-8
                // The content method just adds a Content-Type header
                .content(Content::TXT)
        });

        // Start the server in single threaded mode
        // This will block the current thread
        server.start().unwrap();

        // Now navigate to http://localhost:8080 in your browser
        // You should see "Hi :P"
    }
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a basic route
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Here is where we will attach our Middleware to the Server
        // This is super easy
        Log.attach(&mut server);

        // You can now goto http://localhost:8080 you should see that the request is printed to the console
        // It should look something like this: `[127.0.0.1] GET `

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
More examples
Hide additional examples
examples/basic/state.rs (line 31)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    fn exec(&self) {
        // Create a server on localhost port 8080 with a state of App
        let mut server = Server::<App>::new("localhost", 8080).state(App::default());

        // Add catch all route that takes in state and the request
        server.stateful_route(Method::ANY, "**", |sta, _req| {
            // Respond with and increment request count
            Response::new().text(sta.count.fetch_add(1, Ordering::Relaxed))
        });

        // Start the server
        // This will block the current thread
        // Because there is a stateful route, this will panic if no state is set
        server.start().unwrap();

        // Now go to http://localhost:8080
        // You should see the request count increment each time you refresh
    }
examples/basic/threading.rs (lines 34-38)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // hopefully the ThreadId.as_u64 method will become stable
                // until then im stuck with this mess for the example
                // It just gets the thread ID to show the user what thread is handling the request
                .text(format!(
                    "Hello from thread number {:#?}!",
                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
                        - 1
                ))
                .content(Content::TXT)
        });

        // Start the server with 8 threads
        // This will block the current thread
        server.start_threaded(8).unwrap();

        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
    }
examples/basic/path_prams.rs (line 31)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8081);

        // Define a handler for GET "/greet/{name}"
        // This will handel requests with anything where the {name} is
        // This includes "/greet/bob", "/greet/fin"
        server.route(Method::GET, "/greet/{name}", |req| {
            // Get name path param
            let name = req.param("name").unwrap();

            // Make a nice Message to send
            let message = format!("Hello, {}", name);

            // Send Response
            Response::new().text(message).content(Content::TXT)
        });

        // Define a greet route for Darren because he is very cool
        // This will take priority over the other route as it is defined after
        server.route(Method::GET, "/greet/Darren/", |_req| {
            Response::new().text("Hello, Darren. You are very cool")
        });

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/serve_file.rs (line 35)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            // Try to open a file
            match File::open("examples/basic/data/index.html") {
                // If its found send it as response
                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
                // This is more efficient than reading the whole file into memory and then sending it
                Ok(content) => Response::new().stream(content).content(Content::HTML),

                // If the file is not found, send a 404 response
                Err(_) => Response::new()
                    .status(Status::NotFound)
                    .text("Not Found :/")
                    .content(Content::TXT),
            }
        });

        // View the file at http://localhost:8080

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/routing.rs (line 33)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8080);

        // Define 404 page
        // This route will run for all requests but because any other route
        // will take priority it will only run when no other route is defined.
        /* PRIO 0 */
        server.route(Method::ANY, "**", |_req| {
            Response::new()
                .status(Status::NotFound)
                .text("The page you are looking for does not exist :/")
                .content(Content::TXT)
        });

        // Define a route
        // As this is defined last, it will take a higher priority
        /* PRIO 1 */
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Now goto http://localhost:8080/ and you should see "Hello World"
        // But if you go to http://localhost:8080/somthing-else you should see the 404 page

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            // Try to open a file
            match File::open("examples/basic/data/index.html") {
                // If its found send it as response
                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
                // This is more efficient than reading the whole file into memory and then sending it
                Ok(content) => Response::new().stream(content).content(Content::HTML),

                // If the file is not found, send a 404 response
                Err(_) => Response::new()
                    .status(Status::NotFound)
                    .text("Not Found :/")
                    .content(Content::TXT),
            }
        });

        // View the file at http://localhost:8080

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        // The type parameter is for a server wide state, which we don't need yet so we use ()
        // In this example we are setting the ip with a string, but you can also use a Ipv4Addr or [u8; 4]
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // By default the status is 200 (OK)
                // You can also define it yourself with the status method
                .status(Status::Ok)
                // By default the reason phrase is derived from the status
                // But you can also define it yourself with the reason method
                .reason("OK!")
                // Although is is named `text` it takes any type that implements Display
                // So for example numbers, or a serde_json::Value will work
                .text("Hi :P")
                // You can also add headers
                // The header method will take a HeaderType, String, or &str and the value can be a String or &str
                // (this is not the proper way to use the Date header, but it works for this example)
                .header(HeaderType::Date, "today")
                // Now we will set the content type to text/plain; charset=utf-8
                // The content method just adds a Content-Type header
                .content(Content::TXT)
        });

        // Start the server in single threaded mode
        // This will block the current thread
        server.start().unwrap();

        // Now navigate to http://localhost:8080 in your browser
        // You should see "Hi :P"
    }
More examples
Hide additional examples
examples/basic/data.rs (line 55)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new(Ipv4Addr::LOCALHOST, 8080);

        // Define a route to handel query string
        // This will try to find a name value pair in the query string
        server.route(Method::GET, "/", |req| {
            // Format the response text
            let text = format!(
                "<h1>Hello, {}!</h1>",
                // Get the query value of name and default to "Nobody" if not found
                req.query.get("name").unwrap_or("Nobody")
            );

            Response::new().text(text).content(Content::HTML)
        });

        // Define another route
        // This time to handle form data
        server.route(Method::POST, "/form", |req| {
            // The body of requests is not part of the req.query
            // Instead it is part of the req.body but as a string
            // We will need to parse it get it as a query
            let body_data = Query::from_body(&String::from_utf8_lossy(&req.body));

            let name = body_data.get("name").unwrap_or("Nobody");
            let text = format!("<h1>Hello, {}</h1>", name);

            // Create a new response, with the following default data
            // - Status: 200
            // - Data: OK
            // - Headers: []
            Response::new()
                // Set the response body to be text
                .text(text)
                // Set the `Content-Type` header to be `text/html`
                // Note: This could also be set with the Response::content method
                .header(HeaderType::ContentType, "text/html")
        });

        // Define webpage with form
        // The form data will be post to /form on submit
        server.route(Method::GET, "/form", |_req| {
            let page = r#"<form method="post">
            <label for="name">Name:</label>
            <input type="text" id="name" name="name"><br><br>
            <input type="submit" value="Submit">
      </form>"#;

            Response::new().text(page).content(Content::HTML)
        });

        // Define a page with path params
        server.route(Method::GET, "/greet/{name}", |req| {
            // As this route would ever run without all the path params being filled
            // It is safe to unwrap if the name is in the path
            let data = format!("<h1>Hello, {}</h1>", req.param("name").unwrap());

            Response::new().text(data).content(Content::HTML)
        });

        // You can now goto http://localhost:8080?name=John and should see "Hello, John"
        // If you goto http://localhost:8080/form and submit the form you should see "Hello, {NAME}"
        // Also goto http://localhost:8080/greet/John and you should see "Hello, John"

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/application_quote_book.rs (line 71)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
fn main() {
    set_log_level(Level::Trace);
    let app = App::new(PathBuf::from("quotes.txt"));
    app.load();

    let mut server = Server::new(Ipv4Addr::LOCALHOST, 8080).state(app);

    // Route to serve the homepage (page that has add quote form)
    server.route(Method::GET, "/", |_| {
        Response::new()
            .text(String::new() + HEADER + HOME)
            .content(Content::HTML)
    });

    // Route to handle creating new quotes.
    // After successful creation the user will be redirected to the new quotes page.
    server.stateful_route(Method::POST, "/api/new", |app, req| {
        let form = Query::from_body(&String::from_utf8_lossy(&req.body));
        let name =
            url::decode(form.get("author").expect("No author supplied")).expect("Invalid author");
        let body =
            url::decode(form.get("quote").expect("No quote supplied")).expect("Invalid quote");

        let quote = Quote {
            name,
            value: body,
            date: now(),
        };
        let mut quotes = app.quotes.write().unwrap();
        let id = quotes.len();
        quotes.insert(id.to_string(), quote);
        drop(quotes);
        trace!(Level::Trace, "Added new quote #{id}");

        app.save();
        Response::new()
            .status(Status::SeeOther)
            .header(HeaderType::Location, format!("/quote/{id}"))
            .text("Redirecting to quote page.")
    });

    server.stateful_route(Method::GET, "/quote/{id}", |app, req| {
        let id = req.param("id").unwrap();
        if id == "undefined" {
            return Response::new();
        }

        let id = id.parse::<usize>().expect("ID is not a valid integer");
        let quotes = app.quotes.read().unwrap();
        if id >= quotes.len() {
            return Response::new()
                .status(Status::NotFound)
                .text(format!("No quote with the id {id} was found."));
        }

        let quote = quotes.get(&id.to_string()).unwrap();
        Response::new().content(Content::HTML).text(
            String::new()
                + HEADER
                + &QUOTE
                    .replace("{QUOTE}", &quote.value)
                    .replace("{AUTHOR}", &quote.name)
                    .replace("{TIME}", &imp_date(quote.date)),
        )
    });

    server.stateful_route(Method::GET, "/quotes", |app, _req| {
        let mut out = String::from(HEADER);
        out.push_str("<ul>");
        for i in app.quotes.read().unwrap().iter() {
            out.push_str(&format!(
                "<li><a href=\"/quote/{}\">\"{}\" - {}</a></li>\n",
                i.0, i.1.name, i.1.value
            ));
        }

        Response::new().text(out + "</ul>").content(Content::HTML)
    });

    // Note: In a production application you may want to multithread the server with the Server::start_threaded method.
    server.start().unwrap();
}
examples/application_paste_bin.rs (line 69)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
fn main() {
    // Create Server
    let mut server = Server::new("localhost", 8080).state(RwLock::new(Vec::new()));

    // New paste interface
    server.route(Method::GET, "/", |_req| {
        Response::new().content(Content::HTML).text(
            r#"
        <form action="/new-form" method="post">
        <input type="text" name="name" id="name" placeholder="Title">
        
        <br />
        <textarea id="body" name="body" rows="5" cols="33"></textarea>
        <input type="submit" value="Submit" />
    </form>
    "#,
        )
    });

    // New paste API handler
    server.stateful_route(Method::POST, "/new", move |app, req| {
        // Make sure paste data isn't too long
        if req.body.len() > DATA_LIMIT {
            return Response::new()
                .status(Status::NotFound)
                .text("Data too big!");
        }

        // Get the data as string
        let body_str = String::from_utf8_lossy(&req.body).to_string();

        // Get the name from the Name header
        let name = req.headers.get("Name").unwrap_or("Untitled");

        let paste = Paste {
            name: name.to_owned(),
            body: body_str,
            time: Instant::now(),
        };

        // Push this paste to the pastes vector
        let mut pastes = app.write().unwrap();
        let id = pastes.len();
        pastes.push(paste);

        // Send Redirect response
        Response::new()
            .status(Status::MovedPermanently)
            .header(HeaderType::Location, format!("/p/{id}"))
            .text(format!("Redirecting to /p/{id}."))
    });

    // New paste form handler
    server.stateful_route(Method::POST, "/new-form", |app, req| {
        // Get data from response
        let query = Query::from_body(String::from_utf8_lossy(&req.body).borrow());
        let name = url::decode(query.get("name").unwrap_or("Untitled")).expect("Invalid name");
        let body = url::decode(query.get("body").expect("No body supplied")).expect("Invalid body");

        // Make sure paste data isn't too long
        if body.len() > DATA_LIMIT {
            return Response::new()
                .status(Status::NotFound)
                .text("Data too big!");
        }

        let paste = Paste {
            name,
            body,
            time: Instant::now(),
        };

        // Push this paste to the pastes vector
        let mut pastes = app.write().unwrap();
        let id = pastes.len();
        pastes.push(paste);

        // Send Redirect response
        Response::new()
            .status(Status::MovedPermanently)
            .text("Ok")
            .header(HeaderType::Location, format!("/p/{}", id))
    });

    // Get pate handler
    server.stateful_route(Method::GET, "/p/{id}", move |app, req| {
        // Get is from path param
        let id = req.param("id").unwrap().parse::<usize>().unwrap();

        // Get the paste by id
        let paste = &app.read().unwrap()[id];

        // Send paste
        Response::new().text(&paste.body)
    });

    // View all pastes
    server.stateful_route(Method::GET, "/pastes", move |app, _req| {
        // Starter HTML
        let mut out = String::from(
            r#"<a href="/">New Paste</a><meta charset="UTF-8"><table><tr><th>Name</th><th>Date</th><th>Link</th></tr>"#,
        );

        // Add a table row for each paste
        for (i, e) in app.read().unwrap().iter().enumerate() {
            out.push_str(&format!(
                "<tr><td>{}</td><td>{}</td><td><a href=\"/p/{}\">🔗</a></td></tr>",
                e.name,
                fmt_relative_time(e.time.elapsed().as_secs()),
                i
            ));
        }

        // Send HTML
        Response::new()
            .text(format!("{}</table>", out))
            .content(Content::HTML)
    });

    server.start().unwrap();
}
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080)
            // Define server wide default headers
            // These will be send with every response
            // If the same header is defined in the route it will be put before the default header
            // Although it is not guaranteed to be the one picked by the client it usually is
            // At the bottom of this file is a representation of the order of the headers
            .default_header("X-Server-Header", "This is a server wide header")
            // You can also use the HeaderType enum to define a header type
            // This is also true with the .header method on the Response struct
            .default_header(HeaderType::Server, "afire");

        // Define a route to redirect to another website
        server.route(Method::GET, "/", |_req| {
            // Because this is all bout headers I have put the header vector here
            let headers = vec![
                // Tell the client what type of data we are sending
                afire::Header::new(HeaderType::ContentType, "text/html"),
                // Tell the client to redirect to another website
                afire::Header::new(HeaderType::Location, "https://connorcode.com"),
                // Custom header
                afire::Header::new("X-Custom-Header", "This is a custom header"),
            ];

            // Define response body
            // In this case this should only be seen if the client doesn't support redirects for some reason
            let text = "<a href=\"https://connorcode.com\">connorcode</a>";

            // The response code of 308 tells the client to redirect to the location specified in the header
            // There are other response codes you can use too
            // 301 -> Moved Permanently
            // 302 -> Found
            // 303 -> See Other
            // 307 -> Temporary Redirect
            // 308 -> Permanent Redirect
            Response::new()
                .status(Status::PermanentRedirect)
                .text(text)
                .headers(&headers)
        });

        // Now to define a route to handle client headers
        // This will just echo the headers back to the client
        server.route(Method::GET, "/headers", |req| {
            // Get the headers from the request and make a html string
            let body = req
                .headers
                .iter()
                .fold(String::new(), |old, new| old + &format!("{:?}<br />", new));

            // Create a response with the headers
            Response::new().text(body).content(Content::HTML)
        });

        // You can now goto http://localhost:8080 you should see a redirect to https://connorcode.com
        // And you can goto http://localhost:8080/headers to see the headers your client sent to the server

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
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
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new([127, 0, 0, 1], 8080);

        // Define a route to show request cookies as a table
        server.route(Method::GET, "/", |req| {
            // Return all cookies in a *messy* html table
            let mut html = String::new();
            html.push_str("<style>table, th, td {border:1px solid black;}</style>");
            html.push_str("<table>");
            html.push_str("<tr><th>Name</th><th>Value</th></tr>");
            for cookie in &*req.cookies {
                html.push_str("<tr><td>");
                html.push_str(&cookie.name);
                html.push_str("</td><td>");
                html.push_str(&cookie.value);
                html.push_str("</td></tr>");
            }
            html.push_str("</table>");

            Response::new().text(html).content(Content::HTML)
        });

        // Set a cookie defined in the Query
        server.route(Method::GET, "/set", |req| {
            // Create a new cookie
            let cookie = SetCookie::new(
                req.query.get("name").unwrap_or("test"),
                req.query.get("value").unwrap_or("test"),
            )
            // Set some options
            .max_age(60 * 60)
            .path("/");

            let body = format!(
                "Set Cookie '{}' to '{}'",
                cookie.cookie.name, cookie.cookie.value
            );

            // Set the cookie
            Response::new()
                .text(body)
                .content(Content::HTML)
                .cookie(cookie)
        });

        // Now goto http://localhost:8080/set?name=hello&value=world
        // Then goto http://localhost:8080/ and you should see a table with the cookie

        // Start the server in single threaded mode
        // This will block the current thread
        server.start().unwrap();
    }
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a basic route
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Here is where we will attach our Middleware to the Server
        // This is super easy
        Log.attach(&mut server);

        // You can now goto http://localhost:8080 you should see that the request is printed to the console
        // It should look something like this: `[127.0.0.1] GET `

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
More examples
Hide additional examples
examples/basic/threading.rs (line 39)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                // hopefully the ThreadId.as_u64 method will become stable
                // until then im stuck with this mess for the example
                // It just gets the thread ID to show the user what thread is handling the request
                .text(format!(
                    "Hello from thread number {:#?}!",
                    unsafe { std::mem::transmute::<_, NonZeroU64>(thread::current().id()) }.get()
                        - 1
                ))
                .content(Content::TXT)
        });

        // Start the server with 8 threads
        // This will block the current thread
        server.start_threaded(8).unwrap();

        // If you go to http://localhost:8080 you should see the thread ID change with each refresh
    }
examples/basic/path_prams.rs (line 31)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8081);

        // Define a handler for GET "/greet/{name}"
        // This will handel requests with anything where the {name} is
        // This includes "/greet/bob", "/greet/fin"
        server.route(Method::GET, "/greet/{name}", |req| {
            // Get name path param
            let name = req.param("name").unwrap();

            // Make a nice Message to send
            let message = format!("Hello, {}", name);

            // Send Response
            Response::new().text(message).content(Content::TXT)
        });

        // Define a greet route for Darren because he is very cool
        // This will take priority over the other route as it is defined after
        server.route(Method::GET, "/greet/Darren/", |_req| {
            Response::new().text("Hello, Darren. You are very cool")
        });

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/serve_file.rs (line 30)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            // Try to open a file
            match File::open("examples/basic/data/index.html") {
                // If its found send it as response
                // Because we used File::open and not fs::read, we can use the stream method to send the file in chunks
                // This is more efficient than reading the whole file into memory and then sending it
                Ok(content) => Response::new().stream(content).content(Content::HTML),

                // If the file is not found, send a 404 response
                Err(_) => Response::new()
                    .status(Status::NotFound)
                    .text("Not Found :/")
                    .content(Content::TXT),
            }
        });

        // View the file at http://localhost:8080

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/routing.rs (line 34)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server: Server = Server::<()>::new("localhost", 8080);

        // Define 404 page
        // This route will run for all requests but because any other route
        // will take priority it will only run when no other route is defined.
        /* PRIO 0 */
        server.route(Method::ANY, "**", |_req| {
            Response::new()
                .status(Status::NotFound)
                .text("The page you are looking for does not exist :/")
                .content(Content::TXT)
        });

        // Define a route
        // As this is defined last, it will take a higher priority
        /* PRIO 1 */
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Now goto http://localhost:8080/ and you should see "Hello World"
        // But if you go to http://localhost:8080/somthing-else you should see the 404 page

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/rate_limit.rs (line 21)
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
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // For this example, we'll limit requests to 1 every 2 seconds

        // Make a new Ratelimater
        // Default Limit is 10
        // Default Timeout is 60 sec
        RateLimiter::new()
            // Override the Limit to 1
            .limit(1)
            // Override the timeout to 2
            .timeout(2)
            // Override the Handler
            .handler(Box::new(|_req| {
                Some(
                    Response::new()
                        .status(Status::TooManyRequests)
                        .text("AHHHH!!! Too Many Requests")
                        .content(Content::TXT),
                )
            }))
            // Attach to the server
            .attach(&mut server);

        // Now if you goto http://localhost:8080/ and reload a bunch of times,
        // you'll see the rate limiter kicking in.

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
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 Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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 Twhere 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 Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.