Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Serializer] Added ScalarDenormalizer for denormalize any scalar values #35136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
5179af4
[Translator] Performance improvement in MessageCatalogue and catalogu…
ArtemBrovko Dec 27, 2019
bad07ec
Fix BC issue in phpDoc Reflection library
jaapio Dec 28, 2019
3a3da05
Added ScalarDenormalizer for denormalize any scalar values (see https…
a-menshchikov Dec 28, 2019
d91a284
CHANGELOG.md updated
a-menshchikov Dec 28, 2019
8140804
Code style & license fixes
a-menshchikov Dec 29, 2019
cd40bb8
[Routing] Fix i18n routing when the url contains the locale
fancyweb Dec 24, 2019
f0d227d
[Console][FormatterHelper] Use helper strlen statically and remove du…
fancyweb Dec 29, 2019
3a25878
[HttpClient] fix typo
nicolas-grekas Dec 30, 2019
3a51e01
minor #35148 [HttpClient] fix typo (nicolas-grekas)
nicolas-grekas Dec 31, 2019
c976752
minor #35141 [Console][FormatterHelper] Use helper strlen statically …
nicolas-grekas Dec 31, 2019
8e9aafc
bug #35125 [Translator] fix performance issue in MessageCatalogue and…
nicolas-grekas Dec 31, 2019
889a110
Update year in license files
rosier Jan 1, 2020
0d7a8bd
Update year in license files
rosier Jan 1, 2020
5374d4f
[TwigBridge][Form] Added missing help messages in form themes
cmen Dec 27, 2019
234589a
[HttpClient] fix capturing SSL certificates with NativeHttpClient
nicolas-grekas Jan 2, 2020
9e12a6d
[Mailer][MailchimpBridge] Fix incorrect sender address when sender ha…
vilius-g Jan 2, 2020
7b1bbb6
[Mailer][MailchimpBridge] Fix missing attachments when sending via Ma…
vilius-g Jan 2, 2020
08670cc
bug #35172 [Mailer][MailchimpBridge] Fix incorrect sender address whe…
fabpot Jan 2, 2020
e348513
bug #35173 [Mailer][MailchimpBridge] Fix missing attachments when sen…
fabpot Jan 2, 2020
50ba566
[PhpUnitBridge][SymfonyTestsListenerTrait] Remove $testsWithWarnings …
fancyweb Jan 3, 2020
dba1804
[PhpUnitBridge] Add test case for @expectedDeprecation annotation
fancyweb Jan 3, 2020
8d46f95
ensure to expect no validation for the right reasons
xabbuh Jan 4, 2020
28c9463
minor #35190 [PhpUnitBridge] Add test case for @expectedDeprecation a…
nicolas-grekas Jan 4, 2020
db874f6
minor #35188 [PhpUnitBridge][SymfonyTestsListenerTrait] Remove $tests…
nicolas-grekas Jan 4, 2020
51d8070
minor #35154 Update year in license files (rosier)
nicolas-grekas Jan 4, 2020
9392f76
minor #35207 [Form] ensure to expect no validation for the right reas…
nicolas-grekas Jan 4, 2020
da11771
[Validator] Add the missing translations for the Arabic (ar) locale
Dec 30, 2019
8c7b1c8
minor #35147 [Validator] Add the missing translations for the Arabic …
nicolas-grekas Jan 4, 2020
28e502e
bug #35134 [PropertyInfo] Fix BC issue in phpDoc Reflection library (…
nicolas-grekas Jan 4, 2020
5cac295
Update links to documentation
shahariaazam Dec 20, 2019
4b419f2
minor #35074 Update links to documentation (shahariaazam)
nicolas-grekas Jan 4, 2020
a56c3ef
Merge branch '3.4' into 4.3
nicolas-grekas Jan 4, 2020
d394214
minor #35155 Update year in license files (rosier)
nicolas-grekas Jan 4, 2020
cf83c60
bug #35168 [HttpClient] fix capturing SSL certificates with NativeHtt…
nicolas-grekas Jan 4, 2020
cbf2abd
bug #35124 [TwigBridge][Form] Added missing help messages in form the…
nicolas-grekas Jan 4, 2020
423d3dd
bug #35101 [Routing] Fix i18n routing when the url contains the local…
nicolas-grekas Jan 4, 2020
a28a7f9
[Mailer] Remove line breaks in email attachment content
Sep 23, 2019
eb5171f
bug #33672 [Mailer] Remove line breaks in email attachment content (S…
nicolas-grekas Jan 4, 2020
8b61c95
[HttpClient] NativeHttpClient should not send >1.1 protocol version
nicolas-grekas Jan 4, 2020
ccfc4b6
bug #35210 [HttpClient] NativeHttpClient should not send >1.1 protoco…
nicolas-grekas Jan 4, 2020
99dab87
[DI] DecoratorServicePass should keep container.service_locator on th…
malarzm Jan 4, 2020
ac3d77a
[HttpClient] Don't read from the network faster than the CPU can deal…
nicolas-grekas Jan 5, 2020
6fb2d52
bug #35214 [DI] DecoratorServicePass should keep container.service_lo…
nicolas-grekas Jan 6, 2020
f9b36c7
bug #35223 [HttpClient] Don't read from the network faster than the C…
nicolas-grekas Jan 6, 2020
682631f
Added ScalarDenormalizer for denormalize any scalar values (see https…
a-menshchikov Dec 28, 2019
6a61b37
CHANGELOG.md updated
a-menshchikov Dec 28, 2019
64e0b4e
Code style & license fixes
a-menshchikov Dec 29, 2019
cc890e9
Added scalar denormalization in Serializer (without dedicated class S…
a-menshchikov Jan 6, 2020
946bc61
Merge remote-tracking branch 'origin/bugfix/33784' into bugfix/33784
a-menshchikov Jan 6, 2020
ffe195f
Deleted ScalarDenormalizer
a-menshchikov Dec 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[HttpClient] Don't read from the network faster than the CPU can deal…
… with
  • Loading branch information
nicolas-grekas committed Jan 6, 2020
commit ac3d77a76acbc67da67b67a6f37f39807238d4f0
6 changes: 3 additions & 3 deletions 6 src/Symfony/Component/HttpClient/CurlHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function request(string $method, string $url, array $options = []): Respo
$url = implode('', $url);

if (!isset($options['normalized_headers']['user-agent'])) {
$options['normalized_headers']['user-agent'][] = $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl';
$options['headers'][] = 'User-Agent: Symfony HttpClient/Curl';
}

$curlopts = [
Expand Down Expand Up @@ -194,8 +194,8 @@ public function request(string $method, string $url, array $options = []): Respo
$curlopts[CURLOPT_NOSIGNAL] = true;
}

if (!isset($options['normalized_headers']['accept-encoding']) && CURL_VERSION_LIBZ & self::$curlVersion['features']) {
$curlopts[CURLOPT_ENCODING] = 'gzip'; // Expose only one encoding, some servers mess up when more are provided
if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) {
$options['headers'][] = 'Accept-Encoding: gzip'; // Expose only one encoding, some servers mess up when more are provided
}

foreach ($options['headers'] as $header) {
Expand Down
4 changes: 2 additions & 2 deletions 4 src/Symfony/Component/HttpClient/NativeHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function request(string $method, string $url, array $options = []): Respo
$options['headers'][] = 'Content-Type: application/x-www-form-urlencoded';
}

if ($gzipEnabled = \extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) {
if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) {
// gzip is the most widely available algo, no need to deal with deflate
$options['headers'][] = 'Accept-Encoding: gzip';
}
Expand Down Expand Up @@ -210,7 +210,7 @@ public function request(string $method, string $url, array $options = []): Respo
$context = stream_context_create($context, ['notification' => $notification]);
self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy, $noProxy);

return new NativeResponse($this->multi, $context, implode('', $url), $options, $gzipEnabled, $info, $resolveRedirect, $onProgress, $this->logger);
return new NativeResponse($this->multi, $context, implode('', $url), $options, $info, $resolveRedirect, $onProgress, $this->logger);
}

/**
Expand Down
46 changes: 13 additions & 33 deletions 46 src/Symfony/Component/HttpClient/Response/CurlResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,

$this->id = $id = (int) $ch;
$this->logger = $logger;
$this->shouldBuffer = $options['buffer'] ?? true;
$this->timeout = $options['timeout'] ?? null;
$this->info['http_method'] = $method;
$this->info['user_data'] = $options['user_data'] ?? null;
Expand All @@ -65,30 +66,25 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
curl_setopt($ch, CURLOPT_PRIVATE, \in_array($method, ['GET', 'HEAD', 'OPTIONS', 'TRACE'], true) && 1.0 < (float) ($options['http_version'] ?? 1.1) ? 'H2' : 'H0'); // H = headers + retry counter
}

if (null === $content = &$this->content) {
$content = ($options['buffer'] ?? true) ? fopen('php://temp', 'w+') : null;
} else {
// Move the pushed response to the activity list
if (ftell($content)) {
rewind($content);
$multi->handlesActivity[$id][] = stream_get_contents($content);
}
$content = ($options['buffer'] ?? true) ? $content : null;
}

curl_setopt($ch, CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int {
return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
});

if (null === $options) {
// Pushed response: buffer until requested
curl_setopt($ch, CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use (&$content): int {
return fwrite($content, $data);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int {
$multi->handlesActivity[$id][] = $data;
curl_pause($ch, CURLPAUSE_RECV);

return \strlen($data);
});

return;
}

$this->inflate = !isset($options['normalized_headers']['accept-encoding']);
curl_pause($ch, CURLPAUSE_CONT);

if ($onProgress = $options['on_progress']) {
$url = isset($info['url']) ? ['url' => $info['url']] : [];
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
Expand All @@ -108,33 +104,16 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
});
}

curl_setopt($ch, CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use (&$content, $multi, $id): int {
curl_setopt($ch, CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int {
$multi->handlesActivity[$id][] = $data;

return null !== $content ? fwrite($content, $data) : \strlen($data);
return \strlen($data);
});

$this->initializer = static function (self $response) {
if (null !== $response->info['error']) {
throw new TransportException($response->info['error']);
}

$waitFor = curl_getinfo($ch = $response->handle, CURLINFO_PRIVATE);

if ('H' === $waitFor[0] || 'D' === $waitFor[0]) {
try {
foreach (self::stream([$response]) as $chunk) {
if ($chunk->isFirst()) {
break;
}
}
} catch (\Throwable $e) {
// Persist timeouts thrown during initialization
$response->info['error'] = $e->getMessage();
$response->close();
throw $e;
}
}
return 'H' === $waitFor[0] || 'D' === $waitFor[0];
};

// Schedule the request in a non-blocking way
Expand Down Expand Up @@ -221,6 +200,7 @@ public function __destruct()
*/
private function close(): void
{
$this->inflate = null;
unset($this->multi->openHandles[$this->id], $this->multi->handlesActivity[$this->id]);
curl_multi_remove_handle($this->multi->handle, $this->handle);
curl_setopt_array($this->handle, [
Expand Down
17 changes: 3 additions & 14 deletions 17 src/Symfony/Component/HttpClient/Response/MockResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public function cancel(): void
*/
protected function close(): void
{
$this->inflate = null;
$this->body = [];
}

Expand All @@ -104,16 +105,9 @@ public static function fromRequest(string $method, string $url, array $options,
$response = new self([]);
$response->requestOptions = $options;
$response->id = ++self::$idSequence;
$response->content = ($options['buffer'] ?? true) ? fopen('php://temp', 'w+') : null;
$response->shouldBuffer = $options['buffer'] ?? true;
$response->initializer = static function (self $response) {
if (null !== $response->info['error']) {
throw new TransportException($response->info['error']);
}

if (\is_array($response->body[0] ?? null)) {
// Consume the first chunk if it's not yielded yet
self::stream([$response])->current();
}
return \is_array($response->body[0] ?? null);
};

$response->info['redirect_count'] = 0;
Expand Down Expand Up @@ -186,11 +180,6 @@ protected static function perform(ClientState $multi, array &$responses): void
} else {
// Data or timeout chunk
$multi->handlesActivity[$id][] = $chunk;

if (\is_string($chunk) && null !== $response->content) {
// Buffer response body
fwrite($response->content, $chunk);
}
}
}
}
Expand Down
47 changes: 12 additions & 35 deletions 47 src/Symfony/Component/HttpClient/Response/NativeResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ final class NativeResponse implements ResponseInterface
private $onProgress;
private $remaining;
private $buffer;
private $inflate;
private $multi;
private $debugBuffer;

/**
* @internal
*/
public function __construct(NativeClientState $multi, $context, string $url, $options, bool $gzipEnabled, array &$info, callable $resolveRedirect, ?callable $onProgress, ?LoggerInterface $logger)
public function __construct(NativeClientState $multi, $context, string $url, array $options, array &$info, callable $resolveRedirect, ?callable $onProgress, ?LoggerInterface $logger)
{
$this->multi = $multi;
$this->id = (int) $context;
Expand All @@ -50,27 +49,17 @@ public function __construct(NativeClientState $multi, $context, string $url, $op
$this->info = &$info;
$this->resolveRedirect = $resolveRedirect;
$this->onProgress = $onProgress;
$this->content = $options['buffer'] ? fopen('php://temp', 'w+') : null;
$this->inflate = !isset($options['normalized_headers']['accept-encoding']);
$this->shouldBuffer = $options['buffer'] ?? true;

// Temporary resources to dechunk/inflate the response stream
// Temporary resource to dechunk the response stream
$this->buffer = fopen('php://temp', 'w+');
$this->inflate = $gzipEnabled ? inflate_init(ZLIB_ENCODING_GZIP) : null;

$info['user_data'] = $options['user_data'];
++$multi->responseCount;

$this->initializer = static function (self $response) {
if (null !== $response->info['error']) {
throw new TransportException($response->info['error']);
}

if (null === $response->remaining) {
foreach (self::stream([$response]) as $chunk) {
if ($chunk->isFirst()) {
break;
}
}
}
return null === $response->remaining;
};
}

Expand Down Expand Up @@ -165,7 +154,7 @@ private function open(): void
stream_set_blocking($h, false);
$this->context = $this->resolveRedirect = null;

// Create dechunk and inflate buffers
// Create dechunk buffers
if (isset($this->headers['content-length'])) {
$this->remaining = (int) $this->headers['content-length'][0];
} elseif ('chunked' === ($this->headers['transfer-encoding'][0] ?? null)) {
Expand All @@ -175,10 +164,6 @@ private function open(): void
$this->remaining = -2;
}

if ($this->inflate && 'gzip' !== ($this->headers['content-encoding'][0] ?? null)) {
$this->inflate = null;
}

$this->multi->handlesActivity[$this->id] = [new FirstChunk()];

if ('HEAD' === $context['http']['method'] || \in_array($this->info['http_code'], [204, 304], true)) {
Expand All @@ -188,7 +173,7 @@ private function open(): void
return;
}

$this->multi->openHandles[$this->id] = [$h, $this->buffer, $this->inflate, $this->content, $this->onProgress, &$this->remaining, &$this->info];
$this->multi->openHandles[$this->id] = [$h, $this->buffer, $this->onProgress, &$this->remaining, &$this->info];
}

/**
Expand Down Expand Up @@ -228,15 +213,15 @@ private static function perform(NativeClientState $multi, array &$responses = nu
$multi->handles = [];
}

foreach ($multi->openHandles as $i => [$h, $buffer, $inflate, $content, $onProgress]) {
foreach ($multi->openHandles as $i => [$h, $buffer, $onProgress]) {
$hasActivity = false;
$remaining = &$multi->openHandles[$i][5];
$info = &$multi->openHandles[$i][6];
$remaining = &$multi->openHandles[$i][3];
$info = &$multi->openHandles[$i][4];
$e = null;

// Read incoming buffer and write it to the dechunk one
try {
while ($remaining && '' !== $data = (string) fread($h, 0 > $remaining ? 16372 : $remaining)) {
if ($remaining && '' !== $data = (string) fread($h, 0 > $remaining ? 16372 : $remaining)) {
fwrite($buffer, $data);
$hasActivity = true;
$multi->sleep = false;
Expand Down Expand Up @@ -264,16 +249,8 @@ private static function perform(NativeClientState $multi, array &$responses = nu
rewind($buffer);
ftruncate($buffer, 0);

if (null !== $inflate && false === $data = @inflate_add($inflate, $data)) {
$e = new TransportException('Error while processing content unencoding.');
}

if ('' !== $data && null === $e) {
if (null === $e) {
$multi->handlesActivity[$i][] = $data;

if (null !== $content && \strlen($data) !== fwrite($content, $data)) {
$e = new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($data)));
}
}
}

Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.