-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.cpp
More file actions
94 lines (80 loc) · 3.3 KB
/
Copy pathutils.cpp
File metadata and controls
94 lines (80 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "utils.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <cctype>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#endif
namespace {
std::string getMimeType(const std::string& filePath) {
const std::string extension = filePath.substr(filePath.find_last_of('.') + 1);
std::string lowerExtension = extension;
std::transform(lowerExtension.begin(), lowerExtension.end(), lowerExtension.begin(), [](unsigned char c) {
return static_cast<char>(std::tolower(c));
});
if (lowerExtension == "html" || lowerExtension == "htm") return "text/html; charset=utf-8";
if (lowerExtension == "css") return "text/css; charset=utf-8";
if (lowerExtension == "js") return "application/javascript; charset=utf-8";
if (lowerExtension == "json") return "application/json; charset=utf-8";
if (lowerExtension == "png") return "image/png";
if (lowerExtension == "jpg" || lowerExtension == "jpeg") return "image/jpeg";
if (lowerExtension == "gif") return "image/gif";
if (lowerExtension == "svg") return "image/svg+xml";
if (lowerExtension == "txt") return "text/plain; charset=utf-8";
return "application/octet-stream";
}
}
std::string parseRequest(const std::string& request) {
std::istringstream requestStream(request);
std::string method, path, protocol;
requestStream >> method >> path >> protocol;
if (method != "GET") return "";
if (path.empty()) return "";
const std::size_t queryPos = path.find('?');
if (queryPos != std::string::npos) {
path = path.substr(0, queryPos);
}
if (path == "/") path = "/index.html";
if (path[0] != '/') path = "/" + path;
return "www" + path;
}
void logRequest(const std::string& request, const std::string& statusCode, const std::string& filePath) {
std::istringstream requestStream(request);
std::string method, path;
requestStream >> method >> path;
std::cout << "[" << statusCode << "] " << method << " " << path << " -> " << filePath << std::endl;
}
void sendErrorResponse(int clientSocket, const std::string& statusCode) {
const std::string body = "<html><body><h1>" + statusCode + "</h1></body></html>";
std::ostringstream header;
header << "HTTP/1.1 " << statusCode << "\r\n"
<< "Content-Type: text/html; charset=utf-8\r\n"
<< "Content-Length: " << body.size() << "\r\n"
<< "Connection: close\r\n"
<< "\r\n";
std::string response = header.str() + body;
send(clientSocket, response.c_str(), response.size(), 0);
}
void sendFileResponse(int clientSocket, const std::string& filePath) {
std::ifstream file(filePath, std::ios::binary);
if (!file) {
sendErrorResponse(clientSocket, "404 Not Found");
return;
}
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
const std::string mimeType = getMimeType(filePath);
std::ostringstream header;
header << "HTTP/1.1 200 OK\r\n"
<< "Content-Type: " << mimeType << "\r\n"
<< "Content-Length: " << content.size() << "\r\n"
<< "Connection: close\r\n"
<< "\r\n";
std::string response = header.str();
response.append(content);
send(clientSocket, response.c_str(), response.size(), 0);
}