bowler-framework / Bowler

RESTful Web Framework based on Scala, built on top of Scalatra & Scalate
http://bowlerframework.org
BSD 3-Clause "New" or "Revised" License
119 stars 13 forks source link

Content-type issues #9

Closed mjg123 closed 13 years ago

mjg123 commented 13 years ago

I'm not sure what the root problem is here, but there is odd behaviour around content-types and the accept header. I have a resource at /foo which accepts GET and returns a json response, by calling render(my_case_class_instance). There is no HTML view (.mustache, etc) for that resource.

Wrong content-type returned

If I make a request with: Accept: application/json

I get back my JSON representation, but with a Content-type header of text/plain (bug #1?)

Incorrect HTTP status when no suitable content-type available

If I make a request with: Accept: text/plain or Accept: text/html

Then, I get an error 500 from the service, with the message Could not find a template of type .html, .xhtml, .xml, .mustache, .ssp, .jade or .scaml with path: classpath:///views/GET/foo (bug #2?) I would expect to get 406 here, although I have not specified in code that application/json is the only content-type I can produce, that is how imagine the resource to be defined. (side issue: how do I specify in code what content-type I am producing?)

Incorrect matching of wildcard Accept headers

If I make a request with: Accept: */* or Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 (chrome default)

Then, I get an error 500 from the service, with the message Could not find a template of type .html, .xhtml, .xml, .mustache, .ssp, .jade or .scaml with path: classpath:///views/GET/foo (bug #3?) As these both accept */*, I expect the json representation to be returned.

These 3 situations seem to be connected, but if you would rather I raise 3 separate bugs, I can do that.

wfaler commented 13 years ago

Hi, Case 1 is probably a genuine bug (had the same thing in the html a short while, so this should be fixed in the next 24 hours or so.

Case 2 and 3 unfortunately is one we might have to live with (unless you can come up with a solution?): Internet Explorer does not give nice Content-Type and Accept headers like pretty much every other client/browser on planet earth, and to make matters worse, they differ form version to version. Therefore we fallback to the text/html content-type (ScalateViewRenderer) whenever we have not explicitly registered another ViewRenderer to handle a type of content.

Any ideas on how to solve this more elegantly? Unfortunately, IE keeps messing up and not following HTTP properly, and people still use it.

Thanks for the reports! This is really useful information, to get some real-world feedback from others.. :)

mjg123 commented 13 years ago

We're evaluating bowler for use in RESTful services at my company - especially case #2 is quite important for us. Ideally we'd prefer a REST framework to value adherence to HTTP spec over IE compatibility - or at least have a kind of "quirks mode" for IE people that we could turn off.

wfaler commented 13 years ago

You make a good point, and I think this is where we can make use of Bowlers configurability: We can simply implement a "StrictRenderStrategy" RenderStrategy implementation which adheres more strictly to HTTP and disregards IE, and configure it in in a single line in your bootstrap-class by calling BowlerConfigurator.setRenderStrategy(new StrictRenderStrategy) If you look at the DefaultRenderStrategy (https://github.com/wfaler/Bowler/blob/master/core/src/main/scala/org/bowlerframework/view/DefaultRenderStrategy.scala), you see this is pretty straightforward.

I can write this up tomorrow and do a 0.3.1 maven release which fixes the issue (assuming you configure in the new StrictRenderStrategy), or if you want to beat me to it today and do an implementation and unit-test and contribute, feel free to do so!

..otherwise, I'll do the implementation most likely tomorrow evening and roll out the release.

mjg123 commented 13 years ago

great - I'd be interested in having a look at the code & helping out if I can, but there is no way that I'll get time to do it until the weekend.

wfaler commented 13 years ago

I'll try to get an implementation done tomorrow then and close the issue when you do (you'll see the commit).

As for helping out: especially for the things you are looking at, it should be relatively easy to follow the code and interface-contracts for what you are doing, so hopefully you won't find it too daunting.

It's funny how strict adherence to HTTP makes things really simple, but IE et al muddle things, but I digress..

wfaler commented 13 years ago

Should be fixed, implemented StrictRenderStrategy: https://github.com/wfaler/Bowler/commit/b70f4d96e0244d53f81158e87e31995cfe8dbbb7

Will announce 0.3.1 soonish hopefully, if I fail in doing so, you can always pull the current version from Git

wfaler commented 13 years ago

Realised it is not yet entirely consistent with the specification of the HTTP Accept header (probably "strict enough" as is, but needs tweaking for full strictness): http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

wfaler commented 13 years ago

Closed conclusively by this commit: https://github.com/wfaler/Bowler/commit/8ba49e0b8ccefd6b0eca13493a5fc7de662137eb

0.4 will be released on Monday.