class HttpBrowser
An implementation of a browser using the HttpClient component to make real HTTP requests.
@author Fabien Potencier <fabien@symfony.com>
@template-extends AbstractBrowser<Request, Response>
Hierarchy
- class \Symfony\Component\BrowserKit\AbstractBrowser
- class \Symfony\Component\BrowserKit\HttpBrowser extends \Symfony\Component\BrowserKit\AbstractBrowser
Expanded class hierarchy of HttpBrowser
File
-
vendor/
symfony/ browser-kit/ HttpBrowser.php, line 30
Namespace
Symfony\Component\BrowserKitView source
class HttpBrowser extends AbstractBrowser {
private HttpClientInterface $client;
public function __construct(?HttpClientInterface $client = null, ?History $history = null, ?CookieJar $cookieJar = null) {
if (!$client && !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();
parent::__construct([], $history, $cookieJar);
}
/**
* @param Request $request
*/
protected function doRequest(object $request) : Response {
$headers = $this->getHeaders($request);
[
$body,
$extraHeaders,
] = $this->getBodyAndExtraHeaders($request, $headers);
$response = $this->client
->request($request->getMethod(), $request->getUri(), [
'headers' => array_merge($headers, $extraHeaders),
'body' => $body,
'max_redirects' => 0,
]);
return new Response($response->getContent(false), $response->getStatusCode(), $response->getHeaders(false));
}
/**
* @return array [$body, $headers]
*/
private function getBodyAndExtraHeaders(Request $request, array $headers) : array {
if (\in_array($request->getMethod(), [
'GET',
'HEAD',
]) && !isset($headers['content-type'])) {
return [
'',
[],
];
}
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())) {
if (isset($headers['content-type'])) {
return [
$content,
[],
];
}
$part = new TextPart($content, 'utf-8', 'plain', '8bit');
return [
$part->bodyToString(),
$part->getPreparedHeaders()
->toArray(),
];
}
$fields = $request->getParameters();
if ($uploadedFiles = $this->getUploadedFiles($request->getFiles())) {
$part = new FormDataPart(array_replace_recursive($fields, $uploadedFiles));
return [
$part->bodyToIterable(),
$part->getPreparedHeaders()
->toArray(),
];
}
if (!$fields) {
return [
'',
[],
];
}
array_walk_recursive($fields, $caster = static function (&$v) use (&$caster) {
if (\is_object($v)) {
if ($vars = get_object_vars($v)) {
array_walk_recursive($vars, $caster);
$v = $vars;
}
elseif ($v instanceof \Stringable) {
$v = (string) $v;
}
}
});
return [
http_build_query($fields, '', '&'),
[
'Content-Type' => 'application/x-www-form-urlencoded',
],
];
}
protected 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 (str_starts_with($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;
}
/**
* Recursively go through the list. If the file has a tmp_name, convert it to a DataPart.
* Keep the original hierarchy.
*/
private function getUploadedFiles(array $files) : array {
$uploadedFiles = [];
foreach ($files as $name => $file) {
if (!\is_array($file)) {
return $uploadedFiles;
}
if (!isset($file['tmp_name'])) {
$uploadedFiles[$name] = $this->getUploadedFiles($file);
}
if (isset($file['tmp_name'])) {
$uploadedFiles[$name] = DataPart::fromPath($file['tmp_name'], $file['name']);
}
}
return $uploadedFiles;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
AbstractBrowser::$cookieJar | protected | property | |||
AbstractBrowser::$crawler | protected | property | |||
AbstractBrowser::$followMetaRefresh | protected | property | |||
AbstractBrowser::$followRedirects | protected | property | |||
AbstractBrowser::$history | protected | property | |||
AbstractBrowser::$insulated | protected | property | |||
AbstractBrowser::$internalRequest | protected | property | |||
AbstractBrowser::$internalResponse | protected | property | |||
AbstractBrowser::$isMainRequest | private | property | |||
AbstractBrowser::$maxRedirects | private | property | |||
AbstractBrowser::$redirect | protected | property | |||
AbstractBrowser::$redirectCount | private | property | |||
AbstractBrowser::$redirects | private | property | |||
AbstractBrowser::$request | protected | property | @psalm-var TRequest | ||
AbstractBrowser::$response | protected | property | @psalm-var TResponse | ||
AbstractBrowser::$server | protected | property | |||
AbstractBrowser::$useHtml5Parser | protected | property | |||
AbstractBrowser::back | public | function | Goes back in the browser history. | ||
AbstractBrowser::click | public | function | Clicks on a given link. | ||
AbstractBrowser::clickLink | public | function | Clicks the first link (or clickable image) that contains the given text. | ||
AbstractBrowser::createCrawlerFromContent | protected | function | Creates a crawler. | ||
AbstractBrowser::doRequestInProcess | protected | function | Makes a request in another process. | ||
AbstractBrowser::extractHost | private | function | |||
AbstractBrowser::filterRequest | protected | function | Filters the BrowserKit request to the origin one. | 1 | |
AbstractBrowser::filterResponse | protected | function | Filters the origin response to the BrowserKit one. | 1 | |
AbstractBrowser::followMetaRefresh | public | function | Sets whether to automatically follow meta refresh redirects or not. | ||
AbstractBrowser::followRedirect | public | function | Follow redirects? | ||
AbstractBrowser::followRedirects | public | function | Sets whether to automatically follow redirects or not. | ||
AbstractBrowser::forward | public | function | Goes forward in the browser history. | ||
AbstractBrowser::getAbsoluteUri | protected | function | Takes a URI and converts it to absolute if it is not already absolute. | ||
AbstractBrowser::getCookieJar | public | function | Returns the CookieJar instance. | ||
AbstractBrowser::getCrawler | public | function | Returns the current Crawler instance. | ||
AbstractBrowser::getHistory | public | function | Returns the History instance. | ||
AbstractBrowser::getInternalRequest | public | function | Returns the current BrowserKit Request instance. | ||
AbstractBrowser::getInternalResponse | public | function | Returns the current BrowserKit Response instance. | ||
AbstractBrowser::getMaxRedirects | public | function | Returns the maximum number of redirects that crawler can follow. | ||
AbstractBrowser::getMetaRefreshUrl | private | function | |||
AbstractBrowser::getRequest | public | function | Returns the current origin Request instance. | ||
AbstractBrowser::getResponse | public | function | Returns the current origin response instance. | ||
AbstractBrowser::getScript | protected | function | Returns the script to execute when the request must be insulated. | 1 | |
AbstractBrowser::getServerParameter | public | function | Gets single server parameter for specified key. | ||
AbstractBrowser::insulate | public | function | Sets the insulated flag. | ||
AbstractBrowser::isFollowingRedirects | public | function | Returns whether client automatically follows redirects or not. | ||
AbstractBrowser::jsonRequest | public | function | Converts the request parameters into a JSON string and uses it as request content. | ||
AbstractBrowser::reload | public | function | Reloads the current browser. | ||
AbstractBrowser::request | public | function | Calls a URI. | ||
AbstractBrowser::requestFromRequest | protected | function | Makes a request from a Request object directly. | ||
AbstractBrowser::restart | public | function | Restarts the client. | ||
AbstractBrowser::setMaxRedirects | public | function | Sets the maximum number of redirects that crawler can follow. | ||
AbstractBrowser::setServerParameter | public | function | Sets single server parameter. | ||
AbstractBrowser::setServerParameters | public | function | Sets server parameters. | ||
AbstractBrowser::submit | public | function | Submits a form. | ||
AbstractBrowser::submitForm | public | function | Finds the first form that contains a button with the given content and uses it to submit the given form field values. |
||
AbstractBrowser::updateServerFromUri | private | function | |||
AbstractBrowser::useHtml5Parser | public | function | Sets whether parsing should be done using "masterminds/html5". | ||
AbstractBrowser::xmlHttpRequest | public | function | |||
HttpBrowser::$client | private | property | |||
HttpBrowser::doRequest | protected | function | Overrides AbstractBrowser::doRequest | ||
HttpBrowser::getBodyAndExtraHeaders | private | function | |||
HttpBrowser::getHeaders | protected | function | |||
HttpBrowser::getUploadedFiles | private | function | Recursively go through the list. If the file has a tmp_name, convert it to a DataPart. Keep the original hierarchy. |
||
HttpBrowser::__construct | public | function | Overrides AbstractBrowser::__construct |