[Libwebsockets] Logging WS HS

Olivier Langlois olivier at olivierlanglois.net
Mon Feb 24 05:42:23 CET 2020


On Mon, 2020-02-24 at 02:30 +0000, Andy Green wrote:
> On February 23, 2020 10:02:42 PM GMT, Olivier Langlois <
> olivier at olivierlanglois.net
> > wrote:
> > On Sun, 2020-02-16 at 18:12 +0000, Andy Green wrote:
> > > > You don't need that info when developing a server but when
> > 
> > developing a
> > > > client to use a service that you don't control, you are
> > > > vulnerable
> > 
> > to
> > > > unannounced server changes. One day the HS works. Then it
> > > > doesn't.
> > 
> > With
> > > > those logs, a simple glance at the logs would show what has
> > > > changed
> > 
> > and
> > > > we aren't talking about multi-MB logs. It is 1-2 hundred extra
> > 
> > bytes.
> > > > IMHO, this is something that even lightweight systems could
> > > > afford.
> > > > 
> > > > Another scenario that would be interesting to have some more
> > > > help
> > 
> > from
> > > > lws is when the server returns a HTTP error code during the WS
> > > > HS.
> > 
> > ie:
> > > > I get a 503. I suspect that along with it, in the reply body,
> > > > the
> > > > server provides some useful info such as: 'Service disabled for
> > > > maintenance. Service resuming expected at HH:MM'. Recuperating
> > 
> > those
> > > > messages is something that I would like lws to help with.
> > > 
> > > Feel free to propose a patch, but at that point, it's http body,
> > 
> > unrelated to ws protocol, so this is probably a job about generic
> > handling of http bodies for 4xx / 5xx... not sure if it already
> > appears
> > at the cb or the transaction is abandoned.
> > 
> > Andy,
> > 
> > I think that I have found a way to do it without any modification
> > on
> > the lws side (well almost).
> > 
> > I need to test this option to validate that it works but I'm not
> > seeing
> > why it wouldn't. FYI, my server is using chunked encoding.
> > 
> > In my callback:
> > 
> >      case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: {
> >           int code = lws_hdr_http_response(wsi);
> >           if (code == 503) {
> >               char buf[4096];
> >               char *ptr = buf;
> >               int len = sizeof(buf);
> >               lws_http_client_read(wsi, &ptr, &len);
> >           }
> >         }
> >         break;
> >       case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
> >           INFO2("HTTP 503 reply body:\n%.*s", len, (const char
> > *)in);
> >         break;
> > 
> > Ok, yes I wrote a small utility function. Feel free to add it to
> > lws:
> > 
> > LWS_VISIBLE int
> > lws_hdr_http_response(struct lws *wsi)
> > {
> >         if (!wsi->http.ah)
> >                 return 0;
> >         return wsi->http.ah->http_response;
> > }
> > 
> > because otherwise, what is the alternative?
> 
> We're talking about this, which has been around a few years?
> 
> https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-client.h#n232-244
> 
> 
> > 1. lws_hdr_copy(wsi, buf, 4, WSI_TOKEN_HTTP_COLON_STATUS);
> 
> COLON_STATUS refers to the h2 header :status, it's only present when
> h2 was negotiated.  Lws apis take care to conceal from the user code
> almost completely whether it's actually doing h1 or h2 / hpack
> underneath... even if you thought your user code was talking to an h2
> server that's something only discovered after the connection.
> 

My mistake. I did misread the following code in
roles/http/client/client.c:

        if (!wsi->client_h2_substream) {
                p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
                if (wsi->do_ws && !p) {
                        lwsl_info("no URI\n");
                        cce = "HS: URI missing";
                        goto bail3;
                }
                if (!p) {
                        p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP1_0);
                        wsi->http.conn_type = HTTP_CONNECTION_CLOSE;
                }
                if (!p) {
                        cce = "HS: URI missing";
                        lwsl_info("no URI\n");
                        goto bail3;
                }
        } else {
                p = lws_hdr_simple_ptr(wsi,
WSI_TOKEN_HTTP_COLON_STATUS);
                if (!p) {
                        cce = "HS: :status missing";
                        lwsl_info("no status\n");
                        goto bail3;
                }
        }
        n = atoi(p);
        if (ah)
                ah->http_response = n;

My mistake does in fact add an extra argument for integrating my
suggested function lws_hdr_http_response(). ie: to eliminate the risk
of fetching the wrong header token value...




More information about the Libwebsockets mailing list