diff options
Diffstat (limited to 'internal/modules/middleware.go')
| -rw-r--r-- | internal/modules/middleware.go | 103 |
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 +} |