[Libwebsockets] v2.0 coming very soon

Thomas Spitz thomas.spitz at hestia-france.com
Mon Jun 13 15:13:40 CEST 2016


Hello again Andy,

I have been trying to use lws core library and the following static mounts
(test.html for static contents and protocol-post-demo for dynamic contents
"HTTP requests"):

> static const struct lws_http_mount mount_post = {
> NULL, /* 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 */
> };
> static const struct lws_http_mount mount_vHost = {
> (struct lws_http_mount *)&mount_post, /* linked-list pointer to next*/
> "/", /* mountpoint in URL namespace on this vhost */
> LOCAL_RESOURCE_PATH, /* where to go on the filesystem for that */
> "test.html", /* default filename if none given */
> NULL,
> NULL,
> NULL,
> NULL,
> 0,
> 0,
> 0,
> 0,
> 0,
> 0,
> LWSMPRO_FILE, /* mount type is a directory in a filesystem */
> 1, /* strlen("/"), ie length of the mountpoint */
> };

As you suggested:

> I have enclosed the complete test-server.c file. Main modifications are:
>
>>
>>   * remove callback_http from protocols[]
>> Hm... I think you still need a dummy protocols[0].
>> How the plugins stuff works is you can give it no protocols[] at all
>> (NULL in the info).  The context init stuff will point to to one dummy
>> protocol callback, it basically does nothing but blows a 404 if anything
>> reaches there.
>> https://github.com/warmcat/libwebsockets/blob/master/lib/context.c#L181
>
> I added a HTTP dummy protocol (callback_http_dummy) but my mounts are
never served. When requesting http://localhost:7681/ I always get 404 error
page.

> Mounts however seem OK for lws:
> lwsts[20663]: Initial logging level 7
> lwsts[20663]: Libwebsockets version: 2.0.0 thomas at thomas-laptop-
> lwsts[20663]: IPV6 not compiled in
> lwsts[20663]: libev support not compiled in
> lwsts[20663]: libuv support compiled in but disabled
> lwsts[20663]:  Threads: 1 each 4096 fds
> lwsts[20663]:  mem: platform fd map: 32768 bytes
> lwsts[20663]:  Compiled with OpenSSL support
> lwsts[20663]:  SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
> lwsts[20663]: Creating Vhost 'default' port 7681, 2 protocols
> lwsts[20663]:    mounting http:///home/thomas/workspace/test-libwebsockets-master-PC/serveurweb
> to /
> lwsts[20663]:    mounting http://protocol-post-demo to /formtest
> lwsts[20663]:  Listening on port 7681
> lwsts[20663]:  mem: per-conn:          648 bytes + protocol rx buf
> lwsts[20663]:  canonical_hostname = thomas-laptop
> lwsts[20663]: lws_protocol_init

I even tried to add a Per-Vhost Options linked list :

> static const struct lws_protocol_vhost_options pvo_opt = {
> NULL,
> NULL,
> "default",
> "1"
> };
> static const struct lws_protocol_vhost_options pvo = {
> NULL,
> &pvo_opt,
> "protocol-post-demo",
> ""/* ignored, just matches the protocol name above */
> };

but I suppose it doesn't have any effect as I am not using plugins at all.

Thanks for your great help.
Best regards,
Thomas
PS: I enclosed my demo project.

2016-06-06 11:15 GMT+02:00 Andy Green <andy at warmcat.com>:

>
>
> On 06/06/2016 05:07 PM, Thomas Spitz wrote:
>
>> Hello Andy,
>>
>> When you answered :
>>
>>     >So I wanted to use vhost LWSMPRO_CALLBACK functionnality but
>> apparently
>>     >it
>>     >is bind to plugin approach... So bad for me ;-)
>>     No it is not bound to plugins.  It just uses the protocol array, it
>>     doesn't care if that array was provided directly by user code or
>>     synthesized by collecting the protocols from different plugins at
>>     init time... after init, the two situations are the same.  The
>>     protocols are referred to using their name and looked up in the
>>     protocols array, nobody cares at that point where the protocols
>>     array came from.
>>
>> I understand that a protocol array  provided directly by user code or
>> synthesized by collecting the protocols from different plugins at init
>> time is the same. In my case, I wanted the protocol-post-demo code to
>> come from a C function from my C project and not from a C file compiled
>> externally and placed in a plugin dir.
>>
>
> Well, okay.
>
> In other word, I wanted to specify a C function instead of a name in the
>>
>
> ...
>
> below handler:
>>
>>     static const struct lws_http_mount mount_post = {
>>     NULL,/* 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,
>>     0,
>>     0,
>>     0,
>>     0,
>>     0,
>>     LWSMPRO_CALLBACK,/* origin points to a callback */
>>     9/* strlen("/formtest"), ie length of the mountpoint */
>>     };
>>
>>
>> but I think it is not possible..
>>
>
> Every protocol definition lets you define a callback function and a name.
> So being able to give the protocol name in the mount is actually the same
> as being able to identify the callback function you want calling.
>
> You just need to define one of your protocols[] array (that you are giving
> directly in your code, since you are trying to avoid plugins) to have the
> callback that you want get called.  Give that protocol the name
> "protocol-post-demo" (or change the name in both the protocol[] and the
> mount) and you are done.
>
> -Andy
>
> Best regards,
>> Thomas
>>
>>
>> 2016-06-02 23:58 GMT+02:00 Andy Green <andy at warmcat.com
>> <mailto:andy at warmcat.com>>:
>>
>>
>>
>>     On June 3, 2016 12:21:08 AM GMT+08:00, Thomas Spitz
>>     <thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>> wrote:
>>     >Hello Andy,
>>     >>
>>     >>
>>     >> In fact, as for an example, I modified test-server in order not to
>>     >have
>>     >>> to write my own callback_http but still have post_demo example
>>     >working.
>>     >>
>>     >> test-server-v2.0.c already does this, using plugins.
>>     >
>>     >
>>     >>
>>     >As I already mentionned in our previous discussions, I unfortunately
>>     >cannot
>>     >use plugins because it implies too much refactoring of my project.
>>
>>     Well, you know your code.  But there is a tradeoff there in terms of
>>     difficulty you're creating on lws side as I already noted.
>>
>>     >So I wanted to use vhost LWSMPRO_CALLBACK functionnality but
>> apparently
>>     >it
>>     >is bind to plugin approach... So bad for me ;-)
>>
>>     No it is not bound to plugins.  It just uses the protocol array, it
>>     doesn't care if that array was provided directly by user code or
>>     synthesized by collecting the protocols from different plugins at
>>     init time... after init, the two situations are the same.  The
>>     protocols are referred to using their name and looked up in the
>>     protocols array, nobody cares at that point where the protocols
>>     array came from.
>>
>>     >I will therefore definitively keep on giving HTTP support in the "low
>>     >level" code manner (based on callback_http of
>>     >test-server/test-server-http.c)
>>
>>     Mounts work fine without plugins too.
>>
>>     Plugins don't go any deeper into lws than providing an alternative
>>     way to supply protocol callback code, and to assemble an oldstyle
>>     protocols[] array dynamically onetime at init.  That much has big
>>     benefits architecturally, since interesting protocols can now be
>>     reused cleanly and mix-and-matched per-vhost casually.
>>
>>     Your valgrind problem is something to do with a vsprintf touching
>>     something it shouldn't, ie, a log argument or sprintf argument.  If
>>     you rebuild in DEBUG as suggested, valgrind should report the
>>     related line number and it shouldn't be hard to get a grip on
>>     whatever that is.  It's probably something small rather than a
>>     gateway to hell.
>>
>>     >By the way, is there a way (without plugin support) to accept both
>> HTTP
>>     >and
>>     >HTTPs but only WSS? The idea is to provide a webpage that can be
>>     >reached
>>     >either in HTTP (port 80) or HTTPs (port 443) but then only accept WSS
>>     >(not
>>     >WS without SSL) because my authentification is done through WSS.
>>
>>     Make a vhost on :443 and put your mounts and everything there. Then
>>     add a second vhost on :80 that redirects to https://myhost (ie, on
>> 443).
>>
>>     I can feel you're about to reply, 'ah! but it's not exactly what I
>>     asked!' however what you asked is insecure since there is no way for
>>     the browser to validate your host on port 80.  If someone is on an
>>     AP controlled by the attacker, eg, "Free Airport Wifi", he can MITM
>>     the port 80 access and add things to the non-https page that lets
>>     him use the authenticated wss connection.
>>
>>     The only way to do that securely is bounce him to 443 from the
>>     start, and give him the STS header so subsequently his browser knows
>>     to directly go to 443 even if he typed http.  You can request the
>>     STS is sent by adding info.options |= LWS_SERVER_OPTION_STS; when
>>     creating the vhost for 443.  (or if using lwsws conf, just this in
>>     the vhost definition
>>
>>          "sts": "on",
>>
>>     )
>>
>>     If you're unmoved by that, then, well, just repeat the vhost
>>     contents, including the mounts in both :443 and :80 vhosts, and in
>>     both cases have the JS open wss://.... but not a good idea
>>     security-wise.
>>
>>     -Andy
>>
>>     >
>>     >Best regadrs,
>>     >Thomas
>>     >
>>     >2016-06-02 12:46 GMT+02:00 Andy Green <andy at warmcat.com
>>     <mailto:andy at warmcat.com>>:
>>     >
>>     >>
>>     >>
>>     >> On 06/02/2016 06:11 PM, Thomas Spitz wrote:
>>     >>
>>     >>> Hello Andy,
>>     >>>
>>     >>> In my previous email, I asked you about LWSMPRO_CALLBACKin stable
>>     >release.
>>     >>>
>>     >>
>>     >> It only exists on master, where I have the freedom to change
>> related
>>     >> things, by design.
>>     >>
>>     >> In fact, as for an example, I modified test-server in order not to
>>     >have
>>     >>> to write my own callback_http but still have post_demo example
>>     >working.
>>     >>>
>>     >>
>>     >> test-server-v2.0.c already does this, using plugins.
>>     >>
>>     >> I have enclosed the complete test-server.c file. Main modifications
>>     >are:
>>     >>>
>>     >>>   * remove callback_http from protocols[]
>>     >>>
>>     >>
>>     >> Hm... I think you still need a dummy protocols[0].
>>     >>
>>     >> How the plugins stuff works is you can give it no protocols[] at
>> all
>>     >(NULL
>>     >> in the info).  The context init stuff will point to to one dummy
>>     >protocol
>>     >> callback, it basically does nothing but blows a 404 if anything
>>     >reaches
>>     >> there.
>>     >>
>>     >>
>>     >
>> https://github.com/warmcat/libwebsockets/blob/master/lib/context.c#L181
>>     >>
>>     >> He also provides default routing for CGI stdin/out/err if CGI is
>>     >> configured.
>>     >>
>>     >> When the plugins are discovered, the vhost list of protocols is
>>     >matched
>>     >> against the existing protocols from the plugins, and a new
>> per-vhost
>>     >> generated protocols[] array is created starting with a copy of the
>>     >dummy
>>     >> protocol[0] and followed by the ones the vhost listed as allowed
>> for
>>     >him.
>>     >>
>>     >> So with plugins, there is still always a protocols[0] for http,
>> even
>>     >if
>>     >> you initialized it to have no protocols in your user code.
>>     >>
>>     >>   * copy paste callback_post_demo from plugin/protocol_post_demo
>>     >>>   * Add a linked list of 2 mounts for "test.html" and
>>     >"protocol-post-demo"
>>     >>>
>>     >>> Everything works fine except that form-test only works once (I get
>>     >the
>>     >>> Form results in the browser) before server crashes
>>     >>>
>>     >>
>>     >> If you use the test-server-v2.0.c directly and the provided
>> plugins,
>>     >to
>>     >> test POST, is there any problem?  I am guessing not, since
>> otherwise
>>     >> libwebsockets.org <http://libwebsockets.org>, which offers
>>     plugin-based POST would have blown up
>>     >> long ago.
>>     >>
>>     >> To help debug your problem, make sure you configure lws and your
>> app
>>     >to
>>     >> build with debug info... for lws it's
>>     >>
>>     >> $ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
>>     >>
>>     >> That way you might get some line numbers in your backtrace, which
>>     >will
>>     >> obviously make finding the bug a lot easier.
>>     >>
>>     >> -Andy
>>     >>
>>     >> Here the trace of the test-server:
>>     >>>
>>     >>>     thomas at thomas-laptop
>>     >>>
>>
>> >:~/workspace/Varuna4/0_librairies_sources/libwebsockets/buildPC-nolwsws-noplugins/bin$
>>     >>>     ./libwebsockets-test-server
>>     >>>     lwsts[25448]: libwebsockets test server - license LGPL2.1+SLE
>>     >>>     lwsts[25448]: (C) Copyright 2010-2016 Andy Green
>>     ><andy at warmcat.com <mailto:andy at warmcat.com>
>>     >>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>
>>     >>>     Using resource path "./share/libwebsockets-test-server"
>>     >>>     lwsts[25448]: Initial logging level 7
>>     >>>     lwsts[25448]: Libwebsockets version: 2.0.0
>> thomas at thomas-laptop-
>>     >>>     lwsts[25448]: IPV6 not compiled in
>>     >>>     lwsts[25448]: libev support not compiled in
>>     >>>     lwsts[25448]: libuv support not compiled in
>>     >>>     lwsts[25448]:  Threads: 1 each 1024 fds
>>     >>>     lwsts[25448]:  mem: platform fd map:  8192 bytes
>>     >>>     lwsts[25448]:  Compiled with OpenSSL support
>>     >>>     lwsts[25448]:  SSL disabled: no
>>     >LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
>>     >>>     lwsts[25448]: Creating Vhost 'default' port 7681, 5 protocols
>>     >>>     lwsts[25448]:    mounting
>>     >file://./share/libwebsockets-test-server to
>>     >>> /
>>     >>>     lwsts[25448]:    mounting callback://protocol-post-demo to
>>     >/formtest
>>     >>>     lwsts[25448]:  Listening on port 7681
>>     >>>     lwsts[25448]:  mem: per-conn:          480 bytes + protocol rx
>>     >buf
>>     >>>     lwsts[25448]:  canonical_hostname = thomas-laptop
>>     >>>     lwsts[25448]: lws_protocol_init
>>     >>>     lwsts[25448]: test_server_fops_open: opening
>>     >>>     ./share/libwebsockets-test-server/test.html, ret 9, len 18530
>>     >>>     lwsts[25448]: test_server_fops_open: opening
>>     >>>     ./share/libwebsockets-test-server/libwebsockets.org-logo.png,
>>     >ret 9,
>>     >>>     len 7029
>>     >>>         get  = /xxx
>>     >>>         host: = 192.168.1.190:7681 <http://192.168.1.190:7681>
>>     <http://192.168.1.190:7681>
>>     >>>
>>     >>>         connection: = Upgrade
>>     >>>         upgrade: = websocket
>>     >>>         origin: = http://192.168.1.190:7681
>>     >>>         sec-websocket-extensions: = permessage-deflate;
>>     >>>     client_max_window_bits
>>     >>>         sec-websocket-protocol: = dumb-increment-protocol
>>     >>>         http/1.1  = HTTP/1.1
>>     >>>         accept-encoding: = gzip, deflate, sdch
>>     >>>         accept-language: = fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
>>     >>>         pragma: = no-cache
>>     >>>         cache-control: = no-cache
>>     >>>         sec-websocket-key: = vO6t+VKg0zBTZkrsCja3kA==
>>     >>>         sec-websocket-version: = 13
>>     >>>         user-agent: = Mozilla/5.0 (Windows NT 10.0; WOW64)
>>     >>>     AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63
>>     >>> Safari/537.36
>>     >>>     lwsts[25448]:  permessage-deflate requires the protocol
>>     >>>     (dumb-increment-protocol) to have an RX buffer >= 128
>>     >>>     lwsts[25448]: ext permessage-deflate failed construction
>>     >>>     lwsts[25448]:  Capping pmd rx to 128
>>     >>>     lwsts[25448]: cache_len 280
>>     >>>     lwsts[25448]: lws_header_table_detach: wsi 0x1faee50: ah held
>>     >6s,
>>     >>>     ah.rxpos 559, ah.rxlen 559, mode/state 5
>> 5,wsi->more_rx_waiting
>>     >0
>>     >>>     lwsts[25448]: test_server_fops_open: opening
>>     >>>     ./share/libwebsockets-test-server/favicon.ico, ret 11, len
>> 1406
>>     >>>         get  = /xxx
>>     >>>         host: = 192.168.1.190:7681 <http://192.168.1.190:7681>
>>     <http://192.168.1.190:7681>
>>     >>>         connection: = Upgrade
>>     >>>         upgrade: = websocket
>>     >>>         origin: = http://192.168.1.190:7681
>>     >>>         sec-websocket-extensions: = permessage-deflate;
>>     >>>     client_max_window_bits
>>     >>>         sec-websocket-protocol: = lws-mirror-protocol
>>     >>>         http/1.1  = HTTP/1.1
>>     >>>         accept-encoding: = gzip, deflate, sdch
>>     >>>         accept-language: = fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
>>     >>>         pragma: = no-cache
>>     >>>         cache-control: = no-cache
>>     >>>         sec-websocket-key: = sU8nB7+0wS9MMJse8B3cIw==
>>     >>>         sec-websocket-version: = 13
>>     >>>         user-agent: = Mozilla/5.0 (Windows NT 10.0; WOW64)
>>     >>>     AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63
>>     >>> Safari/537.36
>>     >>>     lwsts[25448]:  Capping pmd rx to 128
>>     >>>     *** Error in `./libwebsockets-test-server': malloc(): memory
>>     >>>     corruption: 0x000000000200b0d0 ***
>>     >>>     Aborted (core dumped)
>>     >>>
>>     >>> Any idea?
>>     >>>
>>     >>> Thanks in advance
>>     >>> Best regards,
>>     >>> Thomas
>>     >>>
>>     >>>
>>     >>> 2016-06-02 10:49 GMT+02:00 Thomas Spitz
>>     ><thomas.spitz at hestia-france.com <mailto:
>> thomas.spitz at hestia-france.com>
>>     >>> <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>>:
>>     >>>
>>     >>>     Hello Andy,
>>     >>>
>>     >>>     I have seen that you released v2.0.2 (on
>>     >>>     https://libwebsockets.org/git/libwebsockets/) but I am
>> surprised
>>     >>>     there is no LWSMPRO_CALLBACK in /lib/libwebsockets.h given
>> that
>>     >you
>>     >>>     mention it
>>     >>>     in
>>     >>>
>>     >
>> https://github.com/warmcat/libwebsockets/blob/master/README.coding.md
>>     >>>
>>     >>>     Best regards,
>>     >>>     Thomas Spitz
>>     >>>
>>     >>>
>>     >>>     2016-05-26 22:31 GMT+02:00 Andy Green <andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     >>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>:
>>     >>>
>>     >>>
>>     >>>
>>     >>>         On May 26, 2016 11:19:05 PM GMT+08:00, Thomas Spitz
>>     >>>         <thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>
>>     >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>> wrote:
>>     >>>         >>
>>     >>>         >>     Maybe you should better prototype it with the high
>>     >end
>>     >>> stuff and
>>     >>>         >>
>>     >>>         >>     when it works, look at reducing that to code,
>>     >including the
>>     >>>         >plugin
>>     >>>         >>     content direct in your app etc if you still want
>> to.
>>     >>>         >> This is what I have done. First lwsws, then
>>     >test-server-v2.0
>>     >>> then
>>     >>>         >> test-server then my program
>>     >>>         >> This leads me to use lws in the old manner because my
>>     >main ws
>>     >>>         >protocol
>>     >>>         >> (which is part of my program) cannot be launched as
>>     >plugin
>>     >>> (too much
>>     >>>         >> work to make it work as separate program and also too
>>     >hard to
>>     >>> debug
>>     >>>         >then)
>>     >>>         >> I don't really understand your situation, but it is
>> not a
>>     >>> separate
>>     >>>         >> program.  As I mentioned the one plugin can service
>> both
>>     >ws
>>     >>> and http
>>     >>>         >in the
>>     >>>         >> one callback function.  Maybe I misunderstand.
>>     >>>         >>
>>     >>>         >> My problem might be sum up to the following : I cannot
>>     >easily
>>     >>>         >separate
>>     >>>         >test-server program into 2 programs compiled separately
>>     >>>         >(test-server-v2.0
>>     >>>         >on one side and protocol_my_protocol on other side). In
>>     >fact my
>>     >>> program
>>     >>>         >share data with each client (mutex, * client_wsi,
>>     >program_data,
>>     >>>         >client_data, client pthread, ...) AND my program is also
>>     >able to
>>     >>>         >start/stop
>>     >>>         >the server (run into a thread) in order to reconfigure
>> it.
>>     >I'm
>>     >>>
>>     >>>         I dunno if this is the point, but in the info struct there
>>     >is this
>>     >>>
>>     >>>          * @user:       CONTEXT: optional user pointer that can be
>>     >>>         recovered via the context
>>     >>>          *              pointer using lws_context_user
>>     >>>
>>     >>>         So you can pass in here a pointer to your shared data
>> struct
>>     >>>         between the main app and lws service thread.  Everywhere
>> in
>>     >your
>>     >>>         code that has access to lws_context, eg, every protocol
>>     >plugin
>>     >>>         callback, has access to that struct; you can share the
>>     >struct
>>     >>>         declaration by #include the same header in the plugin as
>> the
>>     >>>         main app.
>>     >>>
>>     >>>         That means eg a protocol plugin running in its service
>>     >thread
>>     >>>         can directly share and change any data with the main app's
>>     >thread.
>>     >>>
>>     >>>         Although a plugin
>>     >>>
>>     >>>          - has its code separated
>>     >>>
>>     >>>          - may be built separately from the main app
>>     >>>
>>     >>>         It is NOT a separate thread or process or has private
>>     >virtual
>>     >>>         memory restriction like it was fork()ed.  When the plugin
>> is
>>     >>>         loaded, it becomes part of the process using lws, almost
>>     >exactly
>>     >>>         like it was all compiled together originally.
>>     >>>
>>     >>>         It doesn't have access to main app global vars directly,
>>     >that's
>>     >>>         true, but if you put the related globals in a (global)
>>     >struct
>>     >>>         and set info.user to point to it when you create the
>>     >context,
>>     >>>         all plugins can have access to it easily giving the same
>>     >result.
>>     >>>
>>     >>>         My guess is every objection to plugins has a similar
>>     >solution,
>>     >>>         although maybe some of your problems need new apis once I
>>     >>>         understand them.
>>     >>>
>>     >>>         >I will unfortunately have to implement low-level code for
>>     >static
>>     >>> (GET
>>     >>>         >>
>>     >>>         >> file like leaf.png with/without authentification) and
>>     >dynamic
>>     >>> (HTTP
>>     >>>         >> GET/POST command) HTTP serving.
>>     >>>         >> Can you tell a little more about why you "have" to do
>> the
>>     >low
>>     >>> level
>>     >>>         >> serving code for static files?
>>     >>>         >>
>>     >>>         >> -> some files have to be retrieved from other locations
>>     >than
>>     >>> where
>>     >>>         >"test.html" is (for instance from a given folder in a SD
>>     >card)
>>     >>>         >
>>     >>>         >> If it's auth, the generic-sessions plugin is aimed at
>>     >>> providing that.
>>     >>>         >
>>     >>>         >In order not to enable anybody retrieve those files on SD
>>     >card,
>>     >>> I need
>>     >>>         >to
>>     >>>         >protect them by login/password (In fact the only users
>>     >enabled
>>     >>> are the
>>     >>>         >user
>>     >>>         >that manage to connect through our ws protocol using our
>>     >own auth
>>     >>>         >policy).
>>     >>>         >I could have used your future generic-sessions plugin
>>     >(except I
>>     >>> am
>>     >>>         >afraid
>>     >>>         >sqlite is redundant with my actual 400 users login/pwd
>>     >struct)
>>     >>> but as I
>>     >>>         >cannot use plugins due to separate compilation and shared
>>     >>> compenents..
>>     >>>
>>     >>>         400 users sounds to me like you really need sqlite
>> actually.
>>     >>>
>>     >>>         If you look into that I think you will end up with
>> needing a
>>     >>>         "session".  Then the amount of duplicated work will be
>> very
>>     >big.
>>     >>>
>>     >>>         sqlite also has a handy feature you can do sql from the
>>     >>>         commandline on the db, eg to init your 400 users if you
>>     >won't
>>     >>>         let them create their own accounts over the web ui.
>>     >>>
>>     >>>         >I agree you'll have to do your own dynamic HTTP serving
>>     >code,
>>     >>> but this
>>     >>>         >can
>>     >>>         >> coexist in the same plugin - the same source file - as
>>     >the ws
>>     >>> serving
>>     >>>         >part,
>>     >>>         >> if that helps.
>>     >>>         >
>>     >>>         >Without plugins, I think of serving dynamic HTTP using
>>     >general
>>     >>>         >callback_http
>>     >>>
>>     >>>         Yes, for the dynamic html, you are into that one way or
>>     >another.
>>     >>>
>>     >>>         But architecturally, you should be able to do it from a
>>     >plugin.
>>     >>>
>>     >>>         >Hope you will keep test-server always up to date
>>     >>>         >>
>>     >>>         >>
>>     >>>         >> One minor question : Is it possible to do port
>>     >redirection with
>>     >>>         >> test-server (http 80 -> redirect to https 7681). By the
>>     >way one
>>     >>>         >drawback
>>     >>>         >> Sure... you make a vhost at the port you want to
>>     >redirect,
>>     >>>         and tell
>>     >>>         >it the
>>     >>>         >> new URL in the origin  (This one redirects SSL on port
>>     >7681,
>>     >>>         where I
>>     >>>         >used
>>     >>>         >> to run the test server, to SSL on port 443 and the URL
>>     >where
>>     >>>         it now
>>     >>>         >lives)
>>     >>>         >>     {
>>     >>>         >>         # the old test server ran this on :7681, put a
>>     >redirect
>>     >>>         >>         # there to take us to the new location
>>     >>>         >>     "name": "libwebsockets.org <
>> http://libwebsockets.org>
>>     ><http://libwebsockets.org>",
>>     >>>
>>     >>>         >>     "port": "7681",
>>     >>>         >>      "host-ssl-key":
>>     >>>         "/etc/pki/tls/private/libwebsockets.org.key",
>>     >>>         >>      "host-ssl-cert":
>>     >>> "/etc/pki/tls/certs/libwebsockets.org.crt",
>>     >>>         >>      "host-ssl-ca":
>>     >>>  "/etc/pki/tls/certs/libwebsockets.org.cer",
>>     >>>         >>      "mounts": [{
>>     >>>         >>        "mountpoint": "/",
>>     >>>         >>        "origin": ">
>> https://libwebsockets.org/testserver/"
>>     >>>         >>      }]
>>     >>>         >>   }
>>     >>>         >> You should be able to give an origin like
>>     >>>         >> "origin": ">https://libwebsockets.org:7681/testserver/
>> "
>>     >>>         >>
>>     >>>         >> vhost need plugin support if I understood correctly. If
>>     >yes,
>>     >>>         then I
>>     >>>         >don't
>>     >>>         >see how to make it work with vhost
>>     >>>
>>     >>>         No: vhosts are baked into the main lib and are unrelated
>> to
>>     >>> plugins.
>>     >>>
>>     >>>         You can deliver an array of protocols to them when you
>>     >create
>>     >>>         them, and you mention protocol names in the info.pvo
>> linked
>>     >list
>>     >>>         to enable + configure them on the vhost.
>>     >>>
>>     >>>         If plugins are enabled, lws will bind any protocol names
>> to
>>     >the
>>     >>>         plugin that matches, at init time; it makes a new
>> protocols
>>     >>>         array if so with your array and then any dynamically found
>>     >>>         protocols enabled by mentions in pvo appended.  But it's
>>     >>>         completely optional, you can do everything just with the
>>     >static
>>     >>>         array of protocols you fed the vhost and no plugins, since
>>     >>>         vhosts only talks about protocols using their name, it
>>     >doesn't
>>     >>>         care where it found them originally.
>>     >>>
>>     >>>         -Andy
>>     >>>
>>     >>>         >
>>     >>>         >
>>     >>>         >2016-05-26 16:13 GMT+02:00 Andy Green <andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     >>>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>:
>>     >>>
>>     >>>         >
>>     >>>         >>
>>     >>>         >>
>>     >>>         >> On 05/26/2016 08:40 PM, Thomas Spitz wrote:
>>     >>>         >>
>>     >>>         >>>     Maybe you should better prototype it with the high
>>     >end
>>     >>>         stuff and
>>     >>>         >>>     when it works, look at reducing that to code,
>>     >including
>>     >>> the
>>     >>>         >plugin
>>     >>>         >>>     content direct in your app etc if you still want
>> to.
>>     >>>         >>>
>>     >>>         >>> This is what I have done. First lwsws, then
>>     >test-server-v2.0
>>     >>>         then
>>     >>>         >>> test-server then my program
>>     >>>         >>>
>>     >>>         >>> This leads me to use lws in the old manner because my
>>     >main ws
>>     >>>         >protocol
>>     >>>         >>> (which is part of my program) cannot be launched as
>>     >plugin
>>     >>>         (too much
>>     >>>         >>> work to make it work as separate program and also too
>>     >hard
>>     >>>         to debug
>>     >>>         >then)
>>     >>>         >>>
>>     >>>         >>
>>     >>>         >> I don't really understand your situation, but it is
>> not a
>>     >>>         separate
>>     >>>         >> program.  As I mentioned the one plugin can service
>> both
>>     >ws
>>     >>>         and http
>>     >>>         >in the
>>     >>>         >> one callback function.  Maybe I misunderstand.
>>     >>>         >>
>>     >>>         >> I will unfortunately have to implement low-level code
>> for
>>     >>>         static (GET
>>     >>>         >>> file like leaf.png with/without authentification) and
>>     >>>         dynamic (HTTP
>>     >>>         >>> GET/POST command) HTTP serving.
>>     >>>         >>>
>>     >>>         >>
>>     >>>         >> Can you tell a little more about why you "have" to do
>> the
>>     >low
>>     >>>         level
>>     >>>         >> serving code for static files?  If it's auth, the
>>     >>>         generic-sessions
>>     >>>         >plugin
>>     >>>         >> is aimed at providing that.  If there's something
>> special
>>     >>>         about your
>>     >>>         >auth
>>     >>>         >> needs, I am very curious to hear about that atm.
>>     >Generally I
>>     >>>         am very
>>     >>>         >much
>>     >>>         >> trying to provide static file serving with session auth
>>     >"out
>>     >>>         of the
>>     >>>         >box".
>>     >>>         >>
>>     >>>         >> I agree you'll have to do your own dynamic HTTP serving
>>     >code,
>>     >>> but
>>     >>>         >this can
>>     >>>         >> coexist in the same plugin - the same source file - as
>>     >the ws
>>     >>>         serving
>>     >>>         >part,
>>     >>>         >> if that helps.
>>     >>>         >>
>>     >>>         >> Hope you will keep test-server always up to date
>>     >>>         >>>
>>     >>>         >>> One minor question : Is it possible to do port
>>     >redirection
>>     >>> with
>>     >>>         >>> test-server (http 80 -> redirect to https 7681). By
>> the
>>     >way
>>     >>> one
>>     >>>         >drawback
>>     >>>         >>>
>>     >>>         >>
>>     >>>         >> Sure... you make a vhost at the port you want to
>>     >redirect,
>>     >>>         and tell
>>     >>>         >it the
>>     >>>         >> new URL in the origin  (This one redirects SSL on port
>>     >7681,
>>     >>>         where I
>>     >>>         >used
>>     >>>         >> to run the test server, to SSL on port 443 and the URL
>>     >where
>>     >>>         it now
>>     >>>         >lives)
>>     >>>         >>
>>     >>>         >>     {
>>     >>>         >>         # the old test server ran this on :7681, put a
>>     >redirect
>>     >>>         >>         # there to take us to the new location
>>     >>>         >>     "name": "libwebsockets.org <
>> http://libwebsockets.org>
>>     ><http://libwebsockets.org>",
>>     >>>
>>     >>>         >>     "port": "7681",
>>     >>>         >>      "host-ssl-key":
>>     >>>         "/etc/pki/tls/private/libwebsockets.org.key",
>>     >>>         >>      "host-ssl-cert":
>>     >>> "/etc/pki/tls/certs/libwebsockets.org.crt",
>>     >>>         >>      "host-ssl-ca":
>>     >>>  "/etc/pki/tls/certs/libwebsockets.org.cer",
>>     >>>         >>      "mounts": [{
>>     >>>         >>        "mountpoint": "/",
>>     >>>         >>        "origin": ">
>> https://libwebsockets.org/testserver/"
>>     >>>         >>      }]
>>     >>>         >>   }
>>     >>>         >>
>>     >>>         >> You should be able to give an origin like
>>     >>>         >>
>>     >>>         >> "origin": ">https://libwebsockets.org:7681/testserver/
>> "
>>     >>>         >>
>>     >>>         >> with redirection using lwsws is that we have to
>> specify a
>>     >URL
>>     >>>         when
>>     >>>         >doing
>>     >>>         >>> port redirection. For instance if we have server at
>>     >>> 192.168.1.3
>>     >>>         >exposed
>>     >>>         >>> to the web as websockets.org <http://websockets.org>
>>     <http://websockets.org>
>>     >>>         <http://websockets.org> then we need
>>     >>>         >two
>>     >>>         >>> redirections in order to make it work on both LAN and
>>     >WAN
>>     >>>         >>>
>>     >>>         >>
>>     >>>         >> Hm you can configure your local DNS to tell you
>>     >192.168.1.3
>>     >>>         is the
>>     >>>         >address
>>     >>>         >> of your server, to local clients.  That's what I do
>> here
>>     >to
>>     >>>         access my
>>     >>>         >own
>>     >>>         >> internet-facing services.
>>     >>>         >>
>>     >>>         >> If it's a laptop and you take it outside, he gets
>>     >external
>>     >>>         DNS server
>>     >>>         >and
>>     >>>         >> uses the external address automatically.
>>     >>>         >>
>>     >>>         >> That's not really an lws problem, if I understood it.
>>     >>>         >>
>>     >>>         >> -Andy
>>     >>>         >>
>>     >>>         >> Thanks for the support.
>>     >>>         >>>
>>     >>>         >>> Best regards,
>>     >>>         >>> Thomas
>>     >>>         >>>
>>     >>>         >>> 2016-05-26 11:48 GMT+02:00 Andy Green
>>     <andy at warmcat.com <mailto:andy at warmcat.com>
>>     >>>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>
>>     >>>         >>> <mailto:andy at warmcat.com <mailto:andy at warmcat.com>
>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>>:
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     On 05/26/2016 05:15 PM, Thomas Spitz wrote:
>>     >>>         >>>
>>     >>>         >>>         Hello Andy,
>>     >>>         >>>
>>     >>>         >>>         On one hand, I have tried to use the new
>> plugin
>>     >>>         approach in
>>     >>>         >my
>>     >>>         >>>         program
>>     >>>         >>>         but it is very hard in my case because lws
>>     >server and
>>     >>> my
>>     >>>         >main
>>     >>>         >>>         plugin (ws
>>     >>>         >>>         connection) are very tied together (they share
>>     >many
>>     >>>         >variables
>>     >>>         >>>         that would
>>     >>>         >>>         need to be exposed to my application through
>> shm
>>     >or
>>     >>>         other
>>     >>>         >>>         sharing options).
>>     >>>         >>>         On the other hand, in order to get advantage
>> of
>>     >>>         better HTTP
>>     >>>         >file
>>     >>>         >>>         handling, auth management and further
>>     >improvements,
>>     >>>         I would
>>     >>>         >like
>>     >>>         >>>         not to
>>     >>>         >>>         have to write my own callback_http.
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     If you are going to serve dynamic http, you'll
>> need
>>     >to
>>     >>>         have your
>>     >>>         >own
>>     >>>         >>>     http handling.  But that can be in the same
>> plugin -
>>     >the
>>     >>>         same
>>     >>>         >>>     protocol callback - as the ws parts, so there is
>> no
>>     >>> problem
>>     >>>         >about
>>     >>>         >>>     "sharing variables".
>>     >>>         >>>
>>     >>>         >>>         In other word, is it possible to declare my
>> own
>>     >>> protocol
>>     >>>         >>>         definitions and
>>     >>>         >>>         user callback contents like in first
>> test-server
>>     >but
>>     >>>         without
>>     >>>         >>>         declaring
>>     >>>         >>>         http-callback. That is to say
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     If you need it, because you're not serving files
>> but
>>     >>>         generated
>>     >>>         >html,
>>     >>>         >>>     you need it.  If you're serving files, like
>>     >leaf.jpg,
>>     >>>         you can
>>     >>>         >use
>>     >>>         >>>     mounts.
>>     >>>         >>>
>>     >>>         >>>              /* list of supported protocols and
>>     >callbacks */
>>     >>>         >>>              static struct lws_protocols protocols[] =
>>     >>>         >>>              {
>>     >>>         >>>              { "MY_PROTOCOL", callback_my_protocol,
>>     >>>         sizeof(struct
>>     >>>         >>>              per_session_data__my_protocole), 4096},
>>     >>>         >>>              { NULL, NULL, 0, 0 } /* terminator */
>>     >>>         >>>              };
>>     >>>         >>>
>>     >>>         >>>     ...
>>     >>>         >>>
>>     >>>         >>>         it is not clear for me wether libuv (and so
>>     >plugins)
>>     >>> are
>>     >>>         >>>         required or nor.
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     Lws is pretty flexible, it does not itself need
>>     >libuv or
>>     >>>         >plugins.
>>     >>>         >>>     But you are into writing a lot of code and structs
>>     >if you
>>     >>> go
>>     >>>         >that way.
>>     >>>         >>>
>>     >>>         >>>     One of the knock-ons is then you must provide an
>>     >explicit
>>     >>>         >http-only
>>     >>>         >>>     protocols[0] yourself.
>>     >>>         >>>
>>     >>>         >>>     If you use the plugins stuff, actually you can
>> avoid
>>     >it
>>     >>> -->
>>     >>>         >>>
>>     >>>         >>>         I also do not understand how test-server-v2.0
>>     >manage
>>     >>> to
>>     >>>         >serve
>>     >>>         >>>         leaf.png
>>     >>>         >>>         and any other file in any other folder (what
>>     >>> test-server
>>     >>>         >isn't
>>     >>>         >>>         able to
>>     >>>         >>>         do) using HTTP
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     test-server-v2.0.c is even more remarkable if you
>>     >notice
>>     >>> he
>>     >>>         >doesn't
>>     >>>         >>>     define any protocols at all.  Lws defines a dummy
>>     >>>         "protocols[0]"
>>     >>>         >one
>>     >>>         >>>     then and assembles the protocol structs
>> dynamically
>>     >from
>>     >>> the
>>     >>>         >plugins
>>     >>>         >>>     enabled in the config (or info.pvo if you do it by
>>     >hand
>>     >>> with
>>     >>>         >structs).
>>     >>>         >>>
>>     >>>         >>>     The reason it can serve everything is it declares
>> a
>>     >mount:
>>     >>>         >>>
>>     >>>         >>>     static const struct lws_http_mount mount = {
>>     >>>         >>>              (struct lws_http_mount *)&mount_post,
>>     >>>  /*
>>     >>>         >>>     linked-list pointer to next*/
>>     >>>         >>>              "/",            /* mountpoint in URL
>>     >namespace
>>     >>>         on this
>>     >>>         >vhost
>>     >>>         >>> */
>>     >>>         >>>              LOCAL_RESOURCE_PATH, /* where to go on
>> the
>>     >>>         filesystem
>>     >>>         >for
>>     >>>         >>>     that */
>>     >>>         >>>              "test.html",    /* default filename if
>> none
>>     >>>         given */
>>     >>>         >>>              NULL,
>>     >>>         >>>              NULL,
>>     >>>         >>>              NULL,
>>     >>>         >>>              NULL,
>>     >>>         >>>              0,
>>     >>>         >>>              0,
>>     >>>         >>>              0,
>>     >>>         >>>              0,
>>     >>>         >>>              0,
>>     >>>         >>>              0,
>>     >>>         >>>              LWSMPRO_FILE,   /* mount type is a
>>     >directory in a
>>     >>>         >filesystem
>>     >>>         >>> */
>>     >>>         >>>              1,              /* strlen("/"), ie length
>>     >of the
>>     >>>         >mountpoint
>>     >>>         >>> */
>>     >>>         >>>     };
>>     >>>         >>>
>>     >>>         >>>     binding the URL namespace from / to
>>     >LOCAL_RESOURCE_PATH,
>>     >>>         which
>>     >>>         >is
>>     >>>         >>>     /usr/share/libwebsockets-test-server or wherever
>> you
>>     >>>         installed
>>     >>>         >lws.
>>     >>>         >>>
>>     >>>         >>>     Once you set it up, unless it finds another mount
>>     >that's a
>>     >>>         >better
>>     >>>         >>>     match to the URL, lws will automatically serve
>> files
>>     >>>         from that
>>     >>>         >dir
>>     >>>         >>>     when asked for things in /.  leaf.jpg is in that
>>     >>> directory.
>>     >>>         >>>
>>     >>>         >>>     The equivalent bit of lwsws conf is this
>>     >>>         >>>
>>     >>>         >>>             {
>>     >>>         >>>             "mountpoint": "/",
>>     >>>         >>>             "origin":
>>     >>>         "file:///usr/share/libwebsockets-test-server",
>>     >>>         >>>             "default": "test.html",
>>     >>>         >>>             }
>>     >>>         >>>
>>     >>>         >>>     Lws lets you also declare mounts that are bound
>> to a
>>     >>>         protocol
>>     >>>         >name.
>>     >>>         >>>
>>     >>>         >>>             {
>>     >>>         >>>              "mountpoint": "/dynamic",
>>     >>>         >>>              "origin": "callback://my-protocol-name"
>>     >>>         >>>             }
>>     >>>         >>>
>>     >>>         >>>     HTTP GET or POST down /dynamic/* will occur on the
>>     >>>         callback for
>>     >>>         >>>     "my-protocol-name". (The name /dynamic is not
>>     >meaningful,
>>     >>> it
>>     >>>         >could
>>     >>>         >>>     be anything).
>>     >>>         >>>
>>     >>>         >>>     So this way you can automate serving static
>> content
>>     >so
>>     >>>         it is no
>>     >>>         >>>     effort, and isolate serving dynamic content for a
>>     >region
>>     >>>         of the
>>     >>>         >URL
>>     >>>         >>>     space in a plugin, by name.
>>     >>>         >>>
>>     >>>         >>>         As you can see I am quite confusing with all
>> the
>>     >new
>>     >>>         >>>         possibilities. If
>>     >>>         >>>         my questions are not clear, I can send you
>> part
>>     >of my
>>     >>>         >code...
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>     It's difficult to answer in a more straightforward
>>     >way
>>     >>>         because
>>     >>>         >the
>>     >>>         >>>     best solution is pushing to make it as abstract as
>>     >>> possible
>>     >>>         >(lwsws,
>>     >>>         >>>     libuv, protocol plugins) but you want to implement
>>     >it all
>>     >>> in
>>     >>>         >code.
>>     >>>         >>>     So while explaining you should use plugins you're
>>     >also
>>     >>>         asking
>>     >>>         >how to
>>     >>>         >>>     do it without them.
>>     >>>         >>>
>>     >>>         >>>     Maybe you should better prototype it with the high
>>     >end
>>     >>>         stuff and
>>     >>>         >>>     when it works, look at reducing that to code,
>>     >including
>>     >>> the
>>     >>>         >plugin
>>     >>>         >>>     content direct in your app etc if you still want
>> to.
>>     >>>         >>>
>>     >>>         >>>     -Andy
>>     >>>         >>>
>>     >>>         >>>         Best regards,
>>     >>>         >>>         Thomas
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>         2016-05-18 9:06 GMT+02:00 Andy Green
>>     >>>         <andy at warmcat.com <mailto:andy at warmcat.com>
>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>
>>     >>>         >>>         <mailto:andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     ><mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>
>>     >>>         >>>         <mailto:andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     ><mailto:andy at warmcat.com <mailto:andy at warmcat.com>>
>>     >>>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>
>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>>>:
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>
>>     >>>         >>>              On May 18, 2016 2:46:13 PM GMT+08:00,
>>     >Thomas
>>     >>> Spitz
>>     >>>         >>>              <thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>
>>     >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>
>>     >>>         >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>
>>     >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>>
>>     >>>         >>>              <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>
>>     >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>
>>     >>>         >>>
>>     >>>         >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>
>>     >>>         <mailto:thomas.spitz at hestia-france.com
>>     <mailto:thomas.spitz at hestia-france.com>>>>> wrote:
>>     >>>         >>>              >Hello Andy,
>>     >>>         >>>              >
>>     >>>         >>>              >I think I will use plugins however
>>     >regarding
>>     >>>         lwsws I
>>     >>>         >will
>>     >>>         >>>         rather not
>>     >>>         >>>              >use it
>>     >>>         >>>
>>     >>>         >>>              That'll get you most of the benefits.
>>     >>>         >>>
>>     >>>         >>>              >because my application need to
>> computably
>>     >>>         >computationally
>>     >>>         >>>         (not
>>     >>>         >>>              >manually)
>>     >>>         >>>              >configure ports, redirect and protocols.
>>     >Thus,
>>     >>>         I think
>>     >>>         >>>         going through
>>     >>>         >>>              >JSON
>>     >>>         >>>              >files will certainly be more complex
>> than
>>     >>>         dealing with
>>     >>>         >>>         native C
>>     >>>         >>>              >structures... I might be wrong...
>>     >>>         >>>
>>     >>>         >>>              You know your application better than I
>>     >do...
>>     >>>         if it's
>>     >>>         >>>         easier to wire
>>     >>>         >>>              up with structs, no problem.
>>     >>>         >>>
>>     >>>         >>>              One observation though... JSON is easy to
>>     >>>         >machine-generate
>>     >>>         >>>         if need be.
>>     >>>         >>>
>>     >>>         >>>              -Andy
>>     >>>         >>>
>>     >>>         >>>               >Best regards,
>>     >>>         >>>               >Thomas
>>     >>>         >>>               >
>>     >>>         >>>               >
>>     >>>         >>>               >2016-05-17 20:48 GMT+02:00 Andy Green
>>     >>>         ><andy at warmcat.com <mailto:andy at warmcat.com>
>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>
>>     >>>         >>>         <mailto:andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     ><mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>
>>     >>>         >>>              <mailto:andy at warmcat.com
>>     <mailto:andy at warmcat.com>
>>     >>>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>
>>     <mailto:andy at warmcat.com <mailto:andy at warmcat.com>
>>     >>>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>>>>:
>>     >>>         >>>               >
>>     >>>         >>>               >>
>>     >>>         >>>               >>
>>     >>>         >>>               >> On May 18, 2016 1:43:04 AM GMT+08:00,
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20160613/c20db0ab/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: protocol_post_demo.c
Type: text/x-csrc
Size: 5922 bytes
Desc: not available
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20160613/c20db0ab/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-server.c
Type: text/x-csrc
Size: 15483 bytes
Desc: not available
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20160613/c20db0ab/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-server.h
Type: text/x-chdr
Size: 2612 bytes
Desc: not available
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20160613/c20db0ab/attachment-0002.bin>


More information about the Libwebsockets mailing list