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

ASF subversion and git services commented on HTTPCORE-799:
----------------------------------------------------------

Commit 9cb751ee37589fd07b13563095959ede3ebac6be in httpcomponents-core's branch 
refs/heads/5.4.x from Matthias Kurz
[ https://gitbox.apache.org/repos/asf?p=httpcomponents-core.git;h=9cb751ee3 ]

HTTPCORE-799: Reset async entity producer state after interrupted writes

Discard buffered but unwritten bytes and partial digest state when async
entity producers are released, so repeating an interrupted production
starts cleanly from the beginning.

Add regression tests for file, path, string, repeatable binary, and
digesting producers.


> Async entity producers retain stale state after interrupted writes
> ------------------------------------------------------------------
>
>                 Key: HTTPCORE-799
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-799
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: HttpCore
>    Affects Versions: 5.4.3, 5.5-beta2
>            Reporter: Matthias
>            Priority: Major
>             Fix For: 5.4.4, 5.5-beta3
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> h2. Description
> Several repeatable async entity producers do not fully reset their 
> per-production state when {{releaseResources()}} is called before the current 
> production has completed.
> h3. Buffered output
> {{FileEntityProducer}}, {{PathEntityProducer}}, 
> {{AbstractCharAsyncEntityProducer}}, and {{AbstractBinAsyncEntityProducer}} 
> can retain bytes that the data channel did not accept. Although the 
> underlying source is reset for a replay, the internal staging buffer still 
> contains the unwritten tail, so those stale bytes are emitted before the 
> complete entity.
> {{StringAsyncEntityProducer}} is affected through 
> {{AbstractCharAsyncEntityProducer}}. Repeatable custom binary producers can 
> be affected through {{AbstractBinAsyncEntityProducer}}.
> For example, with content {{abcdef}}:
> # The producer reads {{abcdef}} and the data channel accepts only {{abc}}.
> # {{releaseResources()}} is called, simulating an interrupted request.
> # The same repeatable producer is used again.
> # The second production emits {{defabcdef}} instead of {{abcdef}}.
> h3. Digest state
> {{DigestingEntityProducer.releaseResources()}} delegates to the wrapped 
> producer but does not reset its {{MessageDigest}}. If the first production 
> writes {{abc}} before interruption and the replay writes {{abcdef}}, the 
> replay body can be correct while {{getDigest()}} and the {{digest}} trailer 
> contain the MD5 of {{abcabcdef}} ({{89091e2d8ada6ecb23f3d2b71fb1764b}}) 
> instead of the MD5 of {{abcdef}} ({{e80b5017098950fc58aad83c8c14978e}}).
> h2. Context
> This was exposed while testing an HTTP/2 authentication retry after a server 
> returned a {{401}} response and then reset the stream with 
> {{RST_STREAM(NO_ERROR)}}. The request producer was released mid-write and 
> reused for the retry. See 
> [HTTPCLIENT-2433|https://issues.apache.org/jira/browse/HTTPCLIENT-2433] for 
> the related HttpClient issue.
> The HttpCore problem is not specific to HTTP/2 or authentication; it can 
> occur whenever a repeatable producer is released after a partial write and 
> then reused.
> h2. Expected behavior
> Calling {{releaseResources()}} should discard pending output and reset all 
> per-production digest state. A subsequent production should emit exactly the 
> original entity, and its digest should cover only that production.
> h2. Actual behavior
> Buffered but unwritten bytes can be prepended to the next production, and 
> bytes accepted during an interrupted production can be included in the 
> replay's digest.
> h2. Affected code
> * {{org.apache.hc.core5.http.nio.entity.FileEntityProducer}}
> * {{org.apache.hc.core5.http.nio.entity.PathEntityProducer}}
> * {{org.apache.hc.core5.http.nio.entity.AbstractCharAsyncEntityProducer}} 
> (including {{StringAsyncEntityProducer}})
> * {{org.apache.hc.core5.http.nio.entity.AbstractBinAsyncEntityProducer}} (for 
> repeatable subclasses)
> * {{org.apache.hc.core5.http.nio.entity.DigestingEntityProducer}}
> The problem is present in HttpCore 5.4.3, 5.5-beta2, and the current 
> {{5.4.x}} and {{master}} branches.
> h2. Proposed fix
> Clear the internal staging buffers when the file, path, character, and binary 
> producers are released. Reset {{DigestingEntityProducer}}'s {{MessageDigest}} 
> before releasing its wrapped producer, while preserving the completed 
> {{digest}} value returned by {{getDigest()}}.
> Add regression tests that interrupt production after a partial channel write, 
> release the producer, and verify that the next production contains the 
> original entity exactly once and calculates its digest only from the replayed 
> bytes.
> Implementation: 
> [apache/httpcomponents-core#698|https://github.com/apache/httpcomponents-core/pull/698]



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to