mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
ss: add set_metadata that takes a heap copy and make ss-h1 use it
Until now we set metadata value pointers into the onward wsi ah data area... that's OK until we get a situation the wsi has gone away before we have a chance to deliver the metadata over the proxy link. Add a variant lws_ss_alloc_set_metadata() that allocates space on the heap and takes a copy of the input metadata. Change ss-h1 to alloc copies of its metadata so we no longer race the wsi ah lifetime.
This commit is contained in:
parent
4804624905
commit
546c151555
5 changed files with 92 additions and 30 deletions
|
@ -629,6 +629,22 @@ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
|
|||
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
|
||||
const void *value, size_t len);
|
||||
|
||||
/**
|
||||
* lws_ss_alloc_set_metadata() - copy data and bind to ss metadata
|
||||
*
|
||||
* \param h: secure streams handle
|
||||
* \param name: metadata name from the policy
|
||||
* \param value: pointer to user-managed data to bind to name
|
||||
* \param len: length of the user-managed data in value
|
||||
*
|
||||
* Same as lws_ss_set_metadata(), but allocates a heap buffer for the data
|
||||
* first and takes a copy of it, so the original can go out of scope
|
||||
* immediately after.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
|
||||
lws_ss_alloc_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
|
||||
*
|
||||
|
|
|
@ -93,6 +93,49 @@ lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
|
|||
return _lws_ss_set_metadata(omd, name, value, len);
|
||||
}
|
||||
|
||||
int
|
||||
_lws_ss_alloc_set_metadata(lws_ss_metadata_t *omd, const char *name,
|
||||
const void *value, size_t len)
|
||||
{
|
||||
uint8_t *p;
|
||||
int n;
|
||||
|
||||
if (omd->value_on_lws_heap) {
|
||||
lws_free_set_NULL(omd->value__may_own_heap);
|
||||
omd->value_on_lws_heap = 0;
|
||||
}
|
||||
|
||||
p = lws_malloc(len, __func__);
|
||||
if (!p)
|
||||
return 1;
|
||||
|
||||
n = _lws_ss_set_metadata(omd, name, p, len);
|
||||
if (n) {
|
||||
lws_free(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
memcpy(p, value, len);
|
||||
|
||||
omd->value_on_lws_heap = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
lws_ss_alloc_set_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;
|
||||
}
|
||||
|
||||
return _lws_ss_alloc_set_metadata(omd, name, value, len);
|
||||
}
|
||||
|
||||
int
|
||||
lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
|
||||
const void **value, size_t *len)
|
||||
|
|
|
@ -468,6 +468,10 @@ int
|
|||
_lws_ss_set_metadata(lws_ss_metadata_t *omd, const char *name,
|
||||
const void *value, size_t len);
|
||||
|
||||
int
|
||||
_lws_ss_alloc_set_metadata(lws_ss_metadata_t *omd, const char *name,
|
||||
const void *value, size_t len);
|
||||
|
||||
lws_ss_state_return_t
|
||||
_lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw);
|
||||
|
||||
|
|
|
@ -303,7 +303,8 @@ lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
|
|||
* set the related metadata name to it then
|
||||
*/
|
||||
|
||||
_lws_ss_set_metadata(omd, polmd->name, cp, (unsigned int)n);
|
||||
_lws_ss_alloc_set_metadata(omd, polmd->name, cp,
|
||||
(unsigned int)n);
|
||||
|
||||
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
|
||||
/*
|
||||
|
@ -363,8 +364,8 @@ lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
|
|||
omd = lws_ss_get_handle_metadata(h,
|
||||
polmd->name);
|
||||
|
||||
_lws_ss_set_metadata(omd, polmd->name,
|
||||
p, (size_t)n);
|
||||
_lws_ss_set_metadata(omd,
|
||||
polmd->name, p, (size_t)n);
|
||||
omd->value_on_lws_heap = 1;
|
||||
|
||||
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
|
||||
|
@ -962,12 +963,12 @@ malformed:
|
|||
#if defined(LWS_ROLE_H2)
|
||||
m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
|
||||
if (m) {
|
||||
if (lws_ss_set_metadata(h, "method",
|
||||
if (lws_ss_alloc_set_metadata(h, "method",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_METHOD), (unsigned int)m))
|
||||
return -1;
|
||||
m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
|
||||
if (lws_ss_set_metadata(h, "path",
|
||||
if (lws_ss_alloc_set_metadata(h, "path",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_PATH), (unsigned int)m))
|
||||
return -1;
|
||||
|
@ -976,20 +977,20 @@ malformed:
|
|||
{
|
||||
m = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
|
||||
if (m) {
|
||||
if (lws_ss_set_metadata(h, "path",
|
||||
if (lws_ss_alloc_set_metadata(h, "path",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_GET_URI), (unsigned int)m))
|
||||
return -1;
|
||||
if (lws_ss_set_metadata(h, "method", "GET", 3))
|
||||
if (lws_ss_alloc_set_metadata(h, "method", "GET", 3))
|
||||
return -1;
|
||||
} else {
|
||||
m = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI);
|
||||
if (m) {
|
||||
if (lws_ss_set_metadata(h, "path",
|
||||
if (lws_ss_alloc_set_metadata(h, "path",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_POST_URI), (unsigned int)m))
|
||||
return -1;
|
||||
if (lws_ss_set_metadata(h, "method", "POST", 4))
|
||||
if (lws_ss_alloc_set_metadata(h, "method", "POST", 4))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,34 +146,32 @@ ss_s3_state(void *userobj, void *sh, lws_ss_constate_t state,
|
|||
|
||||
switch (state) {
|
||||
case LWSSSCS_CREATING:
|
||||
lws_ss_set_metadata(m->ss, "s3bucket",
|
||||
s3bucketName, strlen(s3bucketName));
|
||||
lws_ss_set_metadata(m->ss, "s3Obj",
|
||||
s3ObjName, strlen(s3ObjName));
|
||||
lws_ss_set_metadata(m->ss, "ctype",
|
||||
"text/plain", strlen("text/plain"));
|
||||
create_payload(jpl, sizeof(jpl));
|
||||
m->buf = (uint8_t *)jpl;
|
||||
m->total = sizeof(jpl);
|
||||
|
||||
lws_ss_set_metadata(m->ss, "region",
|
||||
awsRegion, strlen(awsRegion));
|
||||
lws_ss_set_metadata(m->ss, "service",
|
||||
awsService, strlen(awsService));
|
||||
|
||||
lws_ss_set_metadata(m->ss, "xacl",
|
||||
"bucket-owner-full-control",
|
||||
strlen("bucket-owner-full-control"));
|
||||
|
||||
sigv4_sha256hash_payload(m->buf, m->total, payload_hash);
|
||||
|
||||
lws_ss_set_metadata(m->ss, "xcsha256",
|
||||
payload_hash, strlen(payload_hash));
|
||||
|
||||
memset(timestamp, 0, sizeof(timestamp));
|
||||
set_time(timestamp);
|
||||
lws_ss_set_metadata(m->ss, "xdate",
|
||||
timestamp, strlen(timestamp));
|
||||
|
||||
if (lws_ss_set_metadata(m->ss, "s3bucket",
|
||||
s3bucketName, strlen(s3bucketName)) ||
|
||||
lws_ss_set_metadata(m->ss, "s3Obj",
|
||||
s3ObjName, strlen(s3ObjName)) ||
|
||||
lws_ss_set_metadata(m->ss, "ctype",
|
||||
"text/plain", strlen("text/plain")) ||
|
||||
lws_ss_set_metadata(m->ss, "region",
|
||||
awsRegion, strlen(awsRegion)) ||
|
||||
lws_ss_set_metadata(m->ss, "service",
|
||||
awsService, strlen(awsService)) ||
|
||||
lws_ss_set_metadata(m->ss, "xacl",
|
||||
"bucket-owner-full-control",
|
||||
strlen("bucket-owner-full-control")) ||
|
||||
lws_ss_set_metadata(m->ss, "xcsha256",
|
||||
payload_hash, strlen(payload_hash)) ||
|
||||
lws_ss_set_metadata(m->ss, "xdate",
|
||||
timestamp, strlen(timestamp)))
|
||||
return LWSSSSRET_DESTROY_ME;
|
||||
|
||||
lws_ss_request_tx_len(m->ss, m->total);
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue