Код: Выделить всё
#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]