Skip to content

Commit c9d31dc

Browse files
authored
Fixes for handling XML content (Azure#17578)
1 parent 314636d commit c9d31dc

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

sdk/azcore/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
### Breaking Changes
88

99
### Bugs Fixed
10+
* Include XML header when marshalling XML content.
11+
* Handle XML namespaces when searching for error code.
1012

1113
### Other Changes
1214

sdk/azcore/internal/shared/response_error.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func extractErrorCodeJSON(body []byte) string {
7575

7676
func extractErrorCodeXML(body []byte) string {
7777
// regular expression is much easier than dealing with the XML parser
78-
rx := regexp.MustCompile(`<[c|C]ode>\s*(\w+)\s*<\/[c|C]ode>`)
78+
rx := regexp.MustCompile(`<(?:\w+:)?[c|C]ode>\s*(\w+)\s*<\/(?:\w+:)?[c|C]ode>`)
7979
res := rx.FindStringSubmatch(string(body))
8080
if len(res) != 2 {
8181
return ""

sdk/azcore/internal/shared/response_error_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,43 @@ ERROR CODE: ContainerAlreadyExists
348348
}
349349
}
350350

351+
func TestNewResponseErrorErrorCodeHeaderXMLWithNamespace(t *testing.T) {
352+
fakeURL, err := url.Parse("https://fakeurl.com/the/path?qp=removed")
353+
if err != nil {
354+
t.Fatal(err)
355+
}
356+
respHeader := http.Header{}
357+
respHeader.Set("x-ms-error-code", "ContainerAlreadyExists")
358+
err = NewResponseError(&http.Response{
359+
Status: "the system is down",
360+
StatusCode: http.StatusInternalServerError,
361+
Header: respHeader,
362+
Body: io.NopCloser(strings.NewReader(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><m:Error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:Code>ContainerAlreadyExists</m:Code><m:Message>The specified container already exists.\nRequestId:73b2473b-c1c8-4162-97bb-dc171bff61c9\nTime:2021-12-13T19:45:40.679Z</m:Message></m:Error>`)),
363+
Request: &http.Request{
364+
Method: http.MethodGet,
365+
URL: fakeURL,
366+
},
367+
})
368+
re, ok := err.(*ResponseError)
369+
if !ok {
370+
t.Fatalf("unexpected error type %T", err)
371+
}
372+
if c := re.StatusCode; c != http.StatusInternalServerError {
373+
t.Fatalf("unexpected status code %d", c)
374+
}
375+
const want = `GET https://fakeurl.com/the/path
376+
--------------------------------------------------------------------------------
377+
RESPONSE 500: the system is down
378+
ERROR CODE: ContainerAlreadyExists
379+
--------------------------------------------------------------------------------
380+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><m:Error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:Code>ContainerAlreadyExists</m:Code><m:Message>The specified container already exists.\nRequestId:73b2473b-c1c8-4162-97bb-dc171bff61c9\nTime:2021-12-13T19:45:40.679Z</m:Message></m:Error>
381+
--------------------------------------------------------------------------------
382+
`
383+
if got := re.Error(); got != want {
384+
t.Fatalf("\ngot:\n%s\nwant:\n%s\n", got, want)
385+
}
386+
}
387+
351388
func TestNewResponseErrorAllMissingXML(t *testing.T) {
352389
fakeURL, err := url.Parse("https://fakeurl.com/the/path?qp=removed")
353390
if err != nil {

sdk/azcore/runtime/request.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ func MarshalAsXML(req *policy.Request, v interface{}) error {
106106
if err != nil {
107107
return fmt.Errorf("error marshalling type %T: %s", v, err)
108108
}
109+
// inclue the XML header as some services require it
110+
b = []byte(xml.Header + string(b))
109111
return req.SetBody(shared.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppXML)
110112
}
111113

0 commit comments

Comments
 (0)