Make regex a define exclusive (#617)

* Change compiler error to runtime error.
Add compiler warining when a ASYNCWEBSERVER_REGEX function is used, but not enabled

* Update docs for usage in Arduino IDE

* Update docs for platform.local.txt
This commit is contained in:
Bob 2019-10-14 22:06:38 +02:00 committed by Me No Dev
parent f3ebe2dea9
commit a84f16989a
7 changed files with 89 additions and 15 deletions

View File

@ -75,16 +75,17 @@ if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo ""
fi
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> <build-flags> [extra-options]
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]"
echo "USAGE: build_sketch <fqbn> <path-to-ino> <build-flags> [extra-options]"
return 1
fi
local fqbn="$1"
local sketch="$2"
local xtra_opts="$3"
local build_flags="$3"
local xtra_opts="$4"
local win_opts=""
if [ "$OS_IS_WINDOWS" == "1" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
@ -107,6 +108,7 @@ function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
-libraries "$ARDUINO_USR_PATH/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$ARDUINO_BUILD_DIR" \
-prefs=compiler.cpp.extra_flags="$build_flags" \
$win_opts $xtra_opts "$sketch"
}
@ -210,7 +212,13 @@ function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_sketch "$fqbn" "$sketch" "$xtra_opts"
local sketchBuildFlags=""
if [ -f "$sketchdir/.test.build_flags" ]; then
while read line; do
sketchBuildFlags="$sketchBuildFlags $line"
done < "$sketchdir/.test.build_flags"
fi
build_sketch "$fqbn" "$sketch" "$sketchBuildFlags" "$xtra_opts"
local result=$?
if [ $result -ne 0 ]; then
return $result

View File

@ -10,19 +10,20 @@ echo "PlatformIO has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
if [ "$#" -lt 2 ]; then
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino> <build-flags>
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketch <board> <path-to-ino>"
echo "USAGE: build_pio_sketch <board> <path-to-ino> <build-flags>"
return 1
fi
local board="$1"
local sketch="$2"
local buildFlags="$3"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" --project-option="build_flags=$buildFlags"
}
function count_sketches() # count_sketches <examples-path>
@ -118,12 +119,18 @@ function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chun
|| [ -f "$sketchdir/.test.skip" ]; then
continue
fi
local sketchBuildFlags=""
if [ -f "$sketchdir/.test.build_flags" ]; then
while read line; do
sketchBuildFlags="$sketchBuildFlags $line"
done < "$sketchdir/.test.build_flags"
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_pio_sketch "$board" "$sketch"
build_pio_sketch "$board" "$sketch" "$sketchBuildFlags"
local result=$?
if [ $result -ne 0 ]; then
return $result

View File

@ -89,6 +89,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht
- [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers)
- [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections)
- [Adding Default Headers](#adding-default-headers)
- [Path variable](#path-variable)
## Installation
@ -1484,3 +1485,37 @@ webServer.onNotFound([](AsyncWebServerRequest *request) {
}
});
```
### Path variable
With path variable you can create a custom regex rule for a specific parameter in a route.
For example we want a `sensorId` parameter in a route rule to match only a integer.
```cpp
server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) {
String sensorId = request->pathArg(0);
});
```
*NOTE*: All regex patterns starts with `^` and ends with `$`
To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`.
For Arduino IDE create/update `platform.local.txt`:
`Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt
`Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt
Add/Update the following line:
```
compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX
```
For platformio modify `platformio.ini`:
```ini
[env:myboard]
build_flags =
-DASYNCWEBSERVER_REGEX
```
*NOTE*: By enabling `ASYNCWEBSERVER_REGEX`, `<regex>` will be included. This will add an 100k to your binary.

View File

@ -0,0 +1 @@
-DASYNCWEBSERVER_REGEX=1

View File

@ -5,6 +5,18 @@
// * handle missing pages / 404s
//
// Add buildflag ASYNCWEBSERVER_REGEX to enable the regex support
// For platformio: platformio.ini:
// build_flags =
// -DASYNCWEBSERVER_REGEX
// For arduino IDE: create/update platform.local.txt
// Windows: C:\Users\(username)\AppData\Local\Arduino15\packages\espxxxx\hardware\espxxxx\{version}\platform.local.txt
// Linux: ~/.arduino15/packages/espxxxx/hardware/espxxxx/{version}/platform.local.txt
//
// compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX=1
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>

View File

@ -38,6 +38,12 @@
#error Platform not supported
#endif
#ifdef ASYNCWEBSERVER_REGEX
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE
#else
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined")))
#endif
#define DEBUGF(...) //Serial.printf(__VA_ARGS__)
class AsyncWebServer;
@ -271,7 +277,7 @@ class AsyncWebServerRequest {
bool hasArg(const char* name) const; // check if argument exists
bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists
const String& pathArg(size_t i) const;
const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const;
const String& header(const char* name) const;// get request header value by name
const String& header(const __FlashStringHelper * data) const;// get request header value by F(name)

View File

@ -22,7 +22,9 @@
#define ASYNCWEBSERVERHANDLERIMPL_H_
#include <string>
#ifdef ASYNCWEBSERVER_REGEX
#include <regex>
#endif
#include "stddef.h"
#include <time.h>
@ -71,10 +73,10 @@ class AsyncCallbackWebHandler: public AsyncWebHandler {
ArBodyHandlerFunction _onBody;
bool _isRegex;
public:
AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false){}
AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
void setUri(const String& uri){
_uri = uri;
_isRegex = uri.startsWith("^") && uri.endsWith("$");
_isRegex = uri.startsWith("^") && uri.endsWith("$");
}
void setMethod(WebRequestMethodComposite method){ _method = method; }
void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; }
@ -89,18 +91,21 @@ class AsyncCallbackWebHandler: public AsyncWebHandler {
if(!(_method & request->method()))
return false;
#ifdef ASYNCWEBSERVER_REGEX
if (_isRegex) {
std::regex rgx(_uri.c_str());
std::regex pattern(_uri.c_str());
std::smatch matches;
std::string s(request->url().c_str());
if(std::regex_search(s, matches, rgx)) {
if(std::regex_search(s, matches, pattern)) {
for (size_t i = 1; i < matches.size(); ++i) { // start from 1
request->_addPathParam(matches[i].str().c_str());
}
} else {
return false;
}
} else if (_uri.length() && _uri.endsWith("*")) {
} else
#endif
if (_uri.length() && _uri.endsWith("*")) {
String uriTemplate = String(_uri);
uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1);
if (!request->url().startsWith(uriTemplate))