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

View File

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

View File

@ -15,29 +15,29 @@ concurrency:
jobs:
android-arm64-v8a-ndk-latest-cmake:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: nttld/setup-ndk@v1
with:
ndk-version: r25c
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
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
with:
ndk-version: r25c
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
android-arm64-v8a-ndk-cmake:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: nttld/setup-ndk@v1
with:
ndk-version: r25c
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
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
with:
ndk-version: r25c
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
android-armeabi-v7a-ndk-cmake:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
with:
ndk-version: r25c
@ -47,14 +47,14 @@ jobs:
linux-gcc-make-armv7l:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
linux-gcc-make:
runs-on: ubuntu-22.04
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: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action
@ -70,7 +70,7 @@ jobs:
linux-gcc-make-cxx20:
runs-on: ubuntu-22.04
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: ./configure --config=Linux-c++20 --everything --omit=PDF && make all -s -j4 && sudo make install
- uses: ./.github/actions/retry-action
@ -86,7 +86,15 @@ jobs:
linux-gcc-make-asan:
runs-on: ubuntu-22.04
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: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
- uses: ./.github/actions/retry-action
@ -102,7 +110,15 @@ jobs:
linux-gcc-make-asan-no-soo:
runs-on: ubuntu-22.04
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: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
- uses: ./.github/actions/retry-action
@ -118,7 +134,7 @@ jobs:
linux-gcc-make-ubsan:
runs-on: ubuntu-22.04
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: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install
- uses: ./.github/actions/retry-action
@ -134,7 +150,15 @@ jobs:
linux-gcc-make-tsan:
runs-on: ubuntu-22.04
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: ./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
@ -143,13 +167,12 @@ jobs:
max_attempts: 3
retry_on: any
command: >-
sudo -s
./ci/runtests.sh TSAN
sudo -s ./ci/runtests.sh TSAN
linux-gcc-cmake:
runs-on: ubuntu-22.04
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: cmake -S. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all
- uses: ./.github/actions/retry-action
@ -166,25 +189,25 @@ jobs:
linux-emscripten-cmake:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
# TODO: How to run unit tests in emscripten?
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build &&
# sudo -s
# PWD=`pwd`
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)"
# TODO: How to run unit tests in emscripten?
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build &&
# sudo -s
# PWD=`pwd`
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)"
linux-gcc-make-cross-armhf:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: >-
sudo apt-get -y update &&
sudo apt-get -y install crossbuild-essential-armhf
@ -200,7 +223,7 @@ jobs:
macos-clang-make:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: brew install openssl@1.1 mysql-client unixodbc libpq
- run: >-
./configure --everything --no-prefix --omit=PDF
@ -228,9 +251,10 @@ jobs:
./ci/runtests.sh
macos-clang-make-visibility-hidden:
# macos-12 runs on Intel CPU
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: brew install openssl@1.1 mysql-client unixodbc libpq
- run: >-
./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF
@ -258,9 +282,10 @@ jobs:
./ci/runtests.sh
macos-clang-cmake-openssl:
runs-on: macos-12
# macos-14 runs on Apple Silicon
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
- uses: ./.github/actions/retry-action
@ -283,9 +308,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-cmake-openssl3:
runs-on: macos-12
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
- uses: ./.github/actions/retry-action
@ -308,9 +333,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-cmake-openssl3-visibility-hidden:
runs-on: macos-12
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
- uses: ./.github/actions/retry-action
@ -333,9 +358,9 @@ jobs:
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
macos-clang-make-openssl3-tsan:
runs-on: macos-12
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: brew install openssl@3
- run: >-
./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:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq
- run: >-
./configure --everything --no-prefix --no-samples --omit=PDF
@ -395,7 +420,7 @@ jobs:
macos-clang-make-openssl3-asan:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: brew install openssl@3 mysql-client unixodbc libpq
- run: >-
./configure --everything --no-prefix --no-samples --omit=PDF
@ -422,63 +447,63 @@ jobs:
EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF"
./ci/runtests.sh
# windows-2019-msvc-cmake:
# runs-on: windows-2019
# 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,
# class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer
# steps:
# - uses: actions/checkout@v3
# - 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
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
# windows-2019-msvc-cmake:
# runs-on: windows-2019
# 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,
# class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer
# steps:
# - 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 --build cmake-build --config Release
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
# windows-2019-msvc-buildwin-x64:
# runs-on: windows-2019
# 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
# steps:
# - uses: actions/checkout@v3
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
# windows-2019-msvc-buildwin-x64:
# runs-on: windows-2019
# 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
# steps:
# - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
# windows-2019-msvc-buildwin-win32:
# runs-on: windows-2019
# 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
# steps:
# - uses: actions/checkout@v3
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
# windows-2019-msvc-buildwin-win32:
# runs-on: windows-2019
# 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
# steps:
# - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
windows-2022-msvc-buildwin-x64:
runs-on: windows-2022
@ -492,7 +517,7 @@ jobs:
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ./.github/actions/retry-action
with:
timeout_minutes: 90
@ -500,25 +525,25 @@ jobs:
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"
# windows-2022-msvc-buildwin-win32:
# runs-on: windows-2022
# 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
# steps:
# - uses: actions/checkout@v3
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
# windows-2022-msvc-buildwin-win32:
# runs-on: windows-2022
# 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
# steps:
# - uses: actions/checkout@v4
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# 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"
windows-2022-msvc-cmake:
runs-on: windows-2022
@ -532,8 +557,8 @@ jobs:
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
steps:
- uses: actions/checkout@v3
- 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
- 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 --build cmake-build --config Release
- uses: ./.github/actions/retry-action
with:
@ -544,30 +569,30 @@ jobs:
cd cmake-build;
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
# missing asan dll path
# windows-2022-msvc-cmake-asan:
# runs-on: windows-2022
# 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
# steps:
# - uses: actions/checkout@v3
# - 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
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug
# missing asan dll path
# windows-2022-msvc-cmake-asan:
# runs-on: windows-2022
# 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
# steps:
# - 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 --build cmake-build --config Debug
# - uses: ./.github/actions/retry-action
# with:
# timeout_minutes: 90
# max_attempts: 3
# retry_on: any
# command: >-
# cd cmake-build;
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug
linux-gcc-make-mysql:
runs-on: ubuntu-22.04
@ -582,7 +607,7 @@ jobs:
ports:
- 3306:3306
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: ./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
@ -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"
./ci/runtests.sh
# TODO tests sometimes failing on testTransaction and testReconnect
# TODO tests sometimes failing on testTransaction and testReconnect
linux-gcc-make-postgres:
runs-on: ubuntu-22.04
services:
@ -606,7 +631,7 @@ jobs:
ports:
- 5432:5432
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: ./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
@ -622,7 +647,7 @@ jobs:
linux-gcc-make-redis:
runs-on: ubuntu-22.04
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: |
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:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: supercharge/mongodb-github-action@1.10.0
- 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
@ -690,7 +715,7 @@ jobs:
ports:
- 1433:1433
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: ./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
@ -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"
- name: Setup SQL Server ODBC connector
run: |
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
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
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
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
- uses: ./.github/actions/retry-action
with:
timeout_minutes: 90
@ -739,7 +764,7 @@ jobs:
ports:
- 3306:3306
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- 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
- uses: ./.github/actions/retry-action

View File

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

View File

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

View File

@ -72,6 +72,9 @@ public:
Poco::UInt64 size() const;
/// Returns file size
void flushToDisk();
/// Forces buffered data to be written to the disk
protected:
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);
/// Change to specified position, according to mode.
void flushToDisk();
/// Forces buffered data to be written to the disk
NativeHandle nativeHandle() const;
/// 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);
/// change to specified position, according to mode
void flushToDisk();
/// Forces buffered data to be written to the disk
NativeHandle nativeHandle() const;
/// Returns native file descriptor handle

View File

@ -17,21 +17,14 @@
#ifndef Foundation_LogFile_INCLUDED
#define Foundation_LogFile_INCLUDED
#include "Poco/Foundation.h"
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "Poco/LogFile_WIN32U.h"
#else
#include "Poco/LogFile_STD.h"
#endif
#include "Poco/Timestamp.h"
#include "Poco/FileStream.h"
namespace Poco {
class Foundation_API LogFile: public LogFileImpl
class Foundation_API LogFile
/// This class is used by FileChannel to work
/// with a log file.
{
@ -55,36 +48,15 @@ public:
const std::string& path() const;
/// 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

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;
}
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()
{

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_REGEX(
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sun)), *)?"
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sunday)), *)?"
"\\d\\d? +"
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
"\\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():
_times("utc"),
_compress(false),
_flush(true),
_flush(false),
_rotateOnOpen(false),
_pFile(nullptr),
_pRotateStrategy(new NullRotateStrategy()),
@ -56,7 +56,7 @@ FileChannel::FileChannel(const std::string& path):
_path(path),
_times("utc"),
_compress(false),
_flush(true),
_flush(false),
_rotateOnOpen(false),
_pFile(nullptr),
_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();
}
void FileIOS::flushToDisk()
{
_buf.flushToDisk();
}
FileInputStream::FileInputStream():
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
{
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
{
return _handle;

View File

@ -13,20 +13,34 @@
#include "Poco/LogFile.h"
#if defined(POCO_OS_FAMILY_WINDOWS)
#include "LogFile_WIN32U.cpp"
#else
#include "LogFile_STD.cpp"
#endif
#include "Poco/File.h"
#include "Poco/Exception.h"
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

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;
_host = host;
toLowerInPlace(_host);
if (_host.size() && _host[0] != '%')
toLowerInPlace(_host);
}

View File

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

View File

@ -798,6 +798,15 @@ void URITest::testOther()
assertTrue (uri.getRawFragment() == "foo%2Fbar");
assertTrue (uri.toString() == "http://google.com/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
/// 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);
/// Bind a local address to the socket.
@ -143,7 +143,7 @@ public:
/// If reusePort is true, sets the SO_REUSEPORT
/// 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);
/// Bind a local address to the socket.
@ -160,7 +160,7 @@ public:
/// Sets the IPV6_V6ONLY socket option in accordance with
/// 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);
/// Sends the contents of the given buffer through

View File

@ -216,7 +216,7 @@ public:
/// as the system is free to adjust the value.
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
/// workaround using poll() is provided.

View File

@ -147,7 +147,7 @@ SocketImpl* SocketImpl::acceptConnection(SocketAddress& clientAddr)
return new StreamSocketImpl(sd);
}
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_iov = const_cast<iovec*>(&buffers[0]);
msgHdr.msg_iovlen = buffers.size();
msgHdr.msg_control = 0;
msgHdr.msg_control = nullptr;
msgHdr.msg_controllen = 0;
msgHdr.msg_flags = 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_iov = &buffers[0];
msgHdr.msg_iovlen = buffers.size();
msgHdr.msg_control = 0;
msgHdr.msg_control = nullptr;
msgHdr.msg_controllen = 0;
msgHdr.msg_flags = flags;
rc = recvmsg(_sockfd, &msgHdr, flags);
@ -652,7 +652,7 @@ int SocketImpl::available()
if (result && (type() == SOCKET_TYPE_DATAGRAM))
{
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
return result;
@ -1114,7 +1114,7 @@ void SocketImpl::setReusePort(bool flag)
int value = flag ? 1 : 0;
setOption(SOL_SOCKET, SO_REUSEPORT, value);
}
catch (IOException&)
catch (const IOException&)
{
// ignore error, since not all implementations
// support SO_REUSEPORT, even if the macro

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,6 @@
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Thread.h"
#include <iostream>
using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest;
@ -55,13 +54,14 @@ namespace
do
{
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
Poco::Thread::current()->sleep(handleDelay.totalMilliseconds());
if (n == 0)
break;
ws.sendFrame(pBuffer.get(), n, flags);
}
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
}
catch (WebSocketException& exc)
catch (const WebSocketException& exc)
{
switch (exc.code())
{
@ -79,10 +79,17 @@ namespace
}
}
public:
static Poco::Timespan handleDelay;
private:
std::size_t _bufSize;
};
Poco::Timespan WebSocketRequestHandler::handleDelay {0};
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
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);
}
@ -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()
{
Poco::Net::SecureServerSocket ss(0);
@ -227,6 +274,7 @@ CppUnit::Test* WebSocketTest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketTimeout);
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
return pSuite;

View File

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

View File

@ -159,6 +159,9 @@ public:
/// If task execution takes longer than the given interval,
/// further executions are delayed.
bool idle() const;
/// Returns true if the task queue is empty, otherwise false.
template <typename Fn>
static TimerTask::Ptr func(const Fn& fn)
/// 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

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()
{
}
@ -346,6 +368,7 @@ CppUnit::Test* TimerTest::suite()
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testFunc);
CppUnit_addTest(pSuite, TimerTest, testIdle);
return pSuite;
}

View File

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

View File

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

View File

@ -28,10 +28,11 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.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) 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:
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,
const char **fromLimRef);
#if XML_GE == 1
#if defined(XML_GE) && XML_GE == 1
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
const char *unsignedCharToPrintable(unsigned char c);
#endif
extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
extern unsigned int g_parseAttempts; // used for testing only
extern
#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
}

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 Sean McBride <sean@rogue-research.com>
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:
Permission is hereby granted, free of charge, to any person obtaining
@ -217,7 +217,7 @@ typedef char ICHAR;
#endif
/* 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 */
#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.
*/
#define SECOND_HASH(hash, mask, power) \
((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
@ -636,8 +636,14 @@ static unsigned long getDebugLevel(const char *variableName,
? 0 \
: ((*((pool)->ptr)++ = c), 1))
XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c
unsigned int g_parseAttempts = 0; // used for testing only
#if ! defined(XML_TESTING)
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 {
/* 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;
}
}
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);
if (ret == XML_ERROR_NONE) {
// 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;
goto endEntityValue;
}
if (entity->open) {
if (entity->open || (entity == parser->m_declEntity)) {
if (enc == parser->m_encoding)
parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_RECURSIVE_ENTITY_REF;
@ -7797,6 +7805,8 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
static float
accountingGetCurrentAmplification(XML_Parser rootParser) {
// 1.........1.........12 => 22
const size_t lenOfShortestInclude = sizeof("<!ENTITY a SYSTEM 'b'>") - 1;
const XmlBigCount countBytesOutput
= rootParser->m_accounting.countBytesDirect
+ rootParser->m_accounting.countBytesIndirect;
@ -7804,7 +7814,9 @@ accountingGetCurrentAmplification(XML_Parser rootParser) {
= rootParser->m_accounting.countBytesDirect
? (countBytesOutput
/ (float)(rootParser->m_accounting.countBytesDirect))
: 1.0f;
: ((lenOfShortestInclude
+ rootParser->m_accounting.countBytesIndirect)
/ (float)lenOfShortestInclude);
assert(! rootParser->m_parentParser);
return amplificationFactor;
}