123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- ESP32WebServer.h - Dead simple web-server.
- Supports only one simultaneous client, knows how to handle GET and POST.
- Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- 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,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
- */
- #ifndef ESP32WEBSERVER_H
- #define ESP32WEBSERVER_H
- #include <functional>
- #include <WiFi.h>
- enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
- enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
- UPLOAD_FILE_ABORTED };
- enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
- #define HTTP_DOWNLOAD_UNIT_SIZE 1460
- #define HTTP_UPLOAD_BUFLEN 2048
- #define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
- #define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
- #define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
- #define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
- #define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
- #define CONTENT_LENGTH_NOT_SET ((size_t) -2)
- class ESP32WebServer;
- typedef struct {
- HTTPUploadStatus status;
- String filename;
- String name;
- String type;
- size_t totalSize; // file size
- size_t currentSize; // size of data currently in buf
- uint8_t buf[HTTP_UPLOAD_BUFLEN];
- } HTTPUpload;
- #include "detail/RequestHandler.h"
- namespace fs {
- class FS;
- }
- class ESP32WebServer
- {
- public:
- ESP32WebServer(IPAddress addr, int port = 80);
- ESP32WebServer(int port = 80);
- ~ESP32WebServer();
- void begin();
- void handleClient();
- void close();
- void stop();
- bool authenticate(const char * username, const char * password);
- void requestAuthentication();
- typedef std::function<void(void)> THandlerFunction;
- void on(const String &uri, THandlerFunction handler);
- void on(const String &uri, HTTPMethod method, THandlerFunction fn);
- void on(const String &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
- void addHandler(RequestHandler* handler);
- void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
- void onNotFound(THandlerFunction fn); //called when handler is not assigned
- void onFileUpload(THandlerFunction fn); //handle file uploads
- String uri() { return _currentUri; }
- HTTPMethod method() { return _currentMethod; }
- WiFiClient client() { return _currentClient; }
- HTTPUpload& upload() { return _currentUpload; }
- String arg(String name); // get request argument value by name
- String arg(int i); // get request argument value by number
- String argName(int i); // get request argument name by number
- int args(); // get arguments count
- bool hasArg(String name); // check if argument exists
- void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect
- String header(String name); // get request header value by name
- String header(int i); // get request header value by number
- String headerName(int i); // get request header name by number
- int headers(); // get header count
- bool hasHeader(String name); // check if header exists
- String hostHeader(); // get request host header if available or empty String if not
- // send response to the client
- // code - HTTP response code, can be 200 or 404
- // content_type - HTTP content type, like "text/plain" or "image/png"
- // content - actual content body
- void send(int code, const char* content_type = NULL, const String& content = String(""));
- void send(int code, char* content_type, const String& content);
- void send(int code, const String& content_type, const String& content);
- void send_P(int code, PGM_P content_type, PGM_P content);
- void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);
- void setContentLength(size_t contentLength);
- void sendHeader(const String& name, const String& value, bool first = false);
- void sendContent(const String& content);
- void sendContent_P(PGM_P content);
- void sendContent_P(PGM_P content, size_t size);
- static String urlDecode(const String& text);
- template<typename T> size_t streamFile(T &file, const String& contentType){
- setContentLength(file.size());
- if (String(file.name()).endsWith(".gz") &&
- contentType != "application/x-gzip" &&
- contentType != "application/octet-stream"){
- sendHeader("Content-Encoding", "gzip");
- }
- send(200, contentType, "");
- uint8_t buf[20];
- size_t fsize = 0;
- while(file.available()){
- int got = file.read(buf, 20);
- _currentClient.write(buf, got);
- fsize += got;
- yield();
- }
- return fsize;
- }
- protected:
- void _addRequestHandler(RequestHandler* handler);
- void _handleRequest();
- bool _parseRequest(WiFiClient& client);
- void _parseArguments(String data);
- static String _responseCodeToString(int code);
- bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
- bool _parseFormUploadAborted();
- void _uploadWriteByte(uint8_t b);
- uint8_t _uploadReadByte(WiFiClient& client);
- void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
- bool _collectHeader(const char* headerName, const char* headerValue);
- struct RequestArgument {
- String key;
- String value;
- };
- WiFiServer _server;
- WiFiClient _currentClient;
- HTTPMethod _currentMethod;
- String _currentUri;
- uint8_t _currentVersion;
- HTTPClientStatus _currentStatus;
- unsigned long _statusChange;
- RequestHandler* _currentHandler;
- RequestHandler* _firstHandler;
- RequestHandler* _lastHandler;
- THandlerFunction _notFoundHandler;
- THandlerFunction _fileUploadHandler;
- int _currentArgCount;
- RequestArgument* _currentArgs;
- HTTPUpload _currentUpload;
- int _headerKeysCount;
- RequestArgument* _currentHeaders;
- size_t _contentLength;
- String _responseHeaders;
- String _hostHeader;
- bool _chunked;
- };
- #endif //ESP32WEBSERVER_H
|