├── .gitignore
├── .travis.yml
├── LICENSE.md
├── README.md
├── examples
├── handlers.cpp
├── handlers.hpp
├── main.cpp
├── my_server.cpp
└── my_server.hpp
├── makefile
├── server
├── route.cpp
├── route.hpp
├── server.cpp
└── server.hpp
├── static
├── 404.html
├── home.html
├── home.png
├── login.html
├── logincss.html
└── upload_form.html
├── template
└── colors.html
└── utils
├── include.hpp
├── request.cpp
├── request.hpp
├── response.cpp
├── response.hpp
├── template_parser.cpp
├── template_parser.hpp
├── utilities.cpp
└── utilities.hpp
/.gitignore:
--------------------------------------------------------------------------------
1 | ###C++###
2 |
3 | # Prerequisites
4 | *.d
5 |
6 | # Compiled Object files
7 | *.slo
8 | *.lo
9 | *.o
10 | *.obj
11 |
12 | # Precompiled Headers
13 | *.gch
14 | *.pch
15 |
16 | # Compiled Dynamic libraries
17 | *.so
18 | *.dylib
19 | *.dll
20 |
21 | # Fortran module files
22 | *.mod
23 | *.smod
24 |
25 | # Compiled Static libraries
26 | *.lai
27 | *.la
28 | *.a
29 | *.lib
30 |
31 | # Executables
32 | *.exe
33 | *.out
34 | *.app
35 |
36 |
37 | ###OSX###
38 |
39 | .DS_Store
40 | .AppleDouble
41 | .LSOverride
42 |
43 | # Icon must end with two \r
44 | Icon
45 |
46 |
47 | # Thumbnails
48 | ._*
49 |
50 | # Files that might appear on external disk
51 | .Spotlight-V100
52 | .Trashes
53 |
54 | # Directories potentially created on remote AFP share
55 | .AppleDB
56 | .AppleDesktop
57 | Network Trash Folder
58 | Temporary Items
59 | .apdisk
60 |
61 |
62 | ###Linux###
63 |
64 | *~
65 |
66 | # KDE directory preferences
67 | .directory
68 |
69 |
70 | ###Other###
71 | build
72 |
73 |
74 | # Editors
75 | .vscode
76 |
77 | ###APHTTP###
78 |
79 | # Compiled Template
80 | compiled.cpp
81 |
82 | # Template cache
83 | .template
84 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | before_install:
2 | - "eval \"${MATRIX_EVAL}\""
3 | language: cpp
4 | matrix:
5 | include:
6 | -
7 | env:
8 | - "MATRIX_EVAL=\"TESTENV=lint && STYLE=LLVM\""
9 | os: osx
10 | script:
11 | - "find . -name *.h -exec bash -c 'cmp <(clang-format --style=LLVM $0) $0' {} \\;"
12 | - "find . -name *.hpp -exec bash -c 'cmp <(clang-format --style=LLVM $0) $0' {} \\;"
13 | - "find . -name *.c -exec bash -c 'cmp <(clang-format --style=LLVM $0) $0' {} \\;"
14 | - "find . -name *.cpp -exec bash -c 'cmp <(clang-format --style=LLVM $0) $0' {} \\;"
15 | -
16 | before_install:
17 | - "sudo apt-get update"
18 | - "sudo apt-get install -y g++ make"
19 | env:
20 | - "MATRIX_EVAL=\"TESTENV=build && CC=gcc && CXX=g++\""
21 | os: linux
22 | script:
23 | - make
24 | -
25 | env:
26 | - "MATRIX_EVAL=\"TESTENV=build && CC=gcc && CXX=g++\""
27 | os: osx
28 | script:
29 | - make
30 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AP HTTP
2 | ===
3 | [](https://travis-ci.com/UTAP/APHTTP)
4 | [](https://llvm.org/docs/CodingStandards.html)
5 | [](https://github.com/UTAP/APHTTP/releases/latest)
6 | [](https://github.com/UTAP/APHTTP/wiki)
7 |
8 | **AP HTTP::_server_** is a simple web application server-side blocking framework for C++ based on simplified versions of [W++](http://konteck.github.io/wpp/), [HappyHTTP](http://scumways.com/happyhttp/happyhttp.html), and [cpp-netlib](http://cpp-netlib.org/).
9 |
--------------------------------------------------------------------------------
/examples/handlers.cpp:
--------------------------------------------------------------------------------
1 | #include "handlers.hpp"
2 |
3 | using namespace std;
4 |
5 | Response *RandomNumberHandler::callback(Request *req) {
6 | Response *res = new Response;
7 | res->setHeader("Content-Type", "text/html");
8 | string body;
9 | body += "";
10 | body += "";
11 | body += "
";
12 | body += "AP HTTP
";
13 | body += "";
14 | body += "a random number in [1, 10] is: ";
15 | body += to_string(rand() % 10 + 1);
16 | body += "
";
17 | body += "";
18 | body += "SeddionId: ";
19 | body += req->getSessionId();
20 | body += "
";
21 | body += "";
22 | body += "";
23 | res->setBody(body);
24 | return res;
25 | }
26 |
27 | Response *LoginHandler::callback(Request *req) {
28 | string username = req->getBodyParam("username");
29 | string password = req->getBodyParam("password");
30 | if (username == "root")
31 | throw Server::Exception("Remote root access has been disabled.");
32 | cout << "username: " << username << ",\tpassword: " << password << endl;
33 | Response *res = Response::redirect("/rand");
34 | res->setSessionId("SID");
35 | return res;
36 | }
37 |
38 | Response *UploadHandler::callback(Request *req) {
39 | string name = req->getBodyParam("file_name");
40 | string file = req->getBodyParam("file");
41 | cout << name << " (" << file.size() << "B):\n" << file << endl;
42 | Response *res = Response::redirect("/");
43 | return res;
44 | }
45 |
46 | ColorHandler::ColorHandler(string filePath) : TemplateHandler(filePath) {}
47 |
48 | map ColorHandler::handle(Request *req) {
49 | map context;
50 | string newName = "I am " + req->getQueryParam("name");
51 | context["name"] = newName;
52 | context["color"] = req->getQueryParam("color");
53 | return context;
54 | }
55 |
--------------------------------------------------------------------------------
/examples/handlers.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _MY_HANDLERS_
2 | #define _MY_HANDLERS_
3 |
4 | #include "../server/server.hpp"
5 | #include // for rand and srand
6 | #include // for time
7 | #include
8 |
9 | class RandomNumberHandler : public RequestHandler {
10 | public:
11 | Response *callback(Request *);
12 | };
13 |
14 | class LoginHandler : public RequestHandler {
15 | public:
16 | Response *callback(Request *);
17 | };
18 |
19 | class UploadHandler : public RequestHandler {
20 | public:
21 | Response *callback(Request *);
22 | };
23 |
24 | class ColorHandler : public TemplateHandler {
25 | public:
26 | ColorHandler(std::string filePath);
27 | std::map handle(Request *req);
28 | };
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/examples/main.cpp:
--------------------------------------------------------------------------------
1 | #include "handlers.hpp"
2 | #include "my_server.hpp"
3 | #include // for rand and srand
4 | #include // for time
5 | #include
6 |
7 | using namespace std;
8 |
9 | int main(int argc, char **argv) {
10 | srand(time(NULL)); // for rand
11 | try {
12 | MyServer server(argc > 1 ? atoi(argv[1]) : 5000);
13 | server.setNotFoundErrPage("static/404.html");
14 | server.get("/login", new ShowPage("static/logincss.html"));
15 | server.post("/login", new LoginHandler());
16 | server.get("/up", new ShowPage("static/upload_form.html"));
17 | server.post("/up", new UploadHandler());
18 | server.get("/rand", new RandomNumberHandler());
19 | server.get("/home.png", new ShowImage("static/home.png"));
20 | server.get("/", new ShowPage("static/home.html"));
21 | server.get("/colors", new ColorHandler("template/colors.html"));
22 | server.run();
23 | } catch (const Server::Exception& e) {
24 | cerr << e.getMessage() << endl;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/my_server.cpp:
--------------------------------------------------------------------------------
1 | #include "my_server.hpp"
2 |
3 | MyServer::MyServer(int port) : Server(port) {}
4 |
--------------------------------------------------------------------------------
/examples/my_server.hpp:
--------------------------------------------------------------------------------
1 | #ifndef __MY_SERVER__
2 | #define __MY_SERVER__
3 |
4 | #include "../server/server.hpp"
5 |
6 | class MyServer : public Server {
7 | public:
8 | MyServer(int port = 5000);
9 | };
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | CC=g++
2 | STD=-std=c++11 -Wall -pedantic
3 | CF=$(STD)
4 | BUILD_DIR=build
5 | TEMPLATE_DIR=.template
6 |
7 | ifeq ($(OS),Windows_NT)
8 | LDLIBS += -l Ws2_32
9 | endif
10 |
11 | all: $(BUILD_DIR) myserver.out
12 |
13 | $(BUILD_DIR):
14 | mkdir -p $(BUILD_DIR)
15 |
16 | $(BUILD_DIR)/template_parser.o: utils/template_parser.cpp utils/template_parser.hpp utils/request.cpp utils/request.hpp utils/utilities.hpp utils/utilities.cpp
17 | $(CC) $(CF) -c utils/template_parser.cpp -o $(BUILD_DIR)/template_parser.o
18 |
19 | $(BUILD_DIR)/response.o: utils/response.cpp utils/response.hpp utils/include.hpp
20 | $(CC) $(CF) -c utils/response.cpp -o $(BUILD_DIR)/response.o
21 |
22 | $(BUILD_DIR)/request.o: utils/request.cpp utils/request.hpp utils/include.hpp utils/utilities.hpp
23 | $(CC) $(CF) -c utils/request.cpp -o $(BUILD_DIR)/request.o
24 |
25 | $(BUILD_DIR)/utilities.o: utils/utilities.cpp utils/utilities.hpp
26 | $(CC) $(CF) -c utils/utilities.cpp -o $(BUILD_DIR)/utilities.o
27 |
28 | $(BUILD_DIR)/server.o: server/server.cpp server/server.hpp server/route.hpp utils/utilities.hpp utils/response.hpp utils/request.hpp utils/include.hpp utils/template_parser.hpp utils/template_parser.cpp
29 | $(CC) $(CF) -c server/server.cpp -o $(BUILD_DIR)/server.o
30 |
31 | $(BUILD_DIR)/route.o: server/route.cpp server/route.hpp utils/utilities.hpp utils/response.hpp utils/request.hpp utils/include.hpp
32 | $(CC) $(CF) -c server/route.cpp -o $(BUILD_DIR)/route.o
33 |
34 | $(BUILD_DIR)/handlers.o: examples/handlers.cpp server/server.hpp utils/utilities.hpp utils/response.hpp utils/request.hpp utils/include.hpp
35 | $(CC) $(CF) -c examples/handlers.cpp -o $(BUILD_DIR)/handlers.o
36 |
37 | $(BUILD_DIR)/my_server.o: examples/my_server.cpp server/server.hpp utils/utilities.hpp utils/response.hpp utils/request.hpp utils/include.hpp
38 | $(CC) $(CF) -c examples/my_server.cpp -o $(BUILD_DIR)/my_server.o
39 |
40 | $(BUILD_DIR)/main.o: examples/main.cpp server/server.hpp utils/utilities.hpp utils/response.hpp utils/request.hpp utils/include.hpp
41 | $(CC) $(CF) -c examples/main.cpp -o $(BUILD_DIR)/main.o
42 |
43 | myserver.out: $(BUILD_DIR)/my_server.o $(BUILD_DIR)/main.o $(BUILD_DIR)/handlers.o $(BUILD_DIR)/response.o $(BUILD_DIR)/request.o $(BUILD_DIR)/utilities.o $(BUILD_DIR)/server.o $(BUILD_DIR)/route.o $(BUILD_DIR)/template_parser.o
44 | $(CC) $(CF) $(BUILD_DIR)/my_server.o $(BUILD_DIR)/main.o $(BUILD_DIR)/handlers.o $(BUILD_DIR)/response.o $(BUILD_DIR)/request.o $(BUILD_DIR)/utilities.o $(BUILD_DIR)/server.o $(BUILD_DIR)/route.o $(BUILD_DIR)/template_parser.o $(LDLIBS) -o myserver.out
45 |
46 | .PHONY: clean
47 | clean:
48 | rm -rf $(BUILD_DIR) $(TEMPLATE_DIR) *.o *.out &> /dev/null
49 |
--------------------------------------------------------------------------------
/server/route.cpp:
--------------------------------------------------------------------------------
1 | #include "route.hpp"
2 | #include "server.hpp"
3 |
4 | using namespace std;
5 |
6 | Route::Route(Method _method, string _path) {
7 | method = _method;
8 | path = _path;
9 | }
10 |
11 | void Route::setHandler(RequestHandler *_handler) { handler = _handler; }
12 |
13 | bool Route::isMatch(Method _method, string url) {
14 | return (url == path) && (_method == method);
15 | }
16 |
17 | Response *Route::handle(Request *req) { return handler->callback(req); }
18 |
19 | Route::~Route() { delete handler; }
20 |
--------------------------------------------------------------------------------
/server/route.hpp:
--------------------------------------------------------------------------------
1 | #ifndef __ROUTE__
2 | #define __ROUTE__
3 | #include "../utils/include.hpp"
4 | #include "../utils/request.hpp"
5 | #include "../utils/response.hpp"
6 | #include
7 |
8 | class RequestHandler;
9 |
10 | class Route {
11 | private:
12 | Method method;
13 | std::string path;
14 | RequestHandler *handler;
15 |
16 | public:
17 | Route(Method _method, std::string _path);
18 | ~Route();
19 | bool isMatch(Method, std::string url);
20 | Response *handle(Request *req);
21 | void setHandler(RequestHandler *_handler);
22 | };
23 | #endif
24 |
--------------------------------------------------------------------------------
/server/server.cpp:
--------------------------------------------------------------------------------
1 | #include "server.hpp"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 | #include