10000 Added request parameters (like /resource?param=val) · gmos/esp32_https_server@cd070bd · GitHub
[go: up one dir, main page]

Skip to content

Commit cd070bd

Browse files
committed
Added request parameters (like /resource?param=val)
1 parent 7208938 commit cd070bd

File tree

4 files changed

+83
-19
lines changed

4 files changed

+83
-19
lines changed

https/ResourceParameters.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,35 @@ ResourceParameters::~ResourceParameters() {
1717

1818
}
1919

20+
bool ResourceParameters::isRequestParameterSet(std::string &name) {
21+
for(auto reqParam = _reqParams.begin(); reqParam != _reqParams.end(); ++reqParam) {
22+
if ((*reqParam).first.compare(name)==0) {
23+
return true;
24+
}
25+
}
26+
return false;
27+
}
2028

2129
std::string ResourceParameters::getRequestParameter(std::string &name) {
30+
for(auto reqParam = _reqParams.begin(); reqParam != _reqParams.end(); ++reqParam) {
31+
if ((*reqParam).first.compare(name)==0) {
32+
return (*reqParam).second;
33+
}
34+
}
2235
return "";
2336
}
2437

2538
uint16_t ResourceParameters::getRequestParameterInt(std::string &name) {
2639
return parseInt(getRequestParameter(name));
2740
}
2841

42+
void ResourceParameters::setRequestParameter(std::string name, std::string value) {
43+
std::pair<std::string, std::string> param;
44+
param.first = std::move(name);
45+
param.second = std::move(value);
46+
_reqParams.push_back(param);
47+
}
48+
2949
/**
3050
* Returns an URL parameter as string.
3151
*

https/ResourceParameters.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,23 @@
1515
#undef min
1616
#undef max
1717
#include <vector>
18+
#include <utility>
1819

1920
#include "util.hpp"
2021

2122
namespace httpsserver {
2223

24+
struct requestparam_t {std::string name; std::string value;};
25+
2326
class ResourceParameters {
2427
public:
2528
ResourceParameters();
2629
virtual ~ResourceParameters();
2730

31+
bool isRequestParameterSet(std::string &name);
2832
std::string getRequestParameter(std::string &name);
2933
uint16_t getRequestParameterInt(std::string &name);
34+
void setRequestParameter(std::string name, std::string value);
3035

3136
std::string getUrlParameter(uint8_t idx);
3237
uint16_t getUrlParameterInt(uint8_t idx);
@@ -36,6 +41,7 @@ class ResourceParameters {
3641

3742
private:
3843
std::vector<std::string> _urlParams;
44+
std::vector<std::pair<std::string, std::string>> _reqParams;
3945
};
4046

4147
} /* namespace httpsserver */

https/ResourceResolver.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,43 @@ void ResourceResolver::resolveNode(const std::string &method, const std::string
4040
// Memory management of this object will be performed by the ResolvedResource instance
4141
ResourceParameters * params = new ResourceParameters();
4242

43-
// TODO: Split URL in resource name and request params, set request params in params object
44-
std::string resourceName = url;
43+
// Split URL in resource name and request params. Request params start after an optional '?'
44+
size_t reqparamIdx = url.find('?');
45+
46+
// If no '?' is contained in url, 0:npos will return the string as it is
47+
std::string resourceName = url.substr(0, reqparamIdx);
48+
49+
// Set request params in params object if a '?' exists
50+
if (reqparamIdx != std::string::npos) {
51+
do {
52+
// Drop the '?' or '&'
53+
reqparamIdx += 1;
54+
55+
// Parameters are separated by '&'
56+
size_t nextparamIdx = url.find('&', reqparamIdx);
57+
58+
// Get the "name=value" string
59+
std::string param = url.substr(reqparamIdx, nextparamIdx - reqparamIdx);
60+
61+
// Find the position where the string has to be split
62+
size_t nvSplitIdx = param.find('=');
63+
64+
// Use empty string if only name is set. /foo?bar&baz=1 will return "" for bar
65+
std::string name = param.substr(0, nvSplitIdx);
66+
std::string value = "";
67+
if (nvSplitIdx != std::string::npos) {
68+
// TODO: There may be url encoding in here.
69+
value = param.substr(nvSplitIdx+1);
70+
}
71+
72+
// Now we finally have name and value.
73+
params->setRequestParameter(name, value);
74+
75+
// Update reqparamIdx
76+
reqparamIdx = nextparamIdx;
77+
78+
} while(reqparamIdx != std::string::npos);
79+
}
4580

4681

4782
// Check whether a resource matches

https_server.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ void testCallback(HTTPRequest * req, HTTPResponse * res) {
2828
res->println("<h1>Hello world!</h1>");
2929
res->println("<p>... from your ESP32</p>");
3030
// The image resource is created in the awesomeCallback some lines below
31-
res->println("<img src=\"images/fede58/awesome.svg\" alt=\"Awesome face\" style=\"width:250px;\" />");
32-
res->println("<img src=\"images/de58fe/awesome.svg\" alt=\"Awesome face\" style=\"width:250px;\" />");
33-
res->println("<img src=\"images/58fede/awesome.svg\" alt=\"Awesome face\" style=\"width:250px;\" />");
31+
res->println("<img src=\"images/awesome.svg\" alt=\"Awesome face\" style=\"width:250px;\" />");
32+
res->println("<img src=\"images/awesome.svg?color=de58fe\" alt=\"Awesome face\" style=\"width:250px;\" />");
33+
res->println("<img src=\"images/awesome.svg?color=58fede\" alt=\"Awesome face\" style=\"width:250px;\" />");
3434
res->print("<p>System has been up for ");
3535
res->print((int)(millis()/1000), DEC);
3636
res->println(" seconds.</p>");
@@ -91,20 +91,23 @@ void awesomeCallback(HTTPRequest * req, HTTPResponse * res) {
9191
// Check if there is a suitabel fill color in the parameter:
9292
std::string fillColor = "fede58";
9393

94-
//FIXME: Turn this into a request param
95-
std::string requestColor = params->getUrlParameter(0);
96-
if (requestColor.length()==6) {
97-
bool colorOk = true;
98-
for(int i = 1; i < 6 && colorOk; i++) {
99-
if (!(
100-
(requestColor[i]>='0' && requestColor[i]<='9' ) ||
101-
(requestColor[i]>='a' && requestColor[i]<='f' )
102-
)) {
103-
colorOk = false;
94+
// Get request parameter
95+
std::string colorParamName = "color";
96+
if (params->isRequestParameterSet(colorParamName)) {
97+
std::string requestColor = params->getRequestParameter(colorParamName);
98+
if (requestColor.length()==6) {
99+
bool colorOk = true;
100+
for(int i = 1; i < 6 && colorOk; i++) {
101+
if (!(
102+
(requestColor[i]>='0' && requestColor[i]<='9' ) ||
103+
(requestColor[i]>='a' && requestColor[i]<='f' )
104+
)) {
105+
colorOk = false;
106+
}
107+
}
108+
if (colorOk) {
109+
fillColor = requestColor;
104110
}
105-
}
106-
if (colorOk) {
107-
fillColor = requestColor;
108111
}
109112
}
110113

@@ -209,7 +212,7 @@ void serverTask(void *params) {
209212
ResourceNode faviconNode = ResourceNode("/favicon.ico", "GET", &faviconCallback);
210213

211214
// The awesomeCallback is very similar to the favicon.
212-
ResourceNode awesomeNode = ResourceNode("/images/*/awesome.svg", "GET", &awesomeCallback);
215+
ResourceNode awesomeNode = ResourceNode("/images/awesome.svg", "GET", &awesomeCallback);
213216

214217
// A simple callback showing URL parameters. Every asterisk (*) is a placeholder value
215218
// So, the following URL has two placeholders that have to be filled.

0 commit comments

Comments
 (0)
0