Skip to content

Commit

Permalink
Client URL scheme validation pipeline fixes 2
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkec committed Aug 27, 2023
1 parent ca0a04f commit be3e911
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public T uri(String uri) {
@Override
public ClientUri resolvedUri() {
// we do not want to update our own URI, as this method may be called multiple times
return resolveUri(ClientUri.create(this.clientUri));
return resolveUri(this.clientUri.copy());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,34 @@
* URI abstraction for WebClient.
*/
public class ClientUri implements UriInfo {
private static final Set<String> SUPPORTED_SCHEMES = Set.of("http", "https");
private static final Set<String> DEFAULT_SUPPORTED_SCHEMES = Set.of("http", "https");
private final UriInfo base;
private final UriQueryWriteable query;

private UriInfo.Builder uriBuilder;
private boolean skipUriEncoding = false;

private ClientUri() {
protected ClientUri() {
this.base = null;
this.query = UriQueryWriteable.create();
this.uriBuilder = UriInfo.builder();
}

private ClientUri(ClientUri baseUri) {
protected ClientUri(ClientUri baseUri) {
validateScheme(baseUri.scheme());
this.base = baseUri;
this.uriBuilder = UriInfo.builder(base);
this.skipUriEncoding = baseUri.skipUriEncoding;
this.query = UriQueryWriteable.create().from(baseUri.query());
validateScheme(baseUri.scheme());
}

private ClientUri(UriInfo baseUri) {
validateScheme(baseUri.scheme());
protected ClientUri(UriInfo baseUri) {
this.base = baseUri;
this.uriBuilder = UriInfo.builder(baseUri);
this.skipUriEncoding = false;
this.query = UriQueryWriteable.create().from(baseUri.query());
validateScheme(baseUri.scheme());
}

/**
Expand Down Expand Up @@ -97,6 +98,15 @@ public static ClientUri create(URI baseUri) {
return create().resolve(baseUri);
}

/**
* Create copy of this client uri.
*
* @return copy of this client uri
*/
public ClientUri copy() {
return ClientUri.create(this);
}

@Override
public String toString() {
UriInfo info = uriBuilder.query(this.query).build();
Expand Down Expand Up @@ -327,6 +337,10 @@ public String pathWithQueryAndFragment() {
return path;
}

protected Set<String> supportedSchemes() {
return DEFAULT_SUPPORTED_SCHEMES;
}

private String extractQuery(String path) {
if (path != null) {
int i = path.indexOf('?');
Expand Down Expand Up @@ -366,12 +380,12 @@ private String resolvePath(String path, String resolvePath) {
+ resolvePath;
}

private void validateScheme(String scheme){
if (!SUPPORTED_SCHEMES.contains(scheme)) {
private void validateScheme(String scheme) {
if (!supportedSchemes().contains(scheme)) {
throw new IllegalArgumentException(
String.format("Not supported scheme %s, client supported schemes are: %s",
scheme,
String.join(", ", SUPPORTED_SCHEMES)
String.join(", ", supportedSchemes())
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Http1ClientImpl implements Http1Client, HttpClientSpi {
@Override
public Http1ClientRequest method(Http.Method method) {
ClientUri clientUri = clientConfig.baseUri()
.map(ClientUri::create) // create from base config
.map(ClientUri::copy) // create from base config
.orElseGet(ClientUri::create); // create as empty

clientConfig.baseFragment().ifPresent(clientUri::fragment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* io.helidon.webclient.spi.ProtocolConfig)
*/
@Prototype.Blueprint
@Prototype.CustomMethods(WsClientConfigSupport.WsCustomMethods.class)
@Configured
interface WsClientConfigBlueprint extends HttpClientConfig, Prototype.Factory<WsClient> {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.webclient.websocket;

import java.net.URI;

import io.helidon.builder.api.Prototype;

class WsClientConfigSupport {

static class WsCustomMethods {
/**
* Base URI of the client.
*
* @param builder builder to update
* @param baseUri base URI to use, query is extracted to base query (if any)
*/
@Prototype.BuilderMethod
static void baseUri(WsClientConfig.BuilderBase<?, ?> builder, URI baseUri) {
builder.baseUri(WsClientUri.create().resolve(baseUri));
}

/**
* Base URI of the client.
*
* @param builder builder to update
* @param baseUri base URI to use, query is extracted to base query (if any)
*/
@Prototype.BuilderMethod
static void baseUri(WsClientConfig.BuilderBase<?, ?> builder, String baseUri) {
baseUri(builder, URI.create(baseUri));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import io.helidon.http.ClientResponseHeaders;
import io.helidon.http.Http;
import io.helidon.webclient.api.ClientConnection;
import io.helidon.webclient.api.ClientUri;
import io.helidon.webclient.api.HttpClientResponse;
import io.helidon.webclient.api.WebClient;
import io.helidon.webclient.http1.Http1Client;
Expand Down Expand Up @@ -95,9 +94,9 @@ public void connect(URI uri, WsListener listener) {
UriInfo resolvedUri = upgradeRequest.resolvedUri();
String scheme = resolvedUri.scheme();
if ("ws".equals(scheme)) {
upgradeRequest.uri(ClientUri.create(resolvedUri).scheme("http"));
upgradeRequest.uri(WsClientUri.create(resolvedUri).scheme("http"));
} else if ("wss".equals(scheme)) {
upgradeRequest.uri(ClientUri.create(resolvedUri).scheme("https"));
upgradeRequest.uri(WsClientUri.create(resolvedUri).scheme("https"));
}

upgradeRequest.headers(headers -> headers.setIfAbsent(Http.Headers.create(Http.HeaderNames.HOST, resolvedUri
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.webclient.websocket;

import java.net.URI;
import java.util.Set;

import io.helidon.common.uri.UriInfo;
import io.helidon.webclient.api.ClientUri;

/**
* URI abstraction for WsClient.
*/
public class WsClientUri extends ClientUri {

private static final Set<String> SUPPORTED_SCHEMES = Set.of("http", "https", "ws", "wss");

private WsClientUri() {
super();
}

private WsClientUri(ClientUri baseUri) {
super(baseUri);
}

private WsClientUri(UriInfo baseUri) {
super(baseUri);
}

/**
* Create an empty URI helper.
*
* @return uri helper
*/
public static WsClientUri create() {
return new WsClientUri();
}

/**
* Create a new client uri.
*
* @param baseUri base URI
* @return a new client uri
*/
public static WsClientUri create(ClientUri baseUri) {
return new WsClientUri(baseUri);
}

/**
* Create a new client uri.
*
* @param baseUri base URI
* @return a new client uri
*/
public static WsClientUri create(UriInfo baseUri) {
return new WsClientUri(baseUri);
}

/**
* Create a new client URI from an existing URI.
*
* @param baseUri base URI
* @return a new client uri
*/
public static ClientUri create(URI baseUri) {
return create().resolve(baseUri);
}

@Override
protected Set<String> supportedSchemes() {
return SUPPORTED_SCHEMES;
}

@Override
public WsClientUri clone() {
return WsClientUri.create(this);
}
}

0 comments on commit be3e911

Please sign in to comment.