mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
Merge branch 'devel' into 2208-merge-dnssd
This commit is contained in:
commit
056deb3834
6
.github/actions/retry-action/action.yml
vendored
6
.github/actions/retry-action/action.yml
vendored
@ -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"
|
||||
|
2
.github/actions/retry-action/package.json
vendored
2
.github/actions/retry-action/package.json
vendored
@ -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",
|
||||
|
353
.github/workflows/ci.yml
vendored
353
.github/workflows/ci.yml
vendored
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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()
|
||||
{
|
||||
|
@ -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)? "
|
||||
|
@ -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()),
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
void testCancelAllWaitStop();
|
||||
void testMultiCancelAllWaitStop();
|
||||
void testFunc();
|
||||
void testIdle();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user