ESP8266WebServer.h 6.5 KB

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