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