]> 127.0.0.1 Git - part/.git/commitdiff
1 v0.28.20240309172046
authorqydysky <qydysky@foxmail.com>
Sat, 9 Mar 2024 17:14:25 +0000 (01:14 +0800)
committerqydysky <qydysky@foxmail.com>
Sat, 9 Mar 2024 17:14:25 +0000 (01:14 +0800)
web/Web.go
web/Web_test.go

index 2f12d4fc2a309a854766e78022587b4222c818e4..47d04641e12bb38eab3a34ea887778108280732c 100644 (file)
@@ -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
index 1f974e7f0291437c2c126298234117b46a5be57f..3bc1b2a5b666c466e3b861606ff91d22a58ef1df 100644 (file)
@@ -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()
 }