[ 
https://issues.apache.org/jira/browse/HTTPCORE-707?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17467231#comment-17467231
 ] 

Lubos Husivarga commented on HTTPCORE-707:
------------------------------------------

Hi [~olegk] 

You are right about the spec, but not about the HttpClient behaviour. The frame 
exceeded exception is thrown when HttpClient is sending a second frame of my 
POST operation and the stacktrace confirms this:

    {*}FrameOutputBuffer.write{*}(RawFrame, WritableByteChannel) line: 70    
    
ClientH2StreamMultiplexer(AbstractH2StreamMultiplexer).{*}streamDataFrame{*}(int,
 AtomicInteger, ByteBuffer, int) line: 342    
    
ClientH2StreamMultiplexer(AbstractH2StreamMultiplexer).{*}streamData{*}(int, 
AtomicInteger, ByteBuffer) line: 363    
    AbstractH2StreamMultiplexer.access$11(AbstractH2StreamMultiplexer, int, 
AtomicInteger, ByteBuffer) line: 345    
    AbstractH2StreamMultiplexer$H2StreamChannelImpl.write(ByteBuffer) line: 
1424    
    ClientH2StreamHandler$1.write(ByteBuffer) line: 92

 

The bug can be spotted directly from constructor of 
AbstractH2StreamMultiplexer, where the outputBuffer is instantiated with 
localConfig (which is default and defines max frame size as 65536) and method 
org.apache.hc.core5.http2.impl.nio.AbstractH2StreamMultiplexer.streamData(int, 
AtomicInteger, ByteBuffer) where the payload is divided into frames, but now 
based on remoteConfig (where the server defined max frame size as 16777215). 
This is the place where the frame size is calculated incorrectly and the second 
frame size in my case was calculated as 98295 bytes. When streamDataFrame(...) 
is called and tries to write to outputBuffer, the Frame size exceeded exception 
is thrown, because the buffer was instantiated with 65536 size.

When I simply replace remoteConfig with localConfig in 
org.apache.hc.core5.http2.impl.nio.AbstractH2StreamMultiplexer.{*}streamData{*}(int,
 AtomicInteger, ByteBuffer):

-            final int maxPayloadSize = Math.min(capacity, 
{*}remoteConfig{*}.getMaxFrameSize());
+            final int maxPayloadSize = Math.min(capacity, 
{*}localConfig{*}.getMaxFrameSize());

it all works, but I am limited with small frame size, since the remote config 
is not affecting the outputBuffer :( This means I will send bigger payloads 
(binary files) slower than server can handle due to small outputBuffer size on 
client side.

I believe 
org.apache.hc.core5.http2.impl.nio.AbstractH2StreamMultiplexer.{*}applyRemoteSettings{*}(H2Config)
 method should enlarge the outputBuffer when it receives the remote config from 
remote side to enable HttpClient to send bigger frames and use full 
capabilities of the server.

 

Here is the log which looks much better. I have removed the raw data output 
with ...

[^http2_flow_frame.txt]

> AbstractH2StreamMultiplexer: FrameOutputBuffer: Frame size exceeds maximum
> --------------------------------------------------------------------------
>
>                 Key: HTTPCORE-707
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-707
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: HttpCore NIO
>    Affects Versions: 5.2-alpha1
>            Reporter: Lubos Husivarga
>            Priority: Major
>         Attachments: context_wire_log.txt, http2_flow_frame.txt
>
>
> AbstractH2StreamMultiplexer initializes outputBuffer with frame size from 
> local config:
> _this.outputBuffer = new FrameOutputBuffer(this.outputMetrics, 
> this.{*}localConfig{*}.getMaxFrameSize());_
>  
> Data are streamed using streamData(...) method which checks maxPayloadSize 
> against remote config:
> _final int maxPayloadSize = Math.min(capacity, 
> {*}remoteConfig{*}.getMaxFrameSize());_
>  
> Issue: When remote config has greater max frame size than local config and 
> the payload is also greater than local max frame size, the FrameOutputBuffer 
> throws "Frame size exceeds maximum" error, since it compares the payload size 
> against local frame size as it was initialized with it, not remote frame size.
>  
> My suggestion: AbstractH2StreamMultiplexer.{*}applyRemoteSettings{*}(...) 
> should update the outputBuffer's max frame size based on remote config.
>  
> I will appreciate your help, as it is really annoying issue depending on 
> remote site config and payload size, so it may be spotted randomly.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org
For additional commands, e-mail: dev-h...@hc.apache.org

Reply via email to