From 048ec75801156d9cd10991cca741935b17a9041f Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Fri, 16 Sep 2011 10:36:54 -0700 Subject: [PATCH] http/cgi: clean up environment. clean up duplicate environment for CGI. overriding former by latter. On windows, When there are duplicated environments like following, SCRIPT_FILENAME=c:/progra~1/php/php-cgi.exe SCRIPT_FILENAME=/foo.php CreateProcess use first entry. If make cgi.Handle like following, cgih = cgi.Handler{ Path: "c:/strawberry/perl/bin/perl.exe", Dir: "c:/path/to/webroot", Root: "c:/path/to/webroot", Args: []string{"foo.php"}, Env: []string{"SCRIPT_FILENAME=foo.php"}, } http/cgi should behave "SCRIPT_FILENAME is foo.php". But currently, http/cgi is set duplicate environment entries. So, browser show binary dump of "php-cgi.exe" that is specified indented SCRIPT_FILENAME in first entry. This change clean up duplicates, and use latters. R=golang-dev, bradfitz, bradfitz CC=golang-dev https://golang.org/cl/5010044 --- src/pkg/http/cgi/host.go | 27 +++++++++++++++++++++++++++ src/pkg/http/cgi/host_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/pkg/http/cgi/host.go b/src/pkg/http/cgi/host.go index bcd1477034f..1d63821416d 100644 --- a/src/pkg/http/cgi/host.go +++ b/src/pkg/http/cgi/host.go @@ -69,6 +69,31 @@ type Handler struct { PathLocationHandler http.Handler } +// removeLeadingDuplicates remove leading duplicate in environments. +// It's possible to override environment like following. +// cgi.Handler{ +// ... +// Env: []string{"SCRIPT_FILENAME=foo.php"}, +// } +func removeLeadingDuplicates(env []string) (ret []string) { + n := len(env) + for i := 0; i < n; i++ { + e := env[i] + s := strings.SplitN(e, "=", 2)[0] + found := false + for j := i + 1; j < n; j++ { + if s == strings.SplitN(env[j], "=", 2)[0] { + found = true + break + } + } + if !found { + ret = append(ret, e) + } + } + return +} + func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { root := h.Root if root == "" { @@ -150,6 +175,8 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } } + env = removeLeadingDuplicates(env) + var cwd, path string if h.Dir != "" { path = h.Path diff --git a/src/pkg/http/cgi/host_test.go b/src/pkg/http/cgi/host_test.go index 1dc3abdbb32..8111ba19e30 100644 --- a/src/pkg/http/cgi/host_test.go +++ b/src/pkg/http/cgi/host_test.go @@ -447,3 +447,32 @@ func TestDirWindows(t *testing.T) { } runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) } + +func TestEnvOverride(t *testing.T) { + cgifile, _ := filepath.Abs("testdata/test.cgi") + + var perl string + var err os.Error + perl, err = exec.LookPath("perl") + if err != nil { + return + } + perl, _ = filepath.Abs(perl) + + cwd, _ := os.Getwd() + h := &Handler{ + Path: perl, + Root: "/test.cgi", + Dir: cwd, + Args: []string{cgifile}, + Env: []string{ + "SCRIPT_FILENAME=" + cgifile, + "REQUEST_URI=/foo/bar"}, + } + expectedMap := map[string]string{ + "cwd": cwd, + "env-SCRIPT_FILENAME": cgifile, + "env-REQUEST_URI": "/foo/bar", + } + runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) +}