Skip to content

Add support for custom redirectsΒ #39

@ThorstenHans

Description

@ThorstenHans

Users who want to host their apps using spin-fileserver may wish to configure custom redirects. This is especially useful when users may want to modify URL structures or relocate content that is already indexed by different search engines or where external links are pointed to.

Based on feedback provided by @jpflueger on Discord, I tried to find a spec that defines how redirects should be configured. However, I was not able to find anything that fits the needs.

As an alternative I would suggest outsourcing the configuration to a dedicated .toml file (e.G. redirects.toml). Users could configure redirects as shown in the following snippet:

[[redirects]]
source = "old.html"
destination = "new.html"
status = 301

[[redirects]]
source = "old2.html"
destination = "new2.html"
status = 302

# have another source pointing to the desitination new2.html
[[redirects]]
source = "old3.html"
destination = "new2.html"
status = 302

In spin-fileserver, the toml crate could be used to deserialise the configuration into a vector of a corresponding Redirect struct.

I looked at the current implementation of spin-fileserver and tried to come up with a proper way of altering the current implementation to support handling redirects while minimising modifications to the existing code-base.

I would suggest modifying the resolve function of FileServer to return Option<PathBuf, StatusCode> instead of Option<PathBuf>, this would allow handling redirects during resolution.

FileServer::send could pickup the status code received as part of the tuple returned by resolve and send proper status code along with the actual content.

The corresponding part of server would be changed to something like this:

let doc = match FileServer::resolve(path) {
    Some(res) => (FileServer::read(&res.0, &enc).ok(), res.1),
    None => (None, StatusCode::NOT_FOUND),
};

let etag = FileServer::get_etag(doc.0.clone());
FileServer::send(doc.0, path, enc, &etag, if_none_match, doc.1)

Although using a tuple would be a simple solution, using a custom struct here would be way more readable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions