Permalink
Browse files

In the middle of refactoring.

  • Loading branch information...
1 parent 0b10143 commit 9b6cc3508fe499b3731086907222655b674eb38f @satyamshekhar satyamshekhar committed Feb 22, 2012
Showing with 497 additions and 549 deletions.
  1. +118 −219 src/bosh.js
  2. +7 −0 src/cross_domain.xml
  3. +183 −133 src/http-server.js
  4. +28 −9 src/main.js
  5. +40 −32 src/options.js
  6. +85 −0 src/session-store.js
  7. +33 −148 src/session.js
  8. +3 −8 src/stream.js
View
@@ -23,256 +23,155 @@
*
*/
-var ltx = require('ltx');
var dutil = require('./dutil.js');
-var us = require('underscore');
-var sess = require('./session.js');
-var strm = require('./stream.js');
+var _ = require('underscore');
var helper = require('./helper.js');
-var opt = require('./options.js');
-var path = require('path');
-var bee = require('./bosh-event-emitter.js');
-var http = require('./http-server.js');
+var EventPipe = require('eventpipe').EventPipe;
+var BOSHServer = require('./bosh-http-server.js').BOSHServer;
+
+var stream_store = require('./stream-store.js');
+var session_store = require('./session-store.js');
-var toNumber = us.toNumber;
+var toNumber = _.toNumber;
var sprintf = dutil.sprintf;
var sprintfd = dutil.sprintfd;
+var path = require('path');
var filename = "[" + path.basename(path.normalize(__filename)) + "]";
var log = require('./log.js').getLogger(filename);
//
-// Important links:
-//
-// List of BOSH errors for the terminate packet
-// http://xmpp.org/extensions/xep-0124.html#errorstatus-terminal
-//
-// XEP-206
-// http://xmpp.org/extensions/xep-0206.html
-//
-// CORS headers
-// https://developer.mozilla.org/En/HTTP_access_control
-//
-
-//
-// options:
+// +-------+
+// | NOTE: |
+// +-------+
//
-// * path
-// * port
-// * host
-// * max_data_held
-// * max_bosh_connections
-// * window_size
-// * default_inactivity
-// * max_inactivity
-// * http_socket_keepalive
-// * http_headers
+// Always ensure that you update the definitions of the objects (in the
+// comments) as and when you add/remove members from them. Please try to
+// keep these object definitions up-to-date since it is the main
+// (and only) place of reference for object structure.
//
+function process_bosh_request(res, node) {
+ if (!node) return;
+ var nodes = [ ];
-exports.createServer = function (options) {
- //
- // +-------+
- // | NOTE: |
- // +-------+
- //
- // Always ensure that you update the definitions of the objects (in the
- // comments) as and when you add/remove members from them. Please try to
- // keep these object definitions up-to-date since it is the main
- // (and only) place of reference for object structure.
- //
-
- var started;
- var session_store;
- var stream_store;
- var bep;
- var bosh_options;
- var server;
-
- started = new Date(); // When was this server started?
-
- function get_statistics() {
- var stats = [ ];
- stats.push('<?xml version="1.0" encoding="utf-8"?>');
- stats.push('<!DOCTYPE html>');
- var content = new ltx.Element('html', {
- 'xmlns': 'http://www.w3.org/1999/xhtml',
- 'xml:lang': 'en'
- })
- .c('head')
- .c('title').t('node-xmpp-bosh').up()
- .up()
- .c('body')
- .c('h1')
- .c('a', {'href': 'https://github.com/dhruvbird/node-xmpp-bosh'})
- .t('node-xmpp-bosh')
- .up()
- .up()
- .c('h3').t('Bidirectional-streams Over Synchronous HTTP').up()
- .c('p').t(sprintf('Uptime: %s', dutil.time_diff(started, new Date()))).up()
- .c('p').t(sprintf('%s/%s active %s', session_store.get_active_no(),
- session_store.get_total_no(),
- dutil.pluralize(session_store.get_total_no(), 'session'))).up()
- .c('p').t(sprintf('%s/%s active %s', stream_store.get_active_no(),
- stream_store.get_total_no(),
- dutil.pluralize(stream_store.get_total_no(), 'stream'))).up()
- .tree();
- stats.push(content.toString());
- return stats.join('\n');
- }
-
- function process_bosh_request(res, node) {
- // This will eventually contain all the nodes to be processed.
- var nodes = [ ];
-
- var session = null;
- var stream = null;
+ var session = null;
+ var stream = null;
- node = helper.sanitize_request_node(node);
-
- // Check if this is a session start packet.
- if (helper.is_session_creation_packet(node)) {
- log.trace("Session Creation");
- session = session_store.add_session(node, res);
- stream = stream_store.add_stream(session, node);
-
- // Respond to the client.
- session.send_creation_response(stream);
- nodes = node.children;
-
- // NULL out res so that it is not added again
- res = null;
-
- //
- // In any case, we should process the XML nodes.
- //
- if (nodes.length > 0) {
- session.emit_nodes_event(nodes, stream);
- }
-
- } else {
- session = session_store.get_session(node);
- if (!session) { //No (valid) session ID in BOSH request. Not phare enuph.
- log.trace("%s Invalid Session", node.attrs.sid || "No_Session_ID");
- session_store.send_invalid_session_terminate_response(res, node);
- return;
- }
- try {
- // This is enclosed in a try/catch block since invalid requests
- // at this point MAY not have these attributes
- log.trace("%s %s req.rid: %s, session.rid: %s", session.sid,
- node.attrs.stream || "NO_Stream", node.attrs.rid,
- session.rid);
- } catch (ex) { }
+ node = helper.sanitize_request_node(node);
- // Check the validity of the packet and the BOSH session
- if (!session.is_valid_packet(node)) {
- log.trace("%s Invalid Packet", session.sid);
- session.send_invalid_packet_terminate_response(res, node);
- return;
- }
+ // Check if this is a session start packet.
+ if (helper.is_session_creation_packet(node)) {
+ log.trace("Session Creation");
+ session = session_store.add_session(node, res);
+ stream = stream_store.add_stream(session, node);
- // Reset the BOSH session timeout
- session.reset_inactivity_timeout();
+ // Respond to the client.
+ session.send_creation_response(stream);
+ nodes = node.children;
- if (session.add_request_for_processing(node, res, stream_store)){
- session.process_requests(stream_store);
- } else {
- session.send_pending_responses();
- }
- } // else (not session start)
+ // NULL out res so that it is not added again
+ res = null;
-
- // Comment #001
- //
- // Respond to any extra "held" response objects that we actually
- // should not be holding on to (Thanks Stefan)
- //
- // This is in disagreement with the XEP
- // http://xmpp.org/extensions/xep-0124.html#overactive
- // if the client sent an empty <body/> tag and was overactive
//
- // However, we do it since many flaky clients and network
- // configurations exist in the wild.
+ // In any case, we should process the XML nodes.
//
- session.respond_to_extra_held_response_objects();
- }
-
-
- function http_error_handler(ex) {
- // We enforce similar semantics as the rest of the node.js for the 'error'
- // event and throw an exception if it is unhandled
- if (!bep.emit('error', ex)) {
- throw new Error(
- sprintf('ERROR on listener at endpoint: http://%s:%s%s',
- options.host, options.port, options.path)
- );
+ if (nodes.length > 0) {
+ session.emit_nodes_event(nodes, stream);
}
- }
- //Called when the 'end' event for the request is fired by the HTTP request handler
- function bosh_request_handler(res, node) {
- if (!node) {
- res.writeHead(200, bosh_options.HTTP_POST_RESPONSE_HEADERS);
- res.end(helper.$terminate({ condition: 'bad-request' }).toString());
+ } else {
+ session = session_store.get_session(node);
+ if (!session) { //No (valid) session ID in BOSH request. Not phare enuph.
+ log.trace("%s Invalid Session", node.attrs.sid || "No_Session_ID");
+ session_store.send_invalid_session_terminate_response(res, node);
return;
}
- log.trace("Processing Request");
- process_bosh_request(res, node);
- }
-
- // When the Connector is able to add the stream, we too do the same and
- // respond to the client accordingly.
- function _on_stream_added(stream) {
- log.trace("%s %s stream-added", stream.state.sid, stream.name);
- // Send only if this is the 2nd (or more) stream on this BOSH session.
- // This should work all the time. If anyone finds a case where it will
- // NOT work, please do let me know.
- var session = stream.session;
- if (session.no_of_streams > 1) {
- stream.send_stream_add_response();
+ try {
+ // This is enclosed in a try/catch block since invalid requests
+ // at this point MAY not have these attributes
+ log.trace("%s %s req.rid: %s, session.rid: %s", session.sid,
+ node.attrs.stream || "NO_Stream", node.attrs.rid,
+ session.rid);
+ } catch (ex) { }
+
+ // Check the validity of the packet and the BOSH session
+ if (!session.is_valid_packet(node)) {
+ log.trace("%s Invalid Packet", session.sid);
+ session.send_invalid_packet_terminate_response(res, node);
+ return;
}
- }
- // When a response is received from the connector, try to send it out to the
- // real client if possible.
- function _on_repsponse(connector_response, stream) {
- log.trace("%s %s response: %s", stream.state.sid, stream.name, connector_response);
- var session = stream.session;
- session.enqueue_stanza(connector_response, stream);
- }
+ // Reset the BOSH session timeout
+ session.reset_inactivity_timeout();
- // This event is raised when the server terminates the connection.
- // The Connector typically raises this even so that we can tell
- // the client (user) that such an event has occurred.
- function _on_terminate(stream, error) {
- // We send a terminate response to the client.
- var condition = error || '';
- stream.send_stream_terminate_response(condition);
- stream.terminate(condition);
-
- var session = stream.session;
- // Should we terminate the BOSH session as well?
- if (session.no_of_streams === 0) {
- session.send_terminate_response(session.get_response_object(),
- condition);
- session.terminate(condition);
+ if (session.add_request_for_processing(node, res, stream_store)){
+ session.process_requests(stream_store);
+ } else {
+ session.send_pending_responses();
}
- }
+ } // else (not session start)
- bosh_options = new opt.BOSH_Options(options);
- server = new http.HTTPServer(options.port, options.host, get_statistics,
- bosh_request_handler, http_error_handler, bosh_options);
+
+ // Comment #001
+ //
+ // Respond to any extra "held" response objects that we actually
+ // should not be holding on to (Thanks Stefan)
+ //
+ // This is in disagreement with the XEP
+ // http://xmpp.org/extensions/xep-0124.html#overactive
+ // if the client sent an empty <body/> tag and was overactive
+ //
+ // However, we do it since many flaky clients and network
+ // configurations exist in the wild.
+ //
+ session.respond_to_extra_held_response_objects();
+}
+
+
+// When the Connector is able to add the stream, we too do the same and
+// respond to the client accordingly.
+function _on_stream_added(stream) {
+ log.trace("%s %s stream-added", stream.state.sid, stream.name);
+ // Send only if this is the 2nd (or more) stream on this BOSH session.
+ // This should work all the time. If anyone finds a case where it will
+ // NOT work, please do let me know.
+ var session = stream.session;
+ if (session.no_of_streams > 1) {
+ stream.send_stream_add_response();
+ }
+}
+
+// When a response is received from the connector, try to send it out to the
+// real client if possible.
+function _on_repsponse(connector_response, stream) {
+ log.trace("%s %s response: %s", stream.state.sid, stream.name, connector_response);
+ stream.session.enqueue_stanza(connector_response, stream);
+}
+
+// This event is raised when the server terminates the connection.
+// The Connector typically raises this even so that we can tell
+// the client (user) that such an event has occurred.
+function _on_terminate(stream, error) {
+ // We send a terminate response to the client.
+ var condition = error || '';
+ stream.send_stream_terminate_response(condition);
+ stream_store.
+ stream.terminate(condition);
+}
+
+exports.createServer = function () {
// The BOSH event emitter. People outside will subscribe to
// events from this guy. We return an instance of BoshEventPipe
// to the outside world when anyone calls createServer()
- bep = new bee.BoshEventPipe(server.http_server);
- bep.on('stream-added', _on_stream_added);
- bep.on('response', _on_repsponse);
- bep.on('terminate', _on_terminate);
- session_store = new sess.SessionStore(bosh_options, bep);
- stream_store = new strm.StreamStore(bosh_options, bep);
- bep.set_session_data(session_store);
- bep.set_stream_data(stream_store);
- return bep;
+ var bosh_server = new BOSHServer();
+ var boshEventPipe = new EventPipe();
+
+ boshEventPipe.on('stream-added', _on_stream_added)
+ .on('response', _on_repsponse)
+ .on('terminate', _on_terminate);
+ bosh_server.on("bosh-request", process_bosh_request);
+ bosh_server.start();
+
+ return boshEventPipe;
};
View
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
+<cross-domain-policy>
+ <site-control permitted-cross-domain-policies="all" />
+ <allow-access-from domain="*" to-ports="<%= port>" secure="true"/>
+ <allow-http-request-headers-from domain="*" headers="*" />
+</cross-domain-policy>
Oops, something went wrong.

0 comments on commit 9b6cc35

Please sign in to comment.