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
}
}
-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
}
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
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
}
}
+// 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
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 {
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"))
}
checkFull(&webPath)
+ checkOnePerfix(&webPath)
checkPerfix(&webPath)
webPath.Reset()
+ t.Log(1)
webPath.Store("/1", f("b"))
webPath.Store("/", f("a"))
}
checkFull(&webPath)
+ checkOnePerfix(&webPath)
checkPerfix(&webPath)
webPath.Reset()
+ t.Log(2)
webPath.Store("/1/1", f("c"))
webPath.Store("/", f("a"))
}
checkFull(&webPath)
+ checkOnePerfix(&webPath)
checkPerfix(&webPath)
webPath.Reset()
}