我正在使用C ++代码获取特定网站的HTML源代码。 一个函数创建HTTP请求,其他函数发送它。
但是当我尝试以相同的方式访问网站时,除了TOR(SOCKS5),我得到HTTP 400 Bad Request response
。请求两次都是相同的,我可以通过Wiresahrk /调试看到它是正确的。
似乎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.1\r\n";
request = request + "Host: " + info.Host + "\r\n";
request = request + "User-Agent: " + UA + "\r\n";
request = request + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
request = request + "Accept-Language: en-US;q=0.7,en;q=0.3\r\n";
if(Cookie != ""){
request = request + "Cookie: " + Cookie + "\r\n";
}
request = request + "Connection: close\r\n\r\n";
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中请求的图片:
正如我所说,具有完全相同的功能,只是没有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;
}
只是另一个更新。在我的代码中没有更改任何内容的情况下,我重新编写了我的程序,现在它似乎适用于大多数网站,尽管我有时会得到以下响应:
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代理端口)的传出请求,并且传入了en1与tcpdump,它们都是完全相同的,逐字节。 所以问题不依赖于TOR或socks5代理。请求按照应该和发送的方式到达,但会产生400个错误请求。
正如服务器的整个世界知道我在代理后面并阻止我......
另一个更新,也许是最重要的一个:调试erro_log中的Apache报告:AH00566:请求失败:URI中的字符无效
但是,再看看请求/响应,没有无效的字符......