mirror of
https://github.com/actix/actix-web.git
synced 2024-11-22 01:21:10 +00:00
refactor(multipart): move lints to manifest
This commit is contained in:
parent
7326707599
commit
00c185f617
4 changed files with 61 additions and 59 deletions
|
@ -69,3 +69,8 @@ futures-util = { version = "0.3.17", default-features = false, features = ["allo
|
|||
multer = "3"
|
||||
tokio = { version = "1.24.2", features = ["sync"] }
|
||||
tokio-stream = "0.1"
|
||||
|
||||
[lints.rust]
|
||||
future_incompatible = { level = "deny" }
|
||||
rust_2018_idioms = { level = "deny" }
|
||||
nonstandard_style = { level = "deny" }
|
||||
|
|
|
@ -46,9 +46,6 @@
|
|||
//! -F file=@./Cargo.lock
|
||||
//! ```
|
||||
|
||||
#![deny(rust_2018_idioms, nonstandard_style)]
|
||||
#![warn(future_incompatible)]
|
||||
#![allow(clippy::borrow_interior_mutable_const)]
|
||||
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
|
||||
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
cmp,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
task::{Context, Poll},
|
||||
|
@ -75,7 +76,7 @@ impl PayloadBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Read exact number of bytes
|
||||
/// Read exact number of bytes.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn read_exact(&mut self, size: usize) -> Option<Bytes> {
|
||||
if size <= self.buf.len() {
|
||||
|
@ -87,7 +88,7 @@ impl PayloadBuffer {
|
|||
|
||||
pub(crate) fn read_max(&mut self, size: u64) -> Result<Option<Bytes>, MultipartError> {
|
||||
if !self.buf.is_empty() {
|
||||
let size = std::cmp::min(self.buf.len() as u64, size) as usize;
|
||||
let size = cmp::min(self.buf.len() as u64, size) as usize;
|
||||
Ok(Some(self.buf.split_to(size).freeze()))
|
||||
} else if self.eof {
|
||||
Err(MultipartError::Incomplete)
|
||||
|
@ -96,7 +97,7 @@ impl PayloadBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Read until specified ending
|
||||
/// Read until specified ending.
|
||||
pub(crate) fn read_until(&mut self, line: &[u8]) -> Result<Option<Bytes>, MultipartError> {
|
||||
let res = memchr::memmem::find(&self.buf, line)
|
||||
.map(|idx| self.buf.split_to(idx + line.len()).freeze());
|
||||
|
@ -108,12 +109,12 @@ impl PayloadBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Read bytes until new line delimiter
|
||||
/// Read bytes until new line delimiter.
|
||||
pub(crate) fn readline(&mut self) -> Result<Option<Bytes>, MultipartError> {
|
||||
self.read_until(b"\n")
|
||||
}
|
||||
|
||||
/// Read bytes until new line delimiter or eof
|
||||
/// Read bytes until new line delimiter or EOF.
|
||||
pub(crate) fn readline_or_eof(&mut self) -> Result<Option<Bytes>, MultipartError> {
|
||||
match self.readline() {
|
||||
Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())),
|
||||
|
@ -121,7 +122,7 @@ impl PayloadBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Put unprocessed data back to the buffer
|
||||
/// Put unprocessed data back to the buffer.
|
||||
pub(crate) fn unprocessed(&mut self, data: Bytes) {
|
||||
let buf = BytesMut::from(data.as_ref());
|
||||
let buf = std::mem::replace(&mut self.buf, buf);
|
||||
|
|
|
@ -34,7 +34,7 @@ const MAX_HEADERS: usize = 32;
|
|||
/// used for nested multipart streams.
|
||||
pub struct Multipart {
|
||||
safety: Safety,
|
||||
inner: Option<InnerMultipart>,
|
||||
inner: Option<Inner>,
|
||||
error: Option<MultipartError>,
|
||||
}
|
||||
|
||||
|
@ -90,12 +90,12 @@ impl Multipart {
|
|||
{
|
||||
Multipart {
|
||||
safety: Safety::new(),
|
||||
inner: Some(InnerMultipart {
|
||||
inner: Some(Inner {
|
||||
payload: PayloadRef::new(PayloadBuffer::new(stream)),
|
||||
content_type: ct,
|
||||
boundary,
|
||||
state: InnerState::FirstBoundary,
|
||||
item: InnerMultipartItem::None,
|
||||
state: State::FirstBoundary,
|
||||
item: Item::None,
|
||||
}),
|
||||
error: None,
|
||||
}
|
||||
|
@ -155,10 +155,7 @@ impl Stream for Multipart {
|
|||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum InnerState {
|
||||
/// Stream EOF.
|
||||
Eof,
|
||||
|
||||
enum State {
|
||||
/// Skip data until first boundary.
|
||||
FirstBoundary,
|
||||
|
||||
|
@ -167,14 +164,17 @@ enum InnerState {
|
|||
|
||||
/// Reading Headers.
|
||||
Headers,
|
||||
|
||||
/// Stream EOF.
|
||||
Eof,
|
||||
}
|
||||
|
||||
enum InnerMultipartItem {
|
||||
enum Item {
|
||||
None,
|
||||
Field(Rc<RefCell<InnerField>>),
|
||||
}
|
||||
|
||||
struct InnerMultipart {
|
||||
struct Inner {
|
||||
/// Request's payload stream & buffer.
|
||||
payload: PayloadRef,
|
||||
|
||||
|
@ -186,11 +186,11 @@ struct InnerMultipart {
|
|||
/// Field boundary.
|
||||
boundary: String,
|
||||
|
||||
state: InnerState,
|
||||
item: InnerMultipartItem,
|
||||
state: State,
|
||||
item: Item,
|
||||
}
|
||||
|
||||
impl InnerMultipart {
|
||||
impl Inner {
|
||||
fn read_field_headers(
|
||||
payload: &mut PayloadBuffer,
|
||||
) -> Result<Option<HeaderMap>, MultipartError> {
|
||||
|
@ -265,6 +265,7 @@ impl InnerMultipart {
|
|||
boundary: &str,
|
||||
) -> Result<Option<bool>, MultipartError> {
|
||||
let mut eof = false;
|
||||
|
||||
loop {
|
||||
match payload.readline()? {
|
||||
Some(chunk) => {
|
||||
|
@ -306,7 +307,7 @@ impl InnerMultipart {
|
|||
safety: &Safety,
|
||||
cx: &Context<'_>,
|
||||
) -> Poll<Option<Result<Field, MultipartError>>> {
|
||||
if self.state == InnerState::Eof {
|
||||
if self.state == State::Eof {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
// release field
|
||||
|
@ -315,20 +316,18 @@ impl InnerMultipart {
|
|||
// before switching to next
|
||||
if safety.current() {
|
||||
let stop = match self.item {
|
||||
InnerMultipartItem::Field(ref mut field) => {
|
||||
match field.borrow_mut().poll(safety) {
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Some(Ok(_))) => continue,
|
||||
Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))),
|
||||
Poll::Ready(None) => true,
|
||||
}
|
||||
}
|
||||
InnerMultipartItem::None => false,
|
||||
Item::Field(ref mut field) => match field.borrow_mut().poll(safety) {
|
||||
Poll::Pending => return Poll::Pending,
|
||||
Poll::Ready(Some(Ok(_))) => continue,
|
||||
Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))),
|
||||
Poll::Ready(None) => true,
|
||||
},
|
||||
Item::None => false,
|
||||
};
|
||||
if stop {
|
||||
self.item = InnerMultipartItem::None;
|
||||
self.item = Item::None;
|
||||
}
|
||||
if let InnerMultipartItem::None = self.item {
|
||||
if let Item::None = self.item {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -337,40 +336,40 @@ impl InnerMultipart {
|
|||
let field_headers = if let Some(mut payload) = self.payload.get_mut(safety) {
|
||||
match self.state {
|
||||
// read until first boundary
|
||||
InnerState::FirstBoundary => {
|
||||
match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? {
|
||||
State::FirstBoundary => {
|
||||
match Inner::skip_until_boundary(&mut payload, &self.boundary)? {
|
||||
Some(eof) => {
|
||||
if eof {
|
||||
self.state = InnerState::Eof;
|
||||
self.state = State::Eof;
|
||||
return Poll::Ready(None);
|
||||
} else {
|
||||
self.state = InnerState::Headers;
|
||||
self.state = State::Headers;
|
||||
}
|
||||
}
|
||||
None => return Poll::Pending,
|
||||
}
|
||||
}
|
||||
|
||||
// read boundary
|
||||
InnerState::Boundary => {
|
||||
match InnerMultipart::read_boundary(&mut payload, &self.boundary)? {
|
||||
None => return Poll::Pending,
|
||||
Some(eof) => {
|
||||
if eof {
|
||||
self.state = InnerState::Eof;
|
||||
return Poll::Ready(None);
|
||||
} else {
|
||||
self.state = InnerState::Headers;
|
||||
}
|
||||
State::Boundary => match Inner::read_boundary(&mut payload, &self.boundary)? {
|
||||
None => return Poll::Pending,
|
||||
Some(eof) => {
|
||||
if eof {
|
||||
self.state = State::Eof;
|
||||
return Poll::Ready(None);
|
||||
} else {
|
||||
self.state = State::Headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// read field headers for next field
|
||||
if self.state == InnerState::Headers {
|
||||
if let Some(headers) = InnerMultipart::read_field_headers(&mut payload)? {
|
||||
self.state = InnerState::Boundary;
|
||||
if self.state == State::Headers {
|
||||
if let Some(headers) = Inner::read_field_headers(&mut payload)? {
|
||||
self.state = State::Boundary;
|
||||
headers
|
||||
} else {
|
||||
return Poll::Pending;
|
||||
|
@ -418,7 +417,7 @@ impl InnerMultipart {
|
|||
.and_then(|ct| ct.to_str().ok())
|
||||
.and_then(|ct| ct.parse().ok());
|
||||
|
||||
self.state = InnerState::Boundary;
|
||||
self.state = State::Boundary;
|
||||
|
||||
// nested multipart stream is not supported
|
||||
if let Some(mime) = &field_content_type {
|
||||
|
@ -430,7 +429,7 @@ impl InnerMultipart {
|
|||
let field_inner =
|
||||
InnerField::new_in_rc(self.payload.clone(), self.boundary.clone(), &field_headers)?;
|
||||
|
||||
self.item = InnerMultipartItem::Field(Rc::clone(&field_inner));
|
||||
self.item = Item::Field(Rc::clone(&field_inner));
|
||||
|
||||
Poll::Ready(Some(Ok(Field::new(
|
||||
field_content_type,
|
||||
|
@ -444,10 +443,10 @@ impl InnerMultipart {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for InnerMultipart {
|
||||
impl Drop for Inner {
|
||||
fn drop(&mut self) {
|
||||
// InnerMultipartItem::Field has to be dropped first because of Safety.
|
||||
self.item = InnerMultipartItem::None;
|
||||
self.item = Item::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,7 +771,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_readmax() {
|
||||
async fn read_max() {
|
||||
let (mut sender, payload) = h1::Payload::create(false);
|
||||
let mut payload = PayloadBuffer::new(payload);
|
||||
|
||||
|
@ -789,7 +788,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_readexactly() {
|
||||
async fn read_exactly() {
|
||||
let (mut sender, payload) = h1::Payload::create(false);
|
||||
let mut payload = PayloadBuffer::new(payload);
|
||||
|
||||
|
@ -807,7 +806,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_readuntil() {
|
||||
async fn read_until() {
|
||||
let (mut sender, payload) = h1::Payload::create(false);
|
||||
let mut payload = PayloadBuffer::new(payload);
|
||||
|
||||
|
|
Loading…
Reference in a new issue