Skip to content

Commit

Permalink
Server support for htmlfile transport
Browse files Browse the repository at this point in the history
  • Loading branch information
majek committed Aug 23, 2011
1 parent b0a58ed commit 16de93d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/sockjs.coffee
Expand Up @@ -7,6 +7,7 @@ trans_jsonp = require('./trans-jsonp')
trans_xhr = require('./trans-xhr')
iframe = require('./iframe')
trans_eventsource = require('./trans-eventsource')
trans_htmlfile = require('./trans-htmlfile')


app =
Expand All @@ -27,6 +28,7 @@ $.extend(app, trans_websocket.app)
$.extend(app, trans_jsonp.app)
$.extend(app, trans_xhr.app)
$.extend(app, trans_eventsource.app)
$.extend(app, trans_htmlfile.app)


class Server extends events.EventEmitter
Expand All @@ -52,14 +54,16 @@ class Server extends events.EventEmitter
dispatcher = [
['GET', p(''), ['welcome_screen']],
['GET', p('/iframe[0-9-.a-z_]*.html'), ['iframe', 'cache_for', 'expose']],
['GET', t('/jsonp'), ['h_sid', 'h_no_cache', 'jsonp']],
['POST',t('/jsonp_send'), ['h_sid', 'expect_form', 'jsonp_send']],
['GET', t('/jsonp'), ['h_sid', 'h_no_cache', 'jsonp']],
['POST', t('/jsonp_send'), ['h_sid', 'expect_form', 'jsonp_send']],
['POST', t('/xhr'), ['h_sid', 'xhr_cors', 'xhr_poll']],
['OPTIONS', t('/xhr'), opts_filters],
['POST', t('/xhr_send'), ['h_sid', 'xhr_cors', 'expect_xhr', 'xhr_send']],
['OPTIONS', t('/xhr_send'), opts_filters],
['POST', t('/xhr_streaming'), ['h_sid', 'xhr_cors', 'xhr_streaming']],
['OPTIONS', t('/xhr_streaming'), opts_filters],
['GET', t('/eventsource'), ['h_sid', 'h_no_cache', 'eventsource']],
['GET', t('/htmlfile'), ['h_sid', 'h_no_cache', 'htmlfile']],
]
maybe_add_transport = (name, urls) ->
if options.disabled_transports.indexOf(name) isnt -1
Expand All @@ -70,8 +74,6 @@ class Server extends events.EventEmitter
dispatcher = dispatcher.concat(urls)
maybe_add_transport('websocket',[
['GET', t('/websocket'), ['websocket']]])
maybe_add_transport('eventsource',[
['GET', t('/eventsource'), ['h_sid', 'h_no_cache', 'eventsource']]])
webjs_handler = new webjs.WebJS(app, dispatcher)

install_handler = (ee, event, handler) ->
Expand Down
51 changes: 51 additions & 0 deletions src/trans-htmlfile.coffee
@@ -0,0 +1,51 @@
utils = require('./utils')
transport = require('./transport')

# Browsers fail with "Uncaught exception: ReferenceError: Security
# error: attempted to read protected variable: _jp". Set
# document.domain in order to work around that.
iframe_template = """
<!doctype html>
<html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head><body><h2>Don't panic!</h2>
<script>
document.domain = document.domain;
function p(d){
if (d[0] === 'c') {
document.body.onload = null;
}
parent.{{ callback }}(d);
};
document.body.onload = function() {p('c[1006, "Html iframe connection broken"]');};
</script>
"""
# Safari needs at least 1024 bytes to parse the website. Relevant:
# http://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors
iframe_template += Array(1024 - iframe_template.length).join(' ')
iframe_template += '\r\n\r\n'


class HtmlFileReceiver extends transport.ResponseReceiver
protocol: "htmlfile"

doSendFrame: (payload) ->
super( '<script>p(' + JSON.stringify(payload) + ');</script>\r\n' )


exports.app =
htmlfile: (req, res) ->
if not('c' of req.query or 'callback' of req.query)
throw {
status: 500
message: '"callback" parameter required'
}
callback = if 'c' of req.query then req.query['c'] else req.query['callback']
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
res.writeHead(200)
res.write(iframe_template.replace(/{{ callback }}/g, callback));

session = transport.Session.bySessionIdOrNew(req.session, req.sockjs_server)
session.register( new HtmlFileReceiver(res) )
return true

0 comments on commit 16de93d

Please sign in to comment.