views:

268

answers:

3

Anyone who has developed file upload progress bar with following:

Ajax Javascript HTML C based CGI

I am stuck at one point. I am not able to read each updated progress bar value from CGI script.

/*****************CLIENT SIDE CODE*************************/

var intervalID;
var percentage;
var request;
var tempvar=0;
var progress;


function polling_start() {   // This is called when user hits FILEULOAD button
        //alert ("polling_start");
        intervalID = window.setInterval(send_request,1000);
}

window.onload = function (){
        request  = initXMLHttpClient();
        progress = document.getElementById('progress');
}

function initXMLHttpClient() {
        //alert("send_request");
        if (window.XMLHttpRequest){
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
        }
        else{
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
return xmlhttp
}

function send_request()
{
request.onreadystatechange = request_handler;
request.open("GET","progress_bar.txt",true);
request.send(null);
}

function request_handler()
{
        if (request.readyState == 4 && request.status == 200)
        {
        document.getElementById("progress").innerHTML= request.responseText + '%';
        document.getElementById("progress").style.width = request.responseText + '%';
        document.getElementById("progress").style.backgroundColor = "green";
        }
}

/***********************SERVER SIDE CODE*****************************/

    cgiFormFileSize("UPDATEFILE", &size);   //UPDATEFILE = file being uploaded
    cgiFormFileName("UPDATEFILE", file_name, 1024);
    cgiFormFileContentType("UPDATEFILE", mime_type, 1024);
    buffer = malloc(sizeof(char) * size);

        if (cgiFormFileOpen("UPDATEFILE", &file) != cgiFormSuccess) {
        exit(1);
    }
    output = fopen("/tmp/cgi.tar.gz", "w+");

    printf("The size of file is: %d bytes", size);
    inc = size/(1024*100);

        while (cgiFormFileRead(file, b, sizeof(b), &got_count) == cgiFormSuccess)
        {
        fwrite(b,sizeof(char),got_count,output);
        i++;
                if(i == inc && j<=100)
                {
                fptr = fopen("progress_bar.txt", "w");
                fprintf(fptr, "%d" ,j);
                fseek(fptr, 0, SEEK_SET);
                i = 0;
                fflush(fptr);
                fclose(fptr);
                j++;   // j is the progress bar increment value
                }
        }

    fclose(output);
    cgiFormFileClose(file);
    retval = system("mkdir /tmp/update-tmp;\
                     cd /tmp/update-tmp;\
                     tar -xzf ../cgi.tar.gz;\
                     bash -c /tmp/update-tmp/update.sh");
}


/********************************************************************/

So,Ajax is not able to read each incremented value of "j". Therefore the progress bar starts as soon as the CGI stops writing to the text file. However, Ajax is able to display values from 1 to 100 (If I put sleep(1); the progress bar could be seen incremented at each second) ; but not at appropriate time.

A: 

I don't believe it's possible to implement a progress bar with only html/javascript on the client side, you need flash to do this.

The YUI Uploader can help you with this.

camomileCase
I have very limited memory on system therefore can not use anything else except for the above said technologies.I am using Ajax at server end to read the data from a CGI script.However, it is not happening the way I want.if (request.readyState == 4 document.getElementById("progress").style.width = request.responseText + '%'; document.getElementById("progress").style.backgroundColor = "green";}It reads frm a text file updated at CGI script
Punit
So, it reads the text file but couldn't read the updated values each time instead reads the text file only once CGI has stopped writting to it , thats why it doesnt go inside request.readyState == 4
Punit
@Punit: Please update your question with this information, this doesn't belong in a comment (on an answer). And I think you need to show the server side code, too.
Marcel Korpel
It's certainly possible with only HTML/JS on the client side. You only have to maintain a session on the server side.
BalusC
my client side handling is working fine, but my server side is not letting Ajax to read updated value each time.
Punit
A: 

Have a look at AJAX progress bar to see how this can be implemented in JavaScript. You only have to write the C code yourself (the part that serves the XML containing the progress percentage; of course you could also use JSON to send this data).

Update: What happens when you increase the interval to e.g. 10000? At the moment every second the XMLHTTPRequest connection is reset by calling request.open in send_request.

Marcel Korpel
Yes, that is what I followed, but the Ajax is not able to read the updated value each time. Instead it starts reading once the whole data is written at the server side.
Punit
@Punit: Are the contents of the text file not updated? Or is it not reread by the JS part? In the latter case, it could be a caching problem. Do you send a Last-Modified header with a date set in the past? See [Caching in HTTP](http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html).
Marcel Korpel
contents are updated. For example in the above code if I put sleep(1); then after the file update the progress bar starts and keeps incrementing after one second. But this is not what I want because it should increment at when file upload is taking place NOT when its done.
Punit
To add here, I saw that Ajax is working file it waits until request.readyState == 4, but this gets true only after file upload is completed.
Punit
@Punit: what do you see when you put `console.log(request.readyState + ", " + request.status);` inside `request_handler` (outside the `if`)?
Marcel Korpel
If I increase the interval to e.g. 10000 then also same thing happens. As 1000ms = 1 sec. If I increase the value, polling delays and so does Ajax to read text file delays.
Punit
I used alert(request.readyState + ", " + request.status); and it shows: 2,220 if the file is not deleted (I delete the file manually right now) So, if file is not deleted then it is available to Ajax even before CGI starts. 2,404 when CGI creates the file (and is deleted manually onc upload is completed )
Punit
what seems to me is that there is an issue at server side. As it doesnt let Ajax to read data
Punit
@Punit: using alerts in this case might mess up the results. It's better to use the console to output data. But as you suspect this being a problem on your server and as I don't have access to it (nor to a test page), I think I am stuck...
Marcel Korpel
is it possible that text file is not a good choice in this case. If I use xml? But I do not know how to do that in C.
Punit
@Punit: This shouldn't matter. You're able to read whatever text file using XMLHTTPRequests.
Marcel Korpel
So it could be OS (i am using Linux) issue, that you can not read a file while its being getting updated
Punit
Yes, that's possible (I'm using Linux, too, but I doubt that the situation in Windows servers will be better). But *when* are you updating this file (running this server code). Moreover, why are you doing this using a file in the first place? You can just get the current file size on-the-fly, when it is actually needed by the client. E.g., I can use a script that just sends the current file size/percentage back to the client.
Marcel Korpel
"can use a script that just sends the current file size/percentage back to the client"I can get the file size, however how would I know that how much data has been got copied?When the user hits upload button, then a CGI is called where data copy takes place; after certain number of data copy I increment the value for progress bar, which gets stored in a text file every time it is changed.
Punit
A: 

@Marcel: yes I can get the size of the file, but then it would be difficult to say after how many bytes the progress bar will get updated. Any idea?

Punit