use correct xml package for custom MarshalXML() (#16421)

This commit is contained in:
Harshavardhana 2023-01-17 05:08:33 +05:30 committed by GitHub
parent 5a9f7516d6
commit 3db658e51e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 15 deletions

View File

@ -20,6 +20,7 @@ package cmd
import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
"net/url"
@ -64,15 +65,31 @@ func setCommonHeaders(w http.ResponseWriter) {
// Encodes the response headers into XML format.
func encodeResponse(response interface{}) []byte {
var bytesBuffer bytes.Buffer
bytesBuffer.WriteString(xxml.Header)
buf, err := xxml.Marshal(response)
if err != nil {
var buf bytes.Buffer
buf.WriteString(xml.Header)
if err := xml.NewEncoder(&buf).Encode(response); err != nil {
logger.LogIf(GlobalContext, err)
return nil
}
bytesBuffer.Write(buf)
return bytesBuffer.Bytes()
return buf.Bytes()
}
// Use this encodeResponseList() to support control characters
// this function must be used by only ListObjects() for objects
// with control characters, this is a specialized extension
// to support AWS S3 compatible behavior.
//
// Do not use this function for anything other than ListObjects()
// variants, please open a github discussion if you wish to use
// this in other places.
func encodeResponseList(response interface{}) []byte {
var buf bytes.Buffer
buf.WriteString(xxml.Header)
if err := xxml.NewEncoder(&buf).Encode(response); err != nil {
logger.LogIf(GlobalContext, err)
return nil
}
return buf.Bytes()
}
// Encodes the response headers into JSON format.

View File

@ -314,12 +314,12 @@ func (s *Metadata) Set(k, v string) {
}
type xmlKeyEntry struct {
XMLName xml.Name
XMLName xxml.Name
Value string `xml:",chardata"`
}
// MarshalXML - StringMap marshals into XML.
func (s *Metadata) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
func (s *Metadata) MarshalXML(e *xxml.Encoder, start xxml.StartElement) error {
if s == nil {
return nil
}
@ -334,7 +334,7 @@ func (s *Metadata) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
for _, item := range s.Items {
if err := e.Encode(xmlKeyEntry{
XMLName: xml.Name{Local: item.Key},
XMLName: xxml.Name{Local: item.Key},
Value: item.Value,
}); err != nil {
return err

View File

@ -115,7 +115,7 @@ func (api objectAPIHandlers) ListObjectVersionsHandler(w http.ResponseWriter, r
response := generateListVersionsResponse(bucket, prefix, marker, versionIDMarker, delimiter, encodingType, maxkeys, listObjectVersionsInfo)
// Write success response.
writeSuccessResponseXML(w, encodeResponse(response))
writeSuccessResponseXML(w, encodeResponseList(response))
}
// ListObjectsV2MHandler - GET Bucket (List Objects) Version 2 with metadata.
@ -185,7 +185,7 @@ func (api objectAPIHandlers) ListObjectsV2MHandler(w http.ResponseWriter, r *htt
maxKeys, listObjectsV2Info.Objects, listObjectsV2Info.Prefixes, true)
// Write success response.
writeSuccessResponseXML(w, encodeResponse(response))
writeSuccessResponseXML(w, encodeResponseList(response))
}
// ListObjectsV2Handler - GET Bucket (List Objects) Version 2.
@ -260,7 +260,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
maxKeys, listObjectsV2Info.Objects, listObjectsV2Info.Prefixes, false)
// Write success response.
writeSuccessResponseXML(w, encodeResponse(response))
writeSuccessResponseXML(w, encodeResponseList(response))
}
func parseRequestToken(token string) (subToken string, nodeIndex int) {
@ -357,5 +357,5 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
response := generateListObjectsV1Response(bucket, prefix, marker, delimiter, encodingType, maxKeys, listObjectsInfo)
// Write success response.
writeSuccessResponseXML(w, encodeResponse(response))
writeSuccessResponseXML(w, encodeResponseList(response))
}

View File

@ -23,7 +23,10 @@ import (
)
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
const iso8601TimeFormat = "2006-01-02T15:04:05.000Z" // Reply date format with nanosecond precision.
const (
iso8601TimeFormat = "2006-01-02T15:04:05.000Z" // Reply date format with millisecond precision.
iso8601TimeFormatLong = "2006-01-02T15:04:05.000000Z" // Reply date format with nanosecond precision.
)
// ISO8601Format converts time 't' into ISO8601 time format expected in AWS S3 spec.
//
@ -43,6 +46,7 @@ func ISO8601Format(t time.Time) string {
func ISO8601Parse(iso8601 string) (t time.Time, err error) {
for _, layout := range []string{
iso8601TimeFormat,
iso8601TimeFormatLong,
time.RFC3339,
} {
t, err = time.Parse(layout, iso8601)

View File

@ -320,7 +320,7 @@ func (rDate *RetentionDate) UnmarshalXML(d *xml.Decoder, startElement xml.StartE
// MarshalXML encodes expiration date if it is non-zero and encodes
// empty string otherwise
func (rDate *RetentionDate) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
func (rDate RetentionDate) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
if rDate.IsZero() {
return nil
}