1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ss: rx metadata

At the moment you can define and set per-stream metadata at the client,
which will be string-substituted and if configured in the policy, set in
related outgoing protocol specific content like h1 headers.

This patch extends the metadata concept to also check incoming protocol-
specific content like h1 headers and where it matches the binding in the
streamtype's metadata entry, make it available to the client by name, via
a new lws_ss_get_metadata() api.

Currently warmcat.com has additional headers for

server: lwsws                (well-known header name)
test-custom-header: hello    (custom header name)

minimal-secure-streams test is updated to try to recover these both
in direct and -client (via proxy) versions.  The corresponding metadata
part of the "mintest" stream policy from warmcat.com is

                        {
                                "srv": "server:"
                        }, {
                                "test": "test-custom-header:"
                        },

If built direct, or at the proxy, the stream has access to the static
policy metadata definitions and can store the rx metadata in the stream
metadata allocation, with heap-allocated a value.  For client side that
talks to a proxy, only the proxy knows the policy, and it returns rx
metadata inside the serialized link to the client, which stores it on
the heap attached to the stream.

In addition an optimization for mapping static policy metadata definitions
to individual stream handle metadata is changed to match by name.
This commit is contained in:
Andy Green 2020-09-10 06:43:43 +01:00
parent d41bb16074
commit 101b474217
17 changed files with 473 additions and 47 deletions

View file

@ -52,6 +52,7 @@
#define lws_ss_get_context lws_sspc_get_context
#define lws_ss_rideshare lws_sspc_rideshare
#define lws_ss_set_metadata lws_sspc_set_metadata
#define lws_ss_get_metadata lws_sspc_get_metadata
#define lws_ss_add_peer_tx_credit lws_sspc_add_peer_tx_credit
#define lws_ss_get_est_peer_tx_credit lws_sspc_get_est_peer_tx_credit
#define lws_ss_start_timeout lws_sspc_start_timeout
@ -190,6 +191,10 @@ LWS_VISIBLE LWS_EXTERN int
lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
const void *value, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_sspc_get_metadata(struct lws_sspc_handle *h, const char *name,
const void **value, size_t *len);
LWS_VISIBLE LWS_EXTERN int
lws_sspc_add_peer_tx_credit(struct lws_sspc_handle *h, int32_t add);

View file

@ -154,13 +154,23 @@ enum {
_LWSSS_HBI_COUNT /* always last */
};
/*
* This does for both the static policy metadata entry, and the runtime metadata
* handling object.
*/
typedef struct lws_ss_metadata {
struct lws_ss_metadata *next;
const char *name;
void *value;
size_t length;
uint8_t value_on_lws_heap; /* proxy does this */
uint8_t value_on_lws_heap; /* proxy + rx metadata does this */
uint8_t value_is_http_token; /* valid if set by policy */
uint8_t value_length; /* only valid if set by policy */
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
uint8_t pending_onward:1;
#endif
} lws_ss_metadata_t;

View file

@ -132,6 +132,14 @@
* - 1: 00, 04
* - 3: 4-byte MSB-first addition tx credit bytes
*
* - Proxied rx metadata
*
* - 0: LWSSS_SER_RXPRE_METADATA
* - 1: 2-byte MSB-first rest-of-frame length
* - 3: 1-byte metadata name length
* - 4: metadata name
* - ...: metadata value (for rest of packet)
*
* - Proxied state
*
* - 0: LWSSS_SER_RXPRE_CONNSTATE
@ -227,6 +235,7 @@ enum {
LWSSS_SER_RXPRE_CREATE_RESULT,
LWSSS_SER_RXPRE_CONNSTATE,
LWSSS_SER_RXPRE_TXCR_UPDATE,
LWSSS_SER_RXPRE_METADATA,
LWSSS_SER_RXPRE_TLSNEG_ENCLAVE_SIGN,
/* tx (send by client) prepends for proxied connections */
@ -564,6 +573,37 @@ LWS_VISIBLE LWS_EXTERN int
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
const void *value, size_t len);
/**
* lws_ss_get_metadata() - get current value of stream metadata item
*
* \param h: secure streams handle
* \param name: metadata name from the policy
* \param value: pointer to pointer to be set to point at the value
* \param len: pointer to size_t to set to the length of the value
*
* Binds user-managed data to the named metadata item from the ss policy.
* If present, the metadata item is handled in a protocol-specific way using
* the associated policy information. For example, in the policy
*
* "\"metadata\":" "["
* "{\"uptag\":" "\"X-Upload-Tag:\"},"
* "{\"ctype\":" "\"Content-Type:\"},"
* "{\"xctype\":" "\"\"}"
* "],"
*
* when the policy is using h1 is interpreted to add h1 headers of the given
* name with the value of the metadata on the left.
*
* Return 0 if *value and *len set OK, or nonzero if, eg, metadata name does
* not exist on the streamtype.
*
* The pointed-to values may only exist until the next time around the event
* loop.
*/
LWS_VISIBLE LWS_EXTERN int
lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
const void **value, size_t *len);
/*
* lws_ss_server_ack() - indicate how we feel about what the server has sent
*

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -35,6 +35,22 @@ lws_token_to_string(enum lws_token_indexes token)
return (unsigned char *)set[token];
}
/*
* Return http header index if one matches slen chars of s, or -1
*/
int
lws_http_string_to_known_header(const char *s, size_t slen)
{
int n;
for (n = 0; n < (int)LWS_ARRAY_SIZE(set); n++)
if (!strncmp(set[n], s, slen))
return n;
return -1;
}
int
lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name,
const unsigned char *value, int length,

View file

@ -327,6 +327,9 @@ lws_sul_http_ah_lifecheck(lws_sorted_usec_list_t *sul);
uint8_t *
lws_http_multipart_headers(struct lws *wsi, uint8_t *p);
int
lws_http_string_to_known_header(const char *s, size_t slen);
enum {
CCTLS_RETURN_ERROR = -1,
CCTLS_RETURN_DONE = 0,

View file

@ -326,6 +326,33 @@ interval described in the associated retry / backoff selection, are important
enough to wake the whole system from low power suspend so they happen on
schedule.
### `metadata`
This allows declaring basically dynamic symbol names to be used by the streamtype,
along with an optional mapping to a protocol-specific entity such as a given
http header. Eg:
```
"metadata": [ { "myname": "" }, { "ctype": "content-type:" } ],
```
In this example "ctype" is associated with the http header "content-type" while
"myname" doesn't have any association to a header.
Symbol names may be used in the other policy for the streamtype for string
substitution using the syntax like `xxx${myname}yyy`, forward references are
valid but the scope of the symbols is just the streamtype the metadata is
defined for.
Client code can set metadata by name, using the `lws_ss_set_metadata()` api, this
should be done before a transaction. And for metadata associated with a
protocol-specific entity, like http headers, if incoming responses contain the
mentioned header, the metadata symbol is set to that value at the client before
any rx proceeds.
Metadata continues to work the same for the client in the case it is proxying its
connectivity, metadata is passed in both directions serialized over the proxy link.
## http transport
### `http_method`

View file

@ -59,16 +59,35 @@ int
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
const void *value, size_t len)
{
lws_ss_metadata_t *omd = lws_ss_policy_metadata(h->policy, name);
lws_ss_metadata_t *omd = lws_ss_get_handle_metadata(h, name);
if (!omd) {
lwsl_info("%s: unknown metadata %s\n", __func__, name);
return 1;
}
h->metadata[omd->length].name = name;
h->metadata[omd->length].value = (void *)value;
h->metadata[omd->length].length = len;
// lwsl_notice("%s: %s %s\n", __func__, name, (const char *)value);
omd->name = name;
omd->value = (void *)value;
omd->length = len;
return 0;
}
int
lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
const void **value, size_t *len)
{
lws_ss_metadata_t *omd = lws_ss_get_handle_metadata(h, name);
if (!omd) {
lwsl_info("%s: unknown metadata %s\n", __func__, name);
return 1;
}
*value = omd->value;
*len = omd->length;
return 0;
}
@ -76,12 +95,13 @@ lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
lws_ss_metadata_t *
lws_ss_get_handle_metadata(struct lws_ss_handle *h, const char *name)
{
lws_ss_metadata_t *omd = lws_ss_policy_metadata(h->policy, name);
int n = 0;
if (!omd)
return NULL;
for (n = 0; n < h->policy->metadata_count; n++)
if (!strcmp(name, h->metadata[n].name))
return &h->metadata[n];
return &h->metadata[omd->length];
return NULL;
}
lws_ss_metadata_t *

View file

@ -642,8 +642,20 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
a->curr[LTY_POLICY].p->metadata->value = q;
memcpy(q, ctx->buf, ctx->npos);
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
/*
* Check the metadata value part to see if it's a well-known
* http header... if so, 0xff means no header string match else
* it's the well-known header index
*/
a->curr[LTY_POLICY].p->metadata->value_is_http_token = (uint8_t)
lws_http_string_to_known_header(ctx->buf, ctx->npos);
#endif
a->curr[LTY_POLICY].p->metadata->length = /* the index in handle->metadata */
a->curr[LTY_POLICY].p->metadata_count++;
a->curr[LTY_POLICY].p->metadata->value_length = ctx->npos;
break;
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)

View file

@ -200,6 +200,7 @@ struct lws_ss_serialization_parser {
uint64_t ust_pwait;
lws_ss_metadata_t *ssmd;
uint8_t *rxmetaval;
int ps;
int ctr;
@ -259,6 +260,7 @@ typedef struct lws_sspc_handle {
struct lws_ss_serialization_parser parser;
lws_dll2_owner_t metadata_owner;
lws_dll2_owner_t metadata_owner_rx;
struct lws_dll2 client_list;
struct lws_tx_credit txc;
@ -373,6 +375,9 @@ lws_ss_destroy_dll(struct lws_dll2 *d, void *user);
int
lws_sspc_destroy_dll(struct lws_dll2 *d, void *user);
void
lws_sspc_rxmetadata_destroy(lws_sspc_handle_t *h);
int
lws_ss_policy_set(struct lws_context *context, const char *name);

View file

@ -152,26 +152,21 @@ around:
}
#endif
/*
* This converts any set metadata items into outgoing http headers
*/
static int
lws_apply_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
uint8_t **pp, uint8_t *end)
{
int m;
lws_ss_metadata_t *polmd = h->policy->metadata;
int m = 0;
for (m = 0; m < h->policy->metadata_count; m++) {
lws_ss_metadata_t *polmd;
while (polmd) {
/* has to have a header string listed */
if (!h->metadata[m].value)
continue;
/* has to have a non-empty header string */
polmd = lws_ss_policy_metadata_index(h->policy, m);
assert(polmd);
if (!polmd)
return -1;
/* has to have a value */
if (polmd->value && ((uint8_t *)polmd->value)[0]) {
if (lws_add_http_header_by_name(wsi,
polmd->value,
@ -179,6 +174,9 @@ lws_apply_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
(int)h->metadata[m].length, pp, end))
return -1;
}
m++;
polmd = polmd->next;
}
/*
@ -204,6 +202,111 @@ lws_apply_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
return 0;
}
/*
* Check if any metadata headers present in the server headers, and record
* them into the associated metadata item if so.
*/
static int
lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
{
lws_ss_metadata_t *polmd = h->policy->metadata, *omd;
int n, m = 0;
while (polmd) {
if (polmd->value_is_http_token != 0xff) {
/* it's a well-known header token */
n = lws_hdr_total_length(wsi, polmd->value_is_http_token);
if (n) {
const char *cp = lws_hdr_simple_ptr(wsi,
polmd->value_is_http_token);
/*
* it's present on the wsi, we want to
* set the related metadata name to it then
*/
lws_ss_set_metadata(h, polmd->name, cp, n);
/*
* ...and because we are doing it from parsing
* onward rx, we want to mark the metadata as
* needing passing to the client
*/
omd = lws_ss_get_handle_metadata(h, polmd->name);
assert(!strcmp(omd->name, polmd->name));
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
omd->pending_onward = 1;
#endif
}
}
#if defined(LWS_WITH_CUSTOM_HEADERS)
else
/* has to have a non-empty header string */
if (polmd->value && ((uint8_t *)polmd->value)[0]) {
char *p;
/*
* Can it be a custom header?
*/
n = lws_hdr_custom_length(wsi,
(const char *)polmd->value,
polmd->value_length);
if (n > 0) {
p = lws_malloc(n + 1, __func__);
if (!p)
return 1;
/* if needed, free any previous value */
if (polmd->value_on_lws_heap) {
lws_free(polmd->value);
polmd->value_on_lws_heap = 0;
}
/*
* copy the named custom header value into the
* malloc'd buffer
*/
if (lws_hdr_custom_copy(wsi, p, n + 1,
(const char *)polmd->value,
polmd->value_length) < 0) {
lws_free(p);
return 1;
}
omd = lws_ss_get_handle_metadata(h,
polmd->name);
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
omd->pending_onward = 1;
#endif
omd->value = p;
omd->length = (size_t)n;
omd->value_on_lws_heap = 1;
}
}
#endif
m++;
polmd = polmd->next;
}
return 0;
}
static const uint8_t blob_idx[] = {
LWS_SYSBLOB_TYPE_AUTH,
LWS_SYSBLOB_TYPE_DEVICE_SERIAL,
@ -295,6 +398,12 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
h->u.http.good_respcode = (status >= 200 && status < 300);
// lwsl_err("%s: good resp %d %d\n", __func__, status, h->u.http.good_respcode);
if (lws_extract_metadata(h, wsi)) {
lwsl_info("%s: rx metadata extract failed\n", __func__);
return -1;
}
if (h->u.http.good_respcode)
lwsl_info("%s: Connected streamtype %s, %d\n", __func__,
h->policy->streamtype, status);
@ -747,6 +856,9 @@ secstream_connect_munge_h1(lws_ss_handle_t *h, char *buf, size_t len,
if (!pbasis)
return 0;
/* uncomment to force h1 */
// i->alpn = "http/1.1";
#if defined(LWS_WITH_SS_RIDESHARE)
if (h->policy->flags & LWSSSPOLF_HTTP_MULTIPART)
i->ssl_connection |= LCCSCF_HTTP_MULTIPART_MIME;

View file

@ -302,8 +302,6 @@ callback_sspc_client(struct lws *wsi, enum lws_callback_reasons reason,
case LPCSCLI_OPERATIONAL:
lwsl_notice("%s: LPCSCLI_OPERATIONAL\n", __func__);
/*
*
* - Do we need to prioritize sending any metadata
@ -486,6 +484,19 @@ lws_sspc_destroy_dll(struct lws_dll2 *d, void *user)
return 0;
}
void
lws_sspc_rxmetadata_destroy(lws_sspc_handle_t *h)
{
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
lws_dll2_get_head(&h->metadata_owner_rx)) {
lws_sspc_metadata_t *md =
lws_container_of(d, lws_sspc_metadata_t, list);
lws_dll2_remove(&md->list);
lws_free(md);
} lws_end_foreach_dll_safe(d, d1);
}
void
lws_sspc_destroy(lws_sspc_handle_t **ph)
@ -530,6 +541,8 @@ lws_sspc_destroy(lws_sspc_handle_t **ph)
} lws_end_foreach_dll_safe(d, d1);
lws_sspc_rxmetadata_destroy(h);
h->ssi.state(m, NULL, LWSSSCS_DESTROYING, 0);
*ph = NULL;
free(h);
@ -726,6 +739,36 @@ lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
return _lws_sspc_set_metadata(h, name, value, len, 0);
}
int
lws_sspc_get_metadata(struct lws_sspc_handle *h, const char *name,
const void **value, size_t *len)
{
lws_sspc_metadata_t *md;
/*
* client side does not have access to policy
* and any metadata are new to it each time,
* we allocate them, removing any existing with
* the same name first
*/
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
lws_dll2_get_head(&h->metadata_owner_rx)) {
md = lws_container_of(d,
lws_sspc_metadata_t, list);
if (!strcmp(md->name, name)) {
*len = md->len;
*value = &md[1];
return 0;
}
} lws_end_foreach_dll_safe(d, d1);
return 1;
}
int
lws_sspc_add_peer_tx_credit(struct lws_sspc_handle *h, int32_t bump)
{

View file

@ -231,12 +231,13 @@ callback_ss_proxy(struct lws *wsi, enum lws_callback_reasons reason,
struct raw_pss *pss = (struct raw_pss *)user;
const lws_ss_policy_t *rsp;
struct conn *conn = NULL;
lws_ss_metadata_t *md;
lws_ss_info_t ssi;
const uint8_t *cp;
#if defined(LWS_WITH_DETAILED_LATENCY)
lws_usec_t us;
#endif
char s[128];
char s[256];
uint8_t *p;
size_t si;
char pay;
@ -430,6 +431,48 @@ callback_ss_proxy(struct lws *wsi, enum lws_callback_reasons reason,
lws_set_timeout(wsi, 0, 0);
break;
case LPCSPROX_OPERATIONAL:
/*
* rx metadata has priority
*/
md = conn->ss->metadata;
while (md) {
// lwsl_notice("%s: check %s: %d\n", __func__,
// md->name, md->pending_onward);
if (md->pending_onward) {
size_t naml = strlen(md->name);
// lwsl_notice("%s: proxy issuing rxmd\n", __func__);
if (4 + naml + md->length > sizeof(s)) {
lwsl_err("%s: rxmdata too big\n",
__func__);
goto hangup;
}
md->pending_onward = 0;
p = (uint8_t *)s;
p[0] = LWSSS_SER_RXPRE_METADATA;
lws_ser_wu16be(&p[1], 1 + naml +
md->length);
p[3] = (uint8_t)naml;
memcpy(&p[4], md->name, naml);
p += 4 + naml;
memcpy(p, md->value, md->length);
p += md->length;
n = lws_ptr_diff(p, cp);
goto again;
}
md = md->next;
}
/*
* if no fresh rx metadata, just pass through incoming
* dsh
*/
if (lws_dsh_get_head(conn->dsh, KIND_SS_TO_P,
(void **)&p, &si))
break;
@ -511,10 +554,8 @@ again:
return lws_callback_http_dummy(wsi, reason, user, in, len);
hangup:
//lws_ss_destroy(&conn->ss);
//conn->state = LPCSPROX_DESTROYED;
/* hang up on him */
return -1;
}

View file

@ -487,6 +487,15 @@ lws_ss_deserialize_parse(struct lws_ss_serialization_parser *par,
par->ps = RPAR_STATEINDEX;
break;
case LWSSS_SER_RXPRE_METADATA:
if (!client)
goto hangup;
if (par->rem < 3)
goto hangup;
par->ctr = 0;
par->ps = RPAR_METADATA_NAMELEN;
break;
case LWSSS_SER_RXPRE_TXCR_UPDATE:
par->ctr = 0;
par->ps = RPAR_RX_TXCR_UPDATE;
@ -870,6 +879,7 @@ payload_ff:
break;
case RPAR_METADATA_NAMELEN:
/* both client and proxy */
if (!--par->rem)
goto hangup;
par->slen = *cp++;
@ -880,6 +890,7 @@ payload_ff:
break;
case RPAR_METADATA_NAME:
/* both client and proxy */
if (!--par->rem)
goto hangup;
par->metadata_name[par->ctr++] = *cp++;
@ -888,7 +899,62 @@ payload_ff:
par->metadata_name[par->ctr] = '\0';
par->ps = RPAR_METADATA_VALUE;
/* only proxy side can receive these */
if (client) {
lws_sspc_metadata_t *md;
lws_sspc_handle_t *h =
client_pss_to_sspc_h(pss, ssi);
/*
* client side does not have access to policy
* and any metadata are new to it each time,
* we allocate them, removing any existing with
* the same name first
*/
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
lws_dll2_get_head(
&h->metadata_owner_rx)) {
md = lws_container_of(d,
lws_sspc_metadata_t, list);
if (!strcmp(md->name,
par->metadata_name)) {
lws_dll2_remove(&md->list);
lws_free(md);
}
} lws_end_foreach_dll_safe(d, d1);
/*
* Create the client's rx metadata entry
*/
md = lws_malloc(sizeof(lws_sspc_metadata_t) +
par->rem + 1, "rxmeta");
if (!md) {
lwsl_err("%s: OOM\n", __func__);
goto hangup;
}
memset(md, 0, sizeof(lws_sspc_metadata_t));
lws_strncpy(md->name, par->metadata_name,
sizeof(md->name));
md->len = par->rem;
par->rxmetaval = (uint8_t *)&md[1];
/*
* Overallocate by 1 and put a NUL just beyond
* the official md->len, so value can be easily
* dereferenced safely for NUL-terminated string
* apis that's the most common usage
*/
par->rxmetaval[md->len] = '\0';
lws_dll2_add_tail(&md->list,
&h->metadata_owner_rx);
par->ctr = 0;
break;
}
/* proxy side is receiving it */
if (!proxy_pss_to_ss_h(pss))
goto hangup;
@ -897,8 +963,9 @@ payload_ff:
* This is the policy's metadata list for the given
* name
*/
pm = lws_ss_policy_metadata(proxy_pss_to_ss_h(pss)->policy,
par->metadata_name);
pm = lws_ss_policy_metadata(
proxy_pss_to_ss_h(pss)->policy,
par->metadata_name);
if (!pm) {
lwsl_err("%s: metadata %s not in proxy policy\n",
__func__, par->metadata_name);
@ -906,7 +973,9 @@ payload_ff:
goto hangup;
}
par->ssmd = &proxy_pss_to_ss_h(pss)->metadata[pm->length];
par->ssmd = lws_ss_get_handle_metadata(
proxy_pss_to_ss_h(pss),
par->metadata_name);
if (par->ssmd->value_on_lws_heap)
lws_free_set_NULL(par->ssmd->value);
@ -918,21 +987,33 @@ payload_ff:
goto hangup;
}
par->ssmd->length = par->rem;
((uint8_t *)par->ssmd->value)[par->rem] = '\0';
/* mark it as needing cleanup */
par->ssmd->value_on_lws_heap = 1;
par->ctr = 0;
break;
case RPAR_METADATA_VALUE:
((uint8_t *)(par->ssmd->value))[par->ctr++] = *cp++;
/* both client and proxy */
if (client) {
*par->rxmetaval++ = *cp++;
} else
((uint8_t *)(par->ssmd->value))[par->ctr++] = *cp++;
if (--par->rem)
break;
/* we think we got all the value */
lwsl_info("%s: RPAR_METADATA_VALUE for %s (len %d)\n",
if (client)
lwsl_notice("%s: RX METADATA %s\n", __func__,
par->metadata_name);
else {
lwsl_info("%s: RPAR_METADATA_VALUE for %s (len %d)\n",
__func__, par->ssmd->name,
(int)par->ssmd->length);
lwsl_hexdump_info(par->ssmd->value, par->ssmd->length);
lwsl_hexdump_info(par->ssmd->value, par->ssmd->length);
}
par->ps = RPAR_TYPE;
break;

View file

@ -142,7 +142,8 @@ lws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
lws_ss_handle_t *h = (lws_ss_handle_t *)priv;
const char *replace = NULL;
size_t total, budget;
lws_ss_metadata_t *md = lws_ss_policy_metadata(h->policy, name);
lws_ss_metadata_t *md = lws_ss_policy_metadata(h->policy, name),
*hmd = lws_ss_get_handle_metadata(h, name);
if (!md) {
lwsl_err("%s: Unknown metadata %s\n", __func__, name);
@ -150,10 +151,8 @@ lws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
return LSTRX_FATAL_NAME_UNKNOWN;
}
lwsl_info("%s %s %d\n", __func__, name, (int)md->length);
replace = h->metadata[md->length].value;
total = h->metadata[md->length].length;
replace = hmd->value;
total = hmd->length;
// lwsl_hexdump_err(replace, total);
budget = olen - *pos;

View file

@ -181,10 +181,15 @@ int main(int argc, const char **argv)
printf("\t.name = \"%s\",\n", (const char *)md->name);
if (md->value)
printf("\t.value = (void *)\"%s\",\n", (const char *)md->value);
printf("\t.value = (void *)\"%s\",\n",
(const char *)md->value);
printf("\t.length = %d,\n", idx++); // md->length);
printf("\t.value_length = 0x%x,\n",
(unsigned int)strlen(
(const char *)md->value));
printf("\t.value_is_http_token = 0x%x,\n",
(unsigned int)md->value_is_http_token);
printf("}");
if (md->next)
printf(",\n");

View file

@ -1,5 +1,5 @@
/*
* lws-minimal-secure-streams
* lws-minimal-secure-streams-staticpolicy
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
*
@ -276,7 +276,7 @@ int main(int argc, const char **argv)
lws_system_blob_heap_append(lws_system_get_blob(context,
LWS_SYSBLOB_TYPE_DEVICE_TYPE, 0),
(const uint8_t *)"spacerocket", 11);
(const uint8_t *)"spacerocket", 11);
/* the event loop */

View file

@ -230,9 +230,16 @@ static const char *canned_root_token_payload =
static int
myss_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
{
// myss_t *m = (myss_t *)userobj;
myss_t *m = (myss_t *)userobj;
const char *md_srv = NULL, *md_test = NULL;
size_t md_len;
lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags);
lws_ss_get_metadata(m->ss, "srv", (const void **)&md_srv, &md_len);
lws_ss_get_metadata(m->ss, "test", (const void **)&md_test, &md_len);
lwsl_user("%s: len %d, flags: %d, srv: %s, test: %s\n", __func__,
(int)len, flags, md_srv ? md_srv : "not set",
md_test ? md_test : "not set");
lwsl_hexdump_info(buf, len);
/*