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\HttpKernel;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\BrowserKit\Client as BaseClient;
|
Chris@0
|
15 use Symfony\Component\BrowserKit\Request as DomRequest;
|
Chris@0
|
16 use Symfony\Component\BrowserKit\Response as DomResponse;
|
Chris@0
|
17 use Symfony\Component\BrowserKit\Cookie as DomCookie;
|
Chris@0
|
18 use Symfony\Component\BrowserKit\History;
|
Chris@0
|
19 use Symfony\Component\BrowserKit\CookieJar;
|
Chris@0
|
20 use Symfony\Component\HttpFoundation\File\UploadedFile;
|
Chris@0
|
21 use Symfony\Component\HttpFoundation\Request;
|
Chris@0
|
22 use Symfony\Component\HttpFoundation\Response;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * Client simulates a browser and makes requests to a Kernel object.
|
Chris@0
|
26 *
|
Chris@0
|
27 * @author Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
28 *
|
Chris@0
|
29 * @method Request|null getRequest() A Request instance
|
Chris@0
|
30 * @method Response|null getResponse() A Response instance
|
Chris@0
|
31 */
|
Chris@0
|
32 class Client extends BaseClient
|
Chris@0
|
33 {
|
Chris@0
|
34 protected $kernel;
|
Chris@0
|
35
|
Chris@0
|
36 /**
|
Chris@0
|
37 * Constructor.
|
Chris@0
|
38 *
|
Chris@0
|
39 * @param HttpKernelInterface $kernel An HttpKernel instance
|
Chris@0
|
40 * @param array $server The server parameters (equivalent of $_SERVER)
|
Chris@0
|
41 * @param History $history A History instance to store the browser history
|
Chris@0
|
42 * @param CookieJar $cookieJar A CookieJar instance to store the cookies
|
Chris@0
|
43 */
|
Chris@0
|
44 public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null)
|
Chris@0
|
45 {
|
Chris@0
|
46 // These class properties must be set before calling the parent constructor, as it may depend on it.
|
Chris@0
|
47 $this->kernel = $kernel;
|
Chris@0
|
48 $this->followRedirects = false;
|
Chris@0
|
49
|
Chris@0
|
50 parent::__construct($server, $history, $cookieJar);
|
Chris@0
|
51 }
|
Chris@0
|
52
|
Chris@0
|
53 /**
|
Chris@0
|
54 * Makes a request.
|
Chris@0
|
55 *
|
Chris@0
|
56 * @param Request $request A Request instance
|
Chris@0
|
57 *
|
Chris@0
|
58 * @return Response A Response instance
|
Chris@0
|
59 */
|
Chris@0
|
60 protected function doRequest($request)
|
Chris@0
|
61 {
|
Chris@0
|
62 $response = $this->kernel->handle($request);
|
Chris@0
|
63
|
Chris@0
|
64 if ($this->kernel instanceof TerminableInterface) {
|
Chris@0
|
65 $this->kernel->terminate($request, $response);
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 return $response;
|
Chris@0
|
69 }
|
Chris@0
|
70
|
Chris@0
|
71 /**
|
Chris@0
|
72 * Returns the script to execute when the request must be insulated.
|
Chris@0
|
73 *
|
Chris@0
|
74 * @param Request $request A Request instance
|
Chris@0
|
75 *
|
Chris@0
|
76 * @return string
|
Chris@0
|
77 */
|
Chris@0
|
78 protected function getScript($request)
|
Chris@0
|
79 {
|
Chris@0
|
80 $kernel = str_replace("'", "\\'", serialize($this->kernel));
|
Chris@0
|
81 $request = str_replace("'", "\\'", serialize($request));
|
Chris@0
|
82
|
Chris@0
|
83 $r = new \ReflectionClass('\\Symfony\\Component\\ClassLoader\\ClassLoader');
|
Chris@0
|
84 $requirePath = str_replace("'", "\\'", $r->getFileName());
|
Chris@0
|
85 $symfonyPath = str_replace("'", "\\'", dirname(dirname(dirname(__DIR__))));
|
Chris@0
|
86 $errorReporting = error_reporting();
|
Chris@0
|
87
|
Chris@0
|
88 $code = <<<EOF
|
Chris@0
|
89 <?php
|
Chris@0
|
90
|
Chris@0
|
91 error_reporting($errorReporting);
|
Chris@0
|
92
|
Chris@0
|
93 require_once '$requirePath';
|
Chris@0
|
94
|
Chris@0
|
95 \$loader = new Symfony\Component\ClassLoader\ClassLoader();
|
Chris@0
|
96 \$loader->addPrefix('Symfony', '$symfonyPath');
|
Chris@0
|
97 \$loader->register();
|
Chris@0
|
98
|
Chris@0
|
99 \$kernel = unserialize('$kernel');
|
Chris@0
|
100 \$request = unserialize('$request');
|
Chris@0
|
101 EOF;
|
Chris@0
|
102
|
Chris@0
|
103 return $code.$this->getHandleScript();
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 protected function getHandleScript()
|
Chris@0
|
107 {
|
Chris@0
|
108 return <<<'EOF'
|
Chris@0
|
109 $response = $kernel->handle($request);
|
Chris@0
|
110
|
Chris@0
|
111 if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
|
Chris@0
|
112 $kernel->terminate($request, $response);
|
Chris@0
|
113 }
|
Chris@0
|
114
|
Chris@0
|
115 echo serialize($response);
|
Chris@0
|
116 EOF;
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119 /**
|
Chris@0
|
120 * Converts the BrowserKit request to a HttpKernel request.
|
Chris@0
|
121 *
|
Chris@0
|
122 * @param DomRequest $request A DomRequest instance
|
Chris@0
|
123 *
|
Chris@0
|
124 * @return Request A Request instance
|
Chris@0
|
125 */
|
Chris@0
|
126 protected function filterRequest(DomRequest $request)
|
Chris@0
|
127 {
|
Chris@0
|
128 $httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
|
Chris@0
|
129
|
Chris@0
|
130 foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
|
Chris@0
|
131 $httpRequest->files->set($key, $value);
|
Chris@0
|
132 }
|
Chris@0
|
133
|
Chris@0
|
134 return $httpRequest;
|
Chris@0
|
135 }
|
Chris@0
|
136
|
Chris@0
|
137 /**
|
Chris@0
|
138 * Filters an array of files.
|
Chris@0
|
139 *
|
Chris@0
|
140 * This method created test instances of UploadedFile so that the move()
|
Chris@0
|
141 * method can be called on those instances.
|
Chris@0
|
142 *
|
Chris@0
|
143 * If the size of a file is greater than the allowed size (from php.ini) then
|
Chris@0
|
144 * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
|
Chris@0
|
145 *
|
Chris@0
|
146 * @see UploadedFile
|
Chris@0
|
147 *
|
Chris@0
|
148 * @param array $files An array of files
|
Chris@0
|
149 *
|
Chris@0
|
150 * @return array An array with all uploaded files marked as already moved
|
Chris@0
|
151 */
|
Chris@0
|
152 protected function filterFiles(array $files)
|
Chris@0
|
153 {
|
Chris@0
|
154 $filtered = array();
|
Chris@0
|
155 foreach ($files as $key => $value) {
|
Chris@0
|
156 if (is_array($value)) {
|
Chris@0
|
157 $filtered[$key] = $this->filterFiles($value);
|
Chris@0
|
158 } elseif ($value instanceof UploadedFile) {
|
Chris@0
|
159 if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
|
Chris@0
|
160 $filtered[$key] = new UploadedFile(
|
Chris@0
|
161 '',
|
Chris@0
|
162 $value->getClientOriginalName(),
|
Chris@0
|
163 $value->getClientMimeType(),
|
Chris@0
|
164 0,
|
Chris@0
|
165 UPLOAD_ERR_INI_SIZE,
|
Chris@0
|
166 true
|
Chris@0
|
167 );
|
Chris@0
|
168 } else {
|
Chris@0
|
169 $filtered[$key] = new UploadedFile(
|
Chris@0
|
170 $value->getPathname(),
|
Chris@0
|
171 $value->getClientOriginalName(),
|
Chris@0
|
172 $value->getClientMimeType(),
|
Chris@0
|
173 $value->getClientSize(),
|
Chris@0
|
174 $value->getError(),
|
Chris@0
|
175 true
|
Chris@0
|
176 );
|
Chris@0
|
177 }
|
Chris@0
|
178 }
|
Chris@0
|
179 }
|
Chris@0
|
180
|
Chris@0
|
181 return $filtered;
|
Chris@0
|
182 }
|
Chris@0
|
183
|
Chris@0
|
184 /**
|
Chris@0
|
185 * Converts the HttpKernel response to a BrowserKit response.
|
Chris@0
|
186 *
|
Chris@0
|
187 * @param Response $response A Response instance
|
Chris@0
|
188 *
|
Chris@0
|
189 * @return DomResponse A DomResponse instance
|
Chris@0
|
190 */
|
Chris@0
|
191 protected function filterResponse($response)
|
Chris@0
|
192 {
|
Chris@0
|
193 $headers = $response->headers->all();
|
Chris@0
|
194 if ($response->headers->getCookies()) {
|
Chris@0
|
195 $cookies = array();
|
Chris@0
|
196 foreach ($response->headers->getCookies() as $cookie) {
|
Chris@0
|
197 $cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
Chris@0
|
198 }
|
Chris@0
|
199 $headers['Set-Cookie'] = $cookies;
|
Chris@0
|
200 }
|
Chris@0
|
201
|
Chris@0
|
202 // this is needed to support StreamedResponse
|
Chris@0
|
203 ob_start();
|
Chris@0
|
204 $response->sendContent();
|
Chris@0
|
205 $content = ob_get_clean();
|
Chris@0
|
206
|
Chris@0
|
207 return new DomResponse($content, $response->getStatusCode(), $headers);
|
Chris@0
|
208 }
|
Chris@0
|
209 }
|