mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-13 01:30:32 +00:00
feat: add Go module proxy (GOPROXY protocol) (#59)
* feat: add Go module proxy (GOPROXY protocol) (#47) Implements caching proxy for Go modules with 5 standard endpoints: - GET /go/{module}/@v/list — list versions - GET /go/{module}/@v/{version}.info — version metadata - GET /go/{module}/@v/{version}.mod — go.mod file - GET /go/{module}/@v/{version}.zip — module zip - GET /go/{module}/@latest — latest version info Features: - Module path encoding/decoding per Go spec (!x → X) - Immutable caching (.info/.mod/.zip never overwritten) - Mutable endpoints (@v/list, @latest) refreshed from upstream - Configurable upstream (default: proxy.golang.org) - Separate timeout for .zip downloads (default: 120s) - Size limit for zips (default: 100MB) - Path traversal protection - Dashboard integration (stats, mount points, index) - 25 unit tests (encoding, path splitting, safety, content-type) Closes #47 * style: cargo fmt * feat(ui): add Go pages, compact cards, fix icons - Go in sidebar + list/detail pages with go get command - Dashboard: fix fallback icon (was Docker whale for Go) - Compact registry cards: lg:grid-cols-6, all 6 in one row - Cargo icon: crate boxes instead of truck - Go icon: stylized Go text (sidebar + dashboard) * fix(go): URL-decode path + send encoded paths to upstream Go client sends %21 for ! in module paths. Axum wildcard does not auto-decode, so we percent-decode manually. Upstream proxy.golang.org expects encoded paths (with !), not decoded uppercase. Tested: full Pusk build (22 modules, 135MB cached) including SherClockHolmes/webpush-go with triple uppercase encoding. * style: cargo fmt
This commit is contained in:
@@ -26,6 +26,8 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
pub docker: DockerConfig,
|
||||
#[serde(default)]
|
||||
pub go: GoConfig,
|
||||
#[serde(default)]
|
||||
pub raw: RawConfig,
|
||||
#[serde(default)]
|
||||
pub auth: AuthConfig,
|
||||
@@ -127,6 +129,48 @@ pub struct PypiConfig {
|
||||
pub proxy_timeout: u64,
|
||||
}
|
||||
|
||||
/// Go module proxy configuration (GOPROXY protocol)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GoConfig {
|
||||
/// Upstream Go module proxy URL (default: https://proxy.golang.org)
|
||||
#[serde(default = "default_go_proxy")]
|
||||
pub proxy: Option<String>,
|
||||
#[serde(default)]
|
||||
pub proxy_auth: Option<String>, // "user:pass" for basic auth
|
||||
#[serde(default = "default_timeout")]
|
||||
pub proxy_timeout: u64,
|
||||
/// Separate timeout for .zip downloads (default: 120s, zips can be large)
|
||||
#[serde(default = "default_go_zip_timeout")]
|
||||
pub proxy_timeout_zip: u64,
|
||||
/// Maximum module zip size in bytes (default: 100MB)
|
||||
#[serde(default = "default_go_max_zip_size")]
|
||||
pub max_zip_size: u64,
|
||||
}
|
||||
|
||||
fn default_go_proxy() -> Option<String> {
|
||||
Some("https://proxy.golang.org".to_string())
|
||||
}
|
||||
|
||||
fn default_go_zip_timeout() -> u64 {
|
||||
120
|
||||
}
|
||||
|
||||
fn default_go_max_zip_size() -> u64 {
|
||||
104_857_600 // 100MB
|
||||
}
|
||||
|
||||
impl Default for GoConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
proxy: default_go_proxy(),
|
||||
proxy_auth: None,
|
||||
proxy_timeout: 30,
|
||||
proxy_timeout_zip: 120,
|
||||
max_zip_size: 104_857_600,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Docker registry configuration with upstream proxy support
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DockerConfig {
|
||||
@@ -387,6 +431,10 @@ impl Config {
|
||||
);
|
||||
}
|
||||
}
|
||||
// Go
|
||||
if self.go.proxy_auth.is_some() && std::env::var("NORA_GO_PROXY_AUTH").is_err() {
|
||||
tracing::warn!("Go proxy credentials in config.toml are plaintext — consider NORA_GO_PROXY_AUTH env var");
|
||||
}
|
||||
// npm
|
||||
if self.npm.proxy_auth.is_some() && std::env::var("NORA_NPM_PROXY_AUTH").is_err() {
|
||||
tracing::warn!("npm proxy credentials in config.toml are plaintext — consider NORA_NPM_PROXY_AUTH env var");
|
||||
@@ -629,6 +677,7 @@ impl Default for Config {
|
||||
maven: MavenConfig::default(),
|
||||
npm: NpmConfig::default(),
|
||||
pypi: PypiConfig::default(),
|
||||
go: GoConfig::default(),
|
||||
docker: DockerConfig::default(),
|
||||
raw: RawConfig::default(),
|
||||
auth: AuthConfig::default(),
|
||||
|
||||
Reference in New Issue
Block a user