From 9ca6f0c45d4a6bd05a5cfee7e3c02418d71c6e80 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 9 Apr 2014 20:30:44 +0200 Subject: [PATCH] Make URL parser more dynamic --- src/http/http_client.c | 4 +- src/input/mpegts/iptv/iptv.c | 1 + src/input/mpegts/satip/satip.c | 6 ++- src/url.c | 69 ++++++++++++++++++++++++++++------ src/url.h | 23 ++++++------ 5 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/http/http_client.c b/src/http/http_client.c index 38741f62..5f7c56b2 100644 --- a/src/http/http_client.c +++ b/src/http/http_client.c @@ -81,6 +81,8 @@ http_remove ( http_client_t *hc ) /* Free CURL memory */ curl_easy_cleanup(hc->hc_curl); hc->hc_curl = NULL; + + urlreset(&hc->hc_url); } /* @@ -199,7 +201,7 @@ http_connect /* Setup structure */ http_client_t *hc = calloc(1, sizeof(http_client_t)); hc->hc_curl = curl_easy_init(); - hc->hc_url = *url; + urlcopy(&hc->hc_url, url); hc->hc_conn = conn_cb; hc->hc_data = data_cb; hc->hc_fail = fail_cb; diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 274cc893..f5ed6590 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -218,6 +218,7 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) im->mm_active = NULL; pthread_mutex_unlock(&iptv_lock); + urlreset(&url); return ret; } diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 0f2b1578..8dd439c3 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -466,6 +466,7 @@ satip_discovery_destroy(satip_discovery_t *d, int unlink) } if (d->http_client) http_close(d->http_client); + urlreset(&d->url); free(d->myaddr); free(d->location); free(d->server); @@ -622,7 +623,7 @@ satip_discovery_timerq_cb(void *aux) next = TAILQ_NEXT(d, disc_link); if (d->http_client) { if (dispatch_clock - d->http_start > 4) - satip_discovery_destroy(d, 1);; + satip_discovery_destroy(d, 1); continue; } d->http_client = http_connect(&d->url, NULL, @@ -631,7 +632,8 @@ satip_discovery_timerq_cb(void *aux) d); if (d->http_client == NULL) satip_discovery_destroy(d, 1); - d->http_start = dispatch_clock; + else + d->http_start = dispatch_clock; } if (TAILQ_FIRST(&satip_discoveries)) gtimer_arm(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 5); diff --git a/src/url.c b/src/url.c index d4c3c20a..53ebdc4f 100644 --- a/src/url.c +++ b/src/url.c @@ -25,11 +25,40 @@ #include #include + +void +urlreset ( url_t *url ) +{ + free(url->scheme); + free(url->user); + free(url->pass); + free(url->host); + free(url->path); + free(url->query); + free(url->frag); + free(url->raw); + memset(url, 0, sizeof(*url)); +} + +void +urlcopy ( url_t *dst, const url_t *src ) +{ + dst->scheme = strdup(src->scheme); + dst->user = strdup(src->user); + dst->pass = strdup(src->pass); + dst->host = strdup(src->host); + dst->port = src->port; + dst->path = strdup(src->path); + dst->query = strdup(src->query); + dst->frag = strdup(src->frag); + dst->raw = strdup(src->raw); +} + /* Use liburiparser if available */ #if ENABLE_URIPARSER #include -int +int urlparse ( const char *str, url_t *url ) { UriParserStateA state; @@ -37,6 +66,11 @@ urlparse ( const char *str, url_t *url ) 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) { @@ -45,32 +79,36 @@ urlparse ( const char *str, url_t *url ) } /* Store raw */ - strncpy(url->raw, str, sizeof(url->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;\ + 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(buf, uri.portText); + uri_copy_static(buf, uri.portText); if (*buf) url->port = atoi(buf); else url->port = 0; - *url->path = 0; path = uri.pathHead; while (path) { - strcat(url->path, "/"); uri_copy(buf, path->text); + url->path = realloc(url->path, strlen(url->path) + strlen(buf) + 2); + strcat(url->path, "/"); strcat(url->path, buf); path = path->next; } @@ -81,8 +119,6 @@ urlparse ( const char *str, url_t *url ) if (s) { strcpy(url->pass, s+1); *s = 0; - } else { - *url->pass = 0; } /* Cleanup */ @@ -113,6 +149,11 @@ 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)); @@ -124,10 +165,14 @@ urlparse ( const char *str, url_t *url ) /* Execute */ if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0)) - return 1; + 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)\ @@ -140,12 +185,12 @@ urlparse ( const char *str, url_t *url ) copy(url->pass, 5); copy(url->host, 6); copy(url->path, 9); - copy(buf, 8); + copy_static(buf, 8); url->port = atoi(buf); copy(url->query, 11); copy(url->frag, 13); - strncpy(url->raw, str, sizeof(url->raw)); + url->raw = strdup(str); return 0; } diff --git a/src/url.h b/src/url.h index dd9aeb22..4d7da6f3 100644 --- a/src/url.h +++ b/src/url.h @@ -22,24 +22,23 @@ #include -// TODO: limits are a bit arbitrary and it's a bit inflexible, but it -// does keep things simple, not having dynamically allocated strings - /* URL structure */ typedef struct url { - char scheme[32]; - char user[128]; - char pass[128]; - char host[256]; - short port; - char path[256]; - char query[1024]; - char frag[256]; - char raw[2048]; + char *scheme; + char *user; + char *pass; + char *host; + short port; + char *path; + char *query; + char *frag; + char *raw; } url_t; +void urlreset ( url_t *url ); int urlparse ( const char *str, url_t *url ); void urlparse_done ( void ); +void urlcopy ( url_t *dst, const url_t *src ); #endif