ADC

流式重写操作中的内容长度标头行为

内容长度标头是指示 HTTP 请求或响应中消息长度(以字节为单位)的方法之一。除了 Content-Length 标头,您还可以使用以下方法之一指定消息的长度:

  • 分块编码
  • FIN 终止

在流式传输过程中,NetScaler 在处理重写操作后持续发送数据。由于数据是连续发送的,不由 NetScaler 保存,因此发送给客户端的消息的实际长度未知。因此,在响应中无法提及内容长度标头的正确值。

为了支持流式传输过程,NetScaler 的重写功能会将消息长度从内容长度标头转换为 FIN 终端。作为转换的一部分,NetScaler 通过重新排列标题名称的前四个字符来损坏 Content-Length 标头。

在 HTTP 中,客户端应该忽略它不理解的标头。因此,客户端无法理解损坏的 Content-Length 标头名称,因此会忽略标头。为了提高 NetScaler 的性能,标头已损坏,而不是被删除。损坏标头名称而不是删除可以避免重新计算校验和,因为如果相同的字节顺序不同,校验和不会改变。

例如,考虑以下 HTTP 请求:

GET / HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, /
Accept-Language: en-GB
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; CMDTDF; MS-RTC LM 8)
Accept-Encoding: gzip, deflate
Host: test.example.net
Connection: Keep-Alive
<!--NeedCopy-->

在工作场景中,NetScaler 与后端服务器之间对此 HTTP 请求的响应如下所示:

HTTP/1.1 200 OK
Content-Length: 10967
Connection: close
var SERVER_URL = 'https\x3a\x2f\x2ftest.example.net\x2f';
var WEB_SERVER_HOST = 'test.example.net';
<!--NeedCopy-->

但是客户端在非工作场景中从NetScaler收到的响应如下。Content-Length 标题被重命名为 ntcoent-Length

HTTP/1.1 200 OK
ntCoent-Length: 10967
nnCoection: close
var SERVER_URL = 'https\x3a\x2f\x2ftest.example.net\x2f';
var WEB_SERVER_HOST = 'test.example.net';
<!--NeedCopy-->

通常,客户端应用程序支持所有三种交易方式——内容长度标头、分块编码和 FIN 终止。因此,从内容长度标头转换为 FIN 终止不得导致任何问题。但是,如果应用程序由于此修改而无法运行,则必须 禁用流媒体进程

如何在重写策略中禁用流媒体进程

您可以使用以下方法之一在重写策略中禁用流媒体进程:

  1. 添加与绑定到更高优先级的重写策略相关的非流式操作。该操作必须以不修改响应的方式进行。

    例如:

    add rewrite action non_stream_act replace_all HTTP.RES.BODY(1000000) HTTP.RES.FULL_HEADER -search text("pattern_which_will_not_match_in_body")

    此重写操作中正文的值必须大于当前流式传输操作所依据的值。

  2. 使用非流式传输配置代替流式传送配置。

    注意:

    从流处理迁移到非流处理可能会影响 NetScaler 的性能。

    例如,流媒体配置可以转换为非流媒体配置,如下所示:

    直播配置:

    add rewrite action rw_act_1 replace_all HTTP.RES.BODY(1000) ""http"" -search text("http")
    
    add policy patset pat_list
    bind policy patset pat_list abcd
    bind policy patset pat_list defg
    
    add rewrite action rw_act_2 replace_all HTTP.RES.BODY(1000) ""replaced_data"" -search patset("pat_list")
    <!--NeedCopy-->
    

    非流媒体配置:

    add rewrite action rw_act_1 replace_all HTTP.RES.BODY(1000) ""http"" -search regex(re/http/)
    
    add rewrite action rw_act_1 replace_all HTTP.RES.BODY(1000) ""http"" -search regex(re/abcd|defg/)
    <!--NeedCopy-->
    
流式重写操作中的内容长度标头行为