| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -446,7 +446,7 @@ void HTTPConnection::loop() { | |||
| 446 | 446 | } | |
| 447 | 447 | ||
| 448 | 448 | // Create request context | |
| 449 | - HTTPRequest req = HTTPRequest(this, _httpHeaders, resolvedResource.getParams(), _httpResource, _httpMethod, resolvedResource.getMatchingNode()->_tag); | ||
| 449 | + HTTPRequest req = HTTPRequest(this, _httpHeaders, resolvedResource.getMatchingNode(), resolvedResource.getParams(), _httpResource); | ||
| 450 | 450 | HTTPResponse res = HTTPResponse(this); | |
| 451 | 451 | ||
| 452 | 452 | // Add default headers to the response | |
@@ -477,6 +477,10 @@ void HTTPConnection::loop() { | |||
| 477 | 477 | next = std::function<void()>(std::bind((*itMw), &req, &res, next)); | |
| 478 | 478 | itMw++; | |
| 479 | 479 | } | |
| 480 | + | ||
| 481 | + // We insert the internal validation middleware at the start of the chain: | ||
| 482 | + next = std::function<void()>(std::bind(&validationMiddleware, &req, &res, next)); | ||
| 483 | + | ||
| 480 | 484 | // Call the whole chain | |
| 481 | 485 | next(); | |
| 482 | 486 | ||
@@ -581,6 +585,32 @@ bool HTTPConnection::checkWebsocket() { | |||
| 581 | 585 | return false; | |
| 582 | 586 | } | |
| 583 | 587 | ||
| 588 | + /** | ||
| 589 | + * Middleware function that handles the validation of parameters | ||
| 590 | + */ | ||
| 591 | + void validationMiddleware(HTTPRequest * req, HTTPResponse * res, std::function<void()> next) { | ||
| 592 | + bool valid = true; | ||
| 593 | + // Get the matched node | ||
| 594 | + HTTPNode * node = req->getResolvedNode(); | ||
| 595 | + // Get the parameters | ||
| 596 | + ResourceParameters * params = req->getParams(); | ||
| 597 | + | ||
| 598 | + // Iterate over the validators and run them | ||
| 599 | + std::vector<HTTPValidator*> * validators = node->getValidators(); | ||
| 600 | + for(std::vector<HTTPValidator*>::iterator validator = validators->begin(); valid && validator != validators->end(); ++validator) { | ||
| 601 | + std::string param = params->getUrlParameter((*validator)->_idx); | ||
| 602 | + valid = ((*validator)->_validatorFunction)(param); | ||
| 603 | + } | ||
| 604 | + | ||
| 605 | + if (valid) { | ||
| 606 | + next(); | ||
| 607 | + } else { | ||
| 608 | + res->setStatusCode(400); | ||
| 609 | + res->setStatusText("Bad Request"); | ||
| 610 | + res->print("400 Bad Request"); | ||
| 611 | + } | ||
| 612 | + } | ||
| 613 | + | ||
| 584 | 614 | /** | |
| 585 | 615 | * Handler function for the websocket handshake. Will be used by HTTPConnection if a websocket is detected | |
| 586 | 616 | */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -163,6 +163,8 @@ void handleWebsocketHandshake(HTTPRequest * req, HTTPResponse * res); | |||
| 163 | 163 | ||
| 164 | 164 | std::string websocketKeyResponseHash(std::string key); | |
| 165 | 165 | ||
| 166 | + void validationMiddleware(HTTPRequest * req, HTTPResponse * res, std::function<void()> next); | ||
| 167 | + | ||
| 166 | 168 | } /* namespace httpsserver */ | |
| 167 | 169 | ||
| 168 | 170 | #endif /* SRC_HTTPCONNECTION_HPP_ */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,9 @@ namespace httpsserver { | |||
| 7 | 7 | _tag(std::move(tag)), | |
| 8 | 8 | _nodeType(nodeType) { | |
| 9 | 9 | ||
| 10 | + // Create vector for valdiators | ||
| 11 | + _validators = new std::vector<HTTPValidator*>(); | ||
| 12 | + | ||
| 10 | 13 | // Count the parameters | |
| 11 | 14 | _urlParamCount = 0; | |
| 12 | 15 | size_t idx = 0; | |
@@ -32,6 +35,12 @@ namespace httpsserver { | |||
| 32 | 35 | if (_urlParamIdx != NULL) { | |
| 33 | 36 | delete[] _urlParamIdx; | |
| 34 | 37 | } | |
| 38 | + | ||
| 39 | + // Delete validator references | ||
| 40 | + for(std::vector<HTTPValidator*>::iterator validator = _validators->begin(); validator != _validators->end(); ++validator) { | ||
| 41 | + delete *validator; | ||
| 42 | + } | ||
| 43 | + delete _validators; | ||
| 35 | 44 | } | |
| 36 | 45 | ||
| 37 | 46 | bool HTTPNode::hasUrlParameter() { | |
@@ -49,4 +58,12 @@ namespace httpsserver { | |||
| 49 | 58 | uint8_t HTTPNode::getUrlParamCount() { | |
| 50 | 59 | return _urlParamCount; | |
| 51 | 60 | } | |
| 61 | + | ||
| 62 | + void HTTPNode::addURLParamValidator(uint8_t paramIdx, const HTTPValidationFunction * validator) { | ||
| 63 | + _validators->push_back(new HTTPValidator(paramIdx, validator)); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + std::vector<HTTPValidator*> * HTTPNode::getValidators() { | ||
| 67 | + return _validators; | ||
| 68 | + } | ||
| 52 | 69 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | 4 | #include <Arduino.h> | |
| 5 | 5 | #include <string> | |
| 6 | + #undef min | ||
| 7 | + #undef max | ||
| 8 | + #include <vector> | ||
| 9 | + #include "HTTPValidator.hpp" | ||
| 6 | 10 | ||
| 7 | 11 | namespace httpsserver { | |
| 8 | 12 | ||
@@ -37,9 +41,21 @@ class HTTPNode { | |||
| 37 | 41 | uint8_t getUrlParamCount(); | |
| 38 | 42 | size_t getParamIdx(uint8_t); | |
| 39 | 43 | ||
| 44 | + std::vector<HTTPValidator*> * getValidators(); | ||
| 45 | + | ||
| 46 | + virtual std::string getMethod() = 0; | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * Adds a validation function that checks if the actual value of a parameter matches the expectation | ||
| 50 | + * @param paramIdx defines the ID of the parameter that should be checked (starts by 0) | ||
| 51 | + * @param validator the function (string -> bool) that checks if the parameter matches the expecatation | ||
| 52 | + */ | ||
| 53 | + void addURLParamValidator(uint8_t paramIdx, const HTTPValidationFunction * validator); | ||
| 54 | + | ||
| 40 | 55 | private: | |
| 41 | 56 | uint8_t _urlParamCount; | |
| 42 | 57 | size_t * _urlParamIdx; | |
| 58 | + std::vector<HTTPValidator*> * _validators; | ||
| 43 | 59 | }; | |
| 44 | 60 | ||
| 45 | 61 | } // namespace httpserver | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,13 +2,17 @@ | |||
| 2 | 2 | ||
| 3 | 3 | namespace httpsserver { | |
| 4 | 4 | ||
| 5 | - HTTPRequest::HTTPRequest(ConnectionContext * con, HTTPHeaders * headers, ResourceParameters * params, std::string requestString, std::string method, std::string tag): | ||
| 5 | + HTTPRequest::HTTPRequest( | ||
| 6 | + ConnectionContext * con, | ||
| 7 | + HTTPHeaders * headers, | ||
| 8 | + HTTPNode * resolvedNode, | ||
| 9 | + ResourceParameters * params, | ||
| 10 | + std::string requestString): | ||
| 6 | 11 | _con(con), | |
| 7 | 12 | _headers(headers), | |
| 13 | + _resolvedNode(resolvedNode), | ||
| 8 | 14 | _params(params), | |
| 9 | - _requestString(requestString), | ||
| 10 | - _method(method), | ||
| 11 | - _tag(tag) { | ||
| 15 | + _requestString(requestString) { | ||
| 12 | 16 | ||
| 13 | 17 | HTTPHeader * contentLength = headers->get("Content-Length"); | |
| 14 | 18 | if (contentLength == NULL) { | |
@@ -43,6 +47,10 @@ void HTTPRequest::setHeader(std::string name, std::string value) { | |||
| 43 | 47 | _headers->set(new HTTPHeader(name, value)); | |
| 44 | 48 | } | |
| 45 | 49 | ||
| 50 | + HTTPNode * HTTPRequest::getResolvedNode() { | ||
| 51 | + return _resolvedNode; | ||
| 52 | + } | ||
| 53 | + | ||
| 46 | 54 | size_t HTTPRequest::readBytes(byte * buffer, size_t length) { | |
| 47 | 55 | ||
| 48 | 56 | // Limit reading to content length | |
@@ -72,11 +80,11 @@ std::string HTTPRequest::getRequestString() { | |||
| 72 | 80 | } | |
| 73 | 81 | ||
| 74 | 82 | std::string HTTPRequest::getMethod() { | |
| 75 | - return _method; | ||
| 83 | + return _resolvedNode->getMethod(); | ||
| 76 | 84 | } | |
| 77 | 85 | ||
| 78 | 86 | std::string HTTPRequest::getTag() { | |
| 79 | - return _tag; | ||
| 87 | + return _resolvedNode->_tag; | ||
| 80 | 88 | } | |
| 81 | 89 | ||
| 82 | 90 | bool HTTPRequest::requestComplete() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ | |||
| 7 | 7 | #include <mbedtls/base64.h> | |
| 8 | 8 | ||
| 9 | 9 | #include "ConnectionContext.hpp" | |
| 10 | + #include "HTTPNode.hpp" | ||
| 10 | 11 | #include "HTTPHeader.hpp" | |
| 11 | 12 | #include "HTTPHeaders.hpp" | |
| 12 | 13 | #include "ResourceParameters.hpp" | |
@@ -16,11 +17,12 @@ namespace httpsserver { | |||
| 16 | 17 | ||
| 17 | 18 | class HTTPRequest { | |
| 18 | 19 | public: | |
| 19 | - HTTPRequest(ConnectionContext * con, HTTPHeaders * headers, ResourceParameters * resource, std::string requestString, std::string method, std::string tag); | ||
| 20 | + HTTPRequest(ConnectionContext * con, HTTPHeaders * headers, HTTPNode * resolvedNode, ResourceParameters * params, std::string requestString); | ||
| 20 | 21 | virtual ~HTTPRequest(); | |
| 21 | 22 | ||
| 22 | 23 | std::string getHeader(std::string name); | |
| 23 | 24 | void setHeader(std::string name, std::string value); | |
| 25 | + HTTPNode * getResolvedNode(); | ||
| 24 | 26 | std::string getRequestString(); | |
| 25 | 27 | std::string getMethod(); | |
| 26 | 28 | std::string getTag(); | |
@@ -43,11 +45,11 @@ class HTTPRequest { | |||
| 43 | 45 | ||
| 44 | 46 | HTTPHeaders * _headers; | |
| 45 | 47 | ||
| 48 | + HTTPNode * _resolvedNode; | ||
| 49 | + | ||
| 46 | 50 | ResourceParameters * _params; | |
| 47 | 51 | ||
| 48 | 52 | std::string _requestString; | |
| 49 | - std::string _method; | ||
| 50 | - std::string _tag; | ||
| 51 | 53 | ||
| 52 | 54 | bool _contentLengthSet; | |
| 53 | 55 | size_t _remainingContent; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,15 @@ | |||
| 1 | + #include "HTTPValidator.hpp" | ||
| 2 | + | ||
| 3 | + namespace httpsserver { | ||
| 4 | + | ||
| 5 | + HTTPValidator::HTTPValidator(const uint8_t idx, const HTTPValidationFunction * validatorFunction): | ||
| 6 | + _idx(idx), | ||
| 7 | + _validatorFunction(validatorFunction) { | ||
| 8 | + | ||
| 9 | + } | ||
| 10 | + | ||
| 11 | + HTTPValidator::~HTTPValidator() { | ||
| 12 | + | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + } /* namespace httpsserver */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,20 @@ | |||
| 1 | + #ifndef SRC_HTTPVALIDATOR_HPP_ | ||
| 2 | + #define SRC_HTTPVALIDATOR_HPP_ | ||
| 3 | + | ||
| 4 | + #include <string> | ||
| 5 | + | ||
| 6 | + namespace httpsserver { | ||
| 7 | + | ||
| 8 | + typedef bool (HTTPValidationFunction)(std::string); | ||
| 9 | + | ||
| 10 | + class HTTPValidator { | ||
| 11 | + public: | ||
| 12 | + HTTPValidator(const uint8_t idx, const HTTPValidationFunction * validatorFunction); | ||
| 13 | + virtual ~HTTPValidator(); | ||
| 14 | + const uint8_t _idx; | ||
| 15 | + const HTTPValidationFunction * _validatorFunction; | ||
| 16 | + }; | ||
| 17 | + | ||
| 18 | + } /* namespace httpsserver */ | ||
| 19 | + | ||
| 20 | + #endif /* SRC_HTTPVALIDATOR_HPP_ */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,7 @@ class ResourceNode : public HTTPNode { | |||
| 15 | 15 | ||
| 16 | 16 | const std::string _method; | |
| 17 | 17 | const HTTPSCallbackFunction * _callback; | |
| 18 | + std::string getMethod() { return _method; } | ||
| 18 | 19 | }; | |
| 19 | 20 | ||
| 20 | 21 | } /* namespace httpsserver */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,7 @@ class WebsocketNode : public HTTPNode { | |||
| 15 | 15 | WebsocketNode(const std::string path, const WebsocketHandlerCreator creatorFunction, const std::string tag = ""); | |
| 16 | 16 | virtual ~WebsocketNode(); | |
| 17 | 17 | WebsocketHandler* newHandler(); | |
| 18 | + std::string getMethod() { return std::string("GET"); } | ||
| 18 | 19 | private: | |
| 19 | 20 | const WebsocketHandlerCreator * _creatorFunction; | |
| 20 | 21 | }; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments