arduino json 6 async web server migration (#491)

* arduino json 6 async web server migration

* Update .travis.yml

fix travis error

* Revert "Update .travis.yml"

This reverts commit 37d1bf0e71ad21dc502aa632c1df503820686046.

* gitignore

* test fix travis

* fix travis

* fix proposed in #487

* fix travis

* fix travis

* fix travis

* fix travis

* ARDUINOJSON_5_COMPATIBILITY

* replaced to #if ARDUINOJSON_VERSION_MAJOR == 5

* fix

* added AsyncWebServer::end()

* added AsyncWebServer::end()

* Update WebServer.cpp

fix

* fix typo

* fix typo
This commit is contained in:
Marco Tombesi 2019-06-22 12:20:31 +02:00 committed by Me No Dev
parent 95dedf7a2d
commit bde2fce07b
8 changed files with 166 additions and 79 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode

View File

@ -3,10 +3,25 @@ language: bash
os: os:
- linux - linux
dist:
- xenial
addons:
apt:
packages:
- xvfb
# services:
# - xvfb
script: script:
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
- sleep 3 # - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -screen 0 1400x900x24 -ac +extension GLX +render;
- export DISPLAY=:1.0 - export DISPLAY=:1.0
- sleep 3
- ls -l /tmp/*pid
- wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz - wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz
- tar xf arduino-1.6.5-linux64.tar.xz - tar xf arduino-1.6.5-linux64.tar.xz
- mv arduino-1.6.5 $HOME/arduino_ide - mv arduino-1.6.5 $HOME/arduino_ide

144
README.md
View File

@ -11,76 +11,80 @@ For ESP32 it requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) to work
To use this library you might need to have the latest git versions of [ESP32](https://github.com/espressif/arduino-esp32) Arduino Core To use this library you might need to have the latest git versions of [ESP32](https://github.com/espressif/arduino-esp32) Arduino Core
## Table of contents ## Table of contents
- [ESPAsyncWebServer ](#espasyncwebserver-) - [ESPAsyncWebServer ![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer)](#espasyncwebserver-build-statushttpstravis-ciorgme-no-devespasyncwebserver)
- [Installation](#installation) - [Table of contents](#table-of-contents)
- [Using PlatformIO](#using-platformio) - [Installation](#installation)
- [Why should you care](#why-should-you-care) - [Using PlatformIO](#using-platformio)
- [Important things to remember](#important-things-to-remember) - [Why should you care](#why-should-you-care)
- [Principles of operation](#principles-of-operation) - [Important things to remember](#important-things-to-remember)
- [The Async Web server](#the-async-web-server) - [Principles of operation](#principles-of-operation)
- [Request Life Cycle](#request-life-cycle) - [The Async Web server](#the-async-web-server)
- [Rewrites and how do they work](#rewrites-and-how-do-they-work) - [Request Life Cycle](#request-life-cycle)
- [Handlers and how do they work](#handlers-and-how-do-they-work) - [Rewrites and how do they work](#rewrites-and-how-do-they-work)
- [Responses and how do they work](#responses-and-how-do-they-work) - [Handlers and how do they work](#handlers-and-how-do-they-work)
- [Template processing](#template-processing) - [Responses and how do they work](#responses-and-how-do-they-work)
- [Libraries and projects that use AsyncWebServer](#libraries-and-projects-that-use-asyncwebserver) - [Template processing](#template-processing)
- [Request Variables](#request-variables) - [Libraries and projects that use AsyncWebServer](#libraries-and-projects-that-use-asyncwebserver)
- [Common Variables](#common-variables) - [Request Variables](#request-variables)
- [Headers](#headers) - [Common Variables](#common-variables)
- [GET, POST and FILE parameters](#get-post-and-file-parameters) - [Headers](#headers)
- [FILE Upload handling](#file-upload-handling) - [GET, POST and FILE parameters](#get-post-and-file-parameters)
- [Body data handling](#body-data-handling) - [FILE Upload handling](#file-upload-handling)
- [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson) - [Body data handling](#body-data-handling)
- [Responses](#responses) - [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson)
- [Redirect to another URL](#redirect-to-another-url) - [Responses](#responses)
- [Basic response with HTTP Code](#basic-response-with-http-code) - [Redirect to another URL](#redirect-to-another-url)
- [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers) - [Basic response with HTTP Code](#basic-response-with-http-code)
- [Basic response with string content](#basic-response-with-string-content) - [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers)
- [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers) - [Basic response with string content](#basic-response-with-string-content)
- [Send large webpage from PROGMEM](#send-large-webpage-from-progmem) - [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers)
- [Send large webpage from PROGMEM and extra headers](#send-large-webpage-from-progmem-and-extra-headers) - [Send large webpage from PROGMEM](#send-large-webpage-from-progmem)
- [Send large webpage from PROGMEM containing templates](#send-large-webpage-from-progmem-containing-templates) - [Send large webpage from PROGMEM and extra headers](#send-large-webpage-from-progmem-and-extra-headers)
- [Send large webpage from PROGMEM containing templates and extra headers](#send-large-webpage-from-progmem-containing-templates-and-extra-headers) - [Send large webpage from PROGMEM containing templates](#send-large-webpage-from-progmem-containing-templates)
- [Send binary content from PROGMEM](#send-binary-content-from-progmem) - [Send large webpage from PROGMEM containing templates and extra headers](#send-large-webpage-from-progmem-containing-templates-and-extra-headers)
- [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream) - [Send binary content from PROGMEM](#send-binary-content-from-progmem)
- [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers) - [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream)
- [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates) - [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers)
- [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers) - [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates)
- [Respond with content coming from a File](#respond-with-content-coming-from-a-file) - [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers)
- [Respond with content coming from a File and extra headers](#respond-with-content-coming-from-a-file-and-extra-headers) - [Respond with content coming from a File](#respond-with-content-coming-from-a-file)
- [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates) - [Respond with content coming from a File and extra headers](#respond-with-content-coming-from-a-file-and-extra-headers)
- [Respond with content using a callback](#respond-with-content-using-a-callback) - [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates)
- [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) - [Respond with content using a callback](#respond-with-content-using-a-callback)
- [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) - [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers)
- [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) - [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates)
- [Chunked Response](#chunked-response) - [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers)
- [Print to response](#print-to-response) - [Chunked Response](#chunked-response)
- [ArduinoJson Basic Response](#arduinojson-basic-response) - [Chunked Response containing templates](#chunked-response-containing-templates)
- [ArduinoJson Advanced Response](#arduinojson-advanced-response) - [Print to response](#print-to-response)
- [Serving static files](#serving-static-files) - [ArduinoJson Basic Response](#arduinojson-basic-response)
- [Serving specific file by name](#serving-specific-file-by-name) - [ArduinoJson Advanced Response](#arduinojson-advanced-response)
- [Serving files in directory](#serving-files-in-directory) - [Serving static files](#serving-static-files)
- [Specifying Cache-Control header](#specifying-cache-control-header) - [Serving specific file by name](#serving-specific-file-by-name)
- [Specifying Date-Modified header](#specifying-date-modified-header) - [Serving files in directory](#serving-files-in-directory)
- [Specifying Template Processor callback](#specifying-template-processor-callback) - [Serving static files with authentication](#serving-static-files-with-authentication)
- [Using filters](#using-filters) - [Specifying Cache-Control header](#specifying-cache-control-header)
- [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode) - [Specifying Date-Modified header](#specifying-date-modified-header)
- [Rewrite to different index on AP](#rewrite-to-different-index-on-ap) - [Specifying Template Processor callback](#specifying-template-processor-callback)
- [Serving different hosts](#serving-different-hosts) - [Using filters](#using-filters)
- [Bad Responses](#bad-responses) - [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode)
- [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients) - [Rewrite to different index on AP](#rewrite-to-different-index-on-ap)
- [Async WebSocket Plugin](#async-websocket-plugin) - [Serving different hosts](#serving-different-hosts)
- [Async WebSocket Event](#async-websocket-event) - [Bad Responses](#bad-responses)
- [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) - [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients)
- [Async Event Source Plugin](#async-event-source-plugin) - [Async WebSocket Plugin](#async-websocket-plugin)
- [Setup Event Source on the server](#setup-event-source-on-the-server) - [Async WebSocket Event](#async-websocket-event)
- [Setup Event Source in the browser](#setup-event-source-in-the-browser) - [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client)
- [Scanning for available WiFi Networks](#scanning-for-available-wifi-networks) - [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer)
- [Remove handlers and rewrites](#remove-handlers-and-rewrites) - [Async Event Source Plugin](#async-event-source-plugin)
- [Setting up the server](#setting-up-the-server) - [Setup Event Source on the server](#setup-event-source-on-the-server)
- [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers) - [Setup Event Source in the browser](#setup-event-source-in-the-browser)
- [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections) - [Scanning for available WiFi Networks](#scanning-for-available-wifi-networks)
- [Adding default headers to all responses](#adding-default-headers) - [Remove handlers and rewrites](#remove-handlers-and-rewrites)
- [Setting up the server](#setting-up-the-server)
- [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)
## Installation ## Installation

View File

@ -12,7 +12,7 @@
"type": "git", "type": "git",
"url": "https://github.com/me-no-dev/ESPAsyncWebServer.git" "url": "https://github.com/me-no-dev/ESPAsyncWebServer.git"
}, },
"version": "1.2.0", "version": "1.2.1",
"license": "LGPL-3.0", "license": "LGPL-3.0",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": ["espressif8266", "espressif32"], "platforms": ["espressif8266", "espressif32"],

View File

@ -1,5 +1,5 @@
name=ESP Async WebServer name=ESP Async WebServer
version=1.2.0 version=1.2.1
author=Me-No-Dev author=Me-No-Dev
maintainer=Me-No-Dev maintainer=Me-No-Dev
sentence=Async Web Server for ESP8266 and ESP31B sentence=Async Web Server for ESP8266 and ESP31B

View File

@ -35,8 +35,15 @@
#ifndef ASYNC_JSON_H_ #ifndef ASYNC_JSON_H_
#define ASYNC_JSON_H_ #define ASYNC_JSON_H_
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <Print.h>
constexpr char* JSON_MIMETYPE = "application/json"; #if ARDUINOJSON_VERSION_MAJOR == 5
#define ARDUINOJSON_5_COMPATIBILITY
#else
#define DYNAMIC_JSON_DOCUMENT_SIZE 1024
#endif
constexpr const char* JSON_MIMETYPE = "application/json";
/* /*
* Json Response * Json Response
@ -63,14 +70,27 @@ class ChunkPrint : public Print {
} }
return 0; return 0;
} }
size_t write(const uint8_t *buffer, size_t size)
{
return this->Print::write(buffer, size);
}
}; };
class AsyncJsonResponse: public AsyncAbstractResponse { class AsyncJsonResponse: public AsyncAbstractResponse {
private: private:
#ifdef ARDUINOJSON_5_COMPATIBILITY
DynamicJsonBuffer _jsonBuffer; DynamicJsonBuffer _jsonBuffer;
#else
DynamicJsonDocument _jsonBuffer;
#endif
JsonVariant _root; JsonVariant _root;
bool _isValid; bool _isValid;
public:
public:
#ifdef ARDUINOJSON_5_COMPATIBILITY
AsyncJsonResponse(bool isArray=false): _isValid{false} { AsyncJsonResponse(bool isArray=false): _isValid{false} {
_code = 200; _code = 200;
_contentType = JSON_MIMETYPE; _contentType = JSON_MIMETYPE;
@ -79,11 +99,28 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
else else
_root = _jsonBuffer.createObject(); _root = _jsonBuffer.createObject();
} }
#else
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
_code = 200;
_contentType = JSON_MIMETYPE;
if(isArray)
_root = _jsonBuffer.createNestedArray();
else
_root = _jsonBuffer.createNestedObject();
}
#endif
~AsyncJsonResponse() {} ~AsyncJsonResponse() {}
JsonVariant & getRoot() { return _root; } JsonVariant & getRoot() { return _root; }
bool _sourceValid() const { return _isValid; } bool _sourceValid() const { return _isValid; }
size_t setLength() { size_t setLength() {
#ifdef ARDUINOJSON_5_COMPATIBILITY
_contentLength = _root.measureLength(); _contentLength = _root.measureLength();
#else
_contentLength = measureJson(_root);
#endif
if (_contentLength) { _isValid = true; } if (_contentLength) { _isValid = true; }
return _contentLength; return _contentLength;
} }
@ -92,7 +129,12 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
size_t _fillBuffer(uint8_t *data, size_t len){ size_t _fillBuffer(uint8_t *data, size_t len){
ChunkPrint dest(data, _sentLength, len); ChunkPrint dest(data, _sentLength, len);
#ifdef ARDUINOJSON_5_COMPATIBILITY
_root.printTo( dest ) ; _root.printTo( dest ) ;
#else
serializeJson(_root, dest);
#endif
return len; return len;
} }
}; };
@ -106,9 +148,19 @@ protected:
WebRequestMethodComposite _method; WebRequestMethodComposite _method;
ArJsonRequestHandlerFunction _onRequest; ArJsonRequestHandlerFunction _onRequest;
int _contentLength; int _contentLength;
#ifndef ARDUINOJSON_5_COMPATIBILITY
const size_t maxJsonBufferSize;
#endif
int _maxContentLength; int _maxContentLength;
public: public:
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #ifdef ARDUINOJSON_5_COMPATIBILITY
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest)
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {}
#else
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE)
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
#endif
void setMethod(WebRequestMethodComposite method){ _method = method; } void setMethod(WebRequestMethodComposite method){ _method = method; }
void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; } void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; }
void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; } void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; }
@ -123,7 +175,7 @@ public:
if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
return false; return false;
if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) if ( !request->contentType().equalsIgnoreCase(JSON_MIMETYPE) )
return false; return false;
request->addInterestingHeader("ANY"); request->addInterestingHeader("ANY");
@ -133,9 +185,18 @@ public:
virtual void handleRequest(AsyncWebServerRequest *request) override final { virtual void handleRequest(AsyncWebServerRequest *request) override final {
if(_onRequest) { if(_onRequest) {
if (request->_tempObject != NULL) { if (request->_tempObject != NULL) {
#ifdef ARDUINOJSON_5_COMPATIBILITY
DynamicJsonBuffer jsonBuffer; DynamicJsonBuffer jsonBuffer;
JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject));
if (json.success()) { if (json.success()) {
#else
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
if(!error) {
JsonVariant json = jsonBuffer.as<JsonVariant>();
#endif
_onRequest(request, json); _onRequest(request, json);
return; return;
} }

View File

@ -393,6 +393,7 @@ class AsyncWebServer {
~AsyncWebServer(); ~AsyncWebServer();
void begin(); void begin();
void end();
#if ASYNC_TCP_SSL_ENABLED #if ASYNC_TCP_SSL_ENABLED
void onSslFileRequest(AcSSlFileHandler cb, void* arg); void onSslFileRequest(AcSSlFileHandler cb, void* arg);

View File

@ -52,8 +52,9 @@ AsyncWebServer::AsyncWebServer(uint16_t port)
} }
AsyncWebServer::~AsyncWebServer(){ AsyncWebServer::~AsyncWebServer(){
reset(); reset();
delete _catchAllHandler; end();
if(_catchAllHandler) delete _catchAllHandler;
} }
AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){ AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){
@ -83,6 +84,10 @@ void AsyncWebServer::begin(){
_server.begin(); _server.begin();
} }
void AsyncWebServer::end(){
_server.end();
}
#if ASYNC_TCP_SSL_ENABLED #if ASYNC_TCP_SSL_ENABLED
void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg){ void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg){
_server.onSslFileRequest(cb, arg); _server.onSslFileRequest(cb, arg);