コード例 #1
0
ファイル: iptv_http.c プロジェクト: astrilchuk/tvheadend
/*
 * 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;
}
コード例 #2
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);
}
コード例 #3
0
ファイル: iptv_http.c プロジェクト: flyingfridge/tvheadend
/*
 * 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;
}
コード例 #4
0
ファイル: url.c プロジェクト: cloudy-brain/tvheadend
int
urlparse ( const char *str, url_t *url )
{
    regmatch_t m[16];
    char buf[16];

    if (str == NULL || url == NULL)
        return -1;

    urlreset(url);

    /* Create regexp */
    if (!urlparse_exp) {
        urlparse_exp = calloc(1, sizeof(regex_t));
        if (regcomp(urlparse_exp, URL_RE, REG_ICASE | REG_EXTENDED)) {
            tvherror("url", "failed to compile regexp");
            exit(1);
        }
    }

    /* Execute */
    if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0))
        return -1;

    /* Extract data */
#define copy(x, i)\
  {\
    x = strndup(str+m[i].rm_so, m[i].rm_eo - m[i].rm_so);\
  }(void)0
#define copy_static(x, i)\
  {\
    int len = m[i].rm_eo - m[i].rm_so;\
    if (len >= sizeof(x) - 1)\
      len = sizeof(x) - 1;\
    memcpy(x, str+m[i].rm_so, len);\
    x[len] = 0;\
  }(void)0
    copy(url->scheme, 1);
    copy(url->user,   3);
    copy(url->pass,   5);
    copy(url->host,   6);
    copy(url->path,   9);
    copy_static(buf,  8);
    url->port = atoi(buf);
    copy(url->query, 11);
    copy(url->frag,  13);

    url->raw = strdup(str);

    return 0;
}
コード例 #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_destroy(satip_discovery_t *d, int unlink)
{
  if (d == NULL)
    return;
  if (unlink) {
    satip_discoveries_count--;
    TAILQ_REMOVE(&satip_discoveries, d, disc_link);
  }
  if (d->http_client)
    http_client_close(d->http_client);
  urlreset(&d->url);
  free(d->myaddr);
  free(d->location);
  free(d->server);
  free(d->uuid);
  free(d->bootid);
  free(d->configid);
  free(d->deviceid);
  free(d);
}
コード例 #7
0
ファイル: url.c プロジェクト: cloudy-brain/tvheadend
int
urlparse ( const char *str, url_t *url )
{
    UriParserStateA state;
    UriPathSegmentA *path;
    UriUriA uri;
    char *s, buf[256];

    if (str == NULL || url == NULL)
        return -1;

    urlreset(url);

    /* Parse */
    state.uri = &uri;
    if (uriParseUriA(&state, str) != URI_SUCCESS) {
        uriFreeUriMembersA(&uri);
        return -1;
    }

    /* Store raw */
    url->raw = strdup(str);

    /* Copy */
#define uri_copy(y, x)\
  if (x.first) {\
    size_t len = x.afterLast - x.first;\
    y = strndup(x.first, len);\
  }
#define uri_copy_static(y, x)\
  if (x.first) {\
    size_t len = x.afterLast - x.first;\
    strncpy(y, x.first, len);\
    y[len] = '\0';\
  } else {\
    y[0] = '\0';\
  }
    uri_copy(url->scheme, uri.scheme);
    uri_copy(url->host,   uri.hostText);
    uri_copy(url->user,   uri.userInfo);
    uri_copy(url->query,  uri.query);
    uri_copy(url->frag,   uri.fragment);
    uri_copy_static(buf,  uri.portText);
    if (*buf)
        url->port = atoi(buf);
    else
        url->port = 0;
    path       = uri.pathHead;
    while (path) {
        uri_copy_static(buf, path->text);
        if (url->path)
            url->path = realloc(url->path, strlen(url->path) + strlen(buf) + 2);
        else
            url->path = calloc(1, strlen(buf) + 2);
        strcat(url->path, "/");
        strcat(url->path, buf);
        path = path->next;
    }
    // TODO: query/fragment

    /* Split user/pass */
    if (url->user) {
        s = strstr(url->user, ":");
        if (s) {
            url->pass = strdup(s + 1);
            *s = 0;
        }
    }

    /* Cleanup */
    uriFreeUriMembersA(&uri);
    return 0;
}