Add command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>``

Add command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests (#13209)
This commit is contained in:
Theo Arends 2021-09-24 11:34:44 +02:00
parent 883a9fb12c
commit 7c71c3bdd8
4 changed files with 77 additions and 12 deletions

View File

@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
- Berry support for Serial
- Support for Sensirion SCD40/SCD41 CO2 sensor (#13139)
- Support for BL0939 energy monitor as used in ESP32 based Sonoff Dual R3 V2 Pow (#13195)
- Command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests (#13209)
### Changed
- M5 Stack Core2 uses UNIVERSAL_DISPLAY with enabled LVGL as default now

View File

@ -107,6 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``SetSensor1..127 0|1`` to globally disable individual sensor driver
- Command ``Subscribe2 ...`` to subscribe to a MQTT topic without appended "/#" [#12858](https://github.com/arendst/Tasmota/issues/12858)
- Command ``WebGetConfig <url>`` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver [#13034](https://github.com/arendst/Tasmota/issues/13034)
- Command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests [#13209](https://github.com/arendst/Tasmota/issues/13209)
- Optional IP filter to command ``TCPStart`` [#12806](https://github.com/arendst/Tasmota/issues/12806)
- Neopool commands ``NPPHRes``, ``NPCLRes`` and ``NPIonRes`` [#12813](https://github.com/arendst/Tasmota/issues/12813)
- Support for second DNS server

View File

@ -415,6 +415,7 @@
#define D_CMND_WEBLOG "WebLog"
#define D_CMND_WEBREFRESH "WebRefresh"
#define D_CMND_WEBSEND "WebSend"
#define D_CMND_WEBQUERY "WebQuery"
#define D_CMND_WEBCOLOR "WebColor"
#define D_CMND_WEBBUTTON "WebButton"
#define D_CMND_WEBSENSOR "WebSensor"

View File

@ -3098,14 +3098,67 @@ int WebSend(char *buffer)
}
url += F("cmnd="); // url = |http://192.168.178.86/cm?cmnd=| or |http://192.168.178.86/cm?user=admin&password=joker&cmnd=|
}
url += command; // url = |http://192.168.178.86/cm?cmnd=POWER1 ON|
url += UrlEncode(command); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
url += F(" GET"); // url = |http://192.168.178.86/cm?cmnd=POWER1%20ON GET|
DEBUG_CORE_LOG(PSTR("WEB: Uri |%s|"), url.c_str());
DEBUG_CORE_LOG(PSTR("WEB: Uri '%s'"), url.c_str());
status = WebQuery(const_cast<char*>(url.c_str()));
}
return status;
}
int WebQuery(char *buffer)
{
// http://192.168.1.1/path GET -> Sends HTTP GET http://192.168.1.1/path
// http://192.168.1.1/path POST {"some":"message"} -> Sends HTTP POST to http://192.168.1.1/path with body {"some":"message"}
// http://192.168.1.1/path PUT [Autorization: Bearer abcdxyz] potato -> Sends HTTP PUT to http://192.168.1.1/path with authorization header and body "potato"
// http://192.168.1.1/path PATCH patchInfo -> Sends HTTP PATCH to http://192.168.1.1/path with body "potato"
// Valid HTTP Commands: GET, POST, PUT, and PATCH
// An unlimited number of headers can be sent per request, and a body can be sent for all command types
// The body will be ignored if sending a GET command
WiFiClient http_client;
HTTPClient http;
int status = WEBCMND_WRONG_PARAMETERS;
char *temp;
char *url = strtok_r(buffer, " ", &temp);
char *method = strtok_r(temp, " ", &temp);
if (url && method) {
if (http.begin(http_client, UrlEncode(url))) {
char empty_body[1] = { 0 };
char *body = empty_body;
if (temp) { // There is a body and/or header
if (temp[0] == '[') { // Header information was sent; decode it
temp += 1;
temp = strtok_r(temp, "]", &body);
bool headerFound = true;
while (headerFound) {
char *header = strtok_r(temp, ":", &temp);
if (header) {
char *headerBody = strtok_r(temp, "|", &temp);
if (headerBody) {
http.addHeader(header, headerBody);
}
else headerFound = false;
}
else headerFound = false;
}
} else { // No header information was sent, but there was a body
body = temp;
}
}
int http_code;
if (0 == strcasecmp_P(method, PSTR("GET"))) { http_code = http.GET(); }
else if (0 == strcasecmp_P(method, PSTR("POST"))) { http_code = http.POST(body); }
else if (0 == strcasecmp_P(method, PSTR("PUT"))) { http_code = http.PUT(body); }
else if (0 == strcasecmp_P(method, PSTR("PATCH"))) { http_code = http.PATCH(body); }
else return status;
WiFiClient http_client;
HTTPClient http;
if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
int http_code = http.GET(); // Start connection and send HTTP header
if (http_code > 0) { // http_code will be negative on error
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
#ifdef USE_WEBSEND_RESPONSE
@ -3125,7 +3178,7 @@ int WebSend(char *buffer)
// recursive call must be possible in this case
tasm_cmd_activ = 0;
#endif // USE_SCRIPT
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WEBSEND));
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WEBQUERY));
#endif // USE_WEBSEND_RESPONSE
}
status = WEBCMND_DONE;
@ -3240,8 +3293,8 @@ const char kWebCommands[] PROGMEM = "|" // No prefix
#if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL)
D_CMND_SENDMAIL "|"
#endif
D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_WEBCOLOR "|"
D_CMND_WEBSENSOR "|" D_CMND_WEBBUTTON
D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_WEBQUERY "|"
D_CMND_WEBCOLOR "|" D_CMND_WEBSENSOR "|" D_CMND_WEBBUTTON
#ifdef USE_WEBGETCONFIG
"|" D_CMND_WEBGETCONFIG
#endif
@ -3257,8 +3310,8 @@ void (* const WebCommand[])(void) PROGMEM = {
#if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL)
&CmndSendmail,
#endif
&CmndWebServer, &CmndWebPassword, &CmndWeblog, &CmndWebRefresh, &CmndWebSend, &CmndWebColor,
&CmndWebSensor, &CmndWebButton
&CmndWebServer, &CmndWebPassword, &CmndWeblog, &CmndWebRefresh, &CmndWebSend, &CmndWebQuery,
&CmndWebColor, &CmndWebSensor, &CmndWebButton
#ifdef USE_WEBGETCONFIG
, &CmndWebGetConfig
#endif
@ -3359,6 +3412,15 @@ void CmndWebSend(void)
}
}
void CmndWebQuery(void)
{
if (XdrvMailbox.data_len > 0) {
uint32_t result = WebQuery(XdrvMailbox.data);
char stemp1[20];
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus));
}
}
#ifdef USE_WEBGETCONFIG
void CmndWebGetConfig(void)
{
@ -3519,4 +3581,4 @@ bool Xdrv01(uint8_t function)
}
return result;
}
#endif // USE_WEBSERVER
#endif // USE_WEBSERVER