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 )

Reply via email to