Skip to content

Commit

Permalink
update matcher funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhang93 committed May 13, 2024
1 parent 227538c commit 31eae5b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 39 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func main() {

mux := lnmux.Listener{Root: ln, ConnReadTimeout: 100 * time.Millisecond}

jsonListener := mux.ListenFor("content-type:json", matchers.MatchHeader(192, "Content-Type: application/json"))
httpFastListener := mux.ListenFor("http-fast-listener", matchers.MatchHTTPFast(64))
httpOneListener := mux.ListenFor("http-one-listener", matchers.AutoMatchHTTP)
httpFastListener := mux.ListenFor("http-fast-listener", matchers.AutoMatchHTTPFast)
HTTP2Listener := mux.ListenFor("grpc", matchers.MatchHTTP2Preface())
// same matcher can be used for GRPC as well

Expand All @@ -53,7 +53,7 @@ func main() {
wg.Add(3)
go func() {
defer wg.Done()
startServer(jsonListener, func(writer http.ResponseWriter, request *http.Request) {
startServer(httpOneListener, func(writer http.ResponseWriter, request *http.Request) {
_, _ = fmt.Fprintf(writer, "OK")
}, false)
}()
Expand Down
6 changes: 3 additions & 3 deletions example/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func main() {

mux := lnmux.Listener{Root: ln, ConnReadTimeout: 100 * time.Millisecond}

jsonListener := mux.ListenFor("content-type:json", matchers.MatchHeader(192, "Content-Type: application/json"))
httpFastListener := mux.ListenFor("http-fast-listener", matchers.MatchHTTPFast(64))
HTTP2Listener := mux.ListenFor("grpc", matchers.MatchHTTP2Preface())
jsonListener := mux.ListenFor("content-type:json", matchers.AutoMatchHeader("Content-Type: application/json"))
httpFastListener := mux.ListenFor("http-fast-listener", matchers.AutoMatchHTTPFast)
HTTP2Listener := mux.ListenFor("grpc", matchers.MatchHTTP2Preface)
// same matcher can be used for GRPC as well

var wg sync.WaitGroup
Expand Down
82 changes: 50 additions & 32 deletions matchers/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

const http2ReqLine = "HTTP/2"
const defaultByteReadSize = 512

// copied from
// "golang.org/x/net/http2"
Expand All @@ -20,31 +21,49 @@ const http2ConnPreface = "PRI * HTTP/2.0\n\nSM\n\n"
// peeks into the connection without consuming bytes from the underlying connection
// return a true if match succeeded and an error to signal an error

func AutoMatchHeader(header string) connmatch.Func {
return func(connPkr connmatch.Peeker) (matched bool, matchErr error) {
return matchHeader(connPkr, defaultByteReadSize, header)
}
}

func MatchHeader(sniffN int, header string) connmatch.Func {
return func(pkr connmatch.Peeker) (bool, error) {
peeked, err := pkr.Peek(sniffN)
return matchHeader(pkr, sniffN, header)
}
}

var timeoutErr error
if err != nil && !os.IsTimeout(err) {
return false, err
} else {
timeoutErr = err
}
func matchHeader(pkr connmatch.Peeker, sniffN int, header string) (bool, error) {
peeked, err := pkr.Peek(sniffN)

lines := bytes.Split(peeked, []byte{'\n'})
if len(lines) > 2 {
first := string(lines[0])
lines = lines[1:]
if parseHTTPFast(first) || parseHTTPZero(first) {
for _, line := range lines {
if strings.Contains(string(line), header) {
return true, timeoutErr
}
var timeoutErr error
if err != nil && !os.IsTimeout(err) {
return false, err
} else {
timeoutErr = err
}

lines := bytes.Split(peeked, []byte{'\n'})
if len(lines) > 2 {
first := string(lines[0])
lines = lines[1:]
if parseHTTPFast(first) || parseHTTPZero(first) {
for _, line := range lines {
if strings.Contains(string(line), header) {
return true, timeoutErr
}
}
}
return false, timeoutErr
}
return false, timeoutErr
}

func AutoMatchHTTP(pkr connmatch.Peeker) (bool, error) {
return matchHTTPVersion(defaultByteReadSize, 1, pkr)
}

func AutoMatchHTTPFast(pkr connmatch.Peeker) (bool, error) {
return matchHTTPVersion(defaultByteReadSize, 11, pkr)
}

// MatchHTTPOne matches HTTP/1.0 connections
Expand All @@ -71,24 +90,23 @@ func MatchHTTPTwoCURL(sniffN int) connmatch.Func {
// MatchHTTP2Preface can be used for connections which contain the
// HTTP/2 connection preface `PRI * HTTP/2.0\n\nSM\n\n`
// GRPC connections can also be matched with this
func MatchHTTP2Preface() connmatch.Func {
return func(pkr connmatch.Peeker) (bool, error) {
bs, err := pkr.Peek(len(http2ConnPreface))
func MatchHTTP2Preface(pkr connmatch.Peeker) (bool, error) {
bs, err := pkr.Peek(len(http2ConnPreface))

var timeoutErr error
if err != nil && !os.IsTimeout(err) {
return false, err
} else {
timeoutErr = err
}
var timeoutErr error
if err != nil && !os.IsTimeout(err) {
return false, err
} else {
timeoutErr = err
}

lines := bytes.Split(bs, []byte{'\n'})
if len(lines) > 0 {
first := lines[0]
return strings.HasPrefix(http2ConnPreface, string(first)), timeoutErr
}
return false, timeoutErr
lines := bytes.Split(bs, []byte{'\n'})
if len(lines) > 0 {
first := lines[0]
return strings.HasPrefix(http2ConnPreface, string(first)), timeoutErr
}
return false, timeoutErr

}

func matchHTTPVersion(sniffN int, version int, pkr connmatch.Peeker) (bool, error) {
Expand Down
2 changes: 1 addition & 1 deletion matchers/matchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Accept: application/json`
}
_ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
buffConn := bufio.NewReader(conn)
sniffer := MatchHTTP2Preface()
sniffer := MatchHTTP2Preface
match, err := sniffer(buffConn)
if err != nil && !os.IsTimeout(err) {
t.Errorf("match error:%v", err)
Expand Down

0 comments on commit 31eae5b

Please sign in to comment.