Description

XmlRPC/WikiRpc getPage and putPage are broken in Moin 1.9.2 and HG-20100426 (1.9.1 is working), when using non standard configuration (i.e moin 1.9 with werkzeug 0.6).

Steps to reproduce

  1. setup a wiki for XmlRpc

  2. enable XmlRpc in wiki configuration file

  3. Run the test code below (python get.py)

Example

get.py:

   1 import xmlrpclib
   2 wikiurl = "http://localhost:8080/"
   3 homewiki = xmlrpclib.ServerProxy(wikiurl + "?action=xmlrpc2", allow_none=True)
   4 pagename = 'FrontPage'
   5 raw_text = homewiki.getPage(pagename)
   6 print raw_text

Traceback (most recent call last):
  File "get.py", line 8, in <module>
    raw_text = homewiki.getPage(pagename)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1147, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1437, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.5/xmlrpclib.py", line 1201, in request
    return self._parse_response(h.getfile(), sock)
  File "/usr/lib/python2.5/xmlrpclib.py", line 1340, in _parse_response
    return u.close()
  File "/usr/lib/python2.5/xmlrpclib.py", line 787, in close
    raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: '<type \'exceptions.AttributeError\'>: \'XMLRPCContext\' object has no attribute \'in_data\'\n  File "/usr/lib/pymodules/python2.5/MoinMoin/xmlrpc/__init__.py", line 137, in process\n    data = request.in_data\n\n  File "/usr/lib/pymodules/python2.5/MoinMoin/web/contexts.py", line 224, in __getattr__\n    return super(HTTPContext, self).__getattribute__(name)\n'>

Component selection

Details

MoinMoin Version

1.9.2 ~ hg-20100426, using werkzeug 0.6+

OS and Version

Debian Squeeze

Python Version

2.5

Server Setup

à la Desktop-Edition

Server Details

XmlRpc actoin enabled

Language you are using the wiki in (set in the browser/UserPreferences)

en

The bug only occurs when using werkzeug 0.6+, sorry for the noise. -- FranklinPiat 2010-04-28 13:44:15

Workaround

Discussion

This is the change from 1.9.1 to 1.9.2 that was intended to improve 0.5/0.6 compatibility (and in general, make code less broken), but obviously is not good enough:

diff -r 1ecb884c0deb -r ced05deb11ae MoinMoin/web/request.py
--- a/MoinMoin/web/request.py   Tue Jan 19 00:35:00 2010 +0100
+++ b/MoinMoin/web/request.py   Sun Feb 28 23:49:03 2010 +0100
@@ -47,7 +47,24 @@
         self.response = []
         self.status_code = 200
 
-    in_stream = RequestBase.stream
+    # XXX ugly hack begin - works by sheer luck
+    # TODO keep request and response separate, don't mix them together
+    stream = property() # protect inherited .stream attr from accessing
+
+    try:
+        # for werkzeug 0.6
+        in_stream = cached_property(RequestBase.stream.func, 'in_stream')
+    except AttributeError:
+        # no .func -> werkzeug 0.5
+        in_stream = RequestBase.stream
+
+    try:
+        # for werkzeug 0.6
+        out_stream = cached_property(ResponseBase.stream.func, 'out_stream')
+    except AttributeError:
+        # no .func -> werkzeug 0.5
+        out_stream = ResponseBase.stream
+    # XXX ugly hack end
 
     @cached_property
     def in_data(self):
@@ -104,3 +121,4 @@
     if output:
         result = output
     return (result, headers_set[0], headers_set[1])
+

I did another change http://hg.moinmo.in/moin/1.9/rev/8ed0f132fb44 that simplifies xmlrpc's access to the input stream. It doesn't fix the problem, but one now gets a different traceback when doing an xmlrpc request as described above:

Traceback (most recent call last):
  File "/home/tw/w/mm19/MoinMoin/xmlrpc/__init__.py", line 137, in process
    data = request.read()
  File "/home/tw/w/mm19/MoinMoin/web/contexts.py", line 230, in read
    return self.request.in_stream.read()
  File "/home/tw/w/mm19/MoinMoin/support/werkzeug/utils.py", line 79, in __get__
    value = self.func(obj)
  File "/home/tw/w/mm19/MoinMoin/support/werkzeug/wrappers.py", line 340, in stream
    return self.stream
AttributeError: unreadable attribute

That "self" (as in "self.stream") is an AppRequest instance (simple subclass of MoinMoin.web.request.Request). We explicitly protect from accessing "stream" from there (because it inherits from both request and response base classes) by:

    stream = property() # protect inherited .stream attr from accessing

Plan


CategoryMoinMoinBugFixed

MoinMoin: MoinMoinBugs/1.9.2XMLRPCContext_object_has_no_attribute_in-data (last edited 2010-05-03 21:50:33 by ThomasWaldmann)