diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-03-31 19:00:00 +0200 |
---|---|---|
committer | Wim Taymans <wim@metal.(none)> | 2009-03-31 19:00:00 +0200 |
commit | 8b37dc3eb8fee19fab731e53765c6bc797b0c1ff (patch) | |
tree | f9b7565f6c997ebbee93101c188c2dce33671dad | |
parent | 8be68f983cd10ba1b3a232d214575ef047fb9778 (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.c | 111 | ||||
-rw-r--r-- | gst-libs/gst/rtsp/gstrtspconnection.h | 4 |
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) | |||
683 | write_failed: | 708 | write_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 | } |
688 | eof: | 714 | eof: |
689 | { | 715 | { |
716 | g_free (hostparam); | ||
690 | return GST_RTSP_EEOF; | 717 | return GST_RTSP_EEOF; |
691 | } | 718 | } |
692 | read_error: | 719 | read_error: |
693 | { | 720 | { |
721 | g_free (hostparam); | ||
694 | return res; | 722 | return res; |
695 | } | 723 | } |
696 | timeout: | 724 | timeout: |
697 | { | 725 | { |
726 | g_free (hostparam); | ||
698 | return GST_RTSP_ETIMEOUT; | 727 | return GST_RTSP_ETIMEOUT; |
699 | } | 728 | } |
700 | select_error: | 729 | select_error: |
701 | { | 730 | { |
731 | g_free (hostparam); | ||
702 | return GST_RTSP_ESYS; | 732 | return GST_RTSP_ESYS; |
703 | } | 733 | } |
704 | stopped: | 734 | stopped: |
705 | { | 735 | { |
736 | g_free (hostparam); | ||
706 | return GST_RTSP_EINTR; | 737 | return GST_RTSP_EINTR; |
707 | } | 738 | } |
708 | wrong_result: | 739 | wrong_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 | } |
713 | not_resolved: | 745 | not_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 | } |
718 | connect_failed: | 751 | connect_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 | ||
780 | not_resolved: | 825 | not_resolved: |
781 | { | 826 | { |
782 | GST_ERROR ("could not resolve %s", url->host); | ||
783 | return GST_RTSP_ENET; | 827 | return GST_RTSP_ENET; |
784 | } | 828 | } |
785 | connect_failed: | 829 | connect_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 | } |
791 | tunneling_failed: | 834 | tunneling_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 | */ | ||
2187 | GstRTSPResult | ||
2188 | gst_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 */ |
90 | GstRTSPResult gst_rtsp_connection_flush (GstRTSPConnection *conn, gboolean flush); | 90 | GstRTSPResult gst_rtsp_connection_flush (GstRTSPConnection *conn, gboolean flush); |
91 | 91 | ||
92 | /* HTTP proxy support */ | ||
93 | GstRTSPResult gst_rtsp_connection_set_proxy (GstRTSPConnection *conn, | ||
94 | const gchar *host, guint port); | ||
95 | |||
92 | /* configure authentication data */ | 96 | /* configure authentication data */ |
93 | GstRTSPResult gst_rtsp_connection_set_auth (GstRTSPConnection *conn, GstRTSPAuthMethod method, | 97 | GstRTSPResult gst_rtsp_connection_set_auth (GstRTSPConnection *conn, GstRTSPAuthMethod method, |
94 | const gchar *user, const gchar *pass); | 98 | const gchar *user, const gchar *pass); |