13
13
14
14
IP = "1.2.3.4"
15
15
HOST = "docs.google.com"
16
- PATH = (
16
+ PATH_BASE = (
17
17
"/spreadsheets/d/e/2PACX-1vR1WjUKz35-ek6SiR5droDfvPp51MTds4wUs57vEZNh2uDfihSTPhTaiiRo"
18
- "vLbNe1mkeRgurppRJ_Zy/pub?output=tsv"
18
+ "vLbNe1mkeRgurppRJ_Zy/"
19
+ )
20
+ PATH = PATH_BASE + "pub?output=tsv"
21
+
22
+ FILE_REDIRECT = (
23
+ b"e@2PACX-1vR1WjUKz35-ek6SiR5droDfvPp51MTds4wUs57vEZNh2uDfihSTPhTai"
24
+ b"iRovLbNe1mkeRgurppRJ_Zy?output=tsv"
25
+ )
26
+ RELATIVE_RELATIVE_REDIRECT = (
27
+ b"370cmver1f290kjsnpar5ku2h9g/3llvt5u8njbvat22m9l19db1h4/1656191325000/109226138307867586192/*/"
28
+ + FILE_REDIRECT
29
+ )
30
+ RELATIVE_ABSOLUTE_REDIRECT = (
31
+ b"/pub/70cmver1f290kjsnpar5ku2h9g/" + RELATIVE_RELATIVE_REDIRECT
32
+ )
33
+ ABSOLUTE_ABSOLUTE_REDIRECT = (
34
+ b"https://doc-14-2g-sheets.googleusercontent.com" + RELATIVE_ABSOLUTE_REDIRECT
19
35
)
20
36
21
37
# response headers returned from the initial request
26
42
b"Pragma: no-cache\r \n "
27
43
b"Expires: Mon, 01 Jan 1990 00:00:00 GMT\r \n "
28
44
b"Date: Sat, 25 Jun 2022 21:08:48 GMT\r \n "
29
- b"Location: https://doc-14-2g-sheets.googleusercontent.com/pub/70cmver1f290kjsnpar5ku2h9g/3"
30
- b"llvt5u8njbvat22m9l19db1h4/1656191325000"
31
- b"/109226138307867586192/*/e@2PACX-1vR1WjUKz35-ek6SiR5droDfvPp51MTds4wUs57vEZNh2uDfihSTPhTai"
32
- b"iRovLbNe1mkeRgurppRJ_Zy?output=tsv\r \n "
45
+ b"Location: NEW_LOCATION_HERE\r \n "
33
46
b'P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."\r \n '
34
47
b"X-Content-Type-Options: nosniff\r \n "
35
48
b"X-XSS-Protection: 1; mode=block\r \n "
@@ -118,13 +131,16 @@ def _recv_into(self, buf, nbytes=0):
118
131
return read
119
132
120
133
121
- def do_test_chunked_redirect ():
134
+ def test_chunked_absolute_absolute_redirect ():
122
135
pool = mocket .MocketPool ()
123
136
pool .getaddrinfo .return_value = ((None , None , None , None , (IP , 443 )),)
124
137
chunk = _chunk (BODY_REDIRECT , len (BODY_REDIRECT ))
125
138
chunk2 = _chunk (BODY , len (BODY ))
126
139
127
- sock1 = MocketRecvInto (HEADERS_REDIRECT + chunk )
140
+ redirect = HEADERS_REDIRECT .replace (
141
+ b"NEW_LOCATION_HERE" , ABSOLUTE_ABSOLUTE_REDIRECT
142
+ )
143
+ sock1 = MocketRecvInto (redirect + chunk )
128
144
sock2 = mocket .Mocket (HEADERS + chunk2 )
129
145
pool .socket .side_effect = (sock1 , sock2 )
130
146
@@ -135,9 +151,109 @@ def do_test_chunked_redirect():
135
151
sock2 .connect .assert_called_once_with (
136
152
("doc-14-2g-sheets.googleusercontent.com" , 443 )
137
153
)
154
+ sock2 .send .assert_has_calls ([mock .call (RELATIVE_ABSOLUTE_REDIRECT [1 :])])
155
+
156
+ assert response .text == str (BODY , "utf-8" )
157
+
158
+
159
+ def test_chunked_relative_absolute_redirect ():
160
+ pool = mocket .MocketPool ()
161
+ pool .getaddrinfo .return_value = ((None , None , None , None , (IP , 443 )),)
162
+ chunk = _chunk (BODY_REDIRECT , len (BODY_REDIRECT ))
163
+ chunk2 = _chunk (BODY , len (BODY ))
164
+
165
+ redirect = HEADERS_REDIRECT .replace (
166
+ b"NEW_LOCATION_HERE" , RELATIVE_ABSOLUTE_REDIRECT
167
+ )
168
+ sock1 = MocketRecvInto (redirect + chunk )
169
+ sock2 = mocket .Mocket (HEADERS + chunk2 )
170
+ pool .socket .side_effect = (sock1 , sock2 )
171
+
172
+ requests_session = adafruit_requests .Session (pool , mocket .SSLContext ())
173
+ response = requests_session .get ("https://" + HOST + PATH )
174
+
175
+ sock1 .connect .assert_called_once_with ((HOST , 443 ))
176
+ sock2 .connect .assert_called_once_with (("docs.google.com" , 443 ))
177
+ sock2 .send .assert_has_calls ([mock .call (RELATIVE_ABSOLUTE_REDIRECT [1 :])])
178
+
179
+ assert response .text == str (BODY , "utf-8" )
180
+
181
+
182
+ def test_chunked_relative_relative_redirect ():
183
+ pool = mocket .MocketPool ()
184
+ pool .getaddrinfo .return_value = ((None , None , None , None , (IP , 443 )),)
185
+ chunk = _chunk (BODY_REDIRECT , len (BODY_REDIRECT ))
186
+ chunk2 = _chunk (BODY , len (BODY ))
187
+
188
+ redirect = HEADERS_REDIRECT .replace (
189
+ b"NEW_LOCATION_HERE" , RELATIVE_RELATIVE_REDIRECT
190
+ )
191
+ sock1 = MocketRecvInto (redirect + chunk )
192
+ sock2 = mocket .Mocket (HEADERS + chunk2 )
193
+ pool .socket .side_effect = (sock1 , sock2 )
194
+
195
+ requests_session = adafruit_requests .Session (pool , mocket .SSLContext ())
196
+ response = requests_session .get ("https://" + HOST + PATH )
197
+
198
+ sock1 .connect .assert_called_once_with ((HOST , 443 ))
199
+ sock2 .connect .assert_called_once_with (("docs.google.com" , 443 ))
200
+ sock2 .send .assert_has_calls (
201
+ [mock .call (bytes (PATH_BASE [1 :], "utf-8" ) + RELATIVE_RELATIVE_REDIRECT )]
202
+ )
138
203
139
204
assert response .text == str (BODY , "utf-8" )
140
205
141
206
142
- def test_chunked_redirect ():
143
- do_test_chunked_redirect ()
207
+ def test_chunked_relative_relative_redirect_backstep ():
208
+ pool = mocket .MocketPool ()
209
+ pool .getaddrinfo .return_value = ((None , None , None , None , (IP , 443 )),)
210
+ chunk = _chunk (BODY_REDIRECT , len (BODY_REDIRECT ))
211
+ chunk2 = _chunk (BODY , len (BODY ))
212
+
213
+ remove_paths = 2
214
+ backstep = b"../" * remove_paths
215
+ path_base_parts = PATH_BASE .split ("/" )
216
+ # PATH_BASE starts with "/" so skip it and also remove from the count
217
+ path_base = (
218
+ "/" .join (path_base_parts [1 : len (path_base_parts ) - remove_paths - 1 ]) + "/"
219
+ )
220
+
221
+ redirect = HEADERS_REDIRECT .replace (
222
+ b"NEW_LOCATION_HERE" , backstep + RELATIVE_RELATIVE_REDIRECT
223
+ )
224
+ sock1 = MocketRecvInto (redirect + chunk )
225
+ sock2 = mocket .Mocket (HEADERS + chunk2 )
226
+ pool .socket .side_effect = (sock1 , sock2 )
227
+
228
+ requests_session = adafruit_requests .Session (pool , mocket .SSLContext ())
229
+ response = requests_session .get ("https://" + HOST + PATH )
230
+
231
+ sock1 .connect .assert_called_once_with ((HOST , 443 ))
232
+ sock2 .connect .assert_called_once_with (("docs.google.com" , 443 ))
233
+ sock2 .send .assert_has_calls (
234
+ [mock .call (bytes (path_base , "utf-8" ) + RELATIVE_RELATIVE_REDIRECT )]
235
+ )
236
+
237
+ assert response .text == str (BODY , "utf-8" )
238
+
239
+
240
+ def test_chunked_allow_redirects_false ():
241
+ pool = mocket .MocketPool ()
242
+ pool .getaddrinfo .return_value = ((None , None , None , None , (IP , 443 )),)
243
+ chunk = _chunk (BODY_REDIRECT , len (BODY_REDIRECT ))
244
+ chunk2 = _chunk (BODY , len (BODY ))
245
+
246
+ redirect = HEADERS_REDIRECT .replace (
247
+ b"NEW_LOCATION_HERE" , ABSOLUTE_ABSOLUTE_REDIRECT
248
+ )
249
+ sock1 = MocketRecvInto (redirect + chunk )
250
+ sock2 = mocket .Mocket (HEADERS + chunk2 )
251
+ pool .socket .side_effect = (sock1 , sock2 )
252
+
253
+ requests_session = adafruit_requests .Session (pool , mocket .SSLContext ())
254
+ response = requests_session .get ("https://" + HOST + PATH , allow_redirects = False )
255
+
256
+ sock1 .connect .assert_called_once_with ((HOST , 443 ))
257
+ sock2 .connect .assert_not_called ()
258
+
259
+ assert response .text == str (BODY_REDIRECT , "utf-8" )
0 commit comments