apache/apache.patch.davquo

Mon, 17 Sep 2012 19:10:10 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 17 Sep 2012 19:10:10 +0200
changeset 689
9fe04d4d4e5a
permissions
-rw-r--r--

Update to new version of vendor software although Oracle fails to deliver.
More specifically, newer db(3) patch revisions exist but Oracle has
removed them from the canonical download server URI for Berkely DB.

     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          }

mercurial