File Upload script hangs on Safari?

Discussion in 'Web Design and Development' started by Brendon Bauer, Mar 21, 2009.

  1. Brendon Bauer
    Expand Collapse
    macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #1
    I have taken bits and pieces of an upload script to upload files to my server, but it seems like every browser works fine except Safari. It's like a 50/50 chance that Safari will hang or upload it successfully. I'm dealing with 10-20mb files and so it's not fun to sit around for 5 minutes and then realize it wasn't working. I've tested with 200kb files so I know in a matter of seconds whether it worked or not. When it doesn't work and just is "loading" if I click upload again, it will work. I was wondering if maybe you could spot my problem in the code:

    Here is the form:
    Code:
    <html>
    <title>File Upload</title>
    <script type="text/javascript">
    <!--
    	function toggle_visibility(id) {
    	   var e = document.getElementById(id);
    	   if(e.style.display == 'block')
    		  e.style.display = 'none';
    	   else
    		  e.style.display = 'block';
    	}
    -->
    </script>
    </head>
    <body>
    
    <h2>File Upload</h2>
    
    <?php
    	error_reporting(0);
    	$errors = array();
    	$mm = $_GET['mm'];
    	$dd = $_GET['dd'];
    	$yy = $_GET['yy'];
    	$date = $mm."/".$dd."/".$yy;
    ?>
    		
    <br /><p>Date: <?php echo $mm."/".$dd."/".$yy; ?><br /><br /><i>(The audio sermon must be an mp3 file under 20MB in size)</i></p>
    
    <p><form enctype="multipart/form-data" action="audio_sermon_2a.php" method="POST">
    
    	<input type="hidden" name="MAX_FILE_SIZE" value="21000000" />
    	<input type="hidden" name="year" value="<?php echo "20".$yy; ?>" />
    	<input type="hidden" name="mm" value="<?php echo $mm; ?>" />
    	<input type="hidden" name="dd" value="<?php echo $dd; ?>" />
    	<input type="hidden" name="yy" value="<?php echo $yy; ?>" />
    
    	Choose a sermon file to upload: <input type="file" name="file" size="30" /><br /><br /><br />
    
    	<div class="buttons"><button type="submit" name="submit" onclick="toggle_visibility('loadinggif');" class="positive"><img src="/images/icons/tick.png" alt="" /> Upload Sermon</button></div><br /><br /><br />
    </form></p>
    <div id="loadinggif" style="margin: 0; padding: 0; display: none;"><p><table border="0"><tr><td><img src="/images/loading.gif" alt="loading..." /></td><td valign="middle">  Uploading... please be patient...</td></tr></table></p></div>
    
    </body>
    </html>
    That page takes a date passed to it via get and uses it to choose the location and filename for uploading.

    Here is the actual uploader:
    Code:
    <?php
    // ==============
    // Configuration
    // ==============
    error_reporting(0);
    $uploaddir = "path_to_location_hidden_just_because/".$_POST['year']; // Where you want the files to upload to - Important: Make sure this folders permissions is 0777!
    $allowed_ext = "mp3"; // These are the allowed extensions of the files that are uploaded
    $max_size = "21000000"; // 50000 is the same as 50kb
    $max_height = ""; // This is in pixels - Leave this field empty if you don't want to
    $max_width = ""; // This is in pixels - Leave this field empty if you don't want to upload images
    // Check Entension
    $extension = pathinfo($_FILES['file']['name']);
    $extension = $extension['extension'];
    $allowed_paths = explode(", ", $allowed_ext);
    for($i = 0; $i < count($allowed_paths); $i++) {
    	if ($allowed_paths[$i] == "$extension") {
    		$ok = "1";
    	}
    }
    
    // Check File Size
    if ($ok == "1") {
    	if($_FILES['file']['size'] > $max_size) {
    	print "<font color=\"red\">The sermon is too big! It can't be bigger than 20mb. Try making it smaller, <a href=\"#\" onclick=\"history.go(-1);return false;\">go back</a>, and upload it again.</font>";
    	exit;
    	}
    
    	// Check Height & Width
    	if ($max_width && $max_height) {
    		list($width, $height, $type, $w) = getimagesize($_FILES['file']['tmp_name']);
    		if($width > $max_width || $height > $max_height) {
    			print "File height and/or width are too big!";
    			exit;
    		}
    	}
    
    	// The Upload Part
    	if(is_uploaded_file($_FILES['file']['tmp_name'])) {
    		move_uploaded_file($_FILES['file']['tmp_name'],$uploaddir.'/'.$_POST['mm'].".".$_POST['dd'].".".$_POST['yy'].".mp3");
    	
    		print "<meta http-equiv=\"Refresh\" content=\"0; url=path_to_page_on_successful_upload?mm=".$_POST['mm']."&dd=".$_POST['dd']."&yy=".$_POST['yy']."\">";
    		
    	}
    	
    } else {
    	print "<font color=\"red\">You must select a file to upload and it must be an mp3 file (ends in '.mp3'). Fix this, <a href=\"#\" onclick=\"history.go(-1);return false;\">go back</a>, and try uploading again.</font>";
    }
    ?>
    Unfortunately I can't allow access to this page for security reasons so you can't really test it. Just hoping you can see the problem :). I removed a couple of file locations above...

    Thanks.
     
  2. Brendon Bauer
    Expand Collapse
    thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #3
    Interesting... Thanks for the response!

    I tried adding
    Code:
    <script type="text/javascript">
    /* A pretty little hack to make uploads not hang in Safari. Just call this
     * immediately before the upload is submitted. This does an Ajax call to
     * the server, which returns an empty document with the "Connection: close"
     * header, telling Safari to close the active connection. A hack, but
     * effective. */
    function closeKeepAlive() {
      if (/AppleWebKit|MSIE/.test(navigator.userAgent)) {
        new Ajax.Request("/ping/close", { asynchronous:false });
      }
    }
    </script>
    within the head section of the page with the form, and
    Code:
    onsubmit="closeKeepAlive();"
    to the form tag, making it
    Code:
    <form enctype="multipart/form-data" action="audio_sermon_2a.php" onsubmit="closeKeepAlive();" method="POST">
    This didn't seem to fix the problem though... It will still hang on about 50% of my attempts to upload a small file. Did I implement the "hack" or fix wrong? Or is that what they were implying on airbladesoftware website you gave as an example? As a note, I'm using Safari 4 beta, but I did uninstall the beta earlier to test the latest nonbeta version of Safari with the form (not with this hack applied, though) and it hung as well. I assume it shouldn't make much of a difference with the beta version? In other words I haven't tested this hack with nonbeta Safari, but I have tested the form w/out the hack with nonbeta Safari (which occasionally hung as well).

    Any idea what's up?
     
  3. Jay Francis
    Expand Collapse
    macrumors newbie

    Joined:
    Dec 1, 2009
    #4
    Brendon - were you able to fix the problem?

    I'm heading down the same path, and haven't worked it out yet.

    Thanks,
    Jay
     
  4. Brendon Bauer
    Expand Collapse
    thread starter macrumors 6502

    Joined:
    May 14, 2007
    Location:
    Good 'ol USofA
    #5
    Jay,

    I never did find a fix to the problem... so instead I put a warning note next to the uploader for those using safari. Sorry I couldn't help you!

    Brendon
     
  5. Jay Francis
    Expand Collapse
    macrumors newbie

    Joined:
    Dec 1, 2009
    #6
    Ok - thanks.

    I'll post if I eventually get something to work reliably... (ugh)

    --Jay
     
  6. Jay Francis
    Expand Collapse
    macrumors newbie

    Joined:
    Dec 1, 2009
    #7
    Got it to work.

    A couple of noob mistakes:

    1) Ajax.Request is found in prototype.js (Google it), and needs to be included.
    2) "/ping/close" needs to be an empty file accessible by the server. I'm using Django, so I put it in a directory along with other statically served files. My path isn't "/ping/close", so I needed to change it (e.g. "/media/close").

    Now when I watch the TCP packets between the browser and the server, I can see the connection close. Safari file uploads seem to be working properly (it's an intermittent problem, so I wouldn't put money on it yet...).

    Hope this helps,
    Jay
     
  7. alnaqba
    Expand Collapse
    macrumors newbie

    Joined:
    Jun 15, 2010
    #8
    Safari Hangs on PHP upload script

    I am having the same problem. I have a very simple php upload script but after one or two iterations of the upload, the page just sits there.
    If I click "submit" again it completes.
    This script works in Firefox without failure, haven't tested anything else.
    But I see there are more than one reports of this same behavior.
    If anyone solves it I'd like to know.

    Here's the whole script:
    Don't laugh, I'm just at testing stage when I noticed this bug with Safari.
    If it's my script, PLEASE let me know.

    Thank you

    <?php

    session_start();


    $target_path = "/var/www/uploads/";
    $target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

    if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    //echo "The file ". basename( $_FILES['uploadedfile']['name']). " has been uploaded";
    } else{
    // echo "There was an error uploading the file, please try again!";
    }


    $_SESSION['thefileweuploaded'] = basename( $_FILES['uploadedfile']['name'] );
    $_SESSION['project_description'] = $_POST['project_description'];
    $_SESSION['job_details'] = $_POST['job_details'];

    $duhname = $_SESSION['thefileweuploaded'];

    //echo "Updating your upload: Don't click anything until this message changes!";


    // redirect page to upload confirmation page
    if( $_SERVER['SERVER_ADDR'] == "::1" ) {
    $url = "http://localhost/index.html?page=upload/upload_confirmation.html&uploadedfile=$duhname";
    } else {
    $url = "http://" . $_SERVER['SERVER_ADDR'] . "/index.html?page=upload/upload_confirmation.html&uploadedfile=$duhname";
    }
    header("Location: $url");

    ?>
     

Share This Page