Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
88f4bed7
Commit
88f4bed7
authored
Mar 04, 1999
by
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup
parent
5edd9bec
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
801 additions
and
236 deletions
+801
-236
lib/python/webdav/Collection.py
lib/python/webdav/Collection.py
+11
-10
lib/python/webdav/NullResource.py
lib/python/webdav/NullResource.py
+9
-8
lib/python/webdav/Resource.py
lib/python/webdav/Resource.py
+19
-74
lib/python/webdav/__init__.py
lib/python/webdav/__init__.py
+5
-2
lib/python/webdav/client.py
lib/python/webdav/client.py
+587
-0
lib/python/webdav/common.py
lib/python/webdav/common.py
+132
-0
lib/python/webdav/xmlcmds.py
lib/python/webdav/xmlcmds.py
+36
-141
lib/python/webdav/xmltools.py
lib/python/webdav/xmltools.py
+2
-1
No files found.
lib/python/webdav/Collection.py
View file @
88f4bed7
...
@@ -85,10 +85,11 @@
...
@@ -85,10 +85,11 @@
"""WebDAV support - collection objects."""
"""WebDAV support - collection objects."""
__version__
=
'$Revision: 1.
1
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
import
sys
,
os
,
string
,
mimetypes
import
sys
,
os
,
string
from
Resource
import
Resource
from
Resource
import
Resource
from
common
import
urlfix
class
Collection
(
Resource
):
class
Collection
(
Resource
):
...
@@ -96,8 +97,9 @@ class Collection(Resource):
...
@@ -96,8 +97,9 @@ class Collection(Resource):
collection objects. It provides default implementations
collection objects. It provides default implementations
for all supported WebDAV HTTP methods. The behaviors of some
for all supported WebDAV HTTP methods. The behaviors of some
WebDAV HTTP methods for collections are slightly different
WebDAV HTTP methods for collections are slightly different
than those for non-collection resources.
than those for non-collection resources."""
"""
__dav_collection__
=
1
def
redirect_check
(
self
,
req
,
rsp
):
def
redirect_check
(
self
,
req
,
rsp
):
# By the spec, we are not supposed to accept /foo for a
# By the spec, we are not supposed to accept /foo for a
...
@@ -126,14 +128,13 @@ class Collection(Resource):
...
@@ -126,14 +128,13 @@ class Collection(Resource):
"""Delete a collection resource. For collection resources, DELETE
"""Delete a collection resource. For collection resources, DELETE
may return either 200 (OK) or 204 (No Content) to indicate total
may return either 200 (OK) or 204 (No Content) to indicate total
success, or may return 207 (Multistatus) to indicate partial
success, or may return 207 (Multistatus) to indicate partial
success."""
success.
Note that in Zope a DELETE never returns 207.
"""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
self
.
redirect_check
(
REQUEST
,
RESPONSE
)
self
.
redirect_check
(
REQUEST
,
RESPONSE
)
if
self
.
dav__is_acquired
():
url
=
urlfix
(
REQUEST
[
'URL'
],
'DELETE'
)
raise
'Not Found'
,
'The requested resource does not exist.'
name
=
filter
(
None
,
string
.
split
(
url
,
'/'
))[
-
1
]
path
=
filter
(
None
,
string
.
split
(
REQUEST
[
'PATH_INFO'
],
'/'
))
# TODO: add lock checking here
name
=
path
[
-
1
]
# TODO: add lock check here
self
.
aq_parent
.
_delObject
(
name
)
self
.
aq_parent
.
_delObject
(
name
)
RESPONSE
.
setStatus
(
204
)
RESPONSE
.
setStatus
(
204
)
return
RESPONSE
return
RESPONSE
lib/python/webdav/NullResource.py
View file @
88f4bed7
...
@@ -85,22 +85,25 @@
...
@@ -85,22 +85,25 @@
"""WebDAV support - null resource objects."""
"""WebDAV support - null resource objects."""
__version__
=
'$Revision: 1.
1
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
import
sys
,
os
,
string
,
mimetypes
import
sys
,
os
,
string
,
mimetypes
import
Acquisition
,
OFS
.
content_types
import
Acquisition
,
OFS
.
content_types
from
Resource
import
Resource
,
aq_base
from
common
import
absattr
,
aq_base
,
urlfix
from
Resource
import
Resource
from
Globals
import
Persistent
class
NullResource
(
Acquisition
.
Implicit
,
Resource
):
class
NullResource
(
Persistent
,
Acquisition
.
Implicit
,
Resource
):
"""Null resources are used to handle HTTP method calls on
"""Null resources are used to handle HTTP method calls on
objects which do not yet exist in the url namespace."""
objects which do not yet exist in the url namespace."""
_isNullResource
=
1
__dav_null__
=
1
def
__init__
(
self
,
parent
,
id
):
def
__init__
(
self
,
parent
,
id
):
self
.
id
=
id
self
.
id
=
id
self
.
__parent__
=
parent
self
.
__parent__
=
parent
self
.
__roles__
=
None
# fix this!!
self
.
__roles__
=
parent
.
__roles__
def
HEAD
(
self
,
REQUEST
,
RESPONSE
):
def
HEAD
(
self
,
REQUEST
,
RESPONSE
):
"""Retrieve resource information without a response message body."""
"""Retrieve resource information without a response message body."""
...
@@ -143,8 +146,7 @@ class NullResource(Acquisition.Implicit, Resource):
...
@@ -143,8 +146,7 @@ class NullResource(Acquisition.Implicit, Resource):
parent
=
self
.
__parent__
parent
=
self
.
__parent__
if
hasattr
(
aq_base
(
parent
),
self
.
id
):
if
hasattr
(
aq_base
(
parent
),
self
.
id
):
raise
'Method Not Allowed'
,
'The name %s is in use.'
%
self
.
id
raise
'Method Not Allowed'
,
'The name %s is in use.'
%
self
.
id
if
(
not
hasattr
(
parent
.
aq_base
,
'isAnObjectManager'
))
or
\
if
not
hasattr
(
parent
,
'__dav_collection__'
):
(
not
parent
.
isAnObjectManager
):
raise
'Forbidden'
,
'Unable to create collection resource.'
raise
'Forbidden'
,
'Unable to create collection resource.'
# This should probably do self.__class__(id, ...), except Folder
# This should probably do self.__class__(id, ...), except Folder
# doesn't currently have a constructor.
# doesn't currently have a constructor.
...
@@ -161,5 +163,4 @@ class NullResource(Acquisition.Implicit, Resource):
...
@@ -161,5 +163,4 @@ class NullResource(Acquisition.Implicit, Resource):
def
UNLOCK
(
self
):
def
UNLOCK
(
self
):
"""Remove a lock-null resource."""
"""Remove a lock-null resource."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
lib/python/webdav/Resource.py
View file @
88f4bed7
...
@@ -85,13 +85,12 @@
...
@@ -85,13 +85,12 @@
"""WebDAV support - resource objects."""
"""WebDAV support - resource objects."""
__version__
=
'$Revision: 1.
1
$'
[
11
:
-
2
]
__version__
=
'$Revision: 1.
2
$'
[
11
:
-
2
]
import
sys
,
os
,
string
,
time
import
sys
,
os
,
string
,
time
import
mimetypes
,
xmlcmds
import
mimetypes
,
xmlcmds
from
common
import
absattr
,
aq_base
zpns
=
'http://www.zope.org/propertysets/default/'
from
common
import
urlfix
,
rfc1123_date
class
Resource
:
class
Resource
:
...
@@ -101,13 +100,12 @@ class Resource:
...
@@ -101,13 +100,12 @@ class Resource:
such as PUT should be overridden to ensure correct behavior in
such as PUT should be overridden to ensure correct behavior in
the context of the object type."""
the context of the object type."""
__dav_resource__
=
1
__http_methods__
=
(
'GET'
,
'HEAD'
,
'POST'
,
'PUT'
,
'DELETE'
,
'OPTIONS'
,
__http_methods__
=
(
'GET'
,
'HEAD'
,
'POST'
,
'PUT'
,
'DELETE'
,
'OPTIONS'
,
'TRACE'
,
'PROPFIND'
,
'PROPPATCH'
,
'MKCOL'
,
'COPY'
,
'TRACE'
,
'PROPFIND'
,
'PROPPATCH'
,
'MKCOL'
,
'COPY'
,
'MOVE'
,
'MOVE'
,
)
)
__dav_resource__
=
1
def
init_headers
(
self
,
r
):
def
init_headers
(
self
,
r
):
# Init expected HTTP 1.1 / WebDAV headers which are not
# Init expected HTTP 1.1 / WebDAV headers which are not
# currently set by the response object automagically.
# currently set by the response object automagically.
...
@@ -130,35 +128,16 @@ class Resource:
...
@@ -130,35 +128,16 @@ class Resource:
lock
=
Lock
(
'xxxx'
,
'xxxx'
)
lock
=
Lock
(
'xxxx'
,
'xxxx'
)
return
self
.
dav__locks
+
(
lock
,)
return
self
.
dav__locks
+
(
lock
,)
def
dav__is_acquired
(
self
,
ob
=
None
):
# Return true if this object is not a direct
# subobject of its aq_parent object.
if
ob
is
None
:
ob
=
self
if
not
hasattr
(
ob
,
'aq_parent'
):
return
0
if
hasattr
(
aq_base
(
ob
.
aq_parent
),
absattr
(
ob
.
id
)):
return
0
if
hasattr
(
aq_base
(
ob
),
'isTopLevelPrincipiaApplicationObject'
):
return
0
return
1
# WebDAV class 1 support
# WebDAV class 1 support
def
HEAD
(
self
,
REQUEST
,
RESPONSE
):
def
HEAD
(
self
,
REQUEST
,
RESPONSE
):
"""Retrieve resource information without a response message
"""Retrieve resource information without a response body."""
body. It would be great if we had a standard way to ask an
arbitrary object for its headers -- that would allow the
default HEAD implementation to handle most needs."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
"""Replace the GET response entity of an existing resource.
"""Replace the GET response entity of an existing resource.
Because this is often object-dependent, objects which handle
Because this is often object-dependent, objects which handle
PUT should override the default PUT implementation with an
PUT should override the default PUT implementation with an
object-specific implementation. By default, PUT requests
object-specific implementation. By default, PUT requests
...
@@ -176,11 +155,11 @@ class Resource:
...
@@ -176,11 +155,11 @@ class Resource:
def
TRACE
(
self
,
REQUEST
,
RESPONSE
):
def
TRACE
(
self
,
REQUEST
,
RESPONSE
):
"""Return the HTTP message received back to the client as the
"""Return the HTTP message received back to the client as the
entity-body of a 200 (OK) response. This will often act
ually
entity-body of a 200 (OK) response. This will often us
ually
be intercepted by the web server in use. If not, the TRACE
be intercepted by the web server in use. If not, the TRACE
request will fail with a 405 (Method Not Allowed), since it
request will fail with a 405 (Method Not Allowed), since it
is not often possible to reproduce the HTTP request verbatim
is not often possible to reproduce the HTTP request verbatim
from within the Zope environment."""
from within the Zope environment."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
raise
'Method Not Allowed'
,
'Method not supported for this resource.'
...
@@ -188,12 +167,8 @@ class Resource:
...
@@ -188,12 +167,8 @@ class Resource:
"""Delete a resource. For non-collection resources, DELETE may
"""Delete a resource. For non-collection resources, DELETE may
return either 200 or 204 (No Content) to indicate success."""
return either 200 or 204 (No Content) to indicate success."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
if
self
.
dav__is_acquired
():
url
=
urlfix
(
REQUEST
[
'URL'
],
'DELETE'
)
raise
'Not Found'
,
'The requested resource does not exist.'
name
=
filter
(
None
,
string
.
split
(
url
,
'/'
))[
-
1
]
path
=
filter
(
None
,
string
.
split
(
REQUEST
[
'URL'
],
'/'
))
if
path
[
-
1
]
==
'DELETE'
:
del
path
[
-
1
]
name
=
path
[
-
1
]
# TODO: add lock checking here
# TODO: add lock checking here
self
.
aq_parent
.
_delObject
(
name
)
self
.
aq_parent
.
_delObject
(
name
)
RESPONSE
.
setStatus
(
204
)
RESPONSE
.
setStatus
(
204
)
...
@@ -202,11 +177,9 @@ class Resource:
...
@@ -202,11 +177,9 @@ class Resource:
def
PROPFIND
(
self
,
REQUEST
,
RESPONSE
):
def
PROPFIND
(
self
,
REQUEST
,
RESPONSE
):
"""Retrieve properties defined on the resource."""
"""Retrieve properties defined on the resource."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
if
self
.
dav__is_acquired
():
try
:
cmd
=
xmlcmds
.
PropFind
(
REQUEST
)
raise
'Not Found'
,
'The requested resource does not exist.'
try
:
request
=
xmlcmds
.
PropFind
(
REQUEST
)
except
:
raise
'Bad Request'
,
'Invalid xml request.'
except
:
raise
'Bad Request'
,
'Invalid xml request.'
result
=
request
.
apply
(
self
)
result
=
cmd
.
apply
(
self
)
RESPONSE
.
setStatus
(
207
)
RESPONSE
.
setStatus
(
207
)
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/xml; charset="utf-8"'
)
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/xml; charset="utf-8"'
)
RESPONSE
.
setBody
(
result
)
RESPONSE
.
setBody
(
result
)
...
@@ -215,15 +188,13 @@ class Resource:
...
@@ -215,15 +188,13 @@ class Resource:
def
PROPPATCH
(
self
,
REQUEST
,
RESPONSE
):
def
PROPPATCH
(
self
,
REQUEST
,
RESPONSE
):
"""Set and/or remove properties defined on the resource."""
"""Set and/or remove properties defined on the resource."""
self
.
init_headers
(
RESPONSE
)
self
.
init_headers
(
RESPONSE
)
if
self
.
dav__is_acquired
():
raise
'Not Found'
,
'The requested resource does not exist.'
if
not
hasattr
(
self
,
'__propsets__'
):
if
not
hasattr
(
self
,
'__propsets__'
):
raise
'Method Not Allowed'
,
(
raise
'Method Not Allowed'
,
(
'Method not supported for this resource.'
)
'Method not supported for this resource.'
)
# TODO: add lock checking here
# TODO: add lock checking here
try
:
request
=
xmlcmds
.
PropPatch
(
REQUEST
)
try
:
cmd
=
xmlcmds
.
PropPatch
(
REQUEST
)
except
:
raise
'Bad Request'
,
'Invalid xml request.'
except
:
raise
'Bad Request'
,
'Invalid xml request.'
result
=
request
.
apply
(
self
)
result
=
cmd
.
apply
(
self
)
RESPONSE
.
setStatus
(
207
)
RESPONSE
.
setStatus
(
207
)
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/xml; charset="utf-8"'
)
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/xml; charset="utf-8"'
)
RESPONSE
.
setBody
(
result
)
RESPONSE
.
setBody
(
result
)
...
@@ -245,8 +216,6 @@ class Resource:
...
@@ -245,8 +216,6 @@ class Resource:
if
not
hasattr
(
aq_base
(
self
),
'cb_isCopyable'
)
or
\
if
not
hasattr
(
aq_base
(
self
),
'cb_isCopyable'
)
or
\
not
self
.
cb_isCopyable
():
not
self
.
cb_isCopyable
():
raise
'Method Not Allowed'
,
'This object may not be copied.'
raise
'Method Not Allowed'
,
'This object may not be copied.'
if
self
.
dav__is_acquired
():
raise
'Not Found'
,
'The requested resource does not exist.'
depth
=
REQUEST
.
get_header
(
'Depth'
,
'infinity'
)
depth
=
REQUEST
.
get_header
(
'Depth'
,
'infinity'
)
dest
=
REQUEST
.
get_header
(
'Destination'
,
''
)
dest
=
REQUEST
.
get_header
(
'Destination'
,
''
)
if
not
dest
:
raise
'Bad Request'
,
'No destination given'
if
not
dest
:
raise
'Bad Request'
,
'No destination given'
...
@@ -261,7 +230,7 @@ class Resource:
...
@@ -261,7 +230,7 @@ class Resource:
except
'Not Found'
:
except
'Not Found'
:
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
except
:
raise
sys
.
exc_type
,
sys
.
exc_value
except
:
raise
sys
.
exc_type
,
sys
.
exc_value
if
hasattr
(
parent
,
'_
isNullResource
'
):
if
hasattr
(
parent
,
'_
_dav_null__
'
):
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
if
self
.
dav__is_acquired
(
parent
):
if
self
.
dav__is_acquired
(
parent
):
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
...
@@ -296,8 +265,6 @@ class Resource:
...
@@ -296,8 +265,6 @@ class Resource:
if
not
hasattr
(
aq_base
(
self
),
'cb_isMoveable'
)
or
\
if
not
hasattr
(
aq_base
(
self
),
'cb_isMoveable'
)
or
\
not
self
.
cb_isMoveable
():
not
self
.
cb_isMoveable
():
raise
'Method Not Allowed'
,
'This object may not be moved.'
raise
'Method Not Allowed'
,
'This object may not be moved.'
if
self
.
dav__is_acquired
():
raise
'Not Found'
,
'The requested resource does not exist.'
dest
=
REQUEST
.
get_header
(
'Destination'
,
''
)
dest
=
REQUEST
.
get_header
(
'Destination'
,
''
)
if
not
dest
:
raise
'Bad Request'
,
'No destination given'
if
not
dest
:
raise
'Bad Request'
,
'No destination given'
flag
=
REQUEST
.
get_header
(
'Overwrite'
,
'F'
)
flag
=
REQUEST
.
get_header
(
'Overwrite'
,
'F'
)
...
@@ -311,7 +278,7 @@ class Resource:
...
@@ -311,7 +278,7 @@ class Resource:
except
'Not Found'
:
except
'Not Found'
:
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
except
:
raise
sys
.
exc_type
,
sys
.
exc_value
except
:
raise
sys
.
exc_type
,
sys
.
exc_value
if
hasattr
(
parent
,
'_
isNullResource
'
):
if
hasattr
(
parent
,
'_
_dav_null__
'
):
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
if
self
.
dav__is_acquired
(
parent
):
if
self
.
dav__is_acquired
(
parent
):
raise
'Conflict'
,
'The resource %s must exist.'
%
path
raise
'Conflict'
,
'The resource %s must exist.'
%
path
...
@@ -377,25 +344,3 @@ class Lock:
...
@@ -377,25 +344,3 @@ class Lock:
'<d:href>opaquelocktoken:%(token)s</d:href>
\
n
'
\
'<d:href>opaquelocktoken:%(token)s</d:href>
\
n
'
\
'</d:locktoken>
\
n
'
\
'</d:locktoken>
\
n
'
\
'</d:activelock>
\
n
'
%
self
.
__dict__
'</d:activelock>
\
n
'
%
self
.
__dict__
def
absattr
(
attr
):
if
callable
(
attr
):
return
attr
()
return
attr
def
aq_base
(
ob
):
if
hasattr
(
ob
,
'aq_base'
):
return
ob
.
aq_base
return
ob
def
rfc1123_date
(
ts
=
None
):
# Return an RFC 1123 format date string, required for
# use in HTTP Date headers per the HTTP 1.1 spec.
if
ts
is
None
:
ts
=
time
.
time
()
ts
=
time
.
asctime
(
time
.
gmtime
(
ts
))
ts
=
string
.
split
(
ts
)
return
'%s, %s %s %s %s GMT'
%
(
ts
[
0
],
ts
[
2
],
ts
[
1
],
ts
[
3
],
ts
[
4
])
lib/python/webdav/__init__.py
View file @
88f4bed7
...
@@ -84,7 +84,10 @@
...
@@ -84,7 +84,10 @@
##############################################################################
##############################################################################
"""The webdav package provides WebDAV class 1 functionality within
"""The webdav package provides WebDAV class 1 functionality within
the Zope environment. Based on
RFC 2518."""
the Zope environment. Based on
:
__version__
=
'$Revision: 1.2 $'
[
11
:
-
2
]
[WebDAV] Y. Y. Goland, E. J. Whitehead, Jr., A. Faizi, S. R. Carter, D.
Jensen, "HTTP Extensions for Distributed Authoring - WebDAV." RFC 2518.
Microsoft, U.C. Irvine, Netscape, Novell. February, 1999."""
__version__
=
'$Revision: 1.3 $'
[
11
:
-
2
]
lib/python/webdav/client.py
0 → 100644
View file @
88f4bed7
This diff is collapsed.
Click to expand it.
lib/python/webdav/common.py
0 → 100644
View file @
88f4bed7
##############################################################################
#
# Zope Public License (ZPL) Version 0.9.4
# ---------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions in source code must retain the above
# copyright notice, this list of conditions, and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions, and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Any use, including use of the Zope software to operate a
# website, must either comply with the terms described below
# under "Attribution" or alternatively secure a separate
# license from Digital Creations.
#
# 4. All advertising materials, documentation, or technical papers
# mentioning features derived from or use of this software must
# display the following acknowledgement:
#
# "This product includes software developed by Digital
# Creations for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# 5. Names associated with Zope or Digital Creations must not be
# used to endorse or promote products derived from this
# software without prior written permission from Digital
# Creations.
#
# 6. Redistributions of any form whatsoever must retain the
# following acknowledgment:
#
# "This product includes software developed by Digital
# Creations for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# 7. Modifications are encouraged but must be packaged separately
# as patches to official Zope releases. Distributions that do
# not clearly separate the patches from the original work must
# be clearly labeled as unofficial distributions.
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND
# ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
# SHALL DIGITAL CREATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#
# Attribution
#
# Individuals or organizations using this software as a web site
# must provide attribution by placing the accompanying "button"
# and a link to the accompanying "credits page" on the website's
# main entry point. In cases where this placement of
# attribution is not feasible, a separate arrangment must be
# concluded with Digital Creations. Those using the software
# for purposes other than web sites must provide a corresponding
# attribution in locations that include a copyright using a
# manner best suited to the application environment.
#
# This software consists of contributions made by Digital
# Creations and many individuals on behalf of Digital Creations.
# Specific attributions are listed in the accompanying credits
# file.
#
##############################################################################
"""Commonly used functions for WebDAV support modules."""
__version__
=
'$Revision: 1.1 $'
[
11
:
-
2
]
import
string
,
time
def
absattr
(
attr
):
if
callable
(
attr
):
return
attr
()
return
attr
def
aq_base
(
ob
):
if
hasattr
(
ob
,
'aq_base'
):
return
ob
.
aq_base
return
ob
def
urlfix
(
url
,
s
):
n
=
len
(
s
)
if
url
[
-
n
:]
==
s
:
url
=
url
[:
-
n
]
if
len
(
url
)
>
1
and
url
[
-
1
]
==
'/'
:
url
=
url
[:
-
1
]
return
url
def
is_acquired
(
ob
):
# Return true if this object is not a direct
# subobject of its aq_parent object.
if
not
hasattr
(
ob
,
'aq_parent'
):
return
0
if
hasattr
(
aq_base
(
ob
.
aq_parent
),
absattr
(
ob
.
id
)):
return
0
if
hasattr
(
aq_base
(
ob
),
'isTopLevelPrincipiaApplicationObject'
):
return
0
return
1
def
rfc1123_date
(
ts
=
None
):
# Return an RFC 1123 format date string, required for
# use in HTTP Date headers per the HTTP 1.1 spec.
if
ts
is
None
:
ts
=
time
.
time
()
ts
=
time
.
asctime
(
time
.
gmtime
(
ts
))
ts
=
string
.
split
(
ts
)
return
'%s, %s %s %s %s GMT'
%
(
ts
[
0
],
ts
[
2
],
ts
[
1
],
ts
[
3
],
ts
[
4
])
lib/python/webdav/xmlcmds.py
View file @
88f4bed7
...
@@ -83,24 +83,20 @@
...
@@ -83,24 +83,20 @@
#
#
##############################################################################
##############################################################################
"""WebDAV XML request objects."""
"""WebDAV xml request objects."""
__version__
=
'$Revision: 1.1 $'
[
11
:
-
2
]
import
sys
,
os
,
string
,
xmllib
__version__
=
'$Revision: 1.2 $'
[
11
:
-
2
]
import
sys
,
os
,
string
from
common
import
absattr
,
aq_base
,
urlfix
from
xmltools
import
XmlParser
from
xmltools
import
XmlParser
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
zope_id
=
'http://www.zope.org/propsets/default'
dav_id
=
'DAV:'
def
compact
(
self
,
data
):
root
=
XmlParser
().
parse
(
data
)
class
PropFind
:
class
PropFind
:
"""Model a PROPFIND request."""
def
__init__
(
self
,
request
):
def
__init__
(
self
,
request
):
self
.
request
=
request
self
.
request
=
request
data
=
request
.
get
(
'BODY'
,
''
)
data
=
request
.
get
(
'BODY'
,
''
)
...
@@ -110,17 +106,17 @@ class PropFind:
...
@@ -110,17 +106,17 @@ class PropFind:
self
.
propnames
=
[]
self
.
propnames
=
[]
self
.
parse
(
data
)
self
.
parse
(
data
)
def
parse
(
self
,
data
):
def
parse
(
self
,
data
,
dav
=
'DAV:'
):
if
not
data
:
return
if
not
data
:
return
root
=
XmlParser
().
parse
(
data
)
root
=
XmlParser
().
parse
(
data
)
e
=
root
.
elements
(
'propfind'
,
ns
=
dav
_id
)[
0
]
e
=
root
.
elements
(
'propfind'
,
ns
=
dav
)[
0
]
if
e
.
elements
(
'allprop'
,
ns
=
dav
_id
):
if
e
.
elements
(
'allprop'
,
ns
=
dav
):
self
.
allprop
=
1
self
.
allprop
=
1
return
return
if
e
.
elements
(
'propname'
,
ns
=
dav
_id
):
if
e
.
elements
(
'propname'
,
ns
=
dav
):
self
.
propname
=
1
self
.
propname
=
1
return
return
prop
=
e
.
elements
(
'prop'
,
ns
=
dav
_id
)[
0
]
prop
=
e
.
elements
(
'prop'
,
ns
=
dav
)[
0
]
for
val
in
prop
.
elements
():
for
val
in
prop
.
elements
():
self
.
propnames
.
append
((
val
.
name
(),
val
.
namespace
()))
self
.
propnames
.
append
((
val
.
name
(),
val
.
namespace
()))
return
return
...
@@ -129,19 +125,15 @@ class PropFind:
...
@@ -129,19 +125,15 @@ class PropFind:
if
result
is
None
:
if
result
is
None
:
result
=
StringIO
()
result
=
StringIO
()
depth
=
self
.
depth
depth
=
self
.
depth
url
=
self
.
request
[
'URL'
]
url
=
urlfix
(
self
.
request
[
'URL'
],
'PROPFIND'
)
if
url
[
-
9
:]
==
'/PROPFIND'
:
url
=
url
[:
-
9
]
result
.
write
(
'<?xml version="1.0" encoding="utf-8"?>
\
n
'
\
result
.
write
(
'<?xml version="1.0" encoding="utf-8"?>
\
n
'
\
'<d:multistatus xmlns:d="DAV:" '
\
'<d:multistatus xmlns:d="DAV:">
\
n
'
'xmlns:z="%s">
\
n
'
%
zope_id
)
iscol
=
hasattr
(
aq_base
(
obj
),
'isAnObjectManager'
)
and
\
iscol
=
hasattr
(
aq_base
(
obj
),
'isAnObjectManager'
)
and
\
obj
.
isAnObjectManager
obj
.
isAnObjectManager
if
iscol
and
url
[
-
1
]
!=
'/'
:
url
=
url
+
'/'
if
iscol
and
url
[
-
1
]
!=
'/'
:
url
=
url
+
'/'
result
.
write
(
'<d:response>
\
n
<d:href>%s</d:href>
\
n
'
%
url
)
result
.
write
(
'<d:response>
\
n
<d:href>%s</d:href>
\
n
'
%
url
)
if
hasattr
(
obj
,
'__propsets__'
):
if
hasattr
(
obj
,
'__propsets__'
):
for
ps
in
obj
.
propertysheets
.
item
s
():
for
ps
in
obj
.
propertysheets
.
value
s
():
if
hasattr
(
aq_base
(
ps
),
'dav__propstat'
):
if
hasattr
(
aq_base
(
ps
),
'dav__propstat'
):
stat
=
ps
.
dav__propstat
(
self
.
allprop
,
self
.
propnames
)
stat
=
ps
.
dav__propstat
(
self
.
allprop
,
self
.
propnames
)
result
.
write
(
stat
)
result
.
write
(
stat
)
...
@@ -160,18 +152,19 @@ class PropFind:
...
@@ -160,18 +152,19 @@ class PropFind:
class
PropPatch
:
class
PropPatch
:
"""Model a PROPPATCH request."""
def
__init__
(
self
,
request
):
def
__init__
(
self
,
request
):
self
.
request
=
request
self
.
request
=
request
data
=
request
.
get
(
'BODY'
,
''
)
data
=
request
.
get
(
'BODY'
,
''
)
self
.
values
=
[]
self
.
values
=
[]
self
.
parse
(
data
)
self
.
parse
(
data
)
def
parse
(
self
,
data
):
def
parse
(
self
,
data
,
dav
=
'DAV:'
):
root
=
XmlParser
().
parse
(
data
)
root
=
XmlParser
().
parse
(
data
)
e
=
root
.
elements
(
'propertyupdate'
,
ns
=
dav
_id
)[
0
]
e
=
root
.
elements
(
'propertyupdate'
,
ns
=
dav
)[
0
]
for
ob
in
e
.
elements
():
for
ob
in
e
.
elements
():
if
ob
.
name
()
==
'set'
and
ob
.
namespace
()
==
dav
_id
:
if
ob
.
name
()
==
'set'
and
ob
.
namespace
()
==
dav
:
prop
=
ob
.
elements
(
'prop'
,
ns
=
dav
_id
)[
0
]
prop
=
ob
.
elements
(
'prop'
,
ns
=
dav
)[
0
]
for
val
in
prop
.
elements
():
for
val
in
prop
.
elements
():
# We have to ensure that all tag attrs (including
# We have to ensure that all tag attrs (including
# an xmlns attr for all xml namespaces used by the
# an xmlns attr for all xml namespaces used by the
...
@@ -183,25 +176,23 @@ class PropPatch:
...
@@ -183,25 +176,23 @@ class PropPatch:
md
=
{
'attrs'
:
attrs
,
'nsid'
:
val
.
__nskey__
}
md
=
{
'attrs'
:
attrs
,
'nsid'
:
val
.
__nskey__
}
item
=
(
val
.
name
(),
val
.
namespace
(),
val
.
strval
(),
md
)
item
=
(
val
.
name
(),
val
.
namespace
(),
val
.
strval
(),
md
)
self
.
values
.
append
(
item
)
self
.
values
.
append
(
item
)
if
ob
.
name
()
==
'remove'
and
ob
.
namespace
()
==
dav
_id
:
if
ob
.
name
()
==
'remove'
and
ob
.
namespace
()
==
dav
:
prop
=
ob
.
elements
(
'prop'
,
ns
=
dav
_id
)[
0
]
prop
=
ob
.
elements
(
'prop'
,
ns
=
dav
)[
0
]
for
val
in
prop
.
elements
():
for
val
in
prop
.
elements
():
item
=
(
val
.
name
(),
val
.
namespace
())
item
=
(
val
.
name
(),
val
.
namespace
())
self
.
values
.
append
(
item
)
self
.
values
.
append
(
item
)
def
apply
(
self
,
obj
):
def
apply
(
self
,
obj
):
url
=
self
.
request
[
'URL'
]
url
=
urlfix
(
self
.
request
[
'URL'
],
'PROPPATCH'
)
if
url
[
-
10
:]
==
'/PROPPATCH'
:
url
=
url
[:
-
10
]
if
hasattr
(
aq_base
(
obj
),
'isAnObjectManager'
)
and
\
if
hasattr
(
aq_base
(
obj
),
'isAnObjectManager'
)
and
\
obj
.
isAnObjectManager
and
url
[
-
1
]
!=
'/'
:
obj
.
isAnObjectManager
and
url
[
-
1
]
!=
'/'
:
url
=
url
+
'/'
url
=
url
+
'/'
result
=
StringIO
()
result
=
StringIO
()
errors
=
[]
errors
=
[]
result
.
write
(
'<?xml version="1.0" encoding="utf-8"?>
\
n
'
\
result
.
write
(
'<?xml version="1.0" encoding="utf-8"?>
\
n
'
\
'<d:multistatus xmlns:d="DAV:"
xmlns:z="%s"
>
\
n
'
\
'<d:multistatus xmlns:d="DAV:">
\
n
'
\
'<d:response>
\
n
'
\
'<d:response>
\
n
'
\
'<d:href>%s</d:href>
\
n
'
%
(
zope_id
,
url
)
)
'<d:href>%s</d:href>
\
n
'
%
url
)
propsets
=
obj
.
propertysheets
propsets
=
obj
.
propertysheets
for
value
in
self
.
values
:
for
value
in
self
.
values
:
status
=
'200 OK'
status
=
'200 OK'
...
@@ -210,7 +201,7 @@ class PropPatch:
...
@@ -210,7 +201,7 @@ class PropPatch:
propset
=
propsets
.
get
(
ns
,
None
)
propset
=
propsets
.
get
(
ns
,
None
)
if
propset
is
None
:
if
propset
is
None
:
obj
.
propertysheets
.
manage_addPropertySheet
(
''
,
ns
)
obj
.
propertysheets
.
manage_addPropertySheet
(
''
,
ns
)
propsets
=
obj
.
propertysheets
.
item
s
()
propsets
=
obj
.
propertysheets
.
value
s
()
propset
=
propsets
.
get
(
ns
)
propset
=
propsets
.
get
(
ns
)
if
propset
.
hasProperty
(
name
):
if
propset
.
hasProperty
(
name
):
try
:
propset
.
_updateProperty
(
name
,
val
,
meta
=
md
)
try
:
propset
.
_updateProperty
(
name
,
val
,
meta
=
md
)
...
@@ -234,9 +225,9 @@ class PropPatch:
...
@@ -234,9 +225,9 @@ class PropPatch:
errors
.
append
(
'%s cannot be deleted.'
%
name
)
errors
.
append
(
'%s cannot be deleted.'
%
name
)
status
=
'409 Conflict'
status
=
'409 Conflict'
if
result
!=
'200 OK'
:
abort
=
1
if
result
!=
'200 OK'
:
abort
=
1
result
.
write
(
'<d:propstat xmlns:
ps
="%s">
\
n
'
\
result
.
write
(
'<d:propstat xmlns:
n
="%s">
\
n
'
\
' <d:prop>
\
n
'
\
' <d:prop>
\
n
'
\
' <
ps
:%s/>
\
n
'
\
' <
n
:%s/>
\
n
'
\
' </d:prop>
\
n
'
\
' </d:prop>
\
n
'
\
' <d:status>HTTP/1.1 %s</d:status>
\
n
'
\
' <d:status>HTTP/1.1 %s</d:status>
\
n
'
\
'</d:propstat>
\
n
'
%
(
ns
,
name
,
status
))
'</d:propstat>
\
n
'
%
(
ns
,
name
,
status
))
...
@@ -256,117 +247,21 @@ class PropPatch:
...
@@ -256,117 +247,21 @@ class PropPatch:
class
Lock
:
class
Lock
:
def
__init__
(
self
,
data
):
"""Model a LOCK request."""
def
__init__
(
self
,
request
):
self
.
request
=
request
data
=
request
.
get
(
'BODY'
,
''
)
self
.
scope
=
'exclusive'
self
.
scope
=
'exclusive'
self
.
type
=
'write'
self
.
type
=
'write'
self
.
owner
=
''
self
.
owner
=
''
self
.
parse
(
data
)
self
.
parse
(
data
)
def
parse
(
self
,
data
):
def
parse
(
self
,
data
,
dav
=
'DAV:'
):
root
=
XmlParser
().
parse
(
data
)
root
=
XmlParser
().
parse
(
data
)
info
=
root
.
elements
(
'lockinfo'
,
ns
=
dav
_id
)[
0
]
info
=
root
.
elements
(
'lockinfo'
,
ns
=
dav
)[
0
]
ls
=
info
.
elements
(
'lockscope'
,
ns
=
dav
_id
)[
0
]
ls
=
info
.
elements
(
'lockscope'
,
ns
=
dav
)[
0
]
self
.
scope
=
ls
.
elements
()[
0
].
name
()
self
.
scope
=
ls
.
elements
()[
0
].
name
()
lt
=
info
.
elements
(
'locktype'
,
ns
=
dav
_id
)[
0
]
lt
=
info
.
elements
(
'locktype'
,
ns
=
dav
)[
0
]
self
.
type
=
lt
.
elements
()[
0
].
name
()
self
.
type
=
lt
.
elements
()[
0
].
name
()
lo
=
info
.
elements
(
'owner'
,
ns
=
dav
_id
)
lo
=
info
.
elements
(
'owner'
,
ns
=
dav
)
if
lo
:
self
.
owner
=
lo
[
0
].
toxml
()
if
lo
:
self
.
owner
=
lo
[
0
].
toxml
()
def
absattr
(
attr
):
if
callable
(
attr
):
return
attr
()
return
attr
def
aq_base
(
ob
):
if
hasattr
(
ob
,
'aq_base'
):
return
ob
.
aq_base
return
ob
propfind_xml
=
"""<?xml version="1.0" encoding="utf-8" ?>
<d:propfind xmlns:d="DAV:">
<d:prop xmlns:z="http://www.zope.org/propsets/default">
<z:title/>
<z:author/>
<z:content_type/>
</d:prop>
</d:propfind>
"""
rem_xml
=
"""<?xml version="1.0" encoding="utf-8"?>
<d:propertyupdate xmlns:d="DAV:"
xmlns:z="http://www.zope.org/propsets/default">
<d:remove>
<d:prop>
<z:author/>
<z:title/>
</d:prop>
</d:remove>
</d:propertyupdate>
"""
proppatch_xml
=
"""<?xml version="1.0" encoding="utf-8" ?>
<d:propertyupdate xmlns:d="DAV:"
xmlns:z="http://www.w3.com/standards/z39.50/">
<d:set>
<d:prop>
<z:authors>
<z:Author>Jim Whitehead</z:Author>
<z:Author>Roy Fielding</z:Author>
</z:authors>
</d:prop>
</d:set>
<d:remove>
<d:prop><z:Copyright-Owner/></d:prop>
</d:remove>
</d:propertyupdate>
"""
lock_xml
=
"""<?xml version="1.0" encoding="utf-8" ?>
<D:lockinfo xmlns:D='DAV:'>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
<D:owner>
<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
</D:owner>
</D:lockinfo>
"""
multistatus_xml
=
"""<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response xmlns:z="http://www.zope.org/dav/">
<href>http://www.foo.bar/container/</href>
<propstat>
<prop xmlns:R="http://www.foo.bar/boxschema/">
<R:bigbox z:type="int"/>
<R:author/>
<creationdate/>
<displayname/>
<resourcetype/>
<supportedlock/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://www.foo.bar/container/front.html</href>
<propstat>
<prop xmlns:R="http://www.foo.bar/boxschema/">
<R:bigbox/>
<creationdate/>
<displayname/>
<getcontentlength/>
<getcontenttype/>
<getetag/>
<getlastmodified/>
<resourcetype/>
<supportedlock/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
"""
lib/python/webdav/xmltools.py
View file @
88f4bed7
...
@@ -84,7 +84,8 @@
...
@@ -84,7 +84,8 @@
##############################################################################
##############################################################################
"""WebDAV XML parsing tools."""
"""WebDAV XML parsing tools."""
__version__
=
'$Revision: 1.1 $'
[
11
:
-
2
]
__version__
=
'$Revision: 1.2 $'
[
11
:
-
2
]
import
sys
,
os
,
string
,
xmllib
import
sys
,
os
,
string
,
xmllib
from
Acquisition
import
Implicit
from
Acquisition
import
Implicit
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment