From 0e6cd64232f54cb4defe76656348f4fb4eefbf18 Mon Sep 17 00:00:00 2001 From: Daniel Moberg Date: Mon, 18 Sep 2023 08:40:07 +0200 Subject: [PATCH] rtspsrc: Property for adding custom http request headers This commit adds a property which enables adding custom http request headers to the rtspsrc element. Added headers will be appended to http requests made during http tunneling. Part-of: --- .../docs/gst_plugins_cache.json | 12 ++++ .../gst-plugins-good/gst/rtsp/gstrtspsrc.c | 56 ++++++++++++++++++- .../gst-plugins-good/gst/rtsp/gstrtspsrc.h | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index 82380a1835..bf5ad6657b 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -21342,6 +21342,18 @@ "type": "gboolean", "writable": true }, + "extra-http-request-headers": { + "blurb": "Extra headers to append to HTTP requests when in tunneled mode", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "extra-http-request-headers;", + "mutable": "null", + "readable": true, + "type": "GstStructure", + "writable": true + }, "ignore-x-server-reply": { "blurb": "Whether to ignore the x-server-ip-address server header reply", "conditionally-available": false, diff --git a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c index 2a6751d586..864594d025 100644 --- a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c +++ b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c @@ -363,7 +363,8 @@ enum PROP_ONVIF_MODE, PROP_ONVIF_RATE_CONTROL, PROP_IS_LIVE, - PROP_IGNORE_X_SERVER_REPLY + PROP_IGNORE_X_SERVER_REPLY, + PROP_EXTRA_HTTP_REQUEST_HEADERS, }; #define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type()) @@ -1098,6 +1099,22 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass) DEFAULT_IGNORE_X_SERVER_REPLY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRTSPSrc:extra-http-request-headers + * + * When in tunneled mode append provided headers to any HTTP requests + * made by rtspsrc. + * + * Only applicable for RTSP over HTTP. + * + * Since: 1.24 + */ + g_object_class_install_property (gobject_class, + PROP_EXTRA_HTTP_REQUEST_HEADERS, + g_param_spec_boxed ("extra-http-request-headers", "Extra Headers", + "Extra headers to append to HTTP requests when in tunneled mode", + GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstRTSPSrc::handle-request: * @rtspsrc: a #GstRTSPSrc @@ -1527,6 +1544,8 @@ gst_rtspsrc_init (GstRTSPSrc * src) src->is_live = DEFAULT_IS_LIVE; src->seek_seqnum = GST_SEQNUM_INVALID; src->group_id = GST_GROUP_ID_INVALID; + src->prop_extra_http_request_headers = + gst_structure_new_empty ("extra-http-request-headers"); /* get a list of all extensions */ src->extensions = gst_rtsp_ext_list_get (); @@ -1602,6 +1621,11 @@ gst_rtspsrc_finalize (GObject * object) if (rtspsrc->initial_seek) gst_event_unref (rtspsrc->initial_seek); + if (rtspsrc->prop_extra_http_request_headers) { + gst_structure_free (rtspsrc->prop_extra_http_request_headers); + rtspsrc->prop_extra_http_request_headers = NULL; + } + /* free locks */ g_rec_mutex_clear (&rtspsrc->stream_rec_lock); g_rec_mutex_clear (&rtspsrc->state_rec_lock); @@ -1872,6 +1896,16 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value, case PROP_IGNORE_X_SERVER_REPLY: rtspsrc->ignore_x_server_reply = g_value_get_boolean (value); break; + case PROP_EXTRA_HTTP_REQUEST_HEADERS:{ + const GstStructure *s = gst_value_get_structure (value); + if (rtspsrc->prop_extra_http_request_headers) { + gst_structure_free (rtspsrc->prop_extra_http_request_headers); + } + rtspsrc->prop_extra_http_request_headers = + s ? gst_structure_copy (s) : + gst_structure_new_empty ("extra-http-request-headers"); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2045,6 +2079,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_IGNORE_X_SERVER_REPLY: g_value_set_boolean (value, rtspsrc->ignore_x_server_reply); break; + case PROP_EXTRA_HTTP_REQUEST_HEADERS: + gst_value_set_structure (value, rtspsrc->prop_extra_http_request_headers); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -5289,6 +5326,18 @@ accept_certificate_cb (GTlsConnection * conn, GTlsCertificate * peer_cert, return accept; } +static gboolean +_add_header_to_conn (GQuark field_id, const GValue * value, gpointer user_data) +{ + const gchar *key_str = g_quark_to_string (field_id); + const gchar *value_str = g_value_get_string (value); + + GstRTSPConnection *conn = (GstRTSPConnection *) user_data; + gst_rtsp_connection_add_extra_http_request_header (conn, key_str, value_str); + + return TRUE; +} + static GstRTSPResult gst_rtsp_conninfo_connect (GstRTSPSrc * src, GstRTSPConnInfo * info, gboolean async) @@ -5347,6 +5396,11 @@ gst_rtsp_conninfo_connect (GstRTSPSrc * src, GstRTSPConnInfo * info, gst_rtsp_connection_set_proxy (info->connection, src->proxy_host, src->proxy_port); } + + if (src->prop_extra_http_request_headers != NULL) { + gst_structure_foreach (src->prop_extra_http_request_headers, + _add_header_to_conn, info->connection); + } } if (!info->connected) { diff --git a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.h b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.h index 9457972b56..2adfcba0f8 100644 --- a/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.h +++ b/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.h @@ -280,6 +280,7 @@ struct _GstRTSPSrc { gboolean onvif_rate_control; gboolean is_live; gboolean ignore_x_server_reply; + GstStructure *prop_extra_http_request_headers; /* state */ GstRTSPState state;