Make Request.Host optional
This commit is contained in:
parent
41eec39a1d
commit
46e10da3a8
36
client.go
36
client.go
@ -59,10 +59,20 @@ func (c *Client) Get(url string) (*Response, error) {
|
|||||||
//
|
//
|
||||||
// Generally Get will be used instead of Do.
|
// Generally Get will be used instead of Do.
|
||||||
func (c *Client) Do(req *Request) (*Response, error) {
|
func (c *Client) Do(req *Request) (*Response, error) {
|
||||||
// Punycode request URL
|
// Punycode request URL host
|
||||||
if punycode, err := punycodeHost(req.URL.Host); err != nil {
|
hostname, port, err := net.SplitHostPort(req.URL.Host)
|
||||||
|
if err != nil {
|
||||||
|
// Likely no port
|
||||||
|
hostname = req.URL.Host
|
||||||
|
port = "1965"
|
||||||
|
}
|
||||||
|
punycode, err := punycodeHostname(hostname)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
}
|
||||||
|
if hostname != punycode {
|
||||||
|
hostname = punycode
|
||||||
|
|
||||||
// Make a copy of the request
|
// Make a copy of the request
|
||||||
_req := *req
|
_req := *req
|
||||||
req = &_req
|
req = &_req
|
||||||
@ -70,17 +80,21 @@ func (c *Client) Do(req *Request) (*Response, error) {
|
|||||||
req.URL = &_url
|
req.URL = &_url
|
||||||
|
|
||||||
// Set the host
|
// Set the host
|
||||||
req.URL.Host = punycode
|
req.URL.Host = net.JoinHostPort(hostname, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract hostname and punycode it
|
// Use request host if provided
|
||||||
hostname, port, err := net.SplitHostPort(req.Host)
|
if req.Host != "" {
|
||||||
|
hostname, port, err = net.SplitHostPort(req.Host)
|
||||||
|
if err != nil {
|
||||||
|
// Port is required
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Punycode hostname
|
||||||
|
hostname, err = punycodeHostname(hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
punycode, err := punycodeHostname(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to the host
|
// Connect to the host
|
||||||
@ -96,7 +110,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
|
|||||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||||
return c.verifyConnection(hostname, punycode, cs)
|
return c.verifyConnection(hostname, punycode, cs)
|
||||||
},
|
},
|
||||||
ServerName: punycode,
|
ServerName: hostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := req.Context
|
ctx := req.Context
|
||||||
@ -109,7 +123,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
|
|||||||
Timeout: c.Timeout,
|
Timeout: c.Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
address := net.JoinHostPort(punycode, port)
|
address := net.JoinHostPort(hostname, port)
|
||||||
netConn, err := dialer.DialContext(ctx, "tcp", address)
|
netConn, err := dialer.DialContext(ctx, "tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
18
punycode.go
18
punycode.go
@ -26,21 +26,3 @@ func punycodeHostname(hostname string) (string, error) {
|
|||||||
}
|
}
|
||||||
return idna.Lookup.ToASCII(hostname)
|
return idna.Lookup.ToASCII(hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
// punycodeHost returns the punycoded version of host.
|
|
||||||
// host may contain a port.
|
|
||||||
func punycodeHost(host string) (string, error) {
|
|
||||||
hostname, port, err := net.SplitHostPort(host)
|
|
||||||
if err != nil {
|
|
||||||
hostname = host
|
|
||||||
port = ""
|
|
||||||
}
|
|
||||||
hostname, err = punycodeHostname(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if port == "" {
|
|
||||||
return hostname, nil
|
|
||||||
}
|
|
||||||
return net.JoinHostPort(hostname, port), nil
|
|
||||||
}
|
|
||||||
|
16
request.go
16
request.go
@ -18,8 +18,12 @@ type Request struct {
|
|||||||
// requests) or the URL to access (for client requests).
|
// requests) or the URL to access (for client requests).
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
|
|
||||||
// For client requests, Host specifies the server to connect to.
|
// For client requests, Host optionally specifies the server to
|
||||||
// Host must contain a port.
|
// connect to. It must be of the form "host:port".
|
||||||
|
// If empty, the value of URL.Host is used.
|
||||||
|
// For international domain names, Host may be in Punycode or
|
||||||
|
// Unicode form. Use golang.org/x/net/idna to convert it to
|
||||||
|
// either format if needed.
|
||||||
// This field is ignored by the Gemini server.
|
// This field is ignored by the Gemini server.
|
||||||
Host string
|
Host string
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ type Request struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRequest returns a new request. The host is inferred from the URL.
|
// NewRequest returns a new request.
|
||||||
//
|
//
|
||||||
// The returned Request is suitable for use with Client.Do.
|
// The returned Request is suitable for use with Client.Do.
|
||||||
func NewRequest(rawurl string) (*Request, error) {
|
func NewRequest(rawurl string) (*Request, error) {
|
||||||
@ -67,18 +71,12 @@ func NewRequest(rawurl string) (*Request, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRequestFromURL returns a new request for the given URL.
|
// NewRequestFromURL returns a new request for the given URL.
|
||||||
// The host is inferred from the URL.
|
|
||||||
//
|
//
|
||||||
// Callers should be careful that the URL query is properly escaped.
|
// Callers should be careful that the URL query is properly escaped.
|
||||||
// See the documentation for QueryEscape for more information.
|
// See the documentation for QueryEscape for more information.
|
||||||
func NewRequestFromURL(url *url.URL) *Request {
|
func NewRequestFromURL(url *url.URL) *Request {
|
||||||
host := url.Host
|
|
||||||
if url.Port() == "" {
|
|
||||||
host += ":1965"
|
|
||||||
}
|
|
||||||
return &Request{
|
return &Request{
|
||||||
URL: url,
|
URL: url,
|
||||||
Host: host,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user