From 35b1e9e17547c0a6c01bc49d267335217613d87c Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Fri, 24 Jan 2025 19:18:09 -0500 Subject: [PATCH 01/65] detect if client is offline using feedback instead of ntp signal --- README.html | 18 +++++++------- README.md | 12 ++++----- README.txt | 18 +++++++------- lib/raop.c | 5 ---- lib/raop.h | 3 ++- lib/raop_handlers.h | 4 ++- lib/raop_ntp.c | 27 ++++++-------------- lib/raop_ntp.h | 2 +- lib/raop_rtp_mirror.c | 5 ++-- uxplay.1 | 2 +- uxplay.cpp | 58 ++++++++++++++++++++++++++++++++----------- 11 files changed, 84 insertions(+), 70 deletions(-) diff --git a/README.html b/README.html index a441989..e27e320 100644 --- a/README.html +++ b/README.html @@ -1159,16 +1159,16 @@ in which uxplay was put into the background). To quit, use ctrl-C fg ctrl-C to terminate the image viewer, bring uxplay into the foreground, and terminate it too.

-reset n sets a limit of n consecutive -timeout failures of the client to respond to ntp requests from the -server (these are sent every 3 seconds to check if the client is still -present, and synchronize with it). After n failures, the client -will be presumed to be offline, and the connection will be reset to -allow a new connection. The default value of n is 5; the value -n = 0 means “no limit” on timeouts.

+failures of the client to send feedback requests (these “heartbeat +signals” are sent by the client once per second to ask for a response +showing that the server is still online). After n missing +signals, the client will be presumed to be offline, and the connection +will be reset to allow a new connection. The default value of n +is 15 seconds; the value n = 0 means “no limit”.

-nofreeze closes the video window after a reset due -to ntp timeout (default is to leave window open to allow a smoother -reconection to the same client). This option may be useful in fullscreen -mode.

+to client going offline (default is to leave window open to allow a +smoother reconection to the same client). This option may be useful in +fullscreen mode.

-nc maintains previous UxPlay < 1.45 behavior that does not close the video window when the the client sends the “Stop Mirroring” signal. This option is currently diff --git a/README.md b/README.md index ab3f872..60c06fc 100644 --- a/README.md +++ b/README.md @@ -1179,14 +1179,14 @@ uxplay was put into the background). To quit, use `ctrl-C fg ctrl-C` to terminate the image viewer, bring `uxplay` into the foreground, and terminate it too. -**-reset n** sets a limit of *n* consecutive timeout failures of the -client to respond to ntp requests from the server (these are sent every -3 seconds to check if the client is still present, and synchronize with -it). After *n* failures, the client will be presumed to be offline, and +**-reset n** sets a limit of *n* consecutive failures of the +client to send feedback requests (these "heartbeat signals" are sent by the client +once per second to ask for a response showing that the server is still online). +After *n* missing signals, the client will be presumed to be offline, and the connection will be reset to allow a new connection. The default -value of *n* is 5; the value *n* = 0 means "no limit" on timeouts. +value of *n* is 15 seconds; the value *n* = 0 means "no limit". -**-nofreeze** closes the video window after a reset due to ntp timeout +**-nofreeze** closes the video window after a reset due to client going offline (default is to leave window open to allow a smoother reconection to the same client). This option may be useful in fullscreen mode. diff --git a/README.txt b/README.txt index 01ed687..be6448b 100644 --- a/README.txt +++ b/README.txt @@ -1180,16 +1180,16 @@ uxplay was put into the background). To quit, use `ctrl-C fg ctrl-C` to terminate the image viewer, bring `uxplay` into the foreground, and terminate it too. -**-reset n** sets a limit of *n* consecutive timeout failures of the -client to respond to ntp requests from the server (these are sent every -3 seconds to check if the client is still present, and synchronize with -it). After *n* failures, the client will be presumed to be offline, and -the connection will be reset to allow a new connection. The default -value of *n* is 5; the value *n* = 0 means "no limit" on timeouts. +**-reset n** sets a limit of *n* consecutive failures of the client to +send feedback requests (these "heartbeat signals" are sent by the client +once per second to ask for a response showing that the server is still +online). After *n* missing signals, the client will be presumed to be +offline, and the connection will be reset to allow a new connection. The +default value of *n* is 15 seconds; the value *n* = 0 means "no limit". -**-nofreeze** closes the video window after a reset due to ntp timeout -(default is to leave window open to allow a smoother reconection to the -same client). This option may be useful in fullscreen mode. +**-nofreeze** closes the video window after a reset due to client going +offline (default is to leave window open to allow a smoother reconection +to the same client). This option may be useful in fullscreen mode. **-nc** maintains previous UxPlay \< 1.45 behavior that does **not close** the video window when the the client sends the "Stop Mirroring" diff --git a/lib/raop.c b/lib/raop.c index c275dc1..41b2d2d 100644 --- a/lib/raop.c +++ b/lib/raop.c @@ -64,7 +64,6 @@ struct raop_s { uint8_t clientFPSdata; int audio_delay_micros; - int max_ntp_timeouts; /* for temporary storage of pin during pair-pin start */ unsigned short pin; @@ -554,7 +553,6 @@ raop_init(raop_callbacks_t *callbacks) { /* initialize switch for display of client's streaming data records */ raop->clientFPSdata = 0; - raop->max_ntp_timeouts = 0; raop->audio_delay_micros = 250000; raop->hls_support = false; @@ -662,9 +660,6 @@ int raop_set_plist(raop_t *raop, const char *plist_item, const int value) { } else if (strcmp(plist_item, "clientFPSdata") == 0) { raop->clientFPSdata = (value ? 1 : 0); if ((int) raop->clientFPSdata != value) retval = 1; - } else if (strcmp(plist_item, "max_ntp_timeouts") == 0) { - raop->max_ntp_timeouts = (value > 0 ? value : 0); - if (raop->max_ntp_timeouts != value) retval = 1; } else if (strcmp(plist_item, "audio_delay_micros") == 0) { if (value >= 0 && value <= 10 * SECOND_IN_USECS) { raop->audio_delay_micros = value; diff --git a/lib/raop.h b/lib/raop.h index e0a2062..97e7eb9 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -67,11 +67,12 @@ struct raop_callbacks_s { void (*video_process)(void *cls, raop_ntp_t *ntp, video_decode_struct *data); void (*video_pause)(void *cls); void (*video_resume)(void *cls); + void (*conn_feedback) (void *cls); /* Optional but recommended callback functions */ void (*conn_init)(void *cls); void (*conn_destroy)(void *cls); - void (*conn_reset) (void *cls, int timeouts, bool reset_video); + void (*conn_reset) (void *cls); void (*conn_teardown)(void *cls, bool *teardown_96, bool *teardown_110 ); void (*audio_flush)(void *cls); void (*video_flush)(void *cls); diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 3b2c838..0bc980e 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -742,7 +742,7 @@ raop_handler_setup(raop_conn_t *conn, } conn->raop_ntp = raop_ntp_init(conn->raop->logger, &conn->raop->callbacks, remote, conn->remotelen, (unsigned short) timing_rport, &time_protocol); - raop_ntp_start(conn->raop_ntp, &timing_lport, conn->raop->max_ntp_timeouts); + raop_ntp_start(conn->raop_ntp, &timing_lport); conn->raop_rtp = raop_rtp_init(conn->raop->logger, &conn->raop->callbacks, conn->raop_ntp, remote, conn->remotelen, aeskey, aesiv); conn->raop_rtp_mirror = raop_rtp_mirror_init(conn->raop->logger, &conn->raop->callbacks, @@ -983,6 +983,8 @@ raop_handler_feedback(raop_conn_t *conn, char **response_data, int *response_datalen) { logger_log(conn->raop->logger, LOGGER_DEBUG, "raop_handler_feedback"); + /* register receipt of client's "heartbeat" signal */ + conn->raop->callbacks.conn_feedback(conn->raop->callbacks.cls); } static void diff --git a/lib/raop_ntp.c b/lib/raop_ntp.c index 1a932e4..026f70b 100644 --- a/lib/raop_ntp.c +++ b/lib/raop_ntp.c @@ -58,8 +58,6 @@ struct raop_ntp_s { logger_t *logger; raop_callbacks_t callbacks; - int max_ntp_timeouts; - thread_handle_t thread; mutex_handle_t run_mutex; @@ -94,6 +92,8 @@ struct raop_ntp_s { int tsock; timing_protocol_t time_protocol; + bool client_time_received; + }; @@ -153,6 +153,7 @@ raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const c raop_ntp->logger = logger; memcpy(&raop_ntp->callbacks, callbacks, sizeof(raop_callbacks_t)); raop_ntp->timing_rport = timing_rport; + raop_ntp->client_time_received = false; if (raop_ntp_parse_remote(raop_ntp, remote, remote_addr_len) < 0) { free(raop_ntp); @@ -274,8 +275,6 @@ raop_ntp_thread(void *arg) }; raop_ntp_data_t data_sorted[RAOP_NTP_DATA_COUNT]; const unsigned two_pow_n[RAOP_NTP_DATA_COUNT] = {2, 4, 8, 16, 32, 64, 128, 256}; - int timeout_counter = 0; - bool conn_reset = false; bool logger_debug = (logger_get_level(raop_ntp->logger) >= LOGGER_DEBUG); while (1) { @@ -308,20 +307,15 @@ raop_ntp_thread(void *arg) // Read response response_len = recvfrom(raop_ntp->tsock, (char *)response, sizeof(response), 0, NULL, NULL); if (response_len < 0) { - timeout_counter++; char time[30]; - int level = (timeout_counter == 1 ? LOGGER_DEBUG : LOGGER_ERR); ntp_timestamp_to_time(send_time, time, sizeof(time)); - logger_log(raop_ntp->logger, level, "raop_ntp receive timeout %d (limit %d) (request sent %s)", - timeout_counter, raop_ntp->max_ntp_timeouts, time); - if (timeout_counter == raop_ntp->max_ntp_timeouts) { - conn_reset = true; /* client is no longer responding */ - break; - } + logger_log(raop_ntp->logger, LOGGER_DEBUG , "raop_ntp receive timeout (request sent %s)", time); } else { + if (!raop_ntp->client_time_received) { + raop_ntp->client_time_received = true; + } //local time of the server when the NTP response packet returns int64_t t3 = (int64_t) raop_ntp_get_local_time(raop_ntp); - timeout_counter = 0; // Local time of the server when the NTP request packet leaves the server int64_t t0 = (int64_t) byteutils_get_ntp_timestamp(response, 8); @@ -391,15 +385,11 @@ raop_ntp_thread(void *arg) MUTEX_UNLOCK(raop_ntp->run_mutex); logger_log(raop_ntp->logger, LOGGER_DEBUG, "raop_ntp exiting thread"); - if (conn_reset && raop_ntp->callbacks.conn_reset) { - const bool video_reset = false; /* leave "frozen video" in place */ - raop_ntp->callbacks.conn_reset(raop_ntp->callbacks.cls, timeout_counter, video_reset); - } return 0; } void -raop_ntp_start(raop_ntp_t *raop_ntp, unsigned short *timing_lport, int max_ntp_timeouts) +raop_ntp_start(raop_ntp_t *raop_ntp, unsigned short *timing_lport) { logger_log(raop_ntp->logger, LOGGER_DEBUG, "raop_ntp starting time"); int use_ipv6 = 0; @@ -407,7 +397,6 @@ raop_ntp_start(raop_ntp_t *raop_ntp, unsigned short *timing_lport, int max_ntp_t assert(raop_ntp); assert(timing_lport); - raop_ntp->max_ntp_timeouts = max_ntp_timeouts; raop_ntp->timing_lport = *timing_lport; MUTEX_LOCK(raop_ntp->run_mutex); diff --git a/lib/raop_ntp.h b/lib/raop_ntp.h index bf2f5bb..f829f4e 100644 --- a/lib/raop_ntp.h +++ b/lib/raop_ntp.h @@ -27,7 +27,7 @@ typedef struct raop_ntp_s raop_ntp_t; typedef enum timing_protocol_e { NTP, TP_NONE, TP_OTHER, TP_UNSPECIFIED } timing_protocol_t; -void raop_ntp_start(raop_ntp_t *raop_ntp, unsigned short *timing_lport, int max_ntp_timeouts); +void raop_ntp_start(raop_ntp_t *raop_ntp, unsigned short *timing_lport); void raop_ntp_stop(raop_ntp_t *raop_ntp); diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index bc88472..5b66194 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -804,9 +804,8 @@ raop_rtp_mirror_thread(void *arg) MUTEX_UNLOCK(raop_rtp_mirror->run_mutex); logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror exiting TCP thread"); - if (conn_reset && raop_rtp_mirror->callbacks.conn_reset) { - const bool video_reset = false; /* leave "frozen video" showing */ - raop_rtp_mirror->callbacks.conn_reset(raop_rtp_mirror->callbacks.cls, 0, video_reset); + if (conn_reset&& raop_rtp_mirror->callbacks.conn_reset) { + raop_rtp_mirror->callbacks.conn_reset(raop_rtp_mirror->callbacks.cls); } if (unsupported_codec) { diff --git a/uxplay.1 b/uxplay.1 index ee8d3f6..f760cca 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -106,7 +106,7 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-ca\fI fn \fR In Airplay Audio (ALAC) mode, write cover-art to file fn. .TP -\fB\-reset\fR n Reset after 3n seconds client silence (default 5, 0=never). +\fB\-reset\fR n Reset after n seconds client silence (default n=15, 0=never). .TP \fB\-nofreeze\fR Do NOT leave frozen screen in place after reset. .TP diff --git a/uxplay.cpp b/uxplay.cpp index b96053d..eda3c67 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -70,7 +70,7 @@ #define DEFAULT_DEBUG_LOG false #define LOWEST_ALLOWED_PORT 1024 #define HIGHEST_PORT 65535 -#define NTP_TIMEOUT_LIMIT 5 +#define MISSED_FEEDBACK_LIMIT 15 #define BT709_FIX "capssetter caps=\"video/x-h264, colorimetry=bt709\"" #define SRGB_FIX " ! video/x-raw,colorimetry=sRGB,format=RGB ! " #ifdef FULL_RANGE_RGB_FIX @@ -104,7 +104,6 @@ static std::string video_parser = "h264parse"; static std::string video_decoder = "decodebin"; static std::string video_converter = "videoconvert"; static bool show_client_FPS_data = false; -static unsigned int max_ntp_timeouts = NTP_TIMEOUT_LIMIT; static FILE *video_dumpfile = NULL; static std::string video_dumpfile_name = "videodump"; static int video_dump_limit = 0; @@ -156,6 +155,8 @@ static std::string url = ""; static guint gst_x11_window_id = 0; static guint gst_hls_position_id = 0; static bool preserve_connections = false; +static guint missed_feedback_limit = MISSED_FEEDBACK_LIMIT; +static guint missed_feedback = 0; /* logging */ @@ -365,6 +366,28 @@ static void dump_video_to_file(unsigned char *data, int datalen) { } } +static gboolean feedback_callback(gpointer loop) { + if (open_connections) { + if (missed_feedback_limit && missed_feedback > missed_feedback_limit) { + LOGI("***ERROR lost connection with client (network problem?)"); + LOGI("%u missed client feedback signals exceeds limit of %u", missed_feedback, missed_feedback_limit); + LOGI(" Sometimes the network connection may recover after a longer delay:\n" + " the default limit n = %d seconds, can be changed with the \"-reset n\" option", MISSED_FEEDBACK_LIMIT); + if (!nofreeze) { + close_window = false; /* leave "frozen" window open if reset_video is false */ + } + raop_stop(raop); + reset_loop = true; + } else if (missed_feedback > 2) { + LOGE("%u missed client feedback signals (expected once per second); client may be offline", missed_feedback); + } + missed_feedback++; + } else { + missed_feedback = 0; + } + return TRUE; +} + static gboolean reset_callback(gpointer loop) { if (reset_loop) { g_main_loop_quit((GMainLoop *) loop); @@ -435,6 +458,8 @@ static void main_loop() { gst_bus_watch_id[i] = (guint) video_renderer_listen((void *)loop, i); } } + missed_feedback = 0; + guint feedback_watch_id = g_timeout_add_seconds(1, (GSourceFunc) feedback_callback, (gpointer) loop); guint reset_watch_id = g_timeout_add(100, (GSourceFunc) reset_callback, (gpointer) loop); guint video_reset_watch_id = g_timeout_add(100, (GSourceFunc) video_reset_callback, (gpointer) loop); guint sigterm_watch_id = g_unix_signal_add(SIGTERM, (GSourceFunc) sigterm_callback, (gpointer) loop); @@ -449,6 +474,7 @@ static void main_loop() { if (sigterm_watch_id > 0) g_source_remove(sigterm_watch_id); if (reset_watch_id > 0) g_source_remove(reset_watch_id); if (video_reset_watch_id > 0) g_source_remove(video_reset_watch_id); + if (feedback_watch_id > 0) g_source_remove(feedback_watch_id); g_main_loop_unref(loop); } @@ -657,7 +683,7 @@ static void print_info (char *name) { printf("-as 0 (or -a) Turn audio off, streamed video only\n"); printf("-al x Audio latency in seconds (default 0.25) reported to client.\n"); printf("-ca In Airplay Audio (ALAC) mode, write cover-art to file \n"); - printf("-reset n Reset after 3n seconds client silence (default %d, 0=never)\n", NTP_TIMEOUT_LIMIT); + printf("-reset n Reset after n seconds of client silence (default n=%d, 0=never)\n", MISSED_FEEDBACK_LIMIT); printf("-nofreeze Do NOT leave frozen screen in place after reset\n"); printf("-nc Do NOT Close video window when client stops mirroring\n"); printf("-nohold Drop current connection when new client connects.\n"); @@ -739,7 +765,7 @@ static bool get_value (const char *str, unsigned int *n) { static bool get_ports (int nports, std::string option, const char * value, unsigned short * const port) { /*valid entries are comma-separated values port_1,port_2,...,port_r, 0 < r <= nports */ /*where ports are distinct, and are in the allowed range. */ - /*missing values are consecutive to last given value (at least one value needed). */ + /*missed values are consecutive to last given value (at least one value needed). */ char *end; unsigned long l; std::size_t pos; @@ -1020,9 +1046,11 @@ static void parse_arguments (int argc, char *argv[]) { } else if (arg == "-FPSdata") { show_client_FPS_data = true; } else if (arg == "-reset") { - max_ntp_timeouts = 0; - if (!get_value(argv[++i], &max_ntp_timeouts)) { - fprintf(stderr, "invalid \"-reset %s\"; -reset n must have n >= 0, default n = %d\n", argv[i], NTP_TIMEOUT_LIMIT); + /* now using feedback (every 1 sec ) instead of ntp timeouts (every 3 secs) to detect offline client and reset connections */ + fprintf(stderr,"*** NOTE CHANGE: -reset n now means reset n seconds (not 3n seconds) after client goes offline\n"); + missed_feedback_limit = 0; + if (!get_value(argv[++i], &missed_feedback_limit)) { + fprintf(stderr, "invalid \"-reset %s\"; -reset n must have n >= 0, default n = %d seconds\n", argv[i], MISSED_FEEDBACK_LIMIT); exit(1); } } else if (arg == "-vdmp") { @@ -1587,15 +1615,15 @@ extern "C" void conn_destroy (void *cls) { } } -extern "C" void conn_reset (void *cls, int timeouts, bool reset_video) { +extern "C" void conn_feedback (void *cls) { + /* received client heartbeat signal: connection still exists */ + missed_feedback = 0; +} + +extern "C" void conn_reset (void *cls) { LOGI("***ERROR lost connection with client (network problem?)"); - if (timeouts) { - LOGI(" Client no-response limit of %d timeouts (%d seconds) reached:", timeouts, 3*timeouts); - LOGI(" Sometimes the network connection may recover after a longer delay:\n" - " the default timeout limit n = %d can be changed with the \"-reset n\" option", NTP_TIMEOUT_LIMIT); - } if (!nofreeze) { - close_window = reset_video; /* leave "frozen" window open if reset_video is false */ + close_window = false; /* leave "frozen" window open */ } raop_stop(raop); reset_loop = true; @@ -1931,6 +1959,7 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3], raop_cbs.conn_init = conn_init; raop_cbs.conn_destroy = conn_destroy; raop_cbs.conn_reset = conn_reset; + raop_cbs.conn_feedback = conn_feedback; raop_cbs.conn_teardown = conn_teardown; raop_cbs.audio_process = audio_process; raop_cbs.video_process = video_process; @@ -1981,7 +2010,6 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3], if (display[4]) raop_set_plist(raop, "overscanned", (int) display[4]); if (show_client_FPS_data) raop_set_plist(raop, "clientFPSdata", 1); - raop_set_plist(raop, "max_ntp_timeouts", max_ntp_timeouts); if (audiodelay >= 0) raop_set_plist(raop, "audio_delay_micros", audiodelay); if (require_password) raop_set_plist(raop, "pin", (int) pin); if (hls_support) raop_set_plist(raop, "hls", 1); From 518b72d9c5008bc50b549b4c77f97481d7773b29 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Sat, 25 Jan 2025 11:46:38 -0500 Subject: [PATCH 02/65] fix bug in setting udp timing port (doesnt fix macOS 15.2 bug) --- uxplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uxplay.cpp b/uxplay.cpp index eda3c67..3322ffb 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -960,7 +960,7 @@ static void parse_arguments (int argc, char *argv[]) { if(!get_ports(3, arg, argv[++i], udp)) exit(1); } else { if(!get_ports(3, arg, argv[i], tcp)) exit(1); - for (int j = 1; j < 3; j++) { + for (int j = 0; j < 3; j++) { udp[j] = tcp[j]; } } From bccc42e4e25c7f79efbb14ac2bf1fcb55718ee64 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 27 Jan 2025 03:53:01 -0500 Subject: [PATCH 03/65] raop_rtp fixes/cleanups to remove unneeded ntp use --- README.html | 2 + README.md | 3 + README.txt | 3 + lib/raop.c | 4 + lib/raop.h | 3 +- lib/raop_buffer.c | 13 ++- lib/raop_buffer.h | 4 +- lib/raop_ntp.c | 30 +++++- lib/raop_ntp.h | 5 +- lib/raop_rtp.c | 225 +++++++++++++++--------------------------- lib/raop_rtp_mirror.c | 12 ++- uxplay.cpp | 6 +- 12 files changed, 143 insertions(+), 167 deletions(-) diff --git a/README.html b/README.html index e27e320..27adc8c 100644 --- a/README.html +++ b/README.html @@ -15,6 +15,8 @@ until advertisements have finished or been skipped before clicking the YouTube airplay icon.) Please report any issues with this new feature of UxPlay. +

NEWS: macOS Sequoia 15.2 has an AirPlay +bug: update to macOS 15.3 for mirroring screen with UxPlay.

Highlights:

NEWS: macOS Sequoia 15.2 has an AirPlay bug: update to macOS 15.3 for mirroring screen with UxPlay.

@@ -955,10 +957,14 @@ and some iPhones) can send h265 video if a resolution “-s wxh” with h > 1080 is requested. The “-h265” option changes the default resolution (“-s” option) from 1920x1080 to 3840x2160, and leaves default maximum framerate (“-fps” option) at 30fps.

-

-hls Activate HTTP Live Streaming support. With this -option YouTube videos can be streamed directly from YouTube servers to -UxPlay (without passing through the client) by clicking on the AirPlay -icon in the YouTube app.

+

-hls [v] Activate HTTP Live Streaming support. With +this option YouTube videos can be streamed directly from YouTube servers +to UxPlay (without passing through the client) by clicking on the +AirPlay icon in the YouTube app. Optional [v] (allowed values 2 or 3, +default: 3) allows selection of the version of GStreamer’s "playbin" +video player to use for playing HLS video. (Playbin v3 is the +recommended player, but if some videos fail to play, you can try with +version 2.)

-pin [nnnn]: (since v1.67) use Apple-style (one-time) “pin” authentication when a new client connects for the first time: a four-digit pin code is displayed on the terminal, and the client diff --git a/README.md b/README.md index 71e6ddd..1f5f26f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ YouTube app to stream video. (You may need to wait until advertisements have finished or been skipped before clicking the YouTube airplay icon.) **Please report any issues with this new - feature of UxPlay**. + feature of UxPlay**. _The default video player for HLS is + GStreamer playbin v3: use "-hls 2" to revert to playbin v2 if + some videos fail to play_. ***NEWS***: macOS Sequoia 15.2 has an AirPlay bug: update to macOS 15.3 for mirroring screen with UxPlay. @@ -961,10 +963,14 @@ The "-h265" option changes the default resolution ("-s" option) from 1920x1080 to 3840x2160, and leaves default maximum framerate ("-fps" option) at 30fps. -**-hls** Activate HTTP Live Streaming support. With this option YouTube +**-hls \[v\]** Activate HTTP Live Streaming support. With this option YouTube videos can be streamed directly from YouTube servers to UxPlay (without passing through the client) by clicking on the AirPlay icon in the -YouTube app. +YouTube app. Optional \[v\] (allowed values 2 or 3, default: 3) +allows selection of the version of GStreamer's +\"playbin\" video player to use for playing HLS video. _(Playbin v3 +is the recommended player, but if some videos fail to play, you can try +with version 2.)_ **-pin \[nnnn\]**: (since v1.67) use Apple-style (one-time) "pin" authentication when a new client connects for the first time: a diff --git a/README.txt b/README.txt index 323f86a..0648b6c 100644 --- a/README.txt +++ b/README.txt @@ -7,7 +7,9 @@ YouTube app to stream video. (You may need to wait until advertisements have finished or been skipped before clicking the YouTube airplay icon.) **Please report any issues with this new - feature of UxPlay**. + feature of UxPlay**. *The default video player for HLS is GStreamer + playbin v3: use "-hls 2" to revert to playbin v2 if some videos fail + to play*. ***NEWS***: macOS Sequoia 15.2 has an AirPlay bug: update to macOS 15.3 for mirroring screen with UxPlay. @@ -962,10 +964,13 @@ The "-h265" option changes the default resolution ("-s" option) from 1920x1080 to 3840x2160, and leaves default maximum framerate ("-fps" option) at 30fps. -**-hls** Activate HTTP Live Streaming support. With this option YouTube -videos can be streamed directly from YouTube servers to UxPlay (without -passing through the client) by clicking on the AirPlay icon in the -YouTube app. +**-hls \[v\]** Activate HTTP Live Streaming support. With this option +YouTube videos can be streamed directly from YouTube servers to UxPlay +(without passing through the client) by clicking on the AirPlay icon in +the YouTube app. Optional \[v\] (allowed values 2 or 3, default: 3) +allows selection of the version of GStreamer's \"playbin\" video player +to use for playing HLS video. *(Playbin v3 is the recommended player, +but if some videos fail to play, you can try with version 2.)* **-pin \[nnnn\]**: (since v1.67) use Apple-style (one-time) "pin" authentication when a new client connects for the first time: a diff --git a/renderers/video_renderer.c b/renderers/video_renderer.c index 257a456..e722306 100644 --- a/renderers/video_renderer.c +++ b/renderers/video_renderer.c @@ -193,7 +193,7 @@ GstElement *make_video_sink(const char *videosink, const char *videosink_options void video_renderer_init(logger_t *render_logger, const char *server_name, videoflip_t videoflip[2], const char *parser, const char *decoder, const char *converter, const char *videosink, const char *videosink_options, - bool initial_fullscreen, bool video_sync, bool h265_support, const char *uri) { + bool initial_fullscreen, bool video_sync, bool h265_support, guint playbin_version, const char *uri) { GError *error = NULL; GstCaps *caps = NULL; hls_video = (uri != NULL); @@ -230,8 +230,19 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide renderer_type[i]->id = i; renderer_type[i]->bus = NULL; if (hls_video) { - /* use playbin3 to play HLS video: replace "playbin3" by "playbin" to use playbin2 */ - renderer_type[i]->pipeline = gst_element_factory_make("playbin3", "hls-playbin3"); + /* use playbin3 to play HLS video: replace "playbin3" by "playbin" to use playbin2 */ + switch (playbin_version) { + case 2: + renderer_type[i]->pipeline = gst_element_factory_make("playbin", "hls-playbin2"); + break; + case 3: + renderer_type[i]->pipeline = gst_element_factory_make("playbin3", "hls-playbin3"); + break; + default: + logger_log(logger, LOGGER_ERR, "video_renderer_init: invalid playbin versiion %u", playbin_version); + g_assert(0); + } + logger_log(logger, LOGGER_INFO, "Will use GStreamer playbin version %u to play HLS streamed video", playbin_version); g_assert(renderer_type[i]->pipeline); renderer_type[i]->appsrc = NULL; renderer_type[i]->codec = hls; diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 4db432a..a19e192 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -49,7 +49,7 @@ typedef struct video_renderer_s video_renderer_t; void video_renderer_init (logger_t *logger, const char *server_name, videoflip_t videoflip[2], const char *parser, const char *decoder, const char *converter, const char *videosink, const char *videosink_options, - bool initial_fullscreen, bool video_sync, bool h265_support, const char *uri); + bool initial_fullscreen, bool video_sync, bool h265_support, guint playbin_version, const char *uri); void video_renderer_start (); void video_renderer_stop (); void video_renderer_pause (); diff --git a/uxplay.1 b/uxplay.1 index dd7594d..35b8b8d 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -16,6 +16,8 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server: \fB\-h265\fR Support h265 (4K) video (with h265 versions of h264 plugins) .TP \fB\-hls\fR Support HTTP Live Streaming (currently YouTube video only) +.IP + v = 2 or 3 (default 3) optionally selects video player version .TP \fB\-pin\fI[xxxx]\fRUse a 4-digit pin code to control client access (default: no) .IP diff --git a/uxplay.cpp b/uxplay.cpp index 34d517e..cb0a23b 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -71,6 +71,7 @@ #define LOWEST_ALLOWED_PORT 1024 #define HIGHEST_PORT 65535 #define MISSED_FEEDBACK_LIMIT 15 +#define DEFAULT_PLAYBIN_VERSION 3 #define BT709_FIX "capssetter caps=\"video/x-h264, colorimetry=bt709\"" #define SRGB_FIX " ! video/x-raw,colorimetry=sRGB,format=RGB ! " #ifdef FULL_RANGE_RGB_FIX @@ -157,7 +158,7 @@ static guint gst_hls_position_id = 0; static bool preserve_connections = false; static guint missed_feedback_limit = MISSED_FEEDBACK_LIMIT; static guint missed_feedback = 0; - +static guint playbin_version = DEFAULT_PLAYBIN_VERSION; /* logging */ static void log(int level, const char* format, ...) { @@ -639,7 +640,8 @@ static void print_info (char *name) { printf("-n name Specify the network name of the AirPlay server\n"); printf("-nh Do not add \"@hostname\" at the end of AirPlay server name\n"); printf("-h265 Support h265 (4K) video (with h265 versions of h264 plugins)\n"); - printf("-hls Support HTTP Live Streaming (currently Youtube video only) \n"); + printf("-hls [v] Support HTTP Live Streaming (currently Youtube video only) \n"); + printf(" v = 2 or 3 (default 3) optionally selects video player version\n"); printf("-pin[xxxx]Use a 4-digit pin code to control client access (default: no)\n"); printf(" default pin is random: optionally use fixed pin xxxx\n"); printf("-reg [fn] Keep a register in $HOME/.uxplay.register to verify returning\n"); @@ -1220,6 +1222,14 @@ static void parse_arguments (int argc, char *argv[]) { printf("db range %f:%f\n", db_low, db_high); } else if (arg == "-hls") { hls_support = true; + if (i < argc - 1 && *argv[i+1] != '-') { + unsigned int n = 3; + if (!get_value(argv[++i], &n) || playbin_version < 2) { + fprintf(stderr, "invalid \"-hls %s\"; -hls n only allows \"playbin\" video player versions 2 or 3\n", argv[i]); + exit(1); + } + playbin_version = (guint) n; + } } else if (arg == "-h265") { h265_support = true; } else if (arg == "-nofreeze") { @@ -2295,7 +2305,7 @@ int main (int argc, char *argv[]) { if (use_video) { video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), - videosink_options.c_str(), fullscreen, video_sync, h265_support, NULL); + videosink_options.c_str(), fullscreen, video_sync, h265_support, playbin_version, NULL); video_renderer_start(); } @@ -2370,7 +2380,7 @@ int main (int argc, char *argv[]) { const char *uri = (url.empty() ? NULL : url.c_str()); video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), - videosink_options.c_str(), fullscreen, video_sync, h265_support, uri); + videosink_options.c_str(), fullscreen, video_sync, h265_support, playbin_version, uri); video_renderer_start(); } if (relaunch_video) { From 14e6ba55434870ff3660938898a8d4b83ca5cdfe Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Sun, 2 Feb 2025 17:35:05 -0500 Subject: [PATCH 09/65] detect unsupported (non-youtube) HLS --- README.html | 19 ++++++++++--------- README.md | 7 +++---- README.txt | 9 ++++----- lib/http_handlers.h | 23 +++++++++++++++++++++-- lib/raop.h | 9 +++++---- lib/raop_rtp_mirror.c | 2 +- uxplay.cpp | 14 ++++++++++++-- 7 files changed, 56 insertions(+), 27 deletions(-) diff --git a/README.html b/README.html index 7d0ad55..9e9e513 100644 --- a/README.html +++ b/README.html @@ -9,16 +9,17 @@ class="uri">https://github.com/FDH2/UxPlay (where ALL user issues should be posted, and latest versions can be found).

-

NEWS: macOS Sequoia 15.2 has an AirPlay -bug: update to macOS 15.3 for mirroring screen with UxPlay.

Highlights:

Starting and running UxPlay

Since UxPlay-1.64, UxPlay can be started with options read from a diff --git a/README.md b/README.md index c871564..621cf19 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - Install uxplay on Debian-based Linux systems with "`sudo apt install uxplay`"; on FreeBSD with - "`sudo pkg install uxplay`". Also available on Arch-based systems + "`sudo pkg install uxplay`"; on OpenBSD with + "`doas pkg_add uxplay`". Also available on Arch-based systems through AUR. Since v. 1.66, uxplay is now also packaged in RPM format by Fedora 38 ("`sudo dnf install uxplay`"). @@ -373,6 +374,10 @@ package](#building-an-installable-rpm-package). avahi-libdns or mDNSResponder must also be installed to provide the dns_sd library. OpenSSL is already installed as a System Library. +- **OpenBSD:** (doas pkg_add) libplist gstreamer1-plugins-base. + avahi-libs must also be installed to provide the dns_sd library. + OpenSSL is already installed as a System Library. + #### Building an installable RPM package First-time RPM builders should first install the rpm-build and @@ -454,6 +459,10 @@ repositories for those distributions. gstreamer1-plugins-\* (\* = core, good, bad, x, gtk, gl, vulkan, pulse, v4l2, ...), (+ gstreamer1-vaapi for Intel/AMD graphics). +- **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* + (\* = core, bad, base, good). avahi-main must also be installed for + the avahi_daemon rc startup script. + ### Starting and running UxPlay Since UxPlay-1.64, UxPlay can be started with options read from a diff --git a/README.txt b/README.txt index a0d5064..8eed072 100644 --- a/README.txt +++ b/README.txt @@ -48,7 +48,8 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - Install uxplay on Debian-based Linux systems with "`sudo apt install uxplay`"; on FreeBSD with - "`sudo pkg install uxplay`". Also available on Arch-based systems + "`sudo pkg install uxplay`"; on OpenBSD with + "`doas pkg_add uxplay`". Also available on Arch-based systems through AUR. Since v. 1.66, uxplay is now also packaged in RPM format by Fedora 38 ("`sudo dnf install uxplay`"). @@ -373,6 +374,10 @@ package](#building-an-installable-rpm-package). avahi-libdns or mDNSResponder must also be installed to provide the dns_sd library. OpenSSL is already installed as a System Library. +- **OpenBSD:** (doas pkg_add) libplist gstreamer1-plugins-base. + avahi-libs must also be installed to provide the dns_sd library. + OpenSSL is already installed as a System Library. + #### Building an installable RPM package First-time RPM builders should first install the rpm-build and @@ -454,6 +459,10 @@ repositories for those distributions. gstreamer1-plugins-\* (\* = core, good, bad, x, gtk, gl, vulkan, pulse, v4l2, ...), (+ gstreamer1-vaapi for Intel/AMD graphics). +- **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* + (\* = core, bad, base, good). avahi-main must also be installed for + the avahi_daemon rc startup script. + ### Starting and running UxPlay Since UxPlay-1.64, UxPlay can be started with options read from a diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index de79ed4..82faef9 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -62,6 +62,11 @@ #define TCP_KEEPIDLE TCP_KEEPALIVE #endif +/* for OpenBSD, where TCP_KEEPIDLE and TCP_KEEPALIVE are not defined */ +#if !defined(TCP_KEEPIDLE) && !defined(TCP_KEEPALIVE) +#define TCP_KEEPIDLE SO_KEEPALIVE +#endif + //struct h264codec_s { // unsigned char compatibility; // short pps_size; @@ -279,6 +284,8 @@ raop_rtp_mirror_thread(void *arg) logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "raop_rtp_mirror could not set stream socket keepalive time %d %s", sock_err, SOCKET_ERROR_STRING(sock_err)); } +/* OpenBSD does not have these options. */ +#ifndef __OpenBSD__ option = 10; if (setsockopt(stream_fd, SOL_TCP, TCP_KEEPINTVL, CAST &option, sizeof(option)) < 0) { int sock_err = SOCKET_GET_ERROR(); @@ -291,6 +298,7 @@ raop_rtp_mirror_thread(void *arg) logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "raop_rtp_mirror could not set stream socket keepalive probes %d %s", sock_err, SOCKET_ERROR_STRING(sock_err)); } +#endif /* !__OpenBSD__ */ readstart = 0; } From c51b37c71d11b9ab42875dfa4cb3fb413940f068 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sun, 13 Apr 2025 20:35:27 +0300 Subject: [PATCH 32/65] OpenBSD: use unveil(2) and pledge(2) to drop privileges On startup, lose the ability to execute any file as uxplay(1) facilitates no such feature and should thus never be allowed to run another program. Further, if video is disabled, promise to only use certain system call subsets (video uses shmget(2), which no pledge(2) promise covers). This is a start to restrict uxplay(1) for it has full network, audio, filesystem and graphical user session access, usually running as your private user instead and not a dedicated one. No change on other systems. However, this may help them understand and implement similar security mechanisms. --- uxplay.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/uxplay.cpp b/uxplay.cpp index 914c263..d66c34b 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -52,6 +52,9 @@ # include # else # include +# ifdef __OpenBSD__ +# include +# endif # endif #endif @@ -2179,6 +2182,12 @@ int main (int argc, char *argv[]) { std::vector server_hw_addr; std::string config_file = ""; +#ifdef __OpenBSD__ + if (unveil("/", "rwc") == -1 || unveil(NULL, NULL) == -1) { + err(1, "unveil"); + } +#endif + #ifdef SUPPRESS_AVAHI_COMPAT_WARNING // suppress avahi_compat nag message. avahi emits a "nag" warning (once) // if getenv("AVAHI_COMPAT_NOWARN") returns null. @@ -2340,6 +2349,12 @@ int main (int argc, char *argv[]) { video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), videosink_options.c_str(), fullscreen, video_sync, h265_support, playbin_version, NULL); video_renderer_start(); +#ifdef __OpenBSD__ + } else { + if (pledge("stdio rpath wpath cpath inet unix prot_exec", NULL) == -1) { + err(1, "pledge"); + } +#endif } if (udp[0]) { From 47120552c468a1ba29f8147537460500361a43eb Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Wed, 16 Apr 2025 19:07:44 -0400 Subject: [PATCH 33/65] add -md option to output audio-mode metadata text to file --- README.html | 19 +++++++---- README.md | 7 ++++ README.txt | 15 +++++--- uxplay.1 | 2 ++ uxplay.cpp | 98 ++++++++++++++++++++++++++++++++++++++--------------- 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/README.html b/README.html index 77cbffe..aedb5c7 100644 --- a/README.html +++ b/README.html @@ -57,9 +57,9 @@ alt="Current Packaging status" />.

  • Install uxplay on Debian-based Linux systems with “sudo apt install uxplay”; on FreeBSD with “sudo pkg install uxplay”; on OpenBSD with -“doas pkg_add uxplay”. Also available on Arch-based -systems through AUR. Since v. 1.66, uxplay is now also packaged in RPM -format by Fedora 38 (“sudo dnf install uxplay”).

  • +“doas pkg_add uxplay”. Also available on Arch-based systems +through AUR. Since v. 1.66, uxplay is now also packaged in RPM format by +Fedora 38 (“sudo dnf install uxplay”).

  • For other RPM-based distributions which have not yet packaged UxPlay, a RPM “specfile” uxplay.spec is now provided with recent

  • OpenBSD: Install gstreamer1-libav, -gstreamer1-plugins-* (* = core, bad, base, good). avahi-main must also -be installed for the avahi_daemon rc startup script.

  • +gstreamer-plugins-* (* = core, bad, base, good). avahi-main must also be +installed for the avahi_daemon rc startup script.

    Starting and running UxPlay

    Since UxPlay-1.64, UxPlay can be started with options read from a @@ -1174,6 +1174,11 @@ then run the the image viewer in the foreground. Example, using in which uxplay was put into the background). To quit, use ctrl-C fg ctrl-C to terminate the image viewer, bring uxplay into the foreground, and terminate it too.

    +

    -md filename Like the -ca option, but +exports audio metadata text (Artist, Title, Genre, etc.) to file for +possible display by a process that watches the file for changes. +Previous text is overwritten as new metadata is received, and the file +is deleted when uxplay terminates.

    -reset n sets a limit of n consecutive failures of the client to send feedback requests (these “heartbeat signals” are sent by the client once per second to ask for a response @@ -1620,7 +1625,9 @@ introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

    Changelog

    1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows.

    +only for YouTube movies. Fix issue with NTP timeout on Windows. Add +requested option -md <filename> to output audio metadata text to a +file for possible display (complements -ca option).

    1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer >= 1.24 when client sleeps, then wakes.

    diff --git a/README.md b/README.md index 621cf19..5ee18f6 100644 --- a/README.md +++ b/README.md @@ -1195,6 +1195,11 @@ uxplay was put into the background). To quit, use `ctrl-C fg ctrl-C` to terminate the image viewer, bring `uxplay` into the foreground, and terminate it too. +**-md *filename*** Like the -ca option, but exports audio metadata text +(Artist, Title, Genre, etc.) to file for possible display by a process that watches +the file for changes. Previous text is overwritten as new metadata is received, +and the file is deleted when uxplay terminates. + **-reset n** sets a limit of *n* consecutive failures of the client to send feedback requests (these "heartbeat signals" are sent by the client once per second to ask for a response showing that the server is still online). @@ -1666,6 +1671,8 @@ what version UxPlay claims to be. 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially only for YouTube movies. Fix issue with NTP timeout on Windows. +Add requested option -md \ to output audio metadata text to a file +for possible display (complements -ca option). 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/README.txt b/README.txt index 8eed072..fb71b6e 100644 --- a/README.txt +++ b/README.txt @@ -459,9 +459,9 @@ repositories for those distributions. gstreamer1-plugins-\* (\* = core, good, bad, x, gtk, gl, vulkan, pulse, v4l2, ...), (+ gstreamer1-vaapi for Intel/AMD graphics). -- **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* - (\* = core, bad, base, good). avahi-main must also be installed for - the avahi_daemon rc startup script. +- **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* (\* = + core, bad, base, good). avahi-main must also be installed for the + avahi_daemon rc startup script. ### Starting and running UxPlay @@ -1196,6 +1196,11 @@ uxplay was put into the background). To quit, use `ctrl-C fg ctrl-C` to terminate the image viewer, bring `uxplay` into the foreground, and terminate it too. +**-md *filename*** Like the -ca option, but exports audio metadata text +(Artist, Title, Genre, etc.) to file for possible display by a process +that watches the file for changes. Previous text is overwritten as new +metadata is received, and the file is deleted when uxplay terminates. + **-reset n** sets a limit of *n* consecutive failures of the client to send feedback requests (these "heartbeat signals" are sent by the client once per second to ask for a response showing that the server is still @@ -1665,7 +1670,9 @@ what version UxPlay claims to be. # Changelog 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows. +only for YouTube movies. Fix issue with NTP timeout on Windows. Add +requested option -md \ to output audio metadata text to a +file for possible display (complements -ca option). 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/uxplay.1 b/uxplay.1 index 29b1179..6c930d2 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -108,6 +108,8 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-ca\fI fn \fR In Airplay Audio (ALAC) mode, write cover-art to file fn. .TP +\fB\-md\fI fn \fR In Airplay Audio (ALAC) mode, write metadata text to file fn. +.TP \fB\-reset\fR n Reset after n seconds client silence (default n=15, 0=never). .TP \fB\-nofreeze\fR Do NOT leave frozen screen in place after reset. diff --git a/uxplay.cpp b/uxplay.cpp index d66c34b..0fd3b60 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -125,6 +125,7 @@ static unsigned char audio_type = 0x00; static unsigned char previous_audio_type = 0x00; static bool fullscreen = false; static std::string coverart_filename = ""; +static std::string metadata_filename = ""; static bool do_append_hostname = true; static bool use_random_hw_addr = false; static unsigned short display[5] = {0}, tcp[3] = {0}, udp[3] = {0}; @@ -232,6 +233,13 @@ static size_t write_coverart(const char *filename, const void *image, size_t len return count; } +static size_t write_metadata(const char *filename, const char *text) { + FILE *fp = fopen(filename, "wb"); + size_t count = fwrite(text, sizeof(char), strlen(text) + 1, fp); + fclose(fp); + return count; +} + static char *create_pin_display(char *pin_str, int margin, int gap) { char *ptr; char num[2] = { 0 }; @@ -695,6 +703,7 @@ static void print_info (char *name) { printf("-as 0 (or -a) Turn audio off, streamed video only\n"); printf("-al x Audio latency in seconds (default 0.25) reported to client.\n"); printf("-ca In Airplay Audio (ALAC) mode, write cover-art to file \n"); + printf("-md In Airplay Audio (ALAC) mode, write metadata text to file \n"); printf("-reset n Reset after n seconds of client silence (default n=%d, 0=never)\n", MISSED_FEEDBACK_LIMIT); printf("-nofreeze Do NOT leave frozen screen in place after reset\n"); printf("-nc Do NOT Close video window when client stops mirroring\n"); @@ -1137,6 +1146,19 @@ static void parse_arguments (int argc, char *argv[]) { fprintf(stderr,"option -ca must be followed by a filename for cover-art output\n"); exit(1); } + } else if (arg == "-md" ) { + if (option_has_value(i, argc, arg, argv[i+1])) { + metadata_filename.erase(); + metadata_filename.append(argv[++i]); + const char *fn = metadata_filename.c_str(); + if (!file_has_write_access(fn)) { + fprintf(stderr, "%s cannot be written to:\noption \"-ca \" must be to a file with write access\n", fn); + exit(1); + } + } else { + fprintf(stderr,"option -md must be followed by a filename for metadata text output\n"); + exit(1); + } } else if (arg == "-bt709") { bt709_fix = true; } else if (arg == "-srgb") { @@ -1262,7 +1284,7 @@ static void parse_arguments (int argc, char *argv[]) { } } -static void process_metadata(int count, const char *dmap_tag, const unsigned char* metadata, int datalen) { +static void process_metadata(int count, const char *dmap_tag, const unsigned char* metadata, int datalen, std::string *metadata_text) { int dmap_type = 0; /* DMAP metadata items can be strings (dmap_type = 9); other types are byte, short, int, long, date, and list. * * The DMAP item begins with a 4-character (4-letter) "dmap_tag" string that identifies the type. */ @@ -1284,13 +1306,13 @@ static void process_metadata(int count, const char *dmap_tag, const unsigned cha case 'a': switch (dmap_tag[3]) { case 'a': - printf("Album artist: "); /*asaa*/ + metadata_text->append("Album artist: "); /*asaa*/ break; case 'l': - printf("Album: "); /*asal*/ + metadata_text->append("Album: "); /*asal*/ break; case 'r': - printf("Artist: "); /*asar*/ + metadata_text->append("Artist: "); /*asar*/ break; default: dmap_type = 0; @@ -1300,16 +1322,16 @@ static void process_metadata(int count, const char *dmap_tag, const unsigned cha case 'c': switch (dmap_tag[3]) { case 'm': - printf("Comment: "); /*ascm*/ + metadata_text->append("Comment: "); /*ascm*/ break; case 'n': - printf("Content description: "); /*ascn*/ + metadata_text->append("Content description: "); /*ascn*/ break; case 'p': - printf("Composer: "); /*ascp*/ + metadata_text->append("Composer: "); /*ascp*/ break; case 't': - printf("Category: "); /*asct*/ + metadata_text->append("Category: "); /*asct*/ break; default: dmap_type = 0; @@ -1319,22 +1341,22 @@ static void process_metadata(int count, const char *dmap_tag, const unsigned cha case 's': switch (dmap_tag[3]) { case 'a': - printf("Sort Artist: "); /*assa*/ + metadata_text->append("Sort Artist: "); /*assa*/ break; case 'c': - printf("Sort Composer: "); /*assc*/ + metadata_text->append("Sort Composer: "); /*assc*/ break; case 'l': - printf("Sort Album artist: "); /*assl*/ + metadata_text->append("Sort Album artist: "); /*assl*/ break; case 'n': - printf("Sort Name: "); /*assn*/ + metadata_text->append("Sort Name: "); /*assn*/ break; case 's': - printf("Sort Series: "); /*asss*/ + metadata_text->append("Sort Series: "); /*asss*/ break; case 'u': - printf("Sort Album: "); /*assu*/ + metadata_text->append("Sort Album: "); /*assu*/ break; default: dmap_type = 0; @@ -1343,15 +1365,15 @@ static void process_metadata(int count, const char *dmap_tag, const unsigned cha break; default: if (strcmp(dmap_tag, "asdt") == 0) { - printf("Description: "); + metadata_text->append("Description: "); } else if (strcmp (dmap_tag, "asfm") == 0) { - printf("Format: "); + metadata_text->append("Format: "); } else if (strcmp (dmap_tag, "asgn") == 0) { - printf("Genre: "); + metadata_text->append("Genre: "); } else if (strcmp (dmap_tag, "asky") == 0) { - printf("Keywords: "); + metadata_text->append("Keywords: "); } else if (strcmp (dmap_tag, "aslc") == 0) { - printf("Long Content Description: "); + metadata_text->append("Long Content Description: "); } else { dmap_type = 0; } @@ -1359,21 +1381,27 @@ static void process_metadata(int count, const char *dmap_tag, const unsigned cha } } else if (strcmp (dmap_tag, "minm") == 0) { dmap_type = 9; - printf("Title: "); + metadata_text->append("Title: "); } if (dmap_type == 9) { - char *str = (char *) calloc(1, datalen + 1); + char *str = (char *) calloc(datalen + 1, sizeof(char)); memcpy(str, metadata, datalen); - printf("%s", str); + metadata_text->append(str); + metadata_text->append("\n"); free(str); } else if (debug_log) { + std::string md = ""; + char hex[4]; for (int i = 0; i < datalen; i++) { - if (i > 0 && i % 16 == 0) printf("\n"); - printf("%2.2x ", (int) metadata[i]); + if (i > 0 && i % 16 == 0) { + md.append("\n"); + } + snprintf(hex, 4, "%2.2x ", (int) metadata[i]); + md.append(hex); } + LOGI("%s", md.c_str()); } - printf("\n"); } static int parse_dmap_header(const unsigned char *metadata, char *tag, int *len) { @@ -1833,6 +1861,9 @@ extern "C" void audio_get_format (void *cls, unsigned char *ct, unsigned short * if (coverart_filename.length()) { write_coverart(coverart_filename.c_str(), (const void *) empty_image, sizeof(empty_image)); } + if (metadata_filename.length()) { + write_metadata(metadata_filename.c_str(), "no data\n"); + } } extern "C" void video_report_size(void *cls, float *width_source, float *height_source, float *width, float *height) { @@ -1879,6 +1910,7 @@ extern "C" void audio_set_metadata(void *cls, const void *buffer, int buflen) { dmap_tag, datalen, buflen); return; } + std::string metadata_text = ""; while (buflen >= 8) { count++; if (parse_dmap_header(metadata, dmap_tag, &datalen)) { @@ -1887,12 +1919,16 @@ extern "C" void audio_set_metadata(void *cls, const void *buffer, int buflen) { } metadata += 8; buflen -= 8; - process_metadata(count, (const char *) dmap_tag, metadata, datalen); + process_metadata(count, (const char *) dmap_tag, metadata, datalen, &metadata_text); metadata += datalen; buflen -= datalen; } + LOGI("%s", metadata_text.c_str()); + if (metadata_filename.length()) { + write_metadata(metadata_filename.c_str(), metadata_text.c_str()); + } if (buflen != 0) { - LOGE("%d bytes of metadata were not processed", buflen); + LOGE("%d bytes of metadata were not processed", buflen); } } @@ -2381,6 +2417,11 @@ int main (int argc, char *argv[]) { write_coverart(coverart_filename.c_str(), (const void *) empty_image, sizeof(empty_image)); } + if (metadata_filename.length()) { + LOGI("any AirPlay audio metadata text will be written to file %s",metadata_filename.c_str()); + write_metadata(metadata_filename.c_str(), "no data\n"); + } + /* set default resolutions for h264 or h265*/ if (!display[0] && !display[1]) { if (h265_support) { @@ -2459,4 +2500,7 @@ int main (int argc, char *argv[]) { if (coverart_filename.length()) { remove (coverart_filename.c_str()); } + if (metadata_filename.length()) { + remove (metadata_filename.c_str()); + } } From 9d6a3e2af888147d89f45562911f544a69749b68 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 22 Apr 2025 03:47:30 -0400 Subject: [PATCH 34/65] add -vol option --- README.html | 10 +++++++--- README.md | 9 +++++++-- README.txt | 11 ++++++++--- lib/raop.h | 1 + lib/raop_handlers.h | 6 ++++-- uxplay.1 | 2 ++ uxplay.cpp | 45 ++++++++++++++++++++++++++++++++++++++------- 7 files changed, 67 insertions(+), 17 deletions(-) diff --git a/README.html b/README.html index aedb5c7..10ff849 100644 --- a/README.html +++ b/README.html @@ -1046,6 +1046,9 @@ each time the length of the volume slider (or the number of steps above mute, where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the “untapered” volume if it is louder.)

    +

    -vol v Sets initial audio-streaming volume +(on client): range is [0:1], with 0.0 = mute, 1.0 = full volume +(v is a decimal number).

    -s wxh e.g. -s 1920x1080 (= “1080p”), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= “4K”) when the -h265 option is used.) This is just @@ -1624,10 +1627,11 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

    Changelog

    +

    1.72 2024-04-22 Add requested options -md <filename> to output +audio metadata text to a file for possible display (complements -ca +option), and -vol option to set initial audio-streaming volume.

    1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows. Add -requested option -md <filename> to output audio metadata text to a -file for possible display (complements -ca option).

    +only for YouTube movies. Fix issue with NTP timeout on Windows.

    1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer >= 1.24 when client sleeps, then wakes.

    diff --git a/README.md b/README.md index 5ee18f6..3f6db3d 100644 --- a/README.md +++ b/README.md @@ -1054,6 +1054,9 @@ where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the "untapered" volume if it is louder.) +**-vol *v*** Sets initial audio-streaming volume (on client): range is [0:1], +with 0.0 = mute, 1.0 = full volume (*v* is a decimal number). + **-s wxh** e.g. -s 1920x1080 (= "1080p"), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= "4K") when the -h265 option is used.) This is just a request made to the @@ -1669,10 +1672,12 @@ what version UxPlay claims to be. # Changelog +1.72 2024-04-22 Add requested options -md \ to output audio +metadata text to a file for possible display (complements -ca option), +and -vol option to set initial audio-streaming volume. + 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially only for YouTube movies. Fix issue with NTP timeout on Windows. -Add requested option -md \ to output audio metadata text to a file -for possible display (complements -ca option). 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/README.txt b/README.txt index fb71b6e..5a4bca0 100644 --- a/README.txt +++ b/README.txt @@ -1055,6 +1055,9 @@ where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the "untapered" volume if it is louder.) +**-vol *v*** Sets initial audio-streaming volume (on client): range is +\[0:1\], with 0.0 = mute, 1.0 = full volume (*v* is a decimal number). + **-s wxh** e.g. -s 1920x1080 (= "1080p"), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= "4K") when the -h265 option is used.) This is just a request made to the @@ -1669,10 +1672,12 @@ what version UxPlay claims to be. # Changelog +1.72 2024-04-22 Add requested options -md \ to output audio +metadata text to a file for possible display (complements -ca option), +and -vol ``{=html} option to set initial audio-streaming volume. + 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows. Add -requested option -md \ to output audio metadata text to a -file for possible display (complements -ca option). +only for YouTube movies. Fix issue with NTP timeout on Windows. 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/lib/raop.h b/lib/raop.h index 50c9f71..0cb96ac 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -78,6 +78,7 @@ struct raop_callbacks_s { void (*conn_teardown)(void *cls, bool *teardown_96, bool *teardown_110 ); void (*audio_flush)(void *cls); void (*video_flush)(void *cls); + double (*audio_set_client_volume)(void *cls); void (*audio_set_volume)(void *cls, float volume); void (*audio_set_metadata)(void *cls, const void *buffer, int buflen); void (*audio_set_coverart)(void *cls, const void *buffer, int buflen); diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 3f34e0d..f760d02 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -903,8 +903,10 @@ raop_handler_get_parameter(raop_conn_t *conn, /* This is a bit ugly, but seems to be how airport works too */ if ((datalen - (current - data) >= 8) && !strncmp(current, "volume\r\n", 8)) { - const char volume[] = "volume: 0.0\r\n"; - + char volume[25] = "volume: 0.0\r\n"; + if (conn->raop->callbacks.audio_set_client_volume) { + snprintf(volume, 25, "volume: %9.6f\r\n", conn->raop->callbacks.audio_set_client_volume(conn->raop->callbacks.cls)); + } http_response_add_header(response, "Content-Type", "text/parameters"); *response_data = strdup(volume); if (*response_data) { diff --git a/uxplay.1 b/uxplay.1 index 6c930d2..6531a2f 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -44,6 +44,8 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-taper\fR Use a "tapered" AirPlay volume-control profile. .TP +\fB\-vol\fI v \fR Set initial audio-streaming volume: range [mute=0.0:1.0=full]. +.TP \fB\-s\fR wxh[@r]Request to client for video display resolution [refresh_rate] .IP default 1920x1080[@60] (or 3840x2160[@60] with -h265 option). diff --git a/uxplay.cpp b/uxplay.cpp index 0fd3b60..2ec5708 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -154,6 +154,7 @@ static std::vector registered_keys; static double db_low = -30.0; static double db_high = 0.0; static bool taper_volume = false; +static double initial_volume = 0.0; static bool h265_support = false; static int n_renderers = 0; static bool hls_support = false; @@ -672,6 +673,7 @@ static void print_info (char *name) { printf("-db l[:h] Set minimum volume attenuation to l dB (decibels, negative);\n"); printf(" optional: set maximum to h dB (+ or -) default: -30.0:0.0 dB\n"); printf("-taper Use a \"tapered\" AirPlay volume-control profile\n"); + printf("-vol Set initial audio-streaming volume: range [mute=0.0:1.0=full]\n"); printf("-s wxh[@r]Request to client for video display resolution [refresh_rate]\n"); printf(" default 1920x1080[@60] (or 3840x2160[@60] with -h265 option)\n"); printf("-o Set display \"overscanned\" mode on (not usually needed)\n"); @@ -1240,29 +1242,53 @@ static void parse_arguments (int argc, char *argv[]) { } else if (arg == "-db") { bool db_bad = true; double db1, db2; - char *start = NULL; if ( i < argc -1) { char *end1, *end2; - start = argv[i+1]; - db1 = strtod(start, &end1); - if (end1 > start && *end1 == ':') { + db1 = strtod(argv[i+1], &end1); + if (*end1 == ':') { db2 = strtod(++end1, &end2); if ( *end2 == '\0' && end2 > end1 && db1 < 0 && db1 < db2) { db_bad = false; } - } else if (*end1 =='\0' && end1 > start && db1 < 0 ) { + } else if (*end1 =='\0' && db1 < 0 ) { db_bad = false; db2 = 0.0; } } if (db_bad) { - fprintf(stderr, "invalid %s %s: db value must be \"low\" or \"low:high\", low < 0 and high > low are decibel gains\n", argv[i], start); + fprintf(stderr, "invalid \"-db %s\": db value must be \"low\" or \"low:high\", low < 0 and high > low are decibel gains\n", argv[i+1]); exit(1); } i++; db_low = db1; db_high = db2; - printf("db range %f:%f\n", db_low, db_high); + printf("db range %f:%f\n", db_low, db_high); + } else if (arg == "-vol") { + bool vol_bad = true; + if (i < argc - 1) { + char *end; + double frac = strtod(argv[i+1], &end); + if (*end == '\0' && frac >= 0.0 && frac <= 1.0) { + if (frac == 0.0) { + initial_volume = -144.0; + } else if (frac == 1.0) { + initial_volume = 0.0; + } else { + double db_flat = -30.0 + 30.0*frac; + //double db = 10.0 * (log10(frac) / log10(2.0)); //tapered + //printf("db %f db_flat %f \n", db, db_flat); + //db = (db > db_flat) ? db : db_flat; + initial_volume = db_flat; + } + } + printf("initial_volume attenuation %f db\n", initial_volume); + vol_bad = false; + } + if (vol_bad) { + fprintf(stderr, "invalid \"-vol %s\", value must be between 0.0 (mute) and 1.0 (full volume)\n", argv[i+1]); + exit(1); + } + i++; } else if (arg == "-hls") { hls_support = true; if (i < argc - 1 && *argv[i+1] != '-') { @@ -1789,6 +1815,10 @@ extern "C" void video_flush (void *cls) { } } +extern "C" double audio_set_client_volume(void *cls) { + return initial_volume; +} + extern "C" void audio_set_volume (void *cls, float volume) { double db, db_flat, frac, gst_volume; if (!use_audio) { @@ -2047,6 +2077,7 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3], raop_cbs.video_flush = video_flush; raop_cbs.video_pause = video_pause; raop_cbs.video_resume = video_resume; + raop_cbs.audio_set_client_volume = audio_set_client_volume; raop_cbs.audio_set_volume = audio_set_volume; raop_cbs.audio_get_format = audio_get_format; raop_cbs.video_report_size = video_report_size; From 2f809eeadd1a9e88192e9278d7df4f9f9ff3e6c8 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 22 Apr 2025 14:42:12 -0400 Subject: [PATCH 35/65] fix to make sure pts is not less than gst_video_pipeline_base_time --- renderers/video_renderer.c | 5 +++-- renderers/video_renderer.h | 2 +- uxplay.cpp | 12 ++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/renderers/video_renderer.c b/renderers/video_renderer.c index 6c59b31..7c6af65 100644 --- a/renderers/video_renderer.c +++ b/renderers/video_renderer.c @@ -452,7 +452,7 @@ bool waiting_for_x11_window() { return false; } -void video_renderer_render_buffer(unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time) { +uint64_t video_renderer_render_buffer(unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time) { GstBuffer *buffer; GstClockTime pts = (GstClockTime) *ntp_time; /*now in nsecs */ //GstClockTimeDiff latency = GST_CLOCK_DIFF(gst_element_get_current_clock_time (renderer->appsrc), pts); @@ -462,7 +462,7 @@ void video_renderer_render_buffer(unsigned char* data, int *data_len, int *nal_c } else { logger_log(logger, LOGGER_ERR, "*** invalid ntp_time < gst_video_pipeline_base_time\n%8.6f ntp_time\n%8.6f base_time", ((double) *ntp_time) / SECOND_IN_NSECS, ((double) gst_video_pipeline_base_time) / SECOND_IN_NSECS); - return; + return (uint64_t) gst_video_pipeline_base_time - pts; } } g_assert(data_len != 0); @@ -499,6 +499,7 @@ void video_renderer_render_buffer(unsigned char* data, int *data_len, int *nal_c } #endif } + return 0; } void video_renderer_flush() { diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 9e2e944..0a34805 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -57,7 +57,7 @@ void video_renderer_seek(float position); void video_renderer_set_start(float position); void video_renderer_resume (); bool video_renderer_is_paused(); -void video_renderer_render_buffer (unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time); +uint64_t video_renderer_render_buffer (unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time); void video_renderer_flush (); unsigned int video_renderer_listen(void *loop, int id); void video_renderer_destroy (); diff --git a/uxplay.cpp b/uxplay.cpp index 2ec5708..acdf7f6 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -1785,8 +1785,16 @@ extern "C" void video_process (void *cls, raop_ntp_t *ntp, video_decode_struct * uint64_t local_time = (data->ntp_time_local ? data->ntp_time_local : get_local_time()); remote_clock_offset = local_time - data->ntp_time_remote; } - data->ntp_time_remote = data->ntp_time_remote + remote_clock_offset; - video_renderer_render_buffer(data->data, &(data->data_len), &(data->nal_count), &(data->ntp_time_remote)); + int count = 0; + uint64_t pts_mismatch = 0; + do { + data->ntp_time_remote = data->ntp_time_remote + remote_clock_offset; + pts_mismatch = video_renderer_render_buffer(data->data, &(data->data_len), &(data->nal_count), &(data->ntp_time_remote)); + if (pts_mismatch) { + remote_clock_offset += pts_mismatch; + } + count++; + } while (pts_mismatch && count < 10); } } From be4fb423c40cd55e9dbc9f742287f4a4318b9d72 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 22 Apr 2025 17:13:13 -0400 Subject: [PATCH 36/65] add suppport for user access control by -pw password (HTML digest) --- README.html | 57 +++++++++++----- README.md | 41 ++++++++--- README.txt | 49 +++++++++---- lib/crypto.c | 60 +++++++++++++++- lib/crypto.h | 9 +++ lib/dnssd.c | 47 +++++++++---- lib/dnssd.h | 2 +- lib/dnssdint.h | 2 +- lib/pairing.c | 163 ++++++++++++++++++++++++++++++++++++++++++++ lib/pairing.h | 3 + lib/raop.c | 27 ++++++-- lib/raop.h | 1 + lib/raop_handlers.h | 111 ++++++++++++++++++++++++++++-- lib/utils.c | 12 ++-- lib/utils.h | 2 +- uxplay.1 | 7 ++ uxplay.cpp | 54 ++++++++++++--- 17 files changed, 566 insertions(+), 81 deletions(-) diff --git a/README.html b/README.html index 10ff849..505bf7f 100644 --- a/README.html +++ b/README.html @@ -1,24 +1,26 @@

    UxPlay -1.71: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix -(now also runs on Windows).

    +id="uxplay-1.72-beta-airplay-mirror-and-airplay-audio-server-for-linux-macos-and-unix-now-also-runs-on-windows.">UxPlay +1.72 (beta): AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, +and Unix (now also runs on Windows).

    Now developed at the GitHub site https://github.com/FDH2/UxPlay (where ALL user issues should be posted, and latest versions can be found).

    Highlights:

    Highlights:

    @@ -1650,12 +1653,8 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

    Changelog

    -

    1.72 2025-05-03. Improved HLS Live Streaming (YouTube) support. Add -support for password (HTTP Digest Authentication, -pw option) as -alternative to on-screen one-time pin codes. Add requested options -md -to export audio-mode metadata text to a file for display, and -vol for -setting initial audio-streaming volume on client.

    -

    1.72 2024-04-22 Add requested options -md <filename> to output +

    1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, +including “scrub”. Add requested options -md <filename> to output audio metadata text to a file for possible display (complements -ca option), and -vol option to set initial audio-streaming volume. Add support password user access control with HTTP digest Authentication diff --git a/README.md b/README.md index f62a187..8de9264 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ * in HLS video streaming from the YouTube app (-hls option), rendered using GStreamer's media player "playbin3" (or playbin2, with option -hls 2), we don't understand how to correctly deal with "interstitials" (= 15 sec commercials) when "skip" is pressed on the client. - (HLS is handled by handlers in lib/http_handlers.h) + (HLS is handled by handlers in lib/http_handlers.h). (Should response to HTTP requests POST /action (playlistRemove) and POST + /Stop be modified? _Wireshark data from HLS on an AppleTV model 3 with UN-upgraded original OS (unencrypted communications) could be useful!_ ## Highlights: @@ -1690,13 +1691,9 @@ introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be. # Changelog -1.72 2025-05-03. Improved HLS Live Streaming (YouTube) support. -Add support for password (HTTP Digest Authentication, -pw option) as -alternative to on-screen one-time pin codes. Add requested options --md to export audio-mode metadata text to a file for display, and --vol for setting initial audio-streaming volume on client. - -1.72 2024-04-22 Add requested options -md \ to output audio +1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, including +"scrub". +Add requested options -md \ to output audio metadata text to a file for possible display (complements -ca option), and -vol option to set initial audio-streaming volume. Add support password user access control with HTTP digest Authentication (-pw [pwd]). diff --git a/README.txt b/README.txt index d09aa71..a6f5fd4 100644 --- a/README.txt +++ b/README.txt @@ -27,7 +27,10 @@ with option -hls 2), we don't understand how to correctly deal with "interstitials" (= 15 sec commercials) when "skip" is pressed on the client. (HLS is handled by handlers in - lib/http_handlers.h) + lib/http_handlers.h). (Should response to HTTP requests POST + /action (playlistRemove) and POST /Stop be modified? *Wireshark + data from HLS on an AppleTV model 3 with UN-upgraded original OS + (unencrypted communications) could be useful!* ## Highlights: @@ -1697,18 +1700,13 @@ what version UxPlay claims to be. # Changelog -1.72 2025-05-03. Improved HLS Live Streaming (YouTube) support. Add -support for password (HTTP Digest Authentication, -pw option) as -alternative to on-screen one-time pin codes. Add requested options -md -to export audio-mode metadata text to a file for display, and -vol for -setting initial audio-streaming volume on client. - -1.72 2024-04-22 Add requested options -md \ to output audio -metadata text to a file for possible display (complements -ca option), -and -vol ``{=html} option to set initial audio-streaming volume. Add -support password user access control with HTTP digest Authentication -(-pw \[pwd\]). If no pwd is set, a random pin is displayed for entry at -each new connection. +1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, +including "scrub". Add requested options -md \ to output +audio metadata text to a file for possible display (complements -ca +option), and -vol ``{=html} option to set initial audio-streaming +volume. Add support password user access control with HTTP digest +Authentication (-pw \[pwd\]). If no pwd is set, a random pin is +displayed for entry at each new connection. 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially only for YouTube movies. Fix issue with NTP timeout on Windows. From 3bb34553c0e367a409b41b526b0e73ce4f74f837 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Wed, 7 May 2025 13:09:46 -0400 Subject: [PATCH 52/65] Windows: README update; use d3d11 as default videosink --- README.html | 93 ++++++++++++++++++++++++++++++++--------------------- README.md | 69 ++++++++++++++++++++++----------------- README.txt | 89 ++++++++++++++++++++++++++++++-------------------- uxplay.cpp | 30 ++++++++++++++--- 4 files changed, 176 insertions(+), 105 deletions(-) diff --git a/README.html b/README.html index ac51b77..4202942 100644 --- a/README.html +++ b/README.html @@ -852,22 +852,38 @@ href="https://www.msys2.org">https://www.msys2.org/. Accept the default installation location C:\mysys64.

  • MSYS2 packages are installed with a variant of the “pacman” package manager used by -Arch Linux. Open a “MSYS2 MINGW64” terminal from the MSYS2 tab in the -Windows Start menu, and update the new MSYS2 installation with “pacman --Syu”. Then install the MinGW-64 compiler and -cmake

    -
    pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc
    -

    The compiler with all required dependencies will be installed in the -msys64 directory, with default path C:/msys64/mingw64. Here -we will simply build UxPlay from the command line in the MSYS2 -environment (this uses “ninja” in place of -“make” for the build system).

  • +Arch Linux. Open a “MSYS2” terminal from the MSYS2 tab in the Windows +Start menu, and update the new MSYS2 installation with “pacman +-Syu”.

    + +
      +
    1. change the MSYS2 terminal type from UCRT64 to MINGW64; (2) modify +mingw-w64-ucrt-x86_64-* package names to mingw-w64-x86_64-*, (just omit +“-ucrt”);
    2. +
    3. replace ucrt64 by mingw64 in directory +names._
    4. +
    +

    Open a new MSYS2 UCRT64 terminal, and install the gcc compiler and +cmake:

    +

    pacman -S mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc

    +

    We will simply build UxPlay from the command line in the MSYS2 +environment (using “ninja” in place of “make” +for the build system).

  • Download the latest UxPlay from github (to use git, install it with pacman -S git, then “git clone https://github.com/FDH2/UxPlay”), then install UxPlay dependencies (openssl is already installed with MSYS2):

    -

    pacman -S mingw-w64-x86_64-libplist mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base

    +
    `pacman -S mingw-w64-ucrt-x86_64-libplist mingw-w64-ucrt-x86_64-gstreamer mingw-w64-ucrt-x86_64-gst-plugins-base`

    If you are trying a different Windows build system, MSVC versions of GStreamer for Windows are available from the official GStreamer @@ -884,19 +900,23 @@ build UxPlay with

  • Assuming no error in either of these, you will have built the uxplay executable uxplay.exe in the current (“build”) directory. The “sudo make install” and “sudo make uninstall” features -offered in the other builds are not available on Windows; instead, the -MSYS2 environment has /mingw64/... available, and you can -install the uxplay.exe executable in C:/msys64/mingw64/bin -(plus manpage and documentation in -C:/msys64/mingw64/share/...) with

    -

    cmake --install . --prefix /mingw64

    +offered in the other builds are not available on Windows; instead, you +can install the uxplay.exe executable in +C:/msys64/ucrt64/bin (plus manpage and documentation in +C:/msys64/ucrt64/share/...) with

    +

    cmake --install . --prefix $HOME/../../ucrt64

    +

    You can later uninstall uxplay by returning to the build directory +and running

    +

    ninja uninstall

    +

    (This assumes that certain files in the build directory were not +deleted since building UxPlay).

    To be able to view the manpage, you need to install the manpage viewer with “pacman -S man”.

  • To run uxplay.exe you need to install some gstreamer plugin packages with -pacman -S mingw-w64-x86_64-gst-<plugin>, where the -required ones have <plugin> given by

    +pacman -S mingw-w64-ucrt-x86_64-gst-<plugin>, where +the required ones have <plugin> given by

    1. libav
    2. plugins-good
    3. @@ -913,9 +933,9 @@ Settings->Update and Security->Windows Security->Firewall & network protection -> allow an app through firewall. If your virus protection flags uxplay.exe as “suspicious” (but without a true malware signature) you may need to give it an exception.

      -

      Now test by running “uxplay” (in a MSYS2 terminal -window). If you need to specify the audiosink, there are two main -choices on Windows: the older DirectSound plugin +

      Now test by running “uxplay” (in a MSYS2 UCRT64 terminal +window. If you need to specify the audiosink, there are two main choices +on Windows: the older DirectSound plugin “-as directsoundsink”, and the more modern Windows Audio Session API (wasapi) plugin “-as wasapisink”, which supports device” is not specified, the default audio device is used.

      If you wish to specify the videosink using the -vs <videosink> option, some choices for -<videosink> are d3d11videosink, -d3dvideosink, glimagesink, -gtksink.

      +<videosink> are d3d12videosink, +d3d11videosink, d3dvideosink, +glimagesink, gtksink, +autovideosink. If you do not specify the videosink, the +d3d11videosink will be used (users have reported segfaults of the newer +d3d12 videodecoder on certain older Nvidia cards when the image +resolution changes: d3d11 will used by default until this is fixed).

        -
      • With Direct3D 11.0 or greater, you can either always be in -fullscreen mode using option --vs "d3d11videosink fullscreen-toggle-mode=property fullscreen=true", -or get the ability to toggle into and out of fullscreen mode using the -Alt-Enter key combination with option --vs "d3d11videosink fullscreen-toggle-mode=alt-enter". For -convenience, these options will be added if just --vs d3d11videosink with or without the fullscreen option -“-fs” is used. (Windows users may wish to add -“vs d3d11videosink” (no initial “-”) to the -UxPlay startup options file; see “man uxplay” or “uxplay -h”.)
      • +
      • With Direct3D 11.0 or greater, various options can be set using +e.g. -vs "d3d11videosink <options>" (see the +gstreamer videosink documentation for these videosinks). For +convenience, if no <options> are set, the option to +toggle in and out of fullscreen mode with the Alt-Enter key combination +is added.

      The executable uxplay.exe can also be run without the MSYS2 environment, in the Windows Terminal, with -C:\msys64\mingw64\bin\uxplay.

      +C:\msys64\ucrt64\bin\uxplay.

      Usage

      Options:

      -

      After installation:

      +

      After installation:

      -

      To (easily) compile the latest UxPlay from source, see the section Getting UxPlay.

      Detailed description of UxPlay

      This project is a GPLv3 open source unix AirPlay2 Mirror server for @@ -261,7 +289,7 @@ can be regarded as a “System Library”, which it is in *BSD). Many Linux distributions treat OpenSSL as a “System Library”, but some (e.g. Debian) do not: in this case, the issue is solved by linking with OpenSSL-3.0.0 or later.

      -

      Getting UxPlay

      +

      Building UxPlay from source

      Either download and unzip UxPlay-master.zip, or (if git is installed): “git clone https://github.com/FDH2/UxPlay”. @@ -526,7 +554,7 @@ href="#usage">Usage for details, if you wish to use it. Some clients with MDM (Mobile Device Management, often present on employer-owned devices) are required to use pin-authentication: UxPlay will provide this even when running without the pin option. -Password authentication (-pw pwd)is also offered as an +Password authentication (-pw pwd) is also offered as an alternative solution to pin codes: users need to know the password pwd and enter it on their iOS/macOS device to access UxPlay, when prompted (if pwd is not set, a displayed random pin code diff --git a/README.md b/README.md index 543c6f5..af66a00 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,12 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo See the section on using this specfile for [building an installable RPM package](#building-an-installable-rpm-package). -After installation: +- If your distribution does not supply UxPlay, or you want the latest version, + it is very easy to build it yourself: see the very + [detailed instructions for building UxPlay from source](#building-uxplay-from-source). + later in this document. + +## After installation: - (On Linux and \*BSD): if a firewall is active on the server hosting UxPlay, make sure the default network port (UDP 5353) for @@ -90,6 +95,10 @@ After installation: with the option "uxplay -async", but there is then a 2 second latency imposed by iOS. +- If you are using UxPlay just to mirror the client's screen (without + showing videos that need audio synchronized with video), it is best to + use the option "uxplay -vsync no". + - Add any UxPlay options you want to use as defaults to a startup file `~/.uxplayrc` (see "`man uxplay`" or "`uxplay -h`" for format and other possible locations). In particular, if your system uses @@ -98,6 +107,22 @@ After installation: from terminal commands "ps waux \| grep pulse" or "pactl info" will contain "pipewire" if your Linux/BSD system uses it).* +- For Linux systems using systemd, there is a **systemd** service file **uxplay.service** + found in the UxPlay top directory of the distribution, and also installed + in `/uxplay/systemd/` (where DOCDIR is usually ``/usr/local/share/doc``), that allows users to start + their own instance of UxPlay as a rootless daemon: it should either be added to the + directory /etc/systemd/user, or the user can just create their own + systemd directory `~/.config/systemd/user/` and then copy uxplay.service into it. To save + uxplay terminal output to a file ~/uxplay.log, uncomment the StandardOutput entry in + uxplay.service. Then + + `systemctl --user [start/stop/enable/disable/status] uxplay` + + can be used to control the daemon. If it is enabled, the daemon will start + at the user's first login and stop when they no longer have any open sessions. See + https://www.baeldung.com/linux/systemd-create-user-services for more about + systemd user services. **Note: it is NOT recommended to run UxPlay as a root service.** + - On Raspberry Pi: models using hardware h264 video decoding by the Broadcom GPU (models 4B and earlier) may require the uxplay option -bt709. If you use Ubuntu 22.10 or earlier, GStreamer must @@ -108,9 +133,10 @@ After installation: decoding is used seems to have reappeared starting with GStreamer-1.22. -To (easily) compile the latest UxPlay from source, see the section -[Getting UxPlay](#getting-uxplay). - +- If UxPlay is used in a public space, there are security options for requiring an AppleTV-style + one-time pin (displayed on the terminal) to be entered, or a password, and for barring/permitting + client access by their device ID. See options -pin, -reg, -pw, -restrict, -allow, -block. + # Detailed description of UxPlay This project is a GPLv3 open source unix AirPlay2 Mirror server for @@ -252,7 +278,7 @@ clause incompatible with the GPL unless OpenSSL can be regarded as a OpenSSL as a "System Library", but some (e.g. Debian) do not: in this case, the issue is solved by linking with OpenSSL-3.0.0 or later. -# Getting UxPlay +# Building UxPlay from source Either download and unzip [UxPlay-master.zip](https://github.com/FDH2/UxPlay/archive/refs/heads/master.zip), @@ -512,7 +538,7 @@ below for help with this or other problems. with MDM (Mobile Device Management, often present on employer-owned devices) are required to use pin-authentication: UxPlay will provide this even when running without the pin option.* Password authentication - (-pw _pwd_)is also offered as an alternative solution to pin codes: + (-pw _pwd_) is also offered as an alternative solution to pin codes: users need to know the password _pwd_ and enter it on their iOS/macOS device to access UxPlay, when prompted (if _pwd_ is not set, a displayed random pin code must be entered at **each** new connection.) diff --git a/README.txt b/README.txt index cd372fe..7eb51a8 100644 --- a/README.txt +++ b/README.txt @@ -79,7 +79,12 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo See the section on using this specfile for [building an installable RPM package](#building-an-installable-rpm-package). -After installation: +- If your distribution does not supply UxPlay, or you want the latest + version, it is very easy to build it yourself: see the very + [detailed instructions for building UxPlay from + source](#building-uxplay-from-source). later in this document. + +## After installation: - (On Linux and \*BSD): if a firewall is active on the server hosting UxPlay, make sure the default network port (UDP 5353) for @@ -97,6 +102,10 @@ After installation: with the option "uxplay -async", but there is then a 2 second latency imposed by iOS. +- If you are using UxPlay just to mirror the client's screen (without + showing videos that need audio synchronized with video), it is best + to use the option "uxplay -vsync no". + - Add any UxPlay options you want to use as defaults to a startup file `~/.uxplayrc` (see "`man uxplay`" or "`uxplay -h`" for format and other possible locations). In particular, if your system uses @@ -105,6 +114,26 @@ After installation: from terminal commands "ps waux \| grep pulse" or "pactl info" will contain "pipewire" if your Linux/BSD system uses it).* +- For Linux systems using systemd, there is a **systemd** service file + **uxplay.service** found in the UxPlay top directory of the + distribution, and also installed in `/uxplay/systemd/` + (where DOCDIR is usually `/usr/local/share/doc`), that allows users + to start their own instance of UxPlay as a rootless daemon: it + should either be added to the directory /etc/systemd/user, or the + user can just create their own systemd directory + `~/.config/systemd/user/` and then copy uxplay.service into it. To + save uxplay terminal output to a file \~/uxplay.log, uncomment the + StandardOutput entry in uxplay.service. Then + + `systemctl --user [start/stop/enable/disable/status] uxplay` + + can be used to control the daemon. If it is enabled, the daemon will + start at the user's first login and stop when they no longer have + any open sessions. See + https://www.baeldung.com/linux/systemd-create-user-services for more + about systemd user services. **Note: it is NOT recommended to run + UxPlay as a root service.** + - On Raspberry Pi: models using hardware h264 video decoding by the Broadcom GPU (models 4B and earlier) may require the uxplay option -bt709. If you use Ubuntu 22.10 or earlier, GStreamer must be @@ -115,8 +144,11 @@ After installation: video decoding is used seems to have reappeared starting with GStreamer-1.22. -To (easily) compile the latest UxPlay from source, see the section -[Getting UxPlay](#getting-uxplay). +- If UxPlay is used in a public space, there are security options for + requiring an AppleTV-style one-time pin (displayed on the terminal) + to be entered, or a password, and for barring/permitting client + access by their device ID. See options -pin, -reg, -pw, -restrict, + -allow, -block. # Detailed description of UxPlay @@ -259,7 +291,7 @@ clause incompatible with the GPL unless OpenSSL can be regarded as a OpenSSL as a "System Library", but some (e.g. Debian) do not: in this case, the issue is solved by linking with OpenSSL-3.0.0 or later. -# Getting UxPlay +# Building UxPlay from source Either download and unzip [UxPlay-master.zip](https://github.com/FDH2/UxPlay/archive/refs/heads/master.zip), @@ -519,11 +551,11 @@ below for help with this or other problems. with MDM (Mobile Device Management, often present on employer-owned devices) are required to use pin-authentication: UxPlay will provide this even when running without the pin option.* Password - authentication (-pw *pwd*)is also offered as an alternative solution - to pin codes: users need to know the password *pwd* and enter it on - their iOS/macOS device to access UxPlay, when prompted (if *pwd* is - not set, a displayed random pin code must be entered at **each** new - connection.) + authentication (-pw *pwd*) is also offered as an alternative + solution to pin codes: users need to know the password *pwd* and + enter it on their iOS/macOS device to access UxPlay, when prompted + (if *pwd* is not set, a displayed random pin code must be entered at + **each** new connection.) - By default, UxPlay is locked to its current client until that client drops the connection; since UxPlay-1.58, the option `-nohold` diff --git a/uxplay.service b/uxplay.service index 7b7c651..50f0c27 100644 --- a/uxplay.service +++ b/uxplay.service @@ -7,6 +7,7 @@ After=avahi-daemon Type=simple ExecStart=uxplay Restart=on-failure +#StandardOutput=file:%h/uxplay.log [Install] WantedBy=default.target From ffa0c61d5e9a247104ec4afafade21b6e2bc230d Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Wed, 14 May 2025 13:04:34 -0400 Subject: [PATCH 56/65] add -rc option to specify startup options file --- README.html | 19 ++++++++++++------- README.md | 16 +++++++++++----- README.txt | 28 +++++++++++++++++----------- uxplay.1 | 2 ++ uxplay.cpp | 29 +++++++++++++++++++++++++++-- 5 files changed, 69 insertions(+), 25 deletions(-) diff --git a/README.html b/README.html index eb7d65a..1120dee 100644 --- a/README.html +++ b/README.html @@ -113,7 +113,8 @@ imposed by iOS.

      best to use the option “uxplay -vsync no”.

    4. Add any UxPlay options you want to use as defaults to a startup file ~/.uxplayrc (see “man uxplay” or -“uxplay -h” for format and other possible locations). In +“uxplay -h” for format and other possible locations; the +location can also be set with “uxplay -rc location”). In particular, if your system uses PipeWire audio or Wayland video systems, you may wish to add “as pipewiresink” or “vs waylandsink” as defaults to the file. (Output from terminal commands “ps waux | grep pulse” or @@ -135,8 +136,10 @@ uxplay.service. Then

      start at the user’s first login and stop when they no longer have any open sessions. See https://www.baeldung.com/linux/systemd-create-user-services for more -about systemd user services. Note: it is NOT recommended to run -UxPlay as a root service.

    5. +about systemd user services. If more than one user might simultaneously +run uxplay this way, they should specify distinct -p and -m options +(ports and deviceID) in their startup files. Note: it is NOT +recommended to run UxPlay as a root service.

    6. On Raspberry Pi: models using hardware h264 video decoding by the Broadcom GPU (models 4B and earlier) may require the uxplay option -bt709. If you use Ubuntu 22.10 or earlier, GStreamer must be

    7. OpenBSD: (doas pkg_add) libplist gstreamer1-plugins-base. avahi-libs must also be installed to provide -the dns_sd library. OpenSSL is already installed as a System -Library.

    8. +the dns_sd library; (avahi-main must also be installed). OpenSSL is +already installed as a System Library.

      Building an installable RPM package

      @@ -513,8 +516,7 @@ gstreamer1-plugins, gstreamer1-plugins-* (* = core, good, bad, x, gtk, gl, vulkan, pulse, v4l2, …), (+ gstreamer1-vaapi for Intel/AMD graphics).

    9. OpenBSD: Install gstreamer1-libav, -gstreamer-plugins-* (* = core, bad, base, good). avahi-main must also be -installed for the avahi_daemon rc startup script.

    10. +gstreamer-plugins-* (* = core, bad, base, good).

      Starting and running UxPlay

      Since UxPlay-1.64, UxPlay can be started with options read from a @@ -1007,6 +1009,9 @@ or ~/.config/uxplayrc); lines begining with “#” are treated as comments, and ignored. Command line options supersede options in the startup file. +

      -rc file can also be used to specify the +startup file location: this overrides $UXPLAYRC, +~/.uxplayrc, etc.

      -n server_name (Default: UxPlay); server_name@_hostname_ will be the name that appears offering AirPlay services to your iPad, iPhone etc, where hostname is the name diff --git a/README.md b/README.md index af66a00..115bebf 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,8 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - Add any UxPlay options you want to use as defaults to a startup file `~/.uxplayrc` (see "`man uxplay`" or "`uxplay -h`" for format and - other possible locations). In particular, if your system uses + other possible locations; the location can also be set with "uxplay -rc _location_"). + In particular, if your system uses PipeWire audio or Wayland video systems, you may wish to add "as pipewiresink" or "vs waylandsink" as defaults to the file. *(Output from terminal commands "ps waux \| grep pulse" or "pactl info" will @@ -121,7 +122,9 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo can be used to control the daemon. If it is enabled, the daemon will start at the user's first login and stop when they no longer have any open sessions. See https://www.baeldung.com/linux/systemd-create-user-services for more about - systemd user services. **Note: it is NOT recommended to run UxPlay as a root service.** + systemd user services. If more than one user might simultaneously run uxplay this way, they should + specify distinct -p and -m options (ports and deviceID) in their startup files. + **Note: it is NOT recommended to run UxPlay as a root service.** - On Raspberry Pi: models using hardware h264 video decoding by the Broadcom GPU (models 4B and earlier) may require the uxplay option -bt709. @@ -413,7 +416,8 @@ package](#building-an-installable-rpm-package). dns_sd library. OpenSSL is already installed as a System Library. - **OpenBSD:** (doas pkg_add) libplist gstreamer1-plugins-base. - avahi-libs must also be installed to provide the dns_sd library. + avahi-libs must also be installed to provide the dns_sd library; + (avahi-main must also be installed). OpenSSL is already installed as a System Library. #### Building an installable RPM package @@ -498,8 +502,7 @@ repositories for those distributions. pulse, v4l2, ...), (+ gstreamer1-vaapi for Intel/AMD graphics). - **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* - (\* = core, bad, base, good). avahi-main must also be installed for - the avahi_daemon rc startup script. + (\* = core, bad, base, good). ### Starting and running UxPlay @@ -995,6 +998,9 @@ Options: comments, and ignored. Command line options supersede options in the startup file. +**-rc _file_** can also be used to specify the startup file location: this +overrides `$UXPLAYRC`, ``~/.uxplayrc``, etc. + **-n server_name** (Default: UxPlay); server_name@\_hostname\_ will be the name that appears offering AirPlay services to your iPad, iPhone etc, where *hostname* is the name of the server running uxplay. This diff --git a/README.txt b/README.txt index 7eb51a8..b5a7538 100644 --- a/README.txt +++ b/README.txt @@ -108,11 +108,12 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - Add any UxPlay options you want to use as defaults to a startup file `~/.uxplayrc` (see "`man uxplay`" or "`uxplay -h`" for format and - other possible locations). In particular, if your system uses - PipeWire audio or Wayland video systems, you may wish to add "as - pipewiresink" or "vs waylandsink" as defaults to the file. *(Output - from terminal commands "ps waux \| grep pulse" or "pactl info" will - contain "pipewire" if your Linux/BSD system uses it).* + other possible locations; the location can also be set with "uxplay + -rc *location*"). In particular, if your system uses PipeWire audio + or Wayland video systems, you may wish to add "as pipewiresink" or + "vs waylandsink" as defaults to the file. *(Output from terminal + commands "ps waux \| grep pulse" or "pactl info" will contain + "pipewire" if your Linux/BSD system uses it).* - For Linux systems using systemd, there is a **systemd** service file **uxplay.service** found in the UxPlay top directory of the @@ -131,8 +132,10 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo start at the user's first login and stop when they no longer have any open sessions. See https://www.baeldung.com/linux/systemd-create-user-services for more - about systemd user services. **Note: it is NOT recommended to run - UxPlay as a root service.** + about systemd user services. If more than one user might + simultaneously run uxplay this way, they should specify distinct -p + and -m options (ports and deviceID) in their startup files. **Note: + it is NOT recommended to run UxPlay as a root service.** - On Raspberry Pi: models using hardware h264 video decoding by the Broadcom GPU (models 4B and earlier) may require the uxplay option @@ -426,8 +429,9 @@ package](#building-an-installable-rpm-package). dns_sd library. OpenSSL is already installed as a System Library. - **OpenBSD:** (doas pkg_add) libplist gstreamer1-plugins-base. - avahi-libs must also be installed to provide the dns_sd library. - OpenSSL is already installed as a System Library. + avahi-libs must also be installed to provide the dns_sd library; + (avahi-main must also be installed). OpenSSL is already installed as + a System Library. #### Building an installable RPM package @@ -511,8 +515,7 @@ repositories for those distributions. pulse, v4l2, ...), (+ gstreamer1-vaapi for Intel/AMD graphics). - **OpenBSD:** Install gstreamer1-libav, gstreamer-plugins-\* (\* = - core, bad, base, good). avahi-main must also be installed for the - avahi_daemon rc startup script. + core, bad, base, good). ### Starting and running UxPlay @@ -1019,6 +1022,9 @@ Options: comments, and ignored. Command line options supersede options in the startup file. +**-rc *file*** can also be used to specify the startup file location: +this overrides `$UXPLAYRC`, `~/.uxplayrc`, etc. + **-n server_name** (Default: UxPlay); server_name@\_hostname\_ will be the name that appears offering AirPlay services to your iPad, iPhone etc, where *hostname* is the name of the server running uxplay. This diff --git a/uxplay.1 b/uxplay.1 index c2739ae..3675670 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -181,6 +181,8 @@ UxPlay 1.72: An open\-source AirPlay mirroring (+ audio streaming) server: \fB\-v\fR Displays version information .TP \fB\-h\fR Displays help information +.TP +\fB\-rc\fI fn\fR Read startup options from file "fn" instead of ~/.uxplayrc, etc .SH FILES Options in one of $UXPLAYRC, or ~/.uxplayrc, or ~/.config/uxplayrc diff --git a/uxplay.cpp b/uxplay.cpp index fb0cc8c..0eadbef 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -741,6 +741,7 @@ static void print_info (char *name) { printf("-d [n] Enable debug logging; optional: n=1 to skip normal packet data\n"); printf("-v Displays version information\n"); printf("-h Displays this help\n"); + printf("-rc fn Read startup options from file \"fn\" instead of ~/.uxplayrc, etc\n"); printf("Startup options in $UXPLAYRC, ~/.uxplayrc, or ~/.config/uxplayrc are\n"); printf("applied first (command-line options may modify them): format is one \n"); printf("option per line, no initial \"-\"; lines starting with \"#\" are ignored.\n"); @@ -882,7 +883,9 @@ static void parse_arguments (int argc, char *argv[]) { // Parse arguments for (int i = 1; i < argc; i++) { std::string arg(argv[i]); - if (arg == "-allow") { + if (arg == "-rc") { + i++; //specifies startup file: has already been processed + } else if (arg == "-allow") { if (!option_has_value(i, argc, arg, argv[i+1])) exit(1); i++; allowed_clients.push_back(argv[i]); @@ -2310,7 +2313,29 @@ int main (int argc, char *argv[]) { if (!getenv("AVAHI_COMPAT_NOWARN")) putenv(avahi_compat_nowarn); #endif - config_file = find_uxplay_config_file(); + char *rcfile = NULL; + /* see if option -rc was given */ + for (int i = 1; i < argc ; i++) { + std::string arg(argv[i]); + if (arg == "-rc") { + struct stat sb; + if (i+1 == argc) { + LOGE ("option -rc requires a filename (-rc )"); + exit(1); + } + rcfile = argv[i+1]; + if (stat(rcfile, &sb) == -1) { + LOGE("startup file %s specified by option -rc was not found", rcfile); + exit(0); + } + break; + } + } + if (rcfile) { + config_file = rcfile; + } else { + config_file = find_uxplay_config_file(); + } if (config_file.length()) { read_config_file(config_file.c_str(), argv[0]); } From 878ccf2400a56ee4499749b5c09c7d8423b0f3c2 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Wed, 21 May 2025 10:59:28 -0400 Subject: [PATCH 57/65] add "-nc no" to unset nc option (for macOS, where -nc is default) --- README.html | 27 +++++++++++---------------- README.md | 26 +++++++++++--------------- README.txt | 27 +++++++++++---------------- uxplay.1 | 4 +++- uxplay.cpp | 21 +++++++++++++++++---- 5 files changed, 53 insertions(+), 52 deletions(-) diff --git a/README.html b/README.html index 1120dee..0e87632 100644 --- a/README.html +++ b/README.html @@ -841,23 +841,18 @@ another error (about videometa) that shows up in the GStreamer warnings. “-vsync no” (you can add a line “vsync no” in the uxplayrc configuration file).

    11. On macOS with this installation of GStreamer, the only videosinks -available seem to be glimagesink (default choice made by autovideosink) -and osxvideosink. The window title does not show the Airplay server -name, but the window is visible to screen-sharing apps (e.g., Zoom). The -only available audiosink seems to be osxaudiosink.

    12. -
    13. The option -nc is always used, whether or not it is selected. -This is a workaround for a problem with GStreamer videosinks on macOS: -if the GStreamer pipeline is destroyed while the mirror window is still -open, a segfault occurs.

    14. -
    15. In the case of glimagesink, the resolution settings “-s wxh” do +available are glimagesink (default choice made by autovideosink) and +osxvideosink. The window title does not show the Airplay server name, +but the window can be shared on Zoom. Because of issues with +glimagesink, you may find osxvideosink works better. The only available +audiosink is osxaudiosink.

    16. +
    17. The option -nc is currently used by default om macOS, This is a +workaround for window-closing problems with GStreamer videosinks on +macOS. In anticipation of fixes, this option can be canceled with “-nc +no”, if not needed.

    18. +
    19. In the case of glimagesink, the resolution settings “-s wxh” may not affect the (small) initial OpenGL mirror window size, but the window -can be expanded using the mouse or trackpad. In contrast, a window -created with “-vs osxvideosink” is initially big, but has the wrong -aspect ratio (stretched image); in this case the aspect ratio changes -when the window width is changed by dragging its side; the option --vs "osxvideosink force-aspect-ratio=true" can be used to -make the window have the correct aspect ratio when it first -opens.

    20. +can be expanded using the mouse or trackpad.

      Building diff --git a/README.md b/README.md index 115bebf..4772596 100644 --- a/README.md +++ b/README.md @@ -834,25 +834,21 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with the uxplayrc configuration file). - On macOS with this installation of GStreamer, the only videosinks - available seem to be glimagesink (default choice made by - autovideosink) and osxvideosink. The window title does not show the - Airplay server name, but the window is visible to screen-sharing - apps (e.g., Zoom). The only available audiosink seems to be + available are glimagesink (default choice made by + autovideosink) and osxvideosink. + The window title does not show the + Airplay server name, but the window can be shared on Zoom. + Because of issues with glimagesink, you may find + osxvideosink works better. The only available audiosink is osxaudiosink. -- The option -nc is always used, whether or not it is selected. This - is a workaround for a problem with GStreamer videosinks on macOS: if - the GStreamer pipeline is destroyed while the mirror window is still - open, a segfault occurs. +- The option -nc is currently used by default om macOS, This + is a workaround for window-closing problems with GStreamer videosinks on macOS. + In anticipation of fixes, this option can be canceled with "-nc no", if not needed. -- In the case of glimagesink, the resolution settings "-s wxh" do not +- In the case of glimagesink, the resolution settings "-s wxh" may not affect the (small) initial OpenGL mirror window size, but the window - can be expanded using the mouse or trackpad. In contrast, a window - created with "-vs osxvideosink" is initially big, but has the wrong - aspect ratio (stretched image); in this case the aspect ratio - changes when the window width is changed by dragging its side; the - option `-vs "osxvideosink force-aspect-ratio=true"` can be used to - make the window have the correct aspect ratio when it first opens. + can be expanded using the mouse or trackpad. ## Building UxPlay on Microsoft Windows, using MSYS2 with the MinGW-64 compiler. diff --git a/README.txt b/README.txt index b5a7538..4e4d602 100644 --- a/README.txt +++ b/README.txt @@ -850,25 +850,20 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with the uxplayrc configuration file). - On macOS with this installation of GStreamer, the only videosinks - available seem to be glimagesink (default choice made by - autovideosink) and osxvideosink. The window title does not show the - Airplay server name, but the window is visible to screen-sharing - apps (e.g., Zoom). The only available audiosink seems to be - osxaudiosink. + available are glimagesink (default choice made by autovideosink) and + osxvideosink. The window title does not show the Airplay server + name, but the window can be shared on Zoom. Because of issues with + glimagesink, you may find osxvideosink works better. The only + available audiosink is osxaudiosink. -- The option -nc is always used, whether or not it is selected. This - is a workaround for a problem with GStreamer videosinks on macOS: if - the GStreamer pipeline is destroyed while the mirror window is still - open, a segfault occurs. +- The option -nc is currently used by default om macOS, This is a + workaround for window-closing problems with GStreamer videosinks on + macOS. In anticipation of fixes, this option can be canceled with + "-nc no", if not needed. -- In the case of glimagesink, the resolution settings "-s wxh" do not +- In the case of glimagesink, the resolution settings "-s wxh" may not affect the (small) initial OpenGL mirror window size, but the window - can be expanded using the mouse or trackpad. In contrast, a window - created with "-vs osxvideosink" is initially big, but has the wrong - aspect ratio (stretched image); in this case the aspect ratio - changes when the window width is changed by dragging its side; the - option `-vs "osxvideosink force-aspect-ratio=true"` can be used to - make the window have the correct aspect ratio when it first opens. + can be expanded using the mouse or trackpad. ## Building UxPlay on Microsoft Windows, using MSYS2 with the MinGW-64 compiler. diff --git a/uxplay.1 b/uxplay.1 index 3675670..f4554e3 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -123,7 +123,9 @@ UxPlay 1.72: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-nofreeze\fR Do NOT leave frozen screen in place after reset. .TP -\fB\-nc\fR Do NOT close video window when client stops mirroring +\fB\-nc\fR Do NOT close video window when client stops mirroring. +.TP +\fB\-nc\fR no Cancel the -nc option (DO close video window). .TP \fB\-nohold\fR Drop current connection when new client connects. .TP diff --git a/uxplay.cpp b/uxplay.cpp index 0eadbef..7fb0815 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -103,7 +103,11 @@ static unsigned char compression_type = 0; static std::string audiosink = "autoaudiosink"; static int audiodelay = -1; static bool use_audio = true; +#if __APPLE__ +static bool new_window_closing_behavior = false; +#else static bool new_window_closing_behavior = true; +#endif static bool close_window; static std::string video_parser = "h264parse"; static std::string video_decoder = "decodebin"; @@ -714,7 +718,8 @@ static void print_info (char *name) { printf("-md In Airplay Audio (ALAC) mode, write metadata text to file \n"); printf("-reset n Reset after n seconds of client silence (default n=%d, 0=never)\n", MISSED_FEEDBACK_LIMIT); printf("-nofreeze Do NOT leave frozen screen in place after reset\n"); - printf("-nc Do NOT Close video window when client stops mirroring\n"); + printf("-nc Do NOT Close video window when client stops mirroring\n"); + printf("-nc no Cancel the -nc option (DO close video window) \n"); printf("-nohold Drop current connection when new client connects.\n"); printf("-restrict Restrict clients to those specified by \"-allow \"\n"); printf(" UxPlay displays deviceID when a client attempts to connect\n"); @@ -1063,6 +1068,13 @@ static void parse_arguments (int argc, char *argv[]) { exit(1); } else if (arg == "-nc") { new_window_closing_behavior = false; + if (i < argc - 1) { + if (strlen(argv[i+1]) == 2 && strncmp(argv[i+1], "no", 2) == 0) { + new_window_closing_behavior = true; + i++; + continue; + } + } } else if (arg == "-avdec") { video_parser.erase(); video_parser = "h264parse"; @@ -2376,9 +2388,10 @@ int main (int argc, char *argv[]) { } #if __APPLE__ - /* force use of -nc option on macOS */ - LOGI("macOS detected: using -nc option as workaround for GStreamer problem"); - new_window_closing_behavior = false; + /* warn about default use of -nc option on macOS */ + if (!new_window_closing_behavior) { + LOGI("UxPlay on macOS is using -nc option as workaround for GStreamer problem: use \"-nc no\" to omit workaround"); + } #endif #ifdef _WIN32 From e306bbf72ed6bd6cd149b28f30f22d1777e2f657 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Thu, 5 Jun 2025 12:49:04 -0400 Subject: [PATCH 58/65] cleanup to fix bug/regression in -reg option --- lib/pairing.c | 5 ++--- lib/pairing.h | 2 +- lib/raop_handlers.h | 13 ++++--------- uxplay.cpp | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/pairing.c b/lib/pairing.c index b6141bd..3660e6e 100644 --- a/lib/pairing.c +++ b/lib/pairing.c @@ -626,11 +626,10 @@ srp_confirm_pair_setup(pairing_session_t *session, pairing_t *pairing, return epk_len; } -void access_client_session_data(pairing_session_t *session, char **username, char **client_pk64, bool *setup) { +void get_pairing_session_client_data(pairing_session_t *session, char **username, char **client_pk64) { int len64 = 4 * (1 + (ED25519_KEY_SIZE / 3)) + 1; - setup = &(session->pair_setup); *username = session->username; - if (setup) { + if (session->pair_setup) { *client_pk64 = (char *) malloc(len64); pk_to_base64(session->client_pk, ED25519_KEY_SIZE, *client_pk64, len64); } else { diff --git a/lib/pairing.h b/lib/pairing.h index 83075d0..cdb1374 100644 --- a/lib/pairing.h +++ b/lib/pairing.h @@ -60,7 +60,7 @@ int srp_validate_proof(pairing_session_t *session, pairing_t *pairing, const uns int len_A, unsigned char *proof, int client_proof_len, int proof_len); int srp_confirm_pair_setup(pairing_session_t *session, pairing_t *pairing, unsigned char *epk, unsigned char *auth_tag); -void access_client_session_data(pairing_session_t *session, char **username, char **client_pk, bool *setup); +void get_pairing_session_client_data(pairing_session_t *session, char **username, char **client_pk); void ed25519_pk_to_base64(const unsigned char *pk, char **pk64); int pairing_session_make_nonce(pairing_session_t *session, uint64_t *local_time, const char *client_data, unsigned char *nonce, int len); bool pairing_digest_verify(const char *method, const char * authorization, const char *password); diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 81dbf0b..37d3db9 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -690,16 +690,11 @@ raop_handler_setup(raop_conn_t *conn, conn->raop->callbacks.report_client_request(conn->raop->callbacks.cls, deviceID, model, name, &admit_client); } if (admit_client && deviceID && name && conn->raop->callbacks.register_client) { - bool pending_registration = false;; char *client_device_id = NULL; - char *client_pk = NULL; /* encoded as null-terminated base64 string*/ - access_client_session_data(conn->session, &client_device_id, &client_pk, &pending_registration); - if (pending_registration) { - if (client_pk && !strcmp(deviceID, client_device_id)) { - conn->raop->callbacks.register_client(conn->raop->callbacks.cls, client_device_id, client_pk, name); - } - } - if (client_pk) { + char *client_pk = NULL; /* encoded as null-terminated base64 string, must be freed*/ + get_pairing_session_client_data(conn->session, &client_device_id, &client_pk); + if (client_pk && !strcmp(deviceID, client_device_id)) { + conn->raop->callbacks.register_client(conn->raop->callbacks.cls, client_device_id, client_pk, name); free (client_pk); } } diff --git a/uxplay.cpp b/uxplay.cpp index 7fb0815..b869806 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -1226,7 +1226,7 @@ static void parse_arguments (int argc, char *argv[]) { pairing_register.append(argv[++i]); const char * fn = pairing_register.c_str(); if (!file_has_write_access(fn)) { - fprintf(stderr, "%s cannot be written to:\noption \"-key \" must be to a file with write access\n", fn); + fprintf(stderr, "%s cannot be written to:\noption \"-reg \" must be to a file with write access\n", fn); exit(1); } } From afebae6891333b8751e8e10db7f8596f3b1cd62a Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Fri, 6 Jun 2025 09:51:12 -0400 Subject: [PATCH 59/65] 1.72.1 release: README update, uxplay.spec update --- README.html | 21 +++++++++++++-------- README.md | 18 ++++++++++++------ README.txt | 25 +++++++++++++++---------- uxplay.spec | 6 +++--- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/README.html b/README.html index 0e87632..1bdc809 100644 --- a/README.html +++ b/README.html @@ -754,10 +754,10 @@ FILE (which can be /dev/null to discard it)

      id="building-uxplay-on-macos-intel-x86_64-and-apple-silicon-m1m2-macs">Building UxPlay on macOS: (Intel X86_64 and “Apple Silicon” M1/M2 Macs)

      -

      Note: A native AirPlay Server feature is included in macOS 12 -Monterey, but is restricted to recent hardware. UxPlay can run on older -macOS systems that will not be able to run Monterey, or can run Monterey -but not AirPlay.

      +

      Note: A native AirPlay Server feature is included in macOS since +macOS 12 Monterey, but is restricted to recent hardware. As well as +running on latest macOS, UxPlay can run on older macOS systems that will +cannot run Monterey, or can run Monterey but not AirPlay.

      These instructions for macOS assume that the Xcode command-line developer tools are installed (if Xcode is installed, open the Terminal, type “sudo xcode-select –install” and accept the conditions).

      @@ -837,7 +837,7 @@ with “export GST_DEBUG=2” before runnng UxPlay) reveals that with the default (since UxPlay 1.64) use of timestamps for video synchonization, many video frames are being dropped (only on macOS), perhaps due to another error (about videometa) that shows up in the GStreamer warnings. -Recommendation: use the new UxPlay “no timestamp” option +Recommendation: use the UxPlay “no timestamp” option “-vsync no (you can add a line “vsync no” in the uxplayrc configuration file).

    21. On macOS with this installation of GStreamer, the only videosinks @@ -846,10 +846,10 @@ osxvideosink. The window title does not show the Airplay server name, but the window can be shared on Zoom. Because of issues with glimagesink, you may find osxvideosink works better. The only available audiosink is osxaudiosink.

    22. -
    23. The option -nc is currently used by default om macOS, This is a +

    24. The option -nc is currently used by default on macOS, This is a workaround for window-closing problems with GStreamer videosinks on -macOS. In anticipation of fixes, this option can be canceled with “-nc -no”, if not needed.

    25. +macOS. This option can be canceled with “-nc no”, if not +needed.

    26. In the case of glimagesink, the resolution settings “-s wxh” may not affect the (small) initial OpenGL mirror window size, but the window can be expanded using the mouse or trackpad.

    27. @@ -1700,6 +1700,11 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

      Changelog

      +

      1.72.1 2025-06-06 minor update: fix regression in -reg option; add +option -rc to specify initialization file; add “-nc no” to +unset “-nc” option (for macOS users, where -nc is default); add +user-installable systemd script for running UxPlay as an +always-available “rootless daemon”

      1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, including “scrub”. Add requested options -md <filename> to output audio metadata text to a file for possible display (complements -ca diff --git a/README.md b/README.md index 4772596..76c17fe 100644 --- a/README.md +++ b/README.md @@ -745,9 +745,10 @@ running if the ssh session is closed. Terminal output is saved to FILE ## Building UxPlay on macOS: **(Intel X86_64 and "Apple Silicon" M1/M2 Macs)** -*Note: A native AirPlay Server feature is included in macOS 12 Monterey, -but is restricted to recent hardware. UxPlay can run on older macOS -systems that will not be able to run Monterey, or can run Monterey but +*Note: A native AirPlay Server feature is included in macOS since macOS 12 Monterey, +but is restricted to recent hardware. As well as running on latest macOS, +UxPlay can run on older macOS +systems that will cannot run Monterey, or can run Monterey but not AirPlay.* These instructions for macOS assume that the Xcode command-line @@ -829,7 +830,7 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with default (since UxPlay 1.64) use of timestamps for video synchonization, many video frames are being dropped (only on macOS), perhaps due to another error (about videometa) that shows up in the - GStreamer warnings. **Recommendation: use the new UxPlay "no + GStreamer warnings. **Recommendation: use the UxPlay "no timestamp" option "`-vsync no`"** (you can add a line "vsync no" in the uxplayrc configuration file). @@ -842,9 +843,9 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with osxvideosink works better. The only available audiosink is osxaudiosink. -- The option -nc is currently used by default om macOS, This +- The option -nc is currently used by default on macOS, This is a workaround for window-closing problems with GStreamer videosinks on macOS. - In anticipation of fixes, this option can be canceled with "-nc no", if not needed. + This option can be canceled with "-nc no", if not needed. - In the case of glimagesink, the resolution settings "-s wxh" may not affect the (small) initial OpenGL mirror window size, but the window @@ -1730,6 +1731,11 @@ introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be. # Changelog +1.72.1 2025-06-06 minor update: fix regression in -reg option; add option +-rc to specify initialization file; add "-nc no" to unset "-nc" +option (for macOS users, where -nc is default); add user-installable +systemd script for running UxPlay as an always-available "rootless daemon" + 1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, including "scrub". Add requested options -md \ to output audio diff --git a/README.txt b/README.txt index 4e4d602..aca484c 100644 --- a/README.txt +++ b/README.txt @@ -761,10 +761,10 @@ running if the ssh session is closed. Terminal output is saved to FILE ## Building UxPlay on macOS: **(Intel X86_64 and "Apple Silicon" M1/M2 Macs)** -*Note: A native AirPlay Server feature is included in macOS 12 Monterey, -but is restricted to recent hardware. UxPlay can run on older macOS -systems that will not be able to run Monterey, or can run Monterey but -not AirPlay.* +*Note: A native AirPlay Server feature is included in macOS since macOS +12 Monterey, but is restricted to recent hardware. As well as running on +latest macOS, UxPlay can run on older macOS systems that will cannot run +Monterey, or can run Monterey but not AirPlay.* These instructions for macOS assume that the Xcode command-line developer tools are installed (if Xcode is installed, open the Terminal, @@ -845,9 +845,9 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with default (since UxPlay 1.64) use of timestamps for video synchonization, many video frames are being dropped (only on macOS), perhaps due to another error (about videometa) that shows up in the - GStreamer warnings. **Recommendation: use the new UxPlay "no - timestamp" option "`-vsync no`"** (you can add a line "vsync no" in - the uxplayrc configuration file). + GStreamer warnings. **Recommendation: use the UxPlay "no timestamp" + option "`-vsync no`"** (you can add a line "vsync no" in the + uxplayrc configuration file). - On macOS with this installation of GStreamer, the only videosinks available are glimagesink (default choice made by autovideosink) and @@ -856,10 +856,9 @@ downloads, "UxPlay" for "git clone" downloads) and build/install with glimagesink, you may find osxvideosink works better. The only available audiosink is osxaudiosink. -- The option -nc is currently used by default om macOS, This is a +- The option -nc is currently used by default on macOS, This is a workaround for window-closing problems with GStreamer videosinks on - macOS. In anticipation of fixes, this option can be canceled with - "-nc no", if not needed. + macOS. This option can be canceled with "-nc no", if not needed. - In the case of glimagesink, the resolution settings "-s wxh" may not affect the (small) initial OpenGL mirror window size, but the window @@ -1752,6 +1751,12 @@ what version UxPlay claims to be. # Changelog +1.72.1 2025-06-06 minor update: fix regression in -reg option; add +option -rc ``{=html} to specify initialization file; add "-nc +no" to unset "-nc" option (for macOS users, where -nc is default); add +user-installable systemd script for running UxPlay as an +always-available "rootless daemon" + 1.72 2025-05-07. Improved HLS Live Streaming (YouTube) support, including "scrub". Add requested options -md \ to output audio metadata text to a file for possible display (complements -ca diff --git a/uxplay.spec b/uxplay.spec index 85b4f96..87d46b1 100644 --- a/uxplay.spec +++ b/uxplay.spec @@ -1,5 +1,5 @@ Name: uxplay -Version: 1.72 +Version: 1.72.1 Release: 1%{?dist} %global gittag v%{version} @@ -135,8 +135,8 @@ cd build %{_docdir}/%{name}/llhttp/LICENSE-MIT %changelog -* Thu May 1 2025 UxPlay maintainer - Update for 1.72 release +* Thu Jun 5 2025 UxPlay maintainer + Update for 1.72.1 release * Fri Nov 15 2024 UxPlay maintainer Initial uxplay.spec: tested on Fedora 38, Rocky Linux 9.2, OpenSUSE Leap 15.5, Mageia 9, OpenMandriva ROME, PCLinuxOS From ff7e0136ebc597fda7252faab933d409bf210ca8 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Thu, 26 Jun 2025 09:54:52 -0400 Subject: [PATCH 60/65] update llhttp to v9.3.0 --- lib/llhttp/api.c | 45 +- lib/llhttp/llhttp.c | 3019 +++++++++++++++++++++---------------------- lib/llhttp/llhttp.h | 10 +- 3 files changed, 1504 insertions(+), 1570 deletions(-) diff --git a/lib/llhttp/api.c b/lib/llhttp/api.c index 8c2ce3d..0245254 100644 --- a/lib/llhttp/api.c +++ b/lib/llhttp/api.c @@ -57,29 +57,14 @@ static int wasm_on_headers_complete_wrap(llhttp_t* p) { } const llhttp_settings_t wasm_settings = { - wasm_on_message_begin, - wasm_on_url, - wasm_on_status, - NULL, - NULL, - wasm_on_header_field, - wasm_on_header_value, - NULL, - NULL, - wasm_on_headers_complete_wrap, - wasm_on_body, - wasm_on_message_complete, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + .on_message_begin = wasm_on_message_begin, + .on_url = wasm_on_url, + .on_status = wasm_on_status, + .on_header_field = wasm_on_header_field, + .on_header_value = wasm_on_header_value, + .on_headers_complete = wasm_on_headers_complete_wrap, + .on_body = wasm_on_body, + .on_message_complete = wasm_on_message_complete, }; @@ -341,6 +326,20 @@ int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) { } +int llhttp__on_protocol(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_protocol, p, endp - p); + return err; +} + + +int llhttp__on_protocol_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_protocol_complete); + return err; +} + + int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) { int err; SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p); diff --git a/lib/llhttp/llhttp.c b/lib/llhttp/llhttp.c index 3ef3b81..aa4c468 100644 --- a/lib/llhttp/llhttp.c +++ b/lib/llhttp/llhttp.c @@ -10,10 +10,20 @@ #endif /* _MSC_VER */ #endif /* __SSE4_2__ */ +#ifdef __ARM_NEON__ + #include +#endif /* __ARM_NEON__ */ + +#ifdef __wasm__ + #include +#endif /* __wasm__ */ + #ifdef _MSC_VER #define ALIGN(n) _declspec(align(n)) + #define UNREACHABLE __assume(0) #else /* !_MSC_VER */ #define ALIGN(n) __attribute__((aligned(n))) + #define UNREACHABLE __builtin_unreachable() #endif /* _MSC_VER */ #include "llhttp.h" @@ -72,16 +82,16 @@ static const unsigned char llparse_blob12[] = { 'p', 'g', 'r', 'a', 'd', 'e' }; static const unsigned char llparse_blob13[] = { - 'T', 'T', 'P', '/' + 'T', 'T', 'P' }; static const unsigned char llparse_blob14[] = { 0xd, 0xa, 0xd, 0xa, 'S', 'M', 0xd, 0xa, 0xd, 0xa }; static const unsigned char llparse_blob15[] = { - 'C', 'E', '/' + 'C', 'E' }; static const unsigned char llparse_blob16[] = { - 'T', 'S', 'P', '/' + 'T', 'S', 'P' }; static const unsigned char llparse_blob17[] = { 'N', 'O', 'U', 'N', 'C', 'E' @@ -207,12 +217,18 @@ static const unsigned char llparse_blob57[] = { 'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E' }; static const unsigned char llparse_blob58[] = { - 'H', 'T', 'T', 'P', '/' + 'T', 'T', 'P' }; static const unsigned char llparse_blob59[] = { - 'A', 'D' + 'C', 'E' }; static const unsigned char llparse_blob60[] = { + 'T', 'S', 'P' +}; +static const unsigned char llparse_blob61[] = { + 'A', 'D' +}; +static const unsigned char llparse_blob62[] = { 'T', 'P', '/' }; @@ -425,17 +441,27 @@ enum llparse_state_e { s_n_llhttp__internal__n_req_http_complete, s_n_llhttp__internal__n_invoke_load_method_1, s_n_llhttp__internal__n_invoke_llhttp__on_version_complete, - s_n_llhttp__internal__n_error_66, - s_n_llhttp__internal__n_error_73, - s_n_llhttp__internal__n_req_http_minor, + s_n_llhttp__internal__n_error_67, s_n_llhttp__internal__n_error_74, - s_n_llhttp__internal__n_req_http_dot, + s_n_llhttp__internal__n_req_http_minor, s_n_llhttp__internal__n_error_75, + s_n_llhttp__internal__n_req_http_dot, + s_n_llhttp__internal__n_error_76, s_n_llhttp__internal__n_req_http_major, s_n_llhttp__internal__n_span_start_llhttp__on_version, - s_n_llhttp__internal__n_req_http_start_1, - s_n_llhttp__internal__n_req_http_start_2, - s_n_llhttp__internal__n_req_http_start_3, + s_n_llhttp__internal__n_req_after_protocol, + s_n_llhttp__internal__n_invoke_load_method, + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete, + s_n_llhttp__internal__n_error_82, + s_n_llhttp__internal__n_req_after_http_start_1, + s_n_llhttp__internal__n_invoke_load_method_2, + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_1, + s_n_llhttp__internal__n_req_after_http_start_2, + s_n_llhttp__internal__n_invoke_load_method_3, + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_2, + s_n_llhttp__internal__n_req_after_http_start_3, + s_n_llhttp__internal__n_req_after_http_start, + s_n_llhttp__internal__n_span_start_llhttp__on_protocol, s_n_llhttp__internal__n_req_http_start, s_n_llhttp__internal__n_url_to_http, s_n_llhttp__internal__n_url_skip_to_http, @@ -543,15 +569,22 @@ enum llparse_state_e { s_n_llhttp__internal__n_res_status_code_digit_1, s_n_llhttp__internal__n_res_after_version, s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1, - s_n_llhttp__internal__n_error_89, - s_n_llhttp__internal__n_error_103, + s_n_llhttp__internal__n_error_93, + s_n_llhttp__internal__n_error_107, s_n_llhttp__internal__n_res_http_minor, - s_n_llhttp__internal__n_error_104, + s_n_llhttp__internal__n_error_108, s_n_llhttp__internal__n_res_http_dot, - s_n_llhttp__internal__n_error_105, + s_n_llhttp__internal__n_error_109, s_n_llhttp__internal__n_res_http_major, s_n_llhttp__internal__n_span_start_llhttp__on_version_1, - s_n_llhttp__internal__n_start_res, + s_n_llhttp__internal__n_res_after_protocol, + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_3, + s_n_llhttp__internal__n_error_115, + s_n_llhttp__internal__n_res_after_start_1, + s_n_llhttp__internal__n_res_after_start_2, + s_n_llhttp__internal__n_res_after_start_3, + s_n_llhttp__internal__n_res_after_start, + s_n_llhttp__internal__n_span_start_llhttp__on_protocol_1, s_n_llhttp__internal__n_invoke_llhttp__on_method_complete, s_n_llhttp__internal__n_req_or_res_method_2, s_n_llhttp__internal__n_invoke_update_type_1, @@ -574,6 +607,10 @@ int llhttp__on_url( llhttp__internal_t* s, const unsigned char* p, const unsigned char* endp); +int llhttp__on_protocol( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + int llhttp__on_version( llhttp__internal_t* s, const unsigned char* p, const unsigned char* endp); @@ -1057,6 +1094,10 @@ int llhttp__internal__c_or_flags_20( return 0; } +int llhttp__on_protocol_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + int llhttp__internal__c_load_method( llhttp__internal_t* state, const unsigned char* p, @@ -1192,8 +1233,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_3; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: { @@ -1203,8 +1243,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_update_finish_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_pause_1: s_n_llhttp__internal__n_pause_1: { @@ -1213,8 +1252,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_is_equal_upgrade: s_n_llhttp__internal__n_invoke_is_equal_upgrade: { @@ -1224,8 +1262,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_pause_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: { @@ -1237,8 +1274,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_38; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_data_almost_done_1: s_n_llhttp__internal__n_chunk_data_almost_done_1: { @@ -1254,8 +1290,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_7; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_data_almost_done: s_n_llhttp__internal__n_chunk_data_almost_done: { @@ -1275,8 +1310,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_7; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_consume_content_length: s_n_llhttp__internal__n_consume_content_length: { @@ -1293,8 +1327,7 @@ static llparse_state_t llhttp__internal__run( state->content_length -= avail; return s_n_llhttp__internal__n_consume_content_length; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_body: s_n_llhttp__internal__n_span_start_llhttp__on_body: { @@ -1304,8 +1337,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_body; goto s_n_llhttp__internal__n_consume_content_length; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_is_equal_content_length: s_n_llhttp__internal__n_invoke_is_equal_content_length: { @@ -1315,8 +1347,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_or_flags; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_size_almost_done: s_n_llhttp__internal__n_chunk_size_almost_done: { @@ -1332,8 +1363,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_8; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_test_lenient_flags_9: s_n_llhttp__internal__n_invoke_test_lenient_flags_9: { @@ -1343,8 +1373,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_20; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: { @@ -1356,8 +1385,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_19; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: { @@ -1369,8 +1397,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_21; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2: { @@ -1382,8 +1409,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_22; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_test_lenient_flags_10: s_n_llhttp__internal__n_invoke_test_lenient_flags_10: { @@ -1393,8 +1419,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_25; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: { @@ -1406,8 +1431,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_24; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: { @@ -1419,8 +1443,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_26; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extension_quoted_value_done: s_n_llhttp__internal__n_chunk_extension_quoted_value_done: { @@ -1443,8 +1466,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_29; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: { @@ -1456,8 +1478,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_27; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_30: s_n_llhttp__internal__n_error_30: { @@ -1466,8 +1487,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extension_quoted_value_quoted_pair: s_n_llhttp__internal__n_chunk_extension_quoted_value_quoted_pair: { @@ -1501,8 +1521,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_31: s_n_llhttp__internal__n_error_31: { @@ -1511,8 +1530,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extension_quoted_value: s_n_llhttp__internal__n_chunk_extension_quoted_value: { @@ -1554,8 +1572,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_3: s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_3: { @@ -1567,8 +1584,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_32; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_33: s_n_llhttp__internal__n_error_33: { @@ -1577,8 +1593,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extension_value: s_n_llhttp__internal__n_chunk_extension_value: { @@ -1625,8 +1640,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_6; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: { @@ -1636,8 +1650,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_chunk_extension_value; goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_3; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_34: s_n_llhttp__internal__n_error_34: { @@ -1646,8 +1659,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extension_name: s_n_llhttp__internal__n_chunk_extension_name: { @@ -1693,8 +1705,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_4; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: { @@ -1704,8 +1715,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_chunk_extension_name; goto s_n_llhttp__internal__n_chunk_extension_name; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_extensions: s_n_llhttp__internal__n_chunk_extensions: { @@ -1725,8 +1735,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_size_otherwise: s_n_llhttp__internal__n_chunk_size_otherwise: { @@ -1758,8 +1767,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_35; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_size: s_n_llhttp__internal__n_chunk_size: { @@ -1881,8 +1889,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_chunk_size_otherwise; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_chunk_size_digit: s_n_llhttp__internal__n_chunk_size_digit: { @@ -2004,8 +2011,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_37; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_update_content_length_1: s_n_llhttp__internal__n_invoke_update_content_length_1: { @@ -2013,8 +2019,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_chunk_size_digit; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_consume_content_length_1: s_n_llhttp__internal__n_consume_content_length_1: { @@ -2031,8 +2036,7 @@ static llparse_state_t llhttp__internal__run( state->content_length -= avail; return s_n_llhttp__internal__n_consume_content_length_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_body_1: s_n_llhttp__internal__n_span_start_llhttp__on_body_1: { @@ -2042,8 +2046,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_body; goto s_n_llhttp__internal__n_consume_content_length_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_eof: s_n_llhttp__internal__n_eof: { @@ -2052,8 +2055,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_eof; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_body_2: s_n_llhttp__internal__n_span_start_llhttp__on_body_2: { @@ -2063,8 +2065,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_body; goto s_n_llhttp__internal__n_eof; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: { @@ -2082,8 +2083,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_5: s_n_llhttp__internal__n_error_5: { @@ -2092,8 +2092,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_headers_almost_done: s_n_llhttp__internal__n_headers_almost_done: { @@ -2109,8 +2108,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_12; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_colon_discard_ws: s_n_llhttp__internal__n_header_field_colon_discard_ws: { @@ -2126,8 +2124,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_field_colon; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: { @@ -2139,8 +2136,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_48; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_header_value: s_n_llhttp__internal__n_span_start_llhttp__on_header_value: { @@ -2150,8 +2146,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_header_value; goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_discard_lws: s_n_llhttp__internal__n_header_value_discard_lws: { @@ -2171,8 +2166,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_load_header_state_1; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_discard_ws_almost_done: s_n_llhttp__internal__n_header_value_discard_ws_almost_done: { @@ -2188,8 +2182,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_16; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_lws: s_n_llhttp__internal__n_header_value_lws: { @@ -2207,8 +2200,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_load_header_state_5; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_almost_done: s_n_llhttp__internal__n_header_value_almost_done: { @@ -2224,8 +2216,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_53; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_test_lenient_flags_17: s_n_llhttp__internal__n_invoke_test_lenient_flags_17: { @@ -2235,8 +2226,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_51; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_lenient: s_n_llhttp__internal__n_header_value_lenient: { @@ -2255,8 +2245,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_lenient; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_54: s_n_llhttp__internal__n_error_54: { @@ -2265,8 +2254,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_otherwise: s_n_llhttp__internal__n_header_value_otherwise: { @@ -2284,8 +2272,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_19; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection_token: s_n_llhttp__internal__n_header_value_connection_token: { @@ -2323,8 +2310,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_otherwise; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection_ws: s_n_llhttp__internal__n_header_value_connection_ws: { @@ -2350,8 +2336,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_5; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection_1: s_n_llhttp__internal__n_header_value_connection_1: { @@ -2374,8 +2359,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_connection_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection_2: s_n_llhttp__internal__n_header_value_connection_2: { @@ -2398,8 +2382,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_connection_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection_3: s_n_llhttp__internal__n_header_value_connection_3: { @@ -2422,8 +2405,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_connection_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_connection: s_n_llhttp__internal__n_header_value_connection: { @@ -2455,8 +2437,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_connection_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_56: s_n_llhttp__internal__n_error_56: { @@ -2465,8 +2446,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_57: s_n_llhttp__internal__n_error_57: { @@ -2475,8 +2455,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_content_length_ws: s_n_llhttp__internal__n_header_value_content_length_ws: { @@ -2498,8 +2477,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_content_length: s_n_llhttp__internal__n_header_value_content_length: { @@ -2561,8 +2539,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_content_length_ws; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_59: s_n_llhttp__internal__n_error_59: { @@ -2571,8 +2548,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_error_58: s_n_llhttp__internal__n_error_58: { @@ -2581,8 +2557,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_te_token_ows: s_n_llhttp__internal__n_header_value_te_token_ows: { @@ -2602,8 +2577,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_te_chunked; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value: s_n_llhttp__internal__n_header_value: { @@ -2632,7 +2606,6 @@ static llparse_state_t llhttp__internal__run( if (endp - p >= 16) { __m128i ranges; __m128i input; - int avail; int match_len; /* Load input */ @@ -2652,6 +2625,78 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_otherwise; } #endif /* __SSE4_2__ */ + #ifdef __ARM_NEON__ + while (endp - p >= 16) { + uint8x16_t input; + uint8x16_t single; + uint8x16_t mask; + uint8x8_t narrow; + uint64_t match_mask; + int match_len; + + /* Load input */ + input = vld1q_u8(p); + /* Find first character that does not match `ranges` */ + single = vceqq_u8(input, vdupq_n_u8(0x9)); + mask = single; + single = vandq_u16( + vcgeq_u8(input, vdupq_n_u8(' ')), + vcleq_u8(input, vdupq_n_u8('~')) + ); + mask = vorrq_u16(mask, single); + single = vandq_u16( + vcgeq_u8(input, vdupq_n_u8(0x80)), + vcleq_u8(input, vdupq_n_u8(0xff)) + ); + mask = vorrq_u16(mask, single); + narrow = vshrn_n_u16(mask, 4); + match_mask = ~vget_lane_u64(vreinterpret_u64_u8(narrow), 0); + match_len = __builtin_ctzll(match_mask) >> 2; + if (match_len != 16) { + p += match_len; + goto s_n_llhttp__internal__n_header_value_otherwise; + } + p += 16; + } + if (p == endp) { + return s_n_llhttp__internal__n_header_value; + } + #endif /* __ARM_NEON__ */ + #ifdef __wasm_simd128__ + while (endp - p >= 16) { + v128_t input; + v128_t mask; + v128_t single; + int match_len; + + /* Load input */ + input = wasm_v128_load(p); + /* Find first character that does not match `ranges` */ + single = wasm_i8x16_eq(input, wasm_u8x16_const_splat(0x9)); + mask = single; + single = wasm_v128_and( + wasm_i8x16_ge(input, wasm_u8x16_const_splat(' ')), + wasm_i8x16_le(input, wasm_u8x16_const_splat('~')) + ); + mask = wasm_v128_or(mask, single); + single = wasm_v128_and( + wasm_i8x16_ge(input, wasm_u8x16_const_splat(0x80)), + wasm_i8x16_le(input, wasm_u8x16_const_splat(0xff)) + ); + mask = wasm_v128_or(mask, single); + match_len = __builtin_ctz( + ~wasm_i8x16_bitmask(mask) + ); + if (match_len != 16) { + p += match_len; + goto s_n_llhttp__internal__n_header_value_otherwise; + } + p += 16; + } + if (p == endp) { + return s_n_llhttp__internal__n_header_value; + } + #endif /* __wasm_simd128__ */ switch (lookup_table[(uint8_t) *p]) { case 1: { p++; @@ -2661,8 +2706,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_otherwise; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_te_token: s_n_llhttp__internal__n_header_value_te_token: { @@ -2700,8 +2744,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_9; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_te_chunked_last: s_n_llhttp__internal__n_header_value_te_chunked_last: { @@ -2726,8 +2769,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_te_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_te_chunked: s_n_llhttp__internal__n_header_value_te_chunked: { @@ -2750,8 +2792,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_value_te_token; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: { @@ -2761,8 +2802,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_header_value; goto s_n_llhttp__internal__n_invoke_load_header_state_3; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_value_discard_ws: s_n_llhttp__internal__n_header_value_discard_ws: { @@ -2790,8 +2830,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_load_header_state: s_n_llhttp__internal__n_invoke_load_header_state: { @@ -2803,8 +2842,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_discard_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: { @@ -2816,8 +2854,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_45; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_general_otherwise: s_n_llhttp__internal__n_header_field_general_otherwise: { @@ -2832,8 +2869,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_62; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_general: s_n_llhttp__internal__n_header_field_general: { @@ -2862,7 +2898,6 @@ static llparse_state_t llhttp__internal__run( if (endp - p >= 16) { __m128i ranges; __m128i input; - int avail; int match_len; /* Load input */ @@ -2903,8 +2938,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_field_general_otherwise; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_colon: s_n_llhttp__internal__n_header_field_colon: { @@ -2922,8 +2956,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_10; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_3: s_n_llhttp__internal__n_header_field_3: { @@ -2947,8 +2980,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_4: s_n_llhttp__internal__n_header_field_4: { @@ -2972,8 +3004,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_2: s_n_llhttp__internal__n_header_field_2: { @@ -2993,8 +3024,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_1: s_n_llhttp__internal__n_header_field_1: { @@ -3017,8 +3047,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_5: s_n_llhttp__internal__n_header_field_5: { @@ -3042,8 +3071,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_6: s_n_llhttp__internal__n_header_field_6: { @@ -3067,8 +3095,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_7: s_n_llhttp__internal__n_header_field_7: { @@ -3092,8 +3119,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field: s_n_llhttp__internal__n_header_field: { @@ -3121,8 +3147,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_header_state_11; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_header_field: s_n_llhttp__internal__n_span_start_llhttp__on_header_field: { @@ -3132,8 +3157,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_header_field; goto s_n_llhttp__internal__n_header_field; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_header_field_start: s_n_llhttp__internal__n_header_field_start: { @@ -3156,8 +3180,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_header_field; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_headers_start: s_n_llhttp__internal__n_headers_start: { @@ -3173,8 +3196,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_header_field_start; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_to_http_09: s_n_llhttp__internal__n_url_to_http_09: { @@ -3194,8 +3216,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_http_major; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_skip_to_http09: s_n_llhttp__internal__n_url_skip_to_http09: { @@ -3216,8 +3237,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_to_http_09; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_skip_lf_to_http09_1: s_n_llhttp__internal__n_url_skip_lf_to_http09_1: { @@ -3233,8 +3253,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_63; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_skip_lf_to_http09: s_n_llhttp__internal__n_url_skip_lf_to_http09: { @@ -3258,8 +3277,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_error_63; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_pri_upgrade: s_n_llhttp__internal__n_req_pri_upgrade: { @@ -3273,17 +3291,16 @@ static llparse_state_t llhttp__internal__run( switch (match_seq.status) { case kMatchComplete: { p++; - goto s_n_llhttp__internal__n_error_71; + goto s_n_llhttp__internal__n_error_72; } case kMatchPause: { return s_n_llhttp__internal__n_req_pri_upgrade; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_72; + goto s_n_llhttp__internal__n_error_73; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_complete_crlf: s_n_llhttp__internal__n_req_http_complete_crlf: { @@ -3299,8 +3316,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_26; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_complete: s_n_llhttp__internal__n_req_http_complete: { @@ -3317,11 +3333,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_req_http_complete_crlf; } default: { - goto s_n_llhttp__internal__n_error_70; + goto s_n_llhttp__internal__n_error_71; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_load_method_1: s_n_llhttp__internal__n_invoke_load_method_1: { @@ -3331,8 +3346,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_req_http_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: { @@ -3342,30 +3356,27 @@ static llparse_state_t llhttp__internal__run( case 21: goto s_n_llhttp__internal__n_pause_21; default: - goto s_n_llhttp__internal__n_error_67; + goto s_n_llhttp__internal__n_error_68; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_66: - s_n_llhttp__internal__n_error_66: { + case s_n_llhttp__internal__n_error_67: + s_n_llhttp__internal__n_error_67: { state->error = 0x9; state->reason = "Invalid HTTP version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_73: - s_n_llhttp__internal__n_error_73: { + case s_n_llhttp__internal__n_error_74: + s_n_llhttp__internal__n_error_74: { state->error = 0x9; state->reason = "Invalid minor version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_minor: s_n_llhttp__internal__n_req_http_minor: { @@ -3427,18 +3438,16 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_2; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_74: - s_n_llhttp__internal__n_error_74: { + case s_n_llhttp__internal__n_error_75: + s_n_llhttp__internal__n_error_75: { state->error = 0x9; state->reason = "Expected dot"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_dot: s_n_llhttp__internal__n_req_http_dot: { @@ -3454,18 +3463,16 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_3; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_75: - s_n_llhttp__internal__n_error_75: { + case s_n_llhttp__internal__n_error_76: + s_n_llhttp__internal__n_error_76: { state->error = 0x9; state->reason = "Invalid major version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_major: s_n_llhttp__internal__n_req_http_major: { @@ -3527,8 +3534,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_4; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_version: s_n_llhttp__internal__n_span_start_llhttp__on_version: { @@ -3538,80 +3544,297 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_version; goto s_n_llhttp__internal__n_req_http_major; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_req_http_start_1: - s_n_llhttp__internal__n_req_http_start_1: { - llparse_match_t match_seq; - + case s_n_llhttp__internal__n_req_after_protocol: + s_n_llhttp__internal__n_req_after_protocol: { if (p == endp) { - return s_n_llhttp__internal__n_req_http_start_1; + return s_n_llhttp__internal__n_req_after_protocol; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob13, 4); - p = match_seq.current; - switch (match_seq.status) { - case kMatchComplete: { + switch (*p) { + case '/': { p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_load_method: + s_n_llhttp__internal__n_invoke_load_method: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_after_protocol; + case 1: + goto s_n_llhttp__internal__n_req_after_protocol; + case 2: + goto s_n_llhttp__internal__n_req_after_protocol; + case 3: + goto s_n_llhttp__internal__n_req_after_protocol; + case 4: + goto s_n_llhttp__internal__n_req_after_protocol; + case 5: + goto s_n_llhttp__internal__n_req_after_protocol; + case 6: + goto s_n_llhttp__internal__n_req_after_protocol; + case 7: + goto s_n_llhttp__internal__n_req_after_protocol; + case 8: + goto s_n_llhttp__internal__n_req_after_protocol; + case 9: + goto s_n_llhttp__internal__n_req_after_protocol; + case 10: + goto s_n_llhttp__internal__n_req_after_protocol; + case 11: + goto s_n_llhttp__internal__n_req_after_protocol; + case 12: + goto s_n_llhttp__internal__n_req_after_protocol; + case 13: + goto s_n_llhttp__internal__n_req_after_protocol; + case 14: + goto s_n_llhttp__internal__n_req_after_protocol; + case 15: + goto s_n_llhttp__internal__n_req_after_protocol; + case 16: + goto s_n_llhttp__internal__n_req_after_protocol; + case 17: + goto s_n_llhttp__internal__n_req_after_protocol; + case 18: + goto s_n_llhttp__internal__n_req_after_protocol; + case 19: + goto s_n_llhttp__internal__n_req_after_protocol; + case 20: + goto s_n_llhttp__internal__n_req_after_protocol; + case 21: + goto s_n_llhttp__internal__n_req_after_protocol; + case 22: + goto s_n_llhttp__internal__n_req_after_protocol; + case 23: + goto s_n_llhttp__internal__n_req_after_protocol; + case 24: + goto s_n_llhttp__internal__n_req_after_protocol; + case 25: + goto s_n_llhttp__internal__n_req_after_protocol; + case 26: + goto s_n_llhttp__internal__n_req_after_protocol; + case 27: + goto s_n_llhttp__internal__n_req_after_protocol; + case 28: + goto s_n_llhttp__internal__n_req_after_protocol; + case 29: + goto s_n_llhttp__internal__n_req_after_protocol; + case 30: + goto s_n_llhttp__internal__n_req_after_protocol; + case 31: + goto s_n_llhttp__internal__n_req_after_protocol; + case 32: + goto s_n_llhttp__internal__n_req_after_protocol; + case 33: + goto s_n_llhttp__internal__n_req_after_protocol; + case 34: + goto s_n_llhttp__internal__n_req_after_protocol; + case 46: + goto s_n_llhttp__internal__n_req_after_protocol; + default: + goto s_n_llhttp__internal__n_error_66; + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete: { + switch (llhttp__on_protocol_complete(state, p, endp)) { + case 0: goto s_n_llhttp__internal__n_invoke_load_method; - } - case kMatchPause: { - return s_n_llhttp__internal__n_req_http_start_1; - } - case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_78; - } + case 21: + goto s_n_llhttp__internal__n_pause_22; + default: + goto s_n_llhttp__internal__n_error_65; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_req_http_start_2: - s_n_llhttp__internal__n_req_http_start_2: { + case s_n_llhttp__internal__n_error_82: + s_n_llhttp__internal__n_error_82: { + state->error = 0x8; + state->reason = "Expected HTTP/, RTSP/ or ICE/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + case s_n_llhttp__internal__n_req_after_http_start_1: + s_n_llhttp__internal__n_req_after_http_start_1: { llparse_match_t match_seq; if (p == endp) { - return s_n_llhttp__internal__n_req_http_start_2; + return s_n_llhttp__internal__n_req_after_http_start_1; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 3); + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob13, 3); p = match_seq.current; switch (match_seq.status) { case kMatchComplete: { p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_after_http_start_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_3; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_load_method_2: + s_n_llhttp__internal__n_invoke_load_method_2: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 33: + goto s_n_llhttp__internal__n_req_after_protocol; + default: + goto s_n_llhttp__internal__n_error_79; + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_1: { + switch (llhttp__on_protocol_complete(state, p, endp)) { + case 0: goto s_n_llhttp__internal__n_invoke_load_method_2; - } - case kMatchPause: { - return s_n_llhttp__internal__n_req_http_start_2; - } - case kMatchMismatch: { + case 21: + goto s_n_llhttp__internal__n_pause_23; + default: goto s_n_llhttp__internal__n_error_78; - } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_req_http_start_3: - s_n_llhttp__internal__n_req_http_start_3: { + case s_n_llhttp__internal__n_req_after_http_start_2: + s_n_llhttp__internal__n_req_after_http_start_2: { llparse_match_t match_seq; if (p == endp) { - return s_n_llhttp__internal__n_req_http_start_3; + return s_n_llhttp__internal__n_req_after_http_start_2; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 4); + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 2); p = match_seq.current; switch (match_seq.status) { case kMatchComplete: { p++; - goto s_n_llhttp__internal__n_invoke_load_method_3; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_1; } case kMatchPause: { - return s_n_llhttp__internal__n_req_http_start_3; + return s_n_llhttp__internal__n_req_after_http_start_2; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_78; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_3; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_load_method_3: + s_n_llhttp__internal__n_invoke_load_method_3: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_req_after_protocol; + case 3: + goto s_n_llhttp__internal__n_req_after_protocol; + case 6: + goto s_n_llhttp__internal__n_req_after_protocol; + case 35: + goto s_n_llhttp__internal__n_req_after_protocol; + case 36: + goto s_n_llhttp__internal__n_req_after_protocol; + case 37: + goto s_n_llhttp__internal__n_req_after_protocol; + case 38: + goto s_n_llhttp__internal__n_req_after_protocol; + case 39: + goto s_n_llhttp__internal__n_req_after_protocol; + case 40: + goto s_n_llhttp__internal__n_req_after_protocol; + case 41: + goto s_n_llhttp__internal__n_req_after_protocol; + case 42: + goto s_n_llhttp__internal__n_req_after_protocol; + case 43: + goto s_n_llhttp__internal__n_req_after_protocol; + case 44: + goto s_n_llhttp__internal__n_req_after_protocol; + case 45: + goto s_n_llhttp__internal__n_req_after_protocol; + default: + goto s_n_llhttp__internal__n_error_81; + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_2: + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_2: { + switch (llhttp__on_protocol_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_method_3; + case 21: + goto s_n_llhttp__internal__n_pause_24; + default: + goto s_n_llhttp__internal__n_error_80; + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_req_after_http_start_3: + s_n_llhttp__internal__n_req_after_http_start_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_after_http_start_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_2; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_after_http_start_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_3; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_req_after_http_start: + s_n_llhttp__internal__n_req_after_http_start: { + if (p == endp) { + return s_n_llhttp__internal__n_req_after_http_start; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_req_after_http_start_1; + } + case 'I': { + p++; + goto s_n_llhttp__internal__n_req_after_http_start_2; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_req_after_http_start_3; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_3; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_span_start_llhttp__on_protocol: + s_n_llhttp__internal__n_span_start_llhttp__on_protocol: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_protocol; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_protocol; + goto s_n_llhttp__internal__n_req_after_http_start; + UNREACHABLE; } case s_n_llhttp__internal__n_req_http_start: s_n_llhttp__internal__n_req_http_start: { @@ -3623,24 +3846,11 @@ static llparse_state_t llhttp__internal__run( p++; goto s_n_llhttp__internal__n_req_http_start; } - case 'H': { - p++; - goto s_n_llhttp__internal__n_req_http_start_1; - } - case 'I': { - p++; - goto s_n_llhttp__internal__n_req_http_start_2; - } - case 'R': { - p++; - goto s_n_llhttp__internal__n_req_http_start_3; - } default: { - goto s_n_llhttp__internal__n_error_78; + goto s_n_llhttp__internal__n_span_start_llhttp__on_protocol; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_to_http: s_n_llhttp__internal__n_url_to_http: { @@ -3660,8 +3870,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_skip_to_http: s_n_llhttp__internal__n_url_skip_to_http: { @@ -3682,8 +3891,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_to_http; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_fragment: s_n_llhttp__internal__n_url_fragment: { @@ -3727,11 +3935,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_fragment; } default: { - goto s_n_llhttp__internal__n_error_79; + goto s_n_llhttp__internal__n_error_83; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_end_stub_query_3: s_n_llhttp__internal__n_span_end_stub_query_3: { @@ -3740,8 +3947,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_url_fragment; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_query: s_n_llhttp__internal__n_url_query: { @@ -3788,11 +3994,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_stub_query_3; } default: { - goto s_n_llhttp__internal__n_error_80; + goto s_n_llhttp__internal__n_error_84; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_query_or_fragment: s_n_llhttp__internal__n_url_query_or_fragment: { @@ -3826,11 +4031,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_query; } default: { - goto s_n_llhttp__internal__n_error_81; + goto s_n_llhttp__internal__n_error_85; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_path: s_n_llhttp__internal__n_url_path: { @@ -3868,8 +4072,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_query_or_fragment; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_stub_path_2: s_n_llhttp__internal__n_span_start_stub_path_2: { @@ -3878,8 +4081,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_url_path; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_stub_path: s_n_llhttp__internal__n_span_start_stub_path: { @@ -3888,8 +4090,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_url_path; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_stub_path_1: s_n_llhttp__internal__n_span_start_stub_path_1: { @@ -3898,8 +4099,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_url_path; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_server_with_at: s_n_llhttp__internal__n_url_server_with_at: { @@ -3951,14 +4151,13 @@ static llparse_state_t llhttp__internal__run( } case 8: { p++; - goto s_n_llhttp__internal__n_error_82; + goto s_n_llhttp__internal__n_error_86; } default: { - goto s_n_llhttp__internal__n_error_83; + goto s_n_llhttp__internal__n_error_87; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_server: s_n_llhttp__internal__n_url_server: { @@ -4013,11 +4212,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_server_with_at; } default: { - goto s_n_llhttp__internal__n_error_84; + goto s_n_llhttp__internal__n_error_88; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_schema_delim_1: s_n_llhttp__internal__n_url_schema_delim_1: { @@ -4030,11 +4228,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_server; } default: { - goto s_n_llhttp__internal__n_error_85; + goto s_n_llhttp__internal__n_error_89; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_schema_delim: s_n_llhttp__internal__n_url_schema_delim: { @@ -4067,11 +4264,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_schema_delim_1; } default: { - goto s_n_llhttp__internal__n_error_85; + goto s_n_llhttp__internal__n_error_89; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_end_stub_schema: s_n_llhttp__internal__n_span_end_stub_schema: { @@ -4080,8 +4276,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_url_schema_delim; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_schema: s_n_llhttp__internal__n_url_schema: { @@ -4119,11 +4314,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_schema; } default: { - goto s_n_llhttp__internal__n_error_86; + goto s_n_llhttp__internal__n_error_90; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_start: s_n_llhttp__internal__n_url_start: { @@ -4160,11 +4354,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_url_schema; } default: { - goto s_n_llhttp__internal__n_error_87; + goto s_n_llhttp__internal__n_error_91; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_url_1: s_n_llhttp__internal__n_span_start_llhttp__on_url_1: { @@ -4174,8 +4367,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_url; goto s_n_llhttp__internal__n_url_start; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_entry_normal: s_n_llhttp__internal__n_url_entry_normal: { @@ -4195,8 +4387,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_url_1; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_url: s_n_llhttp__internal__n_span_start_llhttp__on_url: { @@ -4206,8 +4397,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_url; goto s_n_llhttp__internal__n_url_server; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_url_entry_connect: s_n_llhttp__internal__n_url_entry_connect: { @@ -4227,8 +4417,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_url; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_spaces_before_url: s_n_llhttp__internal__n_req_spaces_before_url: { @@ -4244,8 +4433,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_is_equal_method; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_first_space_before_url: s_n_llhttp__internal__n_req_first_space_before_url: { @@ -4258,11 +4446,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_req_spaces_before_url; } default: { - goto s_n_llhttp__internal__n_error_88; + goto s_n_llhttp__internal__n_error_92; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: { @@ -4270,12 +4457,11 @@ static llparse_state_t llhttp__internal__run( case 0: goto s_n_llhttp__internal__n_req_first_space_before_url; case 21: - goto s_n_llhttp__internal__n_pause_26; + goto s_n_llhttp__internal__n_pause_29; default: - goto s_n_llhttp__internal__n_error_107; + goto s_n_llhttp__internal__n_error_111; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_2: s_n_llhttp__internal__n_after_start_req_2: { @@ -4289,11 +4475,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_3: s_n_llhttp__internal__n_after_start_req_3: { @@ -4314,11 +4499,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_3; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_1: s_n_llhttp__internal__n_after_start_req_1: { @@ -4335,11 +4519,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_3; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_4: s_n_llhttp__internal__n_after_start_req_4: { @@ -4360,11 +4543,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_4; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_6: s_n_llhttp__internal__n_after_start_req_6: { @@ -4385,11 +4567,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_6; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_8: s_n_llhttp__internal__n_after_start_req_8: { @@ -4410,11 +4591,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_8; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_9: s_n_llhttp__internal__n_after_start_req_9: { @@ -4428,11 +4608,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_7: s_n_llhttp__internal__n_after_start_req_7: { @@ -4449,11 +4628,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_9; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_5: s_n_llhttp__internal__n_after_start_req_5: { @@ -4470,11 +4648,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_7; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_12: s_n_llhttp__internal__n_after_start_req_12: { @@ -4495,11 +4672,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_12; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_13: s_n_llhttp__internal__n_after_start_req_13: { @@ -4520,11 +4696,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_13; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_11: s_n_llhttp__internal__n_after_start_req_11: { @@ -4541,11 +4716,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_13; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_10: s_n_llhttp__internal__n_after_start_req_10: { @@ -4558,11 +4732,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_11; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_14: s_n_llhttp__internal__n_after_start_req_14: { @@ -4583,11 +4756,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_14; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_17: s_n_llhttp__internal__n_after_start_req_17: { @@ -4608,11 +4780,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_17; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_16: s_n_llhttp__internal__n_after_start_req_16: { @@ -4629,8 +4800,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_15: s_n_llhttp__internal__n_after_start_req_15: { @@ -4650,11 +4820,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_15; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_18: s_n_llhttp__internal__n_after_start_req_18: { @@ -4675,11 +4844,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_18; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_20: s_n_llhttp__internal__n_after_start_req_20: { @@ -4700,11 +4868,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_20; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_21: s_n_llhttp__internal__n_after_start_req_21: { @@ -4725,11 +4892,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_21; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_19: s_n_llhttp__internal__n_after_start_req_19: { @@ -4746,11 +4912,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_21; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_23: s_n_llhttp__internal__n_after_start_req_23: { @@ -4771,11 +4936,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_23; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_24: s_n_llhttp__internal__n_after_start_req_24: { @@ -4796,11 +4960,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_24; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_26: s_n_llhttp__internal__n_after_start_req_26: { @@ -4821,11 +4984,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_26; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_28: s_n_llhttp__internal__n_after_start_req_28: { @@ -4846,11 +5008,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_28; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_29: s_n_llhttp__internal__n_after_start_req_29: { @@ -4864,11 +5025,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_27: s_n_llhttp__internal__n_after_start_req_27: { @@ -4885,11 +5045,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_29; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_25: s_n_llhttp__internal__n_after_start_req_25: { @@ -4906,11 +5065,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_27; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_30: s_n_llhttp__internal__n_after_start_req_30: { @@ -4931,11 +5089,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_30; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_22: s_n_llhttp__internal__n_after_start_req_22: { @@ -4960,11 +5117,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_30; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_31: s_n_llhttp__internal__n_after_start_req_31: { @@ -4985,11 +5141,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_31; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_32: s_n_llhttp__internal__n_after_start_req_32: { @@ -5010,11 +5165,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_32; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_35: s_n_llhttp__internal__n_after_start_req_35: { @@ -5035,11 +5189,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_35; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_36: s_n_llhttp__internal__n_after_start_req_36: { @@ -5060,11 +5213,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_36; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_34: s_n_llhttp__internal__n_after_start_req_34: { @@ -5081,11 +5233,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_36; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_37: s_n_llhttp__internal__n_after_start_req_37: { @@ -5106,11 +5257,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_37; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_38: s_n_llhttp__internal__n_after_start_req_38: { @@ -5131,11 +5281,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_38; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_42: s_n_llhttp__internal__n_after_start_req_42: { @@ -5156,11 +5305,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_42; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_43: s_n_llhttp__internal__n_after_start_req_43: { @@ -5181,11 +5329,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_43; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_41: s_n_llhttp__internal__n_after_start_req_41: { @@ -5202,11 +5349,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_43; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_40: s_n_llhttp__internal__n_after_start_req_40: { @@ -5219,11 +5365,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_41; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_39: s_n_llhttp__internal__n_after_start_req_39: { @@ -5241,11 +5386,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_40; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_45: s_n_llhttp__internal__n_after_start_req_45: { @@ -5266,11 +5410,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_45; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_44: s_n_llhttp__internal__n_after_start_req_44: { @@ -5288,11 +5431,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_33: s_n_llhttp__internal__n_after_start_req_33: { @@ -5321,11 +5463,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_44; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_46: s_n_llhttp__internal__n_after_start_req_46: { @@ -5346,11 +5487,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_46; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_49: s_n_llhttp__internal__n_after_start_req_49: { @@ -5371,11 +5511,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_49; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_50: s_n_llhttp__internal__n_after_start_req_50: { @@ -5396,11 +5535,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_50; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_51: s_n_llhttp__internal__n_after_start_req_51: { @@ -5421,11 +5559,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_51; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_52: s_n_llhttp__internal__n_after_start_req_52: { @@ -5446,11 +5583,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_52; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_48: s_n_llhttp__internal__n_after_start_req_48: { @@ -5475,11 +5611,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_52; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_47: s_n_llhttp__internal__n_after_start_req_47: { @@ -5492,11 +5627,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_48; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_55: s_n_llhttp__internal__n_after_start_req_55: { @@ -5517,11 +5651,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_55; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_57: s_n_llhttp__internal__n_after_start_req_57: { @@ -5535,11 +5668,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_store_method_1; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_58: s_n_llhttp__internal__n_after_start_req_58: { @@ -5560,11 +5692,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_58; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_56: s_n_llhttp__internal__n_after_start_req_56: { @@ -5581,11 +5712,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_58; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_54: s_n_llhttp__internal__n_after_start_req_54: { @@ -5602,11 +5732,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_56; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_59: s_n_llhttp__internal__n_after_start_req_59: { @@ -5627,11 +5756,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_59; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_60: s_n_llhttp__internal__n_after_start_req_60: { @@ -5652,11 +5780,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_60; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_53: s_n_llhttp__internal__n_after_start_req_53: { @@ -5677,11 +5804,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_60; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_62: s_n_llhttp__internal__n_after_start_req_62: { @@ -5702,11 +5828,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_62; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_63: s_n_llhttp__internal__n_after_start_req_63: { @@ -5727,11 +5852,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_63; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_61: s_n_llhttp__internal__n_after_start_req_61: { @@ -5748,11 +5872,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_63; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_66: s_n_llhttp__internal__n_after_start_req_66: { @@ -5773,11 +5896,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_66; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_68: s_n_llhttp__internal__n_after_start_req_68: { @@ -5798,11 +5920,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_68; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_69: s_n_llhttp__internal__n_after_start_req_69: { @@ -5823,11 +5944,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_69; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_67: s_n_llhttp__internal__n_after_start_req_67: { @@ -5844,11 +5964,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_69; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_70: s_n_llhttp__internal__n_after_start_req_70: { @@ -5869,11 +5988,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_after_start_req_70; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_65: s_n_llhttp__internal__n_after_start_req_65: { @@ -5894,11 +6012,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_70; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req_64: s_n_llhttp__internal__n_after_start_req_64: { @@ -5911,11 +6028,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_65; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_after_start_req: s_n_llhttp__internal__n_after_start_req: { @@ -5992,11 +6108,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_after_start_req_64; } default: { - goto s_n_llhttp__internal__n_error_108; + goto s_n_llhttp__internal__n_error_112; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_method_1: s_n_llhttp__internal__n_span_start_llhttp__on_method_1: { @@ -6006,8 +6121,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_method; goto s_n_llhttp__internal__n_after_start_req; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_line_almost_done: s_n_llhttp__internal__n_res_line_almost_done: { @@ -6027,8 +6141,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_test_lenient_flags_29; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_test_lenient_flags_30: s_n_llhttp__internal__n_invoke_test_lenient_flags_30: { @@ -6036,10 +6149,9 @@ static llparse_state_t llhttp__internal__run( case 1: goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; default: - goto s_n_llhttp__internal__n_error_94; + goto s_n_llhttp__internal__n_error_98; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_status: s_n_llhttp__internal__n_res_status: { @@ -6058,8 +6170,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_res_status; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_status: s_n_llhttp__internal__n_span_start_llhttp__on_status: { @@ -6069,8 +6180,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_status; goto s_n_llhttp__internal__n_res_status; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_status_code_otherwise: s_n_llhttp__internal__n_res_status_code_otherwise: { @@ -6091,11 +6201,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_start_llhttp__on_status; } default: { - goto s_n_llhttp__internal__n_error_95; + goto s_n_llhttp__internal__n_error_99; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_status_code_digit_3: s_n_llhttp__internal__n_res_status_code_digit_3: { @@ -6154,11 +6263,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_mul_add_status_code_2; } default: { - goto s_n_llhttp__internal__n_error_97; + goto s_n_llhttp__internal__n_error_101; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_status_code_digit_2: s_n_llhttp__internal__n_res_status_code_digit_2: { @@ -6217,11 +6325,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_mul_add_status_code_1; } default: { - goto s_n_llhttp__internal__n_error_99; + goto s_n_llhttp__internal__n_error_103; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_status_code_digit_1: s_n_llhttp__internal__n_res_status_code_digit_1: { @@ -6280,11 +6387,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_mul_add_status_code; } default: { - goto s_n_llhttp__internal__n_error_101; + goto s_n_llhttp__internal__n_error_105; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_after_version: s_n_llhttp__internal__n_res_after_version: { @@ -6297,11 +6403,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_status_code; } default: { - goto s_n_llhttp__internal__n_error_102; + goto s_n_llhttp__internal__n_error_106; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: { @@ -6309,32 +6414,29 @@ static llparse_state_t llhttp__internal__run( case 0: goto s_n_llhttp__internal__n_res_after_version; case 21: - goto s_n_llhttp__internal__n_pause_25; + goto s_n_llhttp__internal__n_pause_28; default: - goto s_n_llhttp__internal__n_error_90; + goto s_n_llhttp__internal__n_error_94; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_89: - s_n_llhttp__internal__n_error_89: { + case s_n_llhttp__internal__n_error_93: + s_n_llhttp__internal__n_error_93: { state->error = 0x9; state->reason = "Invalid HTTP version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_103: - s_n_llhttp__internal__n_error_103: { + case s_n_llhttp__internal__n_error_107: + s_n_llhttp__internal__n_error_107: { state->error = 0x9; state->reason = "Invalid minor version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_http_minor: s_n_llhttp__internal__n_res_http_minor: { @@ -6396,18 +6498,16 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_7; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_104: - s_n_llhttp__internal__n_error_104: { + case s_n_llhttp__internal__n_error_108: + s_n_llhttp__internal__n_error_108: { state->error = 0x9; state->reason = "Expected dot"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_http_dot: s_n_llhttp__internal__n_res_http_dot: { @@ -6423,18 +6523,16 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_8; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_error_105: - s_n_llhttp__internal__n_error_105: { + case s_n_llhttp__internal__n_error_109: + s_n_llhttp__internal__n_error_109: { state->error = 0x9; state->reason = "Invalid major version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_res_http_major: s_n_llhttp__internal__n_res_http_major: { @@ -6496,8 +6594,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_span_end_llhttp__on_version_9; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_version_1: s_n_llhttp__internal__n_span_start_llhttp__on_version_1: { @@ -6507,32 +6604,147 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_version; goto s_n_llhttp__internal__n_res_http_major; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - case s_n_llhttp__internal__n_start_res: - s_n_llhttp__internal__n_start_res: { + case s_n_llhttp__internal__n_res_after_protocol: + s_n_llhttp__internal__n_res_after_protocol: { + if (p == endp) { + return s_n_llhttp__internal__n_res_after_protocol; + } + switch (*p) { + case '/': { + p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + default: { + goto s_n_llhttp__internal__n_error_114; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_3: + s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_3: { + switch (llhttp__on_protocol_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_res_after_protocol; + case 21: + goto s_n_llhttp__internal__n_pause_30; + default: + goto s_n_llhttp__internal__n_error_113; + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_error_115: + s_n_llhttp__internal__n_error_115: { + state->error = 0x8; + state->reason = "Expected HTTP/, RTSP/ or ICE/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + case s_n_llhttp__internal__n_res_after_start_1: + s_n_llhttp__internal__n_res_after_start_1: { llparse_match_t match_seq; if (p == endp) { - return s_n_llhttp__internal__n_start_res; + return s_n_llhttp__internal__n_res_after_start_1; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 5); + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 3); p = match_seq.current; switch (match_seq.status) { case kMatchComplete: { p++; - goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_4; } case kMatchPause: { - return s_n_llhttp__internal__n_start_res; + return s_n_llhttp__internal__n_res_after_start_1; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_109; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_5; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; + } + case s_n_llhttp__internal__n_res_after_start_2: + s_n_llhttp__internal__n_res_after_start_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_res_after_start_2; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_4; + } + case kMatchPause: { + return s_n_llhttp__internal__n_res_after_start_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_5; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_res_after_start_3: + s_n_llhttp__internal__n_res_after_start_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_res_after_start_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_4; + } + case kMatchPause: { + return s_n_llhttp__internal__n_res_after_start_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_5; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_res_after_start: + s_n_llhttp__internal__n_res_after_start: { + if (p == endp) { + return s_n_llhttp__internal__n_res_after_start; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_res_after_start_1; + } + case 'I': { + p++; + goto s_n_llhttp__internal__n_res_after_start_2; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_res_after_start_3; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_protocol_5; + } + } + UNREACHABLE; + } + case s_n_llhttp__internal__n_span_start_llhttp__on_protocol_1: + s_n_llhttp__internal__n_span_start_llhttp__on_protocol_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_protocol_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_protocol; + goto s_n_llhttp__internal__n_res_after_start; + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: { @@ -6540,12 +6752,11 @@ static llparse_state_t llhttp__internal__run( case 0: goto s_n_llhttp__internal__n_req_first_space_before_url; case 21: - goto s_n_llhttp__internal__n_pause_23; + goto s_n_llhttp__internal__n_pause_26; default: goto s_n_llhttp__internal__n_error_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_or_res_method_2: s_n_llhttp__internal__n_req_or_res_method_2: { @@ -6554,7 +6765,7 @@ static llparse_state_t llhttp__internal__run( if (p == endp) { return s_n_llhttp__internal__n_req_or_res_method_2; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 2); + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob61, 2); p = match_seq.current; switch (match_seq.status) { case kMatchComplete: { @@ -6566,11 +6777,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_req_or_res_method_2; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_106; + goto s_n_llhttp__internal__n_error_110; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_update_type_1: s_n_llhttp__internal__n_invoke_update_type_1: { @@ -6578,8 +6788,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_or_res_method_3: s_n_llhttp__internal__n_req_or_res_method_3: { @@ -6588,7 +6797,7 @@ static llparse_state_t llhttp__internal__run( if (p == endp) { return s_n_llhttp__internal__n_req_or_res_method_3; } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 3); + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob62, 3); p = match_seq.current; switch (match_seq.status) { case kMatchComplete: { @@ -6599,11 +6808,10 @@ static llparse_state_t llhttp__internal__run( return s_n_llhttp__internal__n_req_or_res_method_3; } case kMatchMismatch: { - goto s_n_llhttp__internal__n_error_106; + goto s_n_llhttp__internal__n_error_110; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_or_res_method_1: s_n_llhttp__internal__n_req_or_res_method_1: { @@ -6620,11 +6828,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_req_or_res_method_3; } default: { - goto s_n_llhttp__internal__n_error_106; + goto s_n_llhttp__internal__n_error_110; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_req_or_res_method: s_n_llhttp__internal__n_req_or_res_method: { @@ -6637,11 +6844,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_req_or_res_method_1; } default: { - goto s_n_llhttp__internal__n_error_106; + goto s_n_llhttp__internal__n_error_110; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_span_start_llhttp__on_method: s_n_llhttp__internal__n_span_start_llhttp__on_method: { @@ -6651,8 +6857,7 @@ static llparse_state_t llhttp__internal__run( state->_span_pos0 = (void*) p; state->_span_cb0 = llhttp__on_method; goto s_n_llhttp__internal__n_req_or_res_method; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_start_req_or_res: s_n_llhttp__internal__n_start_req_or_res: { @@ -6667,8 +6872,7 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_update_type_2; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_load_type: s_n_llhttp__internal__n_invoke_load_type: { @@ -6676,12 +6880,11 @@ static llparse_state_t llhttp__internal__run( case 1: goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; case 2: - goto s_n_llhttp__internal__n_start_res; + goto s_n_llhttp__internal__n_span_start_llhttp__on_protocol_1; default: goto s_n_llhttp__internal__n_start_req_or_res; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_invoke_update_finish: s_n_llhttp__internal__n_invoke_update_finish: { @@ -6689,8 +6892,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_llhttp__on_message_begin; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } case s_n_llhttp__internal__n_start: s_n_llhttp__internal__n_start: { @@ -6710,12 +6912,10 @@ static llparse_state_t llhttp__internal__run( goto s_n_llhttp__internal__n_invoke_load_initial_message_completed; } } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } default: - /* UNREACHABLE */ - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_2: { state->error = 0x7; @@ -6723,32 +6923,28 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_finish_2: { switch (llhttp__internal__c_update_finish_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_start; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_initial_message_completed: { switch (llhttp__internal__c_update_initial_message_completed(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_finish_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_content_length: { switch (llhttp__internal__c_update_content_length(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_initial_message_completed; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_8: { state->error = 0x5; @@ -6756,8 +6952,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_3: { switch (llhttp__internal__c_test_lenient_flags_3(state, p, endp)) { @@ -6766,8 +6961,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_8; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_2: { switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) { @@ -6776,16 +6970,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_closed; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_finish_1: { switch (llhttp__internal__c_update_finish_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_13: { state->error = 0x15; @@ -6793,8 +6985,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_upgrade; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_38: { state->error = 0x12; @@ -6802,8 +6993,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_15: { state->error = 0x15; @@ -6811,8 +7001,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_40: { state->error = 0x14; @@ -6820,8 +7009,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1: { switch (llhttp__on_chunk_complete(state, p, endp)) { @@ -6832,8 +7020,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_40; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_2: { state->error = 0x15; @@ -6841,8 +7028,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_pause_1; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_9: { state->error = 0x12; @@ -6850,8 +7036,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1: { switch (llhttp__on_message_complete(state, p, endp)) { @@ -6862,8 +7047,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_9; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_36: { state->error = 0xc; @@ -6871,8 +7055,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_10: { state->error = 0xc; @@ -6880,8 +7063,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_4: { switch (llhttp__internal__c_test_lenient_flags_4(state, p, endp)) { @@ -6890,8 +7072,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_10; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_3: { state->error = 0x15; @@ -6899,8 +7080,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_content_length_1; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_14: { state->error = 0x14; @@ -6908,8 +7088,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete: { switch (llhttp__on_chunk_complete(state, p, endp)) { @@ -6920,8 +7099,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_14; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_13: { state->error = 0x19; @@ -6929,8 +7107,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_6: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { @@ -6939,8 +7116,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_13; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_15: { state->error = 0x2; @@ -6948,8 +7124,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_7: { switch (llhttp__internal__c_test_lenient_flags_7(state, p, endp)) { @@ -6958,8 +7133,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_15; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_body: { const unsigned char* start; @@ -6975,16 +7149,14 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_chunk_data_almost_done; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags: { switch (llhttp__internal__c_or_flags(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_field_start; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_4: { state->error = 0x15; @@ -6992,8 +7164,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_content_length; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_12: { state->error = 0x13; @@ -7001,8 +7172,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header: { switch (llhttp__on_chunk_header(state, p, endp)) { @@ -7013,8 +7183,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_12; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_16: { state->error = 0x2; @@ -7022,8 +7191,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_8: { switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { @@ -7032,8 +7200,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_16; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_11: { state->error = 0x19; @@ -7041,8 +7208,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_5: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { @@ -7051,8 +7217,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_11; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_17: { state->error = 0x2; @@ -7060,8 +7225,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_18: { state->error = 0x2; @@ -7069,8 +7233,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_20: { state->error = 0x19; @@ -7078,8 +7241,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_5: { state->error = 0x15; @@ -7087,8 +7249,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_test_lenient_flags_9; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_19: { state->error = 0x22; @@ -7096,8 +7257,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name: { const unsigned char* start; @@ -7113,8 +7273,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_6: { state->error = 0x15; @@ -7122,8 +7281,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_21: { state->error = 0x22; @@ -7131,8 +7289,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_1: { const unsigned char* start; @@ -7149,8 +7306,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_7: { state->error = 0x15; @@ -7158,8 +7314,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extensions; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_22: { state->error = 0x22; @@ -7167,8 +7322,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_2: { const unsigned char* start; @@ -7185,8 +7339,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_25: { state->error = 0x19; @@ -7194,8 +7347,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_8: { state->error = 0x15; @@ -7203,8 +7355,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_test_lenient_flags_10; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_24: { state->error = 0x23; @@ -7212,8 +7363,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value: { const unsigned char* start; @@ -7229,8 +7379,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_9: { state->error = 0x15; @@ -7238,8 +7387,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_26: { state->error = 0x23; @@ -7247,8 +7395,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_1: { const unsigned char* start; @@ -7265,8 +7412,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_28: { state->error = 0x19; @@ -7274,8 +7420,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_11: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { @@ -7284,8 +7429,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_28; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_29: { state->error = 0x2; @@ -7293,8 +7437,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_10: { state->error = 0x15; @@ -7302,8 +7445,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_quoted_value_done; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_27: { state->error = 0x23; @@ -7311,8 +7453,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_2: { const unsigned char* start; @@ -7328,8 +7469,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3: { const unsigned char* start; @@ -7346,8 +7486,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_30; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4: { const unsigned char* start; @@ -7364,8 +7503,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_31; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_11: { state->error = 0x15; @@ -7373,8 +7511,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extensions; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_32: { state->error = 0x23; @@ -7382,8 +7519,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_5: { const unsigned char* start; @@ -7400,8 +7536,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_3; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_6: { const unsigned char* start; @@ -7418,8 +7553,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_33; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_12: { state->error = 0x15; @@ -7427,8 +7561,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_value; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_23: { state->error = 0x22; @@ -7436,8 +7569,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_3: { switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { @@ -7448,8 +7580,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_23; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_3: { const unsigned char* start; @@ -7466,8 +7597,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_4: { const unsigned char* start; @@ -7484,8 +7614,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_34; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_35: { state->error = 0xc; @@ -7493,8 +7622,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_mul_add_content_length: { switch (llhttp__internal__c_mul_add_content_length(state, p, endp, match)) { @@ -7503,8 +7631,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_chunk_size; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_37: { state->error = 0xc; @@ -7512,8 +7639,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_body_1: { const unsigned char* start; @@ -7529,16 +7655,14 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_finish_3: { switch (llhttp__internal__c_update_finish_3(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_39: { state->error = 0xf; @@ -7546,8 +7670,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause: { state->error = 0x15; @@ -7555,8 +7678,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_7: { state->error = 0x12; @@ -7564,8 +7686,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_message_complete: { switch (llhttp__on_message_complete(state, p, endp)) { @@ -7576,32 +7697,28 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_7; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_1: { switch (llhttp__internal__c_or_flags_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_2: { switch (llhttp__internal__c_or_flags_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_upgrade: { switch (llhttp__internal__c_update_upgrade(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_or_flags_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_14: { state->error = 0x15; @@ -7609,8 +7726,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_6: { state->error = 0x11; @@ -7618,8 +7734,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete: { switch (llhttp__on_headers_complete(state, p, endp)) { @@ -7634,16 +7749,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_6; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete: { switch (llhttp__before_headers_complete(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags: { switch (llhttp__internal__c_test_flags(state, p, endp)) { @@ -7652,8 +7765,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_1: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { @@ -7662,8 +7774,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_5; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_17: { state->error = 0x15; @@ -7671,8 +7782,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_42: { state->error = 0x14; @@ -7680,8 +7790,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_2: { switch (llhttp__on_chunk_complete(state, p, endp)) { @@ -7692,32 +7801,28 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_42; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_3: { switch (llhttp__internal__c_or_flags_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_4: { switch (llhttp__internal__c_or_flags_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_upgrade_1: { switch (llhttp__internal__c_update_upgrade(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_or_flags_4; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_16: { state->error = 0x15; @@ -7725,8 +7830,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_41: { state->error = 0x11; @@ -7734,8 +7838,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete_1: { switch (llhttp__on_headers_complete(state, p, endp)) { @@ -7750,16 +7853,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_41; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete_1: { switch (llhttp__before_headers_complete(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags_1: { switch (llhttp__internal__c_test_flags(state, p, endp)) { @@ -7768,8 +7869,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_43: { state->error = 0x2; @@ -7777,8 +7877,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_12: { switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { @@ -7787,8 +7886,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_43; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_44: { state->error = 0xa; @@ -7796,8 +7894,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_field: { const unsigned char* start; @@ -7814,8 +7911,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_5; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_13: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -7824,8 +7920,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_60: { state->error = 0xb; @@ -7833,8 +7928,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_47: { state->error = 0xa; @@ -7842,8 +7936,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_15: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -7852,8 +7945,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_47; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_49: { state->error = 0xb; @@ -7861,8 +7953,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_18: { state->error = 0x15; @@ -7870,8 +7961,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_field_start; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_48: { state->error = 0x1d; @@ -7879,8 +7969,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value: { const unsigned char* start; @@ -7896,48 +7985,42 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state: { switch (llhttp__internal__c_update_header_state(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_5: { switch (llhttp__internal__c_or_flags_5(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_6: { switch (llhttp__internal__c_or_flags_6(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_7: { switch (llhttp__internal__c_or_flags_7(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_8: { switch (llhttp__internal__c_or_flags_8(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_2: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -7952,8 +8035,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_1: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -7962,8 +8044,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_load_header_state_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_46: { state->error = 0xa; @@ -7971,8 +8052,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_14: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { @@ -7981,8 +8061,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_46; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_50: { state->error = 0x2; @@ -7990,8 +8069,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_16: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -8000,16 +8078,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_50; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_1: { switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_4: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -8018,8 +8094,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_52: { state->error = 0xa; @@ -8027,8 +8102,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_18: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -8037,48 +8111,42 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_52; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_2: { switch (llhttp__internal__c_update_header_state(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_9: { switch (llhttp__internal__c_or_flags_5(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_10: { switch (llhttp__internal__c_or_flags_6(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_11: { switch (llhttp__internal__c_or_flags_7(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_12: { switch (llhttp__internal__c_or_flags_8(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_5: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -8093,8 +8161,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_53: { state->error = 0x3; @@ -8102,8 +8169,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_51: { state->error = 0x19; @@ -8111,8 +8177,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1: { const unsigned char* start; @@ -8128,8 +8193,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_test_lenient_flags_17; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2: { const unsigned char* start; @@ -8146,8 +8210,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_header_value_almost_done; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4: { const unsigned char* start; @@ -8163,8 +8226,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_header_value_almost_done; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5: { const unsigned char* start; @@ -8181,8 +8243,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_header_value_almost_done; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3: { const unsigned char* start; @@ -8198,8 +8259,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_error_54; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_19: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -8208,48 +8268,42 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_4: { switch (llhttp__internal__c_update_header_state(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_13: { switch (llhttp__internal__c_or_flags_5(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_4; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_14: { switch (llhttp__internal__c_or_flags_6(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_4; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_15: { switch (llhttp__internal__c_or_flags_7(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_4; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_16: { switch (llhttp__internal__c_or_flags_8(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_6: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -8264,40 +8318,35 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_connection; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_5: { switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection_token; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_3: { switch (llhttp__internal__c_update_header_state_3(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_6: { switch (llhttp__internal__c_update_header_state_6(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_7: { switch (llhttp__internal__c_update_header_state_7(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_connection_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_6: { const unsigned char* start; @@ -8313,8 +8362,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_error_56; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_mul_add_content_length_1: { switch (llhttp__internal__c_mul_add_content_length_1(state, p, endp, match)) { @@ -8323,16 +8371,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_content_length; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_17: { switch (llhttp__internal__c_or_flags_17(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_otherwise; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7: { const unsigned char* start; @@ -8348,8 +8394,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_error_57; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_55: { state->error = 0x4; @@ -8357,8 +8402,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags_2: { switch (llhttp__internal__c_test_flags_2(state, p, endp)) { @@ -8367,8 +8411,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_55; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_9: { const unsigned char* start; @@ -8385,16 +8428,14 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_59; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_8: { switch (llhttp__internal__c_update_header_state_8(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_otherwise; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_value_8: { const unsigned char* start; @@ -8411,8 +8452,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_error_58; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_20: { switch (llhttp__internal__c_test_lenient_flags_20(state, p, endp)) { @@ -8421,8 +8461,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_te_chunked; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_type_1: { switch (llhttp__internal__c_load_type(state, p, endp)) { @@ -8431,32 +8470,28 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_te_chunked; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_9: { switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_and_flags: { switch (llhttp__internal__c_and_flags(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_value_te_chunked; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_19: { switch (llhttp__internal__c_or_flags_18(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_and_flags; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_21: { switch (llhttp__internal__c_test_lenient_flags_20(state, p, endp)) { @@ -8465,8 +8500,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_or_flags_19; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_type_2: { switch (llhttp__internal__c_load_type(state, p, endp)) { @@ -8475,16 +8509,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_or_flags_19; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_18: { switch (llhttp__internal__c_or_flags_18(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_and_flags; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags_3: { switch (llhttp__internal__c_test_flags_3(state, p, endp)) { @@ -8493,16 +8525,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_or_flags_18; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_or_flags_20: { switch (llhttp__internal__c_or_flags_20(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_header_state_9; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_header_state_3: { switch (llhttp__internal__c_load_header_state(state, p, endp)) { @@ -8517,8 +8547,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_22: { switch (llhttp__internal__c_test_lenient_flags_22(state, p, endp)) { @@ -8527,8 +8556,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_discard_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags_4: { switch (llhttp__internal__c_test_flags_4(state, p, endp)) { @@ -8537,8 +8565,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_discard_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_61: { state->error = 0xf; @@ -8546,8 +8573,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_23: { switch (llhttp__internal__c_test_lenient_flags_22(state, p, endp)) { @@ -8556,8 +8582,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_discard_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_flags_5: { switch (llhttp__internal__c_test_flags_2(state, p, endp)) { @@ -8566,8 +8591,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_header_value_discard_ws; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_19: { state->error = 0x15; @@ -8575,8 +8599,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_header_state; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_45: { state->error = 0x1c; @@ -8584,8 +8607,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1: { const unsigned char* start; @@ -8602,8 +8624,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_header_field_2: { const unsigned char* start; @@ -8620,8 +8641,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_62: { state->error = 0xa; @@ -8629,32 +8649,28 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_10: { switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_field_general; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_header_state: { switch (llhttp__internal__c_store_header_state(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_header_field_colon; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_header_state_11: { switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { default: goto s_n_llhttp__internal__n_header_field_general; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_4: { state->error = 0x1e; @@ -8662,8 +8678,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags: { switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { @@ -8672,8 +8687,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_4; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_20: { state->error = 0x15; @@ -8681,8 +8695,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_3: { state->error = 0x1a; @@ -8690,8 +8703,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_url_complete: { switch (llhttp__on_url_complete(state, p, endp)) { @@ -8702,24 +8714,21 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_error_3; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_http_minor: { switch (llhttp__internal__c_update_http_minor(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_http_major: { switch (llhttp__internal__c_update_http_major(state, p, endp)) { default: goto s_n_llhttp__internal__n_invoke_update_http_minor; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_3: { const unsigned char* start; @@ -8735,8 +8744,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_63: { state->error = 0x7; @@ -8744,8 +8752,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_4: { const unsigned char* start; @@ -8761,73 +8768,65 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_lf_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_71: { + s_n_llhttp__internal__n_error_72: { state->error = 0x17; state->reason = "Pause on PRI/Upgrade"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_72: { + s_n_llhttp__internal__n_error_73: { state->error = 0x9; state->reason = "Expected HTTP/2 Connection Preface"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_69: { + s_n_llhttp__internal__n_error_70: { state->error = 0x2; state->reason = "Expected CRLF after version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_26: { switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { case 1: goto s_n_llhttp__internal__n_headers_start; default: - goto s_n_llhttp__internal__n_error_69; + goto s_n_llhttp__internal__n_error_70; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_68: { + s_n_llhttp__internal__n_error_69: { state->error = 0x9; state->reason = "Expected CRLF after version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_25: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { case 1: goto s_n_llhttp__internal__n_req_http_complete_crlf; default: - goto s_n_llhttp__internal__n_error_68; + goto s_n_llhttp__internal__n_error_69; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_70: { + s_n_llhttp__internal__n_error_71: { state->error = 0x9; state->reason = "Expected CRLF after version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_pause_21: { state->error = 0x15; @@ -8835,17 +8834,15 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method_1; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_67: { + s_n_llhttp__internal__n_error_68: { state->error = 0x21; state->reason = "`on_version_complete` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_1: { const unsigned char* start; @@ -8861,8 +8858,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version: { const unsigned char* start; @@ -8874,12 +8870,11 @@ static llparse_state_t llhttp__internal__run( if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_66; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_67; return s_error; } - goto s_n_llhttp__internal__n_error_66; - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_error_67; + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -8888,8 +8883,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor_1: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -8900,8 +8894,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor_2: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -8910,8 +8903,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_major: { switch (llhttp__internal__c_load_http_major(state, p, endp)) { @@ -8924,8 +8916,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_24: { switch (llhttp__internal__c_test_lenient_flags_24(state, p, endp)) { @@ -8934,38 +8925,19 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_load_http_major; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_http_minor: { switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_invoke_test_lenient_flags_24; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_2: { const unsigned char* start; int err; - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llhttp__on_version(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_73; - return s_error; - } - goto s_n_llhttp__internal__n_error_73; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_span_end_llhttp__on_version_3: { - const unsigned char* start; - int err; - start = state->_span_pos0; state->_span_pos0 = NULL; err = llhttp__on_version(state, start, p); @@ -8976,18 +8948,9 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_error_74; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_invoke_store_http_major: { - switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { - default: - goto s_n_llhttp__internal__n_req_http_dot; - } - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_span_end_llhttp__on_version_4: { + s_n_llhttp__internal__n_span_end_llhttp__on_version_3: { const unsigned char* start; int err; @@ -9001,179 +8964,182 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_error_75; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_65: { + s_n_llhttp__internal__n_invoke_store_http_major: { + switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_req_http_dot; + } + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_76; + return s_error; + } + goto s_n_llhttp__internal__n_error_76; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_77: { + state->error = 0x8; + state->reason = "Expected HTTP/, RTSP/ or ICE/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_66: { state->error = 0x8; state->reason = "Invalid method for HTTP/x.x request"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_invoke_load_method: { - switch (llhttp__internal__c_load_method(state, p, endp)) { - case 0: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 1: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 2: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 3: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 4: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 5: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 6: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 7: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 8: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 9: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 10: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 11: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 12: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 13: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 14: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 15: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 16: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 17: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 18: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 19: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 20: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 21: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 22: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 23: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 24: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 25: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 26: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 27: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 28: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 29: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 30: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 31: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 32: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 33: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 34: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 46: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - default: - goto s_n_llhttp__internal__n_error_65; - } - /* UNREACHABLE */; - abort(); + s_n_llhttp__internal__n_pause_22: { + state->error = 0x15; + state->reason = "on_protocol_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method; + return s_error; + UNREACHABLE; } - s_n_llhttp__internal__n_error_78: { - state->error = 0x8; - state->reason = "Expected HTTP/"; + s_n_llhttp__internal__n_error_65: { + state->error = 0x26; + state->reason = "`on_protocol_complete` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_76: { + s_n_llhttp__internal__n_span_end_llhttp__on_protocol: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete; + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_protocol_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_82; + return s_error; + } + goto s_n_llhttp__internal__n_error_82; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_79: { state->error = 0x8; state->reason = "Expected SOURCE method for ICE/x.x request"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_invoke_load_method_2: { - switch (llhttp__internal__c_load_method(state, p, endp)) { - case 33: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - default: - goto s_n_llhttp__internal__n_error_76; + s_n_llhttp__internal__n_pause_23: { + state->error = 0x15; + state->reason = "on_protocol_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method_2; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_78: { + state->error = 0x26; + state->reason = "`on_protocol_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_protocol_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_1; + return s_error; } - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_1; + UNREACHABLE; } - s_n_llhttp__internal__n_error_77: { + s_n_llhttp__internal__n_error_81: { state->error = 0x8; state->reason = "Invalid method for RTSP/x.x request"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_invoke_load_method_3: { - switch (llhttp__internal__c_load_method(state, p, endp)) { - case 1: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 3: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 6: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 35: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 36: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 37: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 38: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 39: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 40: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 41: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 42: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 43: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 44: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - case 45: - goto s_n_llhttp__internal__n_span_start_llhttp__on_version; - default: - goto s_n_llhttp__internal__n_error_77; + s_n_llhttp__internal__n_pause_24: { + state->error = 0x15; + state->reason = "on_protocol_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method_3; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_80: { + state->error = 0x26; + state->reason = "`on_protocol_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_protocol_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_2; + return s_error; } - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_2; + UNREACHABLE; } - s_n_llhttp__internal__n_pause_22: { + s_n_llhttp__internal__n_pause_25: { state->error = 0x15; state->reason = "on_url_complete pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_http_start; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_64: { state->error = 0x1a; @@ -9181,20 +9147,18 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1: { switch (llhttp__on_url_complete(state, p, endp)) { case 0: goto s_n_llhttp__internal__n_req_http_start; case 21: - goto s_n_llhttp__internal__n_pause_22; + goto s_n_llhttp__internal__n_pause_25; default: goto s_n_llhttp__internal__n_error_64; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_5: { const unsigned char* start; @@ -9210,8 +9174,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_6: { const unsigned char* start; @@ -9227,8 +9190,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_7: { const unsigned char* start; @@ -9244,8 +9206,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_lf_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_8: { const unsigned char* start; @@ -9261,17 +9222,15 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_79: { + s_n_llhttp__internal__n_error_83: { state->error = 0x7; state->reason = "Invalid char in url fragment start"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_9: { const unsigned char* start; @@ -9287,8 +9246,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_10: { const unsigned char* start; @@ -9304,8 +9262,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_lf_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_11: { const unsigned char* start; @@ -9321,26 +9278,23 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_80: { + s_n_llhttp__internal__n_error_84: { state->error = 0x7; state->reason = "Invalid char in url query"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_81: { + s_n_llhttp__internal__n_error_85: { state->error = 0x7; state->reason = "Invalid char in url path"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url: { const unsigned char* start; @@ -9356,8 +9310,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_1: { const unsigned char* start; @@ -9373,8 +9326,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_lf_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_2: { const unsigned char* start; @@ -9390,8 +9342,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_12: { const unsigned char* start; @@ -9407,8 +9358,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_13: { const unsigned char* start; @@ -9424,8 +9374,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_lf_to_http09; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_url_14: { const unsigned char* start; @@ -9441,62 +9390,55 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_url_skip_to_http; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_82: { + s_n_llhttp__internal__n_error_86: { state->error = 0x7; state->reason = "Double @ in url"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_83: { - state->error = 0x7; - state->reason = "Unexpected char in url server"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_84: { - state->error = 0x7; - state->reason = "Unexpected char in url server"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_85: { - state->error = 0x7; - state->reason = "Unexpected char in url schema"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_86: { - state->error = 0x7; - state->reason = "Unexpected char in url schema"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_87: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_88: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_89: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_90: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_91: { state->error = 0x7; state->reason = "Unexpected start char in url"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_is_equal_method: { switch (llhttp__internal__c_is_equal_method(state, p, endp)) { @@ -9505,35 +9447,31 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_url_entry_connect; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_88: { + s_n_llhttp__internal__n_error_92: { state->error = 0x6; state->reason = "Expected space after method"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_pause_26: { + s_n_llhttp__internal__n_pause_29: { state->error = 0x15; state->reason = "on_method_complete pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_107: { + s_n_llhttp__internal__n_error_111: { state->error = 0x20; state->reason = "`on_method_complete` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_method_2: { const unsigned char* start; @@ -9549,25 +9487,38 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_method_1: { switch (llhttp__internal__c_store_method(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_span_end_llhttp__on_method_2; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_108: { + s_n_llhttp__internal__n_error_112: { state->error = 0x6; state->reason = "Invalid method encountered"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; + } + s_n_llhttp__internal__n_error_104: { + state->error = 0xd; + state->reason = "Invalid status code"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_102: { + state->error = 0xd; + state->reason = "Invalid status code"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; } s_n_llhttp__internal__n_error_100: { state->error = 0xd; @@ -9575,103 +9526,76 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_98: { - state->error = 0xd; - state->reason = "Invalid status code"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_96: { - state->error = 0xd; - state->reason = "Invalid status code"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_pause_24: { + s_n_llhttp__internal__n_pause_27: { state->error = 0x15; state->reason = "on_status_complete pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_92: { + s_n_llhttp__internal__n_error_96: { state->error = 0x1b; state->reason = "`on_status_complete` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: { switch (llhttp__on_status_complete(state, p, endp)) { case 0: goto s_n_llhttp__internal__n_headers_start; case 21: - goto s_n_llhttp__internal__n_pause_24; + goto s_n_llhttp__internal__n_pause_27; default: - goto s_n_llhttp__internal__n_error_92; + goto s_n_llhttp__internal__n_error_96; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_91: { + s_n_llhttp__internal__n_error_95: { state->error = 0xd; state->reason = "Invalid response status"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_28: { switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { case 1: goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; default: - goto s_n_llhttp__internal__n_error_91; + goto s_n_llhttp__internal__n_error_95; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_93: { + s_n_llhttp__internal__n_error_97: { state->error = 0x2; state->reason = "Expected LF after CR"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_29: { switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { case 1: goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; default: - goto s_n_llhttp__internal__n_error_93; + goto s_n_llhttp__internal__n_error_97; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_94: { + s_n_llhttp__internal__n_error_98: { state->error = 0x19; state->reason = "Missing expected CR after response line"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_status: { const unsigned char* start; @@ -9688,8 +9612,7 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_invoke_test_lenient_flags_30; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_status_1: { const unsigned char* start; @@ -9706,65 +9629,24 @@ static llparse_state_t llhttp__internal__run( } p++; goto s_n_llhttp__internal__n_res_line_almost_done; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_95: { + s_n_llhttp__internal__n_error_99: { state->error = 0xd; state->reason = "Invalid response status"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_mul_add_status_code_2: { switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { case 1: - goto s_n_llhttp__internal__n_error_96; + goto s_n_llhttp__internal__n_error_100; default: goto s_n_llhttp__internal__n_res_status_code_otherwise; } - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_97: { - state->error = 0xd; - state->reason = "Invalid status code"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_invoke_mul_add_status_code_1: { - switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { - case 1: - goto s_n_llhttp__internal__n_error_98; - default: - goto s_n_llhttp__internal__n_res_status_code_digit_3; - } - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_error_99: { - state->error = 0xd; - state->reason = "Invalid status code"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - /* UNREACHABLE */; - abort(); - } - s_n_llhttp__internal__n_invoke_mul_add_status_code: { - switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { - case 1: - goto s_n_llhttp__internal__n_error_100; - default: - goto s_n_llhttp__internal__n_res_status_code_digit_2; - } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_101: { state->error = 0xd; @@ -9772,43 +9654,72 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; + } + s_n_llhttp__internal__n_invoke_mul_add_status_code_1: { + switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_102; + default: + goto s_n_llhttp__internal__n_res_status_code_digit_3; + } + UNREACHABLE; + } + s_n_llhttp__internal__n_error_103: { + state->error = 0xd; + state->reason = "Invalid status code"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_invoke_mul_add_status_code: { + switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_104; + default: + goto s_n_llhttp__internal__n_res_status_code_digit_2; + } + UNREACHABLE; + } + s_n_llhttp__internal__n_error_105: { + state->error = 0xd; + state->reason = "Invalid status code"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_status_code: { switch (llhttp__internal__c_update_status_code(state, p, endp)) { default: goto s_n_llhttp__internal__n_res_status_code_digit_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_102: { + s_n_llhttp__internal__n_error_106: { state->error = 0x9; state->reason = "Expected space after version"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_pause_25: { + s_n_llhttp__internal__n_pause_28: { state->error = 0x15; state->reason = "on_version_complete pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_after_version; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_90: { + s_n_llhttp__internal__n_error_94: { state->error = 0x21; state->reason = "`on_version_complete` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_6: { const unsigned char* start; @@ -9824,8 +9735,7 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_5: { const unsigned char* start; @@ -9837,12 +9747,11 @@ static llparse_state_t llhttp__internal__run( if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_89; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_93; return s_error; } - goto s_n_llhttp__internal__n_error_89; - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_error_93; + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor_3: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -9851,8 +9760,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor_4: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -9863,8 +9771,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_minor_5: { switch (llhttp__internal__c_load_http_minor(state, p, endp)) { @@ -9873,8 +9780,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_http_major_1: { switch (llhttp__internal__c_load_http_major(state, p, endp)) { @@ -9887,8 +9793,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_test_lenient_flags_27: { switch (llhttp__internal__c_test_lenient_flags_24(state, p, endp)) { @@ -9897,16 +9802,14 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_load_http_major_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_http_minor_1: { switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_invoke_test_lenient_flags_27; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_7: { const unsigned char* start; @@ -9918,12 +9821,11 @@ static llparse_state_t llhttp__internal__run( if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_103; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_107; return s_error; } - goto s_n_llhttp__internal__n_error_103; - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_error_107; + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_8: { const unsigned char* start; @@ -9935,20 +9837,18 @@ static llparse_state_t llhttp__internal__run( if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_104; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_108; return s_error; } - goto s_n_llhttp__internal__n_error_104; - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_error_108; + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_http_major_1: { switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_res_http_dot; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_version_9: { const unsigned char* start; @@ -9960,30 +9860,75 @@ static llparse_state_t llhttp__internal__run( if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_105; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_109; return s_error; } - goto s_n_llhttp__internal__n_error_105; - /* UNREACHABLE */; - abort(); + goto s_n_llhttp__internal__n_error_109; + UNREACHABLE; } - s_n_llhttp__internal__n_error_109: { + s_n_llhttp__internal__n_error_114: { state->error = 0x8; - state->reason = "Expected HTTP/"; + state->reason = "Expected HTTP/, RTSP/ or ICE/"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_pause_23: { + s_n_llhttp__internal__n_pause_30: { + state->error = 0x15; + state->reason = "on_protocol_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_after_protocol; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_error_113: { + state->error = 0x26; + state->reason = "`on_protocol_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_protocol_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_3; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_protocol_complete_3; + UNREACHABLE; + } + s_n_llhttp__internal__n_span_end_llhttp__on_protocol_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_protocol(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_115; + return s_error; + } + goto s_n_llhttp__internal__n_error_115; + UNREACHABLE; + } + s_n_llhttp__internal__n_pause_26: { state->error = 0x15; state->reason = "on_method_complete pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error_1: { state->error = 0x20; @@ -9991,8 +9936,7 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_method: { const unsigned char* start; @@ -10008,33 +9952,29 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_type: { switch (llhttp__internal__c_update_type(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_end_llhttp__on_method; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_store_method: { switch (llhttp__internal__c_store_method(state, p, endp, match)) { default: goto s_n_llhttp__internal__n_invoke_update_type; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_106: { + s_n_llhttp__internal__n_error_110: { state->error = 0x8; state->reason = "Invalid word encountered"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_span_end_llhttp__on_method_1: { const unsigned char* start; @@ -10050,25 +9990,22 @@ static llparse_state_t llhttp__internal__run( return s_error; } goto s_n_llhttp__internal__n_invoke_update_type_1; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_update_type_2: { switch (llhttp__internal__c_update_type(state, p, endp)) { default: goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_pause_27: { + s_n_llhttp__internal__n_pause_31: { state->error = 0x15; state->reason = "on_message_begin pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_type; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_error: { state->error = 0x10; @@ -10076,50 +10013,45 @@ static llparse_state_t llhttp__internal__run( state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_message_begin: { switch (llhttp__on_message_begin(state, p, endp)) { case 0: goto s_n_llhttp__internal__n_invoke_load_type; case 21: - goto s_n_llhttp__internal__n_pause_27; + goto s_n_llhttp__internal__n_pause_31; default: goto s_n_llhttp__internal__n_error; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_pause_28: { + s_n_llhttp__internal__n_pause_32: { state->error = 0x15; state->reason = "on_reset pause"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_finish; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } - s_n_llhttp__internal__n_error_110: { + s_n_llhttp__internal__n_error_116: { state->error = 0x1f; state->reason = "`on_reset` callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_llhttp__on_reset: { switch (llhttp__on_reset(state, p, endp)) { case 0: goto s_n_llhttp__internal__n_invoke_update_finish; case 21: - goto s_n_llhttp__internal__n_pause_28; + goto s_n_llhttp__internal__n_pause_32; default: - goto s_n_llhttp__internal__n_error_110; + goto s_n_llhttp__internal__n_error_116; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } s_n_llhttp__internal__n_invoke_load_initial_message_completed: { switch (llhttp__internal__c_load_initial_message_completed(state, p, endp)) { @@ -10128,8 +10060,7 @@ static llparse_state_t llhttp__internal__run( default: goto s_n_llhttp__internal__n_invoke_update_finish; } - /* UNREACHABLE */; - abort(); + UNREACHABLE; } } diff --git a/lib/llhttp/llhttp.h b/lib/llhttp/llhttp.h index 37b7934..6054459 100644 --- a/lib/llhttp/llhttp.h +++ b/lib/llhttp/llhttp.h @@ -3,8 +3,8 @@ #define INCLUDE_LLHTTP_H_ #define LLHTTP_VERSION_MAJOR 9 -#define LLHTTP_VERSION_MINOR 2 -#define LLHTTP_VERSION_PATCH 1 +#define LLHTTP_VERSION_MINOR 3 +#define LLHTTP_VERSION_PATCH 0 #ifndef INCLUDE_LLHTTP_ITSELF_H_ #define INCLUDE_LLHTTP_ITSELF_H_ @@ -90,7 +90,8 @@ enum llhttp_errno { HPE_CB_HEADER_VALUE_COMPLETE = 29, HPE_CB_CHUNK_EXTENSION_NAME_COMPLETE = 34, HPE_CB_CHUNK_EXTENSION_VALUE_COMPLETE = 35, - HPE_CB_RESET = 31 + HPE_CB_RESET = 31, + HPE_CB_PROTOCOL_COMPLETE = 38 }; typedef enum llhttp_errno llhttp_errno_t; @@ -326,6 +327,7 @@ typedef enum llhttp_status llhttp_status_t; XX(34, CB_CHUNK_EXTENSION_NAME_COMPLETE, CB_CHUNK_EXTENSION_NAME_COMPLETE) \ XX(35, CB_CHUNK_EXTENSION_VALUE_COMPLETE, CB_CHUNK_EXTENSION_VALUE_COMPLETE) \ XX(31, CB_RESET, CB_RESET) \ + XX(38, CB_PROTOCOL_COMPLETE, CB_PROTOCOL_COMPLETE) \ #define HTTP_METHOD_MAP(XX) \ @@ -567,6 +569,7 @@ struct llhttp_settings_s { llhttp_cb on_message_begin; /* Possible return values 0, -1, HPE_USER */ + llhttp_data_cb on_protocol; llhttp_data_cb on_url; llhttp_data_cb on_status; llhttp_data_cb on_method; @@ -592,6 +595,7 @@ struct llhttp_settings_s { /* Possible return values 0, -1, `HPE_PAUSED` */ llhttp_cb on_message_complete; + llhttp_cb on_protocol_complete; llhttp_cb on_url_complete; llhttp_cb on_status_complete; llhttp_cb on_method_complete; From f3db82fcfe9fab2c0977b4cb900c2e913a325e29 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 7 Jul 2025 11:25:54 -0400 Subject: [PATCH 61/65] cleanup in httpd.c --- lib/httpd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/httpd.c b/lib/httpd.c index 1d17b99..9a4b990 100644 --- a/lib/httpd.c +++ b/lib/httpd.c @@ -211,17 +211,19 @@ httpd_remove_connection(httpd_t *httpd, http_connection_t *connection) httpd->callbacks.conn_destroy(connection->user_data); connection->user_data = NULL; } - shutdown(connection->socket_fd, SHUT_WR); if (connection->socket_fd) { + shutdown(connection->socket_fd, SHUT_WR); int ret = closesocket(connection->socket_fd); if (ret == -1) { logger_log(httpd->logger, LOGGER_ERR, "httpd error in closesocket (close): %d %s", errno, strerror(errno)); } connection->socket_fd = 0; } - connection->connected = 0; + if (connection->connected) { + connection->connected = 0; + httpd->open_connections--; + } connection->type = CONNECTION_TYPE_UNKNOWN; - httpd->open_connections--; } static int From ae28bc7930857c52d965b0d66a94fe699eb19672 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 7 Jul 2025 13:34:33 -0400 Subject: [PATCH 62/65] fix -pw bug in dnssd.c (fixes #426) --- lib/dnssd.c | 8 +++++--- lib/raop_handlers.h | 2 +- uxplay.cpp | 14 +++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/dnssd.c b/lib/dnssd.c index 90f152b..b66563c 100644 --- a/lib/dnssd.c +++ b/lib/dnssd.c @@ -164,8 +164,8 @@ dnssd_init(const char* name, int name_len, const char* hw_addr, int hw_addr_len, unsigned long features; /* pin_pw = 0: no pin or password 1: use onscreen pin for client access control - 2: require password for client accress control. - */ + 2 or 3: require password for client access control + */ if (error) *error = DNSSD_ERROR_NOERROR; @@ -308,6 +308,7 @@ dnssd_register_raop(dnssd_t *dnssd, unsigned short port) dnssd->TXTRecordSetValue(&dnssd->raop_record, "rhd", strlen(RAOP_RHD), RAOP_RHD); switch (dnssd->pin_pw) { case 2: + case 3: dnssd->TXTRecordSetValue(&dnssd->raop_record, "pw", strlen("true"), "true"); dnssd->TXTRecordSetValue(&dnssd->raop_record, "sf", 4, "0x84"); break; @@ -316,7 +317,7 @@ dnssd_register_raop(dnssd_t *dnssd, unsigned short port) dnssd->TXTRecordSetValue(&dnssd->raop_record, "sf", 3, "0x8c"); break; default: - dnssd->TXTRecordSetValue(&dnssd->raop_record, "pw", strlen("true"), "false"); + dnssd->TXTRecordSetValue(&dnssd->raop_record, "pw", strlen("false"), "false"); dnssd->TXTRecordSetValue(&dnssd->raop_record, "sf", strlen(RAOP_SF), RAOP_SF); break; } @@ -384,6 +385,7 @@ dnssd_register_airplay(dnssd_t *dnssd, unsigned short port) dnssd->TXTRecordSetValue(&dnssd->airplay_record, "flags", 3, "0x4"); break; case 2: // require password + case 3: dnssd->TXTRecordSetValue(&dnssd->airplay_record, "pw", strlen("true"), "true"); dnssd->TXTRecordSetValue(&dnssd->airplay_record, "flags", 3, "0x4"); break; diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 37d3db9..5003cbe 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -588,7 +588,7 @@ raop_handler_setup(raop_conn_t *conn, if (!conn->authenticated && conn->raop->callbacks.passwd) { int len; const char *password = conn->raop->callbacks.passwd(conn->raop->callbacks.cls, &len); - // len = -1 means use a random password for this connection + // len = -1 means use a random password for this connection; len = 0 means no password if (len == -1 && conn->raop->random_pw && conn->raop->auth_fail_count >= 5) { // change random_pw after 5 failed authentication attempts logger_log(conn->raop->logger, LOGGER_INFO, "Too many authentication failures: generate new random password"); diff --git a/uxplay.cpp b/uxplay.cpp index b869806..a0e936e 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -1543,8 +1543,9 @@ static int start_dnssd(std::vector hw_addr, std::string name) { return 2; } /* pin_pw controls client access - pin_pw = 1: client must enter pin displayed onscreen (first access only) + pin_pw = 1: client must enter pin displayed onscreen (first access only) = 2: client must enter password (same password for all clients) + = 3: client must enter randoe 4-digit password displayed like an onscreen pin (every access) = 0: no access control */ dnssd = dnssd_init(name.c_str(), strlen(name.c_str()), hw_addr.data(), hw_addr.size(), &dnssd_error, pin_pw); @@ -1705,12 +1706,15 @@ extern "C" void display_pin(void *cls, char *pin) { } extern "C" const char *passwd(void *cls, int *len){ - if (pin_pw == 3) { + if (pin_pw == 2) { + *len = password.size(); + return password.c_str(); + } else if (pin_pw == 3) { *len = -1; - return NULL; + } else { + *len = 0; /* no password used */ } - *len = password.size(); - return password.c_str(); + return NULL; } extern "C" void export_dacp(void *cls, const char *active_remote, const char *dacp_id) { From 89844fa53ffa0cc14fda0417f64c3a7dd81f0f6e Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 7 Jul 2025 20:34:22 -0400 Subject: [PATCH 63/65] update for v1.72.2 release --- README.html | 2 ++ README.md | 3 +++ README.txt | 3 +++ uxplay.spec | 6 +++--- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.html b/README.html index 1bdc809..e55b176 100644 --- a/README.html +++ b/README.html @@ -1700,6 +1700,8 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

      Changelog

      +

      1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced +with -pw option. Update llhttp to v 9.3.0

      1.72.1 2025-06-06 minor update: fix regression in -reg option; add option -rc to specify initialization file; add “-nc no” to unset “-nc” option (for macOS users, where -nc is default); add diff --git a/README.md b/README.md index 76c17fe..9e53aa1 100644 --- a/README.md +++ b/README.md @@ -1731,6 +1731,9 @@ introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be. # Changelog +1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced with -pw +option. Update llhttp to v 9.3.0 + 1.72.1 2025-06-06 minor update: fix regression in -reg option; add option -rc to specify initialization file; add "-nc no" to unset "-nc" option (for macOS users, where -nc is default); add user-installable diff --git a/README.txt b/README.txt index aca484c..bd95777 100644 --- a/README.txt +++ b/README.txt @@ -1751,6 +1751,9 @@ what version UxPlay claims to be. # Changelog +1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced with +-pw option. Update llhttp to v 9.3.0 + 1.72.1 2025-06-06 minor update: fix regression in -reg option; add option -rc ``{=html} to specify initialization file; add "-nc no" to unset "-nc" option (for macOS users, where -nc is default); add diff --git a/uxplay.spec b/uxplay.spec index 87d46b1..e302bb4 100644 --- a/uxplay.spec +++ b/uxplay.spec @@ -1,5 +1,5 @@ Name: uxplay -Version: 1.72.1 +Version: 1.72.2 Release: 1%{?dist} %global gittag v%{version} @@ -135,8 +135,8 @@ cd build %{_docdir}/%{name}/llhttp/LICENSE-MIT %changelog -* Thu Jun 5 2025 UxPlay maintainer - Update for 1.72.1 release +* Mon Jul 7 2025 UxPlay maintainer + Update for 1.72.2 release * Fri Nov 15 2024 UxPlay maintainer Initial uxplay.spec: tested on Fedora 38, Rocky Linux 9.2, OpenSUSE Leap 15.5, Mageia 9, OpenMandriva ROME, PCLinuxOS From 546145a9634e8fbce697a24f85c55ba16d6ca9e1 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 7 Jul 2025 20:55:47 -0400 Subject: [PATCH 64/65] add -ca (w/o filename) option for gstreamer rendering of coverart --- README.html | 30 +++++++++---- README.md | 32 ++++++++++---- README.txt | 37 ++++++++++------ lib/raop.h | 3 +- lib/raop_handlers.h | 4 ++ renderers/video_renderer.c | 86 +++++++++++++++++++++++++------------- renderers/video_renderer.h | 3 +- uxplay.1 | 2 + uxplay.cpp | 25 +++++++---- 9 files changed, 154 insertions(+), 68 deletions(-) diff --git a/README.html b/README.html index e55b176..d647f50 100644 --- a/README.html +++ b/README.html @@ -8,6 +8,10 @@ developed at the GitHub site https://github.com/FDH2/UxPlay (where ALL user issues should be posted, and latest versions can be found).

        +
      • NEW on github: option -ca (with no filename +given) will now render Apple Music cover art (in audio-only mode) inside +UxPlay. (-ca <filename> will continue to export cover +art for display by an external viewer).

      • NEW in v1.72: Improved Support for (YouTube) HLS (HTTP Live Streaming) video with the new “-hls” option (introduced in 1.71).* Only streaming from the YouTube iOS app (in "m3u8" @@ -107,7 +111,8 @@ distribution’s GStreamer plugin packages you should also install.

      • For Audio-only mode (Apple Music, etc.) best quality is obtained with the option “uxplay -async”, but there is then a 2 second latency -imposed by iOS.

      • +imposed by iOS. Use option “uxplay -ca” to display any “Cover Art” that +accompanies the audio.

      • If you are using UxPlay just to mirror the client’s screen (without showing videos that need audio synchronized with video), it is best to use the option “uxplay -vsync no”.

      • @@ -621,12 +626,14 @@ some video to be played at 60 frames per second. (You can see what framerate is actually streaming by using -vs fpsdisplaysink, and/or -FPSdata.) When using this, you should use the default timestamp-based synchronization option -vsync.

        -
      • Since UxPlay-1.54, you can display the accompanying “Cover Art” -from sources like Apple Music in Audio-Only (ALAC) mode: run +

      • You can now display (inside UxPlay) the accompanying “Cover Art” +from sources like Apple Music in Audio-Only (ALAC) mode with the option +uxplay -ca. The older method of exporting cover art to +an external viewer remains available: run “uxplay -ca <name> &” in the background, then run a image viewer with an autoreload feature: an example is “feh”: run “feh -R 1 <name>” in the foreground; terminate feh -and then Uxplay with “ctrl-C fg ctrl-C”.

      • +and then Uxplay with “ctrl-C fg ctrl-C.

      By default, GStreamer uses an algorithm to search for the best “videosink” (GStreamer’s term for a graphics driver to display images) @@ -1067,11 +1074,11 @@ starts (set it in the .uxplay startup file, where it is stored as cleartext.) All users must then know this password. This uses HTTP md5 Digest authentication, which is now regarded as providing weak security, but it is only used to validate the uxplay password, and no user -credentials are exposed. _Note: -pin and -pw are alternatives: if both -are specified at startup, the earlier of these two options is discarded. -If pwd is not specified, a random 4-digit pin code is -displayed, and must be entered on the client at each -new conenction.

      +credentials are exposed. If pwd is not +specified, a random 4-digit pin code is displayed, and must be entered +on the client at each new connection. Note: -pin +and -pw are alternatives: if both are specified at startup, the earlier +of these two options is discarded.

      -vsync [x] (In Mirror mode:) this option (now the default) uses timestamps to synchronize audio with video on the server, with an optional audio delay in (decimal) @@ -1236,6 +1243,9 @@ client. Values in the range [0.0, 10.0] seconds are allowed, and will be converted to a whole number of microseconds. Default is 0.25 sec (250000 usec). (However, the client appears to ignore this reported latency, so this option seems non-functional.)

      +

      -ca (without specifying a filename) now displays +“cover art” that accompanies Apple Music when played in “Audio-only” +(ALAC) mode.

      -ca filename provides a file (where filename can include a full path) used for output of “cover art” (from Apple Music, etc.,) in audio-only ALAC mode. This @@ -1700,6 +1710,8 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

      Changelog

      +

      xxxx 2025-07-07 Render Audio cover-art inside UxPlay with -ca option +(no file specified).

      1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced with -pw option. Update llhttp to v 9.3.0

      1.72.1 2025-06-06 minor update: fix regression in -reg option; add diff --git a/README.md b/README.md index 9e53aa1..2821164 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ ### **Now developed at the GitHub site (where ALL user issues should be posted, and latest versions can be found).** +- **NEW on github**: option -ca (with no filename given) will now render + Apple Music cover art (in audio-only mode) inside + UxPlay. (-ca `` will continue to export cover art for + display by an external viewer). + - **NEW in v1.72**: Improved Support for (YouTube) HLS (HTTP Live Streaming) video with the new "-hls" option (introduced in 1.71).* **Only streaming from the YouTube iOS app (in \"m3u8\" protocol) is currently supported**: (streaming using the AirPlay icon in a browser window @@ -93,7 +98,8 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - For Audio-only mode (Apple Music, etc.) best quality is obtained with the option "uxplay -async", but there is then a 2 second - latency imposed by iOS. + latency imposed by iOS. Use option "uxplay -ca" to display any "Cover Art" that + accompanies the audio. - If you are using UxPlay just to mirror the client's screen (without showing videos that need audio synchronized with video), it is best to @@ -606,12 +612,14 @@ value advances it.) -FPSdata.) When using this, you should use the default timestamp-based synchronization option `-vsync`. -- Since UxPlay-1.54, you can display the accompanying "Cover Art" from - sources like Apple Music in Audio-Only (ALAC) mode: run +- You can now display (inside UxPlay) the accompanying "Cover Art" from + sources like Apple Music in Audio-Only (ALAC) mode with the option + `uxplay -ca`. _The older method of exporting cover art to an external + viewer remains available: run "`uxplay -ca &`" in the background, then run a image viewer with an autoreload feature: an example is "feh": run "`feh -R 1 `" in the foreground; terminate feh and then Uxplay - with "`ctrl-C fg ctrl-C`". + with "`ctrl-C fg ctrl-C`"_. By default, GStreamer uses an algorithm to search for the best "videosink" (GStreamer's term for a graphics driver to display images) @@ -1060,11 +1068,11 @@ can be controlled with a password set when uxplay starts (set it in the .uxplay startup file, where it is stored as cleartext.) All users must then know this password. This uses HTTP md5 Digest authentication, which is now regarded as providing weak security, but it is only used to -validate the uxplay password, and no user credentials are exposed. _Note: --pin and -pw are alternatives: if both are specified at startup, the -earlier of these two options is discarded. If *pwd* is not specified, -a random 4-digit pin code is displayed, and must be entered on the client -at **each** new conenction. +validate the uxplay password, and no user credentials are exposed. +If *pwd* is **not** specified, a random 4-digit pin code is displayed, and must +be entered on the client at **each** new connection. +_Note: -pin and -pw are alternatives: if both are specified at startup, the +earlier of these two options is discarded._ **-vsync \[x\]** (In Mirror mode:) this option (**now the default**) uses timestamps to synchronize audio with video on the server, with an @@ -1245,6 +1253,9 @@ number of microseconds. Default is 0.25 sec (250000 usec). *(However, the client appears to ignore this reported latency, so this option seems non-functional.)* +**-ca** (without specifying a filename) now displays "cover art" + that accompanies Apple Music when played in "Audio-only" (ALAC) mode. + **-ca *filename*** provides a file (where *filename* can include a full path) used for output of "cover art" (from Apple Music, *etc.*,) in audio-only ALAC mode. This file is overwritten with the latest cover art @@ -1731,6 +1742,9 @@ introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be. # Changelog +xxxx 2025-07-07 Render Audio cover-art inside UxPlay with -ca option (no file +specified). + 1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced with -pw option. Update llhttp to v 9.3.0 diff --git a/README.txt b/README.txt index bd95777..c2283ef 100644 --- a/README.txt +++ b/README.txt @@ -2,6 +2,11 @@ ### **Now developed at the GitHub site (where ALL user issues should be posted, and latest versions can be found).** +- **NEW on github**: option -ca (with no filename given) will now + render Apple Music cover art (in audio-only mode) inside UxPlay. + (-ca `` will continue to export cover art for display by + an external viewer). + - **NEW in v1.72**: Improved Support for (YouTube) HLS (HTTP Live Streaming) video with the new "-hls" option (introduced in 1.71).\* **Only streaming from the YouTube iOS app (in \"m3u8\" protocol) is @@ -100,7 +105,8 @@ status](https://repology.org/badge/vertical-allrepos/uxplay.svg)](https://repolo - For Audio-only mode (Apple Music, etc.) best quality is obtained with the option "uxplay -async", but there is then a 2 second - latency imposed by iOS. + latency imposed by iOS. Use option "uxplay -ca" to display any + "Cover Art" that accompanies the audio. - If you are using UxPlay just to mirror the client's screen (without showing videos that need audio synchronized with video), it is best @@ -620,12 +626,13 @@ value advances it.) -FPSdata.) When using this, you should use the default timestamp-based synchronization option `-vsync`. -- Since UxPlay-1.54, you can display the accompanying "Cover Art" from - sources like Apple Music in Audio-Only (ALAC) mode: run - "`uxplay -ca &`" in the background, then run a image viewer - with an autoreload feature: an example is "feh": run - "`feh -R 1 `" in the foreground; terminate feh and then Uxplay - with "`ctrl-C fg ctrl-C`". +- You can now display (inside UxPlay) the accompanying "Cover Art" + from sources like Apple Music in Audio-Only (ALAC) mode with the + option `uxplay -ca`. *The older method of exporting cover art to an + external viewer remains available: run "`uxplay -ca &`" in + the background, then run a image viewer with an autoreload feature: + an example is "feh": run "`feh -R 1 `" in the foreground; + terminate feh and then Uxplay with "`ctrl-C fg ctrl-C`"*. By default, GStreamer uses an algorithm to search for the best "videosink" (GStreamer's term for a graphics driver to display images) @@ -1080,11 +1087,11 @@ access can be controlled with a password set when uxplay starts (set it in the .uxplay startup file, where it is stored as cleartext.) All users must then know this password. This uses HTTP md5 Digest authentication, which is now regarded as providing weak security, but it is only used to -validate the uxplay password, and no user credentials are exposed. -\_Note: -pin and -pw are alternatives: if both are specified at startup, -the earlier of these two options is discarded. If *pwd* is not -specified, a random 4-digit pin code is displayed, and must be entered -on the client at **each** new conenction. +validate the uxplay password, and no user credentials are exposed. If +*pwd* is **not** specified, a random 4-digit pin code is displayed, and +must be entered on the client at **each** new connection. *Note: -pin +and -pw are alternatives: if both are specified at startup, the earlier +of these two options is discarded.* **-vsync \[x\]** (In Mirror mode:) this option (**now the default**) uses timestamps to synchronize audio with video on the server, with an @@ -1265,6 +1272,9 @@ number of microseconds. Default is 0.25 sec (250000 usec). *(However, the client appears to ignore this reported latency, so this option seems non-functional.)* +**-ca** (without specifying a filename) now displays "cover art" that +accompanies Apple Music when played in "Audio-only" (ALAC) mode. + **-ca *filename*** provides a file (where *filename* can include a full path) used for output of "cover art" (from Apple Music, *etc.*,) in audio-only ALAC mode. This file is overwritten with the latest cover art @@ -1751,6 +1761,9 @@ what version UxPlay claims to be. # Changelog +xxxx 2025-07-07 Render Audio cover-art inside UxPlay with -ca option (no +file specified). + 1.72.2 2025-07-07 Fix bug (typo) in DNS_SD advertisement introduced with -pw option. Update llhttp to v 9.3.0 diff --git a/lib/raop.h b/lib/raop.h index fe81818..6cbe3d6 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -82,6 +82,7 @@ struct raop_callbacks_s { void (*audio_set_volume)(void *cls, float volume); void (*audio_set_metadata)(void *cls, const void *buffer, int buflen); void (*audio_set_coverart)(void *cls, const void *buffer, int buflen); + void (*audio_stop_coverart_rendering) (void* cls); void (*audio_remote_control_id)(void *cls, const char *dacp_id, const char *active_remote_header); void (*audio_set_progress)(void *cls, unsigned int start, unsigned int curr, unsigned int end); void (*audio_get_format)(void *cls, unsigned char *ct, unsigned short *spf, bool *usingScreen, bool *isMedia, uint64_t *audioFormat); @@ -99,8 +100,8 @@ struct raop_callbacks_s { void (*on_video_rate) (void *cls, const float rate); void (*on_video_stop) (void *cls); void (*on_video_acquire_playback_info) (void *cls, playback_info_t *playback_video); - }; + typedef struct raop_callbacks_s raop_callbacks_t; raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote, int remote_addr_len, unsigned short timing_rport, diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 5003cbe..c89fb7f 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -1191,6 +1191,10 @@ raop_handler_teardown(raop_conn_t *conn, if (conn->raop_rtp) { /* Stop our audio RTP session */ raop_rtp_stop(conn->raop_rtp); + /* stop any coverart rendering */ + if (conn->raop->callbacks.audio_stop_coverart_rendering) { + conn->raop->callbacks.audio_stop_coverart_rendering(conn->raop->callbacks.cls); + } } } else if (teardown_110) { conn->raop->callbacks.video_reset(conn->raop->callbacks.cls); diff --git a/renderers/video_renderer.c b/renderers/video_renderer.c index f336d6d..c701c88 100644 --- a/renderers/video_renderer.c +++ b/renderers/video_renderer.c @@ -72,7 +72,7 @@ typedef enum { //GST_PLAY_FLAG_FORCE_SW_DECODERS = (1 << 12), } GstPlayFlags; -#define NCODECS 2 /* renderers for h264 and h265 */ +#define NCODECS 3 /* renderers for h264,h265, and jpeg images */ struct video_renderer_s { GstElement *appsrc, *pipeline; @@ -95,7 +95,8 @@ static video_renderer_t *renderer_type[NCODECS] = {0}; static int n_renderers = NCODECS; static char h264[] = "h264"; static char h265[] = "h265"; -static char hls[] = "hls"; +static char hls[] = "hls"; +static char jpeg[] = "jpeg"; static void append_videoflip (GString *launch, const videoflip_t *flip, const videoflip_t *rot) { /* videoflip image transform */ @@ -164,6 +165,7 @@ static void append_videoflip (GString *launch, const videoflip_t *flip, const vi * closest used by GStreamer < 1.20.4 is BT709, 2:3:5:1 with * // now use sRGB = 1:1:7:1 * range = 2 -> GST_VIDEO_COLOR_RANGE_16_235 ("limited RGB") */ +static const char jpeg_caps[]="image/jpeg"; static const char h264_caps[]="video/x-h264,stream-format=(string)byte-stream,alignment=(string)au"; static const char h265_caps[]="video/x-h265,stream-format=(string)byte-stream,alignment=(string)au"; @@ -246,18 +248,20 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide appname = NULL; /* the renderer for hls video will only be built if a HLS uri is provided in - * the call to video_renderer_init, in which case the h264 and 265 mirror-mode - * renderers will not be built. This is because it appears that we cannot + * the call to video_renderer_init, in which case the h264/h265 mirror-mode and jpeg + * audio-mode renderers will not be built. This is because it appears that we cannot * put playbin into GST_STATE_READY before knowing the uri (?), so cannot use a - * unified renderer structure with h264, h265 and hls */ + * unified renderer structure with h264, h265, jpeg and hls */ if (hls_video) { n_renderers = 1; + /* renderer[0]: playbin (hls) */ } else { - n_renderers = h265_support ? 2 : 1; + n_renderers = h265_support ? 3 : 2; + /* renderer[0]: jpeg; [1]: h264; [2]: h265 */ } g_assert (n_renderers <= NCODECS); for (int i = 0; i < n_renderers; i++) { - g_assert (i < 2); + g_assert (i < 3); renderer_type[i] = (video_renderer_t *) calloc(1, sizeof(video_renderer_t)); g_assert(renderer_type[i]); renderer_type[i]->autovideo = auto_videosink; @@ -280,8 +284,8 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide g_assert(renderer_type[i]->pipeline); renderer_type[i]->appsrc = NULL; renderer_type[i]->codec = hls; - /* if we are not using autovideosink, build a videossink based on the string "videosink" */ - if(strcmp(videosink, "autovideosink")) { + /* if we are not using an autovideosink, build a videosink based on the string "videosink" */ + if (!auto_videosink) { GstElement *playbin_videosink = make_video_sink(videosink, videosink_options); if (!playbin_videosink) { logger_log(logger, LOGGER_ERR, "video_renderer_init: failed to create playbin_videosink"); @@ -297,12 +301,18 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide g_object_set(renderer_type[i]->pipeline, "flags", flags, NULL); g_object_set (G_OBJECT (renderer_type[i]->pipeline), "uri", uri, NULL); } else { + bool jpeg_pipeline = false; switch (i) { case 0: + jpeg_pipeline = true; + renderer_type[i]->codec = jpeg; + caps = gst_caps_from_string(jpeg_caps); + break; + case 1: renderer_type[i]->codec = h264; caps = gst_caps_from_string(h264_caps); break; - case 1: + case 2: renderer_type[i]->codec = h265; caps = gst_caps_from_string(h265_caps); break; @@ -310,22 +320,29 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide g_assert(0); } GString *launch = g_string_new("appsrc name=video_source ! "); - g_string_append(launch, "queue ! "); - g_string_append(launch, parser); - g_string_append(launch, " ! "); - g_string_append(launch, decoder); + if (jpeg_pipeline) { + g_string_append(launch, "jpegdec "); + } else { + g_string_append(launch, "queue ! "); + g_string_append(launch, parser); + g_string_append(launch, " ! "); + g_string_append(launch, decoder); + } g_string_append(launch, " ! "); append_videoflip(launch, &videoflip[0], &videoflip[1]); g_string_append(launch, converter); g_string_append(launch, " ! "); g_string_append(launch, "videoscale ! "); + if (jpeg_pipeline) { + g_string_append(launch, " imagefreeze allow-replace=TRUE ! "); + } g_string_append(launch, videosink); g_string_append(launch, " name="); g_string_append(launch, videosink); g_string_append(launch, "_"); g_string_append(launch, renderer_type[i]->codec); g_string_append(launch, videosink_options); - if (video_sync) { + if (video_sync && !jpeg_pipeline) { g_string_append(launch, " sync=true"); sync = true; } else { @@ -366,7 +383,6 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide gst_pipeline_use_clock(GST_PIPELINE_CAST(renderer_type[i]->pipeline), clock); renderer_type[i]->appsrc = gst_bin_get_by_name (GST_BIN (renderer_type[i]->pipeline), "video_source"); g_assert(renderer_type[i]->appsrc); - g_object_set(renderer_type[i]->appsrc, "caps", caps, "stream-type", 0, "is-live", TRUE, "format", GST_FORMAT_TIME, NULL); g_string_free(launch, TRUE); gst_caps_unref(caps); @@ -388,7 +404,7 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide g_assert(renderer_type[0]->gst_window); get_X11_Display(renderer_type[0]->gst_window, x11_display_name); if (renderer_type[0]->gst_window->display) { - renderer_type[i]->use_x11 = true; + renderer_type[0]->use_x11 = true; } else { free(renderer_type[0]->gst_window); renderer_type[0]->gst_window = NULL; @@ -487,6 +503,16 @@ bool waiting_for_x11_window() { return false; } +void video_renderer_display_jpeg(const void *data, int *data_len) { + GstBuffer *buffer; + if (renderer && !strcmp(renderer->codec, jpeg)) { + buffer = gst_buffer_new_allocate(NULL, *data_len, NULL); + g_assert(buffer != NULL); + gst_buffer_fill(buffer, 0, data, *data_len); + gst_app_src_push_buffer (GST_APP_SRC(renderer->appsrc), buffer); + } +} + uint64_t video_renderer_render_buffer(unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time) { GstBuffer *buffer; GstClockTime pts = (GstClockTime) *ntp_time; /*now in nsecs */ @@ -849,19 +875,19 @@ gboolean gstreamer_pipeline_bus_callback(GstBus *bus, GstMessage *message, void return TRUE; } -int video_renderer_choose_codec (bool video_is_h265) { +int video_renderer_choose_codec (bool video_is_jpeg, bool video_is_h265) { video_renderer_t *renderer_used = NULL; - video_renderer_t *renderer_unused = NULL; g_assert(!hls_video); - if (n_renderers == 1) { + if (video_is_jpeg) { + renderer_used = renderer_type[0]; + } else if (n_renderers == 2) { if (video_is_h265) { logger_log(logger, LOGGER_ERR, "video is h265 but the -h265 option was not used"); return -1; } - renderer_used = renderer_type[0]; + renderer_used = renderer_type[1]; } else { - renderer_used = video_is_h265 ? renderer_type[1] : renderer_type[0]; - renderer_unused = video_is_h265 ? renderer_type[0] : renderer_type[1]; + renderer_used = video_is_h265 ? renderer_type[2] : renderer_type[1]; } if (renderer_used == NULL) { return -1; @@ -880,14 +906,16 @@ int video_renderer_choose_codec (bool video_is_h265) { logger_log(logger, LOGGER_DEBUG, "video_pipeline state change from %s to %s\n", gst_element_state_get_name (old_state),gst_element_state_get_name (new_state)); gst_video_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); - if (renderer == renderer_type[1]) { + if (n_renderers > 2 && renderer == renderer_type[2]) { logger_log(logger, LOGGER_INFO, "*** video format is h265 high definition (HD/4K) video %dx%d", width, height); } - if (renderer_unused) { - for (int i = 0; i < n_renderers; i++) { - if (renderer_type[i] != renderer_unused) { - continue; - } + /* destroy unused renderers */ + for (int i = 1; i < n_renderers; i++) { + if (renderer_type[i] == renderer) { + continue; + } + if (renderer_type[i]) { + video_renderer_t *renderer_unused = renderer_type[i]; renderer_type[i] = NULL; video_renderer_destroy_instance(renderer_unused); } diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 1fbdbf4..9c307e8 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -58,13 +58,14 @@ void video_renderer_set_start(float position); void video_renderer_resume (); bool video_renderer_is_paused(); uint64_t video_renderer_render_buffer (unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time); +void video_renderer_display_jpeg(const void *data, int *data_len); void video_renderer_flush (); unsigned int video_renderer_listen(void *loop, int id); void video_renderer_destroy (); void video_renderer_size(float *width_source, float *height_source, float *width, float *height); bool waiting_for_x11_window(); bool video_get_playback_info(double *duration, double *position, float *rate, bool *buffer_empty, bool *buffer_full); -int video_renderer_choose_codec(bool is_h265); +int video_renderer_choose_codec (bool video_is_jpeg, bool video_is_h265); unsigned int video_renderer_listen(void *loop, int id); unsigned int video_reset_callback(void *loop); #ifdef __cplusplus diff --git a/uxplay.1 b/uxplay.1 index f4554e3..3cda48d 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -115,6 +115,8 @@ UxPlay 1.72: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-al\fR x Audio latency in seconds (default 0.25) reported to client. .TP +\fB\-ca\fR Display cover-art in AirPlay Audio (ALAC) mode. +.TP \fB\-ca\fI fn \fR In Airplay Audio (ALAC) mode, write cover-art to file fn. .TP \fB\-md\fI fn \fR In Airplay Audio (ALAC) mode, write metadata text to file fn. diff --git a/uxplay.cpp b/uxplay.cpp index a0e936e..48f3a3b 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -129,6 +129,7 @@ static bool dump_audio = false; static unsigned char audio_type = 0x00; static unsigned char previous_audio_type = 0x00; static bool fullscreen = false; +static bool render_coverart = false; static std::string coverart_filename = ""; static std::string metadata_filename = ""; static bool do_append_hostname = true; @@ -714,7 +715,7 @@ static void print_info (char *name) { printf(" osssink,oss4sink,osxaudiosink,wasapisink,directsoundsink.\n"); printf("-as 0 (or -a) Turn audio off, streamed video only\n"); printf("-al x Audio latency in seconds (default 0.25) reported to client.\n"); - printf("-ca In Airplay Audio (ALAC) mode, write cover-art to file \n"); + printf("-ca []In Audio (ALAC) mode, render cover-art [or write to file ]\n"); printf("-md In Airplay Audio (ALAC) mode, write metadata text to file \n"); printf("-reset n Reset after n seconds of client silence (default n=%d, 0=never)\n", MISSED_FEEDBACK_LIMIT); printf("-nofreeze Do NOT leave frozen screen in place after reset\n"); @@ -1154,20 +1155,20 @@ static void parse_arguments (int argc, char *argv[]) { if (!file_has_write_access(fn)) { fprintf(stderr, "%s cannot be written to:\noption \"-admp \" must be to a file with write access\n", fn); exit(1); - } + } } } else if (arg == "-ca" ) { - if (option_has_value(i, argc, arg, argv[i+1])) { + if (i < argc - 1 && *argv[i+1] != '-') { coverart_filename.erase(); coverart_filename.append(argv[++i]); const char *fn = coverart_filename.c_str(); + render_coverart = false; if (!file_has_write_access(fn)) { fprintf(stderr, "%s cannot be written to:\noption \"-ca \" must be to a file with write access\n", fn); exit(1); } } else { - fprintf(stderr,"option -ca must be followed by a filename for cover-art output\n"); - exit(1); + render_coverart = true; } } else if (arg == "-md" ) { if (option_has_value(i, argc, arg, argv[i+1])) { @@ -1175,7 +1176,7 @@ static void parse_arguments (int argc, char *argv[]) { metadata_filename.append(argv[++i]); const char *fn = metadata_filename.c_str(); if (!file_has_write_access(fn)) { - fprintf(stderr, "%s cannot be written to:\noption \"-ca \" must be to a file with write access\n", fn); + fprintf(stderr, "%s cannot be written to:\noption \"-md \" must be to a file with write access\n", fn); exit(1); } } else { @@ -1690,7 +1691,7 @@ extern "C" void video_reset(void *cls) { extern "C" int video_set_codec(void *cls, video_codec_t codec) { bool video_is_h265 = (codec == VIDEO_CODEC_H265); - return video_renderer_choose_codec(video_is_h265); + return video_renderer_choose_codec(false, video_is_h265); } extern "C" void display_pin(void *cls, char *pin) { @@ -1967,6 +1968,15 @@ extern "C" void audio_set_coverart(void *cls, const void *buffer, int buflen) { if (buffer && coverart_filename.length()) { write_coverart(coverart_filename.c_str(), buffer, buflen); LOGI("coverart size %d written to %s", buflen, coverart_filename.c_str()); + } else if (buffer && render_coverart) { + video_renderer_choose_codec(true, false); /* video_is_jpeg = true */ + video_renderer_display_jpeg(buffer, &buflen); + } +} + +extern "C" void audio_stop_coverart_rendering(void *cls) { + if (render_coverart) { + video_reset(cls); } } @@ -2149,6 +2159,7 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3], raop_cbs.video_report_size = video_report_size; raop_cbs.audio_set_metadata = audio_set_metadata; raop_cbs.audio_set_coverart = audio_set_coverart; + raop_cbs.audio_stop_coverart_rendering = audio_stop_coverart_rendering; raop_cbs.audio_set_progress = audio_set_progress; raop_cbs.report_client_request = report_client_request; raop_cbs.display_pin = display_pin; From cf27c06c3333c05375b00a4ef2e0ed88f1e9c8b2 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Wed, 9 Jul 2025 23:02:15 -0400 Subject: [PATCH 65/65] -pw option: do not reuse random_pw for new client --- lib/raop_handlers.h | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index c89fb7f..4dcfbab 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -26,6 +26,7 @@ #define AUDIO_SAMPLE_RATE 44100 /* all supported AirPlay audio format use this sample rate */ #define SECOND_IN_USECS 1000000 #define SECOND_IN_NSECS 1000000000 +#define MAX_PW_ATTEMPTS 5 typedef void (*raop_handler_t)(raop_conn_t *, http_request_t *, http_response_t *, char **, int *); @@ -584,14 +585,23 @@ raop_handler_setup(raop_conn_t *conn, // First setup + char *deviceID = NULL; + plist_t req_deviceid_node = plist_dict_get_item(req_root_node, "deviceID"); + plist_get_string_val(req_deviceid_node, &deviceID); + + /* RFC2617 Digest authentication (md5 hash) of uxplay client-access password, if set */ if (!conn->authenticated && conn->raop->callbacks.passwd) { + size_t pin_len = 4; + if (conn->raop->random_pw && strncmp(conn->raop->random_pw + pin_len + 1, deviceID, 17)) { + conn->raop->auth_fail_count = MAX_PW_ATTEMPTS; + } int len; const char *password = conn->raop->callbacks.passwd(conn->raop->callbacks.cls, &len); // len = -1 means use a random password for this connection; len = 0 means no password - if (len == -1 && conn->raop->random_pw && conn->raop->auth_fail_count >= 5) { - // change random_pw after 5 failed authentication attempts - logger_log(conn->raop->logger, LOGGER_INFO, "Too many authentication failures: generate new random password"); + if (len == -1 && conn->raop->random_pw && conn->raop->auth_fail_count >= MAX_PW_ATTEMPTS) { + // change random_pw after MAX_PW_ATTEMPTS failed authentication attempts + logger_log(conn->raop->logger, LOGGER_INFO, "Too many authentication failures or new client: generate new random password"); free(conn->raop->random_pw); conn->raop->random_pw = NULL; } @@ -602,11 +612,11 @@ raop_handler_setup(raop_conn_t *conn, logger_log(conn->raop->logger, LOGGER_ERR, "Failed to generate random pin"); pin_4 = 1234; } - size_t len = 4; - conn->raop->random_pw = (char *) malloc(len + 1); + conn->raop->random_pw = (char *) malloc(pin_len + 1 + 18); char *pin = conn->raop->random_pw; - snprintf(pin, len + 1, "%04u", pin_4 % 10000); - pin[len] = '\0'; + snprintf(pin, pin_len + 1, "%04u", pin_4 % 10000); + pin[pin_len] = '\0'; + snprintf(pin + pin_len + 1, 18, "%s", deviceID); conn->raop->auth_fail_count = 0; if (conn->raop->callbacks.display_pin) { conn->raop->callbacks.display_pin(conn->raop->callbacks.cls, pin); @@ -635,7 +645,7 @@ raop_handler_setup(raop_conn_t *conn, logger_log(conn->raop->logger, LOGGER_INFO, "*** CLIENT MUST NOW ENTER PIN = \"%s\" AS AIRPLAY PASSWORD", conn->raop->random_pw); } if (conn->authenticated) { - printf("initial authenticatication OK\n"); + //printf("initial authenticatication OK\n"); conn->authenticated = conn->authenticated && !strcmp(nonce_string, conn->raop->nonce); if (!conn->authenticated) { logger_log(conn->raop->logger, LOGGER_INFO, "authentication rejected (nonce mismatch) %s %s", @@ -675,13 +685,9 @@ raop_handler_setup(raop_conn_t *conn, char* eiv = NULL; uint64_t eiv_len = 0; - - char *deviceID = NULL; - char *model = NULL; + char *model = NULL; char *name = NULL; bool admit_client = true; - plist_t req_deviceid_node = plist_dict_get_item(req_root_node, "deviceID"); - plist_get_string_val(req_deviceid_node, &deviceID); plist_t req_model_node = plist_dict_get_item(req_root_node, "model"); plist_get_string_val(req_model_node, &model); plist_t req_name_node = plist_dict_get_item(req_root_node, "name");