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 2021/02/10 21:21:34 UTC

[httpcomponents-core] branch master updated (d375a17 -> e9e7b1a)

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

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


    from d375a17  Improved message builder support
     new 5af7cb5  RFC 3986 conformance: BasicHttpRequest to support parsing of valid URI authority components not recognized by java.net.URI
     new eddbc1a  RFC 3986 conformance: BasicHttpRequest to reject requests whose path component begins with multiple slashes
     new e9e7b1a  BasicHttpRequest to support absolute request URI representation

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../testing/framework/TestTestingFramework.java    |  2 +-
 .../http/io/support/ClassicRequestBuilder.java     |  7 ++
 .../hc/core5/http/message/BasicHttpRequest.java    | 88 +++++++++++++++-------
 .../http/nio/support/AsyncRequestBuilder.java      |  7 ++
 .../core5/http/support/AbstractRequestBuilder.java | 10 +++
 .../hc/core5/http/support/BasicRequestBuilder.java |  7 ++
 .../hc/core5/http/message/TestBasicMessages.java   | 26 ++++++-
 7 files changed, 118 insertions(+), 29 deletions(-)


[httpcomponents-core] 01/03: RFC 3986 conformance: BasicHttpRequest to support parsing of valid URI authority components not recognized by java.net.URI

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5af7cb596220b1f3aa9fb7998fbffeb56b80e6ac
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Feb 9 17:53:28 2021 +0100

    RFC 3986 conformance: BasicHttpRequest to support parsing of valid URI authority components not recognized by java.net.URI
---
 .../hc/core5/http/message/BasicHttpRequest.java    | 22 +++++++++++++++-------
 .../hc/core5/http/message/TestBasicMessages.java   | 13 +++++++++++--
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
index 17742de..d83a83e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
@@ -27,9 +27,6 @@
 
 package org.apache.hc.core5.http.message;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.Method;
@@ -39,6 +36,9 @@ import org.apache.hc.core5.net.URIAuthority;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TextUtils;
 
+import java.net.URI;
+import java.net.URISyntaxException;
+
 /**
  * Basic implementation of {@link HttpRequest}.
  *
@@ -223,10 +223,18 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
     @Override
     public void setUri(final URI requestUri) {
         this.scheme = requestUri.getScheme();
-        this.authority = requestUri.getHost() != null ? new URIAuthority(
-                requestUri.getRawUserInfo(),
-                requestUri.getHost(),
-                requestUri.getPort()) : null;
+        if (requestUri.getHost() != null) {
+            this.authority = new URIAuthority(
+                    requestUri.getRawUserInfo(), requestUri.getHost(), requestUri.getPort());
+        } else if (requestUri.getRawAuthority() != null) {
+            try {
+                this.authority = URIAuthority.create(requestUri.getRawAuthority());
+            } catch (final URISyntaxException ignore) {
+                this.authority = null;
+            }
+        } else {
+            this.authority = null;
+        }
         final StringBuilder buf = new StringBuilder();
         final String rawPath = requestUri.getRawPath();
         if (!TextUtils.isBlank(rawPath)) {
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
index 760bf8c..1b3937c 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
@@ -27,8 +27,6 @@
 
 package org.apache.hc.core5.http.message;
 
-import java.net.URI;
-
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
@@ -38,6 +36,8 @@ import org.apache.hc.core5.net.URIAuthority;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.net.URI;
+
 /**
  * Unit tests for {@link org.apache.hc.core5.http.HttpMessage}.
  *
@@ -205,5 +205,14 @@ public class TestBasicMessages {
         Assert.assertEquals(new URI("http://somehost/stuff"), request.getUri());
     }
 
+    @Test
+    public void testRequestHostWithReservedChars() throws Exception {
+        final HttpRequest request = new BasicHttpRequest(Method.GET, URI.create("http://someuser%21@%21example%21.com/stuff"));
+        Assert.assertEquals(Method.GET.name(), request.getMethod());
+        Assert.assertEquals("/stuff", request.getPath());
+        Assert.assertEquals(new URIAuthority("someuser%21", "%21example%21.com", -1), request.getAuthority());
+        Assert.assertEquals(new URI("http://%21example%21.com/stuff"), request.getUri());
+    }
+
 }
 


[httpcomponents-core] 02/03: RFC 3986 conformance: BasicHttpRequest to reject requests whose path component begins with multiple slashes

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit eddbc1acbe029c95ff86ea7b45bdb7cd1bd803da
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Feb 9 17:53:34 2021 +0100

    RFC 3986 conformance: BasicHttpRequest to reject requests whose path component begins with multiple slashes
---
 .../org/apache/hc/core5/testing/framework/TestTestingFramework.java  | 2 +-
 .../main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java | 4 ++++
 .../java/org/apache/hc/core5/http/message/TestBasicMessages.java     | 5 +++++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
index 5877106..2999fbf 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
@@ -1029,7 +1029,7 @@ public class TestTestingFramework {
         final Map<String, Object> request = new HashMap<>();
         test.put(REQUEST, request);
 
-        request.put(PATH, "/stuff");
+        request.put(PATH, "stuff");
 
         final Map<String, Object> queryMap = new HashMap<>();
         request.put(QUERY, queryMap);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
index d83a83e..ac93392 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
@@ -189,6 +189,9 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
 
     @Override
     public void setPath(final String path) {
+        if (path != null) {
+            Args.check(!path.startsWith("//"), "URI path begins with multiple slashes");
+        }
         this.path = path;
         this.requestUri = null;
     }
@@ -238,6 +241,7 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
         final StringBuilder buf = new StringBuilder();
         final String rawPath = requestUri.getRawPath();
         if (!TextUtils.isBlank(rawPath)) {
+            Args.check(!rawPath.startsWith("//"), "URI path begins with multiple slashes");
             buf.append(rawPath);
         } else {
             buf.append("/");
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
index 1b3937c..86d3c96 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
@@ -214,5 +214,10 @@ public class TestBasicMessages {
         Assert.assertEquals(new URI("http://%21example%21.com/stuff"), request.getUri());
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testRequestPathWithMultipleLeadingSlashes() throws Exception {
+        new BasicHttpRequest(Method.GET, URI.create("http://host//stuff"));
+    }
+
 }
 


[httpcomponents-core] 03/03: BasicHttpRequest to support absolute request URI representation

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e9e7b1aadfffae3d4ff95245dbc313ab53c377d0
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Feb 9 17:53:42 2021 +0100

    BasicHttpRequest to support absolute request URI representation
---
 .../http/io/support/ClassicRequestBuilder.java     |  7 +++
 .../hc/core5/http/message/BasicHttpRequest.java    | 62 +++++++++++++++-------
 .../http/nio/support/AsyncRequestBuilder.java      |  7 +++
 .../core5/http/support/AbstractRequestBuilder.java | 10 ++++
 .../hc/core5/http/support/BasicRequestBuilder.java |  7 +++
 .../hc/core5/http/message/TestBasicMessages.java   |  8 +++
 6 files changed, 82 insertions(+), 19 deletions(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/ClassicRequestBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/ClassicRequestBuilder.java
index 5c407f5..cd8835b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/ClassicRequestBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/ClassicRequestBuilder.java
@@ -273,6 +273,12 @@ public class ClassicRequestBuilder extends AbstractRequestBuilder<ClassicHttpReq
         return this;
     }
 
+    @Override
+    public ClassicRequestBuilder setAbsoluteRequestUri(final boolean absoluteRequestUri) {
+        super.setAbsoluteRequestUri(absoluteRequestUri);
+        return this;
+    }
+
     public HttpEntity getEntity() {
         return entity;
     }
@@ -328,6 +334,7 @@ public class ClassicRequestBuilder extends AbstractRequestBuilder<ClassicHttpReq
         result.setVersion(getVersion());
         result.setHeaders(getHeaders());
         result.setEntity(entityCopy);
+        result.setAbsoluteRequestUri(isAbsoluteRequestUri());
         return result;
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
index ac93392..ed94598 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BasicHttpRequest.java
@@ -54,6 +54,7 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
     private URIAuthority authority;
     private ProtocolVersion version;
     private URI requestUri;
+    private boolean absoluteRequestUri;
 
     /**
      * Creates request message with the given method and request path.
@@ -218,9 +219,27 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
         this.requestUri = null;
     }
 
+    /**
+     * Sets a flag that the {@link #getRequestUri()} method should return the request URI
+     * in an absolute form.
+     * <p>
+     * This flag can used when the request is going to be transmitted via an HTTP/1.1 proxy.
+     *
+     * @since 5.1
+     */
+    public void setAbsoluteRequestUri(final boolean absoluteRequestUri) {
+        this.absoluteRequestUri = absoluteRequestUri;
+    }
+
     @Override
     public String getRequestUri() {
-        return getPath();
+        if (absoluteRequestUri) {
+            final StringBuilder buf = new StringBuilder();
+            assembleRequestUri(buf);
+            return buf.toString();
+        } else {
+            return getPath();
+        }
     }
 
     @Override
@@ -253,25 +272,29 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
         this.path = buf.toString();
     }
 
+    private void assembleRequestUri(final StringBuilder buf) {
+        if (this.authority != null) {
+            buf.append(this.scheme != null ? this.scheme : URIScheme.HTTP.id).append("://");
+            buf.append(this.authority.getHostName());
+            if (this.authority.getPort() >= 0) {
+                buf.append(":").append(this.authority.getPort());
+            }
+        }
+        if (this.path == null) {
+            buf.append("/");
+        } else {
+            if (buf.length() > 0 && !this.path.startsWith("/")) {
+                buf.append("/");
+            }
+            buf.append(this.path);
+        }
+    }
+
     @Override
     public URI getUri() throws URISyntaxException {
         if (this.requestUri == null) {
             final StringBuilder buf = new StringBuilder();
-            if (this.authority != null) {
-                buf.append(this.scheme != null ? this.scheme : URIScheme.HTTP.id).append("://");
-                buf.append(this.authority.getHostName());
-                if (this.authority.getPort() >= 0) {
-                    buf.append(":").append(this.authority.getPort());
-                }
-            }
-            if (this.path == null) {
-                buf.append("/");
-            } else {
-                if (buf.length() > 0 && !this.path.startsWith("/")) {
-                    buf.append("/");
-                }
-                buf.append(this.path);
-            }
+            assembleRequestUri(buf);
             this.requestUri = new URI(buf.toString());
         }
         return this.requestUri;
@@ -279,9 +302,10 @@ public class BasicHttpRequest extends HeaderGroup implements HttpRequest {
 
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append(this.method).append(" ").append(this.scheme).append("://").append(this.authority).append(this.path);
-        return sb.toString();
+        final StringBuilder buf = new StringBuilder();
+        buf.append(method).append(" ");
+        assembleRequestUri(buf);
+        return buf.toString();
     }
 
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncRequestBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncRequestBuilder.java
index a80737c..52212b6 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncRequestBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncRequestBuilder.java
@@ -273,6 +273,12 @@ public class AsyncRequestBuilder extends AbstractRequestBuilder<AsyncRequestProd
         return this;
     }
 
+    @Override
+    public AsyncRequestBuilder setAbsoluteRequestUri(final boolean absoluteRequestUri) {
+        super.setAbsoluteRequestUri(absoluteRequestUri);
+        return this;
+    }
+
     public AsyncEntityProducer getEntity() {
         return entityProducer;
     }
@@ -333,6 +339,7 @@ public class AsyncRequestBuilder extends AbstractRequestBuilder<AsyncRequestProd
         final BasicHttpRequest request = new BasicHttpRequest(method, uriCopy);
         request.setVersion(getVersion());
         request.setHeaders(getHeaders());
+        request.setAbsoluteRequestUri(isAbsoluteRequestUri());
         return new BasicRequestProducer(request, entityProducerCopy);
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/support/AbstractRequestBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/support/AbstractRequestBuilder.java
index 9c3c801..e01e439 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/support/AbstractRequestBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/support/AbstractRequestBuilder.java
@@ -51,6 +51,7 @@ public abstract class AbstractRequestBuilder<T> extends AbstractMessageBuilder<T
     private URI uri;
     private Charset charset;
     private List<NameValuePair> parameters;
+    private boolean absoluteRequestUri;
 
     protected AbstractRequestBuilder(final String method) {
         super();
@@ -180,4 +181,13 @@ public abstract class AbstractRequestBuilder<T> extends AbstractMessageBuilder<T
         return this;
     }
 
+    public boolean isAbsoluteRequestUri() {
+        return absoluteRequestUri;
+    }
+
+    public AbstractRequestBuilder<T> setAbsoluteRequestUri(final boolean absoluteRequestUri) {
+        this.absoluteRequestUri = absoluteRequestUri;
+        return this;
+    }
+
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/support/BasicRequestBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/http/support/BasicRequestBuilder.java
index dab7bb7..74d3001 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/support/BasicRequestBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/support/BasicRequestBuilder.java
@@ -258,6 +258,12 @@ public class BasicRequestBuilder extends AbstractRequestBuilder<BasicHttpRequest
     }
 
     @Override
+    public BasicRequestBuilder setAbsoluteRequestUri(final boolean absoluteRequestUri) {
+        super.setAbsoluteRequestUri(absoluteRequestUri);
+        return this;
+    }
+
+    @Override
     public BasicHttpRequest build() {
         URI uri = getUri();
         final List<NameValuePair> parameters = getParameters();
@@ -274,6 +280,7 @@ public class BasicRequestBuilder extends AbstractRequestBuilder<BasicHttpRequest
         final BasicHttpRequest result = new BasicHttpRequest(getMethod(), uri != null ? uri : URI.create("/"));
         result.setVersion(getVersion());
         result.setHeaders(getHeaders());
+        result.setAbsoluteRequestUri(isAbsoluteRequestUri());
         return result;
     }
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
index 86d3c96..020d6a3 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBasicMessages.java
@@ -219,5 +219,13 @@ public class TestBasicMessages {
         new BasicHttpRequest(Method.GET, URI.create("http://host//stuff"));
     }
 
+    @Test
+    public void testRequestAbsoluteRequestUri() throws Exception {
+        final BasicHttpRequest request = new BasicHttpRequest(Method.GET, new HttpHost("http", "somehost", -1), "stuff");
+        Assert.assertEquals("stuff", request.getRequestUri());
+        request.setAbsoluteRequestUri(true);
+        Assert.assertEquals("http://somehost/stuff", request.getRequestUri());
+    }
+
 }