fixes PlatformIO 6.2.0 breaks compilation #1166 (thanks Michael)

This commit is contained in:
Proddy
2023-04-30 16:22:51 +02:00
parent 0d9cd64619
commit dc4bd64aff
5 changed files with 2362 additions and 2361 deletions

View File

@@ -1,487 +1,487 @@
/* /*
Asynchronous WebServer library for Espressif MCUs Asynchronous WebServer library for Espressif MCUs
Copyright (c) 2016 Hristo Gochkov. All rights reserved. Copyright (c) 2016 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef _ESPAsyncWebServer_H_ #ifndef _ESPAsyncWebServer_H_
#define _ESPAsyncWebServer_H_ #define _ESPAsyncWebServer_H_
#include "Arduino.h" #include "Arduino.h"
#include <functional> #include <functional>
#include "FS.h" #include "FS.h"
#include "StringArray.h" #include "StringArray.h"
#ifdef ESP32 #ifdef ESP32
#include <WiFi.h> #include <WiFi.h>
#include <AsyncTCP.h> #include <AsyncTCP.h>
#elif defined(ESP8266) #elif defined(ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h> #include <ESPAsyncTCP.h>
#else #else
#error Platform not supported #error Platform not supported
#endif #endif
#ifdef ASYNCWEBSERVER_REGEX #ifdef ASYNCWEBSERVER_REGEX
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE #define ASYNCWEBSERVER_REGEX_ATTRIBUTE
#else #else
#define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined"))) #define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined")))
#endif #endif
#define DEBUGF(...) //Serial.printf(__VA_ARGS__) #define DEBUGF(...) //Serial.printf(__VA_ARGS__)
class AsyncWebServer; class AsyncWebServer;
class AsyncWebServerRequest; class AsyncWebServerRequest;
class AsyncWebServerResponse; class AsyncWebServerResponse;
class AsyncWebHeader; class AsyncWebHeader;
class AsyncWebParameter; class AsyncWebParameter;
class AsyncWebRewrite; class AsyncWebRewrite;
class AsyncWebHandler; class AsyncWebHandler;
class AsyncStaticWebHandler; class AsyncStaticWebHandler;
class AsyncCallbackWebHandler; class AsyncCallbackWebHandler;
class AsyncResponseStream; class AsyncResponseStream;
#ifndef WEBSERVER_H #ifndef WEBSERVER_H
typedef enum { typedef enum {
HTTP_GET = 0b00000001, HTTP_GET = 0b00000001,
HTTP_POST = 0b00000010, HTTP_POST = 0b00000010,
HTTP_DELETE = 0b00000100, HTTP_DELETE = 0b00000100,
HTTP_PUT = 0b00001000, HTTP_PUT = 0b00001000,
HTTP_PATCH = 0b00010000, HTTP_PATCH = 0b00010000,
HTTP_HEAD = 0b00100000, HTTP_HEAD = 0b00100000,
HTTP_OPTIONS = 0b01000000, HTTP_OPTIONS = 0b01000000,
HTTP_ANY = 0b01111111, HTTP_ANY = 0b01111111,
} WebRequestMethod; } WebRequestMethod;
#endif #endif
#ifndef HAVE_FS_FILE_OPEN_MODE #ifndef HAVE_FS_FILE_OPEN_MODE
namespace fs { namespace fs {
class FileOpenMode { class FileOpenMode {
public: public:
static const char *read; static const char *read;
static const char *write; static const char *write;
static const char *append; static const char *append;
}; };
}; };
#else #else
#include "FileOpenMode.h" #include "FileOpenMode.h"
#endif #endif
//if this value is returned when asked for data, packet will not be sent and you will be asked for data again //if this value is returned when asked for data, packet will not be sent and you will be asked for data again
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF #define RESPONSE_TRY_AGAIN 0xFFFFFFFF
typedef uint8_t WebRequestMethodComposite; typedef uint8_t WebRequestMethodComposite;
typedef std::function<void(void)> ArDisconnectHandler; typedef std::function<void(void)> ArDisconnectHandler;
/* /*
* PARAMETER :: Chainable object to hold GET/POST and FILE parameters * PARAMETER :: Chainable object to hold GET/POST and FILE parameters
* */ * */
class AsyncWebParameter { class AsyncWebParameter {
private: private:
String _name; String _name;
String _value; String _value;
size_t _size; size_t _size;
bool _isForm; bool _isForm;
bool _isFile; bool _isFile;
public: public:
AsyncWebParameter(const String& name, const String& value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file){} AsyncWebParameter(const String& name, const String& value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file){}
const String& name() const { return _name; } const String& name() const { return _name; }
const String& value() const { return _value; } const String& value() const { return _value; }
size_t size() const { return _size; } size_t size() const { return _size; }
bool isPost() const { return _isForm; } bool isPost() const { return _isForm; }
bool isFile() const { return _isFile; } bool isFile() const { return _isFile; }
}; };
/* /*
* HEADER :: Chainable object to hold the headers * HEADER :: Chainable object to hold the headers
* */ * */
class AsyncWebHeader { class AsyncWebHeader {
private: private:
String _name; String _name;
String _value; String _value;
public: public:
AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){} AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){}
AsyncWebHeader(const String& data): _name(), _value(){ AsyncWebHeader(const String& data): _name(), _value(){
if(!data) return; if(!data) return;
int index = data.indexOf(':'); int index = data.indexOf(':');
if (index < 0) return; if (index < 0) return;
_name = data.substring(0, index); _name = data.substring(0, index);
_value = data.substring(index + 2); _value = data.substring(index + 2);
} }
~AsyncWebHeader(){} ~AsyncWebHeader(){}
const String& name() const { return _name; } const String& name() const { return _name; }
const String& value() const { return _value; } const String& value() const { return _value; }
String toString() const { return String(_name + F(": ") + _value + F("\r\n")); } String toString() const { return String(_name + F(": ") + _value + F("\r\n")); }
}; };
/* /*
* REQUEST :: Each incoming Client is wrapped inside a Request and both live together until disconnect * REQUEST :: Each incoming Client is wrapped inside a Request and both live together until disconnect
* */ * */
typedef enum { RCT_NOT_USED = -1, RCT_DEFAULT = 0, RCT_HTTP, RCT_WS, RCT_EVENT, RCT_MAX } RequestedConnectionType; typedef enum { RCT_NOT_USED = -1, RCT_DEFAULT = 0, RCT_HTTP, RCT_WS, RCT_EVENT, RCT_MAX } RequestedConnectionType;
typedef std::function<size_t(uint8_t*, size_t, size_t)> AwsResponseFiller; typedef std::function<size_t(uint8_t*, size_t, size_t)> AwsResponseFiller;
typedef std::function<String(const String&)> AwsTemplateProcessor; typedef std::function<String(const String&)> AwsTemplateProcessor;
class AsyncWebServerRequest { class AsyncWebServerRequest {
using File = fs::File; using File = fs::File;
using FS = fs::FS; using FS = fs::FS;
friend class AsyncWebServer; friend class AsyncWebServer;
friend class AsyncCallbackWebHandler; friend class AsyncCallbackWebHandler;
friend class HttpCookieHeader; friend class HttpCookieHeader;
private: private:
AsyncClient* _client; AsyncClient* _client;
AsyncWebServer* _server; AsyncWebServer* _server;
AsyncWebHandler* _handler; AsyncWebHandler* _handler;
AsyncWebServerResponse* _response; AsyncWebServerResponse* _response;
StringArray _interestingHeaders; StringArray _interestingHeaders;
ArDisconnectHandler _onDisconnectfn; ArDisconnectHandler _onDisconnectfn;
String _temp; String _temp;
uint8_t _parseState; uint8_t _parseState;
uint8_t _version; uint8_t _version;
WebRequestMethodComposite _method; WebRequestMethodComposite _method;
String _url; String _url;
String _host; String _host;
String _contentType; String _contentType;
String _boundary; String _boundary;
String _authorization; String _authorization;
RequestedConnectionType _reqconntype; RequestedConnectionType _reqconntype;
void _removeNotInterestingHeaders(); void _removeNotInterestingHeaders();
bool _isDigest; bool _isDigest;
bool _isMultipart; bool _isMultipart;
bool _isPlainPost; bool _isPlainPost;
bool _expectingContinue; bool _expectingContinue;
size_t _contentLength; size_t _contentLength;
size_t _parsedLength; size_t _parsedLength;
LinkedList<AsyncWebHeader *> _headers; LinkedList<AsyncWebHeader *> _headers;
LinkedList<AsyncWebParameter *> _params; LinkedList<AsyncWebParameter *> _params;
LinkedList<String *> _pathParams; LinkedList<String *> _pathParams;
uint8_t _multiParseState; uint8_t _multiParseState;
uint8_t _boundaryPosition; uint8_t _boundaryPosition;
size_t _itemStartIndex; size_t _itemStartIndex;
size_t _itemSize; size_t _itemSize;
String _itemName; String _itemName;
String _itemFilename; String _itemFilename;
String _itemType; String _itemType;
String _itemValue; String _itemValue;
uint8_t *_itemBuffer; uint8_t *_itemBuffer;
size_t _itemBufferIndex; size_t _itemBufferIndex;
bool _itemIsFile; bool _itemIsFile;
void _onPoll(); void _onPoll();
void _onAck(size_t len, uint32_t time); void _onAck(size_t len, uint32_t time);
void _onError(int8_t error); void _onError(int8_t error);
void _onTimeout(uint32_t time); void _onTimeout(uint32_t time);
void _onDisconnect(); void _onDisconnect();
void _onData(void *buf, size_t len); void _onData(void *buf, size_t len);
void _addParam(AsyncWebParameter*); void _addParam(AsyncWebParameter*);
void _addPathParam(const char *param); void _addPathParam(const char *param);
bool _parseReqHead(); bool _parseReqHead();
bool _parseReqHeader(); bool _parseReqHeader();
void _parseLine(); void _parseLine();
void _parsePlainPostChar(uint8_t data); void _parsePlainPostChar(uint8_t data);
void _parseMultipartPostByte(uint8_t data, bool last); void _parseMultipartPostByte(uint8_t data, bool last);
void _addGetParams(const String& params); void _addGetParams(const String& params);
void _handleUploadStart(); void _handleUploadStart();
void _handleUploadByte(uint8_t data, bool last); void _handleUploadByte(uint8_t data, bool last);
void _handleUploadEnd(); void _handleUploadEnd();
public: public:
File _tempFile; File _tempFile;
void *_tempObject; void *_tempObject;
AsyncWebServerRequest(AsyncWebServer*, AsyncClient*); AsyncWebServerRequest(AsyncWebServer*, AsyncClient*);
~AsyncWebServerRequest(); ~AsyncWebServerRequest();
AsyncClient* client(){ return _client; } AsyncClient* client(){ return _client; }
uint8_t version() const { return _version; } uint8_t version() const { return _version; }
WebRequestMethodComposite method() const { return _method; } WebRequestMethodComposite method() const { return _method; }
const String& url() const { return _url; } const String& url() const { return _url; }
const String& host() const { return _host; } const String& host() const { return _host; }
const String& contentType() const { return _contentType; } const String& contentType() const { return _contentType; }
size_t contentLength() const { return _contentLength; } size_t contentLength() const { return _contentLength; }
bool multipart() const { return _isMultipart; } bool multipart() const { return _isMultipart; }
const __FlashStringHelper *methodToString() const; const char *methodToString() const;
const __FlashStringHelper *requestedConnTypeToString() const; const char *requestedConnTypeToString() const;
RequestedConnectionType requestedConnType() const { return _reqconntype; } RequestedConnectionType requestedConnType() const { return _reqconntype; }
bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED); bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED);
void onDisconnect (ArDisconnectHandler fn); void onDisconnect (ArDisconnectHandler fn);
//hash is the string representation of: //hash is the string representation of:
// base64(user:pass) for basic or // base64(user:pass) for basic or
// user:realm:md5(user:realm:pass) for digest // user:realm:md5(user:realm:pass) for digest
bool authenticate(const char * hash); bool authenticate(const char * hash);
bool authenticate(const char * username, const char * password, const char * realm = NULL, bool passwordIsHash = false); bool authenticate(const char * username, const char * password, const char * realm = NULL, bool passwordIsHash = false);
void requestAuthentication(const char * realm = NULL, bool isDigest = true); void requestAuthentication(const char * realm = NULL, bool isDigest = true);
void setHandler(AsyncWebHandler *handler){ _handler = handler; } void setHandler(AsyncWebHandler *handler){ _handler = handler; }
void addInterestingHeader(const String& name); void addInterestingHeader(const String& name);
void redirect(const String& url); void redirect(const String& url);
void send(AsyncWebServerResponse *response); void send(AsyncWebServerResponse *response);
void send(int code, const String& contentType=String(), const String& content=String()); void send(int code, const String& contentType=String(), const String& content=String());
void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr);
AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String()); AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String());
AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
AsyncWebServerResponse *beginResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr);
AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr);
AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460); AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460);
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr);
size_t headers() const; // get header count size_t headers() const; // get header count
bool hasHeader(const String& name) const; // check if header exists bool hasHeader(const String& name) const; // check if header exists
bool hasHeader(const __FlashStringHelper * data) const; // check if header exists bool hasHeader(const __FlashStringHelper * data) const; // check if header exists
AsyncWebHeader* getHeader(const String& name) const; AsyncWebHeader* getHeader(const String& name) const;
AsyncWebHeader* getHeader(const __FlashStringHelper * data) const; AsyncWebHeader* getHeader(const __FlashStringHelper * data) const;
AsyncWebHeader* getHeader(size_t num) const; AsyncWebHeader* getHeader(size_t num) const;
size_t params() const; // get arguments count size_t params() const; // get arguments count
bool hasParam(const String& name, bool post=false, bool file=false) const; bool hasParam(const String& name, bool post=false, bool file=false) const;
bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const; bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const;
AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const; AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const;
AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const; AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const;
AsyncWebParameter* getParam(size_t num) const; AsyncWebParameter* getParam(size_t num) const;
size_t args() const { return params(); } // get arguments count size_t args() const { return params(); } // get arguments count
const String& arg(const String& name) const; // get request argument value by name const String& arg(const String& name) const; // get request argument value by name
const String& arg(const __FlashStringHelper * data) const; // get request argument value by F(name) const String& arg(const __FlashStringHelper * data) const; // get request argument value by F(name)
const String& arg(size_t i) const; // get request argument value by number const String& arg(size_t i) const; // get request argument value by number
const String& argName(size_t i) const; // get request argument name by number const String& argName(size_t i) const; // get request argument name by number
bool hasArg(const char* name) const; // check if argument exists bool hasArg(const char* name) const; // check if argument exists
bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists
const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE 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 char* name) const;// get request header value by name
const String& header(const __FlashStringHelper * data) const;// get request header value by F(name) const String& header(const __FlashStringHelper * data) const;// get request header value by F(name)
const String& header(size_t i) const; // get request header value by number const String& header(size_t i) const; // get request header value by number
const String& headerName(size_t i) const; // get request header name by number const String& headerName(size_t i) const; // get request header name by number
String urlDecode(const String& text) const; String urlDecode(const String& text) const;
}; };
/* /*
* FILTER :: Callback to filter AsyncWebRewrite and AsyncWebHandler (done by the Server) * FILTER :: Callback to filter AsyncWebRewrite and AsyncWebHandler (done by the Server)
* */ * */
typedef std::function<bool(AsyncWebServerRequest *request)> ArRequestFilterFunction; typedef std::function<bool(AsyncWebServerRequest *request)> ArRequestFilterFunction;
bool ON_STA_FILTER(AsyncWebServerRequest *request); bool ON_STA_FILTER(AsyncWebServerRequest *request);
bool ON_AP_FILTER(AsyncWebServerRequest *request); bool ON_AP_FILTER(AsyncWebServerRequest *request);
/* /*
* REWRITE :: One instance can be handle any Request (done by the Server) * REWRITE :: One instance can be handle any Request (done by the Server)
* */ * */
class AsyncWebRewrite { class AsyncWebRewrite {
protected: protected:
String _from; String _from;
String _toUrl; String _toUrl;
String _params; String _params;
ArRequestFilterFunction _filter; ArRequestFilterFunction _filter;
public: public:
AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL){ AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL){
int index = _toUrl.indexOf('?'); int index = _toUrl.indexOf('?');
if (index > 0) { if (index > 0) {
_params = _toUrl.substring(index +1); _params = _toUrl.substring(index +1);
_toUrl = _toUrl.substring(0, index); _toUrl = _toUrl.substring(0, index);
} }
} }
virtual ~AsyncWebRewrite(){} virtual ~AsyncWebRewrite(){}
AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
bool filter(AsyncWebServerRequest *request) const { return _filter == NULL || _filter(request); } bool filter(AsyncWebServerRequest *request) const { return _filter == NULL || _filter(request); }
const String& from(void) const { return _from; } const String& from(void) const { return _from; }
const String& toUrl(void) const { return _toUrl; } const String& toUrl(void) const { return _toUrl; }
const String& params(void) const { return _params; } const String& params(void) const { return _params; }
virtual bool match(AsyncWebServerRequest *request) { return from() == request->url() && filter(request); } virtual bool match(AsyncWebServerRequest *request) { return from() == request->url() && filter(request); }
}; };
/* /*
* HANDLER :: One instance can be attached to any Request (done by the Server) * HANDLER :: One instance can be attached to any Request (done by the Server)
* */ * */
class AsyncWebHandler { class AsyncWebHandler {
protected: protected:
ArRequestFilterFunction _filter; ArRequestFilterFunction _filter;
String _username; String _username;
String _password; String _password;
public: public:
AsyncWebHandler():_username(""), _password(""){} AsyncWebHandler():_username(""), _password(""){}
AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; }
AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; }; AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; };
bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); } bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); }
virtual ~AsyncWebHandler(){} virtual ~AsyncWebHandler(){}
virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){ virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){
return false; return false;
} }
virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))){} virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))){}
virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))){} virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))){}
virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))){} virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))){}
virtual bool isRequestHandlerTrivial(){return true;} virtual bool isRequestHandlerTrivial(){return true;}
}; };
/* /*
* RESPONSE :: One instance is created for each Request (attached by the Handler) * RESPONSE :: One instance is created for each Request (attached by the Handler)
* */ * */
typedef enum { typedef enum {
RESPONSE_SETUP, RESPONSE_HEADERS, RESPONSE_CONTENT, RESPONSE_WAIT_ACK, RESPONSE_END, RESPONSE_FAILED RESPONSE_SETUP, RESPONSE_HEADERS, RESPONSE_CONTENT, RESPONSE_WAIT_ACK, RESPONSE_END, RESPONSE_FAILED
} WebResponseState; } WebResponseState;
class AsyncWebServerResponse { class AsyncWebServerResponse {
protected: protected:
int _code; int _code;
LinkedList<AsyncWebHeader *> _headers; LinkedList<AsyncWebHeader *> _headers;
String _contentType; String _contentType;
size_t _contentLength; size_t _contentLength;
bool _sendContentLength; bool _sendContentLength;
bool _chunked; bool _chunked;
size_t _headLength; size_t _headLength;
size_t _sentLength; size_t _sentLength;
size_t _ackedLength; size_t _ackedLength;
size_t _writtenLength; size_t _writtenLength;
WebResponseState _state; WebResponseState _state;
const char* _responseCodeToString(int code); const char* _responseCodeToString(int code);
public: public:
static const __FlashStringHelper *responseCodeToString(int code); static const __FlashStringHelper *responseCodeToString(int code);
public: public:
AsyncWebServerResponse(); AsyncWebServerResponse();
virtual ~AsyncWebServerResponse(); virtual ~AsyncWebServerResponse();
virtual void setCode(int code); virtual void setCode(int code);
virtual void setContentLength(size_t len); virtual void setContentLength(size_t len);
virtual void setContentType(const String& type); virtual void setContentType(const String& type);
virtual void addHeader(const String& name, const String& value); virtual void addHeader(const String& name, const String& value);
virtual String _assembleHead(uint8_t version); virtual String _assembleHead(uint8_t version);
virtual bool _started() const; virtual bool _started() const;
virtual bool _finished() const; virtual bool _finished() const;
virtual bool _failed() const; virtual bool _failed() const;
virtual bool _sourceValid() const; virtual bool _sourceValid() const;
virtual void _respond(AsyncWebServerRequest *request); virtual void _respond(AsyncWebServerRequest *request);
virtual size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); virtual size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
}; };
/* /*
* SERVER :: One instance * SERVER :: One instance
* */ * */
typedef std::function<void(AsyncWebServerRequest *request)> ArRequestHandlerFunction; typedef std::function<void(AsyncWebServerRequest *request)> ArRequestHandlerFunction;
typedef std::function<void(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final)> ArUploadHandlerFunction; typedef std::function<void(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final)> ArUploadHandlerFunction;
typedef std::function<void(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)> ArBodyHandlerFunction; typedef std::function<void(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)> ArBodyHandlerFunction;
class AsyncWebServer { class AsyncWebServer {
protected: protected:
AsyncServer _server; AsyncServer _server;
LinkedList<AsyncWebRewrite*> _rewrites; LinkedList<AsyncWebRewrite*> _rewrites;
LinkedList<AsyncWebHandler*> _handlers; LinkedList<AsyncWebHandler*> _handlers;
AsyncCallbackWebHandler* _catchAllHandler; AsyncCallbackWebHandler* _catchAllHandler;
public: public:
AsyncWebServer(uint16_t port); AsyncWebServer(uint16_t port);
~AsyncWebServer(); ~AsyncWebServer();
void begin(); void begin();
void end(); void end();
#if ASYNC_TCP_SSL_ENABLED #if ASYNC_TCP_SSL_ENABLED
void onSslFileRequest(AcSSlFileHandler cb, void* arg); void onSslFileRequest(AcSSlFileHandler cb, void* arg);
void beginSecure(const char *cert, const char *private_key_file, const char *password); void beginSecure(const char *cert, const char *private_key_file, const char *password);
#endif #endif
AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite); AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite);
bool removeRewrite(AsyncWebRewrite* rewrite); bool removeRewrite(AsyncWebRewrite* rewrite);
AsyncWebRewrite& rewrite(const char* from, const char* to); AsyncWebRewrite& rewrite(const char* from, const char* to);
AsyncWebHandler& addHandler(AsyncWebHandler* handler); AsyncWebHandler& addHandler(AsyncWebHandler* handler);
bool removeHandler(AsyncWebHandler* handler); bool removeHandler(AsyncWebHandler* handler);
AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest); AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest);
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest);
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody);
AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL); AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL);
void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned
void onFileUpload(ArUploadHandlerFunction fn); //handle file uploads void onFileUpload(ArUploadHandlerFunction fn); //handle file uploads
void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request) void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request)
void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody
void _handleDisconnect(AsyncWebServerRequest *request); void _handleDisconnect(AsyncWebServerRequest *request);
void _attachHandler(AsyncWebServerRequest *request); void _attachHandler(AsyncWebServerRequest *request);
void _rewriteRequest(AsyncWebServerRequest *request); void _rewriteRequest(AsyncWebServerRequest *request);
}; };
class DefaultHeaders { class DefaultHeaders {
using headers_t = LinkedList<AsyncWebHeader *>; using headers_t = LinkedList<AsyncWebHeader *>;
headers_t _headers; headers_t _headers;
DefaultHeaders() DefaultHeaders()
:_headers(headers_t([](AsyncWebHeader *h){ delete h; })) :_headers(headers_t([](AsyncWebHeader *h){ delete h; }))
{} {}
public: public:
using ConstIterator = headers_t::ConstIterator; using ConstIterator = headers_t::ConstIterator;
void addHeader(const String& name, const String& value){ void addHeader(const String& name, const String& value){
_headers.add(new AsyncWebHeader(name, value)); _headers.add(new AsyncWebHeader(name, value));
} }
ConstIterator begin() const { return _headers.begin(); } ConstIterator begin() const { return _headers.begin(); }
ConstIterator end() const { return _headers.end(); } ConstIterator end() const { return _headers.end(); }
DefaultHeaders(DefaultHeaders const &) = delete; DefaultHeaders(DefaultHeaders const &) = delete;
DefaultHeaders &operator=(DefaultHeaders const &) = delete; DefaultHeaders &operator=(DefaultHeaders const &) = delete;
static DefaultHeaders &Instance() { static DefaultHeaders &Instance() {
static DefaultHeaders instance; static DefaultHeaders instance;
return instance; return instance;
} }
}; };
#include "WebResponseImpl.h" #include "WebResponseImpl.h"
#include "WebHandlerImpl.h" #include "WebHandlerImpl.h"
#include "AsyncWebSocket.h" #include "AsyncWebSocket.h"
#include "AsyncEventSource.h" #include "AsyncEventSource.h"
#endif /* _AsyncWebServer_H_ */ #endif /* _AsyncWebServer_H_ */

View File

@@ -1,235 +1,235 @@
/* /*
Asynchronous WebServer library for Espressif MCUs Asynchronous WebServer library for Espressif MCUs
Copyright (c) 2016 Hristo Gochkov. All rights reserved. Copyright (c) 2016 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "WebAuthentication.h" #include "WebAuthentication.h"
#include <libb64/cencode.h> #include <libb64/cencode.h>
#ifdef ESP32 #ifdef ESP32
#include "mbedtls/md5.h" #include "mbedtls/md5.h"
#else #else
#include "md5.h" #include "md5.h"
#endif #endif
// Basic Auth hash = base64("username:password") // Basic Auth hash = base64("username:password")
bool checkBasicAuthentication(const char * hash, const char * username, const char * password){ bool checkBasicAuthentication(const char * hash, const char * username, const char * password){
if(username == NULL || password == NULL || hash == NULL) if(username == NULL || password == NULL || hash == NULL)
return false; return false;
size_t toencodeLen = strlen(username)+strlen(password)+1; size_t toencodeLen = strlen(username)+strlen(password)+1;
size_t encodedLen = base64_encode_expected_len(toencodeLen); size_t encodedLen = base64_encode_expected_len(toencodeLen);
if(strlen(hash) != encodedLen) if(strlen(hash) != encodedLen)
return false; return false;
char *toencode = new char[toencodeLen+1]; char *toencode = new char[toencodeLen+1];
if(toencode == NULL){ if(toencode == NULL){
return false; return false;
} }
char *encoded = new char[base64_encode_expected_len(toencodeLen)+1]; char *encoded = new char[base64_encode_expected_len(toencodeLen)+1];
if(encoded == NULL){ if(encoded == NULL){
delete[] toencode; delete[] toencode;
return false; return false;
} }
sprintf_P(toencode, PSTR("%s:%s"), username, password); sprintf_P(toencode, PSTR("%s:%s"), username, password);
if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0){ if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0){
delete[] toencode; delete[] toencode;
delete[] encoded; delete[] encoded;
return true; return true;
} }
delete[] toencode; delete[] toencode;
delete[] encoded; delete[] encoded;
return false; return false;
} }
static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more
#ifdef ESP32 #ifdef ESP32
mbedtls_md5_context _ctx; mbedtls_md5_context _ctx;
#else #else
md5_context_t _ctx; md5_context_t _ctx;
#endif #endif
uint8_t i; uint8_t i;
uint8_t * _buf = (uint8_t*)malloc(16); uint8_t * _buf = (uint8_t*)malloc(16);
if(_buf == NULL) if(_buf == NULL)
return false; return false;
memset(_buf, 0x00, 16); memset(_buf, 0x00, 16);
#ifdef ESP32 #ifdef ESP32
mbedtls_md5_init(&_ctx); mbedtls_md5_init(&_ctx);
mbedtls_md5_update_ret (&_ctx,data,len); mbedtls_md5_update_ret (&_ctx,data,len);
mbedtls_md5_finish_ret(&_ctx,data); mbedtls_md5_finish_ret(&_ctx,data);
mbedtls_internal_md5_process( &_ctx ,data); mbedtls_internal_md5_process( &_ctx ,data);
#else #else
MD5Init(&_ctx); MD5Init(&_ctx);
MD5Update(&_ctx, data, len); MD5Update(&_ctx, data, len);
MD5Final(_buf, &_ctx); MD5Final(_buf, &_ctx);
#endif #endif
for(i = 0; i < 16; i++) { for(i = 0; i < 16; i++) {
sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]); sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]);
} }
free(_buf); free(_buf);
return true; return true;
} }
static String genRandomMD5(){ static String genRandomMD5(){
#ifdef ESP8266 #ifdef ESP8266
uint32_t r = RANDOM_REG32; uint32_t r = RANDOM_REG32;
#else #else
uint32_t r = rand(); uint32_t r = rand();
#endif #endif
char * out = (char*)malloc(33); char * out = (char*)malloc(33);
if(out == NULL || !getMD5((uint8_t*)(&r), 4, out)) if(out == NULL || !getMD5((uint8_t*)(&r), 4, out))
return emptyString; return emptyString;
String res = String(out); String res = String(out);
free(out); free(out);
return res; return res;
} }
static String stringMD5(const String& in){ static String stringMD5(const String& in){
char * out = (char*)malloc(33); char * out = (char*)malloc(33);
if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out))
return emptyString; return emptyString;
String res = String(out); String res = String(out);
free(out); free(out);
return res; return res;
} }
String generateDigestHash(const char * username, const char * password, const char * realm){ String generateDigestHash(const char * username, const char * password, const char * realm){
if(username == NULL || password == NULL || realm == NULL){ if(username == NULL || password == NULL || realm == NULL){
return emptyString; return emptyString;
} }
char * out = (char*)malloc(33); char * out = (char*)malloc(33);
String res = String(username); String res = String(username);
res += ':'; res += ':';
res.concat(realm); res.concat(realm);
res += ':'; res += ':';
String in = res; String in = res;
in.concat(password); in.concat(password);
if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out))
return emptyString; return emptyString;
res.concat(out); res.concat(out);
free(out); free(out);
return res; return res;
} }
String requestDigestAuthentication(const char * realm){ String requestDigestAuthentication(const char * realm){
String header = F("realm=\""); String header = F("realm=\"");
if(realm == NULL) if(realm == NULL)
header.concat(F("asyncesp")); header.concat(F("asyncesp"));
else else
header.concat(realm); header.concat(realm);
header.concat(F("\", qop=\"auth\", nonce=\"")); header.concat(F("\", qop=\"auth\", nonce=\""));
header.concat(genRandomMD5()); header.concat(genRandomMD5());
header.concat(F("\", opaque=\"")); header.concat(F("\", opaque=\""));
header.concat(genRandomMD5()); header.concat(genRandomMD5());
header += '"'; header += '"';
return header; return header;
} }
bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri){ bool checkDigestAuthentication(const char * header, const char *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri){
if(username == NULL || password == NULL || header == NULL || method == NULL){ if(username == NULL || password == NULL || header == NULL || method == NULL){
//os_printf("AUTH FAIL: missing requred fields\n"); //os_printf("AUTH FAIL: missing requred fields\n");
return false; return false;
} }
String myHeader = String(header); String myHeader = String(header);
int nextBreak = myHeader.indexOf(','); int nextBreak = myHeader.indexOf(',');
if(nextBreak < 0){ if(nextBreak < 0){
//os_printf("AUTH FAIL: no variables\n"); //os_printf("AUTH FAIL: no variables\n");
return false; return false;
} }
String myUsername = String(); String myUsername = String();
String myRealm = String(); String myRealm = String();
String myNonce = String(); String myNonce = String();
String myUri = String(); String myUri = String();
String myResponse = String(); String myResponse = String();
String myQop = String(); String myQop = String();
String myNc = String(); String myNc = String();
String myCnonce = String(); String myCnonce = String();
myHeader += F(", "); myHeader += F(", ");
do { do {
String avLine = myHeader.substring(0, nextBreak); String avLine = myHeader.substring(0, nextBreak);
avLine.trim(); avLine.trim();
myHeader = myHeader.substring(nextBreak+1); myHeader = myHeader.substring(nextBreak+1);
nextBreak = myHeader.indexOf(','); nextBreak = myHeader.indexOf(',');
int eqSign = avLine.indexOf('='); int eqSign = avLine.indexOf('=');
if(eqSign < 0){ if(eqSign < 0){
//os_printf("AUTH FAIL: no = sign\n"); //os_printf("AUTH FAIL: no = sign\n");
return false; return false;
} }
String varName = avLine.substring(0, eqSign); String varName = avLine.substring(0, eqSign);
avLine = avLine.substring(eqSign + 1); avLine = avLine.substring(eqSign + 1);
if(avLine.startsWith(String('"'))){ if(avLine.startsWith(String('"'))){
avLine = avLine.substring(1, avLine.length() - 1); avLine = avLine.substring(1, avLine.length() - 1);
} }
if(varName.equals(F("username"))){ if(varName.equals(F("username"))){
if(!avLine.equals(username)){ if(!avLine.equals(username)){
//os_printf("AUTH FAIL: username\n"); //os_printf("AUTH FAIL: username\n");
return false; return false;
} }
myUsername = avLine; myUsername = avLine;
} else if(varName.equals(F("realm"))){ } else if(varName.equals(F("realm"))){
if(realm != NULL && !avLine.equals(realm)){ if(realm != NULL && !avLine.equals(realm)){
//os_printf("AUTH FAIL: realm\n"); //os_printf("AUTH FAIL: realm\n");
return false; return false;
} }
myRealm = avLine; myRealm = avLine;
} else if(varName.equals(F("nonce"))){ } else if(varName.equals(F("nonce"))){
if(nonce != NULL && !avLine.equals(nonce)){ if(nonce != NULL && !avLine.equals(nonce)){
//os_printf("AUTH FAIL: nonce\n"); //os_printf("AUTH FAIL: nonce\n");
return false; return false;
} }
myNonce = avLine; myNonce = avLine;
} else if(varName.equals(F("opaque"))){ } else if(varName.equals(F("opaque"))){
if(opaque != NULL && !avLine.equals(opaque)){ if(opaque != NULL && !avLine.equals(opaque)){
//os_printf("AUTH FAIL: opaque\n"); //os_printf("AUTH FAIL: opaque\n");
return false; return false;
} }
} else if(varName.equals(F("uri"))){ } else if(varName.equals(F("uri"))){
if(uri != NULL && !avLine.equals(uri)){ if(uri != NULL && !avLine.equals(uri)){
//os_printf("AUTH FAIL: uri\n"); //os_printf("AUTH FAIL: uri\n");
return false; return false;
} }
myUri = avLine; myUri = avLine;
} else if(varName.equals(F("response"))){ } else if(varName.equals(F("response"))){
myResponse = avLine; myResponse = avLine;
} else if(varName.equals(F("qop"))){ } else if(varName.equals(F("qop"))){
myQop = avLine; myQop = avLine;
} else if(varName.equals(F("nc"))){ } else if(varName.equals(F("nc"))){
myNc = avLine; myNc = avLine;
} else if(varName.equals(F("cnonce"))){ } else if(varName.equals(F("cnonce"))){
myCnonce = avLine; myCnonce = avLine;
} }
} while(nextBreak > 0); } while(nextBreak > 0);
String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + String(password)); String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + String(password));
String ha2 = String(method) + ':' + myUri; String ha2 = String(method) + ':' + myUri;
String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + stringMD5(ha2); String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + stringMD5(ha2);
if(myResponse.equals(stringMD5(response))){ if(myResponse.equals(stringMD5(response))){
//os_printf("AUTH SUCCESS\n"); //os_printf("AUTH SUCCESS\n");
return true; return true;
} }
//os_printf("AUTH FAIL: password\n"); //os_printf("AUTH FAIL: password\n");
return false; return false;
} }

View File

@@ -26,7 +26,7 @@
bool checkBasicAuthentication(const char * header, const char * username, const char * password); bool checkBasicAuthentication(const char * header, const char * username, const char * password);
String requestDigestAuthentication(const char * realm); String requestDigestAuthentication(const char * realm);
bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); bool checkDigestAuthentication(const char * header, const char *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri);
//for storing hashed versions on the device that can be authenticated against //for storing hashed versions on the device that can be authenticated against
String generateDigestHash(const char * username, const char * password, const char * realm); String generateDigestHash(const char * username, const char * password, const char * realm);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff