一、HTTP协议简介
超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议,自 1990 年起,HTTP 就已经被应用于 WWW 全球信息服务系统。
HTTP 是一种请求/响应式的协议。一个客户机与服务器建立连接后,发送一个请求给服务器;服务器接到请求后,给予相应的响应信息。
HTTP 的第一版本 HTTP/0.9是一种简单的用于网络间原始数据传输的协议;
HTTP/1.0由 RFC 1945 定义 ,在原 HTTP/0.9 的基础上,有了进一步的改进,允许消息以类 MIME 信息格式存 在,包括请求/响应范式中的已传输数据和修饰符等方面的信息;
HTTP/1.1(RFC2616) 的要求更加严格以确保服务的可靠性,增强了在HTTP/1.0 没有充分考虑到分层代理服务器、高速缓冲存储器、持久连接需求或虚拟主机等方面的效能;
安全增强版的 HTTP (即S-HTTP或HTTPS),则是HTTP协议与安全套接口层(SSL)的结合,使HTTP的协议数据在传输过程中更加安全
二、HTTP请求
http请求由三部分组成,分别是:请求行、消息报头、请求正文
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:
Method Request-URI HTTP-Version CRLF 其中:
Method表示请求方法;
Request-URI是一个统一资源标识符;
HTTP-Version表示请求的HTTP协议版本;
CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
http请求方法有多种,常见的有如下几个(请求方法名全为大写字母)
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
下面是用于HTTP请求中的常用请求头字段:
Accept:用于高速服务器,客户机支持的数据类型
Accept-Charset:用于告诉服务器,客户机采用的编码格式
Accept-Encoding:用于告诉服务器,客户机支持的数据压缩格式
Accept-Language:客户机的语言环境
Host:客户机通过这个头高速服务器,想访问的主机名
If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间
Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)
User-Agent:客户机通过这个头告诉服务器,客户机的软件环境
Cookie:客户机通过这个头可以向服务器带数据
Connection:处理完这次请求后是否断开连接还是继续保持连接
Date:当前时间值
HTTP响应头:
Location:这个头配合302状态码使用,用于告诉客户找谁。
Server:服务器通过这个头告诉浏览器服务器的类型。
Content-Encoding:服务器通过这个头告诉浏览器数据的压缩格式。
Content-Length:服务器通过这个头告诉浏览器回送数据的长度
Content-Type:服务器通过这个头告诉浏览器回送数据的类型
Last-Modified:告诉浏览器当前资源的最后缓存时间
Refresh:告诉浏览器隔多久刷新一次
Content-Disposition:告诉浏览器以下载方式打开数据
Transfer-Encoding:告诉浏览器数据的传送格式
ETag:缓存相关的头
后面三种禁止浏览器缓存的头字段:
Expires:告诉浏览器把回送的资源缓存多长时间 -1或0则是不缓存
Cache-Control:no-cache
Pragma:no-cache
服务器通过以上两个头,也就是控制浏览器不要缓存数据
实体内容:代表服务器向客户端回送的数据
下面是HTTP GET 请求的请求头:
1 //请求url:http://down.360safe.com/inst.exe 2 3 /*Request*/ 4 HEAD /inst.exe HTTP/1.1 " 5 "Host: down.360safe.com " 6 "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 " 7 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 " 8 "Accept-Language: zh-cn,zh;q=0.5 " 9 "Accept-Encoding: gzip,deflate " 10 "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 " 11 "Connection: close " 12 " 13 14 /*Reponse*/ 15 HTTP/1.1 200 OK 16 Server: nginx 17 Date: Sat, 23 Jul 2016 07:28:11 GMT 18 Content-Type: application/octet-stream 19 Content-Length: 1430256 20 Last-Modified: Fri, 22 Jan 2016 14:49:14 GMT 21 Connection: close 22 Expires: Sat, 23 Jul 2016 15:28:11 GMT 23 Cache-Control: max-age=28800 24 Accept-Ranges: bytes
三、组装HTTP HEAD报文
下面使我们自己组包HEAD报文从原站取head,下面贴出代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdbool.h> 5 #include <sys/socket.h> 6 #include <sys/types.h> 7 #include <netinet/in.h> 8 #include <unistd.h> 9 #include <net/if.h> 10 #include <netdb.h> //gethostbyname 11 12 #define STATUS_OK 0 13 #define STATUS_NOK 1 14 #define BUFF_MAX_LEN 1024 15 #define HOST_IP_LEN 32 16 17 #define HTTP_HEAD 18 "HEAD /%s HTTP/1.1 " 19 "Host: %s " 20 "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 " 21 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 " 22 "Accept-Language: zh-cn,zh;q=0.5 " 23 "Accept-Encoding: gzip,deflate " 24 "Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 " 25 "Connection: close " 26 " " 27 28 int getIPbyDomain(const char* domain, char* ip); 29 int parse_http_url(const char *url, char *domain, char *header); 30 31 /********************************************************** 32 * get host ip by domain 33 **********************************************************/ 34 int getIPbyDomain(const char* domain, char* ip) 35 { 36 struct hostent *answer; 37 38 answer = gethostbyname(domain); 39 if (NULL == answer) 40 { 41 return STATUS_NOK; 42 } 43 if (answer->h_addr_list[0]) 44 inet_ntop(AF_INET, (answer->h_addr_list)[0], ip, 16); 45 else 46 return STATUS_NOK; 47 return STATUS_OK; 48 } 49 50 /********************************************************** 51 * Send a http package to detect network connecting status 52 **********************************************************/ 53 int parse_http_url(const char *url, char *domain, char *header) 54 { 55 char *ptr = NULL; 56 char *host = NULL; 57 char *head = NULL; 58 char buff[BUFF_MAX_LEN] = {0}; 59 60 if (NULL == url || NULL == domain || NULL == header) 61 return STATUS_NOK; 62 63 memset(buff, 0, sizeof(buff)); 64 strcpy(buff, url); 65 66 host = strtok(buff + 7, "/"); 67 head = strtok(NULL, "