diff --git a/presto-docs/src/main/sphinx/installation/jdbc.rst b/presto-docs/src/main/sphinx/installation/jdbc.rst index 90fc3c059500c..47330d51d113c 100644 --- a/presto-docs/src/main/sphinx/installation/jdbc.rst +++ b/presto-docs/src/main/sphinx/installation/jdbc.rst @@ -76,6 +76,8 @@ Name Description ``password`` Password to use for LDAP authentication. ``socksProxy`` SOCKS proxy host and port. Example: ``localhost:1080`` ``httpProxy`` HTTP proxy host and port. Example: ``localhost:8888`` +``protocols`` Comma delineated list of HTTP protocols to use. Example: ``protocols=http11``. + Acceptable values: ``http11,http10,http2`` ``applicationNamePrefix`` Prefix to append to any specified ``ApplicationName`` client info property, which is used to set the source name for the Presto query. If neither this property nor ``ApplicationName`` are set, the source diff --git a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/AbstractConnectionProperty.java b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/AbstractConnectionProperty.java index c008a3f34a762..29ad24d6fef8a 100644 --- a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/AbstractConnectionProperty.java +++ b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/AbstractConnectionProperty.java @@ -15,6 +15,7 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; +import okhttp3.Protocol; import java.io.File; import java.sql.DriverPropertyInfo; @@ -216,6 +217,41 @@ private QueryInterceptor loadClass(String interceptor) } } + protected static final class HttpProtocolConverter + implements Converter> + { + public static final HttpProtocolConverter HTTP_PROTOCOL_CONVERTER = new HttpProtocolConverter(); + private HttpProtocolConverter() {} + + @Override + public List convert(String value) + { + return Splitter.on(',').splitToList(value).stream() + .map(this::loadProtocol) + .distinct() + .collect(toImmutableList()); + } + + private Protocol loadProtocol(String protocolName) + { + try { + switch (protocolName.toLowerCase(ENGLISH)) { + case "http11": + return Protocol.HTTP_1_1; + case "http10": + return Protocol.HTTP_1_0; + case "http2": + return Protocol.HTTP_2; + default: + return Protocol.get(protocolName); + } + } + catch (Exception e) { + throw new IllegalArgumentException(format("Could not load OkhttpProtocol from %s", protocolName), e); + } + } + } + protected interface CheckedPredicate { boolean test(T t) diff --git a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/ConnectionProperties.java b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/ConnectionProperties.java index 8c8e678610623..5195d77ec559d 100644 --- a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/ConnectionProperties.java +++ b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/ConnectionProperties.java @@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.net.HostAndPort; +import okhttp3.Protocol; import java.io.File; import java.util.List; @@ -26,6 +27,7 @@ import java.util.function.Predicate; import static com.facebook.presto.jdbc.AbstractConnectionProperty.ClassListConverter.CLASS_LIST_CONVERTER; +import static com.facebook.presto.jdbc.AbstractConnectionProperty.HttpProtocolConverter.HTTP_PROTOCOL_CONVERTER; import static com.facebook.presto.jdbc.AbstractConnectionProperty.StringMapConverter.STRING_MAP_CONVERTER; import static com.facebook.presto.jdbc.AbstractConnectionProperty.checkedPredicate; import static java.util.Collections.unmodifiableMap; @@ -54,6 +56,7 @@ final class ConnectionProperties public static final ConnectionProperty ACCESS_TOKEN = new AccessToken(); public static final ConnectionProperty> EXTRA_CREDENTIALS = new ExtraCredentials(); public static final ConnectionProperty> SESSION_PROPERTIES = new SessionProperties(); + public static final ConnectionProperty> HTTP_PROTOCOLS = new HttpProtocols(); public static final ConnectionProperty> QUERY_INTERCEPTORS = new QueryInterceptors(); private static final Set> ALL_PROPERTIES = ImmutableSet.>builder() @@ -77,6 +80,7 @@ final class ConnectionProperties .add(ACCESS_TOKEN) .add(EXTRA_CREDENTIALS) .add(SESSION_PROPERTIES) + .add(HTTP_PROTOCOLS) .add(QUERY_INTERCEPTORS) .build(); @@ -313,6 +317,15 @@ public SessionProperties() } } + private static class HttpProtocols + extends AbstractConnectionProperty> + { + public HttpProtocols() + { + super("protocols", NOT_REQUIRED, ALLOWED, HTTP_PROTOCOL_CONVERTER); + } + } + private static class QueryInterceptors extends AbstractConnectionProperty> { diff --git a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoDriverUri.java b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoDriverUri.java index 4ae49a240c413..845833590711d 100644 --- a/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoDriverUri.java +++ b/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoDriverUri.java @@ -21,6 +21,7 @@ import com.google.common.collect.Maps; import com.google.common.net.HostAndPort; import okhttp3.OkHttpClient; +import okhttp3.Protocol; import java.io.File; import java.net.URI; @@ -47,6 +48,7 @@ import static com.facebook.presto.jdbc.ConnectionProperties.APPLICATION_NAME_PREFIX; import static com.facebook.presto.jdbc.ConnectionProperties.DISABLE_COMPRESSION; import static com.facebook.presto.jdbc.ConnectionProperties.EXTRA_CREDENTIALS; +import static com.facebook.presto.jdbc.ConnectionProperties.HTTP_PROTOCOLS; import static com.facebook.presto.jdbc.ConnectionProperties.HTTP_PROXY; import static com.facebook.presto.jdbc.ConnectionProperties.KERBEROS_CONFIG_PATH; import static com.facebook.presto.jdbc.ConnectionProperties.KERBEROS_CREDENTIAL_CACHE_PATH; @@ -170,6 +172,12 @@ public boolean isCompressionDisabled() return DISABLE_COMPRESSION.getValue(properties).orElse(false); } + public Optional> getProtocols() + throws SQLException + { + return HTTP_PROTOCOLS.getValue(properties); + } + public void setupClient(OkHttpClient.Builder builder) throws SQLException { @@ -178,6 +186,9 @@ public void setupClient(OkHttpClient.Builder builder) setupSocksProxy(builder, SOCKS_PROXY.getValue(properties)); setupHttpProxy(builder, HTTP_PROXY.getValue(properties)); + // add user specified protocols to okhttp3 client if specified + getProtocols().ifPresent(builder::protocols); + // TODO: fix Tempto to allow empty passwords String password = PASSWORD.getValue(properties).orElse(""); if (!password.isEmpty() && !password.equals("***empty***")) { diff --git a/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestJdbcConnection.java b/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestJdbcConnection.java index 99ea4dc8f1f43..502b4843f2c86 100644 --- a/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestJdbcConnection.java +++ b/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestJdbcConnection.java @@ -216,6 +216,22 @@ public void testApplicationName() } } + @Test + public void testHttpProtocols() + throws SQLException + { + String extra = "protocols=http11"; + try (Connection connection = createConnection(extra)) { + assertThat(connection.getCatalog()).isEqualTo("hive"); + } + + // deduplication + extra = "protocols=http11,http11"; + try (Connection connection = createConnection(extra)) { + assertThat(connection.getCatalog()).isEqualTo("hive"); + } + } + @Test public void testExtraCredentials() throws SQLException diff --git a/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestPrestoDriverUri.java b/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestPrestoDriverUri.java index 0fc170f279519..5e90126b93657 100644 --- a/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestPrestoDriverUri.java +++ b/presto-jdbc/src/test/java/com/facebook/presto/jdbc/TestPrestoDriverUri.java @@ -24,6 +24,7 @@ import static com.facebook.presto.jdbc.ConnectionProperties.DISABLE_COMPRESSION; import static com.facebook.presto.jdbc.ConnectionProperties.EXTRA_CREDENTIALS; +import static com.facebook.presto.jdbc.ConnectionProperties.HTTP_PROTOCOLS; import static com.facebook.presto.jdbc.ConnectionProperties.HTTP_PROXY; import static com.facebook.presto.jdbc.ConnectionProperties.QUERY_INTERCEPTORS; import static com.facebook.presto.jdbc.ConnectionProperties.SESSION_PROPERTIES; @@ -265,6 +266,16 @@ public void testUriWithSessionProperties() assertEquals(properties.getProperty(SESSION_PROPERTIES.getKey()), sessionProperties); } + @Test + public void testUriWithHttpProtocols() + throws SQLException + { + String protocols = "h2,http/1.1"; + PrestoDriverUri parameters = createDriverUri("presto://localhost:8080?protocols=" + protocols); + Properties properties = parameters.getProperties(); + assertEquals(properties.getProperty(HTTP_PROTOCOLS.getKey()), protocols); + } + @Test public void testUriWithQueryInterceptors() throws SQLException