Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read file URL in chunks #21560

Merged
merged 3 commits into from Sep 7, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -25,14 +25,17 @@ use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::io::{BufReader, BufRead};
use std::mem;
use std::str;
use std::sync::{Arc, Mutex};
use std::sync::atomic::Ordering;
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread;
use subresource_integrity::is_response_integrity_valid;

const FILE_CHUNK_SIZE: usize = 32768; //32 KB

pub type Target<'a> = &'a mut (FetchTaskTarget + Send);

pub enum Data {
@@ -486,13 +489,51 @@ fn scheme_fetch(request: &mut Request,
Ok(file_path) => {
match File::open(file_path.clone()) {
Ok(mut file) => {
let mut bytes = vec![];
let _ = file.read_to_end(&mut bytes);
let mime = guess_mime_type(file_path);

let mut response = Response::new(url);
*response.body.lock().unwrap() = ResponseBody::Done(bytes);
response.headers.set(ContentType(mime));

let (done_sender, done_receiver) = channel();
*done_chan = Some((done_sender.clone(), done_receiver));
*response.body.lock().unwrap() = ResponseBody::Receiving(vec![]);

let mut res_body = response.body.clone();

let cancellation_listener = context.cancellation_listener.clone();

thread::Builder::new().name("fetch file worker thread".to_string()).spawn(move || {
let mut reader = BufReader::with_capacity(FILE_CHUNK_SIZE, file);
loop {
if cancellation_listener.lock().unwrap().cancelled() {
*res_body.lock().unwrap() = ResponseBody::Done(vec![]);
let _ = done_sender.send(Data::Cancelled);
return;
}
let length = {
let mut buffer = reader.fill_buf().unwrap().to_vec();
let buffer_len = buffer.len();
if let ResponseBody::Receiving(ref mut body) = *res_body.lock().unwrap() {
body.extend_from_slice(&buffer);
let _ = done_sender.send(Data::Payload(buffer));
}
buffer_len
};
if length == 0 {
let mut body = res_body.lock().unwrap();
let completed_body = match *body {
ResponseBody::Receiving(ref mut body) => {
mem::replace(body, vec![])
},
_ => vec![],
};
*body = ResponseBody::Done(completed_body);
let _ = done_sender.send(Data::Done);
break;
}
reader.consume(length);
}
}).expect("Failed to create fetch file worker thread");
response
},
_ => Response::network_error(NetworkError::Internal("Opening file failed".into())),
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.