예제 #1
0
/*
 * Complete data
 */
static int
iptv_http_complete
  ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  char *url, *url2, *s, *p;
  url_t u;
  int r;

  if (im->im_m3u_header) {
    im->im_m3u_header = 0;
    sbuf_append(&im->mm_iptv_buffer, "", 1);
    url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
    sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
    if (url == NULL) {
      tvherror("iptv", "m3u contents parsing failed");
      return 0;
    }
    urlinit(&u);
    if (url[0] == '/') {
      s = strdupa(im->mm_iptv_url_raw);
      if ((p = strchr(s, '/')) != NULL)
        *p = '\0';
      if (!urlparse(s, &u))
        goto invalid;
      url2 = malloc(512);
      url2[0] = '\0';
      if ((p = http_arg_get(&hc->hc_args, "Host")) != NULL) {
        snprintf(url2, 512, "%s://%s%s",
                 hc->hc_ssl ? "https" : "http", p, url);
      } else if (im->mm_iptv_url_raw) {
        snprintf(url2, 512, "%s%s", s, url);
      }
      free(url);
      url = url2;
      urlinit(&u);
    }
    if (!urlparse(url, &u)) {
      hc->hc_keepalive = 0;
      r = http_client_simple_reconnect(hc, &u, HTTP_VERSION_1_1);
      if (r < 0)
        tvherror("iptv", "cannot reopen http client: %d'", r);
    } else {
invalid:
      tvherror("iptv", "m3u url invalid '%s'", url);
    }
    urlreset(&u);
    free(url);
    return 0;
  }
  return 0;
}
예제 #2
0
파일: satip.c 프로젝트: Akheon23/tvheadend
static void
satip_discovery_static(const char *descurl)
{
  satip_discovery_t *d;

  lock_assert(&global_lock);

  if (satip_device_find_by_descurl(descurl))
    return;
  d = calloc(1, sizeof(satip_discovery_t));
  if (urlparse(descurl, &d->url)) {
    satip_discovery_destroy(d, 0);
    return;
  }
  d->myaddr   = strdup("");
  d->location = strdup(descurl);
  d->server   = strdup("");
  d->uuid     = strdup("");
  d->bootid   = strdup("");
  d->configid = strdup("");
  d->deviceid = strdup("");
  TAILQ_INSERT_TAIL(&satip_discoveries, d, disc_link);
  satip_discoveries_count++;
  satip_discovery_timerq_cb(NULL);
}
예제 #3
0
/*
 * Complete data
 */
static int
iptv_http_complete
  ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  char *url;
  url_t u;
  int r;

  if (im->im_m3u_header) {
    im->im_m3u_header = 0;
    sbuf_append(&im->mm_iptv_buffer, "", 1);
    url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
    sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
    if (url == NULL) {
      tvherror("iptv", "m3u contents parsing failed");
      return 0;
    }
    urlinit(&u);
    if (!urlparse(url, &u)) {
      hc->hc_keepalive = 0;
      r = http_client_simple_reconnect(hc, &u);
      if (r < 0)
        tvherror("iptv", "cannot reopen http client: %d'", r);
    } else {
      tvherror("iptv", "m3u url invalid '%s'", url);
    }
    urlreset(&u);
    free(url);
    return 0;
  }
  return 0;
}
예제 #4
0
파일: download.c 프로젝트: Ferni7/tvheadend
static void
download_fetch(void *aux)
{
  download_t *dn = aux;
  http_client_t *hc;
  url_t u;

  urlinit(&u);

  if (dn->url == NULL)
    goto done;

  if (strncmp(dn->url, "file://", 7) == 0) {
    download_file(dn, dn->url + 7);
    goto done;
  }

  if (strncmp(dn->url, "pipe://", 7) == 0) {
    download_pipe(dn, dn->url + 7);
    goto done;
  }

  if (dn->http_client) {
    http_client_close(dn->http_client);
    dn->http_client = NULL;
  }

  if (urlparse(dn->url, &u) < 0) {
    tvherror(dn->log, "wrong url");
    goto stop;
  }
  hc = http_client_connect(dn, HTTP_VERSION_1_1, u.scheme, u.host, u.port, NULL);
  if (hc == NULL) {
    tvherror(dn->log, "unable to open http client");
    goto stop;
  }
  hc->hc_handle_location = 1;
  hc->hc_data_limit = 1024*1024;
  hc->hc_data_complete = download_fetch_complete;
  http_client_register(hc);
  http_client_ssl_peer_verify(hc, dn->ssl_peer_verify);
  if (http_client_simple(hc, &u) < 0) {
    http_client_close(hc);
    tvherror(dn->log, "unable to send http command");
    goto stop;
  }

  dn->http_client = hc;
  goto done;

stop:
  if (dn->stop)
    dn->stop(dn->aux);
done:
  urlreset(&u);
}
예제 #5
0
파일: download.c 프로젝트: Ferni7/tvheadend
static int
download_fetch_complete(http_client_t *hc)
{
  download_t *dn = hc->hc_aux;
  const char *last_url = NULL;
  url_t u;

  switch (hc->hc_code) {
  case HTTP_STATUS_MOVED:
  case HTTP_STATUS_FOUND:
  case HTTP_STATUS_SEE_OTHER:
  case HTTP_STATUS_NOT_MODIFIED:
    return 0;
  }

  urlinit(&u);
  if (!urlparse(dn->url, &u)) {
    last_url = strrchr(u.path, '/');
    if (last_url)
      last_url++;
  }

  pthread_mutex_lock(&global_lock);

  if (dn->http_client == NULL)
    goto out;

  if (hc->hc_code == HTTP_STATUS_OK && hc->hc_result == 0 && hc->hc_data_size > 0)
    dn->process(dn->aux, last_url, hc->hc_url, hc->hc_data, hc->hc_data_size);
  else
    tvherror(dn->log, "unable to fetch data from url [%d-%d/%zd]",
             hc->hc_code, hc->hc_result, hc->hc_data_size);

  /* note: http_client_close must be called outside http_client callbacks */
  gtimer_arm(&dn->fetch_timer, download_fetch_done, hc, 0);

out:
  pthread_mutex_unlock(&global_lock);

  urlreset(&u);
  return 0;
}
예제 #6
0
파일: satip.c 프로젝트: Akheon23/tvheadend
static void
satip_discovery_service_received
  (uint8_t *data, size_t len, udp_connection_t *conn,
   struct sockaddr_storage *storage)
{
  char *buf, *ptr, *saveptr;
  char *argv[10];
  char *st = NULL;
  char *location = NULL;
  char *server = NULL;
  char *uuid = NULL;
  char *bootid = NULL;
  char *configid = NULL;
  char *deviceid = NULL;
  char sockbuf[128];
  satip_discovery_t *d;
  int n, i;

  if (len > 8191 || satip_discoveries_count > 100)
    return;
  buf = alloca(len+1);
  memcpy(buf, data, len);
  buf[len] = '\0';
  ptr = strtok_r(buf, "\r\n", &saveptr);
  /* Request decoder */
  if (ptr) {
    if (http_tokenize(ptr, argv, 3, -1) != 3)
      return;
    if (conn->multicast) {
      if (strcmp(argv[0], "NOTIFY"))
        return;
      if (strcmp(argv[1], "*"))
        return;
      if (strcmp(argv[2], "HTTP/1.1"))
        return;
    } else {
      if (strcmp(argv[0], "HTTP/1.1"))
        return;
      if (strcmp(argv[1], "200"))
        return;
    }
    ptr = strtok_r(NULL, "\r\n", &saveptr);
  }
  /* Header decoder */
  while (1) {
    if (ptr == NULL)
      break;
    if (http_tokenize(ptr, argv, 2, ':') == 2) {
      if (strcmp(argv[0], "ST") == 0)
        st = argv[1];
      else if (strcmp(argv[0], "LOCATION") == 0)
        location = argv[1];
      else if (strcmp(argv[0], "SERVER") == 0)
        server = argv[1];
      else if (strcmp(argv[0], "BOOTID.UPNP.ORG") == 0)
        bootid = argv[1];
      else if (strcmp(argv[0], "CONFIGID.UPNP.ORG") == 0)
        configid = argv[1];
      else if (strcmp(argv[0], "DEVICEID.SES.COM") == 0)
        deviceid = argv[1];
      else if (strcmp(argv[0], "USN") == 0) {
        n = http_tokenize(argv[1], argv, ARRAY_SIZE(argv), ':');
        for (i = 0; i < n-1; i++)
          if (argv[i] && strcmp(argv[i], "uuid") == 0) {
            uuid = argv[++i];
            break;
          }
      }
    }
    ptr = strtok_r(NULL, "\r\n", &saveptr);
  }
  /* Sanity checks */
  if (st == NULL || strcmp(st, "urn:ses-com:device:SatIPServer:1"))
    goto add_uuid;
  if (uuid == NULL || strlen(uuid) < 16 || satip_server_match_uuid(uuid))
    goto add_uuid;
  if (location == NULL || strncmp(location, "http://", 7))
    goto add_uuid;
  if (bootid == NULL || configid == NULL || server == NULL)
    goto add_uuid;

  /* Forward information to next layer */

  d = calloc(1, sizeof(satip_discovery_t));
  if (inet_ntop(conn->ip.ss_family, IP_IN_ADDR(conn->ip),
                sockbuf, sizeof(sockbuf)) == NULL) {
    satip_discovery_destroy(d, 0);
    return;
  }
  d->myaddr   = strdup(sockbuf);
  d->location = strdup(location);
  d->server   = strdup(server);
  d->uuid     = strdup(uuid);
  d->bootid   = strdup(bootid);
  d->configid = strdup(configid);
  d->deviceid = strdup(deviceid ? deviceid : "");
  if (urlparse(d->location, &d->url)) {
    satip_discovery_destroy(d, 0);
    return;
  }

  pthread_mutex_lock(&global_lock);  
  i = 1;
  if (!satip_discovery_find(d) && !satip_device_find(d->uuid)) {
    TAILQ_INSERT_TAIL(&satip_discoveries, d, disc_link);
    satip_discoveries_count++;
    gtimer_arm_ms(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 250);
    i = 0;
  }
  pthread_mutex_unlock(&global_lock);
  if (i) /* duplicate */
    satip_discovery_destroy(d, 0);
  return;

add_uuid:
  if (deviceid == NULL || uuid == NULL)
    return;
  /* if new uuid was discovered, retrigger MSEARCH */
  pthread_mutex_lock(&global_lock);
  if (!satip_device_find(uuid))
    gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 5);
  pthread_mutex_unlock(&global_lock);
}