fsockopen: adding Content-Length corrupts downloaded file?

Discussion in 'PHP' started by szalinski, Feb 7, 2008.

  1. #1
    Hello

    I wonder if anyone can tell me if I am misunderstanding something in the way headers and so on work.
    I found this little script for fetching a remote file, and prompting the user to download it in their browser.

    However, if I add the content-length manually, which i added just test, the file downloaded is corrupt. But if I comment this out, the file downloads with an unknown filesize, but is NOT corrupt - it is fine.

    Not only this, but if I want to get the filesize of files before I download them, I can't - because I can't send headers to GET the Content-Length, and then when I have the size I send more headers to allow the user to be prompted to download the file - I will get the infamous 'headers already sent' error. It's like there is some sort of paradox in this respect?? (Hope you understand that!).

    This fsockopen thing is starting to drive me nuts, I really hope somebody has some idea of what's going on. And I can't use cURL, or anything else so please help!!
    This isn't the first method in which I've had this problem. :(

    <?php
    $host = "files.thetravelcabin.com";
    $uri = "/file/rs-dlh.rar";
    
    //Get the file from the remote location
    function getFile($host, $uri, $port)
    {
        $hdr = '';
        $file_cont = '';
        $fh = fsockopen($host, $port, $errno, $errstr, 300);
    
        if(!$fh)
        {
            return "error";
        } else {
    
            $hdr .= "POST $uri HTTP/1.0\r\n";
            $hdr .= "Host: $host\r\n";
            $hdr .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n";
            $hdr .= "Content-Type: application/x-www-form-urlencoded\r\n";
            $hdr .= "Content-Length: ".strlen($uri)."\r\n";
            $hdr .= "Connection: close\r\n\r\n";
    
    fwrite($fh, $hdr);
    
            while(!feof($fh))
            {
                $file_cont .= fgets($fh, 128);
            }
    
            //Return the file as a string
            return $file_cont;
        }
    }
    
    //Set up essential headers
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=".basename($uri));
    
    //I add this manually to test (I know the size is correct). But I get a corrupt file? If I comment out Content-Length, the file is not corrupt, but has a filesize 'unknown' when i download it.
    header("Content-Length: 782839");
    
    //Strip the text headers in the file and print it out.
    //print getFile($host, $uri, 80);
    print preg_replace("/^.*\r\n\r\n/m", "", getFile($host, $uri, 80));
    ?>
    PHP:
     
    szalinski, Feb 7, 2008 IP
  2. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #2
    strlen($vars) equals zero, because $vars isn't set.

    You can get the size (in most cases) of the file before downloading it using get_headers().
     
    nico_swd, Feb 7, 2008 IP
  3. szalinski

    szalinski Peon

    Messages:
    341
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #3
    I knew I'd forget something. And sure enough, I did.
    You said "strlen($vars) equals zero, because $vars isn't set" - well, i tried it a different way already with that not being the problem, and the file is still corrupt.
    I've changed the code and put $uri in place of $vars - yet it is still corrupt. if i remove an \r\n from the preg_replace, i get text back that looks to be the start of the file with the headers removed ok, but the file is still corrupt -maybe it chops away end of the file.

    I think I am correct in being able to put a Content-Length there manually, it shouldn't effect the output of the file right? because it's only if i add that myself, the file output is corrupt. I'm only doing it, purely to simulate what would normally be there if i did choose to get the content-length from the headers first...

    any ideas what to do next? :(
     
    szalinski, Feb 7, 2008 IP
  4. szalinski

    szalinski Peon

    Messages:
    341
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #4
    nevermind, i solved it, only i don't know how! :D
     
    szalinski, Feb 19, 2008 IP