Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate {application,text}/xml headers on gateway by client's choice #992

Merged
merged 4 commits into from
Dec 8, 2020

Conversation

arielshaqed
Copy link
Contributor

If no header is specified, none is explicitly generated. Then the Go http server generates
one by scanning content, it happens to be text/xml. If either of these headers is
specified, generate that requested content type. If (only) other headers are generated,
respond "Not Acceptable".

This does not break backwards compatibility with clients that do not generate such a
header (boto, mc). This should improve compatibility with a client that explicitly asks for
application/xml (the Akka S3 client alpakka only accepts that Content-Type, so it had better
ask for it). It will break a lying client that requests only anything-but-standard-XML.

If no header is specified, none is explicitly generated.  Then the Go http server generates
one by scanning content, it happens to be text/xml.  If either of these headers is
specified, generate that requested content type.  If (only) other headers are generated,
respond "Not Acceptable".

This does not break backwards compatibility with clients that do not generate such a
header (boto, mc).  This should improve compatibility with a client that explicitly asks for
application/xml (the Akka S3 client alpakka only accepts that Content-Type, so it had better
ask for it).  It *will* break a lying client that requests only anything-but-standard-XML.
@arielshaqed arielshaqed requested a review from johnnyaug December 3, 2020 08:50
@arielshaqed
Copy link
Contributor Author

Tested by capturing traffic (from the minio/mc client) to our gateway and adding various Accept: header values. (The AWS sigv4 security protocol allows replays, that is so very useful for testing, if horribly badly wrong for actual security...)

Should fix #987 , but ideally wait for customer confirmation that it does before pulling :-)

@arielshaqed
Copy link
Contributor Author

@keimoon could you please take a look, too, and see whether this PR would fix your issue?

@codecov-io
Copy link

codecov-io commented Dec 3, 2020

Codecov Report

Merging #992 (7d4b24e) into master (a57e068) will increase coverage by 0.46%.
The diff coverage is 17.39%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #992      +/-   ##
==========================================
+ Coverage   44.26%   44.72%   +0.46%     
==========================================
  Files         140      147       +7     
  Lines       11570    11869     +299     
==========================================
+ Hits         5121     5308     +187     
- Misses       5799     5879      +80     
- Partials      650      682      +32     
Impacted Files Coverage Δ
gateway/operations/base.go 0.00% <0.00%> (ø)
gateway/operations/getobject.go 0.00% <0.00%> (ø)
gateway/operations/headobject.go 0.00% <0.00%> (ø)
gateway/handler.go 57.23% <26.66%> (-1.55%) ⬇️
catalog/mvcc/cataloger_create_repository.go 59.25% <0.00%> (-3.71%) ⬇️
catalog/mvcc/cataloger_list_entries.go 85.21% <0.00%> (-0.32%) ⬇️
pyramid/file.go 76.47% <0.00%> (ø)
graveler/graveler.go 0.00% <0.00%> (ø)
pyramid/ro_file.go 71.42% <0.00%> (ø)
graveler/staging_iterator.go 81.08% <0.00%> (ø)
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a57e068...7d4b24e. Read the comment docs.

@keimoon
Copy link

keimoon commented Dec 3, 2020

Unfortunately, alpakka does not send Accept header so this fix does not work for us. Currently we are using an work around (proxy the response to replace the response header) to overcome this issue.

johnnyaug
johnnyaug previously approved these changes Dec 3, 2020
Matches behavipours of S3 (verified by @ozkatz on encrypted with Postman) and
minio (verified on plaintext with Wireshark)
@arielshaqed
Copy link
Contributor Author

Thanks! Also need to set the default to application/xml because @keimoon points out the Alpakka client doesn't pass an Accepts: header. Turns out that passing this header just doesn't happen in the world of S3 clients. Since S3 and Minio both seem happy to return application/xml, go with that.

@@ -358,6 +385,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
start := time.Now()
mrw := httputil.NewMetricResponseWriter(w)
setContentType(mrw, r)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this return application/xml for non-xml responses? (i.e. GetObject?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this return application/xml for non-xml responses? (i.e. GetObject?)

Ouch, good catch! I'll need to figure out how to make go-swagger prefer application/xml :-(

@arielshaqed arielshaqed requested a review from johnnyaug December 6, 2020 11:52
@arielshaqed
Copy link
Contributor Author

Dismissed reviews because of Oz' issue with adding content types to files and heads from the backing store. Will re-request soon(-ish).

All S3 gateway responses are application/xml, except when replying with contents from
adapter.  There keep the existing behaviour (Go http content type detection).  We can
add content-type forwarding to all our adapters, but that would be a separate change.
Files returned from get-object keep their original Content-Type - auto-detected right
now, but may change to forward from the block adapter if we decide to be more like S3
(in response to customer demand).

Honour an Accepts header *if present*, allowing a client to prefer text/xml.  Accepts
headers are not usefully relevant to get-object, and continue to be ignored.
@arielshaqed arielshaqed force-pushed the feature/987-return-acceptable-content-type branch from 63fb096 to 7d4b24e Compare December 6, 2020 16:13
@arielshaqed arielshaqed requested a review from ozkatz December 6, 2020 16:13
@arielshaqed
Copy link
Contributor Author

@johnnyaug @ozkatz PTAL, I cleaned up behaviour of Accepts:, get-object is back to ignoring everything except the auto-detected content-type.

if ok {
defaultContentType := selectContentType(acceptable)
// No requested content type matched. This is OK at least for a GET or
// HEAD, so set up to auto-detect.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrase comment, or put it somewhere else

w.Header().Set("Content-Type", *defaultContentType)
}
} else {
// For all proxied content the type will be reset according to whatever headers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also rephrase to clarify how this comment is related to this code

@arielshaqed
Copy link
Contributor Author

@ozkatz are we good to go with this?

Copy link
Collaborator

@ozkatz ozkatz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good!

@arielshaqed
Copy link
Contributor Author

Thanks!

@arielshaqed arielshaqed merged commit 68cdf0c into master Dec 8, 2020
@arielshaqed arielshaqed deleted the feature/987-return-acceptable-content-type branch December 8, 2020 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants