checks-parser/http_server/http_server.cpp

114 lines
3.3 KiB
C++

#include "http_server.h"
#include <qobjectdefs.h>
#include <unistd.h>
#include <utils/utils.h>
#include <iostream>
#include <mainwindow.h>
#include <thread>
void HttpServer::generateRandomPort() {
port = rand() % (65535 - 1024) + 1024;
}
HttpServer::HttpServer(QWidget *caller) : caller(caller) {
started = false;
port = 8080;
}
HttpServer::~HttpServer() {
started = false;
shutdown(serverSocket, SHUT_RDWR);
close(serverSocket);
for (auto &thread : clientHandlersThreads) {
thread.join();
}
listenClientsThread.join();
}
int HttpServer::start() {
unsigned short number_of_retries = 0;
while (number_of_retries < 10) {
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {
std::cerr << QObject::tr("Could not obtain socket.").toStdString() << std::endl;
number_of_retries ++;
continue;
}
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
serverAddress.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
std::cerr << QObject::tr("Port ").toStdString() << port << QObject::tr(" seems to be occupied. Trying to generate another one").toStdString() << std::endl;
number_of_retries ++;
generateRandomPort();
continue;
}
if (listen(serverSocket, 1) < 0) {
std::cerr << QObject::tr("Could not listen port.").toStdString() << std::endl;
number_of_retries ++;
generateRandomPort();
continue;
}
started = true;
std::cout << QObject::tr("Listening on port: ").toStdString() << port << std::endl;
listenClientsThread = std::thread(&HttpServer::acceptClients, this);
return 0;
}
return -1;
}
void HttpServer::handleClient(int clientSocket) {
std::string localIp;
try {
localIp = get_local_ip_address();
} catch(std::exception e) {
std::cerr << e.what() << std::endl;
close(clientSocket);
return;
}
char buffer[256] = {0};
recv(clientSocket, buffer, 256, 0);
std::string response = "HTTP/1.1 301 Moved Permanently\r\n"
"Content-Length: 0\r\n"
"Keep-Alive: timeout=5, max=100\r\n"
"Location: binaryeye://scan/?ret=http://" + get_local_ip_address() + ":" + std::to_string(port) + "/?result={RESULT}\r\n"
"\r\n";
if (send(clientSocket, response.c_str(), response.length(), 0) < 0) {
std::cerr << response.c_str() << std::endl;
std::cerr << response.length() << std::endl;
std::cerr << QObject::tr("Could not send message").toStdString() << std::endl;
}
emit ((MainWindow *)caller)->httpNewMessage(QString::fromStdString(std::string(buffer)));
}
void HttpServer::acceptClients() {
while (true) {
if (!started) return;
int clientSocket = accept(serverSocket, nullptr, nullptr);
if (!started) return;
clientHandlersThreads.push_back (
std::thread(&HttpServer::handleClient, this, clientSocket)
);
}
}
unsigned short HttpServer::getPort() {
return port;
}
bool HttpServer::isStarted() {
return started;
}