I am building a web-server. I am trying to build a function handler that parses the index.html file in the root directory. It works but when I go to the website on my localhost 127.0.0.1:8080 I get page not found. I programmed it to say that when the ifstream has falied. I'm positive it failed because it cannot find the root directory.
WebServer.h
// Handler for when a message is received from the client
void WebServer::onHTMLReceived(int clientSocket, const char* msg, int length)
{
// Parse out the client's request string e.g. GET /index. HTTP/1.1
std::istringstream iss(msg);
std::vector<std::string> parsed((std::istream_iterator<std::string>(iss)), std::istream_iterator<std::string>());
// Some defaults for output to the client (404 file not found 'page')
std::string content = "<h1>404 Not Found</h1>";
std::string htmlFile = "/index.html";
int errorCode = 404;
// If the GET request is valid, try and get the name
if (parsed.size() >= 3 && parsed[0] == "GET")
{
htmlFile = parsed[1];
// If the file is just a slash, use index.html. This should really
// be if it _ends_ in a slash. I'll leave that for you :)
if (htmlFile == "/")
{
htmlFile = "/index.html";
}
}
// Open the document in the local file system
// The problem is here, ".\\wwwroot" isn't working
std::ifstream f(".\\wwwroot" + htmlFile);
// Check if it opened and if it did, grab the entire contents
if (f.good())
{
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
content = str;
errorCode = 200;
}
f.close();
// Write the document back to the client
std::ostringstream oss;
oss << "HTTP/1.1 " << errorCode << " OK\r\n";
oss << "Cache-Control: no-cache, private\r\n";
oss << "Content-Type: text/html\r\n";
oss << "Content-Length: " << content.size() << "\r\n";
oss << "\r\n";
oss << content;
std::string output = oss.str();
int size = output.size() + 1;
send(clientSocket, output.c_str(), size, 0);
std::cout << "" << std::endl;
}
I thought .\\wwwroot would take me to the root directory but it didn't. I don't think that works for windows. When I go to 127.0.0.1 in the web-browser I get this output in the terminal:
output:
CLIENT> GET /favicon.ico HTTP/1.1
Host: localhost:8080
Connection: keep-alive
sec-ch-ua-platform: "Windows"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
Does anyone have any suggestions?
I trid to use:
namespace fs = std::filesystem;
fs::path path(fs::current_path());
std::u8string path_string{path.u8string()};
But the compiler says namespace "std" has no member "u8string". I'm not sure if that is because of the version I am using or not.
wwwrootin the same directory as you ran your program from? Have you tried using an absolute path or using a debugger?int size = output.size() + 1;is wrong. You are including theoutput's null terminator in the data that yousend()to the client, but HTTP doesn't send null terminators...in the path, as they can be used to steal any file in your file system if you don't take care to handle them.