"use strict"; import {XMPPService} from "../XMPPService"; import {getJsonFromXML, logEntryExit} from "../../common/Utils"; import {GenericHandler} from "./GenericHandler"; import {RESTService} from "../RESTService"; const xml = require("@xmpp/xml"); const packageVersion = require("../../../package"); const prettydata = require("../pretty-data").pd; const LOG_ID = "XMPP/HNDL/IQ/HTTPoverXMPP - "; @logEntryExit(LOG_ID) class HttpoverxmppEventHandler extends GenericHandler { public IQ_GET: any; public IQ_SET: any; public IQ_RESULT: any; public IQ_ERROR: any; private _rest: RESTService; options: any; /*public onIqGetReceived: any; public onIqResultReceived: any; public _onIqGetPingReceived: any; public _onIqGetQueryReceived: any; public _onIqGetPbxAgentStatusReceived: any; */ static getClassName(){ return 'HttpoverxmppEventHandler'; } getClassName(){ return HttpoverxmppEventHandler.getClassName(); } static getAccessorName(){ return 'httpoverxmppevent'; } getAccessorName(){ return HttpoverxmppEventHandler.getAccessorName(); } constructor(xmppService: XMPPService, restService: RESTService, options: any) { super( xmppService); let that = this; that._rest = restService; this.IQ_GET = "jabber:client.iq.get"; this.IQ_SET = "jabber:client.iq.set"; this.IQ_RESULT = "jabber:client.iq.result"; this.IQ_ERROR = "jabber:client.iq.error"; that.options = options; } onIqGetSetReceived (msg, stanzaTab) { let that = this; let stanza = stanzaTab[0]; let prettyStanza = stanzaTab[1]; let jsonStanza = stanzaTab[2]; try { that._logger.log(that.INTERNAL, LOG_ID + "(onIqGetSetReceived) _entering_ : ", msg, prettyStanza); let children = stanza.children; children.forEach((node) => { switch (node.getName()) { case "req": that._logger.log(that.INTERNAL, LOG_ID + "(onIqGetSetReceived) query : ", msg, stanza); that._onIqGetSetReqReceived(stanza, node); break; case "query": // treatement in iqEventHandler break; case "ping": // treatement in iqEventHandler break; case "events": // treatement in presenceEventHandler break; case "autoreply": // treatement in presenceEventHandler break; /*case "default": that._logger.log(that.INTERNAL, LOG_ID + "(onIqGetSetReceived) default : ", msg, stanza.root ? prettydata.xml(stanza.root().toString()) : stanza); that._logger.log(that.WARN, LOG_ID + "(onIqGetSetReceived) not managed - 'stanza'", node.getName()); break; // */ default: that._logger.log(that.INTERNAL, LOG_ID + "(onIqGetSetReceived) _entering_ : ", msg, prettyStanza); that._logger.log(that.WARN, LOG_ID + "(onIqGetSetReceived) child not managed for iq - 'stanza' name : ", node.getName()); that._logger.log(that.INTERNAL, LOG_ID + "(onIqGetSetReceived) child not managed for iq - 'stanza' name : ", node.getName(), ",stanza : ", "\n", prettyStanza, " node : ", node); } }); } catch (err) { // that._logger.log(that.ERROR, LOG_ID + "(onIqGetSetReceived) CATCH ErrorManager !!! "); that._logger.log(that.ERROR, LOG_ID + "(onIqGetSetReceived) CATCH ErrorManager !!! : ", err); } }; onIqResultReceived (msg, stanzaTab) { let that = this; let stanza = stanzaTab[0]; let prettyStanza = stanzaTab[1]; let jsonStanza = stanzaTab[2]; try { that._logger.log(that.INTERNAL, LOG_ID + "(onIqResultReceived) _entering_", msg, "\n", prettyStanza); let children = stanza.children; children.forEach((node) => { switch (node.getName()) { case "query": // The treatment is in iqEventHandler break; case "resp": that._logger.log(that.DEBUG, LOG_ID + "(onIqResultReceived) - 'stanza'", node.getName()); that._onIqRespResultReceived(stanza, node); break; case "bind": // The treatment is in iqEventHandler //that._logger.log(that.INFO, LOG_ID + "(onIqResultReceived) - 'stanza'", node.getName()); break; case "pbxagentstatus": // The treatment is in telephonyEventHandler //that._onIqGetPbxAgentStatusReceived(stanza, node); break; case "deleted": // One treatment is in calllogEventHandler break; /*case "default": that._logger.log(that.WARN, LOG_ID + "(onIqResultReceived) - not managed - 'stanza'", node.getName()); break; //*/ default: that._logger.log(that.WARN, LOG_ID + "(onIqResultReceived) - child not managed for iq - 'stanza'", node.getName()); that._logger.log(that.INTERNAL, LOG_ID + "(onIqResultReceived) - child not managed for iq - 'stanza' name : ", node.getName(), ", stanza : ", "\n", prettyStanza, " node : ", node); } }); } catch (err) { // that._logger.log(that.ERROR, LOG_ID + "(onIqResultReceived) CATCH ErrorManager !!! "); that._logger.log(that.ERROR, LOG_ID + "(onIqResultReceived) CATCH ErrorManager !!! : ", err); } }; async _onIqGetSetReqReceived(stanza, node) { let that = this; // treatment of the XEP 0332. try { if ( !that.options._httpoverxmppserver) { that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) httpoverxmppserver is desactivated, so send empty response to request : ", "\n", stanza.root ? prettydata.xml(stanza.root().toString()):stanza, "\n", node.root ? prettydata.xml(node.root().toString()):node); await that.xmppClient.resolvPendingRequest(stanza.attrs.id, {}); return (0); } that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) _entering_ : ", "\n", stanza.root ? prettydata.xml(stanza.root().toString()):stanza, "\n", node.root ? prettydata.xml(node.root().toString()):node); let xmlNodeStr = node ? node.toString():""; let reqObj = await getJsonFromXML(xmlNodeStr); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) reqObj : ", reqObj); let host = ""; let resourceUrl = ""; let method = ""; let headers = {}; if (reqObj && reqObj.req ) { if (reqObj.req.headers && reqObj.req.headers.header) { if (reqObj.req.headers.header.length===undefined) { if (reqObj.req.headers.header && reqObj.req.headers.header.$attrs.name==="Host") { host = reqObj.req.headers.header._; } } else { for (let i = 0; i < reqObj.req.headers.header.length; i++) { // Add headers from comming event to Http Headers. Not sure it is necessary for http GET method. if (reqObj.req.headers.header[i] && reqObj.req.headers.header[i].$attrs.name==="Host") { host = reqObj.req.headers.header[i]._; } else { headers[reqObj.req.headers.header[i].$attrs.name] = reqObj.req.headers.header[i]._; } } } } if (reqObj.req.$attrs) { resourceUrl = reqObj.req.$attrs.resource; method = reqObj.req.$attrs.method; } let urlBuilt = host + resourceUrl; let resultOfHttp = undefined; let statusCodeHttp = -1; let statusMessageHttp = ""; let headersHttp; switch (method) { case "GET": { let response = await that._rest.http.getUrlRaw(urlBuilt, headers, undefined); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) get url successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); if (response) { if (response.statusCode) { statusCodeHttp = response.statusCode; statusMessageHttp = response.statusMessage; headersHttp = response.headers; that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) get HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = response.body; } else { statusCodeHttp = -1; } } else { } } break; case "TRACE": { that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) trace successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); statusCodeHttp = 200; statusMessageHttp = "OK"; headersHttp = { 'Date': new Date().toLocaleDateString(), 'Server': "rainbowNodeSDK_" + packageVersion.version, 'Content-Type': "message/http", 'Content-Length': 100 } that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) trace HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = "GET " + resourceUrl + " HTTP/1.1 " + "Host: " + host; } break; case "HEAD": { let response = await that._rest.http.headUrlRaw(urlBuilt, headers); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) head url successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); if (response) { if (response.statusCode) { statusCodeHttp = response.statusCode; statusMessageHttp = response.statusMessage; headersHttp = response.headers; that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) head HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = response.body; } else { statusCodeHttp = -1; } } else { } } break; case "POST": { let data = undefined; if (reqObj && reqObj.req && reqObj.req.data && reqObj.req.data.text) { data = decodeURIComponent(reqObj.req.data.text); } let response = await that._rest.http.postUrlRaw(urlBuilt, headers, data); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) post url successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); if (response) { if (response.statusCode) { statusCodeHttp = response.statusCode; statusMessageHttp = response.statusMessage; headersHttp = response.headers; that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) post HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = response.body; } else { statusCodeHttp = -1; } } else { } } break; case "PUT": { let data = undefined; if (reqObj && reqObj.req && reqObj.req.data && reqObj.req.data.text) { data = decodeURIComponent(reqObj.req.data.text); } let response = await that._rest.http.putUrlRaw(urlBuilt, headers, data); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) put url successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); if (response) { if (response.statusCode) { statusCodeHttp = response.statusCode; statusMessageHttp = response.statusMessage; headersHttp = response.headers; that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) put HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = response.body; } else { statusCodeHttp = -1; } } else { } } break; case "DELETE": { let data = undefined; if (reqObj && reqObj.req && reqObj.req.data && reqObj.req.data.text) { data = decodeURIComponent(reqObj.req.data.text); } let response = await that._rest.http.deleteUrlRaw(urlBuilt, headers, data); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) delete url successfull"); //that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetSetReqReceived) get url HTTP result : ", response); if (response) { if (response.statusCode) { statusCodeHttp = response.statusCode; statusMessageHttp = response.statusMessage; headersHttp = response.headers; that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) delete HTTP statusCode defined, statusCodeHttp: ", statusCodeHttp, ", statusMessageHttp : ", statusMessageHttp); resultOfHttp = response.body; } else { statusCodeHttp = -1; } } else { } } break; default: { } } that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) (handleXMPPConnection) urlBuilt : ", urlBuilt); let stanzaResp = xml("resp", { "xmlns": "urn:xmpp:http", "version": "1.1", "statusCode": statusCodeHttp, "statusMessage": statusMessageHttp }) let stanzaHeaders = xml("headers", { "xmlns" : 'http://jabber.org/protocol/shim'}, undefined); for (const methodKey in headersHttp) { let stanzaHeader1 = xml("header", {"name": methodKey}, headersHttp[methodKey]); stanzaHeaders.append(stanzaHeader1, undefined); } let encodedData = encodeURIComponent(resultOfHttp); let stanzaText = xml("text", {}, encodedData); let stanzaData = xml("data",{}, undefined); stanzaResp.append(stanzaHeaders, undefined); stanzaData.append(stanzaText, undefined); stanzaResp.append(stanzaData, undefined); that._logger.log(that.DEBUG, LOG_ID + "(_onIqGetSetReqReceived) (handleXMPPConnection) send req result - 'stanza' : ", stanzaResp); await that.xmppClient.resolvPendingRequest(stanza.attrs.id, stanzaResp); } else { await that.xmppClient.resolvPendingRequest(stanza.attrs.id, {}); } } catch (err) { // that._logger.log(that.ERROR, LOG_ID + "(_onIqGetSetReqReceived) (handleXMPPConnection) CATCH ErrorManager !!! "); that._logger.log(that.ERROR, LOG_ID + "(_onIqGetSetReqReceived) (handleXMPPConnection) CATCH ErrorManager !!! : ", err); } }; async _onIqRespResultReceived(stanza, node) { let that = this; /*
Fri, 03 May 2013 16:39:54GMT-4
Clayster
text/turtle
...
Close
@prefix dc: <http://purl.org/dc/elements/1.1/>. @base <http://example.org/>. <xep> dc:title "HTTP over XMPP"; dc:creator <PeterWaher>; dc:publisher <XSF>.
*/ try { that._logger.log(that.INTERNAL, LOG_ID + "(_onIqRespResultReceived) _entering_ : ", "\n", stanza.root ? prettydata.xml(stanza.root().toString()):stanza, "\n", node.root ? prettydata.xml(node.root().toString()):node); /* let xmlNodeStr = node ? node.toString():""; let reqObj = await getJsonFromXML(xmlNodeStr); that._logger.log(that.INTERNAL, LOG_ID + "(_onIqGetReqReceived) (handleXMPPConnection) reqObj : ", reqObj); let version = reqObj["resp"]["$attrs"].version; let statusCode = reqObj["resp"]["$attrs"].statusCode; let statusMessage = reqObj["resp"]["$attrs"].statusMessage; // */ } catch (err) { // that._logger.log(that.ERROR, LOG_ID + "(_onIqRespResultReceived) (handleXMPPConnection) CATCH ErrorManager !!! "); that._logger.log(that.ERROR, LOG_ID + "(_onIqRespResultReceived) (handleXMPPConnection) CATCH ErrorManager !!! : ", err); } } } module.exports.HttpoverxmppEventHandler = HttpoverxmppEventHandler; export {HttpoverxmppEventHandler};