Skip to content

Commit

Permalink
Skip uri encoding feature (#6910)
Browse files Browse the repository at this point in the history
Skip uri encoding feature

Signed-off-by: David Kral <[email protected]>
  • Loading branch information
Verdent authored May 29, 2023
1 parent cfcef76 commit 717cef1
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ public Http2ClientRequest connection(ClientConnection connection) {
return this;
}

@Override
public Http2ClientRequest skipUriEncoding() {
this.uri.skipUriEncoding(true);
return this;
}

@Override
public Http2ClientRequest priority(int priority) {
if (priority < 1 || priority > 256) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ default <T> T request(Class<T> type) {
*/
B connection(ClientConnection connection);

/**
* Disable uri encoding.
*
* @return updated client request
*/
B skipUriEncoding();

/**
* Handle output stream.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class UriHelper {
private String path;
private String host;
private int port;
private boolean skipUriEncoding = false;

private UriHelper() {
this.baseScheme = null;
Expand Down Expand Up @@ -130,6 +131,15 @@ public void path(String path, UriQueryWriteable query) {
this.path = extractQuery(path, query);
}

/**
* Whether to skip uri encoding.
*
* @param skipUriEncoding skip uri encoding
*/
public void skipUriEncoding(boolean skipUriEncoding) {
this.skipUriEncoding = skipUriEncoding;
}

/**
* Resolve the provided URI against this URI and extract query from it.
*
Expand Down Expand Up @@ -229,22 +239,23 @@ public String path() {
* @return string containing encoded path with query
*/
public String pathWithQueryAndFragment(UriQuery query, UriFragment fragment) {
String queryString = query.rawValue();
String queryString = skipUriEncoding ? query.value() : query.rawValue();

boolean hasQuery = !queryString.isEmpty();

String path;
if (this.path.equals("")) {
path = "/";
} else {
path = UriEncoding.encodeUri(this.path);
path = skipUriEncoding ? this.path : UriEncoding.encodeUri(this.path);
}

if (hasQuery) {
path = path + '?' + queryString;
}
if (fragment.hasValue()) {
path = path + '#' + fragment.rawValue();
String fragmentValue = skipUriEncoding ? fragment.value() : fragment.rawValue();
path = path + '#' + fragmentValue;
}

return path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ClientRequestImpl implements Http1ClientRequest {
private String uriTemplate;
private ClientConnection connection;
private UriFragment fragment;
private boolean skipUriEncoding = false;

ClientRequestImpl(Http1ClientConfig clientConfig,
Http.Method method,
Expand All @@ -69,14 +70,19 @@ class ClientRequestImpl implements Http1ClientRequest {
this.query = query;

this.requestId = "http1-client-" + COUNTER.getAndIncrement();
this.fragment = UriFragment.empty();
}

@Override
public Http1ClientRequest uri(String uri) {
if (uri.indexOf('{') > -1) {
this.uriTemplate = uri;
} else {
uri(URI.create(UriEncoding.encodeUri(uri)));
if (skipUriEncoding) {
uri(URI.create(uri));
} else {
uri(URI.create(UriEncoding.encodeUri(uri)));
}
}

return this;
Expand Down Expand Up @@ -168,7 +174,11 @@ public Http1ClientResponse outputStream(OutputStreamHandler streamHandler) {
public URI resolvedUri() {
if (uriTemplate != null) {
String resolved = resolvePathParams(uriTemplate);
this.uri.resolve(URI.create(UriEncoding.encodeUri(resolved)), query);
if (skipUriEncoding) {
this.uri.resolve(URI.create(resolved), query);
} else {
this.uri.resolve(URI.create(UriEncoding.encodeUri(resolved)), query);
}
}
return URI.create(this.uri.scheme() + "://"
+ uri.authority()
Expand All @@ -182,6 +192,13 @@ public Http1ClientRequest connection(ClientConnection connection) {
return this;
}

@Override
public Http1ClientRequest skipUriEncoding() {
this.skipUriEncoding = true;
this.uri.skipUriEncoding(true);
return this;
}

Http1ClientConfig clientConfig() {
return clientConfig;
}
Expand All @@ -199,7 +216,11 @@ private ClientResponseImpl invokeServices(WebClientService.Chain callChain,
CompletableFuture<WebClientServiceResponse> whenComplete) {
if (uriTemplate != null) {
String resolved = resolvePathParams(uriTemplate);
this.uri.resolve(URI.create(UriEncoding.encodeUri(resolved)), query);
if (skipUriEncoding) {
this.uri.resolve(URI.create(resolved), query);
} else {
this.uri.resolve(URI.create(UriEncoding.encodeUri(resolved)), query);
}
}

ClientRequestHeaders headers = ClientRequestHeaders.create(explicitHeaders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,10 @@ public URI resolvedUri() {
public FakeHttpClientRequest connection(ClientConnection connection) {
return null;
}

@Override
public FakeHttpClientRequest skipUriEncoding() {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.helidon.nima.webclient.http1;

import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
Expand Down Expand Up @@ -175,6 +176,23 @@ void testHeadMethod() {
http1ClientConnection.close();
}

@Test
void testSkipUrlEncoding() {
//Fill with chars which should be encoded
Http1ClientRequest request = getHttp1ClientRequest(Http.Method.PUT, "/ěščžř")
.queryParam("specialChar+", "someValue,").fragment("someFragment,");
URI uri = request.resolvedUri();
assertThat(uri.getRawPath(), is("/%C4%9B%C5%A1%C4%8D%C5%BE%C5%99"));
assertThat(uri.getRawQuery(), is("specialChar%2B=someValue%2C"));
assertThat(uri.getRawFragment(), is("someFragment%2C"));

request = request.skipUriEncoding();
uri = request.resolvedUri();
assertThat(uri.getRawPath(), is("/ěščžř"));
assertThat(uri.getRawQuery(), is("specialChar+=someValue,"));
assertThat(uri.getRawFragment(), is("someFragment,"));
}

private static void validateSuccessfulResponse(Http1Client client, ClientConnection connection) {
String requestEntity = "Sending Something";
Http1ClientRequest request = client.put("http://localhost:" + dummyPort + "/test");
Expand Down

0 comments on commit 717cef1

Please sign in to comment.