Tiny HTTP - Setting status to 404 page not found

tiny_http web with_status_code status code 404

Part of the Tiny HTTP series.

When a user arrives to a page that does not exist we would like to display some nice text, but we should also send the famous 404 Not Found HTTP status code.

This is how we set the status code to any number:

request
    .respond(
        Response::from_string(html)
            .with_status_code(StatusCode::from(status_code))
            .with_header(header),
    )
    .unwrap();

We have a function, boringly called default that would return the "nice" HTML page and the status code.

fn default(_request: &tiny_http::Request) -> (String, u32) {
    (String::from("Page not found"), 404)
}

Try it

You can run cargo run that will launch the server. Then you can visit http://localhost:5000/ and follow the "broken link". In the browser you will see the HTML content.

If you use curl with the -i flag you will see (in the first line of the result) that the status code was indeed set to 404. It automatically comes with the text "Not Found". At the bottom of the response you can see the text we sent back.

$ curl -i http://localhost:5000/other

HTTP/1.1 404 Not Found
Server: tiny-http (Rust)
Date: Wed, 20 Dec 2023 08:09:16 GMT
Content-Type: text/html
Content-Length: 14

Page not found

The full source code

examples/tiny-http/page-not-found-404/src/main.rs

use ascii::AsciiString;
use std::str::FromStr;
use tiny_http::{Header, HeaderField, Response, Server, StatusCode};

fn main() {
    let host = "127.0.0.1";
    let port = "5000";

    let server_str = format!("{}:{}", host, port);

    let server = Server::http(&server_str).expect("Failed to start demo server.");
    println!("Visit http://{}", server_str);


    for request in server.incoming_requests() {
        let path = if let Some((path, _)) = request.url().split_once('?') {
            path
        } else {
            request.url()
        };

        println!("path: {}", path);

        let (html, status_code) = match path {
            "/" => root_page(&request),
            "/hello" => hello(&request),
            _ => default(&request),
        };

        let header = Header {
            field: HeaderField::from_str("Content-type").unwrap(),
            value: AsciiString::from_ascii("text/html").unwrap(),
        };

        request
            .respond(
                Response::from_string(html)
                    .with_status_code(StatusCode::from(status_code))
                    .with_header(header),
            )
            .unwrap();
    }
}

fn default(_request: &tiny_http::Request) -> (String, u32) {
    (String::from("Page not found"), 404)
}

fn root_page(_request: &tiny_http::Request) -> (String, u32) {
    (
        String::from(r#"Welcome! Try <a href="/hello">this</a> page.  This is a <a href="/other">broken link</a>"#),
        200,
    )
}

fn hello(_request: &tiny_http::Request) -> (String, u32) {
    (
        String::from(r#"Hello World! <a href="/">home</a> page."#),
        200,
    )
}

Related Pages

Getting started with Tiny HTTP building a web application in Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo