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