我目前正在尝试优化多个应用程序之间基于http的数据传输.我们当前的方法,先下载然后创建后请求,显然会增加额外的IO /内存负载和延迟,这是我想要规避的.
所有的核心问题:
是否需要在HTTP POST请求中发送"Content-Length"标头?IIRC,HTTP 2616声明它是可选的,但我不确定应用程序在这一点上的实际行为.
我读过对"如何计算多部分HTTP请求内容长度?"这一问题的冲突和有些含糊不清的回复.我特别想知道:
有人能提供一个明确的例子来回答这些问题吗?
使用Varnish 4,我有一组后端,它们响应有效的Content-Length
标头而没有Transfer-Encoding
标头.
在客户端的第一次点击中,Varnish正在删除Content-Length
标题并添加Transfer-Encoding: chunked
到响应中,而不是使用这些标头响应客户端.(有趣的是,有效载荷似乎没有任何块 - 它是一个连续的有效载荷).
这会给像Flash视频播放器这样的客户端造成严重问题,这些客户端正试图根据Content-Length
标头进行分段大小,带宽等分析.他们的分析失败了,他们不能做多比特流等等.
我尝试过一些半明显的事情,比如:
beresp.do_stream = true
beresp.do_gzip = false
unset req.http.Accept-Encoding
示例后端响应:
HTTP/1.1 200 OK
Cache-Control: public, max-age=600
Content-Type: video/mp4
Date: Tue, 13 May 2014 19:44:35 GMT
Server: Apache
Content-Length: 796618
Connection: keep-alive
Run Code Online (Sandbox Code Playgroud)
样品清漆响应:
HTTP/1.1 200 OK
Server: Apache
Cache-Control: public, max-age=600
Content-Type: video/mp4
Date: Tue, 13 May 2014 23:10:06 GMT
X-Varnish: 2
Age: 0
Transfer-Encoding: chunked
Accept-Ranges: bytes
Run Code Online (Sandbox Code Playgroud)
对象的后续加载不包括Content-Length …
我的应用程序如何利用etags,并引入流/分块编码引入任何复杂性?
在进行HTTP流式传输时Transfer-Encoding: chunked
,Content-Length
无法发送,因为它通常是未知的.
据我所知,当浏览器利用etags时,他们需要知道Content-Length
.如果提供了etag但不提供Content-Length
,则浏览器将永远不会发送If-None-Match
.
有没有解决的办法?
我正在加载一个由PHP动态生成的特别大的JSON字符串.为了向用户提供一些反馈,我想显示下载进度.
我已经找到了代码,它适用于静态内容,如图像,JS文件等.但是,它似乎不适用于动态文件.
这是有道理的,因为动态文件没有可预测的内容长度,但即使我在PHP中添加它:
ob_start(function($c) {
header("Content-Length: ".strlen($c));
return $c;
});
Run Code Online (Sandbox Code Playgroud)
它仍然不发送标题(但如果我添加任何其他标题,它工作正常).
有没有办法强制Apache发送Content-Length
标题?目前我唯一的选择是将输出保存到临时文件并改为重定向到它.这可行,但它有点混乱,所以我宁愿避免它,如果可能的话.
我知道在 HTTP 1.0 中,响应的内容通过关闭连接终止。
在 HTTP 1.1 中,引入了保持活动连接,在单个 TCP 连接中启用多个请求和响应。
当通过同一个连接发送多条消息时,需要有一种机制来定义一条消息在哪里结束,下一条消息从哪里开始。
通过测试,我发现当我在响应中设置content-length 标头时这是有效的。通过知道内容长度,客户端知道什么时候完全接收到内容并且可以解析下一个响应。
我的问题是:
是否可以在不设置内容长度标头的情况下在保持活动连接中发送多个响应?
如果是,如何?
澄清一下:我正在考虑开始将响应发送到客户端时不知道响应长度的情况,我想知道关闭连接是否是实现它的唯一方法。
我在Android中有一个http客户端将HTTP PUT请求发送到使用C#和ASP.NET WebApi框架实现的REST API.
只要JSON字段与C#类中的属性匹配,框架就应该能够将JSON神奇地转换(反序列化)到模型类(普通对象)中.
问题是当该HTTP请求来与块传输编码,使内容长度= 0(根据http://en.wikipedia.org/wiki/Chunked_transfer_encoding)和框架是不是能够映射内是这样的JSON Http请求消息,因此参数为null.
看这个简单的例子:
[HttpPut]
public HttpStatusCode SendData(int id, int count, [FromBody]MyData records, HttpRequestMessage requestMessage)
{
var content = requestMessage.Content;
string jsonContent = content.ReadAsStringAsync().Result; //this gets proper JSON
return HttpStatusCode.OK;
}
Run Code Online (Sandbox Code Playgroud)
问题是当客户端发送嵌入的http请求时,记录为空.
据我所知,Chunked Transfer编码只是一个传输属性,http客户端或服务器不应该担心应用层(传输层的业务).但似乎框架并没有按照我的意愿来管理它.
我可以从HttpRequestMessage手动检索JSON并将其反序列化为MyData对象,但我无法利用ASP.NET框架的魔力.而且您知道规则:您添加的代码越多,您可能会引入的错误就越多.
有没有办法处理带有JSON的Http Put请求,这些请求来自ASP.NET Web Api 2中的分块传输?
编辑:这是此示例的模型类,框架应在反序列化JSON时实例化
public class MyData
{
public string NamePerson {get; set;}
public int Age {get; set;}
public string Color {get; set;}
}
Run Code Online (Sandbox Code Playgroud) c# json http-content-length chunked-encoding asp.net-web-api
我有一段Java代码将字节数组传输到HTTP服务器:
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ myBoundary);
connection.setRequestProperty("Content-Length", 1024);
Run Code Online (Sandbox Code Playgroud)
我使用此代码传输大小大于1024的字节数组.它运行良好.但实际的HTTP消息(由Wireshark捕获)显示Content-Length的值是实际大小而不是1024.为什么?
我在HTTP规范中搜索但没有发现任何提示.我没有使用任何Transfer-Encoding或Transfer-coding.
发送HTTP响应时,是否应该使用换行符(行分隔符)结束响应正文(内容本身)?
如果是这样的话,我应该在Content-Length中包含行分隔符的大小(我想在发送\ r \n时增加2的计数)?
我正在尝试使用此代码下载.zip文件
<?php
$file = "something.zip";
$size = filesize($file);
header('Content-type: application/octet-stream');
header("Content-length: $size");
header('Content-Disposition: attachment; filename="downloaded.zip"');
readfile($file);
?>
Run Code Online (Sandbox Code Playgroud)
但它似乎不起作用,即使我尝试将文件大小设置为类似的数字header("Content-length: 567247784");
.我只得到一个没有声明大小的文件,或者只有28个字节的小文件大小.
我看了这个问题,我认为我和海报有同样的问题,但他的解决方案是"存在服务器问题".我想我也有服务器配置问题,但他的回答根本没有帮助我.