Skip to content

Commit

Permalink
Support usecurl flag on HTTP request action
Browse files Browse the repository at this point in the history
  • Loading branch information
toggledbits committed Nov 10, 2022
1 parent f018d25 commit 140e215
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 45 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ NOTE TO ALTUI USERS: All current versions of Reactor REQUIRE AltUI 2536 to 2553;

**DEPRECATION NOTICE:** The `Reactor.groups` table is now deprecated; use `Reactor.conditions` instead (just change the name in your code, it works the same). See [the Reactor documentation](https://www.toggledbits.com/static/reactor/docs/Run-Lua-Action/) for more information.

## Version 3.11 (22308)
## Version 3.11 (22314)

* HTTP Request action: handle SSL/TLS negotation failure, returns nil httpStatus.
* HTTP Request action: Add "Use curl" checkbox to use curl command instead of the aging Lua http/https libraries; this may resolve issues some users will have connecting to some servers caused by the Lua libraries being unable to negotiate newer ciphers.

## Version 3.10 (22145)

Expand Down
4 changes: 2 additions & 2 deletions J_ReactorSensor_ALTUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

var ReactorSensor_ALTUI = ( function( window, undefined ) {

var pluginVersion = "3.10 (22145)";
var pluginVersion = "3.11 (22314)";

var _UIVERSION = 21170;
var _UIVERSION = 22314;

function _getStyle() {
var style = "button.reactor-cpb { padding: .25rem .5rem; min-width: 4rem; }";
Expand Down
57 changes: 36 additions & 21 deletions J_ReactorSensor_UI7.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ var ReactorSensor = (function(api, $) {
/* unique identifier for this plugin... */
var uuid = '21b5725a-6dcd-11e8-8342-74d4351650de';

var pluginVersion = "3.10 (22145)";
var pluginVersion = "3.11 (22314)";

var _UIVERSION = 21170; /* must coincide with Lua core */
var _UIVERSION = 22314; /* must coincide with Lua core */

var _CDATAVERSION = 20045; /* must coincide with Lua core */

Expand Down Expand Up @@ -2018,6 +2018,7 @@ div#reactorstatus div.cond.re-cond-error { border: 3px solid red; } \
div#reactorstatus div.cond.reactor-timing { animation: pulse 2s infinite; } \
@keyframes pulse { 0% { background-color: #fff; } 50% { background-color: #cfc; } 100% { background-color: #fff; } } \
div.re-updatestatus { margin: 8px 0; padding: 8px 8px; border: 3px solid #0c0; border-radius: 8px; font-weight: bold; text-align: center; } \
div.re-msr { margin: 8px 0; padding: 8px 8px; border: 3px solid #0c0; border-radius: 8px; font-weight: bold; text-align: center; } \
</style>');
}

Expand All @@ -2027,6 +2028,9 @@ div.re-updatestatus { margin: 8px 0; padding: 8px 8px; border: 3px solid #0c0; b
captureControlPanelClose( $('div#reactorstatus') );

try {
$( `<div class="re-msr">If you are considering moving to Home Assistant or Hubitat, check out my <a href="https://reactor.toggledbits.com/docs/" target="_blank">Multi-Hub Reactor</a> project. It's an evolution of Reactor for Vera that supports multiple home automation hubs including Vera, to ease your transition between them -- take your time moving devices from one platform to another, rather than trying to do a "fork lift upgrade" of your entire home automation system and devices at once. It also works with MQTT, giving you accecss to its universe of supported devices and integrations, including a ton of inexpensive WiFi devices. And yes, it even supports Ezlo hubs, too.</div>` )
.insertBefore( $( 'div#reactorstatus' ) );

updateStatus( myid );

checkUpdate().then( function( data ) {
Expand Down Expand Up @@ -6032,6 +6036,11 @@ div#tab-vars.reactortab button.md-btn.attn { background-color: #ff8; background-
} else {
action.data = t;
}
if ( $( 'input#' + idSelector( pfx + 'usecurl' ), row ).prop( "checked" ) ) {
action.usecurl = 1;
} else {
delete action.usecurl;
}
break;

default:
Expand Down Expand Up @@ -6213,24 +6222,24 @@ div#tab-vars.reactortab button.md-btn.attn { background-color: #ff8; background-
} else {
xf = $( '<input class="form-control form-control-sm">' )
.attr( 'placeholder', fld.placeholder || "" );
if ( Array.isArray( fld.datalist ) ) {
// if ( undefined !== window.HTMLDataListElement ) {
var dlid = 'notify-' + method + '-' + fld.id;
var $dl = $( 'datalist#' + idSelector( dlid ) );
if ( 0 === $dl.length ) {
/* build datalist */
var $ct = $( 'div#re-activities' );
$dl = $( '<datalist></datalist>' ).attr( 'id', dlid ).appendTo( $ct );
fld.datalist.forEach( function( v ) {
var pm = v.match( "^([^=]*)=(.*)$" );
if ( pm ) {
$( '<option></option>' ).val( pm[1] ).text( pm[2] )
.appendTo( $dl );
}
});
}
xf.attr( 'list', dlid );
}
if ( Array.isArray( fld.datalist ) ) {
// if ( undefined !== window.HTMLDataListElement ) {
var dlid = 'notify-' + method + '-' + fld.id;
var $dl = $( 'datalist#' + idSelector( dlid ) );
if ( 0 === $dl.length ) {
/* build datalist */
var $ct = $( 'div#re-activities' );
$dl = $( '<datalist></datalist>' ).attr( 'id', dlid ).appendTo( $ct );
fld.datalist.forEach( function( v ) {
var pm = v.match( "^([^=]*)=(.*)$" );
if ( pm ) {
$( '<option></option>' ).val( pm[1] ).text( pm[2] )
.appendTo( $dl );
}
});
}
xf.attr( 'list', dlid );
}
}
if ( ! isEmpty( fld.default ) ) {
xf.val( fld.default );
Expand Down Expand Up @@ -7291,7 +7300,12 @@ div#tab-vars.reactortab button.md-btn.attn { background-color: #ff8; background-
}
$m.appendTo( $lb );

$('<div></div>').html("Substitutions are available in all request fields using <tt>{expr}</tt> syntax.")
$fs = $( '<div></div>' ).appendTo( ct );
getCheckbox( pfx + 'usecurl', 1, "Use \"curl\" instead of Lua http/https libraries" )
.on( 'change.reactor', handleActionValueChange )
.appendTo( $fs );

$('<div></div>').html("Substitutions are available in all request fields using <tt>{expr}</tt> syntax. Using <tt>curl</tt> instead of the aging Lua libraries in the Vera firmware may resolves some SSL/TLS connection issues.")
.appendTo( ct );
break;

Expand Down Expand Up @@ -7823,6 +7837,7 @@ div#tab-vars.reactortab button.md-btn.attn { background-color: #ff8; background-
.appendTo( $( 'select.re-reqtarget', newRow ) );
}
$( 'select.re-reqtarget', newRow ).val( act.target || "" );
$( 'input#' + idSelector( rid + '-usecurl' ), newRow ).prop( "checked", !!act.usecurl );
break;

default:
Expand Down
4 changes: 2 additions & 2 deletions J_Reactor_UI7.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ var Reactor = (function(api, $) {
/* unique identifier for this plugin... */
var uuid = '72acc6ea-f24d-11e8-bd87-74d4351650de';

var pluginVersion = "3.10 (22145)";
var pluginVersion = "3.11 (22314)";

var _UIVERSION = 21170; /* must coincide with Lua core */
var _UIVERSION = 22314; /* must coincide with Lua core */

var _DOCURL = "https://www.toggledbits.com/static/reactor/docs/3.9/";
var _FORUMURL = "https://community.getvera.com/c/plugins-and-plugin-development/reactor/178";
Expand Down
60 changes: 41 additions & 19 deletions L_Reactor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ local debugMode = false

local _PLUGIN_ID = 9086
local _PLUGIN_NAME = "Reactor"
local _PLUGIN_VERSION = "3.11 (22308)"
local _PLUGIN_VERSION = "3.11 (22314)"
local _PLUGIN_URL = "https://www.toggledbits.com/reactor"
local _DOC_URL = "https://www.toggledbits.com/static/reactor/docs/3.9/"
local _FORUM_URL = "https://community.getvera.com/c/plugins-and-plugin-development/reactor/178"

local _CONFIGVERSION = 22145
local _CDATAVERSION = 20045 -- must coincide with JS
local _UIVERSION = 21170 -- must coincide with JS
local _UIVERSION = 22314 -- must coincide with JS
_SVCVERSION = 20185 -- must coincide with impl file (not local)

local MYSID = "urn:toggledbits-com:serviceId:Reactor"
Expand Down Expand Up @@ -1000,6 +1000,11 @@ local function sensor_runOnce( tdev )
setVar( RSSID, "WatchResponseHoldOff", "", tdev )
end

if s < 22314 then
setVar( RSSID, "RequestActionUseCurl", "0", tdev )
setVar( RSSID, "RequestActionCurlOptions", "", tdev )
end

-- Update version last.
if s < _CONFIGVERSION then
luup.variable_set(RSSID, "Version", _CONFIGVERSION, tdev)
Expand Down Expand Up @@ -2736,42 +2741,57 @@ local function doActionRequest( action, scid, tdev )
local vv = getValue( ref, nil, tdev )
return ( vv ~= nil ) and vv or ref
end )
tHeaders[key] = val
tHeaders[string.lower(key)] = val
end
end

local src
local body = tostring( action.data )
if body:gsub( '[\r\n\t]+', ' ' ):match( '^ *{ *"[^"]+" *: *' ) then
-- Looks like a JSON string, which unfortunately has a similar pattern to our
-- substitutions, so just take it as JSON with not substitutions.
L( "Detected JSON data in request body; not performing inline substitutions" )
else
body = body:gsub( "%{[^}]+%}", function( ref )
local vv = getValue( ref, nil, tdev )
return ( vv ~= nil ) and vv or ref
end )
end
if body == "" then
src = nil
else
local body = tostring( action.data or "" )
if "GET" ~= method then
if "application/json" == tHeaders['content-type'] then
-- Looks like a JSON string, which unfortunately has a similar pattern to our
-- substitutions, so just take it as JSON with no substitutions.
L( "Detected JSON data in request body; not performing inline substitutions" )
addEvent{ dev=tdev, msg="Detected JSON data in request body; not performing inline substitutions." }
else
body = body:gsub( "%{[^}]+%}", function( ref )
local vv = getValue( ref, nil, tdev )
return ( vv ~= nil ) and vv or ref
end )
end
src = ltn12.source.string( body )
tHeaders["Content-Length"] = string.len( body )
tHeaders["content-length"] = string.len( body )
D("doActionRequest() body is %1", body)
else
src = nil
end

local respBody
local r = {}
if action.usecurl or getVarBool( "RequestActionUseCurl", false, tdev, RSSID ) then
local req = string.format( "curl -s -m %d -o -", timeout )
if "GET" ~= method then
req = req .. " -X " .. method
end
if getVarBool( "RequestActionFollowRedirects", false, tdev, RSSID ) then
req = req .. " -L"
end
for k,v in pairs( tHeaders or {} ) do
req = req .. " -H '" .. k .. ": " .. v:gsub( "'", "''" ) .. "'"
if ( "content-length" ~= k ) then
req = req .. " -H '" .. k .. ": " .. string.gsub( v, "'", "''" ) .. "'"
end
end
local s = action.curlopts or luup.variable_get( RSSID, "RequestCurlOptions", tdev ) or ""
if s ~= "" then req = req .. " " .. s end
if "" ~= body then
-- To avoid quoting and length issues, write the body to temp file
local tf = os.tmpname()
local f = io.open( tf, "w" )
f:write( body )
f:close()
req = req .. " -d '@" .. tf .. "'"
D("doActionRequest() body written to temporary file %1", tf)
end
req = req .. " '" .. url .. "'"
L("%1 (#%2) request action: %3", luup.devices[tdev].description, tdev, req)
addEvent{ dev=tdev, msg="Request via curl: %(req)s", req=req }
Expand All @@ -2783,6 +2803,8 @@ local function doActionRequest( action, scid, tdev )
if chunk then
count = count + #chunk
table.insert( r, chunk )
else
break
end
until count >= maxResp
f:close()
Expand Down

0 comments on commit 140e215

Please sign in to comment.