1
1
package authz
2
2
3
3
import (
4
+ "context"
4
5
"encoding/json"
5
6
"fmt"
6
7
"net"
@@ -11,7 +12,6 @@ import (
11
12
"strings"
12
13
13
14
"github.com/cesanta/glog"
14
- "github.com/schwarmco/go-cartesian-product"
15
15
16
16
"github.com/cesanta/docker_auth/auth_server/api"
17
17
)
@@ -180,21 +180,63 @@ func matchStringWithLabelPermutations(pp *string, s string, vars []string, label
180
180
}
181
181
}
182
182
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 ... ) {
184
187
var labelVars []string
185
188
for _ , val := range permuation {
186
189
labelVars = append (labelVars , val .([]string )... )
187
190
}
188
191
matched = matchString (pp , s , append (vars , labelVars ... ))
189
192
if matched {
190
- break
193
+ return matched
191
194
}
192
195
}
193
196
}
194
197
}
195
198
return matched
196
199
}
197
200
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
+
198
240
func matchIP (ipp * string , ip net.IP ) bool {
199
241
if ipp == nil {
200
242
return true
0 commit comments