Use lighttpd instead of mogstored

Meno Abels meno.abels at adviser.com
Mon Jun 5 08:12:34 UTC 2006


hello,

i just want to use what i know, and this is a standard httpd. The 
perlbal is for me a bit obscure so i made a small patch to the
lighttpd which enables them to run as mogstored substition.

Use need to enable the mod_webdav on the lighttpd and than add the 
following options and everything is working:

webdav.activate             = "enable"
webdav.is-readonly          = "disable"
webdav.mkdir-on-put          = "enable"

Currently i lack the support of the usage stuff but is should be also 
easy done in the next step-:) Currently i generate
the usage every 5 seconds by using a for ever running small script.

cheers

meno
-------------- next part --------------
--- src/mod_webdav.c	Thu Mar  2 23:28:58 2006
+++ ../mod_webdav.c	Mon Jun  5 07:54:31 2006
@@ -50,6 +50,7 @@
 	unsigned short enabled;
 	unsigned short is_readonly;
 	unsigned short log_xml;
+	unsigned short mkdir_on_put;
 
 	buffer *sqlite_db_name;
 #ifdef USE_PROPPATCH
@@ -159,6 +160,7 @@
 		{ "webdav.is-readonly",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
 		{ "webdav.sqlite-db-name",      NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
 		{ "webdav.log-xml",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
+		{ "webdav.mkdir-on-put",        NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 4 */
 		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
 	};
 	
@@ -176,6 +178,7 @@
 		cv[1].destination = &(s->is_readonly);
 		cv[2].destination = s->sqlite_db_name;
 		cv[3].destination = &(s->log_xml);
+		cv[4].destination = &(s->mkdir_on_put);
 		
 		p->config_storage[i] = s;
 	
@@ -292,6 +295,7 @@
 	PATCH(enabled);
 	PATCH(is_readonly);
 	PATCH(log_xml);
+	PATCH(mkdir_on_put);
 	
 #ifdef USE_PROPPATCH
 	PATCH(sql);
@@ -322,6 +326,8 @@
 				PATCH(is_readonly);
 			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) {
 				PATCH(log_xml);
+			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.mkdir-on-put"))) {
+				PATCH(mkdir_on_put);
 			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) {
 #ifdef USE_PROPPATCH
 				PATCH(sql);
@@ -991,6 +997,47 @@
 }
 #endif
 
+static int rmkdir(const char *path_and_file)
+{
+	const int len = strlen(path_and_file);
+	if (len > 1024) {
+		return 405; /* not allowed */
+	}
+	{
+		char *buf = malloc(len+1);
+		char *bptr = buf;
+		const char *path_end = strrchr(path_and_file, (int)'/');
+		int ret = 201;
+		const char *path_pos = path_and_file;
+		for(path_pos = path_and_file; 
+			ret == 201 && path_end > path_and_file && path_pos <= path_end; ++path_pos) {
+			if (path_pos > path_and_file && *path_pos == '/' && path_pos[-1] != '/') {
+				bptr[1] = '\0';
+/*printf("mkdir=%s\n", buf);*/
+				if (-1 == mkdir(buf, 0700)) {
+					switch(errno) {
+					case EPERM:
+						ret = 403;
+						break;
+					case ENOENT:
+					case ENOTDIR:
+						ret = 409;
+						break;
+					case EEXIST:
+						break;
+					default:
+						ret = 405;
+						break;
+					}
+				}
+			}
+			*bptr++ = *path_pos;
+		}
+		free(buf);
+		return ret;
+	}
+}
+
 URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
 	plugin_data *p = p_d;
 	buffer *b;
@@ -1374,6 +1421,7 @@
 		return HANDLER_FINISHED;
 	case HTTP_METHOD_PUT: {
 		int fd;
+		int restart;
 		chunkqueue *cq = con->request_content_queue;
 
 		if (p->conf.is_readonly) {
@@ -1384,10 +1432,21 @@
 		assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
 
 		/* taken what we have in the request-body and write it to a file */
-		if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
-			/* we can't open the file */
-			con->http_status = 403;
-		} else {
+		for (restart = p->conf.mkdir_on_put ? 2 : 1; restart > 0; --restart) {	
+			if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
+				/* we can't open the file */
+				if (restart == 2) {
+					con->http_status = rmkdir(con->physical.path->ptr);	
+					if (con->http_status > 201) {
+						break;
+					}
+				} else {
+					con->http_status = 403;
+				}
+			} 
+		}
+
+		if (fd >= 0) {
 			chunk *c;
 
 			con->http_status = 201; /* created */


More information about the mogilefs mailing list