如何在 Python 中伪造肥皂响应?
我正在尝试测试公司产品中的功能。我们的软件将发出如下所示的 SOAP 请求:
请求标头
POST /testfunction.php HTTP/1.1
Accept: application/soap+xml, application/xml, text/xml
SOAPAction: "http://www.abc.com/testfunction#test"
Host: soap.abc.com
Content-Length: 461
Connection: Keep-Alive
请求内容
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction">
<SOAP-ENV:Body>
<ns1:test>
<productID>3</productID>
<productSubID>1</productSubID>
<version>1.0.1</version>
<serialNumber/>
<language>EN</language>
<daysLicensed>0</daysLicensed>
<daysLeft>0</daysLeft>
</ns1:test>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP 服务应响应:
响应标头
HTTP/1.1 200 OK
Server: nginx/0.7.67
Date: Mon, 02 May 2011 13:43:46 GMT
Content-Type: text/xml; charset=utf-8
Connection: keep-alive
X-Powered-By: PHP/5.3.3-1ubuntu9.3
Content-Length: 304
Content-encoding: gzip
响应内容< /strong>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
一开始我以为我可以在 web.py 中创建一个 Web 服务,并在有人在 http://www.abc.com/testfunction。
import web
url = (
'/testfunction', 'testfunction',
)
class testfunction:
def POST(self):
web.header('Content-Type', 'text/xml; charset=utf-8')
return """<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
"""
app = web.application(url, globals())
if __name__== "__main__":
app.run()
但这没有用。我认为这可能与标题有关。然后我尝试使用 SimpleXMLRPCServer。
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import xmlrpclib
class MyRequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/',)
def do_POST(self):
return SimpleXMLRPCRequestHandler.do_POST(self)
def test():
return "hello, world"
server = SimpleXMLRPCServer(
("0.0.0.0", 80),
requestHandler = MyRequestHandler,
)
server.register_function(test, 'test')
server.serve_forever()
但问题是我不知道如何处理标头中的 SOAPAction 并且客户端没有使用此处的测试功能。谁能帮助我吗?多谢!!
更新:
终于做到了,使用以下代码:
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
def echo(environ, start_response):
status = "200 OK"
headers = [("Content-type", "text/xml")]
start_response(status, headers)
return ["""<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"""]
httpd = WSGIServer(('0.0.0.0', 80), WSGIRequestHandler)
httpd.set_app(echo)
httpd.serve_forever()
它应该与 web.py 代码相同,但 web.py 代码却不然。从wireshark中捕获的包中我发现xml内容前后有一些乱码(“3bc”和“0),与编码有关吗?
I am trying to test a function in company product. Our software will make a SOAP request like this:
Request Header
POST /testfunction.php HTTP/1.1
Accept: application/soap+xml, application/xml, text/xml
SOAPAction: "http://www.abc.com/testfunction#test"
Host: soap.abc.com
Content-Length: 461
Connection: Keep-Alive
Request Content
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction">
<SOAP-ENV:Body>
<ns1:test>
<productID>3</productID>
<productSubID>1</productSubID>
<version>1.0.1</version>
<serialNumber/>
<language>EN</language>
<daysLicensed>0</daysLicensed>
<daysLeft>0</daysLeft>
</ns1:test>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And the SOAP service should respond:
Response Header
HTTP/1.1 200 OK
Server: nginx/0.7.67
Date: Mon, 02 May 2011 13:43:46 GMT
Content-Type: text/xml; charset=utf-8
Connection: keep-alive
X-Powered-By: PHP/5.3.3-1ubuntu9.3
Content-Length: 304
Content-encoding: gzip
Response Content
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
In the beginning I thought I could just make a web service in web.py and returns the same response whenever someone make a POST request on http://www.abc.com/testfunction.
import web
url = (
'/testfunction', 'testfunction',
)
class testfunction:
def POST(self):
web.header('Content-Type', 'text/xml; charset=utf-8')
return """<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
"""
app = web.application(url, globals())
if __name__== "__main__":
app.run()
But it didn't work. I think that maybe something to do with the header. Then I tried with SimpleXMLRPCServer.
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import xmlrpclib
class MyRequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/',)
def do_POST(self):
return SimpleXMLRPCRequestHandler.do_POST(self)
def test():
return "hello, world"
server = SimpleXMLRPCServer(
("0.0.0.0", 80),
requestHandler = MyRequestHandler,
)
server.register_function(test, 'test')
server.serve_forever()
but problem is I don't know how to deal with SOAPAction in the header and the client is not using the test function here. Can anyone help me? Thanks a lot!!
Update:
Finally did it, using the following code:
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
def echo(environ, start_response):
status = "200 OK"
headers = [("Content-type", "text/xml")]
start_response(status, headers)
return ["""<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.abc.com/testfunction"><SOAP-ENV:Body><ns1:testResponse><result>1000</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"""]
httpd = WSGIServer(('0.0.0.0', 80), WSGIRequestHandler)
httpd.set_app(echo)
httpd.serve_forever()
It should work the same with the web.py code, however the web.py one doesn't. From the captured package in wireshark I found some garbled code ("3bc" and "0) before and after the xml content, something to do with the encoding?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用 soaplib 创建一个真正的 SOAP 服务,该服务实现您的接口并返回虚拟数据。与创建手写静态响应相比,这应该更容易维护,并且代码不应比基于 web.py 的示例长很多。
这是一个 Hello World 示例。
You could use soaplib to create a real SOAP service which implements your interface and returns dummy data. This should be a bit easier to maintain then creating handwritten static responses, and the code shouldn't be much longer than your web.py-based example.
Here's a Hello World example.