Как написать обратный HTTP-прокси?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как написать обратный HTTP-прокси?

Сообщение Anonymous »

Итак, я возился с программированием сокетов и написал прямой прокси, который работает следующим образом:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 

#pragma comment(lib, "ws2_32.lib")

#define BUFFER_SIZE 8192
#define DEFAULT_PORT "87"

// Global variables
SOCKET g_listenSocket = INVALID_SOCKET;
bool g_running = false;

bool initWinsock() {
WSADATA wsaData;
return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
}

bool initServer() {
struct addrinfo* result = nullptr, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

if (getaddrinfo(NULL, DEFAULT_PORT, &hints, &result) != 0) {
return false;
}

g_listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (g_listenSocket == INVALID_SOCKET) {
freeaddrinfo(result);
return false;
}

if (bind(g_listenSocket, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
closesocket(g_listenSocket);
return false;
}

freeaddrinfo(result);

if (listen(g_listenSocket, SOMAXCONN) == SOCKET_ERROR) {
closesocket(g_listenSocket);
return false;
}

return true;
}

bool isConnectMethod(const char* request) {
return strncmp(request, "CONNECT", 7) == 0;
}

void parseHostAndPort(const char* request, char* host, char* port) {
char* line = new char[strlen(request) + 1];
strcpy(line, request);

if (isConnectMethod(line)) {
// Handle CONNECT method (HTTPS)
char* start = line + 8; // Skip "CONNECT "
char* end = strchr(start, ' ');
if (end) {
*end = '\0';
char* colon = strchr(start, ':');
if (colon) {
*colon = '\0';
strcpy(host, start);
strcpy(port, colon + 1);
}
else {
strcpy(host, start);
strcpy(port, "443");
}
}
}
else {
// Handle HTTP requests
bool foundHost = false;
char* current = line;
char* eol;

// Look for Host header
while ((eol = strstr(current, "\r\n")) != nullptr) {
*eol = '\0';
if (strncmp(current, "Host: ", 6) == 0) {
char* hostLine = current + 6;
char* colon = strchr(hostLine, ':');
if (colon) {
*colon = '\0';
strcpy(host, hostLine);
strcpy(port, colon + 1);
}
else {
strcpy(host, hostLine);
strcpy(port, "80");
}
foundHost = true;
break;
}
current = eol + 2;
}

// If no Host header found, try to parse from the request line
if (!foundHost) {
if (strncmp(line, "GET http://", 11) == 0 ||
strncmp(line, "POST http://", 12) == 0) {
char* start = strchr(line, '/') + 2;
char* end = strchr(start, '/');
if (end) {
*end = '\0';
char* colon = strchr(start, ':');
if (colon) {
*colon = '\0';
strcpy(host, start);
strcpy(port, colon + 1);
}
else {
strcpy(host, start);
strcpy(port, "80");
}
}
}
}
}

delete[] line;
}

SOCKET connectToHost(const char* host, const char* port) {
struct addrinfo hints = {}, * result = nullptr;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if (getaddrinfo(host, port, &hints, &result) != 0) {
return INVALID_SOCKET;
}

SOCKET serverSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (serverSocket == INVALID_SOCKET) {
freeaddrinfo(result);
return INVALID_SOCKET;
}

if (connect(serverSocket, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
closesocket(serverSocket);
freeaddrinfo(result);
return INVALID_SOCKET;
}

freeaddrinfo(result);
return serverSocket;
}

void handleBidirectionalTraffic(SOCKET client, SOCKET server) {
fd_set readSet;
char buffer[BUFFER_SIZE];

while (true) {
FD_ZERO(&readSet);
FD_SET(client, &readSet);
FD_SET(server, &readSet);

// Wait for data on either socket
if (select(0, &readSet, NULL, NULL, NULL) == SOCKET_ERROR) {
break;
}

// Check client -> server
if (FD_ISSET(client, &readSet)) {
int bytes = recv(client, buffer, sizeof(buffer), 0);
if (bytes 

Подробнее здесь: [url]https://stackoverflow.com/questions/79175824/how-to-write-a-reverse-http-proxy[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»