[Libwebsockets] Newbie Questions

Andy Green andy at warmcat.com
Tue Nov 21 06:18:22 CET 2017



On 11/21/2017 12:55 PM, Chad Cravens wrote:
> Hello Andy:
> 
> thank you for your response! Please find some additional questions below 
> in blue:
> 
> On Mon, Nov 20, 2017 at 11:14 PM, Andy Green <andy at warmcat.com 
> <mailto:andy at warmcat.com>> wrote:
> 
> 
> 
>     On 11/21/2017 11:49 AM, Chad Cravens wrote:
> 
>         Hello!
> 
>         First, thanks to warmcat for his hard work and a great open
>         source library for us all to use! I'm a newbie to libwebsockets.
>         I've been working with the test-apps for a few days now, and I
>         feel like I have a decent grasp of what's going on but I still
>         have so many questions I'm going to take it one at a time until
>         I can get a good grasp on the library :)
> 
>         My first question is regarding HTTP. I have copied the
>         test-server-v2.0.c source code into my project, and stripped it
>         down to what I believe is the bare minimum. I have a mount:
> 
>         *static const struct lws_http_mount mount = {
>               NULL,    /* linked-list pointer to next*/
>               "/",        /* mountpoint in URL namespace on this vhost */*
> 
>         and vhost options struct
> 
>         *static const struct lws_protocol_vhost_options pvo = {
>               NULL,
>               NULL, // &pvo_opt,
>               "dumb-increment-protocol",
>               ""
>         };*
> 
>         I also have a plugin_dirs array:
> 
>         *static const char * const plugin_dirs[] = {
>                   "/Users/user/myproject/plugins",
>                   NULL
>         };*
> 
>         I then have a main() function where I
>         1) set option parameters in a *struct lws_context_creation_info
>         info*
>         2) create the context with *lws_create_context(&info)*
>         3) create a vhost with *lws_create_vhost(context, &info)*
>         4) configure the event loop *lws_uv_sigint_cfg(context, 1,
>         signal_cb)*
>         5) run the event loop *lws_libuv_run*
> 
>         When I run the server, I can successfully load the web page in a
>         browser and connect a websocket client (hooray! \o/). But now....?
> 
> 
>     That sounds like a good start.
> 
>         What I would like to do first is handle any HTTP requests other
>         than / with the server itself (not a directory mount).
>         Essentially I want to build a RESTful service handler for
>         /api/v1/etc, but they all result in 404. I've tried implementing
>         several of the plugins. It does seem that the plugin is
>         discovered by libwebsockets, as I see this debug log message:
> 
>         *[2017/11/20 22:25:17:8362] NOTICE: Plugins:
>         [2017/11/20 22:25:17:8362] NOTICE: Scanning
>         /Users/user/myproject/plugins
>         [2017/11/20 22:25:17:8364] NOTICE: protocol_dumb_increment.cpp
>         [2017/11/20 22:25:17:8370] NOTICE: Creating Vhost 'default' port
>         8080, 1 protocols, IPv6 off
>         [2017/11/20 22:25:17:8370] NOTICE: mounting
>         file:///Users/user/myproject/web/dist to /*
> 
>         I have put printf() messages in this plugin file, but nothing is
>         getting invoked. I have looked for samples on how to statically
>         include this plugin, but maybe I'm not doing it right?
> 
>         Maybe I just need some guidance, sample app or a link to some
>         documentation to get me moving in the right direction on how I
>         can handle HTTP requests properly and include a static plugin.
> 
> 
>     1) If you just want to mount and serve local directories, as you
>     found that is simple to bind parts of the URL space to internal
>     support for serving files from a local directory there.
> 
>     You can also bind protocol names to part of the URL space, ie, bind
>     parts to the URL space to be handled by a specific plugin.
> 
> 
> 1) Is there any way to have a wildcard handler? For example, the URL 
> http://localhost:8080/ would invoke the mounted directory, but anything 
> else (/formtest, /api/v1, /test), essentially /*, would be handled by a 
> single plugin handler? Or is it only possible to bind a specific URL to 
> a specific plugin handler?

That is how it works already.  These "mounts" work like "mounting a 
filesystem" "on a directory".  Everything underneath the mountpoint is 
handled by the filesystem or protocol callback mounted there.

It matches the most exact mountpoint it can, so you can have a 
mountpoint at / and one at /thing, a URL /thing will match the mount at 
/thing, not the one at /.

>     If you refer back to the test-server-v2.0.c example, there's an
>     example mount that binds /formtest in the URL space to
>     "protocol-post-demo".
> 
>     static const struct lws_http_mount mount_post = {
>              (struct lws_http_mount *)&mount_ziptest, /* linked-list
>     pointer to next*/
>              "/formtest",            /* mountpoint in URL namespace on
>     this vhost */
>              "protocol-post-demo",   /* handler */
>              NULL,   /* default filename if none given */
>              NULL,
>              NULL,
>              NULL,
>              NULL,
>              0,
>              0,
>              0,
>              0,
>              0,
>              0,
>              LWSMPRO_CALLBACK,       /* origin points to a callback */
>              9,                      /* strlen("/formtest"), ie length
>     of the mountpoint */
>              NULL,
> 
>              { NULL, NULL } // sentinel
>     };
> 
>     With the LWSMPRO_CALLBACK binding, it means in effect bind /formtest
>     to the protocol that handles "protocol-post-demo".  In this case,
>     that is a provided protocol plugin
> 
>     https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_post_demo.c
>     <https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_post_demo.c>
> 
>     That plugin handles POST actions, but the deal is basically the same
>     to handle HTTP GET or whatever in the protocol plugin.  For examples
>     of handling GET "by hand" like this in the callback, look at
> 
>     https://github.com/warmcat/libwebsockets/blob/master/test-apps/test-server-http.c
>     <https://github.com/warmcat/libwebsockets/blob/master/test-apps/test-server-http.c>
> 
>     For an example of handling WS in the protocol plugin, eg,
> 
>     https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_lws_mirror.c
>     <https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_lws_mirror.c>
> 
>     2) You need to mention a protocol name in a pvo like
>     test-server-v2.0.c does to enable that protocol on that vhost.  For
>     example you may have a lot of plugins for various things, and
>     multiple vhosts, but you do not want every plugin to be initialized
>     on every vhost, so you can control what is happening where.
> 
> 
> 2) I believe I'm doing that already, please checkout my code below:
> */*
>   * We must enable the plugin protocols we want into our vhost with a
>   * linked-list.  We can also give the plugin per-vhost options here.
>   */
> static const struct lws_protocol_vhost_options pvo = {
>      NULL,
>      NULL, // &pvo_opt,
>      "dumb-increment-protocol",
>      ""
> };*
> 
> */*
>   * give it our linked-list of Per-Vhost Options, these control
>   * which protocols (from plugins) are allowed to be enabled on
>   * our vhost
> */
> info.pvo = &pvo;*
> 
> How is libwebsockets associating the plugin name 
> "dumb-increment-protocol" to the plugin file? I don't see that name in 
> the "dumb-increment-protocol" plugin file itself, which I have not 

You didn't look hard enough.

https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_dumb_increment.c#L131

> changed at all. Am I including the plugin and associating it correctly? 
> It looks like libwebsockets properly found the plugin, but nothing in 
> the plugin is being invoked:
> 
> *[2017/11/20 23:49:18:6747] NOTICE:   Plugins:
> [2017/11/20 23:49:18:6748] NOTICE:   Scanning /Users/user/myproject/plugins
> [2017/11/20 23:49:18:6750] NOTICE:    protocol_dumb_increment.cpp

What's with the ".cpp"?  It should be ".so".

You should be building it according to the plugin-standalone example

https://github.com/warmcat/libwebsockets/tree/master/plugin-standalone

-Andy

> [2017/11/20 23:49:18:6757] NOTICE: Creating Vhost 'default' port 8080, 1 
> protocols, IPv6 off
> [2017/11/20 23:49:18:6757] NOTICE:    mounting 
> file:///Users/user/myproject/web/dist to /*
> 
>     The pvo just needs to mention the name of the protocol to enable it
>     on the vhost, as is done in test-server-v2.0.c:
> 
>     static const struct lws_protocol_vhost_options pvo_3 = {
>              &pvo_4,
>              NULL,
>              "protocol-post-demo",
>              "" /* ignored, just matches the protocol name above */
>     };
> 
>     -Andy
> 
> 
>         Thanks again!
> 
>         -- 
>         Chad Cravens
>         +1 (800) 214-9146 x700 <tel:%2B1%20%28800%29%20214-9146%20x700>
>         chad.cravens at ossys.com <mailto:chad.cravens at ossys.com>
>         <mailto:chad.cravens at ossys.com <mailto:chad.cravens at ossys.com>>
>         http://www.ossys.com
> 
>         Open Source Systems <https://www.ossys.com>
> 
>         LinkedIn
>         <https://www.linkedin.com/company/open-source-systems-llc
>         <https://www.linkedin.com/company/open-source-systems-llc>>
>         Facebook <https://www.facebook.com/OpenSrcSys
>         <https://www.facebook.com/OpenSrcSys>> Twitter
>         <https://www.twitter.com/OpenSrcSys
>         <https://www.twitter.com/OpenSrcSys>> YouTube
>         <https://www.youtube.com/OpenSrcSys
>         <https://www.youtube.com/OpenSrcSys>> Instagram
>         <https://www.instagram.com/OpenSrcSys
>         <https://www.instagram.com/OpenSrcSys>> RSS Feed
>         <http://www.ossys.com/feed>
> 
> 
>         _______________________________________________
>         Libwebsockets mailing list
>         Libwebsockets at ml.libwebsockets.org
>         <mailto:Libwebsockets at ml.libwebsockets.org>
>         https://libwebsockets.org/mailman/listinfo/libwebsockets
>         <https://libwebsockets.org/mailman/listinfo/libwebsockets>
> 
> 
> 
> 
> -- 
> Chad Cravens
> +1 (800) 214-9146 x700
> chad.cravens at ossys.com <mailto:chad.cravens at ossys.com>
> http://www.ossys.com
> 
> Open Source Systems <https://www.ossys.com>
> 
> LinkedIn <https://www.linkedin.com/company/open-source-systems-llc> 
> Facebook <https://www.facebook.com/OpenSrcSys> Twitter 
> <https://www.twitter.com/OpenSrcSys> YouTube 
> <https://www.youtube.com/OpenSrcSys> Instagram 
> <https://www.instagram.com/OpenSrcSys> RSS Feed <http://www.ossys.com/feed>



More information about the Libwebsockets mailing list