-
Notifications
You must be signed in to change notification settings - Fork 982
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
Accept header handling with accept-extensions #1219
Comments
This fixes the issue where Accept headers with accept parameters are not match to the acceptable list and the formatters map.
@DonutEspresso mind taking a look at this? I know you were most recently in the formatters code base. |
Thanks for filing the issue and PR! There's a lot to unpack here. Let's table the formatters for a second. My reading of the RFC is that That said,
I think this reads as, attempt to do a match with accept-extensions (other than q) before attempting to normalize the type. I think when we create the server, it'll have to be smarter and extrapolate accepted content-types automatically from the provided formatters when possible. Presumably that would trickle down through to |
Right. My issue is not with the handling of the '+' in the accept header. I only showed that because that is the format of the header I am using which lead to my discovery of this issue. I am not proposing any changes for this. You are correct that the accept headers should be ordered by precedence according to each request. The problem is that there are 2 places in restify where the accept headers are used: acceptable and formatters. My PR would only adds simple support which basically allows extensions to function but without precedence. I think implementing precedence would require bigger changes like storing parsed accept headers which are then used when trying to choose a formatter. I don't think the formatter definitions will trickle down to the acceptable list properly unless you start storing parsed accept headers or generate permutations into strings. People may also want to define complex acceptable types without formatters. |
Ah, sorry - maybe I misread the initial issue, it sounded like you wanted automatic mapping to the subtype, i.e.,
If that's not the case, then I think we're on the same page. It looks like negotiator captured similar concerns in negotiator#35. My understanding is that that PR is primarily concerned with exposing the parsed parameters and extensions such that the end user can determine the correct value. What's less clear to me is whether the desired behavior ( If it is in the spec, then I'd argue it's up to negotiator to do this resolution, rather than restify doing normalization prior to calling negotiator (as you have in the PR). If it is not in the spec, then I think we'd have to expose a negotiation hook in restify and pass the parsed accept parameters/extensions for the end user to decide. |
Let's break the resolution of accept/content-type values into 2 types:
I looked at negotiator#35 referenced above and agree that Negotiator is what is causing the first problem defined above and should be fixed. I'll put together a PR for negotiator with a fix for better extension handling. The second problem defined above regarding formatters is a fix that will probably need to be made in Restify. When you define formatters it is already normalizing the accept values to exclude any parameters ( see To sum this all up:
Do you agree? Thanks, Josh |
Hey @jkennedy1980, sorry for delayed reply. I'm with you on part 1. Part 2 is where I'm less clear - my understanding based on reading the spec and the negotiator threads was that negotiation based on extensions is application specific - i.e., restify cannot safely determine the correct type for users when a match is not found. Instead, restify would return the parsed extensions (provided by negotiator) and a list of the formatters, allowing user land to make the correct determination. Likely, it'd have to be a new plugin that takes a user supplied function to do the resolution. Thoughts? |
Is this issue fixed? I am talking about allowing Accept Headers of type - I see there is a PR - #1220 but when I look at the Recent codebase it does not have any of these changes. Was this change removed? |
Hey @anup4f82, These changes weren't removed, the PR was never merged. "Part 2" above is where the conversation left off during the review. According to the comment in #1220, it looks like the original author of the PR wont be finishing it up. If we get a PR for part 1 above (which it sounds like @DonutEspresso 👍ed), I'll gladly do a review! I haven't looked too closely at the original PR yet, part 1 may be implemented there already and just needs to be pulled out. Part 2 needs a bit more thought. I'm going to close the PR, but leave this issue open. |
I need Restify to accept "application/vnd.api+json" (JsonAPI format) Accept headers and the below is not working:
When I do a
Is there a correct way to do this that I'm missing? Or even a hacky way? Is the problem I'm running into related to this issue (#1219)? |
Please disregard, I solved the problem just now. Turns out I was using both the 'acceptable' property in the call to createServer() above, and the |
I don't know which version did @nateq314 use, but I don't see "acceptable" option in current docs - my restify v4.3.0 ignored this option anyway.
The above workaround worked for me. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been automatically closed as stale because it has not had recent activity. |
If you submit a request with an accept header like
application/vnd.restify+json;ext=value
you will get a 406 even if you addapplication/vnd.restify+json
to the list of acceptable types. Additionally, customer formatters forapplication/vnd.restify
will not be chosen and restify will throw a "500 no formatter" error. This appears to be due to the way that restify compares the accept header to the acceptable list and formatters map.According to RFC2616 an accept header can contain 0 or more accept-parameters. Clients can use custom accept parameters with the exception of the 'q' parameter which is reserved. See spec here: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
After digging into the code I see that the content types from the formatters map are normalized to the media-range part of the header and then merged into the acceptable list. e.g.
application/vnd.restify+json;ext=value
becomesapplication/vnd.restify+json
.I think it's safe to assume that a request with
Accept: application/vnd.restify+json;ext=value
should be consideredacceptable
when the server is configured with a formatter forapplication/vnd.restify
. I'll be submitting failing tests and PR shortly.The text was updated successfully, but these errors were encountered: