How to parse query URLs using ESP-IDF webserver on ESP32
This utility class allows you to easily parse query URLs. In order to use it, you must add -std=gnu++17
or later to your compiler flags.
class QueryURLParser {
public:
QueryURLParser(httpd_req_t *req) {
size_t queryURLLen = httpd_req_get_url_query_len(req) + 1;
if(queryURLLen > 1) {
// Allocate temporary buffer to store the parameter
char buf[queryURLLen] = {0};
if (httpd_req_get_url_query_str(req, buf, queryURLLen) != ESP_OK) {
ESP_LOGE("Query URL parser", "Failed to extract query URL");
// Set string to empty string => "not found"
this->queryURLString = "";
} else {
// Copy into a std::string
this->queryURLString = std::string(buf, queryURLLen);
}
delete[] buf;
}
}
std::string GetParameter(const char* key) {
// Allocate enough space to store the parameter.
// NOTE: The parameter can only be as long as the query URL itself.
// Therefore, allocating "too much" space upfront will
// avoid unneccessary copying
size_t bufSize = queryURLString.size();
char* buf = (char*)malloc(bufSize);
/* Get value of expected key from query string */
esp_err_t err = httpd_query_key_value(queryURLString.c_str(), key, buf, bufSize);
if(err != ESP_OK) {
ESP_LOGE("Query URL parser", "parsing URL");
Serial.println(esp_err_to_name(err));
free(buf);
return "";
}
// Convert to std::string
std::string param(buf);
free(buf);
// Shrink param so it fits.
return param;
}
private:
std::string queryURLString;
};
Usage example:
static const httpd_uri_t setMQTTURLHandler = {
.uri = "/api/set-mqtt-url",
.method = HTTP_GET,
.handler = [](httpd_req_t *req) {
QueryURLParser parser(req);
std::string url = parser.GetParameter("url");
if(url.empty()) {
return SendStatusError(req, "Query parameter 'url' missing");
}
// TODO Do something with [url]
return SendStatusOK(req);
}
};
SendStatusError()
and SendStatusOK()
are from our blogpost ESP-IDF webserver: How to respond with JSON success or error message.