You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.2 KiB

4 years ago
  1. 'use strict';
  2. var inherits = require('inherits')
  3. , iframeUtils = require('../../utils/iframe')
  4. , urlUtils = require('../../utils/url')
  5. , EventEmitter = require('events').EventEmitter
  6. , random = require('../../utils/random')
  7. ;
  8. var debug = function() {};
  9. if (process.env.NODE_ENV !== 'production') {
  10. debug = require('debug')('sockjs-client:receiver:htmlfile');
  11. }
  12. function HtmlfileReceiver(url) {
  13. debug(url);
  14. EventEmitter.call(this);
  15. var self = this;
  16. iframeUtils.polluteGlobalNamespace();
  17. this.id = 'a' + random.string(6);
  18. url = urlUtils.addQuery(url, 'c=' + decodeURIComponent(iframeUtils.WPrefix + '.' + this.id));
  19. debug('using htmlfile', HtmlfileReceiver.htmlfileEnabled);
  20. var constructFunc = HtmlfileReceiver.htmlfileEnabled ?
  21. iframeUtils.createHtmlfile : iframeUtils.createIframe;
  22. global[iframeUtils.WPrefix][this.id] = {
  23. start: function() {
  24. debug('start');
  25. self.iframeObj.loaded();
  26. }
  27. , message: function(data) {
  28. debug('message', data);
  29. self.emit('message', data);
  30. }
  31. , stop: function() {
  32. debug('stop');
  33. self._cleanup();
  34. self._close('network');
  35. }
  36. };
  37. this.iframeObj = constructFunc(url, function() {
  38. debug('callback');
  39. self._cleanup();
  40. self._close('permanent');
  41. });
  42. }
  43. inherits(HtmlfileReceiver, EventEmitter);
  44. HtmlfileReceiver.prototype.abort = function() {
  45. debug('abort');
  46. this._cleanup();
  47. this._close('user');
  48. };
  49. HtmlfileReceiver.prototype._cleanup = function() {
  50. debug('_cleanup');
  51. if (this.iframeObj) {
  52. this.iframeObj.cleanup();
  53. this.iframeObj = null;
  54. }
  55. delete global[iframeUtils.WPrefix][this.id];
  56. };
  57. HtmlfileReceiver.prototype._close = function(reason) {
  58. debug('_close', reason);
  59. this.emit('close', null, reason);
  60. this.removeAllListeners();
  61. };
  62. HtmlfileReceiver.htmlfileEnabled = false;
  63. // obfuscate to avoid firewalls
  64. var axo = ['Active'].concat('Object').join('X');
  65. if (axo in global) {
  66. try {
  67. HtmlfileReceiver.htmlfileEnabled = !!new global[axo]('htmlfile');
  68. } catch (x) {
  69. // intentionally empty
  70. }
  71. }
  72. HtmlfileReceiver.enabled = HtmlfileReceiver.htmlfileEnabled || iframeUtils.iframeEnabled;
  73. module.exports = HtmlfileReceiver;