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) {