+#include "server.h"
#include <exception>
#include <typeinfo>
#include <msp/core/maputils.h>
-#include <msp/core/refptr.h>
#include <msp/debug/demangle.h>
#include <msp/net/inet.h>
#include <msp/net/resolve.h>
#include <msp/strings/utils.h>
#include "request.h"
#include "response.h"
-#include "server.h"
using namespace std;
void Server::listen(unsigned port)
{
- RefPtr<Net::SockAddr> addr = Net::resolve("*", format("%d", port), Net::INET6);
+ unique_ptr<Net::SockAddr> addr(Net::resolve("*", format("%d", port), Net::INET6));
sock.listen(*addr, 8);
sock.signal_data_available.connect(sigc::mem_fun(this, &Server::data_available));
}
void Server::data_available()
{
- Net::StreamSocket *csock = sock.accept();
- clients.push_back(Client(csock));
- csock->signal_data_available.connect(sigc::bind(sigc::mem_fun(this, &Server::client_data_available), sigc::ref(clients.back())));
- csock->signal_end_of_file.connect(sigc::bind(sigc::mem_fun(this, &Server::client_end_of_file), sigc::ref(clients.back())));
+ unique_ptr<Net::StreamSocket> csock(sock.accept());
+ clients.emplace_back(move(csock));
+ Client &cl = clients.back();
+ cl.sock->signal_data_available.connect(sigc::bind(sigc::mem_fun(this, &Server::client_data_available), sigc::ref(clients.back())));
+ cl.sock->signal_end_of_file.connect(sigc::bind(sigc::mem_fun(this, &Server::client_end_of_file), sigc::ref(clients.back())));
if(event_disp)
- event_disp->add(*csock);
+ event_disp->add(*cl.sock);
}
void Server::client_data_available(Client &cl)
return;
}
- RefPtr<Response> response;
+ unique_ptr<Response> response;
if(!cl.request)
{
if(cl.in_buf.find("\r\n\r\n")!=string::npos || cl.in_buf.find("\n\n")!=string::npos)
{
try
{
- cl.request = new Request(Request::parse(cl.in_buf));
+ cl.request = make_unique<Request>(Request::parse(cl.in_buf));
string addr_str = cl.sock->get_peer_address().str();
- string::size_type colon = addr_str.find(':');
+ string::size_type colon = addr_str.find(':', (addr_str[0]=='[' ? addr_str.find(']')+1 : 0));
cl.request->set_header("-Client-Host", addr_str.substr(0, colon));
if(cl.request->get_method()!="GET" && cl.request->get_method()!="POST")
{
- response = new Response(NOT_IMPLEMENTED);
+ response = make_unique<Response>(NOT_IMPLEMENTED);
response->add_content("Method not implemented\n");
}
else if(cl.request->get_path()[0]!='/')
{
- response = new Response(BAD_REQUEST);
+ response = make_unique<Response>(BAD_REQUEST);
response->add_content("Path must be absolute\n");
}
}
catch(const exception &e)
{
- response = new Response(BAD_REQUEST);
+ response = make_unique<Response>(BAD_REQUEST);
response->add_content(format("An error occurred while parsing request headers:\ntype: %s\nwhat: %s",
Debug::demangle(typeid(e).name()), e.what()));
}
if(cl.request->has_header("Connection"))
cl.keepalive = !strcasecmp(cl.request->get_header("Connection"), "keep-alive");
- response = new Response(NONE);
+ response = make_unique<Response>(NONE);
try
{
- cl.response = response.get();
- responses[cl.response] = &cl;
- signal_request.emit(*cl.request, *response);
- if(cl.async)
- response.release();
- else
+ cl.response = move(response);
+ responses[cl.response.get()] = &cl;
+ signal_request.emit(*cl.request, *cl.response);
+ if(!cl.async)
{
- responses.erase(cl.response);
- cl.response = 0;
+ responses.erase(cl.response.get());
+ response = move(cl.response);
if(response->get_status()==NONE)
{
- response = new Response(NOT_FOUND);
+ response = make_unique<Response>(NOT_FOUND);
response->add_content("The requested resource was not found\n");
}
}
}
catch(const exception &e)
{
- responses.erase(cl.response);
- cl.response = 0;
- response = new Response(INTERNAL_ERROR);
+ responses.erase(cl.response.get());
+ cl.response.reset();
+ response = make_unique<Response>(INTERNAL_ERROR);
response->add_content(format("An error occurred while processing the request:\ntype: %s\nwhat: %s",
Debug::demangle(typeid(e).name()), e.what()));
}
cl.async = false;
if(cl.keepalive)
{
- delete cl.request;
- cl.request = 0;
- delete cl.response;
- cl.response = 0;
+ cl.request.reset();
+ cl.response.reset();
}
else
{
}
-Server::Client::Client(RefPtr<Net::StreamSocket> s):
- sock(s)
+Server::Client::Client(unique_ptr<Net::StreamSocket> s):
+ sock(move(s))
{ }
-Server::Client::~Client()
-{
- delete request;
- delete response;
-}
-
} // namespace Http
} // namespace Msp