9be8ea7733337bf73ae4788a9f845357181dedb0
[yaffs-website] / vendor / fabpot / goutte / Goutte / Client.php
1 <?php
2
3 /*
4  * This file is part of the Goutte package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Goutte;
13
14 use GuzzleHttp\Client as GuzzleClient;
15 use GuzzleHttp\ClientInterface as GuzzleClientInterface;
16 use GuzzleHttp\Cookie\CookieJar;
17 use GuzzleHttp\Exception\RequestException;
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\UriInterface;
20 use Symfony\Component\BrowserKit\Client as BaseClient;
21 use Symfony\Component\BrowserKit\Request;
22 use Symfony\Component\BrowserKit\Response;
23
24 /**
25  * Client.
26  *
27  * @author Fabien Potencier <fabien.potencier@symfony-project.com>
28  * @author Michael Dowling <michael@guzzlephp.org>
29  * @author Charles Sarrazin <charles@sarraz.in>
30  * @author Kévin Dunglas <dunglas@gmail.com>
31  */
32 class Client extends BaseClient
33 {
34     protected $client;
35
36     private $headers = array();
37     private $auth;
38
39     public function setClient(GuzzleClientInterface $client)
40     {
41         $this->client = $client;
42
43         /**
44          * @var $baseUri UriInterface
45          */
46         if (null !== $this->getServerParameter('HTTP_HOST', null) || null === $baseUri = $client->getConfig('base_uri')) {
47             return $this;
48         }
49
50         $path = $baseUri->getPath();
51         if ('' !== $path && '/' !== $path) {
52             throw new \InvalidArgumentException('Setting a path in the Guzzle "base_uri" config option is not supported by Goutte yet.');
53         }
54
55         if (null === $this->getServerParameter('HTTPS', null) && 'https' === $baseUri->getScheme()) {
56             $this->setServerParameter('HTTPS', 'on');
57         }
58
59         $host = $baseUri->getHost();
60         if (null !== $port = $baseUri->getPort()) {
61             $host .= ":$port";
62         }
63
64         $this->setServerParameter('HTTP_HOST', $host);
65
66         return $this;
67     }
68
69     public function getClient()
70     {
71         if (!$this->client) {
72             $this->client = new GuzzleClient(array('allow_redirects' => false, 'cookies' => true));
73         }
74
75         return $this->client;
76     }
77
78     public function setHeader($name, $value)
79     {
80         $this->headers[strtolower($name)] = $value;
81
82         return $this;
83     }
84
85     public function removeHeader($name)
86     {
87         unset($this->headers[strtolower($name)]);
88     }
89
90     public function resetHeaders()
91     {
92         $this->headers = array();
93
94         return $this;
95     }
96
97     /**
98      * {@inheritdoc}
99      */
100     public function restart()
101     {
102         parent::restart();
103         $this->resetAuth()
104              ->resetHeaders();
105     }
106
107     public function setAuth($user, $password = '', $type = 'basic')
108     {
109         $this->auth = array($user, $password, $type);
110
111         return $this;
112     }
113
114     public function resetAuth()
115     {
116         $this->auth = null;
117
118         return $this;
119     }
120
121     /**
122      * @param Request $request
123      *
124      * @return Response
125      */
126     protected function doRequest($request)
127     {
128         $headers = array();
129         foreach ($request->getServer() as $key => $val) {
130             $key = strtolower(str_replace('_', '-', $key));
131             $contentHeaders = array('content-length' => true, 'content-md5' => true, 'content-type' => true);
132             if (0 === strpos($key, 'http-')) {
133                 $headers[substr($key, 5)] = $val;
134             }
135             // CONTENT_* are not prefixed with HTTP_
136             elseif (isset($contentHeaders[$key])) {
137                 $headers[$key] = $val;
138             }
139         }
140
141         $cookies = CookieJar::fromArray(
142             $this->getCookieJar()->allRawValues($request->getUri()),
143             parse_url($request->getUri(), PHP_URL_HOST)
144         );
145
146         $requestOptions = array(
147             'cookies' => $cookies,
148             'allow_redirects' => false,
149             'auth' => $this->auth,
150         );
151
152         if (!in_array($request->getMethod(), array('GET', 'HEAD'))) {
153             if (null !== $content = $request->getContent()) {
154                 $requestOptions['body'] = $content;
155             } else {
156                 if ($files = $request->getFiles()) {
157                     $requestOptions['multipart'] = [];
158
159                     $this->addPostFields($request->getParameters(), $requestOptions['multipart']);
160                     $this->addPostFiles($files, $requestOptions['multipart']);
161                 } else {
162                     $requestOptions['form_params'] = $request->getParameters();
163                 }
164             }
165         }
166
167         if (!empty($headers)) {
168             $requestOptions['headers'] = $headers;
169         }
170
171         $method = $request->getMethod();
172         $uri = $request->getUri();
173
174         foreach ($this->headers as $name => $value) {
175             $requestOptions['headers'][$name] = $value;
176         }
177
178         // Let BrowserKit handle redirects
179         try {
180             $response = $this->getClient()->request($method, $uri, $requestOptions);
181         } catch (RequestException $e) {
182             $response = $e->getResponse();
183             if (null === $response) {
184                 throw $e;
185             }
186         }
187
188         return $this->createResponse($response);
189     }
190
191     protected function addPostFiles(array $files, array &$multipart, $arrayName = '')
192     {
193         if (empty($files)) {
194             return;
195         }
196
197         foreach ($files as $name => $info) {
198             if (!empty($arrayName)) {
199                 $name = $arrayName.'['.$name.']';
200             }
201
202             $file = [
203                 'name' => $name,
204             ];
205
206             if (is_array($info)) {
207                 if (isset($info['tmp_name'])) {
208                     if ('' !== $info['tmp_name']) {
209                         $file['contents'] = fopen($info['tmp_name'], 'r');
210                         if (isset($info['name'])) {
211                             $file['filename'] = $info['name'];
212                         }
213                     } else {
214                         continue;
215                     }
216                 } else {
217                     $this->addPostFiles($info, $multipart, $name);
218                     continue;
219                 }
220             } else {
221                 $file['contents'] = fopen($info, 'r');
222             }
223
224             $multipart[] = $file;
225         }
226     }
227
228     public function addPostFields(array $formParams, array &$multipart, $arrayName = '')
229     {
230         foreach ($formParams as $name => $value) {
231             if (!empty($arrayName)) {
232                 $name = $arrayName.'['.$name.']';
233             }
234
235             if (is_array($value)) {
236                 $this->addPostFields($value, $multipart, $name);
237             } else {
238                 $multipart[] = [
239                     'name' => $name,
240                     'contents' => $value,
241                 ];
242             }
243         }
244     }
245
246     protected function createResponse(ResponseInterface $response)
247     {
248         return new Response((string) $response->getBody(), $response->getStatusCode(), $response->getHeaders());
249     }
250 }