internal/frontend: add support for golang.org/dl

pkg.go.dev/golang.org/dl now shows the contents of that module, instead
of a 400.

Fixes golang/go#43075

Change-Id: If8c6c78ed521fc7f1b93b7f23f70eacfe771587e
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/276232
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/internal/frontend/fetch.go b/internal/frontend/fetch.go
index 6f9a7a3..eecb73a 100644
--- a/internal/frontend/fetch.go
+++ b/internal/frontend/fetch.go
@@ -450,7 +450,6 @@
 	"gitee.com":     true,
 	"github.com":    true,
 	"gitlab.com":    true,
-	"golang.org":    true,
 }
 
 // maxPathsToFetch is the number of modulePaths that are fetched from a single
@@ -461,6 +460,12 @@
 // candidateModulePaths returns the potential module paths that could contain
 // the fullPath. The paths are returned in reverse length order.
 func candidateModulePaths(fullPath string) (_ []string, err error) {
+	if !isValidPath(fullPath) {
+		return nil, &serverError{
+			status: http.StatusBadRequest,
+			err:    fmt.Errorf("isValidPath(%q): false", fullPath),
+		}
+	}
 	var (
 		path        string
 		modulePaths []string
diff --git a/internal/frontend/urlinfo.go b/internal/frontend/urlinfo.go
index 0db1485..0b31e8a 100644
--- a/internal/frontend/urlinfo.go
+++ b/internal/frontend/urlinfo.go
@@ -144,6 +144,15 @@
 		return false
 	}
 	parts := strings.Split(fullPath, "/")
+	if parts[0] == "golang.org" {
+		if fullPath == "golang.org/dl" {
+			return true
+		}
+		if len(parts) >= 3 && parts[1] == "x" {
+			return true
+		}
+		return false
+	}
 	if _, ok := vcsHostsWithThreeElementRepoName[parts[0]]; ok {
 		if len(parts) < 3 {
 			return false
diff --git a/internal/frontend/urlinfo_test.go b/internal/frontend/urlinfo_test.go
index 209af0b..11c886a 100644
--- a/internal/frontend/urlinfo_test.go
+++ b/internal/frontend/urlinfo_test.go
@@ -179,6 +179,31 @@
 	}
 }
 
+func TestIsValidPath(t *testing.T) {
+	tests := []struct {
+		path string
+		want bool
+	}{
+		{"net/http", true},
+		{"github.com/foo", false},
+		{"github.com/foo", false},
+		{"/github.com/foo/bar", false},
+		{"github.com/foo/bar/", false},
+		{"github.com/foo/bar", true},
+		{"github.com/foo/bar/baz", true},
+		{"golang.org/dl", true},
+		{"golang.org/x", false},
+		{"golang.org/x/tools", true},
+		{"golang.org/x/tools/go/packages", true},
+	}
+	for _, test := range tests {
+		got := isValidPath(test.path)
+		if got != test.want {
+			t.Errorf("isValidPath(ctx, ds, %q) = %t, want %t", test.path, got, test.want)
+		}
+	}
+}
+
 func TestIsSupportedVersion(t *testing.T) {
 	tests := []struct {
 		path, version string