Skip to content

Commit

Permalink
Make regex a define exclusive (#617)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Bmooij authored and me-no-dev committed Oct 14, 2019
1 parent f3ebe2d commit a84f169
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 15 deletions.
16 changes: 12 additions & 4 deletions .github/scripts/install-arduino-ide.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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/"`
Expand All @@ -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"
}

Expand Down Expand Up @@ -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
Expand Down
17 changes: 12 additions & 5 deletions .github/scripts/install-platformio.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
1 change: 1 addition & 0 deletions examples/regex_patterns/.test.build_flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-DASYNCWEBSERVER_REGEX=1
12 changes: 12 additions & 0 deletions examples/regex_patterns/regex_patterns.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
8 changes: 7 additions & 1 deletion src/ESPAsyncWebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 10 additions & 5 deletions src/WebHandlerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#define ASYNCWEBSERVERHANDLERIMPL_H_

#include <string>
#ifdef ASYNCWEBSERVER_REGEX
#include <regex>
#endif

#include "stddef.h"
#include <time.h>
Expand Down Expand Up @@ -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; }
Expand All @@ -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))
Expand Down

0 comments on commit a84f169

Please sign in to comment.