aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Makefile.am2
-rw-r--r--README.md2
-rw-r--r--blogc.spec.in4
-rw-r--r--configure.ac7
-rw-r--r--src/blogc-runserver/main.c187
6 files changed, 119 insertions, 84 deletions
diff --git a/.travis.yml b/.travis.yml
index 15c4906..0c5bd6c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,6 @@ addons:
apt:
packages:
- libcmocka-dev
- - libmagic-dev
- libevent-dev
- rpm
- valgrind
diff --git a/Makefile.am b/Makefile.am
index 6cf2f6c..7ecb21a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -143,12 +143,10 @@ blogc_runserver_SOURCES = \
blogc_runserver_CFLAGS = \
$(AM_CFLAGS) \
$(LIBEVENT_CFLAGS) \
- $(SQUAREBALL_CFLAGS) \
$(NULL)
blogc_runserver_LDADD = \
$(LIBEVENT_LIBS) \
- $(MAGIC_LIBS) \
libblogc_common.la \
$(NULL)
endif
diff --git a/README.md b/README.md
index 74b96f8..609468b 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ Inside the source directory, run the following commands:
$ make
# make install
-The `./configure` options listed above will enable building of helper tools. To learn more about these tools, please read the man pages. Be aware that [`blogc-runserver(1)`](https://blogc.rgm.io/man/blogc-runserver.1.html) depends on [libmagic](https://github.com/file/file) and [libevent](http://libevent.org/), but this tool can be replaced by any HTTP server you want to use.
+The `./configure` options listed above will enable building of helper tools. To learn more about these tools, please read the man pages. Be aware that [`blogc-runserver(1)`](https://blogc.rgm.io/man/blogc-runserver.1.html) depends on [libevent](http://libevent.org/), but this tool can be replaced by any HTTP server you want to use.
To create your first blog, please clone our example repository and adapt it to your needs:
diff --git a/blogc.spec.in b/blogc.spec.in
index 946631d..420a75b 100644
--- a/blogc.spec.in
+++ b/blogc.spec.in
@@ -7,7 +7,7 @@ Summary: A blog compiler
URL: @PACKAGE_URL@
Source0: https://github.com/blogc/blogc/releases/download/v@PACKAGE_VERSION@/blogc-@PACKAGE_VERSION@.tar.xz
%if ! 0%{?el6}
-BuildRequires: libevent-devel >= 2.0, file-devel
+BuildRequires: libevent-devel >= 2.0
%endif
%description
@@ -26,7 +26,7 @@ blogc-git-receiver is a simple login shell/git hook to deploy blogc websites.
%package runserver
Summary: A simple HTTP server to test blogc websites
Group: Development/Tools
-Requires: libevent >= 2.0, file-libs
+Requires: libevent >= 2.0
%description runserver
blogc-runserver is a simple HTTP server to test blogc websites.
diff --git a/configure.ac b/configure.ac
index 11d2216..ce27e54 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,13 +139,6 @@ AS_IF([test "x$enable_runserver" = "xyes"], [
AC_CHECK_HEADERS([signal.h stdarg.h fcntl.h unistd.h sys/stat.h sys/types.h],, [
AC_MSG_ERROR([blogc-runserver tool requested but required headers not found])
])
- AC_CHECK_HEADERS([magic.h],, [
- AC_MSG_ERROR([blogc-runserver tool requested but libmagic headers not found])
- ])
- AC_CHECK_LIB(magic, [magic_open], [MAGIC_LIBS="-lmagic"], [
- AC_MSG_ERROR([blogc-runserver tool requested but libmagic library not found])
- ])
- AC_SUBST(MAGIC_LIBS)
PKG_CHECK_MODULES([LIBEVENT], [libevent >= 2.0])
RUNSERVER="enabled"
have_runserver=yes
diff --git a/src/blogc-runserver/main.c b/src/blogc-runserver/main.c
index 93f404a..e10f8e8 100644
--- a/src/blogc-runserver/main.c
+++ b/src/blogc-runserver/main.c
@@ -13,7 +13,6 @@
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
-#include <magic.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
@@ -26,31 +25,124 @@
#include "../common/utils.h"
-/**
- * this mapping is used to declare "supported" file types, that are forced over
- * whatever detected by libmagic, but we will still use the charset provided by
- * libmagic anyway. it also helps detecting index files when the client asks
- * for a directory.
- */
+// mime types with index should be in the begin of the list. first NULL
+// index aborts the lookup, for optimization
static const struct content_type_map {
const char *mimetype;
const char *extension;
const char *index;
} content_types[] = {
+
+ // with index
{"text/html", "html", "index.html"},
{"text/html", "htm", "index.htm"},
+ {"text/html", "shtml", "index.shtml"},
{"text/xml", "xml", "index.xml"},
{"text/plain", "txt", "index.txt"},
+ {"application/xhtml+xml", "xhtml", "index.xhtml"},
+
+ // withoud index
{"text/css", "css", NULL},
+ {"image/gif", "gif", NULL},
+ {"image/jpeg", "jpeg", NULL},
+ {"image/jpeg", "jpg", NULL},
{"application/javascript", "js", NULL},
+ {"application/atom+xml", "atom", NULL},
+ {"application/rss+xml", "rss", NULL},
+ {"text/mathml", "mml", NULL},
+ {"text/vnd.sun.j2me.app-descriptor", "jad", NULL},
+ {"text/vnd.wap.wml", "wml", NULL},
+ {"text/x-component", "htc", NULL},
+ {"image/png", "png", NULL},
+ {"image/tiff", "tif", NULL},
+ {"image/tiff", "tiff", NULL},
+ {"image/vnd.wap.wbmp", "wbmp", NULL},
+ {"image/x-icon", "ico", NULL},
+ {"image/x-jng", "jng", NULL},
+ {"image/x-ms-bmp", "bmp", NULL},
+ {"image/svg+xml", "svg", NULL},
+ {"image/svg+xml", "svgz", NULL},
+ {"image/webp", "webp", NULL},
+ {"application/font-woff", "woff", NULL},
+ {"application/java-archive", "jar", NULL},
+ {"application/java-archive", "war", NULL},
+ {"application/java-archive", "ear", NULL},
+ {"application/json", "json", NULL},
+ {"application/mac-binhex40", "hqx", NULL},
+ {"application/msword", "doc", NULL},
+ {"application/pdf", "pdf", NULL},
+ {"application/postscript", "ps", NULL},
+ {"application/postscript", "eps", NULL},
+ {"application/postscript", "ai", NULL},
+ {"application/rtf", "rtf", NULL},
+ {"application/vnd.apple.mpegurl", "m3u8", NULL},
+ {"application/vnd.ms-excel", "xls", NULL},
+ {"application/vnd.ms-fontobject", "eot", NULL},
+ {"application/vnd.ms-powerpoint", "ppt", NULL},
+ {"application/vnd.wap.wmlc", "wmlc", NULL},
+ {"application/vnd.google-earth.kml+xml", "kml", NULL},
+ {"application/vnd.google-earth.kmz", "kmz", NULL},
+ {"application/x-7z-compressed", "7z", NULL},
+ {"application/x-cocoa", "cco", NULL},
+ {"application/x-java-archive-diff", "jardiff", NULL},
+ {"application/x-java-jnlp-file", "jnlp", NULL},
+ {"application/x-makeself", "run", NULL},
+ {"application/x-perl", "pl", NULL},
+ {"application/x-perl", "pm", NULL},
+ {"application/x-pilot", "prc", NULL},
+ {"application/x-pilot", "pdb", NULL},
+ {"application/x-rar-compressed", "rar", NULL},
+ {"application/x-redhat-package-manager", "rpm", NULL},
+ {"application/x-sea", "sea", NULL},
+ {"application/x-shockwave-flash", "swf", NULL},
+ {"application/x-stuffit", "sit", NULL},
+ {"application/x-tcl", "tcl", NULL},
+ {"application/x-tcl", "tk", NULL},
+ {"application/x-x509-ca-cert", "der", NULL},
+ {"application/x-x509-ca-cert", "pem", NULL},
+ {"application/x-x509-ca-cert", "crt", NULL},
+ {"application/x-xpinstall", "xpi", NULL},
+ {"application/xspf+xml", "xspf", NULL},
+ {"application/zip", "zip", NULL},
+ {"application/octet-stream", "bin", NULL},
+ {"application/octet-stream", "exe", NULL},
+ {"application/octet-stream", "dll", NULL},
+ {"application/octet-stream", "deb", NULL},
+ {"application/octet-stream", "dmg", NULL},
+ {"application/octet-stream", "iso", NULL},
+ {"application/octet-stream", "img", NULL},
+ {"application/octet-stream", "msi", NULL},
+ {"application/octet-stream", "msp", NULL},
+ {"application/octet-stream", "msm", NULL},
+ {"application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx", NULL},
+ {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx", NULL},
+ {"application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx", NULL},
+ {"audio/midi", "mid", NULL},
+ {"audio/midi", "midi", NULL},
+ {"audio/midi", "kar", NULL},
+ {"audio/mpeg", "mp3", NULL},
+ {"audio/ogg", "ogg", NULL},
+ {"audio/x-m4a", "m4a", NULL},
+ {"audio/x-realaudio", "ra", NULL},
+ {"video/3gpp", "3gpp", NULL},
+ {"video/3gpp", "3gp", NULL},
+ {"video/mp2t", "ts", NULL},
+ {"video/mp4", "mp4", NULL},
+ {"video/mpeg", "mpeg", NULL},
+ {"video/mpeg", "mpg", NULL},
+ {"video/quicktime", "mov", NULL},
+ {"video/webm", "webm", NULL},
+ {"video/x-flv", "flv", NULL},
+ {"video/x-m4v", "m4v", NULL},
+ {"video/x-mng", "mng", NULL},
+ {"video/x-ms-asf", "asx", NULL},
+ {"video/x-ms-asf", "asf", NULL},
+ {"video/x-ms-wmv", "wmv", NULL},
+ {"video/x-msvideo", "avi", NULL},
{NULL, NULL, NULL}
};
-static magic_t magic_all = NULL;
-static magic_t magic_charset = NULL;
-
-
static const char*
get_extension(const char *filename)
{
@@ -68,41 +160,19 @@ get_extension(const char *filename)
}
-static char*
-guess_content_type(const char *filename, int fd)
+static const char*
+guess_content_type(const char *filename)
{
- int newfd;
-
- // try "supported" types first, and just use libmagic for charset
const char *extension = get_extension(filename);
if (extension == NULL)
- goto libmagic;
- const char *supported = NULL;
- for (unsigned int i = 0; content_types[i].extension != NULL; i++)
- if (0 == strcmp(content_types[i].extension, extension))
- supported = content_types[i].mimetype;
- if (supported != NULL) {
- newfd = dup(fd);
- if (-1 != newfd) {
- const char* charset = magic_descriptor(magic_charset, newfd);
- close(newfd);
- if (charset != NULL)
- return bc_strdup_printf("%s; charset=%s", supported, charset);
+ goto default_type;
+ for (unsigned int i = 0; content_types[i].extension != NULL; i++) {
+ if (0 == strcmp(content_types[i].extension, extension)) {
+ return content_types[i].mimetype;
}
- return bc_strdup(supported);
- }
-
-libmagic:
-
- // fallback to use libmagic for everything
- newfd = dup(fd);
- if (-1 != newfd) {
- const char* content_type = magic_descriptor(magic_all, newfd);
- close(newfd);
- if (content_type != NULL)
- return bc_strdup(content_type);
}
- return bc_strdup("application/octet-stream");
+default_type:
+ return "application/octet-stream";
}
@@ -159,13 +229,11 @@ handler(struct evhttp_request *request, void *ptr)
if (S_ISDIR(st.st_mode)) {
char *found = NULL;
- for (unsigned int i = 0; content_types[i].mimetype != NULL; i++) {
- if (content_types[i].index == NULL)
- continue;
+ for (unsigned int i = 0; content_types[i].index != NULL; i++) {
char *f = bc_strdup_printf("%s/%s", real_path,
content_types[i].index);
if (0 == access(f, F_OK)) {
- found = bc_strdup(f);
+ found = f;
break;
}
free(f);
@@ -190,11 +258,11 @@ handler(struct evhttp_request *request, void *ptr)
goto point4;
}
- char *type = guess_content_type(real_path, fd);
+ const char *type = guess_content_type(real_path);
if (fstat(fd, &st) < 0) {
evhttp_send_error(request, 500, "Internal server error");
- goto point5;
+ goto point4;
}
struct evkeyvalq *headers = evhttp_request_get_output_headers(request);
@@ -206,7 +274,7 @@ handler(struct evhttp_request *request, void *ptr)
// production webservers usually returns 301 in such cases, but 302 is
// better for development/testing.
evhttp_send_reply(request, 302, "Found", NULL);
- goto point5;
+ goto point4;
}
evhttp_add_header(headers, "Content-Type", type);
@@ -218,8 +286,6 @@ handler(struct evhttp_request *request, void *ptr)
evbuffer_add_file(evb, fd, 0, st.st_size);
evhttp_send_reply(request, 200, "OK", evb);
-point5:
- free(type);
point4:
free(real_root);
point3:
@@ -355,29 +421,8 @@ main(int argc, char **argv)
if (host == NULL)
host = bc_strdup("127.0.0.1");
- magic_all = magic_open(MAGIC_MIME);
- magic_charset = magic_open(MAGIC_MIME_ENCODING);
- if (magic_all == NULL || magic_charset == NULL) {
- fprintf(stderr, "error: failed to initialize libmagic\n");
- rv = 1;
- goto cleanup;
- }
-
- if ((0 != magic_load(magic_all, NULL)) ||
- (0 != magic_load(magic_charset, NULL)))
- {
- fprintf(stderr, "error: failed to load libmagic data\n");
- magic_close(magic_all);
- magic_close(magic_charset);
- rv = 1;
- goto cleanup;
- }
-
rv = runserver(host, port, docroot);
- magic_close(magic_all);
- magic_close(magic_charset);
-
cleanup:
free(host);
free(docroot);