Anonymous
Как написать обратный HTTP-прокси?
Сообщение
Anonymous » 11 ноя 2024, 00:09
Итак, я возился с программированием сокетов и написал прямой прокси, который работает следующим образом:
Код: Выделить всё
#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]
1731272947
Anonymous
Итак, я возился с программированием сокетов и написал прямой прокси, который работает следующим образом: [code]#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]