func makeRequest(params map[string]string) (*http.Request, error) { r := new(http.Request) r.Method = params["METHOD"] if r.Method == "" { return nil, errors.New("mongrel2: no METHOD") } r.Proto = params["VERSION"] var ok bool r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto) if !ok { return nil, errors.New("mongrel2: invalid protocol version") } r.Trailer = http.Header{} r.Header = http.Header{} r.Host = params["Host"] r.Header.Set("Referer", params["Referer"]) r.Header.Set("User-Agent", params["User-Agent"]) if lenstr := params["Content-Length"]; lenstr != "" { clen, err := strconv.ParseInt(lenstr, 10, 64) if err != nil { return nil, errors.New("mongrel2: bad Content-Length") } r.ContentLength = clen } for k, v := range params { if !skipHeader[k] { r.Header.Add(k, v) } } // TODO: cookies if r.Host != "" { url_, err := url.Parse("http://" + r.Host + params["URI"]) if err != nil { return nil, errors.New("mongrel2: failed to parse host and URI into a URL") } r.URL = url_ } if r.URL == nil { url_, err := url.Parse(params["URI"]) if err != nil { return nil, errors.New("mongrel2: failed to parse URI into a URL") } r.URL = url_ } // TODO: how do we know if we're using HTTPS? // TODO: fill in r.RemoteAddr return r, nil }
func RequestFromMap(params map[string]string) (*http.Request, error) { r:= new (http.Request) r.Method =params["REQUEST_METHOD"] if r.Method ==""{ return nil ,errors.New("cgi:no REQUEST_METHOD in enviroment") } r.Proto = params["SERVER_PROTOCOL"] var ok bool r.ProtoMajor, r.ProtoMinor ,ok = http.ParseHTTPVersion(r.Proto) if !ok { return nil,errors.New("cgi:invalid SERVER_PROTOCOL version") } r.Close = true r.Trailer = http.Header{} r.Header = http.Header{} r.Host = params["HTTP_HOST"] if lenstr := params["CONTENT_LENGTH"]; lenstr != "" { clen ,err := strconv.ParseInt(lenstr, 10, 64) if err !=nil { return nil ,errors.New("cgi:bad CONTENT_LENTH in environment :"+ lenstr) } r.ContentLength = clen } if ct := params["CONTENT_TYPE"];ct != ""{ r.Header.Set("Content-Type", ct) } for k,v:=range params { if !strings.HasPrefix(k, "HTTP_"|| K == "HTTP_HOST"){ continue } r.Header.Add(strings.Replace(k[5:],"_","-", -1), v) } uriStr = params["SCRIPT_NAME"] +params["PATH_INFO"] s:=params["QUERY_STRING"] if s!=""{ uriStr +="?"+s } }
// RequestFromMap creates an http.Request from CGI variables. // The returned Request's Body field is not populated. func RequestFromMap(params map[string]string) (*http.Request, error) { r := new(http.Request) r.Method = params["REQUEST_METHOD"] if r.Method == "" { return nil, errors.New("cgi: no REQUEST_METHOD in environment") } r.Proto = params["SERVER_PROTOCOL"] var ok bool r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto) if !ok { return nil, errors.New("cgi: invalid SERVER_PROTOCOL version") } r.Close = true r.Trailer = http.Header{} r.Header = http.Header{} r.Host = params["HTTP_HOST"] if lenstr := params["CONTENT_LENGTH"]; lenstr != "" { clen, err := strconv.ParseInt(lenstr, 10, 64) if err != nil { return nil, errors.New("cgi: bad CONTENT_LENGTH in environment: " + lenstr) } r.ContentLength = clen } if ct := params["CONTENT_TYPE"]; ct != "" { r.Header.Set("Content-Type", ct) } // Copy "HTTP_FOO_BAR" variables to "Foo-Bar" Headers for k, v := range params { if !strings.HasPrefix(k, "HTTP_") || k == "HTTP_HOST" { continue } r.Header.Add(strings.Replace(k[5:], "_", "-", -1), v) } // TODO: cookies. parsing them isn't exported, though. if r.Host != "" { // Hostname is provided, so we can reasonably construct a URL, // even if we have to assume 'http' for the scheme. rawurl := "http://" + r.Host + params["REQUEST_URI"] url, err := url.Parse(rawurl) if err != nil { return nil, errors.New("cgi: failed to parse host and REQUEST_URI into a URL: " + rawurl) } r.URL = url } // Fallback logic if we don't have a Host header or the URL // failed to parse if r.URL == nil { uriStr := params["REQUEST_URI"] url, err := url.Parse(uriStr) if err != nil { return nil, errors.New("cgi: failed to parse REQUEST_URI into a URL: " + uriStr) } r.URL = url } // There's apparently a de-facto standard for this. // http://docstore.mik.ua/orelly/linux/cgi/ch03_02.htm#ch03-35636 if s := params["HTTPS"]; s == "on" || s == "ON" || s == "1" { r.TLS = &tls.ConnectionState{HandshakeComplete: true} } // Request.RemoteAddr has its port set by Go's standard http // server, so we do here too. We don't have one, though, so we // use a dummy one. r.RemoteAddr = net.JoinHostPort(params["REMOTE_ADDR"], "0") return r, nil }