Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: static file serving support #444

Open
matthiask opened this issue Nov 27, 2024 · 1 comment
Open

Feature request: static file serving support #444

matthiask opened this issue Nov 27, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@matthiask
Copy link
Contributor

From #97

Nginx serves static files

Now that can be (IMO) a more interesting feature request for Granian.

I think it would be very useful to have some sort of static file serving functionality.

Either something like nginx's try_files where granian could first check a folder for a match, and if not, fall back to the RSGI/ASGI/WSGI app, or maybe just support mapping URL paths to folders.

A plus would be if granian could optionally serve those files with far-future expiry headers. nginx does the following when using expires max:

The max parameter sets “Expires” to the value “Thu, 31 Dec 2037 23:55:55 GMT”, and “Cache-Control” to 10 years.

From https://nginx.org/en/docs/http/ngx_http_headers_module.html

This is the only feature which is missing for me to make granian a one-stop solution to serve everything with a single ingress, no sidecars or similar.

(I'd be willing to work on this with some guidance, or fund it if that's helpful.)

@gi0baro gi0baro added the enhancement New feature or request label Nov 27, 2024
@gi0baro
Copy link
Member

gi0baro commented Nov 27, 2024

I think this would be a useful feature for a lot of deployments out there, I definitely agree this should be implemented in the near future. I don't think this will be in time for 1.7, but possibly we can target 1.8.

In terms of implementation, here are some notes I can think of at the moment:

  • we would need 2 additional configuration parameters, one for the folder path to serve, one for the URL path to expose that folder to (might be smth like --static-path-mount my_app/static --static-patch-route /static)
  • this potentially affects only the build_service! macro here

    granian/src/workers.rs

    Lines 169 to 180 in a6cfc2f

    macro_rules! build_service {
    ($local_addr:expr, $remote_addr:expr, $callback_wrapper:expr, $rt:expr, $target:expr, $proto:expr) => {
    hyper::service::service_fn(move |request: crate::http::HTTPRequest| {
    let callback_wrapper = $callback_wrapper.clone();
    let rth = $rt.clone();
    async move {
    Ok::<_, anyhow::Error>($target(rth, callback_wrapper, $local_addr, $remote_addr, request, $proto).await)
    }
    })
    };
    }
    thus the best implementation would probably be to add a new macro and switch which macro gets used by the accept loop based on wether a static path is defined (on worker boot)
  • the main attention point should be on the security of that endpoint: the implementation should do some type of checks to avoid exploiting that path going outside of the target folder (eg: avoid /static/../../../some_file_in_root_path)
  • the expiration can probably be an additional param, I don't see any particular difficulties there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants