Commit 45d334ec authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http/cgi: allow CGI host to configure where child's stderr goes

Patch originally from Steven Hartland. Tweaked a bit & added a test.

Fixes #7197

Change-Id: I09012b4674e7c641dba31a24e9758cedb898d3ee
Reviewed-on: https://go-review.googlesource.com/21196Reviewed-by: 's avatarAndrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
parent 093a9a1f
...@@ -58,6 +58,7 @@ type Handler struct { ...@@ -58,6 +58,7 @@ type Handler struct {
InheritEnv []string // environment variables to inherit from host, as "key" InheritEnv []string // environment variables to inherit from host, as "key"
Logger *log.Logger // optional log for errors or nil to use log.Print Logger *log.Logger // optional log for errors or nil to use log.Print
Args []string // optional arguments to pass to child process Args []string // optional arguments to pass to child process
Stderr io.Writer // optional stderr for the child process; nil means os.Stderr
// PathLocationHandler specifies the root http Handler that // PathLocationHandler specifies the root http Handler that
// should handle internal redirects when the CGI process // should handle internal redirects when the CGI process
...@@ -70,6 +71,13 @@ type Handler struct { ...@@ -70,6 +71,13 @@ type Handler struct {
PathLocationHandler http.Handler PathLocationHandler http.Handler
} }
func (h *Handler) stderr() io.Writer {
if h.Stderr != nil {
return h.Stderr
}
return os.Stderr
}
// removeLeadingDuplicates remove leading duplicate in environments. // removeLeadingDuplicates remove leading duplicate in environments.
// It's possible to override environment like following. // It's possible to override environment like following.
// cgi.Handler{ // cgi.Handler{
...@@ -204,7 +212,7 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { ...@@ -204,7 +212,7 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
Args: append([]string{h.Path}, h.Args...), Args: append([]string{h.Path}, h.Args...),
Dir: cwd, Dir: cwd,
Env: env, Env: env,
Stderr: os.Stderr, // for now Stderr: h.stderr(),
} }
if req.ContentLength != 0 { if req.ContentLength != 0 {
cmd.Stdin = req.Body cmd.Stdin = req.Body
......
...@@ -8,6 +8,7 @@ package cgi ...@@ -8,6 +8,7 @@ package cgi
import ( import (
"bufio" "bufio"
"bytes"
"fmt" "fmt"
"io" "io"
"net" "net"
...@@ -500,6 +501,23 @@ func TestEnvOverride(t *testing.T) { ...@@ -500,6 +501,23 @@ func TestEnvOverride(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 TestHandlerStderr(t *testing.T) {
check(t)
var stderr bytes.Buffer
h := &Handler{
Path: "testdata/test.cgi",
Root: "/test.cgi",
Stderr: &stderr,
}
rw := httptest.NewRecorder()
req := newRequest("GET /test.cgi?writestderr=1 HTTP/1.0\nHost: example.com\n\n")
h.ServeHTTP(rw, req)
if got, want := stderr.String(), "Hello, stderr!\n"; got != want {
t.Errorf("Stderr = %q; want %q", got, want)
}
}
func TestRemoveLeadingDuplicates(t *testing.T) { func TestRemoveLeadingDuplicates(t *testing.T) {
tests := []struct { tests := []struct {
env []string env []string
......
...@@ -23,6 +23,10 @@ print "X-CGI-Pid: $$\r\n"; ...@@ -23,6 +23,10 @@ print "X-CGI-Pid: $$\r\n";
print "X-Test-Header: X-Test-Value\r\n"; print "X-Test-Header: X-Test-Value\r\n";
print "\r\n"; print "\r\n";
if ($params->{"writestderr"}) {
print STDERR "Hello, stderr!\n";
}
if ($params->{"bigresponse"}) { if ($params->{"bigresponse"}) {
# 17 MB, for OS X: golang.org/issue/4958 # 17 MB, for OS X: golang.org/issue/4958
for (1..(17 * 1024)) { for (1..(17 * 1024)) {
......
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