图解HTTP读书笔记(一)
第一章 网络基础
网络基础TCP/IP
为了理解HTTP,事先了解下TCP/IP协议族。通常使用的网络实在TCP/IP协议族的基础上运作的。HTTP属于它内部的一个子集。
计算机与网络设备要相互通信,双方就必须基于相同的方法,如:如何探测到通信目标,由哪边先发起通信,使用哪种语言进行通信,如何结束通信等都需要事先确定。不同的硬件、操作系统之间的通信,所有的一切都需要一种规则,而我们就把这种规则称之为协议。
像这样与互联网相关的协议集合起来总称为TCP/IP协议。
TCP/IP的分层管理
TCP/IP协议族按层次分别分为以下4层:应用层、传输层、网络层、数据链路层。
o 应用层:决定了向用户提供应用服务时通信的活动。TCP/IP协议族内预存了各类通用的应用服务。如:HTTP,FTP(文件传输协议)和DNS(域名系统)。
o 传输层:传输层对上层应用层负责,提供处于网络连接中的两台计算机之间的数据传输。在传输层有2个性质不同的协议TCP和UDP。
o 网络层IP逻辑地址:网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方的计算机,比把数据包传送给对方。
o 数据链路层MAC地址在本网络内:用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NTC(网络适配器,即网卡),及光纤等物理可见部分。硬件上的范畴均在链路层的作用范围之内。
· TCP/IP通信传输流
利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通讯,发送端从应用层往下走,接收端则链路层往上走。
以HTTP协议为例:
发送端的客户端在应用层发生出一个HTTP请求。(TCP作用)在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。在网络层(IP协议),增加作为通信目的地的MAC地址后转发给链路层。
接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的HTTP请求。
发送段在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时,会把对应的首部信息去掉。
与HTTP有关协议:IP、TCP和DNS
· IP协议:
o IP协议的作用:是把各种数据包传送给对方。要保证确实传送到对方那里,需要满足各类条件。其中两个重要的条件是IP地址和MAC地址(网卡所属的固定地址)。
o ARP协议:是一种可以解析地址的协议,根据通信方的IP地址就可以反查出对应的MAC地址。
o 路由选择(routing):是指选择通过互连网络从源节点向目的节点传输信息的通道,而且信息至少通过一个中间节点。
TCP协议
TCP位于传输层,提供可靠的字节流服务。所谓的字节流服务,是指为了方便传输,将大块数据分割成以报文段为单位的数据包进行管理。为了准确无误的将数据送达目标处,TCP协议采用了三次握手策略。
· DNS协议:与HTTP协议一样位于应用层的协议。他提供域名到IP地址之间的解析服务或逆向从IP地址反查找域名服务。
各协议与HTTP的关系
如图:
关系:最上为http请求报文,最下为http响应报文,层层封装两个报文来传输!
URI和URL
· URI(Uniform Resource Identifier):统一资源标识符。
· URL(Uniform Resource Locator):统一资源定位符。
URI用字符串标识某一互联网资源,而URL表示资源的地点(互联网上所处的位置)。URL是URI的子集。
URI,是统一资源标识符,用来唯一的标识一个资源。而URL是统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。而URN,uniform resource name,统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。就是说,URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。
在Java的URI中,一个URI实例可以代表绝对的,也可以是相对的,只要它符合URI的语法规则。而URL类则不仅符合语义,还包含了定位该资源的信息,因此它不能是相对的,schema必须被指定。(实际实现的相对地址也是在绝对地址的基础上)
现在回答文章开头提出的问题,到底是imgUrl好呢,还是imgUri好?显然,如果说imgUri是肯定没问题的,因为即使它实际上是url,那它也是uri的一种。那么用imgUrl有没有问题呢?此时则要看它的可能取值,如果是绝对路径,能够定位的,那么用imgUrl是没问题的,而如果是相对路径,那还是不要用ImgUrl的好。总之,用imgUri是肯定没问题的,而用imgUrl则要视实际情况而定。
第二个,从HttpServletRequest的javadoc中可以看出,getRequestURI返回一个String,“the part of this request’s URL from the protocol name up to the query string in the first line of the HTTP request”,比如“POST /some/path.html?a=b HTTP/1.1”,则返回的值为”/some/path.html”。现在可以明白为什么是getRequestURI而不是getRequestURL了,因为此处返回的是相对的路径。而getRequestURL返回一个StringBuffer,“The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.”,完整的请求资源路径,不包括querystring。
注:这里的绝对(absolute)是指包含scheme,而相对(relative)则不包含scheme。
URI抽象结构 [scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
authority为[user-info@]host[:port]
总结:
从http报文开始层层传输,应用层可能有DNS查询,经过TCP分段报文连接序列,IP选择路由和查询mac地址,传输到另一端。
图解HTTP读书笔记(二)
第二章 简单的HTTP协议
HTTP请求与响应报文
HTTP协议规定,请求从客户端发出,最后服务端响应该请求并返回。所以是客户端开始建立通信的,服务端在没有接收到请求之前是不会响应的。
请求
HTTP请求信息称为请求报文。由请求行,请求头(请求首部字段),请求正文(内容实体)3部分组成。
请求报文:
请求行:包括请求方法,URI,HTTP协议版本组成。
如:GET http://blog.csdn.net/qq_33689414?viewmode=contents HTTP/1.1
下图将Host放入了首部
· 响应
响应报文:有响应行,响应头部,响应正文组成。
响应行:有协议版本,状态码,解释状态码的原因短语(不用加URI,只有请求才需要URI)。
HTTP是不保存状态的协议与Cookie
HTTP是一种不保存状态,即无状态协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说不做持久化处理。
为了实现期望的保持状态功能,于是引入了Cookie技术。
· Cookie技术
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。
Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会检查是从哪一个客户端发过来的请求,对比服务器上的记录,最后得到之前的状态信息。
(可以看到根据sid来判断是哪个用户端的cookie)
如图
报文信息
请求URI定位资源
请求URI定位资源的方式有多种:
- URI为完整的请求:
GET http://hacker.jp/index.htm HTTP/1.1
· 在首部字段Host中写明网络域名或IP地址
GET /index.htm HTTP/1.1
Host:hacker.jp(在首部)
· 以*来代替请求的URI
OPTIONS * HTTP/1.1
HTTP请求方法
GET:获取资源
GET方法用来请求访问已被URI识别的资源(服务器放在上边的内容,否则返回4xx资源不存在错误)。指定的资源经服务器端解析后返回相应的内容。
if-Modified-Since:用来请求内容状态,不用返回内容
POST方法用来传输实体的主体。
content-length
· HEAD:获得报文首部
HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期和时间等。
· PUT:传输文件
PUT方法用来传输文件。但是鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全问题,因此一般的web网站不使用该方法。
content-type
- DELETE:删除文件
DELETE方法用来删除文件,与PUT相反,DELETE方法按请求URI删除指定的资源。和PUT一样不带验证机制,存在安全问题。
OPTIONS:询问支持的方法
OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
· TRACE:追踪路径
TRACE方法是让web服务器端将之前的请求通信环回给客户端的方法。
发送请求时,在Max-Forwards首部字段中填入数值,每经过服务端就将该数值减1,当数值刚好减到0时,就停止继续传输,最后接受到请求的服务器端则返回状态码200的响应。
客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改/篡改的。
但是,TRACE方法本来就不怎么常用,加上它容易引发XST(跨站追踪)攻击。
看到content-type为message
内容为:客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改/篡改的。
· CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接字)和TLS(传输层安全)协议把通信内容加密后经过网络隧道传输。
CONNECT方法的格式如下:
CONNECT 代理服务器名 : 端口号 HTTP版本
SSL TLS
持久连接与管线化
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。当初传输的文件比较小,所以没什么问题。现在使用浏览器浏览包含一个多张图片的HTML页面时,在发送请求访问HTML页面的同时,也会请求该HTML页面里包含的其他资源。因此,每次请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。(tcp每次都会发送SYN报文和FIN报文,发送完后服务端确定收到就发送一个FIN给服务器端,具体见补充)
· 持久连接
为了解决上述TCP连接的问题,HTTP/1.1和一部分HTTP/1.0想出了持久连接(HTTP Persistent Connection,也称为HTTP keep-alive)的方法。
持久连接的特点是:只要任意一端没有明确提出断开连接,则保持TCP连接状态。
持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器的负载。
在HTTP/1.1中,所有连接默认都是持久连接。
· 管线化
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现以后,不用等待响应可直接发送下一个请求。
这样就能够做到同时并行发送多个请求,而不需要一个接一个的等待响应了。
总结:
请求响应报文的格式
cookie
请求URI的方式
不同的get put方法是http报文内部的协议即根据不同请求返回不同内容(GET方法用来请求访问已被URI识别的资源(服务器放在上边的内容,否则返回4xx资源不存在错误))(CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接字)和TLS(传输层安全)协议把通信内容加密后经过网络隧道传输。
)
持久化连接和管线化
补充:
下面是具体步骤。
1)HTTP客户初始化一个与服务器主机www.phei.com中的HTTP服务器的TCP连接。HTTP服务器使用默认端口号80监听来自HTTP客户的连接建立请求。(TCP报文中有上层协议标号,指明其协议是HTTP,FTP,SMTP等等)
2)HTTP客户经由与TCP连接相关联的本地套接字发出个HTTP请求消息(报文)。这个消息中包含路径名/somepath/index.html。
3)HTTP服务器经由与TCP连接相关联的本地套接字IP+端口接收这个请求消息,再从服务器主机的内存或硬盘中取出对象/somepath/index.html,经由同一个套接字发出包含该对象的响应消息。
4)HTTP服务器告知TCP关闭这个TCP连接(不过TCP要到客户收到刚才这个响应消息之后才会真正终止这个连接)---服务器发送FIN,客户端发送FIN+ACK。
5)HTTP客户经由同一个套接字接收这个响应消息。TCP连接随后终止。该消息标明所封装的对象是一个HTML文件。客户从中取出这个文件,加以分析后发现其中有10个JPEG对象的引用。
6)给每一个引用到的JPEG对象重复步骡1~4。
浏览器在接收Web页面的同时把它显示给用户。不同的浏览器可能会以略有不同的方式解释(也就是向用户显示)同一个Web页面。HTTP与客户如何解释Web页面没有任何关系,其规范[RFC 1945]和[RFC 2616I]仅仅定义HTTP客户程序和服务器程序之间的通信协议。
在上述步骡中,我们有意不说清楚客户是通过10个串行的TCP连接先后取得所有JPEG对象,还是通过并行的TCP连接同时取得其中某些JPEG对象的。实际上,现今的浏览器允许用户通过配置来控制并行连接的程度。大多数浏览器默认可以打开5到10个并行的TCP连接(管线化),每个连接处理一个请求--响应事务。用户要是喜欢,可以把最大并行连接数设为l,那样的话,这10个连接是串行建立的。
2.持久连接
非持久连接有些缺点。首先,客户得为每个待请求的对象建立并维护一个新的连接。对于每个这样的连接,TCP得在客户端和服务器端分配TCP缓冲区,并维持TCP变量。对于有可能同时为来自数百个不同客户的请求提供服务的Web服务器来说,这会严重增加其负担。其次,每个对象都有2个RTT的响应延长(最大连接时长)--一个RTT用于建立TCP连接,另-个RTT用于请求和接收对象。最后,每个对象都遭受TCP慢启动,因为每个TCP连接都起始于慢启动阶段。不过并行TCP连接的使用能够部分减轻RTT延迟和慢启动延迟的影响。
(HTTP为何是2个RTT?
用户的点击导致浏览器发起建立一个与Web服务器的TCP连接,这里涉及·-次"三次握手"过程--首先是客户向服务器发送一个小的冗余消息,接着是服务器向客户确认并响应以一个小的TCP消息,最后是客户向服务器回确认。三次握手过程的前两次结束时,流逝的时间为1个RTT。此时客户把HTTP请求消息发送到TCP连接中,客户接着把三次握手过程最后一次中的确认捎带在包含这个消息的数据分节中发送出去。服务器收到来自TCP连接的请求消息后,把相应的HTML文件发送到TCP连接中,服务器接着把对早先收到的客户请求的确认捎带在包含该HTML文件的数据分节中发送出去。这个HTTP请求顺应交互也花去1个RTT时间。因此,总的响应时间粗略地算是2个RTT加上服务器发送这个HTMI文件的时间。)
在持久连接情况下,服务器在发出响应后让TCP连接继续打开着。同一对客户/服务器之间的后续请求和响应可以通过这个连接发送。整个Web页面(上例中为包含一个基本HTMLL文件和10个图像的页面)自不用说可以通过单个持久TCP连接发送:甚至存放在同一个服务器中的多个Web页面也可以通过单个持久TCP连接发送。通常,HTTP服务器在某个连接闲置一段特定时间后关闭它,而这段时间通常是可以配置的。持久连接分为不带流水线(without pipelining)和带流水线(with pipelining)两个版本。如果是不带流水线的版本,那么客户只在收到前一个请求的响应后才发出新的请求。这种情况下,Web页面所引用的每个对象(上例中的10个图像)都经历1个RTT的延迟,用于请求和接收该对象。与非持久连接2个RTT的延迟相比,不带流水线的持久连接已有所改善,不过带流水线的持久连接还能进一步降低响应延迟。不带流水线版本的另一个缺点是,服务器送出一个对象后开始等待下一个请求,而这个新请求却不能马上到达。这段时间服务器资源便闲置了。
HTTP/1.1的默认模式使用带流水线的持久连接。这种情况下,HTTP客户每碰到一个引用就立即发出一个请求,因而HTTP客户可以一个接一个紧挨着发出各个引用对象的请求。服务器收到这些请求后,也可以一个接一个紧挨着发出各个对象。如果所有的请求和响应都是紧挨着发送的,那么所有引用到的对象一共只经历1个RTT的延迟(而不是像不带流水线的版本那样,每个引用到的对象都各有1个RTT的延迟)。另外,带流水线的持久连接中服务器空等请求的时间比较少。与非持久连接相比,持久连接(不论是否带流水线)除降低了1个RTT的响应延迟外,慢启动延迟也比较小。其原因在于既然各个对象使用同一个TCP连接,服务器发出第一个对象后就不必再以一开始的缓慢速率发送后续对象。相反,服务器可以按照第一个对象发送完毕时的速率开始发送下一个对象。