From 9dc89f1a58e8d036298d4f270259e2a65252e833 Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:10:15 +0300 Subject: [PATCH 1/6] g --- internal/mx/mx_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++ internal/mx/route.go | 7 +++++ 2 files changed, 69 insertions(+) diff --git a/internal/mx/mx_test.go b/internal/mx/mx_test.go index cff08c83..b2567023 100644 --- a/internal/mx/mx_test.go +++ b/internal/mx/mx_test.go @@ -452,3 +452,65 @@ func BenchmarkMuxNew(b *testing.B) { // so the compiler cannot eliminate the Benchmark itself. result = r } + +func TestMuxKomu(t *testing.T) { + t.Parallel() + + tr := &http.Transport{ + // since we are using self-signed certificates, we need to skip verification. + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + + httpsPort := tst.GetPort() + domain := "localhost" + + l := log.New(context.Background(), &bytes.Buffer{}, 500) + + t.Run("todo", func(t *testing.T) { + t.Parallel() + + msg := "hello world" + rt, err := NewRoute( + "/*", + MethodGet, + someMuxHandler(msg), + ) + attest.Ok(t, err) + mux, err := New( + config.WithOpts(domain, httpsPort, tst.SecretKey(), config.DirectIpStrategy, l), + nil, + rt, + ) + attest.Ok(t, err) + + ts, err := tst.TlsServer(mux, domain, httpsPort) + attest.Ok(t, err) + defer ts.Close() + + // { + // rec := httptest.NewRecorder() + // req := httptest.NewRequest(http.MethodGet, "/UnknownUri", nil) + // mux.ServeHTTP(rec, req) + + // res := rec.Result() + // defer res.Body.Close() + + // _, err := io.ReadAll(res.Body) + // attest.Ok(t, err) + + // attest.Equal(t, res.StatusCode, http.StatusNotFound) + // } + + { + res, err := client.Get(ts.URL + "/") + attest.Ok(t, err) + + rb, err := io.ReadAll(res.Body) + attest.Ok(t, err) + + attest.Equal(t, res.StatusCode, http.StatusOK) + attest.Equal(t, string(rb), msg) + } + }) +} diff --git a/internal/mx/route.go b/internal/mx/route.go index 37510172..aaa28233 100644 --- a/internal/mx/route.go +++ b/internal/mx/route.go @@ -73,6 +73,12 @@ func (r Route) match(ctx context.Context, segs []string) (context.Context, bool) if len(segs) > len(r.segments) { return nil, false } + + if len(r.segments) == 1 && r.segments[0] == "*" { + // The router is allowed to handle all request paths + return ctx, true + } + for i, seg := range r.segments { if i > len(segs)-1 { return nil, false @@ -91,6 +97,7 @@ func (r Route) match(ctx context.Context, segs []string) (context.Context, bool) ctx = context.WithValue(ctx, muxContextKey(seg), segs[i]) } } + return ctx, true } From ac8ef976bb3858f6025117e3a3a8fb74e1599f74 Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:12:17 +0300 Subject: [PATCH 2/6] g --- internal/mx/mx_test.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/internal/mx/mx_test.go b/internal/mx/mx_test.go index b2567023..29527b0c 100644 --- a/internal/mx/mx_test.go +++ b/internal/mx/mx_test.go @@ -488,19 +488,16 @@ func TestMuxKomu(t *testing.T) { attest.Ok(t, err) defer ts.Close() - // { - // rec := httptest.NewRecorder() - // req := httptest.NewRequest(http.MethodGet, "/UnknownUri", nil) - // mux.ServeHTTP(rec, req) - - // res := rec.Result() - // defer res.Body.Close() + { + res, err := client.Get(ts.URL + "/UnknownUri") + attest.Ok(t, err) - // _, err := io.ReadAll(res.Body) - // attest.Ok(t, err) + rb, err := io.ReadAll(res.Body) + attest.Ok(t, err) - // attest.Equal(t, res.StatusCode, http.StatusNotFound) - // } + attest.Equal(t, res.StatusCode, http.StatusOK) + attest.Equal(t, string(rb), msg) + } { res, err := client.Get(ts.URL + "/") From 3d1522bfc80a1bf6ba41ae459dac9e43c56f0d9f Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:22:57 +0300 Subject: [PATCH 3/6] good --- internal/mx/route.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/mx/route.go b/internal/mx/route.go index aaa28233..8a02a0a9 100644 --- a/internal/mx/route.go +++ b/internal/mx/route.go @@ -229,6 +229,10 @@ already exists and would conflict`, getfunc(rt.originalHandler), ) + if len(existingSegments) == 1 && existingSegments[0] == "*" && len(incomingSegments) > 0 { + return errMsg + } + if pattern == rt.pattern { return errMsg } From 4520180e1bdf94b06d8c419b9c26965adb7cfefd Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:27:28 +0300 Subject: [PATCH 4/6] g --- internal/mx/mx_test.go | 123 +++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/internal/mx/mx_test.go b/internal/mx/mx_test.go index 29527b0c..a5df3a27 100644 --- a/internal/mx/mx_test.go +++ b/internal/mx/mx_test.go @@ -408,52 +408,7 @@ func TestMux(t *testing.T) { }) } -func getManyRoutes(b *testing.B) []Route { - b.Helper() - - routes := []Route{} - - for i := 0; i <= 200; i++ { - uri := fmt.Sprintf("uri-%d", i) - rt, err := NewRoute( - uri, - MethodAll, - someMuxHandler(uri), - ) - attest.Ok(b, err) - routes = append( - routes, - rt, - ) - } - - return routes -} - -var result Muxer //nolint:gochecknoglobals - -func BenchmarkMuxNew(b *testing.B) { - var r Muxer - - l := log.New(context.Background(), &bytes.Buffer{}, 500) - - b.ReportAllocs() - b.ResetTimer() - for range b.N { - mux, err := New( - config.WithOpts("localhost", 443, tst.SecretKey(), config.DirectIpStrategy, l), - nil, - getManyRoutes(b)..., - ) - attest.Ok(b, err) - r = mux - } - // always store the result to a package level variable - // so the compiler cannot eliminate the Benchmark itself. - result = r -} - -func TestMuxKomu(t *testing.T) { +func TestMuxFlexiblePattern(t *testing.T) { t.Parallel() tr := &http.Transport{ @@ -467,7 +422,7 @@ func TestMuxKomu(t *testing.T) { l := log.New(context.Background(), &bytes.Buffer{}, 500) - t.Run("todo", func(t *testing.T) { + t.Run("flexible pattern accepts all uris", func(t *testing.T) { t.Parallel() msg := "hello world" @@ -510,4 +465,78 @@ func TestMuxKomu(t *testing.T) { attest.Equal(t, string(rb), msg) } }) + + t.Run("conflict", func(t *testing.T) { + t.Parallel() + + msg := "hello world" + + rt1, err := NewRoute( + "/*", + MethodGet, + someMuxHandler(msg), + ) + attest.Ok(t, err) + + rt2, err := NewRoute( + "/hi", + MethodGet, + thisIsAnotherMuxHandler(), + ) + attest.Ok(t, err) + + _, err = New( + config.WithOpts(domain, httpsPort, tst.SecretKey(), config.DirectIpStrategy, l), + nil, + rt1, + rt2, + ) + attest.Error(t, err) + attest.Subsequence(t, err.Error(), "would conflict") + }) +} + +func getManyRoutes(b *testing.B) []Route { + b.Helper() + + routes := []Route{} + + for i := 0; i <= 200; i++ { + uri := fmt.Sprintf("uri-%d", i) + rt, err := NewRoute( + uri, + MethodAll, + someMuxHandler(uri), + ) + attest.Ok(b, err) + routes = append( + routes, + rt, + ) + } + + return routes +} + +var result Muxer //nolint:gochecknoglobals + +func BenchmarkMuxNew(b *testing.B) { + var r Muxer + + l := log.New(context.Background(), &bytes.Buffer{}, 500) + + b.ReportAllocs() + b.ResetTimer() + for range b.N { + mux, err := New( + config.WithOpts("localhost", 443, tst.SecretKey(), config.DirectIpStrategy, l), + nil, + getManyRoutes(b)..., + ) + attest.Ok(b, err) + r = mux + } + // always store the result to a package level variable + // so the compiler cannot eliminate the Benchmark itself. + result = r } From ac7edb9724fd72c3135225508d7db15ba02a0677 Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:34:45 +0300 Subject: [PATCH 5/6] g --- internal/mx/mx_test.go | 11 +++++++++++ internal/mx/route.go | 8 ++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/mx/mx_test.go b/internal/mx/mx_test.go index a5df3a27..8317c766 100644 --- a/internal/mx/mx_test.go +++ b/internal/mx/mx_test.go @@ -464,6 +464,17 @@ func TestMuxFlexiblePattern(t *testing.T) { attest.Equal(t, res.StatusCode, http.StatusOK) attest.Equal(t, string(rb), msg) } + + { + res, err := client.Get(ts.URL + "/hey/a/b/cool") + attest.Ok(t, err) + + rb, err := io.ReadAll(res.Body) + attest.Ok(t, err) + + attest.Equal(t, res.StatusCode, http.StatusOK) + attest.Equal(t, string(rb), msg) + } }) t.Run("conflict", func(t *testing.T) { diff --git a/internal/mx/route.go b/internal/mx/route.go index 8a02a0a9..eb0a6bc8 100644 --- a/internal/mx/route.go +++ b/internal/mx/route.go @@ -70,15 +70,15 @@ func NewRoute( } func (r Route) match(ctx context.Context, segs []string) (context.Context, bool) { - if len(segs) > len(r.segments) { - return nil, false - } - if len(r.segments) == 1 && r.segments[0] == "*" { // The router is allowed to handle all request paths return ctx, true } + if len(segs) > len(r.segments) { + return nil, false + } + for i, seg := range r.segments { if i > len(segs)-1 { return nil, false From b8a3d22cbee10b3de84860298ecae51d946cd7bb Mon Sep 17 00:00:00 2001 From: komuw Date: Fri, 18 Oct 2024 16:40:48 +0300 Subject: [PATCH 6/6] g --- internal/mx/mx_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/mx/mx_test.go b/internal/mx/mx_test.go index 8317c766..0e3562c9 100644 --- a/internal/mx/mx_test.go +++ b/internal/mx/mx_test.go @@ -444,33 +444,33 @@ func TestMuxFlexiblePattern(t *testing.T) { defer ts.Close() { - res, err := client.Get(ts.URL + "/UnknownUri") - attest.Ok(t, err) + res, errA := client.Get(ts.URL + "/UnknownUri") + attest.Ok(t, errA) - rb, err := io.ReadAll(res.Body) - attest.Ok(t, err) + rb, errB := io.ReadAll(res.Body) + attest.Ok(t, errB) attest.Equal(t, res.StatusCode, http.StatusOK) attest.Equal(t, string(rb), msg) } { - res, err := client.Get(ts.URL + "/") - attest.Ok(t, err) + res, errC := client.Get(ts.URL + "/") + attest.Ok(t, errC) - rb, err := io.ReadAll(res.Body) - attest.Ok(t, err) + rb, errD := io.ReadAll(res.Body) + attest.Ok(t, errD) attest.Equal(t, res.StatusCode, http.StatusOK) attest.Equal(t, string(rb), msg) } { - res, err := client.Get(ts.URL + "/hey/a/b/cool") - attest.Ok(t, err) + res, errE := client.Get(ts.URL + "/hey/a/b/cool") + attest.Ok(t, errE) - rb, err := io.ReadAll(res.Body) - attest.Ok(t, err) + rb, errF := io.ReadAll(res.Body) + attest.Ok(t, errF) attest.Equal(t, res.StatusCode, http.StatusOK) attest.Equal(t, string(rb), msg)