Skip to content

Commit

Permalink
doc: explain xmlrpc.Proxy's queryFactory
Browse files Browse the repository at this point in the history
Give an example of how to debug raw XML-RPC responses using xmlrpc.Proxy.
  • Loading branch information
ktdreyer committed May 29, 2020
1 parent d87581b commit f586a11
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/web/examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ XML-RPC

- :download:`xmlrpc.py` XML-RPC server with several methods, including echoing, faulting, returning deferreds and failed deferreds
- :download:`xmlrpcclient.py` - use ``twisted.web.xmlrpc.Proxy`` to call remote XML-RPC methods
- :download:`xmlrpc-debug.py` - use ``xmlrpc.Proxy``'s ``queryFactory`` to debug raw XML-RPC traffic
- :download:`advogato.py` - use ``twisted.web.xmlrpc`` to post a diary entry to advogato.org; requires an advogato account


Expand Down
51 changes: 51 additions & 0 deletions docs/web/examples/xmlrpc-debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
This example prints raw XML-RPC traffic for a client.
Usage:
$ python xmlrpc-debug.py
The example will make a simple XML-RPC request to bugzilla.redhat.com and print
the raw XML response string from the server.
"""

from __future__ import print_function

from twisted.web.xmlrpc import Proxy
from twisted.web.xmlrpc import QueryFactory
from twisted.internet import reactor



class DebuggingQueryFactory(QueryFactory):
""" Print the server's raw responses before continuing with parsing. """
def parseResponse(self, contents):
print(contents) # show the raw XML-RPC string
return QueryFactory.parseResponse(self, contents)



def printValue(value):
print(repr(value))
reactor.stop()



def printError(error):
print('error', error)
reactor.stop()



proxy = Proxy(b'https://bugzilla.redhat.com/xmlrpc.cgi')

# Enable our debugging factory for our client:
proxy.queryFactory = DebuggingQueryFactory

# "Bugzilla.version" returns the Bugzilla software version,
# like "{'version': '5.0.4.rh11'}":
proxy.callRemote('Bugzilla.version').addCallbacks(printValue, printError)

reactor.run()
18 changes: 18 additions & 0 deletions docs/web/howto/xmlrpc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,24 @@ prints:



Debugging with an XML-RPC client
--------------------------------



Sometimes an XML-RPC server may send non-standard XML-RPC responses to your
client. In those cases, you can access the raw XML-RPC responses from the
server with :api:`twisted.web.xmlrpc <twisted.web.xmlrpc>`'s ``QueryFactory``.

You can simply log the response content strings for debugging, or implement
your own custom XML-RPC marshaller to handle the non-standard XML-RPC
responses.

An example Twisted application that does this can be found in
``docs/web/examples/xmlrpc-debug.py`` .




Serving SOAP and XML-RPC simultaneously
---------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/twisted/web/newsfragments/9350.doc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xmlrpc's QueryFactory class is now public, more explanation for xmlrpc's queryFactory, and new xmlrpc-debug.py example script for debugging raw XML-RPC traffic.
10 changes: 8 additions & 2 deletions src/twisted/web/xmlrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,14 @@ class Proxy:
@ivar _reactor: The reactor used to create connections.
@type _reactor: Object providing L{twisted.internet.interfaces.IReactorTCP}
@ivar queryFactory: Object returning a factory for XML-RPC protocol. Mainly
useful for tests.
@ivar queryFactory: Object returning a factory for XML-RPC protocol. Use
this for testing, or to manipulate the XML-RPC parsing behavior. For
example, you may set this to a custom "debugging" factory object that
reimplements C{parseResponse} in order to log the raw XML-RPC contents
from the server before continuing on with parsing. Another possibility
is to implement your own XML-RPC marshaller here to handle non-standard
XML-RPC traffic.
@type queryFactory: L{twisted.web.xmlrpc.QueryFactory}
"""
queryFactory = QueryFactory

Expand Down

0 comments on commit f586a11

Please sign in to comment.