Ticket #4290 (closed Bug: fixed)
HEAD request returns 404 error for Plone folders w/o index_html
| Reported by: | krid | Owned by: | |
|---|---|---|---|
| Priority: | major | Milestone: | 2.1 |
| Component: | Infrastructure | Keywords: | |
| Cc: |
Description
A HEAD request for a Plone folder that does not have a default document defined (eg. index_html) returns a "404 Not Found" response. This causes major headaches for any external systems that use HEAD to check the existence or update time of a page (for instance, caches, search engines, site monitors, etc.). In my case, it means that some folders are erroneously excluded from search results on our intranet.
This is a Plone bug, not a CMF or Zope problem. A zope folder, created in the zmi in the root folder, and a CMF folder, created in a plain CMF site, both return the correct "200 OK" response to a HEAD request.
A similar problem affects smart-folders (topics), save that they return a "405 Method Not Allowed" response.
The attachment shows the headers returned from various HEAD requests, and the corresponding tracebacks.
This problem affects Plone 2.0.5 on Zope 2.7.4, and Plone 2.1beta1 on Zope 2.7.4 and 2.8.
It may be related to Zope Issue 919 ( http://www.zope.org/Collectors/Zope/919), but, after some hacking in BaseRequest.py, I think not. Note that you will not see this problem if your plone site is behind a caching proxy, and you are not logged in (eg. on plone.org).
Change History
comment:2 Changed 7 years ago by tiran
Mostly fixed. Either Sid or Tesdal have to very one chance to the browser default code to make everything work. Reason: the HEAD() method of the folder should be called for HEAD requests.
Index: PloneTool.py =================================================================== --- PloneTool.py (revision 7563) +++ PloneTool.py (working copy) @@ -955,7 +955,7 @@
# its all very odd and WebDAV'y request = getattr(self, 'REQUEST', None) if request and request.has_key('REQUEST_METHOD'):
- if requestREQUEST_METHOD? not in ['GET', 'HEAD', 'POST']:
+ if requestREQUEST_METHOD? not in ['GET', 'POST']:
return obj, [requestREQUEST_METHOD?]
# Now back to normal
comment:3 Changed 7 years ago by Anonymous User
There appears to be a typo in the last response. The second sentence doesn't parse: "Either Sid or Tesdal have to very one chance to the browser default code to make everything work."
comment:4 Changed 7 years ago by tiran
uhm ... damn :) One should never type while beeing tired and thinking about another issue.
Sidnei or Tesdal have to verify that my proposed change to the browserDefaul() method doesn't break it.
comment:5 Changed 7 years ago by krid
This patch doesn't work in Plone 2.0.5. What changed in 2.1 that makes it work? I looked for implementations of HEAD in 2.1, but that's not it. I'd like to backport the fix, since we're not ready for 2.1 yet.
I can hack a HEAD method into my product, but I'm guessing there's a better way...

I'm able to reproduce the bug in a unit test for ATCT. The special index_html ComputedAttribute does some evil things. It tries to acquire an object index_html from the parent folder. When an index_html can be acquired it returns 200 OK but if it can't aquire an index_html it returns NullResource.HEAD() -> 404.
-> Pdb().set_trace() (Pdb) n
-> self.davinit(REQUEST, RESPONSE) (Pdb) n
-> if hasattr(self, 'index_html'): (Pdb) n
-> if hasattr(self.index_html, 'HEAD'): (Pdb) n
-> return self.index_html.HEAD(REQUEST, RESPONSE) (Pdb) self.index_html <PythonScript at /testsite/Members/tiran/index_html> (Pdb) self.index_html.getPhysicalPath() (, 'testsite', 'Members', 'tiran', 'index_html') (Pdb) self.index_html.aq_inner.aq_parent <ATFolder at /testsite/Members/tiran> (Pdb) self.objectIds() .personal? (Pdb)