LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file implements the host side of CGI (being the webserver | 5 // This file implements the host side of CGI (being the webserver |
6 // parent process). | 6 // parent process). |
7 | 7 |
8 // Package cgi implements CGI (Common Gateway Interface) as specified | 8 // Package cgi implements CGI (Common Gateway Interface) as specified |
9 // in RFC 3875. | 9 // in RFC 3875. |
10 // | 10 // |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 internalError(err) | 180 internalError(err) |
181 return | 181 return |
182 } | 182 } |
183 | 183 |
184 err = cmd.Start() | 184 err = cmd.Start() |
185 if err != nil { | 185 if err != nil { |
186 internalError(err) | 186 internalError(err) |
187 return | 187 return |
188 } | 188 } |
189 defer cmd.Wait() | 189 defer cmd.Wait() |
| 190 defer stdoutRead.Close() |
190 | 191 |
191 linebody, _ := bufio.NewReaderSize(stdoutRead, 1024) | 192 linebody, _ := bufio.NewReaderSize(stdoutRead, 1024) |
192 headers := make(http.Header) | 193 headers := make(http.Header) |
193 statusCode := 0 | 194 statusCode := 0 |
194 for { | 195 for { |
195 line, isPrefix, err := linebody.ReadLine() | 196 line, isPrefix, err := linebody.ReadLine() |
196 if isPrefix { | 197 if isPrefix { |
197 rw.WriteHeader(http.StatusInternalServerError) | 198 rw.WriteHeader(http.StatusInternalServerError) |
198 h.printf("cgi: long header line from subprocess.") | 199 h.printf("cgi: long header line from subprocess.") |
199 return | 200 return |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 for _, v := range vv { | 257 for _, v := range vv { |
257 rw.Header().Add(k, v) | 258 rw.Header().Add(k, v) |
258 } | 259 } |
259 } | 260 } |
260 | 261 |
261 rw.WriteHeader(statusCode) | 262 rw.WriteHeader(statusCode) |
262 | 263 |
263 _, err = io.Copy(rw, linebody) | 264 _, err = io.Copy(rw, linebody) |
264 if err != nil { | 265 if err != nil { |
265 h.printf("cgi: copy error: %v", err) | 266 h.printf("cgi: copy error: %v", err) |
266 cmd.Process.Kill() | |
267 } | 267 } |
268 } | 268 } |
269 | 269 |
270 func (h *Handler) printf(format string, v ...interface{}) { | 270 func (h *Handler) printf(format string, v ...interface{}) { |
271 if h.Logger != nil { | 271 if h.Logger != nil { |
272 h.Logger.Printf(format, v...) | 272 h.Logger.Printf(format, v...) |
273 } else { | 273 } else { |
274 log.Printf(format, v...) | 274 log.Printf(format, v...) |
275 } | 275 } |
276 } | 276 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 return '_' | 314 return '_' |
315 case rune == '=': | 315 case rune == '=': |
316 // Maybe not part of the CGI 'spec' but would mess up | 316 // Maybe not part of the CGI 'spec' but would mess up |
317 // the environment in any case, as Go represents the | 317 // the environment in any case, as Go represents the |
318 // environment as a slice of "key=value" strings. | 318 // environment as a slice of "key=value" strings. |
319 return '_' | 319 return '_' |
320 } | 320 } |
321 // TODO: other transformations in spec or practice? | 321 // TODO: other transformations in spec or practice? |
322 return rune | 322 return rune |
323 } | 323 } |
LEFT | RIGHT |