]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Make URL parser more dynamic
authorJaroslav Kysela <perex@perex.cz>
Wed, 9 Apr 2014 18:30:44 +0000 (20:30 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 5 May 2014 20:00:35 +0000 (22:00 +0200)
src/http/http_client.c
src/input/mpegts/iptv/iptv.c
src/input/mpegts/satip/satip.c
src/url.c
src/url.h

index 38741f62c55b78bcdbb4a9462946f9ba6d82ab6f..5f7c56b2dbb830147d3d7289724ce5f02c5b6a0d 100644 (file)
@@ -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;
index 274cc893f988a9388f76c52683d73335ab708958..f5ed65906d050590d9ee868fd87f1caaea07fb3e 100644 (file)
@@ -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;
 }
 
index 0f2b1578043464037b7c78cf7592ec9a6b4bac88..8dd439c3bc326cf5efca64de86b3a2f6617ca0a9 100644 (file)
@@ -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);
index d4c3c20aac12859c9fb85fdb581b8cdbe2f589ff..53ebdc4f7f3723ef7caa4a0efaa6687677bd6a62 100644 (file)
--- a/src/url.c
+++ b/src/url.c
 #include <regex.h>
 #include <string.h>
 
+
+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 <uriparser/Uri.h>
 
-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;
 }
index dd9aeb22d970d118ebef3a77eaf236f3666a17f6..4d7da6f3aa83c6cd229aed5cbc2bba5302ea3c04 100644 (file)
--- a/src/url.h
+++ b/src/url.h
 
 #include <stdint.h>
 
-// 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