Giter Site home page Giter Site logo

trillium-rs / trillium Goto Github PK

View Code? Open in Web Editor NEW
323.0 323.0 17.0 5.05 MB

๐ŸŒฑ๐Ÿฆ€๐ŸŒฑ Trillium is a composable toolkit for building internet applications with async rust

Home Page: https://trillium.rs

License: Apache License 2.0

Rust 82.79% HTML 0.30% Handlebars 0.01% JavaScript 16.90%
trillium

trillium's Introduction

Welcome to Trillium!

๐Ÿ“– Guide ๐Ÿ“–

The guide provides an architectural overview and lay of the land connecting the trillium crates.

๐Ÿ“‘ Rustdocs ๐Ÿ“‘

The rustdocs represent the best way to learn about any of trillium's individual crates and the specific interfaces.




Legal:

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

trillium's People

Contributors

dependabot[bot] avatar divergentdave avatar foresterre avatar jalcine avatar jbr avatar joshtriplett avatar mathiversen avatar mqudsi avatar vijfhoek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

trillium's Issues

Bug report for trillium-websockets

Websocket requests doesn't upgrade in Firefox because of incorrect parsing of the connection header.

To Reproduce
Steps to reproduce the behavior:

  1. Run example
  2. Make websocket request to ws endpoint with firefox

Expected behavior
Successful websocket connection

Screenshots
Screenshot from 2021-06-09 08-19-24

Bug report for trillium-http/cookie: Panic on non ascii cookie

Describe the bug
There are situations where client can send a non ascii cookie, currently trillium panics when encountering one, That can be a potential DOS attack.

To Reproduce
Steps to reproduce the behavior:

  1. Set cookie value to non-ascii symbol in browser.
  2. Send any request.

Expected behavior
At least not panic. May be skip this header and log error would be better.

Looks like this is beacuse of this unwrap.
trillium-http-types-0.0.3/src/headers/headers.rs

pub fn insert(
        &mut self,
        name: impl Into<HeaderName>,
        values: impl ToHeaderValues,
    ) -> Option<HeaderValues> {
        let name = name.into();
        let values: HeaderValues = values.to_header_values().unwrap().collect();
        self.headers.insert(name, values)
    }
Log
TRACE trillium_http::conn: in head, finished headers:
 GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cookie: {78b7507b-cd4e-484e-a1f0-090e7cabdc22}=ั„ั‹ะฒ
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Sec-GPC: 1
Cache-Control: max-age=0    
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: String slice should be valid ASCII', /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-types-0.0.3/src/headers/headers.rs:54:62
stack backtrace:
   0: rust_begin_unwind
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/panicking.rs:92:14
   2: core::result::unwrap_failed
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/core/src/result.rs:1355:5
   3: core::result::Result<T,E>::unwrap
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1037:23
   4: trillium_http_types::headers::headers::Headers::insert
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-types-0.0.3/src/headers/headers.rs:54:36
   5: trillium_http::conn::Conn<Transport>::new::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.1.7/src/conn.rs:498:13
   6: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
   7: trillium_http::conn::Conn<Transport>::next::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.1.7/src/conn.rs:686:9
   8: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
   9: trillium_http::conn::Conn<Transport>::finish::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.1.7/src/conn.rs:721:19
  10: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  11: trillium_http::conn::Conn<Transport>::send::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.1.7/src/conn.rs:174:22
  12: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  13: trillium_http::conn::Conn<Transport>::map::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.1.7/src/conn.rs:148:26
  14: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  15: <trillium_server_common::config::Config<ServerType,AcceptorType> as trillium_server_common::config_ext::ConfigExt<ServerType,AcceptorType>>::handle_stream::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-server-common-0.1.2/src/config_ext.rs:154:22
  16: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  17: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:120:9
  18: tokio::runtime::task::core::CoreStage<T>::poll::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/core.rs:243:17
  19: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/loom/std/unsafe_cell.rs:14:9
  20: tokio::runtime::task::core::CoreStage<T>::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/core.rs:233:13
  21: tokio::runtime::task::harness::poll_future::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:438:23
  22: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  23: std::panicking::try::do_call
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  24: __rust_try
  25: std::panicking::try
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  26: std::panic::catch_unwind
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  27: tokio::runtime::task::harness::poll_future
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:425:19
  28: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:89:9
  29: tokio::runtime::task::harness::Harness<T,S>::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:59:15
  30: tokio::runtime::task::raw::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/raw.rs:113:5
  31: tokio::runtime::task::raw::RawTask::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/raw.rs:70:18
  32: tokio::runtime::task::Notified<S>::run
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/mod.rs:171:9
  33: tokio::runtime::thread_pool::worker::Context::run_task::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:349:13
  34: tokio::coop::with_budget::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/coop.rs:106:9
  35: std::thread::local::LocalKey<T>::try_with
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:376:16
  36: std::thread::local::LocalKey<T>::with
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:352:9
  37: tokio::coop::with_budget
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/coop.rs:99:5
  38: tokio::coop::budget
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/coop.rs:76:5
  39: tokio::runtime::thread_pool::worker::Context::run_task
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:348:9
  40: tokio::runtime::thread_pool::worker::Context::run
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:318:24
  41: tokio::runtime::thread_pool::worker::run::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:303:17
  42: tokio::macros::scoped_tls::ScopedKey<T>::set
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/macros/scoped_tls.rs:61:9
  43: tokio::runtime::thread_pool::worker::run
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:300:5
  44: tokio::runtime::thread_pool::worker::Launch::launch::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/thread_pool/worker.rs:279:45
  45: <tokio::runtime::blocking::task::BlockingTask<T> as core::future::future::Future>::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/blocking/task.rs:42:21
  46: tokio::runtime::task::core::CoreStage<T>::poll::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/core.rs:243:17
  47: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/loom/std/unsafe_cell.rs:14:9
  48: tokio::runtime::task::core::CoreStage<T>::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/core.rs:233:13
  49: tokio::runtime::task::harness::poll_future::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:438:23
  50: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  51: std::panicking::try::do_call
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  52: __rust_try
  53: std::panicking::try
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  54: std::panic::catch_unwind
             at /home/mark/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  55: tokio::runtime::task::harness::poll_future
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:425:19
  56: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:89:9
  57: tokio::runtime::task::harness::Harness<T,S>::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/harness.rs:59:15
  58: tokio::runtime::task::raw::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/raw.rs:113:5
  59: tokio::runtime::task::raw::RawTask::poll
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/raw.rs:70:18
  60: tokio::runtime::task::Notified<S>::run
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/task/mod.rs:171:9
  61: tokio::runtime::blocking::pool::Inner::run
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/blocking/pool.rs:265:17
  62: tokio::runtime::blocking::pool::Spawner::spawn_thread::{{closure}}
             at /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.8.1/src/runtime/blocking/pool.rs:245:17
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Attribute access is inconsistent

There are up to three accessors on conn for each attribute. For a given {attr} and {value},

setter: set_{attr}(&mut self, {value});
getter: {attr}(&self) -> {value}
chainable setter / builder: with_{attr}(self, {value}) -> self

although this prioritizes the getter, which doesn't necessarily make sense
there should be a systematic naming convention for this. For something like status, maybe it would be `with_status(

Returning a long Vec<u8> panics

I'm trying to return a 27477 byte long Vec<u8> using conn.ok(...) but when doing so, the tokio/async-std (tried both) runtime workers panic with in the latter case the following backtrace:

Click to expand

[src/main.rs:67] thumbnail.len() = 27477
thread 'async-std/runtime' panicked at 'source slice length (0) does not match destination slice length (8192)', /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/slice/mod.rs:3058:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
   2: core::slice::<impl [T]>::copy_from_slice::len_mismatch_fail
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/slice/mod.rs:3051:13
   3: core::slice::<impl [T]>::copy_from_slice
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/slice/mod.rs:3058:13
   4: <trillium_http::body::Body as futures_io::if_std::AsyncRead>::poll_read
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.2.0/src/body.rs:129:17
   5: <futures_lite::io::BufReader<R> as futures_io::if_std::AsyncBufRead>::poll_fill_buf
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/io.rs:635:32
   6: <futures_lite::io::copy::{{closure}}::CopyFuture<R,W> as core::future::future::Future>::poll
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/io.rs:87:37
   7: futures_lite::io::copy::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/io.rs:108:5
   8: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
   9: trillium_http::conn::Conn<Transport>::send::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.2.0/src/conn.rs:157:17
  10: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  11: trillium_http::conn::Conn<Transport>::map::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-http-0.2.0/src/conn.rs:144:26
  12: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  13: <trillium_server_common::config::Config<ServerType,AcceptorType> as trillium_server_common::config_ext::ConfigExt<ServerType,AcceptorType>>::handle_stream::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-server-common-0.3.0/src/config_ext.rs:173:22
  14: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  15: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/future.rs:119:9
  16: <async_std::task::builder::SupportTaskLocals<F> as core::future::future::Future>::poll::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.10.0/src/task/builder.rs:199:17
  17: async_std::task::task_locals_wrapper::TaskLocalsWrapper::set_current::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.10.0/src/task/task_locals_wrapper.rs:60:13
  18: std::thread::local::LocalKey<T>::try_with
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:400:16
  19: std::thread::local::LocalKey<T>::with
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:376:9
  20: async_std::task::task_locals_wrapper::TaskLocalsWrapper::set_current
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.10.0/src/task/task_locals_wrapper.rs:55:9
  21: <async_std::task::builder::SupportTaskLocals<F> as core::future::future::Future>::poll
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.10.0/src/task/builder.rs:197:13
  22: async_executor::Executor::spawn::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:144:13
  23: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  24: async_task::raw::RawTask<F,T,S>::run
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  25: async_task::runnable::Runnable::run
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/runnable.rs:309:18
  26: async_executor::Executor::run::{{closure}}::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:235:21
  27: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  28: <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/future.rs:529:33
  29: async_executor::Executor::run::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:242:9
  30: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19
  31: <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/future.rs:529:33
  32: async_io::driver::block_on
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-io-1.6.0/src/driver.rs:142:33
  33: async_global_executor::reactor::block_on::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-global-executor-2.0.2/src/reactor.rs:3:18
  34: async_global_executor::reactor::block_on
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-global-executor-2.0.2/src/reactor.rs:12:5
  35: async_global_executor::threading::thread_main_loop::{{closure}}::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-global-executor-2.0.2/src/threading.rs:95:17
  36: std::thread::local::LocalKey<T>::try_with
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:400:16
  37: std::thread::local::LocalKey<T>::with
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:376:9
  38: async_global_executor::threading::thread_main_loop::{{closure}}
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-global-executor-2.0.2/src/threading.rs:89:13
  39: std::panicking::try::do_call
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:401:40
  40: __rust_try
  41: std::panicking::try
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:365:19
  42: std::panic::catch_unwind
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panic.rs:434:14
  43: async_global_executor::threading::thread_main_loop
             at /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/async-global-executor-2.0.2/src/threading.rs:88:12
  44: core::ops::function::FnOnce::call_once
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

When truncating the Vec to 8192 bytes, the panic disappears.

Support for unix sockets

Discussed in #82

Originally posted by markusgod July 21, 2021
Unix socket support is usefull when app will be deployed behind a proxy (like nginx).
As an example warp currently allows to use tokio's UnixListener.

#[cfg(unix)]
#[tokio::main]
async fn main() {
    use tokio::net::UnixListener;
    use tokio_stream::wrappers::UnixListenerStream;

    pretty_env_logger::init();

    let listener = UnixListener::bind("/tmp/warp.sock").unwrap();
    let incoming = UnixListenerStream::new(listener);
    warp::serve(warp::fs::dir("examples/dir"))
        .run_incoming(incoming)
        .await;
}

#[cfg(not(unix))]
#[tokio::main]
async fn main() {
    panic!("Must run under Unix-like platform!");
}
```</div>

SessionHandler should allow taking multiple secrets

This is useful for production apps where we can gradually rollout the apps. If primary fails to decrypt we should decrypt with secondary.

SessionHandler::new(MemoryStore::new(), primary_secret, secondary_secret);

Secondary secret could be an Option.

trillium-http protocol correctness

in particular http/1.0 vs http/1.1. It does support both, but likely does not do so correctly yet. This just needs a bit more careful attention, and has been less important than showing the other capabilities of the trillium approach

Fix the client tls options

and possibly extract both the client and server tls implementations to a single crate with feature flags

look into switching from `http-types` to `http`

I'd like to drop the dependency on http-types and evaluate the http crate. Right now the most important types trillium uses from http-types are Headers, Extensions, StatusCode, Method, and Body. Extensions probably could be replaced with typemap and Body probably could be something simpler than http-types's body. The other types have direct analogues in http.

Feature suggestion for `trillium-router`: Allow `String` or `&str` to be used as the path

While working on Lighthouse, I wanted a way to 'build' route URLs for use elsewhere (like returning in a page or in my case, checking if it's referenced in a remote document as part of Webmention discovery). I attempted to do the following to build my pathsโ€”a change from manually writing in the URL, and it didn't work. It looks like TryFrom for RouteSpec is a thing, so I'm curious as to why it's been restricted to require a lifetime across the entire application.

    static URL_PATH_WEBMENTION_PREFIX: &str = "/endpoints/webmention";
Router::build(|mut router| {
    let path = format!("{}/:token", URL_PATH_WEBMENTION_PREFIX).as_str();

    // This _will_ fail, I did `path.as_str()` initially but of course, that's a short-lived reference.
    router.get(path, |conn: Conn| async move { conn.halt() })
})

(Originally posted at https://jacky.wtf/2022/4/nS/nSsFq7XHDUUOpXCc6ptwtfOx)

h2/h3

As a long term goal, I'd like to look into h2 and h3. I really don't want to write my own implementation of these, but I'm not sure how hard it will be to fit existing implementations into the conn model.

Router: OPTIONS request handling for CORS

Discussed in #62

Originally posted by happysalada July 5, 2021
On a cors request the browser sends an OPTIONS request to check for the cors header.
How can I respond to the OPTIONS request. I couldn't find a method on the router for it.
https://docs.rs/trillium-router/0.1.0/trillium_router/struct.Router.html
I tried using any but it didn't work. Perhaps there is a way I haven't found yet?
Or is it just waiting adding an Options here ? https://docs.rs/trillium-router/0.1.0/src/trillium_router/router.rs.html#138
Just curious.

max-connections/backpressure/load-shedding

Logic for when the server is overwhelmed, like backpressure or load shedding. Potentially since we have a count of the number of open connections, we can also set a maximum number of connections and choices for what to do when that threshold is met (put them in a queue or just respond immediately with an error). This is not essential now, but I think it's valuable to be able to point to mature features like this when communicating with people assessing this as a framework to build on.

trillium-http security and perf

trillium-http may have security vulnerabilities, but once people are using trillium, I intend to make the http implementation comparable in correctness and speed to other rust http implementations

A blog post about the API?

I'd love to read from you, as an insider, about different approaches to server-side web frameworks in Rust. As a user, I can guess that Rocket gives more compile time guaranties, comparing to eg Actix. Tide and warp seems more straightforward and easy to use for smaller things like microservices. Dropshot and Rocket (potentially) can auto-generate OpenApi specs. Would you elaborate on these trade-offs with maybe some examples of APIs comparing to once taken by Trillium? Maybe in form of a blogpost to have people responses?

add support for verifying the response header is absent

Is it possible to support None for a non existence header? Passing empty string will not work since the None != Some("").

I added the compression middleware and wanted to do a sanity test.

#[test]
fn should_compress_html() {
    let handler = app();
    assert_headers!(
        get("/")
            .with_request_header(KnownHeaderName::AcceptEncoding, "gzip, deflate, br")
            .on(&handler),
        "content-encoding" => "br"
    );

    assert_headers!(
        get("/")
            .with_request_header(KnownHeaderName::AcceptEncoding, "gzip")
            .on(&handler),
        "content-encoding" => "gzip"
    );

    assert_headers!(
        get("/")
            .with_request_header(KnownHeaderName::AcceptEncoding, "")
            .on(&handler),
        "content-encoding" => None
    );

}

Cannot run nesting router example

Was just testing out the code on the Nesting example Nesting Router and have the following error:

`
Listening at 127.0.0.1:8080 (bound as tcp://127.0.0.1:8080)

Control-C to quit
thread 'main' panicked at 'cannot call init when there are already clones of an Arc', /home/ed/.cargo/registry/src/github.com-1ecc6299db9ec823/trillium-0.2.2/src/handler.rs:211:14
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
`

Bug report for `trillium-async-std`: Ctrl-C crashes the server on Windows

Describe the bug
The handling of Ctrl-C currently fails on Windows: pressing Ctrl-C leads to crash.

To Reproduce

  1. Run the following code:
fn main() {
    trillium_async_std::config()
        .with_host("127.0.0.1")
        .with_port(7878)
        .run(|conn: Conn| async move { conn.ok("It will fail")})
}
  1. Press Ctrl-C.
  2. The server would crash with the following message:

error: process didn't exit successfully: target\debug\trillium-fun.exe (exit code: 0xc000013a, STATUS_CONTROL_C_EXIT)

Expected behavior
The server stops gracefully.

Screenshots
Not applicable.

Desktop

  • OS: Windows 11 (Microsoft Windows [Version 10.0.22000.593])
  • Browser: does not matter
  • Version: from cargo.lock, trillium 0.2.2, trillium-asyn-std 0.2.0

Additional context
Just in case I checked the other adapters: trillium-tokio and trillium-smol fail in the same way.

make it easy to get the response string

Seems like take_request_body_string internally uses block on but not take_response_body_string.

#[test]
fn test_html_output() {
    trillium_testing::block_on(async {
        let html = get("/")
            .on(&handler)
            .take_response_body_string()
            .await
            .unwrap();
        assert_eq!(&html, "some html content");
    });
}

I need to get html output and use selector to verify the response output using https://crates.io/crates/nipper. Is it possible to make it easy to get the response body so it is simple as the request body? I would expect the above code to be simple as below.

    let mut conn = TestConn::build("post", "/", "some body")
        .with_request_body("once told me");
    assert_eq!(conn.take_request_body_string(), "once told me");

GraphQL support

It'd be nice to have a Trillium plugin for turning an endpoint into a GraphQL interface. To my knowledge there are really only two major GraphQL implementations for Rust, Juniper and async-graphql, and plug-ins could potentially be provided for both.

Bug report for `trillium-proxy`: does not response on status 204, 304

Describe the bug
Proxy does not response on status 204, 304.

To Reproduce
Steps to reproduce the behavior:

  1. Run the proxy example code: https://trillium.rs/handlers/proxy.html (it's proxy to https://httpbin.org/)
  2. curl on 'localhost:8080/status/204'
  3. Does not response

Expected behavior

Should response with no body.

Screenshots

from example code:

use trillium_logger::Logger;
use trillium_rustls::RustlsConnector;
use trillium_smol::TcpConnector;

type Proxy = trillium_proxy::Proxy<RustlsConnector<TcpConnector>>;

pub fn main() {
    env_logger::init();
    trillium_smol::run((Logger::new(), Proxy::new("https://httpbin.org/")));
}

with proxy:

% curl localhost:8080/status/204 -i
HTTP/1.1 204 No Content
access-control-allow-credentials: true
access-control-allow-origin: *
connection: keep-alive
content-type: text/html; charset=utf-8
date: Sun, 18 Jul 2021 12:40:56 GMT
server: gunicorn/19.9.0
transfer-encoding: chunked

without proxy:

% curl https://httpbin.org/status/204 -i
HTTP/2 204 
date: Sun, 18 Jul 2021 12:48:50 GMT
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true

Desktop (please complete the following information):

  • OS: macOS Big Sur 11.4
  • Browser curl
  • Version 7.64.1

Bug report for `trillium-method-override`: Not converting from method field in request body

Describe the bug
While using htmx.org, namely hx-post with <input type="hidden" name="_method" value="put"> in a form, I noticed that the request wasn't being translated into an PUT request on the server side.

To Reproduce
Reproduction of this could work by copying one of the tests at trillium-rs/trillium#main/method-override/tests/tests.rs:L16-L29 but instead of checking the query string , putting the test body as the request body, like:

assert_ok!(post("/").with_request_body("_method=put").on(&amp;app), "it was a PUT");

This way, it'll show that the use of only query string extraction wouldn't be enough. However, it looks like reading the body of the request will mutate the connection itself at https://docs.rs/trillium/latest/src/trillium/conn.rs.html#257-274. Perhaps an updated test will show otherwise.

Expected behavior
Proper conversion of a POST request with a hint to the expected HTTP Verb.

Additional context
I figure that the code of method-override is a bit older than the tests and perhaps led to this not being covered.

(Originally published at: https://jacky.wtf/2022/4/W1/W1YTNu6QaaLQ33o0zcbWFhRr)

look into making `trillium::Conn<S> where S: Server` (and Handler)

I'm going to explore making Conn generic over the server type, which would open up the possibility of spawning tasks off of Conn. I might hate this in practice because it will require application code import something like trillium_smol_server::Conn instead of trillium::Conn, but library code would be generic over trillium::Conn<S> where S: Server. One exciting upside of this is that some library could say impl Handler<Smol> for MyHandler instead of impl<S> Handler<S> for MyHandler where S: Server, allowing them to write different implementations.

Consider other essential handlers

from rails:

  • Rack::Sendfile Sets server specific X-Sendfile header. Configure this via config.action_dispatch.x_sendfile_header option.
  • ActionDispatch::Static Used to serve static files from the public directory. Disabled if config.public_file_server.enabled is false.
  • Rack::Lock -- Sets env["rack.multithread"] flag to false and wraps the application within a Mutex.
  • ActionDispatch::Executor Used for thread safe code reloading during development.
  • ActiveSupport::Cache::Strategy::LocalCache::Middleware -- Used for memory caching. This cache is not thread safe.
  • Rack::Runtime Sets an X-Runtime header, containing the time (in seconds) taken to execute the request.
  • Rack::MethodOverride -- Allows the method to be overridden if params[:_method] is set. This is the middleware which supports the PUT and DELETE HTTP method types.
  • ActionDispatch::RequestId Makes a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#request_id method.
  • ActionDispatch::RemoteIp Checks for IP spoofing attacks.
  • Sprockets::Rails::QuietAssets Suppresses logger output for asset requests.
  • Rails::Rack::Logger Notifies the logs that the request has begun. After the request is complete, flushes all the logs.
  • ActionDispatch::ShowExceptions Rescues any exception returned by the application and calls an exceptions app that will wrap it in a format for the end user.
  • ActionDispatch::DebugExceptions Responsible for logging exceptions and showing a debugging page in case the request is local.
  • ActionDispatch::ActionableExceptions Provides a way to dispatch actions from Rails' error pages.
  • ActionDispatch::Reloader Provides prepare and cleanup callbacks, intended to assist with code reloading during development.
  • ActionDispatch::Callbacks Provides callbacks to be executed before and after dispatching the request.
  • ActiveRecord::Migration::CheckPending Checks pending migrations and raises ActiveRecord::PendingMigrationError if any migrations are pending.
  • ActionDispatch::Cookies Sets cookies for the request.
  • ActionDispatch::Session::CookieStore Responsible for storing the session in cookies.
  • ActionDispatch::Flash Sets up the flash keys. Only available if config.action_controller.session_store is set to a value.
  • ActionDispatch::ContentSecurityPolicy::Middleware Provides a DSL to configure a Content-Security-Policy header.
  • Rack::Head Converts HEAD requests to GET requests and serves them as so.
  • Rack::ConditionalGet Adds support for "Conditional GET" so that server responds with nothing if the page wasn't changed.
  • Rack::ETag Adds ETag header on all String bodies. ETags are used to validate cache.
  • Rack::TempfileReaper Cleans up tempfiles used to buffer multipart requests.

from phoenix:

  • Plug.Static - serves static assets. Since this plug comes before the logger, serving of static assets is not logged
  • Phoenix.CodeReloader - a plug that enables code reloading for all entries in the web directory. It is configured directly in the Phoenix application
  • Plug.RequestId - generates a unique request id for each request.
  • Plug.Telemetry - adds instrumentation points so Phoenix can log the request path, status code and request time by default.
  • Plug.Parsers - parses the request body when a known parser is available. By default parsers parse urlencoded, multipart and json (with jason). The request body is left untouched when the request content-type cannot be parsed
  • Plug.MethodOverride - converts the request method to PUT, PATCH or DELETE for POST requests with a valid _method parameter
  • Plug.Head - converts HEAD requests to GET requests and strips the response body
  • Plug.Session - a plug that sets up session management. Note that fetch_session/2 must still be explicitly called before using the session as this Plug just sets up how the session is fetched
  • accepts Performs content negotiation based on the available formats.
  • fetch_flash Fetches the flash storage.
  • put_secure_browser_headers Put headers that improve browser security.

from plug:

  • Plug.BasicAuth - provides Basic HTTP authentication;
  • Plug.CSRFProtection - adds Cross-Site Request Forgery protection to your application. Typically required if you are using Plug.Session;
  • Plug.Head - converts HEAD requests to GET requests;
  • Plug.Logger - logs requests;
  • Plug.MethodOverride - overrides a request method with one specified in the request parameters;
  • Plug.Parsers - responsible for parsing the request body given its content-type;
  • Plug.RequestId - sets up a request ID to be used in logs;
  • Plug.RewriteOn - rewrite the request's host/port/protocol from x-forwarded-* headers;
  • Plug.Session - handles session management and storage;
  • Plug.SSL - enforces requests through SSL;
  • Plug.Static - serves static files;
  • Plug.Telemetry - instruments the plug pipeline with :telemetry events;

from express

  • body-parser - previous bodyParser, json, and urlencoded. You may also be interested in:
  • compression
  • connect-timeout
  • cookie-parser
  • cookie-session
  • csurf
  • errorhandler
  • express-session
  • method-override
  • morgan logger
  • response-time
  • serve-favicon
  • serve-static
  • vhost

Running code after response is sent

Trillium looks really nice and I thought I'd give it a go for a small project. I was wondering if it's possible to run some code after the response is finished? I have a situation where I need to perform an operation that will affect the machine's ability to send a response, so this can only be started once the response has actually been sent.

Bug report for trillium-static-compiled: Missing charset in response headers

When i try to serve a .js file i get this error in firefox: Uncaught SyntaxError: identifier starts immediately after numeric literal and it looks like charset=utf-8 is missing in the content-type.

Not sure if you can just add the charset here: static-compiled or if you want to do something else.

In short i think it should be: Content-Type: "application/javascript; charset=utf-8"

log right before server can start accepting

Is there an equivalent of this?

let mut app = tide::new();
let mut listener = app.bind(("0.0.0.0", "3000")).await?;
for info in listener.info().iter() {
    println!("Server listening on {}", info);
}
listener.accept().await?;

trillium-static should respect If-None-Match and ETag and return no content if it matches

Seems like trillium-static sends the file with correct response headers but never looks at the request header and always sends the full response body instead of a 304 Not Modified.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#caching_of_unchanged_resources

The server compares the client's ETag (sent with If-None-Match) with the ETag for its current version of the resource, and if both values match (that is, the resource has not changed), the server sends back a 304 Not Modified status, without a body, which tells the client that the cached version of the response is still good to use (fresh).

Add support for sending a file

I have been working on porting a tide app to use trillium and noticed that there is no way to send a single file. Closest I found was StaticFileHandler.

I'm looking for an alternative for Body::from_file().

 let res = Response::builder(StatusCode::Ok)
                .header("cache-control", "max-age=31536000") // 1 year as second
                .body(Body::from_file(&attachment.get_path()).await?)
                .build();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.