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 03868dfb18 GH-1318: Calculate proper request-target for digest auth use. new 8f24a0ad07 Merge pull request #1319 from afs/digest401 03868dfb18 is described below commit 03868dfb18deea01c2277cf35c49506d8243e222 Author: Andy Seaborne <a...@apache.org> AuthorDate: Tue May 17 15:18:51 2022 +0100 GH-1318: Calculate proper request-target for digest auth use. --- .../main/java/org/apache/jena/http/HttpLib.java | 32 +++++++++++----- .../org/apache/jena/http/TestAuthDigestRemote.java | 43 +++++++++++----------- .../java/org/apache/jena/rdflink/RDFLinkHTTP.java | 10 ++--- 3 files changed, 50 insertions(+), 35 deletions(-) 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 683d6d5b10..106a6442e0 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 @@ -347,15 +347,29 @@ public class HttpLib { return uriStr.substring(0, idx); } - /** RFC7320 "request-target", used in digest authentication. */ + /** + * RFC7616, section 3.4 The Effective Request URI (Section 5.5 of [RFC7230]). + * Unclear whether the query string is/isn't included but for SPARQL, while the query + * may change, the resource is the query service, not a resource named by the + * uri+query string. + * + * This makes query-by-GET and query-by-POST work. + */ public static String requestTarget(URI uri) { + // RFC7616 -> 7230 5.5 + // If the request-target is in authority-form or asterisk-form, the + // effective request URI's combined path and query component is + // empty. + String path = uri.getRawPath(); if ( path == null || path.isEmpty() ) path = "/"; - String qs = uri.getQuery(); - if ( qs == null || qs.isEmpty() ) - return path; - return path+"?"+qs; + return path; +// // This would include the query string in encoded form. +// String qs = uri.getRawQuery(); +// if ( qs == null || qs.isEmpty() ) +// return path; +// return path+"?"+qs; } /** URI, without query string and fragment. */ @@ -363,7 +377,7 @@ public class HttpLib { if ( uri.getRawQuery() == null && uri.getRawFragment() == null ) return uri; try { - // Same URI except without query strinf an fragment. + // Same URI except without query string and fragment. return new URI(uri.getScheme(), uri.getRawAuthority(), uri.getRawPath(), null, null); } catch (URISyntaxException x) { throw new IllegalArgumentException(x.getMessage(), x); @@ -524,12 +538,12 @@ public class HttpLib { AuthEnv authEnv = AuthEnv.get(); if ( uri.getUserInfo() != null ) { - String[] up = uri.getUserInfo().split(":"); - if ( up.length == 2 ) { + String[] userpasswd = uri.getUserInfo().split(":"); + if ( userpasswd.length == 2 ) { // Only if "user:password@host", not "user@host" key = HttpLib.endpointURI(uri); // The auth key will be with u:p making it specific. - authEnv.registerUsernamePassword(key, up[0], up[1]); + authEnv.registerUsernamePassword(key, userpasswd[0], userpasswd[1]); } } try { diff --git a/jena-integration-tests/src/test/java/org/apache/jena/http/TestAuthDigestRemote.java b/jena-integration-tests/src/test/java/org/apache/jena/http/TestAuthDigestRemote.java index c5b00d0ef1..1bce3265b1 100644 --- a/jena-integration-tests/src/test/java/org/apache/jena/http/TestAuthDigestRemote.java +++ b/jena-integration-tests/src/test/java/org/apache/jena/http/TestAuthDigestRemote.java @@ -31,6 +31,8 @@ import org.apache.jena.fuseki.jetty.JettyLib; import org.apache.jena.fuseki.main.FusekiServer; import org.apache.jena.graph.Graph; import org.apache.jena.http.auth.AuthEnv; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryFactory; import org.apache.jena.sparql.core.DatasetGraph; import org.apache.jena.sparql.core.DatasetGraphFactory; import org.apache.jena.sparql.exec.QueryExec; @@ -45,7 +47,8 @@ import org.junit.Test; /** * Digest authentication. - * Digest auth is not provided by java.net.http. + * Digest auth is not provided by java.net.http, + * so {@code Authenticator} on the {@code HttpClient} does not work. * Jena has to implement it itself (in AuthLib). */ public class TestAuthDigestRemote { @@ -113,27 +116,10 @@ public class TestAuthDigestRemote { }); } -// @Test -// public void auth_disgest_qe_good_auth() { -// // Digest auth does not work with java.net.http. -// // Jena has to implement it itself (in AuthLib). -// Authenticator authenticator = AuthLib.authenticator(user, password); -// HttpClient hc = HttpClient.newBuilder().authenticator(authenticator).build(); -// -// expect401(()->{ -// try ( QueryExec qexec = QueryExecHTTP.newBuilder() -// .httpClient(hc) -// .endpoint(dsEndpoint) -// .queryString("ASK{}") -// .build()) { -// qexec.ask(); -// } -// }); -// } - @Test public void auth_disgest_qe_good_registered() { - // Digest only work via AuthEnv. + // Digest auth is not provided by java.net.http. + // Digest only works via AuthEnv. AuthEnv.get().registerUsernamePassword(dsEndpointURI, user, password); try ( QueryExec qexec = QueryExecHTTP.newBuilder() @@ -145,6 +131,22 @@ public class TestAuthDigestRemote { } } + @Test + public void auth_disgest_qe_good_registered_query() { + // Digest only works via AuthEnv. + AuthEnv.get().registerUsernamePassword(dsEndpointURI, user, password); + // This has a query string with newlines. + // Issue: https://github.com/apache/jena/issues/1318 + Query query = QueryFactory.create("ASK{}"); + try ( QueryExec qexec = QueryExecHTTP.newBuilder() + //.httpClient(hc) + .endpoint(dsEndpoint) + .query(query) + .build()) { + qexec.ask(); + } + } + @Test public void auth_disgest_qe_bad_registered() { expect401(()->{ @@ -158,7 +160,6 @@ public class TestAuthDigestRemote { }); } - // ---- GSP @Test diff --git a/jena-rdfconnection/src/main/java/org/apache/jena/rdflink/RDFLinkHTTP.java b/jena-rdfconnection/src/main/java/org/apache/jena/rdflink/RDFLinkHTTP.java index 1ed556418b..1c80aa4b20 100644 --- a/jena-rdfconnection/src/main/java/org/apache/jena/rdflink/RDFLinkHTTP.java +++ b/jena-rdfconnection/src/main/java/org/apache/jena/rdflink/RDFLinkHTTP.java @@ -97,11 +97,11 @@ public class RDFLinkHTTP implements RDFLink { // Used by the builder. protected RDFLinkHTTP(Transactional txnLifecycle, HttpClient httpClient, String destination, - String queryURL, String updateURL, String gspURL, RDFFormat outputQuads, RDFFormat outputTriples, - String acceptDataset, String acceptGraph, - String acceptSparqlResults, - String acceptSelectResult, String acceptAskResult, - boolean parseCheckQueries, boolean parseCheckUpdates) { + String queryURL, String updateURL, String gspURL, RDFFormat outputQuads, RDFFormat outputTriples, + String acceptDataset, String acceptGraph, + String acceptSparqlResults, + String acceptSelectResult, String acceptAskResult, + boolean parseCheckQueries, boolean parseCheckUpdates) { // Any defaults. HttpClient hc = httpClient!=null ? httpClient : HttpEnv.getDftHttpClient(); if ( txnLifecycle == null )