Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #92 from pmclanahan/support-bad-post-fxos-962225
Browse files Browse the repository at this point in the history
Fix bug 962225: Support malformed POSTs from FxOS
  • Loading branch information
jgmize committed Jan 22, 2014
2 parents 0498f44 + 12f65f5 commit 3ef587f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
27 changes: 27 additions & 0 deletions news/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,33 @@
from news.views import language_code_is_valid


@patch('news.views.update_user_task')
class FxOSMalformedPOSTTest(TestCase):
"""Bug 962225"""

def setUp(self):
self.rf = RequestFactory()

def test_deals_with_broken_post_data(self, update_user_mock):
"""Should be able to parse data from the raw request body.
FxOS sends POST requests with the wrong mime-type, so request.POST is never
filled out. We should parse the raw request body to get the data until this
is fixed in FxOS in bug 949170.
"""
req = self.rf.generic('POST', '/news/subscribe/',
data='email=dude@example.com&newsletters=firefox-os',
content_type='text/plain; charset=UTF-8')
self.assertFalse(bool(req.POST))
views.subscribe(req)
update_user_mock.assert_called_with(req, views.SUBSCRIBE, data=ANY, optin=True, sync=False)
data = update_user_mock.call_args[1]['data']
self.assertDictEqual(data.dict(), {
'email': 'dude@example.com',
'newsletters': 'firefox-os',
})


class SubscribeTest(TestCase):
def setUp(self):
kwargs = {
Expand Down
28 changes: 18 additions & 10 deletions news/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import re

from django.conf import settings
from django.http import HttpResponse
from django.http import HttpResponse, QueryDict
from django.shortcuts import render
from django.views.decorators.cache import cache_control, never_cache
from django.views.decorators.csrf import csrf_exempt
Expand Down Expand Up @@ -398,16 +398,24 @@ def confirm(request, token):
@require_POST
@csrf_exempt
def subscribe(request):
newsletters = request.POST.get('newsletters', None)
data = request.POST.copy()
newsletters = data.get('newsletters', None)
if not newsletters:
return HttpResponseJSON({
'status': 'error',
'desc': 'newsletters is missing',
'code': errors.BASKET_USAGE_ERROR,
}, 400)
# request.body causes tests to raise exceptions
# while request.read() works.
raw_request = request.read()
if 'newsletters=' in raw_request:
# malformed request from FxOS
data = QueryDict(raw_request, encoding=request.encoding)
else:
return HttpResponseJSON({
'status': 'error',
'desc': 'newsletters is missing',
'code': errors.BASKET_USAGE_ERROR,
}, 400)

optin = request.POST.get('optin', 'Y') == 'Y'
sync = request.POST.get('sync', 'N') == 'Y'
optin = data.get('optin', 'Y') == 'Y'
sync = data.get('sync', 'N') == 'Y'

if sync:
if not request.is_secure():
Expand All @@ -424,7 +432,7 @@ def subscribe(request):
'code': errors.BASKET_AUTH_ERROR,
}, 401)

return update_user_task(request, SUBSCRIBE, optin=optin, sync=sync)
return update_user_task(request, SUBSCRIBE, data=data, optin=optin, sync=sync)


@require_POST
Expand Down

0 comments on commit 3ef587f

Please sign in to comment.