7

無効な XML 文字を Python SimpleXMLRPCServer に渡すと、クライアント側で次のエラーが発生します。

Fault: <Fault 1: "<class 'xml.parsers.expat.ExpatError'>:not well-formed (invalid token): line 6, column 15">

なんで?これを修正するには、SimpleXMLRPCServer ライブラリ コードを変更する必要がありますか?

これが私の XML-RPC サーバー コードです。

from SimpleXMLRPCServer import SimpleXMLRPCServer

import logging
logging.basicConfig(level=logging.DEBUG)

def tt(text):
    return "cool"

server = SimpleXMLRPCServer(("0.0.0.0", 9000))
server.register_introspection_functions()
server.register_function(tt)

# Run the server's main loop
server.serve_forever()

これが私の XML-RPC クライアント コードです。

s = xmlrpclib.ServerProxy('http://localhost:9000')
s.tt(unichr(0x8))

サーバー側では、エラーやトレースバックはありません。

liXXXXXX.members.linode.com - - [06/Dec/2010 23:19:40] "POST /RPC2 HTTP/1.0" 200 -

サーバー側でエラーが発生しないのはなぜですか? 何が起こっているのかを診断するにはどうすればよいですか?

そして、クライアント側で次のトレースバックを取得します。

/usr/lib/python2.6/xmlrpclib.pyc in __call__(self, *args)
   1197         return _Method(self.__send, "%s.%s" % (self.__name, name))
   1198     def __call__(self, *args):
-> 1199         return self.__send(self.__name, args)
   1200 
   1201 ##


/usr/lib/python2.6/xmlrpclib.pyc in __request(self, methodname, params)
   1487             self.__handler,
   1488             request,
-> 1489             verbose=self.__verbose
   1490             )
   1491 

/usr/lib/python2.6/xmlrpclib.pyc in request(self, host, handler, request_body, verbose)
   1251             sock = None
   1252 
-> 1253         return self._parse_response(h.getfile(), sock)
   1254 
   1255     ##


/usr/lib/python2.6/xmlrpclib.pyc in _parse_response(self, file, sock)
   1390         p.close()
   1391 
-> 1392         return u.close()
   1393 
   1394 ##


/usr/lib/python2.6/xmlrpclib.pyc in close(self)
    836             raise ResponseError()
    837         if self._type == "fault":
--> 838             raise Fault(**self._stack[0])
    839         return tuple(self._stack)
    840 

Fault: <Fault 1: "<class 'xml.parsers.expat.ExpatError'>:not well-formed (invalid token): line 6, column 15">

入力に無効な XML が含まれている場合、サーバー側で適切な処理を行うにはどうすればよいですか? このデータ サーバー側をクリーンアップできますか? どのように?

4

3 に答える 3

3

まず、あなたの例は私にとってもうまくいきません。「入力に無効な XML が含まれている場合の適切なサーバー側処理」について何を求めているのかわかりません。サーバーに無効な XML を送信すると、エラーが返されます...これ以上何が必要ですか?

次に、 を挿入するprint 'hi there'と、 を送信したときに が呼び出されていないことttがわかります。サーバーによる正確な応答 (200) は次のとおりです。ttunichr(0x8)

HTTP/1.0 200 OK
Server: BaseHTTP/0.3 Python/2.6.5
Date: Tue, 07 Dec 2010 07:33:09 GMT
Content-type: text/xml
Content-length: 350

<?xml version='1.0'?>
<methodResponse>
<fault>
<value><struct>
<member>
<name>faultCode</name>
<value><int>1</int></value>
</member>
<member>
<name>faultString</name>
<value><string>&lt;class 'xml.parsers.expat.ExpatError'&gt;:not well-formed (invalid token): line 6, column 15</string></value>
</member>
</struct></value>
</fault>
</methodResponse>

したがって、エラーメッセージが表示されます。

さて、XML-RPC仕様によると、

  • 文字列に使用できる文字は何ですか? 印刷できない文字?空文字?「文字列」を使用して、バイナリ データの任意のチャンクを保持できますか?

< としてエンコードされる < と & を除くすべての文字を文字列に使用できます。と &。文字列を使用して、バイナリ データをエンコードできます。

わかりましたが、これは XML であり、XML 仕様によると:

有効な文字は、タブ、キャリッジ リターン、ライン フィード、および Unicode と ISO/IEC 10646 の有効な文字です。

文字 ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

これには 0x08 が含まれておらず、XML-RPC 仕様と完全に矛盾しているようです! したがって、XML 仕様が XML パーサー (エラーから判断すると、expat のように見えます) によってかなり厳密に実装されていることがわかります。XML では 0x08 が許可されていないため、0x08 を送信することはできません。実際、エラーが返されます。

もしそうなら:

data = "<?xml version='1.0'?>\n<methodCall>\n<methodName>tt</methodName>\n<params>\n<param>\n<value><string>\x08</string></value>\n</param>\n</params>\n</methodCall>"
p = xml.parsers.expat.ParserCreate()
p.Parse(data, True)

...エラーが発生しました。ここでも、ガベージ XML をサーバーに渡しています。サーバーはエラー メッセージを返しています。途中の Python はそのエラーを例外として提示しています。どのような動作を期待していましたか?

于 2010-12-07T07:58:33.530 に答える
0

Thanatos は、彼の投稿で問題の理由を完全に説明しました。

この問題を回避するための解決策として: xmlrpclib.Binaryを使用して、送信するデータを base64 エンコードすることができます。(PY3K の場合: xmlrpc.client.Binary )

于 2012-05-25T08:19:06.610 に答える
0

コメントで、クライアントの XML をできるだけ多く処理したいと述べました。これは一見良さそうに聞こえるかもしれませんが (?)、考慮すべき短所があります。

  • 何を剥がすことができるかをどうやって知るのですか?重要だったはずの何かを取り除いたとしても、クライアントはそれを不適切なコードで送信したりします。

  • 最初に、特定の奇形のあるリクエストをサポートすると想像してください。しかし、その後、ユーザーは 2 番目のタイプの奇形を送信し始め、その例外にも例外を追加します (最初のものに追加したら、なぜですか?)。これは長い道のりです...

  • 物事はできるだけ早く失敗に任せ、あるべき場所で対処するのに任せたほうがよいでしょう。今回はクライアントの実装が間違っているので、クライアントに修正してもらいます。長い目で見れば、あなたの両方にとってより良い.

クライアント コードも管理している場合は、最後の手段として XML tidy をプッシュすることもできます (たとえば、BeautifulSoupを参照してください)。ただし、最初に無効な入力を無効にすることで問題に対処してください。

于 2011-01-13T22:14:30.030 に答える