2
2
from __future__ import absolute_import , division , print_function
3
3
4
4
import json
5
+ import re
5
6
import tempfile
6
7
import unittest
7
8
8
9
import requests
9
10
10
- from vcr import vcr
11
+ from vcr import vcr , VCRSystem
12
+
13
+
14
+ def _normalize_http_header (name , args , kwargs ):
15
+ """
16
+ normalize http headers in outgoing traffic:
17
+
18
+ Expected: sendall (b'POST /post HTTP/1.1\r \n '
19
+ b'Host: httpbin.org\r \n '
20
+ b'User-Agent: python-requests/2.13.0\r \n '
21
+ b'Accept-Encoding: gzip, deflate\r \n '
22
+ b'Accept: */*\r \n '
23
+ b'Connection: keep-alive\r \n '
24
+ b'Content-Length: 147\r \n '
25
+ b'Content-Type: multipart/form-data; '
26
+ b'boundary=45c2c6ddafe3498c94b4554d6fb6e503\r \n \r \n ',) {}
27
+ Got: sendall (b'POST /post HTTP/1.1\r \n '
28
+ b'Host: httpbin.org\r \n '
29
+ b'User-Agent: python-requests/2.13.0\r \n '
30
+ b'Accept-Encoding: gzip, deflate\r \n '
31
+ b'Accept: */*\r \n '
32
+ b'Connection: keep-alive\r \n '
33
+ b'Content-Length: 147\r \n '
34
+ b'Content-Type: multipart/form-data; '
35
+ b'boundary=9ce384e773e444fc9ae202103e971aab\r \n \r \n ',) {}
36
+ """
37
+ if name != 'sendall' :
38
+ return name , args , kwargs
39
+ if len (args ) != 1 :
40
+ return name , args , kwargs
41
+ if b'HTTP' in args [0 ]:
42
+ # sort HTTP headers
43
+ # example:
44
+ # (b'GET /fdsnws/event/1/contributors HTTP/1.1\r\n'
45
+ # b'Host: service.iris.edu\r\nAccept-Encoding: gzip, deflate\r\n'
46
+ # b'User-Agent: python-requests/2.13.0\r\nConnection: keep-alive\r\n'
47
+ # b'Accept: */*\r\n\r\n')
48
+ x = args [0 ]
49
+ x = x .split (b'\r \n ' )
50
+ # two empty items at the end
51
+ x = x [:1 ] + sorted (x [1 :- 2 ]) + x [- 2 :]
52
+ x = b'\r \n ' .join (x )
53
+ args = tuple ([x ])
54
+
55
+ # normalize user-agent string
56
+ pattern = (
57
+ b'User-Agent: python-requests/.*?(\\ r\\ n)' )
58
+ repl = b'User-Agent: python-requests/x.x.x\\ 1'
59
+ args = tuple ([re .sub (pattern , repl , args [0 ], count = 1 )])
60
+
61
+ # normalize 'boundary=...' string
62
+ pattern = (
63
+ b'(boundary)=[0-9a-fA-F]{32}((\\ r\\ n)|(;))' )
64
+ repl = b'\\ 1=xxx\\ 2'
65
+ args = tuple ([re .sub (pattern , repl , args [0 ], count = 1 )])
66
+ elif args [0 ].startswith (b'--' ):
67
+ # treat follow-up line with above boundary string.. right now our
68
+ # normalization is only aware of the current line.. this should be
69
+ # changed, we should normalize on the whole playlist to be able to
70
+ # properly handle such matches that appear over multiple lines..
71
+
72
+ # normalize boundary strings on follow-up lines
73
+ pattern = b'--[0-9a-fA-F]{32}'
74
+ repl = b'--' + b'x' * 32
75
+ args = tuple ([re .sub (pattern , repl , args [0 ])])
76
+ return name , args , kwargs
11
77
12
78
13
79
class RequestsTestCase (unittest .TestCase ):
@@ -33,13 +99,18 @@ def test_http_post(self):
33
99
34
100
@vcr
35
101
def test_http_post_file (self ):
36
- with tempfile .TemporaryFile (mode = 'wb+' ) as file :
37
- file .write (b'test123' )
38
- file .seek (0 )
39
- files = {'file' : file }
40
- r = requests .post ('http://httpbin.org/post' , files = files )
41
- out = json .loads (r .text )
42
- self .assertEqual (out ['files' ]['file' ], 'test123' )
102
+ VCRSystem .outgoing_check_normalizations = [
103
+ _normalize_http_header ]
104
+ try :
105
+ with tempfile .TemporaryFile (mode = 'wb+' ) as file :
106
+ file .write (b'test123' )
107
+ file .seek (0 )
108
+ files = {'file' : file }
109
+ r = requests .post ('http://httpbin.org/post' , files = files )
110
+ out = json .loads (r .text )
111
+ self .assertEqual (out ['files' ]['file' ], 'test123' )
112
+ finally :
113
+ VCRSystem .outgoing_check_normalizations = []
43
114
44
115
@vcr
45
116
def test_cookies (self ):
0 commit comments