[asterisk-commits] russell: trunk r48930 - in /trunk: ./ configs/
include/asterisk/ main/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Dec 23 13:13:15 MST 2006
Author: russell
Date: Sat Dec 23 14:13:14 2006
New Revision: 48930
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48930
Log:
- Convert the list of URI handlers to use the linked list macros. While doing
this, implementing locking of this list to make it thread-safe.
- Add a "redirect" option to http.conf that allows redirecting one URI to
another. I was inspired to do this while playing with the Asterisk GUI. I
got tired of typing this URL to get to the GUI:
http://localhost:8088/asterisk/static/config/cfgadvanced.html
So, now I have the following line in http.conf:
redirect=/=/asterisk/static/config/cfgadvanced.html
Now, I can type the following into my browser and go to the GUI:
http://localhost:8088
Modified:
trunk/CHANGES
trunk/configs/http.conf.sample
trunk/include/asterisk/http.h
trunk/main/http.c
Modified: trunk/CHANGES
URL: http://svn.digium.com/view/asterisk/trunk/CHANGES?view=diff&rev=48930&r1=48929&r2=48930
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Sat Dec 23 14:13:14 2006
@@ -64,4 +64,4 @@
* Added maxfiles option to options section of asterisk.conf which allows you to specify
what Asterisk should set as the maximum number of open files when it loads.
* Added the jittertargetextra configuration option.
-
+ * Added the URI redirect option for the built-in HTTP server
Modified: trunk/configs/http.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/http.conf.sample?view=diff&rev=48930&r1=48929&r2=48930
==============================================================================
--- trunk/configs/http.conf.sample (original)
+++ trunk/configs/http.conf.sample Sat Dec 23 14:13:14 2006
@@ -8,11 +8,6 @@
; This also affects manager/rawman/mxml access (see manager.conf)
;
;enabled=yes
-;
-; Whether Asterisk should serve static content from http-static
-; Default is no.
-;
-;enablestatic=yes
;
; Address to bind to, both for HTTP and HTTPS. Default is 0.0.0.0
;
@@ -27,7 +22,20 @@
; requests must begin with /asterisk
;
;prefix=asterisk
-
+;
+; Whether Asterisk should serve static content from http-static
+; Default is no.
+;
+;enablestatic=yes
+;
+; Redirect one URI to another. This is how you would set a
+; default page.
+; Syntax: redirect=<from here>=<to there>
+; For example, if you are using the Asterisk-gui,
+; it is convenient to enable the following redirect:
+;
+;redirect=/=/asterisk/static/config/cfgadvanced.html
+;
; HTTPS support. In addition to enabled=yes, you need to
; explicitly enable ssl, define the port to use,
; and have a certificate somewhere.
Modified: trunk/include/asterisk/http.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/http.h?view=diff&rev=48930&r1=48929&r2=48930
==============================================================================
--- trunk/include/asterisk/http.h (original)
+++ trunk/include/asterisk/http.h Sat Dec 23 14:13:14 2006
@@ -147,7 +147,7 @@
typedef struct ast_str *(*ast_http_callback)(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
struct ast_http_uri {
- struct ast_http_uri *next;
+ AST_LIST_ENTRY(ast_http_uri) entry;
const char *description;
const char *uri;
int has_subtree;
Modified: trunk/main/http.c
URL: http://svn.digium.com/view/asterisk/trunk/main/http.c?view=diff&rev=48930&r1=48929&r2=48930
==============================================================================
--- trunk/main/http.c (original)
+++ trunk/main/http.c Sat Dec 23 14:13:14 2006
@@ -53,6 +53,7 @@
#include "asterisk/strings.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
+#include "asterisk/stringfields.h"
#define MAX_PREFIX 80
#define DEFAULT_PREFIX "/asterisk"
@@ -106,7 +107,7 @@
.worker_fn = httpd_helper_thread,
};
-static struct ast_http_uri *uris; /*!< list of supported handlers */
+static AST_LIST_HEAD_STATIC(uris, ast_http_uri); /*!< list of supported handlers */
/* all valid URIs must be prepended by the string in prefix. */
static char prefix[MAX_PREFIX];
@@ -123,6 +124,16 @@
{ "wav", "audio/x-wav" },
{ "mp3", "audio/mpeg" },
};
+
+struct http_uri_redirect {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(target);
+ AST_STRING_FIELD(dest);
+ );
+ AST_LIST_ENTRY(http_uri_redirect) entry;
+};
+
+static AST_LIST_HEAD_STATIC(uri_redirects, http_uri_redirect);
static char *ftype2mtype(const char *ftype, char *wkspace, int wkspacelen)
{
@@ -297,37 +308,38 @@
*/
int ast_http_uri_link(struct ast_http_uri *urih)
{
- struct ast_http_uri *prev=uris;
+ struct ast_http_uri *uri;
int len = strlen(urih->uri);
- if (!uris || strlen(uris->uri) <= len ) {
- urih->next = uris;
- uris = urih;
- } else {
- while (prev->next && strlen(prev->next->uri) > len)
- prev = prev->next;
- /* Insert it here */
- urih->next = prev->next;
- prev->next = urih;
- }
+ AST_LIST_LOCK(&uris);
+
+ if ( AST_LIST_EMPTY(&uris) || strlen(AST_LIST_FIRST(&uris)->uri) <= len ) {
+ AST_LIST_INSERT_HEAD(&uris, urih, entry);
+ AST_LIST_UNLOCK(&uris);
+ return 0;
+ }
+
+ AST_LIST_TRAVERSE(&uris, uri, entry) {
+ if ( AST_LIST_NEXT(uri, entry)
+ && strlen(AST_LIST_NEXT(uri, entry)->uri) <= len ) {
+ AST_LIST_INSERT_AFTER(&uris, uri, urih, entry);
+ AST_LIST_UNLOCK(&uris);
+ return 0;
+ }
+ }
+
+ AST_LIST_INSERT_TAIL(&uris, urih, entry);
+
+ AST_LIST_UNLOCK(&uris);
+
return 0;
}
void ast_http_uri_unlink(struct ast_http_uri *urih)
{
- struct ast_http_uri *prev = uris;
- if (!uris)
- return;
- if (uris == urih) {
- uris = uris->next;
- }
- while(prev->next) {
- if (prev->next == urih) {
- prev->next = urih->next;
- break;
- }
- prev = prev->next;
- }
+ AST_LIST_LOCK(&uris);
+ AST_LIST_REMOVE(&uris, urih, entry);
+ AST_LIST_UNLOCK(&uris);
}
static struct ast_str *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **title, int *contentlength, struct ast_variable **cookies)
@@ -338,6 +350,7 @@
struct ast_http_uri *urih=NULL;
int l;
struct ast_variable *vars=NULL, *v, *prev = NULL;
+ struct http_uri_redirect *redirect;
strsep(¶ms, "?");
/* Extract arguments from the request and store them in variables. */
@@ -372,12 +385,29 @@
*cookies = NULL;
ast_uri_decode(uri);
+ AST_LIST_LOCK(&uri_redirects);
+ AST_LIST_TRAVERSE(&uri_redirects, redirect, entry) {
+ if (!strcasecmp(uri, redirect->target)) {
+ char buf[512];
+ snprintf(buf, sizeof(buf), "Location: %s\r\n", redirect->dest);
+ out = ast_http_error(302, "Moved Temporarily", buf,
+ "There is no spoon...");
+ *status = 302;
+ *title = strdup("Moved Temporarily");
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&uri_redirects);
+ if (redirect)
+ goto cleanup;
+
/* We want requests to start with the prefix and '/' */
l = strlen(prefix);
if (l && !strncasecmp(uri, prefix, l) && uri[l] == '/') {
uri += l + 1;
/* scan registered uris to see if we match one. */
- for (urih = uris; urih; urih = urih->next) {
+ AST_LIST_LOCK(&uris);
+ AST_LIST_TRAVERSE(&uris, urih, entry) {
l = strlen(urih->uri);
c = uri + l; /* candidate */
if (strncasecmp(urih->uri, uri, l) /* no match */
@@ -390,22 +420,20 @@
break;
}
}
+ if (!urih)
+ AST_LIST_UNLOCK(&uris);
}
if (urih) {
out = urih->callback(sin, uri, vars, status, title, contentlength);
- } else if (ast_strlen_zero(uri) && ast_strlen_zero(prefix)) {
- /* Special case: no prefix, no URI, send to /static/index.html */
- out = ast_http_error(302, "Moved Temporarily",
- "Location: /static/index.html\r\n",
- "This is not the page you are looking for...");
- *status = 302;
- *title = strdup("Moved Temporarily");
+ AST_LIST_UNLOCK(&uris);
} else {
out = ast_http_error(404, "Not Found", NULL,
"The requested URL was not found on this server.");
*status = 404;
*title = strdup("Not Found");
}
+
+cleanup:
ast_variables_destroy(vars);
return out;
}
@@ -778,6 +806,66 @@
desc->accept_fd = -1;
}
+/*!
+ * \brief Add a new URI redirect
+ * The entries in the redirect list are sorted by length, just like the list
+ * of URI handlers.
+ */
+static void add_redirect(const char *value)
+{
+ char *target, *dest;
+ struct http_uri_redirect *redirect, *cur;
+ unsigned int len;
+
+ dest = ast_strdupa(value);
+ target = strsep(&dest, "=");
+
+ if (!dest) {
+ ast_log(LOG_WARNING, "Invalid redirect '%s'\n", value);
+ return;
+ }
+
+ if (!(redirect = ast_calloc(1, sizeof(*redirect))))
+ return;
+
+ if (ast_string_field_init(redirect, 32)) {
+ free(redirect);
+ return;
+ }
+
+ ast_string_field_set(redirect, target, target);
+ ast_string_field_set(redirect, dest, dest);
+
+ AST_LIST_LOCK(&uri_redirects);
+
+ len = strlen(target);
+ if ( AST_LIST_EMPTY(&uri_redirects)
+ || strlen(AST_LIST_FIRST(&uri_redirects)->target) <= len ) {
+ AST_LIST_INSERT_HEAD(&uri_redirects, redirect, entry);
+ AST_LIST_UNLOCK(&uri_redirects);
+ return;
+ }
+
+ AST_LIST_TRAVERSE(&uri_redirects, cur, entry) {
+ if ( AST_LIST_NEXT(cur, entry)
+ && strlen(AST_LIST_NEXT(cur, entry)->target) <= len ) {
+ AST_LIST_INSERT_AFTER(&uri_redirects, cur, redirect, entry);
+ AST_LIST_UNLOCK(&uri_redirects);
+ return;
+ }
+ }
+
+ AST_LIST_INSERT_TAIL(&uri_redirects, redirect, entry);
+
+ AST_LIST_UNLOCK(&uri_redirects);
+}
+
+static void destroy_redirect(struct http_uri_redirect *redirect)
+{
+ ast_string_field_free_all(redirect);
+ free(redirect);
+}
+
static int __ast_http_load(int reload)
{
struct ast_config *cfg;
@@ -788,6 +876,7 @@
struct ast_hostent ahp;
char newprefix[MAX_PREFIX];
int have_sslbindaddr = 0;
+ struct http_uri_redirect *redirect;
/* default values */
memset(&http_desc.sin, 0, sizeof(http_desc.sin));
@@ -796,7 +885,6 @@
memset(&https_desc.sin, 0, sizeof(https_desc.sin));
https_desc.sin.sin_port = htons(8089);
strcpy(newprefix, DEFAULT_PREFIX);
- cfg = ast_config_load("http.conf");
http_tls_cfg.enabled = 0;
if (http_tls_cfg.certfile)
@@ -806,9 +894,15 @@
free(http_tls_cfg.cipher);
http_tls_cfg.cipher = ast_strdup("");
+ AST_LIST_LOCK(&uri_redirects);
+ while ((redirect = AST_LIST_REMOVE_HEAD(&uri_redirects, entry)))
+ destroy_redirect(redirect);
+ AST_LIST_UNLOCK(&uri_redirects);
+
+ cfg = ast_config_load("http.conf");
if (cfg) {
v = ast_variable_browse(cfg, "general");
- while(v) {
+ for (; v; v = v->next) {
if (!strcasecmp(v->name, "enabled"))
enabled = ast_true(v->value);
else if (!strcasecmp(v->name, "sslenable"))
@@ -846,9 +940,11 @@
} else {
newprefix[0] = '\0';
}
-
+ } else if (!strcasecmp(v->name, "redirect")) {
+ add_redirect(v->value);
+ } else {
+ ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
}
- v = v->next;
}
ast_config_destroy(cfg);
}
@@ -868,8 +964,11 @@
static int handle_show_http(int fd, int argc, char *argv[])
{
struct ast_http_uri *urih;
+ struct http_uri_redirect *redirect;
+
if (argc != 3)
return RESULT_SHOWUSAGE;
+
ast_cli(fd, "HTTP Server Status:\n");
ast_cli(fd, "Prefix: %s\n", prefix);
if (!http_desc.oldsin.sin_family)
@@ -883,14 +982,23 @@
ast_inet_ntoa(https_desc.oldsin.sin_addr),
ntohs(https_desc.oldsin.sin_port));
}
+
ast_cli(fd, "Enabled URI's:\n");
- urih = uris;
- while(urih){
+ AST_LIST_LOCK(&uris);
+ AST_LIST_TRAVERSE(&uris, urih, entry)
ast_cli(fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
- urih = urih->next;
- }
- if (!uris)
+ if (AST_LIST_EMPTY(&uris))
ast_cli(fd, "None.\n");
+ AST_LIST_UNLOCK(&uris);
+
+ ast_cli(fd, "\nEnabled Redirects:\n");
+ AST_LIST_LOCK(&uri_redirects);
+ AST_LIST_TRAVERSE(&uri_redirects, redirect, entry)
+ ast_cli(fd, " %s => %s\n", redirect->target, redirect->dest);
+ if (AST_LIST_EMPTY(&uri_redirects))
+ ast_cli(fd, " None.\n");
+ AST_LIST_UNLOCK(&uri_redirects);
+
return RESULT_SUCCESS;
}
More information about the asterisk-commits
mailing list