diff --git a/READMEs/README.lws_system.md b/READMEs/README.lws_system.md index 44890524d..499d0acaa 100644 --- a/READMEs/README.lws_system.md +++ b/READMEs/README.lws_system.md @@ -19,6 +19,13 @@ typedef struct lws_system_ops { } lws_system_ops_t; ``` +|Item|Meaning| +|---|---| +|`(*get_info)()`|Retreive system information in a standardized way| +|`(*reboot)()`|Reboot the system| +|`(*set_clock)()`|Set the system clock| +|`(*auth)()`|Set and Get dynamic auth strings| + ### `get_info` This allows the user code to query some common system values without introducing @@ -44,6 +51,8 @@ Set the system clock to us-resolution Unix time in seconds Get and set generic binary auth blobs so the rest of lws can access them independently. +Call with `set` 0 to get and 1 to set the auth code with the index `idx`. + ## System state and notifiers Lws implements a state in the context that reflects the readiness of the system diff --git a/include/libwebsockets/lws-client.h b/include/libwebsockets/lws-client.h index a5fdd485f..0c7839ef6 100644 --- a/include/libwebsockets/lws-client.h +++ b/include/libwebsockets/lws-client.h @@ -42,6 +42,7 @@ enum lws_client_connect_ssl_connection_flags { LCCSCF_ALLOW_INSECURE = (1 << 4), LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM = (1 << 5), LCCSCF_H2_QUIRK_OVERFLOWS_TXCR = (1 << 6), + LCCSCF_H2_AUTH_BEARER = (1 << 7), LCCSCF_PIPELINE = (1 << 16), /**< Serialize / pipeline multiple client connections diff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c index 32e5b160e..a625368b2 100644 --- a/lib/roles/h2/http2.c +++ b/lib/roles/h2/http2.c @@ -2198,11 +2198,12 @@ fail: return 1; } +#if defined(LWS_WITH_CLIENT) int lws_h2_client_handshake(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - uint8_t *buf, *start, *p, *end; + uint8_t *buf, *start, *p, *end, *q; char *meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD), *uri = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI); struct lws *nwsi = lws_get_network_wsi(wsi); @@ -2241,7 +2242,8 @@ lws_h2_client_handshake(struct lws *wsi) lws_pps_schedule(wsi, pps); p = start = buf = pt->serv_buf + LWS_PRE; - end = start + wsi->context->pt_serv_buf_size - LWS_PRE - 1; + end = start + (wsi->context->pt_serv_buf_size / 2) - LWS_PRE - 1; + q = start + (wsi->context->pt_serv_buf_size / 2); /* it's time for us to send our client stream headers */ @@ -2287,6 +2289,26 @@ lws_h2_client_handshake(struct lws *wsi) &p, end)) goto fail_length; + if (wsi->flags & LCCSCF_H2_AUTH_BEARER) { + + uint8_t *qend = q + (wsi->context->pt_serv_buf_size / 2) - 1; + + strcpy((char *)q, "bearer "); + + n = lws_system_get_auth(wsi->context, 0, q + 7, + lws_ptr_diff(qend, q + 7), + LWSSYSGAUTH_HEX); + if (n < 0) + return -1; + + lwsl_debug("%s: adding auth: %s\n", __func__, q); + + if (lws_add_http_header_by_token(wsi, + WSI_TOKEN_HTTP_AUTHORIZATION, + q, n + 7, &p, end)) + return -1; + } + /* give userland a chance to append, eg, cookies */ if (wsi->protocol->callback(wsi, @@ -2297,6 +2319,8 @@ lws_h2_client_handshake(struct lws *wsi) if (lws_finalize_http_header(wsi, &p, end)) goto fail_length; + // lwsl_hexdump_notice(start, p - start); + #if defined(LWS_WITH_DETAILED_LATENCY) wsi->detlat.earliest_write_req_pre_write = lws_now_usecs(); #endif @@ -2327,6 +2351,7 @@ fail_length: return -1; } +#endif int lws_h2_ws_handshake(struct lws *wsi) diff --git a/lib/roles/h2/ops-h2.c b/lib/roles/h2/ops-h2.c index 907e8ad45..edd5da476 100644 --- a/lib/roles/h2/ops-h2.c +++ b/lib/roles/h2/ops-h2.c @@ -986,12 +986,14 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi) goto next_child; } +#if defined(LWS_WITH_CLIENT) if (lwsi_state(w) == LRS_H2_WAITING_TO_SEND_HEADERS) { if (lws_h2_client_handshake(w)) return -1; goto next_child; } +#endif #if defined(LWS_WITH_SERVER) if (lwsi_state(w) == LRS_DEFERRING_ACTION) { diff --git a/lib/system/system.c b/lib/system/system.c index 920ca4511..ab52f77dd 100644 --- a/lib/system/system.c +++ b/lib/system/system.c @@ -43,7 +43,8 @@ lws_system_get_ops(struct lws_context *context) } 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) { size_t bl = buflen; uint8_t *p, b; @@ -54,14 +55,14 @@ lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf, size_t b return -1; } - if (context->system_ops->auth(idx, buf, &buflen, 0)) { + if (context->system_ops->auth(idx, buf, &buflen, 0) < 0) { lwsl_err("%s: auth get failed\n", __func__); return -1; } if (flags & LWSSYSGAUTH_HEX) { if (bl < (buflen * 2) + 1) { - lwsl_err("%s: auth in hex oversize\n", __func__); + lwsl_err("%s: auth in hex oversize %d\n", __func__, (int)bl); return -1; } diff --git a/minimal-examples/http-client/minimal-http-client-hugeurl/minimal-http-client-hugeurl.c b/minimal-examples/http-client/minimal-http-client-hugeurl/minimal-http-client-hugeurl.c index 174ddb9b5..6178396f7 100644 --- a/minimal-examples/http-client/minimal-http-client-hugeurl/minimal-http-client-hugeurl.c +++ b/minimal-examples/http-client/minimal-http-client-hugeurl/minimal-http-client-hugeurl.c @@ -169,6 +169,7 @@ int main(int argc, const char **argv) info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ info.protocols = protocols; + info.pt_serv_buf_size = 8192; /* * since we know this lws context is only ever going to be used with * one client wsis / fds / sockets at a time, let lws know it doesn't