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"
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
5
hello
with
5
h ello
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With