Fix mux URL sorting logic
This commit is contained in:
		
							parent
							
								
									744884127c
								
							
						
					
					
						commit
						5a07b49ef5
					
				@ -24,13 +24,18 @@ func TestServeMuxEntryOrder(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// Shuffle input
 | 
			
		||||
	a := make([]string, len(expected))
 | 
			
		||||
	copy(expected, a)
 | 
			
		||||
	copy(a, expected)
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
 | 
			
		||||
 | 
			
		||||
	mux := &ServeMux{}
 | 
			
		||||
	for _, s := range a {
 | 
			
		||||
		mux.Handle(s, nil)
 | 
			
		||||
		mux.Handle(s, NotFoundHandler())
 | 
			
		||||
		var es string
 | 
			
		||||
		for i := range mux.es {
 | 
			
		||||
			es += mux.es[i].u.String() + " "
 | 
			
		||||
		}
 | 
			
		||||
		t.Logf(es)
 | 
			
		||||
	}
 | 
			
		||||
	for i, e := range mux.es {
 | 
			
		||||
		s := e.u.String()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								server.go
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								server.go
									
									
									
									
									
								
							@ -454,10 +454,9 @@ func isSlashRune(r rune) bool { return r == '/' || r == '\\' }
 | 
			
		||||
// header, stripping the port number and redirecting any request containing . or
 | 
			
		||||
// .. elements or repeated slashes to an equivalent, cleaner URL.
 | 
			
		||||
type ServeMux struct {
 | 
			
		||||
	mu    sync.RWMutex
 | 
			
		||||
	m     map[string]muxEntry
 | 
			
		||||
	es    []muxEntry // slice of entries sorted from longest to shortest.
 | 
			
		||||
	hosts bool       // whether any patterns contain hostnames
 | 
			
		||||
	mu sync.RWMutex
 | 
			
		||||
	m  map[string]muxEntry
 | 
			
		||||
	es []muxEntry // slice of entries sorted from longest to shortest.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type muxEntry struct {
 | 
			
		||||
@ -646,13 +645,9 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
 | 
			
		||||
	}
 | 
			
		||||
	e := muxEntry{h: handler, pattern: pattern, u: url}
 | 
			
		||||
	mux.m[pattern] = e
 | 
			
		||||
	if pattern[len(pattern)-1] == '/' {
 | 
			
		||||
		mux.es = appendSorted(mux.es, e)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if pattern[0] != '/' {
 | 
			
		||||
		mux.hosts = true
 | 
			
		||||
	}
 | 
			
		||||
	// if pattern[len(pattern)-1] == '/' {
 | 
			
		||||
	mux.es = appendSorted(mux.es, e)
 | 
			
		||||
	// }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
 | 
			
		||||
@ -662,9 +657,27 @@ func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
 | 
			
		||||
		// - Entries with a scheme take preference over entries without.
 | 
			
		||||
		// - Entries with a host take preference over entries without.
 | 
			
		||||
		// - Longer paths take preference over shorter paths.
 | 
			
		||||
		return (es[i].u.Scheme == "" || (e.u.Scheme != "" && len(es[i].u.Scheme) < len(e.u.Scheme))) &&
 | 
			
		||||
			(es[i].u.Host == "" || (e.u.Host != "" && len(es[i].u.Host) < len(e.u.Host))) &&
 | 
			
		||||
			len(es[i].u.Path) < len(e.u.Path)
 | 
			
		||||
		if e.u.Scheme != "" {
 | 
			
		||||
			if es[i].u.Scheme == "" {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
			if es[i].u.Scheme != e.u.Scheme {
 | 
			
		||||
				return len(es[i].u.Scheme) < len(e.u.Scheme)
 | 
			
		||||
			}
 | 
			
		||||
		} else if es[i].u.Scheme != "" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		if e.u.Host != "" {
 | 
			
		||||
			if es[i].u.Host == "" {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
			if es[i].u.Host != e.u.Host {
 | 
			
		||||
				return len(es[i].u.Scheme) < len(e.u.Scheme)
 | 
			
		||||
			}
 | 
			
		||||
		} else if es[i].u.Host != "" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		return len(es[i].u.Path) < len(e.u.Path)
 | 
			
		||||
	})
 | 
			
		||||
	if i == n {
 | 
			
		||||
		return append(es, e)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user