summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-03-29 13:39:31 (GMT)
committerGitHub <noreply@github.com>2021-03-29 13:39:31 (GMT)
commitc1b073a630bb731de18bb17afb2b8b1388b92a72 (patch)
tree9be9c9c8f9e8d2b893ddc976c34015bf54d87ace
parent70cdf1812cf479c6b1cd7435a6fc0679ec1fb0da (diff)
downloadcpython-c1b073a630bb731de18bb17afb2b8b1388b92a72.zip
cpython-c1b073a630bb731de18bb17afb2b8b1388b92a72.tar.gz
cpython-c1b073a630bb731de18bb17afb2b8b1388b92a72.tar.bz2
bpo-43433: Preserve query and fragment in the URL of the server in ServerProxy. (GH-25057)
-rw-r--r--Lib/test/test_xmlrpc.py40
-rw-r--r--Lib/xmlrpc/client.py6
-rw-r--r--Misc/NEWS.d/next/Library/2021-03-28-23-50-20.bpo-43433.so9j5G.rst2
3 files changed, 45 insertions, 3 deletions
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index c54aeb1..a9f6746 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -698,11 +698,16 @@ def http_multi_server(evt, numrequests, requestHandler=None):
#on AF_INET only.
URL = "http://%s:%d"%(ADDR, PORT)
serv.server_activate()
- paths = ["/foo", "/foo/bar"]
+ paths = [
+ "/foo", "/foo/bar",
+ "/foo?k=v", "/foo#frag", "/foo?k=v#frag",
+ "", "/", "/RPC2", "?k=v", "#frag",
+ ]
for path in paths:
d = serv.add_dispatcher(path, xmlrpc.server.SimpleXMLRPCDispatcher())
d.register_introspection_functions()
d.register_multicall_functions()
+ d.register_function(lambda p=path: p, 'test')
serv.get_dispatcher(paths[0]).register_function(pow)
serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add')
serv.add_dispatcher("/is/broken", BrokenDispatcher())
@@ -1018,6 +1023,39 @@ class MultiPathServerTestCase(BaseServerTestCase):
p = xmlrpclib.ServerProxy(URL+"/is/broken")
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
+ def test_invalid_path(self):
+ p = xmlrpclib.ServerProxy(URL+"/invalid")
+ self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
+
+ def test_path_query_fragment(self):
+ p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag")
+ self.assertEqual(p.test(), "/foo?k=v#frag")
+
+ def test_path_fragment(self):
+ p = xmlrpclib.ServerProxy(URL+"/foo#frag")
+ self.assertEqual(p.test(), "/foo#frag")
+
+ def test_path_query(self):
+ p = xmlrpclib.ServerProxy(URL+"/foo?k=v")
+ self.assertEqual(p.test(), "/foo?k=v")
+
+ def test_empty_path(self):
+ p = xmlrpclib.ServerProxy(URL)
+ self.assertEqual(p.test(), "/RPC2")
+
+ def test_root_path(self):
+ p = xmlrpclib.ServerProxy(URL + "/")
+ self.assertEqual(p.test(), "/")
+
+ def test_empty_path_query(self):
+ p = xmlrpclib.ServerProxy(URL + "?k=v")
+ self.assertEqual(p.test(), "?k=v")
+
+ def test_empty_path_fragment(self):
+ p = xmlrpclib.ServerProxy(URL + "#frag")
+ self.assertEqual(p.test(), "#frag")
+
+
#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism
#does indeed serve subsequent requests on the same connection
class BaseKeepaliveServerTestCase(BaseServerTestCase):
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
index d15d60d..9e7449c 100644
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -1421,11 +1421,13 @@ class ServerProxy:
# establish a "logical" server connection
# get the url
- p = urllib.parse.urlparse(uri)
+ p = urllib.parse.urlsplit(uri)
if p.scheme not in ("http", "https"):
raise OSError("unsupported XML-RPC protocol")
self.__host = p.netloc
- self.__handler = p.path or "/RPC2"
+ self.__handler = urllib.parse.urlunsplit(["", "", *p[2:]])
+ if not self.__handler:
+ self.__handler = "/RPC2"
if transport is None:
if p.scheme == "https":
diff --git a/Misc/NEWS.d/next/Library/2021-03-28-23-50-20.bpo-43433.so9j5G.rst b/Misc/NEWS.d/next/Library/2021-03-28-23-50-20.bpo-43433.so9j5G.rst
new file mode 100644
index 0000000..2f67e31
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-03-28-23-50-20.bpo-43433.so9j5G.rst
@@ -0,0 +1,2 @@
+:class:`xmlrpc.client.ServerProxy` no longer ignores query and fragment in
+the URL of the server.