]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
add callbacks for a virtual http server
authorAndreas Öman <andreas@lonelycoder.com>
Sat, 3 Nov 2007 06:34:53 +0000 (06:34 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sat, 3 Nov 2007 06:34:53 +0000 (06:34 +0000)
http.c
http.h

diff --git a/http.c b/http.c
index f18ff9a6526a697944952a0a908698a6d4bbcce7..87fe94d10f83947265620e57e955b156b9fee935 100644 (file)
--- a/http.c
+++ b/http.c
@@ -44,6 +44,8 @@
 #include "http.h"
 #include "rtsp.h"
 
+static LIST_HEAD(, http_path) http_paths;
+
 static struct strtab HTTP_cmdtab[] = {
   { "GET",        HTTP_CMD_GET },
   { "DESCRIBE",   RTSP_CMD_DESCRIBE },
@@ -64,6 +66,33 @@ static struct strtab HTTP_versiontab[] = {
 };
 
 
+/**
+ *
+ */
+static http_path_t *
+http_resolve(http_connection_t *hc, char **remainp)
+{
+  http_path_t *hp;
+  char *v;
+  LIST_FOREACH(hp, &http_paths, hp_link) {
+    if(!strncmp(hc->hc_url, hp->hp_path, hp->hp_len))
+      break;
+  }
+
+  if(hp == NULL)
+    return NULL;
+
+  v = hc->hc_url + hp->hp_len;
+
+  if(*v != 0 && *v != '/')
+    return NULL;
+
+  *remainp = v;
+  return hp;
+}
+
+
+
 /*
  * HTTP status code to string
  */
@@ -107,7 +136,7 @@ http_output_reply_header(http_connection_t *hc, int rc)
 /**
  * Send HTTP error back
  */
-static void
+void
 http_error(http_connection_t *hc, int error)
 {
   char ret[300];
@@ -126,45 +155,15 @@ http_error(http_connection_t *hc, int error)
           error, errtxt);
 
   if(hc->hc_version >= HTTP_VERSION_1_0) {
-    http_printf(hc, "Content-Type: text/html\r\n");
-    http_printf(hc, "Content-Length: %d\r\n", strlen(ret));
-    http_printf(hc, "\r\n");
-  }
-  http_printf(hc, "%s", ret);
-}
+    if(error == HTTP_STATUS_UNAUTHORIZED)
+      http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
 
-#if 0
-/**
- * Send HTTP unauthorized back, and ask for authentication
- */
-static void
-http_unauthorized(http_connection_t *hc)
-{
-  char ret[300];
-  const char *errtxt = http_rc2str(HTTP_STATUS_UNAUTHORIZED);
-
-  http_output_reply_header(hc, HTTP_STATUS_UNAUTHORIZED);
-
-  snprintf(ret, sizeof(ret),
-          "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
-          "<HTML><HEAD>\r\n"
-          "<TITLE>%d %s</TITLE>\r\n"
-          "</HEAD><BODY>\r\n"
-          "<H1>%d %s</H1>\r\n"
-          "</BODY></HTML>\r\n",
-          HTTP_STATUS_UNAUTHORIZED, errtxt,
-          HTTP_STATUS_UNAUTHORIZED, errtxt);
-
-  if(hc->hc_version >= HTTP_VERSION_1_0) {
-    http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
     http_printf(hc, "Content-Type: text/html\r\n");
     http_printf(hc, "Content-Length: %d\r\n", strlen(ret));
     http_printf(hc, "\r\n");
   }
   http_printf(hc, "%s", ret);
 }
-#endif
-
 
 /**
  * HTTP GET
@@ -172,7 +171,19 @@ http_unauthorized(http_connection_t *hc)
 static void
 http_cmd_get(http_connection_t *hc)
 {
-  http_error(hc, HTTP_STATUS_NOT_FOUND);
+  http_path_t *hp;
+  char *remain;
+  int err;
+
+  hp = http_resolve(hc, &remain);
+  if(hp == NULL) {
+    http_error(hc, HTTP_STATUS_NOT_FOUND);
+    return;
+  }
+
+  err = hp->hp_callback(hc, remain, hp->hp_opaque);
+  if(err)
+    http_error(hc, err);
 }
 
 
@@ -469,3 +480,21 @@ http_tokenize(char *buf, char **vec, int vecsize, int delimiter)
   }
   return n;
 }
+
+
+/**
+ * Add a callback for a given "virtual path" on our HTTP server
+ */
+http_path_t *
+http_path_add(const char *path, void *opaque, http_callback_t *callback)
+{
+  http_path_t *hp = malloc(sizeof(http_path_t));
+
+  hp->hp_len      = strlen(path);
+  hp->hp_path     = strdup(path);
+  hp->hp_opaque   = opaque;
+  hp->hp_callback = callback;
+  LIST_INSERT_HEAD(&http_paths, hp, hp_link);
+  return hp;
+}
+
diff --git a/http.h b/http.h
index add001cd563ab2e92638063d44abf9e60bcc5321..8f580e0cf853cb32d06999fb29d0327ce0ba97dd 100644 (file)
--- a/http.h
+++ b/http.h
@@ -83,4 +83,21 @@ void http_arg_set(struct http_arg_list *list, char *key, char *val);
 
 int http_tokenize(char *buf, char **vec, int vecsize, int delimiter);
 
+void http_error(http_connection_t *hc, int error);
+
+
+typedef int (http_callback_t)(http_connection_t *hc, const char *remain,
+                             void *opaque);
+
+typedef struct http_path {
+  LIST_ENTRY(http_path) hp_link;
+  const char *hp_path;
+  void *hp_opaque;
+  http_callback_t *hp_callback;
+  int hp_len;
+} http_path_t;
+
+http_path_t *http_path_add(const char *path, void *opaque,
+                          http_callback_t *callback);
+
 #endif /* HTTP_H_ */