xref: /aosp_15_r20/external/cronet/build/android/pylib/utils/chrome_proxy_utils.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1# Copyright 2020 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Utilities for setting up and tear down WPR and TsProxy service."""
5
6from py_utils import ts_proxy_server
7from py_utils import webpagereplay_go_server
8
9from devil.android import forwarder
10
11PROXY_HOST_IP = '127.0.0.1'
12# From Catapult/WebPageReplay document.
13IGNORE_CERT_ERROR_SPKI_LIST = 'PhrPvGIaAMmd29hj8BCZOq096yj7uMpRNHpn5PDxI6I='
14PROXY_SERVER = 'socks5://localhost'
15DEFAULT_DEVICE_PORT = 1080
16DEFAULT_ROUND_TRIP_LATENCY_MS = 100
17DEFAULT_DOWNLOAD_BANDWIDTH_KBPS = 72000
18DEFAULT_UPLOAD_BANDWIDTH_KBPS = 72000
19
20
21class WPRServer:
22  """Utils to set up a webpagereplay_go_server instance."""
23
24  def __init__(self):
25    self._archive_path = None
26    self._host_http_port = 0
27    self._host_https_port = 0
28    self._record_mode = False
29    self._server = None
30
31  def StartServer(self, wpr_archive_path):
32    """Starts a webpagereplay_go_server instance."""
33    if wpr_archive_path == self._archive_path and self._server:
34      # Reuse existing webpagereplay_go_server instance.
35      return
36
37    if self._server:
38      self.StopServer()
39
40    replay_options = []
41    if self._record_mode:
42      replay_options.append('--record')
43
44    ports = {}
45    if not self._server:
46      self._server = webpagereplay_go_server.ReplayServer(
47          wpr_archive_path,
48          PROXY_HOST_IP,
49          http_port=self._host_http_port,
50          https_port=self._host_https_port,
51          replay_options=replay_options)
52      self._archive_path = wpr_archive_path
53      ports = self._server.StartServer()
54
55    self._host_http_port = ports['http']
56    self._host_https_port = ports['https']
57
58  def StopServer(self):
59    """Stops the webpagereplay_go_server instance and resets archive."""
60    self._server.StopServer()
61    self._server = None
62    self._host_http_port = 0
63    self._host_https_port = 0
64
65  @staticmethod
66  def SetServerBinaryPath(go_binary_path):
67    """Sets the go_binary_path for webpagereplay_go_server.ReplayServer."""
68    webpagereplay_go_server.ReplayServer.SetGoBinaryPath(go_binary_path)
69
70  @property
71  def record_mode(self):
72    return self._record_mode
73
74  @record_mode.setter
75  def record_mode(self, value):
76    self._record_mode = value
77
78  @property
79  def http_port(self):
80    return self._host_http_port
81
82  @property
83  def https_port(self):
84    return self._host_https_port
85
86  @property
87  def archive_path(self):
88    return self._archive_path
89
90
91class ChromeProxySession:
92  """Utils to help set up a Chrome Proxy."""
93
94  def __init__(self, device_proxy_port=DEFAULT_DEVICE_PORT):
95    self._device_proxy_port = device_proxy_port
96    self._ts_proxy_server = ts_proxy_server.TsProxyServer(PROXY_HOST_IP)
97    self._wpr_server = WPRServer()
98
99  @property
100  def wpr_record_mode(self):
101    """Returns whether this proxy session was running in record mode."""
102    return self._wpr_server.record_mode
103
104  @wpr_record_mode.setter
105  def wpr_record_mode(self, value):
106    self._wpr_server.record_mode = value
107
108  @property
109  def wpr_replay_mode(self):
110    """Returns whether this proxy session was running in replay mode."""
111    return not self._wpr_server.record_mode
112
113  @property
114  def wpr_archive_path(self):
115    """Returns the wpr archive file path used in this proxy session."""
116    return self._wpr_server.archive_path
117
118  @property
119  def device_proxy_port(self):
120    return self._device_proxy_port
121
122  def GetFlags(self):
123    """Gets the chrome command line flags to be needed by ChromeProxySession."""
124    extra_flags = []
125
126    extra_flags.append('--ignore-certificate-errors-spki-list=%s' %
127                       IGNORE_CERT_ERROR_SPKI_LIST)
128    extra_flags.append('--proxy-server=%s:%s' %
129                       (PROXY_SERVER, self._device_proxy_port))
130    return extra_flags
131
132  @staticmethod
133  def SetWPRServerBinary(go_binary_path):
134    """Sets the WPR server go_binary_path."""
135    WPRServer.SetServerBinaryPath(go_binary_path)
136
137  def Start(self, device, wpr_archive_path):
138    """Starts the wpr_server as well as the ts_proxy server and setups env.
139
140    Args:
141      device: A DeviceUtils instance.
142      wpr_archive_path: A abs path to the wpr archive file.
143
144    """
145    self._wpr_server.StartServer(wpr_archive_path)
146    self._ts_proxy_server.StartServer()
147
148    # Maps device port to host port
149    forwarder.Forwarder.Map(
150        [(self._device_proxy_port, self._ts_proxy_server.port)], device)
151    # Maps tsProxy port to wpr http/https ports
152    self._ts_proxy_server.UpdateOutboundPorts(
153        http_port=self._wpr_server.http_port,
154        https_port=self._wpr_server.https_port)
155    self._ts_proxy_server.UpdateTrafficSettings(
156        round_trip_latency_ms=DEFAULT_ROUND_TRIP_LATENCY_MS,
157        download_bandwidth_kbps=DEFAULT_DOWNLOAD_BANDWIDTH_KBPS,
158        upload_bandwidth_kbps=DEFAULT_UPLOAD_BANDWIDTH_KBPS)
159
160  def Stop(self, device):
161    """Stops the wpr_server, and ts_proxy server and tears down env.
162
163    Note that Stop does not reset wpr_record_mode, wpr_replay_mode,
164    wpr_archive_path property.
165
166    Args:
167      device: A DeviceUtils instance.
168    """
169    self._wpr_server.StopServer()
170    self._ts_proxy_server.StopServer()
171    forwarder.Forwarder.UnmapDevicePort(self._device_proxy_port, device)
172