Пример #1
0
static void
gst_curl_http_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstCurlHttpSink *sink;

  g_return_if_fail (GST_IS_CURL_HTTP_SINK (object));
  sink = GST_CURL_HTTP_SINK (object);

  switch (prop_id) {
    case PROP_PROXY:
      g_value_set_string (value, sink->proxy);
      break;
    case PROP_PROXY_PORT:
      g_value_set_int (value, sink->proxy_port);
      break;
    case PROP_PROXY_USER_NAME:
      g_value_set_string (value, sink->proxy_user);
      break;
    case PROP_PROXY_USER_PASSWD:
      g_value_set_string (value, sink->proxy_passwd);
      break;
    case PROP_USE_CONTENT_LENGTH:
      g_value_set_boolean (value, sink->use_content_length);
      break;
    case PROP_CONTENT_TYPE:
      g_value_set_string (value, sink->content_type);
      break;
    default:
      GST_DEBUG_OBJECT (sink, "invalid property id");
      break;
  }
}
Пример #2
0
static gboolean
gst_curl_http_sink_set_options_unlocked (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  GstCurlTlsSinkClass *parent_class;

  /* proxy settings */
  if (sink->proxy != NULL && strlen (sink->proxy)) {
    if (!proxy_setup (bcsink)) {
      return FALSE;
    }
  }

  curl_easy_setopt (bcsink->curl, CURLOPT_POST, 1L);

  /* FIXME: check user & passwd */
  curl_easy_setopt (bcsink->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

  parent_class = GST_CURL_TLS_SINK_GET_CLASS (sink);

  if (g_str_has_prefix (bcsink->url, "https://")) {
    return parent_class->set_options_unlocked (bcsink);
  }

  return TRUE;
}
Пример #3
0
static gboolean
gst_curl_http_sink_set_header_unlocked (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  gchar *tmp;
  CURLcode res;

  if (sink->header_list) {
    curl_slist_free_all (sink->header_list);
    sink->header_list = NULL;
  }

  if (!sink->proxy_headers_set && sink->use_proxy) {
    sink->header_list = curl_slist_append (sink->header_list,
        "Content-Length: 0");
    sink->proxy_headers_set = TRUE;
    goto set_headers;
  }

  if (sink->use_content_length) {
    /* if content length is used we assume that every buffer is one
     * entire file, which is the case when uploading several jpegs */
    tmp =
        g_strdup_printf ("Content-Length: %d", (int) bcsink->transfer_buf->len);
    sink->header_list = curl_slist_append (sink->header_list, tmp);
    g_free (tmp);
  } else {
    /* when sending a POST request to a HTTP 1.1 server, you can send data
     * without knowing the size before starting the POST if you use chunked
     * encoding */
    sink->header_list = curl_slist_append (sink->header_list,
        "Transfer-Encoding: chunked");
  }

  tmp = g_strdup_printf ("Content-Type: %s", sink->content_type);
  sink->header_list = curl_slist_append (sink->header_list, tmp);
  g_free (tmp);

set_headers:

  tmp = g_strdup_printf ("Content-Disposition: attachment; filename="
      "\"%s\"", bcsink->file_name);
  sink->header_list = curl_slist_append (sink->header_list, tmp);
  g_free (tmp);
  res = curl_easy_setopt (bcsink->curl, CURLOPT_HTTPHEADER, sink->header_list);
  if (res != CURLE_OK) {
    bcsink->error = g_strdup_printf ("failed to set HTTP headers: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  return TRUE;
}
Пример #4
0
// FIXME check this: why critical when no mime is set???
static void
gst_curl_http_sink_set_mime_type (GstCurlBaseSink * bcsink, GstCaps * caps)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  GstStructure *structure;
  const gchar *mime_type;

  if (sink->content_type != NULL) {
    return;
  }

  structure = gst_caps_get_structure (caps, 0);
  mime_type = gst_structure_get_name (structure);
  sink->content_type = g_strdup (mime_type);
}
Пример #5
0
static gboolean
gst_curl_http_sink_transfer_verify_response_code (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  glong resp;

  curl_easy_getinfo (bcsink->curl, CURLINFO_RESPONSE_CODE, &resp);
  GST_DEBUG_OBJECT (sink, "response code: %ld", resp);

  if (resp < 100 || resp >= 300) {
    bcsink->error = g_strdup_printf ("HTTP response error: (received: %ld)",
        resp);
    return FALSE;
  }

  return TRUE;
}
Пример #6
0
static void
gst_curl_http_sink_finalize (GObject * gobject)
{
  GstCurlHttpSink *this = GST_CURL_HTTP_SINK (gobject);

  GST_DEBUG ("finalizing curlhttpsink");
  g_free (this->proxy);
  g_free (this->proxy_user);
  g_free (this->proxy_passwd);
  g_free (this->content_type);

  if (this->header_list) {
    curl_slist_free_all (this->header_list);
    this->header_list = NULL;
  }

  G_OBJECT_CLASS (parent_class)->finalize (gobject);
}
Пример #7
0
static void
gst_curl_http_sink_transfer_prepare_poll_wait (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);

  if (!sink->proxy_conn_established
      && (sink->proxy_resp != RESPONSE_CONNECT_PROXY)
      && sink->proxy_auth) {
    curl_easy_getinfo (bcsink->curl, CURLINFO_HTTP_CONNECTCODE,
        &sink->proxy_resp);
    if (sink->proxy_resp == RESPONSE_CONNECT_PROXY) {
      GST_LOG ("received HTTP/1.0 200 Connection Established");
      /* Workaround: redefine HTTP headers before connecting to HTTP server.
       * When talking to proxy, the Content-Length: 0 is send with the request.
       */
      curl_multi_remove_handle (bcsink->multi_handle, bcsink->curl);
      gst_curl_http_sink_set_header_unlocked (bcsink);
      curl_multi_add_handle (bcsink->multi_handle, bcsink->curl);
      sink->proxy_conn_established = TRUE;
    }
  }
}
Пример #8
0
static gboolean
gst_curl_http_sink_set_options_unlocked (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  GstCurlTlsSinkClass *parent_class;
  CURLcode res;

  /* proxy settings */
  if (sink->proxy != NULL) {
    if (!proxy_setup (bcsink)) {
      return FALSE;
    }
  }

  res = curl_easy_setopt (bcsink->curl, CURLOPT_POST, 1L);
  if (res != CURLE_OK) {
    bcsink->error = g_strdup_printf ("failed to set HTTP POST: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  /* FIXME: check user & passwd */
  res = curl_easy_setopt (bcsink->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  if (res != CURLE_OK) {
    bcsink->error =
        g_strdup_printf ("failed to set HTTP authentication methods: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  parent_class = GST_CURL_TLS_SINK_GET_CLASS (sink);

  if (g_str_has_prefix (bcsink->url, "https://")) {
    return parent_class->set_options_unlocked (bcsink);
  }

  return TRUE;
}
Пример #9
0
static gboolean
proxy_setup (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);

  if (curl_easy_setopt (bcsink->curl, CURLOPT_PROXY, sink->proxy)
      != CURLE_OK) {
    return FALSE;
  }

  if (curl_easy_setopt (bcsink->curl, CURLOPT_PROXYPORT, sink->proxy_port)
      != CURLE_OK) {
    return FALSE;
  }

  if (sink->proxy_user != NULL &&
      strlen (sink->proxy_user) &&
      sink->proxy_passwd != NULL && strlen (sink->proxy_passwd)) {
    curl_easy_setopt (bcsink->curl, CURLOPT_PROXYUSERNAME, sink->proxy_user);
    curl_easy_setopt (bcsink->curl, CURLOPT_PROXYPASSWORD, sink->proxy_passwd);
    curl_easy_setopt (bcsink->curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    sink->proxy_auth = TRUE;
  }

  if (g_str_has_prefix (bcsink->url, "https://")) {
    /* tunnel all operations through a given HTTP proxy */
    if (curl_easy_setopt (bcsink->curl, CURLOPT_HTTPPROXYTUNNEL, 1L)
        != CURLE_OK) {
      return FALSE;
    }
  }

  sink->use_proxy = TRUE;

  return TRUE;
}
Пример #10
0
static gboolean
proxy_setup (GstCurlBaseSink * bcsink)
{
  GstCurlHttpSink *sink = GST_CURL_HTTP_SINK (bcsink);
  CURLcode res;

  res = curl_easy_setopt (bcsink->curl, CURLOPT_PROXY, sink->proxy);
  if (res != CURLE_OK) {
    bcsink->error = g_strdup_printf ("failed to set proxy: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  res = curl_easy_setopt (bcsink->curl, CURLOPT_PROXYPORT, sink->proxy_port);
  if (res != CURLE_OK) {
    bcsink->error = g_strdup_printf ("failed to set proxy port: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  if (sink->proxy_user != NULL &&
      strlen (sink->proxy_user) &&
      sink->proxy_passwd != NULL && strlen (sink->proxy_passwd)) {
    res = curl_easy_setopt (bcsink->curl, CURLOPT_PROXYUSERNAME,
        sink->proxy_user);
    if (res != CURLE_OK) {
      bcsink->error = g_strdup_printf ("failed to set proxy user name: %s",
          curl_easy_strerror (res));
      return FALSE;
    }

    res = curl_easy_setopt (bcsink->curl, CURLOPT_PROXYPASSWORD,
        sink->proxy_passwd);
    if (res != CURLE_OK) {
      bcsink->error = g_strdup_printf ("failed to set proxy password: %s",
          curl_easy_strerror (res));
      return FALSE;
    }

    res = curl_easy_setopt (bcsink->curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
    if (res != CURLE_OK) {
      bcsink->error =
          g_strdup_printf ("failed to set proxy authentication method: %s",
          curl_easy_strerror (res));
      return FALSE;
    }

    sink->proxy_auth = TRUE;
  }

  if (g_str_has_prefix (bcsink->url, "https://")) {
    /* tunnel all operations through a given HTTP proxy */
    res = curl_easy_setopt (bcsink->curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
    if (res != CURLE_OK) {
      bcsink->error = g_strdup_printf ("failed to set HTTP proxy tunnel: %s",
          curl_easy_strerror (res));
      return FALSE;
    }
  }

  sink->use_proxy = TRUE;

  return TRUE;
}
Пример #11
0
static void
gst_curl_http_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCurlHttpSink *sink;
  GstState cur_state;

  g_return_if_fail (GST_IS_CURL_HTTP_SINK (object));
  sink = GST_CURL_HTTP_SINK (object);

  gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
  if (cur_state != GST_STATE_PLAYING && cur_state != GST_STATE_PAUSED) {
    GST_OBJECT_LOCK (sink);

    switch (prop_id) {
      case PROP_PROXY:
        g_free (sink->proxy);
        sink->proxy = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "proxy set to %s", sink->proxy);
        break;
      case PROP_PROXY_PORT:
        sink->proxy_port = g_value_get_int (value);
        GST_DEBUG_OBJECT (sink, "proxy port set to %d", sink->proxy_port);
        break;
      case PROP_PROXY_USER_NAME:
        g_free (sink->proxy_user);
        sink->proxy_user = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "proxy user set to %s", sink->proxy_user);
        break;
      case PROP_PROXY_USER_PASSWD:
        g_free (sink->proxy_passwd);
        sink->proxy_passwd = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "proxy password set to %s", sink->proxy_passwd);
        break;
      case PROP_USE_CONTENT_LENGTH:
        sink->use_content_length = g_value_get_boolean (value);
        GST_DEBUG_OBJECT (sink, "use_content_length set to %d",
            sink->use_content_length);
        break;
      case PROP_CONTENT_TYPE:
        g_free (sink->content_type);
        sink->content_type = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "content type set to %s", sink->content_type);
        break;
      default:
        GST_DEBUG_OBJECT (sink, "invalid property id %d", prop_id);
        break;
    }

    GST_OBJECT_UNLOCK (sink);

    return;
  }

  /* in PLAYING or PAUSED state */
  GST_OBJECT_LOCK (sink);

  switch (prop_id) {
    case PROP_CONTENT_TYPE:
      g_free (sink->content_type);
      sink->content_type = g_value_dup_string (value);
      GST_DEBUG_OBJECT (sink, "content type set to %s", sink->content_type);
      break;
    default:
      GST_WARNING_OBJECT (sink, "cannot set property when PLAYING");
      break;
  }

  GST_OBJECT_UNLOCK (sink);
}