1 var http = require('http'); 2 var OpalRequest = require('./OpalRequest.js').OpalRequest; 3 var Event = require('../../../lib/core/event/Event.js').Event; 4 var ErrorEvent = require('../../../lib/core/event/ErrorEvent.js').ErrorEvent; 5 var EventDispatcher = require('../../../lib/core/event/EventDispatcher.js').EventDispatcher; 6 var Class = require('../../../lib/mootools/mootools-node.js').Class; 7 8 /** 9 * @class OpalLoader 10 * @extends EventDispatcher 11 * @requires Class 12 * @requires OpalRequest 13 * @requires Event 14 * @requires ErrorEvent 15 * @requires EventDispatcher 16 * @requires http 17 * 18 * @param {OpalRequest} request 19 */ 20 var OpalLoader = function(){ 21 22 /** @ignore */ 23 this.Extends = EventDispatcher; 24 25 26 /** 27 * @property {Object} data 28 */ 29 this.data = {}; 30 31 /** 32 * @private 33 * @property {Object} _chunks 34 */ 35 this._chunks = []; 36 37 /** 38 * @private 39 * @property {Object} _request 40 */ 41 this._request = null; 42 43 /** 44 * @private 45 * @property {Number} _timeout 46 */ 47 this._timeout = 15000; 48 49 /** 50 * @private 51 * @property {Object} _timer 52 */ 53 this._timer = null; 54 55 56 /** @ignore */ 57 this.initialize = function(request){ 58 this.setRequest(request); 59 }; 60 61 /** 62 * callback responsible for gathering response chunks 63 * @private 64 * @param {Server.HttpResponse} response 65 */ 66 this._response = function(response){ 67 var self = this; 68 69 if(response.statusCode !== 200){ 70 this._clearTimer(); 71 var event = new ErrorEvent(OpalLoader.ERROR, response.statusCode, -2, 'Wrong HTTP status code'); 72 this.dispatchEvent(event); 73 return; 74 } 75 76 response.setEncoding('utf8'); 77 response.addListener('data', function(chunk){ 78 self._chunks.push(chunk); 79 }).addListener('end', function(){ 80 self._onEnd(); 81 }); 82 }; 83 84 /** 85 * sets timer who is responsible for timeout detection 86 * @private 87 * @param {Server.HttpRequest} request 88 */ 89 this._setTimer = function(request){ 90 var self = this; 91 this._timer = setTimeout(function(){ 92 request.removeAllListeners('response'); 93 self.dispatchEvent(new ErrorEvent(OpalLoader.ERROR, null, -4, 'Http response timeout')); 94 }, this.getTimeout()); 95 }; 96 97 /** 98 * clears timer handle that is responsible for timeout detection 99 * @private 100 */ 101 this._clearTimer = function(){ 102 clearTimeout(this._timer); 103 }; 104 105 /** 106 * called on request end, when whole data is retreived from server 107 * @private 108 */ 109 this._onEnd = function(){ 110 this._clearTimer(); 111 112 try { 113 this._data = JSON.parse(this._chunks.join('')); 114 } catch(err) { 115 this.dispatchEvent(new ErrorEvent(OpalLoader.ERROR, {json: this._chunks.join(''), error: err.message}, -3, 'JSON parse error')); 116 return; 117 } 118 119 if(this._data.hasOwnProperty('error')) { 120 this.dispatchEvent(new ErrorEvent(OpalLoader.ERROR, null, this._data.error.code, this._data.error.message)); 121 return; 122 } 123 124 this.dispatchEvent(new Event(OpalLoader.LOADED, this._data.result)); 125 }; 126 127 128 /** 129 * sets timeout in miliseconds 130 * @param {Number} ms 131 */ 132 this.setTimeout = function(ms){ 133 this._timeout = ms; 134 return this; 135 }; 136 137 /** 138 * gets timeout in miliseconds 139 * @returns {Number} 140 */ 141 this.getTimeout = function(){ 142 return this._timeout; 143 }; 144 145 /** 146 * sets request object to process 147 * @param {OpalRequest} request 148 */ 149 this.setRequest = function(request){ 150 if(request && !(request instanceof OpalRequest)){ 151 throw 'Given request is not a instance of OpalRequest'; 152 } else if(request) { 153 this._request = request; 154 } 155 }; 156 157 /** 158 * makes request to the backend system based on the request object 159 * @param {OpalRequest} request 160 */ 161 this.load = function(request){ 162 this.setRequest(request); 163 164 if(this._request == null){ 165 throw new Error('Request has not been set'); 166 } 167 168 var self = this; 169 170 var request = http.request({ 171 host: this._request.getGatewayHost(), 172 port: this._request.getGatewayPort(), 173 path: this._request.getUrl(), 174 method: this._request.getMethod(), 175 headers: this._request.getHeaders() 176 }, function(response){ 177 self._response(response); 178 }).addListener('error', function(e){ 179 self._clearTimer(); 180 self.dispatchEvent(new ErrorEvent(OpalLoader.ERROR, e, -1, 'Http request error')); 181 }); 182 183 request.write(this._request.getData()); 184 request.end(); 185 186 this._setTimer(request); 187 }; 188 }; 189 190 OpalLoader = new Class(new OpalLoader()); 191 OpalLoader.LOADED = "OpalLoader_LOADED"; 192 OpalLoader.ERROR = "OpalLoaded_ERROR"; 193 exports.OpalLoader = OpalLoader;