xpc.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Provides the namesspace for client-side communication
  16. * between pages originating from different domains (it works also
  17. * with pages from the same domain, but doing that is kinda
  18. * pointless).
  19. *
  20. * The only publicly visible class is goog.net.xpc.CrossPageChannel.
  21. *
  22. * Note: The preferred name for the main class would have been
  23. * CrossDomainChannel. But as there already is a class named like
  24. * that (which serves a different purpose) in the maps codebase,
  25. * CrossPageChannel was chosen to avoid confusion.
  26. *
  27. * CrossPageChannel abstracts the underlying transport mechanism to
  28. * provide a common interface in all browsers.
  29. *
  30. *
  31. * @suppress {underscore}
  32. */
  33. /*
  34. TODO(user)
  35. - resolve fastback issues in Safari (IframeRelayTransport)
  36. */
  37. /**
  38. * Namespace for CrossPageChannel
  39. */
  40. goog.provide('goog.net.xpc');
  41. goog.provide('goog.net.xpc.CfgFields');
  42. goog.provide('goog.net.xpc.ChannelStates');
  43. goog.provide('goog.net.xpc.TransportNames');
  44. goog.provide('goog.net.xpc.TransportTypes');
  45. goog.provide('goog.net.xpc.UriCfgFields');
  46. goog.require('goog.log');
  47. goog.forwardDeclare('goog.net.xpc.CrossPageChannel'); // circular
  48. /**
  49. * Enum used to identify transport types.
  50. * @enum {number}
  51. */
  52. goog.net.xpc.TransportTypes = {
  53. NATIVE_MESSAGING: 1,
  54. FRAME_ELEMENT_METHOD: 2,
  55. IFRAME_RELAY: 3,
  56. IFRAME_POLLING: 4,
  57. FLASH: 5,
  58. NIX: 6,
  59. DIRECT: 7
  60. };
  61. /**
  62. * Enum containing transport names. These need to correspond to the
  63. * transport class names for createTransport_() to work.
  64. * @const {!Object<string,string>}
  65. */
  66. goog.net.xpc.TransportNames = {
  67. '1': 'NativeMessagingTransport',
  68. '2': 'FrameElementMethodTransport',
  69. '3': 'IframeRelayTransport',
  70. '4': 'IframePollingTransport',
  71. '5': 'FlashTransport',
  72. '6': 'NixTransport',
  73. '7': 'DirectTransport'
  74. };
  75. // TODO(user): Add auth token support to other methods.
  76. /**
  77. * Field names used on configuration object.
  78. * @const
  79. */
  80. goog.net.xpc.CfgFields = {
  81. /**
  82. * Channel name identifier.
  83. * Both peers have to be initialized with
  84. * the same channel name. If not present, a channel name is
  85. * generated (which then has to transferred to the peer somehow).
  86. */
  87. CHANNEL_NAME: 'cn',
  88. /**
  89. * Authorization token. If set, NIX will use this authorization token
  90. * to validate the setup.
  91. */
  92. AUTH_TOKEN: 'at',
  93. /**
  94. * Remote party's authorization token. If set, NIX will validate this
  95. * authorization token against that sent by the other party.
  96. */
  97. REMOTE_AUTH_TOKEN: 'rat',
  98. /**
  99. * The URI of the peer page.
  100. */
  101. PEER_URI: 'pu',
  102. /**
  103. * Ifame-ID identifier.
  104. * The id of the iframe element the peer-document lives in.
  105. */
  106. IFRAME_ID: 'ifrid',
  107. /**
  108. * Transport type identifier.
  109. * The transport type to use. Possible values are entries from
  110. * goog.net.xpc.TransportTypes. If not present, the transport is
  111. * determined automatically based on the useragent's capabilities.
  112. */
  113. TRANSPORT: 'tp',
  114. /**
  115. * Local relay URI identifier (IframeRelayTransport-specific).
  116. * The URI (can't contain a fragment identifier) used by the peer to
  117. * relay data through.
  118. */
  119. LOCAL_RELAY_URI: 'lru',
  120. /**
  121. * Peer relay URI identifier (IframeRelayTransport-specific).
  122. * The URI (can't contain a fragment identifier) used to relay data
  123. * to the peer.
  124. */
  125. PEER_RELAY_URI: 'pru',
  126. /**
  127. * Local poll URI identifier (IframePollingTransport-specific).
  128. * The URI (can't contain a fragment identifier)which is polled
  129. * to receive data from the peer.
  130. */
  131. LOCAL_POLL_URI: 'lpu',
  132. /**
  133. * Local poll URI identifier (IframePollingTransport-specific).
  134. * The URI (can't contain a fragment identifier) used to send data
  135. * to the peer.
  136. */
  137. PEER_POLL_URI: 'ppu',
  138. /**
  139. * The hostname of the peer window, including protocol, domain, and port
  140. * (if specified). Used for security sensitive applications that make
  141. * use of NativeMessagingTransport (i.e. most applications).
  142. */
  143. PEER_HOSTNAME: 'ph',
  144. /**
  145. * Usually both frames using a connection initially send a SETUP message to
  146. * each other, and each responds with a SETUP_ACK. A frame marks itself
  147. * connected when it receives that SETUP_ACK. If this parameter is true
  148. * however, the channel it is passed to will not send a SETUP, but rather will
  149. * wait for one from its peer and mark itself connected when that arrives.
  150. * Peer iframes created using such a channel will send SETUP however, and will
  151. * wait for SETUP_ACK before marking themselves connected. The goal is to
  152. * cope with a situation where the availability of the URL for the peer frame
  153. * cannot be relied on, eg when the application is offline. Without this
  154. * setting, the primary frame will attempt to send its SETUP message every
  155. * 100ms, forever. This floods the javascript console with uncatchable
  156. * security warnings, and fruitlessly burns CPU. There is one scenario this
  157. * mode will not support, and that is reconnection by the outer frame, ie the
  158. * creation of a new channel object to connect to a peer iframe which was
  159. * already communicating with a previous channel object of the same name. If
  160. * that behavior is needed, this mode should not be used. Reconnection by
  161. * inner frames is supported in this mode however.
  162. */
  163. ONE_SIDED_HANDSHAKE: 'osh',
  164. /**
  165. * The frame role (inner or outer). Used to explicitly indicate the role for
  166. * each peer whenever the role cannot be reliably determined (e.g. the two
  167. * peer windows are not parent/child frames). If unspecified, the role will
  168. * be dynamically determined, assuming a parent/child frame setup.
  169. */
  170. ROLE: 'role',
  171. /**
  172. * Which version of the native transport startup protocol should be used, the
  173. * default being '2'. Version 1 had various timing vulnerabilities, which
  174. * had to be compensated for by introducing delays, and is deprecated. V1
  175. * and V2 are broadly compatible, although the more robust timing and lack
  176. * of delays is not gained unless both sides are using V2. The only
  177. * unsupported case of cross-protocol interoperation is where a connection
  178. * starts out with V2 at both ends, and one of the ends reconnects as a V1.
  179. * All other initial startup and reconnection scenarios are supported.
  180. */
  181. NATIVE_TRANSPORT_PROTOCOL_VERSION: 'nativeProtocolVersion',
  182. /**
  183. * Whether the direct transport runs in synchronous mode. The default is to
  184. * emulate the other transports and run asyncronously but there are some
  185. * circumstances where syncronous calls are required. If this property is
  186. * set to true, the transport will send the messages synchronously.
  187. */
  188. DIRECT_TRANSPORT_SYNC_MODE: 'directSyncMode'
  189. };
  190. /**
  191. * Config properties that need to be URL sanitized.
  192. * @type {Array<string>}
  193. */
  194. goog.net.xpc.UriCfgFields = [
  195. goog.net.xpc.CfgFields.PEER_URI, goog.net.xpc.CfgFields.LOCAL_RELAY_URI,
  196. goog.net.xpc.CfgFields.PEER_RELAY_URI, goog.net.xpc.CfgFields.LOCAL_POLL_URI,
  197. goog.net.xpc.CfgFields.PEER_POLL_URI
  198. ];
  199. /**
  200. * @enum {number}
  201. */
  202. goog.net.xpc.ChannelStates = {
  203. NOT_CONNECTED: 1,
  204. CONNECTED: 2,
  205. CLOSED: 3
  206. };
  207. /**
  208. * The name of the transport service (used for internal signalling).
  209. * @type {string}
  210. * @suppress {underscore|visibility}
  211. */
  212. goog.net.xpc.TRANSPORT_SERVICE_ = 'tp';
  213. /**
  214. * Transport signaling message: setup.
  215. * @type {string}
  216. */
  217. goog.net.xpc.SETUP = 'SETUP';
  218. /**
  219. * Transport signaling message: setup for native transport protocol v2.
  220. * @type {string}
  221. */
  222. goog.net.xpc.SETUP_NTPV2 = 'SETUP_NTPV2';
  223. /**
  224. * Transport signaling message: setup acknowledgement.
  225. * @type {string}
  226. * @suppress {underscore|visibility}
  227. */
  228. goog.net.xpc.SETUP_ACK_ = 'SETUP_ACK';
  229. /**
  230. * Transport signaling message: setup acknowledgement.
  231. * @type {string}
  232. */
  233. goog.net.xpc.SETUP_ACK_NTPV2 = 'SETUP_ACK_NTPV2';
  234. /**
  235. * Object holding active channels.
  236. *
  237. * @package {Object<string, goog.net.xpc.CrossPageChannel>}
  238. */
  239. goog.net.xpc.channels = {};
  240. /**
  241. * Returns a random string.
  242. * @param {number} length How many characters the string shall contain.
  243. * @param {string=} opt_characters The characters used.
  244. * @return {string} The random string.
  245. */
  246. goog.net.xpc.getRandomString = function(length, opt_characters) {
  247. var chars = opt_characters || goog.net.xpc.randomStringCharacters_;
  248. var charsLength = chars.length;
  249. var s = '';
  250. while (length-- > 0) {
  251. s += chars.charAt(Math.floor(Math.random() * charsLength));
  252. }
  253. return s;
  254. };
  255. /**
  256. * The default characters used for random string generation.
  257. * @type {string}
  258. * @private
  259. */
  260. goog.net.xpc.randomStringCharacters_ =
  261. 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  262. /**
  263. * The logger.
  264. * @type {goog.log.Logger}
  265. */
  266. goog.net.xpc.logger = goog.log.getLogger('goog.net.xpc');