diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..5c35341eb
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+# Unix-style linebreaks with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# space indentation for Java
+[*.java]
+indent_size = 4
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..3c0f4c376
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+- package-ecosystem: github-actions
+ directory: "/"
+ schedule:
+ interval: weekly
+- package-ecosystem: maven
+ directory: "/"
+ schedule:
+ interval: weekly
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 05b389dac..01cfa5509 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,13 +12,13 @@ jobs:
if: github.repository == 'pgjdbc/r2dbc-postgresql'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - name: Set up JDK 1.8
- uses: actions/setup-java@v3
+ - uses: actions/checkout@v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
with:
- java-version: 8
- distribution: temurin
- cache: maven
+ java-version: '17'
+ distribution: 'temurin'
+ cache: 'maven'
- name: Build with Maven
env:
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
diff --git a/.github/workflows/pullrequests.yml b/.github/workflows/pullrequests.yml
index d48e10976..aba1ed0af 100644
--- a/.github/workflows/pullrequests.yml
+++ b/.github/workflows/pullrequests.yml
@@ -9,12 +9,12 @@ jobs:
pr-build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - name: Set up JDK 1.8
- uses: actions/setup-java@v3
+ - uses: actions/checkout@v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
with:
- java-version: 8
- distribution: temurin
- cache: maven
+ java-version: '17'
+ distribution: 'temurin'
+ cache: 'maven'
- name: Build with Maven
run: ./mvnw -B verify -D skipITs
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2545e1d50..fc49cd238 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,14 +12,14 @@ jobs:
if: github.repository == 'pgjdbc/r2dbc-postgresql'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - name: Set up JDK 1.8
- uses: actions/setup-java@v3
+ - uses: actions/checkout@v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
with:
- java-version: 8
- distribution: temurin
+ java-version: '17'
+ distribution: 'temurin'
- name: Initialize Maven Version
- run: ./mvnw -q org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version
+ run: ./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout
- name: GPG Check
run: gpg -k
- name: Release with Maven
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
deleted file mode 100644
index c32394f14..000000000
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2007-present the original author or authors.
- *
- * 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.
- */
-import java.net.*;
-import java.io.*;
-import java.nio.channels.*;
-import java.util.Properties;
-
-public class MavenWrapperDownloader {
-
- private static final String WRAPPER_VERSION = "0.5.5";
- /**
- * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
- */
- private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
- + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
-
- /**
- * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
- * use instead of the default one.
- */
- private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
- ".mvn/wrapper/maven-wrapper.properties";
-
- /**
- * Path where the maven-wrapper.jar will be saved to.
- */
- private static final String MAVEN_WRAPPER_JAR_PATH =
- ".mvn/wrapper/maven-wrapper.jar";
-
- /**
- * Name of the property which should be used to override the default download url for the wrapper.
- */
- private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
-
- public static void main(String args[]) {
- System.out.println("- Downloader started");
- File baseDirectory = new File(args[0]);
- System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
-
- // If the maven-wrapper.properties exists, read it and check if it contains a custom
- // wrapperUrl parameter.
- File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
- String url = DEFAULT_DOWNLOAD_URL;
- if(mavenWrapperPropertyFile.exists()) {
- FileInputStream mavenWrapperPropertyFileInputStream = null;
- try {
- mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
- Properties mavenWrapperProperties = new Properties();
- mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
- url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
- } catch (IOException e) {
- System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
- } finally {
- try {
- if(mavenWrapperPropertyFileInputStream != null) {
- mavenWrapperPropertyFileInputStream.close();
- }
- } catch (IOException e) {
- // Ignore ...
- }
- }
- }
- System.out.println("- Downloading from: " + url);
-
- File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
- if(!outputFile.getParentFile().exists()) {
- if(!outputFile.getParentFile().mkdirs()) {
- System.out.println(
- "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
- }
- }
- System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
- try {
- downloadFileFromURL(url, outputFile);
- System.out.println("Done");
- System.exit(0);
- } catch (Throwable e) {
- System.out.println("- Error downloading");
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private static void downloadFileFromURL(String urlString, File destination) throws Exception {
- if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
- String username = System.getenv("MVNW_USERNAME");
- char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
- Authenticator.setDefault(new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- }
- URL website = new URL(urlString);
- ReadableByteChannel rbc;
- rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(destination);
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
- fos.close();
- rbc.close();
- }
-
-}
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
index 0d5e64988..7967f30dd 100644
Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 471b1a1c9..76e6ae113 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,2 +1,20 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+wrapperVersion=3.3.2
+distributionType=script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
diff --git a/ci/build-and-deploy-to-maven-central.sh b/ci/build-and-deploy-to-maven-central.sh
index 095c3d9ea..0886285e6 100755
--- a/ci/build-and-deploy-to-maven-central.sh
+++ b/ci/build-and-deploy-to-maven-central.sh
@@ -2,7 +2,7 @@
set -euo pipefail
-VERSION=$(./mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -o | grep -v INFO)
+VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
if [[ $VERSION =~ [^.*-SNAPSHOT$] ]] ; then
@@ -36,4 +36,3 @@ else
echo "Not a release: $VERSION"
exit 1
fi
-
diff --git a/mvnw b/mvnw
index d2f0ea380..5e9618cac 100755
--- a/mvnw
+++ b/mvnw
@@ -19,7 +19,7 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
+# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Required ENV vars:
# ------------------
@@ -27,284 +27,306 @@
#
# Optional ENV vars
# -----------------
-# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
-if [ -z "$MAVEN_SKIP_RC" ] ; then
+if [ -z "$MAVEN_SKIP_RC" ]; then
- if [ -f /etc/mavenrc ] ; then
+ if [ -f /usr/local/etc/mavenrc ]; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ]; then
. /etc/mavenrc
fi
- if [ -f "$HOME/.mavenrc" ] ; then
+ if [ -f "$HOME/.mavenrc" ]; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
+cygwin=false
+darwin=false
mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- export JAVA_HOME="`/usr/libexec/java_home`"
- else
- export JAVA_HOME="/Library/Java/Home"
- fi
+case "$(uname)" in
+CYGWIN*) cygwin=true ;;
+MINGW*) mingw=true ;;
+Darwin*)
+ darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ JAVA_HOME="$(/usr/libexec/java_home)"
+ export JAVA_HOME
+ else
+ JAVA_HOME="/Library/Java/Home"
+ export JAVA_HOME
fi
- ;;
+ fi
+ ;;
esac
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
+if [ -z "$JAVA_HOME" ]; then
+ if [ -r /etc/gentoo-release ]; then
+ JAVA_HOME=$(java-config --jre-home)
fi
fi
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- PRG="$0"
-
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+if $cygwin; then
+ [ -n "$JAVA_HOME" ] \
+ && JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
+ [ -n "$CLASSPATH" ] \
+ && CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+if $mingw; then
+ [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \
+ && JAVA_HOME="$(
+ cd "$JAVA_HOME" || (
+ echo "cannot cd into $JAVA_HOME." >&2
+ exit 1
+ )
+ pwd
+ )"
fi
if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ javaExecutable="$(which javac)"
+ if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ readLink=$(which readlink)
+ if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
+ if $darwin; then
+ javaHome="$(dirname "$javaExecutable")"
+ javaExecutable="$(cd "$javaHome" && pwd -P)/javac"
else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
+ javaExecutable="$(readlink -f "$javaExecutable")"
fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ javaHome="$(dirname "$javaExecutable")"
+ javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+if [ -z "$JAVACMD" ]; then
+ if [ -n "$JAVA_HOME" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
- JAVACMD="`which java`"
+ JAVACMD="$(
+ \unset -f command 2>/dev/null
+ \command -v java
+ )"
fi
fi
-if [ ! -x "$JAVACMD" ] ; then
+if [ ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
+if [ -z "$JAVA_HOME" ]; then
+ echo "Warning: JAVA_HOME environment variable is not set." >&2
fi
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
-
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
+ if [ -z "$1" ]; then
+ echo "Path not specified to find_maven_basedir" >&2
return 1
fi
basedir="$1"
wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
+ while [ "$wdir" != '/' ]; do
+ if [ -d "$wdir"/.mvn ]; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
- wdir=`cd "$wdir/.."; pwd`
+ wdir=$(
+ cd "$wdir/.." || exit 1
+ pwd
+ )
fi
# end of workaround
done
- echo "${basedir}"
+ printf '%s' "$(
+ cd "$basedir" || exit 1
+ pwd
+ )"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
+ # Remove \r in case we run on Windows within Git Bash
+ # and check out the repository with auto CRLF management
+ # enabled. Otherwise, we may read lines that are delimited with
+ # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+ # splitting rules.
+ tr -s '\r\n' ' ' <"$1"
+ fi
+}
+
+log() {
+ if [ "$MVNW_VERBOSE" = true ]; then
+ printf '%s\n' "$1"
fi
}
-BASE_DIR=`find_maven_basedir "$(pwd)"`
+BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
- exit 1;
+ exit 1
fi
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+export MAVEN_PROJECTBASEDIR
+log "$MAVEN_PROJECTBASEDIR"
+
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
-if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found .mvn/wrapper/maven-wrapper.jar"
- fi
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+ log "Found $wrapperJarPath"
else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
- fi
- if [ -n "$MVNW_REPOURL" ]; then
- jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ log "Couldn't find $wrapperJarPath, downloading it ..."
+
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+ fi
+ while IFS="=" read -r key value; do
+ # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+ safeValue=$(echo "$value" | tr -d '\r')
+ case "$key" in wrapperUrl)
+ wrapperUrl="$safeValue"
+ break
+ ;;
+ esac
+ done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+ log "Downloading from: $wrapperUrl"
+
+ if $cygwin; then
+ wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+ fi
+
+ if command -v wget >/dev/null; then
+ log "Found wget ... using wget"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
- while IFS="=" read key value; do
- case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
- esac
- done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Downloading from: $jarUrl"
+ elif command -v curl >/dev/null; then
+ log "Found curl ... using curl"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
- wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ else
+ log "Falling back to using Java to download"
+ javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
+ # For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
- wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ javaSource=$(cygpath --path --windows "$javaSource")
+ javaClass=$(cygpath --path --windows "$javaClass")
fi
-
- if command -v wget > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found wget ... using wget"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget "$jarUrl" -O "$wrapperJarPath"
- else
- wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found curl ... using curl"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl -o "$wrapperJarPath" "$jarUrl" -f
- else
- curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
- fi
-
- else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Falling back to using Java to download"
- fi
- javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaClass=`cygpath --path --windows "$javaClass"`
- fi
- if [ -e "$javaClass" ]; then
- if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Compiling MavenWrapperDownloader.java ..."
- fi
- # Compiling the Java class
- ("$JAVA_HOME/bin/javac" "$javaClass")
- fi
- if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- # Running the downloader
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Running MavenWrapperDownloader.java ..."
- fi
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
- fi
- fi
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
+ log " - Compiling MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ log " - Running MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+ fi
fi
+ fi
fi
##########################################################################################
# End of extension
##########################################################################################
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+ case "$key" in wrapperSha256Sum)
+ wrapperSha256Sum=$value
+ break
+ ;;
+ esac
+done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+ wrapperSha256Result=false
+ if command -v sha256sum >/dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ elif command -v shasum >/dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $wrapperSha256Result = false ]; then
+ echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+ echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+ echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+ exit 1
+ fi
fi
+
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+ [ -n "$JAVA_HOME" ] \
+ && JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
+ [ -n "$CLASSPATH" ] \
+ && CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
+ [ -n "$MAVEN_PROJECTBASEDIR" ] \
+ && MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
index b26ab24f0..4136715f0 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -18,15 +18,14 @@
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@@ -46,8 +45,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
@@ -60,22 +59,22 @@ set ERROR_CODE=0
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
-echo.
+echo. >&2
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
-echo.
+echo. >&2
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
-echo.
+echo. >&2
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
-echo.
+echo. >&2
goto error
@REM ==== END VALIDATION ====
@@ -120,10 +119,10 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
-FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@@ -134,11 +133,11 @@ if exist %WRAPPER_JAR% (
)
) else (
if not "%MVNW_REPOURL%" == "" (
- SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %DOWNLOAD_URL%
+ echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
@@ -146,7 +145,7 @@ if exist %WRAPPER_JAR% (
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
@@ -154,11 +153,36 @@ if exist %WRAPPER_JAR% (
)
@REM End of extension
+@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
+SET WRAPPER_SHA_256_SUM=""
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
+)
+IF NOT %WRAPPER_SHA_256_SUM%=="" (
+ powershell -Command "&{"^
+ "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^
+ "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
+ "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
+ " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
+ " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
+ " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
+ " exit 1;"^
+ "}"^
+ "}"
+ if ERRORLEVEL 1 goto error
+)
+
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
@@ -168,15 +192,15 @@ set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-exit /B %ERROR_CODE%
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 9b4f26ac4..68c8763a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,26 +32,39 @@
https://github.com/pgjdbc/r2dbc-postgresql
- 3.25.3
- 4.2.0
- 4.0.3
- 1.8
+ 3.26.0
+ 4.2.1
+ 5.1.0
+ 8
3.0.2
- 5.10.2
- 1.35
+ 5.10.3
+ 1.37
0.3.0.RELEASE
- 1.3.14
- 4.11.0
- 4.1.104.Final
- 42.7.2
+ 5.12.0
+ 4.1.111.Final
+ 42.7.3
UTF-8
UTF-8
1.0.0.RELEASE
- 2022.0.16
- 3.0
- 5.3.32
- 1.19.5
+ 2023.0.7
+ 3.1
+ 2.0.13
+ 6.1.10
+ 1.19.8
1.19.0
+ 3.6.0
+ 3.3.0
+ 1.6.0
+ 3.13.0
+ 3.1.2
+ 3.5.0
+ 3.3.0
+ 3.2.4
+ 3.4.2
+ 3.7.0
+ 3.3.1
+ 3.3.0
+ 1.6.13
@@ -116,6 +129,13 @@
pom
import
+
+ org.slf4j
+ slf4j-bom
+ ${slf4j.version}
+ pom
+ import
+
@@ -152,7 +172,13 @@
io.netty
netty-transport-native-kqueue
- osx-x86_64
+ osx-aarch_64
+ true
+
+
+ io.netty
+ netty-resolver-dns-native-macos
+ osx-aarch_64
true
@@ -194,17 +220,7 @@
org.junit.jupiter
- junit-jupiter-api
- test
-
-
- org.junit.jupiter
- junit-jupiter-params
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
+ junit-jupiter
test
@@ -237,15 +253,35 @@
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ junit
+ junit
+
+
+
org.testcontainers
postgresql
test
- ch.qos.logback
- logback-classic
- ${logback.version}
+ org.slf4j
+ slf4j-api
+ test
+
+
+ org.slf4j
+ slf4j-nop
test
@@ -261,7 +297,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.12.1
+ ${maven-compiler-plugin.version}
-Werror
@@ -270,16 +306,15 @@
-Xlint:-options
-Xlint:-processing
-Xlint:-serial
+ -Xlint:-classfile
true
- ${java.version}
- ${java.version}
org.apache.maven.plugins
maven-jar-plugin
- 3.3.0
+ ${maven-jar-plugin.version}
@@ -296,12 +331,12 @@
org.apache.maven.plugins
maven-deploy-plugin
- 3.1.1
+ ${maven-deploy-plugin.version}
org.apache.maven.plugins
maven-enforcer-plugin
- 3.4.1
+ ${maven-enforcer-plugin.version}
enforce-no-snapshots
@@ -322,7 +357,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.6.3
+ ${maven-javadoc-plugin.version}
io.r2dbc.postgresql.authentication,io.r2dbc.postgresql.client,io.r2dbc.postgresql.message,io.r2dbc.postgresql.util
@@ -345,7 +380,7 @@
org.apache.maven.plugins
maven-source-plugin
- 3.3.0
+ ${maven-source-plugin.version}
attach-javadocs
@@ -358,7 +393,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.2.3
+ ${maven-surefire-plugin.version}
random
@@ -367,6 +402,9 @@
**/*Tests.java
+
+ -Dfile.encoding=${project.build.sourceEncoding}
+
paranoid
@@ -375,7 +413,7 @@
org.apache.maven.plugins
maven-failsafe-plugin
- 3.2.3
+ ${maven-failsafe-plugin.version}
@@ -390,6 +428,9 @@
**/*TestKit.java
**/*IntegrationTests.java
+
+ -Dfile.encoding=${project.build.sourceEncoding}
+
paranoid
@@ -398,7 +439,7 @@
org.codehaus.mojo
flatten-maven-plugin
- 1.5.0
+ ${flatten-maven-plugin.version}
flatten
@@ -472,7 +513,7 @@
org.codehaus.mojo
build-helper-maven-plugin
- 3.5.0
+ ${build-helper-maven-plugin.version}
add-source
@@ -506,7 +547,7 @@
org.codehaus.mojo
exec-maven-plugin
- 3.1.1
+ ${exec-maven-plugin.version}
run-benchmarks
@@ -558,7 +599,7 @@
org.apache.maven.plugins
maven-gpg-plugin
- 3.1.0
+ ${maven-gpg-plugin.version}
sign-artifacts
@@ -581,7 +622,7 @@
org.sonatype.plugins
nexus-staging-maven-plugin
- 1.6.13
+ ${nexus-staging-maven-plugin.version}
true
sonatype
diff --git a/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java b/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java
index 0ca21ac9b..653f03821 100644
--- a/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java
+++ b/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java
@@ -1,7 +1,6 @@
package io.r2dbc.postgresql.authentication;
import com.ongres.scram.client.ScramClient;
-import com.ongres.scram.common.StringPreparation;
import com.ongres.scram.common.exception.ScramException;
import com.ongres.scram.common.util.TlsServerEndpoint;
import io.r2dbc.postgresql.client.ConnectionContext;
@@ -25,6 +24,9 @@
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import static com.ongres.scram.common.StringPreparation.POSTGRESQL_PREPARATION;
+import static com.ongres.scram.common.util.TlsServerEndpoint.TLS_SERVER_END_POINT;
+
public class SASLAuthenticationHandler implements AuthenticationHandler {
private static final Logger LOG = Loggers.getLogger(SASLAuthenticationHandler.class);
@@ -82,22 +84,16 @@ public FrontendMessage handle(AuthenticationMessage message) {
}
private FrontendMessage handleAuthenticationSASL(AuthenticationSASL message) {
-
- char[] password = new char[this.password.length()];
- for (int i = 0; i < password.length; i++) {
- password[i] = this.password.charAt(i);
- }
-
ScramClient.FinalBuildStage builder = ScramClient.builder()
.advertisedMechanisms(message.getAuthenticationMechanisms())
.username(this.username) // ignored by the server, use startup message
- .password(password)
- .stringPreparation(StringPreparation.POSTGRESQL_PREPARATION);
+ .password(password.toString().toCharArray())
+ .stringPreparation(POSTGRESQL_PREPARATION);
SSLSession sslSession = this.context.getSslSession();
if (sslSession != null && sslSession.isValid()) {
- builder.channelBinding(TlsServerEndpoint.TLS_SERVER_END_POINT, extractSslEndpoint(sslSession));
+ builder.channelBinding(TLS_SERVER_END_POINT, extractSslEndpoint(sslSession));
}
this.scramClient = builder.build();
@@ -107,14 +103,9 @@ private FrontendMessage handleAuthenticationSASL(AuthenticationSASL message) {
private static byte[] extractSslEndpoint(SSLSession sslSession) {
try {
- Certificate[] certificates = sslSession.getPeerCertificates();
- if (certificates != null && certificates.length > 0) {
- Certificate peerCert = certificates[0]; // First certificate is the peer's certificate
- if (peerCert instanceof X509Certificate) {
- X509Certificate cert = (X509Certificate) peerCert;
- return TlsServerEndpoint.getChannelBindingData(cert);
-
- }
+ Certificate[] certificates = sslSession.getPeerCertificates(); // First certificate is the peer's certificate
+ if (certificates != null && certificates.length > 0 && certificates[0] instanceof X509Certificate ) {
+ return TlsServerEndpoint.getChannelBindingData((X509Certificate) certificates[0]);
}
} catch (CertificateException | SSLException e) {
LOG.debug("Cannot extract X509Certificate from SSL session", e);
@@ -125,7 +116,6 @@ private static byte[] extractSslEndpoint(SSLSession sslSession) {
private FrontendMessage handleAuthenticationSASLContinue(AuthenticationSASLContinue message) {
try {
this.scramClient.serverFirstMessage(ByteBufferUtils.decode(message.getData()));
-
return new SASLResponse(ByteBufferUtils.encode(this.scramClient.clientFinalMessage().toString()));
} catch (ScramException e) {
throw Exceptions.propagate(e);
diff --git a/src/test/java/io/r2dbc/postgresql/PgBouncerIntegrationTests.java b/src/test/java/io/r2dbc/postgresql/PgBouncerIntegrationTests.java
index 203d96796..fab77b2a9 100644
--- a/src/test/java/io/r2dbc/postgresql/PgBouncerIntegrationTests.java
+++ b/src/test/java/io/r2dbc/postgresql/PgBouncerIntegrationTests.java
@@ -30,7 +30,7 @@
final class PgBouncerIntegrationTests {
@RegisterExtension
- static final PostgresqlServerExtension SERVER = new PostgresqlServerExtension();
+ static final PostgresqlServerExtension SERVER = new PostgresqlServerExtension("pg_hba_pgbouncer.conf");
@ParameterizedTest
@ValueSource(strings = {"transaction", "statement"})
diff --git a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java
index cb6db4f23..a52384e1b 100644
--- a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java
+++ b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java
@@ -36,6 +36,7 @@
import java.util.Collections;
+import static com.ongres.scram.common.StringPreparation.POSTGRESQL_PREPARATION;
import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -85,6 +86,7 @@ void createAuthenticationSASL() {
.advertisedMechanisms(Collections.singletonList("SCRAM-SHA-256"))
.username("test-username")
.password("test-password".toCharArray())
+ .stringPreparation(POSTGRESQL_PREPARATION)
.build();
// @formatter:off
@@ -103,6 +105,12 @@ void createAuthenticationSASL() {
.username("test-username")
.password("test-password")
.build();
+
+ new PostgresqlConnectionFactory(testClientFactory(client, configuration), configuration)
+ .create()
+ .as(StepVerifier::create)
+ .expectNextCount(1)
+ .verifyComplete();
}
@Test
diff --git a/src/test/java/io/r2dbc/postgresql/client/ReactorNettyClientIntegrationTests.java b/src/test/java/io/r2dbc/postgresql/client/ReactorNettyClientIntegrationTests.java
index c03aba09a..c90b2a466 100644
--- a/src/test/java/io/r2dbc/postgresql/client/ReactorNettyClientIntegrationTests.java
+++ b/src/test/java/io/r2dbc/postgresql/client/ReactorNettyClientIntegrationTests.java
@@ -22,7 +22,7 @@
import io.r2dbc.postgresql.PostgresqlConnectionConfiguration;
import io.r2dbc.postgresql.PostgresqlConnectionFactory;
import io.r2dbc.postgresql.api.PostgresqlConnection;
-import io.r2dbc.postgresql.authentication.PasswordAuthenticationHandler;
+import io.r2dbc.postgresql.authentication.SASLAuthenticationHandler;
import io.r2dbc.postgresql.message.backend.BackendMessage;
import io.r2dbc.postgresql.message.backend.CommandComplete;
import io.r2dbc.postgresql.message.backend.DataRow;
@@ -86,20 +86,26 @@ final class ReactorNettyClientIntegrationTests {
private final ReactorNettyClient client = ReactorNettyClient.connect(SERVER.getHost(), SERVER.getPort())
.delayUntil(client -> StartupMessageFlow
- .exchange(this.getClass().getName(), m -> new PasswordAuthenticationHandler(SERVER.getPassword(), SERVER.getUsername()), client, SERVER.getDatabase(), SERVER.getUsername()))
+ .exchange(this.getClass().getName(), m -> new SASLAuthenticationHandler(SERVER.getPassword(), SERVER.getUsername(), client.getContext()), client, SERVER.getDatabase(), SERVER.getUsername()))
.block();
@BeforeEach
void before() {
- SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
- SERVER.getJdbcOperations().execute("CREATE TABLE test ( value INTEGER )");
+ if (SERVER.getJdbcOperations() != null) {
+ SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
+ SERVER.getJdbcOperations().execute("CREATE TABLE test ( value INTEGER )");
+ }
}
@AfterEach
void after() {
- SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
- this.client.close()
- .block();
+ if (SERVER.getJdbcOperations() != null) {
+ SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
+ }
+ if (this.client != null) {
+ this.client.close()
+ .block();
+ }
}
@Test
@@ -312,11 +318,10 @@ void timeoutTest() {
@Test
@DisabledOnOs(OS.WINDOWS)
void unixDomainSocketTest() {
-
String socket = "/tmp/.s.PGSQL.5432";
assumeThat(KQueue.isAvailable() || Epoll.isAvailable()).describedAs("EPoll or KQueue must be available").isTrue();
- assumeThat(new File(socket)).exists();
+ assumeThat(new File(socket)).describedAs("Local server must be running").exists();
PostgresqlConnectionFactory postgresqlConnectionFactory = new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder()
.socket(socket)
diff --git a/src/test/java/io/r2dbc/postgresql/codec/HStoreCodecUnitTests.java b/src/test/java/io/r2dbc/postgresql/codec/HStoreCodecUnitTests.java
index 96fc406e2..1af36766c 100644
--- a/src/test/java/io/r2dbc/postgresql/codec/HStoreCodecUnitTests.java
+++ b/src/test/java/io/r2dbc/postgresql/codec/HStoreCodecUnitTests.java
@@ -23,6 +23,7 @@
import org.junit.jupiter.api.Test;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -52,6 +53,8 @@ void constructorNoByteBufAllocator() {
@Test
void decodeAsText() {
ByteBuf buffer = TEST.buffer();
+ // The test expects the JVM running with JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
+ assertThat(Charset.defaultCharset()).isEqualTo(StandardCharsets.UTF_8);
buffer.writeCharSequence("\"b\"=>\"\\\"2.2\", \"a\\\"\"=>\"1\", \"c\"=>NULL, \"d\"=>\"Zoë\", \"é\"=>\"120°\"", Charset.defaultCharset());
Map res = new HStoreCodec(TEST, dataType).decode(buffer, dataType, Format.FORMAT_TEXT, Map.class);
Map expect = new HashMap<>();
diff --git a/src/test/java/io/r2dbc/postgresql/util/PgBouncer.java b/src/test/java/io/r2dbc/postgresql/util/PgBouncer.java
index 37593649c..9adcf291e 100644
--- a/src/test/java/io/r2dbc/postgresql/util/PgBouncer.java
+++ b/src/test/java/io/r2dbc/postgresql/util/PgBouncer.java
@@ -25,13 +25,14 @@
*/
public final class PgBouncer implements AutoCloseable {
- public static String IMAGE_NAME = "edoburu/pgbouncer:1.9.0";
+ public static String IMAGE_NAME = "edoburu/pgbouncer:1.22.0-p0";
private final GenericContainer> container;
public PgBouncer(PostgresqlServerExtension server, String poolMode) {
this.container = new GenericContainer<>(IMAGE_NAME)
.withExposedPorts(PostgreSQLContainer.POSTGRESQL_PORT)
+ .withEnv("AUTH_TYPE", "scram-sha-256")
.withEnv("POOL_MODE", poolMode)
.withEnv("SERVER_RESET_QUERY_ALWAYS", "1")
.withEnv("DB_USER", server.getUsername())
diff --git a/src/test/java/io/r2dbc/postgresql/util/PgPool.java b/src/test/java/io/r2dbc/postgresql/util/PgPool.java
index b0105403a..2485c522a 100644
--- a/src/test/java/io/r2dbc/postgresql/util/PgPool.java
+++ b/src/test/java/io/r2dbc/postgresql/util/PgPool.java
@@ -28,7 +28,7 @@ public final class PgPool implements AutoCloseable {
private final GenericContainer> container;
public PgPool(PostgresqlServerExtension server) {
- this.container = new GenericContainer<>("bitnami/pgpool:4.1.0")
+ this.container = new GenericContainer<>("bitnami/pgpool:4.5.2")
.withExposedPorts(PostgreSQLContainer.POSTGRESQL_PORT)
.withEnv("PGPOOL_BACKEND_NODES", String.format("0:%s:%s", server.getPostgres().getNetworkAlias(), PostgreSQLContainer.POSTGRESQL_PORT))
.withEnv("PGPOOL_SR_CHECK_USER", server.getUsername())
diff --git a/src/test/java/io/r2dbc/postgresql/util/PostgresqlHighAvailabilityClusterExtension.java b/src/test/java/io/r2dbc/postgresql/util/PostgresqlHighAvailabilityClusterExtension.java
index 38cb33ddd..088310196 100644
--- a/src/test/java/io/r2dbc/postgresql/util/PostgresqlHighAvailabilityClusterExtension.java
+++ b/src/test/java/io/r2dbc/postgresql/util/PostgresqlHighAvailabilityClusterExtension.java
@@ -21,11 +21,9 @@
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
-import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;
diff --git a/src/test/java/io/r2dbc/postgresql/util/PostgresqlServerExtension.java b/src/test/java/io/r2dbc/postgresql/util/PostgresqlServerExtension.java
index 67ce96f54..d4fe4935d 100644
--- a/src/test/java/io/r2dbc/postgresql/util/PostgresqlServerExtension.java
+++ b/src/test/java/io/r2dbc/postgresql/util/PostgresqlServerExtension.java
@@ -48,7 +48,7 @@
*/
public final class PostgresqlServerExtension implements BeforeAllCallback, AfterAllCallback {
- static final String IMAGE_NAME = "postgres:13.3";
+ static final String IMAGE_NAME = "postgres:16-alpine";
static PostgreSQLContainer> containerInstance = null;
@@ -64,15 +64,24 @@ public final class PostgresqlServerExtension implements BeforeAllCallback, After
return PostgresqlServerExtension.containerInstance = container();
};
- private final DatabaseContainer postgres = getContainer();
+ private final DatabaseContainer postgres;
- private final boolean useTestContainer = this.postgres instanceof TestContainer;
+ private final boolean useTestContainer;
private HikariDataSource dataSource;
private JdbcOperations jdbcOperations;
+ private final String hbaConf;
+
public PostgresqlServerExtension() {
+ this("pg_hba.conf");
+ }
+
+ public PostgresqlServerExtension(String hbaConf) {
+ this.hbaConf = hbaConf;
+ this.postgres = getContainer();
+ this.useTestContainer = postgres instanceof TestContainer;
}
private DatabaseContainer getContainer() {
@@ -191,7 +200,7 @@ private > T container() {
.withCopyFileToContainer(getHostPath("server.crt", 0600), "/var/server.crt")
.withCopyFileToContainer(getHostPath("server.key", 0600), "/var/server.key")
.withCopyFileToContainer(getHostPath("client.crt", 0600), "/var/client.crt")
- .withCopyFileToContainer(getHostPath("pg_hba.conf", 0600), "/var/pg_hba.conf")
+ .withCopyFileToContainer(getHostPath(hbaConf, 0600), "/var/pg_hba.conf")
.withCopyFileToContainer(getHostPath("setup.sh", 0755), "/var/setup.sh")
.withCopyFileToContainer(getHostPath("test-db-init-script.sql", 0755), "/docker-entrypoint-initdb.d/test-db-init-script.sql")
.withReuse(true)
diff --git a/src/test/resources/pg_hba.conf b/src/test/resources/pg_hba.conf
index 6330483ea..6f7d48e99 100644
--- a/src/test/resources/pg_hba.conf
+++ b/src/test/resources/pg_hba.conf
@@ -4,3 +4,5 @@ hostssl all test-ssl all password
hostssl all test-ssl-scram all scram-sha-256
hostssl all test-ssl-with-cert all cert
local all all md5
+
+# host all all all scram-sha-256
diff --git a/src/test/resources/pg_hba_pgbouncer.conf b/src/test/resources/pg_hba_pgbouncer.conf
new file mode 100644
index 000000000..33ce39341
--- /dev/null
+++ b/src/test/resources/pg_hba_pgbouncer.conf
@@ -0,0 +1,8 @@
+hostnossl all test all md5
+hostnossl all test-scram all scram-sha-256
+hostssl all test-ssl all password
+hostssl all test-ssl-with-cert all cert
+local all all md5
+
+# for PgBouncerIntegrationTests
+host all all all scram-sha-256
diff --git a/src/test/resources/setup-standby.sh b/src/test/resources/setup-standby.sh
index 13a5f7bfc..a8e4f78a6 100644
--- a/src/test/resources/setup-standby.sh
+++ b/src/test/resources/setup-standby.sh
@@ -19,4 +19,9 @@ EOF
fi
sed -i 's/wal_level = hot_standby/wal_level = replica/g' "${PGDATA}"/postgresql.conf
echo "ready to run"
-exec gosu postgres postgres
+# gosu isn't installed in alpine: https://github.com/docker-library/postgres/blob/master/Dockerfile-alpine.template
+if [ -x "$(type gosu >/dev/null 2>&1)" ]; then
+ exec gosu postgres postgres
+else
+ exec su-exec postgres postgres
+fi
diff --git a/test.bash b/test.bash
index 2880206a5..005e39917 100755
--- a/test.bash
+++ b/test.bash
@@ -1,16 +1,20 @@
#!/usr/bin/env bash
-docker run -it \
+# https://github.com/docker-library/postgres/blob/master/Dockerfile-alpine.template
+chmod 0600 "$(pwd)/src/test/resources/server.key"
+
+docker run --rm -it \
+ --user 70:70 \
-e "POSTGRES_USER=test" \
-e "POSTGRES_PASSWORD=test" \
-e "POSTGRES_DB=test" \
- --mount type=bind,source="$(pwd)/src/test/resources/server.crt",target=/var/server.crt \
+ --mount type=bind,source="$(pwd)/src/test/resources/server.crt",target=/var/server.crt,readonly \
--mount type=bind,source="$(pwd)/src/test/resources/server.key",target=/var/server.key \
- --mount type=bind,source="$(pwd)/src/test/resources/client.crt",target=/var/client.crt \
- --mount type=bind,source="$(pwd)/src/test/resources/pg_hba.conf",target=/var/pg_hba.conf \
- --mount type=bind,source="$(pwd)/src/test/resources/setup.sh",target=/var/setup.sh \
- --mount type=bind,source="$(pwd)/src/test/resources/test-db-init-script.sql",target=/docker-entrypoint-initdb.d/test-db-init-script.sql \
- postgres:11.1 \
+ --mount type=bind,source="$(pwd)/src/test/resources/client.crt",target=/var/client.crt,readonly \
+ --mount type=bind,source="$(pwd)/src/test/resources/pg_hba.conf",target=/var/pg_hba.conf,readonly \
+ --mount type=bind,source="$(pwd)/src/test/resources/setup.sh",target=/var/setup.sh,readonly \
+ --mount type=bind,source="$(pwd)/src/test/resources/test-db-init-script.sql",target=/docker-entrypoint-initdb.d/test-db-init-script.sql,readonly \
+ postgres:16-alpine \
-c 'ssl=on' \
-c 'ssl_key_file=/var/server.key' \
-c 'ssl_cert_file=/var/server.crt' \