Add Content Range Header and add one for blob end range (#34797)

Signed-off-by: rayguo17 <rayguo17@gmail.com>
This commit is contained in:
TIN TUN AUNG 2025-01-14 08:21:29 +08:00 committed by GitHub
parent faf30176f1
commit 55ac1887dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 75 additions and 95 deletions

View file

@ -11,7 +11,7 @@ use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, RwLock, Weak};
use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern};
use headers::{ContentLength, ContentType, HeaderMap, HeaderMapExt, Range};
use headers::{ContentLength, ContentRange, ContentType, HeaderMap, HeaderMapExt, Range};
use http::header::{self, HeaderValue};
use ipc_channel::ipc::{self, IpcSender};
use log::warn;
@ -290,24 +290,39 @@ impl FileManager {
response: &mut Response,
) -> Result<(), BlobURLStoreError> {
let file_impl = self.store.get_impl(id, file_token, origin_in)?;
/*
Only Fetch Blob Range Request would have unresolved range, and only in that case we care about range header.
*/
let mut is_range_requested = false;
match file_impl {
FileImpl::Memory(buf) => {
let bounds = match bounds {
BlobBounds::Unresolved(range) => get_range_request_bounds(range, buf.size),
BlobBounds::Unresolved(range) => {
if range.is_some() {
is_range_requested = true;
}
get_range_request_bounds(range, buf.size)
},
BlobBounds::Resolved(bounds) => bounds,
};
let range = bounds
.get_final(Some(buf.size))
.map_err(|_| BlobURLStoreError::InvalidRange)?;
let range = range.to_abs_range(buf.size as usize);
let range = range.to_abs_blob_range(buf.size as usize);
let len = range.len() as u64;
let content_range = if is_range_requested {
ContentRange::bytes(range.start as u64..range.end as u64, buf.size).ok()
} else {
None
};
set_headers(
&mut response.headers,
len,
buf.type_string.parse().unwrap_or(mime::TEXT_PLAIN),
/* filename */ None,
content_range,
);
let mut bytes = vec![];
@ -327,9 +342,14 @@ impl FileManager {
let file = File::open(&metadata.path)
.map_err(|e| BlobURLStoreError::External(e.to_string()))?;
let mut is_range_requested = false;
let bounds = match bounds {
BlobBounds::Unresolved(range) => get_range_request_bounds(range, metadata.size),
BlobBounds::Unresolved(range) => {
if range.is_some() {
is_range_requested = true;
}
get_range_request_bounds(range, metadata.size)
},
BlobBounds::Resolved(bounds) => bounds,
};
let range = bounds
@ -349,6 +369,13 @@ impl FileManager {
.and_then(|osstr| osstr.to_str())
.map(|s| s.to_string());
let content_range = if is_range_requested {
let abs_range = range.to_abs_blob_range(metadata.size as usize);
ContentRange::bytes(abs_range.start as u64..abs_range.end as u64, metadata.size)
.ok()
} else {
None
};
set_headers(
&mut response.headers,
metadata.size,
@ -356,6 +383,7 @@ impl FileManager {
.first()
.unwrap_or(mime::TEXT_PLAIN),
filename,
content_range,
);
self.fetch_file_in_chunks(
@ -939,8 +967,17 @@ fn read_file_in_chunks(
}
}
fn set_headers(headers: &mut HeaderMap, content_length: u64, mime: Mime, filename: Option<String>) {
fn set_headers(
headers: &mut HeaderMap,
content_length: u64,
mime: Mime,
filename: Option<String>,
content_range: Option<ContentRange>,
) {
headers.typed_insert(ContentLength(content_length));
if let Some(content_range) = content_range {
headers.typed_insert(content_range);
}
headers.typed_insert(ContentType::from(mime.clone()));
let name = match filename {
Some(name) => name,