]> Sergey Matveev's repositories - tofuproxy.git/commitdiff
HTTP/2.0
authorSergey Matveev <stargrave@stargrave.org>
Mon, 6 Sep 2021 12:52:40 +0000 (15:52 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 6 Sep 2021 17:04:35 +0000 (20:04 +0300)
conn.go
doc/index.texi
main.go
verify.go

diff --git a/conn.go b/conn.go
index 1542abda9935a85b1afdefb4b49b05861b78cd9b..fbb8a5c19aa13a7d858493fa9182d03e791074cf 100644 (file)
--- a/conn.go
+++ b/conn.go
@@ -25,6 +25,7 @@ import (
 type SingleConn struct {
        conn net.Conn
        ln   *SingleListener
+       once sync.Once
 }
 
 func (conn *SingleConn) Read(b []byte) (int, error) { return conn.conn.Read(b) }
@@ -32,7 +33,7 @@ func (conn *SingleConn) Read(b []byte) (int, error) { return conn.conn.Read(b) }
 func (conn *SingleConn) Write(b []byte) (int, error) { return conn.conn.Write(b) }
 
 func (conn *SingleConn) Close() error {
-       conn.ln.Unlock()
+       conn.once.Do(conn.ln.Unlock)
        return conn.conn.Close()
 }
 
@@ -62,7 +63,7 @@ func (ln *SingleListener) Accept() (net.Conn, error) {
                return nil, AlreadyAccepted{}
        }
        ln.accepted = true
-       return &SingleConn{ln.conn, ln}, nil
+       return &SingleConn{conn: ln.conn, ln: ln}, nil
 }
 
 func (ln *SingleListener) Close() error { return nil }
index 62b18bce79029c668c36b2611f21487b2a11017b..a860f633086eb1f7e23096661b8ccd6f10564312 100644 (file)
@@ -91,6 +91,9 @@ creating some kind of complex configuration framework.
 
 @item TLS session resumption is also supported.
 
+@item And Go itself tries also to act as a
+@url{https://http2.github.io/, HTTP/2} client too.
+
 @end itemize
 
 @image{dialog,,,Example dialog,.webp}
diff --git a/main.go b/main.go
index 69448ce2a66f53860064e9bde6ba3c0b4ed0f73c..663bf9508980fd9a3600f7f952b4cfdf1d80c825 100644 (file)
--- a/main.go
+++ b/main.go
@@ -42,9 +42,8 @@ var (
        caCert        *x509.Certificate
        caPrv         crypto.PrivateKey
        transport     = http.Transport{
-               ForceAttemptHTTP2: false,
-               TLSNextProto:      make(map[string]func(string, *tls.Conn) http.RoundTripper),
                DialTLSContext:    dialTLS,
+               ForceAttemptHTTP2: true,
        }
        sessionCache = tls.NewLRUClientSessionCache(1024)
 
@@ -62,6 +61,7 @@ func dialTLS(ctx context.Context, network, addr string) (net.Conn, error) {
                        return verifyCert(host, nil, rawCerts, verifiedChains)
                },
                ClientSessionCache: sessionCache,
+               NextProtos:         []string{"h2", "http/1.1"},
        }
        conn, dialErr := tls.Dial(network, addr, &cfg)
        if dialErr != nil {
@@ -83,17 +83,16 @@ func dialTLS(ctx context.Context, network, addr string) (net.Conn, error) {
                }
        }
        connState := conn.ConnectionState()
-       msg := fmt.Sprintf(
-               "%s\t%s %s\t%s",
-               strings.TrimSuffix(addr, ":443"),
-               ucspi.TLSVersion(connState.Version),
-               tls.CipherSuiteName(connState.CipherSuite),
-               spkiHash(connState.PeerCertificates[0]),
-       )
        if connState.DidResume {
-               msg += "\tresumed"
+               sinkTLS <- fmt.Sprintf(
+                       "%s\t%s %s\t%s\t%s",
+                       strings.TrimSuffix(addr, ":443"),
+                       ucspi.TLSVersion(connState.Version),
+                       tls.CipherSuiteName(connState.CipherSuite),
+                       spkiHash(connState.PeerCertificates[0]),
+                       connState.NegotiatedProtocol,
+               )
        }
-       sinkTLS <- msg
        return conn, nil
 }
 
index f6844cd997f7fd13a3198eb488ca6ff102ba6e01..7844d14f97ee8bc1542614b930971e24348064dc 100644 (file)
--- a/verify.go
+++ b/verify.go
@@ -42,6 +42,7 @@ var (
        acceptedM sync.RWMutex
        rejected  = make(map[string]string)
        rejectedM sync.RWMutex
+       VerifyM   sync.Mutex
 )
 
 func spkiHash(cert *x509.Certificate) string {
@@ -103,6 +104,8 @@ func verifyCert(
                }
        }
        certTheirHash := spkiHash(certTheir)
+       VerifyM.Lock()
+       defer VerifyM.Unlock()
        acceptedM.RLock()
        certOurHash := accepted[host]
        acceptedM.RUnlock()