Implement blob url support in the fetch stack.

This commit is contained in:
Ms2ger 2016-10-13 17:01:24 +02:00
parent 92f1cbcbe3
commit e134871a95
6 changed files with 147 additions and 4 deletions

View file

@ -18,6 +18,7 @@ use resource_thread::{send_error, start_sending_sniffed_opt};
use resource_thread::CancellationListener;
use std::boxed::FnBox;
use std::sync::Arc;
use url::Url;
use util::thread::spawn_named;
// TODO: Check on GET
@ -119,3 +120,72 @@ fn load_blob<UI: 'static + UIProvider>
send_error(load_data.url.clone(), format_err, start_chan);
}
}
/// https://fetch.spec.whatwg.org/#concept-basic-fetch (partial)
// TODO: make async.
pub fn load_blob_sync<UI: 'static + UIProvider>
(url: Url,
filemanager: FileManager<UI>)
-> Result<(Headers, Vec<u8>), NetworkError> {
let (id, origin) = match parse_blob_url(&url) {
Ok((id, origin, _fragment)) => (id, origin),
Err(()) => {
let e = format!("Invalid blob URL format {:?}", url);
return Err(NetworkError::Internal(e));
}
};
let (sender, receiver) = ipc::channel().unwrap();
let check_url_validity = true;
let msg = FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin);
let _ = filemanager.handle(msg, None);
let blob_buf = match receiver.recv().unwrap() {
Ok(ReadFileProgress::Meta(blob_buf)) => blob_buf,
Ok(_) => {
return Err(NetworkError::Internal("Invalid filemanager reply".to_string()));
}
Err(e) => {
return Err(NetworkError::Internal(format!("{:?}", e)));
}
};
let content_type: Mime = blob_buf.type_string.parse().unwrap_or(mime!(Text / Plain));
let charset = content_type.get_param(Attr::Charset);
let mut headers = Headers::new();
if let Some(name) = blob_buf.filename {
let charset = charset.and_then(|c| c.as_str().parse().ok());
headers.set(ContentDisposition {
disposition: DispositionType::Inline,
parameters: vec![
DispositionParam::Filename(charset.unwrap_or(Charset::Us_Ascii),
None, name.as_bytes().to_vec())
]
});
}
// Basic fetch, Step 4.
headers.set(ContentLength(blob_buf.size as u64));
// Basic fetch, Step 5.
headers.set(ContentType(content_type.clone()));
let mut bytes = blob_buf.bytes;
loop {
match receiver.recv().unwrap() {
Ok(ReadFileProgress::Partial(ref mut new_bytes)) => {
bytes.append(new_bytes);
}
Ok(ReadFileProgress::EOF) => {
return Ok((headers, bytes));
}
Ok(_) => {
return Err(NetworkError::Internal("Invalid filemanager reply".to_string()));
}
Err(e) => {
return Err(NetworkError::Internal(format!("{:?}", e)));
}
}
}
}