[svn-commits] russell: branch group/http_mods r59773 - in /team/group/http_mods/main: ./ mi...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Apr 2 16:28:06 MST 2007


Author: russell
Date: Mon Apr  2 18:28:05 2007
New Revision: 59773

URL: http://svn.digium.com/view/asterisk?view=rev&rev=59773
Log: (empty)

Added:
    team/group/http_mods/main/minimime/
    team/group/http_mods/main/minimime/.cvsignore   (with props)
    team/group/http_mods/main/minimime/Doxyfile   (with props)
    team/group/http_mods/main/minimime/Make.conf   (with props)
    team/group/http_mods/main/minimime/Makefile   (with props)
    team/group/http_mods/main/minimime/mimeparser.h   (with props)
    team/group/http_mods/main/minimime/mimeparser.l   (with props)
    team/group/http_mods/main/minimime/mimeparser.y   (with props)
    team/group/http_mods/main/minimime/minimime.c   (with props)
    team/group/http_mods/main/minimime/mm-docs/
    team/group/http_mods/main/minimime/mm-docs/html/
    team/group/http_mods/main/minimime/mm-docs/html/bug.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/doxygen.css   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/files.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/globals.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/globals_func.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__codecs.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__contenttype.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__context.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__envelope.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__error.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__mimepart.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__mimeutil.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__param.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/group__util.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/index.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mimeparser_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mimeparser_8tab_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__codecs_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__contenttype_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__context_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__envelope_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__error_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__header_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__internal_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__internal_8h.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__mem_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__mimepart_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__mimeutil_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__param_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__parse_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__queue_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__util_8c.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/mm__util_8h-source.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/modules.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/pages.html   (with props)
    team/group/http_mods/main/minimime/mm-docs/html/tabs.css   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/
    team/group/http_mods/main/minimime/mm-docs/latex/Makefile   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/bug.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/doxygen.sty   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/files.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__codecs.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__contenttype.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__context.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__envelope.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__error.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__mimepart.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__mimeutil.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__param.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/group__util.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__codecs_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__contenttype_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__context_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__envelope_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__error_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__header_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__internal_8h.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__mimepart_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__mimeutil_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__param_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__parse_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/mm__util_8c.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/modules.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/pages.tex   (with props)
    team/group/http_mods/main/minimime/mm-docs/latex/refman.tex   (with props)
    team/group/http_mods/main/minimime/mm.h   (with props)
    team/group/http_mods/main/minimime/mm_base64.c   (with props)
    team/group/http_mods/main/minimime/mm_codecs.c   (with props)
    team/group/http_mods/main/minimime/mm_contenttype.c   (with props)
    team/group/http_mods/main/minimime/mm_context.c   (with props)
    team/group/http_mods/main/minimime/mm_envelope.c   (with props)
    team/group/http_mods/main/minimime/mm_error.c   (with props)
    team/group/http_mods/main/minimime/mm_header.c   (with props)
    team/group/http_mods/main/minimime/mm_init.c   (with props)
    team/group/http_mods/main/minimime/mm_internal.h   (with props)
    team/group/http_mods/main/minimime/mm_mem.c   (with props)
    team/group/http_mods/main/minimime/mm_mem.h   (with props)
    team/group/http_mods/main/minimime/mm_mimepart.c   (with props)
    team/group/http_mods/main/minimime/mm_mimeutil.c   (with props)
    team/group/http_mods/main/minimime/mm_param.c   (with props)
    team/group/http_mods/main/minimime/mm_parse.c   (with props)
    team/group/http_mods/main/minimime/mm_queue.h   (with props)
    team/group/http_mods/main/minimime/mm_util.c   (with props)
    team/group/http_mods/main/minimime/mm_util.h   (with props)
    team/group/http_mods/main/minimime/mm_warnings.c   (with props)
    team/group/http_mods/main/minimime/strlcat.c   (with props)
    team/group/http_mods/main/minimime/strlcpy.c   (with props)
    team/group/http_mods/main/minimime/sys/
    team/group/http_mods/main/minimime/sys/CVS/
    team/group/http_mods/main/minimime/sys/CVS/Entries   (with props)
    team/group/http_mods/main/minimime/sys/CVS/Repository   (with props)
    team/group/http_mods/main/minimime/sys/CVS/Root   (with props)
    team/group/http_mods/main/minimime/sys/mm_queue.h   (with props)
    team/group/http_mods/main/minimime/test/
    team/group/http_mods/main/minimime/test.sh   (with props)
    team/group/http_mods/main/minimime/test/CVS/
    team/group/http_mods/main/minimime/test/CVS/Entries   (with props)
    team/group/http_mods/main/minimime/test/CVS/Repository   (with props)
    team/group/http_mods/main/minimime/test/CVS/Root   (with props)
    team/group/http_mods/main/minimime/tests/
    team/group/http_mods/main/minimime/tests/CVS/
    team/group/http_mods/main/minimime/tests/CVS/Entries   (with props)
    team/group/http_mods/main/minimime/tests/CVS/Entries.Log   (with props)
    team/group/http_mods/main/minimime/tests/CVS/Repository   (with props)
    team/group/http_mods/main/minimime/tests/CVS/Root   (with props)
    team/group/http_mods/main/minimime/tests/Makefile   (with props)
    team/group/http_mods/main/minimime/tests/create.c   (with props)
    team/group/http_mods/main/minimime/tests/messages/
    team/group/http_mods/main/minimime/tests/messages/CVS/
    team/group/http_mods/main/minimime/tests/messages/CVS/Entries   (with props)
    team/group/http_mods/main/minimime/tests/messages/CVS/Repository   (with props)
    team/group/http_mods/main/minimime/tests/messages/CVS/Root   (with props)
    team/group/http_mods/main/minimime/tests/messages/test1.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test2.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test3.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test4.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test5.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test6.txt   (with props)
    team/group/http_mods/main/minimime/tests/messages/test7.txt   (with props)
    team/group/http_mods/main/minimime/tests/parse.c   (with props)
Modified:
    team/group/http_mods/main/Makefile
    team/group/http_mods/main/http.c

Modified: team/group/http_mods/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/Makefile?view=diff&rev=59773&r1=59772&r2=59773
==============================================================================
--- team/group/http_mods/main/Makefile (original)
+++ team/group/http_mods/main/Makefile Mon Apr  2 18:28:05 2007
@@ -135,7 +135,7 @@
 	@rm -f $(ASTTOPDIR)/include/asterisk/build.h.tmp
 	@$(CC) -c -o buildinfo.o $(ASTCFLAGS) buildinfo.c
 	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
-	$(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS)
+	$(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $^ minimime/libmmime.a buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS)
 	@$(ASTTOPDIR)/build_tools/strip_nonapi $@
 
 clean::
@@ -144,3 +144,4 @@
 	@if [ -f editline/Makefile ]; then $(MAKE) -C editline distclean ; fi
 	@$(MAKE) -C db1-ast clean
 	@$(MAKE) -C stdtime clean
+	@$(MAKE) -C minimime clean

Modified: team/group/http_mods/main/http.c
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/http.c?view=diff&rev=59773&r1=59772&r2=59773
==============================================================================
--- team/group/http_mods/main/http.c (original)
+++ team/group/http_mods/main/http.c Mon Apr  2 18:28:05 2007
@@ -21,8 +21,9 @@
  * \brief http server for AMI access
  *
  * \author Mark Spencer <markster at digium.com>
- * This program implements a tiny http server supporting the "get" method
- * only and was inspired by micro-httpd by Jef Poskanzer 
+ *
+ * This program implements a tiny http server
+ * and was inspired by micro-httpd by Jef Poskanzer 
  * 
  * \ref AstHTTP - AMI over the http protocol
  */
@@ -47,6 +48,8 @@
 #include <fcntl.h>
 #include <pthread.h>
 
+#include "minimime/mm.h"
+
 #include "asterisk/cli.h"
 #include "asterisk/http.h"
 #include "asterisk/utils.h"
@@ -67,6 +70,14 @@
 
 AST_RWLOCK_DEFINE_STATIC(uris_lock);
 static struct ast_http_uri *uris;
+
+struct ast_http_post_mapping {
+	AST_RWLIST_ENTRY(ast_http_post_mapping) entry;
+	char *from;
+	char *to;
+};
+
+static AST_RWLIST_HEAD_STATIC(post_mappings, ast_http_post_mapping);
 
 static int httpfd = -1;
 static pthread_t master = AST_PTHREADT_NULL;
@@ -284,6 +295,231 @@
 		prev = prev->next;
 	}
 	ast_rwlock_unlock(&uris_lock);
+}
+
+/*! \note This assumes that the post_mappings list is locked */
+static struct ast_http_post_mapping *find_post_mapping(const char *uri)
+{
+	struct ast_http_post_mapping *post_map;
+
+	if (!ast_strlen_zero(prefix) && strncmp(prefix, uri, strlen(prefix))) {
+		ast_log(LOG_DEBUG, "URI %s does not have prefix %s\n", uri, prefix);
+		return NULL;
+	}
+
+	uri += strlen(prefix);
+	if (*uri == '/')
+		uri++;
+	
+	AST_RWLIST_TRAVERSE(&post_mappings, post_map, entry) {
+		if (!strcmp(uri, post_map->from))
+			return post_map;
+	}
+
+	return NULL;
+}
+
+static int get_mimepart_header(struct mm_mimepart *part, const char *header,
+	char *hdr_buf, size_t hdr_buf_len)
+{
+	const char *body;
+	const char *val_begin, *val_end;
+	size_t copy_len;
+
+	if (!(body = mm_mimepart_getbody(part, 1))) {
+		ast_log(LOG_DEBUG, "Can't get message part body\n");
+		return -1;
+	}
+
+	if (!(val_begin = strcasestr(body, header))) {
+		ast_log(LOG_DEBUG, "Can't find the header %s in the opaque body\n", header);
+		return -1;
+	}
+	val_begin += strlen(header);
+	val_begin = ast_skip_blanks(val_begin);
+	
+	if (!(val_end = strstr(val_begin, "\r\n"))) {
+		ast_log(LOG_DEBUG, "Can't find the end of the %s header\n", header);
+		return -1;
+	}
+	
+	copy_len = val_end - val_begin + 1;
+	if (copy_len > hdr_buf_len)
+		copy_len = hdr_buf_len;
+
+	ast_copy_string(hdr_buf, val_begin, copy_len);
+
+	return 0;
+}
+
+static int get_filename(struct mm_mimepart *part, char *fn, size_t fn_len)
+{
+	char disp[1024] = "";
+	char *tmp, *filename;
+
+	if (get_mimepart_header(part, "Content-Disposition:", disp, sizeof(disp))) {
+		ast_log(LOG_DEBUG, "No Content-Disposition header\n");
+		return -1;
+	}
+
+#if 0
+	/* This doesn't work ... :( */
+	if (!(disp = mm_mimepart_getheadervalue(part, "Content-Disposition", 0))) {
+		ast_log(LOG_DEBUG, "No Content-Disposition header\n");
+		return -1;
+	}
+#endif
+
+	filename = ast_strdupa(disp);
+	if (!(filename = strcasestr(filename, "filename"))) {
+		ast_log(LOG_DEBUG, "No filename found in the disposition header\n");
+		return -1;
+	}
+
+	strsep(&filename, "=");
+	if (ast_strlen_zero(filename))
+		return -1;
+
+	strsep(&filename, "\"");
+	if (ast_strlen_zero(filename))
+		return -1;
+
+	tmp = filename;
+	strsep(&tmp, "\"");
+
+	ast_log(LOG_DEBUG, "The filename for this part is %s\n", filename);
+	ast_copy_string(fn, filename, fn_len);
+
+	return 0;
+}
+
+static void post_raw(struct mm_mimepart *part, const char *post_dir, const char *fn)
+{
+	char filename[PATH_MAX];
+	FILE *f;
+	const char *body;
+	size_t body_len;
+
+	snprintf(filename, sizeof(filename), "%s/%s", post_dir, fn);
+
+	if (!(f = fopen(filename, "w"))) {
+		ast_log(LOG_WARNING, "Unable to open %s for writing file from a POST!\n", filename);
+		return;
+	}
+
+	if (!(body = mm_mimepart_getbody(part, 0))) {
+		ast_log(LOG_DEBUG, "Couldn't get the mimepart body\n");
+		fclose(f);
+		return;
+	}
+	body_len = mm_mimepart_getlength(part);
+	ast_log(LOG_DEBUG, "Body length is %ld\n", body_len);	
+
+	fwrite(body, 1, body_len, f);
+
+	fclose(f);
+}
+
+static char *handle_post(struct ast_http_server_instance *ser, char *uri, 
+	int *status, char **title, int *contentlength, struct ast_variable *headers)
+{
+	char buf;
+	FILE *f;
+	size_t res;
+	struct ast_variable *var;
+	int content_len = 0;
+	MM_CTX *ctx;
+	int mm_res, i;
+	struct ast_http_post_mapping *post_map;
+	const char *post_dir;
+
+	ast_log(LOG_DEBUG, "uri: %s\n", uri);
+	*status = 404;
+	*title = ast_strdup("Not Found");
+
+	if (!(f = fopen("/tmp/ast_postdata", "w")))
+		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+
+	for (var = headers; var; var = var->next) {
+		ast_log(LOG_DEBUG, "Name: %s  Value: %s\n", var->name, var->value);
+		if (!strcasecmp(var->name, "Content-Length")) {
+			if ((sscanf(var->value, "%u", &content_len)) != 1) {
+				ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n");
+				return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+			}
+			ast_log(LOG_DEBUG, "Got Content-Length of %d\n", content_len);
+		} else if (!strcasecmp(var->name, "Content-Type"))
+			fprintf(f, "Content-Type: %s\r\n\r\n", var->value);
+	}
+
+	while ((res = fread(&buf, 1, 1, ser->f))) {
+		fwrite(&buf, 1, 1, f);
+		content_len--;
+		if (!content_len)
+			break;
+	}
+
+	fclose(f);
+
+	AST_RWLIST_RDLOCK(&post_mappings);
+	if (!(post_map = find_post_mapping(uri))) {
+		ast_log(LOG_DEBUG, "%s is not a valid URI for POST\n", uri);
+		AST_RWLIST_UNLOCK(&post_mappings);
+		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+	}
+	post_dir = ast_strdupa(post_map->to);
+	post_map = NULL;
+	AST_RWLIST_UNLOCK(&post_mappings);
+
+	ast_log(LOG_DEBUG, "Going to post files to dir %s\n", post_dir);
+
+	if (!(ctx = mm_context_new()))
+		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+
+	mm_res = mm_parse_file(ctx, "/tmp/ast_postdata", MM_PARSE_LOOSE, 0);
+	if (mm_res == -1) {
+		ast_log(LOG_ERROR, "Error parsing MIME data\n");
+		mm_context_free(ctx);
+		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+	}
+
+	mm_res = mm_context_countparts(ctx);
+	if (!mm_res) {
+		ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n");
+		mm_context_free(ctx);
+		return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
+	}
+	if (mm_context_iscomposite(ctx))
+		ast_log(LOG_DEBUG, "Found %d MIME parts\n", mm_res - 1);
+	else
+		ast_log(LOG_DEBUG, "We have a flag (not multi-part) message\n");
+
+	for (i = 1; i < mm_res; i++) {
+		struct mm_mimepart *part;
+		char fn[PATH_MAX];
+		char content_type[1024];
+
+		if (!(part = mm_context_getpart(ctx, i))) {
+			ast_log(LOG_DEBUG, "Failed to get mime part num %d\n", i);
+			continue;
+		}
+
+		ast_log(LOG_DEBUG, "Body of Part %d: %s\n", i, mm_mimepart_getbody(part, 0));
+
+		if (get_filename(part, fn, sizeof(fn)))
+			continue;
+		if (get_mimepart_header(part, "Content-Type:", content_type, sizeof(content_type)))
+			continue;
+
+		if (!strcasecmp(content_type, "application/octet-stream"))
+			post_raw(part, post_dir, fn);
+		else
+			ast_log(LOG_WARNING, "Don't know how to handle Content-Type '%s'\n", content_type);
+	}
+
+	mm_context_free(ctx);
+
+	return ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server.");
 }
 
 static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **title, int *contentlength, struct ast_variable **cookies)
@@ -375,13 +611,14 @@
 	char cookie[4096];
 	char timebuf[256];
 	struct ast_http_server_instance *ser = data;
-	struct ast_variable *var, *prev=NULL, *vars=NULL;
+	struct ast_variable *var, *prev=NULL, *vars=NULL, *headers = NULL;
 	char *uri, *c, *title=NULL;
 	char *vname, *vval;
 	int status = 200, contentlength = 0;
 	time_t t;
 
 	if (fgets(buf, sizeof(buf), ser->f)) {
+		ast_log(LOG_DEBUG, "Read line (1): %s\n", buf);
 		/* Skip method */
 		uri = buf;
 		while(*uri && (*uri > 32))
@@ -405,6 +642,7 @@
 		}
 
 		while (fgets(cookie, sizeof(cookie), ser->f)) {
+			ast_log(LOG_DEBUG, "Read line (2): %s\n", cookie);
 			/* Trim trailing characters */
 			while(!ast_strlen_zero(cookie) && (cookie[strlen(cookie) - 1] < 33)) {
 				cookie[strlen(cookie) - 1] = '\0';
@@ -458,12 +696,31 @@
 						}
 					}
 				}
+			} else {
+				char *name, *value;
+
+				ast_log(LOG_DEBUG, "Other Header: %s\n", cookie);
+
+				value = ast_strdupa(cookie);
+				name = strsep(&value, ":");
+				if (!value)
+					continue;
+				value = ast_skip_blanks(value);
+				if (ast_strlen_zero(value))
+					continue;
+				var = ast_variable_new(name, value);
+				if (!var)
+					continue;
+				var->next = headers;
+				headers = var;
 			}
 		}
 
 		if (*uri) {
 			if (!strcasecmp(buf, "get")) 
 				c = handle_uri(&ser->requestor, uri, &status, &title, &contentlength, &vars);
+			else if (!strcasecmp(buf, "post")) 
+				c = handle_post(ser, uri, &status, &title, &contentlength, headers);
 			else 
 				c = ast_http_error(501, "Not Implemented", NULL, "Attempt to use unimplemented / unsupported method");\
 		} else 
@@ -623,6 +880,47 @@
 	}
 }
 
+static void destroy_post_mapping(struct ast_http_post_mapping *post_map)
+{
+	if (post_map->from)
+		free(post_map->from);
+	if (post_map->to)
+		free(post_map->to);
+	free(post_map);
+}
+
+static void destroy_post_mappings(void)
+{
+	struct ast_http_post_mapping *post_map;
+
+	AST_RWLIST_WRLOCK(&post_mappings);
+	while ((post_map = AST_RWLIST_REMOVE_HEAD(&post_mappings, entry)))
+		destroy_post_mapping(post_map);
+	AST_RWLIST_UNLOCK(&post_mappings);
+}
+
+static void add_post_mapping(const char *from, const char *to)
+{
+	struct ast_http_post_mapping *post_map;
+
+	if (!(post_map = ast_calloc(1, sizeof(*post_map))))
+		return;
+
+	if (!(post_map->from = ast_strdup(from))) {
+		destroy_post_mapping(post_map);
+		return;
+	}
+
+	if (!(post_map->to = ast_strdup(to))) {
+		destroy_post_mapping(post_map);
+		return;
+	}
+
+	AST_RWLIST_WRLOCK(&post_mappings);
+	AST_RWLIST_INSERT_TAIL(&post_mappings, post_map, entry);
+	AST_RWLIST_UNLOCK(&post_mappings);
+}
+
 static int __ast_http_load(int reload)
 {
 	struct ast_config *cfg;
@@ -636,7 +934,11 @@
 
 	memset(&sin, 0, sizeof(sin));
 	sin.sin_port = htons(8088);
+
 	strcpy(newprefix, DEFAULT_PREFIX);
+
+	destroy_post_mappings();
+
 	cfg = ast_config_load("http.conf");
 	if (cfg) {
 		v = ast_variable_browse(cfg, "general");
@@ -664,6 +966,10 @@
 			}
 			v = v->next;
 		}
+
+		for (v = ast_variable_browse(cfg, "post_mappings"); v; v = v->next)
+			add_post_mapping(v->name, v->value);
+
 		ast_config_destroy(cfg);
 	}
 	if (enabled)
@@ -673,15 +979,21 @@
 		prefix_len = strlen(prefix);
 	}
 	enablestatic = newenablestatic;
+
 	http_server_start(&sin);
+
+
 	return 0;
 }
 
 static int handle_show_http(int fd, int argc, char *argv[])
 {
 	struct ast_http_uri *urih;
+	struct ast_http_post_mapping *post_map;
+
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
+
 	ast_cli(fd, "HTTP Server Status:\n");
 	ast_cli(fd, "Prefix: %s\n", prefix);
 	if (oldsin.sin_family)
@@ -700,6 +1012,14 @@
 	if (!uris)
 		ast_cli(fd, "None.\n");
 	ast_rwlock_unlock(&uris_lock);
+
+	ast_cli(fd, "\nPOST mappings:\n");
+	AST_RWLIST_RDLOCK(&post_mappings);
+	AST_LIST_TRAVERSE(&post_mappings, post_map, entry)
+		ast_cli(fd, "%s/%s => %s\n", prefix, post_map->from, post_map->to);
+	ast_cli(fd, "%s\n", AST_LIST_EMPTY(&post_mappings) ? "None.\n" : "");
+	AST_RWLIST_UNLOCK(&post_mappings);
+
 	return RESULT_SUCCESS;
 }
 
@@ -720,8 +1040,12 @@
 
 int ast_http_init(void)
 {
+	mm_library_init();
+	mm_codec_registerdefaultcodecs();
+
 	ast_http_uri_link(&statusuri);
 	ast_http_uri_link(&staticuri);
 	ast_cli_register_multiple(cli_http, sizeof(cli_http) / sizeof(struct ast_cli_entry));
+
 	return __ast_http_load(0);
 }

Added: team/group/http_mods/main/minimime/.cvsignore
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/.cvsignore?view=auto&rev=59773
==============================================================================
--- team/group/http_mods/main/minimime/.cvsignore (added)
+++ team/group/http_mods/main/minimime/.cvsignore Mon Apr  2 18:28:05 2007
@@ -1,0 +1,4 @@
+minimime
+*.so.*
+*.o
+*.swp

Propchange: team/group/http_mods/main/minimime/.cvsignore
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/http_mods/main/minimime/.cvsignore
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/http_mods/main/minimime/.cvsignore
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/group/http_mods/main/minimime/Doxyfile
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/Doxyfile?view=auto&rev=59773
==============================================================================
--- team/group/http_mods/main/minimime/Doxyfile (added)
+++ team/group/http_mods/main/minimime/Doxyfile Mon Apr  2 18:28:05 2007
@@ -1,0 +1,1098 @@
+# Doxyfile 1.3.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MiniMIME
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = mm-docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is used 
+# as the annotated text. Otherwise, the brief description is used as-is. If left 
+# blank, the following values are used ("$name" is automatically replaced with the 
+# name of the entity): "The $name class" "The $name widget" "The $name file" 
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+

[... 19363 lines stripped ...]


More information about the svn-commits mailing list