简单解析一下http协议
首先说,http协议是基于TCP协议实现的,http协议首先是文本协议(请区别于二进制协议),其次他还是超文本协议。超文本传输协议的意思就是出了传递文本消息,他真也能传递二进制数据,比如图片,甚至其他流媒体信息。
一般说来,tcp的数据是流式的,所以判断数据包就是靠数据边界来识别的。一般说来,识别数据边界靠的是两种办法,一种是特殊字符,另一种就是包头定长+包体这种办法。那么我们通过这方面来透析http协议,其实这东西没那么神秘。
下面,我请求了一下http://so.com?username=wahaha,然后通过charles找到这条访问记录,然后将raw这次请求(注意是请求,不是应答)的信息全部抓了下来:
GET /?username=wahah HTTP/1.1 Host: so.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: __guid=15484592.1828564546403386400.1536323769395.3423 Connection: keep-alive
好了,以上信息就是这次访问http://so.com?username=wahaha请求产生的http信息,那么我们来解析一些:
- 第一行叫做请求行。GET /?username=wahah HTTP/1.1,交代了三个问题,访问方法是GET,queryString是username=wahah,http版本是1.1。那么我们在使用一些php框架的时候,类似于$this->input->get(‘username’)这样的方法就是通过解析这个来实现的;那么当然了,类似于$this->request()->isGet()判断这次请求是不是GET方法,也是根据这一行来实现的。其中GET和/?username=wahah之间有一个空格,/?username=wahah和HTTP/1.1之间又是一个空格。这一行的最后,是一个回车换行符。
- 从第二行Host: so.com开始一直到Connection: keep-alive中间这一坨叫做请求头,也就是传说中的http header。每个http header之间,都在结尾用一个回车换行符实现换行;每一行都是一个典型的key:value型文本。有一些php框架中类似于$this->request()->header(‘User-Agent’)就是通过解析这一坨字符串来实现的。
- 然后,就空了。实际上并不是,因为这个GET方法,下面我们看下POST方法(注意依旧是请求,不是响应):
POST / HTTP/1.1 Content-Type: application/x-www-form-urlencoded cache-control: no-cache Postman-Token: 9535f6cf-d539-48a4-9f06-e1ae61c1c9ed User-Agent: PostmanRuntime/7.2.0 Accept: */* Host: so.com accept-encoding: gzip, deflate content-length: 14 Connection: keep-alive username=wahha
注意,Connection: keep-alive之后,这次有东西了,因为这是POST方法,Connection: keep-alive之后的内容就是传说中的http body体了。http body和http header之间是通过两个回车换行符实现的。http body中的内容就是提交上来的数据,也就是username=wahha,一些php框架中类似于$this->request()->post(‘username’)就是通过解析这段字符串实现的,明白了吧。
下面,我们开始http响应。上面是我们发出去的请求,然后服务回应了,我们看回应,还是上面这个POST请求,响应如下:
HTTP/1.1 301 Moved Permanently Server: openresty Date: Fri, 07 Sep 2018 13:07:44 GMT Content-Type: text/html Content-Length: 178 Location: https://www.so.com?src=so.com Connection: keep-alive <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html>
第一行,叫做响应行,关键字就是HTTP/1.1说明了http版本,然后一个空格就是大名鼎鼎的http状态码了,之后一个空格,表示301的含义!然后一个回车换行。
第二行开始,就是一坨http header了,没什么好说的
然后又是两个回车换行,来到了http响应body。也就是那一坨<html>.... ....</html>代码
如果让你用php语言去解析http协议,现在你应该能做到了吧?