Sat, 06 Oct 2012 16:24:01 +0200
Update to new vendor software version and adjust patch code accordingly.
Unfortunately the vendor has apparently failed to properly test this
release which depends on missing object symbols in libsasl2.a(common.o):
undefined reference to `sasl_randcreate'
undefined reference to `sasl_mkchal'
undefined reference to `sasl_utf8verify'
undefined reference to `sasl_rand'
undefined reference to `sasl_churn'
undefined reference to `sasl_encode64'
undefined reference to `sasl_decode64'
undefined reference to `sasl_erasebuffer'
undefined reference to `sasl_randfree'
undefined reference to `sasl_strlower'
undefined reference to `get_fqhostname'
...yet to be patched.
1 Index: modules/dav/fs/mod_dav_fs.c
2 diff -Nau modules/dav/fs/mod_dav_fs.c.orig modules/dav/fs/mod_dav_fs.c
3 --- modules/dav/fs/mod_dav_fs.c.orig 2006-07-12 05:38:44.000000000 +0200
4 +++ modules/dav/fs/mod_dav_fs.c 2012-09-17 14:16:06.937987679 +0200
5 @@ -15,6 +15,7 @@
6 */
8 #include "httpd.h"
9 +#include "http_log.h"
10 #include "http_config.h"
11 #include "apr_strings.h"
13 @@ -24,9 +25,19 @@
14 /* per-server configuration */
15 typedef struct {
16 const char *lockdb_path;
17 + const char *diskusagedb_path;
19 } dav_fs_server_conf;
21 +/* per-dir configuration */
22 +typedef struct {
23 + apr_size_t quota;
24 + const char *area_path;
25 + int hiddenfiles;
26 + ap_regex_t *mask;
27 +
28 +} dav_fs_dir_conf;
29 +
30 extern module AP_MODULE_DECLARE_DATA dav_fs_module;
32 const char *dav_get_lockdb_path(const request_rec *r)
33 @@ -37,9 +48,20 @@
34 return conf->lockdb_path;
35 }
37 +const char *dav_get_diskusagedb_path(const request_rec *r)
38 +{
39 + dav_fs_server_conf *conf;
40 +
41 + conf = ap_get_module_config(r->server->module_config, &dav_fs_module);
42 + return conf->diskusagedb_path;
43 +}
44 +
45 static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s)
46 {
47 - return apr_pcalloc(p, sizeof(dav_fs_server_conf));
48 + dav_fs_server_conf *conf;
49 + conf = apr_pcalloc(p, sizeof(dav_fs_server_conf));
50 + conf->diskusagedb_path = NULL;
51 + return conf;
52 }
54 static void *dav_fs_merge_server_config(apr_pool_t *p,
55 @@ -53,6 +75,35 @@
57 newconf->lockdb_path =
58 child->lockdb_path ? child->lockdb_path : parent->lockdb_path;
59 + newconf->diskusagedb_path =
60 + child->diskusagedb_path ? child->diskusagedb_path : parent->diskusagedb_path;
61 +
62 + return newconf;
63 +}
64 +
65 +static void *dav_fs_create_dir_config(apr_pool_t *p, char *dir)
66 +{
67 + dav_fs_dir_conf *conf=apr_pcalloc(p, sizeof(dav_fs_dir_conf));
68 + conf->area_path = NULL;
69 + conf->mask = NULL;
70 + conf->quota = 0;
71 + conf->hiddenfiles = -1;
72 + return conf;
73 +}
74 +
75 +static void *dav_fs_merge_dir_config(apr_pool_t *p,
76 + void *base, void *overrides)
77 +{
78 + dav_fs_dir_conf *parent = base;
79 + dav_fs_dir_conf *child = overrides;
80 + dav_fs_dir_conf *newconf;
81 +
82 + newconf = apr_pcalloc(p, sizeof(*newconf));
83 +
84 + newconf->quota = child->quota ? child->quota : parent->quota;
85 + newconf->area_path = child->area_path ? child->area_path : parent->area_path;
86 + newconf->hiddenfiles = child->hiddenfiles!=-1 ? child->hiddenfiles : parent->hiddenfiles;
87 + newconf->mask = child->mask ? child->mask : parent->mask;
89 return newconf;
90 }
91 @@ -76,12 +127,83 @@
92 return NULL;
93 }
95 +/*
96 + * Command handler for the DAVLockDB directive, which is TAKE1
97 + */
98 +static const char *dav_fs_cmd_diskusagedb(cmd_parms *cmd, void *config,
99 + const char *arg1)
100 +{
101 + dav_fs_server_conf *conf;
102 + conf = ap_get_module_config(cmd->server->module_config,
103 + &dav_fs_module);
104 + conf->diskusagedb_path = ap_server_root_relative(cmd->pool, arg1);
105 +
106 + if (!conf->diskusagedb_path) {
107 + return apr_pstrcat(cmd->pool, "Invalid DAVDiskUsageDB path ",
108 + arg1, NULL);
109 + }
110 +
111 + return NULL;
112 +}
113 +
114 +/*
115 + * Command handler for the DAVFSQuota directive, which is TAKE1
116 + */
117 +
118 +static const char *dav_fs_cmd_davareasize( cmd_parms *cmd , void *config , const char *arg1 ) {
119 +
120 + dav_fs_dir_conf *conf = ( dav_fs_dir_conf * )config;
121 +
122 + conf->quota = (apr_size_t)atoi( arg1 );
123 + if ( conf->quota < 0 )
124 + return "DAVFSQuota requires a nonnegative integer.";
125 +
126 + conf->area_path = cmd->path;
127 + return NULL;
128 +
129 +}
130 +
131 +static const char *dav_fs_cmd_hidefiles( cmd_parms *cmd , void *config , const char *type , const char *arg1 ) {
132 +
133 + dav_fs_dir_conf *conf = ( dav_fs_dir_conf * )config;
134 +
135 +//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"arg1 %s, type %s",arg1, type);
136 +
137 + if (!strcasecmp(type, "None"))
138 + conf->hiddenfiles = DAV_FS_HIDE_NONE;
139 + else if (!strcasecmp(type, "Hidden"))
140 + conf->hiddenfiles = DAV_FS_HIDE_HIDDEN;
141 + else if (!strcasecmp(type, "Deny"))
142 + conf->hiddenfiles = DAV_FS_HIDE_DENY;
143 + else if (!strcasecmp(type, "Htaccess"))
144 + conf->hiddenfiles = DAV_FS_HIDE_HTACCESS;
145 + else if (!strcasecmp(type, "Mask")) {
146 + conf->hiddenfiles = DAV_FS_HIDE_MASK;
147 + conf->mask = ap_pregcomp(cmd->pool, arg1, AP_REG_EXTENDED|AP_REG_ICASE);
148 + if (!conf->mask) {
149 + return apr_psprintf(cmd->pool, "Regex '%s' in DAVFSHideFiles Mask could not be compiled", arg1);
150 + }
151 + } else {
152 + return "DAVFSHideFiles must be one of: "
153 + "None | Hidden | Deny | Htaccess | Mask <regexp>";
154 + }
155 + return NULL;
156 +}
157 +
158 static const command_rec dav_fs_cmds[] =
159 {
160 /* per server */
161 AP_INIT_TAKE1("DAVLockDB", dav_fs_cmd_davlockdb, NULL, RSRC_CONF,
162 "specify a lock database"),
163 -
164 + AP_INIT_TAKE1("DAVDiskUsageDB", dav_fs_cmd_diskusagedb, NULL, RSRC_CONF,
165 + "specify a disk usage database"),
166 + /* per directory/location */
167 + AP_INIT_TAKE1("DAVFSQuota", dav_fs_cmd_davareasize, NULL,
168 + OR_LIMIT|ACCESS_CONF,
169 + "max size of user storage area, per KByte"),
170 + AP_INIT_TAKE12("DAVFSHideFiles", dav_fs_cmd_hidefiles, NULL,
171 + OR_LIMIT|ACCESS_CONF,
172 + "how files need for hide in collection: None | Hidden | Deny | Htaccess | Mask <regexp>"),
173 { NULL }
174 };
176 @@ -99,10 +221,38 @@
177 module AP_MODULE_DECLARE_DATA dav_fs_module =
178 {
179 STANDARD20_MODULE_STUFF,
180 - NULL, /* dir config creater */
181 - NULL, /* dir merger --- default is to override */
182 + dav_fs_create_dir_config, /* dir config creater */
183 + dav_fs_merge_dir_config, /* dir merger --- default is to override */
184 dav_fs_create_server_config, /* server config */
185 dav_fs_merge_server_config, /* merge server config */
186 dav_fs_cmds, /* command table */
187 register_hooks, /* register hooks */
188 };
189 +
190 +const apr_size_t dav_fs_get_quota( request_rec *r ) {
191 +
192 + dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
193 + return conf->quota;
194 +
195 +}
196 +
197 +const char *dav_fs_get_dir( request_rec *r ) {
198 +
199 + dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
200 + return conf->area_path;
201 +
202 +}
203 +
204 +const int dav_fs_get_hidefiles( request_rec *r ) {
205 +
206 + dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
207 + return conf->hiddenfiles;
208 +
209 +}
210 +
211 +const ap_regex_t *dav_fs_get_mask( request_rec *r ) {
212 +
213 + dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
214 + return conf->mask;
215 +
216 +}
217 Index: modules/dav/fs/quota.h
218 diff -Nau modules/dav/fs/quota.h.orig modules/dav/fs/quota.h
219 --- modules/dav/fs/quota.h.orig 1970-01-01 01:00:00.000000000 +0100
220 +++ modules/dav/fs/quota.h 2012-09-17 14:16:06.938238230 +0200
221 @@ -0,0 +1,13 @@
222 +/**
223 + disk quota check modules for WebDAV service
224 + author: satake@goodcrew.ne.jp, changed by bjaka.max@gmail.com
225 +*/
226 +
227 +/** set your storage cluster size */
228 +#ifndef DAV_CLUSTER_SIZE
229 + #define DAV_CLUSTER_SIZE 4096
230 +#endif
231 +
232 +static apr_size_t dav_qchk_du(const char *dirname, apr_pool_t *pool);
233 +static apr_size_t dav_cached_du(char *dirname, const request_rec *r);
234 +static apr_status_t dav_change_cached_du(const char *dirname, const request_rec *r, int add_size, apr_size_t delta);
235 Index: modules/dav/fs/repos.c
236 diff -Nau modules/dav/fs/repos.c.orig modules/dav/fs/repos.c
237 --- modules/dav/fs/repos.c.orig 2011-09-08 17:59:38.000000000 +0200
238 +++ modules/dav/fs/repos.c 2012-09-17 14:18:07.509160501 +0200
239 @@ -27,6 +27,8 @@
240 #include <stdio.h> /* for sprintf() */
241 #endif
243 +#include "util_filter.h"
244 +#include "apr_sdbm.h"
245 #include "httpd.h"
246 #include "http_log.h"
247 #include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */
248 @@ -34,6 +36,7 @@
250 #include "mod_dav.h"
251 #include "repos.h"
252 +#include "quota.h"
255 /* to assist in debugging mod_dav's GET handling */
256 @@ -46,6 +49,10 @@
257 apr_pool_t *pool; /* memory storage pool associated with request */
258 const char *pathname; /* full pathname to resource */
259 apr_finfo_t finfo; /* filesystem info */
260 + request_rec *r; /* request of this resource*/
261 + apr_size_t quota; /* config data for quota check */
262 + const char *area_path;
263 + int hiddenfiles;
264 };
266 /* private context for doing a filesystem walk */
267 @@ -137,7 +144,12 @@
268 /*
269 ** The single property that we define (in the DAV_FS_URI_MYPROPS namespace)
270 */
271 -#define DAV_PROPID_FS_executable 1
272 +#define DAV_PROPID_FS_executable 1
273 +/*
274 +**Quota property in DAV:namespace
275 +*/
276 +#define DAV_PROPID_quota_available_bytes 2
277 +#define DAV_PROPID_quota_used_bytes 3
279 static const dav_liveprop_spec dav_fs_props[] =
280 {
281 @@ -166,8 +178,20 @@
282 DAV_PROPID_getlastmodified,
283 0
284 },
285 -
286 + {
287 + DAV_FS_URI_DAV,
288 + "quota-available-bytes",
289 + DAV_PROPID_quota_available_bytes,
290 + 0
291 + },
292 + {
293 + DAV_FS_URI_DAV,
294 + "quota-used-bytes",
295 + DAV_PROPID_quota_used_bytes,
296 + 0
297 + },
298 /* our custom properties */
299 +
300 {
301 DAV_FS_URI_MYPROPS,
302 "executable",
303 @@ -191,6 +215,9 @@
304 apr_pool_t *p;
305 apr_file_t *f;
306 const char *pathname; /* we may need to remove it at close time */
307 + apr_size_t quota; /* config data for quota check */
308 + const char *area_path;
309 + request_rec *r; /* request of this resource*/
310 };
312 /* returns an appropriate HTTP status code given an APR status code for a
313 @@ -641,6 +668,8 @@
314 dav_resource *resource;
315 char *s;
316 char *filename;
317 + apr_size_t nowsize, putsize;
318 + const char *conlen;
319 apr_size_t len;
321 /* ### optimize this into a single allocation! */
322 @@ -652,6 +681,37 @@
323 /* ### this should go away */
324 ctx->pool = r->pool;
326 + ctx->r = r;
327 + ctx->quota = dav_fs_get_quota(r);
328 + ctx->area_path = dav_fs_get_dir(r);
329 +
330 + ctx->hiddenfiles = dav_fs_get_hidefiles(r);
331 +
332 +// ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Pathname is %s, quota is %d",ctx->area_path,ctx->quota);
333 + /** Check quota limit*/
334 + if (ctx->quota && r->method_number==M_PUT) {
335 +
336 + /** get now user used size */
337 + nowsize = dav_cached_du(ctx->area_path, r);
338 +
339 + /** get put size */
340 + conlen = NULL;
341 + putsize = 0;
342 + if ( r->headers_in!=NULL ) {
343 + conlen = apr_table_get( r->headers_in , "content-length" );
344 + }
345 + if ( conlen!=NULL ) {
346 + putsize = ((atoi(conlen)+DAV_CLUSTER_SIZE-1)/DAV_CLUSTER_SIZE)*(DAV_CLUSTER_SIZE/1024);
347 + }
348 +
349 + /** check size */
350 +// ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Pathname is %s, directory size is %d, quota is %d",ctx->area_path, nowsize+putsize, ctx->quota);
351 + if ( nowsize+putsize>=ctx->quota ) {
352 + return dav_new_error(r->pool, HTTP_INSUFFICIENT_STORAGE, 0,
353 + apr_psprintf(r->pool,"WebDAV-Quota: Directory `%s' size %dKB+%dKB(%s) is over %dKB!",ctx->area_path, nowsize,putsize,conlen, ctx->quota));
354 + }
355 + }
356 +
357 /* Preserve case on OSes which fold canonical filenames */
358 #if 0
359 /* ### not available in Apache 2.0 yet */
360 @@ -865,6 +925,12 @@
362 ds->p = p;
363 ds->pathname = resource->info->pathname;
364 +
365 + ds->quota=resource->info->quota;
366 + ds->area_path=resource->info->area_path;
367 +
368 + ds->r = resource->info->r;
369 +
370 rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
371 if (rv != APR_SUCCESS) {
372 return dav_new_error(p, MAP_IO2HTTP(rv), 0,
373 @@ -889,6 +955,23 @@
374 "back) the resource "
375 "when it was being closed.");
376 }
377 + } else {
378 +
379 + if(stream->area_path && stream->r->method_number==M_PUT) {
380 + const char *conlen = NULL;
381 + apr_size_t putsize = 0;
382 + /** get put size */
383 +
384 + if ( stream->r->headers_in!=NULL ) {
385 + conlen = apr_table_get( stream->r->headers_in , "content-length" );
386 + }
387 + if ( conlen!=NULL ) {
388 + putsize = ((atoi(conlen)+DAV_CLUSTER_SIZE-1)/DAV_CLUSTER_SIZE)*(DAV_CLUSTER_SIZE/1024);
389 + }
390 +
391 + dav_change_cached_du(stream->area_path, stream->r, 1, putsize);
392 + }
393 +
394 }
396 return NULL;
397 @@ -926,8 +1009,145 @@
398 }
399 return NULL;
400 }
401 +/**
402 + get (dirname) total size ( per 512byte )
403 + @param dirname directory name
404 + @return block size
405 +*/
406 +static apr_size_t get_dir_size(const char *dirname, apr_pool_t *pool) {
407 +
408 + DIR *dir;
409 + struct dirent *ent;
410 + struct stat status;
411 + char *buffer;
412 + apr_size_t size = 0;
413 +
414 + dir = opendir(dirname);
415 + if ( dir==NULL ) {
416 + return 0;
417 + }
418 +
419 + while ( (ent = readdir(dir))!=NULL ) {
420 + if ( (!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, "..")) ) {
421 + continue;
422 + }
423 +
424 + apr_filepath_merge(&buffer, dirname, ent->d_name, 0, pool);
425 +
426 + if ( !lstat(buffer, &status) ) {
427 + size += status.st_blocks;
428 + if ( status.st_mode & S_IFDIR ) {
429 + size += get_dir_size(buffer, pool);
430 + }
431 + }
432 + }
433 + closedir(dir);
434 + return size;
435 +}
437 +/**
438 + return directory total disk space.
439 + same as 'du -sk dirname' command.
440 + @param dirname directory
441 + @return total space
442 +*/
443 +static apr_size_t dav_qchk_du(const char *dirname, apr_pool_t *pool) {
444 + struct stat status;
446 + if ( lstat(dirname, &status) ) {
447 + return 0;
448 + }
449 + return (status.st_blocks+((status.st_mode & S_IFDIR)?get_dir_size(dirname, pool):0))/2;
450 +}
451 +
452 +static apr_sdbm_datum_t dav_cached_du_prepare_key(const char *dirname, apr_pool_t *pool) {
453 + apr_sdbm_datum_t key;
454 + key.dsize = strlen(dirname)+1;
455 + key.dptr = apr_palloc(pool, key.dsize);
456 + memcpy(key.dptr, dirname, key.dsize);
457 + if (key.dptr[key.dsize - 2] == '/')
458 + key.dptr[--key.dsize - 1] = '\0';
459 + return key;
460 +}
461 +
462 +static apr_size_t dav_cached_du(char *dirname, const request_rec *r) {
463 + const char *pathname = dav_get_diskusagedb_path(r);
464 + apr_status_t status;
465 + apr_sdbm_t *db;
466 + apr_sdbm_datum_t val = { 0 };
467 + apr_size_t size;
468 + apr_sdbm_datum_t key;
469 + if (dirname[strlen(dirname)-1] == '/')
470 + dirname[strlen(dirname)-1] = '\0';
471 +
472 + if(!pathname)
473 + return dav_qchk_du(dirname, r->pool);
474 +
475 + key=dav_cached_du_prepare_key(dirname, r->pool);
476 +
477 + if ((status = apr_sdbm_open(&db, pathname, APR_WRITE | APR_CREATE,
478 + APR_OS_DEFAULT, r->pool))!= APR_SUCCESS) {
479 + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Error accessing to '%s' Disk Usage db file.", pathname);
480 + return dav_qchk_du(dirname, r->pool);
481 + }
482 +
483 + apr_sdbm_fetch(db, &val, key);
484 + if(val.dptr) {
485 + size = atoi(val.dptr);
486 + } else {
487 + size=dav_qchk_du(dirname, r->pool);
488 + val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
489 + val.dsize = strlen(val.dptr);
490 + apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
491 + }
492 +
493 + apr_sdbm_close(db);
494 + return size;
495 +}
496 +
497 +static apr_status_t dav_change_cached_du(const char *dirname, const request_rec *r, int add_size, apr_size_t delta) {
498 + const char *pathname = dav_get_diskusagedb_path(r);
499 + apr_status_t status;
500 + apr_sdbm_t *db;
501 + apr_sdbm_datum_t val = { 0 };
502 + apr_size_t size;
503 + apr_sdbm_datum_t key;
504 +
505 + if(!pathname)
506 + return APR_SUCCESS;
507 +
508 + key=dav_cached_du_prepare_key(dirname, r->pool);
509 +
510 + if ((status = apr_sdbm_open(&db, pathname, APR_WRITE | APR_CREATE | APR_SHARELOCK,
511 + APR_OS_DEFAULT, r->pool))!= APR_SUCCESS) {
512 + return status;
513 + }
514 +
515 + apr_sdbm_fetch(db, &val, key);
516 +
517 + if(val.dptr) {
518 + apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE);
519 + apr_sdbm_fetch(db, &val, key);
520 + size = atoi(val.dptr);
521 + if(add_size) {
522 + size += delta;
523 + } else {
524 + size -= delta;
525 + }
526 + val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
527 + val.dsize = strlen(val.dptr);
528 + apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
529 + apr_sdbm_unlock(db);
530 + } else {
531 + size=dav_qchk_du(dirname, r->pool);
532 + val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
533 + val.dsize = strlen(val.dptr);
534 + apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
535 + }
536 +
537 + apr_sdbm_close(db);
538 + return APR_SUCCESS;
539 +}
540 #if DEBUG_GET_HANDLER
542 /* only define set_headers() and deliver() for debug purposes */
543 @@ -1355,6 +1575,8 @@
544 dav_response **response)
545 {
546 dav_resource_private *info = resource->info;
547 + struct stat status;
548 + apr_size_t putsize = 0;
550 *response = NULL;
552 @@ -1394,6 +1616,10 @@
553 }
555 /* not a collection; remove the file and its properties */
556 + if (info->area_path && !lstat(info->pathname, &status) ) {
557 + putsize = status.st_blocks/2;
558 + dav_change_cached_du(info->area_path, info->r, 0, putsize);
559 + }
560 if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) {
561 /* ### put a description in here */
562 return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);
563 @@ -1418,7 +1644,12 @@
564 int isdir = fsctx->res1.collection;
565 apr_finfo_t dirent;
566 apr_dir_t *dirp;
567 + char *dirname;
568 + const ap_regex_t *mask;
570 + if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_MASK) {
571 + mask=dav_fs_get_mask(fsctx->info1.r);
572 + }
573 /* ensure the context is prepared properly, then call the func */
574 err = (*params->func)(&fsctx->wres,
575 isdir
576 @@ -1455,13 +1686,16 @@
577 fsctx->res2.collection = 0;
579 /* open and scan the directory */
580 + dirname=apr_pstrdup(pool, fsctx->path1.buf);
581 if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
582 /* ### need a better error */
583 return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
584 }
585 - while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
586 + while ((apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_NORM, dirp)) == APR_SUCCESS) {
587 apr_size_t len;
588 apr_status_t status;
589 + apr_finfo_t finfo;
590 + apr_status_t rv;
592 len = strlen(dirent.name);
594 @@ -1479,6 +1713,37 @@
595 if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) {
596 continue;
597 }
598 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Hiddenfiles %i",fsctx->info1.hiddenfiles);
599 + if(fsctx->info1.hiddenfiles && fsctx->info1.hiddenfiles!=-1) {
600 + if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_HIDDEN) {
601 + if(dirent.name[0]=='.') {
602 + continue;
603 + }
604 + } else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_DENY) {
605 + request_rec *rr;
606 + const char *fullname = apr_pstrcat(pool, dirname, dirent.name, NULL);
607 + if (!(rr = ap_sub_req_lookup_file(ap_os_escape_path(pool,fullname,1), fsctx->info1.r, NULL))) {
608 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Path %s, filename %s, fullname %s, return false", dirname, dirent.name, fullname);
609 + continue;
610 + }
611 + if (rr->status >= 400) {
612 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Path %s, filename %s, fullname(escaped) %s(%s), status %i", dirname, dirent.name, fullname, ap_os_escape_path(pool,fullname,1), rr->status);
613 + ap_destroy_sub_req(rr);
614 + continue;
615 + }
616 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"dirname %s, subrequest filename %s",dirname, rr->filename);
617 + ap_destroy_sub_req(rr);
618 + } else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_HTACCESS) {
619 + if(!strcmp(dirent.name, ".htaccess")) {
620 + continue;
621 + }
622 + } else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_MASK) {
623 + if(!ap_regexec(mask, dirent.name, 0, NULL, 0)) {
624 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"hide %s",dirent.name);
625 + continue;
626 + }
627 + }
628 + }
629 }
630 /* skip the state dir unless a HIDDEN is performed */
631 if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
632 @@ -1489,14 +1754,8 @@
633 /* append this file onto the path buffer (copy null term) */
634 dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);
636 - status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
637 - DAV_FINFO_MASK, pool);
638 - if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
639 - /* woah! where'd it go? */
640 - /* ### should have a better error here */
641 - err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
642 - break;
643 - }
644 + //set the finfo for further process
645 + fsctx->info1.finfo=dirent;
647 /* copy the file to the URI, too. NOTE: we will pad an extra byte
648 for the trailing slash later. */
649 @@ -1512,10 +1771,11 @@
650 fsctx->info2.pathname = fsctx->path2.buf;
652 /* set up the URI for the current resource */
653 + //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"the_request: %s,hostname: %s,status_line: %s,method: %s,range: %s,content_type: %s,unparsed_uri: %s,uri: %s,filename: %s,canonical_filename: %s,path_info: %s,args: %s,uri: %s",fsctx->info1.r->the_request ,fsctx->info1.r->hostname ,fsctx->info1.r->status_line,fsctx->info1.r->method,fsctx->info1.r->range,fsctx->info1.r->content_type,fsctx->info1.r->unparsed_uri,fsctx->info1.r->uri,fsctx->info1.r->filename,fsctx->info1.r->canonical_filename,fsctx->info1.r->path_info,fsctx->info1.r->args,fsctx->uri_buf.buf);
654 fsctx->res1.uri = fsctx->uri_buf.buf;
656 /* ### for now, only process regular files (e.g. skip symlinks) */
657 - if (fsctx->info1.finfo.filetype == APR_REG) {
658 + if (dirent.filetype == APR_REG) {
659 /* call the function for the specified dir + file */
660 if ((err = (*params->func)(&fsctx->wres,
661 DAV_CALLTYPE_MEMBER)) != NULL) {
662 @@ -1523,7 +1783,7 @@
663 break;
664 }
665 }
666 - else if (fsctx->info1.finfo.filetype == APR_DIR) {
667 + else if (dirent.filetype == APR_DIR) {
668 apr_size_t save_path_len = fsctx->path1.cur_len;
669 apr_size_t save_uri_len = fsctx->uri_buf.cur_len;
670 apr_size_t save_path2_len = fsctx->path2.cur_len;
671 @@ -1690,6 +1950,7 @@
672 dav_fs_walker_context fsctx = { 0 };
673 dav_error *err;
674 dav_fs_copymove_walk_ctx cm_ctx = { 0 };
675 + const char *uri,*request=params->root->info->r->the_request;
677 #if DAV_DEBUG
678 if ((params->walk_type & DAV_WALKTYPE_LOCKNULL) != 0
679 @@ -1743,7 +2004,11 @@
680 }
682 /* prep the URI buffer */
683 - dav_buffer_init(params->pool, &fsctx.uri_buf, params->root->uri);
684 +
685 + uri = ap_getword(params->pool, &request, ' '); //get method
686 + uri = ap_getword(params->pool, &request, ' '); //get uri
687 + ap_unescape_url(uri);
688 + dav_buffer_init(params->pool, &fsctx.uri_buf, uri);
690 /* if we have a directory, then ensure the URI has a trailing "/" */
691 if (fsctx.res1.collection
692 @@ -1844,8 +2109,11 @@
693 ** client cannot store dead values -- we deny that thru the is_writable
694 ** hook function.
695 */
696 - if (!resource->exists)
697 + if (!resource->exists) {
698 +//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"resource not exist");
699 +
700 return DAV_PROP_INSERT_NOTDEF;
701 +}
703 switch (propid) {
704 case DAV_PROPID_creationdate:
705 @@ -1896,15 +2164,29 @@
706 value = "F";
707 break;
709 + case DAV_PROPID_quota_available_bytes:
710 + /* Property defined only for collection with quota */
711 + if (!resource->info->quota || !resource->collection)
712 + return DAV_PROP_INSERT_NOTDEF;
713 + value = apr_psprintf(p, "%d", (resource->info->quota-dav_cached_du(resource->info->area_path, resource->info->r))*1024);
714 + break;
715 +
716 + case DAV_PROPID_quota_used_bytes:
717 + /* Property defined only for collection with quota */
718 + if (!resource->info->quota || !resource->collection)
719 + return DAV_PROP_INSERT_NOTDEF;
720 + value = apr_psprintf(p, "%d", dav_cached_du(resource->info->area_path, resource->info->r)*1024);
721 + break;
722 +
723 default:
724 /* ### what the heck was this property? */
725 return DAV_PROP_INSERT_NOTDEF;
726 }
728 /* assert: value != NULL */
729 -
730 /* get the information and global NS index for the property */
731 global_ns = dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info);
732 +//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"ns=%d name=%s value=%s",global_ns, info->name, value);
734 /* assert: info != NULL && info->name != NULL */
736 @@ -2138,7 +2420,7 @@
737 */
738 return;
739 }
740 -
741 +//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Try show all props");
742 (void) dav_fs_insert_prop(resource, DAV_PROPID_creationdate,
743 what, phdr);
744 (void) dav_fs_insert_prop(resource, DAV_PROPID_getcontentlength,
745 @@ -2148,6 +2430,11 @@
746 (void) dav_fs_insert_prop(resource, DAV_PROPID_getetag,
747 what, phdr);
749 + (void) dav_fs_insert_prop(resource, DAV_PROPID_quota_available_bytes,
750 + what, phdr);
751 + (void) dav_fs_insert_prop(resource, DAV_PROPID_quota_used_bytes,
752 + what, phdr);
753 +
754 #ifdef DAV_FS_HAS_EXECUTABLE
755 /* Only insert this property if it is defined for this platform. */
756 (void) dav_fs_insert_prop(resource, DAV_PROPID_FS_executable,
757 Index: modules/dav/fs/repos.h
758 diff -Nau modules/dav/fs/repos.h.orig modules/dav/fs/repos.h
759 --- modules/dav/fs/repos.h.orig 2006-07-12 05:38:44.000000000 +0200
760 +++ modules/dav/fs/repos.h 2012-09-17 14:16:06.941582156 +0200
761 @@ -30,6 +30,12 @@
762 #define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir"
763 #define DAV_FS_LOCK_NULL_FILE ".locknull"
765 +#define DAV_FS_HIDE_NONE 0
766 +#define DAV_FS_HIDE_HIDDEN 1
767 +#define DAV_FS_HIDE_DENY 2
768 +#define DAV_FS_HIDE_HTACCESS 3
769 +#define DAV_FS_HIDE_MASK 4
770 +
772 /* ensure that our state subdirectory is present */
773 void dav_fs_ensure_state_dir(apr_pool_t *p, const char *dirname);
774 @@ -67,6 +73,8 @@
775 /* where is the lock database located? */
776 const char *dav_get_lockdb_path(const request_rec *r);
778 +const char *dav_get_diskusagedb_path(const request_rec *r);
779 +
780 const dav_hooks_locks *dav_fs_get_lock_hooks(request_rec *r);
781 const dav_hooks_propdb *dav_fs_get_propdb_hooks(request_rec *r);
783 @@ -79,6 +87,11 @@
785 void dav_fs_register(apr_pool_t *p);
787 +const apr_size_t dav_fs_get_quota( request_rec *r );
788 +const char *dav_fs_get_dir( request_rec *r );
789 +const int dav_fs_get_hidefiles( request_rec *r );
790 +const ap_regex_t *dav_fs_get_mask( request_rec *r );
791 +
792 #endif /* _DAV_FS_REPOS_H_ */
793 /** @} */
795 Index: modules/dav/main/mod_dav.c
796 diff -Nau modules/dav/main/mod_dav.c.orig modules/dav/main/mod_dav.c
797 --- modules/dav/main/mod_dav.c.orig 2011-02-09 09:43:17.000000000 +0100
798 +++ modules/dav/main/mod_dav.c 2012-09-17 14:16:06.944219747 +0200
799 @@ -884,7 +884,14 @@
801 return DECLINED;
802 }
803 -
804 +struct dav_stream {
805 + apr_pool_t *p;
806 + apr_file_t *f;
807 + const char *pathname; /* we may need to remove it at close time */
808 + apr_size_t quota; /* config data for quota check */
809 + const char *area_path;
810 + request_rec *r; /* request of this resource*/
811 +};
812 /* handle the PUT method */
813 static int dav_method_put(request_rec *r)
814 {
815 @@ -958,7 +965,6 @@
816 else {
817 mode = DAV_MODE_WRITE_TRUNC;
818 }
819 -
820 /* make sure the resource can be modified (if versioning repository) */
821 if ((err = dav_auto_checkout(r, resource,
822 0 /* not parent_only */,
823 @@ -1043,6 +1049,7 @@
824 /* no error during the write, but we hit one at close. use it. */
825 err = err2;
826 }
827 +
828 }
830 /*
831 @@ -2583,7 +2590,6 @@
832 dav_lockdb *lockdb;
833 int replace_dest;
834 int resnew_state;
835 -
836 /* Ask repository module to resolve the resource */
837 err = dav_get_resource(r, !is_move /* label_allowed */,
838 0 /* use_checked_in */, &resource);
839 @@ -2635,6 +2641,7 @@
841 return dav_error_response(r, lookup.err.status, lookup.err.desc);
842 }
843 +
844 if (lookup.rnew->status != HTTP_OK) {
845 const char *auth = apr_table_get(lookup.rnew->err_headers_out,
846 "WWW-Authenticate");
847 @@ -2700,6 +2707,7 @@
848 if ((depth = dav_get_depth(r, DAV_INFINITY)) < 0) {
849 /* dav_get_depth() supplies additional information for the
850 * default message. */
851 +
852 return HTTP_BAD_REQUEST;
853 }
854 if (depth == 1) {
855 @@ -2817,7 +2825,6 @@
856 /* ### pass lockdb! */
857 (void)dav_unlock(r, resource, NULL);
858 }
859 -
860 /* if this is a move, then the source parent collection will be modified */
861 if (is_move) {
862 if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */,
863 @@ -2835,7 +2842,6 @@
864 * can be notified as to how it changed.
865 */
866 resnew_state = dav_get_resource_state(lookup.rnew, resnew);
867 -
868 /* In a MOVE operation, the destination is replaced by the source.
869 * In a COPY operation, if the destination exists, is under version
870 * control, and is the same resource type as the source,
871 @@ -4573,7 +4579,7 @@
872 * be more destructive than the user intended. */
873 if (r->parsed_uri.fragment != NULL) {
874 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
875 - "buggy client used un-escaped hash in Request-URI");
876 + "buggy client used un-escaped hash in Request-URI uri is '%s'",r->uri);
877 return dav_error_response(r, HTTP_BAD_REQUEST,
878 "The request was invalid: the URI included "
879 "an un-escaped hash character");
880 Index: modules/dav/main/util.c
881 diff -Nau modules/dav/main/util.c.orig modules/dav/main/util.c
882 --- modules/dav/main/util.c.orig 2010-07-21 20:25:49.000000000 +0200
883 +++ modules/dav/main/util.c 2012-09-17 14:16:06.945216500 +0200
884 @@ -168,6 +168,8 @@
885 apr_port_t port;
886 apr_uri_t comp;
887 char *new_file;
888 + const char *new_filename;
889 + char *redirect;
890 const char *domain;
892 /* first thing to do is parse the URI into various components */
893 @@ -278,7 +280,13 @@
894 * to apply appropriate restrictions (e.g. readonly).
895 */
896 result.rnew = ap_sub_req_method_uri(r->method, new_file, r, NULL);
897 -
898 + //detect redirect
899 + new_filename=apr_pstrdup(r->pool, result.rnew->filename);
900 + redirect=ap_getword(r->pool, &new_filename, ':');
901 + //ap_unescape_url(new_filename);
902 + if(!strcasecmp(redirect, "redirect")) {//subrequest for resolve redirect
903 + result.rnew = ap_sub_req_method_uri(r->method, new_filename, r, NULL);
904 + }
905 return result;
906 }
908 @@ -1420,11 +1428,11 @@
910 retVal = ap_meets_conditions(r);
912 - /* If-None-Match '*' fix. If-None-Match '*' request should succeed
913 + /* If-None-Match '*' fix. If-None-Match '*' request should succeed
914 * if the resource does not exist. */
915 if (retVal == HTTP_PRECONDITION_FAILED) {
916 /* Note. If if_none_match != NULL, if_none_match is the culprit.
917 - * Since, in presence of If-None-Match,
918 + * Since, in presence of If-None-Match,
919 * other If-* headers are undefined. */
920 if ((if_none_match =
921 apr_table_get(r->headers_in, "If-None-Match")) != NULL) {
922 Index: modules/mappers/mod_rewrite.c
923 diff -Nau modules/mappers/mod_rewrite.c.orig modules/mappers/mod_rewrite.c
924 --- modules/mappers/mod_rewrite.c.orig 2012-01-24 20:39:31.000000000 +0100
925 +++ modules/mappers/mod_rewrite.c 2012-09-17 14:16:06.947134500 +0200
926 @@ -2286,7 +2286,7 @@
927 current->len = span;
928 current->string = bri->source + bri->regmatch[n].rm_so;
929 }
930 -
931 +
932 outlen += span;
933 }
935 @@ -3250,7 +3250,7 @@
936 case 'B':
937 if (!*key || !strcasecmp(key, "ackrefescaping")) {
938 cfg->flags |= RULEFLAG_ESCAPEBACKREF;
939 - }
940 + }
941 else {
942 ++error;
943 }
944 @@ -4026,6 +4026,7 @@
945 if (r->main != NULL &&
946 (p->flags & RULEFLAG_IGNOREONSUBREQ ||
947 p->flags & RULEFLAG_FORCEREDIRECT )) {
948 +ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Ignore this rule on subrequests");
949 continue;
950 }