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\BrowserKit ;
use Symfony\Component\HttpClient\HttpClient ;
use Symfony\Component\Mime\Part\AbstractPart ;
2019-04-05 18:29:13 +01:00
use Symfony\Component\Mime\Part\DataPart ;
2019-01-30 09:26:19 +00:00
use Symfony\Component\Mime\Part\Multipart\FormDataPart ;
use Symfony\Component\Mime\Part\TextPart ;
use Symfony\Contracts\HttpClient\HttpClientInterface ;
/**
* An implementation of a browser using the HttpClient component
* to make real HTTP requests .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
class HttpBrowser extends AbstractBrowser
{
private $client ;
public function __construct ( HttpClientInterface $client = null , History $history = null , CookieJar $cookieJar = null )
{
2019-09-02 15:45:56 +01:00
if ( ! $client && ! class_exists ( HttpClient :: class )) {
2019-01-30 09:26:19 +00:00
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 ();
parent :: __construct ([], $history , $cookieJar );
}
protected function doRequest ( $request )
{
$headers = $this -> getHeaders ( $request );
2019-04-05 18:29:13 +01:00
[ $body , $extraHeaders ] = $this -> getBodyAndExtraHeaders ( $request );
2019-01-30 09:26:19 +00:00
$response = $this -> client -> request ( $request -> getMethod (), $request -> getUri (), [
2019-04-05 18:29:13 +01:00
'headers' => array_merge ( $headers , $extraHeaders ),
2019-01-30 09:26:19 +00:00
'body' => $body ,
'max_redirects' => 0 ,
]);
return new Response ( $response -> getContent ( false ), $response -> getStatusCode (), $response -> getHeaders ( false ));
}
2019-04-05 18:29:13 +01:00
/**
* @ return array [ $body , $headers ]
*/
private function getBodyAndExtraHeaders ( Request $request ) : array
2019-01-30 09:26:19 +00:00
{
if ( \in_array ( $request -> getMethod (), [ 'GET' , 'HEAD' ])) {
2019-04-05 18:29:13 +01:00
return [ '' , []];
2019-01-30 09:26:19 +00:00
}
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 ( null !== $content = $request -> getContent ()) {
2019-04-05 18:29:13 +01:00
$part = new TextPart ( $content , 'utf-8' , 'plain' , '8bit' );
return [ $part -> bodyToString (), $part -> getPreparedHeaders () -> toArray ()];
2019-01-30 09:26:19 +00:00
}
$fields = $request -> getParameters ();
2019-04-05 18:29:13 +01:00
$hasFile = false ;
2019-01-30 09:26:19 +00:00
foreach ( $request -> getFiles () as $name => $file ) {
if ( ! isset ( $file [ 'tmp_name' ])) {
continue ;
}
2019-04-05 18:29:13 +01:00
$hasFile = true ;
2019-01-30 09:26:19 +00:00
$fields [ $name ] = DataPart :: fromPath ( $file [ 'tmp_name' ], $file [ 'name' ]);
}
2019-04-05 18:29:13 +01:00
if ( $hasFile ) {
$part = new FormDataPart ( $fields );
return [ $part -> bodyToIterable (), $part -> getPreparedHeaders () -> toArray ()];
}
if ( empty ( $fields )) {
return [ '' , []];
}
return [ http_build_query ( $fields , '' , '&' , PHP_QUERY_RFC1738 ), [ 'Content-Type' => 'application/x-www-form-urlencoded' ]];
2019-01-30 09:26:19 +00:00
}
private function getHeaders ( Request $request ) : array
{
$headers = [];
foreach ( $request -> getServer () as $key => $value ) {
$key = strtolower ( str_replace ( '_' , '-' , $key ));
$contentHeaders = [ 'content-length' => true , 'content-md5' => true , 'content-type' => true ];
if ( 0 === strpos ( $key , 'http-' )) {
$headers [ substr ( $key , 5 )] = $value ;
} elseif ( isset ( $contentHeaders [ $key ])) {
// CONTENT_* are not prefixed with HTTP_
$headers [ $key ] = $value ;
}
}
$cookies = [];
foreach ( $this -> getCookieJar () -> allRawValues ( $request -> getUri ()) as $name => $value ) {
$cookies [] = $name . '=' . $value ;
}
if ( $cookies ) {
$headers [ 'cookie' ] = implode ( '; ' , $cookies );
}
return $headers ;
}
}