index : static-web-server.git

ascending towards madness

author Jose Quintana <joseluisquintana20@gmail.com> 2021-05-19 21:26:35.0 +00:00:00
committer Jose Quintana <joseluisquintana20@gmail.com> 2021-05-19 21:26:35.0 +00:00:00
commit
d389803b8a455be057ff31a3f4e61f5770751a6e [patch]
tree
60df0f1743458574fd36539decff8a856680ac60
parent
0d2762d82f7d87b4c4568e1047d1c7d1cabb88d6
download
d389803b8a455be057ff31a3f4e61f5770751a6e.tar.gz

feat: gzip, deflate or brotli --compression (-x) flag

this flag enables or disables gzip, deflate or brotli on demand based
on Accept-Encoding header. feature enabled by default

Diff

 README.md      | 10 ++++++++--
 src/config.rs  | 10 ++++++++++
 src/handler.rs |  9 ++++++---
 src/server.rs  | 19 +++++++++++++++++--
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 5dc91a5..5876c54 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ Server can be configured either via environment variables or their equivalent co
| `SERVER_HTTP2_TLS_CERT`     | Specify the file path to read the certificate. | Default empty |
| `SERVER_HTTP2_TLS_KEY`      | Specify the file path to read the private key. | Default empty |
| `SERVER_CORS_ALLOW_ORIGINS` | Specify a optional CORS list of allowed origin hosts separated by comas. Host ports or protocols aren't being checked. Use an asterisk (*) to allow any host. | Default empty (which means CORS is disabled) |
| `SERVER_COMPRESSION`  | Gzip, Deflate or Brotli compression on demand determined by the *Accept-Encoding* header and applied to text-based web file types only. See [ad-hoc mime-type list]https://github.com/joseluisq/static-web-server/blob/master/src/compression.rs#L20 | Default `true` (enabled) |
| `SERVER_DIRECTORY_LISTING`  | Enable directory listing for all requests ending with the slash character (‘/’) | Default `false` (disabled) |

### Command-line arguments
@@ -72,16 +73,21 @@ FLAGS:
    -V, --version    Prints version information

OPTIONS:
    -x, --compression <compression>
            Gzip, Deflate or Brotli compression on demand determined by the Accept-Encoding header and applied to text-
            based web file types only [env: SERVER_COMPRESSION=]  [default: true]
    -c, --cors-allow-origins <cors-allow-origins>
            Specify an optional CORS list of allowed origin hosts separated by comas. Host ports or protocols aren't
            being checked. Use an asterisk (*) to allow any host [env: SERVER_CORS_ALLOW_ORIGINS=]  [default: ]
    -z, --directory-listing <directory-listing>
            Enable directory listing for all requests ending with the slash character (‘/’) [env:
            SERVER_DIRECTORY_LISTING=]
            SERVER_DIRECTORY_LISTING=]  [default: false]
    -a, --host <host>
            Host address (E.g 127.0.0.1 or ::1) [env: SERVER_HOST=]  [default: ::]

    -t, --http2 <http2>                              Enable HTTP/2 with TLS support [env: SERVER_HTTP2_TLS=]
    -t, --http2 <http2>
            Enable HTTP/2 with TLS support [env: SERVER_HTTP2_TLS=]  [default: false]

        --http2-tls-cert <http2-tls-cert>
            Specify the file path to read the certificate [env: SERVER_HTTP2_TLS_CERT=]  [default: ]

diff --git a/src/config.rs b/src/config.rs
index 7137243..f77f09e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -76,6 +76,16 @@ pub struct Config {

    #[structopt(
        long,
        short = "x",
        parse(try_from_str),
        default_value = "true",
        env = "SERVER_COMPRESSION"
    )]
    /// Gzip, Deflate or Brotli compression on demand determined by the Accept-Encoding header and applied to text-based web file types only.
    pub compression: bool,

    #[structopt(
        long,
        short = "z",
        parse(try_from_str),
        default_value = "false",
diff --git a/src/handler.rs b/src/handler.rs
index 4a9ec48..cb191f7 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -7,6 +7,7 @@ use crate::{error::Result, error_page};
/// Main server request handler.
pub async fn handle_request(
    base: &Path,
    compression: bool,
    dir_listing: bool,
    req: &Request<Body>,
) -> Result<Response<Body>> {
@@ -14,9 +15,11 @@ pub async fn handle_request(
    let method = req.method();

    match static_files::handle_request(method, headers, base, req.uri().path(), dir_listing).await {
        Ok(resp) => {
            // Compression on demand based on`Accept-Encoding` header
            let mut resp = compression::auto(method, headers, resp)?;
        Ok(mut resp) => {
            // Auto compression based on the `Accept-Encoding` header
            if compression {
                resp = compression::auto(method, headers, resp)?;
            }

            // Append `Cache-Control` headers for web assets
            let ext = req.uri().path().to_lowercase();
diff --git a/src/server.rs b/src/server.rs
index c04fe51..701993b 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -78,6 +78,9 @@ impl Server {
        // Directory listing option
        let dir_listing = opts.directory_listing;

        // Auto compression based on the `Accept-Encoding` header
        let compression = opts.compression;

        // Spawn a new Tokio asynchronous server task with its given options
        let threads = self.threads;

@@ -94,7 +97,13 @@ impl Server {
                        Ok::<_, error::Error>(service_fn(move |req| {
                            let root_dir = root_dir.clone();
                            async move {
                                handler::handle_request(root_dir.as_ref(), dir_listing, &req).await
                                handler::handle_request(
                                    root_dir.as_ref(),
                                    compression,
                                    dir_listing,
                                    &req,
                                )
                                .await
                            }
                        }))
                    }
@@ -130,7 +139,13 @@ impl Server {
                        Ok::<_, error::Error>(service_fn(move |req| {
                            let root_dir = root_dir.clone();
                            async move {
                                handler::handle_request(root_dir.as_ref(), dir_listing, &req).await
                                handler::handle_request(
                                    root_dir.as_ref(),
                                    compression,
                                    dir_listing,
                                    &req,
                                )
                                .await
                            }
                        }))
                    }