OLD | NEW |
1 <script src="framework.js"> | 1 <!-- |
2 </script> | 2 * Copyright (c) 2011 The Chromium Authors. All rights reserved. Use of this |
3 <script> | 3 * source code is governed by a BSD-style license that can be found in the |
4 var pass = chrome.test.callbackPass; | 4 * LICENSE file. |
5 | 5 --> |
6 // Constants as functions, not to be called until after runTests. | 6 <script src="framework.js"></script> |
7 function getURLEchoUserAgent() { | 7 <script src="test_blocking.js"></script> |
8 return getServerURL('echoheader?User-Agent'); | |
9 } | |
10 | |
11 function getURLSetCookie() { | |
12 return getServerURL('set-cookie?Foo=Bar'); | |
13 } | |
14 | |
15 function getURLNonUTF8SetCookie() { | |
16 return getServerURL('set-header?Set-Cookie%3A%20Foo%3D%FE%D1'); | |
17 } | |
18 | |
19 function getURLHttpSimpleLoad() { | |
20 return getServerURL('files/extensions/api_test/webrequest/simpleLoad/a.html'); | |
21 } | |
22 function getURLHttpXHRData() { | |
23 return getServerURL('files/extensions/api_test/webrequest/xhr/data.json'); | |
24 } | |
25 | |
26 function toCharCodes(str) { | |
27 var result = []; | |
28 for (var i = 0; i < str.length; ++i) { | |
29 result[i] = str.charCodeAt(i); | |
30 } | |
31 return result; | |
32 } | |
33 | |
34 runTests([ | |
35 // Navigates to a page with subresources, with a blocking handler that | |
36 // cancels the page request. The page will not load, and we should not | |
37 // see the subresources. | |
38 function complexLoadCancelled() { | |
39 expect( | |
40 [ // events | |
41 { label: "onBeforeRequest", | |
42 event: "onBeforeRequest", | |
43 details: { | |
44 type: "main_frame", | |
45 url: getURL("complexLoad/b.html"), | |
46 frameUrl: getURL("complexLoad/b.html") | |
47 }, | |
48 retval: {cancel: true} | |
49 }, | |
50 // Cancelling is considered an error. | |
51 { label: "onErrorOccurred", | |
52 event: "onErrorOccurred", | |
53 details: { | |
54 url: getURL("complexLoad/b.html"), | |
55 fromCache: false, | |
56 error: "net::ERR_BLOCKED_BY_CLIENT" | |
57 // Request to chrome-extension:// url has no IP. | |
58 } | |
59 }, | |
60 ], | |
61 [ // event order | |
62 ["onBeforeRequest", "onErrorOccurred"] | |
63 ], | |
64 {}, // filter | |
65 ["blocking"]); | |
66 navigateAndWait(getURL("complexLoad/b.html")); | |
67 }, | |
68 | |
69 // Navigates to a page with subresources, with a blocking handler that | |
70 // cancels the page request. The page will not load, and we should not | |
71 // see the subresources. | |
72 function simpleLoadCancelledOnReceiveHeaders() { | |
73 expect( | |
74 [ // events | |
75 { label: "onBeforeRequest", | |
76 event: "onBeforeRequest", | |
77 details: { | |
78 method: "GET", | |
79 type: "main_frame", | |
80 url: getURLHttpSimpleLoad(), | |
81 frameUrl: getURLHttpSimpleLoad() | |
82 }, | |
83 retval: {cancel: false} | |
84 }, | |
85 { label: "onBeforeSendHeaders", | |
86 event: "onBeforeSendHeaders", | |
87 details: { | |
88 url: getURLHttpSimpleLoad(), | |
89 // Note: no requestHeaders because we don't ask for them. | |
90 }, | |
91 }, | |
92 { label: "onSendHeaders", | |
93 event: "onSendHeaders", | |
94 details: { | |
95 url: getURLHttpSimpleLoad() | |
96 } | |
97 }, | |
98 { label: "onHeadersReceived", | |
99 event: "onHeadersReceived", | |
100 details: { | |
101 url: getURLHttpSimpleLoad(), | |
102 statusLine: "HTTP/1.0 200 OK", | |
103 }, | |
104 retval: {cancel: true} | |
105 }, | |
106 // Cancelling is considered an error. | |
107 { label: "onErrorOccurred", | |
108 event: "onErrorOccurred", | |
109 details: { | |
110 url: getURLHttpSimpleLoad(), | |
111 fromCache: false, | |
112 error: "net::ERR_BLOCKED_BY_CLIENT" | |
113 // Request to chrome-extension:// url has no IP. | |
114 } | |
115 }, | |
116 ], | |
117 [ // event order | |
118 ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders", | |
119 "onHeadersReceived", "onErrorOccurred"] | |
120 ], | |
121 {}, // filter | |
122 ["blocking"]); | |
123 navigateAndWait(getURLHttpSimpleLoad()); | |
124 }, | |
125 | |
126 // Navigates to a page with a blocking handler that redirects to a different | |
127 // page. | |
128 // TODO(mpcomplete): We should see an onBeforeRedirect as well, but our | |
129 // process switching logic cancels the original redirect request and | |
130 // starts a new one instead. See http://crbug.com/79520. | |
131 function complexLoadRedirected() { | |
132 expect( | |
133 [ // events | |
134 { label: "onBeforeRequest-1", | |
135 event: "onBeforeRequest", | |
136 details: { | |
137 url: getURL("complexLoad/a.html"), | |
138 frameUrl: getURL("complexLoad/a.html") | |
139 }, | |
140 retval: {redirectUrl: getURL("simpleLoad/a.html")} | |
141 }, | |
142 { label: "onErrorOccurred-1", | |
143 event: "onErrorOccurred", | |
144 details: { | |
145 url: getURL("complexLoad/a.html"), | |
146 fromCache: false, | |
147 error: "net::ERR_ABORTED" | |
148 // Request to chrome-extension:// url has no IP. | |
149 } | |
150 }, | |
151 { label: "onBeforeRequest-2", | |
152 event: "onBeforeRequest", | |
153 details: { | |
154 url: getURL("simpleLoad/a.html"), | |
155 frameUrl: getURL("simpleLoad/a.html"), | |
156 }, | |
157 }, | |
158 { label: "onResponseStarted", | |
159 event: "onResponseStarted", | |
160 details: { | |
161 url: getURL("simpleLoad/a.html"), | |
162 fromCache: false, | |
163 statusCode: 200, | |
164 statusLine: "HTTP/1.1 200 OK", | |
165 // Request to chrome-extension:// url has no IP. | |
166 } | |
167 }, | |
168 { label: "onCompleted", | |
169 event: "onCompleted", | |
170 details: { | |
171 url: getURL("simpleLoad/a.html"), | |
172 fromCache: false, | |
173 statusCode: 200, | |
174 statusLine: "HTTP/1.1 200 OK", | |
175 // Request to chrome-extension:// url has no IP. | |
176 } | |
177 }, | |
178 ], | |
179 [ // event order | |
180 ["onBeforeRequest-1", "onErrorOccurred-1", "onBeforeRequest-2", | |
181 "onResponseStarted", "onCompleted"], | |
182 ], | |
183 {}, // filter | |
184 ["blocking"]); | |
185 navigateAndWait(getURL("complexLoad/a.html")); | |
186 }, | |
187 | |
188 // Loads a testserver page that echoes the User-Agent header that was | |
189 // sent to fetch it. We modify the outgoing User-Agent in | |
190 // onBeforeSendHeaders, so we should see that modified version. | |
191 function modifyRequestHeaders() { | |
192 expect( | |
193 [ // events | |
194 { label: "onBeforeRequest", | |
195 event: "onBeforeRequest", | |
196 details: { | |
197 url: getURLEchoUserAgent(), | |
198 frameUrl: getURLEchoUserAgent() | |
199 } | |
200 }, | |
201 { label: "onBeforeSendHeaders", | |
202 event: "onBeforeSendHeaders", | |
203 details: { | |
204 url: getURLEchoUserAgent(), | |
205 // Note: no requestHeaders because we don't ask for them. | |
206 }, | |
207 retval: {requestHeaders: [{name: "User-Agent", value: "FoobarUA"}]} | |
208 }, | |
209 { label: "onSendHeaders", | |
210 event: "onSendHeaders", | |
211 details: { | |
212 url: getURLEchoUserAgent() | |
213 } | |
214 }, | |
215 { label: "onHeadersReceived", | |
216 event: "onHeadersReceived", | |
217 details: { | |
218 url: getURLEchoUserAgent(), | |
219 statusLine: "HTTP/1.0 200 OK", | |
220 } | |
221 }, | |
222 { label: "onResponseStarted", | |
223 event: "onResponseStarted", | |
224 details: { | |
225 url: getURLEchoUserAgent(), | |
226 fromCache: false, | |
227 statusCode: 200, | |
228 ip: "127.0.0.1", | |
229 statusLine: "HTTP/1.0 200 OK", | |
230 } | |
231 }, | |
232 { label: "onCompleted", | |
233 event: "onCompleted", | |
234 details: { | |
235 url: getURLEchoUserAgent(), | |
236 fromCache: false, | |
237 statusCode: 200, | |
238 ip: "127.0.0.1", | |
239 statusLine: "HTTP/1.0 200 OK", | |
240 } | |
241 }, | |
242 ], | |
243 [ // event order | |
244 ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders", | |
245 "onHeadersReceived", "onResponseStarted", "onCompleted"] | |
246 ], | |
247 {}, ["blocking"]); | |
248 // Check the page content for our modified User-Agent string. | |
249 navigateAndWait(getURLEchoUserAgent(), function() { | |
250 chrome.test.listenOnce(chrome.extension.onRequest, function(request) { | |
251 chrome.test.assertTrue(request.pass, "Request header was not set."); | |
252 }); | |
253 chrome.tabs.executeScript(tabId, | |
254 { | |
255 code: "chrome.extension.sendRequest(" + | |
256 "{pass: document.body.innerText.indexOf('FoobarUA') >= 0});" | |
257 }); | |
258 }); | |
259 }, | |
260 | |
261 // Loads a testserver page that echoes the User-Agent header that was | |
262 // sent to fetch it. We modify the outgoing User-Agent in | |
263 // onBeforeSendHeaders, so we should see that modified version. | |
264 // In this version we check whether we can set binary header values. | |
265 function modifyBinaryRequestHeaders() { | |
266 expect( | |
267 [ // events | |
268 { label: "onBeforeRequest", | |
269 event: "onBeforeRequest", | |
270 details: { | |
271 url: getURLEchoUserAgent(), | |
272 frameUrl: getURLEchoUserAgent() | |
273 } | |
274 }, | |
275 { label: "onBeforeSendHeaders", | |
276 event: "onBeforeSendHeaders", | |
277 details: { | |
278 url: getURLEchoUserAgent(), | |
279 // Note: no requestHeaders because we don't ask for them. | |
280 }, | |
281 retval: {requestHeaders: [{name: "User-Agent", | |
282 binaryValue: toCharCodes("FoobarUA")}]} | |
283 }, | |
284 { label: "onSendHeaders", | |
285 event: "onSendHeaders", | |
286 details: { | |
287 url: getURLEchoUserAgent() | |
288 } | |
289 }, | |
290 { label: "onHeadersReceived", | |
291 event: "onHeadersReceived", | |
292 details: { | |
293 url: getURLEchoUserAgent(), | |
294 statusLine: "HTTP/1.0 200 OK", | |
295 } | |
296 }, | |
297 { label: "onResponseStarted", | |
298 event: "onResponseStarted", | |
299 details: { | |
300 url: getURLEchoUserAgent(), | |
301 fromCache: false, | |
302 statusCode: 200, | |
303 ip: "127.0.0.1", | |
304 statusLine: "HTTP/1.0 200 OK", | |
305 } | |
306 }, | |
307 { label: "onCompleted", | |
308 event: "onCompleted", | |
309 details: { | |
310 url: getURLEchoUserAgent(), | |
311 fromCache: false, | |
312 statusCode: 200, | |
313 ip: "127.0.0.1", | |
314 statusLine: "HTTP/1.0 200 OK", | |
315 } | |
316 }, | |
317 ], | |
318 [ // event order | |
319 ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders", | |
320 "onHeadersReceived", "onResponseStarted", "onCompleted"] | |
321 ], | |
322 {}, ["blocking"]); | |
323 // Check the page content for our modified User-Agent string. | |
324 navigateAndWait(getURLEchoUserAgent(), function() { | |
325 chrome.test.listenOnce(chrome.extension.onRequest, function(request) { | |
326 chrome.test.assertTrue(request.pass, "Request header was not set."); | |
327 }); | |
328 chrome.tabs.executeScript(tabId, | |
329 { | |
330 code: "chrome.extension.sendRequest(" + | |
331 "{pass: document.body.innerText.indexOf('FoobarUA') >= 0});" | |
332 }); | |
333 }); | |
334 }, | |
335 | |
336 // Loads a testserver page that sets a cookie "Foo=Bar" but removes | |
337 // the cookies from the response headers so that they are not set. | |
338 function modifyResponseHeaders() { | |
339 expect( | |
340 [ // events | |
341 { label: "onBeforeRequest", | |
342 event: "onBeforeRequest", | |
343 details: { | |
344 method: "GET", | |
345 type: "main_frame", | |
346 url: getURLSetCookie(), | |
347 frameUrl: getURLSetCookie() | |
348 } | |
349 }, | |
350 { label: "onBeforeSendHeaders", | |
351 event: "onBeforeSendHeaders", | |
352 details: { | |
353 url: getURLSetCookie(), | |
354 // Note: no requestHeaders because we don't ask for them. | |
355 }, | |
356 }, | |
357 { label: "onSendHeaders", | |
358 event: "onSendHeaders", | |
359 details: { | |
360 url: getURLSetCookie(), | |
361 } | |
362 }, | |
363 { label: "onHeadersReceived", | |
364 event: "onHeadersReceived", | |
365 details: { | |
366 url: getURLSetCookie(), | |
367 statusLine: "HTTP/1.0 200 OK", | |
368 responseHeadersExist: true, | |
369 }, | |
370 retval_function: function(name, details) { | |
371 responseHeaders = details.responseHeaders; | |
372 var found = false; | |
373 for (var i = 0; i < responseHeaders.length; ++i) { | |
374 if (responseHeaders[i].name === "Set-Cookie" && | |
375 responseHeaders[i].value.indexOf("Foo") != -1) { | |
376 found = true; | |
377 responseHeaders.splice(i); | |
378 break; | |
379 } | |
380 } | |
381 chrome.test.assertTrue(found); | |
382 return {responseHeaders: responseHeaders}; | |
383 } | |
384 }, | |
385 { label: "onResponseStarted", | |
386 event: "onResponseStarted", | |
387 details: { | |
388 url: getURLSetCookie(), | |
389 fromCache: false, | |
390 statusCode: 200, | |
391 statusLine: "HTTP/1.0 200 OK", | |
392 ip: "127.0.0.1", | |
393 responseHeadersExist: true, | |
394 } | |
395 }, | |
396 { label: "onCompleted", | |
397 event: "onCompleted", | |
398 details: { | |
399 url: getURLSetCookie(), | |
400 fromCache: false, | |
401 statusCode: 200, | |
402 statusLine: "HTTP/1.0 200 OK", | |
403 ip: "127.0.0.1", | |
404 responseHeadersExist: true, | |
405 } | |
406 }, | |
407 ], | |
408 [ // event order | |
409 ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders", | |
410 "onHeadersReceived", "onResponseStarted", "onCompleted"] | |
411 ], | |
412 {}, ["blocking", "responseHeaders"]); | |
413 // Check that the cookie was really removed. | |
414 navigateAndWait(getURLSetCookie(), function() { | |
415 chrome.test.listenOnce(chrome.extension.onRequest, function(request) { | |
416 chrome.test.assertTrue(request.pass, "Cookie was not removed."); | |
417 }); | |
418 chrome.tabs.executeScript(tabId, | |
419 { code: "chrome.extension.sendRequest(" + | |
420 "{pass: document.cookie.indexOf('Foo') == -1});" | |
421 }); | |
422 }); | |
423 }, | |
424 | |
425 // Loads a testserver page that sets a cookie "Foo=U+FDD1" which is not a | |
426 // valid UTF-8 code point. Therefore, it cannot be passed to JavaScript | |
427 // as a normal string. | |
428 function handleNonUTF8InModifyResponseHeaders() { | |
429 expect( | |
430 [ // events | |
431 { label: "onBeforeRequest", | |
432 event: "onBeforeRequest", | |
433 details: { | |
434 method: "GET", | |
435 type: "main_frame", | |
436 url: getURLNonUTF8SetCookie(), | |
437 frameUrl: getURLNonUTF8SetCookie() | |
438 } | |
439 }, | |
440 { label: "onBeforeSendHeaders", | |
441 event: "onBeforeSendHeaders", | |
442 details: { | |
443 url: getURLNonUTF8SetCookie(), | |
444 // Note: no requestHeaders because we don't ask for them. | |
445 }, | |
446 }, | |
447 { label: "onSendHeaders", | |
448 event: "onSendHeaders", | |
449 details: { | |
450 url: getURLNonUTF8SetCookie(), | |
451 } | |
452 }, | |
453 { label: "onHeadersReceived", | |
454 event: "onHeadersReceived", | |
455 details: { | |
456 url: getURLNonUTF8SetCookie(), | |
457 statusLine: "HTTP/1.0 200 OK", | |
458 responseHeadersExist: true, | |
459 }, | |
460 retval_function: function(name, details) { | |
461 console.log(JSON.stringify(details)); | |
462 responseHeaders = details.responseHeaders; | |
463 var found = false; | |
464 var expectedValue = [ | |
465 "F".charCodeAt(0), | |
466 "o".charCodeAt(0), | |
467 "o".charCodeAt(0), | |
468 0x3D, 0xFE, 0xD1 | |
469 ]; | |
470 | |
471 for (var i = 0; i < responseHeaders.length; ++i) { | |
472 if (responseHeaders[i].name === "Set-Cookie" && | |
473 deepEq(responseHeaders[i].binaryValue, expectedValue)) { | |
474 found = true; | |
475 responseHeaders.splice(i); | |
476 break; | |
477 } | |
478 } | |
479 chrome.test.assertTrue(found); | |
480 return {responseHeaders: responseHeaders}; | |
481 } | |
482 }, | |
483 { label: "onResponseStarted", | |
484 event: "onResponseStarted", | |
485 details: { | |
486 url: getURLNonUTF8SetCookie(), | |
487 fromCache: false, | |
488 statusCode: 200, | |
489 statusLine: "HTTP/1.0 200 OK", | |
490 ip: "127.0.0.1", | |
491 responseHeadersExist: true, | |
492 } | |
493 }, | |
494 { label: "onCompleted", | |
495 event: "onCompleted", | |
496 details: { | |
497 url: getURLNonUTF8SetCookie(), | |
498 fromCache: false, | |
499 statusCode: 200, | |
500 statusLine: "HTTP/1.0 200 OK", | |
501 ip: "127.0.0.1", | |
502 responseHeadersExist: true, | |
503 } | |
504 }, | |
505 ], | |
506 [ // event order | |
507 ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders", | |
508 "onHeadersReceived", "onResponseStarted", "onCompleted"] | |
509 ], | |
510 {}, ["blocking", "responseHeaders"]); | |
511 // Check that the cookie was really removed. | |
512 navigateAndWait(getURLNonUTF8SetCookie(), function() { | |
513 chrome.test.listenOnce(chrome.extension.onRequest, function(request) { | |
514 chrome.test.assertTrue(request.pass, "Cookie was not removed."); | |
515 }); | |
516 chrome.tabs.executeScript(tabId, | |
517 { code: "chrome.extension.sendRequest(" + | |
518 "{pass: document.cookie.indexOf('Foo') == -1});" | |
519 }); | |
520 }); | |
521 }, | |
522 | |
523 // Checks that XHR requests from ourself are invisible to blocking handlers. | |
524 function xhrsFromOurselfAreInvisible() { | |
525 expect( | |
526 [ // events | |
527 { label: "a-onBeforeRequest", | |
528 event: "onBeforeRequest", | |
529 details: { | |
530 url: getURL("simpleLoad/a.html"), | |
531 frameUrl: getURL("simpleLoad/a.html") | |
532 } | |
533 }, | |
534 { label: "a-onResponseStarted", | |
535 event: "onResponseStarted", | |
536 details: { | |
537 url: getURL("simpleLoad/a.html"), | |
538 statusCode: 200, | |
539 fromCache: false, | |
540 statusLine: "HTTP/1.1 200 OK", | |
541 // Request to chrome-extension:// url has no IP. | |
542 } | |
543 }, | |
544 { label: "a-onCompleted", | |
545 event: "onCompleted", | |
546 details: { | |
547 url: getURL("simpleLoad/a.html"), | |
548 statusCode: 200, | |
549 fromCache: false, | |
550 statusLine: "HTTP/1.1 200 OK", | |
551 // Request to chrome-extension:// url has no IP. | |
552 } | |
553 }, | |
554 // We do not see onBeforeRequest for the XHR request here because it is | |
555 // handled by a blocking handler. | |
556 { label: "x-onSendHeaders", | |
557 event: "onSendHeaders", | |
558 details: { | |
559 url: getURLHttpXHRData(), | |
560 tabId: 1, | |
561 type: "xmlhttprequest", | |
562 } | |
563 }, | |
564 { label: "x-onResponseStarted", | |
565 event: "onResponseStarted", | |
566 details: { | |
567 url: getURLHttpXHRData(), | |
568 statusCode: 200, | |
569 fromCache: false, | |
570 statusLine: "HTTP/1.0 200 OK", | |
571 tabId: 1, | |
572 type: "xmlhttprequest", | |
573 ip: "127.0.0.1", | |
574 // Request to chrome-extension:// url has no IP. | |
575 } | |
576 }, | |
577 { label: "x-onCompleted", | |
578 event: "onCompleted", | |
579 details: { | |
580 url: getURLHttpXHRData(), | |
581 statusCode: 200, | |
582 fromCache: false, | |
583 statusLine: "HTTP/1.0 200 OK", | |
584 tabId: 1, | |
585 type: "xmlhttprequest", | |
586 ip: "127.0.0.1", | |
587 // Request to chrome-extension:// url has no IP. | |
588 } | |
589 }, | |
590 { label: "b-onBeforeRequest", | |
591 event: "onBeforeRequest", | |
592 details: { | |
593 url: getURL("complexLoad/b.jpg"), | |
594 frameUrl: getURL("complexLoad/b.jpg") | |
595 } | |
596 }, | |
597 { label: "b-onResponseStarted", | |
598 event: "onResponseStarted", | |
599 details: { | |
600 url: getURL("complexLoad/b.jpg"), | |
601 statusCode: 200, | |
602 fromCache: false, | |
603 statusLine: "HTTP/1.1 200 OK", | |
604 // Request to chrome-extension:// url has no IP. | |
605 } | |
606 }, | |
607 { label: "b-onCompleted", | |
608 event: "onCompleted", | |
609 details: { | |
610 url: getURL("complexLoad/b.jpg"), | |
611 statusCode: 200, | |
612 fromCache: false, | |
613 statusLine: "HTTP/1.1 200 OK", | |
614 // Request to chrome-extension:// url has no IP. | |
615 } | |
616 }, | |
617 ], | |
618 [ // event order | |
619 ["a-onBeforeRequest", "a-onResponseStarted", "a-onCompleted", | |
620 "x-onSendHeaders", "x-onResponseStarted", "x-onCompleted", | |
621 "b-onBeforeRequest", "b-onResponseStarted", "b-onCompleted"] | |
622 ], | |
623 {}, ["blocking"]); | |
624 // Check the page content for our modified User-Agent string. | |
625 navigateAndWait(getURL("simpleLoad/a.html"), function() { | |
626 var req = new XMLHttpRequest(); | |
627 var asynchronous = false; | |
628 req.open("GET", getURLHttpXHRData(), asynchronous); | |
629 req.send(null); | |
630 navigateAndWait(getURL("complexLoad/b.jpg")); | |
631 }); | |
632 }, | |
633 ]); | |
634 </script> | |
OLD | NEW |