diff -ur lighttpd-1.2.7-orig/config.h.in lighttpd-1.2.7-xattr/config.h.in --- lighttpd-1.2.7-orig/config.h.in 2004-08-29 04:03:44.000000000 -0600 +++ lighttpd-1.2.7-xattr/config.h.in 2004-08-29 21:02:37.604255730 -0600 @@ -356,3 +356,10 @@ /* Define as `fork' if `vfork' does not work. */ #undef vfork + +/* Define to 1 if you have */ +#undef HAVE_ATTR_ATTRIBUTES_H + +/* Whether to enable xattr support */ +#undef HAVE_XATTR + diff -ur lighttpd-1.2.7-orig/configure.in lighttpd-1.2.7-xattr/configure.in --- lighttpd-1.2.7-orig/configure.in 2004-08-29 04:03:07.000000000 -0600 +++ lighttpd-1.2.7-xattr/configure.in 2004-08-29 21:02:37.604255730 -0600 @@ -164,9 +164,22 @@ AC_DEFINE([HAVE_LIBLDAP], [1], [libldap]) AC_DEFINE([HAVE_LDAP_H], [1]) ]) + ]) ]) AC_SUBST(LDAP_LIB) +AC_MSG_CHECKING(for extended attributes support) +AC_ARG_WITH(attr, AC_HELP_STRING([--with-attr],[enable extended attribute support]), +[AC_MSG_RESULT(yes) + AC_CHECK_LIB(attr, attr_get, [ + AC_CHECK_HEADERS([attr/attributes.h],[ + ATTR_LIB=-lattr + AC_DEFINE([HAVE_XATTR], [1], [libattr]) + AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1]) + ]) +]) +AC_SUBST(ATTR_LIB) + AC_CHECK_LIB(lber, ber_printf, [ AC_CHECK_HEADERS([lber.h],[ LBER_LIB=-llber diff -ur lighttpd-1.2.7-orig/doc/lighttpd.conf lighttpd-1.2.7-xattr/doc/lighttpd.conf --- lighttpd-1.2.7-orig/doc/lighttpd.conf 2004-08-29 03:44:53.000000000 -0600 +++ lighttpd-1.2.7-xattr/doc/lighttpd.conf 2004-08-29 21:02:37.605255591 -0600 @@ -82,6 +82,9 @@ ".wmv" => "video/x-ms-wmv" ) +# Use the "Content-Type" extended attribute to obtain mime type if possible +# mimetypes.use-xattr = "enable" + #### accesslog module accesslog.filename = "/www/logs/access.log" diff -ur lighttpd-1.2.7-orig/src/base.h lighttpd-1.2.7-xattr/src/base.h --- lighttpd-1.2.7-orig/src/base.h 2004-08-29 02:51:53.000000000 -0600 +++ lighttpd-1.2.7-xattr/src/base.h 2004-08-29 21:23:21.977559690 -0600 @@ -163,6 +163,7 @@ size_t is_dirty; time_t stat_ts; + buffer *content_type; } file_cache_entry; typedef struct { @@ -199,6 +200,9 @@ unsigned short max_keep_alive_idle; unsigned short max_read_idle; unsigned short max_write_idle; +#ifdef HAVE_XATTR + unsigned short use_xattr; +#endif } specific_config; Only in lighttpd-1.2.7-xattr/src: base.h~ diff -ur lighttpd-1.2.7-orig/src/config.c lighttpd-1.2.7-xattr/src/config.c --- lighttpd-1.2.7-orig/src/config.c 2004-08-29 02:54:27.000000000 -0600 +++ lighttpd-1.2.7-xattr/src/config.c 2004-08-29 21:02:37.606255451 -0600 @@ -163,8 +163,9 @@ { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */ { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */ { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 23 */ - { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 23 */ - { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 23 */ + { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 24 */ + { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 25 */ + { "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 26 */ { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -214,6 +215,7 @@ s->max_keep_alive_idle = 30; s->max_read_idle = 60; s->max_write_idle = 360; + s->use_xattr = 0; cv[17].destination = s->document_root; cv[18].destination = &(s->dir_listing); @@ -225,6 +227,7 @@ cv[23].destination = &(s->max_keep_alive_idle); cv[24].destination = &(s->max_read_idle); cv[25].destination = &(s->max_write_idle); + cv[26].destination = &(s->use_xattr); srv->config_storage[i] = s; srv->config = ((data_config *)srv->config_context->data[i])->value; @@ -305,6 +308,7 @@ PATCH(max_keep_alive_idle); PATCH(max_read_idle); PATCH(max_write_idle); + PATCH(use_xattr); buffer_copy_string_buffer(con->server_name, s->server_name); return 0; @@ -344,6 +348,8 @@ PATCH(max_write_idle); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.max-read-idle"))) { PATCH(max_read_idle); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.use-xattr"))) { + PATCH(use_xattr); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) { buffer_copy_string_buffer(con->server_name, s->server_name); } diff -ur lighttpd-1.2.7-orig/src/file_cache.c lighttpd-1.2.7-xattr/src/file_cache.c --- lighttpd-1.2.7-orig/src/file_cache.c 2004-06-05 13:20:22.000000000 -0600 +++ lighttpd-1.2.7-xattr/src/file_cache.c 2004-08-29 21:29:03.890833672 -0600 @@ -17,6 +17,10 @@ #include "fdevent.h" #include "etag.h" +#ifdef HAVE_ATTR_ATTRIBUTES_H +#include +#endif + #ifndef O_LARGEFILE # define O_LARGEFILE 0 #endif @@ -40,6 +44,9 @@ fce->fde_ndx = -1; fce->name = buffer_init(); fce->etag = buffer_init(); +#ifdef HAVE_XATTR + fce->content_type = buffer_init(); +#endif return fce; } @@ -51,6 +58,7 @@ buffer_free(fce->etag); buffer_free(fce->name); + buffer_free(fce->content_type); if (fce->mmap_p) munmap(fce->mmap_p, fce->mmap_length); @@ -91,6 +99,20 @@ } +#ifdef HAVE_XATTR +int fce_attr_get(buffer *buf, char *name) { + int attrlen; + int ret; + attrlen = 1024; + buffer_prepare_copy(buf, attrlen); + if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) { + buf->used = attrlen + 1; + buf->ptr[attrlen] = '\0'; + } + return ret; +} +#endif + file_cache_entry * file_cache_get_entry(server *srv, connection *con, buffer *name, file_cache_entry *o_fce) { file_cache_entry *fce = NULL; file_cache *fc = srv->file_cache; @@ -136,6 +158,10 @@ return NULL; } fce->stat_ts = srv->cur_ts; + +#ifdef HAVE_XATTR + fce_attr_get(fce->content_type, name); +#endif etag_create(srv->file_cache_etag, &(fce->st)); @@ -222,6 +248,10 @@ return NULL; } +#ifdef HAVE_XATTR + fce_attr_get(fce->content_type, name->ptr); +#endif + etag_create(fce->etag, &(fce->st)); } else if (S_ISDIR(fce->st.st_mode)) { #ifdef USE_LINUX_SIGIO Only in lighttpd-1.2.7-xattr/src: file_cache.c~ diff -ur lighttpd-1.2.7-orig/src/Makefile.am lighttpd-1.2.7-xattr/src/Makefile.am --- lighttpd-1.2.7-orig/src/Makefile.am 2004-08-03 05:26:31.000000000 -0600 +++ lighttpd-1.2.7-xattr/src/Makefile.am 2004-08-29 21:02:37.607255312 -0600 @@ -152,7 +152,7 @@ DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" lighttpd_SOURCES = $(src) -lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) +lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) lighttpd_LDFLAGS = -export-dynamic lighttpd_CCPFLAGS = $(MYSQL_INCLUDES) diff -ur lighttpd-1.2.7-orig/src/response.c lighttpd-1.2.7-xattr/src/response.c --- lighttpd-1.2.7-orig/src/response.c 2004-08-29 02:52:01.000000000 -0600 +++ lighttpd-1.2.7-xattr/src/response.c 2004-08-29 21:22:28.477027570 -0600 @@ -31,6 +31,9 @@ #include "plugin.h" +#ifdef HAVE_ATTR_ATTRIBUTES_H +#include +#endif /* * This was 'borrowed' from tcpdump. @@ -659,27 +662,44 @@ if (S_ISDIR(st.st_mode)) { buffer_append_string_rfill(b, "directory", 28); } else { +#ifdef HAVE_XATTR + char attrval[128]; + int attrlen; +#endif size_t k; + unsigned short have_content_type; + have_content_type = 0; + +#ifdef HAVE_XATTR + attrlen = 127; + if(con->conf.use_xattr && 0 == attr_get(srv->tmp_buf->ptr, "Content-Type", attrval, &attrlen, 0)) { + attrval[attrlen] = 0; + buffer_append_string_rfill(b, attrval, 28); + have_content_type = 1; + } +#endif - for (k = 0; k < con->conf.mimetypes->used; k++) { - data_string *ds = (data_string *)con->conf.mimetypes->data[k]; - size_t ct_len; - - if (ds->key->used == 0) continue; - - ct_len = ds->key->used - 1; - - if (s_len < ct_len) continue; + if(!have_content_type) { + for (k = 0; k < con->conf.mimetypes->used; k++) { + data_string *ds = (data_string *)con->conf.mimetypes->data[k]; + size_t ct_len; + + if (ds->key->used == 0) continue; + + ct_len = ds->key->used - 1; + + if (s_len < ct_len) continue; + + if (0 == strncmp(sb->ptr[i] + s_len - ct_len, ds->key->ptr, ct_len)) { + buffer_append_string_rfill(b, ds->value->ptr, 28); + break; + } + } - if (0 == strncmp(sb->ptr[i] + s_len - ct_len, ds->key->ptr, ct_len)) { - buffer_append_string_rfill(b, ds->value->ptr, 28); - break; + if (k == con->conf.mimetypes->used) { + buffer_append_string_rfill(b, "application/octet-stream", 28); } } - - if (k == con->conf.mimetypes->used) { - buffer_append_string_rfill(b, "application/octet-type", 28); - } } /* URL */ @@ -1117,24 +1137,41 @@ /* set response content-type */ s_len = con->physical.path->used - 1; + +#ifdef HAVE_XATTR + if(con->conf.use_xattr && (NULL != (con->fce = file_cache_get_entry(srv, con, con->physical.path, con->fce))) && con->fce->content_type->used) { + response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), con->fce->content_type->ptr, con->fce->content_type->used); + } else { +#endif - for (k = 0; k < con->conf.mimetypes->used; k++) { - data_string *ds = (data_string *)con->conf.mimetypes->data[k]; - - if (buffer_is_equal_right_len(con->physical.path, ds->key, ds->key->used - 1)) { - if (con->http_status == 200) { - response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(ds->value)); - } + for (k = 0; k < con->conf.mimetypes->used; k++) { + data_string *ds = (data_string *)con->conf.mimetypes->data[k]; + size_t ct_len; - break; + if (ds->key->used == 0) continue; + + ct_len = ds->key->used - 1; + + if (s_len < ct_len) continue; + + if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->key->ptr, ct_len)) { + if (con->http_status == 200) { + response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(ds->value)); + } + + break; + } } - } - if (k == con->conf.mimetypes->used) { - /* not found, set a default */ - - response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream")); + if (k == con->conf.mimetypes->used) { + /* not found, set a default */ + + response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream")); + } +#ifdef HAVE_XATTR } +#endif + /* generate e-tag */ etag_mutate(con->physical.etag, con->fce->etag);