/* 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/. */ //! Loads resources using a mapping from well-known shortcuts to resource: urls. //! Recognized shortcuts: //! - servo:default-user-agent //! - servo:experimental-preferences //! - servo:newtab //! - servo:preferences use std::future::Future; use std::pin::Pin; use headers::{ContentType, HeaderMapExt}; use net::fetch::methods::{DoneChannel, FetchContext}; use net::protocols::ProtocolHandler; use net_traits::ResourceFetchTiming; use net_traits::request::Request; use net_traits::response::{Response, ResponseBody}; use servo::config::prefs::UserAgentPlatform; use crate::desktop::protocols::resource::ResourceProtocolHandler; use crate::prefs::EXPERIMENTAL_PREFS; #[derive(Default)] pub struct ServoProtocolHandler {} impl ProtocolHandler for ServoProtocolHandler { fn privileged_paths(&self) -> &'static [&'static str] { &["preferences"] } fn is_fetchable(&self) -> bool { true } fn load( &self, request: &mut Request, done_chan: &mut DoneChannel, context: &FetchContext, ) -> Pin + Send>> { let url = request.current_url(); match url.path() { "newtab" => ResourceProtocolHandler::response_for_path( request, done_chan, context, "/newtab.html", ), "preferences" => ResourceProtocolHandler::response_for_path( request, done_chan, context, "/preferences.html", ), "experimental-preferences" => { let pref_list = EXPERIMENTAL_PREFS .iter() .map(|pref| format!("\"{pref}\"")) .collect::>() .join(","); json_response(request, format!("[{pref_list}]")) }, "default-user-agent" => { let user_agent = UserAgentPlatform::default().to_user_agent_string(); json_response(request, format!("\"{user_agent}\"")) }, _ => Box::pin(std::future::ready(Response::network_internal_error( "Invalid shortcut", ))), } } } fn json_response( request: &Request, body: String, ) -> Pin + Send>> { let mut response = Response::new( request.current_url(), ResourceFetchTiming::new(request.timing_type()), ); response.headers.typed_insert(ContentType::json()); *response.body.lock().unwrap() = ResponseBody::Done(body.into_bytes()); Box::pin(std::future::ready(response)) }