diff --git a/include/libwebsockets/lws-client.h b/include/libwebsockets/lws-client.h index 41f6569c4..b49e22224 100644 --- a/include/libwebsockets/lws-client.h +++ b/include/libwebsockets/lws-client.h @@ -43,7 +43,9 @@ enum lws_client_connect_ssl_connection_flags { LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM = (1 << 5), LCCSCF_H2_QUIRK_OVERFLOWS_TXCR = (1 << 6), LCCSCF_H2_AUTH_BEARER = (1 << 7), - LCCSCF_HTTP_MULTIPART_MIME = (1 << 8), + LCCSCF_H2_HEXIFY_AUTH_TOKEN = (1 << 8), + LCCSCF_HTTP_MULTIPART_MIME = (1 << 9), + LCCSCF_HTTP_X_WWW_FORM_URLENCODED = (1 << 10), LCCSCF_PIPELINE = (1 << 16), /**< Serialize / pipeline multiple client connections diff --git a/include/libwebsockets/lws-misc.h b/include/libwebsockets/lws-misc.h index 7c35d23a3..cdb5e17b3 100644 --- a/include/libwebsockets/lws-misc.h +++ b/include/libwebsockets/lws-misc.h @@ -641,7 +641,6 @@ LWS_VISIBLE LWS_EXTERN int lws_humanize(char *buf, int len, uint64_t value, const lws_humanize_unit_t *schema); - LWS_VISIBLE LWS_EXTERN void lws_ser_wu16be(uint8_t *b, uint16_t u); diff --git a/include/libwebsockets/lws-state.h b/include/libwebsockets/lws-state.h index 582aab814..b074a9208 100644 --- a/include/libwebsockets/lws-state.h +++ b/include/libwebsockets/lws-state.h @@ -70,7 +70,8 @@ lws_state_reg_notifier(lws_state_manager_t *mgr, lws_state_notify_link_t *nl); */ LWS_EXTERN LWS_VISIBLE void -lws_state_reg_notifier_list(lws_state_manager_t *mgr, lws_state_notify_link_t **nl); +lws_state_reg_notifier_list(lws_state_manager_t *mgr, + lws_state_notify_link_t * const *nl); /** * lws_state_transition_steps() - move to state via starting any deps diff --git a/include/libwebsockets/lws-system.h b/include/libwebsockets/lws-system.h index 28b26af7c..cef617307 100644 --- a/include/libwebsockets/lws-system.h +++ b/include/libwebsockets/lws-system.h @@ -136,16 +136,20 @@ lws_system_get_info(struct lws_context *context, lws_system_item_t item, * * \param context: the lws_context * \param idx: which auth token - * \param buf: where to store result + * \param buf: where to store result, or NULL * \param buflen: size of buf * \param flags: how to write the result * * Attempts to fill buf with the requested system auth token. If flags has * LWSSYSGAUTH_HEX set, then the auth token is written as pairs of hex chars * for each byte. If not set, written as 1 byte per byte binary. + * + * If buf is NULL, returns <= 0 if auth token is not set or > 0 if set, without + * writing anything. *buflen is still set to the size of the auth token. */ LWS_EXTERN LWS_VISIBLE int -lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf, size_t buflen, int flags); +lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf, + size_t buflen, int flags); /** * lws_system_get_ops() - get ahold of the system ops struct from the context @@ -158,6 +162,17 @@ lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf, size_t b LWS_EXTERN LWS_VISIBLE const lws_system_ops_t * lws_system_get_ops(struct lws_context *context); +/** + * lws_system_context_from_system_mgr() - return context from system state mgr + * + * \param mgr: pointer to specifically the system state mgr + * + * Returns the context from the system state mgr. Helper since the lws_context + * is opaque. + */ +LWS_EXTERN LWS_VISIBLE struct lws_context * +lws_system_context_from_system_mgr(lws_state_manager_t *mgr); + typedef int (*dhcpc_cb_t)(void *opaque, int af, uint8_t *ip, int ip_len); /** diff --git a/lib/core-net/connect.c b/lib/core-net/connect.c index ccad6bf91..57605e26b 100644 --- a/lib/core-net/connect.c +++ b/lib/core-net/connect.c @@ -162,6 +162,12 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) p = lws_vhost_name_to_protocol(wsi->vhost, local); if (p) lws_bind_protocol(wsi, p, __func__); + else + lwsl_err("%s: unknown protocol %s\n", __func__, local); + + lwsl_info("%s: wsi %p: %s %s entry\n", + __func__, wsi, wsi->role_ops->name, + wsi->protocol ? wsi->protocol->name : "none"); } /* @@ -277,13 +283,17 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) /* PHASE 8: notify protocol with role-specific connected callback */ - lwsl_debug("%s: wsi %p: cb %d to %s %s\n", __func__, - wsi, wsi->role_ops->adoption_cb[0], - wsi->role_ops->name, wsi->protocol->name); + /* raw socket doesn't want this... not sure if any want this */ + if (wsi->role_ops != &role_ops_raw_skt) { + lwsl_debug("%s: wsi %p: cb %d to %s %s\n", __func__, + wsi, wsi->role_ops->adoption_cb[0], + wsi->role_ops->name, wsi->protocol->name); + + wsi->protocol->callback(wsi, + wsi->role_ops->adoption_cb[0], + wsi->user_space, NULL, 0); + } - wsi->protocol->callback(wsi, - wsi->role_ops->adoption_cb[0], - wsi->user_space, NULL, 0); #if defined(LWS_WITH_HUBBUB) if (i->uri_replace_to) diff --git a/lib/core-net/state.c b/lib/core-net/state.c index e49c28625..537cc95f9 100644 --- a/lib/core-net/state.c +++ b/lib/core-net/state.c @@ -26,14 +26,14 @@ void lws_state_reg_notifier(lws_state_manager_t *mgr, - lws_state_notify_link_t *notify_link) + lws_state_notify_link_t *notify_link) { lws_dll2_add_head(¬ify_link->list, &mgr->notify_list); } void lws_state_reg_notifier_list(lws_state_manager_t *mgr, - lws_state_notify_link_t **notify_link_array) + lws_state_notify_link_t * const *notify_link_array) { if (notify_link_array) while (*notify_link_array) diff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c index 5bb65b0cb..70a14be61 100644 --- a/lib/roles/h2/http2.c +++ b/lib/roles/h2/http2.c @@ -2296,6 +2296,14 @@ lws_h2_client_handshake(struct lws *wsi) p = p1; } + if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED) { + if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, + (unsigned char *)"application/x-www-form-urlencoded", + 33, &p, end)) + goto fail_length; + lws_client_http_body_pending(wsi, 1); + } + if (wsi->flags & LCCSCF_H2_AUTH_BEARER) { uint8_t *qend = q + (wsi->context->pt_serv_buf_size / 2) - 1; @@ -2304,7 +2312,8 @@ lws_h2_client_handshake(struct lws *wsi) n = lws_system_get_auth(wsi->context, 0, q + 7, lws_ptr_diff(qend, q + 7), - LWSSYSGAUTH_HEX); + wsi->flags & LCCSCF_H2_HEXIFY_AUTH_TOKEN ? + LWSSYSGAUTH_HEX : 0); if (n < 0) return -1; diff --git a/lib/roles/http/client/client-http.c b/lib/roles/http/client/client-http.c index 5235439f4..3024b9c6e 100644 --- a/lib/roles/http/client/client-http.c +++ b/lib/roles/http/client/client-http.c @@ -446,6 +446,9 @@ start_ws_handshake: lws_set_timeout(wsi, PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD, context->timeout_secs); + + if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED) + lws_callback_on_writable(wsi); #if defined(LWS_WITH_HTTP_PROXY) if (wsi->http.proxy_clientside) lws_callback_on_writable(wsi); @@ -1229,6 +1232,12 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt) (pkt + wsi->context->pt_serv_buf_size) - p - 12)) return NULL; + if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED) { + p += lws_snprintf(p, 128, "Content-Type: application/x-www-form-urlencoded\x0d\x0a"); + p += lws_snprintf(p, 128, "Content-Length: %lu\x0d\x0a", wsi->http.writeable_len); + lws_client_http_body_pending(wsi, 1); + } + p += lws_snprintf(p, 4, "\x0d\x0a"); // puts(pkt); diff --git a/lib/roles/http/private-lib-roles-http.h b/lib/roles/http/private-lib-roles-http.h index e9ce4e5c1..5dfd3e842 100644 --- a/lib/roles/http/private-lib-roles-http.h +++ b/lib/roles/http/private-lib-roles-http.h @@ -228,6 +228,8 @@ struct _lws_http_mode_related { struct allocated_headers *ah; struct lws *ah_wait_list; + unsigned long writeable_len; + #if defined(LWS_WITH_FILE_OPS) lws_filepos_t filepos; lws_filepos_t filelen; diff --git a/lib/roles/ws/client-ws.c b/lib/roles/ws/client-ws.c index e2819c354..fe117bf6a 100644 --- a/lib/roles/ws/client-ws.c +++ b/lib/roles/ws/client-ws.c @@ -252,6 +252,11 @@ lws_client_ws_upgrade(struct lws *wsi, const char **cce) char ignore; #endif +#if defined(LWS_WITH_DETAILED_LATENCY) + wsi->detlat.earliest_write_req = 0; + wsi->detlat.earliest_write_req_pre_write = 0; +#endif + if (wsi->client_h2_substream) {/* !!! client ws-over-h2 not there yet */ lwsl_warn("%s: client ws-over-h2 upgrade not supported yet\n", __func__); diff --git a/lib/system/system.c b/lib/system/system.c index ab52f77dd..13b6619a7 100644 --- a/lib/system/system.c +++ b/lib/system/system.c @@ -56,11 +56,12 @@ lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf, } if (context->system_ops->auth(idx, buf, &buflen, 0) < 0) { - lwsl_err("%s: auth get failed\n", __func__); + if (buf) + lwsl_err("%s: auth get failed\n", __func__); return -1; } - if (flags & LWSSYSGAUTH_HEX) { + if (buf && (flags & LWSSYSGAUTH_HEX)) { if (bl < (buflen * 2) + 1) { lwsl_err("%s: auth in hex oversize %d\n", __func__, (int)bl); return -1;