summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-03-31 19:00:00 +0200
committerWim Taymans <wim@metal.(none)>2009-03-31 19:00:00 +0200
commit8b37dc3eb8fee19fab731e53765c6bc797b0c1ff (patch)
treef9b7565f6c997ebbee93101c188c2dce33671dad
parent8be68f983cd10ba1b3a232d214575ef047fb9778 (diff)
rtsp: add support for proxies
Add suport for proxy servers. Currently only used for tunneled HTTP connections without authentication.
-rw-r--r--gst-libs/gst/rtsp/gstrtspconnection.c111
-rw-r--r--gst-libs/gst/rtsp/gstrtspconnection.h4
2 files changed, 94 insertions, 21 deletions
diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c
index 6f52ea00c..c9bcea076 100644
--- a/gst-libs/gst/rtsp/gstrtspconnection.c
+++ b/gst-libs/gst/rtsp/gstrtspconnection.c
@@ -192,6 +192,9 @@ struct _GstRTSPConnection
192 192
193 DecodeCtx ctx; 193 DecodeCtx ctx;
194 DecodeCtx *ctxp; 194 DecodeCtx *ctxp;
195
196 gchar *proxy_host;
197 guint proxy_port;
195}; 198};
196 199
197#ifdef G_OS_WIN32 200#ifdef G_OS_WIN32
@@ -537,10 +540,11 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
537 gint retval; 540 gint retval;
538 GstClockTime to; 541 GstClockTime to;
539 gchar *ip; 542 gchar *ip;
540 guint16 port; 543 guint16 port, url_port;
541 gchar codestr[4], *resultstr; 544 gchar codestr[4], *resultstr;
542 gint code; 545 gint code;
543 GstRTSPUrl *url; 546 GstRTSPUrl *url;
547 gchar *hostparam;
544 548
545 /* create a random sessionid */ 549 /* create a random sessionid */
546 for (i = 0; i < TUNNELID_LEN; i++) 550 for (i = 0; i < TUNNELID_LEN; i++)
@@ -548,15 +552,28 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
548 conn->tunnelid[TUNNELID_LEN - 1] = '\0'; 552 conn->tunnelid[TUNNELID_LEN - 1] = '\0';
549 553
550 url = conn->url; 554 url = conn->url;
555 /* get the port from the url */
556 gst_rtsp_url_get_port (url, &url_port);
557
558 if (conn->proxy_host) {
559 hostparam = g_strdup_printf ("Host: %s:%d\r\n", url->host, url_port);
560 ip = conn->proxy_host;
561 port = conn->proxy_port;
562 } else {
563 hostparam = NULL;
564 ip = conn->ip;
565 port = url_port;
566 }
551 567
552 /* */ 568 /* */
553 str = g_strdup_printf ("GET %s%s%s HTTP/1.0\r\n" 569 str = g_strdup_printf ("GET %s%s%s HTTP/1.0\r\n"
570 "%s"
554 "x-sessioncookie: %s\r\n" 571 "x-sessioncookie: %s\r\n"
555 "Accept: application/x-rtsp-tunnelled\r\n" 572 "Accept: application/x-rtsp-tunnelled\r\n"
556 "Pragma: no-cache\r\n" 573 "Pragma: no-cache\r\n"
557 "Cache-Control: no-cache\r\n" "\r\n", 574 "Cache-Control: no-cache\r\n" "\r\n",
558 url->abspath, url->query ? "?" : "", url->query ? url->query : "", 575 url->abspath, url->query ? "?" : "", url->query ? url->query : "",
559 conn->tunnelid); 576 hostparam ? hostparam : "", conn->tunnelid);
560 577
561 /* we start by writing to this fd */ 578 /* we start by writing to this fd */
562 conn->writefd = &conn->fd0; 579 conn->writefd = &conn->fd0;
@@ -634,23 +651,28 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
634 if (res == GST_RTSP_OK) { 651 if (res == GST_RTSP_OK) {
635 /* we got a new ip address */ 652 /* we got a new ip address */
636 if (g_ascii_strcasecmp (key, "x-server-ip-address") == 0) { 653 if (g_ascii_strcasecmp (key, "x-server-ip-address") == 0) {
637 g_free (conn->ip); 654 if (conn->proxy_host) {
638 conn->ip = g_strdup (value); 655 /* if we use a proxy we need to change the destination url */
656 g_free (url->host);
657 url->host = g_strdup (value);
658 g_free (hostparam);
659 hostparam =
660 g_strdup_printf ("Host: %s:%d\r\n", url->host, url_port);
661 } else {
662 /* and resolve the new ip address */
663 if (!(ip = do_resolve (conn->ip)))
664 goto not_resolved;
665 g_free (conn->ip);
666 conn->ip = ip;
667 }
639 } 668 }
640 } 669 }
641 } 670 }
642 line++; 671 line++;
643 } 672 }
644 673
645 if (!(ip = do_resolve (conn->ip)))
646 goto not_resolved;
647
648 /* get the port from the url */
649 gst_rtsp_url_get_port (conn->url, &port);
650
651 /* connect to the host/port */ 674 /* connect to the host/port */
652 res = do_connect (ip, port, &conn->fd1, conn->fdset, timeout); 675 res = do_connect (ip, port, &conn->fd1, conn->fdset, timeout);
653 g_free (ip);
654 if (res != GST_RTSP_OK) 676 if (res != GST_RTSP_OK)
655 goto connect_failed; 677 goto connect_failed;
656 678
@@ -659,6 +681,7 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
659 681
660 /* */ 682 /* */
661 str = g_strdup_printf ("POST %s%s%s HTTP/1.0\r\n" 683 str = g_strdup_printf ("POST %s%s%s HTTP/1.0\r\n"
684 "%s"
662 "x-sessioncookie: %s\r\n" 685 "x-sessioncookie: %s\r\n"
663 "Content-Type: application/x-rtsp-tunnelled\r\n" 686 "Content-Type: application/x-rtsp-tunnelled\r\n"
664 "Pragma: no-cache\r\n" 687 "Pragma: no-cache\r\n"
@@ -667,11 +690,13 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
667 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n" 690 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n"
668 "\r\n", 691 "\r\n",
669 url->abspath, url->query ? "?" : "", url->query ? url->query : "", 692 url->abspath, url->query ? "?" : "", url->query ? url->query : "",
670 conn->tunnelid); 693 hostparam ? hostparam : "", conn->tunnelid);
671 694
672 /* we start by writing to this fd */ 695 /* we start by writing to this fd */
673 conn->writefd = &conn->fd1; 696 conn->writefd = &conn->fd1;
674 697
698 g_free (hostparam);
699
675 res = gst_rtsp_connection_write (conn, (guint8 *) str, strlen (str), timeout); 700 res = gst_rtsp_connection_write (conn, (guint8 *) str, strlen (str), timeout);
676 g_free (str); 701 g_free (str);
677 if (res != GST_RTSP_OK) 702 if (res != GST_RTSP_OK)
@@ -683,41 +708,50 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
683write_failed: 708write_failed:
684 { 709 {
685 GST_ERROR ("write failed (%d)", res); 710 GST_ERROR ("write failed (%d)", res);
711 g_free (hostparam);
686 return res; 712 return res;
687 } 713 }
688eof: 714eof:
689 { 715 {
716 g_free (hostparam);
690 return GST_RTSP_EEOF; 717 return GST_RTSP_EEOF;
691 } 718 }
692read_error: 719read_error:
693 { 720 {
721 g_free (hostparam);
694 return res; 722 return res;
695 } 723 }
696timeout: 724timeout:
697 { 725 {
726 g_free (hostparam);
698 return GST_RTSP_ETIMEOUT; 727 return GST_RTSP_ETIMEOUT;
699 } 728 }
700select_error: 729select_error:
701 { 730 {
731 g_free (hostparam);
702 return GST_RTSP_ESYS; 732 return GST_RTSP_ESYS;
703 } 733 }
704stopped: 734stopped:
705 { 735 {
736 g_free (hostparam);
706 return GST_RTSP_EINTR; 737 return GST_RTSP_EINTR;
707 } 738 }
708wrong_result: 739wrong_result:
709 { 740 {
710 GST_ERROR ("got failure response %d %s", code, resultstr); 741 GST_ERROR ("got failure response %d %s", code, resultstr);
742 g_free (hostparam);
711 return GST_RTSP_ERROR; 743 return GST_RTSP_ERROR;
712 } 744 }
713not_resolved: 745not_resolved:
714 { 746 {
715 GST_ERROR ("could not resolve %s", conn->ip); 747 GST_ERROR ("could not resolve %s", conn->ip);
748 g_free (hostparam);
716 return GST_RTSP_ENET; 749 return GST_RTSP_ENET;
717 } 750 }
718connect_failed: 751connect_failed:
719 { 752 {
720 GST_ERROR ("failed to connect"); 753 GST_ERROR ("failed to connect");
754 g_free (hostparam);
721 return res; 755 return res;
722 } 756 }
723} 757}
@@ -750,20 +784,31 @@ gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
750 784
751 url = conn->url; 785 url = conn->url;
752 786
753 if (!(ip = do_resolve (url->host))) 787 if (conn->proxy_host && conn->tunneled) {
754 goto not_resolved; 788 if (!(ip = do_resolve (conn->proxy_host))) {
789 GST_ERROR ("could not resolve %s", conn->proxy_host);
790 goto not_resolved;
791 }
792 port = conn->proxy_port;
793 g_free (conn->proxy_host);
794 conn->proxy_host = ip;
795 } else {
796 if (!(ip = do_resolve (url->host))) {
797 GST_ERROR ("could not resolve %s", url->host);
798 goto not_resolved;
799 }
800 /* get the port from the url */
801 gst_rtsp_url_get_port (url, &port);
755 802
756 /* get the port from the url */ 803 g_free (conn->ip);
757 gst_rtsp_url_get_port (url, &port); 804 conn->ip = ip;
805 }
758 806
759 /* connect to the host/port */ 807 /* connect to the host/port */
760 res = do_connect (ip, port, &conn->fd0, conn->fdset, timeout); 808 res = do_connect (ip, port, &conn->fd0, conn->fdset, timeout);
761 if (res != GST_RTSP_OK) 809 if (res != GST_RTSP_OK)
762 goto connect_failed; 810 goto connect_failed;
763 811
764 g_free (conn->ip);
765 conn->ip = ip;
766
767 /* this is our read URL */ 812 /* this is our read URL */
768 conn->readfd = &conn->fd0; 813 conn->readfd = &conn->fd0;
769 814
@@ -779,13 +824,11 @@ gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
779 824
780not_resolved: 825not_resolved:
781 { 826 {
782 GST_ERROR ("could not resolve %s", url->host);
783 return GST_RTSP_ENET; 827 return GST_RTSP_ENET;
784 } 828 }
785connect_failed: 829connect_failed:
786 { 830 {
787 GST_ERROR ("failed to connect"); 831 GST_ERROR ("failed to connect");
788 g_free (ip);
789 return res; 832 return res;
790 } 833 }
791tunneling_failed: 834tunneling_failed:
@@ -1963,6 +2006,7 @@ gst_rtsp_connection_free (GstRTSPConnection * conn)
1963 gst_poll_free (conn->fdset); 2006 gst_poll_free (conn->fdset);
1964 g_timer_destroy (conn->timer); 2007 g_timer_destroy (conn->timer);
1965 gst_rtsp_url_free (conn->url); 2008 gst_rtsp_url_free (conn->url);
2009 g_free (conn->proxy_host);
1966 g_free (conn); 2010 g_free (conn);
1967#ifdef G_OS_WIN32 2011#ifdef G_OS_WIN32
1968 WSACleanup (); 2012 WSACleanup ();
@@ -2129,6 +2173,31 @@ gst_rtsp_connection_flush (GstRTSPConnection * conn, gboolean flush)
2129} 2173}
2130 2174
2131/** 2175/**
2176 * gst_rtsp_connection_set_proxy:
2177 * @conn: a #GstRTSPConnection
2178 * @host: the proxy host
2179 * @port: the proxy port
2180 *
2181 * Set the proxy host and port.
2182 *
2183 * Returns: #GST_RTSP_OK.
2184 *
2185 * Since: 0.10.23
2186 */
2187GstRTSPResult
2188gst_rtsp_connection_set_proxy (GstRTSPConnection * conn,
2189 const gchar * host, guint port)
2190{
2191 g_return_val_if_fail (conn != NULL, GST_RTSP_EINVAL);
2192
2193 g_free (conn->proxy_host);
2194 conn->proxy_host = g_strdup (host);
2195 conn->proxy_port = port;
2196
2197 return GST_RTSP_OK;
2198}
2199
2200/**
2132 * gst_rtsp_connection_set_auth: 2201 * gst_rtsp_connection_set_auth:
2133 * @conn: a #GstRTSPConnection 2202 * @conn: a #GstRTSPConnection
2134 * @method: authentication method 2203 * @method: authentication method
diff --git a/gst-libs/gst/rtsp/gstrtspconnection.h b/gst-libs/gst/rtsp/gstrtspconnection.h
index 372d4af75..9982d1179 100644
--- a/gst-libs/gst/rtsp/gstrtspconnection.h
+++ b/gst-libs/gst/rtsp/gstrtspconnection.h
@@ -89,6 +89,10 @@ GstRTSPResult gst_rtsp_connection_reset_timeout (GstRTSPConnection *conn);
89/* flushing state */ 89/* flushing state */
90GstRTSPResult gst_rtsp_connection_flush (GstRTSPConnection *conn, gboolean flush); 90GstRTSPResult gst_rtsp_connection_flush (GstRTSPConnection *conn, gboolean flush);
91 91
92/* HTTP proxy support */
93GstRTSPResult gst_rtsp_connection_set_proxy (GstRTSPConnection *conn,
94 const gchar *host, guint port);
95
92/* configure authentication data */ 96/* configure authentication data */
93GstRTSPResult gst_rtsp_connection_set_auth (GstRTSPConnection *conn, GstRTSPAuthMethod method, 97GstRTSPResult gst_rtsp_connection_set_auth (GstRTSPConnection *conn, GstRTSPAuthMethod method,
94 const gchar *user, const gchar *pass); 98 const gchar *user, const gchar *pass);