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

rnewson pushed a commit to branch nouveau-gun-http2
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/nouveau-gun-http2 by this push:
     new 06bb54d77 eliminate 204 responses
06bb54d77 is described below

commit 06bb54d77a8126d2d912a22482ff19d5074ff19b
Author: Robert Newson <[email protected]>
AuthorDate: Fri Jul 11 14:09:57 2025 +0100

    eliminate 204 responses
    
    Jetty or Jersey sends a 204 No Content response with a Content-Length: 0
    header over http/2 (though not over http 1.1...)
    
    Gun considers this a fatal error 
(https://github.com/ninenines/cowlib/issues/140)
    
    Return `{"ok":true}` instead of nothing so we don't bump into this problem.
---
 .../java/org/apache/couchdb/nouveau/api/Ok.java    | 26 ++++++++++++++++++++++
 .../couchdb/nouveau/resources/IndexResource.java   | 26 ++++++++++++----------
 src/nouveau/src/nouveau_api.erl                    |  8 +++----
 3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/nouveau/src/main/java/org/apache/couchdb/nouveau/api/Ok.java 
b/nouveau/src/main/java/org/apache/couchdb/nouveau/api/Ok.java
new file mode 100644
index 000000000..b393e1978
--- /dev/null
+++ b/nouveau/src/main/java/org/apache/couchdb/nouveau/api/Ok.java
@@ -0,0 +1,26 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.couchdb.nouveau.api;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Ok {
+
+    public static final Ok INSTANCE = new Ok();
+
+    @JsonProperty
+    public boolean ok() {
+        return true;
+    }
+}
diff --git 
a/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java 
b/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
index a6ca2c47b..a52e00da9 100644
--- 
a/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
+++ 
b/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
@@ -35,6 +35,7 @@ import org.apache.couchdb.nouveau.api.DocumentUpdateRequest;
 import org.apache.couchdb.nouveau.api.IndexDefinition;
 import org.apache.couchdb.nouveau.api.IndexInfo;
 import org.apache.couchdb.nouveau.api.IndexInfoRequest;
+import org.apache.couchdb.nouveau.api.Ok;
 import org.apache.couchdb.nouveau.api.SearchRequest;
 import org.apache.couchdb.nouveau.api.SearchResults;
 import org.apache.couchdb.nouveau.core.IndexManager;
@@ -54,27 +55,29 @@ public final class IndexResource {
     }
 
     @PUT
-    public void createIndex(@PathParam("name") String name, @NotNull @Valid 
IndexDefinition indexDefinition)
+    public Ok createIndex(@PathParam("name") String name, @NotNull @Valid 
IndexDefinition indexDefinition)
             throws IOException {
         indexManager.create(name, indexDefinition);
+        return Ok.INSTANCE;
     }
 
     @DELETE
     @Path("/doc/{docId}")
-    public void deleteDoc(
+    public Ok deleteDoc(
             @PathParam("name") String name,
             @PathParam("docId") String docId,
             @NotNull @Valid DocumentDeleteRequest request)
             throws Exception {
-        indexManager.with(name, (index) -> {
+        return indexManager.with(name, (index) -> {
             index.delete(docId, request);
-            return null;
+            return Ok.INSTANCE;
         });
     }
 
     @DELETE
-    public void deletePath(@PathParam("name") String path, @Valid final 
List<String> exclusions) throws IOException {
+    public Ok deletePath(@PathParam("name") String path, @Valid final 
List<String> exclusions) throws IOException {
         indexManager.deleteAll(path, exclusions);
+        return Ok.INSTANCE;
     }
 
     @GET
@@ -85,9 +88,8 @@ public final class IndexResource {
     }
 
     @POST
-    public void setIndexInfo(@PathParam("name") String name, @NotNull @Valid 
IndexInfoRequest request)
-            throws Exception {
-        indexManager.with(name, (index) -> {
+    public Ok setIndexInfo(@PathParam("name") String name, @NotNull @Valid 
IndexInfoRequest request) throws Exception {
+        return indexManager.with(name, (index) -> {
             if (request.getMatchUpdateSeq().isPresent()
                     && request.getUpdateSeq().isPresent()) {
                 index.setUpdateSeq(
@@ -99,7 +101,7 @@ public final class IndexResource {
                         request.getMatchPurgeSeq().getAsLong(),
                         request.getPurgeSeq().getAsLong());
             }
-            return null;
+            return Ok.INSTANCE;
         });
     }
 
@@ -114,14 +116,14 @@ public final class IndexResource {
 
     @PUT
     @Path("/doc/{docId}")
-    public void updateDoc(
+    public Ok updateDoc(
             @PathParam("name") String name,
             @PathParam("docId") String docId,
             @NotNull @Valid DocumentUpdateRequest request)
             throws Exception {
-        indexManager.with(name, (index) -> {
+        return indexManager.with(name, (index) -> {
             index.update(docId, request);
-            return null;
+            return Ok.INSTANCE;
         });
     }
 }
diff --git a/src/nouveau/src/nouveau_api.erl b/src/nouveau/src/nouveau_api.erl
index 044251ec5..aa981e6ef 100644
--- a/src/nouveau/src/nouveau_api.erl
+++ b/src/nouveau/src/nouveau_api.erl
@@ -72,7 +72,7 @@ create_index(#index{} = Index, IndexDefinition) ->
         index_path(Index), [?JSON_CONTENT_TYPE], <<"PUT">>, 
jiffy:encode(IndexDefinition)
     ),
     case Resp of
-        {ok, 204, _, _} ->
+        {ok, 200, _, _} ->
             ok;
         {ok, StatusCode, _, RespBody} ->
             {error, jaxrs_error(StatusCode, RespBody)};
@@ -90,7 +90,7 @@ delete_path(Path, Exclusions) when
         index_path(Path), [?JSON_CONTENT_TYPE], <<"DELETE">>, 
jiffy:encode(Exclusions)
     ),
     case Resp of
-        {ok, 204, _, _} ->
+        {ok, 200, _, _} ->
             ok;
         {ok, StatusCode, _, RespBody} ->
             {error, jaxrs_error(StatusCode, RespBody)};
@@ -125,7 +125,7 @@ purge_doc(#index{} = Index, DocId, MatchSeq, PurgeSeq) when
         doc_path(Index, DocId), [?JSON_CONTENT_TYPE], <<"DELETE">>, 
jiffy:encode(ReqBody)
     ),
     case Resp of
-        {ok, 204, _, _} ->
+        {ok, 200, _, _} ->
             ok;
         {ok, StatusCode, _, RespBody} ->
             {error, jaxrs_error(StatusCode, RespBody)};
@@ -190,7 +190,7 @@ set_seq(#index{} = Index, ReqBody) ->
         index_path(Index), [?JSON_CONTENT_TYPE], <<"POST">>, 
jiffy:encode(ReqBody)
     ),
     case Resp of
-        {ok, 204, _, _} ->
+        {ok, 200, _, _} ->
             ok;
         {ok, StatusCode, _, RespBody} ->
             {error, jaxrs_error(StatusCode, RespBody)};

Reply via email to