Commit 418bb775 authored by zhujiashun's avatar zhujiashun

ignore_flowcontrol_in_first_req: make parseh2setting unchanged

parent c64fbea7
...@@ -162,14 +162,12 @@ enum H2SettingsIdentifier { ...@@ -162,14 +162,12 @@ enum H2SettingsIdentifier {
// Parse from n bytes from the iterator. // Parse from n bytes from the iterator.
// Returns true on success. // Returns true on success.
bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it, bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it, size_t n) {
size_t n, bool setting_received) {
const uint32_t npairs = n / 6; const uint32_t npairs = n / 6;
if (npairs * 6 != n) { if (npairs * 6 != n) {
LOG(ERROR) << "Invalid payload_size=" << n; LOG(ERROR) << "Invalid payload_size=" << n;
return false; return false;
} }
bool met_stream_window_size = false;
for (uint32_t i = 0; i < npairs; ++i) { for (uint32_t i = 0; i < npairs; ++i) {
uint16_t id = LoadUint16(it); uint16_t id = LoadUint16(it);
uint32_t value = LoadUint32(it); uint32_t value = LoadUint32(it);
...@@ -193,7 +191,6 @@ bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it, ...@@ -193,7 +191,6 @@ bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it,
return false; return false;
} }
out->stream_window_size = value; out->stream_window_size = value;
met_stream_window_size = true;
break; break;
case H2_SETTINGS_MAX_FRAME_SIZE: case H2_SETTINGS_MAX_FRAME_SIZE:
if (value > H2Settings::MAX_OF_MAX_FRAME_SIZE || if (value > H2Settings::MAX_OF_MAX_FRAME_SIZE ||
...@@ -213,15 +210,6 @@ bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it, ...@@ -213,15 +210,6 @@ bool ParseH2Settings(H2Settings* out, butil::IOBufBytesIterator& it,
break; break;
} }
} }
// To solve the problem that sender can't send large request before receving
// remote setting, the initial window size of stream is set to MAX_WINDOW_SIZE
// (see constructor of H2Context).
// As a result, in the view of remote side, window size is 65535 by default so
// it may not send its stream size to sender, making stream size still be
// MAX_WINDOW_SIZE. In this case we need to revert this value to default.
if (!setting_received && !met_stream_window_size) {
out->stream_window_size = H2Settings::DEFAULT_INITIAL_WINDOW_SIZE;
}
return true; return true;
} }
...@@ -878,11 +866,28 @@ H2ParseResult H2Context::OnSettings( ...@@ -878,11 +866,28 @@ H2ParseResult H2Context::OnSettings(
return MakeH2Message(NULL); return MakeH2Message(NULL);
} }
const int64_t old_stream_window_size = _remote_settings.stream_window_size; const int64_t old_stream_window_size = _remote_settings.stream_window_size;
if (!ParseH2Settings(&_remote_settings, it, H2Settings tmp_settings;
frame_head.payload_size, _remote_settings_received)) { H2Settings* settings = &_remote_settings;
if (!_remote_settings_received) {
settings = &tmp_settings;
}
if (!ParseH2Settings(settings, it, frame_head.payload_size)) {
LOG(ERROR) << "Fail to parse from SETTINGS"; LOG(ERROR) << "Fail to parse from SETTINGS";
return MakeH2Error(H2_PROTOCOL_ERROR); return MakeH2Error(H2_PROTOCOL_ERROR);
} }
// To solve the problem that sender can't send large request before receving
// remote setting, the initial window size of stream/connection is set to
// MAX_WINDOW_SIZE(see constructor of H2Context).
// As a result, in the view of remote side, window size is 65535 by default so
// it may not send its stream size to sender, making stream size still be
// MAX_WINDOW_SIZE. In this case we need to revert this value to default.
if (!_remote_settings_received) {
_remote_settings_received = true;
_remote_settings = tmp_settings;
_remote_window_left.fetch_sub(
H2Settings::MAX_WINDOW_SIZE - H2Settings::DEFAULT_INITIAL_WINDOW_SIZE,
butil::memory_order_relaxed);
}
const int64_t window_diff = const int64_t window_diff =
static_cast<int64_t>(_remote_settings.stream_window_size) static_cast<int64_t>(_remote_settings.stream_window_size)
- old_stream_window_size; - old_stream_window_size;
...@@ -906,16 +911,6 @@ H2ParseResult H2Context::OnSettings( ...@@ -906,16 +911,6 @@ H2ParseResult H2Context::OnSettings(
LOG(WARNING) << "Fail to respond settings with ack to " << *_socket; LOG(WARNING) << "Fail to respond settings with ack to " << *_socket;
return MakeH2Error(H2_PROTOCOL_ERROR); return MakeH2Error(H2_PROTOCOL_ERROR);
} }
// To solve the problem that sender can't send large request before receving
// remote setting, the initial window size of connection is set to MAX_WINDOW_SIZE
// (see constructor of H2Context). So when the settings are received, we should
// revert the value to default and respect the remote setting.
if (!_remote_settings_received) {
_remote_settings_received = true;
_remote_window_left.fetch_sub(
H2Settings::MAX_WINDOW_SIZE - H2Settings::DEFAULT_INITIAL_WINDOW_SIZE,
butil::memory_order_relaxed);
}
return MakeH2Message(NULL); return MakeH2Message(NULL);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment