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
|
name: Retry Step
|
||||||
description: 'Retry a step on failure or timeout'
|
description: "Retry a step on failure or timeout"
|
||||||
inputs:
|
inputs:
|
||||||
timeout_minutes:
|
timeout_minutes:
|
||||||
description: Minutes to wait before attempt times out. Must only specify either minutes or seconds
|
description: Minutes to wait before attempt times out. Must only specify either minutes or seconds
|
||||||
@ -50,5 +50,5 @@ outputs:
|
|||||||
exit_error:
|
exit_error:
|
||||||
description: The final error returned by the command
|
description: The final error returned by the command
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: "node20"
|
||||||
main: 'dist/index.js'
|
main: "dist/index.js"
|
||||||
|
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/babel-generator": "^6.25.7",
|
||||||
"@types/jest": "^28.1.6",
|
"@types/jest": "^28.1.6",
|
||||||
"@types/milliseconds": "0.0.30",
|
"@types/milliseconds": "0.0.30",
|
||||||
"@types/node": "^16.11.7",
|
"@types/node": "^20.11.24",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.32.0",
|
"@typescript-eslint/eslint-plugin": "^5.32.0",
|
||||||
"@typescript-eslint/parser": "^5.32.0",
|
"@typescript-eslint/parser": "^5.32.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
|
353
.github/workflows/ci.yml
vendored
353
.github/workflows/ci.yml
vendored
@ -15,29 +15,29 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
android-arm64-v8a-ndk-latest-cmake:
|
android-arm64-v8a-ndk-latest-cmake:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: nttld/setup-ndk@v1
|
- uses: nttld/setup-ndk@v1
|
||||||
with:
|
with:
|
||||||
ndk-version: r25c
|
ndk-version: r25c
|
||||||
add-to-path: true
|
add-to-path: true
|
||||||
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
|
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
|
||||||
|
|
||||||
android-arm64-v8a-ndk-cmake:
|
android-arm64-v8a-ndk-cmake:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: nttld/setup-ndk@v1
|
- uses: nttld/setup-ndk@v1
|
||||||
with:
|
with:
|
||||||
ndk-version: r25c
|
ndk-version: r25c
|
||||||
add-to-path: true
|
add-to-path: true
|
||||||
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
|
- run: cmake -S$GITHUB_WORKSPACE -B$HOME/android-build -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake && cmake --build $HOME/android-build --target all
|
||||||
|
|
||||||
android-armeabi-v7a-ndk-cmake:
|
android-armeabi-v7a-ndk-cmake:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: nttld/setup-ndk@v1
|
- uses: nttld/setup-ndk@v1
|
||||||
with:
|
with:
|
||||||
ndk-version: r25c
|
ndk-version: r25c
|
||||||
@ -47,14 +47,14 @@ jobs:
|
|||||||
linux-gcc-make-armv7l:
|
linux-gcc-make-armv7l:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install g++-arm-linux-gnueabihf
|
- run: sudo apt -y update && sudo apt -y install g++-arm-linux-gnueabihf
|
||||||
- run: ./configure --config=X-Linux-gcc-arm --everything --omit=ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/ODBC,JWT,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,SevenZip && make all -s -j4
|
- run: ./configure --config=X-Linux-gcc-arm --everything --omit=ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/ODBC,JWT,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,SevenZip && make all -s -j4
|
||||||
|
|
||||||
linux-gcc-make:
|
linux-gcc-make:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
|
||||||
- run: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install
|
- run: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -70,7 +70,7 @@ jobs:
|
|||||||
linux-gcc-make-cxx20:
|
linux-gcc-make-cxx20:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev
|
||||||
- run: ./configure --config=Linux-c++20 --everything --omit=PDF && make all -s -j4 && sudo make install
|
- run: ./configure --config=Linux-c++20 --everything --omit=PDF && make all -s -j4 && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -86,7 +86,15 @@ jobs:
|
|||||||
linux-gcc-make-asan:
|
linux-gcc-make-asan:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
|
||||||
|
# causes sanitizer to fail.
|
||||||
|
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
|
||||||
|
# (https://github.com/google/sanitizers/issues/1716)
|
||||||
|
- run: sysctl vm.legacy_va_layout
|
||||||
|
- run: sysctl kernel.randomize_va_space
|
||||||
|
- run: sudo sysctl vm.mmap_rnd_bits
|
||||||
|
- run: sudo sysctl -w vm.mmap_rnd_bits=28
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
||||||
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
|
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -102,7 +110,15 @@ jobs:
|
|||||||
linux-gcc-make-asan-no-soo:
|
linux-gcc-make-asan-no-soo:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
|
||||||
|
# causes sanitizer to fail.
|
||||||
|
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
|
||||||
|
# (https://github.com/google/sanitizers/issues/1716)
|
||||||
|
- run: sysctl vm.legacy_va_layout
|
||||||
|
- run: sysctl kernel.randomize_va_space
|
||||||
|
- run: sudo sysctl vm.mmap_rnd_bits
|
||||||
|
- run: sudo sysctl -w vm.mmap_rnd_bits=28
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
||||||
- run: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
|
- run: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -118,7 +134,7 @@ jobs:
|
|||||||
linux-gcc-make-ubsan:
|
linux-gcc-make-ubsan:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
||||||
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install
|
- run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -134,7 +150,15 @@ jobs:
|
|||||||
linux-gcc-make-tsan:
|
linux-gcc-make-tsan:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
# ASLR (https://en.wikipedia.org/wiki/Address_space_layout_randomization)
|
||||||
|
# causes sanitizer to fail.
|
||||||
|
# vm.mmap_rnd_bits needs to be set to 28 to make it work.
|
||||||
|
# (https://github.com/google/sanitizers/issues/1716)
|
||||||
|
- run: sysctl vm.legacy_va_layout
|
||||||
|
- run: sysctl kernel.randomize_va_space
|
||||||
|
- run: sudo sysctl vm.mmap_rnd_bits
|
||||||
|
- run: sudo sysctl -w vm.mmap_rnd_bits=28
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
||||||
- run: ./configure --everything --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip && make all -s -j4 SANITIZEFLAGS=-fsanitize=thread && sudo make install
|
- run: ./configure --everything --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip && make all -s -j4 SANITIZEFLAGS=-fsanitize=thread && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -143,13 +167,12 @@ jobs:
|
|||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
retry_on: any
|
retry_on: any
|
||||||
command: >-
|
command: >-
|
||||||
sudo -s
|
sudo -s ./ci/runtests.sh TSAN
|
||||||
./ci/runtests.sh TSAN
|
|
||||||
|
|
||||||
linux-gcc-cmake:
|
linux-gcc-cmake:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
- run: sudo apt -y update && sudo apt -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server
|
||||||
- run: cmake -S. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all
|
- run: cmake -S. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -166,25 +189,25 @@ jobs:
|
|||||||
linux-emscripten-cmake:
|
linux-emscripten-cmake:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install cmake ninja-build emscripten
|
- run: sudo apt -y update && sudo apt -y install cmake ninja-build emscripten
|
||||||
- run: emcmake cmake -H. -B cmake-build -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=off && emmake cmake --build cmake-build --target all -j4
|
- run: emcmake cmake -H. -B cmake-build -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=off && emmake cmake --build cmake-build --target all -j4
|
||||||
# TODO: How to run unit tests in emscripten?
|
# TODO: How to run unit tests in emscripten?
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: >-
|
# command: >-
|
||||||
# cd cmake-build &&
|
# cd cmake-build &&
|
||||||
# sudo -s
|
# sudo -s
|
||||||
# PWD=`pwd`
|
# PWD=`pwd`
|
||||||
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)"
|
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)"
|
||||||
|
|
||||||
linux-gcc-make-cross-armhf:
|
linux-gcc-make-cross-armhf:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: >-
|
- run: >-
|
||||||
sudo apt-get -y update &&
|
sudo apt-get -y update &&
|
||||||
sudo apt-get -y install crossbuild-essential-armhf
|
sudo apt-get -y install crossbuild-essential-armhf
|
||||||
@ -200,7 +223,7 @@ jobs:
|
|||||||
macos-clang-make:
|
macos-clang-make:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
||||||
- run: >-
|
- run: >-
|
||||||
./configure --everything --no-prefix --omit=PDF
|
./configure --everything --no-prefix --omit=PDF
|
||||||
@ -228,9 +251,10 @@ jobs:
|
|||||||
./ci/runtests.sh
|
./ci/runtests.sh
|
||||||
|
|
||||||
macos-clang-make-visibility-hidden:
|
macos-clang-make-visibility-hidden:
|
||||||
|
# macos-12 runs on Intel CPU
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
||||||
- run: >-
|
- run: >-
|
||||||
./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF
|
./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF
|
||||||
@ -258,9 +282,10 @@ jobs:
|
|||||||
./ci/runtests.sh
|
./ci/runtests.sh
|
||||||
|
|
||||||
macos-clang-cmake-openssl:
|
macos-clang-cmake-openssl:
|
||||||
runs-on: macos-12
|
# macos-14 runs on Apple Silicon
|
||||||
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
- run: brew install openssl@1.1 mysql-client unixodbc libpq
|
||||||
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -283,9 +308,9 @@ jobs:
|
|||||||
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
||||||
|
|
||||||
macos-clang-cmake-openssl3:
|
macos-clang-cmake-openssl3:
|
||||||
runs-on: macos-12
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@3 mysql-client unixodbc libpq
|
- run: brew install openssl@3 mysql-client unixodbc libpq
|
||||||
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
- run: cmake -S. -Bcmake-build -DENABLE_PDF=OFF -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -308,9 +333,9 @@ jobs:
|
|||||||
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
||||||
|
|
||||||
macos-clang-cmake-openssl3-visibility-hidden:
|
macos-clang-cmake-openssl3-visibility-hidden:
|
||||||
runs-on: macos-12
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@3 mysql-client unixodbc libpq
|
- run: brew install openssl@3 mysql-client unixodbc libpq
|
||||||
- run: cmake -S. -Bcmake-build -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DENABLE_ENCODINGS_COMPILER=ON -DENABLE_PDF=ON -DENABLE_SEVENZIP=ON -DENABLE_CPPPARSER=ON -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
- run: cmake -S. -Bcmake-build -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DENABLE_ENCODINGS_COMPILER=ON -DENABLE_PDF=ON -DENABLE_SEVENZIP=ON -DENABLE_CPPPARSER=ON -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -333,9 +358,9 @@ jobs:
|
|||||||
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)"
|
||||||
|
|
||||||
macos-clang-make-openssl3-tsan:
|
macos-clang-make-openssl3-tsan:
|
||||||
runs-on: macos-12
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@3
|
- run: brew install openssl@3
|
||||||
- run: >-
|
- run: >-
|
||||||
./configure --everything --no-prefix --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip
|
./configure --everything --no-prefix --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip
|
||||||
@ -365,7 +390,7 @@ jobs:
|
|||||||
macos-clang-make-openssl3-ubsan:
|
macos-clang-make-openssl3-ubsan:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@3 mysql-client unixodbc libpq
|
- run: brew install openssl@3 mysql-client unixodbc libpq
|
||||||
- run: >-
|
- run: >-
|
||||||
./configure --everything --no-prefix --no-samples --omit=PDF
|
./configure --everything --no-prefix --no-samples --omit=PDF
|
||||||
@ -395,7 +420,7 @@ jobs:
|
|||||||
macos-clang-make-openssl3-asan:
|
macos-clang-make-openssl3-asan:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: brew install openssl@3 mysql-client unixodbc libpq
|
- run: brew install openssl@3 mysql-client unixodbc libpq
|
||||||
- run: >-
|
- run: >-
|
||||||
./configure --everything --no-prefix --no-samples --omit=PDF
|
./configure --everything --no-prefix --no-samples --omit=PDF
|
||||||
@ -422,63 +447,63 @@ jobs:
|
|||||||
EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF"
|
EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF"
|
||||||
./ci/runtests.sh
|
./ci/runtests.sh
|
||||||
|
|
||||||
# windows-2019-msvc-cmake:
|
# windows-2019-msvc-cmake:
|
||||||
# runs-on: windows-2019
|
# runs-on: windows-2019
|
||||||
# env:
|
# env:
|
||||||
# CPPUNIT_IGNORE: >-
|
# CPPUNIT_IGNORE: >-
|
||||||
# class CppUnit::TestCaller<class PathTest>.testFind,
|
# class CppUnit::TestCaller<class PathTest>.testFind,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
||||||
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy,
|
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy,
|
||||||
# class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer
|
# class CppUnit::TestCaller<class PollSetTest>.testPollClosedServer
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
# - run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
|
# - run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
|
||||||
# - run: cmake --build cmake-build --config Release
|
# - run: cmake --build cmake-build --config Release
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: >-
|
# command: >-
|
||||||
# cd cmake-build;
|
# cd cmake-build;
|
||||||
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
|
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
|
||||||
|
|
||||||
# windows-2019-msvc-buildwin-x64:
|
# windows-2019-msvc-buildwin-x64:
|
||||||
# runs-on: windows-2019
|
# runs-on: windows-2019
|
||||||
# env:
|
# env:
|
||||||
# CPPUNIT_IGNORE: >-
|
# CPPUNIT_IGNORE: >-
|
||||||
# class CppUnit::TestCaller<class PathTest>.testFind,
|
# class CppUnit::TestCaller<class PathTest>.testFind,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
||||||
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
||||||
|
|
||||||
# windows-2019-msvc-buildwin-win32:
|
# windows-2019-msvc-buildwin-win32:
|
||||||
# runs-on: windows-2019
|
# runs-on: windows-2019
|
||||||
# env:
|
# env:
|
||||||
# CPPUNIT_IGNORE: class CppUnit::TestCaller<class PathTest>.testFind,class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,class CppUnit::TestCaller<class ICMPClientTest>.testPing,class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
# CPPUNIT_IGNORE: class CppUnit::TestCaller<class PathTest>.testFind,class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,class CppUnit::TestCaller<class ICMPClientTest>.testPing,class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
# command: .\buildwin.ps1 -poco_base . -vs 160 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
||||||
|
|
||||||
windows-2022-msvc-buildwin-x64:
|
windows-2022-msvc-buildwin-x64:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
@ -492,7 +517,7 @@ jobs:
|
|||||||
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 90
|
timeout_minutes: 90
|
||||||
@ -500,25 +525,25 @@ jobs:
|
|||||||
retry_on: any
|
retry_on: any
|
||||||
command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
||||||
|
|
||||||
# windows-2022-msvc-buildwin-win32:
|
# windows-2022-msvc-buildwin-win32:
|
||||||
# runs-on: windows-2022
|
# runs-on: windows-2022
|
||||||
# env:
|
# env:
|
||||||
# CPPUNIT_IGNORE: >-
|
# CPPUNIT_IGNORE: >-
|
||||||
# class CppUnit::TestCaller<class PathTest>.testFind,
|
# class CppUnit::TestCaller<class PathTest>.testFind,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
||||||
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
# command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform Win32 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT"
|
||||||
|
|
||||||
windows-2022-msvc-cmake:
|
windows-2022-msvc-cmake:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
@ -532,8 +557,8 @@ jobs:
|
|||||||
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_DNSSD=OFF -DENABLE_TESTS=ON
|
- run: cmake -S. -Bcmake-build -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
|
||||||
- run: cmake --build cmake-build --config Release
|
- run: cmake --build cmake-build --config Release
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
with:
|
with:
|
||||||
@ -544,30 +569,30 @@ jobs:
|
|||||||
cd cmake-build;
|
cd cmake-build;
|
||||||
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
|
ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release
|
||||||
|
|
||||||
# missing asan dll path
|
# missing asan dll path
|
||||||
# windows-2022-msvc-cmake-asan:
|
# windows-2022-msvc-cmake-asan:
|
||||||
# runs-on: windows-2022
|
# runs-on: windows-2022
|
||||||
# env:
|
# env:
|
||||||
# CPPUNIT_IGNORE: >-
|
# CPPUNIT_IGNORE: >-
|
||||||
# class CppUnit::TestCaller<class PathTest>.testFind,
|
# class CppUnit::TestCaller<class PathTest>.testFind,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testSendToReceiveFrom,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testPing,
|
||||||
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
# class CppUnit::TestCaller<class ICMPClientTest>.testBigPing,
|
||||||
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
# class CppUnit::TestCaller<class ICMPSocketTest>.testMTU,
|
||||||
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
# class CppUnit::TestCaller<class HTTPSClientSessionTest>.testProxy,
|
||||||
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
# class CppUnit::TestCaller<class HTTPSStreamFactoryTest>.testProxy
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
# - run: cmake -S. -Bcmake-build -DPOCO_SANITIZE_ASAN=ON -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
|
# - run: cmake -S. -Bcmake-build -DPOCO_SANITIZE_ASAN=ON -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON
|
||||||
# - run: cmake --build cmake-build --config Debug
|
# - run: cmake --build cmake-build --config Debug
|
||||||
# - uses: ./.github/actions/retry-action
|
# - uses: ./.github/actions/retry-action
|
||||||
# with:
|
# with:
|
||||||
# timeout_minutes: 90
|
# timeout_minutes: 90
|
||||||
# max_attempts: 3
|
# max_attempts: 3
|
||||||
# retry_on: any
|
# retry_on: any
|
||||||
# command: >-
|
# command: >-
|
||||||
# cd cmake-build;
|
# cd cmake-build;
|
||||||
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug
|
# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug
|
||||||
|
|
||||||
linux-gcc-make-mysql:
|
linux-gcc-make-mysql:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
@ -582,7 +607,7 @@ jobs:
|
|||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev mysql-client
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev mysql-client
|
||||||
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/SQLite,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/SQLite,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -595,7 +620,7 @@ jobs:
|
|||||||
EXCLUDE_TESTS="ActiveRecord ApacheConnector CppParser CppUnit Crypto Data Data/PostgreSQL Data/ODBC Data/SQLite Encodings Foundation JSON JWT MongoDB Net NetSSL_OpenSSL NetSSL_Win PDF PageCompiler PocoDoc ProGen Prometheus Redis SevenZip Util XML Zip"
|
EXCLUDE_TESTS="ActiveRecord ApacheConnector CppParser CppUnit Crypto Data Data/PostgreSQL Data/ODBC Data/SQLite Encodings Foundation JSON JWT MongoDB Net NetSSL_OpenSSL NetSSL_Win PDF PageCompiler PocoDoc ProGen Prometheus Redis SevenZip Util XML Zip"
|
||||||
./ci/runtests.sh
|
./ci/runtests.sh
|
||||||
|
|
||||||
# TODO tests sometimes failing on testTransaction and testReconnect
|
# TODO tests sometimes failing on testTransaction and testReconnect
|
||||||
linux-gcc-make-postgres:
|
linux-gcc-make-postgres:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
services:
|
services:
|
||||||
@ -606,7 +631,7 @@ jobs:
|
|||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev odbc-postgresql
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev odbc-postgresql
|
||||||
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/ODBC,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/ODBC,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
@ -622,7 +647,7 @@ jobs:
|
|||||||
linux-gcc-make-redis:
|
linux-gcc-make-redis:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
|
||||||
- run: |
|
- run: |
|
||||||
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
|
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
|
||||||
@ -643,7 +668,7 @@ jobs:
|
|||||||
linux-gcc-make-mongodb:
|
linux-gcc-make-mongodb:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: supercharge/mongodb-github-action@1.10.0
|
- uses: supercharge/mongodb-github-action@1.10.0
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev
|
||||||
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/ODBC,Data/MySQL,Data/SQLite,Data/PostgreSQL,Encodings,JSON,JWT,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/ODBC,Data/MySQL,Data/SQLite,Data/PostgreSQL,Encodings,JSON,JWT,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
||||||
@ -690,7 +715,7 @@ jobs:
|
|||||||
ports:
|
ports:
|
||||||
- 1433:1433
|
- 1433:1433
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev alien libaio1 gnupg2 curl # libmysqlclient-dev mysql-client odbc-postgresql
|
- run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev alien libaio1 gnupg2 curl # libmysqlclient-dev mysql-client odbc-postgresql
|
||||||
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
- run: ./configure --everything --no-samples --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/MySQL,Data/PostgreSQL,Data/SQLite,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
||||||
# - name: Setup MySQL ODBC connector
|
# - name: Setup MySQL ODBC connector
|
||||||
@ -712,10 +737,10 @@ jobs:
|
|||||||
# sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / "/usr/lib/oracle/21/client64/lib" "" "" "/etc/odbc.ini"
|
# sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / "/usr/lib/oracle/21/client64/lib" "" "" "/etc/odbc.ini"
|
||||||
- name: Setup SQL Server ODBC connector
|
- name: Setup SQL Server ODBC connector
|
||||||
run: |
|
run: |
|
||||||
curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
|
curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
|
||||||
curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
|
curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
|
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 90
|
timeout_minutes: 90
|
||||||
@ -739,7 +764,7 @@ jobs:
|
|||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- run: sudo apt -y update
|
- run: sudo apt -y update
|
||||||
- run: ./configure --everything --no-samples --no-sqlparser --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/MySQL,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
- run: ./configure --everything --no-samples --no-sqlparser --omit=ActiveRecord,ApacheConnector,CppParser,Crypto,Data/PostgreSQL,Data/MySQL,Data/ODBC,Encodings,JSON,JWT,MongoDB,Net,NetSSL_OpenSSL,NetSSL_Win,PDF,PageCompiler,PocoDoc,ProGen,Prometheus,Redis,SevenZip,Util,XML,Zip && make all -s -j4 && sudo make install
|
||||||
- uses: ./.github/actions/retry-action
|
- uses: ./.github/actions/retry-action
|
||||||
|
@ -97,7 +97,7 @@ void ConnectionHandle::setTimeouts(SQLULEN loginTimeout, SQLULEN timeout)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
setTimeout(timeout);
|
setTimeout(static_cast<int>(timeout));
|
||||||
}
|
}
|
||||||
catch(const NotSupportedException&) {}
|
catch(const NotSupportedException&) {}
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ bool ConnectionHandle::connect(const std::string& connectString, SQLULEN loginTi
|
|||||||
// for Oracle) flat out refuse to set login timeout and return error - that's why these calls
|
// for Oracle) flat out refuse to set login timeout and return error - that's why these calls
|
||||||
// are wrapped in try/catch and silently ignore errors.
|
// are wrapped in try/catch and silently ignore errors.
|
||||||
if (getTimeout() != timeout)
|
if (getTimeout() != timeout)
|
||||||
setTimeout(timeout);
|
setTimeout(static_cast<int>(timeout));
|
||||||
if (getLoginTimeout() != loginTimeout)
|
if (getLoginTimeout() != loginTimeout)
|
||||||
setLoginTimeout(loginTimeout);
|
setLoginTimeout(loginTimeout);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ inline Poco::Any SessionImpl::getCursorUse(const std::string&) const
|
|||||||
void SessionImpl::setConnectionTimeout(std::size_t timeout)
|
void SessionImpl::setConnectionTimeout(std::size_t timeout)
|
||||||
{
|
{
|
||||||
SQLULEN value = static_cast<SQLUINTEGER>(timeout);
|
SQLULEN value = static_cast<SQLUINTEGER>(timeout);
|
||||||
_db.setTimeout(value);
|
_db.setTimeout(static_cast<int>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/Unicode_UNIXODBC.h"
|
#include "Poco/Data/ODBC/Unicode_UNIXODBC.h"
|
||||||
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/TextConverter.h"
|
#include "Poco/TextConverter.h"
|
||||||
#include "Poco/UTF8Encoding.h"
|
#include "Poco/UTF8Encoding.h"
|
||||||
#include "Poco/UTF16Encoding.h"
|
#include "Poco/UTF16Encoding.h"
|
||||||
@ -73,6 +74,12 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
|
|||||||
SQLSMALLINT* pcbCharAttr,
|
SQLSMALLINT* pcbCharAttr,
|
||||||
NumAttrPtrType pNumAttr)
|
NumAttrPtrType pNumAttr)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbCharAttr = 0;
|
||||||
|
if (!pcbCharAttr) pcbCharAttr = &cbCharAttr;
|
||||||
|
|
||||||
|
SQLSMALLINT cbCharAttr;
|
||||||
|
if (!pcbCharAttr) pcbCharAttr = &cbCharAttr;
|
||||||
|
|
||||||
if (isString(pCharAttr, cbCharAttrMax))
|
if (isString(pCharAttr, cbCharAttrMax))
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(stringLength(pCharAttr, cbCharAttrMax));
|
Buffer<SQLWCHAR> buffer(stringLength(pCharAttr, cbCharAttrMax));
|
||||||
@ -85,7 +92,9 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
|
|||||||
pcbCharAttr,
|
pcbCharAttr,
|
||||||
pNumAttr);
|
pNumAttr);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +116,11 @@ SQLRETURN SQLColAttributes(SQLHSTMT hstmt,
|
|||||||
SQLSMALLINT* pcbDesc,
|
SQLSMALLINT* pcbDesc,
|
||||||
SQLLEN* pfDesc)
|
SQLLEN* pfDesc)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbDesc = 0;
|
||||||
|
if (!pcbDesc) pcbDesc = &cbDesc;
|
||||||
|
SQLLEN fDesc = 0;
|
||||||
|
if (!pfDesc) pfDesc = &fDesc;
|
||||||
|
|
||||||
return SQLColAttribute(hstmt,
|
return SQLColAttribute(hstmt,
|
||||||
icol,
|
icol,
|
||||||
fDescType,
|
fDescType,
|
||||||
@ -151,6 +165,17 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
|
|||||||
SQLSMALLINT* pibScale,
|
SQLSMALLINT* pibScale,
|
||||||
SQLSMALLINT* pfNullable)
|
SQLSMALLINT* pfNullable)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbColName = 0;
|
||||||
|
if (!pcbColName) pcbColName = &cbColName;
|
||||||
|
SQLSMALLINT fSqlType = 0;
|
||||||
|
if (!pfSqlType) pfSqlType = &fSqlType;
|
||||||
|
SQLULEN cbColDef = 0;
|
||||||
|
if (!pcbColDef) pcbColDef = &cbColDef;
|
||||||
|
SQLSMALLINT ibScale = 0;
|
||||||
|
if (!pibScale) pibScale = &ibScale;
|
||||||
|
SQLSMALLINT fNullable = 0;
|
||||||
|
if (!pfNullable) pfNullable = &fNullable;
|
||||||
|
|
||||||
Buffer<SQLWCHAR> buffer(cbColNameMax);
|
Buffer<SQLWCHAR> buffer(cbColNameMax);
|
||||||
SQLRETURN rc = SQLDescribeColW(hstmt,
|
SQLRETURN rc = SQLDescribeColW(hstmt,
|
||||||
icol,
|
icol,
|
||||||
@ -162,7 +187,9 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
|
|||||||
pibScale,
|
pibScale,
|
||||||
pfNullable);
|
pfNullable);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +225,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -208,7 +238,8 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
|
|||||||
(SQLINTEGER) buffer.sizeBytes(),
|
(SQLINTEGER) buffer.sizeBytes(),
|
||||||
pcbValue);
|
pcbValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +294,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -274,7 +308,8 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
|
|||||||
(SQLINTEGER) buffer.sizeBytes(),
|
(SQLINTEGER) buffer.sizeBytes(),
|
||||||
pcbValue);
|
pcbValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -312,6 +347,9 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
|
|||||||
SQLSMALLINT cbDiagInfoMax,
|
SQLSMALLINT cbDiagInfoMax,
|
||||||
SQLSMALLINT* pcbDiagInfo)
|
SQLSMALLINT* pcbDiagInfo)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbDiagInfo = 0;
|
||||||
|
if (!pcbDiagInfo) pcbDiagInfo = &cbDiagInfo;
|
||||||
|
|
||||||
if (isString(rgbDiagInfo, cbDiagInfoMax))
|
if (isString(rgbDiagInfo, cbDiagInfoMax))
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(stringLength(rgbDiagInfo, cbDiagInfoMax));
|
Buffer<SQLWCHAR> buffer(stringLength(rgbDiagInfo, cbDiagInfoMax));
|
||||||
@ -324,7 +362,8 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
|
|||||||
(SQLSMALLINT) buffer.sizeBytes(),
|
(SQLSMALLINT) buffer.sizeBytes(),
|
||||||
pcbDiagInfo);
|
pcbDiagInfo);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -348,6 +387,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
|
|||||||
SQLSMALLINT cbErrorMsgMax,
|
SQLSMALLINT cbErrorMsgMax,
|
||||||
SQLSMALLINT* pcbErrorMsg)
|
SQLSMALLINT* pcbErrorMsg)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER fNativeError = 0;
|
||||||
|
if (!pfNativeError) pfNativeError = &fNativeError;
|
||||||
|
SQLSMALLINT cbErrorMsg = 0;
|
||||||
|
if (!pcbErrorMsg) pcbErrorMsg = &cbErrorMsg;
|
||||||
|
|
||||||
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
|
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
|
||||||
Buffer<SQLWCHAR> bufState(stateLen);
|
Buffer<SQLWCHAR> bufState(stateLen);
|
||||||
Buffer<SQLWCHAR> bufErr(cbErrorMsgMax);
|
Buffer<SQLWCHAR> bufErr(cbErrorMsgMax);
|
||||||
@ -361,8 +405,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
|
|||||||
(SQLSMALLINT) bufErr.size(),
|
(SQLSMALLINT) bufErr.size(),
|
||||||
pcbErrorMsg);
|
pcbErrorMsg);
|
||||||
|
|
||||||
makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax);
|
{
|
||||||
|
makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen);
|
||||||
|
makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -433,6 +480,9 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<SQLWCHAR> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -476,6 +526,9 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
|
|||||||
SQLSMALLINT cbInfoValueMax,
|
SQLSMALLINT cbInfoValueMax,
|
||||||
SQLSMALLINT* pcbInfoValue)
|
SQLSMALLINT* pcbInfoValue)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbInfoValue = 0;
|
||||||
|
if (!pcbInfoValue) pcbInfoValue = &cbInfoValue;
|
||||||
|
|
||||||
if (cbInfoValueMax)
|
if (cbInfoValueMax)
|
||||||
{
|
{
|
||||||
Buffer<SQLWCHAR> buffer(cbInfoValueMax);
|
Buffer<SQLWCHAR> buffer(cbInfoValueMax);
|
||||||
@ -486,7 +539,8 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
|
|||||||
(SQLSMALLINT) buffer.sizeBytes(),
|
(SQLSMALLINT) buffer.sizeBytes(),
|
||||||
pcbInfoValue);
|
pcbInfoValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -561,6 +615,10 @@ SQLRETURN SQLDataSources(SQLHENV henv,
|
|||||||
SQLSMALLINT cbDescMax,
|
SQLSMALLINT cbDescMax,
|
||||||
SQLSMALLINT* pcbDesc)
|
SQLSMALLINT* pcbDesc)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbDSN = 0, cbDesc = 0;
|
||||||
|
if (!pcbDSN) pcbDSN = &cbDSN;
|
||||||
|
if (!pcbDesc) pcbDesc = &cbDesc;
|
||||||
|
|
||||||
Buffer<SQLWCHAR> bufDSN(cbDSNMax);
|
Buffer<SQLWCHAR> bufDSN(cbDSNMax);
|
||||||
Buffer<SQLWCHAR> bufDesc(cbDescMax);
|
Buffer<SQLWCHAR> bufDesc(cbDescMax);
|
||||||
|
|
||||||
@ -573,8 +631,11 @@ SQLRETURN SQLDataSources(SQLHENV henv,
|
|||||||
(SQLSMALLINT) bufDesc.size(),
|
(SQLSMALLINT) bufDesc.size(),
|
||||||
pcbDesc);
|
pcbDesc);
|
||||||
|
|
||||||
makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax);
|
{
|
||||||
|
makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax);
|
||||||
|
makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -589,6 +650,9 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
|
|||||||
SQLSMALLINT* pcbConnStrOut,
|
SQLSMALLINT* pcbConnStrOut,
|
||||||
SQLUSMALLINT fDriverCompletion)
|
SQLUSMALLINT fDriverCompletion)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbConnStrOut = 0;
|
||||||
|
if (!pcbConnStrOut) pcbConnStrOut = &cbConnStrOut;
|
||||||
|
|
||||||
SQLSMALLINT len = cbConnStrIn;
|
SQLSMALLINT len = cbConnStrIn;
|
||||||
if (SQL_NTS == len)
|
if (SQL_NTS == len)
|
||||||
len = (SQLSMALLINT) std::strlen((const char*) szConnStrIn) + 1;
|
len = (SQLSMALLINT) std::strlen((const char*) szConnStrIn) + 1;
|
||||||
@ -606,7 +670,8 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
|
|||||||
pcbConnStrOut,
|
pcbConnStrOut,
|
||||||
fDriverCompletion);
|
fDriverCompletion);
|
||||||
|
|
||||||
makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -619,6 +684,9 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
|
|||||||
SQLSMALLINT cbConnStrOutMax,
|
SQLSMALLINT cbConnStrOutMax,
|
||||||
SQLSMALLINT* pcbConnStrOut)
|
SQLSMALLINT* pcbConnStrOut)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbConnStrOut = 0;
|
||||||
|
if (!pcbConnStrOut) pcbConnStrOut = &cbConnStrOut;
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
makeUTF16(szConnStrIn, cbConnStrIn, str);
|
makeUTF16(szConnStrIn, cbConnStrIn, str);
|
||||||
|
|
||||||
@ -631,7 +699,8 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
|
|||||||
(SQLSMALLINT) bufConnStrOut.size(),
|
(SQLSMALLINT) bufConnStrOut.size(),
|
||||||
pcbConnStrOut);
|
pcbConnStrOut);
|
||||||
|
|
||||||
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -676,6 +745,9 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
|
|||||||
SQLINTEGER cbSqlStrMax,
|
SQLINTEGER cbSqlStrMax,
|
||||||
SQLINTEGER* pcbSqlStr)
|
SQLINTEGER* pcbSqlStr)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbSqlStr = 0;
|
||||||
|
if (!pcbSqlStr) pcbSqlStr = &cbSqlStr;
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
makeUTF16(szSqlStrIn, cbSqlStrIn, str);
|
makeUTF16(szSqlStrIn, cbSqlStrIn, str);
|
||||||
|
|
||||||
@ -688,7 +760,8 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
|
|||||||
(SQLINTEGER) bufSQLOut.size(),
|
(SQLINTEGER) bufSQLOut.size(),
|
||||||
pcbSqlStr);
|
pcbSqlStr);
|
||||||
|
|
||||||
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -753,6 +826,10 @@ SQLRETURN SQLDrivers(SQLHENV henv,
|
|||||||
SQLSMALLINT cbDrvrAttrMax,
|
SQLSMALLINT cbDrvrAttrMax,
|
||||||
SQLSMALLINT* pcbDrvrAttr)
|
SQLSMALLINT* pcbDrvrAttr)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbDriverDesc = 0, cbDrvrAttr = 0;
|
||||||
|
if (!pcbDriverDesc) pcbDriverDesc = &cbDriverDesc;
|
||||||
|
if (!pcbDrvrAttr) pcbDrvrAttr = &cbDrvrAttr;
|
||||||
|
|
||||||
Buffer<SQLWCHAR> bufDriverDesc(cbDriverDescMax);
|
Buffer<SQLWCHAR> bufDriverDesc(cbDriverDescMax);
|
||||||
Buffer<SQLWCHAR> bufDriverAttr(cbDrvrAttrMax);
|
Buffer<SQLWCHAR> bufDriverAttr(cbDrvrAttrMax);
|
||||||
|
|
||||||
@ -765,8 +842,11 @@ SQLRETURN SQLDrivers(SQLHENV henv,
|
|||||||
(SQLSMALLINT) bufDriverAttr.size(),
|
(SQLSMALLINT) bufDriverAttr.size(),
|
||||||
pcbDrvrAttr);
|
pcbDrvrAttr);
|
||||||
|
|
||||||
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax);
|
{
|
||||||
|
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax);
|
||||||
|
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,9 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
|
|||||||
pcbCharAttr,
|
pcbCharAttr,
|
||||||
pNumAttr);
|
pNumAttr);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbCharAttr, pCharAttr, cbCharAttrMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +131,9 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
|
|||||||
pibScale,
|
pibScale,
|
||||||
pfNullable);
|
pfNullable);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +171,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -177,7 +184,9 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
|
|||||||
(SQLINTEGER) buffer.sizeBytes(),
|
(SQLINTEGER) buffer.sizeBytes(),
|
||||||
pcbValue);
|
pcbValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +243,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -245,7 +257,9 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
|
|||||||
(SQLINTEGER) buffer.sizeBytes(),
|
(SQLINTEGER) buffer.sizeBytes(),
|
||||||
pcbValue);
|
pcbValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +308,8 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
|
|||||||
(SQLSMALLINT) buffer.sizeBytes(),
|
(SQLSMALLINT) buffer.sizeBytes(),
|
||||||
pcbDiagInfo);
|
pcbDiagInfo);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +332,12 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
|
|||||||
SQLSMALLINT cbErrorMsgMax,
|
SQLSMALLINT cbErrorMsgMax,
|
||||||
SQLSMALLINT* pcbErrorMsg)
|
SQLSMALLINT* pcbErrorMsg)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER nativeError = 0;
|
||||||
|
SQLSMALLINT cbErrorMsg = 0;
|
||||||
|
|
||||||
|
if (!pfNativeError) pfNativeError = &nativeError;
|
||||||
|
if (!pcbErrorMsg) pcbErrorMsg = &cbErrorMsg;
|
||||||
|
|
||||||
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
|
const SQLINTEGER stateLen = SQL_SQLSTATE_SIZE + 1;
|
||||||
Buffer<wchar_t> bufState(stateLen);
|
Buffer<wchar_t> bufState(stateLen);
|
||||||
Buffer<wchar_t> bufErr(cbErrorMsgMax);
|
Buffer<wchar_t> bufErr(cbErrorMsgMax);
|
||||||
@ -330,8 +351,11 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
|
|||||||
(SQLSMALLINT) bufErr.size(),
|
(SQLSMALLINT) bufErr.size(),
|
||||||
pcbErrorMsg);
|
pcbErrorMsg);
|
||||||
|
|
||||||
makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax);
|
{
|
||||||
|
makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen);
|
||||||
|
makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -410,6 +434,9 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
|
|||||||
SQLINTEGER cbValueMax,
|
SQLINTEGER cbValueMax,
|
||||||
SQLINTEGER* pcbValue)
|
SQLINTEGER* pcbValue)
|
||||||
{
|
{
|
||||||
|
SQLINTEGER cbValue = 0;
|
||||||
|
if (!pcbValue) pcbValue = &cbValue;
|
||||||
|
|
||||||
if (isString(rgbValue, cbValueMax))
|
if (isString(rgbValue, cbValueMax))
|
||||||
{
|
{
|
||||||
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
Buffer<wchar_t> buffer(stringLength(rgbValue, cbValueMax));
|
||||||
@ -457,6 +484,9 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
|
|||||||
SQLSMALLINT cbInfoValueMax,
|
SQLSMALLINT cbInfoValueMax,
|
||||||
SQLSMALLINT* pcbInfoValue)
|
SQLSMALLINT* pcbInfoValue)
|
||||||
{
|
{
|
||||||
|
SQLSMALLINT cbValue = 0;
|
||||||
|
if (!pcbInfoValue) pcbInfoValue = &cbValue;
|
||||||
|
|
||||||
if (cbInfoValueMax)
|
if (cbInfoValueMax)
|
||||||
{
|
{
|
||||||
Buffer<wchar_t> buffer(cbInfoValueMax);
|
Buffer<wchar_t> buffer(cbInfoValueMax);
|
||||||
@ -467,7 +497,8 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
|
|||||||
(SQLSMALLINT) buffer.sizeBytes(),
|
(SQLSMALLINT) buffer.sizeBytes(),
|
||||||
pcbInfoValue);
|
pcbInfoValue);
|
||||||
|
|
||||||
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -558,8 +589,11 @@ SQLRETURN SQLDataSources(SQLHENV henv,
|
|||||||
(SQLSMALLINT) bufDesc.size(),
|
(SQLSMALLINT) bufDesc.size(),
|
||||||
pcbDesc);
|
pcbDesc);
|
||||||
|
|
||||||
makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax);
|
{
|
||||||
|
makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax);
|
||||||
|
makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -617,7 +651,8 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
|
|||||||
(SQLSMALLINT) bufConnStrOut.size(),
|
(SQLSMALLINT) bufConnStrOut.size(),
|
||||||
pcbConnStrOut);
|
pcbConnStrOut);
|
||||||
|
|
||||||
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -674,7 +709,8 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
|
|||||||
(SQLINTEGER) bufSQLOut.size(),
|
(SQLINTEGER) bufSQLOut.size(),
|
||||||
pcbSqlStr);
|
pcbSqlStr);
|
||||||
|
|
||||||
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax);
|
if (!Utility::isError(rc))
|
||||||
|
makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -751,8 +787,11 @@ SQLRETURN SQLDrivers(SQLHENV henv,
|
|||||||
(SQLSMALLINT) bufDriverAttr.size(),
|
(SQLSMALLINT) bufDriverAttr.size(),
|
||||||
pcbDrvrAttr);
|
pcbDrvrAttr);
|
||||||
|
|
||||||
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax);
|
if (!Utility::isError(rc))
|
||||||
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax);
|
{
|
||||||
|
makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax);
|
||||||
|
makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,9 @@ public:
|
|||||||
Poco::UInt64 size() const;
|
Poco::UInt64 size() const;
|
||||||
/// Returns file size
|
/// Returns file size
|
||||||
|
|
||||||
|
void flushToDisk();
|
||||||
|
/// Forces buffered data to be written to the disk
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FileStreamBuf _buf;
|
FileStreamBuf _buf;
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,9 @@ public:
|
|||||||
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
|
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
|
||||||
/// Change to specified position, according to mode.
|
/// Change to specified position, according to mode.
|
||||||
|
|
||||||
|
void flushToDisk();
|
||||||
|
/// Forces buffered data to be written to the disk
|
||||||
|
|
||||||
NativeHandle nativeHandle() const;
|
NativeHandle nativeHandle() const;
|
||||||
/// Returns native file descriptor handle
|
/// Returns native file descriptor handle
|
||||||
|
|
||||||
|
@ -51,6 +51,9 @@ public:
|
|||||||
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
|
std::streampos seekpos(std::streampos pos, std::ios::openmode mode = std::ios::in | std::ios::out);
|
||||||
/// change to specified position, according to mode
|
/// change to specified position, according to mode
|
||||||
|
|
||||||
|
void flushToDisk();
|
||||||
|
/// Forces buffered data to be written to the disk
|
||||||
|
|
||||||
NativeHandle nativeHandle() const;
|
NativeHandle nativeHandle() const;
|
||||||
/// Returns native file descriptor handle
|
/// Returns native file descriptor handle
|
||||||
|
|
||||||
|
@ -17,21 +17,14 @@
|
|||||||
#ifndef Foundation_LogFile_INCLUDED
|
#ifndef Foundation_LogFile_INCLUDED
|
||||||
#define Foundation_LogFile_INCLUDED
|
#define Foundation_LogFile_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
|
#include "Poco/Timestamp.h"
|
||||||
|
#include "Poco/FileStream.h"
|
||||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
|
||||||
#include "Poco/LogFile_WIN32U.h"
|
|
||||||
#else
|
|
||||||
#include "Poco/LogFile_STD.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
class Foundation_API LogFile: public LogFileImpl
|
class Foundation_API LogFile
|
||||||
/// This class is used by FileChannel to work
|
/// This class is used by FileChannel to work
|
||||||
/// with a log file.
|
/// with a log file.
|
||||||
{
|
{
|
||||||
@ -55,36 +48,15 @@ public:
|
|||||||
|
|
||||||
const std::string& path() const;
|
const std::string& path() const;
|
||||||
/// Returns the path given in the constructor.
|
/// Returns the path given in the constructor.
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _path;
|
||||||
|
mutable Poco::FileOutputStream _str;
|
||||||
|
Timestamp _creationDate;
|
||||||
|
UInt64 _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline void LogFile::write(const std::string& text, bool flush)
|
|
||||||
{
|
|
||||||
writeImpl(text, flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline UInt64 LogFile::size() const
|
|
||||||
{
|
|
||||||
return sizeImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Timestamp LogFile::creationDate() const
|
|
||||||
{
|
|
||||||
return creationDateImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& LogFile::path() const
|
|
||||||
{
|
|
||||||
return pathImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
return newoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
|
||||||
|
{
|
||||||
|
const off_type off = pos;
|
||||||
|
return seekoff(off, std::ios::beg, which);
|
||||||
|
}
|
||||||
|
|
||||||
virtual int sync()
|
virtual int sync()
|
||||||
{
|
{
|
||||||
|
@ -67,7 +67,7 @@ const std::string DateTimeFormat::RFC850_REGEX(
|
|||||||
|
|
||||||
const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z");
|
const std::string DateTimeFormat::RFC1036_FORMAT("%W, %e %b %y %H:%M:%S %Z");
|
||||||
const std::string DateTimeFormat::RFC1036_REGEX(
|
const std::string DateTimeFormat::RFC1036_REGEX(
|
||||||
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sun)), *)?"
|
"(((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sunday)), *)?"
|
||||||
"\\d\\d? +"
|
"\\d\\d? +"
|
||||||
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
"((Jan)|(Feb)|(Mar)|(Apr)|(May)|(Jun)|(Jul)|(Aug)|(Sep)|(Oct)|(Nov)|(Dec)) +"
|
||||||
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "
|
"\\d\\d(\\d\\d)? +\\d\\d:\\d\\d(:\\d\\d)? "
|
||||||
|
@ -42,7 +42,7 @@ const std::string FileChannel::PROP_ROTATEONOPEN = "rotateOnOpen";
|
|||||||
FileChannel::FileChannel():
|
FileChannel::FileChannel():
|
||||||
_times("utc"),
|
_times("utc"),
|
||||||
_compress(false),
|
_compress(false),
|
||||||
_flush(true),
|
_flush(false),
|
||||||
_rotateOnOpen(false),
|
_rotateOnOpen(false),
|
||||||
_pFile(nullptr),
|
_pFile(nullptr),
|
||||||
_pRotateStrategy(new NullRotateStrategy()),
|
_pRotateStrategy(new NullRotateStrategy()),
|
||||||
@ -56,7 +56,7 @@ FileChannel::FileChannel(const std::string& path):
|
|||||||
_path(path),
|
_path(path),
|
||||||
_times("utc"),
|
_times("utc"),
|
||||||
_compress(false),
|
_compress(false),
|
||||||
_flush(true),
|
_flush(false),
|
||||||
_rotateOnOpen(false),
|
_rotateOnOpen(false),
|
||||||
_pFile(nullptr),
|
_pFile(nullptr),
|
||||||
_pRotateStrategy(new NullRotateStrategy()),
|
_pRotateStrategy(new NullRotateStrategy()),
|
||||||
|
@ -56,10 +56,18 @@ FileIOS::NativeHandle FileIOS::nativeHandle() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Poco::UInt64 FileIOS::size() const {
|
Poco::UInt64 FileIOS::size() const
|
||||||
|
{
|
||||||
return _buf.size();
|
return _buf.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileIOS::flushToDisk()
|
||||||
|
{
|
||||||
|
_buf.flushToDisk();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FileInputStream::FileInputStream():
|
FileInputStream::FileInputStream():
|
||||||
std::istream(&_buf)
|
std::istream(&_buf)
|
||||||
{
|
{
|
||||||
|
@ -169,6 +169,17 @@ std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileStreamBuf::flushToDisk()
|
||||||
|
{
|
||||||
|
if (getMode() & std::ios::out)
|
||||||
|
{
|
||||||
|
sync();
|
||||||
|
if (fsync(_fd) != 0)
|
||||||
|
File::handleLastError(_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
|
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
|
||||||
{
|
{
|
||||||
return _fd;
|
return _fd;
|
||||||
|
@ -199,6 +199,17 @@ std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileStreamBuf::flushToDisk()
|
||||||
|
{
|
||||||
|
if (getMode() & std::ios::out)
|
||||||
|
{
|
||||||
|
sync();
|
||||||
|
if (FlushFileBuffers(_handle) == 0)
|
||||||
|
File::handleLastError(_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
|
FileStreamBuf::NativeHandle FileStreamBuf::nativeHandle() const
|
||||||
{
|
{
|
||||||
return _handle;
|
return _handle;
|
||||||
|
@ -13,20 +13,34 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/LogFile.h"
|
#include "Poco/LogFile.h"
|
||||||
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/Exception.h"
|
||||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
|
||||||
#include "LogFile_WIN32U.cpp"
|
|
||||||
#else
|
|
||||||
#include "LogFile_STD.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
LogFile::LogFile(const std::string& path): LogFileImpl(path)
|
LogFile::LogFile(const std::string& path):
|
||||||
|
_path(path),
|
||||||
|
_str(_path, std::ios::app),
|
||||||
|
_size(static_cast<UInt64>(_str.tellp()))
|
||||||
{
|
{
|
||||||
|
// There seems to be a strange "optimization" in the Windows NTFS
|
||||||
|
// filesystem that causes it to reuse directory entries of deleted
|
||||||
|
// files. Example:
|
||||||
|
// 1. create a file named "test.dat"
|
||||||
|
// note the file's creation date
|
||||||
|
// 2. delete the file "test.dat"
|
||||||
|
// 3. wait a few seconds
|
||||||
|
// 4. create a file named "test.dat"
|
||||||
|
// the new file will have the same creation
|
||||||
|
// date as the old one.
|
||||||
|
// We work around this bug by taking the file's
|
||||||
|
// modification date as a reference when the
|
||||||
|
// file is empty.
|
||||||
|
if (_size == 0)
|
||||||
|
_creationDate = File(path).getLastModified();
|
||||||
|
else
|
||||||
|
_creationDate = File(path).created();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -35,4 +49,63 @@ LogFile::~LogFile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LogFile::write(const std::string& text, bool flush)
|
||||||
|
{
|
||||||
|
std::streampos pos = _str.tellp();
|
||||||
|
|
||||||
|
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||||
|
// Replace \n with \r\n
|
||||||
|
std::string logText;
|
||||||
|
logText.reserve(text.size() + 16); // keep some reserve for \n -> \r\n
|
||||||
|
char prevChar = 0;
|
||||||
|
for (char c: text)
|
||||||
|
{
|
||||||
|
if (c == '\n' && prevChar != '\r')
|
||||||
|
logText += POCO_DEFAULT_NEWLINE_CHARS;
|
||||||
|
else
|
||||||
|
logText += c;
|
||||||
|
|
||||||
|
prevChar = c;
|
||||||
|
}
|
||||||
|
_str << logText;
|
||||||
|
#else
|
||||||
|
_str << text;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_str << POCO_DEFAULT_NEWLINE_CHARS;
|
||||||
|
|
||||||
|
if (flush)
|
||||||
|
_str.flushToDisk();
|
||||||
|
else
|
||||||
|
_str.flush();
|
||||||
|
|
||||||
|
if (!_str.good())
|
||||||
|
{
|
||||||
|
_str.clear();
|
||||||
|
_str.seekp(pos);
|
||||||
|
throw WriteFileException(_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
_size = static_cast<UInt64>(_str.tellp());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UInt64 LogFile::size() const
|
||||||
|
{
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Timestamp LogFile::creationDate() const
|
||||||
|
{
|
||||||
|
return _creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::string& LogFile::path() const
|
||||||
|
{
|
||||||
|
return _path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
@ -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;
|
else _port = 0;
|
||||||
_host = host;
|
_host = host;
|
||||||
toLowerInPlace(_host);
|
if (_host.size() && _host[0] != '%')
|
||||||
|
toLowerInPlace(_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,6 +143,14 @@ void MemoryStreamTest::testInputSeek()
|
|||||||
assertTrue (istr.good());
|
assertTrue (istr.good());
|
||||||
assertTrue (9 == istr.tellg());
|
assertTrue (9 == istr.tellg());
|
||||||
|
|
||||||
|
|
||||||
|
istr.seekg(5);
|
||||||
|
assertTrue (istr.good());
|
||||||
|
assertTrue (5 == istr.tellg());
|
||||||
|
istr >> c;
|
||||||
|
assertTrue (c == '6');
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
|
Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
|
||||||
istr2.seekg(10, std::ios_base::beg);
|
istr2.seekg(10, std::ios_base::beg);
|
||||||
@ -337,6 +345,12 @@ void MemoryStreamTest::testOutputSeek()
|
|||||||
assertTrue (ostr.good());
|
assertTrue (ostr.good());
|
||||||
assertTrue (9 == ostr.tellp());
|
assertTrue (9 == ostr.tellp());
|
||||||
|
|
||||||
|
|
||||||
|
ostr.seekp(5);
|
||||||
|
assertTrue (ostr.good());
|
||||||
|
assertTrue (5 == ostr.tellp());
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
|
Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
|
||||||
ostr2.seekp(10, std::ios_base::beg);
|
ostr2.seekp(10, std::ios_base::beg);
|
||||||
|
@ -798,6 +798,15 @@ void URITest::testOther()
|
|||||||
assertTrue (uri.getRawFragment() == "foo%2Fbar");
|
assertTrue (uri.getRawFragment() == "foo%2Fbar");
|
||||||
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo%2Fbar");
|
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo%2Fbar");
|
||||||
assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo%2Fbar");
|
assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo%2Fbar");
|
||||||
|
|
||||||
|
uri = "http://ServerSocket.com/index.html";
|
||||||
|
assertTrue (uri.toString() == "http://serversocket.com/index.html");
|
||||||
|
|
||||||
|
uri = "http+unix://%2Ftmp%2FServerSocket/index.html";
|
||||||
|
assertTrue (uri.toString() == "http+unix://%2Ftmp%2FServerSocket/index.html");
|
||||||
|
std::string decoded;
|
||||||
|
uri.decode("http+unix://%2Ftmp%2FServerSocket/index.html", decoded);
|
||||||
|
assertTrue (decoded == "http+unix:///tmp/ServerSocket/index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ public:
|
|||||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||||
/// socket option.
|
/// socket option.
|
||||||
///
|
///
|
||||||
/// Calls to connect cannot() come before calls to bind().
|
/// Calls to connect() cannot come before calls to bind().
|
||||||
|
|
||||||
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||||
/// Bind a local address to the socket.
|
/// Bind a local address to the socket.
|
||||||
@ -143,7 +143,7 @@ public:
|
|||||||
/// If reusePort is true, sets the SO_REUSEPORT
|
/// If reusePort is true, sets the SO_REUSEPORT
|
||||||
/// socket option.
|
/// socket option.
|
||||||
///
|
///
|
||||||
/// Calls to connect cannot() come before calls to bind().
|
/// Calls to connect() cannot come before calls to bind().
|
||||||
|
|
||||||
void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only = false);
|
void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only = false);
|
||||||
/// Bind a local address to the socket.
|
/// Bind a local address to the socket.
|
||||||
@ -160,7 +160,7 @@ public:
|
|||||||
/// Sets the IPV6_V6ONLY socket option in accordance with
|
/// Sets the IPV6_V6ONLY socket option in accordance with
|
||||||
/// the supplied ipV6Only value.
|
/// the supplied ipV6Only value.
|
||||||
///
|
///
|
||||||
/// Calls to connect cannot() come before calls to bind().
|
/// Calls to connect() cannot come before calls to bind().
|
||||||
|
|
||||||
int sendBytes(const void* buffer, int length, int flags = 0);
|
int sendBytes(const void* buffer, int length, int flags = 0);
|
||||||
/// Sends the contents of the given buffer through
|
/// Sends the contents of the given buffer through
|
||||||
|
@ -216,7 +216,7 @@ public:
|
|||||||
/// as the system is free to adjust the value.
|
/// as the system is free to adjust the value.
|
||||||
|
|
||||||
void setReceiveTimeout(const Poco::Timespan& timeout);
|
void setReceiveTimeout(const Poco::Timespan& timeout);
|
||||||
/// Sets the send timeout for the socket.
|
/// Sets the receive timeout for the socket.
|
||||||
///
|
///
|
||||||
/// On systems that do not support SO_RCVTIMEO, a
|
/// On systems that do not support SO_RCVTIMEO, a
|
||||||
/// workaround using poll() is provided.
|
/// workaround using poll() is provided.
|
||||||
|
@ -147,7 +147,7 @@ SocketImpl* SocketImpl::acceptConnection(SocketAddress& clientAddr)
|
|||||||
return new StreamSocketImpl(sd);
|
return new StreamSocketImpl(sd);
|
||||||
}
|
}
|
||||||
error(); // will throw
|
error(); // will throw
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -527,7 +527,7 @@ int SocketImpl::sendTo(const SocketBufVec& buffers, const SocketAddress& address
|
|||||||
msgHdr.msg_namelen = address.length();
|
msgHdr.msg_namelen = address.length();
|
||||||
msgHdr.msg_iov = const_cast<iovec*>(&buffers[0]);
|
msgHdr.msg_iov = const_cast<iovec*>(&buffers[0]);
|
||||||
msgHdr.msg_iovlen = buffers.size();
|
msgHdr.msg_iovlen = buffers.size();
|
||||||
msgHdr.msg_control = 0;
|
msgHdr.msg_control = nullptr;
|
||||||
msgHdr.msg_controllen = 0;
|
msgHdr.msg_controllen = 0;
|
||||||
msgHdr.msg_flags = flags;
|
msgHdr.msg_flags = flags;
|
||||||
rc = sendmsg(_sockfd, &msgHdr, flags);
|
rc = sendmsg(_sockfd, &msgHdr, flags);
|
||||||
@ -613,7 +613,7 @@ int SocketImpl::receiveFrom(SocketBufVec& buffers, struct sockaddr** pSA, poco_s
|
|||||||
msgHdr.msg_namelen = **ppSALen;
|
msgHdr.msg_namelen = **ppSALen;
|
||||||
msgHdr.msg_iov = &buffers[0];
|
msgHdr.msg_iov = &buffers[0];
|
||||||
msgHdr.msg_iovlen = buffers.size();
|
msgHdr.msg_iovlen = buffers.size();
|
||||||
msgHdr.msg_control = 0;
|
msgHdr.msg_control = nullptr;
|
||||||
msgHdr.msg_controllen = 0;
|
msgHdr.msg_controllen = 0;
|
||||||
msgHdr.msg_flags = flags;
|
msgHdr.msg_flags = flags;
|
||||||
rc = recvmsg(_sockfd, &msgHdr, flags);
|
rc = recvmsg(_sockfd, &msgHdr, flags);
|
||||||
@ -652,7 +652,7 @@ int SocketImpl::available()
|
|||||||
if (result && (type() == SOCKET_TYPE_DATAGRAM))
|
if (result && (type() == SOCKET_TYPE_DATAGRAM))
|
||||||
{
|
{
|
||||||
std::vector<char> buf(result);
|
std::vector<char> buf(result);
|
||||||
result = recvfrom(sockfd(), &buf[0], result, MSG_PEEK, NULL, NULL);
|
result = recvfrom(sockfd(), &buf[0], result, MSG_PEEK, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
@ -1114,7 +1114,7 @@ void SocketImpl::setReusePort(bool flag)
|
|||||||
int value = flag ? 1 : 0;
|
int value = flag ? 1 : 0;
|
||||||
setOption(SOL_SOCKET, SO_REUSEPORT, value);
|
setOption(SOL_SOCKET, SO_REUSEPORT, value);
|
||||||
}
|
}
|
||||||
catch (IOException&)
|
catch (const IOException&)
|
||||||
{
|
{
|
||||||
// ignore error, since not all implementations
|
// ignore error, since not all implementations
|
||||||
// support SO_REUSEPORT, even if the macro
|
// support SO_REUSEPORT, even if the macro
|
||||||
|
@ -132,7 +132,7 @@ public:
|
|||||||
/// a SecureStreamSocketImpl, otherwise an InvalidArgumentException
|
/// a SecureStreamSocketImpl, otherwise an InvalidArgumentException
|
||||||
/// will be thrown.
|
/// will be thrown.
|
||||||
|
|
||||||
virtual ~SecureStreamSocket();
|
~SecureStreamSocket() override;
|
||||||
/// Destroys the StreamSocket.
|
/// Destroys the StreamSocket.
|
||||||
|
|
||||||
SecureStreamSocket& operator = (const Socket& socket);
|
SecureStreamSocket& operator = (const Socket& socket);
|
||||||
|
@ -39,12 +39,12 @@ public:
|
|||||||
SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext);
|
SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext);
|
||||||
/// Creates the SecureStreamSocketImpl.
|
/// Creates the SecureStreamSocketImpl.
|
||||||
|
|
||||||
SocketImpl* acceptConnection(SocketAddress& clientAddr);
|
SocketImpl* acceptConnection(SocketAddress& clientAddr) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
void connect(const SocketAddress& address);
|
void connect(const SocketAddress& address) override;
|
||||||
/// Initializes the socket and establishes a connection to
|
/// Initializes the socket and establishes a connection to
|
||||||
/// the TCP server at the given address.
|
/// the TCP server at the given address.
|
||||||
///
|
///
|
||||||
@ -52,57 +52,57 @@ public:
|
|||||||
/// connection is established. Instead, incoming and outgoing
|
/// connection is established. Instead, incoming and outgoing
|
||||||
/// packets are restricted to the specified address.
|
/// packets are restricted to the specified address.
|
||||||
|
|
||||||
void connect(const SocketAddress& address, const Poco::Timespan& timeout);
|
void connect(const SocketAddress& address, const Poco::Timespan& timeout) override;
|
||||||
/// Initializes the socket, sets the socket timeout and
|
/// Initializes the socket, sets the socket timeout and
|
||||||
/// establishes a connection to the TCP server at the given address.
|
/// establishes a connection to the TCP server at the given address.
|
||||||
|
|
||||||
void connectNB(const SocketAddress& address);
|
void connectNB(const SocketAddress& address) override;
|
||||||
/// Initializes the socket and establishes a connection to
|
/// Initializes the socket and establishes a connection to
|
||||||
/// the TCP server at the given address. Prior to opening the
|
/// the TCP server at the given address. Prior to opening the
|
||||||
/// connection the socket is set to nonblocking mode.
|
/// connection the socket is set to nonblocking mode.
|
||||||
|
|
||||||
void bind(const SocketAddress& address, bool reuseAddress = false);
|
void bind(const SocketAddress& address, bool reuseAddress = false) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
void listen(int backlog = 64);
|
void listen(int backlog = 64) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
void close();
|
void close() override;
|
||||||
/// Close the socket.
|
/// Close the socket.
|
||||||
|
|
||||||
int sendBytes(const void* buffer, int length, int flags = 0);
|
int sendBytes(const void* buffer, int length, int flags = 0) override;
|
||||||
/// Sends the contents of the given buffer through
|
/// Sends the contents of the given buffer through
|
||||||
/// the socket. Any specified flags are ignored.
|
/// the socket. Any specified flags are ignored.
|
||||||
///
|
///
|
||||||
/// Returns the number of bytes sent, which may be
|
/// Returns the number of bytes sent, which may be
|
||||||
/// less than the number of bytes specified.
|
/// less than the number of bytes specified.
|
||||||
|
|
||||||
int receiveBytes(void* buffer, int length, int flags = 0);
|
int receiveBytes(void* buffer, int length, int flags = 0) override;
|
||||||
/// Receives data from the socket and stores it
|
/// Receives data from the socket and stores it
|
||||||
/// in buffer. Up to length bytes are received.
|
/// in buffer. Up to length bytes are received.
|
||||||
///
|
///
|
||||||
/// Returns the number of bytes received.
|
/// Returns the number of bytes received.
|
||||||
|
|
||||||
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0);
|
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0);
|
int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
void sendUrgent(unsigned char data);
|
void sendUrgent(unsigned char data) override;
|
||||||
/// Not supported by a SecureStreamSocket.
|
/// Not supported by a SecureStreamSocket.
|
||||||
///
|
///
|
||||||
/// Throws a Poco::InvalidAccessException.
|
/// Throws a Poco::InvalidAccessException.
|
||||||
|
|
||||||
int available();
|
int available() override;
|
||||||
/// Returns the number of bytes available that can be read
|
/// Returns the number of bytes available that can be read
|
||||||
/// without causing the socket to block.
|
/// without causing the socket to block.
|
||||||
///
|
///
|
||||||
@ -110,26 +110,26 @@ public:
|
|||||||
/// can be read from the currently buffered SSL record,
|
/// can be read from the currently buffered SSL record,
|
||||||
/// before a new record is read from the underlying socket.
|
/// before a new record is read from the underlying socket.
|
||||||
|
|
||||||
void shutdownReceive();
|
void shutdownReceive() override;
|
||||||
/// Shuts down the receiving part of the socket connection.
|
/// Shuts down the receiving part of the socket connection.
|
||||||
///
|
///
|
||||||
/// Since SSL does not support a half shutdown, this does
|
/// Since SSL does not support a half shutdown, this does
|
||||||
/// nothing.
|
/// nothing.
|
||||||
|
|
||||||
void shutdownSend();
|
void shutdownSend() override;
|
||||||
/// Shuts down the receiving part of the socket connection.
|
/// Shuts down the receiving part of the socket connection.
|
||||||
///
|
///
|
||||||
/// Since SSL does not support a half shutdown, this does
|
/// Since SSL does not support a half shutdown, this does
|
||||||
/// nothing.
|
/// nothing.
|
||||||
|
|
||||||
void shutdown();
|
void shutdown() override;
|
||||||
/// Shuts down the SSL connection.
|
/// Shuts down the SSL connection.
|
||||||
|
|
||||||
void abort();
|
void abort();
|
||||||
/// Aborts the connection by closing the underlying
|
/// Aborts the connection by closing the underlying
|
||||||
/// TCP connection. No orderly SSL shutdown is performed.
|
/// TCP connection. No orderly SSL shutdown is performed.
|
||||||
|
|
||||||
bool secure() const;
|
bool secure() const override;
|
||||||
/// Returns true iff the socket's connection is secure
|
/// Returns true iff the socket's connection is secure
|
||||||
/// (using SSL or TLS).
|
/// (using SSL or TLS).
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ protected:
|
|||||||
void connectSSL();
|
void connectSSL();
|
||||||
/// Performs a SSL client-side handshake on an already connected TCP socket.
|
/// Performs a SSL client-side handshake on an already connected TCP socket.
|
||||||
|
|
||||||
~SecureStreamSocketImpl();
|
~SecureStreamSocketImpl() override;
|
||||||
/// Destroys the SecureStreamSocketImpl.
|
/// Destroys the SecureStreamSocketImpl.
|
||||||
|
|
||||||
static int lastError();
|
static int lastError();
|
||||||
|
@ -22,10 +22,7 @@
|
|||||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||||
#include "Poco/Net/StreamSocketImpl.h"
|
#include "Poco/Net/StreamSocketImpl.h"
|
||||||
#include "Poco/Net/StreamSocket.h"
|
#include "Poco/Net/StreamSocket.h"
|
||||||
#include "Poco/Net/NetException.h"
|
|
||||||
#include "Poco/Net/DNS.h"
|
|
||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/NumberParser.h"
|
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@ -38,16 +35,12 @@ using Poco::NumberFormatter;
|
|||||||
using Poco::Timespan;
|
using Poco::Timespan;
|
||||||
|
|
||||||
|
|
||||||
// workaround for C++-incompatible macro
|
|
||||||
#define POCO_BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(void*)((n)?"a":NULL))
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
|
||||||
SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext):
|
SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext):
|
||||||
_pSSL(0),
|
_pSSL(nullptr),
|
||||||
_pSocket(pSocketImpl),
|
_pSocket(pSocketImpl),
|
||||||
_pContext(pContext),
|
_pContext(pContext),
|
||||||
_needHandshake(false)
|
_needHandshake(false)
|
||||||
@ -86,14 +79,14 @@ void SecureSocketImpl::acceptSSL()
|
|||||||
{
|
{
|
||||||
poco_assert (!_pSSL);
|
poco_assert (!_pSSL);
|
||||||
|
|
||||||
BIO* pBIO = BIO_new(BIO_s_socket());
|
BIO* pBIO = ::BIO_new(BIO_s_socket());
|
||||||
if (!pBIO) throw SSLException("Cannot create BIO object");
|
if (!pBIO) throw SSLException("Cannot create BIO object");
|
||||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||||
|
|
||||||
_pSSL = SSL_new(_pContext->sslContext());
|
_pSSL = ::SSL_new(_pContext->sslContext());
|
||||||
if (!_pSSL)
|
if (!_pSSL)
|
||||||
{
|
{
|
||||||
BIO_free(pBIO);
|
::BIO_free(pBIO);
|
||||||
throw SSLException("Cannot create SSL object");
|
throw SSLException("Cannot create SSL object");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,15 +98,15 @@ void SecureSocketImpl::acceptSSL()
|
|||||||
* tickets. */
|
* tickets. */
|
||||||
if (1 != SSL_set_num_tickets(_pSSL, 0))
|
if (1 != SSL_set_num_tickets(_pSSL, 0))
|
||||||
{
|
{
|
||||||
BIO_free(pBIO);
|
::BIO_free(pBIO);
|
||||||
throw SSLException("Cannot create SSL object");
|
throw SSLException("Cannot create SSL object");
|
||||||
}
|
}
|
||||||
//Otherwise we can perform two-way shutdown. Client must call SSL_read() before the final SSL_shutdown().
|
//Otherwise we can perform two-way shutdown. Client must call SSL_read() before the final SSL_shutdown().
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_set_bio(_pSSL, pBIO, pBIO);
|
::SSL_set_bio(_pSSL, pBIO, pBIO);
|
||||||
SSL_set_accept_state(_pSSL);
|
::SSL_set_accept_state(_pSSL);
|
||||||
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
|
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
|
||||||
_needHandshake = true;
|
_needHandshake = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,18 +155,18 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
|
|||||||
poco_assert (!_pSSL);
|
poco_assert (!_pSSL);
|
||||||
poco_assert (_pSocket->initialized());
|
poco_assert (_pSocket->initialized());
|
||||||
|
|
||||||
BIO* pBIO = BIO_new(BIO_s_socket());
|
::BIO* pBIO = ::BIO_new(BIO_s_socket());
|
||||||
if (!pBIO) throw SSLException("Cannot create SSL BIO object");
|
if (!pBIO) throw SSLException("Cannot create SSL BIO object");
|
||||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||||
|
|
||||||
_pSSL = SSL_new(_pContext->sslContext());
|
_pSSL = ::SSL_new(_pContext->sslContext());
|
||||||
if (!_pSSL)
|
if (!_pSSL)
|
||||||
{
|
{
|
||||||
BIO_free(pBIO);
|
::BIO_free(pBIO);
|
||||||
throw SSLException("Cannot create SSL object");
|
throw SSLException("Cannot create SSL object");
|
||||||
}
|
}
|
||||||
SSL_set_bio(_pSSL, pBIO, pBIO);
|
::SSL_set_bio(_pSSL, pBIO, pBIO);
|
||||||
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
|
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), this);
|
||||||
|
|
||||||
if (!_peerHostName.empty())
|
if (!_peerHostName.empty())
|
||||||
{
|
{
|
||||||
@ -189,27 +182,27 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
|
|||||||
|
|
||||||
if (_pSession && _pSession->isResumable())
|
if (_pSession && _pSession->isResumable())
|
||||||
{
|
{
|
||||||
SSL_set_session(_pSSL, _pSession->sslSession());
|
::SSL_set_session(_pSSL, _pSession->sslSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (performHandshake && _pSocket->getBlocking())
|
if (performHandshake && _pSocket->getBlocking())
|
||||||
{
|
{
|
||||||
int ret = SSL_connect(_pSSL);
|
int ret = ::SSL_connect(_pSSL);
|
||||||
handleError(ret);
|
handleError(ret);
|
||||||
verifyPeerCertificate();
|
verifyPeerCertificate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SSL_set_connect_state(_pSSL);
|
::SSL_set_connect_state(_pSSL);
|
||||||
_needHandshake = true;
|
_needHandshake = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
SSL_free(_pSSL);
|
::SSL_free(_pSSL);
|
||||||
_pSSL = 0;
|
_pSSL = nullptr;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,11 +252,11 @@ void SecureSocketImpl::shutdown()
|
|||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
{
|
{
|
||||||
// Don't shut down the socket more than once.
|
// Don't shut down the socket more than once.
|
||||||
int shutdownState = SSL_get_shutdown(_pSSL);
|
int shutdownState = ::SSL_get_shutdown(_pSSL);
|
||||||
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
|
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
|
||||||
if (!shutdownSent)
|
if (!shutdownSent)
|
||||||
{
|
{
|
||||||
// A proper clean shutdown would require us to
|
// A proper clean shutdown would require us to
|
||||||
// retry the shutdown if we get a zero return
|
// retry the shutdown if we get a zero return
|
||||||
// value, until SSL_shutdown() returns 1.
|
// value, until SSL_shutdown() returns 1.
|
||||||
@ -274,7 +267,7 @@ void SecureSocketImpl::shutdown()
|
|||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if (!_bidirectShutdown)
|
if (!_bidirectShutdown)
|
||||||
rc = SSL_shutdown(_pSSL);
|
rc = ::SSL_shutdown(_pSSL);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Poco::Timespan recvTimeout = _pSocket->getReceiveTimeout();
|
Poco::Timespan recvTimeout = _pSocket->getReceiveTimeout();
|
||||||
@ -282,11 +275,11 @@ void SecureSocketImpl::shutdown()
|
|||||||
Poco::Timestamp tsNow;
|
Poco::Timestamp tsNow;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rc = SSL_shutdown(_pSSL);
|
rc = ::SSL_shutdown(_pSSL);
|
||||||
if (rc == 1) break;
|
if (rc == 1) break;
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
int err = SSL_get_error(_pSSL, rc);
|
int err = ::SSL_get_error(_pSSL, rc);
|
||||||
if (err == SSL_ERROR_WANT_READ)
|
if (err == SSL_ERROR_WANT_READ)
|
||||||
_pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ);
|
_pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ);
|
||||||
else if (err == SSL_ERROR_WANT_WRITE)
|
else if (err == SSL_ERROR_WANT_WRITE)
|
||||||
@ -294,7 +287,7 @@ void SecureSocketImpl::shutdown()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int socketError = SocketImpl::lastError();
|
int socketError = SocketImpl::lastError();
|
||||||
long lastError = ERR_get_error();
|
long lastError = ::ERR_get_error();
|
||||||
if ((err == SSL_ERROR_SSL) && (socketError == 0) && (lastError == 0x0A000123))
|
if ((err == SSL_ERROR_SSL) && (socketError == 0) && (lastError == 0x0A000123))
|
||||||
rc = 0;
|
rc = 0;
|
||||||
break;
|
break;
|
||||||
@ -304,7 +297,7 @@ void SecureSocketImpl::shutdown()
|
|||||||
} while (!tsNow.isElapsed(recvTimeout.totalMicroseconds()));
|
} while (!tsNow.isElapsed(recvTimeout.totalMicroseconds()));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int rc = SSL_shutdown(_pSSL);
|
int rc = ::SSL_shutdown(_pSSL);
|
||||||
#endif
|
#endif
|
||||||
if (rc < 0) handleError(rc);
|
if (rc < 0) handleError(rc);
|
||||||
if (_pSocket->getBlocking())
|
if (_pSocket->getBlocking())
|
||||||
@ -361,11 +354,17 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
|||||||
else
|
else
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
do
|
const auto sendTimeout = _pSocket->getSendTimeout();
|
||||||
|
Poco::Timestamp tsStart;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
rc = SSL_write(_pSSL, buffer, length);
|
rc = ::SSL_write(_pSSL, buffer, length);
|
||||||
}
|
if (!mustRetry(rc))
|
||||||
while (mustRetry(rc));
|
break;
|
||||||
|
|
||||||
|
if (tsStart.isElapsed(sendTimeout.totalMicroseconds()))
|
||||||
|
throw Poco::TimeoutException();
|
||||||
|
};
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
{
|
{
|
||||||
rc = handleError(rc);
|
rc = handleError(rc);
|
||||||
@ -389,11 +388,18 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
else
|
else
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
do
|
|
||||||
|
const auto recvTimeout = _pSocket->getReceiveTimeout();
|
||||||
|
Poco::Timestamp tsStart;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
rc = SSL_read(_pSSL, buffer, length);
|
rc = ::SSL_read(_pSSL, buffer, length);
|
||||||
}
|
if (!mustRetry(rc))
|
||||||
while (mustRetry(rc));
|
break;
|
||||||
|
|
||||||
|
if (tsStart.isElapsed(recvTimeout.totalMicroseconds()))
|
||||||
|
throw Poco::TimeoutException();
|
||||||
|
};
|
||||||
_bidirectShutdown = false;
|
_bidirectShutdown = false;
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
{
|
{
|
||||||
@ -407,7 +413,7 @@ int SecureSocketImpl::available() const
|
|||||||
{
|
{
|
||||||
poco_check_ptr (_pSSL);
|
poco_check_ptr (_pSSL);
|
||||||
|
|
||||||
return SSL_pending(_pSSL);
|
return ::SSL_pending(_pSSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -417,11 +423,17 @@ int SecureSocketImpl::completeHandshake()
|
|||||||
poco_check_ptr (_pSSL);
|
poco_check_ptr (_pSSL);
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
do
|
const auto recvTimeout = _pSocket->getReceiveTimeout();
|
||||||
|
Poco::Timestamp tsStart;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
rc = SSL_do_handshake(_pSSL);
|
rc = ::SSL_do_handshake(_pSSL);
|
||||||
}
|
if (!mustRetry(rc))
|
||||||
while (mustRetry(rc));
|
break;
|
||||||
|
|
||||||
|
if (tsStart.isElapsed(recvTimeout.totalMicroseconds()))
|
||||||
|
throw Poco::TimeoutException();
|
||||||
|
};
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
{
|
{
|
||||||
return handleError(rc);
|
return handleError(rc);
|
||||||
@ -460,7 +472,7 @@ long SecureSocketImpl::verifyPeerCertificateImpl(const std::string& hostName)
|
|||||||
return X509_V_OK;
|
return X509_V_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509* pCert = SSL_get_peer_certificate(_pSSL);
|
::X509* pCert = ::SSL_get_peer_certificate(_pSSL);
|
||||||
if (pCert)
|
if (pCert)
|
||||||
{
|
{
|
||||||
X509Certificate cert(pCert);
|
X509Certificate cert(pCert);
|
||||||
@ -477,7 +489,7 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
|
|||||||
SocketAddress addr(hostName, 0);
|
SocketAddress addr(hostName, 0);
|
||||||
return addr.host().isLoopback();
|
return addr.host().isLoopback();
|
||||||
}
|
}
|
||||||
catch (Poco::Exception&)
|
catch (const Poco::Exception&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -487,9 +499,9 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
|
|||||||
X509* SecureSocketImpl::peerCertificate() const
|
X509* SecureSocketImpl::peerCertificate() const
|
||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
return SSL_get_peer_certificate(_pSSL);
|
return ::SSL_get_peer_certificate(_pSSL);
|
||||||
else
|
else
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -497,26 +509,24 @@ bool SecureSocketImpl::mustRetry(int rc)
|
|||||||
{
|
{
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
{
|
{
|
||||||
int sslError = SSL_get_error(_pSSL, rc);
|
static const Poco::Timespan pollTimeout(0, 100000);
|
||||||
|
|
||||||
|
int sslError = ::SSL_get_error(_pSSL, rc);
|
||||||
int socketError = _pSocket->lastError();
|
int socketError = _pSocket->lastError();
|
||||||
switch (sslError)
|
switch (sslError)
|
||||||
{
|
{
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
if (_pSocket->getBlocking())
|
if (_pSocket->getBlocking())
|
||||||
{
|
{
|
||||||
if (_pSocket->poll(_pSocket->getReceiveTimeout(), Poco::Net::Socket::SELECT_READ))
|
_pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_READ);
|
||||||
return true;
|
return true;
|
||||||
else
|
|
||||||
throw Poco::TimeoutException();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
if (_pSocket->getBlocking())
|
if (_pSocket->getBlocking())
|
||||||
{
|
{
|
||||||
if (_pSocket->poll(_pSocket->getSendTimeout(), Poco::Net::Socket::SELECT_WRITE))
|
_pSocket->poll(pollTimeout, Poco::Net::Socket::SELECT_WRITE);
|
||||||
return true;
|
return true;
|
||||||
else
|
|
||||||
throw Poco::TimeoutException();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
@ -533,7 +543,7 @@ int SecureSocketImpl::handleError(int rc)
|
|||||||
{
|
{
|
||||||
if (rc > 0) return rc;
|
if (rc > 0) return rc;
|
||||||
|
|
||||||
int sslError = SSL_get_error(_pSSL, rc);
|
int sslError = ::SSL_get_error(_pSSL, rc);
|
||||||
int socketError = SocketImpl::lastError();
|
int socketError = SocketImpl::lastError();
|
||||||
|
|
||||||
switch (sslError)
|
switch (sslError)
|
||||||
@ -569,12 +579,12 @@ int SecureSocketImpl::handleError(int rc)
|
|||||||
// fallthrough
|
// fallthrough
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
long lastError = ERR_get_error();
|
long lastError = ::ERR_get_error();
|
||||||
std::string msg;
|
std::string msg;
|
||||||
if (lastError)
|
if (lastError)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
ERR_error_string_n(lastError, buffer, sizeof(buffer));
|
::ERR_error_string_n(lastError, buffer, sizeof(buffer));
|
||||||
msg = buffer;
|
msg = buffer;
|
||||||
}
|
}
|
||||||
// SSL_GET_ERROR(3ossl):
|
// SSL_GET_ERROR(3ossl):
|
||||||
@ -627,9 +637,9 @@ void SecureSocketImpl::reset()
|
|||||||
close();
|
close();
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
{
|
{
|
||||||
SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
|
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
|
||||||
SSL_free(_pSSL);
|
::SSL_free(_pSSL);
|
||||||
_pSSL = 0;
|
_pSSL = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +665,7 @@ void SecureSocketImpl::useSession(Session::Ptr pSession)
|
|||||||
bool SecureSocketImpl::sessionWasReused()
|
bool SecureSocketImpl::sessionWasReused()
|
||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
return SSL_session_reused(_pSSL) != 0;
|
return ::SSL_session_reused(_pSSL) != 0;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -663,7 +673,7 @@ bool SecureSocketImpl::sessionWasReused()
|
|||||||
|
|
||||||
int SecureSocketImpl::onSessionCreated(SSL* pSSL, SSL_SESSION* pSession)
|
int SecureSocketImpl::onSessionCreated(SSL* pSSL, SSL_SESSION* pSession)
|
||||||
{
|
{
|
||||||
void* pEx = SSL_get_ex_data(pSSL, SSLManager::instance().socketIndex());
|
void* pEx = ::SSL_get_ex_data(pSSL, SSLManager::instance().socketIndex());
|
||||||
if (pEx)
|
if (pEx)
|
||||||
{
|
{
|
||||||
SecureSocketImpl* pThis = reinterpret_cast<SecureSocketImpl*>(pEx);
|
SecureSocketImpl* pThis = reinterpret_cast<SecureSocketImpl*>(pEx);
|
||||||
|
@ -103,7 +103,7 @@ void HTTPSStreamFactoryTest::testError()
|
|||||||
uri.setPort(server.port());
|
uri.setPort(server.port());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::istream* pStr = factory.open(uri);
|
factory.open(uri);
|
||||||
fail("not found - must throw");
|
fail("not found - must throw");
|
||||||
}
|
}
|
||||||
catch (HTTPException& exc)
|
catch (HTTPException& exc)
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "Poco/Net/SecureServerSocket.h"
|
#include "Poco/Net/SecureServerSocket.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
#include "Poco/Thread.h"
|
#include "Poco/Thread.h"
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using Poco::Net::HTTPSClientSession;
|
using Poco::Net::HTTPSClientSession;
|
||||||
using Poco::Net::HTTPRequest;
|
using Poco::Net::HTTPRequest;
|
||||||
@ -55,13 +54,14 @@ namespace
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
|
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
|
||||||
|
Poco::Thread::current()->sleep(handleDelay.totalMilliseconds());
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
ws.sendFrame(pBuffer.get(), n, flags);
|
ws.sendFrame(pBuffer.get(), n, flags);
|
||||||
}
|
}
|
||||||
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
||||||
}
|
}
|
||||||
catch (WebSocketException& exc)
|
catch (const WebSocketException& exc)
|
||||||
{
|
{
|
||||||
switch (exc.code())
|
switch (exc.code())
|
||||||
{
|
{
|
||||||
@ -79,10 +79,17 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Poco::Timespan handleDelay;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t _bufSize;
|
std::size_t _bufSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Poco::Timespan WebSocketRequestHandler::handleDelay {0};
|
||||||
|
|
||||||
|
|
||||||
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -90,7 +97,7 @@ namespace
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
|
Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) override
|
||||||
{
|
{
|
||||||
return new WebSocketRequestHandler(_bufSize);
|
return new WebSocketRequestHandler(_bufSize);
|
||||||
}
|
}
|
||||||
@ -111,6 +118,46 @@ WebSocketTest::~WebSocketTest()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::testWebSocketTimeout()
|
||||||
|
{
|
||||||
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
|
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory, ss, new Poco::Net::HTTPServerParams);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
Poco::Thread::sleep(200);
|
||||||
|
|
||||||
|
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
|
||||||
|
HTTPResponse response;
|
||||||
|
WebSocket ws(cs, request, response);
|
||||||
|
ws.setSendTimeout( Poco::Timespan(2, 0));
|
||||||
|
ws.setReceiveTimeout( Poco::Timespan(2, 0));
|
||||||
|
|
||||||
|
Poco::Timestamp sendStart;
|
||||||
|
char buffer[1024] = {};
|
||||||
|
int flags;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Server will take long to process and cause WS timeout
|
||||||
|
WebSocketRequestHandler::handleDelay.assign(3, 0);
|
||||||
|
|
||||||
|
std::string payload("x");
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
|
||||||
|
failmsg("Data exchange shall time out.");
|
||||||
|
}
|
||||||
|
catch (const Poco::TimeoutException& te)
|
||||||
|
{
|
||||||
|
assertTrue(sendStart.elapsed() < Poco::Timespan(4, 0).totalMicroseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.shutdown();
|
||||||
|
ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WebSocketTest::testWebSocket()
|
void WebSocketTest::testWebSocket()
|
||||||
{
|
{
|
||||||
Poco::Net::SecureServerSocket ss(0);
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
@ -227,6 +274,7 @@ CppUnit::Test* WebSocketTest::suite()
|
|||||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
|
||||||
|
|
||||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
||||||
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketTimeout);
|
||||||
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
|
@ -22,13 +22,14 @@ class WebSocketTest: public CppUnit::TestCase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocketTest(const std::string& name);
|
WebSocketTest(const std::string& name);
|
||||||
~WebSocketTest();
|
~WebSocketTest() override;
|
||||||
|
|
||||||
|
void testWebSocketTimeout();
|
||||||
void testWebSocket();
|
void testWebSocket();
|
||||||
void testWebSocketLarge();
|
void testWebSocketLarge();
|
||||||
|
|
||||||
void setUp();
|
void setUp() override;
|
||||||
void tearDown();
|
void tearDown() override;
|
||||||
|
|
||||||
static CppUnit::Test* suite();
|
static CppUnit::Test* suite();
|
||||||
|
|
||||||
|
@ -159,6 +159,9 @@ public:
|
|||||||
/// If task execution takes longer than the given interval,
|
/// If task execution takes longer than the given interval,
|
||||||
/// further executions are delayed.
|
/// further executions are delayed.
|
||||||
|
|
||||||
|
bool idle() const;
|
||||||
|
/// Returns true if the task queue is empty, otherwise false.
|
||||||
|
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
static TimerTask::Ptr func(const Fn& fn)
|
static TimerTask::Ptr func(const Fn& fn)
|
||||||
/// Helper function template to use a functor or lambda
|
/// Helper function template to use a functor or lambda
|
||||||
@ -188,6 +191,15 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline bool Timer::idle() const
|
||||||
|
{
|
||||||
|
return _queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Util
|
} } // namespace Poco::Util
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,6 +314,28 @@ void TimerTest::testFunc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TimerTest::testIdle()
|
||||||
|
{
|
||||||
|
Timer timer;
|
||||||
|
|
||||||
|
assertTrue (timer.idle());
|
||||||
|
|
||||||
|
Timestamp time;
|
||||||
|
time += 1000000;
|
||||||
|
|
||||||
|
TimerTask::Ptr pTask = new TimerTaskAdapter<TimerTest>(*this, &TimerTest::onTimer);
|
||||||
|
|
||||||
|
timer.schedule(pTask, time);
|
||||||
|
|
||||||
|
assertFalse (timer.idle());
|
||||||
|
|
||||||
|
_event.wait();
|
||||||
|
assertTrue (pTask->lastExecution() >= time);
|
||||||
|
|
||||||
|
assertTrue (timer.idle());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TimerTest::setUp()
|
void TimerTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -346,6 +368,7 @@ CppUnit::Test* TimerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
|
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
|
||||||
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
|
CppUnit_addTest(pSuite, TimerTest, testMultiCancelAllWaitStop);
|
||||||
CppUnit_addTest(pSuite, TimerTest, testFunc);
|
CppUnit_addTest(pSuite, TimerTest, testFunc);
|
||||||
|
CppUnit_addTest(pSuite, TimerTest, testIdle);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
void testCancelAllWaitStop();
|
void testCancelAllWaitStop();
|
||||||
void testMultiCancelAllWaitStop();
|
void testMultiCancelAllWaitStop();
|
||||||
void testFunc();
|
void testFunc();
|
||||||
|
void testIdle();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl>
|
Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl>
|
||||||
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
|
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
|
||||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||||
|
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
@ -1042,7 +1043,7 @@ typedef struct {
|
|||||||
XMLPARSEAPI(const XML_Feature *)
|
XMLPARSEAPI(const XML_Feature *)
|
||||||
XML_GetFeatureList(void);
|
XML_GetFeatureList(void);
|
||||||
|
|
||||||
#if XML_GE == 1
|
#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
|
||||||
/* Added in Expat 2.4.0 for XML_DTD defined and
|
/* Added in Expat 2.4.0 for XML_DTD defined and
|
||||||
* added in Expat 2.6.0 for XML_GE == 1. */
|
* added in Expat 2.6.0 for XML_GE == 1. */
|
||||||
XMLPARSEAPI(XML_Bool)
|
XMLPARSEAPI(XML_Bool)
|
||||||
@ -1065,7 +1066,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
|
|||||||
*/
|
*/
|
||||||
#define XML_MAJOR_VERSION 2
|
#define XML_MAJOR_VERSION 2
|
||||||
#define XML_MINOR_VERSION 6
|
#define XML_MINOR_VERSION 6
|
||||||
#define XML_MICRO_VERSION 0
|
#define XML_MICRO_VERSION 2
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@
|
|||||||
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||||
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
|
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
|
||||||
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
|
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
|
||||||
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
|
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
|
||||||
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
|
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
|
||||||
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
|
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
|
||||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||||
|
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
@ -155,14 +156,20 @@ extern "C" {
|
|||||||
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
|
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
|
||||||
const char **fromLimRef);
|
const char **fromLimRef);
|
||||||
|
|
||||||
#if XML_GE == 1
|
#if defined(XML_GE) && XML_GE == 1
|
||||||
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
|
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
|
||||||
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
|
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
|
||||||
const char *unsignedCharToPrintable(unsigned char c);
|
const char *unsignedCharToPrintable(unsigned char c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
|
extern
|
||||||
extern unsigned int g_parseAttempts; // used for testing only
|
#if ! defined(XML_TESTING)
|
||||||
|
const
|
||||||
|
#endif
|
||||||
|
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
|
||||||
|
#if defined(XML_TESTING)
|
||||||
|
extern unsigned int g_bytesScanned; // used for testing only
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* 628e24d4966bedbd4800f6ed128d06d29703765b4bce12d3b7f099f90f842fc9 (2.6.0+)
|
/* 2a14271ad4d35e82bde8ba210b4edb7998794bcbae54deab114046a300f9639a (2.6.2+)
|
||||||
__ __ _
|
__ __ _
|
||||||
___\ \/ /_ __ __ _| |_
|
___\ \/ /_ __ __ _| |_
|
||||||
/ _ \\ /| '_ \ / _` | __|
|
/ _ \\ /| '_ \ / _` | __|
|
||||||
@ -38,7 +38,7 @@
|
|||||||
Copyright (c) 2022 Jann Horn <jannh@google.com>
|
Copyright (c) 2022 Jann Horn <jannh@google.com>
|
||||||
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
||||||
Copyright (c) 2023 Owain Davies <owaind@bath.edu>
|
Copyright (c) 2023 Owain Davies <owaind@bath.edu>
|
||||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
@ -217,7 +217,7 @@ typedef char ICHAR;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Round up n to be a multiple of sz, where sz is a power of 2. */
|
/* Round up n to be a multiple of sz, where sz is a power of 2. */
|
||||||
#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
|
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
|
||||||
|
|
||||||
/* Do safe (NULL-aware) pointer arithmetic */
|
/* Do safe (NULL-aware) pointer arithmetic */
|
||||||
#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
|
#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
|
||||||
@ -255,7 +255,7 @@ static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
|
|||||||
it odd, since odd numbers are always relative prime to a power of 2.
|
it odd, since odd numbers are always relative prime to a power of 2.
|
||||||
*/
|
*/
|
||||||
#define SECOND_HASH(hash, mask, power) \
|
#define SECOND_HASH(hash, mask, power) \
|
||||||
((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
|
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
|
||||||
#define PROBE_STEP(hash, mask, power) \
|
#define PROBE_STEP(hash, mask, power) \
|
||||||
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
|
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
|
||||||
|
|
||||||
@ -636,8 +636,14 @@ static unsigned long getDebugLevel(const char *variableName,
|
|||||||
? 0 \
|
? 0 \
|
||||||
: ((*((pool)->ptr)++ = c), 1))
|
: ((*((pool)->ptr)++ = c), 1))
|
||||||
|
|
||||||
XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c
|
#if ! defined(XML_TESTING)
|
||||||
unsigned int g_parseAttempts = 0; // used for testing only
|
const
|
||||||
|
#endif
|
||||||
|
XML_Bool g_reparseDeferralEnabledDefault
|
||||||
|
= XML_TRUE; // write ONLY in runtests.c
|
||||||
|
#if defined(XML_TESTING)
|
||||||
|
unsigned int g_bytesScanned = 0; // used for testing only
|
||||||
|
#endif
|
||||||
|
|
||||||
struct XML_ParserStruct {
|
struct XML_ParserStruct {
|
||||||
/* The first member must be m_userData so that the XML_GetUserData
|
/* The first member must be m_userData so that the XML_GetUserData
|
||||||
@ -1035,7 +1041,9 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
|
|||||||
return XML_ERROR_NONE;
|
return XML_ERROR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_parseAttempts += 1;
|
#if defined(XML_TESTING)
|
||||||
|
g_bytesScanned += (unsigned)have_now;
|
||||||
|
#endif
|
||||||
const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
|
const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
|
||||||
if (ret == XML_ERROR_NONE) {
|
if (ret == XML_ERROR_NONE) {
|
||||||
// if we consumed nothing, remember what we had on this parse attempt.
|
// if we consumed nothing, remember what we had on this parse attempt.
|
||||||
@ -6250,7 +6258,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
|||||||
dtd->keepProcessing = dtd->standalone;
|
dtd->keepProcessing = dtd->standalone;
|
||||||
goto endEntityValue;
|
goto endEntityValue;
|
||||||
}
|
}
|
||||||
if (entity->open) {
|
if (entity->open || (entity == parser->m_declEntity)) {
|
||||||
if (enc == parser->m_encoding)
|
if (enc == parser->m_encoding)
|
||||||
parser->m_eventPtr = entityTextPtr;
|
parser->m_eventPtr = entityTextPtr;
|
||||||
result = XML_ERROR_RECURSIVE_ENTITY_REF;
|
result = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||||
@ -7797,6 +7805,8 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
|
|||||||
|
|
||||||
static float
|
static float
|
||||||
accountingGetCurrentAmplification(XML_Parser rootParser) {
|
accountingGetCurrentAmplification(XML_Parser rootParser) {
|
||||||
|
// 1.........1.........12 => 22
|
||||||
|
const size_t lenOfShortestInclude = sizeof("<!ENTITY a SYSTEM 'b'>") - 1;
|
||||||
const XmlBigCount countBytesOutput
|
const XmlBigCount countBytesOutput
|
||||||
= rootParser->m_accounting.countBytesDirect
|
= rootParser->m_accounting.countBytesDirect
|
||||||
+ rootParser->m_accounting.countBytesIndirect;
|
+ rootParser->m_accounting.countBytesIndirect;
|
||||||
@ -7804,7 +7814,9 @@ accountingGetCurrentAmplification(XML_Parser rootParser) {
|
|||||||
= rootParser->m_accounting.countBytesDirect
|
= rootParser->m_accounting.countBytesDirect
|
||||||
? (countBytesOutput
|
? (countBytesOutput
|
||||||
/ (float)(rootParser->m_accounting.countBytesDirect))
|
/ (float)(rootParser->m_accounting.countBytesDirect))
|
||||||
: 1.0f;
|
: ((lenOfShortestInclude
|
||||||
|
+ rootParser->m_accounting.countBytesIndirect)
|
||||||
|
/ (float)lenOfShortestInclude);
|
||||||
assert(! rootParser->m_parentParser);
|
assert(! rootParser->m_parentParser);
|
||||||
return amplificationFactor;
|
return amplificationFactor;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user