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;
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;
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);
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;
+ }
+}
}
}
+/**
+ * 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