Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IIS7 refuses chunked-encoded file upload

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"
like image 572
Serge Wautier Avatar asked Oct 09 '22 10:10

Serge Wautier


1 Answers

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

like image 198
Andre Sikma Avatar answered Oct 14 '22 07:10

Andre Sikma