1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use afire::{Content, HeaderType, Method, Response, Server, Status};

use crate::Example;

// Read request headers and send a response with custom headers
// You may want to read https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers to understand headers more

pub struct Header;

impl Example for Header {
    fn name(&self) -> &'static str {
        "header"
    }
    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();
    }
}

// This is a representation of the order of the headers
// The order is important because the client usually picks the first header it can find
// Note: The default headers and ContentLength are only added if they are not already defined

// -------------------
// | Default Headers |
// -------------------
// |  ContentLength  |
// -------------------
// |  Route Headers  |
// -------------------