xmlrpc.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. """xmlrpclib.Transport implementation
  2. """
  3. import logging
  4. import urllib.parse
  5. import xmlrpc.client
  6. from typing import TYPE_CHECKING, Tuple
  7. from pip._internal.exceptions import NetworkConnectionError
  8. from pip._internal.network.session import PipSession
  9. from pip._internal.network.utils import raise_for_status
  10. if TYPE_CHECKING:
  11. from xmlrpc.client import _HostType, _Marshallable
  12. logger = logging.getLogger(__name__)
  13. class PipXmlrpcTransport(xmlrpc.client.Transport):
  14. """Provide a `xmlrpclib.Transport` implementation via a `PipSession`
  15. object.
  16. """
  17. def __init__(
  18. self, index_url: str, session: PipSession, use_datetime: bool = False
  19. ) -> None:
  20. super().__init__(use_datetime)
  21. index_parts = urllib.parse.urlparse(index_url)
  22. self._scheme = index_parts.scheme
  23. self._session = session
  24. def request(
  25. self,
  26. host: "_HostType",
  27. handler: str,
  28. request_body: bytes,
  29. verbose: bool = False,
  30. ) -> Tuple["_Marshallable", ...]:
  31. assert isinstance(host, str)
  32. parts = (self._scheme, host, handler, None, None, None)
  33. url = urllib.parse.urlunparse(parts)
  34. try:
  35. headers = {"Content-Type": "text/xml"}
  36. response = self._session.post(
  37. url,
  38. data=request_body,
  39. headers=headers,
  40. stream=True,
  41. )
  42. raise_for_status(response)
  43. self.verbose = verbose
  44. return self.parse_response(response.raw)
  45. except NetworkConnectionError as exc:
  46. assert exc.response
  47. logger.critical(
  48. "HTTP error %s while getting %s",
  49. exc.response.status_code,
  50. url,
  51. )
  52. raise