This commit is contained in:
Mateusz Gruszczyński committed 2026-10-07 14:50:13 +02:00
1 parent e0194fbaff
commit a631068cbe
39 files changed
+246 -138

No files matched your search

+16 -13
View File
@@ -60,6 +60,7 @@ impl Manager {
struct RuntimeLaunch {
python: PathBuf,
prepend_path: Option<PathBuf>,
managed_certbot_python: Option<PathBuf>,
}
fn find_on_path(name: &str) -> Option<PathBuf> {
@@ -96,15 +97,6 @@ fn venv_python(directory: &Path) -> PathBuf {
venv_bin(directory).join("python")
}
#[cfg(windows)]
fn venv_certbot(directory: &Path) -> PathBuf {
venv_bin(directory).join("certbot.exe")
}
#[cfg(not(windows))]
fn venv_certbot(directory: &Path) -> PathBuf {
venv_bin(directory).join("certbot")
}
async fn command_success(
mut command: Command,
timeout: Duration,
@@ -131,8 +123,7 @@ async fn managed_environment_valid(
shutdown: &tokio_util::sync::CancellationToken,
) -> bool {
let python = venv_python(directory);
let certbot = venv_certbot(directory);
if !python.is_file() || !certbot.is_file() {
if !python.is_file() {
return false;
}
let mut imports = Command::new(&python);
@@ -144,8 +135,13 @@ async fn managed_environment_valid(
if !command_success(imports, Duration::from_secs(20), shutdown).await {
return false;
}
let mut version = Command::new(&certbot);
version.arg("--version");
// A venv is created under an atomic staging directory and then renamed
// into place. pip-generated console scripts contain an absolute shebang,
// so the staged `bin/certbot` is not relocatable after that rename. Invoke
// Certbot as a module through the final venv interpreter instead. This also
// makes existing 0.27.1 environments immediately usable after upgrade.
let mut version = Command::new(&python);
version.args(["-I", "-m", "certbot", "--version"]);
command_success(version, Duration::from_secs(20), shutdown).await
}
@@ -307,6 +303,7 @@ async fn ensure_runtime(state: &App) -> Result<RuntimeLaunch, String> {
return Ok(RuntimeLaunch {
python: venv_python(&managed),
prepend_path: Some(venv_bin(&managed)),
managed_certbot_python: Some(venv_python(&managed)),
});
}
@@ -355,6 +352,7 @@ async fn ensure_runtime(state: &App) -> Result<RuntimeLaunch, String> {
return Ok(RuntimeLaunch {
python: venv_python(&managed),
prepend_path: Some(venv_bin(&managed)),
managed_certbot_python: Some(venv_python(&managed)),
});
}
@@ -371,6 +369,7 @@ async fn ensure_runtime(state: &App) -> Result<RuntimeLaunch, String> {
return Ok(RuntimeLaunch {
python,
prepend_path: None,
managed_certbot_python: None,
});
}
@@ -434,9 +433,13 @@ async fn worker(state: &App, directory: PathBuf, raw: Zeroizing<String>) -> Resu
.stdout(Stdio::piped())
.stderr(Stdio::null())
.kill_on_drop(true);
command.env_remove("RUSTPROXY_CERTBOT_PYTHON");
if let Some(prepend) = launch.prepend_path.as_deref() {
command.env("PATH", merged_path(prepend)?);
}
if let Some(python) = launch.managed_certbot_python.as_deref() {
command.env("RUSTPROXY_CERTBOT_PYTHON", python);
}
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
+2 -1
View File
@@ -409,7 +409,8 @@ pub(super) static READER_DOCUMENTS: &[(&str, &str, &str)] = &[
"/docs/V0.25.1_AUDIT.md"
)),
),
reader_doc!("docs/V0.27.1_IMPLEMENTATION.md", "technical"),
reader_doc!("docs/V0.27.2_IMPLEMENTATION.md", "technical"),
reader_doc!("docs/V0.27.1_IMPLEMENTATION.md", "historical"),
reader_doc!("docs/V0.27.0_IMPLEMENTATION.md", "technical"),
reader_doc!("docs/V0.26.7_IMPLEMENTATION.md", "technical"),
reader_doc!("docs/V0.26.6_IMPLEMENTATION.md", "technical"),
+1 -1
View File
@@ -2,7 +2,7 @@
"openapi": "3.0.3",
"info": {
"title": "RustProxy Administration API",
"version": "0.27.1",
"version": "0.27.2",
"description": "Administration API for the active panel origin. Sign in through the panel; the same-origin HttpOnly cookie authenticates all private operations. Mutations also require the exact Origin, X-RustProxy-Request: 1 and a session-bound X-CSRF-Token. Loopback HTTP is the default; Settings can enable HTTPS before using a non-loopback administration bind. This document contains no live configuration or credentials. Object schemas marked extensible are summaries: full configuration validation is authoritative in Rust."
},
"servers": [
+2 -2
View File
@@ -2823,7 +2823,7 @@
</section>
</div>
</section>
<footer class="page-footer"><span>RustProxy <b>0.27.1</b></span><span id="footer-status">API - /
<footer class="page-footer"><span>RustProxy <b>0.27.2</b></span><span id="footer-status">API - /
dropped: 0</span></footer>
</div>
</main>
@@ -3567,7 +3567,7 @@ max_execution_time = 30</code></pre>
<article class="card about-card">
<div class="about-product">
<span aria-hidden="true" class="brand-mark">r<span>/</span>p</span>
<div><span class="small-label">RustProxy</span><strong>0.27.1</strong></div>
<div><span class="small-label">RustProxy</span><strong>0.27.2</strong></div>
</div>
<dl class="about-meta">
<div>
+1 -1
View File
@@ -41,7 +41,7 @@ use zeroize::Zeroizing;
#[command(
name = "rust-proxy",
version,
about = "RustProxy - independent Rust reverse proxy and static Web Server 0.27.1"
about = "RustProxy - independent Rust reverse proxy and static Web Server 0.27.2"
)]
struct Cli {
#[arg(
+1 -1
View File
@@ -239,7 +239,7 @@ async fn live_logs_command(dir: PathBuf, addr: SocketAddr) -> Result<()> {
}
});
let interactive = io::stdin().is_terminal() && io::stdout().is_terminal();
println!("RustProxy live logs 0.27.1 - all vhosts. Type 'help' for interactive filters; Ctrl-C or 'quit' exits.");
println!("RustProxy live logs 0.27.2 - all vhosts. Type 'help' for interactive filters; Ctrl-C or 'quit' exits.");
if interactive { print!("> "); io::stdout().flush()?; }
let mut filters = LiveLogFilters::default();
let mut history = std::collections::BTreeMap::<u64, serde_json::Value>::new();
+1 -1
View File
@@ -159,7 +159,7 @@ pub(super) fn fastcgi_params(
if context.tls { "on" } else { "off" }.into(),
);
params.insert("GATEWAY_INTERFACE".into(), "CGI/1.1".into());
params.insert("SERVER_SOFTWARE".into(), "RustProxy/0.27.1".into());
params.insert("SERVER_SOFTWARE".into(), "RustProxy/0.27.2".into());
params.insert("REDIRECT_STATUS".into(), "200".into());
if let Some(value) = headers
.get(CONTENT_TYPE)
+1 -1
View File
@@ -185,7 +185,7 @@ pub(super) fn directory_listing(path: &str, entries: &[DirectoryEntry]) -> Vec<u
"<a class=\"{class}\" href=\"{href}\"><span class=\"type\">{type_label}</span><span class=\"name\">{label}{slash}</span><span class=\"kind\">{kind}</span></a>"
));
}
html.push_str(r#"</div></section><footer class="page-footer"><span>RustProxy <b>0.27.1</b></span><span>Web Server · Directory listing</span></footer></main></body></html>"#);
html.push_str(r#"</div></section><footer class="page-footer"><span>RustProxy <b>0.27.2</b></span><span>Web Server · Directory listing</span></footer></main></body></html>"#);
html.into_bytes()
}
+1 -1
View File
@@ -202,7 +202,7 @@ async fn empty_index_can_go_directly_to_directory_listing() {
let body = std::str::from_utf8(&body).unwrap();
assert!(body.contains("file.txt"));
assert!(body.contains("DIRECTORY LISTING"));
assert!(body.contains("RustProxy <b>0.27.1</b>"));
assert!(body.contains("RustProxy <b>0.27.2</b>"));
}
#[tokio::test]