根據此檔案,我們可以http.Client通過httptrace這種方式進行跟蹤
t := &transport{}
req, _ := http.NewRequest("GET", "https://google.com", nil)
trace := &httptrace.ClientTrace{
GotConn: t.GotConn,
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
client := &http.Client{Transport: t}
對于谷歌 API 客戶端,這里是一個包裝器代碼
func NewWithClient(jsonKey []byte, cli *http.Client) (*Client, error) {
if cli == nil {
return nil, fmt.Errorf("client is nil")
}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cli)
conf, err := google.JWTConfigFromJSON(jsonKey, androidpublisher.AndroidpublisherScope)
if err != nil {
return nil, err
}
service, err := androidpublisher.NewService(ctx, option.WithHTTPClient(conf.Client(ctx)))
if err != nil {
return nil, err
}
return &Client{service}, err
}
我們想應用到做 HTTP 跟蹤httptrace的http.Client引數NewWithClient。
我們嘗試過的
type TraceTransport struct {
}
var traceTransport = &TraceTransport{}
var trace = &httptrace.ClientTrace{
GotConn: traceTransport.GotConn,
}
func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return http.DefaultTransport.RoundTrip(req)
}
func (t *TraceTransport) GotConn(info httptrace.GotConnInfo) {
fmt.Printf("Connection reused for %v \n", info.Reused)
}
type ClientWrapper struct {
defaultClient *http.Client
}
var clientWrapperTrace = &httptrace.ClientTrace{GotConn: traceTransport.GotConn}
func (c *ClientWrapper) Do(req *http.Request) (*http.Response, error) {
req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientWrapperTrace))
return c.defaultClient.Do(req)
}
func NewClientTrace(jsonKey []byte) (*Client, error) {
cli := &http.Client{
Transport: traceTransport,
Timeout: time.Duration(10) * time.Second,
}
cliWrapper := &ClientWrapper{defaultClient: cli}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cliWrapper)
conf, err := google.JWTConfigFromJSON(jsonKey, androidpublisher.AndroidpublisherScope)
if err != nil {
return nil, err
}
service, err := androidpublisher.NewService(ctx, option.WithHTTPClient(conf.Client(ctx)))
if err != nil {
return nil, err
}
return &Client{service}, err
}
type Client struct {
service *androidpublisher.Service
}
func (c *Client) VerifyProduct(
ctx context.Context,
packageName string,
productID string,
token string,
) (*androidpublisher.ProductPurchase, error) {
ps := androidpublisher.NewPurchasesProductsService(c.service)
result, err := ps.Get(packageName, productID, token).Context(ctx).Do()
return result, err
}
// test codes
c, err := NewClientTrace([]byte(privateKey))
if err != nil {
return
}
packageName := "package.name"
productID := "product_id"
token := "xxxxx"
r, err := c.VerifyProduct(context.Background(), packageName, productID, token)
但是,跟蹤失敗http.Client,沒有輸出GotConn。有人可以幫助我們找出上述代碼的問題嗎?
uj5u.com熱心網友回復:
來自
google/oauth2的請求無法由 追蹤httptrace。您ClientWrapper傳遞的 withcontext.WithValue將在此處被忽略,并且 oauth2 有它自己的 http.Client,它只是使用from context.Value的Transport方法*http.Client。來自 androidpublisher 的請求可以通過 httptrace 跟蹤,如下所示:
ctx := httptrace.WithClientTrace(context.Background(), clientWrapperTrace)
r, err := c.VerifyProduct(ctx, packageName, productID, token)
- 如果您只想計算請求數,我認為覆寫
http.Client.Transport是一種簡單的方法。
type TraceTransport struct {
}
func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
fmt.Printf("RoundTrip hook %v\n", req.URL)
return http.DefaultTransport.RoundTrip(req)
}
func NewClientTrace(jsonKey []byte) (*Client, error) {
cli := &http.Client{Transport: &TraceTransport{}}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cli)
// ...
service, err := androidpublisher.NewService(ctx, option.WithHTTPClient(conf.Client(ctx)))
// ....
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/341218.html
上一篇:Spring-boot重定向:/到http而不是https
下一篇:NVDA不讀取v-html標簽
