WebHandlerImpl.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. Asynchronous WebServer library for Espressif MCUs
  3. Copyright (c) 2016 Hristo Gochkov. All rights reserved.
  4. This file is part of the esp8266 core for Arduino environment.
  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. */
  17. #ifndef ASYNCWEBSERVERHANDLERIMPL_H_
  18. #define ASYNCWEBSERVERHANDLERIMPL_H_
  19. #include <string>
  20. #ifdef ASYNCWEBSERVER_REGEX
  21. #include <regex>
  22. #endif
  23. #include "stddef.h"
  24. #include <time.h>
  25. class AsyncStaticWebHandler: public AsyncWebHandler {
  26. using File = fs::File;
  27. using FS = fs::FS;
  28. private:
  29. bool _getFile(AsyncWebServerRequest *request);
  30. bool _fileExists(AsyncWebServerRequest *request, const String& path);
  31. uint8_t _countBits(const uint8_t value) const;
  32. protected:
  33. FS _fs;
  34. String _uri;
  35. String _path;
  36. String _default_file;
  37. String _cache_control;
  38. String _last_modified;
  39. AwsTemplateProcessor _callback;
  40. bool _isDir;
  41. bool _gzipFirst;
  42. uint8_t _gzipStats;
  43. public:
  44. AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control);
  45. virtual bool canHandle(AsyncWebServerRequest *request) override final;
  46. virtual void handleRequest(AsyncWebServerRequest *request) override final;
  47. AsyncStaticWebHandler& setIsDir(bool isDir);
  48. AsyncStaticWebHandler& setDefaultFile(const char* filename);
  49. AsyncStaticWebHandler& setCacheControl(const char* cache_control);
  50. AsyncStaticWebHandler& setLastModified(const char* last_modified);
  51. AsyncStaticWebHandler& setLastModified(struct tm* last_modified);
  52. #ifdef ESP8266
  53. AsyncStaticWebHandler& setLastModified(time_t last_modified);
  54. AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated
  55. #endif
  56. AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) {_callback = newCallback; return *this;}
  57. };
  58. class AsyncCallbackWebHandler: public AsyncWebHandler {
  59. private:
  60. protected:
  61. String _uri;
  62. WebRequestMethodComposite _method;
  63. ArRequestHandlerFunction _onRequest;
  64. ArUploadHandlerFunction _onUpload;
  65. ArBodyHandlerFunction _onBody;
  66. bool _isRegex;
  67. public:
  68. AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
  69. void setUri(const String& uri){
  70. _uri = uri;
  71. _isRegex = uri.startsWith("^") && uri.endsWith("$");
  72. }
  73. void setMethod(WebRequestMethodComposite method){ _method = method; }
  74. void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; }
  75. void onUpload(ArUploadHandlerFunction fn){ _onUpload = fn; }
  76. void onBody(ArBodyHandlerFunction fn){ _onBody = fn; }
  77. virtual bool canHandle(AsyncWebServerRequest *request) override final{
  78. if(!_onRequest)
  79. return false;
  80. if(!(_method & request->method()))
  81. return false;
  82. #ifdef ASYNCWEBSERVER_REGEX
  83. if (_isRegex) {
  84. std::regex pattern(_uri.c_str());
  85. std::smatch matches;
  86. std::string s(request->url().c_str());
  87. if(std::regex_search(s, matches, pattern)) {
  88. for (size_t i = 1; i < matches.size(); ++i) { // start from 1
  89. request->_addPathParam(matches[i].str().c_str());
  90. }
  91. } else {
  92. return false;
  93. }
  94. } else
  95. #endif
  96. if (_uri.length() && _uri.startsWith("/*.")) {
  97. String uriTemplate = String (_uri);
  98. uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf("."));
  99. if (!request->url().endsWith(uriTemplate))
  100. return false;
  101. }
  102. else
  103. if (_uri.length() && _uri.endsWith("*")) {
  104. String uriTemplate = String(_uri);
  105. uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1);
  106. if (!request->url().startsWith(uriTemplate))
  107. return false;
  108. }
  109. else if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
  110. return false;
  111. request->addInterestingHeader("ANY");
  112. return true;
  113. }
  114. virtual void handleRequest(AsyncWebServerRequest *request) override final {
  115. if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str()))
  116. return request->requestAuthentication();
  117. if(_onRequest)
  118. _onRequest(request);
  119. else
  120. request->send(500);
  121. }
  122. virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final {
  123. if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str()))
  124. return request->requestAuthentication();
  125. if(_onUpload)
  126. _onUpload(request, filename, index, data, len, final);
  127. }
  128. virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
  129. if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str()))
  130. return request->requestAuthentication();
  131. if(_onBody)
  132. _onBody(request, data, len, index, total);
  133. }
  134. virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;}
  135. };
  136. #endif /* ASYNCWEBSERVERHANDLERIMPL_H_ */