14 fcgiclient "github.com/alash3al/go-fastcgi-client"
15 "go.stargrave.org/godlighty"
19 w http.ResponseWriter,
21 host, docRoot, scriptName, sockProto, sockPath string,
22 timeout time.Duration,
25 serverHost, serverPort, err := net.SplitHostPort(godlighty.BindAddr)
29 remoteAddr, remotePort, _ := net.SplitHostPort(r.RemoteAddr)
30 params := map[string]string{
31 "GATEWAY_INTERFACE": "CGI/1.1",
33 "PATH_INFO": r.URL.Path,
34 "QUERY_STRING": r.URL.RawQuery,
36 "REMOTE_ADDR": remoteAddr,
37 "REMOTE_PORT": remotePort,
39 "SERVER_NAME": serverHost,
40 "SERVER_PORT": serverPort,
41 "SERVER_PROTOCOL": r.Proto,
42 "SERVER_SOFTWARE": godlighty.Version,
44 "REQUEST_METHOD": r.Method,
45 "DOCUMENT_ROOT": docRoot,
46 "SCRIPT_NAME": scriptName,
47 "SCRIPT_FILENAME": path.Join(docRoot, scriptName),
49 for k, vs := range r.Header {
53 k = "HTTP_" + strings.ToUpper(strings.Replace(k, "-", "_", -1))
54 params[k] = strings.Join(vs, ";")
56 c, err := fcgiclient.Dial(sockProto, sockPath)
58 http.Error(w, err.Error(), http.StatusInternalServerError)
59 log.Println("can not FCGI:", err)
63 c.SetReadTimeout(timeout)
64 c.SetSendTimeout(timeout)
65 resp, err := c.Request(params, r.Body)
67 http.Error(w, err.Error(), http.StatusInternalServerError)
68 log.Println("can not FCGI:", err)
71 defer resp.Body.Close()
72 for k, vs := range resp.Header {
73 for _, v := range vs {
77 if resp.ContentLength > 0 {
78 w.Header().Set("Content-Length", strconv.FormatInt(resp.ContentLength, 10))
80 w.WriteHeader(resp.StatusCode)
81 written, err := io.Copy(w, resp.Body)
84 log.Println("can not copy FCGI:", string(stderr.Bytes()))
87 fmt.Printf("%s %s \"%s %+q %s\" %d %d \"%s\"\n",
88 r.RemoteAddr, host, r.Method, godlighty.PathWithQuery(r.URL), r.Proto,
89 resp.StatusCode, written,
90 r.Header.Get("User-Agent"),