Skip to content

Commit

Permalink
Add command WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>
Browse files Browse the repository at this point in the history
Add command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests (#13209)
  • Loading branch information
arendst committed Sep 24, 2021
1 parent 883a9fb commit 7c71c3b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions tasmota/i18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
86 changes: 74 additions & 12 deletions tasmota/xdrv_01_webserver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -3519,4 +3581,4 @@ bool Xdrv01(uint8_t function)
}
return result;
}
#endif // USE_WEBSERVER
#endif // USE_WEBSERVER

0 comments on commit 7c71c3b

Please sign in to comment.