diff options
Diffstat (limited to 'libgo/go/http/cgi')
-rw-r--r-- | libgo/go/http/cgi/child.go | 12 | ||||
-rw-r--r-- | libgo/go/http/cgi/child_test.go | 6 | ||||
-rw-r--r-- | libgo/go/http/cgi/host.go | 43 | ||||
-rw-r--r-- | libgo/go/http/cgi/host_test.go | 29 |
4 files changed, 70 insertions, 20 deletions
diff --git a/libgo/go/http/cgi/child.go b/libgo/go/http/cgi/child.go index 8d0eca8d55b..bf14c04a843 100644 --- a/libgo/go/http/cgi/child.go +++ b/libgo/go/http/cgi/child.go @@ -93,20 +93,20 @@ func RequestFromMap(params map[string]string) (*http.Request, os.Error) { if r.Host != "" { // Hostname is provided, so we can reasonably construct a URL, // even if we have to assume 'http' for the scheme. - r.RawURL = "http://" + r.Host + params["REQUEST_URI"] - url, err := url.Parse(r.RawURL) + rawurl := "http://" + r.Host + params["REQUEST_URI"] + url, err := url.Parse(rawurl) if err != nil { - return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + r.RawURL) + return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + rawurl) } r.URL = url } // Fallback logic if we don't have a Host header or the URL // failed to parse if r.URL == nil { - r.RawURL = params["REQUEST_URI"] - url, err := url.Parse(r.RawURL) + uriStr := params["REQUEST_URI"] + url, err := url.Parse(uriStr) if err != nil { - return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + r.RawURL) + return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + uriStr) } r.URL = url } diff --git a/libgo/go/http/cgi/child_test.go b/libgo/go/http/cgi/child_test.go index eee043bc90d..ec53ab851ba 100644 --- a/libgo/go/http/cgi/child_test.go +++ b/libgo/go/http/cgi/child_test.go @@ -49,9 +49,6 @@ func TestRequest(t *testing.T) { if g, e := req.Header.Get("Foo-Bar"), "baz"; e != g { t.Errorf("expected Foo-Bar %q; got %q", e, g) } - if g, e := req.RawURL, "http://example.com/path?a=b"; e != g { - t.Errorf("expected RawURL %q; got %q", e, g) - } if g, e := req.URL.String(), "http://example.com/path?a=b"; e != g { t.Errorf("expected URL %q; got %q", e, g) } @@ -81,9 +78,6 @@ func TestRequestWithoutHost(t *testing.T) { if err != nil { t.Fatalf("RequestFromMap: %v", err) } - if g, e := req.RawURL, "/path?a=b"; e != g { - t.Errorf("expected RawURL %q; got %q", e, g) - } if req.URL == nil { t.Fatalf("unexpected nil URL") } diff --git a/libgo/go/http/cgi/host.go b/libgo/go/http/cgi/host.go index f7de89f9974..9ea4c9d8bf2 100644 --- a/libgo/go/http/cgi/host.go +++ b/libgo/go/http/cgi/host.go @@ -32,13 +32,14 @@ import ( var trailingPort = regexp.MustCompile(`:([0-9]+)$`) var osDefaultInheritEnv = map[string][]string{ - "darwin": []string{"DYLD_LIBRARY_PATH"}, - "freebsd": []string{"LD_LIBRARY_PATH"}, - "hpux": []string{"LD_LIBRARY_PATH", "SHLIB_PATH"}, - "irix": []string{"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}, - "linux": []string{"LD_LIBRARY_PATH"}, - "solaris": []string{"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}, - "windows": []string{"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}, + "darwin": {"DYLD_LIBRARY_PATH"}, + "freebsd": {"LD_LIBRARY_PATH"}, + "hpux": {"LD_LIBRARY_PATH", "SHLIB_PATH"}, + "irix": {"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}, + "linux": {"LD_LIBRARY_PATH"}, + "openbsd": {"LD_LIBRARY_PATH"}, + "solaris": {"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}, + "windows": {"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}, } // Handler runs an executable in a subprocess with a CGI environment. @@ -68,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 == "" { @@ -149,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 @@ -294,7 +322,6 @@ func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Reque newReq := &http.Request{ Method: "GET", URL: url, - RawURL: path, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, diff --git a/libgo/go/http/cgi/host_test.go b/libgo/go/http/cgi/host_test.go index ff46631383b..6c0f1a09747 100644 --- a/libgo/go/http/cgi/host_test.go +++ b/libgo/go/http/cgi/host_test.go @@ -451,3 +451,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) +} |