Roll src/third_party/WebKit bf18a82:a9cee16 (svn 185297:185304)
[chromium-blink-merge.git] / chrome / browser / resources / cryptotoken / webrequestsender.js
blobd3fdf3d239a1b0e586ac3e167f625c0f2c02bf78
1 // Copyright 2014 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 /**
6 * @fileoverview Provides a representation of a web request sender, and
7 * utility functions for creating them.
8 */
9 'use strict';
11 /**
12 * @typedef {{
13 * origin: string,
14 * tlsChannelId: (string|undefined),
15 * tabId: (number|undefined)
16 * }}
18 var WebRequestSender;
20 /**
21 * Creates an object representing the sender's origin, and, if available,
22 * tab.
23 * @param {MessageSender} messageSender The message sender.
24 * @return {?WebRequestSender} The sender's origin and tab, or null if the
25 * sender is invalid.
27 function createSenderFromMessageSender(messageSender) {
28 var origin = getOriginFromUrl(/** @type {string} */ (messageSender.url));
29 if (!origin) {
30 return null;
32 var sender = {
33 origin: origin
35 if (messageSender.tlsChannelId) {
36 sender.tlsChannelId = messageSender.tlsChannelId;
38 if (messageSender.tab) {
39 sender.tabId = messageSender.tab.id;
41 return sender;
44 /**
45 * Checks whether the given tab could have sent a message from the given
46 * origin.
47 * @param {Tab} tab The tab to match
48 * @param {string} origin The origin to check.
49 * @return {Promise} A promise resolved with the tab id if it the tab could,
50 * have sent the request, and rejected if it can't.
52 function tabMatchesOrigin(tab, origin) {
53 return new Promise(function(resolve, reject) {
54 // If the tab's origin matches, trust that the request came from this tab.
55 if (getOriginFromUrl(tab.url) == origin) {
56 resolve(tab.id);
57 return;
59 // Look for an iframe in the current tab matching the origin.
60 chrome.tabs.executeScript(tab.id, { file: 'taborigincs.js' }, function() {
61 chrome.tabs.sendMessage(tab.id, { origin: origin },
62 function(response) {
63 if (response) {
64 resolve(tab.id);
65 } else {
66 reject(false);
68 });
69 });
70 });
73 /**
74 * Attempts to ensure that the tabId of the sender is set, using chrome.tabs
75 * when available.
76 * @param {WebRequestSender} sender The request sender.
77 * @return {Promise} A promise resolved once the tabId retrieval is done.
78 * The promise is rejected if the tabId is untrustworthy, e.g. if the
79 * user rapidly switched tabs.
81 function getTabIdWhenPossible(sender) {
82 if (sender.tabId) {
83 // Already got it? Done.
84 return Promise.resolve(true);
85 } else if (!chrome.tabs) {
86 // Can't get it? Done. (This happens to packaged apps, which can't access
87 // chrome.tabs.)
88 return Promise.resolve(true);
89 } else {
90 return new Promise(function(resolve, reject) {
91 chrome.tabs.query({active: true, lastFocusedWindow: true},
92 function(tabs) {
93 if (!tabs.length) {
94 // Safety check.
95 reject(false);
96 return;
98 var tab = tabs[0];
99 tabMatchesOrigin(tab, sender.origin).then(function(tabId) {
100 sender.tabId = tabId;
101 resolve(true);
102 }, function() {
103 // Didn't match? Check if the debugger is open.
104 if (tab.url.indexOf('chrome-devtools://') != 0) {
105 reject(false);
106 return;
108 // Debugger active: find first tab with the sender's origin.
109 chrome.tabs.query({active: true}, function(tabs) {
110 if (!tabs.length) {
111 // Safety check.
112 reject(false);
113 return;
115 var numRejected = 0;
116 for (var i = 0; i < tabs.length; i++) {
117 tab = tabs[i];
118 tabMatchesOrigin(tab, sender.origin).then(function(tabId) {
119 sender.tabId = tabId;
120 resolve(true);
121 }, function() {
122 if (++numRejected >= tabs.length) {
123 // None matches: reject.
124 reject(false);