[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