UNPKG

onvif

Version:

Client to ONVIF NVT devices Profile S: cameras

128 lines (119 loc) 3.14 kB
/** * @namespace utils * @description Common utils module * @author Andrew D.Laptev <a.d.laptev@gmail.com> * @licence MIT */ const xml2js = require('xml2js'), numberRE = /^-?([1-9]\d*|0)(\.\d*)?$/, dateRE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d+)?Z$/, prefixMatch = /(?!xmlns)^.*:/; /** * Parse SOAP object to pretty JS-object * @param {object} xml * @returns {object} */ const linerase = function(xml) { if (Array.isArray(xml)) { if (xml.length > 1) { return xml.map(linerase); } else { xml = xml[0]; } } if (typeof xml === 'object') { var obj = {}; Object.keys(xml).forEach(function(key) { obj[key] = linerase(xml[key]); }); return obj; } else { if (xml === 'true') { return true; } if (xml === 'false') { return false; } if (numberRE.test(xml)) { return parseFloat(xml); } if (dateRE.test(xml)) { return new Date(xml); } return xml; } }; /** * @callback ParseSOAPStringCallback * @property {?Error} error * @property {object} SOAP response * @property {string} raw XML * @property {number} HTTP Status Code */ /** * Parse SOAP response * @param {string} xml * @param {ParseSOAPStringCallback} callback * @param {number} statusCode. This is passed in so it can be passed back out to the callback */ const parseSOAPString = function(xml, callback, statusCode) { /* Filter out xml name spaces */ xml = xml.replace(/xmlns([^=]*?)=(".*?")/g, ''); try { xml2js.parseString( xml, { tagNameProcessors: [function(str) { str = str.replace(prefixMatch, ''); var secondLetter = str.charAt(1); if (secondLetter && secondLetter.toUpperCase() !== secondLetter) { return str.charAt(0).toLowerCase() + str.slice(1); } else { return str; } }] }, function(err, result) { if (!result || !result['envelope'] || !result['envelope']['body']) { callback(new Error('Wrong ONVIF SOAP response'), null, xml, statusCode); } else { if (!err && result['envelope']['body'][0]['fault']) { var fault = result['envelope']['body'][0]['fault'][0]; var reason; try { if (fault.reason[0].text[0]._) { reason = fault.reason[0].text[0]._; } } catch (e) { reason = ''; } if (!reason) { try { reason = JSON.stringify(linerase(fault.code[0])); } catch (e) { reason = ''; } } var detail = ''; try { detail = fault.detail[0].text[0]; } catch (e) { detail = ''; } // console.error('Fault:', reason, detail); err = new Error('ONVIF SOAP Fault: ' + (reason) + (detail)); } callback(err, result['envelope']['body'], xml, statusCode); } } ); } catch (err) { callback(err, '', xml, statusCode); } }; const s4 = function() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); }; /** * Generate GUID * @returns {string} */ const guid = function() { return (s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4()); }; module.exports = { linerase: linerase, parseSOAPString: parseSOAPString, guid: guid };