Fetch the repository succeeded.
// Copyright 2014 hey Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package work
import (
"bytes"
"crypto/tls"
"golang.org/x/net/http2"
"io/ioutil"
"net/http"
"net/http/httptrace"
"net/url"
"time"
)
const heyUA = "hey/0.0.1"
type Result struct {
Err error
StatusCode int
Duration time.Duration
ConnDuration time.Duration // connection setup(DNS lookup + Dial up) duration
DnsDuration time.Duration // dns lookup duration
ReqDuration time.Duration // request "write" duration
ResDuration time.Duration // response "read" duration
DelayDuration time.Duration // delay between response and request
ContentLength int64
Body []byte
}
type HttpWork struct {
// H2 is an option to make HTTP/2 requests
H2 bool
// Timeout in seconds.
Timeout int
// DisableCompression is an option to disable compression in response
DisableCompression bool
// DisableKeepAlives is an option to prevents re-use of TCP connections between different HTTP requests
DisableKeepAlives bool
// DisableRedirects is an option to prevent the following of HTTP redirects
DisableRedirects bool
// ProxyAddr is the address of HTTP proxy server in the format on "host:port".
// Optional.
ProxyAddr *url.URL
client *http.Client
}
func (this *HttpWork) GetClient() *http.Client {
if this.client != nil {
return this.client
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
DisableCompression: this.DisableCompression,
DisableKeepAlives: this.DisableKeepAlives,
Proxy: http.ProxyURL(this.ProxyAddr),
}
if this.H2 {
http2.ConfigureTransport(tr)
} else {
tr.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper)
}
client := &http.Client{Transport: tr, Timeout: time.Duration(this.Timeout) * time.Second}
if this.DisableRedirects {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
}
this.client = client
return client
}
func (this *HttpWork) MakeRequest(client *http.Client, req *http.Request) *Result {
s := time.Now()
var dnsStart, connStart, resStart, reqStart, delayStart time.Time
var dnsDuration, connDuration, resDuration, reqDuration, delayDuration time.Duration
trace := &httptrace.ClientTrace{
DNSStart: func(info httptrace.DNSStartInfo) {
dnsStart = time.Now()
},
DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
dnsDuration = time.Now().Sub(dnsStart)
},
GetConn: func(h string) {
connStart = time.Now()
},
GotConn: func(connInfo httptrace.GotConnInfo) {
connDuration = time.Now().Sub(connStart)
reqStart = time.Now()
},
WroteRequest: func(w httptrace.WroteRequestInfo) {
reqDuration = time.Now().Sub(reqStart)
delayStart = time.Now()
},
GotFirstResponseByte: func() {
delayDuration = time.Now().Sub(delayStart)
resStart = time.Now()
},
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
resp, err := client.Do(req)
result := &Result{
Err: err,
ConnDuration: connDuration,
DnsDuration: dnsDuration,
ReqDuration: reqDuration,
ResDuration: resDuration,
DelayDuration: delayDuration,
}
if err == nil {
result.ContentLength = resp.ContentLength
result.StatusCode = resp.StatusCode
//io.Copy(ioutil.Discard, resp.Body)
result.Body,err=ioutil.ReadAll(resp.Body)
resp.Body.Close()
}else{
result.Err = err
}
t := time.Now()
result.ResDuration = t.Sub(resStart)
result.Duration = t.Sub(s)
return result
}
// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
func (this *HttpWork) CloneRequest(r *http.Request, body []byte) *http.Request {
// shallow copy of the struct
r2 := new(http.Request)
*r2 = *r
// deep copy of the Header
r2.Header = make(http.Header, len(r.Header))
for k, s := range r.Header {
r2.Header[k] = append([]string(nil), s...)
}
if len(body) > 0 {
r2.Body = ioutil.NopCloser(bytes.NewReader(body))
}
return r2
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。