在Django测试中设置HTTP_REFERER头

时间:2021-01-12 15:23:09

I'm working on a Django web application which (amongst other things) needs to handle transaction status info sent using a POST request.

我正在开发一个Django web应用程序,它需要处理使用POST请求发送的事务状态信息。

In addition to the HTTP security supported by the payment gateway, my view checks request.META['HTTP_REFERER'] against an entry in settings.py to try to prevent funny business:

除了支付网关支持的HTTP安全性之外,my view还检查请求。元['HTTP_REFERER']在设置中的条目。为了避免有趣的事情发生:

if request.META.get('HTTP_REFERER', '') != settings.PAYMENT_URL and not settings.DEBUG:
    return HttpResponseForbidden('Incorrect source URL for updating payment status')

Now I'd like to work out how to test this behaviour.

现在我想研究如何测试这种行为。

I can generate a failure easily enough; HTTP_REFERER is (predictably) None with a normal page load:

我很容易产生失败;HTTP_REFERER(可预见的)没有正常页面负载:

def test_transaction_status_succeeds(self):
    response = self.client.post(reverse('transaction_status'), { ... })
    self.assertEqual(response.status_code, 403)

How, though, can I fake a successful submission? I've tried setting HTTP_REFERER in extra, e.g. self.client.post(..., extra={'HTTP_REFERER': 'http://foo/bar'}), but this isn't working; the view is apparently still seeing a blank header.

但是,我怎么能假装提交成功呢?我试过在extra中设置HTTP_REFERER,例如self。client.post(…), extra={'HTTP_REFERER': 'http://foo/bar'}),但这不起作用;该视图显然仍在看到一个空标题。

Does the test client even support custom headers? Is there a work-around if not? I'm using Django 1.1, and would prefer not to upgrade just yet if at all possible.

测试客户端是否支持自定义头文件?如果没有,是否有一个变通的办法?我正在使用Django 1.1,如果可能的话,我宁愿现在不升级。

2 个解决方案

#1


16  

Almost right. It's actually:

几乎是正确的。它实际上是:

def transaction_status_suceeds(self):
    response = self.client.post(reverse('transaction_status'), {}, HTTP_REFERER='http://foo/bar')

I'd missed a ** (scatter operator / keyword argument unpacking operator / whatever) when reading the source of test/client.py; extra ends up being a dictionary of extra keyword arguments to the function itself.

在读取test/client.py源代码时,我错过了**(分散操作符/关键字参数解包操作符/随便什么);额外结果是函数本身的额外关键字参数字典。

#2


1  

You can pass HTTP headers to the constructor of Client:

可以将HTTP报头传递给客户端构造函数:

from django.test import Client
from django.urls import reverse

client = Client(
    HTTP_USER_AGENT='Mozilla/5.0',
    HTTP_REFERER='http://www.google.com',
)
response1 = client.get(reverse('foo'))
response2 = client.get(reverse('bar'))

This way you don't need to pass headers every time you make a request.

这样,您就不需要每次发出请求时都传递header了。

#1


16  

Almost right. It's actually:

几乎是正确的。它实际上是:

def transaction_status_suceeds(self):
    response = self.client.post(reverse('transaction_status'), {}, HTTP_REFERER='http://foo/bar')

I'd missed a ** (scatter operator / keyword argument unpacking operator / whatever) when reading the source of test/client.py; extra ends up being a dictionary of extra keyword arguments to the function itself.

在读取test/client.py源代码时,我错过了**(分散操作符/关键字参数解包操作符/随便什么);额外结果是函数本身的额外关键字参数字典。

#2


1  

You can pass HTTP headers to the constructor of Client:

可以将HTTP报头传递给客户端构造函数:

from django.test import Client
from django.urls import reverse

client = Client(
    HTTP_USER_AGENT='Mozilla/5.0',
    HTTP_REFERER='http://www.google.com',
)
response1 = client.get(reverse('foo'))
response2 = client.get(reverse('bar'))

This way you don't need to pass headers every time you make a request.

这样,您就不需要每次发出请求时都传递header了。