Skip to content

Commit c1b073a

Browse files
bpo-43433: Preserve query and fragment in the URL of the server in ServerProxy. (GH-25057)
1 parent 70cdf18 commit c1b073a

3 files changed

Lines changed: 45 additions & 3 deletions

File tree

Lib/test/test_xmlrpc.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,11 +698,16 @@ def _marshaled_dispatch(self, data, dispatch_method=None, path=None):
698698
#on AF_INET only.
699699
URL = "http://%s:%d"%(ADDR, PORT)
700700
serv.server_activate()
701-
paths = ["/foo", "/foo/bar"]
701+
paths = [
702+
"/foo", "/foo/bar",
703+
"/foo?k=v", "/foo#frag", "/foo?k=v#frag",
704+
"", "/", "/RPC2", "?k=v", "#frag",
705+
]
702706
for path in paths:
703707
d = serv.add_dispatcher(path, xmlrpc.server.SimpleXMLRPCDispatcher())
704708
d.register_introspection_functions()
705709
d.register_multicall_functions()
710+
d.register_function(lambda p=path: p, 'test')
706711
serv.get_dispatcher(paths[0]).register_function(pow)
707712
serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add')
708713
serv.add_dispatcher("/is/broken", BrokenDispatcher())
@@ -1018,6 +1023,39 @@ def test_path3(self):
10181023
p = xmlrpclib.ServerProxy(URL+"/is/broken")
10191024
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
10201025

1026+
def test_invalid_path(self):
1027+
p = xmlrpclib.ServerProxy(URL+"/invalid")
1028+
self.assertRaises(xmlrpclib.Fault, p.add, 6, 8)
1029+
1030+
def test_path_query_fragment(self):
1031+
p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag")
1032+
self.assertEqual(p.test(), "/foo?k=v#frag")
1033+
1034+
def test_path_fragment(self):
1035+
p = xmlrpclib.ServerProxy(URL+"/foo#frag")
1036+
self.assertEqual(p.test(), "/foo#frag")
1037+
1038+
def test_path_query(self):
1039+
p = xmlrpclib.ServerProxy(URL+"/foo?k=v")
1040+
self.assertEqual(p.test(), "/foo?k=v")
1041+
1042+
def test_empty_path(self):
1043+
p = xmlrpclib.ServerProxy(URL)
1044+
self.assertEqual(p.test(), "/RPC2")
1045+
1046+
def test_root_path(self):
1047+
p = xmlrpclib.ServerProxy(URL + "/")
1048+
self.assertEqual(p.test(), "/")
1049+
1050+
def test_empty_path_query(self):
1051+
p = xmlrpclib.ServerProxy(URL + "?k=v")
1052+
self.assertEqual(p.test(), "?k=v")
1053+
1054+
def test_empty_path_fragment(self):
1055+
p = xmlrpclib.ServerProxy(URL + "#frag")
1056+
self.assertEqual(p.test(), "#frag")
1057+
1058+
10211059
#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism
10221060
#does indeed serve subsequent requests on the same connection
10231061
class BaseKeepaliveServerTestCase(BaseServerTestCase):

Lib/xmlrpc/client.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,11 +1421,13 @@ def __init__(self, uri, transport=None, encoding=None, verbose=False,
14211421
# establish a "logical" server connection
14221422

14231423
# get the url
1424-
p = urllib.parse.urlparse(uri)
1424+
p = urllib.parse.urlsplit(uri)
14251425
if p.scheme not in ("http", "https"):
14261426
raise OSError("unsupported XML-RPC protocol")
14271427
self.__host = p.netloc
1428-
self.__handler = p.path or "/RPC2"
1428+
self.__handler = urllib.parse.urlunsplit(["", "", *p[2:]])
1429+
if not self.__handler:
1430+
self.__handler = "/RPC2"
14291431

14301432
if transport is None:
14311433
if p.scheme == "https":
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:class:`xmlrpc.client.ServerProxy` no longer ignores query and fragment in
2+
the URL of the server.

0 commit comments

Comments
 (0)