@@ -2,6 +2,8 @@ package handlers
22
33import (
44 "net/http"
5+ "sort"
6+ "strings"
57 "sync"
68
79 "github.com/elazarl/goproxy"
@@ -65,6 +67,12 @@ func NewTerraformRegistryHandler(credentials config.Credentials) *TerraformRegis
6567 }
6668 handler .credentials = append (handler .credentials , terraformCred )
6769 }
70+
71+ // Sort credentials by URL path length descending (longest first)
72+ sort .Slice (handler .credentials , func (i , j int ) bool {
73+ return len (handler .credentials [i ].url ) > len (handler .credentials [j ].url )
74+ })
75+
6876 return & handler
6977}
7078
@@ -80,7 +88,7 @@ func (h *TerraformRegistryHandler) HandleRequest(request *http.Request, context
8088
8189 // Fall back to static credentials
8290 for _ , cred := range h .credentials {
83- if ! helpers . UrlMatchesRequest (request , cred .url , true ) && ! helpers .CheckHost (request , cred .host ) {
91+ if ! urlMatchesRequestWithBoundary (request , cred .url ) && ! helpers .CheckHost (request , cred .host ) {
8492 continue
8593 }
8694
@@ -91,3 +99,53 @@ func (h *TerraformRegistryHandler) HandleRequest(request *http.Request, context
9199
92100 return request , nil
93101}
102+
103+ // urlMatchesRequestWithBoundary checks if the request URL matches the credential URL
104+ // with proper path boundary checking.
105+ func urlMatchesRequestWithBoundary (request * http.Request , credURL string ) bool {
106+ if credURL == "" {
107+ return false
108+ }
109+
110+ parsedURL , err := helpers .ParseURLLax (credURL )
111+ if err != nil {
112+ return false
113+ }
114+
115+ if ! helpers .AreHostnamesEqual (parsedURL .Hostname (), request .URL .Hostname ()) {
116+ return false
117+ }
118+
119+ urlPort := parsedURL .Port ()
120+ if urlPort == "" {
121+ urlPort = "443"
122+ }
123+
124+ reqPort := request .URL .Port ()
125+ if reqPort == "" {
126+ reqPort = "443"
127+ }
128+
129+ if urlPort != reqPort {
130+ return false
131+ }
132+
133+ credPath := strings .TrimRight (parsedURL .Path , "/" )
134+ reqPath := request .URL .Path
135+
136+ if credPath == "" {
137+ // Empty path matches everything on the host
138+ return true
139+ }
140+
141+ if reqPath == credPath {
142+ return true
143+ }
144+
145+ // Check if request path starts with credPath followed by /
146+ if strings .HasPrefix (reqPath , credPath + "/" ) {
147+ return true
148+ }
149+
150+ return false
151+ }
0 commit comments