diff --git a/matchers.go b/matchers.go index cfc24c7..bb4bc90 100644 --- a/matchers.go +++ b/matchers.go @@ -16,6 +16,7 @@ package cmux import ( "bufio" + "crypto/tls" "io" "io/ioutil" "net/http" @@ -37,6 +38,13 @@ func PrefixMatcher(strs ...string) Matcher { return pt.matchPrefix } +// PrefixByteMatcher returns a matcher that matches a connection if it +// starts with any of the []byte in list. +func PrefixByteMatcher(list ...[]byte) Matcher { + pt := newPatriciaTree(list...) + return pt.matchPrefix +} + var defaultHTTPMethods = []string{ "OPTIONS", "GET", @@ -57,6 +65,27 @@ func HTTP1Fast(extMethods ...string) Matcher { return PrefixMatcher(append(defaultHTTPMethods, extMethods...)...) } +// TLS matches HTTPS requests. +// +// By default, any TLS handshake packet is matched. An optional whitelist +// of versions can be passed in to restrict the matcher, for example: +// TLS(tls.VersionTLS11, tls.VersionTLS12) +func TLS(versions ...int) Matcher { + if len(versions) == 0 { + versions = []int{ + tls.VersionSSL30, + tls.VersionTLS10, + tls.VersionTLS11, + tls.VersionTLS12, + } + } + prefixes := [][]byte{} + for _, v := range versions { + prefixes = append(prefixes, []byte{22, byte(v >> 8 & 0xff), byte(v & 0xff)}) + } + return PrefixByteMatcher(prefixes...) +} + const maxHTTPRead = 4096 // HTTP1 parses the first line or upto 4096 bytes of the request to see if