Index: django/contrib/admin/media/js/UploadProgress.js
===================================================================
--- django/contrib/admin/media/js/UploadProgress.js	(revision 0)
+++ django/contrib/admin/media/js/UploadProgress.js	(revision 0)
@@ -0,0 +1,102 @@
+function getxy(){
+    var x,y;
+    if (self.innerHeight) // all except Explorer
+        {
+        x = self.innerWidth;
+        y = self.innerHeight;
+        }
+    else if (document.documentElement && document.documentElement.clientHeight)
+        // Explorer 6 Strict Mode
+        {
+        x = document.documentElement.clientWidth;
+        y = document.documentElement.clientHeight;
+        }
+    else if (document.body) // other Explorers
+        {
+        x = document.body.clientWidth;
+        y = document.body.clientHeight;
+        }
+    return {'x':x,'y':y}
+    }
+
+var humanvalue = ['B','KB','MB','GB']
+function humanize(bytes) {
+    curbytes = bytes
+    iterations = 0
+    while (curbytes>1024) {
+        iterations++
+        curbytes=curbytes/1024
+        }
+    return curbytes.toFixed(1) + ' ' + humanvalue[iterations]
+    }
+
+interval = null;
+function fetch(uuid) {
+    req = xmlhttp
+    req.open("GET", "/upload_progress/", 1);
+    req.setRequestHeader("X-Progress-Id", uuid);
+    req.onreadystatechange = function () {
+    if (req.readyState == 4) {
+        if (req.status == 200) {
+
+            var upload = eval( '(' + req.responseText + ')' );
+
+            if (upload.state == 'done' || upload.state == 'uploading') {
+                bar = document.getElementById('progress_bar');
+                bar_txt = document.getElementById('progress_text')
+                bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) + '% - ' +
+                    humanize(upload.received) + ' of ' + humanize(upload.size) 
+                w = 400 * upload.received / upload.size;
+                bar.style.width = w + 'px';
+
+                }
+                if (upload.state == 'done') {
+                    window.clearTimeout(interval);
+                    }
+                }
+            }
+        }
+    req.send(null); 
+
+    }
+
+function openprogress(e) {
+
+    uuid = "";
+    for (i = 0; i < 32; i++) {
+        uuid += Math.floor(Math.random() * 16).toString(16);
+        }
+    frm = e.target||e.srcElement
+
+    frm.action=frm.action+"?" + uuid; 
+
+    pos = getxy()
+    posx = parseInt((pos.x/2)-(420/2), 10)
+    posy = parseInt((pos.y/2)-(50/2), 10)
+
+    progress_wrap = quickElement('div', document.body, '', 'style', 
+        'position: absolute; top: '+posy+'px; left: '+posx+'px; height: 50px; ' +
+        'padding: 10px; width: 420px; background: #ffffff; ' +
+        'border: solid 1px #dddddd;', 'id', 'progress_wrap')
+
+    progress_label = quickElement('h1', progress_wrap, 'Upload progress')
+
+    progress = quickElement('div', progress_wrap, '', 'style', 
+        'top: 0; left: 0; width: 0px; ', 'id', 'progress_bar', 'class', 'submit-row')
+
+    progress_text = quickElement('div', progress_wrap, '0%', 'style',
+        'color: #000000; ', 'id', 'progress_text')
+ 
+    interval = window.setInterval(
+        function () {
+            fetch(uuid);
+            },
+        1000
+        );
+    }
+
+addEvent(window, 'load', function() {
+        frm = document.getElementsByTagName('form')[0]
+        addEvent(frm, 'submit',  openprogress)    
+        }
+    )
Index: django/middleware/upload.py
===================================================================
--- django/middleware/upload.py	(revision 0)
+++ django/middleware/upload.py	(revision 0)
@@ -0,0 +1,22 @@
+"streaming upload middleware"
+from django.conf import settings
+from django.utils import simplejson
+from django.http import HttpResponse
+
+class UploadStateMiddleware(object):
+
+    def process_request(self, request):
+        progress_url = getattr(settings, 'PROGRESS_URL', '/upload_progress/')
+
+        if request.path == progress_url:
+            progress_id = request.META['UPLOAD_PROGRESS_ID']
+
+            try:
+                content = simplejson.dumps(request.file_progress)
+            except:
+                content="{}"
+            if not content:
+                content="{}"
+
+
+            return HttpResponse(content=content, mimetype='text/plain')
