Пример #1
0
static int
vimeo_callback(http_connection_t *hc, const char *remain,
      void *opaque)
{
  state_entry_t *vce;
  static state_entry_t *skel;

  const char *referer = http_arg_get(&hc->hc_args, "referer");
  if(referer == NULL || strcmp(referer, "https://movian.tv/"))
    return 403;

  const char *state = http_arg_get(&hc->hc_req_args, "state");
  const char *code = http_arg_get(&hc->hc_req_args, "code");
  if(state == NULL || code == NULL)
    return 400;

  if(skel == NULL)
    skel = calloc(1, sizeof(state_entry_t));

  skel->se_state = strdup(state);
  skel->se_code = strdup(code);

  pthread_mutex_lock(&state_mutex);

  vce = RB_INSERT_SORTED(&state_entries, skel, se_entry, state_entry_cmp);
  if (vce != NULL)
    vce->se_code = strdup(code);
  else
    skel = NULL;

  pthread_mutex_unlock(&state_mutex);

  return 200;
}
Пример #2
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;
}
Пример #3
0
static int
vimeo_code(http_connection_t *hc, const char *remain,
      void *opaque)
{
  state_entry_t *vce;
  static state_entry_t *skel;

  const char *referer = http_arg_get(&hc->hc_args, "referer");
  if(referer == NULL || strcmp(referer, "https://movian.tv/"))
    return 403;

  const char *state = http_arg_get(&hc->hc_req_args, "state");
  if(state == NULL)
    return 400;

  if(skel == NULL)
    skel = calloc(1, sizeof(state_entry_t));

  skel->se_state = (char *)state;

  pthread_mutex_lock(&state_mutex);

  vce = RB_FIND(&state_entries, skel, se_entry, state_entry_cmp);

  pthread_mutex_unlock(&state_mutex);

  if (vce == NULL)
    return 404;

  char *code = vce->se_code;

  htsmsg_t *msg = htsmsg_create_map();
  htsmsg_add_str(msg, "code", code);

  char *out = htsmsg_json_serialize_to_str(msg, 0);
  htsbuf_append(&hc->hc_reply, out, strlen(out));
  free(out);
  return http_send_reply(hc, 200, "application/json", NULL, NULL, 0);
}
Пример #4
0
int
rtsp_options_decode( http_client_t *hc )
{
  char *argv[32], *p;
  int i, n, what = 0;

  p = http_arg_get(&hc->hc_args, "Public");
  if (p == NULL)
    return -EIO;
  n = http_tokenize(p, argv, 32, ',');
  for (i = 1; i < n; i++) {
    if (strcmp(argv[i], "DESCRIBE") == 0)
      what |= 1;
    else if (strcmp(argv[i], "SETUP") == 0)
      what |= 2;
    else if (strcmp(argv[i], "PLAY") == 0)
      what |= 4;
    else if (strcmp(argv[i], "TEARDOWN") == 0)
      what |= 8;
  }
  return (hc->hc_code != 200 && what != 0x0f) ? -EIO : HTTP_CON_OK;
}
Пример #5
0
/*
 * Connected
 */
static int
iptv_http_header ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  char *argv[3], *s;
  int n;

  if (hc->hc_aux == NULL)
    return 0;

  /* multiple headers for redirections */
  if (hc->hc_code != HTTP_STATUS_OK)
    return 0;

  s = http_arg_get(&hc->hc_args, "Content-Type");
  if (s) {
    n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';');
    if (n > 0 &&
        (strcasecmp(s, "audio/mpegurl") == 0 ||
         strcasecmp(s, "audio/x-mpegurl") == 0 ||
         strcasecmp(s, "application/x-mpegurl") == 0 ||
         strcasecmp(s, "application/apple.vnd.mpegurl") == 0 ||
         strcasecmp(s, "application/vnd.apple.mpegurl") == 0)) {
      if (im->im_m3u_header > 10) {
        im->im_m3u_header = 0;
        return 0;
      }
      im->im_m3u_header++;
      return 0;
    }
  }

  im->im_m3u_header = 0;
  pthread_mutex_lock(&global_lock);
  iptv_input_mux_started(hc->hc_aux);
  pthread_mutex_unlock(&global_lock);
  return 0;
}
Пример #6
0
int
rtsp_setup_decode( http_client_t *hc, int satip )
{
  char *argv[32], *argv2[2], *p;
  int i, n, j;

#if 0
  { http_arg_t *ra;
  TAILQ_FOREACH(ra, &hc->hc_args, link)
    printf("  %s: %s\n", ra->key, ra->val); }
#endif
  rtsp_clear_session(hc);
  if (hc->hc_code != 200)
    return -EIO;
  p = http_arg_get(&hc->hc_args, "Session");
  if (p == NULL)
    return -EIO;
  n = http_tokenize(p, argv, 32, ';');
  if (n < 1)
    return -EIO;
  hc->hc_rtsp_session = strdup(argv[0]);
  for (i = 1; i < n; i++) {
    if (strncasecmp(argv[i], "timeout=", 8) == 0) {
      hc->hc_rtp_timeout = atoi(argv[i] + 8);
      if (hc->hc_rtp_timeout < 20 || hc->hc_rtp_timeout > 3600) {
        tvhwarn(LS_RTSP, "timeout value out of range 20-3600 (%i)", hc->hc_rtp_timeout);
        return -EIO;
      }
    }
  }
  if (satip) {
    p = http_arg_get(&hc->hc_args, "com.ses.streamID");
    if (p == NULL)
      return -EIO;
    /* zero is valid stream id per specification */
    while (*p && ((*p == '0' && *(p + 1) == '0') || *p < ' '))
      p++;
    if (p[0] == '0' && p[1] == '\0') {
      hc->hc_rtsp_stream_id = 0;
    } else {
      hc->hc_rtsp_stream_id = atoll(p);
      if (hc->hc_rtsp_stream_id <= 0)
        return -EIO;
    }
  }
  p = http_arg_get(&hc->hc_args, "Transport");
  if (p == NULL)
    return -EIO;
  n = http_tokenize(p, argv, 32, ';');
  if (n < 2)
    return -EIO;
  hc->hc_rtp_tcp = -1;
  hc->hc_rtcp_tcp = -1;
  hc->hc_rtp_port = -1;
  hc->hc_rtcp_port = -1;
  if (!strcasecmp(argv[0], "RTP/AVP/TCP")) {
    for (i = 1; i < n; i++) {
      if (strncmp(argv[i], "interleaved=", 12) == 0) {
        j = http_tokenize(argv[i] + 12, argv2, 2, '-');
        if (j > 0) {
          hc->hc_rtp_tcp = atoi(argv2[0]);
          if (hc->hc_rtp_tcp < 0)
            return -EIO;
          if (j > 1) {
            hc->hc_rtcp_tcp = atoi(argv2[1]);
            if (hc->hc_rtcp_tcp < 0)
              return -EIO;
          }
        } else {
          return -EIO;
        }
      }
    }
  } else if (!strcasecmp(argv[0], "RTP/AVP") ||
             !strcasecmp(argv[0], "RTP/AVP/UDP")) {
    if (n < 3)
      return -EIO;
    hc->hc_rtp_multicast = strcasecmp(argv[1], "multicast") == 0;
    if (strcasecmp(argv[1], "unicast") && !hc->hc_rtp_multicast)
      return -EIO;
    for (i = 2; i < n; i++) {
      if (strncmp(argv[i], "destination=", 12) == 0)
        hc->hc_rtp_dest = strdup(argv[i] + 12);
      else if (strncmp(argv[i], "client_port=", 12) == 0) {
        j = http_tokenize(argv[i] + 12, argv2, 2, '-');
        if (j > 0) {
          hc->hc_rtp_port = atoi(argv2[0]);
          if (hc->hc_rtp_port <= 0)
            return -EIO;
          if (j > 1) {
            hc->hc_rtcp_port = atoi(argv2[1]);
            if (hc->hc_rtcp_port <= 0)
              return -EIO;
          }
        } else {
          return -EIO;
        }
      }
      else if (strncmp(argv[i], "server_port=", 12) == 0) {
        j = http_tokenize(argv[i] + 12, argv2, 2, '-');
        if (j > 1) {
          hc->hc_rtcp_server_port = atoi(argv2[1]);
          if (hc->hc_rtcp_server_port <= 0)
            return -EIO;
        } else {
          return -EIO;
        }
      }
    }
  } else {
    return -EIO;
  }
  return HTTP_CON_OK;
}
Пример #7
0
static void
satip_discovery_http_closed(http_client_t *hc, int errn)
{
  satip_discovery_t *d = hc->hc_aux;
  char *s;
  htsmsg_t *xml = NULL, *tags, *root, *device;
  const char *friendlyname, *manufacturer, *manufacturerURL, *modeldesc;
  const char *modelname, *modelnum, *serialnum;
  const char *presentation, *tunercfg, *udn, *uuid;
  const char *cs, *arg;
  satip_device_info_t info;
  char errbuf[100];
  char *argv[10];
  int i, n;

  s = http_arg_get(&hc->hc_args, "Content-Type");
  if (s) {
    n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';');
    if (n <= 0 || strcasecmp(s, "text/xml")) {
      errn = ENOENT;
      s = NULL;
    }
  }
  if (errn != 0 || s == NULL || hc->hc_code != 200 ||
      hc->hc_data_size == 0 || hc->hc_data == NULL) {
    tvhlog(LOG_ERR, "satip", "Cannot get %s: %s", d->location, strerror(errn));
    return;
  }

  if (tvhtrace_enabled()) {
    tvhtrace("satip", "received XML description from %s", hc->hc_host);
    tvhlog_hexdump("satip", hc->hc_data, hc->hc_data_size);
  }

  if (d->myaddr == NULL || d->myaddr[0] == '\0') {
    struct sockaddr_storage ip;
    socklen_t addrlen = sizeof(ip);
    errbuf[0] = '\0';
    getsockname(hc->hc_fd, (struct sockaddr *)&ip, &addrlen);
    inet_ntop(ip.ss_family, IP_IN_ADDR(ip), errbuf, sizeof(errbuf));
    free(d->myaddr);
    d->myaddr = strdup(errbuf);
  }

  s = hc->hc_data + hc->hc_data_size - 1;
  while (s != hc->hc_data && *s != '/')
    s--;
  if (s != hc->hc_data)
    s--;
  if (strncmp(s, "</root>", 7))
    return;
  /* Parse */
  xml = htsmsg_xml_deserialize(hc->hc_data, errbuf, sizeof(errbuf));
  hc->hc_data = NULL;
  if (!xml) {
    tvhlog(LOG_ERR, "satip_discovery_desc", "htsmsg_xml_deserialize error %s", errbuf);
    goto finish;
  }
  if ((tags         = htsmsg_get_map(xml, "tags")) == NULL)
    goto finish;
  if ((root         = htsmsg_get_map(tags, "root")) == NULL)
    goto finish;
  if ((device       = htsmsg_get_map(root, "tags")) == NULL)
    goto finish;
  if ((device       = htsmsg_get_map(device, "device")) == NULL)
    goto finish;
  if ((device       = htsmsg_get_map(device, "tags")) == NULL)
    goto finish;
  if ((cs           = htsmsg_xml_get_cdata_str(device, "deviceType")) == NULL)
    goto finish;
  if (strcmp(cs, "urn:ses-com:device:SatIPServer:1"))
    goto finish;
  if ((friendlyname = htsmsg_xml_get_cdata_str(device, "friendlyName")) == NULL)
    goto finish;
  if ((manufacturer = htsmsg_xml_get_cdata_str(device, "manufacturer")) == NULL)
    goto finish;
  if ((manufacturerURL = htsmsg_xml_get_cdata_str(device, "manufacturerURL")) == NULL)
    manufacturerURL = "";
  if ((modeldesc    = htsmsg_xml_get_cdata_str(device, "modelDescription")) == NULL)
    modeldesc = "";
  if ((modelname    = htsmsg_xml_get_cdata_str(device, "modelName")) == NULL)
    goto finish;
  if ((modelnum     = htsmsg_xml_get_cdata_str(device, "modelNumber")) == NULL)
    modelnum = "";
  if ((serialnum    = htsmsg_xml_get_cdata_str(device, "serialNumber")) == NULL)
    serialnum = "";
  if ((presentation = htsmsg_xml_get_cdata_str(device, "presentationURL")) == NULL)
    presentation = "";
  if ((udn          = htsmsg_xml_get_cdata_str(device, "UDN")) == NULL)
    goto finish;
  if ((tunercfg     = htsmsg_xml_get_cdata_str(device, "urn:ses-com:satipX_SATIPCAP")) == NULL)
    tunercfg = "";

  uuid = NULL;
  n = http_tokenize((char *)udn, argv, ARRAY_SIZE(argv), ':');
  for (i = 0; i < n+1; i++)
    if (argv[i] && strcmp(argv[i], "uuid") == 0) {
      uuid = argv[++i];
      break;
    }
  if (uuid == NULL || (d->uuid[0] && strcmp(uuid, d->uuid)))
    goto finish;

  info.rtsp_port = 554;
  info.srcs = 4;

  arg = http_arg_get(&hc->hc_args, "X-SATIP-RTSP-Port");
  if (arg) {
    i = atoi(arg);
    if (i > 0 && i < 65535)
      info.rtsp_port = i;
  }
  arg = http_arg_get(&hc->hc_args, "X-SATIP-Sources");
  if (arg) {
    i = atoi(arg);
    if (i > 0 && i < 128)
      info.srcs = i;
  }

  info.myaddr = strdup(d->myaddr);
  info.addr = strdup(d->url.host);
  info.uuid = strdup(uuid);
  info.bootid = strdup(d->bootid);
  info.configid = strdup(d->configid);
  info.deviceid = strdup(d->deviceid);
  info.location = strdup(d->location);
  info.server = strdup(d->server);
  info.friendlyname = strdup(friendlyname);
  info.manufacturer = strdup(manufacturer);
  info.manufacturerURL = strdup(manufacturerURL);
  info.modeldesc = strdup(modeldesc);
  info.modelname = strdup(modelname);
  info.modelnum = strdup(modelnum);
  info.serialnum = strdup(serialnum);
  info.presentation = strdup(presentation);
  info.tunercfg = strdup(tunercfg);
  htsmsg_destroy(xml);
  xml = NULL;
  pthread_mutex_lock(&global_lock);
  if (!satip_device_find(info.uuid))
    satip_device_create(&info);
  pthread_mutex_unlock(&global_lock);
  free(info.myaddr);
  free(info.location);
  free(info.server);
  free(info.addr);
  free(info.uuid);
  free(info.bootid);
  free(info.configid);
  free(info.deviceid);
  free(info.friendlyname);
  free(info.manufacturer);
  free(info.manufacturerURL);
  free(info.modeldesc);
  free(info.modelname);
  free(info.modelnum);
  free(info.serialnum);
  free(info.presentation);
  free(info.tunercfg);
finish:
  htsmsg_destroy(xml);
}
Пример #8
0
/**
 * Root page, we direct the client to different pages depending
 * on if it is a full blown browser or just some mobile app
 */
static int
page_simple(http_connection_t *hc,
	  const char *remain, void *opaque)
{
  htsbuf_queue_t *hq = &hc->hc_reply;
  const char *s = http_arg_get(&hc->hc_req_args, "s");
  epg_broadcast_t *e;
  int c, k, i;
  struct tm a, b, day;
  dvr_entry_t *de;
  dvr_query_result_t dqr;
  const char *rstatus = NULL;
  epg_query_result_t eqr;
  const char *lang  = http_arg_get(&hc->hc_args, "Accept-Language");

  htsbuf_qprintf(hq, "<html>");
  htsbuf_qprintf(hq, "<body>");

  htsbuf_qprintf(hq, "<form>");
  htsbuf_qprintf(hq, "Event: <input type=\"text\" ");
  if(s != NULL)
    htsbuf_qprintf(hq, "value=\"%s\" ", s);
  
  htsbuf_qprintf(hq, "name=\"s\">");
  htsbuf_qprintf(hq, "<input type=\"submit\" value=\"Search\">");
  
  htsbuf_qprintf(hq, "</form><hr>");

  pthread_mutex_lock(&global_lock);


  if(s != NULL) {

    //Note: force min/max durations for this interface to 0 and INT_MAX seconds respectively
    epg_query(&eqr, NULL, NULL, NULL, s, lang, 0, INT_MAX);
    epg_query_sort(&eqr);

    c = eqr.eqr_entries;

    if(eqr.eqr_entries == 0) {
      htsbuf_qprintf(hq, "<b>No matching entries found</b>");
    } else {

      htsbuf_qprintf(hq, "<b>%d entries found", c);

      if(c > 25) {
	c = 25;
	htsbuf_qprintf(hq, ", %d entries shown", c);
      }

      htsbuf_qprintf(hq, "</b>");

      memset(&day, -1, sizeof(struct tm));
      for(k = 0; k < c; k++) {
	e = eqr.eqr_array[k];
      
	localtime_r(&e->start, &a);
	localtime_r(&e->stop, &b);

	if(a.tm_wday != day.tm_wday || a.tm_mday != day.tm_mday  ||
	   a.tm_mon  != day.tm_mon  || a.tm_year != day.tm_year) {
	  memcpy(&day, &a, sizeof(struct tm));
	  htsbuf_qprintf(hq, 
		      "<br><i>%s, %d/%d</i><br>",
		      days[day.tm_wday], day.tm_mday, day.tm_mon + 1);
	}

	de = dvr_entry_find_by_event(e);
	rstatus = de != NULL ? val2str(de->de_sched_state,
				       recstatustxt) : NULL;

        s = epg_broadcast_get_title(e, lang);
	htsbuf_qprintf(hq, 
		    "<a href=\"/eventinfo/%u\">"
		    "%02d:%02d-%02d:%02d&nbsp;%s%s%s</a><br>",
		    e->id,
		    a.tm_hour, a.tm_min, b.tm_hour, b.tm_min,
        s ?: "",
		    rstatus ? "&nbsp;" : "", rstatus ?: "");
      }
    }
    htsbuf_qprintf(hq, "<hr>");
    epg_query_free(&eqr);
  }
Пример #9
0
static int
http_github(http_connection_t *hc, const char *remain, void *opaque)
{
  const char *pid = http_arg_get(&hc->hc_req_args, "project");
  const char *key = http_arg_get(&hc->hc_req_args, "key");


  if(pid == NULL) {
    trace(LOG_WARNING, "github: Missing 'project' in request");
    return 400;
  }

  if(key == NULL) {
    trace(LOG_WARNING, "github: Missing 'key' in request");
    return 400;
  }

  project_cfg(pc, pid);
  if(pc == NULL) {
    trace(LOG_DEBUG, "github: Project '%s' not configured", pid);
    return 404;
  }

  const char *mykey = cfg_get_str(pc, CFG("github", "key"), "");

  if(strcmp(mykey, key)) {
    trace(LOG_WARNING, "github: Invalid key received (%s) for project %s",
          key, pid);
    return 403;
  }

  project_t *p = project_get(pid);

  const char *json = http_arg_get(&hc->hc_req_args, "payload");
  if(json == NULL) {
    plog(p, "github", "github: Missing payload in request");
    return 400;
  }

  char errbuf[256];
  htsmsg_t *msg = htsmsg_json_deserialize(json, errbuf, sizeof(errbuf));
  if(msg == NULL) {
    plog(p, "github", "github: Malformed JSON in github request -- %s",
         errbuf);
    return 400;
  }

  const char *ref = htsmsg_get_str(msg, "ref");
  if(ref != NULL && !strncmp(ref, "refs/heads/", strlen("refs/heads/")))
    ref += strlen("refs/heads/");

  htsmsg_t *list = htsmsg_get_list(msg, "commits");
  if(ref != NULL && list != NULL) {
    htsmsg_field_t *f;
    HTSMSG_FOREACH(f, list) {
      htsmsg_t *c = htsmsg_get_map_by_field(f);
      if(c == NULL)
        continue;

      const char *url = htsmsg_get_str(c, "url");
      const char *msg = htsmsg_get_str(c, "message");
      htsmsg_t *a = htsmsg_get_map(c, "author");
      const char *author = a ? htsmsg_get_str(a, "name") : NULL;

      int added    = count_list(c, "added");
      int removed  = count_list(c, "removed");
      int modified = count_list(c, "modified");

      int len;
      char buf[512];
      char ctx[128];

      url = url ? urlshorten(url) : NULL;

      snprintf(ctx, sizeof(ctx), "changes/%s", ref);

      len = snprintf(buf, sizeof(buf),
                     "Commit in '"COLOR_BLUE"%s"COLOR_OFF"' by "COLOR_PURPLE"%s"COLOR_OFF" [",
                     ref, author ?: "???");

      if(added)
        len += snprintf(buf + len, sizeof(buf) - len,
                        COLOR_GREEN "%d file%s added",
                        added, added == 1 ? "" : "s");

      if(modified)
        len += snprintf(buf + len, sizeof(buf) - len,
                        COLOR_YELLOW "%s%d file%s modified",
                        added ? ", "  : "",
                        modified, modified == 1 ? "" : "s");

      if(removed)
        len += snprintf(buf + len, sizeof(buf) - len,
                        COLOR_RED "%s%d file%s removed",
                        added || modified ? ", "  : "",
                        removed, removed == 1 ? "" : "s");

      snprintf(buf + len, sizeof(buf) - len, COLOR_OFF"]%s%s",
               url ? " " : "", url ?: "");

      plog(p, ctx, "%s", buf);
      plog(p, ctx, "%s", msg);
    }