char pkt[1024];
char *p = &pkt[0];
const char *pc;
+ const char *c;
+ int more = 1;
int okay = 0;
+ char ext_name[128];
struct lws_tokens eff_buf;
int more = 1;
int ext_count = 0;
goto bail2;
}
+
+ /* instantiate the accepted extensions */
+
+ if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len)
+ goto check_accept;
+
+ /*
+ * break down the list of server accepted extensions
+ * and go through matching them or identifying bogons
+ */
+
+ c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
+ n = 0;
+ while (more) {
+
+ if (*c && *c != ',') {
+ ext_name[n] = *c++;
+ if (n < sizeof(ext_name) - 1)
+ n++;
+ continue;
+ }
+ ext_name[n] = '\0';
+ if (!*c)
+ more = 0;
+
+ /* check we actually support it */
+
+ n = 0;
+ ext = wsi->protocol->owning_server->extensions;
+ while (ext && ext->callback) {
+
+ if (strcmp(ext_name, ext->name)) {
+ ext++;
+ continue;
+ }
+
+ n = 1;
+
+ /* instantiate the extension on this conn */
+
+ wsi->active_extensions_user[
+ wsi->count_active_extensions] =
+ malloc(ext->per_session_data_size);
+ wsi->active_extensions[
+ wsi->count_active_extensions] = ext;
+
+ /* allow him to construct his context */
+
+ ext->callback(wsi->protocol->owning_server,
+ wsi, LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
+ wsi->active_extensions_user[
+ wsi->count_active_extensions], NULL, 0);
+
+ wsi->count_active_extensions++;
+
+ ext++;
+ }
+
+ if (n == 0) {
+ fprintf(stderr, "Server said we should use"
+ "an unknown extension '%s'!\n", ext_name);
+ goto bail2;
+ }
+
+ n = 0;
+ }
+
+
check_accept:
if (wsi->ietf_spec_revision == 0) {
enum libwebsocket_extension_callback_reasons {
LWS_EXT_CALLBACK_CONSTRUCT,
+ LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
LWS_EXT_CALLBACK_DESTROY,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
* extension a chance to initialize its connection context found
* in @user.
*
+ * LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
+ * but called when client is instantiating this extension. Some
+ * extensions will work the same on client and server side and then
+ * you can just merge handlers for both CONSTRUCTS.
+ *
* LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
- * user data is deleted.
+ * user data is deleted. This same callback is used whether you
+ * are in client or server instantiation context.
*
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
extension a chance to initialize its connection context found
in <tt><b>user</b></tt>.
</blockquote>
+<h3>LWS_EXT_CALLBACK_CLIENT_CONSTRUCT</h3>
+<blockquote>
+same as LWS_EXT_CALLBACK_CONSTRUCT
+but called when client is instantiating this extension. Some
+extensions will work the same on client and server side and then
+you can just merge handlers for both CONSTRUCTS.
+</blockquote>
<h3>LWS_EXT_CALLBACK_DESTROY</h3>
<blockquote>
called when the connection the extension was
being used on is about to be closed and deallocated. It's the
last chance for the extension to deallocate anything it has
allocated in the user data (pointed to by <tt><b>user</b></tt>) before the
-user data is deleted.
+user data is deleted. This same callback is used whether you
+are in client or server instantiation context.
</blockquote>
<h3>LWS_EXT_CALLBACK_PACKET_RX_PREPARSE</h3>
<blockquote>