• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer unit tests for the GstRTSPConnection API (RTSP support
2  * library)
3  *
4  * Copyright (C) 2014 Ognyan Tonchev <ognyan axis com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <gst/check/gstcheck.h>
27 
28 #include <gst/rtsp/gstrtspconnection.h>
29 #include <string.h>
30 
31 
32 static const gchar *get_msg =
33     "GET /example/url HTTP/1.0\r\n"
34     "Host: 127.0.0.1\r\n" "x-sessioncookie: 805849328\r\n\r\n";
35 static const gchar *post_msg =
36     "POST /example/url HTTP/1.0\r\n"
37     "Host: 127.0.0.1\r\n"
38     "x-sessioncookie: 805849328\r\n"
39     "Content-Length: 0\r\n"
40     "Content-Type: application/x-rtsp-tunnelled\r\n\r\n";
41 
42 static guint tunnel_get_count;
43 static guint tunnel_post_count;
44 static guint tunnel_lost_count;
45 static guint closed_count;
46 static guint message_sent_count;
47 
48 typedef struct
49 {
50   GMainLoop *loop;
51   guint16 port;
52   GSocketConnection *conn;
53   GMutex mutex;
54   GCond cond;
55   gboolean started;
56 } ServiceData;
57 
58 static gboolean
incoming_callback(GSocketService * service,GSocketConnection * connection,GObject * source_object,gpointer user_data)59 incoming_callback (GSocketService * service, GSocketConnection * connection,
60     GObject * source_object, gpointer user_data)
61 {
62   ServiceData *data = user_data;
63 
64   GST_DEBUG ("new incoming connection");
65   data->conn = g_object_ref (connection);
66   g_main_loop_quit (data->loop);
67   return FALSE;
68 }
69 
70 static gpointer
service_thread_func(gpointer user_data)71 service_thread_func (gpointer user_data)
72 {
73   ServiceData *data = user_data;
74   GMainContext *service_context;
75   GSocketService *service;
76 
77   service_context = g_main_context_new ();
78   g_main_context_push_thread_default (service_context);
79 
80   data->loop = g_main_loop_new (service_context, FALSE);
81 
82   /* find available port and start service */
83   service = g_socket_service_new ();
84   data->port = g_socket_listener_add_any_inet_port ((GSocketListener *) service,
85       NULL, NULL);
86   fail_unless (data->port != 0);
87 
88   /* get notified upon new connection */
89   g_signal_connect (service, "incoming", G_CALLBACK (incoming_callback), data);
90 
91   g_socket_service_start (service);
92 
93   /* service is started */
94   g_mutex_lock (&data->mutex);
95   data->started = TRUE;
96   g_cond_signal (&data->cond);
97   g_mutex_unlock (&data->mutex);
98 
99   /* our service will run in the main context of this main loop */
100   g_main_loop_run (data->loop);
101 
102   g_main_context_pop_thread_default (service_context);
103 
104   g_main_loop_unref (data->loop);
105   data->loop = NULL;
106 
107   return NULL;
108 }
109 
110 static void
create_connection(GSocketConnection ** client_conn,GSocketConnection ** server_conn)111 create_connection (GSocketConnection ** client_conn,
112     GSocketConnection ** server_conn)
113 {
114   ServiceData *data;
115   GThread *service_thread;
116   GSocketClient *client = g_socket_client_new ();
117 
118   data = g_new0 (ServiceData, 1);
119   g_mutex_init (&data->mutex);
120   g_cond_init (&data->cond);
121 
122   service_thread = g_thread_new ("service thread", service_thread_func, data);
123   fail_unless (service_thread != NULL);
124 
125   /* wait for the service to start */
126   g_mutex_lock (&data->mutex);
127   while (!data->started) {
128     g_cond_wait (&data->cond, &data->mutex);
129   }
130   g_mutex_unlock (&data->mutex);
131 
132   /* create the tcp link */
133   *client_conn = g_socket_client_connect_to_host (client, (gchar *) "localhost",
134       data->port, NULL, NULL);
135   fail_unless (*client_conn != NULL);
136   fail_unless (g_socket_connection_is_connected (*client_conn));
137 
138   g_thread_join (service_thread);
139   *server_conn = data->conn;
140   data->conn = NULL;
141   fail_unless (g_socket_connection_is_connected (*server_conn));
142 
143   g_mutex_clear (&data->mutex);
144   g_cond_clear (&data->cond);
145   g_free (data);
146   g_object_unref (client);
147 }
148 
149 static GstRTSPStatusCode
tunnel_get(GstRTSPWatch * watch,gpointer user_data)150 tunnel_get (GstRTSPWatch * watch, gpointer user_data)
151 {
152   tunnel_get_count++;
153   return GST_RTSP_STS_OK;
154 }
155 
156 static GstRTSPResult
tunnel_post(GstRTSPWatch * watch,gpointer user_data)157 tunnel_post (GstRTSPWatch * watch, gpointer user_data)
158 {
159   tunnel_post_count++;
160   return GST_RTSP_OK;
161 }
162 
163 static GstRTSPResult
tunnel_lost(GstRTSPWatch * watch,gpointer user_data)164 tunnel_lost (GstRTSPWatch * watch, gpointer user_data)
165 {
166   tunnel_lost_count++;
167   return GST_RTSP_OK;
168 }
169 
170 static GstRTSPResult
closed(GstRTSPWatch * watch,gpointer user_data)171 closed (GstRTSPWatch * watch, gpointer user_data)
172 {
173   closed_count++;
174   return GST_RTSP_OK;
175 }
176 
177 static GstRTSPResult
message_sent(GstRTSPWatch * watch,guint id,gpointer user_data)178 message_sent (GstRTSPWatch * watch, guint id, gpointer user_data)
179 {
180   message_sent_count++;
181   return GST_RTSP_OK;
182 }
183 
184 static GstRTSPWatchFuncs watch_funcs = {
185   NULL,
186   message_sent,
187   closed,
188   NULL,
189   tunnel_get,
190   tunnel_post,
191   NULL,
192   tunnel_lost
193 };
194 
195 /* sets up a new tunnel, then disconnects the read connection and creates it
196  * again */
GST_START_TEST(test_rtspconnection_tunnel_setup)197 GST_START_TEST (test_rtspconnection_tunnel_setup)
198 {
199   GstRTSPConnection *rtsp_conn1 = NULL;
200   GstRTSPConnection *rtsp_conn2 = NULL;
201   GstRTSPWatch *watch1;
202   GstRTSPWatch *watch2;
203   GstRTSPResult res;
204   GSocketConnection *client_get = NULL;
205   GSocketConnection *server_get = NULL;
206   GSocketConnection *client_post = NULL;
207   GSocketConnection *server_post = NULL;
208   GSocket *server_sock;
209   GOutputStream *ostream_get;
210   GInputStream *istream_get;
211   GOutputStream *ostream_post;
212   gsize size = 0;
213   gchar buffer[1024];
214 
215   /* create GET connection */
216   create_connection (&client_get, &server_get);
217   server_sock = g_socket_connection_get_socket (server_get);
218   fail_unless (server_sock != NULL);
219 
220   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
221       NULL, &rtsp_conn1);
222   fail_unless (res == GST_RTSP_OK);
223   fail_unless (rtsp_conn1 != NULL);
224 
225   watch1 = gst_rtsp_watch_new (rtsp_conn1, &watch_funcs, NULL, NULL);
226   fail_unless (watch1 != NULL);
227   fail_unless (gst_rtsp_watch_attach (watch1, NULL) > 0);
228   g_source_unref ((GSource *) watch1);
229 
230   ostream_get = g_io_stream_get_output_stream (G_IO_STREAM (client_get));
231   fail_unless (ostream_get != NULL);
232 
233   istream_get = g_io_stream_get_input_stream (G_IO_STREAM (client_get));
234   fail_unless (istream_get != NULL);
235 
236   /* initiate the tunnel by sending HTTP GET */
237   fail_unless (g_output_stream_write_all (ostream_get, get_msg,
238           strlen (get_msg), &size, NULL, NULL));
239   fail_unless (size == strlen (get_msg));
240 
241   while (!g_main_context_iteration (NULL, TRUE));
242   fail_unless (tunnel_get_count == 1);
243   fail_unless (tunnel_post_count == 0);
244   fail_unless (tunnel_lost_count == 0);
245   fail_unless (closed_count == 0);
246 
247   /* read the HTTP GET response */
248   size = g_input_stream_read (istream_get, buffer, 1024, NULL, NULL);
249   fail_unless (size > 0);
250   buffer[size] = 0;
251   fail_unless (g_strrstr (buffer, "HTTP/1.0 200 OK") != NULL);
252 
253   /* create POST channel */
254   create_connection (&client_post, &server_post);
255   server_sock = g_socket_connection_get_socket (server_post);
256   fail_unless (server_sock != NULL);
257 
258   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
259       NULL, &rtsp_conn2);
260   fail_unless (res == GST_RTSP_OK);
261   fail_unless (rtsp_conn2 != NULL);
262 
263   watch2 = gst_rtsp_watch_new (rtsp_conn2, &watch_funcs, NULL, NULL);
264   fail_unless (watch2 != NULL);
265   fail_unless (gst_rtsp_watch_attach (watch2, NULL) > 0);
266   g_source_unref ((GSource *) watch2);
267 
268   ostream_post = g_io_stream_get_output_stream (G_IO_STREAM (client_post));
269   fail_unless (ostream_post != NULL);
270 
271   /* complete the tunnel by sending HTTP POST */
272   fail_unless (g_output_stream_write_all (ostream_post, post_msg,
273           strlen (post_msg), &size, NULL, NULL));
274   fail_unless (size == strlen (post_msg));
275 
276   while (!g_main_context_iteration (NULL, TRUE));
277   fail_unless (tunnel_get_count == 1);
278   fail_unless (tunnel_post_count == 1);
279   fail_unless (tunnel_lost_count == 0);
280   fail_unless (closed_count == 0);
281 
282   /* merge the two connections together */
283   fail_unless (gst_rtsp_connection_do_tunnel (rtsp_conn1, rtsp_conn2) ==
284       GST_RTSP_OK);
285   gst_rtsp_watch_reset (watch1);
286   g_source_destroy ((GSource *) watch2);
287   gst_rtsp_connection_free (rtsp_conn2);
288   rtsp_conn2 = NULL;
289 
290   /* it must be possible to reconnect the POST channel */
291   g_object_unref (client_post);
292   while (!g_main_context_iteration (NULL, TRUE));
293   fail_unless (tunnel_get_count == 1);
294   fail_unless (tunnel_post_count == 1);
295   fail_unless (tunnel_lost_count == 1);
296   fail_unless (closed_count == 0);
297   g_object_unref (server_post);
298 
299   /* no other source should get dispatched */
300   fail_if (g_main_context_iteration (NULL, FALSE));
301 
302   /* create new POST connection */
303   create_connection (&client_post, &server_post);
304   server_sock = g_socket_connection_get_socket (server_post);
305   fail_unless (server_sock != NULL);
306 
307   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
308       NULL, &rtsp_conn2);
309   fail_unless (res == GST_RTSP_OK);
310   fail_unless (rtsp_conn2 != NULL);
311 
312   watch2 = gst_rtsp_watch_new (rtsp_conn2, &watch_funcs, NULL, NULL);
313   fail_unless (watch2 != NULL);
314   fail_unless (gst_rtsp_watch_attach (watch2, NULL) > 0);
315   g_source_unref ((GSource *) watch2);
316 
317   ostream_post = g_io_stream_get_output_stream (G_IO_STREAM (client_post));
318   fail_unless (ostream_post != NULL);
319 
320   /* complete the tunnel by sending HTTP POST */
321   fail_unless (g_output_stream_write_all (ostream_post, post_msg,
322           strlen (post_msg), &size, NULL, NULL));
323   fail_unless (size == strlen (post_msg));
324 
325   while (!g_main_context_iteration (NULL, TRUE));
326   fail_unless (tunnel_get_count == 1);
327   fail_unless (tunnel_post_count == 2);
328   fail_unless (tunnel_lost_count == 1);
329   fail_unless (closed_count == 0);
330 
331   /* merge the two connections together */
332   fail_unless (gst_rtsp_connection_do_tunnel (rtsp_conn1, rtsp_conn2) ==
333       GST_RTSP_OK);
334   gst_rtsp_watch_reset (watch1);
335   g_source_destroy ((GSource *) watch2);
336   gst_rtsp_connection_free (rtsp_conn2);
337   rtsp_conn2 = NULL;
338 
339   /* check if rtspconnection can detect close of the get channel */
340   g_object_unref (client_get);
341   while (!g_main_context_iteration (NULL, TRUE));
342   fail_unless (tunnel_get_count == 1);
343   fail_unless (tunnel_post_count == 2);
344   fail_unless (tunnel_lost_count == 1);
345   fail_unless (closed_count == 1);
346 
347   fail_unless (gst_rtsp_connection_close (rtsp_conn1) == GST_RTSP_OK);
348   fail_unless (gst_rtsp_connection_free (rtsp_conn1) == GST_RTSP_OK);
349 
350   g_object_unref (client_post);
351   g_object_unref (server_post);
352   g_object_unref (server_get);
353 }
354 
355 GST_END_TEST;
356 
357 /* sets up a new tunnel, starting with the read channel,
358  * then disconnects the read connection and creates it again
359  * ideally this test should be merged with test_rtspconnection_tunnel_setup but
360  * but it became quite messy */
GST_START_TEST(test_rtspconnection_tunnel_setup_post_first)361 GST_START_TEST (test_rtspconnection_tunnel_setup_post_first)
362 {
363   GstRTSPConnection *rtsp_conn1 = NULL;
364   GstRTSPConnection *rtsp_conn2 = NULL;
365   GstRTSPWatch *watch1;
366   GstRTSPWatch *watch2;
367   GstRTSPResult res;
368   GSocketConnection *client_get = NULL;
369   GSocketConnection *server_get = NULL;
370   GSocketConnection *client_post = NULL;
371   GSocketConnection *server_post = NULL;
372   GSocket *server_sock;
373   GOutputStream *ostream_get;
374   GInputStream *istream_get;
375   GOutputStream *ostream_post;
376   gsize size = 0;
377   gchar buffer[1024];
378 
379   /* create POST channel */
380   create_connection (&client_post, &server_post);
381   server_sock = g_socket_connection_get_socket (server_post);
382   fail_unless (server_sock != NULL);
383 
384   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
385       NULL, &rtsp_conn1);
386   fail_unless (res == GST_RTSP_OK);
387   fail_unless (rtsp_conn1 != NULL);
388 
389   watch1 = gst_rtsp_watch_new (rtsp_conn1, &watch_funcs, NULL, NULL);
390   fail_unless (watch1 != NULL);
391   fail_unless (gst_rtsp_watch_attach (watch1, NULL) > 0);
392   g_source_unref ((GSource *) watch1);
393 
394   ostream_post = g_io_stream_get_output_stream (G_IO_STREAM (client_post));
395   fail_unless (ostream_post != NULL);
396 
397   /* initiate the tunnel by sending HTTP POST */
398   fail_unless (g_output_stream_write_all (ostream_post, post_msg,
399           strlen (post_msg), &size, NULL, NULL));
400   fail_unless (size == strlen (post_msg));
401 
402   while (!g_main_context_iteration (NULL, TRUE));
403   fail_unless (tunnel_get_count == 0);
404   fail_unless (tunnel_post_count == 1);
405   fail_unless (tunnel_lost_count == 0);
406   fail_unless (closed_count == 0);
407 
408   /* create GET connection */
409   create_connection (&client_get, &server_get);
410   server_sock = g_socket_connection_get_socket (server_get);
411   fail_unless (server_sock != NULL);
412 
413   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
414       NULL, &rtsp_conn2);
415   fail_unless (res == GST_RTSP_OK);
416   fail_unless (rtsp_conn2 != NULL);
417 
418   watch2 = gst_rtsp_watch_new (rtsp_conn2, &watch_funcs, NULL, NULL);
419   fail_unless (watch2 != NULL);
420   fail_unless (gst_rtsp_watch_attach (watch2, NULL) > 0);
421   g_source_unref ((GSource *) watch2);
422 
423   ostream_get = g_io_stream_get_output_stream (G_IO_STREAM (client_get));
424   fail_unless (ostream_get != NULL);
425 
426   istream_get = g_io_stream_get_input_stream (G_IO_STREAM (client_get));
427   fail_unless (istream_get != NULL);
428 
429   /* complete the tunnel by sending HTTP GET */
430   fail_unless (g_output_stream_write_all (ostream_get, get_msg,
431           strlen (get_msg), &size, NULL, NULL));
432   fail_unless (size == strlen (get_msg));
433 
434   while (!g_main_context_iteration (NULL, TRUE));
435   fail_unless (tunnel_get_count == 1);
436   fail_unless (tunnel_post_count == 1);
437   fail_unless (tunnel_lost_count == 0);
438   fail_unless (closed_count == 0);
439 
440   /* read the HTTP GET response */
441   size = g_input_stream_read (istream_get, buffer, 1024, NULL, NULL);
442   fail_unless (size > 0);
443   buffer[size] = 0;
444   fail_unless (g_strrstr (buffer, "HTTP/1.0 200 OK") != NULL);
445 
446   /* merge the two connections together */
447   fail_unless (gst_rtsp_connection_do_tunnel (rtsp_conn1, rtsp_conn2) ==
448       GST_RTSP_OK);
449   gst_rtsp_watch_reset (watch1);
450   g_source_destroy ((GSource *) watch2);
451   gst_rtsp_connection_free (rtsp_conn2);
452   rtsp_conn2 = NULL;
453 
454   /* it must be possible to reconnect the POST channel */
455   g_object_unref (client_post);
456   while (!g_main_context_iteration (NULL, TRUE));
457   fail_unless (tunnel_get_count == 1);
458   fail_unless (tunnel_post_count == 1);
459   fail_unless (tunnel_lost_count == 1);
460   fail_unless (closed_count == 0);
461   g_object_unref (server_post);
462 
463   /* no other source should get dispatched */
464   fail_if (g_main_context_iteration (NULL, FALSE));
465 
466   /* create new POST connection */
467   create_connection (&client_post, &server_post);
468   server_sock = g_socket_connection_get_socket (server_post);
469   fail_unless (server_sock != NULL);
470 
471   res = gst_rtsp_connection_create_from_socket (server_sock, "127.0.0.1", 4444,
472       NULL, &rtsp_conn2);
473   fail_unless (res == GST_RTSP_OK);
474   fail_unless (rtsp_conn2 != NULL);
475 
476   watch2 = gst_rtsp_watch_new (rtsp_conn2, &watch_funcs, NULL, NULL);
477   fail_unless (watch2 != NULL);
478   fail_unless (gst_rtsp_watch_attach (watch2, NULL) > 0);
479   g_source_unref ((GSource *) watch2);
480 
481   ostream_post = g_io_stream_get_output_stream (G_IO_STREAM (client_post));
482   fail_unless (ostream_post != NULL);
483 
484   /* complete the tunnel by sending HTTP POST */
485   fail_unless (g_output_stream_write_all (ostream_post, post_msg,
486           strlen (post_msg), &size, NULL, NULL));
487   fail_unless (size == strlen (post_msg));
488 
489   while (!g_main_context_iteration (NULL, TRUE));
490   fail_unless (tunnel_get_count == 1);
491   fail_unless (tunnel_post_count == 2);
492   fail_unless (tunnel_lost_count == 1);
493   fail_unless (closed_count == 0);
494 
495   /* merge the two connections together */
496   fail_unless (gst_rtsp_connection_do_tunnel (rtsp_conn1, rtsp_conn2) ==
497       GST_RTSP_OK);
498   gst_rtsp_watch_reset (watch1);
499   g_source_destroy ((GSource *) watch2);
500   gst_rtsp_connection_free (rtsp_conn2);
501   rtsp_conn2 = NULL;
502 
503   /* check if rtspconnection can detect close of the get channel */
504   g_object_unref (client_get);
505   while (!g_main_context_iteration (NULL, TRUE));
506   fail_unless (tunnel_get_count == 1);
507   fail_unless (tunnel_post_count == 2);
508   fail_unless (tunnel_lost_count == 1);
509   fail_unless (closed_count == 1);
510 
511   fail_unless (gst_rtsp_connection_close (rtsp_conn1) == GST_RTSP_OK);
512   fail_unless (gst_rtsp_connection_free (rtsp_conn1) == GST_RTSP_OK);
513 
514   g_object_unref (client_post);
515   g_object_unref (server_post);
516   g_object_unref (server_get);
517 }
518 
519 GST_END_TEST;
520 
GST_START_TEST(test_rtspconnection_send_receive)521 GST_START_TEST (test_rtspconnection_send_receive)
522 {
523   GSocketConnection *input_conn = NULL;
524   GSocketConnection *output_conn = NULL;
525   GSocket *input_sock;
526   GSocket *output_sock;
527   GstRTSPConnection *rtsp_output_conn;
528   GstRTSPConnection *rtsp_input_conn;
529   GstRTSPMessage *msg;
530   gchar body[] = "message body";
531   gchar *recv_body;
532   guint recv_body_len;
533 
534   create_connection (&input_conn, &output_conn);
535   input_sock = g_socket_connection_get_socket (input_conn);
536   fail_unless (input_sock != NULL);
537   output_sock = g_socket_connection_get_socket (output_conn);
538   fail_unless (output_sock != NULL);
539 
540   fail_unless (gst_rtsp_connection_create_from_socket (input_sock, "127.0.0.1",
541           4444, NULL, &rtsp_input_conn) == GST_RTSP_OK);
542   fail_unless (rtsp_input_conn != NULL);
543 
544   fail_unless (gst_rtsp_connection_create_from_socket (output_sock, "127.0.0.1",
545           4444, NULL, &rtsp_output_conn) == GST_RTSP_OK);
546   fail_unless (rtsp_output_conn != NULL);
547 
548   /* send data message */
549   fail_unless (gst_rtsp_message_new_data (&msg, 1) == GST_RTSP_OK);
550   fail_unless (gst_rtsp_message_set_body (msg, (guint8 *) body,
551           sizeof (body)) == GST_RTSP_OK);
552   fail_unless (gst_rtsp_connection_send (rtsp_output_conn, msg,
553           NULL) == GST_RTSP_OK);
554   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
555   msg = NULL;
556 
557   /* receive data message and make sure it is correct */
558   fail_unless (gst_rtsp_message_new (&msg) == GST_RTSP_OK);
559   fail_unless (gst_rtsp_connection_receive (rtsp_input_conn, msg, NULL) ==
560       GST_RTSP_OK);
561   fail_unless (gst_rtsp_message_get_type (msg) == GST_RTSP_MESSAGE_DATA);
562   fail_unless (gst_rtsp_message_get_body (msg, (guint8 **) & recv_body,
563           &recv_body_len) == GST_RTSP_OK);
564   /* RTSPConnection adds an extra byte for the trailing '\0' */
565   fail_unless_equals_int (recv_body_len, sizeof (body) + 1);
566   fail_unless_equals_string (recv_body, body);
567   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
568   msg = NULL;
569 
570   /* send request message */
571   fail_unless (gst_rtsp_message_new_request (&msg, GST_RTSP_OPTIONS,
572           "example.org") == GST_RTSP_OK);
573   fail_unless (gst_rtsp_message_set_body (msg, (guint8 *) body,
574           sizeof (body)) == GST_RTSP_OK);
575   fail_unless (gst_rtsp_connection_send (rtsp_output_conn, msg,
576           NULL) == GST_RTSP_OK);
577   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
578   msg = NULL;
579 
580   /* receive request message and make sure it is correct */
581   fail_unless (gst_rtsp_message_new (&msg) == GST_RTSP_OK);
582   fail_unless (gst_rtsp_connection_receive (rtsp_input_conn, msg, NULL) ==
583       GST_RTSP_OK);
584   fail_unless (gst_rtsp_message_get_type (msg) == GST_RTSP_MESSAGE_REQUEST);
585   fail_unless (gst_rtsp_message_get_body (msg, (guint8 **) & recv_body,
586           &recv_body_len) == GST_RTSP_OK);
587   /* RTSPConnection adds an extra byte for the trailing '\0' */
588   fail_unless_equals_int (recv_body_len, sizeof (body) + 1);
589   fail_unless_equals_string (recv_body, body);
590   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
591   msg = NULL;
592 
593   fail_unless (gst_rtsp_connection_close (rtsp_input_conn) == GST_RTSP_OK);
594   fail_unless (gst_rtsp_connection_free (rtsp_input_conn) == GST_RTSP_OK);
595   fail_unless (gst_rtsp_connection_close (rtsp_output_conn) == GST_RTSP_OK);
596   fail_unless (gst_rtsp_connection_free (rtsp_output_conn) == GST_RTSP_OK);
597 
598   g_object_unref (input_conn);
599   g_object_unref (output_conn);
600 }
601 
602 GST_END_TEST;
603 
GST_START_TEST(test_rtspconnection_send_receive_check_headers)604 GST_START_TEST (test_rtspconnection_send_receive_check_headers)
605 {
606   GSocketConnection *input_conn = NULL;
607   GSocketConnection *output_conn = NULL;
608   GSocket *input_sock;
609   GSocket *output_sock;
610   GstRTSPConnection *rtsp_output_conn;
611   GstRTSPConnection *rtsp_input_conn;
612   GstRTSPMessage *msg;
613   gchar *header_val;
614 
615   create_connection (&input_conn, &output_conn);
616   input_sock = g_socket_connection_get_socket (input_conn);
617   fail_unless (input_sock != NULL);
618   output_sock = g_socket_connection_get_socket (output_conn);
619   fail_unless (output_sock != NULL);
620 
621   fail_unless (gst_rtsp_connection_create_from_socket (input_sock, "127.0.0.1",
622           4444, NULL, &rtsp_input_conn) == GST_RTSP_OK);
623   fail_unless (rtsp_input_conn != NULL);
624 
625   fail_unless (gst_rtsp_connection_create_from_socket (output_sock, "127.0.0.1",
626           4444, NULL, &rtsp_output_conn) == GST_RTSP_OK);
627   fail_unless (rtsp_output_conn != NULL);
628 
629   /* send request message */
630   fail_unless (gst_rtsp_message_new_request (&msg, GST_RTSP_SETUP,
631           "rtsp://example.com/") == GST_RTSP_OK);
632   fail_unless (gst_rtsp_message_add_header (msg, GST_RTSP_HDR_BLOCKSIZE,
633           "1024") == GST_RTSP_OK);
634   fail_unless (gst_rtsp_message_add_header_by_name (msg, "Custom-Header",
635           "lol") == GST_RTSP_OK);
636   fail_unless (gst_rtsp_connection_send (rtsp_output_conn, msg,
637           NULL) == GST_RTSP_OK);
638   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
639   msg = NULL;
640 
641   /* receive request message and make sure it is correct */
642   fail_unless (gst_rtsp_message_new (&msg) == GST_RTSP_OK);
643   fail_unless (gst_rtsp_connection_receive (rtsp_input_conn, msg, NULL) ==
644       GST_RTSP_OK);
645   fail_unless (gst_rtsp_message_get_type (msg) == GST_RTSP_MESSAGE_REQUEST);
646   /* check headers */
647   fail_unless (gst_rtsp_message_get_header (msg, GST_RTSP_HDR_BLOCKSIZE,
648           &header_val, 0) == GST_RTSP_OK);
649   fail_unless (!g_strcmp0 (header_val, "1024"));
650   fail_unless (gst_rtsp_message_get_header_by_name (msg, "Custom-Header",
651           &header_val, 0) == GST_RTSP_OK);
652   fail_unless (!g_strcmp0 (header_val, "lol"));
653   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
654   msg = NULL;
655 
656   fail_unless (gst_rtsp_connection_close (rtsp_input_conn) == GST_RTSP_OK);
657   fail_unless (gst_rtsp_connection_free (rtsp_input_conn) == GST_RTSP_OK);
658   fail_unless (gst_rtsp_connection_close (rtsp_output_conn) == GST_RTSP_OK);
659   fail_unless (gst_rtsp_connection_free (rtsp_output_conn) == GST_RTSP_OK);
660 
661   g_object_unref (input_conn);
662   g_object_unref (output_conn);
663 }
664 
665 GST_END_TEST;
666 
GST_START_TEST(test_rtspconnection_connect)667 GST_START_TEST (test_rtspconnection_connect)
668 {
669   ServiceData *data;
670   GThread *service_thread;
671   GSocketConnection *socket_conn;
672   GstRTSPConnection *rtsp_conn = NULL;
673   GstRTSPUrl *url = NULL;
674   gchar *path;
675 
676   data = g_new0 (ServiceData, 1);
677   g_mutex_init (&data->mutex);
678   g_cond_init (&data->cond);
679 
680   /* create socket service */
681   service_thread = g_thread_new ("service thread", service_thread_func, data);
682   fail_unless (service_thread != NULL);
683 
684   /* wait for the service to start */
685   g_mutex_lock (&data->mutex);
686   while (!data->started) {
687     g_cond_wait (&data->cond, &data->mutex);
688   }
689   g_mutex_unlock (&data->mutex);
690 
691   /* connect to our service using the RTSPConnection API */
692   path = g_strdup_printf ("rtsp://localhost:%d", data->port);
693   fail_unless (gst_rtsp_url_parse (path, &url) == GST_RTSP_OK);
694   fail_unless (gst_rtsp_connection_create (url, &rtsp_conn) == GST_RTSP_OK);
695   fail_unless (gst_rtsp_connection_connect (rtsp_conn, NULL) == GST_RTSP_OK);
696   g_free (path);
697   gst_rtsp_url_free (url);
698 
699   /* wait for the other end and check whether it is connected */
700   g_thread_join (service_thread);
701   socket_conn = data->conn;
702   data->conn = NULL;
703   fail_unless (g_socket_connection_is_connected (socket_conn));
704 
705   fail_unless (gst_rtsp_connection_close (rtsp_conn) == GST_RTSP_OK);
706   fail_unless (gst_rtsp_connection_free (rtsp_conn) == GST_RTSP_OK);
707   g_object_unref (socket_conn);
708   g_mutex_clear (&data->mutex);
709   g_cond_clear (&data->cond);
710   g_free (data);
711 }
712 
713 GST_END_TEST;
714 
GST_START_TEST(test_rtspconnection_poll)715 GST_START_TEST (test_rtspconnection_poll)
716 {
717   GSocketConnection *conn1 = NULL;
718   GSocketConnection *conn2 = NULL;
719   GSocket *sock;
720   GstRTSPConnection *rtsp_conn;
721   GstRTSPEvent event;
722   GOutputStream *ostream;
723   gsize size;
724   gint64 timeout;
725 
726   create_connection (&conn1, &conn2);
727   sock = g_socket_connection_get_socket (conn1);
728   fail_unless (sock != NULL);
729 
730   ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn2));
731   fail_unless (ostream != NULL);
732 
733   fail_unless (gst_rtsp_connection_create_from_socket (sock, "127.0.0.1",
734           4444, NULL, &rtsp_conn) == GST_RTSP_OK);
735   fail_unless (rtsp_conn != NULL);
736 
737   /* should be possible to write on socket */
738   fail_unless (gst_rtsp_connection_poll (rtsp_conn, GST_RTSP_EV_WRITE, &event,
739           NULL) == GST_RTSP_OK);
740   fail_unless (event & GST_RTSP_EV_WRITE);
741 
742   /* but not read, add timeout so that we don't block forever */
743   timeout = G_USEC_PER_SEC;
744   fail_unless (gst_rtsp_connection_poll_usec (rtsp_conn, GST_RTSP_EV_READ,
745           &event, timeout) == GST_RTSP_ETIMEOUT);
746   fail_if (event & GST_RTSP_EV_READ);
747 
748   /* write on the other end and make sure socket can be read */
749   fail_unless (g_output_stream_write_all (ostream, "data", 5, &size, NULL,
750           NULL));
751   fail_unless (gst_rtsp_connection_poll (rtsp_conn, GST_RTSP_EV_READ, &event,
752           NULL) == GST_RTSP_OK);
753   fail_unless (event & GST_RTSP_EV_READ);
754 
755   fail_unless (gst_rtsp_connection_close (rtsp_conn) == GST_RTSP_OK);
756   fail_unless (gst_rtsp_connection_free (rtsp_conn) == GST_RTSP_OK);
757   g_object_unref (conn1);
758   g_object_unref (conn2);
759 }
760 
761 GST_END_TEST;
762 
GST_START_TEST(test_rtspconnection_backlog)763 GST_START_TEST (test_rtspconnection_backlog)
764 {
765   GSocketConnection *conn1 = NULL;
766   GSocketConnection *conn2 = NULL;
767   GSocket *sock;
768   GstRTSPConnection *rtsp_conn = NULL;
769   GstRTSPWatch *watch;
770   GInputStream *istream;
771   guint8 *buffer;
772   guint8 recv[1024];
773   gsize count;
774   GstRTSPResult res = GST_RTSP_OK;
775   guint num_queued;
776   guint num_sent;
777 
778   create_connection (&conn1, &conn2);
779   sock = g_socket_connection_get_socket (conn1);
780   fail_unless (sock != NULL);
781 
782   fail_unless (gst_rtsp_connection_create_from_socket (sock, "127.0.0.1",
783           4444, NULL, &rtsp_conn) == GST_RTSP_OK);
784   fail_unless (rtsp_conn != NULL);
785 
786   watch = gst_rtsp_watch_new (rtsp_conn, &watch_funcs, NULL, NULL);
787   fail_unless (watch != NULL);
788   fail_unless (gst_rtsp_watch_attach (watch, NULL) > 0);
789   g_source_unref ((GSource *) watch);
790 
791   gst_rtsp_watch_set_send_backlog (watch, 1024, 0);
792 
793   /* write until we fill tcp window and writes result in would_block,
794    * data will then start getting queued until the backlog also gets full */
795   num_queued = 0;
796   num_sent = 0;
797   while (res == GST_RTSP_OK) {
798     guint id = 0;
799     buffer = malloc (1024);
800     memset (buffer, 0, 1024);
801     res = gst_rtsp_watch_write_data (watch, buffer, 1024, &id);
802     if (id > 0)
803       num_queued++;
804     if (res == GST_RTSP_OK)
805       num_sent++;
806   }
807 
808   /* make sure we got enomem and at least 1 message got queued */
809   fail_unless (res == GST_RTSP_ENOMEM);
810   fail_unless (num_queued > 0);
811 
812   istream = g_io_stream_get_input_stream (G_IO_STREAM (conn2));
813   fail_unless (istream != NULL);
814 
815   /* read a bit from the socket and make sure queued data gets sent */
816   while (num_queued > 0) {
817     fail_unless (g_input_stream_read_all (istream, recv, 1024, &count, NULL,
818             NULL));
819     num_sent--;
820 
821     g_main_context_iteration (NULL, FALSE);
822     num_queued -= message_sent_count;
823     fail_unless (num_queued >= 0);
824   }
825 
826   /* make sure we can read the rest of the data */
827   while (num_sent > 0) {
828     fail_unless (g_input_stream_read_all (istream, recv, 1024, &count, NULL,
829             NULL));
830     num_sent--;
831   }
832 
833   g_source_destroy ((GSource *) watch);
834   fail_unless (gst_rtsp_connection_close (rtsp_conn) == GST_RTSP_OK);
835   fail_unless (gst_rtsp_connection_free (rtsp_conn) == GST_RTSP_OK);
836   g_object_unref (conn1);
837   g_object_unref (conn2);
838 }
839 
840 GST_END_TEST;
841 
GST_START_TEST(test_rtspconnection_ip)842 GST_START_TEST (test_rtspconnection_ip)
843 {
844   GstRTSPConnection *conn = NULL;
845   GstRTSPUrl *url = NULL;
846 
847   fail_unless (gst_rtsp_url_parse ("rtsp://127.0.0.1:42", &url) == GST_RTSP_OK);
848   fail_unless (url != NULL);
849   fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
850   fail_unless (conn != NULL);
851 
852   gst_rtsp_connection_set_ip (conn, "127.0.0.1");
853   fail_unless_equals_string (gst_rtsp_connection_get_ip (conn), "127.0.0.1");
854 
855   gst_rtsp_url_free (url);
856   fail_unless (gst_rtsp_connection_free (conn) == GST_RTSP_OK);
857 }
858 
859 GST_END_TEST;
860 
GST_START_TEST(test_rtspconnection_send_receive_content_length)861 GST_START_TEST (test_rtspconnection_send_receive_content_length)
862 {
863   GSocketConnection *input_conn = NULL;
864   GSocketConnection *output_conn = NULL;
865   GSocket *input_sock;
866   GSocket *output_sock;
867   GstRTSPConnection *rtsp_output_conn;
868   GstRTSPConnection *rtsp_input_conn;
869   GstRTSPMessage *msg;
870 
871   create_connection (&input_conn, &output_conn);
872   input_sock = g_socket_connection_get_socket (input_conn);
873   fail_unless (input_sock != NULL);
874   output_sock = g_socket_connection_get_socket (output_conn);
875   fail_unless (output_sock != NULL);
876 
877   fail_unless (gst_rtsp_connection_create_from_socket (input_sock, "127.0.0.1",
878           4444, NULL, &rtsp_input_conn) == GST_RTSP_OK);
879   fail_unless (rtsp_input_conn != NULL);
880 
881   fail_unless (gst_rtsp_connection_create_from_socket (output_sock, "127.0.0.1",
882           4444, NULL, &rtsp_output_conn) == GST_RTSP_OK);
883   fail_unless (rtsp_output_conn != NULL);
884 
885   /* send request message with to big payload */
886   fail_unless (gst_rtsp_message_new_request (&msg, GST_RTSP_SETUP,
887           "rtsp://example.com/") == GST_RTSP_OK);
888   fail_unless (gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CONTENT_LENGTH,
889           "2000") == GST_RTSP_OK);
890   fail_unless (gst_rtsp_connection_send (rtsp_output_conn, msg,
891           NULL) == GST_RTSP_OK);
892   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
893   msg = NULL;
894 
895   /* receive request message, expect ENOMEM */
896   gst_rtsp_connection_set_content_length_limit (rtsp_input_conn, 1000);
897   fail_unless (gst_rtsp_message_new (&msg) == GST_RTSP_OK);
898   fail_unless (gst_rtsp_connection_receive (rtsp_input_conn, msg, NULL) ==
899       GST_RTSP_ENOMEM);
900   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
901   msg = NULL;
902 
903   /* send request message with negative payload */
904   fail_unless (gst_rtsp_message_new_request (&msg, GST_RTSP_SETUP,
905           "rtsp://example.com/") == GST_RTSP_OK);
906   fail_unless (gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CONTENT_LENGTH,
907           "-2000") == GST_RTSP_OK);
908   fail_unless (gst_rtsp_connection_send (rtsp_output_conn, msg,
909           NULL) == GST_RTSP_OK);
910   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
911   msg = NULL;
912 
913   /* receive request message, expect EPARSE */
914   fail_unless (gst_rtsp_message_new (&msg) == GST_RTSP_OK);
915   fail_unless (gst_rtsp_connection_receive (rtsp_input_conn, msg, NULL) ==
916       GST_RTSP_EPARSE);
917   fail_unless (gst_rtsp_message_free (msg) == GST_RTSP_OK);
918   msg = NULL;
919 
920   fail_unless (gst_rtsp_connection_close (rtsp_input_conn) == GST_RTSP_OK);
921   fail_unless (gst_rtsp_connection_free (rtsp_input_conn) == GST_RTSP_OK);
922   fail_unless (gst_rtsp_connection_close (rtsp_output_conn) == GST_RTSP_OK);
923   fail_unless (gst_rtsp_connection_free (rtsp_output_conn) == GST_RTSP_OK);
924 
925   g_object_unref (input_conn);
926   g_object_unref (output_conn);
927 }
928 
929 GST_END_TEST;
930 
931 static Suite *
rtspconnection_suite(void)932 rtspconnection_suite (void)
933 {
934   Suite *s = suite_create ("rtsp support library(rtspconnection)");
935   TCase *tc_chain = tcase_create ("general");
936 
937   suite_add_tcase (s, tc_chain);
938   tcase_add_test (tc_chain, test_rtspconnection_tunnel_setup);
939   tcase_add_test (tc_chain, test_rtspconnection_tunnel_setup_post_first);
940   tcase_add_test (tc_chain, test_rtspconnection_send_receive);
941   tcase_add_test (tc_chain, test_rtspconnection_send_receive_check_headers);
942   tcase_add_test (tc_chain, test_rtspconnection_connect);
943   tcase_add_test (tc_chain, test_rtspconnection_poll);
944   tcase_add_test (tc_chain, test_rtspconnection_backlog);
945   tcase_add_test (tc_chain, test_rtspconnection_ip);
946   tcase_add_test (tc_chain, test_rtspconnection_send_receive_content_length);
947 
948   return s;
949 }
950 
951 GST_CHECK_MAIN (rtspconnection);
952