Bug 27578 - made getlastmodified a writable property
made getlastmodified a writable property
Status: NEW
Product: Apache httpd-2
Classification: Unclassified
Component: mod_dav
2.0.48
Other other
: P3 enhancement with 1 vote (vote)
: ---
Assigned To: Apache HTTPD Bugs Mailing List
: PatchAvailable
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2004-03-10 18:18 UTC by Oliver Dewdney
Modified: 2013-03-19 22:11 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Dewdney 2004-03-10 18:18:32 UTC
we have a load-balanced array of apache web servers and are trying to 
syncronise content between them using webdav. to make the content optimally 
cacheable we have switched off using the inode number in the etag and have to 
have the Last-Modified date the same across all the servers so the If-Modified-
Since request header works as it hopes to.

Oli


diff -u repos.c.orig repos.c
--- repos.c.orig        2004-03-10 17:32:57.000000000 +0000
+++ repos.c     2004-03-10 12:35:14.000000000 +0000
@@ -60,6 +60,7 @@
 #include "apr_file_io.h"
 #include "apr_strings.h"
 #include "apr_buckets.h"
+#include "apr_date.h"
 
 #if APR_HAVE_STDIO_H
 #include <stdio.h>              /* for sprintf() */
@@ -1940,10 +1959,32 @@
         return 1;
 #endif
 
+    if (propid == DAV_PROPID_getlastmodified )
+        return 1;
+
     (void) dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info);
     return info->is_writable;
 }
 
+struct dav_fs_context
+{
+    int propid;
+    union rollback
+    {
+        apr_time_t modtime;
+        apr_fileperms_t perms;
+    } oldvalue;
+    union context
+    {
+        apr_time_t modtime;
+        int perms;
+    } value;
+};
+
+apr_time_t xapr_date_parse_http(char*s)
+{
+return 12345000000000LL + (int)s;
+}
 static dav_error *dav_fs_patch_validate(const dav_resource *resource,
                                         const apr_xml_elem *elem,
                                         int operation,
@@ -1954,7 +1995,34 @@
     const apr_text *f_cdata;
     char value;
     dav_elem_private *priv = elem->priv;
+    struct dav_fs_context *fscontext;
+
+    fscontext = apr_pcalloc(resource->info->pool, sizeof(*fscontext) );
+    fscontext->propid = priv->propid;
+
+    if ( priv->propid == DAV_PROPID_getlastmodified ) {
+        if (operation == DAV_PROP_OP_DELETE)
+            return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+                             "The 'lastmodified' property cannot be removed.");
+        if ( elem->first_cdata.first )
+            cdata = elem->first_cdata.first;
+        else if ( elem->first_child )
+            cdata = elem->first_child->following_cdata.first;
+        else
+            cdata = NULL;
 
+       if ( cdata == NULL )
+            return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+                             "The 'lastmodified' property cannot be found.");
+        fscontext->value.modtime = apr_date_parse_http(cdata->text);
+        short ttt = apr_date_parse_http(cdata->text);
+        if ( fscontext->value.modtime == 0 ) {
+            return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+                             "The 'lastmodified' property cannot be parsed.");
+        }
+        *context = (void*)fscontext;
+       return NULL;
+    }
     if (priv->propid != DAV_PROPID_FS_executable) {
         *defer_to_dead = 1;
         return NULL;
@@ -1997,8 +2065,8 @@
                              "submitted is invalid.");
     }
 
-    *context = (void *)(value == 'T');
-
+    fscontext->value.perms = (value == 'T');
+    *context = (void*)fscontext;
     return NULL;
 
   too_long:
@@ -2009,37 +2077,49 @@
 
 }
 
+
 static dav_error *dav_fs_patch_exec(const dav_resource *resource,
                                     const apr_xml_elem *elem,
                                     int operation,
                                     void *context,
                                     dav_liveprop_rollback **rollback_ctx)
 {
-    int value = context != NULL;
-    apr_fileperms_t perms = resource->info->finfo.protection;
-    int old_value = (perms & APR_UEXECUTE) != 0;
-
-    /* assert: prop == executable. operation == SET. */
-
-    /* don't do anything if there is no change. no rollback info either. */
-    /* DBG2("new value=%d  (old=%d)", value, old_value); */
-    if (value == old_value)
-        return NULL;
-
-    perms &= ~APR_UEXECUTE;
-    if (value)
-        perms |= APR_UEXECUTE;
-
-    if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) {
-        return dav_new_error(resource->info->pool,
+    struct dav_fs_context *fscontext;
+    
+    fscontext = (struct dav_fs_context*)context;
+    if ( fscontext->propid == DAV_PROPID_getlastmodified ) {
+        fscontext->oldvalue.modtime = resource->info->finfo.mtime;
+        if ( apr_file_mtime_set(resource->info->pathname, fscontext-
>value.modtime, resource->info->pool) != APR_SUCCESS )
+            return dav_new_error(resource->info->pool,
+                             HTTP_INTERNAL_SERVER_ERROR, 0,
+                             "Could not set the lastmodified date of the "
+                             "target resource.");
+        resource->info->finfo.mtime = fscontext->value.modtime;
+    } else if (fscontext->propid == DAV_PROPID_FS_executable ) {
+        apr_fileperms_t perms = resource->info->finfo.protection;
+        fscontext->oldvalue.perms = perms;
+
+        /* assert: prop == executable. operation == SET. */
+
+        /* don't do anything if there is no change. no rollback info either. */
+        /* DBG2("new value=%d  (old=%d)", value, old_value); */
+
+        perms &= ~APR_UEXECUTE;
+        if (fscontext->value.perms != 0 )
+            perms |= APR_UEXECUTE;
+
+        if ( perms != fscontext->oldvalue.perms )
+            if (apr_file_perms_set(resource->info->pathname, perms) != 
APR_SUCCESS) {
+            return dav_new_error(resource->info->pool,
                              HTTP_INTERNAL_SERVER_ERROR, 0,
                              "Could not set the executable flag of the "
                              "target resource.");
-    }
+            }
 
-    /* update the resource and set up the rollback context */
-    resource->info->finfo.protection = perms;
-    *rollback_ctx = (dav_liveprop_rollback *)old_value;
+        /* update the resource and set up the rollback context */
+        resource->info->finfo.protection = perms;
+    }
+    *rollback_ctx = (dav_liveprop_rollback *)fscontext;
 
     return NULL;
 }
@@ -2057,8 +2137,17 @@
                                         void *context,
                                         dav_liveprop_rollback *rollback_ctx)
 {
+    struct dav_fs_context *rollback = (struct dav_fs_context*)rollback_ctx;
+    if ( rollback->propid == DAV_PROPID_getlastmodified ) {
+        if ( apr_file_mtime_set(resource->info->pathname, rollback-
>oldvalue.modtime, resource->info->pool) != APR_SUCCESS )
+            return dav_new_error(resource->info->pool,
+                             HTTP_INTERNAL_SERVER_ERROR, 0,
+                             "Could not set the lastmodified date of the "
+                             "target resource.");
+        return NULL;
+    }
     apr_fileperms_t perms = resource->info->finfo.protection & ~APR_UEXECUTE;
-    int value = rollback_ctx != NULL;
+    int value = (rollback->oldvalue.perms & APR_UEXECUTE) != 0;
 
     /* assert: prop == executable. operation == SET. */
Comment 1 Wim Lewis 2013-03-19 22:11:05 UTC
++. I have also run into situation where I'd like to be able to set the last-modified-date via PROPPATCH.