IIS7 拒绝分块编码文件上传
我有一个 Windows/Apache2/PHP 应用程序,它使用分块编码接收文件。原因是上传的文件是动态的,传输前未知其长度。这一直开箱即用,效果很好。
现在我需要将应用程序移植到 IIS7/PHP。 问题是 IIS 无法接收分块文件:上传文件时,服务器根本没有响应。我该如何解决这个问题?
请注意,在我的测试中,我什至没有使用 PHP。我只是有一个 .php 扩展名,因为 IIS 拒绝对 .htm 文件进行 POST(这是有道理的)。
正如 rupello 在此答案中所建议的,我使用 cURL 进行了测试,以确保我的客户端没有损坏。 cURL 也无法得到答案,尽管如果传输没有分块,一切都可以正常工作。
我做了以下测试:
test.php:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
</head>
<body>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="upfile" />
<input type="submit" value="go"/>
</form>
</body>
</html>
此命令不返回(卡在等待答案)
curl.exe http://serveur/test.php --form "[email protected]"
-H "Transfer-Encoding: chunked" -H "Expect:"
注意:-H“Expect:”
是抑制Expect 100-Continue
代码> 由curl 发布。没有这个标头,结果是相同的,当然除了额外的往返。 已发送:
POST http://serveur/test.php HTTP/1.1
User-Agent: curl/7.15.3 (i586-pc-mingw32msvc) libcurl/7.15.3 zlib/1.2.2
Host: serveur
Pragma: no-cache
Accept: */*
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=----------------------------310dbcc6761b
8c
------------------------------310dbcc6761b
Content-Disposition: form-data; name="upfile"; filename="text.txt"
Content-Type: text/plain
5
hello
30
------------------------------310dbcc6761b--
0
问题:服务器没有返回任何内容。服务器看起来一直在等待。卷曲不返回。
没有块编码的相同命令按预期工作:
已发送:
POST http://serveur/test.php HTTP/1.1
User-Agent: curl/7.15.3 (i586-pc-mingw32msvc) libcurl/7.15.3 zlib/1.2.2
Host: serveur
Pragma: no-cache
Accept: */*
Connection: Keep-Alive
Content-Length: 193
Content-Type: multipart/form-data; boundary=----------------------------e2d761bc173a
------------------------------e2d761bc173a
Content-Disposition: form-data; name="upfile"; filename="text.txt"
Content-Type: text/plain
hello
------------------------------e2d761bc173a--
服务器现在正确回复:
HTTP/1.1 200 OK
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: PHP/5.3.8
X-Powered-By: ASP.NET
Date: Mon, 21 Nov 2011 10:47:57 GMT
Content-Length: 272
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
</head>
<body>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="upfile" />
<input type="submit" value="go"/>
</form>
</body>
</html>
在具有相同文件和请求的普通 LAMP 服务器上进行的测试工作正常。
那么如何在 IIS 上启用请求块编码呢?
注:我确实尝试了相关的ASP参数,但无济于事:
C:\...\inetsrv>appcmd.exe set config /section:asp /enableChunkedEncoding:True
Applied configuration changes to section "system.webServer/asp" for "MACHINE/
WEBROOT/APPHOST" at configuration commit path "MACHINE/WEBROOT/APPHOST"
I have a Windows/Apache2/PHP app that receives file using chunked encoding. The reason is that the file uploaded is dynamic and its length is not known before transfer. This has always worked fine out of the box.
Now I need to port the app to IIS7/PHP.
The problem is that IIS fails to receive the chunked file: When file is uploaded, the server just does not respond at all. How do I solve this?
Note that in my test, I don't even use PHP. I simply have a .php extension because IIS refuses a POST on .htm file (which makes sense).
As suggested by rupello in this answer, I made the test with cURL to make sure my client is not broken. cURL fails to get an answer as well, although it all works fine if transfer is not chunked.
I made the following tests:
test.php:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
</head>
<body>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="upfile" />
<input type="submit" value="go"/>
</form>
</body>
</html>
This command does not return (stuck waiting for an answer)
curl.exe http://serveur/test.php --form "[email protected]"
-H "Transfer-Encoding: chunked" -H "Expect:"
Note: -H "Expect:"
is to suppress the Expect 100-Continue
issued by curl. The result is the same without this header, execpt of course an additional roundtrip.
Sent:
POST http://serveur/test.php HTTP/1.1
User-Agent: curl/7.15.3 (i586-pc-mingw32msvc) libcurl/7.15.3 zlib/1.2.2
Host: serveur
Pragma: no-cache
Accept: */*
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=----------------------------310dbcc6761b
8c
------------------------------310dbcc6761b
Content-Disposition: form-data; name="upfile"; filename="text.txt"
Content-Type: text/plain
5
hello
30
------------------------------310dbcc6761b--
0
Problem: Nothing returned by server. Server looks like it keeps waiting. curl does not return.
The same command without the chunk encoding works as expected:
Sent:
POST http://serveur/test.php HTTP/1.1
User-Agent: curl/7.15.3 (i586-pc-mingw32msvc) libcurl/7.15.3 zlib/1.2.2
Host: serveur
Pragma: no-cache
Accept: */*
Connection: Keep-Alive
Content-Length: 193
Content-Type: multipart/form-data; boundary=----------------------------e2d761bc173a
------------------------------e2d761bc173a
Content-Disposition: form-data; name="upfile"; filename="text.txt"
Content-Type: text/plain
hello
------------------------------e2d761bc173a--
Server now replies correctly:
HTTP/1.1 200 OK
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: PHP/5.3.8
X-Powered-By: ASP.NET
Date: Mon, 21 Nov 2011 10:47:57 GMT
Content-Length: 272
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
</head>
<body>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="upfile" />
<input type="submit" value="go"/>
</form>
</body>
</html>
The test on plain-vanilla LAMP server with the same files and requests work fine.
So how do I enable request chunk-encoding on IIS?
Note: I did try the related ASP parameter, to no avail:
C:\...\inetsrv>appcmd.exe set config /section:asp /enableChunkedEncoding:True
Applied configuration changes to section "system.webServer/asp" for "MACHINE/
WEBROOT/APPHOST" at configuration commit path "MACHINE/WEBROOT/APPHOST"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
IIS 7(至少 IIS 7.5)确实支持分块文件上传。
当块长度错误时,IIS 返回 Http 错误 400:请求中的内容长度或块长度无效。 (例如,添加时替换
为
问题在于将 CGI 调用从 IIS 转移到 PHP。IIS 似乎并不是 PHP 作为(快速)CGI 无法处理分块文件上传的唯一环境。
请参阅 PHP 错误 ID 60826
IIS 7 (at least IIS 7.5) does support chuncked file uploads.
When the chunk length is wrong IIS returns an Http error 400: There is an invalid content length or chunk length in the request. (for example replace when adding
with
The problem lies in the transfer of the CGI call from IIS to PHP. IIS does not seem to be the only environment for which PHP as (Fast)CGI cannot deal with chunked file-uploads.
See PHP-Bugs ID 60826
根据 HTTP 1.1 规范,分块编码定义为 < strong>服务器编码 - 即服务器以这种编码发送响应,而不是相反(Wiki 页面也说了同样的话)。没有提到服务器接受分块编码请求,因此它没有在 IIS 中实现。
话虽如此,APACHE 似乎已经在 HTTP 规范之外实现了这一点。
According to HTTP 1.1 spec, chunked encoding is defined as server encoding - i.e. server sending response in such encoding, not the other way around (Wiki page also says the same). There is no mention of Server accepting a chunked encoded request, hence it is not implemented in IIS.
Having said that, it seems that APACHE has implemented this while being outside HTTP spec.