client: allow absolute path in requests
[platform/upstream/gstreamer.git] / tests / check / gst / client.c
1 /* GStreamer
2  * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <gst/check/gstcheck.h>
21
22 #include <rtsp-client.h>
23
24 static gint cseq;
25 static guint expected_session_timeout = 60;
26
27 static gboolean
28 test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
29     gboolean close, gpointer user_data)
30 {
31   GstRTSPStatusCode code;
32   const gchar *reason;
33   GstRTSPVersion version;
34
35   fail_unless (gst_rtsp_message_get_type (response) ==
36       GST_RTSP_MESSAGE_RESPONSE);
37
38   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
39           &version)
40       == GST_RTSP_OK);
41   fail_unless (code == GST_RTSP_STS_OK);
42   fail_unless (g_str_equal (reason, "OK"));
43   fail_unless (version == GST_RTSP_VERSION_1_0);
44
45   return TRUE;
46 }
47
48 static gboolean
49 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
50     gboolean close, gpointer user_data)
51 {
52   GstRTSPStatusCode code;
53   const gchar *reason;
54   GstRTSPVersion version;
55
56   fail_unless (gst_rtsp_message_get_type (response) ==
57       GST_RTSP_MESSAGE_RESPONSE);
58
59   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
60           &version)
61       == GST_RTSP_OK);
62   fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
63   fail_unless (g_str_equal (reason, "Bad Request"));
64   fail_unless (version == GST_RTSP_VERSION_1_0);
65
66   return TRUE;
67 }
68
69 static gboolean
70 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
71     gboolean close, gpointer user_data)
72 {
73   GstRTSPStatusCode code;
74   const gchar *reason;
75   GstRTSPVersion version;
76
77   fail_unless (gst_rtsp_message_get_type (response) ==
78       GST_RTSP_MESSAGE_RESPONSE);
79
80   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
81           &version)
82       == GST_RTSP_OK);
83   fail_unless (code == GST_RTSP_STS_NOT_FOUND);
84   fail_unless (g_str_equal (reason, "Not Found"));
85   fail_unless (version == GST_RTSP_VERSION_1_0);
86
87   return TRUE;
88 }
89
90 static gboolean
91 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
92     gboolean close, gpointer user_data)
93 {
94   GstRTSPStatusCode code;
95   const gchar *reason;
96   GstRTSPVersion version;
97
98   fail_unless (gst_rtsp_message_get_type (response) ==
99       GST_RTSP_MESSAGE_RESPONSE);
100
101   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
102           &version)
103       == GST_RTSP_OK);
104   fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
105   fail_unless (g_str_equal (reason, "Session Not Found"));
106   fail_unless (version == GST_RTSP_VERSION_1_0);
107
108   return TRUE;
109 }
110
111 static GstRTSPClient *
112 setup_client (const gchar * launch_line)
113 {
114   GstRTSPClient *client;
115   GstRTSPSessionPool *session_pool;
116   GstRTSPMountPoints *mount_points;
117   GstRTSPMediaFactory *factory;
118   GstRTSPThreadPool *thread_pool;
119
120   client = gst_rtsp_client_new ();
121
122   session_pool = gst_rtsp_session_pool_new ();
123   gst_rtsp_client_set_session_pool (client, session_pool);
124
125   mount_points = gst_rtsp_mount_points_new ();
126   factory = gst_rtsp_media_factory_new ();
127   if (launch_line == NULL)
128     gst_rtsp_media_factory_set_launch (factory,
129         "videotestsrc ! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96");
130   else
131     gst_rtsp_media_factory_set_launch (factory, launch_line);
132
133   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
134   gst_rtsp_client_set_mount_points (client, mount_points);
135
136   thread_pool = gst_rtsp_thread_pool_new ();
137   gst_rtsp_client_set_thread_pool (client, thread_pool);
138
139   g_object_unref (mount_points);
140   g_object_unref (session_pool);
141   g_object_unref (thread_pool);
142
143   return client;
144 }
145
146 static void
147 teardown_client (GstRTSPClient *client)
148 {
149   gst_rtsp_client_set_thread_pool (client, NULL);
150   g_object_unref (client);
151 }
152
153 GST_START_TEST (test_request)
154 {
155   GstRTSPClient *client;
156   GstRTSPMessage request = { 0, };
157   gchar *str;
158   GstRTSPConnection *conn;
159   GSocket *sock;
160   GError *error = NULL;
161
162   client = gst_rtsp_client_new ();
163
164   /* OPTIONS with invalid url */
165   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
166           "foopy://padoop/") == GST_RTSP_OK);
167   str = g_strdup_printf ("%d", cseq);
168   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
169   g_free (str);
170
171   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
172   fail_unless (gst_rtsp_client_handle_message (client,
173           &request) == GST_RTSP_OK);
174
175   gst_rtsp_message_unset (&request);
176
177   /* OPTIONS with unknown session id */
178   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
179           "rtsp://localhost/test") == GST_RTSP_OK);
180   str = g_strdup_printf ("%d", cseq);
181   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
182   g_free (str);
183   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
184
185   gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
186   fail_unless (gst_rtsp_client_handle_message (client,
187           &request) == GST_RTSP_OK);
188
189   gst_rtsp_message_unset (&request);
190
191   /* OPTIONS with an absolute path instead of an absolute url */
192   /* set host information */
193   sock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
194       G_SOCKET_PROTOCOL_TCP, &error);
195   g_assert_no_error (error);
196   gst_rtsp_connection_create_from_socket (sock, "localhost", 444, NULL, &conn);
197   fail_unless (gst_rtsp_client_set_connection (client, conn));
198   g_object_unref (sock);
199
200   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
201           "/test") == GST_RTSP_OK);
202   str = g_strdup_printf ("%d", cseq);
203   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
204   g_free (str);
205
206   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
207   fail_unless (gst_rtsp_client_handle_message (client,
208           &request) == GST_RTSP_OK);
209   gst_rtsp_message_unset (&request);
210
211   /* OPTIONS with an absolute path instead of an absolute url with invalid
212    * host information */
213   g_object_unref (client);
214   client = gst_rtsp_client_new ();
215   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
216           "/test") == GST_RTSP_OK);
217   str = g_strdup_printf ("%d", cseq);
218   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
219   g_free (str);
220
221   gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
222   fail_unless (gst_rtsp_client_handle_message (client,
223           &request) == GST_RTSP_OK);
224   gst_rtsp_message_unset (&request);
225
226   g_object_unref (client);
227 }
228
229 GST_END_TEST;
230
231 static gboolean
232 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
233     gboolean close, gpointer user_data)
234 {
235   GstRTSPStatusCode code;
236   const gchar *reason;
237   GstRTSPVersion version;
238   gchar *str;
239   GstRTSPMethod methods;
240
241   fail_unless (gst_rtsp_message_get_type (response) ==
242       GST_RTSP_MESSAGE_RESPONSE);
243
244   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
245           &version)
246       == GST_RTSP_OK);
247   fail_unless (code == GST_RTSP_STS_OK);
248   fail_unless (g_str_equal (reason, "OK"));
249   fail_unless (version == GST_RTSP_VERSION_1_0);
250
251   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
252           0) == GST_RTSP_OK);
253   fail_unless (atoi (str) == cseq++);
254
255   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
256           0) == GST_RTSP_OK);
257
258   methods = gst_rtsp_options_from_text (str);
259   fail_if (methods == 0);
260   fail_unless (methods == (GST_RTSP_DESCRIBE |
261           GST_RTSP_OPTIONS |
262           GST_RTSP_PAUSE |
263           GST_RTSP_PLAY |
264           GST_RTSP_SETUP |
265           GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
266
267   return TRUE;
268 }
269
270 GST_START_TEST (test_options)
271 {
272   GstRTSPClient *client;
273   GstRTSPMessage request = { 0, };
274   gchar *str;
275
276   client = gst_rtsp_client_new ();
277
278   /* simple OPTIONS */
279   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
280           "rtsp://localhost/test") == GST_RTSP_OK);
281   str = g_strdup_printf ("%d", cseq);
282   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
283   g_free (str);
284
285   gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
286   fail_unless (gst_rtsp_client_handle_message (client,
287           &request) == GST_RTSP_OK);
288   gst_rtsp_message_unset (&request);
289
290   g_object_unref (client);
291 }
292
293 GST_END_TEST;
294
295 GST_START_TEST (test_describe)
296 {
297   GstRTSPClient *client;
298   GstRTSPMessage request = { 0, };
299   gchar *str;
300
301   client = gst_rtsp_client_new ();
302
303   /* simple DESCRIBE for non-existing url */
304   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
305           "rtsp://localhost/test") == GST_RTSP_OK);
306   str = g_strdup_printf ("%d", cseq);
307   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
308   g_free (str);
309
310   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
311   fail_unless (gst_rtsp_client_handle_message (client,
312           &request) == GST_RTSP_OK);
313   gst_rtsp_message_unset (&request);
314
315   g_object_unref (client);
316
317   /* simple DESCRIBE for an existing url */
318   client = setup_client (NULL);
319   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
320           "rtsp://localhost/test") == GST_RTSP_OK);
321   str = g_strdup_printf ("%d", cseq);
322   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
323   g_free (str);
324
325   gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
326   fail_unless (gst_rtsp_client_handle_message (client,
327           &request) == GST_RTSP_OK);
328   gst_rtsp_message_unset (&request);
329
330   teardown_client (client);
331 }
332
333 GST_END_TEST;
334
335 gchar *expected_transport = NULL;;
336
337 static gboolean
338 test_setup_response_200_multicast (GstRTSPClient * client,
339     GstRTSPMessage * response, gboolean close, gpointer user_data)
340 {
341   GstRTSPStatusCode code;
342   const gchar *reason;
343   GstRTSPVersion version;
344   gchar *str;
345   GstRTSPSessionPool *session_pool;
346   GstRTSPSession *session;
347   gchar **session_hdr_params;
348
349   fail_unless (expected_transport != NULL);
350
351   fail_unless (gst_rtsp_message_get_type (response) ==
352       GST_RTSP_MESSAGE_RESPONSE);
353
354   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
355           &version)
356       == GST_RTSP_OK);
357   fail_unless (code == GST_RTSP_STS_OK);
358   fail_unless (g_str_equal (reason, "OK"));
359   fail_unless (version == GST_RTSP_VERSION_1_0);
360
361   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
362           0) == GST_RTSP_OK);
363   fail_unless (atoi (str) == cseq++);
364
365   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
366           &str, 0) == GST_RTSP_OK);
367
368   fail_unless (!strcmp (str, expected_transport));
369
370   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
371           &str, 0) == GST_RTSP_OK);
372   session_hdr_params = g_strsplit (str, ";", -1);
373
374   /* session-id value */
375   fail_unless (session_hdr_params[0] != NULL);
376
377   if (expected_session_timeout != 60) {
378     /* session timeout param */
379     gchar *timeout_str = g_strdup_printf ("timeout=%u",
380         expected_session_timeout);
381
382     fail_unless (session_hdr_params[1] != NULL);
383     g_strstrip (session_hdr_params[1]);
384     fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0);
385     g_free (timeout_str);
386   }
387
388   session_pool = gst_rtsp_client_get_session_pool (client);
389   fail_unless (session_pool != NULL);
390
391   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
392   session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]);
393   g_strfreev (session_hdr_params);
394
395   fail_unless (session != NULL);
396   g_object_unref (session);
397
398   g_object_unref (session_pool);
399
400
401   return TRUE;
402 }
403
404 static GstRTSPClient *
405 setup_multicast_client (void)
406 {
407   GstRTSPClient *client;
408   GstRTSPSessionPool *session_pool;
409   GstRTSPMountPoints *mount_points;
410   GstRTSPMediaFactory *factory;
411   GstRTSPAddressPool *address_pool;
412   GstRTSPThreadPool *thread_pool;
413
414   client = gst_rtsp_client_new ();
415
416   session_pool = gst_rtsp_session_pool_new ();
417   gst_rtsp_client_set_session_pool (client, session_pool);
418
419   mount_points = gst_rtsp_mount_points_new ();
420   factory = gst_rtsp_media_factory_new ();
421   gst_rtsp_media_factory_set_launch (factory,
422       "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
423   address_pool = gst_rtsp_address_pool_new ();
424   fail_unless (gst_rtsp_address_pool_add_range (address_pool,
425           "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
426   gst_rtsp_media_factory_set_address_pool (factory, address_pool);
427   gst_rtsp_media_factory_add_role (factory, "user",
428       "media.factory.access", G_TYPE_BOOLEAN, TRUE,
429       "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
430   gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
431   gst_rtsp_client_set_mount_points (client, mount_points);
432
433   thread_pool = gst_rtsp_thread_pool_new ();
434   gst_rtsp_client_set_thread_pool (client, thread_pool);
435
436   g_object_unref (mount_points);
437   g_object_unref (session_pool);
438   g_object_unref (address_pool);
439   g_object_unref (thread_pool);
440
441   return client;
442 }
443
444 GST_START_TEST (test_client_multicast_transport_404)
445 {
446   GstRTSPClient *client;
447   GstRTSPMessage request = { 0, };
448   gchar *str;
449
450   client = setup_multicast_client ();
451
452   /* simple SETUP for non-existing url */
453   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
454           "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
455   str = g_strdup_printf ("%d", cseq);
456   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
457   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
458       "RTP/AVP;multicast");
459
460   gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
461   fail_unless (gst_rtsp_client_handle_message (client,
462           &request) == GST_RTSP_OK);
463   gst_rtsp_message_unset (&request);
464
465   teardown_client (client);
466 }
467
468 GST_END_TEST;
469
470 static void
471 new_session_cb (GObject * client, GstRTSPSession * session, gpointer user_data)
472 {
473   GST_DEBUG ("%p: new session %p", client, session);
474   gst_rtsp_session_set_timeout (session, expected_session_timeout);
475 }
476
477 GST_START_TEST (test_client_multicast_transport)
478 {
479   GstRTSPClient *client;
480   GstRTSPMessage request = { 0, };
481   gchar *str;
482
483   client = setup_multicast_client ();
484
485   expected_session_timeout = 20;
486   g_signal_connect (G_OBJECT (client), "new-session",
487       G_CALLBACK (new_session_cb), NULL);
488
489   /* simple SETUP with a valid URI and multicast */
490   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
491           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
492   str = g_strdup_printf ("%d", cseq);
493   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
494   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
495       "RTP/AVP;multicast");
496
497   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
498       "ttl=1;port=5000-5001;mode=\"PLAY\"";
499   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
500       NULL, NULL);
501   fail_unless (gst_rtsp_client_handle_message (client,
502           &request) == GST_RTSP_OK);
503   gst_rtsp_message_unset (&request);
504   expected_transport = NULL;
505   expected_session_timeout = 60;
506   teardown_client (client);
507 }
508
509 GST_END_TEST;
510
511 GST_START_TEST (test_client_multicast_ignore_transport_specific)
512 {
513   GstRTSPClient *client;
514   GstRTSPMessage request = { 0, };
515   gchar *str;
516
517   client = setup_multicast_client ();
518
519   /* simple SETUP with a valid URI and multicast and a specific dest,
520    * but ignore it  */
521   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
522           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
523   str = g_strdup_printf ("%d", cseq);
524   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
525   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
526       "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
527
528   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
529       "ttl=1;port=5000-5001;mode=\"PLAY\"";
530   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
531       NULL, NULL);
532   fail_unless (gst_rtsp_client_handle_message (client,
533           &request) == GST_RTSP_OK);
534   gst_rtsp_message_unset (&request);
535   expected_transport = NULL;
536
537   teardown_client (client);
538 }
539
540 GST_END_TEST;
541
542 static gboolean
543 test_setup_response_461 (GstRTSPClient * client,
544     GstRTSPMessage * response, gboolean close, gpointer user_data)
545 {
546   GstRTSPStatusCode code;
547   const gchar *reason;
548   GstRTSPVersion version;
549   gchar *str;
550
551   fail_unless (expected_transport == NULL);
552
553   fail_unless (gst_rtsp_message_get_type (response) ==
554       GST_RTSP_MESSAGE_RESPONSE);
555
556   fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
557           &version)
558       == GST_RTSP_OK);
559   fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
560   fail_unless (g_str_equal (reason, "Unsupported transport"));
561   fail_unless (version == GST_RTSP_VERSION_1_0);
562
563   fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
564           0) == GST_RTSP_OK);
565   fail_unless (atoi (str) == cseq++);
566
567
568   return TRUE;
569 }
570
571 GST_START_TEST (test_client_multicast_invalid_transport_specific)
572 {
573   GstRTSPClient *client;
574   GstRTSPMessage request = { 0, };
575   gchar *str;
576   GstRTSPSessionPool *session_pool;
577   GstRTSPContext ctx = { NULL };
578
579   client = setup_multicast_client ();
580
581   ctx.client = client;
582   ctx.auth = gst_rtsp_auth_new ();
583   ctx.token =
584       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
585       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
586       "user", NULL);
587   gst_rtsp_context_push_current (&ctx);
588
589   /* simple SETUP with a valid URI and multicast, but an invalid ip */
590   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
591           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
592   str = g_strdup_printf ("%d", cseq);
593   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
594   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
595       "RTP/AVP;multicast;destination=233.252.0.2;ttl=1;port=5000-5001;");
596
597   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
598   fail_unless (gst_rtsp_client_handle_message (client,
599           &request) == GST_RTSP_OK);
600   gst_rtsp_message_unset (&request);
601
602   session_pool = gst_rtsp_client_get_session_pool (client);
603   fail_unless (session_pool != NULL);
604   /* FIXME: There seems to be a leak of a session here ! */
605   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
606   g_object_unref (session_pool);
607
608
609
610   /* simple SETUP with a valid URI and multicast, but an invalid prt */
611   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
612           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
613   str = g_strdup_printf ("%d", cseq);
614   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
615   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
616       "RTP/AVP;multicast;destination=233.252.0.1;ttl=1;port=6000-6001;");
617
618   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
619   fail_unless (gst_rtsp_client_handle_message (client,
620           &request) == GST_RTSP_OK);
621   gst_rtsp_message_unset (&request);
622
623   session_pool = gst_rtsp_client_get_session_pool (client);
624   fail_unless (session_pool != NULL);
625   /* FIXME: There seems to be a leak of a session here ! */
626   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
627   g_object_unref (session_pool);
628
629
630
631   /* simple SETUP with a valid URI and multicast, but an invalid ttl */
632   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
633           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
634   str = g_strdup_printf ("%d", cseq);
635   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
636   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
637       "RTP/AVP;multicast;destination=233.252.0.1;ttl=2;port=5000-5001;");
638
639   gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
640   fail_unless (gst_rtsp_client_handle_message (client,
641           &request) == GST_RTSP_OK);
642   gst_rtsp_message_unset (&request);
643
644   session_pool = gst_rtsp_client_get_session_pool (client);
645   fail_unless (session_pool != NULL);
646   /* FIXME: There seems to be a leak of a session here ! */
647   /* fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0); */
648   g_object_unref (session_pool);
649
650
651   teardown_client (client);
652   g_object_unref (ctx.auth);
653   gst_rtsp_token_unref (ctx.token);
654   gst_rtsp_context_pop_current (&ctx);
655 }
656
657 GST_END_TEST;
658
659 GST_START_TEST (test_client_multicast_transport_specific)
660 {
661   GstRTSPClient *client;
662   GstRTSPMessage request = { 0, };
663   gchar *str;
664   GstRTSPSessionPool *session_pool;
665   GstRTSPContext ctx = { NULL };
666
667   client = setup_multicast_client ();
668
669   ctx.client = client;
670   ctx.auth = gst_rtsp_auth_new ();
671   ctx.token =
672       gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
673       G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
674       "user", NULL);
675   gst_rtsp_context_push_current (&ctx);
676
677   expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
678       "ttl=1;port=5000-5001;mode=\"PLAY\"";
679
680   /* simple SETUP with a valid URI and multicast, but an invalid ip */
681   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
682           "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
683   str = g_strdup_printf ("%d", cseq);
684   gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
685   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
686       expected_transport);
687
688   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
689       NULL, NULL);
690   fail_unless (gst_rtsp_client_handle_message (client,
691           &request) == GST_RTSP_OK);
692   gst_rtsp_message_unset (&request);
693   expected_transport = NULL;
694
695   gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
696       NULL, NULL);
697   session_pool = gst_rtsp_client_get_session_pool (client);
698   fail_unless (session_pool != NULL);
699   fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
700   g_object_unref (session_pool);
701
702   teardown_client (client);
703   g_object_unref (ctx.auth);
704   gst_rtsp_token_unref (ctx.token);
705   gst_rtsp_context_pop_current (&ctx);
706 }
707
708 GST_END_TEST;
709
710 static gboolean
711 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
712     gboolean close, gpointer user_data)
713 {
714   guint8 *data;
715   guint size;
716   GstSDPMessage *sdp_msg;
717   const GstSDPMedia *sdp_media;
718   const GstSDPBandwidth *bw;
719   gint bandwidth_val = GPOINTER_TO_INT (user_data);
720
721   fail_unless (gst_rtsp_message_get_body (response, &data, &size)
722       == GST_RTSP_OK);
723   gst_sdp_message_new (&sdp_msg);
724   fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
725       == GST_SDP_OK);
726
727   /* session description */
728   /* v= */
729   fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
730   /* o= */
731   fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
732   /* s= */
733   fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
734   /* t=0 0 */
735   fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
736
737   /* verify number of medias */
738   fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
739
740   /* media description */
741   sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
742   fail_unless (sdp_media != NULL);
743
744   /* m= */
745   fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
746
747   /* media bandwidth */
748   if (bandwidth_val) {
749     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
750     bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
751     fail_unless (bw != NULL);
752     fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
753     fail_unless (bw->bandwidth == bandwidth_val);
754   } else {
755     fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
756   }
757
758   gst_sdp_message_free (sdp_msg);
759
760   return TRUE;
761 }
762
763 static void
764 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
765 {
766   GstRTSPClient *client;
767   GstRTSPMessage request = { 0, };
768   gchar *str;
769
770   /* simple DESCRIBE for an existing url */
771   client = setup_client (launch_line);
772   fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
773           "rtsp://localhost/test") == GST_RTSP_OK);
774   str = g_strdup_printf ("%d", cseq);
775   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
776   g_free (str);
777
778   gst_rtsp_client_set_send_func (client, test_response_sdp,
779       (gpointer) bandwidth_val, NULL);
780   fail_unless (gst_rtsp_client_handle_message (client,
781           &request) == GST_RTSP_OK);
782   gst_rtsp_message_unset (&request);
783
784   teardown_client (client);
785 }
786
787 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
788 {
789   test_client_sdp ("videotestsrc "
790       "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
791       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
792       GUINT_TO_POINTER (50000));
793
794
795   /* max-bitrate=0: no bandwidth line */
796   test_client_sdp ("videotestsrc "
797       "! taginject tags=\"maximum-bitrate=(uint)0\" "
798       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
799       GUINT_TO_POINTER (0));
800 }
801
802 GST_END_TEST;
803
804 GST_START_TEST (test_client_sdp_with_bitrate_tag)
805 {
806   test_client_sdp ("videotestsrc "
807       "! taginject tags=\"bitrate=(uint)7000000\" "
808       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
809       GUINT_TO_POINTER (7000));
810
811   /* bitrate=0: no bandwdith line */
812   test_client_sdp ("videotestsrc "
813       "! taginject tags=\"bitrate=(uint)0\" "
814       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
815       GUINT_TO_POINTER (0));
816 }
817
818 GST_END_TEST;
819
820 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
821 {
822   test_client_sdp ("videotestsrc "
823       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
824       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
825       GUINT_TO_POINTER (50000));
826
827   /* max-bitrate is zero: fallback to bitrate */
828   test_client_sdp ("videotestsrc "
829       "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
830       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
831       GUINT_TO_POINTER (7000));
832
833   /* max-bitrate=bitrate=0o: no bandwidth line */
834   test_client_sdp ("videotestsrc "
835       "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
836       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
837       GUINT_TO_POINTER (0));
838 }
839
840 GST_END_TEST;
841
842 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
843 {
844   test_client_sdp ("videotestsrc "
845       "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
846 }
847
848 GST_END_TEST;
849
850 static Suite *
851 rtspclient_suite (void)
852 {
853   Suite *s = suite_create ("rtspclient");
854   TCase *tc = tcase_create ("general");
855
856   suite_add_tcase (s, tc);
857   tcase_set_timeout (tc, 20);
858   tcase_add_test (tc, test_request);
859   tcase_add_test (tc, test_options);
860   tcase_add_test (tc, test_describe);
861   tcase_add_test (tc, test_client_multicast_transport_404);
862   tcase_add_test (tc, test_client_multicast_transport);
863   tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
864   tcase_add_test (tc, test_client_multicast_invalid_transport_specific);
865   tcase_add_test (tc, test_client_multicast_transport_specific);
866   tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
867   tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
868   tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
869   tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
870
871   return s;
872 }
873
874 GST_CHECK_MAIN (rtspclient);