aboutsummaryrefslogtreecommitdiff
path: root/internal/modules/middleware.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/modules/middleware.go')
-rw-r--r--internal/modules/middleware.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/internal/modules/middleware.go b/internal/modules/middleware.go
new file mode 100644
index 0000000..6159573
--- /dev/null
+++ b/internal/modules/middleware.go
@@ -0,0 +1,103 @@
+package modules
+
+import (
+ "net/http"
+ "strings"
+)
+
+// ModuleMiddleware handles Go module requests directly or passes to next handler
+func ModuleMiddleware(moduleHandler http.Handler, next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if isModuleRequest(r) {
+ moduleHandler.ServeHTTP(w, r)
+ return
+ }
+ next.ServeHTTP(w, r)
+ })
+}
+
+// isModuleRequest checks if the request is for Go module endpoints
+func isModuleRequest(r *http.Request) bool {
+ // Check for go-import meta tag requests
+ if r.URL.Query().Get("go-get") == "1" {
+ return true
+ }
+
+ // Check for Go module proxy endpoints
+ return isModuleProxyPath(r.URL.Path)
+}
+
+// isModuleProxyPath checks if the path matches Go module proxy endpoints
+func isModuleProxyPath(path string) bool {
+ // Module proxy endpoints:
+ // /{module}/@v/list
+ // /{module}/@v/{version}.info
+ // /{module}/@v/{version}.mod
+ // /{module}/@v/{version}.zip
+ // /{module}/@latest
+
+ // Check for @latest endpoint
+ if strings.HasSuffix(path, "/@latest") {
+ return true
+ }
+
+ // Check for @v/ endpoints
+ if !strings.Contains(path, "/@v/") {
+ return false
+ }
+
+ // Valid @v/ endpoint suffixes
+ suffixes := []string{"/list", ".info", ".mod", ".zip"}
+ for _, suffix := range suffixes {
+ if strings.HasSuffix(path, suffix) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// ExtractModulePath extracts the module path from a request URL
+func ExtractModulePath(path string) string {
+ // Remove leading slash
+ path = strings.TrimPrefix(path, "/")
+
+ // For proxy endpoints, extract module path before /@v/ or /@latest
+ if idx := strings.Index(path, "/@v/"); idx != -1 {
+ return path[:idx]
+ }
+
+ if strings.HasSuffix(path, "/@latest") {
+ return strings.TrimSuffix(path, "/@latest")
+ }
+
+ // Remove trailing slash for clean module paths
+ return strings.TrimSuffix(path, "/")
+}
+
+// ExtractVersion extracts the version from a module proxy request
+func ExtractVersion(path string) string {
+ if !strings.Contains(path, "/@v/") {
+ return ""
+ }
+
+ // Extract version from /@v/{version}.{suffix}
+ parts := strings.Split(path, "/@v/")
+ if len(parts) != 2 {
+ return ""
+ }
+
+ versionPart := parts[1]
+
+ // Special case for /list endpoint
+ if versionPart == "list" {
+ return ""
+ }
+
+ // Remove suffix (.info, .mod, .zip)
+ if idx := strings.LastIndex(versionPart, "."); idx != -1 {
+ return versionPart[:idx]
+ }
+
+ return versionPart
+}