Skip to content

Commit a9b7701

Browse files
authored
Allow passing custom get query params (#1905)
Allow checking if a query param starts with "x-" which is documented by Amazon as a parameter S3 will ignore and recommended as a way to add custom info to server access logs. Allow GetObject calls to set custom query parameters if they want.
1 parent db8fd75 commit a9b7701

File tree

4 files changed

+75
-4
lines changed

4 files changed

+75
-4
lines changed

api-get-options.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ func (o *GetObjectOptions) Set(key, value string) {
8787
}
8888

8989
// SetReqParam - set request query string parameter
90-
// supported key: see supportedQueryValues.
90+
// supported key: see supportedQueryValues and allowedCustomQueryPrefix.
9191
// If an unsupported key is passed in, it will be ignored and nothing will be done.
9292
func (o *GetObjectOptions) SetReqParam(key, value string) {
93-
if !isStandardQueryValue(key) {
93+
if !isCustomQueryValue(key) && !isStandardQueryValue(key) {
9494
// do nothing
9595
return
9696
}
@@ -101,10 +101,10 @@ func (o *GetObjectOptions) SetReqParam(key, value string) {
101101
}
102102

103103
// AddReqParam - add request query string parameter
104-
// supported key: see supportedQueryValues.
104+
// supported key: see supportedQueryValues and allowedCustomQueryPrefix.
105105
// If an unsupported key is passed in, it will be ignored and nothing will be done.
106106
func (o *GetObjectOptions) AddReqParam(key, value string) {
107-
if !isStandardQueryValue(key) {
107+
if !isCustomQueryValue(key) && !isStandardQueryValue(key) {
108108
// do nothing
109109
return
110110
}

get-options_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,45 @@ func TestSetHeader(t *testing.T) {
5757
}
5858
}
5959
}
60+
61+
func TestCustomQueryParameters(t *testing.T) {
62+
var (
63+
paramKey = "x-test-param"
64+
paramValue = "test-value"
65+
66+
invalidParamKey = "invalid-test-param"
67+
invalidParamValue = "invalid-test-param"
68+
)
69+
70+
testCases := []struct {
71+
setParamsFunc func(o *GetObjectOptions)
72+
}{
73+
{func(o *GetObjectOptions) {
74+
o.AddReqParam(paramKey, paramValue)
75+
o.AddReqParam(invalidParamKey, invalidParamValue)
76+
}},
77+
{func(o *GetObjectOptions) {
78+
o.SetReqParam(paramKey, paramValue)
79+
o.SetReqParam(invalidParamKey, invalidParamValue)
80+
}},
81+
}
82+
83+
for i, testCase := range testCases {
84+
opts := GetObjectOptions{}
85+
testCase.setParamsFunc(&opts)
86+
87+
// This and the following checks indirectly ensure that only the expected
88+
// valid header is added.
89+
if len(opts.reqParams) != 1 {
90+
t.Errorf("Test %d: Expected 1 kv-pair in query parameters, got %v", i+1, len(opts.reqParams))
91+
}
92+
93+
if v, ok := opts.reqParams[paramKey]; !ok {
94+
t.Errorf("Test %d: Expected query parameter with key %s missing", i+1, paramKey)
95+
} else if len(v) != 1 {
96+
t.Errorf("Test %d: Expected 1 value for query parameter with key %s, got %d values", i+1, paramKey, len(v))
97+
} else if v[0] != paramValue {
98+
t.Errorf("Test %d: Expected query value %s for key %s, got %s", i+1, paramValue, paramKey, v[0])
99+
}
100+
}
101+
}

utils.go

+8
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ func isStandardQueryValue(qsKey string) bool {
528528
return supportedQueryValues[qsKey]
529529
}
530530

531+
// Per documentation at https://docs.aws.amazon.com/AmazonS3/latest/userguide/LogFormat.html#LogFormatCustom, the
532+
// set of query params starting with "x-" are ignored by S3.
533+
const allowedCustomQueryPrefix = "x-"
534+
535+
func isCustomQueryValue(qsKey string) bool {
536+
return strings.HasPrefix(qsKey, allowedCustomQueryPrefix)
537+
}
538+
531539
var (
532540
md5Pool = sync.Pool{New: func() interface{} { return md5.New() }}
533541
sha256Pool = sync.Pool{New: func() interface{} { return sha256.New() }}

utils_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,24 @@ func TestIsAmzHeader(t *testing.T) {
408408
}
409409
}
410410
}
411+
412+
// Tests if query parameter starts with "x-" and will be ignored by S3.
413+
func TestIsCustomQueryValue(t *testing.T) {
414+
testCases := []struct {
415+
// Input.
416+
queryParamKey string
417+
// Expected result.
418+
expectedValue bool
419+
}{
420+
{"x-custom-key", true},
421+
{"xcustom-key", false},
422+
{"random-header", false},
423+
}
424+
425+
for i, testCase := range testCases {
426+
actual := isCustomQueryValue(testCase.queryParamKey)
427+
if actual != testCase.expectedValue {
428+
t.Errorf("Test %d: Expected to pass, but failed", i+1)
429+
}
430+
}
431+
}

0 commit comments

Comments
 (0)