mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 13:50:31 +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:
@@ -24,22 +24,8 @@ pub fn render_dashboard(data: &DashboardResponse, lang: Lang) -> String {
|
||||
.registry_stats
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let icon = match r.name.as_str() {
|
||||
"docker" => icons::DOCKER,
|
||||
"maven" => icons::MAVEN,
|
||||
"npm" => icons::NPM,
|
||||
"cargo" => icons::CARGO,
|
||||
"pypi" => icons::PYPI,
|
||||
_ => icons::DOCKER,
|
||||
};
|
||||
let display_name = match r.name.as_str() {
|
||||
"docker" => "Docker",
|
||||
"maven" => "Maven",
|
||||
"npm" => "npm",
|
||||
"cargo" => "Cargo",
|
||||
"pypi" => "PyPI",
|
||||
_ => &r.name,
|
||||
};
|
||||
let icon = get_registry_icon(&r.name);
|
||||
let display_name = get_registry_title(&r.name);
|
||||
render_registry_card(
|
||||
display_name,
|
||||
icon,
|
||||
@@ -155,7 +141,7 @@ pub fn render_dashboard(data: &DashboardResponse, lang: Lang) -> String {
|
||||
|
||||
{}
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4 mb-6">
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3 mb-6">
|
||||
{}
|
||||
</div>
|
||||
|
||||
@@ -669,6 +655,7 @@ pub fn render_package_detail(
|
||||
"pip install {} --index-url http://127.0.0.1:4000/simple",
|
||||
name
|
||||
),
|
||||
"go" => format!("GOPROXY=http://127.0.0.1:4000/go go get {}", name),
|
||||
_ => String::new(),
|
||||
};
|
||||
|
||||
@@ -835,6 +822,7 @@ fn get_registry_icon(registry_type: &str) -> &'static str {
|
||||
"npm" => icons::NPM,
|
||||
"cargo" => icons::CARGO,
|
||||
"pypi" => icons::PYPI,
|
||||
"go" => icons::GO,
|
||||
_ => {
|
||||
r#"<path fill="currentColor" d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>"#
|
||||
}
|
||||
@@ -848,6 +836,7 @@ fn get_registry_title(registry_type: &str) -> &'static str {
|
||||
"npm" => "npm Registry",
|
||||
"cargo" => "Cargo Registry",
|
||||
"pypi" => "PyPI Repository",
|
||||
"go" => "Go Modules",
|
||||
_ => "Registry",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user