add callbacks for a virtual http server

This commit is contained in:
Andreas Öman 2007-11-03 06:34:53 +00:00
parent f25e221766
commit 50f37f1456
2 changed files with 81 additions and 35 deletions

99
http.c
View file

@ -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,6 +155,9 @@ http_error(http_connection_t *hc, int error)
error, errtxt);
if(hc->hc_version >= HTTP_VERSION_1_0) {
if(error == HTTP_STATUS_UNAUTHORIZED)
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");
@ -133,46 +165,25 @@ http_error(http_connection_t *hc, int error)
http_printf(hc, "%s", ret);
}
#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
*/
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;
}

17
http.h
View file

@ -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_ */