[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 |





