mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
rtsp-server: use an existing socket to establish HTTP tunnel
Make it possible to transfer a socket from an HTTP server to be used as an RTSP over HTTP tunnel.
This commit is contained in:
parent
86e53af34a
commit
ed66f974dd
4 changed files with 145 additions and 31 deletions
|
@ -1904,26 +1904,10 @@ client_watch_notify (GstRTSPClient * client)
|
|||
g_object_unref (client);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_client_attach:
|
||||
* @client: a #GstRTSPClient
|
||||
* @socket: a #GSocket
|
||||
* @cancellable: a #GCancellable
|
||||
* @error: a #GError
|
||||
*
|
||||
* Accept a new connection for @client on @socket.
|
||||
*
|
||||
* This function should be called when the client properties and urls are fully
|
||||
* configured and the client is ready to start.
|
||||
*
|
||||
* Returns: %TRUE if the client could be accepted.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_client_accept (GstRTSPClient * client, GSocket * socket,
|
||||
GCancellable * cancellable, GError ** error)
|
||||
static gboolean
|
||||
attach_client (GstRTSPClient * client, GSocket * socket,
|
||||
GstRTSPConnection *conn, GError ** error)
|
||||
{
|
||||
GstRTSPConnection *conn;
|
||||
GstRTSPResult res;
|
||||
GSocket *read_socket;
|
||||
GSocketAddress *addres;
|
||||
GSource *source;
|
||||
|
@ -1933,10 +1917,6 @@ gst_rtsp_client_accept (GstRTSPClient * client, GSocket * socket,
|
|||
socklen_t addrlen;
|
||||
gchar ip[INET6_ADDRSTRLEN];
|
||||
|
||||
/* a new client connected. */
|
||||
GST_RTSP_CHECK (gst_rtsp_connection_accept (socket, &conn, cancellable),
|
||||
accept_failed);
|
||||
|
||||
read_socket = gst_rtsp_connection_get_read_socket (conn);
|
||||
client->is_ipv6 = g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV6;
|
||||
|
||||
|
@ -1982,14 +1962,6 @@ gst_rtsp_client_accept (GstRTSPClient * client, GSocket * socket,
|
|||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
accept_failed:
|
||||
{
|
||||
gchar *str = gst_rtsp_strresult (res);
|
||||
|
||||
GST_ERROR ("Could not accept client on server socket %p: %s", socket, str);
|
||||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
no_address:
|
||||
{
|
||||
GST_ERROR ("could not get remote address %s", (*error)->message);
|
||||
|
@ -2007,3 +1979,77 @@ getnameinfo_failed:
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_client_create_from_socket:
|
||||
* @client: a #GstRTSPClient
|
||||
* @socket: a #GSocket
|
||||
* @ip: the IP address of the remote client
|
||||
* @port: the port used by the other end
|
||||
* @initial_buffer: any initial data that was already read from the socket
|
||||
* @error: a #GError
|
||||
*
|
||||
* Take an existing network socket and use it for an RTSP connection.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_client_create_from_socket (GstRTSPClient * client, GSocket * socket,
|
||||
const gchar * ip, gint port, const gchar * initial_buffer, GError ** error)
|
||||
{
|
||||
GstRTSPConnection *conn;
|
||||
GstRTSPResult res;
|
||||
|
||||
GST_RTSP_CHECK (gst_rtsp_connection_create_from_socket (socket, ip, port,
|
||||
initial_buffer, &conn), no_connection);
|
||||
|
||||
return attach_client (client, socket, conn, error);
|
||||
|
||||
/* ERRORS */
|
||||
no_connection:
|
||||
{
|
||||
gchar *str = gst_rtsp_strresult (res);
|
||||
|
||||
GST_ERROR ("could not create connection from socket %p: %s", socket, str);
|
||||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_client_attach:
|
||||
* @client: a #GstRTSPClient
|
||||
* @socket: a #GSocket
|
||||
* @cancellable: a #GCancellable
|
||||
* @error: a #GError
|
||||
*
|
||||
* Accept a new connection for @client on @socket.
|
||||
*
|
||||
* This function should be called when the client properties and urls are fully
|
||||
* configured and the client is ready to start.
|
||||
*
|
||||
* Returns: %TRUE if the client could be accepted.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_client_accept (GstRTSPClient * client, GSocket * socket,
|
||||
GCancellable * cancellable, GError ** error)
|
||||
{
|
||||
GstRTSPConnection *conn;
|
||||
GstRTSPResult res;
|
||||
|
||||
/* a new client connected. */
|
||||
GST_RTSP_CHECK (gst_rtsp_connection_accept (socket, &conn, cancellable),
|
||||
accept_failed);
|
||||
|
||||
return attach_client (client, socket, conn, error);
|
||||
|
||||
/* ERRORS */
|
||||
accept_failed:
|
||||
{
|
||||
gchar *str = gst_rtsp_strresult (res);
|
||||
|
||||
GST_ERROR ("Could not accept client on server socket %p: %s", socket, str);
|
||||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,6 +136,13 @@ gboolean gst_rtsp_client_accept (GstRTSPClient *client,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean gst_rtsp_client_create_from_socket(GstRTSPClient * client,
|
||||
GSocket *socket,
|
||||
const gchar * ip,
|
||||
gint port,
|
||||
const gchar *initial_buffer,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTSP_CLIENT_H__ */
|
||||
|
|
|
@ -779,6 +779,65 @@ accept_failed:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_transfer_connection:
|
||||
* @server: a #GstRTSPServer
|
||||
* @socket: a network socket
|
||||
* @ip: the IP address of the remote client
|
||||
* @port: the port used by the other end
|
||||
* @initial_buffer: any initial data that was already read from the socket
|
||||
*
|
||||
* Take an existing network socket and use it for an RTSP connection. This
|
||||
* is used when transferring a socket from an HTTP server which should be used
|
||||
* as an RTSP over HTTP tunnel. The @initial_buffer contains any remaining data
|
||||
* that the HTTP server read from the socket while parsing the HTTP header.
|
||||
*
|
||||
* Returns: TRUE if all was ok, FALSE if an error occured.
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_server_transfer_connection (GstRTSPServer * server, GSocket * socket,
|
||||
const gchar * ip, gint port, const gchar *initial_buffer)
|
||||
{
|
||||
GstRTSPClient *client = NULL;
|
||||
GstRTSPServerClass *klass;
|
||||
GError *error = NULL;
|
||||
|
||||
klass = GST_RTSP_SERVER_GET_CLASS (server);
|
||||
|
||||
if (klass->create_client)
|
||||
client = klass->create_client (server);
|
||||
if (client == NULL)
|
||||
goto client_failed;
|
||||
|
||||
/* a new client connected, create a client object to handle the client. */
|
||||
if (!gst_rtsp_client_create_from_socket (client, socket, ip, port,
|
||||
initial_buffer, &error)) {
|
||||
goto transfer_failed;
|
||||
}
|
||||
|
||||
/* manage the client connection */
|
||||
manage_client (server, client);
|
||||
|
||||
g_signal_emit (server, gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED], 0,
|
||||
client);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
client_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (server, "failed to create a client");
|
||||
return FALSE;
|
||||
}
|
||||
transfer_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (server, "failed to accept client: %s", error->message);
|
||||
g_error_free (error);
|
||||
gst_object_unref (client);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_server_io_func:
|
||||
* @socket: a #GSocket
|
||||
|
|
|
@ -116,6 +116,8 @@ GstRTSPMediaMapping * gst_rtsp_server_get_media_mapping (GstRTSPServer *serve
|
|||
void gst_rtsp_server_set_auth (GstRTSPServer *server, GstRTSPAuth *auth);
|
||||
GstRTSPAuth * gst_rtsp_server_get_auth (GstRTSPServer *server);
|
||||
|
||||
gboolean gst_rtsp_server_transfer_connection (GstRTSPServer * server, GSocket *socket, const gchar * ip, gint port, const gchar *initial_buffer);
|
||||
|
||||
gboolean gst_rtsp_server_io_func (GSocket *socket, GIOCondition condition,
|
||||
GstRTSPServer *server);
|
||||
|
||||
|
|
Loading…
Reference in a new issue