Jump to content

Archived

This topic is now archived and is closed to further replies.

freelance84

downloading a file to smartphone acting up...

Recommended Posts

 

I have written a page on my site which essentially is a web based ftp program. It has the added bonus of indicating which files are being worked on, what jobs need completing on each file.

 

Everything works perfectly fine on a laptop or desktop computer: Files can be downloaded, the indicators are set, the files can then be uploaded again and the indicators reset... etc etc.

 

Earlier today I found my self wanting to test the new system on a train with my HTC smartphone. All the scripts to display the contents of the public_html, the indicators as to which files were being worked on and all the toDoLists were working fine.

 

THE PROBLEM was, when I attempted to download any of the scripts on the smartphone i kept hitting a 'safety' and instead of getting the file i wanted i was getting the 'in_use.png' image.

 

(the 'safety' i am talking about is this: If two users load up the directory tree on two separate computers simultaneously, if user1 downloads file x there will be no way of user2 knowing this until they reload their page. As a result user2 may then try to download file X before reloading their page. As a 'safety', i simply wrote in that in such a scenario user2 simply gets a very small image which reads 'sorry in use' instead of the file, thus preventing two people working on the same file at the same time.)

 

 

 

I was wondering if somebody might be able to have a glance through the 'download' script and spot any reasons why it works on a proper computer but not on a smartphone... (be as brutal as you like with it, i'm still learning)

	if(isset($_GET['theFile']))
		{
			//the file name
			$theFile = htmlentities($_GET['theFile']);

			//the files location
			$theLocal = htmlentities($_GET['theLocal']);

			//the full path
			$dirFile = $theLocal.$theFile;

			$dirFile_mysql = mysql_real_escape_string($dirFile);

			//the mime type of the file (the function is set into the functions.php
			$mimeType = mime_content_type($dirFile);

			//check if the file has an entry in the management table and check if the entry indicates if the file is currently being worked on:
			$query_checkFile = mysql_query("SELECT
												beingEdited,
												editorID
											FROM
												ftp_management
											WHERE
												theFile = '$dirFile_mysql'
										");
			if(!$query_checkFile)
				{
					echo mysql_error();
					exit();
				}
			//an entry for this file already exists. Check if it being edited
			if(mysql_num_rows($query_checkFile))
				{
					$query_checkFile_row = mysql_fetch_row($query_checkFile);
					//if the file is in use then send back the in_use.png instead of the file they wanted.
					if($query_checkFile_row[0] == 'yes')
						{
							//get the username of the person editing the file
							$query_username = mysql_query("SELECT
															username
														FROM
															members
														WHERE
															ID = '$query_checkFile_row[1]'
													");
							$query_username_row = mysql_fetch_row($query_username);
							//set the name of the file
							$messageFileName = "$query_username_row[0]_is_now_editing_this_file.png";
							//the path of the in_use.png file to throw back instead of the actual file
							$actualErrorImgPath = '../public_html/png/error_inUse.png';
							//getting the mime type of the file to throw back
							$actualErrorImgPathMim = mime_content_type($actualErrorImgPath);
							//headering back with the download of the inuse image instead of the file
							header('Content-disposition: attachment; filename='.$messageFileName);
							header('Content-type:'.$actualErrorImgPathMim);
							readfile($actualErrorImgPath);
						}
					//if the file is not in use then enter 'yes' in the ftp_management table then give them the file they wanted:
					else{
							//alter the in_use status and details to the file in question
							if(isset($_GET['theReason']))
								{
									$reason = mysql_real_escape_string(htmlentities($_GET['theReason']));
								}
							$time = time();

							$query_alterInUseSign = mysql_query("UPDATE
																	ftp_management
																SET
																	beingEdited = 'yes',
																	editorID = '$u_ID',
																	startTime = '$time',
																	startReason = '$reason',
																WHERE
																	theFile = '$dirFile_mysql'
																");
							//now header back with the file in question
							header('Content-disposition: attachment; filename='.$theFile);
							header('Content-type:'.$mimeType);
							readfile($dirFile);
						}
				}
			//an entry does not already exist for this file, a new entry must be made before downloading
			else{
					//enter the new entry
					//alter the in_use status and details to the file in question
					if(isset($_GET['theReason']))
						{
							$reason = mysql_real_escape_string(htmlentities($_GET['theReason']));
						}
					$time = time();

					$query_newEntry = mysql_query("INSERT INTO
														ftp_management(
															theFile,
															beingEdited,
															editorID,
															startTime,
															startReason,
															)

														VALUES(
																'$dirFile_mysql',
																'yes',
																'$u_ID',
																'$time',
																'$reason',
															)
												");

					header('Content-disposition: attachment; filename='.$theFile);
					header('Content-type:'.$mimeType);
					readfile($dirFile);
				}
		}

 

 

If you've got the time to have a look through and comment i would be very appreciative.

Share this post


Link to post
Share on other sites

the code looks like it should only trigger the "in use" PNG when the "beingEdited" column returns "yes"

 

perhaps your problem isn't in the download script but in whatever script should have set the column back to "no" before you ran the download script?

Share this post


Link to post
Share on other sites

 

Hmm, yea this is what i'm thinking... however it doesnt seem to explain how it works ok on a computer but not a smartphone. Even with the ftp_management table empty it still returns the 'in_use.png'...

 

It's almost as if the smartphone is running the script twice for some reason.

 

Maybe the smartphone is getting some response after the update or insert meaning (somehow) that it is sending the xml request again... meaning the above php script runs twice.

 

I don't get it.

 

Maybe if i rearrange the script so the first instance of any header is outputting the actual file... i'll have a go 2mo.

 

Thanks for having a look though  :)

Share this post


Link to post
Share on other sites

Ok, i've rearranged my script so now the very last option from the it statements is to download the 'in_use.png'.

 

I tested the script on the desktop and everything work fine.

 

I try to download test.php file from a smartphone and the result is: the smartphone downloads a file called 'test.htm' Upon opening the file, the phone asks which program to open test.htm with, i choose a text editor and then see what a .png file looks like when you open it in a text editor.... a load of ? in black diamonds...etc. I really dont get it.

 

 

Here is the rearranged code. If anyone has the time and spots something... that would be awesome. If not I might have to just leave this one on the back burner for a while. Doesn't make any sense to me though.

 

if(isset($_GET['theFile']))
		{
			//the file name
			$theFile = htmlentities($_GET['theFile']);
				//if the file is a.thaccess then remove the a
				if($theFile == 'aaa')
					{
						$theFile = '.htaccess';
					}

			//the files location
			$theLocal = htmlentities($_GET['theLocal']);

			//the full path
			$dirFile = $theLocal.$theFile;

			$dirFile_mysql = mysql_real_escape_string($dirFile);

			//the mime type of the file (the function is set into the functions.php
			$mimeType = mime_content_type($dirFile);

			//check if the file has an entry in the management table and check if the entry indicates if the file is currently being worked on:
			$query_checkFile = mysql_query("SELECT
												beingEdited,
												editorID
											FROM
												ftp_management
											WHERE
												theFile = '$dirFile_mysql'
										");
			if(!$query_checkFile)
				{
					echo mysql_error();
					exit();
				}

			//an entry does not already exist for this file, a new entry must be made before downloading
			if(!mysql_num_rows($query_checkFile))
				{
					//enter the new entry
					//alter the in_use status and details to the file in question
					if(isset($_GET['theReason']))
						{
							$reason = mysql_real_escape_string(htmlentities($_GET['theReason']));
						}
					$time = time();

					$query_newEntry = mysql_query("INSERT INTO
														ftp_management(
															theFile,
															beingEdited,
															editorID,
															startTime,
															startReason,
															finishTime,
															finishNotes)

														VALUES(
																'$dirFile_mysql',
																'yes',
																'$u_ID',
																'$time',
																'$reason',
																'',
																'')
												");

					header('Content-disposition: attachment; filename='.$theFile);
					header('Content-type:'.$mimeType);
					readfile($dirFile);
				}
			//an entry for this file already exists. Check if it being edited
			else
				{
					$query_checkFile_row = mysql_fetch_row($query_checkFile);
					//if the file is not in use then enter the in use sign in the ftp_management file then give them the file they wanted:
					if($query_checkFile_row[0] != 'yes')
						{
							//alter the in_use status and details to the file in question
							if(isset($_GET['theReason']))
								{
									$reason = mysql_real_escape_string(htmlentities($_GET['theReason']));
								}
							$time = time();

							$query_alterInUseSign = mysql_query("UPDATE
																	ftp_management
																SET
																	beingEdited = 'yes',
																	editorID = '$u_ID',
																	startTime = '$time',
																	startReason = '$reason',
																	finishTime = '',
																	finishNotes = ''
																WHERE
																	theFile = '$dirFile_mysql'
																");
							//now header back with the file in question
							header('Content-disposition: attachment; filename='.$theFile);
							header('Content-type:'.$mimeType);
							readfile($dirFile);
						}
					//if the file is in use then send back the in use . png instead of the file they wanted.
					else
						{
							//get the username of the person editing the file
							$query_username = mysql_query("SELECT
															username
														FROM
															members
														WHERE
															ID = '$query_checkFile_row[1]'
													");
							$query_username_row = mysql_fetch_row($query_username);
							//set the name of the file
							$messageFileName = "$query_username_row[0]_is_now_editing_this_file.png";
							//the path of the in_use.png file to throw back instead of the actual file
							$actualErrorImgPath = '../public_html/png/error_inUse.png';
							//getting the mime type of the file to throw back
							$actualErrorImgPathMim = mime_content_type($actualErrorImgPath);
							//headering back with the download of the inuse image instead of the file
							header('Content-disposition: attachment; filename='.$messageFileName);
							header('Content-type:'.$actualErrorImgPathMim);
							readfile($actualErrorImgPath);
						}
				}
	}

Share this post


Link to post
Share on other sites

I didn't have a chance to look at the code again,  but again, thinking out side of the programming aspect, since it works from a PC and PHP is run serverside (meaning it should matter if your accessing it from a PC or a phone or a mac or whatever) then I would starting thinking about what exactly does the phones browser do that your computer doesnt'.

 

maybe it's cacheing that image file? and displaying it regardless of what the PHP is returning.

 

have you tried this from more than one phone yet?

Share this post


Link to post
Share on other sites

Yea I've tried it on a htc desire z and a samsung galaxy s. Same results on both. Haven't had chance to test it on a non-google android OS yet though.

 

 

The result on both was: a download consisting of the .png file renamed to a .htm version of the target file.

 

EG:

Click to download "about_us.php" and get a file called "about_us.htm". Try to open the said file in an editor to find it is the png file....  :shrug:

 

Here is a snap shot of three files downloaded to the phone, each is actually a .png image named as a .thm, where they should all actually be .php files...

 

(hahaha, and just read properly what the ad on the app was haha!)

 

[attachment deleted by admin]

Share this post


Link to post
Share on other sites

what happens (for testing purposes) when you completly remove that last ELSE block (lines ~104-125) which send the header info of the png file?  If you take that out and its still shows up on the phone then its not the code.  If it doesn't show up on the phone, then you gotta wonder why that block of code is executing.

Share this post


Link to post
Share on other sites

Hmm...

 

Well with the last ELSE block removed the results are:

 

TEST 1 (when downloading a file named anotherTester.php from a smartphone)

1. A file is downloaded

2. The file is saved on the phone as 'anotherTester.htm'

3. The contents of the file... nothing. It is completely empty.

 

TEST 2 (when downloading an image file named chevrons.png from a smartphone)

1. A file is downloaded

2. The file is saved on the phone as 'chevrons.png'

3. The contents of the file... nothing. It is completely empty.

 

TEST 3 (when downloading an image file named chevrons.png from a PC)

1. A file is downloaded

2. The file is saved on the phone as 'chevrons.png'

3. The image downloaded is readable and perfectly fine.

 

____________________________________________________

 

 

 

Could it be that the smartphone requires a different sort header for downloading images? I have currently been using the androids built in browser. I will give it shot with FF mobile version and see what the results are.

 

But then that still doesn't explain how before it downloaded an image it was never asked to do... and named it something different to what should have been instructed by the above scripts.

Share this post


Link to post
Share on other sites

 

OK.

 

Testing the download script in the mobile version of FireFox works fine.

 

If anyone ever reads this thread in the future wanting to write something similar... the built in Android web browser doesn't download properly. No idea what goes wrong or why but it does.

 

Use the mobile FireFox.

 

Thanks for the help micah1701. Much appreciated.

Share this post


Link to post
Share on other sites

glad to see you got it worked out, even if the work around is using a different browser.

 

I googled the issue and it seems lots of people have had problems with Android's interpretation of various header types, here's an interesting blog post which a related issue (although, they're not talking about images specifically I don't think) http://digiblog.de/2011/04/19/android-and-the-download-file-headers/

 

 

Share this post


Link to post
Share on other sites



×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.