Mon, 28 Jan 2013 17:37:18 +0100
Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.
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 |