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
7abca36a
Commit
7abca36a
authored
Apr 30, 2006
by
Lennart Regebro
Browse files
Options
Browse Files
Download
Plain Diff
Complete WSGI support rewrite.
parents
c4cceb84
9c8f4d5e
e32a284a
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
381 additions
and
145 deletions
+381
-145
doc/CHANGES.txt
doc/CHANGES.txt
+11
-0
lib/python/OFS/Traversable.py
lib/python/OFS/Traversable.py
+34
-8
lib/python/Products/PageTemplates/Expressions.py
lib/python/Products/PageTemplates/Expressions.py
+39
-3
lib/python/ZPublisher/BaseRequest.py
lib/python/ZPublisher/BaseRequest.py
+219
-123
lib/python/ZPublisher/Publish.py
lib/python/ZPublisher/Publish.py
+0
-1
lib/python/ZServer/HTTPResponse.py
lib/python/ZServer/HTTPResponse.py
+9
-0
lib/python/ZServer/HTTPServer.py
lib/python/ZServer/HTTPServer.py
+42
-0
lib/python/ZServer/PubCore/ZServerPublisher.py
lib/python/ZServer/PubCore/ZServerPublisher.py
+20
-9
lib/python/ZServer/component.xml
lib/python/ZServer/component.xml
+2
-0
lib/python/ZServer/datatypes.py
lib/python/ZServer/datatypes.py
+5
-1
No files found.
doc/CHANGES.txt
View file @
7abca36a
...
@@ -49,6 +49,17 @@ Zope Changes
...
@@ -49,6 +49,17 @@ Zope Changes
Features added
Features added
- The traversal has been refactored to take heed of Zope3s
IPublishTraverse adapter interfaces. The ZCML directives
five:traversable and five:defaultViewable are therefore no
longer needed, as everything now is five:traversable and
five:defaultViewable.
There was a bug in earlier versions of Five that allowed you
to do custom publishing traversal with ITraversable adapters.
This bug has been corrected. Anybody using ITraversable
adapters need to convert them to IPublishTraversal adapters.
- Testing.makerequest: Added an 'environ' argument so
- Testing.makerequest: Added an 'environ' argument so
clients can use mappings other than os.environ.
clients can use mappings other than os.environ.
...
...
lib/python/OFS/Traversable.py
View file @
7abca36a
...
@@ -25,9 +25,14 @@ from AccessControl.ZopeGuards import guarded_getattr
...
@@ -25,9 +25,14 @@ from AccessControl.ZopeGuards import guarded_getattr
from
Acquisition
import
Acquired
,
aq_inner
,
aq_parent
,
aq_base
from
Acquisition
import
Acquired
,
aq_inner
,
aq_parent
,
aq_base
from
zExceptions
import
NotFound
from
zExceptions
import
NotFound
from
ZODB.POSException
import
ConflictError
from
ZODB.POSException
import
ConflictError
from
zope.interface
import
implements
from
zope.interface
import
implements
,
Interface
from
interfaces
import
ITraversable
from
interfaces
import
ITraversable
from
zope.app.traversing.interfaces
import
ITraversable
as
IZope3Traversable
from
zope.component
import
queryMultiAdapter
from
zope.app.traversing.interfaces
import
TraversalError
from
zope.app.traversing.namespace
import
nsParse
from
zope.app.traversing.namespace
import
namespaceLookup
_marker
=
object
()
_marker
=
object
()
...
@@ -59,6 +64,7 @@ class Traversable:
...
@@ -59,6 +64,7 @@ class Traversable:
return
self
.
virtual_url_path
()
return
self
.
virtual_url_path
()
spp
=
self
.
getPhysicalPath
()
spp
=
self
.
getPhysicalPath
()
try
:
try
:
toUrl
=
self
.
REQUEST
.
physicalPathToURL
toUrl
=
self
.
REQUEST
.
physicalPathToURL
except
AttributeError
:
except
AttributeError
:
...
@@ -133,7 +139,6 @@ class Traversable:
...
@@ -133,7 +139,6 @@ class Traversable:
If true, then all of the objects along the path are validated with
If true, then all of the objects along the path are validated with
the security machinery. Usually invoked using restrictedTraverse().
the security machinery. Usually invoked using restrictedTraverse().
"""
"""
if
not
path
:
if
not
path
:
return
self
return
self
...
@@ -188,7 +193,19 @@ class Traversable:
...
@@ -188,7 +193,19 @@ class Traversable:
continue
continue
bobo_traverse
=
_getattr
(
obj
,
'__bobo_traverse__'
,
_none
)
bobo_traverse
=
_getattr
(
obj
,
'__bobo_traverse__'
,
_none
)
if
bobo_traverse
is
not
_none
:
if
name
and
name
[:
1
]
in
'@+'
:
# Process URI segment parameters.
ns
,
nm
=
nsParse
(
name
)
if
ns
:
try
:
next
=
namespaceLookup
(
ns
,
nm
,
obj
,
self
.
REQUEST
).
__of__
(
obj
)
if
restricted
and
not
securityManager
.
validate
(
obj
,
obj
,
name
,
next
):
raise
Unauthorized
,
name
except
TraversalError
:
raise
AttributeError
(
name
)
elif
bobo_traverse
is
not
_none
:
next
=
bobo_traverse
(
REQUEST
,
name
)
next
=
bobo_traverse
(
REQUEST
,
name
)
if
restricted
:
if
restricted
:
if
aq_base
(
next
)
is
not
next
:
if
aq_base
(
next
)
is
not
next
:
...
@@ -227,12 +244,21 @@ class Traversable:
...
@@ -227,12 +244,21 @@ class Traversable:
else
:
else
:
next
=
_getattr
(
obj
,
name
,
marker
)
next
=
_getattr
(
obj
,
name
,
marker
)
if
next
is
marker
:
if
next
is
marker
:
try
:
try
:
try
:
next
=
obj
[
name
]
next
=
obj
[
name
]
except
AttributeError
:
except
AttributeError
:
# Raise NotFound for easier debugging
# Raise NotFound for easier debugging
# instead of AttributeError: __getitem__
# instead of AttributeError: __getitem__
raise
NotFound
,
name
raise
NotFound
,
name
except
(
NotFound
,
KeyError
):
# Try to look for a view
next
=
queryMultiAdapter
((
obj
,
self
.
REQUEST
),
Interface
,
name
)
if
next
is
None
:
# Didn't find one, reraise the error:
raise
next
=
next
.
__of__
(
obj
)
if
restricted
and
not
securityManager
.
validate
(
if
restricted
and
not
securityManager
.
validate
(
obj
,
obj
,
_none
,
next
):
obj
,
obj
,
_none
,
next
):
raise
Unauthorized
,
name
raise
Unauthorized
,
name
...
...
lib/python/Products/PageTemplates/Expressions.py
View file @
7abca36a
...
@@ -248,12 +248,28 @@ class NotExpr:
...
@@ -248,12 +248,28 @@ class NotExpr:
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'not:%s'
%
`self._s`
return
'not:%s'
%
`self._s`
from
zope.interface
import
Interface
,
implements
from
zope.component
import
queryMultiAdapter
from
zope.app.traversing.namespace
import
nsParse
from
zope.app.traversing.namespace
import
namespaceLookup
from
zope.app.traversing.interfaces
import
TraversalError
from
zope.publisher.interfaces.browser
import
IBrowserRequest
from
zope.app.publication.browser
import
setDefaultSkin
class
FakeRequest
(
dict
):
implements
(
IBrowserRequest
)
def
getURL
(
self
):
return
"http://codespeak.net/z3/five"
def
restrictedTraverse
(
object
,
path
,
securityManager
,
def
restrictedTraverse
(
object
,
path
,
securityManager
,
get
=
getattr
,
has
=
hasattr
,
N
=
None
,
M
=
[],
get
=
getattr
,
has
=
hasattr
,
N
=
None
,
M
=
[],
TupleType
=
type
(())
):
TupleType
=
type
(())
):
REQUEST
=
{
'path'
:
path
}
REQUEST
=
FakeRequest
()
REQUEST
[
'path'
]
=
path
REQUEST
[
'TraversalRequestNameStack'
]
=
path
=
path
[:]
# Copy!
REQUEST
[
'TraversalRequestNameStack'
]
=
path
=
path
[:]
# Copy!
setDefaultSkin
(
REQUEST
)
path
.
reverse
()
path
.
reverse
()
validate
=
securityManager
.
validate
validate
=
securityManager
.
validate
__traceback_info__
=
REQUEST
__traceback_info__
=
REQUEST
...
@@ -282,7 +298,18 @@ def restrictedTraverse(object, path, securityManager,
...
@@ -282,7 +298,18 @@ def restrictedTraverse(object, path, securityManager,
continue
continue
t
=
get
(
object
,
'__bobo_traverse__'
,
N
)
t
=
get
(
object
,
'__bobo_traverse__'
,
N
)
if
t
is
not
N
:
if
name
and
name
[:
1
]
in
'@+'
:
# Process URI segment parameters.
ns
,
nm
=
nsParse
(
name
)
if
ns
:
try
:
o
=
namespaceLookup
(
ns
,
nm
,
object
,
REQUEST
).
__of__
(
object
)
if
not
validate
(
object
,
object
,
name
,
o
):
raise
Unauthorized
,
name
except
TraversalError
:
raise
AttributeError
(
name
)
elif
t
is
not
N
:
o
=
t
(
REQUEST
,
name
)
o
=
t
(
REQUEST
,
name
)
container
=
None
container
=
None
...
@@ -305,7 +332,16 @@ def restrictedTraverse(object, path, securityManager,
...
@@ -305,7 +332,16 @@ def restrictedTraverse(object, path, securityManager,
# XXX maybe in Python 2.2 we can just check whether
# XXX maybe in Python 2.2 we can just check whether
# the object has the attribute "__getitem__"
# the object has the attribute "__getitem__"
# instead of blindly catching exceptions.
# instead of blindly catching exceptions.
try
:
o
=
object
[
name
]
o
=
object
[
name
]
except
(
AttributeError
,
KeyError
):
# Try to look for a view
o
=
queryMultiAdapter
((
object
,
REQUEST
),
Interface
,
name
)
if
o
is
None
:
# Didn't find one, reraise the error:
raise
o
=
o
.
__of__
(
object
)
except
AttributeError
,
exc
:
except
AttributeError
,
exc
:
if
str
(
exc
).
find
(
'__getitem__'
)
>=
0
:
if
str
(
exc
).
find
(
'__getitem__'
)
>=
0
:
# The object does not support the item interface.
# The object does not support the item interface.
...
...
lib/python/ZPublisher/BaseRequest.py
View file @
7abca36a
This diff is collapsed.
Click to expand it.
lib/python/ZPublisher/Publish.py
View file @
7abca36a
...
@@ -122,7 +122,6 @@ def publish(request, module_name, after_list, debug=0,
...
@@ -122,7 +122,6 @@ def publish(request, module_name, after_list, debug=0,
return
response
return
response
except
:
except
:
# DM: provide nicer error message for FTP
# DM: provide nicer error message for FTP
sm
=
None
sm
=
None
if
response
is
not
None
:
if
response
is
not
None
:
...
...
lib/python/ZServer/HTTPResponse.py
View file @
7abca36a
...
@@ -311,6 +311,15 @@ class ChannelPipe:
...
@@ -311,6 +311,15 @@ class ChannelPipe:
self
.
_close
=
1
self
.
_close
=
1
self
.
_request
.
reply_code
=
response
.
status
self
.
_request
.
reply_code
=
response
.
status
def
start_response
(
self
,
status
,
headers
,
exc_info
=
None
):
# Used for WSGI
status
=
'HTTP/%s %s
\
r
\
n
'
%
(
self
.
_request
.
version
,
status
)
self
.
write
(
status
)
headers
=
'
\
r
\
n
'
.
join
([
': '
.
join
(
x
)
for
x
in
headers
])
self
.
write
(
headers
)
self
.
write
(
'
\
r
\
n
\
r
\
n
'
)
return
self
.
write
is_proxying_match
=
re
.
compile
(
r'[^ ]* [^ \\]*:'
).
match
is_proxying_match
=
re
.
compile
(
r'[^ ]* [^ \\]*:'
).
match
proxying_connection_re
=
re
.
compile
(
'Proxy-Connection: (.*)'
,
re
.
IGNORECASE
)
proxying_connection_re
=
re
.
compile
(
'Proxy-Connection: (.*)'
,
re
.
IGNORECASE
)
...
...
lib/python/ZServer/HTTPServer.py
View file @
7abca36a
...
@@ -279,6 +279,48 @@ class zhttp_handler:
...
@@ -279,6 +279,48 @@ class zhttp_handler:
</ul>"""
%
(
self
.
module_name
,
self
.
hits
)
</ul>"""
%
(
self
.
module_name
,
self
.
hits
)
)
)
from
HTTPResponse
import
ChannelPipe
class
zwsgi_handler
(
zhttp_handler
):
def
continue_request
(
self
,
sin
,
request
):
"continue handling request now that we have the stdin"
s
=
get_header
(
CONTENT_LENGTH
,
request
.
header
)
if
s
:
s
=
int
(
s
)
else
:
s
=
0
DebugLogger
.
log
(
'I'
,
id
(
request
),
s
)
env
=
self
.
get_environment
(
request
)
version
=
request
.
version
if
version
==
'1.0'
and
is_proxying_match
(
request
.
request
):
# a request that was made as if this zope was an http 1.0 proxy.
# that means we have to use some slightly different http
# headers to manage persistent connections.
connection_re
=
proxying_connection_re
else
:
# a normal http request
connection_re
=
CONNECTION
env
[
'http_connection'
]
=
get_header
(
connection_re
,
request
.
header
).
lower
()
env
[
'server_version'
]
=
request
.
channel
.
server
.
SERVER_IDENT
env
[
'wsgi.output'
]
=
ChannelPipe
(
request
)
env
[
'wsgi.input'
]
=
sin
env
[
'wsgi.errors'
]
=
sys
.
stderr
env
[
'wsgi.version'
]
=
(
1
,
0
)
env
[
'wsgi.multithread'
]
=
True
env
[
'wsgi.multiprocess'
]
=
True
env
[
'wsgi.run_once'
]
=
True
env
[
'wsgi.url_scheme'
]
=
env
[
'SERVER_PROTOCOL'
].
split
(
'/'
)[
0
]
request
.
channel
.
current_request
=
None
request
.
channel
.
queue
.
append
((
'Zope2WSGI'
,
env
,
env
[
'wsgi.output'
].
start_response
))
request
.
channel
.
work
()
class
zhttp_channel
(
http_channel
):
class
zhttp_channel
(
http_channel
):
...
...
lib/python/ZServer/PubCore/ZServerPublisher.py
View file @
7abca36a
...
@@ -14,13 +14,24 @@
...
@@ -14,13 +14,24 @@
class
ZServerPublisher
:
class
ZServerPublisher
:
def
__init__
(
self
,
accept
):
def
__init__
(
self
,
accept
):
from
ZPublisher
import
publish_module
from
ZPublisher
import
publish_module
from
ZPublisher.WSGIPublisher
import
publish_module
as
publish_wsgi
while
1
:
while
1
:
name
,
a
,
b
=
accept
()
if
name
==
"Zope2"
:
try
:
try
:
name
,
request
,
response
=
accept
()
publish_module
(
publish_module
(
name
,
name
,
request
=
request
,
request
=
a
,
response
=
response
)
response
=
b
)
finally
:
finally
:
response
.
_finish
()
b
.
_finish
()
request
=
response
=
None
a
=
b
=
None
elif
name
==
"Zope2WSGI"
:
try
:
res
=
publish_wsgi
(
a
,
b
)
for
r
in
res
:
a
[
'wsgi.output'
].
write
(
r
)
finally
:
a
[
'wsgi.output'
].
_close
=
1
a
[
'wsgi.output'
].
close
()
lib/python/ZServer/component.xml
View file @
7abca36a
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
receive WebDAV source responses to GET requests.
receive WebDAV source responses to GET requests.
</description>
</description>
</key>
</key>
<key
name=
"use-wsgi"
datatype=
"boolean"
default=
"off"
/>
</sectiontype>
</sectiontype>
<sectiontype
name=
"webdav-source-server"
<sectiontype
name=
"webdav-source-server"
...
@@ -26,6 +27,7 @@
...
@@ -26,6 +27,7 @@
implements=
"ZServer.server"
>
implements=
"ZServer.server"
>
<key
name=
"address"
datatype=
"inet-binding-address"
/>
<key
name=
"address"
datatype=
"inet-binding-address"
/>
<key
name=
"force-connection-close"
datatype=
"boolean"
default=
"off"
/>
<key
name=
"force-connection-close"
datatype=
"boolean"
default=
"off"
/>
<key
name=
"use-wsgi"
datatype=
"boolean"
default=
"off"
/>
</sectiontype>
</sectiontype>
<sectiontype
name=
"persistent-cgi"
<sectiontype
name=
"persistent-cgi"
...
...
lib/python/ZServer/datatypes.py
View file @
7abca36a
...
@@ -71,6 +71,7 @@ class HTTPServerFactory(ServerFactory):
...
@@ -71,6 +71,7 @@ class HTTPServerFactory(ServerFactory):
# webdav-source-server sections won't have webdav_source_clients:
# webdav-source-server sections won't have webdav_source_clients:
webdav_clients
=
getattr
(
section
,
"webdav_source_clients"
,
None
)
webdav_clients
=
getattr
(
section
,
"webdav_source_clients"
,
None
)
self
.
webdav_source_clients
=
webdav_clients
self
.
webdav_source_clients
=
webdav_clients
self
.
use_wsgi
=
section
.
use_wsgi
def
create
(
self
):
def
create
(
self
):
from
ZServer.AccessLogger
import
access_logger
from
ZServer.AccessLogger
import
access_logger
...
@@ -86,6 +87,9 @@ class HTTPServerFactory(ServerFactory):
...
@@ -86,6 +87,9 @@ class HTTPServerFactory(ServerFactory):
def
createHandler
(
self
):
def
createHandler
(
self
):
from
ZServer
import
HTTPServer
from
ZServer
import
HTTPServer
if
self
.
use_wsgi
:
return
HTTPServer
.
zwsgi_handler
(
self
.
module
,
''
,
self
.
cgienv
)
else
:
return
HTTPServer
.
zhttp_handler
(
self
.
module
,
''
,
self
.
cgienv
)
return
HTTPServer
.
zhttp_handler
(
self
.
module
,
''
,
self
.
cgienv
)
...
...
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