I recently added progress bars (actually, a percentage instead of a bar, but it was the same to implement) to 
Ringlight uploads and downloads. I was suprised to find that the available server-side libraries for dealing with file uploads seemed to be inadequate for adding this functionality to my website.
The basic technique for adding progress bars is relatively simple. With jQuery:
- Install the Ajax File Upload extension.
 - Install the periodic execution extension.
 - Register some Ajax event callbacks to reveal the progress bar on the page when the upload starts and also to catch errors.
 - Call the $.ajaxFileUpload function with the URL of the upload handler script, the id of the file input element, and the callback function to handle output from the upload handler.
 - Have the upload handler return a Json object with an id for the upload.
 - Call your progress bar update function with the periodic execution model: $.periodic(updateProgressBar);
 - The updateProgressBar function should fetch the download status from a server-side script, supplying the upload id and a callback function: $.getJSON("fetchProgress", {id: id}, function(data) {/* update progress bar with data.percentDownloaded*/});
 - The fetchProgress script should return upload progress information in a Json object. I return percentDownloaded, but you can include anything you'd like, such as upload rate. You should also provide error information here, such as if the upload failed.
 - The callback function for fetchProgress should update the page to reflect updated progress. For instance, updating a percentage to completion could be as simple as $("#percent").empty().append(data.percentDownloaded);
 
This was all very simple to implement and jQuery made it possible in very few lines of code. The difficulty was in providing a percentDownloaded value. The difficulty comes from the fact that it is common for browsers to not include the Content-Length field for uploaded files. The file upload handling libraries generally solve this problem by either 1) not providing a content length or 2) loading the whole file into memory (or disk, in some cases) and then finding the length of it. Either way, not very useful for a progress bar! This total failure to handle streaming files is a 
common problem in libraries and if you could avoid it in the libraries you implement then the world would be most appreciative.
In the meantime, there are a number of action items that require your attention. First, calculate the file length by taking the HTTP request Content-Length field and subtracting the size of everything which is not the file in order to yield the file length. I did this with the following shoddy algorithm:
- Extract the MIME boundary from the Content-Disposition field.
 - Subtract the size of the MIME boundary twice (there is a boundary on both sides of the file).
 - Subtract 2 because the second boundary has a trailing "--".
 - Subtract 4 because each boundary has a trailing two-character newline (\r\n).
 - Subtract 8 because my numbers were always off by exactly 8. I'm not sure where this additional 8 is coming from.
 
As I said, this algorithm is shoddy, a kludge not fit for use in production. However, it works for now! It needs extensive testing and tweaking on a variety of browsers. The next steps:
- Improve algorithm so that it's robust enough to work with most browsers
 - Submit a patch to python's FieldStorage class to support this algorithm
 - Submit a bug report to Mozilla requesting that they supply content length in file uploads
 
For now, my upload progress bars are working, so I'm happy.