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

Add Prefer: return=minimal support #605

Merged
merged 8 commits into from
Aug 9, 2017
Merged

Add Prefer: return=minimal support #605

merged 8 commits into from
Aug 9, 2017

Conversation

garrensmith
Copy link
Member

Overview

Adding this header allows the client to request that only Non-Essential
or All headers are removed from the response. This will decrease the
size of the response.

The idea is to remove all headers that a non-browser client would not need.
I've had to leave Server header in otherwise Mochiweb adds its very lame/snarky header in its place.

There are two options Non-Essential which removes everything except caching headers. And then All which removes everything except Content-length, Content-Type, Server, Date.

Testing recommendations

curl -v --header "X-Couch-Exclude-Headers: Non-Essential" 'http://dev:5984/_all_dbs

GitHub issue number

This PR will be the number

Checklist

  • Code is written and works correctly;
  • Changes are covered by tests;
  • Documentation reflects the changes;



% List of essential headers for an http request. If we leave out server then Mochiweb adds in its default one
-define(ESSENTIAL_HEADERS, ["Cache-Control", "ETag", "Content-Type", "Content-Length", "Vary", "Server"]).
Copy link
Member

Choose a reason for hiding this comment

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

list these in alphabetical order.

Copy link
Member

Choose a reason for hiding this comment

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

and probably best to lay them out one line per header, so we can modify it over time.

Copy link
Member

Choose a reason for hiding this comment

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

perhaps it should even come from config?

@rnewson
Copy link
Member

rnewson commented Jun 21, 2017

forgot to add, the structure of the change looks good to me. My comments are mainly about configurability. I like the use of a custom header to modify the response, rather than a query parameter. The recommendation these days is not to add X- but there's so much precedence in CouchDB that it might be weird not to always have it. I do think the request header, and its permitted values, are a bit wordy at the same time as being a bit unclear. Perhaps if the filtering were controlled by config this problem goes away.

@garrensmith
Copy link
Member Author

Thanks @rnewson I've changed it to support using a config setting.

; List of headers that will be kept when the header option X-Couch-Exclude-Headers is included in a request
; 'X-Couch-Exclude-Headers' : "All"
all = Server
minimal = Cache-Control, Content-Length, Content-Type, ETag, Server, Vary
Copy link
Member

Choose a reason for hiding this comment

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

will need Transfer-Encoding and perhaps more

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I've added Content-Length, Content-Type and Transfer-Encoding to the all list

@rnewson
Copy link
Member

rnewson commented Jun 29, 2017

Take a look at RFC 7240 (https://tools.ietf.org/html/rfc7240).

Prefer: return=minimal

@garrensmith garrensmith changed the title Add X-Couch-Exclude-Headers support Add Prefer: return=minimal support Jun 30, 2017
Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Pretty good overall. This is a lot simpler than I expected going into the review so that makes me quite happy. Mostly a few nits other than the case sensitive matching for header filtering.

-module(chttpd_prefer_header).



Copy link
Member

Choose a reason for hiding this comment

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

Two blank lines between sections and functions please.




-export([maybe_return_minimal/2]).
Copy link
Member

Choose a reason for hiding this comment

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

Exports should go one per line so diff's in the future are nicer.

-export([
    maybe_return_minimal/2
]).



default_no_exclude_header_test() ->
Headers = chttpd_prefer_header:maybe_return_minimal(mock_request([]), default_headers()),
Copy link
Member

Choose a reason for hiding this comment

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

Line length too long.

-include_lib("eunit/include/eunit.hrl").



Copy link
Member

Choose a reason for hiding this comment

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

Only two blank lines between sections and functions please.

@@ -188,6 +188,10 @@ credentials = false
; List of accepted methods
; methods =

[prefer_header]
Copy link
Member

Choose a reason for hiding this comment

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

Bike shed: Is this the best place for this, or would it be better as a key in the chttpd section. Something like "prefer_minimal = List-Of-Headers"

You might also add a comment that a user doesn't specify Server here that Mochiweb will add its own regardless.


filter_headers(Headers, IncludeList) ->
lists:filter(fun({HeaderName, _}) ->
lists:member(HeaderName, IncludeList)
Copy link
Member

Choose a reason for hiding this comment

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

Seems like you probably want to look into mochiweb's header handling to make this comparison case insensitive.

Copy link
Member

Choose a reason for hiding this comment

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

Because users may or may not give headers in the same case as we have them specified internally.

Copy link
Member

Choose a reason for hiding this comment

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

Also that'd make for a good unit test as well.

Adding this header allows the client to request that only Non-Essential
or All headers are removed from the response. This will decrease the
size of the response.
Use the Prefer: return=minimal header options from
[rfc7240](https://tools.ietf.org/html/rfc7240). This will reduce the
number of headers in the response. The headers to be included is
configurable via the config.
Copy link
Member

@rnewson rnewson left a comment

Choose a reason for hiding this comment

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

thanks for pursuing this for so long. I have some comments to address.

I think it would be safer if we identified which headers couchdb sends that are strictly optional, I can't be sure I've listed all the ones I think need to be added back in, though I did read through the standard response header list as part of this review.

@@ -57,6 +57,9 @@ backlog = 512
docroot = {{fauxton_root}}
socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
require_valid_user = false
; List of headers that will be kept when the header Prefer: return=minimal is included in a request.
; If Server header is left out, Mochiweb will add its own one in.
prefer_minimal = Cache-Control, Content-Length, Content-Type, ETag, Server, Vary
Copy link
Member

Choose a reason for hiding this comment

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

we'll need Transfer-Encoding otherwise views, changes, _all_dbs will be broken.
we'll need Set-Cookie so we can login.
what about CORS related headers?
we'll need Content-Range for range reqs on attachments.
we'll need WWW-Authenticate for users that enable the standard login prompting setting.

Copy link
Member

Choose a reason for hiding this comment

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

Agree on Transfer-Encoding and Content-Range. For cooking and authentication headers I think not since this is aimed at non-browser clients and those are both for browsers (and or, non browsers would just have to be smart enough to not request it when they need to get a cookie.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think CORS is required since this is for non-browser clients. I agree with Paul around needing the auth headers, don't use this header when you need a cookie.


-export([
maybe_return_minimal/2
]).
Copy link
Member

Choose a reason for hiding this comment

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

this line should be at column 0.

@garrensmith
Copy link
Member Author

Thanks @rnewson and @davisp for the reviews on this. I've updated the default.ini and added in the two missing headers. I've also fixed the spacing issue.

@@ -57,6 +57,9 @@ backlog = 512
docroot = {{fauxton_root}}
socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
require_valid_user = false
; List of headers that will be kept when the header Prefer: return=minimal is included in a request.
; If Server header is left out, Mochiweb will add its own one in.
prefer_minimal = Cache-Control, Content-Length, Content-Range, Content-Type, ETag, Server, Transfer-Encoding, Vary
Copy link
Member

Choose a reason for hiding this comment

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

should be commented out by default.



get_header_list() ->
SectionStr = config:get("chttpd", "prefer_minimal", []),
Copy link
Member

Choose a reason for hiding this comment

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

the default needs to be ""?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've changed it to "". It seems re:split("", "\\s*,\\s*", [trim, {return, list}]). and re:split([], "\\s*,\\s*", [trim, {return, list}]). return the same result of [[]]

@@ -57,6 +57,9 @@ backlog = 512
docroot = {{fauxton_root}}
socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
require_valid_user = false
; List of headers that will be kept when the header Prefer: return=minimal is included in a request.
; If Server header is left out, Mochiweb will add its own one in.
; prefer_minimal = Cache-Control, Content-Length, Content-Range, Content-Type, ETag, Server, Transfer-Encoding, Vary
Copy link
Member

Choose a reason for hiding this comment

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

I'm an idiot. I forgot that this is opt-in (you have to pass 'Prefer: return=minimal'). So please uncomment this again. :)

@rnewson
Copy link
Member

rnewson commented Aug 9, 2017

+1 to merge but please squash down from the 7 commits as appropriate.

@garrensmith
Copy link
Member Author

@garrensmith garrensmith merged commit 52da19b into apache:master Aug 9, 2017
garrensmith added a commit to apache/couchdb-documentation that referenced this pull request Aug 9, 2017
wohali pushed a commit that referenced this pull request Oct 19, 2017
Use the Prefer: return=minimal header options from
[rfc7240](https://tools.ietf.org/html/rfc7240) to reduce the
number of headers in the response. The header is configurable via the config
jiangphcn pushed a commit to cloudant/couchdb-documentation that referenced this pull request Mar 16, 2018
thilo added a commit to thilo/couch_potato that referenced this pull request Mar 15, 2019
to minimise response headers for non browser clients. See apache/couchdb#605
langalex pushed a commit to langalex/couch_potato that referenced this pull request Mar 15, 2019
to minimise response headers for non browser clients. See apache/couchdb#605
@garrensmith garrensmith deleted the header-reductions branch December 12, 2019 17:20
nickva pushed a commit to nickva/couchdb that referenced this pull request Sep 7, 2022
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.

3 participants