func (client ApiClient) do(req *http.Request, body interface{}, responseBody interface{}) error { var buf *bytes.Buffer if body != nil { switch body.(type) { case io.Reader: req.Body = ioutil.NopCloser(body.(io.Reader)) default: buf = new(bytes.Buffer) encoder := client.encoder(buf) if err := encoder.Encode(body); err != nil { return err } req.Body = ioutil.NopCloser(buf) } } if resp, err := http.DefaultClient.Do(req); err != nil { return err } else if err = client.errorFromResponse(resp); err != nil { return err } else { if responseBody != nil { defer resp.Body.Close() decoder := client.decoder(resp.Body) return decoder.Decode(responseBody) } return nil } }
func CopyHttpRequest(r *http.Request) *http.Request { reqCopy := new(http.Request) if r == nil { return reqCopy } *reqCopy = *r if r.Body != nil { defer r.Body.Close() // Buffer body data var bodyBuffer bytes.Buffer bodyBuffer2 := new(bytes.Buffer) io.Copy(&bodyBuffer, r.Body) *bodyBuffer2 = bodyBuffer // Create new ReadClosers so we can split output r.Body = ioutil.NopCloser(&bodyBuffer) reqCopy.Body = ioutil.NopCloser(bodyBuffer2) } return reqCopy }
// dispatchRequest sends a request to the server, and interprets the response. // Client-side errors will return an empty response and a non-nil error. For // server-side errors however (i.e. responses with a non 2XX status code), the // returned error will be ServerError and the returned body will reflect the // server's response. If the server returns a 503 response with a 'Retry-after' // header, the request will be transparenty retried. func (client Client) dispatchRequest(request *http.Request) ([]byte, error) { // First, store the request's body into a byte[] to be able to restore it // after each request. bodyContent, err := readAndClose(request.Body) if err != nil { return nil, err } for retry := 0; retry < NumberOfRetries; retry++ { // Restore body before issuing request. newBody := ioutil.NopCloser(bytes.NewReader(bodyContent)) request.Body = newBody body, err := client.dispatchSingleRequest(request) // If this is a 503 response with a non-void "Retry-After" header: wait // as instructed and retry the request. if err != nil { serverError, ok := err.(ServerError) if ok && serverError.StatusCode == http.StatusServiceUnavailable { retry_time_int, errConv := strconv.Atoi(serverError.Header.Get(RetryAfterHeaderName)) if errConv == nil { select { case <-time.After(time.Duration(retry_time_int) * time.Second): } continue } } } return body, err } // Restore body before issuing request. newBody := ioutil.NopCloser(bytes.NewReader(bodyContent)) request.Body = newBody return client.dispatchSingleRequest(request) }
func (t *logTransport) RoundTrip(req *http.Request) (*http.Response, error) { var buf bytes.Buffer os.Stdout.Write([]byte("\n[request]\n")) if req.Body != nil { req.Body = ioutil.NopCloser(&readButCopy{req.Body, &buf}) } req.Write(os.Stdout) if req.Body != nil { req.Body = ioutil.NopCloser(&buf) } os.Stdout.Write([]byte("\n[/request]\n")) res, err := t.rt.RoundTrip(req) fmt.Printf("[response]\n") if err != nil { fmt.Printf("ERROR: %v", err) } else { body := res.Body res.Body = nil res.Write(os.Stdout) if body != nil { res.Body = ioutil.NopCloser(&echoAsRead{body}) } } return res, err }
func ReadBody(req *http.Request) *string { save := req.Body var err error if req.Body == nil { req.Body = nil } else { save, req.Body, err = drainBody(req.Body) if err != nil { return nil } } b := bytes.NewBuffer([]byte("")) chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" if req.Body == nil { return nil } var dest io.Writer = b if chunked { dest = httputil.NewChunkedWriter(dest) } _, err = io.Copy(dest, req.Body) if chunked { dest.(io.Closer).Close() } req.Body = save body := b.String() return &body }
// handle request body func (conn Conn) handleBody(req *http.Request, body io.Reader) { rc, ok := body.(io.ReadCloser) if !ok && body != nil { rc = ioutil.NopCloser(body) } req.Body = rc switch v := body.(type) { case *bytes.Buffer: req.ContentLength = int64(v.Len()) case *bytes.Reader: req.ContentLength = int64(v.Len()) case *strings.Reader: req.ContentLength = int64(v.Len()) case *os.File: req.ContentLength = tryGetFileSize(v) } req.Header.Set(HTTPHeaderContentLength, strconv.FormatInt(req.ContentLength, 10)) // md5 if req.Body != nil { buf, _ := ioutil.ReadAll(req.Body) req.Body = ioutil.NopCloser(bytes.NewReader(buf)) sum := md5.Sum(buf) b64 := base64.StdEncoding.EncodeToString(sum[:]) req.Header.Set(HTTPHeaderContentMD5, b64) } }
func (k *AuthKey) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) { thisConfig := k.TykMiddleware.Spec.APIDefinition.Auth authHeaderValue := r.Header.Get(thisConfig.AuthHeaderName) if thisConfig.UseParam { tempRes := new(http.Request) *tempRes = *r defer r.Body.Close() // Buffer body data - don't like thi but we would otherwise drain the request body var bodyBuffer bytes.Buffer bodyBuffer2 := new(bytes.Buffer) k.copyResponse(&bodyBuffer, r.Body) *bodyBuffer2 = bodyBuffer // Create new ReadClosers so we can split output r.Body = ioutil.NopCloser(&bodyBuffer) tempRes.Body = ioutil.NopCloser(bodyBuffer2) // Set hte header name authHeaderValue = tempRes.FormValue(thisConfig.AuthHeaderName) } if authHeaderValue == "" { // No header value, fail log.WithFields(logrus.Fields{ "path": r.URL.Path, "origin": r.RemoteAddr, }).Info("Attempted access with malformed header, no auth header found.") return errors.New("Authorization field missing"), 400 } // Check if API key valid thisSessionState, keyExists := k.TykMiddleware.CheckSessionAndIdentityForValidKey(authHeaderValue) if !keyExists { log.WithFields(logrus.Fields{ "path": r.URL.Path, "origin": r.RemoteAddr, "key": authHeaderValue, }).Info("Attempted access with non-existent key.") // Fire Authfailed Event AuthFailed(k.TykMiddleware, r, authHeaderValue) // Report in health check ReportHealthCheckValue(k.Spec.Health, KeyFailure, "1") return errors.New("Key not authorised"), 403 } // Set session state on context, we will need it later context.Set(r, SessionData, thisSessionState) context.Set(r, AuthHeaderValue, authHeaderValue) return nil, 200 }
// DumpRequest returns the as-received wire representation of req, // optionally including the request body, for debugging. // DumpRequest is semantically a no-op, but in order to // dump the body, it reads the body data into memory and // changes req.Body to refer to the in-memory copy. // The documentation for http.Request.Write details which fields // of req are used. func DumpRequest(req *http.Request, body bool) (dump []byte, err error) { save := req.Body if !body || req.Body == nil { req.Body = nil } else { save, req.Body, err = drainBody(req.Body) if err != nil { return } } var b bytes.Buffer fmt.Fprintf(&b, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"), req.URL.RequestURI(), req.ProtoMajor, req.ProtoMinor) host := req.Host if host == "" && req.URL != nil { host = req.URL.Host } if host != "" { fmt.Fprintf(&b, "Host: %s\r\n", host) } chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" if len(req.TransferEncoding) > 0 { fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ",")) } if req.Close { fmt.Fprintf(&b, "Connection: close\r\n") } err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump) if err != nil { return } io.WriteString(&b, "\r\n") if req.Body != nil { var dest io.Writer = &b if chunked { dest = NewChunkedWriter(dest) } _, err = io.Copy(dest, req.Body) if chunked { dest.(io.Closer).Close() io.WriteString(&b, "\r\n") } } req.Body = save if err != nil { return } dump = b.Bytes() return }
// captureRequest saves request for later playback func (hf *Hoverfly) captureRequest(req *http.Request) (*http.Response, error) { // this is mainly for testing, since when you create if req.Body == nil { req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(""))) } reqBody, err := ioutil.ReadAll(req.Body) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "mode": "capture", }).Error("Got error when reading request body") } // outputting request body if verbose logging is set log.WithFields(log.Fields{ "body": string(reqBody), "mode": "capture", }).Debug("got request body") // forwarding request req.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) req, resp, err := hf.doRequest(req) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "mode": "capture", }).Error("Got error when reading body after being modified by middleware") } reqBody, err = ioutil.ReadAll(req.Body) req.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) if err == nil { respBody, err := extractBody(resp) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "mode": "capture", }).Error("Failed to copy response body.") return resp, err } // saving response body with request/response meta to cache hf.save(req, reqBody, resp, respBody) } // return new response or error here return resp, err }
// eccaProxy: proxy the user requests and authenticate with the credentials we know. func eccaProxy(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { //log.Println("\n\n\nRequest is ", req.Method, req.URL.String()) ctx.Logf("Start-of-eccaProxy handler") for _, c := range req.Cookies() { ctx.Logf("Cookie send by the client is: %#v", c.Name) } // set the scheme to https so we connect upstream securely if req.URL.Scheme == "http" { req.URL.Scheme = "https" } // Copy the body because we need it untouched. But we also need to parse // the POST parameters and that eats the original buffer with the body body, err := ioutil.ReadAll(req.Body) check(err) req.Body.Close() // close it before replacing. Prevents leaking file descriptors. // give the data back immedeately. req.Body = ioutil.NopCloser(bytes.NewReader(body)) // Read the parameters req.ParseForm() // eats req.Body req.Body = ioutil.NopCloser(bytes.NewReader(body)) // copy back in again // Check for POST method with 'encrypt', 'sign' or 'initiate-direct-connection' parameter. if req.Method == "POST" { if req.Form.Get("initiate-direct-connection") == "required" { // create a direct connection listener, awaiting reply return initiateDirectConnection(req) } else if req.Form.Get("encrypt") == "required" { // transparantly encrypt and sign for a private message return encryptMessage(req) } else if req.Form.Get("sign") == "required" || req.Form.Get("sign") == "optional" { // transparently sign the message before publication return signMessage(req, ctx) } } // Fetch the request from upstream resp, err := fetchRequest(req, ctx) if err != nil { ctx.Warnf("There was an error fetching the users' request: %v", err) return req, goproxy.NewResponse(req, goproxy.ContentTypeText, http.StatusInternalServerError, "Some server error!") } ctx.Logf("response is %#v", resp) for _, c := range resp.Cookies() { ctx.Logf("Cookie send by the server is: %#v\n", c.Name) } ctx.Logf("End-of-eccaProxy handler") //log.Printf("Sleeping for 10 seconds...\n") //time.Sleep(10 * time.Second) return nil, resp // let goproxy send our response }
// RoundTrip makes a request expecting a 401 response that will require digest // authentication. It creates the credentials it needs and makes a follow-up // request. func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { if t.Transport == nil { return nil, ErrNilTransport } // Hold on to the request body; a reader cannot be un-read. b, err := ioutil.ReadAll(req.Body) if err != nil { return nil, err } // Copy the request so we don't modify the input. req2 := new(http.Request) *req2 = *req // Copying drains the request body. Set to body we saved above. req.Body = ioutil.NopCloser(bytes.NewReader(b)) req2.Body = ioutil.NopCloser(bytes.NewReader(b)) req2.Header = make(http.Header) for k, s := range req.Header { req2.Header[k] = s } // Make a request to get the 401 that contains the challenge. resp, err := t.Transport.RoundTrip(req) if err != nil || resp.StatusCode != 401 { return resp, err } // Read the response body, to enable the connection to be reused. _, err = io.Copy(ioutil.Discard, resp.Body) if err != nil { return nil, err } defer resp.Body.Close() chal := resp.Header.Get("WWW-Authenticate") c, err := parseChallenge(chal) if err != nil { return resp, err } // Form credentials based on the challenge. cr := t.newCredentials(req2, c) auth, err := cr.authorize() if err != nil { return resp, err } // Make authenticated request. req2.Header.Set("Authorization", auth) return t.Transport.RoundTrip(req2) }
// DumpRequestOut is like DumpRequest but includes // headers that the standard http.Transport adds, // such as User-Agent. func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { save := req.Body if !body || req.Body == nil { req.Body = nil } else { var err error save, req.Body, err = drainBody(req.Body) if err != nil { return nil, err } } // Since we're using the actual Transport code to write the request, // switch to http so the Transport doesn't try to do an SSL // negotiation with our dumpConn and its bytes.Buffer & pipe. // The wire format for https and http are the same, anyway. reqSend := req if req.URL.Scheme == "https" { reqSend = new(http.Request) *reqSend = *req reqSend.URL = new(url.URL) *reqSend.URL = *req.URL reqSend.URL.Scheme = "http" } // Use the actual Transport code to record what we would send // on the wire, but not using TCP. Use a Transport with a // customer dialer that returns a fake net.Conn that waits // for the full input (and recording it), and then responds // with a dummy response. var buf bytes.Buffer // records the output pr, pw := io.Pipe() dr := &delegateReader{c: make(chan io.Reader)} // Wait for the request before replying with a dummy response: go func() { http.ReadRequest(bufio.NewReader(pr)) dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n") }() t := &http.Transport{ Dial: func(net, addr string) (net.Conn, error) { return &dumpConn{io.MultiWriter(pw, &buf), dr}, nil }, } _, err := t.RoundTrip(reqSend) req.Body = save if err != nil { return nil, err } return buf.Bytes(), nil }
func CopyRequest(req *http.Request) *http.Request { outreq := new(http.Request) *outreq = *req // includes shallow copies of maps, but okay outreq.Proto = "HTTP/1.1" outreq.ProtoMajor = 1 outreq.ProtoMinor = 1 outreq.Close = false // Remove hop-by-hop headers to the backend. Especially // important is "Connection" because we want a persistent // connection, regardless of what the client sent to us. This // is modifying the same underlying map from req (shallow // copied above) so we only copy it if necessary. copiedHeaders := false for _, h := range hopHeaders { if outreq.Header.Get(h) != "" { if !copiedHeaders { outreq.Header = make(http.Header) copyHeader(outreq.Header, req.Header) copiedHeaders = true } outreq.Header.Del(h) } } if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { // If we aren't the first proxy retain prior // X-Forwarded-For information as a comma+space // separated list and fold multiple headers into one. if prior, ok := outreq.Header["X-Forwarded-For"]; ok { clientIP = strings.Join(prior, ", ") + ", " + clientIP } outreq.Header.Set("X-Forwarded-For", clientIP) } // If the request body is not chunked, tee it into the // proxy request's body & and replace it with a buffered // copy of the request body (it will be fully read by // the proxy request). if !isChunked(req) { bodyBuffer := bytes.NewBuffer(make([]byte, 0, req.ContentLength)) bodyReader := io.TeeReader(req.Body, bodyBuffer) outreq.Body = ioutil.NopCloser(bodyReader) req.Body = ioutil.NopCloser(bodyBuffer) } else { outreq.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) } return outreq }
// ReadRequest reads an HTTP request. The header is taken from h, // which must include the SPDY-specific fields starting with ':'. // If r is not nil, the body will be read from r. If t is not nil, // the trailer will be taken from t after the body is finished. func ReadRequest(h, t http.Header, r io.Reader) (*http.Request, error) { req := new(http.Request) req.Header = make(http.Header) copyHeader(req.Header, h) path := h.Get(":path") if path == "" { return nil, errors.New("missing path") } if path[0] != '/' { return nil, errors.New("invalid path: " + path) } req.URL = &url.URL{ Scheme: h.Get(":scheme"), Path: path, Host: h.Get(":host"), } req.Close = true req.Method = h.Get(":method") req.Host = h.Get(":host") req.Proto = h.Get(":version") var ok bool if req.ProtoMajor, req.ProtoMinor, ok = http.ParseHTTPVersion(req.Proto); !ok { return nil, errors.New("bad http version: " + req.Proto) } req.Header.Del("Host") cl := strings.TrimSpace(req.Header.Get("Content-Length")) if cl != "" { n, err := parseContentLength(cl) if err != nil { return nil, err } req.ContentLength = n } else { // Assume GET request has no body by default. if req.Method != "GET" { req.ContentLength = -1 } req.Header.Del("Content-Length") } // TODO(kr): content length / limit reader? if r == nil { r = eofReader } if t != nil { req.Body = &body{r: r, hdr: req, trailer: t} } else { req.Body = &body{r: r} } return req, nil }
//把request转换成[]byte,并且使body可以被再次读取 func MustRequestToStringCanRead(req *http.Request) (s string) { oldBody := req.Body defer oldBody.Close() body, err := ioutil.ReadAll(req.Body) if err != nil { panic(err) } req.Body = ioutil.NopCloser(bytes.NewReader(body)) buf := &bytes.Buffer{} req.Write(buf) req.Body = ioutil.NopCloser(bytes.NewReader(body)) return string(buf.Bytes()) }
// readRequest is like Read, but for HTTP request. Upon return, the body is // replaced wit a buffer and can be read again. func (srv *Server) readRequest(req *http.Request) ([]byte, error) { p, err := srv.read(req.Body, req.ContentLength) req.Body.Close() switch e := srv.uninstrument(err); { case e == io.EOF || e == io.ErrUnexpectedEOF || len(p) == 0: req.Body = ioutil.NopCloser(eofReader{}) return nil, io.EOF case err != nil: return nil, err case len(p) != 0: req.Body = ioutil.NopCloser(bytes.NewReader(p)) } return p, nil }
// RoundTrip makes a request expecting a 401 response that will require digest // authentication. It creates the credentials it needs and makes a follow-up // request. func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { if t.Transport == nil { return nil, ErrNilTransport } // Copy the request so we don't modify the input. req2 := new(http.Request) *req2 = *req req2.Header = make(http.Header) for k, s := range req.Header { req2.Header[k] = s } // copy buf to resend it if req.Body != nil { buf, _ := ioutil.ReadAll(req.Body) req.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) req2.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) } // Make a request to get the 401 that contains the challenge. resp, err := t.Transport.RoundTrip(req) if err != nil || resp.StatusCode != 401 { return resp, err } chal := resp.Header.Get("WWW-Authenticate") c, err := parseChallenge(chal) if err != nil { return resp, err } // Form credentials based on the challenge. cr := t.newCredentials(req2, c) auth, err := cr.authorize() if err != nil { return resp, err } // close response body to avoid goroutines leak if resp.Body != nil { resp.Body.Close() } // not sure about request body, but close it as well if req.Body != nil { req.Body.Close() } // Make authenticated request. req2.Header.Set("Authorization", auth) return t.Transport.RoundTrip(req2) }
func (u *URL) Request(out interface{}, req *http.Request) error { var bodyBytes []byte var err error if req.Body != nil { bodyBytes, err = ioutil.ReadAll(req.Body) if err != nil { return err } req.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes)) if err != nil { return err } } r, err := makeRequest(req) if err != nil { return err } defer r.Body.Close() if r.StatusCode == 401 { if req.Body != nil { req.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes)) } r, err = promptAndAuth(r, req) if err != nil { return err } } var final error = nil if r.StatusCode != 200 { final = fmt.Errorf("Error %s", r.Status) } if out != nil { body, err := ioutil.ReadAll(r.Body) if err != nil { return err } err = json.Unmarshal(body, out) if err != nil && final == nil { return err } } return final }
func main() { if 3 <= len(os.Args) && len(os.Args) <= 5 { method := os.Args[1] ackordurl, _ := url.Parse(os.Args[2]) request := new(http.Request) if len(os.Args) == 3 && method == "GET" { } else if len(os.Args) == 3 && method == "DELETE" { } else if len(os.Args) == 4 && method == "PUT" { request.Header = make(http.Header) request.Header.Add("Content-Type", "application/x-www-form-urlencoded") myBody := bytes.NewBufferString(fmt.Sprintf("value=%s", os.Args[3])) request.Body = ioutil.NopCloser(myBody) request.ContentLength = int64(myBody.Len()) } else if len(os.Args) == 5 && method == "POST" { request.Header = make(http.Header) request.Header.Add("Content-Type", "application/x-www-form-urlencoded") myBody := bytes.NewBufferString(fmt.Sprintf("key=%s&value=%s", os.Args[3], os.Args[4])) request.Body = ioutil.NopCloser(myBody) request.ContentLength = int64(myBody.Len()) } else { fmt.Println("wrong method") return } client := new(http.Client) request.Method = method request.URL = ackordurl bb, _ := httputil.DumpRequest(request, true) fmt.Println("Request: " + string(bb[:])) response, err := client.Do(request) if err != nil { fmt.Println(err.Error()) return } rb, _ := httputil.DumpResponse(response, true) fmt.Println("Response body: " + string(rb[:])) } else { fmt.Println("rester POST http://localhost:12080/storage/ MyText \"Some text here.\"") fmt.Println("rester GET http://localhost:12080/storage/MyText") fmt.Println("rester PUT http://localhost:12080/storage/MyText \"Some other text.\"") fmt.Println("rester DELETE http://localhost:12080/storage/MyText") } }
// Prepares an *http.Request for doHttpRequest func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) { u, err := req.url() if err != nil { return nil, err } u.Opaque = fmt.Sprintf("//%s%s", u.Host, partiallyEscapedPath(u.Path)) hreq := http.Request{ URL: u, Method: req.method, ProtoMajor: 1, ProtoMinor: 1, Close: true, Header: req.headers, } if v, ok := req.headers["Content-Length"]; ok { hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64) delete(req.headers, "Content-Length") } if req.payload != nil { hreq.Body = ioutil.NopCloser(req.payload) } return &hreq, nil }
// signatureBase combines the uppercase request method, percent encoded base // string URI, and parameter string. Returns the OAuth1 signature base string // according to RFC5849 3.4.1. // Does not mutate the Request or basicOAuthParams. func signatureBase(req *http.Request, basicOAuthParams map[string]string) (string, error) { method := strings.ToUpper(req.Method) baseURL := strings.Split(req.URL.String(), "?")[0] // add oauth, query, and body parameters into params params := map[string]string{} for key, value := range req.URL.Query() { // most backends do not accept duplicate query keys params[key] = value[0] } if req.Body != nil && req.Header.Get(contentType) == formContentType { // reads data to a []byte, draining req.Body b, err := ioutil.ReadAll(req.Body) if err != nil { return "", err } values, err := url.ParseQuery(string(b)) if err != nil { return "", err } for key, value := range values { params[key] = value[0] } // reinitialize Body with ReadCloser over the []byte req.Body = ioutil.NopCloser(bytes.NewReader(b)) } for key, value := range basicOAuthParams { params[key] = value } // encode params into a parameter string (RFC5849 3.4.1.3, 3.4.1.3.2) parameterString := encodeParams(params) baseParts := []string{method, PercentEncode(baseURL), PercentEncode(parameterString)} return strings.Join(baseParts, "&"), nil }
// Prepares an *http.Request for doHttpRequest func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) { // Copy so that signing the http request will not mutate it headers := make(http.Header) for k, v := range req.headers { headers[k] = v } req.headers = headers u, err := req.url() if err != nil { return nil, err } u.Opaque = fmt.Sprintf("//%s%s", u.Host, partiallyEscapedPath(u.Path)) hreq := http.Request{ URL: u, Method: req.method, ProtoMajor: 1, ProtoMinor: 1, Close: true, Header: req.headers, Form: req.params, } if v, ok := req.headers["Content-Length"]; ok { hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64) delete(req.headers, "Content-Length") } if req.payload != nil { hreq.Body = ioutil.NopCloser(req.payload) } return &hreq, nil }
// ServeHTTP wraps the http.Request and http.ResponseWriter to log to standard // output and pass through to the underlying http.Handler. func (l *Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) { requestID := l.RequestIDCreator(r) l.Printf( "%s > %s %s %s\n", requestID, r.Method, r.URL.RequestURI(), r.Proto, ) for key, values := range r.Header { for _, value := range values { l.Printf("%s > %s: %s\n", requestID, key, value) } } l.Println(requestID, ">") r.Body = &readCloser{ ReadCloser: r.Body, Logger: l, requestID: requestID, } l.handler.ServeHTTP(&loggerResponseWriter{ ResponseWriter: w, Logger: l, request: r, requestID: requestID, }, r) }
func (rt *BackendRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { var err error var res *http.Response var endpoint *route.Endpoint if request.Body != nil { closer := request.Body request.Body = ioutil.NopCloser(request.Body) defer func() { closer.Close() }() } for retry := 0; retry < handler.MaxRetries; retry++ { endpoint, err = rt.selectEndpoint(request) if err != nil { return nil, err } rt.setupRequest(request, endpoint) res, err = rt.transport.RoundTrip(request) if err == nil || !retryableError(err) { break } rt.reportError(err) } if rt.after != nil { rt.after(res, endpoint, err) } return res, err }
// Prepares an *http.Request for doHttpRequest func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) { u, err := req.url() if err != nil { return nil, err } hreq := http.Request{ URL: u, Host: "s3.amazonaws.com", Method: req.method, ProtoMajor: 1, ProtoMinor: 1, Close: true, Header: req.headers, } if v, ok := req.headers["Content-Length"]; ok { hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64) delete(req.headers, "Content-Length") } if req.payload != nil { hreq.Body = ioutil.NopCloser(req.payload) } return &hreq, nil }
// NewMessage returns a new Message given a HTTP request, and an array of // custom headers used in the HMAC signature generation. func NewMessage(r *http.Request, headers ...[]string) *Message { h := NewHeaders() if len(headers) > 0 { for _, header := range headers[0] { h.Set(header, r.Header.Get(header)) } } var body []byte = []byte{} if r.Body != nil { var err error body, err = ioutil.ReadAll(r.Body) if err != nil { return nil } r.Body.Close() copy := body[:] r.Body = ioutil.NopCloser(bytes.NewReader(copy)) } return &Message{ r.Method, HashData(body), r.Header.Get("Content-Type"), r.Header.Get("Date"), h, r.URL, true, } }
func NewRequestDetailsFromHttpRequest(req *http.Request) (RequestDetails, error) { if req.Body == nil { req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(""))) } reqBody, err := extractRequestBody(req) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "mode": "capture", }).Error("Got error while reading request body") return RequestDetails{}, err } requestDetails := RequestDetails{ Path: req.URL.Path, Method: req.Method, Destination: req.Host, Scheme: req.URL.Scheme, Query: req.URL.RawQuery, Body: string(reqBody), Headers: req.Header, } return requestDetails, nil }
func authzViaPOST(r *http.Request, tok string) int { r.Method = "POST" r.Header.Add("Content-Type", "application/x-www-form-urlencoded") r.Body = ioutil.NopCloser(strings.NewReader( url.Values{"api_token": {tok}}.Encode())) return http.StatusUnauthorized }
func runHandler(resp http.ResponseWriter, req *http.Request, fn func(resp http.ResponseWriter, req *http.Request) error, errfn httputil.Error) { defer func() { if rv := recover(); rv != nil { err := errors.New("handler panic") logError(req, err, rv) errfn(resp, req, http.StatusInternalServerError, err) } }() if s := req.Header.Get("X-Real-Ip"); s != "" && httputil.StripPort(req.RemoteAddr) == "127.0.0.1" { req.RemoteAddr = s } req.Body = http.MaxBytesReader(resp, req.Body, 2048) req.ParseForm() var rb httputil.ResponseBuffer err := fn(&rb, req) if err == nil { rb.WriteTo(resp) } else if e, ok := err.(*httpError); ok { if e.status >= 500 { logError(req, err, nil) } errfn(resp, req, e.status, e.err) } else { logError(req, err, nil) errfn(resp, req, http.StatusInternalServerError, err) } }
// also from goiardi calc and encodebody data func calcBodyHash(r *http.Request) (string, error) { var bodyStr string var err error if r.Body == nil { bodyStr = "" } else { save := r.Body save, r.Body, err = drainBody(r.Body) if err != nil { return "", err } mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) if err != nil { return "", err } if strings.HasPrefix(mediaType, "multipart/form-data") { bodyStr, err = readFileFromRequest(r, params["boundary"]) if err != nil { return "", err } } else { buf := new(bytes.Buffer) buf.ReadFrom(r.Body) bodyStr = buf.String() } r.Body = save } chkHash := hashStr(bodyStr) return chkHash, err }