/* Starshatter: The Open Source Project Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors Copyright (c) 1997-2006, Destroyer Studios LLC. AUTHOR: John DiCamillo OVERVIEW ======== Network Server Pump for HTTP Server */ #include "HttpServletExec.h" #include #include #include #include #include "HttpRequest.h" #include "HttpResponse.h" #include "HttpServer.h" #include "HttpServlet.h" #include "HttpSession.h" #include "List.h" #include "HttpParam.h" #include "Utils.h" #include "NetLayer.h" class HttpTestServlet : public HttpServlet { public: HttpTestServlet() { } virtual ~HttpTestServlet() { } virtual bool DoGet(HttpRequest& request, HttpResponse& response) { char buffer[1024]; Text content; content = "HttpTestServlet\n"; content += "\n

HttpTestServlet

\n"; content += "

HttpSessionId:

\n"; if (session) content += session->GetID(); else content += "No Session Found"; content += "
\n"; content += "

URI Requested:

\n"; content += request.URI(); content += "
\n"; if (request.GetQuery().size() > 0) { content += "

Query Parameters:

\n"; ListIter q_iter = request.GetQuery(); while (++q_iter) { HttpParam* q = q_iter.value(); std::sprintf(buffer, "%s: %s
\n", q->name.data(), q->value.data()); content += buffer; } } content += "

Request Headers:

\n"; ListIter h_iter = request.GetHeaders(); while (++h_iter) { HttpParam* h = h_iter.value(); std::sprintf(buffer, "%s: %s
\n", h->name.data(), h->value.data()); content += buffer; } if (request.GetCookies().size() > 0) { content += "

Cookies:

\n"; ListIter c_iter = request.GetCookies(); while (++c_iter) { HttpParam* c = c_iter.value(); std::sprintf(buffer, "%s: %s
\n", c->name.data(), c->value.data()); content += buffer; } } content += "\n\n"; response.SetStatus(HttpResponse::SC_OK); response.AddHeader("MIME-Version", "1.0"); response.AddHeader("Content-Type", "text/html"); response.SetContent(content); return true; } }; HttpServletExec::HttpServletExec(std::uint16_t port, int poolsize) : HttpServer(port, poolsize), session_timeout(60), exec_shutdown(false) { http_server_name = "Generic HttpServletExec 1.0"; hsession = std::thread([&]{ CheckSessions(); }); } HttpServletExec::~HttpServletExec() { if (!exec_shutdown) exec_shutdown = true; if (hsession.joinable()) hsession.join(); sessions.destroy(); } HttpServlet* HttpServletExec::GetServlet(HttpRequest& request) { return new HttpTestServlet; } HttpSession* HttpServletExec::GetSession(HttpRequest& request) { HttpSession* session = 0; Text reqID = request.GetCookie("SessionID"); if (reqID.length() > 0) { ListIter iter = sessions; while (++iter && !session) { HttpSession* s = iter.value(); if (s->GetID() == reqID) { session = s; session->Access(); } } } if (!session) { session = new HttpSession; if (session) { sessions.append(session); ::Print("HttpServletExec created new session '%s' for request '%s'\n", (const char*) session->GetID(), (const char*) request.RequestLine()); } else { ::Print("HttpServletExec out of memory for request '%s'\n", (const char*) request.RequestLine()); } } return session; } bool HttpServletExec::DoGet(HttpRequest& request, HttpResponse& response) { bool result = false; HttpSession* session = GetSession(request); HttpServlet* servlet = GetServlet(request); if (servlet) { servlet->SetSession(session); result = servlet->Service(request, response); delete servlet; } if (result) { response.SetHeader("Server", http_server_name); if (session) response.SetCookie("SessionID", session->GetID()); } return result; } void HttpServletExec::CheckSessions() { while (!exec_shutdown) { sync.lock(); if (sessions.size()) { ListIter iter = sessions; while (++iter) { HttpSession* s = iter.value(); if (NetLayer::GetUTC() - s->GetLastAccess() > session_timeout) { ::Print("HttpServletExec deleting expired session '%s'\n", (const char*) s->GetID()); delete iter.removeItem(); } } } DoSyncedCheck(); sync.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } void HttpServletExec::DoSyncedCheck() { }