Skip to content

Commit ced715f

Browse files
author
Steven Yuan
authored
Revert "Deprecate url path cleaning during http request serialization" (#4849)
* Revert "Deprecate url path cleaning during http request serialization"
1 parent 17200eb commit ced715f

File tree

4 files changed

+46
-52
lines changed

4 files changed

+46
-52
lines changed

CHANGELOG_PENDING.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
### SDK Enhancements
44

55
### SDK Bugs
6+
* `rest`: Revert removing unnecessary path normalization behavior.
7+
* This behavior would mutate request paths with URI-encoded characters, potentially resulting in misrouted requests.
8+
* `config`: Revert deprecating `DisableRestProtocolURICleaning` config setting.
9+
* This setting will have an effect again. REST-protocol paths will now be normalized after serialization.

aws/config.go

+16-5
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,19 @@ type Config struct {
252252
// and specify a Retryer instead.
253253
SleepDelay func(time.Duration)
254254

255-
// Deprecated: This setting no longer has any effect.
256-
// RESTful paths are no longer cleaned after request serialization.
255+
// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
256+
// Will default to false. This would only be used for empty directory names in s3 requests.
257+
//
258+
// Example:
259+
// sess := session.Must(session.NewSession(&aws.Config{
260+
// DisableRestProtocolURICleaning: aws.Bool(true),
261+
// }))
262+
//
263+
// svc := s3.New(sess)
264+
// out, err := svc.GetObject(&s3.GetObjectInput {
265+
// Bucket: aws.String("bucketname"),
266+
// Key: aws.String("//foo//bar//moo"),
267+
// })
257268
DisableRestProtocolURICleaning *bool
258269

259270
// EnableEndpointDiscovery will allow for endpoint discovery on operations that
@@ -486,8 +497,8 @@ func (c *Config) WithLowerCaseHeaderMaps(t bool) *Config {
486497
return c
487498
}
488499

489-
// Deprecated: This setting no longer has any effect.
490-
// RESTful paths are no longer cleaned after request serialization.
500+
// WithDisableRestProtocolURICleaning sets a config DisableRestProtocolURICleaning value
501+
// returning a Config pointer for chaining.
491502
func (c *Config) WithDisableRestProtocolURICleaning(t bool) *Config {
492503
c.DisableRestProtocolURICleaning = &t
493504
return c
@@ -600,7 +611,7 @@ func mergeInConfig(dst *Config, other *Config) {
600611
if other.DisableRestProtocolURICleaning != nil {
601612
dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
602613
}
603-
614+
604615
if other.EnforceShouldRetryCheck != nil {
605616
dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
606617
}

private/protocol/rest/build.go

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"math"
1010
"net/http"
1111
"net/url"
12+
"path"
1213
"reflect"
1314
"strconv"
1415
"strings"
@@ -133,6 +134,9 @@ func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bo
133134
}
134135

135136
r.HTTPRequest.URL.RawQuery = query.Encode()
137+
if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) {
138+
cleanPath(r.HTTPRequest.URL)
139+
}
136140
}
137141

138142
func buildBody(r *request.Request, v reflect.Value) {
@@ -240,6 +244,19 @@ func buildQueryString(query url.Values, v reflect.Value, name string, tag reflec
240244
return nil
241245
}
242246

247+
func cleanPath(u *url.URL) {
248+
hasSlash := strings.HasSuffix(u.Path, "/")
249+
250+
// clean up path, removing duplicate `/`
251+
u.Path = path.Clean(u.Path)
252+
u.RawPath = path.Clean(u.RawPath)
253+
254+
if hasSlash && !strings.HasSuffix(u.Path, "/") {
255+
u.Path += "/"
256+
u.RawPath += "/"
257+
}
258+
}
259+
243260
// EscapePath escapes part of a URL path in Amazon style
244261
func EscapePath(path string, encodeSep bool) string {
245262
var buf bytes.Buffer

private/protocol/rest/build_test.go

+9-47
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,17 @@ import (
1414
"github.com/aws/aws-sdk-go/aws/request"
1515
)
1616

17-
func TestBuildURI(t *testing.T) {
18-
cases := map[string]struct {
19-
Topic *string
20-
ExpectPath string
21-
ExpectRawPath string
22-
}{
23-
"path without prefix slash": {
24-
Topic: aws.String("devices/123/test"),
25-
ExpectPath: "/topics/devices/123/test",
26-
ExpectRawPath: "/topics/devices%2F123%2Ftest",
27-
},
28-
"path containing single prefix slashes": {
29-
Topic: aws.String("/devices/123/test"),
30-
ExpectPath: "/topics//devices/123/test",
31-
ExpectRawPath: "/topics/%2Fdevices%2F123%2Ftest",
32-
},
33-
"path containing prefix multi-slashes": {
34-
Topic: aws.String("///devices/123/test"),
35-
ExpectPath: "/topics////devices/123/test",
36-
ExpectRawPath: "/topics/%2F%2F%2Fdevices%2F123%2Ftest",
37-
},
17+
func TestCleanPath(t *testing.T) {
18+
uri := &url.URL{
19+
Path: "//foo//bar",
20+
Scheme: "https",
21+
Host: "host",
3822
}
23+
cleanPath(uri)
3924

40-
for _, c := range cases {
41-
uri := &url.URL{
42-
Path: "/topics/{topic}",
43-
Scheme: "https",
44-
Host: "host",
45-
}
46-
47-
req := &request.Request{
48-
HTTPRequest: &http.Request{
49-
URL: uri,
50-
},
51-
Params: &struct {
52-
Topic *string `location:"uri" locationName:"topic" type:"string" required:"true"`
53-
}{
54-
c.Topic,
55-
},
56-
}
57-
58-
Build(req)
59-
60-
if a, e := uri.Path, c.ExpectPath; a != e {
61-
t.Errorf("expect %q Path, got %q", e, a)
62-
}
63-
if a, e := uri.RawPath, c.ExpectRawPath; a != e {
64-
t.Errorf("expect %q RawPath, got %q", e, a)
65-
}
25+
expected := "https://host/foo/bar"
26+
if a, e := uri.String(), expected; a != e {
27+
t.Errorf("expect %q URI, got %q", e, a)
6628
}
6729
}
6830

0 commit comments

Comments
 (0)