diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index fb432dad..3b9bf582 100755
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -6,11 +6,28 @@ set(benchmark_sources benchmark/BenchmarkCtrl.cc benchmark/JsonCtrl.cc
add_executable(client client_example/main.cc)
add_executable(websocket_client websocket_client/WebSocketClient.cc)
add_executable(benchmark ${benchmark_sources})
+add_executable(helloworld helloworld/main.cc
+ helloworld/HelloController.cc
+ helloworld/HelloViewController.cc)
+drogon_create_views(helloworld
+ ${CMAKE_CURRENT_SOURCE_DIR}/helloworld
+ ${CMAKE_CURRENT_BINARY_DIR})
+add_executable(file_upload file_upload/file_upload.cc)
+drogon_create_views(file_upload
+ ${CMAKE_CURRENT_SOURCE_DIR}/file_upload
+ ${CMAKE_CURRENT_BINARY_DIR})
+add_executable(login_session login_session/main.cc)
+drogon_create_views(login_session
+ ${CMAKE_CURRENT_SOURCE_DIR}/login_session
+ ${CMAKE_CURRENT_BINARY_DIR})
set(example_targets
benchmark
client
- websocket_client)
+ websocket_client
+ helloworld
+ file_upload
+ login_session)
set_property(TARGET ${example_targets}
PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
diff --git a/examples/README.md b/examples/README.md
index 464d52dd..b2fab4b0 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -2,10 +2,15 @@
The following examples can help you understand how to use Drogon:
-1. [benchmark](https://github.com/an-tao/drogon/tree/master/examples/benchmark) - Basic benchmark example. see [wiki benchmarks](https://github.com/an-tao/drogon/wiki/13-Benchmarks)
+1. [hellowrold](https://github.com/an-tao/drogon/tree/master/examples/hellowrold) - The multuple ways of "Hello, World!"
2. [client_example](https://github.com/an-tao/drogon/tree/master/examples/client_example/main.cc) - A client example.
-3. [simple_reverse_proxy](https://github.com/an-tao/drogon/tree/master/examples/simple_reverse_proxy) - A Example showing how to use drogon as a http reverse proxy with a simple round robin.
-4. [websocket_client](https://github.com/an-tao/drogon/tree/master/examples/websocket_client/WebSocketClient.cc) - An example on how to use the WebSocket client
+3. [websocket_client](https://github.com/an-tao/drogon/tree/master/examples/websocket_client/WebSocketClient.cc) - An example on how to use the WebSocket client
+4. [login_session](https://github.com/an-tao/drogon/tree/master/examples/login_session) - How to use the built-in session system to handle login and out
+5. [file_upload](https://github.com/an-tao/drogon/tree/master/examples/file_upload) - How to handle file uploads in Drogon
+6. [simple_reverse_proxy](https://github.com/an-tao/drogon/tree/master/examples/simple_reverse_proxy) - A Example showing how to use drogon as a http reverse
+proxy with a simple round robin.
+7. [benchmark](https://github.com/an-tao/drogon/tree/master/examples/benchmark) - Basic benchmark example. see [wiki benchmarks](https://github.com/an-tao/drogon/wiki/13-Benchmarks)
+
### [TechEmpower Framework Benchmarks](https://github.com/TechEmpower/FrameworkBenchmarks) test suite
diff --git a/examples/file_upload/FileUpload.csp b/examples/file_upload/FileUpload.csp
new file mode 100644
index 00000000..d21ccf9e
--- /dev/null
+++ b/examples/file_upload/FileUpload.csp
@@ -0,0 +1,83 @@
+
+
+
+
+ File upload
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/file_upload/file_upload.cc b/examples/file_upload/file_upload.cc
new file mode 100644
index 00000000..625c7a78
--- /dev/null
+++ b/examples/file_upload/file_upload.cc
@@ -0,0 +1,46 @@
+#include
+using namespace drogon;
+
+int main()
+{
+ app().registerHandler(
+ "/",
+ [](const HttpRequestPtr &req,
+ std::function &&callback) {
+ auto resp = HttpResponse::newHttpViewResponse("FileUpload");
+ callback(resp);
+ });
+
+ app().registerHandler(
+ "/upload_endpoint",
+ [](const HttpRequestPtr &req,
+ std::function &&callback) {
+ MultiPartParser fileUpload;
+ if (fileUpload.parse(req) != 0 || fileUpload.getFiles().size() != 1)
+ {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody("Must only be 1 file");
+ resp->setStatusCode(k403Forbidden);
+ callback(resp);
+ return;
+ }
+
+ auto &file = fileUpload.getFiles()[0];
+ auto md5 = file.getMd5();
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody(
+ "The server has calculated the file's MD5 hash to be " + md5);
+ file.save();
+ LOG_INFO << "The uploaded file have been saved to the ./uploads "
+ "directory";
+ callback(resp);
+ },
+ {Post});
+
+ LOG_INFO << "Server running on 127.0.0.1:8848";
+ app()
+ .setClientMaxBodySize(20 * 2000 * 2000)
+ .setUploadPath("./uploads")
+ .addListener("127.0.0.1", 8848)
+ .run();
+}
\ No newline at end of file
diff --git a/examples/helloworld/HelloController.cc b/examples/helloworld/HelloController.cc
new file mode 100644
index 00000000..39e67167
--- /dev/null
+++ b/examples/helloworld/HelloController.cc
@@ -0,0 +1,40 @@
+#include
+
+using namespace drogon;
+
+// HttpControllers are automatically added to Drogon upon Drogon initializing.
+class SayHello : public HttpController
+{
+ public:
+ METHOD_LIST_BEGIN
+ // Drogon automatically appends the namespce and name of the controller to
+ // the handlers of the controller. In this example, although we are adding
+ // a handler to /. But because it is a part of the SayHello controller. It
+ // ends up in path /SayHello/ (IMOPRTANT! It is /SayHello/ not /SayHello
+ // they are different paths).
+ METHOD_ADD(SayHello::genericHello, "/", Get);
+ // Same for /hello. It ends up at /SayHello/hello
+ METHOD_ADD(SayHello::personalizedHello, "/hello", Get);
+ METHOD_LIST_END
+
+ protected:
+ void genericHello(const HttpRequestPtr &req,
+ std::function &&callback)
+ {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody(
+ "Hello, this is a generic hello message from the SayHello "
+ "controller");
+ callback(resp);
+ }
+
+ void personalizedHello(
+ const HttpRequestPtr &req,
+ std::function &&callback)
+ {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody(
+ "Hi there, this is another hello from the SayHello Controller");
+ callback(resp);
+ }
+};
\ No newline at end of file
diff --git a/examples/helloworld/HelloView.csp b/examples/helloworld/HelloView.csp
new file mode 100644
index 00000000..064bb6eb
--- /dev/null
+++ b/examples/helloworld/HelloView.csp
@@ -0,0 +1,24 @@
+
+
+<%c++
+ auto name=@@.get("name");
+ bool nameIsEmpty = name == "";
+ if (nameIsEmpty)
+ name = "anonymous";
+ auto message = "Hello, " + name + " from a CSP template";
+%>
+
+
+ [[ name ]]
+
+
+ <%c++ $$<
+ <%c++
+ if (nameIsEmpty)
+ {
+ $$ << " "
+ << "You can revisit the same page and append ?name=your_name to change the name";
+ }
+ %>
+
+
diff --git a/examples/helloworld/HelloViewController.cc b/examples/helloworld/HelloViewController.cc
new file mode 100644
index 00000000..30023f7e
--- /dev/null
+++ b/examples/helloworld/HelloViewController.cc
@@ -0,0 +1,29 @@
+#include
+#include
+
+using namespace drogon;
+
+// HttpSimpleController does not allow registration of multiple handlers.
+// Instead, it has one handler - asyncHandleHttpRequest. The
+// HttpSimpleController is a lightweight class designed to handle really simple
+// cases.
+class HelloViewController : public HttpSimpleController
+{
+ public:
+ PATH_LIST_BEGIN
+ // Also unlike HttpContoller, HttpSimpleController does not automatically
+ // prepend the namespace and class name to the path. Thus the path of this
+ // controller is at "/view".
+ PATH_ADD("/view")
+ PATH_LIST_END
+
+ void asyncHandleHttpRequest(
+ const HttpRequestPtr &req,
+ std::function &&callback) override
+ {
+ HttpViewData data;
+ data["name"] = req->getParameter("name");
+ auto resp = HttpResponse::newHttpViewResponse("HelloView", data);
+ callback(resp);
+ }
+};
\ No newline at end of file
diff --git a/examples/helloworld/main.cc b/examples/helloworld/main.cc
new file mode 100644
index 00000000..030e52db
--- /dev/null
+++ b/examples/helloworld/main.cc
@@ -0,0 +1,70 @@
+#include
+using namespace drogon;
+
+int main()
+{
+ // `registerHandler()` adds a handler to the desired path. The handler is
+ // responsible for generating a HTTP response upon an HTTP request being
+ // sent to Drogon
+ app().registerHandler(
+ "/",
+ [](const HttpRequestPtr &req,
+ std::function &&callback) {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody("Hello, World!");
+ callback(resp);
+ },
+ {Get});
+
+ // `registrHandler()` also supports parsing and passing the path as
+ // parameters to the handler. Parameters are specified using {}. The text
+ // indide {} does not correspond to the index of parameter passed to the
+ // handler (nor it has any meaning). Instead, it is only to make it easier
+ // for users to recognize the function of each parameter.
+ app().registerHandler(
+ "/user/{user-name}",
+ [](const HttpRequestPtr &req,
+ std::function &&callback,
+ const std::string &name) {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody("Hello, " + name + "!");
+ callback(resp);
+ },
+ {Get});
+
+ // You can aslo specsify that the parameter is in the query section of the
+ // URL!
+ app().registerHandler(
+ "/hello?user={user-name}",
+ [](const HttpRequestPtr &req,
+ std::function &&callback,
+ const std::string &name) {
+ auto resp = HttpResponse::newHttpResponse();
+ resp->setBody("Hello, " + name + "!");
+ callback(resp);
+ },
+ {Get});
+
+ // Or, if you want to, instead of asking drogon to parse it fot you. You can
+ // parse the request yourselves.
+ app().registerHandler(
+ "/hello_user",
+ [](const HttpRequestPtr &req,
+ std::function &&callback) {
+ auto resp = HttpResponse::newHttpResponse();
+ std::string name = req->getParameter("user");
+ if (name == "")
+ resp->setBody("Please tell me your name");
+ else
+ resp->setBody("Hello, " + name + "!");
+ callback(resp);
+ },
+ {Get});
+
+ // Ask Drogon to listern on 127.0.0.1 port 8848. Drogon supports listerning
+ // on multuiple IP addresses by adding multiple listeners. For example, if
+ // you want the server also Listen on 127.0.0.1 port 5555. Just add another
+ // line of addListener("127.0.0.1", 5555)
+ LOG_INFO << "Server running on 127.0.0.1:8848";
+ app().addListener("127.0.0.1", 8848).run();
+}
\ No newline at end of file
diff --git a/examples/login_session/LoginPage.csp b/examples/login_session/LoginPage.csp
new file mode 100644
index 00000000..8d521997
--- /dev/null
+++ b/examples/login_session/LoginPage.csp
@@ -0,0 +1,22 @@
+
+
+
+
+ session example
+
+
+
+
+
Please login with the credential Username: user Password: password123