extensions add api for user code option manipulation

Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
Andy Green 2016-04-08 09:45:49 +08:00
parent 150233d61f
commit c5376b141a
6 changed files with 133 additions and 17 deletions

View file

@ -394,3 +394,25 @@ LWS_SERVER_OPTION_LIBEV
LWS_SERVER_OPTION_LIBUV
to indicate it will use either of the event libraries.
Extension option control from user code
---------------------------------------
User code may set per-connection extension options now, using a new api
"lws_set_extension_option()".
This should be called from the ESTABLISHED callback like this
lws_set_extension_option(wsi, "permessage-deflate",
"rx_buf_size", "12"); /* 1 << 12 */
If the extension is not active (missing or not negotiated for the
connection, or extensions are disabled on the library) the call is
just returns -1. Otherwise the connection's extension has its
named option changed.
The extension may decide to alter or disallow the change, in the
example above permessage-deflate restricts the size of his rx
output buffer also considering the protocol's rx_buf_size member.

View file

@ -185,6 +185,24 @@ LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS. If you give this, non-ssl
connections to the server listen port are accepted and receive a 301
redirect to / on the same host and port using https://
8) User code may set per-connection extension options now, using a new api
"lws_set_extension_option()".
This should be called from the ESTABLISHED callback like this
lws_set_extension_option(wsi, "permessage-deflate",
"rx_buf_size", "12"); /* 1 << 12 */
If the extension is not active (missing or not negotiated for the
connection, or extensions are disabled on the library) the call is
just returns -1. Otherwise the connection's extension has its
named option changed.
The extension may decide to alter or disallow the change, in the
example above permessage-deflate restricts the size of his rx
output buffer also considering the protocol's rx_buf_size member.
New application lwsws
---------------------

View file

@ -41,6 +41,28 @@ const struct lws_ext_options lws_ext_pm_deflate_options[] = {
{ NULL, 0 }, /* sentinel */
};
static void
lws_extension_pmdeflate_restrict_args(struct lws *wsi,
struct lws_ext_pm_deflate_priv *priv)
{
int n, extra;
/* cap the RX buf at the nearest power of 2 to protocol rx buf */
n = LWS_MAX_SOCKET_IO_BUF;
if (wsi->protocol->rx_buffer_size)
n = wsi->protocol->rx_buffer_size;
extra = 7;
while (n >= 1 << (extra + 1))
extra++;
if (extra < priv->args[PMD_RX_BUF_PWR2]) {
priv->args[PMD_RX_BUF_PWR2] = extra;
lwsl_err(" Capping pmd rx to %d\n", 1 << extra);
}
}
LWS_VISIBLE int
lws_extension_callback_pm_deflate(struct lws_context *context,
const struct lws_extension *ext,
@ -56,6 +78,20 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
struct lws_ext_option_arg *oa;
switch (reason) {
case LWS_EXT_CB_NAMED_OPTION_SET:
oa = in;
if (!oa->option_name)
break;
for (n = 0; n < ARRAY_SIZE(lws_ext_pm_deflate_options); n++)
if (!strcmp(lws_ext_pm_deflate_options[n].name, oa->option_name))
break;
if (n == ARRAY_SIZE(lws_ext_pm_deflate_options))
break;
oa->option_index = n;
/* fallthru */
case LWS_EXT_CB_OPTION_SET:
oa = in;
lwsl_info("%s: option set: idx %d, %s, len %d\n", __func__,
@ -64,7 +100,10 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
priv->args[oa->option_index] = atoi(oa->start);
else
priv->args[oa->option_index] = 1;
lws_extension_pmdeflate_restrict_args(wsi, priv);
break;
case LWS_EXT_CB_OPTION_CONFIRM:
if (priv->args[PMD_SERVER_MAX_WINDOW_BITS] < 8 ||
priv->args[PMD_SERVER_MAX_WINDOW_BITS] > 15 ||
@ -94,7 +133,8 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
/* fill in pointer to options list */
if (in)
*((const struct lws_ext_options **)in) = lws_ext_pm_deflate_options;
*((const struct lws_ext_options **)in) =
lws_ext_pm_deflate_options;
/* fallthru */
@ -114,22 +154,7 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
priv->args[PMD_COMP_LEVEL] = 1;
priv->args[PMD_MEM_LEVEL] = 8;
/* cap the RX buf at the nearest power of 2 to protocol rx buf */
n = LWS_MAX_SOCKET_IO_BUF;
if (wsi->protocol->rx_buffer_size)
n = wsi->protocol->rx_buffer_size;
extra = 7;
while (n >= 1 << (extra + 1))
extra++;
if (extra < priv->args[PMD_RX_BUF_PWR2]) {
priv->args[PMD_RX_BUF_PWR2] = extra;
lwsl_err(" Capping pmd rx to %d\n", 1 << extra);
}
lwsl_err(" ok\n");
lws_extension_pmdeflate_restrict_args(wsi, priv);
break;
case LWS_EXT_CB_DESTROY:

View file

@ -27,6 +27,8 @@ lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi,
pending_close_quote = 0;
struct lws_ext_option_arg oa;
oa.option_name = NULL;
while (opts[count_options].name)
count_options++;
while (len) {
@ -315,3 +317,37 @@ lws_any_extension_handled(struct lws *wsi, enum lws_extension_callback_reasons r
return handled;
}
/**
* lws_set_extension_option(): set extension option if possible
*
* @wsi: websocket connection
* @ext_name: name of ext, like "permessage-deflate"
* @opt_name: name of option, like "rx_buf_size"
* @opt_val: value to set option to
*/
int
lws_set_extension_option(struct lws *wsi, const char *ext_name,
const char *opt_name, const char *opt_val)
{
struct lws_ext_option_arg oa;
int idx = 0;
/* first identify if the ext is active on this wsi */
while (idx < wsi->count_act_ext &&
strcmp(wsi->active_extensions[idx]->name, ext_name))
idx++;
if (idx == wsi->count_act_ext)
return -1; /* request ext not active on this wsi */
oa.option_name = opt_name;
oa.option_index = 0;
oa.start = opt_val;
oa.len = 0;
return wsi->active_extensions[idx]->callback(
wsi->context, wsi->active_extensions[idx], wsi,
LWS_EXT_CB_NAMED_OPTION_SET, wsi->act_ext_user[idx], &oa, 0);
}

View file

@ -2024,3 +2024,12 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt)
return 0;
}
#endif
#ifdef LWS_NO_EXTENSIONS
LWS_EXTERN int
lws_set_extension_option(struct lws *wsi, const char *ext_name,
const char *opt_name, const char *opt_val)
{
return -1;
}
#endif

View file

@ -514,6 +514,7 @@ enum lws_extension_callback_reasons {
LWS_EXT_CB_OPTION_DEFAULT = 23,
LWS_EXT_CB_OPTION_SET = 24,
LWS_EXT_CB_OPTION_CONFIRM = 25,
LWS_EXT_CB_NAMED_OPTION_SET = 26,
/****** add new things just above ---^ ******/
};
@ -1279,6 +1280,7 @@ struct lws_ext_options {
};
struct lws_ext_option_arg {
const char *option_name; /* may be NULL, option_index used then */
int option_index;
const char *start;
int len;
@ -1331,6 +1333,10 @@ extern int lws_extension_callback_pm_deflate(
struct lws *wsi, enum lws_extension_callback_reasons reason,
void *user, void *in, size_t len);
LWS_EXTERN int
lws_set_extension_option(struct lws *wsi, const char *ext_name,
const char *opt_name, const char *opt_val);
/**
* struct lws_context_creation_info - parameters to create context with