Bug 6927 - CLI command has 3 args, not 2.
[asterisk/asterisk.git] / http.c
diff --git a/http.c b/http.c
index 5fcdc8a..97eb676 100644 (file)
--- a/http.c
+++ b/http.c
 
 /*!
  * \file 
- * \brief http server
+ * \brief http server for AMI access
  *
+ * \author Mark Spencer <markster@digium.com>
  * This program implements a tiny http server supporting the "get" method
  * only and was inspired by micro-httpd by Jef Poskanzer 
+ * 
+ * \ref AstHTTP - AMI over the http protocol
  */
 
 #include <sys/types.h>
@@ -41,6 +44,9 @@
 #include <pthread.h>
 
 #include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
 #include "asterisk/cli.h"
 #include "asterisk/http.h"
 #include "asterisk/utils.h"
@@ -49,7 +55,7 @@
 #include "asterisk/config.h"
 
 #define MAX_PREFIX 80
-#define DEFAULT_PREFIX "asterisk"
+#define DEFAULT_PREFIX "/asterisk"
 
 struct ast_http_server_instance {
        FILE *f;
@@ -67,7 +73,7 @@ static int prefix_len = 0;
 static struct sockaddr_in oldsin;
 static int enablestatic=0;
 
-/* Limit the kinds of files we're willing to serve up */
+/*! \brief Limit the kinds of files we're willing to serve up */
 static struct {
        char *ext;
        char *mtype;
@@ -278,8 +284,6 @@ static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **
        struct ast_variable *vars=NULL, *v, *prev = NULL;
        
        
-       if (*uri == '/')
-               uri++;
        params = strchr(uri, '?');
        if (params) {
                *params = '\0';
@@ -334,6 +338,11 @@ static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **
        if (urih) {
                c = urih->callback(sin, uri, vars, status, title, contentlength);
                ast_variables_destroy(vars);
+       } else if (ast_strlen_zero(uri) && ast_strlen_zero(prefix)) {
+               /* Special case: If no prefix, and no URI, send to /static/index.html */
+               c = 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");
        } else {
                c = ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this serer.");
                *status = 404;
@@ -357,18 +366,21 @@ static void *ast_httpd_helper_thread(void *data)
        if (fgets(buf, sizeof(buf), ser->f)) {
                /* Skip method */
                uri = buf;
-               while(*uri && (*uri > 32)) uri++;
+               while(*uri && (*uri > 32))
+                       uri++;
                if (*uri) {
                        *uri = '\0';
                        uri++;
                }
 
                /* Skip white space */
-               while (*uri && (*uri < 33)) uri++;
+               while (*uri && (*uri < 33))
+                       uri++;
 
                if (*uri) {
                        c = uri;
-                       while (*c && (*c > 32)) c++;
+                       while (*c && (*c > 32))
+                                c++;
                        if (*c) {
                                *c = '\0';
                        }
@@ -452,6 +464,8 @@ static void *http_root(void *data)
        int sinlen;
        struct ast_http_server_instance *ser;
        pthread_t launched;
+       pthread_attr_t attr;
+       
        for (;;) {
                ast_wait_for_input(httpfd, -1);
                sinlen = sizeof(sin);
@@ -466,7 +480,10 @@ static void *http_root(void *data)
                        ser->fd = fd;
                        memcpy(&ser->requestor, &sin, sizeof(ser->requestor));
                        if ((ser->f = fdopen(ser->fd, "w+"))) {
-                               if (ast_pthread_create(&launched, NULL, ast_httpd_helper_thread, ser)) {
+                               pthread_attr_init(&attr);
+                               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+                               
+                               if (ast_pthread_create(&launched, &attr, ast_httpd_helper_thread, ser)) {
                                        ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
                                        fclose(ser->f);
                                        free(ser);
@@ -484,7 +501,7 @@ static void *http_root(void *data)
        return NULL;
 }
 
-char *ast_http_setcookie(const char *var, const char *val, int expires, char *buf, int buflen)
+char *ast_http_setcookie(const char *var, const char *val, int expires, char *buf, size_t buflen)
 {
        char *c;
        c = buf;
@@ -567,6 +584,7 @@ static int __ast_http_load(int reload)
        struct hostent *hp;
        struct ast_hostent ahp;
        char newprefix[MAX_PREFIX];
+
        memset(&sin, 0, sizeof(sin));
        sin.sin_port = 8088;
        strcpy(newprefix, DEFAULT_PREFIX);
@@ -586,8 +604,15 @@ static int __ast_http_load(int reload)
                                } else {
                                        ast_log(LOG_WARNING, "Invalid bind address '%s'\n", v->value);
                                }
-                       } else if (!strcasecmp(v->name, "prefix"))
-                               ast_copy_string(newprefix, v->value, sizeof(newprefix));
+                       } else if (!strcasecmp(v->name, "prefix")) {
+                               if (!ast_strlen_zero(v->value)) {
+                                       newprefix[0] = '/';
+                                       ast_copy_string(newprefix + 1, v->value, sizeof(newprefix) - 1);
+                               } else {
+                                       newprefix[0] = '\0';
+                               }
+                                       
+                       }
                        v = v->next;
                }
                ast_config_destroy(cfg);
@@ -607,7 +632,7 @@ static int handle_show_http(int fd, int argc, char *argv[])
 {
        char iabuf[INET_ADDRSTRLEN];
        struct ast_http_uri *urih;
-       if (argc != 2)
+       if (argc != 3)
                return RESULT_SHOWUSAGE;
        ast_cli(fd, "HTTP Server Status:\n");
        ast_cli(fd, "Prefix: %s\n", prefix);
@@ -620,7 +645,7 @@ static int handle_show_http(int fd, int argc, char *argv[])
        ast_cli(fd, "Enabled URI's:\n");
        urih = uris;
        while(urih){
-               ast_cli(fd, "/%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
+               ast_cli(fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
                urih = urih->next;
        }
        if (!uris)
@@ -634,12 +659,12 @@ int ast_http_reload(void)
 }
 
 static char show_http_help[] =
-"Usage: show http\n"
+"Usage: http show status\n"
 "       Shows status of internal HTTP engine\n";
 
 static struct ast_cli_entry http_cli[] = {
-       { { "show", "http", NULL }, handle_show_http,
-         "Display HTTP status", show_http_help },
+       { { "http", "show", "status", NULL }, handle_show_http,
+         "Display HTTP server status", show_http_help },
 };
 
 int ast_http_init(void)