Source file
src/net/http/cgi/cgi_main.go
1
2
3
4
5 package cgi
6
7 import (
8 "fmt"
9 "io"
10 "net/http"
11 "os"
12 "path"
13 "slices"
14 "strings"
15 "time"
16 )
17
18 func cgiMain() {
19 switch path.Join(os.Getenv("SCRIPT_NAME"), os.Getenv("PATH_INFO")) {
20 case "/bar", "/test.cgi", "/myscript/bar", "/test.cgi/extrapath":
21 testCGI()
22 return
23 }
24 childCGIProcess()
25 }
26
27
28
29 func testCGI() {
30 req, err := Request()
31 if err != nil {
32 panic(err)
33 }
34
35 err = req.ParseForm()
36 if err != nil {
37 panic(err)
38 }
39
40 params := req.Form
41 if params.Get("loc") != "" {
42 fmt.Printf("Location: %s\r\n\r\n", params.Get("loc"))
43 return
44 }
45
46 fmt.Printf("Content-Type: text/html\r\n")
47 fmt.Printf("X-CGI-Pid: %d\r\n", os.Getpid())
48 fmt.Printf("X-Test-Header: X-Test-Value\r\n")
49 fmt.Printf("\r\n")
50
51 if params.Get("writestderr") != "" {
52 fmt.Fprintf(os.Stderr, "Hello, stderr!\n")
53 }
54
55 if params.Get("bigresponse") != "" {
56
57 line := strings.Repeat("A", 1024)
58 for i := 0; i < 17*1024; i++ {
59 fmt.Printf("%s\r\n", line)
60 }
61 return
62 }
63
64 fmt.Printf("test=Hello CGI\r\n")
65
66 keys := make([]string, 0, len(params))
67 for k := range params {
68 keys = append(keys, k)
69 }
70 slices.Sort(keys)
71 for _, key := range keys {
72 fmt.Printf("param-%s=%s\r\n", key, params.Get(key))
73 }
74
75 envs := envMap(os.Environ())
76 keys = make([]string, 0, len(envs))
77 for k := range envs {
78 keys = append(keys, k)
79 }
80 slices.Sort(keys)
81 for _, key := range keys {
82 fmt.Printf("env-%s=%s\r\n", key, envs[key])
83 }
84
85 cwd, _ := os.Getwd()
86 fmt.Printf("cwd=%s\r\n", cwd)
87 }
88
89 type neverEnding byte
90
91 func (b neverEnding) Read(p []byte) (n int, err error) {
92 for i := range p {
93 p[i] = byte(b)
94 }
95 return len(p), nil
96 }
97
98
99 func childCGIProcess() {
100 if os.Getenv("REQUEST_METHOD") == "" {
101
102 return
103 }
104 switch os.Getenv("REQUEST_URI") {
105 case "/immediate-disconnect":
106 os.Exit(0)
107 case "/no-content-type":
108 fmt.Printf("Content-Length: 6\n\nHello\n")
109 os.Exit(0)
110 case "/empty-headers":
111 fmt.Printf("\nHello")
112 os.Exit(0)
113 }
114 Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
115 if req.FormValue("nil-request-body") == "1" {
116 fmt.Fprintf(rw, "nil-request-body=%v\n", req.Body == nil)
117 return
118 }
119 rw.Header().Set("X-Test-Header", "X-Test-Value")
120 req.ParseForm()
121 if req.FormValue("no-body") == "1" {
122 return
123 }
124 if eb, ok := req.Form["exact-body"]; ok {
125 io.WriteString(rw, eb[0])
126 return
127 }
128 if req.FormValue("write-forever") == "1" {
129 io.Copy(rw, neverEnding('a'))
130 for {
131 time.Sleep(5 * time.Second)
132 }
133 }
134 fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n")
135 for k, vv := range req.Form {
136 for _, v := range vv {
137 fmt.Fprintf(rw, "param-%s=%s\n", k, v)
138 }
139 }
140 for _, kv := range os.Environ() {
141 fmt.Fprintf(rw, "env-%s\n", kv)
142 }
143 }))
144 os.Exit(0)
145 }
146
View as plain text