C ++ HTTP over SOCKS5(TOR)400错误请求

我有工作C ++代码获取特定网站的HTML源代码。 一个函数创建HTTP请求和其他函数发送它。

但是当我尝试以同样的方式访问网站时,除了使用TOR(SOCKS5),我得到了HTTP 400 Bad Request response 。 请求两次都是一样的,我可以通过Wiresahrk / debugging看到它是正确的。

似乎TOR可能会搞砸某些东西,但其他需要通过TOR发送HTTP / HTTPS请求的工具似乎能够正常工作。

以下是我的代码的一些片段:

主要

int main(int argc, const char * argv[]) {

bool use_tor = false;

if(argc < 3){

    std::cout << "[!] Please supply a url and 0 for no tor or 1 for tor." << std::endl;

    return -1;

}

if(strcmp(argv[2],"1")==0){

    use_tor = true;

}

        int sock = createSocket();

        if(use_tor){

            SOCKS5_Greeting_Response socks_gresp;
            SOCKS5_Command_Response socks_cresp;

            socketConnect(sock, "127.0.0.1", 9050);

            socks_gresp = socketWriteSOCKS5Greeting_TOR(sock);

            if(socks_gresp.Version != 5){

                std::cout << std::endl << "[!] SOCKS5 Version mismatch!" << std::endl;

                closeSocket(sock);

                return -1;

            }

            socks_cresp = SOCKS5_Connect(sock, get_IPv4(argv[1]), 80);

            if(socks_cresp.Reply != 0){

                std::cout << std::endl << "[!] SOCKS5 Connection failed!" << std::endl;

                closeSocket(sock);

                return -1;

            }

        }
        else{

            socketConnect(sock, argv[1], 80);

        }

        socketWrite(sock, generate_basic_GET_request("url","UA",""));

        socketRead(sock)

        closeSocket(sock);
}

http的东西

std::string generate_basic_GET_request(std::string url, std::string UA, std::string Cookie){

splitted_host info = parse_host(url);

std::string request;

request = "GET " + info.GET + " HTTP/1.1rn";
request = request + "Host: " + info.Host + "rn";
request = request + "User-Agent: " + UA + "rn";
request = request + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rn";
request = request + "Accept-Language: en-US;q=0.7,en;q=0.3rn";

if(Cookie != ""){
    request = request + "Cookie: " + Cookie + "rn";
}

request = request + "Connection: closernrn";

std::cout << std::endl << request << "----END-----" << std::endl << std::endl;

return request;

}

这是我的代码的输出:

GET / HTTP/1.1
Host: www.host.de
User-Agent: UA
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US;q=0.7,en;q=0.3
Connection: close

----END-----

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>

这是Wireshark中请求的图片:

HTTP请求的Wireshark快照

正如我所说的,具有完全相同的功能,只是没有SOCKS5代理,我可以像获得HTML代码一样工作。

这方面的一些消息:

我会在下面发布我的SOCKS5代码,但首先要做的事情。

我设置了portforwarding并连接到自己,监听'ncat -vvl 80',并且能够接收带有或不带有SOCKS5代理的发送头。 标题看起来是正确的,所以一切都应该没问题。

现在我知道我实际上可以成功连接到SOCKS5代理; 代理连接到所需的网站并发送数据。 那不是问题。 由于头部应该是这样,我真的不知道为什么这个400错误的请求错误发生。 由于完全相同的头文件与直接连接一起工作,并且代理服务器不是问题,因此不应该发生此错误。

使用Google上公用列表中的某些免费SOCKS5代理时,会发生同样的错误。 所以它必须是我的SOCKS5代码。

但是当它发生的时候,某些东西一定是错的。 我希望有人能找到它!

这是我的代码(是的,它不是完美的,有时不是最好的实现方式):

struct SOCKS5_Greeting{

unsigned char Version;
unsigned char NumberOfMethods;
unsigned char Methods[256];

};

struct SOCKS5_Greeting_Response{

unsigned char Version;
unsigned char Method;

};

struct SOCKS5_Command{

unsigned char Version;
unsigned char Cmd;
unsigned char Reserved = 0x00;
unsigned char AddrType;
union{
    in_addr_t IPv4;
} DestAddr;
unsigned short DestPort;

};

struct SOCKS5_Command_Response{

unsigned char Version;
unsigned char Reply;
unsigned char Reserved = 0x00;
unsigned char AddrType;
union{
    in_addr_t IPv4;
} BindAddr;
unsigned short BindPort;

};

SOCKS5_Greeting_Response socketWriteSOCKS5Greeting_TOR(int sock){

SOCKS5_Greeting req;
SOCKS5_Greeting_Response resp;

req.Version = 5;
req.NumberOfMethods = 1;
req.Methods[0] = 0x00; //No Auth

send(sock, &req, 2+req.NumberOfMethods, 0);

recv(sock, &resp, sizeof(resp), 0);

return resp;

}

SOCKS5_Command_Response SOCKS5_Connect(int sock, std::string dest_str, unsigned short port){

SOCKS5_Command req;
SOCKS5_Command_Response resp;

in_addr_t dest = inet_addr(dest_str.c_str());

req.Version = 5;
req.Cmd = 1;
req.AddrType = 1;
req.DestAddr.IPv4 = dest;
req.DestPort = htons(port);

send(sock, &req, sizeof(req), 0);

recv(sock, &resp, sizeof(resp), 0);

return resp;

}

int createSocket(){

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

return sockfd;

}

void closeSocket(int sock){

close(sock);

}

int socketConnect(int sock, const char *address, int port){

struct hostent *server;
struct sockaddr_in serv_addr;

server = gethostbyname(address);

if(server == NULL){
    return -1;
}

bzero((char *) &serv_addr, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

serv_addr.sin_port = htons(port);

if(connect(sock,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
    return -1;
}
else{
    return 0;
}

}

int socketWrite(int sock, std::string data){

char buffer[512];

int error;

std::string chunk;

if(data.length() > 511){

    while(data.length() > 0){

        if(data.length() >= 511){

            chunk = data.substr(0, 511);

            data = data.substr(511, data.length());

        }
        else{

            chunk = data;

            data = "";

        }

        bzero(buffer, 512);

        chunk.copy(buffer, chunk.length());

        error = write(sock, buffer, strlen(buffer));

        if(error < 0){
            return error;
        }

    }

}
else{

    bzero(buffer, 512);

    data.copy(buffer, 512);

    error = write(sock, buffer, strlen(buffer));

}

return error;

}

std::string socketRead(int sock){

std::string response = "";

char buffer[512];

int bytes;

while((bytes = read(sock, buffer, 511)) > 0){

    std::string temp(buffer, bytes);

    response = response + temp;

    bzero(buffer, 512);

}

return response;

}

更新2:

只是另一个更新。 在不改变我的代码中的任何内容的情况下,我重新执行了我的程序,现在它似乎适用于大多数网站,尽管我有时会得到以下回复:

HTTP/1.1 501 Not Implemented
Date: Sat, 06 Feb 2016 21:43:08 GMT
Server: Apache
Allow: OPTIONS,GET,HEAD,POST
Vary: Accept-Encoding
Content-Length: 240
Content-Type: text/html; charset=iso-8859-1
Connection: close

这实际上使这更奇怪...

另一个更新:现在它不再工作,400个不好的请求,1分钟后似乎工作。 我不明白...

只是另一个更新:我设置端口转发,通过ncat(nmap工具)打开一个端口,使用Wireshark监视lo0(到TOR的socks5代理端口)上的传出请求,并使用tcpdump监听en1上的传入请求,它们都是同样,字节为字节。 所以这个问题不依赖于TOR或者socks5代理。 该请求按照原样发送,但会产生400个错误的请求。

正如服务器的整个世界知道我在代理后面并阻止我......

另一个更新,也许是最重要的一个: Apache在debug erro_log报告中:AH00566:请求失败:URI中的无效字符

但是,再看看请求/响应,没有无效的字符......

链接地址: http://www.djcxy.com/p/62649.html

上一篇: C++ HTTP over SOCKS5 (TOR) 400 Bad Request

下一篇: C# running websocket connection under tor circuit