From: qydysky Date: Sat, 9 Mar 2024 17:14:25 +0000 (+0800) Subject: 1 X-Git-Tag: v0.28.20240309172046 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=435d4ad97400714aa485af1487f656a8cb3d36da;p=part%2F.git 1 --- diff --git a/web/Web.go b/web/Web.go index 2f12d4f..47d0464 100644 --- a/web/Web.go +++ b/web/Web.go @@ -125,6 +125,11 @@ func (t *WebPath) GetConn(r *http.Request) net.Conn { return r.Context().Value(t).(net.Conn) } +// O /../../1 => /../../1 +// +// X /../../1 => /../../ +// +// X /../../1 => /../ func (t *WebPath) Load(path string) (func(w http.ResponseWriter, r *http.Request), bool) { if len(path) == 0 || path[0] != '/' { return nil, false @@ -152,7 +157,12 @@ func (t *WebPath) Load(path string) (func(w http.ResponseWriter, r *http.Request } } -func (t *WebPath) LoadPerfix(path string) (f func(w http.ResponseWriter, r *http.Request), ok bool) { +// O /../../1 => /../../1 +// +// O /../../1 => /../../ +// +// X /../../1 => /../ +func (t *WebPath) LoadOnePerfix(path string) (f func(w http.ResponseWriter, r *http.Request), ok bool) { if len(path) == 0 || path[0] != '/' { return nil, false } @@ -165,7 +175,7 @@ func (t *WebPath) LoadPerfix(path string) (f func(w http.ResponseWriter, r *http f = t.f } if t.Same != nil { - if f1, ok := t.Same.LoadPerfix(left); ok { + if f1, ok := t.Same.LoadOnePerfix(left); ok { f = f1 } return f, f != nil @@ -177,7 +187,7 @@ func (t *WebPath) LoadPerfix(path string) (f func(w http.ResponseWriter, r *http f = t.f } if t.Next != nil { - if f1, ok := t.Next.LoadPerfix(path); ok { + if f1, ok := t.Next.LoadOnePerfix(path); ok { f = f1 } return f, f != nil @@ -187,6 +197,56 @@ func (t *WebPath) LoadPerfix(path string) (f func(w http.ResponseWriter, r *http } } +// O /../../1 => /../../1 +// +// O /../../1 => /../../ +// +// O /../../1 => /../ +func (t *WebPath) LoadPerfix(path string) (f func(w http.ResponseWriter, r *http.Request), ok bool) { + if len(path) == 0 || path[0] != '/' { + return nil, false + } + + t.l.RLock() + defer t.l.RUnlock() + + if key, left, fin := parsePath(path); t.Path == "/" { + f = t.f + if t.Path != key { + if t.Next != nil { + if f1, ok := t.Next.LoadPerfix(path); ok { + f = f1 + } + } + } + return f, f != nil + } else if t.Path == key { + if fin { + f = t.f + return f, f != nil + } + if t.Same != nil { + if f1, ok := t.Same.LoadPerfix(left); ok { + f = f1 + return f, f != nil + } + } + if t.Next != nil { + if f1, ok := t.Next.LoadPerfix(path); ok { + f = f1 + } + } + return f, f != nil + } else { + if t.Next != nil { + if f1, ok := t.Next.LoadPerfix(path); ok { + f = f1 + } + } + return f, f != nil + } +} + func parsePath(path string) (key string, left string, fin bool) { if pi := 1 + strings.Index(path[1:], "/"); pi != 0 { return path[:pi], path[pi:], false diff --git a/web/Web_test.go b/web/Web_test.go index 1f974e7..3bc1b2a 100644 --- a/web/Web_test.go +++ b/web/Web_test.go @@ -142,14 +142,56 @@ func Test_Store(t *testing.T) { t.Fatal() } } + var checkOnePerfix = func(webPath *WebPath) { + res = "" + if _, ok := webPath.LoadOnePerfix("/1/2"); ok { + t.Fatal() + } + + if _, ok := webPath.LoadOnePerfix("/1/"); ok { + t.Fatal() + } + + if f, ok := webPath.LoadOnePerfix("/2"); !ok { + t.Fatal() + } else { + f(nil, nil) + } + + if f, ok := webPath.LoadOnePerfix("/1/1"); !ok { + t.Fatal() + } else { + f(nil, nil) + } + + if f, ok := webPath.LoadOnePerfix("/1"); !ok { + t.Fatal() + } else { + f(nil, nil) + } + + if f, ok := webPath.LoadOnePerfix("/"); !ok { + t.Fatal() + } else { + f(nil, nil) + } + + if res != "acba" { + t.Fatal() + } + } var checkPerfix = func(webPath *WebPath) { res = "" - if _, ok := webPath.LoadPerfix("/1/2"); ok { + if f, ok := webPath.LoadPerfix("/1/2"); !ok { t.Fatal() + } else { + f(nil, nil) } - if _, ok := webPath.LoadPerfix("/1/"); ok { + if f, ok := webPath.LoadPerfix("/1/"); !ok { t.Fatal() + } else { + f(nil, nil) } if f, ok := webPath.LoadPerfix("/2"); !ok { @@ -176,11 +218,23 @@ func Test_Store(t *testing.T) { f(nil, nil) } - if res != "acba" { - t.Fatal() + if res != "aaacba" { + t.Fatal(res) } } + webPath.Store("/", f("a")) + webPath.Store("/1", f("b")) + webPath.Store("/1/", f("b")) + webPath.Store("/1/1", f("b")) + if m, e := json.Marshal(webPath); e != nil { + t.Fatal(e) + } else if string(m) != `{"path":"/","same":null,"next":{"path":"/1","same":{"path":"/","same":null,"next":{"path":"/1","same":null,"next":null}},"next":null}}` { + t.Fatal(string(m)) + } + webPath.Reset() + t.Log(0) + webPath.Store("/", f("a")) webPath.Store("/1", f("b")) webPath.Store("/2", f("b")) @@ -195,8 +249,10 @@ func Test_Store(t *testing.T) { } checkFull(&webPath) + checkOnePerfix(&webPath) checkPerfix(&webPath) webPath.Reset() + t.Log(1) webPath.Store("/1", f("b")) webPath.Store("/", f("a")) @@ -208,8 +264,10 @@ func Test_Store(t *testing.T) { } checkFull(&webPath) + checkOnePerfix(&webPath) checkPerfix(&webPath) webPath.Reset() + t.Log(2) webPath.Store("/1/1", f("c")) webPath.Store("/", f("a")) @@ -221,6 +279,7 @@ func Test_Store(t *testing.T) { } checkFull(&webPath) + checkOnePerfix(&webPath) checkPerfix(&webPath) webPath.Reset() }