Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / test / data / extensions / api_test / webrequest / test_blocking.js
blob3cd5d9bbf4a9344b615ba40d06d94539cc803646
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var pass = chrome.test.callbackPass;
7 // Constants as functions, not to be called until after runTests.
8 function getURLEchoUserAgent() {
9   return getServerURL('echoheader?User-Agent');
12 function getURLSetCookie() {
13   return getServerURL('set-cookie?Foo=Bar');
16 function getURLNonUTF8SetCookie() {
17   return getServerURL('set-header?Set-Cookie%3A%20Foo%3D%FE%D1');
20 function getURLHttpSimpleLoad() {
21   return getServerURL('extensions/api_test/webrequest/simpleLoad/a.html');
23 function getURLHttpXHRData() {
24   return getServerURL('extensions/api_test/webrequest/xhr/data.json');
27 function toCharCodes(str) {
28   var result = [];
29   for (var i = 0; i < str.length; ++i) {
30     result[i] = str.charCodeAt(i);
31   }
32   return result;
35 runTests([
36   // Navigates to a page with subresources, with a blocking handler that
37   // cancels the page request. The page will not load, and we should not
38   // see the subresources.
39   function complexLoadCancelled() {
40     expect(
41       [  // events
42         { label: "onBeforeRequest",
43           event: "onBeforeRequest",
44           details: {
45             type: "main_frame",
46             url: getURL("complexLoad/b.html"),
47             frameUrl: getURL("complexLoad/b.html")
48           },
49           retval: {cancel: true}
50         },
51         // Cancelling is considered an error.
52         { label: "onErrorOccurred",
53           event: "onErrorOccurred",
54           details: {
55             url: getURL("complexLoad/b.html"),
56             fromCache: false,
57             error: "net::ERR_BLOCKED_BY_CLIENT"
58             // Request to chrome-extension:// url has no IP.
59           }
60         },
61       ],
62       [  // event order
63         ["onBeforeRequest", "onErrorOccurred"]
64       ],
65       {urls: ["<all_urls>"]},  // filter
66       ["blocking"]);
67     navigateAndWait(getURL("complexLoad/b.html"));
68   },
70   // Navigates to a page with subresources, with a blocking handler that
71   // cancels the page request. The page will not load, and we should not
72   // see the subresources.
73   function simpleLoadCancelledOnReceiveHeaders() {
74     expect(
75       [  // events
76         { label: "onBeforeRequest",
77           event: "onBeforeRequest",
78           details: {
79             method: "GET",
80             type: "main_frame",
81             url: getURLHttpSimpleLoad(),
82             frameUrl: getURLHttpSimpleLoad()
83           },
84           retval: {cancel: false}
85         },
86         { label: "onBeforeSendHeaders",
87           event: "onBeforeSendHeaders",
88           details: {
89             url: getURLHttpSimpleLoad(),
90             // Note: no requestHeaders because we don't ask for them.
91           },
92         },
93         { label: "onSendHeaders",
94           event: "onSendHeaders",
95           details: {
96             url: getURLHttpSimpleLoad()
97           }
98         },
99         { label: "onHeadersReceived",
100           event: "onHeadersReceived",
101           details: {
102             url: getURLHttpSimpleLoad(),
103             statusLine: "HTTP/1.1 200 OK",
104             statusCode: 200,
105           },
106           retval: {cancel: true}
107         },
108         // Cancelling is considered an error.
109         { label: "onErrorOccurred",
110           event: "onErrorOccurred",
111           details: {
112             url: getURLHttpSimpleLoad(),
113             fromCache: false,
114             error: "net::ERR_BLOCKED_BY_CLIENT"
115             // Request to chrome-extension:// url has no IP.
116           }
117         },
118       ],
119       [  // event order
120         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
121          "onHeadersReceived", "onErrorOccurred"]
122       ],
123       {urls: ["<all_urls>"]},  // filter
124       ["blocking"]);
125     navigateAndWait(getURLHttpSimpleLoad());
126   },
128   // Navigates to a page and provides invalid header information. The request
129   // should continue as if the headers were not changed.
130   function simpleLoadIgnoreOnBeforeSendHeadersInvalidHeaders() {
131     expect(
132       [  // events
133         { label: "onBeforeRequest",
134           event: "onBeforeRequest",
135           details: {
136             method: "GET",
137             type: "main_frame",
138             url: getURLHttpSimpleLoad(),
139             frameUrl: getURLHttpSimpleLoad()
140           },
141         },
142         { label: "onBeforeSendHeaders",
143           event: "onBeforeSendHeaders",
144           details: {
145             url: getURLHttpSimpleLoad(),
146             requestHeadersValid: true
147           },
148           retval: {requestHeaders: [{name: "User-Agent"}]}
149         },
150         // The headers were invalid, so they should not be modified.
151         // TODO(robwu): Test whether an error is logged to the console.
152         { label: "onSendHeaders",
153           event: "onSendHeaders",
154           details: {
155             url: getURLHttpSimpleLoad(),
156             requestHeadersValid: true
157           }
158         },
159         { label: "onHeadersReceived",
160           event: "onHeadersReceived",
161           details: {
162             url: getURLHttpSimpleLoad(),
163             statusLine: "HTTP/1.1 200 OK",
164             statusCode: 200,
165           }
166         },
167         { label: "onResponseStarted",
168           event: "onResponseStarted",
169           details: {
170             url: getURLHttpSimpleLoad(),
171             fromCache: false,
172             statusCode: 200,
173             ip: "127.0.0.1",
174             statusLine: "HTTP/1.1 200 OK",
175           }
176         },
177         { label: "onCompleted",
178           event: "onCompleted",
179           details: {
180             url: getURLHttpSimpleLoad(),
181             fromCache: false,
182             statusCode: 200,
183             ip: "127.0.0.1",
184             statusLine: "HTTP/1.1 200 OK",
185           }
186         },
187       ],
188       [  // event order
189         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
190          "onHeadersReceived", "onResponseStarted", "onCompleted"]
191       ],
192       {urls: ["<all_urls>"]},  // filter
193       ["blocking", "requestHeaders"]);
194     navigateAndWait(getURLHttpSimpleLoad());
195   },
197   // Navigates to a page and provides invalid header information. The request
198   // should continue as if the headers were not changed.
199   function simpleLoadIgnoreOnBeforeSendHeadersInvalidResponse() {
200     // Exception handling seems to break this test, so disable it.
201     // See http://crbug.com/370897. TODO(robwu): Fix me.
202     chrome.test.setExceptionHandler(function(){});
203     expect(
204       [  // events
205         { label: "onBeforeRequest",
206           event: "onBeforeRequest",
207           details: {
208             method: "GET",
209             type: "main_frame",
210             url: getURLHttpSimpleLoad(),
211             frameUrl: getURLHttpSimpleLoad()
212           },
213         },
214         { label: "onBeforeSendHeaders",
215           event: "onBeforeSendHeaders",
216           details: {
217             url: getURLHttpSimpleLoad(),
218             requestHeadersValid: true
219           },
220           retval: {foo: "bar"}
221         },
222         // TODO(robwu): Test whether an error is logged to the console.
223         { label: "onSendHeaders",
224           event: "onSendHeaders",
225           details: {
226             url: getURLHttpSimpleLoad(),
227             requestHeadersValid: true
228           }
229         },
230         { label: "onHeadersReceived",
231           event: "onHeadersReceived",
232           details: {
233             url: getURLHttpSimpleLoad(),
234             statusLine: "HTTP/1.1 200 OK",
235             statusCode: 200,
236           }
237         },
238         { label: "onResponseStarted",
239           event: "onResponseStarted",
240           details: {
241             url: getURLHttpSimpleLoad(),
242             fromCache: false,
243             statusCode: 200,
244             ip: "127.0.0.1",
245             statusLine: "HTTP/1.1 200 OK",
246           }
247         },
248         { label: "onCompleted",
249           event: "onCompleted",
250           details: {
251             url: getURLHttpSimpleLoad(),
252             fromCache: false,
253             statusCode: 200,
254             ip: "127.0.0.1",
255             statusLine: "HTTP/1.1 200 OK",
256           }
257         },
258       ],
259       [  // event order
260         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
261          "onHeadersReceived", "onResponseStarted", "onCompleted"]
262       ],
263       {urls: ["<all_urls>"]},  // filter
264       ["blocking", "requestHeaders"]);
265     navigateAndWait(getURLHttpSimpleLoad());
266   },
268   // Navigates to a page with a blocking handler that redirects to a different
269   // page.
270   function complexLoadRedirected() {
271     expect(
272       [  // events
273         { label: "onBeforeRequest-1",
274           event: "onBeforeRequest",
275           details: {
276             url: getURL("complexLoad/a.html"),
277             frameUrl: getURL("complexLoad/a.html")
278           },
279           retval: {redirectUrl: getURL("simpleLoad/a.html")}
280         },
281         { label: "onBeforeRedirect",
282           event: "onBeforeRedirect",
283           details: {
284             url: getURL("complexLoad/a.html"),
285             redirectUrl: getURL("simpleLoad/a.html"),
286             fromCache: false,
287             statusLine: "HTTP/1.1 307 Internal Redirect",
288             statusCode: 307,
289           }
290         },
291         { label: "onBeforeRequest-2",
292           event: "onBeforeRequest",
293           details: {
294             url: getURL("simpleLoad/a.html"),
295             frameUrl: getURL("simpleLoad/a.html"),
296           },
297         },
298         { label: "onResponseStarted",
299           event: "onResponseStarted",
300           details: {
301             url: getURL("simpleLoad/a.html"),
302             fromCache: false,
303             statusCode: 200,
304             statusLine: "HTTP/1.1 200 OK",
305             // Request to chrome-extension:// url has no IP.
306           }
307         },
308         { label: "onCompleted",
309           event: "onCompleted",
310           details: {
311             url: getURL("simpleLoad/a.html"),
312             fromCache: false,
313             statusCode: 200,
314             statusLine: "HTTP/1.1 200 OK",
315             // Request to chrome-extension:// url has no IP.
316           }
317         },
318       ],
319       [  // event order
320         ["onBeforeRequest-1", "onBeforeRedirect", "onBeforeRequest-2",
321          "onResponseStarted", "onCompleted"],
322       ],
323       {urls: ["<all_urls>"]}, // filter
324       ["blocking"]);
325     navigateAndWait(getURL("complexLoad/a.html"));
326   },
328   // Tests redirect of <img crossorigin="anonymous" src="...">
329   function crossOriginAnonymousRedirect() {
330     testLoadCORSImage("anonymous");
331   },
333   // Tests redirect of <img crossorigin="use-credentials" src="...">
334   function crossOriginCredentialedRedirect() {
335     testLoadCORSImage("use-credentials");
336   },
338   // Loads a testserver page that echoes the User-Agent header that was
339   // sent to fetch it. We modify the outgoing User-Agent in
340   // onBeforeSendHeaders, so we should see that modified version.
341   function modifyRequestHeaders() {
342     expect(
343       [  // events
344         { label: "onBeforeRequest",
345           event: "onBeforeRequest",
346           details: {
347             url: getURLEchoUserAgent(),
348             frameUrl: getURLEchoUserAgent()
349           }
350         },
351         { label: "onBeforeSendHeaders",
352           event: "onBeforeSendHeaders",
353           details: {
354             url: getURLEchoUserAgent(),
355             // Note: no requestHeaders because we don't ask for them.
356           },
357           retval: {requestHeaders: [{name: "User-Agent", value: "FoobarUA"}]}
358         },
359         { label: "onSendHeaders",
360           event: "onSendHeaders",
361           details: {
362             url: getURLEchoUserAgent()
363           }
364         },
365         { label: "onHeadersReceived",
366           event: "onHeadersReceived",
367           details: {
368             url: getURLEchoUserAgent(),
369             statusLine: "HTTP/1.1 200 OK",
370             statusCode: 200,
371           }
372         },
373         { label: "onResponseStarted",
374           event: "onResponseStarted",
375           details: {
376             url: getURLEchoUserAgent(),
377             fromCache: false,
378             statusCode: 200,
379             ip: "127.0.0.1",
380             statusLine: "HTTP/1.1 200 OK",
381           }
382         },
383         { label: "onCompleted",
384           event: "onCompleted",
385           details: {
386             url: getURLEchoUserAgent(),
387             fromCache: false,
388             statusCode: 200,
389             ip: "127.0.0.1",
390             statusLine: "HTTP/1.1 200 OK",
391           }
392         },
393       ],
394       [  // event order
395         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
396          "onHeadersReceived", "onResponseStarted", "onCompleted"]
397       ],
398       {urls: ["<all_urls>"]}, ["blocking"]);
399     // Check the page content for our modified User-Agent string.
400     navigateAndWait(getURLEchoUserAgent(), function() {
401       chrome.test.listenOnce(chrome.extension.onRequest, function(request) {
402         chrome.test.assertTrue(request.pass, "Request header was not set.");
403       });
404       chrome.tabs.executeScript(tabId,
405         {
406           code: "chrome.extension.sendRequest(" +
407               "{pass: document.body.innerText.indexOf('FoobarUA') >= 0});"
408         });
409     });
410   },
412   // Loads a testserver page that echoes the User-Agent header that was
413   // sent to fetch it. We modify the outgoing User-Agent in
414   // onBeforeSendHeaders, so we should see that modified version.
415   // In this version we check whether we can set binary header values.
416   function modifyBinaryRequestHeaders() {
417     expect(
418       [  // events
419         { label: "onBeforeRequest",
420           event: "onBeforeRequest",
421           details: {
422             url: getURLEchoUserAgent(),
423             frameUrl: getURLEchoUserAgent()
424           }
425         },
426         { label: "onBeforeSendHeaders",
427           event: "onBeforeSendHeaders",
428           details: {
429             url: getURLEchoUserAgent(),
430             // Note: no requestHeaders because we don't ask for them.
431           },
432           retval: {requestHeaders: [{name: "User-Agent",
433                                      binaryValue: toCharCodes("FoobarUA")}]}
434         },
435         { label: "onSendHeaders",
436           event: "onSendHeaders",
437           details: {
438             url: getURLEchoUserAgent()
439           }
440         },
441         { label: "onHeadersReceived",
442           event: "onHeadersReceived",
443           details: {
444             url: getURLEchoUserAgent(),
445             statusLine: "HTTP/1.1 200 OK",
446             statusCode: 200,
447           }
448         },
449         { label: "onResponseStarted",
450           event: "onResponseStarted",
451           details: {
452             url: getURLEchoUserAgent(),
453             fromCache: false,
454             statusCode: 200,
455             ip: "127.0.0.1",
456             statusLine: "HTTP/1.1 200 OK",
457           }
458         },
459         { label: "onCompleted",
460           event: "onCompleted",
461           details: {
462             url: getURLEchoUserAgent(),
463             fromCache: false,
464             statusCode: 200,
465             ip: "127.0.0.1",
466             statusLine: "HTTP/1.1 200 OK",
467           }
468         },
469       ],
470       [  // event order
471         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
472          "onHeadersReceived", "onResponseStarted", "onCompleted"]
473       ],
474       {urls: ["<all_urls>"]}, ["blocking"]);
475     // Check the page content for our modified User-Agent string.
476     navigateAndWait(getURLEchoUserAgent(), function() {
477       chrome.test.listenOnce(chrome.extension.onRequest, function(request) {
478         chrome.test.assertTrue(request.pass, "Request header was not set.");
479       });
480       chrome.tabs.executeScript(tabId,
481         {
482           code: "chrome.extension.sendRequest(" +
483               "{pass: document.body.innerText.indexOf('FoobarUA') >= 0});"
484         });
485     });
486   },
488   // Loads a testserver page that sets a cookie "Foo=Bar" but removes
489   // the cookies from the response headers so that they are not set.
490   function modifyResponseHeaders() {
491     expect(
492       [  // events
493         { label: "onBeforeRequest",
494           event: "onBeforeRequest",
495           details: {
496             method: "GET",
497             type: "main_frame",
498             url: getURLSetCookie(),
499             frameUrl: getURLSetCookie()
500           }
501         },
502         { label: "onBeforeSendHeaders",
503           event: "onBeforeSendHeaders",
504           details: {
505             url: getURLSetCookie(),
506             // Note: no requestHeaders because we don't ask for them.
507           },
508         },
509         { label: "onSendHeaders",
510           event: "onSendHeaders",
511           details: {
512             url: getURLSetCookie(),
513           }
514         },
515         { label: "onHeadersReceived",
516           event: "onHeadersReceived",
517           details: {
518             url: getURLSetCookie(),
519             statusLine: "HTTP/1.1 200 OK",
520             statusCode: 200,
521             responseHeadersExist: true,
522           },
523           retval_function: function(name, details) {
524             responseHeaders = details.responseHeaders;
525             var found = false;
526             for (var i = 0; i < responseHeaders.length; ++i) {
527               if (responseHeaders[i].name === "Set-Cookie" &&
528                   responseHeaders[i].value.indexOf("Foo") != -1) {
529                 found = true;
530                 responseHeaders.splice(i);
531                 break;
532               }
533             }
534             chrome.test.assertTrue(found);
535             return {responseHeaders: responseHeaders};
536           }
537         },
538         { label: "onResponseStarted",
539           event: "onResponseStarted",
540           details: {
541             url: getURLSetCookie(),
542             fromCache: false,
543             statusCode: 200,
544             statusLine: "HTTP/1.1 200 OK",
545             ip: "127.0.0.1",
546             responseHeadersExist: true,
547           }
548         },
549         { label: "onCompleted",
550           event: "onCompleted",
551           details: {
552             url: getURLSetCookie(),
553             fromCache: false,
554             statusCode: 200,
555             statusLine: "HTTP/1.1 200 OK",
556             ip: "127.0.0.1",
557             responseHeadersExist: true,
558           }
559         },
560       ],
561       [  // event order
562         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
563          "onHeadersReceived", "onResponseStarted", "onCompleted"]
564       ],
565       {urls: ["<all_urls>"]}, ["blocking", "responseHeaders"]);
566     // Check that the cookie was really removed.
567     navigateAndWait(getURLSetCookie(), function() {
568       chrome.test.listenOnce(chrome.extension.onRequest, function(request) {
569         chrome.test.assertTrue(request.pass, "Cookie was not removed.");
570       });
571       chrome.tabs.executeScript(tabId,
572       { code: "chrome.extension.sendRequest(" +
573             "{pass: document.cookie.indexOf('Foo') == -1});"
574         });
575     });
576   },
578   // Loads a testserver page that sets a cookie "Foo=U+FDD1" which is not a
579   // valid UTF-8 code point. Therefore, it cannot be passed to JavaScript
580   // as a normal string.
581   function handleNonUTF8InModifyResponseHeaders() {
582     expect(
583       [  // events
584         { label: "onBeforeRequest",
585           event: "onBeforeRequest",
586           details: {
587             method: "GET",
588             type: "main_frame",
589             url: getURLNonUTF8SetCookie(),
590             frameUrl: getURLNonUTF8SetCookie()
591           }
592         },
593         { label: "onBeforeSendHeaders",
594           event: "onBeforeSendHeaders",
595           details: {
596             url: getURLNonUTF8SetCookie(),
597             // Note: no requestHeaders because we don't ask for them.
598           },
599         },
600         { label: "onSendHeaders",
601           event: "onSendHeaders",
602           details: {
603             url: getURLNonUTF8SetCookie(),
604           }
605         },
606         { label: "onHeadersReceived",
607           event: "onHeadersReceived",
608           details: {
609             url: getURLNonUTF8SetCookie(),
610             statusLine: "HTTP/1.1 200 OK",
611             statusCode: 200,
612             responseHeadersExist: true,
613           },
614           retval_function: function(name, details) {
615             responseHeaders = details.responseHeaders;
616             var found = false;
617             var expectedValue = [
618               "F".charCodeAt(0),
619               "o".charCodeAt(0),
620               "o".charCodeAt(0),
621               0x3D, 0xFE, 0xD1
622               ];
624             for (var i = 0; i < responseHeaders.length; ++i) {
625               if (responseHeaders[i].name === "Set-Cookie" &&
626                   deepEq(responseHeaders[i].binaryValue, expectedValue)) {
627                 found = true;
628                 responseHeaders.splice(i);
629                 break;
630               }
631             }
632             chrome.test.assertTrue(found);
633             return {responseHeaders: responseHeaders};
634           }
635         },
636         { label: "onResponseStarted",
637           event: "onResponseStarted",
638           details: {
639             url: getURLNonUTF8SetCookie(),
640             fromCache: false,
641             statusCode: 200,
642             statusLine: "HTTP/1.1 200 OK",
643             ip: "127.0.0.1",
644             responseHeadersExist: true,
645           }
646         },
647         { label: "onCompleted",
648           event: "onCompleted",
649           details: {
650             url: getURLNonUTF8SetCookie(),
651             fromCache: false,
652             statusCode: 200,
653             statusLine: "HTTP/1.1 200 OK",
654             ip: "127.0.0.1",
655             responseHeadersExist: true,
656           }
657         },
658       ],
659       [  // event order
660         ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
661          "onHeadersReceived", "onResponseStarted", "onCompleted"]
662       ],
663       {urls: ["<all_urls>"]}, ["blocking", "responseHeaders"]);
664     // Check that the cookie was really removed.
665     navigateAndWait(getURLNonUTF8SetCookie(), function() {
666       chrome.test.listenOnce(chrome.extension.onRequest, function(request) {
667         chrome.test.assertTrue(request.pass, "Cookie was not removed.");
668       });
669       chrome.tabs.executeScript(tabId,
670       { code: "chrome.extension.sendRequest(" +
671             "{pass: document.cookie.indexOf('Foo') == -1});"
672         });
673     });
674   },
676   // Navigates to a page with a blocking handler that redirects to a different
677   // non-http page during onHeadersReceived. The requested page should not be
678   // loaded, and the redirect should succeed.
679   function simpleLoadRedirectOnReceiveHeaders() {
680     expect(
681       [  // events
682         { label: "onBeforeRequest-1",
683           event: "onBeforeRequest",
684           details: {
685             method: "GET",
686             type: "main_frame",
687             url: getURLHttpSimpleLoad(),
688             frameUrl: getURLHttpSimpleLoad()
689           },
690         },
691         { label: "onBeforeSendHeaders",
692           event: "onBeforeSendHeaders",
693           details: {
694             url: getURLHttpSimpleLoad(),
695             // Note: no requestHeaders because we don't ask for them.
696           },
697         },
698         { label: "onSendHeaders",
699           event: "onSendHeaders",
700           details: {
701             url: getURLHttpSimpleLoad()
702           }
703         },
704         { label: "onHeadersReceived",
705           event: "onHeadersReceived",
706           details: {
707             url: getURLHttpSimpleLoad(),
708             statusLine: "HTTP/1.1 200 OK",
709             statusCode: 200,
710           },
711           retval: {redirectUrl: getURL("simpleLoad/a.html")}
712         },
713         { label: "onBeforeRedirect",
714           event: "onBeforeRedirect",
715           details: {
716             url: getURLHttpSimpleLoad(),
717             redirectUrl: getURL("simpleLoad/a.html"),
718             statusLine: "HTTP/1.1 302 Found",
719             statusCode: 302,
720             fromCache: false,
721             ip: "127.0.0.1",
722           }
723         },
724         { label: "onBeforeRequest-2",
725           event: "onBeforeRequest",
726           details: {
727             url: getURL("simpleLoad/a.html"),
728             frameUrl: getURL("simpleLoad/a.html"),
729           },
730         },
731         { label: "onResponseStarted",
732           event: "onResponseStarted",
733           details: {
734             url: getURL("simpleLoad/a.html"),
735             fromCache: false,
736             statusCode: 200,
737             statusLine: "HTTP/1.1 200 OK",
738             // Request to chrome-extension:// url has no IP.
739           }
740         },
741         { label: "onCompleted",
742           event: "onCompleted",
743           details: {
744             url: getURL("simpleLoad/a.html"),
745             fromCache: false,
746             statusCode: 200,
747             statusLine: "HTTP/1.1 200 OK",
748             // Request to chrome-extension:// url has no IP.
749           }
750         },
751       ],
752       [  // event order
753         ["onBeforeRequest-1", "onBeforeSendHeaders", "onSendHeaders",
754          "onHeadersReceived", "onBeforeRedirect", "onBeforeRequest-2",
755          "onResponseStarted", "onCompleted"]
756       ],
757       {urls: ["<all_urls>"]},  // filter
758       ["blocking"]);
759     navigateAndWait(getURLHttpSimpleLoad());
760   },
762   // Checks that synchronous XHR requests from ourself are invisible to blocking
763   // handlers.
764   function syncXhrsFromOurselfAreInvisible() {
765     expect(
766       [  // events
767         { label: "a-onBeforeRequest",
768           event: "onBeforeRequest",
769           details: {
770             url: getURL("simpleLoad/a.html"),
771             frameUrl: getURL("simpleLoad/a.html")
772           }
773         },
774         { label: "a-onResponseStarted",
775           event: "onResponseStarted",
776           details: {
777             url: getURL("simpleLoad/a.html"),
778             statusCode: 200,
779             fromCache: false,
780             statusLine: "HTTP/1.1 200 OK",
781             // Request to chrome-extension:// url has no IP.
782           }
783         },
784         { label: "a-onCompleted",
785           event: "onCompleted",
786           details: {
787             url: getURL("simpleLoad/a.html"),
788             statusCode: 200,
789             fromCache: false,
790             statusLine: "HTTP/1.1 200 OK",
791             // Request to chrome-extension:// url has no IP.
792           }
793         },
794         // We do not see onBeforeRequest for the XHR request here because it is
795         // handled by a blocking handler.
796         { label: "x-onSendHeaders",
797           event: "onSendHeaders",
798           details: {
799             url: getURLHttpXHRData(),
800             tabId: 1,
801             type: "xmlhttprequest",
802           }
803         },
804         { label: "x-onResponseStarted",
805           event: "onResponseStarted",
806           details: {
807             url: getURLHttpXHRData(),
808             statusCode: 200,
809             fromCache: false,
810             statusLine: "HTTP/1.1 200 OK",
811             tabId: 1,
812             type: "xmlhttprequest",
813             ip: "127.0.0.1",
814             // Request to chrome-extension:// url has no IP.
815           }
816         },
817         { label: "x-onCompleted",
818           event: "onCompleted",
819           details: {
820             url: getURLHttpXHRData(),
821             statusCode: 200,
822             fromCache: false,
823             statusLine: "HTTP/1.1 200 OK",
824             tabId: 1,
825             type: "xmlhttprequest",
826             ip: "127.0.0.1",
827             // Request to chrome-extension:// url has no IP.
828           }
829         },
830         { label: "b-onBeforeRequest",
831           event: "onBeforeRequest",
832           details: {
833             url: getURL("complexLoad/b.jpg"),
834             frameUrl: getURL("complexLoad/b.jpg")
835           }
836         },
837         { label: "b-onResponseStarted",
838           event: "onResponseStarted",
839           details: {
840             url: getURL("complexLoad/b.jpg"),
841             statusCode: 200,
842             fromCache: false,
843             statusLine: "HTTP/1.1 200 OK",
844             // Request to chrome-extension:// url has no IP.
845           }
846         },
847         { label: "b-onCompleted",
848           event: "onCompleted",
849           details: {
850             url: getURL("complexLoad/b.jpg"),
851             statusCode: 200,
852             fromCache: false,
853             statusLine: "HTTP/1.1 200 OK",
854             // Request to chrome-extension:// url has no IP.
855           }
856         },
857       ],
858       [  // event order
859         ["a-onBeforeRequest", "a-onResponseStarted", "a-onCompleted",
860          "x-onSendHeaders", "x-onResponseStarted", "x-onCompleted",
861          "b-onBeforeRequest", "b-onResponseStarted", "b-onCompleted"]
862       ],
863       {urls: ["<all_urls>"]}, ["blocking"]);
864     // Check the page content for our modified User-Agent string.
865     navigateAndWait(getURL("simpleLoad/a.html"), function() {
866         var req = new XMLHttpRequest();
867         var asynchronous = false;
868         req.open("GET", getURLHttpXHRData(), asynchronous);
869         req.send(null);
870         navigateAndWait(getURL("complexLoad/b.jpg"));
871     });
872   },
874   // Checks that asynchronous XHR requests from ourself are visible to blocking
875   // handlers.
876   function asyncXhrsFromOurselfAreVisible() {
877     expect(
878       [  // events
879         { label: "a-onBeforeRequest",
880           event: "onBeforeRequest",
881           details: {
882             url: getURL("simpleLoad/a.html"),
883             frameUrl: getURL("simpleLoad/a.html")
884           }
885         },
886         { label: "a-onResponseStarted",
887           event: "onResponseStarted",
888           details: {
889             url: getURL("simpleLoad/a.html"),
890             statusCode: 200,
891             fromCache: false,
892             statusLine: "HTTP/1.1 200 OK",
893             // Request to chrome-extension:// url has no IP.
894           }
895         },
896         { label: "a-onCompleted",
897           event: "onCompleted",
898           details: {
899             url: getURL("simpleLoad/a.html"),
900             statusCode: 200,
901             fromCache: false,
902             statusLine: "HTTP/1.1 200 OK",
903             // Request to chrome-extension:// url has no IP.
904           }
905         },
906         {
907           label: "x-onBeforeRequest",
908           event: "onBeforeRequest",
909           details: {
910             url: getURLHttpXHRData(),
911             tabId: 1,
912             type: "xmlhttprequest",
913             frameUrl: "unknown frame URL",
914           }
915         },
916         {
917           label: "x-onBeforeSendHeaders",
918           event: "onBeforeSendHeaders",
919           details: {
920             url: getURLHttpXHRData(),
921             tabId: 1,
922             type: "xmlhttprequest",
923           }
924         },
925         { label: "x-onSendHeaders",
926           event: "onSendHeaders",
927           details: {
928             url: getURLHttpXHRData(),
929             tabId: 1,
930             type: "xmlhttprequest",
931           }
932         },
933         { label: "x-onResponseStarted",
934           event: "onResponseStarted",
935           details: {
936             url: getURLHttpXHRData(),
937             statusCode: 200,
938             fromCache: false,
939             statusLine: "HTTP/1.1 200 OK",
940             tabId: 1,
941             type: "xmlhttprequest",
942             ip: "127.0.0.1",
943             // Request to chrome-extension:// url has no IP.
944           }
945         },
946         {
947           label: "x-onHeadersReceived",
948           event: "onHeadersReceived",
949           details: {
950             url: getURLHttpXHRData(),
951             tabId: 1,
952             type: "xmlhttprequest",
953             statusLine: "HTTP/1.1 200 OK",
954             statusCode: 200,
955           }
956         },
957         { label: "x-onCompleted",
958           event: "onCompleted",
959           details: {
960             url: getURLHttpXHRData(),
961             statusCode: 200,
962             fromCache: false,
963             statusLine: "HTTP/1.1 200 OK",
964             tabId: 1,
965             type: "xmlhttprequest",
966             ip: "127.0.0.1",
967             // Request to chrome-extension:// url has no IP.
968           }
969         },
970         { label: "b-onBeforeRequest",
971           event: "onBeforeRequest",
972           details: {
973             url: getURL("complexLoad/b.jpg"),
974             frameUrl: getURL("complexLoad/b.jpg")
975           }
976         },
977         { label: "b-onResponseStarted",
978           event: "onResponseStarted",
979           details: {
980             url: getURL("complexLoad/b.jpg"),
981             statusCode: 200,
982             fromCache: false,
983             statusLine: "HTTP/1.1 200 OK",
984             // Request to chrome-extension:// url has no IP.
985           }
986         },
987         { label: "b-onCompleted",
988           event: "onCompleted",
989           details: {
990             url: getURL("complexLoad/b.jpg"),
991             statusCode: 200,
992             fromCache: false,
993             statusLine: "HTTP/1.1 200 OK",
994             // Request to chrome-extension:// url has no IP.
995           }
996         },
997       ],
998       [  // event order
999         ["a-onBeforeRequest", "a-onResponseStarted", "a-onCompleted",
1000          "x-onBeforeRequest", "x-onBeforeSendHeaders", "x-onSendHeaders",
1001          "x-onHeadersReceived", "x-onResponseStarted", "x-onCompleted"],
1002         ["a-onCompleted", "x-onBeforeRequest",
1003          "b-onBeforeRequest", "b-onResponseStarted", "b-onCompleted"]
1004       ],
1005       {urls: ["<all_urls>"]}, ["blocking"]);
1006     // Check the page content for our modified User-Agent string.
1007     navigateAndWait(getURL("simpleLoad/a.html"), function() {
1008         var req = new XMLHttpRequest();
1009         var asynchronous = true;
1010         req.open("GET", getURLHttpXHRData(), asynchronous);
1011         req.send(null);
1012         navigateAndWait(getURL("complexLoad/b.jpg"));
1013     });
1014   },
1018 // This helper verifies that extensions can successfully redirect resources even
1019 // if cross-origin access control is in effect via the crossorigin attribute.
1020 // Used by crossOriginAnonymousRedirect and crossOriginCredentialedRedirect.
1021 function testLoadCORSImage(crossOriginAttributeValue) {
1022   // (Non-existent) image URL, with random query string to bust the cache.
1023   var requestedUrl = getServerURL("cors/intercepted_by_extension.gif?" +
1024                                   Math.random(), "original.tld");
1025   var frameUrl = getServerURL(
1026       "extensions/api_test/webrequest/cors/load_image.html?" +
1027       "crossOrigin=" + crossOriginAttributeValue +
1028       "&src=" + encodeURIComponent(requestedUrl));
1029   var redirectTarget = getServerURL(
1030       "extensions/api_test/webrequest/cors/redirect_target.gif", "domain.tld");
1031   expect(
1032     [  // events
1033       { label: "onBeforeRequest-1",
1034         event: "onBeforeRequest",
1035         details: {
1036           type: "image",
1037           url: requestedUrl,
1038           // Frame URL unavailable because requests are filtered by type=image.
1039           frameUrl: "unknown frame URL",
1040         },
1041         retval: {redirectUrl: redirectTarget}
1042       },
1043       { label: "onBeforeRedirect",
1044         event: "onBeforeRedirect",
1045         details: {
1046           type: "image",
1047           url: requestedUrl,
1048           redirectUrl: redirectTarget,
1049           statusLine: "HTTP/1.1 307 Internal Redirect",
1050           statusCode: 307,
1051           fromCache: false,
1052         }
1053       },
1054       { label: "onBeforeRequest-2",
1055         event: "onBeforeRequest",
1056         details: {
1057           type: "image",
1058           url: redirectTarget,
1059           // Frame URL unavailable because requests are filtered by type=image.
1060           frameUrl: "unknown frame URL",
1061         },
1062       },
1063       {
1064         label: "onBeforeSendHeaders",
1065         event: "onBeforeSendHeaders",
1066         details: {
1067           type: "image",
1068           url: redirectTarget,
1069         }
1070       },
1071       {
1072         label: "onSendHeaders",
1073         event: "onSendHeaders",
1074         details: {
1075           type: "image",
1076           url: redirectTarget,
1077         }
1078       },
1079       {
1080         label: "onHeadersReceived",
1081         event: "onHeadersReceived",
1082         details: {
1083           type: "image",
1084           url: redirectTarget,
1085           statusLine: "HTTP/1.1 200 OK",
1086           statusCode: 200,
1087         }
1088       },
1089       { label: "onResponseStarted",
1090         event: "onResponseStarted",
1091         details: {
1092           type: "image",
1093           url: redirectTarget,
1094           fromCache: false,
1095           statusCode: 200,
1096           ip: "127.0.0.1",
1097           statusLine: "HTTP/1.1 200 OK",
1098         }
1099       },
1100       { label: "onCompleted",
1101         event: "onCompleted",
1102         details: {
1103           type: "image",
1104           url: redirectTarget,
1105           fromCache: false,
1106           statusCode: 200,
1107           ip: "127.0.0.1",
1108           statusLine: "HTTP/1.1 200 OK",
1109         }
1110       },
1111       // After the image loads, the test will load the following URL
1112       // to signal that the test succeeded.
1113       {
1114         label: "onBeforeRequest-3",
1115         event: "onBeforeRequest",
1116         details: {
1117           type: "image",
1118           url: getServerURL("signal_that_image_loaded_successfully"),
1119           // Frame URL unavailable because requests are filtered by type=image.
1120           frameUrl: "unknown frame URL",
1121         },
1122         retval: {cancel: true}
1123       },
1124       { label: "onErrorOccurred",
1125         event: "onErrorOccurred",
1126         details: {
1127           type: "image",
1128           url: getServerURL("signal_that_image_loaded_successfully"),
1129           fromCache: false,
1130           error: "net::ERR_BLOCKED_BY_CLIENT",
1131         }
1132       },
1133     ],
1134     [  // event order
1135       ["onBeforeRequest-1", "onBeforeRedirect", "onBeforeRequest-2",
1136        "onBeforeSendHeaders", "onSendHeaders", "onHeadersReceived",
1137        "onResponseStarted", "onCompleted",
1138        "onBeforeRequest-3", "onErrorOccurred"],
1139     ],
1140     {urls: ["<all_urls>"], types: ['image']}, // filter
1141     ["blocking"]);
1142   navigateAndWait(frameUrl);