ESP_IOT v2.5
IOT ESP Coding
WebServer.h
Go to the documentation of this file.
1/*
2 WebServer.h - Dead simple web-server.
3 Supports only one simultaneous client, knows how to handle GET and POST.
4
5 Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
21*/
22
23
24#ifndef WEBSERVER_H
25#define WEBSERVER_H
26#include "../../Defines.h"
27#ifdef USE_LIB_WEBSERVER
28#else
29
30#include <functional>
31#ifdef USE_REST_MESSAGING
32#include <WiFiClientSecure.h>
33#else
34#include <WiFi.h>
35#endif
36#include <Update.h>
37#include <WiFiUdp.h>
38
39enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
40enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
41 UPLOAD_FILE_ABORTED };
42enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
43
44#define HTTP_DOWNLOAD_UNIT_SIZE 1460
45#define HTTP_UPLOAD_BUFLEN 2048
46#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
47#define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
48#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
49#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
50
51#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
52#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
53
54class WebServer;
55
56typedef struct {
57 HTTPUploadStatus status;
58 String filename;
59 String name;
60 String type;
61 size_t totalSize; // file size
62 size_t currentSize; // size of data currently in buf
63 uint8_t buf[HTTP_UPLOAD_BUFLEN];
64} HTTPUpload;
65
66#include "RequestHandler.h"
67
68namespace fs {
69class FS;
70}
71
72class WebServer
73{
74public:
75 WebServer(IPAddress addr, int port = 80);
76 WebServer(int port = 80);
77 ~WebServer();
78
79 void begin();
80 void handleClient();
81
82 void close();
83 void stop();
84
85 bool authenticate(const char * username, const char * password);
86 void requestAuthentication();
87
88 typedef std::function<void(void)> THandlerFunction;
89 void on(const String &uri, THandlerFunction handler);
90 void on(const String &uri, HTTPMethod method, THandlerFunction fn);
91 void on(const String &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
92 void addHandler(RequestHandler* handler);
93 void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
94 void onNotFound(THandlerFunction fn); //called when handler is not assigned
95 void onFileUpload(THandlerFunction fn); //handle file uploads
96
97 String uri() { return _currentUri; }
98 HTTPMethod method() { return _currentMethod; }
99 WiFiClient client() { return _currentClient; }
100 HTTPUpload& upload() { return _currentUpload; }
101
102 String arg(String name); // get request argument value by name
103 String arg(int i); // get request argument value by number
104 String argName(int i); // get request argument name by number
105 int args(); // get arguments count
106 bool hasArg(String name); // check if argument exists
107 void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect
108 String header(String name); // get request header value by name
109 String header(int i); // get request header value by number
110 String headerName(int i); // get request header name by number
111 int headers(); // get header count
112 bool hasHeader(String name); // check if header exists
113
114 String hostHeader(); // get request host header if available or empty String if not
115
116 // send response to the client
117 // code - HTTP response code, can be 200 or 404
118 // content_type - HTTP content type, like "text/plain" or "image/png"
119 // content - actual content body
120 void send(int code, const char* content_type = NULL, const String& content = String(""));
121 void send(int code, char* content_type, const String& content);
122 void send(int code, const String& content_type, const String& content);
123 void send_P(int code, PGM_P content_type, PGM_P content);
124 void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);
125
126 void setContentLength(size_t contentLength);
127 void sendHeader(const String& name, const String& value, bool first = false);
128 void sendContent(const String& content);
129 void sendContent_P(PGM_P content);
130 void sendContent_P(PGM_P content, size_t size);
131
132 static String urlDecode(const String& text);
133
134template<typename T> size_t streamFile(T &file, const String& contentType){
135 setContentLength(file.size());
136 if (String(file.name()).endsWith(".gz") &&
137 contentType != "application/x-gzip" &&
138 contentType != "application/octet-stream"){
139 sendHeader("Content-Encoding", "gzip");
140 }
141 send(200, contentType, "");
142 return _currentClient.write(file);
143}
144
145protected:
146 void _addRequestHandler(RequestHandler* handler);
147 void _handleRequest();
148 bool _parseRequest(WiFiClient& client);
149 void _parseArguments(String data);
150 static String _responseCodeToString(int code);
151 bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
152 bool _parseFormUploadAborted();
153 void _uploadWriteByte(uint8_t b);
154 uint8_t _uploadReadByte(WiFiClient& client);
155 void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
156 bool _collectHeader(const char* headerName, const char* headerValue);
157
158 struct RequestArgument {
159 String key;
160 String value;
161 };
162
163 WiFiServer _server;
164
165 WiFiClient _currentClient;
166 HTTPMethod _currentMethod;
167 String _currentUri;
168 uint8_t _currentVersion;
169 HTTPClientStatus _currentStatus;
170 unsigned long _statusChange;
171
172 RequestHandler* _currentHandler;
173 RequestHandler* _firstHandler;
174 RequestHandler* _lastHandler;
175 THandlerFunction _notFoundHandler;
176 THandlerFunction _fileUploadHandler;
177
178 int _currentArgCount;
179 RequestArgument* _currentArgs;
180 HTTPUpload _currentUpload;
181
182 int _headerKeysCount;
183 RequestArgument* _currentHeaders;
184 size_t _contentLength;
185 String _responseHeaders;
186
187 String _hostHeader;
188 bool _chunked;
189
190};
191
192#endif
193#endif //WebServer_H
long _contentLength