mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
gst/rtsp/: Fix for new API.
Original commit message from CVS: Patch by: Peter Kjellerstedt <pkj at axis com> * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_setup_auth), (gst_rtspsrc_try_send), (gst_rtspsrc_parse_methods), (gst_rtspsrc_setup_streams), (gst_rtspsrc_open), (gst_rtspsrc_play): (rtsp_connection_send), (rtsp_connection_receive): * gst/rtsp/rtspextwms.c: (rtsp_ext_wms_after_send): Fix for new API. * gst/rtsp/rtspconnection.c: (add_auth_header), Only add authorisation and session headers when sending messages. * gst/rtsp/rtspmessage.c: (key_value_foreach), (rtsp_message_init), (rtsp_message_init_request), (rtsp_message_init_response), (rtsp_message_unset), (rtsp_message_add_header), (rtsp_message_remove_header), (rtsp_message_get_header), (rtsp_message_append_headers), (dump_key_value), (rtsp_message_dump): * gst/rtsp/rtspmessage.h: Add support for multiple headers of the same type by storing the parsed headers in a GArray instaed of a hashtable.
This commit is contained in:
parent
877b1be83a
commit
77cc870bbc
6 changed files with 192 additions and 113 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
||||||
|
2007-05-24 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
Patch by: Peter Kjellerstedt <pkj at axis com>
|
||||||
|
|
||||||
|
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_setup_auth),
|
||||||
|
(gst_rtspsrc_try_send), (gst_rtspsrc_parse_methods),
|
||||||
|
(gst_rtspsrc_setup_streams), (gst_rtspsrc_open),
|
||||||
|
(gst_rtspsrc_play):
|
||||||
|
(rtsp_connection_send), (rtsp_connection_receive):
|
||||||
|
* gst/rtsp/rtspextwms.c: (rtsp_ext_wms_after_send):
|
||||||
|
Fix for new API.
|
||||||
|
|
||||||
|
* gst/rtsp/rtspconnection.c: (add_auth_header),
|
||||||
|
Only add authorisation and session headers when sending messages.
|
||||||
|
|
||||||
|
* gst/rtsp/rtspmessage.c: (key_value_foreach), (rtsp_message_init),
|
||||||
|
(rtsp_message_init_request), (rtsp_message_init_response),
|
||||||
|
(rtsp_message_unset), (rtsp_message_add_header),
|
||||||
|
(rtsp_message_remove_header), (rtsp_message_get_header),
|
||||||
|
(rtsp_message_append_headers), (dump_key_value),
|
||||||
|
(rtsp_message_dump):
|
||||||
|
* gst/rtsp/rtspmessage.h:
|
||||||
|
Add support for multiple headers of the same type by storing the parsed
|
||||||
|
headers in a GArray instaed of a hashtable.
|
||||||
|
|
||||||
2007-05-21 Wim Taymans <wim@fluendo.com>
|
2007-05-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/udp/gstudpsrc.c: (gst_udpsrc_class_init),
|
* gst/udp/gstudpsrc.c: (gst_udpsrc_class_init),
|
||||||
|
|
|
@ -2640,7 +2640,7 @@ gst_rtspsrc_setup_auth (GstRTSPSrc * src, RTSPMessage * response)
|
||||||
gchar *hdr;
|
gchar *hdr;
|
||||||
|
|
||||||
/* Identify the available auth methods and see if any are supported */
|
/* Identify the available auth methods and see if any are supported */
|
||||||
if (rtsp_message_get_header (response, RTSP_HDR_WWW_AUTHENTICATE, &hdr) ==
|
if (rtsp_message_get_header (response, RTSP_HDR_WWW_AUTHENTICATE, &hdr, 0) ==
|
||||||
RTSP_OK) {
|
RTSP_OK) {
|
||||||
gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods);
|
gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods);
|
||||||
}
|
}
|
||||||
|
@ -2772,7 +2772,7 @@ next:
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
|
|
||||||
/* store new content base if any */
|
/* store new content base if any */
|
||||||
rtsp_message_get_header (response, RTSP_HDR_CONTENT_BASE, &content_base);
|
rtsp_message_get_header (response, RTSP_HDR_CONTENT_BASE, &content_base, 0);
|
||||||
g_free (src->content_base);
|
g_free (src->content_base);
|
||||||
src->content_base = g_strdup (content_base);
|
src->content_base = g_strdup (content_base);
|
||||||
|
|
||||||
|
@ -2905,53 +2905,63 @@ error_response:
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response)
|
gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response)
|
||||||
{
|
{
|
||||||
|
RTSPHeaderField field;
|
||||||
gchar *respoptions = NULL;
|
gchar *respoptions = NULL;
|
||||||
gchar **options;
|
gchar **options;
|
||||||
|
gint indx = 0;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
/* clear supported methods */
|
/* clear supported methods */
|
||||||
src->methods = 0;
|
src->methods = 0;
|
||||||
|
|
||||||
/* Try Allow Header first */
|
/* try the Allow header first */
|
||||||
rtsp_message_get_header (response, RTSP_HDR_ALLOW, &respoptions);
|
field = RTSP_HDR_ALLOW;
|
||||||
if (!respoptions)
|
while (TRUE) {
|
||||||
/* Then maybe Public Header... */
|
rtsp_message_get_header (response, field, &respoptions, indx);
|
||||||
rtsp_message_get_header (response, RTSP_HDR_PUBLIC, &respoptions);
|
if (indx == 0 && !respoptions) {
|
||||||
if (!respoptions) {
|
/* if no Allow header was found then try the Public header... */
|
||||||
/* this field is not required, assume the server supports
|
field = RTSP_HDR_PUBLIC;
|
||||||
* DESCRIBE, SETUP and PLAY */
|
rtsp_message_get_header (response, field, &respoptions, indx);
|
||||||
|
}
|
||||||
|
if (!respoptions)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If we get here, the server gave a list of supported methods, parse
|
||||||
|
* them here. The string is like:
|
||||||
|
*
|
||||||
|
* OPTIONS, DESCRIBE, ANNOUNCE, PLAY, SETUP, ...
|
||||||
|
*/
|
||||||
|
options = g_strsplit (respoptions, ",", 0);
|
||||||
|
|
||||||
|
for (i = 0; options[i]; i++) {
|
||||||
|
gchar *stripped;
|
||||||
|
gint method;
|
||||||
|
|
||||||
|
stripped = g_strstrip (options[i]);
|
||||||
|
method = rtsp_find_method (stripped);
|
||||||
|
|
||||||
|
/* keep bitfield of supported methods */
|
||||||
|
if (method != RTSP_INVALID)
|
||||||
|
src->methods |= method;
|
||||||
|
}
|
||||||
|
g_strfreev (options);
|
||||||
|
|
||||||
|
indx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->methods == 0) {
|
||||||
|
/* neither Allow nor Public are required, assume the server supports
|
||||||
|
* DESCRIBE, SETUP, PLAY and PAUSE */
|
||||||
GST_DEBUG_OBJECT (src, "could not get OPTIONS");
|
GST_DEBUG_OBJECT (src, "could not get OPTIONS");
|
||||||
src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY | RTSP_PAUSE;
|
src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY | RTSP_PAUSE;
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, the server gave a list of supported methods, parse
|
|
||||||
* them here. The string is like:
|
|
||||||
*
|
|
||||||
* OPTIONS, DESCRIBE, ANNOUNCE, PLAY, SETUP, ...
|
|
||||||
*/
|
|
||||||
options = g_strsplit (respoptions, ",", 0);
|
|
||||||
|
|
||||||
for (i = 0; options[i]; i++) {
|
|
||||||
gchar *stripped;
|
|
||||||
gint method;
|
|
||||||
|
|
||||||
stripped = g_strstrip (options[i]);
|
|
||||||
method = rtsp_find_method (stripped);
|
|
||||||
|
|
||||||
/* keep bitfield of supported methods */
|
|
||||||
if (method != RTSP_INVALID)
|
|
||||||
src->methods |= method;
|
|
||||||
}
|
|
||||||
g_strfreev (options);
|
|
||||||
|
|
||||||
/* we need describe and setup */
|
/* we need describe and setup */
|
||||||
if (!(src->methods & RTSP_DESCRIBE))
|
if (!(src->methods & RTSP_DESCRIBE))
|
||||||
goto no_describe;
|
goto no_describe;
|
||||||
if (!(src->methods & RTSP_SETUP))
|
if (!(src->methods & RTSP_SETUP))
|
||||||
goto no_setup;
|
goto no_setup;
|
||||||
|
|
||||||
done:
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -3219,7 +3229,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
|
||||||
gchar *resptrans = NULL;
|
gchar *resptrans = NULL;
|
||||||
RTSPTransport transport = { 0 };
|
RTSPTransport transport = { 0 };
|
||||||
|
|
||||||
rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
|
rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans, 0);
|
||||||
if (!resptrans)
|
if (!resptrans)
|
||||||
goto no_transport;
|
goto no_transport;
|
||||||
|
|
||||||
|
@ -3425,7 +3435,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||||
goto send_error;
|
goto send_error;
|
||||||
|
|
||||||
/* check if reply is SDP */
|
/* check if reply is SDP */
|
||||||
rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont);
|
rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont, 0);
|
||||||
/* could not be set but since the request returned OK, we assume it
|
/* could not be set but since the request returned OK, we assume it
|
||||||
* was SDP, else check it. */
|
* was SDP, else check it. */
|
||||||
if (respcont) {
|
if (respcont) {
|
||||||
|
@ -3756,14 +3766,14 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
||||||
|
|
||||||
/* parse RTP npt field. This is the current position in the stream (Normal
|
/* parse RTP npt field. This is the current position in the stream (Normal
|
||||||
* Play Time) and should be put in the NEWSEGMENT position field. */
|
* Play Time) and should be put in the NEWSEGMENT position field. */
|
||||||
if (rtsp_message_get_header (&response, RTSP_HDR_RANGE, &range) == RTSP_OK)
|
if (rtsp_message_get_header (&response, RTSP_HDR_RANGE, &range, 0) == RTSP_OK)
|
||||||
gst_rtspsrc_parse_range (src, range);
|
gst_rtspsrc_parse_range (src, range);
|
||||||
|
|
||||||
/* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp
|
/* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp
|
||||||
* for the RTP packets. If this is not present, we assume all starts from 0...
|
* for the RTP packets. If this is not present, we assume all starts from 0...
|
||||||
* This is info for the RTP session manager that we pass to it in caps. */
|
* This is info for the RTP session manager that we pass to it in caps. */
|
||||||
if (rtsp_message_get_header (&response, RTSP_HDR_RTP_INFO,
|
if (rtsp_message_get_header (&response, RTSP_HDR_RTP_INFO,
|
||||||
&rtpinfo) == RTSP_OK)
|
&rtpinfo, 0) == RTSP_OK)
|
||||||
gst_rtspsrc_parse_rtpinfo (src, rtpinfo);
|
gst_rtspsrc_parse_rtpinfo (src, rtpinfo);
|
||||||
|
|
||||||
rtsp_message_unset (&response);
|
rtsp_message_unset (&response);
|
||||||
|
|
|
@ -273,15 +273,7 @@ timeout:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_header (gint key, gchar * value, GString * str)
|
add_auth_header (RTSPConnection * conn, RTSPMessage * message)
|
||||||
{
|
|
||||||
const gchar *keystr = rtsp_header_as_text (key);
|
|
||||||
|
|
||||||
g_string_append_printf (str, "%s: %s\r\n", keystr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
append_auth_header (RTSPConnection * conn, RTSPMessage * message, GString * str)
|
|
||||||
{
|
{
|
||||||
switch (conn->auth_method) {
|
switch (conn->auth_method) {
|
||||||
case RTSP_AUTH_BASIC:{
|
case RTSP_AUTH_BASIC:{
|
||||||
|
@ -290,7 +282,7 @@ append_auth_header (RTSPConnection * conn, RTSPMessage * message, GString * str)
|
||||||
gchar *user_pass64 = util_base64_encode (user_pass, strlen (user_pass));
|
gchar *user_pass64 = util_base64_encode (user_pass, strlen (user_pass));
|
||||||
gchar *auth_string = g_strdup_printf ("Basic %s", user_pass64);
|
gchar *auth_string = g_strdup_printf ("Basic %s", user_pass64);
|
||||||
|
|
||||||
append_header (RTSP_HDR_AUTHORIZATION, auth_string, str);
|
rtsp_message_add_header (message, RTSP_HDR_AUTHORIZATION, auth_string);
|
||||||
|
|
||||||
g_free (user_pass);
|
g_free (user_pass);
|
||||||
g_free (user_pass64);
|
g_free (user_pass64);
|
||||||
|
@ -427,6 +419,12 @@ rtsp_connection_send (RTSPConnection * conn, RTSPMessage * message,
|
||||||
"CSeq: %d\r\n",
|
"CSeq: %d\r\n",
|
||||||
rtsp_method_as_text (message->type_data.request.method),
|
rtsp_method_as_text (message->type_data.request.method),
|
||||||
message->type_data.request.uri, conn->cseq++);
|
message->type_data.request.uri, conn->cseq++);
|
||||||
|
/* add session id if we have one */
|
||||||
|
if (conn->session_id[0] != '\0') {
|
||||||
|
rtsp_message_add_header (message, RTSP_HDR_SESSION, conn->session_id);
|
||||||
|
}
|
||||||
|
/* add any authentication headers */
|
||||||
|
add_auth_header (conn, message);
|
||||||
break;
|
break;
|
||||||
case RTSP_MESSAGE_RESPONSE:
|
case RTSP_MESSAGE_RESPONSE:
|
||||||
/* create response string */
|
/* create response string */
|
||||||
|
@ -455,39 +453,28 @@ rtsp_connection_send (RTSPConnection * conn, RTSPMessage * message,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append specific headers and body */
|
/* append headers and body */
|
||||||
switch (message->type) {
|
if (message->type != RTSP_MESSAGE_DATA) {
|
||||||
case RTSP_MESSAGE_REQUEST:
|
/* append headers */
|
||||||
case RTSP_MESSAGE_RESPONSE:
|
rtsp_message_append_headers (message, str);
|
||||||
/* append session id if we have one */
|
|
||||||
if (conn->session_id[0] != '\0') {
|
|
||||||
append_header (RTSP_HDR_SESSION, conn->session_id, str);
|
|
||||||
}
|
|
||||||
/* append headers */
|
|
||||||
g_hash_table_foreach (message->hdr_fields, (GHFunc) append_header, str);
|
|
||||||
|
|
||||||
/* Append any authentication headers */
|
/* append Content-Length and body if needed */
|
||||||
append_auth_header (conn, message, str);
|
if (message->body != NULL && message->body_size > 0) {
|
||||||
|
gchar *len;
|
||||||
|
|
||||||
/* append Content-Length and body if needed */
|
len = g_strdup_printf ("%d", message->body_size);
|
||||||
if (message->body != NULL && message->body_size > 0) {
|
g_string_append_printf (str, "%s: %s\r\n",
|
||||||
gchar *len;
|
rtsp_header_as_text (RTSP_HDR_CONTENT_LENGTH), len);
|
||||||
|
g_free (len);
|
||||||
len = g_strdup_printf ("%d", message->body_size);
|
/* header ends here */
|
||||||
append_header (RTSP_HDR_CONTENT_LENGTH, len, str);
|
g_string_append (str, "\r\n");
|
||||||
g_free (len);
|
str =
|
||||||
/* header ends here */
|
g_string_append_len (str, (gchar *) message->body,
|
||||||
g_string_append (str, "\r\n");
|
message->body_size);
|
||||||
str =
|
} else {
|
||||||
g_string_append_len (str, (gchar *) message->body,
|
/* just end headers */
|
||||||
message->body_size);
|
g_string_append (str, "\r\n");
|
||||||
} else {
|
}
|
||||||
/* just end headers */
|
|
||||||
g_string_append (str, "\r\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write request */
|
/* write request */
|
||||||
|
@ -914,7 +901,7 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg,
|
||||||
if (need_body) {
|
if (need_body) {
|
||||||
/* see if there is a Content-Length header */
|
/* see if there is a Content-Length header */
|
||||||
if (rtsp_message_get_header (msg, RTSP_HDR_CONTENT_LENGTH,
|
if (rtsp_message_get_header (msg, RTSP_HDR_CONTENT_LENGTH,
|
||||||
&hdrval) == RTSP_OK) {
|
&hdrval, 0) == RTSP_OK) {
|
||||||
/* there is, read the body */
|
/* there is, read the body */
|
||||||
content_length = atol (hdrval);
|
content_length = atol (hdrval);
|
||||||
RTSP_CHECK (read_body (conn, content_length, msg, timeout), read_error);
|
RTSP_CHECK (read_body (conn, content_length, msg, timeout), read_error);
|
||||||
|
@ -925,7 +912,7 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg,
|
||||||
gchar *session_id;
|
gchar *session_id;
|
||||||
|
|
||||||
if (rtsp_message_get_header (msg, RTSP_HDR_SESSION,
|
if (rtsp_message_get_header (msg, RTSP_HDR_SESSION,
|
||||||
&session_id) == RTSP_OK) {
|
&session_id, 0) == RTSP_OK) {
|
||||||
gint sesslen, maxlen, i;
|
gint sesslen, maxlen, i;
|
||||||
|
|
||||||
/* default session timeout */
|
/* default session timeout */
|
||||||
|
|
|
@ -86,7 +86,7 @@ rtsp_ext_wms_after_send (RTSPExtensionCtx * ctx, RTSPMessage * req,
|
||||||
{
|
{
|
||||||
gchar *server = NULL;
|
gchar *server = NULL;
|
||||||
|
|
||||||
rtsp_message_get_header (resp, RTSP_HDR_SERVER, &server);
|
rtsp_message_get_header (resp, RTSP_HDR_SERVER, &server, 0);
|
||||||
if (server && g_str_has_prefix (server, SERVER_PREFIX))
|
if (server && g_str_has_prefix (server, SERVER_PREFIX))
|
||||||
rext->active = TRUE;
|
rext->active = TRUE;
|
||||||
else
|
else
|
||||||
|
|
|
@ -45,6 +45,24 @@
|
||||||
|
|
||||||
#include "rtspmessage.h"
|
#include "rtspmessage.h"
|
||||||
|
|
||||||
|
typedef struct _RTSPKeyValue
|
||||||
|
{
|
||||||
|
RTSPHeaderField field;
|
||||||
|
gchar *value;
|
||||||
|
} RTSPKeyValue;
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_value_foreach (GArray * array, GFunc func, gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_return_if_fail (array != NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < array->len; i++) {
|
||||||
|
(*func) (&g_array_index (array, RTSPKeyValue, i), user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
rtsp_message_new (RTSPMessage ** msg)
|
rtsp_message_new (RTSPMessage ** msg)
|
||||||
{
|
{
|
||||||
|
@ -67,8 +85,7 @@ rtsp_message_init (RTSPMessage * msg)
|
||||||
rtsp_message_unset (msg);
|
rtsp_message_unset (msg);
|
||||||
|
|
||||||
msg->type = RTSP_MESSAGE_INVALID;
|
msg->type = RTSP_MESSAGE_INVALID;
|
||||||
msg->hdr_fields =
|
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
|
||||||
|
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
}
|
}
|
||||||
|
@ -101,8 +118,7 @@ rtsp_message_init_request (RTSPMessage * msg, RTSPMethod method,
|
||||||
msg->type = RTSP_MESSAGE_REQUEST;
|
msg->type = RTSP_MESSAGE_REQUEST;
|
||||||
msg->type_data.request.method = method;
|
msg->type_data.request.method = method;
|
||||||
msg->type_data.request.uri = g_strdup (uri);
|
msg->type_data.request.uri = g_strdup (uri);
|
||||||
msg->hdr_fields =
|
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
|
||||||
|
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
}
|
}
|
||||||
|
@ -136,19 +152,19 @@ rtsp_message_init_response (RTSPMessage * msg, RTSPStatusCode code,
|
||||||
msg->type = RTSP_MESSAGE_RESPONSE;
|
msg->type = RTSP_MESSAGE_RESPONSE;
|
||||||
msg->type_data.response.code = code;
|
msg->type_data.response.code = code;
|
||||||
msg->type_data.response.reason = g_strdup (reason);
|
msg->type_data.response.reason = g_strdup (reason);
|
||||||
msg->hdr_fields =
|
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
gchar *header;
|
gchar *header;
|
||||||
|
|
||||||
/* copy CSEQ */
|
/* copy CSEQ */
|
||||||
if (rtsp_message_get_header (request, RTSP_HDR_CSEQ, &header) == RTSP_OK) {
|
if (rtsp_message_get_header (request, RTSP_HDR_CSEQ, &header, 0) == RTSP_OK) {
|
||||||
rtsp_message_add_header (msg, RTSP_HDR_CSEQ, header);
|
rtsp_message_add_header (msg, RTSP_HDR_CSEQ, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy session id */
|
/* copy session id */
|
||||||
if (rtsp_message_get_header (request, RTSP_HDR_SESSION, &header) == RTSP_OK) {
|
if (rtsp_message_get_header (request, RTSP_HDR_SESSION, &header,
|
||||||
|
0) == RTSP_OK) {
|
||||||
char *pos;
|
char *pos;
|
||||||
|
|
||||||
header = g_strdup (header);
|
header = g_strdup (header);
|
||||||
|
@ -201,7 +217,7 @@ rtsp_message_unset (RTSPMessage * msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->hdr_fields != NULL)
|
if (msg->hdr_fields != NULL)
|
||||||
g_hash_table_destroy (msg->hdr_fields);
|
g_array_free (msg->hdr_fields, TRUE);
|
||||||
|
|
||||||
g_free (msg->body);
|
g_free (msg->body);
|
||||||
|
|
||||||
|
@ -228,44 +244,80 @@ RTSPResult
|
||||||
rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
|
rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||||
const gchar * value)
|
const gchar * value)
|
||||||
{
|
{
|
||||||
|
RTSPKeyValue key_value;
|
||||||
|
|
||||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||||
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
|
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
|
||||||
|
|
||||||
g_hash_table_insert (msg->hdr_fields, GINT_TO_POINTER (field),
|
key_value.field = field;
|
||||||
g_strdup (value));
|
key_value.value = g_strdup (value);
|
||||||
|
|
||||||
|
g_array_append_val (msg->hdr_fields, key_value);
|
||||||
|
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
rtsp_message_remove_header (RTSPMessage * msg, RTSPHeaderField field)
|
rtsp_message_remove_header (RTSPMessage * msg, RTSPHeaderField field, gint indx)
|
||||||
{
|
{
|
||||||
|
RTSPResult res = RTSP_ENOTIMPL;
|
||||||
|
guint i = 0;
|
||||||
|
gint cnt = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||||
|
|
||||||
g_hash_table_remove (msg->hdr_fields, GINT_TO_POINTER (field));
|
while (i < msg->hdr_fields->len) {
|
||||||
|
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||||
|
|
||||||
return RTSP_ENOTIMPL;
|
if (key_value.field == field && (indx == -1 || cnt++ == indx)) {
|
||||||
|
g_array_remove_index (msg->hdr_fields, i);
|
||||||
|
res = RTSP_OK;
|
||||||
|
if (indx != -1)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
rtsp_message_get_header (const RTSPMessage * msg, RTSPHeaderField field,
|
rtsp_message_get_header (const RTSPMessage * msg, RTSPHeaderField field,
|
||||||
gchar ** value)
|
gchar ** value, gint indx)
|
||||||
{
|
{
|
||||||
gchar *val;
|
guint i;
|
||||||
|
gint cnt = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||||
|
|
||||||
if (msg->type == RTSP_MESSAGE_INVALID || msg->type == RTSP_MESSAGE_DATA)
|
for (i = 0; i < msg->hdr_fields->len; i++) {
|
||||||
return RTSP_ENOTIMPL;
|
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||||
|
|
||||||
val = g_hash_table_lookup (msg->hdr_fields, GINT_TO_POINTER (field));
|
if (key_value.field == field && cnt++ == indx) {
|
||||||
if (val == NULL)
|
if (value)
|
||||||
return RTSP_ENOTIMPL;
|
*value = key_value.value;
|
||||||
|
return RTSP_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (value)
|
return RTSP_ENOTIMPL;
|
||||||
*value = val;
|
}
|
||||||
|
|
||||||
return RTSP_OK;
|
void
|
||||||
|
rtsp_message_append_headers (const RTSPMessage * msg, GString * str)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_return_if_fail (msg != NULL);
|
||||||
|
g_return_if_fail (str != NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < msg->hdr_fields->len; i++) {
|
||||||
|
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||||
|
const gchar *keystr = rtsp_header_as_text (key_value.field);
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
|
@ -352,12 +404,12 @@ dump_mem (guint8 * mem, guint size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_key_value (gpointer key, gpointer value, gpointer data)
|
dump_key_value (gpointer data, gpointer user_data)
|
||||||
{
|
{
|
||||||
RTSPHeaderField field = GPOINTER_TO_INT (key);
|
RTSPKeyValue *key_value = (RTSPKeyValue *) data;
|
||||||
|
|
||||||
g_print (" key: '%s', value: '%s'\n", rtsp_header_as_text (field),
|
g_print (" key: '%s', value: '%s'\n",
|
||||||
(gchar *) value);
|
rtsp_header_as_text (key_value->field), key_value->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
|
@ -376,7 +428,7 @@ rtsp_message_dump (RTSPMessage * msg)
|
||||||
rtsp_method_as_text (msg->type_data.request.method));
|
rtsp_method_as_text (msg->type_data.request.method));
|
||||||
g_print (" uri: '%s'\n", msg->type_data.request.uri);
|
g_print (" uri: '%s'\n", msg->type_data.request.uri);
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
g_hash_table_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
g_print (" body:\n");
|
g_print (" body:\n");
|
||||||
rtsp_message_get_body (msg, &data, &size);
|
rtsp_message_get_body (msg, &data, &size);
|
||||||
dump_mem (data, size);
|
dump_mem (data, size);
|
||||||
|
@ -387,7 +439,7 @@ rtsp_message_dump (RTSPMessage * msg)
|
||||||
g_print (" code: '%d'\n", msg->type_data.response.code);
|
g_print (" code: '%d'\n", msg->type_data.response.code);
|
||||||
g_print (" reason: '%s'\n", msg->type_data.response.reason);
|
g_print (" reason: '%s'\n", msg->type_data.response.reason);
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
g_hash_table_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
rtsp_message_get_body (msg, &data, &size);
|
rtsp_message_get_body (msg, &data, &size);
|
||||||
g_print (" body: length %d\n", size);
|
g_print (" body: length %d\n", size);
|
||||||
dump_mem (data, size);
|
dump_mem (data, size);
|
||||||
|
|
|
@ -75,7 +75,7 @@ typedef struct _RTSPMessage
|
||||||
} data;
|
} data;
|
||||||
} type_data;
|
} type_data;
|
||||||
|
|
||||||
GHashTable *hdr_fields;
|
GArray *hdr_fields;
|
||||||
|
|
||||||
guint8 *body;
|
guint8 *body;
|
||||||
guint body_size;
|
guint body_size;
|
||||||
|
@ -112,10 +112,15 @@ RTSPResult rtsp_message_add_header (RTSPMessage *msg,
|
||||||
RTSPHeaderField field,
|
RTSPHeaderField field,
|
||||||
const gchar *value);
|
const gchar *value);
|
||||||
RTSPResult rtsp_message_remove_header (RTSPMessage *msg,
|
RTSPResult rtsp_message_remove_header (RTSPMessage *msg,
|
||||||
RTSPHeaderField field);
|
RTSPHeaderField field,
|
||||||
|
gint indx);
|
||||||
RTSPResult rtsp_message_get_header (const RTSPMessage *msg,
|
RTSPResult rtsp_message_get_header (const RTSPMessage *msg,
|
||||||
RTSPHeaderField field,
|
RTSPHeaderField field,
|
||||||
gchar **value);
|
gchar **value,
|
||||||
|
gint indx);
|
||||||
|
|
||||||
|
void rtsp_message_append_headers (const RTSPMessage *msg,
|
||||||
|
GString *str);
|
||||||
|
|
||||||
RTSPResult rtsp_message_set_body (RTSPMessage *msg,
|
RTSPResult rtsp_message_set_body (RTSPMessage *msg,
|
||||||
const guint8 *data,
|
const guint8 *data,
|
||||||
|
|
Loading…
Reference in a new issue