MCPcopy Create free account
hub / github.com/apache/brpc / OnSettings

Method OnSettings

src/brpc/policy/http2_rpc_protocol.cpp:848–916  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

846}
847
848H2ParseResult H2Context::OnSettings(
849 butil::IOBufBytesIterator& it, const H2FrameHead& frame_head) {
850 // SETTINGS frames always apply to a connection, never a single stream.
851 // The stream identifier for a SETTINGS frame MUST be zero (0x0). If an
852 // endpoint receives a SETTINGS frame whose stream identifier field is
853 // anything other than 0x0, the endpoint MUST respond with a connection
854 // error (Section 5.4.1) of type PROTOCOL_ERROR.
855 if (frame_head.stream_id != 0) {
856 LOG(ERROR) << "Invalid stream_id=" << frame_head.stream_id;
857 return MakeH2Error(H2_PROTOCOL_ERROR);
858 }
859 if (frame_head.flags & H2_FLAGS_ACK) {
860 if (frame_head.payload_size != 0) {
861 LOG(ERROR) << "Non-zero payload_size=" << frame_head.payload_size
862 << " for settings-ACK";
863 return MakeH2Error(H2_PROTOCOL_ERROR);
864 }
865 _local_settings = _unack_local_settings;
866 return MakeH2Message(NULL);
867 }
868 const int64_t old_stream_window_size = _remote_settings.stream_window_size;
869 if (!_remote_settings_received) {
870 // To solve the problem that sender can't send large request before receving
871 // remote setting, the initial window size of stream/connection is set to
872 // MAX_WINDOW_SIZE(see constructor of H2Context).
873 // As a result, in the view of remote side, window size is 65535 by default so
874 // it may not send its stream size to sender, making stream size still be
875 // MAX_WINDOW_SIZE. In this case we need to revert this value to default.
876 H2Settings tmp_settings;
877 if (!ParseH2Settings(&tmp_settings, it, frame_head.payload_size)) {
878 LOG(ERROR) << "Fail to parse from SETTINGS";
879 return MakeH2Error(H2_PROTOCOL_ERROR);
880 }
881 _remote_settings = tmp_settings;
882 _remote_window_left.fetch_sub(
883 H2Settings::MAX_WINDOW_SIZE - H2Settings::DEFAULT_INITIAL_WINDOW_SIZE,
884 butil::memory_order_relaxed);
885 _remote_settings_received = true;
886 } else {
887 if (!ParseH2Settings(&_remote_settings, it, frame_head.payload_size)) {
888 LOG(ERROR) << "Fail to parse from SETTINGS";
889 return MakeH2Error(H2_PROTOCOL_ERROR);
890 }
891 }
892 const int64_t window_diff =
893 static_cast<int64_t>(_remote_settings.stream_window_size)
894 - old_stream_window_size;
895 if (window_diff) {
896 // Do not update the connection flow-control window here, which can only
897 // be changed using WINDOW_UPDATE frames.
898 // https://tools.ietf.org/html/rfc7540#section-6.9.2
899 // TODO(gejun): Has race conditions with AppendAndDestroySelf
900 std::unique_lock<butil::Mutex> mu(_stream_mutex);
901 for (StreamMap::const_iterator it = _pending_streams.begin();
902 it != _pending_streams.end(); ++it) {
903 if (!AddWindowSize(&it->second->_remote_window_left, window_diff)) {
904 return MakeH2Error(H2_FLOW_CONTROL_ERROR);
905 }

Callers

nothing calls this directly

Calls 9

MakeH2ErrorFunction · 0.85
MakeH2MessageFunction · 0.85
ParseH2SettingsFunction · 0.85
AddWindowSizeFunction · 0.85
SerializeFrameHeadFunction · 0.85
WriteAckFunction · 0.85
fetch_subMethod · 0.80
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected