[Libwebsockets] protocol plugin

Andy Green andy at warmcat.com
Fri Feb 10 01:34:40 CET 2017



On 02/10/2017 08:06 AM, Joel Winarske wrote:
> Using - http://www.websocket.org/echo.html to test:

Hm echo is maybe not a good way to test this.

>
> In wireshark I see:
>  160.690778127.0.0.1127.0.0.1HTTP1128GET /activation?encoding=text 
> HTTP/1.1
>  180.691789127.0.0.1127.0.0.1HTTP434HTTP/1.1 101 Switching Protocols
> packets from client to server
> <no response from my protocol plugin>
> close from client
> close response from server
>
> In the log I see:
> [2017/02/09 15:04:57:8757] NOTICE: Creating Vhost '127.0.0.1' port 
> 7681, 3 protocols, IPv6 off
> [2017/02/09 15:04:57:8767] NOTICE:    mounting 
> callback://activation-protocol to /activation
> ...
> [2017/02/09 15:04:57:8777] NOTICE:  Using non-SSL mode
> [2017/02/09 15:04:57:8817] NOTICE:     vh 127.0.0.1 prot cmd-protocol 
> opt status
> [2017/02/09 15:04:57:8817] NOTICE:     vh 127.0.0.1 prot 
> activation-protocol opt status
> [2017/02/09 15:04:57:8827] NOTICE: activate: LWS_CALLBACK_PROTOCOL_INIT
> [2017/02/09 15:05:15:6913] NOTICE: Accepted wsi 002C3FC8 to context 
> 0020A890, tsi 0
> [2017/02/09 15:06:02:7518] NOTICE: Accepted wsi 022C5100 to context 
> 0020A890, tsi 0
>
> But when I send data from the websocket.org <http://websocket.org> 
> site, I never see the callback happen.  Not 
> even LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED.

"send data from"?
>
> It would seem the server is consuming the WS data packet, and not 
> making the callback.  What am I missing?
>
> In addition - when I select an unknown WS "mount", such as 
> "ws://localhost:7681/install", I get the identical behavior.
>
> Switching the vhosts name to "127.0.0.1", has no impact.
>
> When I use the test-client to test, I do see 
> LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED as expected, but it 
> ends with "CLIENT_CONNECTION_ERROR: dumb: (null)", after which I see 
> the WebSocket Close packet on the wire.  I instrumented what you 
> checked in yesterday.
>
> [2017/02/09 16:03:26:0400] NOTICE: dumb: connecting
> [2017/02/09 16:03:26:0410] ERR: getaddrinfo localhost -> 127.0.0.1
> [2017/02/09 16:03:26:0544] ERR: getaddrinfo localhost -> 127.0.0.1
> [2017/02/09 16:03:26:0544] NOTICE: dumb: 
> LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED [permessage-deflate]
> [2017/02/09 16:03:26:0544] NOTICE: dumb: 
> LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED [deflate-frame]
> [2017/02/09 16:03:26:0554] NOTICE: dumb: 
> LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER
> [2017/02/09 16:03:26:0554] NOTICE: dumb: 
> LWS_CALLBACK_CLIENT_CONNECTION_ERROR
> [2017/02/09 16:03:26:0564] ERR: CLIENT_CONNECTION_ERROR: dumb: (null)

I am not 100% sure what you are trying to do overall, but notice that 
with ws, the subprotocol header is optional.

If it doesn't come, the peers are just magically supposed to know what 
default protocol to speak on the wire, instead of affirmatively 
negotiating it.

"Echo" is one of these lazy servers that does not tell the protocol.  In 
that case lws falls back to protocols[0] by default, which may not be 
the protocol you are looking at.

You can override who will be the default

To indicate that a protocol should be used when no Protocol: header is sent
by the client, you can use "default": "1"

```
              "ws-protocols": [{
                "warmcat-timezoom": {
                  "status": "ok",
                  "default": "1"
                }
              }]
```

-Andy


>
> My current config:
> {
>  "vhosts": [{
>      "name": "localhost",
>      "port": "7681",
>      "mounts": [{
>        "mountpoint": "/activation",
>        "origin": "callback://activation-protocol"
> },{
>          "mountpoint": "/",
>          "origin": "file://c:/etc/lwsws/www/",
>          "default": "index.html",
>          "cache-max-age": "60",
>          "cache-reuse": "1",
>          "cache-revalidate": "1",
>          "cache-intermediaries": "0",
>     "extra-mimetypes": {
>         ".hbs": "text/x-handlebars-template",
> ".json": "text/json",
>     }
> },{
>        "mountpoint": "/sys",
>        "origin": "callback://cmd-protocol",
>   "pmo":[{"api":"2"}]
> },{
>        "mountpoint": "/ui/fileCount",
>        "origin": "callback://cmd-protocol",
>   "pmo":[{"api":"3"}]
> },{
>        "mountpoint": "/prop",
>        "origin": "callback://cmd-protocol",
>   "pmo":[{"api":"1"}]
> }],
>      "ws-protocols": [{
>          "activation-protocol": {
> "status": "ok"
> },
> "cmd-protocol": {
> "status": "ok"
> }
>      }]
>     }
>   ]
> }
>
>
> On Sun, Feb 5, 2017 at 1:14 PM, Andy Green <andy at warmcat.com 
> <mailto:andy at warmcat.com>> wrote:
>
>
>
>     On February 6, 2017 2:56:03 AM GMT+08:00, Joel Winarske
>     <joel.winarske at gmail.com <mailto:joel.winarske at gmail.com>> wrote:
>     >It seems it only looks at the first defined vhost.  If I move the
>     >primary
>     >site vhost to the bottom of the config, it no longer loads the site,
>     >and I
>     >see LWS_CALLBACK_HTTP.
>
>     Determining which vhost to serve happens one of two ways...
>
>      - if ssl is in use, the SNI feature is used to match what it
>     sends against the vhost name.  This allows use of the correct cert
>     for the vhost before the ssl tunnel is established.
>
>      - if no ssl, the Host: header contents are matched against the
>     vhost names.
>
>     So turn up the logging and see what you're sending from your
>     client for Host:.
>
>     For backwards compatibility if lws only has one default vhost all
>     protocols are enabled on it.  With multiple vhosts they must be
>     enabled individually on the vhost you want to have access to them.
>
>     -Andy
>
>     >On Sun, Feb 5, 2017 at 9:50 AM, Joel Winarske
>     <joel.winarske at gmail.com <mailto:joel.winarske at gmail.com>>
>     >wrote:
>     >
>     >> Here is my config.  I see protocol init happen for each, but
>     I'm not
>     >> seeing LWS_CALLBACK_HTTP.  If I revert to single vhost, many
>     mounts -
>     >init,
>     >> and LWS_CALLBACK_HTTP happen.  Albeit I can't differentiate what is
>     >what.
>     >>
>     >> {
>     >>  "vhosts": [{
>     >>      "name": "localhost",
>     >>      "port": "7681",
>     >>      "mounts": [{
>     >>          "mountpoint": "/ui",
>     >>          "origin": "file://c:/etc/lwsws/www",
>     >>          "default": "index.html",
>     >>          "cache-max-age": "60",
>     >>          "cache-reuse": "1",
>     >>          "cache-revalidate": "1",
>     >>          "cache-intermediaries": "0",
>     >>      "extra-mimetypes": {
>     >>          ".hbs": "text/x-handlebars-template",
>     >>  ".json": "text/json"
>     >>      }
>     >>  }]
>     >>  }, {
>     >>      "name": "fileCount",
>     >>      "port": "7681",
>     >>      "mounts": [{
>     >>        "mountpoint": "/ui/fileCount",
>     >>        "origin": "callback://cmd-protocol"
>     >>  }],
>     >>        "ws-protocols": [{
>     >>      "cmd-protocol": {
>     >>       "api" : "3",
>     >>        "status": "ok"
>     >>      }
>     >>        }]
>     >>      }, {
>     >>      "name": "prop",
>     >>      "port": "7681",
>     >>      "mounts": [{
>     >>        "mountpoint": "/prop",
>     >>        "origin": "callback://cmd-protocol"
>     >>  }],
>     >>        "ws-protocols": [{
>     >>      "cmd-protocol": {
>     >>       "api" : "1",
>     >>        "status": "ok"
>     >>      }
>     >>        }]
>     >>      }, {
>     >>      "name": "sys",
>     >>      "port": "7681",
>     >>      "mounts": [{
>     >>        "mountpoint": "/sys",
>     >>        "origin": "callback://cmd-protocol"
>     >>  }],
>     >>        "ws-protocols": [{
>     >>      "cmd-protocol": {
>     >>       "api" : "2",
>     >>        "status": "ok"
>     >>      }
>     >>        }]
>     >>      }, {
>     >>     "name": "rest",
>     >>      "port": "7681",
>     >>      "mounts": [{
>     >>        "mountpoint": "/rest",
>     >>        "origin": "callback://cmd-protocol"
>     >>  }],
>     >>        "ws-protocols": [{
>     >>      "cmd-protocol": {
>     >>       "api" : "4",
>     >>        "status": "ok"
>     >>      }
>     >>        }]
>     >>      }
>     >>   ]
>     >> }
>     >>
>     >> Something else odd I am seeing, I have no valid WS protocols
>     defined,
>     >yet
>     >> the server accepts all client WS requests and indicates it's
>     switched
>     >> protocols.  Am I missing something here?
>     >>
>     >>
>     >>    1. Request URL:
>     >>    ws://localhost:7681/activation
>     >>    2. Request Method:
>     >>    GET
>     >>    3. Status Code:
>     >>    101 Switching Protocols
>     >>
>     >>
>     >> On Wed, Feb 1, 2017 at 10:30 PM, Andy Green <andy at warmcat.com
>     <mailto:andy at warmcat.com>> wrote:
>     >>
>     >>>
>     >>>
>     >>> On 02/02/2017 02:17 PM, Joel Winarske wrote:
>     >>>
>     >>>> Say I want to implement a single plugin for multiple mount
>     points.
>     >In
>     >>>> the protocol callback, how do I get the mount point string value?
>     >Do I
>     >>>> have to examine the header, or is it already available somewhere?
>     >>>>
>     >>>
>     >>> The right way to look at it is you created a plugin with a single
>     >>> protocol.
>     >>>
>     >>> It happened that multiple mountpoints, usually on a different
>     vhost
>     >each
>     >>> time, wanted to mount an instance of that protocol somewhere in
>     >their URL
>     >>> space.
>     >>>
>     >>> As far as that goes, in itself the protocol callback is not
>     aware of
>     >the
>     >>> mountpoint, and the mounts are all treated the same, although you
>     >can use
>     >>> per-vhost structs in the callback to mean that mounted protocol
>     >instances
>     >>> on each vhost can do things separately.
>     >>>
>     >>> To make things more useful, you can pass in "pvo", per-vhost
>     options
>     >when
>     >>> you enable the protocol for each vhost individually.  For example
>     >the
>     >>> server-status URL I sent before has its protocol enabled like this
>     >>>
>     >>>        "lws-server-status": {
>     >>>          "status": "ok",
>     >>>          "update-ms": "5000",
>     >>>          "filepath": "/sys/class/thermal/thermal_zone0/temp",
>     >>>          "filepath": "/proc/version",
>     >>>          "hide-vhosts": "1"
>     >>>         },
>     >>>
>     >>> So you could just as easily enable the protocol on another vhost,
>     >but
>     >>> with different settings.
>     >>>
>     >>> There are also "pmo", per-mount options the plugin can
>     access.  But
>     >pvo
>     >>> are probably want you want if each mount is on a different vhost.
>     >>>
>     >>> You can see how the server status plugin gets ahold of the pvo at
>     >init
>     >>>
>     >>> https://github.com/warmcat/libwebsockets/blob/master/plugins
>     <https://github.com/warmcat/libwebsockets/blob/master/plugins>
>     >>> /protocol_lws_server_status.c
>     >>>
>     >>> since he stashes them in his per-vhost struct, he can act
>     completely
>     >>> differently simultaneously depndning on the vhost you access him
>     >from.
>     >>>
>     >>> -Andy
>     >>>
>     >>>
>     >>>> Thanks!
>     >>>>
>     >>>>
>     >>>> _______________________________________________
>     >>>> 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>
>     >>>>
>     >>>
>     >>>
>     >>
>
>




More information about the Libwebsockets mailing list