forked from CrowCpp/Crow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.cpp
225 lines (191 loc) · 7.44 KB
/
example.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include "crow.h"
class ExampleLogHandler : public crow::ILogHandler
{
public:
void log(std::string /*message*/, crow::LogLevel /*level*/) override
{
// cerr << "ExampleLogHandler -> " << message;
}
};
struct ExampleMiddleware
{
std::string message;
ExampleMiddleware():
message("foo")
{
}
void setMessage(const std::string& newMsg)
{
message = newMsg;
}
struct context
{};
void before_handle(crow::request& /*req*/, crow::response& /*res*/, context& /*ctx*/)
{
CROW_LOG_DEBUG << " - MESSAGE: " << message;
}
void after_handle(crow::request& /*req*/, crow::response& /*res*/, context& /*ctx*/)
{
// no-op
}
};
int main()
{
crow::App<ExampleMiddleware> app;
app.get_middleware<ExampleMiddleware>().setMessage("hello");
CROW_ROUTE(app, "/")
.name("hello")([] {
return "Hello World!";
});
CROW_ROUTE(app, "/about")
([]() {
return "About Crow example.";
});
// a request to /path should be forwarded to /path/
CROW_ROUTE(app, "/path/")
([]() {
return "Trailing slash test case..";
});
// simple json response
CROW_ROUTE(app, "/json")
([] {
crow::json::wvalue x({{"message", "Hello, World!"}});
x["message2"] = "Hello, World.. Again!";
return x;
});
CROW_ROUTE(app, "/json-initializer-list-constructor")
([] {
return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", std::int64_t(54)}, /* stores a 64-bit int hence a std::int64_t. */
{"fourth", std::uint64_t(54)}, /* stores a 64-bit unsigned int hence a std::uint64_t. */
{"fifth", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"sixth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
});
});
// json list response
CROW_ROUTE(app, "/json_list")
([] {
crow::json::wvalue x(crow::json::wvalue::list({1, 2, 3}));
return x;
});
// To see it in action enter {ip}:18080/hello/{integer_between -2^32 and 100} and you should receive
// {integer_between -2^31 and 100} bottles of beer!
CROW_ROUTE(app, "/hello/<int>")
([](int count) {
if (count > 100)
return crow::response(400);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str());
});
// Same as above, but using crow::status
CROW_ROUTE(app, "/hello_status/<int>")
([](int count) {
if (count > 100)
return crow::response(crow::status::BAD_REQUEST);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str());
});
// To see it in action submit {ip}:18080/add/1/2 and you should receive 3 (exciting, isn't it)
CROW_ROUTE(app, "/add/<int>/<int>")
([](crow::response& res, int a, int b) {
std::ostringstream os;
os << a + b;
res.write(os.str());
res.end();
});
//same as the example above but uses mustache instead of stringstream
CROW_ROUTE(app, "/add_mustache/<int>/<int>")
([](int a, int b) {
auto t = crow::mustache::compile("Value is {{func}}");
crow::mustache::context ctx;
ctx["func"] = [&](std::string) {
return std::to_string(a + b);
};
auto result = t.render(ctx);
return result;
});
// Compile error with message "Handler type is mismatched with URL paramters"
//CROW_ROUTE(app,"/another/<int>")
//([](int a, int b){
//return crow::response(500);
//});
// more json example
// To see it in action, I recommend to use the Postman Chrome extension:
// * Set the address to {ip}:18080/add_json
// * Set the method to post
// * Select 'raw' and then JSON
// * Add {"a": 1, "b": 1}
// * Send and you should receive 2
// A simpler way for json example:
// * curl -d '{"a":1,"b":2}' {ip}:18080/add_json
CROW_ROUTE(app, "/add_json")
.methods("POST"_method)([](const crow::request& req) {
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
int sum = x["a"].i() + x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()};
});
// Example of a request taking URL parameters
// If you want to activate all the functions just query
// {ip}:18080/params?foo='blabla'&pew=32&count[]=a&count[]=b
CROW_ROUTE(app, "/params")
([](const crow::request& req) {
std::ostringstream os;
// To get a simple string from the url params
// To see it in action /params?foo='blabla'
os << "Params: " << req.url_params << "\n\n";
os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
// To get a double from the request
// To see in action submit something like '/params?pew=42'
if (req.url_params.get("pew") != nullptr)
{
double countD = crow::utility::lexical_cast<double>(req.url_params.get("pew"));
os << "The value of 'pew' is " << countD << '\n';
}
// To get a list from the request
// You have to submit something like '/params?count[]=a&count[]=b' to have a list with two values (a and b)
auto count = req.url_params.get_list("count");
os << "The key 'count' contains " << count.size() << " value(s).\n";
for (const auto& countVal : count)
{
os << " - " << countVal << '\n';
}
// To get a dictionary from the request
// You have to submit something like '/params?mydict[a]=b&mydict[abcd]=42' to have a list of pairs ((a, b) and (abcd, 42))
auto mydict = req.url_params.get_dict("mydict");
os << "The key 'dict' contains " << mydict.size() << " value(s).\n";
for (const auto& mydictVal : mydict)
{
os << " - " << mydictVal.first << " -> " << mydictVal.second << '\n';
}
return crow::response{os.str()};
});
CROW_ROUTE(app, "/large")
([] {
return std::string(512 * 1024, ' ');
});
// Take a multipart/form-data request and print out its body
CROW_ROUTE(app, "/multipart")
([](const crow::request& req) {
crow::multipart::message_view msg(req);
CROW_LOG_INFO << "body of the first part " << msg.parts[0].body;
return "it works!";
});
// enables all log
app.loglevel(crow::LogLevel::Debug);
//crow::logger::setHandler(std::make_shared<ExampleLogHandler>());
app.port(18080)
.multithreaded()
.run();
}