]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Add a decent URL argument parser
authorAndreas Öman <andreas@lonelycoder.com>
Sun, 2 Dec 2007 16:24:14 +0000 (16:24 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sun, 2 Dec 2007 16:24:14 +0000 (16:24 +0000)
http.c
http.h

diff --git a/http.c b/http.c
index 2c50a73526e071d7f738e9fc386d9a0c59cbe53f..29256b7ecac304d6628160fc0350dd05088becbc 100644 (file)
--- a/http.c
+++ b/http.c
@@ -67,12 +67,13 @@ static struct strtab HTTP_versiontab[] = {
   { "RTSP/1.0",        RTSP_VERSION_1_0 }, /* not enabled yet */
 };
 
+static void http_parse_get_args(http_connection_t *hc, char *args);
 
 /**
  *
  */
 static http_path_t *
-http_resolve(http_connection_t *hc, char **remainp)
+http_resolve(http_connection_t *hc, char **remainp, char **argsp)
 {
   http_path_t *hp;
   char *v;
@@ -86,13 +87,35 @@ http_resolve(http_connection_t *hc, char **remainp)
 
   v = hc->hc_url + hp->hp_len;
 
-  if(*v != 0 && *v != '/' && *v != '?')
-    return NULL;
+  *remainp = NULL;
+  *argsp = NULL;
+
+  switch(*v) {
+  case 0:
+    break;
 
-  if(*v == '/' || *v == '?')
-    v++;
+  case '/':
+    if(v[1] == '?') {
+      *argsp = v + 1;
+      break;
+    }
+
+    *remainp = v + 1;
+    v = strchr(v + 1, '?');
+    if(v != NULL) {
+      *v = 0;  /* terminate remaining url */
+      *argsp = v + 1;
+    }
+    break;
+
+  case '?':
+    *argsp = v + 1;
+    break;
+
+  default:
+    return NULL;
+  }
 
-  *remainp = v;
   return hp;
 }
 
@@ -193,14 +216,18 @@ http_cmd_get(http_connection_t *hc)
 {
   http_path_t *hp;
   char *remain;
+  char *args;
   int err;
 
-  hp = http_resolve(hc, &remain);
+  hp = http_resolve(hc, &remain, &args);
   if(hp == NULL) {
     http_error(hc, HTTP_STATUS_NOT_FOUND);
     return;
   }
 
+  if(args != NULL)
+    http_parse_get_args(hc, args);
+
   err = hp->hp_callback(hc, remain, hp->hp_opaque);
   if(err)
     http_error(hc, err);
@@ -349,6 +376,7 @@ http_con_parse(void *aux, char *buf)
   switch(hc->hc_state) {
   case HTTP_CON_WAIT_REQUEST:
     http_arg_flush(&hc->hc_args);
+    http_arg_flush(&hc->hc_url_args);
     if(hc->hc_url != NULL) {
       free(hc->hc_url);
       hc->hc_url = NULL;
@@ -410,6 +438,7 @@ http_disconnect(http_connection_t *hc)
 {
   rtsp_disconncet(hc);
   http_arg_flush(&hc->hc_args);
+  http_arg_flush(&hc->hc_url_args);
   free(hc->hc_url);
 }
 
@@ -555,3 +584,33 @@ http_path_add(const char *path, void *opaque, http_callback_t *callback)
   return hp;
 }
 
+
+/**
+ * Parse arguments of a HTTP GET url, not perfect, but works for us
+ */
+static void
+http_parse_get_args(http_connection_t *hc, char *args)
+{
+  char *k, *v, *s;
+
+  while(args) {
+    k = args;
+    if((args = strchr(args, '=')) == NULL)
+      break;
+    *args++ = 0;
+    v = args;
+    args = strchr(args, '&');
+
+    if(args != NULL)
+      *args++ = 0;
+
+    s = v;
+    while(*s) {
+      if(*s == '+')
+       *s = ' ';
+      s++;
+    }
+
+    http_arg_set(&hc->hc_url_args, k, v);
+  }
+}
diff --git a/http.h b/http.h
index f6ddb1785cff3e06921fe1a18d247e97ce88a9bd..a0b02d094f2312cba88ad22b20700bf6d7961561 100644 (file)
--- a/http.h
+++ b/http.h
@@ -49,6 +49,8 @@ typedef struct http_connection {
 
   struct http_arg_list hc_args;
 
+  struct http_arg_list hc_url_args;
+
   enum {
     HTTP_CON_WAIT_REQUEST,
     HTTP_CON_READ_HEADER,