aboutsummaryrefslogtreecommitdiff
path: root/client.go
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2021-02-09 15:59:45 -0500
committerAdnan Maolood <[email protected]>2021-02-09 15:59:47 -0500
commit79e0296bed62dad1399e888112ea5c6bd1d8c6bd (patch)
tree2955f7b5103f43038e5f025431507a6f97038001 /client.go
parentAdd Gemini specification version to README.md (diff)
downloadgo-gemini-79e0296bed62dad1399e888112ea5c6bd1d8c6bd.tar.xz
go-gemini-79e0296bed62dad1399e888112ea5c6bd1d8c6bd.zip
client: Support IDNs
Convert IDNs to punycode before performing DNS lookups.
Diffstat (limited to 'client.go')
-rw-r--r--client.go37
1 files changed, 18 insertions, 19 deletions
diff --git a/client.go b/client.go
index 0c92e1d..820e4c3 100644
--- a/client.go
+++ b/client.go
@@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"net"
- "strings"
"time"
)
@@ -44,11 +43,14 @@ func (c *Client) Get(url string) (*Response, error) {
// Do performs a Gemini request and returns a Gemini response.
func (c *Client) Do(req *Request) (*Response, error) {
// Extract hostname
- colonPos := strings.LastIndex(req.Host, ":")
- if colonPos == -1 {
- colonPos = len(req.Host)
+ hostname, port, err := net.SplitHostPort(req.Host)
+ if err != nil {
+ return nil, err
+ }
+ punycode, err := punycodeHostname(hostname)
+ if err != nil {
+ return nil, err
}
- hostname := req.Host[:colonPos]
// Connect to the host
config := &tls.Config{
@@ -61,11 +63,11 @@ func (c *Client) Do(req *Request) (*Response, error) {
return &tls.Certificate{}, nil
},
VerifyConnection: func(cs tls.ConnectionState) error {
- return c.verifyConnection(req, cs)
+ return c.verifyConnection(hostname, punycode, cs)
},
- ServerName: hostname,
+ ServerName: punycode,
}
- // Set connection context
+
ctx := req.Context
if ctx == nil {
ctx = context.Background()
@@ -76,7 +78,8 @@ func (c *Client) Do(req *Request) (*Response, error) {
Timeout: c.Timeout,
}
- netConn, err := dialer.DialContext(ctx, "tcp", req.Host)
+ address := net.JoinHostPort(punycode, port)
+ netConn, err := dialer.DialContext(ctx, "tcp", address)
if err != nil {
return nil, err
}
@@ -129,17 +132,13 @@ func (c *Client) do(conn *tls.Conn, req *Request) (*Response, error) {
return resp, nil
}
-func (c *Client) verifyConnection(req *Request, cs tls.ConnectionState) error {
- // Verify the hostname
- var hostname string
- if host, _, err := net.SplitHostPort(req.Host); err == nil {
- hostname = host
- } else {
- hostname = req.Host
- }
+func (c *Client) verifyConnection(hostname, punycode string, cs tls.ConnectionState) error {
cert := cs.PeerCertificates[0]
- if err := verifyHostname(cert, hostname); err != nil {
- return err
+ // Try punycode and then hostname
+ if err := verifyHostname(cert, punycode); err != nil {
+ if err := verifyHostname(cert, hostname); err != nil {
+ return err
+ }
}
// Check expiration date
if !time.Now().Before(cert.NotAfter) {