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

gyogal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-livy.git


The following commit(s) were added to refs/heads/master by this push:
     new fc4202ea [LIVY-1046] Avoid decoding user info twice in HTTP client
fc4202ea is described below

commit fc4202ea31722979566f7f730f141420828e4d6b
Author: Arnav Balyan <[email protected]>
AuthorDate: Tue May 19 20:00:13 2026 +0530

    [LIVY-1046] Avoid decoding user info twice in HTTP client
    
    ## What changes were proposed in this pull request?
    
     - The HTTP client decodes the user info in url twice.
     - Java `URI` returns percent decoded output which is passed to .decode() 
again. Any password sent with special characters is wrongly decoded.
     - Remove the second decode call and ensure `:` inside the password is not 
treated as a delimiter
     - Closes LIVY-1046
    
    ## How was this patch tested?
    
     - UT
---
 .../src/main/java/org/apache/livy/client/http/LivyConnection.java | 8 +++-----
 .../scala/org/apache/livy/client/http/LivyConnectionSpec.scala    | 8 +++++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git 
a/client-http/src/main/java/org/apache/livy/client/http/LivyConnection.java 
b/client-http/src/main/java/org/apache/livy/client/http/LivyConnection.java
index 018331cf..2d492ee6 100644
--- a/client-http/src/main/java/org/apache/livy/client/http/LivyConnection.java
+++ b/client-http/src/main/java/org/apache/livy/client/http/LivyConnection.java
@@ -20,8 +20,6 @@ package org.apache.livy.client.http;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
 import java.security.Principal;
 import java.util.concurrent.TimeUnit;
 
@@ -104,15 +102,15 @@ class LivyConnection {
     Credentials credentials;
     // If user info is specified in the url, pass them to the 
CredentialsProvider.
     if (uri.getUserInfo() != null) {
-      String[] userInfo = uri.getUserInfo().split(":");
+      String[] userInfo = uri.getUserInfo().split(":", 2);
       if (userInfo.length < 1) {
         throw new IllegalArgumentException("Malformed user info in the url.");
       }
       try {
-        String username = URLDecoder.decode(userInfo[0], 
StandardCharsets.UTF_8.name());
+        String username = userInfo[0];
         String password = "";
         if (userInfo.length > 1) {
-          password = URLDecoder.decode(userInfo[1], 
StandardCharsets.UTF_8.name());
+          password = userInfo[1];
         }
         credentials = new UsernamePasswordCredentials(username, password);
       } catch (Exception e) {
diff --git 
a/client-http/src/test/scala/org/apache/livy/client/http/LivyConnectionSpec.scala
 
b/client-http/src/test/scala/org/apache/livy/client/http/LivyConnectionSpec.scala
index 05e28a34..508871c5 100644
--- 
a/client-http/src/test/scala/org/apache/livy/client/http/LivyConnectionSpec.scala
+++ 
b/client-http/src/test/scala/org/apache/livy/client/http/LivyConnectionSpec.scala
@@ -18,7 +18,6 @@
 package org.apache.livy.client.http
 
 import java.io.IOException
-import java.net.URLEncoder
 import java.nio.charset.StandardCharsets.UTF_8
 
 import org.apache.http.client.utils.URIBuilder
@@ -73,12 +72,11 @@ class LivyConnectionSpec extends FunSpecLike with 
BeforeAndAfterAll with LivyBas
       server.context.addEventListener(new ScalatraListener)
       server.start()
 
-      val utf8Name = UTF_8.name()
       val uri = new URIBuilder()
         .setScheme(server.protocol)
         .setHost(server.host)
         .setPort(server.port)
-        .setUserInfo(URLEncoder.encode(username, utf8Name), 
URLEncoder.encode(password, utf8Name))
+        .setUserInfo(username, password)
         .build()
       info(uri.toString)
       val conn = new LivyConnection(uri, new HttpConf(null))
@@ -97,6 +95,10 @@ class LivyConnectionSpec extends FunSpecLike with 
BeforeAndAfterAll with LivyBas
       test("pass:word")
     }
 
+    it("should support HTTP auth with password containing plus") {
+      test("p+w")
+    }
+
     it("should support HTTP auth with empty password") {
       test("")
     }

Reply via email to