Wednesday, January 2, 2013

Using upload progress module in Nginx with Tornado

Previously I have set up a working upload conf.
I am following the official tutorial, http://wiki.nginx.org/HttpUploadProgressModule

1) Insert these into proper position in your Nginx.conf


upload_progress proxied 1m; #place under http{ ...}


track_uploads proxied 30s; #In my example, my upload button on the html template points to /upload (i.e. location /upload {...} , so I insert it in location /upload {...}


        location ^~ /progress {
            # report uploads tracked in the 'proxied' zone
            report_uploads proxied;
        } #Put this as a new location block


       #For see the effect of upload progress bar, I suggest u temporarily limit the upload rate by add upload_limit_rate 20000 in location /upload {...}



2) In your html template, just copy form the official doc


<form id="upload" enctype="multipart/form-data"
action="/upload.php" method="post" onsubmit="openProgressBar(); return true;">
  <input type="hidden" name="MAX_FILE_SIZE" value="30000000"  />
  <input name="userfile" type="file" label="fileupload" />
  <input type="submit" value="Send File" />
</form>

-- Change ...action="/upload.php"... to your destination


<div>
 <div id="progress" style="width: 400px; border: 1px solid black">
  <div id="progressbar" style="width: 1px; background-color: black; border: 1px solid white"> </div>
 </div>
 <div id="tp">(progress)</div>
</div>

-- Just copy it


 interval = null;

function openProgressBar() {
 /* generate random progress-id */
 uuid = "";
 for (i = 0; i < 32; i++) {
  uuid += Math.floor(Math.random() * 16).toString(16);
 }
 /* patch the form-action tag to include the progress-id */
 document.getElementById("upload").action="/upload.php?X-Progress-ID=" + uuid;

 /* call the progress-updater every 1000ms */
 interval = window.setInterval(
   function () {
     fetch(uuid);
   },
   1000
 );
}

function fetch(uuid) {
 req = new XMLHttpRequest();
 req.open("GET", "/progress", 1);
 req.setRequestHeader("X-Progress-ID", uuid);
 req.onreadystatechange = function () {
  if (req.readyState == 4) {
   if (req.status == 200) {
    /* poor-man JSON parser */
    var upload = eval(req.responseText);

    document.getElementById('tp').innerHTML = upload.state;

    /* change the width if the inner progress-bar */
    if (upload.state == 'done' || upload.state == 'uploading') {
     bar = document.getElementById('progressbar');
     w = 400 * upload.received / upload.size;
     bar.style.width = w + 'px';
    }
    /* we are done, stop the interval */
    if (upload.state == 'done') {
     window.clearTimeout(interval);
    }
   }
  }
 }
 req.send(null);
}

-- Copy the above too and you are done.