This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch 3.3.x-pending-changes-3.3.3
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 4188889b8e5262f7bb65f244fdcf5d74c66ac541
Author: Nick Vatamaniuc <vatam...@gmail.com>
AuthorDate: Mon Jul 17 16:42:56 2023 -0400

    Fix multipart parser "attachment longer than expected" error
    
    Previously, we used a stale `Waiting` list of workers instead of the updated
    `NewWaiting` one. Then, when we recursed back to the top in
    `maybe_send_data/1`, and tried to reply to all waiting clients, we re-sent 
the
    same block to the client. That client would then get more attachment blocks
    than it expected and would throw an `attachment longer than expected` error.
    
    At the API level this would manifest as an intermittent 400 (bad_request) 
HTTP
    error for multipart document + attachments PUTs. For the error to occur, a
    `{hello_from_writer, ...}` has to be recieved when we're in the bottom part 
of
    `maybe_send_data/1` in the couch_httpd_multipart parser. However, due to how
    CouchDB replicator skips over documents PUTs which generate 4xx errors, the
    effect was that these documents were skipped over during replication, with 
only
    a `doc_write_failures` statistic bump to indicate that something went wrong.
    There is a somewhat related issue for discussion whether that replicator
    behavior is desirable [1]
    
    [1] https://github.com/apache/couchdb/issues/4676.
---
 src/couch/src/couch_httpd_multipart.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/couch/src/couch_httpd_multipart.erl 
b/src/couch/src/couch_httpd_multipart.erl
index 11ee6790e..80fc48a75 100644
--- a/src/couch/src/couch_httpd_multipart.erl
+++ b/src/couch/src/couch_httpd_multipart.erl
@@ -203,7 +203,7 @@ maybe_send_data({Ref, Chunks, Offset, Counters, Waiting}) ->
                         end;
                     {hello_from_writer, Ref, WriterPid} ->
                         C2 = handle_hello(WriterPid, Counters),
-                        maybe_send_data({Ref, NewChunks, NewOffset, C2, 
Waiting});
+                        maybe_send_data({Ref, NewChunks, NewOffset, C2, 
NewWaiting});
                     {get_bytes, Ref, X} ->
                         C2 = update_writer(X, Counters),
                         maybe_send_data({Ref, NewChunks, NewOffset, C2, [X | 
NewWaiting]})

Reply via email to