// Copyright 2007 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview Provides the namesspace for client-side communication * between pages originating from different domains (it works also * with pages from the same domain, but doing that is kinda * pointless). * * The only publicly visible class is goog.net.xpc.CrossPageChannel. * * Note: The preferred name for the main class would have been * CrossDomainChannel. But as there already is a class named like * that (which serves a different purpose) in the maps codebase, * CrossPageChannel was chosen to avoid confusion. * * CrossPageChannel abstracts the underlying transport mechanism to * provide a common interface in all browsers. * * * @suppress {underscore} */ /* TODO(user) - resolve fastback issues in Safari (IframeRelayTransport) */ /** * Namespace for CrossPageChannel */ goog.provide('goog.net.xpc'); goog.provide('goog.net.xpc.CfgFields'); goog.provide('goog.net.xpc.ChannelStates'); goog.provide('goog.net.xpc.TransportNames'); goog.provide('goog.net.xpc.TransportTypes'); goog.provide('goog.net.xpc.UriCfgFields'); goog.require('goog.log'); goog.forwardDeclare('goog.net.xpc.CrossPageChannel'); // circular /** * Enum used to identify transport types. * @enum {number} */ goog.net.xpc.TransportTypes = { NATIVE_MESSAGING: 1, FRAME_ELEMENT_METHOD: 2, IFRAME_RELAY: 3, IFRAME_POLLING: 4, FLASH: 5, NIX: 6, DIRECT: 7 }; /** * Enum containing transport names. These need to correspond to the * transport class names for createTransport_() to work. * @const {!Object} */ goog.net.xpc.TransportNames = { '1': 'NativeMessagingTransport', '2': 'FrameElementMethodTransport', '3': 'IframeRelayTransport', '4': 'IframePollingTransport', '5': 'FlashTransport', '6': 'NixTransport', '7': 'DirectTransport' }; // TODO(user): Add auth token support to other methods. /** * Field names used on configuration object. * @const */ goog.net.xpc.CfgFields = { /** * Channel name identifier. * Both peers have to be initialized with * the same channel name. If not present, a channel name is * generated (which then has to transferred to the peer somehow). */ CHANNEL_NAME: 'cn', /** * Authorization token. If set, NIX will use this authorization token * to validate the setup. */ AUTH_TOKEN: 'at', /** * Remote party's authorization token. If set, NIX will validate this * authorization token against that sent by the other party. */ REMOTE_AUTH_TOKEN: 'rat', /** * The URI of the peer page. */ PEER_URI: 'pu', /** * Ifame-ID identifier. * The id of the iframe element the peer-document lives in. */ IFRAME_ID: 'ifrid', /** * Transport type identifier. * The transport type to use. Possible values are entries from * goog.net.xpc.TransportTypes. If not present, the transport is * determined automatically based on the useragent's capabilities. */ TRANSPORT: 'tp', /** * Local relay URI identifier (IframeRelayTransport-specific). * The URI (can't contain a fragment identifier) used by the peer to * relay data through. */ LOCAL_RELAY_URI: 'lru', /** * Peer relay URI identifier (IframeRelayTransport-specific). * The URI (can't contain a fragment identifier) used to relay data * to the peer. */ PEER_RELAY_URI: 'pru', /** * Local poll URI identifier (IframePollingTransport-specific). * The URI (can't contain a fragment identifier)which is polled * to receive data from the peer. */ LOCAL_POLL_URI: 'lpu', /** * Local poll URI identifier (IframePollingTransport-specific). * The URI (can't contain a fragment identifier) used to send data * to the peer. */ PEER_POLL_URI: 'ppu', /** * The hostname of the peer window, including protocol, domain, and port * (if specified). Used for security sensitive applications that make * use of NativeMessagingTransport (i.e. most applications). */ PEER_HOSTNAME: 'ph', /** * Usually both frames using a connection initially send a SETUP message to * each other, and each responds with a SETUP_ACK. A frame marks itself * connected when it receives that SETUP_ACK. If this parameter is true * however, the channel it is passed to will not send a SETUP, but rather will * wait for one from its peer and mark itself connected when that arrives. * Peer iframes created using such a channel will send SETUP however, and will * wait for SETUP_ACK before marking themselves connected. The goal is to * cope with a situation where the availability of the URL for the peer frame * cannot be relied on, eg when the application is offline. Without this * setting, the primary frame will attempt to send its SETUP message every * 100ms, forever. This floods the javascript console with uncatchable * security warnings, and fruitlessly burns CPU. There is one scenario this * mode will not support, and that is reconnection by the outer frame, ie the * creation of a new channel object to connect to a peer iframe which was * already communicating with a previous channel object of the same name. If * that behavior is needed, this mode should not be used. Reconnection by * inner frames is supported in this mode however. */ ONE_SIDED_HANDSHAKE: 'osh', /** * The frame role (inner or outer). Used to explicitly indicate the role for * each peer whenever the role cannot be reliably determined (e.g. the two * peer windows are not parent/child frames). If unspecified, the role will * be dynamically determined, assuming a parent/child frame setup. */ ROLE: 'role', /** * Which version of the native transport startup protocol should be used, the * default being '2'. Version 1 had various timing vulnerabilities, which * had to be compensated for by introducing delays, and is deprecated. V1 * and V2 are broadly compatible, although the more robust timing and lack * of delays is not gained unless both sides are using V2. The only * unsupported case of cross-protocol interoperation is where a connection * starts out with V2 at both ends, and one of the ends reconnects as a V1. * All other initial startup and reconnection scenarios are supported. */ NATIVE_TRANSPORT_PROTOCOL_VERSION: 'nativeProtocolVersion', /** * Whether the direct transport runs in synchronous mode. The default is to * emulate the other transports and run asyncronously but there are some * circumstances where syncronous calls are required. If this property is * set to true, the transport will send the messages synchronously. */ DIRECT_TRANSPORT_SYNC_MODE: 'directSyncMode' }; /** * Config properties that need to be URL sanitized. * @type {Array} */ goog.net.xpc.UriCfgFields = [ goog.net.xpc.CfgFields.PEER_URI, goog.net.xpc.CfgFields.LOCAL_RELAY_URI, goog.net.xpc.CfgFields.PEER_RELAY_URI, goog.net.xpc.CfgFields.LOCAL_POLL_URI, goog.net.xpc.CfgFields.PEER_POLL_URI ]; /** * @enum {number} */ goog.net.xpc.ChannelStates = { NOT_CONNECTED: 1, CONNECTED: 2, CLOSED: 3 }; /** * The name of the transport service (used for internal signalling). * @type {string} * @suppress {underscore|visibility} */ goog.net.xpc.TRANSPORT_SERVICE_ = 'tp'; /** * Transport signaling message: setup. * @type {string} */ goog.net.xpc.SETUP = 'SETUP'; /** * Transport signaling message: setup for native transport protocol v2. * @type {string} */ goog.net.xpc.SETUP_NTPV2 = 'SETUP_NTPV2'; /** * Transport signaling message: setup acknowledgement. * @type {string} * @suppress {underscore|visibility} */ goog.net.xpc.SETUP_ACK_ = 'SETUP_ACK'; /** * Transport signaling message: setup acknowledgement. * @type {string} */ goog.net.xpc.SETUP_ACK_NTPV2 = 'SETUP_ACK_NTPV2'; /** * Object holding active channels. * * @package {Object} */ goog.net.xpc.channels = {}; /** * Returns a random string. * @param {number} length How many characters the string shall contain. * @param {string=} opt_characters The characters used. * @return {string} The random string. */ goog.net.xpc.getRandomString = function(length, opt_characters) { var chars = opt_characters || goog.net.xpc.randomStringCharacters_; var charsLength = chars.length; var s = ''; while (length-- > 0) { s += chars.charAt(Math.floor(Math.random() * charsLength)); } return s; }; /** * The default characters used for random string generation. * @type {string} * @private */ goog.net.xpc.randomStringCharacters_ = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; /** * The logger. * @type {goog.log.Logger} */ goog.net.xpc.logger = goog.log.getLogger('goog.net.xpc');