我正在开发一个简单的下载应用程序。在请求以下文件时,firefox和我的应用程序都没有获取content-length字段。但是如果我使用wget服务器发出请求会发送内容长度字段。我确实更改了wgets用户代理字符串以进行测试,它仍然有内容长度字段。
为什么会发生这种情况?
wget request
---request begin---
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 HTTP/1.0
User-Agent: test
Accept: */*
Host: media.defcon.org
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.0 200 OK
Server: lighttpd
Date: Sun, 05 Apr 2009 04:40:08 GMT
Last-Modified: Tue, 23 May 2006 22:18:19 GMT
Content-Type: video/mp4
Content-Length: 104223909
Connection: keep-alive
firefox请求
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 HTTP/1.1
Host: media.defcon.org
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.0.8) Gecko/2009032608 Firefox/3.0.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.defcon.org/html/links/defcon-media-archives.html
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Server: lighttpd
Date: Sun, 05 Apr 2009 05:20:12 GMT
Last-Modified: Tue, 23 May 2006 22:18:19 GMT
Content-Type: video/mp4
Transfer-Encoding: chunked
更新
我是否可以发送一个标题,告诉Lighthttpd不要使用分块编码。我原来的问题是我使用urlConnection
来抓取我自己发送HTTP 1.1请求的java应用程序中的文件。
我想知道文件的大小,以便我可以更新我的百分比。
答案 0 :(得分:13)
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 的 HTTP / 1.1 强>
Firefox正在执行HTTP 1.1 GET请求。 Lighthttpd理解客户端将支持分块传输编码并以块的形式返回内容,每个块报告自己的长度。
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 的 HTTP / 1.0 强>
另一方面,Wget执行HTTP 1.0 GET请求。 Lighthttpd,了解客户端不支持HTTP 1.1(以及因此分块传输编码),在一个块中返回内容,并在响应头中报告长度。
答案 1 :(得分:4)
看起来是因为chunked
transfer encoding:
Transfer-Encoding: chunked
这将以视频形式发送视频,每个视频都有自己的大小。这是在HTTP 1.1中定义的,这是Firefox正在使用的,而wget
正在使用HTTP 1.0,它不支持分块传输编码,因此服务器必须立即发送整个文件。
答案 2 :(得分:1)
我遇到了同样的问题,无论哪个HTTP版本都找到了解决方案:
HEAD
请求,该请求仅使用HTTP标头正确响应而没有内容。此标头正确包含要下载的文件所需的Content-Length:
字节大小。GET
下载文件的请求(GET响应中的标题无法包含Content-length)。Objective-C语言示例:
NSString *zipURL = @"http://1.bp.blogspot.com/_6-cw84gcURw/TRNb3PDWneI/AAAAAAAAAYM/YFCZP1foTiM/s1600/paragliding1.jpg";
NSURL *url = [NSURL URLWithString:zipURL];
// Configure the HTTP request for HEAD header fetch
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
urlRequest.HTTPMethod = @"HEAD"; // Default is "GET"
// Define response class
__autoreleasing NSHTTPURLResponse *response;
// Send HEAD request to server
NSData *contentsData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
// Header response field
NSDictionary *headerDeserialized = response.allHeaderFields;
// The contents length
int contents_length = [(NSString*)headerDeserialized[@"Content-Length"] intValue];
//printf("HEAD Response header: %s\n",headerDeserialized.description.UTF8String);
printf("HEAD:\ncontentsData.length: %d\n",contentsData.length);
printf("contents_length = %d\n\n",contents_length);
urlRequest.HTTPMethod = @"GET";
// Send "GET" to download file
contentsData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
// Header response field
headerDeserialized = response.allHeaderFields;
// The contents length
contents_length = [(NSString*)headerDeserialized[@"Content-Length"] intValue];
printf("GET Response header: %s\n",headerDeserialized.description.UTF8String);
printf("GET:\ncontentsData.length: %d\n",contentsData.length);
printf("contents_length = %d\n",contents_length);
return;
输出:
HEAD:
contentsData.length: 0
contents_length = 146216
GET:
contentsData.length: 146216
contents_length = 146216
(注意:此示例网址正确地提供了来自GET响应的标题Content-Length,但显示了它是否失败的想法)