1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

Allow to disable Content-Disposition header #686

This commit is contained in:
Nikolay Kim 2019-07-20 11:43:49 +06:00
parent 3618a84164
commit 7bca1f7d8d
3 changed files with 74 additions and 18 deletions

View File

@ -1,5 +1,10 @@
# Changes # Changes
## [0.1.4] - 2019-07-20
* Allow to disable `Content-Disposition` header #686
## [0.1.3] - 2019-06-28 ## [0.1.3] - 2019-06-28
* Do not set `Content-Length` header, let actix-http set it #930 * Do not set `Content-Length` header, let actix-http set it #930

View File

@ -314,23 +314,32 @@ impl Files {
} }
#[inline] #[inline]
///Specifies whether to use ETag or not. /// Specifies whether to use ETag or not.
/// ///
///Default is true. /// Default is true.
pub fn use_etag(mut self, value: bool) -> Self { pub fn use_etag(mut self, value: bool) -> Self {
self.file_flags.set(named::Flags::ETAG, value); self.file_flags.set(named::Flags::ETAG, value);
self self
} }
#[inline] #[inline]
///Specifies whether to use Last-Modified or not. /// Specifies whether to use Last-Modified or not.
/// ///
///Default is true. /// Default is true.
pub fn use_last_modified(mut self, value: bool) -> Self { pub fn use_last_modified(mut self, value: bool) -> Self {
self.file_flags.set(named::Flags::LAST_MD, value); self.file_flags.set(named::Flags::LAST_MD, value);
self self
} }
/// Disable `Content-Disposition` header.
///
/// By default Content-Disposition` header is enabled.
#[inline]
pub fn disable_content_disposition(mut self) -> Self {
self.file_flags.remove(named::Flags::CONTENT_DISPOSITION);
self
}
/// Sets default handler which is used when no matched file could be found. /// Sets default handler which is used when no matched file could be found.
pub fn default_handler<F, U>(mut self, f: F) -> Self pub fn default_handler<F, U>(mut self, f: F) -> Self
where where
@ -638,6 +647,33 @@ mod tests {
); );
} }
#[test]
fn test_named_file_content_disposition() {
assert!(NamedFile::open("test--").is_err());
let mut file = NamedFile::open("Cargo.toml").unwrap();
{
file.file();
let _f: &File = &file;
}
{
let _f: &mut File = &mut file;
}
let req = TestRequest::default().to_http_request();
let resp = file.respond_to(&req).unwrap();
assert_eq!(
resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
"inline; filename=\"Cargo.toml\""
);
let file = NamedFile::open("Cargo.toml")
.unwrap()
.disable_content_disposition();
let req = TestRequest::default().to_http_request();
let resp = file.respond_to(&req).unwrap();
assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none());
}
#[test] #[test]
fn test_named_file_set_content_type() { fn test_named_file_set_content_type() {
let mut file = NamedFile::open("Cargo.toml") let mut file = NamedFile::open("Cargo.toml")

View File

@ -23,9 +23,10 @@ use crate::range::HttpRange;
use crate::ChunkedReadFile; use crate::ChunkedReadFile;
bitflags! { bitflags! {
pub(crate) struct Flags: u32 { pub(crate) struct Flags: u8 {
const ETAG = 0b0000_0001; const ETAG = 0b0000_0001;
const LAST_MD = 0b0000_0010; const LAST_MD = 0b0000_0010;
const CONTENT_DISPOSITION = 0b0000_0100;
} }
} }
@ -40,13 +41,13 @@ impl Default for Flags {
pub struct NamedFile { pub struct NamedFile {
path: PathBuf, path: PathBuf,
file: File, file: File,
modified: Option<SystemTime>,
pub(crate) md: Metadata,
pub(crate) flags: Flags,
pub(crate) status_code: StatusCode,
pub(crate) content_type: mime::Mime, pub(crate) content_type: mime::Mime,
pub(crate) content_disposition: header::ContentDisposition, pub(crate) content_disposition: header::ContentDisposition,
pub(crate) md: Metadata,
modified: Option<SystemTime>,
pub(crate) encoding: Option<ContentEncoding>, pub(crate) encoding: Option<ContentEncoding>,
pub(crate) status_code: StatusCode,
pub(crate) flags: Flags,
} }
impl NamedFile { impl NamedFile {
@ -172,11 +173,21 @@ impl NamedFile {
/// sent to the peer. By default the disposition is `inline` for text, /// sent to the peer. By default the disposition is `inline` for text,
/// image, and video content types, and `attachment` otherwise, and /// image, and video content types, and `attachment` otherwise, and
/// the filename is taken from the path provided in the `open` method /// the filename is taken from the path provided in the `open` method
/// after converting it to UTF-8 using /// after converting it to UTF-8 using.
/// [to_string_lossy](https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_string_lossy). /// [to_string_lossy](https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_string_lossy).
#[inline] #[inline]
pub fn set_content_disposition(mut self, cd: header::ContentDisposition) -> Self { pub fn set_content_disposition(mut self, cd: header::ContentDisposition) -> Self {
self.content_disposition = cd; self.content_disposition = cd;
self.flags.insert(Flags::CONTENT_DISPOSITION);
self
}
/// Disable `Content-Disposition` header.
///
/// By default Content-Disposition` header is enabled.
#[inline]
pub fn disable_content_disposition(mut self) -> Self {
self.flags.remove(Flags::CONTENT_DISPOSITION);
self self
} }
@ -294,10 +305,12 @@ impl Responder for NamedFile {
if self.status_code != StatusCode::OK { if self.status_code != StatusCode::OK {
let mut resp = HttpResponse::build(self.status_code); let mut resp = HttpResponse::build(self.status_code);
resp.set(header::ContentType(self.content_type.clone())) resp.set(header::ContentType(self.content_type.clone()))
.header( .if_true(self.flags.contains(Flags::CONTENT_DISPOSITION), |res| {
header::CONTENT_DISPOSITION, res.header(
self.content_disposition.to_string(), header::CONTENT_DISPOSITION,
); self.content_disposition.to_string(),
);
});
if let Some(current_encoding) = self.encoding { if let Some(current_encoding) = self.encoding {
resp.encoding(current_encoding); resp.encoding(current_encoding);
} }
@ -368,10 +381,12 @@ impl Responder for NamedFile {
let mut resp = HttpResponse::build(self.status_code); let mut resp = HttpResponse::build(self.status_code);
resp.set(header::ContentType(self.content_type.clone())) resp.set(header::ContentType(self.content_type.clone()))
.header( .if_true(self.flags.contains(Flags::CONTENT_DISPOSITION), |res| {
header::CONTENT_DISPOSITION, res.header(
self.content_disposition.to_string(), header::CONTENT_DISPOSITION,
); self.content_disposition.to_string(),
);
});
// default compressing // default compressing
if let Some(current_encoding) = self.encoding { if let Some(current_encoding) = self.encoding {
resp.encoding(current_encoding); resp.encoding(current_encoding);