11package authz
22
33import (
4+ "context"
45 "encoding/json"
56 "fmt"
67 "net"
@@ -11,7 +12,6 @@ import (
1112 "strings"
1213
1314 "github.com/cesanta/glog"
14- "github.com/schwarmco/go-cartesian-product"
1515
1616 "github.com/cesanta/docker_auth/auth_server/api"
1717)
@@ -180,21 +180,63 @@ func matchStringWithLabelPermutations(pp *string, s string, vars []string, label
180180 }
181181 }
182182 if len (labelSets ) > 0 {
183- for permuation := range cartesian .Iter (labelSets ... ) {
183+ ctx , cancel := context .WithCancel (context .Background ())
184+ defer cancel ()
185+
186+ for permuation := range IterWithContext (ctx , labelSets ... ) {
184187 var labelVars []string
185188 for _ , val := range permuation {
186189 labelVars = append (labelVars , val .([]string )... )
187190 }
188191 matched = matchString (pp , s , append (vars , labelVars ... ))
189192 if matched {
190- break
193+ return matched
191194 }
192195 }
193196 }
194197 }
195198 return matched
196199}
197200
201+ func IterWithContext (ctx context.Context , params ... []interface {}) <- chan []interface {} {
202+ c := make (chan []interface {})
203+
204+ if len (params ) == 0 {
205+ close (c )
206+ return c
207+ }
208+
209+ go func () {
210+ defer close (c ) // Ensure the channel is closed when the goroutine exits
211+
212+ iterate (ctx , c , params [0 ], []interface {}{}, params [1 :]... )
213+ }()
214+
215+ return c
216+ }
217+
218+ func iterate (ctx context.Context , channel chan []interface {}, topLevel , result []interface {}, needUnpacking ... []interface {}) {
219+ if len (needUnpacking ) == 0 {
220+ for _ , p := range topLevel {
221+ select {
222+ case <- ctx .Done ():
223+ return // Exit if the context is canceled
224+ case channel <- append (append ([]interface {}{}, result ... ), p ):
225+ }
226+ }
227+ return
228+ }
229+
230+ for _ , p := range topLevel {
231+ select {
232+ case <- ctx .Done ():
233+ return // Exit if the context is canceled
234+ default :
235+ iterate (ctx , channel , needUnpacking [0 ], append (result , p ), needUnpacking [1 :]... )
236+ }
237+ }
238+ }
239+
198240func matchIP (ipp * string , ip net.IP ) bool {
199241 if ipp == nil {
200242 return true
0 commit comments