Solved

PHP interpret file with spaces

Posted on 2010-09-15
11
528 Views
Last Modified: 2013-12-25
I  have a photo gallery where the user is allowed to download a hires version of the images by clicking a link. I usually use non web safe names for the photo naming convention mainly for design purposes. This causes the PHP script to stop interpreting the file name at the first instance of  "%20". So if 50  images have the same name except for a counter, the user will be offered to download the same file name every time.

So... I need to modify the code below to properly interpret file name when it contains "%20".

download.php - this file is in the directory along with hires images.

<?php
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['img']))
{
   $filename = basename($_GET['img']); // don't accept other directories
   $size = @getimagesize($filename);
   $fp = @fopen($filename, "rb");
   if ($size && $fp)
   {
      header("Content-type: {$size['mime']}");
      header("Content-Length: " . filesize($filename));
      header("Content-Disposition: attachment; filename=$filename");
      header('Content-Transfer-Encoding: binary');
      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
      fpassthru($fp);
      exit;
   }
}
header("HTTP/1.0 404 Not Found");
?> 

Open in new window


This HTML code invokes the download option:
<img src="/images/download.php?img=imagename.jpg" alt="test">

Open in new window


Example: These file names work:

Game_1_Hopkins_09_10_01.jpg
Game_1_Hopkins_09_10_02.jpg

These don't:
Game%201%20Hopkins%2009%2010%2001.jpg
Game%201%20Hopkins%2009%2010%2002.jpg

I normally would use this naming convention on the original files, and my gallery design software would add the "%20" to enable the browser to interpret the file name. Which has always worked fine except in this instance, which allows a download of the original image.

Game 1 Hopkins.09.10.01.jpg

Which is:  filename:month:year:counter

Sorry for this very long winded description. Just wanted to be clear.

0
Comment
Question by:tplowe56
  • 4
  • 4
  • 3
11 Comments
 
LVL 6

Expert Comment

by:DalHorinek
Comment Utility
try not to suppress error notifications and see, if there are any errors ...

Generally this should work.
0
 
LVL 6

Accepted Solution

by:
DalHorinek earned 125 total points
Comment Utility
Also you should use
header("Content-Disposition: attachment; filename=".urlencode($filename));

Maybe some browsers can't handle it :)


Anyway your code works perfectly on my server no  matter what filename is used.
0
 
LVL 42

Assisted Solution

by:Chris Stanyon
Chris Stanyon earned 125 total points
Comment Utility
You can use the urldecode function to convert the %20 back to spaces.

http://php.net/manual/en/function.urldecode.php



$filename = urldecode(basename($_GET['img'])); // don't accept other directories

Open in new window

0
 
LVL 6

Expert Comment

by:DalHorinek
Comment Utility
This PHP does automatically.

See urldecode Warning:

The superglobals $_GET and $_REQUEST  are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
Apparently not!

If it does it automatically, then why are you still getting %20 in the GET variables? These are urlencoded spaces and to convert them back to spaces you need to use urldecode($string);

You could try and echo out the $_GET['img'] value (or $filename) and see what you get.







0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:tplowe56
Comment Utility
I have been investigating this further. The code will work fine if my gallery engine would generate the "%20" for the spaces in this instance, which it isn't and won't. So I think I need to add urlencode to the code above to get it to parse the file names which have spaces in them.

I am not a coder, I am a copy/paste coder. So I am not sure how to do it.

The code invokes a download just fine but it suggests to save every file as "game" (the first word in the file name before a space", thus allowing unsuspecting users to overwrite the last image they downloaded if they are not paying attention.
0
 

Author Comment

by:tplowe56
Comment Utility
OK...I got it working fine now with this code:

<?php
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['img']))
{
   $filename = basename($_GET['img']); // don't accept other directories
   $size = @getimagesize($filename);
   $fp = @fopen($filename, "rb");
   if ($size && $fp)
   {    
      header("Content-type: {$size['mime']}");
      header("Content-Length: " . filesize($filename));
      header("Content-Disposition: attachment; filename=".urlencode($filename));
      $filename = urlencode(basename($_GET['img'])); // don't accept other directories
      header('Content-Transfer-Encoding: binary');
      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
      fpassthru($fp);
      exit;
   }
}
header("HTTP/1.0 404 Not Found");
?>


Not sure who gets the credit, I initially describe the problem wrong.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
DalHorinek has already posted the code to urlencode your filename to present to your user.

Change line 13 (in your code above) to the following, and see how you get on.


 
 

 header("Content-Disposition: attachment; filename=" . urlencode($filename));

Open in new window

0
 
LVL 6

Expert Comment

by:DalHorinek
Comment Utility
ChrisStanyon, than it probably depends on configuration, because it works for me.

See
http://www.travelcook.com/~dal/test.php?file=whatever%20with%20spaces.jpg

It's ok.

Even if you try it over telnet (to avoid browsers handling)

telnet travelcook.com 80
Trying 89.185.224.39...
Connected to travelcook.com.
Escape character is '^]'.
GET /~dal/test.php?file=whatever%20with%20spaces.jpg HTTP/1.0

HTTP/1.1 200 OK
Date: Wed, 15 Sep 2010 19:48:33 GMT
Server: Apache
X-Powered-By: PHP/5.3.1-5
Content-Length: 29
Connection: close
Content-Type: text/html; charset=UTF-8

Filename: 'whatever goes.jpg'
0
 
LVL 42

Expert Comment

by:Chris Stanyon
Comment Utility
DalHorinek.

It worked for me aswell.

@tplowe56 said that the $filename in his script still contained the %20, which indicated that the GET array wasn't being urldecoded. Turned out to not be the case.






0
 

Author Comment

by:tplowe56
Comment Utility
Thanks guys, experts exchange is THE place for accurate support. Mission accomplished.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now