diff options
| author | Adnan Maolood <[email protected]> | 2021-02-14 19:02:34 -0500 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2021-02-14 19:02:34 -0500 |
| commit | 46e10da3a844bd72485772242a28fa4d88ee8b58 (patch) | |
| tree | 7c4aa0edba5f5aa2ae7fe06b37f84f6c079b98c9 | |
| parent | Update examples/client.go (diff) | |
| download | go-gemini-46e10da3a844bd72485772242a28fa4d88ee8b58.tar.xz go-gemini-46e10da3a844bd72485772242a28fa4d88ee8b58.zip | |
Make Request.Host optional
| -rw-r--r-- | client.go | 42 | ||||
| -rw-r--r-- | punycode.go | 18 | ||||
| -rw-r--r-- | request.go | 18 |
3 files changed, 36 insertions, 42 deletions
@@ -59,10 +59,20 @@ func (c *Client) Get(url string) (*Response, error) { // // Generally Get will be used instead of Do. func (c *Client) Do(req *Request) (*Response, error) { - // Punycode request URL - if punycode, err := punycodeHost(req.URL.Host); err != nil { + // Punycode request URL host + 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 - } else { + } + if hostname != punycode { + hostname = punycode + // Make a copy of the request _req := *req req = &_req @@ -70,17 +80,21 @@ func (c *Client) Do(req *Request) (*Response, error) { req.URL = &_url // Set the host - req.URL.Host = punycode + req.URL.Host = net.JoinHostPort(hostname, port) } - // Extract hostname and punycode it - hostname, port, err := net.SplitHostPort(req.Host) - if err != nil { - return nil, err - } - punycode, err := punycodeHostname(hostname) - if err != nil { - return nil, err + // Use request host if provided + 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 { + return nil, err + } } // Connect to the host @@ -96,7 +110,7 @@ func (c *Client) Do(req *Request) (*Response, error) { VerifyConnection: func(cs tls.ConnectionState) error { return c.verifyConnection(hostname, punycode, cs) }, - ServerName: punycode, + ServerName: hostname, } ctx := req.Context @@ -109,7 +123,7 @@ func (c *Client) Do(req *Request) (*Response, error) { Timeout: c.Timeout, } - address := net.JoinHostPort(punycode, port) + address := net.JoinHostPort(hostname, port) netConn, err := dialer.DialContext(ctx, "tcp", address) if err != nil { return nil, err diff --git a/punycode.go b/punycode.go index cf0ecb4..58f84e5 100644 --- a/punycode.go +++ b/punycode.go @@ -26,21 +26,3 @@ func punycodeHostname(hostname string) (string, error) { } 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 -} @@ -18,8 +18,12 @@ type Request struct { // requests) or the URL to access (for client requests). URL *url.URL - // For client requests, Host specifies the server to connect to. - // Host must contain a port. + // For client requests, Host optionally specifies the server to + // 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. Host string @@ -55,7 +59,7 @@ type Request struct { 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. 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. -// The host is inferred from the URL. // // Callers should be careful that the URL query is properly escaped. // See the documentation for QueryEscape for more information. func NewRequestFromURL(url *url.URL) *Request { - host := url.Host - if url.Port() == "" { - host += ":1965" - } return &Request{ - URL: url, - Host: host, + URL: url, } } |