summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-03-24 21:15:21 +0000
committerLennart Poettering <lennart@poettering.net>2004-03-24 21:15:21 +0000
commitc174f20109543c0a0bc999369784a8ee52f7141c (patch)
treed8a892a1264831e9829f363c03bf3ae4bf7e5223 /src
parent85b5c5365026f6a49d441e11810e8e3fe1d57ea8 (diff)
initial commit
git-svn-id: file:///home/lennart/svn/public/mod_mime_xattr/trunk@3 f01872de-66d6-0310-9185-fc3b30f50adc
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in64
-rw-r--r--src/mod_mime_xattr.c227
2 files changed, 291 insertions, 0 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..0311c0d
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,64 @@
+# $Id$
+
+# Copyright 2004 Lennart Poettering
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You
+# may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+DISTFILES=Makefile.in mod_mime_xattr.c
+APXS=@APXS@
+APACHECTL=apachectl
+
+# additional user defines, includes and libraries
+#DEF=-Dmy_define=my_value
+#INC=-Imy/include/dir
+#LIB=-Lmy/lib/dir -lc -lmylib
+LIB=-lattr
+
+# the default target
+all: mod_mime_xattr.so
+
+# compile the DSO file
+mod_mime_xattr.so: mod_mime_xattr.c
+ $(APXS) -c $(DEF) $(INC) $(LIB) mod_mime_xattr.c
+
+# install the DSO file into the Apache installation
+# and activate it in the Apache configuration
+install: all
+ $(APXS) -i -a -n 'mime_xattr' mod_mime_xattr.so
+
+# cleanup
+clean:
+ -rm -f mod_mime_xattr.o mod_mime_xattr.so
+
+# reload the module by installing and restarting Apache
+reload: install restart
+
+# the general Apache start/restart/stop procedures
+start:
+ $(APACHECTL) start
+restart:
+ $(APACHECTL) restart
+stop:
+ $(APACHECTL) stop
+
+distdir:
+ mkdir -p $(distdir)
+ cp -p $(DISTFILES) $(distdir)
+
+mostlyclean: clean
+distclean: clean
+
+maintainer-clean: clean
+ rm -f Makefile
+
+.PHONY: all clean maintainer-clean mostlyclean distclean distdir install reload start stop restart
diff --git a/src/mod_mime_xattr.c b/src/mod_mime_xattr.c
new file mode 100644
index 0000000..434de4a
--- /dev/null
+++ b/src/mod_mime_xattr.c
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+/***
+
+ Copyright 2004 Lennart Poettering
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you
+ may not use this file except in compliance with the License. You
+ may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+***/
+
+#include <sys/types.h>
+#include <attr/xattr.h>
+#include <ctype.h>
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "ap_config.h"
+
+#define XATTR_NAME_MIMETYPE "user.mime-type"
+#define XATTR_NAME_ENCODING "user.mime-encoding"
+#define XATTR_NAME_CHARSET "user.charset"
+#define XATTR_NAME_HANDLER "user.apache-handler"
+
+module MODULE_VAR_EXPORT mime_xattr_module;
+
+struct mime_xattr_dir_config {
+ int enable_mime_type;
+ int enable_handler;
+};
+
+static void* create_mime_xattr_dir_config(pool *p, char*dummy) {
+ struct mime_xattr_dir_config *c = (struct mime_xattr_dir_config*) ap_palloc(p, sizeof(struct mime_xattr_dir_config));
+ c->enable_mime_type = 0;
+ c->enable_handler = 0;
+ return c;
+}
+
+static const char *enable_xattr_mime_type(cmd_parms *parms, void *mconfig, int flag) {
+ struct mime_xattr_dir_config *c = (struct mime_xattr_dir_config*) mconfig;
+ c->enable_mime_type = flag;
+ return NULL;
+}
+
+static const char *enable_xattr_handler(cmd_parms *parms, void *mconfig, int flag) {
+ struct mime_xattr_dir_config *c = (struct mime_xattr_dir_config*) mconfig;
+ c->enable_handler = flag;
+ return NULL;
+}
+
+static const command_rec mime_xattr_cmds[] = {
+ {"XAttrMimeType",
+ enable_xattr_mime_type,
+ NULL,
+ OR_FILEINFO,
+ FLAG,
+ "Requires 'On' or 'Off' for enabling resp. disabling usage of file system extended attribute data for MIME type detection." },
+
+ {"XAttrHandler",
+ enable_xattr_handler,
+ NULL,
+ OR_FILEINFO,
+ FLAG,
+ "Requires 'On' or 'Off' for enabling resp. disabling usage of file system extended attribute data for handler detection." },
+
+ { NULL }
+};
+
+static char* get_xattr(pool *p, const char *fn, const char *attr) {
+ char v[256];
+ ssize_t l;
+
+ if ((l = lgetxattr(fn, attr, v, sizeof(v)-1)) < 0)
+ if ((l = getxattr(fn, attr, v, sizeof(v)-1)) < 0)
+ return NULL;
+
+ v[l] = 0;
+
+ return ap_pstrdup(p, v);
+}
+
+static char* validate_charset(char *f) {
+ char *c;
+
+ for (c = f; *c; c++) {
+ *c = tolower(*c);
+ if (!(*c >= 'a' && *c <= 'z') && !(*c >= '0' && *c <= '9') && *c != '-')
+ return NULL;
+ }
+
+ return c > f ? f : NULL;
+}
+
+#define validate_encoding(f) validate_charset(f)
+#define validate_handler(f) validate_charset(f)
+
+static char* validate_mime_type(char *f) {
+ char *c, *slash = NULL;
+
+ for (c = f; *c; c++) {
+ *c = tolower(*c);
+
+ if (*c == '/') {
+ if (!slash && c > f) {
+ slash = c;
+ continue;
+ } else
+ return NULL;
+ }
+
+ if (!(*c >= 'a' && *c <= 'z') && !(*c >= '0' && *c <= '9') && *c != '-')
+ return NULL;
+ }
+
+ return c > f && slash && slash < c-1 ? f : NULL;
+}
+
+static int find_ct(request_rec *r) {
+ int result = DECLINED;
+ struct mime_xattr_dir_config* c;
+
+ if (r->finfo.st_mode == 0 || !r->filename || !S_ISREG(r->finfo.st_mode))
+ return DECLINED;
+
+ c = (struct mime_xattr_dir_config*) ap_get_module_config(r->per_dir_config, &mime_xattr_module);
+
+ if (c->enable_mime_type) {
+ char *mime_type, *charset, *encoding;
+
+ if ((charset = get_xattr(r->pool, r->filename, XATTR_NAME_CHARSET)))
+ if (!(charset = validate_charset(charset)))
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_mime_xattr: bad charset specification on file <%s>", r->filename);
+
+ if ((mime_type = get_xattr(r->pool, r->filename, XATTR_NAME_MIMETYPE))) {
+ if (!(mime_type = validate_mime_type(mime_type)))
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_mime_xattr: bad mime type specification on file <%s>", r->filename);
+ else {
+ if (charset)
+ mime_type = ap_psprintf(r->pool, "%s; charset=%s", mime_type, charset);
+
+ r->content_type = mime_type;
+ result = OK;
+ }
+ }
+
+ if (charset && !mime_type && r->content_type) {
+ char *a, *ct = ap_pstrdup(r->pool, r->content_type);
+ static const char spec[] = "; charset=";
+
+ if ((a = strstr(ct, spec))) {
+ char *e;
+ e = a+strlen(spec);
+ e += strcspn(e, "; ");
+
+ *a = 0;
+
+ r->content_type = ap_psprintf(r->pool, "%s; charset=%s%s", ct, charset, e);
+ } else
+ r->content_type = ap_psprintf(r->pool, "%s; charset=%s", ct, charset);
+ }
+
+ if ((encoding = get_xattr(r->pool, r->filename, XATTR_NAME_ENCODING))) {
+ if (!(encoding = validate_encoding(encoding)))
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_mime_xattr: bad encoding specification on file <%s>", r->filename);
+ else
+ r->content_encoding = encoding;
+ }
+ }
+
+ if (c->enable_handler) {
+ char *handler;
+
+ if ((handler = get_xattr(r->pool, r->filename, XATTR_NAME_HANDLER))) {
+ if (!(handler = validate_handler(handler)))
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_mime_xattr: bad apache handler specification on file <%s>", r->filename);
+ else {
+ r->handler = handler;
+ result = OK;
+ }
+ }
+ }
+
+ return result;
+}
+
+/* Dispatch list for API hooks */
+module MODULE_VAR_EXPORT mime_xattr_module = {
+ STANDARD_MODULE_STUFF,
+ NULL, /* module initializer */
+ create_mime_xattr_dir_config, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ mime_xattr_cmds, /* table of config file commands */
+ NULL, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ NULL, /* [#4] validate user id from request */
+ NULL, /* [#5] check if the user is ok _here_ */
+ NULL, /* [#3] check access by host address */
+ find_ct, /* [#6] determine MIME type */
+ NULL, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ NULL, /* [#2] header parser */
+ NULL, /* child_init */
+ NULL, /* child_exit */
+ NULL /* [#0] post read-request */
+#ifdef EAPI
+ ,NULL, /* EAPI: add_module */
+ NULL, /* EAPI: remove_module */
+ NULL, /* EAPI: rewrite_command */
+ NULL /* EAPI: new_connection */
+#endif
+};