1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-28 05:01:28 +03:00

webserver hook: allow to handle external http protocol (#7459)

* webhook api
* simplify webserver debug printouts, move text to flash
* Hook examples in HelloServer example
* print executable code address in example
* simplify example per @mcspr suggestion
This commit is contained in:
david gauchard
2020-07-28 23:34:26 +02:00
committed by GitHub
parent 63b41bcfab
commit 33083861c8
5 changed files with 187 additions and 144 deletions

View File

@ -26,11 +26,24 @@
#include <functional>
#include <memory>
#include <functional>
#include <ESP8266WiFi.h>
#include <FS.h>
#include "detail/mimetable.h"
#include "Uri.h"
//#define DEBUG_ESP_HTTP_SERVER
#ifdef DEBUG_ESP_HTTP_SERVER
#ifdef DEBUG_ESP_PORT
#define DBGWS(f,...) do { DEBUG_ESP_PORT.printf(PSTR(f), ##__VA_ARGS__); } while (0)
#else
#define DBGWS(f,...) do { Serial.printf(PSTR(f), ##__VA_ARGS__); } while (0)
#endif
#else
#define DBGWS(x...) do { (void)0; } while (0)
#endif
enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
UPLOAD_FILE_ABORTED };
@ -80,6 +93,9 @@ public:
using ClientType = typename ServerType::ClientType;
using RequestHandlerType = RequestHandler<ServerType>;
using WebServerType = ESP8266WebServerTemplate<ServerType>;
enum ClientFuture { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN };
typedef String (*ContentTypeFunction) (const String&);
using HookFunction = std::function<ClientFuture(const String& method, const String& url, WiFiClient* client, ContentTypeFunction contentType)>;
void begin();
void begin(uint16_t port);
@ -200,11 +216,25 @@ public:
static String responseCodeToString(const int code);
void addHook (HookFunction hook) {
if (_hook) {
auto previousHook = _hook;
_hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentTypeFunction contentType) {
auto whatNow = previousHook(method, url, client, contentType);
if (whatNow == CLIENT_REQUEST_CAN_CONTINUE)
return hook(method, url, client, contentType);
return whatNow;
};
} else {
_hook = hook;
}
}
protected:
void _addRequestHandler(RequestHandlerType* handler);
void _handleRequest();
void _finalizeResponse();
bool _parseRequest(ClientType& client);
ClientFuture _parseRequest(ClientType& client);
void _parseArguments(const String& data);
int _parseArgumentsPrivate(const String& data, std::function<void(String&,String&,const String&,int,int,int,int)> handler);
bool _parseForm(ClientType& client, const String& boundary, uint32_t len);
@ -261,8 +291,7 @@ protected:
String _sopaque;
String _srealm; // Store the Auth realm between Calls
HookFunction _hook;
};