@@ -145,6 +145,33 @@ def test_putheader(self):
145145 conn .putheader ('Content-length' ,42 )
146146 self .assertIn ('Content-length: 42' , conn ._buffer )
147147
148+ conn .putheader ('Foo' , ' bar ' )
149+ self .assertIn (b'Foo: bar ' , conn ._buffer )
150+ conn .putheader ('Bar' , '\t baz\t ' )
151+ self .assertIn (b'Bar: \t baz\t ' , conn ._buffer )
152+ conn .putheader ('Authorization' , 'Bearer mytoken' )
153+ self .assertIn (b'Authorization: Bearer mytoken' , conn ._buffer )
154+ conn .putheader ('IterHeader' , 'IterA' , 'IterB' )
155+ self .assertIn (b'IterHeader: IterA\r \n \t IterB' , conn ._buffer )
156+ conn .putheader ('LatinHeader' , b'\xFF ' )
157+ self .assertIn (b'LatinHeader: \xFF ' , conn ._buffer )
158+ conn .putheader ('Utf8Header' , b'\xc3 \x80 ' )
159+ self .assertIn (b'Utf8Header: \xc3 \x80 ' , conn ._buffer )
160+ conn .putheader ('C1-Control' , b'next\x85 line' )
161+ self .assertIn (b'C1-Control: next\x85 line' , conn ._buffer )
162+ conn .putheader ('Embedded-Fold-Space' , 'is\r \n allowed' )
163+ self .assertIn (b'Embedded-Fold-Space: is\r \n allowed' , conn ._buffer )
164+ conn .putheader ('Embedded-Fold-Tab' , 'is\r \n \t allowed' )
165+ self .assertIn (b'Embedded-Fold-Tab: is\r \n \t allowed' , conn ._buffer )
166+ conn .putheader ('Key Space' , 'value' )
167+ self .assertIn (b'Key Space: value' , conn ._buffer )
168+ conn .putheader ('KeySpace ' , 'value' )
169+ self .assertIn (b'KeySpace : value' , conn ._buffer )
170+ conn .putheader (b'Nonbreak\xa0 Space' , 'value' )
171+ self .assertIn (b'Nonbreak\xa0 Space: value' , conn ._buffer )
172+ conn .putheader (b'\xa0 NonbreakSpace' , 'value' )
173+ self .assertIn (b'\xa0 NonbreakSpace: value' , conn ._buffer )
174+
148175 def test_ipv6host_header (self ):
149176 # Default host header on IPv6 transaction should wrapped by [] if
150177 # its actual IPv6 address
@@ -174,6 +201,35 @@ def test_malformed_headers_coped_with(self):
174201 self .assertEqual (resp .getheader ('First' ), 'val' )
175202 self .assertEqual (resp .getheader ('Second' ), 'val' )
176203
204+ def test_invalid_headers (self ):
205+ conn = httplib .HTTPConnection ('example.com' )
206+ conn .sock = FakeSocket ('' )
207+ conn .putrequest ('GET' , '/' )
208+
209+ # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no
210+ # longer allowed in header names
211+ cases = (
212+ (b'Invalid\r \n Name' , b'ValidValue' ),
213+ (b'Invalid\r Name' , b'ValidValue' ),
214+ (b'Invalid\n Name' , b'ValidValue' ),
215+ (b'\r \n InvalidName' , b'ValidValue' ),
216+ (b'\r InvalidName' , b'ValidValue' ),
217+ (b'\n InvalidName' , b'ValidValue' ),
218+ (b' InvalidName' , b'ValidValue' ),
219+ (b'\t InvalidName' , b'ValidValue' ),
220+ (b'Invalid:Name' , b'ValidValue' ),
221+ (b':InvalidName' , b'ValidValue' ),
222+ (b'ValidName' , b'Invalid\r \n Value' ),
223+ (b'ValidName' , b'Invalid\r Value' ),
224+ (b'ValidName' , b'Invalid\n Value' ),
225+ (b'ValidName' , b'InvalidValue\r \n ' ),
226+ (b'ValidName' , b'InvalidValue\r ' ),
227+ (b'ValidName' , b'InvalidValue\n ' ),
228+ )
229+ for name , value in cases :
230+ with self .assertRaisesRegexp (ValueError , 'Invalid header' ):
231+ conn .putheader (name , value )
232+
177233
178234class BasicTest (TestCase ):
179235 def test_status_lines (self ):
0 commit comments