Forum Moderators: coopster

Message Too Old, No Replies

Image upload issue

         

dave1236

3:55 am on Oct 31, 2009 (gmt 0)

10+ Year Member



I earlier posted a question regarding how to upload images. Thanks to tweaking and this forum, I have been able to accomplish that goal.

Uploaded files show in the proper directory.

But now I am left with a strange issue where I cannot access these uploaded images. I receive a HTTP 403 Forbidden error.

For what it is worth, I use Yahoo Web Hosting.

My goal is to be able to save these images to my directory, insert the file name and location into my database, and ultimately to call and display these images on a webpage.

Here is the exact code:

<?php

$directory_self = str_replace(basename($_SERVER['PHP_SELF']), '', $_SERVER['PHP_SELF']);

$uploadsDirectory = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/';

$uploadForm = 'http://' . $_SERVER['HTTP_HOST'].'/upload.form';

$uploadSuccess = 'http://' . $_SERVER['HTTP_HOST'].'/upload.success.php';

// fieldname used within the file <input> of the HTML form
$fieldname = 'file'; // fieldname used within the file <input> of the HTML form
$fieldname = 'file';

// Now let's deal with the upload

// possible PHP upload errors
$errors = array(1 => 'php.ini max file size exceeded',
2 => 'html form max file size exceeded',
3 => 'file upload was only partial',
4 => 'no file was attached');

// check the upload form was actually submitted else print form
isset($_POST['submit'])
or error('the upload form is neaded', $uploadForm);

// check for standard uploading errors
($_FILES[$fieldname]['error'] == 0)
or error($errors[$_FILES[$fieldname]['error']], $uploadForm);

// check that the file we are working on really was an HTTP upload
@is_uploaded_file($_FILES[$fieldname]['tmp_name'])
or error('not an HTTP upload', $uploadForm);

// validation... since this is an image upload script we
// should run a check to make sure the upload is an image
@getimagesize($_FILES[$fieldname]['tmp_name'])
or error('only image uploads are allowed', $uploadForm);

// make a unique filename for the uploaded file and check it is
// not taken... if it is keep trying until we find a vacant one
$now = time();
while(file_exists($uploadFilename = $uploadsDirectory.$now.'-'.$_FILES[$fieldname]['name']))
{
$now++;
}

// now let's move the file to its final and allocate it with the new filename
@move_uploaded_file($_FILES[$fieldname]['tmp_name'], $uploadFilename)
or error('receiving directory insuffiecient permission', $uploadForm);

// If you got this far, everything has worked and the file has been successfully saved.
// We are now going to redirect the client to the success page.
header('Location: ' . $uploadSuccess);

// make an error handler which will be used if the upload fails
function error($error, $location, $seconds = 5)
{
header("Refresh: $seconds; URL=\"$location\"");
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'."\n".
'"http://www.w3.org/TR/html4/strict.dtd">'."\n\n".
'<html lang="en">'."\n".
'<head>'."\n".
'<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">'."\n\n".
'<link rel="stylesheet" type="text/css" href="stylesheet.css">'."\n\n".
'<title>Upload error</title>'."\n\n".
'</head>'."\n\n".
'<body>'."\n\n".
'<div id="Upload">'."\n\n".
'<h1>Upload failure</h1>'."\n\n".
'<p>An error has occured: '."\n\n".
'<span class="red">' . $error . '...</span>'."\n\n".
' The upload form is reloading</p>'."\n\n".
' </div>'."\n\n".
'</html>';
exit;
} // end error handler

?>

bkeep

4:51 am on Oct 31, 2009 (gmt 0)

10+ Year Member



Just to make sure. You can upload the images and they are available through the file directories, right? Check if hotlinking is disabled or direct image access is denied via htaccess or something similar. Also Check the uploaded file permissions. I don't know about yahoo's hosting services explicitly so that seems like a logical start.

dave1236

2:23 pm on Oct 31, 2009 (gmt 0)

10+ Year Member



The files show in the inserted directory. When I try to open them, I cannot. How do I check permissions and htaccess, etc.

bkeep

4:55 pm on Oct 31, 2009 (gmt 0)

10+ Year Member



If you can login with a ftp client, it should show you the permissions. I use FileZilla it is Open Source. some ftp clients hide . files automagicly but the filename is .htaccess

rocknbil

7:34 pm on Oct 31, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



But now I am left with a strange issue where I cannot access these uploaded images.

$uploadsDirectory = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/';

Suplement to my reply in your other thread:

- How are you accessing these images?" If you are going to

example.com/inserted/uploaded_files/

And hoping to view all uploaded files, it may be simply that directory indexing is disabled for this directory - which is a good thing. You don't want someone snooping around in your directories.

If you do this

example.com/inserted/uploaded_files/sample.jpg

and get a 403, see other thread - it's likely a permissions issue or not going where you think they are going. The reason I say that is this:

$_SERVER['DOCUMENT_ROOT']

is not always the domain root. (Thx to phranque for the reminder.) With virtual hosting, you may have

[user account root]
cgi-bin
usr
public_html
public_html/sample.com
public_html/sampletoo.com
public_html/sample3.com
stats
error_log
(etc.)

In which case $_SERVER['DOCUMENT_ROOT'] may very likely be public_html, not public_html/domain name. Anything outside of public_html is likely disallowed, with the exception of cgi-bin (which PHP guys and gals never use.:-) )

dave1236

3:01 am on Nov 1, 2009 (gmt 0)

10+ Year Member



Thanks for this enlightening feedback.

Based on your response, I did the following:

1) looked for .htaccess and found that Yahoo does not allow access to them.
2) used ftp to upload a specific image directly...this showed up in the same directory as other files loaded via my form. And the file added via FTP was accessible.
3) entered the complete path in my browser...I was shown all the uploaded files resided in the directory, yet the only file I was able to access was the file loaded via FTP.

I guess I am looking at a permissions issue...is there any way to resolve this issue?

Or is this a hosting issue?

rocknbil

6:14 pm on Nov 1, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Okay, so you can see the files via FTP. You should be able to get directory information which shows the file permissions, or get permissions set on a sample file. They are probably set to read only by owner, and that is likely to be the user account or Apache (varies.) It needs to be read by all (but not execute or write by all. Execute and write by owner only.)

I would normally suggest checking the permissions of the parent directory(ies) first, but if you can view all contents, the directory is already read by all (this is not great, by the way, but you wouldn't change it using permissions, you'd change the domain or specific directory configuration to disable directory indexing.)

Review the chmod command [us3.php.net], (there are nuances you need to know) and how to use it. If you need more help understanding permissions, Google for chmod (the PHP chmod and the actual server command are the same name, but not the same thing.) Immediately after executing move_upload_file(), add a line to set the permissions on the uploaded file to read by all, write and execute by owner only.

$thisFile = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/' . $filename;

chmod("$thisFile", 0644);

Note that we use the full server path as it's a system command, not a URL.

That should do it.

dave1236

7:34 pm on Nov 2, 2009 (gmt 0)

10+ Year Member



Thanks. I have read up on permissions, and am currently testing.

A quick question however - I am a little confused about the difference between 'read' and 'execute'. If i have a script, would I not have to have execute permissions as well to run that script?

Much appreciated!

FourDegreez

4:02 am on Nov 3, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you are going to be using chmod, you may drive yourself crazy unless you also look into umask.

rocknbil

7:52 pm on Nov 3, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If i have a script, would I not have to have execute permissions as well to run that script?

You're mixing up the files with the scripts. First, (I am pretty sure, someone correct me) PHP scripts don't **need** execute permissions. With a Perl script, for example, you need to set permissions to execute or it will 500 error. This is one of the things administrators always liked about PHP - no more phone calls for "my script won't work" when it's just execute permissions.

Second, permissions are a multidimensional "array" if you will, usually expressed in columns for owner, group, other, and rows for read, write, execute. Do a G search for chmod to see what they all mean.

The problem you are having: your script, which is likely running under the owner "user account" or "Apache," writes a file. That file is now owned by that owner with **only** the owner having read/write/execute permissions on the file.

Along comes "everyone" or "world" (i.e., you in a browser, public access) and tries to view (read) the file, and there are no read permissions for "world." So they get denied.

For world or group, you should not need execute permissions on a file that only needs to be read. Always leave read/write/execute on for owner.

However - hopefully this won't confuse you, but follow the logic - let's say you have a script that opens and prints the files to your browser. If you want to protect the true location of your files, this is a very good approach.

This "reader" script is also under the same "owner" as your upload script. So this SCRIPT would be able to open the files and print them to the browser. This would allow you to leave the permissions alone, restricting "direct" access, making for increased security in respect to those files.

A scenario, only view images if logged in, done all the time on message boards.