File download quirks

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • php newbie

    File download quirks

    Hello,

    I have a php script that allows users to download files they selected
    earlier in the session.
    I use the following code snippet to do this:

    ## set up headers
    header("Content-type: application/x-gzip");
    header("Content-disposition: filename: $filename");
    header("Filenam e: $filename");
    header("Content-length: ".filesize("pri vate/$filename"));

    ## now send the contents
    @readfile("priv ate/$filename");


    The problem is that the downloaded file gets named as this php code's
    file name, and not the actual file name. I mean, if the php code is
    in a file named process.php and the file the users download is
    myfile.zip, the browser chooses to save the file as process.php.gz.

    Any suggestions to fix this?
  • Paul Wellner Bou

    #2
    Re: File download quirks

    php newbie wrote:[color=blue]
    > Hello,
    >
    > I have a php script that allows users to download files they selected
    > earlier in the session.
    > I use the following code snippet to do this:
    >
    > ## set up headers
    > header("Content-type: application/x-gzip");
    > header("Content-disposition: filename: $filename");[/color]
    Use this:
    header('Content-Disposition:att achment;filenam e="$filename"') ;
    [color=blue]
    > header("Filenam e: $filename");
    > header("Content-length: ".filesize("pri vate/$filename"));
    >
    > ## now send the contents
    > @readfile("priv ate/$filename");
    >
    > The problem is that the downloaded file gets named as this php code's
    > file name, and not the actual file name. I mean, if the php code is
    > in a file named process.php and the file the users download is
    > myfile.zip, the browser chooses to save the file as process.php.gz.
    >
    > Any suggestions to fix this?[/color]

    Afaik not. On php.net they say:

    <quote>
    Note: There is a bug in Microsoft Internet Explorer 4.01 that
    prevents this from working. There is no workaround. There is also a
    bug in Microsoft Internet Explorer 5.5 that interferes with this,
    which can be resolved by upgrading to Service Pack 2 or later.
    </quote>

    --> http://de2.php.net/manual/en/function.header.php

    Saludo
    Paul.

    Comment

    • John Dunlop

      #3
      Re: File download quirks

      Paul Wellner Bou wrote:
      [color=blue]
      > Use this:
      > header('Content-Disposition:att achment;filenam e="$filename"') ;[/color]

      Well, I agree with your point: a disposition-type is required. I
      think you've gotten your quotes muddled up though. No variable
      expansion occurs in single-quoted strings.

      If you follow RFC2183's advice, however, and keep to short
      alphanumeric filenames, there's absolutely no need to quote the
      filename value.

      I think RFC2616's grammar here (sec. 19.5.1) is misleading, and not
      in accordance with RFC1806's or RFC2183's definition of the Content-
      Disposition header. In RFC2616, we're given:

      | content-disposition = "Content-Disposition" ":"
      | disposition-type *( ";" disposition-parm )
      | disposition-type = "attachment " | disp-extension-token
      | disposition-parm = filename-parm | disp-extension-parm
      | filename-parm = "filename" "=" quoted-string
      | disp-extension-token = token
      | disp-extension-parm = token "=" ( token | quoted-string )

      (You might have to read it in conjunction with section 2.2, if you
      haven't already memorised every rule. ;-))

      which may give the mistaken impression to those unfamiliar with ABNF
      that the filename parameter value must consist of a quoted-string.
      It doesn't. Verily, this grammar allows characters in the filename
      value that are *not* allowed by RFCs 1806 or 2183! I think RFC2616
      should've left the definition to the RFC it referenced.

      RFC1806, referenced by RFC2616, states the value of the filename
      parameter in a Content-Disposition header to be of type value. A
      value is either a quoted-string or a token; a token is basically the
      entire ASCII character set, save a few special characters
      ("tspecials" , to use their terminology), spaces and control
      characters. Thus, values like name.extension can be left unquoted.

      RFC2183 updates RFC1806, but values stay the same. RFC2183 contains
      the additional proviso that a "short (length <= 78 characters)
      parameter value containing only non-`tspecials' characters SHOULD be
      represented as a single `token'", i.e, filenames like my example
      above *shouldn't* be quoted.

      --
      Jock

      Comment

      • Paul Wellner Bou

        #4
        Re: File download quirks

        John Dunlop wrote:[color=blue]
        > Paul Wellner Bou wrote:[color=green]
        >>Use this:
        >> header('Content-Disposition:att achment;filenam e="$filename"') ;[/color]
        >
        >
        > Well, I agree with your point: a disposition-type is required. I
        > think you've gotten your quotes muddled up though. No variable
        > expansion occurs in single-quoted strings.[/color]

        Of course... sorry.
        Didn't thought enough... and applied the php.net example without
        thinking in the variable ;-)
        [color=blue]
        > If you follow RFC2183's advice, however, and keep to short
        > alphanumeric filenames, there's absolutely no need to quote the
        > filename value.[/color]

        Ok. I trusted the examples, here.
        [color=blue]
        > (You might have to read it in conjunction with section 2.2, if you
        > haven't already memorised every rule. ;-))[/color]

        No, I didn't... ;)
        [color=blue]
        > [...][/color]
        [color=blue]
        > RFC2183 updates RFC1806, but values stay the same. RFC2183 contains
        > the additional proviso that a "short (length <= 78 characters)
        > parameter value containing only non-`tspecials' characters SHOULD be
        > represented as a single `token'", i.e, filenames like my example
        > above *shouldn't* be quoted.[/color]

        Which example?
        The "filename" used here?
        [color=blue]
        > | filename-parm = "filename" "=" quoted-string[/color]

        The example of /php-newbie/ only contains a variable.

        Saludo
        Paul

        Comment

        • John Dunlop

          #5
          Re: File download quirks

          Paul Wellner Bou wrote:
          [color=blue]
          > John Dunlop wrote:[/color]
          [color=blue]
          > Which [filename] example?[/color]

          name.extension
          [color=blue]
          > The "filename" used here?
          >[color=green]
          > > | filename-parm = "filename" "=" quoted-string[/color][/color]

          "filename" is just the (case insensitive) string "filename". The
          grammar, by using quoted-string, makes it look as though the filename
          parameter value must be quoted. It does not have to be quoted.
          [color=blue]
          > The example of /php-newbie/ only contains a variable.[/color]

          It's the contents of that variable which are important. It is
          recommendable that filenames be short and contain only alphanumeric
          characters. If they fit that description, they shouldn't be quoted.

          My article was an observation on RFC2616's misleading grammar. I
          didn't intended to address specific questions.

          --
          Jock

          Comment

          • Shawn Wilson

            #6
            Re: File download quirks

            php newbie wrote:[color=blue]
            >
            > I have a php script that allows users to download files they selected
            > earlier in the session.
            > I use the following code snippet to do this:
            >
            > ## set up headers
            > header("Content-type: application/x-gzip");
            > header("Content-disposition: filename: $filename");
            > header("Filenam e: $filename");
            > header("Content-length: ".filesize("pri vate/$filename"));
            >
            > ## now send the contents
            > @readfile("priv ate/$filename");
            >
            > The problem is that the downloaded file gets named as this php code's
            > file name, and not the actual file name. I mean, if the php code is
            > in a file named process.php and the file the users download is
            > myfile.zip, the browser chooses to save the file as process.php.gz.
            >
            > Any suggestions to fix this?[/color]

            In addition to the helpful suggestions already mentioned, I'd like to add that
            there's no guarantee that all browsers will pick up your file name. What you
            could do is rename your PHP script to something like "download" (notice, no .php
            extension). Make or change a .htaccess to force Apache to treat that file like
            a PHP file.

            In the PHP file, parse the $_SERVER['QUERY_STRING'] to get the file name, and if
            it exists (make sure they can't traverse directories and all the usual security
            stuff) do your thing.

            So you'd call your file with something like:





            Regards,
            Shawn

            --
            Shawn Wilson
            shawn@glassgian t.com

            Comment

            Working...