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

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git


The following commit(s) were added to refs/heads/main by this push:
     new 0f5d0daf13 GH-3008: Rename as HttpLib.finishInputStream. Handle HTTP 
request errors for string returns.
0f5d0daf13 is described below

commit 0f5d0daf13f74f2b1fadf29b8b8f9779e4088e35
Author: Andy Seaborne <[email protected]>
AuthorDate: Mon Aug 4 10:49:02 2025 +0100

    GH-3008: Rename as HttpLib.finishInputStream. Handle HTTP request errors 
for string returns.
---
 .../java/org/apache/jena/http/AsyncHttpRDF.java    |  8 +++++++-
 .../main/java/org/apache/jena/http/HttpLib.java    | 17 +++++++++-------
 .../main/java/org/apache/jena/http/HttpRDF.java    |  4 ++--
 .../jena/sparql/exec/http/QueryExecHTTP.java       | 23 +++++++++++-----------
 .../jena/sparql/exec/http/UpdateExecHTTP.java      | 11 ++++++++---
 5 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/http/AsyncHttpRDF.java 
b/jena-arq/src/main/java/org/apache/jena/http/AsyncHttpRDF.java
index a7954ec47e..5eeee4429b 100644
--- a/jena-arq/src/main/java/org/apache/jena/http/AsyncHttpRDF.java
+++ b/jena-arq/src/main/java/org/apache/jena/http/AsyncHttpRDF.java
@@ -136,7 +136,13 @@ public class AsyncHttpRDF {
         CompletableFuture<HttpResponse<InputStream>> cf = 
asyncGetToInput(httpClient, url, modifier);
         Transactional transact = ( _transactional == null ) ? 
TransactionalNull.create() : _transactional;
         return cf.thenApply(httpResponse->{
-            transact.executeWrite(()->HttpRDF.httpResponseToStreamRDF(url, 
httpResponse, dest));
+            transact.executeWrite(()->{
+                try {
+                    HttpRDF.httpResponseToStreamRDF(url, httpResponse, dest);
+                } finally {
+                    HttpLib.finishResponse(httpResponse);
+                }
+            });
             return null;
         });
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/http/HttpLib.java 
b/jena-arq/src/main/java/org/apache/jena/http/HttpLib.java
index 76ab6d7839..1895105624 100644
--- a/jena-arq/src/main/java/org/apache/jena/http/HttpLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/http/HttpLib.java
@@ -135,7 +135,7 @@ public class HttpLib {
 
     /**
      * Get the InputStream from an HttpResponse, handling possible compression 
settings.
-     * The application must consume or close the {@code InputStream} (see 
{@link #finish(InputStream)}).
+     * The application must consume or close the {@code InputStream} (see 
{@link #finishInputStream(InputStream)}).
      * Closing the InputStream may close the HTTP connection.
      * Assumes the status code has been handled e.g. {@link 
#handleHttpStatusCode} has been called.
      */
@@ -238,7 +238,7 @@ public class HttpLib {
      */
     public static void handleResponseNoBody(HttpResponse<InputStream> 
response) {
         handleHttpStatusCode(response);
-        finish(response);
+        finishResponse(response);
     }
 
     /**
@@ -265,8 +265,11 @@ public class HttpLib {
         }
         try {
             return IO.readWholeFileAsUTF8(input);
-        } catch (RuntimeIOException e) { throw new HttpException(e); }
-        finally { IO.close(input); }
+        } catch (RuntimeIOException e) {
+            throw new HttpException(e);
+        } finally {
+            finishInputStream(input);
+        }
     }
 
     /**
@@ -307,18 +310,18 @@ public class HttpLib {
      * {@code close} may close the underlying HTTP connection.
      *  See {@link BodySubscribers#ofInputStream()}.
      */
-    private static void finish(HttpResponse<InputStream> response) {
+    public static void finishResponse(HttpResponse<InputStream> response) {
         InputStream input = response.body();
         if ( input == null )
             return;
-        finish(input);
+        finishInputStream(input);
     }
 
     /** Read to end of {@link InputStream}.
      *  {@code close} may close the underlying HTTP connection.
      *  See {@link BodySubscribers#ofInputStream()}.
      */
-    public static void finish(InputStream input) {
+    public static void finishInputStream(InputStream input) {
         consumeAndClose(input);
     }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/http/HttpRDF.java 
b/jena-arq/src/main/java/org/apache/jena/http/HttpRDF.java
index 888ffe4431..db95d8b007 100644
--- a/jena-arq/src/main/java/org/apache/jena/http/HttpRDF.java
+++ b/jena-arq/src/main/java/org/apache/jena/http/HttpRDF.java
@@ -149,13 +149,13 @@ public class HttpRDF {
             throw ex;
         } finally {
             // Even if parsing finished, it is possible we only read part of 
the input stream (e.g. RDF/XML).
-            finish(in);
+            finishInputStream(in);
         }
     }
 
     /**
      * MUST consume or close the input stream
-     * @see HttpLib#finish(HttpResponse)
+     * @see HttpLib#finishResponse(HttpResponse)
      */
     private static HttpResponse<InputStream> execGetToInput(HttpClient client, 
String url, Consumer<HttpRequest.Builder> modifier) {
         Objects.requireNonNull(client);
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/QueryExecHTTP.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/QueryExecHTTP.java
index 94811368fc..9a1d52202d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/QueryExecHTTP.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/QueryExecHTTP.java
@@ -241,10 +241,13 @@ public class QueryExecHTTP implements QueryExec {
         if (lang == null) {
             raiseException("Endpoint returned Content-Type: " + 
actualContentType + " which is not supported for ASK queries", request, 
response, in);
         }
-        boolean result = ResultSetMgr.readBoolean(in, lang);
-        finish(in);
-        return result;
-    }
+        try {
+            boolean result = ResultSetMgr.readBoolean(in, lang);
+            return result;
+        } finally {
+            finishInputStream(in);
+        }
+   }
 
     private String removeCharset(String contentType) {
         if ( contentType == null )
@@ -307,9 +310,8 @@ public class QueryExecHTTP implements QueryExec {
         Lang lang = p.getRight();
         try {
             RDFDataMgr.read(graph, in, lang);
-        } catch (RiotException ex) {
-            finish(in);
-            throw ex;
+        } finally {
+            finishInputStream(in);
         }
         return graph;
     }
@@ -320,9 +322,8 @@ public class QueryExecHTTP implements QueryExec {
         Lang lang = p.getRight();
         try {
             RDFDataMgr.read(dataset, in, lang);
-        } catch (RiotException ex) {
-            finish(in);
-            throw ex;
+        } finally {
+            finishInputStream(in);
         }
         return dataset;
     }
@@ -387,7 +388,7 @@ public class QueryExecHTTP implements QueryExec {
         InputStream in = HttpLib.getInputStream(response);
         try {
             return JSON.parseAny(in).getAsArray();
-        } finally { finish(in); }
+        } finally { finishInputStream(in); }
     }
 
     @Override
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/UpdateExecHTTP.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/UpdateExecHTTP.java
index 1269083107..102b38df2c 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/UpdateExecHTTP.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/exec/http/UpdateExecHTTP.java
@@ -141,9 +141,12 @@ public class UpdateExecHTTP implements UpdateExec {
         HttpRequest request = builder.POST(body).build();
         logUpdate(updateString, request);
         HttpResponse<InputStream> response = HttpLib.execute(httpClient, 
request);
+        // Consumes and closes the input stream.
         return HttpLib.handleResponseRtnString(response, 
this::setRetainedConnection);
     }
 
+    // abort() may be called while waiting for the remote update to complete.
+    // Capture the input stream (from HttpLib.handleResponseRtnString)
     private void setRetainedConnection(InputStream in) {
         synchronized (cancelSignal) {
             retainedConnection = in;
@@ -155,8 +158,10 @@ public class UpdateExecHTTP implements UpdateExec {
 
     private static void logUpdate(String updateString, HttpRequest request) {}
 
-    /** Best effort that tries to close an underlying HTTP connection.
-     *  May still hang waiting for the HTTP request to complete. */
+    /**
+     * Best effort that tries to close an underlying HTTP connection.
+     * May still hang waiting for the HTTP request to complete.
+     */
     @Override
     public void abort() {
         cancelSignal.set(true);
@@ -164,7 +169,7 @@ public class UpdateExecHTTP implements UpdateExec {
             try {
                 InputStream in = retainedConnection;
                 if (in != null) {
-                    in.close();
+                    HttpLib.finishInputStream(in);
                     retainedConnection = null;
                 }
             } catch (Exception ex) {

Reply via email to