diff --git a/configure b/configure
index 5e36bac66adfb646e6ed8cf8ef365b69ddb50865..c440f1898686a4b60499e30ec6b4077192b575f0 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac Revision: 71732 .
+# From configure.ac Revision: 72539 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.61.
 #
@@ -16476,6 +16476,66 @@ _ACEOF
 
 
 
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+     #include <sys/sendfile.h>
+int
+main ()
+{
+sendfile(1, 0, NULL, 1);
+  ;
+  return 0;
+}
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+
+    { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+       have_sendfile=yes
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+       have_sendfile=no
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test "${have_sendfile}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SENDFILE 1
+_ACEOF
+
+fi
+
 # do the package library checks now
 
 
diff --git a/configure.ac b/configure.ac
index 4c4a48c7ad07e9faa8b112f55171d96fe544e818..9e8279d0711a06c784b579db7e15431639e27a54 100644
--- a/configure.ac
+++ b/configure.ac
@@ -364,6 +364,23 @@ AC_CHECK_HEADER([libkern/OSAtomic.h],
 
 AC_CHECK_SIZEOF(int)
 
+AC_COMPILE_IFELSE(
+  [AC_LANG_PROGRAM(
+    [#include <stdlib.h>
+     #include <sys/sendfile.h>],
+    [sendfile(1, 0, NULL, 1);])
+  ],[
+    AC_MSG_RESULT(yes)
+       have_sendfile=yes
+  ],[
+    AC_MSG_RESULT(no)
+       have_sendfile=no
+  ]
+)
+if test "${have_sendfile}" = "yes"; then
+  AC_DEFINE([HAVE_SENDFILE], 1, [Define if your system has the sendfile syscall.])
+fi
+
 # do the package library checks now
 
 AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -ldl])
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 85618b9e35eb878a1ebb4ba3f86c1c67bfe2dcd4..3f175ddf06c7f7cd3309ec8a87e64969426066bc 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -394,6 +394,9 @@
 /* Define to 1 if you have the `select' function. */
 #undef HAVE_SELECT
 
+/* Define if your system has the sendfile syscall. */
+#undef HAVE_SENDFILE
+
 /* Define to 1 if you have the `setenv' function. */
 #undef HAVE_SETENV
 
diff --git a/include/asterisk/http.h b/include/asterisk/http.h
index 9d92ef5a76b546beb65b91b03aea6160da0f92cf..b0215221e69b87bd60a1734eccd2762521c9f406 100644
--- a/include/asterisk/http.h
+++ b/include/asterisk/http.h
@@ -147,7 +147,7 @@ int ssl_setup(struct tls_config *cfg);
    content is specified) 
 \endverbatim
 */
-typedef struct ast_str *(*ast_http_callback)(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
+typedef struct ast_str *(*ast_http_callback)(struct server_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
 
 /*! \brief Definition of a URI reachable in the embedded HTTP server */
 struct ast_http_uri {
diff --git a/main/http.c b/main/http.c
index d6c4e25f3481742461112f26f65ea6238582f1cb..f71ae0dfb18d0d60302daf251ca3d823c18ca9ec 100644
--- a/main/http.c
+++ b/main/http.c
@@ -48,6 +48,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <fcntl.h>
 #include <pthread.h>
 
+#ifdef HAVE_SENDFILE
+#include <sys/sendfile.h>
+#endif
+
 #include "minimime/mm.h"
 
 #include "asterisk/cli.h"
@@ -145,9 +149,8 @@ static const char *ftype2mtype(const char *ftype, char *wkspace, int wkspacelen)
 	return wkspace;
 }
 
-static struct ast_str *static_callback(struct sockaddr_in *req, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
+static struct ast_str *static_callback(struct server_instance *ser, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
 {
-	struct ast_str *result;
 	char *path;
 	char *ftype;
 	const char *mtype;
@@ -155,6 +158,8 @@ static struct ast_str *static_callback(struct sockaddr_in *req, const char *uri,
 	struct stat st;
 	int len;
 	int fd;
+	time_t t;
+	char buf[256];
 
 	/* Yuck.  I'm not really sold on this, but if you don't deliver static content it makes your configuration 
 	   substantially more challenging, but this seems like a rather irritating feature creep on Asterisk. */
@@ -185,21 +190,28 @@ static struct ast_str *static_callback(struct sockaddr_in *req, const char *uri,
 	if (fd < 0)
 		goto out403;
 
-	len = st.st_size + strlen(mtype) + 40;
-	result = ast_str_create(len);
-	if (result == NULL)	/* XXX not really but... */
-		goto out403;
+	time(&t);
+	strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
+	fprintf(ser->f, "HTTP/1.1 200 OK\r\n"
+		"Server: Asterisk/%s\r\n"
+		"Date: %s\r\n"
+		"Connection: close\r\n"
+		"Cache-Control: no-cache, no-store\r\n"
+		"Content-Length: %d\r\n"
+		"Content-type: %s\r\n\r\n",
+		ASTERISK_VERSION, buf, (int) st.st_size, mtype);
+
+	fflush(ser->f);
+
+#ifdef HAVE_SENDFILE
+	sendfile(ser->fd, fd, NULL, st.st_size);
+#else
+	while ((len = read(fd, buf, sizeof(buf))) > 0)
+		write(ser->fd, buf, len);
+#endif
 
-	ast_str_append(&result, 0, "Content-type: %s\r\n\r\n", mtype);
-	*contentlength = read(fd, result->str + result->used, st.st_size);
-	if (*contentlength < 0) {
-		close(fd);
-		ast_free(result);
-		goto out403;
-	}
-	result->used += *contentlength;
 	close(fd);
-	return result;
+	return NULL;
 
 out404:
 	*status = 404;
@@ -213,7 +225,7 @@ out403:
 }
 
 
-static struct ast_str *httpstatus_callback(struct sockaddr_in *req, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
+static struct ast_str *httpstatus_callback(struct server_instance *ser, const char *uri, struct ast_variable *vars, int *status, char **title, int *contentlength)
 {
 	struct ast_str *out = ast_str_create(512);
 	struct ast_variable *v;
@@ -541,7 +553,7 @@ static struct ast_str *handle_post(struct server_instance *ser, char *uri,
 	return ast_http_error(200, "OK", NULL, "File successfully uploaded.");
 }
 
-static struct ast_str *handle_uri(struct sockaddr_in *sin, char *uri, int *status, 
+static struct ast_str *handle_uri(struct server_instance *ser, char *uri, int *status, 
 	char **title, int *contentlength, struct ast_variable **cookies, 
 	unsigned int *static_content)
 {
@@ -627,7 +639,7 @@ static struct ast_str *handle_uri(struct sockaddr_in *sin, char *uri, int *statu
 	if (urih) {
 		if (urih->static_content)
 			*static_content = 1;
-		out = urih->callback(sin, uri, vars, status, title, contentlength);
+		out = urih->callback(ser, uri, vars, status, title, contentlength);
 		AST_RWLIST_UNLOCK(&uris);
 	} else {
 		out = ast_http_error(404, "Not Found", NULL,
@@ -834,14 +846,12 @@ static void *httpd_helper_thread(void *data)
 		out = ast_http_error(501, "Not Implemented", NULL,
 			"Attempt to use unimplemented / unsupported method");
 	else	/* try to serve it */
-		out = handle_uri(&ser->requestor, uri, &status, &title, &contentlength, &vars, &static_content);
+		out = handle_uri(ser, uri, &status, &title, &contentlength, &vars, &static_content);
 
 	/* If they aren't mopped up already, clean up the cookies */
 	if (vars)
 		ast_variables_destroy(vars);
 
-	if (out == NULL)
-		out = ast_http_error(500, "Internal Error", NULL, "Internal Server Error");
 	if (out) {
 		time_t t = time(NULL);
 		char timebuf[256];
diff --git a/main/manager.c b/main/manager.c
index 2c66f5fb404b748bc43d9aa1bdc414cda6f476fe..a905bc19959314b0f33bf878454d1126a7020352 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -3182,19 +3182,19 @@ generic_callback_out:
 	return out;
 }
 
-static struct ast_str *manager_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
+static struct ast_str *manager_http_callback(struct server_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
 {
-	return generic_http_callback(FORMAT_HTML, requestor, uri, params, status, title, contentlength);
+	return generic_http_callback(FORMAT_HTML, &ser->requestor, uri, params, status, title, contentlength);
 }
 
-static struct ast_str *mxml_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
+static struct ast_str *mxml_http_callback(struct server_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
 {
-	return generic_http_callback(FORMAT_XML, requestor, uri, params, status, title, contentlength);
+	return generic_http_callback(FORMAT_XML, &ser->requestor, uri, params, status, title, contentlength);
 }
 
-static struct ast_str *rawman_http_callback(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
+static struct ast_str *rawman_http_callback(struct server_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
 {
-	return generic_http_callback(FORMAT_RAW, requestor, uri, params, status, title, contentlength);
+	return generic_http_callback(FORMAT_RAW, &ser->requestor, uri, params, status, title, contentlength);
 }
 
 struct ast_http_uri rawmanuri = {