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