annotate vendor/symfony/browser-kit/Client.php @ 12:7a779792577d

Update Drupal core to v8.4.5 (via Composer)
author Chris Cannam
date Fri, 23 Feb 2018 15:52:07 +0000
parents 4c8ae668cc8c
children 5fb285c0d0e3
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\BrowserKit;
Chris@0 13
Chris@0 14 use Symfony\Component\DomCrawler\Crawler;
Chris@0 15 use Symfony\Component\DomCrawler\Link;
Chris@0 16 use Symfony\Component\DomCrawler\Form;
Chris@0 17 use Symfony\Component\Process\PhpProcess;
Chris@0 18
Chris@0 19 /**
Chris@0 20 * Client simulates a browser.
Chris@0 21 *
Chris@0 22 * To make the actual request, you need to implement the doRequest() method.
Chris@0 23 *
Chris@0 24 * If you want to be able to run requests in their own process (insulated flag),
Chris@0 25 * you need to also implement the getScript() method.
Chris@0 26 *
Chris@0 27 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 28 */
Chris@0 29 abstract class Client
Chris@0 30 {
Chris@0 31 protected $history;
Chris@0 32 protected $cookieJar;
Chris@0 33 protected $server = array();
Chris@0 34 protected $internalRequest;
Chris@0 35 protected $request;
Chris@0 36 protected $internalResponse;
Chris@0 37 protected $response;
Chris@0 38 protected $crawler;
Chris@0 39 protected $insulated = false;
Chris@0 40 protected $redirect;
Chris@0 41 protected $followRedirects = true;
Chris@0 42
Chris@0 43 private $maxRedirects = -1;
Chris@0 44 private $redirectCount = 0;
Chris@12 45 private $redirects = array();
Chris@0 46 private $isMainRequest = true;
Chris@0 47
Chris@0 48 /**
Chris@0 49 * @param array $server The server parameters (equivalent of $_SERVER)
Chris@0 50 * @param History $history A History instance to store the browser history
Chris@0 51 * @param CookieJar $cookieJar A CookieJar instance to store the cookies
Chris@0 52 */
Chris@0 53 public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null)
Chris@0 54 {
Chris@0 55 $this->setServerParameters($server);
Chris@0 56 $this->history = $history ?: new History();
Chris@0 57 $this->cookieJar = $cookieJar ?: new CookieJar();
Chris@0 58 }
Chris@0 59
Chris@0 60 /**
Chris@0 61 * Sets whether to automatically follow redirects or not.
Chris@0 62 *
Chris@0 63 * @param bool $followRedirect Whether to follow redirects
Chris@0 64 */
Chris@0 65 public function followRedirects($followRedirect = true)
Chris@0 66 {
Chris@0 67 $this->followRedirects = (bool) $followRedirect;
Chris@0 68 }
Chris@0 69
Chris@0 70 /**
Chris@0 71 * Returns whether client automatically follows redirects or not.
Chris@0 72 *
Chris@0 73 * @return bool
Chris@0 74 */
Chris@0 75 public function isFollowingRedirects()
Chris@0 76 {
Chris@0 77 return $this->followRedirects;
Chris@0 78 }
Chris@0 79
Chris@0 80 /**
Chris@0 81 * Sets the maximum number of requests that crawler can follow.
Chris@0 82 *
Chris@0 83 * @param int $maxRedirects
Chris@0 84 */
Chris@0 85 public function setMaxRedirects($maxRedirects)
Chris@0 86 {
Chris@0 87 $this->maxRedirects = $maxRedirects < 0 ? -1 : $maxRedirects;
Chris@0 88 $this->followRedirects = -1 != $this->maxRedirects;
Chris@0 89 }
Chris@0 90
Chris@0 91 /**
Chris@0 92 * Returns the maximum number of requests that crawler can follow.
Chris@0 93 *
Chris@0 94 * @return int
Chris@0 95 */
Chris@0 96 public function getMaxRedirects()
Chris@0 97 {
Chris@0 98 return $this->maxRedirects;
Chris@0 99 }
Chris@0 100
Chris@0 101 /**
Chris@0 102 * Sets the insulated flag.
Chris@0 103 *
Chris@0 104 * @param bool $insulated Whether to insulate the requests or not
Chris@0 105 *
Chris@0 106 * @throws \RuntimeException When Symfony Process Component is not installed
Chris@0 107 */
Chris@0 108 public function insulate($insulated = true)
Chris@0 109 {
Chris@0 110 if ($insulated && !class_exists('Symfony\\Component\\Process\\Process')) {
Chris@0 111 throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.');
Chris@0 112 }
Chris@0 113
Chris@0 114 $this->insulated = (bool) $insulated;
Chris@0 115 }
Chris@0 116
Chris@0 117 /**
Chris@0 118 * Sets server parameters.
Chris@0 119 *
Chris@0 120 * @param array $server An array of server parameters
Chris@0 121 */
Chris@0 122 public function setServerParameters(array $server)
Chris@0 123 {
Chris@0 124 $this->server = array_merge(array(
Chris@0 125 'HTTP_USER_AGENT' => 'Symfony BrowserKit',
Chris@0 126 ), $server);
Chris@0 127 }
Chris@0 128
Chris@0 129 /**
Chris@0 130 * Sets single server parameter.
Chris@0 131 *
Chris@0 132 * @param string $key A key of the parameter
Chris@0 133 * @param string $value A value of the parameter
Chris@0 134 */
Chris@0 135 public function setServerParameter($key, $value)
Chris@0 136 {
Chris@0 137 $this->server[$key] = $value;
Chris@0 138 }
Chris@0 139
Chris@0 140 /**
Chris@0 141 * Gets single server parameter for specified key.
Chris@0 142 *
Chris@0 143 * @param string $key A key of the parameter to get
Chris@0 144 * @param string $default A default value when key is undefined
Chris@0 145 *
Chris@0 146 * @return string A value of the parameter
Chris@0 147 */
Chris@0 148 public function getServerParameter($key, $default = '')
Chris@0 149 {
Chris@0 150 return isset($this->server[$key]) ? $this->server[$key] : $default;
Chris@0 151 }
Chris@0 152
Chris@0 153 /**
Chris@0 154 * Returns the History instance.
Chris@0 155 *
Chris@0 156 * @return History A History instance
Chris@0 157 */
Chris@0 158 public function getHistory()
Chris@0 159 {
Chris@0 160 return $this->history;
Chris@0 161 }
Chris@0 162
Chris@0 163 /**
Chris@0 164 * Returns the CookieJar instance.
Chris@0 165 *
Chris@0 166 * @return CookieJar A CookieJar instance
Chris@0 167 */
Chris@0 168 public function getCookieJar()
Chris@0 169 {
Chris@0 170 return $this->cookieJar;
Chris@0 171 }
Chris@0 172
Chris@0 173 /**
Chris@0 174 * Returns the current Crawler instance.
Chris@0 175 *
Chris@0 176 * @return Crawler|null A Crawler instance
Chris@0 177 */
Chris@0 178 public function getCrawler()
Chris@0 179 {
Chris@0 180 return $this->crawler;
Chris@0 181 }
Chris@0 182
Chris@0 183 /**
Chris@0 184 * Returns the current BrowserKit Response instance.
Chris@0 185 *
Chris@0 186 * @return Response|null A BrowserKit Response instance
Chris@0 187 */
Chris@0 188 public function getInternalResponse()
Chris@0 189 {
Chris@0 190 return $this->internalResponse;
Chris@0 191 }
Chris@0 192
Chris@0 193 /**
Chris@0 194 * Returns the current origin response instance.
Chris@0 195 *
Chris@0 196 * The origin response is the response instance that is returned
Chris@0 197 * by the code that handles requests.
Chris@0 198 *
Chris@0 199 * @return object|null A response instance
Chris@0 200 *
Chris@0 201 * @see doRequest()
Chris@0 202 */
Chris@0 203 public function getResponse()
Chris@0 204 {
Chris@0 205 return $this->response;
Chris@0 206 }
Chris@0 207
Chris@0 208 /**
Chris@0 209 * Returns the current BrowserKit Request instance.
Chris@0 210 *
Chris@0 211 * @return Request|null A BrowserKit Request instance
Chris@0 212 */
Chris@0 213 public function getInternalRequest()
Chris@0 214 {
Chris@0 215 return $this->internalRequest;
Chris@0 216 }
Chris@0 217
Chris@0 218 /**
Chris@0 219 * Returns the current origin Request instance.
Chris@0 220 *
Chris@0 221 * The origin request is the request instance that is sent
Chris@0 222 * to the code that handles requests.
Chris@0 223 *
Chris@0 224 * @return object|null A Request instance
Chris@0 225 *
Chris@0 226 * @see doRequest()
Chris@0 227 */
Chris@0 228 public function getRequest()
Chris@0 229 {
Chris@0 230 return $this->request;
Chris@0 231 }
Chris@0 232
Chris@0 233 /**
Chris@0 234 * Clicks on a given link.
Chris@0 235 *
Chris@0 236 * @return Crawler
Chris@0 237 */
Chris@0 238 public function click(Link $link)
Chris@0 239 {
Chris@0 240 if ($link instanceof Form) {
Chris@0 241 return $this->submit($link);
Chris@0 242 }
Chris@0 243
Chris@0 244 return $this->request($link->getMethod(), $link->getUri());
Chris@0 245 }
Chris@0 246
Chris@0 247 /**
Chris@0 248 * Submits a form.
Chris@0 249 *
Chris@0 250 * @param Form $form A Form instance
Chris@0 251 * @param array $values An array of form field values
Chris@0 252 *
Chris@0 253 * @return Crawler
Chris@0 254 */
Chris@0 255 public function submit(Form $form, array $values = array())
Chris@0 256 {
Chris@0 257 $form->setValues($values);
Chris@0 258
Chris@0 259 return $this->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), $form->getPhpFiles());
Chris@0 260 }
Chris@0 261
Chris@0 262 /**
Chris@0 263 * Calls a URI.
Chris@0 264 *
Chris@0 265 * @param string $method The request method
Chris@0 266 * @param string $uri The URI to fetch
Chris@0 267 * @param array $parameters The Request parameters
Chris@0 268 * @param array $files The files
Chris@0 269 * @param array $server The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does)
Chris@0 270 * @param string $content The raw body data
Chris@0 271 * @param bool $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload())
Chris@0 272 *
Chris@0 273 * @return Crawler
Chris@0 274 */
Chris@0 275 public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true)
Chris@0 276 {
Chris@0 277 if ($this->isMainRequest) {
Chris@0 278 $this->redirectCount = 0;
Chris@0 279 } else {
Chris@0 280 ++$this->redirectCount;
Chris@0 281 }
Chris@0 282
Chris@0 283 $uri = $this->getAbsoluteUri($uri);
Chris@0 284
Chris@0 285 $server = array_merge($this->server, $server);
Chris@0 286
Chris@0 287 if (isset($server['HTTPS'])) {
Chris@0 288 $uri = preg_replace('{^'.parse_url($uri, PHP_URL_SCHEME).'}', $server['HTTPS'] ? 'https' : 'http', $uri);
Chris@0 289 }
Chris@0 290
Chris@0 291 if (!$this->history->isEmpty()) {
Chris@0 292 $server['HTTP_REFERER'] = $this->history->current()->getUri();
Chris@0 293 }
Chris@0 294
Chris@0 295 if (empty($server['HTTP_HOST'])) {
Chris@0 296 $server['HTTP_HOST'] = $this->extractHost($uri);
Chris@0 297 }
Chris@0 298
Chris@0 299 $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
Chris@0 300
Chris@0 301 $this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);
Chris@0 302
Chris@0 303 $this->request = $this->filterRequest($this->internalRequest);
Chris@0 304
Chris@0 305 if (true === $changeHistory) {
Chris@0 306 $this->history->add($this->internalRequest);
Chris@0 307 }
Chris@0 308
Chris@0 309 if ($this->insulated) {
Chris@0 310 $this->response = $this->doRequestInProcess($this->request);
Chris@0 311 } else {
Chris@0 312 $this->response = $this->doRequest($this->request);
Chris@0 313 }
Chris@0 314
Chris@0 315 $this->internalResponse = $this->filterResponse($this->response);
Chris@0 316
Chris@0 317 $this->cookieJar->updateFromResponse($this->internalResponse, $uri);
Chris@0 318
Chris@0 319 $status = $this->internalResponse->getStatus();
Chris@0 320
Chris@0 321 if ($status >= 300 && $status < 400) {
Chris@0 322 $this->redirect = $this->internalResponse->getHeader('Location');
Chris@0 323 } else {
Chris@0 324 $this->redirect = null;
Chris@0 325 }
Chris@0 326
Chris@0 327 if ($this->followRedirects && $this->redirect) {
Chris@12 328 $this->redirects[serialize($this->history->current())] = true;
Chris@12 329
Chris@0 330 return $this->crawler = $this->followRedirect();
Chris@0 331 }
Chris@0 332
Chris@0 333 return $this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
Chris@0 334 }
Chris@0 335
Chris@0 336 /**
Chris@0 337 * Makes a request in another process.
Chris@0 338 *
Chris@0 339 * @param object $request An origin request instance
Chris@0 340 *
Chris@0 341 * @return object An origin response instance
Chris@0 342 *
Chris@0 343 * @throws \RuntimeException When processing returns exit code
Chris@0 344 */
Chris@0 345 protected function doRequestInProcess($request)
Chris@0 346 {
Chris@12 347 $deprecationsFile = tempnam(sys_get_temp_dir(), 'deprec');
Chris@12 348 putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$deprecationsFile);
Chris@12 349 $_ENV['SYMFONY_DEPRECATIONS_SERIALIZE'] = $deprecationsFile;
Chris@0 350 $process = new PhpProcess($this->getScript($request), null, null);
Chris@0 351 $process->run();
Chris@0 352
Chris@12 353 if (file_exists($deprecationsFile)) {
Chris@12 354 $deprecations = file_get_contents($deprecationsFile);
Chris@12 355 unlink($deprecationsFile);
Chris@12 356 foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) {
Chris@12 357 if ($deprecation[0]) {
Chris@12 358 trigger_error($deprecation[1], E_USER_DEPRECATED);
Chris@12 359 } else {
Chris@12 360 @trigger_error($deprecation[1], E_USER_DEPRECATED);
Chris@12 361 }
Chris@12 362 }
Chris@12 363 }
Chris@12 364
Chris@0 365 if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) {
Chris@0 366 throw new \RuntimeException(sprintf('OUTPUT: %s ERROR OUTPUT: %s', $process->getOutput(), $process->getErrorOutput()));
Chris@0 367 }
Chris@0 368
Chris@0 369 return unserialize($process->getOutput());
Chris@0 370 }
Chris@0 371
Chris@0 372 /**
Chris@0 373 * Makes a request.
Chris@0 374 *
Chris@0 375 * @param object $request An origin request instance
Chris@0 376 *
Chris@0 377 * @return object An origin response instance
Chris@0 378 */
Chris@0 379 abstract protected function doRequest($request);
Chris@0 380
Chris@0 381 /**
Chris@0 382 * Returns the script to execute when the request must be insulated.
Chris@0 383 *
Chris@0 384 * @param object $request An origin request instance
Chris@0 385 *
Chris@0 386 * @throws \LogicException When this abstract class is not implemented
Chris@0 387 */
Chris@0 388 protected function getScript($request)
Chris@0 389 {
Chris@0 390 throw new \LogicException('To insulate requests, you need to override the getScript() method.');
Chris@0 391 }
Chris@0 392
Chris@0 393 /**
Chris@0 394 * Filters the BrowserKit request to the origin one.
Chris@0 395 *
Chris@0 396 * @param Request $request The BrowserKit Request to filter
Chris@0 397 *
Chris@0 398 * @return object An origin request instance
Chris@0 399 */
Chris@0 400 protected function filterRequest(Request $request)
Chris@0 401 {
Chris@0 402 return $request;
Chris@0 403 }
Chris@0 404
Chris@0 405 /**
Chris@0 406 * Filters the origin response to the BrowserKit one.
Chris@0 407 *
Chris@0 408 * @param object $response The origin response to filter
Chris@0 409 *
Chris@0 410 * @return Response An BrowserKit Response instance
Chris@0 411 */
Chris@0 412 protected function filterResponse($response)
Chris@0 413 {
Chris@0 414 return $response;
Chris@0 415 }
Chris@0 416
Chris@0 417 /**
Chris@0 418 * Creates a crawler.
Chris@0 419 *
Chris@0 420 * This method returns null if the DomCrawler component is not available.
Chris@0 421 *
Chris@0 422 * @param string $uri A URI
Chris@0 423 * @param string $content Content for the crawler to use
Chris@0 424 * @param string $type Content type
Chris@0 425 *
Chris@0 426 * @return Crawler|null
Chris@0 427 */
Chris@0 428 protected function createCrawlerFromContent($uri, $content, $type)
Chris@0 429 {
Chris@0 430 if (!class_exists('Symfony\Component\DomCrawler\Crawler')) {
Chris@0 431 return;
Chris@0 432 }
Chris@0 433
Chris@0 434 $crawler = new Crawler(null, $uri);
Chris@0 435 $crawler->addContent($content, $type);
Chris@0 436
Chris@0 437 return $crawler;
Chris@0 438 }
Chris@0 439
Chris@0 440 /**
Chris@0 441 * Goes back in the browser history.
Chris@0 442 *
Chris@0 443 * @return Crawler
Chris@0 444 */
Chris@0 445 public function back()
Chris@0 446 {
Chris@12 447 do {
Chris@12 448 $request = $this->history->back();
Chris@12 449 } while (array_key_exists(serialize($request), $this->redirects));
Chris@12 450
Chris@12 451 return $this->requestFromRequest($request, false);
Chris@0 452 }
Chris@0 453
Chris@0 454 /**
Chris@0 455 * Goes forward in the browser history.
Chris@0 456 *
Chris@0 457 * @return Crawler
Chris@0 458 */
Chris@0 459 public function forward()
Chris@0 460 {
Chris@12 461 do {
Chris@12 462 $request = $this->history->forward();
Chris@12 463 } while (array_key_exists(serialize($request), $this->redirects));
Chris@12 464
Chris@12 465 return $this->requestFromRequest($request, false);
Chris@0 466 }
Chris@0 467
Chris@0 468 /**
Chris@0 469 * Reloads the current browser.
Chris@0 470 *
Chris@0 471 * @return Crawler
Chris@0 472 */
Chris@0 473 public function reload()
Chris@0 474 {
Chris@0 475 return $this->requestFromRequest($this->history->current(), false);
Chris@0 476 }
Chris@0 477
Chris@0 478 /**
Chris@0 479 * Follow redirects?
Chris@0 480 *
Chris@0 481 * @return Crawler
Chris@0 482 *
Chris@0 483 * @throws \LogicException If request was not a redirect
Chris@0 484 */
Chris@0 485 public function followRedirect()
Chris@0 486 {
Chris@0 487 if (empty($this->redirect)) {
Chris@0 488 throw new \LogicException('The request was not redirected.');
Chris@0 489 }
Chris@0 490
Chris@0 491 if (-1 !== $this->maxRedirects) {
Chris@0 492 if ($this->redirectCount > $this->maxRedirects) {
Chris@12 493 $this->redirectCount = 0;
Chris@0 494 throw new \LogicException(sprintf('The maximum number (%d) of redirections was reached.', $this->maxRedirects));
Chris@0 495 }
Chris@0 496 }
Chris@0 497
Chris@0 498 $request = $this->internalRequest;
Chris@0 499
Chris@12 500 if (in_array($this->internalResponse->getStatus(), array(301, 302, 303))) {
Chris@0 501 $method = 'GET';
Chris@0 502 $files = array();
Chris@0 503 $content = null;
Chris@0 504 } else {
Chris@0 505 $method = $request->getMethod();
Chris@0 506 $files = $request->getFiles();
Chris@0 507 $content = $request->getContent();
Chris@0 508 }
Chris@0 509
Chris@0 510 if ('GET' === strtoupper($method)) {
Chris@0 511 // Don't forward parameters for GET request as it should reach the redirection URI
Chris@0 512 $parameters = array();
Chris@0 513 } else {
Chris@0 514 $parameters = $request->getParameters();
Chris@0 515 }
Chris@0 516
Chris@0 517 $server = $request->getServer();
Chris@0 518 $server = $this->updateServerFromUri($server, $this->redirect);
Chris@0 519
Chris@0 520 $this->isMainRequest = false;
Chris@0 521
Chris@0 522 $response = $this->request($method, $this->redirect, $parameters, $files, $server, $content);
Chris@0 523
Chris@0 524 $this->isMainRequest = true;
Chris@0 525
Chris@0 526 return $response;
Chris@0 527 }
Chris@0 528
Chris@0 529 /**
Chris@0 530 * Restarts the client.
Chris@0 531 *
Chris@0 532 * It flushes history and all cookies.
Chris@0 533 */
Chris@0 534 public function restart()
Chris@0 535 {
Chris@0 536 $this->cookieJar->clear();
Chris@0 537 $this->history->clear();
Chris@0 538 }
Chris@0 539
Chris@0 540 /**
Chris@0 541 * Takes a URI and converts it to absolute if it is not already absolute.
Chris@0 542 *
Chris@0 543 * @param string $uri A URI
Chris@0 544 *
Chris@0 545 * @return string An absolute URI
Chris@0 546 */
Chris@0 547 protected function getAbsoluteUri($uri)
Chris@0 548 {
Chris@0 549 // already absolute?
Chris@0 550 if (0 === strpos($uri, 'http://') || 0 === strpos($uri, 'https://')) {
Chris@0 551 return $uri;
Chris@0 552 }
Chris@0 553
Chris@0 554 if (!$this->history->isEmpty()) {
Chris@0 555 $currentUri = $this->history->current()->getUri();
Chris@0 556 } else {
Chris@0 557 $currentUri = sprintf('http%s://%s/',
Chris@0 558 isset($this->server['HTTPS']) ? 's' : '',
Chris@0 559 isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost'
Chris@0 560 );
Chris@0 561 }
Chris@0 562
Chris@0 563 // protocol relative URL
Chris@0 564 if (0 === strpos($uri, '//')) {
Chris@0 565 return parse_url($currentUri, PHP_URL_SCHEME).':'.$uri;
Chris@0 566 }
Chris@0 567
Chris@0 568 // anchor or query string parameters?
Chris@0 569 if (!$uri || '#' == $uri[0] || '?' == $uri[0]) {
Chris@0 570 return preg_replace('/[#?].*?$/', '', $currentUri).$uri;
Chris@0 571 }
Chris@0 572
Chris@0 573 if ('/' !== $uri[0]) {
Chris@0 574 $path = parse_url($currentUri, PHP_URL_PATH);
Chris@0 575
Chris@0 576 if ('/' !== substr($path, -1)) {
Chris@0 577 $path = substr($path, 0, strrpos($path, '/') + 1);
Chris@0 578 }
Chris@0 579
Chris@0 580 $uri = $path.$uri;
Chris@0 581 }
Chris@0 582
Chris@0 583 return preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $currentUri).$uri;
Chris@0 584 }
Chris@0 585
Chris@0 586 /**
Chris@0 587 * Makes a request from a Request object directly.
Chris@0 588 *
Chris@0 589 * @param Request $request A Request instance
Chris@0 590 * @param bool $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload())
Chris@0 591 *
Chris@0 592 * @return Crawler
Chris@0 593 */
Chris@0 594 protected function requestFromRequest(Request $request, $changeHistory = true)
Chris@0 595 {
Chris@0 596 return $this->request($request->getMethod(), $request->getUri(), $request->getParameters(), $request->getFiles(), $request->getServer(), $request->getContent(), $changeHistory);
Chris@0 597 }
Chris@0 598
Chris@0 599 private function updateServerFromUri($server, $uri)
Chris@0 600 {
Chris@0 601 $server['HTTP_HOST'] = $this->extractHost($uri);
Chris@0 602 $scheme = parse_url($uri, PHP_URL_SCHEME);
Chris@0 603 $server['HTTPS'] = null === $scheme ? $server['HTTPS'] : 'https' == $scheme;
Chris@0 604 unset($server['HTTP_IF_NONE_MATCH'], $server['HTTP_IF_MODIFIED_SINCE']);
Chris@0 605
Chris@0 606 return $server;
Chris@0 607 }
Chris@0 608
Chris@0 609 private function extractHost($uri)
Chris@0 610 {
Chris@0 611 $host = parse_url($uri, PHP_URL_HOST);
Chris@0 612
Chris@0 613 if ($port = parse_url($uri, PHP_URL_PORT)) {
Chris@0 614 return $host.':'.$port;
Chris@0 615 }
Chris@0 616
Chris@0 617 return $host;
Chris@0 618 }
Chris@0 619 }