This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | namespace Codeception\Extension; |
||
| 3 | |||
| 4 | use Codeception\Module; |
||
| 5 | use Codeception\Exception\ModuleException; |
||
| 6 | use Codeception\Exception\ModuleConfigException; |
||
| 7 | use \PHPBrowserMobProxy_Client as BMP; |
||
| 8 | use \Requests; |
||
| 9 | use \RuntimeException; |
||
| 10 | |||
| 11 | /** |
||
| 12 | * @method void _open() Open a new proxy using the PHPBrowserMobProxy_Client method |
||
| 13 | * @method void _close() Close current proxy using the PHPBrowserMobProxy_Client method |
||
| 14 | * @method \Requests_Response _newHar(string $label='') Start new HAR using the PHPBrowserMobProxy_Client method |
||
| 15 | * @method \Requests_Response _newPage(string $label='') Start new HAR page using the PHPBrowserMobProxy_Client method |
||
| 16 | * @method \Requests_Response _blacklist(string $regexp, integer $status_code) Blacklist URLs using the PHPBrowserMobProxy_Client method |
||
| 17 | * @method \Requests_Response _whitelist(string $regexp, integer $status_code) Whitelist URLs using the PHPBrowserMobProxy_Client method |
||
| 18 | * @method \Requests_Response _basicAuth(string $domain, string[] $options) Set HTTP authentication headers using the PHPBrowserMobProxy_Client method |
||
| 19 | * @method \Requests_Response _headers(string[] $options) Override requests HTTP headers using the PHPBrowserMobProxy_Client method |
||
| 20 | * @method \Requests_Response _responseInterceptor(string $js) Intercept HTTP responses using the PHPBrowserMobProxy_Client method |
||
| 21 | * @method \Requests_Response _requestInterceptor(string $js) Intercept HTTP requests using the PHPBrowserMobProxy_Client method |
||
| 22 | * @method \Requests_Response _limits(string[] $options) Set proxy limits using the PHPBrowserMobProxy_Client method |
||
| 23 | * @method \Requests_Response _timeouts(string[] $options) Set proxy timeouts using the PHPBrowserMobProxy_Client method |
||
| 24 | * @method \Requests_Response _remapHosts(string $address, string $ip_address) Map hosts to IP using the PHPBrowserMobProxy_Client method |
||
| 25 | * @method \Requests_Response _waitForTrafficToStop(integer $quiet_period, integer $timeout) Wait for traffic before stopping proxy using the PHPBrowserMobProxy_Client method |
||
| 26 | * @method \Requests_Response _clearDnsCache() Flux proxy DNS cache using the PHPBrowserMobProxy_Client method |
||
| 27 | * @method \Requests_Response _rewriteUrl(string $match, string $replace) Rewrite URLs using the PHPBrowserMobProxy_Client method |
||
| 28 | * @method \Requests_Response _retry(integer $retry_count) Set proxy retries using the PHPBrowserMobProxy_Client method |
||
| 29 | */ |
||
| 30 | class BrowserMob extends Module |
||
| 31 | { |
||
| 32 | |||
| 33 | /** |
||
| 34 | * @var string[] $config |
||
| 35 | */ |
||
| 36 | protected $config = ['host', 'port', 'autostart', 'blacklist', 'whitelist', 'limits', 'timeouts', 'dns', 'retry', 'basicAuth', 'littleproxy']; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * @var string[] $requiredFields |
||
| 40 | */ |
||
| 41 | protected $requiredFields = ['host', 'port']; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @var Requests $response |
||
| 45 | */ |
||
| 46 | protected $response; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @var PHPBrowserMobProxy_Client $bmp |
||
| 50 | */ |
||
| 51 | private $bmp; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @codeCoverageIgnore |
||
| 55 | * @ignore Codeception specific |
||
| 56 | */ |
||
| 57 | public function _initialize() |
||
| 58 | { |
||
| 59 | $host = $this->config['host'].':'.$this->config['port']; |
||
| 60 | |||
| 61 | // test if proxy is available |
||
| 62 | if (static::__pingProxy($host)) { |
||
| 63 | $this->bmp = new BMP($host); |
||
|
0 ignored issues
–
show
|
|||
| 64 | } else { |
||
| 65 | throw new ModuleConfigException(__CLASS__, "Proxy '{$host}' cannot be reached"); |
||
| 66 | } |
||
| 67 | |||
| 68 | // start a new BrowserMobProxy session |
||
| 69 | if (isset($this->config['autostart'])) { |
||
| 70 | if (true === (bool) $this->config['autostart']) { |
||
| 71 | $this->openProxy(); |
||
| 72 | } |
||
| 73 | } |
||
| 74 | } |
||
| 75 | |||
| 76 | /** |
||
| 77 | * Verify if the BrowserMobProxy is reachable |
||
| 78 | * |
||
| 79 | * @param string $host BrowserMob Proxy host, format host:port |
||
| 80 | * |
||
| 81 | * @return boolean Returns true if proxy available, else false |
||
| 82 | */ |
||
| 83 | protected static function __pingProxy($host) |
||
| 84 | { |
||
| 85 | try { |
||
| 86 | $response = Requests::get('http://'.$host.'/proxy/'); |
||
| 87 | } catch (\Exception $e) { |
||
| 88 | throw new ModuleException(__CLASS__, $e->getMessage()); |
||
| 89 | } |
||
| 90 | |||
| 91 | return $response->success; |
||
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * Set proxy capabilitites: blacklist, whitelist, limits, timeouts, dns, retry, basicAuth |
||
| 96 | * |
||
| 97 | * @uses BrowserMob::_blacklist |
||
| 98 | * @uses BrowserMob::_whitelist |
||
| 99 | * @uses BrowserMob::_limits |
||
| 100 | * @uses BrowserMob::_timeouts |
||
| 101 | * @uses BrowserMob::_remapHosts |
||
| 102 | * @uses BrowserMob::_retry |
||
| 103 | * @uses BrowserMob::_basicAuth |
||
| 104 | * |
||
| 105 | * @param mixed[] $options Array of options (see extension configuration) |
||
| 106 | * |
||
| 107 | * @return void |
||
| 108 | */ |
||
| 109 | protected function __setProxyCapabilities($options) |
||
| 110 | { |
||
| 111 | foreach ($options as $config => $data) { |
||
| 112 | if (false === empty($data)) { |
||
| 113 | switch ((string) $config) { |
||
| 114 | case 'blacklist': |
||
| 115 | foreach ($data['patterns'] as $pattern) { |
||
| 116 | $this->_blacklist($pattern, $data['code']); |
||
| 117 | } |
||
| 118 | break; |
||
| 119 | case 'whitelist': |
||
| 120 | $patterns = implode(',', $data['patterns']); |
||
| 121 | $this->_whitelist($patterns, $data['code']); |
||
| 122 | break; |
||
| 123 | case 'limits': |
||
| 124 | $this->_limits($data); |
||
| 125 | break; |
||
| 126 | case 'timeouts': |
||
| 127 | $this->_timeouts($data); |
||
| 128 | break; |
||
| 129 | case 'dns': |
||
| 130 | foreach ($data as $entry) { |
||
| 131 | $this->_remapHosts($entry['domain'], $entry['ip']); |
||
| 132 | } |
||
| 133 | break; |
||
| 134 | case 'retry': |
||
| 135 | $this->_retry($data); |
||
| 136 | break; |
||
| 137 | case 'basicAuth': |
||
| 138 | foreach ($data as $entry) { |
||
| 139 | $this->_basicAuth($entry['domain'], $entry['options']); |
||
| 140 | } |
||
| 141 | break; |
||
| 142 | default: |
||
| 143 | // do nothing |
||
| 144 | } |
||
| 145 | } |
||
| 146 | } |
||
| 147 | } |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Return current proxy port opened on BrowserMobProxy |
||
| 151 | * |
||
| 152 | * @return integer Proxy port |
||
| 153 | */ |
||
| 154 | public function getProxyPort() |
||
| 155 | { |
||
| 156 | return $this->bmp->port; |
||
| 157 | } |
||
| 158 | |||
| 159 | /** |
||
| 160 | * Set current proxy port to use on BrowserMobProxy |
||
| 161 | * |
||
| 162 | * @param integer $port Proxy port |
||
| 163 | */ |
||
| 164 | public function setProxyPort($port) |
||
| 165 | { |
||
| 166 | $prop = new \ReflectionProperty($this->bmp, 'port'); |
||
| 167 | $prop->setAccessible(true); |
||
| 168 | $prop->setValue($this->bmp, $port); |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Open a new proxy on BrowserMobProxy |
||
| 173 | * |
||
| 174 | * @see BrowserMob::__setProxyCapabilities |
||
| 175 | * |
||
| 176 | * @uses BrowserMob::_open |
||
| 177 | * @uses BrowserMob::__setProxyCapabilities |
||
| 178 | * @uses BrowserMob::getProxyPort |
||
| 179 | * |
||
| 180 | * @param mixed[]|null $capabilities Array of capabilities. Use extension configuration if null |
||
| 181 | * |
||
| 182 | * @return integer Proxy port |
||
| 183 | */ |
||
| 184 | public function openProxy($capabilities = null) |
||
| 185 | { |
||
| 186 | $this->_open(); |
||
| 187 | if (empty($capabilities)) { |
||
| 188 | $capabilities = $this->config; |
||
| 189 | } |
||
| 190 | $this->__setProxyCapabilities($capabilities); |
||
| 191 | return $this->getProxyPort(); |
||
| 192 | } |
||
| 193 | |||
| 194 | /** |
||
| 195 | * Close the current proxy opened BrowserMobProxy |
||
| 196 | * Not supported by library chartjes/php-browsermob-proxy |
||
| 197 | * |
||
| 198 | * @uses BrowserMob::_close |
||
| 199 | * |
||
| 200 | * @return void |
||
| 201 | */ |
||
| 202 | public function closeProxy() |
||
| 203 | { |
||
| 204 | $this->_close(); |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Start to capture the HTTP archive |
||
| 209 | * |
||
| 210 | * @uses BrowserMob::_newHar |
||
| 211 | * |
||
| 212 | * @param string|null $label Title of first HAR page |
||
| 213 | * |
||
| 214 | * @return boolean Command status |
||
| 215 | */ |
||
| 216 | public function startHar($label = '') |
||
| 217 | { |
||
| 218 | $this->_newHar($label); |
||
| 219 | return $this->response->success; |
||
| 220 | } |
||
| 221 | |||
| 222 | /** |
||
| 223 | * Add a new page to the HTTP archive |
||
| 224 | * |
||
| 225 | * @uses BrowserMob::_newPage |
||
| 226 | * |
||
| 227 | * @param string|null $label Title of new HAR page |
||
| 228 | * |
||
| 229 | * @return boolean Command status |
||
| 230 | */ |
||
| 231 | public function addPage($label = '') |
||
| 232 | { |
||
| 233 | $this->_newPage($label); |
||
| 234 | return $this->response->success; |
||
| 235 | } |
||
| 236 | |||
| 237 | /** |
||
| 238 | * Get the HTTP archive captured |
||
| 239 | * |
||
| 240 | * @return mixed[] HTTP archive |
||
| 241 | */ |
||
| 242 | public function getHar() |
||
| 243 | { |
||
| 244 | return $this->bmp->har; |
||
| 245 | } |
||
| 246 | |||
| 247 | /** |
||
| 248 | * Override HTTP request headers |
||
| 249 | * |
||
| 250 | * @uses BrowserMob::_headers |
||
| 251 | * |
||
| 252 | * @param string[] $headers Array of HTTP headers |
||
| 253 | * |
||
| 254 | * @return boolean Command status |
||
| 255 | */ |
||
| 256 | public function setHeaders($headers) |
||
| 257 | { |
||
| 258 | $this->_headers($headers); |
||
| 259 | return $this->response->success; |
||
| 260 | } |
||
| 261 | |||
| 262 | /** |
||
| 263 | * Rewrite URLs with regex |
||
| 264 | * |
||
| 265 | * @uses BrowserMob::_rewriteUrl |
||
| 266 | * |
||
| 267 | * @param string $match Matching URL regular expression |
||
| 268 | * @param string $replace Replacement URL |
||
| 269 | * |
||
| 270 | * @return boolean Command status |
||
| 271 | */ |
||
| 272 | public function redirectUrl($match, $replace) |
||
| 273 | { |
||
| 274 | $this->_rewriteUrl($match, $replace); |
||
| 275 | return $this->response->success; |
||
| 276 | } |
||
| 277 | |||
| 278 | /** |
||
| 279 | * Run Javascript against requests before sending them |
||
| 280 | * |
||
| 281 | * @param string $script Javascript code |
||
| 282 | * |
||
| 283 | * @return boolean Command status |
||
| 284 | */ |
||
| 285 | public function filterRequest($script) |
||
| 286 | { |
||
| 287 | $this->_requestInterceptor($script); |
||
| 288 | return $this->response->success; |
||
| 289 | } |
||
| 290 | |||
| 291 | /** |
||
| 292 | * Run Javascript against responses received |
||
| 293 | * |
||
| 294 | * @param string $script Javascript code |
||
| 295 | * |
||
| 296 | * @return boolean Command status |
||
| 297 | */ |
||
| 298 | public function filterResponse($script) |
||
| 299 | { |
||
| 300 | $this->_responseInterceptor($script); |
||
| 301 | return $this->response->success; |
||
| 302 | } |
||
| 303 | |||
| 304 | /** |
||
| 305 | * Magic function that exposes BrowserMobProxy API pulic methods |
||
| 306 | * |
||
| 307 | * @ignore Exclude from documentation |
||
| 308 | */ |
||
| 309 | public function __call($name, $args) |
||
| 310 | { |
||
| 311 | // check if is a command call |
||
| 312 | if (preg_match('/^_[A-z]+$/', $name)) { |
||
| 313 | // extract standard method name |
||
| 314 | $name = preg_filter('/_/', '', $name); |
||
| 315 | // set call array for calling method |
||
| 316 | $call = array($this->bmp, $name); |
||
| 317 | // check if method is callable |
||
| 318 | if (is_callable($call)) { |
||
| 319 | $ret = call_user_func_array($call, $args); |
||
| 320 | if (get_class($ret) === 'Requests_Response') { |
||
| 321 | $this->response = $ret; |
||
|
0 ignored issues
–
show
It seems like
$ret of type object<Requests_Response> is incompatible with the declared type object<Requests> of property $response.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 322 | if (false === $ret->success) { |
||
| 323 | throw new ModuleConfigException(__CLASS__, "Proxy response error '{$ret->status_code}' {$ret->body}"); |
||
| 324 | } |
||
| 325 | } |
||
| 326 | } else { |
||
| 327 | throw new RuntimeException("Method ${name} does not exist or is not callable"); |
||
| 328 | } |
||
| 329 | } else { |
||
| 330 | throw new RuntimeException("Method ${method} does not exist or is not callable"); |
||
| 331 | } |
||
| 332 | $ret = (isset($ret)) ? $ret : null; |
||
| 333 | return $ret; |
||
| 334 | } |
||
| 335 | |||
| 336 | } |
||
| 337 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..