@ -276,53 +276,45 @@ func sortRoutes(routes []ConfigValue) { 
			
		
	
		
			
				
							dirPositions [ dir ]  =  i  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// while we are sorting, we will need to decode a route's path matcher
  
			
		
	
		
			
				
						// in order to sub-sort by path length; we can amortize this operation
  
			
		
	
		
			
				
						// for efficiency by storing the decoded matchers in a slice
  
			
		
	
		
			
				
						decodedMatchers  :=  make ( [ ] caddyhttp . MatchPath ,  len ( routes ) )  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						sort . SliceStable ( routes ,  func ( i ,  j  int )  bool  {  
			
		
	
		
			
				
							// if the directives are different, just use the established directive order
  
			
		
	
		
			
				
							iDir ,  jDir  :=  routes [ i ] . directive ,  routes [ j ] . directive  
			
		
	
		
			
				
							if  iDir  ==  jDir  {  
			
		
	
		
			
				
								// directives are the same; sub-sort by path matcher length
  
			
		
	
		
			
				
								// if there's only one matcher set and one path (common case)
  
			
		
	
		
			
				
								iRoute ,  ok  :=  routes [ i ] . Value . ( caddyhttp . Route )  
			
		
	
		
			
				
								if  ! ok  {  
			
		
	
		
			
				
									return  false  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								jRoute ,  ok  :=  routes [ j ] . Value . ( caddyhttp . Route )  
			
		
	
		
			
				
								if  ! ok  {  
			
		
	
		
			
				
									return  false  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
							if  iDir  !=  jDir  {  
			
		
	
		
			
				
								return  dirPositions [ iDir ]  <  dirPositions [ jDir ]  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								// use already-decoded matcher, or decode if it's the first time seeing it
  
			
		
	
		
			
				
								iPM ,  jPM  :=  decodedMatchers [ i ] ,  decodedMatchers [ j ]  
			
		
	
		
			
				
								if  iPM  ==  nil  &&  len ( iRoute . MatcherSetsRaw )  ==  1  {  
			
		
	
		
			
				
									var  pathMatcher  caddyhttp . MatchPath  
			
		
	
		
			
				
									_  =  json . Unmarshal ( iRoute . MatcherSetsRaw [ 0 ] [ "path" ] ,  & pathMatcher )  
			
		
	
		
			
				
									decodedMatchers [ i ]  =  pathMatcher  
			
		
	
		
			
				
									iPM  =  pathMatcher  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								if  jPM  ==  nil  &&  len ( jRoute . MatcherSetsRaw )  ==  1  {  
			
		
	
		
			
				
									var  pathMatcher  caddyhttp . MatchPath  
			
		
	
		
			
				
									_  =  json . Unmarshal ( jRoute . MatcherSetsRaw [ 0 ] [ "path" ] ,  & pathMatcher )  
			
		
	
		
			
				
									decodedMatchers [ j ]  =  pathMatcher  
			
		
	
		
			
				
									jPM  =  pathMatcher  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
							// directives are the same; sub-sort by path matcher length if there's
  
			
		
	
		
			
				
							// only one matcher set and one path (this is a very common case and
  
			
		
	
		
			
				
							// usually -- but not always -- helpful/expected, oh well; user can
  
			
		
	
		
			
				
							// always take manual control of order using handler or route blocks)
  
			
		
	
		
			
				
							iRoute ,  ok  :=  routes [ i ] . Value . ( caddyhttp . Route )  
			
		
	
		
			
				
							if  ! ok  {  
			
		
	
		
			
				
								return  false  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							jRoute ,  ok  :=  routes [ j ] . Value . ( caddyhttp . Route )  
			
		
	
		
			
				
							if  ! ok  {  
			
		
	
		
			
				
								return  false  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								// sort by longer path (more specific) first; missing
  
			
		
	
		
			
				
								// path matchers are treated as zero-length paths
  
			
		
	
		
			
				
								var  iPathLen ,  jPathLen  int  
			
		
	
		
			
				
								if  iPM  !=  nil  {  
			
		
	
		
			
				
									iPathLen  =  len ( iPM [ 0 ] )  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								if  jPM  !=  nil  {  
			
		
	
		
			
				
									jPathLen  =  len ( jPM [ 0 ] )  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								return  iPathLen  >  jPathLen  
			
		
	
		
			
				
							// decode the path matchers, if there is just one of them
  
			
		
	
		
			
				
							var  iPM ,  jPM  caddyhttp . MatchPath  
			
		
	
		
			
				
							if  len ( iRoute . MatcherSetsRaw )  ==  1  {  
			
		
	
		
			
				
								_  =  json . Unmarshal ( iRoute . MatcherSetsRaw [ 0 ] [ "path" ] ,  & iPM )  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							if  len ( jRoute . MatcherSetsRaw )  ==  1  {  
			
		
	
		
			
				
								_  =  json . Unmarshal ( jRoute . MatcherSetsRaw [ 0 ] [ "path" ] ,  & jPM )  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							return  dirPositions [ iDir ]  <  dirPositions [ jDir ]  
			
		
	
		
			
				
							// sort by longer path (more specific) first; missing path
  
			
		
	
		
			
				
							// matchers or multi-matchers are treated as zero-length paths
  
			
		
	
		
			
				
							var  iPathLen ,  jPathLen  int  
			
		
	
		
			
				
							if  len ( iPM )  >  0  {  
			
		
	
		
			
				
								iPathLen  =  len ( iPM [ 0 ] )  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							if  len ( jPM )  >  0  {  
			
		
	
		
			
				
								jPathLen  =  len ( jPM [ 0 ] )  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							return  iPathLen  >  jPathLen  
			
		
	
		
			
				
						} )  
			
		
	
		
			
				
					}