1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use servo_url::ServoUrl;
use url::Url;
use uuid::Uuid;
use crate::filemanager_thread::FileOrigin;
/// Errors returned to Blob URL Store request
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum BlobURLStoreError {
/// Invalid File UUID
InvalidFileID,
/// Invalid URL origin
InvalidOrigin,
/// Invalid entry content
InvalidEntry,
/// Invalid range
InvalidRange,
/// External error, from like file system, I/O etc.
External(String),
}
/// Standalone blob buffer object
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BlobBuf {
pub filename: Option<String>,
/// MIME type string
pub type_string: String,
/// Size of content in bytes
pub size: u64,
/// Content of blob
pub bytes: Vec<u8>,
}
/// Parse URL as Blob URL scheme's definition
///
/// <https://w3c.github.io/FileAPI/#DefinitionOfScheme>
pub fn parse_blob_url(url: &ServoUrl) -> Result<(Uuid, FileOrigin), &'static str> {
let url_inner = Url::parse(url.path()).map_err(|_| "Failed to parse URL path")?;
let segs = url_inner
.path_segments()
.map(|c| c.collect::<Vec<_>>())
.ok_or("URL has no path segments")?;
if url.query().is_some() {
return Err("URL should not contain a query");
}
if segs.len() > 1 {
return Err("URL should not have more than one path segment");
}
let id = {
let id = segs.first().ok_or("URL has no path segments")?;
Uuid::from_str(id).map_err(|_| "Failed to parse UUID from path segment")?
};
Ok((id, get_blob_origin(&ServoUrl::from_url(url_inner))))
}
/// Given an URL, returning the Origin that a Blob created under this
/// URL should have.
///
/// HACK(izgzhen): Not well-specified on spec, and it is a bit a hack
/// both due to ambiguity of spec and that we have to serialization the
/// Origin here.
pub fn get_blob_origin(url: &ServoUrl) -> FileOrigin {
if url.scheme() == "file" {
// NOTE: by default this is "null" (Opaque), which is not ideal
"file://".to_string()
} else {
url.origin().ascii_serialization()
}
}