diff --git a/pom.xml b/pom.xml
index e1a57834c4618..cf8e996d137f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,7 +49,7 @@
0.38
0.6
1.12.560
- 4.12.0
+ 3.9.0
3.4.0
19.3.0.0
1.40
@@ -2554,7 +2554,6 @@
com.fasterxml.jackson.core:jackson-annotations
com.fasterxml.jackson.core:jackson-core
com.fasterxml.jackson.core:jackson-databind
- org.jetbrains.kotlin:kotlin-stdlib-jdk8
diff --git a/presto-client/src/main/java/com/facebook/presto/client/JsonResponse.java b/presto-client/src/main/java/com/facebook/presto/client/JsonResponse.java
index ac8075e6df206..8823fad06d74c 100644
--- a/presto-client/src/main/java/com/facebook/presto/client/JsonResponse.java
+++ b/presto-client/src/main/java/com/facebook/presto/client/JsonResponse.java
@@ -24,6 +24,7 @@
import javax.annotation.Nullable;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.io.UncheckedIOException;
import static com.google.common.base.MoreObjects.toStringHelper;
@@ -145,6 +146,11 @@ public static JsonResponse execute(JsonCodec codec, OkHttpClient clien
return new JsonResponse<>(response.code(), response.message(), response.headers(), body);
}
catch (IOException e) {
+ // OkHttp throws this after clearing the interrupt status
+ // TODO: remove after updating to Okio 1.15.0+
+ if ((e instanceof InterruptedIOException) && "thread interrupted".equals(e.getMessage())) {
+ Thread.currentThread().interrupt();
+ }
throw new UncheckedIOException(e);
}
}
diff --git a/presto-client/src/main/java/com/facebook/presto/client/OkHttpUtil.java b/presto-client/src/main/java/com/facebook/presto/client/OkHttpUtil.java
index ede0ff646b4c7..78175f158dbb0 100644
--- a/presto-client/src/main/java/com/facebook/presto/client/OkHttpUtil.java
+++ b/presto-client/src/main/java/com/facebook/presto/client/OkHttpUtil.java
@@ -16,7 +16,6 @@
import com.facebook.airlift.security.pem.PemReader;
import com.google.common.base.CharMatcher;
import com.google.common.net.HostAndPort;
-import okhttp.internal.tls.LegacyHostnameVerifier;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Credentials;
@@ -238,7 +237,6 @@ public static void setupSsl(
sslContext.init(keyManagers, new TrustManager[] {trustManager}, null);
clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
- clientBuilder.hostnameVerifier(LegacyHostnameVerifier.INSTANCE);
}
catch (GeneralSecurityException | IOException e) {
throw new ClientException("Error setting up SSL: " + e.getMessage(), e);
diff --git a/presto-client/src/main/java/okhttp/internal/tls/DistinguishedNameParser.java b/presto-client/src/main/java/okhttp/internal/tls/DistinguishedNameParser.java
deleted file mode 100644
index 4c5f22877da9e..0000000000000
--- a/presto-client/src/main/java/okhttp/internal/tls/DistinguishedNameParser.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * 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.
- */
-//CHECKSTYLE:OFF
-package okhttp.internal.tls;
-//CHECKSTYLE:ON
-
-import javax.security.auth.x500.X500Principal;
-
-/**
- * A distinguished name (DN) parser. This parser only supports extracting a string value from a DN.
- * It doesn't support values in the hex-string style.
- *
- * This class is based on the OkHttp library.The original source can be found here:
- *[DistinguishedNameParser.java](https://github.com/square/okhttp/blob/83b9dd427535bce39be43a9e8224cdbc352d7427/okhttp/src/main/java/okhttp3/internal/tls/DistinguishedNameParser.java)
- *
- */
-final class DistinguishedNameParser
-{
- private final String dn;
- private final int length;
- private int pos;
- private int beg;
- private int end;
-
- /**
- * Temporary variable to store positions of the currently parsed item.
- */
- private int cur;
-
- /**
- * Distinguished name characters.
- */
- private char[] chars;
-
- DistinguishedNameParser(X500Principal principal)
- {
- // RFC2253 is used to ensure we get attributes in the reverse
- // order of the underlying ASN.1 encoding, so that the most
- // significant values of repeated attributes occur first.
- this.dn = principal.getName(X500Principal.RFC2253);
- this.length = this.dn.length();
- }
-
- // gets next attribute type: (ALPHA 1*keychar) / oid
- private String nextAT()
- {
- for (; pos < length && chars[pos] == ' '; pos++) {
- // skip preceding space chars, they can present after
- // comma or semicolon (compatibility with RFC 1779)
- }
- if (pos == length) {
- return null; // reached the end of DN
- }
-
- // mark the beginning of attribute type
- beg = pos;
-
- // attribute type chars
- pos++;
- for (; pos < length && chars[pos] != '=' && chars[pos] != ' '; pos++) {
- // we don't follow exact BNF syntax here:
- // accept any char except space and '='
- }
- if (pos >= length) {
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
-
- // mark the end of attribute type
- end = pos;
-
- if (chars[pos] == ' ') {
- for (; pos < length && chars[pos] != '=' && chars[pos] == ' '; pos++) {
- // skip trailing space chars between attribute type and '='
- // (compatibility with RFC 1779)
- }
-
- if (chars[pos] != '=' || pos == length) {
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
- }
-
- pos++; //skip '=' char
-
- for (; pos < length && chars[pos] == ' '; pos++) {
- // skip space chars between '=' and attribute value
- // (compatibility with RFC 1779)
- }
-
- // in case of oid attribute type skip its prefix: "oid." or "OID."
- // (compatibility with RFC 1779)
- if ((end - beg > 4) && (chars[beg + 3] == '.')
- && (chars[beg] == 'O' || chars[beg] == 'o')
- && (chars[beg + 1] == 'I' || chars[beg + 1] == 'i')
- && (chars[beg + 2] == 'D' || chars[beg + 2] == 'd')) {
- beg += 4;
- }
-
- return new String(chars, beg, end - beg);
- }
-
- // gets quoted attribute value: QUOTATION *( quotechar / pair ) QUOTATION
- private String quotedAV()
- {
- pos++;
- beg = pos;
- end = beg;
- while (true) {
- if (pos == length) {
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
-
- if (chars[pos] == '"') {
- // enclosing quotation was found
- pos++;
- break;
- }
- else if (chars[pos] == '\\') {
- chars[end] = getEscaped();
- }
- else {
- // shift char: required for string with escaped chars
- chars[end] = chars[pos];
- }
- pos++;
- end++;
- }
-
- for (; pos < length && chars[pos] == ' '; pos++) {
- // skip trailing space chars before comma or semicolon.
- // (compatibility with RFC 1779)
- }
-
- return new String(chars, beg, end - beg);
- }
-
- // gets hex string attribute value: "#" hexstring
- private String hexAV()
- {
- if (pos + 4 >= length) {
- // encoded byte array must be not less then 4 c
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
-
- beg = pos; // store '#' position
- pos++;
- while (true) {
- // check for end of attribute value
- // looks for space and component separators
- if (pos == length || chars[pos] == '+' || chars[pos] == ','
- || chars[pos] == ';') {
- end = pos;
- break;
- }
-
- if (chars[pos] == ' ') {
- end = pos;
- pos++;
- for (; pos < length && chars[pos] == ' '; pos++) {
- // skip trailing space chars before comma or semicolon.
- // (compatibility with RFC 1779)
- }
- break;
- }
- else if (chars[pos] >= 'A' && chars[pos] <= 'F') {
- chars[pos] += 32; //to low case
- }
-
- pos++;
- }
-
- // verify length of hex string
- // encoded byte array must be not less then 4 and must be even number
- int hexLen = end - beg; // skip first '#' char
- if (hexLen < 5 || (hexLen & 1) == 0) {
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
-
- // get byte encoding from string representation
- byte[] encoded = new byte[hexLen / 2];
- for (int i = 0, p = beg + 1; i < encoded.length; p += 2, i++) {
- encoded[i] = (byte) getByte(p);
- }
- return new String(chars, beg, hexLen);
- }
- // gets string attribute value: *( stringchar / pair)
- private String escapedAV()
- {
- beg = pos;
- end = pos;
- while (true) {
- if (pos >= length) {
- // the end of DN has been found
- return new String(chars, beg, end - beg);
- }
-
- switch (chars[pos]) {
- case '+':
- case ',':
- case ';':
- // separator char has been found
- return new String(chars, beg, end - beg);
- case '\\':
- // escaped char
- chars[end++] = getEscaped();
- pos++;
- break;
- case ' ':
- // need to figure out whether space defines
- // the end of attribute value or not
- cur = end;
-
- pos++;
- chars[end++] = ' ';
-
- for (; pos < length && chars[pos] == ' '; pos++) {
- chars[end++] = ' ';
- }
- if (pos == length || chars[pos] == ',' || chars[pos] == '+'
- || chars[pos] == ';') {
- // separator char or the end of DN has been found
- return new String(chars, beg, cur - beg);
- }
- break;
- default:
- chars[end++] = chars[pos];
- pos++;
- }
- }
- }
-
- // returns escaped char
- private char getEscaped()
- {
- pos++;
- if (pos == length) {
- throw new IllegalStateException("Unexpected end of DN: " + dn);
- }
-
- switch (chars[pos]) {
- case '"':
- case '\\':
- case ',':
- case '=':
- case '+':
- case '<':
- case '>':
- case '#':
- case ';':
- case ' ':
- case '*':
- case '%':
- case '_':
- //FIXME: escaping is allowed only for leading or trailing space char
- return chars[pos];
- default:
- // RFC doesn't explicitly say that escaped hex pair is
- // interpreted as UTF-8 char. It only contains an example of such DN.
- return getUTF8();
- }
- }
-
- // decodes UTF-8 char
- // see http://www.unicode.org for UTF-8 bit distribution table
- private char getUTF8()
- {
- int res = getByte(pos);
- pos++; //FIXME tmp
-
- if (res < 128) { // one byte: 0-7F
- return (char) res;
- }
- else if (res >= 192 && res <= 247) {
- int count;
- if (res <= 223) { // two bytes: C0-DF
- count = 1;
- res = res & 0x1F;
- }
- else if (res <= 239) { // three bytes: E0-EF
- count = 2;
- res = res & 0x0F;
- }
- else { // four bytes: F0-F7
- count = 3;
- res = res & 0x07;
- }
- int b;
- for (int i = 0; i < count; i++) {
- pos++;
- if (pos == length || chars[pos] != '\\') {
- return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
- }
- pos++;
-
- b = getByte(pos);
- pos++; //FIXME tmp
- if ((b & 0xC0) != 0x80) {
- return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
- }
-
- res = (res << 6) + (b & 0x3F);
- }
- return (char) res;
- }
- else {
- return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
- }
- }
-
- // Returns byte representation of a char pair
- // The char pair is composed of DN char in
- // specified 'position' and the next char
- // According to BNF syntax:
- // hexchar = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
- // / "a" / "b" / "c" / "d" / "e" / "f"
- private int getByte(int position)
- {
- if (position + 1 >= length) {
- throw new IllegalStateException("Malformed DN: " + dn);
- }
-
- int b1;
- int b2;
-
- b1 = chars[position];
- if (b1 >= '0' && b1 <= '9') {
- b1 = b1 - '0';
- }
- else if (b1 >= 'a' && b1 <= 'f') {
- b1 = b1 - 87; // 87 = 'a' - 10
- }
- else if (b1 >= 'A' && b1 <= 'F') {
- b1 = b1 - 55; // 55 = 'A' - 10
- }
- else {
- throw new IllegalStateException("Malformed DN: " + dn);
- }
-
- b2 = chars[position + 1];
- if (b2 >= '0' && b2 <= '9') {
- b2 = b2 - '0';
- }
- else if (b2 >= 'a' && b2 <= 'f') {
- b2 = b2 - 87; // 87 = 'a' - 10
- }
- else if (b2 >= 'A' && b2 <= 'F') {
- b2 = b2 - 55; // 55 = 'A' - 10
- }
- else {
- throw new IllegalStateException("Malformed DN: " + dn);
- }
- return (b1 << 4) + b2;
- }
-
- /**
- * Parses the DN and returns the most significant attribute value for an attribute type, or null
- * if none found.
- *
- * @param attributeType attribute type to look for (e.g. "ca")
- */
- public String findMostSpecific(String attributeType)
- {
- // Initialize internal state.
- pos = 0;
- beg = 0;
- end = 0;
- cur = 0;
- chars = dn.toCharArray();
-
- String attType = nextAT();
- if (attType == null) {
- return null;
- }
- while (true) {
- String attValue = "";
-
- if (pos == length) {
- return null;
- }
- switch (chars[pos]) {
- case '"':
- attValue = quotedAV();
- break;
- case '#':
- attValue = hexAV();
- break;
- case '+':
- case ',':
- case ';': // compatibility with RFC 1779: semicolon can separate RDNs
- //empty attribute value
- break;
- default:
- attValue = escapedAV();
- }
-
- // Values are ordered from most specific to least specific
- // due to the RFC2253 formatting. So take the first match
- // we see.
- if (attributeType.equalsIgnoreCase(attType)) {
- return attValue;
- }
-
- if (pos >= length) {
- return null;
- }
- if (chars[pos] == ',' || chars[pos] == ';') {
- //Do nothing
- } else if (chars[pos] != '+') {
- throw new IllegalStateException("Malformed DN: " + dn);
- }
- pos++;
- attType = nextAT();
- if (attType == null) {
- throw new IllegalStateException("Malformed DN: " + dn);
- }
- }
- }
-}
diff --git a/presto-client/src/main/java/okhttp/internal/tls/LegacyHostnameVerifier.java b/presto-client/src/main/java/okhttp/internal/tls/LegacyHostnameVerifier.java
deleted file mode 100644
index 1eac01a7db7f9..0000000000000
--- a/presto-client/src/main/java/okhttp/internal/tls/LegacyHostnameVerifier.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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.
- */
-//CHECKSTYLE:OFF
-package okhttp.internal.tls;
-//CHECKSTYLE:ON
-import okhttp3.internal.tls.OkHostnameVerifier;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.security.auth.x500.X500Principal;
-
-import java.security.cert.Certificate;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-public class LegacyHostnameVerifier
- implements HostnameVerifier
-{
- private static final int ALT_DNS_NAME = 2;
- private static final int ALT_IPA_NAME = 7;
- private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile(
- "([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
-
- public static final HostnameVerifier INSTANCE = new LegacyHostnameVerifier();
-
- private LegacyHostnameVerifier()
- {
- }
-
- @Override
- public boolean verify(String host, SSLSession session)
- {
- if (OkHostnameVerifier.INSTANCE.verify(host, session)) {
- return true;
- }
-
- // the CN cannot be used with IP addresses
- if (verifyAsIpAddress(host)) {
- return false;
- }
-
- // try to verify using the legacy CN rules
- try {
- Certificate[] certificates = session.getPeerCertificates();
- X509Certificate certificate = (X509Certificate) certificates[0];
-
- // only use CN if there are no alt names
- if (!allSubjectAltNames(certificate).isEmpty()) {
- return false;
- }
-
- X500Principal principal = certificate.getSubjectX500Principal();
- // RFC 2818 advises using the most specific name for matching.
- String cn = new DistinguishedNameParser(principal).findMostSpecific("cn");
- if (cn != null) {
- return verifyHostName(host, cn);
- }
-
- return false;
- }
- catch (SSLException e) {
- return false;
- }
- }
-
- static boolean verifyAsIpAddress(String host)
- {
- return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
- }
-
- /**
- * Returns true if {@code certificate} matches {@code ipAddress}.
- */
- private boolean verifyIpAddress(String ipAddress, X509Certificate certificate)
- {
- List altNames = getSubjectAltNames(certificate, ALT_IPA_NAME);
- for (int i = 0, size = altNames.size(); i < size; i++) {
- if (ipAddress.equalsIgnoreCase(altNames.get(i))) {
- return true;
- }
- }
- return false;
- }
-
- private boolean verifyHostName(String hostName, X509Certificate certificate)
- {
- hostName = hostName.toLowerCase(Locale.US);
- boolean hasDns = false;
- List altNames = getSubjectAltNames(certificate, ALT_DNS_NAME);
- for (int i = 0, size = altNames.size(); i < size; i++) {
- hasDns = true;
- if (verifyHostName(hostName, altNames.get(i))) {
- return true;
- }
- }
-
- if (!hasDns) {
- X500Principal principal = certificate.getSubjectX500Principal();
- // RFC 2818 advises using the most specific name for matching.
- String cn = new DistinguishedNameParser(principal).findMostSpecific("cn");
- if (cn != null) {
- return verifyHostName(hostName, cn);
- }
- }
-
- return false;
- }
-
- public static List allSubjectAltNames(X509Certificate certificate)
- {
- List altIpaNames = getSubjectAltNames(certificate, ALT_IPA_NAME);
- List altDnsNames = getSubjectAltNames(certificate, ALT_DNS_NAME);
- List result = new ArrayList<>(altIpaNames.size() + altDnsNames.size());
- result.addAll(altIpaNames);
- result.addAll(altDnsNames);
- return result;
- }
-
- private static List getSubjectAltNames(X509Certificate certificate, int type)
- {
- List result = new ArrayList<>();
- try {
- Collection> subjectAltNames = certificate.getSubjectAlternativeNames();
- if (subjectAltNames == null) {
- return Collections.emptyList();
- }
- for (Object subjectAltName : subjectAltNames) {
- List> entry = (List>) subjectAltName;
- if (entry == null || entry.size() < 2) {
- continue;
- }
- Integer altNameType = (Integer) entry.get(0);
- if (altNameType == null) {
- continue;
- }
- if (altNameType == type) {
- String altName = (String) entry.get(1);
- if (altName != null) {
- result.add(altName);
- }
- }
- }
- return result;
- }
- catch (CertificateParsingException e) {
- return Collections.emptyList();
- }
- }
-
- /**
- * Returns {@code true} iff {@code hostName} matches the domain name {@code pattern}.
- *
- * @param hostName lower-case host name.
- * @param pattern domain name pattern from certificate. May be a wildcard pattern such as
- * {@code *.android.com}.
- */
- private boolean verifyHostName(String hostName, String pattern)
- {
- // Basic sanity checks
- // Check length == 0 instead of .isEmpty() to support Java 5.
- if ((hostName == null) || (hostName.length() == 0) || (hostName.startsWith("."))
- || (hostName.endsWith(".."))) {
- // Invalid domain name
- return false;
- }
- if ((pattern == null) || (pattern.length() == 0) || (pattern.startsWith("."))
- || (pattern.endsWith(".."))) {
- // Invalid pattern/domain name
- return false;
- }
-
- // Normalize hostName and pattern by turning them into absolute domain names if they are not
- // yet absolute. This is needed because server certificates do not normally contain absolute
- // names or patterns, but they should be treated as absolute. At the same time, any hostName
- // presented to this method should also be treated as absolute for the purposes of matching
- // to the server certificate.
- // www.android.com matches www.android.com
- // www.android.com matches www.android.com.
- // www.android.com. matches www.android.com.
- // www.android.com. matches www.android.com
- if (!hostName.endsWith(".")) {
- hostName += '.';
- }
- if (!pattern.endsWith(".")) {
- pattern += '.';
- }
- // hostName and pattern are now absolute domain names.
-
- pattern = pattern.toLowerCase(Locale.US);
- // hostName and pattern are now in lower case -- domain names are case-insensitive.
-
- if (!pattern.contains("*")) {
- // Not a wildcard pattern -- hostName and pattern must match exactly.
- return hostName.equals(pattern);
- }
- // Wildcard pattern
-
- // WILDCARD PATTERN RULES:
- // 1. Asterisk (*) is only permitted in the left-most domain name label and must be the
- // only character in that label (i.e., must match the whole left-most label).
- // For example, *.example.com is permitted, while *a.example.com, a*.example.com,
- // a*b.example.com, a.*.example.com are not permitted.
- // 2. Asterisk (*) cannot match across domain name labels.
- // For example, *.example.com matches test.example.com but does not match
- // sub.test.example.com.
- // 3. Wildcard patterns for single-label domain names are not permitted.
-
- if ((!pattern.startsWith("*.")) || (pattern.indexOf('*', 1) != -1)) {
- // Asterisk (*) is only permitted in the left-most domain name label and must be the only
- // character in that label
- return false;
- }
-
- // Optimization: check whether hostName is too short to match the pattern. hostName must be at
- // least as long as the pattern because asterisk must match the whole left-most label and
- // hostName starts with a non-empty label. Thus, asterisk has to match one or more characters.
- if (hostName.length() < pattern.length()) {
- // hostName too short to match the pattern.
- return false;
- }
-
- if ("*.".equals(pattern)) {
- // Wildcard pattern for single-label domain name -- not permitted.
- return false;
- }
-
- // hostName must end with the region of pattern following the asterisk.
- String suffix = pattern.substring(1);
- if (!hostName.endsWith(suffix)) {
- // hostName does not end with the suffix
- return false;
- }
-
- // Check that asterisk did not match across domain name labels.
- int suffixStartIndexInHostName = hostName.length() - suffix.length();
- if ((suffixStartIndexInHostName > 0)
- && (hostName.lastIndexOf('.', suffixStartIndexInHostName - 1) != -1)) {
- // Asterisk is matching across domain name labels -- not permitted.
- return false;
- }
-
- // hostName matches pattern
- return true;
- }
-}
diff --git a/presto-native-sidecar-plugin/pom.xml b/presto-native-sidecar-plugin/pom.xml
index 958c3ef895aa2..b29409050be23 100644
--- a/presto-native-sidecar-plugin/pom.xml
+++ b/presto-native-sidecar-plugin/pom.xml
@@ -55,12 +55,6 @@
com.squareup.okhttp3
okhttp
-
-
- org.jetbrains
- annotations
-
-