* The RTSP server will call gst_rtsp_auth_check() with a string describing the
* check to perform. The possible checks are prefixed with
* #GST_RTSP_AUTH_CHECK_*. Depending on the check, the default implementation
- * will use the current #GstRTSPToken, #GstRTSPClientState and
+ * will use the current #GstRTSPToken, #GstRTSPContext and
* #GstRTSPPermissions on the object to check if an operation is allowed.
*
* The default #GstRTSPAuth object has support for basic authentication. With
const GValue * value, GParamSpec * pspec);
static void gst_rtsp_auth_finalize (GObject * obj);
-static gboolean default_authenticate (GstRTSPAuth * auth,
- GstRTSPClientState * state);
-static gboolean default_check (GstRTSPAuth * auth, GstRTSPClientState * state,
+static gboolean default_authenticate (GstRTSPAuth * auth, GstRTSPContext * ctx);
+static gboolean default_check (GstRTSPAuth * auth, GstRTSPContext * ctx,
const gchar * check);
G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT);
}
static gboolean
-default_authenticate (GstRTSPAuth * auth, GstRTSPClientState * state)
+default_authenticate (GstRTSPAuth * auth, GstRTSPContext * ctx)
{
GstRTSPAuthPrivate *priv = auth->priv;
GstRTSPResult res;
GST_DEBUG_OBJECT (auth, "authenticate");
g_mutex_lock (&priv->lock);
- /* FIXME, need to ref but we have no way to unref when the state is
+ /* FIXME, need to ref but we have no way to unref when the ctx is
* popped */
- state->token = priv->default_token;
+ ctx->token = priv->default_token;
g_mutex_unlock (&priv->lock);
res =
- gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION,
+ gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_AUTHORIZATION,
&authorization, 0);
if (res < 0)
goto no_auth;
g_mutex_lock (&priv->lock);
if ((token = g_hash_table_lookup (priv->basic, &authorization[6]))) {
GST_DEBUG_OBJECT (auth, "setting token %p", token);
- state->token = token;
+ ctx->token = token;
}
g_mutex_unlock (&priv->lock);
} else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) {
}
static void
-send_response (GstRTSPAuth * auth, GstRTSPStatusCode code,
- GstRTSPClientState * state)
+send_response (GstRTSPAuth * auth, GstRTSPStatusCode code, GstRTSPContext * ctx)
{
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
if (code == GST_RTSP_STS_UNAUTHORIZED) {
/* we only have Basic for now */
- gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_WWW_AUTHENTICATE,
+ gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_WWW_AUTHENTICATE,
"Basic realm=\"GStreamer RTSP Server\"");
}
- gst_rtsp_client_send_message (state->client, state->session, state->response);
+ gst_rtsp_client_send_message (ctx->client, ctx->session, ctx->response);
}
static gboolean
-ensure_authenticated (GstRTSPAuth * auth, GstRTSPClientState * state)
+ensure_authenticated (GstRTSPAuth * auth, GstRTSPContext * ctx)
{
GstRTSPAuthClass *klass;
klass = GST_RTSP_AUTH_GET_CLASS (auth);
/* we need a token to check */
- if (state->token == NULL) {
+ if (ctx->token == NULL) {
if (klass->authenticate) {
- if (!klass->authenticate (auth, state))
+ if (!klass->authenticate (auth, ctx))
goto authenticate_failed;
}
}
- if (state->token == NULL)
+ if (ctx->token == NULL)
goto no_auth;
return TRUE;
authenticate_failed:
{
GST_DEBUG_OBJECT (auth, "authenticate failed");
- send_response (auth, GST_RTSP_STS_UNAUTHORIZED, state);
+ send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
return FALSE;
}
no_auth:
{
GST_DEBUG_OBJECT (auth, "no authorization token found");
- send_response (auth, GST_RTSP_STS_UNAUTHORIZED, state);
+ send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
return FALSE;
}
}
/* new connection */
static gboolean
-check_connect (GstRTSPAuth * auth, GstRTSPClientState * state,
- const gchar * check)
+check_connect (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
{
GstRTSPAuthPrivate *priv = auth->priv;
GTlsConnection *tls;
/* configure the connection */
- tls = gst_rtsp_connection_get_tls (state->conn, NULL);
+ tls = gst_rtsp_connection_get_tls (ctx->conn, NULL);
g_tls_connection_set_certificate (tls, priv->certificate);
}
return TRUE;
/* check url and methods */
static gboolean
-check_url (GstRTSPAuth * auth, GstRTSPClientState * state, const gchar * check)
+check_url (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
{
GstRTSPAuthPrivate *priv = auth->priv;
- if ((state->method & priv->methods) != 0)
- if (!ensure_authenticated (auth, state))
+ if ((ctx->method & priv->methods) != 0)
+ if (!ensure_authenticated (auth, ctx))
goto not_authenticated;
return TRUE;
/* check access to media factory */
static gboolean
-check_factory (GstRTSPAuth * auth, GstRTSPClientState * state,
- const gchar * check)
+check_factory (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
{
const gchar *role;
GstRTSPPermissions *perms;
- if (!ensure_authenticated (auth, state))
+ if (!ensure_authenticated (auth, ctx))
return FALSE;
- if (!(role = gst_rtsp_token_get_string (state->token,
+ if (!(role = gst_rtsp_token_get_string (ctx->token,
GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE)))
goto no_media_role;
- if (!(perms = gst_rtsp_media_factory_get_permissions (state->factory)))
+ if (!(perms = gst_rtsp_media_factory_get_permissions (ctx->factory)))
goto no_permissions;
if (g_str_equal (check, GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS)) {
no_media_role:
{
GST_DEBUG_OBJECT (auth, "no media factory role found");
- send_response (auth, GST_RTSP_STS_UNAUTHORIZED, state);
+ send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
return FALSE;
}
no_permissions:
{
GST_DEBUG_OBJECT (auth, "no permissions on media factory found");
- send_response (auth, GST_RTSP_STS_UNAUTHORIZED, state);
+ send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
return FALSE;
}
no_access:
{
GST_DEBUG_OBJECT (auth, "no permissions to access media factory");
- send_response (auth, GST_RTSP_STS_NOT_FOUND, state);
+ send_response (auth, GST_RTSP_STS_NOT_FOUND, ctx);
return FALSE;
}
no_construct:
{
GST_DEBUG_OBJECT (auth, "no permissions to construct media factory");
- send_response (auth, GST_RTSP_STS_UNAUTHORIZED, state);
+ send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
return FALSE;
}
}
static gboolean
-check_client_settings (GstRTSPAuth * auth, GstRTSPClientState * state,
+check_client_settings (GstRTSPAuth * auth, GstRTSPContext * ctx,
const gchar * check)
{
- if (!ensure_authenticated (auth, state))
+ if (!ensure_authenticated (auth, ctx))
return FALSE;
- return gst_rtsp_token_is_allowed (state->token,
+ return gst_rtsp_token_is_allowed (ctx->token,
GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS);
}
static gboolean
-default_check (GstRTSPAuth * auth, GstRTSPClientState * state,
- const gchar * check)
+default_check (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
{
gboolean res = FALSE;
/* FIXME, use hastable or so */
if (g_str_equal (check, GST_RTSP_AUTH_CHECK_CONNECT)) {
- res = check_connect (auth, state, check);
+ res = check_connect (auth, ctx, check);
} else if (g_str_equal (check, GST_RTSP_AUTH_CHECK_URL)) {
- res = check_url (auth, state, check);
+ res = check_url (auth, ctx, check);
} else if (g_str_has_prefix (check, "auth.check.media.factory.")) {
- res = check_factory (auth, state, check);
+ res = check_factory (auth, ctx, check);
} else if (g_str_equal (check, GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS)) {
- res = check_client_settings (auth, state, check);
+ res = check_client_settings (auth, ctx, check);
}
return res;
}
{
gboolean result = FALSE;
GstRTSPAuthClass *klass;
- GstRTSPClientState *state;
+ GstRTSPContext *ctx;
GstRTSPAuth *auth;
g_return_val_if_fail (check != NULL, FALSE);
- if (!(state = gst_rtsp_client_state_get_current ()))
- goto no_state;
+ if (!(ctx = gst_rtsp_context_get_current ()))
+ goto no_context;
/* no auth, we don't need to check */
- if (!(auth = state->auth))
+ if (!(auth = ctx->auth))
return no_auth_check (check);
klass = GST_RTSP_AUTH_GET_CLASS (auth);
GST_DEBUG_OBJECT (auth, "check authorization '%s'", check);
if (klass->check)
- result = klass->check (auth, state, check);
+ result = klass->check (auth, ctx, check);
return result;
/* ERRORS */
-no_state:
+no_context:
{
- GST_ERROR ("no clientstate found");
+ GST_ERROR ("no context found");
return FALSE;
}
}
static void unlink_session_transports (GstRTSPClient * client,
GstRTSPSession * session, GstRTSPSessionMedia * sessmedia);
static gboolean default_configure_client_transport (GstRTSPClient * client,
- GstRTSPClientState * state, GstRTSPTransport * ct);
+ GstRTSPContext * ctx, GstRTSPTransport * ct);
static GstRTSPResult default_params_set (GstRTSPClient * client,
- GstRTSPClientState * state);
+ GstRTSPContext * ctx);
static GstRTSPResult default_params_get (GstRTSPClient * client,
- GstRTSPClientState * state);
+ GstRTSPContext * ctx);
G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
static void
send_generic_response (GstRTSPClient * client, GstRTSPStatusCode code,
- GstRTSPClientState * state)
+ GstRTSPContext * ctx)
{
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
- send_message (client, NULL, state->response, FALSE);
+ send_message (client, NULL, ctx->response, FALSE);
}
static gboolean
* but is cached for when the same client (without breaking the connection) is
* doing a setup for the exact same url. */
static GstRTSPMedia *
-find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched)
+find_media (GstRTSPClient * client, GstRTSPContext * ctx, gint * matched)
{
GstRTSPClientPrivate *priv = client->priv;
GstRTSPMediaFactory *factory;
if (!priv->mount_points)
goto no_mount_points;
- path = state->uri->abspath;
+ path = ctx->uri->abspath;
/* find the longest matching factory for the uri first */
if (!(factory = gst_rtsp_mount_points_match (priv->mount_points,
path, matched)))
goto no_factory;
- state->factory = factory;
+ ctx->factory = factory;
if (!gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS))
goto no_factory_access;
priv->media = NULL;
/* prepare the media and add it to the pipeline */
- if (!(media = gst_rtsp_media_factory_construct (factory, state->uri)))
+ if (!(media = gst_rtsp_media_factory_construct (factory, ctx->uri)))
goto no_media;
- state->media = media;
+ ctx->media = media;
thread = gst_rtsp_thread_pool_get_thread (priv->thread_pool,
- GST_RTSP_THREAD_TYPE_MEDIA, state);
+ GST_RTSP_THREAD_TYPE_MEDIA, ctx);
if (thread == NULL)
goto no_thread;
} else {
/* we have seen this path before, used cached media */
media = priv->media;
- state->media = media;
+ ctx->media = media;
GST_INFO ("reusing cached media %p for path %s", media, priv->path);
}
g_object_unref (factory);
- state->factory = NULL;
+ ctx->factory = NULL;
if (media)
g_object_ref (media);
no_mount_points:
{
GST_ERROR ("client %p: no mount points configured", client);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return NULL;
}
no_factory:
{
GST_ERROR ("client %p: no factory for uri %s", client, path);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return NULL;
}
no_factory_access:
no_media:
{
GST_ERROR ("client %p: can't create media", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (factory);
- state->factory = NULL;
+ ctx->factory = NULL;
return NULL;
}
no_thread:
{
GST_ERROR ("client %p: can't create thread", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (media);
- state->media = NULL;
+ ctx->media = NULL;
g_object_unref (factory);
- state->factory = NULL;
+ ctx->factory = NULL;
return NULL;
}
no_prepare:
{
GST_ERROR ("client %p: can't prepare media", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (media);
- state->media = NULL;
+ ctx->media = NULL;
g_object_unref (factory);
- state->factory = NULL;
+ ctx->factory = NULL;
return NULL;
}
}
}
static gboolean
-handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPClientPrivate *priv = client->priv;
GstRTSPSession *session;
const gchar *path;
gint matched;
- if (!state->session)
+ if (!ctx->session)
goto no_session;
- session = state->session;
+ session = ctx->session;
- if (!state->uri)
+ if (!ctx->uri)
goto no_uri;
- path = state->uri->abspath;
+ path = ctx->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (path[matched] != '\0')
goto no_aggregate;
- state->sessmedia = sessmedia;
+ ctx->sessmedia = sessmedia;
/* we emit the signal before closing the connection */
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_TEARDOWN_REQUEST],
- 0, state);
+ 0, ctx);
/* unlink the all TCP callbacks */
unlink_session_transports (client, session, sessmedia);
}
/* construct the response now */
code = GST_RTSP_STS_OK;
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
- send_message (client, session, state->response, TRUE);
+ send_message (client, session, ctx->response, TRUE);
return TRUE;
no_session:
{
GST_ERROR ("client %p: no session", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
return FALSE;
}
no_uri:
{
GST_ERROR ("client %p: no uri supplied", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
not_found:
{
GST_ERROR ("client %p: no media for uri", client);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return FALSE;
}
no_aggregate:
{
GST_ERROR ("client %p: no aggregate path %s", client, path);
send_generic_response (client,
- GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, state);
+ GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
return FALSE;
}
}
static GstRTSPResult
-default_params_set (GstRTSPClient * client, GstRTSPClientState * state)
+default_params_set (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPResult res;
- res = gst_rtsp_params_set (client, state);
+ res = gst_rtsp_params_set (client, ctx);
return res;
}
static GstRTSPResult
-default_params_get (GstRTSPClient * client, GstRTSPClientState * state)
+default_params_get (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPResult res;
- res = gst_rtsp_params_get (client, state);
+ res = gst_rtsp_params_get (client, ctx);
return res;
}
static gboolean
-handle_get_param_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_get_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPResult res;
guint8 *data;
guint size;
- res = gst_rtsp_message_get_body (state->request, &data, &size);
+ res = gst_rtsp_message_get_body (ctx->request, &data, &size);
if (res != GST_RTSP_OK)
goto bad_request;
if (size == 0) {
/* no body, keep-alive request */
- send_generic_response (client, GST_RTSP_STS_OK, state);
+ send_generic_response (client, GST_RTSP_STS_OK, ctx);
} else {
/* there is a body, handle the params */
- res = GST_RTSP_CLIENT_GET_CLASS (client)->params_get (client, state);
+ res = GST_RTSP_CLIENT_GET_CLASS (client)->params_get (client, ctx);
if (res != GST_RTSP_OK)
goto bad_request;
- send_message (client, state->session, state->response, FALSE);
+ send_message (client, ctx->session, ctx->response, FALSE);
}
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_GET_PARAMETER_REQUEST],
- 0, state);
+ 0, ctx);
return TRUE;
bad_request:
{
GST_ERROR ("client %p: bad request", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
}
static gboolean
-handle_set_param_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_set_param_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPResult res;
guint8 *data;
guint size;
- res = gst_rtsp_message_get_body (state->request, &data, &size);
+ res = gst_rtsp_message_get_body (ctx->request, &data, &size);
if (res != GST_RTSP_OK)
goto bad_request;
if (size == 0) {
/* no body, keep-alive request */
- send_generic_response (client, GST_RTSP_STS_OK, state);
+ send_generic_response (client, GST_RTSP_STS_OK, ctx);
} else {
/* there is a body, handle the params */
- res = GST_RTSP_CLIENT_GET_CLASS (client)->params_set (client, state);
+ res = GST_RTSP_CLIENT_GET_CLASS (client)->params_set (client, ctx);
if (res != GST_RTSP_OK)
goto bad_request;
- send_message (client, state->session, state->response, FALSE);
+ send_message (client, ctx->session, ctx->response, FALSE);
}
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_SET_PARAMETER_REQUEST],
- 0, state);
+ 0, ctx);
return TRUE;
bad_request:
{
GST_ERROR ("client %p: bad request", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
}
static gboolean
-handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia;
const gchar *path;
gint matched;
- if (!(session = state->session))
+ if (!(session = ctx->session))
goto no_session;
- if (!state->uri)
+ if (!ctx->uri)
goto no_uri;
- path = state->uri->abspath;
+ path = ctx->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (path[matched] != '\0')
goto no_aggregate;
- state->sessmedia = sessmedia;
+ ctx->sessmedia = sessmedia;
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
/* the session state must be playing or recording */
/* construct the response now */
code = GST_RTSP_STS_OK;
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
- send_message (client, session, state->response, FALSE);
+ send_message (client, session, ctx->response, FALSE);
/* the state is now READY */
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_READY);
- g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST],
- 0, state);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST], 0, ctx);
return TRUE;
no_session:
{
GST_ERROR ("client %p: no seesion", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
return FALSE;
}
no_uri:
{
GST_ERROR ("client %p: no uri supplied", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
not_found:
{
GST_ERROR ("client %p: no media for uri", client);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return FALSE;
}
no_aggregate:
{
GST_ERROR ("client %p: no aggregate path %s", client, path);
send_generic_response (client,
- GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, state);
+ GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
return FALSE;
}
invalid_state:
{
GST_ERROR ("client %p: not PLAYING or RECORDING", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
- state);
+ ctx);
return FALSE;
}
}
static gboolean
-handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia;
const gchar *path;
gint matched;
- if (!(session = state->session))
+ if (!(session = ctx->session))
goto no_session;
- if (!state->uri)
+ if (!ctx->uri)
goto no_uri;
- path = state->uri->abspath;
+ path = ctx->uri->abspath;
/* get a handle to the configuration of the media in the session */
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
if (path[matched] != '\0')
goto no_aggregate;
- state->sessmedia = sessmedia;
- state->media = media = gst_rtsp_session_media_get_media (sessmedia);
+ ctx->sessmedia = sessmedia;
+ ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
/* the session state must be playing or ready */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
goto invalid_state;
/* parse the range header if we have one */
- res =
- gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_RANGE, &str, 0);
+ res = gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_RANGE, &str, 0);
if (res == GST_RTSP_OK) {
if (gst_rtsp_range_parse (str, &range) == GST_RTSP_OK) {
/* we have a range, seek to the position */
if (infocount > 0)
g_string_append (rtpinfo, ", ");
- uristr = gst_rtsp_url_get_request_uri (state->uri);
+ uristr = gst_rtsp_url_get_request_uri (ctx->uri);
g_string_append_printf (rtpinfo, "url=%s/stream=%d;seq=%u;rtptime=%u",
uristr, i, seq, rtptime);
g_free (uristr);
/* construct the response now */
code = GST_RTSP_STS_OK;
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
/* add the RTP-Info header */
if (infocount > 0) {
str = g_string_free (rtpinfo, FALSE);
- gst_rtsp_message_take_header (state->response, GST_RTSP_HDR_RTP_INFO, str);
+ gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RTP_INFO, str);
} else {
g_string_free (rtpinfo, TRUE);
}
/* add the range */
str = gst_rtsp_media_get_range_string (media, TRUE, unit);
- gst_rtsp_message_take_header (state->response, GST_RTSP_HDR_RANGE, str);
+ gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RANGE, str);
- send_message (client, session, state->response, FALSE);
+ send_message (client, session, ctx->response, FALSE);
/* start playing after sending the request */
gst_rtsp_session_media_set_state (sessmedia, GST_STATE_PLAYING);
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_PLAYING);
- g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST],
- 0, state);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST], 0, ctx);
return TRUE;
no_session:
{
GST_ERROR ("client %p: no session", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
return FALSE;
}
no_uri:
{
GST_ERROR ("client %p: no uri supplied", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
not_found:
{
GST_ERROR ("client %p: media not found", client);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return FALSE;
}
no_aggregate:
{
GST_ERROR ("client %p: no aggregate path %s", client, path);
send_generic_response (client,
- GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, state);
+ GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
return FALSE;
}
invalid_state:
{
GST_ERROR ("client %p: not PLAYING or READY", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
- state);
+ ctx);
return FALSE;
}
}
static gboolean
default_configure_client_transport (GstRTSPClient * client,
- GstRTSPClientState * state, GstRTSPTransport * ct)
+ GstRTSPContext * ctx, GstRTSPTransport * ct)
{
GstRTSPClientPrivate *priv = client->priv;
if (ct->destination && use_client_settings) {
GstRTSPAddress *addr;
- addr = gst_rtsp_stream_reserve_address (state->stream, ct->destination,
+ addr = gst_rtsp_stream_reserve_address (ctx->stream, ct->destination,
ct->port.min, ct->port.max - ct->port.min + 1, ct->ttl);
if (addr == NULL)
family = priv->is_ipv6 ? G_SOCKET_FAMILY_IPV6 : G_SOCKET_FAMILY_IPV4;
- addr = gst_rtsp_stream_get_multicast_address (state->stream, family);
+ addr = gst_rtsp_stream_get_multicast_address (ctx->stream, family);
if (addr == NULL)
goto no_address;
if (ct->lower_transport & GST_RTSP_LOWER_TRANS_TCP) {
/* check if the client selected channels for TCP */
if (ct->interleaved.min == -1 || ct->interleaved.max == -1) {
- gst_rtsp_session_media_alloc_channels (state->sessmedia,
+ gst_rtsp_session_media_alloc_channels (ctx->sessmedia,
&ct->interleaved);
}
}
}
static GstRTSPTransport *
-make_server_transport (GstRTSPClient * client, GstRTSPClientState * state,
+make_server_transport (GstRTSPClient * client, GstRTSPContext * ctx,
GstRTSPTransport * ct)
{
GstRTSPTransport *st;
switch (st->lower_transport) {
case GST_RTSP_LOWER_TRANS_UDP:
st->client_port = ct->client_port;
- gst_rtsp_stream_get_server_port (state->stream, &st->server_port, family);
+ gst_rtsp_stream_get_server_port (ctx->stream, &st->server_port, family);
break;
case GST_RTSP_LOWER_TRANS_UDP_MCAST:
st->port = ct->port;
break;
}
- gst_rtsp_stream_get_ssrc (state->stream, &st->ssrc);
+ gst_rtsp_stream_get_ssrc (ctx->stream, &st->ssrc);
return st;
}
static gboolean
-handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_setup_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPClientPrivate *priv = client->priv;
GstRTSPResult res;
gchar *path, *control;
gint matched;
- if (!state->uri)
+ if (!ctx->uri)
goto no_uri;
- uri = state->uri;
+ uri = ctx->uri;
path = uri->abspath;
/* parse the transport */
res =
- gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_TRANSPORT,
+ gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_TRANSPORT,
&transport, 0);
if (res != GST_RTSP_OK)
goto no_transport;
if (priv->session_pool == NULL)
goto no_pool;
- session = state->session;
+ session = ctx->session;
if (session) {
g_object_ref (session);
/* we have no session media, find one and manage it */
if (sessmedia == NULL) {
/* get a handle to the configuration of the media in the session */
- media = find_media (client, state, &matched);
+ media = find_media (client, ctx, &matched);
} else {
if ((media = gst_rtsp_session_media_get_media (sessmedia)))
g_object_ref (media);
goto stream_not_found;
/* now we have a uri identifying a valid media and stream */
- state->stream = stream;
- state->media = media;
+ ctx->stream = stream;
+ ctx->media = media;
if (session == NULL) {
/* create a session if this fails we probably reached our session limit or
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_NEW_SESSION], 0,
session);
- state->session = session;
+ ctx->session = session;
}
if (sessmedia == NULL) {
g_object_unref (media);
}
- state->sessmedia = sessmedia;
+ ctx->sessmedia = sessmedia;
/* set blocksize on this stream */
- if (!handle_blocksize (media, stream, state->request))
+ if (!handle_blocksize (media, stream, ctx->request))
goto invalid_blocksize;
gst_rtsp_transport_new (&ct);
/* update the client transport */
klass = GST_RTSP_CLIENT_GET_CLASS (client);
- if (!klass->configure_client_transport (client, state, ct))
+ if (!klass->configure_client_transport (client, ctx, ct))
goto unsupported_client_transport;
/* set in the session media transport */
(GstRTSPKeepAliveFunc) do_keepalive, session, NULL);
/* create and serialize the server transport */
- st = make_server_transport (client, state, ct);
+ st = make_server_transport (client, ctx, ct);
trans_str = gst_rtsp_transport_as_text (st);
gst_rtsp_transport_free (st);
/* construct the response now */
code = GST_RTSP_STS_OK;
- gst_rtsp_message_init_response (state->response, code,
- gst_rtsp_status_as_text (code), state->request);
+ gst_rtsp_message_init_response (ctx->response, code,
+ gst_rtsp_status_as_text (code), ctx->request);
- gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_TRANSPORT,
+ gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_TRANSPORT,
trans_str);
g_free (trans_str);
- send_message (client, session, state->response, FALSE);
+ send_message (client, session, ctx->response, FALSE);
/* update the state */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
}
g_object_unref (session);
- g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_SETUP_REQUEST],
- 0, state);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_SETUP_REQUEST], 0, ctx);
return TRUE;
no_uri:
{
GST_ERROR ("client %p: no uri", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
no_transport:
{
GST_ERROR ("client %p: no transport", client);
- send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, state);
+ send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx);
return FALSE;
}
no_pool:
{
GST_ERROR ("client %p: no session pool configured", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
return FALSE;
}
media_not_found:
{
GST_ERROR ("client %p: media '%s' not found", client, path);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
return FALSE;
}
stream_not_found:
{
GST_ERROR ("client %p: stream '%s' not found", client, control);
- send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_FOUND, ctx);
g_object_unref (media);
return FALSE;
}
service_unavailable:
{
GST_ERROR ("client %p: can't create session", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (media);
return FALSE;
}
sessmedia_unavailable:
{
GST_ERROR ("client %p: can't create session media", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (media);
g_object_unref (session);
return FALSE;
invalid_blocksize:
{
GST_ERROR ("client %p: invalid blocksize", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
g_object_unref (session);
return FALSE;
}
unsupported_transports:
{
GST_ERROR ("client %p: unsupported transports", client);
- send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, state);
+ send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx);
gst_rtsp_transport_free (ct);
g_object_unref (session);
return FALSE;
unsupported_client_transport:
{
GST_ERROR ("client %p: unsupported client transport", client);
- send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, state);
+ send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx);
gst_rtsp_transport_free (ct);
g_object_unref (session);
return FALSE;
/* for the describe we must generate an SDP */
static gboolean
-handle_describe_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_describe_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPResult res;
GstSDPMessage *sdp;
klass = GST_RTSP_CLIENT_GET_CLASS (client);
- if (!state->uri)
+ if (!ctx->uri)
goto no_uri;
/* check what kind of format is accepted, we don't really do anything with it
gchar *accept;
res =
- gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_ACCEPT,
+ gst_rtsp_message_get_header (ctx->request, GST_RTSP_HDR_ACCEPT,
&accept, i);
if (res == GST_RTSP_ENOTIMPL)
break;
}
/* find the media object for the uri */
- if (!(media = find_media (client, state, NULL)))
+ if (!(media = find_media (client, ctx, NULL)))
goto no_media;
/* create an SDP for the media object on this client */
g_object_unref (media);
- gst_rtsp_message_init_response (state->response, GST_RTSP_STS_OK,
- gst_rtsp_status_as_text (GST_RTSP_STS_OK), state->request);
+ gst_rtsp_message_init_response (ctx->response, GST_RTSP_STS_OK,
+ gst_rtsp_status_as_text (GST_RTSP_STS_OK), ctx->request);
- gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONTENT_TYPE,
+ gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_CONTENT_TYPE,
"application/sdp");
/* content base for some clients that might screw up creating the setup uri */
- str = gst_rtsp_url_get_request_uri (state->uri);
+ str = gst_rtsp_url_get_request_uri (ctx->uri);
str_len = strlen (str);
/* check for trailing '/' and append one */
GST_INFO ("adding content-base: %s", content_base);
- gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONTENT_BASE,
+ gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_CONTENT_BASE,
content_base);
g_free (content_base);
/* add SDP to the response body */
str = gst_sdp_message_as_text (sdp);
- gst_rtsp_message_take_body (state->response, (guint8 *) str, strlen (str));
+ gst_rtsp_message_take_body (ctx->response, (guint8 *) str, strlen (str));
gst_sdp_message_free (sdp);
- send_message (client, state->session, state->response, FALSE);
+ send_message (client, ctx->session, ctx->response, FALSE);
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_DESCRIBE_REQUEST],
- 0, state);
+ 0, ctx);
return TRUE;
no_uri:
{
GST_ERROR ("client %p: no uri", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
return FALSE;
}
no_media:
no_sdp:
{
GST_ERROR ("client %p: can't create SDP", client);
- send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
+ send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
g_object_unref (media);
return FALSE;
}
}
static gboolean
-handle_options_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_options_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
GstRTSPMethod options;
gchar *str;
str = gst_rtsp_options_as_text (options);
- gst_rtsp_message_init_response (state->response, GST_RTSP_STS_OK,
- gst_rtsp_status_as_text (GST_RTSP_STS_OK), state->request);
+ gst_rtsp_message_init_response (ctx->response, GST_RTSP_STS_OK,
+ gst_rtsp_status_as_text (GST_RTSP_STS_OK), ctx->request);
- gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_PUBLIC, str);
+ gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_PUBLIC, str);
g_free (str);
- send_message (client, state->session, state->response, FALSE);
+ send_message (client, ctx->session, ctx->response, FALSE);
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_OPTIONS_REQUEST],
- 0, state);
+ 0, ctx);
return TRUE;
}
}
}
-static GPrivate current_state;
-
-/**
- * gst_rtsp_client_state_get_current:
- *
- * Get the current #GstRTSPClientState. This object is retrieved from the
- * current thread that is handling the request for a client.
- *
- * Returns: a #GstRTSPClientState
- */
-GstRTSPClientState *
-gst_rtsp_client_state_get_current (void)
-{
- GSList *l;
-
- l = g_private_get (¤t_state);
- if (l == NULL)
- return NULL;
-
- return (GstRTSPClientState *) (l->data);
-
-}
-
-/**
- * gst_rtsp_client_state_push_current:
- * @state: a ##GstRTSPClientState
- *
- * Pushes @state onto the state stack. The current
- * state can then be received using gst_rtsp_client_state_get_current().
- **/
-void
-gst_rtsp_client_state_push_current (GstRTSPClientState * state)
-{
- GSList *l;
-
- g_return_if_fail (state != NULL);
-
- l = g_private_get (¤t_state);
- l = g_slist_prepend (l, state);
- g_private_set (¤t_state, l);
-}
-
-/**
- * gst_rtsp_client_state_pop_current:
- * @state: a #GstRTSPClientState
- *
- * Pops @state off the state stack (verifying that @state
- * is on the top of the stack).
- **/
-void
-gst_rtsp_client_state_pop_current (GstRTSPClientState * state)
-{
- GSList *l;
-
- l = g_private_get (¤t_state);
-
- g_return_if_fail (l != NULL);
- g_return_if_fail (l->data == state);
-
- l = g_slist_delete_link (l, l);
- g_private_set (¤t_state, l);
-}
-
static void
handle_request (GstRTSPClient * client, GstRTSPMessage * request)
{
GstRTSPVersion version;
GstRTSPResult res;
GstRTSPSession *session = NULL;
- GstRTSPClientState sstate = { NULL }, *state;
+ GstRTSPContext sctx = { NULL }, *ctx;
GstRTSPMessage response = { 0 };
gchar *sessid;
- if (!(state = gst_rtsp_client_state_get_current ())) {
- state = &sstate;
- state->auth = priv->auth;
- gst_rtsp_client_state_push_current (state);
+ if (!(ctx = gst_rtsp_context_get_current ())) {
+ ctx = &sctx;
+ ctx->auth = priv->auth;
+ gst_rtsp_context_push_current (ctx);
}
- state->conn = priv->connection;
- state->client = client;
- state->request = request;
- state->response = &response;
+ ctx->conn = priv->connection;
+ ctx->client = client;
+ ctx->request = request;
+ ctx->response = &response;
if (gst_debug_category_get_threshold (rtsp_client_debug) >= GST_LEVEL_LOG) {
gst_rtsp_message_dump (request);
if (version != GST_RTSP_VERSION_1_0)
goto not_supported;
- state->method = method;
+ ctx->method = method;
/* we always try to parse the url first */
if (strcmp (uristr, "*") == 0) {
/* sanitize the uri */
if (uri)
sanitize_uri (uri);
- state->uri = uri;
- state->session = session;
+ ctx->uri = uri;
+ ctx->session = session;
if (!gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_URL))
goto not_authorized;
/* now see what is asked and dispatch to a dedicated handler */
switch (method) {
case GST_RTSP_OPTIONS:
- handle_options_request (client, state);
+ handle_options_request (client, ctx);
break;
case GST_RTSP_DESCRIBE:
- handle_describe_request (client, state);
+ handle_describe_request (client, ctx);
break;
case GST_RTSP_SETUP:
- handle_setup_request (client, state);
+ handle_setup_request (client, ctx);
break;
case GST_RTSP_PLAY:
- handle_play_request (client, state);
+ handle_play_request (client, ctx);
break;
case GST_RTSP_PAUSE:
- handle_pause_request (client, state);
+ handle_pause_request (client, ctx);
break;
case GST_RTSP_TEARDOWN:
- handle_teardown_request (client, state);
+ handle_teardown_request (client, ctx);
break;
case GST_RTSP_SET_PARAMETER:
- handle_set_param_request (client, state);
+ handle_set_param_request (client, ctx);
break;
case GST_RTSP_GET_PARAMETER:
- handle_get_param_request (client, state);
+ handle_get_param_request (client, ctx);
break;
case GST_RTSP_ANNOUNCE:
case GST_RTSP_RECORD:
}
done:
- if (state == &sstate)
- gst_rtsp_client_state_pop_current (state);
+ if (ctx == &sctx)
+ gst_rtsp_context_pop_current (ctx);
if (session)
g_object_unref (session);
if (uri)
{
GST_ERROR ("client %p: version %d not supported", client, version);
send_generic_response (client, GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
- state);
+ ctx);
goto done;
}
bad_request:
{
GST_ERROR ("client %p: bad request", client);
- send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+ send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
goto done;
}
no_pool:
{
GST_ERROR ("client %p: no pool configured", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
goto done;
}
session_not_found:
{
GST_ERROR ("client %p: session not found", client);
- send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
+ send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, ctx);
goto done;
}
not_authorized:
not_implemented:
{
GST_ERROR ("client %p: method %d not implemented", client, method);
- send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, state);
+ send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, ctx);
goto done;
}
}