You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/02/05 11:30:04 UTC

[httpcomponents-core] branch HTTPCLIENT-1968 updated: Reduced intermediate garbage when generating URI in URIBuilder#build

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

olegk pushed a commit to branch HTTPCLIENT-1968
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/HTTPCLIENT-1968 by this push:
     new fadae7b  Reduced intermediate garbage when generating URI in URIBuilder#build
fadae7b is described below

commit fadae7b2d97a7b449d278e8ac0c0fd141d4f8488
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Feb 5 12:25:44 2019 +0100

    Reduced intermediate garbage when generating URI in URIBuilder#build
---
 .../java/org/apache/hc/core5/net/URIBuilder.java   |  30 +++--
 .../org/apache/hc/core5/net/URLEncodedUtils.java   | 134 +++++++++------------
 2 files changed, 71 insertions(+), 93 deletions(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
index 8264a80..0ccae0c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
@@ -166,7 +166,8 @@ public class URIBuilder {
                 if (this.encodedUserInfo != null) {
                     sb.append(this.encodedUserInfo).append("@");
                 } else if (this.userInfo != null) {
-                    sb.append(encodeUserInfo(this.userInfo)).append("@");
+                    encodeUserInfo(sb, this.userInfo);
+                    sb.append("@");
                 }
                 if (InetAddressUtils.isIPv6Address(this.host)) {
                     sb.append("[").append(this.host).append("]");
@@ -180,20 +181,23 @@ public class URIBuilder {
             if (this.encodedPath != null) {
                 sb.append(normalizePath(this.encodedPath, sb.length() == 0));
             } else if (this.pathSegments != null) {
-                sb.append(encodePath(this.pathSegments));
+                encodePath(sb, this.pathSegments);
             }
             if (this.encodedQuery != null) {
                 sb.append("?").append(this.encodedQuery);
             } else if (this.queryParams != null && !this.queryParams.isEmpty()) {
-                sb.append("?").append(encodeUrlForm(this.queryParams));
+                sb.append("?");
+                encodeUrlForm(sb, this.queryParams);
             } else if (this.query != null) {
-                sb.append("?").append(encodeUric(this.query));
+                sb.append("?");
+                encodeUric(sb, this.query);
             }
         }
         if (this.encodedFragment != null) {
             sb.append("#").append(this.encodedFragment);
         } else if (this.fragment != null) {
-            sb.append("#").append(encodeUric(this.fragment));
+            sb.append("#");
+            encodeUric(sb, this.fragment);
         }
         return sb.toString();
     }
@@ -225,20 +229,20 @@ public class URIBuilder {
         this.fragment = uri.getFragment();
     }
 
-    private String encodeUserInfo(final String userInfo) {
-        return URLEncodedUtils.encUserInfo(userInfo, this.charset != null ? this.charset : StandardCharsets.UTF_8);
+    private void encodeUserInfo(final StringBuilder buf, final String userInfo) {
+        URLEncodedUtils.encUserInfo(buf, userInfo, this.charset != null ? this.charset : StandardCharsets.UTF_8);
     }
 
-    private String encodePath(final List<String> pathSegments) {
-        return URLEncodedUtils.formatSegments(pathSegments, this.charset != null ? this.charset : StandardCharsets.UTF_8);
+    private void encodePath(final StringBuilder buf, final List<String> pathSegments) {
+        URLEncodedUtils.formatSegments(buf, pathSegments, this.charset != null ? this.charset : StandardCharsets.UTF_8);
     }
 
-    private String encodeUrlForm(final List<NameValuePair> params) {
-        return URLEncodedUtils.format(params, this.charset != null ? this.charset : StandardCharsets.UTF_8);
+    private void encodeUrlForm(final StringBuilder buf, final List<NameValuePair> params) {
+        URLEncodedUtils.formatParameters(buf, params, this.charset != null ? this.charset : StandardCharsets.UTF_8);
     }
 
-    private String encodeUric(final String fragment) {
-        return URLEncodedUtils.encUric(fragment, this.charset != null ? this.charset : StandardCharsets.UTF_8);
+    private void encodeUric(final StringBuilder buf, final String fragment) {
+        URLEncodedUtils.encUric(buf, fragment, this.charset != null ? this.charset : StandardCharsets.UTF_8);
     }
 
     /**
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
index 76fd01d..77ad3a7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
@@ -208,6 +208,12 @@ public class URLEncodedUtils {
         return parsePathSegments(s, StandardCharsets.UTF_8);
     }
 
+    static void formatSegments(final StringBuilder buf, final Iterable<String> segments, final Charset charset) {
+        for (final String segment : segments) {
+            buf.append(PATH_SEPARATOR);
+            urlEncode(buf, segment, charset, PATHSAFE, false);
+        }
+    }
     /**
      * Returns a string consisting of joint encoded path segments.
      *
@@ -219,11 +225,9 @@ public class URLEncodedUtils {
      */
     public static String formatSegments(final Iterable<String> segments, final Charset charset) {
         Args.notNull(segments, "Segments");
-        final StringBuilder result = new StringBuilder();
-        for (final String segment : segments) {
-            result.append(PATH_SEPARATOR).append(urlEncode(segment, charset, PATHSAFE, false));
-        }
-        return result.toString();
+        final StringBuilder buf = new StringBuilder();
+        formatSegments(buf, segments, charset);
+        return buf.toString();
     }
 
     /**
@@ -238,20 +242,51 @@ public class URLEncodedUtils {
         return formatSegments(Arrays.asList(segments), StandardCharsets.UTF_8);
     }
 
+    static void formatNameValuePairs(
+            final StringBuilder buf,
+            final Iterable<? extends NameValuePair> parameters,
+            final char parameterSeparator,
+            final Charset charset) {
+        int i = 0;
+        for (final NameValuePair parameter : parameters) {
+            if (i > 0) {
+                buf.append(parameterSeparator);
+            }
+            encodeFormFields(buf, parameter.getName(), charset);
+            if (parameter.getValue() != null) {
+                buf.append(NAME_VALUE_SEPARATOR);
+                encodeFormFields(buf, parameter.getValue(), charset);
+            }
+            i++;
+        }
+    }
+
+    static void formatParameters(
+            final StringBuilder buf,
+            final Iterable<? extends NameValuePair> parameters,
+            final Charset charset) {
+        formatNameValuePairs(buf, parameters, QP_SEP_A, charset);
+    }
+
     /**
      * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded}
      * list of parameters in an HTTP PUT or HTTP POST.
      *
      * @param parameters  The parameters to include.
+     * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}.
      * @param charset The encoding to use.
      * @return An {@code application/x-www-form-urlencoded} string
      *
-     * @since 4.2
+     * @since 4.3
      */
     public static String format(
             final Iterable<? extends NameValuePair> parameters,
+            final char parameterSeparator,
             final Charset charset) {
-        return format(parameters, QP_SEP_A, charset);
+        Args.notNull(parameters, "Parameters");
+        final StringBuilder buf = new StringBuilder();
+        formatNameValuePairs(buf, parameters, parameterSeparator, charset);
+        return buf.toString();
     }
 
     /**
@@ -259,31 +294,15 @@ public class URLEncodedUtils {
      * list of parameters in an HTTP PUT or HTTP POST.
      *
      * @param parameters  The parameters to include.
-     * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}.
      * @param charset The encoding to use.
      * @return An {@code application/x-www-form-urlencoded} string
      *
-     * @since 4.3
+     * @since 4.2
      */
     public static String format(
             final Iterable<? extends NameValuePair> parameters,
-            final char parameterSeparator,
             final Charset charset) {
-        Args.notNull(parameters, "Parameters");
-        final StringBuilder result = new StringBuilder();
-        for (final NameValuePair parameter : parameters) {
-            final String encodedName = encodeFormFields(parameter.getName(), charset);
-            final String encodedValue = encodeFormFields(parameter.getValue(), charset);
-            if (result.length() > 0) {
-                result.append(parameterSeparator);
-            }
-            result.append(encodedName);
-            if (encodedValue != null) {
-                result.append(NAME_VALUE_SEPARATOR);
-                result.append(encodedValue);
-            }
-        }
-        return result.toString();
+        return format(parameters, QP_SEP_A, charset);
     }
 
     /**
@@ -400,15 +419,15 @@ public class URLEncodedUtils {
         return new ArrayList<>(0);
     }
 
-    private static String urlEncode(
+    private static void urlEncode(
+            final StringBuilder buf,
             final String content,
             final Charset charset,
             final BitSet safechars,
             final boolean blankAsPlus) {
         if (content == null) {
-            return null;
+            return;
         }
-        final StringBuilder buf = new StringBuilder();
         final ByteBuffer bb = charset.encode(content);
         while (bb.hasRemaining()) {
             final int b = bb.get() & 0xff;
@@ -424,17 +443,8 @@ public class URLEncodedUtils {
                 buf.append(hex2);
             }
         }
-        return buf.toString();
     }
 
-    /**
-     * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true.
-     *
-     * @param content the portion to decode
-     * @param charset the charset to use
-     * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is.
-     * @return encoded string
-     */
     private static String urlDecode(
             final String content,
             final Charset charset,
@@ -468,13 +478,6 @@ public class URLEncodedUtils {
         return charset.decode(bb).toString();
     }
 
-    /**
-     * Decode/unescape www-url-form-encoded content.
-     *
-     * @param content the content to decode, will decode '+' as space
-     * @param charset the charset to use
-     * @return encoded string
-     */
     private static String decodeFormFields (final String content, final Charset charset) {
         if (content == null) {
             return null;
@@ -482,48 +485,19 @@ public class URLEncodedUtils {
         return urlDecode(content, charset != null ? charset : StandardCharsets.UTF_8, true);
     }
 
-    /**
-     * Encode/escape www-url-form-encoded content.
-     * <p>
-     * Uses the {@link #URLENCODER} set of characters, rather than
-     * the {@link #UNRESERVED} set; this is for compatibilty with previous
-     * releases, URLEncoder.encode() and most browsers.
-     *
-     * @param content the content to encode, will convert space to '+'
-     * @param charset the charset to use
-     * @return encoded string
-     */
-    private static String encodeFormFields (final String content, final Charset charset) {
+    private static void encodeFormFields(final StringBuilder buf, final String content, final Charset charset) {
         if (content == null) {
-            return null;
+            return;
         }
-        return urlEncode(content, charset != null ? charset : StandardCharsets.UTF_8, URLENCODER, true);
+        urlEncode(buf, content, charset != null ? charset : StandardCharsets.UTF_8, URLENCODER, true);
     }
 
-    /**
-     * Encode a String using the {@link #USERINFO} set of characters.
-     * <p>
-     * Used by URIBuilder to encode the userinfo segment.
-     *
-     * @param content the string to encode, does not convert space to '+'
-     * @param charset the charset to use
-     * @return the encoded string
-     */
-    static String encUserInfo(final String content, final Charset charset) {
-        return urlEncode(content, charset, USERINFO, false);
+    static void encUserInfo(final StringBuilder buf, final String content, final Charset charset) {
+        urlEncode(buf, content, charset, USERINFO, false);
     }
 
-    /**
-     * Encode a String using the {@link #URIC} set of characters.
-     * <p>
-     * Used by URIBuilder to encode the query and fragment segments.
-     *
-     * @param content the string to encode, does not convert space to '+'
-     * @param charset the charset to use
-     * @return the encoded string
-     */
-    static String encUric(final String content, final Charset charset) {
-        return urlEncode(content, charset, URIC, false);
+    static void encUric(final StringBuilder buf, final String content, final Charset charset) {
+        urlEncode(buf, content, charset, URIC, false);
     }
 
 }