Cronet fails when it receives data frame larger than 16384 bytes |
||||||||||
Issue descriptionVersion of Google Chrome (Wrench-> About Google Chrome): 56.0.2907 We are using the cronet_c_for_grpc interface. It seems that when Cronet receives an HTTP2 frame of size larger than 16384 Bytes it emits an exception "[1102/162433:FATAL:spdy_session.cc(378)] Check failed: false." due to some failure in "SpdyFramer::ValidationFrameHeader". We wonder if this is a hard written restriction, a configurable parameter, or a bug. Appreciate a lot if you could check for us.
,
Nov 17 2016
,
Nov 17 2016
Looping to bnc@ , who made some latest changes in spdy_session.cc. Almost similar issue : https://bugs.chromium.org/p/chromium/issues/detail?id=666007, but not sure its the dupe of this.
,
Nov 17 2016
Thanks! This does not seem to be the same issue as #666007. This issue is triggered by large frame size and #666007 seems to be about some particular incoming header format (I guess).
,
Nov 18 2016
I am no expert in this part of the code but the internal version of spdy_session.cc has changed and doesn't even have the failing function from your log message. Maybe updating to a newer version of the Cronet lib (if it tracks exactly the internal implementation) might fix it for you.
,
Nov 18 2016
That was my bad; I got the function name wrong. The failing function name is net::SpdyFramer::ValidateFrameHeader.
I tried this on a newer version 56.0.2914.0 and it did not quite help.
Here's a complete stack trace when the problem occurs. I hope this would help:
* thread #5: tid = 0x12fc5d, 0x0000000111ce3744 Cronet`base::debug::BreakDebugger() + 20 at debugger_posix.cc:262, name = 'Chrome Network IO Thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
* frame #0: 0x0000000111ce3744 Cronet`base::debug::BreakDebugger() + 20 at debugger_posix.cc:262
frame #1: 0x0000000111d51658 Cronet`logging::LogMessage::~LogMessage(this=0x00007000005a9bb0) + 4296 at logging.cc:748
frame #2: 0x0000000111d4e385 Cronet`logging::LogMessage::~LogMessage(this=0x00007000005a9bb0) + 21 at logging.cc:528
frame #3: 0x00000001129fcb88 Cronet`net::MapFramerErrorToNetError(err=SPDY_OVERSIZED_PAYLOAD) + 424 at spdy_session.cc:378
frame #4: 0x0000000112a1ce00 Cronet`net::SpdySession::OnError(this=0x00007fbd5c01ec00, error_code=SPDY_OVERSIZED_PAYLOAD) + 272 at spdy_session.cc:1930
frame #5: 0x00000001129618cd Cronet`net::BufferedSpdyFramer::OnError(this=0x00007fbd5b129e40, spdy_framer=0x00007fbd5b129e48) + 301 at buffered_spdy_framer.cc:45
frame #6: 0x00000001129ae57a Cronet`net::SpdyFramer::set_error(this=0x00007fbd5b129e48, error=SPDY_OVERSIZED_PAYLOAD) + 666 at spdy_framer.cc:500
frame #7: 0x00000001129b7f4b Cronet`net::SpdyFramer::ValidateFrameHeader(this=0x00007fbd5b129e48, is_control_frame=false, frame_type_field=0, payload_length_field=32768) + 2331 at spdy_framer.cc:849
frame #8: 0x00000001129b08fd Cronet`net::SpdyFramer::ProcessCommonHeader(this=0x00007fbd5b129e48, data="", len=8144) + 3997 at spdy_framer.cc:962
frame #9: 0x00000001129af108 Cronet`net::SpdyFramer::ProcessInput(this=0x00007fbd5b129e48, data="", len=8153) + 1704 at spdy_framer.cc:639
frame #10: 0x00000001129640a4 Cronet`net::BufferedSpdyFramer::ProcessInput(this=0x00007fbd5b129e40, data="", len=8192) + 52 at buffered_spdy_framer.cc:232
frame #11: 0x0000000112a1483c Cronet`net::SpdySession::DoReadComplete(this=0x00007fbd5c01ec00, result=8192) + 2220 at spdy_session.cc:1345
frame #12: 0x0000000112a13889 Cronet`net::SpdySession::DoReadLoop(this=0x00007fbd5c01ec00, expected_read_state=READ_STATE_DO_READ_COMPLETE, result=8192) + 713 at spdy_session.cc:1271
frame #13: 0x0000000112a0604e Cronet`net::SpdySession::PumpReadLoop(this=0x00007fbd5c01ec00, expected_read_state=READ_STATE_DO_READ_COMPLETE, result=8192) + 238 at spdy_session.cc:1246
frame #14: 0x0000000112a4495b Cronet`void base::internal::FunctorTraits<void (net::SpdySession::*)(net::SpdySession::ReadState, int), void>::Invoke<base::WeakPtr<net::SpdySession> const&, net::SpdySession::ReadState const&, int>(method=60 5f a0 12 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007fbd5b1304d0, args=0x00007fbd5b1304e0, args=0x00007000005ae4fc)(net::SpdySession::ReadState, int), base::WeakPtr<net::SpdySession> const&&&, net::SpdySession::ReadState const&&&, int&&) + 171 at bind_internal.h:214
frame #15: 0x0000000112a44855 Cronet`void base::internal::InvokeHelper<true, void>::MakeItSo<void (functor=0x00007fbd5b1304c0, weak_ptr=0x00007fbd5b1304d0, args=0x00007fbd5b1304e0, args=0x00007000005ae4fc)(net::SpdySession::ReadState, int), base::WeakPtr<net::SpdySession> const&, net::SpdySession::ReadState const&, int>(void (net::SpdySession::* const&&&)(net::SpdySession::ReadState, int), base::WeakPtr<net::SpdySession> const&&&, net::SpdySession::ReadState const&&&, int&&) + 133 at bind_internal.h:305
frame #16: 0x0000000112a447c9 Cronet`void base::internal::Invoker<base::internal::BindState<void (net::SpdySession::*)(net::SpdySession::ReadState, int), base::WeakPtr<net::SpdySession>, net::SpdySession::ReadState>, void (int)>::RunImpl<void (functor=0x00007fbd5b1304c0, bound=0x00007fbd5b1304d0, (null)=IndexSequence<0, 1> @ 0x00007000005ae468, unbound_args=0x00007000005ae4fc)(net::SpdySession::ReadState, int), std::__1::tuple<base::WeakPtr<net::SpdySession>, net::SpdySession::ReadState> const&, 0ul, 1ul>(void (net::SpdySession::* const&&&)(net::SpdySession::ReadState, int), std::__1::tuple<base::WeakPtr<net::SpdySession>, net::SpdySession::ReadState> const&&&, base::IndexSequence<0ul, 1ul>, int&&) + 121 at bind_internal.h:361
frame #17: 0x0000000112a446e4 Cronet`base::internal::Invoker<base::internal::BindState<void (net::SpdySession::*)(net::SpdySession::ReadState, int), base::WeakPtr<net::SpdySession>, net::SpdySession::ReadState>, void (int)>::Run(base=0x00007fbd5b1304a0, unbound_args=0x00007000005ae4fc) + 68 at bind_internal.h:339
frame #18: 0x0000000111c04faa Cronet`base::internal::RunMixin<base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >::Run(this=0x00007000005ae538, args=8192) const + 74 at callback.h:64
frame #19: 0x000000011213b64e Cronet`net::SSLClientSocketImpl::DoReadCallback(this=0x00007fbd59d18870, rv=8192) + 110 at ssl_client_socket_impl.cc:1012
frame #20: 0x000000011213aacd Cronet`net::SSLClientSocketImpl::RetryAllOperations(this=0x00007fbd59d18870) + 189 at ssl_client_socket_impl.cc:1501
frame #21: 0x000000011213aa05 Cronet`net::SSLClientSocketImpl::OnReadReady(this=0x00007fbd59d18870) + 21 at ssl_client_socket_impl.cc:839
frame #22: 0x000000011212cbe6 Cronet`net::SocketBIOAdapter::OnSocketReadComplete(this=0x00007fbd59d1f120, result=17408) + 262 at socket_bio_adapter.cc:136
frame #23: 0x000000011212f219 Cronet`void base::internal::FunctorTraits<void (net::SocketBIOAdapter::*)(int), void>::Invoke<base::WeakPtr<net::SocketBIOAdapter> const&, int>(method=e0 ca 12 12 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007fbd59d19c10, args=0x00007000005ae8cc)(int), base::WeakPtr<net::SocketBIOAdapter> const&&&, int&&) + 153 at bind_internal.h:214
frame #24: 0x000000011212f125 Cronet`void base::internal::InvokeHelper<true, void>::MakeItSo<void (functor=0x00007fbd59d19c00, weak_ptr=0x00007fbd59d19c10, args=0x00007000005ae8cc)(int), base::WeakPtr<net::SocketBIOAdapter> const&, int>(void (net::SocketBIOAdapter::* const&&&)(int), base::WeakPtr<net::SocketBIOAdapter> const&&&, int&&) + 117 at bind_internal.h:305
frame #25: 0x000000011212f0a8 Cronet`void base::internal::Invoker<base::internal::BindState<void (net::SocketBIOAdapter::*)(int), base::WeakPtr<net::SocketBIOAdapter> >, void (int)>::RunImpl<void (functor=0x00007fbd59d19c00, bound=0x00007fbd59d19c10, (null)=IndexSequence<0> @ 0x00007000005ae840, unbound_args=0x00007000005ae8cc)(int), std::__1::tuple<base::WeakPtr<net::SocketBIOAdapter> > const&, 0ul>(void (net::SocketBIOAdapter::* const&&&)(int), std::__1::tuple<base::WeakPtr<net::SocketBIOAdapter> > const&&&, base::IndexSequence<0ul>, int&&) + 88 at bind_internal.h:361
frame #26: 0x000000011212eff4 Cronet`base::internal::Invoker<base::internal::BindState<void (net::SocketBIOAdapter::*)(int), base::WeakPtr<net::SocketBIOAdapter> >, void (int)>::Run(base=0x00007fbd59d19be0, unbound_args=0x00007000005ae8cc) + 68 at bind_internal.h:339
frame #27: 0x0000000111c04faa Cronet`base::internal::RunMixin<base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >::Run(this=0x00007fbd5b12c338, args=17408) const + 74 at callback.h:64
frame #28: 0x0000000112929e58 Cronet`net::TCPClientSocket::DidCompleteReadWrite(this=0x00007fbd59e146d0, callback=0x00007fbd5b12c338, result=17408), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int) + 120 at tcp_client_socket.cc:374
frame #29: 0x000000011292961b Cronet`net::TCPClientSocket::DidCompleteRead(this=0x00007fbd59e146d0, callback=0x00007fbd5b12c338, result=17408), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int) + 75 at tcp_client_socket.cc:357
frame #30: 0x000000011292b157 Cronet`void base::internal::FunctorTraits<void (net::TCPClientSocket::*)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), void>::Invoke<net::TCPClientSocket*, base::Callback<void (method=d0 95 92 12 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007000005aeaa8, args=0x00007fbd5b12c338, args=0x00007000005aeb5c), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int>(void (net::TCPClientSocket::*)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPClientSocket*&&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&&&, int&&) + 167 at bind_internal.h:214
frame #31: 0x000000011292b05a Cronet`void base::internal::InvokeHelper<false, void>::MakeItSo<void (functor=0x00007fbd5b12c320, args=0x00007000005aeaa8, args=0x00007fbd5b12c338, args=0x00007000005aeb5c)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPClientSocket*, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int>(void (net::TCPClientSocket::* const&&&)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPClientSocket*&&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&&&, int&&) + 122 at bind_internal.h:285
frame #32: 0x000000011292afd9 Cronet`void base::internal::Invoker<base::internal::BindState<void (net::TCPClientSocket::*)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), base::internal::UnretainedWrapper<net::TCPClientSocket>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (int)>::RunImpl<void (functor=0x00007fbd5b12c320, bound=0x00007fbd5b12c330, (null)=IndexSequence<0, 1> @ 0x00007000005aeac8, unbound_args=0x00007000005aeb5c)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), std::__1::tuple<base::internal::UnretainedWrapper<net::TCPClientSocket>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> > const&, 0ul, 1ul>(void (net::TCPClientSocket::* const&&&)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), std::__1::tuple<base::internal::UnretainedWrapper<net::TCPClientSocket>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> > const&&&, base::IndexSequence<0ul, 1ul>, int&&) + 121 at bind_internal.h:361
frame #33: 0x000000011292aef4 Cronet`base::internal::Invoker<base::internal::BindState<void (net::TCPClientSocket::*)(base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), base::internal::UnretainedWrapper<net::TCPClientSocket>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (int)>::Run(base=0x00007fbd5b12c300, unbound_args=0x00007000005aeb5c) + 68 at bind_internal.h:339
frame #34: 0x0000000111c04faa Cronet`base::internal::RunMixin<base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >::Run(this=0x00007fbd5b12f900, args=17408) const + 74 at callback.h:64
frame #35: 0x000000011292ee24 Cronet`net::TCPSocketPosix::ReadCompleted(this=0x00007fbd59e14f40, buf=0x00007fbd5b12f8f8, callback=0x00007fbd5b12f900, rv=17408), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int) + 292 at tcp_socket_posix.cc:591
frame #36: 0x000000011293359a Cronet`void base::internal::FunctorTraits<void (net::TCPSocketPosix::*)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), void>::Invoke<net::TCPSocketPosix*, scoped_refptr<net::IOBuffer> const&, base::Callback<void (method=00 ed 92 12 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007000005aee30, args=0x00007fbd5b12f8f8, args=0x00007fbd5b12f900, args=0x00007000005aeeec), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int>(void (net::TCPSocketPosix::*)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPSocketPosix*&&, scoped_refptr<net::IOBuffer> const&&&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&&&, int&&) + 186 at bind_internal.h:214
frame #37: 0x000000011293342a Cronet`void base::internal::InvokeHelper<false, void>::MakeItSo<void (functor=0x00007fbd5b12f8e0, args=0x00007000005aee30, args=0x00007fbd5b12f8f8, args=0x00007fbd5b12f900, args=0x00007000005aeeec)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPSocketPosix*, scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int>(void (net::TCPSocketPosix::* const&&&)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), net::TCPSocketPosix*&&, scoped_refptr<net::IOBuffer> const&&&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&&&, int&&) + 138 at bind_internal.h:285
frame #38: 0x000000011293339a Cronet`void base::internal::Invoker<base::internal::BindState<void (net::TCPSocketPosix::*)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), base::internal::UnretainedWrapper<net::TCPSocketPosix>, scoped_refptr<net::IOBuffer>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (int)>::RunImpl<void (functor=0x00007fbd5b12f8e0, bound=0x00007fbd5b12f8f0, (null)=IndexSequence<0, 1, 2> @ 0x00007000005aee50, unbound_args=0x00007000005aeeec)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), std::__1::tuple<base::internal::UnretainedWrapper<net::TCPSocketPosix>, scoped_refptr<net::IOBuffer>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> > const&, 0ul, 1ul, 2ul>(void (net::TCPSocketPosix::* const&&&)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), std::__1::tuple<base::internal::UnretainedWrapper<net::TCPSocketPosix>, scoped_refptr<net::IOBuffer>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> > const&&&, base::IndexSequence<0ul, 1ul, 2ul>, int&&) + 154 at bind_internal.h:361
frame #39: 0x0000000112933284 Cronet`base::internal::Invoker<base::internal::BindState<void (net::TCPSocketPosix::*)(scoped_refptr<net::IOBuffer> const&, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, int), base::internal::UnretainedWrapper<net::TCPSocketPosix>, scoped_refptr<net::IOBuffer>, base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (int)>::Run(base=0x00007fbd5b12f8c0, unbound_args=0x00007000005aeeec) + 68 at bind_internal.h:339
frame #40: 0x0000000111c04faa Cronet`base::internal::RunMixin<base::Callback<void (int), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >::Run(this=0x00007000005aef20, args=17408) const + 74 at callback.h:64
frame #41: 0x00000001129038fa Cronet`net::SocketPosix::ReadCompleted(this=0x00007fbd59e14fa0) + 410 at socket_posix.cc:460
frame #42: 0x000000011290343f Cronet`net::SocketPosix::OnFileCanReadWithoutBlocking(this=0x00007fbd59e14fa0, fd=15) + 591 at socket_posix.cc:377
frame #43: 0x0000000111d85dfa Cronet`base::MessagePumpIOSForIO::FileDescriptorWatcher::OnFileCanReadWithoutBlocking(this=0x00007fbd59e14ff8, fd=15, pump=0x00007fbd5b123fd0) + 282 at message_pump_io_ios.cc:54
frame #44: 0x0000000111d86d8c Cronet`base::MessagePumpIOSForIO::HandleFdIOEvent(fdref=0x00007fbd5b12d710, callback_types=1, context=0x00007fbd59e14ff8) + 748 at message_pump_io_ios.cc:178
frame #45: 0x00000001078b7364 CoreFoundation`__CFFileDescriptorPerform + 564
frame #46: 0x000000010781b301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #47: 0x00000001078111a7 CoreFoundation`__CFRunLoopDoSources0 + 423
frame #48: 0x00000001078106e3 CoreFoundation`__CFRunLoopRun + 867
frame #49: 0x00000001078100f8 CoreFoundation`CFRunLoopRunSpecific + 488
frame #50: 0x0000000106f50a31 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 267
frame #51: 0x000000011200c9e9 Cronet`base::MessagePumpNSRunLoop::DoRun(this=0x00007fbd5b123fd0, delegate=0x00007fbd5b001920) + 137 at message_pump_mac.mm:580
frame #52: 0x000000011200bd5a Cronet`base::MessagePumpCFRunLoopBase::Run(this=0x00007fbd5b123fd0, delegate=0x00007fbd5b001920) + 122 at message_pump_mac.mm:210
frame #53: 0x0000000111d72385 Cronet`base::MessageLoop::RunHandler(this=0x00007fbd5b001920) + 645 at message_loop.cc:378
frame #54: 0x0000000111e12bc4 Cronet`base::RunLoop::Run(this=0x00007000005b1118) + 68 at run_loop.cc:35
frame #55: 0x0000000111ee055c Cronet`base::Thread::Run(this=0x00007fbd5b001680, run_loop=0x00007000005b1118) + 428 at thread.cc:245
frame #56: 0x0000000111ee1788 Cronet`base::Thread::ThreadMain(this=0x00007fbd5b001680) + 3512 at thread.cc:333
frame #57: 0x0000000111ebcfa7 Cronet`base::(anonymous namespace)::ThreadFunc(params=0x00007fbd5b001300) + 679 at platform_thread_posix.cc:71
frame #58: 0x000000010a50699d libsystem_pthread.dylib`_pthread_body + 131
frame #59: 0x000000010a50691a libsystem_pthread.dylib`_pthread_start + 168
frame #60: 0x000000010a504351 libsystem_pthread.dylib`thread_start + 13
,
Nov 21 2016
Reading through the code of the failing function it is indeed a check for the size of the packet:
if (protocol_version_ == HTTP2 &&
payload_length_field > recv_frame_size_limit_) {
set_error(SPDY_OVERSIZED_PAYLOAD);
}
where recv_frame_size_limit_ is initialized as (1 << 14) so no surprise the check fails for you.
Digging further it seems there is a function called set_recv_frame_size_limit which seems to be public and can change this limit arbitrarily. Have you tried calling it?
,
Nov 21 2016
Ahh thank you for pointing that out. No we are unable to call that func since we are using Cronet's 'cronet_c_for_grpc' api and do not have access to it. I guess right now I will have to treat it as a hard written value. Many thanks!
,
Nov 21 2016
Actually looping in bnc@. This is affecting GRPC usage of cronet bidirectional stream over H2 on iOS. I wonder whether or not it also affects Android implementation?
,
Nov 21 2016
,
Nov 22 2016
,
Nov 22 2016
Removing the enterprise label and myself from this bug as I think I can't contribute to this discussion any further and it is not related tot he enterprise components of Chrome either.
,
Nov 22 2016
We'll discuss this issue in Cronet triage. I'm also removing proxy label
,
Nov 22 2016
,
Nov 22 2016
Sorry for the late response. The HTTP/2 specification says that frames of length greater than 2^14 (16,384) MUST NOT be sent unless the receiver has set a larger value for SETTINGS_MAX_FRAME_SIZE. The receiver in this case is Cronet, and Cronet currently does not set a value for SETTINGS_MAX_FRAME_SIZE (this would be sent by Cronet in a SETTINGS frame). It sounds like the server you are using does not conform to the specification. I believe this is working as intended, so I'm closing the issue. If you believe you would benefit from a knob to increase maximum frame size, please feel free to file another issue against Cronet, that would be a feature request. It is certainly possible to add such a setting to the API, and plumb it through, and make Cronet send a larger value in the initial SETTINGS frame that it is already sending anyway. There never was a need for this, since the dozen or so bytes frame header is already negligible compared to a 16 kB payload, but it is certainly technically possible if there is a need for it.
,
Nov 22 2016
Forgot the link to the relevant part in the spec: http://httpwg.org/specs/rfc7540.html#FrameHeader.
,
Nov 22 2016
Good to know that Bence. Thank you! |
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by kkaluri@chromium.org
, Nov 17 2016