Merge branch 'devel' into 2208-merge-dnssd

This commit is contained in:
Aleksandar Fabijanic 2024-03-28 08:45:39 -05:00 committed by GitHub
commit 056deb3834
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 744 additions and 691 deletions

View File

@ -1,5 +1,5 @@
name: Retry Step name: Retry Step
description: 'Retry a step on failure or timeout' description: "Retry a step on failure or timeout"
inputs: inputs:
timeout_minutes: timeout_minutes:
description: Minutes to wait before attempt times out. Must only specify either minutes or seconds description: Minutes to wait before attempt times out. Must only specify either minutes or seconds
@ -50,5 +50,5 @@ outputs:
exit_error: exit_error:
description: The final error returned by the command description: The final error returned by the command
runs: runs:
using: 'node16' using: "node20"
main: 'dist/index.js' main: "dist/index.js"

View File

@ -35,7 +35,7 @@
"@types/babel-generator": "^6.25.7", "@types/babel-generator": "^6.25.7",
"@types/jest": "^28.1.6", "@types/jest": "^28.1.6",
"@types/milliseconds": "0.0.30", "@types/milliseconds": "0.0.30",
"@types/node": "^16.11.7", "@types/node": "^20.11.24",
"@typescript-eslint/eslint-plugin": "^5.32.0", "@typescript-eslint/eslint-plugin": "^5.32.0",
"@typescript-eslint/parser": "^5.32.0", "@typescript-eslint/parser": "^5.32.0",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.1",

View File

@ -15,29 +15,29 @@ concurrency:
jobs: jobs:
android-arm64-v8a-ndk-latest-cmake: android-arm64-v8a-ndk-latest-cmake:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25c ndk-version: r25c
add-to-path: true add-to-path: true
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all - run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
android-arm64-v8a-ndk-cmake: android-arm64-v8a-ndk-cmake:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25c ndk-version: r25c
add-to-path: true add-to-path: true
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all - run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
android-armeabi-v7a-ndk-cmake: android-armeabi-v7a-ndk-cmake:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25c ndk-version: r25c
@ -47,14 +47,14 @@ jobs:
linux-gcc-make-armv7l: linux-gcc-make-armv7l:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install g++-arm-linux-gnueabihf - run: sudo apt -y update && sudo apt -y install g++-arm-linux-gnueabihf
- run: ./configure --config=X-Linux-gcc-arm --everything --omit=ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/ODBC,JWT,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,SevenZip && make all -s -j4 - run: ./configure --config=X-Linux-gcc-arm --everything --omit=ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/ODBC,JWT,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,SevenZip && make all -s -j4
linux-gcc-make: linux-gcc-make:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
- run: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install - run: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -70,7 +70,7 @@ jobs:
linux-gcc-make-cxx20: linux-gcc-make-cxx20:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
- run: ./configure --config=Linux-c++20 --everything --omit=PDF && make all -s -j4 && sudo make install - run: ./configure --config=Linux-c++20 --everything --omit=PDF && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -86,7 +86,15 @@ jobs:
linux-gcc-make-asan: linux-gcc-make-asan:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
# causes sanitizer to fail.
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
# (https://github.com/google/sanitizers/issues/1716)
- run: sysctl vm.legacy_va_layout
- run: sysctl kernel.randomize_va_space
- run: sudo sysctl vm.mmap_rnd_bits
- run: sudo sysctl -w vm.mmap_rnd_bits=28
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install - run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -102,7 +110,15 @@ jobs:
linux-gcc-make-asan-no-soo: linux-gcc-make-asan-no-soo:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
# causes sanitizer to fail.
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
# (https://github.com/google/sanitizers/issues/1716)
- run: sysctl vm.legacy_va_layout
- run: sysctl kernel.randomize_va_space
- run: sudo sysctl vm.mmap_rnd_bits
- run: sudo sysctl -w vm.mmap_rnd_bits=28
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install - run: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -118,7 +134,7 @@ jobs:
linux-gcc-make-ubsan: linux-gcc-make-ubsan:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install - run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -134,7 +150,15 @@ jobs:
linux-gcc-make-tsan: linux-gcc-make-tsan:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
# causes sanitizer to fail.
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
# (https://github.com/google/sanitizers/issues/1716)
- run: sysctl vm.legacy_va_layout
- run: sysctl kernel.randomize_va_space
- run: sudo sysctl vm.mmap_rnd_bits
- run: sudo sysctl -w vm.mmap_rnd_bits=28
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: ./configure --everything --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip && make all -s -j4 SANITIZEFLAGS=-fsanitize=thread && sudo make install - run: ./configure --everything --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip && make all -s -j4 SANITIZEFLAGS=-fsanitize=thread && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -143,13 +167,12 @@ jobs:
max_attempts: 3 max_attempts: 3
retry_on: any retry_on: any
command: >- command: >-
sudo -s sudo -s ./ci/runtests.sh TSAN
./ci/runtests.sh TSAN
linux-gcc-cmake: linux-gcc-cmake:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: sudo apt -y update && sudo apt -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: cmake -S. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all - run: cmake -S. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -166,25 +189,25 @@ jobs:
linux-emscripten-cmake: linux-emscripten-cmake:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install cmake ninja-build emscripten - run: sudo apt -y update && sudo apt -y install cmake ninja-build emscripten
- run: emcmake cmake -H. -B cmake-build -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=off && emmake cmake --build cmake-build --target all -j4 - run: emcmake cmake -H. -B cmake-build -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=off && emmake cmake --build cmake-build --target all -j4
# TODO: How to run unit tests in emscripten? # TODO: How to run unit tests in emscripten?
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: >- # command: >-
# cd cmake-build && # cd cmake-build &&
# sudo -s # sudo -s
# PWD=`pwd` # PWD=`pwd`
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)" # ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)"
linux-gcc-make-cross-armhf: linux-gcc-make-cross-armhf:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: >- - run: >-
sudo apt-get -y update && sudo apt-get -y update &&
sudo apt-get -y install crossbuild-essential-armhf sudo apt-get -y install crossbuild-essential-armhf
@ -200,7 +223,7 @@ jobs:
macos-clang-make: macos-clang-make:
runs-on: macos-12 runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@1.1 mysql-client unixodbc libpq - run: brew install openssl@1.1 mysql-client unixodbc libpq
- run: >- - run: >-
./configure --everything --no-prefix --omit=PDF ./configure --everything --no-prefix --omit=PDF
@ -228,9 +251,10 @@ jobs:
./ci/runtests.sh ./ci/runtests.sh
macos-clang-make-visibility-hidden: macos-clang-make-visibility-hidden:
# macos-12 runs on Intel CPU
runs-on: macos-12 runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@1.1 mysql-client unixodbc libpq - run: brew install openssl@1.1 mysql-client unixodbc libpq
- run: >- - run: >-
./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF ./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF
@ -258,9 +282,10 @@ jobs:
./ci/runtests.sh ./ci/runtests.sh
macos-clang-cmake-openssl: macos-clang-cmake-openssl:
runs-on: macos-12 # macos-14 runs on Apple Silicon
runs-on: macos-14
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@1.1 mysql-client unixodbc libpq - run: brew install openssl@1.1 mysql-client unixodbc libpq
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all - run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -283,9 +308,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)" ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-cmake-openssl3: macos-clang-cmake-openssl3:
runs-on: macos-12 runs-on: macos-14
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq - run: brew install openssl@3 mysql-client unixodbc libpq
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all - run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -308,9 +333,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)" ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-cmake-openssl3-visibility-hidden: macos-clang-cmake-openssl3-visibility-hidden:
runs-on: macos-12 runs-on: macos-14
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq - run: brew install openssl@3 mysql-client unixodbc libpq
- run: cmake -S. -Bcmake-build -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DENABLE_ENCODINGS_COMPILER=ON -DENABLE_PDF=ON -DENABLE_SEVENZIP=ON -DENABLE_CPPPARSER=ON -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all - run: cmake -S. -Bcmake-build -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DENABLE_ENCODINGS_COMPILER=ON -DENABLE_PDF=ON -DENABLE_SEVENZIP=ON -DENABLE_CPPPARSER=ON -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -333,9 +358,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)" ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-make-openssl3-tsan: macos-clang-make-openssl3-tsan:
runs-on: macos-12 runs-on: macos-14
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@3 - run: brew install openssl@3
- run: >- - run: >-
./configure --everything --no-prefix --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip ./configure --everything --no-prefix --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip
@ -365,7 +390,7 @@ jobs:
macos-clang-make-openssl3-ubsan: macos-clang-make-openssl3-ubsan:
runs-on: macos-12 runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq - run: brew install openssl@3 mysql-client unixodbc libpq
- run: >- - run: >-
./configure --everything --no-prefix --no-samples --omit=PDF ./configure --everything --no-prefix --no-samples --omit=PDF
@ -395,7 +420,7 @@ jobs:
macos-clang-make-openssl3-asan: macos-clang-make-openssl3-asan:
runs-on: macos-12 runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq - run: brew install openssl@3 mysql-client unixodbc libpq
- run: >- - run: >-
./configure --everything --no-prefix --no-samples --omit=PDF ./configure --everything --no-prefix --no-samples --omit=PDF
@ -422,63 +447,63 @@ jobs:
EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF" EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF"
./ci/runtests.sh ./ci/runtests.sh
# windows-2019-msvc-cmake: # windows-2019-msvc-cmake:
# runs-on: windows-2019 # runs-on: windows-2019
# env: # env:
# CPPUNIT_IGNORE: >- # CPPUNIT_IGNORE: >-
# class CppUnit::TestCaller<class PathTest>.testFind, # class CppUnit::TestCaller<class PathTest>.testFind,
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom, # class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
# class CppUnit::TestCaller<class ICMPClientTest>.testPing, # class CppUnit::TestCaller<class ICMPClientTest>.testPing,
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing, # class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU, # class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, # class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy, # class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy,
# class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer # class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@v4
# - run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON # - run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
# - run: cmake --build cmake-build --config Release # - run: cmake --build cmake-build --config Release
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: >- # command: >-
# cd cmake-build; # cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release # ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
# windows-2019-msvc-buildwin-x64: # windows-2019-msvc-buildwin-x64:
# runs-on: windows-2019 # runs-on: windows-2019
# env: # env:
# CPPUNIT_IGNORE: >- # CPPUNIT_IGNORE: >-
# class CppUnit::TestCaller<class PathTest>.testFind, # class CppUnit::TestCaller<class PathTest>.testFind,
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom, # class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
# class CppUnit::TestCaller<class ICMPClientTest>.testPing, # class CppUnit::TestCaller<class ICMPClientTest>.testPing,
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing, # class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU, # class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, # class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy # class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT" # command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
# windows-2019-msvc-buildwin-win32: # windows-2019-msvc-buildwin-win32:
# runs-on: windows-2019 # runs-on: windows-2019
# env: # env:
# CPPUNIT_IGNORE: class CppUnit::TestCaller<class PathTest>.testFind,class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,class CppUnit::TestCaller<class ICMPClientTest>.testPing,class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy # CPPUNIT_IGNORE: class CppUnit::TestCaller<class PathTest>.testFind,class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,class CppUnit::TestCaller<class ICMPClientTest>.testPing,class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT" # command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
windows-2022-msvc-buildwin-x64: windows-2022-msvc-buildwin-x64:
runs-on: windows-2022 runs-on: windows-2022
@ -492,7 +517,7 @@ jobs:
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
with: with:
timeout_minutes: 90 timeout_minutes: 90
@ -500,25 +525,25 @@ jobs:
retry_on: any retry_on: any
command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT" command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
# windows-2022-msvc-buildwin-win32: # windows-2022-msvc-buildwin-win32:
# runs-on: windows-2022 # runs-on: windows-2022
# env: # env:
# CPPUNIT_IGNORE: >- # CPPUNIT_IGNORE: >-
# class CppUnit::TestCaller<class PathTest>.testFind, # class CppUnit::TestCaller<class PathTest>.testFind,
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom, # class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
# class CppUnit::TestCaller<class ICMPClientTest>.testPing, # class CppUnit::TestCaller<class ICMPClientTest>.testPing,
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing, # class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU, # class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, # class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy # class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT" # command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
windows-2022-msvc-cmake: windows-2022-msvc-cmake:
runs-on: windows-2022 runs-on: windows-2022
@ -532,8 +557,8 @@ jobs:
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_DNSSD=OFF -DENABLE_TESTS=ON - run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
- run: cmake --build cmake-build --config Release - run: cmake --build cmake-build --config Release
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
with: with:
@ -544,30 +569,30 @@ jobs:
cd cmake-build; cd cmake-build;
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
# missing asan dll path # missing asan dll path
# windows-2022-msvc-cmake-asan: # windows-2022-msvc-cmake-asan:
# runs-on: windows-2022 # runs-on: windows-2022
# env: # env:
# CPPUNIT_IGNORE: >- # CPPUNIT_IGNORE: >-
# class CppUnit::TestCaller<class PathTest>.testFind, # class CppUnit::TestCaller<class PathTest>.testFind,
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom, # class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
# class CppUnit::TestCaller<class ICMPClientTest>.testPing, # class CppUnit::TestCaller<class ICMPClientTest>.testPing,
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing, # class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU, # class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy, # class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy # class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@v4
# - run: cmake -S. -Bcmake-build -DPOCO_SANITIZE_ASAN=ON -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON # - run: cmake -S. -Bcmake-build -DPOCO_SANITIZE_ASAN=ON -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
# - run: cmake --build cmake-build --config Debug # - run: cmake --build cmake-build --config Debug
# - uses: ./.github/actions/retry-action # - uses: ./.github/actions/retry-action
# with: # with:
# timeout_minutes: 90 # timeout_minutes: 90
# max_attempts: 3 # max_attempts: 3
# retry_on: any # retry_on: any
# command: >- # command: >-
# cd cmake-build; # cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug # ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug
linux-gcc-make-mysql: linux-gcc-make-mysql:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
@ -582,7 +607,7 @@ jobs:
ports: ports:
- 3306:3306 - 3306:3306
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev mysql-client - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev mysql-client
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/SQLite,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install - run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/SQLite,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -595,7 +620,7 @@ jobs:
EXCLUDE_TESTS="ActiveRecord ApacheConnector CppParser CppUnit Crypto Data Data/PostgreSQL Data/ODBC Data/SQLite Encodings Foundation JSON JWT MongoDB Net NetSSL_OpenSSL NetSSL_Win PDF PageCompiler PocoDoc ProGen Prometheus Redis SevenZip Util XML Zip" EXCLUDE_TESTS="ActiveRecord ApacheConnector CppParser CppUnit Crypto Data Data/PostgreSQL Data/ODBC Data/SQLite Encodings Foundation JSON JWT MongoDB Net NetSSL_OpenSSL NetSSL_Win PDF PageCompiler PocoDoc ProGen Prometheus Redis SevenZip Util XML Zip"
./ci/runtests.sh ./ci/runtests.sh
# TODO tests sometimes failing on testTransaction and testReconnect # TODO tests sometimes failing on testTransaction and testReconnect
linux-gcc-make-postgres: linux-gcc-make-postgres:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
services: services:
@ -606,7 +631,7 @@ jobs:
ports: ports:
- 5432:5432 - 5432:5432
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev odbc-postgresql - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev odbc-postgresql
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/ODBC,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install - run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/ODBC,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
@ -622,7 +647,7 @@ jobs:
linux-gcc-make-redis: linux-gcc-make-redis:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
- run: | - run: |
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
@ -643,7 +668,7 @@ jobs:
linux-gcc-make-mongodb: linux-gcc-make-mongodb:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: supercharge/mongodb-github-action@1.10.0 - uses: supercharge/mongodb-github-action@1.10.0
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/ODBC,Data/MySQL,Data/SQLite,Data/PostgreSQL,Encodings,JSON,JWT,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install - run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/ODBC,Data/MySQL,Data/SQLite,Data/PostgreSQL,Encodings,JSON,JWT,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
@ -690,7 +715,7 @@ jobs:
ports: ports:
- 1433:1433 - 1433:1433
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev alien libaio1 gnupg2 curl # libmysqlclient-dev mysql-client odbc-postgresql - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev alien libaio1 gnupg2 curl # libmysqlclient-dev mysql-client odbc-postgresql
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install - run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
# - name: Setup MySQL ODBC connector # - name: Setup MySQL ODBC connector
@ -712,10 +737,10 @@ jobs:
# sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / "/usr/lib/oracle/21/client64/lib" "" "" "/etc/odbc.ini" # sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / "/usr/lib/oracle/21/client64/lib" "" "" "/etc/odbc.ini"
- name: Setup SQL Server ODBC connector - name: Setup SQL Server ODBC connector
run: | run: |
curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
sudo apt-get update sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action
with: with:
timeout_minutes: 90 timeout_minutes: 90
@ -739,7 +764,7 @@ jobs:
ports: ports:
- 3306:3306 - 3306:3306
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: sudo apt -y update - run: sudo apt -y update
- run: ./configure --everything --no-samples --no-sqlparser --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/MySQL,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install - run: ./configure --everything --no-samples --no-sqlparser --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/MySQL,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action - uses: ./.github/actions/retry-action

View File

@ -97,7 +97,7 @@ void ConnectionHandle::setTimeouts(SQLULEN loginTimeout, SQLULEN timeout)
{ {
try try
{ {
setTimeout(timeout); setTimeout(static_cast<int>(timeout));
} }
catch(const NotSupportedException&) {} catch(const NotSupportedException&) {}
} }
@ -145,7 +145,7 @@ bool ConnectionHandle::connect(const std::string& connectString, SQLULEN loginTi
// for Oracle) flat out refuse to set login timeout and return error - that's why these calls // for Oracle) flat out refuse to set login timeout and return error - that's why these calls
// are wrapped in try/catch and silently ignore errors. // are wrapped in try/catch and silently ignore errors.
if (getTimeout() != timeout) if (getTimeout() != timeout)
setTimeout(timeout); setTimeout(static_cast<int>(timeout));
if (getLoginTimeout() != loginTimeout) if (getLoginTimeout() != loginTimeout)
setLoginTimeout(loginTimeout); setLoginTimeout(loginTimeout);
} }

View File

@ -248,7 +248,7 @@ inline Poco::Any SessionImpl::getCursorUse(const std::string&) const
void SessionImpl::setConnectionTimeout(std::size_t timeout) void SessionImpl::setConnectionTimeout(std::size_t timeout)
{ {
SQLULEN value = static_cast<SQLUINTEGER>(timeout); SQLULEN value = static_cast<SQLUINTEGER>(timeout);
_db.setTimeout(value); _db.setTimeout(static_cast<int>(value));
} }

View File

@ -14,6 +14,7 @@
#include "Poco/Data/ODBC/ODBC.h" #include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Unicode_UNIXODBC.h" #include "Poco/Data/ODBC/Unicode_UNIXODBC.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/TextConverter.h" #include "Poco/TextConverter.h"
#include "Poco/UTF8Encoding.h" #include "Poco/UTF8Encoding.h"
#include "Poco/UTF16Encoding.h" #include "Poco/UTF16Encoding.h"
@ -73,6 +74,12 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
SQLSMALLINT* pcbCharAttr, SQLSMALLINT* pcbCharAttr,
NumAttrPtrType pNumAttr) NumAttrPtrType pNumAttr)
{ {
SQLSMALLINT cbCharAttr = 0;
if (!pcbCharAttr) pcbCharAttr = &cbCharAttr;
SQLSMALLINT cbCharAttr;
if (!pcbCharAttr) pcbCharAttr = &cbCharAttr;
if (isString(pCharAttr, cbCharAttrMax)) if (isString(pCharAttr, cbCharAttrMax))
{ {
Buffer<SQLWCHAR> buffer(stringLength(pCharAttr, cbCharAttrMax)); Buffer<SQLWCHAR> buffer(stringLength(pCharAttr, cbCharAttrMax));
@ -85,7 +92,9 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
pcbCharAttr, pcbCharAttr,
pNumAttr); pNumAttr);
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
return rc; return rc;
} }
@ -107,6 +116,11 @@ SQLRETURN SQLColAttributes(SQLHSTMT hstmt,
SQLSMALLINT* pcbDesc, SQLSMALLINT* pcbDesc,
SQLLEN* pfDesc) SQLLEN* pfDesc)
{ {
SQLSMALLINT cbDesc = 0;
if (!pcbDesc) pcbDesc = &cbDesc;
SQLLEN fDesc = 0;
if (!pfDesc) pfDesc = &fDesc;
return SQLColAttribute(hstmt, return SQLColAttribute(hstmt,
icol, icol,
fDescType, fDescType,
@ -151,6 +165,17 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
SQLSMALLINT* pibScale, SQLSMALLINT* pibScale,
SQLSMALLINT* pfNullable) SQLSMALLINT* pfNullable)
{ {
SQLSMALLINT cbColName = 0;
if (!pcbColName) pcbColName = &cbColName;
SQLSMALLINT fSqlType = 0;
if (!pfSqlType) pfSqlType = &fSqlType;
SQLULEN cbColDef = 0;
if (!pcbColDef) pcbColDef = &cbColDef;
SQLSMALLINT ibScale = 0;
if (!pibScale) pibScale = &ibScale;
SQLSMALLINT fNullable = 0;
if (!pfNullable) pfNullable = &fNullable;
Buffer<SQLWCHAR> buffer(cbColNameMax); Buffer<SQLWCHAR> buffer(cbColNameMax);
SQLRETURN rc = SQLDescribeColW(hstmt, SQLRETURN rc = SQLDescribeColW(hstmt,
icol, icol,
@ -162,7 +187,9 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
pibScale, pibScale,
pfNullable); pfNullable);
makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax);
return rc; return rc;
} }
@ -198,6 +225,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax)); Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
@ -208,7 +238,8 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
(SQLINTEGER) buffer.sizeBytes(), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
return rc; return rc;
} }
@ -263,6 +294,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax)); Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
@ -274,7 +308,8 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
(SQLINTEGER) buffer.sizeBytes(), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
return rc; return rc;
} }
@ -312,6 +347,9 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
SQLSMALLINT cbDiagInfoMax, SQLSMALLINT cbDiagInfoMax,
SQLSMALLINT* pcbDiagInfo) SQLSMALLINT* pcbDiagInfo)
{ {
SQLSMALLINT cbDiagInfo = 0;
if (!pcbDiagInfo) pcbDiagInfo = &cbDiagInfo;
if (isString(rgbDiagInfo, cbDiagInfoMax)) if (isString(rgbDiagInfo, cbDiagInfoMax))
{ {
Buffer<SQLWCHAR> buffer(stringLength(rgbDiagInfo, cbDiagInfoMax)); Buffer<SQLWCHAR> buffer(stringLength(rgbDiagInfo, cbDiagInfoMax));
@ -324,7 +362,8 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
(SQLSMALLINT) buffer.sizeBytes(), (SQLSMALLINT) buffer.sizeBytes(),
pcbDiagInfo); pcbDiagInfo);
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
return rc; return rc;
} }
@ -348,6 +387,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
SQLSMALLINT cbErrorMsgMax, SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg) SQLSMALLINT* pcbErrorMsg)
{ {
SQLINTEGER fNativeError = 0;
if (!pfNativeError) pfNativeError = &fNativeError;
SQLSMALLINT cbErrorMsg = 0;
if (!pcbErrorMsg) pcbErrorMsg = &cbErrorMsg;
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1; const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
Buffer<SQLWCHAR> bufState(stateLen); Buffer<SQLWCHAR> bufState(stateLen);
Buffer<SQLWCHAR> bufErr(cbErrorMsgMax); Buffer<SQLWCHAR> bufErr(cbErrorMsgMax);
@ -361,8 +405,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
(SQLSMALLINT) bufErr.size(), (SQLSMALLINT) bufErr.size(),
pcbErrorMsg); pcbErrorMsg);
makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen); if (!Utility::isError(rc))
makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax); {
makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen);
makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax);
}
return rc; return rc;
} }
@ -433,6 +480,9 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax)); Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
@ -476,6 +526,9 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
SQLSMALLINT cbInfoValueMax, SQLSMALLINT cbInfoValueMax,
SQLSMALLINT* pcbInfoValue) SQLSMALLINT* pcbInfoValue)
{ {
SQLSMALLINT cbInfoValue = 0;
if (!pcbInfoValue) pcbInfoValue = &cbInfoValue;
if (cbInfoValueMax) if (cbInfoValueMax)
{ {
Buffer<SQLWCHAR> buffer(cbInfoValueMax); Buffer<SQLWCHAR> buffer(cbInfoValueMax);
@ -486,7 +539,8 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
(SQLSMALLINT) buffer.sizeBytes(), (SQLSMALLINT) buffer.sizeBytes(),
pcbInfoValue); pcbInfoValue);
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
return rc; return rc;
} }
@ -561,6 +615,10 @@ SQLRETURN SQLDataSources(SQLHENV henv,
SQLSMALLINT cbDescMax, SQLSMALLINT cbDescMax,
SQLSMALLINT* pcbDesc) SQLSMALLINT* pcbDesc)
{ {
SQLSMALLINT cbDSN = 0, cbDesc = 0;
if (!pcbDSN) pcbDSN = &cbDSN;
if (!pcbDesc) pcbDesc = &cbDesc;
Buffer<SQLWCHAR> bufDSN(cbDSNMax); Buffer<SQLWCHAR> bufDSN(cbDSNMax);
Buffer<SQLWCHAR> bufDesc(cbDescMax); Buffer<SQLWCHAR> bufDesc(cbDescMax);
@ -573,8 +631,11 @@ SQLRETURN SQLDataSources(SQLHENV henv,
(SQLSMALLINT) bufDesc.size(), (SQLSMALLINT) bufDesc.size(),
pcbDesc); pcbDesc);
makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax); if (!Utility::isError(rc))
makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax); {
makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax);
makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax);
}
return rc; return rc;
} }
@ -589,6 +650,9 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
SQLSMALLINT* pcbConnStrOut, SQLSMALLINT* pcbConnStrOut,
SQLUSMALLINT fDriverCompletion) SQLUSMALLINT fDriverCompletion)
{ {
SQLSMALLINT cbConnStrOut = 0;
if (!pcbConnStrOut) pcbConnStrOut = &cbConnStrOut;
SQLSMALLINT len = cbConnStrIn; SQLSMALLINT len = cbConnStrIn;
if (SQL_NTS == len) if (SQL_NTS == len)
len = (SQLSMALLINT) std::strlen((const char*) szConnStrIn) + 1; len = (SQLSMALLINT) std::strlen((const char*) szConnStrIn) + 1;
@ -606,7 +670,8 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
pcbConnStrOut, pcbConnStrOut,
fDriverCompletion); fDriverCompletion);
makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax); if (!Utility::isError(rc))
makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax);
return rc; return rc;
} }
@ -619,6 +684,9 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
SQLSMALLINT cbConnStrOutMax, SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT* pcbConnStrOut) SQLSMALLINT* pcbConnStrOut)
{ {
SQLSMALLINT cbConnStrOut = 0;
if (!pcbConnStrOut) pcbConnStrOut = &cbConnStrOut;
std::string str; std::string str;
makeUTF16(szConnStrIn, cbConnStrIn, str); makeUTF16(szConnStrIn, cbConnStrIn, str);
@ -631,7 +699,8 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
(SQLSMALLINT) bufConnStrOut.size(), (SQLSMALLINT) bufConnStrOut.size(),
pcbConnStrOut); pcbConnStrOut);
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax); if (!Utility::isError(rc))
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax);
return rc; return rc;
} }
@ -676,6 +745,9 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
SQLINTEGER cbSqlStrMax, SQLINTEGER cbSqlStrMax,
SQLINTEGER* pcbSqlStr) SQLINTEGER* pcbSqlStr)
{ {
SQLINTEGER cbSqlStr = 0;
if (!pcbSqlStr) pcbSqlStr = &cbSqlStr;
std::string str; std::string str;
makeUTF16(szSqlStrIn, cbSqlStrIn, str); makeUTF16(szSqlStrIn, cbSqlStrIn, str);
@ -688,7 +760,8 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
(SQLINTEGER) bufSQLOut.size(), (SQLINTEGER) bufSQLOut.size(),
pcbSqlStr); pcbSqlStr);
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax); if (!Utility::isError(rc))
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax);
return rc; return rc;
} }
@ -753,6 +826,10 @@ SQLRETURN SQLDrivers(SQLHENV henv,
SQLSMALLINT cbDrvrAttrMax, SQLSMALLINT cbDrvrAttrMax,
SQLSMALLINT* pcbDrvrAttr) SQLSMALLINT* pcbDrvrAttr)
{ {
SQLSMALLINT cbDriverDesc = 0, cbDrvrAttr = 0;
if (!pcbDriverDesc) pcbDriverDesc = &cbDriverDesc;
if (!pcbDrvrAttr) pcbDrvrAttr = &cbDrvrAttr;
Buffer<SQLWCHAR> bufDriverDesc(cbDriverDescMax); Buffer<SQLWCHAR> bufDriverDesc(cbDriverDescMax);
Buffer<SQLWCHAR> bufDriverAttr(cbDrvrAttrMax); Buffer<SQLWCHAR> bufDriverAttr(cbDrvrAttrMax);
@ -765,8 +842,11 @@ SQLRETURN SQLDrivers(SQLHENV henv,
(SQLSMALLINT) bufDriverAttr.size(), (SQLSMALLINT) bufDriverAttr.size(),
pcbDrvrAttr); pcbDrvrAttr);
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax); if (!Utility::isError(rc))
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax); {
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax);
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax);
}
return rc; return rc;
} }

View File

@ -49,7 +49,9 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
pcbCharAttr, pcbCharAttr,
pNumAttr); pNumAttr);
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
return rc; return rc;
} }
@ -129,7 +131,9 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
pibScale, pibScale,
pfNullable); pfNullable);
makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax);
return rc; return rc;
} }
@ -167,6 +171,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax)); Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
@ -177,7 +184,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
(SQLINTEGER) buffer.sizeBytes(), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
return rc; return rc;
} }
@ -234,6 +243,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax)); Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
@ -245,7 +257,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
(SQLINTEGER) buffer.sizeBytes(), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
return rc; return rc;
} }
@ -294,7 +308,8 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
(SQLSMALLINT) buffer.sizeBytes(), (SQLSMALLINT) buffer.sizeBytes(),
pcbDiagInfo); pcbDiagInfo);
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
return rc; return rc;
} }
@ -317,6 +332,12 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
SQLSMALLINT cbErrorMsgMax, SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg) SQLSMALLINT* pcbErrorMsg)
{ {
SQLINTEGER nativeError = 0;
SQLSMALLINT cbErrorMsg = 0;
if (!pfNativeError) pfNativeError = &nativeError;
if (!pcbErrorMsg) pcbErrorMsg = &cbErrorMsg;
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1; const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
Buffer<wchar_t> bufState(stateLen); Buffer<wchar_t> bufState(stateLen);
Buffer<wchar_t> bufErr(cbErrorMsgMax); Buffer<wchar_t> bufErr(cbErrorMsgMax);
@ -330,8 +351,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
(SQLSMALLINT) bufErr.size(), (SQLSMALLINT) bufErr.size(),
pcbErrorMsg); pcbErrorMsg);
makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen); if (!Utility::isError(rc))
makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax); {
makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen);
makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax);
}
return rc; return rc;
} }
@ -410,6 +434,9 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER cbValueMax, SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue) SQLINTEGER* pcbValue)
{ {
SQLINTEGER cbValue = 0;
if (!pcbValue) pcbValue = &cbValue;
if (isString(rgbValue, cbValueMax)) if (isString(rgbValue, cbValueMax))
{ {
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax)); Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
@ -457,6 +484,9 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
SQLSMALLINT cbInfoValueMax, SQLSMALLINT cbInfoValueMax,
SQLSMALLINT* pcbInfoValue) SQLSMALLINT* pcbInfoValue)
{ {
SQLSMALLINT cbValue = 0;
if (!pcbInfoValue) pcbInfoValue = &cbValue;
if (cbInfoValueMax) if (cbInfoValueMax)
{ {
Buffer<wchar_t> buffer(cbInfoValueMax); Buffer<wchar_t> buffer(cbInfoValueMax);
@ -467,7 +497,8 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
(SQLSMALLINT) buffer.sizeBytes(), (SQLSMALLINT) buffer.sizeBytes(),
pcbInfoValue); pcbInfoValue);
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); if (!Utility::isError(rc))
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
return rc; return rc;
} }
@ -558,8 +589,11 @@ SQLRETURN SQLDataSources(SQLHENV henv,
(SQLSMALLINT) bufDesc.size(), (SQLSMALLINT) bufDesc.size(),
pcbDesc); pcbDesc);
makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax); if (!Utility::isError(rc))
makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax); {
makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax);
makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax);
}
return rc; return rc;
} }
@ -617,7 +651,8 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
(SQLSMALLINT) bufConnStrOut.size(), (SQLSMALLINT) bufConnStrOut.size(),
pcbConnStrOut); pcbConnStrOut);
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax); if (!Utility::isError(rc))
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax);
return rc; return rc;
} }
@ -674,7 +709,8 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
(SQLINTEGER) bufSQLOut.size(), (SQLINTEGER) bufSQLOut.size(),
pcbSqlStr); pcbSqlStr);
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax); if (!Utility::isError(rc))
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax);
return rc; return rc;
} }
@ -751,8 +787,11 @@ SQLRETURN SQLDrivers(SQLHENV henv,
(SQLSMALLINT) bufDriverAttr.size(), (SQLSMALLINT) bufDriverAttr.size(),
pcbDrvrAttr); pcbDrvrAttr);
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax); if (!Utility::isError(rc))
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax); {
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax);
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax);
}
return rc; return rc;
} }

View File

@ -72,6 +72,9 @@ public:
Poco::UInt64 size() const; Poco::UInt64 size() const;
/// Returns file size /// Returns file size
void flushToDisk();
/// Forces buffered data to be written to the disk
protected: protected:
FileStreamBuf _buf; FileStreamBuf _buf;
}; };

View File

@ -52,6 +52,9 @@ public:
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out); std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
/// Change to specified position, according to mode. /// Change to specified position, according to mode.
void flushToDisk();
/// Forces buffered data to be written to the disk
NativeHandle nativeHandle() const; NativeHandle nativeHandle() const;
/// Returns native file descriptor handle /// Returns native file descriptor handle

View File

@ -51,6 +51,9 @@ public:
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out); std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
/// change to specified position, according to mode /// change to specified position, according to mode
void flushToDisk();
/// Forces buffered data to be written to the disk
NativeHandle nativeHandle() const; NativeHandle nativeHandle() const;
/// Returns native file descriptor handle /// Returns native file descriptor handle

View File

@ -17,21 +17,14 @@
#ifndef Foundation_LogFile_INCLUDED #ifndef Foundation_LogFile_INCLUDED
#define Foundation_LogFile_INCLUDED #define Foundation_LogFile_INCLUDED
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/Timestamp.h"
#include "Poco/FileStream.h"
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "Poco/LogFile_WIN32U.h"
#else
#include "Poco/LogFile_STD.h"
#endif
namespace Poco { namespace Poco {
class Foundation_API LogFile: public LogFileImpl class Foundation_API LogFile
/// This class is used by FileChannel to work /// This class is used by FileChannel to work
/// with a log file. /// with a log file.
{ {
@ -55,36 +48,15 @@ public:
const std::string& path() const; const std::string& path() const;
/// Returns the path given in the constructor. /// Returns the path given in the constructor.
private:
std::string _path;
mutable Poco::FileOutputStream _str;
Timestamp _creationDate;
UInt64 _size;
}; };
//
// inlines
//
inline void LogFile::write(const std::string& text, bool flush)
{
writeImpl(text, flush);
}
inline UInt64 LogFile::size() const
{
return sizeImpl();
}
inline Timestamp LogFile::creationDate() const
{
return creationDateImpl();
}
inline const std::string& LogFile::path() const
{
return pathImpl();
}
} // namespace Poco } // namespace Poco

View File

@ -1,53 +0,0 @@
//
// LogFile_STD.h
//
// Library: Foundation
// Package: Logging
// Module: LogFile
//
// Definition of the LogFileImpl class using iostreams.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_LogFile_STD_INCLUDED
#define Foundation_LogFile_STD_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Timestamp.h"
#include "Poco/FileStream.h"
namespace Poco {
class Foundation_API LogFileImpl
/// The implementation of LogFile for non-Windows platforms.
/// The native filesystem APIs are used for
/// total control over locking behavior.
{
public:
LogFileImpl(const std::string& path);
~LogFileImpl();
void writeImpl(const std::string& text, bool flush);
UInt64 sizeImpl() const;
Timestamp creationDateImpl() const;
const std::string& pathImpl() const;
private:
std::string _path;
mutable Poco::FileOutputStream _str;
Timestamp _creationDate;
UInt64 _size;
};
} // namespace Poco
#endif // Foundation_LogFile_STD_INCLUDED

View File

@ -1,54 +0,0 @@
//
// LogFile_WIN32U.h
//
// Library: Foundation
// Package: Logging
// Module: LogFile
//
// Definition of the LogFileImpl class using the Windows file APIs.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_LogFile_WIN32U_INCLUDED
#define Foundation_LogFile_WIN32U_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Timestamp.h"
#include "Poco/UnWindows.h"
namespace Poco {
class Foundation_API LogFileImpl
/// The implementation of LogFile for Windows.
/// The native filesystem APIs are used for
/// total control over locking behavior.
{
public:
LogFileImpl(const std::string& path);
~LogFileImpl();
void writeImpl(const std::string& text, bool flush);
UInt64 sizeImpl() const;
Timestamp creationDateImpl() const;
const std::string& pathImpl() const;
private:
void createFile();
std::string _path;
HANDLE _hFile;
Timestamp _creationDate;
};
} // namespace Poco
#endif // Foundation_LogFile_WIN32U_INCLUDED

View File

@ -140,6 +140,12 @@ public:
return newoff; return newoff;
} }
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
{
const off_type off = pos;
return seekoff(off, std::ios::beg, which);
}
virtual int sync() virtual int sync()
{ {

View File

@ -67,7 +67,7 @@ const std::string DateTimeFormat::RFC850_REGEX(
const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z"); const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z");
const std::string DateTimeFormat::RFC1036_REGEX( const std::string DateTimeFormat::RFC1036_REGEX(
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sun)), *)?" "(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sunday)), *)?"
"\\d\\d? +" "\\d\\d? +"
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +" "((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? " "\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "

View File

@ -42,7 +42,7 @@ const std::string FileChannel::PROP_ROTATEONOPEN = "rotateOnOpen";
FileChannel::FileChannel(): FileChannel::FileChannel():
_times("utc"), _times("utc"),
_compress(false), _compress(false),
_flush(true), _flush(false),
_rotateOnOpen(false), _rotateOnOpen(false),
_pFile(nullptr), _pFile(nullptr),
_pRotateStrategy(new NullRotateStrategy()), _pRotateStrategy(new NullRotateStrategy()),
@ -56,7 +56,7 @@ FileChannel::FileChannel(const std::string& path):
_path(path), _path(path),
_times("utc"), _times("utc"),
_compress(false), _compress(false),
_flush(true), _flush(false),
_rotateOnOpen(false), _rotateOnOpen(false),
_pFile(nullptr), _pFile(nullptr),
_pRotateStrategy(new NullRotateStrategy()), _pRotateStrategy(new NullRotateStrategy()),

View File

@ -56,10 +56,18 @@ FileIOS::NativeHandle FileIOS::nativeHandle() const
} }
Poco::UInt64 FileIOS::size() const { Poco::UInt64 FileIOS::size() const
{
return _buf.size(); return _buf.size();
} }
void FileIOS::flushToDisk()
{
_buf.flushToDisk();
}
FileInputStream::FileInputStream(): FileInputStream::FileInputStream():
std::istream(&_buf) std::istream(&_buf)
{ {

View File

@ -169,6 +169,17 @@ std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mod
} }
void FileStreamBuf::flushToDisk()
{
if (getMode() & std::ios::out)
{
sync();
if (fsync(_fd) != 0)
File::handleLastError(_path);
}
}
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
{ {
return _fd; return _fd;

View File

@ -199,6 +199,17 @@ std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mod
} }
void FileStreamBuf::flushToDisk()
{
if (getMode() & std::ios::out)
{
sync();
if (FlushFileBuffers(_handle) == 0)
File::handleLastError(_path);
}
}
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
{ {
return _handle; return _handle;

View File

@ -13,20 +13,34 @@
#include "Poco/LogFile.h" #include "Poco/LogFile.h"
#include "Poco/File.h"
#include "Poco/Exception.h"
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "LogFile_WIN32U.cpp"
#else
#include "LogFile_STD.cpp"
#endif
namespace Poco { namespace Poco {
LogFile::LogFile(const std::string& path): LogFileImpl(path) LogFile::LogFile(const std::string& path):
_path(path),
_str(_path, std::ios::app),
_size(static_cast<UInt64>(_str.tellp()))
{ {
// There seems to be a strange "optimization" in the Windows NTFS
// filesystem that causes it to reuse directory entries of deleted
// files. Example:
// 1. create a file named "test.dat"
// note the file's creation date
// 2. delete the file "test.dat"
// 3. wait a few seconds
// 4. create a file named "test.dat"
// the new file will have the same creation
// date as the old one.
// We work around this bug by taking the file's
// modification date as a reference when the
// file is empty.
if (_size == 0)
_creationDate = File(path).getLastModified();
else
_creationDate = File(path).created();
} }
@ -35,4 +49,63 @@ LogFile::~LogFile()
} }
void LogFile::write(const std::string& text, bool flush)
{
std::streampos pos = _str.tellp();
#if defined(POCO_OS_FAMILY_WINDOWS)
// Replace \n with \r\n
std::string logText;
logText.reserve(text.size() + 16); // keep some reserve for \n -> \r\n
char prevChar = 0;
for (char c: text)
{
if (c == '\n' && prevChar != '\r')
logText += POCO_DEFAULT_NEWLINE_CHARS;
else
logText += c;
prevChar = c;
}
_str << logText;
#else
_str << text;
#endif
_str << POCO_DEFAULT_NEWLINE_CHARS;
if (flush)
_str.flushToDisk();
else
_str.flush();
if (!_str.good())
{
_str.clear();
_str.seekp(pos);
throw WriteFileException(_path);
}
_size = static_cast<UInt64>(_str.tellp());
}
UInt64 LogFile::size() const
{
return _size;
}
Timestamp LogFile::creationDate() const
{
return _creationDate;
}
const std::string& LogFile::path() const
{
return _path;
}
} // namespace Poco } // namespace Poco

View File

@ -1,86 +0,0 @@
//
// LogFile_STD.cpp
//
// Library: Foundation
// Package: Logging
// Module: LogFile
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/LogFile_STD.h"
#include "Poco/File.h"
#include "Poco/Exception.h"
#include <unistd.h>
namespace Poco {
LogFileImpl::LogFileImpl(const std::string& path):
_path(path),
_str(_path, std::ios::app),
_size(static_cast<UInt64>(_str.tellp()))
{
if (_size == 0)
_creationDate = File(path).getLastModified();
else
_creationDate = File(path).created();
}
LogFileImpl::~LogFileImpl()
{
}
void LogFileImpl::writeImpl(const std::string& text, bool flush)
{
std::streampos pos = _str.tellp();
_str << text << '\n';
// Flush the stream buffer to file to match the implementation on Windows
_str.flush();
if (!_str.good())
{
_str.clear();
_str.seekp(pos);
throw WriteFileException(_path);
}
if (flush)
{
// Sync the file to disk as it is done on Windows
if (fsync(_str.nativeHandle()) != 0)
throw WriteFileException(_path);
}
_size = static_cast<UInt64>(_str.tellp());
}
UInt64 LogFileImpl::sizeImpl() const
{
return _size;
}
Timestamp LogFileImpl::creationDateImpl() const
{
return _creationDate;
}
const std::string& LogFileImpl::pathImpl() const
{
return _path;
}
} // namespace Poco

View File

@ -1,127 +0,0 @@
//
// LogFile_WIN32U.cpp
//
// Library: Foundation
// Package: Logging
// Module: LogFile
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/LogFile_WIN32U.h"
#include "Poco/File.h"
#include "Poco/Exception.h"
#include "Poco/UnicodeConverter.h"
// TODO: LogStream shall use FileOutputStream for all implementations (see LogStream_STD)
// TODO: Implement flushToDisk function in FileOutputStream.
namespace Poco {
LogFileImpl::LogFileImpl(const std::string& path): _path(path), _hFile(INVALID_HANDLE_VALUE)
{
File file(path);
if (file.exists())
{
if (0 == sizeImpl())
_creationDate = file.getLastModified();
else
_creationDate = file.created();
}
}
LogFileImpl::~LogFileImpl()
{
CloseHandle(_hFile);
}
void LogFileImpl::writeImpl(const std::string& text, bool flush)
{
if (INVALID_HANDLE_VALUE == _hFile) createFile();
std::string logText;
logText.reserve(text.size() + 16); // keep some reserve for \n -> \r\n and terminating \r\n
for (char c: text)
{
if (c == '\n')
logText += "\r\n";
else
logText += c;
}
logText += "\r\n";
DWORD bytesWritten;
BOOL res = WriteFile(_hFile, logText.data(), static_cast<DWORD>(logText.size()), &bytesWritten, NULL);
if (!res) throw WriteFileException(_path);
if (flush)
{
res = FlushFileBuffers(_hFile);
if (!res) throw WriteFileException(_path);
}
}
UInt64 LogFileImpl::sizeImpl() const
{
if (INVALID_HANDLE_VALUE == _hFile)
{
File file(_path);
if (file.exists()) return file.getSize();
else return 0;
}
LARGE_INTEGER li;
li.HighPart = 0;
li.LowPart = SetFilePointer(_hFile, 0, &li.HighPart, FILE_CURRENT);
return li.QuadPart;
}
Timestamp LogFileImpl::creationDateImpl() const
{
return _creationDate;
}
const std::string& LogFileImpl::pathImpl() const
{
return _path;
}
void LogFileImpl::createFile()
{
std::wstring upath;
FileImpl::convertPath(_path, upath);
_hFile = CreateFileW(upath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (_hFile == INVALID_HANDLE_VALUE) throw OpenFileException(_path);
SetFilePointer(_hFile, 0, 0, FILE_END);
// There seems to be a strange "optimization" in the Windows NTFS
// filesystem that causes it to reuse directory entries of deleted
// files. Example:
// 1. create a file named "test.dat"
// note the file's creation date
// 2. delete the file "test.dat"
// 3. wait a few seconds
// 4. create a file named "test.dat"
// the new file will have the same creation
// date as the old one.
// We work around this bug by taking the file's
// modification date as a reference when the
// file is empty.
if (sizeImpl() == 0)
_creationDate = File(_path).getLastModified();
else
_creationDate = File(_path).created();
}
} // namespace Poco

View File

@ -857,7 +857,8 @@ void URI::parseHostAndPort(std::string::const_iterator& it, const std::string::c
} }
else _port = 0; else _port = 0;
_host = host; _host = host;
toLowerInPlace(_host); if (_host.size() && _host[0] != '%')
toLowerInPlace(_host);
} }

View File

@ -143,6 +143,14 @@ void MemoryStreamTest::testInputSeek()
assertTrue (istr.good()); assertTrue (istr.good());
assertTrue (9 == istr.tellg()); assertTrue (9 == istr.tellg());
istr.seekg(5);
assertTrue (istr.good());
assertTrue (5 == istr.tellg());
istr >> c;
assertTrue (c == '6');
{ {
Poco::MemoryInputStream istr2(buffer.begin(), buffer.size()); Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
istr2.seekg(10, std::ios_base::beg); istr2.seekg(10, std::ios_base::beg);
@ -337,6 +345,12 @@ void MemoryStreamTest::testOutputSeek()
assertTrue (ostr.good()); assertTrue (ostr.good());
assertTrue (9 == ostr.tellp()); assertTrue (9 == ostr.tellp());
ostr.seekp(5);
assertTrue (ostr.good());
assertTrue (5 == ostr.tellp());
{ {
Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size()); Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
ostr2.seekp(10, std::ios_base::beg); ostr2.seekp(10, std::ios_base::beg);

View File

@ -798,6 +798,15 @@ void URITest::testOther()
assertTrue (uri.getRawFragment() == "foo%2Fbar"); assertTrue (uri.getRawFragment() == "foo%2Fbar");
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo%2Fbar"); assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo%2Fbar");
assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo%2Fbar"); assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo%2Fbar");
uri = "http://ServerSocket.com/index.html";
assertTrue (uri.toString() == "http://serversocket.com/index.html");
uri = "http+unix://%2Ftmp%2FServerSocket/index.html";
assertTrue (uri.toString() == "http+unix://%2Ftmp%2FServerSocket/index.html");
std::string decoded;
uri.decode("http+unix://%2Ftmp%2FServerSocket/index.html", decoded);
assertTrue (decoded == "http+unix:///tmp/ServerSocket/index.html");
} }

View File

@ -129,7 +129,7 @@ public:
/// If reuseAddress is true, sets the SO_REUSEADDR /// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option. /// socket option.
/// ///
/// Calls to connect cannot() come before calls to bind(). /// Calls to connect() cannot come before calls to bind().
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort); void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
/// Bind a local address to the socket. /// Bind a local address to the socket.
@ -143,7 +143,7 @@ public:
/// If reusePort is true, sets the SO_REUSEPORT /// If reusePort is true, sets the SO_REUSEPORT
/// socket option. /// socket option.
/// ///
/// Calls to connect cannot() come before calls to bind(). /// Calls to connect() cannot come before calls to bind().
void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only = false); void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only = false);
/// Bind a local address to the socket. /// Bind a local address to the socket.
@ -160,7 +160,7 @@ public:
/// Sets the IPV6_V6ONLY socket option in accordance with /// Sets the IPV6_V6ONLY socket option in accordance with
/// the supplied ipV6Only value. /// the supplied ipV6Only value.
/// ///
/// Calls to connect cannot() come before calls to bind(). /// Calls to connect() cannot come before calls to bind().
int sendBytes(const void* buffer, int length, int flags = 0); int sendBytes(const void* buffer, int length, int flags = 0);
/// Sends the contents of the given buffer through /// Sends the contents of the given buffer through

View File

@ -216,7 +216,7 @@ public:
/// as the system is free to adjust the value. /// as the system is free to adjust the value.
void setReceiveTimeout(const Poco::Timespan& timeout); void setReceiveTimeout(const Poco::Timespan& timeout);
/// Sets the send timeout for the socket. /// Sets the receive timeout for the socket.
/// ///
/// On systems that do not support SO_RCVTIMEO, a /// On systems that do not support SO_RCVTIMEO, a
/// workaround using poll() is provided. /// workaround using poll() is provided.

View File

@ -147,7 +147,7 @@ SocketImpl* SocketImpl::acceptConnection(SocketAddress& clientAddr)
return new StreamSocketImpl(sd); return new StreamSocketImpl(sd);
} }
error(); // will throw error(); // will throw
return 0; return nullptr;
} }
@ -527,7 +527,7 @@ int SocketImpl::sendTo(const SocketBufVec& buffers, const SocketAddress& address
msgHdr.msg_namelen = address.length(); msgHdr.msg_namelen = address.length();
msgHdr.msg_iov = const_cast<iovec*>(&buffers[0]); msgHdr.msg_iov = const_cast<iovec*>(&buffers[0]);
msgHdr.msg_iovlen = buffers.size(); msgHdr.msg_iovlen = buffers.size();
msgHdr.msg_control = 0; msgHdr.msg_control = nullptr;
msgHdr.msg_controllen = 0; msgHdr.msg_controllen = 0;
msgHdr.msg_flags = flags; msgHdr.msg_flags = flags;
rc = sendmsg(_sockfd, &msgHdr, flags); rc = sendmsg(_sockfd, &msgHdr, flags);
@ -613,7 +613,7 @@ int SocketImpl::receiveFrom(SocketBufVec& buffers, struct sockaddr** pSA, poco_s
msgHdr.msg_namelen = **ppSALen; msgHdr.msg_namelen = **ppSALen;
msgHdr.msg_iov = &buffers[0]; msgHdr.msg_iov = &buffers[0];
msgHdr.msg_iovlen = buffers.size(); msgHdr.msg_iovlen = buffers.size();
msgHdr.msg_control = 0; msgHdr.msg_control = nullptr;
msgHdr.msg_controllen = 0; msgHdr.msg_controllen = 0;
msgHdr.msg_flags = flags; msgHdr.msg_flags = flags;
rc = recvmsg(_sockfd, &msgHdr, flags); rc = recvmsg(_sockfd, &msgHdr, flags);
@ -652,7 +652,7 @@ int SocketImpl::available()
if (result && (type() == SOCKET_TYPE_DATAGRAM)) if (result && (type() == SOCKET_TYPE_DATAGRAM))
{ {
std::vector<char> buf(result); std::vector<char> buf(result);
result = recvfrom(sockfd(), &buf[0], result, MSG_PEEK, NULL, NULL); result = recvfrom(sockfd(), &buf[0], result, MSG_PEEK, nullptr, nullptr);
} }
#endif #endif
return result; return result;
@ -1114,7 +1114,7 @@ void SocketImpl::setReusePort(bool flag)
int value = flag ? 1 : 0; int value = flag ? 1 : 0;
setOption(SOL_SOCKET, SO_REUSEPORT, value); setOption(SOL_SOCKET, SO_REUSEPORT, value);
} }
catch (IOException&) catch (const IOException&)
{ {
// ignore error, since not all implementations // ignore error, since not all implementations
// support SO_REUSEPORT, even if the macro // support SO_REUSEPORT, even if the macro

View File

@ -132,7 +132,7 @@ public:
/// a SecureStreamSocketImpl, otherwise an InvalidArgumentException /// a SecureStreamSocketImpl, otherwise an InvalidArgumentException
/// will be thrown. /// will be thrown.
virtual ~SecureStreamSocket(); ~SecureStreamSocket() override;
/// Destroys the StreamSocket. /// Destroys the StreamSocket.
SecureStreamSocket& operator = (const Socket& socket); SecureStreamSocket& operator = (const Socket& socket);

View File

@ -39,12 +39,12 @@ public:
SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext); SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext);
/// Creates the SecureStreamSocketImpl. /// Creates the SecureStreamSocketImpl.
SocketImpl* acceptConnection(SocketAddress& clientAddr); SocketImpl* acceptConnection(SocketAddress& clientAddr) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
void connect(const SocketAddress& address); void connect(const SocketAddress& address) override;
/// Initializes the socket and establishes a connection to /// Initializes the socket and establishes a connection to
/// the TCP server at the given address. /// the TCP server at the given address.
/// ///
@ -52,57 +52,57 @@ public:
/// connection is established. Instead, incoming and outgoing /// connection is established. Instead, incoming and outgoing
/// packets are restricted to the specified address. /// packets are restricted to the specified address.
void connect(const SocketAddress& address, const Poco::Timespan& timeout); void connect(const SocketAddress& address, const Poco::Timespan& timeout) override;
/// Initializes the socket, sets the socket timeout and /// Initializes the socket, sets the socket timeout and
/// establishes a connection to the TCP server at the given address. /// establishes a connection to the TCP server at the given address.
void connectNB(const SocketAddress& address); void connectNB(const SocketAddress& address) override;
/// Initializes the socket and establishes a connection to /// Initializes the socket and establishes a connection to
/// the TCP server at the given address. Prior to opening the /// the TCP server at the given address. Prior to opening the
/// connection the socket is set to nonblocking mode. /// connection the socket is set to nonblocking mode.
void bind(const SocketAddress& address, bool reuseAddress = false); void bind(const SocketAddress& address, bool reuseAddress = false) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
void listen(int backlog = 64); void listen(int backlog = 64) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
void close(); void close() override;
/// Close the socket. /// Close the socket.
int sendBytes(const void* buffer, int length, int flags = 0); int sendBytes(const void* buffer, int length, int flags = 0) override;
/// Sends the contents of the given buffer through /// Sends the contents of the given buffer through
/// the socket. Any specified flags are ignored. /// the socket. Any specified flags are ignored.
/// ///
/// Returns the number of bytes sent, which may be /// Returns the number of bytes sent, which may be
/// less than the number of bytes specified. /// less than the number of bytes specified.
int receiveBytes(void* buffer, int length, int flags = 0); int receiveBytes(void* buffer, int length, int flags = 0) override;
/// Receives data from the socket and stores it /// Receives data from the socket and stores it
/// in buffer. Up to length bytes are received. /// in buffer. Up to length bytes are received.
/// ///
/// Returns the number of bytes received. /// Returns the number of bytes received.
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0); int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0); int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
void sendUrgent(unsigned char data); void sendUrgent(unsigned char data) override;
/// Not supported by a SecureStreamSocket. /// Not supported by a SecureStreamSocket.
/// ///
/// Throws a Poco::InvalidAccessException. /// Throws a Poco::InvalidAccessException.
int available(); int available() override;
/// Returns the number of bytes available that can be read /// Returns the number of bytes available that can be read
/// without causing the socket to block. /// without causing the socket to block.
/// ///
@ -110,26 +110,26 @@ public:
/// can be read from the currently buffered SSL record, /// can be read from the currently buffered SSL record,
/// before a new record is read from the underlying socket. /// before a new record is read from the underlying socket.
void shutdownReceive(); void shutdownReceive() override;
/// Shuts down the receiving part of the socket connection. /// Shuts down the receiving part of the socket connection.
/// ///
/// Since SSL does not support a half shutdown, this does /// Since SSL does not support a half shutdown, this does
/// nothing. /// nothing.
void shutdownSend(); void shutdownSend() override;
/// Shuts down the receiving part of the socket connection. /// Shuts down the receiving part of the socket connection.
/// ///
/// Since SSL does not support a half shutdown, this does /// Since SSL does not support a half shutdown, this does
/// nothing. /// nothing.
void shutdown(); void shutdown() override;
/// Shuts down the SSL connection. /// Shuts down the SSL connection.
void abort(); void abort();
/// Aborts the connection by closing the underlying /// Aborts the connection by closing the underlying
/// TCP connection. No orderly SSL shutdown is performed. /// TCP connection. No orderly SSL shutdown is performed.
bool secure() const; bool secure() const override;
/// Returns true iff the socket's connection is secure /// Returns true iff the socket's connection is secure
/// (using SSL or TLS). /// (using SSL or TLS).
@ -203,7 +203,7 @@ protected:
void connectSSL(); void connectSSL();
/// Performs a SSL client-side handshake on an already connected TCP socket. /// Performs a SSL client-side handshake on an already connected TCP socket.
~SecureStreamSocketImpl(); ~SecureStreamSocketImpl() override;
/// Destroys the SecureStreamSocketImpl. /// Destroys the SecureStreamSocketImpl.
static int lastError(); static int lastError();

View File

@ -22,10 +22,7 @@
#include "Poco/Net/SecureStreamSocketImpl.h" #include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/StreamSocketImpl.h" #include "Poco/Net/StreamSocketImpl.h"
#include "Poco/Net/StreamSocket.h" #include "Poco/Net/StreamSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/DNS.h"
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
#include "Poco/NumberParser.h"
#include "Poco/Format.h" #include "Poco/Format.h"
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -38,16 +35,12 @@ using Poco::NumberFormatter;
using Poco::Timespan; using Poco::Timespan;
// workaround for C++-incompatible macro
#define POCO_BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(void*)((n)?"a":NULL))
namespace Poco { namespace Poco {
namespace Net { namespace Net {
SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext): SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext):
_pSSL(0), _pSSL(nullptr),
_pSocket(pSocketImpl), _pSocket(pSocketImpl),
_pContext(pContext), _pContext(pContext),
_needHandshake(false) _needHandshake(false)
@ -86,14 +79,14 @@ void SecureSocketImpl::acceptSSL()
{ {
poco_assert (!_pSSL); poco_assert (!_pSSL);
BIO* pBIO = BIO_new(BIO_s_socket()); BIO* pBIO = ::BIO_new(BIO_s_socket());
if (!pBIO) throw SSLException("Cannot create BIO object"); if (!pBIO) throw SSLException("Cannot create BIO object");
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE); BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
_pSSL = SSL_new(_pContext->sslContext()); _pSSL = ::SSL_new(_pContext->sslContext());
if (!_pSSL) if (!_pSSL)
{ {
BIO_free(pBIO); ::BIO_free(pBIO);
throw SSLException("Cannot create SSL object"); throw SSLException("Cannot create SSL object");
} }
@ -105,15 +98,15 @@ void SecureSocketImpl::acceptSSL()
* tickets. */ * tickets. */
if (1 != SSL_set_num_tickets(_pSSL, 0)) if (1 != SSL_set_num_tickets(_pSSL, 0))
{ {
BIO_free(pBIO); ::BIO_free(pBIO);
throw SSLException("Cannot create SSL object"); throw SSLException("Cannot create SSL object");
} }
//Otherwise we can perform two-way shutdown. Client must call SSL_read() before the final SSL_shutdown(). //Otherwise we can perform two-way shutdown. Client must call SSL_read() before the final SSL_shutdown().
#endif #endif
SSL_set_bio(_pSSL, pBIO, pBIO); ::SSL_set_bio(_pSSL, pBIO, pBIO);
SSL_set_accept_state(_pSSL); ::SSL_set_accept_state(_pSSL);
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this); ::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
_needHandshake = true; _needHandshake = true;
} }
@ -162,18 +155,18 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
poco_assert (!_pSSL); poco_assert (!_pSSL);
poco_assert (_pSocket->initialized()); poco_assert (_pSocket->initialized());
BIO* pBIO = BIO_new(BIO_s_socket()); ::BIO* pBIO = ::BIO_new(BIO_s_socket());
if (!pBIO) throw SSLException("Cannot create SSL BIO object"); if (!pBIO) throw SSLException("Cannot create SSL BIO object");
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE); BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
_pSSL = SSL_new(_pContext->sslContext()); _pSSL = ::SSL_new(_pContext->sslContext());
if (!_pSSL) if (!_pSSL)
{ {
BIO_free(pBIO); ::BIO_free(pBIO);
throw SSLException("Cannot create SSL object"); throw SSLException("Cannot create SSL object");
} }
SSL_set_bio(_pSSL, pBIO, pBIO); ::SSL_set_bio(_pSSL, pBIO, pBIO);
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this); ::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
if (!_peerHostName.empty()) if (!_peerHostName.empty())
{ {
@ -189,27 +182,27 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
if (_pSession && _pSession->isResumable()) if (_pSession && _pSession->isResumable())
{ {
SSL_set_session(_pSSL, _pSession->sslSession()); ::SSL_set_session(_pSSL, _pSession->sslSession());
} }
try try
{ {
if (performHandshake && _pSocket->getBlocking()) if (performHandshake && _pSocket->getBlocking())
{ {
int ret = SSL_connect(_pSSL); int ret = ::SSL_connect(_pSSL);
handleError(ret); handleError(ret);
verifyPeerCertificate(); verifyPeerCertificate();
} }
else else
{ {
SSL_set_connect_state(_pSSL); ::SSL_set_connect_state(_pSSL);
_needHandshake = true; _needHandshake = true;
} }
} }
catch (...) catch (...)
{ {
SSL_free(_pSSL); ::SSL_free(_pSSL);
_pSSL = 0; _pSSL = nullptr;
throw; throw;
} }
} }
@ -259,11 +252,11 @@ void SecureSocketImpl::shutdown()
{ {
if (_pSSL) if (_pSSL)
{ {
// Don't shut down the socket more than once. // Don't shut down the socket more than once.
int shutdownState = SSL_get_shutdown(_pSSL); int shutdownState = ::SSL_get_shutdown(_pSSL);
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN; bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
if (!shutdownSent) if (!shutdownSent)
{ {
// A proper clean shutdown would require us to // A proper clean shutdown would require us to
// retry the shutdown if we get a zero return // retry the shutdown if we get a zero return
// value, until SSL_shutdown() returns 1. // value, until SSL_shutdown() returns 1.
@ -274,7 +267,7 @@ void SecureSocketImpl::shutdown()
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
int rc = 0; int rc = 0;
if (!_bidirectShutdown) if (!_bidirectShutdown)
rc = SSL_shutdown(_pSSL); rc = ::SSL_shutdown(_pSSL);
else else
{ {
Poco::Timespan recvTimeout = _pSocket->getReceiveTimeout(); Poco::Timespan recvTimeout = _pSocket->getReceiveTimeout();
@ -282,11 +275,11 @@ void SecureSocketImpl::shutdown()
Poco::Timestamp tsNow; Poco::Timestamp tsNow;
do do
{ {
rc = SSL_shutdown(_pSSL); rc = ::SSL_shutdown(_pSSL);
if (rc == 1) break; if (rc == 1) break;
if (rc < 0) if (rc < 0)
{ {
int err = SSL_get_error(_pSSL, rc); int err = ::SSL_get_error(_pSSL, rc);
if (err == SSL_ERROR_WANT_READ) if (err == SSL_ERROR_WANT_READ)
_pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ); _pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ);
else if (err == SSL_ERROR_WANT_WRITE) else if (err == SSL_ERROR_WANT_WRITE)
@ -294,7 +287,7 @@ void SecureSocketImpl::shutdown()
else else
{ {
int socketError = SocketImpl::lastError(); int socketError = SocketImpl::lastError();
long lastError = ERR_get_error(); long lastError = ::ERR_get_error();
if ((err == SSL_ERROR_SSL) && (socketError == 0) && (lastError == 0x0A000123)) if ((err == SSL_ERROR_SSL) && (socketError == 0) && (lastError == 0x0A000123))
rc = 0; rc = 0;
break; break;
@ -304,7 +297,7 @@ void SecureSocketImpl::shutdown()
} while (!tsNow.isElapsed(recvTimeout.totalMicroseconds())); } while (!tsNow.isElapsed(recvTimeout.totalMicroseconds()));
} }
#else #else
int rc = SSL_shutdown(_pSSL); int rc = ::SSL_shutdown(_pSSL);
#endif #endif
if (rc < 0) handleError(rc); if (rc < 0) handleError(rc);
if (_pSocket->getBlocking()) if (_pSocket->getBlocking())
@ -361,11 +354,17 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
else else
return rc; return rc;
} }
do const auto sendTimeout = _pSocket->getSendTimeout();
Poco::Timestamp tsStart;
while (true)
{ {
rc = SSL_write(_pSSL, buffer, length); rc = ::SSL_write(_pSSL, buffer, length);
} if (!mustRetry(rc))
while (mustRetry(rc)); break;
if (tsStart.isElapsed(sendTimeout.totalMicroseconds()))
throw Poco::TimeoutException();
};
if (rc <= 0) if (rc <= 0)
{ {
rc = handleError(rc); rc = handleError(rc);
@ -389,11 +388,18 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
else else
return rc; return rc;
} }
do
const auto recvTimeout = _pSocket->getReceiveTimeout();
Poco::Timestamp tsStart;
while (true)
{ {
rc = SSL_read(_pSSL, buffer, length); rc = ::SSL_read(_pSSL, buffer, length);
} if (!mustRetry(rc))
while (mustRetry(rc)); break;
if (tsStart.isElapsed(recvTimeout.totalMicroseconds()))
throw Poco::TimeoutException();
};
_bidirectShutdown = false; _bidirectShutdown = false;
if (rc <= 0) if (rc <= 0)
{ {
@ -407,7 +413,7 @@ int SecureSocketImpl::available() const
{ {
poco_check_ptr (_pSSL); poco_check_ptr (_pSSL);
return SSL_pending(_pSSL); return ::SSL_pending(_pSSL);
} }
@ -417,11 +423,17 @@ int SecureSocketImpl::completeHandshake()
poco_check_ptr (_pSSL); poco_check_ptr (_pSSL);
int rc; int rc;
do const auto recvTimeout = _pSocket->getReceiveTimeout();
Poco::Timestamp tsStart;
while (true)
{ {
rc = SSL_do_handshake(_pSSL); rc = ::SSL_do_handshake(_pSSL);
} if (!mustRetry(rc))
while (mustRetry(rc)); break;
if (tsStart.isElapsed(recvTimeout.totalMicroseconds()))
throw Poco::TimeoutException();
};
if (rc <= 0) if (rc <= 0)
{ {
return handleError(rc); return handleError(rc);
@ -460,7 +472,7 @@ long SecureSocketImpl::verifyPeerCertificateImpl(const std::string& hostName)
return X509_V_OK; return X509_V_OK;
} }
X509* pCert = SSL_get_peer_certificate(_pSSL); ::X509* pCert = ::SSL_get_peer_certificate(_pSSL);
if (pCert) if (pCert)
{ {
X509Certificate cert(pCert); X509Certificate cert(pCert);
@ -477,7 +489,7 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
SocketAddress addr(hostName, 0); SocketAddress addr(hostName, 0);
return addr.host().isLoopback(); return addr.host().isLoopback();
} }
catch (Poco::Exception&) catch (const Poco::Exception&)
{ {
return false; return false;
} }
@ -487,9 +499,9 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
X509* SecureSocketImpl::peerCertificate() const X509* SecureSocketImpl::peerCertificate() const
{ {
if (_pSSL) if (_pSSL)
return SSL_get_peer_certificate(_pSSL); return ::SSL_get_peer_certificate(_pSSL);
else else
return 0; return nullptr;
} }
@ -497,26 +509,24 @@ bool SecureSocketImpl::mustRetry(int rc)
{ {
if (rc <= 0) if (rc <= 0)
{ {
int sslError = SSL_get_error(_pSSL, rc); static const Poco::Timespan pollTimeout(0, 100000);
int sslError = ::SSL_get_error(_pSSL, rc);
int socketError = _pSocket->lastError(); int socketError = _pSocket->lastError();
switch (sslError) switch (sslError)
{ {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
if (_pSocket->getBlocking()) if (_pSocket->getBlocking())
{ {
if (_pSocket->poll(_pSocket->getReceiveTimeout(), Poco::Net::Socket::SELECT_READ)) _pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ);
return true; return true;
else
throw Poco::TimeoutException();
} }
break; break;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
if (_pSocket->getBlocking()) if (_pSocket->getBlocking())
{ {
if (_pSocket->poll(_pSocket->getSendTimeout(), Poco::Net::Socket::SELECT_WRITE)) _pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_WRITE);
return true; return true;
else
throw Poco::TimeoutException();
} }
break; break;
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
@ -533,7 +543,7 @@ int SecureSocketImpl::handleError(int rc)
{ {
if (rc > 0) return rc; if (rc > 0) return rc;
int sslError = SSL_get_error(_pSSL, rc); int sslError = ::SSL_get_error(_pSSL, rc);
int socketError = SocketImpl::lastError(); int socketError = SocketImpl::lastError();
switch (sslError) switch (sslError)
@ -569,12 +579,12 @@ int SecureSocketImpl::handleError(int rc)
// fallthrough // fallthrough
default: default:
{ {
long lastError = ERR_get_error(); long lastError = ::ERR_get_error();
std::string msg; std::string msg;
if (lastError) if (lastError)
{ {
char buffer[256]; char buffer[256];
ERR_error_string_n(lastError, buffer, sizeof(buffer)); ::ERR_error_string_n(lastError, buffer, sizeof(buffer));
msg = buffer; msg = buffer;
} }
// SSL_GET_ERROR(3ossl): // SSL_GET_ERROR(3ossl):
@ -627,9 +637,9 @@ void SecureSocketImpl::reset()
close(); close();
if (_pSSL) if (_pSSL)
{ {
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr); ::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
SSL_free(_pSSL); ::SSL_free(_pSSL);
_pSSL = 0; _pSSL = nullptr;
} }
} }
@ -655,7 +665,7 @@ void SecureSocketImpl::useSession(Session::Ptr pSession)
bool SecureSocketImpl::sessionWasReused() bool SecureSocketImpl::sessionWasReused()
{ {
if (_pSSL) if (_pSSL)
return SSL_session_reused(_pSSL) != 0; return ::SSL_session_reused(_pSSL) != 0;
else else
return false; return false;
} }
@ -663,7 +673,7 @@ bool SecureSocketImpl::sessionWasReused()
int SecureSocketImpl::onSessionCreated(SSL* pSSL, SSL_SESSION* pSession) int SecureSocketImpl::onSessionCreated(SSL* pSSL, SSL_SESSION* pSession)
{ {
void* pEx = SSL_get_ex_data(pSSL, SSLManager::instance().socketIndex()); void* pEx = ::SSL_get_ex_data(pSSL, SSLManager::instance().socketIndex());
if (pEx) if (pEx)
{ {
SecureSocketImpl* pThis = reinterpret_cast<SecureSocketImpl*>(pEx); SecureSocketImpl* pThis = reinterpret_cast<SecureSocketImpl*>(pEx);

View File

@ -103,7 +103,7 @@ void HTTPSStreamFactoryTest::testError()
uri.setPort(server.port()); uri.setPort(server.port());
try try
{ {
std::istream* pStr = factory.open(uri); factory.open(uri);
fail("not found - must throw"); fail("not found - must throw");
} }
catch (HTTPException& exc) catch (HTTPException& exc)

View File

@ -23,7 +23,6 @@
#include "Poco/Net/SecureServerSocket.h" #include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/NetException.h" #include "Poco/Net/NetException.h"
#include "Poco/Thread.h" #include "Poco/Thread.h"
#include <iostream>
using Poco::Net::HTTPSClientSession; using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest; using Poco::Net::HTTPRequest;
@ -55,13 +54,14 @@ namespace
do do
{ {
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags); n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
Poco::Thread::current()->sleep(handleDelay.totalMilliseconds());
if (n == 0) if (n == 0)
break; break;
ws.sendFrame(pBuffer.get(), n, flags); ws.sendFrame(pBuffer.get(), n, flags);
} }
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
} }
catch (WebSocketException& exc) catch (const WebSocketException& exc)
{ {
switch (exc.code()) switch (exc.code())
{ {
@ -79,10 +79,17 @@ namespace
} }
} }
public:
static Poco::Timespan handleDelay;
private: private:
std::size_t _bufSize; std::size_t _bufSize;
}; };
Poco::Timespan WebSocketRequestHandler::handleDelay {0};
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{ {
public: public:
@ -90,7 +97,7 @@ namespace
{ {
} }
Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) override
{ {
return new WebSocketRequestHandler(_bufSize); return new WebSocketRequestHandler(_bufSize);
} }
@ -111,6 +118,46 @@ WebSocketTest::~WebSocketTest()
} }
void WebSocketTest::testWebSocketTimeout()
{
Poco::Net::SecureServerSocket ss(0);
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory, ss, new Poco::Net::HTTPServerParams);
server.start();
Poco::Thread::sleep(200);
HTTPSClientSession cs("127.0.0.1", ss.address().port());
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
HTTPResponse response;
WebSocket ws(cs, request, response);
ws.setSendTimeout( Poco::Timespan(2, 0));
ws.setReceiveTimeout( Poco::Timespan(2, 0));
Poco::Timestamp sendStart;
char buffer[1024] = {};
int flags;
try
{
// Server will take long to process and cause WS timeout
WebSocketRequestHandler::handleDelay.assign(3, 0);
std::string payload("x");
ws.sendFrame(payload.data(), (int) payload.size());
ws.receiveFrame(buffer, sizeof(buffer), flags);
failmsg("Data exchange shall time out.");
}
catch (const Poco::TimeoutException& te)
{
assertTrue(sendStart.elapsed() < Poco::Timespan(4, 0).totalMicroseconds());
}
ws.shutdown();
ws.receiveFrame(buffer, sizeof(buffer), flags);
server.stop();
}
void WebSocketTest::testWebSocket() void WebSocketTest::testWebSocket()
{ {
Poco::Net::SecureServerSocket ss(0); Poco::Net::SecureServerSocket ss(0);
@ -227,6 +274,7 @@ CppUnit::Test* WebSocketTest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest"); CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket); CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketTimeout);
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge); CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
return pSuite; return pSuite;

View File

@ -22,13 +22,14 @@ class WebSocketTest: public CppUnit::TestCase
{ {
public: public:
WebSocketTest(const std::string& name); WebSocketTest(const std::string& name);
~WebSocketTest(); ~WebSocketTest() override;
void testWebSocketTimeout();
void testWebSocket(); void testWebSocket();
void testWebSocketLarge(); void testWebSocketLarge();
void setUp(); void setUp() override;
void tearDown(); void tearDown() override;
static CppUnit::Test* suite(); static CppUnit::Test* suite();

View File

@ -159,6 +159,9 @@ public:
/// If task execution takes longer than the given interval, /// If task execution takes longer than the given interval,
/// further executions are delayed. /// further executions are delayed.
bool idle() const;
/// Returns true if the task queue is empty, otherwise false.
template <typename Fn> template <typename Fn>
static TimerTask::Ptr func(const Fn& fn) static TimerTask::Ptr func(const Fn& fn)
/// Helper function template to use a functor or lambda /// Helper function template to use a functor or lambda
@ -188,6 +191,15 @@ private:
}; };
//
// inlines
//
inline bool Timer::idle() const
{
return _queue.empty();
}
} } // namespace Poco::Util } } // namespace Poco::Util

View File

@ -314,6 +314,28 @@ void TimerTest::testFunc()
} }
void TimerTest::testIdle()
{
Timer timer;
assertTrue (timer.idle());
Timestamp time;
time += 1000000;
TimerTask::Ptr pTask = new TimerTaskAdapter<TimerTest>(*this, &TimerTest::onTimer);
timer.schedule(pTask, time);
assertFalse (timer.idle());
_event.wait();
assertTrue (pTask->lastExecution() >= time);
assertTrue (timer.idle());
}
void TimerTest::setUp() void TimerTest::setUp()
{ {
} }
@ -346,6 +368,7 @@ CppUnit::Test* TimerTest::suite()
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop); CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop); CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testFunc); CppUnit_addTest(pSuite, TimerTest, testFunc);
CppUnit_addTest(pSuite, TimerTest, testIdle);
return pSuite; return pSuite;
} }

View File

@ -37,6 +37,7 @@ public:
void testCancelAllWaitStop(); void testCancelAllWaitStop();
void testMultiCancelAllWaitStop(); void testMultiCancelAllWaitStop();
void testFunc(); void testFunc();
void testIdle();
void setUp(); void setUp();
void tearDown(); void tearDown();

View File

@ -18,6 +18,7 @@
Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl> Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl>
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org> Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Licensed under the MIT license: Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
@ -1042,7 +1043,7 @@ typedef struct {
XMLPARSEAPI(const XML_Feature *) XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void); XML_GetFeatureList(void);
#if XML_GE == 1 #if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
/* Added in Expat 2.4.0 for XML_DTD defined and /* Added in Expat 2.4.0 for XML_DTD defined and
* added in Expat 2.6.0 for XML_GE == 1. */ * added in Expat 2.6.0 for XML_GE == 1. */
XMLPARSEAPI(XML_Bool) XMLPARSEAPI(XML_Bool)
@ -1065,7 +1066,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/ */
#define XML_MAJOR_VERSION 2 #define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 6 #define XML_MINOR_VERSION 6
#define XML_MICRO_VERSION 0 #define XML_MICRO_VERSION 2
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -28,10 +28,11 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Licensed under the MIT license: Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
@ -155,14 +156,20 @@ extern "C" {
void _INTERNAL_trim_to_complete_utf8_characters(const char *from, void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
const char **fromLimRef); const char **fromLimRef);
#if XML_GE == 1 #if defined(XML_GE) && XML_GE == 1
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser); unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
const char *unsignedCharToPrintable(unsigned char c); const char *unsignedCharToPrintable(unsigned char c);
#endif #endif
extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c extern
extern unsigned int g_parseAttempts; // used for testing only #if ! defined(XML_TESTING)
const
#endif
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
#if defined(XML_TESTING)
extern unsigned int g_bytesScanned; // used for testing only
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,4 +1,4 @@
/* 628e24d4966bedbd4800f6ed128d06d29703765b4bce12d3b7f099f90f842fc9 (2.6.0+) /* 2a14271ad4d35e82bde8ba210b4edb7998794bcbae54deab114046a300f9639a (2.6.2+)
__ __ _ __ __ _
___\ \/ /_ __ __ _| |_ ___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __| / _ \\ /| '_ \ / _` | __|
@ -38,7 +38,7 @@
Copyright (c) 2022 Jann Horn <jannh@google.com> Copyright (c) 2022 Jann Horn <jannh@google.com>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com> Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Copyright (c) 2023 Owain Davies <owaind@bath.edu> Copyright (c) 2023 Owain Davies <owaind@bath.edu>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license: Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
@ -217,7 +217,7 @@ typedef char ICHAR;
#endif #endif
/* Round up n to be a multiple of sz, where sz is a power of 2. */ /* Round up n to be a multiple of sz, where sz is a power of 2. */
#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
/* Do safe (NULL-aware) pointer arithmetic */ /* Do safe (NULL-aware) pointer arithmetic */
#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
@ -255,7 +255,7 @@ static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
it odd, since odd numbers are always relative prime to a power of 2. it odd, since odd numbers are always relative prime to a power of 2.
*/ */
#define SECOND_HASH(hash, mask, power) \ #define SECOND_HASH(hash, mask, power) \
((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
#define PROBE_STEP(hash, mask, power) \ #define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
@ -636,8 +636,14 @@ static unsigned long getDebugLevel(const char *variableName,
? 0 \ ? 0 \
: ((*((pool)->ptr)++ = c), 1)) : ((*((pool)->ptr)++ = c), 1))
XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c #if ! defined(XML_TESTING)
unsigned int g_parseAttempts = 0; // used for testing only const
#endif
XML_Bool g_reparseDeferralEnabledDefault
= XML_TRUE; // write ONLY in runtests.c
#if defined(XML_TESTING)
unsigned int g_bytesScanned = 0; // used for testing only
#endif
struct XML_ParserStruct { struct XML_ParserStruct {
/* The first member must be m_userData so that the XML_GetUserData /* The first member must be m_userData so that the XML_GetUserData
@ -1035,7 +1041,9 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
return XML_ERROR_NONE; return XML_ERROR_NONE;
} }
} }
g_parseAttempts += 1; #if defined(XML_TESTING)
g_bytesScanned += (unsigned)have_now;
#endif
const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
if (ret == XML_ERROR_NONE) { if (ret == XML_ERROR_NONE) {
// if we consumed nothing, remember what we had on this parse attempt. // if we consumed nothing, remember what we had on this parse attempt.
@ -6250,7 +6258,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
dtd->keepProcessing = dtd->standalone; dtd->keepProcessing = dtd->standalone;
goto endEntityValue; goto endEntityValue;
} }
if (entity->open) { if (entity->open || (entity == parser->m_declEntity)) {
if (enc == parser->m_encoding) if (enc == parser->m_encoding)
parser->m_eventPtr = entityTextPtr; parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_RECURSIVE_ENTITY_REF; result = XML_ERROR_RECURSIVE_ENTITY_REF;
@ -7797,6 +7805,8 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
static float static float
accountingGetCurrentAmplification(XML_Parser rootParser) { accountingGetCurrentAmplification(XML_Parser rootParser) {
// 1.........1.........12 => 22
const size_t lenOfShortestInclude = sizeof("<!ENTITY a SYSTEM 'b'>") - 1;
const XmlBigCount countBytesOutput const XmlBigCount countBytesOutput
= rootParser->m_accounting.countBytesDirect = rootParser->m_accounting.countBytesDirect
+ rootParser->m_accounting.countBytesIndirect; + rootParser->m_accounting.countBytesIndirect;
@ -7804,7 +7814,9 @@ accountingGetCurrentAmplification(XML_Parser rootParser) {
= rootParser->m_accounting.countBytesDirect = rootParser->m_accounting.countBytesDirect
? (countBytesOutput ? (countBytesOutput
/ (float)(rootParser->m_accounting.countBytesDirect)) / (float)(rootParser->m_accounting.countBytesDirect))
: 1.0f; : ((lenOfShortestInclude
+ rootParser->m_accounting.countBytesIndirect)
/ (float)lenOfShortestInclude);
assert(! rootParser->m_parentParser); assert(! rootParser->m_parentParser);
return amplificationFactor; return amplificationFactor;
} }