/* * 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; }
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); }
/* * 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; }
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); }
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; }
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); }