@@ -134,6 +134,33 @@ def test_putheader(self):
134
134
conn .putheader ('Content-length' , 42 )
135
135
self .assertIn (b'Content-length: 42' , conn ._buffer )
136
136
137
+ conn .putheader ('Foo' , ' bar ' )
138
+ self .assertIn (b'Foo: bar ' , conn ._buffer )
139
+ conn .putheader ('Bar' , '\t baz\t ' )
140
+ self .assertIn (b'Bar: \t baz\t ' , conn ._buffer )
141
+ conn .putheader ('Authorization' , 'Bearer mytoken' )
142
+ self .assertIn (b'Authorization: Bearer mytoken' , conn ._buffer )
143
+ conn .putheader ('IterHeader' , 'IterA' , 'IterB' )
144
+ self .assertIn (b'IterHeader: IterA\r \n \t IterB' , conn ._buffer )
145
+ conn .putheader ('LatinHeader' , b'\xFF ' )
146
+ self .assertIn (b'LatinHeader: \xFF ' , conn ._buffer )
147
+ conn .putheader ('Utf8Header' , b'\xc3 \x80 ' )
148
+ self .assertIn (b'Utf8Header: \xc3 \x80 ' , conn ._buffer )
149
+ conn .putheader ('C1-Control' , b'next\x85 line' )
150
+ self .assertIn (b'C1-Control: next\x85 line' , conn ._buffer )
151
+ conn .putheader ('Embedded-Fold-Space' , 'is\r \n allowed' )
152
+ self .assertIn (b'Embedded-Fold-Space: is\r \n allowed' , conn ._buffer )
153
+ conn .putheader ('Embedded-Fold-Tab' , 'is\r \n \t allowed' )
154
+ self .assertIn (b'Embedded-Fold-Tab: is\r \n \t allowed' , conn ._buffer )
155
+ conn .putheader ('Key Space' , 'value' )
156
+ self .assertIn (b'Key Space: value' , conn ._buffer )
157
+ conn .putheader ('KeySpace ' , 'value' )
158
+ self .assertIn (b'KeySpace : value' , conn ._buffer )
159
+ conn .putheader (b'Nonbreak\xa0 Space' , 'value' )
160
+ self .assertIn (b'Nonbreak\xa0 Space: value' , conn ._buffer )
161
+ conn .putheader (b'\xa0 NonbreakSpace' , 'value' )
162
+ self .assertIn (b'\xa0 NonbreakSpace: value' , conn ._buffer )
163
+
137
164
def test_ipv6host_header (self ):
138
165
# Default host header on IPv6 transaction should wrapped by [] if
139
166
# its actual IPv6 address
@@ -153,6 +180,35 @@ def test_ipv6host_header(self):
153
180
conn .request ('GET' , '/foo' )
154
181
self .assertTrue (sock .data .startswith (expected ))
155
182
183
+ def test_invalid_headers (self ):
184
+ conn = client .HTTPConnection ('example.com' )
185
+ conn .sock = FakeSocket ('' )
186
+ conn .putrequest ('GET' , '/' )
187
+
188
+ # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no
189
+ # longer allowed in header names
2364
190
+ cases = (
191
+ (b'Invalid\r \n Name' , b'ValidValue' ),
192
+ (b'Invalid\r Name' , b'ValidValue' ),
193
+ (b'Invalid\n Name' , b'ValidValue' ),
194
+ (b'\r \n InvalidName' , b'ValidValue' ),
195
+ (b'\r InvalidName' , b'ValidValue' ),
196
+ (b'\n InvalidName' , b'ValidValue' ),
197
+ (b' InvalidName' , b'ValidValue' ),
198
+ (b'\t InvalidName' , b'ValidValue' ),
199
+ (b'Invalid:Name' , b'ValidValue' ),
200
+ (b':InvalidName' , b'ValidValue' ),
201
+ (b'ValidName' , b'Invalid\r \n Value' ),
202
+ (b'ValidName' , b'Invalid\r Value' ),
203
+ (b'ValidName' , b'Invalid\n Value' ),
204
+ (b'ValidName' , b'InvalidValue\r \n ' ),
205
+ (b'ValidName' , b'InvalidValue\r ' ),
206
+ (b'ValidName' , b'InvalidValue\n ' ),
207
+ )
208
+ for name , value in cases :
209
+ with self .assertRaisesRegex (ValueError , 'Invalid header' ):
210
+ conn .putheader (name , value )
211
+
156
212
157
213
class BasicTest (TestCase ):
158
214
def test_status_lines (self ):
0 commit comments