summaryrefslogtreecommitdiffstats
path: root/libgo/go/http/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/http/cgi')
-rw-r--r--libgo/go/http/cgi/child.go12
-rw-r--r--libgo/go/http/cgi/child_test.go6
-rw-r--r--libgo/go/http/cgi/host.go43
-rw-r--r--libgo/go/http/cgi/host_test.go29
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)
+}
OpenPOWER on IntegriCloud