@@ -8,8 +8,10 @@ import (
8
8
"net"
9
9
"net/http"
10
10
"net/url"
11
- "strings"
12
11
"time"
12
+
13
+ "github.com/quic-go/quic-go"
14
+ "github.com/quic-go/quic-go/http3"
13
15
)
14
16
15
17
type HttpPingResult struct {
@@ -48,6 +50,7 @@ type HttpPing struct {
48
50
Insecure bool
49
51
Referrer string
50
52
UserAgent string
53
+ Http3 bool
51
54
IP net.IP
52
55
}
53
56
@@ -60,7 +63,9 @@ func (this *HttpPing) PingContext(ctx context.Context) IPingResult {
60
63
if err != nil {
61
64
return this .errorResult (err )
62
65
}
66
+ orighost := u .Host
63
67
host := u .Hostname ()
68
+ port := u .Port ()
64
69
ip := cloneIP (this .IP )
65
70
if ip == nil {
66
71
var err error
@@ -69,51 +74,53 @@ func (this *HttpPing) PingContext(ctx context.Context) IPingResult {
69
74
return this .errorResult (err )
70
75
}
71
76
}
72
-
73
- dialer := & net.Dialer {
74
- Timeout : this . Timeout ,
75
- KeepAlive : - 1 ,
77
+ if port != "" {
78
+ u . Host = net .JoinHostPort ( ip . String (), port )
79
+ } else {
80
+ u . Host = ip . String ()
76
81
}
77
-
78
- dialfunc := func (ctx context.Context , network , address string ) (net.Conn , error ) {
79
- h , p , err := net .SplitHostPort (address )
80
- if err != nil {
81
- return nil , err
82
+ url2 := u .String ()
83
+
84
+ var transport http.RoundTripper
85
+ if this .Http3 {
86
+ transport = & http3.RoundTripper {
87
+ DisableCompression : this .DisableCompression ,
88
+ QuicConfig : & quic.Config {
89
+ KeepAlivePeriod : 0 ,
90
+ },
91
+ TLSClientConfig : & tls.Config {
92
+ InsecureSkipVerify : this .Insecure ,
93
+ ServerName : host ,
94
+ },
82
95
}
83
- if ip == nil || ! strings .EqualFold (h , host ) {
84
- var err error
85
- ip , err = LookupFunc (h )
86
- if err != nil {
87
- return nil , err
88
- }
96
+ } else {
97
+ trans := http .DefaultTransport .(* http.Transport ).Clone ()
98
+ trans .DisableKeepAlives = true
99
+ trans .MaxIdleConnsPerHost = - 1
100
+ trans .DisableCompression = this .DisableCompression
101
+ trans .ForceAttemptHTTP2 = ! this .DisableHttp2
102
+ trans .TLSClientConfig = & tls.Config {
103
+ InsecureSkipVerify : this .Insecure ,
104
+ ServerName : host ,
89
105
}
90
- addr := net .JoinHostPort (ip .String (), p )
91
- return dialer .DialContext (ctx , network , addr )
92
- }
93
-
94
- trans := http .DefaultTransport .(* http.Transport ).Clone ()
95
- trans .DialContext = dialfunc
96
- trans .DisableKeepAlives = true
97
- trans .MaxIdleConnsPerHost = - 1
98
- trans .DisableCompression = this .DisableCompression
99
- trans .ForceAttemptHTTP2 = ! this .DisableHttp2
100
- trans .TLSClientConfig = & tls.Config {
101
- InsecureSkipVerify : this .Insecure ,
106
+ transport = trans
102
107
}
103
108
104
- req , err := http .NewRequestWithContext (ctx , this .Method , this . URL , nil )
109
+ req , err := http .NewRequestWithContext (ctx , this .Method , url2 , nil )
105
110
if err != nil {
106
111
return this .errorResult (err )
107
112
}
108
- if this .UserAgent == "" {
109
- this .UserAgent = "httping"
113
+ ua := "httping"
114
+ if this .UserAgent != "" {
115
+ ua = this .UserAgent
110
116
}
111
- req .Header .Set ("User-Agent" , this . UserAgent )
117
+ req .Header .Set ("User-Agent" , ua )
112
118
if this .Referrer != "" {
113
119
req .Header .Set ("Referer" , this .Referrer )
114
120
}
121
+ req .Host = orighost
115
122
client := & http.Client {}
116
- client .Transport = trans
123
+ client .Transport = transport
117
124
client .Timeout = this .Timeout
118
125
client .CheckRedirect = func (req * http.Request , via []* http.Request ) error {
119
126
return http .ErrUseLastResponse
0 commit comments