github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/net/http/cgi/cgi_main.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cgi 6 7 import ( 8 "fmt" 9 "io" 10 "net/http" 11 "os" 12 "path" 13 "sort" 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 // testCGI is a CGI program translated from a Perl program to complete host_test. 28 // test cases in host_test should be provided by testCGI. 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 // 17 MB, for OS X: golang.org/issue/4958 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 sort.Strings(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 sort.Strings(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 // childCGIProcess is used by integration_test to complete unit tests. 99 func childCGIProcess() { 100 if os.Getenv("REQUEST_METHOD") == "" { 101 // Not in a CGI environment; skipping test. 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) // hang forever, until killed 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 }