Skip to content

Commit

Permalink
Bugfixes
Browse files Browse the repository at this point in the history
Fixed the header names bug, and started working on the demo site
  • Loading branch information
YotamShvartsun committed Apr 27, 2020
1 parent f5df92a commit fbd0d3f
Show file tree
Hide file tree
Showing 67 changed files with 275,622 additions and 146 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,4 @@ _deps

# End of https://www.gitignore.io/api/c++,cmake,clion

.vs/
146 changes: 146 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@

# Created by https://www.gitignore.io/api/c++,cmake,clion
# Edit at https://www.gitignore.io/?templates=c++,cmake,clion

### C++ ###
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

### CLion ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries
.idea/**
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### CLion Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr

# Sonarlint plugin
.idea/**/sonarlint/

# SonarQube Plugin
.idea/**/sonarIssues.xml

# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/

### CMake ###
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

### CMake Patch ###
# External projects
*-prefix/

# End of https://www.gitignore.io/api/c++,cmake,clion

.vs/
9 changes: 8 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ project(examples)
find_library(chttp REQUIRED)
set(CMAKE_CXX_STANDARD 14)

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp)
include_directories(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/thirdparty/json)
include_directories(../include)

add_executable(examples main.cpp)

target_link_libraries(examples chttp)
target_link_libraries(examples
SQLiteCpp
chttp)
193 changes: 180 additions & 13 deletions examples/main.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,185 @@
#include <chttp/CHttp.h>
#include <iostream>
#include <chttp/CHttp.h>
#include <SQLiteCpp/SQLiteCpp.h>
#include <json.hpp>


struct blogPostJSON {
int id{};
std::string title;
std::string body;
};

void to_json(nlohmann::json& j, const blogPostJSON& p) {
j = nlohmann::json{{"title", p.title}, {"body", p.body}, {"id", p.id}};
}

void from_json(const nlohmann::json& j, blogPostJSON& p) {
j.at("id").get_to(p.id);
j.at("title").get_to(p.title);
j.at("body").get_to(p.body);
}

void CreateTables(SQLite::Database &db) {
db.exec("CREATE TABLE IF NOT EXISTS users(id integer primary key, username char(20), password text)");
db.exec("CREATE TABLE IF NOT EXISTS posts(id integer primary key, publisher_id integer,post_title text, post_content TEXT, foreign key(publisher_id) references users(id))");
}

void Signup(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) {
// if(req->) TODO write a function to return one header
nlohmann::json body = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody());
std::string username = body["username"].get<std::string>();
std::string password = body["password"].get<std::string>();
nlohmann::json responseBody;
try {
SQLite::Database db("exampleBlogDB.db");
SQLite::Statement insertNewUser(db, "insert into users(username, password) values (?,?)");
insertNewUser.bind(1, username);
insertNewUser.bind(2, password);
while (insertNewUser.executeStep()) {
responseBody["id"] = db.getLastInsertRowid();
}
resp->AddCookie("Auth", responseBody.dump());
} catch (std::exception &e) {
responseBody["error"] = "Unable to create a new user!";
resp->SetStatus(Unauthorized);
}
resp->Header("Content-Type", "application/json");
resp->Raw(responseBody.dump());
}

void form(std::shared_ptr<HttpRequest> rq, std::shared_ptr<HttpResponse> rs) {
auto b = ((PostRequest *)rq.get())->GetBody();
auto ct = rq->GetHeaders()["Content-Type"];
MultipartField mp(b, ct);
auto data = mp.getData();
std::string res = std::string(data.begin(), data.end()) + " to you too";
rs->Raw(std::vector<char>(res.begin(), res.end()));
void usersMe(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) {
resp->Header("Content-Type", "application/json");
CookieJar jar(req->GetHeaders()["cookie"]);
resp->Raw(jar.GetCookieValue("Auth"));
}

void Logout(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) {
resp->RemoveCookie("Auth");
resp->Raw("ok");
}

void Login(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) {
nlohmann::json body = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody());
nlohmann::json responseBody;
responseBody["error"] = "Invalid credentials";
resp->SetStatus(Unauthorized);
std::string username = body["username"].get<std::string>();
std::string password = body["password"].get<std::string>();

try {
SQLite::Database db("exampleBlogDB.db");
SQLite::Statement stmt(db, "select id from users where username = ? and password = ?");
stmt.bind(1, username);
stmt.bind(2, password);
while (stmt.executeStep()) {
if (responseBody.contains("error")) {
responseBody.clear();
}
responseBody["UID"] = std::stoi(stmt.getColumn("id"));
}
if (!responseBody.contains("error")) {
resp->SetStatus(OK);
resp->AddCookie("Auth", responseBody.dump());
}
} catch (...) {
resp->SetStatus(Internal_Server_Error);
responseBody["error"] = "Something went wrong";
}
resp->Header("Content-Type", "application/json");
resp->Raw(responseBody.dump());
}

void CreatePost(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp) {
CookieJar cookies(req->GetHeaders()["cookie"]);
nlohmann::json respBody;
if (cookies.IsInJar("Auth")) {
try {
nlohmann::json cookieBody = nlohmann::json::parse(cookies.GetCookieValue("Auth"));
SQLite::Database db("exampleBlogDB.db", SQLite::OPEN_READWRITE);
SQLite::Statement isUser(db, "select count(*) as count from users where id=?");
bool isLoggedIn = false;
int tmp = cookieBody["UID"].get<int>();
isUser.bind(1, tmp);
while (isUser.executeStep()) {
tmp = isUser.getColumn("count");
if (tmp != 0) {
isLoggedIn = true;
}
}
if (isLoggedIn) {
SQLite::Statement insertPost(db,
"insert into posts(publisher_id, post_title, post_content) values (?,?,?)");
tmp = cookieBody["UID"].get<int>();
insertPost.bind(1, tmp);
nlohmann::json requestBody = nlohmann::json::parse(dynamic_cast<PostRequest *>(req.get())->GetBody());
std::string requestTmp = requestBody["title"].get<std::string>();
insertPost.bind(2, requestTmp);
requestTmp = requestBody["body"].get<std::string>();
insertPost.bind(3, requestTmp);
insertPost.exec();
respBody["id"] = db.getLastInsertRowid();
} else {
respBody["error"] = "You are not allowed to do that";
resp->SetStatus(Unauthorized);
}
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
respBody["error"] = "Something went wrong!";
resp->SetStatus(Internal_Server_Error);
}
} else {
respBody["error"] = "You are not allowed to do that";
resp->SetStatus(Unauthorized);
}
resp->Header("Content-Type", "application/json");
resp->Raw(respBody.dump());
}

void AllPosts(std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> resp){
nlohmann::json responseBody;
try{
SQLite::Database db("exampleBlogDB.db");
SQLite::Statement allPosts(db, "select posts.post_content, posts.post_title, posts.id, users.username from posts join users on publisher_id=users.id");
nlohmann::json postsJSON = nlohmann::json::array();
blogPostJSON postTmp;
std::string titleTmp;
std::vector<blogPostJSON> posts;
while(allPosts.executeStep()){
postTmp.body = allPosts.getColumn(0).getString();
titleTmp = allPosts.getColumn(1).getString();
titleTmp += " - " + allPosts.getColumn(3).getString();
postTmp.title = titleTmp;
postTmp.id = allPosts.getColumn(2).getInt();
posts.push_back(postTmp);
}
postsJSON = nlohmann::json(posts);
responseBody["posts"] = postsJSON;
}catch(std::exception &e){
std::cerr << e.what() << std::endl;
resp->SetStatus(Not_Found);
responseBody["error"] = "Unable to fetch posts";
}
resp->Header("Content-Type", "application/json");
resp->Raw(responseBody.dump());
}


int main(int argc, char **argv) {
int port = 8080;
Server app;
app.Post("/form", form, {});
app.ServeStaticFolder("/", "/home/themiper/chttp/examples/public/");
app.Run(port);
int port = 8081;
if (argc == 2) {
port = std::stoi(argv[1]);
}
{
SQLite::Database dbHandler("exampleBlogDB.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
CreateTables(dbHandler);
}
Server server;
server.Post("/api/v1/signup", Signup, {});
server.Post("/api/v1/login", Login, {});
server.Post("/api/v1/newPost", CreatePost, {});
server.Get("/api/v1/users/me", usersMe, {});
server.Get("/api/v1/logout", Logout, {});
server.Get("/api/v1/posts", AllPosts, {});
server.Run(port);
}
Loading

0 comments on commit fbd0d3f

Please sign in to comment.