Giter VIP home page Giter VIP logo

saphir's People

Contributors

awakecoding avatar bcortier-devolutions avatar cbenoit avatar dependabot-preview[bot] avatar dependabot[bot] avatar dsaikali avatar ekse avatar fdubois1 avatar lolo32 avatar lucfauvel avatar pacmancoder avatar recurse-blip avatar richerarc avatar richerlariviere avatar rutrum avatar samuel-b-d avatar sduquette-devolutions avatar sylfwood 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saphir's Issues

[FEATURE] casing for route parameters

route positional paameters name are arbitrarly, so they could be changed to a prefered casing for the api generation.
For example, changing them to camelCase so that when you generate a typescript API for it with ng-openapi-gen, you would have parameters name in the same casing as the rest of your codebase.

[FEATURE] Performance: handler pointers collection on server

Description of the feature
To improve performance, instead of using dynamic dispatch at runtime, in Server::build we could create a fixed list pointers to all registered handlers, which could be iterated through without having to use any dyn_handle.

Is your feature request related to a problem?
Not related to a problem, just a performance improvement

[BUG] Server can't be run due to lack of Send trait on run() future

Description
The following simple code snippet fails on compilation when trying to use saphir 2.8.0 alongside with tokio 0.3.4

use saphir::server::Server;
use tokio::runtime::Runtime;

fn main() {
    let server = Server::builder().build();
    tokio::spawn(server.run());
}
[package]
name = "saphir-test"
version = "0.1.0"
edition = "2018"

[dependencies]
tokio = { version = "=0.3.4", features = [ "rt" ]}
saphir = "=2.8"

This code fails due to the following error:

error[E0277]: `(dyn Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
   --> src\main.rs:6:5
    |
6   |     tokio::spawn(server.run());
    |     ^^^^^^^^^^^^ `(dyn Future<Output = ()> + Unpin + 'static)` cannot be sent between threads safely
    | 
   ::: C:\Users\pacmancoder\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.3.4\src\task\spawn.rs:128:21
    |
128 |         T: Future + Send + 'static,
    |                     ---- required by this bound in `tokio::spawn`
    |
    = help: the trait `Send` is not implemented for `(dyn Future<Output = ()> + Unpin + 'static)`
    = note: required because of the requirements on the impl of `Send` for `Unique<(dyn Future<Output = ()> + Unpin + 'static)>`
    = note: required because it appears within the type `Box<(dyn Future<Output = ()> + Unpin + 'static)>`
    = note: required because it appears within the type `Pin<Box<(dyn Future<Output = ()> + Unpin + 'static)>>`
    = note: required because it appears within the type `saphir::server::ServerShutdown`
    = note: required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}`
    = note: required because it appears within the type `[static generator@saphir::server::Server::run::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}]`
    = note: required because it appears within the type `from_generator::GenFuture<[static generator@saphir::server::Server::run::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23, 't24, 't25, 't26, 't27, 't28, 't29, 't30, 't31, 't32, 't33, 't34, 't35, 't36, 't37, 't38, 't39, 't40, 't41, 't42, 't43, 't44, 't45, 't46, 't47, 't48, 't49, 't50, 't51, 't52, 't53, 't54, 't55, 't56, 't57, 't58> {ResumeTy, saphir::server::Server, ListenerConfig, saphir::server::Stack, HeaderValue, Option<usize>, &'r saphir::server::Stack, saphir::hyper::server::conn::Http, &'s String, String, impl Future, (), tokio::net::tcp::listener::TcpListener, SocketAddr, tokio::net::tcp::incoming::Incoming<'t0>, saphir::server::ServerShutdown, Arc<saphir::server::SeverShutdownState>, Option<u64>, u64, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t1>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t17>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#1}]>, saphir::server::ServerShutdown>, futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t33>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerFuture<futures_util::stream::stream::for_each_concurrent::ForEachConcurrent<tokio::net::tcp::incoming::Incoming<'t46>, impl Future, [closure@saphir::server::Server::run::{closure#0}::{closure#2}]>, saphir::server::ServerShutdown>}]>`
    = note: required because it appears within the type `impl Future`
    = note: required because it appears within the type `impl Future`

error: aborting due to previous error; 1 warning emitted

However, on version 2.7.7 of saphir everything works as expected.

Expected behavior
The provided snippet can be run with saphir 2.8.0 the same way it works with saphir 2.7.7

Additional info (please complete the following information):

  • OS & OS Version: Windows 10 rev.2004
  • Saphir Version: 2.8.0
  • Rust toolchain & version: stable 1.48

Unlimited Path Matching with Captured Path

Add possibility to match any route like /page/<path..>/view. This would match any route that begins with /page and ends with /view, the in between path will be saved in the path capture

[BUG] FileMiddleware issue: HEAD request on a file doesn't cache the file properly

Description
If you use the FileMiddleware with a cache, there is an issue if you receive a HEAD request on a file before any GET request. The problem is that we save in cache an empty file since we don't read it so we save an empty file in cache. All GET request receive after don't return the file as expected.

(Of course, the file has to be cached. Depending of the cache configuration, it could work or not. But for sure, you can get cases that don't work)

Expected behavior
GET request on a file should return the file, even if we have receive a HEAD request before.

Additional info (please complete the following information):

  • Saphir Version: 2.8

[BUG] Query string params don't work in certain cases

I found two edge-cases where the query string parameters are not working in a macro handler in version 3.0.0:

  • same name as the route
#[get("/queries")]
async fn multiple_queries(&self, queries: Option<usize>) -> Result<Json<Vec<World>>, BenchmarkControllerError> {
    // GET /queries?queries=20
    println!("{:?}", queries); // None
}
  • single-letter
#[get("/queries")]
async fn multiple_queries(&self, q: Option<usize>) -> Result<Json<Vec<World>>, BenchmarkControllerError> {
    // GET /queries?q=20
    println!("{:?}", q); // None
}

Other schemes works properly:

#[get("/queries")]
async fn multiple_queries(&self, nb: Option<usize>) -> Result<Json<Vec<World>>, BenchmarkControllerError> {
    // GET /queries?nb=20
    println!("{:?}", q); // Some(20)
}

[Question] - Websocket upgrade

Hello, @richerarc

I would like to know, if I can upgrade the Http request to websocket?
Also, I would like to know if the framework could work with pool of threads to handle those connections ?
And, Iโ€™m new in rust, so if there is any example how to handle the questions above, I would appreciated
Thanks you so much

[BUG]can not complie

Description
A clear and concise description of what the bug is.
saphir v2.6.7
error[E0277]: the trait bound hyper::body::body::Body: std::convert::From<std::boxed::Box<dyn futures_core::stream::Stream<Item = std::result::Result<bytes::bytes::Bytes, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>> + std::marker::Send + std::marker::Sync>> is not satisfied
--> /home/guoyibin3/.cargo/registry/src/github.com-1ecc6299db9ec823/saphir-2.6.7/src/response.rs:374:18
|
374 | self.body(Box::new(file.into())
| ^^^^ the trait std::convert::From<std::boxed::Box<dyn futures_core::stream::Stream<Item = std::result::Result<bytes::bytes::Bytes, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>> + std::marker::Send + std::marker::Sync>> is not implemented for hyper::body::body::Body
|
= help: the following implementations were found:
<hyper::body::body::Body as std::convert::From<&'static [u8]>>
<hyper::body::body::Body as std::convert::From<&'static str>>
<hyper::body::body::Body as std::convert::Frombytes::bytes::Bytes>
<hyper::body::body::Body as std::convert::From<std::borrow::Cow<'static, [u8]>>>
and 4 others
= note: required because of the requirements on the impl of std::convert::Into<hyper::body::body::Body> for std::boxed::Box<dyn futures_core::stream::Stream<Item = std::result::Result<bytes::bytes::Bytes, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>> + std::marker::Send + std::marker::Sync>

error: aborting due to previous error

For more information about this error, try rustc --explain E0277.
error: could not compile saphir.
Expected behavior
A clear and concise description of what you expected to happen.

Additional info (please complete the following information):

  • OS & OS Version: [ubuntu 20]
  • Saphir Version [2.0.0]
  • Rust toolchain & version [1.43.1 (8d69840ab 2020-05-04)
    ]

Dependency Injection

Add a notion of dependency injection inside the server

  • Implement the service trait
  • Add the configure services method on the server
  • Add notion of dependencies through the middleware & controllers trait

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.