UPnP server configurable from UI
This commit is contained in:
parent
3110f68f36
commit
9f340d92e5
6 changed files with 166 additions and 8 deletions
|
|
@ -125,10 +125,21 @@ impl Default for RqbitDesktopConfigHttpApi {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct RqbitDesktopConfigUpnp {
|
||||
pub disable: bool,
|
||||
// rename for backwards compat
|
||||
#[serde(rename = "disable")]
|
||||
pub disable_tcp_port_forward: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub enable_server: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub server_hostname: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub server_friendly_name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
|
@ -162,3 +173,23 @@ impl Default for RqbitDesktopConfig {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RqbitDesktopConfig {
|
||||
pub fn validate(&self) -> anyhow::Result<()> {
|
||||
if self.upnp.enable_server {
|
||||
if self.http_api.disable {
|
||||
anyhow::bail!("if UPnP server is enabled, you need to enable the HTTP API also.")
|
||||
}
|
||||
if self.http_api.listen_addr.ip().is_loopback() {
|
||||
anyhow::bail!("if UPnP server is enabled, you need to set HTTP API IP to 0.0.0.0 or at least non-localhost address.")
|
||||
}
|
||||
match self.upnp.server_hostname.as_ref().map(|s| s.trim()) {
|
||||
Some("") | None => {
|
||||
anyhow::bail!("UPnP hostname must be set to non-empty string")
|
||||
}
|
||||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ async fn api_from_config(
|
|||
init_logging: &InitLoggingResult,
|
||||
config: &RqbitDesktopConfig,
|
||||
) -> anyhow::Result<Api> {
|
||||
config
|
||||
.validate()
|
||||
.context("error validating configuration")?;
|
||||
let persistence = if config.persistence.disable {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -100,7 +103,7 @@ async fn api_from_config(
|
|||
} else {
|
||||
None
|
||||
},
|
||||
enable_upnp_port_forwarding: !config.upnp.disable,
|
||||
enable_upnp_port_forwarding: !config.upnp.disable_tcp_port_forward,
|
||||
fastresume: config.persistence.fastresume,
|
||||
..Default::default()
|
||||
},
|
||||
|
|
@ -118,6 +121,35 @@ async fn api_from_config(
|
|||
let listen_addr = config.http_api.listen_addr;
|
||||
let api = api.clone();
|
||||
let read_only = config.http_api.read_only;
|
||||
let upnp_router = if config.upnp.enable_server {
|
||||
let hostname = config
|
||||
.upnp
|
||||
.server_hostname
|
||||
.as_ref()
|
||||
.map(|h| h.trim())
|
||||
.context("empty UPNP hostname")?
|
||||
.to_owned();
|
||||
let friendly_name = config
|
||||
.upnp
|
||||
.server_friendly_name
|
||||
.as_ref()
|
||||
.map(|f| f.trim())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| s.to_owned())
|
||||
.unwrap_or_else(|| format!("rqbit@{hostname}"));
|
||||
|
||||
let mut upnp_adapter = session
|
||||
.make_upnp_adapter(friendly_name, hostname, config.http_api.listen_addr.port())
|
||||
.await
|
||||
.context("error starting UPnP server")?;
|
||||
let router = upnp_adapter.take_router()?;
|
||||
session.spawn(error_span!("ssdp"), async move {
|
||||
upnp_adapter.run_ssdp_forever().await
|
||||
});
|
||||
Some(router)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let http_api_task = async move {
|
||||
let listener = tokio::net::TcpListener::bind(listen_addr)
|
||||
.await
|
||||
|
|
@ -126,7 +158,7 @@ async fn api_from_config(
|
|||
api.clone(),
|
||||
Some(librqbit::http_api::HttpApiOptions { read_only }),
|
||||
)
|
||||
.make_http_api_and_run(listener, None)
|
||||
.make_http_api_and_run(listener, upnp_router)
|
||||
.await
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue