[subversion:18] Tons of little changes to fix bugs revealed by sorting out interoperatio

  • From: TimBray@kenai.com
  • To: commits@mod-atom.kenai.com
  • Subject: [subversion:18] Tons of little changes to fix bugs revealed by sorting out interoperatio
  • Date: Thu, 6 Nov 2008 18:25:07 +0000 (GMT)

Repository: subversion
Revision:   18
Author:     tim.bray@sun.com
Date:       2008-11-06 18:25:01 UTC

Log Message:
-----------
Tons of little changes to fix bugs revealed by sorting out
interoperation with MarsEdit.  Also, repaired draft-edit handling
breakage.

Modified Paths:
--------------
    src/mod_atom.hsrc/mod_atom.c

Diffs:
-----
Index: src/mod_atom.c
===================================================================
--- src/mod_atom.c      (revision 17)
+++ src/mod_atom.c      (revision 18)
@@ -236,7 +236,7 @@
                                           int ns_ind, char * type,
                                           char * content);
 static char * insert_text_content(request_rec * r, apr_xml_elem * e,
char * t);
-static int is_draft(apr_pool_t * pool, apr_xml_doc * doc);
+static int is_draft(apr_pool_t * pool, apr_xml_doc * doc, apr_xml_elem
* entry);
 static int is_html_enabled(apr_pool_t * pool, pub_t * pub);
 static char * is_prefix(char * s, char * prefix);
 static int lock_file(apr_pool_t * p, char * filename, void * *
mutex_p);
@@ -248,7 +248,7 @@
 static int put_entry(request_rec * r, pub_t * pub, entry_t * e);
 static int put_media(request_rec * r, pub_t * pub, entry_t * e);
 static char * refresh_collection(char * coll_base, pub_t * pub,
-                                 apr_pool_t * pool, apr_finfo_t *
coll_finfo);
+                                 request_rec * r, apr_finfo_t *
coll_finfo);
 static int replace_media(request_rec * r, entry_t * e);
 static char * rm_rf(apr_pool_t * pool, char * dir);
 static int save_new_entry(request_rec * r, entry_t * e);
@@ -428,18 +428,50 @@
     /* assuming the target filename exists */
     if (status == APR_SUCCESS) {
 
-        /* if we're getting a collection, check the timestamp file to
see
-         *  if we need to regenerate it.
+        /* certain GET transactions may require us to get un-lazy and
+         *  refresh certain resources.
          */
-        if ((r->method_number == M_GET) &&
-                MATCHES(pub->patterns->collection, r->uri)) {
+        if ((r->method_number == M_GET)) {
+
             char * coll_base = dir_of(r->pool, r->filename);
-            char * prob = refresh_collection(coll_base, pub, r->pool,
&finfo);
 
-            if (prob)
-                return server_error(r, APR_SUCCESS, "In GET
collection, %s",
-                                    prob);
+            /* if it's a collection, it may need regeneration
+             */
+            if (MATCHES(pub->patterns->collection, r->uri)) {
+                char * prob = refresh_collection(coll_base, pub, r,
&finfo);
 
+                if (prob)
+                    return server_error(r, APR_SUCCESS, "In GET
collection, %s",
+                                        prob);
+            }
+
+            /* if it's on the front page, i.e. index.html or
feed.atom,
+             *  it may need regeneration if the collection needs
refreshing
+             */
+            else {
+                int front_page = 0;
+                
+                /* on the front page if it's feed.atom */
+                if (MATCHES(pub->patterns->feed, r->uri))
+                    front_page = 1;
+
+                /* faiing that, if it's identical to coll_base or
+                 *  that plus a trailing slash
+                 */
+                else {
+                    char * s = is_prefix(r->filename, coll_base);
+                    if ((s != NULL) && (*s == 0 || strcmp(s, "/") ==
0))
+                        front_page = 1;
+                }
+
+                /* OK, on the front page.  If the collection needs
refreshing,
+                 *  then so will the index.html and feed.atom
+                 */
+                if (front_page) {
+                    apr_finfo_t new_finfo;
+                    refresh_collection(coll_base, pub, r, &new_finfo);
+                }
+            }
         }
         r->finfo = finfo;
         return OK;
@@ -448,7 +480,7 @@
     /* Initial stat failed. This may not be a problem.
      * It has to exist... unless this is a PUT into the extras space
*/
     if ((r->method_number == M_PUT) &&
-        MATCHES(pub->patterns->extras_space, r->uri))
+            MATCHES(pub->patterns->extras_space, r->uri))
         return OK;
 
     return HTTP_NOT_FOUND;
@@ -847,7 +879,7 @@
     apr_status_t status;
     char * problem;
     char * coll_base;
-    int html_removed = 0;
+    char * mutex_name;
 
     /* may not be necessary */
     if (!atom_file_exists(r->filename, r->pool))
@@ -893,6 +925,7 @@
 
         /* the bits is the same filename minus the trailing .atom */
         char * bits;
+        char * ancillary;
         bits = apr_pstrdup(r->pool, r->filename);
         *(rindex(bits, '.')) = 0;
         status = apr_file_remove(bits, r->pool);
@@ -900,19 +933,21 @@
             return server_error(r, status,
                                 "Can't remove media resource at '%s'",
bits);
 
-        bits = apr_psprintf(r->pool, "%s.%s", bits,
MEDIA_TYPE_SUFFIX);
-        status = apr_file_remove(bits, r->pool);
+        ancillary = apr_psprintf(r->pool, "%s.%s", bits,
MEDIA_TYPE_SUFFIX);
+        status = apr_file_remove(ancillary, r->pool);
         if (status != APR_SUCCESS)
             return server_error(r, status,
                                 "Can't remove media resource at '%s'",
bits);
 
+        ancillary = apr_psprintf(r->pool, "%s.%s", bits,
MUTEX_SUFFIX);
+        apr_file_remove(ancillary, r->pool);
     }
     else {
         /* not a media-link entry.  Thus there may be an HTML or text
file 
          *  to lose; but there may not be, if the content@type was
none of
          *  'html', 'xhtml', or 'text'.
          * We could parse the entry and look at the content type
-         *  to figure out the exact name, but why not just try
deleting any
+         *  to figure out the exact name, but why not just try
deleting all
          *  of them.
          */
         char * extensions[] = {".html", ".text", ".html", NULL};
@@ -920,10 +955,9 @@
         char * base = apr_pstrdup(r->pool, r->filename);
         *(rindex(base, '.')) = 0;
 
-        for (i = 0; extensions[i] && !html_removed; i++) {
+        for (i = 0; extensions[i]; i++) {
             char * target = apr_pstrcat(r->pool, base, extensions[i],
NULL);
-            status = apr_file_remove(target, r->pool);
-            html_removed = html_removed || (status == APR_SUCCESS);
+            apr_file_remove(target, r->pool);
         }
     }
 
@@ -997,14 +1031,14 @@
     if ((status = apr_file_remove(r->filename, r->pool)) !=
APR_SUCCESS)
         return server_error(r, status, "Can't remove file '%s'",
r->filename);
 
+    /* and its mutex if there is one */
+    mutex_name = apr_psprintf(r->pool, "%s.%s", r->filename,
MUTEX_SUFFIX);
+    apr_file_remove(mutex_name, r->pool);
+
     /* signal that collection needs updating */
     coll_base = find_coll_base(r, pub);
     timestamp(coll_base, r->pool);
 
-    /* we did nuke some HTML.  Have to update feed & front page */
-    if (html_removed)
-        update_public_site(r, pub, coll_base);
-
     return HTTP_NO_CONTENT;
 }
 
@@ -1015,10 +1049,11 @@
  *  collection.
  */
 static char * refresh_collection(char * coll_base, pub_t * pub,
-                                 apr_pool_t * pool, apr_finfo_t *
coll_finfo) {
+                                 request_rec * r, apr_finfo_t *
coll_finfo) {
+    apr_pool_t * pool = r->pool;
     apr_finfo_t ts_finfo;
     apr_status_t ts_status, coll_status;
-    char * ts_fn = atom_join(pool, coll_base, TIMESTAMP_FILE, NULL);
+    char * ts_fn = atom_join(r->pool, coll_base, TIMESTAMP_FILE,
NULL);
     char * coll_fn = atom_join(pool, coll_base, COLLECTION_FILE,
NULL);
     int refresh = 1;
     char * problem = NULL;
@@ -1043,6 +1078,11 @@
                                        "Can't stat refreshed
collection '%s",
                                        coll_fn);
         }
+
+        /* the collection has been refreshed; the index.html and
feed.atom,
+         *  which depend on it, should be too.
+         */
+        update_public_site(r, pub, coll_base);
     }
     return problem;
 }
@@ -1061,7 +1101,7 @@
  */
 static int lock_file(apr_pool_t * p, char * filename, void * *
mutex_p) {
     apr_file_t * fp;
-    char * mutex_name = apr_pstrcat(p, filename, ".mutex", NULL);
+    char * mutex_name = apr_psprintf(p, "%s.%s", filename,
MUTEX_SUFFIX);
     apr_status_t status;
 
     status = apr_file_open(&fp, mutex_name, APR_FOPEN_WRITE |
APR_FOPEN_CREATE,
@@ -1795,7 +1835,7 @@
         &title, &summary, &content, &author
     };
 
-    if (is_draft(r->pool, doc))
+    if (is_draft(r->pool, doc, entry))
         return;
 
     atom_xml_children(doc, entry, ATOM_NS, wanted, children);
@@ -2187,9 +2227,8 @@
     run_fp_template_element(gw, pub, template, template->root, t_ns,
r, state);
 }
 
-/* something has happened to an entry which has a corresponding HTML
- *  version.  Thus, the public feed and front-page for that collection
- *  need to be updated.
+/* A collection has been updated; the front page (index.html and
feed.atom)
+ *  need to be rebuilt from the collection file.
  */
 static void update_public_site(request_rec * r, pub_t * pub, char *
coll_base) {
     apr_file_t * html_fp;
@@ -2315,17 +2354,21 @@
     /* OK, now we'll run through the entries from the feed */
     namespaces = (char * *) coll->namespaces->elts;
     for (count = 0, entry = coll->root->first_child;
-        entry && (count < DEFAULT_ENTRIES_IN_FEED);
-        entry = entry->next) {
+            entry && (count < DEFAULT_ENTRIES_IN_FEED);
+            entry = entry->next) {
         text_construct_type_t type = TEXT_TYPE;
         apr_xml_elem * content;
 
         /* skip non-entries */
         if (entry->ns == APR_XML_NS_NONE ||
-            strcmp(namespaces[entry->ns], ATOM_NS) != 0 ||
-            strcmp(entry->name, "entry") != 0)
+                strcmp(namespaces[entry->ns], ATOM_NS) != 0 ||
+                strcmp(entry->name, "entry") != 0)
             continue;
 
+        /* skip draft entries */
+        if (is_draft(r->pool, coll, entry))
+            continue;
+
         /* for each atom:entry in the feed */
         /* if the type on its content is other than MEDIA_TYPE, we'll
keep it */
         content = atom_xml_child(coll, entry, ATOM_NS, "content");
@@ -2365,11 +2408,11 @@
 /* Does an app:draft appear as a child of an app:control which is a
child
  *  of the atom:entry?
  */
-static int is_draft(apr_pool_t * pool, apr_xml_doc * doc) {
+static int is_draft(apr_pool_t * pool, apr_xml_doc * doc, apr_xml_elem
* entry) {
     apr_xml_elem * control;
     char * draft_val = "no";
 
-    if ((control = atom_xml_child(doc, doc->root, APP_NS, "control")))
{
+    if ((control = atom_xml_child(doc, entry, APP_NS, "control"))) {
         apr_xml_elem * draft;
         if ((draft = atom_xml_child(doc, control, APP_NS, "draft")))
             draft_val = element_text(draft, pool);
@@ -2405,7 +2448,7 @@
      * 1. app:draft is set in the entry
      * 2. the file x/options/html does not exist
      */
-    if (is_draft(r->pool, e->xml))
+    if (is_draft(r->pool, e->xml, e->xml->root))
         return;
     if (!is_html_enabled(r->pool, e->pub))
         return;
@@ -2475,8 +2518,6 @@
                      "Can't rename '%s' to '%s': %s", tempname,
filename,
                      error_message(r->pool, status));
     }
-
-    update_public_site(r, e->pub, e->coll_base);
 }
 
 /* Create an entry, and generate related URIs */
Index: src/mod_atom.h
===================================================================
--- src/mod_atom.h      (revision 17)
+++ src/mod_atom.h      (revision 18)
@@ -74,6 +74,7 @@
 #define MEDIA_DIR "m"
 #define MEDIA_TYPE_SUFFIX "mt"
 #define METAPUB_SUBS "s"
+#define MUTEX_SUFFIX "mutex"
 #define OPTIONS_DIR "options"
 #define PUB_DIR "pub"
 #define SERVICE_FILE "pub.atomsvc"


[subversion:18] Tons of little changes to fix bugs revealed by sorting out interoperatio

TimBray 11/06/2008
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20120127.ac94057)
 
 
Close
loading
Please Confirm
Close