github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/pkg/httptracer/httptracer.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 // Package httptracer implements http tracing functionality 19 package httptracer 20 21 import ( 22 "errors" 23 "net/http" 24 "time" 25 26 "github.com/minio/pkg/v2/console" 27 ) 28 29 // HTTPTracer provides callback hook mechanism for HTTP transport. 30 type HTTPTracer interface { 31 Request(req *http.Request) error 32 Response(res *http.Response) error 33 } 34 35 // RoundTripTrace interposes HTTP transport requests and respsonses using HTTPTracer hooks 36 type RoundTripTrace struct { 37 Trace HTTPTracer // User provides callback methods 38 Transport http.RoundTripper // HTTP transport that needs to be intercepted 39 } 40 41 // RoundTrip executes user provided request and response hooks for each HTTP call. 42 func (t RoundTripTrace) RoundTrip(req *http.Request) (res *http.Response, err error) { 43 timeStamp := time.Now() 44 45 if t.Transport == nil { 46 return nil, errors.New("Invalid Argument") 47 } 48 49 res, err = t.Transport.RoundTrip(req) 50 if err != nil { 51 return res, err 52 } 53 54 if t.Trace != nil { 55 err = t.Trace.Request(req) 56 if err != nil { 57 return nil, err 58 } 59 60 err = t.Trace.Response(res) 61 if err != nil { 62 return nil, err 63 } 64 console.Debugln("Response Time: ", time.Since(timeStamp).String()+"\n") 65 } 66 return res, err 67 } 68 69 // GetNewTraceTransport returns a traceable transport 70 // 71 // Takes first argument a custom tracer which implements Response, Request() conforming to HTTPTracer interface. 72 // Another argument can be a default transport or a custom http.RoundTripper implementation 73 func GetNewTraceTransport(trace HTTPTracer, transport http.RoundTripper) RoundTripTrace { 74 return RoundTripTrace{ 75 Trace: trace, 76 Transport: transport, 77 } 78 }