mirror of https://github.com/fafhrd91/actix-web
#60: Basic Ranges header support
This commit is contained in:
parent
bff6c2caf4
commit
de7c05c45e
|
@ -627,6 +627,12 @@ pub fn ErrorPreconditionFailed<T>(err: T) -> InternalError<T> {
|
||||||
InternalError::new(err, StatusCode::PRECONDITION_FAILED)
|
InternalError::new(err, StatusCode::PRECONDITION_FAILED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function that creates wrapper of any error and generate *RANGE NOT SATISFIABLE* response.
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn ErrorRangeNotSatisfiable<T>(err: T) -> InternalError<T> {
|
||||||
|
InternalError::new(err, StatusCode::RANGE_NOT_SATISFIABLE)
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper function that creates wrapper of any error and generate *EXPECTATION FAILED* response.
|
/// Helper function that creates wrapper of any error and generate *EXPECTATION FAILED* response.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorExpectationFailed<T>(err: T) -> InternalError<T> {
|
pub fn ErrorExpectationFailed<T>(err: T) -> InternalError<T> {
|
||||||
|
|
41
src/fs.rs
41
src/fs.rs
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
// //! TODO: needs to re-implement actual files handling, current impl blocks
|
// //! TODO: needs to re-implement actual files handling, current impl blocks
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::{Read,Seek,SeekFrom};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::fs::{File, DirEntry};
|
use std::fs::{File, DirEntry, metadata};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@ use mime_guess::get_mime_type;
|
||||||
|
|
||||||
use param::FromParam;
|
use param::FromParam;
|
||||||
use handler::{Handler, Responder};
|
use handler::{Handler, Responder};
|
||||||
use headers::ContentEncoding;
|
use headers::{ContentEncoding,HttpRange};
|
||||||
|
use http::header;
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
use httpcodes::HTTPOk;
|
use httpcodes::{HTTPOk,HTTPPartialContent,HTTPRangeNotSatisfiable};
|
||||||
|
|
||||||
/// A file with an associated name; responds with the Content-Type based on the
|
/// A file with an associated name; responds with the Content-Type based on the
|
||||||
/// file extension.
|
/// file extension.
|
||||||
|
@ -83,16 +84,32 @@ impl Responder for NamedFile {
|
||||||
type Item = HttpResponse;
|
type Item = HttpResponse;
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn respond_to(mut self, _: HttpRequest) -> Result<HttpResponse, io::Error> {
|
fn respond_to(mut self, req: HttpRequest) -> Result<HttpResponse, io::Error> {
|
||||||
let mut resp = HTTPOk.build();
|
if let Ok(rangeheader) = req.headers().get("range").unwrap().to_str() {
|
||||||
resp.content_encoding(ContentEncoding::Identity);
|
let file_metadata = metadata(self.0)?;
|
||||||
if let Some(ext) = self.path().extension() {
|
if let Ok(ranges) = HttpRange::parse(rangeheader, file_metadata.len()) {
|
||||||
|
let mut resp = HTTPPartialContent.build();
|
||||||
|
let length: usize = ranges[0].length as usize;
|
||||||
|
let mut data: Vec<u8> = vec![0u8; length];
|
||||||
|
let _ = &self.1.seek(SeekFrom::Start(ranges[0].start))?;
|
||||||
|
let _ = self.1.read_exact(&mut data);
|
||||||
|
Ok(resp.body(data).unwrap())
|
||||||
|
} else {
|
||||||
|
Ok(HTTPRangeNotSatisfiable.build()
|
||||||
|
.header(header::CONTENT_RANGE, format!("0-{}", file_metadata.len()).as_str())
|
||||||
|
.body("").unwrap())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut resp = HTTPOk.build();
|
||||||
|
resp.content_encoding(ContentEncoding::Identity);
|
||||||
|
if let Some(ext) = self.path().extension() {
|
||||||
let mime = get_mime_type(&ext.to_string_lossy());
|
let mime = get_mime_type(&ext.to_string_lossy());
|
||||||
resp.content_type(format!("{}", mime).as_str());
|
resp.content_type(format!("{}", mime).as_str());
|
||||||
|
}
|
||||||
|
let mut data = Vec::new();
|
||||||
|
let _ = self.1.read_to_end(&mut data);
|
||||||
|
Ok(resp.body(data).unwrap())
|
||||||
}
|
}
|
||||||
let mut data = Vec::new();
|
|
||||||
let _ = self.1.read_to_end(&mut data);
|
|
||||||
Ok(resp.body(data).unwrap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ pub const HTTPPreconditionFailed: StaticResponse =
|
||||||
StaticResponse(StatusCode::PRECONDITION_FAILED);
|
StaticResponse(StatusCode::PRECONDITION_FAILED);
|
||||||
pub const HTTPPayloadTooLarge: StaticResponse = StaticResponse(StatusCode::PAYLOAD_TOO_LARGE);
|
pub const HTTPPayloadTooLarge: StaticResponse = StaticResponse(StatusCode::PAYLOAD_TOO_LARGE);
|
||||||
pub const HTTPUriTooLong: StaticResponse = StaticResponse(StatusCode::URI_TOO_LONG);
|
pub const HTTPUriTooLong: StaticResponse = StaticResponse(StatusCode::URI_TOO_LONG);
|
||||||
|
pub const HTTPRangeNotSatisfiable: StaticResponse =
|
||||||
|
StaticResponse(StatusCode::RANGE_NOT_SATISFIABLE);
|
||||||
pub const HTTPExpectationFailed: StaticResponse =
|
pub const HTTPExpectationFailed: StaticResponse =
|
||||||
StaticResponse(StatusCode::EXPECTATION_FAILED);
|
StaticResponse(StatusCode::EXPECTATION_FAILED);
|
||||||
|
|
||||||
|
@ -141,6 +143,7 @@ impl HttpResponse {
|
||||||
STATIC_RESP!(PreconditionFailed, StatusCode::PRECONDITION_FAILED);
|
STATIC_RESP!(PreconditionFailed, StatusCode::PRECONDITION_FAILED);
|
||||||
STATIC_RESP!(PayloadTooLarge, StatusCode::PAYLOAD_TOO_LARGE);
|
STATIC_RESP!(PayloadTooLarge, StatusCode::PAYLOAD_TOO_LARGE);
|
||||||
STATIC_RESP!(UriTooLong, StatusCode::URI_TOO_LONG);
|
STATIC_RESP!(UriTooLong, StatusCode::URI_TOO_LONG);
|
||||||
|
STATIC_RESP!(RangeNotSatisfiable, StatusCode::RANGE_NOT_SATISFIABLE);
|
||||||
STATIC_RESP!(ExpectationFailed, StatusCode::EXPECTATION_FAILED);
|
STATIC_RESP!(ExpectationFailed, StatusCode::EXPECTATION_FAILED);
|
||||||
|
|
||||||
STATIC_RESP!(InternalServerError, StatusCode::INTERNAL_SERVER_ERROR);
|
STATIC_RESP!(InternalServerError, StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
|
Loading…
Reference in New Issue