Official Discord: https://discord.gg/NWpN5mmg3x | Powerful web framework for Rust | https://github.com/actix/actix-web/wiki/FAQ
robjtede on master
tweak migration document (compare)
github-actions[bot] on gh-pages
Deploying to gh-pages from @ 5… (compare)
github-actions[bot] on gh-pages
Deploying to gh-pages from @ f… (compare)
robjtede on test-v0.1.0-beta.13
robjtede on http-test-v3.0.0-beta.13
robjtede on master
prepare actix-http-test release… prepare actix-test release 0.1.… (compare)
github-actions[bot] on gh-pages
Deploying to gh-pages from @ a… (compare)
robjtede on actors-v4.0.0-beta.12
robjtede on master
prepare actix-web-actors releas… (compare)
robjtede on awc-v3.0.0-beta.21
robjtede on master
prepare awc release 3.0.0-beta.… (compare)
robjtede on http-v3.0.0-rc.3
robjtede on master
prepare actix-http release 3.0.… (compare)
ah I figured that of the two middlewares T1 and T2, they respectively have Response = EitherBody and BoxBody. And then there's this bound
T1: Transform<S, Req, Response = S::Response, Error = S::Error>,
T2: Transform<S, Req, Response = S::Response, Error = S::Error, InitError = T1::InitError>,
Which says that they need to equal S::Response.
I don't really know what S::Response is... I mean all we know is S: Service<Req> + 'static,
. Actually I see from https://docs.rs/actix-web/latest/actix_web/struct.App.html#method.wrap that S = T::Service
(where S is the generic argument in my middleware and T the generic argument in App). Still it's a difficult puzzle...
impl<S, Req, T1, T2, R> Transform<S, Req> for OneOrAnother<T1, T2>
where
S: Service<Req> + 'static,
T1: Transform<S, Req, Response = R, Error = S::Error>,
T2: Transform<S, Req, Response = R, Error = S::Error, InitError = T1::InitError>,
T1::Future: 'static,
type Response = EitherBody<T1::Response, T2::Response>;
My next problem is that Etiher from actix-utils
impls Future like this:
impl<L, R> Future for Either<L, R>
where
L: Future,
R: Future<Output = L::Output>,
{
type Output = L::Output;
I don't understand why it doesn't have type Output = either::Either<L::Output, R::Output>;
.
Can someone here enlighten me whether a PR for this would be desired? Meanwhile, I'll try to find a workaround for my own use case
@robjtede:matrix.org Am I going in the right direction here? Let's just look at the signatures and bounds:
impl<S, Req, T1, T2, Response1, Response2> Transform<S, Req> for OneOrAnother<T1, T2>
where
S: Service<Req> + 'static,
T1: Transform<S, Req, Response = ServiceResponse<Response1>, Error = Error>,
T2: Transform<
S,
Req,
Response = ServiceResponse<Response2>,
Error = Error,
InitError = T1::InitError,
>,
T1::Future: 'static,
T1::InitError: 'static,
T1::Transform: 'static,
T2::Future: 'static,
T2::InitError: 'static,
T2::Transform: 'static,
{
type Response = ServiceResponse<EitherBody<Response1, Response2>>;
type Error = Error;
type Transform = OneOrAnotherMiddleware<T1::Transform, T2::Transform>;
type InitError = T1::InitError;
type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
pub enum OneOrAnotherMiddleware<T1, T2> {
Left(T1),
Right(T2),
}
impl<T1, T2, Response1, Response2, Req> Service<Req> for OneOrAnotherMiddleware<T1, T2>
where
T1: Service<Req, Response = ServiceResponse<Response1>, Error = Error>,
T2: Service<Req, Response = ServiceResponse<Response2>, Error = Error>,
{
type Response = ServiceResponse<EitherBody<Response1, Response2>>;
type Error = Error;
type Future =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self::Response, Self::Error>>>>;
I just made it compile, but it doesn't feel completely right.
I just addedd a lot of bounds and generics (Response1
, Response2
) mainly because of the requirement that all Response
types need to be ServiceResponse<_>
. I didn't make the implementation right now but from the bounds and signatures I think we can deduce that the implementation would sort of.. ignore the ServiceResponse it gets from the inner middlewares, and wrap it anew..? But I'm really in doubt about that.
Hello together :) I'm currently trying to implement an auth-middleware, which sets a user's data as the request's extension. To do so it extracts an auth-token from the requests cookie and queries against a r2d2 postgres-pool in order to determine, whether this token belongs to a user. Following the docs, I passed a clone of the pool to app_data. After setting app_data, I attached my middleware. However, it fails to extract the Pool, meaning I can not use it in its implementation of "call". I checked multiple times that the pool's type while setting app_data matches the type during its extraction.
So my question is:
Is app_data supposed to be available within the context of a middleware, or are there other caveats I'm not aware of?
Thanks in advance! :)
I'm working in a system which shows errors in the middleware although it is running the server already as below:
impl<T: std::fmt::Debug> Response<T>
where T: Serialize {
#[log_derive::logfn(DEBUG)]
#[log_derive::logfn_inputs(DEBUG)]
pub fn into_base_response(self) -> actix_http::Response<actix_web::dev::Body> {
let json = serde_json::to_string(&self).expect("Serializing a Response will never fail");
actix_http::Response::build(self.status.status_code())
.append_header((
super::TRUSTED_USER_ID_HEADER,
self.trusted_user_id
.as_ref()
.map(ToString::to_string)
.unwrap_or_default()
))
.insert_header((actix_web::http::header::CONTENT_TYPE, mime::APPLICATION_JSON))
.body(actix_web::dev::Body::from(json))
}
pub fn into_response(self) -> HttpResponse {
let response = self.into_base_response();
HttpResponse::from(response)
}
}
Found issues as below:
error[E0433]: failed to resolve: could not find `Body` in `dev`
--> common/src/api_v1/response.rs:88:35
|
88 | .body(actix_web::dev::Body::from(json))
| ^^^^ could not find `Body` in `dev`
req.app_data<Data<T>>()
Is it efficient if I connect to DB multiple times , in a single function. For example, I want to authenticate ,
Approach 1:
authenticate() {
let conn = db.connect();
do something;
}
main func() {
call authenticate;
do something;
let conn = db.connect();
func1(conn);
let conn = db.connect();
func2(conn);
}
(or)
approach 2:
main func() {
let conn = db.connect();
authenticate(&conn);
func1(&conn);
func2(&conn);
}
Hi, I was trying to use a cookie with Redis as session store for a Vue 3 front end. Cookie was not being received on the front end. Figured out issue was SameSite setting. Have resolved it and got the app working with the following setting:
.wrap(
SessionMiddleware::builder(
store.clone(),
secret_key.clone(),
).cookie_same_site(SameSite::None)
.cookie_domain(Option::from("127.0.0.1".to_string()))
.cookie_name("Pyar".parse().unwrap())
.cookie_content_security(CookieContentSecurity::Private.clone())
.session_length(SessionLength::Predetermined {
max_session_length: Some(time::Duration::minutes(30)),
})
.build(),
)
Was wondering if there are best practice settings for cookies used with front end SPAs like React or Vue for best security?