Author: johnh Date: Wed Mar 2 02:23:13 2011 New Revision: 1076087 URL: http://svn.apache.org/viewvc?rev=1076087&view=rev Log: First working cut of Flash gadgets.rpc transport!
Change desc from http://codereview.appspot.com/4258043/: With these changes, the Flash transport for gadgets.rpc works for the first time! This is with a number of caveats, for the moment: 1. It's only activated when the &flash=1 parameter is added to feature.xml 2. Doesn't work on IE since embed code uses <embed> rather than <object> Both of these will be removed in subsequent CLs. The test harness is updated here in various small ways as well to allow testing of this and other transports. Tested: * Initialization from gadgets.config (asynchronous application of SWF) for configurability. * Callbacks and multiple fast requests (performance is slow) * RPC call before setup completed (early RPC queueing re-enabled). The last point bears attention, since it re-enables the ability to call gadgets.rpc.call before any given transport's setup mechanism is complete (window.postMessage can have dropped messages as a result as well w/o this). But it also means that the transport handshake mechanism is quite important, as completion of it unlocks message passing. Committing now since the transport isn't enabled. Modified: shindig/trunk/config/container.js shindig/trunk/content/container/rpctest_container.html shindig/trunk/content/container/rpctest_gadget.xml shindig/trunk/content/xpc.swf shindig/trunk/features/src/main/flex/Main.as shindig/trunk/features/src/main/javascript/features/rpc/feature.xml shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js shindig/trunk/features/src/main/javascript/features/rpc/rpc.js Modified: shindig/trunk/config/container.js URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/config/container.js (original) +++ shindig/trunk/config/container.js Wed Mar 2 02:23:13 2011 @@ -227,7 +227,10 @@ // If true, this will use the legacy ifpc wire format when making rpc // requests. - "useLegacyProtocol" : false + "useLegacyProtocol" : false, + + // Path to the cross-domain enabling SWF for rpc's Flash transport. + "commSwf": "/xpc.swf" }, // Skin defaults "skins" : { Modified: shindig/trunk/content/container/rpctest_container.html URL: http://svn.apache.org/viewvc/shindig/trunk/content/container/rpctest_container.html?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/content/container/rpctest_container.html (original) +++ shindig/trunk/content/container/rpctest_container.html Wed Mar 2 02:23:13 2011 @@ -37,7 +37,6 @@ This test container/gadget pair is configurable via two other options: * &gadgetdeferred=1 - tests early-message queueing from container to gadget, by preventing attachment of gadget until a button is pressed. - * &uselegacy=1 - tests legacy IFPC functionality. * &uabackward=1 - tests "incorrect" rpc.js setup in container: gadgets.rpc.setAuthToken(...) called before, not after, gadget frame exists. @@ -50,29 +49,18 @@ // Configurable test harness options. var gadgethost = 'http://' + window.location.search.substring(1).split('&')[0]; var gadgetdeferred = window.location.search.indexOf('&gadgetdeferred=1') !== -1; - var uselegacy = window.location.search.indexOf('&uselegacy=1') !== -1; var uabackward = window.location.search.indexOf('&uabackward=1') !== -1; + var flash = window.location.search.indexOf('&flash=1') !== -1; // Useful per-page variables. var gadgeturl = gadgethost + '/container/rpctest_gadget.xml'; var cachebust = 'cachebust=' + Math.random(); - var gadgetrenderingurl = gadgethost + '/gadgets/ifr?url=' + gadgeturl + '&libs=rpc&parent=' + window.location.protocol + '//' + window.location.host + '&debug=1&' + cachebust; + var gadgetrenderingurl = gadgethost + '/gadgets/ifr?url=' + gadgeturl + '&libs=rpc&parent=' + window.location.protocol + '//' + window.location.host + '&debug=1&nocache=1&' + cachebust + (flash ? '&flash=1' : ''); var gadgetrelay = gadgethost + '/container/rpc_relay.uncompressed.html'; - // Set up faux gadgets.config(...) - var gadgets = {}; - gadgets.config = { - register: function(rpc, requiredConfig, callback) { - // rpc === "rpc", requiredConfig is ignored here. - // Just call the callback (function init(...) in rpc.js) - // with a dummy config object. - callback({ rpc: { parentRelayUrl: "", uselegacyProtocol: uselegacy } }); - } - }; - // Include rpc.js. Append random cache-busting param to ensure caching doesn't occur. document.write('<scr' + 'ipt language="JavaScript" type="text/javascript" src="' + - '/gadgets/js/rpc.js?c=1&debug=1&' + cachebust + '"></scr' + 'ipt>'); + '/gadgets/js/rpc.js?c=1&nocache=1&debug=1&' + cachebust + '"></scr' + 'ipt>'); // Include rpctest_perf.js JS test helper, also with cachebusting. document.write('<scr' + 'ipt language="JavaScript" type="text/javascript" src="' + Modified: shindig/trunk/content/container/rpctest_gadget.xml URL: http://svn.apache.org/viewvc/shindig/trunk/content/container/rpctest_gadget.xml?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/content/container/rpctest_gadget.xml (original) +++ shindig/trunk/content/container/rpctest_gadget.xml Wed Mar 2 02:23:13 2011 @@ -64,7 +64,7 @@ </script> <div>gadgets.rpc Performance: "Gadget" page</div><hr/> <script> - document.write("<div>Parent relay: " + gadgets.rpc.getRelayUrl('..') + "</div><hr/>"); + document.write("<div>Parent relay: " + gadgets.rpc.getRelayUrl('..') + "<br/>method: " + gadgets.rpc.getRelayChannel() + "</div><hr/>"); </script> <div>Test<br/> <ul> Modified: shindig/trunk/content/xpc.swf URL: http://svn.apache.org/viewvc/shindig/trunk/content/xpc.swf?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== Files shindig/trunk/content/xpc.swf (original) and shindig/trunk/content/xpc.swf Wed Mar 2 02:23:13 2011 differ Modified: shindig/trunk/features/src/main/flex/Main.as URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/flex/Main.as?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/features/src/main/flex/Main.as (original) +++ shindig/trunk/features/src/main/flex/Main.as Wed Mar 2 02:23:13 2011 @@ -36,7 +36,7 @@ class Main { } else { my_origin = _level0.origin; } - + var domain:String = my_origin.substr(my_origin.indexOf("//") + 2, my_origin.length); if (my_origin.substr(0,5)==="http:") { @@ -45,34 +45,41 @@ class Main { security.allowDomain(domain); } - ExternalInterface.addCallback("setup", { }, function(channel_recv_id:String, role:String) { - if (channel_recv_id.indexOf(":") > -1) { + ExternalInterface.addCallback("setup", { }, function(my_id:String, target_id:String) { + if (target_id.indexOf(":") > -1) { return; } + var role:String; var other_role:String; - - if (role == "INNER") { + var channel_recv_id:String; + + if (target_id == "..") { + role = "INNER"; other_role = "OUTER"; + channel_recv_id = my_id; } else { role = "OUTER"; other_role = "INNER"; + channel_recv_id = target_id; } var receiving_lc:LocalConnection = new LocalConnection(); var sending_lc:LocalConnection = new LocalConnection(); - receiving_lc.receiveMessage = function(to_origin:String, from_origin:String, target_id:String, message:String) { - if ((to_origin === "*" || to_origin === my_origin) && target_id === channel_recv_id) { - ExternalInterface.call("gadgets.rpctx.flash._receiveMessage", target_id, message, from_origin, to_origin); + receiving_lc.receiveMessage = function(to_origin:String, from_origin:String, from_id:String, message:String) { + //ExternalInterface.call("alert", "receiving_lc.receiveMessage(), to_origin=" + to_origin + ", from_origin=" + from_origin + ", from_id=" + from_id + ", my_origin=" + my_origin + ", target_id=" + target_id + ", channel_recv_id=" + channel_recv_id + ", check1=" + (to_origin===my_origin) + ", check2.1=" + (from_id === target_id) + ", check2.2=" + (from_id === "_top") + ", check2.3=" + (target_id === "..")); + if ((to_origin === "*" || to_origin === my_origin) && ((from_id === target_id) || (from_id === "_top" && target_id === ".."))) { + ExternalInterface.call("gadgets.rpctx.flash._receiveMessage", from_id, message, from_origin, to_origin); } }; - ExternalInterface.addCallback("sendMessage_" + channel_recv_id, { }, function(message:String, to_origin:String) { + ExternalInterface.addCallback("sendMessage_" + target_id, { }, function(message:String, to_origin:String) { if (!to_origin) to_origin = "*"; - sending_lc.send(channel_recv_id + "_" + other_role, "receiveMessage", to_origin, my_origin, channel_recv_id, message); - } ); + //ExternalInterface.call("alert", "attempting to send message: " + message + " to=" + to_origin + ", channel=" + channel_recv_id + "_" + other_role + ", target_id=" + target_id); + sending_lc.send(channel_recv_id + "_" + other_role, "receiveMessage", to_origin, my_origin, my_id, message); + }); receiving_lc.connect(channel_recv_id + "_" + role); - } ); + }); ExternalInterface.call("gadgets.rpctx.flash._ready"); } Modified: shindig/trunk/features/src/main/javascript/features/rpc/feature.xml URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/feature.xml?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/rpc/feature.xml (original) +++ shindig/trunk/features/src/main/javascript/features/rpc/feature.xml Wed Mar 2 02:23:13 2011 @@ -45,6 +45,7 @@ specific language governing permissions <exports type="js">gadgets.rpc.getReceiverOrigin</exports> </api> <script src="wpm.transport.js"/> + <script src="flash.transport.js"/> <script src="fe.transport.js"/> <script src="nix.transport.js"/> <script src="rmr.transport.js"/> Modified: shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js (original) +++ shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js Wed Mar 2 02:23:13 2011 @@ -32,8 +32,8 @@ gadgets.rpctx = gadgets.rpctx || {}; if (!gadgets.rpctx.flash) { // make lib resilient to double-inclusion gadgets.rpctx.flash = function() { - // TODO: provide method to override this - var swfUrl = "//flashrpc.googleusercontent.com/xpc.swf"; + var swfUrl = null; + var usingFlash = false; var process = null; var ready = null; var secureReceivers = {}; @@ -45,13 +45,24 @@ if (!gadgets.rpctx.flash) { // make lib var setupHandle = null; var setupAttempts = 0; - var myLoc = window.location.href; + var myLoc = window.location.protocol + "//" + window.location.host; + + function init(config) { + if (usingFlash) { + swfUrl = config['rpc']['commSwf'] || "/xpc.swf"; + } + } + gadgets.config.register('rpc', null, init); function relayLoader() { - if (relayHandle === null && document.body) { + if (relayHandle === null && document.body && swfUrl) { relayHandle = document.createElement('embed'); - relayHandle.allowScriptAccess = true; + relayHandle.setAttribute("allowScriptAccess", "always"); relayHandle.src = swfUrl + '?origin=' + myLoc; + relayHandle.style.top = -1; + relayHandle.style.left = -1; + relayHandle.style.height = 1; + relayHandle.style.width = 1; document.body.appendChild(relayHandle); } ++setupAttempts; @@ -65,7 +76,8 @@ if (!gadgets.rpctx.flash) { // make lib if (relayHandle !== null) { while (pendingHandshakes.length > 0) { var shake = pendingHandshakes.shift(); - relayHandle.setup(shake.id, shake.role); + relayHandle['setup'](shake.myId, shake.targetId); + ready(shake.targetId, true); } } } @@ -83,6 +95,7 @@ if (!gadgets.rpctx.flash) { // make lib init: function(processFn, readyFn) { process = processFn; ready = readyFn; + usingFlash = true; return true; }, @@ -95,8 +108,7 @@ if (!gadgets.rpctx.flash) { // make lib // otherwise polling will occur until the SWF has completed loading, at // which point all connections will complete their handshake. secureReceivers[receiverId] = !!forceSecure; - var role = targetId === ".." ? "OUTER" : "INNER"; - pendingHandshakes.push({ id: targetId, role: role }); + pendingHandshakes.push({ myId: gadgets.rpc.RPC_ID, targetId: receiverId }); if (relayHandle === null && setupHandle === null) { setupHandle = window.setTimeout(relayLoader, LOADER_TIMEOUT_MS); } @@ -106,13 +118,14 @@ if (!gadgets.rpctx.flash) { // make lib call: function(targetId, from, rpc) { var targetOrigin = gadgets.rpc.getTargetOrigin(targetId);; - relayHandle["sendMessage_" + targetId](gadgets.json.stringify(rpc), targetOrigin); + var messageHandler = relayHandle["sendMessage_" + targetId]; + messageHandler.call(relayHandle, gadgets.json.stringify(rpc), targetOrigin); return true; }, // Methods called by relay SWF. Should be considered private. - _receiveMessage: function(targetId, message, fromOrigin, toOrigin) { - // TODO: validate targetId for sanity, and fromOrigin/toOrigin for domain verification. + _receiveMessage: function(fromId, message, fromOrigin, toOrigin) { + // TODO: validate fromId for sanity, and fromOrigin/toOrigin for domain verification. window.setTimeout(function() { process(gadgets.json.parse(message)); }, 0); }, Modified: shindig/trunk/features/src/main/javascript/features/rpc/rpc.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/rpc.js?rev=1076087&r1=1076086&r2=1076087&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/rpc/rpc.js (original) +++ shindig/trunk/features/src/main/javascript/features/rpc/rpc.js Wed Mar 2 02:23:13 2011 @@ -180,6 +180,7 @@ if (!gadgets.rpc) { // make lib resilien * @member gadgets.rpc */ function getTransport() { + if (params['flash'] == "1") return gadgets.rpctx.flash; return typeof window.postMessage === 'function' ? gadgets.rpctx.wpm : typeof window.postMessage === 'object' ? gadgets.rpctx.wpm : window.ActiveXObject ? gadgets.rpctx.nix : @@ -872,7 +873,7 @@ if (!gadgets.rpc) { // make lib resilien // target is misconfigured, it won't affect the others. // In the case of a sibling relay, channel is not found // in the receiverTx map but in the transport itself. - var channel = receiverTx[targetId] || transport; + var channel = receiverTx[targetId]; // || transport; if (!channel) { // Not set up yet. Enqueue the rpc for such time as it is. @@ -1024,7 +1025,7 @@ if (!gadgets.rpc) { // make lib resilien ACK: ACK, - RPC_ID: rpcId, + RPC_ID: rpcId || "_top", SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT, SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
