Skip to content
This repository was archived by the owner on Jun 11, 2018. It is now read-only.

Commit b80a2b9

Browse files
committed
Include request.POST, cope/test for multipart/form-data
1 parent 78917a7 commit b80a2b9

2 files changed

Lines changed: 56 additions & 7 deletions

File tree

opbeat/contrib/django/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ def get_data_from_request(self, request):
116116
raw_data = request.raw_post_data
117117
data = raw_data if raw_data else request.POST
118118
except Exception as exc:
119-
# assume we had a partial read:
120-
data = '<unavailable ({0}: {1})>'.format(
121-
exc.__class__.__name__, exc)
119+
# Assume we had a partial read, or multipart/form-data:
120+
data = '<unavailable ({0}: {1})>\nrequest.POST: {2}'.format(
121+
exc.__class__.__name__, exc, request.POST)
122122
else:
123123
data = None
124124

tests/contrib/django/django_tests.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
import pytest # isort:skip
33

4-
django = pytest.importorskip("django") # isort:skip
4+
django = pytest.importorskip("django") # noqa isort:skip
55

66
import datetime
77
import logging
@@ -21,6 +21,7 @@
2121
from django.test import TestCase
2222
from django.test.client import Client as _TestClient
2323
from django.test.client import ClientHandler as _TestClientHandler
24+
from django.test.client import FakePayload
2425
from django.test.utils import override_settings
2526

2627
import mock
@@ -522,7 +523,8 @@ def test_raw_post_data_partial_read(self):
522523
expected_exception = 'RawPostDataException'
523524
else:
524525
expected_exception = 'Exception'
525-
self.assertEquals(http['data'], "<unavailable ({0}: You cannot access body after reading from request's data stream)>".format(expected_exception))
526+
self.assertEquals(http['data'], "<unavailable ({0}: You cannot access body after reading from request's data stream)>\nrequest.POST: {1}".format(expected_exception, request.POST))
527+
self.assertEquals(request.POST, {})
526528

527529
def test_post_data(self):
528530
request = WSGIRequest(environ={
@@ -602,7 +604,7 @@ def test_disallowed_hosts_error_django_18(self):
602604
self.assertEqual(event['http']['url'], None)
603605

604606
# This test only applies to Django 1.3+
605-
def test_request_capture(self):
607+
def test_request_capture_partial_read(self):
606608
if django.VERSION[:2] < (1, 3):
607609
return
608610
request = WSGIRequest(environ={
@@ -627,7 +629,8 @@ def test_request_capture(self):
627629
expected_exception = 'RawPostDataException'
628630
else:
629631
expected_exception = 'Exception'
630-
self.assertEquals(http['data'], "<unavailable ({0}: You cannot access body after reading from request's data stream)>".format(expected_exception))
632+
self.assertEquals(http['data'], "<unavailable ({0}: You cannot access body after reading from request's data stream)>\nrequest.POST: {1}".format(expected_exception, request.POST))
633+
# self.assertEquals(http['data'], '{}')
631634
self.assertTrue('headers' in http)
632635
headers = http['headers']
633636
self.assertTrue('Content-Type' in headers, headers.keys())
@@ -638,6 +641,52 @@ def test_request_capture(self):
638641
self.assertTrue('SERVER_PORT' in env, env.keys())
639642
self.assertEquals(env['SERVER_PORT'], '80')
640643

644+
def test_request_capture_multipart_formdata(self):
645+
if django.VERSION[:2] < (1, 3):
646+
return
647+
648+
payload = FakePayload("\r\n".join([
649+
'--boundary',
650+
'Content-Disposition: form-data; name="name"',
651+
'',
652+
'value',
653+
'--boundary--'
654+
'']))
655+
request = WSGIRequest({
656+
'REQUEST_METHOD': 'POST',
657+
'SERVER_NAME': 'testserver',
658+
'SERVER_PORT': '80',
659+
'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
660+
'CONTENT_LENGTH': len(payload),
661+
'wsgi.input': payload})
662+
663+
# Read POST data to trigger exception when accessing request.body.
664+
self.assertEqual(request.POST, {'name': ['value']})
665+
666+
self.opbeat.capture('Message', message='foo', request=request)
667+
668+
self.assertEquals(len(self.opbeat.events), 1)
669+
event = self.opbeat.events.pop(0)
670+
671+
self.assertTrue('http' in event)
672+
http = event['http']
673+
self.assertEquals(http['method'], 'POST')
674+
if django.VERSION >= (1, 7):
675+
expected_exception = 'RawPostDataException'
676+
else:
677+
expected_exception = 'Exception'
678+
self.assertEquals(http['data'], "<unavailable ({0}: You cannot access body after reading from request's data stream)>\nrequest.POST: {1}".format(expected_exception, request.POST))
679+
# self.assertEquals(http['data'], '{}')
680+
self.assertTrue('headers' in http)
681+
headers = http['headers']
682+
self.assertTrue('Content-Type' in headers, headers.keys())
683+
self.assertEquals(headers['Content-Type'], 'multipart/form-data; boundary=boundary')
684+
env = http['env']
685+
self.assertTrue('SERVER_NAME' in env, env.keys())
686+
self.assertEquals(env['SERVER_NAME'], 'testserver')
687+
self.assertTrue('SERVER_PORT' in env, env.keys())
688+
self.assertEquals(env['SERVER_PORT'], '80')
689+
641690
def test_transaction_metrics(self):
642691
self.opbeat.instrumentation_store.get_all() # clear the store
643692
with self.settings(MIDDLEWARE_CLASSES=[

0 commit comments

Comments
 (0)