diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index ec71d799e..444357bc9 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -555,6 +555,9 @@ libwebsocket_service_fd(struct libwebsocket_context *context, int okay = 0; struct lws_tokens eff_buf; int more = 1; + int ext_count = 0; + struct libwebsocket_extension *ext; + #ifdef LWS_OPENSSL_SUPPORT char ssl_err_buf[512]; #endif @@ -1119,8 +1122,47 @@ libwebsocket_service_fd(struct libwebsocket_context *context, if (wsi->c_protocol) p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a", wsi->c_protocol); - p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", - wsi->ietf_spec_revision); + + /* tell the server what extensions we could support */ + + p += sprintf(p, "Sec-WebSocket-Extensions: "); + + ext =context->extensions; + while (ext && ext->callback) { + + n = 0; + n = context->protocols[0].callback(context, wsi, + LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, + wsi->user_space, (char *)ext->name, 0); + + /* + * zero return from callback means + * go ahead and allow the extension, + * it's what we get if the callback is + * unhandled + */ + + if (n) { + ext++; + continue; + } + + /* apply it */ + + if (ext_count) + *p++ = ','; + p += sprintf(p, ext->name); + ext_count++; + + ext++; + } + + p += sprintf(p, "\x0d\x0a"); + + if (wsi->ietf_spec_revision) + p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", + wsi->ietf_spec_revision); + /* give userland a chance to append, eg, cookies */ context->protocols[0].callback(context, wsi, diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index c5ca187cc..3b2c11a1f 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -64,6 +64,7 @@ enum libwebsocket_callback_reasons { LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, + LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, /* external poll() management support */ LWS_CALLBACK_ADD_POLL_FD, LWS_CALLBACK_DEL_POLL_FD, @@ -334,6 +335,15 @@ struct libwebsocket_context; * content during this callback might not be useful for anything. * Notice this callback comes to protocols[0]. * + * LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client + * connection is being prepared to start a handshake to a server, + * each supported extension is checked with protocols[0] callback + * with this reason, giving the user code a chance to suppress the + * claim to support that extension by returning non-zero. If + * unhandled, by default 0 will be returned and the extension + * support included in the header to the server. Notice this + * callback comes to protocols[0]. + * * The next four reasons are optional and only need taking care of if you * will be integrating libwebsockets sockets into an external polling * array. diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 46933879c..a82383bc9 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -664,6 +664,17 @@ valid. Note though at this time the ESTABLISHED callback hasn't happened yet so if you initialize user content there, user content during this callback might not be useful for anything. Notice this callback comes to protocols[0]. + +

LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED

+
+When a client +connection is being prepared to start a handshake to a server, +each supported extension is checked with protocols[0] callback +with this reason, giving the user code a chance to suppress the +claim to support that extension by returning non-zero. If +unhandled, by default 0 will be returned and the extension +support included in the header to the server. Notice this +callback comes to protocols[0].

The next four reasons are optional and only need taking care of if you will be integrating libwebsockets sockets into an external polling