Реализовать HTTP server, позволяющий производить математические вычисления по запросу. Поддерживаемые методы - GET, POST Возможные математические вычисления: факториал, число фибоначчи, среднее арифметическое, значение тригонометрических функций, корень, степень. Библиотека для реализации сетевого взаимодействия - boost asio. Добавить возможность многопоточной обработки запросов.
Пример базовой реализации сервера:
#include <iostream>
#include <ostream>
#include <istream>
#include <ctime>
#include <string>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
using boost::asio::ip::tcp;
class HttpServer;
class Request : public boost::enable_shared_from_this<Request>
{
static std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return boost::lexical_cast<std::string>(now);
}
// member variables
HttpServer& server;
boost::asio::streambuf request;
boost::asio::streambuf response;
void afterRead(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
// done reading, writes answer (yes, we ignore the request);
std::ostream res_stream(&response);
// gets daytime string
std::string time = make_daytime_string();
res_stream << "HTTP/1.0 200 OK\r\n"
<< "Content-Type: text/html; charset=UTF-8\r\n"
<< "Content-Length: " << time.length() + 2 << "\r\n\r\n"
<< time << "\r\n";
boost::asio::async_write(*socket, response, boost::bind(&Request::afterWrite, shared_from_this(), _1, _2));
}
void afterWrite(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
// done writing, closing connection
socket->close();
}
public:
boost::shared_ptr<tcp::socket> socket;
Request(HttpServer& server);
void answer()
{
if (!socket) return;
// reads request till the end
boost::asio::async_read_until(*socket, request, "\r\n\r\n",
boost::bind(&Request::afterRead, shared_from_this(), _1, _2));
}
};
class HttpServer
{
public:
HttpServer(unsigned int port) : acceptor(io_service, tcp::endpoint(tcp::v4(), port)) {}
~HttpServer() { if (sThread) sThread->join(); }
void Run()
{
sThread.reset(new boost::thread(boost::bind(&HttpServer::thread_main, this)));
}
boost::asio::io_service io_service;
private:
tcp::acceptor acceptor;
boost::shared_ptr<boost::thread> sThread;
void thread_main()
{
// adds some work to the io_service
start_accept();
io_service.run();
}
void start_accept()
{
boost::shared_ptr<Request> req(new Request(*this));
acceptor.async_accept(*req->socket,
boost::bind(&HttpServer::handle_accept, this, req, _1));
}
void handle_accept(boost::shared_ptr<Request> req, const boost::system::error_code& error)
{
if (!error) { req->answer(); }
start_accept();
}
};
Request::Request(HttpServer& server) : server(server)
{
socket.reset(new tcp::socket(server.io_service));
}
int main(int argc, char* argv[])
{
HttpServer server(8080);
server.Run();
}