Bug 1685822 [wpt PR 27117] - Update wpt metadata, a=testonly
[gecko.git] / remote / remote_agent.rs
blob37f377cd48b9cd67a863679ed5229872f83c324e
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 http://mozilla.org/MPL/2.0/.
5 //! Rust interface for the Gecko remote agent.
7 use std::str::FromStr;
9 use log::*;
10 use nserror::NS_ERROR_ILLEGAL_VALUE;
11 use nsstring::{nsAString, nsString};
12 use xpcom::interfaces::nsIRemoteAgent;
13 use xpcom::RefPtr;
15 use crate::error::RemoteAgentError::{self, *};
17 pub const DEFAULT_HOST: &'static str = "localhost";
18 pub const DEFAULT_PORT: u16 = 9222;
20 pub type RemoteAgentResult<T> = Result<T, RemoteAgentError>;
22 pub struct RemoteAgent {
23     inner: RefPtr<nsIRemoteAgent>,
26 impl RemoteAgent {
27     pub fn get() -> RemoteAgentResult<RemoteAgent> {
28         let inner = xpcom::services::get_RemoteAgent().ok_or(Unavailable)?;
29         Ok(RemoteAgent { inner })
30     }
32     pub fn listen(&self, spec: &str) -> RemoteAgentResult<()> {
33         let addr = http::uri::Authority::from_str(spec)?;
34         let host = if addr.host().is_empty() {
35             DEFAULT_HOST
36         } else {
37             addr.host()
38         }
39         .to_string();
40         let port = addr.port_u16().unwrap_or(DEFAULT_PORT);
42         let url = nsString::from(&format!("http://{}:{}/", host, port));
43         unsafe { self.inner.Listen(&*url as &nsAString) }
44             .to_result()
45             .map_err(|err| {
46                 // TODO(ato): https://bugzil.la/1600139
47                 match err {
48                     NS_ERROR_ILLEGAL_VALUE => RemoteAgentError::LoopbackRestricted,
49                     nsresult => RemoteAgentError::from(nsresult),
50                 }
51             })?;
53         Ok(())
54     }
56     pub fn listening(&self) -> RemoteAgentResult<bool> {
57         let mut listening = false;
58         unsafe { self.inner.GetListening(&mut listening) }.to_result()?;
59         Ok(listening)
60     }
62     pub fn close(&self) -> RemoteAgentResult<()> {
63         unsafe { self.inner.Close() }.to_result()?;
64         Ok(())
65     }
68 impl Drop for RemoteAgent {
69     fn drop(&mut self) {
70         // it should always be safe to call nsIRemoteAgent.close()
71         if let Err(e) = self.close() {
72             error!("unable to close remote agent listener: {}", e);
73         }
74     }