diff --git a/cert_test.go b/cert_test.go index c9c6b8aa5bd..077b2a62732 100644 --- a/cert_test.go +++ b/cert_test.go @@ -640,3 +640,30 @@ func TestCipherSuites(t *testing.T) { ts.Run(t, test.TestCase{Client: client, Path: "/", ErrorMatch: "tls: handshake failure"}) }) } + +func TestHttp2(t *testing.T) { + //configure server so we can useSSL and utilize the logic, but skip verification in the clients + _, _, combinedPEM, _ := genServerCertificate() + serverCertID, _ := CertificateManager.Add(combinedPEM, "") + defer CertificateManager.Delete(serverCertID) + + config.Global.HttpServerOptions.UseSSL = true + config.Global.HttpServerOptions.SSLCertificates = []string{serverCertID} + config.Global.HttpServerOptions.UseHttp2 = true + + defer resetTestConfig() + + ts := newTykTestServer() + defer ts.Close() + + buildAndLoadAPI(func(spec *APISpec) { + spec.Proxy.ListenPath = "/" + }) + + + t.Run("http2client", func(t *testing.T) { + client := getTLSClient(nil, nil) + + ts.Run(t, test.TestCase{Client: client, Path: "/"}) + }) +} diff --git a/config/config.go b/config/config.go index 23bc7b99881..8a55372610f 100644 --- a/config/config.go +++ b/config/config.go @@ -128,6 +128,7 @@ type HttpServerOptionsConfig struct { SkipURLCleaning bool `json:"skip_url_cleaning"` SkipTargetPathEscaping bool `json:"skip_target_path_escaping"` Ciphers []string `json:"ssl_ciphers"` + UseHttp2 bool `json:"use_http2"` } type AuthOverrideConf struct { diff --git a/lint/schema.go b/lint/schema.go index 87f97d5f980..a38684219e4 100644 --- a/lint/schema.go +++ b/lint/schema.go @@ -352,6 +352,9 @@ const confSchema = `{ "type": "string" } }, + "use_http2":{ + "type": "boolean" + }, "ssl_ciphers":{ "type": ["array", "null"], "items": { diff --git a/main.go b/main.go index 9cc4904f097..62bd7777b4f 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "golang.org/x/net/http2" "crypto/tls" "fmt" "html/template" @@ -1217,7 +1218,22 @@ func generateListener(listenPort int) (net.Listener, error) { log.WithFields(logrus.Fields{ "prefix": "main", }).Info("--> Using SSL (https)") - + if config.Global.HttpServerOptions.UseHttp2{ + + tlsConfig := tls.Config{ + GetCertificate: dummyGetCertificate, + ServerName: config.Global.HttpServerOptions.ServerName, + MinVersion: config.Global.HttpServerOptions.MinVersion, + ClientAuth: tls.RequestClientCert, + InsecureSkipVerify: config.Global.HttpServerOptions.SSLInsecureSkipVerify, + CipherSuites: getCipherAliases([]string{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}), + NextProtos: []string{http2.NextProtoTLS}, + } + + tlsConfig.GetConfigForClient = getTLSConfigForClient(&tlsConfig, listenPort) + + return tls.Listen("tcp", targetPort, &tlsConfig) + } tlsConfig := tls.Config{ GetCertificate: dummyGetCertificate, ServerName: config.Global.HttpServerOptions.ServerName, diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go new file mode 100644 index 00000000000..e2987f7db82 --- /dev/null +++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go @@ -0,0 +1,61 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_darwin.go + +package socket + +const ( + sysAF_UNSPEC = 0x0 + sysAF_INET = 0x2 + sysAF_INET6 = 0x1e + + sysSOCK_RAW = 0x3 +) + +type iovec struct { + Base *byte + Len uint64 +} + +type msghdr struct { + Name *byte + Namelen uint32 + Pad_cgo_0 [4]byte + Iov *iovec + Iovlen int32 + Pad_cgo_1 [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +const ( + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 + sizeofCmsghdr = 0xc + + sizeofSockaddrInet = 0x10 + sizeofSockaddrInet6 = 0x1c +)