Search code examples
phpcmongoose-web-serverblackfin

How can you make a cesanta mongoose embedded web server dynamic?


void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{

    char ip[32], subnet[32], gw[32];

    if (ev == MG_EV_HTTP_MSG)
    {
        ip = get_ip();
        subnet = get_subnet();
        gw = get_gateway();
        
        struct mh_http_message *hm = (struct mg_http_message *) ev_data;
        
        if (mg_http_match_uri(hm, "/device/info"))
        {
            
            mg_http_reply(c, 200, "Content-Type: text/html\r\n", ""

            "<!DOCTYPE html>"
            "<html>"
            "<head>"
            "</head>"
            "<body>"

            "<h2>IP address: %s</h2>"
            "<h2>Netmask: %s</h2>"
            "<h2>Gateway: %s</h2>"

            "</body>"
            "</html> "

            "", ip, subnet, gw);
        }
    }
}

int main()
{
    struct mg_mgr mgr;
    mg_mgr_init(&mgr);
    mg_http_listen(&mgr, "http://10.0.0.6:8000", fn, &mgr);
    for (;;) mg_mgr_poll(&mgr, 1000);
}

I am developing an embedded web server using mongoose. Currently I am using mg_http_reply() for sending the entire HTML page as a string. Is there any better way of doing this, something like directly giving variable name inside HTML code itself (dynamic)?

I have read about two things:

  1. using ssi, can't get variable (ip,subnet, gw) from main function to HTML.

  2. use scripting language like PHP, but i think my DSP (adsp bf518) might not support it.


Solution

  • Mongoose author is here.

    The right way to do things is to split a server into 2 parts:

    1. Static part, that serves static pages like HTML, CSS, images, etc
    2. A dynamic part that servers RESTful API requests

    Browser downloads static UI, which in return starts to call REST API. This snippet demonstrates the idea:

    static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
      if (ev == MG_EV_HTTP_MSG) {
        struct mg_http_message *hm = (struct mg_http_message *) ev_data;
        if (mg_http_match_uri(hm, "/api/hello")) {              // On /api/hello requests,
          mg_http_reply(c, 200, "", "{%m:%d}\n",
                        MG_ESC("status"), 1);                   // Send dynamic JSON response
        } else {                                                // For all other URIs,
          struct mg_http_serve_opts opts = {.root_dir = "."};   // Serve files
          mg_http_serve_dir(c, hm, &opts);                      // From root_dir
        }
      }
    }
    

    There are plenty of examples available. I suggest reading the whole WebUI section: https://mongoose.ws/documentation/#web-ui

    The "device dashboard" example is the one you should be using as a reference: https://github.com/cesanta/mongoose/tree/master/examples/device-dashboard