From be5b9e96ab2933766753a9788fc7467c837bb749 Mon Sep 17 00:00:00 2001 From: Joshua Seltzer Date: Sat, 16 Jan 2021 13:49:45 -0500 Subject: [PATCH 1/2] Updates to refine the POST command processing for PTZ which allows more recent ReoLink cameras to function within Shinobi. --- libs/control/ptz.js | 26 ++++++++++++++++++-------- libs/monitor.js | 14 ++++++++------ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/libs/control/ptz.js b/libs/control/ptz.js index 19977afa..5a34304b 100644 --- a/libs/control/ptz.js +++ b/libs/control/ptz.js @@ -217,13 +217,18 @@ module.exports = function(s,config,lang){ let stopURL = controlBaseUrl + monitorConfig.details[`control_url_${options.direction}_stop`] let controlOptions = s.cameraControlOptionsFromUrl(stopURL,monitorConfig) let requestOptions = { - url : stopURL, - method : controlOptions.method, - auth : { - user : controlOptions.username, - pass : controlOptions.password + url : controlBaseUrl + controlOptions.path, + method : controlOptions.method + } + if(controlOptions.username && controlOptions.password){ + requestOptions.auth = { + user: controlOptions.username, + pass: controlOptions.password } } + if(controlOptions.postData){ + requestOptions.form = controlOptions.postData + } if(monitorConfig.details.control_digest_auth === '1'){ requestOptions.sendImmediately = true } @@ -248,13 +253,18 @@ module.exports = function(s,config,lang){ let controlURL = controlBaseUrl + monitorConfig.details[`control_url_${options.direction}`] let controlOptions = s.cameraControlOptionsFromUrl(controlURL,monitorConfig) let requestOptions = { - url: controlURL, - method: controlOptions.method, - auth: { + url: controlBaseUrl + controlOptions.path, + method: controlOptions.method + } + if(controlOptions.username && controlOptions.password){ + requestOptions.auth = { user: controlOptions.username, pass: controlOptions.password } } + if(controlOptions.postData){ + requestOptions.form = controlOptions.postData + } if(monitorConfig.details.control_digest_auth === '1'){ requestOptions.sendImmediately = true } diff --git a/libs/monitor.js b/libs/monitor.js index 6799d217..edc1ade9 100644 --- a/libs/monitor.js +++ b/libs/monitor.js @@ -450,12 +450,14 @@ module.exports = function(s,config,lang){ options = { host: URLobject.hostname, port: URLobject.port, - method: monitorConfig.details.control_url_method, - path: URLobject.pathname, - query: queryStringToObject(URLobject.query || ""), - }; - if(URLobject.query){ - options.path=options.path+'?'+URLobject.query + method: monitorConfig.details.control_url_method + } + const queryStringObjects = queryStringToObject(URLobject.query || "") + if (queryStringObjects && queryStringObjects.postData) { + options.postData = decodeURIComponent(queryStringObjects.postData) + options.path = URLobject.pathname + '?' + decodeURIComponent(URLobject.query.replace(/&postData(\=[^&]*)?(?=&|$)|^postData(\=[^&]*)?(&|$)/, '')) + } else { + options.path = URLobject.pathname } if(URLobject.username&&URLobject.password){ options.username = URLobject.username From 49d1a1a1258b7d6277fff3966bf583960611e605 Mon Sep 17 00:00:00 2001 From: Moe Alam Date: Mon, 18 Jan 2021 08:03:14 -0800 Subject: [PATCH 2/2] rebuild query string without postData instead of search and replace --- libs/common.js | 10 ++++++++++ libs/monitor.js | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libs/common.js b/libs/common.js index 1f8740c8..a993e20c 100644 --- a/libs/common.js +++ b/libs/common.js @@ -63,4 +63,14 @@ module.exports = { }) return newObject }, + createQueryStringFromObject: (theObject) => { + const string = [] + const keys = Object.keys(theObject) + keys.forEach((key) => { + const value = theObject[key] + if(value)string.push(`${key}=${value}`) + }) + return string.join('&') + } + } diff --git a/libs/monitor.js b/libs/monitor.js index edc1ade9..eee6a8e9 100644 --- a/libs/monitor.js +++ b/libs/monitor.js @@ -10,7 +10,7 @@ const connectionTester = require('connection-tester') const SoundDetection = require('shinobi-sound-detection') const async = require("async"); const URL = require('url') -const { copyObject, createQueue, queryStringToObject } = require('./common.js') +const { copyObject, createQueue, queryStringToObject, createQueryStringFromObject } = require('./common.js') module.exports = function(s,config,lang){ const { probeMonitor, @@ -447,7 +447,7 @@ module.exports = function(s,config,lang){ }else if(!URLobject.port){ URLobject.port = 80 } - options = { + const options = { host: URLobject.hostname, port: URLobject.port, method: monitorConfig.details.control_url_method @@ -455,7 +455,7 @@ module.exports = function(s,config,lang){ const queryStringObjects = queryStringToObject(URLobject.query || "") if (queryStringObjects && queryStringObjects.postData) { options.postData = decodeURIComponent(queryStringObjects.postData) - options.path = URLobject.pathname + '?' + decodeURIComponent(URLobject.query.replace(/&postData(\=[^&]*)?(?=&|$)|^postData(\=[^&]*)?(&|$)/, '')) + options.path = URLobject.pathname + '?' + decodeURIComponent(createQueryStringFromObject(Object.assign(queryStringObjects,{postData: null}))) } else { options.path = URLobject.pathname }