I ran into an annoying bug where all my ajax requests from Firefox ended up in 400 Bad Request, yet Chrome was totally fine.
The difference is the Content-Type header that gets sent in the request. Firefox uses
Content-Type: application/x-www-form-urlencoded; charset="utf-8"
whereas Chrome sends
Content-Type: application/x-www-form-urlencoded
Both are perfectly valid yet the first one leads to errors. It turns out this is an old issue (almost 2 years now!) for Piston.
The issue here is that depending on the Content-Type header, Piston will try to parse the incoming parameters. If you send ‘application/json’ it will interpret the incoming data stream as a JSON object, parse it and make it available at request.data . Unfortunately it tries to parse if the Content-Type is not ‘application/x-www-form-urlencoded’. All of this happens internally, so there is little we can do there.
However, since you most likely already have an authenticator in place, you can completely modify the request object before any parsing happens.
class MyAuthentication(object): def is_authenticated(self, request): self.check_content_type(request) return self.check_authenticated(request) def check_authenticated(self, request): # Implement your own authentication checks here. # Don't forget to set the request.user object! return true def check_content_type(self, request): ct = request.META.get('CONTENT_TYPE', None) if ct: request.META['CONTENT_TYPE'] = ct.split(';')[0] |
Another option would be to override the __call__ method of the Resource class you use in urls.py
Coincidentally, when I published this post, an announcement was made on the Google Groups that there is a new developer for django-piston, so this might get fixed pretty soon!