slachiewicz / mongoose

Automatically exported from code.google.com/p/mongoose
MIT License
0 stars 0 forks source link

I cannot get mongoose to process a GET from the client when requesting a JSON file. #407

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago

I have the following javascript that does a GET on a CGI called 
"GeneralInfoParams" that returns JSON formatted data:

var jqxhr = $.getJSON( "/usr/www/cgi-bin/GeneralInfoParams", function() {
            console.log( "success getting parameters from server" );    
})

I am using the example code from server.c to run mongoose. I am attaching my 
config file.

I expected the call to be successful. I have validated my JSON output from the 
script file on another server.
The call fails.

What version of the product are you using? On what operating system?
I am running the current version v.5.4 server on QNX 6.5.0

Do I need to 

Original issue reported on code.google.com by NoahZeld...@gmail.com on 22 Apr 2014 at 3:37

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry. Do I need to add an event handler to handle GET requests? I see in the 
code where SSI #exec's are handled and that works fine, calling a popen to 
spawn the executive. I do not see a place in the code to spawn the cgi I am 
requesting in the GET.

Original comment by NoahZeld...@gmail.com on 22 Apr 2014 at 3:40

GoogleCodeExporter commented 9 years ago
I am having great difficulty getting either a XMLhttpRequest or a jquery 
$.getJSON to work with Mongoose. I was able to get this code to work on 
slinger, with a slight url change to match that servers requirements. I know 
that my JSON data returns correct from the CGI GeneralInfoParams.

I have some javascript to make a get request to the server:

$.ajaxSetup({ cache: false });      
var jqxhr = $.getJSON( "/GeneralInfoParams", function() {
    console.log( "success getting parameters from server" );    
})

.done(function(data) 
{
    document.getElementById('RRName').innerHTML = data.rrname;
    document.getElementById('LocoNum').innerHTML = data.loconum;
    document.getElementById('ModelNum').innerHTML = data.modelnum;
    document.getElementById('SerialNum').innerHTML = data.serialnum;
    document.getElementById('CHMSerialNum').innerHTML = data.chmserialnum;
    document.getElementById('SSDSerialNum').innerHTML = data.ssdserialnum;
    document.getElementById('SWVerDate').innerHTML = data.swverdate;
document.getElementById('ConfigVerDate').innerHTML = data.configverdate;      

})

.fail(function() {  
console.log( "error getting parameter data from server" );
})  
$.ajaxSetup({ cache: true });

Notice I set the URL to "/GeneralInfoParams". I did this because when I try to 
pass in the full path of “/usr/www/cgi-bin/ GeneralInfoParams”, the 
ev_handler I set up below will not have the full path in the conn->uri for some 
reason. The only thing that makes the event handler work is when I pass in a 
single path like "/GeneralInfoParams". This seems to be the case also in your 
form.c example where your javascript passes a URL of "/get_value" which is 
caught in your handler example.

So in the event handler below, I call a function called do_cgi_exec to return 
the json. I found out that if in my CGI I printed the “Content-Type: 
application/json”, that the code would never work. I stripped this out and 
just had my CGI print the JSON data.
This got the $.getJSON to work on Mongoose, however, the time it took for 
$.getJSON to do a callback to the .done function was like 45 seconds. Way too 
slow. So I did a test where I just printed some simple json directly from the 
event handler:
mg_printf_data(conn, "{\"value\": 43}");
This made the response time fast.

//Event handler for CGI calls from client Javascript for JSON data
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
    if (ev == MG_REQUEST)
    {
        if (strcmp(conn->uri, "/GeneralInfoParams") == 0)
        {
            do_cgi_exec(conn, (char *)conn->uri);
            //mg_printf_data(conn, "{\"value\": 43}");
        }
        else if (strcmp(conn->uri, "/set_value") == 0)
        {
            return MG_FALSE;
        }
        else
        {
          // Better way is to set "document_root" option, put "index.html" file
          // into document_root and return MG_FALSE here. We're printing HTML
          // page by hands just to keep everything in one C file.
            //print_params(conn);
            return MG_FALSE;
        }
        return MG_TRUE;
    }
    else if (ev == MG_AUTH)
    {
        return MG_TRUE;
    }
    return MG_FALSE;
}

Calling do_cgi_exec() which does a popen to execute the CGI, seems to execute 
quickly when I single step through the code. But the time it takes for the a 
getJSON to return a callback is really long.

Notice I added the full path "/usr/www/cgi-bin “ back onto the url in this 
function. This is not ideal at all. I only did this to get around the problem I 
had with the full path.

static void do_cgi_exec(struct mg_connection *conn, char *tag) {
  char cmd[IOBUF_SIZE];
  FILE *fp;

  char lCommand[100];
  sprintf (lCommand, "/usr/www/cgi-bin%s", tag);
  if ((fp = popen(lCommand, "r")) == NULL)
  {
    mg_printf(conn, "Cannot exec cgi: [%s]: %s", tag, strerror(errno));
  }
  else
  {
      int n;

      while ((n = fread(cmd, 1, sizeof(cmd), fp)) > 0) {
        mg_write(conn, cmd, n);
    }
    pclose(fp);
  }
}

What I really want is the mongoose.c code to natively be able to handle what I 
am trying to do, or an example code that does this. I want to be able to do a 
getJSON call from Javascript with a URL to an executable that returns dynamic 
JSON data to be used for populating my web page html.

Can you please help me out with this?

Original comment by NoahZeld...@gmail.com on 22 Apr 2014 at 7:29

GoogleCodeExporter commented 9 years ago
Don't use mg_write or mg_printf.
Use mg_send_data() or mg_printf_data.

Original comment by valenok on 27 Jul 2014 at 1:43