diff -urN gst-plugins-0.8.7/gst/tcp/gsthttpclientsrc.c gst-plugins-0.8.7-httpsrc1/gst/tcp/gsthttpclientsrc.c
--- gst-plugins-0.8.7/gst/tcp/gsthttpclientsrc.c	1969-12-31 19:00:00.000000000 -0500
+++ gst-plugins-0.8.7-httpsrc1/gst/tcp/gsthttpclientsrc.c	2005-03-02 11:08:24.546323513 -0500
@@ -0,0 +1,655 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst-i18n-plugin.h>
+#include "gsttcp.h"
+#include "gsthttpclientsrc.h"
+#include <string.h>             /* memset */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+
+#ifdef HAVE_FIONREAD_IN_SYS_FILIO
+#include <sys/filio.h>
+#endif
+
+GST_DEBUG_CATEGORY (httpclientsrc_debug);
+#define GST_CAT_DEFAULT httpclientsrc_debug
+
+#define MAX_READ_SIZE			4 * 1024
+
+/* elementfactory information */
+static GstElementDetails gst_httpclientsrc_details =
+GST_ELEMENT_DETAILS ("HTTP Client source",
+    "Source/Network",
+    "Receive data as a client over the network via HTTP",
+    "Jamey Hicks <jamey dot hicks at hp dot com> based on tcpclientsrc by Thomas Vander Stichele <thomas at apestaart dot org>");
+
+/* HttpclientSrc signals and args */
+enum
+{
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_LOCATION,
+  ARG_METHOD,
+  ARG_PROTOCOL
+};
+
+#define HTTP_DEFAULT_METHOD "GET"
+
+static void gst_httpclientsrc_base_init (gpointer g_class);
+static void gst_httpclientsrc_class_init (GstHttpclientSrc * klass);
+static void gst_httpclientsrc_init (GstHttpclientSrc * httpclientsrc);
+
+static GstCaps *gst_httpclientsrc_getcaps (GstPad * pad);
+
+static GstData *gst_httpclientsrc_get (GstPad * pad);
+static GstElementStateReturn gst_httpclientsrc_change_state (GstElement *
+    element);
+
+static void gst_httpclientsrc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_httpclientsrc_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_httpclientsrc_set_clock (GstElement * element, GstClock * clock);
+
+static GstElementClass *parent_class = NULL;
+
+/*static guint gst_httpclientsrc_signals[LAST_SIGNAL] = { 0 }; */
+
+GType
+gst_httpclientsrc_get_type (void)
+{
+  static GType httpclientsrc_type = 0;
+
+
+  if (!httpclientsrc_type) {
+    static const GTypeInfo httpclientsrc_info = {
+      sizeof (GstHttpclientSrcClass),
+      gst_httpclientsrc_base_init,
+      NULL,
+      (GClassInitFunc) gst_httpclientsrc_class_init,
+      NULL,
+      NULL,
+      sizeof (GstHttpclientSrc),
+      0,
+      (GInstanceInitFunc) gst_httpclientsrc_init,
+      NULL
+    };
+
+    httpclientsrc_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstHttpclientSrc",
+        &httpclientsrc_info, 0);
+  }
+  return httpclientsrc_type;
+}
+
+static void
+gst_httpclientsrc_base_init (gpointer g_class)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+  gst_element_class_set_details (element_class, &gst_httpclientsrc_details);
+}
+
+static void
+gst_httpclientsrc_class_init (GstHttpclientSrc * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
+      g_param_spec_string ("location", "Source Location (URL)",
+          "URL of the data to read", NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_METHOD,
+      g_param_spec_string ("method", "HTTP METHOD, defaults to GET",
+          "Method of the read request", NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, ARG_PROTOCOL,
+      g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in",
+          GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_NONE,
+          G_PARAM_READWRITE));
+
+  gobject_class->set_property = gst_httpclientsrc_set_property;
+  gobject_class->get_property = gst_httpclientsrc_get_property;
+
+  gstelement_class->change_state = gst_httpclientsrc_change_state;
+  gstelement_class->set_clock = gst_httpclientsrc_set_clock;
+
+  GST_DEBUG_CATEGORY_INIT (httpclientsrc_debug, "httpclientsrc", 0,
+      "HTTP Client Source");
+}
+
+static void
+gst_httpclientsrc_set_clock (GstElement * element, GstClock * clock)
+{
+  GstHttpclientSrc *httpclientsrc;
+
+  httpclientsrc = GST_HTTPCLIENTSRC (element);
+
+  httpclientsrc->clock = clock;
+}
+
+static void
+gst_httpclientsrc_init (GstHttpclientSrc * this)
+{
+  /* create the src pad */
+  this->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+  gst_element_add_pad (GST_ELEMENT (this), this->srcpad);
+  gst_pad_set_get_function (this->srcpad, gst_httpclientsrc_get);
+  gst_pad_set_getcaps_function (this->srcpad, gst_httpclientsrc_getcaps);
+
+  this->port = TCP_DEFAULT_PORT;
+  this->method = g_strdup(HTTP_DEFAULT_METHOD);
+  this->location = NULL;
+  this->host = NULL;
+  this->clock = NULL;
+  this->sock_fd = -1;
+  this->protocol = GST_TCP_PROTOCOL_TYPE_NONE;
+  this->curoffset = 0;
+  this->caps = NULL;
+
+  GST_FLAG_UNSET (this, GST_HTTPCLIENTSRC_OPEN);
+}
+
+static GstCaps *
+gst_httpclientsrc_getcaps (GstPad * pad)
+{
+  GstHttpclientSrc *src;
+  GstCaps *caps = NULL;
+
+  src = GST_HTTPCLIENTSRC (GST_OBJECT_PARENT (pad));
+
+  if (!GST_FLAG_IS_SET (src, GST_HTTPCLIENTSRC_OPEN))
+    caps = gst_caps_new_any ();
+  else if (src->caps)
+    caps = gst_caps_copy (src->caps);
+  else
+    caps = gst_caps_new_any ();
+  GST_DEBUG_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
+  g_assert (GST_IS_CAPS (caps));
+  return caps;
+}
+
+static GstData *
+gst_httpclientsrc_get (GstPad * pad)
+{
+  GstHttpclientSrc *src;
+  size_t readsize;
+  int ret;
+
+  GstData *data = NULL;
+  GstBuffer *buf = NULL;
+
+  g_return_val_if_fail (pad != NULL, NULL);
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  src = GST_HTTPCLIENTSRC (GST_OBJECT_PARENT (pad));
+  g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_HTTPCLIENTSRC_OPEN), NULL);
+
+  /* try to negotiate here */
+  if (!gst_pad_is_negotiated (pad)) {
+    if (GST_PAD_LINK_FAILED (gst_pad_renegotiate (pad))) {
+      GST_ELEMENT_ERROR (src, CORE, NEGOTIATION, (NULL), GST_ERROR_SYSTEM);
+      gst_buffer_unref (buf);
+      return GST_DATA (gst_event_new (GST_EVENT_EOS));
+    }
+  }
+
+  /* if we have a left over buffer after a discont, return that */
+  if (src->buffer_after_discont) {
+    buf = src->buffer_after_discont;
+    GST_LOG_OBJECT (src,
+        "Returning buffer after discont of size %d, ts %"
+        GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
+        ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
+        GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
+        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
+        GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf));
+    src->buffer_after_discont = NULL;
+    return GST_DATA (buf);
+  }
+
+  /* read the buffer header if we're using a protocol */
+  switch (src->protocol) {
+      fd_set testfds;
+
+    case GST_TCP_PROTOCOL_TYPE_NONE:
+      /* do a blocking select on the socket */
+      FD_ZERO (&testfds);
+      FD_SET (src->sock_fd, &testfds);
+      ret = select (src->sock_fd + 1, &testfds, (fd_set *) 0, (fd_set *) 0, 0);
+      /* no action (0) is an error too in our case */
+      if (ret <= 0) {
+        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
+            ("select failed: %s", g_strerror (errno)));
+        return GST_DATA (gst_event_new (GST_EVENT_EOS));
+      }
+
+      /* ask how much is available for reading on the socket */
+      ret = ioctl (src->sock_fd, FIONREAD, &readsize);
+      if (ret < 0) {
+        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
+            ("ioctl failed: %s", g_strerror (errno)));
+        return GST_DATA (gst_event_new (GST_EVENT_EOS));
+      }
+      GST_LOG_OBJECT (src, "ioctl says %d bytes available", readsize);
+      buf = gst_buffer_new_and_alloc (readsize);
+      break;
+    case GST_TCP_PROTOCOL_TYPE_GDP:
+      if (!(data = gst_tcp_gdp_read_header (GST_ELEMENT (src), src->sock_fd))) {
+        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
+            ("Could not read data header through GDP"));
+        return GST_DATA (gst_event_new (GST_EVENT_EOS));
+      }
+      if (GST_IS_EVENT (data))
+        return data;
+      buf = GST_BUFFER (data);
+
+      GST_LOG_OBJECT (src, "Going to read data from socket into buffer %p",
+          buf);
+      /* use this new buffer to read data into */
+      readsize = GST_BUFFER_SIZE (buf);
+      break;
+    default:
+      g_warning ("Unhandled protocol type");
+      break;
+  }
+
+  GST_LOG_OBJECT (src, "Reading %d bytes", readsize);
+  ret = gst_tcp_socket_read (src->sock_fd, GST_BUFFER_DATA (buf), readsize);
+  if (ret < 0) {
+    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
+    gst_buffer_unref (buf);
+    return GST_DATA (gst_event_new (GST_EVENT_EOS));
+  }
+
+  /* if we read 0 bytes, and we're blocking, we hit eos */
+  if (ret == 0) {
+    GST_DEBUG ("blocking read returns 0, EOS");
+    gst_buffer_unref (buf);
+    gst_element_set_eos (GST_ELEMENT (src));
+    return GST_DATA (gst_event_new (GST_EVENT_EOS));
+  }
+
+  readsize = ret;
+  GST_BUFFER_SIZE (buf) = readsize;
+  GST_BUFFER_MAXSIZE (buf) = readsize;
+
+  /* FIXME: we could decide to set OFFSET and OFFSET_END for non-protocol
+   * streams to mean the bytes processed */
+
+  /* if this is our first buffer, we need to send a discont with the
+   * given timestamp or the current offset, and store the buffer for
+   * the next iteration through the get loop */
+  if (src->send_discont) {
+    GstClockTime timestamp;
+    GstEvent *event;
+
+    src->send_discont = FALSE;
+    src->buffer_after_discont = buf;
+    /* if the timestamp is valid, send a timed discont
+     * taking into account the incoming buffer's timestamps */
+    timestamp = GST_BUFFER_TIMESTAMP (buf);
+    if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
+      GST_DEBUG_OBJECT (src,
+          "sending discontinuous with timestamp %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (timestamp));
+      event =
+          gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, timestamp, NULL);
+      return GST_DATA (event);
+    }
+    /* otherwise, send an offset discont */
+    GST_DEBUG_OBJECT (src, "sending discontinuous with offset %d",
+        src->curoffset);
+    event =
+        gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset,
+        NULL);
+    return GST_DATA (event);
+  }
+
+  src->curoffset += readsize;
+  GST_LOG_OBJECT (src,
+      "Returning buffer from _get of size %d, ts %"
+      GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
+      ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
+      GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
+      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
+      GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf));
+  return GST_DATA (buf);
+}
+
+static void
+gst_httpclientsrc_set_property (GObject * object, guint prop_id,
+				const GValue * value, GParamSpec * pspec)
+{
+  GstHttpclientSrc *httpclientsrc;
+
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_HTTPCLIENTSRC (object));
+  httpclientsrc = GST_HTTPCLIENTSRC (object);
+
+  GST_DEBUG_OBJECT (httpclientsrc, "setting property %d", prop_id);
+
+  switch (prop_id) {
+  case ARG_LOCATION: {
+    gchar *pathstart = NULL;
+    gchar *location = NULL;
+    gchar *hostport = NULL;
+    gchar *portstart = NULL;
+    int locationlen;
+    g_free (httpclientsrc->location);
+    g_free (httpclientsrc->host);
+    g_free (httpclientsrc->path);
+    httpclientsrc->location = location = g_strdup (g_value_get_string (value));
+    GST_DEBUG_OBJECT (httpclientsrc, "setting location=%s", location);
+
+    if (strncmp(location, "http://", 7) != 0)
+      return;
+    locationlen = strlen(location);
+    hostport = location + 7;
+    GST_DEBUG_OBJECT (httpclientsrc, "    hostport=%s", hostport);
+
+    pathstart = strchr(hostport, '/');
+    GST_DEBUG_OBJECT (httpclientsrc, "    pathstart=%s", pathstart);
+
+    if (pathstart) {
+      httpclientsrc->path = g_strdup(pathstart);
+    } else {
+      httpclientsrc->path = g_strdup("/");
+      pathstart = location+locationlen;
+    }
+    hostport = g_strndup(hostport, pathstart - hostport);
+    portstart = strrchr(hostport, ':');
+    GST_DEBUG_OBJECT (httpclientsrc, "    hostport=%s portstart=%s", hostport, portstart);
+    if (portstart != NULL) {
+      httpclientsrc->host = g_strndup(hostport, portstart - hostport);
+      httpclientsrc->port = strtoul(portstart+1, NULL, 0);
+      g_free(hostport);
+    } else {
+      httpclientsrc->host = hostport;
+      httpclientsrc->port = 80;
+    }
+    GST_DEBUG_OBJECT (httpclientsrc, "    host=%s port=%d path=%s", httpclientsrc->host, httpclientsrc->port, httpclientsrc->path);
+  } break;
+  case ARG_METHOD:
+    g_free (httpclientsrc->method);
+    httpclientsrc->method = g_strdup (g_value_get_string (value));
+    break;
+  case ARG_PROTOCOL:
+    httpclientsrc->protocol = g_value_get_enum (value);
+    break;
+
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+gst_httpclientsrc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstHttpclientSrc *httpclientsrc;
+
+  g_return_if_fail (GST_IS_HTTPCLIENTSRC (object));
+  httpclientsrc = GST_HTTPCLIENTSRC (object);
+
+  switch (prop_id) {
+    case ARG_LOCATION:
+      g_value_set_string (value, httpclientsrc->location);
+      break;
+    case ARG_METHOD:
+      g_value_set_string (value, httpclientsrc->method);
+      break;
+    case ARG_PROTOCOL:
+      g_value_set_enum (value, httpclientsrc->protocol);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+/* create a socket for connecting to remote server */
+static gboolean
+gst_httpclientsrc_init_receive (GstHttpclientSrc * this)
+{
+  int ret;
+  gchar ip[256];
+  struct addrinfo *addrinfo, *top_addrinfo;
+  int addr_family;
+  gchar *request = NULL;
+
+  GST_DEBUG_OBJECT (this, "getaddrinfo %s", this->host);
+  ret = getaddrinfo(this->host, "http", NULL, &addrinfo);
+  top_addrinfo = addrinfo;
+
+ retry:
+  this->addr_family = addr_family = addrinfo->ai_family;
+  this->server_addrlen = addrinfo->ai_addrlen;
+  memset(&this->server_sockaddr, 0, sizeof(this->server_sockaddr));
+  memcpy(&this->server_sockaddr, addrinfo->ai_addr, addrinfo->ai_addrlen);
+
+  /* create receiving client socket */
+  GST_DEBUG_OBJECT (this, "opening receiving client socket to %s:%d\n",
+      this->host, this->port);
+  if ((this->sock_fd = socket (this->addr_family, SOCK_STREAM, 0)) == -1) {
+    GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
+    return FALSE;
+  }
+  GST_DEBUG_OBJECT (this, "opened receiving client socket with fd %d",
+      this->sock_fd);
+
+  /* look up name if we need to */
+  GST_DEBUG_OBJECT (this, "IP address for host %s is %s", this->host, ip);
+
+  /* fill in port */
+  switch (this->addr_family) {
+  case AF_INET:
+    ((struct sockaddr_in *)&this->server_sockaddr)->sin_port = htons(this->port);
+    inet_ntop(this->addr_family, &(((struct sockaddr_in *)&this->server_sockaddr)->sin_addr), ip, sizeof(ip)); 
+    break;
+  case AF_INET6:
+    ((struct sockaddr_in6 *)&this->server_sockaddr)->sin6_port = htons(this->port);
+    inet_ntop(this->addr_family, &(((struct sockaddr_in6 *)&this->server_sockaddr)->sin6_addr), ip, sizeof(ip)); 
+    break;
+  }
+  if (this->addr_family == AF_INET6) { 
+    int offset = 0;
+    int i;
+    struct in6_addr *in6_addr = &(((struct sockaddr_in6 *)&this->server_sockaddr)->sin6_addr);
+    for (i = 0; i < sizeof(struct in6_addr); i++) {
+      int b = in6_addr->s6_addr[i];
+      offset += sprintf(ip+offset, ":%02x", b);
+    }
+  }
+
+  /* connect to server */
+  GST_DEBUG_OBJECT (this, "connecting to server family=%d ip=%s port=%d sockaddrlen=%d",
+		    this->addr_family, ip, this->port, this->server_addrlen);
+  ret = connect (this->sock_fd, (struct sockaddr *) &this->server_sockaddr, this->server_addrlen);
+
+  if (ret) {
+    switch (errno) {
+      case ECONNREFUSED:
+        GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ,
+            (_("Connection to %s:%d refused."), this->host, this->port),
+            (NULL));
+        if (addrinfo->ai_next == NULL)
+	  return FALSE;
+        break;
+      default:
+        GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
+            ("connect to %s:%d failed: %s", this->host, this->port,
+                g_strerror (errno)));
+        if (addrinfo->ai_next == NULL)
+	  return FALSE;
+        break;
+    }
+    addrinfo = addrinfo->ai_next;
+    if (addrinfo) {
+      GST_DEBUG_OBJECT(this, "retrying with addrinfo %p", addrinfo);
+      goto retry;
+    }
+  }
+
+  /* send request and headers */
+  request = g_strdup_printf("%s %s HTTP/1.0\r\nHost: %s\r\n\r\n",
+			    this->method, this->path, this->host);
+  GST_DEBUG_OBJECT(this, "sending request %s", request);
+  if (gst_tcp_socket_write(this->sock_fd, request, strlen(request)) < 0) {
+        GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
+            ("sending HTTP request to %s failed: %s", this->location,
+                g_strerror (errno)));
+        return FALSE;
+  }
+  g_free(request);
+
+  
+  /* receive and discard headers */
+  {
+    char responseline[12];
+    int rc;
+    /* receive response line (HTTP/1.x NNN) */
+    if ((rc = gst_tcp_socket_read(this->sock_fd, responseline, sizeof(responseline))) < 0) {
+      GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
+			 ("reading HTTP response from %s failed: %s", this->location,
+			  g_strerror (errno)));
+      return FALSE;
+    }
+    GST_DEBUG_OBJECT(this, "got %d byte response %s", rc, responseline);
+
+    enum response_state {
+      RESPONSE_CHAR,
+      RESPONSE_CR,
+      RESPONSE_CRLF,
+      RESPONSE_CRLFCR,
+      RESPONSE_END_OF_HEADERS /* saw crlfcrlf */
+    } response_state = RESPONSE_CHAR;
+    while (response_state != RESPONSE_END_OF_HEADERS) {
+      gchar ch;
+      if (gst_tcp_socket_read(this->sock_fd, &ch, sizeof(ch)) < 0) {
+        GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
+			   ("reading HTTP response from %s failed: %s", this->location,
+			    g_strerror (errno)));
+        return FALSE;
+      }
+      switch (ch) {
+      case '\n':
+	switch (response_state) {
+	case RESPONSE_CR: response_state = RESPONSE_CRLF; break;
+	case RESPONSE_CRLFCR: response_state = RESPONSE_END_OF_HEADERS; break;
+	default: response_state = RESPONSE_CHAR;
+	} break;	
+      case '\r':
+	switch (response_state) {
+	case RESPONSE_CRLF: response_state = RESPONSE_CRLFCR; break;
+	default: response_state = RESPONSE_CR;
+	} break;
+      default:
+	response_state = RESPONSE_CHAR;
+      }
+    }
+  }
+
+  this->send_discont = TRUE;
+  this->buffer_after_discont = NULL;
+  GST_FLAG_SET (this, GST_HTTPCLIENTSRC_OPEN);
+
+  /* get the caps if we're using GDP */
+  if (this->protocol == GST_TCP_PROTOCOL_TYPE_GDP) {
+    /* if we haven't received caps yet, we should get them first */
+    if (!this->caps_received) {
+      GstCaps *caps;
+
+      GST_DEBUG_OBJECT (this, "getting caps through GDP");
+      if (!(caps = gst_tcp_gdp_read_caps (GST_ELEMENT (this), this->sock_fd))) {
+        GST_ELEMENT_ERROR (this, RESOURCE, READ, (NULL),
+            ("Could not read caps through GDP"));
+        return FALSE;
+      }
+      if (!GST_IS_CAPS (caps)) {
+        GST_ELEMENT_ERROR (this, RESOURCE, READ, (NULL),
+            ("Could not read caps through GDP"));
+        return FALSE;
+      }
+      GST_DEBUG_OBJECT (this, "Received caps through GDP: %" GST_PTR_FORMAT,
+          caps);
+      this->caps_received = TRUE;
+      this->caps = caps;
+    }
+  }
+  return TRUE;
+}
+
+static void
+gst_httpclientsrc_close (GstHttpclientSrc * this)
+{
+  if (this->sock_fd != -1) {
+    close (this->sock_fd);
+    this->sock_fd = -1;
+  }
+  this->caps_received = FALSE;
+  if (this->caps) {
+    gst_caps_free (this->caps);
+    this->caps = NULL;
+  }
+  GST_FLAG_UNSET (this, GST_HTTPCLIENTSRC_OPEN);
+}
+
+static GstElementStateReturn
+gst_httpclientsrc_change_state (GstElement * element)
+{
+  g_return_val_if_fail (GST_IS_HTTPCLIENTSRC (element), GST_STATE_FAILURE);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+    if (GST_FLAG_IS_SET (element, GST_HTTPCLIENTSRC_OPEN))
+      gst_httpclientsrc_close (GST_HTTPCLIENTSRC (element));
+  } else {
+    if (!GST_FLAG_IS_SET (element, GST_HTTPCLIENTSRC_OPEN)) {
+      if (!gst_httpclientsrc_init_receive (GST_HTTPCLIENTSRC (element)))
+        return GST_STATE_FAILURE;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
diff -urN gst-plugins-0.8.7/gst/tcp/gsthttpclientsrc.h gst-plugins-0.8.7-httpsrc1/gst/tcp/gsthttpclientsrc.h
--- gst-plugins-0.8.7/gst/tcp/gsthttpclientsrc.h	1969-12-31 19:00:00.000000000 -0500
+++ gst-plugins-0.8.7-httpsrc1/gst/tcp/gsthttpclientsrc.h	2005-03-02 09:47:01.640623151 -0500
@@ -0,0 +1,98 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_HTTPCLIENTSRC_H__
+#define __GST_HTTPCLIENTSRC_H__
+
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <netdb.h>                        /* sockaddr_in */
+#include <netinet/in.h>			  /* sockaddr_in */
+#include <unistd.h>
+#include "gsttcp.h"
+
+#define GST_TYPE_HTTPCLIENTSRC \
+  (gst_httpclientsrc_get_type())
+#define GST_HTTPCLIENTSRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_HTTPCLIENTSRC,GstHttpclientSrc))
+#define GST_HTTPCLIENTSRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_HTTPCLIENTSRC,GstHttpclientSrc))
+#define GST_IS_HTTPCLIENTSRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_HTTPCLIENTSRC))
+#define GST_IS_HTTPCLIENTSRC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_HTTPCLIENTSRC))
+
+typedef struct _GstHttpclientSrc GstHttpclientSrc;
+typedef struct _GstHttpclientSrcClass GstHttpclientSrcClass;
+
+typedef enum GstHttpclientSrcFlags {
+  GST_HTTPCLIENTSRC_OPEN       = GST_ELEMENT_FLAG_LAST,
+
+  GST_HTTPCLIENTSRC_FLAG_LAST,
+} GstHttpclientSrcFlags;
+
+struct _GstHttpclientSrc {
+  GstElement element;
+
+  /* pad */
+  GstPad *srcpad;
+
+  /* server information */
+  int port;
+  int addr_family;
+  gchar *method;
+  gchar *host;
+  gchar *path;
+  gchar *location; /* url */
+  struct sockaddr_storage server_sockaddr;
+  int server_addrlen;
+
+  /* socket */
+  int sock_fd;
+
+  /* number of bytes we've gotten */
+  off_t curoffset;
+
+  GstTCPProtocolType protocol; /* protocol used for reading data */
+  gboolean caps_received;      /* if we have received caps yet */
+  GstCaps *caps;
+  GstClock *clock;
+
+  gboolean send_discont;       /* TRUE when we need to send a discont */
+  GstBuffer *buffer_after_discont; /* temporary storage for buffer */
+};
+
+struct _GstHttpclientSrcClass {
+  GstElementClass parent_class;
+};
+
+GType gst_httpclientsrc_get_type (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GST_HTTPCLIENTSRC_H__ */
diff -urN gst-plugins-0.8.7/gst/tcp/gsttcpplugin.c gst-plugins-0.8.7-httpsrc1/gst/tcp/gsttcpplugin.c
--- gst-plugins-0.8.7/gst/tcp/gsttcpplugin.c	2004-11-05 12:15:10.000000000 -0500
+++ gst-plugins-0.8.7-httpsrc1/gst/tcp/gsttcpplugin.c	2005-03-02 09:59:33.003801791 -0500
@@ -23,6 +23,7 @@
 
 #include "gsttcpsrc.h"
 #include "gsttcpsink.h"
+#include "gsthttpclientsrc.h"
 #include "gsttcpclientsrc.h"
 #include "gsttcpclientsink.h"
 #include "gsttcpserversrc.h"
@@ -59,6 +60,9 @@
   if (!gst_element_register (plugin, "multifdsink", GST_RANK_NONE,
           GST_TYPE_MULTIFDSINK))
     return FALSE;
+  if (!gst_element_register (plugin, "httpclientsrc", GST_RANK_NONE,
+          GST_TYPE_HTTPCLIENTSRC))
+    return FALSE;
 
   GST_DEBUG_CATEGORY_INIT (tcp_debug, "tcp", 0, "TCP calls");
 
diff -urN gst-plugins-0.8.7/gst/tcp/Makefile.am gst-plugins-0.8.7-httpsrc1/gst/tcp/Makefile.am
--- gst-plugins-0.8.7/gst/tcp/Makefile.am	2004-11-02 02:41:44.000000000 -0500
+++ gst-plugins-0.8.7-httpsrc1/gst/tcp/Makefile.am	2005-03-02 09:29:30.125528594 -0500
@@ -18,6 +18,7 @@
 	gsttcp.c \
 	gstfdset.c \
 	gstmultifdsink.c  \
+	gsthttpclientsrc.c \
 	gsttcpclientsrc.c gsttcpclientsink.c \
 	gsttcpserversrc.c gsttcpserversink.c
 
@@ -35,6 +36,7 @@
   gsttcp.h \
   gstfdset.h \
   gstmultifdsink.h  \
+  gsthttpclientsrc.h \
   gsttcpclientsrc.h gsttcpclientsink.h \
   gsttcpserversrc.h gsttcpserversink.h
 
diff -urN gst-plugins-0.8.7/gst/tcp/Makefile.in gst-plugins-0.8.7-httpsrc1/gst/tcp/Makefile.in
--- gst-plugins-0.8.7/gst/tcp/Makefile.in	2005-01-05 05:47:55.000000000 -0500
+++ gst-plugins-0.8.7-httpsrc1/gst/tcp/Makefile.in	2005-03-02 09:33:30.515512648 -0500
@@ -99,7 +99,8 @@
 am_libgsttcp_la_OBJECTS = libgsttcp_la-gsttcpplugin.lo \
 	libgsttcp_la-gsttcpsrc.lo libgsttcp_la-gsttcpsink.lo \
 	libgsttcp_la-gsttcp.lo libgsttcp_la-gstfdset.lo \
-	libgsttcp_la-gstmultifdsink.lo libgsttcp_la-gsttcpclientsrc.lo \
+	libgsttcp_la-gstmultifdsink.lo libgsttcp_la-gsthttpclientsrc.lo \
+	libgsttcp_la-gsttcpclientsrc.lo \
 	libgsttcp_la-gsttcpclientsink.lo \
 	libgsttcp_la-gsttcpserversrc.lo \
 	libgsttcp_la-gsttcpserversink.lo
@@ -730,6 +731,7 @@
 	gsttcp.c \
 	gstfdset.c \
 	gstmultifdsink.c  \
+	gsthttpclientsrc.c \
 	gsttcpclientsrc.c gsttcpclientsink.c \
 	gsttcpserversrc.c gsttcpserversink.c
 
@@ -747,7 +749,7 @@
   gsttcp.h \
   gstfdset.h \
   gstmultifdsink.h  \
-  gsttcpclientsrc.h gsttcpclientsink.h \
+  gsthttpclientsrc.h gsttcpclientsrc.h gsttcpclientsink.h \
   gsttcpserversrc.h gsttcpserversink.h
 
 CLEANFILES = $(BUILT_SOURCES)
@@ -844,6 +846,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcpclientsink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcpclientsrc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsthttpclientsrc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcpplugin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcpserversink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsttcp_la-gsttcpserversrc.Plo@am__quote@
@@ -913,6 +916,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsttcp_la_CFLAGS) $(CFLAGS) -c -o libgsttcp_la-gstmultifdsink.lo `test -f 'gstmultifdsink.c' || echo '$(srcdir)/'`gstmultifdsink.c
 
+libgsttcp_la-gsthttpclientsrc.lo: gsthttpclientsrc.c
+@am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsttcp_la_CFLAGS) $(CFLAGS) -MT libgsttcp_la-gsthttpclientsrc.lo -MD -MP -MF "$(DEPDIR)/libgsttcp_la-gsthttpclientsrc.Tpo" -c -o libgsttcp_la-gsthttpclientsrc.lo `test -f 'gsthttpclientsrc.c' || echo '$(srcdir)/'`gsthttpclientsrc.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgsttcp_la-gsthttpclientsrc.Tpo" "$(DEPDIR)/libgsttcp_la-gsthttpclientsrc.Plo"; else rm -f "$(DEPDIR)/libgsttcp_la-gsthttpclientsrc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gsthttpclientsrc.c' object='libgsttcp_la-gsthttpclientsrc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsttcp_la_CFLAGS) $(CFLAGS) -c -o libgsttcp_la-gsthttpclientsrc.lo `test -f 'gsthttpclientsrc.c' || echo '$(srcdir)/'`gsthttpclientsrc.c
+
 libgsttcp_la-gsttcpclientsrc.lo: gsttcpclientsrc.c
 @am__fastdepCC_TRUE@	if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsttcp_la_CFLAGS) $(CFLAGS) -MT libgsttcp_la-gsttcpclientsrc.lo -MD -MP -MF "$(DEPDIR)/libgsttcp_la-gsttcpclientsrc.Tpo" -c -o libgsttcp_la-gsttcpclientsrc.lo `test -f 'gsttcpclientsrc.c' || echo '$(srcdir)/'`gsttcpclientsrc.c; \
 @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgsttcp_la-gsttcpclientsrc.Tpo" "$(DEPDIR)/libgsttcp_la-gsttcpclientsrc.Plo"; else rm -f "$(DEPDIR)/libgsttcp_la-gsttcpclientsrc.Tpo"; exit 1; fi