2019-01-30 09:26:19 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\HttpKernel ;
use Symfony\Component\HttpClient\HttpClient ;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\Response ;
2019-03-24 19:39:17 +00:00
use Symfony\Component\HttpFoundation\ResponseHeaderBag ;
2019-01-30 09:26:19 +00:00
use Symfony\Component\Mime\Part\AbstractPart ;
use Symfony\Component\Mime\Part\DataPart ;
use Symfony\Component\Mime\Part\Multipart\FormDataPart ;
use Symfony\Component\Mime\Part\TextPart ;
use Symfony\Contracts\HttpClient\HttpClientInterface ;
2019-09-24 12:01:54 +01:00
// Help opcache.preload discover always-needed symbols
class_exists ( ResponseHeaderBag :: class );
2019-01-30 09:26:19 +00:00
/**
* An implementation of a Symfony HTTP kernel using a " real " HTTP client .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
2019-01-30 09:26:19 +00:00
final class HttpClientKernel implements HttpKernelInterface
2019-01-30 09:26:19 +00:00
{
private $client ;
2019-04-04 15:02:57 +01:00
public function __construct ( HttpClientInterface $client = null )
2019-01-30 09:26:19 +00:00
{
if ( ! class_exists ( HttpClient :: class )) {
throw new \LogicException ( sprintf ( 'You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".' , __CLASS__ ));
}
$this -> client = $client ? ? HttpClient :: create ();
}
2019-08-20 22:41:37 +01:00
public function handle ( Request $request , int $type = HttpKernelInterface :: MASTER_REQUEST , bool $catch = true ) : Response
2019-01-30 09:26:19 +00:00
{
$headers = $this -> getHeaders ( $request );
$body = '' ;
if ( null !== $part = $this -> getBody ( $request )) {
$headers = array_merge ( $headers , $part -> getPreparedHeaders () -> toArray ());
$body = $part -> bodyToIterable ();
}
$response = $this -> client -> request ( $request -> getMethod (), $request -> getUri (), [
'headers' => $headers ,
'body' => $body ,
'max_redirects' => 0 ,
] + $request -> attributes -> get ( 'http_client_options' , []));
2019-03-24 19:39:17 +00:00
$response = new Response ( $response -> getContent ( ! $catch ), $response -> getStatusCode (), $response -> getHeaders ( ! $catch ));
2020-06-15 08:28:47 +01:00
$response -> headers -> remove ( 'X-Body-File' );
$response -> headers -> remove ( 'X-Body-Eval' );
$response -> headers -> remove ( 'X-Content-Digest' );
2019-03-24 19:39:17 +00:00
$response -> headers = new class ( $response -> headers -> all ()) extends ResponseHeaderBag {
2019-08-20 12:52:38 +01:00
protected function computeCacheControlValue () : string
2019-03-24 19:39:17 +00:00
{
return $this -> getCacheControlHeader (); // preserve the original value
}
};
return $response ;
2019-01-30 09:26:19 +00:00
}
private function getBody ( Request $request ) : ? AbstractPart
{
if ( \in_array ( $request -> getMethod (), [ 'GET' , 'HEAD' ])) {
return null ;
}
if ( ! class_exists ( AbstractPart :: class )) {
throw new \LogicException ( 'You cannot pass non-empty bodies as the Mime component is not installed. Try running "composer require symfony/mime".' );
}
if ( $content = $request -> getContent ()) {
return new TextPart ( $content , 'utf-8' , 'plain' , '8bit' );
}
$fields = $request -> request -> all ();
foreach ( $request -> files -> all () as $name => $file ) {
$fields [ $name ] = DataPart :: fromPath ( $file -> getPathname (), $file -> getClientOriginalName (), $file -> getClientMimeType ());
}
return new FormDataPart ( $fields );
}
private function getHeaders ( Request $request ) : array
{
$headers = [];
foreach ( $request -> headers as $key => $value ) {
$headers [ $key ] = $value ;
}
$cookies = [];
foreach ( $request -> cookies -> all () as $name => $value ) {
$cookies [] = $name . '=' . $value ;
}
if ( $cookies ) {
$headers [ 'cookie' ] = implode ( '; ' , $cookies );
}
return $headers ;
}
}