2 # Copyright 2012 Google Inc. All Rights Reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
19 import platformsettings
22 class RealHttpFetchTest(unittest
.TestCase
):
24 # Initialize test data
25 CONTENT_TYPE
= 'content-type: image/x-icon'
26 COOKIE_1
= ('Set-Cookie: GMAIL_IMP=EXPIRED; '
27 'Expires=Thu, 12-Jul-2012 22:41:22 GMT; '
29 COOKIE_2
= ('Set-Cookie: GMAIL_STAT_205a=EXPIRED; '
30 'Expires=Thu, 12-Jul-2012 22:42:24 GMT; '
32 FIRST_LINE
= 'fake-header: first line'
33 SECOND_LINE
= ' second line'
34 THIRD_LINE
= '\tthird line'
35 BAD_HEADER
= 'this is a bad header'
37 def test__GetHeaderNameValueBasic(self
):
38 """Test _GetHeaderNameValue with normal header."""
40 real_http_fetch
= httpclient
.RealHttpFetch
41 name_value
= real_http_fetch
._GetHeaderNameValue
(self
.CONTENT_TYPE
)
42 self
.assertEqual(name_value
, ('content-type', 'image/x-icon'))
44 def test__GetHeaderNameValueLowercasesName(self
):
45 """_GetHeaderNameValue lowercases header name."""
47 real_http_fetch
= httpclient
.RealHttpFetch
48 header
= 'X-Google-Gfe-Backend-Request-Info: eid=1KMAUMeiK4eMiAL52YyMBg'
49 expected
= ('x-google-gfe-backend-request-info',
50 'eid=1KMAUMeiK4eMiAL52YyMBg')
51 name_value
= real_http_fetch
._GetHeaderNameValue
(header
)
52 self
.assertEqual(name_value
, expected
)
54 def test__GetHeaderNameValueBadLineGivesNone(self
):
55 """_GetHeaderNameValue returns None for a header in wrong format."""
57 real_http_fetch
= httpclient
.RealHttpFetch
58 name_value
= real_http_fetch
._GetHeaderNameValue
(self
.BAD_HEADER
)
59 self
.assertIsNone(name_value
)
61 def test__ToTuplesBasic(self
):
62 """Test _ToTuples with normal input."""
64 real_http_fetch
= httpclient
.RealHttpFetch
65 headers
= [self
.CONTENT_TYPE
, self
.COOKIE_1
, self
.FIRST_LINE
]
66 result
= real_http_fetch
._ToTuples
(headers
)
67 expected
= [('content-type', 'image/x-icon'),
68 ('set-cookie', self
.COOKIE_1
[12:]),
69 ('fake-header', 'first line')]
70 self
.assertEqual(result
, expected
)
72 def test__ToTuplesMultipleHeadersWithSameName(self
):
73 """Test mulitple headers with the same name."""
75 real_http_fetch
= httpclient
.RealHttpFetch
76 headers
= [self
.CONTENT_TYPE
, self
.COOKIE_1
, self
.COOKIE_2
, self
.FIRST_LINE
]
77 result
= real_http_fetch
._ToTuples
(headers
)
78 expected
= [('content-type', 'image/x-icon'),
79 ('set-cookie', self
.COOKIE_1
[12:]),
80 ('set-cookie', self
.COOKIE_2
[12:]),
81 ('fake-header', 'first line')]
82 self
.assertEqual(result
, expected
)
84 def test__ToTuplesAppendsContinuationLine(self
):
85 """Test continuation line is handled."""
87 real_http_fetch
= httpclient
.RealHttpFetch
88 headers
= [self
.CONTENT_TYPE
, self
.COOKIE_1
, self
.FIRST_LINE
,
89 self
.SECOND_LINE
, self
.THIRD_LINE
]
90 result
= real_http_fetch
._ToTuples
(headers
)
91 expected
= [('content-type', 'image/x-icon'),
92 ('set-cookie', self
.COOKIE_1
[12:]),
93 ('fake-header', 'first line\n second line\n third line')]
94 self
.assertEqual(result
, expected
)
96 def test__ToTuplesIgnoresBadHeader(self
):
97 """Test bad header is ignored."""
99 real_http_fetch
= httpclient
.RealHttpFetch
100 bad_headers
= [self
.CONTENT_TYPE
, self
.BAD_HEADER
, self
.COOKIE_1
]
101 expected
= [('content-type', 'image/x-icon'),
102 ('set-cookie', self
.COOKIE_1
[12:])]
103 result
= real_http_fetch
._ToTuples
(bad_headers
)
104 self
.assertEqual(result
, expected
)
106 def test__ToTuplesIgnoresMisplacedContinuationLine(self
):
107 """Test misplaced continuation line is ignored."""
109 real_http_fetch
= httpclient
.RealHttpFetch
110 misplaced_headers
= [self
.THIRD_LINE
, self
.CONTENT_TYPE
,
111 self
.COOKIE_1
, self
.FIRST_LINE
, self
.SECOND_LINE
]
112 result
= real_http_fetch
._ToTuples
(misplaced_headers
)
113 expected
= [('content-type', 'image/x-icon'),
114 ('set-cookie', self
.COOKIE_1
[12:]),
115 ('fake-header', 'first line\n second line')]
116 self
.assertEqual(result
, expected
)
119 class RealHttpFetchGetConnectionTest(unittest
.TestCase
):
120 """Test that a connection is made with request IP/port or proxy IP/port."""
123 def real_dns_lookup(host
):
125 'example.com': '127.127.127.127',
126 'proxy.com': '2.2.2.2',
128 self
.fetch
= httpclient
.RealHttpFetch(real_dns_lookup
)
129 self
.https_proxy
= None
130 self
.http_proxy
= None
131 def get_proxy(is_ssl
):
132 return self
.https_proxy
if is_ssl
else self
.http_proxy
133 self
.fetch
._get
_system
_proxy
= get_proxy
135 def set_http_proxy(self
, host
, port
):
136 self
.http_proxy
= platformsettings
.SystemProxy(host
, port
)
138 def set_https_proxy(self
, host
, port
):
139 self
.https_proxy
= platformsettings
.SystemProxy(host
, port
)
141 def test_get_connection_without_proxy_connects_to_host_ip(self
):
142 """HTTP connection with no proxy connects to host IP."""
143 self
.set_http_proxy(host
=None, port
=None)
144 connection
= self
.fetch
._get
_connection
('example.com', None, is_ssl
=False)
145 self
.assertEqual('127.127.127.127', connection
.host
)
146 self
.assertEqual(80, connection
.port
) # default HTTP port
148 def test_get_connection_without_proxy_uses_nondefault_request_port(self
):
149 """HTTP connection with no proxy connects with request port."""
150 self
.set_https_proxy(host
=None, port
=None)
151 connection
= self
.fetch
._get
_connection
('example.com', 8888, is_ssl
=False)
152 self
.assertEqual('127.127.127.127', connection
.host
)
153 self
.assertEqual(8888, connection
.port
) # request HTTP port
155 def test_get_connection_with_proxy_uses_proxy_port(self
):
156 """HTTP connection with proxy connects used proxy port."""
157 self
.set_http_proxy(host
='proxy.com', port
=None)
158 connection
= self
.fetch
._get
_connection
('example.com', 8888, is_ssl
=False)
159 self
.assertEqual('2.2.2.2', connection
.host
) # proxy IP
160 self
.assertEqual(80, connection
.port
) # proxy port (default HTTP)
162 def test_ssl_get_connection_without_proxy_connects_to_host_ip(self
):
163 """HTTPS (SSL) connection with no proxy connects to host IP."""
164 self
.set_https_proxy(host
=None, port
=None)
165 connection
= self
.fetch
._get
_connection
('example.com', None, is_ssl
=True)
166 self
.assertEqual('127.127.127.127', connection
.host
)
167 self
.assertEqual(443, connection
.port
) # default SSL port
169 def test_ssl_get_connection_with_proxy_connects_to_proxy_ip(self
):
170 """HTTPS (SSL) connection with proxy connects to proxy IP."""
171 self
.set_https_proxy(host
='proxy.com', port
=8443)
172 connection
= self
.fetch
._get
_connection
('example.com', None, is_ssl
=True)
173 self
.assertEqual('2.2.2.2', connection
.host
) # proxy IP
174 self
.assertEqual(8443, connection
.port
) # SSL proxy port
176 def test_ssl_get_connection_with_proxy_tunnels_to_host(self
):
177 """HTTPS (SSL) connection with proxy tunnels to target host."""
178 self
.set_https_proxy(host
='proxy.com', port
=8443)
179 connection
= self
.fetch
._get
_connection
('example.com', None, is_ssl
=True)
180 self
.assertEqual('example.com', connection
._tunnel
_host
) # host name
181 self
.assertEqual(None, connection
._tunnel
_port
) # host port
184 if __name__
== '__main__':