Skip to content

Commit 7c8d391

Browse files
authored
Merge pull request #4375 from shuqz/shuqz-fix-parser-comma
support comma in string pars value
2 parents 650fb5a + f7296d3 commit 7c8d391

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

docs/guide/ingress/annotations.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,15 @@ Custom attributes to LoadBalancers and TargetGroups can be controlled with follo
965965
```
966966
alb.ingress.kubernetes.io/listener-attributes.HTTP-80: routing.http.response.server.enabled=true
967967
```
968+
- Add Access-Control-Allow-Headers header value (with comma)
969+
```
970+
alb.ingress.kubernetes.io/listener-attributes.HTTPS-443: "routing.http.response.access_control_allow_headers.header_value=exampleValue\\,anotherExampleValue"
971+
```
972+
or
973+
```
974+
alb.ingress.kubernetes.io/listener-attributes.HTTPS-443: routing.http.response.access_control_allow_headers.header_value=exampleValue\,anotherExampleValue
975+
```
976+
both result Access-Control-Allow-Headers header value: exampleValue,anotherExampleValue
968977
969978
970979
## Resource Tags

pkg/annotations/parser.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package annotations
33
import (
44
"encoding/json"
55
"fmt"
6-
"github.com/pkg/errors"
76
"strconv"
87
"strings"
8+
9+
"github.com/pkg/errors"
910
)
1011

1112
type ParseOptions struct {
@@ -151,15 +152,15 @@ func (p *suffixAnnotationParser) ParseStringMapAnnotation(annotation string, val
151152
if !exists {
152153
return false, nil
153154
}
154-
rawKVPairs := splitCommaSeparatedString(raw)
155+
rawKVPairs := splitKeyValuePairs(raw)
155156
keyValues := make(map[string]string)
156157
for _, kvPair := range rawKVPairs {
157158
parts := strings.SplitN(kvPair, "=", 2)
158159
if len(parts) != 2 {
159160
return false, errors.Errorf("failed to parse stringMap annotation, %v: %v", matchedKey, raw)
160161
}
161-
key := parts[0]
162-
value := parts[1]
162+
key := strings.TrimSpace(parts[0])
163+
value := strings.TrimSpace(parts[1])
163164
if len(key) == 0 {
164165
return false, errors.Errorf("failed to parse stringMap annotation, %v: %v", matchedKey, raw)
165166
}
@@ -212,3 +213,41 @@ func splitCommaSeparatedString(commaSeparatedString string) []string {
212213
}
213214
return result
214215
}
216+
217+
// splitKeyValuePairs this function supports escaped comma
218+
func splitKeyValuePairs(s string) []string {
219+
var result []string
220+
var currentString strings.Builder
221+
222+
for i := 0; i < len(s); i++ {
223+
if s[i] == '\\' && i+1 < len(s) {
224+
// Escape sequence - add the escaped character literally
225+
currentString.WriteByte(s[i+1])
226+
i++ // skip the escaped character
227+
} else if s[i] == ',' {
228+
// Check if next part contains '=' (a new key-value pair)
229+
remaining := strings.TrimSpace(s[i+1:])
230+
containsEqual := strings.Index(remaining, "=")
231+
if containsEqual != -1 {
232+
result = append(result, strings.TrimSpace(currentString.String()))
233+
currentString.Reset()
234+
} else if len(remaining) > 0 {
235+
// There's content after comma but no '=' - this is malformed
236+
// Add current content and the malformed part as separate items
237+
result = append(result, strings.TrimSpace(currentString.String()))
238+
result = append(result, remaining)
239+
return result
240+
} else {
241+
// Empty after comma, add comma to current
242+
currentString.WriteByte(s[i])
243+
}
244+
} else {
245+
currentString.WriteByte(s[i])
246+
}
247+
}
248+
249+
if currentString.Len() > 0 {
250+
result = append(result, strings.TrimSpace(currentString.String()))
251+
}
252+
return result
253+
}

pkg/annotations/parser_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package annotations
22

33
import (
44
"errors"
5-
"github.com/stretchr/testify/assert"
65
"testing"
6+
7+
"github.com/stretchr/testify/assert"
78
)
89

910
func Test_annotationParser_ParseStringAnnotation(t *testing.T) {
@@ -278,6 +279,22 @@ func Test_serviceAnnotationParser_ParseStringMapAnnotation(t *testing.T) {
278279
"key4/empty-value": "",
279280
},
280281
},
282+
{
283+
name: "multiple values",
284+
prefix: "p.co",
285+
suffix: "sfx",
286+
annotations: map[string]string{
287+
"first-value": "1",
288+
"p.co/sfx": "key1=value1\\,valueOne, key2= value2, key3/with-slash=value3\\,valueThree, key4/empty-value=",
289+
},
290+
wantExist: true,
291+
wantValue: map[string]string{
292+
"key1": "value1,valueOne",
293+
"key2": "value2",
294+
"key3/with-slash": "value3,valueThree",
295+
"key4/empty-value": "",
296+
},
297+
},
281298
{
282299
name: "values containing equals sign",
283300
prefix: "prefix",

0 commit comments

Comments
 (0)