mirror of
https://github.com/fafhrd91/actix-web
synced 2024-12-18 01:43:58 +01:00
Fix actix-multipart field content_type() to return an Option (#2885)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
ef64d6a27c
commit
fd63305859
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## Unreleased - 2022-xx-xx
|
## Unreleased - 2022-xx-xx
|
||||||
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
|
- Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency.
|
||||||
|
- `Field::content_type()` now returns `Option<&mime::Mime>` [#2880]
|
||||||
|
|
||||||
|
[#2880]: https://github.com/actix/actix-web/pull/2880
|
||||||
|
|
||||||
|
|
||||||
## 0.4.0 - 2022-02-25
|
## 0.4.0 - 2022-02-25
|
||||||
|
@ -361,17 +361,18 @@ impl InnerMultipart {
|
|||||||
return Poll::Ready(Some(Err(MultipartError::NoContentDisposition)));
|
return Poll::Ready(Some(Err(MultipartError::NoContentDisposition)));
|
||||||
};
|
};
|
||||||
|
|
||||||
let ct: mime::Mime = headers
|
let ct: Option<mime::Mime> = headers
|
||||||
.get(&header::CONTENT_TYPE)
|
.get(&header::CONTENT_TYPE)
|
||||||
.and_then(|ct| ct.to_str().ok())
|
.and_then(|ct| ct.to_str().ok())
|
||||||
.and_then(|ct| ct.parse().ok())
|
.and_then(|ct| ct.parse().ok());
|
||||||
.unwrap_or(mime::APPLICATION_OCTET_STREAM);
|
|
||||||
|
|
||||||
self.state = InnerState::Boundary;
|
self.state = InnerState::Boundary;
|
||||||
|
|
||||||
// nested multipart stream is not supported
|
// nested multipart stream is not supported
|
||||||
if ct.type_() == mime::MULTIPART {
|
if let Some(mime) = &ct {
|
||||||
return Poll::Ready(Some(Err(MultipartError::Nested)));
|
if mime.type_() == mime::MULTIPART {
|
||||||
|
return Poll::Ready(Some(Err(MultipartError::Nested)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let field =
|
let field =
|
||||||
@ -399,7 +400,7 @@ impl Drop for InnerMultipart {
|
|||||||
|
|
||||||
/// A single field in a multipart stream
|
/// A single field in a multipart stream
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
ct: mime::Mime,
|
ct: Option<mime::Mime>,
|
||||||
cd: ContentDisposition,
|
cd: ContentDisposition,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
inner: Rc<RefCell<InnerField>>,
|
inner: Rc<RefCell<InnerField>>,
|
||||||
@ -410,7 +411,7 @@ impl Field {
|
|||||||
fn new(
|
fn new(
|
||||||
safety: Safety,
|
safety: Safety,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
ct: mime::Mime,
|
ct: Option<mime::Mime>,
|
||||||
cd: ContentDisposition,
|
cd: ContentDisposition,
|
||||||
inner: Rc<RefCell<InnerField>>,
|
inner: Rc<RefCell<InnerField>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -428,9 +429,13 @@ impl Field {
|
|||||||
&self.headers
|
&self.headers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the field's content (mime) type.
|
/// Returns a reference to the field's content (mime) type, if it is supplied by the client.
|
||||||
pub fn content_type(&self) -> &mime::Mime {
|
///
|
||||||
&self.ct
|
/// According to [RFC 7578](https://www.rfc-editor.org/rfc/rfc7578#section-4.4), if it is not
|
||||||
|
/// present, it should default to "text/plain". Note it is the responsibility of the client to
|
||||||
|
/// provide the appropriate content type, there is no attempt to validate this by the server.
|
||||||
|
pub fn content_type(&self) -> Option<&mime::Mime> {
|
||||||
|
self.ct.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the field's Content-Disposition.
|
/// Returns the field's Content-Disposition.
|
||||||
@ -482,7 +487,11 @@ impl Stream for Field {
|
|||||||
|
|
||||||
impl fmt::Debug for Field {
|
impl fmt::Debug for Field {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
writeln!(f, "\nField: {}", self.ct)?;
|
if let Some(ct) = &self.ct {
|
||||||
|
writeln!(f, "\nField: {}", ct)?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "\nField:")?;
|
||||||
|
}
|
||||||
writeln!(f, " boundary: {}", self.inner.borrow().boundary)?;
|
writeln!(f, " boundary: {}", self.inner.borrow().boundary)?;
|
||||||
writeln!(f, " headers:")?;
|
writeln!(f, " headers:")?;
|
||||||
for (key, val) in self.headers.iter() {
|
for (key, val) in self.headers.iter() {
|
||||||
@ -1024,8 +1033,8 @@ mod tests {
|
|||||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
assert_eq!(cd.disposition, DispositionType::FormData);
|
||||||
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
||||||
|
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
match field.next().await.unwrap() {
|
match field.next().await.unwrap() {
|
||||||
Ok(chunk) => assert_eq!(chunk, "test"),
|
Ok(chunk) => assert_eq!(chunk, "test"),
|
||||||
@ -1041,8 +1050,8 @@ mod tests {
|
|||||||
|
|
||||||
match multipart.next().await.unwrap() {
|
match multipart.next().await.unwrap() {
|
||||||
Ok(mut field) => {
|
Ok(mut field) => {
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
match field.next().await {
|
match field.next().await {
|
||||||
Some(Ok(chunk)) => assert_eq!(chunk, "data"),
|
Some(Ok(chunk)) => assert_eq!(chunk, "data"),
|
||||||
@ -1086,8 +1095,8 @@ mod tests {
|
|||||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
assert_eq!(cd.disposition, DispositionType::FormData);
|
||||||
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
||||||
|
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
assert_eq!(get_whole_field(&mut field).await, "test");
|
assert_eq!(get_whole_field(&mut field).await, "test");
|
||||||
}
|
}
|
||||||
@ -1096,8 +1105,8 @@ mod tests {
|
|||||||
|
|
||||||
match multipart.next().await {
|
match multipart.next().await {
|
||||||
Some(Ok(mut field)) => {
|
Some(Ok(mut field)) => {
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
assert_eq!(get_whole_field(&mut field).await, "data");
|
assert_eq!(get_whole_field(&mut field).await, "data");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user