#include "http_server.h" #include #include #include #include #include #include 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; }