http杂谈

2019-07-26  本文已影响0人  你跺你还麻

        因为笔者经常和协议打交道,所以这个专题就从协议入手谈一下我对协议的认识。废话不多说进入正题。

        之所以写http的协议是因为现在web开发多如猪毛,算是自己一点体会,错误的地方请大家斧正。本文根据rfc2616 http1.1撰写。

        http是Hypertext Transfer Protocol的缩写,超文本传输协议。基于OSI模型第四层的tcp,属于OSI模型的第七层,同层的还有telnet ,ftp等。下面是一个http请求的例子,以此展开。

http http

如上图所示,既然说http是文本协议,就是说是可见字符传输,不像coap,mqtt等二进制协议包含不可见字符。当然有的同学就会说了,那我不可见字符就不能传输了?废话,当然可以,要不然要payload干吗?没说payload里面不能有不可见字符啊。言归正传,下面是对上面图片的解析。

nc -l 8000 

笔者本机监听8000端口,其实就相当于一个监听8000端口tcp服务端,如果你要接受udp包加个-u参数。这里说的http协议建立在tcp连接之上大家应该能理解了。也就是说在tcp三次握手建立连接之后才开始传输http报文。

请求

POST /test HTTP/1.1

此部分包括请求方法、请求地址和协议版本,POST  表明http请求的方法,GET,POST,PUT,DELETE等,然后紧接着是一个空格,加上你要访问的资源路径加空格,再加上你采用的协议版本,这里笔者使用的是http 1.1,然后换行符,下面是http请求头部

Host: 127.0.0.1:8000

Host表明你要访问的主机+端口,这里有人会有疑问,我tcp里面连接里面已经有ip和端口了,你这里为什么还要有主机和端口,原因是由于同一个机器上面可能部署多个服务通过解析域名+端口指定服务,同时也可以用作服务端校验客户端的一种手段。在rfc1945 1.0的定义中不带host头,1.1中必须要携带host,不然会报400 bad request(也就是不是正确的http请求)

User-Agent: PostmanRuntime/7.1.1

User-Agent 客户端标识,告诉服务端这个请求是啥client发起的,要是你要限制客户端也可以在这里做文章。

Accept: */*

client想要接受的数据类型,可以是多个,大家看到*理论上应该能想到这是所有的意思啦。

Accept-Encoding: gzip, deflate

client告诉服务端,我支持gzip解压,你尽管发过来吧。

Cache-Control: no-cache

client告诉服务端不使用缓存策略,具体的大家可以google一下Cache-Control的值,了解一些http的缓存策略。

Content-Type: text/plain

告诉服务端我发送的数据是文本类型的啦,不是什么json,二进制的

Postman-Token: 16ba727a-a71d-48ed-96b5-a79c95ab512e

client自己加的,大家可以看的出来,我是使用post man发送的

X-Lantern-Version: 5.4.7

这个……不解释

在这里http请求头已经结束了,需要换行两次,可以看到图片上有个空白的一行,然后发送post请求的payload

i am client

http post请求的payload,大家可以对照Content-Type: text/plain结合着看,是个文本数据,如果我发送的是json数据的话,大家可以猜一下Content-Type的值是啥呢?

响应

HTTP/1.1 200 OK

此部分包括协议版本,状态码,状态码描述。服务端告诉客户端我采用的协议是http1.1 响应的状态是200 OK的,同样的大家猜一下如果客户端发送一个错误的http请求这里的响应应该是啥?

Server: Tengine

告诉客户端服务端信息譬如我是Apache nginx等

Date: Tue, 16 Jul 2019 07:58:07 GMT

响应时间

Content-Type: text/plain; charset=utf-8

同请求的Content-Type

Content-Length: 2

返回的数据长度(单位字节)

Connection: keep-alive

告诉client我想保持长连接,然后如果client不接受长连接那就直接tcp的挥手了。当然tcp异常端开了,服务端可能要等到下一个tcp心跳才能感知客户端已经断开。

紧接着又是两个换行。

ok

响应的paylaod,同reqest的。

所以对于一个web服务大致时序如下图:

http时序

响应码:

http的状态码可以快速的帮我们定位大致问题,一下是我据的几个例子

1、服务端tcp端口根本就没监听,你在tcp连接都建立不上,这时候一般你看到的响应是503之类的,这种就是服务不可用。你的client库自己告诉你的,其实根本没有返回

2、你请求的资源路径上没有handle处理,那服务端给你返回404,资源路径没找到

3、你发送的协议不符合http规范,400bad request

4、你使用http1.0协议请求一个http1.1的服务器,服务器会返回给你状态码101,并在响应头部告诉你服务器希望你使用的协议版本

5、你上传一个很大的文件,不知道服务器是否支持,于是你在你的请求头部添加Expect:100-continue服务端接收到你的指令希望你继续发送http请求会给你返回个100的状态码

6、301,302,303重定向相关,具体区别就是永久重定向还是单次请求重定向,浏览器会自动重定向到服务端返回指定的url

等等

下图是网上找的一个字典树的图,可以帮助大家理解后端,下期讲一下二进制协议coap,以上有错误的地方欢迎大家留言斧正。

上一篇 下一篇

猜你喜欢

热点阅读