{"action":"created","issue":{"url":"https://api.github.com/repos/vert-x3/vertx-web/issues/442","repository_url":"https://api.github.com/repos/vert-x3/vertx-web","labels_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/442/labels{/name}","comments_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/442/comments","events_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/442/events","html_url":"https://github.com/vert-x3/vertx-web/issues/442","id":173593853,"number":442,"title":"Add the ability to get the full Accept/Content-Type header(s) matched when a route is selected","user":{"login":"brunoais","id":639467,"avatar_url":"https://avatars.githubusercontent.com/u/639467?v=3","gravatar_id":"","url":"https://api.github.com/users/brunoais","html_url":"https://github.com/brunoais","followers_url":"https://api.github.com/users/brunoais/followers","following_url":"https://api.github.com/users/brunoais/following{/other_user}","gists_url":"https://api.github.com/users/brunoais/gists{/gist_id}","starred_url":"https://api.github.com/users/brunoais/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brunoais/subscriptions","organizations_url":"https://api.github.com/users/brunoais/orgs","repos_url":"https://api.github.com/users/brunoais/repos","events_url":"https://api.github.com/users/brunoais/events{/privacy}","received_events_url":"https://api.github.com/users/brunoais/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/vert-x3/vertx-web/labels/wishlist","name":"wishlist","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-27T12:28:21Z","updated_at":"2016-08-30T18:36:57Z","closed_at":null,"body":"### Current\r\nCurrently, Vert.x-web only matches `Accept` and `Content-Type` headers by their type and subtype but not the parameters.\r\n\r\n### Problem\r\nIf I want to make a program that handles different output depending on the MIME type, I have to process the `accept` header myself searching for the matched `Content-type`.\r\n\r\n### Use Cases\r\nThese are hypothetical use-cases I see for implementing this.\r\n1. Different handlers for different charsets.\r\n2. Different handlers for different API versions for that `Content-Type` (or `Accept`). Minimalistic example:\r\n`Content-Type: application/json;v=1`\r\n\r\n\t{\r\n\t\t\"thing1\" : {\r\n\t\t\t\"thing1.1\" : \"a\",\r\n\t\t\t\"thing1.2\" : \"b\"\r\n\t\t},\r\n\t\t\"thing2\" : {\r\n\t\t\t\"thing2.1\" : {\r\n\t\t\t\t\"thing2.1.1\" : \"c\"\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\nvs:\r\n`Content-Type: application/json;v=2`\r\n\r\n\t{\r\n\t\t\"thing1.1\" : \"a\",\r\n\t\t\"thing1.2\" : \"b\",\r\n\t\t\"thing2.1.1\" : \"c\"\r\n\t}\r\n\r\n### I can do this if you accept\r\nI've seen Vert.x's code where it parses the `Content-Type` header and I have an idea how to implement this such that, if no parameters are specified in either `Route.produces()` or `Route.consumes()`, it should not get any significant performance loss.\r\n\r\n##### My idea for this approach (summary)\r\n1. All `Accept` and `Content-Type` parameters are kept in `HashMap`s associated with the request and the Route.\r\n2. The Route's `HashMap` is only set if it has parameters defined, otherwise, null. \r\n3. Same as above for the request except that the `q` parameter in `Accept` is filtered (just like it is now)\r\n4. The parameters are only compared if **both** defined parameters.\r\n5. If a Route produces or consumes MIME parameters that are **not set** in the corresponding header, it **is not** called.\r\n6. If a Route does not produce nor consume a MIME parameter that is set in the corresponding header, it **is** called.\r\n\r\nExamples of 5 and 6.\r\n5:\r\n**Setup:**\r\n`a.consumes(\"application/json;v=1\");`\r\n`b.consumes(\"application/json;v=2\");`\r\n`c.consumes(\"application/json;v\");`\r\n`d.consumes(\"application/json\");`\r\n\r\n**Request:**\r\n1. `Content-Type: application/json;v=1` -> `a`, `c` and `d` handle the request (in that order).\r\n2. `Content-Type: application/json;v=2` -> `b` and `c` and `d` handle the request (in that order).\r\n3. `Content-Type: application/json;v=8` -> `c` and `d` handle the request (in that order).\r\n4. `Content-Type: application/json;yay=nope` -> `d` handles the request.\r\n5. `Content-Type: application/json;` -> `d` handles the request.\r\n6. `Content-Type: application/json` -> `d` handles the request.\r\n\r\n6 :\r\n**Setup (same as 5. Feel free to skip):**\r\n`a.produces(\"application/json;v=1\");`\r\n`b.produces(\"application/json;v=2\");`\r\n`c.produces(\"application/json;v\");`\r\n`d.produces(\"application/json\");`\r\n\r\n**Request:**\r\n1. `Accept: application/json;q=0.4;v=2, application/json;q=0.8;v=1` -> `a`, `c` and `d` handle the request (in that order).\r\n2. `Accept: application/json;q=0.8;v=2, application/json;q=0.4;v=1` -> `b` and `c` and `d` handle the request (in that order).\r\n3. `Accept:  application/json;v=8, application/json;v=2` -> `c` and `d` handle the request (in that order).\r\n4. `Accept:  application/json, application/json;v=2` ->`b` and `c` and `d` handle the request (in that order).\r\n5. `Accept:  application/json, text/html` -> `d` handles the request.\r\n\r\nExplanation on the 4th point:\r\nThe [RFC2616-sec14](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) states that:\r\n\r\n> Media ranges can be overridden by more specific media ranges or specific media types. If more than one media range applies to a given type, the most specific reference has precedence.\r\n\r\nAdditionally for this algorithm, repeated parameters are not supported and they override each other. For each parameter of the same name, the last one being processed prevails.\r\n\r\nI'm open for any questions you may have about this."},"comment":{"url":"https://api.github.com/repos/vert-x3/vertx-web/issues/comments/243537142","html_url":"https://github.com/vert-x3/vertx-web/issues/442#issuecomment-243537142","issue_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/442","id":243537142,"user":{"login":"brunoais","id":639467,"avatar_url":"https://avatars.githubusercontent.com/u/639467?v=3","gravatar_id":"","url":"https://api.github.com/users/brunoais","html_url":"https://github.com/brunoais","followers_url":"https://api.github.com/users/brunoais/followers","following_url":"https://api.github.com/users/brunoais/following{/other_user}","gists_url":"https://api.github.com/users/brunoais/gists{/gist_id}","starred_url":"https://api.github.com/users/brunoais/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brunoais/subscriptions","organizations_url":"https://api.github.com/users/brunoais/orgs","repos_url":"https://api.github.com/users/brunoais/repos","events_url":"https://api.github.com/users/brunoais/events{/privacy}","received_events_url":"https://api.github.com/users/brunoais/received_events","type":"User","site_admin":false},"created_at":"2016-08-30T18:36:57Z","updated_at":"2016-08-30T18:36:57Z","body":"@pmlopes What do you think about my implementation proposal?"}}
{"actor":{"display_login":"brunoais"}}