xmlrpc.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. """xmlrpclib.Transport implementation"""
  2. import logging
  3. import urllib.parse
  4. import xmlrpc.client
  5. from typing import TYPE_CHECKING
  6. from pip._internal.exceptions import NetworkConnectionError
  7. from pip._internal.network.session import PipSession
  8. from pip._internal.network.utils import raise_for_status
  9. if TYPE_CHECKING:
  10. from xmlrpc.client import _HostType, _Marshallable
  11. from _typeshed import SizedBuffer
  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: "SizedBuffer",
  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