首页 > 代码库 > HTTP协议之chunk编码(分块传输编码)

HTTP协议之chunk编码(分块传输编码)

分块传输编码Chunked transfer encoding)是超文本传输协议(HTTP)中的一种传输数据机制,同意HTTP由应用server发送给client应用( 一般是网页浏览器)的数据能够分成多个部分。分块传输编码仅仅在HTTP协议1.1版本号(HTTP/1.1)中提供。

通常,HTTP应答消息中发送的数据是整个发送的。Content-Length消息头字段表示数据的长度。数据的长度非常重要,由于client须要知道哪里是应答消息的结束,以及兴许应答消息的開始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样server能够发送数据而不须要预先知道发送内容的总大小。

通常数据块的大小是一致的。但也不总是这样的情况。

 

HTTP 1.1引入分块传输编码提供了下面几点优点:

  1. HTTP分块传输编码同意server为动态生成的内容维持HTTP持久连接。通常,持久链接须要server在開始发送消息体前发送Content-Length消息头字段,可是对于动态生成的内容来说。在内容创建完之前是不可知的。[动态内容,content-length无法预知]
  2. 分块传输编码同意server在最后发送消息头字段。

    对于那些头字段值在内容被生成之前无法知道的情形非常重要。比如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。

    没有分块传输编码时,server必须缓冲内容直到完毕后计算头字段的值并在发送内容前发送这些头字段的值。[散列签名,需缓冲完毕才干计算]

  3. HTTPserver有时使用压缩 (gzip或deflate)以缩短传输花费的时间。分块传输编码能够用来分隔压缩对象的多个部分。在这样的情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描写叙述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完毕压缩过程以得知压缩后数据的大小。[gzip压缩。压缩与传输同一时候进行]

   普通情况HTTP的Header包括Content-Length域来指明报文体的长度。有时候服务生成HTTP回应是无法确定消息大小的,比方大文件的下载,或者后台须要复杂的逻辑才干所有处理页面的请求,这时用须要实时生成消息长度。server一般使用chunked编码。



   在进行Chunked编码传输时。在回复消息的Headers有transfer-coding域值为chunked,表示将用chunked编码传输内容。

使用chunked编码的Headers例如以下(能够利用FireFox的FireBug插件或HttpWatch查看Headers信息):

   採用下面方式编码:   
    Chunked-Body=*chunk   
           "0"CRLF   
           footer   
           CRLF   
    chunk=chunk-size[chunk-ext]CRLF   
        chunk-dataCRLF   
    
    hex-no-zero=<HEXexcluding"0">   
    
    chunk-size=hex-no-zero*HEX   
    chunk-ext=*(";"chunk-ext-name["="chunk-ext-value])   
    chunk-ext-name=token   
    chunk-ext-val=token|quoted-string   
    chunk-data=http://www.mamicode.com/chunk-size(OCTET)
    

    footer=*entity-header 

    编码使用若干个Chunk组成。由一个标明长度为0的chunk结束,每一个Chunk有两部分组成,第一部分是该Chunk的长度和长度单位(一般不 写),第二部分就是指定长度的内容。每一个部分用CRLF隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容。是一些没有写的头部内 容。   
    下面给出一个Chunked的解码过程(RFC文档中有)   
    length:=0   
    readchunk-size,chunk-ext(ifany)andCRLF   
    while(chunk-size>0){   
    readchunk-dataandCRLF   
    appendchunk-datatoentity-body   
    length:=length+chunk-size   
    readchunk-sizeandCRLF   
    }   
    readentity-header   
    while(entity-headernotempty){   
    appendentity-headertoexistingheaderfields   
    readentity-header   
    }   
    Content-Length:=length   
    Remove"chunked"fromTransfer-Encoding

HTTP协议之chunk编码(分块传输编码)