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
[2.2.0-RC2] Regression in routes handling #1676
Comments
What's the payload you're passing out if interest |
There's no payload. The only param is in the URL |
Are you using Chrome? Can you try sending via curl? Can you send the headers to us? |
Does it happen with Firefox? I've seen a similar issue reported recently where it only happened for Chrome, not Firefox. What happened was that Chrome is submitting empty bodies with a Content-Type of application/xml. That's invalid, if the content type is application/xml, then you should be able to parse it with an XML parser, which is what Play is doing. But an empty String is invalid XML. I can't see anything in Play that has changed here, so I suspect it's actually a regression in Chrome that has coincided with Play 2.2, but I could be wrong. |
Yes, I'm using Chrome and it has set the Content-Type to "application/xml". There is something that has changed in Play though. If I send an empty body with "application/xml" in Play 2.1.4 that does work. |
Ok, so the actual change here is that Play used to not recognise |
Could you check to see if it happens in Firefox/Safari/IE? What version of AngularJS are you using? |
I believe it's related to this bug: https://code.google.com/p/chromium/issues/detail?id=172802 If you pass |
And here's the line in AngularJS, I believe, that is sending empty Strings: |
Ok, well I guess now that I know can just pass an empty JS object to Angular to get my app working that's good enough for me. I don't have a super strong feeling about whether Play or Chrome or Angular should change their behavior. Chrome's behavior seems the most wrong here. |
So, I'm not 100% sure what to do here. I think what Play is doing is right. By design, Play's default body parsers parse bodies according to the content type. And Play has every right to parse a request body with Content-Type So, I don't think Play is the right place to fix this. The root cause of the issue is in angular (and any other JS framework that submits an empty string instead of null), and I've raised a PR that I hope fixes it (if you could test for me, that would be great): The Chrome bug exacerbates the issue, but isn't the root cause. For now, I think the right thing to do is for us to publish a temporary work around that can be used until angular/chrome can be fixed. So here it is: package filters
import play.api.mvc._
import play.api.http.HeaderNames._
import play.api.http.MimeTypes._
/**
* Works around the issue where AngularJS on WebKit sends empty application/xml bodies
*/
class FixEmptyXmlFilter extends EssentialFilter {
def apply(next: EssentialAction): EssentialAction = EssentialAction { req =>
(req.headers.get(CONTENT_LENGTH), req.headers.get(CONTENT_TYPE)) match {
case (None | Some("0"), Some(XML)) =>
next(new WrappedRequest(Request(req, "")) {
override lazy val mediaType = None
override lazy val contentType = None
})
case _ => next(req)
}
}
} Using this from a Java project: import play.GlobalSettings;
import play.api.mvc.EssentialFilter;
public class Global extends GlobalSettings {
public <T extends EssentialFilter> Class<T>[] filters() {
return new Class[]{filters.FixEmptyXmlFilter.class};
}
} |
thanks for looking into this one! |
Sorry, chiming in late here. It is acceptable for a POST to contain no data. If there is no data it shouldn't be parsed no matter what the mime type... I think this could be a problem for us to deal with. |
There's nothing in HTTP to differentiate no content and empty content. Both result in a 0 length request body. So there's no such thing as "a POST containing no data", there is only "a POST with an empty body". In the case, for example, of the The important thing here is that the If a client is sending no data, ie, if the client is not sending content, then the client should not set a content type, since it is an error to describe the type of something that doesn't exist. Right? |
@jroper hmm, i don't know the details super well here. so if there's nothing in HTTP to differentiate no content and empty content, then how does your change to Angular to send null instead of empty string work? wouldn't those be interpreted as the same things? is it just a workaround for the Chrome bug? |
There is something in the Javascript XMLHttpRequest API to differentiate between it (null or empty string), and based on that, a Content-Type header is or isn't set. |
Thanks for the workaround, but it looks like this solution won't work in Eclipse without the Scala IDE? |
This issue by the way is now both fixed in Chrome: https://code.google.com/p/chromium/issues/detail?id=172802 And also in WebKit (hence eventually Safari): |
This was legal in 2.1.4, but does not seem to work in the 2.2.0-RC2 release that I just grabbed from Maven.
When I submit the request, I get:
The text was updated successfully, but these errors were encountered: