cmd/godoc: accept GOOS and GOARCH URL parameters in -http mode

This allows users to change the GOOS/GOARCH without running their own
godoc server (or restarting with appropriate env vars).

Change-Id: I0b54ef1b2dd93cf2c965ca584d8df74119ed1be6
Reviewed-on: https://go-review.googlesource.com/1371
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/godoc/server.go b/godoc/server.go
index 6906df8..18f110a 100644
--- a/godoc/server.go
+++ b/godoc/server.go
@@ -54,16 +54,15 @@
 // directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is
 // set to the respective error but the error is not logged.
 //
-func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
+func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode, goos, goarch string) *PageInfo {
 	info := &PageInfo{Dirname: abspath}
 
 	// Restrict to the package files that would be used when building
 	// the package on this system.  This makes sure that if there are
 	// separate implementations for, say, Windows vs Unix, we don't
 	// jumble them all together.
-	// Note: Uses current binary's GOOS/GOARCH.
-	// To use different pair, such as if we allowed the user to choose,
-	// set ctxt.GOOS and ctxt.GOARCH before calling ctxt.ImportDir.
+	// Note: If goos/goarch aren't set, the current binary's GOOS/GOARCH
+	// are used.
 	ctxt := build.Default
 	ctxt.IsAbsPath = pathpkg.IsAbs
 	ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
@@ -84,6 +83,13 @@
 		return ioutil.NopCloser(bytes.NewReader(data)), nil
 	}
 
+	if goos != "" {
+		ctxt.GOOS = goos
+	}
+	if goarch != "" {
+		ctxt.GOARCH = goarch
+	}
+
 	pkginfo, err := ctxt.ImportDir(abspath, 0)
 	// continue if there are no Go source files; we still want the directory info
 	if _, nogo := err.(*build.NoGoError); err != nil && !nogo {
@@ -242,7 +248,7 @@
 	if relpath == builtinPkgPath {
 		mode = NoFiltering | NoTypeAssoc
 	}
-	info := h.GetPageInfo(abspath, relpath, mode)
+	info := h.GetPageInfo(abspath, relpath, mode, r.FormValue("GOOS"), r.FormValue("GOARCH"))
 	if info.Err != nil {
 		log.Print(info.Err)
 		h.p.ServeError(w, r, relpath, info.Err)