《HTTP权威指南》学习总结(上)
写在前面:
因为想了解一些关于反向代理以及负载均衡等中间件的知识,所以在此之前就打算把计算机网络相关的一些东西回顾一下。所以从刚放寒假那会儿就开始看《HTTP权威指南》(后面统称指南)。书中的内容非常丰富,关于HTTP的各个方面都有所涉及。但是由于出版时间较长,书中很多东西放到现如今来看已经是过时的东西了。故本人又买了一本《图解HTTP》(后面统称图解)。两书相较,其实内容大部分都相同,只不过后者针对HTTP 2.0等较新的知识做了简要介绍。其实个人觉得指南一书不必深究,但是基本知识必须掌握,可以当作字典用。而图解一书内容比较精炼,可以当作备忘使用手册使用。
因为最近一直在做客所以没有写读书笔记,一直拖到大年初六初七才动笔,实属不该。本文主要是针对本人学习《HTTP权威指南》一书的学习心得等进行记录。如果有表述不当或者是表达错误的地方,烦请在评论区指正!
总结我将分为两部分
- 第一部分主要是HTTP基本的一些东西,包括报文格式、传递信息的方式以及状态码和方法等知识的总结
- 第二部分将对其连接管理、代理、缓存、Web服务器等知识进行总结。
HTTP概述
HTTP是什么?
HTTP是一种用于在通信双方(通常是客户端和服务器端)传输数据(包括但不限于图片、文本、音频等)的可靠的数据传输协议。值得注意的是,这里的可靠指的并不是信息不会被第三方窃取,而是说HTTP协议在大部分时候可以确保数据在传输的过程中可以保持有序和完整。若想保证使用HTTP协议传输数据不被窃取,需要一种安全的HTTP形式(后面会介绍)。
略微详细地说说HTTP是如何工作的
客户端通过向服务器端发送HTTP请求报文请求所需资源。通常这个请求是通过访问URL发起的。服务器端接收到请求报文之后再解析报文,识别出客户端所需的资源并从对应的存储区域取到该资源,然后生成HTTP相应报文并附带状态码以及对应的资源返回给客户端,一次HTTP请求和相应的过程到此结束。有时客户端可能并不是想获得某种资源,而是想更改或者是删除服务器端上的某个资源。其实过程都是类似的,只不过是请求和响应报文中的内容有所不同。(这里的内容指的是报文本身,而不是单独说报文的主体部分。因为首部等也会有差别)
资源
Web服务器是Web资源的宿主。Web资源是Web内容的源头。最最简单的Web资源就是一些静态文件。这些文件可以包含任意内容:文本文档、HTML页面、各种格式的图片、音频等其他所有我们可以想到的格式。
但是呢,资源不一定是静态文件,也可以是根据我们的需要动态生成的内容。比如说股票行情的走势或者是天气预报等等。
媒体类型
Web服务器在回送HTTP对象数据的时候会加上一个MIME类型,即告诉客户端返回的是什么类型的数据。通常客户端都会查看响应报文中标明的MIME类型,以此来判断自己是否有能力处理服务器返回的内容。
与数据内容一起回送的MIME类型部分MIME类型:常见的MIME类型有几百个,这里不一一列举
- text/html:HTML格式的文本文档
- text/plain:普通的ASCⅡ文本文档
- image/jpeg:JPEG格式的图片
- image/gif:GIF格式的图片
URI(统一资源标识符)
每个Web服务器资源都拥有其特有的名字,这样才能使得客户端准确地向服务器端发送资源请求的报文。而服务器资源名被称为统一资源标识符(Uniform Resource Identifier),即URI。URI就像邮政地址一样,可以唯一标识对应的资源。
形如 http://jwc.jxnu.edu.cn/images/new/banner1.jpg 就是某网站中一张图片资源的URI:
- http:使用HTTP协议
- jwc.jxnu.edu.cn:进入域名为jwc.jxnu.edu.cn的网站
- /images/new/banner1.jpg:获取名为/images/new/banner1.jpg的图片资源
其实URI有两种形式,分别为URL(Uniform Resource Locators)统一资源定位符和URN(Uniform Resource Names)统一资源名称。
URL(统一资源定位符)
URL是URI最常见的表现形式。URL描述了一台特定服务器上某资源的特定位置。它们可以明确地说明应该使用何种服务,如何从一个精确、固定的位置获取资源。其实http://jwc.jxnu.edu.cn/images/new/banner1.jpg就是一个URL。
大部分的URL都遵循一种特定的格式:
- 第一部分被称为方案,说明了访问该资源所使用的协议类型。可以是HTTP,也可以是FTP等。
- 第二部分给出了服务器的因特网地址
- 其余部分指定了该地址对应服务器上的某个资源
URN(统一资源名称)
URI的第二种形式就是URN。URN是作为特定资源的唯一名称使用的,与目前资源的存储地址无关。主要作用是用来标明资源的名称,这个名称在特定的命名空间中。因此,我们也许可以通过不同的协议来访问该资源。
那么URI、URL以及URN三者之间到底存在什么关系呢?
依照我的理解,我觉得URI(Uniform Resource Indentifier)重点在Indentifier,即标识。什么意思呢?就是URI可以确切地标识一个资源。它不仅可以通过网络地址标识资源,还可以在某个命名空间中对资源进行标识。URL和URN分别是URI的两种表现形式。URL的侧重点在对某个网络地址中的资源进行准确标识,而URN的侧重点则放在对某个命名空间中的资源名称进行标识。
事务
一条HTTP事务是由一条由客户端发往服务器端的请求命令和一条由服务器端返还给客户端的响应结果组成。
方法
HTTP支持一些不同的请求命令,这些命令被称为HTTP方法(HTTP method)。其实每条HTTP请求都会包含一个方法,这个方法会告诉服务器应该执行什么动作(获取一个Web页面、删除某个资源或者是运行一个网关程序等)。
常见的几个HTTP方法
- GET 从服务器向客户端发送命名资源
- PUT 将客户端录入的数据存储到一个命名的服务器资源中去
- DELET 从服务器删除命名资源
- POST 将客户端数据发送到一个服务器网关应用程序
- HEAD 仅发送命名资源响应中的HTTP首部
咦??是不是突然发现PUT和POST这两个方法的作用看起来是不是很相似啊?的确,一开始我也糊涂了。既然都是将客户端数据发送到服务器端,那么二者的区别在什么地方呢?
经过一番搜索,我在stackoverflow上找到了一个关于HTTP中PUT和POST的讨论:
http://stackoverflow.com/questions/630453/put-vs-post-in-rest
其实我感觉PUT和POST的本质上的区别在于是否具有幂等性。因为二者都可以用于create和update,所以到底如何使用在于我们自己的考虑。如果您有更好的理解,欢迎在评论区进行探讨~
关于HTTP方法更详细的介绍我将放在HTTP报文部分
状态码
每条HTTP响应报文返回时都会携带一个状态码,用于告知客户端请求是否成功或者是否需要执行其他动作。状态码由三位数字组成。
- 200 表示OK,资源正确返回
- 302 重定向
- 404 Not Found
在介绍HTTP报文的时候会详细说说状态码
HTTP报文
HTTP就如因特网中的信使,给通信双方传递信息。而HTTP报文就是它用来传递信息的包裹了。在这一模块,我大致将总结以下几个部分(在参照书中原有内容的基础上增加了自己的理解):
- 报文流
- HTTP报文的语法及结构
- HTTP报文是如何传递的
- 请求报文和响应报文
- HTTP方法
- 细谈状态码
报文流
HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一些文本形式的元信息开头。这些元信息描述了报文的内容以及含义,后面还跟着可选的数据部分。报文在客户端、服务器以及代理之间流动。因此,由于流动方向不同,“流入”、“流出”、“上游”以及“下游”的名词应运而生。
HTTP报文会像河水一样流动,不管是请求报文还是响应报文。在流动的过程中,报文可能会经过一级一级的代理(后面会介绍代理相关的知识)。但是值得注意的是,报文流只能从上游流向下游而不能逆过来。同时上游和下游也不是绝对的,而是要看报文流动的方向。比如说请求报文由客户端流向服务器端,那么对于后面的代理来说,客户端方向就是上游,服务器端方向就是下游。但是对于从服务器端发出的响应报文来说,服务器端方向就是上游,客户端方向就是下游。
HTTP报文的语法及结构
在详细介绍HTTP报文的语法及结构之前,我想先给大家看看HTTP报文到底长什么样子,在传递信息的过程中起到了什么样的作用。
一边打开wireshark一边登录学校的教务在线抓HTTP的包
学号和cookie等个人隐私信息已进行打码处理,不影响对这部分知识的理解
打开编号为571的包可以发现,这个报文是客户端向服务器端请求用户编号为14080xxxx并且用户类型为学生的个人照片。
报文长度为622 并且使用了GET方法 请求报文主题内容客户端向服务器端发送请求报文,询问该学号对应学生个人照片资源的URI是多少
紧接着服务器做出了相应,将正确的图片资源信息返还给了服务器。请注意此时状态码为302.其实3**状态码都是重定向状态码,关于为什么这里是302我会在后面进行介绍。
服务器关于个人照片资源的URI返还的响应报文 302 Found 报文主体中的Location指明了我们所请求资源对应的URI后面就不详细介绍了,仅把有关图片的请求报文和响应报文贴出来
以GET方式请求学生个人照片 请求包主题内容 其中指明了图片的URI 200 OK 表明返回成功 响应报文主体内容其实报文还包含有最后修改时间(Last-Modified)、版本号(ETag)等其它重要信息,这里不做赘述。在介绍代理和缓存时将对这些知识进行讲解。
下面开始针对报文进行详细介绍
报文的组成部分
- 起始行(start line): 对报文进行描述
- 首部(header): 包含属性
- 主体(body): 可选、包含数据
起始行和首部其实就是由行分割的ASCⅡ文本。每行都以一个由两个字符组成的行终止序列作为结束,其中包括一个回车符(ACSⅡ码13)和一个换行符(ASCⅡ码10)。这个行终止序列可以写作CRLF。需要指出的是,尽管HTTP规范中说明应该用CRLF来表示行终止,但稳健的应用程序也应该接受单个换行符作为行的终止。有些老的或者是不完整的HTTP应用程序并不总是既发送回车符,又发送换行符。(存在CRLF注入攻击的风险)
报文的组成部分报文的语法
报文可以分为两大类-----请求报文和响应报文。
请求报文格式 响应报文格式报文的各个部分
- 方法(method): 客户端希望服务器端执行的动作,例如GET、DELETE等
- 请求URL(request-URL):所请求资源的所在位置
- 版本(version):报文所使用的HTTP版本,格式为 HTTP / <major>.<minor>,有主次版本号之分
- 状态码(status-code):描述请求过程中发生了什么,一般都是由三位数字组成,第一个数字通常表明返回的状态(成功、错误或者其他)
- 原因短语(reason-phrase):其实和数字状态码类似,但是可读性较高
- 首部(header):可以有零个或者多个首部,每个首部都包含一个名字。
- 实体的主体部分(entity-body):由任意数据组成的数据块,但不是所有的报文都包含实体的主体部分。
其实要展开来讲的话,这一部分会有非常多的内容。因为起始行根据报文类型的不同可以分为请求行(请求报文特有)和响应行(响应报文特有),并且首部也可以分为请求首部、响应首部、拓展首部或者是实体首部等等。这里就不一一介绍了,感兴趣的读者可以自行查阅资料进行了解。在这里提醒一下,由于版本(如HTTP / 0.9和HTTP / 1.0)的差别,HTTP报文格式以及语法可能会有差异,所以要特别注意!
下面着重讲讲HTTP方法和状态码
HTTP方法
HTTP方法用来告诉服务器应该进行何种操作。HTTP方法定义了一组被称为安全方法的方法。GET方法和HEAD方法都被认为是安全的,这意味着使用GET方法和HEAD方法的HTTP请求都不会产生什么动作。
GET
GET是最常用的方法,通常用于请求服务器发送某个资源。HTTP/1.1要求服务器实现该方法。
请求报文 客户端使用GET方法 响应报文HEAD
HEAD方法与GET方法比较类似,但服务器在回送响应的时候只返回首部,不会返回实体的主体部分。这样就允许客户端在暂未获取实际资源的时候对资源的首部进行检查。
- 在不获取资源的情况下了解资源的情况(例如判断资源类型)
- 通过查看响应报文中的状态码查看资源是否存在
- 通过查看首部,测试资源是否被修改过了
PUT
PUT与GET相反,它会向服务器写入文档。PUT的语义就是让服务器创建一个由请求的URL命名的新文档。如果那个URL对应的资源存在的话,那么就用新的覆盖它。由于PUT允许用户对服务器内容进行修改,所以Web服务器在执行PUT操作之前,通常都要求用户进行登录从而对操作权限进行判别。
POST
POST方法用以向服务器提交数据,通常用于表单数据提交。虽然POST和PUT看起来类似,但是还是有比较大的区别。感兴趣的读者可以看看stackoverflow关于这两种方法的讨论--http://stackoverflow.com/questions/630453/put-vs-post-in-rest
方法为POST的报文信息 向服务器提交账号密码等重要数据 对应的登录提交表单TRACE
TRACE方法可能没有那么常用,但是它的作用也非常大。众所周知,当客户端向服务器发送请求的时候,请求可能要穿过防火墙、代理、网关或者是其他一些应用程序。每一个中间节点都有可能会修改原有的HTTP请求。TRACE方法允许客户端在最后将请求发送给服务器时,看看它变成了什么样子。TRACE方法主要用于对请求/响应链进行诊断。
OPTIONS
此方法用于请求服务器告知其支持的各种功能,可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
DELETE
请服务器删除所请求URL对应的资源,如果有的话。
其他拓展的方法
HTTP被设计成字段可拓展的,拓展方法的意思就是有可能在HTTP规范中没有定义,但是可以由我们自己设计,并且服务器也支持的方法。
拓展方法示例
- LOCK:允许用户锁定服务器上的某个资源,例如在修改某资源的时候对该资源进行锁定防止其他用户在同一时间操作资源
- UNLOCK:解除对资源的锁定
- MKCOL:允许用户新建资源
- MOVE:将资源移到别处
- COPY:从服务器复制资源
状态码
HTTP状态码被分为了五大类,下面会对着五大类进行略微详细地介绍---不仅会介绍状态码,还会列出其对应的原因短语。尽管没有实际的规范对原因短语进行确切地说明,下面所列的都是HTTP/1.0规范所推荐的原因短语。
100~199 信息性状态码
- 100 Continue:说明服务器收到了请求的初始部分,请客户继续发送实体。服务器在收到请求之后必须进行响应。通常客户端需先发送一个 100 Continue Expect首部。但是如果客户不打算发送实体,那就不应该发送此首部
- 101 Switching Protocols : 说明服务器正根据客户端的指定,将协议切换成Update首部所列的协议
200~299 成功状态码
客户端向服务器进行请求时,通常都是成功的。服务器有一组用于表示成功的状态码,分别对应不同类型的请求。
- 200 OK:请求没有问题,实体的主体部分包含了所请求的资源
- 201 Created:用于对创建服务器资源对象请求的响应(如PUT)。响应的实体部分中应该会包含新建资源的URL,比如Location首部中包含的URL。所以服务器应该在回送此请求之前创建好资源
- 202 Accepted:服务器已经接受了客户端的请求,但是暂未对其执行任何动作。并且不能保证服务器一定会执行。如果会执行的话,可能还会包含预计执行时间等信息
- 203 Non-Authoritative Information:实体首部包含的信息不是来自源端服务器,而是来自资源的一份副本。但是如果资源来自源端服务器,那么响应为200状态的应用程序就可以作为其一种可选项使用
- 204 No Content:响应报文中包含若干首部和一个状态行,但是没有实体的部分。主要用于浏览器不转为显示新文档的情况下对其进行更新。例如刷新一个表单页面。
- 205 Reset Content:另一个主要用于浏览器的代码。负责告知浏览器清除当前页面中的所有HTML表单元素
- 206 Partial Content:成功执行了要给部分部分或者是Range(范围)请求。因为用户可以通过一些特殊的首部来获取部分或者是某个范围的文档-----这个状态码就说明范围请求成功了。
300~399 重定向状态码
重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已经被移走,可发送一个重定向状态码和一个可选的Location首部来告知客户端资源已经被移走,以及现在可以在哪里找到它。浏览器就可以在不影响用户浏览体验的情况下透明地在新的位置找到所需资源了。
- 300 Multiple Choices:客户端请求一个实际指向多个资源的URL时会返回这个状态码。例如服务器上有某个HTML网页有多种语言版本。返回这个代码时会携带一个选择列表,客户端需要沟通解决。
- 301 Move Permanently:所请求的资源已经被移走(永久性重定向)。响应的Location首部中应该包含资源目前所处的URL
- 302 Found:所请求的资源已经被移走,此次将访问由Location指定的新的URL,但是以后还是访问老的URL,即临时性重定向。
- 303 See Other:该状态码表示请求对应的资源存在另一个URL,应使用GET方法获取资源。
当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302标准是禁止将POST方法改编成GET方法,但实际使用时大家都会这么做。
- 304 Not Modified:该状态码表示客户端发送附带条件的请求(包含If-Match、If-Modified等首部)时,服务器端允许请求访问资源,但因发生请求为满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。304状态码返回时,不包含任何响应的主题部分。304虽然放在3XX类别中,但是和重定向没有一点关系。
- 307 Temporary Redirect:临时重定向。该状态码与302有着相同的含义。尽管302禁止由POST变换成GET,但实际使用时大家并不遵守。
307会遵照浏览器标准,不会从POST变成GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
400~499 客户端错误状态码
- 400 Bad Request:请求报文中存在语法错误
- 401 Unauthorized:用户需进行认证。当浏览器初次接收到401响应,会弹出认证用的对话窗口
- 403 Forbidden:表明对所请求资源的访问被服务器拒绝了。服务器没有必要给出拒绝的详细理由。如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。未获得文件访问授权、访问权限出现某些问题等情况都有可能是发生403的原因。
- 404 Not Found:服务器上无法找到所请求的资源,也有可能是服务器拒绝请求且不想说明理由时使用
500~599 服务器错误
- 500 Internal Sever Error:服务器遇到一个妨碍它为请求提供服务的错误时,使用此状态码
- 502 Bad Gateway:作为代理或者网关从请求响应链的下一条链路上收到了伪响应时(例如无法连接父网关),使用此状态码
- 503 Service Unavailable:用来说明服务器现在无法为请求提供服务,但是将来可以。如果服务器知道服务什么时候可用,可以在响应中包含一个Retry-After首部。
- 504 Gateway Timeout:在等待另一服务器对其请求进行响应时超时了
以上为针对HTTP相关的只是做的第一部分的介绍,其余知识我放在《HTTP权威指南》学习总结(下)进行介绍。
最后在文章的末尾安利一下我的个人公众号:
Eakon先生的小板报Eakon先生的小板报,一个不向邪恶势力低头的有趣公众号。欢迎关注噢~