我正在制作一个 http c 客户端套接字。到目前为止,我已经制作了一个自定义 url 解析器,现在问题是连接到绝对 url。该程序适用于相对 URL,但不适用于绝对 URL。
这里是绝对和相对 url 结果的示例输出:
相对网址:http://techpatterns.com/downloads/firefox/useragentswitcher.xml
在绝对 url 中,它给出 301/302 状态代码,而在相对 url 中,状态为 200 OK
这里是关键区域的示例代码
char ip[100],*path, *domain, *abs_domain, *proto3;
char *user_agent = "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0";
char *accept_type = "Accept: text/html, application/xhtml+xml, */*\r\nAccept-Language: en-US\r\n";
char *encoding = "Accept-Encoding: gzip, deflate\r\n";
char *proxy_conn = "Proxy-Connection: Keep-Alive\r\n";
char hostname[1000];
url:
fgets(hostname,sizeof(hostname), stdin);
for(i=0; i<strlen(hostname);i++){//remove new line
if(hostname[i]=='\n'){
hostname[i]='\0';
}
}
proto3 = get_protocol(hostname); //get protocol i.e. http, ftp, etc
//get domain ie http://mail.google.com/index -> mail.google.com
//http://www.google/com/ssl_he -> www.google.com
domain = get_domain(hostname);
if(strlen(domain)==0){
printf("invalid url\n\n");
goto url;
}
abs_domain = get_abs_domain(hostname);//gets abs domain google.com, facebook.com etc
path = get_path(hostname);
//getting the ip address from the hostname
if ( (he = gethostbyname( abs_domain ) ) == NULL)
{
printf("gethostbyname failed : %d" , WSAGetLastError());
goto url;
}
//Cast the h_addr_list to in_addr , since h_addr_list also has the ip address in long format only
addr_list = (struct in_addr **) he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++)
{
//Return the first one;
strcpy(ip , inet_ntoa(*addr_list[i]) );
}
clientService.sin_addr.s_addr = inet_addr(ip);
clientService.sin_family = AF_INET;
clientService.sin_port = htons(80);
sprintf(sendbuf, "GET /%s HTTP/1.1\r\n%sUser-Agent: %s\r\nHost: %s\r\n\r\n", path,accept_type,user_agent, abs_domain);
代码简要说明:
即如果用户输入的url是http://mail.deenze.com/control_panel/index.php
协议(protocol)将是 -> http
域将是 -> mail.deenze.com
abs_domain 将是 -> deenze.com
路径将是 control_panel/index.php
最后,这个值将与用户代理一起用于发送数据。
最佳答案
301 and 302 status codes are redirects ,不是错误。它们表示您应该改为尝试在不同的 URL 请求。
在这种情况下,尽管您输入了 URL http://www.google.com/
,但您发送的 Host
header 看起来像是包括 google.com
。 Google 会向您发回重定向,告诉您改用 www.google.com
。
我注意到您似乎有一个 get_abs_domain
函数正在剥离 www
;你没有理由这样做。 www.google.com
和 google.com
是不同的主机名,可能会为您提供完全不同的内容。实际上,大多数站点都会为您提供相同的结果,但您不能依赖于此;有些会从一个重定向到另一个,有些会简单地提供相同的内容,有些可能只在一个或另一个工作。
与其尝试将一个重写为另一个,不如按照返回的任何重定向进行操作。
我会建议使用现有的 HTTP 客户端库,而不是尝试编写您自己的库(除非这只是为了您自己的启发而进行的练习)。例如,有 cURL如果你想便携或HttpClient如果您只需要在 Windows 上工作(根据您的屏幕截图,我假设这是您正在使用的平台)。编写一个可以实际处理大部分 Web 的 HTTP 客户端非常复杂; SSL、压缩、重定向、分块传输编码等。
关于c - http c 客户端套接字中的 301/302 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25303773/