net_traits/
blob_url_store.rs

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