[Solved] File upload using QFileControl sometimes hangs when using Safari
I'm building a site for a client which involves uploading images, and I'm running into some strange behavior. *Sometimes* (and I'm trying to narrow in on it more), the file upload seems to just hang. Safari shows that the page is loading, but it never completes, and it never shows that a file was uploaded.
A few more details: I'm using the QImageFileAsset control on a form. Click upload to bring up the dialog. Choose a file, and click the upload button. For smaller images (< 1MB) it seems to work just fine. But larger ones (> 2MB) seem to often fail, where they just don't ever return from the uploading form post.
I started hacking into the QFileControl ... and I found that when it hangs, the QFileControl actually never returns back to dlgFileAsset_Upload. I traced where the temp PHP file uploads were going ... and I never see a temp file get created. Uploading the exact same file with Firefox through the exact same procedure ... it works just fine.
When I try that same image on the example form for the QImageFileAsset using Safari, it does return back to the dialog ... but says the image type is invalid. I guess this may not be a problem with QCubed, since it appears to be the basic PHP form upload that is failing. Still ... wondered if anyone has run into this ... or has any suggestions on PHP settings to adjust. This happens both on my local Linux dev environment, and on the hosted server that will host production.

I've never had a hang. On a timeout (such as due to too large a file), the page will reload as if no file were uploaded, but that's the only odd behavior I've seen.
Ya, I know ... it's strange and annoyed.
More info ... I created a simple PHP upload form, and the same images upload just fine there ... no timeout or anything. There does seem to be something in the framework that is causing this issue.
If it works on the example page, then the framework is clearly working correctly. There must be something in your code, though nothing should cause a PHP hang..
True ... good point, except that I wouldn't exactly say that it's working. It doesn't hang ... but also doesn't upload the image.
Don't get me wrong ... I'm not blaming the framework for the problem. I just came here asking for help in where I might look to figure out why my specific implementation of things is having this issue. I appreciate any assistance you or anyone else can lend me.
I'm already committed to this framework, and frankly I think it's very well constructed. I like the site that I've built by using it ... so I need to get this upload issue worked out. I know I have to cap the filesize upload anyways due to server constraints ... but the issue here is that my script never even starts to execute to check the uploaded file size, because the upload part hangs.
Some more info ... the example upload I referred to above was the examples on the qcu.be website. There, when I upload a ~2MB image, it worked ... and my ~2.5MB image just returns back to the dialog indicating that I need to upload JPG, PNG, GIF.
The examples on my local install do not work, and in fact exhibit the same locked behavior as my usage of the control within my site, with both of the images that I used above.
check your PHP upload limits (upload_max_filesize). On the examples server here it is set to: upload_max_filesize = 2M
Well, that explains the behavior of my ~2.5+MB image on your example server.
But I'm fairly convinced there is something with the config of PHP on my server. A brand new install of QCubed 1.1.1 on my server, goto examples, try to upload that 2.5MB image using Safari ... and it just hangs.
PHP 5.2.10
upload_max_filesize = 32M
post_max_size = 32M
max_execution_time = 240
What else can I look at in config? But remember, a very simple single-form PHP file (not using QCubed) will complete a basic file upload for my ~2.5MB file. This is very perplexing.
Let's see if we can narrow down the problem:
1)is this specific to Safari? Can you repro this using Firefox?
2) 5.2.10 isn't the lastest release in the 5.2 PHP branch, try upgrading
Alex - I agree completely ... I am very familiar with software debugging, and have been trying to narrow in on the problem myself. Thanks for your response, and I greatly appreciate any insight or assistance you can give.
To answer your questions specifically:
1) Yes, seems to just be Safari. Uploads of the exact same file through Firefox & Google Chrome both work just fine. I ran the exact same steps on all 3 browsers, starting each one up fresh, using the stock QCubed 1.1.1 examples installed on my PHP server. Safari is the only one where the upload "hangs"
2) True, looks like 5.2.13 is the latest 5.2 revision. My local dev instance is running on a NAS device with PHP "built in". While I can install another instance of PHP to get the latest 5.2.13, my bigger concern is that production for this site I'm developing is running on a hosted server, which is reporting PHP 5.2.11. I don't believe I have any control over this.
PHP revision is an interesting thought though ... because so far, Safari seems to be able to complete all uploads to the example server, but only small files to my local server.
Once again, my testing has shown that consistently, trying to upload a file that's 2.1 MB and 2.5MB both fail to complete the upload on the "Upload Control Just for Images" example on my local install ... they just appear to "hang", where the browser never seems to complete the form post, and the dialog box is never hidden nor refreshed with an error. But on the hosted examples.qcu.be, the 2.1MB image actually completes, and the 2.5MB image finishes the form post, but I think the image size is too large, so the dialog reports that I didn't upload the correct file type. But they do complete, and do not hang. This would seem to indicate that there is something different in my installation, or server config (or server version).
The install is the examples straight from the zip of QCubed 1.1.1. Although, now that I look closely, the example site on example.qcu.be says it's QCubed 1.1.2? I don't see a downloadable release for that?
The server config on my local seems set correctly to allow the uploads, because other browsers work, so I doubt it's a file size or upload limit. Also, a simple PHP form upload of the 2.5MB file using Safari completes ... so again, not sure it's server config.
Server PHP Version could make a difference. I wonder, what version of PHP is running on example.qcu.be?
I'm running out of time on this. I thought it was working, because even though I developed using Safari, I had only uploaded <1MB images during dev/testing ... and those work. If I can't get this figured out by tomorrow, I'm thinking I'll have to ditch the QImageFileAsset class, and do file uploads directly from the main form. Since a simple PHP form upload works, and one using the QImageFileAsset control does not (again, given 2.5MB file using Safari and my server) ... I'm thinking it has something to do with the additional DIV's and such that make up the "dialog" box where the form upload control exists?
OK, so it seems that we have identified that the combination of Safari + something about your server config are causing the issue.
I've googled "safari file upload hangs", and I'm seeing a non-trivial number of pages on the issue... Might be worth investigating.
Totally random note: you're using QServerAction for the button that's submitting the form that has file uploads, right? QAjaxAction doesn't work for it.
On your question about what's running on http://examples.qcu.be: it's the latest bits from the 1.1 branch of the SVN; there's no released 1.1.2 yet. It's a work in progress, and I don't believe there were any patched in the 1.1.2 that affect file upload.
Version of PHP on http://examples.qcu.be: it's actually running pretty ancient bits, PHP 5.2.0-8+etch16.
OK, still a bit perplexing ... but I'm making progress!
First, yes I am using the QServerAction, I know how the file upload works ... requiring a form post and all, plus I've been testing on the unchanged examples pages. Always good to check the basics though.
Second, I feel kinda sheepish for not "Googling" it in the first place. I guess I was thrown by the fact that my "simple form" seemingly worked ... plus the hosted example page always seemed to work. Turns out these may have been coincidental, because the problem is apparently intermittent, although it happens much more consistently when I try large images uploaded through the QCubed framework.
So, through several different posts from my Google search, I began to piece together that Safari (or some say other WebKit-based browsers) have intermittent problems hanging while uploading files. The issue seems sporadic as far as file sizes and timing ... but as this post from Mar 2009 () still indicates that it's still a problem.
So, I implemented a variation of the solution that I'd seen posted with many of these threads. It basically requires making an additional synchronous AJAX call to a script that terminates the keep-alive connection to the server, before then form posting back to the server. It seems crazy ... but I think it's actually working!
I am still a bit confused why the upload seems to work for me on examples.qcu.be. Could be that I just didn't hit one of the times it would hang (I didn't test rigorously), or could be something in the PHP config, or even the version itself that is causing this (such as the server disabling http keep-alives?). I'm also amazed that I'm the only one who's ever run into this? I didn't see any other posts on this forum about issues with file upload hangs. I can't be the only one who uses QCubed and Safari!
I'm going to do a bit more testing ... but if it works out, I'd like to submit my findings for possible inclusion into the next release. The fix is a bit "hacky", but isolates itself to AppleWebKit browsers.
Thanks to Alex for reminding me that Google searches are invaluable at times!
I located a few threads that were having similar file upload hang issues with Safari and PHP, not having anything specifically to do with QCubed. I implemented a variation of the solutions I found, and after several file uploads of different sizes, I haven't had Safari hang yet.
The solution involves adding a synchronous AJAX call to a file that terminates any http-keepalive connection. Then, the form does it's normal post back with the file upload data. Most examples I saw used prototype to do the sync AJAX call, but I rewrote it to use JQuery, since that's already available in QCubed.
I can provide more details if anyone is curious about the exact implementation. But I would like to suggest that some version of what I've done be included in the QCubed framework. I can't be the only one who has run into this issue? At the very least, we could make it some sort of optional parameter to set that triggers QCubed to add the additional AJAX call to the btnUpload handler. The subsequent JavaScript call checks and only does the sync AJAX for Apple WebKit browsers.
Thoughts/comments? How do I formally submit my suggestions for this enhancement?
The first step in getting a change in QCubed is to create a ticket. :) After that, if you have code to getting it working, you can supply it, or ideally, create a patch based off of the version of QCubed currently in SVN. We'll take a look at it, and if everything looks good, we'll commit it to core. :)
Cool. Sounds good. I've got a couple of things going on ... but I'd like to do this. Hopefully I can get to it in the next few days.
Question: there are a few different ways we could wrap this up into a core change (with additional properties, and file locations or approaches for some new JavaScript to add). I'll gladly create & submit a patch, but I'd like to get some feedback on the "best" place for some of the code. How do we facilitate that sort of discussion?
Thanks for asking. :) Generally that stuff can be discussed in the ticket itself. You can ask for implementation preferences, suggested approaches and feedback at any point in the processes, so you aren't left building a patch that doesn't end up meeting our needs / coding standards / etc. :)
We always appreciate any effort towards making the framework better, so don't feel intimidated or afraid to speak your mind. :)
Yup! Please create a Trac ticket, and we'll discuss there. Thanks again for being patient and for your desire to improve the framework!