Commit 048ec758 authored by Yasuhiro Matsumoto's avatar Yasuhiro Matsumoto Committed by Brad Fitzpatrick

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
parent a083fd52
...@@ -69,6 +69,31 @@ type Handler struct { ...@@ -69,6 +69,31 @@ type Handler struct {
PathLocationHandler http.Handler 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) { func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
root := h.Root root := h.Root
if root == "" { if root == "" {
...@@ -150,6 +175,8 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { ...@@ -150,6 +175,8 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
} }
} }
env = removeLeadingDuplicates(env)
var cwd, path string var cwd, path string
if h.Dir != "" { if h.Dir != "" {
path = h.Path path = h.Path
......
...@@ -447,3 +447,32 @@ func TestDirWindows(t *testing.T) { ...@@ -447,3 +447,32 @@ func TestDirWindows(t *testing.T) {
} }
runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) 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)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment