Replies: 12 comments 1 reply
-
You can use https://docs.rs/salvo_core/0.65.2/salvo_core/http/request/fn.set_secure_max_size.html to set request max payload size. If your handler returns before you read the whole request payload, client will get response immediately. |
Beta Was this translation helpful? Give feedback.
-
Actually even I do nothing in the handler, the error also appears. By the way I'm using the stream and the method above has no effect. |
Beta Was this translation helpful? Give feedback.
-
没看到你的代码 不好说
… From: ***@***.***>
Date: Sat, Feb 10, 2024, 21:30
Subject: Re: [salvo-rs/salvo] Is there any way to take control of request earlier? (Discussion #685)
To: ***@***.***>
Cc: "Chrislearn ***@***.***>, ***@***.***>
Actually even I do nothing in the handler, the error also appears. By the way I'm using the stream and the method above has no effect.
—
Reply to this email directly, view it on GitHub<#685 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ABM2JMDVTHUH6NIXRJN3QB3YS5Y43AVCNFSM6AAAAABDCV4BK2VHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM4DIMRXGM2TM>.
You are receiving this because you commented.[image: https://github.com/notifications/beacon/ABM2JMGEMAMYS2W7OKWT2ZLYS5Y43A5CNFSM6AAAAABDCV4BK2WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAQCLVY.gif]Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
pub async fn upload_avatar(req: &mut Request, res: &mut Response) -> AppResult<()> {
let size_hint = req.body().size_hint().1;
if let Some(upper) = size_hint {
if upper > 10*1024 {
return Err(GlobalUserError::PayloadTooLarge.into());
}
} else {
return Err(GlobalUserError::PayloadLengthRequired.into());
}
let mut stream = StreamReader::new(StreamBody::new(req.body_mut()));
// 上传逻辑
Ok(())
} StreamBody 是 ReqBody 的封装,拆掉了外面的那层 pub struct StreamBody<'a>{
body: Pin<&'a mut ReqBody>
}
impl<'a> StreamBody<'a>{
pub fn new(body: &'a mut ReqBody) -> Self{
StreamBody{body: Pin::new(body)}
}
}
impl Stream for StreamBody<'_> {
type Item = Result<Bytes, std::io::Error>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.body.as_mut().poll_next(cx).map_ok(|f| {
f.into_data().unwrap_or(Bytes::new())
})
}
} |
Beta Was this translation helpful? Give feedback.
-
你要给一个最小重现的demo.zip 然后你这似乎也没必要自己整body 直接map 一下就能把frame 脱掉
|
Beta Was this translation helpful? Give feedback.
-
那有没有办法能先发送响应然后保持到客户端关闭连接 |
Beta Was this translation helpful? Give feedback.
-
当然可以,可以把Body设置成stream.具体自己查阅文档
|
Beta Was this translation helpful? Give feedback.
-
但是好像实际上stream只是到缓冲区,并不是发送到客户端,我用wireshark抓了下包,发现貌似函数退出后才会发送tcp报文 |
Beta Was this translation helpful? Give feedback.
-
用stream就是说你函数先返回了,应该是你没用对,这种底层设计不会有问题的。
|
Beta Was this translation helpful? Give feedback.
-
但是我想要的是先响应,然后同时客户端发送数据的时候服务端继续回应而不是发送reset报文,stream好像实现不了这个功能欸 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
你理解错了,代码写错了
|
Beta Was this translation helpful? Give feedback.
-
I'm working on a file uploading api and I need to limit the size of body to a certain size. But I find out that either the salvo's builtin size limiter or the limiter I wrote in the handler cannot response correctly when using some clients. From the trace info from curl, it looks like that when the program runs to the handler, the client has already started to send the body, and the server's action of closing input cause the client to present a
connection closed
error. But I found nginx, when set withclient_max_body_size
option, can work correctly. I also trace the request and find out that nginx responses the header immediately after client sends its header. Is there any way to take control of request earlier and return the header after receiving the client's header?.Beta Was this translation helpful? Give feedback.
All reactions