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

Commit bf1d08a

Browse filesBrowse files
committed
Merge branch '6.4' into 7.0
* 6.4: (29 commits) fix tests add missing method fix merge fix test fix merge fix test change test to use a real ObjectManager [Mailer] Document the usage of custom headers in Infobip bridge [SecurityBundle] Add `provider` XML attribute to the authenticators it’s missing from [DoctrineBridge] Test reset with a true manager Sync php-cs-fixer config file with 7.2 [HttpClient] Fix parsing SSE [Notifier] Fix thread key in GoogleChat bridge [HttpKernel][Security] Fix accessing session for stateless request [Serializer] Fix `ObjectNormalizer` with property path test handling of special "value" constraint option [PhpUnitBridge] Add missing import [FrameworkBundle] Fix setting default context for certain normalizers [57251] Missing translations for Romanian (ro) [ErrorHandler] Fix rendered exception code highlighting on PHP 8.3 ...
2 parents 7a05958 + 979bda8 commit bf1d08a
Copy full SHA for bf1d08a

File tree

Expand file treeCollapse file tree

2 files changed

+55
-60
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+55
-60
lines changed

‎EventSourceHttpClient.php

Copy file name to clipboardExpand all lines: EventSourceHttpClient.php
+20-17Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpClient;
1313

14+
use Symfony\Component\HttpClient\Chunk\DataChunk;
1415
use Symfony\Component\HttpClient\Chunk\ServerSentEvent;
1516
use Symfony\Component\HttpClient\Exception\EventSourceException;
1617
use Symfony\Component\HttpClient\Response\AsyncContext;
@@ -121,17 +122,30 @@ public function request(string $method, string $url, array $options = []): Respo
121122
return;
122123
}
123124

124-
$rx = '/((?:\r\n){2,}|\r{2,}|\n{2,})/';
125-
$content = $state->buffer.$chunk->getContent();
126-
127125
if ($chunk->isLast()) {
128-
$rx = substr_replace($rx, '|$', -2, 0);
126+
if ('' !== $content = $state->buffer) {
127+
$state->buffer = '';
128+
yield new DataChunk(-1, $content);
129+
}
130+
131+
yield $chunk;
132+
133+
return;
129134
}
130-
$events = preg_split($rx, $content, -1, \PREG_SPLIT_DELIM_CAPTURE);
135+
136+
$content = $state->buffer.$chunk->getContent();
137+
$events = preg_split('/((?:\r\n){2,}|\r{2,}|\n{2,})/', $content, -1, \PREG_SPLIT_DELIM_CAPTURE);
131138
$state->buffer = array_pop($events);
132139

133140
for ($i = 0; isset($events[$i]); $i += 2) {
134-
$event = new ServerSentEvent($events[$i].$events[1 + $i]);
141+
$content = $events[$i].$events[1 + $i];
142+
if (!preg_match('/(?:^|\r\n|[\r\n])[^:\r\n]/', $content)) {
143+
yield new DataChunk(-1, $content);
144+
145+
continue;
146+
}
147+
148+
$event = new ServerSentEvent($content);
135149

136150
if ('' !== $event->getId()) {
137151
$context->setInfo('last_event_id', $state->lastEventId = $event->getId());
@@ -143,17 +157,6 @@ public function request(string $method, string $url, array $options = []): Respo
143157

144158
yield $event;
145159
}
146-
147-
if (preg_match('/^(?::[^\r\n]*+(?:\r\n|[\r\n]))+$/m', $state->buffer)) {
148-
$content = $state->buffer;
149-
$state->buffer = '';
150-
151-
yield $context->createChunk($content);
152-
}
153-
154-
if ($chunk->isLast()) {
155-
yield $chunk;
156-
}
157160
});
158161
}
159162
}

‎Tests/EventSourceHttpClientTest.php

Copy file name to clipboardExpand all lines: Tests/EventSourceHttpClientTest.php
+35-43Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
use Symfony\Component\HttpClient\Chunk\DataChunk;
1616
use Symfony\Component\HttpClient\Chunk\ErrorChunk;
1717
use Symfony\Component\HttpClient\Chunk\FirstChunk;
18+
use Symfony\Component\HttpClient\Chunk\LastChunk;
1819
use Symfony\Component\HttpClient\Chunk\ServerSentEvent;
1920
use Symfony\Component\HttpClient\EventSourceHttpClient;
2021
use Symfony\Component\HttpClient\Exception\EventSourceException;
22+
use Symfony\Component\HttpClient\MockHttpClient;
2123
use Symfony\Component\HttpClient\Response\MockResponse;
2224
use Symfony\Component\HttpClient\Response\ResponseStream;
2325
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -34,7 +36,11 @@ class EventSourceHttpClientTest extends TestCase
3436
*/
3537
public function testGetServerSentEvents(string $sep)
3638
{
37-
$rawData = <<<TXT
39+
$es = new EventSourceHttpClient(new MockHttpClient(function (string $method, string $url, array $options) use ($sep): MockResponse {
40+
$this->assertSame(['Accept: text/event-stream', 'Cache-Control: no-cache'], $options['headers']);
41+
42+
return new MockResponse([
43+
str_replace("\n", $sep, <<<TXT
3844
event: builderror
3945
id: 46
4046
data: {"foo": "bar"}
@@ -43,7 +49,18 @@ public function testGetServerSentEvents(string $sep)
4349
id: 47
4450
data: {}
4551
52+
: this is a oneline comment
53+
54+
: this is a
55+
: multiline comment
56+
57+
: comments are ignored
4658
event: reload
59+
60+
TXT
61+
),
62+
str_replace("\n", $sep, <<<TXT
63+
: anywhere
4764
id: 48
4865
data: {}
4966
@@ -62,58 +79,33 @@ public function testGetServerSentEvents(string $sep)
6279
6380
id: 60
6481
data
65-
TXT;
66-
$data = str_replace("\n", $sep, $rawData);
67-
68-
$chunk = new DataChunk(0, $data);
69-
$response = new MockResponse('', ['canceled' => false, 'http_method' => 'GET', 'url' => 'http://localhost:8080/events', 'response_headers' => ['content-type: text/event-stream']]);
70-
$responseStream = new ResponseStream((function () use ($response, $chunk) {
71-
yield $response => new FirstChunk();
72-
yield $response => $chunk;
73-
yield $response => new ErrorChunk(0, 'timeout');
74-
})());
75-
76-
$hasCorrectHeaders = function ($options) {
77-
$this->assertSame(['Accept: text/event-stream', 'Cache-Control: no-cache'], $options['headers']);
78-
79-
return true;
80-
};
81-
82-
$httpClient = $this->createMock(HttpClientInterface::class);
83-
$httpClient->method('request')->with('GET', 'http://localhost:8080/events', $this->callback($hasCorrectHeaders))->willReturn($response);
84-
85-
$httpClient->method('stream')->willReturn($responseStream);
86-
87-
$es = new EventSourceHttpClient($httpClient);
82+
TXT
83+
),
84+
], [
85+
'canceled' => false,
86+
'http_method' => 'GET',
87+
'url' => 'http://localhost:8080/events',
88+
'response_headers' => ['content-type: text/event-stream'],
89+
]);
90+
}));
8891
$res = $es->connect('http://localhost:8080/events');
8992

9093
$expected = [
9194
new FirstChunk(),
9295
new ServerSentEvent(str_replace("\n", $sep, "event: builderror\nid: 46\ndata: {\"foo\": \"bar\"}\n\n")),
9396
new ServerSentEvent(str_replace("\n", $sep, "event: reload\nid: 47\ndata: {}\n\n")),
94-
new ServerSentEvent(str_replace("\n", $sep, "event: reload\nid: 48\ndata: {}\n\n")),
97+
new DataChunk(-1, str_replace("\n", $sep, ": this is a oneline comment\n\n")),
98+
new DataChunk(-1, str_replace("\n", $sep, ": this is a\n: multiline comment\n\n")),
99+
new ServerSentEvent(str_replace("\n", $sep, ": comments are ignored\nevent: reload\n: anywhere\nid: 48\ndata: {}\n\n")),
95100
new ServerSentEvent(str_replace("\n", $sep, "data: test\ndata:test\nid: 49\nevent: testEvent\n\n\n")),
96101
new ServerSentEvent(str_replace("\n", $sep, "id: 50\ndata: <tag>\ndata\ndata: <foo />\ndata\ndata: </tag>\n\n")),
102+
new DataChunk(-1, str_replace("\n", $sep, "id: 60\ndata")),
103+
new LastChunk("\r\n" === $sep ? 355 : 322),
97104
];
98-
$i = 0;
99-
100-
$this->expectExceptionMessage('Response has been canceled');
101-
while ($res) {
102-
if ($i > 0) {
103-
$res->cancel();
104-
}
105-
foreach ($es->stream($res) as $chunk) {
106-
if ($chunk->isTimeout()) {
107-
continue;
108-
}
109-
110-
if ($chunk->isLast()) {
111-
continue;
112-
}
113-
114-
$this->assertEquals($expected[$i++], $chunk);
115-
}
105+
foreach ($es->stream($res) as $chunk) {
106+
$this->assertEquals(array_shift($expected), $chunk);
116107
}
108+
$this->assertSame([], $expected);
117109
}
118110

119111
public function testPostServerSentEvents()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.