113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
#include "http_server.h"
|
|
#include <qobjectdefs.h>
|
|
#include <unistd.h>
|
|
#include <utils/utils.h>
|
|
#include <iostream>
|
|
#include <ofdscene.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 << "Could not obtain socket." << 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 << "Port " << port << " seems to be occupied. Trying to generate another one" << std::endl;
|
|
number_of_retries ++;
|
|
generateRandomPort();
|
|
continue;
|
|
}
|
|
|
|
if (listen(serverSocket, 1) < 0) {
|
|
std::cerr << "Could not listen port." << std::endl;
|
|
number_of_retries ++;
|
|
generateRandomPort();
|
|
continue;
|
|
}
|
|
started = true;
|
|
std::cout << "Listening on port: " << 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 << "Could not send message" << std::endl;
|
|
}
|
|
emit ((OFDScene *)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;
|
|
}
|