自己实现Http服务器:一、Http协议解析
2015-01-05 10:47
267 查看
之前总结过一篇TCP/IP协议的文章,而Http就是建立在TCP的基础之上的。TCP、UDP属于传输层协议,而Http是属于应用层的协议。
Http是超文本传输协议的缩写。协议详细内容参考RFC2616。由于面向文本的,所以使用ASCII编码。
2. 简单快速
3. 灵活:允许传输任意类型数据,通过Content-Type标记
4. Http1.0使用短连接方式,Http1.1支持长连接方式
5. 无状态:对事务处理没有记忆能力
Http报文可以分为请求报文和响应报文两种。下面先给出各报文的例子方便后面的理解
Get请求消息例子:
==========
GET /doaction?p=123&k=3343 HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: name=jackey;
===========
Post请求消息例子:
===========
POST /post HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Content-Length: 11
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:12345/doaction?p=123&k=3343
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
name=jackey
===========
响应消息例子:
===========
HTTP/1.1 200 OK
Connection:keep-alive
Content-Type: text/html;charset=UTF-8
Content-Length:51
Date:2014-12-31 16:02:17
Server:HttpServer
Set-Cookie: name=jackey; Expires=Tue, 03-Feb-2015 08:29:31 GMT; Path=/; Secure
<html><head>title</head><body>content</body></html>
===========
Http采用请求响应模型,浏览器向服务器发送请求,服务器响应消息返回给浏览器。所以http消息分为两种:请求消息和响应消息。(注意消息中的换行都是CRLF,不允许出现单独的CR或LF字符)
这两种消息的结构差不多:
1.一个起始行
2.一个或多个头域
3.一个头域结束标志的空行(CRLF)
4.可选的消息体
请求消息结构:
1.请求行
2.请求头
3.头域结束标志的空行
4.请求正文
响应消息结构:
1. 状态行
2. 响应头
3. 头域结束标志的空行
4. 响应正文
【请求方法】【空格】【请求URI】【空格】【协议版本】
URI通常只要给出服务器根目录的相对目录即可,所以总是以“/”开头。
响应起始行格式:
【协议版本】【空格】【状态码】【空格】【服务器信息】
支持以下这几种方法:
GET、HEAD、POST、OPTIONS、PUT、Delete、TRACE、CONNECT
其中最常用的是GET、POST和HEAD,一般自己做用于应用的http服务器的时候只需要考虑支持这三种方法即可适用于大多数场景。
HEAD方法和GET方法几乎一样,它们的头部是相同的,服务端可以对HEAD方法只返回响应的头部。这一般是爬虫程序会用到这个方法,来测试超链接的有效性,以及最近更新情况。
响应状态码
1XX:信息类,表示接收到请求并且继续处理
2XX:成功类,表示被成功接收、理解和接受
3XX:重定向,为了完成指定动作,必须接受进一步处理
4XX:客户端错误。请求的语法错误或不能正确执行
5XX:服务端错误。服务器不能正确指定一个正确的请求
常用状态吗
200 OK //请求成功
302 Found //请求的资源被临时替代,新的URL在Location头域中
304 Not Modified //告诉客户端该被缓存的文档未修改,可以直接使用缓存
400 Bad Request //请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误,不能完成请求
502 Bad Gateway //服务器作为网关或代理访问下一个服务器失败
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
【域名】【冒号:】【域值】
域值前可以加任意空格不影响域值。
头域可以被扩展为多行,需要在每行开始处使用至少一个空格或制表符。
规范中并没有对头域长度和数量进行限制,但出于性能和安全考虑,多数http服务器会进行一定的限制,如Apache2.3限制头部不能超过8190字节,头域数量不能超过100个。
请求头域:
Accept:客户端(浏览器)可以接收的内容类型
Accept-Charset:浏览器可以处理的字符集,如utf-8
Accept-Encoding:浏览器可以处理的编码方式,如gzip,deflate
Accept-Language:浏览器可接收的语言,zh-CN
Authorization:认证保护的信息的base64编码
Cache-Control:缓存机制。
public:所有内容都将被缓存
private:内容只缓存到私有缓存
no-cache:所有内容都不会被缓存
no-store:所有内容都不会被缓存到缓存或Internet临时文件中
must-revalidate/proxy-revalidate:如果缓存失败,请求必须重新验证
max-age:缓存的内容将在XXX秒后失效,如果和Last-Modified一起使用优先级较高
Connection:告诉服务器使用的连接方式:keep-alive和close。http1.1和http1.0的长连接和短连接。
Cookie:格式:name=value;name=value
Content-Length:请求体的长度(单位字节),头域的结束标志空行之后开始算。
Content-MD5:base64编码的请求体的MD5校验和。
Content-Type:请求体内容的MIME类型,如application/x-www-form-urlencoded
Date:发送请求的GMT时间
From:发送请求的用户的email地址
Host:服务器的域名或IP地址,以及端口。
Referer:指当前请求的URL是在什么地址引用的。通常我们见到的图片防盗链就是用这个实现的
User-Agent:用户浏览器信息
Range:表示请求资源的从某个数值到某个数值间的数据。如Range: bytes=500-999 就是表示请求资源从500到999byte的数据。数据的分段下载和多线程下载就是利用这个实现的
Upgrade:请求服务器更新至另外一个协议
If-Match:通常在PUT方法的请求中,通过资源的tag与If-Match的tag匹配判断,是否更新
If-Modified-Since:询问服务器现在正在请求的资源在某个时间以来有没有被修改过,如果没有,服务器则返回304状态来告诉浏览器使用浏览器自己本地的缓存,如果有修改过,则返回200,并发送新的资源(当然如果资源不存在,则返回404。)
If-None-Match:和If-Modified-Since用意差不多,不过不是根据时间来确定,而是根据一个叫ETag的东西来确定
If-Range:告诉服务器如果这个资源没有更改过,就发送这个资源中在浏览器缺少了的某些部分给浏览器,如果该资源以及被修改过,则将整个资源重新发送一份给浏览器
If-Unmodified-Since:询问服务器现在正在请求的资源在某个时刻以来是否没有被修改过
Max-Forwards:限制请求信息在代理服务器或网关中向前传递的次数
Pragma:用来包含实现特定的指令,如Pragma:no-cache,同Cache-Control:no-cache
Proxy-Authorization:连接到某个代理时使用的身份认证信息,跟Authorization头差不多
Via:用来记录一个请求经过了哪些代理或网关才被送到目标服务器上
Warning:记录一些警告信息
通用但非标准的HTTP头(通常,非标准的头域都是用“X-”开头,例如"x-powered-by"):
X-Requested-With:主要用来识别ajax请求,如XMLHttpRequest
DNT:DO NOT TRACK的缩写,要求服务器程序不要跟踪记录用户信息。1开启,0关闭
X-Forwarded-For:记录一个请求从客户端出发到目标服务器过程中经历的代理,或者负载平衡设备的IP
X-Forwarded-Proto:记录一个请求最初从浏览器发出时候,是使用什么协议,如https,http
Front-End-Https:微软使用与其负载平衡的一个头域
X-ATT-DeviceId:
响应头域:
Access-Control-Allow-Origin:表示该站点可以被哪些网站进行跨域资源共享(cross-origin resource sharing,CORS),如Access-Control-Allow-Origin:http://foo.example.com,Access-Control-Allow-Origin:*
Accept-Ranges:表明服务器支不支持资源范围请求,bytes表示支持,none则不支持
Age:一个资源存在于代理中缓存的时间。单位是秒
Allow:允许哪些HTTP方法进行请求,例如:Allow: GET, HEAD
Cache-Control:见上文
Connection:连接方式,keep-alive和close
Content-Encoding:服务器对响应数据的编码方式,如gzip
da42
Content-Language:响应数据的自然语言,如zh-CN
Content-Length:响应体数据的长度
Content-MD5:base64编码的响应体的MD5检验和
Content-Disposition:当客户端请求资源是一个可下载的资源时,对这个资源的描述。如文件名等,浏览器下载框的文件名就是从这获取的。
Content-Range:表示如果当前这个响应数据是整个资源的一部分时,是具体的哪一部分。例如:Content-Range:500-900
Content-Type:响应数据的MIME类型,例如:Content-Type: text/html; charset=utf-8
Date:响应消息发送的GMT格式日期
ETag:(Entity-Tag的缩写)资源的一个标识,类似于key-value pair(键值对)中的key。ETag通常用于校验一个资源实体有没有被修改过
Expires:告诉客户端该响应数据会在指定的时间过期,通常用于给客户端缓存作为参考
Last-Modified:客户端所请求的资源的最后修改时间
Link:描述当前被请求的资源和另外一个资源的关系
Location:用户通知客户端转跳(重定向)到另一个URL
P3P:表示本站点遵守P3P协议(标称本站点不会违法使用用户信息)并希望收集用户信息
Proxy-Authenticate:访问代理时需要使用的验证方式。例如:Proxy-Authenticate: Basic
Refresh:用于令客户端在指定N秒后转跳到另外一个URL。例如:Refresh:6,http://www.google.com.hk 6秒后转跳到google
Retry-After:用于因为某些原因(例如该资源暂时无效)通知客户端在指定时间后重新尝试请求,时间单位为秒。例如:Retry-After:60 一分钟后重新尝试请求该资源
Server:服务器的名称
Set-Cookie:对客户端设置cookie。例如:Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Strict-Transport-Security:用于指示客户端如何对HTTPS进行缓存(缓存多长时间)以及是否对子域生效
Trailer:当响应资源已chunked编码传输时,每个Chunked-Body尾部的额外数据
Transfer-Encoding:响应内容的传输编码方式,通常有 chunked, deflate, gzip等
Vary:用来指示缓存代理(例如squid)根据什么条件去缓存一个请求
Via:告诉客户端,该回应经历了那些代理
WWW-Authenticate:表示当前是用什么验证方式访问一个资源
通用的非标准HTTP头域:
X-XSS-Protection:IE8+中开启或关闭跨站脚本攻击
X-Content-Type-Options:只有一个值:nosniff,正是用于关闭自动嗅探功能
X-Powered-By:表面当前站点(或资源)是用什么技术开发
当然,http服务器在实现的时候,也会有个超时时间,超过这个时间这个连接一直没有交互(读或写),也会关闭这个连接。
Http1.1在Http1.0基础上,在头部还增加了一些头域。如Host字段,可以根据这个知道客户端通过什么域名访问的,用这个可以在同一个IP端口下配置多个WEB站点,根据域名来分发到相应的server进程。还有上面提到的Connection字段等等。
1. 通过头部中的Content-Length来获取正文的长度,这样就知道什么时候这个请求结束。这也是最常用的方式。
2. 没有Content-Length时,可以通过chunk编码,来一块一块的发送正文。在请求头部中添加Transfer-Encoding: chunked。每个chunk块由头部和正文两部分组成,头部中由一个16进制数字指定了正文的长度,最后一个长度为0的chunk块表示整个http正文结束。
Http是超文本传输协议的缩写。协议详细内容参考RFC2616。由于面向文本的,所以使用ASCII编码。
Http特点
1. 客户/服务器模式,支持基本认证和安全认证(Https)2. 简单快速
3. 灵活:允许传输任意类型数据,通过Content-Type标记
4. Http1.0使用短连接方式,Http1.1支持长连接方式
5. 无状态:对事务处理没有记忆能力
Http报文可以分为请求报文和响应报文两种。下面先给出各报文的例子方便后面的理解
Get请求消息例子:
==========
GET /doaction?p=123&k=3343 HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: name=jackey;
===========
Post请求消息例子:
===========
POST /post HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Content-Length: 11
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:12345/doaction?p=123&k=3343
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
name=jackey
===========
响应消息例子:
===========
HTTP/1.1 200 OK
Connection:keep-alive
Content-Type: text/html;charset=UTF-8
Content-Length:51
Date:2014-12-31 16:02:17
Server:HttpServer
Set-Cookie: name=jackey; Expires=Tue, 03-Feb-2015 08:29:31 GMT; Path=/; Secure
<html><head>title</head><body>content</body></html>
===========
Http采用请求响应模型,浏览器向服务器发送请求,服务器响应消息返回给浏览器。所以http消息分为两种:请求消息和响应消息。(注意消息中的换行都是CRLF,不允许出现单独的CR或LF字符)
这两种消息的结构差不多:
1.一个起始行
2.一个或多个头域
3.一个头域结束标志的空行(CRLF)
4.可选的消息体
请求消息结构:
1.请求行
2.请求头
3.头域结束标志的空行
4.请求正文
响应消息结构:
1. 状态行
2. 响应头
3. 头域结束标志的空行
4. 响应正文
起始行
请求起始行格式:【请求方法】【空格】【请求URI】【空格】【协议版本】
URI通常只要给出服务器根目录的相对目录即可,所以总是以“/”开头。
响应起始行格式:
【协议版本】【空格】【状态码】【空格】【服务器信息】
支持以下这几种方法:
GET、HEAD、POST、OPTIONS、PUT、Delete、TRACE、CONNECT
其中最常用的是GET、POST和HEAD,一般自己做用于应用的http服务器的时候只需要考虑支持这三种方法即可适用于大多数场景。
HEAD方法和GET方法几乎一样,它们的头部是相同的,服务端可以对HEAD方法只返回响应的头部。这一般是爬虫程序会用到这个方法,来测试超链接的有效性,以及最近更新情况。
响应状态码
1XX:信息类,表示接收到请求并且继续处理
2XX:成功类,表示被成功接收、理解和接受
3XX:重定向,为了完成指定动作,必须接受进一步处理
4XX:客户端错误。请求的语法错误或不能正确执行
5XX:服务端错误。服务器不能正确指定一个正确的请求
常用状态吗
200 OK //请求成功
302 Found //请求的资源被临时替代,新的URL在Location头域中
304 Not Modified //告诉客户端该被缓存的文档未修改,可以直接使用缓存
400 Bad Request //请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误,不能完成请求
502 Bad Gateway //服务器作为网关或代理访问下一个服务器失败
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
头域
头域格式:【域名】【冒号:】【域值】
域值前可以加任意空格不影响域值。
头域可以被扩展为多行,需要在每行开始处使用至少一个空格或制表符。
规范中并没有对头域长度和数量进行限制,但出于性能和安全考虑,多数http服务器会进行一定的限制,如Apache2.3限制头部不能超过8190字节,头域数量不能超过100个。
请求头域:
Accept:客户端(浏览器)可以接收的内容类型
Accept-Charset:浏览器可以处理的字符集,如utf-8
Accept-Encoding:浏览器可以处理的编码方式,如gzip,deflate
Accept-Language:浏览器可接收的语言,zh-CN
Authorization:认证保护的信息的base64编码
Cache-Control:缓存机制。
public:所有内容都将被缓存
private:内容只缓存到私有缓存
no-cache:所有内容都不会被缓存
no-store:所有内容都不会被缓存到缓存或Internet临时文件中
must-revalidate/proxy-revalidate:如果缓存失败,请求必须重新验证
max-age:缓存的内容将在XXX秒后失效,如果和Last-Modified一起使用优先级较高
Connection:告诉服务器使用的连接方式:keep-alive和close。http1.1和http1.0的长连接和短连接。
Cookie:格式:name=value;name=value
Content-Length:请求体的长度(单位字节),头域的结束标志空行之后开始算。
Content-MD5:base64编码的请求体的MD5校验和。
Content-Type:请求体内容的MIME类型,如application/x-www-form-urlencoded
Date:发送请求的GMT时间
From:发送请求的用户的email地址
Host:服务器的域名或IP地址,以及端口。
Referer:指当前请求的URL是在什么地址引用的。通常我们见到的图片防盗链就是用这个实现的
User-Agent:用户浏览器信息
Range:表示请求资源的从某个数值到某个数值间的数据。如Range: bytes=500-999 就是表示请求资源从500到999byte的数据。数据的分段下载和多线程下载就是利用这个实现的
Upgrade:请求服务器更新至另外一个协议
If-Match:通常在PUT方法的请求中,通过资源的tag与If-Match的tag匹配判断,是否更新
If-Modified-Since:询问服务器现在正在请求的资源在某个时间以来有没有被修改过,如果没有,服务器则返回304状态来告诉浏览器使用浏览器自己本地的缓存,如果有修改过,则返回200,并发送新的资源(当然如果资源不存在,则返回404。)
If-None-Match:和If-Modified-Since用意差不多,不过不是根据时间来确定,而是根据一个叫ETag的东西来确定
If-Range:告诉服务器如果这个资源没有更改过,就发送这个资源中在浏览器缺少了的某些部分给浏览器,如果该资源以及被修改过,则将整个资源重新发送一份给浏览器
If-Unmodified-Since:询问服务器现在正在请求的资源在某个时刻以来是否没有被修改过
Max-Forwards:限制请求信息在代理服务器或网关中向前传递的次数
Pragma:用来包含实现特定的指令,如Pragma:no-cache,同Cache-Control:no-cache
Proxy-Authorization:连接到某个代理时使用的身份认证信息,跟Authorization头差不多
Via:用来记录一个请求经过了哪些代理或网关才被送到目标服务器上
Warning:记录一些警告信息
通用但非标准的HTTP头(通常,非标准的头域都是用“X-”开头,例如"x-powered-by"):
X-Requested-With:主要用来识别ajax请求,如XMLHttpRequest
DNT:DO NOT TRACK的缩写,要求服务器程序不要跟踪记录用户信息。1开启,0关闭
X-Forwarded-For:记录一个请求从客户端出发到目标服务器过程中经历的代理,或者负载平衡设备的IP
X-Forwarded-Proto:记录一个请求最初从浏览器发出时候,是使用什么协议,如https,http
Front-End-Https:微软使用与其负载平衡的一个头域
X-ATT-DeviceId:
响应头域:
Access-Control-Allow-Origin:表示该站点可以被哪些网站进行跨域资源共享(cross-origin resource sharing,CORS),如Access-Control-Allow-Origin:http://foo.example.com,Access-Control-Allow-Origin:*
Accept-Ranges:表明服务器支不支持资源范围请求,bytes表示支持,none则不支持
Age:一个资源存在于代理中缓存的时间。单位是秒
Allow:允许哪些HTTP方法进行请求,例如:Allow: GET, HEAD
Cache-Control:见上文
Connection:连接方式,keep-alive和close
Content-Encoding:服务器对响应数据的编码方式,如gzip
da42
Content-Language:响应数据的自然语言,如zh-CN
Content-Length:响应体数据的长度
Content-MD5:base64编码的响应体的MD5检验和
Content-Disposition:当客户端请求资源是一个可下载的资源时,对这个资源的描述。如文件名等,浏览器下载框的文件名就是从这获取的。
Content-Range:表示如果当前这个响应数据是整个资源的一部分时,是具体的哪一部分。例如:Content-Range:500-900
Content-Type:响应数据的MIME类型,例如:Content-Type: text/html; charset=utf-8
Date:响应消息发送的GMT格式日期
ETag:(Entity-Tag的缩写)资源的一个标识,类似于key-value pair(键值对)中的key。ETag通常用于校验一个资源实体有没有被修改过
Expires:告诉客户端该响应数据会在指定的时间过期,通常用于给客户端缓存作为参考
Last-Modified:客户端所请求的资源的最后修改时间
Link:描述当前被请求的资源和另外一个资源的关系
Location:用户通知客户端转跳(重定向)到另一个URL
P3P:表示本站点遵守P3P协议(标称本站点不会违法使用用户信息)并希望收集用户信息
Proxy-Authenticate:访问代理时需要使用的验证方式。例如:Proxy-Authenticate: Basic
Refresh:用于令客户端在指定N秒后转跳到另外一个URL。例如:Refresh:6,http://www.google.com.hk 6秒后转跳到google
Retry-After:用于因为某些原因(例如该资源暂时无效)通知客户端在指定时间后重新尝试请求,时间单位为秒。例如:Retry-After:60 一分钟后重新尝试请求该资源
Server:服务器的名称
Set-Cookie:对客户端设置cookie。例如:Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Strict-Transport-Security:用于指示客户端如何对HTTPS进行缓存(缓存多长时间)以及是否对子域生效
Trailer:当响应资源已chunked编码传输时,每个Chunked-Body尾部的额外数据
Transfer-Encoding:响应内容的传输编码方式,通常有 chunked, deflate, gzip等
Vary:用来指示缓存代理(例如squid)根据什么条件去缓存一个请求
Via:告诉客户端,该回应经历了那些代理
WWW-Authenticate:表示当前是用什么验证方式访问一个资源
通用的非标准HTTP头域:
X-XSS-Protection:IE8+中开启或关闭跨站脚本攻击
X-Content-Type-Options:只有一个值:nosniff,正是用于关闭自动嗅探功能
X-Powered-By:表面当前站点(或资源)是用什么技术开发
Http1.1和Http1.0的区别
Http1.1使用的是长链接,根据头部中的Connection值来判断是否继续保持TCP链接,当值是keep-alive时服务器保持连接,值是close时响应内容后就可以关闭连接了。而Http1.0则没有这种长链接的概念,每次请求响应后建立的链接就断开,这样浪费了很多网络资源用于重新建立连接。当然,http服务器在实现的时候,也会有个超时时间,超过这个时间这个连接一直没有交互(读或写),也会关闭这个连接。
Http1.1在Http1.0基础上,在头部还增加了一些头域。如Host字段,可以根据这个知道客户端通过什么域名访问的,用这个可以在同一个IP端口下配置多个WEB站点,根据域名来分发到相应的server进程。还有上面提到的Connection字段等等。
Http1.1判断正文结束
由于http1.1.使用的是长连接的方式,所以浏览器需要知道响应的正文在什么位置该结束。有两种方式:1. 通过头部中的Content-Length来获取正文的长度,这样就知道什么时候这个请求结束。这也是最常用的方式。
2. 没有Content-Length时,可以通过chunk编码,来一块一块的发送正文。在请求头部中添加Transfer-Encoding: chunked。每个chunk块由头部和正文两部分组成,头部中由一个16进制数字指定了正文的长度,最后一个长度为0的chunk块表示整个http正文结束。
相关文章推荐
- 通过解析HTTP协议自己实现文件上传
- 实现php 二级域名无限解析 自己实践+看别人文章
- 自己实现的一个公式表达式解析
- mvc5 解析route源码实现自己的route系统
- 自己实现一个SQL解析引擎
- [BOT]自己动手实现android 饼状图,PieGraphView,附源码解析
- 实现自己的O/R Mapping组件[一]-概念解析
- Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)
- Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)
- 利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
- 自己实现MVVM(Vue源码解析)
- 用TCP/IP实现自己简单的应用程序协议:最后再返回来看HTTP协议
- 用TCP/IP实现自己简单的应用程序协议:最后再返回来看HTTP协议
- Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager) Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager) Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的Trans
- Asp.net mvc5 解析route源码实现自己的route系统
- live555 env->taskScheduler().doEventLoop()解析/自己实现
- 用TCP/IP实现自己简单的应用程序协议:最后再返回来看HTTP协议
- Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)
- 自己动手实现http协议(看透spring mvc笔记)
- Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的