#include "utility.hh"
#include "webserver.hh"
#include "misc.hh"
+#include <thread>
#include <vector>
#include "logger.hh"
#include <stdio.h>
struct connectionThreadData {
WebServer* webServer{nullptr};
- Socket* client{nullptr};
+ std::shared_ptr<Socket> client{nullptr};
};
json11::Json HttpRequest::json()
registerBareHandler(url, f);
}
-static void *WebServerConnectionThreadStart(void *p) {
- connectionThreadData* data = static_cast<connectionThreadData*>(p);
- pthread_detach(pthread_self());
+static void *WebServerConnectionThreadStart(std::shared_ptr<connectionThreadData> data) {
data->webServer->serveConnection(data->client);
-
- delete data->client; // close socket
- delete data;
-
- return NULL;
+ return nullptr;
}
void WebServer::handleRequest(HttpRequest& req, HttpResponse& resp)
}
}
-void WebServer::serveConnection(Socket *client)
+void WebServer::serveConnection(std::shared_ptr<Socket> client)
try {
HttpRequest req;
YaHTTP::AsyncRequestLoader yarl;
if(!d_server)
return;
try {
- pthread_t tid;
-
NetmaskGroup acl;
acl.toMasks(::arg()["webserver-allow-from"]);
while(true) {
// data and data->client will be freed by thread
- connectionThreadData *data = new connectionThreadData;
+ auto data = std::make_shared<connectionThreadData>();
data->webServer = this;
try {
data->client = d_server->accept();
if (data->client->acl(acl)) {
- pthread_create(&tid, 0, &WebServerConnectionThreadStart, (void *)data);
+ std::thread webHandler(WebServerConnectionThreadStart, data);
+ webHandler.detach();
} else {
ComboAddress remote;
if (data->client->getRemote(remote))
L<<Logger::Error<<"Webserver closing socket: remote ("<< remote.toString() <<") does not match 'webserver-allow-from'"<<endl;
- delete data->client; // close socket
- delete data;
}
}
catch(PDNSException &e) {
L<<Logger::Error<<"PDNSException while accepting a connection in main webserver thread: "<<e.reason<<endl;
- delete data->client;
- delete data;
}
catch(std::exception &e) {
L<<Logger::Error<<"STL Exception while accepting a connection in main webserver thread: "<<e.what()<<endl;
- delete data->client;
- delete data;
}
catch(...) {
L<<Logger::Error<<"Unknown exception while accepting a connection in main webserver thread"<<endl;
- delete data->client;
- delete data;
}
}
}
ComboAddress d_local;
- Socket *accept() {
- return d_server_socket.accept();
+ std::shared_ptr<Socket> accept() {
+ return std::shared_ptr<Socket>(d_server_socket.accept());
}
protected:
void bind();
void go();
- void serveConnection(Socket *client);
+ void serveConnection(std::shared_ptr<Socket> client);
void handleRequest(HttpRequest& request, HttpResponse& resp);
typedef boost::function<void(HttpRequest* req, HttpResponse* resp)> HandlerFunction;
void AsyncServerNewConnectionMT(void *p) {
AsyncServer *server = (AsyncServer*)p;
try {
- Socket* socket = server->accept();
+ auto socket = server->accept();
server->d_asyncNewConnectionCallback(socket);
- delete socket;
} catch (NetworkError &e) {
// we're running in a shared process/thread, so can't just terminate/abort.
return;
}
// This is an entry point from FDM, so it needs to catch everything.
-void AsyncWebServer::serveConnection(Socket *client)
+void AsyncWebServer::serveConnection(std::shared_ptr<Socket> client)
try {
HttpRequest req;
YaHTTP::AsyncRequestLoader yarl;
string data;
try {
while(!req.complete) {
- int bytes = arecvtcp(data, 16384, client, true);
+ int bytes = arecvtcp(data, 16384, client.get(), true);
if (bytes > 0) {
req.complete = yarl.feed(data);
} else {
data = ss.str();
// now send the reply
- if (asendtcp(data, client) == -1 || data.empty()) {
+ if (asendtcp(data, client.get()) == -1 || data.empty()) {
L<<Logger::Error<<"Failed sending reply to HTTP client"<<endl;
}
}
friend void AsyncServerNewConnectionMT(void *p);
- typedef boost::function< void(Socket*) > newconnectioncb_t;
+ typedef boost::function< void(std::shared_ptr<Socket>) > newconnectioncb_t;
void asyncWaitForConnections(FDMultiplexer* fdm, const newconnectioncb_t& callback);
private:
private:
FDMultiplexer* d_fdm;
- void serveConnection(Socket *socket);
+ void serveConnection(std::shared_ptr<Socket> socket);
protected:
virtual std::shared_ptr<Server> createServer() override {