php file handling on IIS/Fast-cgi different to apacheRSS

15 replies

Last post Oct 17, 2013 04:41 AM by Peter Roman

  • php file handling on IIS/Fast-cgi different to apache

    Apr 11, 2009 01:07 AM|centralusa|LINK

    Hi,

    I have tried sevral thinsg and cannot work out why my simple file download script processes differently on iis then on apache/linux. The scenario is the following

    header('HTTP/1.1 200 OK');
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header('Date: ' . date("D M j G:i:s T Y"));
                header("Content-Type: $ctype");
                header('Content-Disposition: attachment; filename='.basename($fileSaveName));
                header('Content-Transfer-Encoding: Binary');
                header('Content-Length: '.filesize($filepath));
                ob_clean();
                flush();
                //header('Content-Disposition: attachment; filename=$fileName');
                set_time_limit(0);
                readfile($filepath);

     

    basically the script send a file for download to the browser, after thsi script I have a simple write to a db to note file has been downloaded. On Apache the script following this code above is not executed until the file download has been completed which is great as it allows me to easily store the download start date (before the above code) and download complete date (after the code above). On IIS 7 (64-bit / Fast-cgi) the entire page is processed almost immediately thus my script after the above code is executed immediately and my download complete date is no longer valid.

     

    Any help/advice on making IIS handle the processing of php files as apache does would be greatly appreciated!

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 12, 2009 08:27 PM|centralusa|LINK

     overwhelmed with all the responses I decided to run several tests stressing the fast-cgi/iis7/php combo.

    I found the following when pushing a file to the browser for download by using simple method above I found that iis7/fast-cgi/php5 crapped out (hung) pretty much at around 14MB of any file larger then that. Huh?? that less then acceptable add to that the dilemna I already laid out above.

     I optimized about everything I could think of in my code still without any luck. FWIW this same pathetic result was also achieved on IIS6 with fast-cgi and IIS6 with isapi. My conclusion was then that this was a serious inadequacy with IIS and its handling of streams.

    To test my theory I installed apache 2.2 on my windows server 2008 machine and added support to it for php5 and mysql. What do you know it performs exactly and as reliably as its linux counterpart, hmmm this really casts a serious shadow over running anything serious on IIS when using php. I will say this is probably more then inherit support for php then iis itself but still it has a long way to go obviously to be considered when you are running a native php site

     

     

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 13, 2009 02:12 PM|ksingla|LINK

    Hi.

    I will try to repro this issue in our lab. Can you give me the php code you used to send file data back to client? Also can you paste your FastCgi extension/module configuration? You can use the following appcmd command (run from a command window running as administrator).

    "%windir%\system32\inetsrv\appcmd list config /section:fastcgi /text:*"

    Thanks,
    Kanwal

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 14, 2009 01:28 PM|centralusa|LINK

    Sure

    Microsoft Windows [Version 6.0.6001]
    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

    C:\Users\Administrator>%windir%\system32\inetsrv\appcmd list config /section:fas
    tcgi /text:*
    CONFIG
      CONFIG.SECTION:"system.webServer/fastCgi"
      path:"MACHINE/WEBROOT/APPHOST"
      overrideMode:"Inherit"
      locked:"false"
      [system.webServer/fastCgi]
        [application]
          fullPath:"C:\php\php-cgi.exe"
          arguments:""
          maxInstances:"4"
          idleTimeout:"300"
          activityTimeout:"30"
          requestTimeout:"90"
          instanceMaxRequests:"200"
          protocol:"NamedPipe"
          queueLength:"1000"
          flushNamedPipe:"false"
          rapidFailsPerMinute:"10"
          [environmentVariables]

    C:\Users\Administrator>

     

    PHP Code I am using is pretty much as above. I will post exact code below: What happens before this is the file path is pulled from a database query and populates the $filepath var. Essentially it is a basic php script to read into memory a file from a directory outside the webroot and then push it to the browser for download. The key items here that work fine when running the scirpt in apache with exact same version of php5 and when running the same script in iis7/fast-cgi/php on the same Windows Server 2008 machine is

    1. The stream just dies or timeout after a certain period (usually around 14MB into a download of a large file)

    2. The entire page processes immediately in IIS meaning the code after the download portion of the script (shown below) executes immediately as the page is called. When run from Apache the code after the download script correctly does not process until the download has been completely pushed to the users browser. Essentially using IIS does not provide any way of knowing the download has been completed or not.

     

    Additionally as mentioned I have tested this extensively on Win Server 2003 using fast cgi and win 2003 server using isapi php and all same results so it is more then likely IIS just nto handling streams as reliably as apache. Please note we use IIS extensively for our dedicated servers so I am not making this post to tout apache over IIS we just got too many complaints from customers downloading files from our very powerful multi-core blade servers that we had to start trying something else (sadly it was as simple as installing apache 2.2 on the server now the email complaints have slowed to almost nothing).

     

    /*

    CODE TO PULL FILE PATH FROM DATABASE

    CODE TO LOG THAT THE DOWNLOAD HAS COMMENCED

    */

    if (file_exists($filepath)) {
               
                set_time_limit(0);
                $file_extension = strtolower(substr(strrchr($filename,"."),1));
                $ctype="application/octet-stream";
               
                switch ($file_extension) {
                    case "mp3": $ctype="audio/mp3"; break;
                    case "zip": $ctype="application/zip"; break;
                    default: $ctype="application/octet-stream";
                }
               
                header('HTTP/1.1 200 OK');
                header("Pragma: public");
                header("Expires: 0");
                header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                //header("Cache-Control: private",false);
                header('Date: ' . date("D M j G:i:s T Y"));
                header('Last-Modified: ' . date("D M j G:i:s T Y"));
                header("Content-Type: $ctype");
                header('Content-Disposition: attachment; filename='.basename($fileSaveName));
                header('Content-Transfer-Encoding: Binary');
                header('Content-Length: '.filesize($filepath));
                ob_clean();
                flush();
                //header('Content-Disposition: attachment; filename=$fileName');
               
                readfile($filepath);
                $downloadComplete = 1;
               
            }

     

    /*

    POST FILE DOWNLOAD CODE TO LOG DOWNLOAD HAS BEEN COMPLETED SUCCESSFULLY

    */

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 14, 2009 01:58 PM|ksingla|LINK

    Hi,

    I will try it out today and see what is going on.

    Thanks,
    Kanwal

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 15, 2009 09:19 PM|ksingla|LINK

    Hi,

    I couldn't repro this behavior. Is it possible for you to enable FREB tracing and paste the trace? Steps to enable tracing are available here.

    Thanks,
    Kanwal

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 16, 2009 08:58 AM|centralusa|LINK

     So you are saying that when you run this request the template does not process immediately? meaning you can log the real time start of a file download and real time end? this I know is impossible using IIS and php.What I mean specifically by this is (as described above) use my php script first log to a db or txt file the start date of the file download and then send the file to the users browser usign my script, once the download complete log again the download complete date. When doing this using iis/php your start and complete dates will be exactly the same (to the second) or maybe within 1 second of each due to the current server time/load. Obviously if the file is 10MB or more and you are not on a LAN to the server its not realistic it will take 0 secs to download the file. My point is make sure to test this from a client outside your LAN that is connected via a real world pipe (say in the 2 - 6 MB/s download speed)

    I would certainly see it as possible you cannot get the server to timeout sending the download as you may be using a server on your LAN to do the test.

    Below is a real world log from our database of an actual client download (using Win server 2008/apache/php5). It shows (left to right) file size, download start date/time, download complete date/time, time to download in sec, calculated user download speed kb/sec.

    11.17MB   04/16/09 12:03:09 04/16/09 12:03:48 39   293.38 

    Please confirm what part of my scenario you were unable to reproduce?

    Thanks again for your help with this

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 17, 2009 08:12 PM|ksingla|LINK

    Hi,

    I specified a file of size 150 MB which got downloaded fine. As you guessed, for me download was so fast that I couldn't tell if the statement next to readfile executed immediately. Behavior you are seeing is possible due to IIS response buffering. You can try disabling response buffering by setting responseBufferLimit property for PHP handler to 0. For the timeout issue, can you enable FREB and paste the trace log?

    Thanks,
    Kanwal

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 19, 2009 04:30 PM|centralusa|LINK

     Not exactly sure where to add the responseBufferLimitproperty. I added it to the applicationHost.config file in "C:\Windows\System32\inetsrv\config"

    <add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\php\php-cgi.exe" resourceType="Unspecified" responseBufferLimit="0" />

     Also

    <add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" responseBufferLimit="0" />

    restarted iis service - no change at all.

    In regards to trace log, I have not yet enabled this as this is the primary issue and may be linked to the timeouts. Regardless if the buffering does not work correctly (like apache) then this is fruitless as we cannot use php/iis combo unless this is working.

     Also seems liek this post is related
    http://forums.iis.net/t/1155825.aspx

    I followed these directiosn also but still no changes, although I was unsure about this step " FastCGIModule add line in the local web.config" as this is a php based site and I do not use a local web.config file

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 22, 2009 07:39 PM|centralusa|LINK

     I guess this probably has no resolution due to inadequacies in way iis works, no bother the workaround of usign apache works so I won't spend anymore time trying to force iis into compliance. Its hard to be all things all the time I just thought the glarring issue when using php for file handling woudl have had a simple workaround somewhere considering how mature iis is now. Anyhow thanks very much for your efforts and responses on this.

  • wadeh wadeh

    115 Posts

    Microsoft

    Re: php file handling on IIS/Fast-cgi different to apache

    Apr 22, 2009 10:57 PM|wadeh|LINK

    Hi centralusa,

    I'm not sure how you've reached the conclusion that there is no resolution for this.  Kanwal is the developer that owns the IIS FastCGI code and he is trying to reproduce the problem you are reporting.  If we can get a repro here, we will evaluate the problem and determine if we can release a fix.

    I've noticed that you haven't received a reply to your question from Sunday regarding how to set responseBufferLimit.  I can tell you that this setting goes in the applicationhost.config file and not the administration.config file, but I'm not in a place right now where I can give you a complete example of the syntax.

    I will make sure that someone from our team here posts this information tomorrow.

    Thanks,
    -Wade

  • wadeh wadeh

    115 Posts

    Microsoft

    Re: php file handling on IIS/Fast-cgi different to apache

    Apr 23, 2009 04:43 PM|wadeh|LINK

    Hi centralusa,

    The responseBufferLimit setting is an attribute within the handler mapping.  This information could go into %windir%\system32\inetsrv\config\applicationhost.config, or it could go into a web.config file.  It depends on where you set up your handler mapping for your FastCGI.

    In my case, I've mapped *.php to the FastCGI handler and php-cgi.exe for my default web site.  The following is the contents of the web.config file in my c:\inetpub\wwwroot directory.  It includes a setting to zero out responseBufferLimit.

    I hope that this helps,
    -Wade

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <handlers>
                <add name="PHP 5.2.9-2"
                     path="*.php"
                     verb="*"
                     modules="FastCgiModule"
                     scriptProcessor="c:\php529-2nts\php-cgi.exe"
                     resourceType="Unspecified"
                     responseBufferLimit="0" />
            </handlers>
        </system.webServer>
    </configuration>

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 25, 2009 11:39 AM|centralusa|LINK

     Thank you for your response, firstly I want to make clear I was not taking a shot at anyone here or complaining. I understand this feedback is out of the kindness of both who have replied to me and was trying to say - "Hey, thanks for the time you've invested in this it looks like an unresolvable issue at this point so lets not waste anymore time on it" - however I did not say this very well. As you will see in my post previous to both yours I have in fact added this setting to the correct place in the %windir%\system32\inetsrv\config\applicationhost.config file with no noticeable change.

     Further I had previously stated that I do not believe this is a Fastcgi issue, so was definitely not taking a shot at that module. I believe this is most definitely an inherit iis issue as stated I tested my same script on IIS6 with fastcgi and IIS6 without fastcgi and all 3 situations (including IIS7/fastcgi) gave me the same undesirable result - exactly the same actually, so this would indicate a serious shortcoming in IIS as it relates to file downloading as it compares to apache performing the same task. I will again also say we use almost exclusively Windows/IIS based servers, except for our firewalls/security (we use linux) so are definitely not pro apache just scratching our heads here why performance/reliability for managing file downloading is dramatically different between the two.


  • wadeh wadeh

    115 Posts

    Microsoft

    Re: php file handling on IIS/Fast-cgi different to apache

    Apr 27, 2009 12:37 PM|wadeh|LINK

    Hi centralusa,

    No worries.  I didn't think that you were taking a shot at anyone.  I'm mainly concerned that you may have found a bug that we'd like look at, but we can't reproduce it here.

    When you say that this is "an inherent IIS issue", keep in mind that we work on all of IIS.  It doesn't really matter if the bug is in FastCGI or anywhere else in IIS.  We are interested in understanding it.

    I understand if you don't have any more time to spend with it.  But we are here if you want to pursue it.

    Thanks,
    -Wade

  • Re: php file handling on IIS/Fast-cgi different to apache

    Apr 27, 2009 05:35 PM|centralusa|LINK

     OK, Absolutely the scenario is exactly as I laid out above. I believe the only difference is kslinga was using a setup on a local LAN which is not a real world setup for a website and he mentions that was reason he was unable to reproduce. Essentially your test scenario is quite a bit different to mine when I am operating on a remote dedicated server.

     

    Simply setup your site on a remote IIS machine use an php script to send a file download to your browser. I have supplied above the exact one I use. Log the start date/time of the download (code before the send file operation takes place) then log the date/time the file download completes on the users end. Unless you have a 20GB connection to the server and the file is under 10MB the 2 times to the sec should be different. In apache it manages the buffer so you can track the exact start and complete date/time of a file download using php. You will see above a sample of thsi data we capture for all file downloads.

    Thanks

  • Re: php file handling on IIS/Fast-cgi different to apache

    Oct 17, 2013 04:41 AM|Peter Roman|LINK