I have been given an assignment which involves writing a web server using c++ and the Boost Asio library.
I have got together working server which can send html files back to the client browser using a book called "Boost.Asio C++ Network Programming Cookbook" but I am struggling with handling POST requests from the client.
When a client connects to the server they are given simple HTML form consisting of a username and password field to login in to the server, which is then sent to the server using a POST request.
I have output the contents of the received POST request to the console and I can see all the header information, but I cannot see the form data. I have used Wireshark to inspect the packets and the data is being sent over the network.
The data is being received by the server as a Boost Asio streambuf and I am parsing it to get the requested HTML file by reading it into a vector and then taking the relevant elements such as the method or target.
Does anybody have any suggestions as to where to look for tutorials on how to parse the form data?
The code below is part of the cpp file which parses a POST request and will handle the response based on the contents of the request. the '&request' parameter is the Boost Asio streambuf
I have very little experience in web programming and would be grateful for any advice!
Code to parse requests
// Prepare and return the response message.
// Parse the request from the client to find requested document
std::istream buffer(&request);
std::vector<std::string> parsed((std::istream_iterator<std::string>(buffer)), std::istream_iterator<std::string>() );
Handling POST requests
else if (parsed.size() >= 3 && parsed[0] == "POST") {
htmlFile = "/files.html";
// Retrieve files from server file system. The second element in 'parsed' vector is file name
std::ifstream fileStream(".\\directory" + htmlFile);
// If the file exists then iterate it and assign the value to the content string variable, else return 404.
if (fileStream.good()) {
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "200 ok";
}
else {
std::ifstream fileStream(".\\directory\\404.html");
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "404";
}// End of nested if-else statement
}// End of else-if statement
else {
std::ifstream fileStream(".\\directory\\401.html");
std::string fileContents((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
content = fileContents;
code = "401";
// Write bad request to log file for security audits if not "GET" request
logging.logAction("Illegal request by client IP " + m_sock->remote_endpoint().address().to_string());
}//End of if-else statement
std::ostringstream oss;
oss << "GET HTTP/1.1 " << code << " \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\r\n";
oss << content;
response = oss.str().c_str();
boost::beastit cointains an example webserver."I have used Wireshark to inspect the packets and the data is being sent over the network."- don't use Wireshark. Use Fiddler to debug web traffic. Wireshark is for raw TCP. Fiddler provides better diagnostics for HTTP traffic.