Mon, 17 Sep 2012 19:02:42 +0200
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