#include "SkylarkUpload.h" int ProgressHandler(int reason, Http &http, int size) { // get the upload unique identifier String id = http["uploadid"]; String currentId = "." + id + ".currentSize"; String totalId = "." + id + ".totalSize"; // must be reentrant INTERLOCKED { switch(reason) { // got headers ? case PROGRESS_HEADER: { http .SessionSet(currentId, 0) .SessionSet(totalId, size) ; break; } // reading contents ? case PROGRESS_CONTENT: { int oldPercent = http[currentId]; int total = http[totalId]; // take care to NOT return 100% up to upload ended really int percent = min(99, (int)(100.0 * size / total)); // avoid unnnedded session storing if(oldPercent != percent) http.SessionSet(currentId, percent); break; } // finished reading contents ? case PROGRESS_END: { // signals end by resetting total size http.SessionSet(totalId, 0); break; } // default, used by query handler default: // PROGRESS_QUERY { // check if key is there --> upload started int total = http[totalId]; if(!IsNull(total)) { if(total) // if upload not ended, return the progress % return http[currentId]; else { // upload ended, nullify session variables and return 100% http .SessionSet(currentId, Null) .SessionSet(totalId, Null) ; return 100; } } else // upload still not started, return 0 progress return 0; } } } return true; } SKYLARK(Home, "home") { // we need a session variable for upload id if(http["@__skylark_session_cookie__"].IsNull()) http.NewSessionId(); // show rootpath in html page http("UploadFolder", Upload().GetRootPath()); http.RenderResult("SkylarkUpload/SkylarkUpload"); } SKYLARK(Default, "**") { http.Redirect(Home); } SKYLARK_PROGRESS(PostUpload, "upload:POST", &ProgressHandler) { String fileName = AppendFileName(Upload().GetRootPath(), (String)http["filename"]); Value const &contents = http["filestoupload[]"]; Value const &filenames = http["filestoupload.filename[]"]; if(contents.IsNull() || filenames.IsNull()) return; for(int i = 0; i < contents.GetCount(); i++) SaveFile(AppendFileName(Upload().GetRootPath(), (String)filenames[i]), contents[i]); } SKYLARK(Progress,"progress") { int p = ProgressHandler(PROGRESS_QUERY, http, 0); http.Content("text/plain", Format("%d", p)); http.Response(200, "OK"); }