internal/frontend: serve /vuln

Serve the /vuln endpoint with the following behavior:

/vuln: redirect to the doc for golang.org/x/vulndb.

/vuln/list: display the directory in the vulndb repo containing all
vuln reports.

/vuln/{ID}: display the vuln with ID, in yaml form, directly from the
vulndb repo.

For golang/go#48223

Change-Id: Iedfd1e6a4782fa7f1b3c4fc9cc2dcefd453db288
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/348791
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/frontend/server.go b/internal/frontend/server.go
index 671a7a8..42d2585 100644
--- a/internal/frontend/server.go
+++ b/internal/frontend/server.go
@@ -156,6 +156,7 @@
 	}))
 	handle("/golang.org/x", s.staticPageHandler("subrepo", "Sub-repositories"))
 	handle("/files/", http.StripPrefix("/files", s.fileMux))
+	handle("/vuln/", http.StripPrefix("/vuln", s.errorHandler(s.serveVuln)))
 	handle("/", detailHandler)
 	if s.serveStats {
 		handle("/detail-stats/",
diff --git a/internal/frontend/vulns.go b/internal/frontend/vulns.go
index 0d5c72f..eeddee8 100644
--- a/internal/frontend/vulns.go
+++ b/internal/frontend/vulns.go
@@ -6,8 +6,11 @@
 
 import (
 	"fmt"
+	"net/http"
+	"path"
 
 	"golang.org/x/mod/semver"
+	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/derrors"
 	"golang.org/x/vulndb/osv"
 )
@@ -84,3 +87,19 @@
 	}
 	return Vuln{}, false
 }
+
+const vulndbURL = "https://go.googlesource.com/vulndb/+/refs/heads/master/reports/"
+
+func (s *Server) serveVuln(w http.ResponseWriter, r *http.Request, _ internal.DataSource) error {
+	if r.URL.Path == "/" {
+		http.Redirect(w, r, "/golang.org/x/vulndb", http.StatusFound)
+		return nil
+	}
+	if r.URL.Path == "/list" {
+		http.Redirect(w, r, vulndbURL, http.StatusFound)
+		return nil
+	}
+	// Otherwise, the path should be "/ID".
+	http.Redirect(w, r, path.Join(vulndbURL, r.URL.Path+".yaml"), http.StatusFound)
+	return nil
+}