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

ss: allow url style endpoint addresses

The endpoint field in streamtype policy may continue to just be the
hostname, like "warmcat.com".

But it's also possible now to be a url-formatted string, like, eg,
"https://warmcat.com:444/mailman/listinfo"

If so (ie, if it contains a : ) then the decoded elements may override
if tls is enabled, the endpoint address, the port, and the url path.

No ABI change.
This commit is contained in:
Andy Green 2020-03-14 06:56:41 +00:00
parent 8adcdbb189
commit 2cd8f599eb
10 changed files with 130 additions and 53 deletions

View file

@ -163,7 +163,7 @@ lws_sspc_rideshare(struct lws_sspc_handle *h);
*/
LWS_VISIBLE LWS_EXTERN int
lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
void *value, size_t len);
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

@ -463,7 +463,7 @@ lws_ss_rideshare(struct lws_ss_handle *h);
*/
LWS_VISIBLE LWS_EXTERN int
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
void *value, size_t len);
const void *value, size_t len);
/**

View file

@ -949,7 +949,9 @@ lws_system_cpd_set(struct lws_context *cx, lws_cpd_result_t result)
cx->captive_portal_detect = (uint8_t)result;
/* if nothing is there to intercept anything, go all the way */
lws_state_transition_steps(&cx->mgr_system, LWS_SYSTATE_OPERATIONAL);
if (cx->mgr_system.state != LWS_SYSTATE_POLICY_INVALID)
lws_state_transition_steps(&cx->mgr_system,
LWS_SYSTATE_OPERATIONAL);
}
lws_cpd_result_t

View file

@ -242,7 +242,7 @@ lws_ss_policy_metadata_index(const lws_ss_policy_t *p, size_t index)
int
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
void *value, size_t len)
const void *value, size_t len)
{
lws_ss_metadata_t *omd = lws_ss_policy_metadata(h->policy, name);
@ -252,7 +252,7 @@ lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
}
h->metadata[omd->length].name = name;
h->metadata[omd->length].value = value;
h->metadata[omd->length].value = (void *)value;
h->metadata[omd->length].length = len;
return 0;

View file

@ -543,10 +543,16 @@ secstream_connect_munge_h1(lws_ss_handle_t *h, char *buf, size_t len,
struct lws_client_connect_info *i,
union lws_ss_contemp *ct)
{
const char *pbasis = h->policy->u.http.url;
size_t used_in, used_out;
lws_strexp_t exp;
if (!h->policy->u.http.url)
/* i.path on entry is used to override the policy urlpath if not "" */
if (i->path[0])
pbasis = i->path;
if (!pbasis)
return 0;
#if !defined(LWS_PLAT_FREERTOS) || defined(LWS_ROLE_H2)
@ -564,8 +570,7 @@ secstream_connect_munge_h1(lws_ss_handle_t *h, char *buf, size_t len,
lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, buf + 1, len - 1);
if (lws_strexp_expand(&exp, h->policy->u.http.url,
strlen(h->policy->u.http.url),
if (lws_strexp_expand(&exp, pbasis, strlen(pbasis),
&used_in, &used_out) != LSTRX_DONE)
return 1;

View file

@ -112,6 +112,15 @@ secstream_connect_munge_h2(lws_ss_handle_t *h, char *buf, size_t len,
struct lws_client_connect_info *i,
union lws_ss_contemp *ct)
{
const char *pbasis = h->policy->u.http.url;
size_t used_in, used_out;
lws_strexp_t exp;
/* i.path on entry is used to override the policy urlpath if not "" */
if (i->path[0])
pbasis = i->path;
if (h->policy->flags & LWSSSPOLF_QUIRK_NGHTTP2_END_STREAM)
i->ssl_connection |= LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM;
@ -137,13 +146,19 @@ secstream_connect_munge_h2(lws_ss_handle_t *h, char *buf, size_t len,
i->manual_initial_tx_credit);
}
if (!h->policy->u.http.url)
if (!pbasis)
return 0;
/* protocol aux is the path part */
i->path = buf;
lws_snprintf(buf, len, "/%s", h->policy->u.http.url);
buf[0] = '/';
lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, buf + 1, len - 1);
if (lws_strexp_expand(&exp, pbasis, strlen(pbasis),
&used_in, &used_out) != LSTRX_DONE)
return 1;
return 0;
}

View file

@ -143,15 +143,30 @@ secstream_connect_munge_ws(lws_ss_handle_t *h, char *buf, size_t len,
struct lws_client_connect_info *i,
union lws_ss_contemp *ct)
{
const char *pbasis = h->policy->u.http.url;
size_t used_in, used_out;
lws_strexp_t exp;
lwsl_notice("%s\n", __func__);
if (!h->policy->u.http.url)
/* i.path on entry is used to override the policy urlpath if not "" */
if (i->path[0])
pbasis = i->path;
if (!pbasis)
return 0;
/* protocol aux is the path part ; ws subprotocol name */
i->path = h->policy->u.http.url;
lws_snprintf(buf, len, "/%s", h->policy->u.http.url);
i->path = buf;
buf[0] = '/';
lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, buf + 1, len - 1);
if (lws_strexp_expand(&exp, pbasis, strlen(pbasis),
&used_in, &used_out) != LSTRX_DONE)
return 1;
i->protocol = h->policy->u.http.u.ws.subprotocol;

View file

@ -493,7 +493,7 @@ lws_sspc_rideshare(struct lws_sspc_handle *h)
static int
_lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
void *value, size_t len, int tx_cr_adjust)
const void *value, size_t len, int tx_cr_adjust)
{
lws_sspc_metadata_t *md;
@ -555,7 +555,7 @@ _lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
int
lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
void *value, size_t len)
const void *value, size_t len)
{
return _lws_sspc_set_metadata(h, name, value, len, 0);
}

View file

@ -185,11 +185,13 @@ lws_ss_backoff(lws_ss_handle_t *h)
int
lws_ss_client_connect(lws_ss_handle_t *h)
{
const char *prot, *_prot, *ipath, *_ipath, *ads, *_ads;
struct lws_client_connect_info i;
const struct ss_pcols *ssp;
size_t used_in, used_out;
union lws_ss_contemp ct;
char path[128], ep[96];
int port, _port, tls;
lws_strexp_t exp;
if (!h->policy) {
@ -205,10 +207,53 @@ lws_ss_client_connect(lws_ss_handle_t *h)
if (h->h_sink)
return 0;
/*
* We're going to substitute ${metadata} in the endpoint at connection-
* time, so this can be set dynamically...
*/
lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, ep, sizeof(ep));
if (lws_strexp_expand(&exp, h->policy->endpoint,
strlen(h->policy->endpoint),
&used_in, &used_out) != LSTRX_DONE) {
lwsl_err("%s: address strexp failed\n", __func__);
return -1;
}
/*
* ... in some cases, we might want the user to be able to override
* some policy settings by what he provided in there. For example,
* if he set the endpoint to "https://myendpoint.com:4443/mypath" it
* might be quite convenient to override the policy to follow the info
* that was given for at least server, port and the url path.
*/
_port = port = h->policy->port;
_prot = prot = NULL;
_ipath = ipath = "";
_ads = ads = ep;
if (strchr(ep, ':') &&
!lws_parse_uri(ep, &_prot, &_ads, &_port, &_ipath)) {
lwsl_debug("%s: using uri parse results '%s' '%s' %d '%s'\n",
__func__, _prot, _ads, _port, _ipath);
prot = _prot;
ads = _ads;
port = _port;
ipath = _ipath;
}
memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
i.context = h->context;
tls = !!(h->policy->flags & LWSSSPOLF_TLS);
if (h->policy->flags & LWSSSPOLF_TLS) {
if (prot && (!strcmp(prot, "http") || !strcmp(prot, "ws") ||
!strcmp(prot, "mqtt")))
tls = 0;
if (tls) {
lwsl_info("%s: using tls\n", __func__);
i.ssl_connection = LCCSCF_USE_SSL;
@ -228,28 +273,19 @@ lws_ss_client_connect(lws_ss_handle_t *h)
}
}
/* expand metadata ${symbols} that may be inside the endpoint string */
i.address = ads;
i.port = port;
i.host = i.address;
i.origin = i.address;
i.opaque_user_data = h;
i.seq = h->seq;
i.retry_and_idle_policy = h->policy->retry_bo;
i.sys_tls_client_cert = h->policy->client_cert;
lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, ep, sizeof(ep));
if (lws_strexp_expand(&exp, h->policy->endpoint,
strlen(h->policy->endpoint),
&used_in, &used_out) != LSTRX_DONE) {
lwsl_err("%s: address strexp failed\n", __func__);
return -1;
}
i.address = ep;
i.port = h->policy->port;
i.host = i.address;
i.origin = i.address;
i.opaque_user_data = h;
i.seq = h->seq;
i.retry_and_idle_policy = h->policy->retry_bo;
i.sys_tls_client_cert = h->policy->client_cert;
i.path = "";
i.path = ipath;
/* if this is not "", munge should use it instead of policy
* url path
*/
ssp = ss_pcols[(int)h->policy->protocol];
if (!ssp) {

View file

@ -40,6 +40,7 @@
static int interrupted, bad = 1, force_cpd_fail_portal,
force_cpd_fail_no_internet;
static lws_state_notify_link_t nl;
static const char *server_name_or_url = "warmcat.com";
/*
* If the -proxy app is fulfilling our connection, then we don't need to have
@ -223,7 +224,9 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state,
switch (state) {
case LWSSSCS_CREATING:
lws_ss_set_metadata(m->ss, "servername", "warmcat.com", 11);
lwsl_notice("%s: CREATING: setting servername metadata to %s\n",
__func__, server_name_or_url);
lws_ss_set_metadata(m->ss, "servername", server_name_or_url, strlen(server_name_or_url));
lws_ss_client_connect(m->ss);
break;
case LWSSSCS_ALL_RETRIES_FAILED:
@ -296,6 +299,7 @@ int main(int argc, const char **argv)
{
struct lws_context_creation_info info;
struct lws_context *context;
const char *p;
int n = 0;
signal(SIGINT, sigint_handler);
@ -318,30 +322,30 @@ int main(int argc, const char **argv)
#if defined(LWS_SS_USE_SSPC)
info.protocols = lws_sspc_protocols;
{
const char *p;
/* connect to ssproxy via UDS by default, else via
* tcp connection to this port */
if ((p = lws_cmdline_option(argc, argv, "-p")))
info.ss_proxy_port = atoi(p);
/* connect to ssproxy via UDS by default, else via
* tcp connection to this port */
if ((p = lws_cmdline_option(argc, argv, "-p")))
info.ss_proxy_port = atoi(p);
/* UDS "proxy.ss.lws" in abstract namespace, else this socket
* path; when -p given this can specify the network interface
* to bind to */
if ((p = lws_cmdline_option(argc, argv, "-i")))
info.ss_proxy_bind = p;
/* UDS "proxy.ss.lws" in abstract namespace, else this socket
* path; when -p given this can specify the network interface
* to bind to */
if ((p = lws_cmdline_option(argc, argv, "-i")))
info.ss_proxy_bind = p;
/* if -p given, -a specifies the proxy address to connect to */
if ((p = lws_cmdline_option(argc, argv, "-a")))
info.ss_proxy_address = p;
}
/* if -p given, -a specifies the proxy address to connect to */
if ((p = lws_cmdline_option(argc, argv, "-a")))
info.ss_proxy_address = p;
#else
info.pss_policies_json = default_ss_policy;
info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
if ((p = lws_cmdline_option(argc, argv, "-u")))
server_name_or_url = p;
/* integrate us with lws system state management when context created */
nl.name = "app";