[Checkins] SVN: zope3org/trunk/src/zorg/live/ Fixed ftests. Test
for invalid uid, output still broken.
Uwe Oestermeier
uwe_oestermeier at iwm-kmrc.de
Mon Apr 10 09:17:00 EDT 2006
Log message for revision 66779:
Fixed ftests. Test for invalid uid, output still broken.
Changed:
U zope3org/trunk/src/zorg/live/demo/upload/README.txt
U zope3org/trunk/src/zorg/live/ftest/fakeftest.py
U zope3org/trunk/src/zorg/live/page/client.py
U zope3org/trunk/src/zorg/live/page/configure.zcml
U zope3org/trunk/src/zorg/live/page/page.py
U zope3org/trunk/src/zorg/live/server.py
-=-
Modified: zope3org/trunk/src/zorg/live/demo/upload/README.txt
===================================================================
--- zope3org/trunk/src/zorg/live/demo/upload/README.txt 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/demo/upload/README.txt 2006-04-10 13:16:59 UTC (rev 66779)
@@ -72,7 +72,8 @@
>>> dummy = DummyStream()
>>> import time
>>> from zorg.live.server import LiveInputStream
- >>> stream = LiveInputStream(dummy, client, content_length=100)
+ >>> stream = LiveInputStream(dummy, client, content_length=100,
+ ... type="progress")
>>> for i in range(1, 10) :
... time.sleep(0.1)
... stream.write("Some Data")
Modified: zope3org/trunk/src/zorg/live/ftest/fakeftest.py
===================================================================
--- zope3org/trunk/src/zorg/live/ftest/fakeftest.py 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/ftest/fakeftest.py 2006-04-10 13:16:59 UTC (rev 66779)
@@ -39,6 +39,8 @@
from threading import Thread
+from zorg.live.server import securityInputLimit
+
BASEURL = 'http://localhost:8088/@@livecomments.html'
INURL = BASEURL+'/@@input/%(uuid)s'
OUTURL = BASEURL+'/@@output/%(uuid)s'
@@ -315,9 +317,10 @@
#uid OK, what about DOS attack -- XXL data
#if I hit the memory limit of the server, then it's REAL slow
#although server restart/shutdown is still possible
+
data={'name':'update',
'id':'text',
- 'html':'<p>any</p>'*10000000,
+ 'html':'x' * (securityInputLimit + 1),
'extra':'scroll',
'_':''}
try:
Modified: zope3org/trunk/src/zorg/live/page/client.py
===================================================================
--- zope3org/trunk/src/zorg/live/page/client.py 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/page/client.py 2006-04-10 13:16:59 UTC (rev 66779)
@@ -21,12 +21,17 @@
from zope.interface import implements
from zope.app import zapi
+from zope.component import ComponentLookupError
+from zorg.live.globals import getRequest
+
from zorg.live.page.interfaces import ILivePageClient
from zorg.live.page.interfaces import ILivePageManager
from zorg.live.page.interfaces import ICloseEvent
from zorg.live.page.event import IdleEvent
+from zorg.live.page.event import ReloadEvent
+
from zorg.live.page.event import request2event
class LivePageClient(object):
@@ -75,7 +80,13 @@
"""
self.outbox.put(event)
-
+
+ def tearDown(self) :
+ """ Tear down client and clean up event queue. """
+
+ while self.outbox.qsize() :
+ self.outbox.get_nowait()
+
def output(self) :
""" Checks the event queue for waiting events until a timeout occurrs.
@@ -102,10 +113,17 @@
def input(self, event=None) :
""" Receives a client event and broadcasts the event
to other clients.
+
+ Returns a bad request if the client is not registered.
"""
if event is None :
- event = request2event()
+ try :
+ event = request2event()
+ except ComponentLookupError :
+ request = getRequest()
+ request.response.setStatus(400)
+ return 'Invalid client id'
manager = zapi.getUtility(ILivePageManager)
Modified: zope3org/trunk/src/zorg/live/page/configure.zcml
===================================================================
--- zope3org/trunk/src/zorg/live/page/configure.zcml 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/page/configure.zcml 2006-04-10 13:16:59 UTC (rev 66779)
@@ -16,19 +16,21 @@
name="input"
for="zorg.live.page.interfaces.ILivePage"
class="zorg.live.page.page.Input"
- permission="zope.Public">
-
- </page>
+ permission="zope.Public" />
<page
name="output"
for="zorg.live.page.interfaces.ILivePage"
class="zorg.live.page.page.Output"
- permission="zope.Public">
-
- </page>
+ permission="zope.Public" />
+
+ <page
+ name="tearDown"
+ for="*"
+ class="zorg.live.page.page.LivePage"
+ attribute="tearDown"
+ permission="zope.ManageSite" />
-
<zope:subscriber
for="*"
handler="zorg.live.page.manager.livePageSubscriber"
Modified: zope3org/trunk/src/zorg/live/page/page.py
===================================================================
--- zope3org/trunk/src/zorg/live/page/page.py 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/page/page.py 2006-04-10 13:16:59 UTC (rev 66779)
@@ -119,6 +119,14 @@
def render(self) :
""" Renders the client and returns the HTML for the browser. """
NotImplemented
+
+ def tearDown(self) :
+ """ Tear down test environment. """
+ manager = zapi.getUtility(ILivePageManager)
+ for client in manager._iterClients(self.getLocationId()) :
+ client.tearDown()
+ return "ok"
+
defineChecker(LivePage, NoProxy)
Modified: zope3org/trunk/src/zorg/live/server.py
===================================================================
--- zope3org/trunk/src/zorg/live/server.py 2006-04-10 13:14:48 UTC (rev 66778)
+++ zope3org/trunk/src/zorg/live/server.py 2006-04-10 13:16:59 UTC (rev 66779)
@@ -44,11 +44,16 @@
from zorg.live.page.event import dict2event
badRequest = object()
+securityInputLimit = 64000
+
class ExtractionError(Exception) :
- """ Indicates a failed searach for a URI part. """
+ """ Indicates a failed search for a URI part. """
+class InputLimitExceeded(Exception) :
+ """ Indicates an input that exceeds the security limit. """
+
class Extractor(object) :
""" helper fo extracting uuids from a URI. """
@@ -97,7 +102,13 @@
def readEvent(self) :
""" Deserializes the event from the input stream. """
- input = str(self.context.request.stream.read())
+ global securityInputLimit
+
+ stream = self.context.request.stream
+ input = str(stream.read())
+ if len(input) > securityInputLimit :
+ return None # indicates a bad request
+
args = cgi.parse_qs(input)
print "Input", input, args
for k, v in args.items() :
@@ -105,7 +116,7 @@
try :
return dict2event(args)
except ComponentLookupError :
- return None # indicates a bad request
+ return None
@@ -114,7 +125,7 @@
manager = zapi.getUtility(ILivePageManager)
handler = self.context
-
+
if "/@@output/" in uri :
try :
uuid = handler.uuid = self.extractUUID(uri, 'output')
@@ -130,9 +141,7 @@
client = manager.get(uuid, None)
if client :
event = self.readEvent()
- print ["Reading event", event]
if event :
- print "Reading event", event.pprint()
client.input(event)
ok = DirectResult(("ok",))
handler.result = ok
@@ -166,6 +175,7 @@
client = None
result = None
liverequest = False
+ exceeded = False
def __init__(self, application, ctx) :
super(LivePageWSGIHandler, self).__init__(application, ctx)
@@ -296,44 +306,59 @@
import tempfile
from twisted.web2 import iweb, resource, stream
-max_stringio = 100*1000 # Should this be configurable?
-
class LiveInputStream(object) :
""" A wrapper for live input streams. This wrapper
- can report the progress of the upload tasks.
+ can report the progress of the upload tasks or prevent
+ a malevolent upload.
"""
- def __init__(self, stream, client=None, content_length=None) :
+ exceeded = False
+
+ def __init__(self, stream, client=None, content_length=None, type=None) :
self.stream = stream
self.received_bytes = 0
self.expected_length = content_length or 1.0
self.client = client
self.reported = time.time()
self.interval = LivePageWSGIHandler.idleInterval * 2
+ self.type = type
def write(self, data) :
+ global securityInputLimit
self.received_bytes += len(data)
- self.stream.write(data)
+ if not self.exceeded :
+ self.stream.write(data)
if self.client :
- if time.time() > (self.reported + self.interval) :
- ratio = float(self.received_bytes) / float(self.expected_length)
- percent = int(ratio * 100.0)
-
- event = ProgressEvent(percent=percent)
- manager = zapi.getUtility(ILivePageManager)
- print "addEvent", percent
- manager.addEvent(event)
- print "added"
+
+ if self.type == "progress" :
+ if time.time() > (self.reported + self.interval) :
+ ratio = float(self.received_bytes) / float(self.expected_length)
+ percent = int(ratio * 100.0)
+
+ event = ProgressEvent(percent=percent)
+ manager = zapi.getUtility(ILivePageManager)
+ print "addEvent", percent
+ manager.addEvent(event)
+ print "added"
+
+ elif self.type == "input" :
+ if self.received_bytes > securityInputLimit :
+ self.exceeded = True
+
+
class LivePrebuffer(resource.WrapperResource):
+ max_stringio = 100*1000 # Should this be configurable?
+
def hook(self, ctx):
req = iweb.IRequest(ctx)
content_length = req.headers.getHeader('content-length')
- if content_length is not None and int(content_length) > max_stringio:
+ if content_length is not None and \
+ int(content_length) > self.max_stringio:
temp = tempfile.TemporaryFile()
def done(_):
temp.seek(0)
@@ -352,16 +377,28 @@
print "LivePrebuffer.uri", req.uri
+ manager = zapi.getUtility(ILivePageManager)
+ extractor = Extractor(ctx)
+ type = None
+ client = None
try :
- uuid = Extractor(ctx).queryUUID(req.uri, "progress")
- print "Found uuid", uuid
- manager = zapi.getUtility(ILivePageManager)
- client = manager.get(uuid)
+ uuid = extractor.queryUUID(req.uri, "progress")
+ type = "progress"
except ExtractionError :
- client = None
+ uuid = None
- live = LiveInputStream(temp, client, content_length)
+ if not uuid :
+ try :
+ uuid = extractor.extractUUID(req.uri, "input")
+ type = "input"
+ except ExtractionError :
+ uuid = None
+
+ if uuid :
+ client = manager.get(uuid)
+ live = LiveInputStream(temp, client, content_length, type)
+
return stream.readStream(req.stream, live.write).addCallback(done)
# Oops, fix missing () in lambda in WrapperResource
More information about the Checkins
mailing list