4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel;
14 use Symfony\Component\BrowserKit\Client as BaseClient;
15 use Symfony\Component\BrowserKit\CookieJar;
16 use Symfony\Component\BrowserKit\History;
17 use Symfony\Component\BrowserKit\Request as DomRequest;
18 use Symfony\Component\BrowserKit\Response as DomResponse;
19 use Symfony\Component\HttpFoundation\File\UploadedFile;
20 use Symfony\Component\HttpFoundation\Request;
21 use Symfony\Component\HttpFoundation\Response;
24 * Client simulates a browser and makes requests to a Kernel object.
26 * @author Fabien Potencier <fabien@symfony.com>
28 * @method Request|null getRequest() A Request instance
29 * @method Response|null getResponse() A Response instance
31 class Client extends BaseClient
34 private $catchExceptions = true;
37 * @param HttpKernelInterface $kernel An HttpKernel instance
38 * @param array $server The server parameters (equivalent of $_SERVER)
39 * @param History $history A History instance to store the browser history
40 * @param CookieJar $cookieJar A CookieJar instance to store the cookies
42 public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null)
44 // These class properties must be set before calling the parent constructor, as it may depend on it.
45 $this->kernel = $kernel;
46 $this->followRedirects = false;
48 parent::__construct($server, $history, $cookieJar);
52 * Sets whether to catch exceptions when the kernel is handling a request.
54 * @param bool $catchExceptions Whether to catch exceptions
56 public function catchExceptions($catchExceptions)
58 $this->catchExceptions = $catchExceptions;
64 * @return Response A Response instance
66 protected function doRequest($request)
68 $response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $this->catchExceptions);
70 if ($this->kernel instanceof TerminableInterface) {
71 $this->kernel->terminate($request, $response);
78 * Returns the script to execute when the request must be insulated.
82 protected function getScript($request)
84 $kernel = var_export(serialize($this->kernel), true);
85 $request = var_export(serialize($request), true);
87 $errorReporting = error_reporting();
90 foreach (get_declared_classes() as $class) {
91 if (0 === strpos($class, 'ComposerAutoloaderInit')) {
92 $r = new \ReflectionClass($class);
93 $file = \dirname(\dirname($r->getFileName())).'/autoload.php';
94 if (file_exists($file)) {
95 $requires .= 'require_once '.var_export($file, true).";\n";
101 throw new \RuntimeException('Composer autoloader not found.');
107 error_reporting($errorReporting);
111 \$kernel = unserialize($kernel);
112 \$request = unserialize($request);
115 return $code.$this->getHandleScript();
118 protected function getHandleScript()
121 $response = $kernel->handle($request);
123 if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
124 $kernel->terminate($request, $response);
127 echo serialize($response);
132 * Converts the BrowserKit request to a HttpKernel request.
134 * @return Request A Request instance
136 protected function filterRequest(DomRequest $request)
138 $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
140 foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
141 $httpRequest->files->set($key, $value);
148 * Filters an array of files.
150 * This method created test instances of UploadedFile so that the move()
151 * method can be called on those instances.
153 * If the size of a file is greater than the allowed size (from php.ini) then
154 * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
158 * @return array An array with all uploaded files marked as already moved
160 protected function filterFiles(array $files)
163 foreach ($files as $key => $value) {
164 if (\is_array($value)) {
165 $filtered[$key] = $this->filterFiles($value);
166 } elseif ($value instanceof UploadedFile) {
167 if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
168 $filtered[$key] = new UploadedFile(
170 $value->getClientOriginalName(),
171 $value->getClientMimeType(),
177 $filtered[$key] = new UploadedFile(
178 $value->getPathname(),
179 $value->getClientOriginalName(),
180 $value->getClientMimeType(),
181 $value->getClientSize(),
193 * Converts the HttpKernel response to a BrowserKit response.
195 * @return DomResponse A DomResponse instance
197 protected function filterResponse($response)
199 // this is needed to support StreamedResponse
201 $response->sendContent();
202 $content = ob_get_clean();
204 return new DomResponse($content, $response->getStatusCode(), $response->headers->all());