| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| var callbackPass = chrome.test.callbackPass; |
| |
| chrome.tabs.getCurrent(function(tab) { |
| runTestsForTab([ |
| // Opens a WebSocket connection, writes a message to it, and closes the |
| // connection. WebRequest API should observe the entire handshake. |
| function handshakeSucceeds() { |
| var url = getWSTestURL(testWebSocketPort); |
| expect( |
| [ //events |
| { label: 'onBeforeRequest', |
| event: 'onBeforeRequest', |
| details: { |
| url: url, |
| type: 'websocket', |
| // TODO(pkalinnikov): Figure out why the frame URL is unknown. |
| frameUrl: 'unknown frame URL', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onBeforeSendHeaders', |
| event: 'onBeforeSendHeaders', |
| details: { |
| url: url, |
| type: 'websocket', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onSendHeaders', |
| event: 'onSendHeaders', |
| details: { |
| url: url, |
| type: 'websocket', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onHeadersReceived', |
| event: 'onHeadersReceived', |
| details: { |
| url: url, |
| type: 'websocket', |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onResponseStarted', |
| event: 'onResponseStarted', |
| details: { |
| url: url, |
| type: 'websocket', |
| ip: '127.0.0.1', |
| fromCache: false, |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onCompleted', |
| event: 'onCompleted', |
| details: { |
| url: url, |
| type: 'websocket', |
| ip: '127.0.0.1', |
| fromCache: false, |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| } |
| }, |
| ], |
| [ // event order |
| ['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders', |
| 'onHeadersReceived', 'onResponseStarted', 'onCompleted'] |
| ], |
| {urls: ['ws://*/*']}, // filter |
| ['blocking'] // extraInfoSpec |
| ); |
| testWebSocketConnection(url, true /* expectedToConnect */); |
| }, |
| |
| // Tries to open a WebSocket connection, with a blocking handler that |
| // cancels the request. The connection will not be established. |
| function handshakeRequestCancelled() { |
| var url = getWSTestURL(testWebSocketPort); |
| expect( |
| [ // events |
| { label: 'onBeforeRequest', |
| event: 'onBeforeRequest', |
| details: { |
| url: url, |
| type: 'websocket', |
| frameUrl: 'unknown frame URL', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| retval: {cancel: true} |
| }, |
| // Cancelling is considered an error. |
| { label: 'onErrorOccurred', |
| event: 'onErrorOccurred', |
| details: { |
| url: url, |
| type: 'websocket', |
| fromCache: false, |
| initiator: getDomain(initiators.WEB_INITIATED), |
| error: 'net::ERR_BLOCKED_BY_CLIENT' |
| } |
| }, |
| ], |
| [ // event order |
| ['onBeforeRequest', 'onErrorOccurred'] |
| ], |
| {urls: ['ws://*/*']}, // filter |
| ['blocking'] // extraInfoSpec |
| ); |
| testWebSocketConnection(url, false /* expectedToConnect */); |
| }, |
| |
| // Opens a WebSocket connection, with a blocking handler that tries to |
| // redirect the request. The redirect will be ignored. |
| function redirectIsIgnoredAndHandshakeSucceeds() { |
| var url = getWSTestURL(testWebSocketPort); |
| var redirectedUrl1 = getWSTestURL(testWebSocketPort) + '?redirected1'; |
| var redirectedUrl2 = getWSTestURL(testWebSocketPort) + '?redirected2'; |
| expect( |
| [ // events |
| { label: 'onBeforeRequest', |
| event: 'onBeforeRequest', |
| details: { |
| url: url, |
| type: 'websocket', |
| frameUrl: 'unknown frame URL', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| retval: {redirectUrl: redirectedUrl1} |
| }, |
| { label: 'onBeforeSendHeaders', |
| event: 'onBeforeSendHeaders', |
| details: { |
| url: url, |
| type: 'websocket', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onSendHeaders', |
| event: 'onSendHeaders', |
| details: { |
| url: url, |
| type: 'websocket', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| }, |
| { label: 'onHeadersReceived', |
| event: 'onHeadersReceived', |
| details: { |
| url: url, |
| type: 'websocket', |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| initiator: getDomain(initiators.WEB_INITIATED) |
| }, |
| retval: {redirectUrl: redirectedUrl2} |
| }, |
| { label: 'onResponseStarted', |
| event: 'onResponseStarted', |
| details: { |
| url: url, |
| type: 'websocket', |
| ip: '127.0.0.1', |
| fromCache: false, |
| initiator: getDomain(initiators.WEB_INITIATED), |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| }, |
| }, |
| { label: 'onCompleted', |
| event: 'onCompleted', |
| details: { |
| url: url, |
| type: 'websocket', |
| ip: '127.0.0.1', |
| fromCache: false, |
| initiator: getDomain(initiators.WEB_INITIATED), |
| statusCode: 101, |
| statusLine: 'HTTP/1.1 101 Switching Protocols', |
| } |
| }, |
| ], |
| [ // event order |
| ['onBeforeRequest', 'onBeforeSendHeaders', 'onHeadersReceived', |
| 'onResponseStarted', 'onCompleted'] |
| ], |
| {urls: ['ws://*/*']}, // filter |
| ['blocking'] // extraInfoSpec |
| ); |
| testWebSocketConnection(url, true /* expectedToConnect */); |
| }, |
| |
| // Tests that all the requests headers that are added by net/ are visible |
| // if extraHeaders is specified. |
| function testExtraRequestHeadersVisible() { |
| var url = getWSTestURL(testWebSocketPort); |
| |
| var extraHeadersListener = callbackPass(function(details) { |
| checkHeaders(details.requestHeaders, |
| ['user-agent', 'accept-language'], []); |
| chrome.webRequest.onBeforeSendHeaders.removeListener( |
| extraHeadersListener); |
| }); |
| chrome.webRequest.onBeforeSendHeaders.addListener(extraHeadersListener, |
| {urls: [url]}, ['requestHeaders', 'extraHeaders']); |
| |
| var standardListener = callbackPass(function(details) { |
| checkHeaders(details.requestHeaders, |
| ['user-agent'], ['accept-language']); |
| chrome.webRequest.onBeforeSendHeaders.removeListener(standardListener); |
| }); |
| chrome.webRequest.onBeforeSendHeaders.addListener(standardListener, |
| {urls: [url]}, ['requestHeaders']); |
| |
| testWebSocketConnection(url, true /* expectedToConnect */); |
| }, |
| |
| // Ensure that request headers which are added by net/ could be modified if |
| // the listener uses extraHeaders. |
| function testModifyRequestHeaders() { |
| var url = getWSTestURL(testWebSocketPort); |
| |
| var beforeSendHeadersListener = callbackPass(function(details) { |
| // Test removal. |
| removeHeader(details.requestHeaders, 'accept-language'); |
| |
| // Test modification. |
| for (var i = 0; i < details.requestHeaders.length; i++) { |
| if (details.requestHeaders[i].name == 'User-Agent') |
| details.requestHeaders[i].value = 'Foo'; |
| } |
| |
| // Test addition. |
| details.requestHeaders.push({name: 'X-New-Header', |
| value: 'Bar'}); |
| |
| return {requestHeaders: details.requestHeaders}; |
| }); |
| chrome.webRequest.onBeforeSendHeaders.addListener( |
| beforeSendHeadersListener, |
| {urls: [url]}, ['requestHeaders', 'blocking', 'extraHeaders']); |
| |
| var sendHeadersListener = callbackPass(function(details) { |
| checkHeaders(details.requestHeaders, ['x-new-header'], |
| ['accept-language']); |
| |
| var seen = false; |
| for (var i = 0; i < details.requestHeaders.length; i++) { |
| if (details.requestHeaders[i].name == 'User-Agent') { |
| chrome.test.assertEq(details.requestHeaders[i].value, 'Foo'); |
| seen = true; |
| } |
| } |
| chrome.test.assertTrue(seen); |
| |
| chrome.webRequest.onBeforeSendHeaders.removeListener( |
| beforeSendHeadersListener); |
| chrome.webRequest.onSendHeaders.removeListener(sendHeadersListener); |
| }); |
| chrome.webRequest.onSendHeaders.addListener(sendHeadersListener, |
| {urls: [url]}, ['requestHeaders', 'extraHeaders']); |
| |
| testWebSocketConnection(url, true /* expectedToConnect */); |
| }, |
| |
| // Ensure that response headers can be modified when extraHeaders is used. |
| function testModifyResponseHeaders() { |
| var url = getWSTestURL(testWebSocketPort); |
| |
| var onHeadersReceivedHeadersListener = callbackPass(function(details) { |
| // Test addition. |
| details.responseHeaders.push({name: 'X-New-Header', |
| value: 'Bar'}); |
| |
| return {responseHeaders: details.responseHeaders}; |
| }); |
| chrome.webRequest.onHeadersReceived.addListener( |
| onHeadersReceivedHeadersListener, |
| {urls: [url]}, ['responseHeaders', 'blocking', 'extraHeaders']); |
| |
| var onResponseStartedListener = callbackPass(function(details) { |
| checkHeaders(details.responseHeaders, ['x-new-header'], []); |
| |
| chrome.webRequest.onHeadersReceived.removeListener( |
| onHeadersReceivedHeadersListener); |
| chrome.webRequest.onResponseStarted.removeListener( |
| onResponseStartedListener); |
| }); |
| chrome.webRequest.onResponseStarted.addListener(onResponseStartedListener, |
| {urls: [url]}, ['responseHeaders', 'extraHeaders']); |
| |
| testWebSocketConnection(url, true /* expectedToConnect */); |
| }, |
| ], tab); |
| }); |