Integrate patch to implement RFC 4331 Quota and Size for WebDAV.

Mon, 17 Sep 2012 19:02:42 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 17 Sep 2012 19:02:42 +0200
changeset 685
d612d08c0455
parent 684
f805be991d7f
child 686
8402f4294f85

Integrate patch to implement RFC 4331 Quota and Size for WebDAV.

apache/apache.patch.davquo file | annotate | diff | comparison | revisions
apache/apache.spec file | annotate | diff | comparison | revisions
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/apache/apache.patch.davquo	Mon Sep 17 19:02:42 2012 +0200
     1.3 @@ -0,0 +1,951 @@
     1.4 +Index: modules/dav/fs/mod_dav_fs.c
     1.5 +diff -Nau modules/dav/fs/mod_dav_fs.c.orig modules/dav/fs/mod_dav_fs.c
     1.6 +--- modules/dav/fs/mod_dav_fs.c.orig	2006-07-12 05:38:44.000000000 +0200
     1.7 ++++ modules/dav/fs/mod_dav_fs.c	2012-09-17 14:16:06.937987679 +0200
     1.8 +@@ -15,6 +15,7 @@
     1.9 +  */
    1.10 + 
    1.11 + #include "httpd.h"
    1.12 ++#include "http_log.h"
    1.13 + #include "http_config.h"
    1.14 + #include "apr_strings.h"
    1.15 + 
    1.16 +@@ -24,9 +25,19 @@
    1.17 + /* per-server configuration */
    1.18 + typedef struct {
    1.19 +     const char *lockdb_path;
    1.20 ++    const char *diskusagedb_path;
    1.21 + 
    1.22 + } dav_fs_server_conf;
    1.23 + 
    1.24 ++/* per-dir configuration */
    1.25 ++typedef struct {
    1.26 ++    apr_size_t quota;
    1.27 ++    const char *area_path;
    1.28 ++    int hiddenfiles;
    1.29 ++    ap_regex_t *mask;
    1.30 ++
    1.31 ++} dav_fs_dir_conf;
    1.32 ++
    1.33 + extern module AP_MODULE_DECLARE_DATA dav_fs_module;
    1.34 + 
    1.35 + const char *dav_get_lockdb_path(const request_rec *r)
    1.36 +@@ -37,9 +48,20 @@
    1.37 +     return conf->lockdb_path;
    1.38 + }
    1.39 + 
    1.40 ++const char *dav_get_diskusagedb_path(const request_rec *r)
    1.41 ++{
    1.42 ++    dav_fs_server_conf *conf;
    1.43 ++
    1.44 ++    conf = ap_get_module_config(r->server->module_config, &dav_fs_module);
    1.45 ++    return conf->diskusagedb_path;
    1.46 ++}
    1.47 ++
    1.48 + static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s)
    1.49 + {
    1.50 +-    return apr_pcalloc(p, sizeof(dav_fs_server_conf));
    1.51 ++    dav_fs_server_conf *conf;
    1.52 ++    conf = apr_pcalloc(p, sizeof(dav_fs_server_conf));
    1.53 ++    conf->diskusagedb_path = NULL;
    1.54 ++    return conf;
    1.55 + }
    1.56 + 
    1.57 + static void *dav_fs_merge_server_config(apr_pool_t *p,
    1.58 +@@ -53,6 +75,35 @@
    1.59 + 
    1.60 +     newconf->lockdb_path =
    1.61 +         child->lockdb_path ? child->lockdb_path : parent->lockdb_path;
    1.62 ++    newconf->diskusagedb_path =
    1.63 ++        child->diskusagedb_path ? child->diskusagedb_path : parent->diskusagedb_path;
    1.64 ++
    1.65 ++    return newconf;
    1.66 ++}
    1.67 ++
    1.68 ++static void *dav_fs_create_dir_config(apr_pool_t *p, char *dir)
    1.69 ++{
    1.70 ++    dav_fs_dir_conf *conf=apr_pcalloc(p, sizeof(dav_fs_dir_conf));
    1.71 ++    conf->area_path = NULL;
    1.72 ++    conf->mask = NULL;
    1.73 ++    conf->quota = 0;
    1.74 ++    conf->hiddenfiles = -1;
    1.75 ++    return conf;
    1.76 ++}
    1.77 ++
    1.78 ++static void *dav_fs_merge_dir_config(apr_pool_t *p,
    1.79 ++                                        void *base, void *overrides)
    1.80 ++{
    1.81 ++    dav_fs_dir_conf *parent = base;
    1.82 ++    dav_fs_dir_conf *child = overrides;
    1.83 ++    dav_fs_dir_conf *newconf;
    1.84 ++
    1.85 ++    newconf = apr_pcalloc(p, sizeof(*newconf));
    1.86 ++
    1.87 ++    newconf->quota = child->quota ? child->quota : parent->quota;
    1.88 ++    newconf->area_path = child->area_path ? child->area_path : parent->area_path;
    1.89 ++    newconf->hiddenfiles = child->hiddenfiles!=-1 ? child->hiddenfiles : parent->hiddenfiles;
    1.90 ++    newconf->mask = child->mask ? child->mask : parent->mask;
    1.91 + 
    1.92 +     return newconf;
    1.93 + }
    1.94 +@@ -76,12 +127,83 @@
    1.95 +     return NULL;
    1.96 + }
    1.97 + 
    1.98 ++/*
    1.99 ++ * Command handler for the DAVLockDB directive, which is TAKE1
   1.100 ++ */
   1.101 ++static const char *dav_fs_cmd_diskusagedb(cmd_parms *cmd, void *config,
   1.102 ++                                        const char *arg1)
   1.103 ++{
   1.104 ++    dav_fs_server_conf *conf;
   1.105 ++    conf = ap_get_module_config(cmd->server->module_config,
   1.106 ++                                &dav_fs_module);
   1.107 ++    conf->diskusagedb_path = ap_server_root_relative(cmd->pool, arg1);
   1.108 ++
   1.109 ++    if (!conf->diskusagedb_path) {
   1.110 ++        return apr_pstrcat(cmd->pool, "Invalid DAVDiskUsageDB path ",
   1.111 ++                           arg1, NULL);
   1.112 ++    }
   1.113 ++
   1.114 ++    return NULL;
   1.115 ++}
   1.116 ++
   1.117 ++/*
   1.118 ++ * Command handler for the DAVFSQuota directive, which is TAKE1
   1.119 ++ */
   1.120 ++
   1.121 ++static const char *dav_fs_cmd_davareasize( cmd_parms *cmd , void *config , const char *arg1 ) {
   1.122 ++
   1.123 ++    dav_fs_dir_conf *conf = ( dav_fs_dir_conf * )config;
   1.124 ++
   1.125 ++    conf->quota = (apr_size_t)atoi( arg1 );
   1.126 ++    if ( conf->quota < 0 )
   1.127 ++        return "DAVFSQuota requires a nonnegative integer.";
   1.128 ++
   1.129 ++    conf->area_path = cmd->path;
   1.130 ++    return NULL;
   1.131 ++
   1.132 ++}
   1.133 ++
   1.134 ++static const char *dav_fs_cmd_hidefiles( cmd_parms *cmd , void *config , const char *type , const char *arg1 ) {
   1.135 ++
   1.136 ++    dav_fs_dir_conf *conf = ( dav_fs_dir_conf * )config;
   1.137 ++
   1.138 ++//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"arg1 %s, type %s",arg1, type);
   1.139 ++
   1.140 ++    if (!strcasecmp(type, "None"))
   1.141 ++        conf->hiddenfiles = DAV_FS_HIDE_NONE;
   1.142 ++    else if (!strcasecmp(type, "Hidden"))
   1.143 ++        conf->hiddenfiles = DAV_FS_HIDE_HIDDEN;
   1.144 ++    else if (!strcasecmp(type, "Deny"))
   1.145 ++        conf->hiddenfiles = DAV_FS_HIDE_DENY;
   1.146 ++    else if (!strcasecmp(type, "Htaccess"))
   1.147 ++        conf->hiddenfiles = DAV_FS_HIDE_HTACCESS;
   1.148 ++    else if (!strcasecmp(type, "Mask")) {
   1.149 ++        conf->hiddenfiles = DAV_FS_HIDE_MASK;
   1.150 ++	conf->mask = ap_pregcomp(cmd->pool, arg1, AP_REG_EXTENDED|AP_REG_ICASE);
   1.151 ++        if (!conf->mask) {
   1.152 ++            return apr_psprintf(cmd->pool, "Regex '%s' in DAVFSHideFiles Mask could not be compiled", arg1);
   1.153 ++        }
   1.154 ++    } else {
   1.155 ++        return "DAVFSHideFiles must be one of: "
   1.156 ++            "None | Hidden | Deny | Htaccess | Mask <regexp>";
   1.157 ++    }
   1.158 ++    return NULL;
   1.159 ++}
   1.160 ++
   1.161 + static const command_rec dav_fs_cmds[] =
   1.162 + {
   1.163 +     /* per server */
   1.164 +     AP_INIT_TAKE1("DAVLockDB", dav_fs_cmd_davlockdb, NULL, RSRC_CONF,
   1.165 +                   "specify a lock database"),
   1.166 +-
   1.167 ++    AP_INIT_TAKE1("DAVDiskUsageDB", dav_fs_cmd_diskusagedb, NULL, RSRC_CONF,
   1.168 ++                  "specify a disk usage database"),
   1.169 ++    /* per directory/location */
   1.170 ++    AP_INIT_TAKE1("DAVFSQuota", dav_fs_cmd_davareasize, NULL,
   1.171 ++                  OR_LIMIT|ACCESS_CONF,
   1.172 ++                  "max size of user storage area, per KByte"),
   1.173 ++    AP_INIT_TAKE12("DAVFSHideFiles", dav_fs_cmd_hidefiles, NULL,
   1.174 ++                  OR_LIMIT|ACCESS_CONF,
   1.175 ++                  "how files need for hide in collection: None | Hidden | Deny | Htaccess | Mask <regexp>"),
   1.176 +     { NULL }
   1.177 + };
   1.178 + 
   1.179 +@@ -99,10 +221,38 @@
   1.180 + module AP_MODULE_DECLARE_DATA dav_fs_module =
   1.181 + {
   1.182 +     STANDARD20_MODULE_STUFF,
   1.183 +-    NULL,                        /* dir config creater */
   1.184 +-    NULL,                        /* dir merger --- default is to override */
   1.185 ++    dav_fs_create_dir_config,    /* dir config creater */
   1.186 ++    dav_fs_merge_dir_config,     /* dir merger --- default is to override */
   1.187 +     dav_fs_create_server_config, /* server config */
   1.188 +     dav_fs_merge_server_config,  /* merge server config */
   1.189 +     dav_fs_cmds,                 /* command table */
   1.190 +     register_hooks,              /* register hooks */
   1.191 + };
   1.192 ++
   1.193 ++const apr_size_t dav_fs_get_quota( request_rec *r ) {
   1.194 ++
   1.195 ++    dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
   1.196 ++    return  conf->quota;
   1.197 ++
   1.198 ++}
   1.199 ++
   1.200 ++const char *dav_fs_get_dir( request_rec *r ) {
   1.201 ++
   1.202 ++    dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
   1.203 ++    return  conf->area_path;
   1.204 ++
   1.205 ++}
   1.206 ++
   1.207 ++const int dav_fs_get_hidefiles( request_rec *r ) {
   1.208 ++
   1.209 ++    dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
   1.210 ++    return  conf->hiddenfiles;
   1.211 ++
   1.212 ++}
   1.213 ++
   1.214 ++const ap_regex_t *dav_fs_get_mask( request_rec *r ) {
   1.215 ++
   1.216 ++    dav_fs_dir_conf *conf = ap_get_module_config( r->per_dir_config , &dav_fs_module );
   1.217 ++    return  conf->mask;
   1.218 ++
   1.219 ++}
   1.220 +Index: modules/dav/fs/quota.h
   1.221 +diff -Nau modules/dav/fs/quota.h.orig modules/dav/fs/quota.h
   1.222 +--- modules/dav/fs/quota.h.orig	1970-01-01 01:00:00.000000000 +0100
   1.223 ++++ modules/dav/fs/quota.h	2012-09-17 14:16:06.938238230 +0200
   1.224 +@@ -0,0 +1,13 @@
   1.225 ++/**
   1.226 ++    disk quota check modules for WebDAV service
   1.227 ++                        author: satake@goodcrew.ne.jp, changed by bjaka.max@gmail.com
   1.228 ++*/
   1.229 ++
   1.230 ++/** set your storage cluster size */
   1.231 ++#ifndef     DAV_CLUSTER_SIZE
   1.232 ++    #define     DAV_CLUSTER_SIZE    4096
   1.233 ++#endif
   1.234 ++
   1.235 ++static apr_size_t dav_qchk_du(const char *dirname, apr_pool_t *pool);
   1.236 ++static apr_size_t dav_cached_du(char *dirname, const request_rec *r);
   1.237 ++static apr_status_t dav_change_cached_du(const char *dirname, const request_rec *r, int add_size, apr_size_t delta);
   1.238 +Index: modules/dav/fs/repos.c
   1.239 +diff -Nau modules/dav/fs/repos.c.orig modules/dav/fs/repos.c
   1.240 +--- modules/dav/fs/repos.c.orig	2011-09-08 17:59:38.000000000 +0200
   1.241 ++++ modules/dav/fs/repos.c	2012-09-17 14:18:07.509160501 +0200
   1.242 +@@ -27,6 +27,8 @@
   1.243 + #include <stdio.h>              /* for sprintf() */
   1.244 + #endif
   1.245 + 
   1.246 ++#include "util_filter.h"
   1.247 ++#include "apr_sdbm.h"
   1.248 + #include "httpd.h"
   1.249 + #include "http_log.h"
   1.250 + #include "http_protocol.h"      /* for ap_set_* (in dav_fs_set_headers) */
   1.251 +@@ -34,6 +36,7 @@
   1.252 + 
   1.253 + #include "mod_dav.h"
   1.254 + #include "repos.h"
   1.255 ++#include "quota.h"
   1.256 + 
   1.257 + 
   1.258 + /* to assist in debugging mod_dav's GET handling */
   1.259 +@@ -46,6 +49,10 @@
   1.260 +     apr_pool_t *pool;        /* memory storage pool associated with request */
   1.261 +     const char *pathname;   /* full pathname to resource */
   1.262 +     apr_finfo_t finfo;       /* filesystem info */
   1.263 ++    request_rec *r;         /* request of this resource*/
   1.264 ++    apr_size_t quota;           /* config data for quota check */
   1.265 ++    const char *area_path;
   1.266 ++    int hiddenfiles;
   1.267 + };
   1.268 + 
   1.269 + /* private context for doing a filesystem walk */
   1.270 +@@ -137,7 +144,12 @@
   1.271 + /*
   1.272 + ** The single property that we define (in the DAV_FS_URI_MYPROPS namespace)
   1.273 + */
   1.274 +-#define DAV_PROPID_FS_executable        1
   1.275 ++#define DAV_PROPID_FS_executable		1
   1.276 ++/*
   1.277 ++**Quota property in DAV:namespace
   1.278 ++*/
   1.279 ++#define DAV_PROPID_quota_available_bytes	2
   1.280 ++#define DAV_PROPID_quota_used_bytes		3
   1.281 + 
   1.282 + static const dav_liveprop_spec dav_fs_props[] =
   1.283 + {
   1.284 +@@ -166,8 +178,20 @@
   1.285 +         DAV_PROPID_getlastmodified,
   1.286 +         0
   1.287 +     },
   1.288 +-
   1.289 ++    {
   1.290 ++        DAV_FS_URI_DAV,
   1.291 ++        "quota-available-bytes",
   1.292 ++        DAV_PROPID_quota_available_bytes,
   1.293 ++        0
   1.294 ++    },
   1.295 ++    {
   1.296 ++        DAV_FS_URI_DAV,
   1.297 ++        "quota-used-bytes",
   1.298 ++        DAV_PROPID_quota_used_bytes,
   1.299 ++        0
   1.300 ++    },
   1.301 +     /* our custom properties */
   1.302 ++
   1.303 +     {
   1.304 +         DAV_FS_URI_MYPROPS,
   1.305 +         "executable",
   1.306 +@@ -191,6 +215,9 @@
   1.307 +     apr_pool_t *p;
   1.308 +     apr_file_t *f;
   1.309 +     const char *pathname;       /* we may need to remove it at close time */
   1.310 ++    apr_size_t quota;           /* config data for quota check */
   1.311 ++    const char *area_path;
   1.312 ++    request_rec *r;         /* request of this resource*/
   1.313 + };
   1.314 + 
   1.315 + /* returns an appropriate HTTP status code given an APR status code for a
   1.316 +@@ -641,6 +668,8 @@
   1.317 +     dav_resource *resource;
   1.318 +     char *s;
   1.319 +     char *filename;
   1.320 ++    apr_size_t nowsize, putsize;
   1.321 ++    const char *conlen;
   1.322 +     apr_size_t len;
   1.323 + 
   1.324 +     /* ### optimize this into a single allocation! */
   1.325 +@@ -652,6 +681,37 @@
   1.326 +     /* ### this should go away */
   1.327 +     ctx->pool = r->pool;
   1.328 + 
   1.329 ++    ctx->r = r;
   1.330 ++    ctx->quota = dav_fs_get_quota(r);
   1.331 ++    ctx->area_path = dav_fs_get_dir(r);
   1.332 ++
   1.333 ++    ctx->hiddenfiles = dav_fs_get_hidefiles(r);
   1.334 ++
   1.335 ++//    ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Pathname is %s, quota is %d",ctx->area_path,ctx->quota);
   1.336 ++    /** Check quota limit*/
   1.337 ++    if (ctx->quota && r->method_number==M_PUT) {
   1.338 ++
   1.339 ++	/** get now user used size */
   1.340 ++	nowsize = dav_cached_du(ctx->area_path, r);
   1.341 ++
   1.342 ++	/** get put size */
   1.343 ++	conlen = NULL;
   1.344 ++	putsize = 0;
   1.345 ++	if ( r->headers_in!=NULL ) {
   1.346 ++		conlen = apr_table_get( r->headers_in , "content-length" );
   1.347 ++	}
   1.348 ++	if ( conlen!=NULL ) {
   1.349 ++		putsize = ((atoi(conlen)+DAV_CLUSTER_SIZE-1)/DAV_CLUSTER_SIZE)*(DAV_CLUSTER_SIZE/1024);
   1.350 ++	}
   1.351 ++
   1.352 ++	/** check size */
   1.353 ++//	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);
   1.354 ++	if ( nowsize+putsize>=ctx->quota ) {
   1.355 ++		return dav_new_error(r->pool, HTTP_INSUFFICIENT_STORAGE, 0,
   1.356 ++			apr_psprintf(r->pool,"WebDAV-Quota: Directory `%s' size %dKB+%dKB(%s) is over %dKB!",ctx->area_path, nowsize,putsize,conlen, ctx->quota));
   1.357 ++	}
   1.358 ++    }
   1.359 ++
   1.360 +     /* Preserve case on OSes which fold canonical filenames */
   1.361 + #if 0
   1.362 +     /* ### not available in Apache 2.0 yet */
   1.363 +@@ -865,6 +925,12 @@
   1.364 + 
   1.365 +     ds->p = p;
   1.366 +     ds->pathname = resource->info->pathname;
   1.367 ++
   1.368 ++    ds->quota=resource->info->quota;
   1.369 ++    ds->area_path=resource->info->area_path;
   1.370 ++
   1.371 ++    ds->r = resource->info->r;
   1.372 ++
   1.373 +     rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
   1.374 +     if (rv != APR_SUCCESS) {
   1.375 +         return dav_new_error(p, MAP_IO2HTTP(rv), 0,
   1.376 +@@ -889,6 +955,23 @@
   1.377 +                                  "back) the resource "
   1.378 +                                  "when it was being closed.");
   1.379 +         }
   1.380 ++    } else {
   1.381 ++
   1.382 ++	if(stream->area_path && stream->r->method_number==M_PUT) {
   1.383 ++	    const char *conlen = NULL;
   1.384 ++	    apr_size_t putsize = 0;
   1.385 ++	    /** get put size */
   1.386 ++
   1.387 ++	    if ( stream->r->headers_in!=NULL ) {
   1.388 ++		conlen = apr_table_get( stream->r->headers_in , "content-length" );
   1.389 ++	    }
   1.390 ++	    if ( conlen!=NULL ) {
   1.391 ++		putsize = ((atoi(conlen)+DAV_CLUSTER_SIZE-1)/DAV_CLUSTER_SIZE)*(DAV_CLUSTER_SIZE/1024);
   1.392 ++	    }
   1.393 ++
   1.394 ++	    dav_change_cached_du(stream->area_path, stream->r, 1, putsize);
   1.395 ++	}
   1.396 ++
   1.397 +     }
   1.398 + 
   1.399 +     return NULL;
   1.400 +@@ -926,8 +1009,145 @@
   1.401 +     }
   1.402 +     return NULL;
   1.403 + }
   1.404 ++/**
   1.405 ++    get (dirname) total size ( per 512byte )
   1.406 ++    @param  dirname directory name
   1.407 ++    @return block size
   1.408 ++*/
   1.409 ++static apr_size_t get_dir_size(const char *dirname, apr_pool_t *pool) {
   1.410 ++
   1.411 ++    DIR *dir;
   1.412 ++    struct dirent *ent;
   1.413 ++    struct stat status;
   1.414 ++    char *buffer;
   1.415 ++    apr_size_t size = 0;
   1.416 ++
   1.417 ++    dir = opendir(dirname);
   1.418 ++    if ( dir==NULL ) {
   1.419 ++        return  0;
   1.420 ++    }
   1.421 ++
   1.422 ++    while ( (ent = readdir(dir))!=NULL ) {
   1.423 ++        if ( (!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, "..")) ) {
   1.424 ++            continue;
   1.425 ++        }
   1.426 ++
   1.427 ++        apr_filepath_merge(&buffer, dirname, ent->d_name, 0, pool);
   1.428 ++
   1.429 ++        if ( !lstat(buffer, &status) ) {
   1.430 ++            size += status.st_blocks;
   1.431 ++            if ( status.st_mode & S_IFDIR ) {
   1.432 ++                size += get_dir_size(buffer, pool);
   1.433 ++            }
   1.434 ++        }
   1.435 ++    }
   1.436 ++    closedir(dir);
   1.437 ++    return  size;
   1.438 ++}
   1.439 + 
   1.440 ++/**
   1.441 ++    return  directory total disk space.
   1.442 ++    same as 'du -sk dirname' command.
   1.443 ++    @param  dirname     directory
   1.444 ++    @return     total space
   1.445 ++*/
   1.446 ++static apr_size_t dav_qchk_du(const char *dirname, apr_pool_t *pool) {
   1.447 ++    struct stat     status;
   1.448 + 
   1.449 ++    if ( lstat(dirname, &status) ) {
   1.450 ++        return  0;
   1.451 ++    }
   1.452 ++    return (status.st_blocks+((status.st_mode & S_IFDIR)?get_dir_size(dirname, pool):0))/2;
   1.453 ++}
   1.454 ++
   1.455 ++static apr_sdbm_datum_t dav_cached_du_prepare_key(const char *dirname, apr_pool_t *pool) {
   1.456 ++    apr_sdbm_datum_t key;
   1.457 ++    key.dsize = strlen(dirname)+1;
   1.458 ++    key.dptr = apr_palloc(pool, key.dsize);
   1.459 ++    memcpy(key.dptr, dirname, key.dsize);
   1.460 ++    if (key.dptr[key.dsize - 2] == '/')
   1.461 ++        key.dptr[--key.dsize - 1] = '\0';
   1.462 ++    return key;
   1.463 ++}
   1.464 ++
   1.465 ++static apr_size_t dav_cached_du(char *dirname, const request_rec *r) {
   1.466 ++    const char *pathname = dav_get_diskusagedb_path(r);
   1.467 ++    apr_status_t status;
   1.468 ++    apr_sdbm_t *db;
   1.469 ++    apr_sdbm_datum_t val = { 0 };
   1.470 ++    apr_size_t size;
   1.471 ++    apr_sdbm_datum_t key;
   1.472 ++    if (dirname[strlen(dirname)-1] == '/')
   1.473 ++        dirname[strlen(dirname)-1] = '\0';
   1.474 ++
   1.475 ++    if(!pathname)
   1.476 ++	return dav_qchk_du(dirname, r->pool);
   1.477 ++
   1.478 ++    key=dav_cached_du_prepare_key(dirname, r->pool);
   1.479 ++
   1.480 ++    if ((status = apr_sdbm_open(&db, pathname, APR_WRITE | APR_CREATE,
   1.481 ++                               APR_OS_DEFAULT, r->pool))!= APR_SUCCESS) {
   1.482 ++	ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Error accessing to '%s' Disk Usage db file.", pathname);
   1.483 ++	return dav_qchk_du(dirname, r->pool);
   1.484 ++    }
   1.485 ++
   1.486 ++    apr_sdbm_fetch(db, &val, key);
   1.487 ++    if(val.dptr) {
   1.488 ++	size = atoi(val.dptr);
   1.489 ++    } else {
   1.490 ++	size=dav_qchk_du(dirname, r->pool);
   1.491 ++	val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
   1.492 ++	val.dsize = strlen(val.dptr);
   1.493 ++	apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
   1.494 ++    }
   1.495 ++
   1.496 ++    apr_sdbm_close(db);
   1.497 ++    return size;
   1.498 ++}
   1.499 ++
   1.500 ++static apr_status_t dav_change_cached_du(const char *dirname, const request_rec *r, int add_size, apr_size_t delta) {
   1.501 ++    const char *pathname = dav_get_diskusagedb_path(r);
   1.502 ++    apr_status_t status;
   1.503 ++    apr_sdbm_t *db;
   1.504 ++    apr_sdbm_datum_t val = { 0 };
   1.505 ++    apr_size_t size;
   1.506 ++    apr_sdbm_datum_t key;
   1.507 ++
   1.508 ++    if(!pathname)
   1.509 ++	return APR_SUCCESS;
   1.510 ++
   1.511 ++    key=dav_cached_du_prepare_key(dirname, r->pool);
   1.512 ++
   1.513 ++    if ((status = apr_sdbm_open(&db, pathname, APR_WRITE | APR_CREATE | APR_SHARELOCK,
   1.514 ++                               APR_OS_DEFAULT, r->pool))!= APR_SUCCESS) {
   1.515 ++	return status;
   1.516 ++    }
   1.517 ++
   1.518 ++    apr_sdbm_fetch(db, &val, key);
   1.519 ++
   1.520 ++    if(val.dptr) {
   1.521 ++	apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE);
   1.522 ++	apr_sdbm_fetch(db, &val, key);
   1.523 ++	size = atoi(val.dptr);
   1.524 ++	if(add_size) {
   1.525 ++	    size += delta;
   1.526 ++	} else {
   1.527 ++	    size -= delta;
   1.528 ++	}
   1.529 ++	val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
   1.530 ++	val.dsize = strlen(val.dptr);
   1.531 ++	apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
   1.532 ++	apr_sdbm_unlock(db);
   1.533 ++   } else {
   1.534 ++	size=dav_qchk_du(dirname, r->pool);
   1.535 ++	val.dptr = apr_psprintf(r->pool,"%" APR_OFF_T_FMT, size);
   1.536 ++	val.dsize = strlen(val.dptr);
   1.537 ++	apr_sdbm_store(db, key, val, APR_SDBM_REPLACE);
   1.538 ++    }
   1.539 ++
   1.540 ++    apr_sdbm_close(db);
   1.541 ++    return APR_SUCCESS;
   1.542 ++}
   1.543 + #if DEBUG_GET_HANDLER
   1.544 + 
   1.545 + /* only define set_headers() and deliver() for debug purposes */
   1.546 +@@ -1355,6 +1575,8 @@
   1.547 +                                           dav_response **response)
   1.548 + {
   1.549 +     dav_resource_private *info = resource->info;
   1.550 ++    struct stat status;
   1.551 ++    apr_size_t putsize = 0;
   1.552 + 
   1.553 +     *response = NULL;
   1.554 + 
   1.555 +@@ -1394,6 +1616,10 @@
   1.556 +     }
   1.557 + 
   1.558 +     /* not a collection; remove the file and its properties */
   1.559 ++    if (info->area_path && !lstat(info->pathname, &status) ) {
   1.560 ++	putsize = status.st_blocks/2;
   1.561 ++    	dav_change_cached_du(info->area_path, info->r, 0, putsize);
   1.562 ++    }
   1.563 +     if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) {
   1.564 +         /* ### put a description in here */
   1.565 +         return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);
   1.566 +@@ -1418,7 +1644,12 @@
   1.567 +     int isdir = fsctx->res1.collection;
   1.568 +     apr_finfo_t dirent;
   1.569 +     apr_dir_t *dirp;
   1.570 ++    char *dirname;
   1.571 ++    const ap_regex_t *mask;
   1.572 + 
   1.573 ++    if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_MASK) {
   1.574 ++	mask=dav_fs_get_mask(fsctx->info1.r);
   1.575 ++    }
   1.576 +     /* ensure the context is prepared properly, then call the func */
   1.577 +     err = (*params->func)(&fsctx->wres,
   1.578 +                           isdir
   1.579 +@@ -1455,13 +1686,16 @@
   1.580 +     fsctx->res2.collection = 0;
   1.581 + 
   1.582 +     /* open and scan the directory */
   1.583 ++    dirname=apr_pstrdup(pool, fsctx->path1.buf);
   1.584 +     if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
   1.585 +         /* ### need a better error */
   1.586 +         return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
   1.587 +     }
   1.588 +-    while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
   1.589 ++    while ((apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_NORM, dirp)) == APR_SUCCESS) {
   1.590 +         apr_size_t len;
   1.591 +         apr_status_t status;
   1.592 ++	apr_finfo_t finfo;
   1.593 ++	apr_status_t rv;
   1.594 + 
   1.595 +         len = strlen(dirent.name);
   1.596 + 
   1.597 +@@ -1479,6 +1713,37 @@
   1.598 +             if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) {
   1.599 +                 continue;
   1.600 +             }
   1.601 ++	    //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Hiddenfiles %i",fsctx->info1.hiddenfiles);
   1.602 ++	    if(fsctx->info1.hiddenfiles && fsctx->info1.hiddenfiles!=-1) {
   1.603 ++		if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_HIDDEN) {
   1.604 ++		    if(dirent.name[0]=='.') {
   1.605 ++			continue;
   1.606 ++		    }
   1.607 ++		} else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_DENY) {
   1.608 ++		    request_rec *rr;
   1.609 ++		    const char *fullname = apr_pstrcat(pool, dirname, dirent.name, NULL);
   1.610 ++		    if (!(rr = ap_sub_req_lookup_file(ap_os_escape_path(pool,fullname,1), fsctx->info1.r, NULL))) {
   1.611 ++			//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Path %s, filename %s, fullname %s, return false", dirname, dirent.name, fullname);
   1.612 ++			continue;
   1.613 ++		    }
   1.614 ++		    if (rr->status >= 400) {
   1.615 ++			//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);
   1.616 ++			ap_destroy_sub_req(rr);
   1.617 ++			continue;
   1.618 ++		    }
   1.619 ++		    //ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"dirname %s, subrequest filename %s",dirname, rr->filename);
   1.620 ++		    ap_destroy_sub_req(rr);
   1.621 ++		} else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_HTACCESS) {
   1.622 ++		    if(!strcmp(dirent.name, ".htaccess")) {
   1.623 ++			continue;
   1.624 ++		    }
   1.625 ++		} else if(fsctx->info1.hiddenfiles==DAV_FS_HIDE_MASK) {
   1.626 ++		    if(!ap_regexec(mask, dirent.name, 0, NULL, 0)) {
   1.627 ++			//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"hide %s",dirent.name);
   1.628 ++			continue;
   1.629 ++		    }
   1.630 ++		}
   1.631 ++	    }
   1.632 +         }
   1.633 +         /* skip the state dir unless a HIDDEN is performed */
   1.634 +         if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
   1.635 +@@ -1489,14 +1754,8 @@
   1.636 +         /* append this file onto the path buffer (copy null term) */
   1.637 +         dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);
   1.638 + 
   1.639 +-        status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
   1.640 +-                          DAV_FINFO_MASK, pool);
   1.641 +-        if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
   1.642 +-            /* woah! where'd it go? */
   1.643 +-            /* ### should have a better error here */
   1.644 +-            err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
   1.645 +-            break;
   1.646 +-        }
   1.647 ++        //set the finfo for further process
   1.648 ++        fsctx->info1.finfo=dirent;
   1.649 + 
   1.650 +         /* copy the file to the URI, too. NOTE: we will pad an extra byte
   1.651 +            for the trailing slash later. */
   1.652 +@@ -1512,10 +1771,11 @@
   1.653 +         fsctx->info2.pathname = fsctx->path2.buf;
   1.654 + 
   1.655 +         /* set up the URI for the current resource */
   1.656 ++        //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);
   1.657 +         fsctx->res1.uri = fsctx->uri_buf.buf;
   1.658 + 
   1.659 +         /* ### for now, only process regular files (e.g. skip symlinks) */
   1.660 +-        if (fsctx->info1.finfo.filetype == APR_REG) {
   1.661 ++        if (dirent.filetype == APR_REG) {
   1.662 +             /* call the function for the specified dir + file */
   1.663 +             if ((err = (*params->func)(&fsctx->wres,
   1.664 +                                        DAV_CALLTYPE_MEMBER)) != NULL) {
   1.665 +@@ -1523,7 +1783,7 @@
   1.666 +                 break;
   1.667 +             }
   1.668 +         }
   1.669 +-        else if (fsctx->info1.finfo.filetype == APR_DIR) {
   1.670 ++        else if (dirent.filetype == APR_DIR) {
   1.671 +             apr_size_t save_path_len = fsctx->path1.cur_len;
   1.672 +             apr_size_t save_uri_len = fsctx->uri_buf.cur_len;
   1.673 +             apr_size_t save_path2_len = fsctx->path2.cur_len;
   1.674 +@@ -1690,6 +1950,7 @@
   1.675 +     dav_fs_walker_context fsctx = { 0 };
   1.676 +     dav_error *err;
   1.677 +     dav_fs_copymove_walk_ctx cm_ctx = { 0 };
   1.678 ++    const char *uri,*request=params->root->info->r->the_request;
   1.679 + 
   1.680 + #if DAV_DEBUG
   1.681 +     if ((params->walk_type & DAV_WALKTYPE_LOCKNULL) != 0
   1.682 +@@ -1743,7 +2004,11 @@
   1.683 +     }
   1.684 + 
   1.685 +     /* prep the URI buffer */
   1.686 +-    dav_buffer_init(params->pool, &fsctx.uri_buf, params->root->uri);
   1.687 ++
   1.688 ++    uri = ap_getword(params->pool, &request, ' '); //get method
   1.689 ++    uri = ap_getword(params->pool, &request, ' '); //get uri
   1.690 ++    ap_unescape_url(uri);
   1.691 ++    dav_buffer_init(params->pool, &fsctx.uri_buf, uri);
   1.692 + 
   1.693 +     /* if we have a directory, then ensure the URI has a trailing "/" */
   1.694 +     if (fsctx.res1.collection
   1.695 +@@ -1844,8 +2109,11 @@
   1.696 +     ** client cannot store dead values -- we deny that thru the is_writable
   1.697 +     ** hook function.
   1.698 +     */
   1.699 +-    if (!resource->exists)
   1.700 ++    if (!resource->exists) {
   1.701 ++//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"resource not exist");
   1.702 ++
   1.703 +         return DAV_PROP_INSERT_NOTDEF;
   1.704 ++}
   1.705 + 
   1.706 +     switch (propid) {
   1.707 +     case DAV_PROPID_creationdate:
   1.708 +@@ -1896,15 +2164,29 @@
   1.709 +             value = "F";
   1.710 +         break;
   1.711 + 
   1.712 ++    case DAV_PROPID_quota_available_bytes:
   1.713 ++	/* Property defined only for collection with quota */
   1.714 ++        if (!resource->info->quota || !resource->collection)
   1.715 ++            return DAV_PROP_INSERT_NOTDEF;
   1.716 ++        value = apr_psprintf(p, "%d", (resource->info->quota-dav_cached_du(resource->info->area_path, resource->info->r))*1024);
   1.717 ++	break;
   1.718 ++
   1.719 ++    case DAV_PROPID_quota_used_bytes:
   1.720 ++	/* Property defined only for collection with quota */
   1.721 ++        if (!resource->info->quota || !resource->collection)
   1.722 ++            return DAV_PROP_INSERT_NOTDEF;
   1.723 ++	value = apr_psprintf(p, "%d", dav_cached_du(resource->info->area_path, resource->info->r)*1024);
   1.724 ++	break;
   1.725 ++
   1.726 +     default:
   1.727 +         /* ### what the heck was this property? */
   1.728 +         return DAV_PROP_INSERT_NOTDEF;
   1.729 +     }
   1.730 + 
   1.731 +     /* assert: value != NULL */
   1.732 +-
   1.733 +     /* get the information and global NS index for the property */
   1.734 +     global_ns = dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info);
   1.735 ++//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"ns=%d name=%s value=%s",global_ns, info->name, value);
   1.736 + 
   1.737 +     /* assert: info != NULL && info->name != NULL */
   1.738 + 
   1.739 +@@ -2138,7 +2420,7 @@
   1.740 +         */
   1.741 +         return;
   1.742 +     }
   1.743 +-
   1.744 ++//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Try show all props");
   1.745 +     (void) dav_fs_insert_prop(resource, DAV_PROPID_creationdate,
   1.746 +                               what, phdr);
   1.747 +     (void) dav_fs_insert_prop(resource, DAV_PROPID_getcontentlength,
   1.748 +@@ -2148,6 +2430,11 @@
   1.749 +     (void) dav_fs_insert_prop(resource, DAV_PROPID_getetag,
   1.750 +                               what, phdr);
   1.751 + 
   1.752 ++    (void) dav_fs_insert_prop(resource, DAV_PROPID_quota_available_bytes,
   1.753 ++                              what, phdr);
   1.754 ++    (void) dav_fs_insert_prop(resource, DAV_PROPID_quota_used_bytes,
   1.755 ++                              what, phdr);
   1.756 ++
   1.757 + #ifdef DAV_FS_HAS_EXECUTABLE
   1.758 +     /* Only insert this property if it is defined for this platform. */
   1.759 +     (void) dav_fs_insert_prop(resource, DAV_PROPID_FS_executable,
   1.760 +Index: modules/dav/fs/repos.h
   1.761 +diff -Nau modules/dav/fs/repos.h.orig modules/dav/fs/repos.h
   1.762 +--- modules/dav/fs/repos.h.orig	2006-07-12 05:38:44.000000000 +0200
   1.763 ++++ modules/dav/fs/repos.h	2012-09-17 14:16:06.941582156 +0200
   1.764 +@@ -30,6 +30,12 @@
   1.765 + #define DAV_FS_STATE_FILE_FOR_DIR       ".state_for_dir"
   1.766 + #define DAV_FS_LOCK_NULL_FILE           ".locknull"
   1.767 + 
   1.768 ++#define DAV_FS_HIDE_NONE		0
   1.769 ++#define DAV_FS_HIDE_HIDDEN		1
   1.770 ++#define DAV_FS_HIDE_DENY		2
   1.771 ++#define DAV_FS_HIDE_HTACCESS		3
   1.772 ++#define DAV_FS_HIDE_MASK		4
   1.773 ++
   1.774 + 
   1.775 + /* ensure that our state subdirectory is present */
   1.776 + void dav_fs_ensure_state_dir(apr_pool_t *p, const char *dirname);
   1.777 +@@ -67,6 +73,8 @@
   1.778 + /* where is the lock database located? */
   1.779 + const char *dav_get_lockdb_path(const request_rec *r);
   1.780 + 
   1.781 ++const char *dav_get_diskusagedb_path(const request_rec *r);
   1.782 ++
   1.783 + const dav_hooks_locks *dav_fs_get_lock_hooks(request_rec *r);
   1.784 + const dav_hooks_propdb *dav_fs_get_propdb_hooks(request_rec *r);
   1.785 + 
   1.786 +@@ -79,6 +87,11 @@
   1.787 + 
   1.788 + void dav_fs_register(apr_pool_t *p);
   1.789 + 
   1.790 ++const apr_size_t dav_fs_get_quota( request_rec *r );
   1.791 ++const char *dav_fs_get_dir( request_rec *r );
   1.792 ++const int dav_fs_get_hidefiles( request_rec *r );
   1.793 ++const ap_regex_t *dav_fs_get_mask( request_rec *r );
   1.794 ++
   1.795 + #endif /* _DAV_FS_REPOS_H_ */
   1.796 + /** @} */
   1.797 + 
   1.798 +Index: modules/dav/main/mod_dav.c
   1.799 +diff -Nau modules/dav/main/mod_dav.c.orig modules/dav/main/mod_dav.c
   1.800 +--- modules/dav/main/mod_dav.c.orig	2011-02-09 09:43:17.000000000 +0100
   1.801 ++++ modules/dav/main/mod_dav.c	2012-09-17 14:16:06.944219747 +0200
   1.802 +@@ -884,7 +884,14 @@
   1.803 + 
   1.804 +     return DECLINED;
   1.805 + }
   1.806 +-
   1.807 ++struct dav_stream {
   1.808 ++    apr_pool_t *p;
   1.809 ++    apr_file_t *f;
   1.810 ++    const char *pathname;       /* we may need to remove it at close time */
   1.811 ++    apr_size_t quota;           /* config data for quota check */
   1.812 ++    const char *area_path;
   1.813 ++    request_rec *r;         /* request of this resource*/
   1.814 ++};
   1.815 + /* handle the PUT method */
   1.816 + static int dav_method_put(request_rec *r)
   1.817 + {
   1.818 +@@ -958,7 +965,6 @@
   1.819 +     else {
   1.820 +         mode = DAV_MODE_WRITE_TRUNC;
   1.821 +     }
   1.822 +-
   1.823 +     /* make sure the resource can be modified (if versioning repository) */
   1.824 +     if ((err = dav_auto_checkout(r, resource,
   1.825 +                                  0 /* not parent_only */,
   1.826 +@@ -1043,6 +1049,7 @@
   1.827 +             /* no error during the write, but we hit one at close. use it. */
   1.828 +             err = err2;
   1.829 +         }
   1.830 ++
   1.831 +     }
   1.832 + 
   1.833 +     /*
   1.834 +@@ -2583,7 +2590,6 @@
   1.835 +     dav_lockdb *lockdb;
   1.836 +     int replace_dest;
   1.837 +     int resnew_state;
   1.838 +-
   1.839 +     /* Ask repository module to resolve the resource */
   1.840 +     err = dav_get_resource(r, !is_move /* label_allowed */,
   1.841 +                            0 /* use_checked_in */, &resource);
   1.842 +@@ -2635,6 +2641,7 @@
   1.843 + 
   1.844 +         return dav_error_response(r, lookup.err.status, lookup.err.desc);
   1.845 +     }
   1.846 ++
   1.847 +     if (lookup.rnew->status != HTTP_OK) {
   1.848 +         const char *auth = apr_table_get(lookup.rnew->err_headers_out,
   1.849 +                                         "WWW-Authenticate");
   1.850 +@@ -2700,6 +2707,7 @@
   1.851 +     if ((depth = dav_get_depth(r, DAV_INFINITY)) < 0) {
   1.852 +         /* dav_get_depth() supplies additional information for the
   1.853 +          * default message. */
   1.854 ++
   1.855 +         return HTTP_BAD_REQUEST;
   1.856 +     }
   1.857 +     if (depth == 1) {
   1.858 +@@ -2817,7 +2825,6 @@
   1.859 +         /* ### pass lockdb! */
   1.860 +         (void)dav_unlock(r, resource, NULL);
   1.861 +     }
   1.862 +-
   1.863 +     /* if this is a move, then the source parent collection will be modified */
   1.864 +     if (is_move) {
   1.865 +         if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */,
   1.866 +@@ -2835,7 +2842,6 @@
   1.867 +      * can be notified as to how it changed.
   1.868 +      */
   1.869 +     resnew_state = dav_get_resource_state(lookup.rnew, resnew);
   1.870 +-
   1.871 +     /* In a MOVE operation, the destination is replaced by the source.
   1.872 +      * In a COPY operation, if the destination exists, is under version
   1.873 +      * control, and is the same resource type as the source,
   1.874 +@@ -4573,7 +4579,7 @@
   1.875 +      * be more destructive than the user intended. */
   1.876 +     if (r->parsed_uri.fragment != NULL) {
   1.877 +         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
   1.878 +-                     "buggy client used un-escaped hash in Request-URI");
   1.879 ++                     "buggy client used un-escaped hash in Request-URI uri is '%s'",r->uri);
   1.880 +         return dav_error_response(r, HTTP_BAD_REQUEST,
   1.881 +                                   "The request was invalid: the URI included "
   1.882 +                                   "an un-escaped hash character");
   1.883 +Index: modules/dav/main/util.c
   1.884 +diff -Nau modules/dav/main/util.c.orig modules/dav/main/util.c
   1.885 +--- modules/dav/main/util.c.orig	2010-07-21 20:25:49.000000000 +0200
   1.886 ++++ modules/dav/main/util.c	2012-09-17 14:16:06.945216500 +0200
   1.887 +@@ -168,6 +168,8 @@
   1.888 +     apr_port_t port;
   1.889 +     apr_uri_t comp;
   1.890 +     char *new_file;
   1.891 ++    const char *new_filename;
   1.892 ++    char *redirect;
   1.893 +     const char *domain;
   1.894 + 
   1.895 +     /* first thing to do is parse the URI into various components */
   1.896 +@@ -278,7 +280,13 @@
   1.897 +      * to apply appropriate restrictions (e.g. readonly).
   1.898 +      */
   1.899 +     result.rnew = ap_sub_req_method_uri(r->method, new_file, r, NULL);
   1.900 +-
   1.901 ++    //detect redirect
   1.902 ++    new_filename=apr_pstrdup(r->pool, result.rnew->filename);
   1.903 ++    redirect=ap_getword(r->pool, &new_filename, ':');
   1.904 ++    //ap_unescape_url(new_filename);
   1.905 ++    if(!strcasecmp(redirect, "redirect")) {//subrequest for resolve redirect
   1.906 ++    	result.rnew = ap_sub_req_method_uri(r->method, new_filename, r, NULL);
   1.907 ++    }
   1.908 +     return result;
   1.909 + }
   1.910 + 
   1.911 +@@ -1420,11 +1428,11 @@
   1.912 + 
   1.913 +     retVal = ap_meets_conditions(r);
   1.914 + 
   1.915 +-    /* If-None-Match '*' fix. If-None-Match '*' request should succeed 
   1.916 ++    /* If-None-Match '*' fix. If-None-Match '*' request should succeed
   1.917 +      * if the resource does not exist. */
   1.918 +     if (retVal == HTTP_PRECONDITION_FAILED) {
   1.919 +         /* Note. If if_none_match != NULL, if_none_match is the culprit.
   1.920 +-         * Since, in presence of If-None-Match, 
   1.921 ++         * Since, in presence of If-None-Match,
   1.922 +          * other If-* headers are undefined. */
   1.923 +         if ((if_none_match =
   1.924 +             apr_table_get(r->headers_in, "If-None-Match")) != NULL) {
   1.925 +Index: modules/mappers/mod_rewrite.c
   1.926 +diff -Nau modules/mappers/mod_rewrite.c.orig modules/mappers/mod_rewrite.c
   1.927 +--- modules/mappers/mod_rewrite.c.orig	2012-01-24 20:39:31.000000000 +0100
   1.928 ++++ modules/mappers/mod_rewrite.c	2012-09-17 14:16:06.947134500 +0200
   1.929 +@@ -2286,7 +2286,7 @@
   1.930 +                     current->len = span;
   1.931 +                     current->string = bri->source + bri->regmatch[n].rm_so;
   1.932 +                 }
   1.933 +-                
   1.934 ++
   1.935 +                 outlen += span;
   1.936 +             }
   1.937 + 
   1.938 +@@ -3250,7 +3250,7 @@
   1.939 +     case 'B':
   1.940 +         if (!*key || !strcasecmp(key, "ackrefescaping")) {
   1.941 +             cfg->flags |= RULEFLAG_ESCAPEBACKREF;
   1.942 +-        } 
   1.943 ++        }
   1.944 +         else {
   1.945 +             ++error;
   1.946 +         }
   1.947 +@@ -4026,6 +4026,7 @@
   1.948 +         if (r->main != NULL &&
   1.949 +             (p->flags & RULEFLAG_IGNOREONSUBREQ ||
   1.950 +              p->flags & RULEFLAG_FORCEREDIRECT    )) {
   1.951 ++ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,"Ignore this rule on subrequests");
   1.952 +             continue;
   1.953 +         }
   1.954 + 
     2.1 --- a/apache/apache.spec	Mon Sep 17 19:01:16 2012 +0200
     2.2 +++ b/apache/apache.spec	Mon Sep 17 19:02:42 2012 +0200
     2.3 @@ -32,7 +32,7 @@
     2.4  Group:        Web
     2.5  License:      ASF
     2.6  Version:      2.2.22
     2.7 -Release:      20120205
     2.8 +Release:      20120800
     2.9  
    2.10  #   package options
    2.11  %option       with_mpm_prefork          yes
    2.12 @@ -80,6 +80,7 @@
    2.13  Source3:      apache.conf
    2.14  Source4:      apache.sh
    2.15  Patch0:       apache.patch
    2.16 +Patch1:       apache.patch.davquo
    2.17  
    2.18  #   build information
    2.19  BuildPreReq:  OpenPKG, openpkg >= 20100101, perl, make
    2.20 @@ -126,6 +127,7 @@
    2.21      #   unpack Apache distribution
    2.22      %setup -q -n httpd-%{version}
    2.23      %patch -p0
    2.24 +    %patch -p0 -P 1
    2.25      %{l_shtool} subst \
    2.26          -e 's;(" PLATFORM ");(%{l_openpkg_release -F "OpenPKG/%%t"});g' \
    2.27          server/core.c

mercurial