Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 2a2698f

Browse files
jakobr-googlemkustermann
authored andcommitted
Window updates. (#12)
Make sure the positiveWindow is marked un-buffered if the window opens due to an increase in initial window size. Otherwise, even sub-sequent WindowUpdate frames wouldn't cause a bufferEmpty event to get emitted. Also, if the connection preface doesn't match, don't try to add data to the terminated connection.
1 parent d6ed237 commit 2a2698f

File tree

5 files changed

+20
-22
lines changed

5 files changed

+20
-22
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
* Fixed a bug where a closed window would not open correctly due to an increase
6+
in initial window size.
7+
38
## 0.1.2
49

510
* The endStream bit is now set on the requested frame, instead of on an empty

lib/src/connection_preface.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ Stream<List<int>> readConnectionPreface(Stream<List<int>> incoming) {
3838
terminated = true;
3939
}
4040

41-
void compareConnectionPreface(List<int> data) {
41+
bool compareConnectionPreface(List<int> data) {
4242
for (int i = 0; i < CONNECTION_PREFACE.length; i++) {
4343
if (data[i] != CONNECTION_PREFACE[i]) {
4444
terminate('Connection preface does not match.');
45-
break;
45+
return false;
4646
}
4747
}
4848
prefaceBuffer = null;
4949
connectionPrefaceRead = true;
50+
return true;
5051
}
5152

5253
void onData(List<int> data) {
@@ -55,7 +56,7 @@ Stream<List<int>> readConnectionPreface(Stream<List<int>> incoming) {
5556
result.add(data);
5657
} else {
5758
if (prefaceBuffer.isEmpty && data.length > CONNECTION_PREFACE.length) {
58-
compareConnectionPreface(data);
59+
if (!compareConnectionPreface(data)) return;
5960
data = data.sublist(CONNECTION_PREFACE.length);
6061
} else if (prefaceBuffer.length < CONNECTION_PREFACE.length) {
6162
int remaining = CONNECTION_PREFACE.length - prefaceBuffer.length;
@@ -66,7 +67,7 @@ Stream<List<int>> readConnectionPreface(Stream<List<int>> incoming) {
6667
prefaceBuffer.addAll(part1);
6768

6869
if (prefaceBuffer.length == CONNECTION_PREFACE.length) {
69-
compareConnectionPreface(prefaceBuffer);
70+
if (!compareConnectionPreface(prefaceBuffer)) return;
7071
}
7172
data = part2;
7273
}

lib/src/flowcontrol/window.dart

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,13 @@ class Window {
1515
/// NOTE: This value can potentially become negative.
1616
int _size;
1717

18-
/// The size the window would normally have if there is no outstanding
19-
/// data.
20-
///
21-
/// NOTE: The peer can always increase a stream window above this default
22-
/// limit.
23-
int _defaultSize;
24-
2518
Window({int initialSize: (1 << 16) - 1})
26-
: _size = initialSize, _defaultSize = initialSize;
19+
: _size = initialSize;
2720

2821
/// The current size of the flow control window.
2922
int get size => _size;
3023

3124
void modify(int difference) {
3225
_size += difference;
3326
}
34-
35-
/// This method can be e.g. called after receiving a SettingsFrame
36-
/// which changes the initial window size of all streams.
37-
void modifyDefaultSize(int difference) {
38-
_defaultSize += difference;
39-
}
4027
}

lib/src/flowcontrol/window_handler.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ abstract class AbstractOutgoingWindowHandler {
3030

3131
/// Process a window update frame received from the remote end.
3232
void processWindowUpdate(WindowUpdateFrame frame) {
33-
int oldWindowSize = _peerWindow.size;
34-
3533
int increment = frame.windowSizeIncrement;
3634
if ((_peerWindow.size + increment) > Window.MAX_WINDOW_SIZE) {
3735
throw new FlowControlException(
@@ -43,7 +41,7 @@ abstract class AbstractOutgoingWindowHandler {
4341

4442
// If we transitioned from an negative/empty window to a positive window
4543
// we'll fire an event that more data frames can be sent now.
46-
if (oldWindowSize <= 0 && _peerWindow.size > 0) {
44+
if (positiveWindow.wouldBuffer && _peerWindow.size > 0) {
4745
positiveWindow.markUnBuffered();
4846
}
4947
}
@@ -86,6 +84,8 @@ class OutgoingStreamWindowHandler extends AbstractOutgoingWindowHandler {
8684
_peerWindow.modify(difference);
8785
if (_peerWindow.size <= 0) {
8886
positiveWindow.markBuffered();
87+
} else if (positiveWindow.wouldBuffer) {
88+
positiveWindow.markUnBuffered();
8989
}
9090
}
9191
}

test/src/flowcontrol/window_handler_test.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,17 @@ main() {
8383
handler = new OutgoingStreamWindowHandler(window);
8484

8585
expect(handler.positiveWindow.wouldBuffer, isFalse);
86-
handler.positiveWindow.bufferEmptyEvents.listen(
86+
final bufferEmpty = handler.positiveWindow.bufferEmptyEvents.listen(
8787
expectAsync1((_) {}, count: 0));
8888
handler.processInitialWindowSizeSettingChange(-window.size);
8989
expect(handler.positiveWindow.wouldBuffer, isTrue);
9090
expect(handler.peerWindowSize, 0);
9191
expect(window.size, 0);
92+
bufferEmpty.onData(expectAsync1((_) {}, count: 1));
93+
handler.processInitialWindowSizeSettingChange(1);
94+
expect(handler.positiveWindow.wouldBuffer, isFalse);
95+
expect(handler.peerWindowSize, 1);
96+
expect(window.size, 1);
9297

9398
expect(() => handler.processInitialWindowSizeSettingChange(
9499
Window.MAX_WINDOW_SIZE + 1), throwsA(isFlowControlException));

0 commit comments

Comments
 (0)