[Zope-CMF] A bit of a glitch with FTP PUT
seb bacon
seb@jamkit.com
Mon, 21 May 2001 12:39:55 +0100
* Tres Seaver <tseaver@novacoxmail.com> [010519 17:17]:
> Jonathan Corbet wrote:
> > I can work around this, but, to me, a proper solution is non-obvious. It
> > would be nice if FTP uploads that create items didn't circumvent the
> > workflow mechanism. Something for somebody's list, maybe...
>
> Improving our FTP and WebDAV integration story is pretty high on
> our list; we'll look at that this week.
I've been struggling with the WebDAV, myself. I mentioned last week
that one problem is that CookieCrumbler does redirection when
Unauthorized is raised, which breaks WebDAV. FWIW, although it's not
exactly a watertight solution, I've found the attached works with all
the clients I've tested it on. And I can't think of any other way
round it, unfortunately.
The next problem is that uploading Files fails. I think it's because
there's no fallback for default, globbed-style mimetypes in the
_mime_type_registry hack in PortalFolder: for example, the
NullResource PUT factory ends up trying to create an
application/octet-stream file as a normal File object, and of course
fails. I fixed it with a cheesey hack, because I know you've got
this in mind for a TTW, fully configurable solution. Any idea when
you might be looking at this - it'd be pretty useful - please :)
many thanks,
seb
*** /tmp/CookieCrumbler.py Mon May 21 11:29:28 2001
--- /tmp/CookieCrumbler.py13600WQ Mon May 21 11:29:28 2001
***************
*** 11,16 ****
--- 11,17 ----
from Globals import HTMLFile
from zLOG import LOG, ERROR
import sys
+ import string
# Constants.
ATTEMPT_NONE = 0
***************
*** 113,124 ****
return ATTEMPT_CONT
return ATTEMPT_NONE
def __call__(self, container, req):
'''The __before_publishing_traverse__ hook.'''
resp = self.REQUEST['RESPONSE']
attempt = self.modifyRequest(req, resp)
if self.auto_login_page:
! if not req.get('disable_cookie_login__', 0):
if (attempt == ATTEMPT_LOGIN or
not getattr(resp, '_auth', 0)):
page = getattr(container, self.auto_login_page, None)
--- 114,157 ----
return ATTEMPT_CONT
return ATTEMPT_NONE
+ def intercept_allowed(self,req):
+ '''Can we intercept the unauthorized exception?
+ WebDAV clients will get confused by redirect. Kludgy ways of
+ detecting them...'''
+
+ clients = ['neon/',
+ 'Microsoft Data Access Internet Publishing',
+ ]
+
+ allowed = 1
+
+ # explicit cookie
+ if req.get('disable_cookie_login__', 0):
+ allowed = 0
+
+ # unorthodox method (may be PROPFIND, OPTIONS, etc..)
+ method=req.get('REQUEST_METHOD', 'GET')
+ if not method in ('GET','POST'):
+ allowed = 0
+
+ # existence of known WebDAV client
+ ua = req.get_header('User-Agent','')
+ for c in clients:
+ if string.find(ua,c) > 0:
+ allowed = 0
+
+ # existence of webdav-only header
+ if req.get_header('Depth',None) is not None:
+ allowed = 0
+
+ return allowed
+
def __call__(self, container, req):
'''The __before_publishing_traverse__ hook.'''
resp = self.REQUEST['RESPONSE']
attempt = self.modifyRequest(req, resp)
if self.auto_login_page:
! if self.intercept_allowed(req):
if (attempt == ATTEMPT_LOGIN or
not getattr(resp, '_auth', 0)):
page = getattr(container, self.auto_login_page, None)