servoshell/desktop/protocols/
servo.rs1use std::future::Future;
13use std::pin::Pin;
14
15use headers::{ContentType, HeaderMapExt};
16use net::fetch::methods::{DoneChannel, FetchContext};
17use net::protocols::ProtocolHandler;
18use net_traits::ResourceFetchTiming;
19use net_traits::request::Request;
20use net_traits::response::{Response, ResponseBody};
21use servo::config::prefs::UserAgentPlatform;
22
23use crate::desktop::protocols::resource::ResourceProtocolHandler;
24use crate::prefs::EXPERIMENTAL_PREFS;
25
26#[derive(Default)]
27pub struct ServoProtocolHandler {}
28
29impl ProtocolHandler for ServoProtocolHandler {
30 fn privileged_paths(&self) -> &'static [&'static str] {
31 &["preferences"]
32 }
33
34 fn is_fetchable(&self) -> bool {
35 true
36 }
37
38 fn load(
39 &self,
40 request: &mut Request,
41 done_chan: &mut DoneChannel,
42 context: &FetchContext,
43 ) -> Pin<Box<dyn Future<Output = Response> + Send>> {
44 let url = request.current_url();
45
46 match url.path() {
47 "newtab" => ResourceProtocolHandler::response_for_path(
48 request,
49 done_chan,
50 context,
51 "/newtab.html",
52 ),
53
54 "preferences" => ResourceProtocolHandler::response_for_path(
55 request,
56 done_chan,
57 context,
58 "/preferences.html",
59 ),
60
61 "experimental-preferences" => {
62 let pref_list = EXPERIMENTAL_PREFS
63 .iter()
64 .map(|pref| format!("\"{pref}\""))
65 .collect::<Vec<String>>()
66 .join(",");
67 json_response(request, format!("[{pref_list}]"))
68 },
69
70 "default-user-agent" => {
71 let user_agent = UserAgentPlatform::default().to_user_agent_string();
72 json_response(request, format!("\"{user_agent}\""))
73 },
74
75 _ => Box::pin(std::future::ready(Response::network_internal_error(
76 "Invalid shortcut",
77 ))),
78 }
79 }
80}
81
82fn json_response(
83 request: &Request,
84 body: String,
85) -> Pin<Box<dyn Future<Output = Response> + Send>> {
86 let mut response = Response::new(
87 request.current_url(),
88 ResourceFetchTiming::new(request.timing_type()),
89 );
90 response.headers.typed_insert(ContentType::json());
91 *response.body.lock().unwrap() = ResponseBody::Done(body.into_bytes());
92 Box::pin(std::future::ready(response))
93}