/* 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 "HttpServer.h" #include #include #include "HttpParam.h" #include "HttpRequest.h" #include "HttpResponse.h" #include "List.h" #include "NetAddr.h" #include "NetServer.h" #include "Text.h" HttpServer::HttpServer(std::uint16_t port, int poolsize) : NetServer(port, poolsize) { http_server_name = "Generic HttpServer 1.0"; } HttpServer::~HttpServer() { } Text HttpServer::ProcessRequest(Text msg, const NetAddr& addr) { HttpRequest request(msg); HttpResponse response; request.SetClientAddr(addr); switch (request.Method()) { case HttpRequest::HTTP_GET: if (DoGet(request, response)) return response; case HttpRequest::HTTP_POST: if (DoPost(request, response)) return response; case HttpRequest::HTTP_HEAD: if (DoHead(request, response)) return response; } return ErrorResponse(); } Text HttpServer::GetServerName() { return http_server_name; } void HttpServer::SetServerName(const char* name) { http_server_name = name; } Text HttpServer::DefaultResponse() { Text response = "HTTP/1.1 200 OK\nServer: "; response += http_server_name; response += "\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n"; return response; } Text HttpServer::ErrorResponse() { Text response = "HTTP/1.1 500 Internal Server Error\nServer:"; response += http_server_name; response += "\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n"; response += ""; response += http_server_name; response += " Error\n"; response += "\n

"; response += http_server_name; response += "

\n

Veruca... sweetheart... angel... I'm not a magician!\n"; response += "\n\n"; return response; } bool HttpServer::DoGet(HttpRequest& request, HttpResponse& response) { char buffer[1024]; Text content; content = ""; content += http_server_name; content += "\n"; content += "\n

"; content += http_server_name; content += "

\n"; content += "

Client Address:

\n"; std::sprintf(buffer, "%d.%d.%d.%d:%d

\n", client_addr.B1(), client_addr.B2(), client_addr.B3(), client_addr.B4(), client_addr.Port()); content += buffer; content += "

Request Method:

\n"; switch (request.Method()) { case HttpRequest::HTTP_GET: content += "GET"; break; case HttpRequest::HTTP_POST: content += "POST"; break; case HttpRequest::HTTP_HEAD: content += "HEAD"; break; default: content += "(unsupported?)"; break; } 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::printf(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; } content += "\n\n"; response.SetStatus(HttpResponse::SC_OK); response.AddHeader("Server", http_server_name); response.AddHeader("MIME-Version", "1.0"); response.AddHeader("Content-Type", "text/html"); response.SetContent(content); return true; } bool HttpServer::DoPost(HttpRequest& request, HttpResponse& response) { return DoGet(request, response); } bool HttpServer::DoHead(HttpRequest& request, HttpResponse& response) { if (DoGet(request, response)) { int len = response.Content().length(); char buffer[256]; std::sprintf(buffer, "%d", len); response.SetHeader("Content-Length", buffer); response.SetContent(""); return true; } return false; }