始终以text/html标记的Django响应无法设置Content-Length [英] Django Response always Chunked with text/html cannot set Content-Length

查看:264
本文介绍了始终以text/html标记的Django响应无法设置Content-Length的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Django应用程序的views.py中,尝试设置以下HTTP Header字段后,我返回了HttpResponse对象:

In my Django Application's views.py , I return an HttpResponse object after attempting to set the following HTTP Header fields:

# Create a Response Object with the content to return 
response = HttpResponse("%s"%(output_display),mimetype='text/html')
response['Cache-Control'] = 'must-revalidate, max-age=20'
response['Vary'] = 'Accept-Encoding'
response['Transfer-Encoding'] = 'gzip'
#response['Content-Encoding'] = 'gzip'
response['Connection'] = 'close'
#response['Content-Type'] = 'text/html'
response['Content-Length'] = '%s'%(len(output_display))
return response

然后我使用带有FireFox的Live HTTP Headers插件捕获输出,它看起来像:

I then capture the output using the Live HTTP Headers plugin with FireFox, and it looks like:

HTTP/1.1 200 OK
Date: Sun, 10 Mar 2013 14:55:09 GMT
Server: Apache/2.2.22 (Ubuntu)
Transfer-Encoding: gzip, chunked   <---------- Why 'chunked'?
Vary: Accept-Encoding
Connection: close
Cache-Control: must-revalidate, max-age=20
Content-Encoding: gzip
Content-Type: text/html <---------------------- No Content-Length even though I set it?
X-Pad: avoid browser bug

我正在尝试使用Apache2的mem_cache进行缓存,因此我需要设置Content-Length,并且不能为传输编码"设置块状".

I am trying to cache using Apache2's mem_cache, so I need the Content-Length to be set and cannot have 'chunked' for Transfer-Encoding.

我的Apache2 mem_cache.conf看起来像(大量用于测试):

My Apache2 mem_cache.conf looks like ( large numbers just for testing ):

<IfModule mod_mem_cache.c>
        CacheEnable mem /
        MCacheSize 10000
        MCacheMaxObjectCount 10000000
        MCacheMinObjectSize 1
        MCacheMaxObjectSize 10000000
        MCacheMaxStreamingBuffer 10000000
</IfModule>

但是,即使我在响应代码中明确设置了Content-Length和Transfer-Encoding,也会自动插入"chunked",因此我的Content-Length不被接受.为什么是这样?如何解决此问题以获得所需的响应?谢谢-

But even though I explicitly set the Content-Length and Transfer-Encoding in my response code, 'chunked' is inserted automatically and therefore my Content-Length is not honored. Why is this? How can I fix this to get the desired response? Thanks -

推荐答案

我最近在mod_wsgi应用程序中遇到了类似的问题;我试图更新使用其内置磁盘缓存的apache配置,改为使用socache/memcache.

I came across a similar issue recently with a mod_wsgi application; I was trying to update an apache configuration that was using its built-in disk cache, to use socache/memcache instead.

磁盘高速缓存正在运行,但是切换到memcache或shmcb无效.如果发出对要缓存的资源的请求,它将不会将其存储在缓存中(CacheDetailHeader对此很有帮助).在调试时检查日志,发现消息:

The disk cache was working, but switching to memcache or shmcb didn't work. If I issued a request for a resource I wanted cached, it wouldn't store it in the cache (CacheDetailHeader is helpful for this). Checking the logs at debug, I found the message:

[Wed Dec 05 18:52:16.571002 2018] [cache_socache:debug] \
[pid 884:tid 140422596777728] mod_cache_socache.c(389): \
[client 127.0.0.1:56576] AH02346: URL 'http://127.0.1.1:80/cacheme/c?' \
had no explicit size, ignoring, referer: http://127.0.0.1/

似乎socache不喜欢没有显式大小的对象.我尝试将这些mod_memcache设置的较新的socache等效项设置为足够大的值:CacheSocacheMaxSizeCacheSocacheReadSize.

It seems that socache doesn't like objects that don't have explicit sizes. I tried setting the newer, socache equivalents of those mod_memcache settings to sufficiently large values: CacheSocacheMaxSize and CacheSocacheReadSize.

我知道正在设置Content-Length标头并将其传递到某个地方;当我故意对它进行计算时,它会出现在mod_wsgi日志中.

I know that the Content-Length header was being set and made it through to somewhere; it showed up in the mod_wsgi logs when I deliberately miscalculated it.

我发现的几件事:

  1. 请勿自行设置Transfer-Encoding标头,因为WSGI规范禁止这样做:

  1. Don't set Transfer-Encoding header yourself, as this is forbidden by the WSGI specification:

谁设置了Transfer-Encoding:分块标题?

  • 即使您自己设置Content-Length标头,它也被Apache压缩.这会改变长度;当Apache不知道长度是多少时,它将切换为分块并删除Content-Length标头.

  • Even though you're setting the Content-Length header yourself, it's also being gzipped by apache. This changes the length; when Apache doesn't know what the length will be, it switches to chunked and removes the Content-Length header.

    我发现有:

    • Content-Type: text/html

    Content-Length设置为我的utf-8编码大小

    Content-Length set to my utf-8 encoding size

    在python/mod_wsgi应用程序中设置,然后:

    set in the python/mod_wsgi application, and:

    • SetEnv no-gzip 1

    在apache配置中设置,该对象将其放入shmcb缓存中.

    set in the apache configuration, that the object made it into a shmcb cache.

    当apache gzip压缩对象时,它会将标头更改为socache不接受的标头.

    It looks like when apache gzips an object, it changes the headers to that it isn't accepted by socache.

    我到处寻找使它们兼容的方法,但是在这个问题上找不到太多.在mod_cache文档中有提及重新排序缓存/放气过滤器的内容:

    I looked around for ways to make them compatible, but couldn't find too much on this issue. There is some mention of reordering the cache/deflate filters in the mod_cache documentation:

    https://httpd.apache.org/docs/2.4/mod/mod_cache.html#finecontrol

    如果我输入指令以重新排序缓存/放气过滤器,则此方法有效:

    This worked if I put in a directive to reorder the cache/deflate filters:

    # within a directory
    SetOutputFilter CACHE;DEFLATE
    

    奇怪的是,在发生高速缓存未命中时,服务器返回了压缩的内容,但是在高速缓存命中时,服务器返回了未编码的text/html.这看起来很奇怪,但是我对FilterChain指令的理解还不够好,无法尝试这些指令.

    Curiously, on a cache miss, the server returned gzipped content, but on a cache hit, the server returned unencoded text/html. This looks odd, but I haven't understood the FilterChain directives well enough to try those out.

    在与php/content-length相关的问题中,我也发现了一些提及:

    I also found some mention of this in a related issue with php/content-length:

    https://serverfault.com/questions/183843/在Apache中启用gzip-compression-enabled时未发送content-length-length

    那里的答案发现,如果他们将DeflateBufferSize设置为足够大的值,则将设置content-length.

    The answer there found that if they set the DeflateBufferSize to a large-enough value, then content-length would be set.

    我无法使它正常工作.

    因此,似乎在选择缓存还是gzip压缩之间陷入了困境.

    So it looks like one is stuck between choosing cached or gzipped.

    这篇关于始终以text/html标记的Django响应无法设置Content-Length的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆