diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 0086fa7b7..000000000 --- a/CHANGES +++ /dev/null @@ -1,11822 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - - Changelog - -Version 8.9.1 (31 Jul 2024) - -Daniel Stenberg (31 Jul 2024) - -- RELEASE-NOTES: synced - -- THANKS: add names from the 8.9.1 release notes - - Also remove duplicates - -Stefan Eissing (30 Jul 2024) - -- x509asn1: unittests and fixes for gtime2str - - Fix issues in GTime2str() and add unit test cases to verify correct - behaviour. - - Follow-up to 3c914bc6801 - - Closes #14316 - -Tal Regev (30 Jul 2024) - -- vtls: avoid forward declaration in MultiSSL builds - - The MSVC compiler cannot have forward declaration with const and static - variable, causing this error: - ``` - curl\lib\vtls\vtls.c(417,44): warning C4132: 'Curl_ssl_multi': const object s - hould be initialized - ``` - - Ref: #14276 - Closes #14305 - -Viktor Szakats (30 Jul 2024) - -- tidy-up: URL updates (one more) - - Follow-up to 767d5811b5c783b42cea999dd42ecf0453085d17 #14318 - -- tidy-up: URL updates - - Closes #14318 - -- cmake: drop `if(PKG_CONFIG_FOUND)` guard for `pkg_check_modules()` - - The oldest cmake supported by curl is v3.7.0, which already has such - guard (using `PKG_CONFIG_EXECUTABLE`) inside `pkg_check_modules()`. The - advantage of leaving that guard to CMake is that it will define/reset - all output variables, while the manual guard doesn't do this and also - leaves for example `NETTLE_FOUND` undefined. - - Delete the single use of this guard from the recently added `nettle` - detection, where I included it by accident. Then possibly re-introduce - it universally if we find it useful after more evaluation. - - Follow-up to 669ce42275635dc1f881dab3dfc9a55c9ab49b21 #14285 - Closes #14309 - -Daniel Stenberg (30 Jul 2024) - -- mailmap: dedupe an author showing up twice in shortlog -s - -Ivan Kuchin (30 Jul 2024) - -- misc: cleanup after removing years from copyright - - - remove leftover copyright years from few test files - - fix email in copyright lines - - consistent format of copyright lines - - Closes #14312 - -Alex Snast (30 Jul 2024) - -- wolfssl: avoid calling get_cached_x509_store if store is uncachable - - There's no need for get_cached_x509_store call if the return value won't - be used for caching anyway. - - Closes #14306 - -Daniel Stenberg (30 Jul 2024) - -- contrithanks.sh: use -F with -v to match lines as strings - - Makes names involving [brackets] work. - -Viktor Szakats (30 Jul 2024) - -- GHA/non-native: bump FreeBSD/arm64 python modules - - FreeBSD seems to upgrade their Python separately for arm64 - and Intel. Today, arm64 caught up with the Intel packages. - Update our CI to reflect it. - - Closes #14310 - -dependabot[bot] (30 Jul 2024) - -- GHA: bump github/codeql-action and msys2/setup-msys2 - - - bump github/codeql-action from 3.25.13 to 3.25.15 - - Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3. - 25.13 to 3.25.15. - - [Release notes](https://github.com/github/codeql-action/releases) - - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - - [Commits](https://github.com/github/codeql-action/compare/2d790406f505036ef - 40ecba973cc774a50395aac...afb54ba388a7dca6ecae48f608c4ff05ff4cc77a) - - --- - updated-dependencies: - - dependency-name: github/codeql-action - dependency-type: direct:production - update-type: version-update:semver-patch - ... - - Signed-off-by: dependabot[bot] - Closes #14300 - - - bump msys2/setup-msys2 from 2.23.0 to 2.24.0 - - Bumps [msys2/setup-msys2](https://github.com/msys2/setup-msys2) from 2.23.0 t - o 2.24.0. - - [Release notes](https://github.com/msys2/setup-msys2/releases) - - [Changelog](https://github.com/msys2/setup-msys2/blob/main/CHANGELOG.md) - - [Commits](https://github.com/msys2/setup-msys2/compare/d0e80f58dffbc64f6a3a - 1f43527d469b4fc7b6c8...5df0ca6cbf14efcd08f8d5bd5e049a3cc8e07fd2) - - --- - updated-dependencies: - - dependency-name: msys2/setup-msys2 - dependency-type: direct:production - update-type: version-update:semver-minor - ... - - Signed-off-by: dependabot[bot] - Closes #14301 - -Daniel Stenberg (30 Jul 2024) - -- x509asn1: clean up GTime2str - - Co-authored-by: Stefan Eissing - Reported-by: Dov Murik - - Closes #14307 - -- tool_operate: more defensive socket code - - - use 'struct sockaddr' to getsockname() and its sa_family member - - - use 'curl_socklen_t' instead of 'socklen_t' - - - check for AF_INET6 to exist instead assuming it does - - Should be generally more portable. - - Reported-by: Harry Sintonen - Closes #14304 - -Viktor Szakats (29 Jul 2024) - -- configure: limit `__builtin_available` test to Darwin - - This feature test always fails on non-Apple systems. (For Apple targets - it's supported by llvm and Apple clang.) - - Syncs behaviour with CMake. - - Follow-up to cfd6f43d6ca7e57670b422bab7bbf10221a2cf3e #14127 - Cherry-picked from #14097 - Closes #14196 - -Daniel Stenberg (29 Jul 2024) - -- RELEASE-NOTES: synced - -- CURLOPT_SSL_CTX_FUNCTION.md: mention CA caching - - and add a few more see-also - - Closes #14302 - -Viktor Szakats (29 Jul 2024) - -- cmake: detect `libssh` via `pkg-config` - - Also: - - fix broken libssh `pkg-config` behaviour on old Linux. - (when found, `LIBSSH_LINK_LIBRARIES` remains undefined.) - - - delete manual libssh config from Old Linux CI job, - it's no longer necessary. - - Closes #14199 - -- GHA/non-native: improve, migrate x86_64 FreeBSD with tests from Cirrus CI - - - run tests via `make test-ci` instead of `make check` with autotools. - - add `x86_64` job for FreeBSD, with tests. - It matches the existing Cirrus CI job, with these differences: - - finishes 3x faster (thanks to parallel tests enabled). - - librtmp is not enabled because it's slated for removal by FreeBSD. - (already past the removal deadline, thought the package still - installs.) - - DICT and TELNET servers fail to start. Couldn't figure out why. - It means skipping test 1450 and 1452. - - it runs more tests, e.g. websockets and ip6-localhost. - - no `pkg update -f`. - - it misses the `CRYPTOGRAPHY_DONT_BUILD_RUST=1`, `pkg delete curl`, - `chmod 777`, `sudo -u nobody` and `sysctl net.inet.tcp.blackhole` - tricks. The latter is the default in these runners, the others did - not affect results. - - set `-j0` for tests in the NetBSD job. Flaky otherwise. - - Closes #14244 - -- cmake: detect `nettle` when building with GnuTLS - - `nettle` is a direct dependency of curl, when building with GnuTLS. - Add a new `Find` module to detect it. - - Also: - - GHA/macos: drop `nettle` hack no longer necessary. - - add `nettle` to `libcurl.pc`. - - also add `nettle` to `libcurl.pc` in autotools builds. - - Follow-up to 781242ffa44a9f9b95b6da5ac5a1bf6372ec6257 #11967 - Closes #14285 - -- macos: fix Apple SDK bug workaround for non-macOS targets - - Turns out that MAC != OSX, despite what these names otherwise mean and - what's suggested by source code comments. "MAC" in fact means Darwin - (aka Apple), not macOS. "OSX" means macOS. - - GitHub bumped the macos-14 runner default to Xcode 15.4, hitting the - llvm@15 incompatibility bug by default. Meaning the previous workaround - for the SDK bug is necessary. - - This patch extend the workaround to not apply to mobile OS variants. - - Follow-up to ff784af461175584c73e7e2b65af00b1a5a6f67f #14159 - Reported-by: Sergey - Confirmed-by: Marcel Raad - Fixes #14269 - Closes #14275 - -Stefan Eissing (29 Jul 2024) - -- wolfssl: CA store share fix - - When sharing the x509 store in wolfSSL, always use an explicitly - constructed one, as the SSLCTX might have "only" an internal one which - is not obeying reference count lifetimes. - - Fixes #14278 - Reported-by: Alex Snast - Closes #14279 - -Randall S. Becker (29 Jul 2024) - -- curl: support __ss_family use on NonStop platforms - - The definition of sockaddr_storage incorrectly specifies the ss_family - field as __ss_family. This fix conditionally allows builds to succeed on - all NonStop platforms. - - Signed-off-by: Randall S. Becker - - Closes #14273 - -Daniel Stenberg (29 Jul 2024) - -- test993: list 1000 messages over POP3 - - Attempt to verify issue #14201 - - Closes #14297 - -Stefan Eissing (29 Jul 2024) - -- connect: fix connection shutdown for event based processing - - connections being shutdown would register sockets for events, but then - never remove these sockets again. Nor would the shutdown effectively - been performed. - - - If a socket event involves a transfer, check if that is the - connection cache internal handle and run its multi_perform() - instead (the internal handle is used for all shutdowns). - - When a timer triggers for a transfer, check also if it is - about the connection cache internal handle. - - During processing shutdowns in the connection cache, assess - the shutdown timeouts. Register a Curl_expire() of the lowest - value for the cache's internal handle. - - Reported-by: Gordon Parke - Fixes #14280 - Closes #14296 - -Daniel Stenberg (29 Jul 2024) - -- tests: provide FTP directory contents in the test file - - Instead of providing a fixed single synthetic response in the test - server itself. To allow us to better use *different* directory listings - in different test cases. In this change, most listings remain the same - as before. - - The wildcard match tests still use synthetic responses but we should fix - that as well. - - Updated numerous test cases to use this. - - Closes #14295 - -- ftpserver.pl: make POP3 LIST serve content from the test file - - instead of a fixed list in the test server. - - Adjust test 853 accordingly. - - Closes #14293 - -- TODO: thread-safe sharing - -- CURLSHOPT_SHARE.md: mention sessions/cookies as not thread-safe - - Sharing of these between threads are apparently also not done safely. - - Ref: #14290 - Reported-by: Aki Sakurai - Closes #14292 - -- RELEASE-NOTES: synced - -Patrick Monnerat (28 Jul 2024) - -- os400: build cli manual. - - Use PASE perl to run manual generation scripts. - - As PASE perl is not aware of all possible input file encoding, convert - all files to UTF-8 upon build start (this might be lengthy). - - OS/400 terminal emulation may only offer 76 columns, thus a new -c - parameter has been added to the managen program, defining the allowed - width. - - If perl is not available, omit generation and disable online manual. - - Closes #14289 - -Daniel Stenberg (27 Jul 2024) - -- example/multi-uv: remove the use of globals - - - shows how to pass on local variables (better) - - - start the transfers nicer (with curl_multi_socket_action) - - - consistent and helpful function naming - to better show what functions - and callbacks that are used for what - - - build warning-free with gcc -W -Wall -pedantic - - Closes #14287 - -Viktor Szakats (27 Jul 2024) - -- runtests: fold timing details with GHA, sync `-r` tflags - - - move timing details into a foldable group when run in GitHub Actions. - Spec: - https://docs.github.com/en/actions/using-workflows/workflow-commands-for-gi - thub-actions#grouping-log-lines - - - enable `-r` (run time stats) option in autotools' `test-ci` target, - syncing it with cmake. - - Closes #14284 - -- GHA/windows: increase timeout for vcpkg build step [ci skip] - - Examples: - https://github.com/curl/curl/actions/runs/10102112253/job/27937088909?pr=1427 - 4 - https://github.com/curl/curl/actions/runs/10102112253/job/27937082353?pr=1427 - 4 - https://github.com/curl/curl/actions/runs/10102112253/job/27937088478?pr=1427 - 4 - -- GHA/macos: update comment about default Xcode on macos-14 runner [ci skip] - - New default since: - https://github.com/actions/runner-images/blob/releases/macos-14-arm64/2024072 - 2/images/macos/macos-14-arm64-Readme.md - -Patrick Monnerat (27 Jul 2024) - -- os400: workaround an IBM ASCII run-time library bug - - IBM-provided ASCII function puts() does not output an expected trailing - newline: emulate the correct behavior using other functions. - - Closes #14281 - -Stefan Eissing (27 Jul 2024) - -- transfer: speed limiting fix for 32bit systems - - When checking if a speed limit on receives applies, compare the receive - sizes using the large int type to prevent an overflow on systems where - size_t is 32bit. - - Fixes #14272 - Reported-by: Mamoru Tasaka - Closes #14277 - -Anthony Hu (26 Jul 2024) - -- wolfSSL: allow wolfSSL's implementation of kyber to be used - - Closes #14268 - -Daniel Stenberg (26 Jul 2024) - -- lib: survive some NULL input args - - The input string pointer to: - - curl_escape - curl_easy_escape - curl_unescape - curl_easy_unescape - - The running_handles pointer to: - - curl_multi_perform - curl_multi_socket_action - curl_multi_socket_all - curl_multi_socket - - Reported-by: icy17 on github - Fixes #14247 - Closes #14262 - -- RELEASE-PROCEDURE.md: restore next release date - - Pointed-out-by: extrimexxx on github - Bug: https://github.com/curl/curl/pull/14267#issuecomment-2247062235 - -- RELEASE-NOTES: synced - - bumped to 8.9.1 - -- RELEASE-PROCEDURE.md: remove the initial build step - - Because it is no longer needed to be done by a person as the dmaketgz - script does it by itself. - - Removed two past release dates, added two new future ones - - Closes #14267 - -Version 8.9.0 (24 Jul 2024) - -Daniel Stenberg (24 Jul 2024) - -- RELEASE-NOTES: synced - -- THANKS: updates from the 8.9.0 release - -- curl_easy_escape.md: move historic details to HISTORY - - Closes #14261 - -- docs/libcurl: add to cleanup docs that their inputs go invalid - - Reported-by: icy17 on github - Fixes #14248 - Closes #14258 - -dependabot[bot] (23 Jul 2024) - -- GHA: bump github/codeql-action from 3.25.11 to 3.25.13 - - Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3. - 25.11 to 3.25.13. - - [Release notes](https://github.com/github/codeql-action/releases) - - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - - [Commits](https://github.com/github/codeql-action/compare/b611370bb5703a7ef - b587f9d136a52ea24c5c38c...2d790406f505036ef40ecba973cc774a50395aac) - - --- - updated-dependencies: - - dependency-name: github/codeql-action - dependency-type: direct:production - update-type: version-update:semver-patch - ... - - Signed-off-by: dependabot[bot] - Closes #14255 - -Stefan Eissing (23 Jul 2024) - -- conncache: connection shutdown, multi_socket handling - - - implement the socket hash user/reader/writer processing also - for connections that are being shut down by the connection cache. - - split out handling of current vs. last pollset socket event handling - into a function available in other code parts - - add `shutdown_poll` pollset to `connectdata` struct so that changes - in the pollset can be recorded during shutdown. (The internal handle - cannot keep it since it might be used for many connections) - - Reported-by: calvin2021y on github - Fixes #14252 - Closes #14257 - -Daniel Stenberg (22 Jul 2024) - -- tool_cb_prg: output "flying saucers" with leading carriage return - - Because that is how the progress-bar is output, so when the progress-bar - has been shown at least once and the information is reset, like for a - redirect, there might be a moment where the size goes from known to - unknown and then the flying saucerts are shown after a brief display of - the progress-bar. - - It could previously cause accidental character leftovers on the right - side of the bar when using a narrow display. - - Reported-by: Chris Webb - Fixes #14213 - Closes #14246 - -- lib: Curl_posttransfer => multi_posttransfer - - Moved from transfer.c to multi.c as it was only used within multi.c - - Made a void, as it returned a fixed return code nothing checked. - - Closes #14240 - -- CURLOPT_SSL_VERIFYHOST.md: refresh - - Move mentions of old behavior to the HISTORY section to make it easier - to read about modern behavior. - - Added a MATCHING section. - - Closes #14241 - -- multi: do a final progress update on connect failure - - To fix timing metric etc - - Co-authored-by: Justin Maggard - Fixes #14204 - Closes #14239 - -Orgad Shaneh (19 Jul 2024) - -- md4: fix compilation with OpenSSL 1.x with md4 disabled - - If OpenSSL 1.x is used, and it is configured with md4 disabled, - OPENSSL_NO_MD4 is defined in opensslconf.h, but this header was not - included before checking for this define. - - Later in md4.c, openssl/md4.h is included, and it includes that header - indirectly, leading to inconsistency within md4.c. - - Since the md4.h branch was taken, wincrypt.h (or others) is not - included, and later below the USE_WIN32_CRYPTO branch is taken, but the - types are not defined. - - Closes #14218 - -martinevsky (19 Jul 2024) - -- ftp: remove redundant null pointer check in loop condition - - Closes #14234 - -Justin Maggard (19 Jul 2024) - -- mbedtls: check version before getting tls version - - mbedtls_ssl_get_version_number() was added in mbedtls 3.2.0. Check for - that version before using it. - - Closes #14228 - -martinevsky (19 Jul 2024) - -- urlapi: remove unused definition of HOST_BAD - - Closes #14235 - -Daniel Stenberg (19 Jul 2024) - -- curldown: fixups - - - make DEFAULT sections less repetitive - - - make historic mentions use HISTORY - - - generate the protocols section on `# %PROTOCOLS%` instead of guessing - where to put it - - - generate the availability section on `# %AVAILABILITY%` instead of - guessing where to put it - - - make the protocols section more verbose - - Closes #14227 - -Tal Regev (19 Jul 2024) - -- GHA/windows: enable libssh in !ssl MSVC job - - Closes #14232 - -- GHA/windows: enable libidn2 in !ssl MSVC job - - Closes #14200 - -Viktor Szakats (19 Jul 2024) - -- GHA/macos: improve, fix gcc/llvm, add new test matrix - - This PR began as an attempt to drop GCC support, after repeated reports - on fallouts when trying to use it on macOS. - - Then it transformed into a 3-week project turning up the issues causing - the fallouts, ending up including llvm and all available Xcode / macOS - SDK, macOS runner image, build tools and compiler vendors and versions. - Accumulating 400 sub-commits. - - I developed and tested all fixes under this PR, then merged them as - separate patches. - - This PR retained CI jobs updates, extensively reworking and extending - them: [1] - - At first it seemed GCC and the Apple SDK is "naturally" growing more - incompatible, as Apple added further non-standard features to their - headers. This is partly true, but reality is more complicated. - - Besides some issues local to curl, there were bugs in Apple SDK - headers, Homebrew GCC builds, feature missing in the old llvm version - pre-installed on GitHub CI runner images, and subtle incompatibilities - between GCC and llvm/clang when handling language extensions. - - Resulting compiler errors seldom pointed to a useful direction, and - internet search was silent about these issues too. Thus, I had to peel - them off layer by layer, using trial and error, and by recognizing - patterns of failures accross 150-200 builds combinations. Exposing - configure logs, and curl_config.h in the CI logs helped too. - - 1. GCC header compatibility layer ("hack" as GCC calls it) - - The toughest issue is GCC's built-in compatibility layer: - https://github.com/gcc-mirror/gcc/tree/master/fixincludes - - This patch layer is further patched by a "Darwin compatibility" project - applied on top by Homebrew GCC via: - https://github.com/iains/gcc-12-branch - https://github.com/iains/gcc-13-branch - https://github.com/iains/gcc-14-branch - - The hack layer is designed in a way that breaks more builds than it - fixes, esp. in context of GHA runners. The idea is to build GCC - specifically for the SDK for the target macOS version. The problem with - this approach is that the Xcode + SDK installed on the local/CI machine - often does not match with the SDK used on while building GCC on - Homebrew's build machines. In these cases the GCC compatibility layer - turns into an "uncompatibility" layer and consistently breaks builds. - curl cannot offer a fix for this, because the solution (I found) is to - patch the toolchain on the local machine. I implemented this for our CI - builds and curl-for-win. In other case the user must do this patching - manually, or choose a compatible GCC + Xcode/SDK combination. - - An upstream fix doesn't seem trivial either, because the issue is - ingrained in the compatibility layer's design. Offering an `-fapplesdk` - (or recognizing `-target`) option and/or fixing them within the compiler - would seem like a more robust option, and also how mainline llvm solves - this. - - Here's a table summarizing the GCC + SDK combinations and curl build - failures: [2] - - More info: https://github.com/curl/curl/issues/10356#issuecomment-2222734103 - - db135f8d7207b20d531e7e2100a49f3e16bdcfab #14119 macos: add workaround for gcc - , non-c-ares, IPv6, compile error - Ref: https://github.com/curl/curl-for-win/commit/e2db3c475f5981352e6e6a79854a - 255805b28deb - Ref: https://github.com/curl/curl-for-win/commit/f5c58d7fef78e972be33ca2355dc - b42ba56622a6 - - 2. Homebrew GCC's `availability` extension - - A recent minor Homebrew GCC upgrade caused major breakage. The "Darwin - compatibility" patch applied to GCC implemented the `availability` - compiler attribute in GCC. Apple SDK detected this and enabled using - them, but as it turns out GCC accepts compiler attributes with slightly - different rules than llvm/clang, and how the Apple SDK uses them, - breaking builds. - - Affected Homebrew GCC versions are: 12.4.0, 13.3.0 and 14.1.0. - - Possibly tracked here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796 - More info: https://github.com/llvm/llvm-project/issues/81767 - - Commit implementing the `availability` macro: - gcc-12: https://github.com/iains/gcc-12-branch/commit/fd5530b7cb0012bf4faeddd - 45e13054a1dfa6783 - gcc-13: https://github.com/iains/gcc-13-branch/commit/cb7e4eca68cfc4763474e2e - b0935a844458842a8 - gcc-14: https://github.com/iains/gcc-14-branch/commit/ff62a108865a6403f501738 - 0d7018250c1d3306f - - That applied to Homebrew GCC (12.4.0): - https://github.com/Homebrew/homebrew-core/commit/b904223d9893f62bec2a8f7483bf - 5992747fc6c7#diff-89dd0b4176eca7fcc24b591943509bf8a8d6ea904d71e5dfcd6b78fed62 - fc574R44-R48 - - Ref: #13700 - More info: https://github.com/curl/curl/pull/14091#issuecomment-2222703468 - - e91fcbac7d86292858718a0bfebad57978761af4 #14155 macos: undo `availability` ma - cro enabled by Homebrew gcc - - 3. Proprietary Apple SDK macros - - Apple SDK expects certain macros predefined by the compiler. Missing - them may causes odd issues. Mainline llvm is keeping up with Apple - clang, but it needs a fresh version, while the one installed on GitHub - runners is old (v15). I patched these in `lib/curl_setup.h`. - - baa3270846b2a7307cbd0dd5c02c4e5f00e388dd #14134 build: fix llvm 16 or older + - Xcode 15 or newer, and gcc - - 4. Apple SDK header bug - - Without certain predefined macros, SDK headers can take a codepath where - it mis-defines its own `TARGET_OS_OSX` macro, which make it break its - own headers later. I patched it in `lib/curl_setup.h`. - - ff784af461175584c73e7e2b65af00b1a5a6f67f #14159 build: fix llvm 17 and older - + macOS SDK 14.4 and newer - - 5. `TargetConditionals.h` requires `sys/types.h` - - Fixed in curl. It caused feature-detection failurs with autotools, and - could break builds in certain configurations. - - e1f6192939c9c5ab2310b60bedf4c07d635193f6 #14130 configure: fix `SystemConfigu - ration` detection - - 6. Differences between autotools and CMake compiler options - - Fixed it by syncing compiler warning options. - - 59cadacfcc1d39472245979cdbd614c7a9af6f0d #14128 build: sync warning options b - etween autotools, cmake & compilers - - 7. Differences between autotools and CMake dependency detection - - Fixed it by improving detection of libidn2, with some more fixes - pending for the next feature window. - - f43adc2c4978f7f82a359e89186e58a31d17b0ad #14137 cmake: detect `libidn2` also - via `pkg-config` - Ref: #14136 cmake: detect `nghttp2` via `pkg-config`, enable by default - - 8. libidn2 detection bug with CMake - - Fixed the root cause and also the trigger in the CI config. - - 764fbabf6ed4c1d36c0ab2033ac8df52d9923cd7 #14175 cmake: fix builds with detect - ed libidn2 lib but undetected header - - 9. Suppressed compiler warnings inside Apple-specific curl code - - Fixed these warnings, which allowed to stop silencing them. - - b05dc7eb3592305de9fa85640767f3dd2a8d4c93 #14122 sectransp: fix `HAVE_BUILTIN_ - AVAILABLE` checks to not emit warnings - 5fa534b0dacdc120aaab0766047e0ecac37be4b3 #14162 sectransp: fix clang compiler - warnings, stop silencing them - - 10. CMake mis-detecting a CA bundle path on macOS - - d2ef6255f4a040397d2f40ab7cbf65a203201cd9 #14182 cmake: sync CA bundle/path de - tection with autotools - - 11. Failure to build tests with LibreSSL or wolfSSL with CMake - - Fixed by dropping unnecessary includes, makign test builds dependent - on dependency headers. - - 3765d75ce47b66289f946382b649d0e99389dc77 #14172 cmake: fix building `unit1600 - ` due to missing `ssl/openssl.h` - - 12. curl tests with CMake - - curl's CMake was missing bits for running the C preprocessor accurately. - It made tests 1119 and 1167 fail. I implemented the missing bits. - - efc2c5184d008fe2e5910fd03263e1ab0331d4e6 #14124 tests: include current direct - ory when running test Perl commands - c09db8b51b88ee6ad55bd637dcb4b47678e30906 #14129 cmake: create `configurehelp. - pm` like autotools does - 67cc1e3400b77536a3ca529c986247e1ef985e6e #14125 test1119: adapt for `.md` inp - ut - - 13. GCC missing `__builtin_available()` support - - curl source code assumes this is available to enable certain codepaths. - It's also intermixed with monotonic timer support. - - 14. Monotonic timer support with GCC - - Detected by GCC, while it probably shouldn't be. llvm/clang detects it - depending on target OS version. I've been playing with this, but so far - without a conclusion or fix. - - 15. Runtime/test failures with GCC - - I couldn't find the reason for most of this. A bunch of RTSP tests fail - with GCC. SecureTransport + HTTP/2 is failing a bunch of tests. With - OpenSSL it fails two of those. SecureTransport builds also fail one DoH - test. - - 16. Runtime/test failure in llvm/clang - - AppleIDN support received a fix with two more remaining. - - fd0250869f7837e4a48d7e6f54cc0801ad3820e8 #14179 #14176 IDN: fix ß with Apple - IDN - - 17. Other issues found and fixed while working on this: - - 2c15aa5765900d4351e733671a1c8c3785beee1a GHA/macos: delete misplaced ` - CFLAGS`, drop redundant CMake option - 80fb7c0bef209735ab352bf4afa31193a7bc65f1 #14126 configure: limit `SystemConfi - guration` test to non-c-ares, IPv6 builds - cfd6f43d6ca7e57670b422bab7bbf10221a2cf3e #14127 build: tidy up `__builtin_ava - ilable` feature checks (Apple) - bae555359979016999a9425a2d489f219a78abdd #14174 runtests: show name and keywo - rds for failed tests in summary - 09cdf7e5315711dea4ce7dcf5d99a4d41e7f658b #14178 cmake: delete unused `HAVE_LI - BSSH2`, `HAVE_LIBSOCKET` macros - d3595c74fab829f07ef44da1b7fc2f5668767020 #14186 configure: CA bundle/path det - ection fixes - 58772b0e082eda333e0a5fc8fb0bc7f17a3cd99c #14187 runtests: set `SOURCE_DATE_EP - OCH` to fix failing around midnight - 18f1cd7a77c4beecfd977d43f55634eb593ac99e #14183 tests: sync feature names wit - h `curl -V` - 4c22d97be786ed801e050da6872dd3143d6d0a59 #14181 build: use `#error` instead o - f invalid syntax - - Pending merges: - - - #14185 runtests: fold test details for GitHub CI runs - - #14197 cmake: grab-bag of tidy-ups - - #14196 configure: limit `__builtin_available` test to Darwin - - Summary: - - In general GCC doesn't seem to be a good fit with curl and macOS for - now. These "lucky" combinations (GitHub Actions runner) will build out - of the box now: macos-14 + Xcode 15.0.1 + gcc-11, gcc-12, gcc-14. The - rest builds with the ugly workaround in place, but all this still leaves - some runtime issues. - - More info and links in the commit messages and source code. - - [1]: This PR: - - add info about target OS version requirements per feature, with OS - names and release years. - - stop using `-Wno-deprecated-declarations` to suppress warnings. - - use `LDFLAGS=-w` to suppress 'object file was built for newer macOS - version than being linked' warnings. - (there were tens of thousands of them in some jobs) - - allow overriding Xcode version in all jobs. - - improve job names. - - abbreviate CMake as CM, autotools as AM for more compact job names. - - shorten job names by using `!` instead of `no-` and `non-`. - - bump parellel tests to 10 (from 5). - - drop using `--enable-maintainer-mode` `./configure` option. - - add gcc-12 no-ssl, autotools job with tests, ignore failing test - results. (It's not yet clear why gcc-12 builds have different runtime - results than clang/llvm ones.) - - add comments with OS names and release years next to version numbers, - e.g. 10.15 # Catalina (2019) - - fix broken gcc-12 SecureTransport build. - - show compiler, Xcode, SDK, gcc hack SDK versions, Homebrew - preinstalled packages and C compiler predefined macros for each job. - Useful for debugging all the strange problems these builds might have. - - merge brew bundle and install steps. - - move step names to the top. - - dump configure log for both cmake and autotools also for successful - builds. Useful for debugging. - - dump curl_config.h in short (sorted #defines) and full form. - - add support for the mainline llvm compiler. - - set sysroot for gcc and llvm. - - add timeout for cmake jobs. - - add new job matrix: combinations - It supports building all possible compiler, runner image, Xcode/SDK - combinations, with cmake and autotools, target OS versions and with or - without SecureTransport. It's quick. GHA limits the maximum number of - matrix jobs at 256. - I used this as a test-rig to fix the macOS build fallouts with gcc and - llvm. - I settled with 16 jobs, trying to maximize fallout coverage. - - implement hack to make Homebrew gcc work with all available SDKs. - - add handy mini-table about Xcode / SDK versions, OS names, years for - each GHA images, with the defaults. - - add tests for cmake jobs. - - make cmake config hack to link GnuTLS less intrusive. - - stop ignoring test 1452, seems fine now. - - fix to enable libpsl in autotools builds. - - enable libpsl in cmake builds. - - add an llvm job with tests (both autotools and cmake). - - delete similar macOS jobs from Circle CI. GHA is now arm64 too. - - [2]: Homebrew GCC vs GHA runner images vs curl builds: - ``` - macOS Xcode gcc gcc SDK hacks Xcode SDK SDK major Build - Compile - (*def) (Homebrew) (CommandLineTools) versions - error - -------- -------- ---------- ------------------ ---------- --------- ----- - --------------------- - macos-12 13.1 GCC 11.4.0 MacOSX12 MacOSX12.0 - macos-12 13.2.1 GCC 11.4.0 MacOSX12 MacOSX12.1 - macos-12 13.3.1 GCC 11.4.0 MacOSX12 MacOSX12.3 - macos-12 13.4.1 GCC 11.4.0 MacOSX12 MacOSX12.3 - macos-12 14.0.1 GCC 11.4.0 MacOSX12 MacOSX12.3 - macos-12 14.1 GCC 11.4.0 MacOSX12 MacOSX13.0 MISMATCH FAIL - /Applications/Xcode_14.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-12 *14.2 GCC 11.4.0 MacOSX12 MacOSX13.1 MISMATCH FAIL - /Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-13 14.1 GCC 11.4.0 MacOSX13 MacOSX13.0 - macos-13 14.2 GCC 11.4.0 MacOSX13 MacOSX13.1 - macos-13 14.3.1 GCC 11.4.0 MacOSX13 MacOSX13.3 - macos-13 *15.0.1 GCC 11.4.0 MacOSX13 MacOSX14.0 MISMATCH FAIL - /Applications/Xcode_15.0.1.app/Contents/Developer/Platforms/MacOSX.platform/ - Developer/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown - type name 'dispatch_queue_t' - macos-13 15.1 GCC 11.4.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown ty - pe name 'dispatch_queue_t' - macos-13 15.2 GCC 11.4.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown ty - pe name 'dispatch_queue_t' - macos-14 14.3.1 GCC 11.4.0 MacOSX14 MacOSX13.3 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 *15.0.1 GCC 11.4.0 MacOSX14 MacOSX14.0 - macos-14 15.1 GCC 11.4.0 MacOSX14 MacOSX14.2 - macos-14 15.2 GCC 11.4.0 MacOSX14 MacOSX14.2 - macos-14 15.3 GCC 11.4.0 MacOSX14 MacOSX14.4 - macos-14 15.4 GCC 11.4.0 MacOSX14 MacOSX14.5 - macos-14 16.0 GCC 11.4.0 MacOSX14 MacOSX15.0 MISMATCH FAIL - /opt/homebrew/Cellar/gcc@11/11.4.0/lib/gcc/11/gcc/aarch64-apple-darwin23/11/ - include-fixed/stdio.h:83:8: error: unknown type name 'FILE' - macos-12 13.1 GCC 12.4.0 MacOSX12 MacOSX12.0 - macos-12 13.2.1 GCC 12.4.0 MacOSX12 MacOSX12.1 - macos-12 13.3.1 GCC 12.4.0 MacOSX12 MacOSX12.3 - macos-12 13.4.1 GCC 12.4.0 MacOSX12 MacOSX12.3 - macos-12 14.0.1 GCC 12.4.0 MacOSX12 MacOSX12.3 - macos-12 14.1 GCC 12.4.0 MacOSX12 MacOSX13.0 MISMATCH FAIL - /Applications/Xcode_14.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-12 *14.2 GCC 12.4.0 MacOSX12 MacOSX13.1 MISMATCH FAIL - /Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-13 14.1 GCC 12.4.0 MacOSX13 MacOSX13.0 - macos-13 14.2 GCC 12.4.0 MacOSX13 MacOSX13.1 - macos-13 14.3.1 GCC 12.4.0 MacOSX13 MacOSX13.3 - macos-13 *15.0.1 GCC 12.4.0 MacOSX13 MacOSX14.0 MISMATCH FAIL - /Applications/Xcode_15.0.1.app/Contents/Developer/Platforms/MacOSX.platform/ - Developer/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown - type name 'dispatch_queue_t' - macos-13 15.1 GCC 12.4.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown ty - pe name 'dispatch_queue_t' - macos-13 15.2 GCC 12.4.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:103:1: error: unknown ty - pe name 'dispatch_queue_t' - macos-14 14.3.1 GCC 12.4.0 MacOSX14 MacOSX13.3 MISMATCH - macos-14 *15.0.1 GCC 12.4.0 MacOSX14 MacOSX14.0 - macos-14 15.1 GCC 12.4.0 MacOSX14 MacOSX14.2 - macos-14 15.2 GCC 12.4.0 MacOSX14 MacOSX14.2 - macos-14 15.3 GCC 12.4.0 MacOSX14 MacOSX14.4 - macos-14 15.4 GCC 12.4.0 MacOSX14 MacOSX14.5 - macos-14 16.0 GCC 12.4.0 MacOSX14 MacOSX15.0 MISMATCH FAIL - /opt/homebrew/Cellar/gcc@12/12.4.0/lib/gcc/12/gcc/aarch64-apple-darwin23/12/ - include-fixed/stdio.h:83:8: error: unknown type name 'FILE' - macos-12 13.1 GCC 13.3.0 MacOSX12 MacOSX12.0 - macos-12 13.2.1 GCC 13.3.0 MacOSX12 MacOSX12.1 - macos-12 13.3.1 GCC 13.3.0 MacOSX12 MacOSX12.3 - macos-12 13.4.1 GCC 13.3.0 MacOSX12 MacOSX12.3 - macos-12 14.0.1 GCC 13.3.0 MacOSX12 MacOSX12.3 - macos-12 14.1 GCC 13.3.0 MacOSX12 MacOSX13.0 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-12 *14.2 GCC 13.3.0 MacOSX12 MacOSX13.1 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-13 14.1 GCC 13.3.0 MacOSX13 MacOSX13.0 - macos-13 14.2 GCC 13.3.0 MacOSX13 MacOSX13.1 - macos-13 14.3.1 GCC 13.3.0 MacOSX13 MacOSX13.3 - macos-13 *15.0.1 GCC 13.3.0 MacOSX13 MacOSX14.0 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-13 15.1 GCC 13.3.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-13 15.2 GCC 13.3.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 14.3.1 GCC 13.3.0 MacOSX14 MacOSX13.3 MISMATCH FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 *15.0.1 GCC 13.3.0 MacOSX14 MacOSX14.0 FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 15.1 GCC 13.3.0 MacOSX14 MacOSX14.2 FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 15.2 GCC 13.3.0 MacOSX14 MacOSX14.2 FAIL - /Users/runner/work/curl/curl/bld/lib/curl_config.h:792:19: error: two or mor - e data types in declaration specifiers - macos-14 15.3 GCC 13.3.0 MacOSX14 MacOSX14.4 - macos-14 15.4 GCC 13.3.0 MacOSX14 MacOSX14.5 - macos-14 16.0 GCC 13.3.0 MacOSX14 MacOSX15.0 MISMATCH FAIL - /opt/homebrew/Cellar/gcc@13/13.3.0/lib/gcc/13/gcc/aarch64-apple-darwin23/13/ - include-fixed/stdio.h:83:8: error: unknown type name 'FILE' - macos-12 13.1 GCC 14.1.0 MacOSX12 MacOSX12.0 - macos-12 13.2.1 GCC 14.1.0 MacOSX12 MacOSX12.1 - macos-12 13.3.1 GCC 14.1.0 MacOSX12 MacOSX12.3 - macos-12 13.4.1 GCC 14.1.0 MacOSX12 MacOSX12.3 - macos-12 14.0.1 GCC 14.1.0 MacOSX12 MacOSX12.3 - macos-12 14.1 GCC 14.1.0 MacOSX12 MacOSX13.0 MISMATCH FAIL - /Applications/Xcode_14.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-12 *14.2 GCC 14.1.0 MacOSX12 MacOSX13.1 MISMATCH FAIL - /Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/os/object.h:275:1: error: expected ';' be - fore 'extern' - macos-13 14.1 GCC 14.1.0 MacOSX13 MacOSX13.0 - macos-13 14.2 GCC 14.1.0 MacOSX13 MacOSX13.1 - macos-13 14.3.1 GCC 14.1.0 MacOSX13 MacOSX13.3 - macos-13 *15.0.1 GCC 14.1.0 MacOSX13 MacOSX14.0 MISMATCH FAIL - /Applications/Xcode_15.0.1.app/Contents/Developer/Platforms/MacOSX.platform/ - Developer/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:70:1: error: type defa - ults to 'int' in declaration of 'DISPATCH_DECL_FACTORY_CLASS_SWIFT' [-Wimplic - it-int] - macos-13 15.1 GCC 14.1.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.1.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:70:1: error: type defaul - ts to 'int' in declaration of 'DISPATCH_DECL_FACTORY_CLASS_SWIFT' [-Wimplicit - -int] - macos-13 15.2 GCC 14.1.0 MacOSX13 MacOSX14.2 MISMATCH FAIL - /Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/De - veloper/SDKs/MacOSX.sdk/usr/include/dispatch/queue.h:70:1: error: type defaul - ts to 'int' in declaration of 'DISPATCH_DECL_FACTORY_CLASS_SWIFT' [-Wimplicit - -int] - macos-14 14.3.1 GCC 14.1.0 MacOSX14 MacOSX13.3 MISMATCH - macos-14 *15.0.1 GCC 14.1.0 MacOSX14 MacOSX14.0 - macos-14 15.1 GCC 14.1.0 MacOSX14 MacOSX14.2 - macos-14 15.2 GCC 14.1.0 MacOSX14 MacOSX14.2 - macos-14 15.3 GCC 14.1.0 MacOSX14 MacOSX14.4 - macos-14 15.4 GCC 14.1.0 MacOSX14 MacOSX14.5 - macos-14 16.0 GCC 14.1.0 MacOSX14 MacOSX15.0 MISMATCH FAIL - /opt/homebrew/Cellar/gcc/14.1.0_1/lib/gcc/current/gcc/aarch64-apple-darwin23 - /14/include-fixed/stdio.h:83:8: error: unknown type name 'FILE' - ``` - Source: https://github.com/curl/curl/actions/runs/9883956647/job/27299564218 - - This commit fixes earlier commit - 1e75edd372868048c9f805ac4ca6d2cb5a88ff5a, reverted in - 41a7e0dcc9681afd91e066411bcee4f369c23366, where I cut the commit - message in half by accident. The patch itself is identical. - - Closes #14097 - -- Revert "GHA/macos: improve, fix gcc/llvm, add new test matrix" - - This reverts commit 1e75edd372868048c9f805ac4ca6d2cb5a88ff5a. - - Due to some parts of the commit message missing (my bad.) - -Daniel Stenberg (19 Jul 2024) - -- Revert "lib: send eos flag" - - This reverts commit be93299f10ef0b2bf7fe5c82140120073831867a. - -Viktor Szakats (19 Jul 2024) - -- GHA/windows: use default shell CI feature - - It makes repeating a line in each step unnecessary. - - Closes #14206 - -- GHA/macos: improve, fix gcc/llvm, add new test matrix - - This PR began as an attempt to drop GCC support, after repeated reports - on fallouts when trying to use it on macOS. - - Then it transformed into a 3-week project turning up the issues causing - the fallouts, ending up including llvm and all available Xcode / macOS - SDK, macOS runner image, build tools and compiler vendors and versions. - Accumulating 400 sub-commits. - - I developed and tested all fixes under this PR, then merged them as - separate patches. - - This PR retained CI jobs updates, extensively reworking and extending - them: [1] - - At first it seemed GCC and the Apple SDK is "naturally" growing more - incompatible, as Apple added further non-standard features to their - headers. This is partly true, but reality is more complicated. - - Besides some issues local to curl, there were bugs in Apple SDK - headers, Homebrew GCC builds, feature missing in the old llvm version - pre-installed on GitHub CI runner images, and subtle incompatibilities - between GCC and llvm/clang when handling language extensions. - - Resulting compiler errors seldom pointed to a useful direction, and - internet search was silent about these issues too. Thus, I had to peel - them off layer by layer, using trial and error, and by recognizing - patterns of failures accross 150-200 builds combinations. Exposing - configure logs, and curl_config.h in the CI logs helped too. - - 1. GCC header compatibility layer ("hack" as GCC calls it) - - The toughest issue is GCC's built-in compatibility layer: - https://github.com/gcc-mirror/gcc/tree/master/fixincludes - - This patch layer is further patched by a "Darwin compatibility" project - applied on top by Homebrew GCC via: - https://github.com/iains/gcc-12-branch - https://github.com/iains/gcc-13-branch - https://github.com/iains/gcc-14-branch - - The hack layer is designed in a way that breaks more builds than it - fixes, esp. in context of GHA runners. The idea is to build GCC - specifically for the SDK for the target macOS version. The problem with - this approach is that the Xcode + SDK installed on the local/CI machine - often does not match with the SDK used on while building GCC on - Homebrew's build machines. In these cases the GCC compatibility layer - turns into an "uncompatibility" layer and consistently breaks builds. - curl cannot offer a fix for this, because the solution (I found) is to - patch the toolchain on the local machine. I implemented this for our CI - builds and curl-for-win. In other case the user must do this patching - manually, or choose a compatible GCC + Xcode/SDK combination. - - An upstream fix doesn't seem trivial either, because the issue is - ingrained in the compatibility layer's design. Offering an `-fapplesdk` - (or recognizing `-target`) option and/or fixing them within the compiler - would seem like a more robust option, and also how mainline llvm solves - this. - - Here's a table summarizing the GCC + SDK combinations and curl build - failures: [2] - - More info: https://github.com/curl/curl/issues/10356#issuecomment-2222734103 - - db135f8d7207b20d531e7e2100a49f3e16bdcfab #14119 macos: add workaround for gcc - , non-c-ares, IPv6, compile error - Ref: https://github.com/curl/curl-for-win/commit/e2db3c475f5981352e6e6a79854a - 255805b28deb - Ref: https://github.com/curl/curl-for-win/commit/f5c58d7fef78e972be33ca2355dc - b42ba56622a6 - - 2. Homebrew GCC's `availability` extension - - A recent minor Homebrew GCC upgrade caused major breakage. The "Darwin - compatibility" patch applied to GCC implemented the `availability` - compiler attribute in GCC. Apple SDK detected this and enabled using - them, but as it turns out GCC accepts compiler attributes with slightly - different rules than llvm/clang, and how the Apple SDK uses them, - breaking builds. - - Affected Homebrew GCC versions are: 12.4.0, 13.3.0 and 14.1.0. - - Possibly tracked here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796 - More info: https://github.com/llvm/llvm-project/issues/81767 - - Commit implementing the `availability` macro: - gcc-12: https://github.com/iains/gcc-12-branch/commit/fd5530b7cb0012bf4faeddd - 45e13054a1dfa6783 - gcc-13: https://github.com/iains/gcc-13-branch/commit/cb7e4eca68cfc4763474e2e - b0935a844458842a8 - gcc-14: https://github.com/iains/gcc-14-branch/commit/ff62a108865a6403f501738 - 0d7018250c1d3306f - - That applied to Homebrew GCC (12.4.0): - https://github.com/Homebrew/homebrew-core/commit/b904223d9893f62bec2a8f7483bf - 5992747fc6c7#diff-89dd0b4176eca7fcc24b591943509bf8a8d6ea904d71e5dfcd6b78fed62 - fc574R44-R48 - - Ref: #13700 - More info: https://github.com/curl/curl/pull/14091#issuecomment-2222703468 - - e91fcbac7d86292858718a0bfebad57978761af4 #14155 macos: undo `availability` ma - cro enabled by Homebrew gcc - - 3. Proprietary Apple SDK macros - - Apple SDK expects certain macros predefined by the compiler. Missing - them may causes odd issues. Mainline llvm is keeping up with Apple - clang, but it needs a fresh version, while the one installed on GitHub - runners is old (v15). I patched these in `lib/curl_setup.h`. - - baa3270846b2a7307cbd0dd5c02c4e5f00e388dd #14134 build: fix llvm 16 or older + - Xcode 15 or newer, and gcc - - 4. Apple SDK header bug - - Without certain predefined macros, SDK headers can take a codepath where - it mis-defines its own `TARGET_OS_OSX` macro, which make it break its - own headers later. I patched it in `lib/curl_setup.h`. - - ff784af461175584c73e7e2b65af00b1a5a6f67f #14159 build: fix llvm 17 and older - + macOS SDK 14.4 and newer - - 5. `TargetConditionals.h` requires `sys/types.h` - - Fixed in curl. It caused feature-detection failurs with autotools, and - could break builds in certain configurations. - - e1f6192939c9c5ab2310b60bedf4c07d635193f6 #14130 configure: fix `SystemConfigu - ration` detection - - 6. Differences between autotools and CMake compiler options - - Fixed it by syncing compiler warning options. - - 59cadacfcc1d39472245979cdbd614c7a9af6f0d #14128 build: sync warning options b - etween autotools, cmake & compilers - - 7. Differences between autotools and CMake dependency detection - - Fixed it by improving detection of libidn2, with some more fixes - pending for the next feature window. - - f43adc2c4978f7f82a359e89186e58a31d17b0ad #14137 cmake: detect `libidn2` also - via `pkg-config` - Ref: #14136 cmake: detect `nghttp2` via `pkg-config`, enable by default - - 8. libidn2 detection bug with CMake - - Fixed the root cause and also the trigger in the CI config. - - 764fbabf6ed4c1d36c0ab2033ac8df52d9923cd7 #14175 cmake: fix builds with detect - ed libidn2 lib but undetected header - - 9. Suppressed compiler warnings inside Apple-specific curl code - - Fixed these warnings, which allowed to stop silencing them. - - b05dc7eb3592305de9fa85640767f3dd2a8d4c93 #14122 sectransp: fix `HAVE_BUILTIN_ - AVAILABLE` checks to not emit warnings - 5fa534b0dacdc120aaab0766047e0ecac37be4b3 #14162 sectransp: fix clang compiler - warnings, stop silencing them - - 10. CMake mis-detecting a CA bundle path on macOS - - d2ef6255f4a040397d2f40ab7cbf65a203201cd9 #14182 cmake: sync CA bundle/path de - tection with autotools - - 11. Failure to build tests with LibreSSL or wolfSSL with CMake - - Fixed by dropping unnecessary includes, makign test builds dependent - on dependency headers. - - 3765d75ce47b66289f946382b649d0e99389dc77 #14172 cmake: fix building `unit1600 - ` due to missing `ssl/openssl.h` - - 12. curl tests with CMake - - curl's CMake was missing bits for running the C preprocessor accurately. - It made tests 1119 and 1167 fail. I implemented the missing bits. - - efc2c5184d008fe2e5910fd03263e1ab0331d4e6 #14124 tests: include current direct - ory when running test Perl commands - c09db8b51b88ee6ad55bd637dcb4b47678e30906 #14129 cmake: create `configurehelp. - pm` like autotools does - 67cc1e3400b77536a3ca529c986247e1ef985e6e #14125 test1119: adapt for `.md` inp - ut - - 13. GCC missing `__builtin_available()` support - - curl source code assumes this is available to enable certain codepaths. - It's also intermixed with monotonic timer support. - - 14. Monotonic timer support with GCC - - Detected by GCC, while it probably shouldn't be. llvm/clang detects it - depending on target OS version. I've been playing with this, but so far - without a conclusion or fix. - - 15. Runtime/test failures with GCC - - I couldn't find the reason for most of this. A bunch of RTSP tests fail - with GCC. SecureTransport + HTTP/2 is failing a bunch of tests. With - OpenSSL it fails two of those. SecureTransport builds also fail one DoH - test. - - 16. Runtime/test failure in llvm/clang - - AppleIDN support received a fix with two more remaining. - - fd0250869f7837e4a48d7e6f54cc0801ad3820e8 #14179 #14176 IDN: fix ß with Apple - IDN - - 17. Other issues found and fixed while working on this: - - 2c15aa5765900d4351e733671a1c8c3785beee1a GHA/macos: delete misplaced ` - CFLAGS`, drop redundant CMake option - 80fb7c0bef209735ab352bf4afa31193a7bc65f1 #14126 configure: limit `SystemConfi - guration` test to non-c-ares, IPv6 builds - cfd6f43d6ca7e57670b422bab7bbf10221a2cf3e #14127 build: tidy up `__builtin_ava - ilable` feature checks (Apple) - bae555359979016999a9425a2d489f219a78abdd #14174 runtests: show name and keywo - rds for failed tests in summary - 09cdf7e5315711dea4ce7dcf5d99a4d41e7f658b #14178 cmake: delete unused `HAVE_LI - BSSH2`, `HAVE_LIBSOCKET` macros - d3595c74fab829f07ef44da1b7fc2f5668767020 #14186 configure: CA bundle/path det - ection fixes - 58772b0e082eda333e0a5fc8fb0bc7f17a3cd99c #14187 runtests: set `SOURCE_DATE_EP - OCH` to fix failing around midnight - 18f1cd7a77c4beecfd977d43f55634eb593ac99e #14183 tests: sync feature names wit - h `curl -V` - 4c22d97be786ed801e050da6872dd3143d6d0a59 #14181 build: use `#error` instead o - f invalid syntax - - Pending merge: - -Daniel Stenberg (19 Jul 2024) - -- RELEASE-NOTES: synced - -Stefan Eissing (18 Jul 2024) - -- lib: send eos flag - - Adds a `bool eos` flag to send methods to indicate that the data is the - last chunk the invovled transfer wants to send to the server. - - This will help protocol filters like HTTP/2 and 3 to forward the - stream's EOF flag and also allow to EAGAIN such calls when buffers are - not yet fully flushed. - - Closes #14220 - -Bhanu Prakash (18 Jul 2024) - -- mbedtls: correct the error message for cert blob parsing failure - - Closes #14224 - -Daniel Stenberg (18 Jul 2024) - -- curldown: make 'added-in:' a mandatory header field - - - generate AVAILABILITY manpage sections automatically - for consistent - wording - - - allows us to double-check against other documumentation (symbols-in-version - s - etc) - - - enables proper automation/scripting based on this data - - - lots of them were wrong or missing in the manpages - - - several of them repeated (sometimes mismatching) backend support info - - Add test 1488 to verify "added-in" version numbers against - symbols-in-versions. - - Closes #14217 - -Stefan Eissing (18 Jul 2024) - -- doh: fix cleanup - - When removing an easy handle that had DoH sub-easy handles going, those - were not removed from the multi handle. Their memory was reclaimed on - curl_easy_cleanup() of the owning handle, but multi still had them in - their list. - - Add `Curl_doh_close()` and `Curl_doh_cleanup()` as common point for - handling the DoH resource management. Use the `multi` present in the doh - handles (if so), for removal, as the `data->multi` might already have - been NULLed at this time. - - Reported-by: 罗朝辉 - Fixes #14207 - Closes #14212 - -Daniel Stenberg (18 Jul 2024) - -- tests/scripts: call it 'manpage' (single word) - - Mostly in comments - - Closes #14216 - -Alex Snast (18 Jul 2024) - -- http/3: resume upload on ack if we have more data to send - - Currently we're waiting for sendbuf_len_in_flight to hit zero before - resuming upload which means we're blocking and waiting for _all_ acks to - arrive before sending more data. This causes significant delays especially - when ack delay is used on the server side. - - The fix addresses several issues in h3 over ngtcp2: - - On ack we now call nghttp3_conn_resume_stream() when we have more - data to send. - - upload_left was incorrectly computed on CF_CTRL_DATA_DONE_SEND as - we need to subtract the ammount of data we have in flight. - - Remove upload_blocked_len as we Curl_bufq_write call will do the - right thing when called from cf_ngtcp2_send. - - Fixes #14198 - Closes #14209 - -Daniel Stenberg (18 Jul 2024) - -- idn: make macidn fail before trying conversion if name too long - - - double the max name length to 512 bytes - - Closes #14215 - -z2_ (18 Jul 2024) - -- idn: tweak buffer use when converting with macidn - - Closes #14215 - -Orgad Shaneh (18 Jul 2024) - -- lib: add failure reason on bind errors - - Closes #14221 - -Stefan Eissing (18 Jul 2024) - -- pytests: scorecard upload tests - - - add upload tests to scorecard, invoke with - > python3 tests/http/scorecard.py -u h1|h2|h3 - - add a reverse proxy setup from Caddy to httpd for - upload tests since Caddy does not have other PUT/POST handling - - add caddy tests in test_08 for POST/PUT - - increase read buffer in mod_curltest for larger reads - - Closes #14208 - -Viktor Szakats (18 Jul 2024) - -- runtests: fix newline glitch in FAIL details - - Follow-up to bae555359979016999a9425a2d489f219a78abdd #14174 - -- runtests: show name and keywords for failed tests in summary - - Useful to see what the numbers listed in the `TESTFAIL:` and `IGNORED:` - lines mean. Also list test keywords to help catching failure patterns. - - Example: - ``` - FAIL 1034: 'HTTP over proxy with malformatted IDN host name' HTTP, HTTP GET, - HTTP proxy, IDN, FAILURE, config file - FAIL 1035: 'HTTP over proxy with too long IDN host name' HTTP, HTTP GET, HTTP - proxy, IDN, FAILURE - - TESTFAIL: These test cases failed: 1034 1035 - ``` - - Closes #14174 - -Tal Regev (16 Jul 2024) - -- GHA/windows: add MSVC wolfSSL job with test - - Fix the file of wolfssl.c because of this warning/error: - ``` - curl\lib\vtls\wolfssl.c(1017,42): error C2220: the following warning is treat - ed as an error [curl\bld\lib\libcurl_object.vcxproj] - curl\lib\vtls\wolfssl.c(1017,42): warning C4267: 'function': conversion from - 'size_t' to 'unsigned long', possible loss of data [curl\bld\lib\libcurl_obje - ct.vcxproj] - ``` - - `size_t` in MSVC is different. Change it to `unsigned long` because - `wolfSSL_ERR_error_string_n` last argument is defined as - `unsigned long`. - - Closes #14193 - -Viktor Szakats (16 Jul 2024) - -- cmake: delete unused `HAVE_LIBSSH2`, `HAVE_LIBSOCKET` macros - - - `HAVE_LIBSSH2`: unused in source. Not defined in CMake. - - - `HAVE_LIBSOCKET`: unused in source. Used internally in CMake. - - autotools sets them implicitly, so add them to the flag comparison - ignore-list. - - Closes #14178 - -- cmake: create `configurehelp.pm` like autotools does - - Required by tests 1119 and 1167 to run a C preprocessor. - - Tested OK: https://github.com/curl/curl/actions/runs/9915343826 - - Besides Apple, it also supports any gcc and clang builds, and MSVC. - For other platforms, it defaults to `cpp` (like autotools). - - Follow-up to efc2c5184d008fe2e5910fd03263e1ab0331d4e6 #14124 - Cherry-picked from #14097 - Closes #14129 - -- cmake: sync CA bundle/path detection with autotools - - - skip the entire CA logic if no selected TLS backend support CA - certs/bundles. - Follow-up to 082bb41311a832ae1b83bb8fe1dfdefcf4e68ea5 #2545 - - - sync bundle path detection logic with `./configure`. - - - fix to not auto-detect CA bundle/path on Windows. - - - fix to reflect that BearSSL has CA bundle support. - - - show the detected bundle path (as with the cert bundle). - - - tidy up CMake syntax, fix typos in comments. - - Closes #14182 - -- configure: CA bundle/path detection fixes - - - fix to not auto-detect CA bundle/path on Windows. - - - two checks missed BearSSL, but they were only run for supported - TLS backends anyway. Delete these redundant checks. - - - fix typos in a comment nearby. - - Follow-up to 082bb41311a832ae1b83bb8fe1dfdefcf4e68ea5 #2545 - Closes #14186 - -- runtests: set `SOURCE_DATE_EPOCH` to fix failing around midnight - - To make sure that `managen` called by test 1706 uses the same date as - the test expects in the `%DATE` macro. - - Before this patch when tests started running before UTC midnight and - reached test 1706 after, these dates were different and the test failed. - - Follow-up to 0e73b69b3dd6d174226c60406d3c4266754d70f8 - Fixes #14173 - Closes #14187 - -- GHA/windows: verify 1448 2046 2047 in IDN Unicode jobs - - These IDN tests pass with Unicode and fail without. - - Follow-up to cb22cfca69bded45bf7f9c72c8e6764990490f11 #14077 - Closes #14188 - -- tests: sync feature names with `curl -V` - - Some feature names used in tests had minor differences compared to - the well-known ones from `curl -V`. This patch syncs them to make test - results easier to grok. - - Closes #14183 - -Stefan Eissing (15 Jul 2024) - -- sendf: fix CRLF conversion of input - - When CRLF line end conversion was enabled (--crlf), input after the last - newline in the upload buffer was not sent, if the buffer contained a - newline. - - Reported-by: vuonganh1993 on github - Fixes #14165 - Closes #14169 - -- test2600: disable on win32 - - - disbable this test on WIN32 platforms. It uses the file describtor '1' - as valid socket without events. Not portable. - - reduce trace output somewhat on other runs - - Fixes #14177 - Reported-by: Viktor Szakats - Closes #14191 - -- smtp: for starttls, do full upgrade - - - make sure the TLS handshake after a successful STARTTLS command is - fully done before further sending/receiving on the connection. - - Reported-by: tomy2105 on github - Fixes #14166 - Closes #14190 - -Daniel Stenberg (14 Jul 2024) - -- RELEASE-NOTES: synced - -Viktor Szakats (14 Jul 2024) - -- build: use `#error` instead of invalid syntax - - It reduces configure log noise. - - Follow-up to 20c1b2d75ee38189ffa75d21ed04108e1e0630ae #13287 - Closes #14181 - -Daniel Stenberg (14 Jul 2024) - -- libcurl-docs: make option lists alpha-sorted - - The man pages for curl_easy_getinfo, curl_easy_setopt and - curl_multi_setopt now feature the lists of options alphabetically - sorted. Test 1139 verify that they are. - - The curl_multi_setopt page also got brief explanations of the listed - options. - - Closes #14156 - -Christian Schmitz (14 Jul 2024) - -- IDN: fix ß with AppleIDN - - Add flags UIDNA_NONTRANSITIONAL_TO_ASCII and - UIDNA_NONTRANSITIONAL_TO_UNICODE to encode ß correctly. - - It fixes test 165. - - Reported-by: Viktor Szakats - Bug: #14176 - Closes #14179 - -Viktor Szakats (14 Jul 2024) - -- cmake: fix builds with detected libidn2 lib but undetected header - - It caused IDN to appear in `curl-config`, `libidn2` referenced from - `libcurl.pc`, fail to fallback to `pkg-config` detection. But libidn2 - not actually used. - - It came up in macOS CI builds after enabling cmake build tests. It - remained hidden for a while due to setting `-DUSE_APPLE_IDN=ON`. - - (The half-detection of Homebrew libidn2 was the result of configuring - with `-DCMAKE_EXE_LINKER_FLAGS=-L$(brew --prefix)/lib`, to fix - linking GnuTLS that needs the `nettle` lib from the brew prefix.) - - ``` - FAIL 1014: [Compare curl --version with curl-config --features] curl-config - ``` - Ref: https://github.com/curl/curl/actions/runs/9919357748/job/27405080722 - - Cherry-picked from #14097 - Closes #14175 - -- cmake: fix building `unit1600` due to missing `ssl/openssl.h` - - In specific builds configs, cmake failed to build test `unit1600`, - due missing an OpenSSL (or wolfSSL) header. - - The test code relies on `lib/curl_ntlm_core.h`, which in turn included - TLS library headers. But, dependency header directories are not setup - in cmake for tests, because they should not normally be needed. - - The issue was hidden in most builds because TLS headers are usually - found under the system prefix. One counterexample is macOS + Homebrew - LibreSSL builds, where OpenSSL is purposefully unlinked from there to - avoid a mixup with LibreSSL that resides under its own prefix. It was - also hidden in autotools, possibly because it sets up header directories - globally, tests included. - - The actual bug however is that `lib/curl_ntlm_core.h` should not include - TLS headers. None of its internal users need it, and `curl_ntlm_core.c` - included them already directly. - - Fix it by deleting the TLS header includes from this internal header. - - Fixes: - ``` - In file included from curl/tests/unit/unit1600.c:27: - curl/lib/curl_ntlm_core.h:32:12: fatal error: 'openssl/ssl.h' file not found - # include - ^~~~~~~~~~~~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9912684737/job/27388041520#ste - p:12:1694 - - Follow-up to 48eb71ade41d4b37f416b643063cab846ac027a2 #10322 - Cherry-picked from #14097 - Closes #14172 - -- sectransp: fix clang compiler warnings, stop silencing them - - Fix `-Wpointer-bool-conversion` warnings with the method suggested by - both Apple clang and mainline llvm. This was already tried and dropped - in #1705 (in year 2017), but the issue reported there no longer - replicates. - - Verified with Apple clang 14, llvm 15, llvm 18 and gcc 11, 14 that the - generated objects are bit by bit identical before and after this patch. - - Also: - - stop silencing `-Wtautological-pointer-compare`. This warning don't - seem to be appearing anymore (with or without this patch), at least - with the tested compilers and SDKs (clang 13.1.6-16.0.0beta, llvm 15, - 18, gcc 11, 14) and minimum macOS target of 10.8. Older targets fail - to build curl with SecureTransport. - - - silence `-Wunreachable-code` for clang only. Previously I applied it - also to GCC, by mistake. - Ref: https://github.com/curl/curl/pull/12331/commits/8d7172d20a48ebc6c1b1d9 - 4a76e2c5fb19dd9bfa - - Apple clang `-Wpointer-bool-conversion`: - ``` - curl/lib/vtls/sectransp.c:1103:6: error: address of function 'SSLCreateContex - t' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion] - if(SSLCreateContext) { /* use the newer API if available */ - ~~ ^~~~~~~~~~~~~~~~ - curl/lib/vtls/sectransp.c:1103:6: note: prefix with the address-of operator t - o silence this warning - if(SSLCreateContext) { /* use the newer API if available */ - ^ - & - ``` - Ref: https://github.com/curl/curl/actions/runs/9819538439/job/27113201384#ste - p:8:382 - - llvm `-Wpointer-bool-conversion`: - ``` - curl/lib/vtls/sectransp.c:2663:8: error: address of function 'SSLCreateContex - t' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion] - if(SSLCreateContext) - ~~ ^~~~~~~~~~~~~~~~ - curl/lib/vtls/sectransp.c:2663:8: note: prefix with the address-of operator t - o silence this warning - if(SSLCreateContext) - ^ - & - ``` - Ref: https://github.com/curl/curl/actions/runs/9819538439/job/27113200291#ste - p:8:417 - - gcc still needs `-Waddress` suppressed to avoid these: - ``` - curl/lib/vtls/n/sectransp.c: In function 'getsubject': - curl/lib/vtls/n/sectransp.c:379:6: warning: the address of 'SecCertificateCop - yLongDescription' will always evaluate as 'true' [-Waddress] - 379 | if(&SecCertificateCopyLongDescription) - | ^ - [...] - ``` - - Follow-up to 59cadacfcc1d39472245979cdbd614c7a9af6f0d #14128 - Follow-up to af271ce9b9717ba289417e9cbb7f278c2a12f959 #1722 - Follow-up to 2b7ce3f56dfede107113c6de7d0ca457109d3eda #1706 - Cherry-picked from #14097 - Closes #14162 - -- CI/circleci: config tidy-ups, bump up test parallelism - - - bump parallel test for Linux jobs. - Credit-to: Dan Fandrich - Cherry-picked from #11510 - - bump parallel test for macOS jobs. - - drop no longer necessary `-Wno-vla` option. - - fold long lines. - - drop `--enable-maintainer-mode` `./configure` option. - - replace a hard-coded prefix with `brew --prefix`. - - update documentation link. - - move `--enable-debug` in front. - - tidy up quotes. - - Closes #14171 - -- GHA/windows: re-add gsasl to MSVC jobs - - Now that the package reached the CI runner image. - - Follow-up to f99c08dba40307c07341013ff5f71fa8e3464ffc #14090 - Follow-up to e26cbe20cbedbea0ca743dd33880517309315cb2 #13979 - - Closes #14170 - -- tidy-up: adjust casing of project names - - Mostly TLS/SSH project name. - - Closes #14160 - -Daniel Stenberg (12 Jul 2024) - -- ISSUE_TEMPLATE/docs: correct the field identifiers - -Stephen Farrell (12 Jul 2024) - -- doh: fix leak and zero-length HTTPS RR crash - - This PR fixes a leak and a crash that can happen when curl encounters - bad HTTPS RR values in DNS. We're starting to do better testing of that - kind of thing and e.g. have published bad HTTPS RR values at - dodgy.test.defo.ie. - - Closes #14151 - -Daniel Stenberg (12 Jul 2024) - -- curl_global_init.md: polish the thread-safe wording - - Since this has been thread-safe for two years now, few users actually - are hurt by the previous unsafe ways. - - Closes #14158 - -Viktor Szakats (12 Jul 2024) - -- GHA: FreeBSD 14.1, actions bump - - - bump FreeBSD to 14.1 - - - update cross-platform-actions/action action to v0.25.0 - - Closes #14157 - Closes #14164 - -- build: fix llvm 17 and older + macOS SDK 14.4 and newer - - Fixup faulty target macro initialization in macOS SDK since v14.4 (as of - 15.0 beta). The SDK target detection in `TargetConditionals.h` correctly - detects macOS, but fails to set the macro's old name `TARGET_OS_OSX`, - then continues to set it to a default value of 0. Other parts of the SDK - still rely on the old name, and with this inconsistency our builds fail - due to missing declarations. It happens when using mainline llvm older - than v18. Later versions fixed it by predefining these target macros, - avoiding the faulty dynamic detection. gcc is not affected (for now) - because it lacks the necessary dynamic detection features, so the SDK - falls back to a codepath that sets both the old and new macro to 1. - - Also move the `TargetConditionals.h` include to the top of to make sure - including it also for c-ares builds, combined with SecureTransport or - other curl features that may call use an Apple SDK. - - Before this patch, affected build combinations (e.g. in GHA runners, - llvm@15 + Xcode 15.3, 15.4, 16.0 with their default SDKs + - SecureTransport) fail with: - ``` - error: use of undeclared identifier 'noErr' - or 'SecCertificateCopyLongDescription' - or 'SecItemImportExportKeyParameters' - or 'SecExternalFormat' - or 'SecExternalItemType' - or 'SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION' - ``` - - Example: - ``` - curl/lib/vtls/sectransp.c:311:18: error: use of undeclared identifier 'noErr' - OSStatus rtn = noErr; - ^ - curl/lib/vtls/sectransp.c:379:7: error: use of undeclared identifier 'SecCert - ificateCopyLongDescription' - if(&SecCertificateCopyLongDescription) - ^ - curl/lib/vtls/sectransp.c:381:7: error: call to undeclared function 'SecCerti - ficateCopyLongDescription'; ISO C99 and later do not support implicit functio - n declarations [-Werror,-Wimplicit-function-declaration] - SecCertificateCopyLongDescription(NULL, cert, NULL); - ^ - curl/lib/vtls/sectransp.c:380:25: error: incompatible integer to pointer conv - ersion assigning to 'CFStringRef' (aka 'const struct __CFString *') from 'int - ' [-Wint-conversion] - server_cert_summary = - ^ - [...] - ``` - Ref: https://github.com/curl/curl/actions/runs/9893867519/job/27330135969#ste - p:10:22 - - llvm v18 patches implementing the predefined macros: - https://github.com/llvm/llvm-project/pull/74676 - https://github.com/llvm/llvm-project/commit/6e1f19168bca7e3bd4eefda50ba03eac8 - 441dbbf - https://github.com/llvm/llvm-project/pull/82833 - https://github.com/llvm/llvm-project/commit/e5ed7b6e2fd368b722b6359556cd01258 - 81e7638 - - Cherry-picked from #14097 - Closes #14159 - -- macos: undo `availability` macro enabled by Homebrew gcc - - Homebrew gcc builds starting with 12.4.0, 13.3.0 and 14.1.0 enabled - the `availability` attribute. - - This broke builds because the way the Apple SDK uses attributes (when - available) are incompatible with how gcc accepts them. Causing these - errors: - ``` - error: attributes should be specified before the declarator in a function d - efinition - error: expected ',' or '}' before - ``` - - Upstream commits implementing the `availability` macro: - gcc-12: https://github.com/iains/gcc-12-branch/commit/fd5530b7cb0012bf4faeddd - 45e13054a1dfa6783 - gcc-13: https://github.com/iains/gcc-13-branch/commit/cb7e4eca68cfc4763474e2e - b0935a844458842a8 - gcc-14: https://github.com/iains/gcc-14-branch/commit/ff62a108865a6403f501738 - 0d7018250c1d3306f - - The project above is a Darwin gcc compatibility pack, that is applied - to Homebrew gcc builds. - - This patch works by redefining the `availability` macro to an invalid - value, making `__has_attribute(availability)` checks fail, stopping - Apple SDK from inserting the incompatible attributes. - - It also replaces the previous, local workaround for `lib/macos.c`. - - Example with gcc 12.4.0 with macOS SDK 14.0 (Xcode 15.0.1): - ``` - In file included from /MacOSX14.0.sdk/System/Library/Frameworks/ - CoreFoundation.framework/Headers/CoreFoundation.h:54, - from /MacOSX14.0.sdk/System/Library/Frameworks/ - SystemConfiguration.framework/Headers/SCDynamicStoreCopySpecific.h:30, - from /Users/runner/work/curl/curl/lib/macos.c:33, - from /Users/runner/work/curl/curl/build/lib/CMakeFiles/libcu - rl_shared.dir/Unity/unity_0_c.c:244: - /MacOSX14.0.sdk/System/Library/Frameworks/CoreFoundation.framewo - rk/Headers/CFUserNotification.h:126:1: error: attributes should be specified - before the declarator in a function definition - 126 | CF_INLINE CFOptionFlags CFUserNotificationCheckBoxChecked(CFIndex i) - API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOp - tionFlags)(1UL << (8 + i)));} - | ^~~~~~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9787982387/job/27025351601?pr= - 14096#step:7:18 - - The gcc vs. llvm/clang incompatibility possibly tracked here upstream: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796 - More info: - https://github.com/llvm/llvm-project/issues/81767 - https://github.com/gcc-mirror/gcc/commit/8433baadec88e5f31fa141b6d78094e912 - 56079d - https://discourse.llvm.org/t/changing-attribute-ast-printing-location-for-g - cc-compatibility/73215 - https://reviews.llvm.org/D159362 - - Follow-up to db135f8d7207b20d531e7e2100a49f3e16bdcfab #14119 - Ref: https://github.com/curl/curl/pull/14091#issuecomment-2222703468 - Fixes #13700 - Cherry-picked from #14097 - Closes #14155 - -Daniel Stenberg (11 Jul 2024) - -- ISSUE_TEMPLATE/docs: add a separate GitHub issue template for documentation - - As such problems don't really fit the code related template - - Closes #14161 - -Dan Fandrich (11 Jul 2024) - -- DISTROS: add AlmaLinux package source link - -Viktor Szakats (11 Jul 2024) - -- GHA/windows: ignore FTP test results for old-mingw-w64 [ci skip] - - Missed from previous commit. They are flaky here as well. - - Follow-up to 0b81eccd22fb915aa6b679c0fd23a8a89332dc9e - -Daniel Stenberg (11 Jul 2024) - -- libcurl-easy.md: now *more* than 300 options - - it previously said "almost 300". - - Also cleaned up the language somewhat. - - Closes #14153 - -Martin Peck (10 Jul 2024) - -- MANUAL.md: wrap two example urls that overrun styling - - Closes #14149 - -renovate[bot] (10 Jul 2024) - -- GHA: update wolfSSL and mod_h2 - - - wolfSSL/wolfssl to v5.7.2 - - icing/mod_h2 to v2.0.29 - - Closes #14131 - Closes #14148 - -Dominik Piątkowski (10 Jul 2024) - -- docs: start markdown headers with capital letter where applicable - - Closes #14115 - -CMD (10 Jul 2024) - -- hostip: skip error check for infallible function call - - Closes #14147 - -Daniel Stenberg (10 Jul 2024) - -- cf-socket: remove two "useless" assignments - - 'nread' is already -1, no need to assign it again - - Pointed out by CodeSonar - - Closes #14145 - -Viktor Szakats (10 Jul 2024) - -- cmake: detect `libidn2` also via `pkg-config` - - Also: - - GHA/non-native: install `pkg-config` to detect libidn2 with cmake - on NetBSD and FreeBSD. - - GHA/non-native: tidy-up `curl --version` command if here. - - Cherry-picked from #14097 - Closes #14137 - -- build: fix llvm 16 or older + Xcode 15 or newer, and gcc - - Xcode v15 (2023) or newer requires the built-in macro - `__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__`. This macro is missing from - mainline llvm versions released earlier. llvm v17 introduced it here: - https://github.com/llvm/llvm-project/commit/c8e2dd8c6f490b68e41fe663b44535a8a - 21dfeab - - This patch defines the missing macro when the necessary conditions - align, by using the value via the macro's old name. - - The issue affected SecureTransport builds: The SecureTransport code, - `lib/md4.c` and `lib/md5.c`. - - Existing gcc versions (as of v14) also don't define this macro, so apply - the patch to it as well. Even though gcc is incompatible in other ways, - so this isn't fixing an actual curl build case that I could find yet. - - GHA macOS runner images have llvm v15 pre-installed, which broke builds - when building with an affected Xcode: - ``` - curl/lib/md4.c:80:14: error: '__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__' is not - defined, evaluates to 0 [-Werror,-Wundef] - (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ - ^ - /Applications/Xcode_15.1.app/Contents/Developer/Platforms/MacOSX.platform/Dev - eloper/SDKs/MacOSX14.2.sdk/usr/include/AvailabilityInternal.h:40:53: note: ex - panded from macro '__MAC_OS_X_VERSION_MIN_REQUIRED' - #define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_OS_VERSION_ - MIN_REQUIRED__ - ^ - In file included from curl/build/lib/CMakeFiles/libcurl_shared.dir/Unity/unit - y_0_c.c:250: - curl/lib/md5.c:75:14: error: '__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__' is not - defined, evaluates to 0 [-Werror,-Wundef] - (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ - ^ - /Applications/Xcode_15.1.app/Contents/Developer/Platforms/MacOSX.platform/Dev - eloper/SDKs/MacOSX14.2.sdk/usr/include/AvailabilityInternal.h:40:53: note: ex - panded from macro '__MAC_OS_X_VERSION_MIN_REQUIRED' - #define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_OS_VERSION_ - MIN_REQUIRED__ - ^ - 2 errors generated. - ``` - Ref: https://github.com/curl/curl/actions/runs/9811974634/job/27095218578#ste - p:4:20 - - Cherry-picked from #14097 - Closes #14134 - -- build: tidy up `__builtin_available` feature checks (Apple) - - - sync detection snippet between autotools and cmake - It wasn't causing issues, but it's useful to avoid unnecessary - differences while debugging. - - - cmake: limit check to `APPLE`. - - Ref: b05dc7eb3592305de9fa85640767f3dd2a8d4c93 #14122 - Cherry-picked from #14097 - Closes #14127 - -- configure: limit `SystemConfiguration` test to non-c-ares, IPv6 builds - - The framework this check detects is necessary for the function - `SCDynamicStoreCopyProxies()` used in `lib/macos.c`. Non-c-ares, - IPv6-enabled builds touch this codepath. - - Limit the feature check for builds that actually need it. - - It brings this in sync with CMake which already worked this way. - - Cherry-picked from #14097 - Closes #14126 - -- configure: fix `SystemConfiguration` detection - - Before this patch, `SystemConfiguration` detection failed due to this - error when compiling the detection snippet: - ``` - /Applications/Xcode_15.3.app/Contents/Developer/Platforms/MacOSX.platform/Dev - eloper/SDKs/MacOSX.sdk/usr/include/TargetConditionals.h:140:50: error: missin - g binary operator before token "(" - 140 | #if !defined(__has_extension) || !__has_extension(define_target_os_ma - cros) - | ^ - ``` - Ref: https://github.com/curl/curl/actions/runs/9821817534/job/27117929218#ste - p:6:1079 - - It occured with gcc-11 when combined with macOS SDK 14.4 and 14.5 - (default SDKs in Xcode 15.3 and 15.4 respectively). It did not happen - with earlier releases. - - Despite the failure in `./configure`, `lib/macos.c` compiled with - Apple's `TargetConditionals.h` just fine. - - Turns out that including the `sys/types.h` header before the SDK - header fixes the error and makes the detection snippet compile. - - Cherry-picked from #14097 - Closes #14130 - -- build: sync warning options between autotools, cmake & compilers - - - cmake: enable Apple-specific `-Werror=partial-availability` to match - autotools. - - - autotools: enable `-pedantic-errors` with llvm/clang to match gcc and - CMake. - - - autotools: enable `-Werror-implicit-function-declaration` for - llvm/clang to match gcc. - - - cmake: enable `-Werror-implicit-function-declaration` to match - autotools. - - - move `-Wpointer-bool-conversion` from autotools to the local file - (`sectransp.c`) it was meant to apply. This way it applies to all - build methods. - - - autotoos: show `CURL_CFLAG_EXTRAS` in the `./configure` summary. - (it may contain `-Werror` and/or `-pedentic-errors`.) - - Cherry-picked from #14097 - Closes #14128 - -- CI: simplify running curl with DLLs - - - update `PATH` instead of copying DLLs around. - - drop redundant `export` from `export PATH`. - - delete ending pathseps. - - Closes #14143 - -Alex Snast (9 Jul 2024) - -- wolfssl: use larger error buffer when formatting errors - - Currently we're using WOLFSSL_MAX_ERROR_SZ to define the error buffer - size, this value is user defined which means it can be overwritten with - -DWOLFSSL_MAX_ERROR_SZ=512 when building wolfssl and this overwrite is - not exported to the users of wolfssl. - - Instead of relying on WOLFSSL_MAX_ERROR_SZ we'll just use a 256 bytes - error buffer and use wolfSSL_ERR_error_string_n to fill it thus dropping - the dependency on WOLFSSL_MAX_ERROR_SZ altogether. - - Closes #14114 - -Viktor Szakats (9 Jul 2024) - -- CI: bump FreeBSD Python packages - - Closes #14141 - -- GHA/curl-for-win: don't run if only another CI was changed - - Closes #14142 - -Daniel Stenberg (9 Jul 2024) - -- RELEASE-NOTES: synced - -Stefan Eissing (9 Jul 2024) - -- vtls: replace addsessionid with set_sessionid - - - deduplicate the code in many tls backends that check - for an existing id and delete it before adding the new one - - rename ssl_primary_config's `sessionid` bool to `cache_session` - - Closes #14121 - -Daniel Stenberg (9 Jul 2024) - -- test1175: scan libcurl-errors.md, not the generated .3 version - - Closes #14133 - -- test1139: scan .md files instead of .3 ones - - As they are the canonical sources. - - It still uses the curl.1 for command line option info. - - Closes #14132 - -Stefan Eissing (9 Jul 2024) - -- cf-socket: remove obsolete recvbuf - - - recvbuf was never enabled, remove all its code - - remove `fdsave`ing the socket as that is not longer needed - - Closes #14138 - -Viktor Szakats (9 Jul 2024) - -- test1119: adapt for `.md` input - - Replace logic dealing with `.3` files to handle the Markdown syntax. - - Follow-up to eefcc1bda4bccd800f5a56a0fe17a2f44a96e88b #12730 - Cherry-picked from #14097 - Closes #14125 - -- tests: include current directory when running test Perl commands - - Necessary to find generated files in the out-of-tree build directory. - E.g. `tests/configurehelp.pm`, for tests 1119 and 1167. - - Before this patch macOS autotools builds were failing these two tests - due to falling back to the default preprocessor (`cpp`) instead of - the actual one configured. Then `cpp` failing to compile Apple SDK - headers referenced by curl headers. - - Cherry-picked from #14097 - Closes #14124 - -- configure: sort feature list, lowercase protocols, use backticks - - - sort features case-insensitively to match `curl -V` and cmake. - `sort -f` is POSIX, but check if it's available anyway. - - - make protocols lowercase to match `curl -V` and cmake. - - - replace two outlier `$()` with backticks. - - Closes #14117 - -Yedaya Katsman (8 Jul 2024) - -- variable.md: make example use expand - - I used double quotes since it seemed required for powershell, so this - example works in both (ba)sh and powershell as well as cmd.exe. - - Closes #14118 - -Andy Reitz (8 Jul 2024) - -- GIT-INFO.md: remove version requirements - - Keep them in docs/INTERNALS.md - - Bump lowest perl to 5.8 - - Closes #14112 - -Viktor Szakats (8 Jul 2024) - -- sectransp: fix `HAVE_BUILTIN_AVAILABLE` checks to not emit warnings - - `HAVE_BUILTIN_AVAILABLE` is a curl macro set via autotools and cmake. - Like other `HAVE_`s it signals availability if defined. - - SecureTransport code was specifically looking for the value 1, which - triggered compiler warnings when the feature was not present. - - Replace the existing workaround of locally suppressing the compiler - warning with using `defined()`. - - autotools: - ``` - 767 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILAB - LE == 1 - | ^~~~~~~~~~~~~~~~~~ - ~~~~ - ../../lib/vtls/sectransp.c: In function 'sectransp_connect_step1': - ../../lib/vtls/sectransp.c:1140:52: error: "HAVE_BUILTIN_AVAILABLE" is not de - fined, evaluates to 0 [-Werror=undef] - 1140 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAIL - ABLE == 1 - | ^~~~~~~~~~~~~~~~~~ - ~~~~ - ../../lib/vtls/sectransp.c:1240:52: error: "HAVE_BUILTIN_AVAILABLE" is not de - fined, evaluates to 0 [-Werror=undef] - 1240 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAIL - ABLE == 1 - | ^~~~~~~~~~~~~~~~~~ - ~~~~ - ../../lib/vtls/sectransp.c: In function 'sectransp_connect_step2': - ``` - Ref: https://github.com/curl/curl/actions/runs/9815428701/job/27104448045#ste - p:6:499 - - cmake gcc: - ``` - 1140 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAIL - ABLE == 1 - | ^~~~~~~~~~~~~~~~~~ - ~~~~ - /Users/runner/work/curl/curl/lib/vtls/sectransp.c:1240:52: error: "HAVE_BUILT - IN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef] - 1240 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAIL - ABLE == 1 - | ^~~~~~~~~~~~~~~~~~ - ~~~~ - /Users/runner/work/curl/curl/lib/vtls/sectransp.c: In function 'sectransp_con - nect_step2': - /Users/runner/work/curl/curl/lib/vtls/sectransp.c:2231:51: error: "HAVE_BUILT - IN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef] - 2231 | #if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILA - BLE == 1 - | ^~~~~~~~~~~~~~~~~~~ - ~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9815428701/job/27104445425#ste - p:8:355 - - Cherry-picked from #14097 - Closes #14122 - -- examples: suppress deprecation warnings locally - - Simplify making clean builds by silencing deprecation warnings inside - the example code where these may occur. - - Drop related build tweaks/comments from GHA jobs. - - Example warning: - ``` - curl/docs/examples/postit2-formadd.c:65:16: error: 'CURLFORM_COPYNAME' is dep - recated: since 7.56.0. Use curl_mime_name() [-Werror=deprecated-declarations] - 65 | CURLFORM_COPYNAME, "sendfile", - | ^~~~~~~~~~~~~~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9841099503/job/27166970904#ste - p:10:829 - - Closes #14123 - -- GHA/macos: bump parallel tests to -j5 - - Credit-to: Dan Fandrich - Cherry-picked from #11510 #14097 - -- GHA/windows: usability improvements - - - move `curl --version` into separate step. - - - move configure log to separate step. Run on success, too. - - - add step with `curl_config.h` dump (full and brief/sorted). - - - make `autoreconf` a separate step. - - - add each job configuration a short name. - - - shorten job names. - Dedupe/drop redundant info, introduce abbreviations: - AM = autotools, CM = CMake, U = Unicode, R = Release, not -> `!`, etc. - Instead of mentioning `debug`, mentioned when it's not. - - - simplify `PATH` forming for MSVC jobs. - It's sufficient to add the release binary directory of vcpkg, the debug one - is redundant. - Follow-up to e26cbe20cbedbea0ca743dd33880517309315cb2 #13979 - - - other minor tidy-ups. - - Closes #14116 - -- GHA/macos: delete misplaced `CFLAGS`, drop redundant CMake option - - With macOS there is a long-term struggle with deprecation warnings. - In curl they occur with LDAP, SecureTransport and in docs/examples. - - There are three ways to fix them: - - by CFLAGS `-Wno-deprecated-declarations` as a workaround. - - by CFLAGS `-mmacosx-version-min` set to a version where the the - feature was not deprecated. - - by CMake option `-DCMAKE_OSX_DEPLOYMENT_TARGET=`. - - In GHA CMake jobs, all three were used, and `-mmacosx-version-min` was - set in a bogus way. Delete that bogus option, and delete the lone, - redundant CMake option too. - - In a future commit I might replace the suppression option to properly - setting the target OS. - - Follow-up to dfdd978f7c60224dffe2aac25b436dc0a5cd0186 #13491 - Cherry-picked from #14097 - -- macos: add workaround for gcc, non-c-ares, IPv6, compile error - - Apple macOS SDK 13.0 and later are increasingly incompatible with gcc, - which started causing CI errors with the 20240701.9 revision of the - `macos-latest` (= `macos-14-arm64`) runner image. - - This error is happening inside an Apple SDK header. We use the header - for calling a function in a resolver-related hack, in non-c-ares, IPv6 - builds. You can avoid the problem by using c-ares or disabling IPv6 - (or using clang, llvm, or a compatible gcc + SDK combination). - - This patch fixes affected builds by declaring the ncessary framework - function manually, and not including the problematic header. - - This workaround is ugly, doesn't cover all combinations, and fragile. - - Other options are to disable this resolver-related hack for GCC, or to - replace it with a solution that doesn't rely on Apple SDK. - - If you are aware of a stable fix or workaround, let us know. - - gcc 12.4.0 + macOS SDK 14.0 (Xcode 15.0.1) error example: - ``` - In file included from /Applications/Xcode.app/Contents/Developer/Platforms/Ma - cOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/CoreFou - ndation.framework/Headers/CoreFoundation.h:54, - from /Applications/Xcode.app/Contents/Developer/Platforms/Ma - cOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/SystemC - onfiguration.framework/Headers/SCDynamicStoreCopySpecific.h:30, - from /Users/runner/work/curl/curl/lib/macos.c:33, - from /Users/runner/work/curl/curl/build/lib/CMakeFiles/libcu - rl_shared.dir/Unity/unity_0_c.c:244: - /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Develope - r/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Head - ers/CFUserNotification.h:126:1: error: attributes should be specified before - the declarator in a function definition - 126 | CF_INLINE CFOptionFlags CFUserNotificationCheckBoxChecked(CFIndex i) - API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOp - tionFlags)(1UL << (8 + i)));} - | ^~~~~~~~~ - /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Develope - r/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Head - ers/CFUserNotification.h:127:1: error: attributes should be specified before - the declarator in a function definition - 127 | CF_INLINE CFOptionFlags CFUserNotificationSecureTextField(CFIndex i) - API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOp - tionFlags)(1UL << (16 + i)));} - | ^~~~~~~~~ - /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Develope - r/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Head - ers/CFUserNotification.h:128:1: error: attributes should be specified before - the declarator in a function definition - 128 | CF_INLINE CFOptionFlags CFUserNotificationPopUpSelection(CFIndex n) A - PI_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos) {return ((CFOpt - ionFlags)(n << 24));} - | ^~~~~~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9787982387/job/27025351601?pr= - 14096#step:7:18 - - The exact conditions are fuzzy. Oddly enough gcc 12.3.0 and the SDK - same as above are _compatible_: - https://github.com/curl/curl/actions/runs/9791701214/job/27036037162 - - Also notice that similar errors can also happen in SecureTransport - builds, due to the SDK headers required. - - Ref: https://github.com/curl/curl/pull/14097#issuecomment-2208639046 - Ref: https://github.com/curl/curl/pull/14091#issuecomment-2205870854 - Cherry-picked from #14097 - Closes #14119 - -- cmake: feature casing fix and tidy-ups - - - fix casing of a feature (`Unicode`) in the feature list. - - sort TLS backends case-insensitively. - - sync feature/protocol list heading with `curl -V` and autotools. - - Closes #14120 - -- GHA: ignore FTP test result in Windows jobs - - They are flaky. - - E.g.: - - old-mingw-w64 7.3.0: 2001, 2039, 2083 - - msvc: 1501, 593 (multiple) - - Ref: https://github.com/curl/curl/pull/13599#issuecomment-2119372376 - Cherry-picked from #14116 - -- GHA: improve vcpkg cache, add BoringSSL ECH and LibreSSL MSVC jobs - - - cache on a per-package basis. - Replace manual caching with a built-in solution. It shares cached - package builds between jobs, e.g. libssh2 only builds once - per platform (instead of once per job). Individual packages are built - as needed (not the whole per-job tree). It also fixes the duplicate - cache entry issues. - Ref: https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github- - actions-cache - Follow-up to e26cbe20cbedbea0ca743dd33880517309315cb2 #13979 - Follow-up to cb22cfca69bded45bf7f9c72c8e6764990490f11 #14077 - - - add BoringSSL job with ECH enabled. The first such job in the curl CI. - - - add LibreSSL job. - - - use vcpkg pre-installed on the runner image, instead of rolling our - own. This is quicker, simpler and more robust. - Follow-up to e26cbe20cbedbea0ca743dd33880517309315cb2 #13979 - - - show pre-installed vcpkg and ports version. - - - drop `gsasl` dependency till it reaches the pre-installed vcpkg ports. - - - re-add `find .` to see the binaries generated. - - - simplify setting up `PATH`. - - - exclude failing tests for any job enabling WinIDN. - - - drop collecting and uploading log archives. We already dump CMake - logs, and our build doesn't use Ninja. Rest of files weren't generated - by the curl build. We don't aim to debug vcpkg package builds. - - Closes #14090 - -Tal Regev (7 Jul 2024) - -- GHA: add MSVC UWP job, expand jobs with more options - - - add new dependencies: brotli, libpsl (requires libicu2) and gsasl. - - - enable WinIDN in a job. Exclude failing tests. - - - add UWP job and fix the build logic to support it. - - - increase timeouts to build the new dependencies. - - Assisted-by: Viktor Szakats - Closes #14077 - -Dan Fandrich (6 Jul 2024) - -- tests: fix sshd UserKnownHostsFile path for MinGW/Cygwin - - This is the same thing as the previous commit fd194f46 but on the next - line. - - Follow-up to 70d2fca2 - - Ref: #10818 - -- tests: fix sshd IdentityFile path for MinGW/Cygwin - - This was missed during some refactoring more than a year ago and is - causing a warning "Use of uninitialized value $path in pattern match". - - Follow-up to 70d2fca2 - - Ref: #10818 - Closes #14113 - -Viktor Szakats (7 Jul 2024) - -- build: add Debug, TrackMemory, ECH to feature list - - Also: - - - remove stray `ECH` and `HTTPSRR` from cmake protocol list. - - - stop excluding `Debug` and `TrackMemory` in `test1013.pl`. - - - configure: delete `CURL_CHECK_CURLDEBUG` check. - Ref: 065047dc62cba3efde597fa5420d112fc2f4c500 - This check was effectively doing nothing, except disabling - `--enable-curldebug` in `curl-config` for - Cygwin/MSYS/cegcc/OS2/AIX targets with c-ares enabled. - - Closes #14096 - -Dan Fandrich (5 Jul 2024) - -- CI: bump the libc6 on the linux-old build - - This contains some security fixes for nscd. - -Viktor Szakats (6 Jul 2024) - -- reuse: fix typo in comment - - Follow-up to 9104bad82004d908e1fe66a425f8ca78f975045d #14107 - -Dan Fandrich (5 Jul 2024) - -- CI: Fix typo in comment - -- curl: follow-up to fix categories in --help - - The commit 6483813b was missing changes necessitated by 2abfc75 that - causes a crash. Also, use ARRAYSIZE() for cleaner code. - - Follow-up to 6483813b - - Ref #14055 - -- curl: list categories in --help - - This eliminates the need to run an extra help subcommand to get the - possible categories, reducing the friction in getting relevant help. The - help wording was also slightly tweaked for grammatical accuracy. - - Closes #14055 - -Daniel Stenberg (5 Jul 2024) - -- RELEASE-NOTES: synced - -renovate[bot] (5 Jul 2024) - -- GHA: update actions/upload-artifact and actions/download-artifact - - update actions/upload-artifact digest to 0b2256b - update actions/download-artifact digest to fa0a91b - - Closes #14111 - Closes #14110 - -Max Mehl (5 Jul 2024) - -- reuse: switch to REUSE 3.2 and REUSE.toml - - - remove scripts/copyright.pl - - Closes #14107 - -Yedaya Katsman (5 Jul 2024) - -- curl: move more options to deprecated category - - --no-npn, --sslv2, --sslv3 - - Closes #14109 - -Stefan Eissing (5 Jul 2024) - -- multi: pollset assertion only when IP connected - - Give warning for an empty pollset only when the connection has at least - IP connectivity. There are cases where the connect in QUIC makes another - attempt on a timeout and no socket will be available during that. - - Closes #14108 - -Daniel Stenberg (5 Jul 2024) - -- cmdline-opts: category cleanup - - Option cleanups: - - --get is not upload - --form* are post - - added several options into ldap, smtp, imap and pop3 - - shortened the category descriptions in the list - - category curl fixes: - - --create-dirs removed from 'curl' - --ftp-create-dirs removed from 'curl' - --netrc moved to 'auth' from 'curl' - --netrc-file moved to 'auth' from 'curl' - --netrc-optional moved to 'auth' from 'curl' - --no-buffer moved to 'output' from 'curl' - --no-clobber removed from 'curl' - --output removed from 'curl' - --output-dir removed from 'curl' - --remove-on-error removed from 'curl' - - Add a "global" category: - - - Made all "global" options set this category - - Add a "deprecated" category: - - - Moved the deprecated options to it (maybe they should not be in any - category long term) - - Add a 'timeout' category - - - Put a number of appropriate options in it - - Add an 'ldap' category - - - Put the LDAP related option in there - - Remove categories "ECH" and "ipfs" - - - They should not be categories. Had only one single option each. - - Remove category "misc" - - - It should not be a category as it is impossible to know when to browse - it. - - --use-ascii moved to ftp and output - --xattr moved to output - --service-name moved to auth - - Managen fixes: - - - errors if an option is given a category name that is not already setup - for in code - - - verifies that options set `scope: global` also is put in category - `global´ - - Closes #14101 - -Stefan Eissing (5 Jul 2024) - -- GHA: configure OpenSSL's libdir as 'lib' only - - Also mention in HTTP3.md - - OpenSSL has a bug that messes the config `--libdir=path` to become the - wrong path in its pkgconfig files. If we just pass `--libdir=lib` it - should avoid this. - - Ref: #14099 - See also: https://github.com/openssl/openssl/issues/23569 - - Closes #14102 - -Daniel Stenberg (5 Jul 2024) - -- tool_operate: simplify return code handling from url_proto() - - The additional checks were superfluous as it would only ever return - error if one of those protocols were set. Also: a returned error - *should* mean get out of there, without having to check more conditions. - - Closes #14104 - -- tool_operate: check for --disable case *sensitively* - - curl command line options are specified with the correct casing or they - don't match - - Closes #14103 - -Stefan Eissing (4 Jul 2024) - -- transfer: avoid polling socket every transfer loop - - Improve download performance, minimal effort. - - Do not poll the socket for pending data every transfer loop iteration. - This gives 10-20% performance gains on large HTTP/1.1 downloads (on my - machine). - - Closes #14098 - -Viktor Szakats (4 Jul 2024) - -- tests: delete `CharConv` remains - - Closes #14100 - -- GHA: bump macOS CMake job parallelism to 4 (nproc+1) [ci skip] - - To match autotools ones and the rest of workflows. - - Follow-up to 464282ddfb214917be3d143c035f178f3b77f209 #13807 - -Yedaya Katsman (4 Jul 2024) - -- help: add flags to output and ssh categories - - - Add --output, --remove-on-error, --output-dir and --created-dirs to - the output help category - - - Add --hostpubmd5, --hostpubsha256, --insecure (-k), and --pubkey to - the ssh help category - - Closes #14076 - -Stefan Eissing (4 Jul 2024) - -- TODO: remove item about 'SSL_peak' - - GnuTLS todo item about using an equivalent of `SSL_peak()`, which - nicely escaped the word checks, is no longer relevant. - - We do not use `SSL_peek()` anymore since connection filters were - introduced. - - Closes #14091 - -renovate[bot] (4 Jul 2024) - -- GHA: update dependency gnutls/gnutls to v3.8.6 - - Closes #14094 - -- GHA: update fsfe/reuse-action action to v4 - - Closes #14095 - -Viktor Szakats (3 Jul 2024) - -- GHA: Windows job exclusions tweaks - - - disable SMTP tests in MSYS2/mingw-w64 and MSVC jobs. - On the suspicion of sometimes hanging: - https://github.com/curl/curl/actions/runs/9346162475/job/25720437944?pr=138 - 55#step:14:2838 - https://github.com/curl/curl/actions/runs/9758011305/job/26931678639?pr=140 - 84#step:14:2834 - https://github.com/curl/curl/actions/runs/9774468536/job/26982805294#step:1 - 1:4731 - - - run TFTP, MQTT, WebSockets tests in MSYS2/msys jobs again. - - - switch hanging old-mingw-w64 7.3.0 job to Release (from Debug). - Guessing here, 9.5.0 is more solid, and one difference is - Debug/Release mode. Let's match 7.3.0 with that and see how it changes - hangs and flakiness. - The other difference is Unicode ON in 7.3.0. Flaky 6.3.0 was also - Debug, with Unicode OFF: - 217878bade884202ee5fb2e80186c5fd130392e8 #13566. - (Unicode unlikely to play a role here IMO.) - If 7.3.0 keeps hanging / remains flaky I'll consider disabling its - test runs. - - - opt-out from vcpkg telemetry. - - Ref: https://github.com/curl/curl/pull/13599#issuecomment-2119372376 - Closes #14085 - -renovate[bot] (3 Jul 2024) - -- Dockerfile: update debian:bookworm-slim to 39868a6 - - Closes #14083 - -Daniel Stenberg (3 Jul 2024) - -- FEATURES.md: refresh - - - added lots of missing stuff - - rearranged a little - - remove all footnotes - - Closes #14086 - -- RELEASE-NOTES: synced - -- curl_easy_perform.md: call it network transfer, not file transfer - -Viktor Szakats (2 Jul 2024) - -- winbuild: MS-DOS batch tidy-ups - - - prefer `.bat` extension over `.cmd` for MS-DOS batch, which also - avoids confusion with OS/400 `.cmd` files. - - cleanup `echo` quotes, drop them consistently. - - delete empty output line from one of the error branches. - - prefer lowercase commands like the rest of MS-DOS batches. - - delete a contraction. - - drop backticks from error message. - - use `nmake.exe` consistently. - - use equal/not-equal operator style consistently. - - inline a single-line `if` branch. - - delete exceptions and rules dealing with Windows `.cmd` extension. - - Closes #14084 - -Stefan Eissing (2 Jul 2024) - -- multi: fix pollset during RESOLVING phase - - - add a DEBUGASSERT for when a transfer's pollset should not be empty. - - move write unpausing from transfer loop into curl_easy_pause. This - make sure that the url_updatesocket() finds the correct state when - updating socket events. - - fix HTTP/2 proxy during connect phase to set sockets correctly - - fix test2600 to simulate a socket set - - move write unpausing from transfer loop into curl_easy_pause. This - make sure that the url_updatesocket() finds the correct state when - updating socket events. - - waiting for the resolver to deliver might not involve any sockets to - wait for. Do not generate a warning. - - Fixes #14047 - Closes #14074 - -Daniel Stenberg (2 Jul 2024) - -- cmdline-opts: shorten six help texts - - o --location-trusted - o --next - o --parallel-immmediate - o --pinnedpubkey - o --proxy-pass - o --proxy-ssl-allow-beast - - Closes #14075 - -- managen: fix removing backticks from subtitles - - It erroneously removed them from the wrong variable. - - Closes #14081 - -Viktor Szakats (2 Jul 2024) - -- cmake: show protocols, then features - - To match the order used by `curl -V` and `./configure`. - - Closes #14082 - -- cmdline-docs: fix `--proxy-ca-native` example + tidy-ups - - Also: - - fix an indentation. - - fix capitalized option in comment. - - Closes #14078 - -- cmake: sync protocol/feature list with `curl -V` output - - - sort features case-insensitively. - Requires CMake v3.13.0. - Follow-up to 0f26abeef1dd1d1a02f8e12dbc3d51e73e9d2e9c #14063 - - - convert protocol list to lowercase. - But leave it uppercase in `curl-config`. - - Closes #14066 - -- GHA/badwords.yml: fixup indent for yamllint [ci skip] - -renovate[bot] (1 Jul 2024) - -- GHA: update dependency awslabs/aws-lc to v1.31.0 - - Closes #14080 - -Daniel Stenberg (1 Jul 2024) - -- GHA/badwords.yml: check source code wording - - Closes #14073 - -- code: language cleanup in comments - - Based on the standards and guidelines we use for our documentation. - - - expand contractions (they're => they are etc) - - host name = > hostname - - file name => filename - - user name = username - - man page => manpage - - run-time => runtime - - set-up => setup - - back-end => backend - - a HTTP => an HTTP - - Two spaces after a period => one space after period - - Closes #14073 - -Yedaya Katsman (1 Jul 2024) - -- docs: add RELEASE-TOOLS.md.dist to .gitignore - - Closes #14079 - -Viktor Szakats (1 Jul 2024) - -- libcurl.pc: add more `Requires.private`/`Requires` dependencies - - - add `libmsh3` reference from cmake and autotools. - - - add `mit-krb5-gssapi` reference from cmake. - - It leaves GSS not set from autotools. The handling of heimdal in cmake - is fuzzy, that's probably missing too. - - Follow-up to f057de5a1a950a90d1920021db152a4b695f1a8a #13911 - Closes #14072 - -- cmake: improve wolfSSL detection - - - support detecting wolfSSL via pkg-config (like autotools.) - - - detect wolfSSL version. - - - detect `HAVE_WOLFSSL_DES_ECB_ENCRYPT`. - (needs e.g. `--enable-curl` when building wolfSSL) - - - detect `HAVE_WOLFSSL_FULL_BIO` and enable HTTPS-proxy feature. - (needs e.g. `--enable-opensslall` when building wolfSSL) - - - fix to show `HTTPS-proxy` in cmake feature list. - Ref: 55807e6c056f27846d70cec70ee6ac3f0e5b3bbe #9962 - - - fix to show `NTLM` in cmake feature list. - - - fix to show `smb` and `smbs` in cmake protocol list. - - - add wolfSSL CMake job to GHA (for macOS). - - - fix mqtt and wolfSSL symbol clash. - ``` - ./curl/lib/mqtt.c: In function 'mqtt_doing': - ./curl/lib/mqtt.c:746:17: error: declaration of 'byte' shadows a global dec - laration [-Werror=shadow] - 746 | unsigned char byte; - | ^~~~ - /opt/homebrew/Cellar/wolfssl/5.7.0_1/include/wolfssl/wolfcrypt/types.h:85:3 - 6: note: shadowed declaration is here - 85 | typedef unsigned char byte; - | ^~~~ - ``` - - - format `FindWolfSSL.cmake` closer to neighbours. - - Closes #14064 - -Daniel Stenberg (1 Jul 2024) - -- curl_url_set: elaborate on scheme guessing - - Explain a little more and refer to the CURLU_NO_GUESS_SCHEME flag - for getting scheme or URL. - - Closes #14071 - -- docs: misc language polish - - - CURLINFO_FILETIME*: improve language - - add '32bit' and '64bit' as bad words, use 32-bit and 64-bit - - mksymbolsmanpage.pl: avoid "will" - - Closes #14070 - -- curl_easy_escape: elaborate a little on encoding a URL - - Closes #14069 - -Viktor Szakats (1 Jul 2024) - -- cmake: fix feature and protocol lists for SecureTransport - - NTLM was missing from the features list, and SMB/SMBS from - the protocols list in SecureTransport builds. - - Follow-up to 76a9c3c4be10b3d4d379d5b23ca76806bbae536a #3619 - - Reported-by: Tal Regev - Bug: https://github.com/curl/curl/pull/13963#issuecomment-2178791390 - Closes #14065 - -Daniel Stenberg (1 Jul 2024) - -- curl_str[n]equal.md: tidy up text to make them stand-alone - - Previously this was one single manpage for two functions but as they are - two separate ones since a while back, they should each clearly document - their single specific functions. - - Follow-up to eefcc1bda4bc - - Closes #14068 - -- RELEASE-NOTES: synced - -Tal Regev (30 Jun 2024) - -- GHA: use vcpkg to install packages for MSVC jobs - - - enable new dependencies for existing jobs. - - - add cache for vcpkg packages. - - - tidy-up CMake options and environment for vcpkg. - - Closes #13979 - -Daniel Stenberg (30 Jun 2024) - -- curl_mprintf.md: add missing comma - -- CURLOPT_TLSAUTH_PASSWORD/USERNAME.md: language fixups - - - relies *on* TLS SRP - - *for* the specific TLS backends - - Closes #14061 - -- docs/libcurl: polish the single-line descriptions - - - use imperative form - - use lowercase - - no period - - unify some phrases - - fix curl_multi_socket and curl_multi_socket_all to keep their own - descriptions - - Closes #14062 - -Viktor Szakats (30 Jun 2024) - -- cmake: alpha-sort feature list - - Like autotools does. - - Closes #14063 - -renovate[bot] (29 Jun 2024) - -- GHA: update github/codeql-action digest to b611370 - - Closes #14058 - -Tatsuhiro Tsujikawa (29 Jun 2024) - -- vquic: fix UDP_GRO struct cmsghdr data type - - The data type for UDP_GRO in struct cmsghdr is int. Limit the usage of - UDP_GRO to linux only because it is not portable. - - Closes #14056 - -Sertonix (29 Jun 2024) - -- mk-ca-bundle.pl: delay 'curl -V' execution until it is needed - - Avoid an `Can't exec "curl"` message when curl is not actually needed. - - Closes #14060 - -Daniel Stenberg (29 Jun 2024) - -- src/Makefile.am: remove SUBDIRS assignment - - It was once used to continue into ../docs but is just leftovers now. - - Closes #14054 - -z2_ (28 Jun 2024) - -- x509asn1: remove superfluous free() - -Stefan Eissing (28 Jun 2024) - -- ngtcp2+quictls: fix cert-status use - - - add test for --cert-status on all http versions - - Reported-by: Dexter Gerig - Fixes #14049 - Closes #14050 - -Daniel Stenberg (28 Jun 2024) - -- RELEASE-PROCEDURE.md: update release date - -- managen: insert final .fi for files ending with a quote - - When an individual file ended with a quote (typically an example), the - render function would return without ending the quote correctly with a - ".fi" (fill in) in the manpage output. - - This made the additional text provided below to render wrongly. - - Closes #14048 - -Junho Choi (28 Jun 2024) - -- quic: update to quiche 0.22.0 - - quiche 0.22.0 will set SONAME in libquiche.so (libquiche.so.0) for - linux/BSDs. Install a symlink with SONAME. - - Closes #14030 - Closes #14046 - -Daniel Stenberg (28 Jun 2024) - -- managen: introduce "Multi: per-URL" - - For -O, -o and -T that are used once per specified URL. - - Closes #14045 - -- quiche: fix operand of ‘?:’ changes signedness - - ... from ‘int’ to ‘curl_uint64_t’ - - Closes #14041 - -- GHA: add --enable-werror to the quiche job - - Closes #14041 - -- KNOWN_BUGS: three new bugs - - These have lingered in the issue tracker for a long time without action. - We don't expect any fixes in the near term either. Move them to the - KNOWN_BUGS document. - - Closes #12177 - Closes #12171 - Closes #13350 - - Closes #14042 - -Viktor Szakats (27 Jun 2024) - -- CI: add whitespace checker - - Fix issues detected. - - Also: - - - One of the `.vc` files used LF EOLs, while the other didn't. - Make that one also use LF EOLs, as this is apparently supported by - `nmake`. - - - Drop `.dsw` and `.btn` types from `.gitattributes`. - The repository doesn't use them. - - - Sync section order with the rest of files in - `tests/certs/EdelCurlRoot-ca.prm`. - - - Indent/align `.prm` and `.pem` files. - - - Delete dummy `[something]` section from `.prm` and `.pem` files. - - Mental note: - MSVC `.sln` files seem to accept spaces for indentation and also support - LF line-endings. I cannot test this and I don't know what's more - convenient when updating them, so left them as-is, with specific - exclusions. - - Closes #14031 - -- CI: fix typo in job name - - Closes #14040 - -Stefan Eissing (27 Jun 2024) - -- tests/httpd: adjust ReadBufferSize for better performance - - - list httpd and caddy versions in scorecard run - - Closes #14039 - -Daniel Stenberg (27 Jun 2024) - -- runtests: fix %VERNUM - - It needs to be set to the leading digits and dots only, so that the - `-[date]` suffix strings are not included, as those used in the daily - snapshots. - - Fixes #14035 - Reported-by: Marcel Raad - Closes #14036 - -Philip Heiduck (27 Jun 2024) - -- CI/synopsis.yml: run on `.md` files - - Reported-by: Viktor Szakats - Fixes #14032 - Closes #14037 - -Daniel Stenberg (27 Jun 2024) - -- verify-synopsis.pl: work with .md files - - Ref: #14037 - Closes #14038 - -- conncache: done always evaluates to false - - Follow-up to c9b95c0bb30f88bf00e1ac - - Spotted by CodeSonar - - Reviewed-by: Stefan Eissing - Closes #14034 - -- lib: add a few DEBUGASSERT(data) to aid code analyzers - - ... where 'data' is assumed to always work. - - Closes #14033 - -- RELEASE-NOTES: synced - -Viktor Szakats (26 Jun 2024) - -- tidy-up: use `/usr/bin/env perl` shebang - - Most Perl scripts already used it. Sync up the few outliers. - - Closes #14029 - -Stefan Eissing (26 Jun 2024) - -- quic: openssl quic, cmake and doc version update to 3.3.0 - - Closes #14028 - -- http/3: add shutdown support - - - openssl-quic shutdown handling - - ngtcp2 shutdown handling - - quiche shutdown handling - - add test_19_06 for verfication - - Reported-by: Dexter Gerig - Closes #14027 - Fixes #14022 - -Daniel Stenberg (26 Jun 2024) - -- tests: verify managen - - 1705: verifies the manpage output - - 1706: verifies the ascii output - - Closes #14025 - -- runtests: support %DATE for YYYY-MM-DD of right now - -- runtests: support %VERNUM - - For the plain version number of the built curl without -DEV etc. Only - digits and dots. - -- managen: only output .RE for manpage output - - For ascii they are just rubbish. - - Closes #14025 - -Tatsuhiro Tsujikawa (26 Jun 2024) - -- quic: enable UDP GRO - - Closes #14012 - -Stefan Eissing (26 Jun 2024) - -- quic: require at least OpenSSL 3.3 for QUIC - - - when checking for QUIC support in OpenSSL, also check - for it being at least 3.3.0 - - remove workarounds for features buggy or missing in 3.2 - - Closes #14026 - -Daniel Stenberg (26 Jun 2024) - -- FILEFORMAT.md: mentioned for "client" - - They can be used to create more files. - - Closes #14024 - -Marcel Raad (26 Jun 2024) - -- system_win32: add missing curl.h include - - It's required for `CURLcode`. - - Closes https://github.com/curl/curl/pull/14019 - -Daniel Stenberg (26 Jun 2024) - -- TODO: specify which response codes that make -f/--fail return error - - Suggestion from the user survey 2024 - - Closes #14020 - -Stefan Eissing (26 Jun 2024) - -- lib: graceful connection shutdown - - When libcurl discards a connection there are two phases this may go - through: "shutdown" and "closing". If a connection is aborted, the - shutdown phase is skipped and it is closed right away. - - The connection filters attached to the connection implement the phases - in their `do_shutdown()` and `do_close()` callbacks. Filters carry now a - `shutdown` flags next to `connected` to keep track of the shutdown - operation. - - Filters are shut down from top to bottom. If a filter is not connected, - its shutdown is skipped. Notable filters that *do* something during - shutdown are HTTP/2 and TLS. HTTP/2 sends the GOAWAY frame. TLS sends - its close notify and expects to receive a close notify from the server. - - As sends and receives may EAGAIN on the network, a shutdown is often not - successful right away and needs to poll the connection's socket(s). To - facilitate this, such connections are placed on a new shutdown list - inside the connection cache. - - Since managing this list requires the cooperation of a multi handle, - only the connection cache belonging to a multi handle is used. If a - connection was in another cache when being discarded, it is removed - there and added to the multi's cache. If no multi handle is available at - that time, the connection is shutdown and closed in a one-time, - best-effort attempt. - - When a multi handle is destroyed, all connection still on the shutdown - list are discarded with a final shutdown attempt and close. In curl - debug builds, the environment variable `CURL_GRACEFUL_SHUTDOWN` can be - set to make this graceful with a timeout in milliseconds given by the - variable. - - The shutdown list is limited to the max number of connections configured - for a multi cache. Set via CURLMOPT_MAX_TOTAL_CONNECTIONS. When the - limit is reached, the oldest connection on the shutdown list is - discarded. - - - In multi_wait() and multi_waitfds(), collect all connection caches - involved (each transfer might carry its own) into a temporary list. - Let each connection cache on the list contribute sockets and - POLLIN/OUT events it's connections are waiting for. - - - in multi_perform() collect the connection caches the same way and let - them peform their maintenance. This will make another non-blocking - attempt to shutdown all connections on its shutdown list. - - - for event based multis (multi->socket_cb set), add the sockets and - their poll events via the callback. When `multi_socket()` is invoked - for a socket not known by an active transfer, forward this to the - multi's cache for processing. On closing a connection, remove its - socket(s) via the callback. - - TLS connection filters MUST NOT send close nofity messages in their - `do_close()` implementation. The reason is that a TLS close notify - signals a success. When a connection is aborted and skips its shutdown - phase, the server needs to see a missing close notify to detect - something has gone wrong. - - A graceful shutdown of FTP's data connection is performed implicitly - before regarding the upload/download as complete and continuing on the - control connection. For FTP without TLS, there is just the socket close - happening. But with TLS, the sent/received close notify signals that the - transfer is complete and healthy. Servers like `vsftpd` verify that and - reject uploads without a TLS close notify. - - - added test_19_* for shutdown related tests - - test_19_01 and test_19_02 test for TCP RST packets - which happen without a graceful shutdown and should - no longer appear otherwise. - - add test_19_03 for handling shutdowns by the server - - add test_19_04 for handling shutdowns by curl - - add test_19_05 for event based shutdowny by server - - add test_30_06/07 and test_31_06/07 for shutdown checks - on FTP up- and downloads. - - Closes #13976 - -Daniel Stenberg (25 Jun 2024) - -- managen: fix blank line detection - - Follow-up to d14a53eea7b87 which ruined the output somewhat. - - Closes #14017 - -- managen: output tabs for each 8 leading spaces - - This replacing of eight leading spaces into tabs was already done for - the embedded uncompressed version in tool_hugehelp.c so it does not save - anything there. But the gzip compressed version ends up almost 2K - smaller. - - The output in a terminal should be identical. - - Before using TABs: - - curl.txt 282492 bytes - curl.txt.gz 73261 bytes - - With this change applied: - - curl.txt 249382 bytes - curl.txt.gz 71470 bytes - - Closes #14016 - -- managen: error on trailing blank lines in input files - - Ref: #14014 - Closes #14015 - -Viktor Szakats (25 Jun 2024) - -- tidy-up: more whitespace - - Closes #14014 - -Stefan Eissing (25 Jun 2024) - -- multi: multi_getsock(), check correct socket - - - in phase CONNECTING/TUNNELING/PROTOCONNECT, retrieve - the socket from the connection filters and do not rely - on `conn->sockfd` being already set by the transfer. - - this applies to the default behaviour, a protocol handler - may override this via its callbacks. - - add a warning message in multi_getsock() when the transfer - is expected to have something in its pollset, but instead - it is empty. - - Reported-by: saurabhsingh-dev on github - Fixes #13998 - Closes #14011 - -Daniel Stenberg (25 Jun 2024) - -- managen: fix each options footer to end with newline - - A previous change sometimes made a command line option's description not - end with a newline immediately before the next command line. - - Also widened the lines to wrap on column 79 instead of 78. - - Closes #14010 - -Alex Snast (25 Jun 2024) - -- wolfssl: assume key_file equal to clientcert in the absence of key_file - - When user sets CURLOPT_SSLCERT but leaves CURLOPT_SSLKEY unset assume - the path passed in CURLOPT_SSLCERT holds the ssl key which is what we do - in openssl implementation. - - Fixes #14007 - Closes #14008 - -Viktor Szakats (24 Jun 2024) - -- autotools: fix pkg-config names (zstd, ngtcp2*) - - Also verified that all names now match up with CMake. - - Follow-up to f057de5a1a950a90d1920021db152a4b695f1a8a #13911 - Follow-up to eeab0ea7aa19af61af881e8a0bf9ff1f2e28ef79 #13994 - Reported-by: 李四 - Fixes #14005 - Closes #14006 - -- tidy-up: whitespace [ci skip] - -Daniel Stenberg (24 Jun 2024) - -- cmdline-docs: "added in" cleanups - - - markup fixes - - remove some mentions of < 7.60.0 changes - - Closes #14003 - -- RELEASE-NOTES: synced - -- managen: "added in" fixes - - - up the limit: remove all mentions of 7.60 or earlier from manpage - 7.60 is 6 years old now. - - warn on "broken" added in lines, as they avoid detection - - fixup added in markup in a few curldown files - - Closes #14002 - -Matt Jolly (24 Jun 2024) - -- configure: fix pkg-config library name 'libnghttp3' - - Closes #13994 - -Daniel Stenberg (24 Jun 2024) - -- managen: cleanups to generate nicer-looking output - - - output "see also" last - - when there are multiple mutex items, use commas between all of them - except the last. - - call them mututally exclusive WITH not TO other options. - - remove trailing space from added in, add newline prefix - - smoother language for requires - - Closes #14001 - -- configure: require a QUIC library if nghttp3 is used - - Instead of just silently disabling HTTP/3. - - Reported-by: Matt Jolly - Fixes #13995 - Closes #13999 - -- docs/cmdline-opts: remove two superfluous "Added in" mentions - - The key "added in" phrase for the option itself is added automatically. - - Closes #14000 - -- cookie-jar.md: see also --junk-session-cookies - - Closes #13996 - -- runtests: support crlf="yes" for the section - -- TODO: -h option - - Support "curl -h --insecure" etc to output the manpage section for the - --insecure command line option in the terminal. Should be possible to - work with either long or short versions of command line options. - - Closes #13990 - -- trace-ascii.md: mention "%" for stderr - - Closes #13991 - -- connect-to.md: expand with examples - - - add referer from the resolve section to connect-to if user wants - wildcard for the port number - - Closes #13989 - -- TODO: connect to multiple IPs in parallel - - Closes #13986 - -- dump-header.md: mention minus for stdout - - Closes #13985 - -- CURLOPT_RESOLVE.md: mention hostname can be wildcard ('*') - - Closes #13983 - -Andy Pan (22 Jun 2024) - -- cf-socket: optimize curlx_nonblock() and check its return error - - Reviewed-by: Stefan Eissing - Closes #13942 - -z2_ (22 Jun 2024) - -- x509asn1: prevent NULL dereference - - Closes #13978 - -Daniel Stenberg (19 Jun 2024) - -- unit2604: use 'unitfail' instead of 'error' variable - - Since the framework is already returning that variable by default. - Avoids a warning for unreachable code. - - Reported-by: Tal Regev - Fixes #13967 - Closes #13973 - -- KNOWN_BUGS: TFTP tests fail on OpenBSD - - Closes #13623 - Closes #13975 - -- VULN-DISCLOSURE-POLICY: NULL dereferences and crashes - - If a malicious server can trigger a NULL dereference in curl or - otherwise cause curl to crash (and nothing worse), chances are big that - we do not consider that a security problem. - - Closes #13974 - -- RELEASE-NOTES: synced - -Sergey Markelov (19 Jun 2024) - -- mbedtls: support CURLOPT_CERTINFO - - Closes #13113 - -Daniel Stenberg (19 Jun 2024) - -- x509asn1: ASN1tostr() should fail when 'constructed' is set - - This is a regression from my refactor in 623c3a8fa0bdb (#12808) - - Follow-up to 623c3a8fa0bdb2751f14b37417 - - Closes #13972 - -- x509asn1: remove two static variables - - cnOID and sanOID were not used outside of the OID table anyway - - Closes #13971 - -brian m. carlson (18 Jun 2024) - -- TODO: TLS channel binding - - Closes #13483 - -Tal Regev (17 Jun 2024) - -- cmake: add CURL_USE_GSASL option with detection + CI test - - Reviewed-by: Viktor Szakats - Closes #13948 - -Daniel Stenberg (16 Jun 2024) - -- x509asn1: make Curl_extract_certinfo store error message - - To help us all better understand where the error actually comes from. - - Ref: #13958 - Closes #13959 - -Viktor Szakats (15 Jun 2024) - -- appveyor: dump build logs on failure in VS2008 jobs - - This seems to be the only way to see what actual toolchain commands were - run, and with what arguments. - - Without `dos2unix`, `cat` output comes out empty. - - Closes #13957 - -- cmake: fix quotes when appending multiple options (SecureTransport) - - Copied from a vcpkg distro patch: - https://github.com/microsoft/vcpkg/blob/02745e0f4749d1f51d2025824209408f5a6c3 - 614/ports/curl/dependencies.patch#L43C38-L44 - - Ref: https://github.com/microsoft/vcpkg/pull/38847 - Ref: https://github.com/microsoft/vcpkg/commit/795f2f137e6cf6d985fcc927bffcaf - 9c0a96e4ac - Ref: https://github.com/microsoft/vcpkg/pull/38847/commits/36f0c917de5319e953 - 61451fc0aef0698b264874#diff-ab5c23e5dc5df412539cc93e24b37abbc588e1918236f8abc - 019d676b270c85fR39 (sub-commit) - - Authored-by: Kai Pastor - Closes #13953 - -Daniel Stenberg (15 Jun 2024) - -- CURLOPT_NETRC.md: clarify what it does on Windows - - Closes #13956 - -- KNOWN_BUGS: "HTTP/2 + TLS spends a lot of time in recv" - - Closes #13416 - Closes #13955 - -- RELEASE-NOTES: synced - -Yedaya Katsman (14 Jun 2024) - -- examples: add missing binaries to .gitignore - - They were showing as changed when built. Add them sorted alphabetically, - while also moving a few more entries to sorted order. - - Closes #13952 - -- docs: reference non deprecated libcurl options - - There are a places where man pages reference deprecated CURLOPT options, - where it doesn't make sense, replace them with the reccomended - replacement option. - - also remove reference to the removed mesalink TLS backend - - Closes #13951 - -Daniel Stenberg (14 Jun 2024) - -- gnutls: pass in SNI name, not hostname when checking cert - - The function we use is called 'gnutls_x509_crt_check_hostname()' but if - we pass in the hostname with a trailing dot, the check fails. If we pass - in the SNI name, which cannot have a trailing dot, it succeeds for - https://pyropus.ca./ - - I consider this as a flaw in GnuTLS and have submitted this issue - upstream: - - https://gitlab.com/gnutls/gnutls/-/issues/1548 - - In order to work with old and existing GnuTLS versions, we still need - this change no matter how they view the issue or might change it in the - future. - - Fixes #13428 - Reported-by: Ryan Carsten Schmidt - Closes #13949 - -- BINDINGS: update java link to one that exists - - The previous java binding seems to have vanished. Link to one that still - exists. - - Bug: https://github.com/curl/everything-curl/issues/456 - Reported-by: Jiang Wenjian - Closes #13950 - -renovate[bot] (14 Jun 2024) - -- GHA: update pinned actions - - - github/codeql-action digest to 23acc5c - - actions/checkout digest to 692973e - - rojopolis/spellcheck-github-actions digest to d354a4d - - Closes #13935 - Closes #13945 - Closes #13946 - -Jay Satiro (14 Jun 2024) - -- tool_cb_hdr: allow etag and content-disposition for 3xx reply - - - Parse etag and content-disposition headers for 3xx replies. - - For example, a server may send a content-disposition filename header - with a redirect reply (3xx) but not with the final response (2xx). - Without this change curl would ignore the server's specified filename - and continue to use the filename extracted from the user-specified URL. - - Prior to this change, 75d79a4 had limited etag and content-disposition - to 2xx replies only. - - Tests-by: Daniel Stenberg - - Reported-by: Morgan Willcock - Fixes https://github.com/curl/curl/issues/13302 - Closes #13484 - -Daniel Stenberg (13 Jun 2024) - -- transfer: set CSELECT_IN if there is data pending - - When aborting the transfer loop early, like when there is rate limiting - in effect, there might be buffered data already read off the socket so - the socket might not signal reability. Therefore we must set the - CSELECT_IN manually if data_pending_() suggests there might be more data - to get. This is particularly noticeable with SSH when the underlying - library has drained the socket and holds pending data in its buffer. - - Reported-by: alervd on github - Fixes #13695 - Closes #13943 - -Viktor Szakats (13 Jun 2024) - -- cmake: enable SOVERSION for Cygwin and `CMAKE_DLL_NAME_WITH_SOVERSION` - - - enable SOVERSION when `CMAKE_DLL_NAME_WITH_SOVERSION=ON` is set. - Ref: https://cmake.org/cmake/help/v3.27/variable/CMAKE_DLL_NAME_WITH_SOVERS - ION.html - Use: https://github.com/search?q=-DCMAKE_DLL_NAME_WITH_SOVERSION&type=code - - - enable SOVERSION for Cygwin builds by default. - - Ref: #13936 - Ref: #13944 - Closes #13898 - -- cmake: allow SOVERSION override with `CURL_LIBCURL_SOVERSION` - - Allow overriding SOVERSION with the new CMake option: - `CURL_LIBCURL_SOVERSION=ON/OFF` - - For certain target platforms the shared libcurl library filename - contains the SOVERSION. This new option allows to enable/disable - this behavior manually. If set, it takes precedence over the default - setting. - - Ref: #13898 - Closes #13944 - -renovate[bot] (13 Jun 2024) - -- Dockerfile: update debian:bookworm-slim to 84d83b2 - - Closes #13934 - -Daniel Stenberg (13 Jun 2024) - -- configure: use AC_MSG_WARN for TLS/experimental warning texts - - - no longer warns for mbedtls - - warns for each item on individual lines - - no longer shows irrelevant TLS libraries when multiple are selected - - removes ech repetition - - Closes #13941 - -- GHA: detect and warn for more English contractions - - As we try to avoid them in curl documentation - - Closes #13940 - -Stefan Eissing (13 Jun 2024) - -- transfer: do not use EXPIRE_NOW while blocked - - - When a transfer sets `data->state.select_bits`, it is - scheduled for rerun with EXPIRE_NOW. If such a transfer - is blocked (due to PAUSE, for example), this will lead to - a busy loop. - - multi.c: check for transfer block - - sendf.*: add Curl_xfer_is_blocked() - - sendf.*: add client reader `is_paused()` callback - - implement is_paused()` callback where needed - - Closes #13908 - -renovate[bot] (13 Jun 2024) - -- ci: update dependency ngtcp2/ngtcp2 to v1.6.0 - - Closes #13939 - -- ci: update ngtcp2/nghttp3 to v1.4.0 - - Closes #13938 - -Viktor Szakats (13 Jun 2024) - -- cmake: stop setting SOVERSION for the static lib target - - Also move the logic closer to its use and related tidy-ups. - - Cherry-picked from #13898 - Closes #13936 - -Patrick Monnerat (13 Jun 2024) - -- os400: make it compilable again - - A newly introduced use of getsockname() in the cli tool makes it require - the ascii wrapper module, which is not available outside of the library: - as the tool only uses the address family field (binary), disable - wrappers outside of libcurl. - - Fix setsockopt() parameter type mismatch using a (void *) cast. - - Sync ILE/RPG binding. - - Closes #13930 - -Viktor Szakats (13 Jun 2024) - -- libcurl.pc: add `Requires.private`, `Requires` for static linking - - - cmake: populate for dependencies. - - autotools: populate for dependencies. - (including mbedtls, though the script does not detect - mbedtls through pkgconfig. mbedtls 3.6.0 now supports it.) - - Skip dealing with gssapi in this patch. - - Fixes #864 - Closes #13911 - -- cmake: bring `curl-config.cmake` closer to `FindCURL` - - Set `CURL_LIBRARIES` and `CURL_INCLUDE_DIRS` variables - for compatibility with CMake's `FindCURL.cmake`: - https://github.com/Kitware/CMake/blob/b411d0146c2e06acfb0c823bb039e99f0191b61 - 1/Modules/FindCURL.cmake#L209 - - For dependent projects, CMake's suggestion is to replace - `CURL_LIBRARIES` with `CURL::libcurl`, and drop `CURL_INCLUDE_DIRS`. - - Reported-by: Aurélien Pierre - Ref: https://curl.se/mail/lib-2024-06/0014.html - Ref: https://gitlab.kitware.com/cmake/cmake/-/issues/24580 - Closes #13897 - -Daniel Stenberg (13 Jun 2024) - -- tool_getparam: fix the bsearch call for ip-tos names - - Follow-up to 3c20ae08b9591 - Reported-by: Samuel Chiang - Fixes #13932 - Closes #13933 - -- request: change the struct field bodywrites to a bool, only for hyper - - Only hyper needs to know this, and it can use it as a boolean. - - Closes #13928 - -Andy Pan (12 Jun 2024) - -- test: fix CURLOPT_TCP_KEEPCNT typo - - Follow up to b77d627d242 - - Closes #13931 - -Daniel Stenberg (12 Jun 2024) - -- http: remove "struct HTTP" - - It is not actually used anymore and only contained a dummy struct field. - Remove all traces and uses of it. - - Closes #13927 - -- cd2nroff: convert two warnings to errors - - Since the warnings tend to get missed too easily and these are problems - we rather want addressed than letting slide. - - Closes #13929 - -- urlapi: use a correct value for CURLU_NO_GUESS_SCHEME - - It was mistakenly set to the same value as CURLU_GET_EMPTY uses. - - Reported-by: Patrick Monnerat - Bug: https://github.com/curl/curl/commit/655d44d139489625e77cf6790d36 - Closes #13926 - -- file: separate fake headers and body with a stand-alone CRLF - - Instead of bolting on the extra CRLF to the final header - as that makes - the behavior inconsistent and not as documented. The final CRLF is now - also made unconditional, just like it is for HTTP. - - Reported-by: dogma - Bug: https://curl.se/mail/lib-2024-06/0033.html - Closes #13925 - -- RELEASE-NOTES: synced - -Andy Pan (12 Jun 2024) - -- tcpkeepalive: add CURLOPT_TCP_KEEPCNT and --keepalive-cnt - - Closes #13885 - -Daniel Stenberg (12 Jun 2024) - -- TODO: make it "Add missing features to TLS backends" - - ... instead of just mentioning CA caching. - - Closes #13924 - -Orgad Shaneh (11 Jun 2024) - -- curl: support VLAN Priority: --vlan-priority - - Add --vlan-priority option to the command line tool for setting VLAN - priority. - - Closes #13907 - -RainRat (11 Jun 2024) - -- misc: fix typos - - Closes #13923 - -Daniel Stenberg (11 Jun 2024) - -- CURLOPT_ECH.md: remove repeated 'if' - - Closes #13922 - -- vms: fixed language in comment - - It started with me fixing a repeated "are are" but the wording was - incomprehensible so I tried to untangle it. - - Closes #13921 - -Stefan Eissing (11 Jun 2024) - -- lib: xfer_setup and non-blocking shutdown - - - clarify Curl_xfer_setup() with RECV/SEND flags and different calls for - which socket they operate on. Add a shutdown flag for secondary - sockets - - change Curl_xfer_setup() calls to new functions - - implement non-blocking connection shutdown at the end of receiving or - sending a transfer - - Closes #13913 - -Daniel Stenberg (11 Jun 2024) - -- test1486: verify that write-out.md and tool_writeout.c are in sync - - - also verify alphabetialal order in the source - - add two missing variables to write-out.md - - Closes #13920 - -Viktor Szakats (11 Jun 2024) - -- GHA: add cmake MSYS2 native job - - curl, libcurl, examples, build-only. - - To compare build behaviour with autotools. - - Closes #13917 - -Daniel Stenberg (11 Jun 2024) - -- openssl: shortcut store_expired for negative timeouts - - Avoid some unnecessary computation if the timeout is negative. - - Spotted by CodeSonar - Closes #13919 - -- RELEASE-NOTES: synced - -- curl: support -w '%{num_retries} - - Suggested-by: Jay Guerette - Ref: https://github.com/curl/curl/discussions/13901 - Closes #13910 - -Guilherme Puida (11 Jun 2024) - -- pytest: include testenv/vsftpd.py in dist tarball - - Closes #13918 - -Viktor Szakats (11 Jun 2024) - -- DISTROS: add MSYS2 (native) links - - Also rename existing 'MSYS2' to 'MSYS2 (mingw-w64)'. - - Closes #13915 - -Daniel Stenberg (10 Jun 2024) - -- tool_writeout: get certinfo only when needing it - - Removes a fairly expensive libcurl call when not necessary - - Closes #13914 - -- tool_writeout: bsearch the variable name - - As the list of variable names grows, doing a simple loop to find the - name get increasingly worse. This switches to a bsearch. - - Also: do a case sensitive check for the variable name. The names have - not been documented to be case insensitive and there is no point in - having them so. - - Closes #13914 - -Stefan Eissing (10 Jun 2024) - -- multi: prepare multi_wait() for future shutdown usage - - - new struct curl_pollfds and struct curl_waitfds - - add structs and methods to init/add/cleanup an array of pollfd and - struct curl_waitfd. Use in multi_wait() and multi_waitfds() to - populate the sets for polling. - - place USE_WINSOCK WSAEventSelect() setting into a separate loop over - all collected pfds - - Closes #13900 - -- connection: shutdown TLS (for FTP) better - - This adds connection shutdown infrastructure and first use for FTP. FTP - data connections, when not encountering an error, are now shut down in a - blocking way with a 2sec timeout. - - - add cfilter `Curl_cft_shutdown` callback - - keep a shutdown start timestamp and timeout at connectdata - - provide shutdown timeout default and member in - `data->set.shutdowntimeout`. - - provide methods for starting, interrogating and clearing - shutdown timers - - provide `Curl_conn_shutdown_blocking()` to shutdown the - `sockindex` filter chain in a blocking way. Use that in FTP. - - add `Curl_conn_cf_poll()` to wait for socket events during - shutdown of a connection filter chain. - This gets the monitoring sockets and events via the filters - "adjust_pollset()" methods. This gives correct behaviour when - shutting down a TLS connection through a HTTP/2 proxy. - - Implement shutdown for all socket filters - - for HTTP/2 and h2 proxying to send GOAWAY - - for TLS backends to the best of their capabilities - - for tcp socket filter to make a final, nonblocking - receive to avoid unwanted RST states - - add shutdown forwarding to happy eyeballers and - https connect ballers when applicable. - - Closes #13904 - -Daniel Stenberg (7 Jun 2024) - -- CURLOPT_CONNECTTIMEOUT*: clarify, document the milliseond version - - Provide an explanation in the CURLOPT_CONNECTTIMEOUT_MS page instead of - just referring to the non-MS version. - - Closes #13905 - -- cmdline-opts: tidy up --ip-tos and --mptcp - - To make them render nicer in the manpage and minor polish. - - Closes #13906 - -- RELEASE-NOTES: synced - -Dorian Craps (7 Jun 2024) - -- curl: (on linux) add MPTCP support - - Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension - that enables a TCP connection to use different paths. - - Multipath TCP has been used for several use cases. On smartphones, MPTCP - enables seamless handovers between cellular and Wi-Fi networks while - preserving established connections. This use-case is what pushed Apple - to use MPTCP since 2013 in multiple applications [2]. On dual-stack - hosts, Multipath TCP enables the TCP connection to automatically use the - best performing path, either IPv4 or IPv6. If one path fails, MPTCP - automatically uses the other path. - - To benefit from MPTCP, both the client and the server have to support - it. Multipath TCP is a backward-compatible TCP extension that is enabled - by default on recent Linux distributions (Debian, Ubuntu, Redhat, ...). - Multipath TCP is included in the Linux kernel since version 5.6 [3]. To - use it on Linux, an application must explicitly enable it when creating - the socket. No need to change anything else in the application. - - This attached patch adds an --mptcp option which allows the creation of - an MPTCP socket instead of TCP on Linux. If Multipath TCP is not - supported on the system, an error will be reported. It is important to - note that if the end server doesn't support MPTCP, the connection will - continue after a seamless fallback to TCP. - - Link: https://www.rfc-editor.org/rfc/rfc8684.html [1] - Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2] - Link: https://www.mptcp.dev [3] - Co-developed-by: Dorian Craps (@CrapsDorian) - Co-developed-by: Olivier Bonaventure (@obonaventure) - Co-developed-by: Matthieu Baerts (@matttbe) - Signed-off-by: Dorian Craps - - Closes #13278 - -Orgad Shaneh (7 Jun 2024) - -- curl: support IP Type of Service / Traffic Class: --ip-tos - - Add --ip-tos option to the command line tool for setting TOS for IPv4 or - Traffic Class for IPv6. - - Closes #13606 - -Andy Pan (7 Jun 2024) - -- socketpair: provide `Curl_socketpair` only when `!CURL_DISABLE_SOCKETPAIR` - - Ref: https://curl.se/dev/log.cgi?id=20240605035856-3529577 - - Reported-by: Marcel Raad - Closes #13888 - -Daniel Stenberg (7 Jun 2024) - -- noproxy: test bad ipv6 net size first - - No need to parse anything if the size is out of range. - - Added some tests to this effect to test 1614. - - Closes #13902 - -- managen: warn on excessively long help texts - - Help texts at 49 characters or longer get a warning displayed because - they make --help output uglier and we should make an effort to keep the - help texts short and succinct. - - The warning is only for display, it does not break the build. That is - left for the future if necessary. - - I picked 49 because the longest current text is 48. - - Closes #13895 - -Viktor Szakats (5 Jun 2024) - -- lib: tidy up types and casts - - Cherry-picked from #13489 - Closes #13862 - -Daniel Stenberg (5 Jun 2024) - -- cmdline-opts/ech.md: shorten the help text - - To make --help look sensible again - - Closes #13894 - -- cmdline-opts/_PROTOCOLS.md: mention WS(S) - - Closes #13891 - -Viktor Szakats (5 Jun 2024) - -- GHA: disable TFTP and WebSockets tests in old-mingw-w64 - - Follow-up to 03bd16e5339b069aa9409b75fcab2b21fd3a4b16 #13860 - Follow-up to def7d05382743ea7aa1d356d1e41dcb22ecdd4d7 - -Daniel Stenberg (5 Jun 2024) - -- cmdline-opts/fail.md: expand and clarify - - Closes #13890 - -- doh-insecure.md: expand - - Closes #13889 - -- cmdline: expand proxy option explanations - - - do less references to other options - - provide more specific text about proxies - - added more see-also references - - Closes #13887 - -- cmdline-opts: expand the parallel explanations - - Closes #13886 - -- RELEASE-NOTES: synced - -Stefan Eissing (5 Jun 2024) - -- vtls: new io_need flags for poll handling - - - decouple need to recv/send from negotiation state, we need - this later in shutdown handling as well - - move ssl enums from urldata.h to vtls_int.h - - implement use of `connssl->io_need` in vtls.c. and all backends - - Closes #13879 - -Daniel Stenberg (5 Jun 2024) - -- cfilters: make Curl_conn_connect always assign 'done' - - It could return error without assigning it, and we have a caller in - multi.c that assumes it gets set. - - Spotted by CodeSonar - Closes #13884 - -- CURLOPT_INTERFACE.md: quote the less-than and larger-than - - Fixes the warnings shown on stderr. - - Follow-up from 3060557af702dd5 - - Closes #13883 - -- cmdline-opts/interface.md: expand the documentation - - Explain the syntax it supports. - - Closes #13882 - -- url: allow DoH transfers to override max connection limit - - When reaching the set maximum limit of allowed connections, allow a new - connection anyway if the transfer is created for the (internal) purpose - of doing a DoH name resolve. Otherwise, unrelated "normal" transfers can - starve out new DoH requests making it impossible to name resolve for new - transfers. - - Bug: https://curl.se/mail/lib-2024-06/0001.html - Reported-by: kartatz - Closes #13880 - -Viktor Szakats (5 Jun 2024) - -- windows: fix UWP builds, add GHA job - - Add new job to test building for UWP (aka `CURL_WINDOWS_APP`). - - Fix fallouts when building for UWP: - - rand: do not use `BCryptGenRandom()`. - - cmake: disable using win32 LDAP. - - cmake: disable telnet. - - version_win32: fix code before declaration. - - schannel: disable `HAS_MANUAL_VERIFY_API`. - - schannel: disable `SSLSUPP_PINNEDPUBKEY` - and make `schannel_checksum()` a stub. - Ref: e178fbd40a896f2098278ae61e1166c88e7b31d0 #1429 - - schannel: make `cert_get_name_string()` a failing stub. - - system_win32: make `Curl_win32_impersonating()` a failing stub. - - system_win32: try to fix `Curl_win32_init()` (untested). - - threads: fix to use `CreateThread()`. - - src: disable searching `PATH` for the CA bundle. - - src: disable bold text support and capability detection. - - src: disable `getfiletime()`/`setfiletime()`. - - tests: make `win32_load_system_library()` a failing stub. - - tests/server/util: make it compile. - - tests/server/sockfilt: make it compile. - - tests/lib3026: fix to use `CreateThread()`. - - See individual commits for build error details. - - Some of these fixes may have better solutions, and some may not work - as expected. The goal of this patch is to make curl build for UWP. - - Closes #13870 - -Orgad Shaneh (4 Jun 2024) - -- socket: support binding to interface *AND* IP - - Introduce new notation for CURLOPT_INTERFACE / --interface: - ifhost!! - - Binding to an interface doesn't set the address, and an interface can - have multiple addresses. - - When binding to an address (without interface), the kernel is free to - choose the route, and it can route through any device that can access - the target address, not necessarily the one with the chosen address. - - Moreover, it is possible for different interfaces to have the same IP - address, on which case we need to provide a way to be more specific. - - Factor out the parsing part of interface option, and add unit tests: - 1663. - - Closes #13719 - -Andy Pan (4 Jun 2024) - -- socketpair: add `eventfd` and use `SOCK_NONBLOCK` for `socketpair()` - - Currently, we use `pipe` for `wakeup_create`, which requires ***two*** - file descriptors. Furthermore, given its complexity inside, `pipe` is a - bit heavyweight for just a simple event wait/notify mechanism. - - `eventfd` would be a more suitable solution for this kind of scenario, - kernel also advocates for developers to use `eventfd` instead of `pipe` - in some simple use cases: - - Applications can use an eventfd file descriptor instead of a pipe - (see pipe(2) in all cases where a pipe is used simply to signal - events. The kernel overhead of an eventfd file descriptor is much - lower than that of a pipe, and only one file descriptor is required - (versus the two required for a pipe). - - This change adds the new backend of `eventfd` for `wakeup_create` and - uses it where available, eliminating the overhead of `pipe`. Also, it - optimizes the `wakeup_create` to eliminate the system calls that make - file descriptors non-blocking by moving the logic of setting - non-blocking flags on file descriptors to `socketpair.c` and using - `SOCK_NONBLOCK` for `socketpair(2)`, `EFD_NONBLOCK` for `eventfd(2)`. - - Ref: - https://man7.org/linux/man-pages/man7/pipe.7.html - https://man7.org/linux/man-pages/man2/eventfd.2.html - https://man7.org/linux/man-pages/man2/socketpair.2.html - https://www.gnu.org/software/gnulib/manual/html_node/eventfd.html - - Closes #13874 - -renovate[bot] (4 Jun 2024) - -- ci: update github/codeql-action digest to 2e230e8 - - Closes #13881 - -Jay Satiro (4 Jun 2024) - -- examples/threaded-ssl: remove locking callback code - - - Remove the locking callback code that demonstrates how to meet - requirements of threading libraries (mainly OpenSSL). - - Locking callback code has not been needed for many years. According to - the documentation for OpenSSL and GnuTLS they are thread-safe by design, - assuming support for the underlying OS threading API is built-in. - - Ref: https://github.com/curl/curl/pull/13850#issuecomment-2143538458 - - Closes https://github.com/curl/curl/pull/13851 - -Viktor Szakats (4 Jun 2024) - -- tests: delete redundant `!MSDOS` guard - - This fix was supposed to be committed earlier, but ended up missing from - the final commit. - - Follow-up to e9a7d4a1c8377dbcf9a2d94365f60e3e5dff48f8 #12376 - Closes #13878 - -- lib: fix thread entry point to return `DWORD` on WinCE - - We already do this in `tests/server/util.c`: - https://github.com/curl/curl/blob/97e5e37cc8269660bc5d4a1936f10f2390b97c5a/te - sts/server/util.c#L604-L606 - and in `sockfilt.c`, `lib3026.c`. - - Before this patch it returned `unsigned int`. - - Closes #13877 - -Andy Pan (4 Jun 2024) - -- socket: use SOCK_NONBLOCK to eliminate extra system call - - Every time function `cf_socket_open()` is called to create a socket, - `curlx_nonblock()` is called to make that socket non-blocking. And - `curlx_nonblock()` will cost us 1 or 2 system calls (2 for `fcntl()`, 1 - for `ioctl()`, etc.), meanwhile, tucking `SOCK_NONBLOCK` and - `SOCK_CLOEXEC` into the `type` argument for `socket()` is widely - supported across UNIX-like OS: Linux, *BSD, Solaris, etc. With that - ability, we can save 1 or 2 system calls on each socket. - - Another change in this PR is to eliminate the redundant - `curlx_nonblock()` call on the socket in `cf_udp_setup_quic()` as that - socket created by `cf_socket_open()` is already non-blocking. - - Ref: - https://man7.org/linux/man-pages/man2/socket.2.html - https://man.freebsd.org/cgi/man.cgi?socket(2) - https://man.dragonflybsd.org/?command=socket§ion=2 - https://man.netbsd.org/socket.2 - https://man.openbsd.org/socket - https://docs.oracle.com/cd/E88353_01/html/E37843/socket-3c.html - https://illumos.org/man/3SOCKET/socket - ... - - Closes #13855 - -Viktor Szakats (4 Jun 2024) - -- GHA: show cmake error log in Windows and non-native workflows - - CMake configure doesn't fail often, but when it does, it helps to see - its `CMakeFiles/CMakeConfigureLog.yaml` output. This file is present - since CMake v3.26: - https://cmake.org/cmake/help/v3.26/manual/cmake-configure-log.7.html - - (Older CMake versions save similar contend to - `CMakeFiles\CMakeOutput.log` and - `CMakeFiles\CMakeError.log`. This patch doesn't deal with that because - the workflows touched are all running a newer CMake.) - - After this patch, we dump the content if cmake fails. Syncing this with - autotools, where we already did that. - - Closes #13872 - -- GHA: switch a Windows job to UCRT (gcc) - - Cherry-picked from #13870 - -- curl-config: revert to backticks to support old target envs - - Make an exception for `curl-config` because this script that may be - running on any target system, including old ones, e.g. SunOS 5.10. - - Reported-by: Alejandro R. Sedeño - Ref: https://github.com/curl/curl/pull/13307#issuecomment-2146427358 - Follow-up to fa69b41c7790fab86fd363242c81d8ef2e89e183 #13307 - Closes #13871 - -Stefan Eissing (4 Jun 2024) - -- mbedtls: v3.6.0 workarounds - - - add special sauce to disable unwanted peer verification by mbedtls - when negotiating TLS v1.3 - - add special sauce for MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET - return code on *writing* TLS data. We assume the data had not been - written and EAGAIN. - - return correct Curl error code when peer verification failed. - - disable test_08_05 with 50 HTTP/1.1 connections, as mbedtls reports a - memory allocation failed during handshake. - - bump CI mbedtls version to 3.6.0 - - Fixes #13653 - Closes #13838 - -- gnutls: support CA caching - - - similar to openssl, use a shared 'credentials' instance - among TLS connections with a plain configuration. - - different to openssl, a connection with a client certificate - is not eligible to sharing. - - document CURLOPT_CA_CACHE_TIMEOUT in man page - - Closes #13795 - -Dan Fandrich (3 Jun 2024) - -- tests: don't log buffer length in throwing away message - - It's not available at that point, and it will be written in the - non-error case right afterward. - -- tests: log "Throwing away" messages before throwing away - - In case the read that follows hangs we'll get a clue as to what it was - doing. - -- CI: reduce memory request for FreeBSD builds - - Also, add a comment with link to the Cirrus credit page since it's not - easy to find otherwise. - -Andy Pan (3 Jun 2024) - -- tcpkeepalive: support setting TCP keep-alive parameters on Solaris <11.4 - - Solaris didn't support TCP_KEEPIDLE and TCP_KEEPINTVL until 11.4, - before that it use TCP_KEEPALIVE_THRESHOLD and TCP_KEEPALIVE_ABORT_THRESHOLD - as the substitute. Therefore, for Solaris <11.4 we need to use this substitut - e - for setting TCP keep-alive parameters. - - Ref: - https://docs.oracle.com/cd/E86824_01/html/E54777/tcp-7p.html - https://docs.oracle.com/cd/E88353_01/html/E37851/tcp-4p.html - - Closes #13864 - -Daniel Stenberg (3 Jun 2024) - -- KNOWN_BUGS: quiche: QUIC connection is draining - - Closes #12037 - Closes #13867 - -- KNOWN_BUGS: aws-sigv4 has problems with particular URLs - - Closes #13058 - Closes #13866 - -- KNOWN_BUGS: aws-sigv4 does not handle multipart/form-data correctly - - Closes #13351 - Closes #13866 - -- RELEASE-NOTES: synced - -Viktor Szakats (3 Jun 2024) - -- GHA: fix old mingw-w64 32-bit job - - This toolchain resides in the `mingw32` directory. Make sure to - configure `PATH` accordingly. - - Before this patch, it pointed to a non-existing `mingw64` directory, - making the job use the wrong compiler (gcc 12, 64-bit). - - Follow-up to e838b341a08b44d4a8486fb0d3f15d12fc794c62 #12927 - Closes #13863 - -Daniel Stenberg (2 Jun 2024) - -- tool_cb_hdr: return error for failed header writes - - By checking that fflush() works. - - Reported-by: Sebastian Andersson - Fixes #13836 - Closes #13859 - -Viktor Szakats (2 Jun 2024) - -- GHA: bump all build jobs to nproc+1 - - - bump rest of the workflows (windows, macos, distrocheck). - - - non-native virtualized envs have 2 CPUs, bump down accordingly. - (for `vmactions/omnios-vm` it's just a guess.) - - - bump all to nproc + 1. - - Follow-up to e838b341a08b44d4a8486fb0d3f15d12fc794c62 #12927 - Closes #13807 - -- GHA: disable MQTT and WebSocket tests in Windows jobs - - Trying to figure out which category is causing the remaining hangs. - - Follow-up to def7d05382743ea7aa1d356d1e41dcb22ecdd4d7 - Closes #13860 - -- lib/v*: tidy up types and casts - - Also add a couple of negative checks. - - Cherry-picked from #13489 - Closes #13622 - -- GHA: fix caching old mingw-w64 toolchains in the Windows workflow - - - stop altering the `PATH` via `GITHUB_ENV`. This confused the - `actions/cache` post-job, which needs to run in the exact same - environment as its pre-job, to have a consistent cache entry "version" - hash. Altering the `PATH` via `GITHUB_ENV` spills into the the - post-job and breaks this hash. GHA doesn't reset the env automatically - and I have not found a way to do it manually. - - - add double-quotes where missing. - - - move cache directory under `USERPROFILE` to not rely on absolute - paths. - - - make cache directory flatter and versionless. - - Follow-up to 0914d8aadddac0d1459673d5b7f77e8f3378b22b #13759 - Closes #13856 - -renovate[bot] (2 Jun 2024) - -- ci: pin actions/github-script action to 60a0d83 - - Closes #13846 - -Bo Anderson (2 Jun 2024) - -- x509asn1: add some common ECDSA OIDs - - Closes #13857 - -renovate[bot] (2 Jun 2024) - -- ci: update rojopolis/spellcheck-github-actions digest to e36f662 - - Closes #13852 - -Bo Anderson (2 Jun 2024) - -- x509asn1: fallback to dotted OID representation - - Reported-by: Luke Hamburg - Fixes #13845 - Closes #13858 - -Lee Li (2 Jun 2024) - -- request.md: language fix - - improved for better readability and correctness - - Closes #13854 - -Christian Schmitz (2 Jun 2024) - -- vtls: deprioritize Secure Transport - - Moved Secure Transport behind OpenSSL, so we can build CURL with both - and prefer using OpenSSL over Secure Transport by default. - - Closes #13547 - -Daniel Stenberg (1 Jun 2024) - -- urlapi: add CURLU_NO_GUESS_SCHEME - - Used for extracting: - - - when used asking for a scheme, it will return CURLUE_NO_SCHEME if the - stored information was a guess - - - when used asking for a URL, the URL is returned without a scheme, like - when previously given to the URL parser when it was asked to guess - - - as soon as the scheme is set explicitly, it is no longer internally - marked as guessed - - The idea being: - - 1. allow a user to figure out if a URL's scheme was set as a result of - guessing - - 2. extract the URL without a guessed scheme - - 3. this makes it work similar to how we already deal with port numbers - - Extend test 1560 to verify. - - Closes #13616 - -- wolfssl: support CA caching - - As a bonus, add SSLSUPP_CA_CACHE to let TLS backends signal its support - for this so that *setopt() return error if there is no support. - - Closes #13786 - -Andy Pan (1 Jun 2024) - -- socket: change TCP keepalive from ms to seconds on DragonFly BSD - - DragonFly BSD changed the time unit for TCP keep-alive from milliseconds - to seconds since v5.8, thus setting the keepalive options with - milliseconds with curl/libcurl will result in unexpected behaviors on - DragonFlyBSD 5.8+ - - Distinguish the DragonFly BSD versions and use the proper time units - accordingly. - - Ref: - https://lists.dragonflybsd.org/pipermail/commits/2019-July/719125.html - https://github.com/DragonFlyBSD/DragonFlyBSD/blob/965b380e960908836b97aa034 - fa2753091e0172e/sys/sys/param.h#L207 - - Fixes #13847 - Closes #13848 - -Daniel Stenberg (1 Jun 2024) - -- curlver.h: aiming for 8.9.0 - -- noproxy: patterns need to be comma separated - - or they will not parse correctly. - - Mentioned in DEPRECATED since Janurary 2023 (in 7ad8a7ba9ebdedc). - - Closes #13789 - -Jan Venekamp (1 Jun 2024) - -- sectransp: remove large cipher table - - Previously a large table of ciphers was used to determine the default - ciphers and to lookup manually selected ciphers names. - - With the lookup of the manually selected cipher names moved to - Curl_cipher_suite_walk_str() the large table is no longer needed for - that purpose. - - The list of manually selected cipher can now be intersected with the - ciphers supported by Secure Transport (SSLGetSupportedCiphers()), - instead of using the fixed table for that. - - The other use of the table was to filter the list of all supported - ciphers offered by Secure Transport to create a list of ciphers to - use by default, excluding ciphers in the table marked as weak. - - Instead of using a complement based approach (exclude weak), switch - to using an intersection with a smaller list of ciphers deemed - appropriate. - - Closes #13823 - -Tatsuhiro Tsujikawa (1 Jun 2024) - -- GHA: unify http3 workflows into one - - This commit unifies the following http3 workflows into http3-linux.yml: - - - ngtcp2-linux.yml - - osslq-linux.yml - - quiche-linux.yml - - The idea is better use of the build cache. Previously, they - independently create caches with the same key. Some of the caches - include source code and intermediate object files, which makes cache - quite large. In this commit, only built artifacts are cached, which - drastically reduces the cache size. OpenSSL v3, mod_h2 and quiche caches - still include all stuff, but they are left for the later improvement. - Because the contents of the cache have been changed, the cache keys are - also changed to include the word "http3". - - Closes #13841 - -Stephen Farrell (1 Jun 2024) - -- openSSL: fix hostname handling when using ECH - - Reported-by: vvb2060 - Fixes #13818 - Closes #13822 - -renovate[bot] (1 Jun 2024) - -- ci: update github/codeql-action digest to f079b84 - - Closes #13837 - -Daniel Stenberg (1 Jun 2024) - -- RELEASE-NOTES: synced - -- curl_multi_poll.md: expand the example with an custom file descriptor - - Closes #13842 - -Christian Heusel (1 Jun 2024) - -- DISTROS: add a link to the list archive - - Related to https://github.com/curl/curl/discussions/13833 - - Signed-off-by: Christian Heusel - Closes #13843 - -Matt Jolly (31 May 2024) - -- autoconf: remove 'deeper' checks for `AC_CHECK_FUNCS` - - The net effect of the deeper checks is to raise implicit function decls - on modern compilers. - - These checks appear to have been added ~20 years ago, relating to an - unverifiable claim about HP-UX. Autoconf support for the platform has - grown in leaps and bounds since. - - It didn't cause a real problem here, but when investigating a FP this - came up. No evidence has been identified that this was actually broken - in the past, and there is no evidence that this is necessary now. - - `-Werror=implicit-function-declarations` is enabled for both checks; - without a working prototype they will both fail regardless. In the - second case there will in fact never be a working prototype and - therefore it will always fail unconditionally. - - `AC_CHECK_FUNCS` does effectively the same thing as the removed checks, - except it actually defines a dummy prototype to see if it links. - - If `AC_CHECK_FUNCS` is broken on a given platform we have bigger - problems than trying to build cURL. This should also be faster. - - Bug: https://bugs.gentoo.org/932827 - Reviewed-By: Eli Schwartz - Closes #13830 - -Jay Satiro (30 May 2024) - -- cf-socket: improve SO_SNDBUF update for Winsock - - - Rename: Curl_sndbufset => Curl_sndbuf_init - - - Rename: win_update_buffer_size => win_update_sndbuf_size - - - Save the last set SO_SNDBUF size to compare against so that we can - avoid setsockopt calls every second. - - This is a follow-up to 0b520e12 which moved the SO_SNDBUF update check - into cf-socket. This change improves it further by making the function - names easier to understand and reducing the amount of setsockopt calls. - - Closes https://github.com/curl/curl/pull/13827 - -Viktor Szakats (30 May 2024) - -- tidy-up: use consistent casing for Windows directories - - C:\Windows\System32 - - Closes #13832 - -- GHA: use ubuntu-latest with OmniOS job - - It's the same as ubuntu-22.04. - - Also update OmniOS package search link. - - Closes #13831 - -Ayesh Karunaratne (30 May 2024) - -- GHA: adjust parallel job counts - - Adjusts the `make -j` flag to match the latest GitHub-hosted runner - hardware specs[^1]: - - - `ubuntu-latest` on 4 CPU cores - - `macos-latest` on 3 CPU cores - - The processor count is ideally obtained from `nproc`, but setting env - vars from the current CI yaml files is not possible because they expect - literal strings. - - [^1]: https://docs.github.com/en/actions/using-github-hosted-runners/about-gi - thub-hosted-runners/about-github-hosted-runners#standard-github-hosted-runner - s-for-public-repositories - - Closes #12927 - -pszlazak (30 May 2024) - -- get.d: clarify the explanation - - Closes #13706 - -Daniel Stenberg (30 May 2024) - -- curl_url_set.md: libcurl only parses :// URLs - - Make it clearer in the documentation. - - Closes #13821 - -Stefan Eissing (30 May 2024) - -- multi: fix multi_wait() timeout handling - - - determine the actual poll timeout *after* all sockets - have been collected. Protocols and connection filters may - install new timeouts during collection. - - add debug logging to test1533 where the mistake was noticed - - Reported-by: Matt Jolly - Fixes #13782 - Closes #13825 - -Viktor Szakats (29 May 2024) - -- lib: prefer `var = time(NULL)` over `time(&var)` - - Following up on previous occurrences showing up as gcc warnings, replace - the remaining `time(&var)` calls with `var = time(NULL)`, though these - aren't specifically causing compiler warnings. These are in the TFTP - client code (`lib/tftp.c`), except one which is in a debug branch in - `lib/http_aws_sigv4.c`. - - What's unexplainable is that this patch seems to mitigate TFTP tests - often hanging or going into an infinite loop on GHA windows workflows - with MSYS2, mingw-w64 and MSVC (Cygwin is unaffected): - https://github.com/curl/curl/pull/13599#issuecomment-2119372376 - TFTP hangs did not entirely disappear though, so could be unrelated. - - `time()` docs: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32 - -time64 - https://manpages.debian.org/bookworm/manpages-dev/time.2.en.html - - Follow-up to 58ca0a2f0743a586716ca357c382b29e3f08db69 #13800 - Follow-up to d0728c9109629ee82b855b350a4c3f1f52ee61df #13643 - Closes #13815 - -Stefan Eissing (29 May 2024) - -- winsock: move SO_SNDBUF update into cf-socket - - - Move the code that updates the SO_SNDBUF size for Windows to - cf_socket_send. - - Prior to this change the code was in readwrite_upload but the socket - filter is the more appropriate place because it applies to all sends. - - Background: - - For Windows users SO_SNDBUF (the total per-socket buffer size reserved - by Winsock for sends) is updated dynamically by libcurl during the - transfer. This is because Windows does not do it automatically for - non-blocking sockets and without it the performance of large transfers - may suffer. - - Closes https://github.com/curl/curl/pull/13763 - -Jan Venekamp (29 May 2024) - -- sectransp: use common code for cipher suite lookup - - Take advantage of the Curl_cipher_suite_walk_str() and - Curl_cipher_suite_get_str() functions introduced in commit fba9afe. - - Closes #13521 - -Matthias Gatto (29 May 2024) - -- aws-sigv4: url encode the canonical path - - Refactors canon_query, so it could use the encoding part of the function - to use it in the path. - - As the path doesn't encode '/', but encode '=', I had to add some - conditions to know If I was doing the query or path encoding. - - Also, instead of adding a `bool in_path` variable, I use `bool - *found_equals` to know if the function was called for the query or path, - as found_equals is used only in query_encoding. - - Test 472 verifies. - - Reported-by: Alexander Shtuchkin - Fixes #13754 - Closes #13814 - - Signed-off-by: Matthias Gatto - -Daniel Stenberg (29 May 2024) - -- cd2nroff: use an empty "##" to signal end of .IP sequence - - Like when we list a series of options and then want to add "normal" text - again afterwards. - - Without this, the indentation level wrongly continues even after the - final "##" header, making following text wrongly appear to belong to the - header above. - - Adjusted several curldown files to use this. - - Fixes #13803 - Reported-by: Jay Satiro - Closes #13806 - -vvb2060 (28 May 2024) - -- openssl: fix %-specifier in infof() call - - Closes #13816 - -Daniel Stenberg (28 May 2024) - -- curl: make warnings and other messages aware of terminal width - - This removes unnecessary line wraps when the terminal is wider than 79 - columns and it also makes messages look better in narrower terminals. - - The get_terminal_columns() function is not split out into its own source - file. - - Suggested-by: Elliott Balsley - Fixes #13804 - Closes #13808 - -Viktor Szakats (28 May 2024) - -- GHA: enable tests 1139, 1177, 1477 on Windows - - These exclusions came from the AppVeyor CI config, but they do pass now - and they are static tests with no flakiness risk. - - Follow-up to 0914d8aadddac0d1459673d5b7f77e8f3378b22b #13759 - Closes #13817 - -Dan Fandrich (28 May 2024) - -- CI: Improve labeler tag detection - - Also, simplify patterns with a single glob. - -Viktor Szakats (28 May 2024) - -- GHA: disable TFTP tests in Windows jobs - - Shot in the dark trying to find out which tests are - hanging / going to an infinite loop. - - The ones failing after 45 minutes (mingw-w64) or 30 minutes (MSVC). - - Ref: https://github.com/curl/curl/pull/13599#issuecomment-2119372376 - -renovate[bot] (28 May 2024) - -- ci: update vmactions/omnios-vm digest to a61ca1e - - Closes #13801 - -Daniel Stenberg (28 May 2024) - -- openssl/gnutls: rectify the TLS version checks for QUIC - - The versions check wrongly complained and return error if the *minimum* - version was set to something less than 1.3. QUIC is always TLS 1.3, but - that means minimum 1.2 is still fine to ask for. - - This also renames the local variable to make the mistake harder to make - in the future. - - Regression shipped in 8.8.0 - - Follow-up to 3210101088dfa3d6a125 - - Reported-by: fds242 on github - Fixes #13799 - Closes #13802 - -Stefan Eissing (28 May 2024) - -- gnutls: improve TLS shutdown - - local ftp upload tests sometimes failed with an invalid TLS record being - reported by gnutls. vsftp did log that the shutdown was not regarded as - clean, failing the control connection thereafter. - - These changes make test_31_05 work reliable locally. - - - on closing the SSL filter, shutdown READ *and* WRITE - - on closing, try a receive after shutdown is sent - - convert to DEBUGF to CURL_TRC_CF - - Closes #13790 - -Daniel Stenberg (28 May 2024) - -- RELEASE-NOTES: synced - -- tests: run with "--trace-config all" to provide even more info - - in case of problems. - - Closes #13791 - -Viktor Szakats (28 May 2024) - -- build: untangle `CURLDEBUG` and `DEBUGBUILD` macros - - `CURLDEBUG` is meant to enable memory tracking, but in a bunch of cases, - it was protecting debug features that were supposed to be guarded with - `DEBUGBUILD`. - - Replace these uses with `DEBUGBUILD`. - - This leaves `CURLDEBUG` uses solely for its intended purpose: to enable - the memory tracking debug feature. - - Also: - - autotools: rely on `DEBUGBUILD` to enable `checksrc`. - Instead of `CURLDEBUG`, which worked in most cases because debug - builds enable `CURLDEBUG` by default, but it's not accurate. - - include `lib/easyif.h` instead of keeping a copy of a declaration. - - add CI test jobs for the build issues discovered. - - Ref: https://github.com/curl/curl/pull/13694#issuecomment-2120311894 - Closes #13718 - -- examples: delete unused includes - - Delete a bunch of unnecessary-looking headers from some examples. This - is known to be tricky on AIX (perhaps also in other less-tested envs). - - Let me know if any of this looks incorrect or outright fails on some - systems. - - Follow-up to d4b85890555388bec212b75f47a5c1a48705b156 #13771 - Closes #13785 - -- appveyor: fixup job name [ci skip] - - Follow-up to fc8e0dee3045658f293452121f5290d81ba3aa1e #13694 - -- cmake: fix `-Wredundant-decls` in unity/mingw-w64/gcc/curldebug/DLL builds - - It affected cmake-unity shared-curltool curldebug mingw-w64 gcc builds - when building the `testdeps` target. - - Apply the solution already used in `lib/base64.c` and `lib/dynbuf.c` - to fix it. - - Also update an existing GHA CI job to test the issue fixed. - - ``` - In file included from curl/lib/version_win32.c:35, - from curl/_bld/src/CMakeFiles/curl.dir/Unity/unity_0_c.c:145 - : - curl/lib/memdebug.h:52:14: error: redundant redeclaration of 'curl_dbg_logfil - e' [-Werror=redundant-decls] - 52 | extern FILE *curl_dbg_logfile; - | ^~~~~~~~~~~~~~~~ - In file included from curl/src/slist_wc.c:32, - from curl/_bld/src/CMakeFiles/curl.dir/Unity/unity_0_c.c:4: - curl/lib/memdebug.h:52:14: note: previous declaration of 'curl_dbg_logfile' w - ith type 'FILE *' {aka 'struct _iobuf *'} - 52 | extern FILE *curl_dbg_logfile; - | ^~~~~~~~~~~~~~~~ - curl/lib/memdebug.h:55:44: error: redundant redeclaration of 'curl_dbg_malloc - ' [-Werror=redundant-decls] - 55 | CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) void *curl_dbg_malloc(size_t siz - e, - | ^~~~~~~~~~~~~~~ - curl/lib/memdebug.h:55:44: note: previous declaration of 'curl_dbg_malloc' wi - th type 'void *(size_t, int, const char *)' {aka 'void *(long long unsigned - int, int, const char *)'} - 55 | CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) void *curl_dbg_malloc(size_t siz - e, - | ^~~~~~~~~~~~~~~ - [...] - curl/lib/memdebug.h:110:17: error: redundant redeclaration of 'curl_dbg_fclos - e' [-Werror=redundant-decls] - 110 | CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *sou - rce); - | ^~~~~~~~~~~~~~~ - curl/lib/memdebug.h:110:17: note: previous declaration of 'curl_dbg_fclose' w - ith type 'int(FILE *, int, const char *)' {aka 'int(struct _iobuf *, int, c - onst char *)'} - 110 | CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *sou - rce); - | ^~~~~~~~~~~~~~~ - ``` - Ref: https://ci.appveyor.com/project/curlorg/curl/builds/49840554/job/a4aoet1 - 7e9qnqx1a#L362 - - After: https://ci.appveyor.com/project/curlorg/curl/builds/49843735/job/hbo2u - ah2vj0ns523 - - Ref: #13689 (CI testing this PR with `DEBUGBUILD`/`CURLDEBUG`/shared-static c - ombinations) - Depends-on: #13694 - Depends-on: #13800 - Closes #13705 - -- lib: fix gcc warning in certain debug builds - - ``` - curl/lib/http_aws_sigv4.c:536:10: error: 'clock' may be used uninitialized [- - Werror=maybe-uninitialized] - 536 | time_t clock; - | ^~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9158755123/job/25177765000#ste - p:13:79 - - Cherry-picked from #13718 - Closes #13800 - -- cmake: always build unit tests with the `testdeps` target - - Before this patch, the `testdeps` build target required `-DCURLDEBUG` - be set either via `ENABLE_DEBUG=ON` or `ENABLE_CURLDEBUG=ON` to build - the curl unit tests. - - After fixing build issues in #13694, we can drop this requirement and - build unit tests unconditionally. - - Depends-on: #13694 - Depends-on: #13697 (fix unit test issue revealed by Old Linux CI job) - Follow-up to 39e7c22bb459c2e818f079984989a26a09741860 #11446 - Closes #13698 - -- CI: disable dependency tracking in most autotools builds - - For better build performance. Dependency tracking causes a build - overhead while compiling to help a subsequent build, but in CI there is - never one and the extra work is discarded. - - Closes #13794 - -- build: untangle `UNITTESTS` and `DEBUGBUILD` macros - - - fix `DEBUGBUILD` guards that should be `UNITTESTS`, in libcurl code - used by unit tests. - - fix guards for libcurl functions used in unit tests only. - - sync `UNITTEST` attribute between declarations and definitions. - - drop `DEBUGBUILD` guard from test `unit2600`. - - fix guards for libcurl HSTS code used by both a unit test (`unit1660`) - and `test0446`. - - update an existing AppVeyor CI job to test the issues fixed. - - This fixes building tests with `CURLDEBUG` enabled but `DEBUGBUILD` - disabled. This can happen when building tests with CMake with - `ENABLE_DEBUG=ON` in Release config, or with `ENABLE_CURLDEBUG=ON` - and _without_ `ENABLE_DEBUG=ON`. Possibly also with autotools - when using `--enable-curldebug` without `--enable-debug`. - - Test results: - - before: - https://ci.appveyor.com/project/curlorg/curl/builds/49835609 - https://ci.appveyor.com/project/curlorg/curl/builds/49898529/job/k8qpbs8idb - y70smw - https://github.com/curl/curl/actions/runs/9259078835/job/25470318167?pr=137 - 98#step:13:821 - - after: https://ci.appveyor.com/project/curlorg/curl/builds/49839255 - (the two failures are unrelated, subject to PR #13705) - - Ref: #13592 (issue discovery) - Ref: #13689 (CI testing this PR with `DEBUGBUILD`/`CURLDEBUG` combinations) - Closes #13694 - -- GHA: ignore flaky MQTT and FTP test results [ci skip] - - MQTT / OmniOS: - ``` - TESTFAIL: These test cases failed: 1190 1198 3017 - ``` - Ref: https://github.com/curl/curl/actions/runs/9258522297/job/25468730731?pr= - 13694#step:3:10251 - - MQTT / OmniOS: - ``` - TESTFAIL: These test cases failed: 1194 2200 2203 2205 - ``` - Ref: https://github.com/curl/curl/actions/runs/9150523540/job/25155409832#ste - p:3:10233 - - FTP / OmniOS: - ``` - TESTFAIL: These test cases failed: 1096 - ``` - Ref: https://github.com/curl/curl/actions/runs/9150702711/job/25155793948#ste - p:3:10247 - - FTP / OmniOS: - ``` - TESTFAIL: These test cases failed: 381 - ``` - Ref: https://github.com/curl/curl/actions/runs/9163863822/job/25193897640#ste - p:3:10230 - - FTP / OmniOS: - ``` - TESTFAIL: These test cases failed: 340 - ``` - Ref: https://github.com/curl/curl/actions/runs/9233804752/job/25406671742?pr= - 13771#step:3:10245 - - Ref: https://github.com/curl/curl/pull/13583#issuecomment-2119376898 - -- CI: tidy up skipping tests build/run in Windows jobs - - Simplify controlling whether to build and/run tests in a CI job. - - Apply the TFLAGS='skipall' (do not build nor run tests) or - 'skiprun' (build, but do not run) method already used with old-mingw-w64 - and msvc jobs to existing Windows jobs in GHA and AppVeyor. - - Also: - - add Cygwin/cmake test build and run steps while here. - - replace `DISABLED_TESTS` with `TFLAGS` in AppVeyor. - - Closes #13796 - -- cmake: use `APPLE` instead of `CMAKE_SYSTEM_NAME` string - - Follow-up to a86254b39307af1a53735b065a382567805cd9b8 #12515 - Closes #13713 - -- cmake: whitespace, formatting/tidy-up in comments - - Also correct casing in a few option descriptions. - - Closes #13711 - -- cmake: allow `ENABLE_CURLDEBUG=OFF` with `ENABLE_DEBUG=ON` - - Before this patch, `ENABLE_CURLDEBUG` (memory tracking) was - unconditionally enabled when `ENABLE_DEBUGBUILD` was set. This made - testing some build configurations complicated. To fix it, this patch - makes `ENABLE_CURLDEBUG` to receive the value of `ENABLE_DEBUG` by - default, while allowing free override by the user. - - This allows to use the config: - `ENABLE_DEBUGBUILD=ON ENABLE_CURLDEBUG=OFF` - to enable debug features, without also enabling memory tracking. - - This is important because some other build methods allow to set one of - these features but not the other. This patch allows to test any - combination with CMake. - - This makes it unnecessary to use the workaround of passing - `-DDEBUGBUILD` via `CMAKE_C_FLAGS`. Which has the disadvantage that our - CMake logic cannot easily detect it, e.g. for disabling symbol hiding on - Windows for `ENABLE_DEBUG`/`DEBUGBUILD` builds. - - Cherry-picked from #13718 - Closes #13792 - -- cmake: `ENABLE_DEBUG=ON` to always set `-DDEBUGBUILD` - - Before this patch `ENABLE_DEBUG=ON` always enabled the TrackMemory - (aka `ENABLE_CURLDEBUG=ON`) feature, but required the `Debug` CMake - configration to actually enable curl debug features - (aka `-DDEBUGBUILD`). - - Curl debug features do not require compiling with C debug options. This - also made enabling debug features unintuitive and complicated to use. - Due to other issues (subject to PR #13694) it also caused an error in - default (and `Release`/`MinSizeRel`/`RelWithDebInfo`) configs, when - building the `testdeps` target: - ``` - ld: CMakeFiles/unit1395.dir/unit1395.c.o: in function `test': - unit1395.c:(.text+0x1a0): undefined reference to `dedotdotify' - ``` - Ref: https://github.com/curl/curl/actions/runs/9037287098/job/24835990826#ste - p:3:2483 - - Fix it by always defining `DEBUGBUILD` when setting `ENABLE_DEBUG=ON`. - Decoupling this option from the selected CMake configuration. - - Note that after this patch `ENABLE_DEBUG=ON` unconditionally enables - curl debug features. These features are insecure and unsuited for - production. Make sure to omit this option when building for production - in default, `Release` (and other not-`Debug`) modes. - - Also delete a workaround no longer necessary in GHA CI jobs. - - Ref: 1a62b6e68c08c7e471ff22dd92932aba7e026817 (2015-03-03) - Ref: #13583 - Closes #13592 - -- GHA: add autotools mingw-64, build-only job - - Cherry-picked from #13718 - Closes #13793 - -- GHA: add three MSVC jobs - - Continuing the theme, add 3 MSVC jobs with tests, matching - configurations used on AppVeyor. MSVC versions are identical: - 19.39.33523.0 + Windows SDK 10.0.22621.0. - - Also enable websockets, and build examples. Tests are run in parallel - (`-j14`), with improved performance. - - Job performance: - ``` - AppVeyor GHA - w/examples - -------- ---------- - CMake, VS2022, Debug, x64, Schannel, Static, Unicode 38m 4s 11m57s - CMake, VS2022, Debug, x64, no SSL, Static 35m15s 12m 6s - CMake, VS2022, Debug, x64, no SSL, Static, HTTP only 25m25s 10m36s - ``` - Based on these runs: - https://ci.appveyor.com/project/curlorg/curl/builds/49884748 - https://github.com/curl/curl/actions/runs/9229448468 - - This is the first time examples are built in CI with MSVC: Fix all - warnings and errors that came up via - d4b85890555388bec212b75f47a5c1a48705b156 #13771. - - Closes #13766 - -- GHA: add three old (gcc 6, 7, 9) mingw-w64 jobs - - Re-implement old mingw-w64 jobs in GHA. This allows to use the latest - Windows runners, replacing Windows Server 2012 R2 (gcc 6) and Windows - Server 2016 (gcc 7, 9) with Windows Server 2022. - - GHA runners are also significantly faster, and allow running tests in - parallel (`-j14`). It also offloads 3 more long-running jobs from - AppVeyor CI. - - These jobs download (then cache) the mingw-w64 packages from their - original location, which allows flexibility in choosing which versions - and flavours (win32/POSIX, SEH/DWARF, 64/32-bit) we want to test in CI. - The new jobs use these distros: - - https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20 - Win64/Personal%20Builds/mingw-builds/ (for gcc 7, same as on AppVeyor) - - https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20 - Win32/Personal%20Builds/mingw-builds/ (for gcc 6, same as on AppVeyor) - - https://winlibs.com/ (for gcc 9) - - I matched existing AppVeyor job configs, with these differences: - - gcc 6.4.0 instead of 6.3.0. - (same distro as on AppVeyor, but the latest bugfix release) - - gcc 9.5.0 instead of 9.1.0 and a different (but compatible) binary distro. - (in AppVeyor this relies on an old MSYS2 pre-installed on the runner) - - using win32 builds instead of posix for gcc 6.4.0 and 7.3.0. - - websockets enabled. - - always build examples. - - always build tests (this wasn't done for 6.4.0 with AppVeyor CI). - - I did not replicate existing test exclusions, and oddly enough the few - failures (so far) were different from MSYS2 jobs and also from their - AppVeyor CI counterparts. - - Also: - - delete redundant (default) `-u` option from `cygpath` calls. - - allow matrix options to override default ones in CMake. - - detect and use Windows-supplied curl for `TFLAGS` `-ac` option. - (it's available in modern runners.) - - delete the 3 AppVeyor CI jobs now replicated in GHA. - - appveyor: prefer `SYSTEMROOT` over `WINDIR`. - - tidy-up quotes. - - Job performance: - ``` - AppVeyor GH - A - w/ - examples - w/ - tests - -------- -- - -------- - CMake, mingw-w64, gcc 6, Debug, x86, Schannel, Static, no-unity 1m25s 8 - m50s - CMake, mingw-w64, gcc 7, Debug, x64, Schannel, Static, Unicode 31m45s 9 - m39s - CMake, mingw-w64, gcc 9, Debug, x64, Schannel, Static 28m25s 13 - m38s - ``` - Based on these runs: - https://ci.appveyor.com/project/curlorg/curl/builds/49880799 - https://github.com/curl/curl/actions/runs/9218292508 - - Notice that building examples and tests is time consuming. - - We can tweak any build parameter as necessary to make them more useful - and/or without clogging the job queue or introducing flakiness. - - Closes #13759 - -Daniel Stenberg (27 May 2024) - -- TODO: remove some old, clarify, add something - - Closes #13788 - -- TODO: Add "Share CA cache" + "CA caching to more TLS backends" - - Closes #13787 - -Viktor Szakats (26 May 2024) - -- runtests: sort test IDs in summary lines - - Changing this output: - ``` - TESTFAIL: These test cases failed: 2301 2303 2302 2307 - ``` - Ref: https://github.com/curl/curl/actions/runs/9228638364/job/25393106631#ste - p:6:21181 - - To: - ``` - TESTFAIL: These test cases failed: 2301 2302 2303 2307 - ``` - - Cherry-picked from #13766 - Closes #13774 - -- examples: fix compiling with MSVC - - - `websocket.c`: use `Sleep()` on Windows. - `sleep()` and `unistd.h` are not available in MSVC. - - - `http2-upload.c`: use local `gettimeofday()` implementation when - compiled with MSVC. - (Alternate solution is to disable the trace function for MSVC.) - Public domain code copied and adapted from libssh2: - https://github.com/libssh2/libssh2/blob/e973493f992313b3be73f51d3f7ca6d52e2 - 88558/src/misc.c#L719-L743 - - - silence compiler warning for deprecated `inet_addr()`. - Also drop duplicate winsock2 include. - ``` - curl\docs\examples\externalsocket.c(125,32): error C2220: the following war - ning is treated as an error [curl\bld\docs\examples\curl-example-externalsock - et.vcxproj] - curl\docs\examples\externalsocket.c(125,32): warning C4996: 'inet_addr': Us - e inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS - to disable deprecated API warnings [curl\bld\docs\examples\curl-example-e - ``` - Ref: https://github.com/curl/curl/actions/runs/9227337318/job/25389073450#s - tep:4:95 - - - silence an MSVC compiler warning. This is in conflict with `checksrc` - rules, so silence the rule in favour of the warning-free C syntax. - ``` - curl\docs\examples\multi-legacy.c(152,1): error C2220: the following warnin - g is treated as an error [curl\bld\docs\examples\curl-example-multi-legacy.vc - xproj] - curl\docs\examples\multi-legacy.c(152,1): warning C4706: assignment within - conditional expression [curl\bld\docs\examples\curl-example-multi-legacy.vcxp - roj] - ``` - Ref: https://github.com/curl/curl/actions/runs/9227337318/job/25389073450#s - tep:4:226 - - - do not use `sys/time.h` and `unistd.h` in Windows builds. - Some of these includes look unnecessary. Subject to another PR. - - Cherry-picked from #13766 - Closes #13771 - -Jonathan Matthews (26 May 2024) - -- docs/cmdline-opts: fix mail-auth example TLD typo - - Closes: #13784 - Reviewed-by: Daniel Gustafsson - -Daniel Stenberg (26 May 2024) - -- libssh: remove CURLOPT_SSL_VERIFYHOST check - - It was never meant for SSH: it should rely on the knownhosts file (if - set) in the same way libssh2 already does. - - Reported-by: James Abbatiello - Fixes #13767 - Closes #13781 - -Stefan Eissing (26 May 2024) - -- multi: add multi->proto_hash, a key-value store for protocol data - - - add `Curl_hash_add2()` that passes a destructor function for - the element added. Call element destructor instead of hash - destructor if present. - - multi: add `proto_hash` for protocol related information, - remove `struct multi_ssl_backend_data`. - - openssl: use multi->proto_hash to keep x509 shared store - - schannel: use multi->proto_hash to keep x509 shared store - - vtls: remove Curl_free_multi_ssl_backend_data() and its - equivalents in the TLS backends - - Closes #13345 - -Jan Venekamp (25 May 2024) - -- tests: add pytest for --ciphers and --tls13-ciphers options - - Closes #13530 - -Orgad Shaneh (25 May 2024) - -- tool_operate: avoid explicitly setting verifypeer to 1 - - Also for the proxy verison. It is the default, just like verifyhost, - since a long time. - - Closes #13704 - -- tests: extend user/password parsing test1620 - - Closes #13756 - -Alejandro R. Sedeño (25 May 2024) - -- configure: use `$EGREP` in place of `grep -E` - - `$EGREP` is set based on an earlier test in configure so that we can - work with systems that have `egrep` and a `grep` that does not support - `-E`. - - Closes #13780 - -renovate[bot] (25 May 2024) - -- ci: update dependency awslabs/aws-lc to v1.28.0 - - Closes #13770 - -Jan Venekamp (25 May 2024) - -- tests: test_17_ssl_use.py clarify mbedtls TLSv1.3 support - - Closes #13779 - -Stefan Eissing (25 May 2024) - -- http: write last header line late - - - HEADERFUNCTIONS might inspect response properties like - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T on seeing the last header line. If - the line is being written before this is initialized, values are not - available. - - - write the last header line late when analyzing a HTTP response so that - all information is available at the time of the writing. - - - add test1485 to verify that CURLINFO_CONTENT_LENGTH_DOWNLOAD_T works - on seeing the last header. - - Fixes #13752 - Reported-by: Harry Sintonen - Closes #13757 - -Dan Fandrich (24 May 2024) - -- tests: use exec when spawning nghttpx - - This stops keeping perl and shell processes around that are no longer - needed, plus it eliminates an unneeded shell message when the server is - later terminated. - - Closes #13772 - -Viktor Szakats (24 May 2024) - -- GHA: ignore flaky test 3017 (MQTT) on OpenBSD - - ``` - TESTFAIL: These test cases failed: 3017 - ``` - Ref: https://github.com/curl/curl/actions/runs/9223543272/job/25376999226?pr= - 13759#step:3:16326 - Ref: https://github.com/curl/curl/actions/runs/9230183764/job/25397883193?pr= - 13766#step:3:16345 - - Ref: https://github.com/curl/curl/pull/13583#issuecomment-2119376898 - -Joseph Chen (24 May 2024) - -- build: add more supported attributes to the IAR compiler - - Closes #13744 - -Viktor Szakats (24 May 2024) - -- cmake: fix test 1013 with websockets enabled and no TLS - - test 1013 is 'Compare curl --version with curl-config --protocols'. - - Ref: https://github.com/curl/curl/actions/runs/9228363859/job/25392251955 - - Closes #13769 - -- GHA: stop deleting curl in non-native workflows - - We do it in Cirrus CI, but for some platforms it's not possible to - delete it and tests work anyway. - - The test runner also runs `../src/curl` by default, which is always the - one freshly built. The runner may also need the system curl to talk to - APIs when needed. - - Also: - - stop setting `CURL` env. This isn't picked up by the runners, - and works out of the box anyway. - - quote an option just in case. - - Follow-up to 90e644f944969bb11c6448bf50c6d441b5c0b1e6 #13583 - Closes #13765 - -Jay Satiro (24 May 2024) - -- openssl: stop duplicate ssl key logging for legacy OpenSSL - - - Don't call the keylog function if it has already logged the key. - - For old OpenSSL versions and its forks that do not have support for - OpenSSL's keylog callback, libcurl has its own legacy key logging - function that logs the TLS 1.2 (and earlier) key (client random + master - key) on a single line. - - Prior to this change, since e7de80e8 (precedes 8.8.0), the legacy key - logging function could write the same key line more than once (usually - twice) due to some incorrect logic. - - Closes https://github.com/curl/curl/pull/13683 - -Stefan Eissing (24 May 2024) - -- transfer: remove curl_upload_refill_watermark, no longer used - - the define applied to upload buffers which we removed - - Closes #13764 - -Daniel Stenberg (24 May 2024) - -- RELEASE-NOTES: synced - -Viktor Szakats (24 May 2024) - -- cmake: fix brotli lib order - - Fix root cause that caused missing symbols when linking brotli - statically with e.g. binutils `ld` (and any other "picky" linker, - or "traditional" linker as CMake now calls them). - - Also drop existing workaround that added brotli libs twice to the lib - list. - - ``` - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(decode.c.o - bj):decode.c:(.text$ProcessCommands[ProcessCommands]+0xbb5): undefined refere - nce to `BrotliTransformDictionaryWord' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(decode.c.o - bj):decode.c:(.text$SafeProcessCommands[SafeProcessCommands]+0xe8a): undefine - d reference to `BrotliTransformDictionaryWord' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(decode.c.o - bj):decode.c:(.rdata$.refptr._kBrotliContextLookupTable[.refptr._kBrotliConte - xtLookupTable]+0x0): undefined reference to `_kBrotliContextLookupTable' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(decode.c.o - bj):decode.c:(.rdata$.refptr._kBrotliPrefixCodeRanges[.refptr._kBrotliPrefixC - odeRanges]+0x0): undefined reference to `_kBrotliPrefixCodeRanges' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(state.c.ob - j):state.c:(.text$BrotliDecoderStateInit[BrotliDecoderStateInit]+0x21): undef - ined reference to `BrotliDefaultAllocFunc' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(state.c.ob - j):state.c:(.text$BrotliDecoderStateInit[BrotliDecoderStateInit]+0x2f): undef - ined reference to `BrotliDefaultFreeFunc' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(state.c.ob - j):state.c:(.text$BrotliDecoderStateInit[BrotliDecoderStateInit]+0x10e): unde - fined reference to `BrotliSharedDictionaryCreateInstance' - x86_64-w64-mingw32-ld: .../curl/brotli/_bld/usr/lib/libbrotlidec.a(state.c.ob - j):state.c:(.text$BrotliDecoderStateCleanup[BrotliDecoderStateCleanup]+0xf4): - undefined reference to `BrotliSharedDictionaryDestroyInstance' - collect2: error: ld returned 1 exit status - ``` - - Breakage reproducible with curl-for-win config "`win-gcc`" and deleting - the `LDFLAGS+=' -Wl,--start-group'` line from its `curl.sh` script. - (Above line still required for some non-brotli cases, e.g. libssh2 and - zlib.) - - Assisted-by: Kai Pastor - Ref: https://github.com/curl/curl/pull/10857#discussion_r1611714989 - Follow-up to 1e3319a167d2f32d295603167486e9e88af9bb4e #10857 - Closes #13761 - -Pavel Pavlov (24 May 2024) - -- cmake: fix building in unity mode - - - Fix sha256 and sha512 duplicate macro names (eg function-like macro Ch - is now Sha256_Ch and Sha512_Ch). - - - Avoid defining short defines like R, S. (eg S is now Sha256_S). - - Closes https://github.com/curl/curl/pull/13751 - -Jay Satiro (24 May 2024) - -- winbuild: remove outdated WIN32 defines - - - Remove all instances in the makefile of compiler option /DWIN32. - - This is a follow-up to e9a7d4a1 which replaced all defined(WIN32) checks - with defined(_WIN32) in the codebase, since only the latter is - automatically defined by all compilers for Windows builds. - - Bug: https://github.com/curl/curl/pull/13739#issuecomment-2123937859 - Reported-by: Viktor Szakats - - Closes https://github.com/curl/curl/pull/13742 - -renovate[bot] (24 May 2024) - -- ci: update github/codeql-action digest to 9fdb3e4 - - Closes #13726 - -Pavel Pavlov (23 May 2024) - -- asyn-thread: avoid using GetAddrInfoExW with impersonation - - Multiple reports suggest that GetAddrInfoExW fails when impersonation is - used. This PR checks if thread is impersonating and avoids using - GetAddrInfoExW api. - - Reported-by: Keerthi Timmaraju - Assisted-by: edmcln on github - Fixes #13612 - Closes #13738 - -Stefan Eissing (23 May 2024) - -- transfer: conn close on paused upload - - - add 2 variations on test_07_42 which PAUSEs uploads - and response connections terminating either right away - or after the 100-continue response - - when detecting the connection being closed in transfer.c - readwrite_data(), clear ALL send bits in data->req.keepon. - It no longer makes send to wait for a KEEP_SEND_PAUSE or HOLD. - - in the protocol client writer add the check for incomplete - response bodies. When an EOS is seen and the length is known, - check that and fail if bytes are missing. - - Reported-by: Sergey Bronnikov - Fixes #13740 - Closes #13750 - -- CI GHA: add vsftpd to ngtcp2-linux runs - - - not using HTTP/3, but gnutls does not seem to run - somewhere else right now - - Closes #13760 - -Orgad Shaneh (23 May 2024) - -- GHA: increase timeout for Cygwin autotools build tests step - - Apparently 10 minutes are not (always) enough: - https://github.com/curl/curl/actions/runs/9197003907/job/25296439556#step:8:1 - 936 - - Closes #13753 - -Stefan Eissing (22 May 2024) - -- mbedtls: send close-notify on close - - - send the TLS close notify message when cloding down - the mbedtls connection filter - - this is a "least" effort version and, as other TLS filters, - is lacking a graceful send/receive/timeout for a really - clean shutdown. - - Closes #13745 - -- mbedtls: check version for cipher id - - mbedtls_ssl_get_ciphersuite_id_from_ssl() seems to have been added in - mbedtls 3.2.0. Check for that version. - - Closes #13749 - -Viktor Szakats (22 May 2024) - -- cmake: fix building with both md4 and md5 in unity mode - - Macro and static function names were colliding between - `lib/md4.c` and - `lib/md5.c`. - - Fix it by namespacing these symbols. - - Seen with a basic macOS build using these options: - `-DCMAKE_UNITY_BUILD=ON -DCURL_USE_SECTRANSP=ON` - - Closes #13737 - -Daniel Stenberg (22 May 2024) - -- docs/Makefile.am: make curl-config.1 install - - on "make install" like it should - - Follow-up to 60971d665b9b1df87082 - - Closes #13741 - -dependabot[bot] (22 May 2024) - -- GHA: bump actions/checkout from 4.1.4 to 4.1.6 - - Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4 - .1.6. - - [Release notes](https://github.com/actions/checkout/releases) - - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - - [Commits](https://github.com/actions/checkout/compare/0ad4b8fadaa221de15dce - c353f45205ec38ea70b...a5ac7e51b41094c92402da3b24376905380afc29) - - --- - updated-dependencies: - - dependency-name: actions/checkout - dependency-type: direct:production - update-type: version-update:semver-patch - ... - - Signed-off-by: dependabot[bot] - - Closes #13720 - -Stefan Eissing (22 May 2024) - -- pytest: add ftp upload tests - - - refs #13556 - - allow anon uploads on vsftpd test server - - add test_30_05 for plain upload of 1k, 100k, 1m - - add test_31_05 for SSL upload of 1k, 100k, 1m - - verify file size and contents - - Closes #13734 - -- test: add test1546, chunked not last transfer encoding - - with more than one transfer-encoding, 'chunked' must be the last added - to the writer stack (and therefore the first to decode). RFC 9112, ch. - 6.1. - - Closes #13736 - -- test: add test1484, for HEAD with content - - - test HEAD request with 'Transfer-Encoding:chunked' and - non-encoded response content - - verifies #13725 - - Closes #13735 - -Daniel Stenberg (22 May 2024) - -- RELEASE-NOTES: synced - - bump to 8.8.1 for now - -Viktor Szakats (22 May 2024) - -- (lib)curl.rc: set debug flag also for `CURLDEBUG` and `UNITTESTS` - - These macros also enable debug features in both libcurl and curl. - Enable `VS_FF_DEBUG` version resource flag when they are set. - - Closes #13730 - -Jay Satiro (22 May 2024) - -- winbuild: fix PE version info debug flag - - - Only set PE file flag VS_FF_DEBUG if curl.exe and libcurl.dll were - built with winbuild option DEBUG=yes which builds with debug info. - - VS_FF_DEBUG is a PE flag (Portable Executable file flag - dll, exe, etc) - that indicates the file contains or was built with debug info. - - Prior to this change when winbuild was used to build curl, curl.exe - and libcurl.dll always had VS_FF_DEBUG set, regardless of build option - DEBUG=yes/no, due to some bad logic. - - Closes https://github.com/curl/curl/pull/13739 - -Version 8.8.0 (22 May 2024) - -Daniel Stenberg (22 May 2024) - -- RELEASE-NOTES: synced - -- THANKS: add contributors from 8.8.0 - -Nathan Moinvaziri (21 May 2024) - -- url: remove duplicate call to Curl_conncache_remove_conn when pruning - - - remove unnecessary prunedead struct from prune_dead_connections - - rename extract_if_dead to prune_if_dead for clarity - - Closes #13710 - -Joseph Chen (21 May 2024) - -- curl_setup.h: add support for IAR compiler - - Closes #13728 - -Stephen Farrell (21 May 2024) - -- docs/ECH: typo/clarification - - Closes #13727 - -Viktor Szakats (21 May 2024) - -- hash: delete unused debug function - - It had no use in the curl codebase and was also protected by the macro - `AGGRESSIVE_TEST` (renamed in 2020), also with no local reference. - - Added in ca6e77083768858aa34207f8c5dce38b3c05336d (2002-11-11) - - Closes #13729 - -Stefan Eissing (21 May 2024) - -- content_encoding: reject transfer-encoding after chunked - - reject a response that applies a transfer-encoding after a 'chunked' - encoding. RFC 9112 ch. 6.1 required chunked to be the final encoding. - - Closes #13733 - -- http: HEAD response body tolerance - - - as reported in #13725, some servers wrongly send body bytes in - responses to a HEAD request. This used to be tolerated in curl - 8.4 and before and leads to failed transfers in newer versions. - - restore previous behaviour for HTTP/1.1 and HTTP/2: - * 1.1: do not add 'Transfer-Encoding' writers from HEAD - responses. RFC 9112 says they do not apply. - * 2: when the transfer expects 'no_body', to not report stream - resets as error when all response headers have been received. - - Reported-by: Jeroen Ooms - Fixes #13725 - Closes #13732 - -Viktor Szakats (20 May 2024) - -- tests: fix TFTP test 2305 on Windows - - Ref: #13692 - Closes #13724 - -Jay Satiro (20 May 2024) - -- openssl: revert keylog_callback support for LibreSSL - - - Revert to the legacy TLS 1.2 key logging code for LibreSSL. - - - Document SSLKEYLOGFILE for LibreSSL is TLS 1.2 max. - - Prior to this change if the user specified a filename in the - SSLKEYLOGFILE environment variable and was using LibreSSL 3.5.0+ then - an empty file would be created and no keys would be logged. - - This is effectively a revert of e43474b4 which changed openssl.c to use - SSL_CTX_set_keylog_callback for LibreSSL 3.5.0+. Unfortunately LibreSSL - added that function only as a stub that doesn't actually do anything. - - Reported-by: Gonçalo Carvalho - - Fixes https://github.com/curl/curl/issues/13672 - Closes https://github.com/curl/curl/pull/13682 - -renovate[bot] (19 May 2024) - -- GHA: pin dependencies - - Closes #13712 - -Viktor Szakats (19 May 2024) - -- appveyor: drop unnecessary `--clean-first` cmake option - - In CI all machines are fresh on startup, making the `clean` operation - unnecessary. This can save some time/energy for each job run. - - Closes #13707 - -- cmake: merge two `if(BUILD_TESTING)` branches - - Closes #13708 - -Tatsuhiro Tsujikawa (19 May 2024) - -- GHA: bump nghttp2 to v1.62.1 - - Use gcc-12 explicitly to compile C++20 source files. - - Closes #13702 - -Viktor Szakats (19 May 2024) - -- GHA: add NetBSD, OpenBSD, FreeBSD/arm64 and OmniOS jobs - - Add these jobs to GHA: - - NetBSD, cmake-unity, clang, OpenSSL, x86_64, with tests, w/o python, - no parallelism (was flaky sometimes) - - OpenBSD, cmake-unity, clang, LibreSSL, x86_64, with tests, - with python, -j8, TFTP results ignored due to #13623. - - FreeBSD, cmake-unity and autotools, clang, OpenSSL, arm64 - (Tests disabled for arm64, because they are slow. It's available for - x86_64 with python, -j12.) - Configuration matches our existing Cirrus CI one. - - OmniOS, autotools, gcc, OpenSSL, x86_64, with tests, -j12. - - All build with websockets and examples. - - Closes #13583 - -- GHA: disable TFTP test on native Windows - - Some TFTP tests seem to enter into a loop and maybe hang? - - E.g. 1007, 1009, 1238 - - Try fixing it by skipping all TFTP tests. - - Ref: https://github.com/curl/curl/actions/runs/9141987545/job/25137038249?pr= - 13698 - - Also drop mingw-w64 test exclusions copy-pasted from MSYS jobs. - - Possibly related: cffbcc3110c1eda2e333f9cfe2e269154618793a #5364 - - Close #13699 - -renovate[bot] (18 May 2024) - -- GHA: pin dependencies - - Closes #13691 - -Viktor Szakats (18 May 2024) - -- cmake: do not pass linker flags to the static library tool - - Do not add linker flags to the global CMake static library tool (aka - "static linker") (e.g. `ar`) flags list. They don't mix well. This was - only done after successfully detecting GSSAPI. - - Linker flags seen on Old Linux CI: - ``` - -- |GSS_LINKER_FLAGS|-Wl,--enable-new-dtags -Wl,-rpath -Wl,/usr/lib/x86_64-li - nux-gnu/heimdal| - -- |CMAKE_STATIC_LINKER_FLAGS| -Wl,--enable-new-dtags -Wl,-rpath -Wl,/usr/lib - /x86_64-linux-gnu/heimdal| - ``` - Ref: https://github.com/curl/curl/actions/runs/9138988036/job/25130791712#ste - p:6:85 - - Causing: - ``` - /usr/bin/ar qc libcurltool.a -Wl,--enable-new-dtags -Wl,-rpath -Wl,/usr/lib/ - x86_64-linux-gnu/heimdal - CMakeFiles/curltool.dir/slist_wc.c.o CMakeFiles/curltool.dir/tool_binmode.c - .o CMakeFiles/curltool.dir/tool_bname.c.o - [...] - CMakeFiles/curltool.dir/tool_writeout_json.c.o CMakeFiles/curltool.dir/tool - _xattr.c.o CMakeFiles/curltool.dir/var.c.o - CMakeFiles/curltool.dir/__/lib/base64.c.o CMakeFiles/curltool.dir/__/lib/dy - nbuf.c.o - /usr/bin/ar: invalid option -- 'W' - Usage: /usr/bin/ar [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV] [--pl - ugin ] [member-name] [count] archive-file file... - /usr/bin/ar -M [now - c->timestamp; - | ^~~ - curl/lib/hostip.c: In function 'Curl_hostcache_prune': - curl/lib/hostip.c:241:10: note: 'now' was declared here - 241 | time_t now; - | ^~~ - In function 'hostcache_timestamp_remove', - inlined from 'fetch_addr' at curl/lib/hostip.c:310:8: - curl/lib/hostip.c:205:23: error: 'user.now' may be used uninitialized [-Werro - r=maybe-uninitialized] - 205 | time_t age = prune->now - c->timestamp; - | ~~~~~^~~~~ - curl/lib/hostip.c: In function 'fetch_addr': - curl/lib/hostip.c:304:33: note: 'user' declared here - 304 | struct hostcache_prune_data user; - | ^~~~ - In file included from curl/_bld/lib/CMakeFiles/libcurl_object.dir/Unity/unity - _0_c.c:40: - curl/lib/cf-socket.c: In function 'cf_socket_send': - curl/lib/cf-socket.c:1294:10: error: 'c' may be used uninitialized [-Werror=m - aybe-uninitialized] - 1294 | if(c >= ((100-ctx->wblock_percent)*256/100)) { - | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - curl/lib/cf-socket.c:1292:19: note: 'c' was declared here - 1292 | unsigned char c; - | ^ - In file included from curl/_bld/lib/CMakeFiles/libcurl_object.dir/Unity/unity - _0_c.c:364: - In function 'tftp_state_timeout', - inlined from 'tftp_multi_statemach' at curl/lib/tftp.c:1230:27: - curl/lib/tftp.c:1208:5: error: 'current' may be used uninitialized [-Werror=m - aybe-uninitialized] - 1208 | if(current > state->rx_time + state->retry_time) { - | ^ - curl/lib/tftp.c: In function 'tftp_multi_statemach': - curl/lib/tftp.c:1192:10: note: 'current' was declared here - 1192 | time_t current; - | ^~~~~~~ - ``` - Ref: https://ci.appveyor.com/project/curlorg/curl/builds/49792835/job/91c8dj5 - qb36spfe0#L112 - Ref: https://github.com/curl/curl/actions/runs/9082968838/job/24960616145#ste - p:12:62 - - Ref: #13592 - Closes #13643 - -Andrew (16 May 2024) - -- wakeup_create: use FD_CLOEXEC/SOCK_CLOEXEC - - for `pipe()`/`socketpair()` - - Fixes #13618 - Closes #13625 - -Stefan Eissing (16 May 2024) - -- rustls: fix partial send handling - - When TLS bytes could not completely sent off, the amount of plain bytes - already added to rustls were forgotten. This lead to send those byte - duplicate, corrupting the request send to the server. - - Closes #13676 - -- pytest: add DELETE tests, check server version - - - add tests for DELETE working - - check apache version in keepalive test - - fix some comments - - Closes #13679 - -Juliusz Sosinowicz (16 May 2024) - -- vquic-tls: use correct cert name check API for wolfSSL - - wolfSSL_X509_check_host checks the peer name against the alt names and - the common name. - - Fixes #13487 - Closes #13680 - -Viktor Szakats (16 May 2024) - -- cmake: initialize `BUILD_TESTING` before first use - - Before this patch `BUILD_TESTING` was used once, then initialized, then - used again. This caused the `curlu` library not being built when relying - on an implicit `BUILD_TESTING=ON` setting, and ending up with a link - error when building the `testdeps` target. - - It did not cause issues when `BUILD_TESTING` was explicitly set. - - Move the initialization before the first use to fix it. - - Regression from aace27b0965c10394544d1dacc9c2cb2fe0de3d3 #12287 - Closes #13668 - -Daniel Stenberg (16 May 2024) - -- libtest: 2308 verifies CURLE_WRITE_ERROR after write callback error - - Verifies that the issue in #13669 actually is fixed. This return code is - what the CURLOPT_WRITEFUNCTION manpage documents should be returned. - - This code is mostly from the - Source-written-by: Trumeet on github - Closes #13671 - -Antoine Bollengier (16 May 2024) - -- socketpair: fix compilation when USE_UNIX_SOCKETS is not defined - - Closes #13666 - -Stefan Eissing (16 May 2024) - -- rustsls: fix error code on receive - - - use CURLE_RECV_ERROR instead of CURLE_READ_ERROR when receiving - data fails. - - Closes #13670 - -Max Dymond (16 May 2024) - -- ci: disable Renovate dashboard - - The Renovate dashboard insists on an open issue, - which is a problem. Disable the dashboard. Status - can still be seen at https://developer.mend.io/github/curl/curl. - - Fixes #13630 - Closes #13673 - -Daniel Stenberg (16 May 2024) - -- RELEASE-NOTES: synced - -renovate[bot] (16 May 2024) - -- GHA: update awslabs/aws-lc to v1.27.0 - - Closes #13667 - -Daniel Stenberg (15 May 2024) - -- curl_easy_pause.md: use correct defines in example - - Spotted-by: Harry Sintonen - Closes #13664 - -Viktor Szakats (15 May 2024) - -- appveyor: more tidy-ups - - - use `--disable` when calling `curl --version`. Just in case. - - - use single-quotes for a constant. - - Closes #13662 - -- reuse: migrate standalone license file to dep5 - - Follow-up to 73a36021207284ad2b4340ffde34a51b0ba4d47a - Closes #13660 - -- appveyor: guard against crash-build with VS2008 - - The combination of `-DDEBUGBUILD`, a shared `curl.exe`, and the VS2008 - compiler creates a `curl.exe` segfaulting on startup: - - ``` - + _bld/src/curl.exe --version - ./appveyor.sh: line 122: 793 Segmentation fault "${curl}" --version - Command exited with code 139 - ``` - Ref: https://ci.appveyor.com/project/curlorg/curl/builds/49817266/job/651iy6q - n1e238pqj#L191 - - Add job that triggers the issue and add the necessary logic to skip - running the affected `curl.exe`. - - Ref: #13592 - Closes #13654 - -renovate[bot] (15 May 2024) - -- GHA: pin dependencies - - Closes #13628 - -Orgad Shaneh (15 May 2024) - -- socket: remove redundant call to getsockname - - The result "add" is unused. - - Closes #13655 - -renovate[bot] (15 May 2024) - -- CI: renovate updates - - - GHA: update actions/checkout action to v4 - - GHA: update wolfSSL/wolfssh to v1.4.17 - - GHA: update wolfSSL/wolfssl to v5.7.0 - - Update the regex config in renovate.json - - Closes #13632 - Closes #13641 - Closes #13658 - Closes #13659 - -Max Dymond (15 May 2024) - -- ci: fix renovate config for WolfSSL/WolfSSH tagging scheme - - WolfSSL/WolfSSH use a different versioning scheme; - stable builds end with `-stable`. Renovate requires - some extra configuration to extract the version - from these types of tags. - - Closes #13644 - -- ci: set semantic type as CI and include digests as CI operations - - Replace "chore" with "ci" for renovate's semantic - type, and include digests with "pin" and - "pinDigest" as ci operations. - - Closes #13644 - -Daniel Stenberg (15 May 2024) - -- DEPRECATE.md: TLS libraries without 1.3 support - - curl drops support for TLS libraries without TLS 1.3 capability after - May 2025. - - It requires that a curl build using the library should be able to - negotiate and use TLS 1.3, or else it is not good enough. We support a - vast amount of other TLS libraries that are likely to satisfy users - better. - - Closes #13544 - -- Revert "ci: update nghttp2/nghttp2 to v1.62.0" - - This reverts commit 14f2c767555b7598d7783ccd9093670b84d28488. - - We need to also upgrade the C++ compiler for that bump to work. - - Closes #13656 - -renovate[bot] (15 May 2024) - -- Dockerfile: update debian digest to 911821c - - Closes #13629 - -- ci: update gnutls/gnutls to v3.8.5 - - Closes #13640 - -- ci: update awslabs/aws-lc to v1.26.0 - - Closes #13647 - -- ci: update cloudflare/quiche to v0.21.0 - - Closes #13648 - -- ci: update libressl-portable/portable to v3.9.2 - - Closes #13649 - -- ci: update nghttp2/nghttp2 to v1.62.0 - - Closes #13650 - -- ci: update ngtcp2/nghttp3 to v1.3.0 - - Closes #13651 - -- ci: update ngtcp2/ngtcp2 to v1.5.0 - - Closes #13652 - -Max Dymond (14 May 2024) - -- ci: handle git submodules for mbedTLS - -- ci: reconfigure renovate - - - set prefix for github actions updates to be gha: - - set prefix for other renovate actions to be ci: - - disable debian updates in linux-old.yml - -Viktor Szakats (14 May 2024) - -- tidy-up: whitespace [ci skip] - -- warnless: delete orphan declarations - - Follow-up to 358f7e757781857c4b498a68634726609fa3884a #11932 - Closes #13639 - -Daniel Stenberg (14 May 2024) - -- BUG-BOUNTY.md: clarify the third party situation - - We do not pay bounties for problems in other libraries. - - Closes #13560 - -Stefan Eissing (14 May 2024) - -- http tests: in CI skip test_02_23* for quiche - - For unknown reasons, these tests fail in CI often, but run fine locally. - Skip them in CI to avoid unrelated PRs to have failures. - - Closes #13638 - -Daniel Gustafsson (14 May 2024) - -- hsts: explicitly skip blank lines - - Keep blank lines or lines containing only whitespace to make it all - the way to the more expensive sscanf call in hsts_add. - - Closes: #13603 - Reviewed-by: Daniel Stenberg - -- autotools: Only probe for SGI MIPS compilers on IRIX - - MIPSPro and the predecessor compiler which was part of the IDO (IRIS - Development Option) were only ever shipped on the SGI IRIX operating - system (with MIPSPro on 6.0+ which was released in 1994). Limit the - autoconf check to IRIX when probing for these compilers to save some - cycles on other platforms. - - Closes: #13611 - Reviewed-by: Daniel Stenberg - -Viktor Szakats (14 May 2024) - -- tests: fix test 1167 to skip digit-only symbols - - This avoids mistaking symbols with their numeric value when using - certain C preprocessors which output these numeric values at the - beginning of the line as part of an expression. - - Seen on OpenBSD 7.5 + clang. - - Example `test1167.pl -v` output, before this patch: - ``` - Source: cpp /home/runner/work/curl/curl/tests/../include/curl/curl.h - Symbol: 20000 - Line #3835: 20000 + 142, - [...] - Bad symbols in public header files: - 20000 - [...] - ``` - Ref: https://github.com/curl/curl/actions/runs/9069136530/job/24918015357#ste - p:3:7513 - - Ref: #13583 - Closes #13634 - -Daniel Stenberg (14 May 2024) - -- lib: call Curl_strntolower instead of doing crafted loops - - Closes #13627 - -- setopt: acknowledge errors proper for CURLOPT_COOKIEJAR - - Error out on error, do not continue. - - Closes #13624 - -- vtls: remove duplicate assign - - Curl_ssl_peer_cleanup() already clears the ->sni field, no point in - assigning it again. - - Spotted by CodeSonar - - Closes #13626 - -Max Dymond (13 May 2024) - -- Group all non-major updates together to reduce PR spam - -- Add the remainder of the workflows - -- Add some basic versioning for some workflows to check whether this is detecte - d properly - -renovate[bot] (13 May 2024) - -- Add renovate.json - -Daniel Stenberg (13 May 2024) - -- vauth: make two functions void that always just returned OK - - Removes the need to check return values when they can never fail. - - Pointed out by CodeSonar - - Closes #13621 - -- setopt: remove check for 'option' that is always true - - - make sure that passing in option set to NULL clears the fields - correctly - - - remove the weird second take if Curl_parse_login_details() returns - error - - Follow-up to 7333faf00bf25db7cd1e0012d6b140 - - Spotted by CodeSonar - - Closes #13619 - -Viktor Szakats (13 May 2024) - -- tests: tidy up types in server code - - Cherry-picked from #13489 - Closes #13610 - -Daniel Stenberg (13 May 2024) - -- setopt: make the setstropt_userpwd args compulsory - - They were always used so no point in allowing them to be optional. - - follow-up to 0e37b42dc956bd8a - - Closes #13608 - Reviewed-by: Daniel Gustafsson - -- RELEASE-NOTES: synced - -Daniel Gustafsson (13 May 2024) - -- websocket: Avoid memory leak in error path - - In the errorpath for randstr being too long to copy into the buffer - we leak the randstr when returning CURLE_FAILED_INIT. Fix by using - an explicit free on randstr in the errorpath. - - Closes: #13602 - Reviewed-by: Daniel Stenberg - -- hsts: Remove single-use single-line function - - The hsts_entry() function contains of a single line and is only - used in a single place in the code, so move the allocation into - hsts_create instead to improve code readability. C code usually - don't use the factory abstraction for object creation, and this - small example wasn't following our usual code style. - - Closes: #13604 - Reviewed-by: Daniel Stenberg - -Viktor Szakats (12 May 2024) - -- lib: bump hash sizes to `size_t` - - Follow-up to cc907e80a2498c0599253271a6f657f614b52a4e #13502 - Cherry-picked from #13489 - Closes #13601 - -- tests: make the unit test result type `CURLcode` - - Before this patch, the result code was a mixture of `int` and - `CURLcode`. - - Also adjust casts and fix a couple of minor issues found along the way. - - Cherry-picked from #13489 - Closes #13600 - -- appveyor: tidy-ups - - - delete a duplicate line. - - simplify a `make` call. - - merge two `if` branches. - - reorder autotools options for clarity. - - add `--enable-warnings` where missing (it's also the default.) - - add empty lines to YAML for readability. - - use lowercase install prefix/directory. - - Closes #13598 - -Daniel Stenberg (12 May 2024) - -- docs/cmdline-opts: mention STARTTLS for --ssl and --ssl-reqd - - ... since users might look for those terms in the manpage. - - Closes #13590 - -- setopt: warn on Curl_set*opt() uses not using the return value - - And switch the invokes that would "set" NULL to instead just plainly - free the pointer, as those were otherwise the invokes that would ignore - the return code. And possibly confuse static code analyzers. - - Closes #13591 - -Orgad Shaneh (12 May 2024) - -- autotools: delete unused functions - - Closes #13605 - -Viktor Szakats (11 May 2024) - -- examples: fix/silence `-Wsign-conversion` - - - extend `FD_SET()` hack to all platforms (was only Cygwin). - Warnings may also happen in other envs, e.g. OmniOS. - Ref: https://github.com/libssh2/libssh2/actions/runs/8854199687/job/2431676 - 2831#step:3:2021 - - - tidy-up `CURLcode` vs `int` use. - - - cast an unsigned to `long` before passing to `curl_easy_setopt()`. - - Cherry-picked from #13489 - Follow-up to 3829759bd042c03225ae862062560f568ba1a231 #12489 - Closes #13501 - -Orgad Shaneh (11 May 2024) - -- cmake: fix `HAVE_IOCTLSOCKET_FIONBIO` test with gcc 14 - - The function signature has had u_long flags since ever. This is how it - is defined in the documentation, and implemented in MinGW. - - The code that uses ioctlsocket in nonblock.c also has unsigned long. - - Error: - CurlTests.c:275:41: error: passing argument 3 of 'ioctlsocket' from incompati - ble pointer type [-Wincompatible-pointer-types] - 275 | if(0 != ioctlsocket(0, FIONBIO, &flags)) - | ^~~~~~ - | | - | int * - In file included from CurlTests.c:266: - /opt/mxe/usr/i686-w64-mingw32.static/include/winsock2.h:1007:76: note: expect - ed 'u_long *' {aka 'long unsigned int *'} but argument is of type 'int *' - 1007 | WINSOCK_API_LINKAGE int WSAAPI ioctlsocket(SOCKET s,__LONG32 cmd,u_ - long *argp); - | ~~ - ~~~~~~^~~~ - - Closes #13578 - -Jay Satiro (10 May 2024) - -- ftp: fix build for CURL_DISABLE_VERBOSE_STRINGS - - This is a follow-up to b7c7dffe which changed the FTP state change - verbose debug text (aka infof) to tracing debug text (aka trc). - - Prior to this change if libcurl was without DEBUGBUILD and built with - CURL_DISABLE_VERBOSE_STRINGS (ie --disable-verbose) the build would - error. - - Caught by Circle CI job openssl-no-verbose. - -- lib: clear the easy handle's saved errno before transfer - - - Clear data->state.os_errno before transfer. - - - Explain the change in behavior in the CURLINFO_OS_ERRNO doc. - - - Add to the CURLINFO_OS_ERRNO doc the list of libcurl network-related - errors that may cause the errno to be saved. - - data->state.os_errno is saved before libcurl returns a network-related - failure such as connection failure. It is accessible to the user via - CURLINFO_OS_ERRNO so they can get more information about the failure. - - Prior to this change it wasn't cleared before transfer, so if a user - retrieved the saved errno it could be from a previous transfer. That is - because an errno is not always saved for network-related errors. - - Closes https://github.com/curl/curl/pull/13574 - -Stefan Eissing (10 May 2024) - -- ftp: add tracing support - - - add `Curl_trc_feat_ftp` for tracing via trace config - - add macro CURL_TRC_FTP(data, fmt, ...) - - replace DEBUGF(infof()) statements in ftp.c by CURL_TRC_FTP() - - always trace FTP connection state - - Closes #13580 - -Daniel Stenberg (10 May 2024) - -- http: remove redundant check - - Spotted by CodeSonar - - Closes #13582 - -Viktor Szakats (10 May 2024) - -- ldap: fix unused variables (seen on OmniOS) - - ``` - ../../lib/ldap.c: In function 'ldap_do': - ../../lib/ldap.c:380:11: error: unused variable 'ldap_ca' [-Werror=unused-v - ariable] - 380 | char *ldap_ca = conn->ssl_config.CAfile; - | ^~~~~~~ - ../../lib/ldap.c:379:9: error: unused variable 'ldap_option' [-Werror=unuse - d-variable] - 379 | int ldap_option; - | ^~~~~~~~~~~ - ``` - Ref: https://github.com/curl/curl/actions/runs/9033564377/job/24824192730#ste - p:3:6059 - - Ref: #13583 - Closes #13588 - -Daniel Stenberg (10 May 2024) - -- url: make parse_login_details use memdup0 - - Also make the user and password arguments mandatory, since all code - paths in libcurl used them anyway. - - Adapted unit test case 1620 to the new rules. - - Closes #13584 - -Orgad Shaneh (10 May 2024) - -- digest: replace strcpy for empty string with simple assignment - - Closes #13586 - -Viktor Szakats (10 May 2024) - -- autotools: fix `HAVE_IOCTLSOCKET_FIONBIO` test for gcc 14 - - ``` - conftest.c:152:41: error: passing argument 3 of 'ioctlsocket' from incompatib - le pointer type [-Wincompatible-pointer-types] - 152 | if(0 != ioctlsocket(0, FIONBIO, &flags)) - | ^~~~~~ - | | - | int * - ``` - - Reported-by: LigH - Fixes #13579 - Closes #13587 - -- CI: ignore test 286 on Appveyor gcc 7 build - - Disabled earlier for gcc 9 builds. gcc 7 uses the same runner and - prone to similar intermittent failures. - - Follow-up to f1e05a6e6e7225fa09952abb2c935ae1abe44f45 #12106 #12040 - Closes #13575 - -Daniel Stenberg (10 May 2024) - -- cf-socket: don't try getting local IP without socket - - In cf_tcp_connect(), it might fail and not get a socket assigned to - ctx->sock but set_local_ip() is still called which would make - getsockname() get invoked with a negative file desriptor and fail. - - By adding this check, set_local_ip() will now instead blank out the - fields correctly. - - Spotted by CodeSonar - - Closes #13577 - -- tool_getparam: remove two redundant conditions - - When getstr() does not return error, it returns a valid pointer. - - Spotted by CodeSonar - - Closes #13576 - -Stefan Eissing (10 May 2024) - -- quiche: trust its timeout handling - - - set the idle timeout transport parameter - in milliseconds as documented by quiche - - do not calculate the idle timeout, rely on - quiche handling it - - Closes #13581 - -Daniel Stenberg (10 May 2024) - -- dmaketgz: accept a SOURCE_DATE_EPOCH as an second argument - - to make it easier to reproduce a tarball - - Closes #13573 - -- RELEASE-NOTES: synced - -Stefan Eissing (10 May 2024) - -- h3/ngtcp2: improve error handling - - - identify ngtcp2 and nghttp3 error codes that are fatal - - close quic connection on fatal errors - - refuse further filter operations once connection is closed - - confusion about the nghttp3 API. We should close the QUIC stream on - cancel and not use the nghttp3 calls intended to be invoked when the - QUIC stream was closed by the peer. - - Closes #13562 - -Jay Satiro (10 May 2024) - -- docs: fix some CURLINFO examples - - - improve getinfo result check for example sections: - CURLINFO_ACTIVESOCKET, CURLINFO_LASTSOCKET, CURLINFO_SSL_VERIFYRESULT, - CURLINFO_PROXY_SSL_VERIFYRESULT - - - fix getinfo result check for example sections: - CURLINFO_NUM_CONNECTS, CURLINFO_OS_ERRNO - - - fix verify result check for example sections: - CURLINFO_PROXY_SSL_VERIFYRESULT - - Bug: https://github.com/curl/curl/discussions/13557#discussion-6625507 - Reported-by: farazrbx@users.noreply.github.com - - Closes https://github.com/curl/curl/pull/13559 - -Daniel Stenberg (9 May 2024) - -- KNOWN_BUGS: gssapi library name + version is missing in curl_version_info() - - Closes #13492 - Closes #13570 - -- krb5: use dynbuf - - Closes #13568 - -- managen: fix the option sort order - - ... it used to strip off the .d file extension to sort correctly but - ever since the extension changed to .md the operation failed and the - sort got wrong. - - Follow-up to 2494b8dd5175cee7f2e - - Closes #13567 - -Stefan Eissing (8 May 2024) - -- GHA: repair the linux-old job - - package libc6_2.28-10+deb10u2_amd64.deb changed to - libc6_2.28-10+deb10u3_amd64.deb - - Closes #13564 - -Viktor Szakats (8 May 2024) - -- appveyor: make gcc 6 mingw64 job build-only - - This job has proven to be the flakiest of all, and it's also the oldest - Windows runner we had tests running on: 'Visual Studio 2015', that is - running on Windows Server 2012 R2: - https://www.appveyor.com/docs/windows-images-software/ - - Turn off tests on this job to help stabilizing CI runs. - - This was also one of the slowest running job amongst the AppVeyor CI ones. - - Flakiness data: - https://testclutch.curl.se/static/reports/summary.html - Entries: - Appveyor / CMake, mingw-w64, gcc 6, Debug, x86, Schannel, Static, no-unity - (curl) [current] - Appveyor / CMake, mingw-w64, gcc 6, Debug, x86, Schannel, Static (curl) [fo - rmer] - - Closes #13566 - -Stefan Eissing (8 May 2024) - -- unit2604: use alloc instead of overlong string const - - Closes #13563 - -Daniel Gustafsson (8 May 2024) - -- bufq: remove duplicate word in comment - - Inspired by 13552. - - Closes: #13554 - Reviewed-by: Daniel Stenberg - -Viktor Szakats (8 May 2024) - -- lib/cf-h1-proxy: silence compiler warnings (gcc 14) - - They came up ealier with gcc 12 (Windows), but apparently gcc 14 is - still reporting them, also under Linux. - - ``` - /home/runner/work/curl-for-win/curl-for-win/curl/lib/cf-h1-proxy.c: In functi - on 'cf_h1_proxy_close': - /home/runner/work/curl-for-win/curl-for-win/curl/lib/cf-h1-proxy.c:1060:17: w - arning: null pointer dereference [-Wnull-dereference] - 1060 | cf->connected = FALSE; - /home/runner/work/curl-for-win/curl-for-win/curl/lib/cf-h1-proxy.c:1061:8: wa - rning: null pointer dereference [-Wnull-dereference] - 1061 | if(cf->ctx) { - | ~~^~~~~ - In function 'tunnel_free', - inlined from 'cf_h1_proxy_destroy' at /home/runner/work/curl-for-win/curl - -for-win/curl/lib/cf-h1-proxy.c:1053:3: - /home/runner/work/curl-for-win/curl-for-win/curl/lib/cf-h1-proxy.c:198:27: wa - rning: null pointer dereference [-Wnull-dereference] - 198 | struct h1_tunnel_state *ts = cf->ctx; - | ^~ - ``` - Ref: https://github.com/curl/curl-for-win/actions/runs/8985369476/job/2467921 - 9528#step:3:6320 - - Fixes #13237 - Closes #13555 - -Michał Antoniak (8 May 2024) - -- mbedtls: support TLS 1.3 - - Closes #13539 - -Daniel Stenberg (8 May 2024) - -- version: use msnprintf instead of strncpy - - - to ensure a terminating null byte - - to avoid zero-padding the target - - debug code only - - Closes #13549 - -- curl_path: make Curl_get_pathname use dynbuf - - ... instead of malloc and memcpy - - - unit test 2604 verifies Curl_get_pathname() - - Closes #13550 - -- lib: make protocol handlers store scheme name lowercase - - - saves a lowercase operation when the "[scheme]_proxy" name is - generated - - appears less "shouting" - - update test 970, 972, 1438 and 1536 - - Closes #13553 - -- lib: remove two instances of "only only" messages - - Fixes #13551 - Reported-by: Lucas Nussbaum - Closes #13552 - -Pavel Pavlov (7 May 2024) - -- asyn-thread: fix curl_global_cleanup crash in Windows - - - Make sure that asynchronous resolves handled by Winsock are stopped - before WSACleanup is called. - - This is implemented by ensuring that when Curl_resolver_kill is called - (eg via multi_done) it will cancel the Winsock asynchronous resolve and - wait for the cancellation to complete. Winsock runs the asynchronous - completion routine immediately when a resolve is canceled. - - Prior to this change it was possible that during curl_global_cleanup - "a DNS resolver thread created by GetAddrInfoExW did not terminate yet, - however curl is already shutting down, deinitializing Winsock with - WSACleanup() leading to an access violation." - - Background: - - If libcurl is built with the asynchronous threaded resolver option for - Windows then it resolves in one of two ways. For Windows 8.1 and later, - libcurl resolves by using the Winsock asynchronous resolver which does - its own thread management. For older versions of Windows, libcurl - resolves by creating a separate thread that calls getaddrinfo. This - change only affects the former and it's already handled for the latter. - - Reported-by: Ch40zz@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/13509 - Closes https://github.com/curl/curl/pull/13518 - -Jay Satiro (7 May 2024) - -- asyn-thread: fix Curl_thread_create result check - - - Compare to curl_thread_t_null instead of 0 for error. - - Currently for both supported thread libraries (pthreads and Windows) - curl_thread_t_null is defined as 0. However, the pattern throughout the - code is to check against curl_thread_t_null and not 0 since for - posterity some thread library may not use 0 for error. - - Closes https://github.com/curl/curl/pull/13542 - -- curl_multibyte: remove access() function wrapper for Windows - - - Remove curlx_win32_access() which was a wrapper to use access() in - Windows. - - This is a follow-up to 602fc213, one of two commits which removed - access() calls from the codebase and banned use of the function. - - Closes https://github.com/curl/curl/pull/13529 - -Daniel Gustafsson (6 May 2024) - -- tls: Remove EXAMPLEs from deprecated options - - CURLOPT_EGDSOCKET and CURLOPT_RANDOM_FILE are both completely dead - so remove their example sections since the code there is useless. - There is still a way to inject a random file for OpenSSL older than - 1.1.0 but it's not what the example showed (and it's not even done - with this option) so we refrain from documenting it here. - - Closes: #13540 - Reviewed-by: Daniel Stenberg - -- tests: Only require EXAMPLE for non-deprecated options - - Manpages which document deprecated CURLOPT_ or CURLINFO_ are not - required to have an EXAMPLE section since they might effectively - be dead no-ops which we don't want to trick users into believing - they can use by copying example code. - - Closes: #13540 - Reviewed-by: Daniel Stenberg - -Daniel Stenberg (6 May 2024) - -- EXPERIMENTAL: add graduation requirements for each feature - - Starting now, experimental features should have a set of documentated - requirements of what is needed for the feature to graduate. - - This adds requirements to all existing experiments. - - Closes #13541 - -Ivan (6 May 2024) - -- misc: fix typos, quoting and spelling - - Fix wording of comments, and misquotings where `' is markdown parsed - where it shouldn't be, and remove a misspelled preprocessor comment - which really isn't needed (and removing it makes it match surrounding - code better). - - Closes: #13538 - Reviewed-by: Daniel Gustafsson - -Daniel Gustafsson (6 May 2024) - -- tests: Mark tftpd timer function as noreturn - - This avoids the below compiler warning: - - tftpd.c:280:1: warning: function 'timer' could be declared with - attribute 'noreturn' [-Wmissing-noreturn] - - Closes: #13534 - Reviewed-by: Daniel Stenberg - -- doh: Remove unused function prototype - - Closes: #13536 - Reviewed-by: Daniel Stenberg - -Daniel Stenberg (6 May 2024) - -- doh: cleanups in ECH related functions - - - make local_decode_rdata_name use dynbuf instead of calloc + memcpy - - avoid extra memdup in local_decode_rdata_alpn - - no need to if() before free() - - use memdup instead of calloc + memcpy in Curl_doh_decode_httpsrr - - Reviewed-by: Stephen Farrell - Closes #13526 - -Viktor Szakats (5 May 2024) - -- libssh2: delete redundant feature guard - - Delete `HAVE_LIBSSH2_VERSION` (equivalent to - `LIBSSH2_VERSION_NUM` > 0x010100) guard surrounding - a `LIBSSH2_VERSION_NUM` > 0x010B00 one. - - Reviewed-by: Daniel Gustafsson - Closes #13537 - -Jan Venekamp (5 May 2024) - -- tool_cfgable: free {proxy_}cipher13_list on exit - - Author: Jan Venekamp - Reviewed-by: Daniel Gustafsson - Closes: #13531 - -RainRat (4 May 2024) - -- doh: Fix typo in comment - - Closes: #13504 - Author: RainRat on Github - Reviewed-by: Daniel Stenberg - Reviewed-by: Daniel Gustafsson - -Christian Schmitz (4 May 2024) - -- dynbuf: Fix returncode on memory error - - Curl_dyn_vaddf should return a proper error code in case allocating - memory failed. - - Closes: #13533 - Author: Christian Schmitz - Reviewed-by: Daniel Gustafsson - -Daniel Stenberg (3 May 2024) - -- RELEASE-NOTES: synced - -Jan Venekamp (2 May 2024) - -- bearssl: use common code for cipher suite lookup - - Take advantage of the Curl_cipher_suite_walk_str() and - Curl_cipher_suite_get_str() functions introduced in commit fba9afeb. - - This also fixes CURLOPT_SSL_CIPHER_LIST not working at all for bearssl - due to commit ff74cef5. - - Closes #13464 - -Daniel Stenberg (2 May 2024) - -- curl.h: change CURL_SSLVERSION_* from enum to defines - - C++20 and later compilers emit a deprecation warning if values from two - different enums are combined with a bitwise operation the way the - CURL_SSLVERSION_* values were previously created. - - Reported-by: Michael Kaufmann - Fixes #13510 - Closes #13511 - -- configure: error on missing perl if docs or manual is enabled - - Fixes #13508 - Reported-by: Harmen Stoppels - Closes #13514 - -- tool_cb_rea: limit rate unpause for -T . uploads - - To avoid getting stuck in a busy-loop when nothing is read from stdin, - this function now checks the call rate and might enforce a short sleep - when called repeatedly without uploading anything. It is a crude - work-around to avoid a 100% busy CPU. - - Reported-by: magisterquis on hackerone - Fixes #13174 - Closes #13506 - -Viktor Szakats (1 May 2024) - -- appveyor: enable websockets for VS2017 jobs - - Follow-up to eb4fe6c6340c3d5b0c347c6e30be004d4f9117d7 #13232 - Closes #13513 - -Daniel Stenberg (30 Apr 2024) - -- if2ip: make the buf_size arg a size_t - - sizes should be size_t - - Ref: #13489 - Closes #13505 - -- cf-https-connect: use timeouts as unsigned ints - - To match the type used in 'set.happy_eyeballs_timeout'. - - Ref: #13489 - Closes #13503 - -- hash: change 'slots' to size_t from int - - - an unsigned type makes more sense - - size_t seems suitable - - on 64 bit args, the struct alignment makes the new Curl_hash remain - the same size - - Closes #13502 - -Viktor Szakats (30 Apr 2024) - -- libssh2: replace `access()` with `stat()` - - Prefer `stat()` to verify the presence of key files. - - This drops the last uses of `access()` in the codebase, which was - reported to cause issues in some cases. - - Also add `access()` to the list of banned functions in checksrc. - - Ref: https://github.com/curl/curl/pull/13412#issuecomment-2065505415 - Ref: https://github.com/curl/curl/pull/13482#issuecomment-2078980522 - Ref: #13497 - Co-authored-by: Jay Satiro - Closes #13498 - -Daniel Stenberg (30 Apr 2024) - -- multi: remove useless assignment - - Spotted by CodeSonar - - Closes #13500 - -- RELEASE-NOTES: synced - -fuzzard (29 Apr 2024) - -- cmake: FindNGHTTP2 add static lib name to find_library call - - Add the static library name, nghttp2_static as a name to search. - - This provides cmake parity with the winbuild Makefile.vc allowing - the cmake build to find and allow the link to static nghttp2 library. - -Viktor Szakats (29 Apr 2024) - -- DISTROS: add patch and issues link for curl-for-win - - curl-for-win sometimes includes curl patches that were already merged in - master, but not yet part of a stable release. - - Also include the Issues link. Build-specific issues are handled there. - - Ref: #13493 - Closes #13499 - -Daniel Stenberg (29 Apr 2024) - -- mime: avoid using access() - - If stat() fails, there is no point in calling access() - - Also: return error immediately if the stat() fails. - - Ref: #13482 - Closes #13497 - -Stefan Eissing (29 Apr 2024) - -- tests: add SNI and peer name checks - - - connect to DNS names with trailing dot - - connect to DNS names with double trailing dot - - rustls, always give `peer->hostname` and let it - figure out SNI itself - - add SNI tests for ip address and localhost - - document in code and TODO that QUIC with ngtcp2+wolfssl - does not do proper peer verification of the certificate - - mbedtls, skip tests with ip address verification as not - supported by the library - - Closes #13486 - -Daniel Stenberg (29 Apr 2024) - -- curl_getdate.md: document two-digit year handling - - Mentioned-by: Paul Gilmartin - Ref: https://curl.se/mail/archive-2024-04/0014.html - Closes #13494 - -Viktor Szakats (29 Apr 2024) - -- cmake: add `BUILD_EXAMPLES` option to build examples - - You can enable it with `-DBUILD_EXAMPLES=ON`. - - To match autotools' `make examples` feature. - Windows (static) builds not tested. - - Also enable examples in a pair of CI jobs. - - Apply related updates to the macOS CI workflow: - - drop unused `CXX` envs. - - drop no longer needed `-Wno-error=undef -Wno-error=conversion` flags. - - pass `-Wno-deprecated-declarations` to GCC too (for `BUILD_EXAMPLES`). - - document why `-Wno-deprecated-declarations` is necessary. - - Closes #13491 - -Stefan Eissing (26 Apr 2024) - -- http3: quiche+ngtcp2 improvements - - - quiche: error transfers that try to receive on a closed - or draining connection - - ngtcp2: use callback for extending max bidi streams. This - allows more precise calculation of MAX_CONCURRENT as we - only can start a new stream when the server acknowledges - the close - not when we locally have closed it. - - remove a fprintf() from h2-download client to avoid excess - log files on tests timing out. - - Closes #13475 - -- vtls: TLS session storage overhaul - - - add session with destructor callback - - remove vtls `session_free` method - - let `Curl_ssl_addsessionid()` take ownership - of session object, freeing it also on failures - - change tls backend use - - test_17, add tests for SSL session resumption - - Closes #13386 - -- multi: multi_wait improvements - - - only call `multi_getsock()` once for all transfers - - realloc pollset array on demand - - fold repeated sockets - - Closes #13150 - -Philip Heiduck (25 Apr 2024) - -- ci: remove microsoft-prod.list - - This is added by default, and it is often broken, but we don't need - anything from it. - - Closes #13473 - -Evgeny Grin (Karlson2k) (25 Apr 2024) - -- curl_setup.h: detect 'inline' support - - Closes #13355 - -Daniel Stenberg (25 Apr 2024) - -- multi: avoid memory-leak risk - - 'newurl' is allocated in some conditions and used in a few scenarios, - but there were theoretical combinations in which it would not get freed. - Move the free to happen unconditionally. Never triggered by tests, but - spotted by Coverity. - - Closes #13471 - -Johann Sebastian Schicho (25 Apr 2024) - -- sendf: Curl_cwriter_write: remove comment disallowing zero length writes - - They are needed to pass CLIENTWRITE_EOS. - - Closes #13477 - -Stefan Eissing (25 Apr 2024) - -- CI: macos fixes for new ARM GHA images - - - based on #13478 with additions from #13476 - - make homebrew install path flexible - - fix OpenSSL pkgconfig files libdir - - add path to --with-libssh2 target - - disable gcc securetransport due to linker - errors (missing symbols), probably because - the os version is no longer low enough - - Assisted-by: Viktor Szakats - - Closes #13479 - -- content_encoding: ignore duplicate chunked encoding - - - ignore duplicate "chunked" transfer-encodings from - a server to accomodate for broken implementations - - add test1482 and test1483 - - Reported-by: Mel Zuser - Fixes #13451 - Closes #13461 - -Daniel Stenberg (25 Apr 2024) - -- tool: move tool_ftruncate64 to tool_util.c - - ... and the prototype to tool_setup.h, to make them both available more - widely and accurately. - - Follow-up to 00bef95946d3511 - - Fixes #13458 - Closes #13459 - -Viktor Szakats (24 Apr 2024) - -- lib: silence `-Wsign-conversion` in base64, strcase, mprintf - - Closes #13467 - -- CI: retain failure code after `./configure` with Circle CI - - Suggested-by: Dan Fandrich - Follow-up to 43299e93c06b96fea8a8dc9b1c2e49c82bc21801 #13462 - Follow-up to d7332e3e46c3ef401b34e6a1a129eb4dd846c452 #12635 - Closes #13468 - -Daniel Stenberg (24 Apr 2024) - -- RELEASE-NOTES: synced - -Jan Venekamp (24 Apr 2024) - -- mbedTLS: implement CURLOPT_SSL_CIPHER_LIST option - - Use a lookup list to set the cipher suites, allowing the - ciphers to be set by either openssl or IANA names. - - To keep the binary size of the lookup list down we compress - each entry in the cipher list down to 2 + 6 bytes using the - C preprocessor. - - Closes #13442 - -Viktor Szakats (24 Apr 2024) - -- CI: show more failed `config.log` on Circle CI - - Show last 1000 lines of `config.log` if `./configure` fails. This was - already done for one job, this patch extends it to all. - - Ref: #13438 - Closes #13462 - -Daniel Stenberg (24 Apr 2024) - -- telnet: check return code from fileno() - - and return error if necessary - - Spotted by CodeSonar - - Closes #13457 - -Viktor Szakats (24 Apr 2024) - -- tls: fix SecureTransport + BearSSL cmake unity builds - - Avoid clashing static function names by namespacing them. - - Pointed-out-by: Jan Venekamp - Ref: https://github.com/curl/curl/pull/13442#discussion_r1576350700 - Closes #13450 - -Jay Satiro (24 Apr 2024) - -- dllmain: Call OpenSSL thread cleanup for Windows and Cygwin - - - Call OPENSSL_thread_stop on thread termination (DLL_THREAD_DETACH) - to prevent a memory leak in case OpenSSL is linked statically. - - - Warn in libcurl-thread.3 that if OpenSSL is linked statically then it - may require thread cleanup. - - OpenSSL may need per-thread cleanup to stop a memory leak. For Windows - and Cygwin if libcurl was built as a DLL then we can do that for the - user by calling OPENSSL_thread_stop on thread termination. However, if - libcurl was built statically then we do not have notification of thread - termination and cannot do that for the user. - - Also, there are several other unusual cases where it may be necessary - for the user to call OPENSSL_thread_stop, so in the libcurl-thread - warning I added a link to the OpenSSL documentation. - - Co-authored-by: Viktor Szakats - - Reported-by: southernedge@users.noreply.github.com - Reported-by: zmcx16@users.noreply.github.com - - Ref: https://www.openssl.org/docs/man3.0/man3/OPENSSL_thread_stop.html#NOTES - - Fixes https://github.com/curl/curl/issues/12327 - Closes https://github.com/curl/curl/pull/12408 - -Jan Venekamp (24 Apr 2024) - -- rustls: remove incorrect SSLSUPP_TLS13_CIPHERSUITES flag - - The rustls backend advertises SSLSUPP_TLS13_CIPHERSUITES, but - the code does not actually seem to support it (yet?). Removed - the flag and corrected documentation. - - Closes #13452 - -Stefan Eissing (24 Apr 2024) - -- quiche: expire all active transfers on connection close - - - when a connection close is detected, all ongoing transfers - need to expire bc no more POLL events are likely to happen - for them. - - Fixes #13439 - Reported-by: Jay Satiro - Closes #13447 - -Dan Fandrich (23 Apr 2024) - -- tests: fix feature case in test1481 - - This test was being skipped everywhere because the feature never - matched. - - Closes #13445 - -Gusted (23 Apr 2024) - -- tool_operate: don't truncate the etag save file by default - - This fixes a regression of 75d79a4486b279100209ddf8c7fdb12955fb66e9. The - code in tool-operate truncated the etag save file, under the assumption - that the file would be written with a new etag value. However since - 75d79a4486b279100209ddf8c7fdb12955fb66e9 that might not be the case - anymore and could result in the file being truncated when --etag-compare - and --etag-save was used and that the etag value matched with what the - server responded. Instead the truncation should not be done when a new - etag value should be written. - - Test 3204 was added to verify that the file with the etag value doesn't - change the contents when used by --etag-compare and --etage-save and - that value matches with what the server returns on a non 2xx response. - - Closes #13432 - -Abdullah Alyan (22 Apr 2024) - -- tests: enable test 1117 for hyper - - Closes #13436 - -Daniel Stenberg (22 Apr 2024) - -- sendf: useless assignment in cr_lc_read() - - Spotted by CodeSonar - - Closes #13437 - -- tool_paramhlp: remove duplicate assign - - Spotted by CodeSonar - - Closes #13433 - -- transfer: remove useless assignment - - in Curl_xfer_recv_resp - - Spotted by CodeSonar - - Closes #13435 - -- http: acknowledge a returned error code - - ... and do not overwrite it with a new value that could then hide the - problem. - - Spotted by CodeSonar - - Closes #13434 - -- tool_operate: init vars unconditionally in post_per_transfer - - In case of (the unlikely) early return, they could otherwise remain - uninitialized - - Spotted by CodeSonar - - Closes #13430 - -- RELEASE-NOTES: synced - -- urlapi: allow setting port number zero - - Also set and check errno when strtoul() parsing numbers for better error - checking. - - Updated test 1560 - - Closes #13427 - -- http_aws_sigv4: remove useless assignment - - This code assigned the variable the same value it already had - - Spotted by CodeSonar - - Closes #13426 - -- file: remove useless assignment - - This code assigned the variable the same value it already had. - - Spotted by CodeSonar - - Closes #13425 - -- test2406: verify -f with HTTP/2 - -Stefan Eissing (19 Apr 2024) - -- http2 + ngtcp2: pass CURLcode errors from callbacks - - - errors returned by Curl_xfer_write_resp() and the header variant are - not errors in the protocol. The result needs to be returned on the - next recv() from the protocol filter. - - - make xfer write errors for response data cause the stream to be - cancelled - - - added pytest test_02_14 and test_02_15 to verify that also for - parallel processing - - Reported-by: Laramie Leavitt - Fixes #13411 - Closes #13424 - -Daniel Stenberg (19 Apr 2024) - -- request: make Curl_req_init return void - - Since it could not return error and therefore this change removes dead - code for the caller. - - Spotted by CodeSonar. - - Closes #13423 - -- multi: remove the unused Curl_preconnect function - - The implementation has been removed, no point in keeping it around. - - Follow-up to 476adfeac019ed - - Closes #13422 - -- Curl_creader_read: init two variables to avoid using them uninited - - Spotted by CodeSonar - - Closes #13419 - -- http: reject HTTP major version switch mid connection - - A connection that has seen an HTTP major version now refuses any other - major HTTP version in future responses. Previously, a HTTP/1.x - connection would just silently accept HTTP/2 or HTTP/3 in the status - lines as long as it had support for those built-in. It would then just - lead to confusion and badness. - - Indirectly Spotted by CodeSonar which identified a duplicate assignment - in this function. - - Add test 471 to verify - - Closes #13421 - -- mqtt: when Curl_xfer_recv returns error, don't use nread - - A returned error code makes other return value unreliable, and in this - case potentially uninitialized. On error, do not read other return - values like the nread counter. - - Spotted by CodeSonar - - Closes #13418 - -- ftp: fix socket leak on rare error - - In the function AcceptServerConnect() the newly created socket would - leak if Curl_conn_tcp_accepted_set() returns error. Which basically - should never happen. - - Spotted by CodeSonar. - - Closes #13417 - -- urlapi: remove unused flags argument from Curl_url_set_authority - - The function is only called from a single place (for HTTP/2 server push) - so might as well just assume this fixed option every time. - - Closes #13409 - -- github/ISSUE_TEMPLATE: tweak the commericual support text - -- github/ISSUE_TEMPLATE: link the GitHub discussions too - - ... and move the feature request line to the bottom. - -- curl_url_get.md: clarify queries and fragments and CURLU_GET_EMPTY - - Follow-up to 3eac21d86bc5 - - Closes #13407 - -Stefan Eissing (18 Apr 2024) - -- tests: check caddy server version to match test expectations - - - new caddy servers no longer return 200 on POSTs, but 405 - as they should - - Closes #13405 - -Daniel Stenberg (18 Apr 2024) - -- curl_url_set.md: extended - - Closes #13404 - -- urlapi: add CURLU_GET_EMPTY for empty queries and fragments - - By default the API inhibits empty queries and fragments extracted. - Unless this new flag is set. - - This also makes the behavior more consistent: without it set, zero - length queries and fragments are considered not present in the URL. With - the flag set, they are returned as a zero length strings if they were in - fact present in the URL. - - This applies when extracting the individual query and fragment - components and for the full URL. - - Closes #13396 - -- RELEASE-NOTES: synced - -- lib1560: test with leading zeroes and more IPv4 versions - - Inspired by WHATWG URL Spec test inputs - - Closes #13400 - -Christian Schmitz (17 Apr 2024) - -- smtp: result of Curl_bufq_cread was not used - - return the result back to the caller. - - Closes #13398 - -Daniel Stenberg (17 Apr 2024) - -- urlapi: fix relative redirects to fragment-only - - Using the URL API for a redirect URL when the redirected-to string - starts with a hash, ie is only a fragment, the API would produce the - wrong final URL. - - Adjusted test 1560 to test for several new redirect cases. - - Closes #13394 - -Jiwoo Park (17 Apr 2024) - -- url: fix use of an uninitialized variable - - Closes #13399 - -Patrick Monnerat (17 Apr 2024) - -- os400: sync with latest changes - - - Conversion support for new version info character field rtmp_version. - - New ILE/RPG declarations. - - Closes #13402 - -Daniel Stenberg (17 Apr 2024) - -- ngtcp2: fix macro use - - macro "H3_STREAM_CTX" requires 2 arguments, but only 1 given - - Follow-up to c6655f7029ec5c128561e3ecf1f93db3ed0432a4 - - Closes #13401 - -Christian Schmitz (17 Apr 2024) - -- sendf: fix two typos in comments - - The parameters are named data, not date. - - Closes #13393 - -- lib: silence warnings on comma misuse - - Building curl with -Wcomma, I see warnings about "possible misuse of - comma operator here" and moving fields assignment out of the for() fixes - it. - - Closes #13392 - -Stefan Eissing (17 Apr 2024) - -- http/2, http/3: decouple stream state from easy handle - - - add `Curl_hash_offt` as hashmap between a `curl_off_t` and - an object. Use this in h2+h3 connection filters to associate - `data->id` with the internal stream state. - - changed implementations of all affected connection filters - - removed `h2_ctx*` and `h3_ctx*` from `struct HTTP` and thus - the easy handle - - solves the problem of attaching "foreign protocol" easy handles - during connection shutdown - - Test 1616 verifies the new hash functions. - - Closes #13204 - -Daniel Stenberg (17 Apr 2024) - -- ROADMAP: remove completed entries, mention websocket - -- THANKS-filter: name fixes - -Christian Schmitz (17 Apr 2024) - -- winbuild: add ENABLE_WEBSOCKETS option - - Closes #13232 - -Daniel Stenberg (17 Apr 2024) - -- dmaketgz: compacter - - Removes the need for disabling shellcheck warnings. - - Follow-up to d28f74913c2 - Proposed-by: Viktor Szakats - Closes #13391 - -Dan Fandrich (16 Apr 2024) - -- tests: Fix uninitialized value warning - - The check for an option must be predicated on options existing at all. - - Follow-up to f7cc9e91 - -Christian Schmitz (17 Apr 2024) - -- idn: add native AppleIDN (icucore) support for macOS/iOS - - I implemented the IDN functions for macOS and iOS using Unicode - libraries coming with macOS and iOS. - - Builds and runs here on macOS 14.2.1. Also verified to load and - run on older macOS version 10.13. - - Build requires macOS SDK 13 or equivalent. - - Set `-DUSE_APPLE_IDN=ON` CMake option to enable it. - With autotools and other build tools, set these manual options: - ``` - CPPFLAGS=-DUSE_APPLE_IDN - LIBS=-licucore - ``` - - Completes TODO 1.6. - - TODO: add autotools option and feature-detection. - - Refs: #5330 #5371 - Co-authored-by: Viktor Szakats - Closes #13246 - -Stefan Eissing (16 Apr 2024) - -- http3: extend download abort tests, fixes in ngtcp2 - - - fix flow handling in ngtcp2 to ACK data on streams - we abort ourself. - - extend test_02_23* cases to also run for h3 - - skip test_02_23* for OpenSSL QUIC as it gets stalled - on progressing the connection - - Closes #13374 - -Daniel Stenberg (16 Apr 2024) - -- tests: add -q as first option when invoking curl for tests - - To reduce the risk that the user running the tests has a .curlrc present - that messes things up. - - Support 'option="no-q"' for the tag to switch it off on demand. - Use this new feature in test 433 and 436. - - Ref: #13284 - Closes #13387 - -- dmaketgz: release tarball generation using docker - - For easier reproducibility. - - Mention using this script in RELEASE-PROCEDURE - - Closes #13388 - -Viktor Szakats (16 Apr 2024) - -- cmake: update ECH code and minor fixups - - - `openssl_check_symbol_exists()` expects a 4th argument now. - Follow-up to edc2702a1fe3a4a5386ffd9aa4f240f0c0197fa2 #13373 - - - minor comment/script touch-ups. - Follow-up to a362962b7289ec02b412890c9515657cf0ed50ac #11922 - - - fix indentation. - - Closes #13383 - -- tests: fix shellcheck issues in `ech_tests.sh` - - Add double-quotes where missing. - - Follow-up to a362962b7289ec02b412890c9515657cf0ed50ac #11922 - Closes #13382 - -- dist: add ECH files to tarball - - Also sort `EXTRA_DIST` list in `tests/Makefile.am` and make it diffable. - - Follow-up to a362962b7289ec02b412890c9515657cf0ed50ac #11922 - Closes #13381 - -- openvms: look for `USE_IPV6` in `config.h` (was: `ENABLE_IPV6`) - - The OpenVMS script `config_h.com` is parsing the config header - generated by autotools. Let's make it look for the macro name we now - use universally across the codebase. - - Follow-up to e411c98f702f0fb38dceec95e7507ef15a00d12c #13349 - Closes #13360 - -daniel-j-h (16 Apr 2024) - -- Dockerfile: for release automation and reproducibility - - Closes #13250 - -Stefan Eissing (16 Apr 2024) - -- cw-out: improved error handling - - - remember error encountered in invoking write callback and always fail - afterwards without further invokes - - - check behaviour in test_02_17 with h2-pausing client - - Reported-by: Pavel Kropachev - Fixes #13337 - Closes #13340 - -Daniel Stenberg (16 Apr 2024) - -- version: add "ECH" as a feature - - If available - - Follow-up to a362962b7 - Closes #13378 - -- CURLOPT_ECH: polish - - - remove the pointer to build instructions, it won't work in manpages - - add see-also - - minor white space edits - - Closes #13379 - -Viktor Szakats (16 Apr 2024) - -- tidy-up: whitespace [ci skip] - -- mbedtls: fix building with v3 in CMake Unity mode - - Before this patch the internal feature detection macro - `HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS` was defined in three files, - with an incomplete logic in one of them. In Unity mode that spilled - into another source file and broke the build. - - Closes #13377 - -- cmake: add librtmp/rtmpdump option and detection - - Add CMake option `USE_LIBRTMP`. Disabled by default. - - This library requires OpenSSL TLS-backend when linked statically. - - Follow-up to 6eb9e65781fa1fd8a0bcfe0715187a3a35f09ae4 #13364 - Closes #13373 - -Stephen Farrell (16 Apr 2024) - -- TLS: add support for ECH (Encrypted Client Hello) - - An EXPERIMENTAL feature used with CURLOPT_ECH and --ech. - - Closes #11922 - -Daniel Stenberg (15 Apr 2024) - -- RELEASE-NOTES: synced - -- multi: introduce SETUP state for better timeouts - - Since we can go to the CONNECT state from PENDING, potentially multiple - times for a single transfer, this change introdues a SETUP state that - happens before CONNECT when doing a new transfer. - - Now, doing a redirect on a handle goes back to SETUP (not CONNECT like - before) and we initilize the connect timeout etc in SETUP. Previously, - we would do it in CONNECT but that would make it unreliable in cases - where a transfer goes in and out between CONNECT and PENDING multiple - times. - - SETUP is transient, so the handle never actually stays in that state. - - Additionally: take care of timeouts of PENDING transfers in - curl_multi_perform() - - Ref: #13227 - Closes #13371 - -Tal Regev (15 Apr 2024) - -- cmake: forward `USE_LIBRTMP` option to C - - Define in C `USE_LIBRTMP` if user requested it from cmake. - - Closes #13364 - -Daniel Stenberg (15 Apr 2024) - -- curl_version_info: provide librtmp version - - Ref: https://github.com/curl/curl/pull/13364#issuecomment-2054151942 - Reported-by: talregev on github - Closes #13368 - -blankie (15 Apr 2024) - -- docs: clarify CURLOPT_MAXFILESIZE and CURLOPT_MAXFILESIZE_LARGE - - The bounds of the size parameter were not specified, and nor was it - specified how to disable the maximum file size check. - - The documentation also incorrectly stated that CURLOPT_MAXFILESIZE - always returns CURLE_OK and that CURLOPT_MAXFILESIZE_LARGE only returns - CURLE_OK or CURLE_UNKNOWN_OPTION. - - It also did not mention what the default value is, which is zero. This - commit updates the documentation to make note of all these things. - - Closes #13372 - -Patrick Monnerat (15 Apr 2024) - -- OS400: post-shellcheck changes adjustments - - Build scripts must be executed by the os/400 shell (sh), not bash which - is a PASE program. - - Shell function get_make_vars() escaping reworked to match $() subcommand - construct. - - Follow-up to 8a622baf9e9233241bbe93d6599c99cb46478614 - Closes #13366 - -Viktor Szakats (15 Apr 2024) - -- OS400: tidy-up - - Drop/fixup mods trying to make some syntax highlighters happier. - - Follow-up to 8a622baf9e9233241bbe93d6599c99cb46478614 #13309 - Closes #13362 - -Daniel Stenberg (15 Apr 2024) - -- multi: timeout handles even without connection - - When there is a "change" in a multi handle and pending handles are moved - back to the main list to be retested if they can proceed further (for - example a previous transfer completed or a connection has a confirmed - multiplexed state), the timeout check in multi_runsingle() would not - trigger because it required an established connection. - - This could make a pending tranfer go back to pending state even though - it had been "in progress" for a longer time than permitted. By removing - the requirement for an associated connection, the timeout check will be - done proper even for transfers that has not yet been assigned one. - - Ref #13227 - Reported-by: Rahul Krishna M - Closes #13276 - -Patrick Monnerat (15 Apr 2024) - -- mprintf: check fputc error rather than matching returned character - - OS/400 ascii fputc wrapper deviates from the posix standard by the - fact that it returns the ebcdic encoding of the original ascii - character. Testing for a matching value for success will then always - fail. - - This commit replaces the chariacter comparison by an explicit error - return check. - - Follow-up to ef2cf58 - Closes #13367 - -Viktor Szakats (14 Apr 2024) - -- ci: add CMake build variation, fixup libssh detection in `linux-old` - - To test without c-ares and hit `easy_lock.h` on an old system. Use this - new build step to introduce small variations, and also test libssh2. - - Also add workaround to existing job to enable libssh. (CMake's generic - auto-detection doesn't seem to work here.): - ``` - CMake Warning at CMakeLists.txt:908 (find_package): - Could not find a package configuration file provided by "libssh" with any - of the following names: - - libsshConfig.cmake - libssh-config.cmake - ``` - Ref: https://github.com/curl/curl/actions/runs/8661316091/job/23750974358#ste - p:5:69 - - Closes #13361 - -- lib: merge `ENABLE_QUIC` C macro into `USE_HTTP3` - - Before this patch `lib/curl_setup.h` defined these two macros right - next to each other, then the source code used them interchangeably. - - After this patch, `USE_HTTP3` guards all HTTP/3 / QUIC features. - (Like `USE_HTTP2` does for HTTP/2.) `ENABLE_QUIC` is no longer used. - - This patch doesn't change the way HTTP/3 is enabled via autotools - or CMake. Builders who enabled HTTP/3 manually by defining both of - these macros via `CPPFLAGS` can now delete `-DENABLE_QUIC`. - - Closes #13352 - -- build: prefer `USE_IPV6` macro internally (was: `ENABLE_IPV6`) - - Before this patch, two macros were used to guard IPv6 features in curl - sources: `ENABLE_IPV6` and `USE_IPV6`. This patch makes the source use - the latter for consistency with other similar switches. - - `-DENABLE_IPV6` remains accepted for compatibility as a synonym for - `-DUSE_IPV6`, when passed to the compiler. - - `ENABLE_IPV6` also remains the name of the CMake and `Makefile.vc` - options to control this feature. - - Closes #13349 - -Dan Fandrich (12 Apr 2024) - -- DISTROS: mark rolling release distros - - These are ones that are unlikely to have back-ported curl patches. - - Closes #13353 - -Daniel Stenberg (12 Apr 2024) - -- mbedtls: cut off trailing newlines from debug logs - - To avoid double newlines in the output. - - Reported-by: Gisle Vanem - Fixes #13321 - Closes #13356 - -- RELEASE-NOTES: synced - -Stefan Eissing (12 Apr 2024) - -- CURLINFO_REQUEST_SIZE: fixed, add tests for transfer infos reported - - - tests for 'size_request' and other stats reported, for - presence and consistency - - Reported-by: Jonatan Vela - Fixes #13269 - Closes #13275 - -Viktor Szakats (11 Apr 2024) - -- dist: add files missing from release tarball - - Closes #13346 - -- ci: parallelize more, tidy up cmake commands (distcheck, macos) - - Also enable `-DCURL_WERROR=ON` in the Linux cmake build test. - - Closes #13343 - -Toon Claes (11 Apr 2024) - -- docs: add CURLOPT_NOPROGRESS to CURLOPT_XFERINFOFUNCTION example - - It's important to set `CURLOPT_NOPROGRESS` to `0` if you want your - transfer callback function, set by `CURLOPT_XFERINFOFUNCTION`, getting - called. To emphasize this to the users, add this to the code example. - - Closes #13348 - -RainRat (11 Apr 2024) - -- misc: fix typos - - Closes #13344 - -Colin Leroy-Mira (11 Apr 2024) - -- file: add support for getting basic directory listings - - Not supported on Windows (yet) - - Closes #13137 - -Viktor Szakats (11 Apr 2024) - -- ci: add curl-for-win builds: Linux MUSL, macOS, Windows - - Linux MUSL (llvm/clang), macOS Apple clang, Windows (llvm/clang). - - Configured with HTTP/2 and HTTP/3 and other dependencies (the default - curl-for-win) for a comprehensive build test. - - ``` - curl 8.8.0-DEV (x86_64-unknown-linux-musl) libcurl/8.8.0-DEV LibreSSL/3.9.1 z - lib/1.3.1 brotli/1.1.0 zstd/1.5.6 libpsl/0.21.5 libssh2/1.11.0 nghttp2/1.61.0 - ngtcp2/1.4.0 nghttp3/1.2.0 - Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns - mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss - Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefil - e libz NTLM PSL SSL threadsafe UnixSockets zstd - - curl 8.8.0-DEV (x86_64-apple-darwin) libcurl/8.8.0-DEV LibreSSL/3.9.1 zlib/1. - 3.1 brotli/1.1.0 zstd/1.5.6 libpsl/0.21.5 libssh2/1.11.0 nghttp2/1.61.0 ngtcp - 2/1.4.0 nghttp3/1.2.0 - Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns - ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws w - ss - Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefil - e libz NTLM PSL SSL threadsafe UnixSockets zstd - - curl 8.8.0-DEV (x86_64-w64-mingw32) libcurl/8.8.0-DEV LibreSSL/3.9.1 zlib/1.3 - .1 brotli/1.1.0 zstd/1.5.6 WinIDN libpsl/0.21.5 libssh2/1.11.0 nghttp2/1.61.0 - ngtcp2/1.4.0 nghttp3/1.2.0 - Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns - ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws w - ss - Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerb - eros Largefile libz NTLM PSL SPNEGO SSL SSPI threadsafe UnixSockets zstd - ``` - - Limited to x64, because for build testing the additional CPUs don't add - much value compared to the extra build time. They can be enabled easily - if deemed useful. - - To the extent of curl-for-win configuration options, it's trivial to add - further build combinations. - - Closes #13335 - -- OS400: fix shellcheck warnings in scripts - - - use `$()` instead of backticks, and re-arrange double-quotes inside. - - add missing `|| exit 1` to `cd` calls. (could be dropped by using `set -eu` - .) - - add `-n` to a few `if`s. - - shorten redirections by using `{} >` (as shellcheck recommended). - - silence warnings where variables were detected as unused (SC2034). - - a couple misc updates to silence warnings. - - switch to bash shebang for `-ot` feature. - - split two lines to unbreak syntax highlighting in my editor. (`$(expr \`, ` - $(dirname \`) - - Also enable CI checks for OS/400 shell scripts. - - Ref: #13307 - Closes #13309 - -Stefan Eissing (11 Apr 2024) - -- lib: add Curl_xfer_write_resp_hd - - Add method in protocol handlers to allow writing of a single, - 0-terminated header line. Avoids parsing and copying these lines. - - Closes #13165 - -- llist: add Curl_llist_append() - - - use for better readability in all places where the "insert_next" - actually performs an append to the list - - add some tests in unit1300 - - Closes #13336 - -- gnutls: lazy init the trust settings - - - delay loading of trust anchors and CRLs after the ClientHello - has been sent off - - add tracing to IO operations - - on IO errors, return the CURLcode of the underlying filter - - Closes #13339 - -Marcel Raad (10 Apr 2024) - -- http_negotiate: fix `CURL_DISABLE_PROXY` build - - `proxyuserpwd` was removed from `dynamically_allocated_data` in commit - f46385d36df. - - Closes https://github.com/curl/curl/pull/13334 - -Viktor Szakats (10 Apr 2024) - -- quic: fixup duplicate static function name (for cmake unity) - - Visible in daily curl-for-win builds: - https://github.com/curl/curl-for-win/actions/runs/8621925870 - - ``` - lib/vquic/curl_ngtcp2.c:1916:12: error: redefinition of 'ossl_new_session_cb' - static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) - ^ - lib/vtls/openssl.c:2978:12: note: previous definition is here - static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) - ^ - ``` - https://github.com/curl/curl-for-win/actions/runs/8621925870/job/23631885439# - step:3:6965 - - Follow-up to 3210101088dfa3d6a125d213226b092f2f866722 #13172 - Closes #13332 - -- appveyor: make VS2010 job build-only, enable Schannel, fix compiler warnings - - Tests were consistently flaky for a while. - - Also fix compiler warnings in `CertOpenStore()` calls for old MSVC compilers: - ``` - C:/projects/curl/lib/vtls/schannel.c(688): - warning C4306: 'type cast' : conversion from 'int' to 'LPCSTR' of greater s - ize - C:/projects/curl/lib/vtls/schannel_verify.c(642): - warning C4306: 'type cast' : conversion from 'int' to 'LPCSTR' of greater s - ize - ``` - Ref: https://ci.appveyor.com/project/curlorg/curl/builds/49580310/job/ywu2y44 - kymgc0nif#L106 - - Closes #13330 - -Daniel Stenberg (10 Apr 2024) - -- projects: drop MSVC project files for recent versions - - We encourage users to generate visual studio project files using CMake. - - We keep project files in git for ancient visual studio versions that - cmake cannot generate files for, but we no longer ship the project files - in the tarballs. - - appveyor: switch VisualStudioSolution job to VC12 (Visual Studio 2013) - - Co-Authored-by: Viktor Szakats - Co-Authored-by: Jay Satiro - - Closes #13311 - -Viktor Szakats (9 Apr 2024) - -- cmake: use namespaced custom target names - - Rename custom target to namespaced (unique) names to avoid colliding - with 3rd-party projects (e.g. libzip) built together with curl. - - Reported-by: hammlee96 on github - Fixes #13324 - Closes #13326 - -- appveyor: re-enable OpenSSL 3, bump to 3.2.1 - - Ref: b62454a875d70f93ab5347c050903596feb45a23 #13266 - Closes #13329 - -Stefan Eissing (9 Apr 2024) - -- CI: upgrade openssl version to 3.3.0 for openssl-quic - - Closes #13328 - -Daniel Stenberg (9 Apr 2024) - -- RELEASE-NOTES: synced - - Bump to 8.8.0-DEV - -- curl_multi_waitfds.md: add protocol mention - - Follow-up to 02beac6bb6b - -Dmitry Karpov (9 Apr 2024) - -- lib: add curl_multi_waitfds - - New function call, similar to curl_multi_fdset() - - Closes #13135 - -Viktor Szakats (9 Apr 2024) - -- dist: verify tarball reproducibility in CI - - Closes #13327 - -Stefan Eissing (9 Apr 2024) - -- tests: stabilitze test_02_23* - - - h2-download now always opens the output file on first write callback - invocation, if it will pause the transfer or not. - - Checks on output files then does not depend on the amount of data curl - has collected for the first write. - - Closes #13323 - -- tls: fix compile issues on old-linux CI - - Follow-up to 3210101088dfa - Closes #13325 - -Viktor Szakats (9 Apr 2024) - -- dist: add reproducible dir entries to tarballs - - In the initial implementation of reproducible tarballs, they were - missing directory entries, while .zip archives had them. It meant - that on extracting the tarball, on-disk directory entries got the - current timestamp. - - This patch fixes this by including directory entries in the tarball, - with reproducible timestamps. It also moves sorting inside tar, - to ensure reproducible directory entry timestamps on extract - (without the need of `--delay-directory-restore` option, when - extracting with GNU tar. BSD tar got that right by default.) - - GNU tar 1.28 (2014-07-28) introduced `--sort=`. - - Ref: https://github.com/curl/curl/pull/13299#discussion_r1555957350 - Follow-up to 860cd5fc2dc8e165fadd2c19a9b7c73b3ae5069d #13299 - Closes #13322 - -Stefan Eissing (9 Apr 2024) - -- tls: use shared init code for TCP+QUIC - - Closes #13172 - -Daniel Stenberg (9 Apr 2024) - -- .mailmap: update Gisle's preferred email - -Jan Macku (9 Apr 2024) - -- doc: pytest `--repeat` -> `--count` - - Pytest doesn't have a `--repeat` option, but it does have a `--count` - option. - - ``` - --count=COUNT Number of times to repeat each test - ``` - - Closes #13218 - -Daniel Stenberg (9 Apr 2024) - -- src/Makefile.am: access curl.txt using a relative path, not abs - - ... to make it work when mounted using different mount points. Like when - generated/used inside and outside of a docker image. - - Closes #13320 - -- build: remove MacOSX-Framework script - - I don't think this is much used these days. - - Also remove the libcurl.plist file used (only) by this script - - Closes #13313 - -- release-tools.sh: store the timestamp and release tag too - - When maketgz invokes this script to generate the docs/RELEASE-TOOLS.md - file that gets bundled in the release, it now also passes on the exact - timestamp and version number so that those details also get mentioned in - the document. They will help users reproduce an identical tarball. - - Closes #13319 - -Viktor Szakats (8 Apr 2024) - -- GHA: disable permissions where missing - - Reviewed-by: Daniel Stenberg - Closes #13306 - -Stefan Eissing (8 Apr 2024) - -- CI: update component versions - - - ngtcp2: v1.4.0 - - nghttp3: v1.2.0 - - nghttp2: v1.61.0 - - mod_h2: v2.0.27 - - Closes #13316 - -Jérôme Leclercq (8 Apr 2024) - -- CMake: check fseeko after detecting HAVE_FILE_OFFSET_BITS - - Closes #13264 - -Stefan Eissing (8 Apr 2024) - -- http2: emit RST when client write fails - - - When the writing of response data fails, reset the stream - and do not return a callback error to nghttp2. That would - be a fatal error for the connection and harm other requests. - - add test cases for various abort scenarios - - Reported-by: Konstantin Kuzov - Fixes #13292 - Closes #13298 - -Kailun Qin (8 Apr 2024) - -- mbedtls: call mbedtls_ssl_setup() after RNG callback is set - - Since mbedTLS v3.6.0, the RNG check added in ssl_conf_check() will fail - if no RNG is provided when calling mbedtls_ssl_setup(). - - Therefore, mbedtls_ssl_conf_rng() needs to be called before the SSL - context is passed to mbedtls_ssl_setup(). - - Ref: https://github.com/Mbed-TLS/mbedtls/commit/b422cab052b51ec84758638d6783d - 6ba4fc60613 - - Signed-off-by: Kailun Qin - Closes #13314 - -Daniel Stenberg (8 Apr 2024) - -- NTLM_WB: drop support - - The feature has not worked for months and has been marked as DEPRECATED - for six+ months. - - Closes #13249 - -- curl_trc: fix build error when lacking verbose messages - - Follow-up from 0b28ece657b2273 - Closes #13312 - -Viktor Szakats (8 Apr 2024) - -- contrithanks: honor `CURLWWW` variable - - Reviewed-by: Daniel Stenberg - Closes #13315 - -- GHA: add shellcheck job and fix warnings, shell tidy-ups - - Reviewed-by: Daniel Stenberg - Closes #13307 - -- dist: do not require Perl in `maketgz` - - Perl remains required for the tarball build process. - - Follow-up to 860cd5fc2dc8e165fadd2c19a9b7c73b3ae5069d #13299 - - Reviewed-by: Daniel Stenberg - Closes #13310 - -Daniel Stenberg (8 Apr 2024) - -- RELEASE-NOTES: synced - -- docs/cmdline-opts: invoke managen using a relative path - - ... no need to use an absolute path, that makes the build unncessarily - fail if invoked using a different mount point. managen now takes options - to find the input files. - - Update test1478 to provide the dir arguments to managen - - Closes #13281 - -- GHA: add valgrind to a wolfSSL build - - Closes #13274 - -Viktor Szakats (7 Apr 2024) - -- dist: `set -eu`, fix shellcheck, make reproducible and smaller tarballs - - - set bash `-eu` and fix fallouts. - - fix shellcheck warnings. - - set and use `SOURCE_DATE_EPOCH` for reproducibility. - Authored-by: Daniel J. H. - Ref: #13280 - - set `TZ=UTC` and `LC_ALL=C` for reproducibility. - - make file timestamps in tarball/zip reproducible. - - make directory timestamps in zip reproducible. - - make timestamps of tarballs/zip reproducible. - - make file order in tarball/zip reproducible. - - omit extra file metadata from zip for reproducibility. - - use maximum zip compression. - - use POSIX `ustar` tarball format to avoid supply chain vulnerability: - https://seclists.org/oss-sec/2021/q4/0 - - make uid/gid in tarball reproducible. - - omit owner user/group names from tarball for reproducibility and privacy. - - omit current timestamp from .gz header for reproducibility. - - display SHA-256 hashes of produced tarballs/zip. - - fix whitespace. - - `.tar.gz` also became smaller in the process: 4,462,311 -> 4,148,249 bytes (8 - .7.1) - - Requires GNU tar, GNU date, `sha256sum`. - - Reviewed-by: Daniel Stenberg - Ref: #13250 - Closes #13299 - -Gisle Vanem (7 Apr 2024) - -- tests/http: fix compiler warning - - - Init result code variable to fix clang warning that it may be used - uninitialized. - - Fixes https://github.com/curl/curl/issues/13301 - Closes https://github.com/curl/curl/pull/13304 - -Stefan Eissing (6 Apr 2024) - -- vquic: use new curl_int64_t type - - - add curl_int64_t signed 64-bit type for lib use - - - define CURL_PRId64, CURL_PRIu64 format ids - - - use curl_int64_t in vquic - - curl_int64_t signed complements the existing curl_uint64_t unsigned. - - Note that `curl_int64_t` and `int64_t` are assignable from each other - but not identical. Some platforms with 64 long type defint int64_t as - "long long" (staring at macOS) which messes up things like pointers and - format identifiers. - - Closes https://github.com/curl/curl/pull/13293 - -Jay Satiro (5 Apr 2024) - -- lib: use multi instead of multi_easy for the active multi - - - Use data->multi and not data->multi_easy to refer to the active multi. - - The easy handle's active multi is always data->multi. - - This is a follow up to 757dfdf which changed curl so that an easy handle - used with the easy interface and then multi interface cannot have two - different multi handles associated with it at the same time - (data->multi_easy from the easy interface and data->multi from the multi - interface). - - Closes https://github.com/curl/curl/pull/12665 - -Viktor Szakats (5 Apr 2024) - -- tidy-up: whitespace [ci skip] - -Daniel Stenberg (5 Apr 2024) - -- makefile: remove the sorting from the vc-ide action - - This target generates the MSVC project files. This change removes the - extra sorting and instead makes the script use the order of the files as - listed in the variables - which are mostly sorted anyway. - - This is an attempt to make the project file generation more easily - reproducible. - - Ref: #13250 - Closes #13294 - -Gisle Vanem (5 Apr 2024) - -- bearssl: fix compiler warnings - - "variables may be uninitialized when used" - - Fixes #13290 - Closes #13297 - -Daniel Stenberg (5 Apr 2024) - -- DISTROS: Cygwin updates - - Brought-by: Brian Inglis - Fixes #13258 - Co-authored-by: Viktor Szakats - Closes #13279 - -Stefan Eissing (5 Apr 2024) - -- lib: add trace support for client reads and writes - - - add `CURL_TRC_READ()` and `CURL_TRC_WRITE()` - - use in generic client writers and readers, as well - as http headers, chunking and websockets - - Closes #13223 - -Michał Antoniak (5 Apr 2024) - -- urldata: remove fields not used depending on used features - - Reduced size of dynamically_allocated_data structure. - - Reduced number of stored values in enum dupstring and enum dupblob. This - affects the reduced array placed in the UserDefined structure. - - Closes #13188 - -Viktor Szakats (5 Apr 2024) - -- cmake: enable `-pedantic-errors` for clang when `CURL_WERROR=ON` - - clang doesn't have the issues of GCC and old CMake versions. - - Note: This introduces asymmetry with autotools, which only enables - this for GCC. - - Reviewed-by: Daniel Stenberg - Closes #13286 - -- cmake: fix `CURL_WERROR=ON` for old CMake and use it in GHA/linux-old - - - cmake: fix `-pedantic-errors` for old CMake with `CURL_WERROR=ON` set. - - `-pedantic-errors` option throws a warning with GCC (all versions) and - makes `check_symbol_exists()` fail in CMake versions older than - v3.23.0 (2022-03-29), when CMake introduced a workaround: - - https://gitlab.kitware.com/cmake/cmake/-/issues/13208 - https://gitlab.kitware.com/cmake/cmake/-/commit/eeb45401163d831b8c841ef6eba - 81466b4067b68 - https://gitlab.kitware.com/cmake/cmake/-/commit/1ab7c3cd28b27ca162c4559e102 - 6e5cad1898ade - - Follow-up to 3829759bd042c03225ae862062560f568ba1a231 #12489 - - - set `CURL_WERROR=ON` for the `linux-old` job in CI. - - Closes #13282 - -- lib: use `#error` instead of invalid syntax in `curl_setup_once.h` - - Reviewed-by: Daniel Stenberg - Closes #13287 - -Daniel Stenberg (5 Apr 2024) - -- GHA: on macOS remove $HOME/.curlrc - - A recent image upgrade added a $HOME/.curlrc by default using --ipv4. - - Ref: https://github.com/actions/runner-images/pull/9586 - Fixes #13284 - Closes #13285 - -Viktor Szakats (4 Apr 2024) - -- cmake: fixup `DEPENDS` filename - - Fixing: - ``` - make[2]: Circular docs/curl-config.1 <- docs/curl-config.1 dependency dropped - . - make[2]: Circular docs/mk-ca-bundle.1 <- docs/mk-ca-bundle.1 dependency dropp - ed. - ``` - Ref: https://github.com/curl/curl/actions/runs/8559617487/job/23456740844?pr= - 13282#step:6:18 - - Follow-up to 5023ffad2c27d4b916ddb91800f99ecc5d3aad07 #13197 - Closes #13283 - -- GHA: enable unity mode for cmake jobs + tidy-ups - - Unity mode is not supported by CMake v3.7.2 used in linux-old, but - enable it anyway for consistency and to kick in automatically once - migrating to a newer old Linux in the future. - - Also: - - replace `CMAKE_COMPILE_WARNING_AS_ERROR` with `CURL_WERROR`. - - delete default build option `PICKY_COMPILER=ON`. - - Closes #13277 - -Dan Fandrich (4 Apr 2024) - -- CI: Add CI build on Debian stretch to test old support - - This version still has ELTS support and contains some old versions of - key components like cmake to help prevent us from breaking that support. - - Closes #13029 - -Stefan Eissing (4 Apr 2024) - -- request: paused upload on completed download, assess connection - - A transfer with a completed download that is still uploading needs to - check the connection state when it is PAUSEd, since connection - close/errors would otherwise go unnoticed. - - Reported-by: Sergey Bronnikov - Fixes #13260 - Closes #13271 - -Daniel Stenberg (4 Apr 2024) - -- url: do not URL decode proxy crendentials - - The two options CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD set the - actual names as-is, not URL encoded. - - Modified test 503 to use percent-encoded strings in the credential - strings that should be passed on as-is. - - Reported-by: Sergey Ogryzkov - Fixes #13265 - Closes #13270 - -Viktor Szakats (4 Apr 2024) - -- appveyor: enable cmake unity mode by default - - Leave one non-unity cmake job. This makes the jobs finish slightly - quicker, while giving more coverage for unity issues. - - Before: - https://ci.appveyor.com/project/curlorg/curl/builds/49496977 - https://ci.appveyor.com/project/curlorg/curl/builds/49500372 - After: - https://ci.appveyor.com/project/curlorg/curl/builds/49500338 - - Also fixup unrelated whitespace. - - Reviewed-by: Daniel Stenberg - Closes #13217 - -Daniel Stenberg (4 Apr 2024) - -- RELEASE-NOTES: synced - -Viktor Szakats (4 Apr 2024) - -- cmake: speed up libcurl doc building again - - This time limit the number of files per command to avoid exceeding - limitations of certain OS/shell envs. - - Such known env is Windows with the `cmd.exe` shell, which features an - 8K command-line length limit to this day. - - Allowlisting `UNIX` to have no limit and using a limit of 200 for other - envs to be safe. If there is a way to detect `cmd.exe` and/or we know - which precise envs are sensitive to this, we can tweak these conditions - further. - - Even with the low limit, this patch reduces external commands by 200x, - making builds much faster. - - Ref: #12762 2620aa930bc73af1e4c70b10e3125b957b96ecfb (initial) - Ref: #13047 f03c85635f35269f1f45b983bf216624f541760a (revert) - - Reviewed-by: Daniel Stenberg - Closes #13207 - -- cmake: tidy-up to use `WORKING_DIRECTORY` - - Reviewed-by: Daniel Stenberg - Closes #13206 - -- cmake: generate misc manpages and install `mk-ca-bundle.pl` - - - install `mk-ca-bundle.pl` like autotools does. - - - generate and install `mk-ca-bundle.1` and `curl-config.1` like - autotools. This fixes tests 1140 and 1173. - - Reported-by: Dan Fandrich - Fixes #13194 - - - add option `BUILD_MISC_DOCS` to control building the above two - manpages. Enabled by default. - - - appveyor: stop disabling tests 1140 and 1173. - - Reviewed-by: Daniel Stenberg - Closes #13197 - -Fabian Keil (4 Apr 2024) - -- wolfssl: plug memory leak in wolfssl_connect_step2() - - Fixes: - - test 2034...[simple HTTPS GET with DER public key pinning] - ==61829== 22,610 (3,744 direct, 18,866 indirect) bytes in 1 blocks are d - efinitely lost in loss record 51 of 54 - ==61829== at 0x484BB74: malloc (vg_replace_malloc.c:446) - ==61829== by 0x4B53A80: wolfSSL_Malloc (memory.c:344) - ==61829== by 0x4C1C8E1: wolfSSL_X509_new (x509.c:5326) - ==61829== by 0x4C3977D: d2i_X509orX509REQ (x509.c:3628) - ==61829== by 0x4C1D1F4: wolfSSL_X509_d2i (x509.c:3664) - ==61829== by 0x4C1C37B: wolfSSL_X509_dup (x509.c:13425) - ==61829== by 0x4C197DB: wolfSSL_get_peer_certificate (ssl.c:18765) - ==61829== by 0x33297C: wolfssl_connect_step2 (wolfssl.c:875) - ==61829== by 0x331669: wolfssl_connect_common (wolfssl.c:1287) - ==61829== by 0x3303E9: wolfssl_connect_nonblocking (wolfssl.c:1319) - ==61829== by 0x32FE89: ssl_connect_nonblocking (vtls.c:510) - ==61829== by 0x32DBE5: ssl_cf_connect (vtls.c:1679) - ==61829== by 0x27ABD7: Curl_conn_cf_connect (cfilters.c:307) - ==61829== by 0x27D9CF: cf_setup_connect (connect.c:1199) - ==61829== by 0x27ABD7: Curl_conn_cf_connect (cfilters.c:307) - ==61829== by 0x283CEA: cf_hc_baller_connect (cf-https-connect.c:135) - - Closes #13272 - -Viktor Szakats (3 Apr 2024) - -- appveyor: OpenSSL 3 no longer found by CMake, revert to 1.1.1 - - OpenSSL moved directories, and bumped versions in AppVeyor CI. - - Downgrading is not an ideal solution, but however trivial the solution - may be, I failed to come with anything that made CMake recognize either - OpenSSL 3.1 or 3.2. - - Possibly caused by: - https://github.com/appveyor/build-images/commit/702e8cdca01f28f6a40687783f493 - c786cebbe2c - https://github.com/appveyor/build-images/pull/149 - - Closes #13266 - -hongfei.li (3 Apr 2024) - -- winbuild: use $(RC) correctly - - Cloes #13267 - -Daniel Stenberg (3 Apr 2024) - -- dist: remove the curl-config.1 from the tarball - - The markdown file is already there and the .1 file gets generated in the - build. - - Ref: #13250 - Closes #13268 - -- curl_global_trace.md: shorten the description - - Closes #13263 - -- test1901: verify chunked POST from callback with CURLOPT_POSTFIELDSIZE set - - Follow-up to 721941aadf4ad - - Ref: #13257 - Closes #13262 - -Stefan Eissing (2 Apr 2024) - -- http: with chunked POST forced, disable length check on read callback - - - when an application forces HTTP/1.1 chunked transfer encoding - by setting the corresponding header and instructs curl to use - the CURLOPT_READFUNCTION, disregard any POST length information. - - this establishes backward compatibility with previous curl versions - - Applications are encouraged to not force "chunked", but rather - set length information for a POST. By setting -1, curl will - auto-select chunked on HTTP/1.1 and work properly on other HTTP - versions. - - Reported-by: Jeff King - Fixes #13229 - Closes #13257 - -Jay Satiro (1 Apr 2024) - -- INSTALL-CMAKE.md: explain `cmake -G ` - - - Explain that CMake's -G option can be used to specify which build - system to generate files for. - - Example: cmake ../curl -G "MinGW Makefiles" - - Ref: https://github.com/curl/curl/pull/12224#issuecomment-2026813645 - - Closes https://github.com/curl/curl/pull/13244 - -Daniel Stenberg (1 Apr 2024) - -- libcurl-opts: mention pipelining less - - libcurl has not supported HTTP pipelining since many years. Remove a few - (more) mentions of the feature. - - Closes #13254 - -Daniel McCarney (31 Mar 2024) - -- m4: reposition USE_RUSTLS="yes" for pkg-config - - It's necessary to set this var to "yes" _after_ AC_DEFINE and AC_SUBST - in order for a later `test` to pass so that `check_for_ca_bundle=1` ends - up being set. This is in turn required for the default CA certificate - bundle to be set when building w/ rustls & pkg-config. - - Reported-by: Matt Jolly - Fixes #13248 - Closes #13251 - -Daniel Stenberg (31 Mar 2024) - -- maketgz: put docs/RELEASE-TOOL.md into the tarball - - Generated with scripts/release-tools.sh - - The script lists the exact Debian package names and version numbers for - the tools that are used to generate the tarball. - - Closes #13239 - -- cd2nroff/manage: use UTC when SOURCE_DATE_EPOCH is set - - Make them independent of the TZ setting. Also set a date string like - YYYY-MM-DD to avoid a local month name in the date. - - Reported-by: Carlos Henrique Lima Melara - Fixes #13242 - Closes #13243 - -- RELEASE-NOTES: synced - -- docs/MAIL-ETIQUETTE: convert to markdown - - To render nicer. To get spellchecked. - - Closes #13247 - -- reuse: add copyright + license info to individual docs/*.md files - - Instead of use 'docs/*.md' in dep5. For clarity and avoiding a wide- - matching wildcard. - - + Remove mention of old files from .reuse/dep5 - + add info to .github/dependabot.yml - + make scripts/copyright.pl warn on non-matching patterns - - Closes #13245 - -- test470: warn about unicode quote character read from config file - - Idea-by: Emanuele Torre - -- test469: verify warning when argument has unicode quote - -- tool_getparam: output warning for leading unicode quote character - - ... in the option argument. - - Typically this is a mistake done when copying example command lines from - online documentation using the wrong quote character. - - Presumably there are also other potential quote characters that might be - used, and this check is done without even knowing that unicode is used! - - Reported-by: Sanjay Pujare - Fixes #13214 - Closes #13215 - -- tool: follow-up getenv fix - - Remove a double free. Change the IPFS env use to a plain getenv() simply - because coverity gets confused. - - Follow-up to 9126b141c9398fe - Closes #13241 - -- idn: make Curl_idnconvert_hostname() use Curl_idn_decode() - - In the name of less code duplication - - Closes #13236 - -- curl-confopts.m4: define CARES_NO_DEPRECATED when c-ares is used - - Starting in 1.28.0 c-ares added deprecation warnings for some API calls - libcurl uses. - - Closes #13240 - -- vquic: use CURL_FORMAT_CURL_OFF_T for 64 bit printf output - - Reported-by: Keitagit-kun on github - Fixes #13224 - Closes #13231 - -- openldap: create ldap URLs correctly for IPv6 addresses - - Reported-by: Sergio Durigan Junior - Fixes #13228 - Closes #13235 - -- curl: use curl_getenv instead of the curlx_ version - - The curlx one was once introduced when we still considered dropping the - libcurl function at some point. To reduce confusion and to make it - easier to understand when curl_free() should be used, use the actual - libcurl function call directly instead. - - Closes #13230 - -Evgeny Grin (Karlson2k) (30 Mar 2024) - -- curl_sha512_256: do not use workaround for NetBSD when not needed - - Assisted-by: riastradh on github - Assisted-by: Michael Kaufmann - Closes #13225 - -Matt Jolly (30 Mar 2024) - -- m4: fix rustls pkg-config codepath - - The previous pkg-config code would successfully detect rustls but did - not set all appropriate variables and call the right macros to properly - configure cURL. - - Reported-by: kpcyrd on github - Fixes #13200 - Closes #13202 - -Daniel McCarney (30 Mar 2024) - -- deps: update librustls 0.12.0 -> 0.13.0 - - This commit updates the optional rustls-ffi librustls dependency from - 0.12.0 to 0.13.0. This version is based on the latest available rustls - release (0.23.4). - - The breaking API changes from 0.12.0 to 0.13.0 are in API surface unused - by curl, so this is an in-place update without any code changes. - - The `RUSTLS.md` documentation is updated to reflect the new version in - use, and to clarify that `cbindgen` isn't required to build `librustls` - - it's only used by developers to update the vendored `rustls.h` header - file maintained upstream. - - Closes #13238 - -Daniel Stenberg (28 Mar 2024) - -- RELEASE-NOTES: synced - -- tool_xattr: "guess" URL scheme if none is provided - - ... when figuring out the source URL to store. - - Reported-by: Dagfinn Ilmari Mannsåker - Fixes #13205 - Closes #13221 - -- tool_xattr: in debug builds, act normally if CURL_FAKE_XATTR is not set - - Closes #13220 - -Stefan Eissing (28 Mar 2024) - -- content_encoding: brotli and others, pass through 0-length writes - - - curl's transfer handling may write 0-length chunks at the end of the - download with an EOS flag. (HTTP/2 does this commonly) - - - content encoders need to pass-through such a write and not count this - as error in case they are finished decoding - - Fixes #13209 - Fixes #13212 - Closes #13219 - -Tobias Stoeckmann (28 Mar 2024) - -- libssh2: set length to 0 if strdup failed - - Internally, libssh2 dereferences the NULL pointer if length is non-zero. - The callback function cannot return the error condition, so at least - prevent subsequent crash. - - Closes #13213 - -Daniel Stenberg (28 Mar 2024) - -- RELEASE-PROCEDURE: mention an initial working build - - This is the step that was not done and caused the 8.7.0 mishap (it - lacked the correctly generated hugehelp file). - - Remove the mention of the copyright script as this is verified by a CI - job these days: the REUSE one. - - Closes #13216 - -Paul Howarth (28 Mar 2024) - -- curl_sha512_255: fix detection of OpenSSL 1.1.1 or later - - Use the same OPENSSL_VERSION_NUMBER comparison as in lib/vtls/openssl.c. - - Closes #13208 - -Robert Moreton (28 Mar 2024) - -- cf-socket: remove references to l_ip, l_port - - Fixes #13210 - Closes #13211 - -Daniel Stenberg (28 Mar 2024) - -- openssl: do not set SSL_MODE_RELEASE_BUFFERS - - While it might save some memory, it causes OpenSSL to instead do a huge - amount of allocations. - - Ref: #13136 - Closes #13203 - -- curl: make --help adapt to the terminal width - - Instead of assuming and working with 80 colums, try figuring out what - width is actually used. - - Ref: #13141 - - Closes #13171 - -- RELEASE-NOTES: synced - - and bump to 8.7.2 for now - -- configure: make --disable-docs imply --disable-manual - - Because when the docs is not built, the necesary curl.txt file is not - present so then the manual cannot get built. - - Reported-by: Harry Sintonen - Closes #13191 - -Chris Webb (27 Mar 2024) - -- cmdline-docs: fix make install with configure --disable-docs - - make -C docs/cmdline-opts install depends on all-am, which in turn - depends on $(MANS), unconditionally defined to be $(man_MANS). - - As with CLEANFILES, only add curl.1 to man_MANS when BUILD_DOCS is true - so we don't try to build curl.1 unnecessarily. - - Closes #13198 - -Version 8.7.1 (27 Mar 2024) - -Daniel Stenberg (27 Mar 2024) - -- RELEASE-PROCEDURE: remove old release dates, add new pending ones - -Version 8.7.0 (27 Mar 2024) - -Daniel Stenberg (27 Mar 2024) - -- RELEASE-NOTES: synced - - curl 8.7.0 release - -- THANKS: new contributors from the 8.7.0 release - -- CURLOPT_POSTFIELDS.md: used for MQTT as well - - Closes #13189 - -- http: remove stale comment about rewindbeforesend - - ... because that struct field exists no more. - - Follow-up to 14bcea074a782272. - - Closes #13187 - -- DISTROS: add document with distro pointers - - Lots of organizations distribute curl packages to end users. This is a - collection of pointers to where to learn more about curl on and with - each distro. - - Assisted-by: Alan Coopersmith - Assisted-by: Andrew Kaster - Assisted-by: Andy Fiddaman - Assisted-by: Arjan van de Ven - Assisted-by: Brian Clemens - Assisted-by: chrysos349 on github - Assisted-by: Dan Fandrich - Assisted-by: Dan McDonald - Assisted-by: Gaelan Steele - Assisted-by: graywolf on github - Assisted-by: Jan Macku - Assisted-by: John Marshall - Assisted-by: Jonathan Perkin - Assisted-by: Kevin Daudt - Assisted-by: Marcus Müller - Assisted-by: Michał Górny - Assisted-by: Outvi V - Assisted-by: Ross Burton - Assisted-by: Sean Molenaar - Assisted-by: Till Wegmüller - Assisted-by: Viktor Szakats - Assisted-by: Winni Neessen - - Closes #13178 - -Fabian Keil (25 Mar 2024) - -- wolfSSL: do not call the stub function wolfSSL_BIO_set_init() - - Calling the function isn't necessary and causes the build - to fail when wolfSSL has been compiled with NO_WOLFSSL_STUB: - - Making all in opts - CCLD curl - ld: error: undefined symbol: wolfSSL_BIO_set_init - >>> referenced by wolfssl.c:235 (vtls/wolfssl.c:235) - >>> libcurl_la-wolfssl.o:(wolfssl_bio_cf_create) in archiv - e ../lib/.libs/libcurl.a - cc: error: linker command failed with exit code 1 (use -v to see invocat - ion) - *** Error code 1 - - Closes #13164 - -Daniel Stenberg (25 Mar 2024) - -- cmdline-opts: shorter help texts - - In an effort to increase the readability of the "--help all" output on - narrow (80 column) terminals. - - Co-authored-by: Jay Satiro - - Closes #13169 - -Matt Jolly (25 Mar 2024) - -- curl-rustls.m4: add pkg-config support to rustls detection - - Based on the existing openssl pkg-config detection, this commit tries to - use pkg-config to find `rustls` then falls back to the current approach - if that fails. - - We use the following logic: - - - if no path is provided, just use pkg-config, if it's not there we have - a problem! - - if a path is provided, try pkg-config - + if pkg-config fails, try and find rustls directly - - Closes #13179 - -Mohammadreza Hendiani (25 Mar 2024) - -- TODO: update 13.11 with more information - - Closes #13173 - -Daniel Stenberg (23 Mar 2024) - -- docs/libcurl: generate PROTOCOLS from meta-data - - Remove the PROTOCOLS section from the source files completely and - instead generate them based on the header data in the curldown files. - - It also generates TLS backend information for options marked for TLS as - protocol. - - Closes #13175 - -- CURLMOPT_MAX*: mention what happens if changed mid-transfer - - For CURLMOPT_MAXCONNECTS and CURLMOPT_MAX_HOST_CONNECTIONS - - Ref: #13158 - Closes #13176 - -- docs/libcurl: add TLS backend info for all TLS options - - All man pages that are listed to be for TLS now must also specify - exactly what TLS backends the option works for, or use All if they all - work. - - cd2nroff makes sure this is done and that the listed backends exist. - - Closes #13168 - -- docs/libcurl: cleanups - - - CURLINFO_TLS_SESSION.md: remove mention of NSS - - CURLINFO_TLS_SSL_PTR.md: remove NSS leftover - - CURLOPT_CAINFO.md: drop mention of backends not supporting this - - CURLOPT_CAPATH.md: wolfSSL also supports this - - Closes #13166 - -- docs: make each libcurl man specify protocol(s) - - The mandatory header now has a mandatory list of protocols for which the - manpage is relevant. - - Most man pages already has a "PROTOCOLS" section, but this introduces a - stricter way to specify the relevant protocols. - - cd2nroff verifies that at least one protocol is mentioned (which can be - `*`). - - This information is not used just yet, but A) the PROTOCOLS section can - now instead get generated and get a unified wording across all manpages - and B) this allows us to more reliably filter/search for protocol - specific manpages/options. - - Closes #13166 - -Stefan Eissing (21 Mar 2024) - -- http2, http3: only return CURLE_PARTIAL_FILE when bytes were received - - - should resolve spurious pytest failures when stream were reset - right after response header were received - - Clsoes #13151 - -- http: separate response parsing from response action - - - move code that triggers on end-of-response into separate function from - parsing - - simplify some headp/headerlen usage - - add `httpversion` to SingleRequest to indicate the version of the - current response - - Closes #13134 - -Daniel Stenberg (21 Mar 2024) - -- http2: remove the third (unused) argument from http2_data_done() - - Closes #13154 - -- RELEASE-NOTES: synced - -Evgeny Grin (Karlson2k) (21 Mar 2024) - -- RELEASE-NOTES: corrected - - Corrected link for item 118 - - Closes #13157 - -Daniel Stenberg (19 Mar 2024) - -- CURLOPT_INTERFACE.md: remove spurious amp, add see-also - - Closes #13149 - -Stefan Eissing (19 Mar 2024) - -- http: improve response header handling, save cpu cycles - - Saving some cpu cycles in http response header processing: - - pass the length of the header line along - - use string constant sizeof() instead of strlen() - - check line length if prefix is possible - - switch on first header char to limit checks - - Closes #13143 - -Daniel Stenberg (19 Mar 2024) - -- tool_getparam: accept a blank -w "" - - Added test 468 to verify. - - Regression from 07bcae89d5d00 (shipped in 8.6.0) - Reported-by: Thomas Pyle - Fixes #13144 - Closes #13145 - -Evgeny Grin (Karlson2k) (18 Mar 2024) - -- curl_sha512_256: work around a NetBSD bug - - Based on Michael Kaufmann analysis and suggestion - - Closes #13133 - -Stefan Eissing (18 Mar 2024) - -- http: expect 100 rework - - Move all handling of HTTP's `Expect: 100-continue` feature into a client - reader. Add sending flag `KEEP_SEND_TIMED` that triggers transfer - sending on general events like a timer. - - HTTP installs a `CURL_CR_PROTOCOL` reader when announcing `Expect: - 100-continue`. That reader works as follows: - - - on first invocation, records time, starts the `EXPIRE_100_TIMEOUT` - timer, disables `KEEP_SEND`, enables `KEEP_SEND_TIMER` and returns 0, - eos=FALSE like a paused upload. - - - on subsequent invocation it checks if the timer has expired. If so, it - enables `KEEP_SEND` and switches to passing through reads to the - underlying readers. - - Transfer handling's `readwrite()` will be invoked when a timer expires - (like `EXPIRE_100_TIMEOUT`) or when data from the server arrives. Seeing - `KEEP_SEND_TIMER`, it will try to upload more data, which triggers - reading from the client readers again. Which then may lead to a new - pausing or cause the upload to start. - - Flags and timestamps connected to this have been moved from - `SingleRequest` into the reader's context. - - Closes #13110 - -- mbedtls: fix pytest for newer versions - - Fix the expectations in pytest for newer versions of mbedtls - - Closes #13132 - -Daniel Stenberg (15 Mar 2024) - -- ipv6.md: mention IPv4 mapped addresses - - Reported-by: Josh Soref - Assisted-by: Jay Satiro - Fixes #13112 - Closes #13131 - -Stefan Eissing (15 Mar 2024) - -- http: revisit http_perhapsrewind() - - - use facilities provided by client readers better - - work also for non-uploading requests like GET/HEAD - - update documentation - - Closes #13117 - -- test 1541: verify getinfo values on first header callback - - Reported-by: chensong1211 on github - Ref: #13125 - Closes #13128 - -- TLS: start shutdown only when peer did not already close - - - When curl sees a TCP close from the peer, do not start a TLS shutdown. - TLS shutdown is a handshake and if the peer already closed the - connection, it is not interested in participating. - - Reported-by: dfdity on github - Assisted-by: Jiří Bok - Assisted-by: Pēteris Caune - Fixes #10290 - Closes #13087 - -Daniel Stenberg (14 Mar 2024) - -- RELEASE-NOTES: synced - -- curl: make --libcurl output better CURLOPT_*SSLVERSION - - The option is really two enums ORed together, so it needs special - attention to make the code output nice. - - Added test 1481 to verify. Both the server and the proxy versions. - - Reported-by: Boris Verkhovskiy - Fixes #13127 - Closes #13129 - -- GHA/linux: add sysctl trick to work-around GitHub runner issue - - The GitHub image runner update from 20240304.1.0 to 20240310.1 - introduces a problem for clang-14. The issue is caused by - incompatibility between llvm 14 provided in ubuntu-22.04 image and the - much newer kernel configured with high-entropy ASLR. - - As a work-around, we issue a sysctl command to lower the entropy and get - clang-14 to work again. - - URL: https://github.com/actions/runner-images/issues/9491 - - Closes #13124 - -- SPONSORS: describe the basics - - Closes #13119 - -- GOVERNANCE: document the core team - - Closes #13118 - -Jay Satiro (13 Mar 2024) - -- vquic-tls: fix the error code returned for bad CA file - - - Return CURLE_SSL_CACERT_BADFILE if wolfSSL encounters a problem - reading the cert file or path. - - This is a follow-up to the parent commit aedbbdf1. - - Reported-by: Karthikdasari0423@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/13115 - -Daniel Stenberg (12 Mar 2024) - -- vquic-tls: return appropirate errors on wolfSSL errors - - Reported-by: Dexter Gerig - Closes #13107 - -Viktor Szakats (12 Mar 2024) - -- tidy-up: one comment and EOF newlines - - Reviewed-by: Daniel Stenberg - Closes #13108 - -Daniel Stenberg (12 Mar 2024) - -- cmdline-opts: language cleanups - - Use imperative mood consistently for the first sentence describing an - option. - - "Set this" instead "tell curl to set" or "this sets..." - - Plus some extra cleanups and rephrasing. - - Closes #13106 - -- managen: remove space before protocols - - For options that are listed for specific protocols, the protocols (shown - first within parentheses) are now output without the leading space in the - manpage output. - - Closes #13105 - -Jay Satiro (12 Mar 2024) - -- mbedtls: properly cleanup the thread-shared entropy - - - Store the state of the thread-shared entropy for global init/cleanup. - - - Use curl's thread support of mbedtls for all Windows builds instead of - just when the threaded resolver is used via USE_THREADS_WIN32. - - Prior to this change on global cleanup curl builds that have curl thread - support for mbedtls freed the entropy (8b1d2298) but failed to mark that - it had been freed, which caused problems on subsequent init + transfer. - - Bug: https://github.com/curl/curl/discussions/11919#discussioncomment-8687105 - Reported-by: awesomekosm@users.noreply.github.com - - Closes https://github.com/curl/curl/pull/13071 - -Daniel Stenberg (12 Mar 2024) - -- tool_getparam: handle non-existing (out of range) short-options - - ... correctly, even when they follow an existing one without a space in - between. - - Verify with test 467 - - Follow-up to 07dd60c05b - Reported-by: Geeknik Labs - Fixes #13101 - Closes #13102 - -Stefan Eissing (11 Mar 2024) - -- lib: move 'done' parameter to SingleRequests - - A transfer may do several `SingleRequest`s for its success. This happens - regularly for authentication, follows and retries on failed connections. - The "readwrite()" calls and functions connected to those carried a `bool - *done` parameter to indicate that the current `SingleRequest` is over. - This may happen before `upload_done` or `download_done` bits of - `SingleRequest` are set. - - The problem with that is now `write_resp()` protocol handlers are - invoked in places where the `bool *done` cannot be passed up to the - caller. Instead of being a bool in the call chain, it needs to become a - member of `SingleRequest`, reflecting its state. - - This removes the `bool *done` parameter and adds the `done` bit to - `SingleRequest` instead. It adds `Curl_req_soft_reset()` for using a - `SingleRequest` in a follow up, clearing `done` and other - flags/counters. - - Closes #13096 - -- request: clarify message when request has been sent off - - Change the "uploaded and fine" message for requests without a body - - Reported-by: Karthikdasari0423 on github - Fixes #13093 - Closes #13095 - -Daniel Stenberg (11 Mar 2024) - -- RELEASE-NOTES: synced - -Stefan Eissing (9 Mar 2024) - -- lib: keep conn IP information together - - new struct ip_quadruple for holding local/remote addr+port - - - used in data->info and conn and cf-socket.c - - copy back and forth complete struct - - add 'secondary' to conn - - use secondary in reporting success for ftp 2nd connection - - Reported-by: DasKutti on github - Fixes #13084 - Closes #13090 - -Daniel Stenberg (8 Mar 2024) - -- scripts/managen: the new name and home for the manpage generator - - It was previously docs/cmdline-opts/gen.pl - - Closes #13089 - -- VULN-DISCLOSURE-POLICY.md: update detail about CVE requests - - curl is a CNA now - - Closes #13088 - -Stefan Eissing (8 Mar 2024) - -- lib: client reader polish - - - seek_func/seek_client, use transfer values only - - remove copies held in `struct connectdata`, use only - ever `data->set.seek_func` - - resolves possible issues in multiuse connections - - new mime post reader eliminates need to ever overwriting this - - - websockets, remove empty Curl_ws_done() function - - Closes #13079 - -Marcel Raad (8 Mar 2024) - -- lib1598: fix `CURLOPT_POSTFIELDSIZE` usage - - It requires a `long` argument. - - Closes https://github.com/curl/curl/pull/13085 - -Daniel Stenberg (8 Mar 2024) - -- docs/cmdline-opts: drop the curl.1 from the dist tarball - - Since it is no longer needed for building tool_hugehelp.c and all the - docs is available in readable markdown format in the tarball, the peeps - that don't want to build the manpage still do good. - - Removing it also fixes the complexity of out-of-tree builds when the - curl.1 exists in the source tree. - -- test1140/1173: extend wildcards to find curl.1 - - ... in its new build path. - - Also update the test scripts to be more precise in error messages to - help us understand CI errors better. - - Follow-up to f03c85635f35269f1 - Ref: #13029 - Closes #13083 - -- http2: minor tweaks to optimize two struct sizes - - - use BIT() instead of bool - - place the struct fields in (roughly) size order - - Closes #13082 - -- buildconf.bat: remove outdated groff/nroff use - - - don't try to generate the real hugehelp file, because it requires - curl.txt which needs a build - - don't attempt to do anything in a c-ares subdirectory - - Follow-up to f03c85635f35269 - Closes #13078 - -- http2: memory errors in the push callbacks are fatal - - Use the correct nghttp2 error code accordingly. - - Closes #13081 - -Viktor Szakats (7 Mar 2024) - -- mkhelp: rename variable to fix compiler warnings - - ``` - src\tool_operate.c(541,33): warning C4459: declaration of 'm' hides global de - claration [_bld\src\curl.vcxproj] - _bld\src\tool_hugehelp.c(8,27): - see declaration of 'm' - src\tool_paramhlp.c(307,14): warning C4459: declaration of 'm' hides global d - eclaration [_bld\src\curl.vcxproj] - src\tool_progress.c(118,16): warning C4459: declaration of 'm' hides global d - eclaration [_bld\src\curl.vcxproj] - src\tool_writeout.c(288,31): warning C4459: declaration of 'm' hides global d - eclaration [_bld\src\curl.vcxproj] - ``` - Ref: https://ci.appveyor.com/project/curlorg/curl/builds/49348159/job/51ee75c - d2n0wj6lc#L614 - - Reviewed-by: Daniel Stenberg - Closes #13077 - -Daniel Stenberg (7 Mar 2024) - -- KNOWN_BUGS: POP3 issue when reading small chunks - - Closes #12063 - -- RELEASE-NOTES: synced - -Robert Moreton (7 Mar 2024) - -- asyn-ares: fix data race warning - - - Store the c-ares version during global init. - - Prior to this change several threads could write the same data to a - static int variable at the same time. Though in practice it's not a - problem ThreadSanitizer may warn. - - Reported-by: Nikita Taranov - Assisted-by: Jay Satiro - - Fixes #13065 - Closes #13000 - -Stefan Eissing (7 Mar 2024) - -- hyper: implement unpausing via client reader - - Just a tidy up to contain 'ifdef' pollution of common - code parts with implementation specifics. - - - remove the ifdef hyper unpausing in easy.c - - add hyper client reader for CURL_CR_PROTOCOL phase - that implements the unpause method for calling - the hyper waker if it is set - - Closes #13075 - -- ngtcp2: no recvbuf for stream - - - write response data directly to the transfer via - `Curl_xfer_write_resp()` like we do in HTTP/2. - - Closes #13073 - -- docs/cmdline-opts/.gitignore: ignore curl.txt - - Closes #13076 - -Evgeny Grin (Karlson2k) (7 Mar 2024) - -- sha512_256: add support for GnuTLS and OpenSSL - - This is a follow-up for PR #12897. - - Add support for SHA-512/256 digest calculation by TLS backends. - Currently only OpenSSL and GnuTLS (actually, nettle) support - SHA-512/256. - - Closes #13070 - -- digest: add check for hashing error - - Closes #13072 - -Viktor Szakats (7 Mar 2024) - -- cmake: enable `ENABLE_CURL_MANUAL` by default - - Meaning `curl.1` and `src/tool_hugehelp.c` are built by default, - and `--manual` in curl tool is also enabled by default. - - This syncs behaviour with autotools. - - For a reproducible `curl.1`, `SOURCE_DATE_EPOCH` needs to be set - to a consistent date, e.g. the timestamp of `CHANGES`. - - A pre-built manual (e.g. the one distributed in the official source - tarball) will be ignored and rebuilt after this patch, unless - explicitly disabling this option. - - Fixes #13028 - Closes #13069 - -Stefan Eissing (7 Mar 2024) - -- http2: push headers better cleanup - - - provide common cleanup method for push headers - - Closes #13054 - -Daniel Stenberg (7 Mar 2024) - -- GIT-INFO: convert to markdown - - Closes #13074 - -Richard Levitte (7 Mar 2024) - -- cmake: fix libcurl.pc and curl-config library specifications - - Letting CMake figure out where libraries are located gives you full - paths. When generating libcurl.pc and curl-config, getting libraries as - full paths is unusual when one expects to get a list of -l. - - To meet expectations, an effort is made to convert the full paths into - -l, possibly with -L before it. - - Fixes #6169 - Fixes #12748 - Closes #12930 - -Daniel Stenberg (7 Mar 2024) - -- test463: HTTP with -d @file with file containing CR, LF and null byte - -- paramhlp: fix CRLF-stripping files with "-d @file" - - All CR and LF bytes should be stripped, as documented, and all other - bytes are inluded in the data. Starting now, it also excludes null bytes - as they would otherwise also cut the data short. - - Reported-by: Simon K - Fixes #13063 - Closes #13064 - -Viktor Szakats (7 Mar 2024) - -- cmake: fix `CURL_WINDOWS_SSPI=ON` with Schannel disabled - - Prior to this change `CURL_WINDOWS_SSPI` was accidentally forced `OFF` - when building without the Schannel TLS backend. - - This in turn may have caused Kerberos, SPNEGO and SSPI features - disappearing even with `CURL_WINDOWS_SSPI=ON` set. - - This patch fixes it by using the `CURL_USE_SCHANNEL` setting as a - default for `CURL_WINDOWS_SSPI`, but allowing a manual override. - - Also update the option text to better tell its purpose. - - Thanks-to: Andreas Loew - Reviewed-by: Daniel Stenberg - Ref: #13056 - Closes #13061 - -Jay Satiro (6 Mar 2024) - -- KNOWN_BUGS: FTPS server compatibility on Windows with Schannel - - - Remove "2.12 FTPS with Schannel times out file list operation" - - - Remove "7.12 FTPS directory listing hangs on Windows with Schannel" - - - Add "7.12 FTPS server compatibility on Windows with Schannel" - - This change adds a more generic bug description that explains FTPS with - the latest curl and Schannel is not widely used and may have more bugs - than other TLS backends. - - The two removed FTPS Schannel bugs can't be reproduced any longer and - were likely fixed by 24d6c288. - - Ref: https://github.com/curl/curl/issues/5284 - Ref: https://github.com/curl/curl/issues/9161 - Ref: https://github.com/curl/curl/issues/12894 - - Closes https://github.com/curl/curl/pull/13032 - -- trace-config.md: remove the mutexed options list - - - Remove the rendered manpage message that says: - "[--trace-config] is mutually exclusive to --trace and -v, --verbose". - - Actually it can be used with either of those options, which are mutually - exclusive to each other but not to --trace-config. - - Ref: https://curl.se/docs/manpage.html#--trace-config - - Closes https://github.com/curl/curl/pull/13031 - -Daniel Stenberg (6 Mar 2024) - -- mkhelp: simplify the generated hugehelp program - - Use a plain array and puts() every line, also allows us to provide the - strings without ending newlines. - - - merge blank lines into the next one as a prefixed newline. - - turn eight consecutive spaces into a tab (since they can only be on the - left side of text) - - the newly generated tool_hugehelp is 3K lines shorter and 50K smaller - - modifies the top logo layout a little by reducing the indent - - Closes #13047 - -- docs: ascii version of manpage without nroff - - Create ASCII version of manpage without nroff - - - build src/tool_hugegelp.c from the ascii manpage - - move the the manpage and the ascii version build to docs/cmdline-opts - - remove all use of nroff from the build process - - should make the build entirely reproducible (by avoiding nroff) - - - partly reverts 2620aa9 to build libcurl option man pages one by one - in cmake because the appveyor builds got all crazy until I did - - The ASCII version of the manpage - - - is built with gen.pl, just like the manpage is - - has a right-justified column making the appearance similar to the previous - version - - uses a 4-space indent per level (instead of the old version's 7) - - does not do hyphenation of words (which nroff does) - - History - - We first made the curl build use nroff for building the hugehelp file in - December 1998, for curl 5.2. - - Closes #13047 - -Stefan Eissing (6 Mar 2024) - -- lib: add `void *ctx` to reader/writer instances - - - `struct Curl_cwriter` and `struct Curl_creader` now carry a - `void *ctx` member that points to the instance as allocated. - - using `r->ctx` and `w->ctx` as pointer to the instance specific - struct that has been allocated - - Reported-by: Rudi Heitbaum - Fixes #13035 - Closes #13059 - -- http: fix dead code in setting post client reader - - - postsize was always 0, thus the check's else never happened - after the mime client reader was introduced - - Follow-up to 0ba47146f7ff3d - Closes #13060 - -- http2: fix push discard - - - fix logic in discarding a failed pushed stream so that - stream context is properly cleaned up - - Closes #13055 - -- transfer.c: break receive loop in speed limited transfers - - - the change breaks looping in transfer.c receive for transfers that are - speed limited on having gotten *some* bytes. - - the overall speed limit timing is done in multi.c - - Reported-by: Dmitry Karpov - Bug: https://curl.se/mail/lib-2024-03/0001.html - Closes #13050 - -- mime: add client reader - - Add `mime` client reader. Encapsulates reading from mime parts, getting - their length, rewinding and unpausing. - - - remove special mime handling from sendf.c and easy.c - - add general "unpause" method to client readers - - use new reader in http/imap/smtp - - make some mime functions static that are now only used internally - - In addition: - - remove flag 'forbidchunk' as no longer needed - - Closes #13039 - -Daniel Stenberg (5 Mar 2024) - -- RELEASE-NOTES: synced - -- TODO: remove "build HTTP/3 with OpenSSL and nghttp3 using cmake" - - Follow-up to 8e741644a229c37 - -Tal Regev (5 Mar 2024) - -- cmake: add USE_OPENSSL_QUIC support - - Closes #13034 - -Stefan Eissing (5 Mar 2024) - -- TIMER_STARTTRANSFER: set the same for everyone - - - set TIMER_STARTTRANSFER on seeing the first response bytes - in the download client writer, not coming from a CONNECT - - initialized the timer the same way for all protocols - - remove explicit setting of TIMER_STARTTRANSFER in file.c - and c-hyper.c - - Closes #13052 - -Michael Kaufmann (5 Mar 2024) - -- http: better error message for HTTP/1.x response without status line - - If a response without a status line is received, and the connection is - known to use HTTP/1.x (not HTTP/0.9), report the error "Invalid status - line" instead of "Received HTTP/0.9 when not allowed". - - Closes #13045 - -Viktor Szakats (5 Mar 2024) - -- KNOWN_BUGS: fix typo - - Reviewed-by: Daniel Stenberg - Closes #13051 - -Sebastian Neubauer (5 Mar 2024) - -- smpt: fix starttls - - In cases where the connection was fast, curl sometimes failed to open a - connection. This fixes a regression of c2d973627bab12abc5486a3f3. - - The regression triggered in these steps: - - 1. Create an smtp connection - 2. Use STARTTLS - 3. Receive the response - 4. We are inside the loop in `smtp_statemachine`, calling - `smtp_state_starttls_resp` - 5. In the good flow, we exit the loop, re-enter `smtp_statemachine` and - run `smtp_perform_upgrade_tls` at the start of the function. - - In the bad flow, we stay in the while loop, calling - `Curl_pp_readresp`, which reads part of the TLS handshake and things - go wrong. - - The reason is that `Curl_pp_moredata` changed behavior and always - returns `true`, so we stay in the loop in `smtp_statemachine`. With a - slow connection `Curl_pp_readresp` cannot read new data and returns - `CURL_AGAIN`, so we leave the loop and re-enter `smtp_statemachine`. - - With a fast connection, `Curl_pp_readresp` reads new data from the tcp - connection, which is part of the TLS handshake. - - The fix is in `Curl_pp_moredata`, which needs to take the final line - into account and return `false` if only the final line is stored. - - Closes #13048 - -Stefan Eissing (5 Mar 2024) - -- lib: enhance client reader resume + rewind - - - update client reader documentation - - client reader, add rewind capabilities - - tell creader to rewind on next start - - Curl_client_reset() will keep reader for future rewind if requested - - add Curl_client_cleanup() for freeing all resources independent of - rewinds - - add Curl_client_start() to trigger rewinds - - move rewind code from multi.c to sendf.c and make part of - "cr-in"'s implementation - - http, move the "resume_from" handling into the client readers - - the setup of a HTTP request is reshuffled to follow: - * determine method, target, auth negotiation - * install the client reader(s) for the request, including crlf - conversions and "chunked" encoding - * apply ranges to client reader - * concat request headers, upgrades, cookies, etc. - * complete request by determining Content-Length of installed - readers in combination with method - * send - - add methods for client readers to - * return the overall length they will generate (or -1 when unknown) - * return the amount of data on the CLIENT level, so that - expect-100 can decide if it want to apply itself - * set a "resume_from" offset or fail if unsupported - - struct HTTP has become largely empty now - - rename `Client_reader_*` to `Curl_creader_*` - - Closes #13026 - -Viktor Szakats (5 Mar 2024) - -- openssl-quic: fix BIO leak and Windows warning - - Caused by an accidentally duplicated line in - d6825df334def106f735ce7e0c1a2ea87bddffb0. - - ``` - .../lib/vquic/curl_osslq.c:1095:30: warning: implicit conversion loses intege - r precision: 'curl_socket_t' (aka 'unsigned long long') to 'int' [-Wshorten-6 - 4-to-32] - 1095 | bio = BIO_new_dgram(ctx->q.sockfd, BIO_NOCLOSE); - | ~~~~~~~~~~~~~ ~~~~~~~^~~~~~ - 1 warning and 2 errors generated. - ``` - - Reviewed-by: Stefan Eissing - Closes #13043 - -- openssl-quic: fix unity build, casing, indentation - - - rename static functions to avoid duplicate symbols in unity mode. - - windows -> Windows/window in error message and comment. - - fix indentation. - - Reviewed-by: Stefan Eissing - Closes #13044 - -Daniel Stenberg (5 Mar 2024) - -- gen.pl: make the "manpageification" faster - - The function that replaces occurances of "--longoption" with "-Z, - --longoption" etc with the proper highlight applied, no longer loops - over the options. - - Closes #13041 - -- CONTRIBUTE: update the section on documentation format - - ... since most of it is markdown now. - - Closes #13046 - -- smtp: free a temp resource - - The returned address needs to be freed. - - Follow-up to e3905de8196d67b89df1602feb84c1f993211b20 - Spotted by Coverity - - Closes #13038 - -- _VARIABLES.md: improve the description - - Closes #13040 - -dependabot[bot] (4 Mar 2024) - -- build(deps): bump fsfe/reuse-action from 2 to 3 - - Bumps [fsfe/reuse-action](https://github.com/fsfe/reuse-action) from 2 to 3. - - [Release notes](https://github.com/fsfe/reuse-action/releases) - - [Commits](https://github.com/fsfe/reuse-action/compare/v2...v3) - - --- - updated-dependencies: - - dependency-name: fsfe/reuse-action - dependency-type: direct:production - update-type: version-update:semver-major - ... - - Signed-off-by: dependabot[bot] - -Stefan Eissing (4 Mar 2024) - -- pytest: adapt to API change - - - pytest has changed the signature of the hook pytest_report_header() - for some obscure reason and that change landed in our CI now - - - remove the changed param that we never used anyway - - Closes #13037 - -Daniel Stenberg (4 Mar 2024) - -- cookie: if psl fails, reject the cookie - - A libpsl install without data and no built-in database is now considered - bad enough to reject all cookies since they cannot be checked. It is - somewhat of a user error, but still. - - Reported-by: Dan Fandrich - Closes #13033 - -Stefan Eissing (4 Mar 2024) - -- lib: further send/upload handling polish - - - Move all the "upload_done" handling to request.c - - - add possibility to abort sending of a request - - add `Curl_req_done_sending()` for checks - - transfer.c: readwrite_upload() now clean - - - removing data->state.ulbuf and data->req.upload_fromhere - - - as well as data->req.upload_present - - set data->req.upload_done on having read all from - the client and completely flushed the send buffer - - - tftp, remove setting of data->req.upload_fromhere - - - serves no purpose as `upload_present` is not set - and the data itself is directly `sendto()` anyway - - - smtp, make upload EOB conversion a client reader - - xfer_ulbuf addition - - - add xfer_ulbuf for borrowing, similar to xfer_buf - - use in file upload - - use in c-hyper body sending - - - h1-proxy, remove init of data->state.uilbuf that is never used - - smb, add own send_buf instead of using data->state.ulbuf - - Closes #13010 - -Daniel Stenberg (4 Mar 2024) - -- RELEASE-NOTES: synced - -kpcyrd (3 Mar 2024) - -- rustls: fix two warnings related to number types - - Reported-by: Gisle Vanem - Follow-up to #12989 - Closes #13017 - -Stefan Eissing (3 Mar 2024) - -- bufq: writing into a softlimit queue cannot be partial - - - when unable to obtain a new chunk on a softlimit bufq, - this is an allocation error and needs to be reported as - such. - - writes into a soflimit bufq never must be partial success - - Reported-by: Dan Fandrich - Fixes #13020 - Closes #13023 - -Dan Fandrich (2 Mar 2024) - -- configure: Don't build shell completions when disabled - - With the recent changes to completion file building, the files were - built always and only installation was selectively disabled. Now, when - they are disabled they aren't even built, avoiding a build-time error in - environments where it's not possible to run the curl binary that was - just created (e.g. if library paths were not set up correctly). - - Follow-up to 0f7aba83c - - Reported-by: av223119 on github - Fixes #13027 - Closes #13030 - -Jay Satiro (2 Mar 2024) - -- cmdline-opts/_EXITCODES: sync with libcurl-errors - - - Add error code 100 (CURLE_TOO_LARGE) to the list of error codes that - can be returned by the curl tool. - - Closes https://github.com/curl/curl/pull/13015 - -Stefan Eissing (1 Mar 2024) - -- hyper: disable test1598 due to lack of trailer support - - Follow-up to 50838095 - - Closes #13016 - -Dan Fandrich (1 Mar 2024) - -- ftp: Mark a const buffer as const - -- appveyor: Properly skip if only CircleCI is changed - -- docs: Update minimal binary size in INSTALL.md - - Include more options to reduce binary size. - -- configure: Don't make shell completions without perl - - The code that attempted to skip building the shell completions didn't - work properly and tried to build them even if perl wasn't available. - This step, as well as the install step, is now properly skipped without - perl. - - Follow-up to 89733e2dd - - Closes #13022 - -RainRat (1 Mar 2024) - -- misc: Fix typos in docs and lib - - This fixes miscellaneous typos and duplicated words in the docs, lib - and test comments and a few user facing errorstrings. - - Author: RainRat on Github - Reviewed-by: Daniel Gustafsson - Reviewed-by: Dan Fandrich - Closes: #13019 - -Dan Fandrich (29 Feb 2024) - -- configure: build & install shell completions when enabled - - The --with-fish-functions-dir and --with-zsh-functions-dir options - currently have no effect on a normal build because the scripts/ directory - where they're used is not built. Add scripts/ to a normal build and - change the completion options to default to off to preserve the existing - behaviour. - - Closes: #12906 - -- github/labeler: improve the match patterns - -Stefan Eissing (28 Feb 2024) - -- tests: add test1598 for POST with trailers - - - test POST fields with trailers and chunked encoding - - Ref: #12938 - Closes #13009 - -Daniel Stenberg (28 Feb 2024) - -- cmdline-opts/_VERSION: provide %VERSION correctly - - ... so that it does not get included verbatim in the output. Fixes a - regression shipped in 8.6.0. - - Also fix a format mistake in form.md - - Closes #13008 - -Stefan Eissing (28 Feb 2024) - -- lib: Curl_read/Curl_write clarifications - - - replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to - clarify when and at what level they operate - - send/recv of transfer related data is now done via - `Curl_xfer_send()/Curl_xfer_recv()` which no longer has - socket/socketindex as parameter. It decides on the transfer - setup of `conn->sockfd` and `conn->writesockfd` on which - connection filter chain to operate. - - send/recv on a specific connection filter chain is done via - `Curl_conn_send()/Curl_conn_recv()` which get the socket index - as parameter. - - rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for - naming consistency - - clarify that the special CURLE_AGAIN hangling to return - `CURLE_OK` with length 0 only applies to `Curl_xfer_send()` - and CURLE_AGAIN is returned by all other send() variants. - - fix a bug in websocket `curl_ws_recv()` that mixed up data - when it arrived in more than a single chunk (to be made - into a sperate PR, also) - - Added as documented [in - CLIENT-READER.md](https://github.com/curl/curl/blob/5b1f31dfbab8aef467c419c68 - aa06dc738cb75d4/docs/CLIENT-READERS.md). - - - old `Curl_buffer_send()` completely replaced by new `Curl_req_send()` - - old `Curl_fillreadbuffer()` replaced with `Curl_client_read()` - - HTTP chunked uploads are now formatted in a client reader added when - needed. - - FTP line-end conversions are done in a client reader added when - needed. - - when sending requests headers, remaining buffer space is filled with - body data for sending in "one go". This is independent of the request - body size. Resolves #12938 as now small and large requests have the - same code path. - - Changes done to test cases: - - - test513: now fails before sending request headers as this initial - "client read" triggers the setup fault. Behaves now the same as in - hyper build - - test547, test555, test1620: fix the length check in the lib code to - only fail for reads *smaller* than expected. This was a bug in the - test code that never triggered in the old implementation. - - Closes #12969 - -Daniel Gustafsson (28 Feb 2024) - -- curldown: Fix email address in Copyright - - The curldown conversion accidentally replaced daniel@haxx.se with - just daniel.se. This reverts back to the proper email address in - the curldown docs as well as in a few other stray places where it - was incorrect (while unrelated to curldown). - - Reviewed-by: Daniel Stenberg - Closes: #12997 - -Daniel Stenberg (28 Feb 2024) - -- getparam: make --ftp-ssl work again - - Follow-up to 9e4e527 which accidentally broke it - - Reported-by: Jordan Brown - Fixes #13006 - Closes #13007 - -- KNOWN_BUGS: IMAPS connection fails with rustls error - - Closes #10457 - -- KNOWN_BUGS: FTPS upload, FileZilla, GnuTLS and close_notify - - Closes #11383 - -- KNOWN_BUGS: Implicit FTPS upload timeout - - Closes #11720 - -- KNOWN_BUGS: HTTP/2 prior knowledge over proxy - - Closes #12641 - -- TODO: build HTTP/3 with OpenSSL and nghttp3 using cmake - - Closes #12988 - -- TODO: Select signature algorithms - - Closes #12982 - -- examples: use present tense in comments - - remove "will" and some other word fixes - - Closes #13003 - -- docs: more language cleanups - - - present tense - - avoid bad words - - Closes #13003 - -Daniel Gustafsson (27 Feb 2024) - -- setopt: Fix disabling all protocols - - When disabling all protocols without enabling any, the resulting - set of allowed protocols remained the default set. Clearing the - allowed set before inspecting the passed value from --proto make - the set empty even in the errorpath of no protocols enabled. - - Co-authored-by: Dan Fandrich - Reported-by: Dan Fandrich - Reviewed-by: Daniel Stenberg - Closes: #13004 - -Andreas Kiefer (27 Feb 2024) - -- fopen: fix narrowing conversion warning on 32-bit Android - - This was fixed in commit 06dc599405f, but came back in commit - 03cb1ff4d62. - - When building for 32-bit ARM or x86 Android, `st_mode` is defined as - `unsigned int` instead of `mode_t`, resulting in a - `-Wimplicit-int-conversion` clang warning because `mode_t` is - `unsigned short`. Add a cast to silence the warning, but only for - 32-bit Android builds, because other architectures and platforms are - not affected. - - Ref: https://android.googlesource.com/platform/bionic/+/refs/tags/ndk-r25c/li - bc/include/sys/stat.h#86 - Closes https://github.com/curl/curl/pull/12998 - -Stefan Eissing (27 Feb 2024) - -- lib: Curl_read/Curl_write clarifications - - - replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to - clarify when and at what level they operate - - send/recv of transfer related data is now done via - `Curl_xfer_send()/Curl_xfer_recv()` which no longer has - socket/socketindex as parameter. It decides on the transfer - setup of `conn->sockfd` and `conn->writesockfd` on which - connection filter chain to operate. - - send/recv on a specific connection filter chain is done via - `Curl_conn_send()/Curl_conn_recv()` which get the socket index - as parameter. - - rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for - naming consistency - - clarify that the special CURLE_AGAIN hangling to return - `CURLE_OK` with length 0 only applies to `Curl_xfer_send()` - and CURLE_AGAIN is returned by all other send() variants. - - fix a bug in websocket `curl_ws_recv()` that mixed up data - when it arrived in more than a single chunk - - The method for sending not just raw bytes, but bytes that are either - "headers" or "body". The send abstraction stack, to to bottom, now is: - - * `Curl_req_send()`: has parameter to indicate amount of header bytes, - buffers all data. - * `Curl_xfer_send()`: knows on which socket index to send, returns - amount of bytes sent. - * `Curl_conn_send()`: called with socket index, returns amount of bytes - sent. - - In addition there is `Curl_req_flush()` for writing out all buffered - bytes. - - `Curl_req_send()` is active for requests without body, - `Curl_buffer_send()` still being used for others. This is because the - special quirks need to be addressed in future parts: - - * `expect-100` handling - * `Curl_fillreadbuffer()` needs to add directly to the new - `data->req.sendbuf` - * special body handlings, like `chunked` encodings and line end - conversions will be moved into something like a Client Reader. - - In functions of the pattern `CURLcode xxx_send(..., ssize_t *written)`, - replace the `ssize_t` with a `size_t`. It makes no sense to allow for negativ - e - values as the returned `CURLcode` already specifies error conditions. This - allows easier handling of lengths without casting. - - Closes #12964 - -Daniel Stenberg (27 Feb 2024) - -- multi: make add_handle free any multi_easy - - If the easy handle that is being added to a multi handle has previously - been used for curl_easy_perform(), there is a private multi handle here - that we can kill off. While it flushes some caches etc for the easy - handle would it be used for an easy interface transfer again after being - used in the multi stack, this cleanup simplifies behavior and uses less - memory. - - Closes #12992 - -- docs: use present tense - - avoid "will", detect "will" as a bad word in the CI - - Also line wrapped a bunch of paragraphs - - Closes #13001 - -- CURLOPT_SSL_CTX_FUNCTION.md: no promises of lifetime after return - - ... and cleanup other language. - - Closes #12999 - -Stefan Eissing (27 Feb 2024) - -- lib: send rework - - Curl_read/Curl_write clarifications - - - replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to 1clarify - when and at what level they operate - - - send/recv of transfer related data is now done via - `Curl_xfer_send()/Curl_xfer_recv()` which no longer has - socket/socketindex as parameter. It decides on the transfer setup of - `conn->sockfd` and `conn->writesockfd` on which connection filter - chain to operate. - - - send/recv on a specific connection filter chain is done via - `Curl_conn_send()/Curl_conn_recv()` which get the socket index as - parameter. - - - rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for naming - consistency - - - clarify that the special CURLE_AGAIN handling to return `CURLE_OK` - with length 0 only applies to `Curl_xfer_send()` and CURLE_AGAIN is - returned by all other send() variants. - - SingleRequest reshuffling - - - move functions into request.[ch] - - differentiate between reset and free - - add Curl_req_done() to perform last actions - - add a send `bufq` to SingleRequest for future use in keeping upload data - - Closes #12963 - -Daniel Stenberg (26 Feb 2024) - -- RELEASE-NOTES: synced - -- http_chunks: remove unused 'endptr' variable - - Closes #12996 - -Louis Solofrizzo (26 Feb 2024) - -- lib: initialize output pointers to NULL before calling strto[ff,l,ul] - - In order to make MSAN happy: - - ==2200945==WARNING: MemorySanitizer: use-of-uninitialized-value - #0 0x596f3b3ed246 in curlx_strtoofft [...]/libcurl/src/lib/strtoofft.c:23 - 9:11 - #1 0x596f3b402156 in Curl_httpchunk_read [...]/libcurl/src/lib/http_chunk - s.c:149:12 - #2 0x596f3b348550 in readwrite_data [...]/libcurl/src/lib/transfer.c:607: - 11 - [...] - - ==2202041==WARNING: MemorySanitizer: use-of-uninitialized-value - #0 0x5a3fab66a72a in Curl_parse_port [...]/libcurl/src/lib/urlapi.c:547:8 - #1 0x5a3fab650645 in parse_authority [...]/libcurl/src/lib/urlapi.c:796:1 - 2 - #2 0x5a3fab6740f6 in parseurl [...]/libcurl/src/lib/urlapi.c:1176:16 - #3 0x5a3fab664fc5 in parseurl_and_replace [...]/libcurl/src/lib/urlapi.c: - 1342:12 - [...] - - ==2202320==WARNING: MemorySanitizer: use-of-uninitialized-value - #0 0x569076a0d6b0 in ipv4_normalize [...]/libcurl/src/lib/urlapi.c:683:12 - #1 0x5690769f2820 in parse_authority [...]/libcurl/src/lib/urlapi.c:803:1 - 0 - #2 0x569076a160f6 in parseurl [...]/libcurl/src/lib/urlapi.c:1176:16 - #3 0x569076a06fc5 in parseurl_and_replace [...]/libcurl/src/lib/urlapi.c: - 1342:12 - [...] - - Signed-off-by: Louis Solofrizzo - Closes #12995 - -Stefan Eissing (26 Feb 2024) - -- lib: move client writer into own source - - Refactoring of the client writer that passes the data to the - client/application's callback functions. - - - split out into own source cw-out.[ch] from sendf.c - - - move tempwrite and tempcount from data->state into the context of the - client writer - - - redesign the 3 tempwrite dynbufs as a linked list of dynbufs. On - paused transfers, this allows to "record" interleaved HEADER/BODY - chunks to be "played back" in the same order on unpausing. - - - keep the overall size limit of all buffered data to DYN_PAUSE_BUFFER. - On exceeding that, return CURLE_TOO_LARGE instead of - CURLE_OUT_OF_MEMORY as before. - - - add method to be called when a transfer is DONE to allow writing of - any data still buffered - - - when paused, record HEADER writes exactly as they come for later - playback. HEADERs are documented to be written one-by-one. - - Closes #12898 - -- urldata: move authneg bit from conn to Curl_easy - - - from `conn->bits.authneg` to `data->req.authneg` - - this is a property of the request about to be made - and not a property of the connection - - in multiuse connections, transfer could step on each others - toes here potentially. - - Closes #12949 - -- c-hyper: add header collection writer in hyper builds - - Closes #12880 - -- http: move headers collecting to writer - - - add a client writer that does "push" response - headers written to the client if the headers api - is enabled - - remove special handling in sendf.c - - needs to be installed very early on connection - setup to catch CONNECT response headers - - Closes #12880 - -- sendf: Curl_client_write(), make passed in buf const - -Michał Antoniak (26 Feb 2024) - -- lib: remove curl_mimepart object when CURL_DISABLE_MIME - - Remove curl_mimepart object from UserDefined structure when - CURL_DISABLE_MIME flag is active. Reduce size of UserDefined structure. - - Also remove unreachable code: when CURL_DISABLE_MIME is set, httpreq can - never have HTTPREQ_POST_MIME value and the same goes for the - CURL_DISABLE_FORM_API flag and the HTTPREQ_POST_FORM value - - Closes #12948 - -kpcyrd (26 Feb 2024) - -- rustls: make curl compile with 0.12.0 - - Closes #12989 - -Daniel Stenberg (26 Feb 2024) - -- strtoofft: fix the overflow check - - ... to not rely on wrapping, since it is an undefined behavior that is - not what always might happen. This is in our private strtoff() parser - function, used only on platforms without a native version. - - Reported-by: vulnerabilityspotter on hackerone - Closes #12990 - -- libssh/libssh2: return error on too big range - - If trying to get the range 0 - 2^63 and the remote file is 2^63 bytes or - larger. - - Fixes #12983 - Closes #12984 - -Scott Talbert (24 Feb 2024) - -- setopt: fix check for CURLOPT_PROXY_TLSAUTH_TYPE value - - Prior to this change CURLOPT_PROXY_TLSAUTH_TYPE would return - CURLE_BAD_FUNCTION_ARGUMENT on any type other than NULL. Since there is - only one type of TLS auth and it is also the default (SRP) the TLS auth - would work anyway. - - Closes https://github.com/curl/curl/pull/12981 - -Jay Satiro (24 Feb 2024) - -- mprintf: fix format prefix I32/I64 for windows compilers - - - Support I32 & I64 (eg: %I64d) for all Win32 builds. - - Prior to this change mprintf support for the I format prefix, which is a - Microsoft extension, was dependent on the compiler used. - - When Borland compiler support was removed in fd7ef00f the prefix was - then no longer supported for that compiler; however since it's still - possible to build with Borland I'm restoring support for the prefix in - this way. - - Reported-by: Paweł Witas - - Fixes https://github.com/curl/curl/issues/12944 - Closes https://github.com/curl/curl/pull/12950 - -Daniel Stenberg (23 Feb 2024) - -- cd2nroff: gen: make `\>` in input to render as plain '>' in output - - The same (copy and pasted) fix/mistake as in gen.pl - -- gen: make `\>` in input to render as plain '>' in output - - Reported-by: Gisle Vanem - Fixes #12977 - Closes #12978 - -Fabrice Fontaine (23 Feb 2024) - -- configure.ac: find libpsl with pkg-config - - Find libpsl with pkg-config to avoid static build failures. - - Ref: http://autobuild.buildroot.org/results/1fb15e1a99472c403d0d3b1a688902f32 - e78d002 - - Signed-off-by: Fabrice Fontaine - Closes #12947 - -Daniel Stenberg (23 Feb 2024) - -- BUG-BOUNTY.md: clarify that the curl security team decides - - Closes #12975 - -- THANKS: add bug reporter from #740 - - Ref: https://github.com/curl/curl/issues/740 - -Stefan Eissing (22 Feb 2024) - -- multi: fix multi_sock handling of select_bits - - - OR the event bitmask to data->state.select_bits instead of overwriting - them. They are cleared again on use. - - Reported-by: 5533asdg on github - Fixes #12971 - Closes #12972 - -Daniel Stenberg (22 Feb 2024) - -- curlver: bump to 8.7.0 for next release - -- RELEASE-NOTES: synced - -- write-out: add '%{proxy_used}' - - Returns 1 if the previous transfer used a proxy, otherwise 0. Useful to - for example determine if a `NOPROXY` pattern matched the hostname or - not. - - Extended test 970 and 972 - -- CURLINFO_USED_PROXY: return bool whether the proxy was used - - Adds test536 to verify - - Closes #12719 - -- sha512_256: remove the cast macro, minor language/format edits - - Follow-up to cbe41d151d6a100c - - Closes #12966 - -Stefan Eissing (20 Feb 2024) - -- DoH: add trace configuration - - - refs #12397 where it is dicussed how to en-/disable verbose output - of DoH operations - - introducing `struct curl_trc_feat` to track a curl feature for - tracing - - adding `data->state.feat` optionally pointing to the feature a - transfer belongs to - - adding trace functions and verbosity checks on features - - using trace feature in DoH code - - documenting `doh` as feature for `--trace-config` - - Closes #12411 - -- websocket: fix curl_ws_recv() - - - when data arrived in several chunks, the collection into - the passed buffer always started at offset 0, overwriting - the data already there. - - adding test_20_07 to verify fix - - - debug environment var CURL_WS_CHUNK_SIZE can be used to - influence the buffer chunk size used for en-/decoding. - - Closes #12945 - -Evgeny Grin (Karlson2k) (20 Feb 2024) - -- digest: support SHA-512/256 - - Also fix the tests. New implementation tested with GNU libmicrohttpd. - The new numbers in tests are real SHA-512/256 numbers (not just some - random ;) numbers ). - -- tests: add SHA-512/256 unit test - -- SHA-512/256: implement hash algorithm - - Closes #12897 - -- curl_setup.h: add curl_uint64_t internal type - - The unsigned version of curl_off_t basically - -Daniel Stenberg (20 Feb 2024) - -- docs: dist curl*.1 and install without perl - - Drop docs/mk-ca-bundle.1 from the tarball. It can be generated at will. - - Closes #12959 - Fixes #12921 - Reported-by: Michael Forney - -Stefan Eissing (20 Feb 2024) - -- OpenSSL QUIC: adapt to v3.3.x - - - set our idle timeout as transport parameter - - query negotiated idle timeout for connection alive checks - - query number of available bidi streams on a connection - - use write_ex2 with SSL_WRITE_FLAG_CONCLUDE to signal - EOF on last chunk write, so stream close does not - require an additional QUIC packet - - Closes #12933 - -Ramiro Garcia (19 Feb 2024) - -- MANUAL.md: fix typo - - Closes #12965 - -Daniel Stenberg (19 Feb 2024) - -- BINDINGS: add mcurl, the python binding - - Ref: #12956 - Closes #12962 - -- mk-ca-bundle.md: cleanups and polish - - Closes #12958 - -- spellcheck.yml: remove .1/.3 handling, clean all man page .md files - - Since we generate all .1 and .3 files from markdown now, we can limit - the spellcheck to the markdown versions only. - - Closes #12960 - -- libcurl-docs: cleanups - - CURLMOPT_SOCKETDATA.md: fix typo - CURLMOPT_TIMERDATA.md: fix typo - CURLOPT_COOKIELIST.m: quote strings - CURLOPT_PREREQFUNCTION.md: quote variable names - CURLOPT_TCP_NODELAY.md: rephrased to please spell checker - CURLOPT_WILDCARDMATCH.md: rephrased - libcurl-tutorial.md: use correct option name - curl_global_init_mem.md: quote headers - curl_easy_getinfo.md: use correct symbol names in headers - curl_global_trace.md: quote some headers - curl_ws_meta.md: quote struct field names - libcurl-env.md: quote headers - -- cd2nroff: remove backticks from titles - -- RELEASE-NOTES: synced - -Stefan Eissing (18 Feb 2024) - -- http_chunks: fix the accounting of consumed bytes - - Prior to this change chunks were handled correctly although in verbose - mode libcurl could incorrectly warn of "Leftovers after chunking" even - if there were none. - - Reported-by: Michael Kaufmann - - Fixes https://github.com/curl/curl/issues/12937 - Closes https://github.com/curl/curl/pull/12939 - -- file: use xfer buf for file:// transfers - - - For file:// transfers use the multi handle's transfer buffer for - up- and downloads. - - Prior to this change a6c9a33 (precedes 8.6.0) changed the file:// - transfers to use a smaller stack based buffer, and that caused a - significant performance decrease in Windows. - - Bug: https://github.com/curl/curl/issues/12750#issuecomment-1920103086 - Reported-by: edmcln@users.noreply.github.com - - Closes https://github.com/curl/curl/pull/12932 - -Karthikdasari0423 (18 Feb 2024) - -- HTTP3.md: always run nghttp3 submodule init - - - For consistency change all 'build nghttp3' commands to run submodule - init after cloning, even if the branch does not have submodules. - - Follow-up to 5a4b2f93 and 4f794558. - - Closes https://github.com/curl/curl/pull/12928 - -LeeRiva (18 Feb 2024) - -- CURLOPT_POSTQUOTE.md: fix typo - - Closes https://github.com/curl/curl/pull/12926 - -Evgeny Grin (Karlson2k) (18 Feb 2024) - -- checksrc.pl: fix handling .checksrc with CRLF - - - When parsing .checksrc chomp the (CR)LF line ending. - - Prior to this change on Windows checksrc.pl would not process the - symbols in .checksrc properly, since many git repos in Windows use auto - crlf to check out files with CRLF line endings. - - Closes https://github.com/curl/curl/pull/12924 - -Richard Levitte (18 Feb 2024) - -- cmake: fix install for older CMake versions - - - Generate the docs install list by using a foreach loop instead of - LIST:TRANSFORM since older CMake can't handle the latter. - - Reported-by: Dan Fandrich - - Fixes https://github.com/curl/curl/issues/12920 - Closes https://github.com/curl/curl/pull/12922 - -Stefan Eissing (16 Feb 2024) - -- vtls: fix tls proxy peer verification - - - When verifying a proxy certificate for an ip address, use the correct - ip family. - - Prior to this change the "connection" ip family was used, which was not - necessarily the same. - - Reported-by: HsiehYuho@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/12831 - Closes https://github.com/curl/curl/pull/12931 - -Dan Fandrich (15 Feb 2024) - -- CI: Bump the Circle CI base Ubuntu image to the latest 20.04 - - The previous ones are going to be removed soon, plus the new ones - include all the fixes since then. - -Jay Satiro (13 Feb 2024) - -- transfer: improve Windows SO_SNDBUF update limit - - - Change the 1 second SO_SNDBUF update limit from per transfer to per - connection. - - Prior to this change many transfers over the same connection could cause - many SO_SNDBUF updates made to that connection per second, which was - unnecessary. - - Closes https://github.com/curl/curl/pull/12911 - -- schannel: fix hang on unexpected server close - - - Treat TLS connection close (either due to a close_notify from the - server or just closed due to receiving 0) as pending data. - - This is because in some cases schannel_recv knows the connection is - closed but has to return actual pending data so it can't return 0 or an - error to indicate no more data. In this case schannel_recv must be - called again, which only happens if readwrite_data sees that there is - still pending data. - - Prior to this change if the total size of the body that libcurl expected - to receive from the server was unknown then it was possible under some - network conditions that libcurl would hang waiting to receive more data, - when in fact a close_notify alert indicating no more data would be sent - was already processed. - - Fixes https://github.com/curl/curl/issues/12894 - Closes https://github.com/curl/curl/pull/12910 - -Daniel Stenberg (10 Feb 2024) - -- KNOWN_BUGS: FTP upload fails if remebered dir is deleted - - Closes #12181 - Closes #12923 - -Michał Antoniak (10 Feb 2024) - -- mbedtls: use mbedtls_ssl_conf_{min|max}_tls_version - - ... instead of the deprecated mbedtls_ssl_conf_{min|max}_version - - Closes #12905 - -Dan Fandrich (9 Feb 2024) - -- CI: bump to actions/cache@v4 to avoid warning diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 000000000..6e2f7c6bc --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,12 @@ + + +In a release tarball, check the RELEASES-NOTES file for what was done in the +most recent release. In a git check-out, that file mentions changes that have +been done since the previous release. + +See the online [changelog](https://curl.se/changes.html) for the edited and +human readable version of what has changed in different curl releases. diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake index 07f4fc0b6..00b7b3c10 100644 --- a/CMake/CurlSymbolHiding.cmake +++ b/CMake/CurlSymbolHiding.cmake @@ -23,7 +23,7 @@ ########################################################################### include(CheckCSourceCompiles) -option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON) +option(CURL_HIDDEN_SYMBOLS "Hide libcurl internal symbols (=hide all symbols that are not officially external)" ON) mark_as_advanced(CURL_HIDDEN_SYMBOLS) if(WIN32 AND (ENABLE_DEBUG OR ENABLE_CURLDEBUG)) @@ -34,52 +34,47 @@ if(WIN32 AND (ENABLE_DEBUG OR ENABLE_CURLDEBUG)) endif() if(CURL_HIDDEN_SYMBOLS) - set(SUPPORTS_SYMBOL_HIDING FALSE) + set(_supports_symbol_hiding FALSE) if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC) - set(SUPPORTS_SYMBOL_HIDING TRUE) - set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") - set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + set(_supports_symbol_hiding TRUE) + set(_symbol_extern "__attribute__ ((__visibility__ (\"default\")))") + set(_cflag_symbols_hide "-fvisibility=hidden") elseif(CMAKE_COMPILER_IS_GNUCC) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) - # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact - set(SUPPORTS_SYMBOL_HIDING TRUE) - set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") - set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + # Note: This is considered buggy prior to 4.0 but the autotools do not care, so let us ignore that fact + set(_supports_symbol_hiding TRUE) + set(_symbol_extern "__attribute__ ((__visibility__ (\"default\")))") + set(_cflag_symbols_hide "-fvisibility=hidden") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) - set(SUPPORTS_SYMBOL_HIDING TRUE) - set(_SYMBOL_EXTERN "__global") - set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden") + set(_supports_symbol_hiding TRUE) + set(_symbol_extern "__global") + set(_cflag_symbols_hide "-xldscope=hidden") elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) - # note: this should probably just check for version 9.1.045 but I'm not 100% sure - # so let's do it the same way autotools do. - set(SUPPORTS_SYMBOL_HIDING TRUE) - set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))") - set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden") + # Note: This should probably just check for version 9.1.045 but I am not 100% sure + # so let us do it the same way autotools do. + set(_supports_symbol_hiding TRUE) + set(_symbol_extern "__attribute__ ((__visibility__ (\"default\")))") + set(_cflag_symbols_hide "-fvisibility=hidden") check_c_source_compiles("#include - int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug) + int main(void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug) if(NOT _no_bug) - set(SUPPORTS_SYMBOL_HIDING FALSE) - set(_SYMBOL_EXTERN "") - set(_CFLAG_SYMBOLS_HIDE "") + set(_supports_symbol_hiding FALSE) + set(_symbol_extern "") + set(_cflag_symbols_hide "") endif() elseif(MSVC) - set(SUPPORTS_SYMBOL_HIDING TRUE) + set(_supports_symbol_hiding TRUE) endif() - set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING}) -elseif(MSVC) - if(NOT CMAKE_VERSION VERSION_LESS 3.7) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken - set(HIDES_CURL_PRIVATE_SYMBOLS FALSE) - else() - message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.") - set(HIDES_CURL_PRIVATE_SYMBOLS TRUE) - endif() + set(CURL_HIDES_PRIVATE_SYMBOLS ${_supports_symbol_hiding}) else() - set(HIDES_CURL_PRIVATE_SYMBOLS FALSE) + if(MSVC) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + endif() + set(CURL_HIDES_PRIVATE_SYMBOLS FALSE) endif() -set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE}) -set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN}) +set(CURL_CFLAG_SYMBOLS_HIDE ${_cflag_symbols_hide}) +set(CURL_EXTERN_SYMBOL ${_symbol_extern}) diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c index f04abd79b..579758654 100644 --- a/CMake/CurlTests.c +++ b/CMake/CurlTests.c @@ -152,7 +152,7 @@ int main(void) { return 0; } #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, + We cannot simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) @@ -337,7 +337,7 @@ int main(void) #include #include -/* float, because a pointer can't be implicitly cast to float */ +/* Float, because a pointer cannot be implicitly cast to float */ void check(float f) {} int main(void) diff --git a/CMake/FindBearSSL.cmake b/CMake/FindBearSSL.cmake index 653ca9dde..dba4f5e60 100644 --- a/CMake/FindBearSSL.cmake +++ b/CMake/FindBearSSL.cmake @@ -21,12 +21,39 @@ # SPDX-License-Identifier: curl # ########################################################################### -find_path(BEARSSL_INCLUDE_DIRS bearssl.h) +# Find the bearssl library +# +# Input variables: +# +# BEARSSL_INCLUDE_DIR The bearssl include directory +# BEARSSL_INCLUDE_DIRS The bearssl include directory (deprecated) +# BEARSSL_LIBRARY Path to bearssl library +# +# Result variables: +# +# BEARSSL_FOUND System has bearssl +# BEARSSL_INCLUDE_DIRS The bearssl include directories +# BEARSSL_LIBRARIES The bearssl library names + +if(DEFINED BEARSSL_INCLUDE_DIRS AND NOT DEFINED BEARSSL_INCLUDE_DIR) + message(WARNING "BEARSSL_INCLUDE_DIRS is deprecated, use BEARSSL_INCLUDE_DIR instead.") + set(BEARSSL_INCLUDE_DIR "${BEARSSL_INCLUDE_DIRS}") + unset(BEARSSL_INCLUDE_DIRS) +endif() -find_library(BEARSSL_LIBRARY bearssl) +find_path(BEARSSL_INCLUDE_DIR NAMES "bearssl.h") +find_library(BEARSSL_LIBRARY NAMES "bearssl") include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(BEARSSL DEFAULT_MSG - BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY) +find_package_handle_standard_args(BearSSL + REQUIRED_VARS + BEARSSL_INCLUDE_DIR + BEARSSL_LIBRARY +) + +if(BEARSSL_FOUND) + set(BEARSSL_INCLUDE_DIRS ${BEARSSL_INCLUDE_DIR}) + set(BEARSSL_LIBRARIES ${BEARSSL_LIBRARY}) +endif() -mark_as_advanced(BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY) +mark_as_advanced(BEARSSL_INCLUDE_DIR BEARSSL_LIBRARY) diff --git a/CMake/FindBrotli.cmake b/CMake/FindBrotli.cmake index 7f316aaa1..1150d4cc7 100644 --- a/CMake/FindBrotli.cmake +++ b/CMake/FindBrotli.cmake @@ -21,23 +21,60 @@ # SPDX-License-Identifier: curl # ########################################################################### -include(FindPackageHandleStandardArgs) +# Find the brotli library +# +# Input variables: +# +# BROTLI_INCLUDE_DIR The brotli include directory +# BROTLICOMMON_LIBRARY Path to brotlicommon library +# BROTLIDEC_LIBRARY Path to brotlidec library +# +# Result variables: +# +# BROTLI_FOUND System has brotli +# BROTLI_INCLUDE_DIRS The brotli include directories +# BROTLI_LIBRARIES The brotli library names +# BROTLI_VERSION Version of brotli + +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_BROTLI "libbrotlidec") +endif() + +find_path(BROTLI_INCLUDE_DIR "brotli/decode.h" + HINTS + ${PC_BROTLI_INCLUDEDIR} + ${PC_BROTLI_INCLUDE_DIRS} +) -find_path(BROTLI_INCLUDE_DIR "brotli/decode.h") +find_library(BROTLICOMMON_LIBRARY NAMES "brotlicommon" + HINTS + ${PC_BROTLI_LIBDIR} + ${PC_BROTLI_LIBRARY_DIRS} +) +find_library(BROTLIDEC_LIBRARY NAMES "brotlidec" + HINTS + ${PC_BROTLI_LIBDIR} + ${PC_BROTLI_LIBRARY_DIRS} +) -find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon) -find_library(BROTLIDEC_LIBRARY NAMES brotlidec) +if(PC_BROTLI_VERSION) + set(BROTLI_VERSION ${PC_BROTLI_VERSION}) +endif() +include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Brotli - FOUND_VAR - BROTLI_FOUND REQUIRED_VARS + BROTLI_INCLUDE_DIR BROTLIDEC_LIBRARY BROTLICOMMON_LIBRARY - BROTLI_INCLUDE_DIR - FAIL_MESSAGE - "Could NOT find Brotli" + VERSION_VAR + BROTLI_VERSION ) -set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR}) -set(BROTLI_LIBRARIES ${BROTLIDEC_LIBRARY} ${BROTLICOMMON_LIBRARY}) +if(BROTLI_FOUND) + set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR}) + set(BROTLI_LIBRARIES ${BROTLIDEC_LIBRARY} ${BROTLICOMMON_LIBRARY}) +endif() + +mark_as_advanced(BROTLI_INCLUDE_DIR BROTLIDEC_LIBRARY BROTLICOMMON_LIBRARY) diff --git a/CMake/FindCARES.cmake b/CMake/FindCARES.cmake index e82b1de4a..e7b821afc 100644 --- a/CMake/FindCARES.cmake +++ b/CMake/FindCARES.cmake @@ -21,27 +21,60 @@ # SPDX-License-Identifier: curl # ########################################################################### -# - Find c-ares -# Find the c-ares includes and library -# This module defines -# CARES_INCLUDE_DIR, where to find ares.h, etc. -# CARES_LIBRARIES, the libraries needed to use c-ares. -# CARES_FOUND, If false, do not try to use c-ares. -# also defined, but not for general use are -# CARES_LIBRARY, where to find the c-ares library. +# Find the c-ares library +# +# Input variables: +# +# CARES_INCLUDE_DIR The c-ares include directory +# CARES_LIBRARY Path to c-ares library +# +# Result variables: +# +# CARES_FOUND System has c-ares +# CARES_INCLUDE_DIRS The c-ares include directories +# CARES_LIBRARIES The c-ares library names +# CARES_VERSION Version of c-ares -find_path(CARES_INCLUDE_DIR ares.h) +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_CARES "libcares") +endif() -set(CARES_NAMES ${CARES_NAMES} cares) -find_library(CARES_LIBRARY - NAMES ${CARES_NAMES} - ) +find_path(CARES_INCLUDE_DIR NAMES "ares.h" + HINTS + ${PC_CARES_INCLUDEDIR} + ${PC_CARES_INCLUDE_DIRS} +) + +find_library(CARES_LIBRARY NAMES ${CARES_NAMES} "cares" + HINTS + ${PC_CARES_LIBDIR} + ${PC_CARES_LIBRARY_DIRS} +) + +if(PC_CARES_VERSION) + set(CARES_VERSION ${PC_CARES_VERSION}) +elseif(CARES_INCLUDE_DIR AND EXISTS "${CARES_INCLUDE_DIR}/ares_version.h") + set(_version_regex "#[\t ]*define[\t ]+ARES_VERSION_STR[\t ]+\"([^\"]*)\"") + file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(CARES_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) +endif() include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(CARES - REQUIRED_VARS CARES_LIBRARY CARES_INCLUDE_DIR) +find_package_handle_standard_args(Cares + REQUIRED_VARS + CARES_INCLUDE_DIR + CARES_LIBRARY + VERSION_VAR + CARES_VERSION +) + +if(CARES_FOUND) + set(CARES_INCLUDE_DIRS ${CARES_INCLUDE_DIR}) + set(CARES_LIBRARIES ${CARES_LIBRARY}) +endif() -mark_as_advanced( - CARES_LIBRARY - CARES_INCLUDE_DIR - ) +mark_as_advanced(CARES_INCLUDE_DIR CARES_LIBRARY) diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake index 9061e6c85..e84f8947e 100644 --- a/CMake/FindGSS.cmake +++ b/CMake/FindGSS.cmake @@ -21,275 +21,276 @@ # SPDX-License-Identifier: curl # ########################################################################### -# - Try to find the GSS Kerberos library -# Once done this will define +# Find the GSS Kerberos library # -# GSS_ROOT_DIR - Set this variable to the root installation of GSS +# Input variables: # -# Read-Only variables: -# GSS_FOUND - system has the Heimdal library -# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found. -# GSS_INCLUDE_DIR - the Heimdal include directory -# GSS_LIBRARIES - The libraries needed to use GSS -# GSS_LINK_DIRECTORIES - Directories to add to linker search path -# GSS_LINKER_FLAGS - Additional linker flags -# GSS_COMPILER_FLAGS - Additional compiler flags -# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest. -# In case the library is found but no version info available it'll be set to "unknown" - -set(_MIT_MODNAME mit-krb5-gssapi) -set(_HEIMDAL_MODNAME heimdal-gssapi) +# GSS_ROOT_DIR Set this variable to the root installation of GSS +# +# Result variables: +# +# GSS_FOUND System has the Heimdal library +# GSS_FLAVOUR "MIT" or "Heimdal" if anything found +# GSS_INCLUDE_DIRS The GSS include directories +# GSS_LIBRARIES The GSS library names +# GSS_LIBRARY_DIRS The GSS library directories +# GSS_LDFLAGS Required linker flags +# GSS_CFLAGS Required compiler flags +# GSS_VERSION This is set to version advertised by pkg-config or read from manifest. +# In case the library is found but no version info available it is set to "unknown" + +set(_mit_modname "mit-krb5-gssapi") +set(_heimdal_modname "heimdal-gssapi") include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckTypeSize) -set(_GSS_ROOT_HINTS +set(_gss_root_hints "${GSS_ROOT_DIR}" "$ENV{GSS_ROOT_DIR}" ) -# try to find library using system pkg-config if user didn't specify root dir +# Try to find library using system pkg-config if user did not specify root dir if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") - if(UNIX) + if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME}) - list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}") - elseif(WIN32) - list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]") + pkg_search_module(_GSS ${_mit_modname} ${_heimdal_modname}) + list(APPEND _gss_root_hints "${_GSS_PREFIX}") + endif() + if(WIN32) + list(APPEND _gss_root_hints "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]") endif() endif() -if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach. - find_file(_GSS_CONFIGURE_SCRIPT +if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional approach. + find_file(_gss_configure_script NAMES "krb5-config" HINTS - ${_GSS_ROOT_HINTS} + ${_gss_root_hints} PATH_SUFFIXES - bin + "bin" NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH ) - # if not found in user-supplied directories, maybe system knows better - find_file(_GSS_CONFIGURE_SCRIPT + # If not found in user-supplied directories, maybe system knows better + find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES - bin + "bin" ) - if(_GSS_CONFIGURE_SCRIPT) + if(_gss_configure_script) execute_process( - COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi" + COMMAND ${_gss_configure_script} "--cflags" "gssapi" OUTPUT_VARIABLE _GSS_CFLAGS - RESULT_VARIABLE _GSS_CONFIGURE_FAILED + RESULT_VARIABLE _gss_configure_failed OUTPUT_STRIP_TRAILING_WHITESPACE - ) - message(STATUS "CFLAGS: ${_GSS_CFLAGS}") - if(NOT _GSS_CONFIGURE_FAILED) # 0 means success - # should also work in an odd case when multiple directories are given + ) + message(STATUS "FindGSS CFLAGS: ${_GSS_CFLAGS}") + if(NOT _gss_configure_failed) # 0 means success + # Should also work in an odd case when multiple directories are given string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS) string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}") string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}") - foreach(_flag ${_GSS_CFLAGS}) + foreach(_flag IN LISTS _GSS_CFLAGS) if(_flag MATCHES "^-I.*") string(REGEX REPLACE "^-I" "" _val "${_flag}") - list(APPEND _GSS_INCLUDE_DIR "${_val}") + list(APPEND _GSS_INCLUDE_DIRS "${_val}") else() - list(APPEND _GSS_COMPILER_FLAGS "${_flag}") + list(APPEND _GSS_CFLAGS "${_flag}") endif() endforeach() endif() execute_process( - COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi" - OUTPUT_VARIABLE _GSS_LIB_FLAGS - RESULT_VARIABLE _GSS_CONFIGURE_FAILED + COMMAND ${_gss_configure_script} "--libs" "gssapi" + OUTPUT_VARIABLE _gss_lib_flags + RESULT_VARIABLE _gss_configure_failed OUTPUT_STRIP_TRAILING_WHITESPACE ) - message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}") + message(STATUS "FindGSS LDFLAGS: ${_gss_lib_flags}") - if(NOT _GSS_CONFIGURE_FAILED) # 0 means success - # this script gives us libraries and link directories. Blah. We have to deal with it. - string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS) - string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") - string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") + if(NOT _gss_configure_failed) # 0 means success + # This script gives us libraries and link directories. Blah. We have to deal with it. + string(STRIP "${_gss_lib_flags}" _gss_lib_flags) + string(REGEX REPLACE " +-(L|l)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") + string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") - foreach(_flag ${_GSS_LIB_FLAGS}) + foreach(_flag IN LISTS _gss_lib_flags) if(_flag MATCHES "^-l.*") string(REGEX REPLACE "^-l" "" _val "${_flag}") list(APPEND _GSS_LIBRARIES "${_val}") elseif(_flag MATCHES "^-L.*") string(REGEX REPLACE "^-L" "" _val "${_flag}") - list(APPEND _GSS_LINK_DIRECTORIES "${_val}") + list(APPEND _GSS_LIBRARY_DIRS "${_val}") else() - list(APPEND _GSS_LINKER_FLAGS "${_flag}") + list(APPEND _GSS_LDFLAGS "${_flag}") endif() endforeach() endif() execute_process( - COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version" + COMMAND ${_gss_configure_script} "--version" OUTPUT_VARIABLE _GSS_VERSION - RESULT_VARIABLE _GSS_CONFIGURE_FAILED + RESULT_VARIABLE _gss_configure_failed OUTPUT_STRIP_TRAILING_WHITESPACE ) - # older versions may not have the "--version" parameter. In this case we just don't care. - if(_GSS_CONFIGURE_FAILED) + # Older versions may not have the "--version" parameter. In this case we just do not care. + if(_gss_configure_failed) set(_GSS_VERSION 0) endif() execute_process( - COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor" - OUTPUT_VARIABLE _GSS_VENDOR - RESULT_VARIABLE _GSS_CONFIGURE_FAILED + COMMAND ${_gss_configure_script} "--vendor" + OUTPUT_VARIABLE _gss_vendor + RESULT_VARIABLE _gss_configure_failed OUTPUT_STRIP_TRAILING_WHITESPACE ) - # older versions may not have the "--vendor" parameter. In this case we just don't care. - if(_GSS_CONFIGURE_FAILED) - set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter + # Older versions may not have the "--vendor" parameter. In this case we just do not care. + if(_gss_configure_failed) + set(GSS_FLAVOUR "Heimdal") # most probably, should not really matter else() - if(_GSS_VENDOR MATCHES ".*H|heimdal.*") + if(_gss_vendor MATCHES ".*H|heimdal.*") set(GSS_FLAVOUR "Heimdal") else() set(GSS_FLAVOUR "MIT") endif() endif() - else() # either there is no config script or we are on a platform that doesn't provide one (Windows?) + else() # Either there is no config script or we are on a platform that does not provide one (Windows?) - find_path(_GSS_INCLUDE_DIR - NAMES - "gssapi/gssapi.h" + find_path(_GSS_INCLUDE_DIRS NAMES "gssapi/gssapi.h" HINTS - ${_GSS_ROOT_HINTS} + ${_gss_root_hints} PATH_SUFFIXES - include - inc + "include" + "inc" ) - if(_GSS_INCLUDE_DIR) #jay, we've found something - set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}") - check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS) + if(_GSS_INCLUDE_DIRS) # jay, we have found something + set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}") + check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers) - if(_GSS_HAVE_MIT_HEADERS) + if(_gss_have_mit_headers) set(GSS_FLAVOUR "MIT") else() - # prevent compiling the header - just check if we can include it - list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__) - check_include_file( "roken.h" _GSS_HAVE_ROKEN_H) + # Prevent compiling the header - just check if we can include it + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__") + check_include_file("roken.h" _gss_have_roken_h) - check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H) - if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H) + check_include_file("heimdal/roken.h" _gss_have_heimdal_roken_h) + if(_gss_have_roken_h OR _gss_have_heimdal_roken_h) set(GSS_FLAVOUR "Heimdal") endif() - list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__) + list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__") endif() else() - # I'm not convinced if this is the right way but this is what autotools do at the moment - find_path(_GSS_INCLUDE_DIR - NAMES - "gssapi.h" + # I am not convinced if this is the right way but this is what autotools do at the moment + find_path(_GSS_INCLUDE_DIRS NAMES "gssapi.h" HINTS - ${_GSS_ROOT_HINTS} + ${_gss_root_hints} PATH_SUFFIXES - include - inc + "include" + "inc" ) - if(_GSS_INCLUDE_DIR) + if(_GSS_INCLUDE_DIRS) set(GSS_FLAVOUR "Heimdal") endif() endif() - # if we have headers, check if we can link libraries + # If we have headers, check if we can link libraries if(GSS_FLAVOUR) - set(_GSS_LIBDIR_SUFFIXES "") - set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS}) - get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH) - list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT}) + set(_gss_libdir_suffixes "") + set(_gss_libdir_hints ${_gss_root_hints}) + get_filename_component(_gss_calculated_potential_root "${_GSS_INCLUDE_DIRS}" DIRECTORY) + list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root}) if(WIN32) if(CMAKE_SIZEOF_VOID_P EQUAL 8) - list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64") + list(APPEND _gss_libdir_suffixes "lib/AMD64") if(GSS_FLAVOUR STREQUAL "MIT") - set(_GSS_LIBNAME "gssapi64") + set(_gss_libname "gssapi64") else() - set(_GSS_LIBNAME "libgssapi") + set(_gss_libname "libgssapi") endif() else() - list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386") + list(APPEND _gss_libdir_suffixes "lib/i386") if(GSS_FLAVOUR STREQUAL "MIT") - set(_GSS_LIBNAME "gssapi32") + set(_gss_libname "gssapi32") else() - set(_GSS_LIBNAME "libgssapi") + set(_gss_libname "libgssapi") endif() endif() else() - list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS + list(APPEND _gss_libdir_suffixes "lib;lib64") # those suffixes are not checked for HINTS if(GSS_FLAVOUR STREQUAL "MIT") - set(_GSS_LIBNAME "gssapi_krb5") + set(_gss_libname "gssapi_krb5") else() - set(_GSS_LIBNAME "gssapi") + set(_gss_libname "gssapi") endif() endif() - find_library(_GSS_LIBRARIES - NAMES - ${_GSS_LIBNAME} + find_library(_GSS_LIBRARIES NAMES ${_gss_libname} HINTS - ${_GSS_LIBDIR_HINTS} + ${_gss_libdir_hints} PATH_SUFFIXES - ${_GSS_LIBDIR_SUFFIXES} + ${_gss_libdir_suffixes} ) - endif() endif() else() - if(_GSS_PKG_${_MIT_MODNAME}_VERSION) + if(_GSS_MODULE_NAME STREQUAL _mit_modname OR _GSS_${_mit_modname}_VERSION) # _GSS_MODULE_NAME set since CMake 3.16 set(GSS_FLAVOUR "MIT") - set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION) + if(NOT _GSS_VERSION) # for old CMake versions? + set(_GSS_VERSION ${_GSS_${_mit_modname}_VERSION}) + endif() else() set(GSS_FLAVOUR "Heimdal") - set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION) + if(NOT _GSS_VERSION) # for old CMake versions? + set(_GSS_VERSION ${_GSS_${_heimdal_modname}_VERSION}) + endif() endif() + message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_GSS_INCLUDE_DIRS} (found version \"${_GSS_VERSION}\")") endif() -set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR}) +set(GSS_INCLUDE_DIRS ${_GSS_INCLUDE_DIRS}) set(GSS_LIBRARIES ${_GSS_LIBRARIES}) -set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES}) -set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS}) -set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS}) +set(GSS_LIBRARY_DIRS ${_GSS_LIBRARY_DIRS}) +set(GSS_LDFLAGS ${_GSS_LDFLAGS}) +set(GSS_CFLAGS ${_GSS_CFLAGS}) set(GSS_VERSION ${_GSS_VERSION}) if(GSS_FLAVOUR) if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal") if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest") + set(_heimdal_manifest_file "Heimdal.Application.amd64.manifest") else() - set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest") + set(_heimdal_manifest_file "Heimdal.Application.x86.manifest") endif() - if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}") - file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str - REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$") + if(EXISTS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}") + file(STRINGS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}" _heimdal_version_str + REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$") - string(REGEX MATCH "[0-9]\\.[^\"]+" - GSS_VERSION "${heimdal_version_str}") + string(REGEX MATCH "[0-9]\\.[^\"]+" GSS_VERSION "${_heimdal_version_str}") endif() if(NOT GSS_VERSION) set(GSS_VERSION "Heimdal Unknown") endif() elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT") - get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE) - if(WIN32 AND _MIT_VERSION) - set(GSS_VERSION "${_MIT_VERSION}") + get_filename_component(_mit_version "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME + CACHE) + if(WIN32 AND _mit_version) + set(GSS_VERSION "${_mit_version}") else() set(GSS_VERSION "MIT Unknown") endif() @@ -297,16 +298,24 @@ if(GSS_FLAVOUR) endif() include(FindPackageHandleStandardArgs) - -set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR) - find_package_handle_standard_args(GSS REQUIRED_VARS - ${_GSS_REQUIRED_VARS} + GSS_FLAVOUR + GSS_LIBRARIES VERSION_VAR GSS_VERSION FAIL_MESSAGE "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR" ) -mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES) +mark_as_advanced( + _GSS_CFLAGS + _GSS_FOUND + _GSS_INCLUDE_DIRS + _GSS_LDFLAGS + _GSS_LIBRARIES + _GSS_LIBRARY_DIRS + _GSS_MODULE_NAME + _GSS_PREFIX + _GSS_VERSION +) diff --git a/CMake/FindLibPSL.cmake b/CMake/FindLibPSL.cmake index 9ad4bc639..b2cd64f0d 100644 --- a/CMake/FindLibPSL.cmake +++ b/CMake/FindLibPSL.cmake @@ -21,25 +21,60 @@ # SPDX-License-Identifier: curl # ########################################################################### -# - Try to find the libpsl library -# Once done this will define +# Find the libpsl library # -# LIBPSL_FOUND - system has the libpsl library -# LIBPSL_INCLUDE_DIR - the libpsl include directory -# LIBPSL_LIBRARY - the libpsl library name +# Input variables: +# +# LIBPSL_INCLUDE_DIR The libpsl include directory +# LIBPSL_LIBRARY Path to libpsl library +# +# Result variables: +# +# LIBPSL_FOUND System has libpsl +# LIBPSL_INCLUDE_DIRS The libpsl include directories +# LIBPSL_LIBRARIES The libpsl library names +# LIBPSL_VERSION Version of libpsl -find_path(LIBPSL_INCLUDE_DIR libpsl.h) +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_LIBPSL "libpsl") +endif() -find_library(LIBPSL_LIBRARY NAMES psl libpsl) +find_path(LIBPSL_INCLUDE_DIR NAMES "libpsl.h" + HINTS + ${PC_LIBPSL_INCLUDEDIR} + ${PC_LIBPSL_INCLUDE_DIRS} +) -if(LIBPSL_INCLUDE_DIR) - file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" libpsl_version_str REGEX "^#define[\t ]+PSL_VERSION[\t ]+\"(.*)\"") - string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBPSL_VERSION "${libpsl_version_str}") +find_library(LIBPSL_LIBRARY NAMES "psl" "libpsl" + HINTS + ${PC_LIBPSL_LIBDIR} + ${PC_LIBPSL_LIBRARY_DIRS} +) + +if(PC_LIBPSL_VERSION) + set(LIBPSL_VERSION ${PC_LIBPSL_VERSION}) +elseif(LIBPSL_INCLUDE_DIR AND EXISTS "${LIBPSL_INCLUDE_DIR}/libpsl.h") + set(_version_regex "#[\t ]*define[\t ]+PSL_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(LIBPSL_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) endif() include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LibPSL - REQUIRED_VARS LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR - VERSION_VAR LIBPSL_VERSION) +find_package_handle_standard_args(Libpsl + REQUIRED_VARS + LIBPSL_INCLUDE_DIR + LIBPSL_LIBRARY + VERSION_VAR + LIBPSL_VERSION +) + +if(LIBPSL_FOUND) + set(LIBPSL_INCLUDE_DIRS ${LIBPSL_INCLUDE_DIR}) + set(LIBPSL_LIBRARIES ${LIBPSL_LIBRARY}) +endif() mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY) diff --git a/CMake/FindLibSSH2.cmake b/CMake/FindLibSSH2.cmake index 3466b6bfc..0007a8a72 100644 --- a/CMake/FindLibSSH2.cmake +++ b/CMake/FindLibSSH2.cmake @@ -21,25 +21,60 @@ # SPDX-License-Identifier: curl # ########################################################################### -# - Try to find the libssh2 library -# Once done this will define +# Find the libssh2 library # -# LIBSSH2_FOUND - system has the libssh2 library -# LIBSSH2_INCLUDE_DIR - the libssh2 include directory -# LIBSSH2_LIBRARY - the libssh2 library name +# Input variables: +# +# LIBSSH2_INCLUDE_DIR The libssh2 include directory +# LIBSSH2_LIBRARY Path to libssh2 library +# +# Result variables: +# +# LIBSSH2_FOUND System has libssh2 +# LIBSSH2_INCLUDE_DIRS The libssh2 include directories +# LIBSSH2_LIBRARIES The libssh2 library names +# LIBSSH2_VERSION Version of libssh2 -find_path(LIBSSH2_INCLUDE_DIR libssh2.h) +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_LIBSSH2 "libssh2") +endif() -find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2) +find_path(LIBSSH2_INCLUDE_DIR NAMES "libssh2.h" + HINTS + ${PC_LIBSSH2_INCLUDEDIR} + ${PC_LIBSSH2_INCLUDE_DIRS} +) -if(LIBSSH2_INCLUDE_DIR) - file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION[\t ]+\"(.*)\"") - string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBSSH2_VERSION "${libssh2_version_str}") +find_library(LIBSSH2_LIBRARY NAMES "ssh2" "libssh2" + HINTS + ${PC_LIBSSH2_LIBDIR} + ${PC_LIBSSH2_LIBRARY_DIRS} +) + +if(PC_LIBSSH2_VERSION) + set(LIBSSH2_VERSION ${PC_LIBSSH2_VERSION}) +elseif(LIBSSH2_INCLUDE_DIR AND EXISTS "${LIBSSH2_INCLUDE_DIR}/libssh2.h") + set(_version_regex "#[\t ]*define[\t ]+LIBSSH2_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(LIBSSH2_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) endif() include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LibSSH2 - REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR - VERSION_VAR LIBSSH2_VERSION) +find_package_handle_standard_args(Libssh2 + REQUIRED_VARS + LIBSSH2_INCLUDE_DIR + LIBSSH2_LIBRARY + VERSION_VAR + LIBSSH2_VERSION +) + +if(LIBSSH2_FOUND) + set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) + set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) +endif() mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) diff --git a/CMake/FindLibgsasl.cmake b/CMake/FindLibgsasl.cmake new file mode 100644 index 000000000..ed930ebb7 --- /dev/null +++ b/CMake/FindLibgsasl.cmake @@ -0,0 +1,78 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the libgsasl library +# +# Input variables: +# +# LIBGSASL_INCLUDE_DIR The libgsasl include directory +# LIBGSASL_LIBRARY Path to libgsasl library +# +# Result variables: +# +# LIBGSASL_FOUND System has libgsasl +# LIBGSASL_INCLUDE_DIRS The libgsasl include directories +# LIBGSASL_LIBRARIES The libgsasl library names +# LIBGSASL_LIBRARY_DIRS The libgsasl library directories +# LIBGSASL_CFLAGS Required compiler flags +# LIBGSASL_VERSION Version of libgsasl + +if(CURL_USE_PKGCONFIG AND + NOT DEFINED LIBGSASL_INCLUDE_DIR AND + NOT DEFINED LIBGSASL_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(LIBGSASL "libgsasl") +endif() + +if(LIBGSASL_FOUND) + string(REPLACE ";" " " LIBGSASL_CFLAGS "${LIBGSASL_CFLAGS}") + message(STATUS "Found Libgsasl (via pkg-config): ${LIBGSASL_INCLUDE_DIRS} (found version \"${LIBGSASL_VERSION}\")") +else() + find_path(LIBGSASL_INCLUDE_DIR NAMES "gsasl.h") + find_library(LIBGSASL_LIBRARY NAMES "gsasl" "libgsasl") + + if(LIBGSASL_INCLUDE_DIR AND EXISTS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h") + set(_version_regex "#[\t ]*define[\t ]+GSASL_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(LIBGSASL_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Libgsasl + REQUIRED_VARS + LIBGSASL_INCLUDE_DIR + LIBGSASL_LIBRARY + VERSION_VAR + LIBGSASL_VERSION + ) + + if(LIBGSASL_FOUND) + set(LIBGSASL_INCLUDE_DIRS ${LIBGSASL_INCLUDE_DIR}) + set(LIBGSASL_LIBRARIES ${LIBGSASL_LIBRARY}) + endif() + + mark_as_advanced(LIBGSASL_INCLUDE_DIR LIBGSASL_LIBRARY) +endif() diff --git a/CMake/FindLibidn2.cmake b/CMake/FindLibidn2.cmake new file mode 100644 index 000000000..47d4a5862 --- /dev/null +++ b/CMake/FindLibidn2.cmake @@ -0,0 +1,78 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the libidn2 library +# +# Input variables: +# +# LIBIDN2_INCLUDE_DIR The libidn2 include directory +# LIBIDN2_LIBRARY Path to libidn2 library +# +# Result variables: +# +# LIBIDN2_FOUND System has libidn2 +# LIBIDN2_INCLUDE_DIRS The libidn2 include directories +# LIBIDN2_LIBRARIES The libidn2 library names +# LIBIDN2_LIBRARY_DIRS The libidn2 library directories +# LIBIDN2_CFLAGS Required compiler flags +# LIBIDN2_VERSION Version of libidn2 + +if(CURL_USE_PKGCONFIG AND + NOT DEFINED LIBIDN2_INCLUDE_DIR AND + NOT DEFINED LIBIDN2_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(LIBIDN2 "libidn2") +endif() + +if(LIBIDN2_FOUND) + string(REPLACE ";" " " LIBIDN2_CFLAGS "${LIBIDN2_CFLAGS}") + message(STATUS "Found Libidn2 (via pkg-config): ${LIBIDN2_INCLUDE_DIRS} (found version \"${LIBIDN2_VERSION}\")") +else() + find_path(LIBIDN2_INCLUDE_DIR NAMES "idn2.h") + find_library(LIBIDN2_LIBRARY NAMES "idn2" "libidn2") + + if(LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h") + set(_version_regex "#[\t ]*define[\t ]+IDN2_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(LIBIDN2_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Libidn2 + REQUIRED_VARS + LIBIDN2_INCLUDE_DIR + LIBIDN2_LIBRARY + VERSION_VAR + LIBIDN2_VERSION + ) + + if(LIBIDN2_FOUND) + set(LIBIDN2_INCLUDE_DIRS ${LIBIDN2_INCLUDE_DIR}) + set(LIBIDN2_LIBRARIES ${LIBIDN2_LIBRARY}) + endif() + + mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARY) +endif() diff --git a/CMake/FindLibssh.cmake b/CMake/FindLibssh.cmake new file mode 100644 index 000000000..7dc019be7 --- /dev/null +++ b/CMake/FindLibssh.cmake @@ -0,0 +1,92 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the libssh library +# +# Input variables: +# +# LIBSSH_INCLUDE_DIR The libssh include directory +# LIBSSH_LIBRARY Path to libssh library +# +# Result variables: +# +# LIBSSH_FOUND System has libssh +# LIBSSH_INCLUDE_DIRS The libssh include directories +# LIBSSH_LIBRARIES The libssh library names +# LIBSSH_LIBRARY_DIRS The libssh library directories +# LIBSSH_CFLAGS Required compiler flags +# LIBSSH_VERSION Version of libssh + +if(CURL_USE_PKGCONFIG AND + NOT DEFINED LIBSSH_INCLUDE_DIR AND + NOT DEFINED LIBSSH_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(LIBSSH "libssh") +endif() + +if(LIBSSH_FOUND) + string(REPLACE ";" " " LIBSSH_CFLAGS "${LIBSSH_CFLAGS}") + message(STATUS "Found Libssh (via pkg-config): ${LIBSSH_INCLUDE_DIRS} (found version \"${LIBSSH_VERSION}\")") +else() + find_path(LIBSSH_INCLUDE_DIR NAMES "libssh/libssh.h") + find_library(LIBSSH_LIBRARY NAMES "ssh" "libssh") + + if(LIBSSH_INCLUDE_DIR AND EXISTS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h") + set(_version_regex1 "#[\t ]*define[\t ]+LIBSSH_VERSION_MAJOR[\t ]+([0-9]+).*") + set(_version_regex2 "#[\t ]*define[\t ]+LIBSSH_VERSION_MINOR[\t ]+([0-9]+).*") + set(_version_regex3 "#[\t ]*define[\t ]+LIBSSH_VERSION_MICRO[\t ]+([0-9]+).*") + file(STRINGS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h" _version_str1 REGEX "${_version_regex1}") + file(STRINGS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h" _version_str2 REGEX "${_version_regex2}") + file(STRINGS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h" _version_str3 REGEX "${_version_regex3}") + string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}") + string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}") + string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}") + set(LIBSSH_VERSION "${_version_str1}.${_version_str2}.${_version_str3}") + unset(_version_regex1) + unset(_version_regex2) + unset(_version_regex3) + unset(_version_str1) + unset(_version_str2) + unset(_version_str3) + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Libssh + REQUIRED_VARS + LIBSSH_INCLUDE_DIR + LIBSSH_LIBRARY + VERSION_VAR + LIBSSH_VERSION + ) + + if(LIBSSH_FOUND) + set(LIBSSH_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR}) + set(LIBSSH_LIBRARIES ${LIBSSH_LIBRARY}) + endif() + + mark_as_advanced(LIBSSH_INCLUDE_DIR LIBSSH_LIBRARY) +endif() + +if(LIBSSH_FOUND AND WIN32) + list(APPEND LIBSSH_LIBRARIES "iphlpapi") # for if_nametoindex +endif() diff --git a/CMake/FindLibuv.cmake b/CMake/FindLibuv.cmake new file mode 100644 index 000000000..d4dfa2450 --- /dev/null +++ b/CMake/FindLibuv.cmake @@ -0,0 +1,88 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the libuv library +# +# Input variables: +# +# LIBUV_INCLUDE_DIR The libuv include directory +# LIBUV_LIBRARY Path to libuv library +# +# Result variables: +# +# LIBUV_FOUND System has libuv +# LIBUV_INCLUDE_DIRS The libuv include directories +# LIBUV_LIBRARIES The libuv library names +# LIBUV_LIBRARY_DIRS The libuv library directories +# LIBUV_CFLAGS Required compiler flags +# LIBUV_VERSION Version of libuv + +if(CURL_USE_PKGCONFIG AND + NOT DEFINED LIBUV_INCLUDE_DIR AND + NOT DEFINED LIBUV_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(LIBUV "libuv") +endif() + +if(LIBUV_FOUND) + string(REPLACE ";" " " LIBUV_CFLAGS "${LIBUV_CFLAGS}") + message(STATUS "Found Libuv (via pkg-config): ${LIBUV_INCLUDE_DIRS} (found version \"${LIBUV_VERSION}\")") +else() + find_path(LIBUV_INCLUDE_DIR NAMES "uv.h") + find_library(LIBUV_LIBRARY NAMES "uv" "libuv") + + if(LIBUV_INCLUDE_DIR AND EXISTS "${LIBUV_INCLUDE_DIR}/uv/version.h") + set(_version_regex1 "#[\t ]*define[\t ]+UV_VERSION_MAJOR[\t ]+([0-9]+).*") + set(_version_regex2 "#[\t ]*define[\t ]+UV_VERSION_MINOR[\t ]+([0-9]+).*") + set(_version_regex3 "#[\t ]*define[\t ]+UV_VERSION_PATCH[\t ]+([0-9]+).*") + file(STRINGS "${LIBUV_INCLUDE_DIR}/uv/version.h" _version_str1 REGEX "${_version_regex1}") + file(STRINGS "${LIBUV_INCLUDE_DIR}/uv/version.h" _version_str2 REGEX "${_version_regex2}") + file(STRINGS "${LIBUV_INCLUDE_DIR}/uv/version.h" _version_str3 REGEX "${_version_regex3}") + string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}") + string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}") + string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}") + set(LIBUV_VERSION "${_version_str1}.${_version_str2}.${_version_str3}") + unset(_version_regex1) + unset(_version_regex2) + unset(_version_regex3) + unset(_version_str1) + unset(_version_str2) + unset(_version_str3) + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Libuv + REQUIRED_VARS + LIBUV_INCLUDE_DIR + LIBUV_LIBRARY + VERSION_VAR + LIBUV_VERSION + ) + + if(LIBUV_FOUND) + set(LIBUV_INCLUDE_DIRS ${LIBUV_INCLUDE_DIR}) + set(LIBUV_LIBRARIES ${LIBUV_LIBRARY}) + endif() + + mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY) +endif() diff --git a/CMake/FindMSH3.cmake b/CMake/FindMSH3.cmake index 7d9c6b654..46cee8871 100644 --- a/CMake/FindMSH3.cmake +++ b/CMake/FindMSH3.cmake @@ -21,50 +21,53 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the msh3 library +# +# Input variables: +# +# MSH3_INCLUDE_DIR The msh3 include directory +# MSH3_LIBRARY Path to msh3 library +# +# Result variables: +# +# MSH3_FOUND System has msh3 +# MSH3_INCLUDE_DIRS The msh3 include directories +# MSH3_LIBRARIES The msh3 library names +# MSH3_VERSION Version of msh3 -#[=======================================================================[.rst: -FindMSH3 ----------- - -Find the msh3 library - -Result Variables -^^^^^^^^^^^^^^^^ - -``MSH3_FOUND`` - System has msh3 -``MSH3_INCLUDE_DIRS`` - The msh3 include directories. -``MSH3_LIBRARIES`` - The libraries needed to use msh3 -#]=======================================================================] -if(UNIX) +if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(PC_MSH3 libmsh3) + pkg_check_modules(PC_MSH3 "libmsh3") endif() -find_path(MSH3_INCLUDE_DIR msh3.h +find_path(MSH3_INCLUDE_DIR NAMES "msh3.h" HINTS ${PC_MSH3_INCLUDEDIR} ${PC_MSH3_INCLUDE_DIRS} ) -find_library(MSH3_LIBRARY NAMES msh3 +find_library(MSH3_LIBRARY NAMES "msh3" HINTS ${PC_MSH3_LIBDIR} ${PC_MSH3_LIBRARY_DIRS} ) +if(PC_MSH3_VERSION) + set(MSH3_VERSION ${PC_MSH3_VERSION}) +endif() + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MSH3 REQUIRED_VARS - MSH3_LIBRARY MSH3_INCLUDE_DIR + MSH3_LIBRARY + VERSION_VAR + MSH3_VERSION ) if(MSH3_FOUND) - set(MSH3_LIBRARIES ${MSH3_LIBRARY}) set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR}) + set(MSH3_LIBRARIES ${MSH3_LIBRARY}) endif() -mark_as_advanced(MSH3_INCLUDE_DIRS MSH3_LIBRARIES) +mark_as_advanced(MSH3_INCLUDE_DIR MSH3_LIBRARY) diff --git a/CMake/FindMbedTLS.cmake b/CMake/FindMbedTLS.cmake index 7692a2587..53b86149e 100644 --- a/CMake/FindMbedTLS.cmake +++ b/CMake/FindMbedTLS.cmake @@ -21,16 +21,91 @@ # SPDX-License-Identifier: curl # ########################################################################### -find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) +# Find the mbedtls library +# +# Input variables: +# +# MBEDTLS_INCLUDE_DIR The mbedtls include directory +# MBEDTLS_INCLUDE_DIRS The mbedtls include directory (deprecated) +# MBEDTLS_LIBRARY Path to mbedtls library +# MBEDX509_LIBRARY Path to mbedx509 library +# MBEDCRYPTO_LIBRARY Path to mbedcrypto library +# +# Result variables: +# +# MBEDTLS_FOUND System has mbedtls +# MBEDTLS_INCLUDE_DIRS The mbedtls include directories +# MBEDTLS_LIBRARIES The mbedtls library names +# MBEDTLS_VERSION Version of mbedtls -find_library(MBEDTLS_LIBRARY mbedtls) -find_library(MBEDX509_LIBRARY mbedx509) -find_library(MBEDCRYPTO_LIBRARY mbedcrypto) +if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR) + message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.") + set(MBEDTLS_INCLUDE_DIR "${MBEDTLS_INCLUDE_DIRS}") + unset(MBEDTLS_INCLUDE_DIRS) +endif() -set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}") +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_MBEDTLS "mbedtls") +endif() + +find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h" + HINTS + ${PC_MBEDTLS_INCLUDEDIR} + ${PC_MBEDTLS_INCLUDE_DIRS} +) + +find_library(MBEDTLS_LIBRARY NAMES "mbedtls" + HINTS + ${PC_MBEDTLS_LIBDIR} + ${PC_MBEDTLS_LIBRARY_DIRS} +) +find_library(MBEDX509_LIBRARY NAMES "mbedx509" + HINTS + ${PC_MBEDTLS_LIBDIR} + ${PC_MBEDTLS_LIBRARY_DIRS} +) +find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto" + HINTS + ${PC_MBEDTLS_LIBDIR} + ${PC_MBEDTLS_LIBRARY_DIRS} +) + +if(PC_MBEDTLS_VERSION) + set(MBEDTLS_VERSION ${PC_MBEDTLS_VERSION}) +elseif(MBEDTLS_INCLUDE_DIR) + if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") # 3.x + set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") + elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") # 2.x + set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") + else() + unset(_version_header) + endif() + if(_version_header) + set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"") + file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(MBEDTLS_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) + unset(_version_header) + endif() +endif() include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MbedTLS DEFAULT_MSG - MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) +find_package_handle_standard_args(MbedTLS + REQUIRED_VARS + MBEDTLS_INCLUDE_DIR + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY + VERSION_VAR + MBEDTLS_VERSION +) + +if(MBEDTLS_FOUND) + set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR}) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY}) +endif() -mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) +mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) diff --git a/CMake/FindNGHTTP2.cmake b/CMake/FindNGHTTP2.cmake index 88ac03741..e632d2054 100644 --- a/CMake/FindNGHTTP2.cmake +++ b/CMake/FindNGHTTP2.cmake @@ -21,21 +21,60 @@ # SPDX-License-Identifier: curl # ########################################################################### -include(FindPackageHandleStandardArgs) +# Find the nghttp2 library +# +# Input variables: +# +# NGHTTP2_INCLUDE_DIR The nghttp2 include directory +# NGHTTP2_LIBRARY Path to nghttp2 library +# +# Result variables: +# +# NGHTTP2_FOUND System has nghttp2 +# NGHTTP2_INCLUDE_DIRS The nghttp2 include directories +# NGHTTP2_LIBRARIES The nghttp2 library names +# NGHTTP2_VERSION Version of nghttp2 + +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_NGHTTP2 "libnghttp2") +endif() -find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h") +find_path(NGHTTP2_INCLUDE_DIR NAMES "nghttp2/nghttp2.h" + HINTS + ${PC_NGHTTP2_INCLUDEDIR} + ${PC_NGHTTP2_INCLUDE_DIRS} +) + +find_library(NGHTTP2_LIBRARY NAMES "nghttp2" "nghttp2_static" + HINTS + ${PC_NGHTTP2_LIBDIR} + ${PC_NGHTTP2_LIBRARY_DIRS} +) -find_library(NGHTTP2_LIBRARY NAMES nghttp2 nghttp2_static) +if(PC_NGHTTP2_VERSION) + set(NGHTTP2_VERSION ${PC_NGHTTP2_VERSION}) +elseif(NGHTTP2_INCLUDE_DIR AND EXISTS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h") + set(_version_regex "#[\t ]*define[\t ]+NGHTTP2_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(NGHTTP2_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) +endif() +include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NGHTTP2 - FOUND_VAR - NGHTTP2_FOUND REQUIRED_VARS - NGHTTP2_LIBRARY NGHTTP2_INCLUDE_DIR + NGHTTP2_LIBRARY + VERSION_VAR + NGHTTP2_VERSION ) -set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR}) -set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY}) +if(NGHTTP2_FOUND) + set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR}) + set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY}) +endif() -mark_as_advanced(NGHTTP2_INCLUDE_DIRS NGHTTP2_LIBRARIES) +mark_as_advanced(NGHTTP2_INCLUDE_DIR NGHTTP2_LIBRARY) diff --git a/CMake/FindNGHTTP3.cmake b/CMake/FindNGHTTP3.cmake index 9b13e6c6f..02a0c87d0 100644 --- a/CMake/FindNGHTTP3.cmake +++ b/CMake/FindNGHTTP3.cmake @@ -21,38 +21,32 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the nghttp3 library +# +# Input variables: +# +# NGHTTP3_INCLUDE_DIR The nghttp3 include directory +# NGHTTP3_LIBRARY Path to nghttp3 library +# +# Result variables: +# +# NGHTTP3_FOUND System has nghttp3 +# NGHTTP3_INCLUDE_DIRS The nghttp3 include directories +# NGHTTP3_LIBRARIES The nghttp3 library names +# NGHTTP3_VERSION Version of nghttp3 -#[=======================================================================[.rst: -FindNGHTTP3 ----------- - -Find the nghttp3 library - -Result Variables -^^^^^^^^^^^^^^^^ - -``NGHTTP3_FOUND`` - System has nghttp3 -``NGHTTP3_INCLUDE_DIRS`` - The nghttp3 include directories. -``NGHTTP3_LIBRARIES`` - The libraries needed to use nghttp3 -``NGHTTP3_VERSION`` - version of nghttp3. -#]=======================================================================] - -if(UNIX) +if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(PC_NGHTTP3 libnghttp3) + pkg_check_modules(PC_NGHTTP3 "libnghttp3") endif() -find_path(NGHTTP3_INCLUDE_DIR nghttp3/nghttp3.h +find_path(NGHTTP3_INCLUDE_DIR NAMES "nghttp3/nghttp3.h" HINTS ${PC_NGHTTP3_INCLUDEDIR} ${PC_NGHTTP3_INCLUDE_DIRS} ) -find_library(NGHTTP3_LIBRARY NAMES nghttp3 +find_library(NGHTTP3_LIBRARY NAMES "nghttp3" HINTS ${PC_NGHTTP3_LIBDIR} ${PC_NGHTTP3_LIBRARY_DIRS} @@ -60,19 +54,27 @@ find_library(NGHTTP3_LIBRARY NAMES nghttp3 if(PC_NGHTTP3_VERSION) set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION}) +elseif(NGHTTP3_INCLUDE_DIR AND EXISTS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h") + set(_version_regex "#[\t ]*define[\t ]+NGHTTP3_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(NGHTTP3_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NGHTTP3 REQUIRED_VARS - NGHTTP3_LIBRARY NGHTTP3_INCLUDE_DIR - VERSION_VAR NGHTTP3_VERSION + NGHTTP3_LIBRARY + VERSION_VAR + NGHTTP3_VERSION ) if(NGHTTP3_FOUND) - set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY}) set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR}) + set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY}) endif() -mark_as_advanced(NGHTTP3_INCLUDE_DIRS NGHTTP3_LIBRARIES) +mark_as_advanced(NGHTTP3_INCLUDE_DIR NGHTTP3_LIBRARY) diff --git a/CMake/FindNGTCP2.cmake b/CMake/FindNGTCP2.cmake index 7ea466582..194483d54 100644 --- a/CMake/FindNGTCP2.cmake +++ b/CMake/FindNGTCP2.cmake @@ -21,46 +21,40 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the ngtcp2 library +# +# This module accepts optional COMPONENTS to control the crypto library (these are +# mutually exclusive): +# +# quictls: Use libngtcp2_crypto_quictls (choose this for LibreSSL) +# BoringSSL: Use libngtcp2_crypto_boringssl (choose this for AWS-LC) +# wolfSSL: Use libngtcp2_crypto_wolfssl +# GnuTLS: Use libngtcp2_crypto_gnutls +# +# Input variables: +# +# NGTCP2_INCLUDE_DIR The ngtcp2 include directory +# NGTCP2_LIBRARY Path to ngtcp2 library +# +# Result variables: +# +# NGTCP2_FOUND System has ngtcp2 +# NGTCP2_INCLUDE_DIRS The ngtcp2 include directories +# NGTCP2_LIBRARIES The ngtcp2 library names +# NGTCP2_VERSION Version of ngtcp2 -#[=======================================================================[.rst: -FindNGTCP2 ----------- - -Find the ngtcp2 library - -This module accepts optional COMPONENTS to control the crypto library (these are -mutually exclusive):: - - quictls, LibreSSL: Use libngtcp2_crypto_quictls - BoringSSL, AWS-LC: Use libngtcp2_crypto_boringssl - wolfSSL: Use libngtcp2_crypto_wolfssl - GnuTLS: Use libngtcp2_crypto_gnutls - -Result Variables -^^^^^^^^^^^^^^^^ - -``NGTCP2_FOUND`` - System has ngtcp2 -``NGTCP2_INCLUDE_DIRS`` - The ngtcp2 include directories. -``NGTCP2_LIBRARIES`` - The libraries needed to use ngtcp2 -``NGTCP2_VERSION`` - version of ngtcp2. -#]=======================================================================] - -if(UNIX) +if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(PC_NGTCP2 libngtcp2) + pkg_check_modules(PC_NGTCP2 "libngtcp2") endif() -find_path(NGTCP2_INCLUDE_DIR ngtcp2/ngtcp2.h +find_path(NGTCP2_INCLUDE_DIR NAMES "ngtcp2/ngtcp2.h" HINTS ${PC_NGTCP2_INCLUDEDIR} ${PC_NGTCP2_INCLUDE_DIRS} ) -find_library(NGTCP2_LIBRARY NAMES ngtcp2 +find_library(NGTCP2_LIBRARY NAMES "ngtcp2" HINTS ${PC_NGTCP2_LIBDIR} ${PC_NGTCP2_LIBRARY_DIRS} @@ -68,33 +62,38 @@ find_library(NGTCP2_LIBRARY NAMES ngtcp2 if(PC_NGTCP2_VERSION) set(NGTCP2_VERSION ${PC_NGTCP2_VERSION}) +elseif(NGTCP2_INCLUDE_DIR AND EXISTS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h") + set(_version_regex "#[\t ]*define[\t ]+NGTCP2_VERSION[\t ]+\"([^\"]*)\"") + file(STRINGS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(NGTCP2_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) endif() if(NGTCP2_FIND_COMPONENTS) - set(NGTCP2_CRYPTO_BACKEND "") - foreach(component IN LISTS NGTCP2_FIND_COMPONENTS) - if(component MATCHES "^(BoringSSL|quictls|wolfSSL|GnuTLS)") - if(NGTCP2_CRYPTO_BACKEND) + set(_ngtcp2_crypto_backend "") + foreach(_component IN LISTS NGTCP2_FIND_COMPONENTS) + if(_component MATCHES "^(BoringSSL|quictls|wolfSSL|GnuTLS)") + if(_ngtcp2_crypto_backend) message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected") endif() - set(NGTCP2_CRYPTO_BACKEND ${component}) + set(_ngtcp2_crypto_backend ${_component}) endif() endforeach() - if(NGTCP2_CRYPTO_BACKEND) - string(TOLOWER "ngtcp2_crypto_${NGTCP2_CRYPTO_BACKEND}" _crypto_library) - if(UNIX) - pkg_search_module(PC_${_crypto_library} lib${_crypto_library}) + if(_ngtcp2_crypto_backend) + string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library) + if(CURL_USE_PKGCONFIG) + pkg_check_modules(PC_${_crypto_library} "lib${_crypto_library}") endif() - find_library(${_crypto_library}_LIBRARY - NAMES - ${_crypto_library} + find_library(${_crypto_library}_LIBRARY NAMES ${_crypto_library} HINTS ${PC_${_crypto_library}_LIBDIR} ${PC_${_crypto_library}_LIBRARY_DIRS} ) if(${_crypto_library}_LIBRARY) - set(NGTCP2_${NGTCP2_CRYPTO_BACKEND}_FOUND TRUE) + set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE) set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY}) endif() endif() @@ -103,15 +102,16 @@ endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NGTCP2 REQUIRED_VARS - NGTCP2_LIBRARY NGTCP2_INCLUDE_DIR - VERSION_VAR NGTCP2_VERSION + NGTCP2_LIBRARY + VERSION_VAR + NGTCP2_VERSION HANDLE_COMPONENTS ) if(NGTCP2_FOUND) - set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY}) set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR}) + set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY}) endif() -mark_as_advanced(NGTCP2_INCLUDE_DIRS NGTCP2_LIBRARIES) +mark_as_advanced(NGTCP2_INCLUDE_DIR NGTCP2_LIBRARY NGTCP2_CRYPTO_LIBRARY) diff --git a/CMake/FindNettle.cmake b/CMake/FindNettle.cmake new file mode 100644 index 000000000..b5da05bf7 --- /dev/null +++ b/CMake/FindNettle.cmake @@ -0,0 +1,83 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the nettle library +# +# Input variables: +# +# NETTLE_INCLUDE_DIR The nettle include directory +# NETTLE_LIBRARY Path to nettle library +# +# Result variables: +# +# NETTLE_FOUND System has nettle +# NETTLE_INCLUDE_DIRS The nettle include directories +# NETTLE_LIBRARIES The nettle library names +# NETTLE_LIBRARY_DIRS The nettle library directories +# NETTLE_CFLAGS Required compiler flags +# NETTLE_VERSION Version of nettle + +if(CURL_USE_PKGCONFIG AND + NOT DEFINED NETTLE_INCLUDE_DIR AND + NOT DEFINED NETTLE_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(NETTLE "nettle") +endif() + +if(NETTLE_FOUND) + string(REPLACE ";" " " NETTLE_CFLAGS "${NETTLE_CFLAGS}") + message(STATUS "Found Nettle (via pkg-config): ${NETTLE_INCLUDE_DIRS} (found version \"${NETTLE_VERSION}\")") +else() + find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h") + find_library(NETTLE_LIBRARY NAMES "nettle") + + if(NETTLE_INCLUDE_DIR AND EXISTS "${NETTLE_INCLUDE_DIR}/nettle/version.h") + set(_version_regex1 "#[\t ]*define[ \t]+NETTLE_VERSION_MAJOR[ \t]+([0-9]+).*") + set(_version_regex2 "#[\t ]*define[ \t]+NETTLE_VERSION_MINOR[ \t]+([0-9]+).*") + file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h" _version_str1 REGEX "${_version_regex1}") + file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h" _version_str2 REGEX "${_version_regex2}") + string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}") + string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}") + set(NETTLE_VERSION "${_version_str1}.${_version_str2}") + unset(_version_regex1) + unset(_version_regex2) + unset(_version_str1) + unset(_version_str2) + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Nettle + REQUIRED_VARS + NETTLE_INCLUDE_DIR + NETTLE_LIBRARY + VERSION_VAR + NETTLE_VERSION + ) + + if(NETTLE_FOUND) + set(NETTLE_INCLUDE_DIRS ${NETTLE_INCLUDE_DIR}) + set(NETTLE_LIBRARIES ${NETTLE_LIBRARY}) + endif() + + mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARY) +endif() diff --git a/CMake/FindQUICHE.cmake b/CMake/FindQUICHE.cmake index 0488463d5..7d1626adc 100644 --- a/CMake/FindQUICHE.cmake +++ b/CMake/FindQUICHE.cmake @@ -21,50 +21,53 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the quiche library +# +# Input variables: +# +# QUICHE_INCLUDE_DIR The quiche include directory +# QUICHE_LIBRARY Path to quiche library +# +# Result variables: +# +# QUICHE_FOUND System has quiche +# QUICHE_INCLUDE_DIRS The quiche include directories +# QUICHE_LIBRARIES The quiche library names +# QUICHE_VERSION Version of quiche -#[=======================================================================[.rst: -FindQUICHE ----------- - -Find the quiche library - -Result Variables -^^^^^^^^^^^^^^^^ - -``QUICHE_FOUND`` - System has quiche -``QUICHE_INCLUDE_DIRS`` - The quiche include directories. -``QUICHE_LIBRARIES`` - The libraries needed to use quiche -#]=======================================================================] -if(UNIX) +if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(PC_QUICHE quiche) + pkg_check_modules(PC_QUICHE "quiche") endif() -find_path(QUICHE_INCLUDE_DIR quiche.h +find_path(QUICHE_INCLUDE_DIR NAMES "quiche.h" HINTS ${PC_QUICHE_INCLUDEDIR} ${PC_QUICHE_INCLUDE_DIRS} ) -find_library(QUICHE_LIBRARY NAMES quiche +find_library(QUICHE_LIBRARY NAMES "quiche" HINTS ${PC_QUICHE_LIBDIR} ${PC_QUICHE_LIBRARY_DIRS} ) +if(PC_QUICHE_VERSION) + set(QUICHE_VERSION ${PC_QUICHE_VERSION}) +endif() + include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(QUICHE +find_package_handle_standard_args(Quiche REQUIRED_VARS - QUICHE_LIBRARY QUICHE_INCLUDE_DIR + QUICHE_LIBRARY + VERSION_VAR + QUICHE_VERSION ) if(QUICHE_FOUND) - set(QUICHE_LIBRARIES ${QUICHE_LIBRARY}) set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR}) + set(QUICHE_LIBRARIES ${QUICHE_LIBRARY}) endif() -mark_as_advanced(QUICHE_INCLUDE_DIRS QUICHE_LIBRARIES) +mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY) diff --git a/CMake/FindRustls.cmake b/CMake/FindRustls.cmake new file mode 100644 index 000000000..ffd6859ff --- /dev/null +++ b/CMake/FindRustls.cmake @@ -0,0 +1,73 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the rustls library +# +# Input variables: +# +# RUSTLS_INCLUDE_DIR The rustls include directory +# RUSTLS_LIBRARY Path to rustls library +# +# Result variables: +# +# RUSTLS_FOUND System has rustls +# RUSTLS_INCLUDE_DIRS The rustls include directories +# RUSTLS_LIBRARIES The rustls library names +# RUSTLS_VERSION Version of rustls + +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_RUSTLS "rustls") +endif() + +find_path(RUSTLS_INCLUDE_DIR NAMES "rustls.h" + HINTS + ${PC_RUSTLS_INCLUDEDIR} + ${PC_RUSTLS_INCLUDE_DIRS} +) + +find_library(RUSTLS_LIBRARY NAMES "rustls" + HINTS + ${PC_RUSTLS_LIBDIR} + ${PC_RUSTLS_LIBRARY_DIRS} +) + +if(PC_RUSTLS_VERSION) + set(RUSTLS_VERSION ${PC_RUSTLS_VERSION}) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Rustls + REQUIRED_VARS + RUSTLS_INCLUDE_DIR + RUSTLS_LIBRARY + VERSION_VAR + RUSTLS_VERSION +) + +if(RUSTLS_FOUND) + set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR}) + set(RUSTLS_LIBRARIES ${RUSTLS_LIBRARY}) +endif() + +mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY) diff --git a/CMake/FindWolfSSH.cmake b/CMake/FindWolfSSH.cmake new file mode 100644 index 000000000..608e3abfc --- /dev/null +++ b/CMake/FindWolfSSH.cmake @@ -0,0 +1,64 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# Find the wolfssh library +# +# Input variables: +# +# WOLFSSH_INCLUDE_DIR The wolfssh include directory +# WOLFSSH_LIBRARY Path to wolfssh library +# +# Result variables: +# +# WOLFSSH_FOUND System has wolfssh +# WOLFSSH_INCLUDE_DIRS The wolfssh include directories +# WOLFSSH_LIBRARIES The wolfssh library names +# WOLFSSH_VERSION Version of wolfssh + +find_path(WOLFSSH_INCLUDE_DIR NAMES "wolfssh/ssh.h") +find_library(WOLFSSH_LIBRARY NAMES "wolfssh" "libwolfssh") + +if(WOLFSSH_INCLUDE_DIR AND EXISTS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h") + set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSH_VERSION_STRING[\t ]+\"([^\"]*)\"") + file(STRINGS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(WOLFSSH_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(WolfSSH + REQUIRED_VARS + WOLFSSH_INCLUDE_DIR + WOLFSSH_LIBRARY + VERSION_VAR + WOLFSSH_VERSION +) + +if(WOLFSSH_FOUND) + set(WOLFSSH_INCLUDE_DIRS ${WOLFSSH_INCLUDE_DIR}) + set(WOLFSSH_LIBRARIES ${WOLFSSH_LIBRARY}) +endif() + +mark_as_advanced(WOLFSSH_INCLUDE_DIR WOLFSSH_LIBRARY) diff --git a/CMake/FindWolfSSL.cmake b/CMake/FindWolfSSL.cmake index 7336c8f4d..905fbfd5d 100644 --- a/CMake/FindWolfSSL.cmake +++ b/CMake/FindWolfSSL.cmake @@ -21,40 +21,78 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the wolfssl library +# +# Input variables: +# +# WOLFSSL_INCLUDE_DIR The wolfssl include directory +# WolfSSL_INCLUDE_DIR The wolfssl include directory (deprecated) +# WOLFSSL_LIBRARY Path to wolfssl library +# WolfSSL_LIBRARY Path to wolfssl library (deprecated) +# +# Result variables: +# +# WOLFSSL_FOUND System has wolfssl +# WOLFSSL_INCLUDE_DIRS The wolfssl include directories +# WOLFSSL_LIBRARIES The wolfssl library names +# WOLFSSL_VERSION Version of wolfssl -find_package(PkgConfig QUIET) -pkg_check_modules(PC_WOLFSSL QUIET "wolfssl") +if(DEFINED WolfSSL_INCLUDE_DIR AND NOT DEFINED WOLFSSL_INCLUDE_DIR) + message(WARNING "WolfSSL_INCLUDE_DIR is deprecated, use WOLFSSL_INCLUDE_DIR instead.") + set(WOLFSSL_INCLUDE_DIR "${WolfSSL_INCLUDE_DIR}") +endif() +if(DEFINED WolfSSL_LIBRARY AND NOT DEFINED WOLFSSL_LIBRARY) + message(WARNING "WolfSSL_LIBRARY is deprecated, use WOLFSSL_LIBRARY instead.") + set(WOLFSSL_LIBRARY "${WolfSSL_LIBRARY}") +endif() + +if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_WOLFSSL "wolfssl") +endif() -find_path(WolfSSL_INCLUDE_DIR - NAMES "wolfssl/ssl.h" - HINTS ${PC_WOLFSSL_INCLUDE_DIRS} +find_path(WOLFSSL_INCLUDE_DIR NAMES "wolfssl/ssl.h" + HINTS + ${PC_WOLFSSL_INCLUDEDIR} + ${PC_WOLFSSL_INCLUDE_DIRS} ) -find_library(WolfSSL_LIBRARY - NAMES "wolfssl" - HINTS ${PC_WOLFSSL_LIBRARY_DIRS} +find_library(WOLFSSL_LIBRARY NAMES "wolfssl" + HINTS + ${PC_WOLFSSL_LIBDIR} + ${PC_WOLFSSL_LIBRARY_DIRS} ) -if(WolfSSL_INCLUDE_DIR) - set(_version_regex "^#define[ \t]+LIBWOLFSSL_VERSION_STRING[ \t]+\"([^\"]+)\".*") - file(STRINGS "${WolfSSL_INCLUDE_DIR}/wolfssl/version.h" - WolfSSL_VERSION REGEX "${_version_regex}") - string(REGEX REPLACE "${_version_regex}" "\\1" - WolfSSL_VERSION "${WolfSSL_VERSION}") +if(PC_WOLFSSL_VERSION) + set(WOLFSSL_VERSION ${PC_WOLFSSL_VERSION}) +elseif(WOLFSSL_INCLUDE_DIR AND EXISTS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h") + set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSL_VERSION_STRING[\t ]+\"([^\"]*)\"") + file(STRINGS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(WOLFSSL_VERSION "${_version_str}") unset(_version_regex) + unset(_version_str) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(WolfSSL REQUIRED_VARS - WolfSSL_INCLUDE_DIR - WolfSSL_LIBRARY - VERSION_VAR WolfSSL_VERSION + WOLFSSL_INCLUDE_DIR + WOLFSSL_LIBRARY + VERSION_VAR + WOLFSSL_VERSION ) -if(WolfSSL_FOUND) - set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR}) - set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY}) +if(WOLFSSL_FOUND) + set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR}) + set(WOLFSSL_LIBRARIES ${WOLFSSL_LIBRARY}) + + if(NOT WIN32) + find_library(_math_library "m") + if(_math_library) + list(APPEND WOLFSSL_LIBRARIES "m") # for log and pow + endif() + endif() endif() -mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY) +mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY) diff --git a/CMake/FindZstd.cmake b/CMake/FindZstd.cmake index 0ea9e0c87..10558ccc4 100644 --- a/CMake/FindZstd.cmake +++ b/CMake/FindZstd.cmake @@ -21,58 +21,81 @@ # SPDX-License-Identifier: curl # ########################################################################### +# Find the zstd library +# +# Input variables: +# +# ZSTD_INCLUDE_DIR The zstd include directory +# Zstd_INCLUDE_DIR The zstd include directory (deprecated) +# ZSTD_LIBRARY Path to zstd library +# Zstd_LIBRARY Path to zstd library (deprecated) +# +# Result variables: +# +# ZSTD_FOUND System has zstd +# ZSTD_INCLUDE_DIRS The zstd include directories +# ZSTD_LIBRARIES The zstd library names +# ZSTD_VERSION Version of zstd -#[=======================================================================[.rst: -FindZstd ----------- - -Find the zstd library - -Result Variables -^^^^^^^^^^^^^^^^ - -``Zstd_FOUND`` - System has zstd -``Zstd_INCLUDE_DIRS`` - The zstd include directories. -``Zstd_LIBRARIES`` - The libraries needed to use zstd -#]=======================================================================] +if(DEFINED Zstd_INCLUDE_DIR AND NOT DEFINED ZSTD_INCLUDE_DIR) + message(WARNING "Zstd_INCLUDE_DIR is deprecated, use ZSTD_INCLUDE_DIR instead.") + set(ZSTD_INCLUDE_DIR "${Zstd_INCLUDE_DIR}") +endif() +if(DEFINED Zstd_LIBRARY AND NOT DEFINED ZSTD_LIBRARY) + message(WARNING "Zstd_LIBRARY is deprecated, use ZSTD_LIBRARY instead.") + set(ZSTD_LIBRARY "${Zstd_LIBRARY}") +endif() -if(UNIX) +if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) - pkg_search_module(PC_Zstd libzstd) + pkg_check_modules(PC_ZSTD "libzstd") endif() -find_path(Zstd_INCLUDE_DIR zstd.h +find_path(ZSTD_INCLUDE_DIR NAMES "zstd.h" HINTS - ${PC_Zstd_INCLUDEDIR} - ${PC_Zstd_INCLUDE_DIRS} + ${PC_ZSTD_INCLUDEDIR} + ${PC_ZSTD_INCLUDE_DIRS} ) -find_library(Zstd_LIBRARY NAMES zstd +find_library(ZSTD_LIBRARY NAMES "zstd" HINTS - ${PC_Zstd_LIBDIR} - ${PC_Zstd_LIBRARY_DIRS} + ${PC_ZSTD_LIBDIR} + ${PC_ZSTD_LIBRARY_DIRS} ) -if(Zstd_INCLUDE_DIR) - file(READ "${Zstd_INCLUDE_DIR}/zstd.h" _zstd_header) - string(REGEX MATCH ".*define ZSTD_VERSION_MAJOR *([0-9]+).*define ZSTD_VERSION_MINOR *([0-9]+).*define ZSTD_VERSION_RELEASE *([0-9]+)" _zstd_ver "${_zstd_header}") - set(Zstd_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") +if(PC_ZSTD_VERSION) + set(ZSTD_VERSION ${PC_ZSTD_VERSION}) +elseif(ZSTD_INCLUDE_DIR AND EXISTS "${ZSTD_INCLUDE_DIR}/zstd.h") + set(_version_regex1 "#[\t ]*define[ \t]+ZSTD_VERSION_MAJOR[ \t]+([0-9]+).*") + set(_version_regex2 "#[\t ]*define[ \t]+ZSTD_VERSION_MINOR[ \t]+([0-9]+).*") + set(_version_regex3 "#[\t ]*define[ \t]+ZSTD_VERSION_RELEASE[ \t]+([0-9]+).*") + file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str1 REGEX "${_version_regex1}") + file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str2 REGEX "${_version_regex2}") + file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str3 REGEX "${_version_regex3}") + string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}") + string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}") + string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}") + set(ZSTD_VERSION "${_version_str1}.${_version_str2}.${_version_str3}") + unset(_version_regex1) + unset(_version_regex2) + unset(_version_regex3) + unset(_version_str1) + unset(_version_str2) + unset(_version_str3) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Zstd REQUIRED_VARS - Zstd_LIBRARY - Zstd_INCLUDE_DIR - VERSION_VAR Zstd_VERSION + ZSTD_INCLUDE_DIR + ZSTD_LIBRARY + VERSION_VAR + ZSTD_VERSION ) -if(Zstd_FOUND) - set(Zstd_LIBRARIES ${Zstd_LIBRARY}) - set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR}) +if(ZSTD_FOUND) + set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR}) + set(ZSTD_LIBRARIES ${ZSTD_LIBRARY}) endif() -mark_as_advanced(Zstd_INCLUDE_DIRS Zstd_LIBRARIES) +mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY) diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake index d5439fcc0..d268667ff 100644 --- a/CMake/Macros.cmake +++ b/CMake/Macros.cmake @@ -21,60 +21,56 @@ # SPDX-License-Identifier: curl # ########################################################################### -#File defines convenience macros for available feature testing +# File defines convenience macros for available feature testing # Check if header file exists and add it to the list. # This macro is intended to be called multiple times with a sequence of # possibly dependent header files. Some headers depend on others to be # compiled correctly. -macro(check_include_file_concat FILE VARIABLE) - check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE}) - if(${VARIABLE}) - set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE}) - set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}") +macro(check_include_file_concat _file _variable) + check_include_files("${CURL_INCLUDES};${_file}" ${_variable}) + if(${_variable}) + set(CURL_INCLUDES ${CURL_INCLUDES} ${_file}) + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}") endif() endmacro() # For other curl specific tests, use this macro. -macro(curl_internal_test CURL_TEST) - if(NOT DEFINED "${CURL_TEST}") - set(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}") +# Return result in variable: CURL_TEST_OUTPUT +macro(curl_internal_test _curl_test) + if(NOT DEFINED "${_curl_test}") + set(_macro_check_function_definitions + "-D${_curl_test} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}") if(CMAKE_REQUIRED_LIBRARIES) - set(CURL_TEST_ADD_LIBRARIES + set(_curl_test_add_libraries "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") endif() - message(STATUS "Performing Test ${CURL_TEST}") - try_compile(${CURL_TEST} + message(STATUS "Performing Test ${_curl_test}") + try_compile(${_curl_test} ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} - "${CURL_TEST_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - if(${CURL_TEST}) - set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") - message(STATUS "Performing Test ${CURL_TEST} - Success") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing Test ${CURL_TEST} passed with the following output:\n" - "${OUTPUT}\n") + "${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c" + CMAKE_FLAGS + "-DCOMPILE_DEFINITIONS:STRING=${_macro_check_function_definitions}" + "${_curl_test_add_libraries}" + OUTPUT_VARIABLE CURL_TEST_OUTPUT) + if(${_curl_test}) + set(${_curl_test} 1 CACHE INTERNAL "Curl test") + message(STATUS "Performing Test ${_curl_test} - Success") else() - message(STATUS "Performing Test ${CURL_TEST} - Failed") - set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing Test ${CURL_TEST} failed with the following output:\n" - "${OUTPUT}\n") + set(${_curl_test} "" CACHE INTERNAL "Curl test") + message(STATUS "Performing Test ${_curl_test} - Failed") endif() endif() endmacro() -macro(optional_dependency DEPENDENCY) - set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)") - set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF) +macro(optional_dependency _dependency) + set(CURL_${_dependency} "AUTO" CACHE STRING "Build curl with ${_dependency} support (AUTO, ON or OFF)") + set_property(CACHE CURL_${_dependency} PROPERTY STRINGS "AUTO" "ON" "OFF") - if(CURL_${DEPENDENCY} STREQUAL AUTO) - find_package(${DEPENDENCY}) - elseif(CURL_${DEPENDENCY}) - find_package(${DEPENDENCY} REQUIRED) + if(CURL_${_dependency} STREQUAL "AUTO") + find_package(${_dependency}) + elseif(CURL_${_dependency}) + find_package(${_dependency} REQUIRED) endif() endmacro() diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake index 2fddb867c..8936cea01 100644 --- a/CMake/OtherTests.cmake +++ b/CMake/OtherTests.cmake @@ -25,17 +25,17 @@ include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckTypeSize) -macro(add_header_include check header) - if(${check}) +macro(add_header_include _check _header) + if(${_check}) set(_source_epilogue "${_source_epilogue} - #include <${header}>") + #include <${_header}>") endif() endmacro() set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE) - set(CMAKE_EXTRA_INCLUDE_FILES) + unset(CMAKE_EXTRA_INCLUDE_FILES) if(WIN32) set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h") set(CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN") @@ -45,6 +45,7 @@ if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE) endif() check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE) set(HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE}) + set(CMAKE_EXTRA_INCLUDE_FILES "") endif() if(NOT WIN32) @@ -75,37 +76,32 @@ check_c_source_compiles("${_source_epilogue} unset(CMAKE_TRY_COMPILE_TARGET_TYPE) -if(NOT CMAKE_CROSSCOMPILING AND NOT APPLE) +if(NOT APPLE) set(_source_epilogue "#undef inline") add_header_include(HAVE_SYS_POLL_H "sys/poll.h") add_header_include(HAVE_POLL_H "poll.h") - check_c_source_runs("${_source_epilogue} - #include - #include - int main(void) - { - if(0 != poll(0, 0, 10)) { - return 1; /* fail */ - } - else { - /* detect the 10.12 poll() breakage */ - struct timeval before, after; - int rc; - size_t us; - - gettimeofday(&before, NULL); - rc = poll(NULL, 0, 500); - gettimeofday(&after, NULL); - - us = (after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec); - - if(us < 400000) { - return 1; + if(NOT CMAKE_CROSSCOMPILING) + check_c_source_runs("${_source_epilogue} + #include + int main(void) + { + if(0 != poll(0, 0, 10)) { + return 1; /* fail */ } - } - return 0; - }" HAVE_POLL_FINE) + return 0; + }" HAVE_POLL_FINE) + elseif(UNIX) + check_c_source_compiles("${_source_epilogue} + #include + int main(void) + { + #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L + (void)poll(0, 0, 0); + #else + #error force compilation error + #endif + }" HAVE_POLL_FINE) + endif() endif() # Detect HAVE_GETADDRINFO_THREADSAFE diff --git a/CMake/PickyWarnings.cmake b/CMake/PickyWarnings.cmake index 96e45f0e8..a711efaea 100644 --- a/CMake/PickyWarnings.cmake +++ b/CMake/PickyWarnings.cmake @@ -28,7 +28,7 @@ unset(WPICKY) if(CURL_WERROR AND ((CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND - NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR # check_symbol_exists() incompatible with GCC -pedantic-errors in earlier CMake versions + NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR # to avoid check_symbol_exists() conflicting with GCC -pedantic-errors CMAKE_C_COMPILER_ID MATCHES "Clang")) set(WPICKY "${WPICKY} -pedantic-errors") endif() @@ -104,13 +104,13 @@ if(PICKY_COMPILER) -Wmissing-noreturn # clang 2.7 gcc 4.1 -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) -Wno-system-headers # clang 1.0 gcc 3.0 - # -Wpadded # clang 2.9 gcc 4.1 # Not used because we cannot change public structs + # -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs -Wold-style-definition # clang 2.7 gcc 3.4 -Wredundant-decls # clang 2.7 gcc 4.1 -Wsign-conversion # clang 2.9 gcc 4.3 -Wno-error=sign-conversion # FIXME -Wstrict-prototypes # clang 1.0 gcc 3.3 - # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used because this basically disallows default case + # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case -Wtype-limits # clang 2.7 gcc 4.3 -Wunreachable-code # clang 2.7 gcc 4.1 # -Wunused-macros # clang 2.7 gcc 4.1 # Not practical @@ -160,7 +160,7 @@ if(PICKY_COMPILER) if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) OR (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.4)) list(APPEND WPICKY_ENABLE - -Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # we have silencing markup for clang 10.0 and above only + -Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # We do silencing for clang 10.0 and above only ) endif() else() # gcc @@ -180,7 +180,7 @@ if(PICKY_COMPILER) endif() if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW) list(APPEND WPICKY_ENABLE - -Wno-pedantic-ms-format # gcc 4.5 (mingw-only) + -Wno-pedantic-ms-format # gcc 4.5 (MinGW-only) ) endif() if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) @@ -206,7 +206,7 @@ if(PICKY_COMPILER) list(APPEND WPICKY_ENABLE -Walloc-zero # gcc 7.0 -Wduplicated-branches # gcc 7.0 - -Wformat-overflow=2 # gcc 7.0 + -Wno-format-overflow # gcc 7.0 -Wformat-truncation=2 # gcc 7.0 -Wimplicit-fallthrough # clang 4.0 gcc 7.0 -Wrestrict # gcc 7.0 @@ -221,20 +221,20 @@ if(PICKY_COMPILER) # - foreach(_CCOPT IN LISTS WPICKY_ENABLE) - set(WPICKY "${WPICKY} ${_CCOPT}") + foreach(_ccopt IN LISTS WPICKY_ENABLE) + set(WPICKY "${WPICKY} ${_ccopt}") endforeach() - foreach(_CCOPT IN LISTS WPICKY_DETECT) + foreach(_ccopt IN LISTS WPICKY_DETECT) # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new # test result in. - string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname) + string(MAKE_C_IDENTIFIER "OPT${_ccopt}" _optvarname) # GCC only warns about unknown -Wno- options if there are also other diagnostic messages, # so test for the positive form instead - string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}") - check_c_compiler_flag(${_CCOPT_ON} ${_optvarname}) + string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}") + check_c_compiler_flag(${_ccopt_on} ${_optvarname}) if(${_optvarname}) - set(WPICKY "${WPICKY} ${_CCOPT}") + set(WPICKY "${WPICKY} ${_ccopt}") endif() endforeach() endif() diff --git a/CMake/Platforms/WindowsCache.cmake b/CMake/Platforms/WindowsCache.cmake index 5346f595e..317f21c87 100644 --- a/CMake/Platforms/WindowsCache.cmake +++ b/CMake/Platforms/WindowsCache.cmake @@ -41,6 +41,10 @@ if(MINGW) set(HAVE_SYS_PARAM_H 1) set(HAVE_SYS_TIME_H 1) set(HAVE_GETTIMEOFDAY 1) + set(HAVE_STRINGS_H 1) # wrapper to string.h + set(HAVE_UTIME_H 1) # wrapper to sys/utime.h + set(HAVE_DIRENT_H 1) + set(HAVE_OPENDIR 1) else() set(HAVE_LIBGEN_H 0) set(HAVE_STRCASECMP 0) @@ -48,6 +52,10 @@ else() set(HAVE_SYS_PARAM_H 0) set(HAVE_SYS_TIME_H 0) set(HAVE_GETTIMEOFDAY 0) + set(HAVE_STRINGS_H 0) + set(HAVE_UTIME_H 0) + set(HAVE_DIRENT_H 0) + set(HAVE_OPENDIR 0) if(MSVC) set(HAVE_UNISTD_H 0) set(HAVE_LOCALE_H 1) @@ -121,7 +129,6 @@ set(HAVE_IOCTL_SIOCGIFADDR 0) set(HAVE_POLL_H 0) set(HAVE_POLL_FINE 0) set(HAVE_PWD_H 0) -set(HAVE_STRINGS_H 0) # mingw-w64 has it (wrapper to string.h) set(HAVE_SYS_EVENTFD_H 0) set(HAVE_SYS_FILIO_H 0) set(HAVE_SYS_WAIT_H 0) @@ -137,12 +144,9 @@ set(HAVE_SYS_UN_H 0) set(HAVE_SYS_UTIME_H 1) set(HAVE_TERMIOS_H 0) set(HAVE_TERMIO_H 0) -set(HAVE_UTIME_H 0) # mingw-w64 has it (wrapper to sys/utime.h) - -set(HAVE_DIRENT_H 0) -set(HAVE_OPENDIR 0) +set(HAVE_LINUX_TCP_H 0) -set(HAVE_FSEEKO 0) +set(HAVE_FSEEKO 0) # mingw-w64 2.0.0 and newer has it set(HAVE__FSEEKI64 1) set(HAVE_SOCKET 1) set(HAVE_SELECT 1) @@ -161,7 +165,6 @@ set(HAVE_GMTIME_R 0) set(HAVE_GETHOSTBYNAME_R 0) set(HAVE_SIGNAL 1) set(HAVE_SIGACTION 0) -set(HAVE_LINUX_TCP_H 0) set(HAVE_GLIBC_STRERROR_R 0) set(HAVE_MACH_ABSOLUTE_TIME 0) set(HAVE_GETIFADDRS 0) diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake index 84a40f4e3..0ecfa3129 100644 --- a/CMake/Utilities.cmake +++ b/CMake/Utilities.cmake @@ -24,12 +24,12 @@ # File containing various utilities # Returns number of arguments that evaluate to true -function(count_true output_count_var) +function(count_true _output_count_var) set(lst_len 0) foreach(option_var IN LISTS ARGN) if(${option_var}) math(EXPR lst_len "${lst_len} + 1") endif() endforeach() - set(${output_count_var} ${lst_len} PARENT_SCOPE) + set(${_output_count_var} ${lst_len} PARENT_SCOPE) endfunction() diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in index 47aec8d42..d1f746fc0 100644 --- a/CMake/cmake_uninstall.cmake.in +++ b/CMake/cmake_uninstall.cmake.in @@ -30,20 +30,20 @@ if(NOT DEFINED CMAKE_INSTALL_PREFIX) endif() message(${CMAKE_INSTALL_PREFIX}) -file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") -foreach(file ${files}) - message(STATUS "Uninstalling $ENV{DESTDIR}${file}") - if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" _files) +string(REGEX REPLACE "\n" ";" _files "${_files}") +foreach(_file ${_files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${_file}") + if(IS_SYMLINK "$ENV{DESTDIR}${_file}" OR EXISTS "$ENV{DESTDIR}${_file}") exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${_file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval - ) + ) if(NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${_file}") endif() else() - message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + message(STATUS "File $ENV{DESTDIR}${_file} does not exist.") endif() endforeach() diff --git a/CMake/curl-config.cmake.in b/CMake/curl-config.cmake.in index 2ce8625ef..7dc1f99f0 100644 --- a/CMake/curl-config.cmake.in +++ b/CMake/curl-config.cmake.in @@ -23,6 +23,14 @@ ########################################################################### @PACKAGE_INIT@ +if(NOT DEFINED CURL_USE_PKGCONFIG) + if(UNIX OR (MSVC AND VCPKG_TOOLCHAIN)) # Keep in sync with root CMakeLists.txt + set(CURL_USE_PKGCONFIG ON) + else() + set(CURL_USE_PKGCONFIG OFF) + endif() +endif() + include(CMakeFindDependencyMacro) if(@USE_OPENSSL@) find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@) diff --git a/CMakeLists.txt b/CMakeLists.txt index 580cc4357..f8e9c25eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,11 +24,11 @@ # by Tetetest and Sukender (Benoit Neil) # Note: By default this CMake build script detects the version of some -# dependencies using `check_symbol_exists`. Those checks do not work -# in the case that both CURL and its dependency are included as -# sub-projects in a larger build using `FetchContent`. To support -# that case, additional variables may be defined by the parent -# project, ideally in the "extra" find package redirect file: +# dependencies using `check_symbol_exists`. Those checks do not work in +# the case that both CURL and its dependency are included as sub-projects +# in a larger build using `FetchContent`. To support that case, additional +# variables may be defined by the parent project, ideally in the "extra" +# find package redirect file: # https://cmake.org/cmake/help/latest/module/FetchContent.html#integrating-with-find-package # # The following variables are available: @@ -36,16 +36,33 @@ # HAVE_OPENSSL_SRP: `SSL_CTX_set_srp_username` present in OpenSSL/wolfSSL # HAVE_GNUTLS_SRP: `gnutls_srp_verifier` present in GnuTLS # HAVE_SSL_CTX_SET_QUIC_METHOD: `SSL_CTX_set_quic_method` present in OpenSSL/wolfSSL -# HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in QUICHE +# HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in quiche # HAVE_ECH: ECH API checks for OpenSSL, BoringSSL or wolfSSL # # For each of the above variables, if the variable is DEFINED (either -# to ON or OFF), the symbol detection will be skipped. If the -# variable is NOT DEFINED, the symbol detection will be performed. +# to ON or OFF), the symbol detection is skipped. If the variable is +# NOT DEFINED, the symbol detection is performed. cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR) message(STATUS "Using CMake version ${CMAKE_VERSION}") +# Collect command-line arguments for buildinfo.txt. +# Must reside at the top of the script to work as expected. +get_cmake_property(_cache_vars CACHE_VARIABLES) +unset(_cmake_args) +foreach(_cache_var ${_cache_vars}) + get_property(_cache_var_helpstring CACHE ${_cache_var} PROPERTY HELPSTRING) + if(_cache_var_helpstring STREQUAL "No help, variable specified on the command line.") + get_property(_cache_var_type CACHE ${_cache_var} PROPERTY TYPE) + if(_cache_var_type STREQUAL "UNINITIALIZED") + set(_cache_var_type) + else() + set(_cache_var_type ":${_cache_var_type}") + endif() + set(_cmake_args "${_cmake_args} -D${_cache_var}${_cache_var_type}=\"${${_cache_var}}\"") + endif() +endforeach() + set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") include(Utilities) include(Macros) @@ -54,76 +71,140 @@ include(CheckCCompilerFlag) project(CURL C) -file(STRINGS ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )") -string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" - CURL_VERSION ${CURL_VERSION_H_CONTENTS}) +unset(_target_flags) +if(APPLE) + set(_target_flags "${_target_flags} APPLE") +endif() +if(UNIX) + set(_target_flags "${_target_flags} UNIX") +endif() +if(WIN32) + set(_target_flags "${_target_flags} WIN32") +endif() +if(CYGWIN) + set(_target_flags "${_target_flags} CYGWIN") +endif() +if(MSYS) + set(_target_flags "${_target_flags} MSYS") +endif() +if(CMAKE_COMPILER_IS_GNUCC) + set(_target_flags "${_target_flags} GCC") +endif() +if(MINGW) + set(_target_flags "${_target_flags} MINGW") +endif() +if(MSVC) + set(_target_flags "${_target_flags} MSVC") +endif() +if(VCPKG_TOOLCHAIN) + set(_target_flags "${_target_flags} VCPKG") +endif() +if(CMAKE_CROSSCOMPILING) + set(_target_flags "${_target_flags} CROSS") +endif() +message(STATUS "CMake platform flags:${_target_flags}") + +if(CMAKE_CROSSCOMPILING) + message(STATUS "Cross-compiling: " + "${CMAKE_HOST_SYSTEM_NAME}/${CMAKE_HOST_SYSTEM_PROCESSOR} -> " + "${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}") +endif() + +function(curl_dumpvars) # Dump all defined variables with their values + message("::group::CMake Variable Dump") + get_cmake_property(_vars VARIABLES) + foreach(_var ${_vars}) + message("${_var} = ${${_var}}") + endforeach() + message("::endgroup::") +endfunction() + +file(STRINGS "${CURL_SOURCE_DIR}/include/curl/curlver.h" _curl_version_h_contents REGEX "#define LIBCURL_VERSION( |_NUM )") +string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" CURL_VERSION ${_curl_version_h_contents}) string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION}) -string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" - CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS}) +string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" CURL_VERSION_NUM ${_curl_version_h_contents}) string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM}) +unset(_curl_version_h_contents) - -# Setup package meta-data -# set(PACKAGE "curl") message(STATUS "curl version=[${CURL_VERSION}]") -# set(PACKAGE_TARNAME "curl") -# set(PACKAGE_NAME "curl") -# set(PACKAGE_VERSION "-") -# set(PACKAGE_STRING "curl-") -# set(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/") -set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}") + if(CMAKE_C_COMPILER_TARGET) set(OS "\"${CMAKE_C_COMPILER_TARGET}\"") else() set(OS "\"${CMAKE_SYSTEM_NAME}\"") endif() -include_directories(${CURL_SOURCE_DIR}/include) +include_directories("${CURL_SOURCE_DIR}/include") -set(CMAKE_UNITY_BUILD_BATCH_SIZE 0) +if(NOT DEFINED CMAKE_UNITY_BUILD_BATCH_SIZE) + set(CMAKE_UNITY_BUILD_BATCH_SIZE 0) +endif() option(CURL_WERROR "Turn compiler warnings into errors" OFF) option(PICKY_COMPILER "Enable picky compiler options" ON) -option(BUILD_CURL_EXE "Set to ON to build curl executable." ON) +option(BUILD_CURL_EXE "Build curl executable" ON) option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(BUILD_STATIC_LIBS "Build static libraries" OFF) option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF) -option(ENABLE_ARES "Set to ON to enable c-ares support" OFF) -option(CURL_DISABLE_INSTALL "Set to ON to disable installation targets" OFF) +option(ENABLE_ARES "Enable c-ares support" OFF) +option(CURL_DISABLE_INSTALL "Disable installation targets" OFF) if(WIN32) - option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF) - option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF) - set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string") - if(CURL_TARGET_WINDOWS_VERSION) - add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}) - set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}") + option(CURL_STATIC_CRT "Build libcurl with static CRT on Windows (/MT)" OFF) + if(CURL_STATIC_CRT) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") endif() + + option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF) if(ENABLE_UNICODE) - add_definitions(-DUNICODE -D_UNICODE) + add_definitions("-DUNICODE" "-D_UNICODE") if(MINGW) - add_compile_options(-municode) + add_compile_options("-municode") endif() endif() + + set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string") + if(CURL_TARGET_WINDOWS_VERSION) + add_definitions("-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}") + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}") + set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}") + endif() + + # Detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT + curl_internal_test(HAVE_WIN32_WINNT) + if(HAVE_WIN32_WINNT) + string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" CURL_TEST_OUTPUT "${CURL_TEST_OUTPUT}") + string(REGEX REPLACE ".*_WIN32_WINNT=" "" CURL_TEST_OUTPUT "${CURL_TEST_OUTPUT}") + string(REGEX REPLACE "0x([0-9a-f][0-9a-f][0-9a-f])$" "0x0\\1" CURL_TEST_OUTPUT "${CURL_TEST_OUTPUT}") # pad to 4 digits + string(TOLOWER "${CURL_TEST_OUTPUT}" HAVE_WIN32_WINNT) + message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}") + endif() + # Avoid storing HAVE_WIN32_WINNT in CMake cache + unset(HAVE_WIN32_WINNT CACHE) endif() -option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF) +option(CURL_LTO "Enable compiler Link Time Optimizations" OFF) -cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup" +cmake_dependent_option(ENABLE_THREADED_RESOLVER "Enable threaded DNS lookup" ON "NOT ENABLE_ARES" OFF) include(PickyWarnings) -option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF) -option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" ${ENABLE_DEBUG}) +option(ENABLE_DEBUG "Enable curl debug features" OFF) +option(ENABLE_CURLDEBUG "Enable TrackMemory feature" ${ENABLE_DEBUG}) + +if(MSVC) + set(ENABLE_CURLDEBUG OFF) # FIXME: TrackMemory + MSVC fails test 558 and 1330. Tested with static build, Debug mode. +endif() if(ENABLE_DEBUG) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS DEBUGBUILD) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "DEBUGBUILD") endif() if(ENABLE_CURLDEBUG) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "CURLDEBUG") endif() # For debug libs and exes, add "-d" postfix @@ -143,122 +224,141 @@ elseif(BUILD_STATIC_CURL AND NOT BUILD_STATIC_LIBS) set(BUILD_STATIC_CURL OFF) endif() -# lib flavour selected for curl tool +# Lib flavour selected for curl tool if(BUILD_STATIC_CURL) set(LIB_SELECTED_FOR_EXE ${LIB_STATIC}) else() set(LIB_SELECTED_FOR_EXE ${LIB_SHARED}) endif() -# lib flavour selected for example and test programs. +# Lib flavour selected for example and test programs. if(BUILD_SHARED_LIBS) set(LIB_SELECTED ${LIB_SHARED}) else() set(LIB_SELECTED ${LIB_STATIC}) endif() -# initialize CURL_LIBS +# Override to force-disable or force-enable the use of pkg-config. +if(UNIX OR (MSVC AND VCPKG_TOOLCHAIN)) # Keep in sync with CMake/curl-config.cmake.in + set(_curl_use_pkgconfig_default ON) +else() + set(_curl_use_pkgconfig_default OFF) +endif() +option(CURL_USE_PKGCONFIG "Enable pkg-config to detect dependencies" ${_curl_use_pkgconfig_default}) + +# Initialize CURL_LIBS set(CURL_LIBS "") +set(CURL_LIBDIRS "") set(LIBCURL_PC_REQUIRES_PRIVATE "") if(ENABLE_ARES) set(USE_ARES 1) - find_package(CARES REQUIRED) - list(APPEND CURL_LIBS ${CARES_LIBRARY}) + find_package(Cares REQUIRED) + list(APPEND CURL_LIBS ${CARES_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libcares") + add_definitions("-DCARES_NO_DEPRECATED") # Ignore c-ares deprecation warnings endif() include(CurlSymbolHiding) -option(CURL_ENABLE_EXPORT_TARGET "to enable cmake export target" ON) +option(CURL_ENABLE_EXPORT_TARGET "Enable CMake export target" ON) mark_as_advanced(CURL_ENABLE_EXPORT_TARGET) -option(CURL_DISABLE_ALTSVC "disables alt-svc support" OFF) +option(CURL_DISABLE_ALTSVC "Disable alt-svc support" OFF) mark_as_advanced(CURL_DISABLE_ALTSVC) -option(CURL_DISABLE_SRP "disables TLS-SRP support" OFF) +option(CURL_DISABLE_SRP "Disable TLS-SRP support" OFF) mark_as_advanced(CURL_DISABLE_SRP) -option(CURL_DISABLE_COOKIES "disables cookies support" OFF) +option(CURL_DISABLE_COOKIES "Disable cookies support" OFF) mark_as_advanced(CURL_DISABLE_COOKIES) -option(CURL_DISABLE_BASIC_AUTH "disables Basic authentication" OFF) +option(CURL_DISABLE_BASIC_AUTH "Disable Basic authentication" OFF) mark_as_advanced(CURL_DISABLE_BASIC_AUTH) -option(CURL_DISABLE_BEARER_AUTH "disables Bearer authentication" OFF) +option(CURL_DISABLE_BEARER_AUTH "Disable Bearer authentication" OFF) mark_as_advanced(CURL_DISABLE_BEARER_AUTH) -option(CURL_DISABLE_DIGEST_AUTH "disables Digest authentication" OFF) +option(CURL_DISABLE_DIGEST_AUTH "Disable Digest authentication" OFF) mark_as_advanced(CURL_DISABLE_DIGEST_AUTH) -option(CURL_DISABLE_KERBEROS_AUTH "disables Kerberos authentication" OFF) +option(CURL_DISABLE_KERBEROS_AUTH "Disable Kerberos authentication" OFF) mark_as_advanced(CURL_DISABLE_KERBEROS_AUTH) -option(CURL_DISABLE_NEGOTIATE_AUTH "disables negotiate authentication" OFF) +option(CURL_DISABLE_NEGOTIATE_AUTH "Disable negotiate authentication" OFF) mark_as_advanced(CURL_DISABLE_NEGOTIATE_AUTH) -option(CURL_DISABLE_AWS "disables AWS-SIG4" OFF) +option(CURL_DISABLE_AWS "Disable AWS-SIG4" OFF) mark_as_advanced(CURL_DISABLE_AWS) -option(CURL_DISABLE_DICT "disables DICT" OFF) +option(CURL_DISABLE_DICT "Disable DICT" OFF) mark_as_advanced(CURL_DISABLE_DICT) -option(CURL_DISABLE_DOH "disables DNS-over-HTTPS" OFF) +option(CURL_DISABLE_DOH "Disable DNS-over-HTTPS" OFF) mark_as_advanced(CURL_DISABLE_DOH) -option(CURL_DISABLE_FILE "disables FILE" OFF) +option(CURL_DISABLE_FILE "Disable FILE" OFF) mark_as_advanced(CURL_DISABLE_FILE) -cmake_dependent_option(CURL_DISABLE_FORM_API "disables form api" OFF - "NOT CURL_DISABLE_MIME" ON) +cmake_dependent_option(CURL_DISABLE_FORM_API "Disable form-api" + OFF "NOT CURL_DISABLE_MIME" + ON) mark_as_advanced(CURL_DISABLE_FORM_API) -option(CURL_DISABLE_FTP "disables FTP" OFF) +option(CURL_DISABLE_FTP "Disable FTP" OFF) mark_as_advanced(CURL_DISABLE_FTP) -option(CURL_DISABLE_GETOPTIONS "disables curl_easy_options API for existing options to curl_easy_setopt" OFF) +option(CURL_DISABLE_GETOPTIONS "Disable curl_easy_options API for existing options to curl_easy_setopt" OFF) mark_as_advanced(CURL_DISABLE_GETOPTIONS) -option(CURL_DISABLE_GOPHER "disables Gopher" OFF) +option(CURL_DISABLE_GOPHER "Disable Gopher" OFF) mark_as_advanced(CURL_DISABLE_GOPHER) -option(CURL_DISABLE_HEADERS_API "disables headers-api support" OFF) +option(CURL_DISABLE_HEADERS_API "Disable headers-api support" OFF) mark_as_advanced(CURL_DISABLE_HEADERS_API) -option(CURL_DISABLE_HSTS "disables HSTS support" OFF) +option(CURL_DISABLE_HSTS "Disable HSTS support" OFF) mark_as_advanced(CURL_DISABLE_HSTS) -option(CURL_DISABLE_HTTP "disables HTTP" OFF) +option(CURL_DISABLE_HTTP "Disable HTTP" OFF) mark_as_advanced(CURL_DISABLE_HTTP) -option(CURL_DISABLE_HTTP_AUTH "disables all HTTP authentication methods" OFF) +option(CURL_DISABLE_HTTP_AUTH "Disable all HTTP authentication methods" OFF) mark_as_advanced(CURL_DISABLE_HTTP_AUTH) -option(CURL_DISABLE_IMAP "disables IMAP" OFF) +option(CURL_DISABLE_IMAP "Disable IMAP" OFF) mark_as_advanced(CURL_DISABLE_IMAP) -option(CURL_DISABLE_LDAP "disables LDAP" OFF) +option(CURL_DISABLE_LDAP "Disable LDAP" OFF) mark_as_advanced(CURL_DISABLE_LDAP) -option(CURL_DISABLE_LDAPS "disables LDAPS" OFF) +option(CURL_DISABLE_LDAPS "Disable LDAPS" ${CURL_DISABLE_LDAP}) mark_as_advanced(CURL_DISABLE_LDAPS) -option(CURL_DISABLE_LIBCURL_OPTION "disables --libcurl option from the curl tool" OFF) +option(CURL_DISABLE_LIBCURL_OPTION "Disable --libcurl option from the curl tool" OFF) mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION) -option(CURL_DISABLE_MIME "disables MIME support" OFF) +option(CURL_DISABLE_MIME "Disable MIME support" OFF) mark_as_advanced(CURL_DISABLE_MIME) -option(CURL_DISABLE_MQTT "disables MQTT" OFF) +option(CURL_DISABLE_MQTT "Disable MQTT" OFF) mark_as_advanced(CURL_DISABLE_BINDLOCAL) -option(CURL_DISABLE_BINDLOCAL "disables local binding support" OFF) +option(CURL_DISABLE_BINDLOCAL "Disable local binding support" OFF) mark_as_advanced(CURL_DISABLE_MQTT) -option(CURL_DISABLE_NETRC "disables netrc parser" OFF) +option(CURL_DISABLE_NETRC "Disable netrc parser" OFF) mark_as_advanced(CURL_DISABLE_NETRC) -option(CURL_DISABLE_NTLM "disables NTLM support" OFF) +option(CURL_DISABLE_NTLM "Disable NTLM support" OFF) mark_as_advanced(CURL_DISABLE_NTLM) -option(CURL_DISABLE_PARSEDATE "disables date parsing" OFF) +option(CURL_DISABLE_PARSEDATE "Disable date parsing" OFF) mark_as_advanced(CURL_DISABLE_PARSEDATE) -option(CURL_DISABLE_POP3 "disables POP3" OFF) +option(CURL_DISABLE_POP3 "Disable POP3" OFF) mark_as_advanced(CURL_DISABLE_POP3) -option(CURL_DISABLE_PROGRESS_METER "disables built-in progress meter" OFF) +option(CURL_DISABLE_PROGRESS_METER "Disable built-in progress meter" OFF) mark_as_advanced(CURL_DISABLE_PROGRESS_METER) -option(CURL_DISABLE_PROXY "disables proxy support" OFF) +option(CURL_DISABLE_PROXY "Disable proxy support" OFF) mark_as_advanced(CURL_DISABLE_PROXY) -option(CURL_DISABLE_RTSP "disables RTSP" OFF) +option(CURL_DISABLE_RTSP "Disable RTSP" OFF) +mark_as_advanced(CURL_DISABLE_SHA512_256) +option(CURL_DISABLE_SHA512_256 "Disable SHA-512/256 hash algorithm" OFF) mark_as_advanced(CURL_DISABLE_RTSP) -option(CURL_DISABLE_SHUFFLE_DNS "disables shuffle DNS feature" OFF) +option(CURL_DISABLE_SHUFFLE_DNS "Disable shuffle DNS feature" OFF) mark_as_advanced(CURL_DISABLE_SHUFFLE_DNS) -option(CURL_DISABLE_SMB "disables SMB" OFF) +option(CURL_DISABLE_SMB "Disable SMB" OFF) mark_as_advanced(CURL_DISABLE_SMB) -option(CURL_DISABLE_SMTP "disables SMTP" OFF) +option(CURL_DISABLE_SMTP "Disable SMTP" OFF) mark_as_advanced(CURL_DISABLE_SMTP) -option(CURL_DISABLE_SOCKETPAIR "disables use of socketpair for curl_multi_poll" OFF) +option(CURL_DISABLE_SOCKETPAIR "Disable use of socketpair for curl_multi_poll" OFF) mark_as_advanced(CURL_DISABLE_SOCKETPAIR) -option(CURL_DISABLE_TELNET "disables Telnet" OFF) +option(CURL_DISABLE_TELNET "Disable Telnet" OFF) mark_as_advanced(CURL_DISABLE_TELNET) -option(CURL_DISABLE_TFTP "disables TFTP" OFF) +option(CURL_DISABLE_TFTP "Disable TFTP" OFF) mark_as_advanced(CURL_DISABLE_TFTP) -option(CURL_DISABLE_VERBOSE_STRINGS "disables verbose strings" OFF) +option(CURL_DISABLE_VERBOSE_STRINGS "Disable verbose strings" OFF) mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS) +if(CURL_DISABLE_HTTP) + set(CURL_DISABLE_RTSP ON) + set(CURL_DISABLE_ALTSVC ON) + set(CURL_DISABLE_HSTS ON) +endif() + # Corresponds to HTTP_ONLY in lib/curl_setup.h -option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF) +option(HTTP_ONLY "Disable all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF) mark_as_advanced(HTTP_ONLY) if(HTTP_ONLY) @@ -282,25 +382,25 @@ if(WINDOWS_STORE) set(CURL_DISABLE_TELNET ON) # telnet code needs fixing to compile for UWP. endif() -option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON) +option(ENABLE_IPV6 "Enable IPv6 support" ON) mark_as_advanced(ENABLE_IPV6) if(ENABLE_IPV6 AND NOT WIN32) include(CheckStructHasMember) - check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h" + check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR) - check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h" + check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR) message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support") # Force the feature off as this name is used as guard macro... - set(ENABLE_IPV6 OFF - CACHE BOOL "Define if you want to enable IPv6 support" FORCE) + set(ENABLE_IPV6 OFF CACHE BOOL "Enable IPv6 support" FORCE) endif() if(APPLE AND NOT ENABLE_ARES) - set(use_core_foundation_and_core_services ON) + set(_use_core_foundation_and_core_services ON) find_library(SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration") + mark_as_advanced(SYSTEMCONFIGURATION_FRAMEWORK) if(NOT SYSTEMCONFIGURATION_FRAMEWORK) message(FATAL_ERROR "SystemConfiguration framework not found") endif() @@ -314,9 +414,9 @@ endif() find_package(Perl) -option(BUILD_LIBCURL_DOCS "to build libcurl man pages" ON) -option(BUILD_MISC_DOCS "to build misc man pages (e.g. curl-config and mk-ca-bundle)" ON) -option(ENABLE_CURL_MANUAL "to build the man page for curl and enable its -M/--manual option" ON) +option(BUILD_LIBCURL_DOCS "Build libcurl man pages" ON) +option(BUILD_MISC_DOCS "Build misc man pages (e.g. curl-config and mk-ca-bundle)" ON) +option(ENABLE_CURL_MANUAL "Build the man page for curl and enable its -M/--manual option" ON) if(ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS) if(PERL_FOUND) @@ -327,25 +427,19 @@ if(ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS) endif() endif() -if(CURL_STATIC_CRT) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") -endif() - # Disable warnings on Borland to avoid changing 3rd party code. if(BORLAND) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-") endif() # If we are on AIX, do the _ALL_SOURCE magic -if(${CMAKE_SYSTEM_NAME} MATCHES AIX) - set(_ALL_SOURCE 1) +if(CMAKE_SYSTEM_NAME STREQUAL "AIX") + add_definitions("-D_ALL_SOURCE") endif() # If we are on Haiku, make sure that the network library is brought in. -if(${CMAKE_SYSTEM_NAME} MATCHES Haiku) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lnetwork") +if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") + list(APPEND CURL_LIBS "network") endif() # Include all the necessary files for macros @@ -358,7 +452,7 @@ include(CheckSymbolExists) include(CheckTypeSize) include(CheckCSourceCompiles) -# On windows preload settings +# Preload settings on Windows if(WIN32) include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake) endif() @@ -370,7 +464,7 @@ if(ENABLE_THREADED_RESOLVER) find_package(Threads REQUIRED) set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT}) set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT}) - set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND CURL_LIBS ${CMAKE_THREAD_LIBS_INIT}) endif() endif() @@ -380,17 +474,17 @@ if(HAVE_LIBSOCKET) set(CURL_LIBS "socket;${CURL_LIBS}") endif() -check_function_exists(gethostname HAVE_GETHOSTNAME) +check_function_exists("gethostname" HAVE_GETHOSTNAME) if(WIN32) list(APPEND CURL_LIBS "ws2_32" "bcrypt") endif() -# check SSL libraries +# Check SSL libraries option(CURL_ENABLE_SSL "Enable SSL support" ON) if(CURL_DEFAULT_SSL_BACKEND) - set(valid_default_ssl_backend FALSE) + set(_valid_default_ssl_backend FALSE) endif() if(APPLE) @@ -404,33 +498,38 @@ cmake_dependent_option(CURL_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF CURL_EN cmake_dependent_option(CURL_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF) cmake_dependent_option(CURL_USE_WOLFSSL "Enable wolfSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF) cmake_dependent_option(CURL_USE_GNUTLS "Enable GnuTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF) +cmake_dependent_option(CURL_USE_RUSTLS "Enable Rustls for SSL/TLS" OFF CURL_ENABLE_SSL OFF) -set(openssl_default ON) +set(_openssl_default ON) if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL) - set(openssl_default OFF) + set(_openssl_default OFF) endif() -cmake_dependent_option(CURL_USE_OPENSSL "Enable OpenSSL for SSL/TLS" ${openssl_default} CURL_ENABLE_SSL OFF) +cmake_dependent_option(CURL_USE_OPENSSL "Enable OpenSSL for SSL/TLS" ${_openssl_default} CURL_ENABLE_SSL OFF) option(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG "Disable automatic loading of OpenSSL configuration" OFF) -count_true(enabled_ssl_options_count +count_true(_enabled_ssl_options_count CURL_USE_SCHANNEL CURL_USE_SECTRANSP CURL_USE_OPENSSL CURL_USE_MBEDTLS CURL_USE_BEARSSL CURL_USE_WOLFSSL + CURL_USE_GNUTLS + CURL_USE_RUSTLS ) -if(enabled_ssl_options_count GREATER "1") +if(_enabled_ssl_options_count GREATER 1) set(CURL_WITH_MULTI_SSL ON) +elseif(_enabled_ssl_options_count EQUAL 0) + set(CURL_DISABLE_HSTS ON) endif() if(CURL_USE_SCHANNEL) - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_SCHANNEL ON) # Windows native SSL/TLS support set(USE_WINDOWS_SSPI ON) # CURL_USE_SCHANNEL implies CURL_WINDOWS_SSPI if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "schannel") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() endif() if(CURL_WINDOWS_SSPI) @@ -438,25 +537,30 @@ if(CURL_WINDOWS_SSPI) endif() if(CURL_USE_SECTRANSP) - set(use_core_foundation_and_core_services ON) + set(_use_core_foundation_and_core_services ON) find_library(SECURITY_FRAMEWORK "Security") + mark_as_advanced(SECURITY_FRAMEWORK) if(NOT SECURITY_FRAMEWORK) message(FATAL_ERROR "Security framework not found") endif() - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_SECTRANSP ON) list(APPEND CURL_LIBS "-framework Security") if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "secure-transport") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() + + message(WARNING "Secure Transport does not support TLS 1.3.") endif() -if(use_core_foundation_and_core_services) +if(_use_core_foundation_and_core_services) find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation") + mark_as_advanced(COREFOUNDATION_FRAMEWORK) find_library(CORESERVICES_FRAMEWORK "CoreServices") + mark_as_advanced(CORESERVICES_FRAMEWORK) if(NOT COREFOUNDATION_FRAMEWORK) message(FATAL_ERROR "CoreFoundation framework not found") @@ -470,99 +574,123 @@ endif() if(CURL_USE_OPENSSL) find_package(OpenSSL REQUIRED) - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_OPENSSL ON) - # Depend on OpenSSL via imported targets if supported by the running - # version of CMake. This allows our dependents to get our dependencies - # transitively. - if(NOT CMAKE_VERSION VERSION_LESS 3.4) - list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto) - else() - list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) - include_directories(${OPENSSL_INCLUDE_DIR}) - endif() + # Depend on OpenSSL via imported targets. This allows our dependents to + # get our dependencies transitively. + list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "openssl") if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() - set(curl_ca_bundle_supported TRUE) + set(_curl_ca_bundle_supported TRUE) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) if(NOT DEFINED HAVE_BORINGSSL) - check_symbol_exists(OPENSSL_IS_BORINGSSL "openssl/base.h" HAVE_BORINGSSL) + check_symbol_exists("OPENSSL_IS_BORINGSSL" "openssl/base.h" HAVE_BORINGSSL) endif() if(NOT DEFINED HAVE_AWSLC) - check_symbol_exists(OPENSSL_IS_AWSLC "openssl/base.h" HAVE_AWSLC) + check_symbol_exists("OPENSSL_IS_AWSLC" "openssl/base.h" HAVE_AWSLC) endif() endif() if(CURL_USE_MBEDTLS) find_package(MbedTLS REQUIRED) - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_MBEDTLS ON) list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "mbedtls") include_directories(${MBEDTLS_INCLUDE_DIRS}) if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() - set(curl_ca_bundle_supported TRUE) + set(_curl_ca_bundle_supported TRUE) endif() if(CURL_USE_BEARSSL) find_package(BearSSL REQUIRED) - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_BEARSSL ON) - list(APPEND CURL_LIBS ${BEARSSL_LIBRARY}) + list(APPEND CURL_LIBS ${BEARSSL_LIBRARIES}) include_directories(${BEARSSL_INCLUDE_DIRS}) if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "bearssl") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() - set(curl_ca_bundle_supported TRUE) + set(_curl_ca_bundle_supported TRUE) + + message(WARNING "BearSSL does not support TLS 1.3.") endif() if(CURL_USE_WOLFSSL) find_package(WolfSSL REQUIRED) - set(SSL_ENABLED ON) + set(_ssl_enabled ON) set(USE_WOLFSSL ON) - list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES}) + list(APPEND CURL_LIBS ${WOLFSSL_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "wolfssl") - include_directories(${WolfSSL_INCLUDE_DIRS}) + include_directories(${WOLFSSL_INCLUDE_DIRS}) if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() - set(curl_ca_bundle_supported TRUE) + set(_curl_ca_bundle_supported TRUE) endif() if(CURL_USE_GNUTLS) - find_package(GnuTLS REQUIRED) - find_package(nettle REQUIRED) - set(SSL_ENABLED ON) + if(CURL_USE_PKGCONFIG) + find_package(PkgConfig QUIET) + pkg_check_modules(GNUTLS "gnutls") + if(GNUTLS_FOUND) + set(GNUTLS_LIBRARIES ${GNUTLS_LINK_LIBRARIES}) + endif() + endif() + if(NOT GNUTLS_FOUND) + find_package(GnuTLS REQUIRED) + endif() + find_package(Nettle REQUIRED) + set(_ssl_enabled ON) set(USE_GNUTLS ON) list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES}) + list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" "nettle") include_directories(${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS}) + link_directories(${NETTLE_LIBRARY_DIRS}) + if(NETTLE_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NETTLE_CFLAGS}") + endif() if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls") - set(valid_default_ssl_backend TRUE) + set(_valid_default_ssl_backend TRUE) endif() - set(curl_ca_bundle_supported TRUE) + set(_curl_ca_bundle_supported TRUE) if(NOT DEFINED HAVE_GNUTLS_SRP AND NOT CURL_DISABLE_SRP) cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES}) - check_symbol_exists(gnutls_srp_verifier "gnutls/gnutls.h" HAVE_GNUTLS_SRP) + check_symbol_exists("gnutls_srp_verifier" "gnutls/gnutls.h" HAVE_GNUTLS_SRP) cmake_pop_check_state() endif() endif() -if(CURL_DEFAULT_SSL_BACKEND AND NOT valid_default_ssl_backend) +if(CURL_USE_RUSTLS) + find_package(Rustls REQUIRED) + set(_ssl_enabled ON) + set(USE_RUSTLS ON) + list(APPEND CURL_LIBS ${RUSTLS_LIBRARIES}) + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "rustls") + include_directories(${RUSTLS_INCLUDE_DIRS}) + + if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "rustls") + set(_valid_default_ssl_backend TRUE) + endif() + set(_curl_ca_bundle_supported TRUE) +endif() + +if(CURL_DEFAULT_SSL_BACKEND AND NOT _valid_default_ssl_backend) message(FATAL_ERROR "CURL_DEFAULT_SSL_BACKEND '${CURL_DEFAULT_SSL_BACKEND}' not enabled.") endif() @@ -576,20 +704,14 @@ if(ZLIB_FOUND) set(HAVE_LIBZ ON) set(USE_ZLIB ON) - # Depend on ZLIB via imported targets if supported by the running - # version of CMake. This allows our dependents to get our dependencies - # transitively. - if(NOT CMAKE_VERSION VERSION_LESS 3.4) - list(APPEND CURL_LIBS ZLIB::ZLIB) - else() - list(APPEND CURL_LIBS ${ZLIB_LIBRARIES}) - include_directories(${ZLIB_INCLUDE_DIRS}) - endif() + # Depend on ZLIB via imported targets. This allows our dependents to + # get our dependencies transitively. + list(APPEND CURL_LIBS ZLIB::ZLIB) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "zlib") list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) endif() -option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF) +option(CURL_BROTLI "Use brotli" OFF) set(HAVE_BROTLI OFF) if(CURL_BROTLI) find_package(Brotli REQUIRED) @@ -602,22 +724,22 @@ if(CURL_BROTLI) endif() endif() -option(CURL_ZSTD "Set to ON to enable building curl with zstd support." OFF) +option(CURL_ZSTD "Use zstd" OFF) set(HAVE_ZSTD OFF) if(CURL_ZSTD) find_package(Zstd REQUIRED) - if(Zstd_FOUND AND NOT Zstd_VERSION VERSION_LESS "1.0.0") + if(ZSTD_FOUND AND NOT ZSTD_VERSION VERSION_LESS 1.0.0) set(HAVE_ZSTD ON) - list(APPEND CURL_LIBS ${Zstd_LIBRARIES}) + list(APPEND CURL_LIBS ${ZSTD_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libzstd") - include_directories(${Zstd_INCLUDE_DIRS}) + include_directories(${ZSTD_INCLUDE_DIRS}) else() message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.") endif() endif() -# Check symbol in an OpenSSL-like TLS backend, or in EXTRA_LIBS depending on it. -macro(openssl_check_symbol_exists SYMBOL FILES VARIABLE EXTRA_LIBS) +# Check symbol in an OpenSSL-like TLS backend, or in _extra_libs depending on it. +macro(openssl_check_symbol_exists _symbol _files _variable _extra_libs) cmake_push_check_state() if(USE_OPENSSL) set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") @@ -630,8 +752,8 @@ macro(openssl_check_symbol_exists SYMBOL FILES VARIABLE EXTRA_LIBS) list(APPEND CMAKE_REQUIRED_LIBRARIES "bcrypt") # for OpenSSL/LibreSSL endif() elseif(USE_WOLFSSL) - set(CMAKE_REQUIRED_INCLUDES "${WolfSSL_INCLUDE_DIRS}") - set(CMAKE_REQUIRED_LIBRARIES "${WolfSSL_LIBRARIES}") + set(CMAKE_REQUIRED_INCLUDES "${WOLFSSL_INCLUDE_DIRS}") + set(CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}") if(HAVE_LIBZ) list(APPEND CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIRS}") # Public wolfSSL headers require zlib headers list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}") @@ -639,12 +761,10 @@ macro(openssl_check_symbol_exists SYMBOL FILES VARIABLE EXTRA_LIBS) if(WIN32) list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "crypt32") endif() - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_UINTPTR_T) # to pull in stdint.h (as of wolfSSL v5.5.4) - endif() - if(NOT "${EXTRA_LIBS}" STREQUAL "") - list(APPEND CMAKE_REQUIRED_LIBRARIES "${EXTRA_LIBS}") + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DHAVE_UINTPTR_T") # to pull in stdint.h (as of wolfSSL v5.5.4) endif() - check_symbol_exists("${SYMBOL}" "${FILES}" "${VARIABLE}") + list(APPEND CMAKE_REQUIRED_LIBRARIES "${_extra_libs}") + check_symbol_exists("${_symbol}" "${_files}" "${_variable}") cmake_pop_check_state() endmacro() @@ -652,9 +772,10 @@ endmacro() macro(openssl_check_quic) if(NOT DEFINED HAVE_SSL_CTX_SET_QUIC_METHOD) if(USE_OPENSSL) - openssl_check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD "") + openssl_check_symbol_exists("SSL_CTX_set_quic_method" "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD "") elseif(USE_WOLFSSL) - openssl_check_symbol_exists(wolfSSL_set_quic_method "wolfssl/options.h;wolfssl/openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD "") + openssl_check_symbol_exists("wolfSSL_set_quic_method" "wolfssl/options.h;wolfssl/openssl/ssl.h" + HAVE_SSL_CTX_SET_QUIC_METHOD "") endif() endif() if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD) @@ -663,16 +784,16 @@ macro(openssl_check_quic) endmacro() if(USE_WOLFSSL) - openssl_check_symbol_exists(wolfSSL_DES_ecb_encrypt "wolfssl/openssl/des.h" HAVE_WOLFSSL_DES_ECB_ENCRYPT "") - openssl_check_symbol_exists(wolfSSL_BIO_set_shutdown "wolfssl/ssl.h" HAVE_WOLFSSL_FULL_BIO "") + openssl_check_symbol_exists("wolfSSL_DES_ecb_encrypt" "wolfssl/openssl/des.h" HAVE_WOLFSSL_DES_ECB_ENCRYPT "") + openssl_check_symbol_exists("wolfSSL_BIO_set_shutdown" "wolfssl/ssl.h" HAVE_WOLFSSL_FULL_BIO "") endif() if(USE_OPENSSL OR USE_WOLFSSL) if(NOT DEFINED HAVE_SSL_SET0_WBIO) - openssl_check_symbol_exists(SSL_set0_wbio "openssl/ssl.h" HAVE_SSL_SET0_WBIO "") + openssl_check_symbol_exists("SSL_set0_wbio" "openssl/ssl.h" HAVE_SSL_SET0_WBIO "") endif() if(NOT DEFINED HAVE_OPENSSL_SRP AND NOT CURL_DISABLE_SRP) - openssl_check_symbol_exists(SSL_CTX_set_srp_username "openssl/ssl.h" HAVE_OPENSSL_SRP "") + openssl_check_symbol_exists("SSL_CTX_set_srp_username" "openssl/ssl.h" HAVE_OPENSSL_SRP "") endif() endif() @@ -683,11 +804,11 @@ if(USE_ECH) # Be sure that the TLS library actually supports ECH. if(NOT DEFINED HAVE_ECH) if(USE_OPENSSL AND HAVE_BORINGSSL) - openssl_check_symbol_exists(SSL_set1_ech_config_list "openssl/ssl.h" HAVE_ECH "") + openssl_check_symbol_exists("SSL_set1_ech_config_list" "openssl/ssl.h" HAVE_ECH "") elseif(USE_OPENSSL) - openssl_check_symbol_exists(SSL_ech_set1_echconfig "openssl/ech.h" HAVE_ECH "") + openssl_check_symbol_exists("SSL_ech_set1_echconfig" "openssl/ech.h" HAVE_ECH "") elseif(USE_WOLFSSL) - openssl_check_symbol_exists(wolfSSL_CTX_GenerateEchConfig "wolfssl/options.h;wolfssl/ssl.h" HAVE_ECH "") + openssl_check_symbol_exists("wolfSSL_CTX_GenerateEchConfig" "wolfssl/options.h;wolfssl/ssl.h" HAVE_ECH "") endif() endif() if(NOT HAVE_ECH) @@ -700,30 +821,34 @@ if(USE_ECH) endif() endif() -option(USE_NGHTTP2 "Use nghttp2 library" OFF) +option(USE_NGHTTP2 "Use nghttp2 library" ON) if(USE_NGHTTP2) - find_package(NGHTTP2 REQUIRED) - include_directories(${NGHTTP2_INCLUDE_DIRS}) - list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES}) - list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp2") + find_package(NGHTTP2) + if(NGHTTP2_FOUND) + include_directories(${NGHTTP2_INCLUDE_DIRS}) + list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES}) + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp2") + else() + set(USE_NGHTTP2 OFF) + endif() endif() option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF) if(USE_NGTCP2) if(USE_OPENSSL OR USE_WOLFSSL) if(USE_WOLFSSL) - find_package(NGTCP2 REQUIRED wolfSSL) + find_package(NGTCP2 REQUIRED "wolfSSL") list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libngtcp2_crypto_wolfssl") elseif(HAVE_BORINGSSL OR HAVE_AWSLC) - find_package(NGTCP2 REQUIRED BoringSSL) + find_package(NGTCP2 REQUIRED "BoringSSL") list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libngtcp2_crypto_boringssl") else() - find_package(NGTCP2 REQUIRED quictls) + find_package(NGTCP2 REQUIRED "quictls") list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libngtcp2_crypto_quictls") endif() openssl_check_quic() elseif(USE_GNUTLS) - find_package(NGTCP2 REQUIRED GnuTLS) + find_package(NGTCP2 REQUIRED "GnuTLS") list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libngtcp2_crypto_gnutls") else() message(FATAL_ERROR "ngtcp2 requires OpenSSL, wolfSSL or GnuTLS") @@ -745,7 +870,7 @@ if(USE_QUICHE) if(USE_NGTCP2) message(FATAL_ERROR "Only one HTTP/3 backend can be selected!") endif() - find_package(QUICHE REQUIRED) + find_package(Quiche REQUIRED) if(NOT HAVE_BORINGSSL) message(FATAL_ERROR "quiche requires BoringSSL") endif() @@ -758,7 +883,7 @@ if(USE_QUICHE) cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}") set(CMAKE_REQUIRED_LIBRARIES "${QUICHE_LIBRARIES}") - check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD) + check_symbol_exists("quiche_conn_set_qlog_fd" "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD) cmake_pop_check_state() endif() endif() @@ -768,6 +893,7 @@ if(USE_MSH3) if(USE_NGTCP2 OR USE_QUICHE) message(FATAL_ERROR "Only one HTTP/3 backend can be selected!") endif() + find_package(MSH3 REQUIRED) set(USE_MSH3 ON) include_directories(${MSH3_INCLUDE_DIRS}) list(APPEND CURL_LIBS ${MSH3_LIBRARIES}) @@ -788,12 +914,6 @@ if(USE_OPENSSL_QUIC) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp3") endif() -if(USE_MBEDTLS OR - USE_BEARSSL OR - USE_SECTRANSP) - message(WARNING "A selected TLS library does not support TLS 1.3.") -endif() - if(CURL_WITH_MULTI_SSL AND (USE_NGTCP2 OR USE_QUICHE OR USE_MSH3 OR USE_OPENSSL_QUIC)) message(FATAL_ERROR "MultiSSL cannot be enabled with HTTP/3 and vice versa.") endif() @@ -816,7 +936,7 @@ if(NOT CURL_DISABLE_LDAP) set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library") set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library") - # Now that we know, we're not using windows LDAP... + # Now that we know, we are not using Windows LDAP... if(NOT USE_WIN32_LDAP) # Check for LDAP set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) @@ -832,37 +952,37 @@ if(NOT CURL_DISABLE_LDAP) if(CMAKE_LDAP_INCLUDE_DIR) list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR}) endif() - check_include_file_concat("ldap.h" HAVE_LDAP_H) - check_include_file_concat("lber.h" HAVE_LBER_H) + check_include_file_concat("ldap.h" HAVE_LDAP_H) + check_include_file_concat("lber.h" HAVE_LBER_H) if(NOT HAVE_LDAP_H) message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON") set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) # LDAP includes will not be used elseif(NOT HAVE_LIBLDAP) message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON") set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) # LDAP includes will not be used else() if(CMAKE_LDAP_INCLUDE_DIR) include_directories(${CMAKE_LDAP_INCLUDE_DIR}) endif() set(NEED_LBER_H ON) - set(_HEADER_LIST) + unset(_header_list) if(WIN32) - list(APPEND _HEADER_LIST "windows.h") + list(APPEND _header_list "windows.h") endif() if(HAVE_SYS_TYPES_H) - list(APPEND _HEADER_LIST "sys/types.h") + list(APPEND _header_list "sys/types.h") endif() - list(APPEND _HEADER_LIST "ldap.h") + list(APPEND _header_list "ldap.h") - set(_INCLUDE_STRING "") - foreach(_HEADER ${_HEADER_LIST}) - set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n") + set(_include_string "") + foreach(_header IN LISTS _header_list) + set(_include_string "${_include_string}#include <${_header}>\n") endforeach() - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DLDAP_DEPRECATED=1) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1") list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB}) set(CURL_LIBS "${CMAKE_LDAP_LIB};${CURL_LIBS}") if(HAVE_LIBLBER) @@ -871,7 +991,7 @@ if(NOT CURL_DISABLE_LDAP) endif() check_c_source_compiles(" - ${_INCLUDE_STRING} + ${_include_string} int main(int argc, char ** argv) { BerValue *bvp = NULL; @@ -885,8 +1005,8 @@ if(NOT CURL_DISABLE_LDAP) set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H") endif() - check_function_exists(ldap_url_parse HAVE_LDAP_URL_PARSE) - check_function_exists(ldap_init_fd HAVE_LDAP_INIT_FD) + check_function_exists("ldap_url_parse" HAVE_LDAP_URL_PARSE) + check_function_exists("ldap_init_fd" HAVE_LDAP_INIT_FD) unset(CMAKE_REQUIRED_LIBRARIES) @@ -911,36 +1031,13 @@ if(CURL_DISABLE_LDAP) endif() endif() -# Check for idn2 -option(USE_LIBIDN2 "Use libidn2 for IDN support" ON) -if(USE_LIBIDN2) - check_library_exists("idn2" "idn2_lookup_ul" "" HAVE_LIBIDN2) - if(HAVE_LIBIDN2) - set(LIBIDN2_LINK_LIBRARIES "idn2") - check_include_file_concat("idn2.h" HAVE_IDN2_H) - endif() - if(NOT HAVE_LIBIDN2 OR NOT HAVE_IDN2_H) - find_package(PkgConfig QUIET) - pkg_check_modules(LIBIDN2 "libidn2") - if(LIBIDN2_FOUND) - include_directories(${LIBIDN2_INCLUDE_DIRS}) - set(HAVE_LIBIDN2 ON) - set(HAVE_IDN2_H ON) - endif() - endif() - if(HAVE_LIBIDN2 AND HAVE_IDN2_H) - set(CURL_LIBS "${LIBIDN2_LINK_LIBRARIES};${CURL_LIBS}") - set(LIBCURL_PC_REQUIRES_PRIVATE "libidn2;${LIBCURL_PC_REQUIRES_PRIVATE}") - endif() -else() - set(HAVE_LIBIDN2 OFF) -endif() - if(WIN32) option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF) if(USE_WIN32_IDN) list(APPEND CURL_LIBS "normaliz") endif() +else() + set(USE_WIN32_IDN OFF) endif() if(APPLE) @@ -951,11 +1048,33 @@ if(APPLE) check_symbol_exists("uidna_openUTS46" "unicode/uidna.h" HAVE_APPLE_IDN) cmake_pop_check_state() if(HAVE_APPLE_IDN) - list(APPEND CURL_LIBS "icucore") + list(APPEND CURL_LIBS "icucore" "iconv") else() set(USE_APPLE_IDN OFF) endif() endif() +else() + set(USE_APPLE_IDN OFF) +endif() + +# Check for libidn2 +option(USE_LIBIDN2 "Use libidn2 for IDN support" ON) +set(HAVE_IDN2_H OFF) +set(HAVE_LIBIDN2 OFF) +if(USE_LIBIDN2 AND NOT USE_APPLE_IDN AND NOT USE_WIN32_IDN) + find_package(Libidn2) + if(LIBIDN2_FOUND) + set(CURL_LIBS "${LIBIDN2_LIBRARIES};${CURL_LIBS}") + list(APPEND CURL_LIBDIRS ${LIBIDN2_LIBRARY_DIRS}) + set(LIBCURL_PC_REQUIRES_PRIVATE "libidn2;${LIBCURL_PC_REQUIRES_PRIVATE}") + include_directories(${LIBIDN2_INCLUDE_DIRS}) + link_directories(${LIBIDN2_LIBRARY_DIRS}) + if(LIBIDN2_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBIDN2_CFLAGS}") + endif() + set(HAVE_IDN2_H 1) + set(HAVE_LIBIDN2 1) + endif() endif() # libpsl @@ -964,28 +1083,30 @@ mark_as_advanced(CURL_USE_LIBPSL) set(USE_LIBPSL OFF) if(CURL_USE_LIBPSL) - find_package(LibPSL) + find_package(Libpsl) # TODO: add REQUIRED to match autotools if(LIBPSL_FOUND) - list(APPEND CURL_LIBS ${LIBPSL_LIBRARY}) + list(APPEND CURL_LIBS ${LIBPSL_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libpsl") - list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIR}") - include_directories("${LIBPSL_INCLUDE_DIR}") + list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIRS}") + include_directories(${LIBPSL_INCLUDE_DIRS}) set(USE_LIBPSL ON) + else() + message(WARNING "libpsl is enabled, but not found.") endif() endif() # libssh2 -option(CURL_USE_LIBSSH2 "Use libssh2" ON) +option(CURL_USE_LIBSSH2 "Use libssh2" ON) # FIXME: default is OFF in autotools mark_as_advanced(CURL_USE_LIBSSH2) set(USE_LIBSSH2 OFF) if(CURL_USE_LIBSSH2) - find_package(LibSSH2) + find_package(Libssh2) if(LIBSSH2_FOUND) - list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY}) + list(APPEND CURL_LIBS ${LIBSSH2_LIBRARIES}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh2") - list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}") - include_directories("${LIBSSH2_INCLUDE_DIR}") + list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIRS}") + include_directories(${LIBSSH2_INCLUDE_DIRS}) set(USE_LIBSSH2 ON) endif() endif() @@ -994,36 +1115,56 @@ endif() option(CURL_USE_LIBSSH "Use libssh" OFF) mark_as_advanced(CURL_USE_LIBSSH) if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH) - find_package(libssh CONFIG QUIET) - if(libssh_FOUND) - message(STATUS "Found libssh ${libssh_VERSION}") - else() - find_package(PkgConfig QUIET) - pkg_check_modules(LIBSSH "libssh") - if(LIBSSH_FOUND) - include_directories(${LIBSSH_INCLUDE_DIRS}) + find_package(Libssh REQUIRED) + if(LIBSSH_FOUND) + list(APPEND CURL_LIBS ${LIBSSH_LIBRARIES}) + list(APPEND CURL_LIBDIRS ${LIBSSH_LIBRARY_DIRS}) + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh") + include_directories(${LIBSSH_INCLUDE_DIRS}) + link_directories(${LIBSSH_LIBRARY_DIRS}) + if(LIBSSH_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH_CFLAGS}") endif() + set(USE_LIBSSH ON) endif() - if(libssh_FOUND OR LIBSSH_FOUND) - if(NOT DEFINED LIBSSH_LINK_LIBRARIES) - set(LIBSSH_LINK_LIBRARIES "ssh") # for find_package() with broken pkg-config (e.g. linux-old CI workflow) +endif() + +# wolfSSH +option(CURL_USE_WOLFSSH "Use wolfSSH" OFF) +mark_as_advanced(CURL_USE_WOLFSSH) +set(USE_WOLFSSH OFF) +if(NOT USE_LIBSSH2 AND NOT USE_LIBSSH AND CURL_USE_WOLFSSH) + if(USE_WOLFSSL) + find_package(WolfSSH) + if(WOLFSSH_FOUND) + list(APPEND CURL_LIBS ${WOLFSSH_LIBRARIES}) + list(APPEND CMAKE_REQUIRED_INCLUDES "${WOLFSSH_INCLUDE_DIRS}") + include_directories(${WOLFSSH_INCLUDE_DIRS}) + set(USE_WOLFSSH ON) endif() - list(APPEND CURL_LIBS ${LIBSSH_LINK_LIBRARIES}) - list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh") - set(USE_LIBSSH ON) + else() + message(WARNING "wolfSSH requires wolfSSL. Skipping.") endif() endif() -option(CURL_USE_GSASL "Use GSASL implementation" OFF) +option(CURL_USE_GSASL "Use libgsasl" OFF) mark_as_advanced(CURL_USE_GSASL) if(CURL_USE_GSASL) - find_package(PkgConfig REQUIRED) - pkg_check_modules(GSASL REQUIRED libgsasl) - list(APPEND CURL_LIBS ${GSASL_LINK_LIBRARIES}) - set(USE_GSASL ON) + find_package(Libgsasl REQUIRED) + if(LIBGSASL_FOUND) + list(APPEND CURL_LIBS ${LIBGSASL_LIBRARIES}) + list(APPEND CURL_LIBDIRS ${LIBGSASL_LIBRARY_DIRS}) + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libgsasl") + include_directories(${LIBGSASL_INCLUDE_DIRS}) + link_directories(${LIBGSASL_LIBRARY_DIRS}) + if(LIBGSASL_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBGSASL_CFLAGS}") + endif() + set(USE_GSASL ON) + endif() endif() -option(CURL_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF) +option(CURL_USE_GSSAPI "Use GSSAPI implementation" OFF) mark_as_advanced(CURL_USE_GSSAPI) if(CURL_USE_GSSAPI) @@ -1031,38 +1172,35 @@ if(CURL_USE_GSSAPI) set(HAVE_GSSAPI ${GSS_FOUND}) if(GSS_FOUND) + list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRS}) + + string(REPLACE ";" " " GSS_CFLAGS "${GSS_CFLAGS}") + string(REPLACE ";" " " GSS_LDFLAGS "${GSS_LDFLAGS}") - message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"") + foreach(_dir IN LISTS GSS_LIBRARY_DIRS) + set(GSS_LDFLAGS "${GSS_LDFLAGS} -L\"${_dir}\"") + endforeach() - list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR}) - check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H) + check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H) check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H) check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H) - if(NOT GSS_FLAVOUR STREQUAL "Heimdal") - # MIT - set(_INCLUDE_LIST "") + if(GSS_FLAVOUR STREQUAL "MIT") + set(_include_list "") if(HAVE_GSSAPI_GSSAPI_H) - list(APPEND _INCLUDE_LIST "gssapi/gssapi.h") + list(APPEND _include_list "gssapi/gssapi.h") endif() if(HAVE_GSSAPI_GSSAPI_GENERIC_H) - list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h") + list(APPEND _include_list "gssapi/gssapi_generic.h") endif() if(HAVE_GSSAPI_GSSAPI_KRB5_H) - list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h") + list(APPEND _include_list "gssapi/gssapi_krb5.h") endif() - string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}") - string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}") - - foreach(_dir ${GSS_LINK_DIRECTORIES}) - set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"") - endforeach() - if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE) - set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}") + set(CMAKE_REQUIRED_FLAGS "${GSS_CFLAGS} ${GSS_LDFLAGS}") set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES}) - check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE) + check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_include_list} HAVE_GSS_C_NT_HOSTBASED_SERVICE) unset(CMAKE_REQUIRED_LIBRARIES) endif() if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE) @@ -1070,21 +1208,43 @@ if(CURL_USE_GSSAPI) endif() endif() - include_directories(${GSS_INCLUDE_DIR}) - link_directories(${GSS_LINK_DIRECTORIES}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}") - string(REPLACE ";" " " GSS_LINKER_FLAGS "${GSS_LINKER_FLAGS}") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}") + include_directories(${GSS_INCLUDE_DIRS}) + link_directories(${GSS_LIBRARY_DIRS}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_CFLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LDFLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LDFLAGS}") list(APPEND CURL_LIBS ${GSS_LIBRARIES}) if(GSS_FLAVOUR STREQUAL "MIT") list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "mit-krb5-gssapi") + else() # Heimdal + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "heimdal-gssapi") endif() else() message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.") endif() endif() +# libuv +option(CURL_USE_LIBUV "Use libuv for event-based tests" OFF) +if(CURL_USE_LIBUV) + if(NOT ENABLE_DEBUG) + message(FATAL_ERROR "Using libuv without debug support enabled is useless") + endif() + find_package(Libuv REQUIRED) + if(LIBUV_FOUND) + list(APPEND CURL_LIBS ${LIBUV_LIBRARIES}) + list(APPEND CURL_LIBDIRS ${LIBUV_LIBRARY_DIRS}) + list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libuv") + include_directories(${LIBUV_INCLUDE_DIRS}) + link_directories(${LIBUV_LIBRARY_DIRS}) + if(LIBUV_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUV_CFLAGS}") + endif() + set(USE_LIBUV ON) + set(HAVE_UV_H ON) + endif() +endif() + option(USE_LIBRTMP "Enable librtmp from rtmpdump" OFF) if(USE_LIBRTMP) cmake_push_check_state() @@ -1106,13 +1266,13 @@ if(USE_LIBRTMP) endif() endif() -option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON) +option(ENABLE_UNIX_SOCKETS "Enable Unix domain sockets support" ON) if(ENABLE_UNIX_SOCKETS) - include(CheckStructHasMember) if(WIN32) set(USE_UNIX_SOCKETS ON) else() - check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS) + include(CheckStructHasMember) + check_struct_has_member("struct sockaddr_un" "sun_path" "sys/un.h" USE_UNIX_SOCKETS) endif() else() unset(USE_UNIX_SOCKETS CACHE) @@ -1121,13 +1281,15 @@ endif() # # CA handling # -if(curl_ca_bundle_supported) - set(CURL_CA_BUNDLE "auto" CACHE STRING - "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") +if(_curl_ca_bundle_supported) + set(CURL_CA_BUNDLE "auto" CACHE + STRING "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") set(CURL_CA_FALLBACK OFF CACHE BOOL - "Set ON to use built-in CA store of TLS backend. Defaults to OFF") - set(CURL_CA_PATH "auto" CACHE STRING - "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + "Set ON to use built-in CA store of TLS backend. Defaults to OFF") + set(CURL_CA_PATH "auto" CACHE + STRING "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + set(CURL_CA_EMBED "" CACHE + STRING "Path to the CA bundle to embed into the curl tool.") if(CURL_CA_BUNDLE STREQUAL "") message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.") @@ -1136,11 +1298,12 @@ if(curl_ca_bundle_supported) elseif(CURL_CA_BUNDLE STREQUAL "auto") unset(CURL_CA_BUNDLE CACHE) if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32) - set(CURL_CA_BUNDLE_AUTODETECT TRUE) + set(_curl_ca_bundle_autodetect TRUE) endif() else() set(CURL_CA_BUNDLE_SET TRUE) endif() + mark_as_advanced(CURL_CA_BUNDLE_SET) if(CURL_CA_PATH STREQUAL "") message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.") @@ -1149,48 +1312,58 @@ if(curl_ca_bundle_supported) elseif(CURL_CA_PATH STREQUAL "auto") unset(CURL_CA_PATH CACHE) if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32) - set(CURL_CA_PATH_AUTODETECT TRUE) + set(_curl_ca_path_autodetect TRUE) endif() else() set(CURL_CA_PATH_SET TRUE) endif() + mark_as_advanced(CURL_CA_PATH_SET) - if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT) + if(CURL_CA_BUNDLE_SET AND _curl_ca_path_autodetect) # Skip auto-detection of unset CA path because CA bundle is set explicitly - elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT) + elseif(CURL_CA_PATH_SET AND _curl_ca_bundle_autodetect) # Skip auto-detection of unset CA bundle because CA path is set explicitly - elseif(CURL_CA_BUNDLE_AUTODETECT OR CURL_CA_PATH_AUTODETECT) + elseif(_curl_ca_bundle_autodetect OR _curl_ca_path_autodetect) # First try auto-detecting a CA bundle, then a CA path - if(CURL_CA_BUNDLE_AUTODETECT) - foreach(SEARCH_CA_BUNDLE_PATH IN ITEMS + if(_curl_ca_bundle_autodetect) + foreach(_search_ca_bundle_path IN ITEMS "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/usr/share/ssl/certs/ca-bundle.crt" "/usr/local/share/certs/ca-root-nss.crt" "/etc/ssl/cert.pem") - if(EXISTS "${SEARCH_CA_BUNDLE_PATH}") - message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}") - set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}" CACHE STRING - "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + if(EXISTS "${_search_ca_bundle_path}") + message(STATUS "Found CA bundle: ${_search_ca_bundle_path}") + set(CURL_CA_BUNDLE "${_search_ca_bundle_path}" CACHE + STRING "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set") break() endif() endforeach() endif() - if(CURL_CA_PATH_AUTODETECT AND NOT CURL_CA_PATH_SET) - set(SEARCH_CA_PATH "/etc/ssl/certs") - file(GLOB curl_ca_files_found "${SEARCH_CA_PATH}/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].0") - if(curl_ca_files_found) - unset(curl_ca_files_found) - message(STATUS "Found CA path: ${SEARCH_CA_PATH}") - set(CURL_CA_PATH "${SEARCH_CA_PATH}" CACHE STRING - "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") + if(_curl_ca_path_autodetect AND NOT CURL_CA_PATH_SET) + set(_search_ca_path "/etc/ssl/certs") + file(GLOB _curl_ca_files_found "${_search_ca_path}/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].0") + if(_curl_ca_files_found) + unset(_curl_ca_files_found) + message(STATUS "Found CA path: ${_search_ca_path}") + set(CURL_CA_PATH "${_search_ca_path}" CACHE + STRING "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.") set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set") endif() endif() endif() + + set(CURL_CA_EMBED_SET FALSE) + if(BUILD_CURL_EXE AND NOT CURL_CA_EMBED STREQUAL "") + if(EXISTS "${CURL_CA_EMBED}") + set(CURL_CA_EMBED_SET TRUE) + else() + message(FATAL_ERROR "CA bundle to embed is missing: '${CURL_CA_EMBED}'") + endif() + endif() endif() # Check for header files @@ -1198,30 +1371,16 @@ if(WIN32) set(CURL_INCLUDES ${CURL_INCLUDES} "winsock2.h") set(CURL_INCLUDES ${CURL_INCLUDES} "ws2tcpip.h") set(CURL_INCLUDES ${CURL_INCLUDES} "windows.h") -endif() - -if(WIN32) - # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT - curl_internal_test(HAVE_WIN32_WINNT) - if(HAVE_WIN32_WINNT) - string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}") - string(REGEX REPLACE ".*_WIN32_WINNT=" "" OUTPUT "${OUTPUT}") - string(REGEX REPLACE "0x([0-9a-f][0-9a-f][0-9a-f])$" "0x0\\1" OUTPUT "${OUTPUT}") # pad to 4 digits - string(TOLOWER "${OUTPUT}" HAVE_WIN32_WINNT) - message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}") - endif() - # avoid storing HAVE_WIN32_WINNT in CMake cache - unset(HAVE_WIN32_WINNT CACHE) if(HAVE_WIN32_WINNT) - if(HAVE_WIN32_WINNT STRLESS "0x0501") + if(HAVE_WIN32_WINNT LESS 0x0501) # Windows XP is required for freeaddrinfo, getaddrinfo message(FATAL_ERROR "Building for Windows XP or newer is required.") endif() - # pre-fill detection results based on target OS version + # Pre-fill detection results based on target OS version if(MINGW OR MSVC) - if(HAVE_WIN32_WINNT STRLESS "0x0600") + if(HAVE_WIN32_WINNT LESS 0x0600) set(HAVE_INET_NTOP 0) set(HAVE_INET_PTON 0) else() # Windows Vista or newer @@ -1275,20 +1434,20 @@ check_include_file_concat("termios.h" HAVE_TERMIOS_H) check_include_file_concat("unistd.h" HAVE_UNISTD_H) check_include_file_concat("utime.h" HAVE_UTIME_H) -check_type_size(size_t SIZEOF_SIZE_T) -check_type_size(ssize_t SIZEOF_SSIZE_T) -check_type_size("long long" SIZEOF_LONG_LONG) -check_type_size("long" SIZEOF_LONG) -check_type_size("int" SIZEOF_INT) -check_type_size("__int64" SIZEOF___INT64) -check_type_size("time_t" SIZEOF_TIME_T) -check_type_size("suseconds_t" SIZEOF_SUSECONDS_T) +check_type_size("size_t" SIZEOF_SIZE_T) +check_type_size("ssize_t" SIZEOF_SSIZE_T) +check_type_size("long long" SIZEOF_LONG_LONG) +check_type_size("long" SIZEOF_LONG) +check_type_size("int" SIZEOF_INT) +check_type_size("__int64" SIZEOF___INT64) +check_type_size("time_t" SIZEOF_TIME_T) +check_type_size("suseconds_t" SIZEOF_SUSECONDS_T) if(NOT HAVE_SIZEOF_SSIZE_T) if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T) - set(ssize_t long) + set(ssize_t "long") endif() if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T) - set(ssize_t __int64) + set(ssize_t "__int64") endif() endif() # off_t is sized later, after the HAVE_FILE_OFFSET_BITS test @@ -1300,104 +1459,99 @@ if(SIZEOF_SUSECONDS_T) set(HAVE_SUSECONDS_T 1) endif() -if(NOT CMAKE_CROSSCOMPILING) - find_file(RANDOM_FILE urandom /dev) - mark_as_advanced(RANDOM_FILE) -endif() - # Check for some functions that are used if(WIN32) - set(CMAKE_REQUIRED_LIBRARIES ws2_32) + set(CMAKE_REQUIRED_LIBRARIES "ws2_32") elseif(HAVE_LIBSOCKET) - set(CMAKE_REQUIRED_LIBRARIES socket) -endif() - -check_symbol_exists(fnmatch "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH) -check_symbol_exists(basename "${CURL_INCLUDES};string.h" HAVE_BASENAME) -check_symbol_exists(opendir "${CURL_INCLUDES};dirent.h" HAVE_OPENDIR) -check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET) -check_symbol_exists(sched_yield "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD) -check_symbol_exists(socketpair "${CURL_INCLUDES}" HAVE_SOCKETPAIR) -check_symbol_exists(recv "${CURL_INCLUDES}" HAVE_RECV) -check_symbol_exists(send "${CURL_INCLUDES}" HAVE_SEND) -check_symbol_exists(sendmsg "${CURL_INCLUDES}" HAVE_SENDMSG) -check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT) -check_symbol_exists(strdup "${CURL_INCLUDES};string.h" HAVE_STRDUP) -check_symbol_exists(strtok_r "${CURL_INCLUDES};string.h" HAVE_STRTOK_R) -check_symbol_exists(strcasecmp "${CURL_INCLUDES};string.h" HAVE_STRCASECMP) -check_symbol_exists(stricmp "${CURL_INCLUDES};string.h" HAVE_STRICMP) -check_symbol_exists(strcmpi "${CURL_INCLUDES};string.h" HAVE_STRCMPI) -check_symbol_exists(memrchr "${CURL_INCLUDES};string.h" HAVE_MEMRCHR) -check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM) -check_symbol_exists(arc4random "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM) -check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL) -check_symbol_exists(getppid "${CURL_INCLUDES}" HAVE_GETPPID) -check_symbol_exists(utimes "${CURL_INCLUDES}" HAVE_UTIMES) - -check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY) -check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET) -check_symbol_exists(sigsetjmp "${CURL_INCLUDES};setjmp.h" HAVE_SIGSETJMP) -check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R) -check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID) -check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R) -check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID) -check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME) -check_symbol_exists(gmtime_r "${CURL_INCLUDES};stdlib.h;time.h" HAVE_GMTIME_R) - -check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) - -check_symbol_exists(signal "${CURL_INCLUDES};signal.h" HAVE_SIGNAL) -check_symbol_exists(strtoll "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL) -check_symbol_exists(strerror_r "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R) -check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) -check_symbol_exists(siginterrupt "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT) -check_symbol_exists(getaddrinfo "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO) -check_symbol_exists(getifaddrs "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS) -check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO) -check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE) -check_symbol_exists(eventfd "${CURL_INCLUDES};sys/eventfd.h" HAVE_EVENTFD) -check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE) -check_symbol_exists(_fseeki64 "${CURL_INCLUDES};stdio.h" HAVE__FSEEKI64) -check_symbol_exists(getpeername "${CURL_INCLUDES}" HAVE_GETPEERNAME) -check_symbol_exists(getsockname "${CURL_INCLUDES}" HAVE_GETSOCKNAME) -check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX) -check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT) -check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE) -check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE) -check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT) + set(CMAKE_REQUIRED_LIBRARIES "socket") +endif() + +check_symbol_exists("fnmatch" "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH) +check_symbol_exists("basename" "${CURL_INCLUDES};string.h" HAVE_BASENAME) +check_symbol_exists("opendir" "${CURL_INCLUDES};dirent.h" HAVE_OPENDIR) +check_symbol_exists("socket" "${CURL_INCLUDES}" HAVE_SOCKET) +check_symbol_exists("sched_yield" "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD) +check_symbol_exists("socketpair" "${CURL_INCLUDES}" HAVE_SOCKETPAIR) +check_symbol_exists("recv" "${CURL_INCLUDES}" HAVE_RECV) +check_symbol_exists("send" "${CURL_INCLUDES}" HAVE_SEND) +check_symbol_exists("sendmsg" "${CURL_INCLUDES}" HAVE_SENDMSG) +check_symbol_exists("select" "${CURL_INCLUDES}" HAVE_SELECT) +check_symbol_exists("strdup" "${CURL_INCLUDES};string.h" HAVE_STRDUP) +check_symbol_exists("strtok_r" "${CURL_INCLUDES};string.h" HAVE_STRTOK_R) +check_symbol_exists("strcasecmp" "${CURL_INCLUDES};string.h" HAVE_STRCASECMP) +check_symbol_exists("stricmp" "${CURL_INCLUDES};string.h" HAVE_STRICMP) +check_symbol_exists("strcmpi" "${CURL_INCLUDES};string.h" HAVE_STRCMPI) +check_symbol_exists("memrchr" "${CURL_INCLUDES};string.h" HAVE_MEMRCHR) +check_symbol_exists("alarm" "${CURL_INCLUDES}" HAVE_ALARM) +check_symbol_exists("arc4random" "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM) +check_symbol_exists("fcntl" "${CURL_INCLUDES}" HAVE_FCNTL) +check_symbol_exists("getppid" "${CURL_INCLUDES}" HAVE_GETPPID) +check_symbol_exists("utimes" "${CURL_INCLUDES}" HAVE_UTIMES) + +check_symbol_exists("gettimeofday" "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY) +check_symbol_exists("closesocket" "${CURL_INCLUDES}" HAVE_CLOSESOCKET) +check_symbol_exists("sigsetjmp" "${CURL_INCLUDES};setjmp.h" HAVE_SIGSETJMP) +check_symbol_exists("getpass_r" "${CURL_INCLUDES}" HAVE_GETPASS_R) +check_symbol_exists("getpwuid" "${CURL_INCLUDES}" HAVE_GETPWUID) +check_symbol_exists("getpwuid_r" "${CURL_INCLUDES}" HAVE_GETPWUID_R) +check_symbol_exists("geteuid" "${CURL_INCLUDES}" HAVE_GETEUID) +check_symbol_exists("utime" "${CURL_INCLUDES}" HAVE_UTIME) +check_symbol_exists("gmtime_r" "${CURL_INCLUDES};stdlib.h;time.h" HAVE_GMTIME_R) + +check_symbol_exists("gethostbyname_r" "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) + +check_symbol_exists("signal" "${CURL_INCLUDES};signal.h" HAVE_SIGNAL) +check_symbol_exists("strtoll" "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL) +check_symbol_exists("strerror_r" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R) +check_symbol_exists("sigaction" "signal.h" HAVE_SIGACTION) +check_symbol_exists("siginterrupt" "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT) +check_symbol_exists("getaddrinfo" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO) +check_symbol_exists("getifaddrs" "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS) +check_symbol_exists("freeaddrinfo" "${CURL_INCLUDES}" HAVE_FREEADDRINFO) +check_symbol_exists("pipe" "${CURL_INCLUDES}" HAVE_PIPE) +check_symbol_exists("eventfd" "${CURL_INCLUDES};sys/eventfd.h" HAVE_EVENTFD) +check_symbol_exists("ftruncate" "${CURL_INCLUDES}" HAVE_FTRUNCATE) +check_symbol_exists("_fseeki64" "${CURL_INCLUDES};stdio.h" HAVE__FSEEKI64) +check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) +check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME) +check_symbol_exists("if_nametoindex" "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX) +check_symbol_exists("getrlimit" "${CURL_INCLUDES}" HAVE_GETRLIMIT) +check_symbol_exists("setlocale" "${CURL_INCLUDES}" HAVE_SETLOCALE) +check_symbol_exists("setmode" "${CURL_INCLUDES}" HAVE_SETMODE) +check_symbol_exists("setrlimit" "${CURL_INCLUDES}" HAVE_SETRLIMIT) if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900)) - # earlier MSVC compilers had faulty snprintf implementations - check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) + # Earlier MSVC compilers had faulty snprintf implementations + check_symbol_exists("snprintf" "stdio.h" HAVE_SNPRINTF) endif() -check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME) -check_symbol_exists(inet_ntop "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) +check_function_exists("mach_absolute_time" HAVE_MACH_ABSOLUTE_TIME) +check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) if(MSVC AND (MSVC_VERSION LESS_EQUAL 1600)) set(HAVE_INET_NTOP OFF) endif() -check_symbol_exists(inet_pton "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) +check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) -check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR) +check_symbol_exists("fsetxattr" "${CURL_INCLUDES}" HAVE_FSETXATTR) if(HAVE_FSETXATTR) - foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6) - curl_internal_test(${CURL_TEST}) + foreach(_curl_test IN ITEMS HAVE_FSETXATTR_5 HAVE_FSETXATTR_6) + curl_internal_test(${_curl_test}) endforeach() endif() -set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") -check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T) -set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T}) -set(CMAKE_EXTRA_INCLUDE_FILES "") +set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") +check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T) +set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T}) +set(CMAKE_EXTRA_INCLUDE_FILES "") if(WIN32) - set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h") - check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY) - set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY}) - set(CMAKE_EXTRA_INCLUDE_FILES "") + set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h") + check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY) + set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY}) + set(CMAKE_EXTRA_INCLUDE_FILES "") endif() # Do curl specific tests -foreach(CURL_TEST +foreach(_curl_test IN ITEMS HAVE_FCNTL_O_NONBLOCK HAVE_IOCTLSOCKET HAVE_IOCTLSOCKET_CAMEL @@ -1419,34 +1573,34 @@ foreach(CURL_TEST HAVE_FILE_OFFSET_BITS HAVE_ATOMIC ) - curl_internal_test(${CURL_TEST}) + curl_internal_test(${_curl_test}) endforeach() if(HAVE_FILE_OFFSET_BITS) set(_FILE_OFFSET_BITS 64) set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64") endif() -check_type_size("off_t" SIZEOF_OFF_T) +check_type_size("off_t" SIZEOF_OFF_T) # fseeko may not exist with _FILE_OFFSET_BITS=64 but can exist with # _FILE_OFFSET_BITS unset or 32 (e.g. Android ARMv7 with NDK 26b and API level < 24) # so we need to test fseeko after testing for _FILE_OFFSET_BITS -check_symbol_exists(fseeko "${CURL_INCLUDES};stdio.h" HAVE_FSEEKO) +check_symbol_exists("fseeko" "${CURL_INCLUDES};stdio.h" HAVE_FSEEKO) if(HAVE_FSEEKO) set(HAVE_DECL_FSEEKO 1) endif() -# include this header to get the type +# Include this header to get the type set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include") set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h") -check_type_size("curl_off_t" SIZEOF_CURL_OFF_T) +check_type_size("curl_off_t" SIZEOF_CURL_OFF_T) set(CMAKE_EXTRA_INCLUDE_FILES "curl/curl.h") -check_type_size("curl_socket_t" SIZEOF_CURL_SOCKET_T) +check_type_size("curl_socket_t" SIZEOF_CURL_SOCKET_T) set(CMAKE_EXTRA_INCLUDE_FILES "") if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - # on not-Windows and not-crosscompiling, check for writable argv[] + # On non-Windows and not cross-compiling, check for writable argv[] include(CheckCSourceRuns) check_c_source_runs(" int main(int argc, char **argv) @@ -1457,45 +1611,45 @@ if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) }" HAVE_WRITABLE_ARGV) endif() -set(CMAKE_REQUIRED_FLAGS) +unset(CMAKE_REQUIRED_FLAGS) -option(ENABLE_WEBSOCKETS "Set to ON to enable EXPERIMENTAL websockets" OFF) +option(ENABLE_WEBSOCKETS "Enable WebSockets (experimental)" OFF) if(ENABLE_WEBSOCKETS) - if(${SIZEOF_CURL_OFF_T} GREATER "4") + if(SIZEOF_CURL_OFF_T GREATER 4) set(USE_WEBSOCKETS ON) else() message(WARNING "curl_off_t is too small to enable WebSockets") endif() endif() -foreach(CURL_TEST +foreach(_curl_test IN ITEMS HAVE_GLIBC_STRERROR_R HAVE_POSIX_STRERROR_R ) - curl_internal_test(${CURL_TEST}) + curl_internal_test(${_curl_test}) endforeach() # Check for reentrant -foreach(CURL_TEST +foreach(_curl_test IN ITEMS HAVE_GETHOSTBYNAME_R_3 HAVE_GETHOSTBYNAME_R_5 HAVE_GETHOSTBYNAME_R_6) - if(NOT ${CURL_TEST}) - if(${CURL_TEST}_REENTRANT) + if(NOT ${_curl_test}) + if(${_curl_test}_REENTRANT) set(NEED_REENTRANT 1) endif() endif() endforeach() if(NEED_REENTRANT) - foreach(CURL_TEST + foreach(_curl_test IN ITEMS HAVE_GETHOSTBYNAME_R_3 HAVE_GETHOSTBYNAME_R_5 HAVE_GETHOSTBYNAME_R_6) - set(${CURL_TEST} 0) - if(${CURL_TEST}_REENTRANT) - set(${CURL_TEST} 1) + set(${_curl_test} 0) + if(${_curl_test}_REENTRANT) + set(${_curl_test} 1) endif() endforeach() endif() @@ -1522,28 +1676,28 @@ if(HAVE_FIONBIO OR HAVE_IOCTLSOCKET OR HAVE_IOCTLSOCKET_CASE OR HAVE_O_NONBLOCK) - set(HAVE_DISABLED_NONBLOCKING) + unset(HAVE_DISABLED_NONBLOCKING) endif() if(CMAKE_COMPILER_IS_GNUCC AND APPLE) include(CheckCCompilerFlag) - check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double) + check_c_compiler_flag("-Wno-long-double" HAVE_C_FLAG_Wno_long_double) if(HAVE_C_FLAG_Wno_long_double) # The Mac version of GCC warns about use of long double. Disable it. - get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS) - if(MPRINTF_COMPILE_FLAGS) - set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double") + get_source_file_property(_mprintf_compile_flags "mprintf.c" COMPILE_FLAGS) + if(_mprintf_compile_flags) + set(_mprintf_compile_flags "${_mprintf_compile_flags} -Wno-long-double") else() - set(MPRINTF_COMPILE_FLAGS "-Wno-long-double") + set(_mprintf_compile_flags "-Wno-long-double") endif() - set_source_files_properties(mprintf.c PROPERTIES - COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS}) + set_source_files_properties("mprintf.c" PROPERTIES + COMPILE_FLAGS ${_mprintf_compile_flags}) endif() endif() include(CMake/OtherTests.cmake) -add_definitions(-DHAVE_CONFIG_H) +add_definitions("-DHAVE_CONFIG_H") # For Windows, all compilers used by CMake should support large files if(WIN32) @@ -1567,7 +1721,7 @@ if(MSVC) # Disable default manifest added by CMake set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) + add_definitions("-D_CRT_SECURE_NO_DEPRECATE" "-D_CRT_NONSTDC_NO_DEPRECATE") if(CMAKE_C_FLAGS MATCHES "/W[0-4]") string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") else() @@ -1581,10 +1735,10 @@ if(MSVC) endif() if(CURL_WERROR) - if(MSVC_VERSION) + if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") else() - # this assumes clang or gcc style options + # This assumes clang or gcc style options set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") endif() endif() @@ -1601,35 +1755,38 @@ if(CURL_LTO) if(CURL_HAS_LTO) message(STATUS "LTO supported and enabled") else() - message(FATAL_ERROR "LTO was requested - but compiler doesn't support it\n${CURL_LTO_ERROR}") + message(FATAL_ERROR "LTO was requested - but compiler does not support it\n${CURL_LTO_ERROR}") endif() endif() # Ugly (but functional) way to include "Makefile.inc" by transforming it # (= regenerate it). -function(transform_makefile_inc INPUT_FILE OUTPUT_FILE) - file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT) - string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) - string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) - - string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) - string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) - string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) - - string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${} - string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts. - file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT}) - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}") +function(transform_makefile_inc _input_file _output_file) + file(READ ${_input_file} _makefile_inc_text) + string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" _makefile_inc_text ${_makefile_inc_text}) + string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" _makefile_inc_text ${_makefile_inc_text}) + + string(REGEX REPLACE "\\\\\n" "!π!α!" _makefile_inc_text ${_makefile_inc_text}) + string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "set(\\1 \\2)" _makefile_inc_text ${_makefile_inc_text}) + string(REPLACE "!π!α!" "\n" _makefile_inc_text ${_makefile_inc_text}) + + # Replace $() with ${} + string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" _makefile_inc_text ${_makefile_inc_text}) + # Replace @@ with ${}, even if that may not be read by CMake scripts. + string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" _makefile_inc_text ${_makefile_inc_text}) + + file(WRITE ${_output_file} ${_makefile_inc_text}) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_input_file}") endfunction() include(GNUInstallDirs) -set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) +set(CURL_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") -set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") -set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") -set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") +set(_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") +set(_project_config "${_generated_dir}/${PROJECT_NAME}Config.cmake") +set(_version_config "${_generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") cmake_dependent_option(BUILD_TESTING "Build tests" ON "PERL_FOUND;NOT CURL_DISABLE_TESTS" @@ -1654,194 +1811,199 @@ if(BUILD_TESTING) add_subdirectory(tests) endif() -if(NOT CURL_DISABLE_INSTALL) +# Helper to populate a list (_items) with a label when conditions +# (the remaining args) are satisfied +macro(_add_if _label) + # Needs to be a macro to allow this indirection + if(${ARGN}) + set(_items ${_items} "${_label}") + endif() +endmacro() - install(FILES "${PROJECT_SOURCE_DIR}/scripts/mk-ca-bundle.pl" - DESTINATION ${CMAKE_INSTALL_BINDIR} - PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE) - - # Helper to populate a list (_items) with a label when conditions - # (the remaining args) are satisfied - macro(_add_if label) - # needs to be a macro to allow this indirection - if(${ARGN}) - set(_items ${_items} "${label}") - endif() - endmacro() - - # NTLM support requires crypto functions from various SSL libs. - # These conditions must match those in lib/curl_setup.h. - if(NOT CURL_DISABLE_NTLM AND - (USE_OPENSSL OR - USE_MBEDTLS OR - USE_GNUTLS OR - USE_SECTRANSP OR - USE_WIN32_CRYPTO OR - (USE_WOLFSSL AND HAVE_WOLFSSL_DES_ECB_ENCRYPT))) - set(use_curl_ntlm_core ON) - endif() - - # Clear list and try to detect available protocols - set(_items) - _add_if("HTTP" NOT CURL_DISABLE_HTTP) - _add_if("IPFS" NOT CURL_DISABLE_HTTP) - _add_if("IPNS" NOT CURL_DISABLE_HTTP) - _add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED) - _add_if("FTP" NOT CURL_DISABLE_FTP) - _add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED) - _add_if("FILE" NOT CURL_DISABLE_FILE) - _add_if("TELNET" NOT CURL_DISABLE_TELNET) - _add_if("LDAP" NOT CURL_DISABLE_LDAP) - # CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS - _add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND - ((USE_OPENLDAP AND SSL_ENABLED) OR - (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) - _add_if("DICT" NOT CURL_DISABLE_DICT) - _add_if("TFTP" NOT CURL_DISABLE_TFTP) - _add_if("GOPHER" NOT CURL_DISABLE_GOPHER) - _add_if("GOPHERS" NOT CURL_DISABLE_GOPHER AND SSL_ENABLED) - _add_if("POP3" NOT CURL_DISABLE_POP3) - _add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED) - _add_if("IMAP" NOT CURL_DISABLE_IMAP) - _add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED) - _add_if("SMB" NOT CURL_DISABLE_SMB AND - use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) - _add_if("SMBS" NOT CURL_DISABLE_SMB AND SSL_ENABLED AND - use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) - _add_if("SMTP" NOT CURL_DISABLE_SMTP) - _add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED) - _add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH) - _add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH) - _add_if("RTSP" NOT CURL_DISABLE_RTSP) - _add_if("RTMP" USE_LIBRTMP) - _add_if("MQTT" NOT CURL_DISABLE_MQTT) - _add_if("WS" USE_WEBSOCKETS) - _add_if("WSS" USE_WEBSOCKETS AND SSL_ENABLED) - if(_items) +# NTLM support requires crypto functions from various SSL libs. +# These conditions must match those in lib/curl_setup.h. +if(NOT CURL_DISABLE_NTLM AND + (USE_OPENSSL OR + USE_MBEDTLS OR + USE_GNUTLS OR + USE_SECTRANSP OR + USE_WIN32_CRYPTO OR + (USE_WOLFSSL AND HAVE_WOLFSSL_DES_ECB_ENCRYPT))) + set(_use_curl_ntlm_core ON) +endif() + +# Clear list and try to detect available protocols +unset(_items) +_add_if("HTTP" NOT CURL_DISABLE_HTTP) +_add_if("IPFS" NOT CURL_DISABLE_HTTP) +_add_if("IPNS" NOT CURL_DISABLE_HTTP) +_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND _ssl_enabled) +_add_if("FTP" NOT CURL_DISABLE_FTP) +_add_if("FTPS" NOT CURL_DISABLE_FTP AND _ssl_enabled) +_add_if("FILE" NOT CURL_DISABLE_FILE) +_add_if("TELNET" NOT CURL_DISABLE_TELNET) +_add_if("LDAP" NOT CURL_DISABLE_LDAP) +# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS +_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND + ((USE_OPENLDAP AND _ssl_enabled) OR + (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) +_add_if("DICT" NOT CURL_DISABLE_DICT) +_add_if("TFTP" NOT CURL_DISABLE_TFTP) +_add_if("GOPHER" NOT CURL_DISABLE_GOPHER) +_add_if("GOPHERS" NOT CURL_DISABLE_GOPHER AND _ssl_enabled) +_add_if("POP3" NOT CURL_DISABLE_POP3) +_add_if("POP3S" NOT CURL_DISABLE_POP3 AND _ssl_enabled) +_add_if("IMAP" NOT CURL_DISABLE_IMAP) +_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND _ssl_enabled) +_add_if("SMB" NOT CURL_DISABLE_SMB AND + _use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) +_add_if("SMBS" NOT CURL_DISABLE_SMB AND _ssl_enabled AND + _use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) +_add_if("SMTP" NOT CURL_DISABLE_SMTP) +_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND _ssl_enabled) +_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH) +_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH) +_add_if("RTSP" NOT CURL_DISABLE_RTSP) +_add_if("RTMP" USE_LIBRTMP) +_add_if("MQTT" NOT CURL_DISABLE_MQTT) +_add_if("WS" USE_WEBSOCKETS) +_add_if("WSS" USE_WEBSOCKETS AND _ssl_enabled) +if(_items) + list(SORT _items) +endif() +string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") +string(TOLOWER "${SUPPORT_PROTOCOLS}" _support_protocols_lower) +message(STATUS "Protocols: ${_support_protocols_lower}") + +# Clear list and try to detect available features +unset(_items) +_add_if("SSL" _ssl_enabled) +_add_if("IPv6" ENABLE_IPV6) +_add_if("UnixSockets" USE_UNIX_SOCKETS) +_add_if("libz" HAVE_LIBZ) +_add_if("brotli" HAVE_BROTLI) +_add_if("gsasl" USE_GSASL) +_add_if("zstd" HAVE_ZSTD) +_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) +_add_if("IDN" (HAVE_LIBIDN2 AND HAVE_IDN2_H) OR + USE_WIN32_IDN OR + USE_APPLE_IDN) +_add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND + ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) +_add_if("SSPI" USE_WINDOWS_SSPI) +_add_if("GSS-API" HAVE_GSSAPI) +_add_if("alt-svc" NOT CURL_DISABLE_ALTSVC) +_add_if("HSTS" NOT CURL_DISABLE_HSTS) +_add_if("SPNEGO" NOT CURL_DISABLE_NEGOTIATE_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +_add_if("Kerberos" NOT CURL_DISABLE_KERBEROS_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) +_add_if("NTLM" NOT (CURL_DISABLE_NTLM) AND + (_use_curl_ntlm_core OR USE_WINDOWS_SSPI)) +_add_if("TLS-SRP" USE_TLS_SRP) +_add_if("HTTP2" USE_NGHTTP2) +_add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE OR USE_OPENSSL_QUIC) +_add_if("MultiSSL" CURL_WITH_MULTI_SSL) +_add_if("HTTPS-proxy" _ssl_enabled AND (USE_OPENSSL OR USE_GNUTLS + OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR + USE_MBEDTLS OR USE_SECTRANSP OR + (USE_WOLFSSL AND HAVE_WOLFSSL_FULL_BIO))) +_add_if("Unicode" ENABLE_UNICODE) +_add_if("threadsafe" HAVE_ATOMIC OR + (USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR + (WIN32 AND HAVE_WIN32_WINNT GREATER_EQUAL 0x0600)) +_add_if("Debug" ENABLE_DEBUG) +_add_if("TrackMemory" ENABLE_CURLDEBUG) +_add_if("ECH" _ssl_enabled AND HAVE_ECH) +_add_if("PSL" USE_LIBPSL) +_add_if("CAcert" CURL_CA_EMBED_SET) +if(_items) + if(NOT CMAKE_VERSION VERSION_LESS 3.13) + list(SORT _items CASE INSENSITIVE) + else() list(SORT _items) endif() - string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") - string(TOLOWER "${SUPPORT_PROTOCOLS}" SUPPORT_PROTOCOLS_LOWER) - message(STATUS "Protocols: ${SUPPORT_PROTOCOLS_LOWER}") - - # Clear list and try to detect available features - set(_items) - _add_if("SSL" SSL_ENABLED) - _add_if("IPv6" ENABLE_IPV6) - _add_if("UnixSockets" USE_UNIX_SOCKETS) - _add_if("libz" HAVE_LIBZ) - _add_if("brotli" HAVE_BROTLI) - _add_if("gsasl" USE_GSASL) - _add_if("zstd" HAVE_ZSTD) - _add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) - _add_if("IDN" (HAVE_LIBIDN2 AND HAVE_IDN2_H) OR - USE_WIN32_IDN OR - USE_APPLE_IDN) - _add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND - ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) - _add_if("SSPI" USE_WINDOWS_SSPI) - _add_if("GSS-API" HAVE_GSSAPI) - _add_if("alt-svc" NOT CURL_DISABLE_ALTSVC) - _add_if("HSTS" NOT CURL_DISABLE_HSTS) - _add_if("SPNEGO" NOT CURL_DISABLE_NEGOTIATE_AUTH AND - (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) - _add_if("Kerberos" NOT CURL_DISABLE_KERBEROS_AUTH AND - (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) - _add_if("NTLM" NOT (CURL_DISABLE_NTLM) AND - (use_curl_ntlm_core OR USE_WINDOWS_SSPI)) - _add_if("TLS-SRP" USE_TLS_SRP) - _add_if("HTTP2" USE_NGHTTP2) - _add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE OR USE_OPENSSL_QUIC) - _add_if("MultiSSL" CURL_WITH_MULTI_SSL) - _add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS - OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR - USE_MBEDTLS OR USE_SECTRANSP OR - (USE_WOLFSSL AND HAVE_WOLFSSL_FULL_BIO))) - _add_if("Unicode" ENABLE_UNICODE) - _add_if("threadsafe" HAVE_ATOMIC OR - (USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR - (WIN32 AND HAVE_WIN32_WINNT GREATER_EQUAL 0x600)) - _add_if("Debug" ENABLE_DEBUG) - _add_if("TrackMemory" ENABLE_CURLDEBUG) - _add_if("ECH" SSL_ENABLED AND HAVE_ECH) - _add_if("PSL" USE_LIBPSL) - if(_items) - if(NOT CMAKE_VERSION VERSION_LESS 3.13) - list(SORT _items CASE INSENSITIVE) - else() - list(SORT _items) - endif() - endif() - string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") - message(STATUS "Features: ${SUPPORT_FEATURES}") - - # Clear list and collect SSL backends - set(_items) - _add_if("Schannel" SSL_ENABLED AND USE_SCHANNEL) - _add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL) - _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP) - _add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS) - _add_if("BearSSL" SSL_ENABLED AND USE_BEARSSL) - _add_if("wolfSSL" SSL_ENABLED AND USE_WOLFSSL) - _add_if("GnuTLS" SSL_ENABLED AND USE_GNUTLS) - - if(_items) - if(NOT CMAKE_VERSION VERSION_LESS 3.13) - list(SORT _items CASE INSENSITIVE) - else() - list(SORT _items) - endif() - endif() - string(REPLACE ";" " " SSL_BACKENDS "${_items}") - message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}") - if(CURL_DEFAULT_SSL_BACKEND) - message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}") +endif() +string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") +message(STATUS "Features: ${SUPPORT_FEATURES}") + +# Clear list and collect SSL backends +unset(_items) +_add_if("Schannel" _ssl_enabled AND USE_SCHANNEL) +_add_if("OpenSSL" _ssl_enabled AND USE_OPENSSL AND OPENSSL_VERSION VERSION_LESS 3.0.0) +_add_if("OpenSSL v3+" _ssl_enabled AND USE_OPENSSL AND NOT OPENSSL_VERSION VERSION_LESS 3.0.0) +_add_if("Secure Transport" _ssl_enabled AND USE_SECTRANSP) +_add_if("mbedTLS" _ssl_enabled AND USE_MBEDTLS) +_add_if("BearSSL" _ssl_enabled AND USE_BEARSSL) +_add_if("wolfSSL" _ssl_enabled AND USE_WOLFSSL) +_add_if("GnuTLS" _ssl_enabled AND USE_GNUTLS) +_add_if("rustls" _ssl_enabled AND USE_RUSTLS) + +if(_items) + if(NOT CMAKE_VERSION VERSION_LESS 3.13) + list(SORT _items CASE INSENSITIVE) + else() + list(SORT _items) endif() +endif() +string(REPLACE ";" " " SSL_BACKENDS "${_items}") +message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}") +if(CURL_DEFAULT_SSL_BACKEND) + message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}") +endif() + +if(NOT CURL_DISABLE_INSTALL) # curl-config needs the following options to be set. set(CC "${CMAKE_C_COMPILER}") - # TODO probably put a -D... options here? + # TODO: probably put a -D... options here? set(CONFIGURE_OPTIONS "") set(CURLVERSION "${CURL_VERSION}") + set(VERSIONNUM "${CURL_VERSION_NUM}") + set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "\${prefix}") set(includedir "\${prefix}/include") set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") - set(LIBCURL_LIBS "") set(libdir "${CMAKE_INSTALL_PREFIX}/lib") + # "a" (Linux) or "lib" (Windows) + string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") + + set(_ldflags "") + set(LIBCURL_PC_LIBS_PRIVATE "") - # For processing full path libraries into -L and -l ld options, - # the directories that go with the -L option are cached, so they - # only get added once per such directory. - set(_libcurl_libs_dirs) - # To avoid getting unnecessary -L options for known system directories, - # _libcurl_libs_dirs is seeded with them. - foreach(_libdir ${CMAKE_SYSTEM_PREFIX_PATH}) + # Avoid getting unnecessary -L options for known system directories. + unset(_sys_libdirs) + foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH) if(_libdir MATCHES "/$") set(_libdir "${_libdir}lib") else() set(_libdir "${_libdir}/lib") endif() if(IS_DIRECTORY "${_libdir}") - list(APPEND _libcurl_libs_dirs "${_libdir}") + list(APPEND _sys_libdirs "${_libdir}") endif() if(DEFINED CMAKE_LIBRARY_ARCHITECTURE) set(_libdir "${_libdir}/${CMAKE_LIBRARY_ARCHITECTURE}") if(IS_DIRECTORY "${_libdir}") - list(APPEND _libcurl_libs_dirs "${_libdir}") + list(APPEND _sys_libdirs "${_libdir}") endif() endif() endforeach() - foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS}) + foreach(_libdir IN LISTS CURL_LIBDIRS) + list(FIND _sys_libdirs "${_libdir}" _libdir_index) + if(_libdir_index LESS 0) + list(APPEND _ldflags "-L${_libdir}") + endif() + endforeach() + + foreach(_lib IN LISTS CMAKE_C_IMPLICIT_LINK_LIBRARIES CURL_LIBS) if(TARGET "${_lib}") set(_libname "${_lib}") get_target_property(_imported "${_libname}" IMPORTED) if(NOT _imported) # Reading the LOCATION property on non-imported target will error out. - # Assume the user won't need this information in the .pc file. + # Assume the user will not need this information in the .pc file. continue() endif() get_target_property(_lib "${_libname}" LOCATION) @@ -1850,137 +2012,172 @@ if(NOT CURL_DISABLE_INSTALL) continue() endif() endif() - if(_lib MATCHES "^-") - set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + if(_lib MATCHES "^-") # '-framework ' + list(APPEND _ldflags "${_lib}") elseif(_lib MATCHES ".*/.*") # This gets a bit more complex, because we want to specify the # directory separately, and only once per directory - string(REGEX REPLACE "^(.*)/[^/]*$" "\\1" _libdir "${_lib}") - string(REGEX REPLACE "^.*/([^/.]*).*$" "\\1" _libname "${_lib}") + get_filename_component(_libdir ${_lib} DIRECTORY) + get_filename_component(_libname ${_lib} NAME_WE) if(_libname MATCHES "^lib") - list(FIND _libcurl_libs_dirs "${_libdir}" _libdir_index) + list(FIND _sys_libdirs "${_libdir}" _libdir_index) if(_libdir_index LESS 0) - list(APPEND _libcurl_libs_dirs "${_libdir}") - set(LIBCURL_LIBS "${LIBCURL_LIBS} -L${_libdir}") + list(APPEND _ldflags "-L${_libdir}") endif() string(REGEX REPLACE "^lib" "" _libname "${_libname}") - set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_libname}") + list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_libname}") else() - set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + list(APPEND LIBCURL_PC_LIBS_PRIVATE "${_lib}") endif() else() - set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}") + list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_lib}") endif() endforeach() - # Export a .pc file for client projects not using CMake if(LIBCURL_PC_REQUIRES_PRIVATE) string(REPLACE ";" "," LIBCURL_PC_REQUIRES_PRIVATE "${LIBCURL_PC_REQUIRES_PRIVATE}") endif() + if(LIBCURL_PC_LIBS_PRIVATE) + string(REPLACE ";" " " LIBCURL_PC_LIBS_PRIVATE "${LIBCURL_PC_LIBS_PRIVATE}") + endif() + if(_ldflags) + list(REMOVE_DUPLICATES _ldflags) + string(REPLACE ";" " " _ldflags "${_ldflags}") + set(LIBCURL_PC_LIBS_PRIVATE "${_ldflags} ${LIBCURL_PC_LIBS_PRIVATE}") + string(STRIP "${LIBCURL_PC_LIBS_PRIVATE}" LIBCURL_PC_LIBS_PRIVATE) + endif() + set(LIBCURL_PC_CFLAGS_PRIVATE "-DCURL_STATICLIB") # Merge pkg-config private fields into public ones when static-only if(BUILD_SHARED_LIBS) - set(ENABLE_SHARED "yes") - set(LIBCURL_PC_REQUIRES "") - set(LIBCURL_NO_SHARED "") - set(CPPFLAG_CURL_STATICLIB "") + set(ENABLE_SHARED "yes") + set(LIBCURL_PC_REQUIRES "") + set(LIBCURL_PC_LIBS "") + set(LIBCURL_PC_CFLAGS "") else() - set(ENABLE_SHARED "no") - set(LIBCURL_PC_REQUIRES "${LIBCURL_PC_REQUIRES_PRIVATE}") - set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}") - set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB") + set(ENABLE_SHARED "no") + set(LIBCURL_PC_REQUIRES "${LIBCURL_PC_REQUIRES_PRIVATE}") + set(LIBCURL_PC_LIBS "${LIBCURL_PC_LIBS_PRIVATE}") + set(LIBCURL_PC_CFLAGS "${LIBCURL_PC_CFLAGS_PRIVATE}") endif() if(BUILD_STATIC_LIBS) - set(ENABLE_STATIC "yes") + set(ENABLE_STATIC "yes") else() - set(ENABLE_STATIC "no") - endif() - # "a" (Linux) or "lib" (Windows) - string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(prefix "${CMAKE_INSTALL_PREFIX}") - # Set this to "yes" to append all libraries on which -lcurl is dependent - set(REQUIRE_LIB_DEPS "no") - # SUPPORT_FEATURES - # SUPPORT_PROTOCOLS - set(VERSIONNUM "${CURL_VERSION_NUM}") - - # Finally generate a "curl-config" matching this config - # Use: - # * ENABLE_SHARED - # * ENABLE_STATIC - configure_file("${CURL_SOURCE_DIR}/curl-config.in" - "${CURL_BINARY_DIR}/curl-config" @ONLY) + set(ENABLE_STATIC "no") + endif() + + # Finally generate a "curl-config" matching this config. + # Consumed variables: + # CC + # CONFIGURE_OPTIONS + # CURLVERSION + # CURL_CA_BUNDLE + # ENABLE_SHARED + # ENABLE_STATIC + # exec_prefix + # includedir + # LDFLAGS + # LIBCURL_PC_CFLAGS + # LIBCURL_PC_LIBS_PRIVATE + # libdir + # libext + # prefix + # SSL_BACKENDS + # SUPPORT_FEATURES + # SUPPORT_PROTOCOLS + # VERSIONNUM + configure_file( + "${CURL_SOURCE_DIR}/curl-config.in" + "${CURL_BINARY_DIR}/curl-config" @ONLY) install(FILES "${CURL_BINARY_DIR}/curl-config" - DESTINATION ${CMAKE_INSTALL_BINDIR} - PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE) + DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) # Finally generate a pkg-config file matching this config - configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" - "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) + # Consumed variables: + # CURLVERSION + # exec_prefix + # includedir + # LIBCURL_PC_CFLAGS + # LIBCURL_PC_CFLAGS_PRIVATE + # LIBCURL_PC_LIBS + # LIBCURL_PC_LIBS_PRIVATE + # LIBCURL_PC_REQUIRES + # LIBCURL_PC_REQUIRES_PRIVATE + # libdir + # prefix + # SUPPORT_FEATURES + # SUPPORT_PROTOCOLS + configure_file( + "${CURL_SOURCE_DIR}/libcurl.pc.in" + "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) install(FILES "${CURL_BINARY_DIR}/libcurl.pc" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") - # install headers + # Install headers install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING PATTERN "*.h") + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h") include(CMakePackageConfigHelpers) write_basic_package_version_file( - "${version_config}" - VERSION ${CURL_VERSION} - COMPATIBILITY SameMajorVersion - ) - file(READ "${version_config}" generated_version_config) - file(WRITE "${version_config}" " - if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\") - # Version 8 satisfies version 7... requirements - set(PACKAGE_FIND_VERSION_MAJOR 8) - set(PACKAGE_FIND_VERSION_COUNT 1) - endif() - ${generated_version_config}" - ) - - # Use: - # * TARGETS_EXPORT_NAME - # * PROJECT_NAME - configure_package_config_file(CMake/curl-config.cmake.in - "${project_config}" + "${_version_config}" + VERSION ${CURL_VERSION} + COMPATIBILITY SameMajorVersion) + file(READ "${_version_config}" _generated_version_config) + file(WRITE "${_version_config}" " + if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\") + # Version 8 satisfies version 7... requirements + set(PACKAGE_FIND_VERSION_MAJOR 8) + set(PACKAGE_FIND_VERSION_COUNT 1) + endif() + ${_generated_version_config}") + + # Consumed custom variables: + # LIB_SELECTED + # TARGETS_EXPORT_NAME + # USE_OPENSSL + # USE_ZLIB + configure_package_config_file("CMake/curl-config.cmake.in" + "${_project_config}" INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR} - PATH_VARS CMAKE_INSTALL_INCLUDEDIR - ) + PATH_VARS CMAKE_INSTALL_INCLUDEDIR) if(CURL_ENABLE_EXPORT_TARGET) install(EXPORT "${TARGETS_EXPORT_NAME}" - NAMESPACE "${PROJECT_NAME}::" - DESTINATION ${CURL_INSTALL_CMAKE_DIR} - ) + NAMESPACE "${PROJECT_NAME}::" + DESTINATION ${CURL_INSTALL_CMAKE_DIR}) endif() - install(FILES ${version_config} ${project_config} - DESTINATION ${CURL_INSTALL_CMAKE_DIR} - ) + install(FILES ${_version_config} ${_project_config} + DESTINATION ${CURL_INSTALL_CMAKE_DIR}) # Workaround for MSVS10 to avoid the Dialog Hell # FIXME: This could be removed with future version of CMake. if(MSVC_VERSION EQUAL 1600) - set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") - if(EXISTS "${CURL_SLN_FILENAME}") - file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n") + set(_curl_sln_filename "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") + if(EXISTS "${_curl_sln_filename}") + file(APPEND "${_curl_sln_filename}" "\n# This should be regenerated!\n") endif() endif() if(NOT TARGET curl_uninstall) configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake + "${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(curl_uninstall - COMMAND ${CMAKE_COMMAND} -P - ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake) + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake") endif() + + install(FILES "${PROJECT_SOURCE_DIR}/scripts/mk-ca-bundle.pl" + DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) endif() diff --git a/Dockerfile b/Dockerfile index 240dc22b2..08944148c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ # docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/usr/src -w /usr/src curl/curl autoreconf -fi # docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/usr/src -w /usr/src curl/curl ./configure --without-ssl --without-libpsl # docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/usr/src -w /usr/src curl/curl make -# docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/usr/src -w /usr/src curl/curl ./maketgz 8.7.1 +# docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/usr/src -w /usr/src curl/curl ./scripts/maketgz 8.7.1 # # or get into a shell in the build environment, for example # @@ -21,10 +21,10 @@ # $ autoreconf -fi # $ ./configure --without-ssl --without-libpsl # $ make -# $ ./maketgz 8.7.1 +# $ ./scripts/maketgz 8.7.1 # To update, get the latest digest e.g. from https://hub.docker.com/_/debian/tags -FROM debian:bookworm-slim@sha256:39868a6f452462b70cf720a8daff250c63e7342970e749059c105bf7c1e8eeaf +FROM debian:bookworm-slim@sha256:903d3225acecaa272bbdd7273c6c312c2af8b73644058838d23a8c9e6e5c82cf RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends \ build-essential make autoconf automake libtool git perl zip zlib1g-dev gawk && \ diff --git a/Makefile.am b/Makefile.am index 6d604ea89..968825eea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,16 +34,24 @@ CMAKE_DIST = \ CMake/CurlTests.c \ CMake/FindBearSSL.cmake \ CMake/FindBrotli.cmake \ - CMake/FindCARES.cmake \ + CMake/FindCares.cmake \ CMake/FindGSS.cmake \ - CMake/FindLibPSL.cmake \ - CMake/FindLibSSH2.cmake \ + CMake/FindLibgsasl.cmake \ + CMake/FindLibidn2.cmake \ + CMake/FindLibpsl.cmake \ + CMake/FindLibssh.cmake \ + CMake/FindLibssh2.cmake \ + CMake/FindLibuv.cmake \ CMake/FindMbedTLS.cmake \ CMake/FindMSH3.cmake \ + CMake/FindMbedTLS.cmake \ CMake/FindNGHTTP2.cmake \ CMake/FindNGHTTP3.cmake \ CMake/FindNGTCP2.cmake \ - CMake/FindQUICHE.cmake \ + CMake/FindNettle.cmake \ + CMake/FindQuiche.cmake \ + CMake/FindRustls.cmake \ + CMake/FindWolfSSH.cmake \ CMake/FindWolfSSL.cmake \ CMake/FindZstd.cmake \ CMake/Macros.cmake \ @@ -74,10 +82,9 @@ PLAN9_DIST = plan9/include/mkfile \ plan9/src/mkfile.inc \ plan9/src/mkfile -EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \ - RELEASE-NOTES buildconf libcurl.pc.in $(CMAKE_DIST) $(VC_DIST) \ - $(WINBUILD_DIST) $(PLAN9_DIST) lib/libcurl.vers.in buildconf.bat \ - libcurl.def Dockerfile +EXTRA_DIST = CHANGES.md COPYING Makefile.dist curl-config.in \ + RELEASE-NOTES libcurl.pc.in $(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) \ + $(PLAN9_DIST) lib/libcurl.vers.in buildconf.bat Dockerfile CLEANFILES = $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) \ $(VC14_10_LIBVCXPROJ) $(VC14_10_SRCVCXPROJ) \ @@ -87,7 +94,7 @@ CLEANFILES = $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) \ bin_SCRIPTS = curl-config SUBDIRS = lib docs src scripts -DIST_SUBDIRS = $(SUBDIRS) tests packages scripts include docs +DIST_SUBDIRS = $(SUBDIRS) tests packages include docs pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcurl.pc @@ -98,8 +105,8 @@ include src/Makefile.inc dist-hook: rm -rf $(top_builddir)/tests/log - find $(distdir) -name "*.dist" -exec rm {} \; - (distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \ + find $(distdir) -name "*.dist" -a \! -name Makefile.dist -exec rm {} \; + (distit=`find $(srcdir) -name "*.dist" | grep -v Makefile`; \ for file in $$distit; do \ strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ cp -p $$file $(distdir)$$strip; \ @@ -187,7 +194,7 @@ pkgadd: cd $(srcdir)/packages/Solaris && $(MAKE) package # -# Build a cygwin binary tarball installation file +# Build a Cygwin binary tarball installation file # resulting .tar.bz2 file will end up at packages/Win32/cygwin cygwinbin: $(MAKE) -C packages/Win32/cygwin cygwinbin diff --git a/Makefile b/Makefile.dist similarity index 95% rename from Makefile rename to Makefile.dist index 3db331a48..e91320403 100644 --- a/Makefile +++ b/Makefile.dist @@ -66,6 +66,6 @@ ca-bundle: scripts/mk-ca-bundle.pl @echo "generate a fresh ca-bundle.crt" @perl $< -b -l -u lib/ca-bundle.crt -ca-firefox: lib/firefox-db2pem.sh +ca-firefox: scripts/firefox-db2pem.sh @echo "generate a fresh ca-bundle.crt" - ./lib/firefox-db2pem.sh lib/ca-bundle.crt + ./scripts/firefox-db2pem.sh lib/ca-bundle.crt diff --git a/Makefile.in b/Makefile.in index d90e03b69..0426ef8b8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -356,11 +356,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -406,7 +406,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -422,8 +421,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -456,10 +457,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -470,6 +469,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -478,6 +478,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -571,16 +572,24 @@ CMAKE_DIST = \ CMake/CurlTests.c \ CMake/FindBearSSL.cmake \ CMake/FindBrotli.cmake \ - CMake/FindCARES.cmake \ + CMake/FindCares.cmake \ CMake/FindGSS.cmake \ - CMake/FindLibPSL.cmake \ - CMake/FindLibSSH2.cmake \ + CMake/FindLibgsasl.cmake \ + CMake/FindLibidn2.cmake \ + CMake/FindLibpsl.cmake \ + CMake/FindLibssh.cmake \ + CMake/FindLibssh2.cmake \ + CMake/FindLibuv.cmake \ CMake/FindMbedTLS.cmake \ CMake/FindMSH3.cmake \ + CMake/FindMbedTLS.cmake \ CMake/FindNGHTTP2.cmake \ CMake/FindNGHTTP3.cmake \ CMake/FindNGTCP2.cmake \ - CMake/FindQUICHE.cmake \ + CMake/FindNettle.cmake \ + CMake/FindQuiche.cmake \ + CMake/FindRustls.cmake \ + CMake/FindWolfSSH.cmake \ CMake/FindWolfSSL.cmake \ CMake/FindZstd.cmake \ CMake/Macros.cmake \ @@ -611,10 +620,9 @@ PLAN9_DIST = plan9/include/mkfile \ plan9/src/mkfile.inc \ plan9/src/mkfile -EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \ - RELEASE-NOTES buildconf libcurl.pc.in $(CMAKE_DIST) $(VC_DIST) \ - $(WINBUILD_DIST) $(PLAN9_DIST) lib/libcurl.vers.in buildconf.bat \ - libcurl.def Dockerfile +EXTRA_DIST = CHANGES.md COPYING Makefile.dist curl-config.in \ + RELEASE-NOTES libcurl.pc.in $(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) \ + $(PLAN9_DIST) lib/libcurl.vers.in buildconf.bat Dockerfile CLEANFILES = $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) \ $(VC14_10_LIBVCXPROJ) $(VC14_10_SRCVCXPROJ) \ @@ -623,7 +631,7 @@ CLEANFILES = $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) \ bin_SCRIPTS = curl-config SUBDIRS = lib docs src scripts -DIST_SUBDIRS = $(SUBDIRS) tests packages scripts include docs +DIST_SUBDIRS = $(SUBDIRS) tests packages include docs pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcurl.pc LIB_VAUTH_CFILES = \ @@ -1664,8 +1672,8 @@ uninstall-am: uninstall-binSCRIPTS uninstall-pkgconfigDATA dist-hook: rm -rf $(top_builddir)/tests/log - find $(distdir) -name "*.dist" -exec rm {} \; - (distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \ + find $(distdir) -name "*.dist" -a \! -name Makefile.dist -exec rm {} \; + (distit=`find $(srcdir) -name "*.dist" | grep -v Makefile`; \ for file in $$distit; do \ strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ cp -p $$file $(distdir)$$strip; \ @@ -1748,7 +1756,7 @@ pkgadd: cd $(srcdir)/packages/Solaris && $(MAKE) package # -# Build a cygwin binary tarball installation file +# Build a Cygwin binary tarball installation file # resulting .tar.bz2 file will end up at packages/Win32/cygwin cygwinbin: $(MAKE) -C packages/Win32/cygwin cygwinbin diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 81a78ccb7..66a2ba5e6 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,51 +1,289 @@ -curl and libcurl 8.9.1 +curl and libcurl 8.10.0 - Public curl releases: 259 - Command line options: 263 + Public curl releases: 260 + Command line options: 265 curl_easy_setopt() options: 306 Public functions in libcurl: 94 - Contributors: 3211 + Contributors: 3239 This release includes the following changes: + o autotools: add `--enable-windows-unicode` option [103] + o curl: --help [option] displays documentation for given cmdline option [19] + o curl: add --skip-existing [54] + o curl: for -O, use "default" as filename when the URL has none [34] + o curl: make --rate accept "number of units" [4] + o curl: make --show-headers the same as --include [6] + o curl: support --dump-header % to direct to stderr [31] + o curl: support embedding a CA bundle and --dump-ca-embed [20] + o curl: support repeated use of the verbose option; -vv etc [35] + o curl: use libuv for parallel transfers with --test-event [82] + o getinfo: add CURLINFO_POSTTRANSFER_TIME_T [87] + o mbedtls: add CURLOPT_TLS13_CIPHERS support [78] + o rustls: add support for setting TLS version and ciphers [113] + o vtls: stop offering alpn http/1.1 for http2-prior-knowledge [53] + o wolfssl: add CURLOPT_TLS13_CIPHERS support [76] + o wolfssl: add support for ssl cert blob / ssl key blob options [50] This release includes the following bugfixes: - o cmake: detect `libssh` via `pkg-config` [10] - o cmake: detect `nettle` when building with GnuTLS [12] - o cmake: drop `if(PKG_CONFIG_FOUND)` guard for `pkg_check_modules()` [25] - o configure: limit `__builtin_available` test to Darwin [22] - o connect: fix connection shutdown for event based processing [17] - o contrithanks.sh: use -F with -v to match lines as strings - o curl: more defensive socket code for --ip-tos [21] - o CURLOPT_SSL_CTX_FUNCTION.md: mention CA caching [9] - o CURLSHOPT_SHARE.md: mention sessions/cookies as not thread-safe [20] - o example/multi-uv: remove the use of globals [3] - o ftpserver.pl: make POP3 LIST serve content from the test file [19] - o GHA/windows: increase timeout for vcpkg build step - o lib: survive some NULL input args [8] - o macos: fix Apple SDK bug workaround for non-macOS targets [13] - o misc: cleanup after removing years from copyright [26] - o os400: build cli manual. [2] - o os400: workaround an IBM ASCII run-time library bug [5] - o RELEASE-PROCEDURE.md: remove the initial build step [1] - o runtests: fold timing details with GHA, sync `-r` tflags [4] - o tests: provide FTP directory contents in the test file [18] - o tidy-up: URL updates [24] - o TODO: thread-safe sharing - o transfer: speed limiting fix for 32bit systems [6] - o vtls: avoid forward declaration in MultiSSL builds [23] - o wolfSSL: allow wolfSSL's implementation of kyber to be used [7] - o wolfssl: avoid calling get_cached_x509_store if store is uncachable [11] - o wolfssl: CA store share fix [14] - o x509asn1: unittests and fixes for gtime2str [15] + o asyn-thread: stop using GetAddrInfoExW on Windows [241] + o autotools: fix MS-DOS builds [249] + o autotools: fix typo in tests/data target [30] + o aws_sigv4: fix canon order for headers with same prefix [74] + o bearssl: fix setting tls version [203] + o bearssl: improve shutdown handling [45] + o BINDINGS: add zig binding [100] + o build: add `iphlpapi` lib for libssh on Windows [166] + o build: add `poll()` detection for cross-builds [244] + o build: add options to disable SHA-512/256 hash algo [239] + o build: check OS-native IDN first, then libidn2 [223] + o build: delete unused `REQUIRE_LIB_DEPS` [226] + o build: drop unused `NROFF` reference [253] + o build: drop unused feature-detection code for Apple `poll()` [227] + o build: generate `buildinfo.txt` for test logs [256] + o build: improve compiler version detection portability + o build: make `CURL_FORMAT_CURL_OFF_T[U]` work with mingw-w64 <=7.0.0 [207] + o build: silence C4232 MSVC warnings in vcpkg ngtcp2 builds [137] + o build: use -Wno-format-overflow [195] + o buildconf.bat: fix tool_hugehelp.c generation [173] + o cf-socket: fix pollset for listening [179] + o cf-socket: prevent KEEPALIVE_FACTOR being set to 1000 for Windows [185] + o cfilters: send flush [13] + o CHANGES: rename to CHANGES.md, no longer generated [40] + o CI: enable parallel testing in CI builds [18] + o ci: Update actions/upload-artifact digest to 89ef406 [24] + o cmake: `Libs.private` improvements [215] + o cmake: add `CURL_USE_PKGCONFIG` option [138] + o cmake: add Linux CI job, fix pytest with cmake [71] + o cmake: add math library when using wolfssl and ngtcp2 [66] + o cmake: add missing `pkg-config` hints to Find modules [158] + o cmake: add missing version detection to Find modules [170] + o cmake: add rustls [116] + o cmake: add support for versioned symbols option [51] + o cmake: add wolfSSH support [117] + o cmake: allow `pkg-config` in more envs [147] + o cmake: cleanup header paths [59] + o cmake: default `CURL_DISABLE_LDAPS` to the value of `CURL_DISABLE_LDAP` [231] + o cmake: delete MSVC warning suppression for tests/server [101] + o cmake: detect `nghttp2` via `pkg-config`, enable by default [21] + o cmake: detect and show VCPKG in platform flags [84] + o cmake: distcheck for files in CMake subdir [9] + o cmake: drop custom `CMakeOutput.log`/`CMakeError.log` logs [27] + o cmake: drop libssh CONFIG-style detection [167] + o cmake: drop no-op `tests/data/CMakeLists.txt` [26] + o cmake: drop reference to undefined variable [25] + o cmake: drop unused `HAVE_IDNA_STRERROR` [62] + o cmake: drop unused internal variable [22] + o cmake: exclude tests/http/clients builds by default [110] + o cmake: fix `GSS_VERSION` for Heimdal found via pkg-config [77] + o cmake: fix `pkg-config`-based detection in `FindGSS.cmake` [94] + o cmake: fix and tidy up c-ares builds, enable in more CI jobs [156] + o cmake: fix find rustls [148] + o cmake: fixup linking libgsasl when detected via CMake-native + o cmake: honor custom `CMAKE_UNITY_BUILD_BATCH_SIZE` [163] + o cmake: limit `pkg-config` to UNIX and MSVC+vcpkg by default [188] + o cmake: limit libidn2 `pkg-config` detection to `UNIX` [109] + o cmake: migrate dependency detections to Find modules [183] + o cmake: more small tidy-ups and fixes [80] + o cmake: rename wolfSSL and zstd config variables to uppercase [151] + o cmake: respect cflags/libdirs of native pkg-config detections [175] + o cmake: show CMake platform/compiler flags [63] + o cmake: show warning if libpsl is not found [154] + o cmake: sync code between test/example targets [234] + o cmake: sync up formatting in Find modules [129] + o cmake: TLS 1.3 warning only for bearssl and sectranp [118] + o cmake: update `curl-config.cmake.in` template var list + o cmake: update list of "advanced" variables [119] + o cmake: use numeric comparison for `HAVE_WIN32_WINNT` [69] + o cmdline-opts: language fix for expect100-timeout.md and max-time.md [192] + o configure: delete unused `CURL_DEFINE_UNQUOTED` function [224] + o configure: delete unused `HAVE_OPENSSL3` macro [225] + o configure: delete unused `m4/xc-translit.m4` [114] + o configure: detect AppleIDN [70] + o configure: fail if PSL is not disabled but not found [46] + o configure: fix WinIDN builds targeting old Windows [210] + o configure: remove USE_EXPLICIT_LIB_DEPS [199] + o configure: replace nonportable grep -o with awk [111] + o connect: always prefer ipv6 in IP eyeballing [209] + o connect: limit update IP info [191] + o cookie.md: try to articulate the two different uses this option has [92] + o curl: allow 500MB data URL encode strings [38] + o curl: find curlrc in XDG_CONFIG_HOME without leading dot [186] + o curl: fix --proxy-pinnedpubkey [91] + o curl: fix the -w urle.* variables [153] + o curl: make the progress bar detect terminal width changes [169] + o curl: warn on unsupported SSL options [106] + o Curl_rand_bytes to control env override [17] + o curl_sha512_256: fix symbol collisions with nettle library [131] + o CURLMOPT_SOCKETFUNCTION.md: expand on the easy argument [216] + o CURLOPT_XFERINFOFUNCTION: clarify the callback return codes [141] + o dist: add missing `docs/examples/CMakeLists.txt` [58] + o dist: add missing `FindNettle.cmake` [11] + o dist: add missing `lib/optiontable.pl` [115] + o dist: add missing `test_*.py` scripts [102] + o dist: drop buildconf [65] + o dist: fix reproducible build from release tarball [36] + o dmaketgz: only run 'make distclean' if Makefile exists + o docs/SSLCERTS: rewrite [174] + o docs: add description of effect of --location-trusted on cookie [157] + o docs: document the (weak) random value situation in rustls builds [252] + o docs: fix some examples in man pages + o docs: improve cipher options documentation [159] + o docs: mention "@-" in more places [67] + o docs: remove ALTSVC.md, HSTS.md, HTTP2.md and PARALLEL-TRANSFERS.md [105] + o docs: update CIPHERS.md [140] + o doh-url.md: point out DOH server IP pinning [37] + o doh: remove redundant checks [242] + o easy: fix curl_easy_upkeep for shared connection caches [52] + o escape: allow curl_easy_escape to generate 3*input length output [39] + o FEATURES.md: fix typo [180] + o ftp: always offer line end conversions [219] + o ftp: flush pingpong before response [73] + o getinfo: return zero for unsupported options (when disabled) [189] + o GHA/windows: enable MulitSSL in an MSVC job [2] + o GHA: scan git repository and detect unvetted binary files [3] + o gnutls/wolfssl: improve error message when certificate fails [125] + o gnutls: send all data [230] + o gtls: fix OCSP stapling management [206] + o haproxy: send though next filter [222] + o hash: provide asserts to verify API use [96] + o http/2: simplify eos/blocked handling [90] + o http2+h3 filters: fix ctx init [142] + o http2: fix GOAWAY message sent to server [171] + o http2: improve rate limiting of downloads [33] + o http2: improved upload eos handling [41] + o http3.md: mention how the fallback can be h1 or h2 [194] + o hyper: call Curl_req_set_upload_done() [126] + o idn: more strictly check AppleIDN errors [98] + o idn: support non-UTF-8 input under AppleIDN [99] + o INSTALL.md: MultiSSL and QUIC are mutually exclusive [7] + o KNOWN_BUGS: "special characers" in URL works with aws-sigv4 [81] + o krb5: add Linux/macOS CI tests, fix cmake GSS detection [83] + o krb5: fix `-Wcast-align` [95] + o lib: add eos flag to send methods [14] + o lib: avoid macro collisions between wolfSSL and GnuTLS headers [133] + o lib: convert some debugf()s into traces [8] + o lib: delete stray undefs for `vsnprintf`, `vsprintf` [152] + o lib: fix AIX build issues [112] + o lib: fix building with wolfSSL without DES support [134] + o lib: make SSPI global symbols use Curl_ prefix [251] + o lib: prefer `CURL_SHA256_DIGEST_LENGTH` over the unprefixed name [132] + o lib: remove the final strncpy() calls [240] + o lib: remove use of RANDOM_FILE [235] + o libcurl.def: move from / into lib [238] + o libcurl.pc: add `Cflags.private` [10] + o libcurl.pc: add reference to `libgsasl` [150] + o libcurl/docs: expand on redirect following and secrets to other hosts [85] + o llist: remove direct struct accesses, use only functions [72] + o Makefile.dist: fix `ca-firefox` target [254] + o Makefile.mk: fixup enabling libidn2 [61] + o Makefile: remove 'scripts' duplicate from DIST_SUBDIRS + o maketgz: accept option to include latest commit hash [5] + o maketgz: fix RELEASE-TOOLS.md for daily tarballs [243] + o maketgz: move from / into scripts [237] + o managen: fix superfluous leading blank line in quoted sections [211] + o managen: in man output, remove the leading space from examples [198] + o managen: wordwrap long example lines in ASCII output [143] + o manpage: ensure a maximum width for the text version [75] + o max-filesize.md: mention zero disables the limit [93] + o mbedtls: add more informative logging [162] + o mbedtls: fix setting tls version [200] + o mbedtls: no longer use MBEDTLS_SSL_VERIFY_OPTIONAL [181] + o mime: avoid inifite loop in client reader [155] + o mk-ca-bundle.pl: include a link to the caextract webpage [68] + o multi: make the "general" list of easy handles a Curl_llist [97] + o multi: on socket callback error, remove socket hash entry nonetheless [149] + o ngtcp2/osslq: remove NULL pointer dereferences [213] + o ngtcp2: use NGHTTP3 prefix instead of NGTCP2 for errors in h3 callbacks [79] + o openssl quic: fix memory leak [229] + o openssl: certinfo errors now fail correctly [250] + o openssl: fix the data race when sharing an SSL session between threads [221] + o openssl: improve shutdown handling [44] + o pingpong: drain the input buffer when reading responses [193] + o POP3: fix multi-line responses [168] + o pop3: use the protocol handler ->write_resp [220] + o printf: fix mingw-w64 format checks [228] + o progress: ratelimit/progress tweaks [32] + o pytests: add tests for HEAD requests in all HTTP versions [42] + o rand: only provide weak random when needed [233] + o runtests: if DISABLED cannot be read, error out [56] + o runtests: log ignored but passed tests [130] + o runtests: remove "has_textaware" [217] + o rustls: fix setting tls version [202] + o rustls: make all tests pass [1] + o schannel: avoid malloc for CAinfo_blob_digest [247] + o scorecard: tweak request measurements [139] + o sectransp: fix setting tls version [204] + o SECURITY: mention OpenSSF best practices gold badge [161] + o setopt: allow CURLOPT_INTERFACE to be set to NULL [165] + o setopt: let CURLOPT_ECH set to NULL reset to default [187] + o setopt: make CURLOPT_TFTP_BLKSIZE accept bad values [184] + o sha256: fix symbol collision between nettle (GnuTLS) and OpenSSL [135] + o share: don't reinitialize conncache [214] + o sigpipe: init the struct so that first apply ignores [49] + o smb: convert superflous assign into assert [246] + o smtp: add tracing feature [120] + o splay: use access functions, add asserts, use Curl_timediff [121] + o spnego_gssapi: implement TLS channel bindings for openssl [146] + o src: delete `curlx_m*printf()` aliases [197] + o src: fix potential macro confusion in cmake unity builds [208] + o src: namespace symbols clashing with lib [248] + o src: replace copy of printf mappings with an include [190] + o ssh: deduplicate SSH backend includes (and fix libssh cmake unity build) [177] + o system_win32: fix typo + o test httpd: tweak cipher list [124] + o test1521: verify setting options to NULL better [182] + o test1707: output diff more for debugging differences in CI outputs + o test556: improve robustness [64] + o test579: improve robustness [60] + o test587: improve robustness [123] + o test649: improve robustness [122] + o test677: improve robustness [47] + o tests/runner: only allow [!A-Za-z0-9_-] in %if feature names [55] + o tests: constrain http pytest to tests/http directory [205] + o tests: don't mangle output if hostname or type unknown + o tests: ignore QUIT from FTP protocol comparisons [108] + o tests: provide docs as curldown, not nroff [12] + o tidy-up: misc build, tests, `lib/macos.c` [172] + o tidy-up: OS names [57] + o tool_operhlp: fix "potentially uninitialized local variable 'pc' used" [48] + o tool_paramhlp: bump maximum post data size in memory to 16GB [128] + o transfer: Curl_sendrecv() and event related improvements [164] + o transfer: remove comments, add asserts [218] + o transfer: skip EOS read when download done [196] + o url: dns_entry related improvements [16] + o url: fix connection reuse for HTTP/2 upgrades [236] + o urlapi: verify URL *decoded* hostname when set [160] + o urldata: introduce `data->mid`, a unique identifier inside a multi [127] + o urldata: remove 'scratch' from the UrlState struct [86] + o urldata: remove crlf_conversions counter [232] + o urldata: remove proxy_connect_closed bit [178] + o verify-release: shell script that verifies a release tarball [29] + o version: fix shadowing a `libssh.h` symbol [176] + o vtls: add SSLSUPP_CIPHER_LIST [107] + o vtls: fix MSVC 'cast truncates constant value' warning [23] + o vtls: fix static function name collisions between TLS backends [136] + o vtls: init ssl peer only once [15] + o websocket: introduce blocking sends [145] + o wolfssl: avoid taking cached x509 store ref if sslctx already using it [88] + o wolfssl: fix CURLOPT_SSLVERSION [144] + o wolfssl: fix setting tls version [201] + o wolfssl: improve shutdown handling [43] + o ws: flags to opcodes should ignore CURLWS_CONT flag [104] + o x509asn1: raise size limit for x509 certification information [28] This release includes the following known bugs: - o see docs/KNOWN_BUGS (https://curl.se/docs/knownbugs.html) + See docs/KNOWN_BUGS (https://curl.se/docs/knownbugs.html) + +For all changes ever done in curl: + + See https://curl.se/changes.html Planned upcoming removals include: + o Hyper support after February 2025 [89] o TLS libraries not supporting TLS 1.3 See https://curl.se/dev/deprecate.html for details @@ -53,36 +291,273 @@ Planned upcoming removals include: This release would not have looked like this without help, code, reports and advice from friends like these: - Aki Sakurai, Alex Snast, Anthony Hu, Daniel Stenberg, dependabot[bot], - Dov Murik, extrimexxx on github, Gordon Parke, Harry Sintonen, - icy17 on github, Ivan Kuchin, Mamoru Tasaka, Marcel Raad, Patrick Monnerat, - Randall S. Becker, Sergey, Stefan Eissing, Tal Regev, Viktor Szakats - (19 contributors) + Aki Sakurai, Alex Snast, Antoine du Hamel, Austin Moore, + Benjamin Riefenstahl Mecom, Bo Anderson, Chris Swan, Christoph Reiter, + Dan Fandrich, Daniel Stenberg, David Sardari, dependabot[bot], + Emanuele Torre, Eric Norris, feelingseas on github, Gruber Glass, + Hiroki Kurosawa, Ionuț-Francisc Oancea, janedenone on github, Jan Venekamp, + Jason Hood, Jiacai Liu, Joe Birr-Pixton, John Haugabook, Joshix-1 on github, + Justin Maggard, Kai Pastor, kit-ty-kate on github, lolbinarycat on github, + MasterInQuestion on github, Matt Jolly, Max Faxälv, Micah Snyder, + Moritz Buhl, Pete Cordell, ralfjunker on github, Rasmus Thomsen, Ray Satiro, + Razvan Pricope, renovate[bot], Ryan Carsten Schmidt, Sam Jessup, + Sergio Durigan Junior, Slaven Rezić, Stanislav Lange, Stefan Eissing, + Steffen Kieß, Tal Regev, Tim Yuer, Venkat Krishna R, Viktor Petersson, + Viktor Szakats, XYenon, Yedaya Katsman, Yoshimasa Ohno, наб, 罗朝辉 + (57 contributors) References to bug reports and discussions on issues: - [1] = https://curl.se/bug/?i=14267 - [2] = https://curl.se/bug/?i=14289 - [3] = https://curl.se/bug/?i=14287 - [4] = https://curl.se/bug/?i=14284 - [5] = https://curl.se/bug/?i=14281 - [6] = https://curl.se/bug/?i=14272 - [7] = https://curl.se/bug/?i=14268 - [8] = https://curl.se/bug/?i=14247 - [9] = https://curl.se/bug/?i=14302 - [10] = https://curl.se/bug/?i=14199 - [11] = https://curl.se/bug/?i=14306 - [12] = https://curl.se/bug/?i=14285 - [13] = https://curl.se/bug/?i=14269 - [14] = https://curl.se/bug/?i=14278 - [15] = https://curl.se/bug/?i=14316 - [17] = https://curl.se/bug/?i=14280 - [18] = https://curl.se/bug/?i=14295 - [19] = https://curl.se/bug/?i=14293 - [20] = https://curl.se/bug/?i=14292 - [21] = https://curl.se/bug/?i=14304 - [22] = https://curl.se/bug/?i=14196 - [23] = https://curl.se/bug/?i=14305 - [24] = https://curl.se/bug/?i=14318 - [25] = https://curl.se/bug/?i=14309 - [26] = https://curl.se/bug/?i=14312 + [1] = https://curl.se/bug/?i=14317 + [2] = https://curl.se/bug/?i=14276 + [3] = https://curl.se/bug/?i=14333 + [4] = https://curl.se/bug/?i=14245 + [5] = https://curl.se/bug/?i=14363 + [6] = https://curl.se/bug/?i=13987 + [7] = https://curl.se/bug/?i=14308 + [8] = https://curl.se/bug/?i=14322 + [9] = https://curl.se/bug/?i=14323 + [10] = https://curl.se/bug/?i=14321 + [11] = https://curl.se/bug/?i=14285 + [12] = https://curl.se/bug/?i=14324 + [13] = https://curl.se/bug/?i=14271 + [14] = https://curl.se/bug/?i=14220 + [15] = https://curl.se/bug/?i=14152 + [16] = https://curl.se/bug/?i=14195 + [17] = https://curl.se/bug/?i=14264 + [18] = https://curl.se/bug/?i=11510 + [19] = https://curl.se/bug/?i=13997 + [20] = https://curl.se/bug/?i=14059 + [21] = https://curl.se/bug/?i=14136 + [22] = https://curl.se/bug/?i=14361 + [23] = https://curl.se/bug/?i=14341 + [24] = https://curl.se/bug/?i=14359 + [25] = https://curl.se/bug/?i=14358 + [26] = https://curl.se/bug/?i=14357 + [27] = https://curl.se/bug/?i=14356 + [28] = https://curl.se/bug/?i=14352 + [29] = https://curl.se/bug/?i=14350 + [30] = https://curl.se/bug/?i=14355 + [31] = https://curl.se/bug/?i=13992 + [32] = https://curl.se/bug/?i=14335 + [33] = https://curl.se/bug/?i=14326 + [34] = https://curl.se/bug/?i=13988 + [35] = https://curl.se/bug/?i=13977 + [36] = https://curl.se/bug/?i=14336 + [37] = https://curl.se/bug/?i=14377 + [38] = https://curl.se/bug/?i=14337 + [39] = https://curl.se/bug/?i=14339 + [40] = https://curl.se/bug/?i=14331 + [41] = https://curl.se/bug/?i=14253 + [42] = https://curl.se/bug/?i=14367 + [43] = https://curl.se/bug/?i=14376 + [44] = https://curl.se/bug/?i=14375 + [45] = https://curl.se/bug/?i=14374 + [46] = https://curl.se/bug/?i=14373 + [47] = https://curl.se/bug/?i=14455 + [48] = https://curl.se/bug/?i=14389 + [49] = https://curl.se/bug/?i=14344 + [50] = https://curl.se/bug/?i=14018 + [51] = https://curl.se/bug/?i=14349 + [52] = https://curl.se/bug/?i=12677 + [53] = https://curl.se/bug/?i=9963 + [54] = https://curl.se/bug/?i=13993 + [55] = https://curl.se/bug/?i=14403 + [56] = https://curl.se/bug/?i=14411 + [57] = https://curl.se/bug/?i=14360 + [58] = https://curl.se/bug/?i=14380 + [59] = https://curl.se/bug/?i=14416 + [60] = https://curl.se/bug/?i=14454 + [61] = https://curl.se/bug/?i=14421 + [62] = https://curl.se/bug/?i=14420 + [63] = https://curl.se/bug/?i=14417 + [64] = https://curl.se/bug/?i=14453 + [65] = https://curl.se/bug/?i=14412 + [66] = https://curl.se/bug/?i=14343 + [67] = https://curl.se/bug/?i=14402 + [68] = https://github.com/curl/curl-www/issues/374 + [69] = https://curl.se/bug/?i=14409 + [70] = https://curl.se/bug/?i=14401 + [71] = https://curl.se/bug/?i=14382 + [72] = https://curl.se/bug/?i=14485 + [73] = https://curl.se/bug/?i=14452 + [74] = https://curl.se/bug/?i=14370 + [75] = https://curl.se/bug/?i=14423 + [76] = https://curl.se/bug/?i=14385 + [77] = https://curl.se/bug/?i=14393 + [78] = https://curl.se/bug/?i=14384 + [79] = https://curl.se/bug/?i=14394 + [80] = https://curl.se/bug/?i=14450 + [81] = https://curl.se/bug/?i=13754 + [82] = https://curl.se/bug/?i=14298 + [83] = https://curl.se/bug/?i=14447 + [84] = https://curl.se/bug/?i=14451 + [85] = https://curl.se/bug/?i=14472 + [86] = https://curl.se/bug/?i=14500 + [87] = https://curl.se/bug/?i=14189 + [88] = https://curl.se/bug/?i=14442 + [89] = https://curl.se/bug/?i=14492 + [90] = https://curl.se/bug/?i=14435 + [91] = https://curl.se/bug/?i=14438 + [92] = https://curl.se/bug/?i=14491 + [93] = https://curl.se/bug/?i=14440 + [94] = https://curl.se/bug/?i=14430 + [95] = https://curl.se/bug/?i=14433 + [96] = https://curl.se/bug/?i=14503 + [97] = https://curl.se/bug/?i=14474 + [98] = https://curl.se/bug/?i=14431 + [99] = https://curl.se/bug/?i=14431 + [100] = https://curl.se/bug/?i=14437 + [101] = https://curl.se/bug/?i=14428 + [102] = https://curl.se/bug/?i=14427 + [103] = https://curl.se/bug/?i=7229 + [104] = https://curl.se/bug/?i=14397 + [105] = https://curl.se/bug/?i=14553 + [106] = https://curl.se/bug/?i=14406 + [107] = https://curl.se/bug/?i=14406 + [108] = https://curl.se/bug/?i=14404 + [109] = https://curl.se/bug/?i=14405 + [110] = https://curl.se/bug/?i=14477 + [111] = https://curl.se/bug/?i=14469 + [112] = https://curl.se/bug/?i=14464 + [113] = https://curl.se/bug/?i=14535 + [114] = https://curl.se/bug/?i=14459 + [115] = https://curl.se/bug/?i=14467 + [116] = https://curl.se/bug/?i=14534 + [117] = https://curl.se/bug/?i=14568 + [118] = https://curl.se/bug/?i=14566 + [119] = https://curl.se/bug/?i=14540 + [120] = https://curl.se/bug/?i=14531 + [121] = https://curl.se/bug/?i=14562 + [122] = https://curl.se/bug/?i=14526 + [123] = https://curl.se/bug/?i=14525 + [124] = https://curl.se/bug/?i=14502 + [125] = https://curl.se/bug/?i=14501 + [126] = https://curl.se/bug/?i=14539 + [127] = https://curl.se/bug/?i=14414 + [128] = https://curl.se/bug/?i=14521 + [129] = https://curl.se/bug/?i=14527 + [130] = https://curl.se/bug/?i=14457 + [131] = https://curl.se/bug/?i=14514 + [132] = https://curl.se/bug/?i=14513 + [133] = https://curl.se/bug/?i=14511 + [134] = https://curl.se/bug/?i=14512 + [135] = https://curl.se/bug/?i=14515 + [136] = https://curl.se/bug/?i=14516 + [137] = https://curl.se/bug/?i=14510 + [138] = https://curl.se/bug/?i=14504 + [139] = https://curl.se/bug/?i=14564 + [140] = https://curl.se/bug/?i=14460 + [141] = https://curl.se/bug/?i=14627 + [142] = https://curl.se/bug/?i=14505 + [143] = https://curl.se/bug/?i=14543 + [144] = https://curl.se/bug/?i=14480 + [145] = https://curl.se/bug/?i=14458 + [146] = https://curl.se/bug/?i=13098 + [147] = https://curl.se/bug/?i=14483 + [148] = https://curl.se/bug/?i=14567 + [149] = https://curl.se/bug/?i=14557 + [150] = https://curl.se/bug/?i=14556 + [151] = https://curl.se/bug/?i=14574 + [152] = https://curl.se/bug/?i=14631 + [153] = https://curl.se/bug/?i=14550 + [154] = https://curl.se/bug/?i=14533 + [155] = https://curl.se/bug/?i=14532 + [156] = https://curl.se/bug/?i=14541 + [157] = https://curl.se/bug/?i=14471 + [158] = https://curl.se/bug/?i=14545 + [159] = https://curl.se/bug/?i=14407 + [160] = https://curl.se/bug/?i=14656 + [161] = https://curl.se/bug/?i=14319 + [162] = https://curl.se/bug/?i=14444 + [163] = https://curl.se/bug/?i=14626 + [164] = https://curl.se/bug/?i=14561 + [165] = https://curl.se/bug/?i=14629 + [166] = https://curl.se/bug/?i=14618 + [167] = https://curl.se/bug/?i=14614 + [168] = https://curl.se/bug/?i=14677 + [169] = https://curl.se/bug/?i=14565 + [170] = https://curl.se/bug/?i=14548 + [171] = https://curl.se/bug/?i=14623 + [172] = https://curl.se/bug/?i=14558 + [173] = https://curl.se/bug/?i=14622 + [174] = https://curl.se/bug/?i=14616 + [175] = https://curl.se/bug/?i=14641 + [176] = https://curl.se/bug/?i=14617 + [177] = https://curl.se/bug/?i=14612 + [178] = https://curl.se/bug/?i=14708 + [179] = https://curl.se/mail/lib-2024-08/0023.html + [180] = https://curl.se/bug/?i=14653 + [181] = https://curl.se/bug/?i=14591 + [182] = https://curl.se/bug/?i=14634 + [183] = https://curl.se/bug/?i=14555 + [184] = https://curl.se/bug/?i=14634 + [185] = https://curl.se/bug/?i=14368 + [186] = https://curl.se/bug/?i=12129 + [187] = https://curl.se/bug/?i=14634 + [188] = https://curl.se/bug/?i=14575 + [189] = https://curl.se/bug/?i=14634 + [190] = https://curl.se/bug/?i=14648 + [191] = https://curl.se/bug/?i=14699 + [192] = https://curl.se/bug/?i=14737 + [193] = https://curl.se/bug/?i=14201 + [194] = https://curl.se/bug/?i=14736 + [195] = https://curl.se/bug/?i=14168 + [196] = https://curl.se/bug/?i=14670 + [197] = https://curl.se/bug/?i=14647 + [198] = https://curl.se/bug/?i=14735 + [199] = https://curl.se/bug/?i=14697 + [200] = https://curl.se/bug/?i=14588 + [201] = https://curl.se/bug/?i=14587 + [202] = https://curl.se/bug/?i=14586 + [203] = https://curl.se/bug/?i=14585 + [204] = https://curl.se/bug/?i=14621 + [205] = https://curl.se/bug/?i=14611 + [206] = https://curl.se/bug/?i=14642 + [207] = https://curl.se/bug/?i=14640 + [208] = https://curl.se/bug/?i=14626 + [209] = https://curl.se/bug/?i=14761 + [210] = https://curl.se/bug/?i=12606 + [211] = https://curl.se/bug/?i=14732 + [213] = https://curl.se/bug/?i=14701 + [214] = https://curl.se/bug/?i=14696 + [215] = https://curl.se/bug/?i=14668 + [216] = https://curl.se/bug/?i=14795 + [217] = https://curl.se/bug/?i=14717 + [218] = https://curl.se/bug/?i=14688 + [219] = https://curl.se/bug/?i=14717 + [220] = https://curl.se/bug/?i=14684 + [221] = https://curl.se/bug/?i=14751 + [222] = https://curl.se/bug/?i=14756 + [223] = https://curl.se/bug/?i=14674 + [224] = https://curl.se/bug/?i=14673 + [225] = https://curl.se/bug/?i=14672 + [226] = https://curl.se/bug/?i=14671 + [227] = https://curl.se/bug/?i=14718 + [228] = https://curl.se/bug/?i=14703 + [229] = https://curl.se/bug/?i=14720 + [230] = https://curl.se/bug/?i=14722 + [231] = https://curl.se/bug/?i=14758 + [232] = https://curl.se/bug/?i=14709 + [233] = https://curl.se/bug/?i=14749 + [234] = https://curl.se/bug/?i=14660 + [235] = https://curl.se/bug/?i=14749 + [236] = https://curl.se/bug/?i=14739 + [237] = https://curl.se/bug/?i=14797 + [238] = https://curl.se/bug/?i=14796 + [239] = https://curl.se/bug/?i=14753 + [240] = https://curl.se/bug/?i=14830 + [241] = https://curl.se/bug/?i=13509 + [242] = https://curl.se/bug/?i=14823 + [243] = https://curl.se/bug/?i=14820 + [244] = https://curl.se/bug/?i=14714 + [246] = https://curl.se/bug/?i=14784 + [247] = https://curl.se/bug/?i=14777 + [248] = https://curl.se/bug/?i=14785 + [249] = https://curl.se/bug/?i=14814 + [250] = https://curl.se/bug/?i=14780 + [251] = https://curl.se/bug/?i=14776 + [252] = https://curl.se/bug/?i=14770 + [253] = https://curl.se/bug/?i=14812 + [254] = https://curl.se/bug/?i=14804 + [256] = https://curl.se/bug/?i=14802 diff --git a/acinclude.m4 b/acinclude.m4 index 7a26ecedc..056a97941 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -580,8 +580,8 @@ dnl hosts have it, but AIX 4.3 is one known exception. AC_DEFUN([TYPE_SOCKADDR_STORAGE], [ AC_CHECK_TYPE([struct sockaddr_storage], - AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, - [if struct sockaddr_storage is defined]), , + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, + [if struct sockaddr_storage is defined]), , [ #undef inline #ifdef _WIN32 @@ -645,9 +645,9 @@ $curl_includes_bsdsocket ]) # if test "$curl_cv_recv" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_RECV, 1, - [Define to 1 if you have the recv function.]) - curl_cv_func_recv="yes" + AC_DEFINE_UNQUOTED(HAVE_RECV, 1, + [Define to 1 if you have the recv function.]) + curl_cv_func_recv="yes" else AC_MSG_ERROR([Unable to link function recv]) fi @@ -1089,26 +1089,6 @@ AC_DEFUN([CURL_CHECK_LIBS_CONNECT], [ ]) -dnl CURL_DEFINE_UNQUOTED (VARIABLE, [VALUE]) -dnl ------------------------------------------------- -dnl Like AC_DEFINE_UNQUOTED this macro will define a C preprocessor -dnl symbol that can be further used in custom template configuration -dnl files. This macro, unlike AC_DEFINE_UNQUOTED, does not use a third -dnl argument for the description. Symbol definitions done with this -dnl macro are intended to be exclusively used in handcrafted *.h.in -dnl template files. Contrary to what AC_DEFINE_UNQUOTED does, this one -dnl prevents autoheader generation and insertion of symbol template -dnl stub and definition into the first configuration header file. Do -dnl not use this macro as a replacement for AC_DEFINE_UNQUOTED, each -dnl one serves different functional needs. - -AC_DEFUN([CURL_DEFINE_UNQUOTED], [ -cat >>confdefs.h <<_EOF -[@%:@define] $1 ifelse($#, 2, [$2], 1) -_EOF -]) - - dnl CURL_CHECK_FUNC_SELECT dnl ------------------------------------------------- dnl Test if the socket select() function is available. @@ -1217,7 +1197,7 @@ AC_DEFUN([CURL_CHECK_CA_BUNDLE], [ AC_ARG_WITH(ca-bundle, AS_HELP_STRING([--with-ca-bundle=FILE], -[Path to a file containing CA certificates (example: /etc/ca-bundle.crt)]) + [Path to a file containing CA certificates (example: /etc/ca-bundle.crt)]) AS_HELP_STRING([--without-ca-bundle], [Don't use a default CA bundle]), [ want_ca="$withval" @@ -1228,7 +1208,7 @@ AS_HELP_STRING([--without-ca-bundle], [Don't use a default CA bundle]), [ want_ca="unset" ]) AC_ARG_WITH(ca-path, AS_HELP_STRING([--with-ca-path=DIRECTORY], -[Path to a directory containing CA certificates stored individually, with \ + [Path to a directory containing CA certificates stored individually, with \ their filenames in a hash format. This option can be used with the OpenSSL, \ GnuTLS, mbedTLS and wolfSSL backends. Refer to OpenSSL c_rehash for details. \ (example: /etc/certificates)]) @@ -1338,10 +1318,10 @@ AS_HELP_STRING([--without-ca-path], [Don't use a default CA path]), AC_MSG_RESULT([no]) fi - AC_MSG_CHECKING([whether to use builtin CA store of SSL library]) + AC_MSG_CHECKING([whether to use built-in CA store of SSL library]) AC_ARG_WITH(ca-fallback, -AS_HELP_STRING([--with-ca-fallback], [Use the built in CA store of the SSL library]) -AS_HELP_STRING([--without-ca-fallback], [Don't use the built in CA store of the SSL library]), +AS_HELP_STRING([--with-ca-fallback], [Use the built-in CA store of the SSL library]) +AS_HELP_STRING([--without-ca-fallback], [Don't use the built-in CA store of the SSL library]), [ if test "x$with_ca_fallback" != "xyes" -a "x$with_ca_fallback" != "xno"; then AC_MSG_ERROR([--with-ca-fallback only allows yes or no as parameter]) @@ -1353,17 +1333,48 @@ AS_HELP_STRING([--without-ca-fallback], [Don't use the built in CA store of the if test "x$OPENSSL_ENABLED" != "x1" -a "x$GNUTLS_ENABLED" != "x1"; then AC_MSG_ERROR([--with-ca-fallback only works with OpenSSL or GnuTLS]) fi - AC_DEFINE_UNQUOTED(CURL_CA_FALLBACK, 1, [define "1" to use built in CA store of SSL library ]) + AC_DEFINE_UNQUOTED(CURL_CA_FALLBACK, 1, [define "1" to use built-in CA store of SSL library ]) + fi +]) + + +dnl CURL_CHECK_CA_EMBED +dnl ------------------------------------------------- +dnl Check if a ca-bundle should be embedded + +AC_DEFUN([CURL_CHECK_CA_EMBED], [ + + AC_MSG_CHECKING([CA cert bundle path to embed]) + + AC_ARG_WITH(ca-embed, +AS_HELP_STRING([--with-ca-embed=FILE], + [Path to a file containing CA certificates (example: /etc/ca-bundle.crt)]) +AS_HELP_STRING([--without-ca-embed], [Don't embed a default CA bundle]), + [ + want_ca_embed="$withval" + if test "x$want_ca_embed" = "xyes"; then + AC_MSG_ERROR([--with-ca-embed=FILE requires a path to the CA bundle]) + fi + ], + [ want_ca_embed="unset" ]) + + CURL_CA_EMBED='' + if test "x$want_ca_embed" != "xno" -a "x$want_ca_embed" != "xunset" -a -f "$want_ca_embed"; then + CURL_CA_EMBED='"'$want_ca_embed'"' + AC_SUBST(CURL_CA_EMBED) + AC_MSG_RESULT([$want_ca_embed]) + else + AC_MSG_RESULT([no]) fi ]) dnl CURL_CHECK_WIN32_LARGEFILE dnl ------------------------------------------------- -dnl Check if curl's WIN32 large file will be used +dnl Check if curl's Win32 large file will be used AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [ AC_REQUIRE([CURL_CHECK_NATIVE_WINDOWS])dnl - AC_MSG_CHECKING([whether build target supports WIN32 file API]) + AC_MSG_CHECKING([whether build target supports Win32 file API]) curl_win32_file_api="no" if test "$curl_cv_native_windows" = "yes"; then if test x"$enable_largefile" != "xno"; then @@ -1373,7 +1384,7 @@ AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [ #if !defined(_WIN32_WCE) && (defined(__MINGW32__) || defined(_MSC_VER)) int dummy=1; #else - WIN32 large file API not supported. + Win32 large file API not supported. #endif ]]) ],[ @@ -1387,7 +1398,7 @@ AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [ #if defined(_WIN32_WCE) || defined(__MINGW32__) || defined(_MSC_VER) int dummy=1; #else - WIN32 small file API not supported. + Win32 small file API not supported. #endif ]]) ],[ @@ -1416,11 +1427,11 @@ AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [ dnl CURL_CHECK_WIN32_CRYPTO dnl ------------------------------------------------- -dnl Check if curl's WIN32 crypto lib can be used +dnl Check if curl's Win32 crypto lib can be used AC_DEFUN([CURL_CHECK_WIN32_CRYPTO], [ AC_REQUIRE([CURL_CHECK_NATIVE_WINDOWS])dnl - AC_MSG_CHECKING([whether build target supports WIN32 crypto API]) + AC_MSG_CHECKING([whether build target supports Win32 crypto API]) curl_win32_crypto_api="no" if test "$curl_cv_native_windows" = "yes"; then AC_COMPILE_IFELSE([ @@ -1464,10 +1475,10 @@ dnl variable while checking PKG_CONFIG_LIBDIR dnl AC_DEFUN([CURL_EXPORT_PCDIR], [ - if test -n "$1"; then - PKG_CONFIG_LIBDIR="$1" - export PKG_CONFIG_LIBDIR - fi + if test -n "$1"; then + PKG_CONFIG_LIBDIR="$1" + export PKG_CONFIG_LIBDIR + fi ]) dnl CURL_CHECK_PKGCONFIG ($module, [$pcdir]) @@ -1482,28 +1493,28 @@ dnl Optionally PKG_CONFIG_LIBDIR may be given as $pcdir. dnl AC_DEFUN([CURL_CHECK_PKGCONFIG], [ - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no], - [$PATH:/usr/bin:/usr/local/bin]) - fi + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no], + [$PATH:/usr/bin:/usr/local/bin]) + fi - if test "x$PKGCONFIG" != "xno"; then - AC_MSG_CHECKING([for $1 options with pkg-config]) - dnl ask pkg-config about $1 - itexists=`CURL_EXPORT_PCDIR([$2]) dnl - $PKGCONFIG --exists $1 >/dev/null 2>&1 && echo 1` + if test "x$PKGCONFIG" != "xno"; then + AC_MSG_CHECKING([for $1 options with pkg-config]) + dnl ask pkg-config about $1 + itexists=`CURL_EXPORT_PCDIR([$2]) dnl + $PKGCONFIG --exists $1 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - dnl pkg-config does not have info about the given module! set the - dnl variable to 'no' - PKGCONFIG="no" - AC_MSG_RESULT([no]) - else - AC_MSG_RESULT([found]) - fi + if test -z "$itexists"; then + dnl pkg-config does not have info about the given module! set the + dnl variable to 'no' + PKGCONFIG="no" + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([found]) fi + fi ]) @@ -1547,6 +1558,59 @@ use vars qw( _EOF ]) + +dnl CURL_GENERATE_BUILDINFO_TXT +dnl ------------------------------------------------- +dnl Save build info for test runner to pick up and log + +AC_DEFUN([CURL_GENERATE_BUILDINFO_TXT], [ + curl_pflags="" + case $host in + *-apple-*) curl_pflags="${curl_pflags} APPLE";; + esac + if test "$curl_cv_native_windows" = 'yes'; then + curl_pflags="${curl_pflags} WIN32" + else + case $host in + *-*-*bsd*|*-*-aix*|*-*-hpux*|*-*-interix*|*-*-irix*|*-*-linux*|*-*-solaris*|*-*-sunos*|*-apple-*|*-*-cygwin*|*-*-msys*) + curl_pflags="${curl_pflags} UNIX";; + esac + fi + case $host_os in + cygwin*|msys*) curl_pflags="${curl_pflags} CYGWIN";; + esac + case $host_os in + msys*) curl_pflags="${curl_pflags} MSYS";; + esac + if test "x$compiler_id" = 'xGNU_C'; then + curl_pflags="${curl_pflags} GCC" + fi + case $host_os in + mingw*) curl_pflags="${curl_pflags} MINGW";; + esac + if test "x$cross_compiling" = 'xyes'; then + curl_pflags="${curl_pflags} CROSS" + fi + squeeze curl_pflags + cat >./tests/buildinfo.txt <<_EOF +[@%:@] This is a generated file. Do not edit. +configure.tool: configure +configure.args: $ac_configure_args +host: $build +host.os: $build_os +host.cpu: $build_cpu +host.vendor: $build_vendor +target: $host +target.os: $host_os +target.cpu: $host_cpu +target.vendor: $host_vendor +target.flags: $curl_pflags +compiler: $compiler_id +compiler.version: $compiler_num +_EOF +]) + + dnl CURL_CPP_P dnl dnl Check if $cpp -P should be used for extract define values due to gcc 5 @@ -1645,7 +1709,7 @@ AC_DEFUN([CURL_SUPPORTS_BUILTIN_AVAILABLE], [ ],[ AC_MSG_RESULT([yes]) AC_DEFINE_UNQUOTED(HAVE_BUILTIN_AVAILABLE, 1, - [Define to 1 if you have the __builtin_available function.]) + [Define to 1 if you have the __builtin_available function.]) ],[ AC_MSG_RESULT([no]) ]) diff --git a/buildconf b/buildconf deleted file mode 100755 index ee6a2800b..000000000 --- a/buildconf +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# Copyright (C) Daniel Stenberg, , et al. -# -# SPDX-License-Identifier: curl - -echo "*** Do not use buildconf. Instead, just use: autoreconf -fi" >&2 -exec ${AUTORECONF:-autoreconf} -fi "${@}" diff --git a/configure b/configure index 03effc57d..ad3117b6e 100644 --- a/configure +++ b/configure @@ -905,7 +905,7 @@ LIBOBJS SSL_BACKENDS SUPPORT_PROTOCOLS SUPPORT_FEATURES -LIBCURL_NO_SHARED +LIBCURL_PC_LIBS LIBCURL_PC_REQUIRES LIBCURL_PC_REQUIRES_PRIVATE ENABLE_STATIC @@ -915,13 +915,11 @@ CROSSCOMPILING_TRUE BLANK_AT_MAKETIME CURL_NETWORK_AND_TIME_LIBS CURL_NETWORK_LIBS -LIBCURL_LIBS +LIBCURL_PC_LIBS_PRIVATE CFLAG_CURL_SYMBOL_HIDING DOING_CURL_SYMBOL_HIDING_FALSE DOING_CURL_SYMBOL_HIDING_TRUE USE_UNIX_SOCKETS -BUILD_LIBHOSTNAME_FALSE -BUILD_LIBHOSTNAME_TRUE USE_ARES USE_MANUAL_FALSE USE_MANUAL_TRUE @@ -934,6 +932,7 @@ FISH_FUNCTIONS_DIR USE_ZSH_COMPLETION_FALSE USE_ZSH_COMPLETION_TRUE ZSH_FUNCTIONS_DIR +USE_LIBUV USE_MSH3 USE_QUICHE USE_OPENSSL_H3 @@ -946,7 +945,10 @@ USE_NGTCP2_CRYPTO_BORINGSSL USE_NGTCP2_CRYPTO_QUICTLS USE_NGTCP2 USE_NGHTTP2 +USE_APPLE_IDN IDN_ENABLED +USE_UNICODE_FALSE +USE_UNICODE_TRUE CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_FALSE CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_TRUE CURL_LT_SHLIB_VERSIONED_FLAVOUR @@ -959,6 +961,9 @@ USE_GSASL_TRUE USE_LIBPSL_FALSE USE_LIBPSL_TRUE USE_LIBPSL +CURL_CA_EMBED_SET_FALSE +CURL_CA_EMBED_SET_TRUE +CURL_CA_EMBED CURL_CA_BUNDLE CURL_WITH_MULTI_SSL SSL_ENABLED @@ -968,9 +973,7 @@ USE_WOLFSSL USE_MBEDTLS HAVE_GNUTLS_SRP USE_GNUTLS -HAVE_OPENSSL_QUIC HAVE_OPENSSL_SRP -RANDOM_FILE SSL_LIBS USE_SECTRANSP USE_WINDOWS_SSPI @@ -1016,10 +1019,8 @@ BUILD_UNITTESTS_TRUE CURL_CFLAG_EXTRAS DOING_NATIVE_WINDOWS_FALSE DOING_NATIVE_WINDOWS_TRUE -USE_EXPLICIT_LIB_DEPS_FALSE -USE_EXPLICIT_LIB_DEPS_TRUE -REQUIRE_LIB_DEPS -CPPFLAG_CURL_STATICLIB +LIBCURL_PC_CFLAGS +LIBCURL_PC_CFLAGS_PRIVATE USE_CPPFLAG_CURL_STATICLIB_FALSE USE_CPPFLAG_CURL_STATICLIB_TRUE CURL_LT_SHLIB_USE_MIMPURE_TEXT_FALSE @@ -1242,11 +1243,11 @@ with_gssapi_includes with_gssapi_libs with_gssapi with_default_ssl_backend -with_random enable_openssl_auto_load_config with_ca_bundle with_ca_path with_ca_fallback +with_ca_embed with_libpsl with_libgsasl with_libmetalink @@ -1255,7 +1256,9 @@ with_libssh with_wolfssh with_librtmp enable_versioned_symbols +enable_windows_unicode with_winidn +with_apple_idn with_libidn2 with_nghttp2 with_ngtcp2 @@ -1263,6 +1266,7 @@ with_openssl_quic with_nghttp3 with_quiche with_msh3 +with_libuv with_zsh_functions_dir with_fish_functions_dir enable_threaded_resolver @@ -1288,6 +1292,7 @@ enable_form_api enable_dateparse enable_netrc enable_progress_meter +enable_sha512_256 enable_dnsshuffle enable_get_easy_options enable_alt_svc @@ -2017,6 +2022,10 @@ Optional Features: Enable versioned symbols in shared library --disable-versioned-symbols Disable versioned symbols in shared library + --enable-windows-unicode + Enable Windows Unicode + --disable-windows-unicode + Disable Windows Unicode (default) --enable-threaded-resolver Enable threaded resolver --disable-threaded-resolver @@ -2067,6 +2076,8 @@ Optional Features: --enable-progress-meter Enable progress-meter --disable-progress-meter Disable progress-meter + --enable-sha512-256 Enable SHA-512/256 hash algorithm (default) + --disable-sha512-256 Disable SHA-512/256 hash algorithm --enable-dnsshuffle Enable DNS shuffling --disable-dnsshuffle Disable DNS shuffling --enable-get-easy-options @@ -2102,7 +2113,7 @@ Optional Packages: installation root (default: system lib default) --with-bearssl=PATH where to look for BearSSL, PATH points to the installation root - --with-rustls=PATH where to look for rustls, PATH points to the + --with-rustls=PATH where to look for Rustls, PATH points to the installation root --with-test-nghttpx=PATH where to find nghttpx for testing @@ -2141,7 +2152,6 @@ Optional Packages: Use NAME as default SSL backend --without-default-ssl-backend Use implicit default SSL backend - --with-random=FILE read randomness from FILE (default=/dev/urandom) --with-ca-bundle=FILE Path to a file containing CA certificates (example: /etc/ca-bundle.crt) --without-ca-bundle Don't use a default CA bundle @@ -2153,8 +2163,11 @@ Optional Packages: OpenSSL c_rehash for details. (example: /etc/certificates) --without-ca-path Don't use a default CA path - --with-ca-fallback Use the built in CA store of the SSL library - --without-ca-fallback Don't use the built in CA store of the SSL library + --with-ca-fallback Use the built-in CA store of the SSL library + --without-ca-fallback Don't use the built-in CA store of the SSL library + --with-ca-embed=FILE Path to a file containing CA certificates (example: + /etc/ca-bundle.crt) + --without-ca-embed Don't embed a default CA bundle --with-libpsl=PATH Where to look for libpsl, PATH points to the LIBPSL installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option @@ -2181,6 +2194,8 @@ Optional Packages: --without-librtmp disable LIBRTMP --with-winidn=PATH enable Windows native IDN --without-winidn disable Windows native IDN + --with-apple-idn Enable AppleIDN + --without-apple-idn Disable AppleIDN --with-libidn2=PATH Enable libidn2 usage --without-libidn2 Disable libidn2 usage --with-nghttp2=PATH Enable nghttp2 usage @@ -2195,6 +2210,8 @@ Optional Packages: --without-quiche Disable quiche usage --with-msh3=PATH Enable msh3 usage --without-msh3 Disable msh3 usage + --with-libuv=PATH Enable libuv + --without-libuv Disable libuv --with-zsh-functions-dir=PATH Install zsh completions to PATH --without-zsh-functions-dir @@ -4378,7 +4395,7 @@ printf "%s\n" "$as_me: $xc_bad_var_msg libraries. Use LIBS for: $xc_word" >&6;} test $xc_bad_var_cflags = yes || test $xc_bad_var_ldflags = yes || test $xc_bad_var_cppflags = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Continuing even with errors mentioned immediately above this line." >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Continuing even with errors mentioned immediately above this line." >&5 printf "%s\n" "$as_me: WARNING: Continuing even with errors mentioned immediately above this line." >&2;} fi @@ -6900,8 +6917,8 @@ TEST_NGHTTPX=nghttpx if test ${with_test_nghttpx+y} then : withval=$with_test_nghttpx; TEST_NGHTTPX=$withval - if test X"$OPT_TEST_NGHTTPX" = "Xno" ; then - TEST_NGHTTPX="" + if test X"$OPT_TEST_NGHTTPX" = "Xno"; then + TEST_NGHTTPX="" fi fi @@ -6914,8 +6931,8 @@ CADDY=/usr/bin/caddy if test ${with_test_caddy+y} then : withval=$with_test_caddy; CADDY=$withval - if test X"$OPT_CADDY" = "Xno" ; then - CADDY="" + if test X"$OPT_CADDY" = "Xno"; then + CADDY="" fi fi @@ -6928,8 +6945,8 @@ VSFTPD=/usr/sbin/vsftpd if test ${with_test_vsftpd+y} then : withval=$with_test_vsftpd; VSFTPD=$withval - if test X"$OPT_VSFTPD" = "Xno" ; then - VSFTPD="" + if test X"$OPT_VSFTPD" = "Xno"; then + VSFTPD="" fi fi @@ -17326,28 +17343,14 @@ fi # targeting a static library and not building its shared counterpart. # -CPPFLAG_CURL_STATICLIB= -if test "x$xc_lt_build_static_only" = 'xyes'; then - CPPFLAG_CURL_STATICLIB='-DCURL_STATICLIB' -fi +LIBCURL_PC_CFLAGS_PRIVATE='-DCURL_STATICLIB' - -# Determine whether all dependent libraries must be specified when linking -if test "X$enable_shared" = "Xyes" -a "X$link_all_deplibs" = "Xno" -then - REQUIRE_LIB_DEPS=no -else - REQUIRE_LIB_DEPS=yes +LIBCURL_PC_CFLAGS= +if test "x$xc_lt_build_static_only" = 'xyes'; then + LIBCURL_PC_CFLAGS="${LIBCURL_PC_CFLAGS_PRIVATE}" fi - if test x$REQUIRE_LIB_DEPS = xyes; then - USE_EXPLICIT_LIB_DEPS_TRUE= - USE_EXPLICIT_LIB_DEPS_FALSE='#' -else - USE_EXPLICIT_LIB_DEPS_TRUE='#' - USE_EXPLICIT_LIB_DEPS_FALSE= -fi @@ -17518,7 +17521,7 @@ rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS=$OLDCPPFLAGS if test "$curl_cv_have_def___DECC" = "yes" && - test "$curl_cv_have_def___DECC_VER" = "yes"; then + test "$curl_cv_have_def___DECC_VER" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } compiler_id="DEC_C" @@ -17987,7 +17990,7 @@ printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler version" >&5 printf %s "checking compiler version... " >&6; } # strip '-suffix' parts, e.g. Ubuntu Windows cross-gcc returns '10-win32' - gccver=`$CC -dumpversion | sed -E 's/-.+$//'` + gccver=`$CC -dumpversion | "$SED" 's/-.\{1,\}$//'` gccvhi=`echo $gccver | cut -d . -f1` if echo $gccver | grep -F '.' >/dev/null; then gccvlo=`echo $gccver | cut -d . -f2` @@ -18633,8 +18636,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ if test "x$cross_compiling" != "xyes" && test "$tmp_compiler_works" = "yes"; then - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -18676,8 +18679,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -18726,8 +18729,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi if test "$tmp_compiler_works" = "yes"; then @@ -18965,8 +18968,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ if test "x$cross_compiling" != "xyes" && test "$tmp_compiler_works" = "yes"; then - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -19008,8 +19011,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -19058,8 +19061,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi if test "$tmp_compiler_works" = "yes"; then @@ -19786,9 +19789,9 @@ printf "%s\n" "$as_me: WARNING: compiler options rejected: $tmp_options" >&2;} squeeze tmp_CFLAGS case $host_os in - cygwin* | mingw*) - ;; - *) + cygwin* | mingw*) + ;; + *) ac_var_added_warnings="" for warning in missing-variable-declarations; do @@ -19809,7 +19812,7 @@ printf "%s\n" "$as_me: WARNING: compiler options rejected: $tmp_options" >&2;} tmp_CFLAGS="$tmp_CFLAGS $ac_var_added_warnings" squeeze tmp_CFLAGS - ;; + ;; esac fi # @@ -20816,7 +20819,7 @@ printf "%s\n" "$as_me: WARNING: compiler options rejected: $tmp_options" >&2;} tmp_CFLAGS="$tmp_CFLAGS $ac_var_added_warnings" squeeze tmp_CFLAGS - tmp_CFLAGS="$tmp_CFLAGS -Wformat-overflow=2" + tmp_CFLAGS="$tmp_CFLAGS -Wno-format-overflow" tmp_CFLAGS="$tmp_CFLAGS -Wformat-truncation=2" tmp_CFLAGS="$tmp_CFLAGS -Wimplicit-fallthrough" fi @@ -21088,8 +21091,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ if test "x$cross_compiling" != "xyes" && test "$tmp_compiler_works" = "yes"; then - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -21131,8 +21134,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -21181,8 +21184,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi if test "$tmp_compiler_works" = "yes"; then @@ -21420,10 +21423,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ $tmp_EXTERN char *dummy(char *buff); char *dummy(char *buff) { - if(buff) - return ++buff; - else - return buff; + if(buff) + return ++buff; + else + return buff; } int main (void) @@ -21519,8 +21522,8 @@ fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build target supports WIN32 file API" >&5 -printf %s "checking whether build target supports WIN32 file API... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build target supports Win32 file API" >&5 +printf %s "checking whether build target supports Win32 file API... " >&6; } curl_win32_file_api="no" if test "$curl_cv_native_windows" = "yes"; then if test x"$enable_largefile" != "xno"; then @@ -21535,7 +21538,7 @@ int main (void) #if !defined(_WIN32_WCE) && (defined(__MINGW32__) || defined(_MSC_VER)) int dummy=1; #else - WIN32 large file API not supported. + Win32 large file API not supported. #endif ; @@ -21563,7 +21566,7 @@ int main (void) #if defined(_WIN32_WCE) || defined(__MINGW32__) || defined(_MSC_VER) int dummy=1; #else - WIN32 small file API not supported. + Win32 small file API not supported. #endif ; @@ -21606,8 +21609,8 @@ printf "%s\n" "no" >&6; } esac - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build target supports WIN32 crypto API" >&5 -printf %s "checking whether build target supports WIN32 crypto API... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build target supports Win32 crypto API" >&5 +printf %s "checking whether build target supports Win32 crypto API... " >&6; } curl_win32_crypto_api="no" if test "$curl_cv_native_windows" = "yes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21702,6 +21705,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi + case $host_os in darwin*) @@ -21765,20 +21769,20 @@ if test ${enable_http+y} then : enableval=$enable_http; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_HTTP 1" >>confdefs.h - disable_http="yes" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: disable HTTP disables FTP over proxy and RTSP" >&5 + disable_http="yes" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: disable HTTP disables FTP over proxy and RTSP" >&5 printf "%s\n" "$as_me: WARNING: disable HTTP disables FTP over proxy and RTSP" >&2;} - CURL_DISABLE_HTTP=1 + CURL_DISABLE_HTTP=1 printf "%s\n" "#define CURL_DISABLE_RTSP 1" >>confdefs.h - CURL_DISABLE_RTSP=1 + CURL_DISABLE_RTSP=1 printf "%s\n" "#define CURL_DISABLE_ALTSVC 1" >>confdefs.h @@ -21786,15 +21790,16 @@ printf "%s\n" "#define CURL_DISABLE_ALTSVC 1" >>confdefs.h printf "%s\n" "#define CURL_DISABLE_HSTS 1" >>confdefs.h - curl_h1_msg="no (--enable-http, --with-hyper)" - curl_altsvc_msg="no"; - curl_hsts_msg="no (--enable-hsts)"; - enable_altsvc="no" - hsts="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + curl_h1_msg="no (--enable-http, --with-hyper)" + curl_altsvc_msg="no"; + curl_hsts_msg="no (--enable-hsts)"; + enable_altsvc="no" + hsts="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -21809,17 +21814,18 @@ if test ${enable_ftp+y} then : enableval=$enable_ftp; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_FTP 1" >>confdefs.h - CURL_DISABLE_FTP=1 + CURL_DISABLE_FTP=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -21834,17 +21840,18 @@ if test ${enable_file+y} then : enableval=$enable_file; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_FILE 1" >>confdefs.h - CURL_DISABLE_FILE=1 + CURL_DISABLE_FILE=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -21859,27 +21866,27 @@ if test ${enable_ldap+y} then : enableval=$enable_ldap; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_LDAP 1" >>confdefs.h - CURL_DISABLE_LDAP=1 + CURL_DISABLE_LDAP=1 - ;; + ;; yes) - ldap_askedfor="yes" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ldap_askedfor="yes" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi @@ -21891,52 +21898,53 @@ if test ${enable_ldaps+y} then : enableval=$enable_ldaps; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_LDAPS 1" >>confdefs.h - CURL_DISABLE_LDAPS=1 + CURL_DISABLE_LDAPS=1 - ;; - *) if test "x$CURL_DISABLE_LDAP" = "x1" ; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: LDAP needs to be enabled to support LDAPS" >&5 + ;; + *) + if test "x$CURL_DISABLE_LDAP" = "x1"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: LDAP needs to be enabled to support LDAPS" >&5 printf "%s\n" "LDAP needs to be enabled to support LDAPS" >&6; } printf "%s\n" "#define CURL_DISABLE_LDAPS 1" >>confdefs.h - CURL_DISABLE_LDAPS=1 + CURL_DISABLE_LDAPS=1 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_LDAP_SSL 1" >>confdefs.h - HAVE_LDAP_SSL=1 + HAVE_LDAP_SSL=1 - fi - ;; + fi + ;; esac else $as_nop - if test "x$CURL_DISABLE_LDAP" = "x1" ; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test "x$CURL_DISABLE_LDAP" = "x1"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_LDAPS 1" >>confdefs.h - CURL_DISABLE_LDAPS=1 + CURL_DISABLE_LDAPS=1 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_LDAP_SSL 1" >>confdefs.h - HAVE_LDAP_SSL=1 + HAVE_LDAP_SSL=1 - fi + fi fi @@ -21975,10 +21983,10 @@ if test X"$want_hyper" != Xno; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -22088,48 +22096,48 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hyper options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hyper options with pkg-config" >&5 printf %s "checking for hyper options with pkg-config... " >&6; } - itexists=` - if test -n "$want_hyper_path"; then - PKG_CONFIG_LIBDIR="$want_hyper_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists hyper >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_hyper_path"; then + PKG_CONFIG_LIBDIR="$want_hyper_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists hyper >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_HYPER=` - if test -n "$want_hyper_path"; then - PKG_CONFIG_LIBDIR="$want_hyper_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_hyper_path"; then + PKG_CONFIG_LIBDIR="$want_hyper_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l hyper` CPP_HYPER=` - if test -n "$want_hyper_path"; then - PKG_CONFIG_LIBDIR="$want_hyper_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_hyper_path"; then + PKG_CONFIG_LIBDIR="$want_hyper_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I hyper` LD_HYPER=` - if test -n "$want_hyper_path"; then - PKG_CONFIG_LIBDIR="$want_hyper_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_hyper_path"; then + PKG_CONFIG_LIBDIR="$want_hyper_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L hyper` else @@ -22193,7 +22201,7 @@ printf "%s\n" "$ac_cv_lib_hyper_hyper_io_new" >&6; } if test "x$ac_cv_lib_hyper_hyper_io_new" = xyes then : - for ac_header in hyper.h + for ac_header in hyper.h do : ac_fn_c_check_header_compile "$LINENO" "hyper.h" "ac_cv_header_hyper_h" "$ac_includes_default" if test "x$ac_cv_header_hyper_h" = xyes @@ -22248,33 +22256,33 @@ if test ${enable_rtsp+y} then : enableval=$enable_rtsp; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_RTSP 1" >>confdefs.h - CURL_DISABLE_RTSP=1 + CURL_DISABLE_RTSP=1 - ;; + ;; *) - if test x$CURL_DISABLE_HTTP = x1 ; then - as_fn_error $? "HTTP support needs to be enabled in order to enable RTSP support!" "$LINENO" 5 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test x$CURL_DISABLE_HTTP = x1; then + as_fn_error $? "HTTP support needs to be enabled in order to enable RTSP support!" "$LINENO" 5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - curl_rtsp_msg="enabled" - fi - ;; + curl_rtsp_msg="enabled" + fi + ;; esac else $as_nop if test "x$CURL_DISABLE_HTTP" != "x1"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - curl_rtsp_msg="enabled" - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + curl_rtsp_msg="enabled" + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi + fi fi @@ -22287,18 +22295,19 @@ if test ${enable_proxy+y} then : enableval=$enable_proxy; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_PROXY 1" >>confdefs.h - CURL_DISABLE_PROXY=1 + CURL_DISABLE_PROXY=1 - https_proxy="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + https_proxy="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22314,17 +22323,18 @@ if test ${enable_dict+y} then : enableval=$enable_dict; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_DICT 1" >>confdefs.h - CURL_DISABLE_DICT=1 + CURL_DISABLE_DICT=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22332,6 +22342,7 @@ printf "%s\n" "yes" >&6; } fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support telnet" >&5 printf %s "checking whether to support telnet... " >&6; } # Check whether --enable-telnet was given. @@ -22339,17 +22350,18 @@ if test ${enable_telnet+y} then : enableval=$enable_telnet; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_TELNET 1" >>confdefs.h - CURL_DISABLE_TELNET=1 + CURL_DISABLE_TELNET=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22357,6 +22369,7 @@ printf "%s\n" "yes" >&6; } fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support tftp" >&5 printf %s "checking whether to support tftp... " >&6; } # Check whether --enable-tftp was given. @@ -22364,17 +22377,18 @@ if test ${enable_tftp+y} then : enableval=$enable_tftp; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_TFTP 1" >>confdefs.h - CURL_DISABLE_TFTP=1 + CURL_DISABLE_TFTP=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22390,17 +22404,18 @@ if test ${enable_pop3+y} then : enableval=$enable_pop3; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_POP3 1" >>confdefs.h - CURL_DISABLE_POP3=1 + CURL_DISABLE_POP3=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22409,7 +22424,6 @@ printf "%s\n" "yes" >&6; } fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support imap" >&5 printf %s "checking whether to support imap... " >&6; } # Check whether --enable-imap was given. @@ -22417,17 +22431,18 @@ if test ${enable_imap+y} then : enableval=$enable_imap; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_IMAP 1" >>confdefs.h - CURL_DISABLE_IMAP=1 + CURL_DISABLE_IMAP=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22436,7 +22451,6 @@ printf "%s\n" "yes" >&6; } fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support smb" >&5 printf %s "checking whether to support smb... " >&6; } # Check whether --enable-smb was given. @@ -22444,17 +22458,18 @@ if test ${enable_smb+y} then : enableval=$enable_smb; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_SMB 1" >>confdefs.h - CURL_DISABLE_SMB=1 + CURL_DISABLE_SMB=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22470,17 +22485,18 @@ if test ${enable_smtp+y} then : enableval=$enable_smtp; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_SMTP 1" >>confdefs.h - CURL_DISABLE_SMTP=1 + CURL_DISABLE_SMTP=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22496,17 +22512,18 @@ if test ${enable_gopher+y} then : enableval=$enable_gopher; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_GOPHER 1" >>confdefs.h - CURL_DISABLE_GOPHER=1 + CURL_DISABLE_GOPHER=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22522,17 +22539,18 @@ if test ${enable_mqtt+y} then : enableval=$enable_mqtt; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_MQTT 1" >>confdefs.h - CURL_DISABLE_MQTT=1 + CURL_DISABLE_MQTT=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -22549,18 +22567,19 @@ if test ${enable_manual+y} then : enableval=$enable_manual; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - USE_MANUAL="1" - ;; + USE_MANUAL="1" + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - USE_MANUAL="1" + USE_MANUAL="1" fi @@ -22573,21 +22592,22 @@ if test ${enable_docs+y} then : enableval=$enable_docs; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - BUILD_DOCS=0 - USE_MANUAL=0 - curl_docs_msg="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + BUILD_DOCS=0 + USE_MANUAL=0 + curl_docs_msg="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - BUILD_DOCS=1 - ;; + BUILD_DOCS=1 + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - BUILD_DOCS=1 + BUILD_DOCS=1 fi @@ -22600,16 +22620,17 @@ if test ${enable_libcurl_option+y} then : enableval=$enable_libcurl_option; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_LIBCURL_OPTION 1" >>confdefs.h - curl_libcurl_msg="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + curl_libcurl_msg="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -22626,13 +22647,14 @@ if test ${enable_libgcc+y} then : enableval=$enable_libgcc; case "$enableval" in yes) - LIBS="-lgcc $LIBS" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + LIBS="-lgcc $LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -22677,10 +22699,12 @@ printf "%s\n" "$tst_lib_xnet_required" >&6; } ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes then : - HAVE_GETHOSTBYNAME="1" + + HAVE_GETHOSTBYNAME="1" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 printf %s "checking for gethostbyname in -lnsl... " >&6; } if test ${ac_cv_lib_nsl_gethostbyname+y} then : @@ -22717,17 +22741,19 @@ fi printf "%s\n" "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes then : - HAVE_GETHOSTBYNAME="1" - LIBS="-lnsl $LIBS" + + HAVE_GETHOSTBYNAME="1" + LIBS="-lnsl $LIBS" + fi + fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lsocket" >&5 printf %s "checking for gethostbyname in -lsocket... " >&6; } if test ${ac_cv_lib_socket_gethostbyname+y} @@ -22765,15 +22791,16 @@ fi printf "%s\n" "$ac_cv_lib_socket_gethostbyname" >&6; } if test "x$ac_cv_lib_socket_gethostbyname" = xyes then : - HAVE_GETHOSTBYNAME="1" - LIBS="-lsocket $LIBS" + + HAVE_GETHOSTBYNAME="1" + LIBS="-lsocket $LIBS" + fi fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lwatt" >&5 printf %s "checking for gethostbyname in -lwatt... " >&6; } if test ${ac_cv_lib_watt_gethostbyname+y} @@ -22811,17 +22838,18 @@ fi printf "%s\n" "$ac_cv_lib_watt_gethostbyname" >&6; } if test "x$ac_cv_lib_watt_gethostbyname" = xyes then : - HAVE_GETHOSTBYNAME="1" - CPPFLAGS="-I/dev/env/WATT_ROOT/inc" - LDFLAGS="-L/dev/env/WATT_ROOT/lib" - LIBS="-lwatt $LIBS" + + HAVE_GETHOSTBYNAME="1" + CPPFLAGS="-I${WATT_ROOT}/inc" + LDFLAGS="-L${WATT_ROOT}/lib" + LIBS="-lwatt $LIBS" + fi fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname with both nsl and socket libs" >&5 printf %s "checking for gethostbyname with both nsl and socket libs... " >&6; } my_ac_save_LIBS=$LIBS @@ -22859,8 +22887,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then if test "$curl_cv_native_windows" = "yes"; then winsock_LIB="-lws2_32" if test ! -z "$winsock_LIB"; then @@ -22910,8 +22937,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ fi fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname for Minix 3" >&5 printf %s "checking for gethostbyname for Minix 3... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -22948,8 +22974,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname for eCos" >&5 printf %s "checking for gethostbyname for eCos... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -22986,8 +23011,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -if test "$HAVE_GETHOSTBYNAME" != "1" -o "${with_amissl+set}" = set -then +if test "$HAVE_GETHOSTBYNAME" != "1" -o "${with_amissl+set}" = set; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname for AmigaOS bsdsocket.library" >&5 printf %s "checking for gethostbyname for AmigaOS bsdsocket.library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23035,8 +23059,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnetwork" >&5 printf %s "checking for gethostbyname in -lnetwork... " >&6; } if test ${ac_cv_lib_network_gethostbyname+y} @@ -23074,8 +23097,10 @@ fi printf "%s\n" "$ac_cv_lib_network_gethostbyname" >&6; } if test "x$ac_cv_lib_network_gethostbyname" = xyes then : - HAVE_GETHOSTBYNAME="1" - LIBS="-lnetwork $LIBS" + + HAVE_GETHOSTBYNAME="1" + LIBS="-lnetwork $LIBS" + fi @@ -23376,8 +23401,8 @@ printf "%s\n" "$curl_cv_gclk_LIBS" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if monotonic clock_gettime works" >&5 printf %s "checking if monotonic clock_gettime works... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -23430,8 +23455,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -23491,8 +23516,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -23584,20 +23609,20 @@ then : fi -if test "$OPT_ZLIB" = "no" ; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: zlib disabled" >&5 +if test "$OPT_ZLIB" = "no"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: zlib disabled" >&5 printf "%s\n" "$as_me: WARNING: zlib disabled" >&2;} else - if test "$OPT_ZLIB" = "yes" ; then + if test "$OPT_ZLIB" = "yes"; then OPT_ZLIB="" fi - if test -z "$OPT_ZLIB" ; then + if test -z "$OPT_ZLIB"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -23707,30 +23732,30 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib options with pkg-config" >&5 printf %s "checking for zlib options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists zlib >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists zlib >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then ZLIB_LIBS="`$PKGCONFIG --libs-only-l zlib`" if test -n "$ZLIB_LIBS"; then LDFLAGS="$LDFLAGS `$PKGCONFIG --libs-only-L zlib`" @@ -23783,28 +23808,33 @@ fi printf "%s\n" "$ac_cv_lib_z_inflateEnd" >&6; } if test "x$ac_cv_lib_z_inflateEnd" = xyes then : - HAVE_LIBZ="1" - ZLIB_LIBS="-lz" - LIBS="$ZLIB_LIBS $LIBS" + + HAVE_LIBZ="1" + ZLIB_LIBS="-lz" + LIBS="$ZLIB_LIBS $LIBS" + else $as_nop - OPT_ZLIB="/usr/local" + + OPT_ZLIB="/usr/local" + + fi fi fi if test -n "$OPT_ZLIB"; then - CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" - LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff" + CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" + LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff" fi ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes then : - HAVE_ZLIB_H="1" - if test "$HAVE_LIBZ" != "1"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 + HAVE_ZLIB_H="1" + if test "$HAVE_LIBZ" != "1"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 printf %s "checking for gzread in -lz... " >&6; } if test ${ac_cv_lib_z_gzread+y} then : @@ -23842,16 +23872,19 @@ printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } if test "x$ac_cv_lib_z_gzread" = xyes then : - HAVE_LIBZ="1" - ZLIB_LIBS="-lz" - LIBS="$ZLIB_LIBS $LIBS" + HAVE_LIBZ="1" + ZLIB_LIBS="-lz" + LIBS="$ZLIB_LIBS $LIBS" else $as_nop - CPPFLAGS=$clean_CPPFLAGS - LDFLAGS=$clean_LDFLAGS + + CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS + + fi - fi + fi else $as_nop @@ -23861,8 +23894,7 @@ else $as_nop fi - if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1" - then + if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: configure found only the libz lib, not the header file!" >&5 printf "%s\n" "$as_me: WARNING: configure found only the libz lib, not the header file!" >&2;} HAVE_LIBZ="" @@ -23870,16 +23902,14 @@ printf "%s\n" "$as_me: WARNING: configure found only the libz lib, not the heade LDFLAGS=$clean_LDFLAGS LIBS=$clean_LIBS ZLIB_LIBS="" - elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1" - then + elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: configure found only the libz header file, not the lib!" >&5 printf "%s\n" "$as_me: WARNING: configure found only the libz header file, not the lib!" >&2;} CPPFLAGS=$clean_CPPFLAGS LDFLAGS=$clean_LDFLAGS LIBS=$clean_LIBS ZLIB_LIBS="" - elif test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" = "1" - then + elif test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" = "1"; then printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h @@ -23921,12 +23951,12 @@ if test X"$OPT_BROTLI" != Xno; then CLEANLIBS="$LIBS" case "$OPT_BROTLI" in - yes) + yes) - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -24036,43 +24066,43 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libbrotlidec options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libbrotlidec options with pkg-config" >&5 printf %s "checking for libbrotlidec options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libbrotlidec >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libbrotlidec >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then - LIB_BROTLI=`$PKGCONFIG --libs-only-l libbrotlidec` - LD_BROTLI=`$PKGCONFIG --libs-only-L libbrotlidec` - CPP_BROTLI=`$PKGCONFIG --cflags-only-I libbrotlidec` - version=`$PKGCONFIG --modversion libbrotlidec` - DIR_BROTLI=`echo $LD_BROTLI | $SED -e 's/^-L//'` - fi + if test "$PKGCONFIG" != "no"; then + LIB_BROTLI=`$PKGCONFIG --libs-only-l libbrotlidec` + LD_BROTLI=`$PKGCONFIG --libs-only-L libbrotlidec` + CPP_BROTLI=`$PKGCONFIG --cflags-only-I libbrotlidec` + version=`$PKGCONFIG --modversion libbrotlidec` + DIR_BROTLI=`echo $LD_BROTLI | $SED -e 's/^-L//'` + fi - ;; - off) - ;; - *) - PREFIX_BROTLI=$OPT_BROTLI - ;; + ;; + off) + ;; + *) + PREFIX_BROTLI=$OPT_BROTLI + ;; esac if test -n "$PREFIX_BROTLI"; then @@ -24156,12 +24186,12 @@ done if test "$HAVE_BROTLI" = "1"; then if test -n "$DIR_BROTLI"; then - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_BROTLI" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_BROTLI to CURL_LIBRARY_PATH" >&5 + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_BROTLI" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_BROTLI to CURL_LIBRARY_PATH" >&5 printf "%s\n" "$as_me: Added $DIR_BROTLI to CURL_LIBRARY_PATH" >&6;} - fi + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libbrotlidec" else @@ -24187,12 +24217,12 @@ if test X"$OPT_ZSTD" != Xno; then CLEANLIBS="$LIBS" case "$OPT_ZSTD" in - yes) + yes) - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -24302,43 +24332,43 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libzstd options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libzstd options with pkg-config" >&5 printf %s "checking for libzstd options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libzstd >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libzstd >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then - LIB_ZSTD=`$PKGCONFIG --libs-only-l libzstd` - LD_ZSTD=`$PKGCONFIG --libs-only-L libzstd` - CPP_ZSTD=`$PKGCONFIG --cflags-only-I libzstd` - version=`$PKGCONFIG --modversion libzstd` - DIR_ZSTD=`echo $LD_ZSTD | $SED -e 's/-L//'` - fi + if test "$PKGCONFIG" != "no"; then + LIB_ZSTD=`$PKGCONFIG --libs-only-l libzstd` + LD_ZSTD=`$PKGCONFIG --libs-only-L libzstd` + CPP_ZSTD=`$PKGCONFIG --cflags-only-I libzstd` + version=`$PKGCONFIG --modversion libzstd` + DIR_ZSTD=`echo $LD_ZSTD | $SED -e 's/-L//'` + fi - ;; - off) - ;; - *) - PREFIX_ZSTD=$OPT_ZSTD - ;; + ;; + off) + ;; + *) + PREFIX_ZSTD=$OPT_ZSTD + ;; esac if test -n "$PREFIX_ZSTD"; then @@ -24422,12 +24452,12 @@ done if test "$HAVE_ZSTD" = "1"; then if test -n "$DIR_ZSTD"; then - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_ZSTD" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_ZSTD to CURL_LIBRARY_PATH" >&5 + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_ZSTD" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_ZSTD to CURL_LIBRARY_PATH" >&5 printf "%s\n" "$as_me: Added $DIR_ZSTD to CURL_LIBRARY_PATH" >&6;} - fi + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libzstd" else @@ -24456,7 +24486,7 @@ then : fi -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lber.h" >&5 @@ -24707,14 +24737,14 @@ printf "%s\n" "#define HAVE_LDAP_SSL_H 1" >>confdefs.h esac - if test -z "$LDAPLIBNAME" ; then + if test -z "$LDAPLIBNAME"; then if test "$curl_cv_native_windows" = "yes"; then LDAPLIBNAME="wldap32" LBERLIBNAME="no" fi fi - if test "$LDAPLIBNAME" ; then + if test "$LDAPLIBNAME"; then as_ac_Lib=`printf "%s\n" "ac_cv_lib_"$LDAPLIBNAME"""_ldap_init" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ldap_init in -l\"$LDAPLIBNAME\"" >&5 printf %s "checking for ldap_init in -l\"$LDAPLIBNAME\"... " >&6; } @@ -24904,10 +24934,10 @@ printf "%s\n" "#define CURL_DISABLE_LDAPS 1" >>confdefs.h fi fi -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then - if test "$LBERLIBNAME" ; then - if test "$LBERLIBNAME" != "no" ; then + if test "$LBERLIBNAME"; then + if test "$LBERLIBNAME" != "no"; then as_ac_Lib=`printf "%s\n" "ac_cv_lib_"$LBERLIBNAME"""_ber_free" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ber_free in -l\"$LBERLIBNAME\"" >&5 printf %s "checking for ber_free in -l\"$LBERLIBNAME\"... " >&6; } @@ -24973,7 +25003,7 @@ fi fi fi -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then ac_fn_c_check_func "$LINENO" "ldap_url_parse" "ac_cv_func_ldap_url_parse" if test "x$ac_cv_func_ldap_url_parse" = xyes then : @@ -25007,8 +25037,8 @@ printf "%s\n" "#define USE_OPENLDAP 1" >>confdefs.h fi fi -if test x$CURL_DISABLE_LDAPS != x1 ; then - curl_ldaps_msg="enabled" +if test x$CURL_DISABLE_LDAPS != x1; then + curl_ldaps_msg="enabled" fi @@ -25019,14 +25049,15 @@ if test ${enable_ipv6+y} then : enableval=$enable_ipv6; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ipv6=no - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ipv6=no + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ipv6=yes - ;; + ipv6=yes + ;; esac else $as_nop if test "$cross_compiling" = yes @@ -25115,7 +25146,7 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1" >>confdefs.h @@ -25134,8 +25165,8 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if argv can be written to" >&5 printf %s "checking if argv can be written to... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : curl_cv_writable_argv=cross @@ -25172,8 +25203,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -25217,27 +25248,27 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac case $curl_cv_writable_argv in -yes) + yes) printf "%s\n" "#define HAVE_WRITABLE_ARGV 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; -no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + ;; + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; -*) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: the previous check could not be made default was used" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: the previous check could not be made default was used" >&5 printf "%s\n" "$as_me: WARNING: the previous check could not be made default was used" >&2;} - ;; + ;; esac @@ -25247,9 +25278,11 @@ GSSAPI_ROOT="/usr" # Check whether --with-gssapi-includes was given. if test ${with_gssapi_includes+y} then : - withval=$with_gssapi_includes; GSSAPI_INCS="-I$withval" + withval=$with_gssapi_includes; + GSSAPI_INCS="-I$withval" want_gss="yes" + fi @@ -25257,9 +25290,11 @@ fi # Check whether --with-gssapi-libs was given. if test ${with_gssapi_libs+y} then : - withval=$with_gssapi_libs; GSSAPI_LIB_DIR="-L$withval" + withval=$with_gssapi_libs; + GSSAPI_LIB_DIR="-L$withval" want_gss="yes" + fi @@ -25268,13 +25303,14 @@ fi if test ${with_gssapi+y} then : withval=$with_gssapi; - GSSAPI_ROOT="$withval" - if test x"$GSSAPI_ROOT" != xno; then - want_gss="yes" - if test x"$GSSAPI_ROOT" = xyes; then - GSSAPI_ROOT="/usr" + GSSAPI_ROOT="$withval" + if test x"$GSSAPI_ROOT" != xno; then + want_gss="yes" + if test x"$GSSAPI_ROOT" = xyes; then + GSSAPI_ROOT="/usr" + fi fi - fi + fi @@ -25290,10 +25326,10 @@ printf "%s\n" "yes" >&6; } if test $GSSAPI_ROOT != "/usr"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -25403,34 +25439,34 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 printf %s "checking for mit-krb5-gssapi options with pkg-config... " >&6; } - itexists=` - if test -n "$GSSAPI_ROOT/lib/pkgconfig"; then - PKG_CONFIG_LIBDIR="$GSSAPI_ROOT/lib/pkgconfig" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$GSSAPI_ROOT/lib/pkgconfig"; then + PKG_CONFIG_LIBDIR="$GSSAPI_ROOT/lib/pkgconfig" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi else - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -25540,39 +25576,39 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 printf %s "checking for mit-krb5-gssapi options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi fi if test -z "$GSSAPI_INCS"; then - if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` - elif test "$PKGCONFIG" != "no" ; then - GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` - elif test -f "$KRB5CONFIG"; then - GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` - elif test "$GSSAPI_ROOT" != "yes"; then - GSSAPI_INCS="-I$GSSAPI_ROOT/include" - fi + if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` + elif test "$PKGCONFIG" != "no"; then + GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` + elif test -f "$KRB5CONFIG"; then + GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` + elif test "$GSSAPI_ROOT" != "yes"; then + GSSAPI_INCS="-I$GSSAPI_ROOT/include" + fi fi CPPFLAGS="$CPPFLAGS $GSSAPI_INCS" @@ -25628,8 +25664,8 @@ then : else $as_nop - want_gss=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: disabling GSS-API support since no header files were found" >&5 + want_gss=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: disabling GSS-API support since no header files were found" >&5 printf "%s\n" "$as_me: WARNING: disabling GSS-API support since no header files were found" >&2;} @@ -25697,17 +25733,17 @@ printf "%s\n" "#define HAVE_GSSAPI 1" >>confdefs.h LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" LIBS="-lgss $LIBS" elif test -z "$GSSAPI_LIB_DIR"; then - case $host in - *-*-darwin*) + case $host in + *-*-darwin*) LIBS="-lgssapi_krb5 -lresolv $LIBS" ;; - *) + *) if test $GSSAPI_ROOT != "/usr"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -25817,34 +25853,34 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 printf %s "checking for mit-krb5-gssapi options with pkg-config... " >&6; } - itexists=` - if test -n "$GSSAPI_ROOT/lib/pkgconfig"; then - PKG_CONFIG_LIBDIR="$GSSAPI_ROOT/lib/pkgconfig" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$GSSAPI_ROOT/lib/pkgconfig"; then + PKG_CONFIG_LIBDIR="$GSSAPI_ROOT/lib/pkgconfig" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi else - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -25954,67 +25990,67 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mit-krb5-gssapi options with pkg-config" >&5 printf %s "checking for mit-krb5-gssapi options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists mit-krb5-gssapi >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi fi if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` - LIBS="$gss_libs $LIBS" - elif test "$PKGCONFIG" != "no" ; then - gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` - LIBS="$gss_libs $LIBS" + gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` + LIBS="$gss_libs $LIBS" + elif test "$PKGCONFIG" != "no"; then + gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` + LIBS="$gss_libs $LIBS" elif test -f "$KRB5CONFIG"; then - gss_libs=`$KRB5CONFIG --libs gssapi` - LIBS="$gss_libs $LIBS" + gss_libs=`$KRB5CONFIG --libs gssapi` + LIBS="$gss_libs $LIBS" else - case $host in - *-hp-hpux*) + case $host in + *-hp-hpux*) gss_libname="gss" ;; - *) + *) gss_libname="gssapi" ;; - esac - - if test "$GSSAPI_ROOT" != "yes"; then - LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" - LIBS="-l$gss_libname $LIBS" - else - LIBS="-l$gss_libname $LIBS" - fi + esac + + if test "$GSSAPI_ROOT" != "yes"; then + LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" + LIBS="-l$gss_libname $LIBS" + else + LIBS="-l$gss_libname $LIBS" + fi fi ;; - esac + esac else - LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" - case $host in - *-hp-hpux*) + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + case $host in + *-hp-hpux*) LIBS="-lgss $LIBS" ;; - *) + *) LIBS="-lgssapi $LIBS" ;; - esac + esac fi else CPPFLAGS="$save_CPPFLAGS" @@ -26213,9 +26249,6 @@ printf "%s\n" "#define USE_AMISSL 1" >>confdefs.h printf "%s\n" "#define USE_OPENSSL 1" >>confdefs.h - -printf "%s\n" "#define HAVE_OPENSSL3 1" >>confdefs.h - ac_fn_c_check_header_compile "$LINENO" "openssl/x509.h" "ac_cv_header_openssl_x509_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_x509_h" = xyes then : @@ -26317,52 +26350,52 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ esac case "$OPT_OPENSSL" in - yes) - PKGTEST="yes" - PREFIX_OPENSSL= - ;; - *) - PKGTEST="no" - PREFIX_OPENSSL=$OPT_OPENSSL - - OPENSSL_PCDIR="$OPT_OPENSSL/lib/pkgconfig" - if test -f "$OPENSSL_PCDIR/openssl.pc"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&5 -printf "%s\n" "$as_me: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&6;} - PKGTEST="yes" - fi + yes) + PKGTEST="yes" + PREFIX_OPENSSL= + ;; + *) + PKGTEST="no" + PREFIX_OPENSSL=$OPT_OPENSSL - if test "$PKGTEST" != "yes"; then - # try lib64 instead - OPENSSL_PCDIR="$OPT_OPENSSL/lib64/pkgconfig" + OPENSSL_PCDIR="$OPT_OPENSSL/lib/pkgconfig" if test -f "$OPENSSL_PCDIR/openssl.pc"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&5 printf "%s\n" "$as_me: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&6;} PKGTEST="yes" fi - fi - if test "$PKGTEST" != "yes"; then - if test ! -f "$PREFIX_OPENSSL/include/openssl/ssl.h"; then - as_fn_error $? "$PREFIX_OPENSSL is a bad --with-openssl prefix!" "$LINENO" 5 + if test "$PKGTEST" != "yes"; then + # try lib64 instead + OPENSSL_PCDIR="$OPT_OPENSSL/lib64/pkgconfig" + if test -f "$OPENSSL_PCDIR/openssl.pc"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&5 +printf "%s\n" "$as_me: PKG_CONFIG_LIBDIR will be set to \"$OPENSSL_PCDIR\"" >&6;} + PKGTEST="yes" + fi fi - fi - LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" - if test "$PREFIX_OPENSSL" != "/usr" ; then - SSL_LDFLAGS="-L$LIB_OPENSSL" - SSL_CPPFLAGS="-I$PREFIX_OPENSSL/include" - fi - ;; + if test "$PKGTEST" != "yes"; then + if test ! -f "$PREFIX_OPENSSL/include/openssl/ssl.h"; then + as_fn_error $? "$PREFIX_OPENSSL is a bad --with-openssl prefix!" "$LINENO" 5 + fi + fi + + LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" + if test "$PREFIX_OPENSSL" != "/usr" ; then + SSL_LDFLAGS="-L$LIB_OPENSSL" + SSL_CPPFLAGS="-I$PREFIX_OPENSSL/include" + fi + ;; esac if test "$PKGTEST" = "yes"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -26472,49 +26505,49 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openssl options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openssl options with pkg-config" >&5 printf %s "checking for openssl options with pkg-config... " >&6; } - itexists=` - if test -n "$OPENSSL_PCDIR"; then - PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists openssl >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$OPENSSL_PCDIR"; then + PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists openssl >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no" ; then SSL_LIBS=` - if test -n "$OPENSSL_PCDIR"; then - PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$OPENSSL_PCDIR"; then + PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l --libs-only-other openssl 2>/dev/null` SSL_LDFLAGS=` - if test -n "$OPENSSL_PCDIR"; then - PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$OPENSSL_PCDIR"; then + PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L openssl 2>/dev/null` SSL_CPPFLAGS=` - if test -n "$OPENSSL_PCDIR"; then - PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$OPENSSL_PCDIR"; then + PKG_CONFIG_LIBDIR="$OPENSSL_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I openssl 2>/dev/null` @@ -26572,22 +26605,22 @@ printf "%s\n" "$ac_cv_lib_crypto_HMAC_Update" >&6; } if test "x$ac_cv_lib_crypto_HMAC_Update" = xyes then : - HAVECRYPTO="yes" - LIBS="-lcrypto $LIBS" + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS" else $as_nop - if test -n "$LIB_OPENSSL" ; then - LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL" - fi - if test "$PKGCONFIG" = "no" -a -n "$PREFIX_OPENSSL" ; then - # only set this if pkg-config wasn't used - CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include" - fi - # Linking previously failed, try extra paths from --with-openssl or - # pkg-config. Use a different function name to avoid reusing the earlier - # cached result. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HMAC_Init_ex in -lcrypto" >&5 + if test -n "$LIB_OPENSSL" ; then + LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL" + fi + if test "$PKGCONFIG" = "no" -a -n "$PREFIX_OPENSSL" ; then + # only set this if pkg-config wasn't used + CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include" + fi + # Linking previously failed, try extra paths from --with-openssl or + # pkg-config. Use a different function name to avoid reusing the earlier + # cached result. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for HMAC_Init_ex in -lcrypto" >&5 printf %s "checking for HMAC_Init_ex in -lcrypto... " >&6; } if test ${ac_cv_lib_crypto_HMAC_Init_ex+y} then : @@ -26625,23 +26658,23 @@ printf "%s\n" "$ac_cv_lib_crypto_HMAC_Init_ex" >&6; } if test "x$ac_cv_lib_crypto_HMAC_Init_ex" = xyes then : - HAVECRYPTO="yes" - LIBS="-lcrypto $LIBS" + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking OpenSSL linking with -ldl" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking OpenSSL linking with -ldl" >&5 printf %s "checking OpenSSL linking with -ldl... " >&6; } - LIBS="-lcrypto $CLEANLIBS -ldl" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + LIBS="-lcrypto $CLEANLIBS -ldl" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main (void) { - ERR_clear_error(); + ERR_clear_error(); ; return 0; @@ -26650,28 +26683,28 @@ _ACEOF if ac_fn_c_try_link "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - HAVECRYPTO="yes" + HAVECRYPTO="yes" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking OpenSSL linking with -ldl and -lpthread" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking OpenSSL linking with -ldl and -lpthread" >&5 printf %s "checking OpenSSL linking with -ldl and -lpthread... " >&6; } - LIBS="-lcrypto $CLEANLIBS -ldl -lpthread" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + LIBS="-lcrypto $CLEANLIBS -ldl -lpthread" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main (void) { - ERR_clear_error(); + ERR_clear_error(); ; return 0; @@ -26680,29 +26713,26 @@ _ACEOF if ac_fn_c_try_link "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - HAVECRYPTO="yes" + HAVECRYPTO="yes" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - LDFLAGS="$CLEANLDFLAGS" - CPPFLAGS="$CLEANCPPFLAGS" - LIBS="$CLEANLIBS" - + LDFLAGS="$CLEANLDFLAGS" + CPPFLAGS="$CLEANCPPFLAGS" + LIBS="$CLEANLIBS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - fi @@ -26756,11 +26786,11 @@ fi if test "$ac_cv_lib_ssl_SSL_connect" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ssl with RSAglue/rsaref libs in use" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ssl with RSAglue/rsaref libs in use" >&5 printf %s "checking for ssl with RSAglue/rsaref libs in use... " >&6; }; - OLIBS=$LIBS - LIBS="-lRSAglue -lrsaref $LIBS" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SSL_connect in -lssl" >&5 + OLIBS=$LIBS + LIBS="-lRSAglue -lrsaref $LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SSL_connect in -lssl" >&5 printf %s "checking for SSL_connect in -lssl... " >&6; } if test ${ac_cv_lib_ssl_SSL_connect+y} then : @@ -26803,14 +26833,14 @@ then : fi - if test "$ac_cv_lib_ssl_SSL_connect" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test "$ac_cv_lib_ssl_SSL_connect" != yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - LIBS=$OLIBS - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + LIBS=$OLIBS + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - fi + fi else @@ -26882,7 +26912,7 @@ fi fi if test X"$OPENSSL_ENABLED" != X"1"; then - LIBS="$CLEANLIBS" + LIBS="$CLEANLIBS" fi if test X"$OPT_OPENSSL" != Xoff && @@ -26899,14 +26929,14 @@ printf %s "checking for BoringSSL... " >&6; } /* end confdefs.h. */ - #include + #include int main (void) { - #ifndef OPENSSL_IS_BORINGSSL - #error not boringssl - #endif + #ifndef OPENSSL_IS_BORINGSSL + #error not boringssl + #endif ; return 0; @@ -26916,14 +26946,14 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ssl_msg="BoringSSL" - OPENSSL_IS_BORINGSSL=1 + ssl_msg="BoringSSL" + OPENSSL_IS_BORINGSSL=1 else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi @@ -26935,14 +26965,14 @@ printf %s "checking for AWS-LC... " >&6; } /* end confdefs.h. */ - #include + #include int main (void) { - #ifndef OPENSSL_IS_AWSLC - #error not AWS-LC - #endif + #ifndef OPENSSL_IS_AWSLC + #error not AWS-LC + #endif ; return 0; @@ -26952,14 +26982,14 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ssl_msg="AWS-LC" - OPENSSL_IS_BORINGSSL=1 + ssl_msg="AWS-LC" + OPENSSL_IS_BORINGSSL=1 else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi @@ -26971,7 +27001,7 @@ printf %s "checking for LibreSSL... " >&6; } /* end confdefs.h. */ -#include + #include int main (void) { @@ -27007,7 +27037,7 @@ printf %s "checking for OpenSSL >= v3... " >&6; } /* end confdefs.h. */ -#include + #include int main (void) { @@ -27028,9 +27058,6 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define HAVE_OPENSSL3 1" >>confdefs.h - ssl_msg="OpenSSL v3+" else $as_nop @@ -27063,12 +27090,12 @@ printf "%s\n" "$as_me: OpenSSL version does not speak QUIC API" >&6;} if test "$OPENSSL_ENABLED" = "1"; then if test -n "$LIB_OPENSSL"; then - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_OPENSSL" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $LIB_OPENSSL to CURL_LIBRARY_PATH" >&5 + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_OPENSSL" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $LIB_OPENSSL to CURL_LIBRARY_PATH" >&5 printf "%s\n" "$as_me: Added $LIB_OPENSSL to CURL_LIBRARY_PATH" >&6;} - fi + fi fi check_for_ca_bundle=1 LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE openssl" @@ -27078,7 +27105,7 @@ printf "%s\n" "$as_me: Added $LIB_OPENSSL to CURL_LIBRARY_PATH" >&6;} fi if test X"$OPT_OPENSSL" != Xno && - test "$OPENSSL_ENABLED" != "1"; then + test "$OPENSSL_ENABLED" != "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: OPT_OPENSSL: $OPT_OPENSSL" >&5 printf "%s\n" "$as_me: OPT_OPENSSL: $OPT_OPENSSL" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: OPENSSL_ENABLED: $OPENSSL_ENABLED" >&5 @@ -27086,55 +27113,6 @@ printf "%s\n" "$as_me: OPENSSL_ENABLED: $OPENSSL_ENABLED" >&6;} as_fn_error $? "--with-openssl was given but OpenSSL could not be detected" "$LINENO" 5 fi - -if test X"$OPENSSL_ENABLED" = X"1"; then - -# Check whether --with-random was given. -if test ${with_random+y} -then : - withval=$with_random; RANDOM_FILE="$withval" -else $as_nop - - if test x$cross_compiling != xyes; then - as_ac_File=`printf "%s\n" "ac_cv_file_"/dev/urandom"" | $as_tr_sh` -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for \"/dev/urandom\"" >&5 -printf %s "checking for \"/dev/urandom\"... " >&6; } -if eval test \${$as_ac_File+y} -then : - printf %s "(cached) " >&6 -else $as_nop - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r ""/dev/urandom""; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes" -then : - RANDOM_FILE="/dev/urandom" -fi - - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: skipped the /dev/urandom detection when cross-compiling" >&5 -printf "%s\n" "$as_me: WARNING: skipped the /dev/urandom detection when cross-compiling" >&2;} - fi - - -fi - - if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then - - -printf "%s\n" "#define RANDOM_FILE \"$RANDOM_FILE\"" >>confdefs.h - - fi -fi - if test "$OPENSSL_ENABLED" = "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SRP support in OpenSSL" >&5 printf %s "checking for SRP support in OpenSSL... " >&6; } @@ -27142,7 +27120,7 @@ printf %s "checking for SRP support in OpenSSL... " >&6; } /* end confdefs.h. */ -#include + #include int main (void) { @@ -27199,7 +27177,7 @@ printf %s "checking for QUIC support and OpenSSL >= 3.3... " >&6; } /* end confdefs.h. */ -#include + #include int main (void) { @@ -27219,11 +27197,7 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define HAVE_OPENSSL_QUIC 1" >>confdefs.h - - HAVE_OPENSSL_QUIC=1 - + have_openssl_quic=1 else $as_nop @@ -27249,10 +27223,10 @@ if test "x$OPT_GNUTLS" != xno; then if test "x$OPT_GNUTLS" = "xyes"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -27362,27 +27336,27 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnutls options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnutls options with pkg-config" >&5 printf %s "checking for gnutls options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists gnutls >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists gnutls >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no" ; then @@ -27430,7 +27404,7 @@ printf "%s\n" "found" >&6; } LIBS="$addlib $LIBS" LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnutls_x509_crt_get_dn2 in -lgnutls" >&5 @@ -27474,18 +27448,18 @@ then : printf "%s\n" "#define USE_GNUTLS 1" >>confdefs.h - USE_GNUTLS=1 + USE_GNUTLS=1 - GNUTLS_ENABLED=1 - USE_GNUTLS="yes" - ssl_msg="GnuTLS" - QUIC_ENABLED=yes - test gnutls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + GNUTLS_ENABLED=1 + USE_GNUTLS="yes" + ssl_msg="GnuTLS" + QUIC_ENABLED=yes + test gnutls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else $as_nop - LIBS="$CLEANLIBS" - CPPFLAGS="$CLEANCPPFLAGS" + LIBS="$CLEANLIBS" + CPPFLAGS="$CLEANCPPFLAGS" fi @@ -27647,7 +27621,7 @@ then : printf "%s\n" "#define HAVE_GNUTLS_SRP 1" >>confdefs.h - HAVE_GNUTLS_SRP=1 + HAVE_GNUTLS_SRP=1 fi @@ -27711,12 +27685,12 @@ then : printf "%s\n" "#define USE_MBEDTLS 1" >>confdefs.h - USE_MBEDTLS=1 + USE_MBEDTLS=1 - MBEDTLS_ENABLED=1 - USE_MBEDTLS="yes" - ssl_msg="mbedTLS" - test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes fi @@ -27734,7 +27708,7 @@ fi LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mbedtls_ssl_init in -lmbedtls" >&5 @@ -27778,17 +27752,17 @@ then : printf "%s\n" "#define USE_MBEDTLS 1" >>confdefs.h - USE_MBEDTLS=1 + USE_MBEDTLS=1 - MBEDTLS_ENABLED=1 - USE_MBEDTLS="yes" - ssl_msg="mbedTLS" - test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else $as_nop - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags fi @@ -27841,10 +27815,10 @@ if test "x$OPT_WOLFSSL" != xno; then fi - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -27954,27 +27928,27 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wolfssl options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wolfssl options with pkg-config" >&5 printf %s "checking for wolfssl options with pkg-config... " >&6; } - itexists=` - if test -n "$wolfpkg"; then - PKG_CONFIG_LIBDIR="$wolfpkg" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists wolfssl >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$wolfpkg"; then + PKG_CONFIG_LIBDIR="$wolfpkg" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists wolfssl >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Check dir $wolfpkg" >&5 printf "%s\n" "$as_me: Check dir $wolfpkg" >&6;} @@ -27984,31 +27958,31 @@ printf "%s\n" "$as_me: Check dir $wolfpkg" >&6;} addcflags="" if test "$PKGCONFIG" != "no" ; then addlib=` - if test -n "$wolfpkg"; then - PKG_CONFIG_LIBDIR="$wolfpkg" - export PKG_CONFIG_LIBDIR - fi + if test -n "$wolfpkg"; then + PKG_CONFIG_LIBDIR="$wolfpkg" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l wolfssl` addld=` - if test -n "$wolfpkg"; then - PKG_CONFIG_LIBDIR="$wolfpkg" - export PKG_CONFIG_LIBDIR - fi + if test -n "$wolfpkg"; then + PKG_CONFIG_LIBDIR="$wolfpkg" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L wolfssl` addcflags=` - if test -n "$wolfpkg"; then - PKG_CONFIG_LIBDIR="$wolfpkg" - export PKG_CONFIG_LIBDIR - fi + if test -n "$wolfpkg"; then + PKG_CONFIG_LIBDIR="$wolfpkg" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I wolfssl` version=` - if test -n "$wolfpkg"; then - PKG_CONFIG_LIBDIR="$wolfpkg" - export PKG_CONFIG_LIBDIR - fi + if test -n "$wolfpkg"; then + PKG_CONFIG_LIBDIR="$wolfpkg" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --modversion wolfssl` wolfssllibpath=`echo $addld | $SED -e 's/^-L//'` @@ -28027,8 +28001,8 @@ printf "%s\n" "$as_me: Check dir $wolfpkg" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Add $addld to LDFLAGS" >&5 printf "%s\n" "$as_me: Add $addld to LDFLAGS" >&6;} if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Add $addcflags to CPPFLAGS" >&5 + CPPFLAGS="$CPPFLAGS $addcflags" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Add $addcflags to CPPFLAGS" >&5 printf "%s\n" "$as_me: Add $addcflags to CPPFLAGS" >&6;} fi @@ -28063,26 +28037,26 @@ _ACEOF if ac_fn_c_try_link "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define USE_WOLFSSL 1" >>confdefs.h - USE_WOLFSSL=1 + USE_WOLFSSL=1 - WOLFSSL_ENABLED=1 - USE_WOLFSSL="yes" - ssl_msg="wolfSSL" - QUIC_ENABLED=yes - test wolfssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + WOLFSSL_ENABLED=1 + USE_WOLFSSL="yes" + ssl_msg="wolfSSL" + QUIC_ENABLED=yes + test wolfssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags - wolfssllibpath="" + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + wolfssllibpath="" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -28101,7 +28075,7 @@ printf "%s\n" "$as_me: detected wolfSSL" >&6;} printf %s "checking size of long long... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -28110,9 +28084,9 @@ printf %s "checking size of long long... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(long long) == $typesize):; - } + case 0: + case (sizeof(long long) == $typesize):; + } ; return 0; @@ -28121,10 +28095,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -28168,7 +28142,7 @@ then : printf "%s\n" "#define HAVE_WOLFSSL_DES_ECB_ENCRYPT 1" >>confdefs.h - WOLFSSL_NTLM=1 + WOLFSSL_NTLM=1 fi @@ -28181,7 +28155,7 @@ then : printf "%s\n" "#define HAVE_WOLFSSL_FULL_BIO 1" >>confdefs.h - WOLFSSL_FULL_BIO=1 + WOLFSSL_FULL_BIO=1 fi @@ -28197,7 +28171,7 @@ printf "%s\n" "$as_me: Added $wolfssllibpath to CURL_LIBRARY_PATH" >&6;} fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE wolfssl" else - as_fn_error $? "--with-wolfssl but wolfSSL was not found or doesn't work" "$LINENO" 5 + as_fn_error $? "--with-wolfssl but wolfSSL was not found or doesn't work" "$LINENO" 5 fi fi @@ -28261,12 +28235,12 @@ then : printf "%s\n" "#define USE_BEARSSL 1" >>confdefs.h - USE_BEARSSL=1 + USE_BEARSSL=1 - BEARSSL_ENABLED=1 - USE_BEARSSL="yes" - ssl_msg="BearSSL" - test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + BEARSSL_ENABLED=1 + USE_BEARSSL="yes" + ssl_msg="BearSSL" + test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes fi @@ -28284,7 +28258,7 @@ fi LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for br_ssl_client_init_full in -lbearssl" >&5 @@ -28328,17 +28302,17 @@ then : printf "%s\n" "#define USE_BEARSSL 1" >>confdefs.h - USE_BEARSSL=1 + USE_BEARSSL=1 - BEARSSL_ENABLED=1 - USE_BEARSSL="yes" - ssl_msg="BearSSL" - test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + BEARSSL_ENABLED=1 + USE_BEARSSL="yes" + ssl_msg="BearSSL" + test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else $as_nop - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags fi @@ -28469,7 +28443,7 @@ printf "%s\n" "#define USE_RUSTLS 1" >>confdefs.h test rustls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else $as_nop - as_fn_error $? "--with-rustls was specified but could not find rustls." "$LINENO" 5 + as_fn_error $? "--with-rustls was specified but could not find Rustls." "$LINENO" 5 fi @@ -28485,10 +28459,10 @@ fi if test "$PKGTEST" = "yes"; then - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -28598,49 +28572,49 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rustls options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rustls options with pkg-config" >&5 printf %s "checking for rustls options with pkg-config... " >&6; } - itexists=` - if test -n "$RUSTLS_PCDIR"; then - PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists rustls >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$RUSTLS_PCDIR"; then + PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists rustls >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no" ; then SSL_LIBS=` - if test -n "$RUSTLS_PCDIR"; then - PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$RUSTLS_PCDIR"; then + PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l --libs-only-other rustls 2>/dev/null` SSL_LDFLAGS=` - if test -n "$RUSTLS_PCDIR"; then - PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$RUSTLS_PCDIR"; then + PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L rustls 2>/dev/null` SSL_CPPFLAGS=` - if test -n "$RUSTLS_PCDIR"; then - PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$RUSTLS_PCDIR"; then + PKG_CONFIG_LIBDIR="$RUSTLS_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I rustls 2>/dev/null` @@ -28664,7 +28638,7 @@ printf "%s\n" "#define USE_RUSTLS 1" >>confdefs.h RUSTLS_ENABLED=1 test rustls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else - as_fn_error $? "pkg-config: Could not find rustls" "$LINENO" 5 + as_fn_error $? "pkg-config: Could not find Rustls" "$LINENO" 5 fi else @@ -28675,8 +28649,8 @@ printf "%s\n" "#define USE_RUSTLS 1" >>confdefs.h LDFLAGS="$CLAN_LDFLAGS $SSL_LDFLAGS" if test "x$USE_RUSTLS" = "xyes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: detected rustls" >&5 -printf "%s\n" "$as_me: detected rustls" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: detected Rustls" >&5 +printf "%s\n" "$as_me: detected Rustls" >&6;} check_for_ca_bundle=1 if test -n "$LIB_RUSTLS"; then @@ -28711,55 +28685,51 @@ if test "x$curl_cv_native_windows" = "xyes"; then LIBS="-lbcrypt $LIBS" fi -case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED" -in -x) - as_fn_error $? "TLS not detected, you will not be able to use HTTPS, FTPS, NTLM and more. +case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED" in + x) + as_fn_error $? "TLS not detected, you will not be able to use HTTPS, FTPS, NTLM and more. Use --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl or --with-rustls to address this." "$LINENO" 5 - ;; -x1) - # one SSL backend is enabled + ;; + x1) + # one SSL backend is enabled - SSL_ENABLED="1" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: built with one SSL backend" >&5 + SSL_ENABLED="1" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: built with one SSL backend" >&5 printf "%s\n" "$as_me: built with one SSL backend" >&6;} - ;; -xD) - # explicitly built without TLS - ;; -xD*) - as_fn_error $? "--without-ssl has been set together with an explicit option to use an ssl library + ;; + xD) + # explicitly built without TLS + ;; + xD*) + as_fn_error $? "--without-ssl has been set together with an explicit option to use an ssl library (e.g. --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl, --with-rustls). Since these are conflicting parameters, verify which is the desired one and drop the other." "$LINENO" 5 - ;; -*) - # more than one SSL backend is enabled + ;; + *) + # more than one SSL backend is enabled - SSL_ENABLED="1" + SSL_ENABLED="1" - CURL_WITH_MULTI_SSL="1" + CURL_WITH_MULTI_SSL="1" printf "%s\n" "#define CURL_WITH_MULTI_SSL 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: built with multiple SSL backends" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: built with multiple SSL backends" >&5 printf "%s\n" "$as_me: built with multiple SSL backends" >&6;} - ;; + ;; esac if test -n "$ssl_backends"; then curl_ssl_msg="enabled ($ssl_backends)" fi -if test no = "$VALID_DEFAULT_SSL_BACKEND" -then - if test -n "$SSL_ENABLED" - then +if test no = "$VALID_DEFAULT_SSL_BACKEND"; then + if test -n "$SSL_ENABLED"; then as_fn_error $? "Default SSL backend $DEFAULT_SSL_BACKEND not enabled!" "$LINENO" 5 else as_fn_error $? "Default SSL backend requires SSL!" "$LINENO" 5 fi -elif test yes = "$VALID_DEFAULT_SSL_BACKEND" -then +elif test yes = "$VALID_DEFAULT_SSL_BACKEND"; then printf "%s\n" "#define CURL_DEFAULT_SSL_BACKEND \"$DEFAULT_SSL_BACKEND\"" >>confdefs.h @@ -28896,8 +28866,8 @@ printf "%s\n" "$capath (capath)" >&6; } printf "%s\n" "no" >&6; } fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use builtin CA store of SSL library" >&5 -printf %s "checking whether to use builtin CA store of SSL library... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use built-in CA store of SSL library" >&5 +printf %s "checking whether to use built-in CA store of SSL library... " >&6; } # Check whether --with-ca-fallback was given. if test ${with_ca_fallback+y} @@ -28922,9 +28892,49 @@ printf "%s\n" "#define CURL_CA_FALLBACK 1" >>confdefs.h fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CA cert bundle path to embed" >&5 +printf %s "checking CA cert bundle path to embed... " >&6; } + + +# Check whether --with-ca-embed was given. +if test ${with_ca_embed+y} +then : + withval=$with_ca_embed; + want_ca_embed="$withval" + if test "x$want_ca_embed" = "xyes"; then + as_fn_error $? "--with-ca-embed=FILE requires a path to the CA bundle" "$LINENO" 5 + fi + +else $as_nop + want_ca_embed="unset" +fi + + + CURL_CA_EMBED='' + if test "x$want_ca_embed" != "xno" -a "x$want_ca_embed" != "xunset" -a -f "$want_ca_embed"; then + CURL_CA_EMBED='"'$want_ca_embed'"' + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $want_ca_embed" >&5 +printf "%s\n" "$want_ca_embed" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + +fi + + if test "x$CURL_CA_EMBED" != "x"; then + CURL_CA_EMBED_SET_TRUE= + CURL_CA_EMBED_SET_FALSE='#' +else + CURL_CA_EMBED_SET_TRUE='#' + CURL_CA_EMBED_SET_FALSE= fi + OPT_LIBPSL=off # Check whether --with-libpsl was given. @@ -28940,12 +28950,12 @@ if test X"$OPT_LIBPSL" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBPSL" in - yes) + yes|off) - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -29055,45 +29065,42 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpsl options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpsl options with pkg-config" >&5 printf %s "checking for libpsl options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libpsl >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libpsl >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then - LIB_PSL=`$PKGCONFIG --libs-only-l libpsl` - LD_PSL=`$PKGCONFIG --libs-only-L libpsl` - CPP_PSL=`$PKGCONFIG --cflags-only-I libpsl` - else - LIB_PSL="-lpsl" - fi + if test "$PKGCONFIG" != "no"; then + LIB_PSL=`$PKGCONFIG --libs-only-l libpsl` + LD_PSL=`$PKGCONFIG --libs-only-L libpsl` + CPP_PSL=`$PKGCONFIG --cflags-only-I libpsl` + else + LIB_PSL="-lpsl" + fi - ;; - off) - LIB_PSL="-lpsl" - ;; - *) - LIB_PSL="-lpsl" - PREFIX_PSL=$OPT_LIBPSL - ;; + ;; + *) + LIB_PSL="-lpsl" + PREFIX_PSL=$OPT_LIBPSL + ;; esac if test -n "$PREFIX_PSL"; then @@ -29143,7 +29150,7 @@ printf "%s\n" "$ac_cv_lib_psl_psl_builtin" >&6; } if test "x$ac_cv_lib_psl_psl_builtin" = xyes then : - for ac_header in libpsl.h + for ac_header in libpsl.h do : ac_fn_c_check_header_compile "$LINENO" "libpsl.h" "ac_cv_header_libpsl_h" "$ac_includes_default" if test "x$ac_cv_header_libpsl_h" = xyes @@ -29170,8 +29177,7 @@ else $as_nop fi - if test X"$OPT_LIBPSL" != Xoff && - test "$LIBPSL_ENABLED" != "1"; then + if test "$LIBPSL_ENABLED" != "1"; then as_fn_error $? "libpsl libs and/or directories were not found where specified!" "$LINENO" 5 fi fi @@ -29256,10 +29262,11 @@ then : printf "%s\n" "#define USE_GSASL 1" >>confdefs.h + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libgsasl" else $as_nop curl_gsasl_msg="no (libgsasl not found)"; - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libgsasl was not found" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libgsasl was not found" >&5 printf "%s\n" "$as_me: WARNING: libgsasl was not found" >&2;} @@ -29324,262 +29331,12 @@ if test X"$OPT_LIBSSH2" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBSSH2" in - yes) - - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_PKGCONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $PKGCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/bin:/usr/local/bin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKGCONFIG=$ac_cv_path_PKGCONFIG -if test -n "$PKGCONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 -printf "%s\n" "$PKGCONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKGCONFIG"; then - ac_pt_PKGCONFIG=$PKGCONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_ac_pt_PKGCONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $ac_pt_PKGCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/bin:/usr/local/bin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG -if test -n "$ac_pt_PKGCONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 -printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_pt_PKGCONFIG" = x; then - PKGCONFIG="no" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKGCONFIG=$ac_pt_PKGCONFIG - fi -else - PKGCONFIG="$ac_cv_path_PKGCONFIG" -fi - - fi - - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh2 options with pkg-config" >&5 -printf %s "checking for libssh2 options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libssh2 >/dev/null 2>&1 && echo 1` - - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 -printf "%s\n" "found" >&6; } - fi - fi - - - if test "$PKGCONFIG" != "no" ; then - LIB_SSH2=`$PKGCONFIG --libs-only-l libssh2` - LD_SSH2=`$PKGCONFIG --libs-only-L libssh2` - CPP_SSH2=`$PKGCONFIG --cflags-only-I libssh2` - version=`$PKGCONFIG --modversion libssh2` - DIR_SSH2=`echo $LD_SSH2 | $SED -e 's/^-L//'` - fi - - ;; - off) - ;; - *) - PREFIX_SSH2=$OPT_LIBSSH2 - ;; - esac - - if test -n "$PREFIX_SSH2"; then - LIB_SSH2="-lssh2" - LD_SSH2=-L${PREFIX_SSH2}/lib$libsuff - CPP_SSH2=-I${PREFIX_SSH2}/include - DIR_SSH2=${PREFIX_SSH2}/lib$libsuff - fi - - LDFLAGS="$LDFLAGS $LD_SSH2" - CPPFLAGS="$CPPFLAGS $CPP_SSH2" - LIBS="$LIB_SSH2 $LIBS" - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh2_session_block_directions in -lssh2" >&5 -printf %s "checking for libssh2_session_block_directions in -lssh2... " >&6; } -if test ${ac_cv_lib_ssh2_libssh2_session_block_directions+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssh2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#ifdef __cplusplus -extern "C" -#endif -char libssh2_session_block_directions (); -int main (void) -{ -return libssh2_session_block_directions (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_ssh2_libssh2_session_block_directions=yes -else $as_nop - ac_cv_lib_ssh2_libssh2_session_block_directions=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_libssh2_session_block_directions" >&5 -printf "%s\n" "$ac_cv_lib_ssh2_libssh2_session_block_directions" >&6; } -if test "x$ac_cv_lib_ssh2_libssh2_session_block_directions" = xyes -then : - printf "%s\n" "#define HAVE_LIBSSH2 1" >>confdefs.h - - LIBS="-lssh2 $LIBS" - -fi - - - ac_fn_c_check_header_compile "$LINENO" "libssh2.h" "ac_cv_header_libssh2_h" "$ac_includes_default" -if test "x$ac_cv_header_libssh2_h" = xyes -then : - curl_ssh_msg="enabled (libssh2)" - LIBSSH2_ENABLED=1 - -printf "%s\n" "#define USE_LIBSSH2 1" >>confdefs.h - - USE_LIBSSH2=1 - - -fi - - - if test X"$OPT_LIBSSH2" != Xoff && - test "$LIBSSH2_ENABLED" != "1"; then - as_fn_error $? "libssh2 libs and/or directories were not found where specified!" "$LINENO" 5 - fi - - if test "$LIBSSH2_ENABLED" = "1"; then - if test -n "$DIR_SSH2"; then + yes) - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH2" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_SSH2 to CURL_LIBRARY_PATH" >&5 -printf "%s\n" "$as_me: Added $DIR_SSH2 to CURL_LIBRARY_PATH" >&6;} - fi - fi - LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libssh2" + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" else - LDFLAGS=$CLEANLDFLAGS - CPPFLAGS=$CLEANCPPFLAGS - LIBS=$CLEANLIBS - fi -elif test X"$OPT_LIBSSH" != Xno; then - CLEANLDFLAGS="$LDFLAGS" - CLEANCPPFLAGS="$CPPFLAGS" - CLEANLIBS="$LIBS" - - case "$OPT_LIBSSH" in - yes) - - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -29689,43 +29446,293 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh options with pkg-config" >&5 -printf %s "checking for libssh options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libssh >/dev/null 2>&1 && echo 1` + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh2 options with pkg-config" >&5 +printf %s "checking for libssh2 options with pkg-config... " >&6; } + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libssh2 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then - LIB_SSH=`$PKGCONFIG --libs-only-l libssh` - LD_SSH=`$PKGCONFIG --libs-only-L libssh` - CPP_SSH=`$PKGCONFIG --cflags-only-I libssh` - version=`$PKGCONFIG --modversion libssh` - DIR_SSH=`echo $LD_SSH | $SED -e 's/^-L//'` + if test "$PKGCONFIG" != "no"; then + LIB_SSH2=`$PKGCONFIG --libs-only-l libssh2` + LD_SSH2=`$PKGCONFIG --libs-only-L libssh2` + CPP_SSH2=`$PKGCONFIG --cflags-only-I libssh2` + version=`$PKGCONFIG --modversion libssh2` + DIR_SSH2=`echo $LD_SSH2 | $SED -e 's/^-L//'` + fi + + ;; + off) + ;; + *) + PREFIX_SSH2=$OPT_LIBSSH2 + ;; + esac + + if test -n "$PREFIX_SSH2"; then + LIB_SSH2="-lssh2" + LD_SSH2=-L${PREFIX_SSH2}/lib$libsuff + CPP_SSH2=-I${PREFIX_SSH2}/include + DIR_SSH2=${PREFIX_SSH2}/lib$libsuff + fi + + LDFLAGS="$LDFLAGS $LD_SSH2" + CPPFLAGS="$CPPFLAGS $CPP_SSH2" + LIBS="$LIB_SSH2 $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh2_session_block_directions in -lssh2" >&5 +printf %s "checking for libssh2_session_block_directions in -lssh2... " >&6; } +if test ${ac_cv_lib_ssh2_libssh2_session_block_directions+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssh2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#ifdef __cplusplus +extern "C" +#endif +char libssh2_session_block_directions (); +int main (void) +{ +return libssh2_session_block_directions (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ssh2_libssh2_session_block_directions=yes +else $as_nop + ac_cv_lib_ssh2_libssh2_session_block_directions=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_libssh2_session_block_directions" >&5 +printf "%s\n" "$ac_cv_lib_ssh2_libssh2_session_block_directions" >&6; } +if test "x$ac_cv_lib_ssh2_libssh2_session_block_directions" = xyes +then : + printf "%s\n" "#define HAVE_LIBSSH2 1" >>confdefs.h + + LIBS="-lssh2 $LIBS" + +fi + + + ac_fn_c_check_header_compile "$LINENO" "libssh2.h" "ac_cv_header_libssh2_h" "$ac_includes_default" +if test "x$ac_cv_header_libssh2_h" = xyes +then : + curl_ssh_msg="enabled (libssh2)" + LIBSSH2_ENABLED=1 + +printf "%s\n" "#define USE_LIBSSH2 1" >>confdefs.h + + USE_LIBSSH2=1 + + +fi + + + if test X"$OPT_LIBSSH2" != Xoff && + test "$LIBSSH2_ENABLED" != "1"; then + as_fn_error $? "libssh2 libs and/or directories were not found where specified!" "$LINENO" 5 + fi + + if test "$LIBSSH2_ENABLED" = "1"; then + if test -n "$DIR_SSH2"; then + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH2" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_SSH2 to CURL_LIBRARY_PATH" >&5 +printf "%s\n" "$as_me: Added $DIR_SSH2 to CURL_LIBRARY_PATH" >&6;} + fi fi + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libssh2" + else + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + fi +elif test X"$OPT_LIBSSH" != Xno; then + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" - ;; - off) - ;; + case "$OPT_LIBSSH" in + yes) + + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. + ;; *) - PREFIX_SSH=$OPT_LIBSSH - ;; + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKGCONFIG=$ac_cv_path_PKGCONFIG +if test -n "$PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 +printf "%s\n" "$PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + + fi + + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssh options with pkg-config" >&5 +printf %s "checking for libssh options with pkg-config... " >&6; } + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libssh >/dev/null 2>&1 && echo 1` + + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 +printf "%s\n" "found" >&6; } + fi + fi + + + if test "$PKGCONFIG" != "no"; then + LIB_SSH=`$PKGCONFIG --libs-only-l libssh` + LD_SSH=`$PKGCONFIG --libs-only-L libssh` + CPP_SSH=`$PKGCONFIG --cflags-only-I libssh` + version=`$PKGCONFIG --modversion libssh` + DIR_SSH=`echo $LD_SSH | $SED -e 's/^-L//'` + fi + + ;; + off) + ;; + *) + PREFIX_SSH=$OPT_LIBSSH + ;; esac if test -n "$PREFIX_SSH"; then @@ -29803,14 +29810,17 @@ fi fi if test "$LIBSSH_ENABLED" = "1"; then + if test "$curl_cv_native_windows" = "yes"; then + LIBS="-liphlpapi $LIBS" + fi if test -n "$DIR_SSH"; then - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_SSH to CURL_LIBRARY_PATH" >&5 + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_SSH to CURL_LIBRARY_PATH" >&5 printf "%s\n" "$as_me: Added $DIR_SSH to CURL_LIBRARY_PATH" >&6;} - fi + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libssh" else @@ -29823,11 +29833,10 @@ elif test X"$OPT_WOLFSSH" != Xno; then CLEANCPPFLAGS="$CPPFLAGS" CLEANLIBS="$LIBS" - if test "$OPT_WOLFSSH" != yes; then - WOLFCONFIG="$OPT_WOLFSSH/bin/wolfssh-config" - LDFLAGS="$LDFLAGS `$WOLFCONFIG --libs`" - CPPFLAGS="$CPPFLAGS `$WOLFCONFIG --cflags`" + WOLFCONFIG="$OPT_WOLFSSH/bin/wolfssh-config" + LDFLAGS="$LDFLAGS `$WOLFCONFIG --libs`" + CPPFLAGS="$CPPFLAGS `$WOLFCONFIG --cflags`" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wolfSSH_Init in -lwolfssh" >&5 @@ -29891,7 +29900,6 @@ printf "%s\n" "#define USE_WOLFSSH 1" >>confdefs.h fi done - fi @@ -29910,12 +29918,12 @@ if test X"$OPT_LIBRTMP" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBRTMP" in - yes) + yes) - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -30025,47 +30033,47 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for librtmp options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for librtmp options with pkg-config" >&5 printf %s "checking for librtmp options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists librtmp >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists librtmp >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then - LIB_RTMP=`$PKGCONFIG --libs-only-l librtmp` - LD_RTMP=`$PKGCONFIG --libs-only-L librtmp` - CPP_RTMP=`$PKGCONFIG --cflags-only-I librtmp` - version=`$PKGCONFIG --modversion librtmp` - DIR_RTMP=`echo $LD_RTMP | $SED -e 's/^-L//'` - else - as_fn_error $? "--librtmp was specified but could not find librtmp pkgconfig file." "$LINENO" 5 - fi + if test "$PKGCONFIG" != "no"; then + LIB_RTMP=`$PKGCONFIG --libs-only-l librtmp` + LD_RTMP=`$PKGCONFIG --libs-only-L librtmp` + CPP_RTMP=`$PKGCONFIG --cflags-only-I librtmp` + version=`$PKGCONFIG --modversion librtmp` + DIR_RTMP=`echo $LD_RTMP | $SED -e 's/^-L//'` + else + as_fn_error $? "--librtmp was specified but could not find librtmp pkgconfig file." "$LINENO" 5 + fi - ;; - off) - LIB_RTMP="-lrtmp" - ;; - *) - LIB_RTMP="-lrtmp" - PREFIX_RTMP=$OPT_LIBRTMP - ;; + ;; + off) + LIB_RTMP="-lrtmp" + ;; + *) + LIB_RTMP="-lrtmp" + PREFIX_RTMP=$OPT_LIBRTMP + ;; esac if test -n "$PREFIX_RTMP"; then @@ -30116,7 +30124,7 @@ printf "%s\n" "$ac_cv_lib_rtmp_RTMP_Init" >&6; } if test "x$ac_cv_lib_rtmp_RTMP_Init" = xyes then : - for ac_header in librtmp/rtmp.h + for ac_header in librtmp/rtmp.h do : ac_fn_c_check_header_compile "$LINENO" "librtmp/rtmp.h" "ac_cv_header_librtmp_rtmp_h" "$ac_includes_default" if test "x$ac_cv_header_librtmp_rtmp_h" = xyes @@ -30147,7 +30155,6 @@ fi test "$LIBRTMP_ENABLED" != "1"; then as_fn_error $? "librtmp libs and/or directories were not found where specified!" "$LINENO" 5 fi - fi @@ -30164,33 +30171,38 @@ printf "%s\n" "yes" >&6; } printf %s "checking if libraries can be versioned... " >&6; } GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` if test -z "$GLD"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You need an ld version supporting the --version-script option" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You need an ld version supporting the --version-script option" >&5 printf "%s\n" "$as_me: WARNING: You need an ld version supporting the --version-script option" >&2;} else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - if test "x$CURL_WITH_MULTI_SSL" = "x1"; then - versioned_symbols_flavour="MULTISSL_" - elif test "x$OPENSSL_ENABLED" = "x1"; then - versioned_symbols_flavour="OPENSSL_" - elif test "x$GNUTLS_ENABLED" = "x1"; then - versioned_symbols_flavour="GNUTLS_" - elif test "x$WOLFSSL_ENABLED" = "x1"; then - versioned_symbols_flavour="WOLFSSL_" - elif test "x$SCHANNEL_ENABLED" = "x1"; then - versioned_symbols_flavour="SCHANNEL_" - elif test "x$SECURETRANSPORT_ENABLED" = "x1"; then - versioned_symbols_flavour="SECURE_TRANSPORT_" - else - versioned_symbols_flavour="" - fi - versioned_symbols="yes" + if test "x$CURL_WITH_MULTI_SSL" = "x1"; then + versioned_symbols_flavour="MULTISSL_" + elif test "x$OPENSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="OPENSSL_" + elif test "x$MBEDTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="MBEDTLS_" + elif test "x$BEARSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="BEARSSL_" + elif test "x$GNUTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="GNUTLS_" + elif test "x$WOLFSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="WOLFSSL_" + elif test "x$SCHANNEL_ENABLED" = "x1"; then + versioned_symbols_flavour="SCHANNEL_" + elif test "x$SECURETRANSPORT_ENABLED" = "x1"; then + versioned_symbols_flavour="SECURE_TRANSPORT_" + else + versioned_symbols_flavour="" + fi + versioned_symbols="yes" fi ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac @@ -30216,9 +30228,48 @@ fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable Windows native IDN (Windows native builds only)" >&5 +want_winuni="no" +if test "$curl_cv_native_windows" = "yes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable Windows Unicode (Windows native builds only)" >&5 +printf %s "checking whether to enable Windows Unicode (Windows native builds only)... " >&6; } + # Check whether --enable-windows-unicode was given. +if test ${enable_windows_unicode+y} +then : + enableval=$enable_windows_unicode; case "$enableval" in + yes) + CPPFLAGS="${CPPFLAGS} -DUNICODE -D_UNICODE" + want_winuni="yes" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi + +fi + + if test "$want_winuni" = "yes"; then + USE_UNICODE_TRUE= + USE_UNICODE_FALSE='#' +else + USE_UNICODE_TRUE='#' + USE_UNICODE_FALSE= +fi + + + +tst_links_winidn='no' +if test "$curl_cv_native_windows" = 'yes'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable Windows native IDN (Windows native builds only)" >&5 printf %s "checking whether to enable Windows native IDN (Windows native builds only)... " >&6; } -OPT_WINIDN="default" + OPT_WINIDN="default" # Check whether --with-winidn was given. if test ${with_winidn+y} @@ -30226,129 +30277,190 @@ then : withval=$with_winidn; OPT_WINIDN=$withval fi -case "$OPT_WINIDN" in - no|default) - want_winidn="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + case "$OPT_WINIDN" in + no|default) + want_winidn="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; - yes) - want_winidn="yes" - want_winidn_path="default" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + yes) + want_winidn="yes" + want_winidn_path="default" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; - *) - want_winidn="yes" - want_winidn_path="$withval" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($withval)" >&5 + ;; + *) + want_winidn="yes" + want_winidn_path="$withval" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($withval)" >&5 printf "%s\n" "yes ($withval)" >&6; } - ;; -esac + ;; + esac -if test "$want_winidn" = "yes"; then - clean_CFLAGS="$CFLAGS" - clean_CPPFLAGS="$CPPFLAGS" - clean_LDFLAGS="$LDFLAGS" - clean_LIBS="$LIBS" - WINIDN_LIBS="-lnormaliz" - WINIDN_CPPFLAGS="" - # - if test "$want_winidn_path" != "default"; then - WINIDN_LDFLAGS="-L$want_winidn_path/lib$libsuff" - WINIDN_CPPFLAGS="-I$want_winidn_path/include" - WINIDN_DIR="$want_winidn_path/lib$libsuff" - fi - # + if test "$want_winidn" = "yes"; then + clean_CPPFLAGS="$CPPFLAGS" + clean_LDFLAGS="$LDFLAGS" + clean_LIBS="$LIBS" + WINIDN_LIBS="-lnormaliz" + WINIDN_CPPFLAGS="" + # + if test "$want_winidn_path" != "default"; then + WINIDN_LDFLAGS="-L$want_winidn_path/lib$libsuff" + WINIDN_CPPFLAGS="-I$want_winidn_path/include" + fi + # + CPPFLAGS="$CPPFLAGS $WINIDN_CPPFLAGS" + LDFLAGS="$LDFLAGS $WINIDN_LDFLAGS" + LIBS="$WINIDN_LIBS $LIBS" + # + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if IdnToUnicode can be linked" >&5 +printf %s "checking if IdnToUnicode can be linked... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main (void) { - #if (WINVER < 0x600) && (_WIN32_WINNT < 0x600) - #error - #endif + #if (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600) && \ + (!defined(WINVER) || WINVER < 0x600) + WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, + const WCHAR *lpASCIICharStr, + int cchASCIIChar, + WCHAR *lpUnicodeCharStr, + int cchUnicodeChar); + #endif + IdnToUnicode(0, NULL, 0, NULL, 0); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO" +if ac_fn_c_try_link "$LINENO" then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + tst_links_winidn="yes" else $as_nop - CFLAGS=`echo $CFLAGS | $SED -e 's/-DWINVER=[^ ]*//g'` - CFLAGS=`echo $CFLAGS | $SED -e 's/-D_WIN32_WINNT=[^ ]*//g'` - CPPFLAGS=`echo $CPPFLAGS | $SED -e 's/-DWINVER=[^ ]*//g'` - CPPFLAGS=`echo $CPPFLAGS | $SED -e 's/-D_WIN32_WINNT=[^ ]*//g'` - WINIDN_CPPFLAGS="$WINIDN_CPPFLAGS -DWINVER=0x0600" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + tst_links_winidn="no" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - # - CPPFLAGS="$CPPFLAGS $WINIDN_CPPFLAGS" - LDFLAGS="$LDFLAGS $WINIDN_LDFLAGS" - LIBS="$WINIDN_LIBS $LIBS" - # - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if IdnToUnicode can be linked" >&5 -printf %s "checking if IdnToUnicode can be linked... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + # + if test "$tst_links_winidn" = "yes"; then +printf "%s\n" "#define USE_WIN32_IDN 1" >>confdefs.h - #include + IDN_ENABLED=1 -int main (void) -{ + curl_idn_msg="enabled (Windows-native)" + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find libraries for IDN support: IDN disabled" >&5 +printf "%s\n" "$as_me: WARNING: Cannot find libraries for IDN support: IDN disabled" >&2;} + CPPFLAGS="$clean_CPPFLAGS" + LDFLAGS="$clean_LDFLAGS" + LIBS="$clean_LIBS" + fi + fi +fi + + +tst_links_appleidn='no' +case $host_os in + darwin*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build with Apple IDN" >&5 +printf %s "checking whether to build with Apple IDN... " >&6; } + OPT_IDN="default" + +# Check whether --with-apple-idn was given. +if test ${with_apple_idn+y} +then : + withval=$with_apple_idn; OPT_IDN=$withval +fi + + case "$OPT_IDN" in + yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes, check" >&5 +printf "%s\n" "yes, check" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uidna_openUTS46 in -licucore" >&5 +printf %s "checking for uidna_openUTS46 in -licucore... " >&6; } +if test ${ac_cv_lib_icucore_uidna_openUTS46+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-licucore $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - IdnToUnicode(0, NULL, 0, NULL, 0); +#ifdef __cplusplus +extern "C" +#endif +char uidna_openUTS46 (); +int main (void) +{ +return uidna_openUTS46 (); ; return 0; } - _ACEOF if ac_fn_c_try_link "$LINENO" then : - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - tst_links_winidn="yes" - + ac_cv_lib_icucore_uidna_openUTS46=yes else $as_nop - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - tst_links_winidn="no" - + ac_cv_lib_icucore_uidna_openUTS46=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - # - if test "$tst_links_winidn" = "yes"; then +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_icucore_uidna_openUTS46" >&5 +printf "%s\n" "$ac_cv_lib_icucore_uidna_openUTS46" >&6; } +if test "x$ac_cv_lib_icucore_uidna_openUTS46" = xyes +then : -printf "%s\n" "#define USE_WIN32_IDN 1" >>confdefs.h + for ac_header in unicode/uidna.h +do : + ac_fn_c_check_header_compile "$LINENO" "unicode/uidna.h" "ac_cv_header_unicode_uidna_h" "$ac_includes_default" +if test "x$ac_cv_header_unicode_uidna_h" = xyes +then : + printf "%s\n" "#define HAVE_UNICODE_UIDNA_H 1" >>confdefs.h + curl_idn_msg="enabled (AppleIDN)" - IDN_ENABLED=1 +printf "%s\n" "#define USE_APPLE_IDN 1" >>confdefs.h + + USE_APPLE_IDN=1 + + IDN_ENABLED=1 + + LIBS="-licucore -liconv $LIBS" + tst_links_appleidn='yes' + +fi + +done - curl_idn_msg="enabled (Windows-native)" - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find libraries for IDN support: IDN disabled" >&5 -printf "%s\n" "$as_me: WARNING: Cannot find libraries for IDN support: IDN disabled" >&2;} - CFLAGS="$clean_CFLAGS" - CPPFLAGS="$clean_CPPFLAGS" - LDFLAGS="$clean_LDFLAGS" - LIBS="$clean_LIBS" - fi fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac + ;; +esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build with libidn2" >&5 printf %s "checking whether to build with libidn2... " >&6; } @@ -30362,8 +30474,12 @@ fi if test "x$tst_links_winidn" = "xyes"; then want_idn="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (using winidn instead)" >&5 -printf "%s\n" "no (using winidn instead)" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (using WinIDN instead)" >&5 +printf "%s\n" "no (using WinIDN instead)" >&6; } +elif test "x$tst_links_appleidn" = "xyes"; then + want_idn="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (using AppleIDN instead)" >&5 +printf "%s\n" "no (using AppleIDN instead)" >&6; } else case "$OPT_IDN" in no) @@ -30401,10 +30517,10 @@ if test "$want_idn" = "yes"; then if test "$want_idn_path" != "default"; then IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -30514,46 +30630,46 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libidn2 options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libidn2 options with pkg-config" >&5 printf %s "checking for libidn2 options with pkg-config... " >&6; } - itexists=` - if test -n "$IDN_PCDIR"; then - PKG_CONFIG_LIBDIR="$IDN_PCDIR" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libidn2 >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$IDN_PCDIR"; then + PKG_CONFIG_LIBDIR="$IDN_PCDIR" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libidn2 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no"; then IDN_LIBS=` - if test -n "$IDN_PCDIR"; then - PKG_CONFIG_LIBDIR="$IDN_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$IDN_PCDIR"; then + PKG_CONFIG_LIBDIR="$IDN_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libidn2 2>/dev/null` IDN_LDFLAGS=` - if test -n "$IDN_PCDIR"; then - PKG_CONFIG_LIBDIR="$IDN_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$IDN_PCDIR"; then + PKG_CONFIG_LIBDIR="$IDN_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libidn2 2>/dev/null` IDN_CPPFLAGS=` - if test -n "$IDN_PCDIR"; then - PKG_CONFIG_LIBDIR="$IDN_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$IDN_PCDIR"; then + PKG_CONFIG_LIBDIR="$IDN_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libidn2 2>/dev/null` IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/^-L//'` else @@ -30564,10 +30680,10 @@ printf "%s\n" "found" >&6; } fi else - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -30677,27 +30793,27 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libidn2 options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libidn2 options with pkg-config" >&5 printf %s "checking for libidn2 options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libidn2 >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libidn2 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no"; then IDN_LIBS=`$PKGCONFIG --libs-only-l libidn2 2>/dev/null` @@ -30803,11 +30919,12 @@ printf "%s\n" "$as_me: Added $IDN_DIR to CURL_LIBRARY_PATH" >&6;} fi LIBCURL_PC_REQUIRES_PRIVATE="libidn2 $LIBCURL_PC_REQUIRES_PRIVATE" else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find libraries for IDN support: IDN disabled" >&5 -printf "%s\n" "$as_me: WARNING: Cannot find libraries for IDN support: IDN disabled" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find libidn2" >&5 +printf "%s\n" "$as_me: WARNING: Cannot find libidn2" >&2;} CPPFLAGS="$clean_CPPFLAGS" LDFLAGS="$clean_LDFLAGS" LIBS="$clean_LIBS" + want_idn="no" fi fi @@ -30848,10 +30965,10 @@ if test X"$want_nghttp2" != Xno; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -30961,54 +31078,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnghttp2 options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnghttp2 options with pkg-config" >&5 printf %s "checking for libnghttp2 options with pkg-config... " >&6; } - itexists=` - if test -n "$want_nghttp2_pkg_config_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libnghttp2 >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_nghttp2_pkg_config_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libnghttp2 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_H2=` - if test -n "$want_nghttp2_pkg_config_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp2_pkg_config_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libnghttp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_H2" >&5 printf "%s\n" "$as_me: -l is $LIB_H2" >&6;} CPP_H2=` - if test -n "$want_nghttp2_pkg_config_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp2_pkg_config_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libnghttp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_H2" >&5 printf "%s\n" "$as_me: -I is $CPP_H2" >&6;} LD_H2=` - if test -n "$want_nghttp2_pkg_config_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp2_pkg_config_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp2_pkg_config_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libnghttp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_H2" >&5 @@ -31070,7 +31187,7 @@ printf "%s\n" "$ac_cv_lib_nghttp2_nghttp2_session_get_stream_local_window_size" if test "x$ac_cv_lib_nghttp2_nghttp2_session_get_stream_local_window_size" = xyes then : - for ac_header in nghttp2/nghttp2.h + for ac_header in nghttp2/nghttp2.h do : ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default" if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes @@ -31089,9 +31206,9 @@ fi done - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_H2" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_H2 to CURL_LIBRARY_PATH" >&5 + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_H2" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_H2 to CURL_LIBRARY_PATH" >&5 printf "%s\n" "$as_me: Added $DIR_H2 to CURL_LIBRARY_PATH" >&6;} else $as_nop @@ -31144,10 +31261,10 @@ if test X"$want_tcp2" != Xno; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -31257,54 +31374,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2 options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2 options with pkg-config" >&5 printf %s "checking for libngtcp2 options with pkg-config... " >&6; } - itexists=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libngtcp2 >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libngtcp2 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_TCP2=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libngtcp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_TCP2" >&5 printf "%s\n" "$as_me: -l is $LIB_TCP2" >&6;} CPP_TCP2=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libngtcp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_TCP2" >&5 printf "%s\n" "$as_me: -I is $CPP_TCP2" >&6;} LD_TCP2=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libngtcp2` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_TCP2" >&5 @@ -31355,7 +31472,7 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_ngtcp2_conn_client_new_versioned" >&6; } if test "x$ac_cv_lib_ngtcp2_ngtcp2_conn_client_new_versioned" = xyes then : - for ac_header in ngtcp2/ngtcp2.h + for ac_header in ngtcp2/ngtcp2.h do : ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2.h" "ac_cv_header_ngtcp2_ngtcp2_h" "$ac_includes_default" if test "x$ac_cv_header_ngtcp2_ngtcp2_h" = xyes @@ -31390,7 +31507,6 @@ fi as_fn_error $? "--with-ngtcp2 was specified but could not find ngtcp2 pkg-config file." "$LINENO" 5 fi fi - fi if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS_BORINGSSL" != "x1"; then @@ -31399,10 +31515,10 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -31512,54 +31628,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_quictls options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_quictls options with pkg-config" >&5 printf %s "checking for libngtcp2_crypto_quictls options with pkg-config... " >&6; } - itexists=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libngtcp2_crypto_quictls >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libngtcp2_crypto_quictls >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_QUICTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libngtcp2_crypto_quictls` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGTCP2_CRYPTO_QUICTLS" >&5 printf "%s\n" "$as_me: -l is $LIB_NGTCP2_CRYPTO_QUICTLS" >&6;} CPP_NGTCP2_CRYPTO_QUICTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libngtcp2_crypto_quictls` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGTCP2_CRYPTO_QUICTLS" >&5 printf "%s\n" "$as_me: -I is $CPP_NGTCP2_CRYPTO_QUICTLS" >&6;} LD_NGTCP2_CRYPTO_QUICTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libngtcp2_crypto_quictls` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGTCP2_CRYPTO_QUICTLS" >&5 @@ -31610,7 +31726,7 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_recv_client_initia if test "x$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_recv_client_initial_cb" = xyes then : - for ac_header in ngtcp2/ngtcp2_crypto.h + for ac_header in ngtcp2/ngtcp2_crypto.h do : ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_h" "$ac_includes_default" if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_h" = xyes @@ -31653,10 +31769,10 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -31766,54 +31882,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_boringssl options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_boringssl options with pkg-config" >&5 printf %s "checking for libngtcp2_crypto_boringssl options with pkg-config... " >&6; } - itexists=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libngtcp2_crypto_boringssl >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libngtcp2_crypto_boringssl >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_BORINGSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libngtcp2_crypto_boringssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGTCP2_CRYPTO_BORINGSSL" >&5 printf "%s\n" "$as_me: -l is $LIB_NGTCP2_CRYPTO_BORINGSSL" >&6;} CPP_NGTCP2_CRYPTO_BORINGSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libngtcp2_crypto_boringssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGTCP2_CRYPTO_BORINGSSL" >&5 printf "%s\n" "$as_me: -I is $CPP_NGTCP2_CRYPTO_BORINGSSL" >&6;} LD_NGTCP2_CRYPTO_BORINGSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libngtcp2_crypto_boringssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGTCP2_CRYPTO_BORINGSSL" >&5 @@ -31864,7 +31980,7 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_boringssl_ngtcp2_crypto_recv_client_init if test "x$ac_cv_lib_ngtcp2_crypto_boringssl_ngtcp2_crypto_recv_client_initial_cb" = xyes then : - for ac_header in ngtcp2/ngtcp2_crypto.h + for ac_header in ngtcp2/ngtcp2_crypto.h do : ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_h" "$ac_includes_default" if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_h" = xyes @@ -31907,10 +32023,264 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$GNUTLS_ENABLED" = "x1"; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKGCONFIG=$ac_cv_path_PKGCONFIG +if test -n "$PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 +printf "%s\n" "$PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + + fi + + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_gnutls options with pkg-config" >&5 +printf %s "checking for libngtcp2_crypto_gnutls options with pkg-config... " >&6; } + itexists=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libngtcp2_crypto_gnutls >/dev/null 2>&1 && echo 1` + + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else - if test -n "$ac_tool_prefix"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 +printf "%s\n" "found" >&6; } + fi + fi + + + if test "$PKGCONFIG" != "no"; then + LIB_NGTCP2_CRYPTO_GNUTLS=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + + $PKGCONFIG --libs-only-l libngtcp2_crypto_gnutls` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGTCP2_CRYPTO_GNUTLS" >&5 +printf "%s\n" "$as_me: -l is $LIB_NGTCP2_CRYPTO_GNUTLS" >&6;} + + CPP_NGTCP2_CRYPTO_GNUTLS=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --cflags-only-I libngtcp2_crypto_gnutls` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGTCP2_CRYPTO_GNUTLS" >&5 +printf "%s\n" "$as_me: -I is $CPP_NGTCP2_CRYPTO_GNUTLS" >&6;} + + LD_NGTCP2_CRYPTO_GNUTLS=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + + $PKGCONFIG --libs-only-L libngtcp2_crypto_gnutls` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGTCP2_CRYPTO_GNUTLS" >&5 +printf "%s\n" "$as_me: -L is $LD_NGTCP2_CRYPTO_GNUTLS" >&6;} + + LDFLAGS="$LDFLAGS $LD_NGTCP2_CRYPTO_GNUTLS" + CPPFLAGS="$CPPFLAGS $CPP_NGTCP2_CRYPTO_GNUTLS" + LIBS="$LIB_NGTCP2_CRYPTO_GNUTLS $LIBS" + + if test "x$cross_compiling" != "xyes"; then + DIR_NGTCP2_CRYPTO_GNUTLS=`echo $LD_NGTCP2_CRYPTO_GNUTLS | $SED -e 's/^-L//'` + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_recv_client_initial_cb in -lngtcp2_crypto_gnutls" >&5 +printf %s "checking for ngtcp2_crypto_recv_client_initial_cb in -lngtcp2_crypto_gnutls... " >&6; } +if test ${ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lngtcp2_crypto_gnutls $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#ifdef __cplusplus +extern "C" +#endif +char ngtcp2_crypto_recv_client_initial_cb (); +int main (void) +{ +return ngtcp2_crypto_recv_client_initial_cb (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb=yes +else $as_nop + ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" >&5 +printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" >&6; } +if test "x$ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" = xyes +then : + + for ac_header in ngtcp2/ngtcp2_crypto.h +do : + ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_h" "$ac_includes_default" +if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_h" = xyes +then : + printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_H 1" >>confdefs.h + NGTCP2_ENABLED=1 + +printf "%s\n" "#define USE_NGTCP2_CRYPTO_GNUTLS 1" >>confdefs.h + + USE_NGTCP2_CRYPTO_GNUTLS=1 + + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGTCP2_CRYPTO_GNUTLS" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH" >&5 +printf "%s\n" "$as_me: Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH" >&6;} + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_gnutls" + +fi + +done + +else $as_nop + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + +fi + + + else + if test X"$want_tcp2" != Xdefault; then + as_fn_error $? "--with-ngtcp2 was specified but could not find ngtcp2_crypto_gnutls pkg-config file." "$LINENO" 5 + fi + fi +fi + +if test "x$NGTCP2_ENABLED" = "x1" -a "x$WOLFSSL_ENABLED" = "x1"; then + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -32020,308 +32390,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi - - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_gnutls options with pkg-config" >&5 -printf %s "checking for libngtcp2_crypto_gnutls options with pkg-config... " >&6; } - itexists=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libngtcp2_crypto_gnutls >/dev/null 2>&1 && echo 1` - - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 -printf "%s\n" "found" >&6; } - fi - fi - - - if test "$PKGCONFIG" != "no" ; then - LIB_NGTCP2_CRYPTO_GNUTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - - $PKGCONFIG --libs-only-l libngtcp2_crypto_gnutls` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGTCP2_CRYPTO_GNUTLS" >&5 -printf "%s\n" "$as_me: -l is $LIB_NGTCP2_CRYPTO_GNUTLS" >&6;} - - CPP_NGTCP2_CRYPTO_GNUTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --cflags-only-I libngtcp2_crypto_gnutls` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGTCP2_CRYPTO_GNUTLS" >&5 -printf "%s\n" "$as_me: -I is $CPP_NGTCP2_CRYPTO_GNUTLS" >&6;} - - LD_NGTCP2_CRYPTO_GNUTLS=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - - $PKGCONFIG --libs-only-L libngtcp2_crypto_gnutls` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGTCP2_CRYPTO_GNUTLS" >&5 -printf "%s\n" "$as_me: -L is $LD_NGTCP2_CRYPTO_GNUTLS" >&6;} - - LDFLAGS="$LDFLAGS $LD_NGTCP2_CRYPTO_GNUTLS" - CPPFLAGS="$CPPFLAGS $CPP_NGTCP2_CRYPTO_GNUTLS" - LIBS="$LIB_NGTCP2_CRYPTO_GNUTLS $LIBS" - - if test "x$cross_compiling" != "xyes"; then - DIR_NGTCP2_CRYPTO_GNUTLS=`echo $LD_NGTCP2_CRYPTO_GNUTLS | $SED -e 's/^-L//'` - fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_recv_client_initial_cb in -lngtcp2_crypto_gnutls" >&5 -printf %s "checking for ngtcp2_crypto_recv_client_initial_cb in -lngtcp2_crypto_gnutls... " >&6; } -if test ${ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lngtcp2_crypto_gnutls $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#ifdef __cplusplus -extern "C" -#endif -char ngtcp2_crypto_recv_client_initial_cb (); -int main (void) -{ -return ngtcp2_crypto_recv_client_initial_cb (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb=yes -else $as_nop - ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" >&5 -printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" >&6; } -if test "x$ac_cv_lib_ngtcp2_crypto_gnutls_ngtcp2_crypto_recv_client_initial_cb" = xyes -then : - - for ac_header in ngtcp2/ngtcp2_crypto.h -do : - ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_h" "$ac_includes_default" -if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_h" = xyes -then : - printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_H 1" >>confdefs.h - NGTCP2_ENABLED=1 - -printf "%s\n" "#define USE_NGTCP2_CRYPTO_GNUTLS 1" >>confdefs.h - - USE_NGTCP2_CRYPTO_GNUTLS=1 - - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGTCP2_CRYPTO_GNUTLS" - export CURL_LIBRARY_PATH - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH" >&5 -printf "%s\n" "$as_me: Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH" >&6;} - LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_gnutls" - -fi - -done - -else $as_nop - LDFLAGS=$CLEANLDFLAGS - CPPFLAGS=$CLEANCPPFLAGS - LIBS=$CLEANLIBS - -fi - - - else - if test X"$want_tcp2" != Xdefault; then - as_fn_error $? "--with-ngtcp2 was specified but could not find ngtcp2_crypto_gnutls pkg-config file." "$LINENO" 5 - fi - fi -fi - -if test "x$NGTCP2_ENABLED" = "x1" -a "x$WOLFSSL_ENABLED" = "x1"; then - CLEANLDFLAGS="$LDFLAGS" - CLEANCPPFLAGS="$CPPFLAGS" - CLEANLIBS="$LIBS" - - - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_PKGCONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $PKGCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/bin:/usr/local/bin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKGCONFIG=$ac_cv_path_PKGCONFIG -if test -n "$PKGCONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 -printf "%s\n" "$PKGCONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKGCONFIG"; then - ac_pt_PKGCONFIG=$PKGCONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_ac_pt_PKGCONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $ac_pt_PKGCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/bin:/usr/local/bin" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG -if test -n "$ac_pt_PKGCONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 -printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - if test "x$ac_pt_PKGCONFIG" = x; then - PKGCONFIG="no" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKGCONFIG=$ac_pt_PKGCONFIG - fi -else - PKGCONFIG="$ac_cv_path_PKGCONFIG" -fi - - fi - - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_wolfssl options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2_crypto_wolfssl options with pkg-config" >&5 printf %s "checking for libngtcp2_crypto_wolfssl options with pkg-config... " >&6; } - itexists=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libngtcp2_crypto_wolfssl >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libngtcp2_crypto_wolfssl >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_WOLFSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libngtcp2_crypto_wolfssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGTCP2_CRYPTO_WOLFSSL" >&5 printf "%s\n" "$as_me: -l is $LIB_NGTCP2_CRYPTO_WOLFSSL" >&6;} CPP_NGTCP2_CRYPTO_WOLFSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libngtcp2_crypto_wolfssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGTCP2_CRYPTO_WOLFSSL" >&5 printf "%s\n" "$as_me: -I is $CPP_NGTCP2_CRYPTO_WOLFSSL" >&6;} LD_NGTCP2_CRYPTO_WOLFSSL=` - if test -n "$want_tcp2_path"; then - PKG_CONFIG_LIBDIR="$want_tcp2_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_tcp2_path"; then + PKG_CONFIG_LIBDIR="$want_tcp2_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libngtcp2_crypto_wolfssl` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGTCP2_CRYPTO_WOLFSSL" >&5 @@ -32372,7 +32488,7 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_wolfssl_ngtcp2_crypto_recv_client_initia if test "x$ac_cv_lib_ngtcp2_crypto_wolfssl_ngtcp2_crypto_recv_client_initial_cb" = xyes then : - for ac_header in ngtcp2/ngtcp2_crypto.h + for ac_header in ngtcp2/ngtcp2_crypto.h do : ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_h" "$ac_includes_default" if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_h" = xyes @@ -32439,7 +32555,7 @@ if test "x$want_openssl_quic" = "xyes"; then if test "$NGTCP2_ENABLED" = 1; then as_fn_error $? "--with-openssl-quic and --with-ngtcp2 are mutually exclusive" "$LINENO" 5 fi - if test "$HAVE_OPENSSL_QUIC" != 1; then + if test "$have_openssl_quic" != 1; then as_fn_error $? "--with-openssl-quic requires quic support and OpenSSL >= 3.3.0" "$LINENO" 5 fi @@ -32492,10 +32608,10 @@ if test X"$want_nghttp3" != Xno; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -32605,54 +32721,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnghttp3 options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnghttp3 options with pkg-config" >&5 printf %s "checking for libnghttp3 options with pkg-config... " >&6; } - itexists=` - if test -n "$want_nghttp3_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp3_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libnghttp3 >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_nghttp3_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp3_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libnghttp3 >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGHTTP3=` - if test -n "$want_nghttp3_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp3_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp3_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp3_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libnghttp3` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_NGHTTP3" >&5 printf "%s\n" "$as_me: -l is $LIB_NGHTTP3" >&6;} CPP_NGHTTP3=` - if test -n "$want_nghttp3_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp3_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp3_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp3_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libnghttp3` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_NGHTTP3" >&5 printf "%s\n" "$as_me: -I is $CPP_NGHTTP3" >&6;} LD_NGHTTP3=` - if test -n "$want_nghttp3_path"; then - PKG_CONFIG_LIBDIR="$want_nghttp3_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_nghttp3_path"; then + PKG_CONFIG_LIBDIR="$want_nghttp3_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libnghttp3` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_NGHTTP3" >&5 @@ -32703,7 +32819,7 @@ printf "%s\n" "$ac_cv_lib_nghttp3_nghttp3_conn_client_new_versioned" >&6; } if test "x$ac_cv_lib_nghttp3_nghttp3_conn_client_new_versioned" = xyes then : - for ac_header in nghttp3/nghttp3.h + for ac_header in nghttp3/nghttp3.h do : ac_fn_c_check_header_compile "$LINENO" "nghttp3/nghttp3.h" "ac_cv_header_nghttp3_nghttp3_h" "$ac_includes_default" if test "x$ac_cv_header_nghttp3_nghttp3_h" = xyes @@ -32737,7 +32853,6 @@ fi as_fn_error $? "--with-nghttp3 was specified but could not find nghttp3 pkg-config file." "$LINENO" 5 fi fi - fi @@ -32809,10 +32924,10 @@ if test X"$want_quiche" != Xno; then CLEANLIBS="$LIBS" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -32922,54 +33037,54 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for quiche options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for quiche options with pkg-config" >&5 printf %s "checking for quiche options with pkg-config... " >&6; } - itexists=` - if test -n "$want_quiche_path"; then - PKG_CONFIG_LIBDIR="$want_quiche_path" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists quiche >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$want_quiche_path"; then + PKG_CONFIG_LIBDIR="$want_quiche_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists quiche >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_QUICHE=` - if test -n "$want_quiche_path"; then - PKG_CONFIG_LIBDIR="$want_quiche_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_quiche_path"; then + PKG_CONFIG_LIBDIR="$want_quiche_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l quiche` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_QUICHE" >&5 printf "%s\n" "$as_me: -l is $LIB_QUICHE" >&6;} CPP_QUICHE=` - if test -n "$want_quiche_path"; then - PKG_CONFIG_LIBDIR="$want_quiche_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_quiche_path"; then + PKG_CONFIG_LIBDIR="$want_quiche_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I quiche` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_QUICHE" >&5 printf "%s\n" "$as_me: -I is $CPP_QUICHE" >&6;} LD_QUICHE=` - if test -n "$want_quiche_path"; then - PKG_CONFIG_LIBDIR="$want_quiche_path" - export PKG_CONFIG_LIBDIR - fi + if test -n "$want_quiche_path"; then + PKG_CONFIG_LIBDIR="$want_quiche_path" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L quiche` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_QUICHE" >&5 @@ -33020,7 +33135,7 @@ printf "%s\n" "$ac_cv_lib_quiche_quiche_conn_send_ack_eliciting" >&6; } if test "x$ac_cv_lib_quiche_quiche_conn_send_ack_eliciting" = xyes then : - for ac_header in quiche.h + for ac_header in quiche.h do : ac_fn_c_check_header_compile "$LINENO" "quiche.h" "ac_cv_header_quiche_h" " $ac_includes_default @@ -33167,7 +33282,7 @@ printf "%s\n" "$ac_cv_lib_msh3_MsH3ApiOpen" >&6; } if test "x$ac_cv_lib_msh3_MsH3ApiOpen" = xyes then : - for ac_header in msh3.h + for ac_header in msh3.h do : ac_fn_c_check_header_compile "$LINENO" "msh3.h" "ac_cv_header_msh3_h" "$ac_includes_default" if test "x$ac_cv_header_msh3_h" = xyes @@ -33201,6 +33316,288 @@ fi fi +OPT_LIBUV=no + +# Check whether --with-libuv was given. +if test ${with_libuv+y} +then : + withval=$with_libuv; OPT_LIBUV=$withval +fi + +case "$OPT_LIBUV" in + no) + want_libuv="no" + ;; + yes) + want_libuv="default" + want_libuv_path="" + ;; + *) + want_libuv="yes" + want_libuv_path="$withval" + ;; +esac + +if test X"$want_libuv" != Xno; then + if test x$want_debug != xyes; then + as_fn_error $? "Using libuv without debug support enabled is useless" "$LINENO" 5 + fi + + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKGCONFIG=$ac_cv_path_PKGCONFIG +if test -n "$PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 +printf "%s\n" "$PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKGCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + + fi + + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libuv options with pkg-config" >&5 +printf %s "checking for libuv options with pkg-config... " >&6; } + itexists=` + if test -n "$want_libuv_path"; then + PKG_CONFIG_LIBDIR="$want_libuv_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libuv >/dev/null 2>&1 && echo 1` + + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 +printf "%s\n" "found" >&6; } + fi + fi + + + if test "$PKGCONFIG" != "no"; then + LIB_LIBUV=` + if test -n "$want_libuv_path"; then + PKG_CONFIG_LIBDIR="$want_libuv_path" + export PKG_CONFIG_LIBDIR + fi + + $PKGCONFIG --libs-only-l libuv` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -l is $LIB_LIBUV" >&5 +printf "%s\n" "$as_me: -l is $LIB_LIBUV" >&6;} + + CPP_LIBUV=` + if test -n "$want_libuv_path"; then + PKG_CONFIG_LIBDIR="$want_libuv_path" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --cflags-only-I libuv` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -I is $CPP_LIBUV" >&5 +printf "%s\n" "$as_me: -I is $CPP_LIBUV" >&6;} + + LD_LIBUV=` + if test -n "$want_libuv_path"; then + PKG_CONFIG_LIBDIR="$want_libuv_path" + export PKG_CONFIG_LIBDIR + fi + + $PKGCONFIG --libs-only-L libuv` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -L is $LD_LIBUV" >&5 +printf "%s\n" "$as_me: -L is $LD_LIBUV" >&6;} + + LDFLAGS="$LDFLAGS $LD_LIBUV" + CPPFLAGS="$CPPFLAGS $CPP_LIBUV" + LIBS="$LIB_LIBUV $LIBS" + + if test "x$cross_compiling" != "xyes"; then + DIR_LIBUV=`echo $LD_LIBUV | $SED -e 's/^-L//'` + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uv_default_loop in -luv" >&5 +printf %s "checking for uv_default_loop in -luv... " >&6; } +if test ${ac_cv_lib_uv_uv_default_loop+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-luv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#ifdef __cplusplus +extern "C" +#endif +char uv_default_loop (); +int main (void) +{ +return uv_default_loop (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_uv_uv_default_loop=yes +else $as_nop + ac_cv_lib_uv_uv_default_loop=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uv_uv_default_loop" >&5 +printf "%s\n" "$ac_cv_lib_uv_uv_default_loop" >&6; } +if test "x$ac_cv_lib_uv_uv_default_loop" = xyes +then : + + for ac_header in uv.h +do : + ac_fn_c_check_header_compile "$LINENO" "uv.h" "ac_cv_header_uv_h" "$ac_includes_default" +if test "x$ac_cv_header_uv_h" = xyes +then : + printf "%s\n" "#define HAVE_UV_H 1" >>confdefs.h + LIBUV_ENABLED=1 + +printf "%s\n" "#define USE_LIBUV 1" >>confdefs.h + + USE_LIBUV=1 + + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_LIBUV" + export CURL_LIBRARY_PATH + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added $DIR_LIBUV to CURL_LIBRARY_PATH" >&5 +printf "%s\n" "$as_me: Added $DIR_LIBUV to CURL_LIBRARY_PATH" >&6;} + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libuv" + +fi + +done + +else $as_nop + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + +fi + + + else + if test X"$want_libuv" != Xdefault; then + as_fn_error $? "--with-libuv was specified but could not find libuv pkg-config file." "$LINENO" 5 + fi + fi + +fi + + OPT_ZSH_FPATH=default # Check whether --with-zsh-functions-dir was given. @@ -33244,10 +33641,10 @@ case "$OPT_FISH_FPATH" in ;; yes) - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -33357,29 +33754,29 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fish options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fish options with pkg-config" >&5 printf %s "checking for fish options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists fish >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists fish >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then FISH_FUNCTIONS_DIR=`$PKGCONFIG --variable completionsdir fish` else FISH_FUNCTIONS_DIR="$datarootdir/fish/vendor_completions.d" @@ -34771,8 +35168,8 @@ printf "%s\n" "#define HAVE_STRUCT_TIMEVAL 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking run-time libs availability" >&5 printf %s "checking run-time libs availability... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -34803,8 +35200,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -34842,8 +35239,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi @@ -34855,7 +35252,7 @@ fi printf %s "checking size of size_t... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -34864,9 +35261,9 @@ printf %s "checking size of size_t... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(size_t) == $typesize):; - } + case 0: + case (sizeof(size_t) == $typesize):; + } ; return 0; @@ -34875,10 +35272,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -34904,7 +35301,7 @@ printf "%s\n" "#define SIZEOF_SIZE_T $r" >>confdefs.h printf %s "checking size of long... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -34913,9 +35310,9 @@ printf %s "checking size of long... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(long) == $typesize):; - } + case 0: + case (sizeof(long) == $typesize):; + } ; return 0; @@ -34924,10 +35321,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -34953,7 +35350,7 @@ printf "%s\n" "#define SIZEOF_LONG $r" >>confdefs.h printf %s "checking size of int... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -34962,9 +35359,9 @@ printf %s "checking size of int... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(int) == $typesize):; - } + case 0: + case (sizeof(int) == $typesize):; + } ; return 0; @@ -34973,10 +35370,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -35002,7 +35399,7 @@ printf "%s\n" "#define SIZEOF_INT $r" >>confdefs.h printf %s "checking size of time_t... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -35011,9 +35408,9 @@ printf %s "checking size of time_t... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(time_t) == $typesize):; - } + case 0: + case (sizeof(time_t) == $typesize):; + } ; return 0; @@ -35022,10 +35419,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -35051,7 +35448,7 @@ printf "%s\n" "#define SIZEOF_TIME_T $r" >>confdefs.h printf %s "checking size of off_t... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -35060,9 +35457,9 @@ printf %s "checking size of off_t... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(off_t) == $typesize):; - } + case 0: + case (sizeof(off_t) == $typesize):; + } ; return 0; @@ -35071,10 +35468,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -35103,7 +35500,7 @@ CPPFLAGS="-I$srcdir/include $CPPFLAGS" printf %s "checking size of curl_off_t... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -35114,9 +35511,9 @@ printf %s "checking size of curl_off_t... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(curl_off_t) == $typesize):; - } + case 0: + case (sizeof(curl_off_t) == $typesize):; + } ; return 0; @@ -35125,10 +35522,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -35154,7 +35551,7 @@ printf "%s\n" "#define SIZEOF_CURL_OFF_T $r" >>confdefs.h printf %s "checking size of curl_socket_t... " >&6; } r=0 for typesize in 8 4 2 16 1; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -35165,9 +35562,9 @@ printf %s "checking size of curl_socket_t... " >&6; } int main (void) { switch(0) { - case 0: - case (sizeof(curl_socket_t) == $typesize):; - } + case 0: + case (sizeof(curl_socket_t) == $typesize):; + } ; return 0; @@ -35176,10 +35573,10 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - r=$typesize + r=$typesize else $as_nop - r=0 + r=0 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $r -gt 0; then @@ -35207,7 +35604,7 @@ then : printf "%s\n" "#define HAVE_LONGLONG 1" >>confdefs.h - longlong="yes" + longlong="yes" fi @@ -35262,8 +35659,8 @@ printf "%s\n" "#define CURL_SA_FAMILY_T sa_family_t" >>confdefs.h else $as_nop - # The windows name? - ac_fn_c_check_type "$LINENO" "ADDRESS_FAMILY" "ac_cv_type_ADDRESS_FAMILY" " + # The Windows name? + ac_fn_c_check_type "$LINENO" "ADDRESS_FAMILY" "ac_cv_type_ADDRESS_FAMILY" " #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -35313,8 +35710,8 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if time_t is unsigned" >&5 printf %s "checking if time_t is unsigned... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -35349,8 +35746,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -35392,8 +35789,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac @@ -35682,7 +36079,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "#define HAVE_RECV 1" >>confdefs.h - curl_cv_func_recv="yes" + curl_cv_func_recv="yes" else as_fn_error $? "Unable to link function recv" "$LINENO" 5 fi @@ -37578,8 +37975,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if getaddrinfo seems to work" >&5 printf %s "checking if getaddrinfo seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -37641,8 +38038,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -37711,8 +38108,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -39152,8 +39549,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if getifaddrs seems to work" >&5 printf %s "checking if getifaddrs seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -39201,8 +39598,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -39257,8 +39654,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -39447,8 +39844,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if gmtime_r seems to work" >&5 printf %s "checking if gmtime_r seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -39496,8 +39893,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -39552,8 +39949,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -39765,8 +40162,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if inet_ntop seems to work" >&5 printf %s "checking if inet_ntop seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -39856,8 +40253,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -39954,8 +40351,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -40117,8 +40514,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if inet_pton seems to work" >&5 printf %s "checking if inet_pton seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -40201,8 +40598,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -40292,8 +40689,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -41451,13 +41848,13 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi # - if test "x$cross_compiling" != "xyes" && - test "$tst_compi_poll" = "yes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if poll seems to work" >&5 + if test "$tst_compi_poll" = "yes"; then + if test "x$cross_compiling" != "xyes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if poll seems to work" >&5 printf %s "checking if poll seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -41469,32 +41866,16 @@ else $as_nop /* end confdefs.h. */ - $curl_includes_stdlib - $curl_includes_poll - $curl_includes_time + $curl_includes_stdlib + $curl_includes_poll int main (void) { - /* detect the original poll() breakage */ - if(0 != poll(0, 0, 10)) - exit(1); /* fail */ - else { - /* detect the 10.12 poll() breakage */ - struct timeval before, after; - int rc; - size_t us; - - gettimeofday(&before, NULL); - rc = poll(NULL, 0, 500); - gettimeofday(&after, NULL); - - us = (after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec); - - if(us < 400000) - exit(1); - } + /* detect the original poll() breakage */ + if(0 != poll(0, 0, 10)) { + return 1; /* fail */ + } ; return 0; @@ -41505,20 +41886,20 @@ if ac_fn_c_try_run "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - tst_works_poll="yes" + tst_works_poll="yes" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - tst_works_poll="no" + tst_works_poll="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -41535,32 +41916,16 @@ else $as_nop /* end confdefs.h. */ - $curl_includes_stdlib - $curl_includes_poll - $curl_includes_time + $curl_includes_stdlib + $curl_includes_poll int main (void) { - /* detect the original poll() breakage */ - if(0 != poll(0, 0, 10)) - exit(1); /* fail */ - else { - /* detect the 10.12 poll() breakage */ - struct timeval before, after; - int rc; - size_t us; - - gettimeofday(&before, NULL); - rc = poll(NULL, 0, 500); - gettimeofday(&after, NULL); - - us = (after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec); - - if(us < 400000) - exit(1); - } + /* detect the original poll() breakage */ + if(0 != poll(0, 0, 10)) { + return 1; /* fail */ + } ; return 0; @@ -41571,12 +41936,12 @@ if ac_fn_c_try_run "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - tst_works_poll="yes" + tst_works_poll="yes" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - tst_works_poll="no" + tst_works_poll="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -41585,9 +41950,48 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac + + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if native poll seems to be supported" >&5 +printf %s "checking if native poll seems to be supported... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + $curl_includes_stdlib + +int main (void) +{ + + #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L + return 0; + #else + #error force compilation error + #endif + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + tst_works_poll="yes" + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + tst_works_poll="no" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi fi # if test "$tst_compi_poll" = "yes" && @@ -43228,8 +43632,8 @@ printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if strerror_r seems to work" >&5 printf %s "checking if strerror_r seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -43280,8 +43684,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -43339,8 +43743,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -43397,8 +43801,8 @@ printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if strerror_r seems to work" >&5 printf %s "checking if strerror_r seems to work... " >&6; } - case $host_os in - darwin*) + case $host_os in + darwin*) if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 @@ -43449,8 +43853,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -43508,8 +43912,8 @@ fi LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac fi # @@ -44034,9 +44438,9 @@ printf "%s\n" "no" >&6; } case $host in *msdosdjgpp) - ac_cv_func_pipe=no - skipcheck_pipe=yes - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: skip check for pipe on msdosdjgpp" >&5 + ac_cv_func_pipe=no + skipcheck_pipe=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: skip check for pipe on msdosdjgpp" >&5 printf "%s\n" "$as_me: skip check for pipe on msdosdjgpp" >&6;} ;; esac @@ -44162,12 +44566,6 @@ if test "x$ac_cv_func_fnmatch" = xyes then : printf "%s\n" "#define HAVE_FNMATCH 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" -if test "x$ac_cv_func_fseeko" = xyes -then : - printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "geteuid" "ac_cv_func_geteuid" if test "x$ac_cv_func_geteuid" = xyes @@ -44279,13 +44677,23 @@ then : fi -ac_fn_check_decl "$LINENO" "fseeko" "ac_cv_have_decl_fseeko" "#include +if test "$curl_cv_native_windows" != 'yes'; then + ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes +then : + printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h + +fi + + + ac_fn_check_decl "$LINENO" "fseeko" "ac_cv_have_decl_fseeko" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_fseeko" = xyes then : printf "%s\n" "#define HAVE_DECL_FSEEKO 1" >>confdefs.h +fi fi @@ -44313,7 +44721,7 @@ printf "%s\n" "$as_me: WARNING: cannot determine non-blocking socket method." >& fi -if test "x$BUILD_DOCS" != "x0" -o "x$USE_MANUAL" != "x0"; then +if test "x$BUILD_DOCS" != "x0" -o "x$USE_MANUAL" != "x0" -o "x$CURL_CA_EMBED" != "x"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -44363,7 +44771,7 @@ fi if test -z "$PERL"; then - as_fn_error $? "perl was not found, needed for docs and manual" "$LINENO" 5 + as_fn_error $? "perl was not found, needed for docs, manual and CA embed" "$LINENO" 5 fi fi @@ -44378,9 +44786,6 @@ fi if test "$USE_MANUAL" = "1"; then - -printf "%s\n" "#define USE_MANUAL 1" >>confdefs.h - curl_manual_msg="enabled" fi @@ -44403,10 +44808,10 @@ fi if test -n "$want_ares_path"; then ARES_PCDIR="$want_ares_path/lib/pkgconfig" - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -44516,48 +44921,48 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libcares options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libcares options with pkg-config" >&5 printf %s "checking for libcares options with pkg-config... " >&6; } - itexists=` - if test -n "$ARES_PCDIR"; then - PKG_CONFIG_LIBDIR="$ARES_PCDIR" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libcares >/dev/null 2>&1 && echo 1` + itexists=` + if test -n "$ARES_PCDIR"; then + PKG_CONFIG_LIBDIR="$ARES_PCDIR" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libcares >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no" ; then ares_LIBS=` - if test -n "$ARES_PCDIR"; then - PKG_CONFIG_LIBDIR="$ARES_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$ARES_PCDIR"; then + PKG_CONFIG_LIBDIR="$ARES_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-l libcares` ares_LDFLAGS=` - if test -n "$ARES_PCDIR"; then - PKG_CONFIG_LIBDIR="$ARES_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$ARES_PCDIR"; then + PKG_CONFIG_LIBDIR="$ARES_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --libs-only-L libcares` ares_CPPFLAGS=` - if test -n "$ARES_PCDIR"; then - PKG_CONFIG_LIBDIR="$ARES_PCDIR" - export PKG_CONFIG_LIBDIR - fi + if test -n "$ARES_PCDIR"; then + PKG_CONFIG_LIBDIR="$ARES_PCDIR" + export PKG_CONFIG_LIBDIR + fi $PKGCONFIG --cflags-only-I libcares` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: pkg-config: ares LIBS: \"$ares_LIBS\"" >&5 @@ -44573,10 +44978,10 @@ printf "%s\n" "$as_me: pkg-config: ares CPPFLAGS: \"$ares_CPPFLAGS\"" >&6;} fi else - if test -n "$PKG_CONFIG"; then - PKGCONFIG="$PKG_CONFIG" - else - if test -n "$ac_tool_prefix"; then + if test -n "$PKG_CONFIG"; then + PKGCONFIG="$PKG_CONFIG" + else + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -44686,27 +45091,27 @@ else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi - fi + fi - if test "x$PKGCONFIG" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libcares options with pkg-config" >&5 + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libcares options with pkg-config" >&5 printf %s "checking for libcares options with pkg-config... " >&6; } - itexists=` - if test -n ""; then - PKG_CONFIG_LIBDIR="" - export PKG_CONFIG_LIBDIR - fi - $PKGCONFIG --exists libcares >/dev/null 2>&1 && echo 1` + itexists=` + if test -n ""; then + PKG_CONFIG_LIBDIR="" + export PKG_CONFIG_LIBDIR + fi + $PKGCONFIG --exists libcares >/dev/null 2>&1 && echo 1` - if test -z "$itexists"; then - PKGCONFIG="no" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test -z "$itexists"; then + PKGCONFIG="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } - fi fi + fi if test "$PKGCONFIG" != "no" ; then ares_LIBS=`$PKGCONFIG --libs-only-l libcares` @@ -44793,21 +45198,6 @@ printf "%s\n" "#define CARES_NO_DEPRECATED 1" >>confdefs.h fi -if test "x$curl_cv_native_windows" != "xyes" && - test "x$enable_shared" = "xyes"; then - build_libhostname=yes -else - build_libhostname=no -fi - if test x$build_libhostname = xyes; then - BUILD_LIBHOSTNAME_TRUE= - BUILD_LIBHOSTNAME_FALSE='#' -else - BUILD_LIBHOSTNAME_TRUE='#' - BUILD_LIBHOSTNAME_FALSE= -fi - - if test "x$want_ares" != xyes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable the threaded resolver" >&5 @@ -44841,17 +45231,17 @@ case $host_os in /* end confdefs.h. */ -#include -#include + #include + #include int main (void) { -#if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) - return 0; -#else -#error Not macOS -#endif + #if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) + return 0; + #else + #error Not macOS + #endif ; return 0; @@ -44892,20 +45282,38 @@ printf %s "checking whether to use POSIX threads for threaded resolver... " >&6; if test ${enable_pthreads+y} then : enableval=$enable_pthreads; case "$enableval" in - no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - want_pthreads=no - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + want_pthreads=no + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - want_pthreads=yes - ;; + want_pthreads=yes + ;; esac else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: auto" >&5 + default_pthreads=1 + if test "$curl_cv_native_windows" = "yes"; then + default_pthreads=0 + else + case $host_os in + msdos*) + default_pthreads=0 + ;; + esac + fi + if test "$default_pthreads" = '0'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + want_pthreads=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: auto" >&5 printf "%s\n" "auto" >&6; } - want_pthreads=auto + want_pthreads=auto + fi fi @@ -44948,33 +45356,32 @@ fi LIBS="$save_LIBS" case $host in - *-hp-hpux*) - USE_THREADS_POSIX="" - ;; - *) - ;; + *-hp-hpux*) + USE_THREADS_POSIX="" + ;; + *) + ;; esac - if test "$USE_THREADS_POSIX" != "1" - then + if test "$USE_THREADS_POSIX" != "1"; then # assign PTHREAD for pkg-config use PTHREAD=" -pthread" case $host in - *-ibm-aix*) - COMPILER_VERSION=`"$CC" -qversion 2>/dev/null` - if test x"$COMPILER_VERSION" = "x"; then - CFLAGS="$CFLAGS -pthread" - else - CFLAGS="$CFLAGS -qthreaded" - fi - ;; - powerpc-*amigaos*) - PTHREAD=" -lpthread" - ;; - *) - CFLAGS="$CFLAGS -pthread" - ;; + *-ibm-aix*) + COMPILER_VERSION=`"$CC" -qversion 2>/dev/null` + if test x"$COMPILER_VERSION" = "x"; then + CFLAGS="$CFLAGS -pthread" + else + CFLAGS="$CFLAGS -qthreaded" + fi + ;; + powerpc-*amigaos*) + PTHREAD=" -lpthread" + ;; + *) + CFLAGS="$CFLAGS -pthread" + ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 printf %s "checking for pthread_create in -lpthread... " >&6; } @@ -45020,8 +45427,7 @@ fi fi - if test "x$USE_THREADS_POSIX" = "x1" - then + if test "x$USE_THREADS_POSIX" = "x1"; then printf "%s\n" "#define USE_THREADS_POSIX 1" >>confdefs.h @@ -45116,16 +45522,17 @@ if test ${enable_verbose+y} then : enableval=$enable_verbose; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_VERBOSE_STRINGS 1" >>confdefs.h - curl_verbose_msg="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + curl_verbose_msg="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45141,42 +45548,42 @@ if test ${enable_sspi+y} then : enableval=$enable_sspi; case "$enableval" in yes) - if test "$curl_cv_native_windows" = "yes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test "$curl_cv_native_windows" = "yes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define USE_WINDOWS_SSPI 1" >>confdefs.h - USE_WINDOWS_SSPI=1 + USE_WINDOWS_SSPI=1 - curl_sspi_msg="enabled" - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + curl_sspi_msg="enabled" + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-sspi Ignored. Only supported on native Windows builds." >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-sspi Ignored. Only supported on native Windows builds." >&5 printf "%s\n" "$as_me: WARNING: --enable-sspi Ignored. Only supported on native Windows builds." >&2;} - fi - ;; + fi + ;; *) - if test "x$SCHANNEL_ENABLED" = "x1"; then - # --with-schannel implies --enable-sspi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test "x$SCHANNEL_ENABLED" = "x1"; then + # --with-schannel implies --enable-sspi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi - ;; + fi + ;; esac else $as_nop if test "x$SCHANNEL_ENABLED" = "x1"; then - # --with-schannel implies --enable-sspi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + # --with-schannel implies --enable-sspi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi + fi fi @@ -45188,16 +45595,17 @@ if test ${enable_basic_auth+y} then : enableval=$enable_basic_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_BASIC_AUTH 1" >>confdefs.h - CURL_DISABLE_BASIC_AUTH=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_BASIC_AUTH=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45213,16 +45621,17 @@ if test ${enable_bearer_auth+y} then : enableval=$enable_bearer_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_BEARER_AUTH 1" >>confdefs.h - CURL_DISABLE_BEARER_AUTH=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_BEARER_AUTH=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45238,16 +45647,17 @@ if test ${enable_digest_auth+y} then : enableval=$enable_digest_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_DIGEST_AUTH 1" >>confdefs.h - CURL_DISABLE_DIGEST_AUTH=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_DIGEST_AUTH=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45263,16 +45673,17 @@ if test ${enable_kerberos_auth+y} then : enableval=$enable_kerberos_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_KERBEROS_AUTH 1" >>confdefs.h - CURL_DISABLE_KERBEROS_AUTH=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_KERBEROS_AUTH=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45288,16 +45699,17 @@ if test ${enable_negotiate_auth+y} then : enableval=$enable_negotiate_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_NEGOTIATE_AUTH 1" >>confdefs.h - CURL_DISABLE_NEGOTIATE_AUTH=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_NEGOTIATE_AUTH=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45306,7 +45718,6 @@ printf "%s\n" "yes" >&6; } fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable aws sig methods" >&5 printf %s "checking whether to enable aws sig methods... " >&6; } # Check whether --enable-aws was given. @@ -45314,16 +45725,17 @@ if test ${enable_aws+y} then : enableval=$enable_aws; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_AWS 1" >>confdefs.h - CURL_DISABLE_AWS=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_AWS=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45339,16 +45751,17 @@ if test ${enable_ntlm+y} then : enableval=$enable_ntlm; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_NTLM 1" >>confdefs.h - CURL_DISABLE_NTLM=1 - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + CURL_DISABLE_NTLM=1 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45364,29 +45777,30 @@ if test ${enable_tls_srp+y} then : enableval=$enable_tls_srp; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - want_tls_srp=no - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + want_tls_srp=no + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - want_tls_srp=yes - ;; + want_tls_srp=yes + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - want_tls_srp=yes + want_tls_srp=yes fi -if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$HAVE_OPENSSL_SRP" = "x1") ; then +if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$HAVE_OPENSSL_SRP" = "x1"); then printf "%s\n" "#define USE_TLS_SRP 1" >>confdefs.h - USE_TLS_SRP=1 - curl_tls_srp_msg="enabled" + USE_TLS_SRP=1 + curl_tls_srp_msg="enabled" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable Unix domain sockets" >&5 @@ -45395,20 +45809,22 @@ printf %s "checking whether to enable Unix domain sockets... " >&6; } if test ${enable_unix_sockets+y} then : enableval=$enable_unix_sockets; case "$enableval" in - no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - want_unix_sockets=no - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + want_unix_sockets=no + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - want_unix_sockets=yes - ;; + want_unix_sockets=yes + ;; esac else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: auto" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: auto" >&5 printf "%s\n" "auto" >&6; } - want_unix_sockets=auto + want_unix_sockets=auto fi @@ -45453,15 +45869,16 @@ if test ${enable_cookies+y} then : enableval=$enable_cookies; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_COOKIES 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45477,15 +45894,16 @@ if test ${enable_socketpair+y} then : enableval=$enable_socketpair; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_SOCKETPAIR 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45501,15 +45919,16 @@ if test ${enable_http_auth+y} then : enableval=$enable_http_auth; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_HTTP_AUTH 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45525,15 +45944,16 @@ if test ${enable_doh+y} then : enableval=$enable_doh; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_DOH 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45549,15 +45969,16 @@ if test ${enable_mime+y} then : enableval=$enable_mime; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_MIME 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45573,15 +45994,16 @@ if test ${enable_bindlocal+y} then : enableval=$enable_bindlocal; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_BINDLOCAL 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45596,17 +46018,19 @@ printf %s "checking whether to support the form API... " >&6; } if test ${enable_form_api+y} then : enableval=$enable_form_api; case "$enableval" in - no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_FORM_API 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - test "$enable_mime" = no && - as_fn_error $? "MIME support needs to be enabled in order to enable form API support" "$LINENO" 5 - ;; + test "$enable_mime" = no && + as_fn_error $? "MIME support needs to be enabled in order to enable form API support" "$LINENO" 5 + ;; esac else $as_nop @@ -45632,15 +46056,16 @@ if test ${enable_dateparse+y} then : enableval=$enable_dateparse; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_PARSEDATE 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45656,15 +46081,16 @@ if test ${enable_netrc+y} then : enableval=$enable_netrc; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_NETRC 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45680,15 +46106,41 @@ if test ${enable_progress_meter+y} then : enableval=$enable_progress_meter; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_PROGRESS_METER 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + esac +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support the SHA-512/256 hash algorithm" >&5 +printf %s "checking whether to support the SHA-512/256 hash algorithm... " >&6; } +# Check whether --enable-sha512-256 was given. +if test ${enable_sha512_256+y} +then : + enableval=$enable_sha512_256; case "$enableval" in + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +printf "%s\n" "#define CURL_DISABLE_SHA512_256 1" >>confdefs.h + + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45704,15 +46156,16 @@ if test ${enable_dnsshuffle+y} then : enableval=$enable_dnsshuffle; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_SHUFFLE_DNS 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45728,15 +46181,16 @@ if test ${enable_get_easy_options+y} then : enableval=$enable_get_easy_options; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_GETOPTIONS 1" >>confdefs.h - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45752,17 +46206,18 @@ if test ${enable_alt_svc+y} then : enableval=$enable_alt_svc; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "#define CURL_DISABLE_ALTSVC 1" >>confdefs.h - curl_altsvc_msg="no"; - enable_altsvc="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + curl_altsvc_msg="no"; + enable_altsvc="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45777,17 +46232,18 @@ printf %s "checking whether to support headers-api... " >&6; } if test ${enable_headers_api+y} then : enableval=$enable_headers_api; case "$enableval" in - no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + no) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - curl_headers_msg="no (--enable-headers-api)" + curl_headers_msg="no (--enable-headers-api)" printf "%s\n" "#define CURL_DISABLE_HEADERS_API 1" >>confdefs.h - ;; + ;; *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -45804,13 +46260,14 @@ if test ${enable_hsts+y} then : enableval=$enable_hsts; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - hsts="no" - ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + hsts="no" + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - ;; + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hsts" >&5 @@ -45923,29 +46380,29 @@ if test ${enable_websockets+y} then : enableval=$enable_websockets; case "$enableval" in no) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; + ;; *) - if test ${ac_cv_sizeof_curl_off_t} -gt 4; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test ${ac_cv_sizeof_curl_off_t} -gt 4; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - curl_ws_msg="enabled" + curl_ws_msg="enabled" printf "%s\n" "#define USE_WEBSOCKETS 1" >>confdefs.h - SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS" - if test "x$SSL_ENABLED" = "x1"; then - SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS" - fi - experimental="$experimental Websockets" - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS" + fi + experimental="$experimental WebSockets" + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Websockets disabled due to lack of >32 bit curl_off_t" >&5 -printf "%s\n" "$as_me: WARNING: Websockets disabled due to lack of >32 bit curl_off_t" >&2;} - fi - ;; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: WebSockets disabled due to lack of >32 bit curl_off_t" >&5 +printf "%s\n" "$as_me: WARNING: WebSockets disabled due to lack of >32 bit curl_off_t" >&2;} + fi + ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -45984,7 +46441,7 @@ fi -LIBCURL_LIBS="$LIBS$PTHREAD" +LIBCURL_PC_LIBS_PRIVATE="$LIBS$PTHREAD" @@ -46015,10 +46472,10 @@ LIBCURL_PC_REQUIRES_PRIVATE=`echo $LIBCURL_PC_REQUIRES_PRIVATE | tr ' ' ','` if test "x$enable_shared" = "xno"; then LIBCURL_PC_REQUIRES=$LIBCURL_PC_REQUIRES_PRIVATE - LIBCURL_NO_SHARED=$LIBCURL_LIBS + LIBCURL_PC_LIBS=$LIBCURL_PC_LIBS_PRIVATE else LIBCURL_PC_REQUIRES= - LIBCURL_NO_SHARED= + LIBCURL_PC_LIBS= fi @@ -46066,7 +46523,7 @@ if test "x$curl_psl_msg" = "xenabled"; then fi if test "x$curl_gsasl_msg" = "xenabled"; then - SUPPORT_FEATURES="$SUPPORT_FEATURES GSASL" + SUPPORT_FEATURES="$SUPPORT_FEATURES gsasl" fi if test "x$enable_altsvc" = "xyes"; then @@ -46195,18 +46652,24 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" + SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +if test "x$want_winuni" = "xyes"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES Unicode" +fi if test "x$want_debug" = "xyes"; then SUPPORT_FEATURES="$SUPPORT_FEATURES Debug" fi if test "x$want_curldebug" = "xyes"; then SUPPORT_FEATURES="$SUPPORT_FEATURES TrackMemory" fi +if test "x$CURL_CA_EMBED" != "x"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES CAcert" +fi if sort -f /dev/null 2>&1; then SUPPORT_FEATURES=`echo $SUPPORT_FEATURES | tr ' ' '\012' | sort -f | tr '\012' ' '` @@ -46311,7 +46774,7 @@ squeeze DEFS squeeze LDFLAGS squeeze LIBS -squeeze LIBCURL_LIBS +squeeze LIBCURL_PC_LIBS_PRIVATE squeeze CURL_NETWORK_LIBS squeeze CURL_NETWORK_AND_TIME_LIBS @@ -46481,7 +46944,7 @@ printf "%s\n" "$as_me: $xc_bad_var_msg libraries. Use LIBS for: $xc_word" >&6;} test $xc_bad_var_cflags = yes || test $xc_bad_var_ldflags = yes || test $xc_bad_var_cppflags = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Continuing even with errors mentioned immediately above this line." >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Continuing even with errors mentioned immediately above this line." >&5 printf "%s\n" "$as_me: WARNING: Continuing even with errors mentioned immediately above this line." >&2;} fi @@ -46653,10 +47116,6 @@ if test -z "${USE_CPPFLAG_CURL_STATICLIB_TRUE}" && test -z "${USE_CPPFLAG_CURL_S as_fn_error $? "conditional \"USE_CPPFLAG_CURL_STATICLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${USE_EXPLICIT_LIB_DEPS_TRUE}" && test -z "${USE_EXPLICIT_LIB_DEPS_FALSE}"; then - as_fn_error $? "conditional \"USE_EXPLICIT_LIB_DEPS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${DOING_NATIVE_WINDOWS_TRUE}" && test -z "${DOING_NATIVE_WINDOWS_FALSE}"; then as_fn_error $? "conditional \"DOING_NATIVE_WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -46681,6 +47140,10 @@ if test -z "${BUILD_STUB_GSS_TRUE}" && test -z "${BUILD_STUB_GSS_FALSE}"; then as_fn_error $? "conditional \"BUILD_STUB_GSS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${CURL_CA_EMBED_SET_TRUE}" && test -z "${CURL_CA_EMBED_SET_FALSE}"; then + as_fn_error $? "conditional \"CURL_CA_EMBED_SET\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_LIBPSL_TRUE}" && test -z "${USE_LIBPSL_FALSE}"; then as_fn_error $? "conditional \"USE_LIBPSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -46693,6 +47156,10 @@ if test -z "${CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_TRUE}" && test -z "${CURL_LT_S as_fn_error $? "conditional \"CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_UNICODE_TRUE}" && test -z "${USE_UNICODE_FALSE}"; then + as_fn_error $? "conditional \"USE_UNICODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_ZSH_COMPLETION_TRUE}" && test -z "${USE_ZSH_COMPLETION_FALSE}"; then as_fn_error $? "conditional \"USE_ZSH_COMPLETION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -46713,10 +47180,6 @@ if test -z "${USE_MANUAL_TRUE}" && test -z "${USE_MANUAL_FALSE}"; then as_fn_error $? "conditional \"USE_MANUAL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${BUILD_LIBHOSTNAME_TRUE}" && test -z "${BUILD_LIBHOSTNAME_FALSE}"; then - as_fn_error $? "conditional \"BUILD_LIBHOSTNAME\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${DOING_CURL_SYMBOL_HIDING_TRUE}" && test -z "${DOING_CURL_SYMBOL_HIDING_FALSE}"; then as_fn_error $? "conditional \"DOING_CURL_SYMBOL_HIDING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -49148,6 +49611,52 @@ use vars qw( _EOF + curl_pflags="" + case $host in + *-apple-*) curl_pflags="${curl_pflags} APPLE";; + esac + if test "$curl_cv_native_windows" = 'yes'; then + curl_pflags="${curl_pflags} WIN32" + else + case $host in + *-*-*bsd*|*-*-aix*|*-*-hpux*|*-*-interix*|*-*-irix*|*-*-linux*|*-*-solaris*|*-*-sunos*|*-apple-*|*-*-cygwin*|*-*-msys*) + curl_pflags="${curl_pflags} UNIX";; + esac + fi + case $host_os in + cygwin*|msys*) curl_pflags="${curl_pflags} CYGWIN";; + esac + case $host_os in + msys*) curl_pflags="${curl_pflags} MSYS";; + esac + if test "x$compiler_id" = 'xGNU_C'; then + curl_pflags="${curl_pflags} GCC" + fi + case $host_os in + mingw*) curl_pflags="${curl_pflags} MINGW";; + esac + if test "x$cross_compiling" = 'xyes'; then + curl_pflags="${curl_pflags} CROSS" + fi + squeeze curl_pflags + cat >./tests/buildinfo.txt <<_EOF +# This is a generated file. Do not edit. +configure.tool: configure +configure.args: $ac_configure_args +host: $build +host.os: $build_os +host.cpu: $build_cpu +host.vendor: $build_vendor +target: $host +target.os: $host_os +target.cpu: $host_cpu +target.vendor: $host_vendor +target.flags: $curl_pflags +compiler: $compiler_id +compiler.version: $compiler_num +_EOF + + SUPPORT_PROTOCOLS_LOWER=`echo "$SUPPORT_PROTOCOLS" | tr A-Z a-z` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configured to build curl/libcurl: @@ -49251,18 +49760,19 @@ printf "%s\n" "$as_me: Configured to build curl/libcurl: Features: ${SUPPORT_FEATURES} " >&6;} -non13=`echo "$TLSCHOICE" | $EGREP -io 'bearssl|secure-transport'`; +# grep -o would simplify this, but is nonportable +non13=`echo "$TLSCHOICE" | $AWK '{split("bearssl secure-transport", a); for (i in a) if(match(tolower($0), a[i])) print a[i];}'` if test -n "$non13"; then - for a in $non13; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $a is enabled for TLS but it does not support TLS 1.3" >&5 + for a in $non13; do + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $a is enabled for TLS but it does not support TLS 1.3" >&5 printf "%s\n" "$as_me: WARNING: $a is enabled for TLS but it does not support TLS 1.3" >&2;} - done + done fi if test -n "$experimental"; then - for a in $experimental; do - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $a is enabled but marked EXPERIMENTAL. Use with caution!" >&5 + for a in $experimental; do + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $a is enabled but marked EXPERIMENTAL. Use with caution!" >&5 printf "%s\n" "$as_me: WARNING: $a is enabled but marked EXPERIMENTAL. Use with caution!" >&2;} - done + done fi diff --git a/configure.ac b/configure.ac index 1e18b8156..269d7bd44 100644 --- a/configure.ac +++ b/configure.ac @@ -293,7 +293,7 @@ AS_HELP_STRING([--with-bearssl=PATH],[where to look for BearSSL, PATH points to OPT_RUSTLS=no AC_ARG_WITH(rustls,dnl -AS_HELP_STRING([--with-rustls=PATH],[where to look for rustls, PATH points to the installation root]),[ +AS_HELP_STRING([--with-rustls=PATH],[where to look for Rustls, PATH points to the installation root]),[ OPT_RUSTLS=$withval if test X"$withval" != Xno; then TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }rustls" @@ -305,8 +305,8 @@ TEST_NGHTTPX=nghttpx AC_ARG_WITH(test-nghttpx,dnl AS_HELP_STRING([--with-test-nghttpx=PATH],[where to find nghttpx for testing]), TEST_NGHTTPX=$withval - if test X"$OPT_TEST_NGHTTPX" = "Xno" ; then - TEST_NGHTTPX="" + if test X"$OPT_TEST_NGHTTPX" = "Xno"; then + TEST_NGHTTPX="" fi ) AC_SUBST(TEST_NGHTTPX) @@ -315,8 +315,8 @@ CADDY=/usr/bin/caddy AC_ARG_WITH(test-caddy,dnl AS_HELP_STRING([--with-test-caddy=PATH],[where to find caddy for testing]), CADDY=$withval - if test X"$OPT_CADDY" = "Xno" ; then - CADDY="" + if test X"$OPT_CADDY" = "Xno"; then + CADDY="" fi ) AC_SUBST(CADDY) @@ -325,8 +325,8 @@ VSFTPD=/usr/sbin/vsftpd AC_ARG_WITH(test-vsftpd,dnl AS_HELP_STRING([--with-test-vsftpd=PATH],[where to find vsftpd for testing]), VSFTPD=$withval - if test X"$OPT_VSFTPD" = "Xno" ; then - VSFTPD="" + if test X"$OPT_VSFTPD" = "Xno"; then + VSFTPD="" fi ) AC_SUBST(VSFTPD) @@ -491,22 +491,15 @@ AM_CONDITIONAL([USE_CPPFLAG_CURL_STATICLIB], # targeting a static library and not building its shared counterpart. # -CPPFLAG_CURL_STATICLIB= +LIBCURL_PC_CFLAGS_PRIVATE='-DCURL_STATICLIB' +AC_SUBST(LIBCURL_PC_CFLAGS_PRIVATE) + +LIBCURL_PC_CFLAGS= if test "x$xc_lt_build_static_only" = 'xyes'; then - CPPFLAG_CURL_STATICLIB='-DCURL_STATICLIB' + LIBCURL_PC_CFLAGS="${LIBCURL_PC_CFLAGS_PRIVATE}" fi -AC_SUBST([CPPFLAG_CURL_STATICLIB]) - +AC_SUBST([LIBCURL_PC_CFLAGS]) -# Determine whether all dependent libraries must be specified when linking -if test "X$enable_shared" = "Xyes" -a "X$link_all_deplibs" = "Xno" -then - REQUIRE_LIB_DEPS=no -else - REQUIRE_LIB_DEPS=yes -fi -AC_SUBST(REQUIRE_LIB_DEPS) -AM_CONDITIONAL(USE_EXPLICIT_LIB_DEPS, test x$REQUIRE_LIB_DEPS = xyes) dnl ********************************************************************** dnl platform/compiler/architecture specific checks/flags @@ -597,6 +590,7 @@ CURL_CHECK_WIN32_LARGEFILE CURL_CHECK_WIN32_CRYPTO CURL_DARWIN_CFLAGS + case $host_os in darwin*) CURL_SUPPORTS_BUILTIN_AVAILABLE @@ -620,26 +614,27 @@ AS_HELP_STRING([--enable-http],[Enable HTTP support]) AS_HELP_STRING([--disable-http],[Disable HTTP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP]) - disable_http="yes" - AC_MSG_WARN([disable HTTP disables FTP over proxy and RTSP]) - AC_SUBST(CURL_DISABLE_HTTP, [1]) - AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) - AC_SUBST(CURL_DISABLE_RTSP, [1]) - dnl toggle off alt-svc too when HTTP is disabled - AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc]) - AC_DEFINE(CURL_DISABLE_HSTS, 1, [disable HSTS]) - curl_h1_msg="no (--enable-http, --with-hyper)" - curl_altsvc_msg="no"; - curl_hsts_msg="no (--enable-hsts)"; - enable_altsvc="no" - hsts="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP]) + disable_http="yes" + AC_MSG_WARN([disable HTTP disables FTP over proxy and RTSP]) + AC_SUBST(CURL_DISABLE_HTTP, [1]) + AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) + AC_SUBST(CURL_DISABLE_RTSP, [1]) + dnl toggle off alt-svc too when HTTP is disabled + AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc]) + AC_DEFINE(CURL_DISABLE_HSTS, 1, [disable HSTS]) + curl_h1_msg="no (--enable-http, --with-hyper)" + curl_altsvc_msg="no"; + curl_hsts_msg="no (--enable-hsts)"; + enable_altsvc="no" + hsts="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support ftp]) AC_ARG_ENABLE(ftp, @@ -647,14 +642,15 @@ AS_HELP_STRING([--enable-ftp],[Enable FTP support]) AS_HELP_STRING([--disable-ftp],[Disable FTP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP]) - AC_SUBST(CURL_DISABLE_FTP, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP]) + AC_SUBST(CURL_DISABLE_FTP, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support file]) AC_ARG_ENABLE(file, @@ -662,14 +658,15 @@ AS_HELP_STRING([--enable-file],[Enable FILE support]) AS_HELP_STRING([--disable-file],[Disable FILE support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE]) - AC_SUBST(CURL_DISABLE_FILE, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE]) + AC_SUBST(CURL_DISABLE_FILE, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support ldap]) AC_ARG_ENABLE(ldap, @@ -677,19 +674,19 @@ AS_HELP_STRING([--enable-ldap],[Enable LDAP support]) AS_HELP_STRING([--disable-ldap],[Disable LDAP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) - AC_SUBST(CURL_DISABLE_LDAP, [1]) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) + AC_SUBST(CURL_DISABLE_LDAP, [1]) + ;; yes) - ldap_askedfor="yes" - AC_MSG_RESULT(yes) - ;; + ldap_askedfor="yes" + AC_MSG_RESULT(yes) + ;; *) - AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(yes) + ;; esac ],[ - AC_MSG_RESULT(yes) ] + AC_MSG_RESULT(yes) ] ) AC_MSG_CHECKING([whether to support ldaps]) AC_ARG_ENABLE(ldaps, @@ -697,30 +694,31 @@ AS_HELP_STRING([--enable-ldaps],[Enable LDAPS support]) AS_HELP_STRING([--disable-ldaps],[Disable LDAPS support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) - AC_SUBST(CURL_DISABLE_LDAPS, [1]) - ;; - *) if test "x$CURL_DISABLE_LDAP" = "x1" ; then - AC_MSG_RESULT(LDAP needs to be enabled to support LDAPS) - AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) - AC_SUBST(CURL_DISABLE_LDAPS, [1]) - else - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) - AC_SUBST(HAVE_LDAP_SSL, [1]) - fi - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + ;; + *) + if test "x$CURL_DISABLE_LDAP" = "x1"; then + AC_MSG_RESULT(LDAP needs to be enabled to support LDAPS) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + else + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) + AC_SUBST(HAVE_LDAP_SSL, [1]) + fi + ;; esac ],[ - if test "x$CURL_DISABLE_LDAP" = "x1" ; then - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) - AC_SUBST(CURL_DISABLE_LDAPS, [1]) - else - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) - AC_SUBST(HAVE_LDAP_SSL, [1]) - fi ] + if test "x$CURL_DISABLE_LDAP" = "x1"; then + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS]) + AC_SUBST(CURL_DISABLE_LDAPS, [1]) + else + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LDAP_SSL, 1, [Use LDAPS implementation]) + AC_SUBST(HAVE_LDAP_SSL, [1]) + fi ] ) dnl ********************************************************************** @@ -762,7 +760,7 @@ if test X"$want_hyper" != Xno; then CURL_CHECK_PKGCONFIG(hyper, $want_hyper_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_HYPER=`CURL_EXPORT_PCDIR([$want_hyper_path]) $PKGCONFIG --libs-only-l hyper` CPP_HYPER=`CURL_EXPORT_PCDIR([$want_hyper_path]) dnl @@ -793,7 +791,7 @@ if test X"$want_hyper" != Xno; then AC_CHECK_LIB(hyper, hyper_io_new, [ - AC_CHECK_HEADERS(hyper.h, + AC_CHECK_HEADERS(hyper.h, experimental="$experimental Hyper" AC_MSG_NOTICE([Hyper support is experimental]) curl_h1_msg="enabled (Hyper)" @@ -804,7 +802,7 @@ if test X"$want_hyper" != Xno; then export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_HYPER to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE hyper" - ) + ) ], for d in `echo $DIR_HYPER | $SED -e 's/:/ /'`; do if test -f "$d/libhyper.a"; then @@ -827,25 +825,25 @@ AS_HELP_STRING([--enable-rtsp],[Enable RTSP support]) AS_HELP_STRING([--disable-rtsp],[Disable RTSP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) - AC_SUBST(CURL_DISABLE_RTSP, [1]) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP]) + AC_SUBST(CURL_DISABLE_RTSP, [1]) + ;; *) - if test x$CURL_DISABLE_HTTP = x1 ; then - AC_MSG_ERROR(HTTP support needs to be enabled in order to enable RTSP support!) - else - AC_MSG_RESULT(yes) - curl_rtsp_msg="enabled" - fi - ;; + if test x$CURL_DISABLE_HTTP = x1; then + AC_MSG_ERROR(HTTP support needs to be enabled in order to enable RTSP support!) + else + AC_MSG_RESULT(yes) + curl_rtsp_msg="enabled" + fi + ;; esac ], - if test "x$CURL_DISABLE_HTTP" != "x1"; then - AC_MSG_RESULT(yes) - curl_rtsp_msg="enabled" - else - AC_MSG_RESULT(no) - fi + if test "x$CURL_DISABLE_HTTP" != "x1"; then + AC_MSG_RESULT(yes) + curl_rtsp_msg="enabled" + else + AC_MSG_RESULT(no) + fi ) fi @@ -855,15 +853,16 @@ AS_HELP_STRING([--enable-proxy],[Enable proxy support]) AS_HELP_STRING([--disable-proxy],[Disable proxy support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_PROXY, 1, [to disable proxies]) - AC_SUBST(CURL_DISABLE_PROXY, [1]) - https_proxy="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_PROXY, 1, [to disable proxies]) + AC_SUBST(CURL_DISABLE_PROXY, [1]) + https_proxy="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support dict]) @@ -872,44 +871,49 @@ AS_HELP_STRING([--enable-dict],[Enable DICT support]) AS_HELP_STRING([--disable-dict],[Disable DICT support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_DICT, 1, [to disable DICT]) - AC_SUBST(CURL_DISABLE_DICT, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_DICT, 1, [to disable DICT]) + AC_SUBST(CURL_DISABLE_DICT, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) + AC_MSG_CHECKING([whether to support telnet]) AC_ARG_ENABLE(telnet, AS_HELP_STRING([--enable-telnet],[Enable TELNET support]) AS_HELP_STRING([--disable-telnet],[Disable TELNET support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET]) - AC_SUBST(CURL_DISABLE_TELNET, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET]) + AC_SUBST(CURL_DISABLE_TELNET, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) + AC_MSG_CHECKING([whether to support tftp]) AC_ARG_ENABLE(tftp, AS_HELP_STRING([--enable-tftp],[Enable TFTP support]) AS_HELP_STRING([--disable-tftp],[Disable TFTP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_TFTP, 1, [to disable TFTP]) - AC_SUBST(CURL_DISABLE_TFTP, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_TFTP, 1, [to disable TFTP]) + AC_SUBST(CURL_DISABLE_TFTP, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support pop3]) @@ -918,48 +922,49 @@ AS_HELP_STRING([--enable-pop3],[Enable POP3 support]) AS_HELP_STRING([--disable-pop3],[Disable POP3 support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_POP3, 1, [to disable POP3]) - AC_SUBST(CURL_DISABLE_POP3, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_POP3, 1, [to disable POP3]) + AC_SUBST(CURL_DISABLE_POP3, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) - AC_MSG_CHECKING([whether to support imap]) AC_ARG_ENABLE(imap, AS_HELP_STRING([--enable-imap],[Enable IMAP support]) AS_HELP_STRING([--disable-imap],[Disable IMAP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_IMAP, 1, [to disable IMAP]) - AC_SUBST(CURL_DISABLE_IMAP, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_IMAP, 1, [to disable IMAP]) + AC_SUBST(CURL_DISABLE_IMAP, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) - AC_MSG_CHECKING([whether to support smb]) AC_ARG_ENABLE(smb, AS_HELP_STRING([--enable-smb],[Enable SMB/CIFS support]) AS_HELP_STRING([--disable-smb],[Disable SMB/CIFS support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_SMB, 1, [to disable SMB/CIFS]) - AC_SUBST(CURL_DISABLE_SMB, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SMB, 1, [to disable SMB/CIFS]) + AC_SUBST(CURL_DISABLE_SMB, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support smtp]) @@ -968,14 +973,15 @@ AS_HELP_STRING([--enable-smtp],[Enable SMTP support]) AS_HELP_STRING([--disable-smtp],[Disable SMTP support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_SMTP, 1, [to disable SMTP]) - AC_SUBST(CURL_DISABLE_SMTP, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SMTP, 1, [to disable SMTP]) + AC_SUBST(CURL_DISABLE_SMTP, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support gopher]) @@ -984,14 +990,15 @@ AS_HELP_STRING([--enable-gopher],[Enable Gopher support]) AS_HELP_STRING([--disable-gopher],[Disable Gopher support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable Gopher]) - AC_SUBST(CURL_DISABLE_GOPHER, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable Gopher]) + AC_SUBST(CURL_DISABLE_GOPHER, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) AC_MSG_CHECKING([whether to support mqtt]) @@ -1000,14 +1007,15 @@ AS_HELP_STRING([--enable-mqtt],[Enable MQTT support]) AS_HELP_STRING([--disable-mqtt],[Disable MQTT support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_MQTT, 1, [to disable MQTT]) - AC_SUBST(CURL_DISABLE_MQTT, [1]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_MQTT, 1, [to disable MQTT]) + AC_SUBST(CURL_DISABLE_MQTT, [1]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(no) + AC_MSG_RESULT(no) ) dnl ********************************************************************** @@ -1020,14 +1028,15 @@ AS_HELP_STRING([--enable-manual],[Enable built-in manual]) AS_HELP_STRING([--disable-manual],[Disable built-in manual]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - ;; - *) AC_MSG_RESULT(yes) - USE_MANUAL="1" - ;; + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_RESULT(yes) + USE_MANUAL="1" + ;; esac ], - AC_MSG_RESULT(yes) - USE_MANUAL="1" + AC_MSG_RESULT(yes) + USE_MANUAL="1" ) dnl The actual use of the USE_MANUAL variable is done much later in this dnl script to allow other actions to disable it as well. @@ -1042,18 +1051,19 @@ AS_HELP_STRING([--enable-docs],[Enable documentation]) AS_HELP_STRING([--disable-docs],[Disable documentation]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - BUILD_DOCS=0 - dnl disable manual too because it needs built documentation - USE_MANUAL=0 - curl_docs_msg="no" - ;; - *) AC_MSG_RESULT(yes) - BUILD_DOCS=1 - ;; + AC_MSG_RESULT(no) + BUILD_DOCS=0 + dnl disable manual too because it needs built documentation + USE_MANUAL=0 + curl_docs_msg="no" + ;; + *) + AC_MSG_RESULT(yes) + BUILD_DOCS=1 + ;; esac ], - AC_MSG_RESULT(yes) - BUILD_DOCS=1 + AC_MSG_RESULT(yes) + BUILD_DOCS=1 ) @@ -1066,14 +1076,15 @@ AS_HELP_STRING([--enable-libcurl-option],[Enable --libcurl C code generation sup AS_HELP_STRING([--disable-libcurl-option],[Disable --libcurl C code generation support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_LIBCURL_OPTION, 1, [to disable --libcurl C code generation option]) - curl_libcurl_msg="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_LIBCURL_OPTION, 1, [to disable --libcurl C code generation option]) + curl_libcurl_msg="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ********************************************************************** @@ -1085,51 +1096,58 @@ AC_ARG_ENABLE(libgcc, AS_HELP_STRING([--enable-libgcc],[use libgcc when linking]), [ case "$enableval" in yes) - LIBS="-lgcc $LIBS" - AC_MSG_RESULT(yes) - ;; - *) AC_MSG_RESULT(no) - ;; + LIBS="-lgcc $LIBS" + AC_MSG_RESULT(yes) + ;; + *) + AC_MSG_RESULT(no) + ;; esac ], - AC_MSG_RESULT(no) + AC_MSG_RESULT(no) ) CURL_CHECK_LIB_XNET dnl gethostbyname without lib or in the nsl lib? AC_CHECK_FUNC(gethostbyname, - [HAVE_GETHOSTBYNAME="1" - ], - [ AC_CHECK_LIB(nsl, gethostbyname, - [HAVE_GETHOSTBYNAME="1" - LIBS="-lnsl $LIBS" - ]) - ]) - -if test "$HAVE_GETHOSTBYNAME" != "1" -then + [ + HAVE_GETHOSTBYNAME="1" + ], + [ + AC_CHECK_LIB(nsl, gethostbyname, + [ + HAVE_GETHOSTBYNAME="1" + LIBS="-lnsl $LIBS" + ] + ) + ] +) + +if test "$HAVE_GETHOSTBYNAME" != "1"; then dnl gethostbyname in the socket lib? AC_CHECK_LIB(socket, gethostbyname, - [HAVE_GETHOSTBYNAME="1" - LIBS="-lsocket $LIBS" - ]) + [ + HAVE_GETHOSTBYNAME="1" + LIBS="-lsocket $LIBS" + ] + ) fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then dnl gethostbyname in the watt lib? AC_CHECK_LIB(watt, gethostbyname, - [HAVE_GETHOSTBYNAME="1" - CPPFLAGS="-I/dev/env/WATT_ROOT/inc" - LDFLAGS="-L/dev/env/WATT_ROOT/lib" - LIBS="-lwatt $LIBS" - ]) + [ + HAVE_GETHOSTBYNAME="1" + CPPFLAGS="-I${WATT_ROOT}/inc" + LDFLAGS="-L${WATT_ROOT}/lib" + LIBS="-lwatt $LIBS" + ] + ) fi dnl At least one system has been identified to require BOTH nsl and socket dnl libs at the same time to link properly. -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then AC_MSG_CHECKING([for gethostbyname with both nsl and socket libs]) my_ac_save_LIBS=$LIBS LIBS="-lnsl -lsocket $LIBS" @@ -1147,9 +1165,8 @@ then ]) fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then - dnl This is for winsock systems +if test "$HAVE_GETHOSTBYNAME" != "1"; then + dnl This is for Winsock systems if test "$curl_cv_native_windows" = "yes"; then winsock_LIB="-lws2_32" if test ! -z "$winsock_LIB"; then @@ -1179,8 +1196,7 @@ then fi fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then dnl This is for Minix 3.1 AC_MSG_CHECKING([for gethostbyname for Minix 3]) AC_LINK_IFELSE([ @@ -1198,8 +1214,7 @@ then ]) fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then dnl This is for eCos with a stubbed DNS implementation AC_MSG_CHECKING([for gethostbyname for eCos]) AC_LINK_IFELSE([ @@ -1217,8 +1232,7 @@ then ]) fi -if test "$HAVE_GETHOSTBYNAME" != "1" -o "${with_amissl+set}" = set -then +if test "$HAVE_GETHOSTBYNAME" != "1" -o "${with_amissl+set}" = set; then dnl This is for AmigaOS with bsdsocket.library - needs testing before -lnet AC_MSG_CHECKING([for gethostbyname for AmigaOS bsdsocket.library]) AC_LINK_IFELSE([ @@ -1244,13 +1258,14 @@ then ]) fi -if test "$HAVE_GETHOSTBYNAME" != "1" -then +if test "$HAVE_GETHOSTBYNAME" != "1"; then dnl gethostbyname in the network lib - for Haiku OS AC_CHECK_LIB(network, gethostbyname, - [HAVE_GETHOSTBYNAME="1" - LIBS="-lnetwork $LIBS" - ]) + [ + HAVE_GETHOSTBYNAME="1" + LIBS="-lnetwork $LIBS" + ] + ) fi if test "$HAVE_GETHOSTBYNAME" != "1"; then @@ -1291,19 +1306,19 @@ ZLIB_LIBS="" AC_ARG_WITH(zlib, AS_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH]) AS_HELP_STRING([--without-zlib],[disable use of zlib]), - [OPT_ZLIB="$withval"]) + [OPT_ZLIB="$withval"]) -if test "$OPT_ZLIB" = "no" ; then - AC_MSG_WARN([zlib disabled]) +if test "$OPT_ZLIB" = "no"; then + AC_MSG_WARN([zlib disabled]) else - if test "$OPT_ZLIB" = "yes" ; then + if test "$OPT_ZLIB" = "yes"; then OPT_ZLIB="" fi - if test -z "$OPT_ZLIB" ; then + if test -z "$OPT_ZLIB"; then CURL_CHECK_PKGCONFIG(zlib) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then ZLIB_LIBS="`$PKGCONFIG --libs-only-l zlib`" if test -n "$ZLIB_LIBS"; then LDFLAGS="$LDFLAGS `$PKGCONFIG --libs-only-L zlib`" @@ -1322,37 +1337,45 @@ else dnl people have it in the default path AC_CHECK_LIB(z, inflateEnd, - dnl libz found, set the variable - [HAVE_LIBZ="1" - ZLIB_LIBS="-lz" - LIBS="$ZLIB_LIBS $LIBS"], - dnl if no lib found, try /usr/local - [OPT_ZLIB="/usr/local"]) + dnl libz found, set the variable + [ + HAVE_LIBZ="1" + ZLIB_LIBS="-lz" + LIBS="$ZLIB_LIBS $LIBS" + ], + dnl if no lib found, try /usr/local + [ + OPT_ZLIB="/usr/local" + ] + ) fi fi dnl Add a nonempty path to the compiler flags if test -n "$OPT_ZLIB"; then - CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" - LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff" + CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" + LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff" fi AC_CHECK_HEADER(zlib.h, [ - dnl zlib.h was found - HAVE_ZLIB_H="1" - dnl if the lib wasn't found already, try again with the new paths - if test "$HAVE_LIBZ" != "1"; then - AC_CHECK_LIB(z, gzread, - [ - dnl the lib was found! - HAVE_LIBZ="1" - ZLIB_LIBS="-lz" - LIBS="$ZLIB_LIBS $LIBS" - ], - [ CPPFLAGS=$clean_CPPFLAGS - LDFLAGS=$clean_LDFLAGS]) - fi + dnl zlib.h was found + HAVE_ZLIB_H="1" + dnl if the lib wasn't found already, try again with the new paths + if test "$HAVE_LIBZ" != "1"; then + AC_CHECK_LIB(z, gzread, + [ + dnl the lib was found! + HAVE_LIBZ="1" + ZLIB_LIBS="-lz" + LIBS="$ZLIB_LIBS $LIBS" + ], + [ + CPPFLAGS=$clean_CPPFLAGS + LDFLAGS=$clean_LDFLAGS + ] + ) + fi ], [ dnl zlib.h was not found, restore the flags @@ -1360,23 +1383,20 @@ else LDFLAGS=$clean_LDFLAGS] ) - if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1" - then + if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1"; then AC_MSG_WARN([configure found only the libz lib, not the header file!]) HAVE_LIBZ="" CPPFLAGS=$clean_CPPFLAGS LDFLAGS=$clean_LDFLAGS LIBS=$clean_LIBS ZLIB_LIBS="" - elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1" - then + elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1"; then AC_MSG_WARN([configure found only the libz header file, not the lib!]) CPPFLAGS=$clean_CPPFLAGS LDFLAGS=$clean_LDFLAGS LIBS=$clean_LIBS ZLIB_LIBS="" - elif test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" = "1" - then + elif test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" = "1"; then dnl both header and lib were found! AC_SUBST(HAVE_LIBZ) AC_DEFINE(HAVE_LIBZ, 1, [if zlib is available]) @@ -1414,26 +1434,26 @@ if test X"$OPT_BROTLI" != Xno; then CLEANLIBS="$LIBS" case "$OPT_BROTLI" in - yes) - dnl --with-brotli (without path) used - CURL_CHECK_PKGCONFIG(libbrotlidec) - - if test "$PKGCONFIG" != "no" ; then - LIB_BROTLI=`$PKGCONFIG --libs-only-l libbrotlidec` - LD_BROTLI=`$PKGCONFIG --libs-only-L libbrotlidec` - CPP_BROTLI=`$PKGCONFIG --cflags-only-I libbrotlidec` - version=`$PKGCONFIG --modversion libbrotlidec` - DIR_BROTLI=`echo $LD_BROTLI | $SED -e 's/^-L//'` - fi + yes) + dnl --with-brotli (without path) used + CURL_CHECK_PKGCONFIG(libbrotlidec) + + if test "$PKGCONFIG" != "no"; then + LIB_BROTLI=`$PKGCONFIG --libs-only-l libbrotlidec` + LD_BROTLI=`$PKGCONFIG --libs-only-L libbrotlidec` + CPP_BROTLI=`$PKGCONFIG --cflags-only-I libbrotlidec` + version=`$PKGCONFIG --modversion libbrotlidec` + DIR_BROTLI=`echo $LD_BROTLI | $SED -e 's/^-L//'` + fi - ;; - off) - dnl no --with-brotli option given, just check default places - ;; - *) - dnl use the given --with-brotli spot - PREFIX_BROTLI=$OPT_BROTLI - ;; + ;; + off) + dnl no --with-brotli option given, just check default places + ;; + *) + dnl use the given --with-brotli spot + PREFIX_BROTLI=$OPT_BROTLI + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -1464,15 +1484,15 @@ if test X"$OPT_BROTLI" != Xno; then if test "$HAVE_BROTLI" = "1"; then if test -n "$DIR_BROTLI"; then - dnl when the brotli shared libs were found in a path that the run-time - dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH - dnl to prevent further configure tests to fail due to this - - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_BROTLI" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $DIR_BROTLI to CURL_LIBRARY_PATH]) - fi + dnl when the brotli shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_BROTLI" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_BROTLI to CURL_LIBRARY_PATH]) + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libbrotlidec" else @@ -1501,26 +1521,26 @@ if test X"$OPT_ZSTD" != Xno; then CLEANLIBS="$LIBS" case "$OPT_ZSTD" in - yes) - dnl --with-zstd (without path) used - CURL_CHECK_PKGCONFIG(libzstd) - - if test "$PKGCONFIG" != "no" ; then - LIB_ZSTD=`$PKGCONFIG --libs-only-l libzstd` - LD_ZSTD=`$PKGCONFIG --libs-only-L libzstd` - CPP_ZSTD=`$PKGCONFIG --cflags-only-I libzstd` - version=`$PKGCONFIG --modversion libzstd` - DIR_ZSTD=`echo $LD_ZSTD | $SED -e 's/-L//'` - fi + yes) + dnl --with-zstd (without path) used + CURL_CHECK_PKGCONFIG(libzstd) + + if test "$PKGCONFIG" != "no"; then + LIB_ZSTD=`$PKGCONFIG --libs-only-l libzstd` + LD_ZSTD=`$PKGCONFIG --libs-only-L libzstd` + CPP_ZSTD=`$PKGCONFIG --cflags-only-I libzstd` + version=`$PKGCONFIG --modversion libzstd` + DIR_ZSTD=`echo $LD_ZSTD | $SED -e 's/-L//'` + fi - ;; - off) - dnl no --with-zstd option given, just check default places - ;; - *) - dnl use the given --with-zstd spot - PREFIX_ZSTD=$OPT_ZSTD - ;; + ;; + off) + dnl no --with-zstd option given, just check default places + ;; + *) + dnl use the given --with-zstd spot + PREFIX_ZSTD=$OPT_ZSTD + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -1551,16 +1571,16 @@ if test X"$OPT_ZSTD" != Xno; then if test "$HAVE_ZSTD" = "1"; then if test -n "$DIR_ZSTD"; then - dnl when the zstd shared lib were found in a path that the run-time - dnl linker doesn't search through, we need to add it to - dnl CURL_LIBRARY_PATH to prevent further configure tests to fail due to - dnl this - - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_ZSTD" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $DIR_ZSTD to CURL_LIBRARY_PATH]) - fi + dnl when the zstd shared lib were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl CURL_LIBRARY_PATH to prevent further configure tests to fail due to + dnl this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_ZSTD" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_ZSTD to CURL_LIBRARY_PATH]) + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libzstd" else @@ -1578,20 +1598,20 @@ dnl ********************************************************************** LDAPLIBNAME="" AC_ARG_WITH(ldap-lib, AS_HELP_STRING([--with-ldap-lib=libname],[Specify name of ldap lib file]), - [LDAPLIBNAME="$withval"]) + [LDAPLIBNAME="$withval"]) LBERLIBNAME="" AC_ARG_WITH(lber-lib, AS_HELP_STRING([--with-lber-lib=libname],[Specify name of lber lib file]), - [LBERLIBNAME="$withval"]) + [LBERLIBNAME="$withval"]) -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then CURL_CHECK_HEADER_LBER CURL_CHECK_HEADER_LDAP CURL_CHECK_HEADER_LDAP_SSL - if test -z "$LDAPLIBNAME" ; then + if test -z "$LDAPLIBNAME"; then if test "$curl_cv_native_windows" = "yes"; then dnl Windows uses a single and unique LDAP library name LDAPLIBNAME="wldap32" @@ -1599,7 +1619,7 @@ if test x$CURL_DISABLE_LDAP != x1 ; then fi fi - if test "$LDAPLIBNAME" ; then + if test "$LDAPLIBNAME"; then AC_CHECK_LIB("$LDAPLIBNAME", ldap_init,, [ if test -n "$ldap_askedfor"; then AC_MSG_ERROR([couldn't detect the LDAP libraries]) @@ -1627,12 +1647,12 @@ if test x$CURL_DISABLE_LDAP != x1 ; then fi fi -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then - if test "$LBERLIBNAME" ; then + if test "$LBERLIBNAME"; then dnl If name is "no" then don't define this library at all dnl (it's only needed if libldap.so's dependencies are broken). - if test "$LBERLIBNAME" != "no" ; then + if test "$LBERLIBNAME" != "no"; then AC_CHECK_LIB("$LBERLIBNAME", ber_free,, [ AC_MSG_WARN(["$LBERLIBNAME" is not an LBER library: LDAP disabled]) AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) @@ -1643,7 +1663,7 @@ if test x$CURL_DISABLE_LDAP != x1 ; then fi fi -if test x$CURL_DISABLE_LDAP != x1 ; then +if test x$CURL_DISABLE_LDAP != x1; then AC_CHECK_FUNCS([ldap_url_parse \ ldap_init_fd]) @@ -1661,8 +1681,8 @@ if test x$CURL_DISABLE_LDAP != x1 ; then fi fi -if test x$CURL_DISABLE_LDAPS != x1 ; then - curl_ldaps_msg="enabled" +if test x$CURL_DISABLE_LDAPS != x1; then + curl_ldaps_msg="enabled" fi dnl ********************************************************************** @@ -1675,12 +1695,13 @@ AS_HELP_STRING([--enable-ipv6],[Enable IPv6 (with IPv4) support]) AS_HELP_STRING([--disable-ipv6],[Disable IPv6 support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - ipv6=no - ;; - *) AC_MSG_RESULT(yes) - ipv6=yes - ;; + AC_MSG_RESULT(no) + ipv6=no + ;; + *) + AC_MSG_RESULT(yes) + ipv6=yes + ;; esac ], AC_RUN_IFELSE([AC_LANG_SOURCE([[ @@ -1735,11 +1756,11 @@ if test "$ipv6" = yes; then struct sockaddr_in6 s; s.sin6_scope_id = 0; ]])], [ - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID, 1, [Define to 1 if struct sockaddr_in6 has the sin6_scope_id member]) - ], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID, 1, [Define to 1 if struct sockaddr_in6 has the sin6_scope_id member]) + ], [ AC_MSG_RESULT([no]) - ]) + ]) fi dnl ********************************************************************** @@ -1770,17 +1791,17 @@ int main(int argc, char **argv) curl_cv_writable_argv=cross ]) case $curl_cv_writable_argv in -yes) - AC_DEFINE(HAVE_WRITABLE_ARGV, 1, [Define this symbol if your OS supports changing the contents of argv]) - AC_MSG_RESULT(yes) - ;; -no) - AC_MSG_RESULT(no) - ;; -*) - AC_MSG_RESULT(no) - AC_MSG_WARN([the previous check could not be made default was used]) - ;; + yes) + AC_DEFINE(HAVE_WRITABLE_ARGV, 1, [Define this symbol if your OS supports changing the contents of argv]) + AC_MSG_RESULT(yes) + ;; + no) + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_RESULT(no) + AC_MSG_WARN([the previous check could not be made default was used]) + ;; esac dnl ********************************************************************** @@ -1791,31 +1812,31 @@ dnl check for GSS-API stuff in the /usr as default GSSAPI_ROOT="/usr" AC_ARG_WITH(gssapi-includes, - AS_HELP_STRING([--with-gssapi-includes=DIR], - [Specify location of GSS-API headers]), - [ GSSAPI_INCS="-I$withval" - want_gss="yes" ] + AS_HELP_STRING([--with-gssapi-includes=DIR], [Specify location of GSS-API headers]), [ + GSSAPI_INCS="-I$withval" + want_gss="yes" + ] ) AC_ARG_WITH(gssapi-libs, - AS_HELP_STRING([--with-gssapi-libs=DIR], - [Specify location of GSS-API libs]), - [ GSSAPI_LIB_DIR="-L$withval" - want_gss="yes" ] + AS_HELP_STRING([--with-gssapi-libs=DIR], [Specify location of GSS-API libs]), [ + GSSAPI_LIB_DIR="-L$withval" + want_gss="yes" + ] ) AC_ARG_WITH(gssapi, - AS_HELP_STRING([--with-gssapi=DIR], - [Where to look for GSS-API]), [ - GSSAPI_ROOT="$withval" - if test x"$GSSAPI_ROOT" != xno; then - want_gss="yes" - if test x"$GSSAPI_ROOT" = xyes; then - dnl if yes, then use default root - GSSAPI_ROOT="/usr" + AS_HELP_STRING([--with-gssapi=DIR], [Where to look for GSS-API]), [ + GSSAPI_ROOT="$withval" + if test x"$GSSAPI_ROOT" != xno; then + want_gss="yes" + if test x"$GSSAPI_ROOT" = xyes; then + dnl if yes, then use default root + GSSAPI_ROOT="/usr" + fi fi - fi -]) + ] +) : ${KRB5CONFIG:="$GSSAPI_ROOT/bin/krb5-config"} @@ -1830,15 +1851,15 @@ if test x"$want_gss" = xyes; then CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) fi if test -z "$GSSAPI_INCS"; then - if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` - elif test "$PKGCONFIG" != "no" ; then - GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` - elif test -f "$KRB5CONFIG"; then - GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` - elif test "$GSSAPI_ROOT" != "yes"; then - GSSAPI_INCS="-I$GSSAPI_ROOT/include" - fi + if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` + elif test "$PKGCONFIG" != "no"; then + GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` + elif test -f "$KRB5CONFIG"; then + GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` + elif test "$GSSAPI_ROOT" != "yes"; then + GSSAPI_INCS="-I$GSSAPI_ROOT/include" + fi fi CPPFLAGS="$CPPFLAGS $GSSAPI_INCS" @@ -1865,13 +1886,13 @@ AC_INCLUDES_DEFAULT if test "x$not_mit" = "x1"; then dnl MIT not found, check for Heimdal AC_CHECK_HEADER(gssapi.h, - [], - [ - dnl no header found, disabling GSS - want_gss=no - AC_MSG_WARN(disabling GSS-API support since no header files were found) - ] - ) + [], + [ + dnl no header found, disabling GSS + want_gss=no + AC_MSG_WARN(disabling GSS-API support since no header files were found) + ] + ) else dnl MIT found dnl check if we have a really old MIT Kerberos version (<= 1.2) @@ -1911,58 +1932,58 @@ if test x"$want_gss" = xyes; then LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" LIBS="-lgss $LIBS" elif test -z "$GSSAPI_LIB_DIR"; then - case $host in - *-*-darwin*) + case $host in + *-*-darwin*) LIBS="-lgssapi_krb5 -lresolv $LIBS" ;; - *) + *) if test $GSSAPI_ROOT != "/usr"; then CURL_CHECK_PKGCONFIG(mit-krb5-gssapi, $GSSAPI_ROOT/lib/pkgconfig) else CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) fi if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - dnl krb5-config doesn't have --libs-only-L or similar, put everything - dnl into LIBS - gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` - LIBS="$gss_libs $LIBS" - elif test "$PKGCONFIG" != "no" ; then - gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` - LIBS="$gss_libs $LIBS" + dnl krb5-config doesn't have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` + LIBS="$gss_libs $LIBS" + elif test "$PKGCONFIG" != "no"; then + gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` + LIBS="$gss_libs $LIBS" elif test -f "$KRB5CONFIG"; then - dnl krb5-config doesn't have --libs-only-L or similar, put everything - dnl into LIBS - gss_libs=`$KRB5CONFIG --libs gssapi` - LIBS="$gss_libs $LIBS" + dnl krb5-config doesn't have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$KRB5CONFIG --libs gssapi` + LIBS="$gss_libs $LIBS" else - case $host in - *-hp-hpux*) + case $host in + *-hp-hpux*) gss_libname="gss" ;; - *) + *) gss_libname="gssapi" ;; - esac - - if test "$GSSAPI_ROOT" != "yes"; then - LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" - LIBS="-l$gss_libname $LIBS" - else - LIBS="-l$gss_libname $LIBS" - fi + esac + + if test "$GSSAPI_ROOT" != "yes"; then + LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" + LIBS="-l$gss_libname $LIBS" + else + LIBS="-l$gss_libname $LIBS" + fi fi ;; - esac + esac else - LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" - case $host in - *-hp-hpux*) + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + case $host in + *-hp-hpux*) LIBS="-lgss $LIBS" ;; - *) + *) LIBS="-lgssapi $LIBS" ;; - esac + esac fi else CPPFLAGS="$save_CPPFLAGS" @@ -2033,51 +2054,47 @@ if test "x$curl_cv_native_windows" = "xyes"; then LIBS="-lbcrypt $LIBS" fi -case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED" -in -x) - AC_MSG_ERROR([TLS not detected, you will not be able to use HTTPS, FTPS, NTLM and more. +case "x$SSL_DISABLED$OPENSSL_ENABLED$GNUTLS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$SCHANNEL_ENABLED$SECURETRANSPORT_ENABLED$BEARSSL_ENABLED$RUSTLS_ENABLED" in + x) + AC_MSG_ERROR([TLS not detected, you will not be able to use HTTPS, FTPS, NTLM and more. Use --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl or --with-rustls to address this.]) - ;; -x1) - # one SSL backend is enabled - AC_SUBST(SSL_ENABLED) - SSL_ENABLED="1" - AC_MSG_NOTICE([built with one SSL backend]) - ;; -xD) - # explicitly built without TLS - ;; -xD*) - AC_MSG_ERROR([--without-ssl has been set together with an explicit option to use an ssl library + ;; + x1) + # one SSL backend is enabled + AC_SUBST(SSL_ENABLED) + SSL_ENABLED="1" + AC_MSG_NOTICE([built with one SSL backend]) + ;; + xD) + # explicitly built without TLS + ;; + xD*) + AC_MSG_ERROR([--without-ssl has been set together with an explicit option to use an ssl library (e.g. --with-openssl, --with-gnutls, --with-wolfssl, --with-mbedtls, --with-schannel, --with-secure-transport, --with-amissl, --with-bearssl, --with-rustls). Since these are conflicting parameters, verify which is the desired one and drop the other.]) - ;; -*) - # more than one SSL backend is enabled - AC_SUBST(SSL_ENABLED) - SSL_ENABLED="1" - AC_SUBST(CURL_WITH_MULTI_SSL) - CURL_WITH_MULTI_SSL="1" - AC_DEFINE(CURL_WITH_MULTI_SSL, 1, [built with multiple SSL backends]) - AC_MSG_NOTICE([built with multiple SSL backends]) - ;; + ;; + *) + # more than one SSL backend is enabled + AC_SUBST(SSL_ENABLED) + SSL_ENABLED="1" + AC_SUBST(CURL_WITH_MULTI_SSL) + CURL_WITH_MULTI_SSL="1" + AC_DEFINE(CURL_WITH_MULTI_SSL, 1, [built with multiple SSL backends]) + AC_MSG_NOTICE([built with multiple SSL backends]) + ;; esac if test -n "$ssl_backends"; then curl_ssl_msg="enabled ($ssl_backends)" fi -if test no = "$VALID_DEFAULT_SSL_BACKEND" -then - if test -n "$SSL_ENABLED" - then +if test no = "$VALID_DEFAULT_SSL_BACKEND"; then + if test -n "$SSL_ENABLED"; then AC_MSG_ERROR([Default SSL backend $DEFAULT_SSL_BACKEND not enabled!]) else AC_MSG_ERROR([Default SSL backend requires SSL!]) fi -elif test yes = "$VALID_DEFAULT_SSL_BACKEND" -then +elif test yes = "$VALID_DEFAULT_SSL_BACKEND"; then AC_DEFINE_UNQUOTED([CURL_DEFAULT_SSL_BACKEND], ["$DEFAULT_SSL_BACKEND"], [Default SSL backend]) fi @@ -2087,8 +2104,11 @@ dnl ********************************************************************** if test -n "$check_for_ca_bundle"; then CURL_CHECK_CA_BUNDLE + CURL_CHECK_CA_EMBED fi +AM_CONDITIONAL(CURL_CA_EMBED_SET, test "x$CURL_CA_EMBED" != "x") + dnl ********************************************************************** dnl Check for libpsl dnl ********************************************************************** @@ -2107,29 +2127,25 @@ if test X"$OPT_LIBPSL" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBPSL" in - yes) - dnl --with-libpsl (without path) used - CURL_CHECK_PKGCONFIG(libpsl) + yes|off) + dnl --with-libpsl (without path) used + CURL_CHECK_PKGCONFIG(libpsl) + + if test "$PKGCONFIG" != "no"; then + LIB_PSL=`$PKGCONFIG --libs-only-l libpsl` + LD_PSL=`$PKGCONFIG --libs-only-L libpsl` + CPP_PSL=`$PKGCONFIG --cflags-only-I libpsl` + else + dnl no libpsl pkg-config found + LIB_PSL="-lpsl" + fi - if test "$PKGCONFIG" != "no" ; then - LIB_PSL=`$PKGCONFIG --libs-only-l libpsl` - LD_PSL=`$PKGCONFIG --libs-only-L libpsl` - CPP_PSL=`$PKGCONFIG --cflags-only-I libpsl` - else - dnl no libpsl pkg-config found + ;; + *) + dnl use the given --with-libpsl spot LIB_PSL="-lpsl" - fi - - ;; - off) - dnl no --with-libpsl option given, just check default places - LIB_PSL="-lpsl" - ;; - *) - dnl use the given --with-libpsl spot - LIB_PSL="-lpsl" - PREFIX_PSL=$OPT_LIBPSL - ;; + PREFIX_PSL=$OPT_LIBPSL + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -2144,13 +2160,13 @@ if test X"$OPT_LIBPSL" != Xno; then AC_CHECK_LIB(psl, psl_builtin, [ - AC_CHECK_HEADERS(libpsl.h, + AC_CHECK_HEADERS(libpsl.h, curl_psl_msg="enabled" LIBPSL_ENABLED=1 AC_DEFINE(USE_LIBPSL, 1, [if libpsl is in use]) AC_SUBST(USE_LIBPSL, [1]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libpsl" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -2158,8 +2174,7 @@ if test X"$OPT_LIBPSL" != Xno; then LIBS=$CLEANLIBS ) - if test X"$OPT_LIBPSL" != Xoff && - test "$LIBPSL_ENABLED" != "1"; then + if test "$LIBPSL_ENABLED" != "1"; then AC_MSG_ERROR([libpsl libs and/or directories were not found where specified!]) fi fi @@ -2171,18 +2186,19 @@ dnl Check for libgsasl dnl ********************************************************************** AC_ARG_WITH(libgsasl, - AS_HELP_STRING([--without-libgsasl], - [disable libgsasl support for SCRAM]), - with_libgsasl=$withval, - with_libgsasl=yes) + AS_HELP_STRING([--without-libgsasl], + [disable libgsasl support for SCRAM]), + with_libgsasl=$withval, + with_libgsasl=yes) if test $with_libgsasl != "no"; then AC_SEARCH_LIBS(gsasl_init, gsasl, [curl_gsasl_msg="enabled"; - AC_DEFINE([USE_GSASL], [1], [GSASL support enabled]) - ], + AC_DEFINE([USE_GSASL], [1], [GSASL support enabled]) + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libgsasl" + ], [curl_gsasl_msg="no (libgsasl not found)"; - AC_MSG_WARN([libgsasl was not found]) - ] + AC_MSG_WARN([libgsasl was not found]) + ] ) fi AM_CONDITIONAL([USE_GSASL], [test "$curl_gsasl_msg" = "enabled"]) @@ -2221,26 +2237,26 @@ if test X"$OPT_LIBSSH2" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBSSH2" in - yes) - dnl --with-libssh2 (without path) used - CURL_CHECK_PKGCONFIG(libssh2) - - if test "$PKGCONFIG" != "no" ; then - LIB_SSH2=`$PKGCONFIG --libs-only-l libssh2` - LD_SSH2=`$PKGCONFIG --libs-only-L libssh2` - CPP_SSH2=`$PKGCONFIG --cflags-only-I libssh2` - version=`$PKGCONFIG --modversion libssh2` - DIR_SSH2=`echo $LD_SSH2 | $SED -e 's/^-L//'` - fi + yes) + dnl --with-libssh2 (without path) used + CURL_CHECK_PKGCONFIG(libssh2) + + if test "$PKGCONFIG" != "no"; then + LIB_SSH2=`$PKGCONFIG --libs-only-l libssh2` + LD_SSH2=`$PKGCONFIG --libs-only-L libssh2` + CPP_SSH2=`$PKGCONFIG --cflags-only-I libssh2` + version=`$PKGCONFIG --modversion libssh2` + DIR_SSH2=`echo $LD_SSH2 | $SED -e 's/^-L//'` + fi - ;; - off) - dnl no --with-libssh2 option given, just check default places - ;; - *) - dnl use the given --with-libssh2 spot - PREFIX_SSH2=$OPT_LIBSSH2 - ;; + ;; + off) + dnl no --with-libssh2 option given, just check default places + ;; + *) + dnl use the given --with-libssh2 spot + PREFIX_SSH2=$OPT_LIBSSH2 + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -2272,15 +2288,15 @@ if test X"$OPT_LIBSSH2" != Xno; then if test "$LIBSSH2_ENABLED" = "1"; then if test -n "$DIR_SSH2"; then - dnl when the libssh2 shared libs were found in a path that the run-time - dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH - dnl to prevent further configure tests to fail due to this - - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH2" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $DIR_SSH2 to CURL_LIBRARY_PATH]) - fi + dnl when the libssh2 shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH2" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_SSH2 to CURL_LIBRARY_PATH]) + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libssh2" else @@ -2296,26 +2312,26 @@ elif test X"$OPT_LIBSSH" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBSSH" in - yes) - dnl --with-libssh (without path) used - CURL_CHECK_PKGCONFIG(libssh) - - if test "$PKGCONFIG" != "no" ; then - LIB_SSH=`$PKGCONFIG --libs-only-l libssh` - LD_SSH=`$PKGCONFIG --libs-only-L libssh` - CPP_SSH=`$PKGCONFIG --cflags-only-I libssh` - version=`$PKGCONFIG --modversion libssh` - DIR_SSH=`echo $LD_SSH | $SED -e 's/^-L//'` - fi + yes) + dnl --with-libssh (without path) used + CURL_CHECK_PKGCONFIG(libssh) + + if test "$PKGCONFIG" != "no"; then + LIB_SSH=`$PKGCONFIG --libs-only-l libssh` + LD_SSH=`$PKGCONFIG --libs-only-L libssh` + CPP_SSH=`$PKGCONFIG --cflags-only-I libssh` + version=`$PKGCONFIG --modversion libssh` + DIR_SSH=`echo $LD_SSH | $SED -e 's/^-L//'` + fi - ;; - off) - dnl no --with-libssh option given, just check default places - ;; - *) - dnl use the given --with-libssh spot - PREFIX_SSH=$OPT_LIBSSH - ;; + ;; + off) + dnl no --with-libssh option given, just check default places + ;; + *) + dnl use the given --with-libssh spot + PREFIX_SSH=$OPT_LIBSSH + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -2345,16 +2361,20 @@ elif test X"$OPT_LIBSSH" != Xno; then fi if test "$LIBSSH_ENABLED" = "1"; then + if test "$curl_cv_native_windows" = "yes"; then + dnl for if_nametoindex + LIBS="-liphlpapi $LIBS" + fi if test -n "$DIR_SSH"; then - dnl when the libssh shared libs were found in a path that the run-time - dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH - dnl to prevent further configure tests to fail due to this - - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $DIR_SSH to CURL_LIBRARY_PATH]) - fi + dnl when the libssh shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_SSH" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_SSH to CURL_LIBRARY_PATH]) + fi fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libssh" else @@ -2369,11 +2389,10 @@ elif test X"$OPT_WOLFSSH" != Xno; then CLEANCPPFLAGS="$CPPFLAGS" CLEANLIBS="$LIBS" - if test "$OPT_WOLFSSH" != yes; then - WOLFCONFIG="$OPT_WOLFSSH/bin/wolfssh-config" - LDFLAGS="$LDFLAGS `$WOLFCONFIG --libs`" - CPPFLAGS="$CPPFLAGS `$WOLFCONFIG --cflags`" + WOLFCONFIG="$OPT_WOLFSSH/bin/wolfssh-config" + LDFLAGS="$LDFLAGS `$WOLFCONFIG --libs`" + CPPFLAGS="$CPPFLAGS `$WOLFCONFIG --cflags`" fi AC_CHECK_LIB(wolfssh, wolfSSH_Init) @@ -2384,7 +2403,6 @@ elif test X"$OPT_WOLFSSH" != Xno; then AC_DEFINE(USE_WOLFSSH, 1, [if wolfSSH is in use]) AC_SUBST(USE_WOLFSSH, [1]) ) - fi dnl ********************************************************************** @@ -2405,32 +2423,32 @@ if test X"$OPT_LIBRTMP" != Xno; then CLEANLIBS="$LIBS" case "$OPT_LIBRTMP" in - yes) - dnl --with-librtmp (without path) used - CURL_CHECK_PKGCONFIG(librtmp) - - if test "$PKGCONFIG" != "no" ; then - LIB_RTMP=`$PKGCONFIG --libs-only-l librtmp` - LD_RTMP=`$PKGCONFIG --libs-only-L librtmp` - CPP_RTMP=`$PKGCONFIG --cflags-only-I librtmp` - version=`$PKGCONFIG --modversion librtmp` - DIR_RTMP=`echo $LD_RTMP | $SED -e 's/^-L//'` - else - dnl To avoid link errors, we do not allow --librtmp without - dnl a pkgconfig file - AC_MSG_ERROR([--librtmp was specified but could not find librtmp pkgconfig file.]) - fi + yes) + dnl --with-librtmp (without path) used + CURL_CHECK_PKGCONFIG(librtmp) + + if test "$PKGCONFIG" != "no"; then + LIB_RTMP=`$PKGCONFIG --libs-only-l librtmp` + LD_RTMP=`$PKGCONFIG --libs-only-L librtmp` + CPP_RTMP=`$PKGCONFIG --cflags-only-I librtmp` + version=`$PKGCONFIG --modversion librtmp` + DIR_RTMP=`echo $LD_RTMP | $SED -e 's/^-L//'` + else + dnl To avoid link errors, we do not allow --librtmp without + dnl a pkgconfig file + AC_MSG_ERROR([--librtmp was specified but could not find librtmp pkgconfig file.]) + fi - ;; - off) - dnl no --with-librtmp option given, just check default places - LIB_RTMP="-lrtmp" - ;; - *) - dnl use the given --with-librtmp spot - LIB_RTMP="-lrtmp" - PREFIX_RTMP=$OPT_LIBRTMP - ;; + ;; + off) + dnl no --with-librtmp option given, just check default places + LIB_RTMP="-lrtmp" + ;; + *) + dnl use the given --with-librtmp spot + LIB_RTMP="-lrtmp" + PREFIX_RTMP=$OPT_LIBRTMP + ;; esac dnl if given with a prefix, we set -L and -I based on that @@ -2446,13 +2464,13 @@ if test X"$OPT_LIBRTMP" != Xno; then AC_CHECK_LIB(rtmp, RTMP_Init, [ - AC_CHECK_HEADERS(librtmp/rtmp.h, + AC_CHECK_HEADERS(librtmp/rtmp.h, curl_rtmp_msg="enabled (librtmp)" LIBRTMP_ENABLED=1 AC_DEFINE(USE_LIBRTMP, 1, [if librtmp is in use]) AC_SUBST(USE_LIBRTMP, [1]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE librtmp" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -2464,7 +2482,6 @@ if test X"$OPT_LIBRTMP" != Xno; then test "$LIBRTMP_ENABLED" != "1"; then AC_MSG_ERROR([librtmp libs and/or directories were not found where specified!]) fi - fi dnl ********************************************************************** @@ -2481,30 +2498,35 @@ AS_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shar AC_MSG_CHECKING([if libraries can be versioned]) GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` if test -z "$GLD"; then - AC_MSG_RESULT(no) - AC_MSG_WARN([You need an ld version supporting the --version-script option]) + AC_MSG_RESULT(no) + AC_MSG_WARN([You need an ld version supporting the --version-script option]) else - AC_MSG_RESULT(yes) - if test "x$CURL_WITH_MULTI_SSL" = "x1"; then - versioned_symbols_flavour="MULTISSL_" - elif test "x$OPENSSL_ENABLED" = "x1"; then - versioned_symbols_flavour="OPENSSL_" - elif test "x$GNUTLS_ENABLED" = "x1"; then - versioned_symbols_flavour="GNUTLS_" - elif test "x$WOLFSSL_ENABLED" = "x1"; then - versioned_symbols_flavour="WOLFSSL_" - elif test "x$SCHANNEL_ENABLED" = "x1"; then - versioned_symbols_flavour="SCHANNEL_" - elif test "x$SECURETRANSPORT_ENABLED" = "x1"; then - versioned_symbols_flavour="SECURE_TRANSPORT_" - else - versioned_symbols_flavour="" - fi - versioned_symbols="yes" + AC_MSG_RESULT(yes) + if test "x$CURL_WITH_MULTI_SSL" = "x1"; then + versioned_symbols_flavour="MULTISSL_" + elif test "x$OPENSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="OPENSSL_" + elif test "x$MBEDTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="MBEDTLS_" + elif test "x$BEARSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="BEARSSL_" + elif test "x$GNUTLS_ENABLED" = "x1"; then + versioned_symbols_flavour="GNUTLS_" + elif test "x$WOLFSSL_ENABLED" = "x1"; then + versioned_symbols_flavour="WOLFSSL_" + elif test "x$SCHANNEL_ENABLED" = "x1"; then + versioned_symbols_flavour="SCHANNEL_" + elif test "x$SECURETRANSPORT_ENABLED" = "x1"; then + versioned_symbols_flavour="SECURE_TRANSPORT_" + else + versioned_symbols_flavour="" + fi + versioned_symbols="yes" fi ;; - *) AC_MSG_RESULT(no) + *) + AC_MSG_RESULT(no) ;; esac ], [ @@ -2517,105 +2539,157 @@ AC_SUBST([CURL_LT_SHLIB_VERSIONED_FLAVOUR], AM_CONDITIONAL([CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS], [test "x$versioned_symbols" = 'xyes']) +dnl ---------------------------- +dnl check Windows Unicode option +dnl ---------------------------- + +want_winuni="no" +if test "$curl_cv_native_windows" = "yes"; then + AC_MSG_CHECKING([whether to enable Windows Unicode (Windows native builds only)]) + AC_ARG_ENABLE(windows-unicode, +AS_HELP_STRING([--enable-windows-unicode],[Enable Windows Unicode]) +AS_HELP_STRING([--disable-windows-unicode],[Disable Windows Unicode (default)]), + [ case "$enableval" in + yes) + CPPFLAGS="${CPPFLAGS} -DUNICODE -D_UNICODE" + want_winuni="yes" + AC_MSG_RESULT([yes]) + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac ], + AC_MSG_RESULT([no]) + ) +fi + +AM_CONDITIONAL([USE_UNICODE], [test "$want_winuni" = "yes"]) + dnl ------------------------------------------------- -dnl check winidn option before other IDN libraries +dnl check WinIDN option before other IDN libraries dnl ------------------------------------------------- -AC_MSG_CHECKING([whether to enable Windows native IDN (Windows native builds only)]) -OPT_WINIDN="default" -AC_ARG_WITH(winidn, +tst_links_winidn='no' +if test "$curl_cv_native_windows" = 'yes'; then + AC_MSG_CHECKING([whether to enable Windows native IDN (Windows native builds only)]) + OPT_WINIDN="default" + AC_ARG_WITH(winidn, AS_HELP_STRING([--with-winidn=PATH],[enable Windows native IDN]) AS_HELP_STRING([--without-winidn], [disable Windows native IDN]), - OPT_WINIDN=$withval) -case "$OPT_WINIDN" in - no|default) - dnl --without-winidn option used or configure option not specified - want_winidn="no" - AC_MSG_RESULT([no]) - ;; - yes) - dnl --with-winidn option used without path - want_winidn="yes" - want_winidn_path="default" - AC_MSG_RESULT([yes]) - ;; - *) - dnl --with-winidn option used with path - want_winidn="yes" - want_winidn_path="$withval" - AC_MSG_RESULT([yes ($withval)]) - ;; -esac + OPT_WINIDN=$withval) + case "$OPT_WINIDN" in + no|default) + dnl --without-winidn option used or configure option not specified + want_winidn="no" + AC_MSG_RESULT([no]) + ;; + yes) + dnl --with-winidn option used without path + want_winidn="yes" + want_winidn_path="default" + AC_MSG_RESULT([yes]) + ;; + *) + dnl --with-winidn option used with path + want_winidn="yes" + want_winidn_path="$withval" + AC_MSG_RESULT([yes ($withval)]) + ;; + esac -if test "$want_winidn" = "yes"; then - dnl winidn library support has been requested - clean_CFLAGS="$CFLAGS" - clean_CPPFLAGS="$CPPFLAGS" - clean_LDFLAGS="$LDFLAGS" - clean_LIBS="$LIBS" - WINIDN_LIBS="-lnormaliz" - WINIDN_CPPFLAGS="" - # - if test "$want_winidn_path" != "default"; then - dnl path has been specified - dnl pkg-config not available or provides no info - WINIDN_LDFLAGS="-L$want_winidn_path/lib$libsuff" - WINIDN_CPPFLAGS="-I$want_winidn_path/include" - WINIDN_DIR="$want_winidn_path/lib$libsuff" - fi - # - dnl WinIDN requires a minimum supported OS version of at least Vista (0x0600) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]],[[ - #if (WINVER < 0x600) && (_WIN32_WINNT < 0x600) - #error - #endif - ]]) - ],[ - ],[ - CFLAGS=`echo $CFLAGS | $SED -e 's/-DWINVER=[[^ ]]*//g'` - CFLAGS=`echo $CFLAGS | $SED -e 's/-D_WIN32_WINNT=[[^ ]]*//g'` - CPPFLAGS=`echo $CPPFLAGS | $SED -e 's/-DWINVER=[[^ ]]*//g'` - CPPFLAGS=`echo $CPPFLAGS | $SED -e 's/-D_WIN32_WINNT=[[^ ]]*//g'` - WINIDN_CPPFLAGS="$WINIDN_CPPFLAGS -DWINVER=0x0600" - ]) - # - CPPFLAGS="$CPPFLAGS $WINIDN_CPPFLAGS" - LDFLAGS="$LDFLAGS $WINIDN_LDFLAGS" - LIBS="$WINIDN_LIBS $LIBS" - # - AC_MSG_CHECKING([if IdnToUnicode can be linked]) - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]],[[ - IdnToUnicode(0, NULL, 0, NULL, 0); - ]]) - ],[ - AC_MSG_RESULT([yes]) - tst_links_winidn="yes" - ],[ - AC_MSG_RESULT([no]) - tst_links_winidn="no" - ]) - # - if test "$tst_links_winidn" = "yes"; then - AC_DEFINE(USE_WIN32_IDN, 1, [Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz).]) - AC_SUBST([IDN_ENABLED], [1]) - curl_idn_msg="enabled (Windows-native)" - else - AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) - CFLAGS="$clean_CFLAGS" - CPPFLAGS="$clean_CPPFLAGS" - LDFLAGS="$clean_LDFLAGS" - LIBS="$clean_LIBS" + if test "$want_winidn" = "yes"; then + dnl WinIDN library support has been requested + clean_CPPFLAGS="$CPPFLAGS" + clean_LDFLAGS="$LDFLAGS" + clean_LIBS="$LIBS" + WINIDN_LIBS="-lnormaliz" + WINIDN_CPPFLAGS="" + # + if test "$want_winidn_path" != "default"; then + dnl path has been specified + dnl pkg-config not available or provides no info + WINIDN_LDFLAGS="-L$want_winidn_path/lib$libsuff" + WINIDN_CPPFLAGS="-I$want_winidn_path/include" + fi + # + CPPFLAGS="$CPPFLAGS $WINIDN_CPPFLAGS" + LDFLAGS="$LDFLAGS $WINIDN_LDFLAGS" + LIBS="$WINIDN_LIBS $LIBS" + # + AC_MSG_CHECKING([if IdnToUnicode can be linked]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #include + ]],[[ + #if (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600) && \ + (!defined(WINVER) || WINVER < 0x600) + WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, + const WCHAR *lpASCIICharStr, + int cchASCIIChar, + WCHAR *lpUnicodeCharStr, + int cchUnicodeChar); + #endif + IdnToUnicode(0, NULL, 0, NULL, 0); + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_winidn="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_winidn="no" + ]) + # + if test "$tst_links_winidn" = "yes"; then + AC_DEFINE(USE_WIN32_IDN, 1, [Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz).]) + AC_SUBST([IDN_ENABLED], [1]) + curl_idn_msg="enabled (Windows-native)" + else + AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) + CPPFLAGS="$clean_CPPFLAGS" + LDFLAGS="$clean_LDFLAGS" + LIBS="$clean_LIBS" + fi fi fi dnl ********************************************************************** -dnl Check for the presence of IDN libraries and headers +dnl Check for the presence of AppleIDN +dnl ********************************************************************** + +tst_links_appleidn='no' +case $host_os in + darwin*) + AC_MSG_CHECKING([whether to build with Apple IDN]) + OPT_IDN="default" + AC_ARG_WITH(apple-idn, +AS_HELP_STRING([--with-apple-idn],[Enable AppleIDN]) +AS_HELP_STRING([--without-apple-idn],[Disable AppleIDN]), + [OPT_IDN=$withval]) + case "$OPT_IDN" in + yes) + dnl --with-apple-idn option used + AC_MSG_RESULT([yes, check]) + AC_CHECK_LIB(icucore, uidna_openUTS46, + [ + AC_CHECK_HEADERS(unicode/uidna.h, + curl_idn_msg="enabled (AppleIDN)" + AC_DEFINE(USE_APPLE_IDN, 1, [if AppleIDN]) + AC_SUBST(USE_APPLE_IDN, [1]) + AC_SUBST([IDN_ENABLED], [1]) + LIBS="-licucore -liconv $LIBS" + tst_links_appleidn='yes' + ) + ]) + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac + ;; +esac + +dnl ********************************************************************** +dnl Check for the presence of libidn2 dnl ********************************************************************** AC_MSG_CHECKING([whether to build with libidn2]) @@ -2626,7 +2700,10 @@ AS_HELP_STRING([--without-libidn2],[Disable libidn2 usage]), [OPT_IDN=$withval]) if test "x$tst_links_winidn" = "xyes"; then want_idn="no" - AC_MSG_RESULT([no (using winidn instead)]) + AC_MSG_RESULT([no (using WinIDN instead)]) +elif test "x$tst_links_appleidn" = "xyes"; then + want_idn="no" + AC_MSG_RESULT([no (using AppleIDN instead)]) else case "$OPT_IDN" in no) @@ -2737,10 +2814,11 @@ if test "$want_idn" = "yes"; then fi LIBCURL_PC_REQUIRES_PRIVATE="libidn2 $LIBCURL_PC_REQUIRES_PRIVATE" else - AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) + AC_MSG_WARN([Cannot find libidn2]) CPPFLAGS="$clean_CPPFLAGS" LDFLAGS="$clean_LDFLAGS" LIBS="$clean_LIBS" + want_idn="no" fi fi @@ -2786,7 +2864,7 @@ if test X"$want_nghttp2" != Xno; then CURL_CHECK_PKGCONFIG(libnghttp2, $want_nghttp2_pkg_config_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_H2=`CURL_EXPORT_PCDIR([$want_nghttp2_pkg_config_path]) $PKGCONFIG --libs-only-l libnghttp2` AC_MSG_NOTICE([-l is $LIB_H2]) @@ -2821,17 +2899,17 @@ if test X"$want_nghttp2" != Xno; then # >= 1.15.0 AC_CHECK_LIB(nghttp2, nghttp2_session_get_stream_local_window_size, [ - AC_CHECK_HEADERS(nghttp2/nghttp2.h, + AC_CHECK_HEADERS(nghttp2/nghttp2.h, curl_h2_msg="enabled (nghttp2)" NGHTTP2_ENABLED=1 AC_DEFINE(USE_NGHTTP2, 1, [if nghttp2 is in use]) AC_SUBST(USE_NGHTTP2, [1]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libnghttp2" - ) + ) - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_H2" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $DIR_H2 to CURL_LIBRARY_PATH]) + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_H2" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_H2 to CURL_LIBRARY_PATH]) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -2886,7 +2964,7 @@ if test X"$want_tcp2" != Xno; then CURL_CHECK_PKGCONFIG(libngtcp2, $want_tcp2_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_TCP2=`CURL_EXPORT_PCDIR([$want_tcp2_path]) $PKGCONFIG --libs-only-l libngtcp2` AC_MSG_NOTICE([-l is $LIB_TCP2]) @@ -2908,7 +2986,7 @@ if test X"$want_tcp2" != Xno; then fi AC_CHECK_LIB(ngtcp2, ngtcp2_conn_client_new_versioned, [ - AC_CHECK_HEADERS(ngtcp2/ngtcp2.h, + AC_CHECK_HEADERS(ngtcp2/ngtcp2.h, NGTCP2_ENABLED=1 AC_DEFINE(USE_NGTCP2, 1, [if ngtcp2 is in use]) AC_SUBST(USE_NGTCP2, [1]) @@ -2916,7 +2994,7 @@ if test X"$want_tcp2" != Xno; then export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_TCP2 to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -2932,7 +3010,6 @@ if test X"$want_tcp2" != Xno; then AC_MSG_ERROR([--with-ngtcp2 was specified but could not find ngtcp2 pkg-config file.]) fi fi - fi if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS_BORINGSSL" != "x1"; then @@ -2943,7 +3020,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS CURL_CHECK_PKGCONFIG(libngtcp2_crypto_quictls, $want_tcp2_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_QUICTLS=`CURL_EXPORT_PCDIR([$want_tcp2_path]) $PKGCONFIG --libs-only-l libngtcp2_crypto_quictls` AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_QUICTLS]) @@ -2965,7 +3042,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS fi AC_CHECK_LIB(ngtcp2_crypto_quictls, ngtcp2_crypto_recv_client_initial_cb, [ - AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, + AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, NGTCP2_ENABLED=1 AC_DEFINE(USE_NGTCP2_CRYPTO_QUICTLS, 1, [if ngtcp2_crypto_quictls is in use]) AC_SUBST(USE_NGTCP2_CRYPTO_QUICTLS, [1]) @@ -2973,7 +3050,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_QUICTLS to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_quictls" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -2999,7 +3076,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS CURL_CHECK_PKGCONFIG(libngtcp2_crypto_boringssl, $want_tcp2_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_BORINGSSL=`CURL_EXPORT_PCDIR([$want_tcp2_path]) $PKGCONFIG --libs-only-l libngtcp2_crypto_boringssl` AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_BORINGSSL]) @@ -3021,7 +3098,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS fi AC_CHECK_LIB(ngtcp2_crypto_boringssl, ngtcp2_crypto_recv_client_initial_cb, [ - AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, + AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, NGTCP2_ENABLED=1 AC_DEFINE(USE_NGTCP2_CRYPTO_BORINGSSL, 1, [if ngtcp2_crypto_boringssl is in use]) AC_SUBST(USE_NGTCP2_CRYPTO_BORINGSSL, [1]) @@ -3029,7 +3106,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$OPENSSL_ENABLED" = "x1" -a "x$OPENSSL_IS export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_BORINGSSL to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_boringssl" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -3055,7 +3132,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$GNUTLS_ENABLED" = "x1"; then CURL_CHECK_PKGCONFIG(libngtcp2_crypto_gnutls, $want_tcp2_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_GNUTLS=`CURL_EXPORT_PCDIR([$want_tcp2_path]) $PKGCONFIG --libs-only-l libngtcp2_crypto_gnutls` AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_GNUTLS]) @@ -3077,7 +3154,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$GNUTLS_ENABLED" = "x1"; then fi AC_CHECK_LIB(ngtcp2_crypto_gnutls, ngtcp2_crypto_recv_client_initial_cb, [ - AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, + AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, NGTCP2_ENABLED=1 AC_DEFINE(USE_NGTCP2_CRYPTO_GNUTLS, 1, [if ngtcp2_crypto_gnutls is in use]) AC_SUBST(USE_NGTCP2_CRYPTO_GNUTLS, [1]) @@ -3085,7 +3162,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$GNUTLS_ENABLED" = "x1"; then export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_GNUTLS to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_gnutls" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -3111,7 +3188,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$WOLFSSL_ENABLED" = "x1"; then CURL_CHECK_PKGCONFIG(libngtcp2_crypto_wolfssl, $want_tcp2_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGTCP2_CRYPTO_WOLFSSL=`CURL_EXPORT_PCDIR([$want_tcp2_path]) $PKGCONFIG --libs-only-l libngtcp2_crypto_wolfssl` AC_MSG_NOTICE([-l is $LIB_NGTCP2_CRYPTO_WOLFSSL]) @@ -3133,7 +3210,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$WOLFSSL_ENABLED" = "x1"; then fi AC_CHECK_LIB(ngtcp2_crypto_wolfssl, ngtcp2_crypto_recv_client_initial_cb, [ - AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, + AC_CHECK_HEADERS(ngtcp2/ngtcp2_crypto.h, NGTCP2_ENABLED=1 AC_DEFINE(USE_NGTCP2_CRYPTO_WOLFSSL, 1, [if ngtcp2_crypto_wolfssl is in use]) AC_SUBST(USE_NGTCP2_CRYPTO_WOLFSSL, [1]) @@ -3141,7 +3218,7 @@ if test "x$NGTCP2_ENABLED" = "x1" -a "x$WOLFSSL_ENABLED" = "x1"; then export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGTCP2_CRYPTO_WOLFSSL to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libngtcp2_crypto_wolfssl" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -3191,7 +3268,7 @@ if test "x$want_openssl_quic" = "xyes"; then if test "$NGTCP2_ENABLED" = 1; then AC_MSG_ERROR([--with-openssl-quic and --with-ngtcp2 are mutually exclusive]) fi - if test "$HAVE_OPENSSL_QUIC" != 1; then + if test "$have_openssl_quic" != 1; then AC_MSG_ERROR([--with-openssl-quic requires quic support and OpenSSL >= 3.3.0]) fi AC_DEFINE(USE_OPENSSL_QUIC, 1, [if openssl QUIC is in use]) @@ -3246,7 +3323,7 @@ if test X"$want_nghttp3" != Xno; then CURL_CHECK_PKGCONFIG(libnghttp3, $want_nghttp3_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_NGHTTP3=`CURL_EXPORT_PCDIR([$want_nghttp3_path]) $PKGCONFIG --libs-only-l libnghttp3` AC_MSG_NOTICE([-l is $LIB_NGHTTP3]) @@ -3268,14 +3345,14 @@ if test X"$want_nghttp3" != Xno; then fi AC_CHECK_LIB(nghttp3, nghttp3_conn_client_new_versioned, [ - AC_CHECK_HEADERS(nghttp3/nghttp3.h, + AC_CHECK_HEADERS(nghttp3/nghttp3.h, AC_DEFINE(USE_NGHTTP3, 1, [if nghttp3 is in use]) AC_SUBST(USE_NGHTTP3, [1]) CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGHTTP3" export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGHTTP3 to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libnghttp3" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -3291,7 +3368,6 @@ if test X"$want_nghttp3" != Xno; then AC_MSG_ERROR([--with-nghttp3 was specified but could not find nghttp3 pkg-config file.]) fi fi - fi dnl ********************************************************************** @@ -3366,7 +3442,7 @@ if test X"$want_quiche" != Xno; then CURL_CHECK_PKGCONFIG(quiche, $want_quiche_path) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then LIB_QUICHE=`CURL_EXPORT_PCDIR([$want_quiche_path]) $PKGCONFIG --libs-only-l quiche` AC_MSG_NOTICE([-l is $LIB_QUICHE]) @@ -3388,7 +3464,7 @@ if test X"$want_quiche" != Xno; then fi AC_CHECK_LIB(quiche, quiche_conn_send_ack_eliciting, [ - AC_CHECK_HEADERS(quiche.h, + AC_CHECK_HEADERS(quiche.h, experimental="$experimental HTTP3" AC_MSG_NOTICE([HTTP3 support is experimental]) curl_h3_msg="enabled (quiche)" @@ -3405,7 +3481,7 @@ if test X"$want_quiche" != Xno; then AC_INCLUDES_DEFAULT #include ] - ) + ) ], dnl not found, revert back to clean variables AC_MSG_ERROR([couldn't use quiche]) @@ -3487,7 +3563,7 @@ if test X"$want_msh3" != Xno; then AC_CHECK_LIB(msh3, MsH3ApiOpen, [ - AC_CHECK_HEADERS(msh3.h, + AC_CHECK_HEADERS(msh3.h, curl_h3_msg="enabled (msh3)" MSH3_ENABLED=1 AC_DEFINE(USE_MSH3, 1, [if msh3 is in use]) @@ -3497,7 +3573,7 @@ if test X"$want_msh3" != Xno; then AC_MSG_NOTICE([Added $DIR_MSH3 to CURL_LIBRARY_PATH]) LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libmsh3" experimental="$experimental HTTP3" - ) + ) ], dnl not found, revert back to clean variables LDFLAGS=$CLEANLDFLAGS @@ -3506,6 +3582,93 @@ if test X"$want_msh3" != Xno; then ) fi +dnl ********************************************************************** +dnl libuv is only ever used for debug purposes +dnl ********************************************************************** + +OPT_LIBUV=no +AC_ARG_WITH(libuv, +AS_HELP_STRING([--with-libuv=PATH],[Enable libuv]) +AS_HELP_STRING([--without-libuv],[Disable libuv]), + [OPT_LIBUV=$withval]) +case "$OPT_LIBUV" in + no) + dnl --without-libuv option used + want_libuv="no" + ;; + yes) + dnl --with-libuv option used without path + want_libuv="default" + want_libuv_path="" + ;; + *) + dnl --with-libuv option used with path + want_libuv="yes" + want_libuv_path="$withval" + ;; +esac + +if test X"$want_libuv" != Xno; then + if test x$want_debug != xyes; then + AC_MSG_ERROR([Using libuv without debug support enabled is useless]) + fi + + dnl backup the pre-libuv variables + CLEANLDFLAGS="$LDFLAGS" + CLEANCPPFLAGS="$CPPFLAGS" + CLEANLIBS="$LIBS" + + CURL_CHECK_PKGCONFIG(libuv, $want_libuv_path) + + if test "$PKGCONFIG" != "no"; then + LIB_LIBUV=`CURL_EXPORT_PCDIR([$want_libuv_path]) + $PKGCONFIG --libs-only-l libuv` + AC_MSG_NOTICE([-l is $LIB_LIBUV]) + + CPP_LIBUV=`CURL_EXPORT_PCDIR([$want_libuv_path]) dnl + $PKGCONFIG --cflags-only-I libuv` + AC_MSG_NOTICE([-I is $CPP_LIBUV]) + + LD_LIBUV=`CURL_EXPORT_PCDIR([$want_libuv_path]) + $PKGCONFIG --libs-only-L libuv` + AC_MSG_NOTICE([-L is $LD_LIBUV]) + + LDFLAGS="$LDFLAGS $LD_LIBUV" + CPPFLAGS="$CPPFLAGS $CPP_LIBUV" + LIBS="$LIB_LIBUV $LIBS" + + if test "x$cross_compiling" != "xyes"; then + DIR_LIBUV=`echo $LD_LIBUV | $SED -e 's/^-L//'` + fi + AC_CHECK_LIB(uv, uv_default_loop, + [ + AC_CHECK_HEADERS(uv.h, + LIBUV_ENABLED=1 + AC_DEFINE(USE_LIBUV, 1, [if libuv is in use]) + AC_SUBST(USE_LIBUV, [1]) + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_LIBUV" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $DIR_LIBUV to CURL_LIBRARY_PATH]) + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE libuv" + ) + ], + dnl not found, revert back to clean variables + LDFLAGS=$CLEANLDFLAGS + CPPFLAGS=$CLEANCPPFLAGS + LIBS=$CLEANLIBS + ) + + else + dnl no libuv pkg-config found, deal with it + if test X"$want_libuv" != Xdefault; then + dnl To avoid link errors, we do not allow --with-libuv without + dnl a pkgconfig file + AC_MSG_ERROR([--with-libuv was specified but could not find libuv pkg-config file.]) + fi + fi + +fi + dnl ********************************************************************** dnl Check for zsh completion path dnl ********************************************************************** @@ -3548,7 +3711,7 @@ case "$OPT_FISH_FPATH" in yes) dnl --with-fish-functions-dir option used without path CURL_CHECK_PKGCONFIG(fish) - if test "$PKGCONFIG" != "no" ; then + if test "$PKGCONFIG" != "no"; then FISH_FUNCTIONS_DIR=`$PKGCONFIG --variable completionsdir fish` else FISH_FUNCTIONS_DIR="$datarootdir/fish/vendor_completions.d" @@ -3566,43 +3729,43 @@ AM_CONDITIONAL(USE_FISH_COMPLETION, test x"$FISH_FUNCTIONS_DIR" != x) dnl Now check for the very most basic headers. Then we can use these dnl ones as default-headers when checking for the rest! AC_CHECK_HEADERS( - sys/types.h \ - sys/time.h \ - sys/select.h \ - sys/socket.h \ - sys/ioctl.h \ - unistd.h \ - stdlib.h \ - arpa/inet.h \ - net/if.h \ - netinet/in.h \ - netinet/in6.h \ - sys/un.h \ - linux/tcp.h \ - netinet/tcp.h \ - netinet/udp.h \ - netdb.h \ - sys/sockio.h \ - sys/stat.h \ - sys/param.h \ - termios.h \ - termio.h \ - fcntl.h \ - io.h \ - pwd.h \ - utime.h \ - sys/utime.h \ - sys/poll.h \ - poll.h \ - socket.h \ - sys/resource.h \ - libgen.h \ - locale.h \ - stdbool.h \ - sys/filio.h \ - sys/wait.h \ - sys/eventfd.h \ - setjmp.h, + sys/types.h \ + sys/time.h \ + sys/select.h \ + sys/socket.h \ + sys/ioctl.h \ + unistd.h \ + stdlib.h \ + arpa/inet.h \ + net/if.h \ + netinet/in.h \ + netinet/in6.h \ + sys/un.h \ + linux/tcp.h \ + netinet/tcp.h \ + netinet/udp.h \ + netdb.h \ + sys/sockio.h \ + sys/stat.h \ + sys/param.h \ + termios.h \ + termio.h \ + fcntl.h \ + io.h \ + pwd.h \ + utime.h \ + sys/utime.h \ + sys/poll.h \ + poll.h \ + socket.h \ + sys/resource.h \ + libgen.h \ + locale.h \ + stdbool.h \ + sys/filio.h \ + sys/wait.h \ + sys/eventfd.h \ + setjmp.h, dnl to do if not found [], dnl to do if found @@ -3660,9 +3823,9 @@ CURL_SIZEOF(curl_socket_t, [ CPPFLAGS=$o AC_CHECK_TYPE(long long, - [AC_DEFINE(HAVE_LONGLONG, 1, - [Define to 1 if the compiler supports the 'long long' data type.])] - longlong="yes" + [AC_DEFINE(HAVE_LONGLONG, 1, + [Define to 1 if the compiler supports the 'long long' data type.])] + longlong="yes" ) if test ${ac_cv_sizeof_curl_off_t} -lt 8; then @@ -3671,7 +3834,7 @@ fi # check for ssize_t AC_CHECK_TYPE(ssize_t, , - AC_DEFINE(ssize_t, int, [the signed version of size_t])) + AC_DEFINE(ssize_t, int, [the signed version of size_t])) # check for bool type AC_CHECK_TYPE([bool],[ @@ -3688,12 +3851,12 @@ AC_CHECK_TYPE([bool],[ # check for sa_family_t AC_CHECK_TYPE(sa_family_t, - AC_DEFINE(CURL_SA_FAMILY_T, sa_family_t, [IP address type in sockaddr]), - [ - # The windows name? - AC_CHECK_TYPE(ADDRESS_FAMILY, - AC_DEFINE(CURL_SA_FAMILY_T, ADDRESS_FAMILY, [IP address type in sockaddr]), - AC_DEFINE(CURL_SA_FAMILY_T, unsigned short, [IP address type in sockaddr]), + AC_DEFINE(CURL_SA_FAMILY_T, sa_family_t, [IP address type in sockaddr]), + [ + # The Windows name? + AC_CHECK_TYPE(ADDRESS_FAMILY, + AC_DEFINE(CURL_SA_FAMILY_T, ADDRESS_FAMILY, [IP address type in sockaddr]), + AC_DEFINE(CURL_SA_FAMILY_T, unsigned short, [IP address type in sockaddr]), [ #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN @@ -3705,7 +3868,7 @@ AC_CHECK_TYPE(sa_family_t, #include #endif ]) - ], + ], [ #ifdef HAVE_SYS_SOCKET_H #include @@ -3794,9 +3957,9 @@ CURL_CHECK_FUNC_STRTOLL case $host in *msdosdjgpp) - ac_cv_func_pipe=no - skipcheck_pipe=yes - AC_MSG_NOTICE([skip check for pipe on msdosdjgpp]) + ac_cv_func_pipe=no + skipcheck_pipe=yes + AC_MSG_NOTICE([skip check for pipe on msdosdjgpp]) ;; esac @@ -3809,7 +3972,6 @@ AC_CHECK_FUNCS([\ arc4random \ eventfd \ fnmatch \ - fseeko \ geteuid \ getpass_r \ getppid \ @@ -3830,24 +3992,28 @@ AC_CHECK_FUNCS([\ utimes \ ]) -dnl On Android, the only way to know if fseeko can be used is to see if it is -dnl declared or not (for this API level), as the symbol always exists in the -dnl lib. -AC_CHECK_DECL([fseeko], - [AC_DEFINE([HAVE_DECL_FSEEKO], [1], - [Define to 1 if you have the fseeko declaration])], - [], - [[#include ]]) +if test "$curl_cv_native_windows" != 'yes'; then + AC_CHECK_FUNCS([fseeko]) + + dnl On Android, the only way to know if fseeko can be used is to see if it is + dnl declared or not (for this API level), as the symbol always exists in the + dnl lib. + AC_CHECK_DECL([fseeko], + [AC_DEFINE([HAVE_DECL_FSEEKO], [1], + [Define to 1 if you have the fseeko declaration])], + [], + [[#include ]]) +fi CURL_CHECK_NONBLOCKING_SOCKET -if test "x$BUILD_DOCS" != "x0" -o "x$USE_MANUAL" != "x0"; then +if test "x$BUILD_DOCS" != "x0" -o "x$USE_MANUAL" != "x0" -o "x$CURL_CA_EMBED" != "x"; then AC_PATH_PROG( PERL, perl, , $PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin ) AC_SUBST(PERL) if test -z "$PERL"; then - AC_MSG_ERROR([perl was not found, needed for docs and manual]) + AC_MSG_ERROR([perl was not found, needed for docs, manual and CA embed]) fi fi @@ -3859,7 +4025,6 @@ dnl If the manual variable still is set, then we go with providing a built-in dnl manual if test "$USE_MANUAL" = "1"; then - AC_DEFINE(USE_MANUAL, 1, [If you want to build curl with the built-in manual]) curl_manual_msg="enabled" fi @@ -3868,14 +4033,6 @@ AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1) CURL_CHECK_LIB_ARES -if test "x$curl_cv_native_windows" != "xyes" && - test "x$enable_shared" = "xyes"; then - build_libhostname=yes -else - build_libhostname=no -fi -AM_CONDITIONAL(BUILD_LIBHOSTNAME, test x$build_libhostname = xyes) - if test "x$want_ares" != xyes; then CURL_CHECK_OPTION_THREADED_RESOLVER @@ -3890,19 +4047,36 @@ dnl AC_MSG_CHECKING([whether to use POSIX threads for threaded resolver]) AC_ARG_ENABLE(pthreads, AS_HELP_STRING([--enable-pthreads], - [Enable POSIX threads (default for threaded resolver)]) + [Enable POSIX threads (default for threaded resolver)]) AS_HELP_STRING([--disable-pthreads],[Disable POSIX threads]), [ case "$enableval" in - no) AC_MSG_RESULT(no) - want_pthreads=no - ;; - *) AC_MSG_RESULT(yes) - want_pthreads=yes - ;; + no) + AC_MSG_RESULT(no) + want_pthreads=no + ;; + *) + AC_MSG_RESULT(yes) + want_pthreads=yes + ;; esac ], [ - AC_MSG_RESULT(auto) - want_pthreads=auto - ] + default_pthreads=1 + if test "$curl_cv_native_windows" = "yes"; then + default_pthreads=0 + else + case $host_os in + msdos*) + default_pthreads=0 + ;; + esac + fi + if test "$default_pthreads" = '0'; then + AC_MSG_RESULT(no) + want_pthreads=no + else + AC_MSG_RESULT(auto) + want_pthreads=auto + fi + ] ) dnl turn off pthreads if rt is disabled @@ -3941,47 +4115,45 @@ if test "$want_pthreads" != "no"; then AC_CHECK_FUNC(pthread_create, [USE_THREADS_POSIX=1] ) LIBS="$save_LIBS" - dnl on HPUX, life is more complicated... + dnl on HP-UX, life is more complicated... case $host in - *-hp-hpux*) - dnl it doesn't actually work without -lpthread - USE_THREADS_POSIX="" - ;; - *) - ;; + *-hp-hpux*) + dnl it doesn't actually work without -lpthread + USE_THREADS_POSIX="" + ;; + *) + ;; esac dnl if it wasn't found without lib, search for it in pthread lib - if test "$USE_THREADS_POSIX" != "1" - then + if test "$USE_THREADS_POSIX" != "1"; then # assign PTHREAD for pkg-config use PTHREAD=" -pthread" case $host in - *-ibm-aix*) - dnl Check if compiler is xlC - COMPILER_VERSION=`"$CC" -qversion 2>/dev/null` - if test x"$COMPILER_VERSION" = "x"; then - CFLAGS="$CFLAGS -pthread" - else - CFLAGS="$CFLAGS -qthreaded" - fi - ;; - powerpc-*amigaos*) - dnl No -pthread option, but link with -lpthread - PTHREAD=" -lpthread" - ;; - *) - CFLAGS="$CFLAGS -pthread" - ;; + *-ibm-aix*) + dnl Check if compiler is xlC + COMPILER_VERSION=`"$CC" -qversion 2>/dev/null` + if test x"$COMPILER_VERSION" = "x"; then + CFLAGS="$CFLAGS -pthread" + else + CFLAGS="$CFLAGS -qthreaded" + fi + ;; + powerpc-*amigaos*) + dnl No -pthread option, but link with -lpthread + PTHREAD=" -lpthread" + ;; + *) + CFLAGS="$CFLAGS -pthread" + ;; esac AC_CHECK_LIB(pthread, pthread_create, [USE_THREADS_POSIX=1], [ CFLAGS="$save_CFLAGS"]) fi - if test "x$USE_THREADS_POSIX" = "x1" - then + if test "x$USE_THREADS_POSIX" = "x1"; then AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup]) curl_res_msg="POSIX threaded" fi @@ -4020,14 +4192,15 @@ AS_HELP_STRING([--enable-verbose],[Enable verbose strings]) AS_HELP_STRING([--disable-verbose],[Disable verbose strings]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_VERBOSE_STRINGS, 1, [to disable verbose strings]) - curl_verbose_msg="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_VERBOSE_STRINGS, 1, [to disable verbose strings]) + curl_verbose_msg="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4039,31 +4212,31 @@ AS_HELP_STRING([--enable-sspi],[Enable SSPI]) AS_HELP_STRING([--disable-sspi],[Disable SSPI]), [ case "$enableval" in yes) - if test "$curl_cv_native_windows" = "yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support]) - AC_SUBST(USE_WINDOWS_SSPI, [1]) - curl_sspi_msg="enabled" - else - AC_MSG_RESULT(no) - AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.]) - fi - ;; + if test "$curl_cv_native_windows" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support]) + AC_SUBST(USE_WINDOWS_SSPI, [1]) + curl_sspi_msg="enabled" + else + AC_MSG_RESULT(no) + AC_MSG_WARN([--enable-sspi Ignored. Only supported on native Windows builds.]) + fi + ;; *) - if test "x$SCHANNEL_ENABLED" = "x1"; then - # --with-schannel implies --enable-sspi - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - ;; + if test "x$SCHANNEL_ENABLED" = "x1"; then + # --with-schannel implies --enable-sspi + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + ;; esac ], - if test "x$SCHANNEL_ENABLED" = "x1"; then - # --with-schannel implies --enable-sspi - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi + if test "x$SCHANNEL_ENABLED" = "x1"; then + # --with-schannel implies --enable-sspi + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi ) dnl ************************************************************ @@ -4075,14 +4248,15 @@ AS_HELP_STRING([--enable-basic-auth],[Enable basic authentication (default)]) AS_HELP_STRING([--disable-basic-auth],[Disable basic authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_BASIC_AUTH, 1, [to disable basic authentication]) - CURL_DISABLE_BASIC_AUTH=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_BASIC_AUTH, 1, [to disable basic authentication]) + CURL_DISABLE_BASIC_AUTH=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4094,14 +4268,15 @@ AS_HELP_STRING([--enable-bearer-auth],[Enable bearer authentication (default)]) AS_HELP_STRING([--disable-bearer-auth],[Disable bearer authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_BEARER_AUTH, 1, [to disable bearer authentication]) - CURL_DISABLE_BEARER_AUTH=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_BEARER_AUTH, 1, [to disable bearer authentication]) + CURL_DISABLE_BEARER_AUTH=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4113,14 +4288,15 @@ AS_HELP_STRING([--enable-digest-auth],[Enable digest authentication (default)]) AS_HELP_STRING([--disable-digest-auth],[Disable digest authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_DIGEST_AUTH, 1, [to disable digest authentication]) - CURL_DISABLE_DIGEST_AUTH=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_DIGEST_AUTH, 1, [to disable digest authentication]) + CURL_DISABLE_DIGEST_AUTH=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4132,14 +4308,15 @@ AS_HELP_STRING([--enable-kerberos-auth],[Enable kerberos authentication (default AS_HELP_STRING([--disable-kerberos-auth],[Disable kerberos authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_KERBEROS_AUTH, 1, [to disable kerberos authentication]) - CURL_DISABLE_KERBEROS_AUTH=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_KERBEROS_AUTH, 1, [to disable kerberos authentication]) + CURL_DISABLE_KERBEROS_AUTH=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4151,17 +4328,17 @@ AS_HELP_STRING([--enable-negotiate-auth],[Enable negotiate authentication (defau AS_HELP_STRING([--disable-negotiate-auth],[Disable negotiate authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_NEGOTIATE_AUTH, 1, [to disable negotiate authentication]) - CURL_DISABLE_NEGOTIATE_AUTH=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_NEGOTIATE_AUTH, 1, [to disable negotiate authentication]) + CURL_DISABLE_NEGOTIATE_AUTH=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) - dnl ************************************************************ dnl disable aws dnl @@ -4171,14 +4348,15 @@ AS_HELP_STRING([--enable-aws],[Enable AWS sig support (default)]) AS_HELP_STRING([--disable-aws],[Disable AWS sig support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_AWS, 1, [to disable AWS sig support]) - CURL_DISABLE_AWS=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_AWS, 1, [to disable AWS sig support]) + CURL_DISABLE_AWS=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4190,14 +4368,15 @@ AS_HELP_STRING([--enable-ntlm],[Enable NTLM support]) AS_HELP_STRING([--disable-ntlm],[Disable NTLM support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_NTLM, 1, [to disable NTLM support]) - CURL_DISABLE_NTLM=1 - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_NTLM, 1, [to disable NTLM support]) + CURL_DISABLE_NTLM=1 + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4209,21 +4388,22 @@ AS_HELP_STRING([--enable-tls-srp],[Enable TLS-SRP authentication]) AS_HELP_STRING([--disable-tls-srp],[Disable TLS-SRP authentication]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - want_tls_srp=no - ;; - *) AC_MSG_RESULT(yes) - want_tls_srp=yes - ;; + AC_MSG_RESULT(no) + want_tls_srp=no + ;; + *) + AC_MSG_RESULT(yes) + want_tls_srp=yes + ;; esac ], - AC_MSG_RESULT(yes) - want_tls_srp=yes + AC_MSG_RESULT(yes) + want_tls_srp=yes ) -if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$HAVE_OPENSSL_SRP" = "x1") ; then - AC_DEFINE(USE_TLS_SRP, 1, [Use TLS-SRP authentication]) - USE_TLS_SRP=1 - curl_tls_srp_msg="enabled" +if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$HAVE_OPENSSL_SRP" = "x1"); then + AC_DEFINE(USE_TLS_SRP, 1, [Use TLS-SRP authentication]) + USE_TLS_SRP=1 + curl_tls_srp_msg="enabled" fi dnl ************************************************************ @@ -4234,16 +4414,18 @@ AC_ARG_ENABLE(unix-sockets, AS_HELP_STRING([--enable-unix-sockets],[Enable Unix domain sockets]) AS_HELP_STRING([--disable-unix-sockets],[Disable Unix domain sockets]), [ case "$enableval" in - no) AC_MSG_RESULT(no) - want_unix_sockets=no - ;; - *) AC_MSG_RESULT(yes) - want_unix_sockets=yes - ;; + no) + AC_MSG_RESULT(no) + want_unix_sockets=no + ;; + *) + AC_MSG_RESULT(yes) + want_unix_sockets=yes + ;; esac ], [ - AC_MSG_RESULT(auto) - want_unix_sockets=auto - ] + AC_MSG_RESULT(auto) + want_unix_sockets=auto + ] ) if test "x$want_unix_sockets" != "xno"; then if test "x$curl_cv_native_windows" = "xyes"; then @@ -4274,13 +4456,14 @@ AS_HELP_STRING([--enable-cookies],[Enable cookies support]) AS_HELP_STRING([--disable-cookies],[Disable cookies support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_COOKIES, 1, [to disable cookies support]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_COOKIES, 1, [to disable cookies support]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4292,13 +4475,14 @@ AS_HELP_STRING([--enable-socketpair],[Enable socketpair support]) AS_HELP_STRING([--disable-socketpair],[Disable socketpair support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_SOCKETPAIR, 1, [to disable socketpair support]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SOCKETPAIR, 1, [to disable socketpair support]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4310,13 +4494,14 @@ AS_HELP_STRING([--enable-http-auth],[Enable HTTP authentication support]) AS_HELP_STRING([--disable-http-auth],[Disable HTTP authentication support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_HTTP_AUTH, 1, [disable HTTP authentication]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_HTTP_AUTH, 1, [disable HTTP authentication]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4328,13 +4513,14 @@ AS_HELP_STRING([--enable-doh],[Enable DoH support]) AS_HELP_STRING([--disable-doh],[Disable DoH support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_DOH, 1, [disable DoH]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_DOH, 1, [disable DoH]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4346,13 +4532,14 @@ AS_HELP_STRING([--enable-mime],[Enable mime API support]) AS_HELP_STRING([--disable-mime],[Disable mime API support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_MIME, 1, [disable mime API]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_MIME, 1, [disable mime API]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4364,13 +4551,14 @@ AS_HELP_STRING([--enable-bindlocal],[Enable local binding support]) AS_HELP_STRING([--disable-bindlocal],[Disable local binding support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_BINDLOCAL, 1, [disable local binding support]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_BINDLOCAL, 1, [disable local binding support]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4381,13 +4569,15 @@ AC_ARG_ENABLE(form-api, AS_HELP_STRING([--enable-form-api],[Enable form API support]) AS_HELP_STRING([--disable-form-api],[Disable form API support]), [ case "$enableval" in - no) AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_FORM_API, 1, [disable form API]) - ;; - *) AC_MSG_RESULT(yes) - test "$enable_mime" = no && - AC_MSG_ERROR(MIME support needs to be enabled in order to enable form API support) - ;; + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_FORM_API, 1, [disable form API]) + ;; + *) + AC_MSG_RESULT(yes) + test "$enable_mime" = no && + AC_MSG_ERROR(MIME support needs to be enabled in order to enable form API support) + ;; esac ], [ if test "$enable_mime" = no; then @@ -4408,13 +4598,14 @@ AS_HELP_STRING([--enable-dateparse],[Enable date parsing]) AS_HELP_STRING([--disable-dateparse],[Disable date parsing]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_PARSEDATE, 1, [disable date parsing]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_PARSEDATE, 1, [disable date parsing]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4426,13 +4617,14 @@ AS_HELP_STRING([--enable-netrc],[Enable netrc parsing]) AS_HELP_STRING([--disable-netrc],[Disable netrc parsing]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_NETRC, 1, [disable netrc parsing]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_NETRC, 1, [disable netrc parsing]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4444,13 +4636,33 @@ AS_HELP_STRING([--enable-progress-meter],[Enable progress-meter]) AS_HELP_STRING([--disable-progress-meter],[Disable progress-meter]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_PROGRESS_METER, 1, [disable progress-meter]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_PROGRESS_METER, 1, [disable progress-meter]) + ;; + *) + AC_MSG_RESULT(yes) + ;; + esac ], + AC_MSG_RESULT(yes) +) + +dnl ************************************************************ +dnl disable SHA-512/256 hash algorithm +dnl +AC_MSG_CHECKING([whether to support the SHA-512/256 hash algorithm]) +AC_ARG_ENABLE(sha512-256, +AS_HELP_STRING([--enable-sha512-256],[Enable SHA-512/256 hash algorithm (default)]) +AS_HELP_STRING([--disable-sha512-256],[Disable SHA-512/256 hash algorithm]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SHA512_256, 1, [disable SHA-512/256 hash algorithm]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4462,13 +4674,14 @@ AS_HELP_STRING([--enable-dnsshuffle],[Enable DNS shuffling]) AS_HELP_STRING([--disable-dnsshuffle],[Disable DNS shuffling]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_SHUFFLE_DNS, 1, [disable DNS shuffling]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_SHUFFLE_DNS, 1, [disable DNS shuffling]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4480,13 +4693,14 @@ AS_HELP_STRING([--enable-get-easy-options],[Enable curl_easy_options]) AS_HELP_STRING([--disable-get-easy-options],[Disable curl_easy_options]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_GETOPTIONS, 1, [to disable curl_easy_options]) - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_GETOPTIONS, 1, [to disable curl_easy_options]) + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4498,15 +4712,16 @@ AS_HELP_STRING([--enable-alt-svc],[Enable alt-svc support]) AS_HELP_STRING([--disable-alt-svc],[Disable alt-svc support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc]) - curl_altsvc_msg="no"; - enable_altsvc="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc]) + curl_altsvc_msg="no"; + enable_altsvc="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl ************************************************************ @@ -4517,15 +4732,16 @@ AC_ARG_ENABLE(headers-api, AS_HELP_STRING([--enable-headers-api],[Enable headers-api support]) AS_HELP_STRING([--disable-headers-api],[Disable headers-api support]), [ case "$enableval" in - no) AC_MSG_RESULT(no) - curl_headers_msg="no (--enable-headers-api)" - AC_DEFINE(CURL_DISABLE_HEADERS_API, 1, [disable headers-api]) - ;; + no) + AC_MSG_RESULT(no) + curl_headers_msg="no (--enable-headers-api)" + AC_DEFINE(CURL_DISABLE_HEADERS_API, 1, [disable headers-api]) + ;; *) - AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) ) dnl only check for HSTS if there's SSL present @@ -4539,13 +4755,14 @@ AS_HELP_STRING([--enable-hsts],[Enable HSTS support]) AS_HELP_STRING([--disable-hsts],[Disable HSTS support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - hsts="no" - ;; - *) AC_MSG_RESULT(yes) - ;; + AC_MSG_RESULT(no) + hsts="no" + ;; + *) + AC_MSG_RESULT(yes) + ;; esac ], - AC_MSG_RESULT($hsts) + AC_MSG_RESULT($hsts) ) else AC_MSG_NOTICE([disables HSTS due to lack of SSL]) @@ -4623,26 +4840,26 @@ AS_HELP_STRING([--enable-websockets],[Enable WebSockets support]) AS_HELP_STRING([--disable-websockets],[Disable WebSockets support]), [ case "$enableval" in no) - AC_MSG_RESULT(no) - ;; + AC_MSG_RESULT(no) + ;; *) - if test ${ac_cv_sizeof_curl_off_t} -gt 4; then - AC_MSG_RESULT(yes) - curl_ws_msg="enabled" - AC_DEFINE_UNQUOTED(USE_WEBSOCKETS, [1], [enable websockets support]) - SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS" - if test "x$SSL_ENABLED" = "x1"; then - SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS" - fi - experimental="$experimental Websockets" - else - dnl websockets requires >32 bit curl_off_t - AC_MSG_RESULT(no) - AC_MSG_WARN([Websockets disabled due to lack of >32 bit curl_off_t]) - fi - ;; + if test ${ac_cv_sizeof_curl_off_t} -gt 4; then + AC_MSG_RESULT(yes) + curl_ws_msg="enabled" + AC_DEFINE_UNQUOTED(USE_WEBSOCKETS, [1], [enable WebSockets support]) + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS" + if test "x$SSL_ENABLED" = "x1"; then + SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS" + fi + experimental="$experimental WebSockets" + else + dnl WebSockets requires >32 bit curl_off_t + AC_MSG_RESULT(no) + AC_MSG_WARN([WebSockets disabled due to lack of >32 bit curl_off_t]) + fi + ;; esac ], - AC_MSG_RESULT(no) + AC_MSG_RESULT(no) ) @@ -4654,9 +4871,9 @@ CURL_CONFIGURE_SYMBOL_HIDING dnl dnl All the library dependencies put into $LIB apply to libcurl only. dnl -LIBCURL_LIBS="$LIBS$PTHREAD" +LIBCURL_PC_LIBS_PRIVATE="$LIBS$PTHREAD" -AC_SUBST(LIBCURL_LIBS) +AC_SUBST(LIBCURL_PC_LIBS_PRIVATE) AC_SUBST(CURL_NETWORK_LIBS) AC_SUBST(CURL_NETWORK_AND_TIME_LIBS) @@ -4685,13 +4902,13 @@ AC_SUBST(LIBCURL_PC_REQUIRES_PRIVATE) dnl Merge pkg-config private fields into public ones when static-only if test "x$enable_shared" = "xno"; then LIBCURL_PC_REQUIRES=$LIBCURL_PC_REQUIRES_PRIVATE - LIBCURL_NO_SHARED=$LIBCURL_LIBS + LIBCURL_PC_LIBS=$LIBCURL_PC_LIBS_PRIVATE else LIBCURL_PC_REQUIRES= - LIBCURL_NO_SHARED= + LIBCURL_PC_LIBS= fi AC_SUBST(LIBCURL_PC_REQUIRES) -AC_SUBST(LIBCURL_NO_SHARED) +AC_SUBST(LIBCURL_PC_LIBS) rm $compilersh @@ -4740,7 +4957,7 @@ if test "x$curl_psl_msg" = "xenabled"; then fi if test "x$curl_gsasl_msg" = "xenabled"; then - SUPPORT_FEATURES="$SUPPORT_FEATURES GSASL" + SUPPORT_FEATURES="$SUPPORT_FEATURES gsasl" fi if test "x$enable_altsvc" = "xyes"; then @@ -4852,17 +5069,23 @@ else #endif ]]) ],[ - SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" + SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" ],[ ]) fi +if test "x$want_winuni" = "xyes"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES Unicode" +fi if test "x$want_debug" = "xyes"; then SUPPORT_FEATURES="$SUPPORT_FEATURES Debug" fi if test "x$want_curldebug" = "xyes"; then SUPPORT_FEATURES="$SUPPORT_FEATURES TrackMemory" fi +if test "x$CURL_CA_EMBED" != "x"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES CAcert" +fi dnl replace spaces with newlines dnl sort the lines @@ -4975,7 +5198,7 @@ squeeze DEFS squeeze LDFLAGS squeeze LIBS -squeeze LIBCURL_LIBS +squeeze LIBCURL_PC_LIBS_PRIVATE squeeze CURL_NETWORK_LIBS squeeze CURL_NETWORK_AND_TIME_LIBS @@ -4992,37 +5215,39 @@ if test "x$want_curldebug_assumed" = "xyes" && ac_configure_args="$ac_configure_args --enable-curldebug" fi -AC_CONFIG_FILES([Makefile \ - docs/Makefile \ - docs/examples/Makefile \ - docs/libcurl/Makefile \ - docs/libcurl/opts/Makefile \ - docs/cmdline-opts/Makefile \ - include/Makefile \ - include/curl/Makefile \ - src/Makefile \ - lib/Makefile \ - scripts/Makefile \ - lib/libcurl.vers \ - tests/Makefile \ - tests/config \ - tests/certs/Makefile \ - tests/certs/scripts/Makefile \ - tests/data/Makefile \ - tests/server/Makefile \ - tests/libtest/Makefile \ - tests/unit/Makefile \ - tests/http/config.ini \ - tests/http/Makefile \ - tests/http/clients/Makefile \ - packages/Makefile \ - packages/vms/Makefile \ - curl-config \ - libcurl.pc +AC_CONFIG_FILES([\ + Makefile \ + docs/Makefile \ + docs/examples/Makefile \ + docs/libcurl/Makefile \ + docs/libcurl/opts/Makefile \ + docs/cmdline-opts/Makefile \ + include/Makefile \ + include/curl/Makefile \ + src/Makefile \ + lib/Makefile \ + scripts/Makefile \ + lib/libcurl.vers \ + tests/Makefile \ + tests/config \ + tests/certs/Makefile \ + tests/certs/scripts/Makefile \ + tests/data/Makefile \ + tests/server/Makefile \ + tests/libtest/Makefile \ + tests/unit/Makefile \ + tests/http/config.ini \ + tests/http/Makefile \ + tests/http/clients/Makefile \ + packages/Makefile \ + packages/vms/Makefile \ + curl-config \ + libcurl.pc ]) AC_OUTPUT CURL_GENERATE_CONFIGUREHELP_PM +CURL_GENERATE_BUILDINFO_TXT SUPPORT_PROTOCOLS_LOWER=`echo "$SUPPORT_PROTOCOLS" | tr A-Z a-z` @@ -5077,15 +5302,16 @@ AC_MSG_NOTICE([Configured to build curl/libcurl: Features: ${SUPPORT_FEATURES} ]) -non13=`echo "$TLSCHOICE" | $EGREP -io 'bearssl|secure-transport'`; +# grep -o would simplify this, but is nonportable +[non13=`echo "$TLSCHOICE" | $AWK '{split("bearssl secure-transport", a); for (i in a) if(match(tolower($0), a[i])) print a[i];}'`] if test -n "$non13"; then - for a in $non13; do - AC_MSG_WARN([$a is enabled for TLS but it does not support TLS 1.3]) - done + for a in $non13; do + AC_MSG_WARN([$a is enabled for TLS but it does not support TLS 1.3]) + done fi if test -n "$experimental"; then - for a in $experimental; do - AC_MSG_WARN([$a is enabled but marked EXPERIMENTAL. Use with caution!]) - done + for a in $experimental; do + AC_MSG_WARN([$a is enabled but marked EXPERIMENTAL. Use with caution!]) + done fi diff --git a/curl-config.in b/curl-config.in index 5d40bc39f..294e083ec 100644 --- a/curl-config.in +++ b/curl-config.in @@ -31,7 +31,7 @@ prefix="@prefix@" exec_prefix=@exec_prefix@ # shellcheck disable=SC2034 includedir=@includedir@ -cppflag_curl_staticlib=@CPPFLAG_CURL_STATICLIB@ +cppflag_curl_staticlib=@LIBCURL_PC_CFLAGS@ usage() { @@ -161,7 +161,7 @@ while test "$#" -gt 0; do CURLLIBDIR="" fi if test "X@ENABLE_SHARED@" = "Xno"; then - echo "${CURLLIBDIR}-lcurl @LIBCURL_LIBS@" + echo "${CURLLIBDIR}-lcurl @LIBCURL_PC_LIBS_PRIVATE@" else echo "${CURLLIBDIR}-lcurl" fi @@ -173,7 +173,7 @@ while test "$#" -gt 0; do --static-libs) if test "X@ENABLE_STATIC@" != "Xno" ; then - echo "@libdir@/libcurl.@libext@" @LDFLAGS@ @LIBCURL_LIBS@ + echo "@libdir@/libcurl.@libext@" @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@ else echo 'curl was built with static libraries disabled' >&2 exit 1 diff --git a/docs/ALTSVC.md b/docs/ALTSVC.md deleted file mode 100644 index 4b5bcffcc..000000000 --- a/docs/ALTSVC.md +++ /dev/null @@ -1,50 +0,0 @@ - - -# Alt-Svc - -curl features support for the Alt-Svc: HTTP header. - -## Enable Alt-Svc in build - -`./configure --enable-alt-svc` - -(enabled by default since 7.73.0) - -## Standard - -[RFC 7838](https://datatracker.ietf.org/doc/html/rfc7838) - -# Alt-Svc cache file format - -This is a text based file with one line per entry and each line consists of nine -space separated fields. - -## Example - - h2 quic.tech 8443 h3-22 quic.tech 8443 "20190808 06:18:37" 0 0 - -## Fields - -1. The ALPN id for the source origin -2. The hostname for the source origin -3. The port number for the source origin -4. The ALPN id for the destination host -5. The hostname for the destination host -6. The port number for the destination host -7. The expiration date and time of this entry within double quotes. The date format is "YYYYMMDD HH:MM:SS" and the time zone is GMT. -8. Boolean (1 or 0) if "persist" was set for this entry -9. Integer priority value (not currently used) - -If the hostname is an IPv6 numerical address, it is stored with brackets such -as `[::1]`. - -# TODO - -- handle multiple response headers, when one of them says `clear` (should - override them all) -- using `Age:` value for caching age as per spec -- `CURLALTSVC_IMMEDIATELY` support diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md index 970df396c..e6287761b 100644 --- a/docs/BINDINGS.md +++ b/docs/BINDINGS.md @@ -144,3 +144,5 @@ Ruby: [curb](https://github.com/taf2/curb) written by Ross Bamford, [XBLite](https://web.archive.org/web/20060426150418/perso.wanadoo.fr/xblite/libraries.html) Written by David Szafranski [Xojo](https://github.com/charonn0/RB-libcURL) Written by Andrew Lambert + +[Zig](https://github.com/jiacai2050/zig-curl) Written by Jiacai Liu, both easy and multi API are supported. diff --git a/docs/CIPHERS-TLS12.md b/docs/CIPHERS-TLS12.md new file mode 100644 index 000000000..d67c62ba7 --- /dev/null +++ b/docs/CIPHERS-TLS12.md @@ -0,0 +1,336 @@ + + +# TLS 1.2 cipher suites + +| Id | IANA name | OpenSSL name | RFC | +|--------|-----------------------------------------------|------------------------------------|--------------------| +| 0x0001 | TLS_RSA_WITH_NULL_MD5 | NULL-MD5 | [RFC5246] | +| 0x0002 | TLS_RSA_WITH_NULL_SHA | NULL-SHA | [RFC5246] | +| 0x0003 | TLS_RSA_EXPORT_WITH_RC4_40_MD5 | EXP-RC4-MD5 | [RFC4346][RFC6347] | +| 0x0004 | TLS_RSA_WITH_RC4_128_MD5 | RC4-MD5 | [RFC5246][RFC6347] | +| 0x0005 | TLS_RSA_WITH_RC4_128_SHA | RC4-SHA | [RFC5246][RFC6347] | +| 0x0006 | TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 | EXP-RC2-CBC-MD5 | [RFC4346] | +| 0x0007 | TLS_RSA_WITH_IDEA_CBC_SHA | IDEA-CBC-SHA | [RFC8996] | +| 0x0008 | TLS_RSA_EXPORT_WITH_DES40_CBC_SHA | EXP-DES-CBC-SHA | [RFC4346] | +| 0x0009 | TLS_RSA_WITH_DES_CBC_SHA | DES-CBC-SHA | [RFC8996] | +| 0x000A | TLS_RSA_WITH_3DES_EDE_CBC_SHA | DES-CBC3-SHA | [RFC5246] | +| 0x000B | TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA | EXP-DH-DSS-DES-CBC-SHA | [RFC4346] | +| 0x000C | TLS_DH_DSS_WITH_DES_CBC_SHA | DH-DSS-DES-CBC-SHA | [RFC8996] | +| 0x000D | TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA | DH-DSS-DES-CBC3-SHA | [RFC5246] | +| 0x000E | TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA | EXP-DH-RSA-DES-CBC-SHA | [RFC4346] | +| 0x000F | TLS_DH_RSA_WITH_DES_CBC_SHA | DH-RSA-DES-CBC-SHA | [RFC8996] | +| 0x0010 | TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA | DH-RSA-DES-CBC3-SHA | [RFC5246] | +| 0x0011 | TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | EXP-DHE-DSS-DES-CBC-SHA | [RFC4346] | +| 0x0012 | TLS_DHE_DSS_WITH_DES_CBC_SHA | DHE-DSS-DES-CBC-SHA | [RFC8996] | +| 0x0013 | TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA | DHE-DSS-DES-CBC3-SHA | [RFC5246] | +| 0x0014 | TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | EXP-DHE-RSA-DES-CBC-SHA | [RFC4346] | +| 0x0015 | TLS_DHE_RSA_WITH_DES_CBC_SHA | DHE-RSA-DES-CBC-SHA | [RFC8996] | +| 0x0016 | TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA | DHE-RSA-DES-CBC3-SHA | [RFC5246] | +| 0x0017 | TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 | EXP-ADH-RC4-MD5 | [RFC4346][RFC6347] | +| 0x0018 | TLS_DH_anon_WITH_RC4_128_MD5 | ADH-RC4-MD5 | [RFC5246][RFC6347] | +| 0x0019 | TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA | EXP-ADH-DES-CBC-SHA | [RFC4346] | +| 0x001A | TLS_DH_anon_WITH_DES_CBC_SHA | ADH-DES-CBC-SHA | [RFC8996] | +| 0x001B | TLS_DH_anon_WITH_3DES_EDE_CBC_SHA | ADH-DES-CBC3-SHA | [RFC5246] | +| 0x001C | | FZA-NULL-SHA | | +| 0x001D | | FZA-FZA-CBC-SHA | | +| 0x001E | TLS_KRB5_WITH_DES_CBC_SHA | KRB5-DES-CBC-SHA | [RFC2712] | +| 0x001F | TLS_KRB5_WITH_3DES_EDE_CBC_SHA | KRB5-DES-CBC3-SHA | [RFC2712] | +| 0x0020 | TLS_KRB5_WITH_RC4_128_SHA | KRB5-RC4-SHA | [RFC2712][RFC6347] | +| 0x0021 | TLS_KRB5_WITH_IDEA_CBC_SHA | KRB5-IDEA-CBC-SHA | [RFC2712] | +| 0x0022 | TLS_KRB5_WITH_DES_CBC_MD5 | KRB5-DES-CBC-MD5 | [RFC2712] | +| 0x0023 | TLS_KRB5_WITH_3DES_EDE_CBC_MD5 | KRB5-DES-CBC3-MD5 | [RFC2712] | +| 0x0024 | TLS_KRB5_WITH_RC4_128_MD5 | KRB5-RC4-MD5 | [RFC2712][RFC6347] | +| 0x0025 | TLS_KRB5_WITH_IDEA_CBC_MD5 | KRB5-IDEA-CBC-MD5 | [RFC2712] | +| 0x0026 | TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA | EXP-KRB5-DES-CBC-SHA | [RFC2712] | +| 0x0027 | TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA | EXP-KRB5-RC2-CBC-SHA | [RFC2712] | +| 0x0028 | TLS_KRB5_EXPORT_WITH_RC4_40_SHA | EXP-KRB5-RC4-SHA | [RFC2712][RFC6347] | +| 0x0029 | TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 | EXP-KRB5-DES-CBC-MD5 | [RFC2712] | +| 0x002A | TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 | EXP-KRB5-RC2-CBC-MD5 | [RFC2712] | +| 0x002B | TLS_KRB5_EXPORT_WITH_RC4_40_MD5 | EXP-KRB5-RC4-MD5 | [RFC2712][RFC6347] | +| 0x002C | TLS_PSK_WITH_NULL_SHA | PSK-NULL-SHA | [RFC4785] | +| 0x002D | TLS_DHE_PSK_WITH_NULL_SHA | DHE-PSK-NULL-SHA | [RFC4785] | +| 0x002E | TLS_RSA_PSK_WITH_NULL_SHA | RSA-PSK-NULL-SHA | [RFC4785] | +| 0x002F | TLS_RSA_WITH_AES_128_CBC_SHA | AES128-SHA | [RFC5246] | +| 0x0030 | TLS_DH_DSS_WITH_AES_128_CBC_SHA | DH-DSS-AES128-SHA | [RFC5246] | +| 0x0031 | TLS_DH_RSA_WITH_AES_128_CBC_SHA | DH-RSA-AES128-SHA | [RFC5246] | +| 0x0032 | TLS_DHE_DSS_WITH_AES_128_CBC_SHA | DHE-DSS-AES128-SHA | [RFC5246] | +| 0x0033 | TLS_DHE_RSA_WITH_AES_128_CBC_SHA | DHE-RSA-AES128-SHA | [RFC5246] | +| 0x0034 | TLS_DH_anon_WITH_AES_128_CBC_SHA | ADH-AES128-SHA | [RFC5246] | +| 0x0035 | TLS_RSA_WITH_AES_256_CBC_SHA | AES256-SHA | [RFC5246] | +| 0x0036 | TLS_DH_DSS_WITH_AES_256_CBC_SHA | DH-DSS-AES256-SHA | [RFC5246] | +| 0x0037 | TLS_DH_RSA_WITH_AES_256_CBC_SHA | DH-RSA-AES256-SHA | [RFC5246] | +| 0x0038 | TLS_DHE_DSS_WITH_AES_256_CBC_SHA | DHE-DSS-AES256-SHA | [RFC5246] | +| 0x0039 | TLS_DHE_RSA_WITH_AES_256_CBC_SHA | DHE-RSA-AES256-SHA | [RFC5246] | +| 0x003A | TLS_DH_anon_WITH_AES_256_CBC_SHA | ADH-AES256-SHA | [RFC5246] | +| 0x003B | TLS_RSA_WITH_NULL_SHA256 | NULL-SHA256 | [RFC5246] | +| 0x003C | TLS_RSA_WITH_AES_128_CBC_SHA256 | AES128-SHA256 | [RFC5246] | +| 0x003D | TLS_RSA_WITH_AES_256_CBC_SHA256 | AES256-SHA256 | [RFC5246] | +| 0x003E | TLS_DH_DSS_WITH_AES_128_CBC_SHA256 | DH-DSS-AES128-SHA256 | [RFC5246] | +| 0x003F | TLS_DH_RSA_WITH_AES_128_CBC_SHA256 | DH-RSA-AES128-SHA256 | [RFC5246] | +| 0x0040 | TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 | DHE-DSS-AES128-SHA256 | [RFC5246] | +| 0x0041 | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA | CAMELLIA128-SHA | [RFC5932] | +| 0x0042 | TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA | DH-DSS-CAMELLIA128-SHA | [RFC5932] | +| 0x0043 | TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA | DH-RSA-CAMELLIA128-SHA | [RFC5932] | +| 0x0044 | TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA | DHE-DSS-CAMELLIA128-SHA | [RFC5932] | +| 0x0045 | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA | DHE-RSA-CAMELLIA128-SHA | [RFC5932] | +| 0x0046 | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA | ADH-CAMELLIA128-SHA | [RFC5932] | +| 0x0060 | | EXP1024-RC4-MD5 | | +| 0x0061 | | EXP1024-RC2-CBC-MD5 | | +| 0x0062 | | EXP1024-DES-CBC-SHA | | +| 0x0063 | | EXP1024-DHE-DSS-DES-CBC-SHA | | +| 0x0064 | | EXP1024-RC4-SHA | | +| 0x0065 | | EXP1024-DHE-DSS-RC4-SHA | | +| 0x0066 | | DHE-DSS-RC4-SHA | | +| 0x0067 | TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 | DHE-RSA-AES128-SHA256 | [RFC5246] | +| 0x0068 | TLS_DH_DSS_WITH_AES_256_CBC_SHA256 | DH-DSS-AES256-SHA256 | [RFC5246] | +| 0x0069 | TLS_DH_RSA_WITH_AES_256_CBC_SHA256 | DH-RSA-AES256-SHA256 | [RFC5246] | +| 0x006A | TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 | DHE-DSS-AES256-SHA256 | [RFC5246] | +| 0x006B | TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 | DHE-RSA-AES256-SHA256 | [RFC5246] | +| 0x006C | TLS_DH_anon_WITH_AES_128_CBC_SHA256 | ADH-AES128-SHA256 | [RFC5246] | +| 0x006D | TLS_DH_anon_WITH_AES_256_CBC_SHA256 | ADH-AES256-SHA256 | [RFC5246] | +| 0x0080 | | GOST94-GOST89-GOST89 | | +| 0x0081 | | GOST2001-GOST89-GOST89 | | +| 0x0082 | | GOST94-NULL-GOST94 | | +| 0x0083 | | GOST2001-NULL-GOST94 | | +| 0x0084 | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA | CAMELLIA256-SHA | [RFC5932] | +| 0x0085 | TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA | DH-DSS-CAMELLIA256-SHA | [RFC5932] | +| 0x0086 | TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA | DH-RSA-CAMELLIA256-SHA | [RFC5932] | +| 0x0087 | TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA | DHE-DSS-CAMELLIA256-SHA | [RFC5932] | +| 0x0088 | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA | DHE-RSA-CAMELLIA256-SHA | [RFC5932] | +| 0x0089 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA | ADH-CAMELLIA256-SHA | [RFC5932] | +| 0x008A | TLS_PSK_WITH_RC4_128_SHA | PSK-RC4-SHA | [RFC4279][RFC6347] | +| 0x008B | TLS_PSK_WITH_3DES_EDE_CBC_SHA | PSK-3DES-EDE-CBC-SHA | [RFC4279] | +| 0x008C | TLS_PSK_WITH_AES_128_CBC_SHA | PSK-AES128-CBC-SHA | [RFC4279] | +| 0x008D | TLS_PSK_WITH_AES_256_CBC_SHA | PSK-AES256-CBC-SHA | [RFC4279] | +| 0x008E | TLS_DHE_PSK_WITH_RC4_128_SHA | DHE-PSK-RC4-SHA | [RFC4279][RFC6347] | +| 0x008F | TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA | DHE-PSK-3DES-EDE-CBC-SHA | [RFC4279] | +| 0x0090 | TLS_DHE_PSK_WITH_AES_128_CBC_SHA | DHE-PSK-AES128-CBC-SHA | [RFC4279] | +| 0x0091 | TLS_DHE_PSK_WITH_AES_256_CBC_SHA | DHE-PSK-AES256-CBC-SHA | [RFC4279] | +| 0x0092 | TLS_RSA_PSK_WITH_RC4_128_SHA | RSA-PSK-RC4-SHA | [RFC4279][RFC6347] | +| 0x0093 | TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA | RSA-PSK-3DES-EDE-CBC-SHA | [RFC4279] | +| 0x0094 | TLS_RSA_PSK_WITH_AES_128_CBC_SHA | RSA-PSK-AES128-CBC-SHA | [RFC4279] | +| 0x0095 | TLS_RSA_PSK_WITH_AES_256_CBC_SHA | RSA-PSK-AES256-CBC-SHA | [RFC4279] | +| 0x0096 | TLS_RSA_WITH_SEED_CBC_SHA | SEED-SHA | [RFC4162] | +| 0x0097 | TLS_DH_DSS_WITH_SEED_CBC_SHA | DH-DSS-SEED-SHA | [RFC4162] | +| 0x0098 | TLS_DH_RSA_WITH_SEED_CBC_SHA | DH-RSA-SEED-SHA | [RFC4162] | +| 0x0099 | TLS_DHE_DSS_WITH_SEED_CBC_SHA | DHE-DSS-SEED-SHA | [RFC4162] | +| 0x009A | TLS_DHE_RSA_WITH_SEED_CBC_SHA | DHE-RSA-SEED-SHA | [RFC4162] | +| 0x009B | TLS_DH_anon_WITH_SEED_CBC_SHA | ADH-SEED-SHA | [RFC4162] | +| 0x009C | TLS_RSA_WITH_AES_128_GCM_SHA256 | AES128-GCM-SHA256 | [RFC5288] | +| 0x009D | TLS_RSA_WITH_AES_256_GCM_SHA384 | AES256-GCM-SHA384 | [RFC5288] | +| 0x009E | TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 | DHE-RSA-AES128-GCM-SHA256 | [RFC5288] | +| 0x009F | TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 | DHE-RSA-AES256-GCM-SHA384 | [RFC5288] | +| 0x00A0 | TLS_DH_RSA_WITH_AES_128_GCM_SHA256 | DH-RSA-AES128-GCM-SHA256 | [RFC5288] | +| 0x00A1 | TLS_DH_RSA_WITH_AES_256_GCM_SHA384 | DH-RSA-AES256-GCM-SHA384 | [RFC5288] | +| 0x00A2 | TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 | DHE-DSS-AES128-GCM-SHA256 | [RFC5288] | +| 0x00A3 | TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 | DHE-DSS-AES256-GCM-SHA384 | [RFC5288] | +| 0x00A4 | TLS_DH_DSS_WITH_AES_128_GCM_SHA256 | DH-DSS-AES128-GCM-SHA256 | [RFC5288] | +| 0x00A5 | TLS_DH_DSS_WITH_AES_256_GCM_SHA384 | DH-DSS-AES256-GCM-SHA384 | [RFC5288] | +| 0x00A6 | TLS_DH_anon_WITH_AES_128_GCM_SHA256 | ADH-AES128-GCM-SHA256 | [RFC5288] | +| 0x00A7 | TLS_DH_anon_WITH_AES_256_GCM_SHA384 | ADH-AES256-GCM-SHA384 | [RFC5288] | +| 0x00A8 | TLS_PSK_WITH_AES_128_GCM_SHA256 | PSK-AES128-GCM-SHA256 | [RFC5487] | +| 0x00A9 | TLS_PSK_WITH_AES_256_GCM_SHA384 | PSK-AES256-GCM-SHA384 | [RFC5487] | +| 0x00AA | TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 | DHE-PSK-AES128-GCM-SHA256 | [RFC5487] | +| 0x00AB | TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 | DHE-PSK-AES256-GCM-SHA384 | [RFC5487] | +| 0x00AC | TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 | RSA-PSK-AES128-GCM-SHA256 | [RFC5487] | +| 0x00AD | TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 | RSA-PSK-AES256-GCM-SHA384 | [RFC5487] | +| 0x00AE | TLS_PSK_WITH_AES_128_CBC_SHA256 | PSK-AES128-CBC-SHA256 | [RFC5487] | +| 0x00AF | TLS_PSK_WITH_AES_256_CBC_SHA384 | PSK-AES256-CBC-SHA384 | [RFC5487] | +| 0x00B0 | TLS_PSK_WITH_NULL_SHA256 | PSK-NULL-SHA256 | [RFC5487] | +| 0x00B1 | TLS_PSK_WITH_NULL_SHA384 | PSK-NULL-SHA384 | [RFC5487] | +| 0x00B2 | TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 | DHE-PSK-AES128-CBC-SHA256 | [RFC5487] | +| 0x00B3 | TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 | DHE-PSK-AES256-CBC-SHA384 | [RFC5487] | +| 0x00B4 | TLS_DHE_PSK_WITH_NULL_SHA256 | DHE-PSK-NULL-SHA256 | [RFC5487] | +| 0x00B5 | TLS_DHE_PSK_WITH_NULL_SHA384 | DHE-PSK-NULL-SHA384 | [RFC5487] | +| 0x00B6 | TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 | RSA-PSK-AES128-CBC-SHA256 | [RFC5487] | +| 0x00B7 | TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 | RSA-PSK-AES256-CBC-SHA384 | [RFC5487] | +| 0x00B8 | TLS_RSA_PSK_WITH_NULL_SHA256 | RSA-PSK-NULL-SHA256 | [RFC5487] | +| 0x00B9 | TLS_RSA_PSK_WITH_NULL_SHA384 | RSA-PSK-NULL-SHA384 | [RFC5487] | +| 0x00BA | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 | CAMELLIA128-SHA256 | [RFC5932] | +| 0x00BD | TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 | DHE-DSS-CAMELLIA128-SHA256 | [RFC5932] | +| 0x00BE | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 | DHE-RSA-CAMELLIA128-SHA256 | [RFC5932] | +| 0x00BF | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 | ADH-CAMELLIA128-SHA256 | [RFC5932] | +| 0x00C0 | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 | CAMELLIA256-SHA256 | [RFC5932] | +| 0x00C3 | TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 | DHE-DSS-CAMELLIA256-SHA256 | [RFC5932] | +| 0x00C4 | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 | DHE-RSA-CAMELLIA256-SHA256 | [RFC5932] | +| 0x00C5 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 | ADH-CAMELLIA256-SHA256 | [RFC5932] | +| 0x00FF | TLS_EMPTY_RENEGOTIATION_INFO_SCSV | | [RFC5746] | +| 0x5600 | TLS_FALLBACK_SCSV | | [RFC7507] | +| 0xC001 | TLS_ECDH_ECDSA_WITH_NULL_SHA | ECDH-ECDSA-NULL-SHA | [RFC8422] | +| 0xC002 | TLS_ECDH_ECDSA_WITH_RC4_128_SHA | ECDH-ECDSA-RC4-SHA | [RFC8422][RFC6347] | +| 0xC003 | TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA | ECDH-ECDSA-DES-CBC3-SHA | [RFC8422] | +| 0xC004 | TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA | ECDH-ECDSA-AES128-SHA | [RFC8422] | +| 0xC005 | TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA | ECDH-ECDSA-AES256-SHA | [RFC8422] | +| 0xC006 | TLS_ECDHE_ECDSA_WITH_NULL_SHA | ECDHE-ECDSA-NULL-SHA | [RFC8422] | +| 0xC007 | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | ECDHE-ECDSA-RC4-SHA | [RFC8422][RFC6347] | +| 0xC008 | TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA | ECDHE-ECDSA-DES-CBC3-SHA | [RFC8422] | +| 0xC009 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA | ECDHE-ECDSA-AES128-SHA | [RFC8422] | +| 0xC00A | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA | ECDHE-ECDSA-AES256-SHA | [RFC8422] | +| 0xC00B | TLS_ECDH_RSA_WITH_NULL_SHA | ECDH-RSA-NULL-SHA | [RFC8422] | +| 0xC00C | TLS_ECDH_RSA_WITH_RC4_128_SHA | ECDH-RSA-RC4-SHA | [RFC8422][RFC6347] | +| 0xC00D | TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA | ECDH-RSA-DES-CBC3-SHA | [RFC8422] | +| 0xC00E | TLS_ECDH_RSA_WITH_AES_128_CBC_SHA | ECDH-RSA-AES128-SHA | [RFC8422] | +| 0xC00F | TLS_ECDH_RSA_WITH_AES_256_CBC_SHA | ECDH-RSA-AES256-SHA | [RFC8422] | +| 0xC010 | TLS_ECDHE_RSA_WITH_NULL_SHA | ECDHE-RSA-NULL-SHA | [RFC8422] | +| 0xC011 | TLS_ECDHE_RSA_WITH_RC4_128_SHA | ECDHE-RSA-RC4-SHA | [RFC8422][RFC6347] | +| 0xC012 | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA | ECDHE-RSA-DES-CBC3-SHA | [RFC8422] | +| 0xC013 | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA | ECDHE-RSA-AES128-SHA | [RFC8422] | +| 0xC014 | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA | ECDHE-RSA-AES256-SHA | [RFC8422] | +| 0xC015 | TLS_ECDH_anon_WITH_NULL_SHA | AECDH-NULL-SHA | [RFC8422] | +| 0xC016 | TLS_ECDH_anon_WITH_RC4_128_SHA | AECDH-RC4-SHA | [RFC8422][RFC6347] | +| 0xC017 | TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA | AECDH-DES-CBC3-SHA | [RFC8422] | +| 0xC018 | TLS_ECDH_anon_WITH_AES_128_CBC_SHA | AECDH-AES128-SHA | [RFC8422] | +| 0xC019 | TLS_ECDH_anon_WITH_AES_256_CBC_SHA | AECDH-AES256-SHA | [RFC8422] | +| 0xC01A | TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA | SRP-3DES-EDE-CBC-SHA | [RFC5054] | +| 0xC01B | TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA | SRP-RSA-3DES-EDE-CBC-SHA | [RFC5054] | +| 0xC01C | TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA | SRP-DSS-3DES-EDE-CBC-SHA | [RFC5054] | +| 0xC01D | TLS_SRP_SHA_WITH_AES_128_CBC_SHA | SRP-AES-128-CBC-SHA | [RFC5054] | +| 0xC01E | TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA | SRP-RSA-AES-128-CBC-SHA | [RFC5054] | +| 0xC01F | TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA | SRP-DSS-AES-128-CBC-SHA | [RFC5054] | +| 0xC020 | TLS_SRP_SHA_WITH_AES_256_CBC_SHA | SRP-AES-256-CBC-SHA | [RFC5054] | +| 0xC021 | TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA | SRP-RSA-AES-256-CBC-SHA | [RFC5054] | +| 0xC022 | TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA | SRP-DSS-AES-256-CBC-SHA | [RFC5054] | +| 0xC023 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | ECDHE-ECDSA-AES128-SHA256 | [RFC5289] | +| 0xC024 | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 | ECDHE-ECDSA-AES256-SHA384 | [RFC5289] | +| 0xC025 | TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 | ECDH-ECDSA-AES128-SHA256 | [RFC5289] | +| 0xC026 | TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 | ECDH-ECDSA-AES256-SHA384 | [RFC5289] | +| 0xC027 | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | ECDHE-RSA-AES128-SHA256 | [RFC5289] | +| 0xC028 | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 | ECDHE-RSA-AES256-SHA384 | [RFC5289] | +| 0xC029 | TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 | ECDH-RSA-AES128-SHA256 | [RFC5289] | +| 0xC02A | TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 | ECDH-RSA-AES256-SHA384 | [RFC5289] | +| 0xC02B | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | ECDHE-ECDSA-AES128-GCM-SHA256 | [RFC5289] | +| 0xC02C | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | ECDHE-ECDSA-AES256-GCM-SHA384 | [RFC5289] | +| 0xC02D | TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 | ECDH-ECDSA-AES128-GCM-SHA256 | [RFC5289] | +| 0xC02E | TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | ECDH-ECDSA-AES256-GCM-SHA384 | [RFC5289] | +| 0xC02F | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | ECDHE-RSA-AES128-GCM-SHA256 | [RFC5289] | +| 0xC030 | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | ECDHE-RSA-AES256-GCM-SHA384 | [RFC5289] | +| 0xC031 | TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 | ECDH-RSA-AES128-GCM-SHA256 | [RFC5289] | +| 0xC032 | TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | ECDH-RSA-AES256-GCM-SHA384 | [RFC5289] | +| 0xC033 | TLS_ECDHE_PSK_WITH_RC4_128_SHA | ECDHE-PSK-RC4-SHA | [RFC5489][RFC6347] | +| 0xC034 | TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA | ECDHE-PSK-3DES-EDE-CBC-SHA | [RFC5489] | +| 0xC035 | TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA | ECDHE-PSK-AES128-CBC-SHA | [RFC5489] | +| 0xC036 | TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA | ECDHE-PSK-AES256-CBC-SHA | [RFC5489] | +| 0xC037 | TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 | ECDHE-PSK-AES128-CBC-SHA256 | [RFC5489] | +| 0xC038 | TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 | ECDHE-PSK-AES256-CBC-SHA384 | [RFC5489] | +| 0xC039 | TLS_ECDHE_PSK_WITH_NULL_SHA | ECDHE-PSK-NULL-SHA | [RFC5489] | +| 0xC03A | TLS_ECDHE_PSK_WITH_NULL_SHA256 | ECDHE-PSK-NULL-SHA256 | [RFC5489] | +| 0xC03B | TLS_ECDHE_PSK_WITH_NULL_SHA384 | ECDHE-PSK-NULL-SHA384 | [RFC5489] | +| 0xC03C | TLS_RSA_WITH_ARIA_128_CBC_SHA256 | ARIA128-SHA256 | [RFC6209] | +| 0xC03D | TLS_RSA_WITH_ARIA_256_CBC_SHA384 | ARIA256-SHA384 | [RFC6209] | +| 0xC044 | TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 | DHE-RSA-ARIA128-SHA256 | [RFC6209] | +| 0xC045 | TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 | DHE-RSA-ARIA256-SHA384 | [RFC6209] | +| 0xC048 | TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 | ECDHE-ECDSA-ARIA128-SHA256 | [RFC6209] | +| 0xC049 | TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 | ECDHE-ECDSA-ARIA256-SHA384 | [RFC6209] | +| 0xC04A | TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 | ECDH-ECDSA-ARIA128-SHA256 | [RFC6209] | +| 0xC04B | TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 | ECDH-ECDSA-ARIA256-SHA384 | [RFC6209] | +| 0xC04C | TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 | ECDHE-ARIA128-SHA256 | [RFC6209] | +| 0xC04D | TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 | ECDHE-ARIA256-SHA384 | [RFC6209] | +| 0xC04E | TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 | ECDH-ARIA128-SHA256 | [RFC6209] | +| 0xC04F | TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 | ECDH-ARIA256-SHA384 | [RFC6209] | +| 0xC050 | TLS_RSA_WITH_ARIA_128_GCM_SHA256 | ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC051 | TLS_RSA_WITH_ARIA_256_GCM_SHA384 | ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC052 | TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 | DHE-RSA-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC053 | TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 | DHE-RSA-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC056 | TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 | DHE-DSS-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC057 | TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 | DHE-DSS-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC05C | TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 | ECDHE-ECDSA-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC05D | TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 | ECDHE-ECDSA-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC05E | TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 | ECDH-ECDSA-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC05F | TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 | ECDH-ECDSA-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC060 | TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 | ECDHE-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC061 | TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 | ECDHE-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC062 | TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 | ECDH-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC063 | TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 | ECDH-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC064 | TLS_PSK_WITH_ARIA_128_CBC_SHA256 | PSK-ARIA128-SHA256 | [RFC6209] | +| 0xC065 | TLS_PSK_WITH_ARIA_256_CBC_SHA384 | PSK-ARIA256-SHA384 | [RFC6209] | +| 0xC066 | TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 | DHE-PSK-ARIA128-SHA256 | [RFC6209] | +| 0xC067 | TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 | DHE-PSK-ARIA256-SHA384 | [RFC6209] | +| 0xC068 | TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 | RSA-PSK-ARIA128-SHA256 | [RFC6209] | +| 0xC069 | TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 | RSA-PSK-ARIA256-SHA384 | [RFC6209] | +| 0xC06A | TLS_PSK_WITH_ARIA_128_GCM_SHA256 | PSK-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC06B | TLS_PSK_WITH_ARIA_256_GCM_SHA384 | PSK-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC06C | TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 | DHE-PSK-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC06D | TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 | DHE-PSK-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC06E | TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 | RSA-PSK-ARIA128-GCM-SHA256 | [RFC6209] | +| 0xC06F | TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 | RSA-PSK-ARIA256-GCM-SHA384 | [RFC6209] | +| 0xC070 | TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 | ECDHE-PSK-ARIA128-SHA256 | [RFC6209] | +| 0xC071 | TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 | ECDHE-PSK-ARIA256-SHA384 | [RFC6209] | +| 0xC072 | TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 | ECDHE-ECDSA-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC073 | TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 | ECDHE-ECDSA-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC074 | TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 | ECDH-ECDSA-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC075 | TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 | ECDH-ECDSA-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC076 | TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 | ECDHE-RSA-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC077 | TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 | ECDHE-RSA-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC078 | TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 | ECDH-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC079 | TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 | ECDH-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC07A | TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 | CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC07B | TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 | CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC07C | TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 | DHE-RSA-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC07D | TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 | DHE-RSA-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC086 | TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 | ECDHE-ECDSA-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC087 | TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 | ECDHE-ECDSA-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC088 | TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 | ECDH-ECDSA-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC089 | TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 | ECDH-ECDSA-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC08A | TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 | ECDHE-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC08B | TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 | ECDHE-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC08C | TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 | ECDH-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC08D | TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 | ECDH-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC08E | TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 | PSK-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC08F | TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 | PSK-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC090 | TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 | DHE-PSK-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC091 | TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 | DHE-PSK-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC092 | TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 | RSA-PSK-CAMELLIA128-GCM-SHA256 | [RFC6367] | +| 0xC093 | TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 | RSA-PSK-CAMELLIA256-GCM-SHA384 | [RFC6367] | +| 0xC094 | TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 | PSK-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC095 | TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 | PSK-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC096 | TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 | DHE-PSK-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC097 | TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 | DHE-PSK-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC098 | TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 | RSA-PSK-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC099 | TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 | RSA-PSK-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC09A | TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 | ECDHE-PSK-CAMELLIA128-SHA256 | [RFC6367] | +| 0xC09B | TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 | ECDHE-PSK-CAMELLIA256-SHA384 | [RFC6367] | +| 0xC09C | TLS_RSA_WITH_AES_128_CCM | AES128-CCM | [RFC6655] | +| 0xC09D | TLS_RSA_WITH_AES_256_CCM | AES256-CCM | [RFC6655] | +| 0xC09E | TLS_DHE_RSA_WITH_AES_128_CCM | DHE-RSA-AES128-CCM | [RFC6655] | +| 0xC09F | TLS_DHE_RSA_WITH_AES_256_CCM | DHE-RSA-AES256-CCM | [RFC6655] | +| 0xC0A0 | TLS_RSA_WITH_AES_128_CCM_8 | AES128-CCM8 | [RFC6655] | +| 0xC0A1 | TLS_RSA_WITH_AES_256_CCM_8 | AES256-CCM8 | [RFC6655] | +| 0xC0A2 | TLS_DHE_RSA_WITH_AES_128_CCM_8 | DHE-RSA-AES128-CCM8 | [RFC6655] | +| 0xC0A3 | TLS_DHE_RSA_WITH_AES_256_CCM_8 | DHE-RSA-AES256-CCM8 | [RFC6655] | +| 0xC0A4 | TLS_PSK_WITH_AES_128_CCM | PSK-AES128-CCM | [RFC6655] | +| 0xC0A5 | TLS_PSK_WITH_AES_256_CCM | PSK-AES256-CCM | [RFC6655] | +| 0xC0A6 | TLS_DHE_PSK_WITH_AES_128_CCM | DHE-PSK-AES128-CCM | [RFC6655] | +| 0xC0A7 | TLS_DHE_PSK_WITH_AES_256_CCM | DHE-PSK-AES256-CCM | [RFC6655] | +| 0xC0A8 | TLS_PSK_WITH_AES_128_CCM_8 | PSK-AES128-CCM8 | [RFC6655] | +| 0xC0A9 | TLS_PSK_WITH_AES_256_CCM_8 | PSK-AES256-CCM8 | [RFC6655] | +| 0xC0AA | TLS_PSK_DHE_WITH_AES_128_CCM_8 | DHE-PSK-AES128-CCM8 | [RFC6655] | +| 0xC0AB | TLS_PSK_DHE_WITH_AES_256_CCM_8 | DHE-PSK-AES256-CCM8 | [RFC6655] | +| 0xC0AC | TLS_ECDHE_ECDSA_WITH_AES_128_CCM | ECDHE-ECDSA-AES128-CCM | [RFC7251] | +| 0xC0AD | TLS_ECDHE_ECDSA_WITH_AES_256_CCM | ECDHE-ECDSA-AES256-CCM | [RFC7251] | +| 0xC0AE | TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 | ECDHE-ECDSA-AES128-CCM8 | [RFC7251] | +| 0xC0AF | TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 | ECDHE-ECDSA-AES256-CCM8 | [RFC7251] | +| 0xC100 | TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC | GOST2012-KUZNYECHIK-KUZNYECHIKOMAC | [RFC9189] | +| 0xC101 | TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC | GOST2012-MAGMA-MAGMAOMAC | [RFC9189] | +| 0xC102 | TLS_GOSTR341112_256_WITH_28147_CNT_IMIT | IANA-GOST2012-GOST8912-GOST8912 | [RFC9189] | +| 0xCC13 | | ECDHE-RSA-CHACHA20-POLY1305-OLD | | +| 0xCC14 | | ECDHE-ECDSA-CHACHA20-POLY1305-OLD | | +| 0xCC15 | | DHE-RSA-CHACHA20-POLY1305-OLD | | +| 0xCCA8 | TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | ECDHE-RSA-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCA9 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 | ECDHE-ECDSA-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCAA | TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | DHE-RSA-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCAB | TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 | PSK-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCAC | TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 | ECDHE-PSK-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCAD | TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 | DHE-PSK-CHACHA20-POLY1305 | [RFC7905] | +| 0xCCAE | TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 | RSA-PSK-CHACHA20-POLY1305 | [RFC7905] | +| 0xD001 | TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 | ECDHE-PSK-AES128-GCM-SHA256 | [RFC8442] | +| 0xE011 | | ECDHE-ECDSA-SM4-CBC-SM3 | | +| 0xE051 | | ECDHE-ECDSA-SM4-GCM-SM3 | | +| 0xE052 | | ECDHE-ECDSA-SM4-CCM-SM3 | | +| 0xFF00 | | GOST-MD5 | | +| 0xFF01 | | GOST-GOST94 | | +| 0xFF02 | | GOST-GOST89MAC | | +| 0xFF03 | | GOST-GOST89STREAM | | diff --git a/docs/CIPHERS.md b/docs/CIPHERS.md index 607810c04..0807423d2 100644 --- a/docs/CIPHERS.md +++ b/docs/CIPHERS.md @@ -4,430 +4,186 @@ Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl --> -# Ciphers +## curl cipher options -With curl's options -[`CURLOPT_SSL_CIPHER_LIST`](https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html) -and -[`--ciphers`](https://curl.se/docs/manpage.html#--ciphers) -users can control which ciphers to consider when negotiating TLS connections. - -TLS 1.3 ciphers are supported since curl 7.61 for OpenSSL 1.1.1+, and since -curl 7.85 for Schannel with options -[`CURLOPT_TLS13_CIPHERS`](https://curl.se/libcurl/c/CURLOPT_TLS13_CIPHERS.html) -and +With curl's option [`--tls13-ciphers`](https://curl.se/docs/manpage.html#--tls13-ciphers) -. If you are using a different SSL backend you can try setting TLS 1.3 cipher -suites by using the respective regular cipher option. - -The names of the known ciphers differ depending on which TLS backend that -libcurl was built to use. This is an attempt to list known cipher names. - -## OpenSSL - -(based on [OpenSSL docs](https://docs.openssl.org/master/man1/openssl-ciphers/)) - -When specifying multiple cipher names, separate them with colon (`:`). - -### SSL3 cipher suites - -`NULL-MD5` -`NULL-SHA` -`RC4-MD5` -`RC4-SHA` -`IDEA-CBC-SHA` -`DES-CBC3-SHA` -`DH-DSS-DES-CBC3-SHA` -`DH-RSA-DES-CBC3-SHA` -`DHE-DSS-DES-CBC3-SHA` -`DHE-RSA-DES-CBC3-SHA` -`ADH-RC4-MD5` -`ADH-DES-CBC3-SHA` - -### TLS v1.0 cipher suites - -`NULL-MD5` -`NULL-SHA` -`RC4-MD5` -`RC4-SHA` -`IDEA-CBC-SHA` -`DES-CBC3-SHA` -`DHE-DSS-DES-CBC3-SHA` -`DHE-RSA-DES-CBC3-SHA` -`ADH-RC4-MD5` -`ADH-DES-CBC3-SHA` - -### AES cipher suites from RFC 3268, extending TLS v1.0 - -`AES128-SHA` -`AES256-SHA` -`DH-DSS-AES128-SHA` -`DH-DSS-AES256-SHA` -`DH-RSA-AES128-SHA` -`DH-RSA-AES256-SHA` -`DHE-DSS-AES128-SHA` -`DHE-DSS-AES256-SHA` -`DHE-RSA-AES128-SHA` -`DHE-RSA-AES256-SHA` -`ADH-AES128-SHA` -`ADH-AES256-SHA` - -### SEED cipher suites from RFC 4162, extending TLS v1.0 - -`SEED-SHA` -`DH-DSS-SEED-SHA` -`DH-RSA-SEED-SHA` -`DHE-DSS-SEED-SHA` -`DHE-RSA-SEED-SHA` -`ADH-SEED-SHA` - -### GOST cipher suites, extending TLS v1.0 - -`GOST94-GOST89-GOST89` -`GOST2001-GOST89-GOST89` -`GOST94-NULL-GOST94` -`GOST2001-NULL-GOST94` - -### Elliptic curve cipher suites - -`ECDHE-RSA-NULL-SHA` -`ECDHE-RSA-RC4-SHA` -`ECDHE-RSA-DES-CBC3-SHA` -`ECDHE-RSA-AES128-SHA` -`ECDHE-RSA-AES256-SHA` -`ECDHE-ECDSA-NULL-SHA` -`ECDHE-ECDSA-RC4-SHA` -`ECDHE-ECDSA-DES-CBC3-SHA` -`ECDHE-ECDSA-AES128-SHA` -`ECDHE-ECDSA-AES256-SHA` -`AECDH-NULL-SHA` -`AECDH-RC4-SHA` -`AECDH-DES-CBC3-SHA` -`AECDH-AES128-SHA` -`AECDH-AES256-SHA` - -### TLS v1.2 cipher suites - -`NULL-SHA256` -`AES128-SHA256` -`AES256-SHA256` -`AES128-GCM-SHA256` -`AES256-GCM-SHA384` -`DH-RSA-AES128-SHA256` -`DH-RSA-AES256-SHA256` -`DH-RSA-AES128-GCM-SHA256` -`DH-RSA-AES256-GCM-SHA384` -`DH-DSS-AES128-SHA256` -`DH-DSS-AES256-SHA256` -`DH-DSS-AES128-GCM-SHA256` -`DH-DSS-AES256-GCM-SHA384` -`DHE-RSA-AES128-SHA256` -`DHE-RSA-AES256-SHA256` -`DHE-RSA-AES128-GCM-SHA256` -`DHE-RSA-AES256-GCM-SHA384` -`DHE-DSS-AES128-SHA256` -`DHE-DSS-AES256-SHA256` -`DHE-DSS-AES128-GCM-SHA256` -`DHE-DSS-AES256-GCM-SHA384` -`ECDHE-RSA-AES128-SHA256` -`ECDHE-RSA-AES256-SHA384` -`ECDHE-RSA-AES128-GCM-SHA256` -`ECDHE-RSA-AES256-GCM-SHA384` -`ECDHE-ECDSA-AES128-SHA256` -`ECDHE-ECDSA-AES256-SHA384` -`ECDHE-ECDSA-AES128-GCM-SHA256` -`ECDHE-ECDSA-AES256-GCM-SHA384` -`ADH-AES128-SHA256` -`ADH-AES256-SHA256` -`ADH-AES128-GCM-SHA256` -`ADH-AES256-GCM-SHA384` -`AES128-CCM` -`AES256-CCM` -`DHE-RSA-AES128-CCM` -`DHE-RSA-AES256-CCM` -`AES128-CCM8` -`AES256-CCM8` -`DHE-RSA-AES128-CCM8` -`DHE-RSA-AES256-CCM8` -`ECDHE-ECDSA-AES128-CCM` -`ECDHE-ECDSA-AES256-CCM` -`ECDHE-ECDSA-AES128-CCM8` -`ECDHE-ECDSA-AES256-CCM8` - -### Camellia HMAC-Based cipher suites from RFC 6367, extending TLS v1.2 - -`ECDHE-ECDSA-CAMELLIA128-SHA256` -`ECDHE-ECDSA-CAMELLIA256-SHA384` -`ECDHE-RSA-CAMELLIA128-SHA256` -`ECDHE-RSA-CAMELLIA256-SHA384` - -### TLS 1.3 cipher suites - -(Note these ciphers are set with `CURLOPT_TLS13_CIPHERS` and `--tls13-ciphers`) - -`TLS_AES_256_GCM_SHA384` -`TLS_CHACHA20_POLY1305_SHA256` -`TLS_AES_128_GCM_SHA256` -`TLS_AES_128_CCM_8_SHA256` -`TLS_AES_128_CCM_SHA256` - -## wolfSSL - -`RC4-SHA`, -`RC4-MD5`, -`DES-CBC3-SHA`, -`AES128-SHA`, -`AES256-SHA`, -`NULL-SHA`, -`NULL-SHA256`, -`DHE-RSA-AES128-SHA`, -`DHE-RSA-AES256-SHA`, -`DHE-PSK-AES256-GCM-SHA384`, -`DHE-PSK-AES128-GCM-SHA256`, -`PSK-AES256-GCM-SHA384`, -`PSK-AES128-GCM-SHA256`, -`DHE-PSK-AES256-CBC-SHA384`, -`DHE-PSK-AES128-CBC-SHA256`, -`PSK-AES256-CBC-SHA384`, -`PSK-AES128-CBC-SHA256`, -`PSK-AES128-CBC-SHA`, -`PSK-AES256-CBC-SHA`, -`DHE-PSK-AES128-CCM`, -`DHE-PSK-AES256-CCM`, -`PSK-AES128-CCM`, -`PSK-AES256-CCM`, -`PSK-AES128-CCM-8`, -`PSK-AES256-CCM-8`, -`DHE-PSK-NULL-SHA384`, -`DHE-PSK-NULL-SHA256`, -`PSK-NULL-SHA384`, -`PSK-NULL-SHA256`, -`PSK-NULL-SHA`, -`HC128-MD5`, -`HC128-SHA`, -`HC128-B2B256`, -`AES128-B2B256`, -`AES256-B2B256`, -`RABBIT-SHA`, -`NTRU-RC4-SHA`, -`NTRU-DES-CBC3-SHA`, -`NTRU-AES128-SHA`, -`NTRU-AES256-SHA`, -`AES128-CCM-8`, -`AES256-CCM-8`, -`ECDHE-ECDSA-AES128-CCM`, -`ECDHE-ECDSA-AES128-CCM-8`, -`ECDHE-ECDSA-AES256-CCM-8`, -`ECDHE-RSA-AES128-SHA`, -`ECDHE-RSA-AES256-SHA`, -`ECDHE-ECDSA-AES128-SHA`, -`ECDHE-ECDSA-AES256-SHA`, -`ECDHE-RSA-RC4-SHA`, -`ECDHE-RSA-DES-CBC3-SHA`, -`ECDHE-ECDSA-RC4-SHA`, -`ECDHE-ECDSA-DES-CBC3-SHA`, -`AES128-SHA256`, -`AES256-SHA256`, -`DHE-RSA-AES128-SHA256`, -`DHE-RSA-AES256-SHA256`, -`ECDH-RSA-AES128-SHA`, -`ECDH-RSA-AES256-SHA`, -`ECDH-ECDSA-AES128-SHA`, -`ECDH-ECDSA-AES256-SHA`, -`ECDH-RSA-RC4-SHA`, -`ECDH-RSA-DES-CBC3-SHA`, -`ECDH-ECDSA-RC4-SHA`, -`ECDH-ECDSA-DES-CBC3-SHA`, -`AES128-GCM-SHA256`, -`AES256-GCM-SHA384`, -`DHE-RSA-AES128-GCM-SHA256`, -`DHE-RSA-AES256-GCM-SHA384`, -`ECDHE-RSA-AES128-GCM-SHA256`, -`ECDHE-RSA-AES256-GCM-SHA384`, -`ECDHE-ECDSA-AES128-GCM-SHA256`, -`ECDHE-ECDSA-AES256-GCM-SHA384`, -`ECDH-RSA-AES128-GCM-SHA256`, -`ECDH-RSA-AES256-GCM-SHA384`, -`ECDH-ECDSA-AES128-GCM-SHA256`, -`ECDH-ECDSA-AES256-GCM-SHA384`, -`CAMELLIA128-SHA`, -`DHE-RSA-CAMELLIA128-SHA`, -`CAMELLIA256-SHA`, -`DHE-RSA-CAMELLIA256-SHA`, -`CAMELLIA128-SHA256`, -`DHE-RSA-CAMELLIA128-SHA256`, -`CAMELLIA256-SHA256`, -`DHE-RSA-CAMELLIA256-SHA256`, -`ECDHE-RSA-AES128-SHA256`, -`ECDHE-ECDSA-AES128-SHA256`, -`ECDH-RSA-AES128-SHA256`, -`ECDH-ECDSA-AES128-SHA256`, -`ECDHE-RSA-AES256-SHA384`, -`ECDHE-ECDSA-AES256-SHA384`, -`ECDH-RSA-AES256-SHA384`, -`ECDH-ECDSA-AES256-SHA384`, -`ECDHE-RSA-CHACHA20-POLY1305`, -`ECDHE-ECDSA-CHACHA20-POLY1305`, -`DHE-RSA-CHACHA20-POLY1305`, -`ECDHE-RSA-CHACHA20-POLY1305-OLD`, -`ECDHE-ECDSA-CHACHA20-POLY1305-OLD`, -`DHE-RSA-CHACHA20-POLY1305-OLD`, -`ADH-AES128-SHA`, -`QSH`, -`RENEGOTIATION-INFO`, -`IDEA-CBC-SHA`, -`ECDHE-ECDSA-NULL-SHA`, -`ECDHE-PSK-NULL-SHA256`, -`ECDHE-PSK-AES128-CBC-SHA256`, -`PSK-CHACHA20-POLY1305`, -`ECDHE-PSK-CHACHA20-POLY1305`, -`DHE-PSK-CHACHA20-POLY1305`, -`EDH-RSA-DES-CBC3-SHA`, - -## Schannel - -Schannel allows the enabling and disabling of encryption algorithms, but not -specific cipher suites, prior to TLS 1.3. The algorithms are -[defined](https://docs.microsoft.com/windows/desktop/SecCrypto/alg-id) by -Microsoft. - -The algorithms below are for TLS 1.2 and earlier. TLS 1.3 is covered in the -next section. - -There is also the case that the selected algorithm is not supported by the -protocol or does not match the ciphers offered by the server during the SSL -negotiation. In this case curl returns error -`CURLE_SSL_CONNECT_ERROR (35) SEC_E_ALGORITHM_MISMATCH` -and the request fails. - -`CALG_MD2`, -`CALG_MD4`, -`CALG_MD5`, -`CALG_SHA`, -`CALG_SHA1`, -`CALG_MAC`, -`CALG_RSA_SIGN`, -`CALG_DSS_SIGN`, -`CALG_NO_SIGN`, -`CALG_RSA_KEYX`, -`CALG_DES`, -`CALG_3DES_112`, -`CALG_3DES`, -`CALG_DESX`, -`CALG_RC2`, -`CALG_RC4`, -`CALG_SEAL`, -`CALG_DH_SF`, -`CALG_DH_EPHEM`, -`CALG_AGREEDKEY_ANY`, -`CALG_HUGHES_MD5`, -`CALG_SKIPJACK`, -`CALG_TEK`, -`CALG_CYLINK_MEK`, -`CALG_SSL3_SHAMD5`, -`CALG_SSL3_MASTER`, -`CALG_SCHANNEL_MASTER_HASH`, -`CALG_SCHANNEL_MAC_KEY`, -`CALG_SCHANNEL_ENC_KEY`, -`CALG_PCT1_MASTER`, -`CALG_SSL2_MASTER`, -`CALG_TLS1_MASTER`, -`CALG_RC5`, -`CALG_HMAC`, -`CALG_TLS1PRF`, -`CALG_HASH_REPLACE_OWF`, -`CALG_AES_128`, -`CALG_AES_192`, -`CALG_AES_256`, -`CALG_AES`, -`CALG_SHA_256`, -`CALG_SHA_384`, -`CALG_SHA_512`, -`CALG_ECDH`, -`CALG_ECMQV`, -`CALG_ECDSA`, -`CALG_ECDH_EPHEM`, - -As of curl 7.77.0, you can also pass `SCH_USE_STRONG_CRYPTO` as a cipher name -to [constrain the set of available ciphers as specified in the Schannel -documentation](https://docs.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-server-2022). -Note that the supported ciphers in this case follow the OS version, so if you -are running an outdated OS you might still be supporting weak ciphers. - -### TLS 1.3 cipher suites - -You can set TLS 1.3 ciphers for Schannel by using `CURLOPT_TLS13_CIPHERS` or -`--tls13-ciphers` with the names below. - -If TLS 1.3 cipher suites are set then libcurl adds or restricts Schannel TLS -1.3 algorithms automatically. Essentially, libcurl is emulating support for -individual TLS 1.3 cipher suites since Schannel does not support it directly. - -`TLS_AES_256_GCM_SHA384` -`TLS_AES_128_GCM_SHA256` -`TLS_CHACHA20_POLY1305_SHA256` -`TLS_AES_128_CCM_8_SHA256` -`TLS_AES_128_CCM_SHA256` - -Note if you set TLS 1.3 ciphers without also setting the minimum TLS version -to 1.3 then it is possible Schannel may negotiate an earlier TLS version and -cipher suite if your libcurl and OS settings allow it. You can set the minimum -TLS version by using `CURLOPT_SSLVERSION` or `--tlsv1.3`. - -## BearSSL - -BearSSL ciphers can be specified by either the OpenSSL name (`ECDHE-RSA-AES128-GCM-SHA256`) or the IANA name (`TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`). - -Since BearSSL 0.1: - -`DES-CBC3-SHA` -`AES128-SHA` -`AES256-SHA` -`AES128-SHA256` -`AES256-SHA256` -`AES128-GCM-SHA256` -`AES256-GCM-SHA384` -`ECDH-ECDSA-DES-CBC3-SHA` -`ECDH-ECDSA-AES128-SHA` -`ECDH-ECDSA-AES256-SHA` -`ECDHE-ECDSA-DES-CBC3-SHA` -`ECDHE-ECDSA-AES128-SHA` -`ECDHE-ECDSA-AES256-SHA` -`ECDH-RSA-DES-CBC3-SHA` -`ECDH-RSA-AES128-SHA` -`ECDH-RSA-AES256-SHA` -`ECDHE-RSA-DES-CBC3-SHA` -`ECDHE-RSA-AES128-SHA` -`ECDHE-RSA-AES256-SHA` -`ECDHE-ECDSA-AES128-SHA256` -`ECDHE-ECDSA-AES256-SHA384` -`ECDH-ECDSA-AES128-SHA256` -`ECDH-ECDSA-AES256-SHA384` -`ECDHE-RSA-AES128-SHA256` -`ECDHE-RSA-AES256-SHA384` -`ECDH-RSA-AES128-SHA256` -`ECDH-RSA-AES256-SHA384` -`ECDHE-ECDSA-AES128-GCM-SHA256` -`ECDHE-ECDSA-AES256-GCM-SHA384` -`ECDH-ECDSA-AES128-GCM-SHA256` -`ECDH-ECDSA-AES256-GCM-SHA384` -`ECDHE-RSA-AES128-GCM-SHA256` -`ECDHE-RSA-AES256-GCM-SHA384` -`ECDH-RSA-AES128-GCM-SHA256` -`ECDH-RSA-AES256-GCM-SHA384` - -Since BearSSL 0.2: - -`ECDHE-RSA-CHACHA20-POLY1305` -`ECDHE-ECDSA-CHACHA20-POLY1305` - -Since BearSSL 0.6: - -`AES128-CCM` -`AES256-CCM` -`AES128-CCM8` -`AES256-CCM8` -`ECDHE-ECDSA-AES128-CCM` -`ECDHE-ECDSA-AES256-CCM` -`ECDHE-ECDSA-AES128-CCM8` -`ECDHE-ECDSA-AES256-CCM8` +or +[`CURLOPT_TLS13_CIPHERS`](https://curl.se/libcurl/c/CURLOPT_TLS13_CIPHERS.html) +users can control which cipher suites to consider when negotiating TLS 1.3 +connections. With option +[`--ciphers`](https://curl.se/docs/manpage.html#--ciphers) +or +[`CURLOPT_SSL_CIPHER_LIST`](https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html) +users can control which cipher suites to consider when negotiating +TLS 1.2 (1.1, 1.0) connections. + +By default, curl may negotiate TLS 1.3 and TLS 1.2 connections, so the cipher +suites considered when negotiating a TLS connection are a union of the TLS 1.3 +and TLS 1.2 cipher suites. If you want curl to consider only TLS 1.3 cipher +suites for the connection, you have to set the minimum TLS version to 1.3 by +using [`--tlsv1.3`](https://curl.se/docs/manpage.html#--tlsv13) +or [`CURLOPT_SSLVERSION`](https://curl.se/libcurl/c/CURLOPT_SSLVERSION.html) +with `CURL_SSLVERSION_TLSv1_3`. + +Both the TLS 1.3 and TLS 1.2 cipher options expect a list of cipher suites +separated by colons (`:`). This list is parsed opportunistically, cipher suites +that are not recognized or implemented are ignored. As long as there is at +least one recognized cipher suite in the list, the list is considered valid. + +For both the TLS 1.3 and TLS 1.2 cipher options, the order in which the +cipher suites are specified determine the preference of them. When negotiating +a TLS connection the server picks a cipher suite from the intersection of the +cipher suites supported by the server and the cipher suites sent by curl. If +the server is configured to honor the client's cipher preference, the first +common cipher suite in the list sent by curl is chosen. + +## TLS 1.3 cipher suites + +Setting TLS 1.3 cipher suites is supported by curl with +OpenSSL (1.1.1+, curl 7.61.0+), LibreSSL (3.4.1+, curl 8.3.0+), +wolfSSL (curl 8.10.0+), mbedTLS (3.6.0+, curl 8.10.0+) and +Schannel (curl 7.85.0+). + +The list of cipher suites that can be used for the `--tls13-ciphers` option: +``` +TLS_AES_128_GCM_SHA256 +TLS_AES_256_GCM_SHA384 +TLS_CHACHA20_POLY1305_SHA256 +TLS_AES_128_CCM_SHA256 +TLS_AES_128_CCM_8_SHA256 +``` + +### wolfSSL notes + +In addition to above list the following cipher suites can be used: +`TLS_SM4_GCM_SM3` `TLS_SM4_CCM_SM3` `TLS_SHA256_SHA256` `TLS_SHA384_SHA384`. +Usage of these cipher suites is not recommended. (The last two cipher suites +are NULL ciphers!) + +### Schannel notes + +Schannel does not support setting individual TLS 1.3 cipher suites directly. +To support `--tls13-ciphers` curl emulates it by adding or restricting +algorithms to use. Due to this the specified order of preference of the +cipher suites is not taken into account. + +## TLS 1.2 (1.1, 1.0) cipher suites + +Setting TLS 1.2 cipher suites is supported by curl with OpenSSL, LibreSSL, +BoringSSL, mbedTLS (curl 8.8.0+), wolfSSL (curl 7.53.0+), +Secure Transport (curl 7.77.0+) and BearSSL (curl 7.83.0+). Schannel does not +support setting cipher suites directly, but does support setting algorithms +(curl 7.61.0+), see Schannel notes below. + +For TLS 1.2 cipher suites there are multiple naming schemes, the two most used +are with OpenSSL names (e.g. `ECDHE-RSA-AES128-GCM-SHA256`) and IANA names +(e.g. `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`). IANA names of TLS 1.2 cipher +suites look similar to TLS 1.3 cipher suite names, to distinguish them note +that TLS 1.2 names contain `_WITH_`, while TLS 1.3 names do not. When setting +TLS 1.2 cipher suites with curl it is recommended that you use OpenSSL names +as these are most widely recognized by the supported SSL backends. + +The complete list of cipher suites that may be considered for the `--ciphers` +option is extensive, it consists of more than 300 ciphers suites. However, +nowadays for most of them their usage is discouraged, and support for a lot of +them have been removed from the various SSL backends, if ever implemented at +all. + +A shortened list (based on [recommendations by +Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS)) of cipher suites, +which are (mostly) supported by all SSL backends, that can be used for the +`--ciphers` option: +``` +ECDHE-ECDSA-AES128-GCM-SHA256 +ECDHE-RSA-AES128-GCM-SHA256 +ECDHE-ECDSA-AES256-GCM-SHA384 +ECDHE-RSA-AES256-GCM-SHA384 +ECDHE-ECDSA-CHACHA20-POLY1305 +ECDHE-RSA-CHACHA20-POLY1305 +DHE-RSA-AES128-GCM-SHA256 +DHE-RSA-AES256-GCM-SHA384 +DHE-RSA-CHACHA20-POLY1305 +ECDHE-ECDSA-AES128-SHA256 +ECDHE-RSA-AES128-SHA256 +ECDHE-ECDSA-AES128-SHA +ECDHE-RSA-AES128-SHA +ECDHE-ECDSA-AES256-SHA384 +ECDHE-RSA-AES256-SHA384 +ECDHE-ECDSA-AES256-SHA +ECDHE-RSA-AES256-SHA +DHE-RSA-AES128-SHA256 +DHE-RSA-AES256-SHA256 +AES128-GCM-SHA256 +AES256-GCM-SHA384 +AES128-SHA256 +AES256-SHA256 +AES128-SHA +AES256-SHA +DES-CBC3-SHA +``` + +See this [list](https://github.com/curl/curl/blob/master/docs/CIPHERS-TLS12.md) +for a complete list of TLS 1.2 cipher suites. + +### OpenSSL notes + +In addition to specifying a list of cipher suites, OpenSSL also accepts a +format with specific cipher strings (like `TLSv1.2`, `AESGCM`, `CHACHA20`) and +`!`, `-` and `+` operators. Refer to the +[OpenSSL cipher documentation](https://docs.openssl.org/master/man1/openssl-ciphers/#cipher-list-format) +for further information on that format. + +### Schannel notes + +Schannel does not support setting individual TLS 1.2 cipher suites directly. +It only allows the enabling and disabling of encryption algorithms. These are +in the form of `CALG_xxx`, see the [Schannel `ALG_ID` +documentation](https://docs.microsoft.com/windows/desktop/SecCrypto/alg-id) +for a list of these algorithms. Also, (since curl 7.77.0) +`SCH_USE_STRONG_CRYPTO` can be given to pass that flag to Schannel, lookup the +[documentation for the Windows version in +use](https://learn.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel) +to see how that affects the cipher suite selection. When not specifying the +`--chiphers` and `--tl13-ciphers` options curl passes this flag by default. + +## Examples + +```sh +curl \ + --tls13-ciphers TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256 \ + --ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ +ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \ + https://example.com/ +``` +Restrict ciphers to `aes128-gcm` and `chacha20`. Works with OpenSSL, LibreSSL, +mbedTLS and wolfSSL. + +```sh +curl \ + --tlsv1.3 \ + --tls13-ciphers TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256 \ + https://example.com/ +``` +Restrict to only TLS 1.3 with `aes128-gcm` and `chacha20` ciphers. Works with +OpenSSL, LibreSSL, mbedTLS, wolfSSL and Schannel. + +```sh +curl \ + --ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ +ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 \ + https://example.com/ +``` +Restrict TLS 1.2 ciphers to `aes128-gcm` and `chacha20`, use default TLS 1.3 +ciphers (if TLS 1.3 is available). Works with OpenSSL, LibreSSL, BoringSSL, +mbedTLS, wolfSSL, Secure Transport and BearSSL. + +## Further reading +- [OpenSSL cipher suite names documentation](https://docs.openssl.org/master/man1/openssl-ciphers/#cipher-suite-names) +- [wolfSSL cipher support documentation](https://www.wolfssl.com/documentation/manuals/wolfssl/chapter04.html#cipher-support) +- [mbedTLS cipher suites reference](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/ssl__ciphersuites_8h/) +- [Schannel cipher suites documentation](https://learn.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel) +- [BearSSL supported crypto](https://www.bearssl.org/support.html) +- [Secure Transport cipher suite values](https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values) +- [IANA cipher suites list](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4) +- [Wikipedia cipher suite article](https://en.wikipedia.org/wiki/Cipher_suite) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 9fd494408..b361d88af 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -34,13 +34,13 @@ if(BUILD_MISC_DOCS) set(_man_target "${CURL_BINARY_DIR}/docs/${_man_misc}.1") add_custom_command(OUTPUT "${_man_target}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND "${PERL_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/scripts/cd2nroff "${_man_misc}.md" > "${_man_target}" + COMMAND "${PERL_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/cd2nroff" "${_man_misc}.md" > "${_man_target}" DEPENDS "${_man_misc}.md" VERBATIM ) add_custom_target("curl-generate-${_man_misc}.1" ALL DEPENDS "${_man_target}") if(NOT CURL_DISABLE_INSTALL) - install(FILES "${_man_target}" DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES "${_man_target}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") endif() endforeach() endif() diff --git a/docs/CONTRIBUTE.md b/docs/CONTRIBUTE.md index 156ea0bef..8860f87c6 100644 --- a/docs/CONTRIBUTE.md +++ b/docs/CONTRIBUTE.md @@ -24,7 +24,7 @@ Before posting to one of the curl mailing lists, please read up on the We also hang out on IRC in #curl on libera.chat If you are at all interested in the code side of things, consider clicking -'watch' on the [curl repo on GitHub](https://github.com/curl/curl) to be +'watch' on the [curl repository on GitHub](https://github.com/curl/curl) to be notified of pull requests and new issues posted there. ## License and copyright @@ -83,11 +83,11 @@ fix one bug at a time and send them as separate patches. ### Write Separate Changes -It is annoying when you get a huge patch from someone that is said to fix 511 -odd problems, but discussions and opinions do not agree with 510 of them - or -509 of them were already fixed in a different way. Then the person merging -this change needs to extract the single interesting patch from somewhere -within the huge pile of source, and that creates a lot of extra work. +It is annoying when you get a huge patch from someone that is said to fix 11 +odd problems, but discussions and opinions do not agree with 10 of them - or 9 +of them were already fixed in a different way. Then the person merging this +change needs to extract the single interesting patch from somewhere within the +huge pile of source, and that creates a lot of extra work. Preferably, each fix that corrects a problem should be in its own patch/commit with its own description/commit message stating exactly what they correct so @@ -129,9 +129,9 @@ If you do not have test cases or perhaps you have done something that is hard to write tests for, do explain exactly how you have otherwise tested and verified your changes. -## Submit Your Changes +# Submit Your Changes -### How to get your changes into the main sources +## Get your changes merged Ideally you file a [pull request on GitHub](https://github.com/curl/curl/pulls), but you can also send your plain @@ -153,7 +153,7 @@ fix nits/flaws. This is important. We take lack of replies as a sign that you are not anxious to get your patch accepted and we tend to simply drop such changes. -### About pull requests +## About pull requests With GitHub it is easy to send a [pull request](https://github.com/curl/curl/pulls) to the curl project to have @@ -185,7 +185,23 @@ checks and qualifications this pull request must also receive more "votes" of user support. More signs that people want this to happen. It could be in the form of messages saying so, or thumbs-up reactions on GitHub. -### Making quality changes +## When the pull request is approved + +If it does not seem to get approved when you think it is ready - feel free to +ask for approval. + +Once your pull request has been approved it can be merged by a maintainer. + +For new features, or changes, we require that the *feature window* is open for +the pull request to be merged. This is typically a three week period that +starts ten days after a previous release. New features submitted as pull +requests while the window is closed simply have to wait until it opens to get +merged. + +If time passes without your approved pull request gets merged: feel free to +ask what more you can do to make it happen. + +## Making quality changes Make the patch against as recent source versions as possible. @@ -193,48 +209,22 @@ If you have followed the tips in this document and your patch still has not been incorporated or responded to after some weeks, consider resubmitting it to the list or better yet: change it to a pull request. -### Commit messages +## Commit messages -A short guide to how to write git commit messages in the curl project. +How to write git commit messages in the curl project. ---- start ---- [area]: [short line describing the main effect] -- empty line -- [full description, no wider than 72 columns that describes as much as possible as to why this change is made, and possibly what things - it fixes and everything else that is related, with unwieldy URLs replaced - with references like [0], [1], etc.] - -- empty line -- - [[0] URL - Reference to a URL in the description, almost like Markdown; - the last numbered reference is followed by an -- empty line -- ] - [Follow-up to {shorthash} - if this fixes or continues a previous commit; - add a Ref: that commit's PR or issue if it's not a small, obvious fix; - followed by an -- empty line -- ] - [Bug: URL to the source of the report or more related discussion; use Fixes - for GitHub issues instead when that is appropriate] - [Approved-by: John Doe - credit someone who approved the PR; if you are - committing this for someone else using --author=... you do not need this - as you are implicitly approving it by committing] - [Authored-by: John Doe - credit the original author of the code; only use - this if you cannot use "git commit --author=..."] - [Signed-off-by: John Doe - we do not use this, but do not bother removing it] - [whatever-else-by: credit all helpers, finders, doers; try to use one of - the following keywords if at all possible, for consistency: - Acked-by:, Assisted-by:, Co-authored-by:, Found-by:, Reported-by:, - Reviewed-by:, Suggested-by:, Tested-by:] - [Ref: #1234 - if this is related to a GitHub issue or PR, possibly one that - has already been closed] - [Ref: URL to more information about the commit; use Bug: instead for - a reference to a bug on another bug tracker] - [Fixes #1234 - if this closes a GitHub issue; GitHub closes the issue once - this commit is merged] - [Closes #1234 - if this closes a GitHub PR; GitHub closes the PR once this - commit is merged] - ---- stop ---- - -The first line is a succinct description of the change: - - - use the imperative, present tense: "change" not "changed" nor "changes" + it fixes and everything else that is related, + -- end -- + +The first line is a succinct description of the change and should ideally work +as a single line in the RELEASE NOTES. + + - use the imperative, present tense: **change** not "changed" nor "changes" - do not capitalize the first letter - no period (.) at the end @@ -242,72 +232,66 @@ The `[area]` in the first line can be `http2`, `cookies`, `openssl` or similar. There is no fixed list to select from but using the same "area" as other related changes could make sense. -Do not forget to use commit --author=... if you commit someone else's work, and -make sure that you have your own user and email setup correctly in git before -you commit. +## Commit message keywords -Add whichever header lines as appropriate, with one line per person if more -than one person was involved. There is no need to credit yourself unless you -are using --author=... which hides your identity. Do not include people's -email addresses in headers to avoid spam, unless they are already public from -a previous commit; saying `{userid} on github` is OK. +Use the following ways to improve the message and provide pointers to related +work. -### Write Access to git Repository +- `Follow-up to {shorthash}` - if this fixes or continues a previous commit; +add a `Ref:` that commit's PR or issue if it is not a small, obvious fix; +followed by an empty line -If you are a frequent contributor, you may be given push access to the git -repository and then you are able to push your changes straight into the git -repo instead of sending changes as pull requests or by mail as patches. +- `Bug: URL` to the source of the report or more related discussion; use +`Fixes` for GitHub issues instead when that is appropriate. -Just ask if this is what you would want. You are required to have posted -several high quality patches first, before you can be granted push access. - -### How To Make a Patch with git - -You need to first checkout the repository: - - git clone https://github.com/curl/curl.git - -You then proceed and edit all the files you like and you commit them to your -local repository: - - git commit [file] +- `Approved-by: John Doe` - credit someone who approved the PR. -As usual, group your commits so that you commit all changes at once that -constitute a logical change. +- `Authored-by: John Doe` - credit the original author of the code; only use +this if you cannot use `git commit --author=...`. -Once you have done all your commits and you are happy with what you see, you -can make patches out of your changes that are suitable for mailing: +- `Signed-off-by: John Doe` - we do not use this, but do not bother removing + it. - git format-patch remotes/origin/master +- `whatever-else-by:` credit all helpers, finders, doers; try to use one of +the following keywords if at all possible, for consistency: `Acked-by:`, +`Assisted-by:`, `Co-authored-by:`, `Found-by:`, `Reported-by:`, +`Reviewed-by:`, `Suggested-by:`, `Tested-by:`. -This creates files in your local directory named `NNNN-[name].patch` for each -commit. +- `Ref: #1234` - if this is related to a GitHub issue or PR, possibly one that +has already been closed. -Now send those patches off to the curl-library list. You can of course opt to -do that with the 'git send-email' command. +- `Ref: URL` to more information about the commit; use `Bug:` instead for a +reference to a bug on another bug tracker] -### How To Make a Patch without git +- `Fixes #1234` - if this fixes a GitHub issue; GitHub closes the issue once +this commit is merged. -Keep a copy of the unmodified curl sources. Make your changes in a separate -source tree. When you think you have something that you want to offer the -curl community, use GNU diff to generate patches. +- `Closes #1234` - if this merges a GitHub PR; GitHub closes the PR once this +commit is merged. -If you have modified a single file, try something like: +Do not forget to use commit with `--author` if you commit someone else's work, +and make sure that you have your own user and email setup correctly in git +before you commit. - diff -u unmodified-file.c my-changed-one.c > my-fixes.diff +Add whichever header lines as appropriate, with one line per person if more +than one person was involved. There is no need to credit yourself unless you +are using `--author` which hides your identity. Do not include people's email +addresses in headers to avoid spam, unless they are already public from a +previous commit; saying `{userid} on github` is OK. -If you have modified several files, possibly in different directories, you -can use diff recursively: +## Push Access - diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff +If you are a frequent contributor, you may be given push access to the git +repository and then you are able to push your changes straight into the git +repository instead of sending changes as pull requests or by mail as patches. -The GNU diff and GNU patch tools exist for virtually all platforms, including -all kinds of Unixes and Windows. +Just ask if this is what you would want. You are required to have posted +several high quality patches first, before you can be granted push access. -### Useful resources +## Useful resources - [Webinar on getting code into cURL](https://www.youtube.com/watch?v=QmZ3W1d6LQI) -## Update copyright and license information +# Update copyright and license information There is a CI job called **REUSE compliance / check** that runs on every pull request and commit to verify that the *REUSE state* of all files are still @@ -315,9 +299,9 @@ fine. This means that all files need to have their license and copyright information clearly stated. Ideally by having the standard curl source code header, with -the SPDX-License-Identifier included. If the header does not work, you can use a -smaller header or add the information for a specific file to the `REUSE.toml` -file. +the `SPDX-License-Identifier` included. If the header does not work, you can +use a smaller header or add the information for a specific file to the +`REUSE.toml` file. You can manually verify the copyright and compliance status by running the [REUSE helper tool](https://github.com/fsfe/reuse-tool): `reuse lint` diff --git a/docs/CURL-DISABLE.md b/docs/CURL-DISABLE.md index 3409bec01..6080851dd 100644 --- a/docs/CURL-DISABLE.md +++ b/docs/CURL-DISABLE.md @@ -144,6 +144,10 @@ Disable support for proxies Disable the RTSP protocol. +## `CURL_DISABLE_SHA512_256` + +Disable the SHA-512/256 hash algorithm. + ## `CURL_DISABLE_SHUFFLE_DNS` Disable the shuffle DNS feature diff --git a/docs/DEPRECATE.md b/docs/DEPRECATE.md index 6ad931723..3d8c8af95 100644 --- a/docs/DEPRECATE.md +++ b/docs/DEPRECATE.md @@ -23,6 +23,36 @@ and use TLS 1.3, or else it is not good enough. As of May 2024, the libraries that need to get fixed to remain supported after May 2025 are: BearSSL and Secure Transport. +## Hyper + +Hyper is an alternative HTTP backend for curl. It uses the hyper library and +could in theory be used for HTTP/1, HTTP/2 and even HTTP/3 in the future with +curl. + +The original plan and goal was that we would add this HTTP alternative (using +a memory-safe library) and that users could eventually build and use libcurl +exactly as previously but with parts of the core being more memory-safe. + +The hyper implementation ran into some snags and 10-15 tests and HTTP/2 +support have remained disabled with hyper. For these reasons, hyper support +has remained tagged EXPERIMENTAL. + +It is undoubtedly hard work to fix these remaining problems, as they typically +require both rust and C knowledge in addition to deep HTTP familiarity. There +does not seem to be that many persons interested or available for this +challenge. Meanwhile, there is little if any demand for hyper from existing +(lib)curl users. + +Finally: having support for hyper in curl has a significant cost: we need to +maintain and develop a lot of functionality and tests twice to make sure +libcurl works identically using either HTTP backend. + +The only way to keep hyper support in curl is to give it a good polish by +someone with time, skill and energy to spend on this task. + +Unless a significant overhaul has proven to be in progress, hyper support is +removed from curl after February 2025. + ## Past removals - Pipelining @@ -32,6 +62,6 @@ May 2025 are: BearSSL and Secure Transport. - Support for systems without 64-bit data types - NSS - gskit - - mingw v1 + - MinGW v1 - NTLM_WB - space-separated `NOPROXY` patterns diff --git a/docs/ECH.md b/docs/ECH.md index 9c7cbf15f..615e63da2 100644 --- a/docs/ECH.md +++ b/docs/ECH.md @@ -231,7 +231,7 @@ purpose. This code also implements the opportunistic (``--ech true``) or hard-fa Other than that, the main additions are in ``lib/doh.c`` where we re-use ``dohprobe()`` to retrieve an HTTPS RR value for the target -domain. If such a value is found, that is stored using a new ``store_https()`` +domain. If such a value is found, that is stored using a new ``doh_store_https()`` function in a new field in the ``dohentry`` structure. The qname for the DoH query is modified if the port number is not 443, as diff --git a/docs/EXPERIMENTAL.md b/docs/EXPERIMENTAL.md index 23be5a5c3..b1e3710ed 100644 --- a/docs/EXPERIMENTAL.md +++ b/docs/EXPERIMENTAL.md @@ -40,6 +40,8 @@ Graduation requirements: - HTTP/1 and HTTP/2 support, including multiplexing +(Hyper is marked for deprecation. It cannot graduate.) + ### HTTP/3 support (non-ngtcp2 backends) Graduation requirements: @@ -49,11 +51,12 @@ Graduation requirements: - Using HTTP/3 with the given build should perform without risking busy-loops -### The rustls backend +### The Rustls backend Graduation requirements: - a reasonable expectation of a stable API going forward. +- a sufficient approach to avoid using weak random numbers ### WebSocket diff --git a/docs/FAQ b/docs/FAQ index 12c743bb5..943a74199 100644 --- a/docs/FAQ +++ b/docs/FAQ @@ -84,8 +84,8 @@ FAQ 5.1 Is libcurl thread-safe? 5.2 How can I receive all data into a large memory chunk? 5.3 How do I fetch multiple files with libcurl? - 5.4 Does libcurl do Winsock initialization on win32 systems? - 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + 5.4 Does libcurl do Winsock initialization on Win32 systems? + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on Win32 ? 5.6 What about Keep-Alive or persistent connections? 5.7 Link errors when building libcurl on Windows 5.8 libcurl.so.X: open failed: No such file or directory @@ -424,7 +424,7 @@ FAQ curl can be built to use one of the following SSL alternatives: OpenSSL, LibreSSL, BoringSSL, AWS-LC, GnuTLS, wolfSSL, mbedTLS, Secure Transport - (native iOS/OS X), Schannel (native Windows), BearSSL or Rustls. They all + (native iOS/macOS), Schannel (native Windows), BearSSL or Rustls. They all have their pros and cons, and we try to maintain a comparison of them here: https://curl.se/docs/ssl-compared.html @@ -566,7 +566,7 @@ FAQ 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? curl adheres to the HTTP spec, which basically means you can play with *any* - protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and + protocol that is built on top of HTTP. Protocols such as SOAP, WebDAV and XML-RPC are all such ones. You can use -X to set custom requests and -H to set custom headers (or replace internally generated ones). @@ -604,7 +604,7 @@ FAQ curl -d ' with spaces ' example.com Exactly what kind of quotes and how to do this is entirely up to the shell - or command line interpreter that you are using. For most unix shells, you + or command line interpreter that you are using. For most Unix shells, you can more or less pick either single (') or double (") quotes. For Windows/DOS command prompts you must use double (") quotes, and if the option string contains inner double quotes you can escape them with a @@ -1174,11 +1174,11 @@ FAQ only reusable, but you are even encouraged to reuse it if you can, as that will enable libcurl to use persistent connections. - 5.4 Does libcurl do Winsock initialization on win32 systems? + 5.4 Does libcurl do Winsock initialization on Win32 systems? Yes, if told to in the curl_global_init() call. - 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? + 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on Win32 ? Yes, but you cannot open a FILE * and pass the pointer to a DLL and have that DLL use the FILE * (as the DLL and the client application cannot access @@ -1352,7 +1352,7 @@ FAQ then you have to work with what you are given. The LIST output format is entirely at the server's own liking and the NLST output does not reveal any types and in many cases does not even include all the directory entries. - Also, both LIST and NLST tend to hide unix-style hidden files (those that + Also, both LIST and NLST tend to hide Unix-style hidden files (those that start with a dot) by default so you need to do "LIST -a" or similar to see them. diff --git a/docs/FEATURES.md b/docs/FEATURES.md index ef5fd0fc1..f36615494 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -38,13 +38,13 @@ SPDX-License-Identifier: curl - asynchronous name resolving - both a push and a pull style interface - international domain names (IDN) - - transfer late limiting + - transfer rate limiting - stable API and ABI - TCP keep alive - TCP Fast Open - DNS cache (that can be shared between transfers) - non-blocking single-threaded parallel transfers - - unix domain sockets to server or proxy + - Unix domain sockets to server or proxy - DNS-over-HTTPS - uses non-blocking name resolves - selectable name resolver backend diff --git a/docs/HISTORY.md b/docs/HISTORY.md index 96cf049dc..0ec3cd159 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -419,14 +419,14 @@ April: added the cyassl backend (later renamed to wolfSSL) February 3: curl 7.75.0 ships with support for Hyper as an HTTP backend - March 31: curl 7.76.0 ships with support for rustls + March 31: curl 7.76.0 ships with support for Rustls July: HSTS is supported 2022 ---- - March: added --json, removed mesalink support +March: added --json, removed mesalink support Public curl releases: 206 Command line options: 245 @@ -437,7 +437,34 @@ April: added the cyassl backend (later renamed to wolfSSL) The curl.se website serves 16,500 GB/month over 462M requests, the official docker image has been pulled 4,098,015,431 times. +October: initial WebSocket support + 2023 ---- +March: remove support for curl_off_t < 8 bytes + +March 31: we started working on a new command line tool for URL parsing and +manipulations: trurl. + +May: added support for HTTP/2 over HTTPS proxy. Refuse to resolve .onion. + August: Dropped support for the NSS library + +September: added "variable" support in the command line tool. Dropped support +for the gskit TLS library. + +October: added support for IPFS via HTTP gateway + +December: HTTP/3 support with ngtcp2 is no longer experimental + +2024 +---- + +January: switched to "curldown" for all documentation + +April 24: the curl container has been pulled more than six billion times + +May: experimental support for ECH + +August 9: we adopted the wcurl tool into the curl organization diff --git a/docs/HSTS.md b/docs/HSTS.md deleted file mode 100644 index 85140ab30..000000000 --- a/docs/HSTS.md +++ /dev/null @@ -1,48 +0,0 @@ - - -# HSTS support - -HTTP Strict-Transport-Security. Added as experimental in curl -7.74.0. Supported "for real" since 7.77.0. - -## Standard - -[HTTP Strict Transport Security](https://datatracker.ietf.org/doc/html/rfc6797) - -## Behavior - -libcurl features an in-memory cache for HSTS hosts, so that subsequent -HTTP-only requests to a hostname present in the cache gets internally -"redirected" to the HTTPS version. - -## `curl_easy_setopt()` options: - - - `CURLOPT_HSTS_CTRL` - enable HSTS for this easy handle - - `CURLOPT_HSTS` - specify filename where to store the HSTS cache on close - (and possibly read from at startup) - -## curl command line options - - - `--hsts [filename]` - enable HSTS, use the file as HSTS cache. If filename - is `""` (no length) then no file is used, only in-memory cache. - -## HSTS cache file format - -Lines starting with `#` are ignored. - -For each hsts entry: - - [host name] "YYYYMMDD HH:MM:SS" - -The `[host name]` is dot-prefixed if it includes subdomains. - -The time stamp is when the entry expires. - -## Possible future additions - - - `CURLOPT_HSTS_PRELOAD` - provide a set of HSTS hostnames to load first - - ability to save to something else than a file diff --git a/docs/HTTP2.md b/docs/HTTP2.md deleted file mode 100644 index 55d3db588..000000000 --- a/docs/HTTP2.md +++ /dev/null @@ -1,108 +0,0 @@ - - -HTTP/2 with curl -================ - -[HTTP/2 Spec](https://www.rfc-editor.org/rfc/rfc7540.txt) -[http2 explained](https://daniel.haxx.se/http2/) - -Build prerequisites -------------------- - - nghttp2 - - OpenSSL, LibreSSL, BoringSSL, GnuTLS, mbedTLS, wolfSSL or Schannel - with a new enough version. - -[nghttp2](https://nghttp2.org/) -------------------------------- - -libcurl uses this 3rd party library for the low level protocol handling -parts. The reason for this is that HTTP/2 is much more complex at that layer -than HTTP/1.1 (which we implement on our own) and that nghttp2 is an already -existing and well functional library. - -We require at least version 1.12.0. - -Over an http:// URL -------------------- - -If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl includes -an upgrade header in the initial request to the host to allow upgrading to -HTTP/2. - -Possibly we can later introduce an option that causes libcurl to fail if it is -not possible to upgrade. Possibly we introduce an option that makes libcurl -use HTTP/2 at once over http:// - -Over an https:// URL --------------------- - -If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl uses ALPN -to negotiate which protocol to continue with. Possibly introduce an option -that causes libcurl to fail if not possible to use HTTP/2. - -`CURL_HTTP_VERSION_2TLS` was added in 7.47.0 as a way to ask libcurl to prefer -HTTP/2 for HTTPS but stick to 1.1 by default for plain old HTTP connections. - -ALPN is the TLS extension that HTTP/2 is expected to use. - -`CURLOPT_SSL_ENABLE_ALPN` is offered to allow applications to explicitly -disable ALPN. - -Multiplexing ------------- - -Starting in 7.43.0, libcurl fully supports HTTP/2 multiplexing, which is the -term for doing multiple independent transfers over the same physical TCP -connection. - -To take advantage of multiplexing, you need to use the multi interface and set -`CURLMOPT_PIPELINING` to `CURLPIPE_MULTIPLEX`. With that bit set, libcurl -attempts to reuse existing HTTP/2 connections and just add a new stream over -that when doing subsequent parallel requests. - -While libcurl sets up a connection to an HTTP server there is a period during -which it does not know if it can pipeline or do multiplexing and if you add -new transfers in that period, libcurl defaults to starting new connections for -those transfers. With the new option `CURLOPT_PIPEWAIT` (added in 7.43.0), you -can ask that a transfer should rather wait and see in case there is a -connection for the same host in progress that might end up being possible to -multiplex on. It favors keeping the number of connections low to the cost of -slightly longer time to first byte transferred. - -Applications ------------- - -We hide HTTP/2's binary nature and convert received HTTP/2 traffic to headers -in HTTP 1.1 style. This allows applications to work unmodified. - -curl tool ---------- - -curl offers the `--http2` command line option to enable use of HTTP/2. - -curl offers the `--http2-prior-knowledge` command line option to enable use of -HTTP/2 without HTTP/1.1 Upgrade. - -Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections. - -curl tool limitations ---------------------- - -The command line tool does not support HTTP/2 server push. It supports -multiplexing when the parallel transfer option is used. - -HTTP Alternative Services -------------------------- - -Alt-Svc is an extension with a corresponding frame (ALTSVC) in HTTP/2 that -tells the client about an alternative "route" to the same content for the same -origin server that you get the response from. A browser or long-living client -can use that hint to create a new connection asynchronously. For libcurl, we -may introduce a way to bring such clues to the application and/or let a -subsequent request use the alternate route automatically. - -[Detailed in RFC 7838](https://datatracker.ietf.org/doc/html/rfc7838) diff --git a/docs/HTTP3.md b/docs/HTTP3.md index c1c6bf249..a7025f173 100644 --- a/docs/HTTP3.md +++ b/docs/HTTP3.md @@ -51,7 +51,7 @@ Building curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3` and OpenSSL does not offer the required APIs for building a QUIC client. You need to use a TLS library that has such APIs and that works with *ngtcp2*. -Build quictls +Build quictls: % git clone --depth 1 -b openssl-3.1.4+quic https://github.com/quictls/openssl % cd openssl @@ -59,7 +59,7 @@ Build quictls % make % make install -Build nghttp3 +Build nghttp3: % cd .. % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 @@ -70,7 +70,7 @@ Build nghttp3 % make % make install -Build ngtcp2 +Build ngtcp2: % cd .. % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 @@ -80,7 +80,7 @@ Build ngtcp2 % make % make install -Build curl +Build curl: % cd .. % git clone https://github.com/curl/curl @@ -94,7 +94,7 @@ For OpenSSL 3.0.0 or later builds on Linux for x86_64 architecture, substitute a ## Build with GnuTLS -Build GnuTLS +Build GnuTLS: % git clone --depth 1 https://gitlab.com/gnutls/gnutls.git % cd gnutls @@ -103,7 +103,7 @@ Build GnuTLS % make % make install -Build nghttp3 +Build nghttp3: % cd .. % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 @@ -114,7 +114,7 @@ Build nghttp3 % make % make install -Build ngtcp2 +Build ngtcp2: % cd .. % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 @@ -124,7 +124,7 @@ Build ngtcp2 % make % make install -Build curl +Build curl: % cd .. % git clone https://github.com/curl/curl @@ -136,7 +136,7 @@ Build curl ## Build with wolfSSL -Build wolfSSL +Build wolfSSL: % git clone https://github.com/wolfSSL/wolfssl.git % cd wolfssl @@ -145,7 +145,7 @@ Build wolfSSL % make % make install -Build nghttp3 +Build nghttp3: % cd .. % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 @@ -156,7 +156,7 @@ Build nghttp3 % make % make install -Build ngtcp2 +Build ngtcp2: % cd .. % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 @@ -166,7 +166,7 @@ Build ngtcp2 % make % make install -Build curl +Build curl: % cd .. % git clone https://github.com/curl/curl @@ -210,7 +210,7 @@ Build curl: QUIC support is **EXPERIMENTAL** -Build OpenSSL 3.3.1 +Build OpenSSL 3.3.1: % cd .. % git clone -b openssl-3.3.1 https://github.com/openssl/openssl @@ -219,7 +219,7 @@ Build OpenSSL 3.3.1 % make % make install -Build nghttp3 +Build nghttp3: % cd .. % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 @@ -317,15 +317,15 @@ directory, or copy `msquic.dll` and `msh3.dll` from that directory to the Use only HTTP/3: - curl --http3-only https://example.org:4433/ + % curl --http3-only https://example.org:4433/ Use HTTP/3 with fallback to HTTP/2 or HTTP/1.1 (see "HTTPS eyeballing" below): - curl --http3 https://example.org:4433/ + % curl --http3 https://example.org:4433/ Upgrade via Alt-Svc: - curl --alt-svc altsvc.cache https://curl.se/ + % curl --alt-svc altsvc.cache https://curl.se/ See this [list of public HTTP/3 servers](https://bagder.github.io/HTTP3-test/) @@ -383,7 +383,7 @@ ones. You can easily create huge local files like `truncate -s=8G 8GB` - they are huge but do not occupy that much space on disk since they are just big holes. -In a Debian setup you can install **apache2**. It runs on port 80 and has a +In a Debian setup you can install apache2. It runs on port 80 and has a document root in `/var/www/html`. Download the 8GB file from apache with `curl localhost/8GB -o dev/null` @@ -396,23 +396,23 @@ You can select either or both of these server solutions. ### nghttpx -Get, build and install **quictls**, **nghttp3** and **ngtcp2** as described +Get, build and install quictls, nghttp3 and ngtcp2 as described above. -Get, build and install **nghttp2**: +Get, build and install nghttp2: - git clone https://github.com/nghttp2/nghttp2.git - cd nghttp2 - autoreconf -fi - PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/daniel/build-quictls/lib/pkgconfig:/home/daniel/build-nghttp3/lib/pkgconfig:/home/daniel/build-ngtcp2/lib/pkgconfig LDFLAGS=-L/home/daniel/build-quictls/lib CFLAGS=-I/home/daniel/build-quictls/include ./configure --enable-maintainer-mode --prefix=/home/daniel/build-nghttp2 --disable-shared --enable-app --enable-http3 --without-jemalloc --without-libxml2 --without-systemd - make && make install + % git clone https://github.com/nghttp2/nghttp2.git + % cd nghttp2 + % autoreconf -fi + % PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/daniel/build-quictls/lib/pkgconfig:/home/daniel/build-nghttp3/lib/pkgconfig:/home/daniel/build-ngtcp2/lib/pkgconfig LDFLAGS=-L/home/daniel/build-quictls/lib CFLAGS=-I/home/daniel/build-quictls/include ./configure --enable-maintainer-mode --prefix=/home/daniel/build-nghttp2 --disable-shared --enable-app --enable-http3 --without-jemalloc --without-libxml2 --without-systemd + % make && make install Run the local h3 server on port 9443, make it proxy all traffic through to HTTP/1 on localhost port 80. For local toying, we can just use the test cert that exists in curl's test dir. - CERT=$CURLSRC/tests/stunnel.pem - $HOME/bin/nghttpx $CERT $CERT --backend=localhost,80 \ + % CERT=$CURLSRC/tests/stunnel.pem + % $HOME/bin/nghttpx $CERT $CERT --backend=localhost,80 \ --frontend="localhost,9443;quic" ### Caddy @@ -429,7 +429,7 @@ localhost:7443 { Then run Caddy: - ./caddy start + % ./caddy start Making requests to `https://localhost:7443` should tell you which protocol is being used. diff --git a/docs/INSTALL.md b/docs/INSTALL.md index d00f22dcb..85de7a1ed 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -154,6 +154,16 @@ conflicting identical symbol names. When you build with multiple TLS backends, you can select the active one at runtime when curl starts up. +## MultiSSL and HTTP/3 + +HTTP/3 needs QUIC and QUIC needs TLS. Building libcurl with HTTP/3 and QUIC +support is not compatible with the MultiSSL feature: they are mutually +exclusive. If you need MultiSSL in your build, you cannot have HTTP/3 support +and vice versa. + +libcurl can only use a single TLS library with QUIC and that *same* TLS +library needs to be used for the other TLS using protocols. + ## Configure finding libs in wrong directory When the configure script checks for third-party libraries, it adds those @@ -243,7 +253,7 @@ Note: The pre-processor settings can be found using the Visual Studio IDE under "Project -> Properties -> Configuration Properties -> C/C++ -> Preprocessor". -## Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds +## Using BSD-style lwIP instead of Winsock TCP/IP stack in Windows builds In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack it is necessary to make the definition of the preprocessor symbol `USE_LWIPSOCK` @@ -511,14 +521,14 @@ disabling support for some feature (run `./configure --help` to see them all): - `--disable-mime` (MIME API) - `--disable-netrc` (.netrc file) - `--disable-ntlm` (NTLM authentication) - - `--disable-ntlm-wb` (NTLM WinBind) + - `--disable-ntlm-wb` (NTLM winbind) - `--disable-progress-meter` (graphical progress meter in library) - `--disable-proxy` (HTTP and SOCKS proxies) - `--disable-pthreads` (multi-threading) - `--disable-socketpair` (socketpair for asynchronous name resolving) - `--disable-threaded-resolver` (threaded name resolver) - `--disable-tls-srp` (Secure Remote Password authentication for TLS) - - `--disable-unix-sockets` (UNIX sockets) + - `--disable-unix-sockets` (Unix sockets) - `--disable-verbose` (eliminates debugging strings and error code strings) - `--disable-versioned-symbols` (versioned symbols) - `--enable-symbol-hiding` (eliminates unneeded symbols in the shared library) diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md index ff77bac77..ae77f0e54 100644 --- a/docs/INTERNALS.md +++ b/docs/INTERNALS.md @@ -35,7 +35,7 @@ versions of libs and build tools. - MIT Kerberos 1.2.4 - Heimdal ? - nghttp2 1.15.0 - - WinSock 2.2 (on Windows 95+ and Windows CE .NET 4.1+) + - Winsock 2.2 (on Windows 95+ and Windows CE .NET 4.1+) ## Build tools diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index be44d16c6..2b04630a9 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -12,11 +12,9 @@ check the changelog of the current development status, as one or more of these problems may have been fixed or changed somewhat since this was written. 1. HTTP - 1.2 hyper is slow - 1.5 Expect-100 meets 417 2. TLS - 2.1 IMAPS connection fails with rustls error + 2.1 IMAPS connection fails with Rustls error 2.3 Unable to use PKCS12 certificate with Secure Transport 2.4 Secure Transport does not import PKCS#12 client certificates without a password 2.5 Client cert handling with Issuer DN differs between backends @@ -27,7 +25,6 @@ problems may have been fixed or changed somewhat since this was written. 3. Email protocols 3.1 IMAP SEARCH ALL truncated response 3.2 No disconnect command - 3.3 POP3 expects "CRLF.CRLF" eob for some single-line responses 3.4 AUTH PLAIN for SMTP is not working on all servers 3.5 APOP authentication fails on POP3 3.6 POP3 issue when reading small chunks @@ -39,22 +36,19 @@ problems may have been fixed or changed somewhat since this was written. 5. Build and portability issues 5.1 OS400 port requires deprecated IBM library 5.2 curl-config --libs contains private details - 5.3 building for old macOS fails with gcc - 5.5 cannot handle Unicode arguments in non-Unicode builds on Windows - 5.6 cygwin: make install installs curl-config.1 twice + 5.6 Cygwin: make install installs curl-config.1 twice 5.11 configure --with-gssapi with Heimdal is ignored on macOS 5.12 flaky CI builds 5.13 long paths are not fully supported on Windows - 5.14 Windows Unicode builds use homedir in current locale 5.15 Unicode on Windows 6. Authentication - 6.1 NTLM authentication and unicode 6.2 MIT Kerberos for Windows build 6.3 NTLM in system context uses wrong name 6.5 NTLM does not support password with § character 6.6 libcurl can fail to try alternatives with --proxy-any 6.7 Do not clear digest for single realm + 6.8 Heimdal memory leaks 6.9 SHA-256 digest not supported in Windows SSPI builds 6.10 curl never completes Negotiate over HTTP 6.11 Negotiate on Windows fails @@ -62,9 +56,6 @@ problems may have been fixed or changed somewhat since this was written. 6.13 Negotiate against Hadoop HDFS 7. FTP - 7.1 FTP upload fails if remembered directory is deleted - 7.2 Implicit FTPS upload timeout - 7.3 FTP with NOBODY and FAILONERROR 7.4 FTP with ACCT 7.12 FTPS directory listing hangs on Windows with Schannel @@ -73,10 +64,9 @@ problems may have been fixed or changed somewhat since this was written. 9.2 wolfssh: publickey auth does not work 9.3 Remote recursive folder creation with SFTP 9.4 libssh blocking and infinite loop problem - 9.5 cygwin: "WARNING: UNPROTECTED PRIVATE KEY FILE!" + 9.5 Cygwin: "WARNING: UNPROTECTED PRIVATE KEY FILE!" 10. SOCKS - 10.3 FTPS over SOCKS 11. Internals 11.1 gssapi library name + version is missing in curl_version_info() @@ -85,6 +75,8 @@ problems may have been fixed or changed somewhat since this was written. 11.4 HTTP test server 'connection-monitor' problems 11.5 Connection information when using TCP Fast Open 11.6 test cases sometimes timeout + 11.7 CURLOPT_CONNECT_TO does not work for HTTPS proxy + 11.8 WinIDN test failures 12. LDAP 12.1 OpenLDAP hangs after returning results @@ -101,11 +93,9 @@ problems may have been fixed or changed somewhat since this was written. 15.3 unusable tool_hugehelp.c with MinGW 15.6 uses -lpthread instead of Threads::Threads 15.7 generated .pc file contains strange entries - 15.11 ExternalProject_Add does not set CURL_CA_PATH 15.13 CMake build with MIT Kerberos does not work 16. aws-sigv4 - 16.1 aws-sigv4 does not sign requests with * correctly 16.2 aws-sigv4 does not handle multipart/form-data correctly 16.3 aws-sigv4 has problems with particular URLs 16.6 aws-sigv4 does not behave well with AWS VPC Lattice @@ -127,22 +117,9 @@ problems may have been fixed or changed somewhat since this was written. 1. HTTP -1.2 hyper is slow - - When curl is built to use hyper for HTTP, it is unnecessary slow. - - https://github.com/curl/curl/issues/11203 - -1.5 Expect-100 meets 417 - - If an upload using Expect: 100-continue receives an HTTP 417 response, it - ought to be automatically resent without the Expect:. A workaround is for - the client application to redo the transfer after disabling Expect:. - https://curl.se/mail/archive-2008-02/0043.html - 2. TLS -2.1 IMAPS connection fails with rustls error +2.1 IMAPS connection fails with Rustls error https://github.com/curl/curl/issues/10457 @@ -194,12 +171,6 @@ problems may have been fixed or changed somewhat since this was written. The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3 and SMTP if a failure occurs during the authentication phase of a connection. -3.3 POP3 expects "CRLF.CRLF" eob for some single-line responses - - You have to tell libcurl not to expect a body, when dealing with one line - response commands. Please see the POP3 examples and test cases which show - this for the NOOP and DELE commands. https://curl.se/bug/?i=740 - 3.4 AUTH PLAIN for SMTP is not working on all servers Specifying "--login-options AUTH=PLAIN" on the command line does not seem to @@ -254,27 +225,7 @@ problems may have been fixed or changed somewhat since this was written. that might be needed only for building libcurl. Further, curl-config --cflags suffers from the same effects with CFLAGS/CPPFLAGS. -5.3 building for old macOS fails with gcc - - Building curl for certain old macOS versions fails when gcc is used. We - command using clang in those cases. - - See https://github.com/curl/curl/issues/11441 - -5.5 cannot handle Unicode arguments in non-Unicode builds on Windows - - If a URL or filename cannot be encoded using the user's current codepage then - it can only be encoded properly in the Unicode character set. Windows uses - UTF-16 encoding for Unicode and stores it in wide characters, however curl - and libcurl are not equipped for that at the moment except when built with - _UNICODE and UNICODE defined. Except for Cygwin, Windows cannot use UTF-8 as - a locale. - - https://curl.se/bug/?i=345 - https://curl.se/bug/?i=731 - https://curl.se/bug/?i=3747 - -5.6 cygwin: make install installs curl-config.1 twice +5.6 Cygwin: make install installs curl-config.1 twice https://github.com/curl/curl/issues/8839 @@ -297,45 +248,58 @@ problems may have been fixed or changed somewhat since this was written. 5.13 long paths are not fully supported on Windows curl on Windows cannot access long paths (paths longer than 260 characters). - However, as a workaround, the Windows path prefix \\?\ which disables all path - interpretation may work to allow curl to access the path. For example: + However, as a workaround, the Windows path prefix \\?\ which disables all + path interpretation may work to allow curl to access the path. For example: \\?\c:\longpath. See https://github.com/curl/curl/issues/8361 -5.14 Windows Unicode builds use homedir in current locale - - The Windows Unicode builds of curl use the current locale, but expect Unicode - UTF-8 encoded paths for internal use such as open, access and stat. The user's - home directory is retrieved via curl_getenv in the current locale and not as - UTF-8 encoded Unicode. - - See https://github.com/curl/curl/pull/7252 and - https://github.com/curl/curl/pull/7281 - 5.15 Unicode on Windows - Passing in a unicode filename with -o: + Passing in a Unicode filename with -o: https://github.com/curl/curl/issues/11461 - Passing in unicode character with -d: + Passing in Unicode character with -d: https://github.com/curl/curl/issues/12231 -6. Authentication + Windows Unicode builds use homedir in current locale + + The Windows Unicode builds of curl use the current locale, but expect Unicode + UTF-8 encoded paths for internal use such as open, access and stat. The + user's home directory is retrieved via curl_getenv in the current locale and + not as UTF-8 encoded Unicode. + + See https://github.com/curl/curl/pull/7252 and + https://github.com/curl/curl/pull/7281 + + Cannot handle Unicode arguments in non-Unicode builds on Windows + + If a URL or filename cannot be encoded using the user's current codepage then + it can only be encoded properly in the Unicode character set. Windows uses + UTF-16 encoding for Unicode and stores it in wide characters, however curl + and libcurl are not equipped for that at the moment except when built with + _UNICODE and UNICODE defined. Except for Cygwin, Windows cannot use UTF-8 as + a locale. -6.1 NTLM authentication and unicode + https://curl.se/bug/?i=345 + https://curl.se/bug/?i=731 + https://curl.se/bug/?i=3747 - NTLM authentication involving unicode username or password only works - properly if built with UNICODE defined together with the Schannel - backend. The original problem was mentioned in: + NTLM authentication and Unicode + + NTLM authentication involving Unicode username or password only works + properly if built with UNICODE defined together with the Schannel backend. + The original problem was mentioned in: https://curl.se/mail/lib-2009-10/0024.html https://curl.se/bug/view.cgi?id=896 The Schannel version verified to work as mentioned in https://curl.se/mail/lib-2012-07/0073.html +6. Authentication + 6.2 MIT Kerberos for Windows build libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's @@ -367,6 +331,13 @@ problems may have been fixed or changed somewhat since this was written. https://github.com/curl/curl/issues/3267 +6.8 Heimdal memory leaks + + Running test 2077 and 2078 with curl built to do GSS with Heimdal causes + valgrind errors (memory leak). + + https://github.com/curl/curl/issues/14446 + 6.9 SHA-256 digest not supported in Windows SSPI builds Windows builds of curl that have SSPI enabled use the native Windows API calls @@ -402,24 +373,6 @@ problems may have been fixed or changed somewhat since this was written. 7. FTP -7.1 FTP upload fails if remembered directory is deleted - - curl's FTP code assumes that the directory it entered in a previous transfer - still exists when it comes back to do a second transfer, and does not respond - well if it was indeed deleted in the mean time. - - https://github.com/curl/curl/issues/12181 - -7.2 Implicit FTPS upload timeout - - https://github.com/curl/curl/issues/11720 - -7.3 FTP with NOBODY and FAILONERROR - - It seems sensible to be able to use CURLOPT_NOBODY and CURLOPT_FAILONERROR - with FTP to detect if a file exists or not, but it is not working: - https://curl.se/mail/lib-2008-07/0295.html - 7.4 FTP with ACCT When doing an operation over FTP that requires the ACCT command (but not when @@ -471,19 +424,14 @@ problems may have been fixed or changed somewhat since this was written. https://github.com/curl/curl/issues/8632 -9.5 cygwin: "WARNING: UNPROTECTED PRIVATE KEY FILE!" +9.5 Cygwin: "WARNING: UNPROTECTED PRIVATE KEY FILE!" - Running SCP and SFTP tests on cygwin makes this warning message appear. + Running SCP and SFTP tests on Cygwin makes this warning message appear. https://github.com/curl/curl/issues/11244 10. SOCKS -10.3 FTPS over SOCKS - - libcurl does not support FTPS over a SOCKS proxy. - - 11. Internals 11.1 gssapi library name + version is missing in curl_version_info() @@ -527,6 +475,17 @@ problems may have been fixed or changed somewhat since this was written. See https://github.com/curl/curl/issues/13350 +11.7 CURLOPT_CONNECT_TO does not work for HTTPS proxy + + It is unclear if the same option should even cover the proxy connection or if + if requires a separate option. + + See https://github.com/curl/curl/issues/14481 + +11.8 WinIDN test failures + + Test 165 disabled when built with WinIDN. + 12. LDAP 12.1 OpenLDAP hangs after returning results @@ -581,12 +540,6 @@ problems may have been fixed or changed somewhat since this was written. https://github.com/curl/curl/issues/11158 -15.2 support build with GnuTLS - -15.3 unusable tool_hugehelp.c with MinGW - - see https://github.com/curl/curl/issues/3125 - 15.6 uses -lpthread instead of Threads::Threads See https://github.com/curl/curl/issues/6166 @@ -598,13 +551,6 @@ problems may have been fixed or changed somewhat since this was written. See https://github.com/curl/curl/issues/6167 -15.11 ExternalProject_Add does not set CURL_CA_PATH - - CURL_CA_BUNDLE and CURL_CA_PATH are not set properly when cmake's - ExternalProject_Add is used to build curl as a dependency. - - See https://github.com/curl/curl/issues/6313 - 15.13 CMake build with MIT Kerberos does not work Minimum CMake version was bumped in curl 7.71.0 (#5358) Since CMake 3.2 @@ -618,10 +564,6 @@ problems may have been fixed or changed somewhat since this was written. 16. aws-sigv4 -16.1 aws-sigv4 does not sign requests with * correctly - - https://github.com/curl/curl/issues/7559 - 16.2 aws-sigv4 does not handle multipart/form-data correctly https://github.com/curl/curl/issues/13351 diff --git a/docs/Makefile.am b/docs/Makefile.am index e9ef62848..e8f2d55bf 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -40,29 +40,40 @@ if BUILD_DOCS CLEANFILES = mk-ca-bundle.1 curl-config.1 endif +INTERNALDOCS = \ + internals/BUFQ.md \ + internals/BUFREF.md \ + internals/CHECKSRC.md \ + internals/CLIENT-READERS.md \ + internals/CLIENT-WRITERS.md \ + internals/CODE_STYLE.md \ + internals/CONNECTION-FILTERS.md \ + internals/DYNBUF.md \ + internals/HASH.md \ + internals/HYPER.md \ + internals/LLIST.md \ + internals/MQTT.md \ + internals/NEW-PROTOCOL.md \ + internals/README.md \ + internals/SPLAY.md \ + internals/WEBSOCKET.md + EXTRA_DIST = \ $(CURLPAGES) \ - ALTSVC.md \ + $(INTERNALDOCS) \ BINDINGS.md \ - BUFQ.md \ - BUFREF.md \ BUG-BOUNTY.md \ BUGS.md \ - CHECKSRC.md \ CIPHERS.md \ + CIPHERS-TLS12.md \ CMakeLists.txt \ CODE_OF_CONDUCT.md \ CODE_REVIEW.md \ - CODE_STYLE.md \ - CLIENT-READERS.md \ - CLIENT-WRITERS.md \ - CONNECTION-FILTERS.md \ CONTRIBUTE.md \ CURL-DISABLE.md \ CURLDOWN.md \ DEPRECATE.md \ DISTROS.md \ - DYNBUF.md \ EARLY-RELEASE.md \ ECH.md \ EXPERIMENTAL.md \ @@ -71,11 +82,8 @@ EXTRA_DIST = \ GOVERNANCE.md \ HELP-US.md \ HISTORY.md \ - HSTS.md \ HTTP-COOKIES.md \ - HTTP2.md \ HTTP3.md \ - HYPER.md \ INSTALL \ INSTALL-CMAKE.md \ INSTALL.md \ @@ -84,10 +92,7 @@ EXTRA_DIST = \ KNOWN_BUGS \ MAIL-ETIQUETTE.md \ MANUAL.md \ - MQTT.md \ - NEW-PROTOCOL.md \ options-in-versions \ - PARALLEL-TRANSFERS.md \ README.md \ RELEASE-PROCEDURE.md \ RUSTLS.md \ @@ -96,13 +101,11 @@ EXTRA_DIST = \ SPONSORS.md \ SSL-PROBLEMS.md \ SSLCERTS.md \ - THANKS \ - TODO \ + THANKS TODO \ TheArtOfHttpScripting.md \ URL-SYNTAX.md \ VERSIONS.md \ - VULN-DISCLOSURE-POLICY.md \ - WEBSOCKET.md + VULN-DISCLOSURE-POLICY.md CD2NROFF = $(top_srcdir)/scripts/cd2nroff $< >$@ diff --git a/docs/Makefile.in b/docs/Makefile.in index 7499d4bb9..6869ae045 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -278,11 +278,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -328,7 +328,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -344,8 +343,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -378,10 +379,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -392,6 +391,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -400,6 +400,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -493,29 +494,40 @@ CURLPAGES = curl-config.md mk-ca-bundle.md SUBDIRS = . cmdline-opts libcurl DIST_SUBDIRS = $(SUBDIRS) examples @BUILD_DOCS_TRUE@CLEANFILES = mk-ca-bundle.1 curl-config.1 +INTERNALDOCS = \ + internals/BUFQ.md \ + internals/BUFREF.md \ + internals/CHECKSRC.md \ + internals/CLIENT-READERS.md \ + internals/CLIENT-WRITERS.md \ + internals/CODE_STYLE.md \ + internals/CONNECTION-FILTERS.md \ + internals/DYNBUF.md \ + internals/HASH.md \ + internals/HYPER.md \ + internals/LLIST.md \ + internals/MQTT.md \ + internals/NEW-PROTOCOL.md \ + internals/README.md \ + internals/SPLAY.md \ + internals/WEBSOCKET.md + EXTRA_DIST = \ $(CURLPAGES) \ - ALTSVC.md \ + $(INTERNALDOCS) \ BINDINGS.md \ - BUFQ.md \ - BUFREF.md \ BUG-BOUNTY.md \ BUGS.md \ - CHECKSRC.md \ CIPHERS.md \ + CIPHERS-TLS12.md \ CMakeLists.txt \ CODE_OF_CONDUCT.md \ CODE_REVIEW.md \ - CODE_STYLE.md \ - CLIENT-READERS.md \ - CLIENT-WRITERS.md \ - CONNECTION-FILTERS.md \ CONTRIBUTE.md \ CURL-DISABLE.md \ CURLDOWN.md \ DEPRECATE.md \ DISTROS.md \ - DYNBUF.md \ EARLY-RELEASE.md \ ECH.md \ EXPERIMENTAL.md \ @@ -524,11 +536,8 @@ EXTRA_DIST = \ GOVERNANCE.md \ HELP-US.md \ HISTORY.md \ - HSTS.md \ HTTP-COOKIES.md \ - HTTP2.md \ HTTP3.md \ - HYPER.md \ INSTALL \ INSTALL-CMAKE.md \ INSTALL.md \ @@ -537,10 +546,7 @@ EXTRA_DIST = \ KNOWN_BUGS \ MAIL-ETIQUETTE.md \ MANUAL.md \ - MQTT.md \ - NEW-PROTOCOL.md \ options-in-versions \ - PARALLEL-TRANSFERS.md \ README.md \ RELEASE-PROCEDURE.md \ RUSTLS.md \ @@ -549,13 +555,11 @@ EXTRA_DIST = \ SPONSORS.md \ SSL-PROBLEMS.md \ SSLCERTS.md \ - THANKS \ - TODO \ + THANKS TODO \ TheArtOfHttpScripting.md \ URL-SYNTAX.md \ VERSIONS.md \ - VULN-DISCLOSURE-POLICY.md \ - WEBSOCKET.md + VULN-DISCLOSURE-POLICY.md CD2NROFF = $(top_srcdir)/scripts/cd2nroff $< >$@ CD2 = $(CD2_$(V)) diff --git a/docs/PARALLEL-TRANSFERS.md b/docs/PARALLEL-TRANSFERS.md deleted file mode 100644 index 08aac544a..000000000 --- a/docs/PARALLEL-TRANSFERS.md +++ /dev/null @@ -1,56 +0,0 @@ - - -# Parallel transfers - -curl 7.66.0 introduced support for doing multiple transfers simultaneously; in -parallel. - -## -Z, --parallel - -When this command line option is used, curl performs the transfers given to it -at the same time. It does up to `--parallel-max` concurrent transfers, with a -default value of 50. - -## Progress meter - -The progress meter that is displayed when doing parallel transfers is -completely different than the regular one used for each single transfer. - - It shows: - - o percent download (if known, which means *all* transfers need to have a - known size) - o percent upload (if known, with the same caveat as for download) - o total amount of downloaded data - o total amount of uploaded data - o number of transfers to perform - o number of concurrent transfers being transferred right now - o number of transfers queued up waiting to start - o total time all transfers are expected to take (if sizes are known) - o current time the transfers have spent so far - o estimated time left (if sizes are known) - o current transfer speed (the faster of upload/download speeds measured over - the last few seconds) - -Example: - - DL% UL% Dled Uled Xfers Live Qd Total Current Left Speed - 72 -- 37.9G 0 101 30 23 0:00:55 0:00:34 0:00:22 2752M - -## Behavior differences - -Connections are shared fine between different easy handles, but the -"authentication contexts" are not. For example doing HTTP Digest auth with one -handle for a particular transfer and then continue on with another handle that -reuses the same connection, the second handle cannot send the necessary -Authorization header at once since the context is only kept in the original -easy handle. - -To fix this, the authorization state could be made possible to share with the -share API as well, as a context per origin + path (realm?) basically. - -Visible in test 153, 1412 and more. diff --git a/docs/RELEASE-TOOLS.md b/docs/RELEASE-TOOLS.md index e449ade54..75a8b4d40 100644 --- a/docs/RELEASE-TOOLS.md +++ b/docs/RELEASE-TOOLS.md @@ -1,4 +1,4 @@ -# Release tools used for curl 8.9.1 +# Release tools used for curl 8.10.0 The following tools and their Debian package version numbers were used to produce this release tarball. @@ -12,7 +12,7 @@ produce this release tarball. # Reproduce the tarball -- Clone the repo and checkout the tag: curl-8_9_1 +- Clone the repo and checkout the tag/commit: curl-8_10_0 - Install the same set of tools + versions as listed above ## Do a standard build @@ -23,6 +23,6 @@ produce this release tarball. ## Generate the tarball with the same timestamp -- export SOURCE_DATE_EPOCH=1722408713 -- ./maketgz [version] +- export SOURCE_DATE_EPOCH=1726033055 +- ./scripts/maketgz [version] diff --git a/docs/RUSTLS.md b/docs/RUSTLS.md index cf32afc5e..893fd2134 100644 --- a/docs/RUSTLS.md +++ b/docs/RUSTLS.md @@ -11,7 +11,7 @@ be built to use it as an alternative to OpenSSL or other TLS backends. We use the [rustls-ffi C bindings](https://github.com/rustls/rustls-ffi/). This version of curl depends on version v0.13.0 of rustls-ffi. -# Building with rustls +# Building with Rustls First, [install Rust](https://rustup.rs/). @@ -22,10 +22,25 @@ Next, check out, build, and install the appropriate version of rustls-ffi: % make % make DESTDIR=${HOME}/rustls-ffi-built/ install -Now configure and build curl with rustls: +Now configure and build curl with Rustls: % git clone https://github.com/curl/curl % cd curl % autoreconf -fi % ./configure --with-rustls=${HOME}/rustls-ffi-built % make + +## Randomness + +Every TLS libcurl curl supports - *except* Rustls - provides a function for +curl to extract cryptographically safe random numbers with. + +When you build curl with Rustls, curl uses its own internal attempts to get a +decent random value: + +1. Windows specific APIs +2. arc4random + +If neither of those are present, then curl using Rustls falls back to **weak +pseudo-random values**, and thus weakening several curl authentication +implementations. diff --git a/docs/SSLCERTS.md b/docs/SSLCERTS.md index ba349ed63..b6d7a6e75 100644 --- a/docs/SSLCERTS.md +++ b/docs/SSLCERTS.md @@ -4,157 +4,117 @@ Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl --> -SSL Certificate Verification -============================ +# TLS Certificate Verification -SSL is TLS ----------- +## Native vs file based -SSL is the old name. It is called TLS these days. +If curl was built with Schannel or Secure Transport support, then curl uses +the system native CA store for verification. All other TLS libraries use a +file based CA store by default. -Native SSL ----------- +## Verification -If libcurl was built with Schannel or Secure Transport support (the native SSL -libraries included in Windows and Mac OS X), then this does not apply to -you. Scroll down for details on how the OS-native engines handle SSL -certificates. If you are not sure, then run "curl -V" and read the results. If -the version string says `Schannel` in it, then it was built with Schannel -support. +Every trusted server certificate is digitally signed by a Certificate +Authority, a CA. -It is about trust ------------------ +In your local CA store you have a collection of certificates from *trusted* +certificate authorities that TLS clients like curl use to verify servers. -This system is about trust. In your local CA certificate store you have certs -from *trusted* Certificate Authorities that you then can use to verify that -the server certificates you see are valid. They are signed by one of the -certificate authorities you trust. +curl does certificate verification by default. This is done by verifying the +signature and making sure the certificate was crafted for the server name +provided in the URL. -Which certificate authorities do you trust? You can decide to trust the same -set of companies your operating system trusts, or the set one of the known -browsers trust. That is basically trust via someone else you trust. You should -just be aware that modern operating systems and browsers are setup to trust -*hundreds* of companies and in recent years several certificate authorities -have been found untrustworthy. +If you communicate with HTTPS, FTPS or other TLS-using servers using +certificates signed by a CA whose certificate is present in the store, you can +be sure that the remote server really is the one it claims to be. -Certificate Verification ------------------------- +If the remote server uses a self-signed certificate, if you do not install a +CA cert store, if the server uses a certificate signed by a CA that is not +included in the store you use or if the remote host is an impostor +impersonating your favorite site, the certificate check fails and reports an +error. -libcurl performs peer SSL certificate verification by default. This is done -by using a CA certificate store that the SSL library can use to make sure the -peer's server certificate is valid. +If you think it wrongly failed the verification, consider one of the following +sections. -If you communicate with HTTPS, FTPS or other TLS-using servers using -certificates in the CA store, you can be sure that the remote server really is -the one it claims to be. +### Skip verification -If the remote server uses a self-signed certificate, if you do not install a CA -cert store, if the server uses a certificate signed by a CA that is not -included in the store you use or if the remote host is an impostor -impersonating your favorite site, and you want to transfer files from this -server, do one of the following: - - 1. Tell libcurl to *not* verify the peer. With libcurl you disable this with - `curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);` - - With the curl command line tool, you disable this with `-k`/`--insecure`. - - 2. Get a CA certificate that can verify the remote server and use the proper - option to point out this CA cert for verification when connecting. For - libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAINFO, cacert);` - - With the curl command line tool: `--cacert [file]` - - 3. Add the CA cert for your server to the existing default CA certificate - store. The default CA certificate store can be changed at compile time with - the following configure options: - - `--with-ca-bundle=FILE`: use the specified file as the CA certificate - store. CA certificates need to be concatenated in PEM format into this - file. - - `--with-ca-path=PATH`: use the specified path as CA certificate store. CA - certificates need to be stored as individual PEM files in this directory. - You may need to run c_rehash after adding files there. - - If neither of the two options is specified, configure tries to auto-detect - a setting. It's also possible to explicitly not set any default store but - rely on the built in default the crypto library may provide instead. You - can achieve that by passing both `--without-ca-bundle` and - `--without-ca-path` to the configure script. - - If you use Internet Explorer, this is one way to get extract the CA cert - for a particular server: - - - View the certificate by double-clicking the padlock - - Find out where the CA certificate is kept (Certificate> - Authority Information Access>URL) - - Get a copy of the crt file using curl - - Convert it from crt to PEM using the OpenSSL tool: - `openssl x509 -inform DES -in yourdownloaded.crt -out outcert.pem -text` - - Add the `outcert.pem` to the CA certificate store or use it stand-alone - as described below. - - If you use the `openssl` tool, this is one way to get extract the CA cert - for a particular server: - - - `openssl s_client -showcerts -servername server -connect server:443 > cacert.pem` - - type "quit", followed by the "ENTER" key - - The certificate has `BEGIN CERTIFICATE` and `END CERTIFICATE` markers. - - If you want to see the data in the certificate, you can do: `openssl - x509 -inform PEM -in certfile -text -out certdata` where `certfile` is - the cert you extracted from logfile. Look in `certdata`. - - If you want to trust the certificate, you can add it to your CA - certificate store or use it stand-alone as described. Just remember that - the security is no better than the way you obtained the certificate. - - 4. If you are using the curl command line tool and the TLS backend is not - Schannel then you can specify your own CA cert file by setting the - environment variable `CURL_CA_BUNDLE` to the path of your choice. - - If you are using the curl command line tool on Windows, curl searches for - a CA cert file named "curl-ca-bundle.crt" in these directories and in this - order: - 1. application's directory - 2. current working directory - 3. Windows System directory (e.g. C:\Windows\System32) - 4. Windows Directory (e.g. C:\Windows) - 5. all directories along %PATH% - - 5. Get another CA cert bundle. One option is to extract the one a recent - Firefox browser uses by running 'make ca-bundle' in the curl build tree - root, or possibly download a version that was generated this way for you: - [CA Extract](https://curl.se/docs/caextract.html) - -Neglecting to use one of the above methods when dealing with a server using a -certificate that is not signed by one of the certificates in the installed CA -certificate store, causes SSL to report an error (`certificate verify failed`) -during the handshake and SSL then refuses further communication with that -server. - -Certificate Verification with Schannel and Secure Transport ------------------------------------------------------------ - -If libcurl was built with Schannel (Microsoft's native TLS engine) or Secure -Transport (Apple's native TLS engine) support, then libcurl still performs -peer certificate verification, but instead of using a CA cert bundle, it uses -the certificates that are built into the OS. These are the same certificates -that appear in the Internet Options control panel (under Windows) or Keychain -Access application (under OS X). Any custom security rules for certificates -are honored. +Tell curl to *not* verify the peer with `-k`/`--insecure`. + +We **strongly** recommend this is avoided and that even if you end up doing +this for experimentation or development, **never** skip verification in +production. + +### Use a custom CA store + +Get a CA certificate that can verify the remote server and use the proper +option to point out this CA cert for verification when connecting - for this +specific transfer only. + +With the curl command line tool: `--cacert [file]` + +If you use the curl command line tool without a native CA store, then you can +specify your own CA cert file by setting the environment variable +`CURL_CA_BUNDLE` to the path of your choice. + +If you are using the curl command line tool on Windows, curl searches for a CA +cert file named `curl-ca-bundle.crt` in these directories and in this order: + 1. application's directory + 2. current working directory + 3. Windows System directory (e.g. C:\Windows\System32) + 4. Windows Directory (e.g. C:\Windows) + 5. all directories along %PATH% + +### Use the native store + +In several environments, in particular on Windows, you can ask curl to use the +system's native CA store when verifying the certificate. + +With the curl command line tool: `--ca-native`. + +### Modify the CA store + +Add the CA cert for your server to the existing default CA certificate store. + +Usually you can figure out the path to the local CA store by looking at the +verbose output that `curl -v` shows when you connect to an HTTPS site. + +### Change curl's default CA store + +The default CA certificate store curl uses is set at build time. When you +build curl you can point out your preferred path. + +### Extract CA cert from a server + + curl -w %{certs} https://example.com > cacert.pem + +The certificate has `BEGIN CERTIFICATE` and `END CERTIFICATE` markers. + +### Get the Mozilla CA store + +Download a version of the Firefox CA store converted to PEM format on the [CA +Extract](https://curl.se/docs/caextract.html) page. It always features the +latest Firefox bundle. + +## Native CA store + +If curl was built with Schannel, Secure Transport or were instructed to use +the native CA Store, then curl uses the certificates that are built into the +OS. These are the same certificates that appear in the Internet Options +control panel (under Windows) or Keychain Access application (under macOS). +Any custom security rules for certificates are honored. Schannel runs CRL checks on certificates unless peer verification is disabled. Secure Transport on iOS runs OCSP checks on certificates unless peer -verification is disabled. Secure Transport on OS X runs either OCSP or CRL +verification is disabled. Secure Transport on macOS runs either OCSP or CRL checks on certificates if those features are enabled, and this behavior can be adjusted in the preferences of Keychain Access. -HTTPS proxy ------------ +## HTTPS proxy -Since version 7.52.0, curl can do HTTPS to the proxy separately from the -connection to the server. This TLS connection is handled separately from the -server connection so instead of `--insecure` and `--cacert` to control the +curl can do HTTPS to the proxy separately from the connection to the server. +This TLS connection is handled and verified separately from the server +connection so instead of `--insecure` and `--cacert` to control the certificate verification, you use `--proxy-insecure` and `--proxy-cacert`. With these options, you make sure that the TLS connection and the trust of the proxy can be kept totally separate from the TLS connection to the server. diff --git a/docs/THANKS b/docs/THANKS index 03bd1b7ac..4f15e01b5 100644 --- a/docs/THANKS +++ b/docs/THANKS @@ -278,6 +278,7 @@ atjg on github Augustus Saunders Aurélien Pierre Austin Green +Austin Moore av223119 on github Avery Fay awesomekosm on github @@ -499,6 +500,7 @@ Chris Paulson-Ellis Chris Roberts Chris Sauer Chris Smowton +Chris Swan Chris Talbot Chris Webb Chris Young @@ -698,6 +700,7 @@ David Phillips David Rosenstrauch David Ryskalczyk David Sanderson +David Sardari David Schweikert David Shaw David Strauss @@ -887,6 +890,7 @@ Eric Melville Eric Mertens Eric Murphy Eric Musser +Eric Norris Eric Rautman Eric Rescorla Eric Ridge @@ -948,6 +952,7 @@ Federico Bianchi Federico Pellegrin Fedor Karpelevitch Fedor Korotkov +feelingseas on github FeignClaims on github Feist Josselin Felipe Gasper @@ -1087,6 +1092,7 @@ Gregory Szorc Griffin Downs Grigory Entin Grisha Levit +Gruber Glass Guenole Bescon Guido Berhoerster Guilherme Puida @@ -1292,6 +1298,7 @@ Jan Venekamp Jan Verbeek Jan-Piet Mens JanB on github +janedenone on github janko-js on github Janne Blomqvist Janne Johansson @@ -1302,6 +1309,7 @@ Jari Sundell jasal82 on github Jason Baietto Jason Glasgow +Jason Hood Jason Juang Jason Lee Jason Liu @@ -1376,6 +1384,7 @@ Jesse Noller Jesse Tan jethrogb on github jhoyla on github +Jiacai Liu Jiang Wenjian Jiawen Geng Jie He @@ -1400,6 +1409,7 @@ jmdavitt on github jnbr on github Jocelyn Jaubert Jochem Broekhoff +Joe Birr-Pixton Joe Halpin Joe Malicki Joe Mason @@ -1629,6 +1639,7 @@ Kimmo Kinnunen kirbyn17 on hackerone Kirill Efimov Kirill Marchuk +kit-ty-kate on github Kjell Ericson Kjetil Jacobsen Klaus Crusius @@ -1746,6 +1757,7 @@ Lluís Batlle i Rossell locpyl-tidnyd on github Loganaden Velvindron Loic Dachary +lolbinarycat on github LoRd_MuldeR Loren Kirkby Lorenzo Miniero @@ -1954,6 +1966,7 @@ Mauro Iorio Mauro Rappa Maurício Meneghini Fauth Max Dymond +Max Faxälv Max Katsev Max Kellermann Max Khon @@ -1978,7 +1991,7 @@ Melissa Mears Melroy van den Berg Mert Yazıcıoğlu Mettgut Jamalla -Micah Snyder) +Micah Snyder Michael Afanasiev Michael Anti Michael Baentsch @@ -2083,6 +2096,7 @@ Momoka Yamamoto MonkeybreadSoftware on github moohoorama on github Morgan Willcock +Moritz Buhl Morten Minde Neergaard Mostyn Bramley-Moore Moti Avrahami @@ -2311,6 +2325,7 @@ Per Jensen Per Lundberg Per Malmberg Per Nilsson +Pete Cordell Pete Lomax Peter Bray Peter Forret @@ -2424,6 +2439,7 @@ Raito Bezarius Rajesh Naganathan Rajkumar Mandal Ralf S. Engelschall +ralfjunker on github Ralph Beckmann Ralph Langendam Ralph Mitchell @@ -2438,12 +2454,14 @@ Randy Armstrong Randy McMurchy Raphael Gozzo Rasmus Melchior Jacobsen +Rasmus Thomsen Raul Onitza-Klugman Ravi Pratap Ray Dassen Ray Pekowski Ray Satiro Razvan Cojocaru +Razvan Pricope rcombs on github Red Hat Product Security Reed Loden @@ -2622,6 +2640,7 @@ Salvatore Sorrentino Sam Deane Sam Hurst Sam James +Sam Jessup Sam Roth Sam Schanken Samanta Navarro @@ -2743,6 +2762,7 @@ Simon Liu Simon Warta simplerobot on github Siva Sivaraman +Slaven Rezić SLDiggie on github Smackd0wn Smackd0wn on github @@ -2766,6 +2786,7 @@ Stadler Stephan Stan Hu Stan van de Burgt Stanislav Ivochkin +Stanislav Lange Stanislav Zidek Stanley Wucw Stathis Kapnidis @@ -2788,6 +2809,7 @@ Stefan Tomanek Stefan Ulrich Stefan Yohansson Stefano Simonelli +Steffen Kieß Steinar H. Gunderson steini2000 on github Stepan Broz @@ -2920,6 +2942,7 @@ Tim Stack Tim Starling Tim Tassonis Tim Verhoeven +Tim Yuer Timmy Schierling Timo Lange Timo Sirainen @@ -3038,6 +3061,7 @@ Vasiliy Ulyanov Vasily Lobaskin Vasy Okhin Venkat Akella +Venkat Krishna R Venkataramana Mokkapati Vicente Garcia Victor Magierski @@ -3046,6 +3070,7 @@ Victor Vieux VictorVG on github Vijay Panghal Vikram Saxena +Viktor Petersson Viktor Szakats Vilhelm Prytz Ville Skyttä @@ -3136,6 +3161,7 @@ XmiliaH on github xnynx on github xtonik on github xwxbug on github +XYenon Xì Gà Yaakov Selkowitz Yadhu Krishna M @@ -3158,6 +3184,7 @@ yiyuaner on github Ymir1711 on github Yonggang Luo Yongkang Huang +Yoshimasa Ohno Younes El-karama youngchopin on github Yousuke Kimoto @@ -3205,6 +3232,7 @@ zzq1015 on github Štefan Kremeň Борис Верховский Коваленко Анатолий Викторович +наб Никита Дорохин ウさん 不确定 diff --git a/docs/TODO b/docs/TODO index 914b9a312..a8162cbd3 100644 --- a/docs/TODO +++ b/docs/TODO @@ -63,9 +63,7 @@ 4. FTP 4.1 HOST - 4.2 Alter passive/active on failure and retry 4.4 Support CURLOPT_PREQUOTE for directories listings - 4.5 ASCII support 4.6 GSSAPI via Windows SSPI 4.7 STAT for LIST without data connection 4.8 Passive transfer could try other IP addresses @@ -148,13 +146,12 @@ 18. Command line tool 18.1 sync 18.2 glob posts - 18.3 -h option 18.4 --proxycommand 18.5 UTF-8 filenames in Content-Disposition 18.6 Option to make -Z merge lined based outputs on stdout 18.7 specify which response codes that make -f/--fail return error 18.9 Choose the name of file in braces for complex URLs - 18.10 improve how curl works in a windows console window + 18.10 improve how curl works in a Windows console window 18.11 Windows: set attribute 'archive' for completed downloads 18.12 keep running, read instructions from pipe/socket 18.13 Acknowledge Ratelimit headers @@ -179,7 +176,6 @@ 19.3 Do not use GNU libtool on OpenBSD 19.4 Package curl for Windows in a signed installer 19.5 make configure use --cache-file more and better - 19.6 build curl with Windows Unicode support 20. Test suite 20.1 SSL tunnel @@ -192,10 +188,14 @@ 21. MQTT 21.1 Support rate-limiting 21.2 Support MQTTS + 21.3 Handle network blocks 22. TFTP 22.1 TFTP does not convert LF to CRLF for mode=netascii + 23. Gopher + 23.1 Handle network blocks + ============================================================================== 1. libcurl @@ -203,7 +203,7 @@ 1.1 TFO support on Windows libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and - Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607 + macOS. Windows supports TCP Fast Open starting with Windows 10, version 1607 and we should add support for it. TCP Fast Open is supported on several platforms but not on Windows. Work on @@ -251,7 +251,7 @@ 1.6 thread-safe sharing Using the share interface users can share some data between easy handles but - several of the sharing options are documented as as not safe and supported to + several of the sharing options are documented as not safe and supported to share between multiple concurrent threads. Fixing this would enable more users to share data in more powerful ways. @@ -346,7 +346,7 @@ 1.17 Add support for IRIs - IRIs (RFC 3987) allow localized, non-ascii, names in the URL. To properly + IRIs (RFC 3987) allow localized, non-ASCII, names in the URL. To properly support this, curl/libcurl would need to translate/encode the given input from the input string encoding into percent encoded output "over the wire". @@ -466,7 +466,7 @@ Make sure we do not ever loop because of non-blocking sockets returning EWOULDBLOCK or similar. Blocking cases include: - - Name resolves on non-windows unless c-ares or the threaded resolver is used. + - Name resolves on non-Windows unless c-ares or the threaded resolver is used. - The threaded resolver may block on cleanup: https://github.com/curl/curl/issues/4852 @@ -482,6 +482,8 @@ - curl_multi_remove_handle for any of the above. See section 2.3. + - Calling curl_ws_send() from a callback + 2.2 Better support for same name resolves If a name resolve has been initiated for name NN and a second easy handle @@ -558,13 +560,6 @@ https://datatracker.ietf.org/doc/html/rfc7151 -4.2 Alter passive/active on failure and retry - - When trying to connect passively to a server which only supports active - connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the - connection. There could be a way to fallback to an active connection (and - vice versa). https://curl.se/bug/feature.cgi?id=1754793 - 4.4 Support CURLOPT_PREQUOTE for directions listings The lack of support is mostly an oversight and requires the FTP state machine @@ -572,11 +567,6 @@ https://github.com/curl/curl/issues/8602 -4.5 ASCII support - - FTP ASCII transfers do not follow RFC 959. They do not convert the data - accordingly. - 4.6 GSSAPI via Windows SSPI In addition to currently supporting the SASL GSSAPI mechanism (Kerberos V5) @@ -759,7 +749,7 @@ 10.4 Certificate-Based Authentication - LDAPS not possible with MAC and Windows with Certificate-Based Authentication + LDAPS not possible with macOS and Windows with Certificate-Based Authentication https://github.com/curl/curl/issues/9641 @@ -827,8 +817,6 @@ sometimes possible to circumvent TLS fingerprinting by servers. The TLS extension order is of course not the only way to fingerprint a client. - See https://github.com/curl/curl/issues/8119 - 13.5 Export session ids Add an interface to libcurl that enables "session IDs" to get @@ -1037,12 +1025,6 @@ Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'. This is easily scripted though. -18.3 -h option - - Support "curl -h --insecure" etc to output the manpage section for the - --insecure command line option in the terminal. Should be possible to work - with either long or short versions of command line options. - 18.4 --proxycommand Allow the user to make curl run a command and use its stdio to make requests @@ -1085,7 +1067,7 @@ See https://github.com/curl/curl/issues/221 -18.10 improve how curl works in a windows console window +18.10 improve how curl works in a Windows console window If you pull the scrollbar when transferring with curl in a Windows console window, the transfer is interrupted and can get disconnected. This can @@ -1246,7 +1228,7 @@ -J/--remote-header-name does not decode %-encoded filenames. RFC 6266 details how it should be done. The can of worm is basically that we have no charset - handling in curl and ascii >=128 is a challenge for us. Not to mention that + handling in curl and ASCII >=128 is a challenge for us. Not to mention that decoding also means that we need to check for nastiness that is attempted, like "../" sequences and the like. Probably everything to the left of any embedded slashes should be cut off. @@ -1314,13 +1296,6 @@ See https://github.com/curl/curl/issues/7753 -19.6 build curl with Windows Unicode support - - The user wants an easier way to tell autotools to build curl with Windows - Unicode support, like ./configure --enable-windows-unicode - - See https://github.com/curl/curl/issues/7229 - 20. Test suite 20.1 SSL tunnel @@ -1341,7 +1316,7 @@ 20.4 more platforms supported - Make the test suite work on more platforms. OpenBSD and Mac OS. Remove + Make the test suite work on more platforms. OpenBSD and macOS. Remove fork()s and it should become even more portable. 20.6 Use the RFC 6265 test suite @@ -1371,6 +1346,12 @@ 21.2 Support MQTTS +21.3 Handle network blocks + + Running test suite with + `CURL_DBG_SOCK_WBLOCK=90 ./runtests.pl -a mqtt` makes several + MQTT test cases fail where they should not. + 22. TFTP 22.1 TFTP does not convert LF to CRLF for mode=netascii @@ -1381,3 +1362,11 @@ for them. See https://github.com/curl/curl/issues/12655 + +23. Gopher + +23.1 Handle network blocks + + Running test suite with + `CURL_DBG_SOCK_WBLOCK=90 ./runtests.pl -a 1200 to 1300` makes several + Gopher test cases fail where they should not. diff --git a/docs/URL-SYNTAX.md b/docs/URL-SYNTAX.md index 30aaea9cf..3c921f857 100644 --- a/docs/URL-SYNTAX.md +++ b/docs/URL-SYNTAX.md @@ -197,7 +197,7 @@ Transitional Processing. The two standards have a huge overlap but differ slightly, perhaps most famously in how they deal with the German "double s" (`ß`). -When winidn is used, curl uses IDNA 2003 Transitional Processing, like the rest +When WinIDN is used, curl uses IDNA 2003 Transitional Processing, like the rest of Windows. ## Port number @@ -226,7 +226,7 @@ directory listing for the root / home directory is returned. FTP servers typically put the user in its "home directory" after login, which then differs between users. To explicitly specify the root directory of an FTP server, start the path with double slash `//` or `/%2f` (2F is the hexadecimal -value of the ascii code for the slash). +value of the ASCII code for the slash). ## FILE diff --git a/docs/VULN-DISCLOSURE-POLICY.md b/docs/VULN-DISCLOSURE-POLICY.md index e6d6f3450..fa379cf53 100644 --- a/docs/VULN-DISCLOSURE-POLICY.md +++ b/docs/VULN-DISCLOSURE-POLICY.md @@ -262,7 +262,7 @@ data. We consider this functionality a best-effort and omissions are not security vulnerabilities. - not all systems allow the arguments to be blanked in the first place - - since curl blanks the argument itself they area readable for a short moment + - since curl blanks the argument itself they are readable for a short moment no matter what - virtually every argument can contain sensitive data, depending on use - blanking all arguments would make it impractical for users to differentiate diff --git a/docs/cmdline-opts/CMakeLists.txt b/docs/cmdline-opts/CMakeLists.txt index d165f841e..7f4187da8 100644 --- a/docs/cmdline-opts/CMakeLists.txt +++ b/docs/cmdline-opts/CMakeLists.txt @@ -24,17 +24,17 @@ set(MANPAGE "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.1") set(ASCIIPAGE "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt") -# Load DPAGES and OTHERPAGES from shared file +# Get 'DPAGES' variable transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") add_custom_command(OUTPUT "${MANPAGE}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND "${PERL_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/scripts/managen mainpage ${DPAGES} > "${MANPAGE}" - COMMAND "${PERL_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/scripts/managen ascii ${DPAGES} > "${ASCIIPAGE}" + COMMAND "${PERL_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/managen" mainpage ${DPAGES} > "${MANPAGE}" + COMMAND "${PERL_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/managen" ascii ${DPAGES} > "${ASCIIPAGE}" VERBATIM ) -add_custom_target(generate-curl.1 ALL DEPENDS "${MANPAGE}") +add_custom_target("generate-curl.1" ALL DEPENDS "${MANPAGE}") if(NOT CURL_DISABLE_INSTALL) - install(FILES "${MANPAGE}" DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES "${MANPAGE}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") endif() diff --git a/docs/cmdline-opts/Makefile.am b/docs/cmdline-opts/Makefile.am index 0aa8a44fa..b087e3852 100644 --- a/docs/cmdline-opts/Makefile.am +++ b/docs/cmdline-opts/Makefile.am @@ -37,6 +37,9 @@ GN_1 = GN_ = $(GN_0) MANAGEN=$(top_srcdir)/scripts/managen +MAXLINE=$(top_srcdir)/scripts/maxline + +# Maximum number of columns accepted in the ASCII version of the manpage INCDIR=$(top_srcdir)/include if BUILD_DOCS diff --git a/docs/cmdline-opts/Makefile.in b/docs/cmdline-opts/Makefile.in index 56080c8c2..c6d1c9633 100644 --- a/docs/cmdline-opts/Makefile.in +++ b/docs/cmdline-opts/Makefile.in @@ -246,11 +246,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -296,7 +296,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -312,8 +311,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -346,10 +347,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -360,6 +359,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -368,6 +368,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -520,6 +521,7 @@ DPAGES = \ doh-cert-status.md \ doh-insecure.md \ doh-url.md \ + dump-ca-embed.md \ dump-header.md \ ech.md \ egd-file.md \ @@ -564,7 +566,6 @@ DPAGES = \ http3.md \ http3-only.md \ ignore-content-length.md \ - include.md \ insecure.md \ interface.md \ ip-tos.md \ @@ -682,7 +683,9 @@ DPAGES = \ sasl-ir.md \ service-name.md \ show-error.md \ + show-headers.md \ silent.md \ + skip-existing.md \ socks4.md \ socks4a.md \ socks5-basic.md \ @@ -746,6 +749,9 @@ GN_0 = @echo " GENERATE" $@; GN_1 = GN_ = $(GN_0) MANAGEN = $(top_srcdir)/scripts/managen +MAXLINE = $(top_srcdir)/scripts/maxline + +# Maximum number of columns accepted in the ASCII version of the manpage INCDIR = $(top_srcdir)/include @BUILD_DOCS_TRUE@CLEANFILES = $(MANPAGE) $(ASCIIPAGE) @BUILD_DOCS_TRUE@man_MANS = $(MANPAGE) diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc index d69635e49..a7f635d8d 100644 --- a/docs/cmdline-opts/Makefile.inc +++ b/docs/cmdline-opts/Makefile.inc @@ -89,6 +89,7 @@ DPAGES = \ doh-cert-status.md \ doh-insecure.md \ doh-url.md \ + dump-ca-embed.md \ dump-header.md \ ech.md \ egd-file.md \ @@ -133,7 +134,6 @@ DPAGES = \ http3.md \ http3-only.md \ ignore-content-length.md \ - include.md \ insecure.md \ interface.md \ ip-tos.md \ @@ -251,7 +251,9 @@ DPAGES = \ sasl-ir.md \ service-name.md \ show-error.md \ + show-headers.md \ silent.md \ + skip-existing.md \ socks4.md \ socks4a.md \ socks5-basic.md \ diff --git a/docs/cmdline-opts/_ENVIRONMENT.md b/docs/cmdline-opts/_ENVIRONMENT.md index 1d40b87b8..02561193b 100644 --- a/docs/cmdline-opts/_ENVIRONMENT.md +++ b/docs/cmdline-opts/_ENVIRONMENT.md @@ -87,7 +87,7 @@ names named after the destination connection id (in hex). Do note that these files can become rather large. Works with the ngtcp2 and quiche QUIC backends. ## `SHELL` -Used on VMS when trying to detect if using a **DCL** or a **unix** shell. +Used on VMS when trying to detect if using a **DCL** or a **Unix** shell. ## `SSL_CERT_DIR` If set, it is used as the --capath value. This environment variable is ignored diff --git a/docs/cmdline-opts/_OPTIONS.md b/docs/cmdline-opts/_OPTIONS.md index 106298e74..ef208ade0 100644 --- a/docs/cmdline-opts/_OPTIONS.md +++ b/docs/cmdline-opts/_OPTIONS.md @@ -24,3 +24,5 @@ clean option state, except for the options that are global. Global options retain their values and meaning even after --next. The following options are global: `%GLOBALS`. + +# ALL OPTIONS diff --git a/docs/cmdline-opts/_VARIABLES.md b/docs/cmdline-opts/_VARIABLES.md index aa6a8ae4f..e46b67553 100644 --- a/docs/cmdline-opts/_VARIABLES.md +++ b/docs/cmdline-opts/_VARIABLES.md @@ -11,12 +11,12 @@ variable `name` inserted, or a blank if the name does not exist as a variable. Insert `{{` verbatim in the string by prefixing it with a backslash, like `\{{`. -You an access and expand environment variables by first importing them. You -can select to either require the environment variable to be set or you can -provide a default value in case it is not already set. Plain --variable %name -imports the variable called 'name' but exits with an error if that environment +You access and expand environment variables by first importing them. You +select to either require the environment variable to be set or you can provide +a default value in case it is not already set. Plain `--variable %name` +imports the variable called `name` but exits with an error if that environment variable is not already set. To provide a default value if it is not set, use ---variable %name=content or --variable %name@content. +`--variable %name=content` or `--variable %name@content`. Example. Get the USER environment variable into the URL, fail if USER is not set: diff --git a/docs/cmdline-opts/ca-native.md b/docs/cmdline-opts/ca-native.md index a771a7a81..3d773a8c4 100644 --- a/docs/cmdline-opts/ca-native.md +++ b/docs/cmdline-opts/ca-native.md @@ -10,6 +10,7 @@ Multi: boolean See-also: - cacert - capath + - dump-ca-embed - insecure Example: - --ca-native $URL diff --git a/docs/cmdline-opts/cacert.md b/docs/cmdline-opts/cacert.md index 3268f966d..1b34ce5b4 100644 --- a/docs/cmdline-opts/cacert.md +++ b/docs/cmdline-opts/cacert.md @@ -10,6 +10,7 @@ Added: 7.5 Multi: single See-also: - capath + - dump-ca-embed - insecure Example: - --cacert CA-file.txt $URL @@ -26,7 +27,7 @@ curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is set and the TLS backend is not Schannel, and uses the given path as a path to a CA cert bundle. This option overrides that variable. -The windows version of curl automatically looks for a CA certs file named +The Windows version of curl automatically looks for a CA certs file named 'curl-ca-bundle.crt', either in the same directory as curl.exe, or in the Current Working Directory, or in any folder along your PATH. diff --git a/docs/cmdline-opts/capath.md b/docs/cmdline-opts/capath.md index 58919dd4a..51be39e29 100644 --- a/docs/cmdline-opts/capath.md +++ b/docs/cmdline-opts/capath.md @@ -10,6 +10,7 @@ Added: 7.9.8 Multi: single See-also: - cacert + - dump-ca-embed - insecure Example: - --capath /local/directory $URL diff --git a/docs/cmdline-opts/ciphers.md b/docs/cmdline-opts/ciphers.md index 9d7e0c6fe..6a597a2c8 100644 --- a/docs/cmdline-opts/ciphers.md +++ b/docs/cmdline-opts/ciphers.md @@ -2,23 +2,24 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Long: ciphers -Arg: -Help: SSL ciphers to use +Arg: +Help: TLS 1.2 (1.1, 1.0) ciphers to use Protocols: TLS Category: tls Added: 7.9 Multi: single See-also: - - tlsv1.3 - tls13-ciphers - proxy-ciphers + - curves Example: - - --ciphers ECDHE-ECDSA-AES256-CCM8 $URL + - --ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 $URL --- # `--ciphers` -Specifies which ciphers to use in the connection. The list of ciphers must -specify valid ciphers. Read up on SSL cipher list details on this URL: +Specifies which cipher suites to use in the connection if it negotiates +TLS 1.2 (1.1, 1.0). The list of ciphers suites must specify valid ciphers. +Read up on cipher suite details on this URL: https://curl.se/docs/ssl-ciphers.html diff --git a/docs/cmdline-opts/cookie.md b/docs/cmdline-opts/cookie.md index cbc8b8457..50f977e70 100644 --- a/docs/cmdline-opts/cookie.md +++ b/docs/cmdline-opts/cookie.md @@ -21,20 +21,21 @@ Example: # `--cookie` -Pass the data to the HTTP server in the Cookie header. It is supposedly the -data previously received from the server in a `Set-Cookie:` line. The data -should be in the format `NAME1=VALUE1; NAME2=VALUE2` or as a single filename. - -When given a set of specific cookies and not a filename, it makes curl use the -cookie header with this content explicitly in all outgoing request(s). If -multiple requests are done due to authentication, followed redirects or -similar, they all get this cookie header passed on. - -If no `=` symbol is used in the argument, it is instead treated as a filename -to read previously stored cookie from. This option also activates the cookie -engine which makes curl record incoming cookies, which may be handy if you are -using this in combination with the --location option or do multiple URL -transfers on the same invoke. +This option has two slightly separate cookie sending functions. + +Either: pass the exact data to send to the HTTP server in the Cookie header. +It is supposedly data previously received from the server in a `Set-Cookie:` +line. The data should be in the format `NAME1=VALUE1; NAME2=VALUE2`. When +given a set of specific cookies, curl populates its cookie header with this +content explicitly in all outgoing request(s). If multiple requests are done +due to authentication, followed redirects or similar, they all get this cookie +header passed on. + +Or: If no `=` symbol is used in the argument, it is instead treated as a +filename to read previously stored cookie from. This option also activates the +cookie engine which makes curl record incoming cookies, which may be handy if +you are using this in combination with the --location option or do multiple +URL transfers on the same invoke. If the filename is a single minus ("-"), curl reads the contents from stdin. If the filename is an empty string ("") and is the only cookie input, curl diff --git a/docs/cmdline-opts/create-dirs.md b/docs/cmdline-opts/create-dirs.md index c509efb0f..89d24f76b 100644 --- a/docs/cmdline-opts/create-dirs.md +++ b/docs/cmdline-opts/create-dirs.md @@ -21,6 +21,6 @@ mentioned with the --output option combined with the path possibly set with --output-dir. If the combined output filename uses no directory, or if the directories it mentions already exist, no directories are created. -Created directories are made with mode 0750 on unix style file systems. +Created directories are made with mode 0750 on Unix-style file systems. To create remote directories when using FTP or SFTP, try --ftp-create-dirs. diff --git a/docs/cmdline-opts/data-binary.md b/docs/cmdline-opts/data-binary.md index 1ce53b32c..4c5e4da8d 100644 --- a/docs/cmdline-opts/data-binary.md +++ b/docs/cmdline-opts/data-binary.md @@ -18,9 +18,10 @@ Example: Post data exactly as specified with no extra processing whatsoever. -If you start the data with the letter @, the rest should be a filename. Data -is posted in a similar manner as --data does, except that newlines and -carriage returns are preserved and conversions are never done. +If you start the data with the letter @, the rest should be a filename. +`@-` makes curl read the data from stdin. Data is posted in a similar +manner as --data does, except that newlines and carriage returns are +preserved and conversions are never done. Like --data the default content-type sent to the server is application/x-www-form-urlencoded. If you want the data to be treated as diff --git a/docs/cmdline-opts/data-urlencode.md b/docs/cmdline-opts/data-urlencode.md index 2bd84f3f1..4edfb4d76 100644 --- a/docs/cmdline-opts/data-urlencode.md +++ b/docs/cmdline-opts/data-urlencode.md @@ -42,7 +42,7 @@ expected to be URL-encoded already. ## @filename load data from the given file (including any newlines), URL-encode that data -and pass it on in the POST. +and pass it on in the POST. Using `@-` makes curl read the data from stdin. ## name@filename load data from the given file (including any newlines), URL-encode that data diff --git a/docs/cmdline-opts/doh-url.md b/docs/cmdline-opts/doh-url.md index 23754cac1..0f745af3b 100644 --- a/docs/cmdline-opts/doh-url.md +++ b/docs/cmdline-opts/doh-url.md @@ -11,6 +11,7 @@ See-also: - doh-insecure Example: - --doh-url https://doh.example $URL + - --doh-url https://doh.example --resolve doh.example:443:192.0.2.1 $URL --- # `--doh-url` @@ -23,5 +24,7 @@ name lookups take place over SSL. However, the certificate verification settings are not inherited but are controlled separately via --doh-insecure and --doh-cert-status. +By default, DoH is bypassed when initially looking up DNS records of the DoH server. You can specify the IP address(es) of the DoH server with --resolve to avoid this. + This option is unset if an empty string "" is used as the URL. (Added in 7.85.0) diff --git a/docs/cmdline-opts/dump-ca-embed.md b/docs/cmdline-opts/dump-ca-embed.md new file mode 100644 index 000000000..2ad123014 --- /dev/null +++ b/docs/cmdline-opts/dump-ca-embed.md @@ -0,0 +1,25 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Long: dump-ca-embed +Help: Write the embedded CA bundle to standard output +Protocols: TLS +Category: http proxy tls +Added: 8.10.0 +Multi: boolean +See-also: + - ca-native + - cacert + - capath + - proxy-ca-native + - proxy-cacert + - proxy-capath +Example: + - --dump-ca-embed +--- + +# `--dump-ca-embed` + +Write the CA bundle embedded in curl to standard output, then quit. + +If curl was not built with a default CA bundle embedded, the output is empty. diff --git a/docs/cmdline-opts/dump-header.md b/docs/cmdline-opts/dump-header.md index 925e6da66..81da38c40 100644 --- a/docs/cmdline-opts/dump-header.md +++ b/docs/cmdline-opts/dump-header.md @@ -19,8 +19,11 @@ Example: # `--dump-header` Write the received protocol headers to the specified file. If no headers are -received, the use of this option creates an empty file. Specify `-` as file -name (a single minus) to have it written to stdout. +received, the use of this option creates an empty file. Specify `-` as +filename (a single minus) to have it written to stdout. + +Starting in curl 8.10.0, specify `%` (a single percent sign) as filename +writes the output to stderr. When used in FTP, the FTP server response lines are considered being "headers" and thus are saved there. diff --git a/docs/cmdline-opts/expect100-timeout.md b/docs/cmdline-opts/expect100-timeout.md index 854761818..80cf4eba6 100644 --- a/docs/cmdline-opts/expect100-timeout.md +++ b/docs/cmdline-opts/expect100-timeout.md @@ -21,5 +21,5 @@ response when curl emits an Expects: 100-continue header in its request. By default curl waits one second. This option accepts decimal values. When curl stops waiting, it continues as if a response was received. -The decimal value needs to provided using a dot (`.`) as decimal separator - +The decimal value needs to be provided using a dot (`.`) as decimal separator - not the local version even if it might be using another separator. diff --git a/docs/cmdline-opts/false-start.md b/docs/cmdline-opts/false-start.md index f25af2374..c6c44ad54 100644 --- a/docs/cmdline-opts/false-start.md +++ b/docs/cmdline-opts/false-start.md @@ -20,4 +20,4 @@ client starts sending application data before verifying the server's Finished message, thus saving a round trip when performing a full handshake. This functionality is currently only implemented in the Secure Transport (on -iOS 7.0 or later, or OS X 10.9 or later) backend. +iOS 7.0 or later, or macOS 10.9 or later) backend. diff --git a/docs/cmdline-opts/form.md b/docs/cmdline-opts/form.md index 5daa571e6..17bfcac0e 100644 --- a/docs/cmdline-opts/form.md +++ b/docs/cmdline-opts/form.md @@ -72,11 +72,13 @@ filename=, like this: If filename/path contains ',' or ';', it must be quoted by double-quotes like: - curl -F "file=@\"local,file\";filename=\"name;in;post\"" example.com + curl -F "file=@\"local,file\";filename=\"name;in;post\"" \ + https://example.com or - curl -F 'file=@"local,file";filename="name;in;post"' example.com + curl -F 'file=@"local,file";filename="name;in;post"' \ + https://example.com Note that if a filename/path is quoted by double-quotes, any double-quote or backslash within the filename must be escaped by backslash. @@ -84,7 +86,8 @@ or backslash within the filename must be escaped by backslash. Quoting must also be applied to non-file data if it contains semicolons, leading/trailing spaces or leading double quotes: - curl -F 'colors="red; green; blue";type=text/x-myapp' example.com + curl -F 'colors="red; green; blue";type=text/x-myapp' \ + https://example.com You can add custom headers to the field by setting headers=, like diff --git a/docs/cmdline-opts/help.md b/docs/cmdline-opts/help.md index 7477a1e40..122c55cd4 100644 --- a/docs/cmdline-opts/help.md +++ b/docs/cmdline-opts/help.md @@ -2,7 +2,7 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Long: help -Arg: +Arg: Short: h Help: Get help for commands Category: important curl @@ -12,15 +12,28 @@ See-also: - verbose Example: - --help all + - --help --insecure + - --help -f --- # `--help` -Usage help. List all curl command line options within the given **category**. +Usage help. Provide help for the subject given as an optional argument. If no argument is provided, curl displays the most important command line arguments. -For category **all**, curl displays help for all options. +The argument can either be a **category** or a **command line option**. When a +category is provided, curl shows all command line options within the given +category. Specify category `all` to list all available options. -If **category** is specified, curl displays all available help categories. +If `category` is specified, curl displays all available help categories. + +If the provided subject is instead an existing command line option, specified +either in its short form with a single dash and a single letter, or in the +long form with two dashes and a longer name, curl displays a help text for +that option in the terminal. + +The help output is extensive for some options. + +If the provided command line option is not known, curl says so. diff --git a/docs/cmdline-opts/http2-prior-knowledge.md b/docs/cmdline-opts/http2-prior-knowledge.md index 727010941..5dffe26a7 100644 --- a/docs/cmdline-opts/http2-prior-knowledge.md +++ b/docs/cmdline-opts/http2-prior-knowledge.md @@ -23,3 +23,7 @@ Issue a non-TLS HTTP requests using HTTP/2 directly without HTTP/1.1 Upgrade. It requires prior knowledge that the server supports HTTP/2 straight away. HTTPS requests still do HTTP/2 the standard way with negotiated protocol version in the TLS handshake. + +Since 8.10.0 if this option is set for an HTTPS request then the application +layer protocol version (ALPN) offered to the server is only HTTP/2. Prior to +that both HTTP/1.1 and HTTP/2 were offered. diff --git a/docs/cmdline-opts/http3.md b/docs/cmdline-opts/http3.md index a1900655a..b5272a60f 100644 --- a/docs/cmdline-opts/http3.md +++ b/docs/cmdline-opts/http3.md @@ -20,14 +20,16 @@ Example: # `--http3` Attempt HTTP/3 to the host in the URL, but fallback to earlier HTTP versions -if the HTTP/3 connection establishment fails. HTTP/3 is only available for -HTTPS and not for HTTP URLs. +if the HTTP/3 connection establishment fails or is slow. HTTP/3 is only +available for HTTPS and not for HTTP URLs. This option allows a user to avoid using the Alt-Svc method of upgrading to -HTTP/3 when you know that the target speaks HTTP/3 on the given host and port. +HTTP/3 when you know or suspect that the target speaks HTTP/3 on the given +host and port. When asked to use HTTP/3, curl issues a separate attempt to use older HTTP versions with a slight delay, so if the HTTP/3 transfer fails or is slow, curl -still tries to proceed with an older HTTP version. +still tries to proceed with an older HTTP version. The fallback performs the +regular negotiation between HTTP/1 and HTTP/2. Use --http3-only for similar functionality *without* a fallback. diff --git a/docs/cmdline-opts/include.md b/docs/cmdline-opts/include.md deleted file mode 100644 index e48799128..000000000 --- a/docs/cmdline-opts/include.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -c: Copyright (C) Daniel Stenberg, , et al. -SPDX-License-Identifier: curl -Long: include -Short: i -Help: Include response headers in output -Protocols: HTTP FTP -Category: important verbose -Added: 4.8 -Multi: boolean -See-also: - - verbose -Example: - - -i $URL ---- - -# `--include` - -Include response headers in the output. HTTP response headers can include -things like server name, cookies, date of the document, HTTP version and -more... With non-HTTP protocols, the "headers" are other server communication. - -To view the request headers, consider the --verbose option. diff --git a/docs/cmdline-opts/ipfs-gateway.md b/docs/cmdline-opts/ipfs-gateway.md index 70ca717a7..e5e8b10bd 100644 --- a/docs/cmdline-opts/ipfs-gateway.md +++ b/docs/cmdline-opts/ipfs-gateway.md @@ -24,7 +24,8 @@ if a `~/.ipfs/gateway` file holding the gateway URL exists. If you run a local IPFS node, this gateway is by default available under `http://localhost:8080`. A full example URL would look like: - curl --ipfs-gateway http://localhost:8080 ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi + curl --ipfs-gateway http://localhost:8080 \ + ipfs://bafybeigagd5nmnn2iys2f3 There are many public IPFS gateways. See for example: https://ipfs.github.io/public-gateway-checker/ diff --git a/docs/cmdline-opts/location-trusted.md b/docs/cmdline-opts/location-trusted.md index edbd0b539..06458a467 100644 --- a/docs/cmdline-opts/location-trusted.md +++ b/docs/cmdline-opts/location-trusted.md @@ -2,7 +2,7 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Long: location-trusted -Help: As --location, but send auth to other hosts +Help: As --location, but send secrets to other hosts Protocols: HTTP Category: http auth Added: 7.10.4 @@ -11,11 +11,16 @@ See-also: - user Example: - --location-trusted -u user:password $URL + - --location-trusted -H "Cookie: session=abc" $URL --- # `--location-trusted` -Like --location, but allows sending the name + password to all hosts that the -site may redirect to. This may or may not introduce a security breach if the -site redirects you to a site to which you send your authentication info (which -is clear-text in the case of HTTP Basic authentication). +Instructs curl to like --location follow HTTP redirects, but permits it to +send credentials and other secrets along to other hosts than the initial one. + +This may or may not introduce a security breach if the site redirects you to a +site to which you send this sensitive data to. Another host means that one or +more of hostname, protocol scheme or port number changed. + +This option also allows curl to pass long cookies set explicitly with --header. diff --git a/docs/cmdline-opts/location.md b/docs/cmdline-opts/location.md index 62e3d470a..dbdcd5bd4 100644 --- a/docs/cmdline-opts/location.md +++ b/docs/cmdline-opts/location.md @@ -20,11 +20,12 @@ Example: If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option makes curl redo the request on the new place. If used together with ---include or --head, headers from all requested pages are shown. +--show-headers or --head, headers from all requested pages are shown. -When authentication is used, curl only sends its credentials to the initial -host. If a redirect takes curl to a different host, it does not get the -user+password pass on. See also --location-trusted on how to change this. +When authentication is used, or send cookie with `-H Cookie:`, curl only sends +its credentials to the initial host. If a redirect takes curl to a different +host, it does not get the credentials pass on. See --location-trusted on how +to change this. Limit the amount of redirects to follow by using the --max-redirs option. diff --git a/docs/cmdline-opts/max-filesize.md b/docs/cmdline-opts/max-filesize.md index 998359cf7..cf2ac6537 100644 --- a/docs/cmdline-opts/max-filesize.md +++ b/docs/cmdline-opts/max-filesize.md @@ -16,9 +16,11 @@ Example: # `--max-filesize` -Specify the maximum size (in bytes) of a file to download. If the file -requested is larger than this value, the transfer does not start and curl -returns with exit code 63. +When set to a non-zero value, it specifies the maximum size (in bytes) of a +file to download. If the file requested is larger than this value, the +transfer does not start and curl returns with exit code 63. + +Setting the maximum value to zero disables the limit. A size modifier may be used. For example, Appending 'k' or 'K' counts the number as kilobytes, 'm' or 'M' makes it megabytes, while 'g' or 'G' makes it diff --git a/docs/cmdline-opts/max-time.md b/docs/cmdline-opts/max-time.md index 1d19e4972..dd5fb23ae 100644 --- a/docs/cmdline-opts/max-time.md +++ b/docs/cmdline-opts/max-time.md @@ -26,5 +26,5 @@ If you enable retrying the transfer (--retry) then the maximum time counter is reset each time the transfer is retried. You can use --retry-max-time to limit the retry time. -The decimal value needs to provided using a dot (.) as decimal separator - not -the local version even if it might be using another separator. +The decimal value needs to be provided using a dot (.) as decimal separator - +not the local version even if it might be using another separator. diff --git a/docs/cmdline-opts/proxy-ca-native.md b/docs/cmdline-opts/proxy-ca-native.md index fd78f12fb..e84dbd960 100644 --- a/docs/cmdline-opts/proxy-ca-native.md +++ b/docs/cmdline-opts/proxy-ca-native.md @@ -10,6 +10,7 @@ Multi: boolean See-also: - cacert - capath + - dump-ca-embed - insecure Example: - --proxy-ca-native $URL diff --git a/docs/cmdline-opts/proxy-cacert.md b/docs/cmdline-opts/proxy-cacert.md index 189ed390d..682349a7e 100644 --- a/docs/cmdline-opts/proxy-cacert.md +++ b/docs/cmdline-opts/proxy-cacert.md @@ -11,6 +11,7 @@ See-also: - proxy-capath - cacert - capath + - dump-ca-embed - proxy Example: - --proxy-cacert CA-file.txt -x https://proxy $URL diff --git a/docs/cmdline-opts/proxy-capath.md b/docs/cmdline-opts/proxy-capath.md index bc2c7b56f..3a3aabf10 100644 --- a/docs/cmdline-opts/proxy-capath.md +++ b/docs/cmdline-opts/proxy-capath.md @@ -11,6 +11,7 @@ See-also: - proxy-cacert - proxy - capath + - dump-ca-embed Example: - --proxy-capath /local/directory -x https://proxy $URL --- diff --git a/docs/cmdline-opts/proxy-ciphers.md b/docs/cmdline-opts/proxy-ciphers.md index 065d44953..420e7563b 100644 --- a/docs/cmdline-opts/proxy-ciphers.md +++ b/docs/cmdline-opts/proxy-ciphers.md @@ -3,24 +3,25 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Long: proxy-ciphers Arg: -Help: SSL ciphers to use for proxy +Help: TLS 1.2 (1.1, 1.0) ciphers to use for proxy +Protocols: TLS Added: 7.52.0 Category: proxy tls Multi: single See-also: + - proxy-tls13-ciphers - ciphers - - curves - proxy Example: - - --proxy-ciphers ECDHE-ECDSA-AES256-CCM8 -x https://proxy $URL + - --proxy-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 -x https://proxy $URL --- # `--proxy-ciphers` Same as --ciphers but used in HTTPS proxy context. -Specifies which ciphers to use in the connection to the HTTPS proxy. The list -of ciphers must specify valid ciphers. Read up on SSL cipher list details on -this URL: +Specify which cipher suites to use in the connection to your HTTPS proxy when +it negotiates TLS 1.2 (1.1, 1.0). The list of ciphers suites must specify +valid ciphers. Read up on cipher suite details on this URL: https://curl.se/docs/ssl-ciphers.html diff --git a/docs/cmdline-opts/proxy-pinnedpubkey.md b/docs/cmdline-opts/proxy-pinnedpubkey.md index 6f0b52d3e..df0b0bb90 100644 --- a/docs/cmdline-opts/proxy-pinnedpubkey.md +++ b/docs/cmdline-opts/proxy-pinnedpubkey.md @@ -27,3 +27,5 @@ When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and if it does not exactly match the public key provided to this option, curl aborts the connection before sending or receiving any data. + +Before curl 8.10.0 this option did not work due to a bug. diff --git a/docs/cmdline-opts/proxy-tls13-ciphers.md b/docs/cmdline-opts/proxy-tls13-ciphers.md index 002fd0b0f..7a03b0f7c 100644 --- a/docs/cmdline-opts/proxy-tls13-ciphers.md +++ b/docs/cmdline-opts/proxy-tls13-ciphers.md @@ -2,28 +2,32 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Long: proxy-tls13-ciphers -Arg: +Arg: help: TLS 1.3 proxy cipher suites Protocols: TLS Category: proxy tls Added: 7.61.0 Multi: single See-also: - - tls13-ciphers - - curves - proxy-ciphers + - tls13-ciphers + - proxy Example: - --proxy-tls13-ciphers TLS_AES_128_GCM_SHA256 -x proxy $URL --- # `--proxy-tls13-ciphers` +Same as --tls13-ciphers but used in HTTPS proxy context. + Specify which cipher suites to use in the connection to your HTTPS proxy when it negotiates TLS 1.3. The list of ciphers suites must specify valid ciphers. Read up on TLS 1.3 cipher suite details on this URL: https://curl.se/docs/ssl-ciphers.html -This option is currently used only when curl is built to use OpenSSL 1.1.1 or -later. If you are using a different SSL backend you can try setting TLS 1.3 -cipher suites by using the --proxy-ciphers option. +This option is used when curl is built to use OpenSSL 1.1.1 or later, +Schannel, wolfSSL, or mbedTLS 3.6.0 or later. + +Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites where set +by using the --proxy-ciphers option. diff --git a/docs/cmdline-opts/proxy.md b/docs/cmdline-opts/proxy.md index 51f638c67..529d3369f 100644 --- a/docs/cmdline-opts/proxy.md +++ b/docs/cmdline-opts/proxy.md @@ -28,7 +28,7 @@ Unix domain sockets are supported for socks proxy. Set localhost for the host part. e.g. socks5h://localhost/path/to/socket.sock HTTPS proxy support works set with the https:// protocol prefix for OpenSSL -and GnuTLS (added in 7.52.0). It also works for BearSSL, mbedTLS, rustls, +and GnuTLS (added in 7.52.0). It also works for BearSSL, mbedTLS, Rustls, Schannel, Secure Transport and wolfSSL (added in 7.87.0). Unrecognized and unsupported proxy protocols cause an error (added in 7.52.0). diff --git a/docs/cmdline-opts/rate.md b/docs/cmdline-opts/rate.md index 49d0010b8..6de65165d 100644 --- a/docs/cmdline-opts/rate.md +++ b/docs/cmdline-opts/rate.md @@ -40,3 +40,7 @@ more than 1000 per second, it instead runs unrestricted. When retrying transfers, enabled with --retry, the separate retry delay logic is used and not this setting. + +Starting in version 8.10.0, you can specify number of time units in the rate +expression. Make curl do no more than 5 transfers per 15 seconds with "5/15s" +or limit it to 3 transfers per 4 hours with "3/4h". No spaces allowed. diff --git a/docs/cmdline-opts/remote-name.md b/docs/cmdline-opts/remote-name.md index 041800fa9..e39dd51ae 100644 --- a/docs/cmdline-opts/remote-name.md +++ b/docs/cmdline-opts/remote-name.md @@ -35,3 +35,8 @@ There is no URL decoding done on the filename. If it has %20 or other URL encoded parts of the name, they end up as-is as filename. You may use this option as many times as the number of URLs you have. + +Before curl 8.10.0, curl returned an error if the URL ended with a slash, +which means that there is no filename part in the URL. Starting in 8.10.0, +curl sets the filename to the last directory part of the URL or if that also +is missing to `curl_response` (without extension) for this situation. diff --git a/docs/cmdline-opts/show-headers.md b/docs/cmdline-opts/show-headers.md new file mode 100644 index 000000000..126610f7c --- /dev/null +++ b/docs/cmdline-opts/show-headers.md @@ -0,0 +1,29 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Long: show-headers +Short: i +Help: Show response headers in output +Protocols: HTTP FTP +Category: important verbose output +Added: 4.8 +Multi: boolean +See-also: + - verbose +Example: + - -i $URL +--- + +# `--show-headers` + +Show response headers in the output. HTTP response headers can include things +like server name, cookies, date of the document, HTTP version and more. With +non-HTTP protocols, the "headers" are other server communication. + +To view the request headers, consider the --verbose option. + +Prior to 7.75.0 curl did not print the headers if --fail was used in +combination with this option and there was error reported by server. + +This option was called --include before 8.10.0. The previous name remains +functional. diff --git a/docs/cmdline-opts/skip-existing.md b/docs/cmdline-opts/skip-existing.md new file mode 100644 index 000000000..cfb7c2f95 --- /dev/null +++ b/docs/cmdline-opts/skip-existing.md @@ -0,0 +1,22 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Long: skip-existing +Help: Skip download if local file already exists +Category: curl output +Added: 8.10.0 +Multi: boolean +See-also: + - output + - remote-name + - no-clobber +Example: + - --skip-existing --output local/dir/file $URL +--- + +# `--skip-existing` + +If there is a local file present when a download is requested, the operation +is skipped. Note that curl cannot know if the local file was previously +downloaded fine, or if it is incomplete etc, it just knows if there is a +filename present in the file system or not and it skips the transfer if it is. diff --git a/docs/cmdline-opts/socks4.md b/docs/cmdline-opts/socks4.md index e74fa787c..99a7fc922 100644 --- a/docs/cmdline-opts/socks4.md +++ b/docs/cmdline-opts/socks4.md @@ -21,7 +21,7 @@ Use the specified SOCKS4 proxy. If the port number is not specified, it is assumed at port 1080. Using this socket type make curl resolve the hostname and passing the address on to the proxy. -To specify proxy on a unix domain socket, use localhost for host, e.g. +To specify proxy on a Unix domain socket, use localhost for host, e.g. `socks4://localhost/path/to/socket.sock` This option overrides any previous use of --proxy, as they are mutually diff --git a/docs/cmdline-opts/socks4a.md b/docs/cmdline-opts/socks4a.md index 49fb9a275..04d60b81b 100644 --- a/docs/cmdline-opts/socks4a.md +++ b/docs/cmdline-opts/socks4a.md @@ -20,7 +20,7 @@ Example: Use the specified SOCKS4a proxy. If the port number is not specified, it is assumed at port 1080. This asks the proxy to resolve the hostname. -To specify proxy on a unix domain socket, use localhost for host, e.g. +To specify proxy on a Unix domain socket, use localhost for host, e.g. `socks4a://localhost/path/to/socket.sock` This option overrides any previous use of --proxy, as they are mutually diff --git a/docs/cmdline-opts/socks5-hostname.md b/docs/cmdline-opts/socks5-hostname.md index 1a5e4c1b5..0ea2ed739 100644 --- a/docs/cmdline-opts/socks5-hostname.md +++ b/docs/cmdline-opts/socks5-hostname.md @@ -19,7 +19,7 @@ Example: Use the specified SOCKS5 proxy (and let the proxy resolve the hostname). If the port number is not specified, it is assumed at port 1080. -To specify proxy on a unix domain socket, use localhost for host, e.g. +To specify proxy on a Unix domain socket, use localhost for host, e.g. `socks5h://localhost/path/to/socket.sock` This option overrides any previous use of --proxy, as they are mutually diff --git a/docs/cmdline-opts/socks5.md b/docs/cmdline-opts/socks5.md index 192adef4a..4ea660d62 100644 --- a/docs/cmdline-opts/socks5.md +++ b/docs/cmdline-opts/socks5.md @@ -19,7 +19,7 @@ Example: Use the specified SOCKS5 proxy - but resolve the hostname locally. If the port number is not specified, it is assumed at port 1080. -To specify proxy on a unix domain socket, use localhost for host, e.g. +To specify proxy on a Unix domain socket, use localhost for host, e.g. `socks5://localhost/path/to/socket.sock` This option overrides any previous use of --proxy, as they are mutually diff --git a/docs/cmdline-opts/suppress-connect-headers.md b/docs/cmdline-opts/suppress-connect-headers.md index 9e2eefea4..e9e32c0ab 100644 --- a/docs/cmdline-opts/suppress-connect-headers.md +++ b/docs/cmdline-opts/suppress-connect-headers.md @@ -8,15 +8,16 @@ Added: 7.54.0 Multi: boolean See-also: - dump-header - - include + - show-headers - proxytunnel Example: - - --suppress-connect-headers --include -x proxy $URL + - --suppress-connect-headers --show-headers -x proxy $URL --- # `--suppress-connect-headers` When --proxytunnel is used and a CONNECT request is made do not output proxy -CONNECT response headers. This option is meant to be used with --dump-header or ---include which are used to show protocol headers in the output. It has no -effect on debug options such as --verbose or --trace, or any statistics. +CONNECT response headers. This option is meant to be used with --dump-header +or --show-headers which are used to show protocol headers in the output. It +has no effect on debug options such as --verbose or --trace, or any +statistics. diff --git a/docs/cmdline-opts/tls13-ciphers.md b/docs/cmdline-opts/tls13-ciphers.md index 55145aacf..0f1ff33ce 100644 --- a/docs/cmdline-opts/tls13-ciphers.md +++ b/docs/cmdline-opts/tls13-ciphers.md @@ -10,8 +10,8 @@ Added: 7.61.0 Multi: single See-also: - ciphers - - curves - proxy-tls13-ciphers + - curves Example: - --tls13-ciphers TLS_AES_128_GCM_SHA256 $URL --- @@ -24,6 +24,8 @@ cipher suite details on this URL: https://curl.se/docs/ssl-ciphers.html -This option is currently used only when curl is built to use OpenSSL 1.1.1 or -later, or Schannel. If you are using a different SSL backend you can try -setting TLS 1.3 cipher suites by using the --ciphers option. +This option is used when curl is built to use OpenSSL 1.1.1 or later, +Schannel, wolfSSL, or mbedTLS 3.6.0 or later. + +Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites where set +by using the --ciphers option. diff --git a/docs/cmdline-opts/use-ascii.md b/docs/cmdline-opts/use-ascii.md index c452ffbb1..30cc860b0 100644 --- a/docs/cmdline-opts/use-ascii.md +++ b/docs/cmdline-opts/use-ascii.md @@ -19,4 +19,4 @@ Example: Enable ASCII transfer mode. For FTP, this can also be enforced by using a URL that ends with `;type=A`. This option causes data sent to stdout to be in text -mode for win32 systems. +mode for Win32 systems. diff --git a/docs/cmdline-opts/verbose.md b/docs/cmdline-opts/verbose.md index 9c42981ad..d29e23a7b 100644 --- a/docs/cmdline-opts/verbose.md +++ b/docs/cmdline-opts/verbose.md @@ -10,7 +10,7 @@ Added: 4.0 Multi: boolean Scope: global See-also: - - include + - show-headers - silent - trace - trace-ascii @@ -25,11 +25,30 @@ what's going on under the hood. A line starting with \> means header data sent by curl, \< means header data received by curl that is hidden in normal cases, and a line starting with * means additional info provided by curl. -If you only want HTTP headers in the output, --include or --dump-header might -be more suitable options. +If you only want HTTP headers in the output, --show-headers or --dump-header +might be more suitable options. -If you think this option still does not give you enough details, consider using ---trace or --trace-ascii instead. +Since curl 8.10, mentioning this option several times in the same argument +increases the level of the trace output. However, as before, a single +--verbose or --no-verbose reverts any additions by previous `-vv` again. This +means that `-vv -v` is equivalent to a single -v. This avoids unwanted +verbosity when the option is mentioned in the command line *and* curl config +files. + +Using it twice, e.g. `-vv`, outputs time (--trace-time) and transfer ids +(--trace-ids), as well as enable tracing for all protocols (--trace-config +protocol). + +Adding a third verbose outputs transfer content (--trace-ascii %) and enable +tracing of more components (--trace-config read,write,ssl). + +A forth time adds tracing of all network components. (--trace-config network). + +Any addition of the verbose option after that has no effect. + +If you think this option does not give you the right details, consider using +--trace or --trace-ascii instead. Or use it only once and use --trace-config +to trace the specific components you wish to see. Note that verbose output of curl activities and network traffic might contain sensitive data, including usernames, credentials or secret data content. Be diff --git a/docs/cmdline-opts/version.md b/docs/cmdline-opts/version.md index 6a7919f89..948e9672f 100644 --- a/docs/cmdline-opts/version.md +++ b/docs/cmdline-opts/version.md @@ -92,6 +92,7 @@ NTLM authentication is supported. ## `NTLM_WB` NTLM delegation to winbind helper is supported. +This feature was removed from curl in 8.8.0. ## `PSL` PSL is short for Public Suffix List and means that this curl has been built diff --git a/docs/cmdline-opts/write-out.md b/docs/cmdline-opts/write-out.md index acfb59dcc..3f8af2b5e 100644 --- a/docs/cmdline-opts/write-out.md +++ b/docs/cmdline-opts/write-out.md @@ -221,6 +221,10 @@ remote host (or proxy) was completed. The time, in seconds, it took from the start until the name resolving was completed. +## `time_posttransfer` +The time it took from the start until the last byte is sent by libcurl. +In microseconds. (Added in 8.10.0) + ## `time_pretransfer` The time, in seconds, it took from the start until the file transfer was just about to begin. This includes all pre-transfer commands and negotiations that diff --git a/docs/examples/CMakeLists.txt b/docs/examples/CMakeLists.txt new file mode 100644 index 000000000..ea2b8035c --- /dev/null +++ b/docs/examples/CMakeLists.txt @@ -0,0 +1,40 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +# Get 'check_PROGRAMS' variable +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +foreach(_target IN LISTS check_PROGRAMS) + set(_target_name "curl-example-${_target}") + add_executable(${_target_name} "${_target}.c") + target_link_libraries(${_target_name} ${LIB_SELECTED} ${CURL_LIBS}) + target_compile_definitions(${_target_name} PRIVATE "CURL_NO_OLDIES") + if(LIB_SELECTED STREQUAL LIB_STATIC AND WIN32) + set_property(TARGET ${_target_name} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") + endif() + set_target_properties(${_target_name} PROPERTIES + OUTPUT_NAME "${_target}" UNITY_BUILD OFF + PROJECT_LABEL "Example ${_target}") +endforeach() diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am index 80ccc5925..91f90cf65 100644 --- a/docs/examples/Makefile.am +++ b/docs/examples/Makefile.am @@ -24,7 +24,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc -EXTRA_DIST = README.md Makefile.example Makefile.inc Makefile.mk \ +EXTRA_DIST = README.md Makefile.example Makefile.mk CMakeLists.txt \ $(COMPLICATED_EXAMPLES) .checksrc # Specify our include paths here, and do it relative to $(top_srcdir) and @@ -50,11 +50,7 @@ endif LIBS = $(BLANK_AT_MAKETIME) # Dependencies -if USE_EXPLICIT_LIB_DEPS -LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@ -else -LDADD = $(LIBDIR)/libcurl.la -endif +LDADD = $(LIBDIR)/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # This might hold -Werror CFLAGS += @CURL_CFLAG_EXTRAS@ diff --git a/docs/examples/Makefile.in b/docs/examples/Makefile.in index 63b21e5f3..a52ef4331 100644 --- a/docs/examples/Makefile.in +++ b/docs/examples/Makefile.in @@ -215,10 +215,7 @@ CONFIG_CLEAN_VPATH_FILES = 10_at_a_time_SOURCES = 10-at-a-time.c 10_at_a_time_OBJECTS = 10-at-a-time.$(OBJEXT) 10_at_a_time_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@10_at_a_time_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@10_at_a_time_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +10_at_a_time_DEPENDENCIES = $(LIBDIR)/libcurl.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -226,759 +223,439 @@ am__v_lt_1 = address_scope_SOURCES = address-scope.c address_scope_OBJECTS = address-scope.$(OBJEXT) address_scope_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@address_scope_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@address_scope_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +address_scope_DEPENDENCIES = $(LIBDIR)/libcurl.la altsvc_SOURCES = altsvc.c altsvc_OBJECTS = altsvc.$(OBJEXT) altsvc_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@altsvc_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@altsvc_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +altsvc_DEPENDENCIES = $(LIBDIR)/libcurl.la anyauthput_SOURCES = anyauthput.c anyauthput_OBJECTS = anyauthput.$(OBJEXT) anyauthput_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@anyauthput_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@anyauthput_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +anyauthput_DEPENDENCIES = $(LIBDIR)/libcurl.la certinfo_SOURCES = certinfo.c certinfo_OBJECTS = certinfo.$(OBJEXT) certinfo_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@certinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@certinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +certinfo_DEPENDENCIES = $(LIBDIR)/libcurl.la chkspeed_SOURCES = chkspeed.c chkspeed_OBJECTS = chkspeed.$(OBJEXT) chkspeed_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@chkspeed_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@chkspeed_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +chkspeed_DEPENDENCIES = $(LIBDIR)/libcurl.la connect_to_SOURCES = connect-to.c connect_to_OBJECTS = connect-to.$(OBJEXT) connect_to_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@connect_to_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@connect_to_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +connect_to_DEPENDENCIES = $(LIBDIR)/libcurl.la cookie_interface_SOURCES = cookie_interface.c cookie_interface_OBJECTS = cookie_interface.$(OBJEXT) cookie_interface_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@cookie_interface_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@cookie_interface_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +cookie_interface_DEPENDENCIES = $(LIBDIR)/libcurl.la debug_SOURCES = debug.c debug_OBJECTS = debug.$(OBJEXT) debug_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@debug_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@debug_DEPENDENCIES = $(LIBDIR)/libcurl.la +debug_DEPENDENCIES = $(LIBDIR)/libcurl.la default_scheme_SOURCES = default-scheme.c default_scheme_OBJECTS = default-scheme.$(OBJEXT) default_scheme_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@default_scheme_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@default_scheme_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +default_scheme_DEPENDENCIES = $(LIBDIR)/libcurl.la externalsocket_SOURCES = externalsocket.c externalsocket_OBJECTS = externalsocket.$(OBJEXT) externalsocket_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@externalsocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@externalsocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +externalsocket_DEPENDENCIES = $(LIBDIR)/libcurl.la fileupload_SOURCES = fileupload.c fileupload_OBJECTS = fileupload.$(OBJEXT) fileupload_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@fileupload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@fileupload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +fileupload_DEPENDENCIES = $(LIBDIR)/libcurl.la ftp_wildcard_SOURCES = ftp-wildcard.c ftp_wildcard_OBJECTS = ftp-wildcard.$(OBJEXT) ftp_wildcard_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftp_wildcard_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftp_wildcard_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftp_wildcard_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpget_SOURCES = ftpget.c ftpget_OBJECTS = ftpget.$(OBJEXT) ftpget_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpget_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpgetinfo_SOURCES = ftpgetinfo.c ftpgetinfo_OBJECTS = ftpgetinfo.$(OBJEXT) ftpgetinfo_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpgetinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpgetinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpgetinfo_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpgetresp_SOURCES = ftpgetresp.c ftpgetresp_OBJECTS = ftpgetresp.$(OBJEXT) ftpgetresp_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpgetresp_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpgetresp_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpgetresp_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpsget_SOURCES = ftpsget.c ftpsget_OBJECTS = ftpsget.$(OBJEXT) ftpsget_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpsget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpsget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpsget_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpupload_SOURCES = ftpupload.c ftpupload_OBJECTS = ftpupload.$(OBJEXT) ftpupload_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpupload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpupload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpupload_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpuploadfrommem_SOURCES = ftpuploadfrommem.c ftpuploadfrommem_OBJECTS = ftpuploadfrommem.$(OBJEXT) ftpuploadfrommem_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpuploadfrommem_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpuploadfrommem_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpuploadfrommem_DEPENDENCIES = $(LIBDIR)/libcurl.la ftpuploadresume_SOURCES = ftpuploadresume.c ftpuploadresume_OBJECTS = ftpuploadresume.$(OBJEXT) ftpuploadresume_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ftpuploadresume_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ftpuploadresume_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ftpuploadresume_DEPENDENCIES = $(LIBDIR)/libcurl.la getinfo_SOURCES = getinfo.c getinfo_OBJECTS = getinfo.$(OBJEXT) getinfo_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@getinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@getinfo_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +getinfo_DEPENDENCIES = $(LIBDIR)/libcurl.la getinmemory_SOURCES = getinmemory.c getinmemory_OBJECTS = getinmemory.$(OBJEXT) getinmemory_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@getinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@getinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +getinmemory_DEPENDENCIES = $(LIBDIR)/libcurl.la getredirect_SOURCES = getredirect.c getredirect_OBJECTS = getredirect.$(OBJEXT) getredirect_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@getredirect_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@getredirect_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +getredirect_DEPENDENCIES = $(LIBDIR)/libcurl.la getreferrer_SOURCES = getreferrer.c getreferrer_OBJECTS = getreferrer.$(OBJEXT) getreferrer_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@getreferrer_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@getreferrer_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +getreferrer_DEPENDENCIES = $(LIBDIR)/libcurl.la headerapi_SOURCES = headerapi.c headerapi_OBJECTS = headerapi.$(OBJEXT) headerapi_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@headerapi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@headerapi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +headerapi_DEPENDENCIES = $(LIBDIR)/libcurl.la hsts_preload_SOURCES = hsts-preload.c hsts_preload_OBJECTS = hsts-preload.$(OBJEXT) hsts_preload_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@hsts_preload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@hsts_preload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +hsts_preload_DEPENDENCIES = $(LIBDIR)/libcurl.la http_options_SOURCES = http-options.c http_options_OBJECTS = http-options.$(OBJEXT) http_options_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http_options_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http_options_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http_options_DEPENDENCIES = $(LIBDIR)/libcurl.la http_post_SOURCES = http-post.c http_post_OBJECTS = http-post.$(OBJEXT) http_post_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http_post_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http_post_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http_post_DEPENDENCIES = $(LIBDIR)/libcurl.la http2_download_SOURCES = http2-download.c http2_download_OBJECTS = http2-download.$(OBJEXT) http2_download_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http2_download_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http2_download_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http2_download_DEPENDENCIES = $(LIBDIR)/libcurl.la http2_pushinmemory_SOURCES = http2-pushinmemory.c http2_pushinmemory_OBJECTS = http2-pushinmemory.$(OBJEXT) http2_pushinmemory_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http2_pushinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http2_pushinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http2_pushinmemory_DEPENDENCIES = $(LIBDIR)/libcurl.la http2_serverpush_SOURCES = http2-serverpush.c http2_serverpush_OBJECTS = http2-serverpush.$(OBJEXT) http2_serverpush_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http2_serverpush_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http2_serverpush_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http2_serverpush_DEPENDENCIES = $(LIBDIR)/libcurl.la http2_upload_SOURCES = http2-upload.c http2_upload_OBJECTS = http2-upload.$(OBJEXT) http2_upload_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http2_upload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http2_upload_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http2_upload_DEPENDENCIES = $(LIBDIR)/libcurl.la http3_SOURCES = http3.c http3_OBJECTS = http3.$(OBJEXT) http3_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http3_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http3_DEPENDENCIES = $(LIBDIR)/libcurl.la +http3_DEPENDENCIES = $(LIBDIR)/libcurl.la http3_present_SOURCES = http3-present.c http3_present_OBJECTS = http3-present.$(OBJEXT) http3_present_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@http3_present_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@http3_present_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +http3_present_DEPENDENCIES = $(LIBDIR)/libcurl.la httpcustomheader_SOURCES = httpcustomheader.c httpcustomheader_OBJECTS = httpcustomheader.$(OBJEXT) httpcustomheader_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@httpcustomheader_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@httpcustomheader_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +httpcustomheader_DEPENDENCIES = $(LIBDIR)/libcurl.la httpput_SOURCES = httpput.c httpput_OBJECTS = httpput.$(OBJEXT) httpput_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@httpput_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@httpput_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +httpput_DEPENDENCIES = $(LIBDIR)/libcurl.la httpput_postfields_SOURCES = httpput-postfields.c httpput_postfields_OBJECTS = httpput-postfields.$(OBJEXT) httpput_postfields_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@httpput_postfields_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@httpput_postfields_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +httpput_postfields_DEPENDENCIES = $(LIBDIR)/libcurl.la https_SOURCES = https.c https_OBJECTS = https.$(OBJEXT) https_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@https_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@https_DEPENDENCIES = $(LIBDIR)/libcurl.la +https_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_append_SOURCES = imap-append.c imap_append_OBJECTS = imap-append.$(OBJEXT) imap_append_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_append_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_append_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_append_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_authzid_SOURCES = imap-authzid.c imap_authzid_OBJECTS = imap-authzid.$(OBJEXT) imap_authzid_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_authzid_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_copy_SOURCES = imap-copy.c imap_copy_OBJECTS = imap-copy.$(OBJEXT) imap_copy_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_copy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_copy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_copy_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_create_SOURCES = imap-create.c imap_create_OBJECTS = imap-create.$(OBJEXT) imap_create_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_create_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_create_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_create_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_delete_SOURCES = imap-delete.c imap_delete_OBJECTS = imap-delete.$(OBJEXT) imap_delete_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_delete_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_delete_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_delete_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_examine_SOURCES = imap-examine.c imap_examine_OBJECTS = imap-examine.$(OBJEXT) imap_examine_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_examine_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_examine_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_examine_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_fetch_SOURCES = imap-fetch.c imap_fetch_OBJECTS = imap-fetch.$(OBJEXT) imap_fetch_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_fetch_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_fetch_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_fetch_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_list_SOURCES = imap-list.c imap_list_OBJECTS = imap-list.$(OBJEXT) imap_list_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_list_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_list_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_list_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_lsub_SOURCES = imap-lsub.c imap_lsub_OBJECTS = imap-lsub.$(OBJEXT) imap_lsub_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_lsub_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_lsub_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_lsub_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_multi_SOURCES = imap-multi.c imap_multi_OBJECTS = imap-multi.$(OBJEXT) imap_multi_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_multi_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_noop_SOURCES = imap-noop.c imap_noop_OBJECTS = imap-noop.$(OBJEXT) imap_noop_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_noop_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_noop_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_noop_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_search_SOURCES = imap-search.c imap_search_OBJECTS = imap-search.$(OBJEXT) imap_search_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_search_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_search_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_search_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_ssl_SOURCES = imap-ssl.c imap_ssl_OBJECTS = imap-ssl.$(OBJEXT) imap_ssl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_ssl_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_store_SOURCES = imap-store.c imap_store_OBJECTS = imap-store.$(OBJEXT) imap_store_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_store_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_store_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_store_DEPENDENCIES = $(LIBDIR)/libcurl.la imap_tls_SOURCES = imap-tls.c imap_tls_OBJECTS = imap-tls.$(OBJEXT) imap_tls_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@imap_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@imap_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +imap_tls_DEPENDENCIES = $(LIBDIR)/libcurl.la interface_SOURCES = interface.c interface_OBJECTS = interface.$(OBJEXT) interface_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@interface_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@interface_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +interface_DEPENDENCIES = $(LIBDIR)/libcurl.la ipv6_SOURCES = ipv6.c ipv6_OBJECTS = ipv6.$(OBJEXT) ipv6_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ipv6_DEPENDENCIES = $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ipv6_DEPENDENCIES = $(LIBDIR)/libcurl.la +ipv6_DEPENDENCIES = $(LIBDIR)/libcurl.la keepalive_SOURCES = keepalive.c keepalive_OBJECTS = keepalive.$(OBJEXT) keepalive_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@keepalive_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@keepalive_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +keepalive_DEPENDENCIES = $(LIBDIR)/libcurl.la localport_SOURCES = localport.c localport_OBJECTS = localport.$(OBJEXT) localport_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@localport_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@localport_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +localport_DEPENDENCIES = $(LIBDIR)/libcurl.la maxconnects_SOURCES = maxconnects.c maxconnects_OBJECTS = maxconnects.$(OBJEXT) maxconnects_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@maxconnects_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@maxconnects_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +maxconnects_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_app_SOURCES = multi-app.c multi_app_OBJECTS = multi-app.$(OBJEXT) multi_app_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_app_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_app_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_app_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_debugcallback_SOURCES = multi-debugcallback.c multi_debugcallback_OBJECTS = multi-debugcallback.$(OBJEXT) multi_debugcallback_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_debugcallback_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_debugcallback_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_debugcallback_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_double_SOURCES = multi-double.c multi_double_OBJECTS = multi-double.$(OBJEXT) multi_double_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_double_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_double_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_double_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_formadd_SOURCES = multi-formadd.c multi_formadd_OBJECTS = multi-formadd.$(OBJEXT) multi_formadd_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_formadd_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_formadd_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_formadd_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_legacy_SOURCES = multi-legacy.c multi_legacy_OBJECTS = multi-legacy.$(OBJEXT) multi_legacy_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_legacy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_legacy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_legacy_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_post_SOURCES = multi-post.c multi_post_OBJECTS = multi-post.$(OBJEXT) multi_post_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_post_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_post_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_post_DEPENDENCIES = $(LIBDIR)/libcurl.la multi_single_SOURCES = multi-single.c multi_single_OBJECTS = multi-single.$(OBJEXT) multi_single_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@multi_single_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@multi_single_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +multi_single_DEPENDENCIES = $(LIBDIR)/libcurl.la netrc_SOURCES = netrc.c netrc_OBJECTS = netrc.$(OBJEXT) netrc_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@netrc_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@netrc_DEPENDENCIES = $(LIBDIR)/libcurl.la +netrc_DEPENDENCIES = $(LIBDIR)/libcurl.la parseurl_SOURCES = parseurl.c parseurl_OBJECTS = parseurl.$(OBJEXT) parseurl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@parseurl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@parseurl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +parseurl_DEPENDENCIES = $(LIBDIR)/libcurl.la persistent_SOURCES = persistent.c persistent_OBJECTS = persistent.$(OBJEXT) persistent_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@persistent_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@persistent_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +persistent_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_authzid_SOURCES = pop3-authzid.c pop3_authzid_OBJECTS = pop3-authzid.$(OBJEXT) pop3_authzid_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_authzid_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_dele_SOURCES = pop3-dele.c pop3_dele_OBJECTS = pop3-dele.$(OBJEXT) pop3_dele_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_dele_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_dele_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_dele_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_list_SOURCES = pop3-list.c pop3_list_OBJECTS = pop3-list.$(OBJEXT) pop3_list_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_list_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_list_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_list_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_multi_SOURCES = pop3-multi.c pop3_multi_OBJECTS = pop3-multi.$(OBJEXT) pop3_multi_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_multi_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_noop_SOURCES = pop3-noop.c pop3_noop_OBJECTS = pop3-noop.$(OBJEXT) pop3_noop_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_noop_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_noop_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_noop_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_retr_SOURCES = pop3-retr.c pop3_retr_OBJECTS = pop3-retr.$(OBJEXT) pop3_retr_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_retr_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_retr_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_retr_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_ssl_SOURCES = pop3-ssl.c pop3_ssl_OBJECTS = pop3-ssl.$(OBJEXT) pop3_ssl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_ssl_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_stat_SOURCES = pop3-stat.c pop3_stat_OBJECTS = pop3-stat.$(OBJEXT) pop3_stat_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_stat_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_stat_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_stat_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_tls_SOURCES = pop3-tls.c pop3_tls_OBJECTS = pop3-tls.$(OBJEXT) pop3_tls_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_tls_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_top_SOURCES = pop3-top.c pop3_top_OBJECTS = pop3-top.$(OBJEXT) pop3_top_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_top_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_top_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_top_DEPENDENCIES = $(LIBDIR)/libcurl.la pop3_uidl_SOURCES = pop3-uidl.c pop3_uidl_OBJECTS = pop3-uidl.$(OBJEXT) pop3_uidl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@pop3_uidl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@pop3_uidl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +pop3_uidl_DEPENDENCIES = $(LIBDIR)/libcurl.la post_callback_SOURCES = post-callback.c post_callback_OBJECTS = post-callback.$(OBJEXT) post_callback_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@post_callback_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@post_callback_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +post_callback_DEPENDENCIES = $(LIBDIR)/libcurl.la postinmemory_SOURCES = postinmemory.c postinmemory_OBJECTS = postinmemory.$(OBJEXT) postinmemory_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@postinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@postinmemory_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +postinmemory_DEPENDENCIES = $(LIBDIR)/libcurl.la postit2_SOURCES = postit2.c postit2_OBJECTS = postit2.$(OBJEXT) postit2_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@postit2_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@postit2_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +postit2_DEPENDENCIES = $(LIBDIR)/libcurl.la postit2_formadd_SOURCES = postit2-formadd.c postit2_formadd_OBJECTS = postit2-formadd.$(OBJEXT) postit2_formadd_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@postit2_formadd_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@postit2_formadd_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +postit2_formadd_DEPENDENCIES = $(LIBDIR)/libcurl.la progressfunc_SOURCES = progressfunc.c progressfunc_OBJECTS = progressfunc.$(OBJEXT) progressfunc_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@progressfunc_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@progressfunc_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +progressfunc_DEPENDENCIES = $(LIBDIR)/libcurl.la protofeats_SOURCES = protofeats.c protofeats_OBJECTS = protofeats.$(OBJEXT) protofeats_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@protofeats_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@protofeats_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +protofeats_DEPENDENCIES = $(LIBDIR)/libcurl.la range_SOURCES = range.c range_OBJECTS = range.$(OBJEXT) range_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@range_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@range_DEPENDENCIES = $(LIBDIR)/libcurl.la +range_DEPENDENCIES = $(LIBDIR)/libcurl.la resolve_SOURCES = resolve.c resolve_OBJECTS = resolve.$(OBJEXT) resolve_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@resolve_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@resolve_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +resolve_DEPENDENCIES = $(LIBDIR)/libcurl.la rtsp_options_SOURCES = rtsp-options.c rtsp_options_OBJECTS = rtsp-options.$(OBJEXT) rtsp_options_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@rtsp_options_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@rtsp_options_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +rtsp_options_DEPENDENCIES = $(LIBDIR)/libcurl.la sendrecv_SOURCES = sendrecv.c sendrecv_OBJECTS = sendrecv.$(OBJEXT) sendrecv_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@sendrecv_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@sendrecv_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +sendrecv_DEPENDENCIES = $(LIBDIR)/libcurl.la sepheaders_SOURCES = sepheaders.c sepheaders_OBJECTS = sepheaders.$(OBJEXT) sepheaders_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@sepheaders_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@sepheaders_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +sepheaders_DEPENDENCIES = $(LIBDIR)/libcurl.la sftpget_SOURCES = sftpget.c sftpget_OBJECTS = sftpget.$(OBJEXT) sftpget_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@sftpget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@sftpget_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +sftpget_DEPENDENCIES = $(LIBDIR)/libcurl.la sftpuploadresume_SOURCES = sftpuploadresume.c sftpuploadresume_OBJECTS = sftpuploadresume.$(OBJEXT) sftpuploadresume_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@sftpuploadresume_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@sftpuploadresume_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +sftpuploadresume_DEPENDENCIES = $(LIBDIR)/libcurl.la shared_connection_cache_SOURCES = shared-connection-cache.c shared_connection_cache_OBJECTS = shared-connection-cache.$(OBJEXT) shared_connection_cache_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@shared_connection_cache_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@shared_connection_cache_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +shared_connection_cache_DEPENDENCIES = $(LIBDIR)/libcurl.la simple_SOURCES = simple.c simple_OBJECTS = simple.$(OBJEXT) simple_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@simple_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@simple_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +simple_DEPENDENCIES = $(LIBDIR)/libcurl.la simplepost_SOURCES = simplepost.c simplepost_OBJECTS = simplepost.$(OBJEXT) simplepost_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@simplepost_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@simplepost_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +simplepost_DEPENDENCIES = $(LIBDIR)/libcurl.la simplessl_SOURCES = simplessl.c simplessl_OBJECTS = simplessl.$(OBJEXT) simplessl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@simplessl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@simplessl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +simplessl_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_authzid_SOURCES = smtp-authzid.c smtp_authzid_OBJECTS = smtp-authzid.$(OBJEXT) smtp_authzid_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_authzid_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_authzid_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_expn_SOURCES = smtp-expn.c smtp_expn_OBJECTS = smtp-expn.$(OBJEXT) smtp_expn_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_expn_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_expn_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_expn_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_mail_SOURCES = smtp-mail.c smtp_mail_OBJECTS = smtp-mail.$(OBJEXT) smtp_mail_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_mail_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_mail_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_mail_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_mime_SOURCES = smtp-mime.c smtp_mime_OBJECTS = smtp-mime.$(OBJEXT) smtp_mime_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_mime_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_mime_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_mime_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_multi_SOURCES = smtp-multi.c smtp_multi_OBJECTS = smtp-multi.$(OBJEXT) smtp_multi_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_multi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_multi_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_ssl_SOURCES = smtp-ssl.c smtp_ssl_OBJECTS = smtp-ssl.$(OBJEXT) smtp_ssl_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_ssl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_ssl_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_tls_SOURCES = smtp-tls.c smtp_tls_OBJECTS = smtp-tls.$(OBJEXT) smtp_tls_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_tls_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_tls_DEPENDENCIES = $(LIBDIR)/libcurl.la smtp_vrfy_SOURCES = smtp-vrfy.c smtp_vrfy_OBJECTS = smtp-vrfy.$(OBJEXT) smtp_vrfy_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@smtp_vrfy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@smtp_vrfy_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +smtp_vrfy_DEPENDENCIES = $(LIBDIR)/libcurl.la sslbackend_SOURCES = sslbackend.c sslbackend_OBJECTS = sslbackend.$(OBJEXT) sslbackend_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@sslbackend_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@sslbackend_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +sslbackend_DEPENDENCIES = $(LIBDIR)/libcurl.la unixsocket_SOURCES = unixsocket.c unixsocket_OBJECTS = unixsocket.$(OBJEXT) unixsocket_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@unixsocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@unixsocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +unixsocket_DEPENDENCIES = $(LIBDIR)/libcurl.la url2file_SOURCES = url2file.c url2file_OBJECTS = url2file.$(OBJEXT) url2file_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@url2file_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@url2file_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +url2file_DEPENDENCIES = $(LIBDIR)/libcurl.la urlapi_SOURCES = urlapi.c urlapi_OBJECTS = urlapi.$(OBJEXT) urlapi_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@urlapi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@urlapi_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +urlapi_DEPENDENCIES = $(LIBDIR)/libcurl.la websocket_SOURCES = websocket.c websocket_OBJECTS = websocket.$(OBJEXT) websocket_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@websocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@websocket_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +websocket_DEPENDENCIES = $(LIBDIR)/libcurl.la websocket_cb_SOURCES = websocket-cb.c websocket_cb_OBJECTS = websocket-cb.$(OBJEXT) websocket_cb_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@websocket_cb_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@websocket_cb_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +websocket_cb_DEPENDENCIES = $(LIBDIR)/libcurl.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -1170,11 +847,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -1220,7 +897,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -1236,8 +912,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -1272,10 +950,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -1286,6 +962,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -1294,6 +971,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -1378,7 +1056,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign nostdinc -EXTRA_DIST = README.md Makefile.example Makefile.inc Makefile.mk \ +EXTRA_DIST = README.md Makefile.example Makefile.mk CMakeLists.txt \ $(COMPLICATED_EXAMPLES) .checksrc @@ -1393,10 +1071,9 @@ EXTRA_DIST = README.md Makefile.example Makefile.inc Makefile.mk \ AM_CPPFLAGS = -I$(top_srcdir)/include -DCURL_DISABLE_DEPRECATION \ -DCURL_NO_OLDIES $(am__append_1) LIBDIR = $(top_builddir)/lib -@USE_EXPLICIT_LIB_DEPS_FALSE@LDADD = $(LIBDIR)/libcurl.la # Dependencies -@USE_EXPLICIT_LIB_DEPS_TRUE@LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@ +LDADD = $(LIBDIR)/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # These examples require external dependencies that may not be commonly # available on POSIX systems, so do not bother attempting to compile them here. diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c index 269e29cf5..3bbc056c0 100644 --- a/docs/examples/anyauthput.c +++ b/docs/examples/anyauthput.c @@ -100,7 +100,7 @@ int main(int argc, char **argv) fp = fopen(file, "rb"); fstat(FILENO(fp), &file_info); - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ diff --git a/docs/examples/debug.c b/docs/examples/debug.c index 68d93039e..ac21b8aed 100644 --- a/docs/examples/debug.c +++ b/docs/examples/debug.c @@ -128,7 +128,7 @@ int main(void) CURLcode res; struct data config; - config.trace_ascii = 1; /* enable ascii tracing */ + config.trace_ascii = 1; /* enable ASCII tracing */ curl = curl_easy_init(); if(curl) { diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c index 0c8a26924..8edcd2015 100644 --- a/docs/examples/ephiperfifo.c +++ b/docs/examples/ephiperfifo.c @@ -33,7 +33,7 @@ * * Written by Jeff Pohlmeyer, converted to use epoll by Josh Bialkowski -Requires a linux system with epoll +Requires a Linux system with epoll When running, the program creates the named pipe "hiper.fifo" diff --git a/docs/examples/ftpgetresp.c b/docs/examples/ftpgetresp.c index 33c26b380..256998d8c 100644 --- a/docs/examples/ftpgetresp.c +++ b/docs/examples/ftpgetresp.c @@ -48,17 +48,17 @@ int main(void) FILE *respfile; /* local filename to store the file as */ - ftpfile = fopen(FTPBODY, "wb"); /* b is binary, needed on win32 */ + ftpfile = fopen(FTPBODY, "wb"); /* b is binary, needed on Windows */ /* local filename to store the FTP server's response lines in */ - respfile = fopen(FTPHEADERS, "wb"); /* b is binary, needed on win32 */ + respfile = fopen(FTPHEADERS, "wb"); /* b is binary, needed on Windows */ curl = curl_easy_init(); if(curl) { /* Get a file listing from sunet */ curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/"); curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile); - /* If you intend to use this on windows with a libcurl DLL, you must use + /* If you intend to use this on Windows with a libcurl DLL, you must use CURLOPT_WRITEFUNCTION as well */ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response); curl_easy_setopt(curl, CURLOPT_HEADERDATA, respfile); diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c index d43f09026..462202e6c 100644 --- a/docs/examples/ftpupload.c +++ b/docs/examples/ftpupload.c @@ -90,7 +90,7 @@ int main(void) /* get a FILE * of the same file */ hd_src = fopen(LOCAL_FILE, "rb"); - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ diff --git a/docs/examples/ftpuploadfrommem.c b/docs/examples/ftpuploadfrommem.c index 699468d1c..253748686 100644 --- a/docs/examples/ftpuploadfrommem.c +++ b/docs/examples/ftpuploadfrommem.c @@ -76,7 +76,7 @@ int main(void) upload.readptr = data; upload.sizeleft = strlen(data); - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ res = curl_global_init(CURL_GLOBAL_DEFAULT); /* Check for errors */ if(res != CURLE_OK) { diff --git a/docs/examples/http-post.c b/docs/examples/http-post.c index 1ee9f69c0..901ee1e3f 100644 --- a/docs/examples/http-post.c +++ b/docs/examples/http-post.c @@ -33,7 +33,7 @@ int main(void) CURL *curl; CURLcode res; - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ diff --git a/docs/examples/http2-upload.c b/docs/examples/http2-upload.c index 4758a2fac..7fa8134d4 100644 --- a/docs/examples/http2-upload.c +++ b/docs/examples/http2-upload.c @@ -32,7 +32,7 @@ #include #include -/* somewhat unix-specific */ +/* somewhat Unix-specific */ #ifndef _MSC_VER #include #include diff --git a/docs/examples/httpput-postfields.c b/docs/examples/httpput-postfields.c index e8a8de7a2..c0436749f 100644 --- a/docs/examples/httpput-postfields.c +++ b/docs/examples/httpput-postfields.c @@ -58,7 +58,7 @@ int main(int argc, char **argv) url = argv[1]; - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ diff --git a/docs/examples/httpput.c b/docs/examples/httpput.c index d26aa9e25..ebd2b7696 100644 --- a/docs/examples/httpput.c +++ b/docs/examples/httpput.c @@ -82,7 +82,7 @@ int main(int argc, char **argv) an example! */ hd_src = fopen(file, "rb"); - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ diff --git a/docs/examples/multi-legacy.c b/docs/examples/multi-legacy.c index 4c1c760ef..32e263abf 100644 --- a/docs/examples/multi-legacy.c +++ b/docs/examples/multi-legacy.c @@ -30,7 +30,7 @@ #include #include -/* somewhat unix-specific */ +/* somewhat Unix-specific */ #ifndef _WIN32 #include #include diff --git a/docs/examples/post-callback.c b/docs/examples/post-callback.c index 311bc3cae..1a213cb2d 100644 --- a/docs/examples/post-callback.c +++ b/docs/examples/post-callback.c @@ -73,7 +73,7 @@ int main(void) wt.readptr = data; wt.sizeleft = strlen(data); - /* In windows, this inits the winsock stuff */ + /* In Windows, this inits the Winsock stuff */ res = curl_global_init(CURL_GLOBAL_DEFAULT); /* Check for errors */ if(res != CURLE_OK) { diff --git a/docs/examples/unixsocket.c b/docs/examples/unixsocket.c index 90c655917..299a121d9 100644 --- a/docs/examples/unixsocket.c +++ b/docs/examples/unixsocket.c @@ -22,7 +22,7 @@ * ***************************************************************************/ /* - * Access HTTP server over unix domain socket + * Access HTTP server over Unix domain socket * */ #include diff --git a/docs/BUFQ.md b/docs/internals/BUFQ.md similarity index 100% rename from docs/BUFQ.md rename to docs/internals/BUFQ.md diff --git a/docs/BUFREF.md b/docs/internals/BUFREF.md similarity index 100% rename from docs/BUFREF.md rename to docs/internals/BUFREF.md diff --git a/docs/CHECKSRC.md b/docs/internals/CHECKSRC.md similarity index 100% rename from docs/CHECKSRC.md rename to docs/internals/CHECKSRC.md diff --git a/docs/CLIENT-READERS.md b/docs/internals/CLIENT-READERS.md similarity index 100% rename from docs/CLIENT-READERS.md rename to docs/internals/CLIENT-READERS.md diff --git a/docs/CLIENT-WRITERS.md b/docs/internals/CLIENT-WRITERS.md similarity index 100% rename from docs/CLIENT-WRITERS.md rename to docs/internals/CLIENT-WRITERS.md diff --git a/docs/CODE_STYLE.md b/docs/internals/CODE_STYLE.md similarity index 99% rename from docs/CODE_STYLE.md rename to docs/internals/CODE_STYLE.md index 7b2b60251..f64c5eb7d 100644 --- a/docs/CODE_STYLE.md +++ b/docs/internals/CODE_STYLE.md @@ -271,7 +271,7 @@ DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " Use **#ifdef HAVE_FEATURE** to do conditional code. We avoid checking for particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE -shall be generated by the configure script for unix-like systems and they are +shall be generated by the configure script for Unix-like systems and they are hard-coded in the `config-[system].h` files for the others. We also encourage use of macros/functions that possibly are empty or defined diff --git a/docs/CONNECTION-FILTERS.md b/docs/internals/CONNECTION-FILTERS.md similarity index 100% rename from docs/CONNECTION-FILTERS.md rename to docs/internals/CONNECTION-FILTERS.md diff --git a/docs/DYNBUF.md b/docs/internals/DYNBUF.md similarity index 100% rename from docs/DYNBUF.md rename to docs/internals/DYNBUF.md diff --git a/docs/internals/HASH.md b/docs/internals/HASH.md new file mode 100644 index 000000000..5a5bdc983 --- /dev/null +++ b/docs/internals/HASH.md @@ -0,0 +1,188 @@ + + +# `hash` + + #include "hash.h" + +This is the internal module for doing hash tables. A hash table uses a hash +function to compute an index. On each index there is a separate linked list of +entries. + +Create a hash table. Add items. Retrieve items. Remove items. Destroy table. + +## `Curl_hash_init` + +~~~c +void Curl_hash_init(struct Curl_hash *h, + size_t slots, + hash_function hfunc, + comp_function comparator, + Curl_hash_dtor dtor); +~~~ + +The call initializes a `struct Curl_hash`. + +- `slots` is the number of entries to create in the hash table. Larger is + better (faster lookups) but also uses more memory. +- `hfunc` is a function pointer to a function that returns a `size_t` value as + a checksum for an entry in this hash table. Ideally, it returns a unique + value for every entry ever added to the hash table, but hash collisions are + handled. +- `comparator` is a function pointer to a function that compares two hash + table entries. It should return non-zero if the compared items are + identical. +- `dtor` is a function pointer to a destructor called when an entry is removed + from the table + +## `Curl_hash_add` + +~~~c +void * +Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p) +~~~ + +This call adds an entry to the hash. `key` points to the hash key and +`key_len` is the length of the hash key. `p` is a custom pointer. + +If there already was a match in the hash, that data is replaced with this new +entry. + +This function also lazily allocates the table if needed, as it is not done in +the `Curl_hash_init` function. + +Returns NULL on error, otherwise it returns a pointer to `p`. + +## `Curl_hash_add2` + +~~~c +void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, + Curl_hash_elem_dtor dtor) +~~~ + +This works like `Curl_hash_add` but has an extra argument: `dtor`, which is a +destructor call for this specific entry. When this entry is removed, this +function is called instead of the function stored for the whole hash table. + +## `Curl_hash_delete` + +~~~c +int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len); +~~~ + +This function removes an entry from the hash table. If successful, it returns +zero. If the entry was not found, it returns 1. + +## `Curl_hash_pick` + +~~~c +void *Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len); +~~~ + +If there is an entry in the hash that matches the given `key` with size of +`key_len`, that its custom pointer is returned. The pointer that was called +`p` when the entry was added. + +It returns NULL if there is no matching entry in the hash. + +## `Curl_hash_destroy` + +~~~c +void Curl_hash_destroy(struct Curl_hash *h); +~~~ + +This function destroys a hash and cleanups up all its related data. Calling it +multiple times is fine. + +## `Curl_hash_clean` + +~~~c +void Curl_hash_clean(struct Curl_hash *h); +~~~ + +This function removes all the entries in the given hash. + +## `Curl_hash_clean_with_criterium` + +~~~c +void +Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, + int (*comp)(void *, void *)) +~~~ + +This function removes all the entries in the given hash that matches the +criterion. The provided `comp` function determines if the criteria is met by +returning non-zero. + +## `Curl_hash_count` + +~~~c +size_t Curl_hash_count(struct Curl_hash *h) +~~~ + +Returns the number of entries stored in the hash. + +## `Curl_hash_start_iterate` + +~~~c +void Curl_hash_start_iterate(struct Curl_hash *hash, + struct Curl_hash_iterator *iter): +~~~ + +This function initializes a `struct Curl_hash_iterator` that `iter` points to. +It can then be used to iterate over all the entries in the hash. + +## `Curl_hash_next_element` + +~~~c +struct Curl_hash_element * +Curl_hash_next_element(struct Curl_hash_iterator *iter); +~~~ + +Given the iterator `iter`, this function returns a pointer to the next hash +entry if there is one, or NULL if there is no more entries. + +Called repeatedly, it iterates over all the entries in the hash table. + +Note: it only guarantees functionality if the hash table remains untouched +during its iteration. + +# `curl_off_t` dedicated hash functions + +## `Curl_hash_offt_init` + +~~~c +void Curl_hash_offt_init(struct Curl_hash *h, + size_t slots, + Curl_hash_dtor dtor); +~~~ + +Initializes a hash table for `curl_off_t` values. Pass in desired number of +`slots` and `dtor` function. + +## `Curl_hash_offt_set` + +~~~c +void *Curl_hash_offt_set(struct Curl_hash *h, curl_off_t id, void *elem); +~~~ + +Associate a custom `elem` pointer with the given `id`. + +## `Curl_hash_offt_remove` + +~~~c +int Curl_hash_offt_remove(struct Curl_hash *h, curl_off_t id); +~~~ + +Remove the `id` from the hash. + +## `Curl_hash_offt_get` + +~~~c +void *Curl_hash_offt_get(struct Curl_hash *h, curl_off_t id); +~~~ + +Get the pointer associated with the specified `id`. diff --git a/docs/HYPER.md b/docs/internals/HYPER.md similarity index 100% rename from docs/HYPER.md rename to docs/internals/HYPER.md diff --git a/docs/internals/LLIST.md b/docs/internals/LLIST.md new file mode 100644 index 000000000..ee9a89bad --- /dev/null +++ b/docs/internals/LLIST.md @@ -0,0 +1,190 @@ + + +# `llist` - linked lists + + #include "llist.h" + +This is the internal module for linked lists. The API is designed to be +flexible but also to avoid dynamic memory allocation. + +None of the involved structs should be accessed using struct fields (outside +of `llist.c`). Use the functions. + +## Setup and shutdown + +`struct Curl_llist` is the struct holding a single linked list. It needs to be +initialized with a call to `Curl_llist_init()` before it can be used + +To clean up a list, call `Curl_llist_destroy()`. Since the linked lists +themselves do not allocate memory, it can also be fine to just *not* clean up +the list. + +## Add a node + +There are two functions for adding a node to a linked list: + +1. Add it last in the list with `Curl_llist_append` +2. Add it after a specific existing node with `Curl_llist_insert_next` + +When a node is added to a list, it stores an associated custom pointer to +anything you like and you provide a pointer to a `struct Curl_llist_node` +struct in which it stores and updates pointers. If you intend to add the same +struct to multiple lists concurrently, you need to have one `struct +Curl_llist_node` for each list. + +Add a node to a list with `Curl_llist_append(list, elem, node)`. Where + +- `list`: points to a `struct Curl_llist` +- `elem`: points to what you want added to the list +- `node`: is a pointer to a `struct Curl_llist_node`. Data storage for this + node. + +Example: to add a `struct foobar` to a linked list. Add a node struct within +it: + + struct foobar { + char *random; + struct Curl_llist_node storage; /* can be anywhere in the struct */ + char *data; + }; + + struct Curl_llist barlist; /* the list for foobar entries */ + struct foobar entries[10]; + + Curl_llist_init(&barlist, NULL); + + /* add the first struct to the list */ + Curl_llist_append(&barlist, &entries[0], &entries[0].storage); + +See also `Curl_llist_insert_next`. + +## Remove a node + +Remove a node again from a list by calling `Curl_llist_remove()`. + +## Iterate + +To iterate over a list: first get the head entry and then iterate over the +nodes as long there is a next. Each node has an *element* associated with it, +the custom pointer you stored there. Usually a struct pointer or similar. + + struct Curl_llist_node *iter; + + /* get the first entry of the 'barlist' */ + iter = Curl_llist_head(&barlist); + + while(iter) { + /* extract the element pointer from the node */ + struct foobar *elem = Curl_node_elem(iter); + + /* advance to the next node in the list */ + iter = Curl_node_next(iter); + } + +# Function overview + +## `Curl_llist_init` + +~~~c +void Curl_llist_init(struct Curl_llist *list, Curl_llist_dtor dtor); +~~~ + +Initializes the `list`. The argument `dtor` is NULL or a function pointer that +gets called when list nodes are removed from this list. + +The function is infallible. + +~~~c +typedef void (*Curl_llist_dtor)(void *user, void *elem); +~~~ + +`dtor` is called with two arguments: `user` and `elem`. The first being the +`user` pointer passed in to `Curl_llist_remove()`or `Curl_llist_destroy()` and +the second is the `elem` pointer associated with removed node. The pointer +that `Curl_node_elem()` would have returned for that node. + +## `Curl_llist_destroy` + +~~~c +void Curl_llist_destroy(struct Curl_llist *list, void *user); +~~~ + +This removes all nodes from the `list`. This leaves the list in a cleared +state. + +The function is infallible. + +## `Curl_llist_append` + +~~~c +void Curl_llist_append(struct Curl_llist *list, + const void *elem, struct Curl_llist_node *node); +~~~ + +Adds `node` last in the `list` with a custom pointer to `elem`. + +The function is infallible. + +## `Curl_llist_insert_next` + +~~~c +void Curl_llist_insert_next(struct Curl_llist *list, + struct Curl_llist_node *node, + const void *elem, + struct Curl_llist_node *node); +~~~ + +Adds `node` to the `list` with a custom pointer to `elem` immediately after +the previous list `node`. + +The function is infallible. + +## `Curl_llist_head` + +~~~c +struct Curl_llist_node *Curl_llist_head(struct Curl_llist *list); +~~~ + +Returns a pointer to the first node of the `list`, or a NULL if empty. + +## `Curl_node_uremove` + +~~~c +void Curl_node_uremove(struct Curl_llist_node *node, void *user); +~~~ + +Removes the `node` the list it was previously added to. Passes the `user` +pointer to the list's destructor function if one was setup. + +The function is infallible. + +## `Curl_node_remove` + +~~~c +void Curl_node_remove(struct Curl_llist_node *node); +~~~ + +Removes the `node` the list it was previously added to. Passes a NULL pointer +to the list's destructor function if one was setup. + +The function is infallible. + +## `Curl_node_elem` + +~~~c +void *Curl_node_elem(struct Curl_llist_node *node); +~~~ + +Given a list node, this function returns the associated element. + +## `Curl_node_next` + +~~~c +struct Curl_llist_node *Curl_node_next(struct Curl_llist_node *node); +~~~ + +Given a list node, this function returns the next node in the list. diff --git a/docs/MQTT.md b/docs/internals/MQTT.md similarity index 100% rename from docs/MQTT.md rename to docs/internals/MQTT.md diff --git a/docs/NEW-PROTOCOL.md b/docs/internals/NEW-PROTOCOL.md similarity index 100% rename from docs/NEW-PROTOCOL.md rename to docs/internals/NEW-PROTOCOL.md diff --git a/docs/internals/README.md b/docs/internals/README.md new file mode 100644 index 000000000..289b360ad --- /dev/null +++ b/docs/internals/README.md @@ -0,0 +1,12 @@ + + +# Internals + +This directory contains documentation covering libcurl internals; APIs and +concepts that are useful for contributors and maintainers. + +Public APIs are documented in the public documentation, not here. diff --git a/docs/internals/SPLAY.md b/docs/internals/SPLAY.md new file mode 100644 index 000000000..29cf3858a --- /dev/null +++ b/docs/internals/SPLAY.md @@ -0,0 +1,111 @@ + + +# `splay` + + #include "splay.h" + +This is an internal module for splay tree management. A splay tree is a binary +search tree with the additional property that recently accessed elements are +quick to access again. A self-balancing tree. + +Nodes are added to the tree, they are accessed and removed from the tree and +it automatically rebalances itself in each operation. + +## libcurl use + +libcurl adds fixed timeout expiry timestamps to the splay tree, and is meant +to scale up to holding a huge amount of pending timeouts with decent +performance. + +The splay tree is used to: + +1. figure out the next timeout expiry value closest in time +2. iterate over timeouts that already have expired + +This splay tree rebalances itself based on the time value. + +Each node in the splay tree points to a `struct Curl_easy`. Each `Curl_easy` +struct is represented only once in the tree. To still allow each easy handle +to have a large number of timeouts per handle, each handle has a sorted linked +list of pending timeouts. Only the handle's timeout that is closest to expire +is the timestamp used for the splay tree node. + +When a specific easy handle's timeout expires, the node gets removed from the +splay tree and from the handle's linked list of timeouts. The next timeout for +that handle is then first in line and becomes the new timeout value as the +node is re-added to the splay. + +## `Curl_splay` + +~~~c +struct Curl_tree *Curl_splay(struct curltime i, struct Curl_tree *t); +~~~ + +Rearranges the tree `t` after the provide time `i`. + +## `Curl_splayinsert` + +~~~c +struct Curl_tree *Curl_splayinsert(struct curltime key, + struct Curl_tree *t, + struct Curl_tree *node); +~~~ + +This function inserts a new `node` in the tree, using the given `key` +timestamp. The `node` struct has a field called `->payload` that can be set to +point to anything. libcurl sets this to the `struct Curl_easy` handle that is +associated with the timeout value set in `key`. + +The splay insert function does not allocate any memory, it assumes the caller +has that arranged. + +It returns a pointer to the new tree root. + +## `Curl_splaygetbest` + +~~~c +struct Curl_tree *Curl_splaygetbest(struct curltime key, + struct Curl_tree *tree, + struct Curl_tree **removed); +~~~ + +If there is a node in the `tree` that has a time value that is less than the +provided `key`, this function removes that node from the tree and provides it +in the `*removed` pointer (or NULL if there was no match). + +It returns a pointer to the new tree root. + +## `Curl_splayremove` + +~~~c +int Curl_splayremove(struct Curl_tree *tree, + struct Curl_tree *node, + struct Curl_tree **newroot); +~~~ + +Removes a given `node` from a splay `tree`, and returns the `newroot` +identifying the new tree root. + +Note that a clean tree without any nodes present implies a NULL pointer. + +## `Curl_splayset` + +~~~c +void Curl_splayset(struct Curl_tree *node, void *payload); +~~~ + +Set a custom pointer to be stored in the splay node. This pointer is not used +by the splay code itself and can be retrieved again with `Curl_splayget`. + +## `Curl_splayget` + +~~~c +void *Curl_splayget(struct Curl_tree *node); +~~~ + +Get the custom pointer from the splay node that was previously set with +`Curl_splayset`. If no pointer was set before, it returns NULL. diff --git a/docs/WEBSOCKET.md b/docs/internals/WEBSOCKET.md similarity index 100% rename from docs/WEBSOCKET.md rename to docs/internals/WEBSOCKET.md diff --git a/docs/libcurl/CMakeLists.txt b/docs/libcurl/CMakeLists.txt index 7eec1ab45..4af47af34 100644 --- a/docs/libcurl/CMakeLists.txt +++ b/docs/libcurl/CMakeLists.txt @@ -21,13 +21,13 @@ # SPDX-License-Identifier: curl # ########################################################################### -# Load man_MANS from shared file +# Get 'man_MANS' variable transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") function(add_manual_pages _listname) # Maximum number of files per command to stay within shell/OS limits - if(UNIX) + if(CMAKE_HOST_UNIX) set(_files_per_batch 10000) else() # e.g. Windows with cmd.exe and other obsolete/unidentified shells set(_files_per_batch 200) @@ -38,10 +38,10 @@ function(add_manual_pages _listname) set(_eol "_EOL_") foreach(_file IN LISTS ${_listname} _eol) math(EXPR _file_count "${_file_count} + 1") - if(NOT _file_count LESS ${_files_per_batch} OR _file STREQUAL "_EOL_") + if(_file_count GREATER_EQUAL _files_per_batch OR _file STREQUAL "_EOL_") add_custom_command(OUTPUT ${_rofffiles} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND "${PERL_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/scripts/cd2nroff -k -d "${CMAKE_CURRENT_BINARY_DIR}" ${_mdfiles} + COMMAND "${PERL_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/cd2nroff" -k -d "${CMAKE_CURRENT_BINARY_DIR}" ${_mdfiles} DEPENDS ${_mdfiles} VERBATIM ) @@ -61,11 +61,11 @@ function(add_manual_pages _listname) endforeach() endfunction() -add_custom_command(OUTPUT libcurl-symbols.md +add_custom_command(OUTPUT "libcurl-symbols.md" COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mksymbolsmanpage.pl" < - "${CMAKE_CURRENT_SOURCE_DIR}/symbols-in-versions" > libcurl-symbols.md + "${CMAKE_CURRENT_SOURCE_DIR}/symbols-in-versions" > "libcurl-symbols.md" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/symbols-in-versions" "${CMAKE_CURRENT_SOURCE_DIR}/mksymbolsmanpage.pl" @@ -76,10 +76,10 @@ add_manual_pages(man_MANS) add_custom_target(curl-man ALL DEPENDS ${man_MANS}) if(NOT CURL_DISABLE_INSTALL) unset(_src) - foreach(_f ${man_MANS}) + foreach(_f IN LISTS man_MANS) list(APPEND _src "${CMAKE_CURRENT_BINARY_DIR}/${_f}") endforeach() - install(FILES ${_src} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) + install(FILES ${_src} DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() add_subdirectory(opts) diff --git a/docs/libcurl/Makefile.in b/docs/libcurl/Makefile.in index 27e39df3a..7067921ac 100644 --- a/docs/libcurl/Makefile.in +++ b/docs/libcurl/Makefile.in @@ -308,11 +308,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -358,7 +358,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -374,8 +373,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -408,10 +409,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -422,6 +421,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -430,6 +430,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/docs/libcurl/curl_easy_getinfo.md b/docs/libcurl/curl_easy_getinfo.md index ce328d6c5..7157cd211 100644 --- a/docs/libcurl/curl_easy_getinfo.md +++ b/docs/libcurl/curl_easy_getinfo.md @@ -180,6 +180,11 @@ See CURLINFO_NUM_CONNECTS(3) The errno from the last failure to connect. See CURLINFO_OS_ERRNO(3) +## CURLINFO_POSTTRANSFER_TIME_T + +The time it took from the start until the last byte is sent by libcurl. +In microseconds. (Added in 8.10.0) See CURLINFO_POSTTRANSFER_TIME_T(3) + ## CURLINFO_PRETRANSFER_TIME The time it took from the start until the file transfer is just about to @@ -375,15 +380,17 @@ An overview of the time values available from curl_easy_getinfo(3) |--|--|--CONNECT |--|--|--|--APPCONNECT |--|--|--|--|--PRETRANSFER - |--|--|--|--|--|--STARTTRANSFER - |--|--|--|--|--|--|--TOTAL - |--|--|--|--|--|--|--REDIRECT + |--|--|--|--|--|--POSTTRANSFER + |--|--|--|--|--|--|--STARTTRANSFER + |--|--|--|--|--|--|--|--TOTAL + |--|--|--|--|--|--|--|--REDIRECT CURLINFO_QUEUE_TIME_T(3), CURLINFO_NAMELOOKUP_TIME_T(3), CURLINFO_CONNECT_TIME_T(3), CURLINFO_APPCONNECT_TIME_T(3), - CURLINFO_PRETRANSFER_TIME_T(3), CURLINFO_STARTTRANSFER_TIME_T(3), - CURLINFO_TOTAL_TIME_T(3), CURLINFO_REDIRECT_TIME_T(3) + CURLINFO_PRETRANSFER_TIME_T(3), CURLINFO_POSTTRANSFER_TIME_T(3), + CURLINFO_STARTTRANSFER_TIME_T(3), CURLINFO_TOTAL_TIME_T(3), + CURLINFO_REDIRECT_TIME_T(3) # %PROTOCOLS% diff --git a/docs/libcurl/curl_easy_header.md b/docs/libcurl/curl_easy_header.md index 7a911116d..0c7125066 100644 --- a/docs/libcurl/curl_easy_header.md +++ b/docs/libcurl/curl_easy_header.md @@ -65,7 +65,7 @@ does not have to bother about multiple headers used wrongly. The memory for the returned struct is associated with the easy handle and subsequent calls to curl_easy_header(3) clobber the struct used in the -previous calls for the same easy handle. Applications need to copy the data if +previous calls for the same easy handle. The application needs to copy the data if it wants to keep it around. The memory used for the struct gets freed with calling curl_easy_cleanup(3) of the easy handle. diff --git a/docs/libcurl/curl_easy_upkeep.md b/docs/libcurl/curl_easy_upkeep.md index c2d798d2d..1b2fef01a 100644 --- a/docs/libcurl/curl_easy_upkeep.md +++ b/docs/libcurl/curl_easy_upkeep.md @@ -39,6 +39,10 @@ This function must be explicitly called in order to perform the upkeep work. The connection upkeep interval is set with CURLOPT_UPKEEP_INTERVAL_MS(3). +If you call this function on an easy handle that uses a shared connection cache +then upkeep is performed on the connections in that cache, even if those +connections were never used by the easy handle. (Added in 8.10.0) + # %PROTOCOLS% # EXAMPLE diff --git a/docs/libcurl/curl_getenv.md b/docs/libcurl/curl_getenv.md index c6f0c268f..4f62161f4 100644 --- a/docs/libcurl/curl_getenv.md +++ b/docs/libcurl/curl_getenv.md @@ -27,7 +27,7 @@ char *curl_getenv(const char *name); curl_getenv() is a portable wrapper for the getenv() function, meant to emulate its behavior and provide an identical interface for all operating -systems libcurl builds on (including win32). +systems libcurl builds on (including Windows). You must curl_free(3) the returned string when you are done with it. @@ -55,6 +55,6 @@ specified name. # NOTE -Under unix operating systems, there is no point in returning an allocated +Under Unix operating systems, there is no point in returning an allocated memory, although other systems does not work properly if this is not done. The -unix implementation thus suffers slightly from the drawbacks of other systems. +Unix implementation thus suffers slightly from the drawbacks of other systems. diff --git a/docs/libcurl/curl_global_init.md b/docs/libcurl/curl_global_init.md index 4ce880f9e..198b6e9f3 100644 --- a/docs/libcurl/curl_global_init.md +++ b/docs/libcurl/curl_global_init.md @@ -89,7 +89,7 @@ unexpected behaviors. Initialize the Win32 socket libraries. The implication here is that if this bit is not set, the initialization of -winsock has to be done by the application or you risk getting undefined +Winsock has to be done by the application or you risk getting undefined behaviors. This option exists for when the initialization is handled outside of libcurl so there is no need for libcurl to do it again. diff --git a/docs/libcurl/curl_global_trace.md b/docs/libcurl/curl_global_trace.md index a76462570..bf722ae6f 100644 --- a/docs/libcurl/curl_global_trace.md +++ b/docs/libcurl/curl_global_trace.md @@ -105,10 +105,39 @@ Tracing of DNS-over-HTTP operations to resolve hostnames. Traces reading of upload data from the application in order to send it to the server. +## `smtp` + +Tracing of SMTP operations when this protocol is enabled in your build. + ## `write` Traces writing of download data, received from the server, to the application. +## `ws` + +Tracing of WebSocket operations when this protocol is enabled in your build. + +# TRACE GROUPS + +Besides the specific component names there are the following group names +defined: + +## `all` + +## `network` + +All components involved in bare network I/O, including the SSL layer. + +All components that your libcurl is built with. + +## `protocol` + +All components involved in transfer protocols, such as 'ftp' and 'http/2'. + +## `proxy` + +All components involved in use of proxies. + # %PROTOCOLS% # EXAMPLE diff --git a/docs/libcurl/curl_multi_poll.md b/docs/libcurl/curl_multi_poll.md index 2c2ccee6e..c19661d0e 100644 --- a/docs/libcurl/curl_multi_poll.md +++ b/docs/libcurl/curl_multi_poll.md @@ -92,6 +92,8 @@ events such as the socket being clear to write without blocking. # EXAMPLE ~~~c +extern void handle_fd(int); + int main(void) { CURL *easy_handle; diff --git a/docs/libcurl/curl_multi_waitfds.md b/docs/libcurl/curl_multi_waitfds.md index a64223027..0a8440eb4 100644 --- a/docs/libcurl/curl_multi_waitfds.md +++ b/docs/libcurl/curl_multi_waitfds.md @@ -57,6 +57,8 @@ subsequent function call. # EXAMPLE ~~~c +#include + int main(void) { CURLMcode mc; @@ -98,7 +100,7 @@ int main(void) /* Do polling on descriptors in ufds */ free(ufds); - } while (!mc); + } while(!mc); } ~~~ diff --git a/docs/libcurl/curl_version_info.md b/docs/libcurl/curl_version_info.md index 2a0220d29..271e935ca 100644 --- a/docs/libcurl/curl_version_info.md +++ b/docs/libcurl/curl_version_info.md @@ -116,13 +116,13 @@ new the libcurl you are using is. You are however guaranteed to get a struct that you have a matching struct for in the header, as you tell libcurl your "age" with the input argument. -*version* is just an ascii string for the libcurl version. +*version* is just an ASCII string for the libcurl version. *version_num* is a 24 bit number created like this: \<8 bits major number\> | \<8 bits minor number\> | \<8 bits patch number\>. Version 7.9.8 is therefore returned as 0x070908. -*host* is an ascii string showing what host information that this libcurl +*host* is an ASCII string showing what host information that this libcurl was built for. As discovered by a configure script or set by the build environment. diff --git a/docs/libcurl/curl_ws_send.md b/docs/libcurl/curl_ws_send.md index 82fce1cff..262250b54 100644 --- a/docs/libcurl/curl_ws_send.md +++ b/docs/libcurl/curl_ws_send.md @@ -53,6 +53,10 @@ If **CURLWS_RAW_MODE** is enabled in CURLOPT_WS_OPTIONS(3), the To send a message consisting of multiple frames, set the *CURLWS_CONT* bit in all frames except the final one. +Warning: while it is possible to invoke this function from a callback, +such a call is blocking in this situation, e.g. only returns after all data +has been sent or an error is encountered. + # FLAGS ## CURLWS_TEXT diff --git a/docs/libcurl/libcurl-env-dbg.md b/docs/libcurl/libcurl-env-dbg.md index 3762b006b..73217ca20 100644 --- a/docs/libcurl/libcurl-env-dbg.md +++ b/docs/libcurl/libcurl-env-dbg.md @@ -64,6 +64,15 @@ Trace logging behavior as an alternative to calling curl_global_trace(3). Example: **CURL_DEBUG=http/2** means trace details about HTTP/2 handling. +In the curl command line tool, built with `--enable-debug`, this environment +variable adds to arguments like `--verbose`, `-vvv`. At least a single `-v` +is needed to make the run emit trace output, but when it does, the contents +of `CURL_DEBUG` are added and can override existing options. + +Example: **CURL_DEBUG=tcp,-http/2 curl -vv url** means trace protocol details, +triggered by `-vv`, add tracing of TCP in addition and remove tracing of +HTTP/2. + ## CURL_DEBUG_SIZE Fake the size returned by CURLINFO_HEADER_SIZE and CURLINFO_REQUEST_SIZE. @@ -98,7 +107,7 @@ the current. ## CURL_TIME -Fake unix timestamp to use for AltSvc, HSTS and CURLINFO variables that are +Fake Unix timestamp to use for AltSvc, HSTS and CURLINFO variables that are time related. This variable can also be used to fake the data returned by some CURLINFO @@ -111,10 +120,6 @@ LDAP tracing is enabled if this variable exists and its value is 1 or greater. OpenLDAP tracing is separate. Refer to CURL_OPENLDAP_TRACE. -## CURL_NTLM_WB_FILE - -Debug-version of the *ntlm-wb* executable. - ## CURL_OPENLDAP_TRACE OpenLDAP tracing is enabled if this variable exists and its value is 1 or diff --git a/docs/libcurl/libcurl-env.md b/docs/libcurl/libcurl-env.md index bf5624f3c..70b41d12d 100644 --- a/docs/libcurl/libcurl-env.md +++ b/docs/libcurl/libcurl-env.md @@ -52,7 +52,7 @@ this variable's selection is used. Setting a name that is not a built-in alternative makes libcurl stay with the default. SSL backend names (case-insensitive): BearSSL, GnuTLS, mbedTLS, -nss, OpenSSL, rustls, Schannel, Secure-Transport, wolfSSL +nss, OpenSSL, Rustls, Schannel, Secure-Transport, wolfSSL ## `HOME` diff --git a/docs/libcurl/libcurl-security.md b/docs/libcurl/libcurl-security.md index d13dceffe..466506bf9 100644 --- a/docs/libcurl/libcurl-security.md +++ b/docs/libcurl/libcurl-security.md @@ -462,6 +462,8 @@ libcurl itself uses *fork()* and *execl()* if told to use the command in a child process with file descriptors duplicated. Make sure that only the trusted and reliable helper program is invoked! +This feature was removed from curl in 8.8.0. + # Secrets in memory When applications pass usernames, passwords or other sensitive data to diff --git a/docs/libcurl/libcurl-symbols.md b/docs/libcurl/libcurl-symbols.md index 5e6a5a1f6..afcf46717 100644 --- a/docs/libcurl/libcurl-symbols.md +++ b/docs/libcurl/libcurl-symbols.md @@ -525,7 +525,7 @@ Introduced in 7.56.0. See curl_version_info(3). Introduced in 7.10.6. See curl_version_info(3). ## CURL_VERSION_NTLM_WB -Introduced in 7.22.0. See curl_version_info(3). +Introduced in 7.22.0. Deprecated since 8.8.0. ## CURL_VERSION_PSL Introduced in 7.47.0. See curl_version_info(3). @@ -624,7 +624,7 @@ Introduced in 7.10.6. See CURLOPT_HTTPAUTH(3). Introduced in 7.10.6. See CURLOPT_HTTPAUTH(3). ## CURLAUTH_NTLM_WB -Introduced in 7.22.0. See CURLOPT_HTTPAUTH(3). +Introduced in 7.22.0. Deprecated since 8.8.0. ## CURLAUTH_ONLY Introduced in 7.21.3. See CURLOPT_HTTPAUTH(3). @@ -1379,6 +1379,9 @@ Introduced in 7.4.1. ## CURLINFO_PRETRANSFER_TIME_T Introduced in 7.61.0. +## CURLINFO_POSTTRANSFER_TIME_T +Introduced in 8.10.0. + ## CURLINFO_PRIMARY_IP Introduced in 7.19.0. diff --git a/docs/libcurl/libcurl-tutorial.md b/docs/libcurl/libcurl-tutorial.md index 4e16e38aa..7c59e2f88 100644 --- a/docs/libcurl/libcurl-tutorial.md +++ b/docs/libcurl/libcurl-tutorial.md @@ -112,7 +112,7 @@ specified are: ## CURL_GLOBAL_WIN32 which only does anything on Windows machines. When used on a Windows machine, -it makes libcurl initialize the win32 socket stuff. Without having that +it makes libcurl initialize the Win32 socket stuff. Without having that initialized properly, your program cannot use sockets properly. You should only do this once for each application, so if your program already does this or of another library in use does it, you should not tell libcurl to do this @@ -235,7 +235,7 @@ to make your program run fine virtually everywhere. (CURLOPT_WRITEDATA(3) was formerly known as *CURLOPT_FILE*. Both names still work and do the same thing). -If you are using libcurl as a win32 DLL, you MUST use the +If you are using libcurl as a Windows DLL, you MUST use the CURLOPT_WRITEFUNCTION(3) if you set CURLOPT_WRITEDATA(3) - or experience crashes. @@ -1255,7 +1255,7 @@ curl_mime_subparts(3). Once it has been bound to its parent multi-part, a nth-level multi-part belongs to it and should not be freed explicitly. -Email messages data is not supposed to be non-ascii and line length is +Email messages data is not supposed to be non-ASCII and line length is limited: fortunately, some transfer encodings are defined by the standards to support the transmission of such incompatible data. Function curl_mime_encoder(3) tells a part that its source data must be encoded diff --git a/docs/libcurl/libcurl.md b/docs/libcurl/libcurl.md index 2f3a45197..5625aa07d 100644 --- a/docs/libcurl/libcurl.md +++ b/docs/libcurl/libcurl.md @@ -95,7 +95,7 @@ See libcurl-ws(3) # LINKING WITH LIBCURL -On unix-like machines, there is a tool named curl-config that gets installed +On Unix-like machines, there is a tool named curl-config that gets installed with the rest of the curl stuff when 'make install' is performed. curl-config is added to make it easier for applications to link with libcurl diff --git a/docs/libcurl/opts/CMakeLists.txt b/docs/libcurl/opts/CMakeLists.txt index 2037793fc..99683c406 100644 --- a/docs/libcurl/opts/CMakeLists.txt +++ b/docs/libcurl/opts/CMakeLists.txt @@ -21,7 +21,7 @@ # SPDX-License-Identifier: curl # ########################################################################### -# Load man_MANS from shared file +# Get 'man_MANS' variable transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") @@ -30,8 +30,8 @@ add_custom_target(curl-opts-man DEPENDS ${man_MANS}) add_dependencies(curl-man curl-opts-man) if(NOT CURL_DISABLE_INSTALL) unset(_src) - foreach(_f ${man_MANS}) + foreach(_f IN LISTS man_MANS) list(APPEND _src "${CMAKE_CURRENT_BINARY_DIR}/${_f}") endforeach() - install(FILES ${_src} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) + install(FILES ${_src} DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() diff --git a/docs/libcurl/opts/CURLINFO_POSTTRANSFER_TIME_T.md b/docs/libcurl/opts/CURLINFO_POSTTRANSFER_TIME_T.md new file mode 100644 index 000000000..9acdbd7fb --- /dev/null +++ b/docs/libcurl/opts/CURLINFO_POSTTRANSFER_TIME_T.md @@ -0,0 +1,70 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Title: CURLINFO_POSTTRANSFER_TIME_T +Section: 3 +Source: libcurl +See-also: + - CURLINFO_PRETRANSFER_TIME_T (3) + - CURLOPT_TIMEOUT (3) + - curl_easy_getinfo (3) + - curl_easy_setopt (3) +Protocol: + - All +Added-in: 8.10.0 +--- + +# NAME + +CURLINFO_POSTTRANSFER_TIME_T - get the time until the last byte is sent + +# SYNOPSIS + +~~~c +#include + +CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_POSTTRANSFER_TIME_T, + curl_off_t *timep); +~~~ + +# DESCRIPTION + +Pass a pointer to a curl_off_t to receive the time, in microseconds, +it took from the start until the last byte is sent by libcurl. + +When a redirect is followed, the time from each request is added together. + +See also the TIMES overview in the curl_easy_getinfo(3) man page. + +# %PROTOCOLS% + +# EXAMPLE + +~~~c +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(CURLE_OK == res) { + curl_off_t posttransfer; + res = curl_easy_getinfo(curl, CURLINFO_POSTTRANSFER_TIME_T, + &posttransfer); + if(CURLE_OK == res) { + printf("Request sent after: %" CURL_FORMAT_CURL_OFF_T ".%06ld us", + posttransfer / 1000000, (long)(posttransfer % 1000000)); + } + } + /* always cleanup */ + curl_easy_cleanup(curl); + } +} +~~~ + +# %AVAILABILITY% + +# RETURN VALUE + +Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not. diff --git a/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.md b/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.md index a53ee43d3..60c1185ea 100644 --- a/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.md +++ b/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.md @@ -50,6 +50,9 @@ libcurl by calling curl_multi_socket_action(3). # CALLBACK ARGUMENTS *easy* identifies the specific transfer for which this update is related. +Since this callback manages a whole multi handle, an application should not +make assumptions about which particular handle that is passed here. It might +even be an internal easy handle that the application did not add itself. *s* is the specific socket this function invocation concerns. If the **what** argument is not CURL_POLL_REMOVE then it holds information about diff --git a/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.md b/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.md index bd80d842f..d0ef75f79 100644 --- a/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.md +++ b/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.md @@ -42,19 +42,19 @@ built-in supported encodings. Alternatively, you can specify exactly the encoding or list of encodings you want in the response. The following encodings are supported: *identity*, -meaning non-compressed, *deflate* which requests the server to compress -its response using the zlib algorithm, *gzip* which requests the gzip -algorithm, (since curl 7.57.0) *br* which is brotli and (since curl -7.72.0) *zstd* which is zstd. Provide them in the string as a -comma-separated list of accepted encodings, like: **"br, gzip, deflate"**. - -Set CURLOPT_ACCEPT_ENCODING(3) to NULL to explicitly disable it, which -makes libcurl not send an Accept-Encoding: header and not decompress received +meaning non-compressed, *deflate* which requests the server to compress its +response using the zlib algorithm, *gzip* which requests the gzip algorithm, +(since curl 7.57.0) *br* which is brotli and (since curl 7.72.0) *zstd* which +is zstd. Provide them in the string as a comma-separated list of accepted +encodings, like: **"br, gzip, deflate"**. + +Set CURLOPT_ACCEPT_ENCODING(3) to NULL to explicitly disable it, which makes +libcurl not send an Accept-Encoding: header and not decompress received contents automatically. You can also opt to just include the Accept-Encoding: header in your request -with CURLOPT_HTTPHEADER(3) but then there is no automatic decompressing -when receiving data. +with CURLOPT_HTTPHEADER(3) but then there is no automatic decompressing when +receiving data. This is a request, not an order; the server may or may not do it. This option must be set (to any non-NULL value) or else any unsolicited encoding done by @@ -72,6 +72,9 @@ sending the length of the non-compressed content is a common server mistake). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. + # HISTORY This option was called CURLOPT_ENCODING before 7.21.6 diff --git a/docs/libcurl/opts/CURLOPT_ALTSVC.md b/docs/libcurl/opts/CURLOPT_ALTSVC.md index 43c52a47e..ef5e83450 100644 --- a/docs/libcurl/opts/CURLOPT_ALTSVC.md +++ b/docs/libcurl/opts/CURLOPT_ALTSVC.md @@ -35,6 +35,12 @@ CURLOPT_ALTSVC_CTRL(3). Specify a blank filename ("") to make libcurl not load from a file at all. +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL. The alt-svc cache is not read nor written to file. diff --git a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.md b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.md index 2e61e897c..0b17b1ed7 100644 --- a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.md +++ b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.md @@ -68,6 +68,12 @@ generated string. Setting CURLOPT_HTTPAUTH(3) with the CURLAUTH_AWS_SIGV4 bit set is the same as setting this option with a **"aws:amz"** parameter. +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_CAINFO.md b/docs/libcurl/opts/CURLOPT_CAINFO.md index 2eeedd508..686d17e05 100644 --- a/docs/libcurl/opts/CURLOPT_CAINFO.md +++ b/docs/libcurl/opts/CURLOPT_CAINFO.md @@ -54,6 +54,9 @@ store of root certificates (the default for Schannel). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + The default value for this can be figured out with CURLINFO_CAINFO(3). # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.md b/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.md index efb071737..39b1f9873 100644 --- a/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.md +++ b/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.md @@ -82,7 +82,7 @@ int main(void) # HISTORY This option is supported by the BearSSL (since 7.79.0), mbedTLS (since -7.81.0), rustls (since 7.82.0), wolfSSL (since 8.2.0), OpenSSL, Secure +7.81.0), Rustls (since 7.82.0), wolfSSL (since 8.2.0), OpenSSL, Secure Transport and Schannel backends. # %AVAILABILITY% diff --git a/docs/libcurl/opts/CURLOPT_CAPATH.md b/docs/libcurl/opts/CURLOPT_CAPATH.md index 3094bf8b5..3dcba2d0a 100644 --- a/docs/libcurl/opts/CURLOPT_CAPATH.md +++ b/docs/libcurl/opts/CURLOPT_CAPATH.md @@ -45,6 +45,9 @@ to some limitation in OpenSSL. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + The default value for this can be figured out with CURLINFO_CAPATH(3). # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.md b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.md index 0106be8bd..83ccfcd27 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.md +++ b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.md @@ -53,7 +53,7 @@ to 2, the operation can never last longer than 2 seconds. Including the connection phase. This option may cause libcurl to use the SIGALRM signal to timeout system -calls on builds not using asynch DNS. In unix-like systems, this might cause +calls on builds not using asynch DNS. In Unix-like systems, this might cause signals to be used unless CURLOPT_NOSIGNAL(3) is set. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.md b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.md index 0baad3e61..cbfc6d3ad 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.md +++ b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.md @@ -54,7 +54,7 @@ With CURLOPT_CONNECTTIMEOUT_MS(3) set to 4000 and CURLOPT_TIMEOUT_MS(3) set to the connection phase. This option may cause libcurl to use the SIGALRM signal to timeout system -calls on builds not using asynch DNS. In unix-like systems, this might cause +calls on builds not using asynch DNS. In Unix-like systems, this might cause signals to be used unless CURLOPT_NOSIGNAL(3) is set. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_CONNECT_TO.md b/docs/libcurl/opts/CURLOPT_CONNECT_TO.md index 933e3b6a3..b4cc638ae 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECT_TO.md +++ b/docs/libcurl/opts/CURLOPT_CONNECT_TO.md @@ -76,6 +76,9 @@ When this option is passed to curl_easy_setopt(3), libcurl does not copy the list so you **must** keep it around until you no longer use this *handle* for a transfer before you call curl_slist_free_all(3) on the list. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_COOKIE.md b/docs/libcurl/opts/CURLOPT_COOKIE.md index 12d947020..c16a59376 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIE.md +++ b/docs/libcurl/opts/CURLOPT_COOKIE.md @@ -35,7 +35,8 @@ NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain. To set multiple cookies, set them all using a single option concatenated like -this: "name1=content1; name2=content2;" etc. +this: "name1=content1; name2=content2;" etc. libcurl does not syntax check the +data but assumes the application gives it what it needs to send. This option sets the cookie header explicitly in the outgoing request(s). If multiple requests are done due to authentication, followed redirections or @@ -43,28 +44,24 @@ similar, they all get this cookie passed on. The cookies set by this option are separate from the internal cookie storage held by the cookie engine and they are not be modified by it. If you enable -the cookie engine and either you have imported a cookie of the same name -(e.g. 'foo') or the server has set one, it has no effect on the cookies you -set here. A request to the server sends both the 'foo' held by the cookie -engine and the 'foo' held by this option. To set a cookie that is instead held -by the cookie engine and can be modified by the server use -CURLOPT_COOKIELIST(3). +the cookie engine and either you have imported a cookie of the same name (e.g. +'foo') or the server has set one, it has no effect on the cookies you set +here. A request to the server sends both the 'foo' held by the cookie engine +and the 'foo' held by this option. To set a cookie that is instead held by the +cookie engine and can be modified by the server use CURLOPT_COOKIELIST(3). -Using this option multiple times makes the last set string override the -previous ones. - -This option does not enable the cookie engine. Use CURLOPT_COOKIEFILE(3) -or CURLOPT_COOKIEJAR(3) to enable parsing and sending cookies -automatically. +Since this custom cookie is appended to the Cookie: header in addition to any +cookies set by the cookie engine, there is a risk that the header ends up too +long and thereby getting the entire request rejected by the server. The application does not have to keep the string around after setting this option. -If libcurl is built with PSL (*Public Suffix List*) support, it detects and -discards cookies that are specified for such suffix domains that should not be -allowed to have cookies. If libcurl is *not* built with PSL support, it has no -ability to stop super cookies. PSL support is identified by the -**CURL_VERSION_PSL** feature bit returned by curl_version_info(3). +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + +This option does not enable the cookie engine. Use CURLOPT_COOKIEFILE(3) or +CURLOPT_COOKIEJAR(3) to enable parsing and sending cookies automatically. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_COOKIEFILE.md b/docs/libcurl/opts/CURLOPT_COOKIEFILE.md index 09c75d014..7f607c735 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIEFILE.md +++ b/docs/libcurl/opts/CURLOPT_COOKIEFILE.md @@ -48,14 +48,12 @@ domain cannot match the target URL's. To address this, set a domain in Set-Cookie line (doing that includes subdomains) or preferably: use the Netscape format. -If you use this option multiple times, you add more files to read cookies -from. - The application does not have to keep the string around after setting this option. -Setting this option to NULL (since 7.77.0) explicitly disables the cookie -engine and clears the list of files to read cookies from. +If you use this option multiple times, you add more files to read cookies +from. Setting this option to NULL disables the cookie engine and clears the +list of files to read cookies from. # SECURITY diff --git a/docs/libcurl/opts/CURLOPT_COOKIEJAR.md b/docs/libcurl/opts/CURLOPT_COOKIEJAR.md index 8fa3680aa..3f76eb7e6 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIEJAR.md +++ b/docs/libcurl/opts/CURLOPT_COOKIEJAR.md @@ -27,22 +27,21 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_COOKIEJAR, char *filename); # DESCRIPTION -Pass a *filename* as a char *, null-terminated. This makes libcurl write -all internally known cookies to the specified file when -curl_easy_cleanup(3) is called. If no cookies are kept in memory at that -time, no file is created. Specify "-" as filename to instead have the cookies -written to stdout. Using this option also enables cookies for this session, so -if you for example follow a redirect it makes matching cookies get sent -accordingly. +Pass a *filename* as a char *, null-terminated. This makes libcurl write all +internally known cookies to the specified file when curl_easy_cleanup(3) is +called. If no cookies are kept in memory at that time, no file is created. +Specify "-" as filename to instead have the cookies written to stdout. Using +this option also enables cookies for this session, so if you for example +follow a redirect it makes matching cookies get sent accordingly. Note that libcurl does not read any cookies from the cookie jar specified with this option. To read cookies from a file, use CURLOPT_COOKIEFILE(3). If the cookie jar file cannot be created or written to (when the -curl_easy_cleanup(3) is called), libcurl does not and cannot report an -error for this. Using CURLOPT_VERBOSE(3) or -CURLOPT_DEBUGFUNCTION(3) displays a warning, but that is the only -visible feedback you get about this possibly lethal situation. +curl_easy_cleanup(3) is called), libcurl does not and cannot report an error +for this. Using CURLOPT_VERBOSE(3) or CURLOPT_DEBUGFUNCTION(3) displays a +warning, but that is the only visible feedback you get about this possibly +lethal situation. Cookies are imported in the Set-Cookie format without a domain name are not exported by this option. @@ -50,6 +49,9 @@ exported by this option. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.md b/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.md index 6650008a6..a014458c9 100644 --- a/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.md +++ b/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.md @@ -33,14 +33,19 @@ HTTP POST operation. It behaves as the CURLOPT_POSTFIELDS(3) option, but the original data is instead copied by the library, allowing the application to overwrite the original data after setting this option. -Because data are copied, care must be taken when using this option in -conjunction with CURLOPT_POSTFIELDSIZE(3) or -CURLOPT_POSTFIELDSIZE_LARGE(3): If the size has not been set prior to -CURLOPT_COPYPOSTFIELDS(3), the data is assumed to be a null-terminated -string; else the stored size informs the library about the byte count to -copy. In any case, the size must not be changed after -CURLOPT_COPYPOSTFIELDS(3), unless another CURLOPT_POSTFIELDS(3) or -CURLOPT_COPYPOSTFIELDS(3) option is issued. +Because data is copied, care must be taken when using this option in +conjunction with CURLOPT_POSTFIELDSIZE(3) or CURLOPT_POSTFIELDSIZE_LARGE(3). +If the size has not been set prior to CURLOPT_COPYPOSTFIELDS(3), the data is +assumed to be a null-terminated string; else the stored size informs the +library about the byte count to copy. In any case, the size must not be +changed after CURLOPT_COPYPOSTFIELDS(3), unless another CURLOPT_POSTFIELDS(3) +or CURLOPT_COPYPOSTFIELDS(3) option is set. + +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_CRLFILE.md b/docs/libcurl/opts/CURLOPT_CRLFILE.md index 1a6b21109..f0bea2821 100644 --- a/docs/libcurl/opts/CURLOPT_CRLFILE.md +++ b/docs/libcurl/opts/CURLOPT_CRLFILE.md @@ -14,6 +14,7 @@ TLS-backend: - GnuTLS - mbedTLS - OpenSSL + - rustls Added-in: 7.19.0 --- @@ -48,13 +49,16 @@ This option makes sense only when used in combination with the CURLOPT_SSL_VERIFYPEER(3) option. A specific error code (*CURLE_SSL_CRL_BADFILE*) is defined with the option. It -is returned when the SSL exchange fails because the CRL file cannot be -loaded. A failure in certificate verification due to a revocation information -found in the CRL does not trigger this specific error. +is returned when the SSL exchange fails because the CRL file cannot be loaded. +A failure in certificate verification due to a revocation information found in +the CRL does not trigger this specific error. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.md b/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.md index 39da7ca00..886f27ce2 100644 --- a/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.md +++ b/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.md @@ -34,14 +34,18 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_CUSTOMREQUEST, char *method); Pass a pointer to a null-terminated string as parameter. -When changing the request *method* by setting CURLOPT_CUSTOMREQUEST(3), you -do not actually change how libcurl behaves or acts: you only change the actual +When changing the request *method* by setting CURLOPT_CUSTOMREQUEST(3), you do +not actually change how libcurl behaves or acts: you only change the actual string sent in the request. libcurl passes on the verbatim string in its request without any filter or other safe guards. That includes white space and control characters. -Restore to the internal default by setting this to NULL. +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Restore to the internal default by setting this to NULL. This option can be used to specify the request: diff --git a/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md b/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md index 3787ff951..9f85c6af0 100644 --- a/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md +++ b/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md @@ -37,12 +37,12 @@ Use one of these protocol (scheme) names: dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp -An unknown or unsupported protocol causes error -*CURLE_UNSUPPORTED_PROTOCOL* when libcurl parses a URL without a -scheme. Parsing happens when curl_easy_perform(3) or -curl_multi_perform(3) is called. The protocol set supported by libcurl -vary depending on how it was built. Use curl_version_info(3) if you need -a list of protocol names supported by the build of libcurl that you are using. +An unknown or unsupported protocol causes error *CURLE_UNSUPPORTED_PROTOCOL* +when libcurl parses a URL without a scheme. Parsing happens when +curl_easy_perform(3) or curl_multi_perform(3) is called. The protocol set +supported by libcurl vary depending on how it was built. Use +curl_version_info(3) if you need a list of protocol names supported by the +build of libcurl that you are using. This option does not change the default proxy protocol (http). @@ -52,6 +52,9 @@ CURLOPT_URL(3) for details. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL (make a guess based on the host) diff --git a/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.md b/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.md index 0d7f435ed..5e58e0fd0 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.md +++ b/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.md @@ -36,6 +36,9 @@ specific interface). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.md b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.md index cf3aae80e..046ddbcdb 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.md +++ b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.md @@ -35,6 +35,9 @@ specific IP address). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.md b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.md index 4750367de..e820ab11e 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.md +++ b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.md @@ -35,6 +35,9 @@ address). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_DNS_SERVERS.md b/docs/libcurl/opts/CURLOPT_DNS_SERVERS.md index f345e3265..48a335230 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_SERVERS.md +++ b/docs/libcurl/opts/CURLOPT_DNS_SERVERS.md @@ -30,15 +30,18 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_DNS_SERVERS, char *servers); Pass a char pointer that is the list of DNS servers to be used instead of the system default. The format of the dns servers option is: -host[:port][,host[:port]]... + host[:port][,host[:port]]... For example: -192.168.1.100,192.168.1.101,3.4.5.6 + 192.168.1.100,192.168.1.101,3.4.5.6 The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_DOH_URL.md b/docs/libcurl/opts/CURLOPT_DOH_URL.md index bd4372fb0..cf7a04e19 100644 --- a/docs/libcurl/opts/CURLOPT_DOH_URL.md +++ b/docs/libcurl/opts/CURLOPT_DOH_URL.md @@ -41,7 +41,11 @@ To find the DoH server itself, which might be specified using a name, libcurl uses the default name lookup function. You can bootstrap that by providing the address for the DoH server with CURLOPT_RESOLVE(3). -Disable DoH use again by setting this option to NULL. +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. # INHERIT OPTIONS diff --git a/docs/libcurl/opts/CURLOPT_ECH.md b/docs/libcurl/opts/CURLOPT_ECH.md index a637b98be..b8251fe18 100644 --- a/docs/libcurl/opts/CURLOPT_ECH.md +++ b/docs/libcurl/opts/CURLOPT_ECH.md @@ -70,6 +70,14 @@ If the string starts with `pn:` then the remainder of the string should be a DNS/hostname that is used to over-ride the public_name field of the ECHConfigList that is used for ECH. +## + +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL or "false" to disable its use again. + # DEFAULT NULL, meaning ECH is disabled. @@ -79,12 +87,17 @@ NULL, meaning ECH is disabled. # EXAMPLE ~~~c -CURL *curl = curl_easy_init(); - -const char *config ="ecl:AED+DQA87wAgACB/RuzUCsW3uBbSFI7mzD63TUXpI8sGDTnFTbFCDpa+CAAEAAEAAQANY292ZXIuZGVmby5pZQAA"; -if(curl) { - curl_easy_setopt(curl, CURLOPT_ECH, config); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + + const char *config = \ + "ecl:AED+DQA87wAgACB/RuzUCsW3uBbSFI7mzD63TUXpI8sGDTnFTbFCDpa+" \ + "CAAEAAEAAQANY292ZXIuZGVmby5pZQAA"; + if(curl) { + curl_easy_setopt(curl, CURLOPT_ECH, config); + curl_easy_perform(curl); + } } ~~~ # %AVAILABILITY% diff --git a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md index 4b8366840..edac39b95 100644 --- a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md +++ b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md @@ -37,16 +37,19 @@ be at least **CURL_ERROR_SIZE** bytes big. You must keep the associated buffer available until libcurl no longer needs it. Failing to do so might cause odd behavior or even crashes. libcurl might -need it until you call curl_easy_cleanup(3) or you set the same option -again to use a different pointer. +need it until you call curl_easy_cleanup(3) or you set the same option again +to use a different pointer. Do not rely on the contents of the buffer unless an error code was returned. Since 7.60.0 libcurl initializes the contents of the error buffer to an empty string before performing the transfer. For earlier versions if an error code was returned but there was no error detail then the buffer was untouched. -Consider CURLOPT_VERBOSE(3) and CURLOPT_DEBUGFUNCTION(3) to better -debug and trace why errors happen. +Consider CURLOPT_VERBOSE(3) and CURLOPT_DEBUGFUNCTION(3) to better debug and +trace why errors happen. + +Using this option multiple times makes the last set pointer override the +previous ones. Set it to NULL to disable its use again. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.md b/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.md index bfbb3b545..4bd02eea0 100644 --- a/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.md +++ b/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.md @@ -10,6 +10,7 @@ See-also: - CURLOPT_POSTREDIR (3) - CURLOPT_PROTOCOLS_STR (3) - CURLOPT_REDIR_PROTOCOLS_STR (3) + - CURLOPT_UNRESTRICTED_AUTH (3) Protocol: - HTTP Added-in: 7.1 @@ -34,9 +35,9 @@ redirects that an HTTP server sends in a 30x response. The Location: header can specify a relative or an absolute URL to follow. libcurl issues another request for the new URL and follows subsequent new -Location: redirects all the way until no more such headers are returned or the -maximum limit is reached. CURLOPT_MAXREDIRS(3) is used to limit the -number of redirects libcurl follows. +`Location:` redirects all the way until no more such headers are returned or +the maximum limit is reached. CURLOPT_MAXREDIRS(3) is used to limit the number +of redirects libcurl follows. libcurl restricts what protocols it automatically follow redirects to. The accepted target protocols are set with CURLOPT_REDIR_PROTOCOLS_STR(3). By @@ -44,23 +45,32 @@ default libcurl allows HTTP, HTTPS, FTP and FTPS on redirects. When following a redirect, the specific 30x response code also dictates which request method libcurl uses in the subsequent request: For 301, 302 and 303 -responses libcurl switches method from POST to GET unless -CURLOPT_POSTREDIR(3) instructs libcurl otherwise. All other redirect -response codes make libcurl use the same method again. +responses libcurl switches method from POST to GET unless CURLOPT_POSTREDIR(3) +instructs libcurl otherwise. All other redirect response codes make libcurl +use the same method again. For users who think the existing location following is too naive, too simple or just lacks features, it is easy to instead implement your own redirect -follow logic with the use of curl_easy_getinfo(3)'s -CURLINFO_REDIRECT_URL(3) option instead of using -CURLOPT_FOLLOWLOCATION(3). +follow logic with the use of curl_easy_getinfo(3)'s CURLINFO_REDIRECT_URL(3) +option instead of using CURLOPT_FOLLOWLOCATION(3). + +By default, libcurl only sends `Authentication:` or explicitly set `Cookie:` +headers to the initial host given in the original URL, to avoid leaking +username + password to other sites. CURLOPT_UNRESTRICTED_AUTH(3) is provided +to change that behavior. + +Due to the way HTTP works, almost any header can be made to contain data a +client may not want to pass on to other servers than the initially intended +host and for all other headers than the two mentioned above, there is no +protection from this happening when libcurl is told to follow redirects. # NOTE Since libcurl changes method or not based on the specific HTTP response code, -setting CURLOPT_CUSTOMREQUEST(3) while following redirects may change -what libcurl would otherwise do and if not that carefully may even make it -misbehave since CURLOPT_CUSTOMREQUEST(3) overrides the method libcurl -would otherwise select internally. +setting CURLOPT_CUSTOMREQUEST(3) while following redirects may change what +libcurl would otherwise do and if not that carefully may even make it +misbehave since CURLOPT_CUSTOMREQUEST(3) overrides the method libcurl would +otherwise select internally. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_FTPPORT.md b/docs/libcurl/opts/CURLOPT_FTPPORT.md index d2f3eae7d..7f82b1794 100644 --- a/docs/libcurl/opts/CURLOPT_FTPPORT.md +++ b/docs/libcurl/opts/CURLOPT_FTPPORT.md @@ -46,12 +46,10 @@ specifier can be in brackets. Examples with specified ports: -~~~c - eth0:0 - 192.168.1.2:32000-33000 - curl.se:32123 - [::1]:1234-4567 -~~~ + eth0:0 + 192.168.1.2:32000-33000 + curl.se:32123 + [::1]:1234-4567 We strongly advise against specifying the address with a name, as it causes libcurl to do a blocking name resolve call to retrieve the IP address. That @@ -61,12 +59,13 @@ CURLOPT_DOH_URL(3) is set. Using anything else than "-" for this option should typically only be done if you have special knowledge and confirmation that it works. -You disable PORT again and go back to using the passive version by setting -this option to NULL. - The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. You disable PORT again and go back to using the passive version +by setting this option to NULL. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.md b/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.md index da6835cc7..aae893d30 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.md +++ b/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.md @@ -33,6 +33,9 @@ this data is sent off using the ACCT command. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.md b/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.md index 64e0085fd..fb0f0ec52 100644 --- a/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.md +++ b/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.md @@ -31,8 +31,14 @@ When this parameter is set to a valid IPv4 or IPv6 numerical address, the library sends this address as client address in the HAProxy PROXY protocol v1 header at beginning of the connection. -This option is an alternative to CURLOPT_HAPROXYPROTOCOL(3) as that one -cannot use a specified address. +This option is an alternative to CURLOPT_HAPROXYPROTOCOL(3) as that one cannot +use a specified address. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + +The application does not have to keep the string around after setting this +option. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_HEADERDATA.md b/docs/libcurl/opts/CURLOPT_HEADERDATA.md index 865cbb74d..0542e158f 100644 --- a/docs/libcurl/opts/CURLOPT_HEADERDATA.md +++ b/docs/libcurl/opts/CURLOPT_HEADERDATA.md @@ -36,7 +36,7 @@ If CURLOPT_WRITEFUNCTION(3) or CURLOPT_HEADERFUNCTION(3) is used, If neither of those options are set, *pointer* must be a valid FILE * and it is used by a plain fwrite() to write headers to. -If you are using libcurl as a win32 DLL, you **MUST** use a +If you are using libcurl as a Windows DLL, you **MUST** use a CURLOPT_WRITEFUNCTION(3) or CURLOPT_HEADERFUNCTION(3) if you set this option or you might experience crashes. diff --git a/docs/libcurl/opts/CURLOPT_HSTS.md b/docs/libcurl/opts/CURLOPT_HSTS.md index b838c9e95..3d5f957a8 100644 --- a/docs/libcurl/opts/CURLOPT_HSTS.md +++ b/docs/libcurl/opts/CURLOPT_HSTS.md @@ -33,8 +33,9 @@ name with this option also enables HSTS for this handle (the equivalent of setting *CURLHSTS_ENABLE* with CURLOPT_HSTS_CTRL(3)). If the given file does not exist or contains no HSTS entries at startup, the -HSTS cache simply starts empty. Setting the filename to NULL or "" only -enables HSTS without reading from or writing to any file. +HSTS cache simply starts empty. Setting the filename to NULL allows HSTS +without reading from or writing to any file. NULL also makes libcurl clear the +list of files to read HSTS data from, if any such were previously set. If this option is set multiple times, libcurl loads cache entries from each given file but only stores the last used name for later writing. @@ -44,7 +45,7 @@ given file but only stores the last used name for later writing. The HSTS cache is saved to and loaded from a text file with one entry per physical line. Each line in the file has the following format: -[host] [stamp] + [host] [stamp] [host] is the domain name for the entry and the name is dot-prefixed if it is an entry valid for all subdomains to the name as well or only for the exact diff --git a/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.md b/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.md index 59cdfeef6..933ed135b 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.md +++ b/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.md @@ -41,6 +41,12 @@ curl_slist_free_all(3) to clean up an entire list. The alias itself is not parsed for any version strings. The protocol is assumed to match HTTP 1.0 when an alias match. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.md b/docs/libcurl/opts/CURLOPT_HTTPHEADER.md index 35a67a12a..d3c06457b 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.md +++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.md @@ -39,19 +39,18 @@ requests! When used within an IMAP or SMTP request to upload a MIME mail, the given header list establishes the document-level MIME headers to prepend to the -uploaded document described by CURLOPT_MIMEPOST(3). This does not affect -raw mail uploads. - -The linked list should be a fully valid list of **struct curl_slist** -structs properly filled in. Use curl_slist_append(3) to create the list -and curl_slist_free_all(3) to clean up an entire list. If you add a -header that is otherwise generated and used by libcurl internally, your added -header is used instead. If you add a header with no content as in 'Accept:' -(no data on the right side of the colon), the internally used header is -disabled/removed. With this option you can add new headers, replace internal -headers and remove internal headers. To add a header with no content (nothing -to the right side of the colon), use the form 'name;' (note the ending -semicolon). +uploaded document described by CURLOPT_MIMEPOST(3). This does not affect raw +mail uploads. + +The linked list should be a fully valid list of **struct curl_slist** structs +properly filled in. Use curl_slist_append(3) to create the list and +curl_slist_free_all(3) to clean up an entire list. If you add a header that is +otherwise generated and used by libcurl internally, your added header is used +instead. If you add a header with no content as in 'Accept:' (no data on the +right side of the colon), the internally used header is disabled/removed. With +this option you can add new headers, replace internal headers and remove +internal headers. To add a header with no content (nothing to the right side +of the colon), use the form 'name;' (note the ending semicolon). The headers included in the linked list **must not** be CRLF-terminated, because libcurl adds CRLF after each header item itself. Failure to comply @@ -65,16 +64,16 @@ following the request-line are headers. Adding this method line in this list of headers only causes your request to send an invalid header. Use CURLOPT_CUSTOMREQUEST(3) to change the method. -When this option is passed to curl_easy_setopt(3), libcurl does not copy -the entire list so you **must** keep it around until you no longer use this -*handle* for a transfer before you call curl_slist_free_all(3) on -the list. +When this option is passed to curl_easy_setopt(3), libcurl does not copy the +entire list so you **must** keep it around until you no longer use this +*handle* for a transfer before you call curl_slist_free_all(3) on the list. -Pass a NULL to this option to reset back to no custom headers. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. The most commonly replaced HTTP headers have "shortcuts" in the options -CURLOPT_COOKIE(3), CURLOPT_USERAGENT(3) and -CURLOPT_REFERER(3). We recommend using those. +CURLOPT_COOKIE(3), CURLOPT_USERAGENT(3) and CURLOPT_REFERER(3). We recommend +using those. There is an alternative option that sets or replaces headers only for requests that are sent with CONNECT to a proxy: CURLOPT_PROXYHEADER(3). Use diff --git a/docs/libcurl/opts/CURLOPT_HTTP_VERSION.md b/docs/libcurl/opts/CURLOPT_HTTP_VERSION.md index 0a9215d8a..32c2c2ce6 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP_VERSION.md +++ b/docs/libcurl/opts/CURLOPT_HTTP_VERSION.md @@ -73,6 +73,10 @@ prior knowledge that the server supports HTTP/2 straight away. HTTPS requests still do HTTP/2 the standard way with negotiated protocol version in the TLS handshake. (Added in 7.49.0) +Since 8.10.0 if this option is set for an HTTPS request then the application +layer protocol version (ALPN) offered to the server is only HTTP/2. Prior to +that both HTTP/1.1 and HTTP/2 were offered. + ## CURL_HTTP_VERSION_3 (Added in 7.66.0) This option makes libcurl attempt to use HTTP/3 to the host diff --git a/docs/libcurl/opts/CURLOPT_INTERFACE.md b/docs/libcurl/opts/CURLOPT_INTERFACE.md index f1ca875fc..ce5636ab6 100644 --- a/docs/libcurl/opts/CURLOPT_INTERFACE.md +++ b/docs/libcurl/opts/CURLOPT_INTERFACE.md @@ -44,13 +44,16 @@ libcurl does not support using network interface names for this option on Windows. We strongly advise against specifying the interface with a hostname, as it -causes libcurl to do a blocking name resolve call to retrieve the IP -address. That name resolve operation does **not** use DNS-over-HTTPS even if +causes libcurl to do a blocking name resolve call to retrieve the IP address. +That name resolve operation does **not** use DNS-over-HTTPS even if CURLOPT_DOH_URL(3) is set. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL, use whatever the TCP stack finds suitable diff --git a/docs/libcurl/opts/CURLOPT_ISSUERCERT.md b/docs/libcurl/opts/CURLOPT_ISSUERCERT.md index fa726b0cf..e11f41a86 100644 --- a/docs/libcurl/opts/CURLOPT_ISSUERCERT.md +++ b/docs/libcurl/opts/CURLOPT_ISSUERCERT.md @@ -46,6 +46,9 @@ which is returned if the setup of the SSL/TLS session has failed due to a mismatch with the issuer of peer certificate (CURLOPT_SSL_VERIFYPEER(3) has to be set too for the check to fail). (Added in 7.19.0) +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + The application does not have to keep the string around after setting this option. diff --git a/docs/libcurl/opts/CURLOPT_KEYPASSWD.md b/docs/libcurl/opts/CURLOPT_KEYPASSWD.md index 79f31555a..08a08f7a0 100644 --- a/docs/libcurl/opts/CURLOPT_KEYPASSWD.md +++ b/docs/libcurl/opts/CURLOPT_KEYPASSWD.md @@ -39,6 +39,9 @@ load a certificate but you need one to load your private key. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_KRBLEVEL.md b/docs/libcurl/opts/CURLOPT_KRBLEVEL.md index 0c35b163f..5a674d3c4 100644 --- a/docs/libcurl/opts/CURLOPT_KRBLEVEL.md +++ b/docs/libcurl/opts/CURLOPT_KRBLEVEL.md @@ -35,6 +35,9 @@ string to NULL to disable kerberos support for FTP. The application does not have to keep the string around after setting this option. +The application does not have to keep the string around after setting this +option. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.md b/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.md index 44f392250..969a2c418 100644 --- a/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.md +++ b/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.md @@ -48,6 +48,9 @@ disables the plain LOGIN (e.g. to prevent password snooping). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_MAIL_AUTH.md b/docs/libcurl/opts/CURLOPT_MAIL_AUTH.md index 44effd4ee..fd5c5f409 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_AUTH.md +++ b/docs/libcurl/opts/CURLOPT_MAIL_AUTH.md @@ -45,6 +45,9 @@ string is used then a pair of brackets are sent by libcurl as required by RFC The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_MAIL_FROM.md b/docs/libcurl/opts/CURLOPT_MAIL_FROM.md index b0b66355c..16d045be2 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_FROM.md +++ b/docs/libcurl/opts/CURLOPT_MAIL_FROM.md @@ -38,6 +38,9 @@ server which might cause the email to be rejected. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT blank diff --git a/docs/libcurl/opts/CURLOPT_MAIL_RCPT.md b/docs/libcurl/opts/CURLOPT_MAIL_RCPT.md index 9910860f3..3a6d17d0d 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_RCPT.md +++ b/docs/libcurl/opts/CURLOPT_MAIL_RCPT.md @@ -32,6 +32,9 @@ SMTP mail request. The linked list should be a fully valid list of **struct curl_slist** structs properly filled in. Use curl_slist_append(3) to create the list and curl_slist_free_all(3) to clean up an entire list. +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. + When performing a mail transfer, each recipient should be specified within a pair of angled brackets (\<\>), however, should you not use an angled bracket as the first character libcurl assumes you provided a single email address and @@ -45,6 +48,9 @@ When performing a mailing list expand (**EXPN** command), each recipient should be specified using the mailing list name, such as `Friends` or `London-Office`. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_NETRC_FILE.md b/docs/libcurl/opts/CURLOPT_NETRC_FILE.md index a27d470ae..4486b9c2d 100644 --- a/docs/libcurl/opts/CURLOPT_NETRC_FILE.md +++ b/docs/libcurl/opts/CURLOPT_NETRC_FILE.md @@ -35,6 +35,9 @@ for a .netrc file in the current user's home directory. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_NOPROXY.md b/docs/libcurl/opts/CURLOPT_NOPROXY.md index 1412a9a58..b27288733 100644 --- a/docs/libcurl/opts/CURLOPT_NOPROXY.md +++ b/docs/libcurl/opts/CURLOPT_NOPROXY.md @@ -41,7 +41,7 @@ proxy for all hostnames, even if there is an environment variable set for it. Enter IPv6 numerical addresses in the list of hostnames without enclosing brackets: - "example.com,::1,localhost" + "example.com,::1,localhost" Since 7.86.0, IP addresses specified to this option can be provided using CIDR notation: an appended slash and number specifies the number of "network bits" @@ -51,6 +51,9 @@ would match all addresses starting with "192.168". The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # Environment variables If there is an environment variable called **no_proxy** (or **NO_PROXY**), diff --git a/docs/libcurl/opts/CURLOPT_NOSIGNAL.md b/docs/libcurl/opts/CURLOPT_NOSIGNAL.md index 3aaac34c9..4c9c5774a 100644 --- a/docs/libcurl/opts/CURLOPT_NOSIGNAL.md +++ b/docs/libcurl/opts/CURLOPT_NOSIGNAL.md @@ -27,7 +27,7 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOSIGNAL, long onoff); If *onoff* is 1, libcurl uses no functions that install signal handlers or any functions that cause signals to be sent to the process. This option is -here to allow multi-threaded unix applications to still set/use all timeout +here to allow multi-threaded Unix applications to still set/use all timeout options etc, without risking getting signals. If this option is set and libcurl has been built with the standard name diff --git a/docs/libcurl/opts/CURLOPT_PASSWORD.md b/docs/libcurl/opts/CURLOPT_PASSWORD.md index 94d90d0dc..68297111e 100644 --- a/docs/libcurl/opts/CURLOPT_PASSWORD.md +++ b/docs/libcurl/opts/CURLOPT_PASSWORD.md @@ -37,6 +37,9 @@ CURLOPT_USERNAME(3) option. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT blank diff --git a/docs/libcurl/opts/CURLOPT_POSTFIELDS.md b/docs/libcurl/opts/CURLOPT_POSTFIELDS.md index edd932c4e..8f6738f7c 100644 --- a/docs/libcurl/opts/CURLOPT_POSTFIELDS.md +++ b/docs/libcurl/opts/CURLOPT_POSTFIELDS.md @@ -41,10 +41,9 @@ preserved by the calling application until the associated transfer finishes. This behavior can be changed (so libcurl does copy the data) by instead using the CURLOPT_COPYPOSTFIELDS(3) option. -This POST is a normal **application/x-www-form-urlencoded** kind (and -libcurl sets that Content-Type by default when this option is used), which is -commonly used by HTML forms. Change Content-Type with -CURLOPT_HTTPHEADER(3). +This POST is a normal **application/x-www-form-urlencoded** kind (and libcurl +sets that Content-Type by default when this option is used), which is commonly +used by HTML forms. Change Content-Type with CURLOPT_HTTPHEADER(3). You can use curl_easy_escape(3) to URL encode your data, if necessary. It returns a pointer to an encoded string that can be passed as @@ -58,9 +57,9 @@ CURLOPT_POSTFIELDS(3) to an empty string, or set CURLOPT_POST(3) to 1 and CURLOPT_POSTFIELDSIZE(3) to 0. libcurl assumes this option points to a null-terminated string unless you also -set CURLOPT_POSTFIELDSIZE(3) to specify the length of the provided data, -which then is strictly required if you want to send off null bytes included in -the data. +set CURLOPT_POSTFIELDSIZE(3) to specify the length of the provided data, which +then is strictly required if you want to send off null bytes included in the +data. Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header, and libcurl adds that header automatically if the POST is either known to be @@ -70,6 +69,9 @@ header with CURLOPT_HTTPHEADER(3) as usual. To make **multipart/formdata** posts, check out the CURLOPT_MIMEPOST(3) option combined with curl_mime_init(3). +Using this option multiple times makes the last set pointer override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_POSTQUOTE.md b/docs/libcurl/opts/CURLOPT_POSTQUOTE.md index 58c4d8710..7efca6044 100644 --- a/docs/libcurl/opts/CURLOPT_POSTQUOTE.md +++ b/docs/libcurl/opts/CURLOPT_POSTQUOTE.md @@ -33,7 +33,11 @@ after your FTP transfer request. The commands are only issued if no error occur. The linked list should be a fully valid list of struct curl_slist structs properly filled in as described for CURLOPT_QUOTE(3). -Disable this operation again by setting a NULL to this option. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. # DEFAULT @@ -62,6 +66,7 @@ int main(void) curl_easy_cleanup(curl); } + curl_slist_free_all(cmdlist); } ~~~ diff --git a/docs/libcurl/opts/CURLOPT_PREQUOTE.md b/docs/libcurl/opts/CURLOPT_PREQUOTE.md index 5291edf06..12383ec4d 100644 --- a/docs/libcurl/opts/CURLOPT_PREQUOTE.md +++ b/docs/libcurl/opts/CURLOPT_PREQUOTE.md @@ -30,8 +30,13 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PREQUOTE, Pass a pointer to a linked list of FTP commands to pass to the server after the transfer type is set. The linked list should be a fully valid list of struct curl_slist structs properly filled in as described for -CURLOPT_QUOTE(3). Disable this operation again by setting a NULL to this -option. +CURLOPT_QUOTE(3). + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. These commands are not performed when a directory listing is performed, only for file transfers. @@ -65,6 +70,7 @@ int main(void) curl_easy_cleanup(curl); } + curl_slist_free_all(cmdlist); } ~~~ diff --git a/docs/libcurl/opts/CURLOPT_PRE_PROXY.md b/docs/libcurl/opts/CURLOPT_PRE_PROXY.md index f6e5dbff0..666f90cd4 100644 --- a/docs/libcurl/opts/CURLOPT_PRE_PROXY.md +++ b/docs/libcurl/opts/CURLOPT_PRE_PROXY.md @@ -54,6 +54,9 @@ single port number used widely for proxies. Specify it. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.md b/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.md index d9a24382b..eb0981e04 100644 --- a/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.md +++ b/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.md @@ -60,11 +60,13 @@ if you only download data, the upload size remains 0). Many times the callback is called one or more times first, before it knows the data sizes so a program must be made to handle that. +Return zero from the callback if everything is fine. + If your callback function returns CURL_PROGRESSFUNC_CONTINUE it causes libcurl to continue executing the default progress function. -Returning any other non-zero value from this callback makes libcurl abort the -transfer and return *CURLE_ABORTED_BY_CALLBACK*. +Return 1 from this callback to make libcurl abort the transfer and return +*CURLE_ABORTED_BY_CALLBACK*. If you transfer data with the multi interface, this function is not called during periods of idleness unless you call the appropriate libcurl function diff --git a/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md b/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md index 1015b993c..854520851 100644 --- a/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md +++ b/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md @@ -49,9 +49,12 @@ You can set "ALL" as a short-cut to enable all protocols. Note that by setting all, you may enable protocols that were not supported the day you write this but are introduced in a future libcurl version. -curl_version_info(3) can be used to get a list of all supported -protocols in the current libcurl. CURLINFO_SCHEME(3) is the recommended -way to figure out the protocol used in a previous transfer. +curl_version_info(3) can be used to get a list of all supported protocols in +the current libcurl. CURLINFO_SCHEME(3) is the recommended way to figure out +the protocol used in a previous transfer. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to the internal default. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_PROXY.md b/docs/libcurl/opts/CURLOPT_PROXY.md index abc42d7f1..c414f4f51 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY.md +++ b/docs/libcurl/opts/CURLOPT_PROXY.md @@ -41,6 +41,12 @@ defaults to using port 1080 for proxies. The proxy string may be prefixed with [scheme]:// to specify which kind of proxy is used. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + +The application does not have to keep the string around after setting this +option. + ## http:// HTTP Proxy. Default when no scheme or proxy type is specified. @@ -48,7 +54,7 @@ HTTP Proxy. Default when no scheme or proxy type is specified. ## https:// HTTPS Proxy. (Added in 7.52.0 for OpenSSL and GnuTLS Since 7.87.0, it -also works for BearSSL, mbedTLS, rustls, Schannel, Secure Transport and +also works for BearSSL, mbedTLS, Rustls, Schannel, Secure Transport and wolfSSL.) This uses HTTP/1 by default. Setting CURLOPT_PROXYTYPE(3) to diff --git a/docs/libcurl/opts/CURLOPT_PROXYHEADER.md b/docs/libcurl/opts/CURLOPT_PROXYHEADER.md index 5bcd01767..e74210abc 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYHEADER.md +++ b/docs/libcurl/opts/CURLOPT_PROXYHEADER.md @@ -39,7 +39,11 @@ NOT a header and cannot be replaced using this option. Only the lines following the request-line are headers. Adding this method line in this list of headers causes your request to send an invalid header. -Pass a NULL to this to reset back to no custom headers. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.md b/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.md index 1b371b22c..5086a4b38 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.md +++ b/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.md @@ -28,15 +28,18 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXYPASSWORD, char *pwd); # DESCRIPTION -Pass a char pointer as parameter, which should be pointing to the null-terminated -password to use for authentication with the proxy. +Pass a char pointer as parameter, which should be pointing to the +null-terminated password to use for authentication with the proxy. -The CURLOPT_PROXYPASSWORD(3) option should be used in conjunction with -the CURLOPT_PROXYUSERNAME(3) option. +The CURLOPT_PROXYPASSWORD(3) option should be used in conjunction with the +CURLOPT_PROXYUSERNAME(3) option. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT blank diff --git a/docs/libcurl/opts/CURLOPT_PROXYTYPE.md b/docs/libcurl/opts/CURLOPT_PROXYTYPE.md index dafd99603..15aa2f845 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYTYPE.md +++ b/docs/libcurl/opts/CURLOPT_PROXYTYPE.md @@ -35,7 +35,7 @@ HTTP Proxy. Default. ## CURLPROXY_HTTPS HTTPS Proxy using HTTP/1. (Added in 7.52.0 for OpenSSL and GnuTLS. Since -7.87.0, it also works for BearSSL, mbedTLS, rustls, Schannel, Secure Transport +7.87.0, it also works for BearSSL, mbedTLS, Rustls, Schannel, Secure Transport and wolfSSL.) ## CURLPROXY_HTTPS2 diff --git a/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.md b/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.md index 38b1288eb..acfd86f7d 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.md +++ b/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.md @@ -39,6 +39,9 @@ Use CURLOPT_PROXYAUTH(3) to specify the authentication method. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.md b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.md index ed0b5e6b3..6365d5f22 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.md @@ -56,6 +56,10 @@ method of verifying the peer's certificate chain. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again and switches back to +internal default. + The default value for this can be figured out with CURLINFO_CAINFO(3). # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.md b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.md index fe680df09..d0fce53ca 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.md @@ -42,6 +42,10 @@ CURLOPT_PROXY_SSL_VERIFYPEER(3) is enabled (which it is by default). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again and switch back to +internal default. + The default value for this can be figured out with CURLINFO_CAPATH(3). # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.md b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.md index f0cb86db1..9dfeeefeb 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.md @@ -55,6 +55,9 @@ the CRL does not trigger this specific error. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.md b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.md index 954848b86..0b7e45dee 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.md @@ -40,18 +40,20 @@ additional check is useful in multi-level PKI where one needs to enforce that the peer certificate is from a specific branch of the tree. This option makes sense only when used in combination with the -CURLOPT_PROXY_SSL_VERIFYPEER(3) option. Otherwise, the result of the -check is not considered as failure. +CURLOPT_PROXY_SSL_VERIFYPEER(3) option. Otherwise, the result of the check is +not considered as failure. A specific error code (CURLE_SSL_ISSUER_ERROR) is defined with the option, which is returned if the setup of the SSL/TLS session has failed due to a -mismatch with the issuer of peer certificate -(CURLOPT_PROXY_SSL_VERIFYPEER(3) has to be set too for the check to -fail). +mismatch with the issuer of peer certificate (CURLOPT_PROXY_SSL_VERIFYPEER(3) +has to be set too for the check to fail). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.md b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.md index 1d7e2b050..6b417cb4a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.md @@ -43,6 +43,9 @@ key. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.md b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.md index c2113a930..6bb75fc6a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.md @@ -50,6 +50,9 @@ On mismatch, *CURLE_SSL_PINNEDPUBKEYNOTMATCH* is returned. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.md b/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.md index b224557e1..7083e252a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.md @@ -35,6 +35,9 @@ service. The default service name is **"HTTP"** for HTTP based proxies and The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT See above diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.md b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.md index 1e8555ae1..c26f00ca0 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.md @@ -52,6 +52,9 @@ private key with CURLOPT_PROXY_SSLKEY(3). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.md b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.md index 5002b3a11..fad7a6d70 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.md @@ -39,12 +39,15 @@ the format of your client certificate used when connecting to an HTTPS proxy. Supported formats are "PEM" and "DER", except with Secure Transport or Schannel. OpenSSL (versions 0.9.3 and later), Secure Transport (on iOS 5 or -later, or OS X 10.7 or later) and Schannel support "P12" for PKCS#12-encoded +later, or macOS 10.7 or later) and Schannel support "P12" for PKCS#12-encoded files. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT "PEM" diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.md b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.md index c355c947c..6352d0e86 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.md @@ -39,13 +39,16 @@ the filename of your private key used for connecting to the HTTPS proxy. The default format is "PEM" and can be changed with CURLOPT_PROXY_SSLKEYTYPE(3). -(Windows, iOS and Mac OS X) This option is ignored by Secure Transport and +(Windows, iOS and macOS) This option is ignored by Secure Transport and Schannel SSL backends because they expect the private key to be already present in the key chain or PKCS#12 file containing the certificate. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.md b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.md index b59ee2623..672318d2b 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.md @@ -39,6 +39,9 @@ the format of your private key. Supported formats are "PEM", "DER" and "ENG". The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # %PROTOCOLS% # EXAMPLE diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md index 0c64abbc9..607760473 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md @@ -18,8 +18,8 @@ TLS-backend: - Schannel - Secure Transport - wolfSSL - - GnuTLS - mbedTLS + - rustls Added-in: 7.52.0 --- @@ -39,25 +39,20 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_SSL_CIPHER_LIST, # DESCRIPTION Pass a char pointer, pointing to a null-terminated string holding the list of -ciphers to use for the connection to the HTTPS proxy. The list must be -syntactically correct, it consists of one or more cipher strings separated by -colons. Commas or spaces are also acceptable separators but colons are -normally used, &!, &- and &+ can be used as operators. - -For OpenSSL and GnuTLS valid examples of cipher lists include **RC4-SHA**, -**SHA1+DES**, **TLSv1** and **DEFAULT**. The default list is normally -set when you compile OpenSSL. - -For wolfSSL, valid examples of cipher lists include **ECDHE-RSA-RC4-SHA**, -**AES256-SHA:AES256-SHA256**, etc. - -For mbedTLS and BearSSL, valid examples of cipher lists include -**ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256**, or when using -IANA names -**TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256**, -etc. With mbedTLS and BearSSL you do not add/remove ciphers. If one uses this -option then all known ciphers are disabled and only those passed in are -enabled. +cipher suites to use for the TLS 1.2 (1.1, 1.0) connection to the HTTPS proxy. +The list must be syntactically correct, it consists of one or more cipher suite +strings separated by colons. + +For setting TLS 1.3 ciphers see CURLOPT_PROXY_TLS13_CIPHERS(3). + +A valid example of a cipher list is: +~~~ +"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:" +"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305" +~~~ + +For Schannel, you can use this option to set algorithms but not specific +cipher suites. Refer to the ciphers lists document for algorithms. Find more details about cipher lists on this URL: @@ -66,6 +61,9 @@ Find more details about cipher lists on this URL: The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL, use internal built-in list. @@ -82,16 +80,26 @@ int main(void) CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, "TLSv1"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, + "ECDHE-ECDSA-CHACHA20-POLY1305:" + "ECDHE-RSA-CHACHA20-POLY1305"); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } } ~~~ +# HISTORY + +OpenSSL support added in 7.52.0. +wolfSSL, Schannel, Secure Transport, and BearSSL support added in 7.87.0 +mbedTLS support added in 8.8.0. +Rustls support added in 8.10.0. + +Since curl 8.10.0 returns CURLE_NOT_BUILT_IN when not supported. + # %AVAILABILITY% # RETURN VALUE -Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or -CURLE_OUT_OF_MEMORY if there was insufficient heap space. +Returns CURLE_OK if supported, CURLE_NOT_BUILT_IN otherwise. diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.md b/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.md index 42a871d09..2294ec69c 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.md @@ -15,6 +15,9 @@ Protocol: TLS-backend: - OpenSSL - Schannel + - wolfSSL + - mbedTLS + - rustls Added-in: 7.61.0 --- @@ -38,17 +41,23 @@ cipher suites to use for the TLS 1.3 connection to a proxy. The list must be syntactically correct, it consists of one or more cipher suite strings separated by colons. +For setting TLS 1.2 (1.1, 1.0) ciphers see CURLOPT_PROXY_SSL_CIPHER_LIST(3). + +A valid example of a cipher list is: +~~~ +"TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256" +~~~ + Find more details about cipher lists on this URL: https://curl.se/docs/ssl-ciphers.html -This option is currently used only when curl is built to use OpenSSL 1.1.1 or -later. If you are using a different SSL backend you can try setting TLS 1.3 -cipher suites by using the CURLOPT_PROXY_SSL_CIPHER_LIST(3) option. - The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL, use internal built-in list @@ -72,6 +81,18 @@ int main(void) } ~~~ +# HISTORY + +OpenSSL support added in 7.61.0, available when built with OpenSSL \>= 1.1.1. +Schannel support added in 7.87.0. +LibreSSL support added in 8.3.0, available when built with LibreSSL \>= 3.4.1. +wolfSSL support added in 8.10.0. +mbedTLS support added in 8.10.0, available when built with mbedTLS \>= 3.6.0. +Rustls support added in 8.10.0. + +Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites where set +by using the CURLOPT_PROXY_SSL_CIPHER_LIST(3) option. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.md b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.md index edff372af..b92b2e27d 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.md @@ -40,6 +40,9 @@ CURLOPT_PROXY_TLSAUTH_USERNAME(3) option also be set. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.md b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.md index f67edd9f5..436a57092 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.md @@ -36,6 +36,12 @@ Pass a pointer to a null-terminated string as parameter. The string should be the method of the TLS authentication used for the HTTPS connection. Supported method is "SRP". +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to internal default. + +The application does not have to keep the string around after setting this +option. + ## SRP TLS-SRP authentication. Secure Remote Password authentication for TLS is diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.md b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.md index db66735ad..6a25f74d7 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.md @@ -40,6 +40,9 @@ CURLOPT_PROXY_TLSAUTH_PASSWORD(3) option also be set. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_QUOTE.md b/docs/libcurl/opts/CURLOPT_QUOTE.md index 58742b7b3..410347142 100644 --- a/docs/libcurl/opts/CURLOPT_QUOTE.md +++ b/docs/libcurl/opts/CURLOPT_QUOTE.md @@ -37,7 +37,9 @@ of 'struct curl_slist' structs properly filled in with text strings. Use curl_slist_append(3) to append strings (commands) to the list, and clear the entire list afterwards with curl_slist_free_all(3). -Disable this operation again by setting a NULL to this option. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. libcurl does not copy the list, +it needs to be kept around until after the transfer has completed. When speaking to an FTP server, prefix the command with an asterisk (*) to make libcurl continue even if the command fails as by default libcurl stops at @@ -151,6 +153,8 @@ int main(void) curl_easy_cleanup(curl); } + + curl_slist_free_all(cmdlist); } ~~~ diff --git a/docs/libcurl/opts/CURLOPT_RANGE.md b/docs/libcurl/opts/CURLOPT_RANGE.md index 417e77022..6d728b164 100644 --- a/docs/libcurl/opts/CURLOPT_RANGE.md +++ b/docs/libcurl/opts/CURLOPT_RANGE.md @@ -50,7 +50,8 @@ RTSP, byte ranges are **not** permitted. Instead, ranges should be given in For HTTP PUT uploads this option should not be used, since it may conflict with other options. -Pass a NULL to this option to disable the use of ranges. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. The application does not have to keep the string around after setting this option. diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md index ea3a78cab..2f14b04d0 100644 --- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md +++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md @@ -33,8 +33,8 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_REDIR_PROTOCOLS_STR, Pass a pointer to a string that holds a comma-separated list of case insensitive protocol names (URL schemes). That list limits what protocols libcurl may use in a transfer that it follows to in a redirect when -CURLOPT_FOLLOWLOCATION(3) is enabled. This option allows applications to -limit specific transfers to only be allowed to use a subset of protocols in +CURLOPT_FOLLOWLOCATION(3) is enabled. This option allows applications to limit +specific transfers to only be allowed to use a subset of protocols in redirections. Protocols denied by CURLOPT_PROTOCOLS_STR(3) are not overridden by this @@ -56,6 +56,12 @@ but are introduced in a future libcurl version. If trying to set a non-existing protocol or if no matching protocol at all is set, it returns error. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to internal default. + +The application does not have to keep the string around after setting this +option. + # DEFAULT HTTP, HTTPS, FTP and FTPS (Added in 7.65.2). diff --git a/docs/libcurl/opts/CURLOPT_REFERER.md b/docs/libcurl/opts/CURLOPT_REFERER.md index e4054e4ab..e666411cf 100644 --- a/docs/libcurl/opts/CURLOPT_REFERER.md +++ b/docs/libcurl/opts/CURLOPT_REFERER.md @@ -35,6 +35,9 @@ set any custom header with CURLOPT_HTTPHEADER(3). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.md b/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.md index c96f0c352..fa4ff1d17 100644 --- a/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.md +++ b/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.md @@ -34,6 +34,12 @@ instead of the path as extracted from the URL. libcurl passes on the verbatim string in its request without any filter or other safe guards. That includes white space and control characters. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + +The application does not have to keep the string around after setting this +option. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_RESOLVE.md b/docs/libcurl/opts/CURLOPT_RESOLVE.md index f290a1c02..a6db5b428 100644 --- a/docs/libcurl/opts/CURLOPT_RESOLVE.md +++ b/docs/libcurl/opts/CURLOPT_RESOLVE.md @@ -34,11 +34,12 @@ list of **struct curl_slist** structs properly filled in. Use curl_slist_append(3) to create the list and curl_slist_free_all(3) to clean up an entire list. +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. + Each resolve rule to add should be written using the format -~~~c - [+]HOST:PORT:ADDRESS[,ADDRESS] -~~~ + [+]HOST:PORT:ADDRESS[,ADDRESS] HOST is the name libcurl wants to resolve, PORT is the port number of the service where libcurl wants to connect to the HOST and ADDRESS is one or more @@ -67,13 +68,14 @@ setting of CURLOPT_IPRESOLVE(3) to a different IP version. To remove names from the DNS cache again, to stop providing these fake resolves, include a string in the linked list that uses the format -~~~ - -HOST:PORT -~~~ + -HOST:PORT The entry to remove must be prefixed with a dash, and the hostname and port number must exactly match what was added previously. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.md b/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.md index 7ff0f7725..36dc1eace 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.md +++ b/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.md @@ -36,6 +36,9 @@ server sets it in a response. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.md b/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.md index 5e06afc43..074b39486 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.md +++ b/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.md @@ -40,6 +40,9 @@ to. (e.g. the CURLOPT_URL(3) for the above examples might be set to The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT "*" diff --git a/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.md b/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.md index 751141206..f4058fc39 100644 --- a/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.md +++ b/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.md @@ -31,14 +31,20 @@ Pass a char pointer as parameter, which should be pointing to the null-terminated authorization identity (*authzid*) for the transfer. Only applicable to the PLAIN SASL authentication mechanism where it is optional. -When not specified only the authentication identity (*authcid*) as -specified by the username is sent to the server, along with the password. The -server derives a *authzid* from the *authcid* when not provided, which -it then uses internally. - -When the *authzid* is specified, the use of which is server dependent, it -can be used to access another user's inbox, that the user has been granted -access to, or a shared mailbox for example. +When not specified only the authentication identity (*authcid*) as specified +by the username is sent to the server, along with the password. The server +derives a *authzid* from the *authcid* when not provided, which it then uses +internally. + +When the *authzid* is specified, the use of which is server dependent, it can +be used to access another user's inbox, that the user has been granted access +to, or a shared mailbox for example. + +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_SERVICE_NAME.md b/docs/libcurl/opts/CURLOPT_SERVICE_NAME.md index 87d6c5c0e..b928c9102 100644 --- a/docs/libcurl/opts/CURLOPT_SERVICE_NAME.md +++ b/docs/libcurl/opts/CURLOPT_SERVICE_NAME.md @@ -40,6 +40,9 @@ allows you to change them. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT See above diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md index 403570a4e..3ad3a63fe 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md +++ b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md @@ -40,6 +40,9 @@ CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256(3) instead. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md index 878e012e0..cd8d6ecdb 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md +++ b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md @@ -33,6 +33,12 @@ Pass a char pointer pointing to a string containing a Base64-encoded SHA256 hash of the remote host's public key. The transfer fails if the given hash does not match the hash the remote host provides. +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.md b/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.md index a099af3a2..8b7705b4b 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.md +++ b/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.md @@ -37,6 +37,9 @@ behavior on host and key matches and mismatches. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSLCERT.md b/docs/libcurl/opts/CURLOPT_SSLCERT.md index c9b3ab64b..8669e9505 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERT.md +++ b/docs/libcurl/opts/CURLOPT_SSLCERT.md @@ -48,13 +48,12 @@ in order to avoid confusion with a nickname. certificate store. (You can import *PFX* to a store first). You can use "\\\\\\\" to refer to a certificate in the system certificates store, for example, -**"CurrentUser\\MY\\934a7ac6f8a5d579285a74fa"**. The thumbprint is usually a -SHA-1 hex string which you can see in certificate details. Following store -locations are supported: **CurrentUser**, **LocalMachine**, -**CurrentService**, **Services**, **CurrentUserGroupPolicy**, -**LocalMachineGroupPolicy**, **LocalMachineEnterprise**. Schannel also support -P12 certificate file, with the string `P12` specified with -CURLOPT_SSLCERTTYPE(3). +**"CurrentUser\\MY\\934a7ac6f8a5d5"**. The thumbprint is usually a SHA-1 hex +string which you can see in certificate details. Following store locations are +supported: **CurrentUser**, **LocalMachine**, **CurrentService**, +**Services**, **CurrentUserGroupPolicy**, **LocalMachineGroupPolicy**, +**LocalMachineEnterprise**. Schannel also support P12 certificate file, with +the string `P12` specified with CURLOPT_SSLCERTTYPE(3). When using a client certificate, you most likely also need to provide a private key with CURLOPT_SSLKEY(3). @@ -62,6 +61,9 @@ private key with CURLOPT_SSLKEY(3). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.md b/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.md index d08273550..efde95b16 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.md +++ b/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.md @@ -38,12 +38,15 @@ the format of your certificate. Supported formats are "PEM" and "DER", except with Secure Transport or Schannel. OpenSSL (versions 0.9.3 and later), Secure Transport (on iOS 5 or -later, or OS X 10.7 or later) and Schannel support "P12" for PKCS#12-encoded +later, or macOS 10.7 or later) and Schannel support "P12" for PKCS#12-encoded files. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL restores back to internal default. + # DEFAULT "PEM" diff --git a/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.md b/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.md index 88f60eb2a..fb1cc62fa 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.md +++ b/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.md @@ -15,6 +15,7 @@ TLS-backend: - Secure Transport - Schannel - mbedTLS + - wolfSSL Added-in: 7.71.0 --- diff --git a/docs/libcurl/opts/CURLOPT_SSLENGINE.md b/docs/libcurl/opts/CURLOPT_SSLENGINE.md index 2e66aa8d0..9bddf39ff 100644 --- a/docs/libcurl/opts/CURLOPT_SSLENGINE.md +++ b/docs/libcurl/opts/CURLOPT_SSLENGINE.md @@ -35,6 +35,9 @@ identifier for the crypto engine you want to use for your private key. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSLKEY.md b/docs/libcurl/opts/CURLOPT_SSLKEY.md index 27f0f347c..13363ce2b 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEY.md +++ b/docs/libcurl/opts/CURLOPT_SSLKEY.md @@ -36,13 +36,16 @@ Pass a pointer to a null-terminated string as parameter. The string should be the filename of your private key. The default format is "PEM" and can be changed with CURLOPT_SSLKEYTYPE(3). -(Windows, iOS and Mac OS X) This option is ignored by Secure Transport and +(Windows, iOS and macOS) This option is ignored by Secure Transport and Schannel SSL backends because they expect the private key to be already present in the key-chain or PKCS#12 file containing the certificate. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.md b/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.md index 73e1a7547..0f0106dc3 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.md +++ b/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.md @@ -42,6 +42,9 @@ currently does not work because of a bug in OpenSSL. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to internal default. + # DEFAULT "PEM" diff --git a/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.md b/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.md index 10b047984..bedf2d33c 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.md +++ b/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.md @@ -11,6 +11,7 @@ Protocol: - TLS TLS-backend: - OpenSSL + - wolfSSL Added-in: 7.71.0 --- diff --git a/docs/libcurl/opts/CURLOPT_SSLVERSION.md b/docs/libcurl/opts/CURLOPT_SSLVERSION.md index e39159696..fd05eb416 100644 --- a/docs/libcurl/opts/CURLOPT_SSLVERSION.md +++ b/docs/libcurl/opts/CURLOPT_SSLVERSION.md @@ -77,7 +77,6 @@ TLS v1.3 or later (Added in 7.52.0) The maximum TLS version can be set by using *one* of the CURL_SSLVERSION_MAX_ macros below. It is also possible to OR *one* of the CURL_SSLVERSION_ macros with *one* of the CURL_SSLVERSION_MAX_ macros. -The MAX macros are not supported for wolfSSL. ## CURL_SSLVERSION_MAX_DEFAULT @@ -138,13 +137,19 @@ int main(void) # HISTORY -SSLv2 and SSLv3 are refused completely since curl 7.77.0 - SSLv2 is disabled by default since 7.18.1. Other SSL versions availability may vary depending on which backend libcurl has been built to use. SSLv3 is disabled by default since 7.39.0. +SSLv2 and SSLv3 are refused completely since curl 7.77.0 + +Since 8.10.0 wolfSSL is fully supported. Before 8.10.0 the MAX macros were not +supported with wolfSSL and the other macros did not set a minimum, but +restricted the TLS version to only the specified one. + +Rustls support added in 8.10.0. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md index c8923e66b..df57c837c 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md +++ b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md @@ -18,8 +18,8 @@ TLS-backend: - Schannel - Secure Transport - wolfSSL - - GnuTLS - mbedTLS + - rustls Added-in: 7.9 --- @@ -38,25 +38,17 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_CIPHER_LIST, char *list); # DESCRIPTION Pass a char pointer, pointing to a null-terminated string holding the list of -ciphers to use for the SSL connection. The list must be syntactically correct, -it consists of one or more cipher strings separated by colons. Commas or -spaces are also acceptable separators but colons are normally used, !, - and -+ can be used as operators. - -For OpenSSL and GnuTLS valid examples of cipher lists include **RC4-SHA**, -**SHA1+DES**, **TLSv1** and **DEFAULT**. The default list is normally set when -you compile OpenSSL. - -For wolfSSL, valid examples of cipher lists include **ECDHE-RSA-RC4-SHA**, -**AES256-SHA:AES256-SHA256**, etc. - -For mbedTLS and BearSSL, valid examples of cipher lists include -**ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256**, or when using -IANA names -**TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256**, -etc. With mbedTLS and BearSSL you do not add/remove ciphers. If one uses this -option then all known ciphers are disabled and only those passed in are -enabled. +cipher suites to use for the TLS 1.2 (1.1, 1.0) connection. The list must +be syntactically correct, it consists of one or more cipher suite strings +separated by colons. + +For setting TLS 1.3 ciphers see CURLOPT_TLS13_CIPHERS(3). + +A valid example of a cipher list is: +~~~ +"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:" +"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305" +~~~ For Schannel, you can use this option to set algorithms but not specific cipher suites. Refer to the ciphers lists document for algorithms. @@ -68,6 +60,9 @@ Find more details about cipher lists on this URL: The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL, use built-in list @@ -83,7 +78,9 @@ int main(void) if(curl) { CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "TLSv1"); + curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, + "ECDHE-ECDSA-CHACHA20-POLY1305:" + "ECDHE-RSA-CHACHA20-POLY1305"); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } @@ -92,11 +89,18 @@ int main(void) # HISTORY -Added in 7.9, in 7.83.0 for BearSSL, in 8.8.0 for mbedTLS +OpenSSL support added in 7.9. +wolfSSL support added in 7.53.0. +Schannel support added in 7.61.0. +Secure Transport support added in 7.77.0. +BearSSL support added in 7.83.0. +mbedTLS support added in 8.8.0. +Rustls support added in 8.10.0. + +Since curl 8.10.0 returns CURLE_NOT_BUILT_IN when not supported. # %AVAILABILITY% # RETURN VALUE -Returns CURLE_OK if TLS is supported, CURLE_UNKNOWN_OPTION if not, or -CURLE_OUT_OF_MEMORY if there was insufficient heap space. +Returns CURLE_OK if supported, CURLE_NOT_BUILT_IN otherwise. diff --git a/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.md b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.md index d1459c420..6256e25f7 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.md +++ b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.md @@ -25,14 +25,20 @@ CURLOPT_SSL_EC_CURVES - key exchange curves ~~~c #include -CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_EC_CURVES, char *alg_list); +CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_EC_CURVES, char *list); ~~~ # DESCRIPTION -Pass a string as parameter with a colon delimited list of (EC) algorithms. This -option defines the client's key exchange algorithms in the SSL handshake (if -the SSL backend libcurl is built to use supports it). +Pass a string as parameter with a colon delimited list of Elliptic curve (EC) +algorithms. This option defines the client's key exchange algorithms in the +SSL handshake (if the SSL backend libcurl is built to use supports it). + +The application does not have to keep the string around after setting this +option. + +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore back to internal default. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.md b/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.md index 34717cbed..85a92f8da 100644 --- a/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.md +++ b/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.md @@ -32,6 +32,12 @@ negotiations. The variables should be in the format \. libcurl supports the options **TTYPE**, **XDISPLOC** and **NEW_ENV**. See the TELNET standard for details. +Using this option multiple times makes the last set list override the previous +ones. Set it to NULL to disable its use again. + +libcurl does not copy the list, it needs to be kept around until after the +transfer has completed. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_TIMEOUT.md b/docs/libcurl/opts/CURLOPT_TIMEOUT.md index 0dc17f036..d5b396cec 100644 --- a/docs/libcurl/opts/CURLOPT_TIMEOUT.md +++ b/docs/libcurl/opts/CURLOPT_TIMEOUT.md @@ -55,7 +55,7 @@ With CURLOPT_CONNECTTIMEOUT(3) set to 4 and CURLOPT_TIMEOUT(3) set to 2, the operation can never last longer than 2 seconds. This option may cause libcurl to use the SIGALRM signal to timeout system -calls on builds not using asynch DNS. In unix-like systems, this might cause +calls on builds not using asynch DNS. In Unix-like systems, this might cause signals to be used unless CURLOPT_NOSIGNAL(3) is set. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.md b/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.md index f9320560d..e720db7bf 100644 --- a/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.md +++ b/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.md @@ -16,6 +16,9 @@ Protocol: TLS-backend: - OpenSSL - Schannel + - wolfSSL + - mbedTLS + - rustls Added-in: 7.61.0 --- @@ -38,18 +41,23 @@ cipher suites to use for the TLS 1.3 connection. The list must be syntactically correct, it consists of one or more cipher suite strings separated by colons. +For setting TLS 1.2 (1.1, 1.0) ciphers see CURLOPT_SSL_CIPHER_LIST(3). + +A valid example of a cipher list is: +~~~c +"TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256" +~~~ + Find more details about cipher lists on this URL: https://curl.se/docs/ssl-ciphers.html -This option is currently used only when curl is built to use OpenSSL 1.1.1 or -later, or Schannel. If you are using a different SSL backend you can try -setting TLS 1.3 cipher suites by using the CURLOPT_SSL_CIPHER_LIST(3) -option. - The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to internal default. + # DEFAULT NULL, use internal built-in @@ -75,9 +83,15 @@ int main(void) # HISTORY -Added in 7.61.0 for OpenSSL. Available when built with OpenSSL \>= 1.1.1. +OpenSSL support added in 7.61.0, available when built with OpenSSL \>= 1.1.1. +Schannel support added in 7.85.0. +LibreSSL support added in 8.3.0, available when built with LibreSSL \>= 3.4.1. +wolfSSL support added in 8.10.0. +mbedTLS support added in 8.10.0, available when built with mbedTLS \>= 3.6.0. +Rustls support added in 8.10.0. -Added in 7.85.0 for Schannel. +Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites where set +by using the CURLOPT_SSL_CIPHER_LIST(3) option. # %AVAILABILITY% diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.md b/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.md index f97108a96..2548aa73d 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.md +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.md @@ -38,6 +38,9 @@ option also be set. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + This feature relies on TLS SRP which does not work with TLS 1.3. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.md b/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.md index 52c38a20d..719095cf5 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.md +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.md @@ -32,6 +32,12 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TLSAUTH_TYPE, char *type); Pass a pointer to a null-terminated string as parameter. The string should be the method of the TLS authentication. Supported method is "SRP". +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to restore to internal default. + +The application does not have to keep the string around after setting this +option. + ## SRP TLS-SRP authentication. Secure Remote Password authentication for TLS is diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.md b/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.md index 6715f75f1..9af68650b 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.md +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.md @@ -37,6 +37,9 @@ option also be set. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + This feature relies on TLS SRP which does not work with TLS 1.3. # DEFAULT diff --git a/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.md b/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.md index bde3b3164..d77274f7d 100644 --- a/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.md +++ b/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.md @@ -26,7 +26,7 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TRANSFERTEXT, long text); # DESCRIPTION A parameter set to 1 tells the library to use ASCII mode for FTP transfers, -instead of the default binary transfer. For win32 systems it does not set the +instead of the default binary transfer. For Win32 systems it does not set the stdout to binary mode. This option can be usable when transferring text data between systems with different views on certain characters, such as newlines or similar. diff --git a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.md b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.md index f5197ee62..7b369f190 100644 --- a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.md +++ b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.md @@ -38,14 +38,17 @@ does not resolve the DNS hostname in the URL. The maximum path length on Cygwin, Linux and Solaris is 107. On other platforms it might be even less. -Proxy and TCP options such as CURLOPT_TCP_NODELAY(3) are not -supported. Proxy options such as CURLOPT_PROXY(3) have no effect either -as these are TCP-oriented, and asking a proxy server to connect to a certain -Unix domain socket is not possible. +Proxy and TCP options such as CURLOPT_TCP_NODELAY(3) are not supported. Proxy +options such as CURLOPT_PROXY(3) have no effect either as these are +TCP-oriented, and asking a proxy server to connect to a certain Unix domain +socket is not possible. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL - no Unix domain sockets are used. diff --git a/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.md b/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.md index 010ec09f2..a80c4f6f2 100644 --- a/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.md +++ b/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.md @@ -31,17 +31,19 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_UNRESTRICTED_AUTH, # DESCRIPTION Set the long *gohead* parameter to 1L to make libcurl continue to send -authentication (user+password) credentials when following locations, even when -hostname changed. This option is meaningful only when setting -CURLOPT_FOLLOWLOCATION(3). +authentication (user+password) credentials or explicitly set cookie headers +when following locations, even when the host changes. This option is +meaningful only when setting CURLOPT_FOLLOWLOCATION(3). -Further, when this option is not used or set to **0L**, libcurl does not -send custom nor internally generated Authentication: headers on requests done -to other hosts than the one used for the initial URL. +Further, when this option is not used or set to **0L**, libcurl does not send +custom nor internally generated `Authentication:` or `Cookie:` headers on +requests done to other hosts than the one used for the initial URL. Another +host means that one or more of hostname, protocol scheme or port number +changed. -By default, libcurl only sends credentials and Authentication headers to the -initial hostname as given in the original URL, to avoid leaking username + -password to other sites. +By default, libcurl only sends `Authentication:` or explicitly set `Cookie:` +headers to the initial host as given in the original URL, to avoid leaking +username + password to other sites. This option should be used with caution: when curl follows redirects it blindly fetches the next URL as instructed by the server. Setting @@ -49,6 +51,11 @@ CURLOPT_UNRESTRICTED_AUTH(3) to 1L makes curl trust the server and sends possibly sensitive credentials to any host the server points to, possibly again and again as the following hosts can keep redirecting to new hosts. +Due to the way HTTP works, almost any header can be made to contain data a +client may not want to pass on to other servers than the initially intended +host and for all other headers than the two mentioned above, there is no +protection from this happening when libcurl is told to follow redirects. + # DEFAULT 0 diff --git a/docs/libcurl/opts/CURLOPT_URL.md b/docs/libcurl/opts/CURLOPT_URL.md index 45d823987..93dacdf27 100644 --- a/docs/libcurl/opts/CURLOPT_URL.md +++ b/docs/libcurl/opts/CURLOPT_URL.md @@ -71,6 +71,10 @@ transfer is started. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. Note however that +libcurl needs a URL set to be able to performed a transfer. + The parser used for handling the URL set with CURLOPT_URL(3) is the same that curl_url_set(3) uses. @@ -81,7 +85,7 @@ expected to be a sequence of characters using an ASCII compatible encoding. If libcurl is built with IDN support, the server name part of the URL can use an "international name" by using the current encoding (according to locale) or -UTF-8 (when winidn is used; or a Windows Unicode build using libidn2). +UTF-8 (when WinIDN is used; or a Windows Unicode build using libidn2). If libcurl is built without IDN support, the server name is used exactly as specified when passed to the name resolver functions. diff --git a/docs/libcurl/opts/CURLOPT_USERAGENT.md b/docs/libcurl/opts/CURLOPT_USERAGENT.md index 1aeb1c9ab..e10ff0cff 100644 --- a/docs/libcurl/opts/CURLOPT_USERAGENT.md +++ b/docs/libcurl/opts/CURLOPT_USERAGENT.md @@ -35,6 +35,9 @@ can also set any custom header with CURLOPT_HTTPHEADER(3). The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL, no User-Agent: header is used. diff --git a/docs/libcurl/opts/CURLOPT_USERPWD.md b/docs/libcurl/opts/CURLOPT_USERPWD.md index 3d5e34d01..b9db9faf6 100644 --- a/docs/libcurl/opts/CURLOPT_USERPWD.md +++ b/docs/libcurl/opts/CURLOPT_USERPWD.md @@ -63,6 +63,9 @@ for that, or include it in the URL. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.md b/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.md index a7c130a50..e2f95371a 100644 --- a/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.md +++ b/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.md @@ -56,12 +56,14 @@ you only download data, the upload size remains 0). Many times the callback is called one or more times first, before it knows the data sizes so a program must be made to handle that. +Return zero from the callback if everything is fine. + +Return 1 from this callback to make libcurl abort the transfer and return +*CURLE_ABORTED_BY_CALLBACK*. + If your callback function returns CURL_PROGRESSFUNC_CONTINUE it makes libcurl to continue executing the default progress function. -Returning any other non-zero value from this callback makes libcurl abort the -transfer and return *CURLE_ABORTED_BY_CALLBACK*. - If you transfer data with the multi interface, this function is not called during periods of idleness unless you call the appropriate libcurl function that performs transfers. diff --git a/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.md b/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.md index 061a1f69b..742896583 100644 --- a/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.md +++ b/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.md @@ -40,6 +40,9 @@ Token should be supplied via the CURLOPT_USERNAME(3) option. The application does not have to keep the string around after setting this option. +Using this option multiple times makes the last set string override the +previous ones. Set it to NULL to disable its use again. + # DEFAULT NULL diff --git a/docs/libcurl/opts/Makefile.in b/docs/libcurl/opts/Makefile.in index abf1fdbf8..dd45c77b3 100644 --- a/docs/libcurl/opts/Makefile.in +++ b/docs/libcurl/opts/Makefile.in @@ -246,11 +246,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -296,7 +296,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -312,8 +311,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -346,10 +347,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -360,6 +359,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -368,6 +368,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -487,6 +488,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies @BUILD_DOCS_TRUE@ CURLINFO_OS_ERRNO.3 \ @BUILD_DOCS_TRUE@ CURLINFO_PRETRANSFER_TIME.3 \ @BUILD_DOCS_TRUE@ CURLINFO_PRETRANSFER_TIME_T.3 \ +@BUILD_DOCS_TRUE@ CURLINFO_POSTTRANSFER_TIME_T.3 \ @BUILD_DOCS_TRUE@ CURLINFO_PRIMARY_IP.3 \ @BUILD_DOCS_TRUE@ CURLINFO_PRIMARY_PORT.3 \ @BUILD_DOCS_TRUE@ CURLINFO_PRIVATE.3 \ diff --git a/docs/libcurl/opts/Makefile.inc b/docs/libcurl/opts/Makefile.inc index f09c5863d..edabe37a7 100644 --- a/docs/libcurl/opts/Makefile.inc +++ b/docs/libcurl/opts/Makefile.inc @@ -58,6 +58,7 @@ man_MANS = \ CURLINFO_OS_ERRNO.3 \ CURLINFO_PRETRANSFER_TIME.3 \ CURLINFO_PRETRANSFER_TIME_T.3 \ + CURLINFO_POSTTRANSFER_TIME_T.3 \ CURLINFO_PRIMARY_IP.3 \ CURLINFO_PRIMARY_PORT.3 \ CURLINFO_PRIVATE.3 \ diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index ebf2cee29..cbabc48bf 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -177,7 +177,7 @@ CURL_VERSION_LARGEFILE 7.11.1 CURL_VERSION_LIBZ 7.10 CURL_VERSION_MULTI_SSL 7.56.0 CURL_VERSION_NTLM 7.10.6 -CURL_VERSION_NTLM_WB 7.22.0 +CURL_VERSION_NTLM_WB 7.22.0 8.8.0 CURL_VERSION_PSL 7.47.0 CURL_VERSION_SPNEGO 7.10.8 CURL_VERSION_SSL 7.10 @@ -210,7 +210,7 @@ CURLAUTH_GSSNEGOTIATE 7.10.6 7.38.0 CURLAUTH_NEGOTIATE 7.38.0 CURLAUTH_NONE 7.10.6 CURLAUTH_NTLM 7.10.6 -CURLAUTH_NTLM_WB 7.22.0 +CURLAUTH_NTLM_WB 7.22.0 8.8.0 CURLAUTH_ONLY 7.21.3 CURLCLOSEPOLICY_CALLBACK 7.7 7.16.1 CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7 7.16.1 @@ -462,6 +462,7 @@ CURLINFO_OFF_T 7.55.0 CURLINFO_OS_ERRNO 7.12.2 CURLINFO_PRETRANSFER_TIME 7.4.1 CURLINFO_PRETRANSFER_TIME_T 7.61.0 +CURLINFO_POSTTRANSFER_TIME_T 8.10.0 CURLINFO_PRIMARY_IP 7.19.0 CURLINFO_PRIMARY_PORT 7.21.0 CURLINFO_PRIVATE 7.10.3 diff --git a/docs/options-in-versions b/docs/options-in-versions index e329f8723..62b61d94a 100644 --- a/docs/options-in-versions +++ b/docs/options-in-versions @@ -54,6 +54,7 @@ --doh-cert-status 7.76.0 --doh-insecure 7.76.0 --doh-url 7.62.0 +--dump-ca-embed 8.10.0 --dump-header (-D) 5.7 --ech 8.8.0 --egd-file 7.7 @@ -100,7 +101,6 @@ --ignore-content-length 7.14.1 --ip-tos 8.9.0 --ipfs-gateway 8.4.0 ---include (-i) 4.8 --insecure (-k) 7.10 --interface 7.3 --ipv4 (-4) 7.10.8 @@ -216,7 +216,9 @@ --sasl-ir 7.31.0 --service-name 7.43.0 --show-error (-S) 5.9 +--show-headers (-i) 4.8 --silent (-s) 4.0 +--skip-existing 8.10.0 --socks4 7.15.2 --socks4a 7.18.0 --socks5 7.18.0 diff --git a/include/Makefile.in b/include/Makefile.in index 1b9510060..04f6bdd31 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -224,11 +224,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -274,7 +274,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -290,8 +289,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -324,10 +325,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -338,6 +337,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -346,6 +346,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/include/curl/Makefile.in b/include/curl/Makefile.in index 5e534ac7f..e360e6511 100644 --- a/include/curl/Makefile.in +++ b/include/curl/Makefile.in @@ -211,11 +211,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -261,7 +261,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -277,8 +276,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -311,10 +312,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -325,6 +324,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -333,6 +333,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/include/curl/curl.h b/include/curl/curl.h index 6da44ce9b..c4fae4d44 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -76,7 +76,7 @@ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) #if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was +/* The check above prevents the winsock2.h inclusion if winsock.h already was included, since they cannot co-exist without problems */ #include #include @@ -721,6 +721,8 @@ typedef enum { with them. */ #define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 #define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 +#define CURLOPT_OBSOLETE72 9999 +#define CURLOPT_OBSOLETE40 9999 #endif /* !CURL_NO_OLDIES */ @@ -1250,8 +1252,7 @@ typedef enum { /* send linked-list of post-transfer QUOTE commands */ CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39), - /* OBSOLETE, do not use! */ - CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40), + /* 40 is not used */ /* talk a lot */ CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41), @@ -1352,9 +1353,7 @@ typedef enum { /* Max amount of cached alive connections */ CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71), - /* OBSOLETE, do not use! */ - CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72), - + /* 72 = OBSOLETE */ /* 73 = OBSOLETE */ /* Set to explicitly use a new connection for the upcoming transfer. @@ -1398,7 +1397,7 @@ typedef enum { operation. Set filename to "-" (dash) to make it go to stdout. */ CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82), - /* Specify which SSL ciphers to use */ + /* Specify which TLS 1.2 (1.1, 1.0) ciphers to use */ CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83), /* Specify which HTTP version to use! This must be set to one of the @@ -2022,7 +2021,7 @@ typedef enum { /* password for the SSL private key for proxy */ CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258), - /* Specify which SSL ciphers to use for proxy */ + /* Specify which TLS 1.2 (1.1, 1.0) ciphers to use for proxy */ CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259), /* CRL file for proxy */ @@ -2203,7 +2202,7 @@ typedef enum { /* specify which protocols that libcurl is allowed to follow directs to */ CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319), - /* websockets options */ + /* WebSockets options */ CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320), /* CA cache timeout */ @@ -2645,7 +2644,7 @@ CURL_EXTERN char *curl_getenv(const char *variable); * * DESCRIPTION * - * Returns a static ascii string of the libcurl version. + * Returns a static ASCII string of the libcurl version. */ CURL_EXTERN char *curl_version(void); @@ -2953,7 +2952,8 @@ typedef enum { CURLINFO_CONN_ID = CURLINFO_OFF_T + 64, CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65, CURLINFO_USED_PROXY = CURLINFO_LONG + 66, - CURLINFO_LASTONE = 66 + CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67, + CURLINFO_LASTONE = 67 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as @@ -3236,7 +3236,9 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #include "options.h" #include "header.h" #include "websockets.h" +#ifndef CURL_SKIP_INCLUDE_MPRINTF #include "mprintf.h" +#endif /* the typechecker does not work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ diff --git a/include/curl/curlver.h b/include/curl/curlver.h index dbee9bd4d..f162a5677 100644 --- a/include/curl/curlver.h +++ b/include/curl/curlver.h @@ -32,13 +32,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "8.9.1" +#define LIBCURL_VERSION "8.10.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 8 -#define LIBCURL_VERSION_MINOR 9 -#define LIBCURL_VERSION_PATCH 1 +#define LIBCURL_VERSION_MINOR 10 +#define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will @@ -59,7 +59,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x080901 +#define LIBCURL_VERSION_NUM 0x080a00 /* * This is the date and time when the full source package was created. The @@ -70,7 +70,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2024-07-31" +#define LIBCURL_TIMESTAMP "2024-09-11" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/include/curl/mprintf.h b/include/curl/mprintf.h index e6bc5bca4..88059c851 100644 --- a/include/curl/mprintf.h +++ b/include/curl/mprintf.h @@ -32,13 +32,18 @@ extern "C" { #endif +#ifndef CURL_TEMP_PRINTF #if (defined(__GNUC__) || defined(__clang__) || \ defined(__IAR_SYSTEMS_ICC__)) && \ defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ !defined(CURL_NO_FMT_CHECKS) #if defined(__MINGW32__) && !defined(__clang__) +#if defined(__MINGW_PRINTF_FORMAT) /* mingw-w64 3.0.0+. Needs stdio.h. */ #define CURL_TEMP_PRINTF(fmt, arg) \ - __attribute__((format(gnu_printf, fmt, arg))) + __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg))) +#else +#define CURL_TEMP_PRINTF(fmt, arg) +#endif #else #define CURL_TEMP_PRINTF(fmt, arg) \ __attribute__((format(printf, fmt, arg))) @@ -46,6 +51,7 @@ extern "C" { #else #define CURL_TEMP_PRINTF(fmt, arg) #endif +#endif CURL_EXTERN int curl_mprintf(const char *format, ...) CURL_TEMP_PRINTF(1, 2); diff --git a/include/curl/system.h b/include/curl/system.h index 363914f20..e5be25684 100644 --- a/include/curl/system.h +++ b/include/curl/system.h @@ -31,7 +31,7 @@ * changed. * * In order to differentiate between platforms/compilers/architectures use - * only compiler built in predefined preprocessor symbols. + * only compiler built-in predefined preprocessor symbols. * * curl_off_t * ---------- diff --git a/lib/.checksrc b/lib/.checksrc index 16133a44c..9066946c8 100644 --- a/lib/.checksrc +++ b/lib/.checksrc @@ -1 +1,2 @@ enable STRERROR +enable STRNCPY diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 63e5b9139..98b4616a1 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -23,46 +23,44 @@ ########################################################################### set(LIB_NAME libcurl) set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library") -add_definitions(-DBUILDING_LIBCURL) +add_definitions("-DBUILDING_LIBCURL") -configure_file(curl_config.h.cmake - ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h) +configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h") +# Get 'CSOURCES', 'HHEADERS' variables transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") # DllMain is added later for DLL builds only. -list(REMOVE_ITEM CSOURCES dllmain.c) +list(REMOVE_ITEM CSOURCES "dllmain.c") -list(APPEND HHEADERS ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h) +list(APPEND HHEADERS "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h") # The rest of the build -include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories( + "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" +) if(USE_ARES) - include_directories(${CARES_INCLUDE_DIR}) + include_directories(${CARES_INCLUDE_DIRS}) endif() if(BUILD_TESTING) add_library( - curlu # special libcurlu library just for unittests + curlu # special libcurlu library just for unittests STATIC EXCLUDE_FROM_ALL ${HHEADERS} ${CSOURCES} ) - target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB) + target_compile_definitions(curlu PUBLIC "UNITTESTS" "CURL_STATICLIB") target_link_libraries(curlu PRIVATE ${CURL_LIBS}) endif() if(ENABLE_CURLDEBUG) # We must compile these sources separately to avoid memdebug.h redefinitions # applying to them. - set_source_files_properties(memdebug.c curl_multibyte.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) + set_source_files_properties("memdebug.c" "curl_multibyte.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) endif() ## Library definition @@ -97,13 +95,12 @@ if(SHARE_LIB_OBJECT) # exported libcurl symbols. We handle exports via libcurl.def instead. # Except with symbol hiding disabled or debug mode enabled, when we export # _all_ symbols from libcurl DLL, without using libcurl.def. - set_property(TARGET ${LIB_OBJECT} APPEND - PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") + set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") endif() target_link_libraries(${LIB_OBJECT} PRIVATE ${CURL_LIBS}) set_target_properties(${LIB_OBJECT} PROPERTIES POSITION_INDEPENDENT_CODE ON) - if(HIDES_CURL_PRIVATE_SYMBOLS) + if(CURL_HIDES_PRIVATE_SYMBOLS) set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") endif() @@ -114,22 +111,21 @@ if(SHARE_LIB_OBJECT) endif() target_include_directories(${LIB_OBJECT} INTERFACE - $ - $) + "$" + "$") set(LIB_SOURCE $) else() set(LIB_SOURCE ${HHEADERS} ${CSOURCES}) endif() -# we want it to be called libcurl on all platforms +# We want it to be called libcurl on all platforms if(BUILD_STATIC_LIBS) list(APPEND libcurl_export ${LIB_STATIC}) add_library(${LIB_STATIC} STATIC ${LIB_SOURCE}) add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC}) if(WIN32) - set_property(TARGET ${LIB_OBJECT} APPEND - PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") + set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") endif() target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS}) # Remove the "lib" prefix since the library is already named "libcurl". @@ -137,7 +133,7 @@ if(BUILD_STATIC_LIBS) PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}" SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}" INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB") - if(HIDES_CURL_PRIVATE_SYMBOLS) + if(CURL_HIDES_PRIVATE_SYMBOLS) set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") endif() @@ -148,8 +144,8 @@ if(BUILD_STATIC_LIBS) endif() target_include_directories(${LIB_STATIC} INTERFACE - $ - $) + "$" + "$") endif() if(BUILD_SHARED_LIBS) @@ -160,15 +156,15 @@ if(BUILD_SHARED_LIBS) if(CYGWIN) # For Cygwin always compile dllmain.c as a separate unit since it # includes windows.h, which should not be included in other units. - set_source_files_properties(dllmain.c PROPERTIES + set_source_files_properties("dllmain.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) endif() - set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES dllmain.c) + set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "dllmain.c") endif() if(WIN32) - set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libcurl.rc) - if(HIDES_CURL_PRIVATE_SYMBOLS) - set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${CURL_SOURCE_DIR}/libcurl.def") + set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libcurl.rc") + if(CURL_HIDES_PRIVATE_SYMBOLS) + set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${CURL_SOURCE_DIR}/lib/libcurl.def") endif() endif() target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS}) @@ -177,7 +173,7 @@ if(BUILD_SHARED_LIBS) PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}" IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}" POSITION_INDEPENDENT_CODE ON) - if(HIDES_CURL_PRIVATE_SYMBOLS) + if(CURL_HIDES_PRIVATE_SYMBOLS) set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") endif() @@ -188,8 +184,8 @@ if(BUILD_SHARED_LIBS) endif() target_include_directories(${LIB_SHARED} INTERFACE - $ - $) + "$" + "$") if(CMAKE_DLL_NAME_WITH_SOVERSION OR CYGWIN OR @@ -203,22 +199,64 @@ if(BUILD_SHARED_LIBS) # up to v3.x and ELF from v3.x. I cannot imagine someone running CMake # on those ancient systems. CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set(soversion_default TRUE) + set(_soversion_default TRUE) else() - set(soversion_default FALSE) + set(_soversion_default FALSE) endif() - option(CURL_LIBCURL_SOVERSION "Enable libcurl SOVERSION" ${soversion_default}) + option(CURL_LIBCURL_SOVERSION "Enable libcurl SOVERSION" ${_soversion_default}) + option(CURL_LIBCURL_VERSIONED_SYMBOLS "Enable libcurl versioned symbols" OFF) - if(CURL_LIBCURL_SOVERSION) + if(CURL_LIBCURL_SOVERSION OR CURL_LIBCURL_VERSIONED_SYMBOLS) + # Get 'VERSIONCHANGE', 'VERSIONADD', 'VERSIONDEL', 'VERSIONINFO' variables transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") - include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake) + include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") - math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}") - set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}") + math(EXPR _cmakesoname "${VERSIONCHANGE} - ${VERSIONDEL}") + set(_cmakeversion "${_cmakesoname}.${VERSIONDEL}.${VERSIONADD}") + endif() + if(CURL_LIBCURL_SOVERSION) set_target_properties(${LIB_SHARED} PROPERTIES - VERSION "${CMAKEVERSION}" SOVERSION "${CMAKESONAME}") + VERSION "${_cmakeversion}" SOVERSION "${_cmakesoname}") + endif() + + ## Versioned symbols + + if(CURL_LIBCURL_VERSIONED_SYMBOLS) + if(NOT DEFINED CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX) + # Default to prefixes used by autotools + if(CURL_WITH_MULTI_SSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MULTISSL_") + elseif(CURL_USE_OPENSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "OPENSSL_") + elseif(CURL_USE_MBEDTLS) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MBEDTLS_") + elseif(CURL_USE_BEARSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "BEARSSL_") + elseif(CURL_USE_WOLFSSL) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_") + elseif(CURL_USE_GNUTLS) + set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_") + endif() + endif() + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers" " + HIDDEN {}; + CURL_${CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX}${_cmakesoname} + { + global: curl_*; + local: *; + };") + include(CheckCSourceCompiles) + set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers") + check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS) + if(HAVE_VERSIONED_SYMBOLS) + # Superseded by LINK_OPTIONS in CMake 3.13 and later. + set_target_properties(${LIB_SHARED} PROPERTIES LINK_FLAGS "${CMAKE_REQUIRED_LINK_OPTIONS}") + else() + message(WARNING "Versioned symbols requested, but not supported by the toolchain.") + endif() + unset(CMAKE_REQUIRED_LINK_OPTIONS) endif() endif() @@ -244,7 +282,7 @@ if(CURL_ENABLE_EXPORT_TARGET) endif() export(TARGETS ${libcurl_export} - FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake - NAMESPACE ${PROJECT_NAME}:: + FILE "${PROJECT_BINARY_DIR}/libcurl-target.cmake" + NAMESPACE ${PROJECT_NAME}:: ) endif() diff --git a/lib/Makefile.am b/lib/Makefile.am index 413fcd4d5..851cee293 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -25,10 +25,14 @@ AUTOMAKE_OPTIONS = foreign nostdinc CMAKE_DIST = CMakeLists.txt curl_config.h.cmake +CHECKSRC_DIST = .checksrc vauth/.checksrc vquic/.checksrc vssh/.checksrc \ + vtls/.checksrc + EXTRA_DIST = Makefile.mk config-win32.h config-win32ce.h config-plan9.h \ config-riscos.h config-mac.h curl_config.h.in config-dos.h libcurl.rc \ config-amigaos.h config-win32ce.h config-os400.h setup-os400.h \ - $(CMAKE_DIST) setup-win32.h .checksrc Makefile.soname + $(CMAKE_DIST) setup-win32.h Makefile.soname optiontable.pl libcurl.def \ + $(CHECKSRC_DIST) lib_LTLIBRARIES = libcurl.la @@ -109,11 +113,11 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING) endif libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) -libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_LIBS) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_PC_LIBS_PRIVATE) libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS -libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) +libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_PC_LIBS_PRIVATE) libcurlu_la_CFLAGS = $(AM_CFLAGS) CHECKSRC = $(CS_$(V)) diff --git a/lib/Makefile.in b/lib/Makefile.in index e0a7c4f94..477e994af 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -897,11 +897,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -947,7 +947,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -963,8 +962,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -999,10 +1000,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -1013,6 +1012,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -1021,6 +1021,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -1130,10 +1131,14 @@ top_srcdir = @top_srcdir@ ########################################################################### AUTOMAKE_OPTIONS = foreign nostdinc CMAKE_DIST = CMakeLists.txt curl_config.h.cmake +CHECKSRC_DIST = .checksrc vauth/.checksrc vquic/.checksrc vssh/.checksrc \ + vtls/.checksrc + EXTRA_DIST = Makefile.mk config-win32.h config-win32ce.h config-plan9.h \ config-riscos.h config-mac.h curl_config.h.in config-dos.h libcurl.rc \ config-amigaos.h config-win32ce.h config-os400.h setup-os400.h \ - $(CMAKE_DIST) setup-win32.h .checksrc Makefile.soname + $(CMAKE_DIST) setup-win32.h Makefile.soname optiontable.pl libcurl.def \ + $(CHECKSRC_DIST) lib_LTLIBRARIES = libcurl.la @BUILD_UNITTESTS_FALSE@noinst_LTLIBRARIES = @@ -1524,10 +1529,10 @@ libcurl_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) libcurl_la_CFLAGS_EXTRA = $(am__append_9) libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) -libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_LIBS) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_PC_LIBS_PRIVATE) libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS -libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) +libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_PC_LIBS_PRIVATE) libcurlu_la_CFLAGS = $(AM_CFLAGS) CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; diff --git a/lib/Makefile.mk b/lib/Makefile.mk index bb6873cc4..7277f8ed4 100644 --- a/lib/Makefile.mk +++ b/lib/Makefile.mk @@ -27,7 +27,7 @@ # Usage: make -f Makefile.mk CFG=-feat1[-feat2][-feat3][...] # Example: make -f Makefile.mk CFG=-zlib-ssl-libssh2-ipv6 # -# Look for ' ?=' to find all accepted customization variables. +# Look for ' ?=' to find accepted customization variables. # This script is reused by 'src' and 'docs/examples' Makefile.mk scripts. @@ -239,7 +239,7 @@ endif ifneq ($(findstring -idn2,$(CFG)),) LIBIDN2_PATH ?= $(PROOT)/../libidn2 - CPPFLAGS += -DUSE_LIBIDN2 + CPPFLAGS += -DHAVE_LIBIDN2 -DHAVE_IDN2_H CPPFLAGS += -I"$(LIBIDN2_PATH)/include" LDFLAGS += -L"$(LIBIDN2_PATH)/lib" LIBS += -lidn2 @@ -277,13 +277,11 @@ DEL = rm -f $1 COPY = -cp -afv $1 $2 MKDIR = mkdir -p $1 RMDIR = rm -fr $1 -WHICH = $(SHELL) -c "command -v $1" else DEL = -del 2>NUL /q /f $(subst /,\,$1) COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) MKDIR = -md 2>NUL $(subst /,\,$1) RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) -WHICH = where $1 endif all: $(TARGETS) diff --git a/lib/altsvc.c b/lib/altsvc.c index db9749c25..dcedc491c 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -337,13 +337,13 @@ CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) */ void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; if(*altsvcp) { + struct Curl_llist_node *e; + struct Curl_llist_node *n; struct altsvcinfo *altsvc = *altsvcp; - for(e = altsvc->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; + for(e = Curl_llist_head(&altsvc->list); e; e = n) { + struct altsvc *as = Curl_node_elem(e); + n = Curl_node_next(e); altsvc_free(as); } free(altsvc->filename); @@ -358,8 +358,6 @@ void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp) CURLcode Curl_altsvc_save(struct Curl_easy *data, struct altsvcinfo *altsvc, const char *file) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; CURLcode result = CURLE_OK; FILE *out; char *tempstore = NULL; @@ -378,12 +376,14 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data, result = Curl_fopen(data, file, &out, &tempstore); if(!result) { + struct Curl_llist_node *e; + struct Curl_llist_node *n; fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n" "# This file was generated by libcurl! Edit at your own risk.\n", out); - for(e = altsvc->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; + for(e = Curl_llist_head(&altsvc->list); e; e = n) { + struct altsvc *as = Curl_node_elem(e); + n = Curl_node_next(e); result = altsvc_out(as, out); if(result) break; @@ -440,15 +440,15 @@ static bool hostcompare(const char *host, const char *check) static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, const char *srchost, unsigned short srcport) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; - for(e = asi->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; + struct Curl_llist_node *e; + struct Curl_llist_node *n; + for(e = Curl_llist_head(&asi->list); e; e = n) { + struct altsvc *as = Curl_node_elem(e); + n = Curl_node_next(e); if((srcalpnid == as->src.alpnid) && (srcport == as->src.port) && hostcompare(srchost, as->src.host)) { - Curl_llist_remove(&asi->list, e, NULL); + Curl_node_remove(e); altsvc_free(as); } } @@ -677,19 +677,19 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, struct altsvc **dstentry, const int versions) /* one or more bits */ { - struct Curl_llist_element *e; - struct Curl_llist_element *n; + struct Curl_llist_node *e; + struct Curl_llist_node *n; time_t now = time(NULL); DEBUGASSERT(asi); DEBUGASSERT(srchost); DEBUGASSERT(dstentry); - for(e = asi->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; + for(e = Curl_llist_head(&asi->list); e; e = n) { + struct altsvc *as = Curl_node_elem(e); + n = Curl_node_next(e); if(as->expires < now) { /* an expired entry, remove */ - Curl_llist_remove(&asi->list, e, NULL); + Curl_node_remove(e); altsvc_free(as); continue; } diff --git a/lib/altsvc.h b/lib/altsvc.h index 58f1905da..48999efb3 100644 --- a/lib/altsvc.h +++ b/lib/altsvc.h @@ -48,7 +48,7 @@ struct altsvc { time_t expires; bool persist; unsigned int prio; - struct Curl_llist_element node; + struct Curl_llist_node node; }; struct altsvcinfo { diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index d91152fdf..79b9c239c 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -54,7 +54,6 @@ # define RESOLVER_ENOMEM ENOMEM #endif -#include "system_win32.h" #include "urldata.h" #include "sendf.h" #include "hostip.h" @@ -145,22 +144,9 @@ static bool init_resolve_thread(struct Curl_easy *data, const char *hostname, int port, const struct addrinfo *hints); -#ifdef _WIN32 -/* Thread sync data used by GetAddrInfoExW for win8+ */ -struct thread_sync_data_w8 -{ - OVERLAPPED overlapped; - ADDRINFOEXW_ *res; - HANDLE cancel_ev; - ADDRINFOEXW_ hints; -}; -#endif /* Data for synchronization between resolver thread and its parent */ struct thread_sync_data { -#ifdef _WIN32 - struct thread_sync_data_w8 w8; -#endif curl_mutex_t *mtx; int done; int port; @@ -179,9 +165,6 @@ struct thread_sync_data { }; struct thread_data { -#ifdef _WIN32 - HANDLE complete_ev; -#endif curl_thread_t thread_hnd; unsigned int poll_interval; timediff_t interval_end; @@ -293,162 +276,6 @@ static CURLcode getaddrinfo_complete(struct Curl_easy *data) return result; } -#ifdef _WIN32 -static VOID WINAPI -query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped) -{ - size_t ss_size; - const ADDRINFOEXW_ *ai; - struct Curl_addrinfo *ca; - struct Curl_addrinfo *cafirst = NULL; - struct Curl_addrinfo *calast = NULL; -#ifndef CURL_DISABLE_SOCKETPAIR -#ifdef USE_EVENTFD - const void *buf; - const uint64_t val = 1; -#else - char buf[1]; -#endif -#endif -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-align" -#endif - struct thread_sync_data *tsd = - CONTAINING_RECORD(overlapped, struct thread_sync_data, w8.overlapped); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - struct thread_data *td = tsd->td; - const ADDRINFOEXW_ *res = tsd->w8.res; - int error = (int)err; - (void)bytes; - - if(error == ERROR_SUCCESS) { - /* traverse the addrinfo list */ - - for(ai = res; ai != NULL; ai = ai->ai_next) { - size_t namelen = ai->ai_canonname ? wcslen(ai->ai_canonname) + 1 : 0; - /* ignore elements with unsupported address family, */ - /* settle family-specific sockaddr structure size. */ - if(ai->ai_family == AF_INET) - ss_size = sizeof(struct sockaddr_in); -#ifdef USE_IPV6 - else if(ai->ai_family == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); -#endif - else - continue; - - /* ignore elements without required address info */ - if(!ai->ai_addr || !(ai->ai_addrlen > 0)) - continue; - - /* ignore elements with bogus address size */ - if((size_t)ai->ai_addrlen < ss_size) - continue; - - ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen); - if(!ca) { - error = EAI_MEMORY; - break; - } - - /* copy each structure member individually, member ordering, */ - /* size, or padding might be different for each platform. */ - ca->ai_flags = ai->ai_flags; - ca->ai_family = ai->ai_family; - ca->ai_socktype = ai->ai_socktype; - ca->ai_protocol = ai->ai_protocol; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = NULL; - ca->ai_canonname = NULL; - ca->ai_next = NULL; - - ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); - memcpy(ca->ai_addr, ai->ai_addr, ss_size); - - if(namelen) { - size_t i; - ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size); - for(i = 0; i < namelen; ++i) /* convert wide string to ascii */ - ca->ai_canonname[i] = (char)ai->ai_canonname[i]; - ca->ai_canonname[namelen] = '\0'; - } - - /* if the return list is empty, this becomes the first element */ - if(!cafirst) - cafirst = ca; - - /* add this element last in the return list */ - if(calast) - calast->ai_next = ca; - calast = ca; - } - - /* if we failed, also destroy the Curl_addrinfo list */ - if(error) { - Curl_freeaddrinfo(cafirst); - cafirst = NULL; - } - else if(!cafirst) { -#ifdef EAI_NONAME - /* rfc3493 conformant */ - error = EAI_NONAME; -#else - /* rfc3493 obsoleted */ - error = EAI_NODATA; -#endif -#ifdef USE_WINSOCK - SET_SOCKERRNO(error); -#endif - } - tsd->res = cafirst; - } - - if(tsd->w8.res) { - Curl_FreeAddrInfoExW(tsd->w8.res); - tsd->w8.res = NULL; - } - - if(error) { - tsd->sock_error = SOCKERRNO?SOCKERRNO:error; - if(tsd->sock_error == 0) - tsd->sock_error = RESOLVER_ENOMEM; - } - else { - Curl_addrinfo_set_port(tsd->res, tsd->port); - } - - Curl_mutex_acquire(tsd->mtx); - if(tsd->done) { - /* too late, gotta clean up the mess */ - Curl_mutex_release(tsd->mtx); - destroy_thread_sync_data(tsd); - free(td); - } - else { -#ifndef CURL_DISABLE_SOCKETPAIR - if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { -#ifdef USE_EVENTFD - buf = &val; -#else - buf[0] = 1; -#endif - /* DNS has been resolved, signal client task */ - if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { - /* update sock_erro to errno */ - tsd->sock_error = SOCKERRNO; - } - } -#endif - tsd->done = 1; - Curl_mutex_release(tsd->mtx); - if(td->complete_ev) - SetEvent(td->complete_ev); /* Notify caller that the query completed */ - } -} -#endif #ifdef HAVE_GETADDRINFO @@ -585,26 +412,9 @@ static void destroy_async_data(struct Curl_async *async) Curl_mutex_release(td->tsd.mtx); if(!done) { -#ifdef _WIN32 - if(td->complete_ev) { - CloseHandle(td->complete_ev); - td->complete_ev = NULL; - } -#endif - if(td->thread_hnd != curl_thread_t_null) { - Curl_thread_destroy(td->thread_hnd); - td->thread_hnd = curl_thread_t_null; - } + Curl_thread_destroy(td->thread_hnd); } else { -#ifdef _WIN32 - if(td->complete_ev) { - Curl_GetAddrInfoExCancel(&td->tsd.w8.cancel_ev); - WaitForSingleObject(td->complete_ev, INFINITE); - CloseHandle(td->complete_ev); - td->complete_ev = NULL; - } -#endif if(td->thread_hnd != curl_thread_t_null) Curl_thread_join(&td->thread_hnd); @@ -650,9 +460,6 @@ static bool init_resolve_thread(struct Curl_easy *data, asp->status = 0; asp->dns = NULL; td->thread_hnd = curl_thread_t_null; -#ifdef _WIN32 - td->complete_ev = NULL; -#endif if(!init_thread_sync_data(td, hostname, port, hints)) { asp->tdata = NULL; @@ -668,42 +475,6 @@ static bool init_resolve_thread(struct Curl_easy *data, /* The thread will set this to 1 when complete. */ td->tsd.done = 0; -#ifdef _WIN32 - if(Curl_isWindows8OrGreater && Curl_FreeAddrInfoExW && - Curl_GetAddrInfoExCancel && Curl_GetAddrInfoExW && - !Curl_win32_impersonating()) { -#define MAX_NAME_LEN 256 /* max domain name is 253 chars */ -#define MAX_PORT_LEN 8 - WCHAR namebuf[MAX_NAME_LEN]; - WCHAR portbuf[MAX_PORT_LEN]; - /* calculate required length */ - int w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, hostname, - -1, NULL, 0); - if((w_len > 0) && (w_len < MAX_NAME_LEN)) { - /* do utf8 conversion */ - w_len = MultiByteToWideChar(CP_UTF8, 0, hostname, -1, namebuf, w_len); - if((w_len > 0) && (w_len < MAX_NAME_LEN)) { - swprintf(portbuf, MAX_PORT_LEN, L"%d", port); - td->tsd.w8.hints.ai_family = hints->ai_family; - td->tsd.w8.hints.ai_socktype = hints->ai_socktype; - td->complete_ev = CreateEvent(NULL, TRUE, FALSE, NULL); - if(!td->complete_ev) { - /* failed to start, mark it as done here for proper cleanup. */ - td->tsd.done = 1; - goto err_exit; - } - err = Curl_GetAddrInfoExW(namebuf, portbuf, NS_DNS, - NULL, &td->tsd.w8.hints, &td->tsd.w8.res, - NULL, &td->tsd.w8.overlapped, - &query_complete, &td->tsd.w8.cancel_ev); - if(err != WSA_IO_PENDING) - query_complete((DWORD)err, 0, &td->tsd.w8.overlapped); - return TRUE; - } - } - } -#endif - #ifdef HAVE_GETADDRINFO td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd); #else @@ -740,23 +511,9 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, DEBUGASSERT(data); td = data->state.async.tdata; DEBUGASSERT(td); -#ifdef _WIN32 - DEBUGASSERT(td->complete_ev || td->thread_hnd != curl_thread_t_null); -#else DEBUGASSERT(td->thread_hnd != curl_thread_t_null); -#endif /* wait for the thread to resolve the name */ -#ifdef _WIN32 - if(td->complete_ev) { - WaitForSingleObject(td->complete_ev, INFINITE); - CloseHandle(td->complete_ev); - td->complete_ev = NULL; - if(entry) - result = getaddrinfo_complete(data); - } - else -#endif if(Curl_thread_join(&td->thread_hnd)) { if(entry) result = getaddrinfo_complete(data); @@ -793,13 +550,6 @@ void Curl_resolver_kill(struct Curl_easy *data) /* If we are still resolving, we must wait for the threads to fully clean up, unfortunately. Otherwise, we can simply cancel to clean up any resolver data. */ -#ifdef _WIN32 - if(td && td->complete_ev) { - Curl_GetAddrInfoExCancel(&td->tsd.w8.cancel_ev); - (void)thread_wait_resolv(data, NULL, FALSE); - } - else -#endif if(td && td->thread_hnd != curl_thread_t_null && (data->set.quick_exit != 1L)) (void)thread_wait_resolv(data, NULL, FALSE); diff --git a/lib/bufq.c b/lib/bufq.c index c3245516c..46e6eaa38 100644 --- a/lib/bufq.c +++ b/lib/bufq.c @@ -91,6 +91,23 @@ static size_t chunk_read(struct buf_chunk *chunk, } } +static size_t chunk_unwrite(struct buf_chunk *chunk, size_t len) +{ + size_t n = chunk->w_offset - chunk->r_offset; + DEBUGASSERT(chunk->w_offset >= chunk->r_offset); + if(!n) { + return 0; + } + else if(n <= len) { + chunk->r_offset = chunk->w_offset = 0; + return n; + } + else { + chunk->w_offset -= len; + return len; + } +} + static ssize_t chunk_slurpn(struct buf_chunk *chunk, size_t max_len, Curl_bufq_reader *reader, void *reader_ctx, CURLcode *err) @@ -363,6 +380,49 @@ static void prune_head(struct bufq *q) } } +static struct buf_chunk *chunk_prev(struct buf_chunk *head, + struct buf_chunk *chunk) +{ + while(head) { + if(head == chunk) + return NULL; + if(head->next == chunk) + return head; + head = head->next; + } + return NULL; +} + +static void prune_tail(struct bufq *q) +{ + struct buf_chunk *chunk; + + while(q->tail && chunk_is_empty(q->tail)) { + chunk = q->tail; + q->tail = chunk_prev(q->head, chunk); + if(q->tail) + q->tail->next = NULL; + if(q->head == chunk) + q->head = q->tail; + if(q->pool) { + bufcp_put(q->pool, chunk); + --q->chunk_count; + } + else if((q->chunk_count > q->max_chunks) || + (q->opts & BUFQ_OPT_NO_SPARES)) { + /* SOFT_LIMIT allowed us more than max. free spares until + * we are at max again. Or free them if we are configured + * to not use spares. */ + free(chunk); + --q->chunk_count; + } + else { + chunk->next = q->spare; + q->spare = chunk; + } + } +} + static struct buf_chunk *get_non_full_tail(struct bufq *q) { struct buf_chunk *chunk; @@ -428,6 +488,15 @@ CURLcode Curl_bufq_cwrite(struct bufq *q, return result; } +CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len) +{ + while(len && q->tail) { + len -= chunk_unwrite(q->head, len); + prune_tail(q); + } + return len? CURLE_AGAIN : CURLE_OK; +} + ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len, CURLcode *err) { diff --git a/lib/bufq.h b/lib/bufq.h index 87ffa45da..ec415648f 100644 --- a/lib/bufq.h +++ b/lib/bufq.h @@ -182,6 +182,12 @@ CURLcode Curl_bufq_cwrite(struct bufq *q, const char *buf, size_t len, size_t *pnwritten); +/** + * Remove `len` bytes from the end of the buffer queue again. + * Returns CURLE_AGAIN if less than `len` bytes were in the queue. + */ +CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len); + /** * Read buf from the start of the buffer queue. The buf is copied * and the amount of copied bytes is returned. diff --git a/lib/c-hyper.c b/lib/c-hyper.c index 3008d9a14..a9a62d0a6 100644 --- a/lib/c-hyper.c +++ b/lib/c-hyper.c @@ -119,7 +119,7 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx, DEBUGF(infof(data, "Curl_hyper_send(%zu)", buflen)); result = Curl_conn_send(data, io_ctx->sockindex, - (void *)buf, buflen, &nwrote); + (void *)buf, buflen, FALSE, &nwrote); if(result == CURLE_AGAIN) { DEBUGF(infof(data, "Curl_hyper_send(%zu) -> EAGAIN", buflen)); /* would block, register interest */ @@ -352,6 +352,8 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, (void)conn; if(data->hyp.send_body_waker) { + /* If there is still something to upload, wake it to give it + * another try. */ hyper_waker_wake(data->hyp.send_body_waker); data->hyp.send_body_waker = NULL; } @@ -367,7 +369,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, h->write_waker = NULL; } - do { + while(1) { hyper_task_return_type t; task = hyper_executor_poll(h->exec); if(!task) { @@ -391,22 +393,22 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, switch(code) { case HYPERE_ABORTED_BY_CALLBACK: result = CURLE_OK; - break; + goto out; case HYPERE_UNEXPECTED_EOF: if(!data->req.bytecount) result = CURLE_GOT_NOTHING; else result = CURLE_RECV_ERROR; - break; + goto out; case HYPERE_INVALID_PEER_MESSAGE: /* bump headerbytecount to avoid the count remaining at zero and appearing to not having read anything from the peer at all */ data->req.headerbytecount++; result = CURLE_UNSUPPORTED_PROTOCOL; /* maybe */ - break; + goto out; default: result = CURLE_RECV_ERROR; - break; + goto out; } } data->req.done = TRUE; @@ -416,7 +418,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, else if(t == HYPER_TASK_EMPTY) { void *userdata = hyper_task_userdata(task); hyper_task_free(task); - if((userdata_t)userdata == USERDATA_RESP_BODY) { + if(userdata == (void *)USERDATA_RESP_BODY) { /* end of transfer */ data->req.done = TRUE; infof(data, "hyperstream is done"); @@ -428,103 +430,115 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, } else { /* A background task for hyper; ignore */ + DEBUGF(infof(data, "hyper: some background task done")); continue; } } + else if(t == HYPER_TASK_RESPONSE) { + resp = hyper_task_value(task); + hyper_task_free(task); - DEBUGASSERT(HYPER_TASK_RESPONSE); - - resp = hyper_task_value(task); - hyper_task_free(task); - - *didwhat = KEEP_RECV; - if(!resp) { - failf(data, "hyperstream: could not get response"); - return CURLE_RECV_ERROR; - } + *didwhat = KEEP_RECV; + if(!resp) { + failf(data, "hyperstream: could not get response"); + result = CURLE_RECV_ERROR; + goto out; + } - http_status = hyper_response_status(resp); - http_version = hyper_response_version(resp); - reasonp = hyper_response_reason_phrase(resp); - reason_len = hyper_response_reason_phrase_len(resp); + http_status = hyper_response_status(resp); + http_version = hyper_response_version(resp); + reasonp = hyper_response_reason_phrase(resp); + reason_len = hyper_response_reason_phrase_len(resp); - if(http_status == 417 && Curl_http_exp100_is_selected(data)) { - infof(data, "Got 417 while waiting for a 100"); - data->state.disableexpect = TRUE; - data->req.newurl = strdup(data->state.url); - Curl_req_abort_sending(data); - } + if(http_status == 417 && Curl_http_exp100_is_selected(data)) { + infof(data, "Got 417 while waiting for a 100"); + data->state.disableexpect = TRUE; + data->req.newurl = strdup(data->state.url); + Curl_req_abort_sending(data); + } - result = status_line(data, conn, - http_status, http_version, reasonp, reason_len); - if(result) - break; + result = status_line(data, conn, + http_status, http_version, reasonp, reason_len); + if(result) + goto out; - headers = hyper_response_headers(resp); - if(!headers) { - failf(data, "hyperstream: could not get response headers"); - result = CURLE_RECV_ERROR; - break; - } + headers = hyper_response_headers(resp); + if(!headers) { + failf(data, "hyperstream: could not get response headers"); + result = CURLE_RECV_ERROR; + goto out; + } - /* the headers are already received */ - hyper_headers_foreach(headers, hyper_each_header, data); - if(data->state.hresult) { - result = data->state.hresult; - break; - } + /* the headers are already received */ + hyper_headers_foreach(headers, hyper_each_header, data); + if(data->state.hresult) { + result = data->state.hresult; + goto out; + } - result = empty_header(data); - if(result) - break; + result = empty_header(data); + if(result) + goto out; - k->deductheadercount = - (100 <= http_status && 199 >= http_status)?k->headerbytecount:0; + k->deductheadercount = + (100 <= http_status && 199 >= http_status)?k->headerbytecount:0; #ifdef USE_WEBSOCKETS - if(k->upgr101 == UPGR101_WS) { - if(http_status == 101) { - /* verify the response */ - result = Curl_ws_accept(data, NULL, 0); - if(result) - return result; - } - else { - failf(data, "Expected 101, got %u", k->httpcode); - result = CURLE_HTTP_RETURNED_ERROR; - break; + if(k->upgr101 == UPGR101_WS) { + if(http_status == 101) { + /* verify the response */ + result = Curl_ws_accept(data, NULL, 0); + if(result) + goto out; + } + else { + failf(data, "Expected 101, got %u", k->httpcode); + result = CURLE_HTTP_RETURNED_ERROR; + goto out; + } } - } #endif - /* Curl_http_auth_act() checks what authentication methods that are - * available and decides which one (if any) to use. It will set 'newurl' - * if an auth method was picked. */ - result = Curl_http_auth_act(data); - if(result) - break; + /* Curl_http_auth_act() checks what authentication methods that are + * available and decides which one (if any) to use. It will set 'newurl' + * if an auth method was picked. */ + result = Curl_http_auth_act(data); + if(result) + goto out; - resp_body = hyper_response_body(resp); - if(!resp_body) { - failf(data, "hyperstream: could not get response body"); - result = CURLE_RECV_ERROR; - break; - } - foreach = hyper_body_foreach(resp_body, hyper_body_chunk, data); - if(!foreach) { - failf(data, "hyperstream: body foreach failed"); - result = CURLE_OUT_OF_MEMORY; - break; + resp_body = hyper_response_body(resp); + if(!resp_body) { + failf(data, "hyperstream: could not get response body"); + result = CURLE_RECV_ERROR; + goto out; + } + foreach = hyper_body_foreach(resp_body, hyper_body_chunk, data); + if(!foreach) { + failf(data, "hyperstream: body foreach failed"); + result = CURLE_OUT_OF_MEMORY; + goto out; + } + hyper_task_set_userdata(foreach, (void *)USERDATA_RESP_BODY); + if(HYPERE_OK != hyper_executor_push(h->exec, foreach)) { + failf(data, "Couldn't hyper_executor_push the body-foreach"); + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + hyper_response_free(resp); + resp = NULL; } - hyper_task_set_userdata(foreach, (void *)USERDATA_RESP_BODY); - if(HYPERE_OK != hyper_executor_push(h->exec, foreach)) { - failf(data, "Couldn't hyper_executor_push the body-foreach"); - result = CURLE_OUT_OF_MEMORY; - break; + else { + DEBUGF(infof(data, "hyper: unhandled tasktype %x", t)); } + } /* while(1) */ - hyper_response_free(resp); - resp = NULL; - } while(1); + if(!result && Curl_xfer_needs_flush(data)) { + DEBUGF(infof(data, "Curl_hyper_stream(), connection needs flush")); + result = Curl_xfer_flush(data); + } + +out: + DEBUGF(infof(data, "Curl_hyper_stream() -> %d", result)); if(resp) hyper_response_free(resp); return result; @@ -671,10 +685,13 @@ static int uploadstreamed(void *userdata, hyper_context *ctx, /* increasing the writebytecount here is a little premature but we do not know exactly when the body is sent */ data->req.writebytecount += fillcount; + if(eos) + data->req.eos_read = TRUE; Curl_pgrsSetUploadCounter(data, data->req.writebytecount); rc = HYPER_POLL_READY; } else if(eos) { + data->req.eos_read = TRUE; *chunk = NULL; rc = HYPER_POLL_READY; } @@ -686,9 +703,15 @@ static int uploadstreamed(void *userdata, hyper_context *ctx, rc = HYPER_POLL_PENDING; } + if(!data->req.upload_done && data->req.eos_read) { + DEBUGF(infof(data, "hyper: uploadstreamed(), upload is done")); + result = Curl_req_set_upload_done(data); + } + out: Curl_multi_xfer_ulbuf_release(data, xfer_ulbuf); data->state.hresult = result; + DEBUGF(infof(data, "hyper: uploadstreamed() -> %d", result)); return rc; } @@ -702,8 +725,9 @@ static CURLcode finalize_request(struct Curl_easy *data, { CURLcode result = CURLE_OK; struct dynbuf req; - if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) + if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) { Curl_pgrsSetUploadSize(data, 0); /* no request body */ + } else { hyper_body *body; Curl_dyn_init(&req, DYN_HTTP_REQUEST); @@ -821,21 +845,21 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) *done = TRUE; result = Curl_client_start(data); if(result) - return result; + goto out; /* Add collecting of headers written to client. For a new connection, * we might have done that already, but reuse * or multiplex needs it here as well. */ result = Curl_headers_init(data); if(result) - return result; + goto out; infof(data, "Time for the Hyper dance"); memset(h, 0, sizeof(struct hyptransfer)); result = Curl_http_host(data, conn); if(result) - return result; + goto out; Curl_http_method(data, conn, &method, &httpreq); @@ -846,33 +870,35 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) char *pq = NULL; if(data->state.up.query) { pq = aprintf("%s?%s", data->state.up.path, data->state.up.query); - if(!pq) - return CURLE_OUT_OF_MEMORY; + if(!pq) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } } result = Curl_http_output_auth(data, conn, method, httpreq, (pq ? pq : data->state.up.path), FALSE); free(pq); if(result) - return result; + goto out; } result = Curl_http_req_set_reader(data, httpreq, &te); if(result) - goto error; + goto out; result = Curl_http_range(data, httpreq); if(result) - return result; + goto out; result = Curl_http_useragent(data); if(result) - return result; + goto out; io = hyper_io_new(); if(!io) { failf(data, "Couldn't create hyper IO"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } /* tell Hyper how to read/write network data */ h->io_ctx.data = data; @@ -887,7 +913,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!h->exec) { failf(data, "Couldn't create hyper executor"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } } @@ -895,12 +921,12 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!options) { failf(data, "Couldn't create hyper client options"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } if(conn->alpn == CURL_HTTP_VERSION_2) { failf(data, "ALPN protocol h2 not supported with Hyper"); result = CURLE_UNSUPPORTED_PROTOCOL; - goto error; + goto out; } hyper_clientconn_options_set_preserve_header_case(options, 1); hyper_clientconn_options_set_preserve_header_order(options, 1); @@ -913,7 +939,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!handshake) { failf(data, "Couldn't create hyper client handshake"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } io = NULL; options = NULL; @@ -921,7 +947,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(HYPERE_OK != hyper_executor_push(h->exec, handshake)) { failf(data, "Couldn't hyper_executor_push the handshake"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } handshake = NULL; /* ownership passed on */ @@ -929,7 +955,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!task) { failf(data, "Couldn't hyper_executor_poll the handshake"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } client = hyper_task_value(task); @@ -939,7 +965,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!req) { failf(data, "Couldn't hyper_request_new"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } if(!Curl_use_http_1_1plus(data, conn)) { @@ -947,57 +973,57 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) HYPER_HTTP_VERSION_1_0)) { failf(data, "error setting HTTP version"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } } if(hyper_request_set_method(req, (uint8_t *)method, strlen(method))) { failf(data, "error setting method"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } result = request_target(data, conn, method, req); if(result) - goto error; + goto out; headers = hyper_request_headers(req); if(!headers) { failf(data, "hyper_request_headers"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } rc = hyper_request_on_informational(req, http1xx_cb, data); if(rc) { result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } if(data->state.aptr.host) { result = Curl_hyper_header(data, headers, data->state.aptr.host); if(result) - goto error; + goto out; } #ifndef CURL_DISABLE_PROXY if(data->state.aptr.proxyuserpwd) { result = Curl_hyper_header(data, headers, data->state.aptr.proxyuserpwd); if(result) - goto error; + goto out; } #endif if(data->state.aptr.userpwd) { result = Curl_hyper_header(data, headers, data->state.aptr.userpwd); if(result) - goto error; + goto out; } if((data->state.use_range && data->state.aptr.rangeline)) { result = Curl_hyper_header(data, headers, data->state.aptr.rangeline); if(result) - goto error; + goto out; } if(data->set.str[STRING_USERAGENT] && @@ -1005,7 +1031,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) data->state.aptr.uagent) { result = Curl_hyper_header(data, headers, data->state.aptr.uagent); if(result) - goto error; + goto out; } p_accept = Curl_checkheaders(data, @@ -1013,12 +1039,12 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(p_accept) { result = Curl_hyper_header(data, headers, p_accept); if(result) - goto error; + goto out; } if(te) { result = Curl_hyper_header(data, headers, te); if(result) - goto error; + goto out; } #ifndef CURL_DISABLE_ALTSVC @@ -1027,11 +1053,11 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) conn->conn_to_host.name, conn->conn_to_port); if(!altused) { result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } result = Curl_hyper_header(data, headers, altused); if(result) - goto error; + goto out; free(altused); } #endif @@ -1042,7 +1068,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) !Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) { result = Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"); if(result) - goto error; + goto out; } #endif @@ -1054,17 +1080,17 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) else result = Curl_hyper_header(data, headers, data->state.aptr.ref); if(result) - goto error; + goto out; } #ifdef HAVE_LIBZ /* we only consider transfer-encoding magic if libz support is built-in */ result = Curl_transferencode(data); if(result) - goto error; + goto out; result = Curl_hyper_header(data, headers, data->state.aptr.te); if(result) - goto error; + goto out; #endif if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) && @@ -1078,29 +1104,29 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) result = Curl_hyper_header(data, headers, data->state.aptr.accept_encoding); if(result) - goto error; + goto out; } else Curl_safefree(data->state.aptr.accept_encoding); result = cookies(data, conn, headers); if(result) - goto error; + goto out; if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS)) result = Curl_ws_request(data, headers); result = Curl_add_timecondition(data, headers); if(result) - goto error; + goto out; result = Curl_add_custom_headers(data, FALSE, headers); if(result) - goto error; + goto out; result = finalize_request(data, headers, req, httpreq); if(result) - goto error; + goto out; Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2); @@ -1114,14 +1140,14 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!sendtask) { failf(data, "hyper_clientconn_send"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } req = NULL; if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) { failf(data, "Couldn't hyper_executor_push the send"); result = CURLE_OUT_OF_MEMORY; - goto error; + goto out; } sendtask = NULL; /* ownership passed on */ @@ -1131,6 +1157,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) { /* HTTP GET/HEAD download */ Curl_pgrsSetUploadSize(data, 0); /* nothing */ + result = Curl_req_set_upload_done(data); + if(result) + goto out; } Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE); @@ -1142,24 +1171,20 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) #ifndef CURL_DISABLE_PROXY Curl_safefree(data->state.aptr.proxyuserpwd); #endif - return CURLE_OK; -error: - DEBUGASSERT(result); - if(io) - hyper_io_free(io); - - if(options) - hyper_clientconn_options_free(options); - - if(handshake) - hyper_task_free(handshake); - - if(client) - hyper_clientconn_free(client); - - if(req) - hyper_request_free(req); +out: + if(result) { + if(io) + hyper_io_free(io); + if(options) + hyper_clientconn_options_free(options); + if(handshake) + hyper_task_free(handshake); + if(client) + hyper_clientconn_free(client); + if(req) + hyper_request_free(req); + } return result; } diff --git a/lib/cf-h1-proxy.c b/lib/cf-h1-proxy.c index 6656b4ddc..6de33d0e2 100644 --- a/lib/cf-h1-proxy.c +++ b/lib/cf-h1-proxy.c @@ -266,7 +266,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf, blen -= ts->nsent; buf += ts->nsent; - nwritten = cf->next->cft->do_send(cf->next, data, buf, blen, &result); + nwritten = cf->next->cft->do_send(cf->next, data, buf, blen, FALSE, &result); if(nwritten < 0) { if(result == CURLE_AGAIN) { result = CURLE_OK; @@ -489,8 +489,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, ts->keepon = KEEPON_IGNORE; if(ts->cl) { - infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T - " bytes of response-body", ts->cl); + infof(data, "Ignore %" FMT_OFF_T " bytes of response-body", ts->cl); } else if(ts->chunked_encoding) { infof(data, "Ignore chunked response-body"); diff --git a/lib/cf-h2-proxy.c b/lib/cf-h2-proxy.c index 7613b7828..0a60ae47c 100644 --- a/lib/cf-h2-proxy.c +++ b/lib/cf-h2-proxy.c @@ -73,7 +73,6 @@ struct tunnel_stream { char *authority; int32_t stream_id; uint32_t error; - size_t upload_blocked_len; h2_tunnel_state state; BIT(has_final_response); BIT(closed); @@ -217,11 +216,13 @@ static void drain_tunnel(struct Curl_cfilter *cf, struct Curl_easy *data, struct tunnel_stream *tunnel) { + struct cf_h2_proxy_ctx *ctx = cf->ctx; unsigned char bits; (void)cf; bits = CURL_CSELECT_IN; - if(!tunnel->closed && !tunnel->reset && tunnel->upload_blocked_len) + if(!tunnel->closed && !tunnel->reset && + !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) bits |= CURL_CSELECT_OUT; if(data->state.select_bits != bits) { CURL_TRC_CF(data, cf, "[%d] DRAIN select_bits=%x", @@ -260,7 +261,7 @@ static ssize_t proxy_h2_nw_out_writer(void *writer_ctx, if(cf) { struct Curl_easy *data = CF_DATA_CURRENT(cf); nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, - err); + FALSE, err); CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %zd, %d", buflen, nwritten, *err); } @@ -1079,7 +1080,7 @@ static CURLcode H2_CONNECT(struct Curl_cfilter *cf, } while(ts->state == H2_TUNNEL_INIT); out: - if(result || ctx->tunnel.closed) + if((result && (result != CURLE_AGAIN)) || ctx->tunnel.closed) h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data); return result; } @@ -1185,7 +1186,8 @@ static CURLcode cf_h2_proxy_shutdown(struct Curl_cfilter *cf, if(!ctx->sent_goaway) { rv = nghttp2_submit_goaway(ctx->h2, NGHTTP2_FLAG_NONE, 0, 0, - (const uint8_t *)"shutown", sizeof("shutown")); + (const uint8_t *)"shutdown", + sizeof("shutdown")); if(rv) { failf(data, "nghttp2_submit_goaway() failed: %s(%d)", nghttp2_strerror(rv), rv); @@ -1231,7 +1233,9 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, bool want_recv, want_send; if(!cf->connected && ctx->h2) { - want_send = nghttp2_session_want_write(ctx->h2); + want_send = nghttp2_session_want_write(ctx->h2) || + !Curl_bufq_is_empty(&ctx->outbufq) || + !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); want_recv = nghttp2_session_want_read(ctx->h2); } else @@ -1247,17 +1251,25 @@ static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, ctx->h2, ctx->tunnel.stream_id); want_recv = (want_recv || c_exhaust || s_exhaust); want_send = (!s_exhaust && want_send) || - (!c_exhaust && nghttp2_session_want_write(ctx->h2)); + (!c_exhaust && nghttp2_session_want_write(ctx->h2)) || + !Curl_bufq_is_empty(&ctx->outbufq) || + !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); Curl_pollset_set(data, ps, sock, want_recv, want_send); + CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d", + want_recv, want_send); CF_DATA_RESTORE(cf, save); } else if(ctx->sent_goaway && !cf->shutdown) { /* shutdown in progress */ CF_DATA_SAVE(save, cf, data); - want_send = nghttp2_session_want_write(ctx->h2); + want_send = nghttp2_session_want_write(ctx->h2) || + !Curl_bufq_is_empty(&ctx->outbufq) || + !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); want_recv = nghttp2_session_want_read(ctx->h2); Curl_pollset_set(data, ps, sock, want_recv, want_send); + CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d", + want_recv, want_send); CF_DATA_RESTORE(cf, save); } } @@ -1364,16 +1376,7 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf, } result = proxy_h2_progress_egress(cf, data); - if(result == CURLE_AGAIN) { - /* pending data to send, need to be called again. Ideally, we would - * monitor the socket for POLLOUT, but we might not be in SENDING - * transfer state any longer and are unable to make this happen. - */ - CURL_TRC_CF(data, cf, "[%d] egress blocked, DRAIN", - ctx->tunnel.stream_id); - drain_tunnel(cf, data, &ctx->tunnel); - } - else if(result) { + if(result && (result != CURLE_AGAIN)) { *err = result; nread = -1; } @@ -1393,15 +1396,16 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf, static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_h2_proxy_ctx *ctx = cf->ctx; struct cf_call_data save; int rv; ssize_t nwritten; CURLcode result; - int blocked = 0; + (void)eos; /* TODO, maybe useful for blocks? */ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { *err = CURLE_SEND_ERROR; return -1; @@ -1413,29 +1417,10 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, *err = CURLE_SEND_ERROR; goto out; } - else if(ctx->tunnel.upload_blocked_len) { - /* the data in `buf` has already been submitted or added to the - * buffers, but have been EAGAINed on the last invocation. */ - DEBUGASSERT(len >= ctx->tunnel.upload_blocked_len); - if(len < ctx->tunnel.upload_blocked_len) { - /* Did we get called again with a smaller `len`? This should not - * happen. We are not prepared to handle that. */ - failf(data, "HTTP/2 proxy, send again with decreased length"); - *err = CURLE_HTTP2; - nwritten = -1; - goto out; - } - nwritten = (ssize_t)ctx->tunnel.upload_blocked_len; - ctx->tunnel.upload_blocked_len = 0; - *err = CURLE_OK; - } else { nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err); - if(nwritten < 0) { - if(*err != CURLE_AGAIN) - goto out; - nwritten = 0; - } + if(nwritten < 0 && (*err != CURLE_AGAIN)) + goto out; } if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { @@ -1458,52 +1443,13 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, /* Call the nghttp2 send loop and flush to write ALL buffered data, * headers and/or request body completely out to the network */ result = proxy_h2_progress_egress(cf, data); - if(result == CURLE_AGAIN) { - blocked = 1; - } - else if(result) { + if(result && (result != CURLE_AGAIN)) { *err = result; nwritten = -1; goto out; } - else if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { - /* although we wrote everything that nghttp2 wants to send now, - * there is data left in our stream send buffer unwritten. This may - * be due to the stream's HTTP/2 flow window being exhausted. */ - blocked = 1; - } - - if(blocked) { - /* Unable to send all data, due to connection blocked or H2 window - * exhaustion. Data is left in our stream buffer, or nghttp2's internal - * frame buffer or our network out buffer. */ - size_t rwin = (size_t)nghttp2_session_get_stream_remote_window_size( - ctx->h2, ctx->tunnel.stream_id); - if(rwin == 0) { - /* H2 flow window exhaustion. - * FIXME: there is no way to HOLD all transfers that use this - * proxy connection AND to UNHOLD all of them again when the - * window increases. - * We *could* iterate over all data on this conn maybe? */ - CURL_TRC_CF(data, cf, "[%d] remote flow " - "window is exhausted", ctx->tunnel.stream_id); - } - /* Whatever the cause, we need to return CURL_EAGAIN for this call. - * We have unwritten state that needs us being invoked again and EAGAIN - * is the only way to ensure that. */ - ctx->tunnel.upload_blocked_len = nwritten; - CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) BLOCK: win %u/%zu " - "blocked_len=%zu", - ctx->tunnel.stream_id, len, - nghttp2_session_get_remote_window_size(ctx->h2), rwin, - nwritten); - drain_tunnel(cf, data, &ctx->tunnel); - *err = CURLE_AGAIN; - nwritten = -1; - goto out; - } - else if(proxy_h2_should_close_session(ctx)) { + if(proxy_h2_should_close_session(ctx)) { /* nghttp2 thinks this session is done. If the stream has not been * closed, this is an error state for out transfer */ if(ctx->tunnel.closed) { @@ -1536,6 +1482,38 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, return nwritten; } +static CURLcode cf_h2_proxy_flush(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_h2_proxy_ctx *ctx = cf->ctx; + struct cf_call_data save; + CURLcode result = CURLE_OK; + + CF_DATA_SAVE(save, cf, data); + if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { + /* resume the potentially suspended tunnel */ + int rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id); + if(nghttp2_is_fatal(rv)) { + result = CURLE_SEND_ERROR; + goto out; + } + } + + result = proxy_h2_progress_egress(cf, data); + +out: + CURL_TRC_CF(data, cf, "[%d] flush -> %d, " + "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)", + ctx->tunnel.stream_id, result, + nghttp2_session_get_stream_remote_window_size( + ctx->h2, ctx->tunnel.stream_id), + nghttp2_session_get_remote_window_size(ctx->h2), + Curl_bufq_len(&ctx->tunnel.sendbuf), + Curl_bufq_len(&ctx->outbufq)); + CF_DATA_RESTORE(cf, save); + return result; +} + static bool proxy_h2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data, bool *input_pending) @@ -1589,6 +1567,52 @@ static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf, return result; } +static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf, + struct Curl_easy *data, + int query, int *pres1, void *pres2) +{ + struct cf_h2_proxy_ctx *ctx = cf->ctx; + + switch(query) { + case CF_QUERY_NEED_FLUSH: { + if(!Curl_bufq_is_empty(&ctx->outbufq) || + !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { + CURL_TRC_CF(data, cf, "needs flush"); + *pres1 = TRUE; + return CURLE_OK; + } + break; + } + default: + break; + } + return cf->next? + cf->next->cft->query(cf->next, data, query, pres1, pres2) : + CURLE_UNKNOWN_OPTION; +} + +static CURLcode cf_h2_proxy_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) +{ + CURLcode result = CURLE_OK; + struct cf_call_data save; + + (void)arg1; + (void)arg2; + + switch(event) { + case CF_CTRL_FLUSH: + CF_DATA_SAVE(save, cf, data); + result = cf_h2_proxy_flush(cf, data); + CF_DATA_RESTORE(cf, save); + break; + default: + break; + } + return result; +} + struct Curl_cftype Curl_cft_h2_proxy = { "H2-PROXY", CF_TYPE_IP_CONNECT|CF_TYPE_PROXY, @@ -1602,10 +1626,10 @@ struct Curl_cftype Curl_cft_h2_proxy = { cf_h2_proxy_data_pending, cf_h2_proxy_send, cf_h2_proxy_recv, - Curl_cf_def_cntrl, + cf_h2_proxy_cntrl, cf_h2_proxy_is_alive, Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, + cf_h2_proxy_query, }; CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, diff --git a/lib/cf-haproxy.c b/lib/cf-haproxy.c index 200c13958..0fc7625c4 100644 --- a/lib/cf-haproxy.c +++ b/lib/cf-haproxy.c @@ -70,8 +70,9 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf, { struct cf_haproxy_ctx *ctx = cf->ctx; CURLcode result; - const char *tcp_version; const char *client_ip; + struct ip_quadruple ipquad; + int is_ipv6; DEBUGASSERT(ctx); DEBUGASSERT(ctx->state == HAPROXY_INIT); @@ -81,19 +82,20 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf, result = Curl_dyn_addn(&ctx->data_out, STRCONST("PROXY UNKNOWN\r\n")); else { #endif /* USE_UNIX_SOCKETS */ + result = Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad); + if(result) + return result; + /* Emit the correct prefix for IPv6 */ - tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4"; if(data->set.str[STRING_HAPROXY_CLIENT_IP]) client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP]; else - client_ip = data->info.primary.local_ip; + client_ip = ipquad.local_ip; result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n", - tcp_version, - client_ip, - data->info.primary.remote_ip, - data->info.primary.local_port, - data->info.primary.remote_port); + is_ipv6? "TCP6" : "TCP4", + client_ip, ipquad.remote_ip, + ipquad.local_port, ipquad.remote_port); #ifdef USE_UNIX_SOCKETS } @@ -129,17 +131,17 @@ static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf, case HAPROXY_SEND: len = Curl_dyn_len(&ctx->data_out); if(len > 0) { - size_t written; - result = Curl_conn_send(data, cf->sockindex, - Curl_dyn_ptr(&ctx->data_out), - len, &written); - if(result == CURLE_AGAIN) { + ssize_t nwritten; + nwritten = Curl_conn_cf_send(cf->next, data, + Curl_dyn_ptr(&ctx->data_out), len, FALSE, + &result); + if(nwritten < 0) { + if(result != CURLE_AGAIN) + goto out; result = CURLE_OK; - written = 0; + nwritten = 0; } - else if(result) - goto out; - Curl_dyn_tail(&ctx->data_out, len - written); + Curl_dyn_tail(&ctx->data_out, len - (size_t)nwritten); if(Curl_dyn_len(&ctx->data_out) > 0) { result = CURLE_OK; goto out; diff --git a/lib/cf-https-connect.c b/lib/cf-https-connect.c index 7a6bd97e1..facb3da27 100644 --- a/lib/cf-https-connect.c +++ b/lib/cf-https-connect.c @@ -96,6 +96,21 @@ static bool cf_hc_baller_data_pending(struct cf_hc_baller *b, return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data); } +static bool cf_hc_baller_needs_flush(struct cf_hc_baller *b, + struct Curl_easy *data) +{ + return b->cf && !b->result && Curl_conn_cf_needs_flush(b->cf, data); +} + +static CURLcode cf_hc_baller_cntrl(struct cf_hc_baller *b, + struct Curl_easy *data, + int event, int arg1, void *arg2) +{ + if(b->cf && !b->result) + return Curl_conn_cf_cntrl(b->cf, data, FALSE, event, arg1, arg2); + return CURLE_OK; +} + struct cf_hc_ctx { cf_hc_state state; const struct Curl_dns_entry *remotehost; @@ -195,8 +210,6 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, } ctx->state = CF_HC_SUCCESS; cf->connected = TRUE; - Curl_conn_cf_cntrl(cf->next, data, TRUE, - CF_CTRL_CONN_INFO_UPDATE, 0, NULL); return result; } @@ -428,6 +441,8 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf, struct Curl_easy *data, int query, int *pres1, void *pres2) { + struct cf_hc_ctx *ctx = cf->ctx; + if(!cf->connected) { switch(query) { case CF_QUERY_TIMER_CONNECT: { @@ -440,6 +455,14 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf, *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT); return CURLE_OK; } + case CF_QUERY_NEED_FLUSH: { + if(cf_hc_baller_needs_flush(&ctx->h3_baller, data) + || cf_hc_baller_needs_flush(&ctx->h21_baller, data)) { + *pres1 = TRUE; + return CURLE_OK; + } + break; + } default: break; } @@ -449,6 +472,23 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf, CURLE_UNKNOWN_OPTION; } +static CURLcode cf_hc_cntrl(struct Curl_cfilter *cf, + struct Curl_easy *data, + int event, int arg1, void *arg2) +{ + struct cf_hc_ctx *ctx = cf->ctx; + CURLcode result = CURLE_OK; + + if(!cf->connected) { + result = cf_hc_baller_cntrl(&ctx->h3_baller, data, event, arg1, arg2); + if(!result || (result == CURLE_AGAIN)) + result = cf_hc_baller_cntrl(&ctx->h21_baller, data, event, arg1, arg2); + if(result == CURLE_AGAIN) + result = CURLE_OK; + } + return result; +} + static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data) { CURL_TRC_CF(data, cf, "close"); @@ -484,7 +524,7 @@ struct Curl_cftype Curl_cft_http_connect = { cf_hc_data_pending, Curl_cf_def_send, Curl_cf_def_recv, - Curl_cf_def_cntrl, + cf_hc_cntrl, Curl_cf_def_conn_is_alive, Curl_cf_def_conn_keep_alive, cf_hc_query, diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 2e92db29d..729e38f88 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -124,7 +124,7 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) } #ifdef SO_NOSIGPIPE -/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when +/* The preferred method on macOS (10.2 and later) to prevent SIGPIPEs when sending data to a dead peer (instead of relying on the 4th argument to send being MSG_NOSIGNAL). Possibly also existing and in use on other BSD systems? */ @@ -146,7 +146,13 @@ static void nosigpipe(struct Curl_easy *data, #define nosigpipe(x,y) Curl_nop_stmt #endif -#if defined(USE_WINSOCK) || \ +#if defined(USE_WINSOCK) && \ + defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) +/* Win 10, v 1709 (10.0.16299) and later can use SetSockOpt TCP_KEEP____ + * so should use seconds */ +#define CURL_WINSOCK_KEEP_SSO +#define KEEPALIVE_FACTOR(x) +#elif defined(USE_WINSOCK) || \ (defined(__sun) && !defined(TCP_KEEPIDLE)) || \ (defined(__DragonFly__) && __DragonFly_version < 500702) || \ (defined(_WIN32) && !defined(TCP_KEEPIDLE)) @@ -177,19 +183,19 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set SO_KEEPALIVE on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } else { #if defined(SIO_KEEPALIVE_VALS) /* Windows */ /* Windows 10, version 1709 (10.0.16299) and later versions */ -#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) +#if defined(CURL_WINSOCK_KEEP_SSO) optval = curlx_sltosi(data->set.tcp_keepidle); KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (const char *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPIDLE on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } optval = curlx_sltosi(data->set.tcp_keepintvl); @@ -197,14 +203,14 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, (const char *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPINTVL on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } optval = curlx_sltosi(data->set.tcp_keepcnt); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, (const char *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPCNT on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #else /* Windows < 10.0.16299 */ @@ -220,8 +226,7 @@ tcpkeepalive(struct Curl_easy *data, if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals), NULL, 0, &dummy, NULL, NULL) != 0) { infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", - sockfd, SOCKERRNO); + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #endif #else /* !Windows */ @@ -231,17 +236,17 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPIDLE on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #elif defined(TCP_KEEPALIVE) - /* Mac OS X style */ + /* macOS style */ optval = curlx_sltosi(data->set.tcp_keepidle); KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPALIVE on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #elif defined(TCP_KEEPALIVE_THRESHOLD) @@ -251,7 +256,7 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPALIVE_THRESHOLD on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #endif @@ -261,7 +266,7 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPINTVL on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #elif defined(TCP_KEEPALIVE_ABORT_THRESHOLD) @@ -282,8 +287,7 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPALIVE_ABORT_THRESHOLD on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", - sockfd, SOCKERRNO); + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #endif #ifdef TCP_KEEPCNT @@ -291,8 +295,7 @@ tcpkeepalive(struct Curl_easy *data, if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&optval, sizeof(optval)) < 0) { infof(data, "Failed to set TCP_KEEPCNT on fd " - "%" CURL_FORMAT_SOCKET_T ": errno %d", - sockfd, SOCKERRNO); + "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); } #endif #endif @@ -404,6 +407,9 @@ CURLcode Curl_socket_open(struct Curl_easy *data, static int socket_close(struct Curl_easy *data, struct connectdata *conn, int use_callback, curl_socket_t sock) { + if(CURL_SOCKET_BAD == sock) + return 0; + if(use_callback && conn && conn->fclosesocket) { int rc; Curl_multi_closed(data, sock); @@ -502,32 +508,37 @@ void Curl_sndbuf_init(curl_socket_t sockfd) * * Returns CURLE_OK on success. */ -CURLcode Curl_parse_interface(const char *input, size_t len, +CURLcode Curl_parse_interface(const char *input, char **dev, char **iface, char **host) { static const char if_prefix[] = "if!"; static const char host_prefix[] = "host!"; static const char if_host_prefix[] = "ifhost!"; + size_t len; DEBUGASSERT(dev); DEBUGASSERT(iface); DEBUGASSERT(host); - if(strncmp(if_prefix, input, strlen(if_prefix)) == 0) { + len = strlen(input); + if(len > 512) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(!strncmp(if_prefix, input, strlen(if_prefix))) { input += strlen(if_prefix); if(!*input) return CURLE_BAD_FUNCTION_ARGUMENT; *iface = Curl_memdup0(input, len - strlen(if_prefix)); return *iface ? CURLE_OK : CURLE_OUT_OF_MEMORY; } - if(strncmp(host_prefix, input, strlen(host_prefix)) == 0) { + else if(!strncmp(host_prefix, input, strlen(host_prefix))) { input += strlen(host_prefix); if(!*input) return CURLE_BAD_FUNCTION_ARGUMENT; *host = Curl_memdup0(input, len - strlen(host_prefix)); return *host ? CURLE_OK : CURLE_OUT_OF_MEMORY; } - if(strncmp(if_host_prefix, input, strlen(if_host_prefix)) == 0) { + else if(!strncmp(if_host_prefix, input, strlen(if_host_prefix))) { const char *host_part; input += strlen(if_host_prefix); len -= strlen(if_host_prefix); @@ -679,12 +690,13 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, conn->ip_version = ipver; if(h) { + int h_af = h->addr->ai_family; /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ Curl_printable_address(h->addr, myhost, sizeof(myhost)); infof(data, "Name '%s' family %i resolved to '%s' family %i", - host, af, myhost, h->addr->ai_family); - Curl_resolv_unlock(data, h); - if(af != h->addr->ai_family) { + host, af, myhost, h_af); + Curl_resolv_unlink(data, &h); /* this will NULL, potential free h */ + if(af != h_af) { /* bad IP version combo, signal the caller to try another address family if available */ return CURLE_UNSUPPORTED_PROTOCOL; @@ -694,7 +706,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, else { /* * provided dev was no interface (or interfaces are not supported - * e.g. solaris) no ip address and no domain we fail here + * e.g. Solaris) no ip address and no domain we fail here */ done = -1; } @@ -843,7 +855,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) err = SOCKERRNO; #ifdef _WIN32_WCE - /* Old WinCE versions do not support SO_ERROR */ + /* Old Windows CE versions do not support SO_ERROR */ if(WSAENOPROTOOPT == err) { SET_SOCKERRNO(0); err = 0; @@ -938,6 +950,7 @@ struct cf_socket_ctx { size_t recv_max; /* max enforced read size */ #endif BIT(got_first_byte); /* if first byte was received */ + BIT(listening); /* socket is listening */ BIT(accepted); /* socket was accepted, not connected */ BIT(sock_connected); /* socket is "connected", e.g. in UDP */ BIT(active); @@ -986,8 +999,7 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data) struct cf_socket_ctx *ctx = cf->ctx; if(ctx && CURL_SOCKET_BAD != ctx->sock) { - CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T - ")", ctx->sock); + CURL_TRC_CF(data, cf, "cf_socket_close(%" FMT_SOCKET_T ")", ctx->sock); if(ctx->sock == cf->conn->sock[cf->sockindex]) cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD; socket_close(data, cf->conn, !ctx->accepted, ctx->sock); @@ -1009,8 +1021,7 @@ static CURLcode cf_socket_shutdown(struct Curl_cfilter *cf, if(cf->connected) { struct cf_socket_ctx *ctx = cf->ctx; - CURL_TRC_CF(data, cf, "cf_socket_shutdown(%" CURL_FORMAT_SOCKET_T - ")", ctx->sock); + CURL_TRC_CF(data, cf, "cf_socket_shutdown(%" FMT_SOCKET_T ")", ctx->sock); /* On TCP, and when the socket looks well and non-blocking mode * can be enabled, receive dangling bytes before close to avoid * entering RST states unnecessarily. */ @@ -1220,7 +1231,7 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf, ctx->connected_at = Curl_now(); cf->connected = TRUE; } - CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" CURL_FORMAT_SOCKET_T, + CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" FMT_SOCKET_T, result, ctx->sock); return result; } @@ -1262,8 +1273,8 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data, #elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */ if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, (void *)&optval, sizeof(optval)) < 0) - infof(data, "Failed to enable TCP Fast Open on fd %" - CURL_FORMAT_SOCKET_T, ctx->sock); + infof(data, "Failed to enable TCP Fast Open on fd %" FMT_SOCKET_T, + ctx->sock); rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen); #elif defined(MSG_FASTOPEN) /* old Linux */ @@ -1398,15 +1409,24 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, struct cf_socket_ctx *ctx = cf->ctx; if(ctx->sock != CURL_SOCKET_BAD) { - if(!cf->connected) { + /* A listening socket filter needs to be connected before the accept + * for some weird FTP interaction. This should be rewritten, so that + * FTP no longer does the socket checks and accept calls and delegates + * all that to the filter. TODO. */ + if(ctx->listening) { + Curl_pollset_set_in_only(data, ps, ctx->sock); + CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%" + FMT_SOCKET_T, ctx->sock); + } + else if(!cf->connected) { Curl_pollset_set_out_only(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%" - CURL_FORMAT_SOCKET_T, ctx->sock); + FMT_SOCKET_T, ctx->sock); } else if(!ctx->active) { Curl_pollset_add_in(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%" - CURL_FORMAT_SOCKET_T, ctx->sock); + FMT_SOCKET_T, ctx->sock); } } } @@ -1449,13 +1469,15 @@ static void win_update_sndbuf_size(struct cf_socket_ctx *ctx) #endif /* USE_WINSOCK */ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_socket_ctx *ctx = cf->ctx; curl_socket_t fdsave; ssize_t nwritten; size_t orig_len = len; + (void)eos; /* unused */ *err = CURLE_OK; fdsave = cf->conn->sock[cf->sockindex]; cf->conn->sock[cf->sockindex] = ctx->sock; @@ -1464,7 +1486,7 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* simulate network blocking/partial writes */ if(ctx->wblock_percent > 0) { unsigned char c = 0; - Curl_rand(data, &c, 1); + Curl_rand_bytes(data, FALSE, &c, 1); if(c >= ((100-ctx->wblock_percent)*256/100)) { CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE EWOULDBLOCK", orig_len); *err = CURLE_AGAIN; @@ -1597,6 +1619,18 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, return nread; } +static void cf_socket_update_data(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + /* Update the IP info held in the transfer, if we have that. */ + if(cf->connected && (cf->sockindex == FIRSTSOCKET)) { + struct cf_socket_ctx *ctx = cf->ctx; + data->info.primary = ctx->ip; + /* not sure if this is redundant... */ + data->info.conn_remote_port = cf->conn->remote_port; + } +} + static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_socket_ctx *ctx = cf->ctx; @@ -1604,17 +1638,15 @@ static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data) /* use this socket from now on */ cf->conn->sock[cf->sockindex] = ctx->sock; set_local_ip(cf, data); - if(cf->sockindex == SECONDARYSOCKET) - cf->conn->secondary = ctx->ip; - else - cf->conn->primary = ctx->ip; - /* the first socket info gets some specials */ if(cf->sockindex == FIRSTSOCKET) { + cf->conn->primary = ctx->ip; cf->conn->remote_addr = &ctx->addr; #ifdef USE_IPV6 cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6)? TRUE : FALSE; #endif - Curl_persistconninfo(data, cf->conn, &ctx->ip); + } + else { + cf->conn->secondary = ctx->ip; } ctx->active = TRUE; } @@ -1630,9 +1662,10 @@ static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf, switch(event) { case CF_CTRL_CONN_INFO_UPDATE: cf_socket_active(cf, data); + cf_socket_update_data(cf, data); break; case CF_CTRL_DATA_SETUP: - Curl_persistconninfo(data, cf->conn, &ctx->ip); + cf_socket_update_data(cf, data); break; case CF_CTRL_FORGET_SOCKET: ctx->sock = CURL_SOCKET_BAD; @@ -1715,6 +1748,10 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf, } return CURLE_OK; } + case CF_QUERY_IP_INFO: + *pres1 = (ctx->addr.family == AF_INET6)? TRUE : FALSE; + *(struct ip_quadruple *)pres2 = ctx->ip; + return CURLE_OK; default: break; } @@ -1793,7 +1830,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, } ctx->sock_connected = TRUE; set_local_ip(cf, data); - CURL_TRC_CF(data, cf, "%s socket %" CURL_FORMAT_SOCKET_T + CURL_TRC_CF(data, cf, "%s socket %" FMT_SOCKET_T " connected: [%s:%d] -> [%s:%d]", (ctx->transport == TRNSPRT_QUIC)? "QUIC" : "UDP", ctx->sock, ctx->ip.local_ip, ctx->ip.local_port, @@ -1858,12 +1895,12 @@ static CURLcode cf_udp_connect(struct Curl_cfilter *cf, if(result) goto out; CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%" - CURL_FORMAT_SOCKET_T " (%s:%d)", + FMT_SOCKET_T " (%s:%d)", ctx->sock, ctx->ip.local_ip, ctx->ip.local_port); } else { CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%" - CURL_FORMAT_SOCKET_T " (unconnected)", ctx->sock); + FMT_SOCKET_T " (unconnected)", ctx->sock); } *done = TRUE; cf->connected = TRUE; @@ -2027,6 +2064,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, } ctx->transport = conn->transport; ctx->sock = *s; + ctx->listening = TRUE; ctx->accepted = FALSE; result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx); if(result) @@ -2038,8 +2076,8 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, ctx->active = TRUE; ctx->connected_at = Curl_now(); cf->connected = TRUE; - CURL_TRC_CF(data, cf, "Curl_conn_tcp_listen_set(%" - CURL_FORMAT_SOCKET_T ")", ctx->sock); + CURL_TRC_CF(data, cf, "Curl_conn_tcp_listen_set(%" FMT_SOCKET_T ")", + ctx->sock); out: if(result) { @@ -2093,8 +2131,10 @@ CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data, return CURLE_FAILED_INIT; ctx = cf->ctx; + DEBUGASSERT(ctx->listening); /* discard the listen socket */ socket_close(data, conn, TRUE, ctx->sock); + ctx->listening = FALSE; ctx->sock = *s; conn->sock[sockindex] = ctx->sock; set_accepted_remote_ip(cf, data); @@ -2103,7 +2143,7 @@ CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data, ctx->accepted = TRUE; ctx->connected_at = Curl_now(); cf->connected = TRUE; - CURL_TRC_CF(data, cf, "accepted_set(sock=%" CURL_FORMAT_SOCKET_T + CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T ", remote=%s port=%d)", ctx->sock, ctx->ip.remote_ip, ctx->ip.remote_port); diff --git a/lib/cf-socket.h b/lib/cf-socket.h index 6040058b0..35225f153 100644 --- a/lib/cf-socket.h +++ b/lib/cf-socket.h @@ -57,7 +57,7 @@ struct Curl_sockaddr_ex { /* * Parse interface option, and return the interface name and the host part. */ -CURLcode Curl_parse_interface(const char *input, size_t len, +CURLcode Curl_parse_interface(const char *input, char **dev, char **iface, char **host); /* diff --git a/lib/cfilters.c b/lib/cfilters.c index 9a5c3578d..bed59f9fb 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -45,6 +45,9 @@ #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) #endif +static void cf_cntrl_update_info(struct Curl_easy *data, + struct connectdata *conn); + #ifdef UNITTESTS /* used by unit2600.c */ void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data) @@ -98,10 +101,11 @@ bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, } ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { return cf->next? - cf->next->cft->do_send(cf->next, data, buf, len, err) : + cf->next->cft->do_send(cf->next, data, buf, len, eos, err) : CURLE_RECV_ERROR; } @@ -256,7 +260,8 @@ ssize_t Curl_cf_recv(struct Curl_easy *data, int num, char *buf, } ssize_t Curl_cf_send(struct Curl_easy *data, int num, - const void *mem, size_t len, CURLcode *code) + const void *mem, size_t len, bool eos, + CURLcode *code) { struct Curl_cfilter *cf; @@ -268,7 +273,7 @@ ssize_t Curl_cf_send(struct Curl_easy *data, int num, cf = cf->next; } if(cf) { - ssize_t nwritten = cf->cft->do_send(cf, data, mem, len, code); + ssize_t nwritten = cf->cft->do_send(cf, data, mem, len, eos, code); DEBUGASSERT(nwritten >= 0 || *code); DEBUGASSERT(nwritten < 0 || !*code || !len); return nwritten; @@ -379,10 +384,11 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) } ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { if(cf) - return cf->cft->do_send(cf, data, buf, len, err); + return cf->cft->do_send(cf, data, buf, len, eos, err); *err = CURLE_SEND_ERROR; return -1; } @@ -416,9 +422,19 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, *done = cf->connected; if(!*done) { + if(Curl_conn_needs_flush(data, sockindex)) { + DEBUGF(infof(data, "Curl_conn_connect(index=%d), flush", sockindex)); + result = Curl_conn_flush(data, sockindex); + if(result && (result != CURLE_AGAIN)) + return result; + } + result = cf->cft->do_connect(cf, data, blocking, done); if(!result && *done) { - Curl_conn_ev_update_info(data, data->conn); + /* Now that the complete filter chain is connected, let all filters + * persist information at the connection. E.g. cf-socket sets the + * socket and ip related information. */ + cf_cntrl_update_info(data, data->conn); conn_report_connect_stats(data, data->conn); data->conn->keepalive = Curl_now(); } @@ -501,6 +517,21 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) return FALSE; } +bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + CURLcode result; + int pending = FALSE; + result = cf? cf->cft->query(cf, data, CF_QUERY_NEED_FLUSH, + &pending, NULL) : CURLE_UNKNOWN_OPTION; + return (result || pending == FALSE)? FALSE : TRUE; +} + +bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex) +{ + return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data); +} + void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, struct easy_pollset *ps) @@ -627,6 +658,15 @@ curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, return CURL_SOCKET_BAD; } +CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, + struct Curl_easy *data, + int *is_ipv6, struct ip_quadruple *ipquad) +{ + if(cf) + return cf->cft->query(cf, data, CF_QUERY_IP_INFO, is_ipv6, ipquad); + return CURLE_UNKNOWN_OPTION; +} + curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex) { struct Curl_cfilter *cf; @@ -693,6 +733,13 @@ CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data) CF_CTRL_DATA_IDLE, 0, NULL); } + +CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex) +{ + return Curl_conn_cf_cntrl(data->conn->cfilter[sockindex], data, FALSE, + CF_CTRL_FLUSH, 0, NULL); +} + /** * Notify connection filters that the transfer represented by `data` * is done with sending data (e.g. has uploaded everything). @@ -717,8 +764,8 @@ CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause) CF_CTRL_DATA_PAUSE, do_pause, NULL); } -void Curl_conn_ev_update_info(struct Curl_easy *data, - struct connectdata *conn) +static void cf_cntrl_update_info(struct Curl_easy *data, + struct connectdata *conn) { cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL); } @@ -811,9 +858,10 @@ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, } CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t blen, + const void *buf, size_t blen, bool eos, size_t *pnwritten) { + size_t write_len = blen; ssize_t nwritten; CURLcode result = CURLE_OK; struct connectdata *conn; @@ -831,11 +879,14 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, if(p) { size_t altsize = (size_t)strtoul(p, NULL, 10); if(altsize) - blen = CURLMIN(blen, altsize); + write_len = CURLMIN(write_len, altsize); } } #endif - nwritten = conn->send[sockindex](data, sockindex, buf, blen, &result); + if(write_len != blen) + eos = FALSE; + nwritten = conn->send[sockindex](data, sockindex, buf, write_len, eos, + &result); DEBUGASSERT((nwritten >= 0) || result); *pnwritten = (nwritten < 0)? 0 : (size_t)nwritten; return result; diff --git a/lib/cfilters.h b/lib/cfilters.h index 7d53607f8..af696f52a 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -30,6 +30,7 @@ struct Curl_cfilter; struct Curl_easy; struct Curl_dns_entry; struct connectdata; +struct ip_quadruple; /* Callback to destroy resources held by this filter instance. * Implementations MUST NOT chain calls to cf->next. @@ -105,6 +106,7 @@ typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* transfer */ const void *buf, /* data to write */ size_t len, /* amount to write */ + bool eos, /* last chunk */ CURLcode *err); /* error to return */ typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf, @@ -140,6 +142,7 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf, /* update conn info at connection and data */ #define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */ #define CF_CTRL_FORGET_SOCKET (256+1) /* 0 NULL ignored */ +#define CF_CTRL_FLUSH (256+2) /* 0 NULL first fail */ /** * Handle event/control for the filter. @@ -162,6 +165,9 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf, * were received. * -1 if not determined yet. * - CF_QUERY_SOCKET: the socket used by the filter chain + * - CF_QUERY_NEED_FLUSH: TRUE iff any of the filters have unsent data + * - CF_QUERY_IP_INFO: res1 says if connection used IPv6, res2 is the + * ip quadruple */ /* query res1 res2 */ #define CF_QUERY_MAX_CONCURRENT 1 /* number - */ @@ -170,6 +176,8 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf, #define CF_QUERY_TIMER_CONNECT 4 /* - struct curltime */ #define CF_QUERY_TIMER_APPCONNECT 5 /* - struct curltime */ #define CF_QUERY_STREAM_ERROR 6 /* error code - */ +#define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */ +#define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */ /** * Query the cfilter for properties. Filters ignorant of a query will @@ -241,7 +249,8 @@ void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data); ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err); + const void *buf, size_t len, bool eos, + CURLcode *err); ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data, char *buf, size_t len, CURLcode *err); CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf, @@ -317,7 +326,8 @@ CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf, bool blocking, bool *done); void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data); ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err); + const void *buf, size_t len, bool eos, + CURLcode *err); ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, char *buf, size_t len, CURLcode *err); CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf, @@ -338,6 +348,12 @@ bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf); curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, struct Curl_easy *data); +CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, + struct Curl_easy *data, + int *is_ipv6, struct ip_quadruple *ipquad); + +bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, + struct Curl_easy *data); #define CURL_CF_SSL_DEFAULT -1 #define CURL_CF_SSL_DISABLE 0 @@ -398,6 +414,17 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done); bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex); +/** + * Return TRUE if any of the connection filters at chain `sockindex` + * have data still to send. + */ +bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex); + +/** + * Flush any pending data on the connection filters at chain `sockindex`. + */ +CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex); + /** * Return the socket used on data's connection for the index. * Returns CURL_SOCKET_BAD if not available. @@ -447,7 +474,7 @@ ssize_t Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf, * The error code is placed into `*code`. */ ssize_t Curl_cf_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, CURLcode *code); + const void *buf, size_t len, bool eos, CURLcode *code); /** * The easy handle `data` is being attached to `conn`. This does @@ -496,12 +523,6 @@ void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature); */ CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause); -/** - * Inform connection filters to update their info in `conn`. - */ -void Curl_conn_ev_update_info(struct Curl_easy *data, - struct connectdata *conn); - /** * Check if FIRSTSOCKET's cfilter chain deems connection alive. */ @@ -557,7 +578,7 @@ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, * Will return CURLE_AGAIN iff blocked on sending. */ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t blen, + const void *buf, size_t blen, bool eos, size_t *pnwritten); diff --git a/lib/config-mac.h b/lib/config-mac.h index c29888f8f..53df87cbb 100644 --- a/lib/config-mac.h +++ b/lib/config-mac.h @@ -27,7 +27,7 @@ /* =================================================================== */ /* Hand crafted config file for Mac OS 9 */ /* =================================================================== */ -/* On Mac OS X you must run configure to generate curl_config.h file */ +/* On macOS you must run configure to generate curl_config.h file */ /* =================================================================== */ #ifndef OS diff --git a/lib/config-os400.h b/lib/config-os400.h index ec83be923..29aa818fb 100644 --- a/lib/config-os400.h +++ b/lib/config-os400.h @@ -65,9 +65,6 @@ /* Define this to 'int' if ssize_t is not an available typedefed type */ #undef ssize_t -/* Define this as a suitable file to read random data from */ -#undef RANDOM_FILE - /* Define to 1 if you have the alarm function. */ #define HAVE_ALARM 1 @@ -232,7 +229,7 @@ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS -/* Define to enable HTTP3 support (experimental, requires NGTCP2, QUICHE or +/* Define to enable HTTP3 support (experimental, requires NGTCP2, quiche or MSH3) */ #undef USE_HTTP3 diff --git a/lib/config-plan9.h b/lib/config-plan9.h index 6f3a15a5e..e56aca15c 100644 --- a/lib/config-plan9.h +++ b/lib/config-plan9.h @@ -41,7 +41,6 @@ #define PACKAGE_STRING "curl -" #define PACKAGE_TARNAME "curl" #define PACKAGE_VERSION "-" -#define RANDOM_FILE "/dev/random" #define VERSION "0.0.0" /* TODO */ #define STDC_HEADERS 1 diff --git a/lib/config-riscos.h b/lib/config-riscos.h index 056f55405..580e822e5 100644 --- a/lib/config-riscos.h +++ b/lib/config-riscos.h @@ -63,9 +63,6 @@ /* Define this to 'int' if ssize_t is not an available typedefed type */ #undef ssize_t -/* Define this as a suitable file to read random data from */ -#undef RANDOM_FILE - /* Define if you have the alarm function. */ #define HAVE_ALARM @@ -204,13 +201,6 @@ /* Version number of package */ #undef VERSION -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS diff --git a/lib/config-win32ce.h b/lib/config-win32ce.h index ae3ca290c..800fc61cf 100644 --- a/lib/config-win32ce.h +++ b/lib/config-win32ce.h @@ -25,7 +25,7 @@ ***************************************************************************/ /* ================================================================ */ -/* lib/config-win32ce.h - Hand crafted config file for windows ce */ +/* lib/config-win32ce.h - Hand crafted config file for Windows CE */ /* ================================================================ */ /* ---------------------------------------------------------------- */ @@ -279,7 +279,7 @@ #define PACKAGE "curl" /* ---------------------------------------------------------------- */ -/* WinCE */ +/* Windows CE */ /* ---------------------------------------------------------------- */ #ifndef UNICODE diff --git a/lib/conncache.c b/lib/conncache.c index 92fd60c4d..8f477827c 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -47,194 +47,242 @@ #include "curl_memory.h" #include "memdebug.h" -#define HASHKEY_SIZE 128 -static void connc_discard_conn(struct conncache *connc, - struct Curl_easy *last_data, +#define CPOOL_IS_LOCKED(c) ((c) && (c)->locked) + +#define CPOOL_LOCK(c) \ + do { \ + if((c)) { \ + if(CURL_SHARE_KEEP_CONNECT((c)->share)) \ + Curl_share_lock(((c)->idata), CURL_LOCK_DATA_CONNECT, \ + CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(c)->locked); \ + (c)->locked = TRUE; \ + } \ + } while(0) + +#define CPOOL_UNLOCK(c) \ + do { \ + if((c)) { \ + DEBUGASSERT((c)->locked); \ + (c)->locked = FALSE; \ + if(CURL_SHARE_KEEP_CONNECT((c)->share)) \ + Curl_share_unlock((c)->idata, CURL_LOCK_DATA_CONNECT); \ + } \ + } while(0) + + +/* A list of connections to the same destinationn. */ +struct cpool_bundle { + struct Curl_llist conns; /* connections in the bundle */ + size_t dest_len; /* total length of destination, including NUL */ + char *dest[1]; /* destination of bundle, allocated to keep dest_len bytes */ +}; + + +static void cpool_discard_conn(struct cpool *cpool, + struct Curl_easy *data, struct connectdata *conn, bool aborted); -static void connc_disconnect(struct Curl_easy *data, - struct connectdata *conn, - struct conncache *connc, - bool do_shutdown); -static void connc_run_conn_shutdown(struct Curl_easy *data, +static void cpool_close_and_destroy(struct cpool *cpool, + struct connectdata *conn, + struct Curl_easy *data, + bool do_shutdown); +static void cpool_run_conn_shutdown(struct Curl_easy *data, struct connectdata *conn, bool *done); -static void connc_run_conn_shutdown_handler(struct Curl_easy *data, +static void cpool_run_conn_shutdown_handler(struct Curl_easy *data, struct connectdata *conn); -static CURLMcode connc_update_shutdown_ev(struct Curl_multi *multi, +static CURLMcode cpool_update_shutdown_ev(struct Curl_multi *multi, struct Curl_easy *data, struct connectdata *conn); -static void connc_shutdown_all(struct conncache *connc, int timeout_ms); +static void cpool_shutdown_all(struct cpool *cpool, + struct Curl_easy *data, int timeout_ms); +static void cpool_close_and_destroy_all(struct cpool *cpool); +static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool); -static CURLcode bundle_create(struct connectbundle **bundlep) +static struct cpool_bundle *cpool_bundle_create(const char *dest, + size_t dest_len) { - DEBUGASSERT(*bundlep == NULL); - *bundlep = malloc(sizeof(struct connectbundle)); - if(!*bundlep) - return CURLE_OUT_OF_MEMORY; - - (*bundlep)->num_connections = 0; - (*bundlep)->multiuse = BUNDLE_UNKNOWN; - - Curl_llist_init(&(*bundlep)->conn_list, NULL); - return CURLE_OK; + struct cpool_bundle *bundle; + bundle = calloc(1, sizeof(*bundle) + dest_len); + if(!bundle) + return NULL; + Curl_llist_init(&bundle->conns, NULL); + bundle->dest_len = dest_len; + memcpy(bundle->dest, dest, dest_len); + return bundle; } -static void bundle_destroy(struct connectbundle *bundle) +static void cpool_bundle_destroy(struct cpool_bundle *bundle) { + DEBUGASSERT(!Curl_llist_count(&bundle->conns)); free(bundle); } /* Add a connection to a bundle */ -static void bundle_add_conn(struct connectbundle *bundle, - struct connectdata *conn) +static void cpool_bundle_add(struct cpool_bundle *bundle, + struct connectdata *conn) { - Curl_llist_append(&bundle->conn_list, conn, &conn->bundle_node); - conn->bundle = bundle; - bundle->num_connections++; + DEBUGASSERT(!Curl_node_llist(&conn->cpool_node)); + Curl_llist_append(&bundle->conns, conn, &conn->cpool_node); + conn->bits.in_cpool = TRUE; } /* Remove a connection from a bundle */ -static int bundle_remove_conn(struct connectbundle *bundle, - struct connectdata *conn) +static void cpool_bundle_remove(struct cpool_bundle *bundle, + struct connectdata *conn) { - struct Curl_llist_element *curr; - - curr = bundle->conn_list.head; - while(curr) { - if(curr->ptr == conn) { - Curl_llist_remove(&bundle->conn_list, curr, NULL); - bundle->num_connections--; - conn->bundle = NULL; - return 1; /* we removed a handle */ - } - curr = curr->next; - } - DEBUGASSERT(0); - return 0; + (void)bundle; + DEBUGASSERT(Curl_node_llist(&conn->cpool_node) == &bundle->conns); + Curl_node_remove(&conn->cpool_node); + conn->bits.in_cpool = FALSE; } -static void free_bundle_hash_entry(void *freethis) +static void cpool_bundle_free_entry(void *freethis) { - struct connectbundle *b = (struct connectbundle *) freethis; - - bundle_destroy(b); + cpool_bundle_destroy((struct cpool_bundle *)freethis); } -int Curl_conncache_init(struct conncache *connc, - struct Curl_multi *multi, size_t size) +int Curl_cpool_init(struct cpool *cpool, + Curl_cpool_disconnect_cb *disconnect_cb, + struct Curl_multi *multi, + struct Curl_share *share, + size_t size) { + DEBUGASSERT(!!multi != !!share); /* either one */ + Curl_hash_init(&cpool->dest2bundle, size, Curl_hash_str, + Curl_str_key_compare, cpool_bundle_free_entry); + Curl_llist_init(&cpool->shutdowns, NULL); + + DEBUGASSERT(disconnect_cb); + if(!disconnect_cb) + return 1; + /* allocate a new easy handle to use when closing cached connections */ - connc->closure_handle = curl_easy_init(); - if(!connc->closure_handle) + cpool->idata = curl_easy_init(); + if(!cpool->idata) return 1; /* bad */ - connc->closure_handle->state.internal = true; + cpool->idata->state.internal = true; + /* TODO: this is quirky. We need an internal handle for certain + * operations, but we do not add it to the multi (if there is one). + * But we give it the multi so that socket event operations can work. + * Probably better to have an internal handle owned by the multi that + * can be used for cpool operations. */ + cpool->idata->multi = multi; #ifdef DEBUGBUILD if(getenv("CURL_DEBUG")) - connc->closure_handle->set.verbose = true; + cpool->idata->set.verbose = true; #endif - Curl_hash_init(&connc->hash, size, Curl_hash_str, - Curl_str_key_compare, free_bundle_hash_entry); - connc->closure_handle->state.conn_cache = connc; - connc->multi = multi; - Curl_llist_init(&connc->shutdowns.conn_list, NULL); + cpool->disconnect_cb = disconnect_cb; + cpool->idata->multi = cpool->multi = multi; + cpool->idata->share = cpool->share = share; return 0; /* good */ } -void Curl_conncache_destroy(struct conncache *connc) +void Curl_cpool_destroy(struct cpool *cpool) { - if(connc) { - Curl_hash_destroy(&connc->hash); - connc->multi = NULL; - DEBUGASSERT(!Curl_llist_count(&connc->shutdowns.conn_list)); + if(cpool) { + if(cpool->idata) { + cpool_close_and_destroy_all(cpool); + /* The internal closure handle is special and we need to + * disconnect it from multi/share before closing it down. */ + cpool->idata->multi = NULL; + cpool->idata->share = NULL; + Curl_close(&cpool->idata); + } + Curl_hash_destroy(&cpool->dest2bundle); + cpool->multi = NULL; } } -/* creates a key to find a bundle for this connection */ -static void hashkey(struct connectdata *conn, char *buf, size_t len) +static struct cpool *cpool_get_instance(struct Curl_easy *data) { - const char *hostname; - long port = conn->remote_port; - DEBUGASSERT(len >= HASHKEY_SIZE); -#ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - hostname = conn->http_proxy.host.name; - port = conn->primary.remote_port; + if(data) { + if(CURL_SHARE_KEEP_CONNECT(data->share)) + return &data->share->cpool; + else if(data->multi_easy) + return &data->multi_easy->cpool; + else if(data->multi) + return &data->multi->cpool; } - else -#endif - if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - - /* put the numbers first so that the hostname gets cut off if too long */ -#ifdef USE_IPV6 - msnprintf(buf, len, "%u/%ld/%s", conn->scope_id, port, hostname); -#else - msnprintf(buf, len, "%ld/%s", port, hostname); -#endif - Curl_strntolower(buf, buf, len); + return NULL; } -/* Returns number of connections currently held in the connection cache. - Locks/unlocks the cache itself! -*/ -size_t Curl_conncache_size(struct Curl_easy *data) +void Curl_cpool_xfer_init(struct Curl_easy *data) { - size_t num; - CONNCACHE_LOCK(data); - num = data->state.conn_cache->num_conn; - CONNCACHE_UNLOCK(data); - return num; + struct cpool *cpool = cpool_get_instance(data); + + DEBUGASSERT(cpool); + if(cpool) { + CPOOL_LOCK(cpool); + /* the identifier inside the connection cache */ + data->id = cpool->next_easy_id++; + if(cpool->next_easy_id <= 0) + cpool->next_easy_id = 0; + data->state.lastconnect_id = -1; + + /* The closure handle only ever has default timeouts set. To improve the + state somewhat we clone the timeouts from each added handle so that the + closure handle always has the same timeouts as the most recently added + easy handle. */ + cpool->idata->set.timeout = data->set.timeout; + cpool->idata->set.server_response_timeout = + data->set.server_response_timeout; + cpool->idata->set.no_signal = data->set.no_signal; + + CPOOL_UNLOCK(cpool); + } + else { + /* We should not get here, but in a non-debug build, do something */ + data->id = 0; + data->state.lastconnect_id = -1; + } } -/* Look up the bundle with all the connections to the same host this - connectdata struct is setup to use. - - **NOTE**: When it returns, it holds the connection cache lock! */ -struct connectbundle * -Curl_conncache_find_bundle(struct Curl_easy *data, - struct connectdata *conn, - struct conncache *connc) +static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool, + struct connectdata *conn) { - struct connectbundle *bundle = NULL; - CONNCACHE_LOCK(data); - if(connc) { - char key[HASHKEY_SIZE]; - hashkey(conn, key, sizeof(key)); - bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); - } - - return bundle; + return Curl_hash_pick(&cpool->dest2bundle, + conn->destination, conn->destination_len); } -static void *connc_add_bundle(struct conncache *connc, - char *key, struct connectbundle *bundle) +static struct cpool_bundle * +cpool_add_bundle(struct cpool *cpool, struct connectdata *conn) { - return Curl_hash_add(&connc->hash, key, strlen(key), bundle); + struct cpool_bundle *bundle; + + bundle = cpool_bundle_create(conn->destination, conn->destination_len); + if(!bundle) + return NULL; + + if(!Curl_hash_add(&cpool->dest2bundle, + bundle->dest, bundle->dest_len, bundle)) { + cpool_bundle_destroy(bundle); + return NULL; + } + return bundle; } -static void connc_remove_bundle(struct conncache *connc, - struct connectbundle *bundle) +static void cpool_remove_bundle(struct cpool *cpool, + struct cpool_bundle *bundle) { struct Curl_hash_iterator iter; struct Curl_hash_element *he; - if(!connc) + if(!cpool) return; - Curl_hash_start_iterate(&connc->hash, &iter); + Curl_hash_start_iterate(&cpool->dest2bundle, &iter); he = Curl_hash_next_element(&iter); while(he) { if(he->ptr == bundle) { /* The bundle is destroyed by the hash destructor function, free_bundle_hash_entry() */ - Curl_hash_delete(&connc->hash, he->key, he->key_len); + Curl_hash_delete(&cpool->dest2bundle, he->key, he->key_len); return; } @@ -242,229 +290,252 @@ static void connc_remove_bundle(struct conncache *connc, } } -CURLcode Curl_conncache_add_conn(struct Curl_easy *data) +static struct connectdata * +cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle); + +int Curl_cpool_check_limits(struct Curl_easy *data, + struct connectdata *conn) { - CURLcode result = CURLE_OK; - struct connectbundle *bundle = NULL; - struct connectdata *conn = data->conn; - struct conncache *connc = data->state.conn_cache; - DEBUGASSERT(conn); + struct cpool *cpool = cpool_get_instance(data); + struct cpool_bundle *bundle; + size_t dest_limit = 0; + size_t total_limit = 0; + int result = CPOOL_LIMIT_OK; + + if(!cpool) + return CPOOL_LIMIT_OK; + + if(data && data->multi) { + dest_limit = data->multi->max_host_connections; + total_limit = data->multi->max_total_connections; + } - /* *find_bundle() locks the connection cache */ - bundle = Curl_conncache_find_bundle(data, conn, data->state.conn_cache); - if(!bundle) { - char key[HASHKEY_SIZE]; + if(!dest_limit && !total_limit) + return CPOOL_LIMIT_OK; + + CPOOL_LOCK(cpool); + if(dest_limit) { + bundle = cpool_find_bundle(cpool, conn); + while(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) { + struct connectdata *oldest_idle = NULL; + /* The bundle is full. Extract the oldest connection that may + * be removed now, if there is one. */ + oldest_idle = cpool_bundle_get_oldest_idle(bundle); + if(!oldest_idle) + break; + /* disconnect the old conn and continue */ + DEBUGF(infof(data, "Discarding connection #%" + FMT_OFF_T " from %zu to reach destination " + "limit of %zu", oldest_idle->connection_id, + Curl_llist_count(&bundle->conns), dest_limit)); + Curl_cpool_disconnect(data, oldest_idle, FALSE); + } + if(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) { + result = CPOOL_LIMIT_DEST; + goto out; + } + } - result = bundle_create(&bundle); - if(result) { - goto unlock; + if(total_limit) { + while(cpool->num_conn >= total_limit) { + struct connectdata *oldest_idle = cpool_get_oldest_idle(cpool); + if(!oldest_idle) + break; + /* disconnect the old conn and continue */ + DEBUGF(infof(data, "Discarding connection #%" + FMT_OFF_T " from %zu to reach total " + "limit of %zu", + oldest_idle->connection_id, cpool->num_conn, total_limit)); + Curl_cpool_disconnect(data, oldest_idle, FALSE); } + if(cpool->num_conn >= total_limit) { + result = CPOOL_LIMIT_TOTAL; + goto out; + } + } + +out: + CPOOL_UNLOCK(cpool); + return result; +} - hashkey(conn, key, sizeof(key)); +CURLcode Curl_cpool_add_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct cpool_bundle *bundle = NULL; + struct cpool *cpool = cpool_get_instance(data); + DEBUGASSERT(conn); - if(!connc_add_bundle(data->state.conn_cache, key, bundle)) { - bundle_destroy(bundle); + DEBUGASSERT(cpool); + if(!cpool) + return CURLE_FAILED_INIT; + + CPOOL_LOCK(cpool); + bundle = cpool_find_bundle(cpool, conn); + if(!bundle) { + bundle = cpool_add_bundle(cpool, conn); + if(!bundle) { result = CURLE_OUT_OF_MEMORY; - goto unlock; + goto out; } } - bundle_add_conn(bundle, conn); - conn->connection_id = connc->next_connection_id++; - connc->num_conn++; - - DEBUGF(infof(data, "Added connection %" CURL_FORMAT_CURL_OFF_T ". " + cpool_bundle_add(bundle, conn); + conn->connection_id = cpool->next_connection_id++; + cpool->num_conn++; + DEBUGF(infof(data, "Added connection %" FMT_OFF_T ". " "The cache now contains %zu members", - conn->connection_id, connc->num_conn)); - -unlock: - CONNCACHE_UNLOCK(data); + conn->connection_id, cpool->num_conn)); +out: + CPOOL_UNLOCK(cpool); return result; } -static void connc_remove_conn(struct conncache *connc, +static void cpool_remove_conn(struct cpool *cpool, struct connectdata *conn) { - struct connectbundle *bundle = conn->bundle; - - /* The bundle pointer can be NULL, since this function can be called - due to a failed connection attempt, before being added to a bundle */ - if(bundle) { - bundle_remove_conn(bundle, conn); - if(connc && bundle->num_connections == 0) - connc_remove_bundle(connc, bundle); - conn->bundle = NULL; /* removed from it */ - if(connc) - connc->num_conn--; + struct Curl_llist *list = Curl_node_llist(&conn->cpool_node); + DEBUGASSERT(cpool); + if(list) { + /* The connection is certainly in the pool, but where? */ + struct cpool_bundle *bundle = cpool_find_bundle(cpool, conn); + if(bundle && (list == &bundle->conns)) { + cpool_bundle_remove(bundle, conn); + if(!Curl_llist_count(&bundle->conns)) + cpool_remove_bundle(cpool, bundle); + conn->bits.in_cpool = FALSE; + cpool->num_conn--; + } + else { + /* Not in a bundle, already in the shutdown list? */ + DEBUGASSERT(list == &cpool->shutdowns); + } } } -/* - * Removes the connectdata object from the connection cache, but the transfer - * still owns this connection. - * - * Pass TRUE/FALSE in the 'lock' argument depending on if the parent function - * already holds the lock or not. - */ -void Curl_conncache_remove_conn(struct Curl_easy *data, - struct connectdata *conn, bool lock) -{ - struct conncache *connc = data->state.conn_cache; - - if(lock) - CONNCACHE_LOCK(data); - connc_remove_conn(connc, conn); - if(lock) - CONNCACHE_UNLOCK(data); - if(connc) - DEBUGF(infof(data, "The cache now contains %zu members", - connc->num_conn)); -} - -/* This function iterates the entire connection cache and calls the function +/* This function iterates the entire connection pool and calls the function func() with the connection pointer as the first argument and the supplied 'param' argument as the other. - The conncache lock is still held when the callback is called. It needs it, + The cpool lock is still held when the callback is called. It needs it, so that it can safely continue traversing the lists once the callback returns. - Returns 1 if the loop was aborted due to the callback's return code. + Returns TRUE if the loop was aborted due to the callback's return code. Return 0 from func() to continue the loop, return 1 to abort it. */ -bool Curl_conncache_foreach(struct Curl_easy *data, - struct conncache *connc, - void *param, - int (*func)(struct Curl_easy *data, - struct connectdata *conn, void *param)) +static bool cpool_foreach(struct Curl_easy *data, + struct cpool *cpool, + void *param, + int (*func)(struct Curl_easy *data, + struct connectdata *conn, void *param)) { struct Curl_hash_iterator iter; - struct Curl_llist_element *curr; struct Curl_hash_element *he; - if(!connc) + if(!cpool) return FALSE; - CONNCACHE_LOCK(data); - Curl_hash_start_iterate(&connc->hash, &iter); + Curl_hash_start_iterate(&cpool->dest2bundle, &iter); he = Curl_hash_next_element(&iter); while(he) { - struct connectbundle *bundle; - - bundle = he->ptr; + struct Curl_llist_node *curr; + struct cpool_bundle *bundle = he->ptr; he = Curl_hash_next_element(&iter); - curr = bundle->conn_list.head; + curr = Curl_llist_head(&bundle->conns); while(curr) { /* Yes, we need to update curr before calling func(), because func() might decide to remove the connection */ - struct connectdata *conn = curr->ptr; - curr = curr->next; + struct connectdata *conn = Curl_node_elem(curr); + curr = Curl_node_next(curr); if(1 == func(data, conn, param)) { - CONNCACHE_UNLOCK(data); return TRUE; } } } - CONNCACHE_UNLOCK(data); return FALSE; } -/* Return the first connection found in the cache. Used when closing all - connections. - - NOTE: no locking is done here as this is presumably only done when cleaning - up a cache! -*/ -static struct connectdata * -connc_find_first_connection(struct conncache *connc) +/* Return a live connection in the pool or NULL. */ +static struct connectdata *cpool_get_live_conn(struct cpool *cpool) { struct Curl_hash_iterator iter; struct Curl_hash_element *he; - struct connectbundle *bundle; + struct cpool_bundle *bundle; + struct Curl_llist_node *conn_node; - Curl_hash_start_iterate(&connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct Curl_llist_element *curr; + Curl_hash_start_iterate(&cpool->dest2bundle, &iter); + for(he = Curl_hash_next_element(&iter); he; + he = Curl_hash_next_element(&iter)) { bundle = he->ptr; - - curr = bundle->conn_list.head; - if(curr) { - return curr->ptr; - } - - he = Curl_hash_next_element(&iter); + conn_node = Curl_llist_head(&bundle->conns); + if(conn_node) + return Curl_node_elem(conn_node); } - return NULL; } /* - * Give ownership of a connection back to the connection cache. Might - * disconnect the oldest existing in there to make space. + * A connection (already in the pool) has become idle. Do any + * cleanups in regard to the pool's limits. * - * Return TRUE if stored, FALSE if closed. + * Return TRUE if idle connection kept in pool, FALSE if closed. */ -bool Curl_conncache_return_conn(struct Curl_easy *data, - struct connectdata *conn) +bool Curl_cpool_conn_now_idle(struct Curl_easy *data, + struct connectdata *conn) { unsigned int maxconnects = !data->multi->maxconnects ? data->multi->num_easy * 4: data->multi->maxconnects; - struct connectdata *conn_candidate = NULL; + struct connectdata *oldest_idle = NULL; + struct cpool *cpool = cpool_get_instance(data); + bool kept = TRUE; conn->lastused = Curl_now(); /* it was used up until now */ - if(maxconnects && Curl_conncache_size(data) > maxconnects) { - infof(data, "Connection cache is full, closing the oldest one"); - - conn_candidate = Curl_conncache_extract_oldest(data); - if(conn_candidate) { - /* Use the closure handle for this disconnect so that anything that - happens during the disconnect is not stored and associated with the - 'data' handle which already just finished a transfer and it is - important that details from this (unrelated) disconnect does not - taint meta-data in the data handle. */ - struct conncache *connc = data->state.conn_cache; - connc_disconnect(NULL, conn_candidate, connc, TRUE); + if(cpool && maxconnects) { + /* may be called form a callback already under lock */ + bool do_lock = !CPOOL_IS_LOCKED(cpool); + if(do_lock) + CPOOL_LOCK(cpool); + if(cpool->num_conn > maxconnects) { + infof(data, "Connection pool is full, closing the oldest one"); + + oldest_idle = cpool_get_oldest_idle(cpool); + kept = (oldest_idle != conn); + if(oldest_idle) { + Curl_cpool_disconnect(cpool->idata, oldest_idle, FALSE); + } } + if(do_lock) + CPOOL_UNLOCK(cpool); } - return (conn_candidate == conn) ? FALSE : TRUE; - + return kept; } /* * This function finds the connection in the connection bundle that has been * unused for the longest time. - * - * Does not lock the connection cache! - * - * Returns the pointer to the oldest idle connection, or NULL if none was - * found. */ -struct connectdata * -Curl_conncache_extract_bundle(struct Curl_easy *data, - struct connectbundle *bundle) +static struct connectdata * +cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle) { - struct Curl_llist_element *curr; + struct Curl_llist_node *curr; timediff_t highscore = -1; timediff_t score; struct curltime now; - struct connectdata *conn_candidate = NULL; + struct connectdata *oldest_idle = NULL; struct connectdata *conn; - (void)data; - now = Curl_now(); - - curr = bundle->conn_list.head; + curr = Curl_llist_head(&bundle->conns); while(curr) { - conn = curr->ptr; + conn = Curl_node_elem(curr); if(!CONN_INUSE(conn)) { /* Set higher score for the age passed since the connection was used */ @@ -472,130 +543,126 @@ Curl_conncache_extract_bundle(struct Curl_easy *data, if(score > highscore) { highscore = score; - conn_candidate = conn; + oldest_idle = conn; } } - curr = curr->next; - } - if(conn_candidate) { - /* remove it to prevent another thread from nicking it */ - bundle_remove_conn(bundle, conn_candidate); - data->state.conn_cache->num_conn--; - DEBUGF(infof(data, "The cache now contains %zu members", - data->state.conn_cache->num_conn)); + curr = Curl_node_next(curr); } - - return conn_candidate; + return oldest_idle; } -/* - * This function finds the connection in the connection cache that has been - * unused for the longest time and extracts that from the bundle. - * - * Returns the pointer to the connection, or NULL if none was found. - */ -struct connectdata * -Curl_conncache_extract_oldest(struct Curl_easy *data) +static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool) { - struct conncache *connc = data->state.conn_cache; struct Curl_hash_iterator iter; - struct Curl_llist_element *curr; + struct Curl_llist_node *curr; struct Curl_hash_element *he; + struct connectdata *oldest_idle = NULL; + struct cpool_bundle *bundle; + struct curltime now; timediff_t highscore =- 1; timediff_t score; - struct curltime now; - struct connectdata *conn_candidate = NULL; - struct connectbundle *bundle; - struct connectbundle *bundle_candidate = NULL; now = Curl_now(); + Curl_hash_start_iterate(&cpool->dest2bundle, &iter); - CONNCACHE_LOCK(data); - Curl_hash_start_iterate(&connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { + for(he = Curl_hash_next_element(&iter); he; + he = Curl_hash_next_element(&iter)) { struct connectdata *conn; - bundle = he->ptr; - curr = bundle->conn_list.head; - while(curr) { - conn = curr->ptr; - - if(!CONN_INUSE(conn) && !conn->bits.close && - !conn->connect_only) { - /* Set higher score for the age passed since the connection was used */ - score = Curl_timediff(now, conn->lastused); - - if(score > highscore) { - highscore = score; - conn_candidate = conn; - bundle_candidate = bundle; - } + for(curr = Curl_llist_head(&bundle->conns); curr; + curr = Curl_node_next(curr)) { + conn = Curl_node_elem(curr); + if(CONN_INUSE(conn) || conn->bits.close || conn->connect_only) + continue; + /* Set higher score for the age passed since the connection was used */ + score = Curl_timediff(now, conn->lastused); + if(score > highscore) { + highscore = score; + oldest_idle = conn; } - curr = curr->next; } - - he = Curl_hash_next_element(&iter); } - if(conn_candidate) { - /* remove it to prevent another thread from nicking it */ - bundle_remove_conn(bundle_candidate, conn_candidate); - connc->num_conn--; - DEBUGF(infof(data, "The cache now contains %zu members", - connc->num_conn)); + return oldest_idle; +} + +bool Curl_cpool_find(struct Curl_easy *data, + const char *destination, size_t dest_len, + Curl_cpool_conn_match_cb *conn_cb, + Curl_cpool_done_match_cb *done_cb, + void *userdata) +{ + struct cpool *cpool = cpool_get_instance(data); + struct cpool_bundle *bundle; + bool result = FALSE; + + DEBUGASSERT(cpool); + DEBUGASSERT(conn_cb); + if(!cpool) + return FALSE; + + CPOOL_LOCK(cpool); + bundle = Curl_hash_pick(&cpool->dest2bundle, (void *)destination, dest_len); + if(bundle) { + struct Curl_llist_node *curr = Curl_llist_head(&bundle->conns); + while(curr) { + struct connectdata *conn = Curl_node_elem(curr); + /* Get next node now. callback might discard current */ + curr = Curl_node_next(curr); + + if(conn_cb(conn, userdata)) { + result = TRUE; + break; + } + } } - CONNCACHE_UNLOCK(data); - return conn_candidate; + if(done_cb) { + result = done_cb(result, userdata); + } + CPOOL_UNLOCK(cpool); + return result; } -static void connc_shutdown_discard_all(struct conncache *connc) +static void cpool_shutdown_discard_all(struct cpool *cpool) { - struct Curl_llist_element *e = connc->shutdowns.conn_list.head; + struct Curl_llist_node *e = Curl_llist_head(&cpool->shutdowns); struct connectdata *conn; if(!e) return; - DEBUGF(infof(connc->closure_handle, "conncache_shutdown_discard_all")); - DEBUGASSERT(!connc->shutdowns.iter_locked); - connc->shutdowns.iter_locked = TRUE; + DEBUGF(infof(cpool->idata, "cpool_shutdown_discard_all")); while(e) { - conn = e->ptr; - Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL); - DEBUGF(infof(connc->closure_handle, "discard connection #%" - CURL_FORMAT_CURL_OFF_T, conn->connection_id)); - connc_disconnect(NULL, conn, connc, FALSE); - e = connc->shutdowns.conn_list.head; + conn = Curl_node_elem(e); + Curl_node_remove(e); + DEBUGF(infof(cpool->idata, "discard connection #%" FMT_OFF_T, + conn->connection_id)); + cpool_close_and_destroy(cpool, conn, NULL, FALSE); + e = Curl_llist_head(&cpool->shutdowns); } - connc->shutdowns.iter_locked = FALSE; } -static void connc_close_all(struct conncache *connc) +static void cpool_close_and_destroy_all(struct cpool *cpool) { - struct Curl_easy *data = connc->closure_handle; struct connectdata *conn; int timeout_ms = 0; SIGPIPE_VARIABLE(pipe_st); - if(!data) - return; - + DEBUGASSERT(cpool); /* Move all connections to the shutdown list */ sigpipe_init(&pipe_st); - conn = connc_find_first_connection(connc); + CPOOL_LOCK(cpool); + conn = cpool_get_live_conn(cpool); while(conn) { - connc_remove_conn(connc, conn); - sigpipe_apply(data, &pipe_st); - /* This will remove the connection from the cache */ + cpool_remove_conn(cpool, conn); + sigpipe_apply(cpool->idata, &pipe_st); connclose(conn, "kill all"); - Curl_conncache_remove_conn(connc->closure_handle, conn, TRUE); - connc_discard_conn(connc, connc->closure_handle, conn, FALSE); + cpool_discard_conn(cpool, cpool->idata, conn, FALSE); - conn = connc_find_first_connection(connc); + conn = cpool_get_live_conn(cpool); } + CPOOL_UNLOCK(cpool); /* Just for testing, run graceful shutdown */ #ifdef DEBUGBUILD @@ -608,73 +675,53 @@ static void connc_close_all(struct conncache *connc) } } #endif - connc_shutdown_all(connc, timeout_ms); + sigpipe_apply(cpool->idata, &pipe_st); + cpool_shutdown_all(cpool, cpool->idata, timeout_ms); /* discard all connections in the shutdown list */ - connc_shutdown_discard_all(connc); + cpool_shutdown_discard_all(cpool); - sigpipe_apply(data, &pipe_st); - Curl_hostcache_clean(data, data->dns.hostcache); - Curl_close(&data); + Curl_hostcache_clean(cpool->idata, cpool->idata->dns.hostcache); sigpipe_restore(&pipe_st); } -void Curl_conncache_close_all_connections(struct conncache *connc) -{ - connc_close_all(connc); -} -static void connc_shutdown_discard_oldest(struct conncache *connc) +static void cpool_shutdown_destroy_oldest(struct cpool *cpool) { - struct Curl_llist_element *e; + struct Curl_llist_node *e; struct connectdata *conn; - DEBUGASSERT(!connc->shutdowns.iter_locked); - if(connc->shutdowns.iter_locked) - return; - - e = connc->shutdowns.conn_list.head; + e = Curl_llist_head(&cpool->shutdowns); if(e) { SIGPIPE_VARIABLE(pipe_st); - conn = e->ptr; - Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL); + conn = Curl_node_elem(e); + Curl_node_remove(e); sigpipe_init(&pipe_st); - sigpipe_apply(connc->closure_handle, &pipe_st); - connc_disconnect(NULL, conn, connc, FALSE); + sigpipe_apply(cpool->idata, &pipe_st); + cpool_close_and_destroy(cpool, conn, NULL, FALSE); sigpipe_restore(&pipe_st); } } -static void connc_discard_conn(struct conncache *connc, - struct Curl_easy *last_data, +static void cpool_discard_conn(struct cpool *cpool, + struct Curl_easy *data, struct connectdata *conn, bool aborted) { - /* `last_data`, if present, is the transfer that last worked with - * the connection. It is present when the connection is being shut down - * via `Curl_conncache_discard_conn()`, e.g. when the transfer failed - * or does not allow connection reuse. - * Using the original handle is necessary for shutting down the protocol - * handler belonging to the connection. Protocols like 'file:' rely on - * being invoked to clean up their allocations in the easy handle. - * When a connection comes from the cache, the transfer is no longer - * there and we use the cache is own closure handle. - */ - struct Curl_easy *data = last_data? last_data : connc->closure_handle; bool done = FALSE; DEBUGASSERT(data); - DEBUGASSERT(connc); - DEBUGASSERT(!conn->bundle); + DEBUGASSERT(cpool); + DEBUGASSERT(!conn->bits.in_cpool); /* * If this connection is not marked to force-close, leave it open if there * are other users of it */ if(CONN_INUSE(conn) && !aborted) { - DEBUGF(infof(data, "[CCACHE] not discarding #%" CURL_FORMAT_CURL_OFF_T - " still in use by %zu transfers", conn->connection_id, - CONN_INUSE(conn))); + DEBUGF(infof(data, "[CCACHE] not discarding #%" FMT_OFF_T + " still in use by %zu transfers", conn->connection_id, + CONN_INUSE(conn))); return; } @@ -694,22 +741,14 @@ static void connc_discard_conn(struct conncache *connc, if(!done) { /* Attempt to shutdown the connection right away. */ Curl_attach_connection(data, conn); - connc_run_conn_shutdown(data, conn, &done); - DEBUGF(infof(data, "[CCACHE] shutdown #%" CURL_FORMAT_CURL_OFF_T - ", done=%d",conn->connection_id, done)); + cpool_run_conn_shutdown(data, conn, &done); + DEBUGF(infof(data, "[CCACHE] shutdown #%" FMT_OFF_T ", done=%d", + conn->connection_id, done)); Curl_detach_connection(data); } if(done) { - connc_disconnect(data, conn, connc, FALSE); - return; - } - - DEBUGASSERT(!connc->shutdowns.iter_locked); - if(connc->shutdowns.iter_locked) { - DEBUGF(infof(data, "[CCACHE] discarding #%" CURL_FORMAT_CURL_OFF_T - ", list locked", conn->connection_id)); - connc_disconnect(data, conn, connc, FALSE); + cpool_close_and_destroy(cpool, conn, data, FALSE); return; } @@ -717,65 +756,89 @@ static void connc_discard_conn(struct conncache *connc, * during multi processing. */ if(data->multi && data->multi->max_shutdown_connections > 0 && (data->multi->max_shutdown_connections >= - (long)Curl_llist_count(&connc->shutdowns.conn_list))) { + (long)Curl_llist_count(&cpool->shutdowns))) { DEBUGF(infof(data, "[CCACHE] discarding oldest shutdown connection " "due to limit of %ld", data->multi->max_shutdown_connections)); - connc_shutdown_discard_oldest(connc); + cpool_shutdown_destroy_oldest(cpool); } if(data->multi && data->multi->socket_cb) { - DEBUGASSERT(connc == &data->multi->conn_cache); + DEBUGASSERT(cpool == &data->multi->cpool); /* Start with an empty shutdown pollset, so out internal closure handle * is added to the sockets. */ memset(&conn->shutdown_poll, 0, sizeof(conn->shutdown_poll)); - if(connc_update_shutdown_ev(data->multi, connc->closure_handle, conn)) { + if(cpool_update_shutdown_ev(data->multi, cpool->idata, conn)) { DEBUGF(infof(data, "[CCACHE] update events for shutdown failed, " - "discarding #%" CURL_FORMAT_CURL_OFF_T, - conn->connection_id)); - connc_disconnect(data, conn, connc, FALSE); + "discarding #%" FMT_OFF_T, + conn->connection_id)); + cpool_close_and_destroy(cpool, conn, data, FALSE); return; } } - Curl_llist_append(&connc->shutdowns.conn_list, conn, &conn->bundle_node); - DEBUGF(infof(data, "[CCACHE] added #%" CURL_FORMAT_CURL_OFF_T - " to shutdown list of length %zu", conn->connection_id, - Curl_llist_count(&connc->shutdowns.conn_list))); + Curl_llist_append(&cpool->shutdowns, conn, &conn->cpool_node); + DEBUGF(infof(data, "[CCACHE] added #%" FMT_OFF_T + " to shutdown list of length %zu", conn->connection_id, + Curl_llist_count(&cpool->shutdowns))); } -void Curl_conncache_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool aborted) +void Curl_cpool_disconnect(struct Curl_easy *data, + struct connectdata *conn, + bool aborted) { - DEBUGASSERT(data); - /* Connection must no longer be in and connection cache */ - DEBUGASSERT(!conn->bundle); + struct cpool *cpool = cpool_get_instance(data); + bool do_lock; + + DEBUGASSERT(cpool); + DEBUGASSERT(data && !data->conn); + if(!cpool) + return; + + /* If this connection is not marked to force-close, leave it open if there + * are other users of it */ + if(CONN_INUSE(conn) && !aborted) { + DEBUGASSERT(0); /* does this ever happen? */ + DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn))); + return; + } + + /* This method may be called while we are under lock, e.g. from a + * user callback in find. */ + do_lock = !CPOOL_IS_LOCKED(cpool); + if(do_lock) + CPOOL_LOCK(cpool); + + if(conn->bits.in_cpool) { + cpool_remove_conn(cpool, conn); + DEBUGASSERT(!conn->bits.in_cpool); + } + + /* Run the callback to let it clean up anything it wants to. */ + aborted = cpool->disconnect_cb(data, conn, aborted); if(data->multi) { - /* Add it to the multi's conncache for shutdown handling */ - infof(data, "%s connection #%" CURL_FORMAT_CURL_OFF_T, + /* Add it to the multi's cpool for shutdown handling */ + infof(data, "%s connection #%" FMT_OFF_T, aborted? "closing" : "shutting down", conn->connection_id); - connc_discard_conn(&data->multi->conn_cache, data, conn, aborted); + cpool_discard_conn(&data->multi->cpool, data, conn, aborted); } else { /* No multi available. Make a best-effort shutdown + close */ - infof(data, "closing connection #%" CURL_FORMAT_CURL_OFF_T, - conn->connection_id); - DEBUGASSERT(!conn->bundle); - connc_run_conn_shutdown_handler(data, conn); - connc_disconnect(data, conn, NULL, !aborted); + infof(data, "closing connection #%" FMT_OFF_T, conn->connection_id); + cpool_close_and_destroy(NULL, conn, data, !aborted); } + + if(do_lock) + CPOOL_UNLOCK(cpool); } -static void connc_run_conn_shutdown_handler(struct Curl_easy *data, +static void cpool_run_conn_shutdown_handler(struct Curl_easy *data, struct connectdata *conn) { if(!conn->bits.shutdown_handler) { - if(conn->dns_entry) { - Curl_resolv_unlock(data, conn->dns_entry); - conn->dns_entry = NULL; - } + if(conn->dns_entry) + Curl_resolv_unlink(data, &conn->dns_entry); /* Cleanup NTLM connection-related data */ Curl_http_auth_cleanup_ntlm(conn); @@ -785,9 +848,10 @@ static void connc_run_conn_shutdown_handler(struct Curl_easy *data, if(conn->handler && conn->handler->disconnect) { /* This is set if protocol-specific cleanups should be made */ - DEBUGF(infof(data, "connection #%" CURL_FORMAT_CURL_OFF_T + DEBUGF(infof(data, "connection #%" FMT_OFF_T ", shutdown protocol handler (aborted=%d)", conn->connection_id, conn->bits.aborted)); + conn->handler->disconnect(data, conn, conn->bits.aborted); } @@ -798,7 +862,7 @@ static void connc_run_conn_shutdown_handler(struct Curl_easy *data, } } -static void connc_run_conn_shutdown(struct Curl_easy *data, +static void cpool_run_conn_shutdown(struct Curl_easy *data, struct connectdata *conn, bool *done) { @@ -808,7 +872,7 @@ static void connc_run_conn_shutdown(struct Curl_easy *data, /* We expect to be attached when called */ DEBUGASSERT(data->conn == conn); - connc_run_conn_shutdown_handler(data, conn); + cpool_run_conn_shutdown_handler(data, conn); if(conn->bits.shutdown_filters) { *done = TRUE; @@ -835,24 +899,23 @@ static void connc_run_conn_shutdown(struct Curl_easy *data, conn->bits.shutdown_filters = TRUE; } -CURLcode Curl_conncache_add_pollfds(struct conncache *connc, - struct curl_pollfds *cpfds) +static CURLcode cpool_add_pollfds(struct cpool *cpool, + struct curl_pollfds *cpfds) { CURLcode result = CURLE_OK; - DEBUGASSERT(!connc->shutdowns.iter_locked); - connc->shutdowns.iter_locked = TRUE; - if(connc->shutdowns.conn_list.head) { - struct Curl_llist_element *e; + if(Curl_llist_head(&cpool->shutdowns)) { + struct Curl_llist_node *e; struct easy_pollset ps; struct connectdata *conn; - for(e = connc->shutdowns.conn_list.head; e; e = e->next) { - conn = e->ptr; + for(e = Curl_llist_head(&cpool->shutdowns); e; + e = Curl_node_next(e)) { + conn = Curl_node_elem(e); memset(&ps, 0, sizeof(ps)); - Curl_attach_connection(connc->closure_handle, conn); - Curl_conn_adjust_pollset(connc->closure_handle, &ps); - Curl_detach_connection(connc->closure_handle); + Curl_attach_connection(cpool->idata, conn); + Curl_conn_adjust_pollset(cpool->idata, &ps); + Curl_detach_connection(cpool->idata); result = Curl_pollfds_add_ps(cpfds, &ps); if(result) { @@ -862,28 +925,37 @@ CURLcode Curl_conncache_add_pollfds(struct conncache *connc, } } out: - connc->shutdowns.iter_locked = FALSE; return result; } -CURLcode Curl_conncache_add_waitfds(struct conncache *connc, - struct curl_waitfds *cwfds) +CURLcode Curl_cpool_add_pollfds(struct cpool *cpool, + struct curl_pollfds *cpfds) +{ + CURLcode result; + CPOOL_LOCK(cpool); + result = cpool_add_pollfds(cpool, cpfds); + CPOOL_UNLOCK(cpool); + return result; +} + +CURLcode Curl_cpool_add_waitfds(struct cpool *cpool, + struct curl_waitfds *cwfds) { CURLcode result = CURLE_OK; - DEBUGASSERT(!connc->shutdowns.iter_locked); - connc->shutdowns.iter_locked = TRUE; - if(connc->shutdowns.conn_list.head) { - struct Curl_llist_element *e; + CPOOL_LOCK(cpool); + if(Curl_llist_head(&cpool->shutdowns)) { + struct Curl_llist_node *e; struct easy_pollset ps; struct connectdata *conn; - for(e = connc->shutdowns.conn_list.head; e; e = e->next) { - conn = e->ptr; + for(e = Curl_llist_head(&cpool->shutdowns); e; + e = Curl_node_next(e)) { + conn = Curl_node_elem(e); memset(&ps, 0, sizeof(ps)); - Curl_attach_connection(connc->closure_handle, conn); - Curl_conn_adjust_pollset(connc->closure_handle, &ps); - Curl_detach_connection(connc->closure_handle); + Curl_attach_connection(cpool->idata, conn); + Curl_conn_adjust_pollset(cpool->idata, &ps); + Curl_detach_connection(cpool->idata); result = Curl_waitfds_add_ps(cwfds, &ps); if(result) @@ -891,15 +963,15 @@ CURLcode Curl_conncache_add_waitfds(struct conncache *connc, } } out: - connc->shutdowns.iter_locked = FALSE; + CPOOL_UNLOCK(cpool); return result; } -static void connc_perform(struct conncache *connc) +static void cpool_perform(struct cpool *cpool) { - struct Curl_easy *data = connc->closure_handle; - struct Curl_llist_element *e = connc->shutdowns.conn_list.head; - struct Curl_llist_element *enext; + struct Curl_easy *data = cpool->idata; + struct Curl_llist_node *e = Curl_llist_head(&cpool->shutdowns); + struct Curl_llist_node *enext; struct connectdata *conn; struct curltime *nowp = NULL; struct curltime now; @@ -910,21 +982,19 @@ static void connc_perform(struct conncache *connc) return; DEBUGASSERT(data); - DEBUGASSERT(!connc->shutdowns.iter_locked); DEBUGF(infof(data, "[CCACHE] perform, %zu connections being shutdown", - Curl_llist_count(&connc->shutdowns.conn_list))); - connc->shutdowns.iter_locked = TRUE; + Curl_llist_count(&cpool->shutdowns))); while(e) { - enext = e->next; - conn = e->ptr; + enext = Curl_node_next(e); + conn = Curl_node_elem(e); Curl_attach_connection(data, conn); - connc_run_conn_shutdown(data, conn, &done); - DEBUGF(infof(data, "[CCACHE] shutdown #%" CURL_FORMAT_CURL_OFF_T - ", done=%d", conn->connection_id, done)); + cpool_run_conn_shutdown(data, conn, &done); + DEBUGF(infof(data, "[CCACHE] shutdown #%" FMT_OFF_T ", done=%d", + conn->connection_id, done)); Curl_detach_connection(data); if(done) { - Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL); - connc_disconnect(NULL, conn, connc, FALSE); + Curl_node_remove(e); + cpool_close_and_destroy(cpool, conn, NULL, FALSE); } else { /* Not done, when does this connection time out? */ @@ -938,72 +1008,56 @@ static void connc_perform(struct conncache *connc) } e = enext; } - connc->shutdowns.iter_locked = FALSE; if(next_from_now_ms) Curl_expire(data, next_from_now_ms, EXPIRE_RUN_NOW); } -void Curl_conncache_multi_perform(struct Curl_multi *multi) +void Curl_cpool_multi_perform(struct Curl_multi *multi) { - connc_perform(&multi->conn_cache); + CPOOL_LOCK(&multi->cpool); + cpool_perform(&multi->cpool); + CPOOL_UNLOCK(&multi->cpool); } /* - * Disconnects the given connection. Note the connection may not be the - * primary connection, like when freeing room in the connection cache or - * killing of a dead old connection. - * - * A connection needs an easy handle when closing down. We support this passed - * in separately since the connection to get closed here is often already - * disassociated from an easy handle. - * - * This function MUST NOT reset state in the Curl_easy struct if that - * is not strictly bound to the life-time of *this* particular connection. - * + * Close and destroy the connection. Run the shutdown sequence once, + * of so requested. */ -static void connc_disconnect(struct Curl_easy *data, - struct connectdata *conn, - struct conncache *connc, - bool do_shutdown) +static void cpool_close_and_destroy(struct cpool *cpool, + struct connectdata *conn, + struct Curl_easy *data, + bool do_shutdown) { bool done; /* there must be a connection to close */ DEBUGASSERT(conn); - /* it must be removed from the connection cache */ - DEBUGASSERT(!conn->bundle); + /* it must be removed from the connection pool */ + DEBUGASSERT(!conn->bits.in_cpool); /* there must be an associated transfer */ - DEBUGASSERT(data || connc); + DEBUGASSERT(data || cpool); if(!data) - data = connc->closure_handle; + data = cpool->idata; /* the transfer must be detached from the connection */ DEBUGASSERT(data && !data->conn); Curl_attach_connection(data, conn); - if(connc && connc->multi && connc->multi->socket_cb) { - struct easy_pollset ps; - /* With an empty pollset, all previously polled sockets will be removed - * via the multi_socket API callback. */ - memset(&ps, 0, sizeof(ps)); - (void)Curl_multi_pollset_ev(connc->multi, data, &ps, &conn->shutdown_poll); - } - - connc_run_conn_shutdown_handler(data, conn); + cpool_run_conn_shutdown_handler(data, conn); if(do_shutdown) { /* Make a last attempt to shutdown handlers and filters, if * not done so already. */ - connc_run_conn_shutdown(data, conn, &done); + cpool_run_conn_shutdown(data, conn, &done); } - if(connc) - DEBUGF(infof(data, "[CCACHE] closing #%" CURL_FORMAT_CURL_OFF_T, + if(cpool) + DEBUGF(infof(data, "[CCACHE] closing #%" FMT_OFF_T, conn->connection_id)); else - DEBUGF(infof(data, "closing connection #%" CURL_FORMAT_CURL_OFF_T, + DEBUGF(infof(data, "closing connection #%" FMT_OFF_T, conn->connection_id)); Curl_conn_close(data, SECONDARYSOCKET); Curl_conn_close(data, FIRSTSOCKET); @@ -1013,7 +1067,7 @@ static void connc_disconnect(struct Curl_easy *data, } -static CURLMcode connc_update_shutdown_ev(struct Curl_multi *multi, +static CURLMcode cpool_update_shutdown_ev(struct Curl_multi *multi, struct Curl_easy *data, struct connectdata *conn) { @@ -1036,49 +1090,41 @@ static CURLMcode connc_update_shutdown_ev(struct Curl_multi *multi, return mresult; } -void Curl_conncache_multi_socket(struct Curl_multi *multi, - curl_socket_t s, int ev_bitmask) +void Curl_cpool_multi_socket(struct Curl_multi *multi, + curl_socket_t s, int ev_bitmask) { - struct conncache *connc = &multi->conn_cache; - struct Curl_easy *data = connc->closure_handle; - struct Curl_llist_element *e = connc->shutdowns.conn_list.head; + struct cpool *cpool = &multi->cpool; + struct Curl_easy *data = cpool->idata; + struct Curl_llist_node *e; struct connectdata *conn; bool done; (void)ev_bitmask; DEBUGASSERT(multi->socket_cb); - if(!e) - return; - - connc->shutdowns.iter_locked = TRUE; + CPOOL_LOCK(cpool); + e = Curl_llist_head(&cpool->shutdowns); while(e) { - conn = e->ptr; + conn = Curl_node_elem(e); if(s == conn->sock[FIRSTSOCKET] || s == conn->sock[SECONDARYSOCKET]) { Curl_attach_connection(data, conn); - connc_run_conn_shutdown(data, conn, &done); - DEBUGF(infof(data, "[CCACHE] shutdown #%" CURL_FORMAT_CURL_OFF_T - ", done=%d", conn->connection_id, done)); + cpool_run_conn_shutdown(data, conn, &done); + DEBUGF(infof(data, "[CCACHE] shutdown #%" FMT_OFF_T ", done=%d", + conn->connection_id, done)); Curl_detach_connection(data); - if(done || connc_update_shutdown_ev(multi, data, conn)) { - Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL); - connc_disconnect(NULL, conn, connc, FALSE); + if(done || cpool_update_shutdown_ev(multi, data, conn)) { + Curl_node_remove(e); + cpool_close_and_destroy(cpool, conn, NULL, FALSE); } break; } - e = e->next; + e = Curl_node_next(e); } - connc->shutdowns.iter_locked = FALSE; -} - -void Curl_conncache_multi_close_all(struct Curl_multi *multi) -{ - connc_close_all(&multi->conn_cache); + CPOOL_UNLOCK(cpool); } - #define NUM_POLLS_ON_STACK 10 -static CURLcode connc_shutdown_wait(struct conncache *connc, int timeout_ms) +static CURLcode cpool_shutdown_wait(struct cpool *cpool, int timeout_ms) { struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct curl_pollfds cpfds; @@ -1086,7 +1132,7 @@ static CURLcode connc_shutdown_wait(struct conncache *connc, int timeout_ms) Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); - result = Curl_conncache_add_pollfds(connc, &cpfds); + result = cpool_add_pollfds(cpool, &cpfds); if(result) goto out; @@ -1097,9 +1143,9 @@ static CURLcode connc_shutdown_wait(struct conncache *connc, int timeout_ms) return result; } -static void connc_shutdown_all(struct conncache *connc, int timeout_ms) +static void cpool_shutdown_all(struct cpool *cpool, + struct Curl_easy *data, int timeout_ms) { - struct Curl_easy *data = connc->closure_handle; struct connectdata *conn; struct curltime started = Curl_now(); @@ -1107,79 +1153,226 @@ static void connc_shutdown_all(struct conncache *connc, int timeout_ms) return; (void)data; - DEBUGF(infof(data, "conncache shutdown all")); + DEBUGF(infof(data, "cpool shutdown all")); /* Move all connections into the shutdown queue */ - conn = connc_find_first_connection(connc); - while(conn) { - /* This will remove the connection from the cache */ - DEBUGF(infof(data, "moving connection %" CURL_FORMAT_CURL_OFF_T + for(conn = cpool_get_live_conn(cpool); conn; + conn = cpool_get_live_conn(cpool)) { + /* Move conn from live set to shutdown or destroy right away */ + DEBUGF(infof(data, "moving connection #%" FMT_OFF_T " to shutdown queue", conn->connection_id)); - connc_remove_conn(connc, conn); - connc_discard_conn(connc, NULL, conn, FALSE); - conn = connc_find_first_connection(connc); + cpool_remove_conn(cpool, conn); + cpool_discard_conn(cpool, data, conn, FALSE); } - DEBUGASSERT(!connc->shutdowns.iter_locked); - while(connc->shutdowns.conn_list.head) { + while(Curl_llist_head(&cpool->shutdowns)) { timediff_t timespent; int remain_ms; - connc_perform(connc); + cpool_perform(cpool); - if(!connc->shutdowns.conn_list.head) { - DEBUGF(infof(data, "conncache shutdown ok")); + if(!Curl_llist_head(&cpool->shutdowns)) { + DEBUGF(infof(data, "cpool shutdown ok")); break; } /* wait for activity, timeout or "nothing" */ timespent = Curl_timediff(Curl_now(), started); if(timespent >= (timediff_t)timeout_ms) { - DEBUGF(infof(data, "conncache shutdown %s", + DEBUGF(infof(data, "cpool shutdown %s", (timeout_ms > 0)? "timeout" : "best effort done")); break; } remain_ms = timeout_ms - (int)timespent; - if(connc_shutdown_wait(connc, remain_ms)) { - DEBUGF(infof(data, "conncache shutdown all, abort")); + if(cpool_shutdown_wait(cpool, remain_ms)) { + DEBUGF(infof(data, "cpool shutdown all, abort")); break; } } - /* Due to errors/timeout, we might come here without being full ydone. */ - connc_shutdown_discard_all(connc); + /* Due to errors/timeout, we might come here without being done. */ + cpool_shutdown_discard_all(cpool); +} + +struct cpool_reaper_ctx { + struct curltime now; +}; + +static int cpool_reap_dead_cb(struct Curl_easy *data, + struct connectdata *conn, void *param) +{ + struct cpool_reaper_ctx *rctx = param; + if(Curl_conn_seems_dead(conn, data, &rctx->now)) { + /* stop the iteration here, pass back the connection that was pruned */ + Curl_cpool_disconnect(data, conn, FALSE); + return 1; + } + return 0; /* continue iteration */ +} + +/* + * This function scans the data's connection pool for half-open/dead + * connections, closes and removes them. + * The cleanup is done at most once per second. + * + * When called, this transfer has no connection attached. + */ +void Curl_cpool_prune_dead(struct Curl_easy *data) +{ + struct cpool *cpool = cpool_get_instance(data); + struct cpool_reaper_ctx rctx; + timediff_t elapsed; + + if(!cpool) + return; + + rctx.now = Curl_now(); + CPOOL_LOCK(cpool); + elapsed = Curl_timediff(rctx.now, cpool->last_cleanup); + + if(elapsed >= 1000L) { + while(cpool_foreach(data, cpool, &rctx, cpool_reap_dead_cb)) + ; + cpool->last_cleanup = rctx.now; + } + CPOOL_UNLOCK(cpool); +} + +static int conn_upkeep(struct Curl_easy *data, + struct connectdata *conn, + void *param) +{ + struct curltime *now = param; + /* TODO, shall we reap connections that return an error here? */ + Curl_conn_upkeep(data, conn, now); + return 0; /* continue iteration */ +} + +CURLcode Curl_cpool_upkeep(void *data) +{ + struct cpool *cpool = cpool_get_instance(data); + struct curltime now = Curl_now(); + + if(!cpool) + return CURLE_OK; + + CPOOL_LOCK(cpool); + cpool_foreach(data, cpool, &now, conn_upkeep); + CPOOL_UNLOCK(cpool); + return CURLE_OK; +} + +struct cpool_find_ctx { + curl_off_t id; + struct connectdata *conn; +}; + +static int cpool_find_conn(struct Curl_easy *data, + struct connectdata *conn, void *param) +{ + struct cpool_find_ctx *fctx = param; + (void)data; + if(conn->connection_id == fctx->id) { + fctx->conn = conn; + return 1; + } + return 0; +} + +struct connectdata *Curl_cpool_get_conn(struct Curl_easy *data, + curl_off_t conn_id) +{ + struct cpool *cpool = cpool_get_instance(data); + struct cpool_find_ctx fctx; + + if(!cpool) + return NULL; + fctx.id = conn_id; + fctx.conn = NULL; + CPOOL_LOCK(cpool); + cpool_foreach(cpool->idata, cpool, &fctx, cpool_find_conn); + CPOOL_UNLOCK(cpool); + return fctx.conn; +} + +struct cpool_do_conn_ctx { + curl_off_t id; + Curl_cpool_conn_do_cb *cb; + void *cbdata; +}; + +static int cpool_do_conn(struct Curl_easy *data, + struct connectdata *conn, void *param) +{ + struct cpool_do_conn_ctx *dctx = param; + (void)data; + if(conn->connection_id == dctx->id) { + dctx->cb(conn, data, dctx->cbdata); + return 1; + } + return 0; +} + +void Curl_cpool_do_by_id(struct Curl_easy *data, curl_off_t conn_id, + Curl_cpool_conn_do_cb *cb, void *cbdata) +{ + struct cpool *cpool = cpool_get_instance(data); + struct cpool_do_conn_ctx dctx; + + if(!cpool) + return; + dctx.id = conn_id; + dctx.cb = cb; + dctx.cbdata = cbdata; + CPOOL_LOCK(cpool); + cpool_foreach(data, cpool, &dctx, cpool_do_conn); + CPOOL_UNLOCK(cpool); +} + +void Curl_cpool_do_locked(struct Curl_easy *data, + struct connectdata *conn, + Curl_cpool_conn_do_cb *cb, void *cbdata) +{ + struct cpool *cpool = cpool_get_instance(data); + if(cpool) { + CPOOL_LOCK(cpool); + cb(conn, data, cbdata); + CPOOL_UNLOCK(cpool); + } + else + cb(conn, data, cbdata); } #if 0 -/* Useful for debugging the connection cache */ -void Curl_conncache_print(struct conncache *connc) +/* Useful for debugging the connection pool */ +void Curl_cpool_print(struct cpool *cpool) { struct Curl_hash_iterator iter; - struct Curl_llist_element *curr; + struct Curl_llist_node *curr; struct Curl_hash_element *he; - if(!connc) + if(!cpool) return; fprintf(stderr, "=Bundle cache=\n"); - Curl_hash_start_iterate(connc->hash, &iter); + Curl_hash_start_iterate(cpool->dest2bundle, &iter); he = Curl_hash_next_element(&iter); while(he) { - struct connectbundle *bundle; + struct cpool_bundle *bundle; struct connectdata *conn; bundle = he->ptr; fprintf(stderr, "%s -", he->key); - curr = bundle->conn_list->head; + curr = Curl_llist_head(bundle->conns); while(curr) { - conn = curr->ptr; + conn = Curl_node_elem(curr); - fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse); - curr = curr->next; + fprintf(stderr, " [%p %d]", (void *)conn, conn->refcount); + curr = Curl_node_next(curr); } fprintf(stderr, "\n"); diff --git a/lib/conncache.h b/lib/conncache.h index 30cc2e259..a379ee747 100644 --- a/lib/conncache.h +++ b/lib/conncache.h @@ -25,140 +25,177 @@ * ***************************************************************************/ -/* - * All accesses to struct fields and changing of data in the connection cache - * and connectbundles must be done with the conncache LOCKED. The cache might - * be shared. - */ - #include #include "timeval.h" struct connectdata; +struct Curl_easy; struct curl_pollfds; struct curl_waitfds; struct Curl_multi; +struct Curl_share; -struct connshutdowns { - struct Curl_llist conn_list; /* The connectdata to shut down */ - BIT(iter_locked); /* TRUE while iterating the list */ -}; - -struct conncache { - struct Curl_hash hash; +/** + * Callback invoked when disconnecting connections. + * @param data transfer last handling the connection, not attached + * @param conn the connection to discard + * @param aborted if the connection is being aborted + * @return if the connection is being aborted, e.g. should NOT perform + * a shutdown and just close. + **/ +typedef bool Curl_cpool_disconnect_cb(struct Curl_easy *data, + struct connectdata *conn, + bool aborted); + +struct cpool { + /* the pooled connections, bundled per destination */ + struct Curl_hash dest2bundle; size_t num_conn; curl_off_t next_connection_id; curl_off_t next_easy_id; struct curltime last_cleanup; - struct connshutdowns shutdowns; - /* handle used for closing cached connections */ - struct Curl_easy *closure_handle; - struct Curl_multi *multi; /* Optional, set if cache belongs to multi */ + struct Curl_llist shutdowns; /* The connections being shut down */ + struct Curl_easy *idata; /* internal handle used for discard */ + struct Curl_multi *multi; /* != NULL iff pool belongs to multi */ + struct Curl_share *share; /* != NULL iff pool belongs to share */ + Curl_cpool_disconnect_cb *disconnect_cb; + BIT(locked); }; -#define BUNDLE_NO_MULTIUSE -1 -#define BUNDLE_UNKNOWN 0 /* initial value */ -#define BUNDLE_MULTIPLEX 2 - -#ifdef DEBUGBUILD -/* the debug versions of these macros make extra certain that the lock is - never doubly locked or unlocked */ -#define CONNCACHE_LOCK(x) \ - do { \ - if((x)->share) { \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, \ - CURL_LOCK_ACCESS_SINGLE); \ - DEBUGASSERT(!(x)->state.conncache_lock); \ - (x)->state.conncache_lock = TRUE; \ - } \ - } while(0) - -#define CONNCACHE_UNLOCK(x) \ - do { \ - if((x)->share) { \ - DEBUGASSERT((x)->state.conncache_lock); \ - (x)->state.conncache_lock = FALSE; \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ - } \ - } while(0) -#else -#define CONNCACHE_LOCK(x) if((x)->share) \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) -#define CONNCACHE_UNLOCK(x) if((x)->share) \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) -#endif - -struct connectbundle { - int multiuse; /* supports multi-use */ - size_t num_connections; /* Number of connections in the bundle */ - struct Curl_llist conn_list; /* The connectdata members of the bundle */ -}; - -/* Init the cache, pass multi only if cache is owned by it. +/* Init the pool, pass multi only if pool is owned by it. * returns 1 on error, 0 is fine. */ -int Curl_conncache_init(struct conncache *, - struct Curl_multi *multi, - size_t size); -void Curl_conncache_destroy(struct conncache *connc); - -/* return the correct bundle, to a host or a proxy */ -struct connectbundle *Curl_conncache_find_bundle(struct Curl_easy *data, - struct connectdata *conn, - struct conncache *connc); -/* returns number of connections currently held in the connection cache */ -size_t Curl_conncache_size(struct Curl_easy *data); - -bool Curl_conncache_return_conn(struct Curl_easy *data, - struct connectdata *conn); -CURLcode Curl_conncache_add_conn(struct Curl_easy *data) WARN_UNUSED_RESULT; -void Curl_conncache_remove_conn(struct Curl_easy *data, - struct connectdata *conn, - bool lock); -bool Curl_conncache_foreach(struct Curl_easy *data, - struct conncache *connc, - void *param, - int (*func)(struct Curl_easy *data, - struct connectdata *conn, - void *param)); - -struct connectdata * -Curl_conncache_find_first_connection(struct conncache *connc); - -struct connectdata * -Curl_conncache_extract_bundle(struct Curl_easy *data, - struct connectbundle *bundle); -struct connectdata * -Curl_conncache_extract_oldest(struct Curl_easy *data); -void Curl_conncache_close_all_connections(struct conncache *connc); -void Curl_conncache_print(struct conncache *connc); +int Curl_cpool_init(struct cpool *cpool, + Curl_cpool_disconnect_cb *disconnect_cb, + struct Curl_multi *multi, + struct Curl_share *share, + size_t size); + +/* Destroy all connections and free all members */ +void Curl_cpool_destroy(struct cpool *connc); + +/* Init the transfer to be used within its connection pool. + * Assigns `data->id`. */ +void Curl_cpool_xfer_init(struct Curl_easy *data); /** - * Tear down the connection. If `aborted` is FALSE, the connection - * will be shut down first before discarding. If the shutdown - * is not immediately complete, the connection - * will be placed into the cache is shutdown queue. + * Get the connection with the given id from the transfer's pool. */ -void Curl_conncache_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool aborted); +struct connectdata *Curl_cpool_get_conn(struct Curl_easy *data, + curl_off_t conn_id); + +CURLcode Curl_cpool_add_conn(struct Curl_easy *data, + struct connectdata *conn) WARN_UNUSED_RESULT; /** - * Add sockets and POLLIN/OUT flags for connections handled by the cache. + * Return if the pool has reached its configured limits for adding + * the given connection. Will try to discard the oldest, idle + * connections to make space. */ -CURLcode Curl_conncache_add_pollfds(struct conncache *connc, - struct curl_pollfds *cpfds); -CURLcode Curl_conncache_add_waitfds(struct conncache *connc, - struct curl_waitfds *cwfds); +#define CPOOL_LIMIT_OK 0 +#define CPOOL_LIMIT_DEST 1 +#define CPOOL_LIMIT_TOTAL 2 +int Curl_cpool_check_limits(struct Curl_easy *data, + struct connectdata *conn); + +/* Return of conn is suitable. If so, stops iteration. */ +typedef bool Curl_cpool_conn_match_cb(struct connectdata *conn, + void *userdata); + +/* Act on the result of the find, may override it. */ +typedef bool Curl_cpool_done_match_cb(bool result, void *userdata); + +/** + * Find a connection in the pool matching `destination`. + * All callbacks are invoked while the pool's lock is held. + * @param data current transfer + * @param destination match agaonst `conn->destination` in pool + * @param dest_len destination length, including terminating NUL + * @param conn_cb must be present, called for each connection in the + * bundle until it returns TRUE + * @param result_cb if not NULL, is called at the end with the result + * of the `conn_cb` or FALSE if never called. + * @return combined result of last conn_db and result_cb or FALSE if no + connections were present. + */ +bool Curl_cpool_find(struct Curl_easy *data, + const char *destination, size_t dest_len, + Curl_cpool_conn_match_cb *conn_cb, + Curl_cpool_done_match_cb *done_cb, + void *userdata); + +/* + * A connection (already in the pool) is now idle. Do any + * cleanups in regard to the pool's limits. + * + * Return TRUE if idle connection kept in pool, FALSE if closed. + */ +bool Curl_cpool_conn_now_idle(struct Curl_easy *data, + struct connectdata *conn); /** - * Perform maintenance on connections in the cache. Specifically, + * Remove the connection from the pool and tear it down. + * If `aborted` is FALSE, the connection will be shut down first + * before closing and destroying it. + * If the shutdown is not immediately complete, the connection + * will be placed into the pool's shutdown queue. + */ +void Curl_cpool_disconnect(struct Curl_easy *data, + struct connectdata *conn, + bool aborted); + +/** + * This function scans the data's connection pool for half-open/dead + * connections, closes and removes them. + * The cleanup is done at most once per second. + * + * When called, this transfer has no connection attached. + */ +void Curl_cpool_prune_dead(struct Curl_easy *data); + +/** + * Perform upkeep actions on connections in the transfer's pool. + */ +CURLcode Curl_cpool_upkeep(void *data); + +typedef void Curl_cpool_conn_do_cb(struct connectdata *conn, + struct Curl_easy *data, + void *cbdata); + +/** + * Invoke the callback on the pool's connection with the + * given connection id (if it exists). + */ +void Curl_cpool_do_by_id(struct Curl_easy *data, + curl_off_t conn_id, + Curl_cpool_conn_do_cb *cb, void *cbdata); + +/** + * Invoked the callback for the given data + connection under the + * connection pool's lock. + * The callback is always invoked, even if the transfer has no connection + * pool associated. + */ +void Curl_cpool_do_locked(struct Curl_easy *data, + struct connectdata *conn, + Curl_cpool_conn_do_cb *cb, void *cbdata); + +/** + * Add sockets and POLLIN/OUT flags for connections handled by the pool. + */ +CURLcode Curl_cpool_add_pollfds(struct cpool *connc, + struct curl_pollfds *cpfds); +CURLcode Curl_cpool_add_waitfds(struct cpool *connc, + struct curl_waitfds *cwfds); + +/** + * Perform maintenance on connections in the pool. Specifically, * progress the shutdown of connections in the queue. */ -void Curl_conncache_multi_perform(struct Curl_multi *multi); +void Curl_cpool_multi_perform(struct Curl_multi *multi); + +void Curl_cpool_multi_socket(struct Curl_multi *multi, + curl_socket_t s, int ev_bitmask); -void Curl_conncache_multi_socket(struct Curl_multi *multi, - curl_socket_t s, int ev_bitmask); -void Curl_conncache_multi_close_all(struct Curl_multi *multi); #endif /* HEADER_CURL_CONNCACHE_H */ diff --git a/lib/connect.c b/lib/connect.c index 9b68f15da..fb785f275 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -208,31 +208,6 @@ bool Curl_shutdown_started(struct Curl_easy *data, int sockindex) return (pt->tv_sec > 0) || (pt->tv_usec > 0); } -/* Copies connection info into the transfer handle to make it available when - the transfer handle is no longer associated with the connection. */ -void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, - struct ip_quadruple *ip) -{ - if(ip) - data->info.primary = *ip; - else { - memset(&data->info.primary, 0, sizeof(data->info.primary)); - data->info.primary.remote_port = -1; - data->info.primary.local_port = -1; - } - data->info.conn_scheme = conn->handler->scheme; - /* conn_protocol can only provide "old" protocols */ - data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK; - data->info.conn_remote_port = conn->remote_port; - data->info.used_proxy = -#ifdef CURL_DISABLE_PROXY - 0 -#else - conn->bits.proxy -#endif - ; -} - static const struct Curl_addrinfo * addr_first_match(const struct Curl_addrinfo *addr, int family) { @@ -312,23 +287,6 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, return FALSE; } -struct connfind { - curl_off_t id_tofind; - struct connectdata *found; -}; - -static int conn_is_conn(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - struct connfind *f = (struct connfind *)param; - (void)data; - if(conn->connection_id == f->id_tofind) { - f->found = conn; - return 1; - } - return 0; -} - /* * Used to extract socket and connectdata struct for the most recent * transfer on the given Curl_easy. @@ -345,30 +303,19 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, * - that is associated with a multi handle, and whose connection * was detached with CURLOPT_CONNECT_ONLY */ - if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) { - struct connectdata *c; - struct connfind find; - find.id_tofind = data->state.lastconnect_id; - find.found = NULL; - - Curl_conncache_foreach(data, - data->share && (data->share->specifier - & (1<< CURL_LOCK_DATA_CONNECT))? - &data->share->conn_cache: - data->multi_easy? - &data->multi_easy->conn_cache: - &data->multi->conn_cache, &find, conn_is_conn); - - if(!find.found) { + if(data->state.lastconnect_id != -1) { + struct connectdata *conn; + + conn = Curl_cpool_get_conn(data, data->state.lastconnect_id); + if(!conn) { data->state.lastconnect_id = -1; return CURL_SOCKET_BAD; } - c = find.found; if(connp) /* only store this if the caller cares for it */ - *connp = c; - return c->sock[FIRSTSOCKET]; + *connp = conn; + return conn->sock[FIRSTSOCKET]; } return CURL_SOCKET_BAD; } @@ -634,7 +581,7 @@ static CURLcode baller_connect(struct Curl_cfilter *cf, baller->is_done = TRUE; } else if(Curl_timediff(*now, baller->started) >= baller->timeoutms) { - infof(data, "%s connect timeout after %" CURL_FORMAT_TIMEDIFF_T + infof(data, "%s connect timeout after %" FMT_TIMEDIFF_T "ms, move on!", baller->name, baller->timeoutms); #if defined(ETIMEDOUT) baller->error = ETIMEDOUT; @@ -725,7 +672,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, /* Nothing connected, check the time before we might * start new ballers or return ok. */ if((ongoing || not_started) && Curl_timeleft(data, &now, TRUE) < 0) { - failf(data, "Connection timeout after %" CURL_FORMAT_CURL_OFF_T " ms", + failf(data, "Connection timeout after %" FMT_OFF_T " ms", Curl_timediff(now, data->progress.t_startsingle)); return CURLE_OPERATION_TIMEDOUT; } @@ -748,8 +695,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, CURL_TRC_CF(data, cf, "%s done", baller->name); } else { - CURL_TRC_CF(data, cf, "%s starting (timeout=%" - CURL_FORMAT_TIMEDIFF_T "ms)", + CURL_TRC_CF(data, cf, "%s starting (timeout=%" FMT_TIMEDIFF_T "ms)", baller->name, baller->timeoutms); ++ongoing; ++added; @@ -794,7 +740,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, hostname = conn->host.name; failf(data, "Failed to connect to %s port %u after " - "%" CURL_FORMAT_TIMEDIFF_T " ms: %s", + "%" FMT_TIMEDIFF_T " ms: %s", hostname, conn->primary.remote_port, Curl_timediff(now, data->progress.t_startsingle), curl_easy_strerror(result)); @@ -821,9 +767,9 @@ static CURLcode start_connect(struct Curl_cfilter *cf, struct cf_he_ctx *ctx = cf->ctx; struct connectdata *conn = cf->conn; CURLcode result = CURLE_COULDNT_CONNECT; - int ai_family0, ai_family1; + int ai_family0 = 0, ai_family1 = 0; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - const struct Curl_addrinfo *addr0, *addr1; + const struct Curl_addrinfo *addr0 = NULL, *addr1 = NULL; if(timeout_ms < 0) { /* a precaution, no need to continue if time already is up */ @@ -842,33 +788,31 @@ static CURLcode start_connect(struct Curl_cfilter *cf, * the 2 connect attempt ballers to try different families, if possible. * */ - if(conn->ip_version == CURL_IPRESOLVE_WHATEVER) { - /* any IP version is allowed */ - ai_family0 = remotehost->addr? - remotehost->addr->ai_family : 0; + if(conn->ip_version == CURL_IPRESOLVE_V6) { #ifdef USE_IPV6 - ai_family1 = ai_family0 == AF_INET6 ? - AF_INET : AF_INET6; -#else - ai_family1 = AF_UNSPEC; + ai_family0 = AF_INET6; + addr0 = addr_first_match(remotehost->addr, ai_family0); #endif } + else if(conn->ip_version == CURL_IPRESOLVE_V4) { + ai_family0 = AF_INET; + addr0 = addr_first_match(remotehost->addr, ai_family0); + } else { - /* only one IP version is allowed */ - ai_family0 = (conn->ip_version == CURL_IPRESOLVE_V4) ? - AF_INET : -#ifdef USE_IPV6 - AF_INET6; -#else - AF_UNSPEC; -#endif - ai_family1 = AF_UNSPEC; + /* no user preference, we try ipv6 always first when available */ + ai_family0 = AF_INET6; + addr0 = addr_first_match(remotehost->addr, ai_family0); + /* next candidate is ipv4 */ + ai_family1 = AF_INET; + addr1 = addr_first_match(remotehost->addr, ai_family1); + /* no ip address families, probably AF_UNIX or something, use the + * address family given to us */ + if(!addr1 && !addr0 && remotehost->addr) { + ai_family0 = remotehost->addr->ai_family; + addr0 = addr_first_match(remotehost->addr, ai_family0); + } } - /* Get the first address in the list that matches the family, - * this might give NULL, if we do not have any matches. */ - addr0 = addr_first_match(remotehost->addr, ai_family0); - addr1 = addr_first_match(remotehost->addr, ai_family1); if(!addr0 && addr1) { /* switch around, so a single baller always uses addr0 */ addr0 = addr1; @@ -887,8 +831,7 @@ static CURLcode start_connect(struct Curl_cfilter *cf, timeout_ms, EXPIRE_DNS_PER_NAME); if(result) return result; - CURL_TRC_CF(data, cf, "created %s (timeout %" - CURL_FORMAT_TIMEDIFF_T "ms)", + CURL_TRC_CF(data, cf, "created %s (timeout %" FMT_TIMEDIFF_T "ms)", ctx->baller[0]->name, ctx->baller[0]->timeoutms); if(addr1) { /* second one gets a delayed start */ @@ -899,8 +842,7 @@ static CURLcode start_connect(struct Curl_cfilter *cf, timeout_ms, EXPIRE_DNS_PER_NAME2); if(result) return result; - CURL_TRC_CF(data, cf, "created %s (timeout %" - CURL_FORMAT_TIMEDIFF_T "ms)", + CURL_TRC_CF(data, cf, "created %s (timeout %" FMT_TIMEDIFF_T "ms)", ctx->baller[1]->name, ctx->baller[1]->timeoutms); Curl_expire(data, data->set.happy_eyeballs_timeout, EXPIRE_HAPPY_EYEBALLS); @@ -1020,8 +962,6 @@ static CURLcode cf_he_connect(struct Curl_cfilter *cf, cf->next = ctx->winner->cf; ctx->winner->cf = NULL; cf_he_ctx_clear(cf, data); - Curl_conn_cf_cntrl(cf->next, data, TRUE, - CF_CTRL_CONN_INFO_UPDATE, 0, NULL); if(cf->conn->handler->protocol & PROTO_FAMILY_SSH) Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ diff --git a/lib/connect.h b/lib/connect.h index e9a4f9c59..160db9420 100644 --- a/lib/connect.h +++ b/lib/connect.h @@ -72,9 +72,6 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, char *addr, int *port); -void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, - struct ip_quadruple *ip); - /* * Curl_conncontrol() marks the end of a connection/stream. The 'closeit' * argument specifies if it is the end of a connection or a stream. diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 4dae41a89..c0b97f1f7 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -79,7 +79,7 @@ #define GZIP_MAGIC_1 0x8b /* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original filename present */ @@ -909,18 +909,18 @@ static CURLcode error_do_write(struct Curl_easy *data, struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { - char all[256]; - (void)Curl_all_content_encodings(all, sizeof(all)); - (void) writer; (void) buf; (void) nbytes; if(!(type & CLIENTWRITE_BODY) || !nbytes) return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - failf(data, "Unrecognized content encoding type. " - "libcurl understands %s content encodings.", all); + else { + char all[256]; + (void)Curl_all_content_encodings(all, sizeof(all)); + failf(data, "Unrecognized content encoding type. " + "libcurl understands %s content encodings.", all); + } return CURLE_BAD_CONTENT_ENCODING; } diff --git a/lib/cookie.c b/lib/cookie.c index b0d8d84be..95ca4a100 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -1028,6 +1028,8 @@ Curl_cookie_add(struct Curl_easy *data, * must also check that the data handle is not NULL since the psl code will * dereference it. */ + DEBUGF(infof(data, "PSL check set-cookie '%s' for domain=%s in %s", + co->name, co->domain, domain)); if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) { bool acceptable = FALSE; char lcase[256]; @@ -1054,6 +1056,9 @@ Curl_cookie_add(struct Curl_easy *data, return NULL; } } +#else + DEBUGF(infof(data, "NO PSL to check set-cookie '%s' for domain=%s in %s", + co->name, co->domain, domain)); #endif /* A non-secure cookie may not overlay an existing secure cookie. */ @@ -1165,7 +1170,7 @@ Curl_cookie_add(struct Curl_easy *data, if(c->running) /* Only show this when NOT reading the cookies from a file */ infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, " - "expire %" CURL_FORMAT_CURL_OFF_T, + "expire %" FMT_OFF_T, replace_old?"Replaced":"Added", co->name, co->value, co->domain, co->path, co->expires); @@ -1584,7 +1589,7 @@ static char *get_netscape_format(const struct Cookie *co) "%s\t" /* tailmatch */ "%s\t" /* path */ "%s\t" /* secure */ - "%" CURL_FORMAT_CURL_OFF_T "\t" /* expires */ + "%" FMT_OFF_T "\t" /* expires */ "%s\t" /* name */ "%s", /* value */ co->httponly?"#HttpOnly_":"", diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c index d290d7da1..44e10e9c9 100644 --- a/lib/curl_addrinfo.c +++ b/lib/curl_addrinfo.c @@ -571,7 +571,7 @@ curl_dbg_getaddrinfo(const char *hostname, #if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS) /* - * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X + * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and macOS * 10.11.5. */ void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port) diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index 631ee27b3..d803885b3 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -89,6 +89,9 @@ /* disables HTTP */ #cmakedefine CURL_DISABLE_HTTP 1 +/* disabled all HTTP authentication methods */ +#cmakedefine CURL_DISABLE_HTTP_AUTH 1 + /* disables IMAP */ #cmakedefine CURL_DISABLE_IMAP 1 @@ -131,6 +134,12 @@ /* disables RTSP */ #cmakedefine CURL_DISABLE_RTSP 1 +/* disables SHA-512/256 hash algorithm */ +#cmakedefine CURL_DISABLE_SHA512_256 1 + +/* disabled shuffle DNS feature */ +#cmakedefine CURL_DISABLE_SHUFFLE_DNS 1 + /* disables SMB */ #cmakedefine CURL_DISABLE_SMB 1 @@ -304,9 +313,6 @@ /* if you have the GNU gssapi libraries */ #cmakedefine HAVE_GSSGNU 1 -/* Define to 1 if you have the `idna_strerror' function. */ -#cmakedefine HAVE_IDNA_STRERROR 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_IFADDRS_H 1 @@ -632,9 +638,6 @@ /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} -/* a suitable file to read random data from */ -#cmakedefine RANDOM_FILE "${RANDOM_FILE}" - /* Note: SIZEOF_* variables are fetched with CMake through check_type_size(). As per CMake documentation on CheckTypeSize, C preprocessor code is @@ -677,7 +680,7 @@ ${SIZEOF_TIME_T_CODE} /* Define if you want to enable POSIX threaded DNS lookup */ #cmakedefine USE_THREADS_POSIX 1 -/* Define if you want to enable WIN32 threaded DNS lookup */ +/* Define if you want to enable Win32 threaded DNS lookup */ #cmakedefine USE_THREADS_WIN32 1 /* if GnuTLS is enabled */ @@ -692,6 +695,9 @@ ${SIZEOF_TIME_T_CODE} /* if BearSSL is enabled */ #cmakedefine USE_BEARSSL 1 +/* if Rustls is enabled */ +#cmakedefine USE_RUSTLS 1 + /* if wolfSSL is enabled */ #cmakedefine USE_WOLFSSL 1 @@ -707,6 +713,9 @@ ${SIZEOF_TIME_T_CODE} /* if libssh2 is in use */ #cmakedefine USE_LIBSSH2 1 +/* if wolfssh is in use */ +#cmakedefine USE_WOLFSSH 1 + /* if libpsl is in use */ #cmakedefine USE_LIBPSL 1 @@ -722,6 +731,12 @@ ${SIZEOF_TIME_T_CODE} /* if GSASL is in use */ #cmakedefine USE_GSASL 1 +/* if libuv is in use */ +#cmakedefine USE_LIBUV 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UV_H 1 + /* Define to 1 if you do not want the OpenSSL configuration to be loaded automatically */ #cmakedefine CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG 1 @@ -765,11 +780,6 @@ ${SIZEOF_TIME_T_CODE} /* Version number of package */ #cmakedefine VERSION ${VERSION} -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - /* Number of bits in a file offset, on hosts where this is settable. */ #cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in index 7871ac147..3e91a8124 100644 --- a/lib/curl_config.h.in +++ b/lib/curl_config.h.in @@ -9,7 +9,7 @@ /* Location of default ca bundle */ #undef CURL_CA_BUNDLE -/* define "1" to use built in CA store of SSL library */ +/* define "1" to use built-in CA store of SSL library */ #undef CURL_CA_FALLBACK /* Location of default ca path */ @@ -120,6 +120,9 @@ /* to disable RTSP */ #undef CURL_DISABLE_RTSP +/* disable SHA-512/256 hash algorithm */ +#undef CURL_DISABLE_SHA512_256 + /* disable DNS shuffling */ #undef CURL_DISABLE_SHUFFLE_DNS @@ -487,9 +490,6 @@ /* if you have opendir */ #undef HAVE_OPENDIR -/* Define to 1 if using OpenSSL 3 or later. */ -#undef HAVE_OPENSSL3 - /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_CRYPTO_H @@ -499,9 +499,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_PEM_H -/* if you have the functions OSSL_QUIC_client_method */ -#undef HAVE_OPENSSL_QUIC - /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RSA_H @@ -729,6 +726,9 @@ /* Define this if time_t is unsigned */ #undef HAVE_TIME_T_UNSIGNED +/* Define to 1 if you have the header file. */ +#undef HAVE_UNICODE_UIDNA_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -741,6 +741,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H +/* Define to 1 if you have the header file. */ +#undef HAVE_UV_H + /* Define to 1 if you have the header file. */ #undef HAVE_WOLFSSH_SSH_H @@ -810,9 +813,6 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* a suitable file to read random data from */ -#undef RANDOM_FILE - /* Size of curl_off_t in number of bytes */ #undef SIZEOF_CURL_OFF_T @@ -845,6 +845,9 @@ /* if AmiSSL is in use */ #undef USE_AMISSL +/* if AppleIDN */ +#undef USE_APPLE_IDN + /* Define to enable c-ares support */ #undef USE_ARES @@ -881,8 +884,8 @@ /* if libssh2 is in use */ #undef USE_LIBSSH2 -/* If you want to build curl with the built-in manual */ -#undef USE_MANUAL +/* if libuv is in use */ +#undef USE_LIBUV /* if mbedTLS is enabled */ #undef USE_MBEDTLS @@ -929,7 +932,7 @@ /* if quiche is in use */ #undef USE_QUICHE -/* if rustls is enabled */ +/* if Rustls is enabled */ #undef USE_RUSTLS /* to enable Windows native SSL/TLS support */ @@ -950,7 +953,7 @@ /* Use Unix domain sockets */ #undef USE_UNIX_SOCKETS -/* enable websockets support */ +/* enable WebSockets support */ #undef USE_WEBSOCKETS /* Define to 1 if you are building a Windows target with crypto API support. diff --git a/lib/curl_des.c b/lib/curl_des.c index 9662ba39a..15836f58b 100644 --- a/lib/curl_des.c +++ b/lib/curl_des.c @@ -24,10 +24,10 @@ #include "curl_setup.h" -#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \ - (defined(USE_GNUTLS) || \ - defined(USE_SECTRANSP) || \ - defined(USE_OS400CRYPTO) || \ +#if defined(USE_CURL_NTLM_CORE) && \ + (defined(USE_GNUTLS) || \ + defined(USE_SECTRANSP) || \ + defined(USE_OS400CRYPTO) || \ defined(USE_WIN32_CRYPTO)) #include "curl_des.h" diff --git a/lib/curl_des.h b/lib/curl_des.h index 66525ab43..2dd498da2 100644 --- a/lib/curl_des.h +++ b/lib/curl_des.h @@ -26,10 +26,10 @@ #include "curl_setup.h" -#if defined(USE_CURL_NTLM_CORE) && !defined(USE_WOLFSSL) && \ - (defined(USE_GNUTLS) || \ - defined(USE_SECTRANSP) || \ - defined(USE_OS400CRYPTO) || \ +#if defined(USE_CURL_NTLM_CORE) && \ + (defined(USE_GNUTLS) || \ + defined(USE_SECTRANSP) || \ + defined(USE_OS400CRYPTO) || \ defined(USE_WIN32_CRYPTO)) /* Applies odd parity to the given byte array */ diff --git a/lib/curl_fnmatch.h b/lib/curl_fnmatch.h index 595646ff0..b8c2a4353 100644 --- a/lib/curl_fnmatch.h +++ b/lib/curl_fnmatch.h @@ -31,7 +31,7 @@ /* default pattern matching function * ================================= * Implemented with recursive backtracking, if you want to use Curl_fnmatch, - * please note that there is not implemented UTF/UNICODE support. + * please note that there is not implemented UTF/Unicode support. * * Implemented features: * '?' notation, does not match UTF characters diff --git a/lib/curl_gethostname.c b/lib/curl_gethostname.c index cd111231d..617a8ad52 100644 --- a/lib/curl_gethostname.c +++ b/lib/curl_gethostname.c @@ -39,15 +39,6 @@ * * Note: The function always returns the un-qualified hostname rather * than being provider dependent. - * - * For libcurl shared library release builds the test suite preloads - * another shared library named libhostname using the LD_PRELOAD - * mechanism which intercepts, and might override, the gethostname() - * function call. In this case a given platform must support the - * LD_PRELOAD mechanism and additionally have environment variable - * CURL_GETHOSTNAME set in order to override the returned hostname. - * - * For libcurl static library release builds no overriding takes place. */ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) @@ -68,7 +59,10 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) /* Override hostname when environment variable CURL_GETHOSTNAME is set */ const char *force_hostname = getenv("CURL_GETHOSTNAME"); if(force_hostname) { - strncpy(name, force_hostname, namelen - 1); + if(strlen(force_hostname) < (size_t)namelen) + strcpy(name, force_hostname); + else + return 1; /* can't do it */ err = 0; } else { @@ -78,9 +72,6 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) #else /* DEBUGBUILD */ - /* The call to system's gethostname() might get intercepted by the - libhostname library when libcurl is built as a non-debug shared - library when running the test suite. */ name[0] = '\0'; err = gethostname(name, namelen); diff --git a/lib/curl_multibyte.h b/lib/curl_multibyte.h index 2d31c28f4..dec384e2f 100644 --- a/lib/curl_multibyte.h +++ b/lib/curl_multibyte.h @@ -39,12 +39,12 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8() * and curlx_unicodefree() main purpose is to minimize the number of * preprocessor conditional directives needed by code using these - * to differentiate UNICODE from non-UNICODE builds. + * to differentiate Unicode from non-Unicode builds. * - * In the case of a non-UNICODE build the tchar strings are char strings that + * In the case of a non-Unicode build the tchar strings are char strings that * are duplicated via strdup and remain in whatever the passed in encoding is, * which is assumed to be UTF-8 but may be other encoding. Therefore the - * significance of the conversion functions is primarily for UNICODE builds. + * significance of the conversion functions is primarily for Unicode builds. * * Allocated memory should be free'd with curlx_unicodefree(). * diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c index 62628c04e..eee33afe5 100644 --- a/lib/curl_ntlm_core.c +++ b/lib/curl_ntlm_core.c @@ -57,9 +57,14 @@ #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) #define USE_OPENSSL_DES #endif +#elif defined(USE_WOLFSSL) + #include + #if !defined(NO_DES3) + #define USE_OPENSSL_DES + #endif #endif -#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) +#if defined(USE_OPENSSL_DES) #if defined(USE_OPENSSL) # include @@ -67,7 +72,6 @@ # include # include #else -# include # include # include # include @@ -148,7 +152,7 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key) } #endif -#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) +#if defined(USE_OPENSSL_DES) /* * Turns a 56-bit key into a 64-bit, odd parity key and sets the key. The * key schedule ks is also set. @@ -313,7 +317,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, const unsigned char *plaintext, unsigned char *results) { -#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) +#if defined(USE_OPENSSL_DES) DES_key_schedule ks; setup_des_key(keys, DESKEY(ks)); @@ -367,7 +371,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, { /* Create LanManager hashed password. */ -#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) +#if defined(USE_OPENSSL_DES) DES_key_schedule ks; setup_des_key(pw, DESKEY(ks)); @@ -534,13 +538,13 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, /* * Curl_ntlm_core_mk_ntlmv2_resp() * - * This creates the NTLMv2 response as set in the ntlm type-3 message. + * This creates the NTLMv2 response as set in the NTLM type-3 message. * * Parameters: * - * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) + * ntlmv2hash [in] - The NTLMv2 hash (16 bytes) * challenge_client [in] - The client nonce (8 bytes) - * ntlm [in] - The ntlm data struct being used to read TargetInfo + * ntlm [in] - The NTLM data struct being used to read TargetInfo and Server challenge received in the type-2 message * ntresp [out] - The address where a pointer to newly allocated * memory holding the NTLMv2 response. @@ -629,11 +633,11 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, /* * Curl_ntlm_core_mk_lmv2_resp() * - * This creates the LMv2 response as used in the ntlm type-3 message. + * This creates the LMv2 response as used in the NTLM type-3 message. * * Parameters: * - * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) + * ntlmv2hash [in] - The NTLMv2 hash (16 bytes) * challenge_client [in] - The client nonce (8 bytes) * challenge_client [in] - The server challenge (8 bytes) * lmresp [out] - The LMv2 response (24 bytes) @@ -657,7 +661,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, if(result) return result; - /* Concatenate the HMAC MD5 output with the client nonce */ + /* Concatenate the HMAC MD5 output with the client nonce */ memcpy(lmresp, hmac_output, 16); memcpy(lmresp + 16, challenge_client, 8); diff --git a/lib/curl_printf.h b/lib/curl_printf.h index c2457d2a6..e851b14a5 100644 --- a/lib/curl_printf.h +++ b/lib/curl_printf.h @@ -29,6 +29,10 @@ * *rintf() functions. */ +#ifndef CURL_TEMP_PRINTF +#error "CURL_TEMP_PRINTF must be set before including curl/mprintf.h" +#endif + #include #define MERR_OK 0 @@ -40,7 +44,6 @@ # undef msnprintf # undef vprintf # undef vfprintf -# undef vsnprintf # undef mvsnprintf # undef aprintf # undef vaprintf diff --git a/lib/curl_range.c b/lib/curl_range.c index d499953c9..49fb5f077 100644 --- a/lib/curl_range.c +++ b/lib/curl_range.c @@ -55,15 +55,13 @@ CURLcode Curl_range(struct Curl_easy *data) if((to_t == CURL_OFFT_INVAL) && !from_t) { /* X - */ data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file", - from)); + DEBUGF(infof(data, "RANGE %" FMT_OFF_T " to end of file", from)); } else if((from_t == CURL_OFFT_INVAL) && !to_t) { /* -Y */ data->req.maxdownload = to; data->state.resume_from = -to; - DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes", - to)); + DEBUGF(infof(data, "RANGE the last %" FMT_OFF_T " bytes", to)); } else { /* X-Y */ @@ -79,13 +77,12 @@ CURLcode Curl_range(struct Curl_easy *data) data->req.maxdownload = totalsize + 1; /* include last byte */ data->state.resume_from = from; - DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes", + DEBUGF(infof(data, "RANGE from %" FMT_OFF_T + " getting %" FMT_OFF_T " bytes", from, data->req.maxdownload)); } - DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T - " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes", + DEBUGF(infof(data, "range-download from %" FMT_OFF_T + " to %" FMT_OFF_T ", totally %" FMT_OFF_T " bytes", from, to, data->req.maxdownload)); } else diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 54d4f979f..49f59e3a7 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -329,13 +329,14 @@ static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf, } static ssize_t rtmp_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, CURLcode *err) { struct connectdata *conn = data->conn; RTMP *r = conn->proto.rtmp; ssize_t num; (void)sockindex; /* unused */ + (void)eos; /* unused */ num = RTMP_Write(r, (char *)buf, curlx_uztosi(len)); if(num < 0) diff --git a/lib/curl_setup.h b/lib/curl_setup.h index c8dba5e2b..930d02a11 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -28,6 +28,9 @@ #define CURL_NO_OLDIES #endif +/* Tell "curl/curl.h" not to include "curl/mprintf.h" */ +#define CURL_SKIP_INCLUDE_MPRINTF + /* FIXME: Delete this once the warnings have been fixed. */ #if !defined(CURL_WARN_SIGN_CONVERSION) #ifdef __GNUC__ @@ -319,7 +322,7 @@ /* curl uses its own printf() function internally. It understands the GNU * format. Use this format, so that is matches the GNU format attribute we - * use with the mingw compiler, allowing it to verify them at compile-time. + * use with the MinGW compiler, allowing it to verify them at compile-time. */ #ifdef __MINGW32__ # undef CURL_FORMAT_CURL_OFF_T @@ -345,6 +348,9 @@ #define CURL_PRINTF(fmt, arg) #endif +/* Override default printf mask check rules in "curl/mprintf.h" */ +#define CURL_TEMP_PRINTF CURL_PRINTF + /* Workaround for mainline llvm v16 and earlier missing a built-in macro expected by macOS SDK v14 / Xcode v15 (2023) and newer. gcc (as of v14) is also missing it. */ @@ -444,7 +450,7 @@ #endif /* - * Large file (>2Gb) support using WIN32 functions. + * Large file (>2Gb) support using Win32 functions. */ #ifdef USE_WIN32_LARGE_FILES @@ -467,7 +473,7 @@ #endif /* - * Small file (<2Gb) support using WIN32 functions. + * Small file (<2Gb) support using Win32 functions. */ #ifdef USE_WIN32_SMALL_FILES @@ -513,11 +519,11 @@ #endif #if SIZEOF_CURL_SOCKET_T < 8 -# define CURL_FORMAT_SOCKET_T "d" +# define FMT_SOCKET_T "d" #elif defined(__MINGW32__) -# define CURL_FORMAT_SOCKET_T "zd" +# define FMT_SOCKET_T "zd" #else -# define CURL_FORMAT_SOCKET_T "qd" +# define FMT_SOCKET_T "qd" #endif /* @@ -565,10 +571,13 @@ # endif # define CURL_UINT64_SUFFIX CURL_SUFFIX_CURL_OFF_TU # define CURL_UINT64_C(val) CURL_CONC_MACROS(val,CURL_UINT64_SUFFIX) -# define CURL_PRId64 CURL_FORMAT_CURL_OFF_T -# define CURL_PRIu64 CURL_FORMAT_CURL_OFF_TU +# define FMT_PRId64 CURL_FORMAT_CURL_OFF_T +# define FMT_PRIu64 CURL_FORMAT_CURL_OFF_TU #endif +#define FMT_OFF_T CURL_FORMAT_CURL_OFF_T +#define FMT_OFF_TU CURL_FORMAT_CURL_OFF_TU + #if (SIZEOF_TIME_T == 4) # ifdef HAVE_TIME_T_UNSIGNED # define TIME_T_MAX UINT_MAX @@ -715,6 +724,11 @@ #define USE_SSL /* SSL support has been enabled */ #endif +#if defined(USE_WOLFSSL) && defined(USE_GNUTLS) +/* Avoid defining unprefixed wolfSSL SHA macros colliding with nettle ones */ +#define NO_OLD_WC_NAMES +#endif + /* Single point where USE_SPNEGO definition might be defined */ #if !defined(CURL_DISABLE_NEGOTIATE_AUTH) && \ (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) @@ -816,7 +830,7 @@ #if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H) # if defined(SOCKET) || defined(USE_WINSOCK) -# error "WinSock and lwIP TCP/IP stack definitions shall not coexist!" +# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" # endif #endif @@ -854,7 +868,7 @@ Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 #define FOPEN_WRITETEXT "wt" #define FOPEN_APPENDTEXT "at" #elif defined(__CYGWIN__) -/* Cygwin has specific behavior we need to address when WIN32 is not defined. +/* Cygwin has specific behavior we need to address when _WIN32 is not defined. https://cygwin.com/cygwin-ug-net/using-textbinary.html For write we want our output to have line endings of LF and be compatible with other Cygwin utilities. For read we want to handle input that may have line diff --git a/lib/curl_sha256.h b/lib/curl_sha256.h index d99f958f9..c3cf00a21 100644 --- a/lib/curl_sha256.h +++ b/lib/curl_sha256.h @@ -33,13 +33,8 @@ extern const struct HMAC_params Curl_HMAC_SHA256[1]; -#ifdef USE_WOLFSSL -/* SHA256_DIGEST_LENGTH is an enum value in wolfSSL. Need to import it from - * sha.h */ -#include -#include -#else -#define SHA256_DIGEST_LENGTH 32 +#ifndef CURL_SHA256_DIGEST_LENGTH +#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ #endif CURLcode Curl_sha256it(unsigned char *outbuffer, const unsigned char *input, diff --git a/lib/curl_sha512_256.c b/lib/curl_sha512_256.c index e3533d8fc..576eda244 100644 --- a/lib/curl_sha512_256.c +++ b/lib/curl_sha512_256.c @@ -37,7 +37,7 @@ * * SecureTransport (Darwin) * * mbedTLS * * BearSSL - * * rustls + * * Rustls * Skip the backend if it does not support the required algorithm */ #if defined(USE_OPENSSL) @@ -93,13 +93,13 @@ /** * Size of the SHA-512/256 single processing block in bytes. */ -#define SHA512_256_BLOCK_SIZE 128 +#define CURL_SHA512_256_BLOCK_SIZE 128 /** * Size of the SHA-512/256 resulting digest in bytes. * This is the final digest size, not intermediate hash. */ -#define SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_LENGTH +#define CURL_SHA512_256_DIGEST_SIZE CURL_SHA512_256_DIGEST_LENGTH /** * Context type used for SHA-512/256 calculations @@ -124,9 +124,9 @@ Curl_sha512_256_init(void *context) if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) { /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(EVP_MD_CTX_size(*ctx) == SHA512_256_DIGEST_SIZE); + DEBUGASSERT(EVP_MD_CTX_size(*ctx) == CURL_SHA512_256_DIGEST_SIZE); /* Check whether the block size is correct */ - DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == SHA512_256_BLOCK_SIZE); + DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == CURL_SHA512_256_BLOCK_SIZE); return CURLE_OK; /* Success */ } @@ -163,7 +163,8 @@ Curl_sha512_256_update(void *context, * Finalise SHA-512/256 calculation, return digest. * * @param context the calculation context - * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes + * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE + # bytes * @return CURLE_OK if succeed, * error code otherwise */ @@ -177,11 +178,11 @@ Curl_sha512_256_finish(unsigned char *digest, #ifdef NEED_NETBSD_SHA512_256_WORKAROUND /* Use a larger buffer to work around a bug in NetBSD: https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */ - unsigned char tmp_digest[SHA512_256_DIGEST_SIZE * 2]; + unsigned char tmp_digest[CURL_SHA512_256_DIGEST_SIZE * 2]; ret = EVP_DigestFinal_ex(*ctx, tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER; if(ret == CURLE_OK) - memcpy(digest, tmp_digest, SHA512_256_DIGEST_SIZE); + memcpy(digest, tmp_digest, CURL_SHA512_256_DIGEST_SIZE); explicit_memset(tmp_digest, 0, sizeof(tmp_digest)); #else /* ! NEED_NETBSD_SHA512_256_WORKAROUND */ ret = EVP_DigestFinal_ex(*ctx, digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER; @@ -195,6 +196,9 @@ Curl_sha512_256_finish(unsigned char *digest, #elif defined(USE_GNUTLS_SHA512_256) +#define CURL_SHA512_256_BLOCK_SIZE SHA512_256_BLOCK_SIZE +#define CURL_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE + /** * Context type used for SHA-512/256 calculations */ @@ -212,7 +216,7 @@ Curl_sha512_256_init(void *context) Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE); + DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); sha512_256_init(ctx); @@ -247,7 +251,8 @@ Curl_sha512_256_update(void *context, * Finalise SHA-512/256 calculation, return digest. * * @param context the calculation context - * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes + * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE + # bytes * @return always CURLE_OK */ static CURLcode @@ -256,7 +261,8 @@ Curl_sha512_256_finish(unsigned char *digest, { Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; - sha512_256_digest(ctx, (size_t)SHA512_256_DIGEST_SIZE, (uint8_t *)digest); + sha512_256_digest(ctx, + (size_t)CURL_SHA512_256_DIGEST_SIZE, (uint8_t *)digest); return CURLE_OK; } @@ -360,7 +366,7 @@ MHDx_rotr64(curl_uint64_t value, unsigned int bits) * Size of the SHA-512/256 resulting digest in bytes * This is the final digest size, not intermediate hash. */ -#define SHA512_256_DIGEST_SIZE \ +#define CURL_SHA512_256_DIGEST_SIZE \ (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD) /** @@ -371,7 +377,7 @@ MHDx_rotr64(curl_uint64_t value, unsigned int bits) /** * Size of the SHA-512/256 single processing block in bytes. */ -#define SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8) +#define CURL_SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8) /** * Size of the SHA-512/256 single processing block in words. @@ -425,7 +431,7 @@ MHDx_sha512_256_init(void *context) struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *) context; /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE); + DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); DEBUGASSERT(sizeof(curl_uint64_t) == 8); @@ -453,7 +459,7 @@ MHDx_sha512_256_init(void *context) * Base of the SHA-512/256 transformation. * Gets a full 128 bytes block of data and updates hash values; * @param H hash values - * @param data the data buffer with #SHA512_256_BLOCK_SIZE bytes block + * @param data the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block */ static void MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS], @@ -636,9 +642,9 @@ MHDx_sha512_256_update(void *context, if(0 == length) return CURLE_OK; /* Shortcut, do nothing */ - /* Note: (count & (SHA512_256_BLOCK_SIZE-1)) - equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ - bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1)); + /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) + equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ + bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); ctx->count += length; if(length > ctx->count) ctx->count_bits_hi += 1U << 3; /* Value wrap */ @@ -646,7 +652,7 @@ MHDx_sha512_256_update(void *context, ctx->count &= CURL_UINT64_C(0x1FFFFFFFFFFFFFFF); if(0 != bytes_have) { - unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have; + unsigned int bytes_left = CURL_SHA512_256_BLOCK_SIZE - bytes_have; if(length >= bytes_left) { /* Combine new data with data in the buffer and process the full block. */ @@ -660,12 +666,12 @@ MHDx_sha512_256_update(void *context, } } - while(SHA512_256_BLOCK_SIZE <= length) { + while(CURL_SHA512_256_BLOCK_SIZE <= length) { /* Process any full blocks of new data directly, without copying to the buffer. */ MHDx_sha512_256_transform(ctx->H, data); - data += SHA512_256_BLOCK_SIZE; - length -= SHA512_256_BLOCK_SIZE; + data += CURL_SHA512_256_BLOCK_SIZE; + length -= CURL_SHA512_256_BLOCK_SIZE; } if(0 != length) { @@ -694,7 +700,8 @@ MHDx_sha512_256_update(void *context, * Finalise SHA-512/256 calculation, return digest. * * @param context the calculation context - * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes + * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE + # bytes * @return always CURLE_OK */ static CURLcode @@ -712,9 +719,9 @@ MHDx_sha512_256_finish(unsigned char *digest, not change the amount of hashed data. */ num_bits = ctx->count << 3; - /* Note: (count & (SHA512_256_BLOCK_SIZE-1)) - equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ - bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1)); + /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) + equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ + bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); /* Input data must be padded with a single bit "1", then with zeros and the finally the length of data in bits must be added as the final bytes @@ -728,12 +735,12 @@ MHDx_sha512_256_finish(unsigned char *digest, processed when formed). */ ((unsigned char *) ctx_buf)[bytes_have++] = 0x80U; - if(SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) { + if(CURL_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) { /* No space in the current block to put the total length of message. Pad the current block with zeros and process it. */ - if(bytes_have < SHA512_256_BLOCK_SIZE) + if(bytes_have < CURL_SHA512_256_BLOCK_SIZE) memset(((unsigned char *) ctx_buf) + bytes_have, 0, - SHA512_256_BLOCK_SIZE - bytes_have); + CURL_SHA512_256_BLOCK_SIZE - bytes_have); /* Process the full block. */ MHDx_sha512_256_transform(ctx->H, ctx->buffer); /* Start the new block. */ @@ -742,17 +749,17 @@ MHDx_sha512_256_finish(unsigned char *digest, /* Pad the rest of the buffer with zeros. */ memset(((unsigned char *) ctx_buf) + bytes_have, 0, - SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); + CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); /* Put high part of number of bits in processed message and then lower part of number of bits as big-endian values. See FIPS PUB 180-4 section 5.1.2. */ /* Note: the target location is predefined and buffer is always aligned */ MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ - + SHA512_256_BLOCK_SIZE \ + + CURL_SHA512_256_BLOCK_SIZE \ - SHA512_256_SIZE_OF_LEN_ADD, \ ctx->count_bits_hi); MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ - + SHA512_256_BLOCK_SIZE \ + + CURL_SHA512_256_BLOCK_SIZE \ - SHA512_256_SIZE_OF_LEN_ADD \ + SHA512_256_BYTES_IN_WORD, \ num_bits); @@ -841,9 +848,9 @@ const struct HMAC_params Curl_HMAC_SHA512_256[] = { /* Context structure size. */ sizeof(Curl_sha512_256_ctx), /* Maximum key length (bytes). */ - SHA512_256_BLOCK_SIZE, + CURL_SHA512_256_BLOCK_SIZE, /* Result length (bytes). */ - SHA512_256_DIGEST_SIZE + CURL_SHA512_256_DIGEST_SIZE } }; diff --git a/lib/curl_sha512_256.h b/lib/curl_sha512_256.h index 30a9f140e..a84e77bc3 100644 --- a/lib/curl_sha512_256.h +++ b/lib/curl_sha512_256.h @@ -33,7 +33,7 @@ extern const struct HMAC_params Curl_HMAC_SHA512_256[1]; -#define SHA512_256_DIGEST_LENGTH 32 +#define CURL_SHA512_256_DIGEST_LENGTH 32 CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input, diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 2c9e38d90..680bb661b 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -52,10 +52,10 @@ typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID); #endif /* Handle of security.dll or secur32.dll, depending on Windows version */ -HMODULE s_hSecDll = NULL; +HMODULE Curl_hSecDll = NULL; /* Pointer to SSPI dispatch table */ -PSecurityFunctionTable s_pSecFn = NULL; +PSecurityFunctionTable Curl_pSecFn = NULL; /* * Curl_sspi_global_init() @@ -79,29 +79,29 @@ CURLcode Curl_sspi_global_init(void) INITSECURITYINTERFACE_FN pInitSecurityInterface; /* If security interface is not yet initialized try to do this */ - if(!s_hSecDll) { + if(!Curl_hSecDll) { /* Security Service Provider Interface (SSPI) functions are located in * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP * have both these DLLs (security.dll forwards calls to secur32.dll) */ /* Load SSPI dll into the address space of the calling process */ if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL)) - s_hSecDll = Curl_load_library(TEXT("security.dll")); + Curl_hSecDll = Curl_load_library(TEXT("security.dll")); else - s_hSecDll = Curl_load_library(TEXT("secur32.dll")); - if(!s_hSecDll) + Curl_hSecDll = Curl_load_library(TEXT("secur32.dll")); + if(!Curl_hSecDll) return CURLE_FAILED_INIT; /* Get address of the InitSecurityInterfaceA function from the SSPI dll */ pInitSecurityInterface = CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN, - (GetProcAddress(s_hSecDll, SECURITYENTRYPOINT))); + (GetProcAddress(Curl_hSecDll, SECURITYENTRYPOINT))); if(!pInitSecurityInterface) return CURLE_FAILED_INIT; /* Get pointer to Security Service Provider Interface dispatch table */ - s_pSecFn = pInitSecurityInterface(); - if(!s_pSecFn) + Curl_pSecFn = pInitSecurityInterface(); + if(!Curl_pSecFn) return CURLE_FAILED_INIT; } @@ -119,10 +119,10 @@ CURLcode Curl_sspi_global_init(void) */ void Curl_sspi_global_cleanup(void) { - if(s_hSecDll) { - FreeLibrary(s_hSecDll); - s_hSecDll = NULL; - s_pSecFn = NULL; + if(Curl_hSecDll) { + FreeLibrary(Curl_hSecDll); + Curl_hSecDll = NULL; + Curl_pSecFn = NULL; } } diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h index b26c39156..535a1ff65 100644 --- a/lib/curl_sspi.h +++ b/lib/curl_sspi.h @@ -57,8 +57,8 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity); /* Forward-declaration of global variables defined in curl_sspi.c */ -extern HMODULE s_hSecDll; -extern PSecurityFunctionTable s_pSecFn; +extern HMODULE Curl_hSecDll; +extern PSecurityFunctionTable Curl_pSecFn; /* Provide some definitions missing in old headers */ #define SP_NAME_DIGEST "WDigest" diff --git a/lib/curl_threads.c b/lib/curl_threads.c index fb4af73d0..6d73273f7 100644 --- a/lib/curl_threads.c +++ b/lib/curl_threads.c @@ -35,7 +35,9 @@ #endif #include "curl_threads.h" +#ifdef BUILDING_LIBCURL #include "curl_memory.h" +#endif /* The last #include file should be: */ #include "memdebug.h" diff --git a/lib/curl_trc.c b/lib/curl_trc.c index f017e21a5..58512d74d 100644 --- a/lib/curl_trc.c +++ b/lib/curl_trc.c @@ -53,6 +53,9 @@ #include "curl_memory.h" #include "memdebug.h" +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif void Curl_debug(struct Curl_easy *data, curl_infotype type, char *ptr, size_t size) @@ -118,10 +121,16 @@ static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat, const char * const fmt, va_list ap) { int len = 0; - char buffer[MAXINFO + 2]; + char buffer[MAXINFO + 5]; if(feat) - len = msnprintf(buffer, MAXINFO, "[%s] ", feat->name); - len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap); + len = msnprintf(buffer, (MAXINFO + 1), "[%s] ", feat->name); + len += mvsnprintf(buffer + len, (MAXINFO + 1) - len, fmt, ap); + if(len >= MAXINFO) { /* too long, shorten with '...' */ + --len; + buffer[len++] = '.'; + buffer[len++] = '.'; + buffer[len++] = '.'; + } buffer[len++] = '\n'; buffer[len] = '\0'; Curl_debug(data, CURLINFO_TEXT, buffer, len); @@ -212,58 +221,144 @@ void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...) } #endif /* !CURL_DISABLE_FTP */ -static struct curl_trc_feat *trc_feats[] = { - &Curl_trc_feat_read, - &Curl_trc_feat_write, +#ifndef CURL_DISABLE_SMTP +struct curl_trc_feat Curl_trc_feat_smtp = { + "SMTP", + CURL_LOG_LVL_NONE, +}; + +void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...) +{ + DEBUGASSERT(!strchr(fmt, '\n')); + if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) { + va_list ap; + va_start(ap, fmt); + trc_infof(data, &Curl_trc_feat_smtp, fmt, ap); + va_end(ap); + } +} +#endif /* !CURL_DISABLE_SMTP */ + +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) +struct curl_trc_feat Curl_trc_feat_ws = { + "WS", + CURL_LOG_LVL_NONE, +}; + +void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...) +{ + DEBUGASSERT(!strchr(fmt, '\n')); + if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) { + va_list ap; + va_start(ap, fmt); + trc_infof(data, &Curl_trc_feat_ws, fmt, ap); + va_end(ap); + } +} +#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */ + +#define TRC_CT_NONE (0) +#define TRC_CT_PROTOCOL (1<<(0)) +#define TRC_CT_NETWORK (1<<(1)) +#define TRC_CT_PROXY (1<<(2)) + +struct trc_feat_def { + struct curl_trc_feat *feat; + unsigned int category; +}; + +static struct trc_feat_def trc_feats[] = { + { &Curl_trc_feat_read, TRC_CT_NONE }, + { &Curl_trc_feat_write, TRC_CT_NONE }, #ifndef CURL_DISABLE_FTP - &Curl_trc_feat_ftp, + { &Curl_trc_feat_ftp, TRC_CT_PROTOCOL }, #endif #ifndef CURL_DISABLE_DOH - &Curl_doh_trc, + { &Curl_doh_trc, TRC_CT_NETWORK }, +#endif +#ifndef CURL_DISABLE_SMTP + { &Curl_trc_feat_smtp, TRC_CT_PROTOCOL }, #endif - NULL, +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) + { &Curl_trc_feat_ws, TRC_CT_PROTOCOL }, +#endif +}; + +struct trc_cft_def { + struct Curl_cftype *cft; + unsigned int category; }; -static struct Curl_cftype *cf_types[] = { - &Curl_cft_tcp, - &Curl_cft_udp, - &Curl_cft_unix, - &Curl_cft_tcp_accept, - &Curl_cft_happy_eyeballs, - &Curl_cft_setup, +static struct trc_cft_def trc_cfts[] = { + { &Curl_cft_tcp, TRC_CT_NETWORK }, + { &Curl_cft_udp, TRC_CT_NETWORK }, + { &Curl_cft_unix, TRC_CT_NETWORK }, + { &Curl_cft_tcp_accept, TRC_CT_NETWORK }, + { &Curl_cft_happy_eyeballs, TRC_CT_NETWORK }, + { &Curl_cft_setup, TRC_CT_PROTOCOL }, #ifdef USE_NGHTTP2 - &Curl_cft_nghttp2, + { &Curl_cft_nghttp2, TRC_CT_PROTOCOL }, #endif #ifdef USE_SSL - &Curl_cft_ssl, + { &Curl_cft_ssl, TRC_CT_NETWORK }, #ifndef CURL_DISABLE_PROXY - &Curl_cft_ssl_proxy, + { &Curl_cft_ssl_proxy, TRC_CT_PROXY }, #endif #endif #if !defined(CURL_DISABLE_PROXY) #if !defined(CURL_DISABLE_HTTP) - &Curl_cft_h1_proxy, + { &Curl_cft_h1_proxy, TRC_CT_PROXY }, #ifdef USE_NGHTTP2 - &Curl_cft_h2_proxy, + { &Curl_cft_h2_proxy, TRC_CT_PROXY }, #endif - &Curl_cft_http_proxy, + { &Curl_cft_http_proxy, TRC_CT_PROXY }, #endif /* !CURL_DISABLE_HTTP */ - &Curl_cft_haproxy, - &Curl_cft_socks_proxy, + { &Curl_cft_haproxy, TRC_CT_PROXY }, + { &Curl_cft_socks_proxy, TRC_CT_PROXY }, #endif /* !CURL_DISABLE_PROXY */ #ifdef USE_HTTP3 - &Curl_cft_http3, + { &Curl_cft_http3, TRC_CT_PROTOCOL }, #endif #if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) - &Curl_cft_http_connect, + { &Curl_cft_http_connect, TRC_CT_PROTOCOL }, #endif - NULL, }; -CURLcode Curl_trc_opt(const char *config) +static void trc_apply_level_by_name(const char * const token, int lvl) +{ + size_t i; + + for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) { + if(strcasecompare(token, trc_cfts[i].cft->name)) { + trc_cfts[i].cft->log_level = lvl; + break; + } + } + for(i = 0; i < ARRAYSIZE(trc_feats); ++i) { + if(strcasecompare(token, trc_feats[i].feat->name)) { + trc_feats[i].feat->log_level = lvl; + break; + } + } +} + +static void trc_apply_level_by_category(int category, int lvl) { - char *token, *tok_buf, *tmp; size_t i; + + for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) { + if(!category || (trc_cfts[i].category & category)) + trc_cfts[i].cft->log_level = lvl; + } + for(i = 0; i < ARRAYSIZE(trc_feats); ++i) { + if(!category || (trc_feats[i].category & category)) + trc_feats[i].feat->log_level = lvl; + } +} + +static CURLcode trc_opt(const char *config) +{ + char *token, *tok_buf, *tmp; int lvl; tmp = strdup(config); @@ -285,42 +380,46 @@ CURLcode Curl_trc_opt(const char *config) lvl = CURL_LOG_LVL_INFO; break; } - for(i = 0; cf_types[i]; ++i) { - if(strcasecompare(token, "all")) { - cf_types[i]->log_level = lvl; - } - else if(strcasecompare(token, cf_types[i]->name)) { - cf_types[i]->log_level = lvl; - break; - } - } - for(i = 0; trc_feats[i]; ++i) { - if(strcasecompare(token, "all")) { - trc_feats[i]->log_level = lvl; - } - else if(strcasecompare(token, trc_feats[i]->name)) { - trc_feats[i]->log_level = lvl; - break; - } - } + if(strcasecompare(token, "all")) + trc_apply_level_by_category(TRC_CT_NONE, lvl); + else if(strcasecompare(token, "protocol")) + trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl); + else if(strcasecompare(token, "network")) + trc_apply_level_by_category(TRC_CT_NETWORK, lvl); + else if(strcasecompare(token, "proxy")) + trc_apply_level_by_category(TRC_CT_PROXY, lvl); + else + trc_apply_level_by_name(token, lvl); + token = strtok_r(NULL, ", ", &tok_buf); } free(tmp); return CURLE_OK; } -CURLcode Curl_trc_init(void) +CURLcode Curl_trc_opt(const char *config) { + CURLcode result = config? trc_opt(config) : CURLE_OK; #ifdef DEBUGBUILD - /* WIP: we use the auto-init from an env var only in DEBUG builds for - * convenience. */ - const char *config = getenv("CURL_DEBUG"); - if(config) { - return Curl_trc_opt(config); + /* CURL_DEBUG can override anything */ + if(!result) { + const char *dbg_config = getenv("CURL_DEBUG"); + if(dbg_config) + result = trc_opt(dbg_config); } #endif /* DEBUGBUILD */ + return result; +} + +CURLcode Curl_trc_init(void) +{ +#ifdef DEBUGBUILD + return Curl_trc_opt(NULL); +#else return CURLE_OK; +#endif } + #else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ CURLcode Curl_trc_init(void) diff --git a/lib/curl_trc.h b/lib/curl_trc.h index 3d3801834..5f675b453 100644 --- a/lib/curl_trc.h +++ b/lib/curl_trc.h @@ -89,6 +89,16 @@ void Curl_failf(struct Curl_easy *data, do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) \ Curl_trc_ftp(data, __VA_ARGS__); } while(0) #endif /* !CURL_DISABLE_FTP */ +#ifndef CURL_DISABLE_SMTP +#define CURL_TRC_SMTP(data, ...) \ + do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \ + Curl_trc_smtp(data, __VA_ARGS__); } while(0) +#endif /* !CURL_DISABLE_SMTP */ +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) +#define CURL_TRC_WS(data, ...) \ + do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \ + Curl_trc_ws(data, __VA_ARGS__); } while(0) +#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */ #else /* CURL_HAVE_C99 */ @@ -100,6 +110,12 @@ void Curl_failf(struct Curl_easy *data, #ifndef CURL_DISABLE_FTP #define CURL_TRC_FTP Curl_trc_ftp #endif +#ifndef CURL_DISABLE_SMTP +#define CURL_TRC_SMTP Curl_trc_smtp +#endif +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) +#define CURL_TRC_WS Curl_trc_ws +#endif #endif /* !CURL_HAVE_C99 */ @@ -148,6 +164,16 @@ extern struct curl_trc_feat Curl_trc_feat_ftp; void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...) CURL_PRINTF(2, 3); #endif +#ifndef CURL_DISABLE_SMTP +extern struct curl_trc_feat Curl_trc_feat_smtp; +void Curl_trc_smtp(struct Curl_easy *data, + const char *fmt, ...) CURL_PRINTF(2, 3); +#endif +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) +extern struct curl_trc_feat Curl_trc_feat_ws; +void Curl_trc_ws(struct Curl_easy *data, + const char *fmt, ...) CURL_PRINTF(2, 3); +#endif #else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ @@ -194,6 +220,12 @@ static void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...) (void)data; (void)fmt; } #endif +#ifndef CURL_DISABLE_SMTP +static void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...) +{ + (void)data; (void)fmt; +} +#endif #endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */ diff --git a/lib/curlx.h b/lib/curlx.h index 54e427957..0391d7cd7 100644 --- a/lib/curlx.h +++ b/lib/curlx.h @@ -31,10 +31,8 @@ * be. */ -#include -/* this is still a public header file that provides the curl_mprintf() - functions while they still are offered publicly. They will be made library- - private one day */ +/* map standard printf functions to curl implementations */ +#include "curl_printf.h" #include "strcase.h" /* "strcase.h" provides the strcasecompare protos */ @@ -77,41 +75,4 @@ */ -#define curlx_mvsnprintf curl_mvsnprintf -#define curlx_msnprintf curl_msnprintf -#define curlx_maprintf curl_maprintf -#define curlx_mvaprintf curl_mvaprintf -#define curlx_msprintf curl_msprintf -#define curlx_mprintf curl_mprintf -#define curlx_mfprintf curl_mfprintf -#define curlx_mvsprintf curl_mvsprintf -#define curlx_mvprintf curl_mvprintf -#define curlx_mvfprintf curl_mvfprintf - -#ifdef ENABLE_CURLX_PRINTF -/* If this define is set, we define all "standard" printf() functions to use - the curlx_* version instead. It makes the source code transparent and - easier to understand/patch. Undefine them first. */ -# undef printf -# undef fprintf -# undef sprintf -# undef msnprintf -# undef vprintf -# undef vfprintf -# undef vsprintf -# undef mvsnprintf -# undef aprintf -# undef vaprintf - -# define printf curlx_mprintf -# define fprintf curlx_mfprintf -# define sprintf curlx_msprintf -# define msnprintf curlx_msnprintf -# define vprintf curlx_mvprintf -# define vfprintf curlx_mvfprintf -# define mvsnprintf curlx_mvsnprintf -# define aprintf curlx_maprintf -# define vaprintf curlx_mvaprintf -#endif /* ENABLE_CURLX_PRINTF */ - #endif /* HEADER_CURL_CURLX_H */ diff --git a/lib/dict.c b/lib/dict.c index 35331ce22..7d9c18dc9 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -146,7 +146,7 @@ static CURLcode sendf(struct Curl_easy *data, const char *fmt, ...) for(;;) { /* Write the buffer to the socket */ - result = Curl_xfer_send(data, sptr, write_len, &bytes_written); + result = Curl_xfer_send(data, sptr, write_len, FALSE, &bytes_written); if(result) break; diff --git a/lib/doh.c b/lib/doh.c index 0dcca17cc..52b357458 100644 --- a/lib/doh.c +++ b/lib/doh.c @@ -46,7 +46,7 @@ #define DNS_CLASS_IN 0x01 -/* local_print_buf truncates if the hex string will be more than this */ +/* doh_print_buf truncates if the hex string will be more than this */ #define LOCAL_PB_HEXMAX 400 #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -82,11 +82,11 @@ struct curl_trc_feat Curl_doh_trc = { /* @unittest 1655 */ -UNITTEST DOHcode doh_encode(const char *host, - DNStype dnstype, - unsigned char *dnsp, /* buffer */ - size_t len, /* buffer size */ - size_t *olen) /* output length */ +UNITTEST DOHcode doh_req_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen) /* output length */ { const size_t hostlen = strlen(host); unsigned char *orig = dnsp; @@ -192,9 +192,9 @@ doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp) } #if defined(USE_HTTPSRR) && defined(DEBUGBUILD) -static void local_print_buf(struct Curl_easy *data, - const char *prefix, - unsigned char *buf, size_t len) +static void doh_print_buf(struct Curl_easy *data, + const char *prefix, + unsigned char *buf, size_t len) { unsigned char hexstr[LOCAL_PB_HEXMAX]; size_t hlen = LOCAL_PB_HEXMAX; @@ -214,19 +214,26 @@ static void local_print_buf(struct Curl_easy *data, /* called from multi.c when this DoH transfer is complete */ static int doh_done(struct Curl_easy *doh, CURLcode result) { - struct Curl_easy *data = doh->set.dohfor; - struct dohdata *dohp = data->req.doh; - /* so one of the DoH request done for the 'data' transfer is now complete! */ - dohp->pending--; - infof(doh, "a DoH request is completed, %u to go", dohp->pending); - if(result) - infof(doh, "DoH request %s", curl_easy_strerror(result)); + struct Curl_easy *data; /* the transfer that asked for the DoH probe */ - if(!dohp->pending) { - /* DoH completed */ - curl_slist_free_all(dohp->headers); - dohp->headers = NULL; - Curl_expire(data, 0, EXPIRE_RUN_NOW); + data = Curl_multi_get_handle(doh->multi, doh->set.dohfor_mid); + if(!data) { + DEBUGF(infof(doh, "doh_done: xfer for mid=%" FMT_OFF_T + " not found", doh->set.dohfor_mid)); + DEBUGASSERT(0); + } + else { + struct doh_probes *dohp = data->req.doh; + /* one of the DoH request done for the 'data' transfer is now complete! */ + dohp->pending--; + infof(doh, "a DoH request is completed, %u to go", dohp->pending); + if(result) + infof(doh, "DoH request %s", curl_easy_strerror(result)); + + if(!dohp->pending) { + /* DoH completed, run the transfer picking up the results */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + } } return 0; } @@ -240,24 +247,24 @@ do { \ goto error; \ } while(0) -static CURLcode dohprobe(struct Curl_easy *data, - struct dnsprobe *p, DNStype dnstype, - const char *host, - const char *url, CURLM *multi, - struct curl_slist *headers) +static CURLcode doh_run_probe(struct Curl_easy *data, + struct doh_probe *p, DNStype dnstype, + const char *host, + const char *url, CURLM *multi, + struct curl_slist *headers) { struct Curl_easy *doh = NULL; CURLcode result = CURLE_OK; timediff_t timeout_ms; - DOHcode d = doh_encode(host, dnstype, p->dohbuffer, sizeof(p->dohbuffer), - &p->dohlen); + DOHcode d = doh_req_encode(host, dnstype, p->req_body, sizeof(p->req_body), + &p->req_body_len); if(d) { failf(data, "Failed to encode DoH packet [%d]", d); return CURLE_OUT_OF_MEMORY; } p->dnstype = dnstype; - Curl_dyn_init(&p->serverdoh, DYN_DOH_RESPONSE); + Curl_dyn_init(&p->resp_body, DYN_DOH_RESPONSE); timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms <= 0) { @@ -266,126 +273,126 @@ static CURLcode dohprobe(struct Curl_easy *data, } /* Curl_open() is the internal version of curl_easy_init() */ result = Curl_open(&doh); - if(!result) { - /* pass in the struct pointer via a local variable to please coverity and - the gcc typecheck helpers */ - struct dynbuf *resp = &p->serverdoh; - doh->state.internal = true; + if(result) + goto error; + + /* pass in the struct pointer via a local variable to please coverity and + the gcc typecheck helpers */ + doh->state.internal = true; #ifndef CURL_DISABLE_VERBOSE_STRINGS - doh->state.feat = &Curl_doh_trc; + doh->state.feat = &Curl_doh_trc; #endif - ERROR_CHECK_SETOPT(CURLOPT_URL, url); - ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https"); - ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); - ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp); - ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer); - ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen); - ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers); + ERROR_CHECK_SETOPT(CURLOPT_URL, url); + ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https"); + ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); + ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, &p->resp_body); + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->req_body); + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->req_body_len); + ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers); #ifdef USE_HTTP2 - ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); - ERROR_CHECK_SETOPT(CURLOPT_PIPEWAIT, 1L); + ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); + ERROR_CHECK_SETOPT(CURLOPT_PIPEWAIT, 1L); #endif #ifndef DEBUGBUILD - /* enforce HTTPS if not debug */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); + /* enforce HTTPS if not debug */ + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); #else - /* in debug mode, also allow http */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); + /* in debug mode, also allow http */ + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #endif - ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); - ERROR_CHECK_SETOPT(CURLOPT_SHARE, data->share); - if(data->set.err && data->set.err != stderr) - ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err); - if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc)) - ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); - if(data->set.no_signal) - ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); - - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, - data->set.doh_verifyhost ? 2L : 0L); - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, - data->set.doh_verifypeer ? 1L : 0L); - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, - data->set.doh_verifystatus ? 1L : 0L); - - /* Inherit *some* SSL options from the user's transfer. This is a - best-guess as to which options are needed for compatibility. #3661 - - Note DoH does not inherit the user's proxy server so proxy SSL settings - have no effect and are not inherited. If that changes then two new - options should be added to check doh proxy insecure separately, - CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. - */ - if(data->set.ssl.falsestart) - ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); - if(data->set.str[STRING_SSL_CAFILE]) { - ERROR_CHECK_SETOPT(CURLOPT_CAINFO, - data->set.str[STRING_SSL_CAFILE]); - } - if(data->set.blobs[BLOB_CAINFO]) { - ERROR_CHECK_SETOPT(CURLOPT_CAINFO_BLOB, - data->set.blobs[BLOB_CAINFO]); - } - if(data->set.str[STRING_SSL_CAPATH]) { - ERROR_CHECK_SETOPT(CURLOPT_CAPATH, - data->set.str[STRING_SSL_CAPATH]); - } - if(data->set.str[STRING_SSL_CRLFILE]) { - ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, - data->set.str[STRING_SSL_CRLFILE]); - } - if(data->set.ssl.certinfo) - ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); - if(data->set.ssl.fsslctx) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); - if(data->set.ssl.fsslctxp) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); - if(data->set.fdebug) - ERROR_CHECK_SETOPT(CURLOPT_DEBUGFUNCTION, data->set.fdebug); - if(data->set.debugdata) - ERROR_CHECK_SETOPT(CURLOPT_DEBUGDATA, data->set.debugdata); - if(data->set.str[STRING_SSL_EC_CURVES]) { - ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, - data->set.str[STRING_SSL_EC_CURVES]); - } + ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); + ERROR_CHECK_SETOPT(CURLOPT_SHARE, data->share); + if(data->set.err && data->set.err != stderr) + ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err); + if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc)) + ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + if(data->set.no_signal) + ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); + + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, + data->set.doh_verifyhost ? 2L : 0L); + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, + data->set.doh_verifypeer ? 1L : 0L); + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, + data->set.doh_verifystatus ? 1L : 0L); + + /* Inherit *some* SSL options from the user's transfer. This is a + best-guess as to which options are needed for compatibility. #3661 + + Note DoH does not inherit the user's proxy server so proxy SSL settings + have no effect and are not inherited. If that changes then two new + options should be added to check doh proxy insecure separately, + CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. + */ + if(data->set.ssl.falsestart) + ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); + if(data->set.str[STRING_SSL_CAFILE]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO, + data->set.str[STRING_SSL_CAFILE]); + } + if(data->set.blobs[BLOB_CAINFO]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO_BLOB, + data->set.blobs[BLOB_CAINFO]); + } + if(data->set.str[STRING_SSL_CAPATH]) { + ERROR_CHECK_SETOPT(CURLOPT_CAPATH, + data->set.str[STRING_SSL_CAPATH]); + } + if(data->set.str[STRING_SSL_CRLFILE]) { + ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, + data->set.str[STRING_SSL_CRLFILE]); + } + if(data->set.ssl.certinfo) + ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); + if(data->set.ssl.fsslctx) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); + if(data->set.ssl.fsslctxp) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); + if(data->set.fdebug) + ERROR_CHECK_SETOPT(CURLOPT_DEBUGFUNCTION, data->set.fdebug); + if(data->set.debugdata) + ERROR_CHECK_SETOPT(CURLOPT_DEBUGDATA, data->set.debugdata); + if(data->set.str[STRING_SSL_EC_CURVES]) { + ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, + data->set.str[STRING_SSL_EC_CURVES]); + } - { - long mask = - (data->set.ssl.enable_beast ? - CURLSSLOPT_ALLOW_BEAST : 0) | - (data->set.ssl.no_revoke ? - CURLSSLOPT_NO_REVOKE : 0) | - (data->set.ssl.no_partialchain ? - CURLSSLOPT_NO_PARTIALCHAIN : 0) | - (data->set.ssl.revoke_best_effort ? - CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | - (data->set.ssl.native_ca_store ? - CURLSSLOPT_NATIVE_CA : 0) | - (data->set.ssl.auto_client_cert ? - CURLSSLOPT_AUTO_CLIENT_CERT : 0); - - (void)curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); - } + { + long mask = + (data->set.ssl.enable_beast ? + CURLSSLOPT_ALLOW_BEAST : 0) | + (data->set.ssl.no_revoke ? + CURLSSLOPT_NO_REVOKE : 0) | + (data->set.ssl.no_partialchain ? + CURLSSLOPT_NO_PARTIALCHAIN : 0) | + (data->set.ssl.revoke_best_effort ? + CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | + (data->set.ssl.native_ca_store ? + CURLSSLOPT_NATIVE_CA : 0) | + (data->set.ssl.auto_client_cert ? + CURLSSLOPT_AUTO_CLIENT_CERT : 0); + + (void)curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); + } - doh->set.fmultidone = doh_done; - doh->set.dohfor = data; /* identify for which transfer this is done */ - p->easy = doh; + doh->set.fmultidone = doh_done; + doh->set.dohfor_mid = data->mid; /* for which transfer this is done */ - /* DoH handles must not inherit private_data. The handles may be passed to - the user via callbacks and the user will be able to identify them as - internal handles because private data is not set. The user can then set - private_data via CURLOPT_PRIVATE if they so choose. */ - DEBUGASSERT(!doh->set.private_data); + /* DoH handles must not inherit private_data. The handles may be passed to + the user via callbacks and the user will be able to identify them as + internal handles because private data is not set. The user can then set + private_data via CURLOPT_PRIVATE if they so choose. */ + DEBUGASSERT(!doh->set.private_data); - if(curl_multi_add_handle(multi, doh)) - goto error; - } - else + if(curl_multi_add_handle(multi, doh)) goto error; + + p->easy_mid = doh->mid; return CURLE_OK; error: Curl_close(&doh); + p->easy_mid = -1; return result; } @@ -400,8 +407,9 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, int *waitp) { CURLcode result = CURLE_OK; - struct dohdata *dohp; + struct doh_probes *dohp; struct connectdata *conn = data->conn; + size_t i; #ifdef USE_HTTPSRR /* for now, this is only used when ECH is enabled */ # ifdef USE_ECH @@ -416,23 +424,27 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, DEBUGASSERT(conn); /* start clean, consider allocating this struct on demand */ - dohp = data->req.doh = calloc(1, sizeof(struct dohdata)); + dohp = data->req.doh = calloc(1, sizeof(struct doh_probes)); if(!dohp) return NULL; + for(i = 0; i < DOH_SLOT_COUNT; ++i) { + dohp->probe[i].easy_mid = -1; + } + conn->bits.doh = TRUE; dohp->host = hostname; dohp->port = port; - dohp->headers = + dohp->req_hds = curl_slist_append(NULL, "Content-Type: application/dns-message"); - if(!dohp->headers) + if(!dohp->req_hds) goto error; /* create IPv4 DoH request */ - result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4], - DNS_TYPE_A, hostname, data->set.str[STRING_DOH], - data->multi, dohp->headers); + result = doh_run_probe(data, &dohp->probe[DOH_SLOT_IPV4], + DNS_TYPE_A, hostname, data->set.str[STRING_DOH], + data->multi, dohp->req_hds); if(result) goto error; dohp->pending++; @@ -440,9 +452,9 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, #ifdef USE_IPV6 if((conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) { /* create IPv6 DoH request */ - result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6], - DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], - data->multi, dohp->headers); + result = doh_run_probe(data, &dohp->probe[DOH_SLOT_IPV6], + DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], + data->multi, dohp->req_hds); if(result) goto error; dohp->pending++; @@ -469,9 +481,9 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, qname = aprintf("_%d._https.%s", port, hostname); if(!qname) goto error; - result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_HTTPS], - DNS_TYPE_HTTPS, qname, data->set.str[STRING_DOH], - data->multi, dohp->headers); + result = doh_run_probe(data, &dohp->probe[DOH_SLOT_HTTPS_RR], + DNS_TYPE_HTTPS, qname, data->set.str[STRING_DOH], + data->multi, dohp->req_hds); Curl_safefree(qname); if(result) goto error; @@ -487,8 +499,8 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, return NULL; } -static DOHcode skipqname(const unsigned char *doh, size_t dohlen, - unsigned int *indexp) +static DOHcode doh_skipqname(const unsigned char *doh, size_t dohlen, + unsigned int *indexp) { unsigned char length; do { @@ -511,12 +523,13 @@ static DOHcode skipqname(const unsigned char *doh, size_t dohlen, return DOH_OK; } -static unsigned short get16bit(const unsigned char *doh, unsigned int index) +static unsigned short doh_get16bit(const unsigned char *doh, + unsigned int index) { return (unsigned short)((doh[index] << 8) | doh[index + 1]); } -static unsigned int get32bit(const unsigned char *doh, unsigned int index) +static unsigned int doh_get32bit(const unsigned char *doh, unsigned int index) { /* make clang and gcc optimize this to bswap by incrementing the pointer first. */ @@ -529,7 +542,8 @@ static unsigned int get32bit(const unsigned char *doh, unsigned int index) ((unsigned)doh[2] << 8) | doh[3]; } -static DOHcode store_a(const unsigned char *doh, int index, struct dohentry *d) +static void doh_store_a(const unsigned char *doh, int index, + struct dohentry *d) { /* silently ignore addresses over the limit */ if(d->numaddr < DOH_MAX_ADDR) { @@ -538,12 +552,10 @@ static DOHcode store_a(const unsigned char *doh, int index, struct dohentry *d) memcpy(&a->ip.v4, &doh[index], 4); d->numaddr++; } - return DOH_OK; } -static DOHcode store_aaaa(const unsigned char *doh, - int index, - struct dohentry *d) +static void doh_store_aaaa(const unsigned char *doh, int index, + struct dohentry *d) { /* silently ignore addresses over the limit */ if(d->numaddr < DOH_MAX_ADDR) { @@ -552,14 +564,11 @@ static DOHcode store_aaaa(const unsigned char *doh, memcpy(&a->ip.v6, &doh[index], 16); d->numaddr++; } - return DOH_OK; } #ifdef USE_HTTPSRR -static DOHcode store_https(const unsigned char *doh, - int index, - struct dohentry *d, - uint16_t len) +static DOHcode doh_store_https(const unsigned char *doh, int index, + struct dohentry *d, uint16_t len) { /* silently ignore RRs over the limit */ if(d->numhttps_rrs < DOH_MAX_HTTPS) { @@ -574,10 +583,8 @@ static DOHcode store_https(const unsigned char *doh, } #endif -static DOHcode store_cname(const unsigned char *doh, - size_t dohlen, - unsigned int index, - struct dohentry *d) +static DOHcode doh_store_cname(const unsigned char *doh, size_t dohlen, + unsigned int index, struct dohentry *d) { struct dynbuf *c; unsigned int loop = 128; /* a valid DNS name can never loop this much */ @@ -626,12 +633,12 @@ static DOHcode store_cname(const unsigned char *doh, return DOH_OK; } -static DOHcode rdata(const unsigned char *doh, - size_t dohlen, - unsigned short rdlength, - unsigned short type, - int index, - struct dohentry *d) +static DOHcode doh_rdata(const unsigned char *doh, + size_t dohlen, + unsigned short rdlength, + unsigned short type, + int index, + struct dohentry *d) { /* RDATA - A (TYPE 1): 4 bytes @@ -644,26 +651,22 @@ static DOHcode rdata(const unsigned char *doh, case DNS_TYPE_A: if(rdlength != 4) return DOH_DNS_RDATA_LEN; - rc = store_a(doh, index, d); - if(rc) - return rc; + doh_store_a(doh, index, d); break; case DNS_TYPE_AAAA: if(rdlength != 16) return DOH_DNS_RDATA_LEN; - rc = store_aaaa(doh, index, d); - if(rc) - return rc; + doh_store_aaaa(doh, index, d); break; #ifdef USE_HTTPSRR case DNS_TYPE_HTTPS: - rc = store_https(doh, index, d, rdlength); + rc = doh_store_https(doh, index, d, rdlength); if(rc) return rc; break; #endif case DNS_TYPE_CNAME: - rc = store_cname(doh, dohlen, (unsigned int)index, d); + rc = doh_store_cname(doh, dohlen, (unsigned int)index, d); if(rc) return rc; break; @@ -687,10 +690,10 @@ UNITTEST void de_init(struct dohentry *de) } -UNITTEST DOHcode doh_decode(const unsigned char *doh, - size_t dohlen, - DNStype dnstype, - struct dohentry *d) +UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d) { unsigned char rcode; unsigned short qdcount; @@ -710,9 +713,9 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(rcode) return DOH_DNS_BAD_RCODE; /* bad rcode */ - qdcount = get16bit(doh, 4); + qdcount = doh_get16bit(doh, 4); while(qdcount) { - rc = skipqname(doh, dohlen, &index); + rc = doh_skipqname(doh, dohlen, &index); if(rc) return rc; /* bad qname */ if(dohlen < (index + 4)) @@ -721,19 +724,19 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, qdcount--; } - ancount = get16bit(doh, 6); + ancount = doh_get16bit(doh, 6); while(ancount) { unsigned short class; unsigned int ttl; - rc = skipqname(doh, dohlen, &index); + rc = doh_skipqname(doh, dohlen, &index); if(rc) return rc; /* bad qname */ if(dohlen < (index + 2)) return DOH_DNS_OUT_OF_RANGE; - type = get16bit(doh, index); + type = doh_get16bit(doh, index); if((type != DNS_TYPE_CNAME) /* may be synthesized from DNAME */ && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */ && (type != dnstype)) @@ -743,7 +746,7 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(dohlen < (index + 2)) return DOH_DNS_OUT_OF_RANGE; - class = get16bit(doh, index); + class = doh_get16bit(doh, index); if(DNS_CLASS_IN != class) return DOH_DNS_UNEXPECTED_CLASS; /* unsupported */ index += 2; @@ -751,7 +754,7 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(dohlen < (index + 4)) return DOH_DNS_OUT_OF_RANGE; - ttl = get32bit(doh, index); + ttl = doh_get32bit(doh, index); if(ttl < d->ttl) d->ttl = ttl; index += 4; @@ -759,21 +762,21 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(dohlen < (index + 2)) return DOH_DNS_OUT_OF_RANGE; - rdlength = get16bit(doh, index); + rdlength = doh_get16bit(doh, index); index += 2; if(dohlen < (index + rdlength)) return DOH_DNS_OUT_OF_RANGE; - rc = rdata(doh, dohlen, rdlength, type, (int)index, d); + rc = doh_rdata(doh, dohlen, rdlength, type, (int)index, d); if(rc) - return rc; /* bad rdata */ + return rc; /* bad doh_rdata */ index += rdlength; ancount--; } - nscount = get16bit(doh, 8); + nscount = doh_get16bit(doh, 8); while(nscount) { - rc = skipqname(doh, dohlen, &index); + rc = doh_skipqname(doh, dohlen, &index); if(rc) return rc; /* bad qname */ @@ -785,7 +788,7 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(dohlen < (index + 2)) return DOH_DNS_OUT_OF_RANGE; - rdlength = get16bit(doh, index); + rdlength = doh_get16bit(doh, index); index += 2; if(dohlen < (index + rdlength)) return DOH_DNS_OUT_OF_RANGE; @@ -793,9 +796,9 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, nscount--; } - arcount = get16bit(doh, 10); + arcount = doh_get16bit(doh, 10); while(arcount) { - rc = skipqname(doh, dohlen, &index); + rc = doh_skipqname(doh, dohlen, &index); if(rc) return rc; /* bad qname */ @@ -807,7 +810,7 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, if(dohlen < (index + 2)) return DOH_DNS_OUT_OF_RANGE; - rdlength = get16bit(doh, index); + rdlength = doh_get16bit(doh, index); index += 2; if(dohlen < (index + rdlength)) return DOH_DNS_OUT_OF_RANGE; @@ -830,8 +833,8 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, } #ifndef CURL_DISABLE_VERBOSE_STRINGS -static void showdoh(struct Curl_easy *data, - const struct dohentry *d) +static void doh_show(struct Curl_easy *data, + const struct dohentry *d) { int i; infof(data, "[DoH] TTL: %u seconds", d->ttl); @@ -864,8 +867,8 @@ static void showdoh(struct Curl_easy *data, #ifdef USE_HTTPSRR for(i = 0; i < d->numhttps_rrs; i++) { # ifdef DEBUGBUILD - local_print_buf(data, "DoH HTTPS", - d->https_rrs[i].val, d->https_rrs[i].len); + doh_print_buf(data, "DoH HTTPS", + d->https_rrs[i].val, d->https_rrs[i].len); # else infof(data, "DoH HTTPS RR: length %d", d->https_rrs[i].len); # endif @@ -876,7 +879,7 @@ static void showdoh(struct Curl_easy *data, } } #else -#define showdoh(x,y) +#define doh_show(x,y) #endif /* @@ -996,7 +999,7 @@ static CURLcode doh2ai(const struct dohentry *de, const char *hostname, } #ifndef CURL_DISABLE_VERBOSE_STRINGS -static const char *type2name(DNStype dnstype) +static const char *doh_type2name(DNStype dnstype) { switch(dnstype) { case DNS_TYPE_A: @@ -1041,8 +1044,8 @@ UNITTEST void de_cleanup(struct dohentry *d) * just after the end of the DNS name encoding on output. (And * that is why it is an "unsigned char **" :-) */ -static CURLcode local_decode_rdata_name(unsigned char **buf, size_t *remaining, - char **dnsname) +static CURLcode doh_decode_rdata_name(unsigned char **buf, size_t *remaining, + char **dnsname) { unsigned char *cp = NULL; int rem = 0; @@ -1088,8 +1091,8 @@ static CURLcode local_decode_rdata_name(unsigned char **buf, size_t *remaining, return CURLE_OK; } -static CURLcode local_decode_rdata_alpn(unsigned char *rrval, size_t len, - char **alpns) +static CURLcode doh_decode_rdata_alpn(unsigned char *rrval, size_t len, + char **alpns) { /* * spec here is as per draft-ietf-dnsop-svcb-https, section-7.1.1 @@ -1145,7 +1148,7 @@ static CURLcode local_decode_rdata_alpn(unsigned char *rrval, size_t len, } #ifdef DEBUGBUILD -static CURLcode test_alpn_escapes(void) +static CURLcode doh_test_alpn_escapes(void) { /* we will use an example from draft-ietf-dnsop-svcb, figure 10 */ static unsigned char example[] = { @@ -1158,7 +1161,7 @@ static CURLcode test_alpn_escapes(void) char *aval = NULL; static const char *expected = "f\\\\oo\\,bar,h2"; - if(local_decode_rdata_alpn(example, example_len, &aval) != CURLE_OK) + if(doh_decode_rdata_alpn(example, example_len, &aval) != CURLE_OK) return CURLE_BAD_CONTENT_ENCODING; if(strlen(aval) != strlen(expected)) return CURLE_BAD_CONTENT_ENCODING; @@ -1168,7 +1171,7 @@ static CURLcode test_alpn_escapes(void) } #endif -static CURLcode Curl_doh_decode_httpsrr(unsigned char *rrval, size_t len, +static CURLcode doh_resp_decode_httpsrr(unsigned char *rrval, size_t len, struct Curl_https_rrinfo **hrr) { size_t remaining = len; @@ -1179,7 +1182,7 @@ static CURLcode Curl_doh_decode_httpsrr(unsigned char *rrval, size_t len, #ifdef DEBUGBUILD /* a few tests of escaping, should not be here but ok for now */ - if(test_alpn_escapes() != CURLE_OK) + if(doh_test_alpn_escapes() != CURLE_OK) return CURLE_OUT_OF_MEMORY; #endif lhrr = calloc(1, sizeof(struct Curl_https_rrinfo)); @@ -1194,7 +1197,7 @@ static CURLcode Curl_doh_decode_httpsrr(unsigned char *rrval, size_t len, lhrr->priority = (uint16_t)((cp[0] << 8) + cp[1]); cp += 2; remaining -= (uint16_t)2; - if(local_decode_rdata_name(&cp, &remaining, &dnsname) != CURLE_OK) + if(doh_decode_rdata_name(&cp, &remaining, &dnsname) != CURLE_OK) goto err; lhrr->target = dnsname; while(remaining >= 4) { @@ -1204,7 +1207,7 @@ static CURLcode Curl_doh_decode_httpsrr(unsigned char *rrval, size_t len, cp += 2; remaining -= 4; if(pcode == HTTPS_RR_CODE_ALPN) { - if(local_decode_rdata_alpn(cp, plen, &lhrr->alpns) != CURLE_OK) + if(doh_decode_rdata_alpn(cp, plen, &lhrr->alpns) != CURLE_OK) goto err; } if(pcode == HTTPS_RR_CODE_NO_DEF_ALPN) @@ -1253,8 +1256,8 @@ static CURLcode Curl_doh_decode_httpsrr(unsigned char *rrval, size_t len, } # ifdef DEBUGBUILD -static void local_print_httpsrr(struct Curl_easy *data, - struct Curl_https_rrinfo *hrr) +static void doh_print_httpsrr(struct Curl_easy *data, + struct Curl_https_rrinfo *hrr) { DEBUGASSERT(hrr); infof(data, "HTTPS RR: priority %d, target: %s", @@ -1268,20 +1271,20 @@ static void local_print_httpsrr(struct Curl_easy *data, else infof(data, "HTTPS RR: no_def_alpn not set"); if(hrr->ipv4hints) { - local_print_buf(data, "HTTPS RR: ipv4hints", - hrr->ipv4hints, hrr->ipv4hints_len); + doh_print_buf(data, "HTTPS RR: ipv4hints", + hrr->ipv4hints, hrr->ipv4hints_len); } else infof(data, "HTTPS RR: no ipv4hints"); if(hrr->echconfiglist) { - local_print_buf(data, "HTTPS RR: ECHConfigList", - hrr->echconfiglist, hrr->echconfiglist_len); + doh_print_buf(data, "HTTPS RR: ECHConfigList", + hrr->echconfiglist, hrr->echconfiglist_len); } else infof(data, "HTTPS RR: no ECHConfigList"); if(hrr->ipv6hints) { - local_print_buf(data, "HTTPS RR: ipv6hint", - hrr->ipv6hints, hrr->ipv6hints_len); + doh_print_buf(data, "HTTPS RR: ipv6hint", + hrr->ipv6hints, hrr->ipv6hints_len); } else infof(data, "HTTPS RR: no ipv6hints"); @@ -1294,52 +1297,45 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, struct Curl_dns_entry **dnsp) { CURLcode result; - struct dohdata *dohp = data->req.doh; + struct doh_probes *dohp = data->req.doh; *dnsp = NULL; /* defaults to no response */ if(!dohp) return CURLE_OUT_OF_MEMORY; - if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy && - !dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) { + if(dohp->probe[DOH_SLOT_IPV4].easy_mid < 0 && + dohp->probe[DOH_SLOT_IPV6].easy_mid < 0) { failf(data, "Could not DoH-resolve: %s", data->state.async.hostname); return CONN_IS_PROXIED(data->conn)?CURLE_COULDNT_RESOLVE_PROXY: CURLE_COULDNT_RESOLVE_HOST; } else if(!dohp->pending) { -#ifndef USE_HTTPSRR - DOHcode rc[DOH_PROBE_SLOTS] = { - DOH_OK, DOH_OK - }; -#else - DOHcode rc[DOH_PROBE_SLOTS] = { - DOH_OK, DOH_OK, DOH_OK - }; -#endif + DOHcode rc[DOH_SLOT_COUNT]; struct dohentry de; int slot; + + memset(rc, 0, sizeof(rc)); /* remove DoH handles from multi handle and close them */ Curl_doh_close(data); /* parse the responses, create the struct and return it! */ de_init(&de); - for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { - struct dnsprobe *p = &dohp->probe[slot]; + for(slot = 0; slot < DOH_SLOT_COUNT; slot++) { + struct doh_probe *p = &dohp->probe[slot]; if(!p->dnstype) continue; - rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh), - Curl_dyn_len(&p->serverdoh), - p->dnstype, - &de); - Curl_dyn_free(&p->serverdoh); + rc[slot] = doh_resp_decode(Curl_dyn_uptr(&p->resp_body), + Curl_dyn_len(&p->resp_body), + p->dnstype, &de); + Curl_dyn_free(&p->resp_body); #ifndef CURL_DISABLE_VERBOSE_STRINGS if(rc[slot]) { infof(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), - type2name(p->dnstype), dohp->host); + doh_type2name(p->dnstype), dohp->host); } #endif } /* next slot */ result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */ - if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) { + if(!rc[DOH_SLOT_IPV4] || !rc[DOH_SLOT_IPV6]) { /* we have an address, of one kind or other */ struct Curl_dns_entry *dns; struct Curl_addrinfo *ai; @@ -1347,7 +1343,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc)) { infof(data, "[DoH] hostname: %s", dohp->host); - showdoh(data, &de); + doh_show(data, &de); } result = doh2ai(&de, dohp->host, dohp->port, &ai); @@ -1360,7 +1356,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); /* we got a response, store it in the cache */ - dns = Curl_cache_addr(data, ai, dohp->host, 0, dohp->port); + dns = Curl_cache_addr(data, ai, dohp->host, 0, dohp->port, FALSE); if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -1380,7 +1376,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, #ifdef USE_HTTPSRR if(de.numhttps_rrs > 0 && result == CURLE_OK && *dnsp) { struct Curl_https_rrinfo *hrr = NULL; - result = Curl_doh_decode_httpsrr(de.https_rrs->val, de.https_rrs->len, + result = doh_resp_decode_httpsrr(de.https_rrs->val, de.https_rrs->len, &hrr); if(result) { infof(data, "Failed to decode HTTPS RR"); @@ -1388,7 +1384,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, } infof(data, "Some HTTPS RR to process"); # ifdef DEBUGBUILD - local_print_httpsrr(data, hrr); + doh_print_httpsrr(data, hrr); # endif (*dnsp)->hinfo = hrr; } @@ -1396,7 +1392,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, /* All done */ de_cleanup(&de); - Curl_safefree(data->req.doh); + Curl_doh_cleanup(data); return result; } /* !dohp->pending */ @@ -1407,28 +1403,39 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, void Curl_doh_close(struct Curl_easy *data) { - struct dohdata *doh = data->req.doh; - if(doh) { + struct doh_probes *doh = data->req.doh; + if(doh && data->multi) { + struct Curl_easy *probe_data; + curl_off_t mid; size_t slot; - for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { - if(!doh->probe[slot].easy) + for(slot = 0; slot < DOH_SLOT_COUNT; slot++) { + mid = doh->probe[slot].easy_mid; + if(mid < 0) continue; + doh->probe[slot].easy_mid = -1; + /* should have been called before data is removed from multi handle */ + DEBUGASSERT(data->multi); + probe_data = data->multi? Curl_multi_get_handle(data->multi, mid) : NULL; + if(!probe_data) { + DEBUGF(infof(data, "Curl_doh_close: xfer for mid=%" + FMT_OFF_T " not found!", + doh->probe[slot].easy_mid)); + continue; + } /* data->multi might already be reset at this time */ - if(doh->probe[slot].easy->multi) - curl_multi_remove_handle(doh->probe[slot].easy->multi, - doh->probe[slot].easy); - Curl_close(&doh->probe[slot].easy); + curl_multi_remove_handle(data->multi, probe_data); + Curl_close(&probe_data); } } } void Curl_doh_cleanup(struct Curl_easy *data) { - struct dohdata *doh = data->req.doh; + struct doh_probes *doh = data->req.doh; if(doh) { Curl_doh_close(data); - curl_slist_free_all(doh->headers); - data->req.doh->headers = NULL; + curl_slist_free_all(doh->req_hds); + data->req.doh->req_hds = NULL; Curl_safefree(data->req.doh); } } diff --git a/lib/doh.h b/lib/doh.h index 5e86bf44a..aae32a654 100644 --- a/lib/doh.h +++ b/lib/doh.h @@ -59,18 +59,39 @@ typedef enum { } DNStype; /* one of these for each DoH request */ -struct dnsprobe { - CURL *easy; +struct doh_probe { + curl_off_t easy_mid; /* multi id of easy handle doing the lookup */ DNStype dnstype; - unsigned char dohbuffer[512]; - size_t dohlen; - struct dynbuf serverdoh; + unsigned char req_body[512]; + size_t req_body_len; + struct dynbuf resp_body; }; -struct dohdata { - struct curl_slist *headers; - struct dnsprobe probe[DOH_PROBE_SLOTS]; - unsigned int pending; /* still outstanding requests */ +enum doh_slot_num { + /* Explicit values for first two symbols so as to match hard-coded + * constants in existing code + */ + DOH_SLOT_IPV4 = 0, /* make 'V4' stand out for readability */ + DOH_SLOT_IPV6 = 1, /* 'V6' likewise */ + + /* Space here for (possibly build-specific) additional slot definitions */ +#ifdef USE_HTTPSRR + DOH_SLOT_HTTPS_RR = 2, /* for HTTPS RR */ +#endif + + /* for example */ + /* #ifdef WANT_DOH_FOOBAR_TXT */ + /* DOH_PROBE_SLOT_FOOBAR_TXT, */ + /* #endif */ + + /* AFTER all slot definitions, establish how many we have */ + DOH_SLOT_COUNT +}; + +struct doh_probes { + struct curl_slist *req_hds; + struct doh_probe probe[DOH_SLOT_COUNT]; + unsigned int pending; /* still outstanding probes */ int port; const char *host; }; @@ -116,7 +137,7 @@ struct dohaddr { #define HTTPS_RR_CODE_IPV6 0x06 /* - * These may need escaping when found within an alpn string + * These may need escaping when found within an ALPN string * value. */ #define COMMA_CHAR ',' @@ -144,15 +165,15 @@ void Curl_doh_close(struct Curl_easy *data); void Curl_doh_cleanup(struct Curl_easy *data); #ifdef UNITTESTS -UNITTEST DOHcode doh_encode(const char *host, - DNStype dnstype, - unsigned char *dnsp, /* buffer */ - size_t len, /* buffer size */ - size_t *olen); /* output length */ -UNITTEST DOHcode doh_decode(const unsigned char *doh, - size_t dohlen, - DNStype dnstype, - struct dohentry *d); +UNITTEST DOHcode doh_req_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen); /* output length */ +UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d); UNITTEST void de_init(struct dohentry *d); UNITTEST void de_cleanup(struct dohentry *d); diff --git a/lib/easy.c b/lib/easy.c index 2ba9af0b3..261445aee 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -113,6 +113,7 @@ static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT; #endif #if defined(_MSC_VER) && defined(_DLL) +# pragma warning(push) # pragma warning(disable:4232) /* MSVC extension, dllimport identity */ #endif @@ -130,7 +131,7 @@ curl_wcsdup_callback Curl_cwcsdup = Curl_wcsdup; #endif #if defined(_MSC_VER) && defined(_DLL) -# pragma warning(default:4232) /* MSVC extension, dllimport identity */ +# pragma warning(pop) #endif #ifdef DEBUGBUILD @@ -390,25 +391,22 @@ struct events { int running_handles; /* store the returned number */ }; +#define DEBUG_EV_POLL 0 + /* events_timer * * Callback that gets called with a new value when the timeout should be * updated. */ - static int events_timer(struct Curl_multi *multi, /* multi handle */ long timeout_ms, /* see above */ void *userp) /* private callback pointer */ { struct events *ev = userp; (void)multi; - if(timeout_ms == -1) - /* timeout removed */ - timeout_ms = 0; - else if(timeout_ms == 0) - /* timeout is already reached! */ - timeout_ms = 1; /* trigger asap */ - +#if DEBUG_EV_POLL + fprintf(stderr, "events_timer: set timeout %ldms\n", timeout_ms); +#endif ev->ms = timeout_ms; ev->msbump = TRUE; return 0; @@ -462,6 +460,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ struct events *ev = userp; struct socketmonitor *m; struct socketmonitor *prev = NULL; + bool found = FALSE; #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) easy; @@ -471,7 +470,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ m = ev->list; while(m) { if(m->socket.fd == s) { - + found = TRUE; if(what == CURL_POLL_REMOVE) { struct socketmonitor *nxt = m->next; /* remove this node from the list of monitored sockets */ @@ -480,15 +479,13 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ else ev->list = nxt; free(m); - m = nxt; - infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T - " REMOVED", s); + infof(easy, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s); } else { /* The socket 's' is already being monitored, update the activity mask. Convert from libcurl bitmask to the poll one. */ m->socket.events = socketcb2poll(what); - infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T + infof(easy, "socket cb: socket %" FMT_SOCKET_T " UPDATED as %s%s", s, (what&CURL_POLL_IN)?"IN":"", (what&CURL_POLL_OUT)?"OUT":""); @@ -498,12 +495,13 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ prev = m; m = m->next; /* move to next node */ } - if(!m) { + + if(!found) { if(what == CURL_POLL_REMOVE) { - /* this happens a bit too often, libcurl fix perhaps? */ - /* fprintf(stderr, - "%s: socket %d asked to be REMOVED but not present!\n", - __func__, s); */ + /* should not happen if our logic is correct, but is no drama. */ + DEBUGF(infof(easy, "socket cb: asked to REMOVE socket %" + FMT_SOCKET_T "but not present!", s)); + DEBUGASSERT(0); } else { m = malloc(sizeof(struct socketmonitor)); @@ -513,8 +511,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ m->socket.events = socketcb2poll(what); m->socket.revents = 0; ev->list = m; - infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T - " ADDED as %s%s", s, + infof(easy, "socket cb: socket %" FMT_SOCKET_T " ADDED as %s%s", s, (what&CURL_POLL_IN)?"IN":"", (what&CURL_POLL_OUT)?"OUT":""); } @@ -564,14 +561,15 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) int pollrc; int i; struct curltime before; - struct curltime after; /* populate the fds[] array */ for(m = ev->list, f = &fds[0]; m; m = m->next) { f->fd = m->socket.fd; f->events = m->socket.events; f->revents = 0; - /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */ +#if DEBUG_EV_POLL + fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); +#endif f++; numfds++; } @@ -579,12 +577,27 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) /* get the time stamp to use to figure out how long poll takes */ before = Curl_now(); - /* wait for activity or timeout */ - pollrc = Curl_poll(fds, (unsigned int)numfds, ev->ms); - if(pollrc < 0) - return CURLE_UNRECOVERABLE_POLL; - - after = Curl_now(); + if(numfds) { + /* wait for activity or timeout */ +#if DEBUG_EV_POLL + fprintf(stderr, "poll(numfds=%d, timeout=%ldms)\n", numfds, ev->ms); +#endif + pollrc = Curl_poll(fds, (unsigned int)numfds, ev->ms); +#if DEBUG_EV_POLL + fprintf(stderr, "poll(numfds=%d, timeout=%ldms) -> %d\n", + numfds, ev->ms, pollrc); +#endif + if(pollrc < 0) + return CURLE_UNRECOVERABLE_POLL; + } + else { +#if DEBUG_EV_POLL + fprintf(stderr, "poll, but no fds, wait timeout=%ldms\n", ev->ms); +#endif + pollrc = 0; + if(ev->ms > 0) + Curl_wait_ms(ev->ms); + } ev->msbump = FALSE; /* reset here */ @@ -597,26 +610,37 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) } else { /* here pollrc is > 0 */ + struct Curl_llist_node *e = Curl_llist_head(&multi->process); + struct Curl_easy *data; + DEBUGASSERT(e); + data = Curl_node_elem(e); + DEBUGASSERT(data); /* loop over the monitored sockets to see which ones had activity */ for(i = 0; i< numfds; i++) { if(fds[i].revents) { /* socket activity, tell libcurl */ int act = poll2cselect(fds[i].revents); /* convert */ - infof(multi->easyp, - "call curl_multi_socket_action(socket " - "%" CURL_FORMAT_SOCKET_T ")", fds[i].fd); + + /* sending infof "randomly" to the first easy handle */ + infof(data, "call curl_multi_socket_action(socket " + "%" FMT_SOCKET_T ")", (curl_socket_t)fds[i].fd); mcode = curl_multi_socket_action(multi, fds[i].fd, act, &ev->running_handles); } } - if(!ev->msbump) { + + if(!ev->msbump && ev->ms >= 0) { /* If nothing updated the timeout, we decrease it by the spent time. * If it was updated, it has the new timeout time stored already. */ - timediff_t timediff = Curl_timediff(after, before); + timediff_t timediff = Curl_timediff(Curl_now(), before); if(timediff > 0) { +#if DEBUG_EV_POLL + fprintf(stderr, "poll timeout %ldms not updated, decrease by " + "time spent %ldms\n", ev->ms, (long)timediff); +#endif if(timediff > ev->ms) ev->ms = 0; else @@ -649,7 +673,7 @@ static CURLcode easy_events(struct Curl_multi *multi) { /* this struct is made static to allow it to be used after this function returns and curl_multi_remove_handle() is called */ - static struct events evs = {2, FALSE, 0, NULL, 0}; + static struct events evs = {-1, FALSE, 0, NULL, 0}; /* if running event-based, do some further multi inits */ events_setup(multi, &evs); @@ -914,8 +938,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER); - /* the connection cache is setup on demand */ - outcurl->state.conn_cache = NULL; + /* the connection pool is setup on demand */ outcurl->state.lastconnect_id = -1; outcurl->state.recent_conn_id = -1; outcurl->id = -1; @@ -1012,7 +1035,9 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) goto fail; } #endif /* USE_ARES */ - +#ifndef CURL_DISABLE_HTTP + Curl_llist_init(&outcurl->state.httphdrs, NULL); +#endif Curl_initinfo(outcurl); outcurl->magic = CURLEASY_MAGIC_NUMBER; @@ -1112,7 +1137,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) (data->mstate == MSTATE_PERFORMING || data->mstate == MSTATE_RATELIMITING)); /* Unpausing writes is detected on the next run in - * transfer.c:Curl_readwrite(). This is because this may result + * transfer.c:Curl_sendrecv(). This is because this may result * in a transfer error if the application's callbacks fail */ /* Set the new keepon state, so it takes effect no matter what error @@ -1264,7 +1289,7 @@ CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, Curl_attach_connection(data, c); sigpipe_ignore(data, &pipe_st); - result = Curl_conn_send(data, FIRSTSOCKET, buffer, buflen, n); + result = Curl_conn_send(data, FIRSTSOCKET, buffer, buflen, FALSE, n); sigpipe_restore(&pipe_st); if(result && result != CURLE_AGAIN) @@ -1289,47 +1314,6 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, return result; } -/* - * Wrapper to call functions in Curl_conncache_foreach() - * - * Returns always 0. - */ -static int conn_upkeep(struct Curl_easy *data, - struct connectdata *conn, - void *param) -{ - struct curltime *now = param; - - if(Curl_timediff(*now, conn->keepalive) <= data->set.upkeep_interval_ms) - return 0; - - /* briefly attach for action */ - Curl_attach_connection(data, conn); - if(conn->handler->connection_check) { - /* Do a protocol-specific keepalive check on the connection. */ - conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE); - } - else { - /* Do the generic action on the FIRSTSOCKET filter chain */ - Curl_conn_keep_alive(data, conn, FIRSTSOCKET); - } - Curl_detach_connection(data); - - conn->keepalive = *now; - return 0; /* continue iteration */ -} - -static CURLcode upkeep(struct conncache *conn_cache, void *data) -{ - struct curltime now = Curl_now(); - /* Loop over every connection and make connection alive. */ - Curl_conncache_foreach(data, - conn_cache, - &now, - conn_upkeep); - return CURLE_OK; -} - /* * Performs connection upkeep for the given session handle. */ @@ -1339,12 +1323,9 @@ CURLcode curl_easy_upkeep(struct Curl_easy *data) if(!GOOD_EASY_HANDLE(data)) return CURLE_BAD_FUNCTION_ARGUMENT; - if(data->multi_easy) { - /* Use the common function to keep connections alive. */ - return upkeep(&data->multi_easy->conn_cache, data); - } - else { - /* No connections, so just return success */ - return CURLE_OK; - } + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + + /* Use the common function to keep connections alive. */ + return Curl_cpool_upkeep(data); } diff --git a/lib/escape.c b/lib/escape.c index 1633c2da2..9b6edb443 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -63,12 +63,12 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string, if(!string || (inlength < 0)) return NULL; - Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH * 3); - length = (inlength?(size_t)inlength:strlen(string)); if(!length) return strdup(""); + Curl_dyn_init(&d, length * 3 + 1); + while(length--) { /* treat the characters unsigned */ unsigned char in = (unsigned char)*string++; diff --git a/lib/file.c b/lib/file.c index 82ff151b6..01af52e72 100644 --- a/lib/file.c +++ b/lib/file.c @@ -223,7 +223,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done) * A leading slash in an AmigaDOS path denotes the parent * directory, and hence we block this as it is relative. * Absolute paths start with 'volumename:', so we check for - * this first. Failing that, we treat the path as a real unix + * this first. Failing that, we treat the path as a real Unix * path, but only if the application was compiled with -lunix. */ fd = -1; @@ -468,8 +468,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) static const char accept_ranges[]= { "Accept-ranges: bytes\r\n" }; if(expected_size >= 0) { headerlen = - msnprintf(header, sizeof(header), - "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", + msnprintf(header, sizeof(header), "Content-Length: %" FMT_OFF_T "\r\n", expected_size); result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); if(result) diff --git a/lib/fileinfo.h b/lib/fileinfo.h index ce009da06..0b3f56d9d 100644 --- a/lib/fileinfo.h +++ b/lib/fileinfo.h @@ -30,7 +30,7 @@ struct fileinfo { struct curl_fileinfo info; - struct Curl_llist_element list; + struct Curl_llist_node list; struct dynbuf buf; }; diff --git a/lib/formdata.c b/lib/formdata.c index 7a282bdd3..c260d442b 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -790,10 +790,10 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len) /* wrap call to fseeko so it matches the calling convention of callback */ static int fseeko_wrapper(void *stream, curl_off_t offset, int whence) { -#if defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO) - return fseeko(stream, (off_t)offset, whence); -#elif defined(HAVE__FSEEKI64) +#if defined(HAVE__FSEEKI64) return _fseeki64(stream, (__int64)offset, whence); +#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO) + return fseeko(stream, (off_t)offset, whence); #else if(offset > LONG_MAX) return -1; diff --git a/lib/ftp.c b/lib/ftp.c index ae340c44a..f9b7e089e 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -188,7 +188,7 @@ static CURLcode ftp_regular_transfer(struct Curl_easy *data, bool *done); #ifndef CURL_DISABLE_VERBOSE_STRINGS static void ftp_pasv_verbose(struct Curl_easy *data, struct Curl_addrinfo *ai, - char *newhost, /* ascii version */ + char *newhost, /* ASCII version */ int port); #endif static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data); @@ -327,7 +327,6 @@ static void freedirs(struct ftp_conn *ftpc) Curl_safefree(ftpc->newhost); } -#ifdef CURL_DO_LINEEND_CONV /*********************************************************************** * * Lineend Conversions @@ -369,7 +368,6 @@ static CURLcode ftp_cw_lc_write(struct Curl_easy *data, } /* either we just wrote the newline or it is part of the next * chunk of bytes we write. */ - data->state.crlf_conversions++; ctx->newline_pending = FALSE; } @@ -400,7 +398,6 @@ static CURLcode ftp_cw_lc_write(struct Curl_easy *data, /* EndOfStream, if we have a trailing cr, now is the time to write it */ if(ctx->newline_pending) { ctx->newline_pending = FALSE; - data->state.crlf_conversions++; return Curl_cwriter_write(data, writer->next, type, &nl, 1); } /* Always pass on the EOS type indicator */ @@ -418,7 +415,6 @@ static const struct Curl_cwtype ftp_cw_lc = { sizeof(struct ftp_cw_lc_ctx) }; -#endif /* CURL_DO_LINEEND_CONV */ /*********************************************************************** * * AcceptServerConnect() @@ -819,6 +815,8 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data, int cache_skip = 0; int value_to_be_ignored = 0; + CURL_TRC_FTP(data, "getFTPResponse start"); + if(ftpcode) *ftpcode = 0; /* 0 for errors */ else @@ -864,21 +862,27 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data, */ } else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) { - switch(SOCKET_READABLE(sockfd, interval_ms)) { - case -1: /* select() error, stop reading */ + curl_socket_t wsock = Curl_pp_needs_flush(data, pp)? + sockfd : CURL_SOCKET_BAD; + int ev = Curl_socket_check(sockfd, CURL_SOCKET_BAD, wsock, interval_ms); + if(ev < 0) { failf(data, "FTP response aborted due to select/poll error: %d", SOCKERRNO); return CURLE_RECV_ERROR; - - case 0: /* timeout */ + } + else if(ev == 0) { if(Curl_pgrsUpdate(data)) return CURLE_ABORTED_BY_CALLBACK; continue; /* just continue in our loop for the timeout duration */ + } + } - default: /* for clarity */ + if(Curl_pp_needs_flush(data, pp)) { + result = Curl_pp_flushsend(data, pp); + if(result) break; - } } + result = ftp_readresp(data, FIRSTSOCKET, pp, ftpcode, &nread); if(result) break; @@ -897,6 +901,8 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data, } /* while there is buffer left and loop is requested */ pp->pending_resp = FALSE; + CURL_TRC_FTP(data, "getFTPResponse -> result=%d, nread=%zd, ftpcode=%d", + result, *nreadp, *ftpcode); return result; } @@ -1042,7 +1048,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, int error; char *host = NULL; char *string_ftpport = data->set.str[STRING_FTPPORT]; - struct Curl_dns_entry *h = NULL; + struct Curl_dns_entry *dns_entry = NULL; unsigned short port_min = 0; unsigned short port_max = 0; unsigned short port; @@ -1178,15 +1184,12 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, } /* resolv ip/host to ip */ - rc = Curl_resolv(data, host, 0, FALSE, &h); + rc = Curl_resolv(data, host, 0, FALSE, &dns_entry); if(rc == CURLRESOLV_PENDING) - (void)Curl_resolver_wait_resolv(data, &h); - if(h) { - res = h->addr; - /* when we return from this function, we can forget about this entry - to we can unlock it now already */ - Curl_resolv_unlock(data, h); - } /* (h) */ + (void)Curl_resolver_wait_resolv(data, &dns_entry); + if(dns_entry) { + res = dns_entry->addr; + } else res = NULL; /* failure! */ @@ -1381,6 +1384,9 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, ftp_state(data, FTP_PORT); out: + /* If we looked up a dns_entry, now is the time to safely release it */ + if(dns_entry) + Curl_resolv_unlink(data, &dns_entry); if(result) { ftp_state(data, FTP_STOP); } @@ -2072,7 +2078,6 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, /* postponed address resolution in case of tcp fastopen */ if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) { - Curl_conn_ev_update_info(data, conn); Curl_safefree(ftpc->newhost); ftpc->newhost = strdup(control_address(conn)); if(!ftpc->newhost) @@ -2098,7 +2103,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE); if(result) { - Curl_resolv_unlock(data, addr); /* we are done using this address */ + Curl_resolv_unlink(data, &addr); /* we are done using this address */ if(ftpc->count1 == 0 && ftpcode == 229) return ftp_epsv_disable(data, conn); @@ -2116,7 +2121,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, /* this just dumps information about this second connection */ ftp_pasv_verbose(data, addr->addr, ftpc->newhost, connectport); - Curl_resolv_unlock(data, addr); /* we are done using this address */ + Curl_resolv_unlink(data, &addr); /* we are done using this address */ Curl_safefree(conn->secondaryhostname); conn->secondary_port = ftpc->newport; @@ -2383,8 +2388,8 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, if(data->state.resume_from< 0) { /* We are supposed to download the last abs(from) bytes */ if(filesize < -data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + failf(data, "Offset (%" FMT_OFF_T + ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, filesize); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -2395,8 +2400,8 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, } else { if(filesize < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + failf(data, "Offset (%" FMT_OFF_T + ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, filesize); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -2418,10 +2423,10 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, } /* Set resume file transfer offset */ - infof(data, "Instructs server to resume from offset %" - CURL_FORMAT_CURL_OFF_T, data->state.resume_from); + infof(data, "Instructs server to resume from offset %" FMT_OFF_T, + data->state.resume_from); - result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, + result = Curl_pp_sendf(data, &ftpc->pp, "REST %" FMT_OFF_T, data->state.resume_from); if(!result) ftp_state(data, FTP_RETR_REST); @@ -2479,7 +2484,7 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data, if(-1 != filesize) { char clbuf[128]; int clbuflen = msnprintf(clbuf, sizeof(clbuf), - "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize); + "Content-Length: %" FMT_OFF_T "\r\n", filesize); result = client_write_header(data, clbuf, clbuflen); if(result) return result; @@ -2659,12 +2664,10 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, else if((instate != FTP_LIST) && (data->state.prefer_ascii)) size = -1; /* kludge for servers that understate ASCII mode file size */ - infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T, - data->req.maxdownload); + infof(data, "Maxdownload = %" FMT_OFF_T, data->req.maxdownload); if(instate != FTP_LIST) - infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T, - size); + infof(data, "Getting file with size: %" FMT_OFF_T, size); /* FTP download: */ conn->proto.ftpc.state_saved = instate; @@ -3529,8 +3532,8 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, (data->state.infilesize != data->req.writebytecount) && !data->set.crlf && (ftp->transfer == PPTRANSFER_BODY)) { - failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T - " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", + failf(data, "Uploaded unaligned file size (%" FMT_OFF_T + " out of %" FMT_OFF_T " bytes)", data->req.writebytecount, data->state.infilesize); result = CURLE_PARTIAL_FILE; } @@ -3538,17 +3541,9 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, else { if((-1 != data->req.size) && (data->req.size != data->req.bytecount) && -#ifdef CURL_DO_LINEEND_CONV - /* Most FTP servers do not adjust their file SIZE response for CRLFs, - * so we will check to see if the discrepancy can be explained by the - * number of CRLFs we have changed to LFs. - */ - ((data->req.size + data->state.crlf_conversions) != - data->req.bytecount) && -#endif /* CURL_DO_LINEEND_CONV */ (data->req.maxdownload != data->req.bytecount)) { - failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T - " bytes", data->req.bytecount); + failf(data, "Received only partial file: %" FMT_OFF_T " bytes", + data->req.bytecount); result = CURLE_PARTIAL_FILE; } else if(!ftpc->dont_check && @@ -3684,7 +3679,7 @@ static CURLcode ftp_nb_type(struct Curl_easy *data, static void ftp_pasv_verbose(struct Curl_easy *data, struct Curl_addrinfo *ai, - char *newhost, /* ascii version */ + char *newhost, /* ASCII version */ int port) { char buf[256]; @@ -4027,7 +4022,7 @@ static CURLcode wc_statemach(struct Curl_easy *data) wildcard->state = CURLWC_CLEAN; continue; } - if(wildcard->filelist.size == 0) { + if(Curl_llist_count(&wildcard->filelist) == 0) { /* no corresponding file */ wildcard->state = CURLWC_CLEAN; return CURLE_REMOTE_FILE_NOT_FOUND; @@ -4038,7 +4033,8 @@ static CURLcode wc_statemach(struct Curl_easy *data) case CURLWC_DOWNLOADING: { /* filelist has at least one file, lets get first one */ struct ftp_conn *ftpc = &conn->proto.ftpc; - struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; + struct Curl_llist_node *head = Curl_llist_head(&wildcard->filelist); + struct curl_fileinfo *finfo = Curl_node_elem(head); struct FTP *ftp = data->req.p.ftp; char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); @@ -4054,7 +4050,8 @@ static CURLcode wc_statemach(struct Curl_easy *data) long userresponse; Curl_set_in_callback(data, true); userresponse = data->set.chunk_bgn( - finfo, data->set.wildcardptr, (int)wildcard->filelist.size); + finfo, data->set.wildcardptr, + (int)Curl_llist_count(&wildcard->filelist)); Curl_set_in_callback(data, false); switch(userresponse) { case CURL_CHUNK_BGN_FUNC_SKIP: @@ -4080,9 +4077,10 @@ static CURLcode wc_statemach(struct Curl_easy *data) return result; /* we do not need the Curl_fileinfo of first file anymore */ - Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + Curl_node_remove(Curl_llist_head(&wildcard->filelist)); - if(wildcard->filelist.size == 0) { /* remains only one file to down. */ + if(Curl_llist_count(&wildcard->filelist) == 0) { + /* remains only one file to down. */ wildcard->state = CURLWC_CLEAN; /* after that will be ftp_do called once again and no transfer will be done because of CURLWC_CLEAN state */ @@ -4097,8 +4095,8 @@ static CURLcode wc_statemach(struct Curl_easy *data) data->set.chunk_end(data->set.wildcardptr); Curl_set_in_callback(data, false); } - Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); - wildcard->state = (wildcard->filelist.size == 0) ? + Curl_node_remove(Curl_llist_head(&wildcard->filelist)); + wildcard->state = (Curl_llist_count(&wildcard->filelist) == 0) ? CURLWC_CLEAN : CURLWC_DOWNLOADING; continue; } @@ -4140,27 +4138,22 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done) CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; struct ftp_conn *ftpc = &conn->proto.ftpc; + /* FTP data may need conversion. */ + struct Curl_cwriter *ftp_lc_writer; *done = FALSE; /* default to false */ ftpc->wait_data_conn = FALSE; /* default to no such wait */ -#ifdef CURL_DO_LINEEND_CONV - { - /* FTP data may need conversion. */ - struct Curl_cwriter *ftp_lc_writer; - - result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, - CURL_CW_CONTENT_DECODE); - if(result) - return result; + result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, + CURL_CW_CONTENT_DECODE); + if(result) + return result; - result = Curl_cwriter_add(data, ftp_lc_writer); - if(result) { - Curl_cwriter_free(data, ftp_lc_writer); - return result; - } + result = Curl_cwriter_add(data, ftp_lc_writer); + if(result) { + Curl_cwriter_free(data, ftp_lc_writer); + return result; } -#endif /* CURL_DO_LINEEND_CONV */ if(data->state.wildcardmatch) { result = wc_statemach(data); diff --git a/lib/getinfo.c b/lib/getinfo.c index 9ca02889c..714610156 100644 --- a/lib/getinfo.c +++ b/lib/getinfo.c @@ -53,6 +53,7 @@ CURLcode Curl_initinfo(struct Curl_easy *data) pro->t_connect = 0; pro->t_appconnect = 0; pro->t_pretransfer = 0; + pro->t_posttransfer = 0; pro->t_starttransfer = 0; pro->timespent = 0; pro->t_redirect = 0; @@ -76,10 +77,9 @@ CURLcode Curl_initinfo(struct Curl_easy *data) free(info->wouldredirect); info->wouldredirect = NULL; - info->primary.remote_ip[0] = '\0'; - info->primary.local_ip[0] = '\0'; - info->primary.remote_port = 0; - info->primary.local_port = 0; + memset(&info->primary, 0, sizeof(info->primary)); + info->primary.remote_port = -1; + info->primary.local_port = -1; info->retry_after = 0; info->conn_scheme = 0; @@ -252,11 +252,13 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, case CURLINFO_SSL_VERIFYRESULT: *param_longp = data->set.ssl.certverifyresult; break; -#ifndef CURL_DISABLE_PROXY case CURLINFO_PROXY_SSL_VERIFYRESULT: +#ifndef CURL_DISABLE_PROXY *param_longp = data->set.proxy_ssl.certverifyresult; - break; +#else + *param_longp = 0; #endif + break; case CURLINFO_REDIRECT_COUNT: *param_longp = data->state.followlocation; break; @@ -314,6 +316,12 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, case CURLINFO_RTSP_CSEQ_RECV: *param_longp = data->state.rtsp_CSeq_recv; break; +#else + case CURLINFO_RTSP_CLIENT_CSEQ: + case CURLINFO_RTSP_SERVER_CSEQ: + case CURLINFO_RTSP_CSEQ_RECV: + *param_longp = 0; + break; #endif case CURLINFO_HTTP_VERSION: switch(data->info.httpversion) { @@ -368,6 +376,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, case CURLINFO_CONNECT_TIME_T: case CURLINFO_APPCONNECT_TIME_T: case CURLINFO_PRETRANSFER_TIME_T: + case CURLINFO_POSTTRANSFER_TIME_T: case CURLINFO_STARTTRANSFER_TIME_T: case CURLINFO_REDIRECT_TIME_T: case CURLINFO_SPEED_DOWNLOAD_T: @@ -384,24 +393,24 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, *param_offt = (curl_off_t)data->info.filetime; break; case CURLINFO_SIZE_UPLOAD_T: - *param_offt = data->progress.uploaded; + *param_offt = data->progress.ul.cur_size; break; case CURLINFO_SIZE_DOWNLOAD_T: - *param_offt = data->progress.downloaded; + *param_offt = data->progress.dl.cur_size; break; case CURLINFO_SPEED_DOWNLOAD_T: - *param_offt = data->progress.dlspeed; + *param_offt = data->progress.dl.speed; break; case CURLINFO_SPEED_UPLOAD_T: - *param_offt = data->progress.ulspeed; + *param_offt = data->progress.ul.speed; break; case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T: *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? - data->progress.size_dl:-1; + data->progress.dl.total_size:-1; break; case CURLINFO_CONTENT_LENGTH_UPLOAD_T: *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? - data->progress.size_ul:-1; + data->progress.ul.total_size:-1; break; case CURLINFO_TOTAL_TIME_T: *param_offt = data->progress.timespent; @@ -418,6 +427,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, case CURLINFO_PRETRANSFER_TIME_T: *param_offt = data->progress.t_pretransfer; break; + case CURLINFO_POSTTRANSFER_TIME_T: + *param_offt = data->progress.t_posttransfer; + break; case CURLINFO_STARTTRANSFER_TIME_T: *param_offt = data->progress.t_starttransfer; break; @@ -488,24 +500,24 @@ static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer); break; case CURLINFO_SIZE_UPLOAD: - *param_doublep = (double)data->progress.uploaded; + *param_doublep = (double)data->progress.ul.cur_size; break; case CURLINFO_SIZE_DOWNLOAD: - *param_doublep = (double)data->progress.downloaded; + *param_doublep = (double)data->progress.dl.cur_size; break; case CURLINFO_SPEED_DOWNLOAD: - *param_doublep = (double)data->progress.dlspeed; + *param_doublep = (double)data->progress.dl.speed; break; case CURLINFO_SPEED_UPLOAD: - *param_doublep = (double)data->progress.ulspeed; + *param_doublep = (double)data->progress.ul.speed; break; case CURLINFO_CONTENT_LENGTH_DOWNLOAD: *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? - (double)data->progress.size_dl:-1; + (double)data->progress.dl.total_size:-1; break; case CURLINFO_CONTENT_LENGTH_UPLOAD: *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? - (double)data->progress.size_ul:-1; + (double)data->progress.ul.total_size:-1; break; case CURLINFO_REDIRECT_TIME: *param_doublep = DOUBLE_SECS(data->progress.t_redirect); diff --git a/lib/gopher.c b/lib/gopher.c index ecea32633..051e6e7ab 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -187,7 +187,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done) if(strlen(sel) < 1) break; - result = Curl_xfer_send(data, sel, k, &amount); + result = Curl_xfer_send(data, sel, k, FALSE, &amount); if(!result) { /* Which may not have written it all! */ result = Curl_client_write(data, CLIENTWRITE_HEADER, sel, amount); if(result) @@ -229,7 +229,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done) free(sel_org); if(!result) - result = Curl_xfer_send(data, "\r\n", 2, &amount); + result = Curl_xfer_send(data, "\r\n", 2, FALSE, &amount); if(result) { failf(data, "Failed sending Gopher request"); return result; diff --git a/lib/hash.c b/lib/hash.c index df8e2abff..1910ac5dc 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -33,6 +33,10 @@ /* The last #include file should be: */ #include "memdebug.h" +/* random patterns for API verification */ +#define HASHINIT 0x7017e781 +#define ITERINIT 0x5FEDCBA9 + static void hash_element_dtor(void *user, void *element) { @@ -77,6 +81,9 @@ Curl_hash_init(struct Curl_hash *h, h->dtor = dtor; h->size = 0; h->slots = slots; +#ifdef DEBUGBUILD + h->init = HASHINIT; +#endif } static struct Curl_hash_element * @@ -102,11 +109,12 @@ void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, Curl_hash_elem_dtor dtor) { struct Curl_hash_element *he; - struct Curl_llist_element *le; + struct Curl_llist_node *le; struct Curl_llist *l; DEBUGASSERT(h); DEBUGASSERT(h->slots); + DEBUGASSERT(h->init == HASHINIT); if(!h->table) { size_t i; h->table = malloc(h->slots * sizeof(struct Curl_llist)); @@ -118,10 +126,10 @@ void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, l = FETCH_LIST(h, key, key_len); - for(le = l->head; le; le = le->next) { - he = (struct Curl_hash_element *) le->ptr; + for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) { + he = (struct Curl_hash_element *) Curl_node_elem(le); if(h->comp_func(he->key, he->key_len, key, key_len)) { - Curl_llist_remove(l, le, (void *)h); + Curl_node_uremove(le, (void *)h); --h->size; break; } @@ -158,18 +166,17 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p) */ int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len) { - struct Curl_llist_element *le; - struct Curl_llist *l; - DEBUGASSERT(h); DEBUGASSERT(h->slots); + DEBUGASSERT(h->init == HASHINIT); if(h->table) { - l = FETCH_LIST(h, key, key_len); + struct Curl_llist_node *le; + struct Curl_llist *l = FETCH_LIST(h, key, key_len); - for(le = l->head; le; le = le->next) { - struct Curl_hash_element *he = le->ptr; + for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) { + struct Curl_hash_element *he = Curl_node_elem(le); if(h->comp_func(he->key, he->key_len, key, key_len)) { - Curl_llist_remove(l, le, (void *) h); + Curl_node_uremove(le, (void *) h); --h->size; return 0; } @@ -185,15 +192,15 @@ int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len) void * Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len) { - struct Curl_llist_element *le; - struct Curl_llist *l; - DEBUGASSERT(h); + DEBUGASSERT(h->init == HASHINIT); if(h->table) { + struct Curl_llist_node *le; + struct Curl_llist *l; DEBUGASSERT(h->slots); l = FETCH_LIST(h, key, key_len); - for(le = l->head; le; le = le->next) { - struct Curl_hash_element *he = le->ptr; + for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) { + struct Curl_hash_element *he = Curl_node_elem(le); if(h->comp_func(he->key, he->key_len, key, key_len)) { return he->ptr; } @@ -213,6 +220,7 @@ Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len) void Curl_hash_destroy(struct Curl_hash *h) { + DEBUGASSERT(h->init == HASHINIT); if(h->table) { size_t i; for(i = 0; i < h->slots; ++i) { @@ -234,28 +242,33 @@ Curl_hash_clean(struct Curl_hash *h) Curl_hash_clean_with_criterium(h, NULL, NULL); } +size_t Curl_hash_count(struct Curl_hash *h) +{ + DEBUGASSERT(h->init == HASHINIT); + return h->size; +} + /* Cleans all entries that pass the comp function criteria. */ void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, int (*comp)(void *, void *)) { - struct Curl_llist_element *le; - struct Curl_llist_element *lnext; - struct Curl_llist *list; size_t i; if(!h || !h->table) return; + DEBUGASSERT(h->init == HASHINIT); for(i = 0; i < h->slots; ++i) { - list = &h->table[i]; - le = list->head; /* get first list entry */ + struct Curl_llist *list = &h->table[i]; + struct Curl_llist_node *le = + Curl_llist_head(list); /* get first list entry */ while(le) { - struct Curl_hash_element *he = le->ptr; - lnext = le->next; + struct Curl_hash_element *he = Curl_node_elem(le); + struct Curl_llist_node *lnext = Curl_node_next(le); /* ask the callback function if we shall remove this entry or not */ if(!comp || comp(user, he->ptr)) { - Curl_llist_remove(list, le, (void *) h); + Curl_node_uremove(le, (void *) h); --h->size; /* one less entry in the hash now */ } le = lnext; @@ -290,29 +303,34 @@ size_t Curl_str_key_compare(void *k1, size_t key1_len, void Curl_hash_start_iterate(struct Curl_hash *hash, struct Curl_hash_iterator *iter) { + DEBUGASSERT(hash->init == HASHINIT); iter->hash = hash; iter->slot_index = 0; iter->current_element = NULL; +#ifdef DEBUGBUILD + iter->init = ITERINIT; +#endif } struct Curl_hash_element * Curl_hash_next_element(struct Curl_hash_iterator *iter) { - struct Curl_hash *h = iter->hash; - + struct Curl_hash *h; + DEBUGASSERT(iter->init == ITERINIT); + h = iter->hash; if(!h->table) return NULL; /* empty hash, nothing to return */ /* Get the next element in the current list, if any */ if(iter->current_element) - iter->current_element = iter->current_element->next; + iter->current_element = Curl_node_next(iter->current_element); /* If we have reached the end of the list, find the next one */ if(!iter->current_element) { size_t i; for(i = iter->slot_index; i < h->slots; i++) { - if(h->table[i].head) { - iter->current_element = h->table[i].head; + if(Curl_llist_head(&h->table[i])) { + iter->current_element = Curl_llist_head(&h->table[i]); iter->slot_index = i + 1; break; } @@ -320,7 +338,7 @@ Curl_hash_next_element(struct Curl_hash_iterator *iter) } if(iter->current_element) { - struct Curl_hash_element *he = iter->current_element->ptr; + struct Curl_hash_element *he = Curl_node_elem(iter->current_element); return he; } return NULL; diff --git a/lib/hash.h b/lib/hash.h index 1cf787525..b16039502 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -56,22 +56,31 @@ struct Curl_hash { Curl_hash_dtor dtor; size_t slots; size_t size; +#ifdef DEBUGBUILD + int init; +#endif }; typedef void (*Curl_hash_elem_dtor)(void *key, size_t key_len, void *p); struct Curl_hash_element { - struct Curl_llist_element list; + struct Curl_llist_node list; void *ptr; Curl_hash_elem_dtor dtor; size_t key_len; +#ifdef DEBUGBUILD + int init; +#endif char key[1]; /* allocated memory following the struct */ }; struct Curl_hash_iterator { struct Curl_hash *hash; size_t slot_index; - struct Curl_llist_element *current_element; + struct Curl_llist_node *current_element; +#ifdef DEBUGBUILD + int init; +#endif }; void Curl_hash_init(struct Curl_hash *h, @@ -85,8 +94,9 @@ void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, Curl_hash_elem_dtor dtor); int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len); void *Curl_hash_pick(struct Curl_hash *, void *key, size_t key_len); -#define Curl_hash_count(h) ((h)->size) + void Curl_hash_destroy(struct Curl_hash *h); +size_t Curl_hash_count(struct Curl_hash *h); void Curl_hash_clean(struct Curl_hash *h); void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, int (*comp)(void *, void *)); diff --git a/lib/headers.c b/lib/headers.c index 59ac42225..7c60c0798 100644 --- a/lib/headers.c +++ b/lib/headers.c @@ -42,7 +42,7 @@ static void copy_header_external(struct Curl_header_store *hs, size_t index, size_t amount, - struct Curl_llist_element *e, + struct Curl_llist_node *e, struct curl_header *hout) { struct curl_header *h = hout; @@ -66,8 +66,8 @@ CURLHcode curl_easy_header(CURL *easy, int request, struct curl_header **hout) { - struct Curl_llist_element *e; - struct Curl_llist_element *e_pick = NULL; + struct Curl_llist_node *e; + struct Curl_llist_node *e_pick = NULL; struct Curl_easy *data = easy; size_t match = 0; size_t amount = 0; @@ -85,8 +85,8 @@ CURLHcode curl_easy_header(CURL *easy, request = data->state.requests; /* we need a first round to count amount of this header */ - for(e = data->state.httphdrs.head; e; e = e->next) { - hs = e->ptr; + for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { + hs = Curl_node_elem(e); if(strcasecompare(hs->name, name) && (hs->type & type) && (hs->request == request)) { @@ -104,8 +104,8 @@ CURLHcode curl_easy_header(CURL *easy, /* if the last or only occurrence is what's asked for, then we know it */ hs = pick; else { - for(e = data->state.httphdrs.head; e; e = e->next) { - hs = e->ptr; + for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { + hs = Curl_node_elem(e); if(strcasecompare(hs->name, name) && (hs->type & type) && (hs->request == request) && @@ -131,8 +131,8 @@ struct curl_header *curl_easy_nextheader(CURL *easy, struct curl_header *prev) { struct Curl_easy *data = easy; - struct Curl_llist_element *pick; - struct Curl_llist_element *e; + struct Curl_llist_node *pick; + struct Curl_llist_node *e; struct Curl_header_store *hs; size_t amount = 0; size_t index = 0; @@ -147,18 +147,18 @@ struct curl_header *curl_easy_nextheader(CURL *easy, if(!pick) /* something is wrong */ return NULL; - pick = pick->next; + pick = Curl_node_next(pick); } else - pick = data->state.httphdrs.head; + pick = Curl_llist_head(&data->state.httphdrs); if(pick) { /* make sure it is the next header of the desired type */ do { - hs = pick->ptr; + hs = Curl_node_elem(pick); if((hs->type & type) && (hs->request == request)) break; - pick = pick->next; + pick = Curl_node_next(pick); } while(pick); } @@ -166,12 +166,12 @@ struct curl_header *curl_easy_nextheader(CURL *easy, /* no more headers available */ return NULL; - hs = pick->ptr; + hs = Curl_node_elem(pick); /* count number of occurrences of this name within the mask and figure out the index for the currently selected entry */ - for(e = data->state.httphdrs.head; e; e = e->next) { - struct Curl_header_store *check = e->ptr; + for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { + struct Curl_header_store *check = Curl_node_elem(e); if(strcasecompare(hs->name, check->name) && (check->request == request) && (check->type & type)) @@ -247,7 +247,7 @@ static CURLcode unfold_value(struct Curl_easy *data, const char *value, /* since this header block might move in the realloc below, it needs to first be unlinked from the list and then re-added again after the realloc */ - Curl_llist_remove(&data->state.httphdrs, &hs->node, NULL); + Curl_node_remove(&hs->node); /* new size = struct + new value length + old name+value length */ newhs = Curl_saferealloc(hs, sizeof(*hs) + vlen + oalloc + 1); @@ -405,12 +405,12 @@ CURLcode Curl_headers_init(struct Curl_easy *data) */ CURLcode Curl_headers_cleanup(struct Curl_easy *data) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; + struct Curl_llist_node *e; + struct Curl_llist_node *n; - for(e = data->state.httphdrs.head; e; e = n) { - struct Curl_header_store *hs = e->ptr; - n = e->next; + for(e = Curl_llist_head(&data->state.httphdrs); e; e = n) { + struct Curl_header_store *hs = Curl_node_elem(e); + n = Curl_node_next(e); free(hs); } headers_reset(data); diff --git a/lib/headers.h b/lib/headers.h index d9813388c..e11fe9804 100644 --- a/lib/headers.h +++ b/lib/headers.h @@ -28,7 +28,7 @@ #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API) struct Curl_header_store { - struct Curl_llist_element node; + struct Curl_llist_node node; char *name; /* points into 'buffer' */ char *value; /* points into 'buffer */ int request; /* 0 is the first request, then 1.. 2.. */ diff --git a/lib/hostasyn.c b/lib/hostasyn.c index 2f6762ca4..4d6a8e859 100644 --- a/lib/hostasyn.c +++ b/lib/hostasyn.c @@ -79,7 +79,7 @@ CURLcode Curl_addrinfo_callback(struct Curl_easy *data, dns = Curl_cache_addr(data, ai, data->state.async.hostname, 0, - data->state.async.port); + data->state.async.port, FALSE); if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); diff --git a/lib/hostip.c b/lib/hostip.c index 2c1f08e74..fc01dc3fb 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -115,7 +115,7 @@ * CURLRES_* defines based on the config*.h and curl_setup.h defines. */ -static void freednsentry(void *freethis); +static void hostcache_unlink_entry(void *entry); #ifndef CURL_DISABLE_VERBOSE_STRINGS static void show_resolve_info(struct Curl_easy *data, @@ -178,7 +178,7 @@ create_hostcache_id(const char *name, struct hostcache_prune_data { time_t now; time_t oldest; /* oldest time in cache not pruned. */ - int cache_timeout; + int max_age_sec; }; /* @@ -189,16 +189,16 @@ struct hostcache_prune_data { * cache. */ static int -hostcache_timestamp_remove(void *datap, void *hc) +hostcache_entry_is_stale(void *datap, void *hc) { struct hostcache_prune_data *prune = (struct hostcache_prune_data *) datap; - struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc; + struct Curl_dns_entry *dns = (struct Curl_dns_entry *) hc; - if(c->timestamp) { + if(dns->timestamp) { /* age in seconds */ - time_t age = prune->now - c->timestamp; - if(age >= prune->cache_timeout) + time_t age = prune->now - dns->timestamp; + if(age >= prune->max_age_sec) return TRUE; if(age > prune->oldest) prune->oldest = age; @@ -216,13 +216,13 @@ hostcache_prune(struct Curl_hash *hostcache, int cache_timeout, { struct hostcache_prune_data user; - user.cache_timeout = cache_timeout; + user.max_age_sec = cache_timeout; user.now = now; user.oldest = 0; Curl_hash_clean_with_criterium(hostcache, (void *) &user, - hostcache_timestamp_remove); + hostcache_entry_is_stale); return user.oldest; } @@ -257,7 +257,8 @@ void Curl_hostcache_prune(struct Curl_easy *data) /* if the cache size is still too big, use the oldest age as new prune limit */ - } while(timeout && (data->dns.hostcache->size > MAX_DNS_CACHE_SIZE)); + } while(timeout && + (Curl_hash_count(data->dns.hostcache) > MAX_DNS_CACHE_SIZE)); if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -299,10 +300,10 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, struct hostcache_prune_data user; user.now = time(NULL); - user.cache_timeout = data->set.dns_cache_timeout; + user.max_age_sec = data->set.dns_cache_timeout; user.oldest = 0; - if(hostcache_timestamp_remove(&user, dns)) { + if(hostcache_entry_is_stale(&user, dns)) { infof(data, "Hostname in DNS cache was stale, zapped"); dns = NULL; /* the memory deallocation is being handled by the hash */ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); @@ -348,7 +349,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, * * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * The returned data *MUST* be "released" with Curl_resolv_unlink() after * use, or we will leak memory! */ struct Curl_dns_entry * @@ -364,7 +365,7 @@ Curl_fetch_addr(struct Curl_easy *data, dns = fetch_addr(data, hostname, port); if(dns) - dns->inuse++; /* we use it! */ + dns->refcount++; /* we use it! */ if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -468,7 +469,8 @@ Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr, const char *hostname, size_t hostlen, /* length or zero */ - int port) + int port, + bool permanent) { char entry_id[MAX_HOSTCACHE_LEN]; size_t entry_len; @@ -496,11 +498,15 @@ Curl_cache_addr(struct Curl_easy *data, entry_len = create_hostcache_id(hostname, hostlen, port, entry_id, sizeof(entry_id)); - dns->inuse = 1; /* the cache has the first reference */ + dns->refcount = 1; /* the cache has the first reference */ dns->addr = addr; /* this is the address(es) */ - time(&dns->timestamp); - if(dns->timestamp == 0) - dns->timestamp = 1; /* zero indicates permanent CURLOPT_RESOLVE entry */ + if(permanent) + dns->timestamp = 0; /* an entry that never goes stale */ + else { + dns->timestamp = time(NULL); + if(dns->timestamp == 0) + dns->timestamp = 1; + } dns->hostport = port; if(hostlen) memcpy(dns->hostname, hostname, hostlen); @@ -514,7 +520,7 @@ Curl_cache_addr(struct Curl_easy *data, } dns = dns2; - dns->inuse++; /* mark entry as in-use */ + dns->refcount++; /* mark entry as in-use */ return dns; } @@ -666,8 +672,8 @@ static bool tailmatch(const char *full, const char *part) * resolves. See the return codes. * * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_resolv_unlock() later (when you are - * done using this struct) to decrease the counter again. + * function is used. You MUST call Curl_resolv_unlink() later (when you are + * done using this struct) to decrease the reference counter again. * * Return codes: * @@ -708,7 +714,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, if(dns) { infof(data, "Hostname %s was found in DNS cache", hostname); - dns->inuse++; /* we use it! */ + dns->refcount++; /* we use it! */ rc = CURLRESOLV_RESOLVED; } @@ -828,7 +834,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); /* we got a response, store it in the cache */ - dns = Curl_cache_addr(data, addr, hostname, 0, port); + dns = Curl_cache_addr(data, addr, hostname, 0, port, FALSE); if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -868,8 +874,8 @@ void alarmfunc(int sig) * resolves. See the return codes. * * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_resolv_unlock() later (when you are - * done using this struct) to decrease the counter again. + * function is used. You MUST call Curl_resolv_unlink() later (when you are + * done using this struct) to decrease the reference counter again. * * If built with a synchronous resolver and use of signals is not * disabled by the application, then a nonzero timeout will cause a @@ -955,7 +961,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data, keep_copysig = TRUE; /* yes, we have a copy */ sigact.sa_handler = alarmfunc; #ifdef SA_RESTART - /* HPUX does not have SA_RESTART but defaults to that behavior! */ + /* HP-UX does not have SA_RESTART but defaults to that behavior! */ sigact.sa_flags &= ~SA_RESTART; #endif /* now set the new struct */ @@ -1037,18 +1043,20 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data, } /* - * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been - * made, the struct may be destroyed due to pruning. It is important that only - * one unlock is made for each Curl_resolv() call. + * Curl_resolv_unlink() releases a reference to the given cached DNS entry. + * When the reference count reaches 0, the entry is destroyed. It is important + * that only one unlink is made for each Curl_resolv() call. * * May be called with 'data' == NULL for global cache. */ -void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns) +void Curl_resolv_unlink(struct Curl_easy *data, struct Curl_dns_entry **pdns) { + struct Curl_dns_entry *dns = *pdns; + *pdns = NULL; if(data && data->share) Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - freednsentry(dns); + hostcache_unlink_entry(dns); if(data && data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -1057,13 +1065,13 @@ void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns) /* * File-internal: release cache dns entry reference, free if inuse drops to 0 */ -static void freednsentry(void *freethis) +static void hostcache_unlink_entry(void *entry) { - struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis; - DEBUGASSERT(dns && (dns->inuse>0)); + struct Curl_dns_entry *dns = (struct Curl_dns_entry *) entry; + DEBUGASSERT(dns && (dns->refcount>0)); - dns->inuse--; - if(dns->inuse == 0) { + dns->refcount--; + if(dns->refcount == 0) { Curl_freeaddrinfo(dns->addr); #ifdef USE_HTTPSRR if(dns->hinfo) { @@ -1092,7 +1100,7 @@ static void freednsentry(void *freethis) void Curl_init_dnscache(struct Curl_hash *hash, size_t size) { Curl_hash_init(hash, size, Curl_hash_str, Curl_str_key_compare, - freednsentry); + hostcache_unlink_entry); } /* @@ -1285,13 +1293,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* put this new host in the cache */ - dns = Curl_cache_addr(data, head, host_begin, hlen, port); + dns = Curl_cache_addr(data, head, host_begin, hlen, port, permanent); if(dns) { - if(permanent) - dns->timestamp = 0; /* mark as permanent */ /* release the returned reference; the cache itself will keep the * entry alive: */ - dns->inuse--; + dns->refcount--; } if(data->share) @@ -1443,8 +1449,7 @@ CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done) if(result) { Curl_detach_connection(data); - Curl_conncache_remove_conn(data, conn, TRUE); - Curl_disconnect(data, conn, TRUE); + Curl_cpool_disconnect(data, conn, TRUE); } return result; } diff --git a/lib/hostip.h b/lib/hostip.h index c85a688db..b1c5ecb2e 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -99,11 +99,11 @@ struct Curl_dns_entry { #endif /* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (does not time out) */ time_t timestamp; - /* use-counter, use Curl_resolv_unlock to release reference */ - long inuse; + /* reference counter, entry is freed on reaching 0 */ + size_t refcount; /* hostname port number that resolved to addr. */ int hostport; - /* hostname that resolved to addr. may be NULL (unix domain sockets). */ + /* hostname that resolved to addr. may be NULL (Unix domain sockets). */ char hostname[1]; }; @@ -113,7 +113,7 @@ bool Curl_host_is_ipnum(const char *hostname); * Curl_resolv() returns an entry with the info for the specified host * and port. * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * The returned data *MUST* be "released" with Curl_resolv_unlink() after * use, or we will leak memory! */ /* return codes */ @@ -161,9 +161,9 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, int *waitp); -/* unlock a previously resolved dns entry */ -void Curl_resolv_unlock(struct Curl_easy *data, - struct Curl_dns_entry *dns); +/* unlink a dns entry, potentially shared with a cache */ +void Curl_resolv_unlink(struct Curl_easy *data, + struct Curl_dns_entry **pdns); /* init a new dns cache */ void Curl_init_dnscache(struct Curl_hash *hash, size_t hashsize); @@ -199,7 +199,7 @@ void Curl_printable_address(const struct Curl_addrinfo *ip, * * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * The returned data *MUST* be "released" with Curl_resolv_unlink() after * use, or we will leak memory! */ struct Curl_dns_entry * @@ -209,12 +209,13 @@ Curl_fetch_addr(struct Curl_easy *data, /* * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. - * + * @param permanent iff TRUE, entry will never become stale * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. */ struct Curl_dns_entry * Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr, - const char *hostname, size_t hostlen, int port); + const char *hostname, size_t hostlen, int port, + bool permanent); #ifndef INADDR_NONE #define CURL_INADDR_NONE (in_addr_t) ~0 diff --git a/lib/hostip4.c b/lib/hostip4.c index 8da809db6..3bfea48d4 100644 --- a/lib/hostip4.c +++ b/lib/hostip4.c @@ -82,7 +82,7 @@ bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn) * detect which one this platform supports in the configure script and set up * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME - * has the corresponding rules. This is primarily on *nix. Note that some unix + * has the corresponding rules. This is primarily on *nix. Note that some Unix * flavours have thread-safe versions of the plain gethostbyname() etc. * */ @@ -221,7 +221,7 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, if(!h) /* failure */ #elif defined(HAVE_GETHOSTBYNAME_R_3) - /* AIX, Digital Unix/Tru64, HPUX 10, more? */ + /* AIX, Digital UNIX/Tru64, HP-UX 10, more? */ /* For AIX 4.3 or later, we do not use gethostbyname_r() at all, because of * the plain fact that it does not return unique full buffers on each diff --git a/lib/hostip6.c b/lib/hostip6.c index 18969a7a7..c16ddfe58 100644 --- a/lib/hostip6.c +++ b/lib/hostip6.c @@ -124,7 +124,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, #ifndef USE_RESOLVE_ON_IPS /* * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from - * an IPv4 address on iOS and Mac OS X. + * an IPv4 address on iOS and macOS. */ if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) || (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) { diff --git a/lib/hsts.c b/lib/hsts.c index 8cd77ae3c..a5c216f6d 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -94,11 +94,11 @@ void Curl_hsts_cleanup(struct hsts **hp) { struct hsts *h = *hp; if(h) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; - for(e = h->list.head; e; e = n) { - struct stsentry *sts = e->ptr; - n = e->next; + struct Curl_llist_node *e; + struct Curl_llist_node *n; + for(e = Curl_llist_head(&h->list); e; e = n) { + struct stsentry *sts = Curl_node_elem(e); + n = Curl_node_next(e); hsts_free(sts); } free(h->filename); @@ -215,7 +215,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, /* remove the entry if present verbatim (without subdomain match) */ sts = Curl_hsts(h, hostname, FALSE); if(sts) { - Curl_llist_remove(&h->list, &sts->node, NULL); + Curl_node_remove(&sts->node); hsts_free(sts); } return CURLE_OK; @@ -253,8 +253,8 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, char buffer[MAX_HSTS_HOSTLEN + 1]; time_t now = time(NULL); size_t hlen = strlen(hostname); - struct Curl_llist_element *e; - struct Curl_llist_element *n; + struct Curl_llist_node *e; + struct Curl_llist_node *n; if((hlen > MAX_HSTS_HOSTLEN) || !hlen) return NULL; @@ -265,12 +265,12 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, buffer[hlen] = 0; hostname = buffer; - for(e = h->list.head; e; e = n) { - struct stsentry *sts = e->ptr; - n = e->next; + for(e = Curl_llist_head(&h->list); e; e = n) { + struct stsentry *sts = Curl_node_elem(e); + n = Curl_node_next(e); if(sts->expires <= now) { /* remove expired entries */ - Curl_llist_remove(&h->list, &sts->node, NULL); + Curl_node_remove(&sts->node); hsts_free(sts); continue; } @@ -353,8 +353,8 @@ static CURLcode hsts_out(struct stsentry *sts, FILE *fp) CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, const char *file) { - struct Curl_llist_element *e; - struct Curl_llist_element *n; + struct Curl_llist_node *e; + struct Curl_llist_node *n; CURLcode result = CURLE_OK; FILE *out; char *tempstore = NULL; @@ -376,9 +376,9 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n" "# This file was generated by libcurl! Edit at your own risk.\n", out); - for(e = h->list.head; e; e = n) { - struct stsentry *sts = e->ptr; - n = e->next; + for(e = Curl_llist_head(&h->list); e; e = n) { + struct stsentry *sts = Curl_node_elem(e); + n = Curl_node_next(e); result = hsts_out(sts, out); if(result) break; @@ -395,12 +395,12 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, if(data->set.hsts_write) { /* if there is a write callback */ struct curl_index i; /* count */ - i.total = h->list.size; + i.total = Curl_llist_count(&h->list); i.index = 0; - for(e = h->list.head; e; e = n) { - struct stsentry *sts = e->ptr; + for(e = Curl_llist_head(&h->list); e; e = n) { + struct stsentry *sts = Curl_node_elem(e); bool stop; - n = e->next; + n = Curl_node_next(e); result = hsts_push(data, &i, sts, &stop); if(result || stop) break; diff --git a/lib/hsts.h b/lib/hsts.h index 21e53a342..1c544f97b 100644 --- a/lib/hsts.h +++ b/lib/hsts.h @@ -34,7 +34,7 @@ extern time_t deltatime; #endif struct stsentry { - struct Curl_llist_element node; + struct Curl_llist_node node; const char *host; bool includeSubDomains; curl_off_t expires; /* the timestamp of this entry's expiry */ diff --git a/lib/http.c b/lib/http.c index cb379e7f9..0cd2d4f2a 100644 --- a/lib/http.c +++ b/lib/http.c @@ -462,16 +462,15 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, if(abort_upload) { if(upload_remain >= 0) - infof(data, "%s%sclose instead of sending %" - CURL_FORMAT_CURL_OFF_T " more bytes", - ongoing_auth? ongoing_auth : "", - ongoing_auth? " send, " : "", - upload_remain); + infof(data, "%s%sclose instead of sending %" FMT_OFF_T " more bytes", + ongoing_auth? ongoing_auth : "", + ongoing_auth? " send, " : "", + upload_remain); else infof(data, "%s%sclose instead of sending unknown amount " - "of more bytes", - ongoing_auth? ongoing_auth : "", - ongoing_auth? " send, " : ""); + "of more bytes", + ongoing_auth? ongoing_auth : "", + ongoing_auth? " send, " : ""); /* We decided to abort the ongoing transfer */ streamclose(conn, "Mid-auth HTTP and much data left to send"); /* FIXME: questionable manipulation here, can we do this differently? */ @@ -2049,7 +2048,7 @@ static CURLcode http_resume(struct Curl_easy *data, Curl_HttpReq httpreq) CURLcode result; result = Curl_creader_resume_from(data, data->state.resume_from); if(result) { - failf(data, "Unable to resume from offset %" CURL_FORMAT_CURL_OFF_T, + failf(data, "Unable to resume from offset %" FMT_OFF_T, data->state.resume_from); return result; } @@ -2186,9 +2185,8 @@ CURLcode Curl_http_req_complete(struct Curl_easy *data, !Curl_checkheaders(data, STRCONST("Content-Length")))) { /* we allow replacing this header if not during auth negotiation, although it is not very wise to actually set your own */ - result = Curl_dyn_addf(r, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T - "\r\n", req_clen); + result = Curl_dyn_addf(r, "Content-Length: %" FMT_OFF_T "\r\n", + req_clen); } if(result) goto out; @@ -2343,8 +2341,7 @@ CURLcode Curl_http_range(struct Curl_easy *data, remote part so we tell the server (and act accordingly) that we upload the whole file (again) */ data->state.aptr.rangeline = - aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T - "/%" CURL_FORMAT_CURL_OFF_T "\r\n", + aprintf("Content-Range: bytes 0-%" FMT_OFF_T "/%" FMT_OFF_T "\r\n", req_clen - 1, req_clen); } @@ -2357,15 +2354,14 @@ CURLcode Curl_http_range(struct Curl_easy *data, data->state.infilesize : (data->state.resume_from + req_clen); data->state.aptr.rangeline = - aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T - "/%" CURL_FORMAT_CURL_OFF_T "\r\n", + aprintf("Content-Range: bytes %s%" FMT_OFF_T "/%" FMT_OFF_T "\r\n", data->state.range, total_len-1, total_len); } else { /* Range was selected and then we just pass the incoming range and append total size */ data->state.aptr.rangeline = - aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n", + aprintf("Content-Range: bytes %s/%" FMT_OFF_T "\r\n", data->state.range, req_clen); } if(!data->state.aptr.rangeline) @@ -3118,7 +3114,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, #ifdef DEBUGBUILD else infof(data, "Parsed STS header fine (%zu entries)", - data->hsts->list.size); + Curl_llist_count(&data->hsts->list)); #endif } #endif @@ -3154,6 +3150,11 @@ CURLcode Curl_http_header(struct Curl_easy *data, } return CURLE_OK; } + v = HD_VAL(hd, hdlen, "Trailer:"); + if(v) { + data->req.resp_trailer = TRUE; + return CURLE_OK; + } break; case 'w': case 'W': @@ -3241,9 +3242,6 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, else if(k->httpversion == 20 || (k->upgr101 == UPGR101_H2 && k->httpcode == 101)) { DEBUGF(infof(data, "HTTP/2 found, allow multiplexing")); - /* HTTP/2 cannot avoid multiplexing since it is a core functionality - of the protocol */ - conn->bundle->multiuse = BUNDLE_MULTIPLEX; } k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; @@ -3393,9 +3391,6 @@ static CURLcode http_on_response(struct Curl_easy *data, if(conn->httpversion != 20) infof(data, "Lying server, not serving HTTP/2"); } - if(conn->httpversion < 20) { - conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; - } if(k->httpcode < 200 && last_hd) { /* Intermediate responses might trigger processing of more @@ -3440,6 +3435,7 @@ static CURLcode http_on_response(struct Curl_easy *data, /* Switching to HTTP/2, where we will get more responses */ infof(data, "Received 101, Switching to HTTP/2"); k->upgr101 = UPGR101_RECEIVED; + data->conn->bits.asks_multiplex = FALSE; /* We expect more response from HTTP/2 later */ k->header = TRUE; k->headerline = 0; /* restart the header line counter */ @@ -3486,6 +3482,7 @@ static CURLcode http_on_response(struct Curl_easy *data, if(k->upgr101 == UPGR101_H2) { /* A requested upgrade was denied, poke the multi handle to possibly allow a pending pipewait to continue */ + data->conn->bits.asks_multiplex = FALSE; Curl_multi_connchanged(data->multi); } @@ -3535,7 +3532,7 @@ static CURLcode http_on_response(struct Curl_easy *data, #endif #ifdef USE_WEBSOCKETS - /* All >=200 HTTP status codes are errors when wanting websockets */ + /* All >=200 HTTP status codes are errors when wanting WebSockets */ if(data->req.upgr101 == UPGR101_WS) { failf(data, "Refused WebSockets upgrade: %d", k->httpcode); result = CURLE_HTTP_RETURNED_ERROR; @@ -4431,9 +4428,18 @@ static CURLcode cr_exp100_read(struct Curl_easy *data, switch(ctx->state) { case EXP100_SENDING_REQUEST: + if(!Curl_req_sendbuf_empty(data)) { + /* The initial request data has not been fully sent yet. Do + * not start the timer yet. */ + DEBUGF(infof(data, "cr_exp100_read, request not full sent yet")); + *nread = 0; + *eos = FALSE; + return CURLE_OK; + } /* We are now waiting for a reply from the server or - * a timeout on our side */ - DEBUGF(infof(data, "cr_exp100_read, start AWAITING_CONTINUE")); + * a timeout on our side IFF the request has been fully sent. */ + DEBUGF(infof(data, "cr_exp100_read, start AWAITING_CONTINUE, " + "timeout %ldms", data->set.expect_100_timeout)); ctx->state = EXP100_AWAITING_CONTINUE; ctx->start = Curl_now(); Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); diff --git a/lib/http2.c b/lib/http2.c index 6a979c136..bc50a2f7a 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -69,25 +69,32 @@ /* buffer dimensioning: * use 16K as chunk size, as that fits H2 DATA frames well */ #define H2_CHUNK_SIZE (16 * 1024) -/* this is how much we want "in flight" for a stream */ -#define H2_STREAM_WINDOW_SIZE (10 * 1024 * 1024) +/* connection window size */ +#define H2_CONN_WINDOW_SIZE (10 * 1024 * 1024) /* on receiving from TLS, we prep for holding a full stream window */ -#define H2_NW_RECV_CHUNKS (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) +#define H2_NW_RECV_CHUNKS (H2_CONN_WINDOW_SIZE / H2_CHUNK_SIZE) /* on send into TLS, we just want to accumulate small frames */ #define H2_NW_SEND_CHUNKS 1 -/* stream recv/send chunks are a result of window / chunk sizes */ -#define H2_STREAM_RECV_CHUNKS (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) +/* this is how much we want "in flight" for a stream, unthrottled */ +#define H2_STREAM_WINDOW_SIZE_MAX (10 * 1024 * 1024) +/* this is how much we want "in flight" for a stream, initially, IFF + * nghttp2 allows us to tweak the local window size. */ +#if NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE +#define H2_STREAM_WINDOW_SIZE_INITIAL (64 * 1024) +#else +#define H2_STREAM_WINDOW_SIZE_INITIAL H2_STREAM_WINDOW_SIZE_MAX +#endif /* keep smaller stream upload buffer (default h2 window size) to have * our progress bars and "upload done" reporting closer to reality */ #define H2_STREAM_SEND_CHUNKS ((64 * 1024) / H2_CHUNK_SIZE) /* spare chunks we keep for a full window */ -#define H2_STREAM_POOL_SPARES (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) +#define H2_STREAM_POOL_SPARES (H2_CONN_WINDOW_SIZE / H2_CHUNK_SIZE) /* We need to accommodate the max number of streams with their window sizes on * the overall connection. Streams might become PAUSED which will block their * received QUOTA in the connection window. If we run out of space, the server * is blocked from sending us any data. See #10988 for an issue with this. */ -#define HTTP2_HUGE_WINDOW_SIZE (100 * H2_STREAM_WINDOW_SIZE) +#define HTTP2_HUGE_WINDOW_SIZE (100 * H2_STREAM_WINDOW_SIZE_MAX) #define H2_SETTINGS_IV_LEN 3 #define H2_BINSETTINGS_LEN 80 @@ -99,7 +106,7 @@ static size_t populate_settings(nghttp2_settings_entry *iv, iv[0].value = Curl_multi_max_concurrent_streams(data->multi); iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - iv[1].value = H2_STREAM_WINDOW_SIZE; + iv[1].value = H2_STREAM_WINDOW_SIZE_INITIAL; iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; iv[2].value = data->multi->push_cb != NULL; @@ -129,12 +136,14 @@ struct cf_h2_ctx { struct bufc_pool stream_bufcp; /* spares for stream buffers */ struct dynbuf scratch; /* scratch buffer for temp use */ - struct Curl_hash streams; /* hash of `data->id` to `h2_stream_ctx` */ + struct Curl_hash streams; /* hash of `data->mid` to `h2_stream_ctx` */ size_t drain_total; /* sum of all stream's UrlState drain */ uint32_t max_concurrent_streams; uint32_t goaway_error; /* goaway error code from server */ int32_t remote_max_sid; /* max id processed by server */ int32_t local_max_sid; /* max id processed by us */ + BIT(initialized); + BIT(via_h1_upgrade); BIT(conn_closed); BIT(rcvd_goaway); BIT(sent_goaway); @@ -147,28 +156,38 @@ struct cf_h2_ctx { #define CF_CTX_CALL_DATA(cf) \ ((struct cf_h2_ctx *)(cf)->ctx)->call_data -static void cf_h2_ctx_clear(struct cf_h2_ctx *ctx) +static void h2_stream_hash_free(void *stream); + +static void cf_h2_ctx_init(struct cf_h2_ctx *ctx, bool via_h1_upgrade) { - struct cf_call_data save = ctx->call_data; + Curl_bufcp_init(&ctx->stream_bufcp, H2_CHUNK_SIZE, H2_STREAM_POOL_SPARES); + Curl_bufq_initp(&ctx->inbufq, &ctx->stream_bufcp, H2_NW_RECV_CHUNKS, 0); + Curl_bufq_initp(&ctx->outbufq, &ctx->stream_bufcp, H2_NW_SEND_CHUNKS, 0); + Curl_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); + Curl_hash_offt_init(&ctx->streams, 63, h2_stream_hash_free); + ctx->remote_max_sid = 2147483647; + ctx->via_h1_upgrade = via_h1_upgrade; + ctx->initialized = TRUE; +} - if(ctx->h2) { - nghttp2_session_del(ctx->h2); +static void cf_h2_ctx_free(struct cf_h2_ctx *ctx) +{ + if(ctx && ctx->initialized) { + Curl_bufq_free(&ctx->inbufq); + Curl_bufq_free(&ctx->outbufq); + Curl_bufcp_free(&ctx->stream_bufcp); + Curl_dyn_free(&ctx->scratch); + Curl_hash_clean(&ctx->streams); + Curl_hash_destroy(&ctx->streams); + memset(ctx, 0, sizeof(*ctx)); } - Curl_bufq_free(&ctx->inbufq); - Curl_bufq_free(&ctx->outbufq); - Curl_bufcp_free(&ctx->stream_bufcp); - Curl_dyn_free(&ctx->scratch); - Curl_hash_clean(&ctx->streams); - Curl_hash_destroy(&ctx->streams); - memset(ctx, 0, sizeof(*ctx)); - ctx->call_data = save; + free(ctx); } -static void cf_h2_ctx_free(struct cf_h2_ctx *ctx) +static void cf_h2_ctx_close(struct cf_h2_ctx *ctx) { - if(ctx) { - cf_h2_ctx_clear(ctx); - free(ctx); + if(ctx->h2) { + nghttp2_session_del(ctx->h2); } } @@ -184,8 +203,6 @@ struct h2_stream_ctx { struct h1_req_parser h1; /* parsing the request */ struct dynhds resp_trailers; /* response trailer fields */ size_t resp_hds_len; /* amount of response header bytes in recvbuf */ - size_t upload_blocked_len; - curl_off_t upload_left; /* number of request bytes left to upload */ curl_off_t nrcvd_data; /* number of DATA bytes received */ char **push_headers; /* allocated array */ @@ -195,19 +212,19 @@ struct h2_stream_ctx { int status_code; /* HTTP response status code */ uint32_t error; /* stream error code */ CURLcode xfer_result; /* Result of writing out response */ - uint32_t local_window_size; /* the local recv window size */ + int32_t local_window_size; /* the local recv window size */ int32_t id; /* HTTP/2 protocol identifier for stream */ BIT(resp_hds_complete); /* we have a complete, final response */ BIT(closed); /* TRUE on stream close */ BIT(reset); /* TRUE on stream reset */ BIT(close_handled); /* TRUE if stream closure is handled by libcurl */ BIT(bodystarted); - BIT(send_closed); /* transfer is done sending, we might have still - buffered data in stream->sendbuf to upload. */ + BIT(body_eos); /* the complete body has been added to `sendbuf` and + * is being/has been processed from there. */ }; #define H2_STREAM_CTX(ctx,data) ((struct h2_stream_ctx *)(\ - data? Curl_hash_offt_get(&(ctx)->streams, (data)->id) : NULL)) + data? Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL)) static struct h2_stream_ctx *h2_stream_ctx_create(struct cf_h2_ctx *ctx) { @@ -229,8 +246,7 @@ static struct h2_stream_ctx *h2_stream_ctx_create(struct cf_h2_ctx *ctx) stream->closed = FALSE; stream->close_handled = FALSE; stream->error = NGHTTP2_NO_ERROR; - stream->local_window_size = H2_STREAM_WINDOW_SIZE; - stream->upload_left = 0; + stream->local_window_size = H2_STREAM_WINDOW_SIZE_INITIAL; stream->nrcvd_data = 0; return stream; } @@ -259,6 +275,77 @@ static void h2_stream_hash_free(void *stream) h2_stream_ctx_free((struct h2_stream_ctx *)stream); } +#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE +static int32_t cf_h2_get_desired_local_win(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + (void)cf; + if(data->set.max_recv_speed && data->set.max_recv_speed < INT32_MAX) { + /* The transfer should only receive `max_recv_speed` bytes per second. + * We restrict the stream's local window size, so that the server cannot + * send us "too much" at a time. + * This gets less precise the higher the latency. */ + return (int32_t)data->set.max_recv_speed; + } + return H2_STREAM_WINDOW_SIZE_MAX; +} + +static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h2_stream_ctx *stream, + bool paused) +{ + struct cf_h2_ctx *ctx = cf->ctx; + int32_t dwsize; + int rv; + + dwsize = paused? 0 : cf_h2_get_desired_local_win(cf, data); + if(dwsize != stream->local_window_size) { + int32_t wsize = nghttp2_session_get_stream_effective_local_window_size( + ctx->h2, stream->id); + if(dwsize > wsize) { + rv = nghttp2_submit_window_update(ctx->h2, NGHTTP2_FLAG_NONE, + stream->id, dwsize - wsize); + if(rv) { + failf(data, "[%d] nghttp2_submit_window_update() failed: " + "%s(%d)", stream->id, nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } + stream->local_window_size = dwsize; + CURL_TRC_CF(data, cf, "[%d] local window update by %d", + stream->id, dwsize - wsize); + } + else { + rv = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, + stream->id, dwsize); + if(rv) { + failf(data, "[%d] nghttp2_session_set_local_window_size() failed: " + "%s(%d)", stream->id, nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } + stream->local_window_size = dwsize; + CURL_TRC_CF(data, cf, "[%d] local window size now %d", + stream->id, dwsize); + } + } + return CURLE_OK; +} + +#else /* NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE */ + +static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h2_stream_ctx *stream, + bool paused) +{ + (void)cf; + (void)data; + (void)stream; + (void)paused; + return CURLE_OK; +} +#endif /* !NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE */ + /* * Mark this transfer to get "drained". */ @@ -270,10 +357,10 @@ static void drain_stream(struct Curl_cfilter *cf, (void)cf; bits = CURL_CSELECT_IN; - if(!stream->send_closed && - (stream->upload_left || stream->upload_blocked_len)) + if(!stream->closed && + (!stream->body_eos || !Curl_bufq_is_empty(&stream->sendbuf))) bits |= CURL_CSELECT_OUT; - if(data->state.select_bits != bits) { + if(stream->closed || (data->state.select_bits != bits)) { CURL_TRC_CF(data, cf, "[%d] DRAIN select_bits=%x", stream->id, bits); data->state.select_bits = bits; @@ -300,7 +387,7 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf, if(!stream) return CURLE_OUT_OF_MEMORY; - if(!Curl_hash_offt_set(&ctx->streams, data->id, stream)) { + if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) { h2_stream_ctx_free(stream); return CURLE_OUT_OF_MEMORY; } @@ -315,7 +402,7 @@ static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); DEBUGASSERT(ctx); - if(!stream) + if(!stream || !ctx->initialized) return; if(ctx->h2) { @@ -329,7 +416,6 @@ static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) stream->id); stream->closed = TRUE; stream->reset = TRUE; - stream->send_closed = TRUE; nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, stream->id, NGHTTP2_STREAM_CLOSED); flush_egress = TRUE; @@ -339,7 +425,7 @@ static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) nghttp2_session_send(ctx->h2); } - Curl_hash_offt_remove(&ctx->streams, data->id); + Curl_hash_offt_remove(&ctx->streams, data->mid); } static int h2_client_new(struct Curl_cfilter *cf, @@ -382,8 +468,8 @@ static ssize_t nw_out_writer(void *writer_ctx, struct Curl_easy *data = CF_DATA_CURRENT(cf); if(data) { - ssize_t nwritten = Curl_conn_cf_send(cf->next, data, - (const char *)buf, buflen, err); + ssize_t nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, + buflen, FALSE, err); if(nwritten > 0) CURL_TRC_CF(data, cf, "[0] egress: wrote %zd bytes", nwritten); return nwritten; @@ -415,12 +501,8 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, static int error_callback(nghttp2_session *session, const char *msg, size_t len, void *userp); -/* - * Initialize the cfilter context - */ -static CURLcode cf_h2_ctx_init(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool via_h1_upgrade) +static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf, + struct Curl_easy *data) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream; @@ -429,12 +511,7 @@ static CURLcode cf_h2_ctx_init(struct Curl_cfilter *cf, nghttp2_session_callbacks *cbs = NULL; DEBUGASSERT(!ctx->h2); - Curl_bufcp_init(&ctx->stream_bufcp, H2_CHUNK_SIZE, H2_STREAM_POOL_SPARES); - Curl_bufq_initp(&ctx->inbufq, &ctx->stream_bufcp, H2_NW_RECV_CHUNKS, 0); - Curl_bufq_initp(&ctx->outbufq, &ctx->stream_bufcp, H2_NW_SEND_CHUNKS, 0); - Curl_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); - Curl_hash_offt_init(&ctx->streams, 63, h2_stream_hash_free); - ctx->remote_max_sid = 2147483647; + DEBUGASSERT(ctx->initialized); rc = nghttp2_session_callbacks_new(&cbs); if(rc) { @@ -463,7 +540,7 @@ static CURLcode cf_h2_ctx_init(struct Curl_cfilter *cf, } ctx->max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS; - if(via_h1_upgrade) { + if(ctx->via_h1_upgrade) { /* HTTP/1.1 Upgrade issued. H2 Settings have already been submitted * in the H1 request and we upgrade from there. This stream * is opened implicitly as #1. */ @@ -529,7 +606,7 @@ static CURLcode cf_h2_ctx_init(struct Curl_cfilter *cf, /* all set, traffic will be send on connect */ result = CURLE_OK; CURL_TRC_CF(data, cf, "[0] created h2 session%s", - via_h1_upgrade? " (via h1 upgrade)" : ""); + ctx->via_h1_upgrade? " (via h1 upgrade)" : ""); out: if(cbs) @@ -975,6 +1052,8 @@ static void h2_xfer_write_resp_hd(struct Curl_cfilter *cf, /* If we already encountered an error, skip further writes */ if(!stream->xfer_result) { stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos); + if(!stream->xfer_result && !eos) + stream->xfer_result = cf_h2_update_local_win(cf, data, stream, FALSE); if(stream->xfer_result) CURL_TRC_CF(data, cf, "[%d] error %d writing %zu bytes of headers", stream->id, stream->xfer_result, blen); @@ -990,6 +1069,8 @@ static void h2_xfer_write_resp(struct Curl_cfilter *cf, /* If we already encountered an error, skip further writes */ if(!stream->xfer_result) stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos); + if(!stream->xfer_result && !eos) + stream->xfer_result = cf_h2_update_local_win(cf, data, stream, FALSE); /* If the transfer write is errored, we do not want any more data */ if(stream->xfer_result) { struct cf_h2_ctx *ctx = cf->ctx; @@ -1083,13 +1164,19 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf, if(frame->rst_stream.error_code) { stream->reset = TRUE; } - stream->send_closed = TRUE; drain_stream(cf, data, stream); break; case NGHTTP2_WINDOW_UPDATE: - if(CURL_WANT_SEND(data)) { + if(CURL_WANT_SEND(data) && Curl_bufq_is_empty(&stream->sendbuf)) { + /* need more data, force processing of transfer */ drain_stream(cf, data, stream); } + else if(!Curl_bufq_is_empty(&stream->sendbuf)) { + /* resume the potentially suspended stream */ + rv = nghttp2_session_resume_data(ctx->h2, stream->id); + if(nghttp2_is_fatal(rv)) + return CURLE_SEND_ERROR; + } break; default: break; @@ -1300,9 +1387,6 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, nghttp2_session_consume(ctx->h2, stream_id, len); stream->nrcvd_data += (curl_off_t)len; - - /* if we receive data for another handle, wake that up */ - drain_stream(cf, data_s, stream); return 0; } @@ -1317,8 +1401,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, (void)session; DEBUGASSERT(call_data); - /* get the stream from the hash based on Stream ID, stream ID zero is for - connection-oriented stuff */ + /* stream id 0 is the connection, do not look there for streams. */ data_s = stream_id? nghttp2_session_get_stream_user_data(session, stream_id) : NULL; if(!data_s) { @@ -1346,7 +1429,6 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, stream->error = error_code; if(stream->error) { stream->reset = TRUE; - stream->send_closed = TRUE; } if(stream->error) @@ -1572,22 +1654,21 @@ static ssize_t req_body_read_callback(nghttp2_session *session, (void)source; (void)cf; - if(stream_id) { - /* get the stream from the hash based on Stream ID, stream ID zero is for - connection-oriented stuff */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - else + if(!stream_id) return NGHTTP2_ERR_INVALID_ARGUMENT; + /* get the stream from the hash based on Stream ID, stream ID zero is for + connection-oriented stuff */ + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) + /* Receiving a Stream ID not in the hash should not happen, this is an + internal error more than anything else! */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + + stream = H2_STREAM_CTX(ctx, data_s); + if(!stream) + return NGHTTP2_ERR_CALLBACK_FAILURE; + nread = Curl_bufq_read(&stream->sendbuf, buf, length, &result); if(nread < 0) { if(result != CURLE_AGAIN) @@ -1595,17 +1676,13 @@ static ssize_t req_body_read_callback(nghttp2_session *session, nread = 0; } - if(nread > 0 && stream->upload_left != -1) - stream->upload_left -= nread; - - CURL_TRC_CF(data_s, cf, "[%d] req_body_read(len=%zu) left=%" - CURL_FORMAT_CURL_OFF_T " -> %zd, %d", - stream_id, length, stream->upload_left, nread, result); + CURL_TRC_CF(data_s, cf, "[%d] req_body_read(len=%zu) eos=%d -> %zd, %d", + stream_id, length, stream->body_eos, nread, result); - if(stream->upload_left == 0) - *data_flags = NGHTTP2_DATA_FLAG_EOF; - else if(nread == 0) + if(nread == 0) return NGHTTP2_ERR_DEFERRED; + if(stream->body_eos && Curl_bufq_is_empty(&stream->sendbuf)) + *data_flags = NGHTTP2_DATA_FLAG_EOF; return nread; } @@ -1659,37 +1736,11 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, free(base64); k->upgr101 = UPGR101_H2; + data->conn->bits.asks_multiplex = TRUE; return result; } -static CURLcode http2_data_done_send(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - - if(!ctx || !ctx->h2 || !stream) - goto out; - - CURL_TRC_CF(data, cf, "[%d] data done send", stream->id); - if(!stream->send_closed) { - stream->send_closed = TRUE; - if(stream->upload_left) { - /* we now know that everything that is buffered is all there is. */ - stream->upload_left = Curl_bufq_len(&stream->sendbuf); - /* resume sending here to trigger the callback to get called again so - that it can signal EOF to nghttp2 */ - (void)nghttp2_session_resume_data(ctx->h2, stream->id); - drain_stream(cf, data, stream); - } - } - -out: - return result; -} - static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf, struct Curl_easy *data, struct h2_stream_ctx *stream, @@ -1934,12 +1985,15 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, if(h2_process_pending_input(cf, data, &result)) return result; + CURL_TRC_CF(data, cf, "[0] progress ingress: inbufg=%zu", + Curl_bufq_len(&ctx->inbufq)); } if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) { connclose(cf->conn, "GOAWAY received"); } + CURL_TRC_CF(data, cf, "[0] progress ingress: done"); return CURLE_OK; } @@ -1957,9 +2011,8 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, * (unlikely) or the transfer has been done, cleaned up its resources, but * a read() is called anyway. It is not clear what the calling sequence * is for such a case. */ - failf(data, "[%zd-%zd], http/2 recv on a transfer never opened " - "or already cleared", (ssize_t)data->id, - (ssize_t)cf->conn->connection_id); + failf(data, "http/2 recv on a transfer never opened " + "or already cleared, mid=%" FMT_OFF_T, data->mid); *err = CURLE_HTTP2; return -1; } @@ -2005,11 +2058,11 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, out: result = h2_progress_egress(cf, data); if(result == CURLE_AGAIN) { - /* pending data to send, need to be called again. Ideally, we would - * monitor the socket for POLLOUT, but we might not be in SENDING - * transfer state any longer and are unable to make this happen. - */ - drain_stream(cf, data, stream); + /* pending data to send, need to be called again. Ideally, we + * monitor the socket for POLLOUT, but when not SENDING + * any more, we force processing of the transfer. */ + if(!CURL_WANT_SEND(data)) + drain_stream(cf, data, stream); } else if(result) { *err = result; @@ -2029,10 +2082,57 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, return nread; } +static ssize_t cf_h2_body_send(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h2_stream_ctx *stream, + const void *buf, size_t blen, bool eos, + CURLcode *err) +{ + struct cf_h2_ctx *ctx = cf->ctx; + ssize_t nwritten; + + if(stream->closed) { + if(stream->resp_hds_complete) { + /* Server decided to close the stream after having sent us a final + * response. This is valid if it is not interested in the request + * body. This happens on 30x or 40x responses. + * We silently discard the data sent, since this is not a transport + * error situation. */ + CURL_TRC_CF(data, cf, "[%d] discarding data" + "on closed stream with response", stream->id); + if(eos) + stream->body_eos = TRUE; + *err = CURLE_OK; + return (ssize_t)blen; + } + /* Server closed before we got a response, this is an error */ + infof(data, "stream %u closed", stream->id); + *err = CURLE_SEND_ERROR; + return -1; + } + + nwritten = Curl_bufq_write(&stream->sendbuf, buf, blen, err); + if(nwritten < 0) + return -1; + + if(eos && (blen == (size_t)nwritten)) + stream->body_eos = TRUE; + + if(eos || !Curl_bufq_is_empty(&stream->sendbuf)) { + /* resume the potentially suspended stream */ + int rv = nghttp2_session_resume_data(ctx->h2, stream->id); + if(nghttp2_is_fatal(rv)) { + *err = CURLE_SEND_ERROR; + return -1; + } + } + return nwritten; +} + static ssize_t h2_submit(struct h2_stream_ctx **pstream, struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, - size_t *phdslen, CURLcode *err) + bool eos, CURLcode *err) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = NULL; @@ -2045,7 +2145,6 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, nghttp2_priority_spec pri_spec; ssize_t nwritten; - *phdslen = 0; Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); *err = http2_data_setup(cf, data, &stream); @@ -2057,7 +2156,6 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err); if(nwritten < 0) goto out; - *phdslen = (size_t)nwritten; if(!stream->h1.done) { /* need more data */ goto out; @@ -2088,19 +2186,12 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, case HTTPREQ_POST_FORM: case HTTPREQ_POST_MIME: case HTTPREQ_PUT: - if(data->state.infilesize != -1) - stream->upload_left = data->state.infilesize; - else - /* data sending without specifying the data amount up front */ - stream->upload_left = -1; /* unknown */ - data_prd.read_callback = req_body_read_callback; data_prd.source.ptr = NULL; stream_id = nghttp2_submit_request(ctx->h2, &pri_spec, nva, nheader, &data_prd, data); break; default: - stream->upload_left = 0; /* no request body */ stream_id = nghttp2_submit_request(ctx->h2, &pri_spec, nva, nheader, NULL, data); } @@ -2135,32 +2226,21 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, } stream->id = stream_id; - stream->local_window_size = H2_STREAM_WINDOW_SIZE; - if(data->set.max_recv_speed) { - /* We are asked to only receive `max_recv_speed` bytes per second. - * Let's limit our stream window size around that, otherwise the server - * will send in large bursts only. We make the window 50% larger to - * allow for data in flight and avoid stalling. */ - curl_off_t n = (((data->set.max_recv_speed - 1) / H2_CHUNK_SIZE) + 1); - n += CURLMAX((n/2), 1); - if(n < (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) && - n < (UINT_MAX / H2_CHUNK_SIZE)) { - stream->local_window_size = (uint32_t)n * H2_CHUNK_SIZE; - } - } body = (const char *)buf + nwritten; bodylen = len - nwritten; - if(bodylen) { - /* We have request body to send in DATA frame */ - ssize_t n = Curl_bufq_write(&stream->sendbuf, body, bodylen, err); - if(n < 0) { + if(bodylen || eos) { + ssize_t n = cf_h2_body_send(cf, data, stream, body, bodylen, eos, err); + if(n >= 0) + nwritten += n; + else if(*err == CURLE_AGAIN) + *err = CURLE_OK; + else if(*err != CURLE_AGAIN) { *err = CURLE_SEND_ERROR; nwritten = -1; goto out; } - nwritten += n; } out: @@ -2173,139 +2253,63 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream, } static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); struct cf_call_data save; - int rv; ssize_t nwritten; - size_t hdslen = 0; CURLcode result; - int blocked = 0, was_blocked = 0; CF_DATA_SAVE(save, cf, data); - if(stream && stream->id != -1) { - if(stream->upload_blocked_len) { - /* the data in `buf` has already been submitted or added to the - * buffers, but have been EAGAINed on the last invocation. */ - /* TODO: this assertion triggers in OSSFuzz runs and it is not - * clear why. Disable for now to let OSSFuzz continue its tests. */ - DEBUGASSERT(len >= stream->upload_blocked_len); - if(len < stream->upload_blocked_len) { - /* Did we get called again with a smaller `len`? This should not - * happen. We are not prepared to handle that. */ - failf(data, "HTTP/2 send again with decreased length (%zd vs %zd)", - len, stream->upload_blocked_len); - *err = CURLE_HTTP2; - nwritten = -1; - goto out; - } - nwritten = (ssize_t)stream->upload_blocked_len; - stream->upload_blocked_len = 0; - was_blocked = 1; - } - else if(stream->closed) { - if(stream->resp_hds_complete) { - /* Server decided to close the stream after having sent us a findl - * response. This is valid if it is not interested in the request - * body. This happens on 30x or 40x responses. - * We silently discard the data sent, since this is not a transport - * error situation. */ - CURL_TRC_CF(data, cf, "[%d] discarding data" - "on closed stream with response", stream->id); - *err = CURLE_OK; - nwritten = (ssize_t)len; - goto out; - } - infof(data, "stream %u closed", stream->id); - *err = CURLE_SEND_ERROR; - nwritten = -1; + if(!stream || stream->id == -1) { + nwritten = h2_submit(&stream, cf, data, buf, len, eos, err); + if(nwritten < 0) { goto out; } - else { - /* If stream_id != -1, we have dispatched request HEADERS and - * optionally request body, and now are going to send or sending - * more request body in DATA frame */ - nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err); - if(nwritten < 0 && *err != CURLE_AGAIN) - goto out; - } - - if(!Curl_bufq_is_empty(&stream->sendbuf)) { - /* req body data is buffered, resume the potentially suspended stream */ - rv = nghttp2_session_resume_data(ctx->h2, stream->id); - if(nghttp2_is_fatal(rv)) { - *err = CURLE_SEND_ERROR; - nwritten = -1; - goto out; - } - } + DEBUGASSERT(stream); } - else { - nwritten = h2_submit(&stream, cf, data, buf, len, &hdslen, err); + else if(stream->body_eos) { + /* We already wrote this, but CURLE_AGAINed the call due to not + * being able to flush stream->sendbuf. Make a 0-length write + * to trigger flushing again. + * If this works, we report to have written `len` bytes. */ + DEBUGASSERT(eos); + nwritten = cf_h2_body_send(cf, data, stream, buf, 0, eos, err); + CURL_TRC_CF(data, cf, "[%d] cf_body_send last CHUNK -> %zd, %d, eos=%d", + stream->id, nwritten, *err, eos); if(nwritten < 0) { goto out; } - DEBUGASSERT(stream); - DEBUGASSERT(hdslen <= (size_t)nwritten); + nwritten = len; + } + else { + nwritten = cf_h2_body_send(cf, data, stream, buf, len, eos, err); + CURL_TRC_CF(data, cf, "[%d] cf_body_send(len=%zu) -> %zd, %d, eos=%d", + stream->id, len, nwritten, *err, eos); } /* Call the nghttp2 send loop and flush to write ALL buffered data, * headers and/or request body completely out to the network */ result = h2_progress_egress(cf, data); + /* if the stream has been closed in egress handling (nghttp2 does that * when it does not like the headers, for example */ - if(stream && stream->closed && !was_blocked) { + if(stream && stream->closed) { infof(data, "stream %u closed", stream->id); *err = CURLE_SEND_ERROR; nwritten = -1; goto out; } - else if(result == CURLE_AGAIN) { - blocked = 1; - } - else if(result) { + else if(result && (result != CURLE_AGAIN)) { *err = result; nwritten = -1; goto out; } - else if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) { - /* although we wrote everything that nghttp2 wants to send now, - * there is data left in our stream send buffer unwritten. This may - * be due to the stream's HTTP/2 flow window being exhausted. */ - blocked = 1; - } - - if(stream && blocked && nwritten > 0) { - /* Unable to send all data, due to connection blocked or H2 window - * exhaustion. Data is left in our stream buffer, or nghttp2's internal - * frame buffer or our network out buffer. */ - size_t rwin = (size_t)nghttp2_session_get_stream_remote_window_size( - ctx->h2, stream->id); - /* At the start of a stream, we are called with request headers - * and, possibly, parts of the body. Later, only body data. - * If we cannot send pure body data, we EAGAIN. If there had been - * header, we return that *they* have been written and remember the - * block on the data length only. */ - stream->upload_blocked_len = ((size_t)nwritten) - hdslen; - CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) BLOCK: win %u/%zu " - "hds_len=%zu blocked_len=%zu", - stream->id, len, - nghttp2_session_get_remote_window_size(ctx->h2), rwin, - hdslen, stream->upload_blocked_len); - if(hdslen) { - *err = CURLE_OK; - nwritten = hdslen; - } - else { - *err = CURLE_AGAIN; - nwritten = -1; - goto out; - } - } - else if(should_close_session(ctx)) { + + if(should_close_session(ctx)) { /* nghttp2 thinks this session is done. If the stream has not been * closed, this is an error state for out transfer */ if(stream->closed) { @@ -2321,11 +2325,10 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, out: if(stream) { CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %zd, %d, " - "upload_left=%" CURL_FORMAT_CURL_OFF_T ", " - "h2 windows %d-%d (stream-conn), " + "eos=%d, h2 windows %d-%d (stream-conn), " "buffers %zu-%zu (stream-conn)", stream->id, len, nwritten, *err, - stream->upload_left, + stream->body_eos, nghttp2_session_get_stream_remote_window_size( ctx->h2, stream->id), nghttp2_session_get_remote_window_size(ctx->h2), @@ -2343,6 +2346,48 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, return nwritten; } +static CURLcode cf_h2_flush(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct cf_h2_ctx *ctx = cf->ctx; + struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); + struct cf_call_data save; + CURLcode result = CURLE_OK; + + CF_DATA_SAVE(save, cf, data); + if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) { + /* resume the potentially suspended stream */ + int rv = nghttp2_session_resume_data(ctx->h2, stream->id); + if(nghttp2_is_fatal(rv)) { + result = CURLE_SEND_ERROR; + goto out; + } + } + + result = h2_progress_egress(cf, data); + +out: + if(stream) { + CURL_TRC_CF(data, cf, "[%d] flush -> %d, " + "h2 windows %d-%d (stream-conn), " + "buffers %zu-%zu (stream-conn)", + stream->id, result, + nghttp2_session_get_stream_remote_window_size( + ctx->h2, stream->id), + nghttp2_session_get_remote_window_size(ctx->h2), + Curl_bufq_len(&stream->sendbuf), + Curl_bufq_len(&ctx->outbufq)); + } + else { + CURL_TRC_CF(data, cf, "flush -> %d, " + "connection-window=%d, nw_send_buffer(%zu)", + result, nghttp2_session_get_remote_window_size(ctx->h2), + Curl_bufq_len(&ctx->outbufq)); + } + CF_DATA_RESTORE(cf, save); + return result; +} + static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, struct easy_pollset *ps) @@ -2368,7 +2413,8 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, stream->id); want_recv = (want_recv || c_exhaust || s_exhaust); want_send = (!s_exhaust && want_send) || - (!c_exhaust && nghttp2_session_want_write(ctx->h2)); + (!c_exhaust && nghttp2_session_want_write(ctx->h2)) || + !Curl_bufq_is_empty(&ctx->outbufq); Curl_pollset_set(data, ps, sock, want_recv, want_send); CF_DATA_RESTORE(cf, save); @@ -2376,7 +2422,8 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, else if(ctx->sent_goaway && !cf->shutdown) { /* shutdown in progress */ CF_DATA_SAVE(save, cf, data); - want_send = nghttp2_session_want_write(ctx->h2); + want_send = nghttp2_session_want_write(ctx->h2) || + !Curl_bufq_is_empty(&ctx->outbufq); want_recv = nghttp2_session_want_read(ctx->h2); Curl_pollset_set(data, ps, sock, want_recv, want_send); CF_DATA_RESTORE(cf, save); @@ -2406,8 +2453,9 @@ static CURLcode cf_h2_connect(struct Curl_cfilter *cf, *done = FALSE; CF_DATA_SAVE(save, cf, data); + DEBUGASSERT(ctx->initialized); if(!ctx->h2) { - result = cf_h2_ctx_init(cf, data, FALSE); + result = cf_h2_ctx_open(cf, data); if(result) goto out; } @@ -2442,7 +2490,7 @@ static void cf_h2_close(struct Curl_cfilter *cf, struct Curl_easy *data) struct cf_call_data save; CF_DATA_SAVE(save, cf, data); - cf_h2_ctx_clear(ctx); + cf_h2_ctx_close(ctx); CF_DATA_RESTORE(cf, save); cf->connected = FALSE; } @@ -2479,7 +2527,8 @@ static CURLcode cf_h2_shutdown(struct Curl_cfilter *cf, if(!ctx->sent_goaway) { rv = nghttp2_submit_goaway(ctx->h2, NGHTTP2_FLAG_NONE, ctx->local_max_sid, 0, - (const uint8_t *)"shutown", sizeof("shutown")); + (const uint8_t *)"shutdown", + sizeof("shutdown")); if(rv) { failf(data, "nghttp2_submit_goaway() failed: %s(%d)", nghttp2_strerror(rv), rv); @@ -2490,14 +2539,19 @@ static CURLcode cf_h2_shutdown(struct Curl_cfilter *cf, } /* GOAWAY submitted, process egress and ingress until nghttp2 is done. */ result = CURLE_OK; - if(nghttp2_session_want_write(ctx->h2)) + if(nghttp2_session_want_write(ctx->h2) || + !Curl_bufq_is_empty(&ctx->outbufq)) result = h2_progress_egress(cf, data); if(!result && nghttp2_session_want_read(ctx->h2)) result = h2_progress_ingress(cf, data, 0); + if(result == CURLE_AGAIN) + result = CURLE_OK; + *done = (ctx->conn_closed || (!result && !nghttp2_session_want_write(ctx->h2) && - !nghttp2_session_want_read(ctx->h2))); + !nghttp2_session_want_read(ctx->h2) && + Curl_bufq_is_empty(&ctx->outbufq))); out: CF_DATA_RESTORE(cf, save); @@ -2509,26 +2563,14 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf, struct Curl_easy *data, bool pause) { -#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE struct cf_h2_ctx *ctx = cf->ctx; struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); DEBUGASSERT(data); if(ctx && ctx->h2 && stream) { - uint32_t window = pause? 0 : stream->local_window_size; - - int rv = (int)nghttp2_session_set_local_window_size(ctx->h2, - NGHTTP2_FLAG_NONE, - stream->id, - (int32_t)window); - if(rv) { - failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)", - nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - - if(!pause) - drain_stream(cf, data, stream); + CURLcode result = cf_h2_update_local_win(cf, data, stream, pause); + if(result) + return result; /* attempt to send the window update */ (void)h2_progress_egress(cf, data); @@ -2542,21 +2584,9 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf, drain_stream(cf, data, stream); Curl_expire(data, 0, EXPIRE_RUN_NOW); } - DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u", - window, stream->id)); - -#ifdef DEBUGBUILD - { - /* read out the stream local window again */ - uint32_t window2 = (uint32_t) - nghttp2_session_get_stream_local_window_size(ctx->h2, - stream->id); - DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u", - window2, stream->id)); - } -#endif + CURL_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id, + pause? "" : "un"); } -#endif return CURLE_OK; } @@ -2576,8 +2606,8 @@ static CURLcode cf_h2_cntrl(struct Curl_cfilter *cf, case CF_CTRL_DATA_PAUSE: result = http2_data_pause(cf, data, (arg1 != 0)); break; - case CF_CTRL_DATA_DONE_SEND: - result = http2_data_done_send(cf, data); + case CF_CTRL_FLUSH: + result = cf_h2_flush(cf, data); break; case CF_CTRL_DATA_DETACH: http2_data_done(cf, data); @@ -2660,6 +2690,15 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf, *pres1 = stream? (int)stream->error : 0; return CURLE_OK; } + case CF_QUERY_NEED_FLUSH: { + struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); + if(!Curl_bufq_is_empty(&ctx->outbufq) || + (stream && !Curl_bufq_is_empty(&stream->sendbuf))) { + *pres1 = TRUE; + return CURLE_OK; + } + break; + } default: break; } @@ -2701,6 +2740,7 @@ static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf, ctx = calloc(1, sizeof(*ctx)); if(!ctx) goto out; + cf_h2_ctx_init(ctx, via_h1_upgrade); result = Curl_cf_create(&cf, &Curl_cft_nghttp2, ctx); if(result) @@ -2708,7 +2748,6 @@ static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf, ctx = NULL; Curl_conn_cf_add(data, conn, sockindex, cf); - result = cf_h2_ctx_init(cf, data, via_h1_upgrade); out: if(result) @@ -2729,6 +2768,7 @@ static CURLcode http2_cfilter_insert_after(struct Curl_cfilter *cf, ctx = calloc(1, sizeof(*ctx)); if(!ctx) goto out; + cf_h2_ctx_init(ctx, via_h1_upgrade); result = Curl_cf_create(&cf_h2, &Curl_cft_nghttp2, ctx); if(result) @@ -2736,7 +2776,6 @@ static CURLcode http2_cfilter_insert_after(struct Curl_cfilter *cf, ctx = NULL; Curl_conn_cf_insert_after(cf, cf_h2); - result = cf_h2_ctx_init(cf_h2, data, via_h1_upgrade); out: if(result) @@ -2791,15 +2830,14 @@ CURLcode Curl_http2_switch(struct Curl_easy *data, CURLcode result; DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex)); - DEBUGF(infof(data, "switching to HTTP/2")); result = http2_cfilter_add(&cf, data, conn, sockindex, FALSE); if(result) return result; + CURL_TRC_CF(data, cf, "switching connection to HTTP/2"); conn->httpversion = 20; /* we know we are on HTTP/2 now */ conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - conn->bundle->multiuse = BUNDLE_MULTIPLEX; Curl_multi_connchanged(data->multi); if(cf->next) { @@ -2823,7 +2861,6 @@ CURLcode Curl_http2_switch_at(struct Curl_cfilter *cf, struct Curl_easy *data) cf_h2 = cf->next; cf->conn->httpversion = 20; /* we know we are on HTTP/2 now */ cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; Curl_multi_connchanged(data->multi); if(cf_h2->next) { @@ -2842,12 +2879,12 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data, CURLcode result; DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex)); - DEBUGF(infof(data, "upgrading to HTTP/2")); DEBUGASSERT(data->req.upgr101 == UPGR101_RECEIVED); result = http2_cfilter_add(&cf, data, conn, sockindex, TRUE); if(result) return result; + CURL_TRC_CF(data, cf, "upgrading connection to HTTP/2"); DEBUGASSERT(cf->cft == &Curl_cft_nghttp2); ctx = cf->ctx; @@ -2876,7 +2913,6 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data, conn->httpversion = 20; /* we know we are on HTTP/2 now */ conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - conn->bundle->multiuse = BUNDLE_MULTIPLEX; Curl_multi_connchanged(data->multi); if(cf->next) { diff --git a/lib/http_aws_sigv4.c b/lib/http_aws_sigv4.c index 9e4f72016..3874993e9 100644 --- a/lib/http_aws_sigv4.c +++ b/lib/http_aws_sigv4.c @@ -60,11 +60,11 @@ #define TIMESTAMP_SIZE 17 /* hex-encoded with trailing null */ -#define SHA256_HEX_LENGTH (2 * SHA256_DIGEST_LENGTH + 1) +#define SHA256_HEX_LENGTH (2 * CURL_SHA256_DIGEST_LENGTH + 1) static void sha256_to_hex(char *dst, unsigned char *sha) { - Curl_hexencode(sha, SHA256_DIGEST_LENGTH, + Curl_hexencode(sha, CURL_SHA256_DIGEST_LENGTH, (unsigned char *)dst, SHA256_HEX_LENGTH); } @@ -129,6 +129,37 @@ static void trim_headers(struct curl_slist *head) /* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */ #define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1) +/* alphabetically compare two headers by their name, expecting + headers to use ':' at this point */ +static int compare_header_names(const char *a, const char *b) +{ + const char *colon_a; + const char *colon_b; + size_t len_a; + size_t len_b; + size_t min_len; + int cmp; + + colon_a = strchr(a, ':'); + colon_b = strchr(b, ':'); + + DEBUGASSERT(colon_a); + DEBUGASSERT(colon_b); + + len_a = colon_a ? (size_t)(colon_a - a) : strlen(a); + len_b = colon_b ? (size_t)(colon_b - b) : strlen(b); + + min_len = (len_a < len_b) ? len_a : len_b; + + cmp = strncmp(a, b, min_len); + + /* return the shorter of the two if one is shorter */ + if(!cmp) + return (int)(len_a - len_b); + + return cmp; +} + /* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */ static CURLcode make_headers(struct Curl_easy *data, const char *hostname, @@ -240,7 +271,7 @@ static CURLcode make_headers(struct Curl_easy *data, if(!tmp_head) goto fail; head = tmp_head; - *date_header = curl_maprintf("%s: %s\r\n", date_hdr_key, timestamp); + *date_header = aprintf("%s: %s\r\n", date_hdr_key, timestamp); } else { char *value; @@ -267,13 +298,13 @@ static CURLcode make_headers(struct Curl_easy *data, *date_header = NULL; } - /* alpha-sort in a case sensitive manner */ + /* alpha-sort by header name in a case sensitive manner */ do { again = 0; for(l = head; l; l = l->next) { struct curl_slist *next = l->next; - if(next && strcmp(l->data, next->data) > 0) { + if(next && compare_header_names(l->data, next->data) > 0) { char *tmp = l->data; l->data = next->data; @@ -573,7 +604,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) const char *method = NULL; char *payload_hash = NULL; size_t payload_hash_len = 0; - unsigned char sha_hash[SHA256_DIGEST_LENGTH]; + unsigned char sha_hash[CURL_SHA256_DIGEST_LENGTH]; char sha_hex[SHA256_HEX_LENGTH]; char content_sha256_hdr[CONTENT_SHA256_HDR_LEN + 2] = ""; /* add \r\n */ char *canonical_request = NULL; @@ -582,8 +613,8 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) char *str_to_sign = NULL; const char *user = data->state.aptr.user ? data->state.aptr.user : ""; char *secret = NULL; - unsigned char sign0[SHA256_DIGEST_LENGTH] = {0}; - unsigned char sign1[SHA256_DIGEST_LENGTH] = {0}; + unsigned char sign0[CURL_SHA256_DIGEST_LENGTH] = {0}; + unsigned char sign1[CURL_SHA256_DIGEST_LENGTH] = {0}; char *auth_headers = NULL; DEBUGASSERT(!proxy); @@ -735,19 +766,19 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) result = CURLE_OUT_OF_MEMORY; canonical_request = - curl_maprintf("%s\n" /* HTTPRequestMethod */ - "%s\n" /* CanonicalURI */ - "%s\n" /* CanonicalQueryString */ - "%s\n" /* CanonicalHeaders */ - "%s\n" /* SignedHeaders */ - "%.*s", /* HashedRequestPayload in hex */ - method, - Curl_dyn_ptr(&canonical_path), - Curl_dyn_ptr(&canonical_query) ? - Curl_dyn_ptr(&canonical_query) : "", - Curl_dyn_ptr(&canonical_headers), - Curl_dyn_ptr(&signed_headers), - (int)payload_hash_len, payload_hash); + aprintf("%s\n" /* HTTPRequestMethod */ + "%s\n" /* CanonicalURI */ + "%s\n" /* CanonicalQueryString */ + "%s\n" /* CanonicalHeaders */ + "%s\n" /* SignedHeaders */ + "%.*s", /* HashedRequestPayload in hex */ + method, + Curl_dyn_ptr(&canonical_path), + Curl_dyn_ptr(&canonical_query) ? + Curl_dyn_ptr(&canonical_query) : "", + Curl_dyn_ptr(&canonical_headers), + Curl_dyn_ptr(&signed_headers), + (int)payload_hash_len, payload_hash); if(!canonical_request) goto fail; @@ -755,12 +786,12 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) /* provider 0 lowercase */ Curl_strntolower(provider0, provider0, strlen(provider0)); - request_type = curl_maprintf("%s4_request", provider0); + request_type = aprintf("%s4_request", provider0); if(!request_type) goto fail; - credential_scope = curl_maprintf("%s/%s/%s/%s", - date, region, service, request_type); + credential_scope = aprintf("%s/%s/%s/%s", + date, region, service, request_type); if(!credential_scope) goto fail; @@ -777,22 +808,22 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) * Google allows using RSA key instead of HMAC, so this code might change * in the future. For now we only support HMAC. */ - str_to_sign = curl_maprintf("%s4-HMAC-SHA256\n" /* Algorithm */ - "%s\n" /* RequestDateTime */ - "%s\n" /* CredentialScope */ - "%s", /* HashedCanonicalRequest in hex */ - provider0, - timestamp, - credential_scope, - sha_hex); + str_to_sign = aprintf("%s4-HMAC-SHA256\n" /* Algorithm */ + "%s\n" /* RequestDateTime */ + "%s\n" /* CredentialScope */ + "%s", /* HashedCanonicalRequest in hex */ + provider0, + timestamp, + credential_scope, + sha_hex); if(!str_to_sign) { goto fail; } /* provider 0 uppercase */ - secret = curl_maprintf("%s4%s", provider0, - data->state.aptr.passwd ? - data->state.aptr.passwd : ""); + secret = aprintf("%s4%s", provider0, + data->state.aptr.passwd ? + data->state.aptr.passwd : ""); if(!secret) goto fail; @@ -805,24 +836,24 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) sha256_to_hex(sha_hex, sign0); /* provider 0 uppercase */ - auth_headers = curl_maprintf("Authorization: %s4-HMAC-SHA256 " - "Credential=%s/%s, " - "SignedHeaders=%s, " - "Signature=%s\r\n" - /* - * date_header is added here, only if it was not - * user-specified (using CURLOPT_HTTPHEADER). - * date_header includes \r\n - */ - "%s" - "%s", /* optional sha256 header includes \r\n */ - provider0, - user, - credential_scope, - Curl_dyn_ptr(&signed_headers), - sha_hex, - date_header ? date_header : "", - content_sha256_hdr); + auth_headers = aprintf("Authorization: %s4-HMAC-SHA256 " + "Credential=%s/%s, " + "SignedHeaders=%s, " + "Signature=%s\r\n" + /* + * date_header is added here, only if it was not + * user-specified (using CURLOPT_HTTPHEADER). + * date_header includes \r\n + */ + "%s" + "%s", /* optional sha256 header includes \r\n */ + provider0, + user, + credential_scope, + Curl_dyn_ptr(&signed_headers), + sha_hex, + date_header ? date_header : "", + content_sha256_hdr); if(!auth_headers) { goto fail; } diff --git a/lib/http_chunks.c b/lib/http_chunks.c index 001185da9..c228eb4f9 100644 --- a/lib/http_chunks.c +++ b/lib/http_chunks.c @@ -189,7 +189,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, else { ch->state = CHUNK_DATA; CURL_TRC_WRITE(data, "http_chunked, chunk start of %" - CURL_FORMAT_CURL_OFF_T " bytes", ch->datasize); + FMT_OFF_T " bytes", ch->datasize); } } @@ -226,7 +226,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, buf += piece; /* move read pointer forward */ blen -= piece; /* decrease space left in this round */ CURL_TRC_WRITE(data, "http_chunked, write %zu body bytes, %" - CURL_FORMAT_CURL_OFF_T " bytes in chunk remain", + FMT_OFF_T " bytes in chunk remain", piece, ch->datasize); if(0 == ch->datasize) diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index 629de834f..26e475c27 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -30,6 +30,7 @@ #include "sendf.h" #include "http_negotiate.h" #include "vauth/vauth.h" +#include "vtls/vtls.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -106,11 +107,27 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, #if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) neg_ctx->sslContext = conn->sslContext; #endif + /* Check if the connection is using SSL and get the channel binding data */ +#ifdef HAVE_GSSAPI + if(conn->handler->flags & PROTOPT_SSL) { + Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE); + result = Curl_ssl_get_channel_binding( + data, FIRSTSOCKET, &neg_ctx->channel_binding_data); + if(result) { + Curl_http_auth_cleanup_negotiate(conn); + return result; + } + } +#endif /* Initialize the security context and decode our challenge */ result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, host, header, neg_ctx); +#ifdef HAVE_GSSAPI + Curl_dyn_free(&neg_ctx->channel_binding_data); +#endif + if(result) Curl_http_auth_cleanup_negotiate(conn); diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 95c138d4f..49230bc1b 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -123,7 +123,7 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, } /* - * This is for creating ntlm header output + * This is for creating NTLM header output */ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) { @@ -187,10 +187,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) passwdp = ""; #ifdef USE_WINDOWS_SSPI - if(!s_hSecDll) { + if(!Curl_hSecDll) { /* not thread safe and leaks - use curl_global_init() to avoid */ CURLcode err = Curl_sspi_global_init(); - if(!s_hSecDll) + if(!Curl_hSecDll) return err; } #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h index f37572bae..c1cf05701 100644 --- a/lib/http_ntlm.h +++ b/lib/http_ntlm.h @@ -28,11 +28,11 @@ #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) -/* this is for ntlm header input */ +/* this is for NTLM header input */ CURLcode Curl_input_ntlm(struct Curl_easy *data, bool proxy, const char *header); -/* this is for creating ntlm header output */ +/* this is for creating NTLM header output */ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy); void Curl_http_auth_cleanup_ntlm(struct connectdata *conn); diff --git a/lib/idn.c b/lib/idn.c index ef55ddfec..ed20cdc16 100644 --- a/lib/idn.c +++ b/lib/idn.c @@ -53,30 +53,70 @@ /* for macOS and iOS targets */ #if defined(USE_APPLE_IDN) #include +#include +#include #define MAX_HOST_LENGTH 512 +static CURLcode iconv_to_utf8(const char *in, size_t inlen, + char **out, size_t *outlen) +{ + iconv_t cd = iconv_open("UTF-8", nl_langinfo(CODESET)); + if(cd != (iconv_t)-1) { + size_t iconv_outlen = *outlen; + char *iconv_in = (char *)in; + size_t iconv_inlen = inlen; + size_t iconv_result = iconv(cd, &iconv_in, &iconv_inlen, + out, &iconv_outlen); + *outlen -= iconv_outlen; + iconv_close(cd); + if(iconv_result == (size_t)-1) { + if(errno == ENOMEM) + return CURLE_OUT_OF_MEMORY; + else + return CURLE_URL_MALFORMAT; + } + + return CURLE_OK; + } + else { + if(errno == ENOMEM) + return CURLE_OUT_OF_MEMORY; + else + return CURLE_FAILED_INIT; + } +} + static CURLcode mac_idn_to_ascii(const char *in, char **out) { size_t inlen = strlen(in); if(inlen < MAX_HOST_LENGTH) { - UErrorCode err = U_ZERO_ERROR; - UIDNA* idna = uidna_openUTS46( - UIDNA_CHECK_BIDI|UIDNA_NONTRANSITIONAL_TO_ASCII, &err); - if(!U_FAILURE(err)) { - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - char buffer[MAX_HOST_LENGTH] = {0}; - (void)uidna_nameToASCII_UTF8(idna, in, -1, buffer, - sizeof(buffer) - 1, &info, &err); - uidna_close(idna); + char iconv_buffer[MAX_HOST_LENGTH] = {0}; + char *iconv_outptr = iconv_buffer; + size_t iconv_outlen = sizeof(iconv_buffer); + CURLcode iconv_result = iconv_to_utf8(in, inlen, + &iconv_outptr, &iconv_outlen); + if(!iconv_result) { + UErrorCode err = U_ZERO_ERROR; + UIDNA* idna = uidna_openUTS46( + UIDNA_CHECK_BIDI|UIDNA_NONTRANSITIONAL_TO_ASCII, &err); if(!U_FAILURE(err)) { - *out = strdup(buffer); - if(*out) - return CURLE_OK; - else - return CURLE_OUT_OF_MEMORY; + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + char buffer[MAX_HOST_LENGTH] = {0}; + (void)uidna_nameToASCII_UTF8(idna, iconv_buffer, (int)iconv_outlen, + buffer, sizeof(buffer) - 1, &info, &err); + uidna_close(idna); + if(!U_FAILURE(err) && !info.errors) { + *out = strdup(buffer); + if(*out) + return CURLE_OK; + else + return CURLE_OUT_OF_MEMORY; + } } } + else + return iconv_result; } return CURLE_URL_MALFORMAT; } @@ -110,7 +150,8 @@ static CURLcode mac_ascii_to_idn(const char *in, char **out) #ifdef USE_WIN32_IDN /* using Windows kernel32 and normaliz libraries. */ -#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600 +#if (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600) && \ + (!defined(WINVER) || WINVER < 0x600) WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, const WCHAR *lpUnicodeCharStr, int cchUnicodeChar, diff --git a/lib/if2ip.c b/lib/if2ip.c index 42e14500b..55afd553d 100644 --- a/lib/if2ip.c +++ b/lib/if2ip.c @@ -216,7 +216,15 @@ if2ip_result_t Curl_if2ip(int af, memcpy(req.ifr_name, interf, len + 1); req.ifr_addr.sa_family = AF_INET; +#if defined(__GNUC__) && defined(_AIX) +/* Suppress warning inside system headers */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshift-sign-overflow" +#endif if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { +#if defined(__GNUC__) && defined(_AIX) +#pragma GCC diagnostic pop +#endif sclose(dummy); /* With SIOCGIFADDR, we cannot tell the difference between an interface that does not exist and an interface that has no address of the diff --git a/lib/imap.c b/lib/imap.c index efe91b14b..4979a18ed 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -814,8 +814,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; /* Send the APPEND command */ - result = imap_sendf(data, - "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}", + result = imap_sendf(data, "APPEND %s (\\Seen) {%" FMT_OFF_T "}", mailbox, data->state.infilesize); free(mailbox); @@ -1168,8 +1167,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, } if(parsed) { - infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download", - size); + infof(data, "Found %" FMT_OFF_T " bytes to download", size); Curl_pgrsSetDownloadSize(data, size); if(pp->overflow) { @@ -1196,7 +1194,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, if(result) return result; - infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU + infof(data, "Written %zu bytes, %" FMT_OFF_TU " bytes are left for transfer", chunk, size - chunk); /* Have we used the entire overflow or just part of it?*/ diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c index 3a81eef6e..a2812cf8e 100644 --- a/lib/inet_ntop.c +++ b/lib/inet_ntop.c @@ -185,8 +185,8 @@ static char *inet_ntop6(const unsigned char *src, char *dst, size_t size) * Returns NULL on error and errno set with the specific * error, EAFNOSUPPORT or ENOSPC. * - * On Windows we store the error in the thread errno, not in the winsock error - * code. This is to avoid losing the actual last winsock error. When this + * On Windows we store the error in the thread errno, not in the Winsock error + * code. This is to avoid losing the actual last Winsock error. When this * function returns NULL, check errno not SOCKERRNO. */ char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) diff --git a/lib/inet_pton.c b/lib/inet_pton.c index 49b923f18..97e6f80d7 100644 --- a/lib/inet_pton.c +++ b/lib/inet_pton.c @@ -65,8 +65,8 @@ static int inet_pton6(const char *src, unsigned char *dst); * -1 if some other error occurred (`dst' is untouched in this case, too) * notice: * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid losing the - * actual last winsock error. When this function returns + * in the Winsock error code. This is to avoid losing the + * actual last Winsock error. When this function returns * -1, check errno not SOCKERRNO. * author: * Paul Vixie, 1996. diff --git a/lib/krb5.c b/lib/krb5.c index 45944cefc..f3649cd1a 100644 --- a/lib/krb5.c +++ b/lib/krb5.c @@ -91,7 +91,7 @@ static CURLcode ftpsend(struct Curl_easy *data, struct connectdata *conn, #ifdef HAVE_GSSAPI conn->data_prot = PROT_CMD; #endif - result = Curl_xfer_send(data, sptr, write_len, &bytes_written); + result = Curl_xfer_send(data, sptr, write_len, FALSE, &bytes_written); #ifdef HAVE_GSSAPI DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); conn->data_prot = data_sec; @@ -336,17 +336,20 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) } _gssresp.value = NULL; /* make sure it is initialized */ + _gssresp.length = 0; p += 4; /* over '789 ' */ p = strstr(p, "ADAT="); if(p) { - result = Curl_base64_decode(p + 5, - (unsigned char **)&_gssresp.value, - &_gssresp.length); + unsigned char *outptr; + size_t outlen; + result = Curl_base64_decode(p + 5, &outptr, &outlen); if(result) { failf(data, "base64-decoding: %s", curl_easy_strerror(result)); ret = AUTH_CONTINUE; break; } + _gssresp.value = outptr; + _gssresp.length = outlen; } gssresp = &_gssresp; @@ -497,7 +500,7 @@ socket_write(struct Curl_easy *data, int sockindex, const void *to, size_t written; while(len > 0) { - result = Curl_conn_send(data, sockindex, to_p, len, &written); + result = Curl_conn_send(data, sockindex, to_p, len, FALSE, &written); if(!result && written > 0) { len -= written; to_p += written; @@ -686,10 +689,12 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn, /* Matches Curl_send signature */ static ssize_t sec_send(struct Curl_easy *data, int sockindex, - const void *buffer, size_t len, CURLcode *err) + const void *buffer, size_t len, bool eos, + CURLcode *err) { struct connectdata *conn = data->conn; curl_socket_t fd = conn->sock[sockindex]; + (void)eos; /* unused */ *err = CURLE_OK; return sec_write(data, conn, fd, buffer, len); } diff --git a/lib/ldap.c b/lib/ldap.c index addb9b353..01429ba79 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -143,7 +143,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp); #endif #if defined(USE_WIN32_LDAP) && defined(ldap_err2string) -/* Use ansi error strings in UNICODE builds */ +/* Use ANSI error strings in Unicode builds */ #undef ldap_err2string #define ldap_err2string ldap_err2stringA #endif diff --git a/libcurl.def b/lib/libcurl.def similarity index 100% rename from libcurl.def rename to lib/libcurl.def diff --git a/lib/llist.c b/lib/llist.c index 716f0cd57..7e19cd509 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -32,16 +32,34 @@ /* this must be the last include file */ #include "memdebug.h" +#define LLISTINIT 0x100cc001 /* random pattern */ +#define NODEINIT 0x12344321 /* random pattern */ +#define NODEREM 0x54321012 /* random pattern */ + + +#ifdef DEBUGBUILD +#define VERIFYNODE(x) verifynode(x) +static struct Curl_llist_node *verifynode(struct Curl_llist_node *n) +{ + DEBUGASSERT(!n || (n->_init == NODEINIT)); + return n; +} +#else +#define VERIFYNODE(x) x +#endif /* * @unittest: 1300 */ void Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor) { - l->size = 0; - l->dtor = dtor; - l->head = NULL; - l->tail = NULL; + l->_size = 0; + l->_dtor = dtor; + l->_head = NULL; + l->_tail = NULL; +#ifdef DEBUGBUILD + l->_init = LLISTINIT; +#endif } /* @@ -56,36 +74,45 @@ Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor) * @unittest: 1300 */ void -Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_element *e, +Curl_llist_insert_next(struct Curl_llist *list, + struct Curl_llist_node *e, /* may be NULL */ const void *p, - struct Curl_llist_element *ne) + struct Curl_llist_node *ne) { - ne->ptr = (void *) p; - if(list->size == 0) { - list->head = ne; - list->head->prev = NULL; - list->head->next = NULL; - list->tail = ne; + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + DEBUGASSERT(ne); + +#ifdef DEBUGBUILD + ne->_init = NODEINIT; +#endif + ne->_ptr = (void *) p; + ne->_list = list; + if(list->_size == 0) { + list->_head = ne; + list->_head->_prev = NULL; + list->_head->_next = NULL; + list->_tail = ne; } else { /* if 'e' is NULL here, we insert the new element first in the list */ - ne->next = e?e->next:list->head; - ne->prev = e; + ne->_next = e?e->_next:list->_head; + ne->_prev = e; if(!e) { - list->head->prev = ne; - list->head = ne; + list->_head->_prev = ne; + list->_head = ne; } - else if(e->next) { - e->next->prev = ne; + else if(e->_next) { + e->_next->_prev = ne; } else { - list->tail = ne; + list->_tail = ne; } if(e) - e->next = ne; + e->_next = ne; } - ++list->size; + ++list->_size; } /* @@ -99,64 +126,141 @@ Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_element *e, */ void Curl_llist_append(struct Curl_llist *list, const void *p, - struct Curl_llist_element *ne) + struct Curl_llist_node *ne) { - Curl_llist_insert_next(list, list->tail, p, ne); + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + DEBUGASSERT(ne); + Curl_llist_insert_next(list, list->_tail, p, ne); } /* * @unittest: 1300 */ void -Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e, - void *user) +Curl_node_uremove(struct Curl_llist_node *e, void *user) { void *ptr; - if(!e || list->size == 0) + struct Curl_llist *list; + if(!e) return; - if(e == list->head) { - list->head = e->next; + list = e->_list; + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + DEBUGASSERT(list->_size); + DEBUGASSERT(e->_init == NODEINIT); + if(e == list->_head) { + list->_head = e->_next; - if(!list->head) - list->tail = NULL; + if(!list->_head) + list->_tail = NULL; else - e->next->prev = NULL; + e->_next->_prev = NULL; } else { - if(e->prev) - e->prev->next = e->next; + if(e->_prev) + e->_prev->_next = e->_next; - if(!e->next) - list->tail = e->prev; + if(!e->_next) + list->_tail = e->_prev; else - e->next->prev = e->prev; + e->_next->_prev = e->_prev; } - ptr = e->ptr; + ptr = e->_ptr; - e->ptr = NULL; - e->prev = NULL; - e->next = NULL; + e->_list = NULL; + e->_ptr = NULL; + e->_prev = NULL; + e->_next = NULL; +#ifdef DEBUGBUILD + e->_init = NODEREM; /* specific pattern on remove - not zero */ +#endif - --list->size; + --list->_size; /* call the dtor() last for when it actually frees the 'e' memory itself */ - if(list->dtor) - list->dtor(user, ptr); + if(list->_dtor) + list->_dtor(user, ptr); +} + +void Curl_node_remove(struct Curl_llist_node *e) +{ + Curl_node_uremove(e, NULL); } void Curl_llist_destroy(struct Curl_llist *list, void *user) { if(list) { - while(list->size > 0) - Curl_llist_remove(list, list->tail, user); + DEBUGASSERT(list->_init == LLISTINIT); + while(list->_size > 0) + Curl_node_uremove(list->_tail, user); } } -size_t -Curl_llist_count(struct Curl_llist *list) +/* Curl_llist_head() returns the first 'struct Curl_llist_node *', which + might be NULL */ +struct Curl_llist_node *Curl_llist_head(struct Curl_llist *list) +{ + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + return VERIFYNODE(list->_head); +} + +#ifdef UNITTESTS +/* Curl_llist_tail() returns the last 'struct Curl_llist_node *', which + might be NULL */ +struct Curl_llist_node *Curl_llist_tail(struct Curl_llist *list) +{ + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + return VERIFYNODE(list->_tail); +} +#endif + +/* Curl_llist_count() returns a size_t the number of nodes in the list */ +size_t Curl_llist_count(struct Curl_llist *list) +{ + DEBUGASSERT(list); + DEBUGASSERT(list->_init == LLISTINIT); + return list->_size; +} + +/* Curl_node_elem() returns the custom data from a Curl_llist_node */ +void *Curl_node_elem(struct Curl_llist_node *n) +{ + DEBUGASSERT(n); + DEBUGASSERT(n->_init == NODEINIT); + return n->_ptr; +} + +/* Curl_node_next() returns the next element in a list from a given + Curl_llist_node */ +struct Curl_llist_node *Curl_node_next(struct Curl_llist_node *n) +{ + DEBUGASSERT(n); + DEBUGASSERT(n->_init == NODEINIT); + return VERIFYNODE(n->_next); +} + +#ifdef UNITTESTS + +/* Curl_node_prev() returns the previous element in a list from a given + Curl_llist_node */ +struct Curl_llist_node *Curl_node_prev(struct Curl_llist_node *n) +{ + DEBUGASSERT(n); + DEBUGASSERT(n->_init == NODEINIT); + return VERIFYNODE(n->_prev); +} + +#endif + +struct Curl_llist *Curl_node_llist(struct Curl_llist_node *n) { - return list->size; + DEBUGASSERT(n); + DEBUGASSERT(!n->_list || n->_init == NODEINIT); + return n->_list; } diff --git a/lib/llist.h b/lib/llist.h index d75582fa9..26581869a 100644 --- a/lib/llist.h +++ b/lib/llist.h @@ -27,28 +27,63 @@ #include "curl_setup.h" #include -typedef void (*Curl_llist_dtor)(void *, void *); +typedef void (*Curl_llist_dtor)(void *user, void *elem); -struct Curl_llist_element { - void *ptr; - struct Curl_llist_element *prev; - struct Curl_llist_element *next; -}; +/* none of these struct members should be referenced directly, use the + dedicated functions */ struct Curl_llist { - struct Curl_llist_element *head; - struct Curl_llist_element *tail; - Curl_llist_dtor dtor; - size_t size; + struct Curl_llist_node *_head; + struct Curl_llist_node *_tail; + Curl_llist_dtor _dtor; + size_t _size; +#ifdef DEBUGBUILD + int _init; /* detect API usage mistakes */ +#endif +}; + +struct Curl_llist_node { + struct Curl_llist *_list; /* the list where this belongs */ + void *_ptr; + struct Curl_llist_node *_prev; + struct Curl_llist_node *_next; +#ifdef DEBUGBUILD + int _init; /* detect API usage mistakes */ +#endif }; void Curl_llist_init(struct Curl_llist *, Curl_llist_dtor); -void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_element *, - const void *, struct Curl_llist_element *node); +void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_node *, + const void *, struct Curl_llist_node *node); void Curl_llist_append(struct Curl_llist *, - const void *, struct Curl_llist_element *node); -void Curl_llist_remove(struct Curl_llist *, struct Curl_llist_element *, - void *); -size_t Curl_llist_count(struct Curl_llist *); + const void *, struct Curl_llist_node *node); +void Curl_node_uremove(struct Curl_llist_node *, void *); +void Curl_node_remove(struct Curl_llist_node *); void Curl_llist_destroy(struct Curl_llist *, void *); + +/* Curl_llist_head() returns the first 'struct Curl_llist_node *', which + might be NULL */ +struct Curl_llist_node *Curl_llist_head(struct Curl_llist *list); + +/* Curl_llist_tail() returns the last 'struct Curl_llist_node *', which + might be NULL */ +struct Curl_llist_node *Curl_llist_tail(struct Curl_llist *list); + +/* Curl_llist_count() returns a size_t the number of nodes in the list */ +size_t Curl_llist_count(struct Curl_llist *list); + +/* Curl_node_elem() returns the custom data from a Curl_llist_node */ +void *Curl_node_elem(struct Curl_llist_node *n); + +/* Curl_node_next() returns the next element in a list from a given + Curl_llist_node */ +struct Curl_llist_node *Curl_node_next(struct Curl_llist_node *n); + +/* Curl_node_prev() returns the previous element in a list from a given + Curl_llist_node */ +struct Curl_llist_node *Curl_node_prev(struct Curl_llist_node *n); + +/* Curl_node_llist() return the list the node is in or NULL. */ +struct Curl_llist *Curl_node_llist(struct Curl_llist_node *n); + #endif /* HEADER_CURL_LLIST_H */ diff --git a/lib/macos.c b/lib/macos.c index 205d30db3..e4662be1d 100644 --- a/lib/macos.c +++ b/lib/macos.c @@ -34,21 +34,19 @@ CURLcode Curl_macos_init(void) { - { - /* - * The automagic conversion from IPv4 literals to IPv6 literals only - * works if the SCDynamicStoreCopyProxies system function gets called - * first. As Curl currently does not support system-wide HTTP proxies, we - * therefore do not use any value this function might return. - * - * This function is only available on macOS and is not needed for - * IPv4-only builds, hence the conditions for defining - * CURL_MACOS_CALL_COPYPROXIES in curl_setup.h. - */ - CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); - if(dict) - CFRelease(dict); - } + /* + * The automagic conversion from IPv4 literals to IPv6 literals only + * works if the SCDynamicStoreCopyProxies system function gets called + * first. As Curl currently does not support system-wide HTTP proxies, we + * therefore do not use any value this function might return. + * + * This function is only available on macOS and is not needed for + * IPv4-only builds, hence the conditions for defining + * CURL_MACOS_CALL_COPYPROXIES in curl_setup.h. + */ + CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + if(dict) + CFRelease(dict); return CURLE_OK; } diff --git a/lib/memdebug.c b/lib/memdebug.c index 57fe591ed..bc83d3eea 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -312,7 +312,7 @@ curl_socket_t curl_dbg_socket(int domain, int type, int protocol, sockfd = socket(domain, type, protocol); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log("FD %s:%d socket() = %" CURL_FORMAT_SOCKET_T "\n", + curl_dbg_log("FD %s:%d socket() = %" FMT_SOCKET_T "\n", source, line, sockfd); return sockfd; @@ -356,8 +356,8 @@ int curl_dbg_socketpair(int domain, int type, int protocol, if(source && (0 == res)) curl_dbg_log("FD %s:%d socketpair() = " - "%" CURL_FORMAT_SOCKET_T " %" CURL_FORMAT_SOCKET_T "\n", - source, line, socket_vector[0], socket_vector[1]); + "%" FMT_SOCKET_T " %" FMT_SOCKET_T "\n", + source, line, socket_vector[0], socket_vector[1]); return res; } @@ -372,7 +372,7 @@ curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, curl_socket_t sockfd = accept(s, addr, addrlen); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log("FD %s:%d accept() = %" CURL_FORMAT_SOCKET_T "\n", + curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n", source, line, sockfd); return sockfd; @@ -382,7 +382,7 @@ curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) { if(source) - curl_dbg_log("FD %s:%d sclose(%" CURL_FORMAT_SOCKET_T ")\n", + curl_dbg_log("FD %s:%d sclose(%" FMT_SOCKET_T ")\n", source, line, sockfd); } diff --git a/lib/memdebug.h b/lib/memdebug.h index fd5cc2c94..cabadbcc8 100644 --- a/lib/memdebug.h +++ b/lib/memdebug.h @@ -34,9 +34,9 @@ #include "functypes.h" #if defined(__GNUC__) && __GNUC__ >= 3 -# define ALLOC_FUNC __attribute__((malloc)) -# define ALLOC_SIZE(s) __attribute__((alloc_size(s))) -# define ALLOC_SIZE2(n, s) __attribute__((alloc_size(n, s))) +# define ALLOC_FUNC __attribute__((__malloc__)) +# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) +# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) #elif defined(_MSC_VER) # define ALLOC_FUNC __declspec(restrict) # define ALLOC_SIZE(s) @@ -114,11 +114,17 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); /* Set this symbol on the command-line, recompile all lib-sources */ #undef strdup #define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +#undef malloc #define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) +#undef calloc #define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) +#undef realloc #define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__) +#undef free #define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) +#undef send #define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) +#undef recv #define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) #ifdef _WIN32 diff --git a/lib/mime.c b/lib/mime.c index e9eeb1bf7..885eca62f 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -92,7 +92,7 @@ static const char base64enc[] = /* Quoted-printable character class table. * * We cannot rely on ctype functions since quoted-printable input data - * is assumed to be ascii-compatible, even on non-ascii platforms. */ + * is assumed to be ASCII-compatible, even on non-ASCII platforms. */ #define QP_OK 1 /* Can be represented by itself. */ #define QP_SP 2 /* Space or tab. */ #define QP_CR 3 /* Carriage return. */ @@ -557,7 +557,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, /* On all platforms, input is supposed to be ASCII compatible: for this reason, we use hexadecimal ASCII codes in this function rather than - character constants that can be interpreted as non-ascii on some + character constants that can be interpreted as non-ASCII on some platforms. Preserve ASCII encoding on output too. */ while(st->bufbeg < st->bufend) { size_t len = 1; @@ -1587,6 +1587,8 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) (void) size; /* Always 1. */ + /* TODO: this loop is broken. If `nitems` is <= 4, some encoders will + * return STOP_FILLING without adding any data and this loops infinitely. */ do { hasread = FALSE; ret = readback_part(part, buffer, nitems, &hasread); @@ -1678,7 +1680,7 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) va_list ap; va_start(ap, fmt); - s = curl_mvaprintf(fmt, ap); + s = vaprintf(fmt, ap); va_end(ap); if(s) { @@ -1944,13 +1946,17 @@ static CURLcode cr_mime_read(struct Curl_easy *data, struct cr_mime_ctx *ctx = reader->ctx; size_t nread; + /* Once we have errored, we will return the same error forever */ if(ctx->errored) { + CURL_TRC_READ(data, "cr_mime_read(len=%zu) is errored -> %d, eos=0", + blen, ctx->error_result); *pnread = 0; *peos = FALSE; return ctx->error_result; } if(ctx->seen_eos) { + CURL_TRC_READ(data, "cr_mime_read(len=%zu) seen eos -> 0, eos=1", blen); *pnread = 0; *peos = TRUE; return CURLE_OK; @@ -1963,16 +1969,27 @@ static CURLcode cr_mime_read(struct Curl_easy *data, else if(remain < (curl_off_t)blen) blen = (size_t)remain; } - nread = 0; - if(blen) { - nread = Curl_mime_read(buf, 1, blen, ctx->part); + + if(blen <= 4) { + /* TODO: Curl_mime_read() may go into an infinite loop when reading + * such small lengths. Returning 0 bytes read is a fix that only works + * as request upload buffers will get flushed eventually and larger + * reads will happen again. */ + CURL_TRC_READ(data, "cr_mime_read(len=%zu), too small, return", blen); + *pnread = 0; + *peos = FALSE; + goto out; } + nread = Curl_mime_read(buf, 1, blen, ctx->part); + CURL_TRC_READ(data, "cr_mime_read(len=%zu), mime_read() -> %zd", + blen, nread); + switch(nread) { case 0: if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { failf(data, "client mime read EOF fail, " - "only %"CURL_FORMAT_CURL_OFF_T"/%"CURL_FORMAT_CURL_OFF_T + "only %"FMT_OFF_T"/%"FMT_OFF_T " of needed bytes read", ctx->read_len, ctx->total_len); return CURLE_READ_ERROR; } @@ -1991,11 +2008,21 @@ static CURLcode cr_mime_read(struct Curl_easy *data, case CURL_READFUNC_PAUSE: /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ + CURL_TRC_READ(data, "cr_mime_read(len=%zu), paused by callback", blen); data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ *pnread = 0; *peos = FALSE; break; /* nothing was read */ + case STOP_FILLING: + case READ_ERROR: + failf(data, "read error getting mime data"); + *pnread = 0; + *peos = FALSE; + ctx->errored = TRUE; + ctx->error_result = CURLE_READ_ERROR; + return CURLE_READ_ERROR; + default: if(nread > blen) { /* the read function returned a too large value */ @@ -2013,9 +2040,11 @@ static CURLcode cr_mime_read(struct Curl_easy *data, *peos = ctx->seen_eos; break; } - DEBUGF(infof(data, "cr_mime_read(len=%zu, total=%"CURL_FORMAT_CURL_OFF_T - ", read=%"CURL_FORMAT_CURL_OFF_T") -> %d, %zu, %d", - blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos)); + +out: + CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" FMT_OFF_T + ", read=%"FMT_OFF_T") -> %d, %zu, %d", + blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos); return CURLE_OK; } @@ -2057,7 +2086,7 @@ static CURLcode cr_mime_resume_from(struct Curl_easy *data, if((nread == 0) || (nread > readthisamountnow)) { /* this checks for greater-than only to make sure that the CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T + failf(data, "Could only read %" FMT_OFF_T " bytes from the mime post", passed); return CURLE_READ_ERROR; } diff --git a/lib/mprintf.c b/lib/mprintf.c index 89cbb87ce..42993c717 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -25,7 +25,6 @@ #include "curl_setup.h" #include "dynbuf.h" #include "curl_printf.h" -#include #include "curl_memory.h" /* The last #include file should be: */ diff --git a/lib/mqtt.c b/lib/mqtt.c index 8c461e163..22d354a5c 100644 --- a/lib/mqtt.c +++ b/lib/mqtt.c @@ -121,7 +121,7 @@ static CURLcode mqtt_send(struct Curl_easy *data, CURLcode result = CURLE_OK; struct MQTT *mq = data->req.p.mqtt; size_t n; - result = Curl_xfer_send(data, buf, len, &n); + result = Curl_xfer_send(data, buf, len, FALSE, &n); if(result) return result; Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n); diff --git a/lib/multi.c b/lib/multi.c index 896f73049..062d09cc0 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -94,9 +94,12 @@ static CURLMcode add_next_timeout(struct curltime now, struct Curl_multi *multi, struct Curl_easy *d); static CURLMcode multi_timeout(struct Curl_multi *multi, + struct curltime *expire_time, long *timeout_ms); static void process_pending_handles(struct Curl_multi *multi); static void multi_xfer_bufs_free(struct Curl_multi *multi); +static void Curl_expire_ex(struct Curl_easy *data, const struct curltime *nowp, + timediff_t milli, expire_id id); #ifdef DEBUGBUILD static const char * const multi_statename[]={ @@ -247,10 +250,8 @@ static size_t trhash(void *key, size_t key_length, size_t slots_num) static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) { - (void)k1_len; (void)k2_len; - - return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2; + return !memcmp(k1, k2, k1_len); } static void trhash_dtor(void *nada) @@ -410,15 +411,18 @@ struct Curl_multi *Curl_multi_handle(size_t hashsize, /* socket hash */ Curl_hash_init(&multi->proto_hash, 23, Curl_hash_str, Curl_str_key_compare, ph_freeentry); - if(Curl_conncache_init(&multi->conn_cache, multi, chashsize)) + if(Curl_cpool_init(&multi->cpool, Curl_on_disconnect, + multi, NULL, chashsize)) goto error; Curl_llist_init(&multi->msglist, NULL); + Curl_llist_init(&multi->process, NULL); Curl_llist_init(&multi->pending, NULL); Curl_llist_init(&multi->msgsent, NULL); multi->multiplexing = TRUE; multi->max_concurrent_streams = 100; + multi->last_timeout_ms = -1; #ifdef USE_WINSOCK multi->wsa_event = WSACreateEvent(); @@ -440,7 +444,7 @@ struct Curl_multi *Curl_multi_handle(size_t hashsize, /* socket hash */ sockhash_destroy(&multi->sockhash); Curl_hash_destroy(&multi->proto_hash); Curl_hash_destroy(&multi->hostcache); - Curl_conncache_destroy(&multi->conn_cache); + Curl_cpool_destroy(&multi->cpool); free(multi); return NULL; } @@ -466,52 +470,6 @@ static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) #define multi_warn_debug(x,y) Curl_nop_stmt #endif -/* returns TRUE if the easy handle is supposed to be present in the main link - list */ -static bool in_main_list(struct Curl_easy *data) -{ - return ((data->mstate != MSTATE_PENDING) && - (data->mstate != MSTATE_MSGSENT)); -} - -static void link_easy(struct Curl_multi *multi, - struct Curl_easy *data) -{ - /* We add the new easy entry last in the list. */ - data->next = NULL; /* end of the line */ - if(multi->easyp) { - struct Curl_easy *last = multi->easylp; - last->next = data; - data->prev = last; - multi->easylp = data; /* the new last node */ - } - else { - /* first node, make prev NULL! */ - data->prev = NULL; - multi->easylp = multi->easyp = data; /* both first and last */ - } -} - -/* unlink the given easy handle from the linked list of easy handles */ -static void unlink_easy(struct Curl_multi *multi, - struct Curl_easy *data) -{ - /* make the previous node point to our next */ - if(data->prev) - data->prev->next = data->next; - else - multi->easyp = data->next; /* point to first node */ - - /* make our next point to our previous node */ - if(data->next) - data->next->prev = data->prev; - else - multi->easylp = data->prev; /* point to last node */ - - data->prev = data->next = NULL; -} - - CURLMcode curl_multi_add_handle(struct Curl_multi *multi, struct Curl_easy *data) { @@ -554,7 +512,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, /* * No failure allowed in this function beyond this point. No modification of * easy nor multi handle allowed before this except for potential multi's - * connection cache growing which will not be undone in this function no + * connection pool growing which will not be undone in this function no * matter what. */ if(data->set.errorbuffer) @@ -574,21 +532,11 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, happen. */ Curl_expire(data, 0, EXPIRE_RUN_NOW); - /* A somewhat crude work-around for a little glitch in Curl_update_timer() - that happens if the lastcall time is set to the same time when the handle - is removed as when the next handle is added, as then the check in - Curl_update_timer() that prevents calling the application multiple times - with the same timer info will not trigger and then the new handle's - timeout will not be notified to the app. - - The work-around is thus simply to clear the 'lastcall' variable to force - Curl_update_timer() to always trigger a callback to the app when a new - easy handle is added */ - memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); - rc = Curl_update_timer(multi); - if(rc) + if(rc) { + data->multi = NULL; /* not anymore */ return rc; + } /* set the easy handle */ multistate(data, MSTATE_INIT); @@ -601,13 +549,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->dns.hostcachetype = HCACHE_MULTI; } - /* Point to the shared or multi handle connection cache */ - if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT))) - data->state.conn_cache = &data->share->conn_cache; - else - data->state.conn_cache = &multi->conn_cache; - data->state.lastconnect_id = -1; - #ifdef USE_LIBPSL /* Do the same for PSL. */ if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL))) @@ -616,7 +557,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->psl = &multi->psl; #endif - link_easy(multi, data); + /* add the easy handle to the process list */ + Curl_llist_append(&multi->process, data, &data->multi_queue); /* increase the node-counter */ multi->num_easy++; @@ -624,21 +566,12 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, /* increase the alive-counter */ multi->num_alive++; - CONNCACHE_LOCK(data); - /* The closure handle only ever has default timeouts set. To improve the - state somewhat we clone the timeouts from each added handle so that the - closure handle always has the same timeouts as the most recently added - easy handle. */ - data->state.conn_cache->closure_handle->set.timeout = data->set.timeout; - data->state.conn_cache->closure_handle->set.server_response_timeout = - data->set.server_response_timeout; - data->state.conn_cache->closure_handle->set.no_signal = - data->set.no_signal; - data->id = data->state.conn_cache->next_easy_id++; - if(data->state.conn_cache->next_easy_id <= 0) - data->state.conn_cache->next_easy_id = 0; - CONNCACHE_UNLOCK(data); + /* the identifier inside the multi instance */ + data->mid = multi->next_easy_mid++; + if(multi->next_easy_mid <= 0) + multi->next_easy_mid = 0; + Curl_cpool_xfer_init(data); multi_warn_debug(multi, data); return CURLM_OK; @@ -660,6 +593,91 @@ static void debug_print_sock_hash(void *p) } #endif +struct multi_done_ctx { + BIT(premature); +}; + +static void multi_done_locked(struct connectdata *conn, + struct Curl_easy *data, + void *userdata) +{ + struct multi_done_ctx *mdctx = userdata; + + Curl_detach_connection(data); + + if(CONN_INUSE(conn)) { + /* Stop if still used. */ + DEBUGF(infof(data, "Connection still in use %zu, " + "no more multi_done now!", + Curl_llist_count(&conn->easyq))); + return; + } + + data->state.done = TRUE; /* called just now! */ + data->state.recent_conn_id = conn->connection_id; + + if(conn->dns_entry) + Curl_resolv_unlink(data, &conn->dns_entry); /* done with this */ + Curl_hostcache_prune(data); + + /* if data->set.reuse_forbid is TRUE, it means the libcurl client has + forced us to close this connection. This is ignored for requests taking + place in a NTLM/NEGOTIATE authentication handshake + + if conn->bits.close is TRUE, it means that the connection should be + closed in spite of all our efforts to be nice, due to protocol + restrictions in our or the server's end + + if premature is TRUE, it means this connection was said to be DONE before + the entire request operation is complete and thus we cannot know in what + state it is for reusing, so we are forced to close it. In a perfect world + we can add code that keep track of if we really must close it here or not, + but currently we have no such detail knowledge. + */ + + if((data->set.reuse_forbid +#if defined(USE_NTLM) + && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || + conn->proxy_ntlm_state == NTLMSTATE_TYPE2) +#endif +#if defined(USE_SPNEGO) + && !(conn->http_negotiate_state == GSS_AUTHRECV || + conn->proxy_negotiate_state == GSS_AUTHRECV) +#endif + ) || conn->bits.close + || (mdctx->premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) { + DEBUGF(infof(data, "multi_done, not reusing connection=%" + FMT_OFF_T ", forbid=%d" + ", close=%d, premature=%d, conn_multiplex=%d", + conn->connection_id, data->set.reuse_forbid, + conn->bits.close, mdctx->premature, + Curl_conn_is_multiplex(conn, FIRSTSOCKET))); + connclose(conn, "disconnecting"); + Curl_cpool_disconnect(data, conn, mdctx->premature); + } + else { + /* the connection is no longer in use by any transfer */ + if(Curl_cpool_conn_now_idle(data, conn)) { + /* connection kept in the cpool */ + const char *host = +#ifndef CURL_DISABLE_PROXY + conn->bits.socksproxy ? + conn->socks_proxy.host.dispname : + conn->bits.httpproxy ? conn->http_proxy.host.dispname : +#endif + conn->bits.conn_to_host ? conn->conn_to_host.dispname : + conn->host.dispname; + data->state.lastconnect_id = conn->connection_id; + infof(data, "Connection #%" FMT_OFF_T " to host %s left intact", + conn->connection_id, host); + } + else { + /* connection was removed from the cpool and destroyed. */ + data->state.lastconnect_id = -1; + } + } +} + static CURLcode multi_done(struct Curl_easy *data, CURLcode status, /* an error if this is called after an error was detected */ @@ -667,6 +685,9 @@ static CURLcode multi_done(struct Curl_easy *data, { CURLcode result, r2; struct connectdata *conn = data->conn; + struct multi_done_ctx mdctx; + + memset(&mdctx, 0, sizeof(mdctx)); #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d", @@ -729,106 +750,22 @@ static CURLcode multi_done(struct Curl_easy *data, if(!result) result = Curl_req_done(&data->req, data, premature); - CONNCACHE_LOCK(data); - Curl_detach_connection(data); - if(CONN_INUSE(conn)) { - /* Stop if still used. */ - CONNCACHE_UNLOCK(data); - DEBUGF(infof(data, "Connection still in use %zu, " - "no more multi_done now!", - conn->easyq.size)); - return CURLE_OK; - } - - data->state.done = TRUE; /* called just now! */ - - if(conn->dns_entry) { - Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ - conn->dns_entry = NULL; - } - Curl_hostcache_prune(data); - - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has - forced us to close this connection. This is ignored for requests taking - place in a NTLM/NEGOTIATE authentication handshake - - if conn->bits.close is TRUE, it means that the connection should be - closed in spite of all our efforts to be nice, due to protocol - restrictions in our or the server's end - - if premature is TRUE, it means this connection was said to be DONE before - the entire request operation is complete and thus we cannot know in what - state it is for reusing, so we are forced to close it. In a perfect world - we can add code that keep track of if we really must close it here or not, - but currently we have no such detail knowledge. - */ - - data->state.recent_conn_id = conn->connection_id; - if((data->set.reuse_forbid -#if defined(USE_NTLM) - && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || - conn->proxy_ntlm_state == NTLMSTATE_TYPE2) -#endif -#if defined(USE_SPNEGO) - && !(conn->http_negotiate_state == GSS_AUTHRECV || - conn->proxy_negotiate_state == GSS_AUTHRECV) -#endif - ) || conn->bits.close - || (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) { - DEBUGF(infof(data, "multi_done, not reusing connection=%" - CURL_FORMAT_CURL_OFF_T ", forbid=%d" - ", close=%d, premature=%d, conn_multiplex=%d", - conn->connection_id, - data->set.reuse_forbid, conn->bits.close, premature, - Curl_conn_is_multiplex(conn, FIRSTSOCKET))); - connclose(conn, "disconnecting"); - Curl_conncache_remove_conn(data, conn, FALSE); - CONNCACHE_UNLOCK(data); - Curl_disconnect(data, conn, premature); - } - else { - char buffer[256]; - const char *host = -#ifndef CURL_DISABLE_PROXY - conn->bits.socksproxy ? - conn->socks_proxy.host.dispname : - conn->bits.httpproxy ? conn->http_proxy.host.dispname : -#endif - conn->bits.conn_to_host ? conn->conn_to_host.dispname : - conn->host.dispname; - /* create string before returning the connection */ - curl_off_t connection_id = conn->connection_id; - msnprintf(buffer, sizeof(buffer), - "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact", - connection_id, host); - /* the connection is no longer in use by this transfer */ - CONNCACHE_UNLOCK(data); - if(Curl_conncache_return_conn(data, conn)) { - /* remember the most recently used connection */ - data->state.lastconnect_id = connection_id; - data->state.recent_conn_id = connection_id; - infof(data, "%s", buffer); - } - else - data->state.lastconnect_id = -1; - } + /* Under the potential connection pool's share lock, decide what to + * do with the transfer's connection. */ + mdctx.premature = premature; + Curl_cpool_do_locked(data, data->conn, multi_done_locked, &mdctx); return result; } -static int close_connect_only(struct Curl_easy *data, - struct connectdata *conn, void *param) +static void close_connect_only(struct connectdata *conn, + struct Curl_easy *data, + void *userdata) { - (void)param; - if(data->state.lastconnect_id != conn->connection_id) - return 0; - - if(!conn->connect_only) - return 1; - - connclose(conn, "Removing connect-only easy handle"); - - return 1; + (void)userdata; + (void)data; + if(conn->connect_only) + connclose(conn, "Removing connect-only easy handle"); } CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, @@ -836,15 +773,16 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, { struct Curl_easy *easy = data; bool premature; - struct Curl_llist_element *e; + struct Curl_llist_node *e; CURLMcode rc; + bool removed_timer = FALSE; /* First, make some basic checks that the CURLM handle is a good handle */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(data)) + if(!GOOD_EASY_HANDLE(data) || !multi->num_easy) return CURLM_BAD_EASY_HANDLE; /* Prevent users from trying to remove same easy handle more than once */ @@ -888,18 +826,10 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* The timer must be shut down before data->multi is set to NULL, else the timenode will remain in the splay tree after curl_easy_cleanup is called. Do it after multi_done() in case that sets another time! */ - Curl_expire_clear(data); + removed_timer = Curl_expire_clear(data); - if(data->connect_queue.ptr) { - /* the handle is in the pending or msgsent lists, so go ahead and remove - it */ - if(data->mstate == MSTATE_PENDING) - Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); - else - Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL); - } - if(in_main_list(data)) - unlink_easy(multi, data); + /* the handle is in a list, remove it from whichever it is */ + Curl_node_remove(&data->multi_queue); if(data->dns.hostcachetype == HCACHE_MULTI) { /* stop using the multi handle's DNS cache, *after* the possible @@ -935,15 +865,14 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, curl_socket_t s; s = Curl_getconnectinfo(data, &c); if((s != CURL_SOCKET_BAD) && c) { - Curl_conncache_remove_conn(data, c, TRUE); - Curl_disconnect(data, c, TRUE); + Curl_cpool_disconnect(data, c, TRUE); } } if(data->state.lastconnect_id != -1) { /* Mark any connect-only connection for closure */ - Curl_conncache_foreach(data, data->state.conn_cache, - NULL, close_connect_only); + Curl_cpool_do_by_id(data, data->state.lastconnect_id, + close_connect_only, NULL); } #ifdef USE_LIBPSL @@ -952,33 +881,31 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, data->psl = NULL; #endif - /* as this was using a shared connection cache we clear the pointer to that - since we are not part of that multi handle anymore */ - data->state.conn_cache = NULL; - - data->multi = NULL; /* clear the association to this multi handle */ - /* make sure there is no pending message in the queue sent from this easy handle */ - for(e = multi->msglist.head; e; e = e->next) { - struct Curl_message *msg = e->ptr; + for(e = Curl_llist_head(&multi->msglist); e; e = Curl_node_next(e)) { + struct Curl_message *msg = Curl_node_elem(e); if(msg->extmsg.easy_handle == easy) { - Curl_llist_remove(&multi->msglist, e, NULL); + Curl_node_remove(e); /* there can only be one from this specific handle */ break; } } + data->multi = NULL; /* clear the association to this multi handle */ + data->mid = -1; + /* NOTE NOTE NOTE We do not touch the easy handle here! */ multi->num_easy--; /* one less to care about now */ - process_pending_handles(multi); - rc = Curl_update_timer(multi); - if(rc) - return rc; + if(removed_timer) { + rc = Curl_update_timer(multi); + if(rc) + return rc; + } return CURLM_OK; } @@ -999,7 +926,7 @@ void Curl_detach_connection(struct Curl_easy *data) struct connectdata *conn = data->conn; if(conn) { Curl_conn_ev_data_detach(conn, data); - Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); + Curl_node_remove(&data->conn_queue); } data->conn = NULL; } @@ -1103,7 +1030,7 @@ static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock) sock[sockindex] = conn->sockfd; } - if(CURL_WANT_SEND(data)) { + if(Curl_req_want_send(data)) { if((conn->sockfd != conn->writesockfd) || bitmap == GETSOCK_BLANK) { /* only if they are not the same socket and we have a readable @@ -1212,10 +1139,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, /* Scan through all the easy handles to get the file descriptors set. Some easy handles may not have connected to the remote host yet, and then we must make sure that is done. */ - struct Curl_easy *data; int this_max_fd = -1; - struct easy_pollset ps; - unsigned int i; + struct Curl_llist_node *e; (void)exc_fd_set; /* not used */ if(!GOOD_MULTI_HANDLE(multi)) @@ -1224,20 +1149,22 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - memset(&ps, 0, sizeof(ps)); - for(data = multi->easyp; data; data = data->next) { - multi_getsock(data, &ps); + for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); + unsigned int i; + + multi_getsock(data, &data->last_poll); - for(i = 0; i < ps.num; i++) { - if(!FDSET_SOCK(ps.sockets[i])) + for(i = 0; i < data->last_poll.num; i++) { + if(!FDSET_SOCK(data->last_poll.sockets[i])) /* pretend it does not exist */ continue; - if(ps.actions[i] & CURL_POLL_IN) - FD_SET(ps.sockets[i], read_fd_set); - if(ps.actions[i] & CURL_POLL_OUT) - FD_SET(ps.sockets[i], write_fd_set); - if((int)ps.sockets[i] > this_max_fd) - this_max_fd = (int)ps.sockets[i]; + if(data->last_poll.actions[i] & CURL_POLL_IN) + FD_SET(data->last_poll.sockets[i], read_fd_set); + if(data->last_poll.actions[i] & CURL_POLL_OUT) + FD_SET(data->last_poll.sockets[i], write_fd_set); + if((int)data->last_poll.sockets[i] > this_max_fd) + this_max_fd = (int)data->last_poll.sockets[i]; } } @@ -1251,10 +1178,9 @@ CURLMcode curl_multi_waitfds(struct Curl_multi *multi, unsigned int size, unsigned int *fd_count) { - struct Curl_easy *data; struct curl_waitfds cwfds; - struct easy_pollset ps; CURLMcode result = CURLM_OK; + struct Curl_llist_node *e; if(!ufds) return CURLM_BAD_FUNCTION_ARGUMENT; @@ -1266,16 +1192,16 @@ CURLMcode curl_multi_waitfds(struct Curl_multi *multi, return CURLM_RECURSIVE_API_CALL; Curl_waitfds_init(&cwfds, ufds, size); - memset(&ps, 0, sizeof(ps)); - for(data = multi->easyp; data; data = data->next) { - multi_getsock(data, &ps); - if(Curl_waitfds_add_ps(&cwfds, &ps)) { + for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); + multi_getsock(data, &data->last_poll); + if(Curl_waitfds_add_ps(&cwfds, &data->last_poll)) { result = CURLM_OUT_OF_MEMORY; goto out; } } - if(Curl_conncache_add_waitfds(&multi->conn_cache, &cwfds)) { + if(Curl_cpool_add_waitfds(&multi->cpool, &cwfds)) { result = CURLM_OUT_OF_MEMORY; goto out; } @@ -1312,15 +1238,16 @@ static CURLMcode multi_wait(struct Curl_multi *multi, bool extrawait, /* when no socket, wait */ bool use_wakeup) { - struct Curl_easy *data; - struct easy_pollset ps; size_t i; + struct curltime expire_time; long timeout_internal; int retcode = 0; struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct curl_pollfds cpfds; unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */ CURLMcode result = CURLM_OK; + struct Curl_llist_node *e; + #ifdef USE_WINSOCK WSANETWORKEVENTS wsa_events; DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT); @@ -1339,18 +1266,19 @@ static CURLMcode multi_wait(struct Curl_multi *multi, return CURLM_BAD_FUNCTION_ARGUMENT; Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); - memset(&ps, 0, sizeof(ps)); /* Add the curl handles to our pollfds first */ - for(data = multi->easyp; data; data = data->next) { - multi_getsock(data, &ps); - if(Curl_pollfds_add_ps(&cpfds, &ps)) { + for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); + + multi_getsock(data, &data->last_poll); + if(Curl_pollfds_add_ps(&cpfds, &data->last_poll)) { result = CURLM_OUT_OF_MEMORY; goto out; } } - if(Curl_conncache_add_pollfds(&multi->conn_cache, &cpfds)) { + if(Curl_cpool_add_pollfds(&multi->cpool, &cpfds)) { result = CURLM_OUT_OF_MEMORY; goto out; } @@ -1407,7 +1335,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, * poll. Collecting the sockets may install new timers by protocols * and connection filters. * Use the shorter one of the internal and the caller requested timeout. */ - (void)multi_timeout(multi, &timeout_internal); + (void)multi_timeout(multi, &expire_time, &timeout_internal); if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) timeout_ms = (int)timeout_internal; @@ -1418,7 +1346,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, #endif int pollrc; #ifdef USE_WINSOCK - if(cpfds.n) /* just pre-check with WinSock */ + if(cpfds.n) /* just pre-check with Winsock */ pollrc = Curl_poll(cpfds.pfds, cpfds.n, 0); else pollrc = 0; @@ -1438,7 +1366,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, (DWORD)timeout_ms, FALSE); } - /* With WinSock, we have to run the following section unconditionally + /* With Winsock, we have to run the following section unconditionally to call WSAEventSelect(fd, event, 0) on all the sockets */ { #endif @@ -1480,18 +1408,18 @@ static CURLMcode multi_wait(struct Curl_multi *multi, /* Count up all our own sockets that had activity, and remove them from the event. */ if(curl_nfds) { + for(e = Curl_llist_head(&multi->process); e && !result; + e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); - for(data = multi->easyp; data; data = data->next) { - multi_getsock(data, &ps); - - for(i = 0; i < ps.num; i++) { + for(i = 0; i < data->last_poll.num; i++) { wsa_events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(ps.sockets[i], NULL, + if(WSAEnumNetworkEvents(data->last_poll.sockets[i], NULL, &wsa_events) == 0) { if(ret && !pollrc && wsa_events.lNetworkEvents) retcode++; } - WSAEventSelect(ps.sockets[i], multi->wsa_event, 0); + WSAEventSelect(data->last_poll.sockets[i], multi->wsa_event, 0); } } } @@ -1741,23 +1669,23 @@ static bool multi_handle_timeout(struct Curl_easy *data, else since = data->progress.t_startop; if(data->mstate == MSTATE_RESOLVING) - failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T + failf(data, "Resolving timed out after %" FMT_TIMEDIFF_T " milliseconds", Curl_timediff(*now, since)); else if(data->mstate == MSTATE_CONNECTING) - failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T + failf(data, "Connection timed out after %" FMT_TIMEDIFF_T " milliseconds", Curl_timediff(*now, since)); else { struct SingleRequest *k = &data->req; if(k->size != -1) { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" - CURL_FORMAT_CURL_OFF_T " bytes received", + failf(data, "Operation timed out after %" FMT_TIMEDIFF_T + " milliseconds with %" FMT_OFF_T " out of %" + FMT_OFF_T " bytes received", Curl_timediff(*now, since), k->bytecount, k->size); } else { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T - " bytes received", Curl_timediff(*now, since), k->bytecount); + failf(data, "Operation timed out after %" FMT_TIMEDIFF_T + " milliseconds with %" FMT_OFF_T " bytes received", + Curl_timediff(*now, since), k->bytecount); } } *result = CURLE_OPERATION_TIMEDOUT; @@ -1974,11 +1902,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* There was no connection available. We will go to the pending state and wait for an available connection. */ multistate(data, MSTATE_PENDING); - - /* add this handle to the list of connect-pending handles */ - Curl_llist_append(&multi->pending, data, &data->connect_queue); - /* unlink from the main list */ - unlink_easy(multi, data); + /* unlink from process list */ + Curl_node_remove(&data->multi_queue); + /* add handle to pending list */ + Curl_llist_append(&multi->pending, data, &data->multi_queue); result = CURLE_OK; break; } @@ -1996,8 +1923,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, WAITDO or DO! */ rc = CURLM_CALL_MULTI_PERFORM; - if(connected) + if(connected) { + if(!data->conn->bits.reuse && + Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { + /* new connection, can multiplex, wake pending handles */ + process_pending_handles(data->multi); + } multistate(data, MSTATE_PROTOCONNECT); + } else { multistate(data, MSTATE_CONNECTING); } @@ -2081,22 +2014,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ DEBUGASSERT(data->conn); result = Curl_http_connect(data, &protocol_connected); -#ifndef CURL_DISABLE_PROXY - if(data->conn->bits.proxy_connect_closed) { + if(!result) { rc = CURLM_CALL_MULTI_PERFORM; - /* connect back to proxy again */ - result = CURLE_OK; - multi_done(data, CURLE_OK, FALSE); - multistate(data, MSTATE_CONNECT); + /* initiate protocol connect phase */ + multistate(data, MSTATE_PROTOCONNECT); } else -#endif - if(!result) { - rc = CURLM_CALL_MULTI_PERFORM; - /* initiate protocol connect phase */ - multistate(data, MSTATE_PROTOCONNECT); - } - else stream_error = TRUE; break; #endif @@ -2106,6 +2029,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, DEBUGASSERT(data->conn); result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected); if(connected && !result) { + if(!data->conn->bits.reuse && + Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { + /* new connection, can multiplex, wake pending handles */ + process_pending_handles(data->multi); + } rc = CURLM_CALL_MULTI_PERFORM; multistate(data, MSTATE_PROTOCONNECT); } @@ -2384,24 +2312,22 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, send_timeout_ms = 0; if(data->set.max_send_speed) send_timeout_ms = - Curl_pgrsLimitWaitTime(data->progress.uploaded, - data->progress.ul_limit_size, + Curl_pgrsLimitWaitTime(&data->progress.ul, data->set.max_send_speed, - data->progress.ul_limit_start, *nowp); recv_timeout_ms = 0; if(data->set.max_recv_speed) recv_timeout_ms = - Curl_pgrsLimitWaitTime(data->progress.downloaded, - data->progress.dl_limit_size, + Curl_pgrsLimitWaitTime(&data->progress.dl, data->set.max_recv_speed, - data->progress.dl_limit_start, *nowp); if(!send_timeout_ms && !recv_timeout_ms) { multistate(data, MSTATE_PERFORMING); Curl_ratelimit(data, *nowp); + /* start performing again right away */ + rc = CURLM_CALL_MULTI_PERFORM; } else if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); @@ -2417,19 +2343,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* check if over send speed */ send_timeout_ms = 0; if(data->set.max_send_speed) - send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, - data->progress.ul_limit_size, + send_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.ul, data->set.max_send_speed, - data->progress.ul_limit_start, *nowp); /* check if over recv speed */ recv_timeout_ms = 0; if(data->set.max_recv_speed) - recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, - data->progress.dl_limit_size, + recv_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.dl, data->set.max_recv_speed, - data->progress.dl_limit_start, *nowp); if(send_timeout_ms || recv_timeout_ms) { @@ -2443,7 +2365,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* read/write data if it is ready to do so */ - result = Curl_readwrite(data); + result = Curl_sendrecv(data, nowp); if(data->req.done || (result == CURLE_RECV_ERROR)) { /* If CURLE_RECV_ERROR happens early enough, we assume it was a race @@ -2568,10 +2490,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->conn) { CURLcode res; - if(data->conn->bits.multiplex) - /* Check if we can move pending requests to connection */ - process_pending_handles(multi); /* multiplexing */ - /* post-transfer command */ res = multi_done(data, result, FALSE); @@ -2646,12 +2564,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, We do not have to do this in every case block above where a failure is detected */ Curl_detach_connection(data); - - /* remove connection from cache */ - Curl_conncache_remove_conn(data, conn, TRUE); - - /* disconnect properly */ - Curl_disconnect(data, conn, dead_connection); + Curl_cpool_disconnect(data, conn, dead_connection); } } else if(data->mstate == MSTATE_CONNECT) { @@ -2695,10 +2608,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } multistate(data, MSTATE_MSGSENT); - /* add this handle to the list of msgsent handles */ - Curl_llist_append(&multi->msgsent, data, &data->connect_queue); - /* unlink from the main list */ - unlink_easy(multi, data); + /* unlink from the process list */ + Curl_node_remove(&data->multi_queue); + /* add this handle msgsent list */ + Curl_llist_append(&multi->msgsent, data, &data->multi_queue); return CURLM_OK; } } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); @@ -2710,10 +2623,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) { - struct Curl_easy *data; CURLMcode returncode = CURLM_OK; - struct Curl_tree *t; + struct Curl_tree *t = NULL; struct curltime now = Curl_now(); + struct Curl_llist_node *e; + struct Curl_llist_node *n = NULL; SIGPIPE_VARIABLE(pipe_st); if(!GOOD_MULTI_HANDLE(multi)) @@ -2723,30 +2637,27 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) return CURLM_RECURSIVE_API_CALL; sigpipe_init(&pipe_st); - data = multi->easyp; - if(data) { + for(e = Curl_llist_head(&multi->process); e; e = n) { + struct Curl_easy *data = Curl_node_elem(e); CURLMcode result; /* Do the loop and only alter the signal ignore state if the next handle has a different NO_SIGNAL state than the previous */ - do { - /* the current node might be unlinked in multi_runsingle(), get the next - pointer now */ - struct Curl_easy *datanext = data->next; - - if(data != multi->conn_cache.closure_handle) { - /* connection cache handle is processed below */ - sigpipe_apply(data, &pipe_st); - result = multi_runsingle(multi, &now, data); - if(result) - returncode = result; - } - data = datanext; /* operate on next handle */ - } while(data); + /* the current node might be unlinked in multi_runsingle(), get the next + pointer now */ + n = Curl_node_next(e); + + if(data != multi->cpool.idata) { + /* connection pool handle is processed below */ + sigpipe_apply(data, &pipe_st); + result = multi_runsingle(multi, &now, data); + if(result) + returncode = result; + } } - sigpipe_apply(multi->conn_cache.closure_handle, &pipe_st); - Curl_conncache_multi_perform(multi); + sigpipe_apply(multi->cpool.idata, &pipe_st); + Curl_cpool_multi_perform(multi); sigpipe_restore(&pipe_st); @@ -2764,7 +2675,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); if(t) { /* the removed may have another timeout in queue */ - data = t->payload; + struct Curl_easy *data = Curl_splayget(t); if(data->mstate == MSTATE_PENDING) { bool stream_unused; CURLcode result_unused; @@ -2774,7 +2685,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) move_pending_to_connect(multi, data); } } - (void)add_next_timeout(now, multi, t->payload); + (void)add_next_timeout(now, multi, Curl_splayget(t)); } } while(t); @@ -2787,38 +2698,45 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) return returncode; } -/* unlink_all_msgsent_handles() detaches all those easy handles from this - multi handle */ +/* unlink_all_msgsent_handles() moves all nodes back from the msgsent list to + the process list */ static void unlink_all_msgsent_handles(struct Curl_multi *multi) { - struct Curl_llist_element *e = multi->msgsent.head; - if(e) { - struct Curl_easy *data = e->ptr; - DEBUGASSERT(data->mstate == MSTATE_MSGSENT); - data->multi = NULL; + struct Curl_llist_node *e; + for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); + if(data) { + DEBUGASSERT(data->mstate == MSTATE_MSGSENT); + Curl_node_remove(&data->multi_queue); + /* put it into the process list */ + Curl_llist_append(&multi->process, data, &data->multi_queue); + } } } CURLMcode curl_multi_cleanup(struct Curl_multi *multi) { - struct Curl_easy *data; - struct Curl_easy *nextdata; - if(GOOD_MULTI_HANDLE(multi)) { + struct Curl_llist_node *e; + struct Curl_llist_node *n; if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; multi->magic = 0; /* not good anymore */ + /* move the pending and msgsent entries back to process + so that there is just one list to iterate over */ unlink_all_msgsent_handles(multi); process_pending_handles(multi); + /* First remove all remaining easy handles */ - data = multi->easyp; - while(data) { + for(e = Curl_llist_head(&multi->process); e; e = n) { + struct Curl_easy *data = Curl_node_elem(e); + if(!GOOD_EASY_HANDLE(data)) return CURLM_BAD_HANDLE; - nextdata = data->next; + n = Curl_node_next(e); if(!data->state.done && data->conn) /* if DONE was never called for this handle */ (void)multi_done(data, CURLE_OK, TRUE); @@ -2829,24 +2747,18 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) data->dns.hostcachetype = HCACHE_NONE; } - /* Clear the pointer to the connection cache */ - data->state.conn_cache = NULL; data->multi = NULL; /* clear the association */ #ifdef USE_LIBPSL if(data->psl == &multi->psl) data->psl = NULL; #endif - - data = nextdata; } - /* Close all the connections in the connection cache */ - Curl_conncache_multi_close_all(multi); + Curl_cpool_destroy(&multi->cpool); sockhash_destroy(&multi->sockhash); Curl_hash_destroy(&multi->proto_hash); - Curl_conncache_destroy(&multi->conn_cache); Curl_hash_destroy(&multi->hostcache); Curl_psl_destroy(&multi->psl); @@ -2889,15 +2801,15 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) !multi->in_callback && Curl_llist_count(&multi->msglist)) { /* there is one or more messages in the list */ - struct Curl_llist_element *e; + struct Curl_llist_node *e; /* extract the head of the list to return */ - e = multi->msglist.head; + e = Curl_llist_head(&multi->msglist); - msg = e->ptr; + msg = Curl_node_elem(e); /* remove the extracted entry */ - Curl_llist_remove(&multi->msglist, e, NULL); + Curl_node_remove(e); *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist)); @@ -2970,18 +2882,24 @@ CURLMcode Curl_multi_pollset_ev(struct Curl_multi *multi, } if(last_action && (last_action != cur_action)) { /* Socket was used already, but different action now */ - if(last_action & CURL_POLL_IN) + if(last_action & CURL_POLL_IN) { + DEBUGASSERT(entry->readers); entry->readers--; - if(last_action & CURL_POLL_OUT) + } + if(last_action & CURL_POLL_OUT) { + DEBUGASSERT(entry->writers); entry->writers--; - if(cur_action & CURL_POLL_IN) + } + if(cur_action & CURL_POLL_IN) { entry->readers++; + } if(cur_action & CURL_POLL_OUT) entry->writers++; } else if(!last_action && !Curl_hash_pick(&entry->transfers, (char *)&data, /* hash key */ sizeof(struct Curl_easy *))) { + DEBUGASSERT(entry->users < 100000); /* detect weird values */ /* a new transfer using this socket */ entry->users++; if(cur_action & CURL_POLL_IN) @@ -3043,23 +2961,27 @@ CURLMcode Curl_multi_pollset_ev(struct Curl_multi *multi, if(entry) { unsigned char oldactions = last_ps->actions[i]; /* this socket has been removed. Decrease user count */ + DEBUGASSERT(entry->users); entry->users--; if(oldactions & CURL_POLL_OUT) entry->writers--; if(oldactions & CURL_POLL_IN) entry->readers--; if(!entry->users) { + bool dead = FALSE; if(multi->socket_cb) { set_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->socketp); set_in_callback(multi, FALSE); - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; - } + if(rc == -1) + dead = TRUE; } sh_delentry(entry, &multi->sockhash, s); + if(dead) { + multi->dead = TRUE; + return CURLM_ABORTED_BY_CALLBACK; + } } else { /* still users, but remove this handle as a user of this socket */ @@ -3097,11 +3019,15 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) if(data) { /* if there is still an easy handle associated with this connection */ struct Curl_multi *multi = data->multi; + DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T + " multi is %p", s, (void *)multi)); if(multi) { /* this is set if this connection is part of a handle that is added to a multi handle, and only then this is necessary */ struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); + DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T + " entry is %p", s, (void *)entry)); if(entry) { int rc = 0; if(multi->socket_cb) { @@ -3141,26 +3067,24 @@ static CURLMcode add_next_timeout(struct curltime now, { struct curltime *tv = &d->state.expiretime; struct Curl_llist *list = &d->state.timeoutlist; - struct Curl_llist_element *e; - struct time_node *node = NULL; + struct Curl_llist_node *e; /* move over the timeout list for this specific handle and remove all timeouts that are now passed tense and store the next pending timeout in *tv */ - for(e = list->head; e;) { - struct Curl_llist_element *n = e->next; - timediff_t diff; - node = (struct time_node *)e->ptr; - diff = Curl_timediff_us(node->time, now); + for(e = Curl_llist_head(list); e;) { + struct Curl_llist_node *n = Curl_node_next(e); + struct time_node *node = Curl_node_elem(e); + timediff_t diff = Curl_timediff_us(node->time, now); if(diff <= 0) /* remove outdated entry */ - Curl_llist_remove(list, e, NULL); + Curl_node_remove(e); else /* the list is sorted so get out on the first mismatch */ break; e = n; } - e = list->head; + e = Curl_llist_head(list); if(!e) { /* clear the expire times within the handles that we remove from the splay tree */ @@ -3168,6 +3092,7 @@ static CURLMcode add_next_timeout(struct curltime now, tv->tv_usec = 0; } else { + struct time_node *node = Curl_node_elem(e); /* copy the first entry to 'tv' */ memcpy(tv, &node->time, sizeof(*tv)); @@ -3179,6 +3104,59 @@ static CURLMcode add_next_timeout(struct curltime now, return CURLM_OK; } +struct multi_run_ctx { + struct Curl_multi *multi; + struct curltime now; + size_t run_xfers; + SIGPIPE_MEMBER(pipe_st); + bool run_cpool; +}; + +static CURLMcode multi_run_expired(struct multi_run_ctx *mrc) +{ + struct Curl_multi *multi = mrc->multi; + struct Curl_easy *data = NULL; + struct Curl_tree *t = NULL; + CURLMcode result = CURLM_OK; + + /* + * The loop following here will go on as long as there are expire-times left + * to process (compared to mrc->now) in the splay and 'data' will be + * re-assigned for every expired handle we deal with. + */ + while(1) { + /* Check if there is one (more) expired timer to deal with! This function + extracts a matching node if there is one */ + multi->timetree = Curl_splaygetbest(mrc->now, multi->timetree, &t); + if(!t) + goto out; + + data = Curl_splayget(t); /* assign this for next loop */ + if(!data) + continue; + + (void)add_next_timeout(mrc->now, multi, data); + if(data == multi->cpool.idata) { + mrc->run_cpool = TRUE; + continue; + } + + mrc->run_xfers++; + sigpipe_apply(data, &mrc->pipe_st); + result = multi_runsingle(multi, &mrc->now, data); + + if(CURLM_OK >= result) { + /* get the socket(s) and check if the state has been changed since + last */ + result = singlesocket(multi, data); + if(result) + goto out; + } + } + +out: + return result; +} static CURLMcode multi_socket(struct Curl_multi *multi, bool checkall, curl_socket_t s, @@ -3187,28 +3165,31 @@ static CURLMcode multi_socket(struct Curl_multi *multi, { CURLMcode result = CURLM_OK; struct Curl_easy *data = NULL; - struct Curl_tree *t; - struct curltime now = Curl_now(); - bool run_conn_cache = FALSE; - SIGPIPE_VARIABLE(pipe_st); + struct multi_run_ctx mrc; + + (void)ev_bitmask; + memset(&mrc, 0, sizeof(mrc)); + mrc.multi = multi; + mrc.now = Curl_now(); + sigpipe_init(&mrc.pipe_st); if(checkall) { + struct Curl_llist_node *e; /* *perform() deals with running_handles on its own */ result = curl_multi_perform(multi, running_handles); /* walk through each easy handle and do the socket state change magic and callbacks */ if(result != CURLM_BAD_HANDLE) { - data = multi->easyp; - while(data && !result) { - result = singlesocket(multi, data); - data = data->next; + for(e = Curl_llist_head(&multi->process); e && !result; + e = Curl_node_next(e)) { + result = singlesocket(multi, Curl_node_elem(e)); } } - - /* or should we fall-through and do the timer-based stuff? */ - return result; + mrc.run_cpool = TRUE; + goto out; } + if(s != CURL_SOCKET_TIMEOUT) { struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); @@ -3219,8 +3200,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi, asked to get removed, so thus we better survive stray socket actions and just move on. */ /* The socket might come from a connection that is being shut down - * by the multi's conncache. */ - Curl_conncache_multi_socket(multi, s, ev_bitmask); + * by the multi's connection pool. */ + Curl_cpool_multi_socket(multi, s, ev_bitmask); } else { struct Curl_hash_iterator iter; @@ -3234,79 +3215,43 @@ static CURLMcode multi_socket(struct Curl_multi *multi, DEBUGASSERT(data); DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); - if(data == multi->conn_cache.closure_handle) - run_conn_cache = TRUE; + if(data == multi->cpool.idata) + mrc.run_cpool = TRUE; else { - if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) - /* set socket event bitmask if they are not locked */ - data->state.select_bits |= (unsigned char)ev_bitmask; - - Curl_expire(data, 0, EXPIRE_RUN_NOW); + /* Expire with out current now, so we will get it below when + * asking the splaytree for expired transfers. */ + Curl_expire_ex(data, &mrc.now, 0, EXPIRE_RUN_NOW); } } - - /* Now we fall-through and do the timer-based stuff, since we do not want - to force the user to have to deal with timeouts as long as at least - one connection in fact has traffic. */ - - data = NULL; /* set data to NULL again to avoid calling - multi_runsingle() in case there is no need to */ - now = Curl_now(); /* get a newer time since the multi_runsingle() loop - may have taken some time */ } } - else { - /* Asked to run due to time-out. Clear the 'lastcall' variable to force - Curl_update_timer() to trigger a callback to the app again even if the - same timeout is still the one to run after this call. That handles the - case when the application asks libcurl to run the timeout - prematurely. */ - memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); - } - /* - * The loop following here will go on as long as there are expire-times left - * to process in the splay and 'data' will be re-assigned for every expired - * handle we deal with. - */ - sigpipe_init(&pipe_st); - do { - if(data == multi->conn_cache.closure_handle) - run_conn_cache = TRUE; - /* the first loop lap 'data' can be NULL */ - else if(data) { - sigpipe_apply(data, &pipe_st); - result = multi_runsingle(multi, &now, data); - - if(CURLM_OK >= result) { - /* get the socket(s) and check if the state has been changed since - last */ - result = singlesocket(multi, data); - if(result) - break; - } - } - - /* Check if there is one (more) expired timer to deal with! This function - extracts a matching node if there is one */ - - multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); - if(t) { - data = t->payload; /* assign this for next loop */ - (void)add_next_timeout(now, multi, t->payload); - } - - } while(t); + result = multi_run_expired(&mrc); + if(result) + goto out; - if(run_conn_cache) { - sigpipe_apply(multi->conn_cache.closure_handle, &pipe_st); - Curl_conncache_multi_perform(multi); + if(mrc.run_xfers) { + /* Running transfers takes time. With a new timestamp, we might catch + * other expires which are due now. Instead of telling the application + * to set a 0 timeout and call us again, we run them here. + * Do that only once or it might be unfair to transfers on other + * sockets. */ + mrc.now = Curl_now(); + result = multi_run_expired(&mrc); } - sigpipe_restore(&pipe_st); +out: + if(mrc.run_cpool) { + sigpipe_apply(multi->cpool.idata, &mrc.pipe_st); + Curl_cpool_multi_perform(multi); + } + sigpipe_restore(&mrc.pipe_st); if(running_handles) *running_handles = (int)multi->num_alive; + + if(CURLM_OK >= result) + result = Curl_update_timer(multi); return result; } @@ -3395,39 +3340,28 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, int *running_handles) { - CURLMcode result; if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - result = multi_socket(multi, FALSE, s, 0, running_handles); - if(CURLM_OK >= result) - result = Curl_update_timer(multi); - return result; + return multi_socket(multi, FALSE, s, 0, running_handles); } CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, int ev_bitmask, int *running_handles) { - CURLMcode result; if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); - if(CURLM_OK >= result) - result = Curl_update_timer(multi); - return result; + return multi_socket(multi, FALSE, s, ev_bitmask, running_handles); } CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) { - CURLMcode result; if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); - if(CURLM_OK >= result) - result = Curl_update_timer(multi); - return result; + return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); } static CURLMcode multi_timeout(struct Curl_multi *multi, + struct curltime *expire_time, long *timeout_ms) { static const struct curltime tv_zero = {0, 0}; @@ -3443,20 +3377,29 @@ static CURLMcode multi_timeout(struct Curl_multi *multi, /* splay the lowest to the bottom */ multi->timetree = Curl_splay(tv_zero, multi->timetree); - - if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) { + /* this will not return NULL from a non-emtpy tree, but some compilers + * are not convinced of that. Analyzers are hard. */ + *expire_time = multi->timetree? multi->timetree->key : tv_zero; + + /* 'multi->timetree' will be non-NULL here but the compilers sometimes + yell at us if we assume so */ + if(multi->timetree && + Curl_timediff_us(multi->timetree->key, now) > 0) { /* some time left before expiration */ timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now); /* this should be safe even on 32-bit archs, as we do not use that overly long timeouts */ *timeout_ms = (long)diff; } - else + else { /* 0 means immediately */ *timeout_ms = 0; + } } - else + else { + *expire_time = tv_zero; *timeout_ms = -1; + } return CURLM_OK; } @@ -3464,6 +3407,8 @@ static CURLMcode multi_timeout(struct Curl_multi *multi, CURLMcode curl_multi_timeout(struct Curl_multi *multi, long *timeout_ms) { + struct curltime expire_time; + /* First, make some basic checks that the CURLM handle is a good handle */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -3471,56 +3416,79 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - return multi_timeout(multi, timeout_ms); + return multi_timeout(multi, &expire_time, timeout_ms); } +#define DEBUG_UPDATE_TIMER 0 + /* * Tell the application it should update its timers, if it subscribes to the * update timer callback. */ CURLMcode Curl_update_timer(struct Curl_multi *multi) { + struct curltime expire_ts; long timeout_ms; int rc; + bool set_value = FALSE; if(!multi->timer_cb || multi->dead) return CURLM_OK; - if(multi_timeout(multi, &timeout_ms)) { + if(multi_timeout(multi, &expire_ts, &timeout_ms)) { return CURLM_OK; } - if(timeout_ms < 0) { - static const struct curltime none = {0, 0}; - if(Curl_splaycomparekeys(none, multi->timer_lastcall)) { - multi->timer_lastcall = none; - /* there is no timeout now but there was one previously, tell the app to - disable it */ - set_in_callback(multi, TRUE); - rc = multi->timer_cb(multi, -1, multi->timer_userp); - set_in_callback(multi, FALSE); - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; - } - return CURLM_OK; - } - return CURLM_OK; - } - - /* When multi_timeout() is done, multi->timetree points to the node with the - * timeout we got the (relative) time-out time for. We can thus easily check - * if this is the same (fixed) time as we got in a previous call and then - * avoid calling the callback again. */ - if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) - return CURLM_OK; - multi->timer_lastcall = multi->timetree->key; + if(timeout_ms < 0 && multi->last_timeout_ms < 0) { +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), still no timeout, no change\n"); +#endif + } + else if(timeout_ms < 0) { + /* there is no timeout now but there was one previously */ +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), remove timeout, " + " last_timeout=%ldms\n", multi->last_timeout_ms); +#endif + timeout_ms = -1; /* normalize */ + set_value = TRUE; + } + else if(multi->last_timeout_ms < 0) { +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), had no timeout, set now\n"); +#endif + set_value = TRUE; + } + else if(Curl_timediff_us(multi->last_expire_ts, expire_ts)) { + /* We had a timeout before and have one now, the absolute timestamp + * differs. The relative timeout_ms may be the same, but the starting + * point differs. Let the application restart its timer. */ +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), expire timestamp changed\n"); +#endif + set_value = TRUE; + } + else { + /* We have same expire time as previously. Our relative 'timeout_ms' + * may be different now, but the application has the timer running + * and we do not to tell it to start this again. */ +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), same expire timestamp, no change\n"); +#endif + } - set_in_callback(multi, TRUE); - rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp); - set_in_callback(multi, FALSE); - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; + if(set_value) { +#if DEBUG_UPDATE_TIMER + fprintf(stderr, "Curl_update_timer(), set timeout %ldms\n", timeout_ms); +#endif + multi->last_expire_ts = expire_ts; + multi->last_timeout_ms = timeout_ms; + set_in_callback(multi, TRUE); + rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp); + set_in_callback(multi, FALSE); + if(rc == -1) { + multi->dead = TRUE; + return CURLM_ABORTED_BY_CALLBACK; + } } return CURLM_OK; } @@ -3533,13 +3501,13 @@ CURLMcode Curl_update_timer(struct Curl_multi *multi) static void multi_deltimeout(struct Curl_easy *data, expire_id eid) { - struct Curl_llist_element *e; + struct Curl_llist_node *e; struct Curl_llist *timeoutlist = &data->state.timeoutlist; /* find and remove the specific node from the list */ - for(e = timeoutlist->head; e; e = e->next) { - struct time_node *n = (struct time_node *)e->ptr; + for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) { + struct time_node *n = Curl_node_elem(e); if(n->eid == eid) { - Curl_llist_remove(timeoutlist, e, NULL); + Curl_node_remove(e); return; } } @@ -3557,9 +3525,9 @@ multi_addtimeout(struct Curl_easy *data, struct curltime *stamp, expire_id eid) { - struct Curl_llist_element *e; + struct Curl_llist_node *e; struct time_node *node; - struct Curl_llist_element *prev = NULL; + struct Curl_llist_node *prev = NULL; size_t n; struct Curl_llist *timeoutlist = &data->state.timeoutlist; @@ -3572,8 +3540,8 @@ multi_addtimeout(struct Curl_easy *data, n = Curl_llist_count(timeoutlist); if(n) { /* find the correct spot in the list */ - for(e = timeoutlist->head; e; e = e->next) { - struct time_node *check = (struct time_node *)e->ptr; + for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) { + struct time_node *check = Curl_node_elem(e); timediff_t diff = Curl_timediff(check->time, node->time); if(diff > 0) break; @@ -3599,10 +3567,12 @@ multi_addtimeout(struct Curl_easy *data, * * Expire replaces a former timeout using the same id if already set. */ -void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) +static void Curl_expire_ex(struct Curl_easy *data, + const struct curltime *nowp, + timediff_t milli, expire_id id) { struct Curl_multi *multi = data->multi; - struct curltime *nowp = &data->state.expiretime; + struct curltime *curr_expire = &data->state.expiretime; struct curltime set; /* this is only interesting while there is still an associated multi struct @@ -3612,7 +3582,7 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) DEBUGASSERT(id < EXPIRE_LAST); - set = Curl_now(); + set = *nowp; set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bits conversion */ set.tv_usec += (int)(milli%1000)*1000; @@ -3628,11 +3598,11 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) in case we need to recompute the minimum timer later. */ multi_addtimeout(data, &set, id); - if(nowp->tv_sec || nowp->tv_usec) { + if(curr_expire->tv_sec || curr_expire->tv_usec) { /* This means that the struct is added as a node in the splay tree. Compare if the new time is earlier, and only remove-old/add-new if it is. */ - timediff_t diff = Curl_timediff(set, *nowp); + timediff_t diff = Curl_timediff(set, *curr_expire); int rc; if(diff > 0) { @@ -3651,12 +3621,18 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) /* Indicate that we are in the splay tree and insert the new timer expiry value since it is our local minimum. */ - *nowp = set; - data->state.timenode.payload = data; - multi->timetree = Curl_splayinsert(*nowp, multi->timetree, + *curr_expire = set; + Curl_splayset(&data->state.timenode, data); + multi->timetree = Curl_splayinsert(*curr_expire, multi->timetree, &data->state.timenode); } +void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) +{ + struct curltime now = Curl_now(); + Curl_expire_ex(data, &now, milli, id); +} + /* * Curl_expire_done() * @@ -3674,7 +3650,7 @@ void Curl_expire_done(struct Curl_easy *data, expire_id id) * * Clear ALL timeout values for this handle. */ -void Curl_expire_clear(struct Curl_easy *data) +bool Curl_expire_clear(struct Curl_easy *data) { struct Curl_multi *multi = data->multi; struct curltime *nowp = &data->state.expiretime; @@ -3682,7 +3658,7 @@ void Curl_expire_clear(struct Curl_easy *data) /* this is only interesting while there is still an associated multi struct remaining! */ if(!multi) - return; + return FALSE; if(nowp->tv_sec || nowp->tv_usec) { /* Since this is an cleared time, we must remove the previous entry from @@ -3695,22 +3671,19 @@ void Curl_expire_clear(struct Curl_easy *data) if(rc) infof(data, "Internal error clearing splay node = %d", rc); - /* flush the timeout list too */ - while(list->size > 0) { - Curl_llist_remove(list, list->tail, NULL); - } + /* clear the timeout list too */ + Curl_llist_destroy(list, NULL); #ifdef DEBUGBUILD infof(data, "Expire cleared"); #endif nowp->tv_sec = 0; nowp->tv_usec = 0; + return TRUE; } + return FALSE; } - - - CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, void *hashp) { @@ -3726,52 +3699,24 @@ CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, return CURLM_OK; } -size_t Curl_multi_max_host_connections(struct Curl_multi *multi) -{ - return multi ? (size_t)multi->max_host_connections : 0; -} - -size_t Curl_multi_max_total_connections(struct Curl_multi *multi) -{ - return multi ? (size_t)multi->max_total_connections : 0; -} - -/* - * When information about a connection has appeared, call this! - */ - -void Curl_multiuse_state(struct Curl_easy *data, - int bundlestate) /* use BUNDLE_* defines */ -{ - struct connectdata *conn; - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - conn = data->conn; - DEBUGASSERT(conn); - DEBUGASSERT(conn->bundle); - - conn->bundle->multiuse = bundlestate; - process_pending_handles(data->multi); -} - static void move_pending_to_connect(struct Curl_multi *multi, struct Curl_easy *data) { DEBUGASSERT(data->mstate == MSTATE_PENDING); - /* put it back into the main list */ - link_easy(multi, data); + /* Remove this node from the pending list */ + Curl_node_remove(&data->multi_queue); - multistate(data, MSTATE_CONNECT); + /* put it into the process list */ + Curl_llist_append(&multi->process, data, &data->multi_queue); - /* Remove this node from the pending list */ - Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); + multistate(data, MSTATE_CONNECT); /* Make sure that the handle will be processed soonish. */ Curl_expire(data, 0, EXPIRE_RUN_NOW); } -/* process_pending_handles() moves a handle from PENDING back into the main +/* process_pending_handles() moves a handle from PENDING back into the process list and change state to CONNECT. We do not move all transfers because that can be a significant amount. @@ -3787,9 +3732,9 @@ static void move_pending_to_connect(struct Curl_multi *multi, */ static void process_pending_handles(struct Curl_multi *multi) { - struct Curl_llist_element *e = multi->pending.head; + struct Curl_llist_node *e = Curl_llist_head(&multi->pending); if(e) { - struct Curl_easy *data = e->ptr; + struct Curl_easy *data = Curl_node_elem(e); move_pending_to_connect(multi, data); } } @@ -3817,12 +3762,12 @@ struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi) (multi->num_easy + 1)); if(a) { unsigned int i = 0; - struct Curl_easy *e = multi->easyp; - while(e) { + struct Curl_llist_node *e; + for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *data = Curl_node_elem(e); DEBUGASSERT(i < multi->num_easy); - if(!e->state.internal) - a[i++] = e; - e = e->next; + if(!data->state.internal) + a[i++] = data; } a[i] = NULL; /* last entry is a NULL */ } @@ -3945,3 +3890,32 @@ static void multi_xfer_bufs_free(struct Curl_multi *multi) multi->xfer_ulbuf_len = 0; multi->xfer_ulbuf_borrowed = FALSE; } + +struct Curl_easy *Curl_multi_get_handle(struct Curl_multi *multi, + curl_off_t mid) +{ + + if(mid >= 0) { + struct Curl_easy *data; + struct Curl_llist_node *e; + + for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { + data = Curl_node_elem(e); + if(data->mid == mid) + return data; + } + /* may be in msgsent queue */ + for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) { + data = Curl_node_elem(e); + if(data->mid == mid) + return data; + } + /* may be in pending queue */ + for(e = Curl_llist_head(&multi->pending); e; e = Curl_node_next(e)) { + data = Curl_node_elem(e); + if(data->mid == mid) + return data; + } + } + return NULL; +} diff --git a/lib/multihandle.h b/lib/multihandle.h index 9b80beab9..fef117c06 100644 --- a/lib/multihandle.h +++ b/lib/multihandle.h @@ -33,7 +33,7 @@ struct connectdata; struct Curl_message { - struct Curl_llist_element list; + struct Curl_llist_node list; /* the 'CURLMsg' is the part that is visible to the external user */ struct CURLMsg extmsg; }; @@ -86,20 +86,17 @@ struct Curl_multi { this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */ unsigned int magic; - /* We have a doubly-linked list with easy handles */ - struct Curl_easy *easyp; - struct Curl_easy *easylp; /* last node */ - unsigned int num_easy; /* amount of entries in the linked list above. */ unsigned int num_alive; /* amount of easy handles that are added but have not yet reached COMPLETE state */ struct Curl_llist msglist; /* a list of messages from completed transfers */ - struct Curl_llist pending; /* Curl_easys that are in the - MSTATE_PENDING state */ - struct Curl_llist msgsent; /* Curl_easys that are in the - MSTATE_MSGSENT state */ + /* Each added easy handle is added to ONE of these three lists */ + struct Curl_llist process; /* not in PENDING or MSGSENT */ + struct Curl_llist pending; /* in PENDING */ + struct Curl_llist msgsent; /* in MSGSENT */ + curl_off_t next_easy_mid; /* next multi-id for easy handle added */ /* callback function and user data pointer for the *socket() API */ curl_socket_callback socket_cb; @@ -141,7 +138,7 @@ struct Curl_multi { struct Curl_hash proto_hash; /* Shared connection cache (bundles)*/ - struct conncache conn_cache; + struct cpool cpool; long max_host_connections; /* if >0, a fixed limit of the maximum number of connections per host */ @@ -154,10 +151,11 @@ struct Curl_multi { /* timer callback and user data pointer for the *socket() API */ curl_multi_timer_callback timer_cb; void *timer_userp; - struct curltime timer_lastcall; /* the fixed time for the timeout for the - previous callback */ + long last_timeout_ms; /* the last timeout value set via timer_cb */ + struct curltime last_expire_ts; /* timestamp of last expiry */ + #ifdef USE_WINSOCK - WSAEVENT wsa_event; /* winsock event used for waits */ + WSAEVENT wsa_event; /* Winsock event used for waits */ #else #ifdef ENABLE_WAKEUP curl_socket_t wakeup_pair[2]; /* eventfd()/pipe()/socketpair() used for diff --git a/lib/multiif.h b/lib/multiif.h index d3c12baee..e5872cd6d 100644 --- a/lib/multiif.h +++ b/lib/multiif.h @@ -30,7 +30,7 @@ CURLcode Curl_updatesocket(struct Curl_easy *data); void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id); -void Curl_expire_clear(struct Curl_easy *data); +bool Curl_expire_clear(struct Curl_easy *data); void Curl_expire_done(struct Curl_easy *data, expire_id id); CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT; void Curl_attach_connection(struct Curl_easy *data, @@ -63,15 +63,6 @@ struct Curl_multi *Curl_multi_handle(size_t hashsize, /* mask for checking if read and/or write is set for index x */ #define GETSOCK_MASK_RW(x) (GETSOCK_READSOCK(x)|GETSOCK_WRITESOCK(x)) -/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */ -size_t Curl_multi_max_host_connections(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */ -size_t Curl_multi_max_total_connections(struct Curl_multi *multi); - -void Curl_multiuse_state(struct Curl_easy *data, - int bundlestate); /* use BUNDLE_* defines */ - /* * Curl_multi_closed() * @@ -153,4 +144,10 @@ CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data, */ void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf); +/** + * Get the transfer handle for the given id. Returns NULL if not found. + */ +struct Curl_easy *Curl_multi_get_handle(struct Curl_multi *multi, + curl_off_t id); + #endif /* HEADER_CURL_MULTIIF_H */ diff --git a/lib/netrc.c b/lib/netrc.c index 571fc7359..490efb64c 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -324,7 +324,7 @@ int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, return retcode; /* no home directory found (or possibly out of memory) */ - filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR); + filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); if(!filealloc) { free(homea); return -1; @@ -334,7 +334,7 @@ int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, #ifdef _WIN32 if(retcode == NETRC_FILE_MISSING) { /* fallback to the old-style "_netrc" file */ - filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); + filealloc = aprintf("%s%s_netrc", home, DIR_CHAR); if(!filealloc) { free(homea); return -1; diff --git a/lib/nonblock.c b/lib/nonblock.c index 9ee93db2e..6dcf42a7e 100644 --- a/lib/nonblock.c +++ b/lib/nonblock.c @@ -47,7 +47,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */) { #if defined(HAVE_FCNTL_O_NONBLOCK) - /* most recent unix versions */ + /* most recent Unix versions */ int flags; flags = sfcntl(sockfd, F_GETFL, 0); if(flags < 0) @@ -65,7 +65,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ #elif defined(HAVE_IOCTL_FIONBIO) - /* older unix versions */ + /* older Unix versions */ int flags = nonblock ? 1 : 0; return ioctl(sockfd, FIONBIO, &flags); diff --git a/lib/openldap.c b/lib/openldap.c index 1b35ba0d7..f3e13ed5c 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -1201,7 +1201,7 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) if(conn) { struct ldapconninfo *li = conn->proto.ldapc; CURLcode err = CURLE_SEND_ERROR; - ret = (li->send)(data, FIRSTSOCKET, buf, len, &err); + ret = (li->send)(data, FIRSTSOCKET, buf, len, FALSE, &err); if(ret < 0 && err == CURLE_AGAIN) { SET_SOCKERRNO(EWOULDBLOCK); } diff --git a/lib/optiontable.pl b/lib/optiontable.pl new file mode 100644 index 000000000..2727784e7 --- /dev/null +++ b/lib/optiontable.pl @@ -0,0 +1,152 @@ +#!/usr/bin/env perl + +print <, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */ + +#include "curl_setup.h" +#include "easyoptions.h" + +/* all easy setopt options listed in alphabetical order */ +struct curl_easyoption Curl_easyopts[] = { +HEAD + ; + +my $lastnum=0; + +sub add { + my($opt, $type, $num)=@_; + my $name; + # remove all spaces from the type + $type =~ s/ //g; + my $ext = $type; + + if($opt =~ /OBSOLETE/) { + # skip obsolete options + next; + } + + if($opt =~ /^CURLOPT_(.*)/) { + $name=$1; + } + $ext =~ s/CURLOPTTYPE_//; + $ext =~ s/CBPOINT/CBPTR/; + $ext =~ s/POINT\z//; + $type = "CURLOT_$ext"; + + $opt{$name} = $opt; + $type{$name} = $type; + push @names, $name; + if($num < $lastnum) { + print STDERR "ERROR: $opt has bad number: $num < $lastnum\n"; + exit 2; + } + else { + $lastnum = $num; + } +} + + +my $fl; +while() { + my $l = $_; + if($fl) { + # continued deprecation + if($l =~ /(.*)\),/) { + $fl .= $1; + + # the end + my @p=split(/, */, $fl); + add($p[0], $p[1], $p[2]); + undef $fl; + } + else { + # another line to append + chomp $l; + $fl .= $l; + } + } + + if(/^ *CURLOPTDEPRECATED\((.*)/) { + $fl = $1; + chomp $fl; + } + + if(/^ *CURLOPT\(([^,]*), ([^,]*), (\d+)\)/) { + my($opt, $type, $num)=($1,$2,$3); + add($opt, $type, $num); + } + + # alias for an older option + # old = new + if(/^#define (CURLOPT_[^ ]*) *(CURLOPT_\S*)/) { + my ($o, $n)=($1, $2); + # skip obsolete ones + if(($n !~ /OBSOLETE/) && ($o !~ /OBSOLETE/)) { + $o =~ s/^CURLOPT_//; + $n =~ s/^CURLOPT_//; + $alias{$o} = $n; + push @names, $o, + } + } +} + + +for my $name (sort @names) { + my $oname = $name; + my $a = $alias{$name}; + my $flag = "0"; + if($a) { + $name = $alias{$name}; + $flag = "CURLOT_FLAG_ALIAS"; + } + $o = sprintf(" {\"%s\", %s, %s, %s},\n", + $oname, $opt{$name}, $type{$name}, $flag); + if(length($o) < 80) { + print $o; + } + else { + printf(" {\"%s\", %s,\n %s, %s},\n", + $oname, $opt{$name}, $type{$name}, $flag); + } +} + +print <data_prot = PROT_CMD; #endif - result = Curl_conn_send(data, FIRSTSOCKET, s, write_len, &bytes_written); + result = Curl_conn_send(data, FIRSTSOCKET, s, write_len, FALSE, + &bytes_written); if(result == CURLE_AGAIN) { bytes_written = 0; } @@ -285,94 +286,99 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, { struct connectdata *conn = data->conn; CURLcode result = CURLE_OK; + ssize_t gotbytes; + char buffer[900]; *code = 0; /* 0 for errors or not done */ *size = 0; - if(pp->nfinal) { - /* a previous call left this many bytes in the beginning of the buffer as - that was the final line; now ditch that */ - size_t full = Curl_dyn_len(&pp->recvbuf); + do { + gotbytes = 0; + if(pp->nfinal) { + /* a previous call left this many bytes in the beginning of the buffer as + that was the final line; now ditch that */ + size_t full = Curl_dyn_len(&pp->recvbuf); - /* trim off the "final" leading part */ - Curl_dyn_tail(&pp->recvbuf, full - pp->nfinal); + /* trim off the "final" leading part */ + Curl_dyn_tail(&pp->recvbuf, full - pp->nfinal); - pp->nfinal = 0; /* now gone */ - } - if(!pp->overflow) { - ssize_t gotbytes = 0; - char buffer[900]; + pp->nfinal = 0; /* now gone */ + } + if(!pp->overflow) { + result = pingpong_read(data, sockindex, buffer, sizeof(buffer), + &gotbytes); + if(result == CURLE_AGAIN) + return CURLE_OK; - result = pingpong_read(data, sockindex, buffer, sizeof(buffer), &gotbytes); - if(result == CURLE_AGAIN) - return CURLE_OK; + if(result) + return result; - if(result) - return result; + if(gotbytes <= 0) { + failf(data, "response reading failed (errno: %d)", SOCKERRNO); + return CURLE_RECV_ERROR; + } - if(gotbytes <= 0) { - failf(data, "response reading failed (errno: %d)", SOCKERRNO); - return CURLE_RECV_ERROR; - } + result = Curl_dyn_addn(&pp->recvbuf, buffer, gotbytes); + if(result) + return result; - result = Curl_dyn_addn(&pp->recvbuf, buffer, gotbytes); - if(result) - return result; + data->req.headerbytecount += (unsigned int)gotbytes; - data->req.headerbytecount += (unsigned int)gotbytes; + pp->nread_resp += gotbytes; + } - pp->nread_resp += gotbytes; - } + do { + char *line = Curl_dyn_ptr(&pp->recvbuf); + char *nl = memchr(line, '\n', Curl_dyn_len(&pp->recvbuf)); + if(nl) { + /* a newline is CRLF in pp-talk, so the CR is ignored as + the line is not really terminated until the LF comes */ + size_t length = nl - line + 1; - do { - char *line = Curl_dyn_ptr(&pp->recvbuf); - char *nl = memchr(line, '\n', Curl_dyn_len(&pp->recvbuf)); - if(nl) { - /* a newline is CRLF in pp-talk, so the CR is ignored as - the line is not really terminated until the LF comes */ - size_t length = nl - line + 1; - - /* output debug output if that is requested */ + /* output debug output if that is requested */ #ifdef HAVE_GSSAPI - if(!conn->sec_complete) + if(!conn->sec_complete) #endif - Curl_debug(data, CURLINFO_HEADER_IN, line, length); - - /* - * Pass all response-lines to the callback function registered for - * "headers". The response lines can be seen as a kind of headers. - */ - result = Curl_client_write(data, CLIENTWRITE_INFO, line, length); - if(result) - return result; - - if(pp->endofresp(data, conn, line, length, code)) { - /* When at "end of response", keep the endofresp line first in the - buffer since it will be accessed outside (by pingpong - parsers). Store the overflow counter to inform about additional - data in this buffer after the endofresp line. */ - pp->nfinal = length; + Curl_debug(data, CURLINFO_HEADER_IN, line, length); + + /* + * Pass all response-lines to the callback function registered for + * "headers". The response lines can be seen as a kind of headers. + */ + result = Curl_client_write(data, CLIENTWRITE_INFO, line, length); + if(result) + return result; + + if(pp->endofresp(data, conn, line, length, code)) { + /* When at "end of response", keep the endofresp line first in the + buffer since it will be accessed outside (by pingpong + parsers). Store the overflow counter to inform about additional + data in this buffer after the endofresp line. */ + pp->nfinal = length; + if(Curl_dyn_len(&pp->recvbuf) > length) + pp->overflow = Curl_dyn_len(&pp->recvbuf) - length; + else + pp->overflow = 0; + *size = pp->nread_resp; /* size of the response */ + pp->nread_resp = 0; /* restart */ + gotbytes = 0; /* force break out of outer loop */ + break; + } if(Curl_dyn_len(&pp->recvbuf) > length) - pp->overflow = Curl_dyn_len(&pp->recvbuf) - length; + /* keep the remaining piece */ + Curl_dyn_tail((&pp->recvbuf), Curl_dyn_len(&pp->recvbuf) - length); else - pp->overflow = 0; - *size = pp->nread_resp; /* size of the response */ - pp->nread_resp = 0; /* restart */ + Curl_dyn_reset(&pp->recvbuf); + } + else { + /* without a newline, there is no overflow */ + pp->overflow = 0; break; } - if(Curl_dyn_len(&pp->recvbuf) > length) - /* keep the remaining piece */ - Curl_dyn_tail((&pp->recvbuf), Curl_dyn_len(&pp->recvbuf) - length); - else - Curl_dyn_reset(&pp->recvbuf); - } - else { - /* without a newline, there is no overflow */ - pp->overflow = 0; - break; - } - } while(1); /* while there is buffer left to scan */ + } while(1); /* while there is buffer left to scan */ + + } while(gotbytes == sizeof(buffer)); pp->pending_resp = FALSE; @@ -394,6 +400,13 @@ int Curl_pp_getsock(struct Curl_easy *data, return GETSOCK_READSOCK(0); } +bool Curl_pp_needs_flush(struct Curl_easy *data, + struct pingpong *pp) +{ + (void)data; + return pp->sendleft > 0; +} + CURLcode Curl_pp_flushsend(struct Curl_easy *data, struct pingpong *pp) { @@ -401,9 +414,12 @@ CURLcode Curl_pp_flushsend(struct Curl_easy *data, size_t written; CURLcode result; + if(!Curl_pp_needs_flush(data, pp)) + return CURLE_OK; + result = Curl_conn_send(data, FIRSTSOCKET, pp->sendthis + pp->sendsize - pp->sendleft, - pp->sendleft, &written); + pp->sendleft, FALSE, &written); if(result == CURLE_AGAIN) { result = CURLE_OK; written = 0; diff --git a/lib/pingpong.h b/lib/pingpong.h index 62f2467fc..72239ff05 100644 --- a/lib/pingpong.h +++ b/lib/pingpong.h @@ -137,6 +137,8 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, int *code, /* return the server code if done */ size_t *size); /* size of the response */ +bool Curl_pp_needs_flush(struct Curl_easy *data, + struct pingpong *pp); CURLcode Curl_pp_flushsend(struct Curl_easy *data, struct pingpong *pp); diff --git a/lib/pop3.c b/lib/pop3.c index 4cf1782ac..1f5334d91 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -83,6 +83,10 @@ #include "curl_memory.h" #include "memdebug.h" +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + /* Local API functions */ static CURLcode pop3_regular_transfer(struct Curl_easy *data, bool *done); static CURLcode pop3_do(struct Curl_easy *data, bool *done); @@ -107,6 +111,11 @@ static CURLcode pop3_continue_auth(struct Curl_easy *data, const char *mech, static CURLcode pop3_cancel_auth(struct Curl_easy *data, const char *mech); static CURLcode pop3_get_message(struct Curl_easy *data, struct bufref *out); +/* This function scans the body after the end-of-body and writes everything + * until the end is found */ +static CURLcode pop3_write(struct Curl_easy *data, + const char *str, size_t nread, bool is_eos); + /* * POP3 protocol handler. */ @@ -125,7 +134,7 @@ const struct Curl_handler Curl_handler_pop3 = { ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ pop3_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ + pop3_write, /* write_resp */ ZERO_NULL, /* write_resp_hd */ ZERO_NULL, /* connection_check */ ZERO_NULL, /* attach connection */ @@ -155,7 +164,7 @@ const struct Curl_handler Curl_handler_pop3s = { ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ pop3_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ + pop3_write, /* write_resp */ ZERO_NULL, /* write_resp_hd */ ZERO_NULL, /* connection_check */ ZERO_NULL, /* attach connection */ @@ -194,6 +203,53 @@ static void pop3_to_pop3s(struct connectdata *conn) #define pop3_to_pop3s(x) Curl_nop_stmt #endif +struct pop3_cmd { + const char *name; + unsigned short nlen; + BIT(multiline); /* response is multi-line with last '.' line */ + BIT(multiline_with_args); /* is multi-line when command has args */ +}; + +static const struct pop3_cmd pop3cmds[] = { + { "APOP", 4, FALSE, FALSE }, + { "AUTH", 4, FALSE, FALSE }, + { "CAPA", 4, TRUE, TRUE }, + { "DELE", 4, FALSE, FALSE }, + { "LIST", 4, TRUE, FALSE }, + { "MSG", 3, TRUE, TRUE }, + { "NOOP", 4, FALSE, FALSE }, + { "PASS", 4, FALSE, FALSE }, + { "QUIT", 4, FALSE, FALSE }, + { "RETR", 4, TRUE, TRUE }, + { "RSET", 4, FALSE, FALSE }, + { "STAT", 4, FALSE, FALSE }, + { "STLS", 4, FALSE, FALSE }, + { "TOP", 3, TRUE, TRUE }, + { "UIDL", 4, TRUE, FALSE }, + { "USER", 4, FALSE, FALSE }, + { "UTF8", 4, FALSE, FALSE }, + { "XTND", 4, TRUE, TRUE }, +}; + +/* Return iff a command is defined as "multi-line" (RFC 1939), + * has a response terminated by a last line with a '.'. + */ +static bool pop3_is_multiline(const char *cmdline) +{ + size_t i; + for(i = 0; i < ARRAYSIZE(pop3cmds); ++i) { + if(strncasecompare(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) { + if(!cmdline[pop3cmds[i].nlen]) + return pop3cmds[i].multiline; + else if(cmdline[pop3cmds[i].nlen] == ' ') + return pop3cmds[i].multiline_with_args; + } + } + /* Unknown command, assume multi-line for backward compatibility with + * earlier curl versions that only could do multi-line responses. */ + return TRUE; +} + /*********************************************************************** * * pop3_endofresp() @@ -609,18 +665,20 @@ static CURLcode pop3_perform_command(struct Curl_easy *data) else command = "RETR"; + if(pop3->custom && pop3->custom[0] != '\0') + command = pop3->custom; + /* Send the command */ if(pop3->id[0] != '\0') result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s %s", - (pop3->custom && pop3->custom[0] != '\0' ? - pop3->custom : command), pop3->id); + command, pop3->id); else - result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", - (pop3->custom && pop3->custom[0] != '\0' ? - pop3->custom : command)); + result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", command); - if(!result) + if(!result) { pop3_state(data, POP3_COMMAND); + data->req.no_body = !pop3_is_multiline(command); + } return result; } @@ -948,8 +1006,8 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data, pp->nfinal = 0; /* done */ if(!data->req.no_body) { - result = Curl_pop3_write(data, Curl_dyn_ptr(&pp->recvbuf), - Curl_dyn_len(&pp->recvbuf)); + result = pop3_write(data, Curl_dyn_ptr(&pp->recvbuf), + Curl_dyn_len(&pp->recvbuf), FALSE); if(result) return result; } @@ -1447,12 +1505,13 @@ static CURLcode pop3_parse_custom_request(struct Curl_easy *data) /*********************************************************************** * - * Curl_pop3_write() + * pop3_write() * * This function scans the body after the end-of-body and writes everything * until the end is found. */ -CURLcode Curl_pop3_write(struct Curl_easy *data, const char *str, size_t nread) +static CURLcode pop3_write(struct Curl_easy *data, const char *str, + size_t nread, bool is_eos) { /* This code could be made into a special function in the handler struct */ CURLcode result = CURLE_OK; @@ -1462,6 +1521,7 @@ CURLcode Curl_pop3_write(struct Curl_easy *data, const char *str, size_t nread) bool strip_dot = FALSE; size_t last = 0; size_t i; + (void)is_eos; /* Search through the buffer looking for the end-of-body marker which is 5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches diff --git a/lib/pop3.h b/lib/pop3.h index e8e98db04..3d08dafa1 100644 --- a/lib/pop3.h +++ b/lib/pop3.h @@ -90,9 +90,4 @@ extern const struct Curl_handler Curl_handler_pop3s; #define POP3_EOB "\x0d\x0a\x2e\x0d\x0a" #define POP3_EOB_LEN 5 -/* This function scans the body after the end-of-body and writes everything - * until the end is found */ -CURLcode Curl_pop3_write(struct Curl_easy *data, - const char *str, size_t nread); - #endif /* HEADER_CURL_POP3_H */ diff --git a/lib/progress.c b/lib/progress.c index 34c29a270..cb9829c31 100644 --- a/lib/progress.c +++ b/lib/progress.c @@ -48,8 +48,7 @@ static void time2str(char *r, curl_off_t seconds) if(h <= CURL_OFF_T_C(99)) { curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60); curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60)); - msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T - ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s); + msnprintf(r, 9, "%2" FMT_OFF_T ":%02" FMT_OFF_T ":%02" FMT_OFF_T, h, m, s); } else { /* this equals to more than 99 hours, switch to a more suitable output @@ -57,10 +56,9 @@ static void time2str(char *r, curl_off_t seconds) curl_off_t d = seconds / CURL_OFF_T_C(86400); h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600); if(d <= CURL_OFF_T_C(999)) - msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T - "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h); + msnprintf(r, 9, "%3" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h); else - msnprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d); + msnprintf(r, 9, "%7" FMT_OFF_T "d", d); } } @@ -76,38 +74,38 @@ static char *max5data(curl_off_t bytes, char *max5) #define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE) if(bytes < CURL_OFF_T_C(100000)) - msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes); + msnprintf(max5, 6, "%5" FMT_OFF_T, bytes); else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE) - msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE); + msnprintf(max5, 6, "%4" FMT_OFF_T "k", bytes/ONE_KILOBYTE); else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) /* 'XX.XM' is good as long as we are less than 100 megs */ - msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" - CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, + msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" + FMT_OFF_T "M", bytes/ONE_MEGABYTE, (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) /* 'XXXXM' is good until we are at 10000MB or above */ - msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); + msnprintf(max5, 6, "%4" FMT_OFF_T "M", bytes/ONE_MEGABYTE); else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) /* 10000 MB - 100 GB, we show it as XX.XG */ - msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" - CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE, + msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" + FMT_OFF_T "G", bytes/ONE_GIGABYTE, (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) ); else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE) /* up to 10000GB, display without decimal: XXXXG */ - msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE); + msnprintf(max5, 6, "%4" FMT_OFF_T "G", bytes/ONE_GIGABYTE); else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE) /* up to 10000TB, display without decimal: XXXXT */ - msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE); + msnprintf(max5, 6, "%4" FMT_OFF_T "T", bytes/ONE_TERABYTE); else /* up to 10000PB, display without decimal: XXXXP */ - msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE); + msnprintf(max5, 6, "%4" FMT_OFF_T "P", bytes/ONE_PETABYTE); /* 16384 petabytes (16 exabytes) is the maximum a 64-bit unsigned number can hold, but our data type is signed so 8192PB will be the maximum. */ @@ -217,7 +215,7 @@ void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer, break; } case TIMER_POSTRANSFER: - /* this is the normal end-of-transfer thing */ + delta = &data->progress.t_posttransfer; break; case TIMER_REDIRECT: data->progress.t_redirect = Curl_timediff_us(timestamp, @@ -252,12 +250,12 @@ void Curl_pgrsStartNow(struct Curl_easy *data) data->progress.speeder_c = 0; /* reset the progress meter display */ data->progress.start = Curl_now(); data->progress.is_t_startransfer_set = false; - data->progress.ul_limit_start = data->progress.start; - data->progress.dl_limit_start = data->progress.start; - data->progress.ul_limit_size = 0; - data->progress.dl_limit_size = 0; - data->progress.downloaded = 0; - data->progress.uploaded = 0; + data->progress.ul.limit.start = data->progress.start; + data->progress.dl.limit.start = data->progress.start; + data->progress.ul.limit.start_size = 0; + data->progress.dl.limit.start_size = 0; + data->progress.dl.cur_size = 0; + data->progress.ul.cur_size = 0; /* clear all bits except HIDE and HEADERS_OUT */ data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT; Curl_ratelimit(data, data->progress.start); @@ -281,17 +279,15 @@ void Curl_pgrsStartNow(struct Curl_easy *data) * starting point should be reset (to current); or the number of milliseconds * to wait to get back under the speed limit. */ -timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, - curl_off_t startsize, - curl_off_t limit, - struct curltime start, +timediff_t Curl_pgrsLimitWaitTime(struct pgrs_dir *d, + curl_off_t speed_limit, struct curltime now) { - curl_off_t size = cursize - startsize; + curl_off_t size = d->cur_size - d->limit.start_size; timediff_t minimum; timediff_t actual; - if(!limit || !size) + if(!speed_limit || !size) return 0; /* @@ -299,9 +295,9 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, * stay below 'limit'. */ if(size < CURL_OFF_T_MAX/1000) - minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / limit); + minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / speed_limit); else { - minimum = (timediff_t) (size / limit); + minimum = (timediff_t) (size / speed_limit); if(minimum < TIMEDIFF_T_MAX/1000) minimum *= 1000; else @@ -312,7 +308,7 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, * 'actual' is the time in milliseconds it took to actually download the * last 'size' bytes. */ - actual = Curl_timediff_ceil(now, start); + actual = Curl_timediff_ceil(now, d->limit.start); if(actual < minimum) { /* if it downloaded the data faster than the limit, make it wait the difference */ @@ -327,7 +323,7 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, */ CURLcode Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size) { - data->progress.downloaded = size; + data->progress.dl.cur_size = size; return CURLE_OK; } @@ -338,17 +334,17 @@ void Curl_ratelimit(struct Curl_easy *data, struct curltime now) { /* do not set a new stamp unless the time since last update is long enough */ if(data->set.max_recv_speed) { - if(Curl_timediff(now, data->progress.dl_limit_start) >= + if(Curl_timediff(now, data->progress.dl.limit.start) >= MIN_RATE_LIMIT_PERIOD) { - data->progress.dl_limit_start = now; - data->progress.dl_limit_size = data->progress.downloaded; + data->progress.dl.limit.start = now; + data->progress.dl.limit.start_size = data->progress.dl.cur_size; } } if(data->set.max_send_speed) { - if(Curl_timediff(now, data->progress.ul_limit_start) >= + if(Curl_timediff(now, data->progress.ul.limit.start) >= MIN_RATE_LIMIT_PERIOD) { - data->progress.ul_limit_start = now; - data->progress.ul_limit_size = data->progress.uploaded; + data->progress.ul.limit.start = now; + data->progress.ul.limit.start_size = data->progress.ul.cur_size; } } } @@ -358,17 +354,17 @@ void Curl_ratelimit(struct Curl_easy *data, struct curltime now) */ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size) { - data->progress.uploaded = size; + data->progress.ul.cur_size = size; } void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size) { if(size >= 0) { - data->progress.size_dl = size; + data->progress.dl.total_size = size; data->progress.flags |= PGRS_DL_SIZE_KNOWN; } else { - data->progress.size_dl = 0; + data->progress.dl.total_size = 0; data->progress.flags &= ~PGRS_DL_SIZE_KNOWN; } } @@ -376,11 +372,11 @@ void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size) void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) { if(size >= 0) { - data->progress.size_ul = size; + data->progress.ul.total_size = size; data->progress.flags |= PGRS_UL_SIZE_KNOWN; } else { - data->progress.size_ul = 0; + data->progress.ul.total_size = 0; data->progress.flags &= ~PGRS_UL_SIZE_KNOWN; } } @@ -407,8 +403,8 @@ static bool progress_calc(struct Curl_easy *data, struct curltime now) /* The time spent so far (from the start) in microseconds */ p->timespent = Curl_timediff_us(now, p->start); - p->dlspeed = trspeed(p->downloaded, p->timespent); - p->ulspeed = trspeed(p->uploaded, p->timespent); + p->dl.speed = trspeed(p->dl.cur_size, p->timespent); + p->ul.speed = trspeed(p->ul.cur_size, p->timespent); /* Calculations done at most once a second, unless end is reached */ if(p->lastshow != now.tv_sec) { @@ -419,7 +415,7 @@ static bool progress_calc(struct Curl_easy *data, struct curltime now) /* Let's do the "current speed" thing, with the dl + ul speeds combined. Store the speed at entry 'nowindex'. */ - p->speeder[ nowindex ] = p->downloaded + p->uploaded; + p->speeder[ nowindex ] = p->dl.cur_size + p->ul.cur_size; /* remember the exact time for this moment */ p->speeder_time [ nowindex ] = now; @@ -465,113 +461,107 @@ static bool progress_calc(struct Curl_easy *data, struct curltime now) } else /* the first second we use the average */ - p->current_speed = p->ulspeed + p->dlspeed; + p->current_speed = p->ul.speed + p->dl.speed; } /* Calculations end */ return timetoshow; } #ifndef CURL_DISABLE_PROGRESS_METER + +struct pgrs_estimate { + curl_off_t secs; + curl_off_t percent; +}; + +static curl_off_t pgrs_est_percent(curl_off_t total, curl_off_t cur) +{ + if(total > CURL_OFF_T_C(10000)) + return cur / (total/CURL_OFF_T_C(100)); + else if(total > CURL_OFF_T_C(0)) + return (cur*100) / total; + return 0; +} + +static void pgrs_estimates(struct pgrs_dir *d, + bool total_known, + struct pgrs_estimate *est) +{ + est->secs = 0; + est->percent = 0; + if(total_known && (d->speed > CURL_OFF_T_C(0))) { + est->secs = d->total_size / d->speed; + est->percent = pgrs_est_percent(d->total_size, d->cur_size); + } +} + static void progress_meter(struct Curl_easy *data) { + struct Progress *p = &data->progress; char max5[6][10]; - curl_off_t dlpercen = 0; - curl_off_t ulpercen = 0; - curl_off_t total_percen = 0; - curl_off_t total_transfer; - curl_off_t total_expected_transfer; + struct pgrs_estimate dl_estm; + struct pgrs_estimate ul_estm; + struct pgrs_estimate total_estm; + curl_off_t total_cur_size; + curl_off_t total_expected_size; char time_left[10]; char time_total[10]; char time_spent[10]; - curl_off_t ulestimate = 0; - curl_off_t dlestimate = 0; - curl_off_t total_estimate; - curl_off_t timespent = - (curl_off_t)data->progress.timespent/1000000; /* seconds */ + curl_off_t cur_secs = (curl_off_t)p->timespent/1000000; /* seconds */ - if(!(data->progress.flags & PGRS_HEADERS_OUT)) { + if(!(p->flags & PGRS_HEADERS_OUT)) { if(data->state.resume_from) { fprintf(data->set.err, - "** Resuming transfer from byte position %" - CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + "** Resuming transfer from byte position %" FMT_OFF_T "\n", + data->state.resume_from); } fprintf(data->set.err, " %% Total %% Received %% Xferd Average Speed " "Time Time Time Current\n" " Dload Upload " "Total Spent Left Speed\n"); - data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ - } - - /* Figure out the estimated time of arrival for the upload */ - if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && - (data->progress.ulspeed > CURL_OFF_T_C(0))) { - ulestimate = data->progress.size_ul / data->progress.ulspeed; - - if(data->progress.size_ul > CURL_OFF_T_C(10000)) - ulpercen = data->progress.uploaded / - (data->progress.size_ul/CURL_OFF_T_C(100)); - else if(data->progress.size_ul > CURL_OFF_T_C(0)) - ulpercen = (data->progress.uploaded*100) / - data->progress.size_ul; - } - - /* ... and the download */ - if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && - (data->progress.dlspeed > CURL_OFF_T_C(0))) { - dlestimate = data->progress.size_dl / data->progress.dlspeed; - - if(data->progress.size_dl > CURL_OFF_T_C(10000)) - dlpercen = data->progress.downloaded / - (data->progress.size_dl/CURL_OFF_T_C(100)); - else if(data->progress.size_dl > CURL_OFF_T_C(0)) - dlpercen = (data->progress.downloaded*100) / - data->progress.size_dl; + p->flags |= PGRS_HEADERS_OUT; /* headers are shown */ } - /* Now figure out which of them is slower and use that one for the - total estimate! */ - total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; + /* Figure out the estimated time of arrival for upload and download */ + pgrs_estimates(&p->ul, (p->flags & PGRS_UL_SIZE_KNOWN), &ul_estm); + pgrs_estimates(&p->dl, (p->flags & PGRS_DL_SIZE_KNOWN), &dl_estm); + /* Since both happen at the same time, total expected duration is max. */ + total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs); /* create the three time strings */ - time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); - time2str(time_total, total_estimate); - time2str(time_spent, timespent); + time2str(time_left, total_estm.secs > 0?(total_estm.secs - cur_secs):0); + time2str(time_total, total_estm.secs); + time2str(time_spent, cur_secs); /* Get the total amount of data expected to get transferred */ - total_expected_transfer = - ((data->progress.flags & PGRS_UL_SIZE_KNOWN)? - data->progress.size_ul:data->progress.uploaded)+ - ((data->progress.flags & PGRS_DL_SIZE_KNOWN)? - data->progress.size_dl:data->progress.downloaded); + total_expected_size = + ((p->flags & PGRS_UL_SIZE_KNOWN)? p->ul.total_size:p->ul.cur_size) + + ((p->flags & PGRS_DL_SIZE_KNOWN)? p->dl.total_size:p->dl.cur_size); /* We have transferred this much so far */ - total_transfer = data->progress.downloaded + data->progress.uploaded; + total_cur_size = p->dl.cur_size + p->ul.cur_size; /* Get the percentage of data transferred so far */ - if(total_expected_transfer > CURL_OFF_T_C(10000)) - total_percen = total_transfer / - (total_expected_transfer/CURL_OFF_T_C(100)); - else if(total_expected_transfer > CURL_OFF_T_C(0)) - total_percen = (total_transfer*100) / total_expected_transfer; + total_estm.percent = pgrs_est_percent(total_expected_size, total_cur_size); fprintf(data->set.err, "\r" - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s", - total_percen, /* 3 letters */ /* total % */ - max5data(total_expected_transfer, max5[2]), /* total size */ - dlpercen, /* 3 letters */ /* rcvd % */ - max5data(data->progress.downloaded, max5[0]), /* rcvd size */ - ulpercen, /* 3 letters */ /* xfer % */ - max5data(data->progress.uploaded, max5[1]), /* xfer size */ - max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ - max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ + "%3" FMT_OFF_T " %s " + "%3" FMT_OFF_T " %s " + "%3" FMT_OFF_T " %s %s %s %s %s %s %s", + total_estm.percent, /* 3 letters */ /* total % */ + max5data(total_expected_size, max5[2]), /* total size */ + dl_estm.percent, /* 3 letters */ /* rcvd % */ + max5data(p->dl.cur_size, max5[0]), /* rcvd size */ + ul_estm.percent, /* 3 letters */ /* xfer % */ + max5data(p->ul.cur_size, max5[1]), /* xfer size */ + max5data(p->dl.speed, max5[3]), /* avrg dl speed */ + max5data(p->ul.speed, max5[4]), /* avrg ul speed */ time_total, /* 8 letters */ /* total time */ time_spent, /* 8 letters */ /* time spent */ time_left, /* 8 letters */ /* time left */ - max5data(data->progress.current_speed, max5[5]) + max5data(p->current_speed, max5[5]) ); /* we flush the output stream to make it appear as soon as possible */ @@ -595,10 +585,10 @@ static int pgrsupdate(struct Curl_easy *data, bool showprogress) /* There is a callback set, call that */ Curl_set_in_callback(data, true); result = data->set.fxferinfo(data->set.progress_client, - data->progress.size_dl, - data->progress.downloaded, - data->progress.size_ul, - data->progress.uploaded); + data->progress.dl.total_size, + data->progress.dl.cur_size, + data->progress.ul.total_size, + data->progress.ul.cur_size); Curl_set_in_callback(data, false); if(result != CURL_PROGRESSFUNC_CONTINUE) { if(result) @@ -611,10 +601,10 @@ static int pgrsupdate(struct Curl_easy *data, bool showprogress) /* The older deprecated callback is set, call that */ Curl_set_in_callback(data, true); result = data->set.fprogress(data->set.progress_client, - (double)data->progress.size_dl, - (double)data->progress.downloaded, - (double)data->progress.size_ul, - (double)data->progress.uploaded); + (double)data->progress.dl.total_size, + (double)data->progress.dl.cur_size, + (double)data->progress.ul.total_size, + (double)data->progress.ul.cur_size); Curl_set_in_callback(data, false); if(result != CURL_PROGRESSFUNC_CONTINUE) { if(result) diff --git a/lib/progress.h b/lib/progress.h index 860257425..04a8f5bce 100644 --- a/lib/progress.h +++ b/lib/progress.h @@ -58,10 +58,8 @@ void Curl_pgrsUpdate_nometer(struct Curl_easy *data); void Curl_pgrsResetTransferSizes(struct Curl_easy *data); struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer); -timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, - curl_off_t startsize, - curl_off_t limit, - struct curltime start, +timediff_t Curl_pgrsLimitWaitTime(struct pgrs_dir *d, + curl_off_t speed_limit, struct curltime now); /** * Update progress timer with the elapsed time from its start to `timestamp`. diff --git a/lib/rand.c b/lib/rand.c index 4ee96fbb6..3c1b88db7 100644 --- a/lib/rand.c +++ b/lib/rand.c @@ -100,86 +100,91 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length) } #endif -static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) +#if !defined(USE_SSL) || defined(USE_RUSTLS) +/* ---- possibly non-cryptographic version following ---- */ +CURLcode Curl_weak_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length) /* always 4, size of int */ { - CURLcode result = CURLE_OK; - static unsigned int randseed; - static bool seeded = FALSE; - -#ifdef DEBUGBUILD - char *force_entropy = getenv("CURL_ENTROPY"); - if(force_entropy) { - if(!seeded) { - unsigned int seed = 0; - size_t elen = strlen(force_entropy); - size_t clen = sizeof(seed); - size_t min = elen < clen ? elen : clen; - memcpy((char *)&seed, force_entropy, min); - randseed = ntohl(seed); - seeded = TRUE; - } - else - randseed++; - *rnd = randseed; - return CURLE_OK; - } -#endif - - /* data may be NULL! */ - result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd)); - if(result != CURLE_NOT_BUILT_IN) - /* only if there is no random function in the TLS backend do the non crypto - version, otherwise return result */ - return result; - - /* ---- non-cryptographic version following ---- */ + unsigned int r; + DEBUGASSERT(length == sizeof(int)); + /* Trying cryptographically secure functions first */ #ifdef _WIN32 - if(!seeded) { - result = Curl_win32_random((unsigned char *)rnd, sizeof(*rnd)); + (void)data; + { + CURLcode result = Curl_win32_random(entropy, length); if(result != CURLE_NOT_BUILT_IN) return result; } #endif -#if defined(HAVE_ARC4RANDOM) && !defined(USE_OPENSSL) - if(!seeded) { - *rnd = (unsigned int)arc4random(); - return CURLE_OK; +#if defined(HAVE_ARC4RANDOM) + (void)data; + r = (unsigned int)arc4random(); + memcpy(entropy, &r, length); +#else + infof(data, "WARNING: using weak random seed"); + { + static unsigned int randseed; + static bool seeded = FALSE; + unsigned int rnd; + if(!seeded) { + struct curltime now = Curl_now(); + randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; + randseed = randseed * 1103515245 + 12345; + randseed = randseed * 1103515245 + 12345; + randseed = randseed * 1103515245 + 12345; + seeded = TRUE; + } + + /* Return an unsigned 32-bit pseudo-random number. */ + r = randseed = randseed * 1103515245 + 12345; + rnd = (r << 16) | ((r >> 16) & 0xFFFF); + memcpy(entropy, &rnd, length); } +#endif + return CURLE_OK; +} +#endif + +#ifdef USE_SSL +#define _random(x,y,z) Curl_ssl_random(x,y,z) +#else +#define _random(x,y,z) Curl_weak_random(x,y,z) #endif -#if defined(RANDOM_FILE) && !defined(_WIN32) - if(!seeded) { - /* if there is a random file to read a seed from, use it */ - int fd = open(RANDOM_FILE, O_RDONLY); - if(fd > -1) { - /* read random data into the randseed variable */ - ssize_t nread = read(fd, &randseed, sizeof(randseed)); - if(nread == sizeof(randseed)) +static CURLcode randit(struct Curl_easy *data, unsigned int *rnd, + bool env_override) +{ +#ifdef DEBUGBUILD + if(env_override) { + char *force_entropy = getenv("CURL_ENTROPY"); + if(force_entropy) { + static unsigned int randseed; + static bool seeded = FALSE; + + if(!seeded) { + unsigned int seed = 0; + size_t elen = strlen(force_entropy); + size_t clen = sizeof(seed); + size_t min = elen < clen ? elen : clen; + memcpy((char *)&seed, force_entropy, min); + randseed = ntohl(seed); seeded = TRUE; - close(fd); + } + else + randseed++; + *rnd = randseed; + return CURLE_OK; } } +#else + (void)env_override; #endif - if(!seeded) { - struct curltime now = Curl_now(); - infof(data, "WARNING: using weak random seed"); - randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - seeded = TRUE; - } - - { - unsigned int r; - /* Return an unsigned 32-bit pseudo-random number. */ - r = randseed = randseed * 1103515245 + 12345; - *rnd = (r << 16) | ((r >> 16) & 0xFFFF); - } - return CURLE_OK; + /* data may be NULL! */ + return _random(data, (unsigned char *)rnd, sizeof(*rnd)); } /* @@ -187,7 +192,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) * 'rnd' points to. * * If libcurl is built without TLS support or with a TLS backend that lacks a - * proper random API (rustls or mbedTLS), this function will use "weak" + * proper random API (Rustls or mbedTLS), this function will use "weak" * random. * * When built *with* TLS support and a backend that offers strong random, it @@ -198,9 +203,16 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) * */ -CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num) +CURLcode Curl_rand_bytes(struct Curl_easy *data, +#ifdef DEBUGBUILD + bool env_override, +#endif + unsigned char *rnd, size_t num) { CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; +#ifndef DEBUGBUILD + const bool env_override = FALSE; +#endif DEBUGASSERT(num); @@ -208,7 +220,7 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num) unsigned int r; size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int); - result = randit(data, &r); + result = randit(data, &r, env_override); if(result) return result; @@ -278,7 +290,7 @@ CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd, while(num) { do { - result = randit(data, &r); + result = randit(data, &r, TRUE); if(result) return result; } while(r >= (UINT_MAX - UINT_MAX % alnumspace)); diff --git a/lib/rand.h b/lib/rand.h index bc05239e4..7810a903a 100644 --- a/lib/rand.h +++ b/lib/rand.h @@ -24,7 +24,22 @@ * ***************************************************************************/ -CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num); +CURLcode Curl_rand_bytes(struct Curl_easy *data, +#ifdef DEBUGBUILD + bool allow_env_override, +#endif + unsigned char *rnd, size_t num); + +#ifdef DEBUGBUILD +#define Curl_rand(a,b,c) Curl_rand_bytes((a), TRUE, (b), (c)) +#else +#define Curl_rand(a,b,c) Curl_rand_bytes((a), (b), (c)) +#endif + +/* ---- non-cryptographic version following ---- */ +CURLcode Curl_weak_random(struct Curl_easy *data, + unsigned char *rnd, + size_t length); /* * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random diff --git a/lib/request.c b/lib/request.c index 5c8d52f69..fb75e5577 100644 --- a/lib/request.c +++ b/lib/request.c @@ -100,6 +100,9 @@ CURLcode Curl_req_done(struct SingleRequest *req, if(!aborted) (void)req_flush(data); Curl_client_reset(data); +#ifndef CURL_DISABLE_DOH + Curl_doh_close(data); +#endif return CURLE_OK; } @@ -179,18 +182,20 @@ static CURLcode xfer_send(struct Curl_easy *data, size_t hds_len, size_t *pnwritten) { CURLcode result = CURLE_OK; + bool eos = FALSE; *pnwritten = 0; + DEBUGASSERT(hds_len <= blen); #ifdef DEBUGBUILD { /* Allow debug builds to override this logic to force short initial - sends - */ + sends */ + size_t body_len = blen - hds_len; char *p = getenv("CURL_SMALLREQSEND"); if(p) { - size_t altsize = (size_t)strtoul(p, NULL, 10); - if(altsize && altsize < blen) - blen = altsize; + size_t body_small = (size_t)strtoul(p, NULL, 10); + if(body_small && body_small < body_len) + blen = hds_len + body_small; } } #endif @@ -202,7 +207,13 @@ static CURLcode xfer_send(struct Curl_easy *data, blen = hds_len + (size_t)data->set.max_send_speed; } - result = Curl_xfer_send(data, buf, blen, pnwritten); + if(data->req.eos_read && + (Curl_bufq_is_empty(&data->req.sendbuf) || + Curl_bufq_len(&data->req.sendbuf) == blen)) { + DEBUGF(infof(data, "sending last upload chunk of %zu bytes", blen)); + eos = TRUE; + } + result = Curl_xfer_send(data, buf, blen, eos, pnwritten); if(!result && *pnwritten) { if(hds_len) Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf, @@ -241,28 +252,32 @@ static CURLcode req_send_buffer_flush(struct Curl_easy *data) return result; } -static CURLcode req_set_upload_done(struct Curl_easy *data) +CURLcode Curl_req_set_upload_done(struct Curl_easy *data) { DEBUGASSERT(!data->req.upload_done); data->req.upload_done = TRUE; data->req.keepon &= ~(KEEP_SEND|KEEP_SEND_TIMED); /* we are done sending */ + Curl_pgrsTime(data, TIMER_POSTRANSFER); Curl_creader_done(data, data->req.upload_aborted); if(data->req.upload_aborted) { + Curl_bufq_reset(&data->req.sendbuf); if(data->req.writebytecount) - infof(data, "abort upload after having sent %" CURL_FORMAT_CURL_OFF_T - " bytes", data->req.writebytecount); + infof(data, "abort upload after having sent %" FMT_OFF_T " bytes", + data->req.writebytecount); else infof(data, "abort upload"); } else if(data->req.writebytecount) - infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T - " bytes", data->req.writebytecount); - else if(!data->req.download_done) + infof(data, "upload completely sent off: %" FMT_OFF_T " bytes", + data->req.writebytecount); + else if(!data->req.download_done) { + DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf)); infof(data, Curl_creader_total_length(data)? "We are completely uploaded and fine" : "Request completely sent off"); + } return Curl_xfer_send_close(data); } @@ -279,9 +294,15 @@ static CURLcode req_flush(struct Curl_easy *data) if(result) return result; if(!Curl_bufq_is_empty(&data->req.sendbuf)) { + DEBUGF(infof(data, "Curl_req_flush(len=%zu) -> EAGAIN", + Curl_bufq_len(&data->req.sendbuf))); return CURLE_AGAIN; } } + else if(Curl_xfer_needs_flush(data)) { + DEBUGF(infof(data, "Curl_req_flush(), xfer send_pending")); + return Curl_xfer_flush(data); + } if(!data->req.upload_done && data->req.eos_read && Curl_bufq_is_empty(&data->req.sendbuf)) { @@ -293,7 +314,7 @@ static CURLcode req_flush(struct Curl_easy *data) if(!done) return CURLE_AGAIN; } - return req_set_upload_done(data); + return Curl_req_set_upload_done(data); } return CURLE_OK; } @@ -367,18 +388,26 @@ CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *req) } #endif /* !USE_HYPER */ +bool Curl_req_sendbuf_empty(struct Curl_easy *data) +{ + return !data->req.sendbuf_init || Curl_bufq_is_empty(&data->req.sendbuf); +} + bool Curl_req_want_send(struct Curl_easy *data) { - return data->req.sendbuf_init && !Curl_bufq_is_empty(&data->req.sendbuf); + /* Not done and + * - KEEP_SEND and not PAUSEd. + * - or request has buffered data to send + * - or transfer connection has pending data to send */ + return !data->req.done && + (((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) || + !Curl_req_sendbuf_empty(data) || + Curl_xfer_needs_flush(data)); } bool Curl_req_done_sending(struct Curl_easy *data) { - if(data->req.upload_done) { - DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf)); - return TRUE; - } - return FALSE; + return data->req.upload_done && !Curl_req_want_send(data); } CURLcode Curl_req_send_more(struct Curl_easy *data) @@ -386,7 +415,10 @@ CURLcode Curl_req_send_more(struct Curl_easy *data) CURLcode result; /* Fill our send buffer if more from client can be read. */ - if(!data->req.eos_read && !Curl_bufq_is_full(&data->req.sendbuf)) { + if(!data->req.upload_aborted && + !data->req.eos_read && + !(data->req.keepon & KEEP_SEND_PAUSE) && + !Curl_bufq_is_full(&data->req.sendbuf)) { ssize_t nread = Curl_bufq_sipn(&data->req.sendbuf, 0, add_from_client, data, &result); if(nread < 0 && result != CURLE_AGAIN) @@ -405,7 +437,18 @@ CURLcode Curl_req_abort_sending(struct Curl_easy *data) if(!data->req.upload_done) { Curl_bufq_reset(&data->req.sendbuf); data->req.upload_aborted = TRUE; - return req_set_upload_done(data); + /* no longer KEEP_SEND and KEEP_SEND_PAUSE */ + data->req.keepon &= ~KEEP_SENDBITS; + return Curl_req_set_upload_done(data); } return CURLE_OK; } + +CURLcode Curl_req_stop_send_recv(struct Curl_easy *data) +{ + /* stop receiving and ALL sending as well, including PAUSE and HOLD. + * We might still be paused on receive client writes though, so + * keep those bits around. */ + data->req.keepon &= ~(KEEP_RECV|KEEP_SENDBITS); + return Curl_req_abort_sending(data); +} diff --git a/lib/request.h b/lib/request.h index 413dacaa4..fb3f9f116 100644 --- a/lib/request.h +++ b/lib/request.h @@ -32,6 +32,9 @@ /* forward declarations */ struct UserDefined; +#ifndef CURL_DISABLE_DOH +struct doh_probes; +#endif enum expect100 { EXP100_SEND_DATA, /* enough waiting, just send the body now */ @@ -114,7 +117,7 @@ struct SingleRequest { struct TELNET *telnet; } p; #ifndef CURL_DISABLE_DOH - struct dohdata *doh; /* DoH specific data for this request */ + struct doh_probes *doh; /* DoH specific data for this request */ #endif #ifndef CURL_DISABLE_COOKIES unsigned char setcookies; @@ -135,6 +138,7 @@ struct SingleRequest { BIT(http_bodyless); /* HTTP response status code is between 100 and 199, 204 or 304 */ BIT(chunk); /* if set, this is a chunked transfer-encoding */ + BIT(resp_trailer); /* response carried 'Trailer:' header field */ BIT(ignore_cl); /* ignore content-length */ BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding on upload */ @@ -220,10 +224,26 @@ CURLcode Curl_req_send_more(struct Curl_easy *data); */ bool Curl_req_want_send(struct Curl_easy *data); +/** + * TRUE iff the request has no buffered bytes yet to send. + */ +bool Curl_req_sendbuf_empty(struct Curl_easy *data); + /** * Stop sending any more request data to the server. * Will clear the send buffer and mark request sending as done. */ CURLcode Curl_req_abort_sending(struct Curl_easy *data); +/** + * Stop sending and receiving any more request data. + * Will abort sending if not done. + */ +CURLcode Curl_req_stop_send_recv(struct Curl_easy *data); + +/** + * Invoked when all request data has been uploaded. + */ +CURLcode Curl_req_set_upload_done(struct Curl_easy *data); + #endif /* HEADER_CURL_REQUEST_H */ diff --git a/lib/rtsp.c b/lib/rtsp.c index a9050806d..c9b1bc0d6 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -533,8 +533,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) * actually set a custom Content-Length in the headers */ if(!Curl_checkheaders(data, STRCONST("Content-Length"))) { result = - Curl_dyn_addf(&req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", + Curl_dyn_addf(&req_buffer, "Content-Length: %" FMT_OFF_T"\r\n", req_clen); if(result) goto out; @@ -854,7 +853,7 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, * In which case we write out the left over bytes, letting the client * writer deal with it (it will report EXCESS and fail the transfer). */ DEBUGF(infof(data, "rtsp_rtp_write_resp(len=%zu, in_header=%d, done=%d " - " rtspc->state=%d, req.size=%" CURL_FORMAT_CURL_OFF_T ")", + " rtspc->state=%d, req.size=%" FMT_OFF_T ")", blen, rtspc->in_header, data->req.done, rtspc->state, data->req.size)); if(!result && (is_eos || blen)) { diff --git a/lib/select.c b/lib/select.c index 96b0632ff..dae736b01 100644 --- a/lib/select.c +++ b/lib/select.c @@ -56,7 +56,7 @@ * Internal function used for waiting a specific amount of ms * in Curl_socket_check() and Curl_poll() when no file descriptor * is provided to wait on, just being used to delay execution. - * WinSock select() and poll() timeout mechanisms need a valid + * Winsock select() and poll() timeout mechanisms need a valid * socket descriptor in a not null file descriptor set to work. * Waiting indefinitely with this function is not allowed, a * zero or negative timeout value will return immediately. @@ -135,7 +135,7 @@ static int our_select(curl_socket_t maxfd, /* highest socket number */ struct timeval *ptimeout; #ifdef USE_WINSOCK - /* WinSock select() cannot handle zero events. See the comment below. */ + /* Winsock select() cannot handle zero events. See the comment below. */ if((!fds_read || fds_read->fd_count == 0) && (!fds_write || fds_write->fd_count == 0) && (!fds_err || fds_err->fd_count == 0)) { @@ -147,7 +147,7 @@ static int our_select(curl_socket_t maxfd, /* highest socket number */ ptimeout = curlx_mstotv(&pending_tv, timeout_ms); #ifdef USE_WINSOCK - /* WinSock select() must not be called with an fd_set that contains zero + /* Winsock select() must not be called with an fd_set that contains zero fd flags, or it will return WSAEINVAL. But, it also cannot be called with no fd_sets at all! From the documentation: @@ -155,8 +155,8 @@ static int our_select(curl_socket_t maxfd, /* highest socket number */ given as null. At least one must be non-null, and any non-null descriptor set must contain at least one handle to a socket. - It is unclear why WinSock does not just handle this for us instead of - calling this an error. Luckily, with WinSock, we can _also_ ask how + It is unclear why Winsock does not just handle this for us instead of + calling this an error. Luckily, with Winsock, we can _also_ ask how many bits are set on an fd_set. So, let's just check it beforehand. */ return select((int)maxfd + 1, @@ -361,8 +361,8 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) } /* - Note also that WinSock ignores the first argument, so we do not worry - about the fact that maxfd is computed incorrectly with WinSock (since + Note also that Winsock ignores the first argument, so we do not worry + about the fact that maxfd is computed incorrectly with Winsock (since curl_socket_t is unsigned in such cases and thus -1 is the largest value). */ diff --git a/lib/sendf.c b/lib/sendf.c index 24b90d2ad..791dff220 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -292,8 +292,8 @@ static CURLcode cw_download_write(struct Curl_easy *data, if((type & CLIENTWRITE_EOS) && !data->req.no_body && (data->req.maxdownload > data->req.bytecount)) { - failf(data, "end of response with %" CURL_FORMAT_CURL_OFF_T - " bytes missing", data->req.maxdownload - data->req.bytecount); + failf(data, "end of response with %" FMT_OFF_T " bytes missing", + data->req.maxdownload - data->req.bytecount); return CURLE_PARTIAL_FILE; } } @@ -328,9 +328,9 @@ static CURLcode cw_download_write(struct Curl_easy *data, infof(data, "Excess found writing body:" " excess = %zu" - ", size = %" CURL_FORMAT_CURL_OFF_T - ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T, + ", size = %" FMT_OFF_T + ", maxdownload = %" FMT_OFF_T + ", bytecount = %" FMT_OFF_T, excess_len, data->req.size, data->req.maxdownload, data->req.bytecount); connclose(data->conn, "excess found in a read"); @@ -338,8 +338,7 @@ static CURLcode cw_download_write(struct Curl_easy *data, } else if(nwrite < nbytes) { failf(data, "Exceeded the maximum allowed file size " - "(%" CURL_FORMAT_CURL_OFF_T ") with %" - CURL_FORMAT_CURL_OFF_T " bytes", + "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes", data->set.max_filesize, data->req.bytecount); return CURLE_FILESIZE_EXCEEDED; } @@ -688,8 +687,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, case 0: if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { failf(data, "client read function EOF fail, " - "only %"CURL_FORMAT_CURL_OFF_T"/%"CURL_FORMAT_CURL_OFF_T - " of needed bytes read", ctx->read_len, ctx->total_len); + "only %"FMT_OFF_T"/%"FMT_OFF_T " of needed bytes read", + ctx->read_len, ctx->total_len); return CURLE_READ_ERROR; } *pnread = 0; @@ -738,8 +737,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, *peos = ctx->seen_eos; break; } - CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%"CURL_FORMAT_CURL_OFF_T - ", read=%"CURL_FORMAT_CURL_OFF_T") -> %d, nread=%zu, eos=%d", + CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%"FMT_OFF_T + ", read=%"FMT_OFF_T") -> %d, nread=%zu, eos=%d", blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos); return CURLE_OK; @@ -804,8 +803,8 @@ static CURLcode cr_in_resume_from(struct Curl_easy *data, if((actuallyread == 0) || (actuallyread > readthisamountnow)) { /* this checks for greater-than only to make sure that the CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T - " bytes from the input", passed); + failf(data, "Could only read %" FMT_OFF_T " bytes from the input", + passed); return CURLE_READ_ERROR; } } while(passed < offset); @@ -1102,11 +1101,7 @@ static CURLcode do_init_reader_stack(struct Curl_easy *data, clen = r->crt->total_length(data, r); /* if we do not have 0 length init, and crlf conversion is wanted, * add the reader for it */ - if(clen && (data->set.crlf -#ifdef CURL_DO_LINEEND_CONV - || data->state.prefer_ascii -#endif - )) { + if(clen && (data->set.crlf || data->state.prefer_ascii)) { result = cr_lc_add(data); if(result) return result; @@ -1130,8 +1125,8 @@ CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len) cl_reset_reader(data); result = do_init_reader_stack(data, r); out: - CURL_TRC_READ(data, "add fread reader, len=%"CURL_FORMAT_CURL_OFF_T - " -> %d", len, result); + CURL_TRC_READ(data, "add fread reader, len=%"FMT_OFF_T " -> %d", + len, result); return result; } diff --git a/lib/setopt.c b/lib/setopt.c index 7d35651d1..2e76ec8c1 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -139,30 +139,24 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) return CURLE_OK; } -static CURLcode setstropt_interface( - char *option, char **devp, char **ifacep, char **hostp) +static CURLcode setstropt_interface(char *option, char **devp, + char **ifacep, char **hostp) { char *dev = NULL; char *iface = NULL; char *host = NULL; - size_t len; CURLcode result; DEBUGASSERT(devp); DEBUGASSERT(ifacep); DEBUGASSERT(hostp); - /* Parse the interface details */ - if(!option || !*option) - return CURLE_BAD_FUNCTION_ARGUMENT; - len = strlen(option); - if(len > 255) - return CURLE_BAD_FUNCTION_ARGUMENT; - - result = Curl_parse_interface(option, len, &dev, &iface, &host); - if(result) - return result; - + if(option) { + /* Parse the interface details if set, otherwise clear them all */ + result = Curl_parse_interface(option, &dev, &iface, &host); + if(result) + return result; + } free(*devp); *devp = dev; @@ -255,15 +249,23 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* deprecated */ break; case CURLOPT_SSL_CIPHER_LIST: - /* set a list of cipher we want to use in the SSL connection */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], - va_arg(param, char *)); + if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) { + /* set a list of cipher we want to use in the SSL connection */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], + va_arg(param, char *)); + } + else + return CURLE_NOT_BUILT_IN; break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_CIPHER_LIST: - /* set a list of cipher we want to use in the SSL connection for proxy */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], - va_arg(param, char *)); + if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) { + /* set a list of cipher we want to use in the SSL connection for proxy */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], + va_arg(param, char *)); + } + else + return CURLE_NOT_BUILT_IN; break; #endif case CURLOPT_TLS13_CIPHERS: @@ -423,8 +425,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * TFTP option that specifies the block size to use for data transmission. */ arg = va_arg(param, long); - if(arg > TFTP_BLKSIZE_MAX || arg < TFTP_BLKSIZE_MIN) - return CURLE_BAD_FUNCTION_ARGUMENT; + if(arg < TFTP_BLKSIZE_MIN) + arg = 512; + else if(arg > TFTP_BLKSIZE_MAX) + arg = TFTP_BLKSIZE_MAX; data->set.tftp_blksize = arg; break; #endif @@ -2165,7 +2169,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) - /* This does not work on windows. */ + /* This does not work on Windows. */ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], va_arg(param, char *)); else @@ -2180,7 +2184,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) - /* This does not work on windows. */ + /* This does not work on Windows. */ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], va_arg(param, char *)); else @@ -2696,17 +2700,27 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_PROTOCOLS_STR: { argptr = va_arg(param, char *); - result = protocol2num(argptr, &data->set.allowed_protocols); - if(result) - return result; + if(argptr) { + result = protocol2num(argptr, &data->set.allowed_protocols); + if(result) + return result; + } + else + /* make a NULL argument reset to default */ + data->set.allowed_protocols = (curl_prot_t) CURLPROTO_ALL; break; } case CURLOPT_REDIR_PROTOCOLS_STR: { argptr = va_arg(param, char *); - result = protocol2num(argptr, &data->set.redir_protocols); - if(result) - return result; + if(argptr) { + result = protocol2num(argptr, &data->set.redir_protocols); + if(result) + return result; + } + else + /* make a NULL argument reset to default */ + data->set.redir_protocols = (curl_prot_t) CURLPROTO_REDIR; break; } @@ -3186,8 +3200,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) argptr = va_arg(param, char *); if(!argptr) { data->set.tls_ech = CURLECH_DISABLE; - result = CURLE_BAD_FUNCTION_ARGUMENT; - return result; + return CURLE_OK; } plen = strlen(argptr); if(plen > CURL_MAX_INPUT_LENGTH) { diff --git a/lib/setup-vms.h b/lib/setup-vms.h index fc2156028..33b74db35 100644 --- a/lib/setup-vms.h +++ b/lib/setup-vms.h @@ -101,7 +101,7 @@ static char *vms_translate_path(const char *path) } } # else - /* VMS translate path is actually not needed on the current 64 bit */ + /* VMS translate path is actually not needed on the current 64-bit */ /* VMS platforms, so instead of figuring out the pointer settings */ /* Change it to a noop */ # define vms_translate_path(__path) __path diff --git a/lib/setup-win32.h b/lib/setup-win32.h index 80efc25f1..a297bdcff 100644 --- a/lib/setup-win32.h +++ b/lib/setup-win32.h @@ -62,11 +62,11 @@ #endif /* - * Include header files for windows builds before redefining anything. + * Include header files for Windows builds before redefining anything. * Use this preprocessor block only to include or exclude windows.h, - * winsock2.h or ws2tcpip.h. Any other windows thing belongs + * winsock2.h or ws2tcpip.h. Any other Windows thing belongs * to any other further and independent block. Under Cygwin things work - * just as under linux (e.g. ) and the winsock headers should + * just as under Linux (e.g. ) and the Winsock headers should * never be included when __CYGWIN__ is defined. */ diff --git a/lib/sha256.c b/lib/sha256.c index 6ff66f741..91dc95016 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -100,10 +100,10 @@ #if defined(USE_OPENSSL_SHA256) -struct sha256_ctx { +struct ossl_sha256_ctx { EVP_MD_CTX *openssl_ctx; }; -typedef struct sha256_ctx my_sha256_ctx; +typedef struct ossl_sha256_ctx my_sha256_ctx; static CURLcode my_sha256_init(my_sha256_ctx *ctx) { @@ -247,7 +247,7 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) unsigned long length = 0; CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == SHA256_DIGEST_LENGTH) + if(length == CURL_SHA256_DIGEST_LENGTH) CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); if(ctx->hHash) diff --git a/lib/share.c b/lib/share.c index 164aceb87..2ddaba6d7 100644 --- a/lib/share.c +++ b/lib/share.c @@ -31,6 +31,7 @@ #include "psl.h" #include "vtls/vtls.h" #include "hsts.h" +#include "url.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -120,8 +121,12 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) break; case CURL_LOCK_DATA_CONNECT: - if(Curl_conncache_init(&share->conn_cache, NULL, 103)) - res = CURLSHE_NOMEM; + /* It is safe to set this option several times on a share. */ + if(!share->cpool.idata) { + if(Curl_cpool_init(&share->cpool, Curl_on_disconnect, + NULL, share, 103)) + res = CURLSHE_NOMEM; + } break; case CURL_LOCK_DATA_PSL: @@ -224,8 +229,9 @@ curl_share_cleanup(struct Curl_share *share) return CURLSHE_IN_USE; } - Curl_conncache_close_all_connections(&share->conn_cache); - Curl_conncache_destroy(&share->conn_cache); + if(share->specifier & (1 << CURL_LOCK_DATA_CONNECT)) { + Curl_cpool_destroy(&share->cpool); + } Curl_hash_destroy(&share->hostcache); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) diff --git a/lib/share.h b/lib/share.h index f63a6f8fe..124f7049f 100644 --- a/lib/share.h +++ b/lib/share.h @@ -34,6 +34,9 @@ #define CURL_GOOD_SHARE 0x7e117a1e #define GOOD_SHARE_HANDLE(x) ((x) && (x)->magic == CURL_GOOD_SHARE) +#define CURL_SHARE_KEEP_CONNECT(s) \ + ((s) && ((s)->specifier & (1<< CURL_LOCK_DATA_CONNECT))) + /* this struct is libcurl-private, do not export details */ struct Curl_share { unsigned int magic; /* CURL_GOOD_SHARE */ @@ -43,7 +46,7 @@ struct Curl_share { curl_lock_function lockfunc; curl_unlock_function unlockfunc; void *clientdata; - struct conncache conn_cache; + struct cpool cpool; struct Curl_hash hostcache; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) struct CookieInfo *cookies; diff --git a/lib/sigpipe.h b/lib/sigpipe.h index b91a2f513..c57580f43 100644 --- a/lib/sigpipe.h +++ b/lib/sigpipe.h @@ -35,10 +35,12 @@ struct sigpipe_ignore { }; #define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x +#define SIGPIPE_MEMBER(x) struct sigpipe_ignore x static void sigpipe_init(struct sigpipe_ignore *ig) { memset(ig, 0, sizeof(*ig)); + ig->no_signal = TRUE; } /* @@ -91,6 +93,7 @@ static void sigpipe_apply(struct Curl_easy *data, #define sigpipe_init(x) Curl_nop_stmt #define sigpipe_restore(x) Curl_nop_stmt #define SIGPIPE_VARIABLE(x) +#define SIGPIPE_MEMBER(x) bool x #endif #endif /* HEADER_CURL_SIGPIPE_H */ diff --git a/lib/smb.c b/lib/smb.c index 102662ace..f4fff9e61 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -572,7 +572,7 @@ static CURLcode smb_send(struct Curl_easy *data, size_t len, size_t bytes_written; CURLcode result; - result = Curl_xfer_send(data, smbc->send_buf, len, &bytes_written); + result = Curl_xfer_send(data, smbc->send_buf, len, FALSE, &bytes_written); if(result) return result; @@ -597,7 +597,7 @@ static CURLcode smb_flush(struct Curl_easy *data) if(!smbc->send_size) return CURLE_OK; - result = Curl_xfer_send(data, smbc->send_buf + smbc->sent, len, + result = Curl_xfer_send(data, smbc->send_buf + smbc->sent, len, FALSE, &bytes_written); if(result) return result; @@ -642,9 +642,9 @@ static CURLcode smb_send_setup(struct Curl_easy *data) unsigned char nt_hash[21]; unsigned char nt[24]; - size_t byte_count = sizeof(lm) + sizeof(nt); - byte_count += strlen(smbc->user) + strlen(smbc->domain); - byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */ + const size_t byte_count = sizeof(lm) + sizeof(nt) + + strlen(smbc->user) + strlen(smbc->domain) + + strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */ if(byte_count > sizeof(msg.bytes)) return CURLE_FILESIZE_EXCEEDED; @@ -653,7 +653,7 @@ static CURLcode smb_send_setup(struct Curl_easy *data) Curl_ntlm_core_mk_nt_hash(conn->passwd, nt_hash); Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt); - memset(&msg, 0, sizeof(msg)); + memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); msg.word_count = SMB_WC_SETUP_ANDX; msg.andx.command = SMB_COM_NO_ANDX_COMMAND; msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE); @@ -671,7 +671,7 @@ static CURLcode smb_send_setup(struct Curl_easy *data) MSGCATNULL(smbc->domain); MSGCATNULL(OS); MSGCATNULL(CLIENTNAME); - byte_count = p - msg.bytes; + DEBUGASSERT(byte_count == (size_t)(p - msg.bytes)); msg.byte_count = smb_swap16((unsigned short)byte_count); return smb_send_message(data, SMB_COM_SETUP_ANDX, &msg, @@ -685,12 +685,12 @@ static CURLcode smb_send_tree_connect(struct Curl_easy *data) struct smb_conn *smbc = &conn->proto.smbc; char *p = msg.bytes; - size_t byte_count = strlen(conn->host.name) + strlen(smbc->share); - byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */ + const size_t byte_count = strlen(conn->host.name) + strlen(smbc->share) + + strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */ if(byte_count > sizeof(msg.bytes)) return CURLE_FILESIZE_EXCEEDED; - memset(&msg, 0, sizeof(msg)); + memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); msg.word_count = SMB_WC_TREE_CONNECT_ANDX; msg.andx.command = SMB_COM_NO_ANDX_COMMAND; msg.pw_len = 0; @@ -699,7 +699,7 @@ static CURLcode smb_send_tree_connect(struct Curl_easy *data) MSGCAT("\\"); MSGCATNULL(smbc->share); MSGCATNULL(SERVICENAME); /* Match any type of service */ - byte_count = p - msg.bytes; + DEBUGASSERT(byte_count == (size_t)(p - msg.bytes)); msg.byte_count = smb_swap16((unsigned short)byte_count); return smb_send_message(data, SMB_COM_TREE_CONNECT_ANDX, &msg, @@ -710,16 +710,15 @@ static CURLcode smb_send_open(struct Curl_easy *data) { struct smb_request *req = data->req.p.smb; struct smb_nt_create msg; - size_t byte_count; + const size_t byte_count = strlen(req->path) + 1; - if((strlen(req->path) + 1) > sizeof(msg.bytes)) + if(byte_count > sizeof(msg.bytes)) return CURLE_FILESIZE_EXCEEDED; - memset(&msg, 0, sizeof(msg)); + memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); msg.word_count = SMB_WC_NT_CREATE_ANDX; msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - byte_count = strlen(req->path); - msg.name_length = smb_swap16((unsigned short)byte_count); + msg.name_length = smb_swap16((unsigned short)(byte_count - 1)); msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); if(data->state.upload) { msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); @@ -729,7 +728,7 @@ static CURLcode smb_send_open(struct Curl_easy *data) msg.access = smb_swap32(SMB_GENERIC_READ); msg.create_disposition = smb_swap32(SMB_FILE_OPEN); } - msg.byte_count = smb_swap16((unsigned short) ++byte_count); + msg.byte_count = smb_swap16((unsigned short) byte_count); strcpy(msg.bytes, req->path); return smb_send_message(data, SMB_COM_NT_CREATE_ANDX, &msg, @@ -924,7 +923,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) /* * Convert a timestamp from the Windows world (100 nsec units from 1 Jan 1601) - * to Posix time. Cap the output to fit within a time_t. + * to POSIX time. Cap the output to fit within a time_t. */ static void get_posix_time(time_t *out, curl_off_t timestamp) { diff --git a/lib/smtp.c b/lib/smtp.c index 5ee1b5ea3..3c5893284 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -288,7 +288,7 @@ static CURLcode smtp_get_message(struct Curl_easy *data, struct bufref *out) static void smtp_state(struct Curl_easy *data, smtpstate newstate) { struct smtp_conn *smtpc = &data->conn->proto.smtpc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) /* for debug purposes */ static const char * const names[] = { "STOP", @@ -308,8 +308,8 @@ static void smtp_state(struct Curl_easy *data, smtpstate newstate) }; if(smtpc->state != newstate) - infof(data, "SMTP %p state change from %s to %s", - (void *)smtpc, names[smtpc->state], names[newstate]); + CURL_TRC_SMTP(data, "state change from %s to %s", + names[smtpc->state], names[newstate]); #endif smtpc->state = newstate; @@ -723,7 +723,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data) /* Calculate the optional SIZE parameter */ if(conn->proto.smtpc.size_supported && data->state.infilesize > 0) { - size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize); + size = aprintf("%" FMT_OFF_T, data->state.infilesize); if(!size) { result = CURLE_OUT_OF_MEMORY; @@ -1422,7 +1422,8 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status, /* Clear the transfer mode for the next request */ smtp->transfer = PPTRANSFER_BODY; - + CURL_TRC_SMTP(data, "smtp_done(status=%d, premature=%d) -> %d", + status, premature, result); return result; } @@ -1440,7 +1441,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, CURLcode result = CURLE_OK; struct SMTP *smtp = data->req.p.smtp; - DEBUGF(infof(data, "DO phase starts")); + CURL_TRC_SMTP(data, "smtp_perform(), start"); if(data->req.no_body) { /* Requested no body means no transfer */ @@ -1472,16 +1473,16 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, result = smtp_perform_command(data); if(result) - return result; + goto out; /* Run the state-machine */ result = smtp_multi_statemach(data, dophase_done); *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete")); - +out: + CURL_TRC_SMTP(data, "smtp_perform() -> %d, connected=%d, done=%d", + result, *connected, *dophase_done); return result; } @@ -1507,7 +1508,7 @@ static CURLcode smtp_do(struct Curl_easy *data, bool *done) return result; result = smtp_regular_transfer(data, done); - + CURL_TRC_SMTP(data, "smtp_do() -> %d, done=%d", result, *done); return result; } @@ -1542,6 +1543,7 @@ static CURLcode smtp_disconnect(struct Curl_easy *data, /* Cleanup our connection based variables */ Curl_safefree(smtpc->domain); + CURL_TRC_SMTP(data, "smtp_disconnect(), finished"); return CURLE_OK; } @@ -1573,6 +1575,7 @@ static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done) DEBUGF(infof(data, "DO phase is complete")); } + CURL_TRC_SMTP(data, "smtp_doing() -> %d, done=%d", result, *dophase_done); return result; } @@ -1607,6 +1610,8 @@ static CURLcode smtp_regular_transfer(struct Curl_easy *data, if(!result && *dophase_done) result = smtp_dophase_done(data, connected); + CURL_TRC_SMTP(data, "smtp_regular_transfer() -> %d, done=%d", + result, *dophase_done); return result; } @@ -1620,10 +1625,8 @@ static CURLcode smtp_setup_connection(struct Curl_easy *data, /* Initialise the SMTP layer */ result = smtp_init(data); - if(result) - return result; - - return CURLE_OK; + CURL_TRC_SMTP(data, "smtp_setup_connection() -> %d", result); + return result; } /*********************************************************************** diff --git a/lib/socketpair.h b/lib/socketpair.h index 42f4034fc..3044f1122 100644 --- a/lib/socketpair.h +++ b/lib/socketpair.h @@ -74,7 +74,7 @@ int Curl_pipe(curl_socket_t socks[2], bool nonblocking); #elif !defined(HAVE_SOCKETPAIR) #define SOCKETPAIR_FAMILY 0 /* not used */ #else -#error "unsupported unix domain and socketpair build combo" +#error "unsupported Unix domain and socketpair build combo" #endif #ifdef SOCK_CLOEXEC diff --git a/lib/socks.c b/lib/socks.c index 094ff42cd..1f2b7b609 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -217,7 +217,7 @@ static CURLproxycode socks_state_send(struct Curl_cfilter *cf, CURLcode result; nwritten = Curl_conn_cf_send(cf->next, data, (char *)sx->outp, - sx->outstanding, &result); + sx->outstanding, FALSE, &result); if(nwritten <= 0) { if(CURLE_AGAIN == result) { return CURLPX_OK; @@ -388,7 +388,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)", buf); - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + Curl_resolv_unlink(data, &dns); /* not used anymore from now on */ } else failf(data, "SOCKS4 connection to %s not supported", sx->hostname); @@ -893,7 +893,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, failf(data, "SOCKS5 connection to %s not supported", dest); } - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + Curl_resolv_unlink(data, &dns); /* not used anymore from now on */ goto CONNECT_REQ_SEND; } CONNECT_RESOLVE_REMOTE: diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c index edcc68326..f83db977a 100644 --- a/lib/socks_gssapi.c +++ b/lib/socks_gssapi.c @@ -204,7 +204,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, us_length = htons((unsigned short)gss_send_token.length); memcpy(socksreq + 2, &us_length, sizeof(short)); - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code); + nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, + FALSE, &code); if(code || (4 != nwritten)) { failf(data, "Failed to send GSS-API authentication request."); gss_release_name(&gss_status, &server); @@ -216,7 +217,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, nwritten = Curl_conn_cf_send(cf->next, data, (char *)gss_send_token.value, - gss_send_token.length, &code); + gss_send_token.length, FALSE, &code); if(code || ((ssize_t)gss_send_token.length != nwritten)) { failf(data, "Failed to send GSS-API authentication token."); gss_release_name(&gss_status, &server); @@ -410,7 +411,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, memcpy(socksreq + 2, &us_length, sizeof(short)); } - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code); + nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &code); if(code || (4 != nwritten)) { failf(data, "Failed to send GSS-API encryption request."); gss_release_buffer(&gss_status, &gss_w_token); @@ -420,7 +422,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(data->set.socks5_gssapi_nec) { memcpy(socksreq, &gss_enc, 1); - nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, &code); + nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, + &code); if(code || ( 1 != nwritten)) { failf(data, "Failed to send GSS-API encryption type."); gss_delete_sec_context(&gss_status, &gss_context, NULL); @@ -430,7 +433,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, else { nwritten = Curl_conn_cf_send(cf->next, data, (char *)gss_w_token.value, - gss_w_token.length, &code); + gss_w_token.length, FALSE, &code); if(code || ((ssize_t)gss_w_token.length != nwritten)) { failf(data, "Failed to send GSS-API encryption type."); gss_release_buffer(&gss_status, &gss_w_token); diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c index a83288dd0..a76d26180 100644 --- a/lib/socks_sspi.c +++ b/lib/socks_sspi.c @@ -139,7 +139,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, cred_handle.dwLower = 0; cred_handle.dwUpper = 0; - status = s_pSecFn->AcquireCredentialsHandle(NULL, + status = Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT("Kerberos"), SECPKG_CRED_OUTBOUND, NULL, @@ -152,7 +152,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(check_sspi_err(data, status, "AcquireCredentialsHandle")) { failf(data, "Failed to acquire credentials."); free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); return CURLE_COULDNT_CONNECT; } @@ -167,7 +167,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(!sname) return CURLE_OUT_OF_MEMORY; - status = s_pSecFn->InitializeSecurityContext(&cred_handle, + status = Curl_pSecFn->InitializeSecurityContext(&cred_handle, context_handle, sname, ISC_REQ_MUTUAL_AUTH | @@ -186,17 +186,17 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, curlx_unicodefree(sname); if(sspi_recv_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); sspi_recv_token.pvBuffer = NULL; sspi_recv_token.cbBuffer = 0; } if(check_sspi_err(data, status, "InitializeSecurityContext")) { free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); failf(data, "Failed to initialise security context."); return CURLE_COULDNT_CONNECT; } @@ -207,44 +207,45 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, us_length = htons((unsigned short)sspi_send_token.cbBuffer); memcpy(socksreq + 2, &us_length, sizeof(short)); - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code); + written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &code); if(code || (4 != written)) { failf(data, "Failed to send SSPI authentication request."); free(service_name); if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } written = Curl_conn_cf_send(cf->next, data, (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, &code); + sspi_send_token.cbBuffer, FALSE, &code); if(code || (sspi_send_token.cbBuffer != (size_t)written)) { failf(data, "Failed to send SSPI authentication token."); free(service_name); if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } } if(sspi_send_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); sspi_send_token.pvBuffer = NULL; } sspi_send_token.cbBuffer = 0; if(sspi_recv_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); sspi_recv_token.pvBuffer = NULL; } sspi_recv_token.cbBuffer = 0; @@ -266,8 +267,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(result || (actualread != 4)) { failf(data, "Failed to receive SSPI authentication response."); free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -276,8 +277,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "User was rejected by the SOCKS5 server (%u %u).", (unsigned int)socksreq[0], (unsigned int)socksreq[1]); free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -285,8 +286,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Invalid SSPI authentication response type (%u %u).", (unsigned int)socksreq[0], (unsigned int)socksreq[1]); free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -298,8 +299,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(!sspi_recv_token.pvBuffer) { free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } result = Curl_blockread_all(cf, data, (char *)sspi_recv_token.pvBuffer, @@ -309,9 +310,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Failed to receive SSPI authentication token."); free(service_name); if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -321,13 +322,13 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, free(service_name); /* Everything is good so far, user was authenticated! */ - status = s_pSecFn->QueryCredentialsAttributes(&cred_handle, + status = Curl_pSecFn->QueryCredentialsAttributes(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names); - s_pSecFn->FreeCredentialsHandle(&cred_handle); + Curl_pSecFn->FreeCredentialsHandle(&cred_handle); if(check_sspi_err(data, status, "QueryCredentialAttributes")) { - s_pSecFn->DeleteSecurityContext(&sspi_context); - s_pSecFn->FreeContextBuffer(names.sUserName); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(names.sUserName); failf(data, "Failed to determine username."); return CURLE_COULDNT_CONNECT; } @@ -338,7 +339,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, (user_utf8 ? user_utf8 : "(unknown)")); curlx_unicodefree(user_utf8); #endif - s_pSecFn->FreeContextBuffer(names.sUserName); + Curl_pSecFn->FreeContextBuffer(names.sUserName); } /* Do encryption */ @@ -393,11 +394,11 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, memcpy(socksreq + 2, &us_length, sizeof(short)); } else { - status = s_pSecFn->QueryContextAttributes(&sspi_context, + status = Curl_pSecFn->QueryContextAttributes(&sspi_context, SECPKG_ATTR_SIZES, &sspi_sizes); if(check_sspi_err(data, status, "QueryContextAttributes")) { - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); failf(data, "Failed to query security context attributes."); return CURLE_COULDNT_CONNECT; } @@ -407,15 +408,15 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer); if(!sspi_w_token[0].pvBuffer) { - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } sspi_w_token[1].cbBuffer = 1; sspi_w_token[1].pvBuffer = malloc(1); if(!sspi_w_token[1].pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } @@ -424,20 +425,20 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize; sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize); if(!sspi_w_token[2].pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } - status = s_pSecFn->EncryptMessage(&sspi_context, + status = Curl_pSecFn->EncryptMessage(&sspi_context, KERB_WRAP_NO_ENCRYPT, &wrap_desc, 0); if(check_sspi_err(data, status, "EncryptMessage")) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); failf(data, "Failed to query security context attributes."); return CURLE_COULDNT_CONNECT; } @@ -446,10 +447,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, + sspi_w_token[2].cbBuffer; sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer); if(!sspi_send_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } @@ -462,13 +463,13 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, + sspi_w_token[1].cbBuffer, sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); sspi_w_token[0].pvBuffer = NULL; sspi_w_token[0].cbBuffer = 0; - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); sspi_w_token[1].pvBuffer = NULL; sspi_w_token[1].cbBuffer = 0; - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); sspi_w_token[2].pvBuffer = NULL; sspi_w_token[2].cbBuffer = 0; @@ -476,43 +477,45 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, memcpy(socksreq + 2, &us_length, sizeof(short)); } - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code); + written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, FALSE, + &code); if(code || (4 != written)) { failf(data, "Failed to send SSPI encryption request."); if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } if(data->set.socks5_gssapi_nec) { memcpy(socksreq, &gss_enc, 1); - written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, &code); + written = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, FALSE, + &code); if(code || (1 != written)) { failf(data, "Failed to send SSPI encryption type."); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } } else { written = Curl_conn_cf_send(cf->next, data, (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, &code); + sspi_send_token.cbBuffer, FALSE, &code); if(code || (sspi_send_token.cbBuffer != (size_t)written)) { failf(data, "Failed to send SSPI encryption type."); if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); } result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); if(result || (actualread != 4)) { failf(data, "Failed to receive SSPI encryption response."); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -520,14 +523,14 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(socksreq[1] == 255) { /* status / message type */ failf(data, "User was rejected by the SOCKS5 server (%u %u).", (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } if(socksreq[1] != 2) { /* status / message type */ failf(data, "Invalid SSPI encryption response type (%u %u).", (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -537,7 +540,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, sspi_w_token[0].cbBuffer = us_length; sspi_w_token[0].pvBuffer = malloc(us_length); if(!sspi_w_token[0].pvBuffer) { - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_OUT_OF_MEMORY; } @@ -546,8 +549,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(result || (actualread != us_length)) { failf(data, "Failed to receive SSPI encryption type."); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } @@ -559,17 +562,17 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, sspi_w_token[1].cbBuffer = 0; sspi_w_token[1].pvBuffer = NULL; - status = s_pSecFn->DecryptMessage(&sspi_context, + status = Curl_pSecFn->DecryptMessage(&sspi_context, &wrap_desc, 0, &qop); if(check_sspi_err(data, status, "DecryptMessage")) { if(sspi_w_token[0].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); if(sspi_w_token[1].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); failf(data, "Failed to query security context attributes."); return CURLE_COULDNT_CONNECT; } @@ -578,27 +581,27 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, failf(data, "Invalid SSPI encryption response length (%lu).", (unsigned long)sspi_w_token[1].cbBuffer); if(sspi_w_token[0].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); if(sspi_w_token[1].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); } else { if(sspi_w_token[0].cbBuffer != 1) { failf(data, "Invalid SSPI encryption response length (%lu).", (unsigned long)sspi_w_token[0].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); return CURLE_COULDNT_CONNECT; } memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + Curl_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); } (void)curlx_nonblock(sock, TRUE); @@ -611,7 +614,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, if(socksreq[0] != 0) conn->socks5_sspi_context = sspi_context; else { - s_pSecFn->DeleteSecurityContext(&sspi_context); + Curl_pSecFn->DeleteSecurityContext(&sspi_context); conn->socks5_sspi_context = sspi_context; } */ diff --git a/lib/splay.c b/lib/splay.c index 99bb14997..5e27b08a6 100644 --- a/lib/splay.c +++ b/lib/splay.c @@ -24,6 +24,7 @@ #include "curl_setup.h" +#include "timeval.h" #include "splay.h" /* @@ -33,7 +34,7 @@ * zero : when i is equal to j * positive when : when i is larger than j */ -#define compare(i,j) Curl_splaycomparekeys((i),(j)) +#define compare(i,j) Curl_timediff_us(i,j) /* * Splay using the key i (which may or may not be in the tree.) The starting @@ -45,12 +46,12 @@ struct Curl_tree *Curl_splay(struct curltime i, struct Curl_tree N, *l, *r, *y; if(!t) - return t; + return NULL; N.smaller = N.larger = NULL; l = r = &N; for(;;) { - long comp = compare(i, t->key); + timediff_t comp = compare(i, t->key); if(comp < 0) { if(!t->smaller) break; @@ -106,11 +107,11 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, ~0, -1 }; /* will *NEVER* appear */ - if(!node) - return t; + DEBUGASSERT(node); if(t) { t = Curl_splay(i, t); + DEBUGASSERT(t); if(compare(i, t->key) == 0) { /* There already exists a node in the tree with the very same key. Build a doubly-linked circular list of nodes. We add the new 'node' struct @@ -166,6 +167,7 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i, /* find smallest */ t = Curl_splay(tv_zero, t); + DEBUGASSERT(t); if(compare(i, t->key) < 0) { /* even the smallest is too big */ *removed = NULL; @@ -217,9 +219,11 @@ int Curl_splayremove(struct Curl_tree *t, }; /* will *NEVER* appear */ struct Curl_tree *x; - if(!t || !removenode) + if(!t) return 1; + DEBUGASSERT(removenode); + if(compare(KEY_NOTUSED, removenode->key) == 0) { /* Key set to NOTUSED means it is a subnode within a 'same' linked list and thus we can unlink it easily. */ @@ -238,6 +242,7 @@ int Curl_splayremove(struct Curl_tree *t, } t = Curl_splay(removenode->key, t); + DEBUGASSERT(t); /* First make sure that we got the same root node as the one we want to remove, as otherwise we might be trying to remove a node that @@ -268,6 +273,7 @@ int Curl_splayremove(struct Curl_tree *t, x = t->larger; else { x = Curl_splay(removenode->key, t->smaller); + DEBUGASSERT(x); x->larger = t->larger; } } @@ -276,3 +282,16 @@ int Curl_splayremove(struct Curl_tree *t, return 0; } + +/* set and get the custom payload for this tree node */ +void Curl_splayset(struct Curl_tree *node, void *payload) +{ + DEBUGASSERT(node); + node->ptr = payload; +} + +void *Curl_splayget(struct Curl_tree *node) +{ + DEBUGASSERT(node); + return node->ptr; +} diff --git a/lib/splay.h b/lib/splay.h index 20b2bb69a..b8c9360e5 100644 --- a/lib/splay.h +++ b/lib/splay.h @@ -26,13 +26,14 @@ #include "curl_setup.h" #include "timeval.h" +/* only use function calls to access this struct */ struct Curl_tree { struct Curl_tree *smaller; /* smaller node */ struct Curl_tree *larger; /* larger node */ struct Curl_tree *samen; /* points to the next node with identical key */ struct Curl_tree *samep; /* points to the prev node with identical key */ - struct curltime key; /* this node's "sort" key */ - void *payload; /* data the splay code does not care about */ + struct curltime key; /* this node's "sort" key */ + void *ptr; /* data the splay code does not care about */ }; struct Curl_tree *Curl_splay(struct curltime i, @@ -50,9 +51,8 @@ int Curl_splayremove(struct Curl_tree *t, struct Curl_tree *removenode, struct Curl_tree **newroot); -#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \ - ( ((i.tv_sec) > (j.tv_sec)) ? 1 : \ - ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \ - ( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0)))) +/* set and get the custom payload for this tree node */ +void Curl_splayset(struct Curl_tree *node, void *payload); +void *Curl_splayget(struct Curl_tree *node); #endif /* HEADER_CURL_SPLAY_H */ diff --git a/lib/strtoofft.c b/lib/strtoofft.c index 8fac230f2..f1c7ba271 100644 --- a/lib/strtoofft.c +++ b/lib/strtoofft.c @@ -207,7 +207,7 @@ static int get_char(char c, int base) #endif /* Only present if we need strtoll, but do not have it. */ /* - * Parse a *positive* up to 64-bit number written in ascii. + * Parse a *positive* up to 64-bit number written in ASCII. */ CURLofft curlx_strtoofft(const char *str, char **endp, int base, curl_off_t *num) diff --git a/lib/system_win32.c b/lib/system_win32.c index 4af86699e..f4dbe0310 100644 --- a/lib/system_win32.c +++ b/lib/system_win32.c @@ -38,25 +38,18 @@ LARGE_INTEGER Curl_freq; bool Curl_isVistaOrGreater; -bool Curl_isWindows8OrGreater; /* Handle of iphlpapp.dll */ static HMODULE s_hIpHlpApiDll = NULL; -/* Function pointers */ +/* Pointer to the if_nametoindex function */ IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; -FREEADDRINFOEXW_FN Curl_FreeAddrInfoExW = NULL; -GETADDRINFOEXCANCEL_FN Curl_GetAddrInfoExCancel = NULL; -GETADDRINFOEXW_FN Curl_GetAddrInfoExW = NULL; -/* Curl_win32_init() performs win32 global initialization */ +/* Curl_win32_init() performs Win32 global initialization */ CURLcode Curl_win32_init(long flags) { -#ifdef USE_WINSOCK - HMODULE ws2_32Dll; -#endif /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which - is just for Winsock at the moment. Any required win32 initialization + is just for Winsock at the moment. Any required Win32 initialization should take place after this block. */ if(flags & CURL_GLOBAL_WIN32) { #ifdef USE_WINSOCK @@ -111,22 +104,6 @@ CURLcode Curl_win32_init(long flags) Curl_if_nametoindex = pIfNameToIndex; } -#ifdef USE_WINSOCK -#ifdef CURL_WINDOWS_APP - ws2_32Dll = Curl_load_library(TEXT("ws2_32.dll")); -#else - ws2_32Dll = GetModuleHandleA("ws2_32"); -#endif - if(ws2_32Dll) { - Curl_FreeAddrInfoExW = CURLX_FUNCTION_CAST(FREEADDRINFOEXW_FN, - GetProcAddress(ws2_32Dll, "FreeAddrInfoExW")); - Curl_GetAddrInfoExCancel = CURLX_FUNCTION_CAST(GETADDRINFOEXCANCEL_FN, - GetProcAddress(ws2_32Dll, "GetAddrInfoExCancel")); - Curl_GetAddrInfoExW = CURLX_FUNCTION_CAST(GETADDRINFOEXW_FN, - GetProcAddress(ws2_32Dll, "GetAddrInfoExW")); - } -#endif - /* curlx_verify_windows_version must be called during init at least once because it has its own initialization routine. */ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT, @@ -136,13 +113,6 @@ CURLcode Curl_win32_init(long flags) else Curl_isVistaOrGreater = FALSE; - if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - Curl_isWindows8OrGreater = TRUE; - } - else - Curl_isWindows8OrGreater = FALSE; - QueryPerformanceFrequency(&Curl_freq); return CURLE_OK; } @@ -150,9 +120,6 @@ CURLcode Curl_win32_init(long flags) /* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ void Curl_win32_cleanup(long init_flags) { - Curl_FreeAddrInfoExW = NULL; - Curl_GetAddrInfoExCancel = NULL; - Curl_GetAddrInfoExW = NULL; if(s_hIpHlpApiDll) { FreeLibrary(s_hIpHlpApiDll); s_hIpHlpApiDll = NULL; @@ -212,7 +179,7 @@ HMODULE Curl_load_library(LPCTSTR filename) HMODULE hModule = NULL; LOADLIBRARYEX_FN pLoadLibraryEx = NULL; - /* Get a handle to kernel32 so we can access it is functions at runtime */ + /* Get a handle to kernel32 so we can access its functions at runtime */ HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); if(!hKernel32) return NULL; @@ -271,16 +238,4 @@ HMODULE Curl_load_library(LPCTSTR filename) #endif } -bool Curl_win32_impersonating(void) -{ -#ifndef CURL_WINDOWS_APP - HANDLE token = NULL; - if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token)) { - CloseHandle(token); - return TRUE; - } -#endif - return FALSE; -} - #endif /* _WIN32 */ diff --git a/lib/system_win32.h b/lib/system_win32.h index 534a5e498..024d959f3 100644 --- a/lib/system_win32.h +++ b/lib/system_win32.h @@ -26,13 +26,12 @@ #include "curl_setup.h" -#ifdef _WIN32 +#if defined(_WIN32) #include extern LARGE_INTEGER Curl_freq; extern bool Curl_isVistaOrGreater; -extern bool Curl_isWindows8OrGreater; CURLcode Curl_win32_init(long flags); void Curl_win32_cleanup(long init_flags); @@ -43,35 +42,6 @@ typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); /* This is used instead of if_nametoindex if available on Windows */ extern IF_NAMETOINDEX_FN Curl_if_nametoindex; -/* Identical copy of addrinfoexW/ADDRINFOEXW */ -typedef struct addrinfoexW_ -{ - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - PWSTR ai_canonname; - struct sockaddr *ai_addr; - void *ai_blob; - size_t ai_bloblen; - LPGUID ai_provider; - struct addrinfoexW_ *ai_next; -} ADDRINFOEXW_; - -typedef void (CALLBACK *LOOKUP_COMPLETION_FN)(DWORD, DWORD, LPWSAOVERLAPPED); -typedef void (WSAAPI *FREEADDRINFOEXW_FN)(ADDRINFOEXW_*); -typedef int (WSAAPI *GETADDRINFOEXCANCEL_FN)(LPHANDLE); -typedef int (WSAAPI *GETADDRINFOEXW_FN)(PCWSTR, PCWSTR, DWORD, LPGUID, - const ADDRINFOEXW_*, ADDRINFOEXW_**, struct timeval*, LPOVERLAPPED, - LOOKUP_COMPLETION_FN, LPHANDLE); - -extern FREEADDRINFOEXW_FN Curl_FreeAddrInfoExW; -extern GETADDRINFOEXCANCEL_FN Curl_GetAddrInfoExCancel; -extern GETADDRINFOEXW_FN Curl_GetAddrInfoExW; - -bool Curl_win32_impersonating(void); - /* This is used to dynamically load DLLs */ HMODULE Curl_load_library(LPCTSTR filename); #else /* _WIN32 */ diff --git a/lib/telnet.c b/lib/telnet.c index 91fa10ada..8cd19b1b0 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -1276,7 +1276,7 @@ static CURLcode send_telnet_data(struct Curl_easy *data, default: /* write! */ bytes_written = 0; result = Curl_xfer_send(data, outbuf + total_written, - outlen - total_written, &bytes_written); + outlen - total_written, FALSE, &bytes_written); total_written += bytes_written; break; } @@ -1342,7 +1342,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) #ifdef USE_WINSOCK /* We want to wait for both stdin and the socket. Since - ** the select() function in winsock only works on sockets + ** the select() function in Winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ @@ -1353,7 +1353,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) return CURLE_FAILED_INIT; } - /* Tell winsock what events we want to listen to */ + /* Tell Winsock what events we want to listen to */ if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { WSACloseEvent(event_handle); return CURLE_OK; diff --git a/lib/tftp.c b/lib/tftp.c index c4cc8049d..dbae202d5 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -240,8 +240,7 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) state->retry_time = 1; infof(state->data, - "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T - ", retry %d maxtry %d", + "set timeouts for state %d; Total % " FMT_OFF_T ", retry %d maxtry %d", (int)state->state, timeout_ms, state->retry_time, state->retry_max); /* init RX time */ @@ -434,7 +433,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, struct Curl_easy *data = state->data; CURLcode result = CURLE_OK; - /* Set ascii mode if -B flag was used */ + /* Set ASCII mode if -B flag was used */ if(data->state.prefer_ascii) mode = "netascii"; @@ -484,7 +483,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, char buf[64]; /* add tsize option */ if(data->state.upload && (data->state.infilesize != -1)) - msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T, + msnprintf(buf, sizeof(buf), "%" FMT_OFF_T, data->state.infilesize); else strcpy(buf, "0"); /* the destination is large enough */ diff --git a/lib/timediff.h b/lib/timediff.h index 1ffa59e77..75f996c55 100644 --- a/lib/timediff.h +++ b/lib/timediff.h @@ -29,7 +29,7 @@ /* Use a larger type even for 32-bit time_t systems so that we can keep microsecond accuracy in it */ typedef curl_off_t timediff_t; -#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T +#define FMT_TIMEDIFF_T FMT_OFF_T #define TIMEDIFF_T_MAX CURL_OFF_T_MAX #define TIMEDIFF_T_MIN CURL_OFF_T_MIN diff --git a/lib/timeval.c b/lib/timeval.c index 10dbaf02c..bb29bfdfe 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -137,7 +137,7 @@ struct curltime Curl_now(void) struct curltime Curl_now(void) { /* - ** Monotonic timer on Mac OS is provided by mach_absolute_time(), which + ** Monotonic timer on macOS is provided by mach_absolute_time(), which ** returns time in Mach "absolute time units," which are platform-dependent. ** To convert to nanoseconds, one must use conversion factors specified by ** mach_timebase_info(). diff --git a/lib/transfer.c b/lib/transfer.c index 6c95a4719..0f42b3f2b 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -184,6 +184,18 @@ static bool xfer_recv_shutdown_started(struct Curl_easy *data) return Curl_shutdown_started(data, sockindex); } +CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) +{ + int sockindex; + + if(!data || !data->conn) + return CURLE_FAILED_INIT; + if(data->conn->writesockfd == CURL_SOCKET_BAD) + return CURLE_FAILED_INIT; + sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]); + return Curl_conn_shutdown(data, sockindex, done); +} + /** * Receive raw response data for the transfer. * @param data the transfer @@ -237,7 +249,7 @@ static ssize_t Curl_xfer_recv_resp(struct Curl_easy *data, return -1; } } - DEBUGF(infof(data, "readwrite_data: we are done")); + DEBUGF(infof(data, "sendrecv_dl: we are done")); } DEBUGASSERT(nread >= 0); return nread; @@ -248,9 +260,9 @@ static ssize_t Curl_xfer_recv_resp(struct Curl_easy *data, * the stream was rewound (in which case we have data in a * buffer) */ -static CURLcode readwrite_data(struct Curl_easy *data, - struct SingleRequest *k, - int *didwhat) +static CURLcode sendrecv_dl(struct Curl_easy *data, + struct SingleRequest *k, + int *didwhat) { struct connectdata *conn = data->conn; CURLcode result = CURLE_OK; @@ -294,11 +306,18 @@ static CURLcode readwrite_data(struct Curl_easy *data, nread = Curl_xfer_recv_resp(data, buf, bytestoread, is_multiplex, &result); if(nread < 0) { - if(CURLE_AGAIN == result) { - result = CURLE_OK; - break; /* get out of loop */ + if(CURLE_AGAIN != result) + goto out; /* real error */ + result = CURLE_OK; + if(data->req.download_done && data->req.no_body && + !data->req.resp_trailer) { + DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, " + "not waiting for EOS")); + nread = 0; + /* continue as if we read the EOS */ } - goto out; /* real error */ + else + break; /* get out of loop */ } /* We only get a 0-length read on EndOfStream */ @@ -313,10 +332,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, DEBUGF(infof(data, "nread == 0, stream closed, bailing")); else DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); - /* stop receiving and ALL sending as well, including PAUSE and HOLD. - * We might still be paused on receive client writes though, so - * keep those bits around. */ - k->keepon &= ~(KEEP_RECV|KEEP_SENDBITS); + result = Curl_req_stop_send_recv(data); + if(result) + goto out; if(k->eos_written) /* already did write this to client, leave */ break; } @@ -352,25 +370,21 @@ static CURLcode readwrite_data(struct Curl_easy *data, may now close the connection. If there is now any kind of sending going on from our side, we need to stop that immediately. */ infof(data, "we are done reading and this is set to close, stop send"); - k->keepon &= ~KEEP_SEND; /* no writing anymore either */ - k->keepon &= ~KEEP_SEND_PAUSE; /* no pausing anymore either */ + Curl_req_abort_sending(data); } out: Curl_multi_xfer_buf_release(data, xfer_buf); if(result) - DEBUGF(infof(data, "readwrite_data() -> %d", result)); + DEBUGF(infof(data, "sendrecv_dl() -> %d", result)); return result; } /* * Send data to upload to the server, when the socket is writable. */ -static CURLcode readwrite_upload(struct Curl_easy *data, int *didwhat) +static CURLcode sendrecv_ul(struct Curl_easy *data, int *didwhat) { - if((data->req.keepon & KEEP_SEND_PAUSE)) - return CURLE_OK; - /* We should not get here when the sending is already done. It * probably means that someone set `data-req.keepon |= KEEP_SEND` * when it should not. */ @@ -402,56 +416,44 @@ static int select_bits_paused(struct Curl_easy *data, int select_bits) } /* - * Curl_readwrite() is the low-level function to be called when data is to + * Curl_sendrecv() is the low-level function to be called when data is to * be read and written to/from the connection. */ -CURLcode Curl_readwrite(struct Curl_easy *data) +CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) { - struct connectdata *conn = data->conn; struct SingleRequest *k = &data->req; - CURLcode result; - struct curltime now; + CURLcode result = CURLE_OK; int didwhat = 0; - int select_bits; + int select_bits = 0; + DEBUGASSERT(nowp); if(data->state.select_bits) { if(select_bits_paused(data, data->state.select_bits)) { /* leave the bits unchanged, so they'll tell us what to do when * this transfer gets unpaused. */ - DEBUGF(infof(data, "readwrite, select_bits, early return on PAUSED")); + /* DEBUGF(infof(data, "sendrecv, select_bits, early return on PAUSED")); + */ result = CURLE_OK; goto out; } - select_bits = data->state.select_bits; data->state.select_bits = 0; + /* DEBUGF(infof(data, "sendrecv, select_bits %x, RUN", select_bits)); */ + select_bits = (CURL_CSELECT_OUT|CURL_CSELECT_IN); } - else { - curl_socket_t fd_read; - curl_socket_t fd_write; - /* only use the proper socket if the *_HOLD bit is not set simultaneously - as then we are in rate limiting state in that transfer direction */ - if((k->keepon & KEEP_RECVBITS) == KEEP_RECV) - fd_read = conn->sockfd; - else - fd_read = CURL_SOCKET_BAD; - - if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) - fd_write = conn->writesockfd; - else - fd_write = CURL_SOCKET_BAD; - - select_bits = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0); + else if(data->last_poll.num) { + /* The transfer wanted something polled. Let's run all available + * send/receives. Worst case we EAGAIN on some. */ + /* DEBUGF(infof(data, "sendrecv, had poll sockets, RUN")); */ + select_bits = (CURL_CSELECT_OUT|CURL_CSELECT_IN); } - - if(select_bits == CURL_CSELECT_ERR) { - failf(data, "select/poll returned error"); - result = CURLE_SEND_ERROR; - goto out; + else if(data->req.keepon & KEEP_SEND_TIMED) { + /* DEBUGF(infof(data, "sendrecv, KEEP_SEND_TIMED, RUN ul")); */ + select_bits = CURL_CSELECT_OUT; } #ifdef USE_HYPER - if(conn->datastream) { - result = conn->datastream(data, conn, &didwhat, select_bits); + if(data->conn->datastream) { + result = data->conn->datastream(data, data->conn, &didwhat, select_bits); if(result || data->req.done) goto out; } @@ -461,17 +463,15 @@ CURLcode Curl_readwrite(struct Curl_easy *data) the stream was rewound (in which case we have data in a buffer) */ if((k->keepon & KEEP_RECV) && (select_bits & CURL_CSELECT_IN)) { - result = readwrite_data(data, k, &didwhat); + result = sendrecv_dl(data, k, &didwhat); if(result || data->req.done) goto out; } /* If we still have writing to do, we check if we have a writable socket. */ - if(((k->keepon & KEEP_SEND) && (select_bits & CURL_CSELECT_OUT)) || - (k->keepon & KEEP_SEND_TIMED)) { - /* write */ - - result = readwrite_upload(data, &didwhat); + if((Curl_req_want_send(data) || (data->req.keepon & KEEP_SEND_TIMED)) && + (select_bits & CURL_CSELECT_OUT)) { + result = sendrecv_ul(data, &didwhat); if(result) goto out; } @@ -479,8 +479,8 @@ CURLcode Curl_readwrite(struct Curl_easy *data) } #endif - now = Curl_now(); - if(!didwhat) { + if(select_bits && !didwhat) { + /* Transfer wanted to send/recv, but nothing was possible. */ result = Curl_conn_ev_data_idle(data); if(result) goto out; @@ -489,23 +489,23 @@ CURLcode Curl_readwrite(struct Curl_easy *data) if(Curl_pgrsUpdate(data)) result = CURLE_ABORTED_BY_CALLBACK; else - result = Curl_speedcheck(data, now); + result = Curl_speedcheck(data, *nowp); if(result) goto out; if(k->keepon) { - if(0 > Curl_timeleft(data, &now, FALSE)) { + if(0 > Curl_timeleft(data, nowp, FALSE)) { if(k->size != -1) { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(now, data->progress.t_startsingle), + failf(data, "Operation timed out after %" FMT_TIMEDIFF_T + " milliseconds with %" FMT_OFF_T " out of %" + FMT_OFF_T " bytes received", + Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount, k->size); } else { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(now, data->progress.t_startsingle), + failf(data, "Operation timed out after %" FMT_TIMEDIFF_T + " milliseconds with %" FMT_OFF_T " bytes received", + Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount); } result = CURLE_OPERATION_TIMEDOUT; @@ -518,16 +518,8 @@ CURLcode Curl_readwrite(struct Curl_easy *data) * returning. */ if(!(data->req.no_body) && (k->size != -1) && - (k->bytecount != k->size) && -#ifdef CURL_DO_LINEEND_CONV - /* Most FTP servers do not adjust their file SIZE response for CRLFs, - so we will check to see if the discrepancy can be explained - by the number of CRLFs we have changed to LFs. - */ - (k->bytecount != (k->size + data->state.crlf_conversions)) && -#endif /* CURL_DO_LINEEND_CONV */ - !k->newurl) { - failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T + (k->bytecount != k->size) && !k->newurl) { + failf(data, "transfer closed with %" FMT_OFF_T " bytes remaining to read", k->size - k->bytecount); result = CURLE_PARTIAL_FILE; goto out; @@ -544,7 +536,7 @@ CURLcode Curl_readwrite(struct Curl_easy *data) out: if(result) - DEBUGF(infof(data, "Curl_readwrite() -> %d", result)); + DEBUGF(infof(data, "Curl_sendrecv() -> %d", result)); return result; } @@ -1193,15 +1185,7 @@ CURLcode Curl_xfer_write_resp(struct Curl_easy *data, int cwtype = CLIENTWRITE_BODY; if(is_eos) cwtype |= CLIENTWRITE_EOS; - -#ifndef CURL_DISABLE_POP3 - if(blen && data->conn->handler->protocol & PROTO_FAMILY_POP3) { - result = data->req.ignorebody? CURLE_OK : - Curl_pop3_write(data, buf, blen); - } - else -#endif /* CURL_DISABLE_POP3 */ - result = Curl_client_write(data, cwtype, buf, blen); + result = Curl_client_write(data, cwtype, buf, blen); } } @@ -1233,25 +1217,35 @@ CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature) return Curl_cw_out_done(data); } +bool Curl_xfer_needs_flush(struct Curl_easy *data) +{ + int sockindex; + sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && + (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); + return Curl_conn_needs_flush(data, sockindex); +} + +CURLcode Curl_xfer_flush(struct Curl_easy *data) +{ + int sockindex; + sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && + (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); + return Curl_conn_flush(data, sockindex); +} + CURLcode Curl_xfer_send(struct Curl_easy *data, - const void *buf, size_t blen, + const void *buf, size_t blen, bool eos, size_t *pnwritten) { CURLcode result; int sockindex; - if(!data || !data->conn) - return CURLE_FAILED_INIT; - /* FIXME: would like to enable this, but some protocols (MQTT) do not - * setup the transfer correctly, it seems - if(data->conn->writesockfd == CURL_SOCKET_BAD) { - failf(data, "transfer not setup for sending"); - DEBUGASSERT(0); - return CURLE_SEND_ERROR; - } */ + DEBUGASSERT(data); + DEBUGASSERT(data->conn); + sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - result = Curl_conn_send(data, sockindex, buf, blen, pnwritten); + result = Curl_conn_send(data, sockindex, buf, blen, eos, pnwritten); if(result == CURLE_AGAIN) { result = CURLE_OK; *pnwritten = 0; @@ -1259,6 +1253,8 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, else if(!result && *pnwritten) data->info.request_size += *pnwritten; + DEBUGF(infof(data, "Curl_xfer_send(len=%zu) -> %d, %zu", + blen, result, *pnwritten)); return result; } @@ -1268,18 +1264,13 @@ CURLcode Curl_xfer_recv(struct Curl_easy *data, { int sockindex; - if(!data || !data->conn) - return CURLE_FAILED_INIT; - /* FIXME: would like to enable this, but some protocols (MQTT) do not - * setup the transfer correctly, it seems - if(data->conn->sockfd == CURL_SOCKET_BAD) { - failf(data, "transfer not setup for receiving"); - DEBUGASSERT(0); - return CURLE_RECV_ERROR; - } */ + DEBUGASSERT(data); + DEBUGASSERT(data->conn); + DEBUGASSERT(data->set.buffer_size > 0); + sockindex = ((data->conn->sockfd != CURL_SOCKET_BAD) && (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET])); - if(data->set.buffer_size > 0 && (size_t)data->set.buffer_size < blen) + if((size_t)data->set.buffer_size < blen) blen = (size_t)data->set.buffer_size; return Curl_conn_recv(data, sockindex, buf, blen, pnrcvd); } @@ -1290,18 +1281,6 @@ CURLcode Curl_xfer_send_close(struct Curl_easy *data) return CURLE_OK; } -CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) -{ - int sockindex; - - if(!data || !data->conn) - return CURLE_FAILED_INIT; - if(data->conn->writesockfd == CURL_SOCKET_BAD) - return CURLE_FAILED_INIT; - sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_conn_shutdown(data, sockindex, done); -} - bool Curl_xfer_is_blocked(struct Curl_easy *data) { bool want_send = ((data)->req.keepon & KEEP_SEND); diff --git a/lib/transfer.h b/lib/transfer.h index 21ad25962..8d6f98d75 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -44,7 +44,7 @@ typedef enum { CURLcode Curl_follow(struct Curl_easy *data, char *newurl, followtype type); -CURLcode Curl_readwrite(struct Curl_easy *data); +CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp); int Curl_single_getsock(struct Curl_easy *data, struct connectdata *conn, curl_socket_t *socks); CURLcode Curl_retry_request(struct Curl_easy *data, char **url); @@ -113,13 +113,24 @@ void Curl_xfer_setup2(struct Curl_easy *data, */ CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature); +/** + * Return TRUE iff transfer has pending data to send. Checks involved + * connection filters. + */ +bool Curl_xfer_needs_flush(struct Curl_easy *data); + +/** + * Flush any pending send data on the transfer connection. + */ +CURLcode Curl_xfer_flush(struct Curl_easy *data); + /** * Send data on the socket/connection filter designated * for transfer's outgoing data. * Will return CURLE_OK on blocking with (*pnwritten == 0). */ CURLcode Curl_xfer_send(struct Curl_easy *data, - const void *buf, size_t blen, + const void *buf, size_t blen, bool eos, size_t *pnwritten); /** diff --git a/lib/url.c b/lib/url.c index 914b5b653..57aeb7c96 100644 --- a/lib/url.c +++ b/lib/url.c @@ -234,8 +234,6 @@ CURLcode Curl_close(struct Curl_easy **datap) data = *datap; *datap = NULL; - Curl_expire_clear(data); /* shut off timers */ - /* Detach connection if any is left. This should not be normal, but can be the case for example with CONNECT_ONLY + recv/send (test 556) */ Curl_detach_connection(data); @@ -253,6 +251,8 @@ CURLcode Curl_close(struct Curl_easy **datap) } } + Curl_expire_clear(data); /* shut off any timers left */ + data->magic = 0; /* force a clear AFTER the possibly enforced removal from the multi handle, since that function uses the magic field! */ @@ -266,7 +266,6 @@ CURLcode Curl_close(struct Curl_easy **datap) /* Close down all open SSL info and sessions */ Curl_ssl_close_all(data); Curl_safefree(data->state.first_host); - Curl_safefree(data->state.scratch); Curl_ssl_free_certinfo(data); if(data->state.referer_alloc) { @@ -415,8 +414,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->new_file_perms = 0644; /* Default permissions */ set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL; - set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | - CURLPROTO_FTPS; + set->redir_protocols = CURLPROTO_REDIR; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* @@ -537,9 +535,16 @@ CURLcode Curl_open(struct Curl_easy **curl) data->state.recent_conn_id = -1; /* and not assigned an id yet */ data->id = -1; + data->mid = -1; +#ifndef CURL_DISABLE_DOH + data->set.dohfor_mid = -1; +#endif data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ +#ifndef CURL_DISABLE_HTTP + Curl_llist_init(&data->state.httphdrs, NULL); +#endif } if(result) { @@ -552,7 +557,6 @@ CURLcode Curl_open(struct Curl_easy **curl) } else *curl = data; - return result; } @@ -593,13 +597,14 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) #ifdef USE_UNIX_SOCKETS Curl_safefree(conn->unix_domain_socket); #endif + Curl_safefree(conn->destination); free(conn); /* free all the connection oriented data */ } /* * Disconnects the given connection. Note the connection may not be the - * primary connection, like when freeing room in the connection cache or + * primary connection, like when freeing room in the connection pool or * killing of a dead old connection. * * A connection needs an easy handle when closing down. We support this passed @@ -609,14 +614,14 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) * This function MUST NOT reset state in the Curl_easy struct if that * is not strictly bound to the life-time of *this* particular connection. */ -void Curl_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool aborted) +bool Curl_on_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool aborted) { /* there must be a connection to close */ DEBUGASSERT(conn); - /* it must be removed from the connection cache */ - DEBUGASSERT(!conn->bundle); + /* it must be removed from the connection pool */ + DEBUGASSERT(!conn->bits.in_cpool); /* there must be an associated transfer */ DEBUGASSERT(data); @@ -624,23 +629,11 @@ void Curl_disconnect(struct Curl_easy *data, /* the transfer must be detached from the connection */ DEBUGASSERT(!data->conn); - DEBUGF(infof(data, "Curl_disconnect(conn #%" - CURL_FORMAT_CURL_OFF_T ", aborted=%d)", + DEBUGF(infof(data, "Curl_disconnect(conn #%" FMT_OFF_T ", aborted=%d)", conn->connection_id, aborted)); - /* - * If this connection is not marked to force-close, leave it open if there - * are other users of it - */ - if(CONN_INUSE(conn) && !aborted) { - DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn))); - return; - } - - if(conn->dns_entry) { - Curl_resolv_unlock(data, conn->dns_entry); - conn->dns_entry = NULL; - } + if(conn->dns_entry) + Curl_resolv_unlink(data, &conn->dns_entry); /* Cleanup NTLM connection-related data */ Curl_http_auth_cleanup_ntlm(conn); @@ -652,30 +645,28 @@ void Curl_disconnect(struct Curl_easy *data, /* treat the connection as aborted in CONNECT_ONLY situations */ aborted = TRUE; - Curl_conncache_disconnect(data, conn, aborted); + return aborted; } /* - * IsMultiplexingPossible() + * Curl_xfer_may_multiplex() * - * Return a bitmask with the available multiplexing options for the given - * requested connection. + * Return a TRUE, iff the transfer can be done over an (appropriate) + * multiplexed connection. */ -static int IsMultiplexingPossible(const struct Curl_easy *handle, - const struct connectdata *conn) +static bool Curl_xfer_may_multiplex(const struct Curl_easy *data, + const struct connectdata *conn) { - int avail = 0; - /* If an HTTP protocol and multiplexing is enabled */ if((conn->handler->protocol & PROTO_FAMILY_HTTP) && (!conn->bits.protoconnstart || !conn->bits.close)) { - if(Curl_multiplex_wanted(handle->multi) && - (handle->state.httpwant >= CURL_HTTP_VERSION_2)) - /* allows HTTP/2 */ - avail |= CURLPIPE_MULTIPLEX; + if(Curl_multiplex_wanted(data->multi) && + (data->state.httpwant >= CURL_HTTP_VERSION_2)) + /* allows HTTP/2 or newer */ + return TRUE; } - return avail; + return FALSE; } #ifndef CURL_DISABLE_PROXY @@ -729,7 +720,7 @@ static bool conn_maxage(struct Curl_easy *data, idletime /= 1000; /* integer seconds is fine */ if(idletime > data->set.maxage_conn) { - infof(data, "Too old connection (%" CURL_FORMAT_TIMEDIFF_T + infof(data, "Too old connection (%" FMT_TIMEDIFF_T " seconds idle), disconnect it", idletime); return TRUE; } @@ -739,7 +730,7 @@ static bool conn_maxage(struct Curl_easy *data, if(data->set.maxlifetime_conn && lifetime > data->set.maxlifetime_conn) { infof(data, - "Too old connection (%" CURL_FORMAT_TIMEDIFF_T + "Too old connection (%" FMT_TIMEDIFF_T " seconds since creation), disconnect it", lifetime); return TRUE; } @@ -749,23 +740,24 @@ static bool conn_maxage(struct Curl_easy *data, } /* - * This function checks if the given connection is dead and prunes it from - * the connection cache if so. - * - * When this is called as a Curl_conncache_foreach() callback, the connection - * cache lock is held! - * - * Returns TRUE if the connection was dead and pruned. + * Return TRUE iff the given connection is considered dead. */ -static bool prune_if_dead(struct connectdata *conn, - struct Curl_easy *data) +bool Curl_conn_seems_dead(struct connectdata *conn, + struct Curl_easy *data, + struct curltime *pnow) { + DEBUGASSERT(!data->conn); if(!CONN_INUSE(conn)) { /* The check for a dead socket makes sense only if the connection is not in use */ bool dead; - struct curltime now = Curl_now(); - if(conn_maxage(data, conn, now)) { + struct curltime now; + if(!pnow) { + now = Curl_now(); + pnow = &now; + } + + if(conn_maxage(data, conn, *pnow)) { /* avoid check if already too old */ dead = TRUE; } @@ -805,64 +797,40 @@ static bool prune_if_dead(struct connectdata *conn, } if(dead) { - /* remove connection from cache */ - infof(data, "Connection %" CURL_FORMAT_CURL_OFF_T " seems to be dead", + /* remove connection from cpool */ + infof(data, "Connection %" FMT_OFF_T " seems to be dead", conn->connection_id); - Curl_conncache_remove_conn(data, conn, FALSE); return TRUE; } } return FALSE; } -/* - * Wrapper to use prune_if_dead() function in Curl_conncache_foreach() - * - */ -static int call_prune_if_dead(struct Curl_easy *data, - struct connectdata *conn, void *param) +CURLcode Curl_conn_upkeep(struct Curl_easy *data, + struct connectdata *conn, + struct curltime *now) { - struct connectdata **pruned = (struct connectdata **)param; - if(prune_if_dead(conn, data)) { - /* stop the iteration here, pass back the connection that was pruned */ - *pruned = conn; - return 1; - } - return 0; /* continue iteration */ -} - -/* - * This function scans the connection cache for half-open/dead connections, - * closes and removes them. The cleanup is done at most once per second. - * - * When called, this transfer has no connection attached. - */ -static void prune_dead_connections(struct Curl_easy *data) -{ - struct curltime now = Curl_now(); - timediff_t elapsed; - - DEBUGASSERT(!data->conn); /* no connection */ - CONNCACHE_LOCK(data); - elapsed = - Curl_timediff(now, data->state.conn_cache->last_cleanup); - CONNCACHE_UNLOCK(data); - - if(elapsed >= 1000L) { - struct connectdata *pruned = NULL; - while(Curl_conncache_foreach(data, data->state.conn_cache, &pruned, - call_prune_if_dead)) { - /* unlocked */ - - /* connection previously removed from cache in prune_if_dead() */ + CURLcode result = CURLE_OK; + if(Curl_timediff(*now, conn->keepalive) <= data->set.upkeep_interval_ms) + return result; - /* disconnect it, do not treat as aborted */ - Curl_disconnect(data, pruned, FALSE); - } - CONNCACHE_LOCK(data); - data->state.conn_cache->last_cleanup = now; - CONNCACHE_UNLOCK(data); + /* briefly attach for action */ + Curl_attach_connection(data, conn); + if(conn->handler->connection_check) { + /* Do a protocol-specific keepalive check on the connection. */ + unsigned int rc; + rc = conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE); + if(rc & CONNRESULT_DEAD) + result = CURLE_RECV_ERROR; + } + else { + /* Do the generic action on the FIRSTSOCKET filter chain */ + result = Curl_conn_keep_alive(data, conn, FIRSTSOCKET); } + Curl_detach_connection(data); + + conn->keepalive = *now; + return result; } #ifdef USE_SSH @@ -876,425 +844,420 @@ static bool ssh_config_matches(struct connectdata *one, #define ssh_config_matches(x,y) FALSE #endif -/* - * Given one filled in connection struct (named needle), this function should - * detect if there already is one that has all the significant details - * exactly the same and thus should be used instead. - * - * If there is a match, this function returns TRUE - and has marked the - * connection as 'in-use'. It must later be called with ConnectionDone() to - * return back to 'idle' (unused) state. - * - * The force_reuse flag is set if the connection must be used. - */ -static bool -ConnectionExists(struct Curl_easy *data, - struct connectdata *needle, - struct connectdata **usethis, - bool *force_reuse, - bool *waitpipe) +struct url_conn_match { + struct connectdata *found; + struct Curl_easy *data; + struct connectdata *needle; + BIT(may_multiplex); + BIT(want_ntlm_http); + BIT(want_proxy_ntlm_http); + + BIT(wait_pipe); + BIT(force_reuse); + BIT(seen_pending_conn); + BIT(seen_single_use_conn); + BIT(seen_multiplex_conn); +}; + +static bool url_match_conn(struct connectdata *conn, void *userdata) { - struct connectdata *chosen = NULL; - bool foundPendingCandidate = FALSE; - bool canmultiplex = FALSE; - struct connectbundle *bundle; - struct Curl_llist_element *curr; + struct url_conn_match *match = userdata; + struct Curl_easy *data = match->data; + struct connectdata *needle = match->needle; -#ifdef USE_NTLM - bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) && - (needle->handler->protocol & PROTO_FAMILY_HTTP)); -#ifndef CURL_DISABLE_PROXY - bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && - ((data->state.authproxy.want & - CURLAUTH_NTLM) && - (needle->handler->protocol & PROTO_FAMILY_HTTP))); -#else - bool wantProxyNTLMhttp = FALSE; -#endif -#endif - /* plain HTTP with upgrade */ - bool h2upgrade = (data->state.httpwant == CURL_HTTP_VERSION_2_0) && - (needle->handler->protocol & CURLPROTO_HTTP); + /* Check if `conn` can be used for transfer `data` */ - *usethis = NULL; - *force_reuse = FALSE; - *waitpipe = FALSE; + if(conn->connect_only || conn->bits.close) + /* connect-only or to-be-closed connections will not be reused */ + return FALSE; - /* Look up the bundle with all the connections to this particular host. - Locks the connection cache, beware of early returns! */ - bundle = Curl_conncache_find_bundle(data, needle, data->state.conn_cache); - if(!bundle) { - CONNCACHE_UNLOCK(data); + if(data->set.ipver != CURL_IPRESOLVE_WHATEVER + && data->set.ipver != conn->ip_version) { + /* skip because the connection is not via the requested IP version */ return FALSE; } - infof(data, "Found bundle for host: %p [%s]", - (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? - "can multiplex" : "serially")); - - /* We can only multiplex iff the transfer allows it AND we know - * that the server we want to talk to supports it as well. */ - canmultiplex = FALSE; - if(IsMultiplexingPossible(data, needle)) { - if(bundle->multiuse == BUNDLE_UNKNOWN) { - if(data->set.pipewait) { - infof(data, "Server does not support multiplex yet, wait"); - *waitpipe = TRUE; - CONNCACHE_UNLOCK(data); - return FALSE; /* no reuse */ - } - infof(data, "Server does not support multiplex (yet)"); - } - else if(bundle->multiuse == BUNDLE_MULTIPLEX) { - if(Curl_multiplex_wanted(data->multi)) - canmultiplex = TRUE; - else - infof(data, "Could multiplex, but not asked to"); - } - else if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { - infof(data, "Can not multiplex, even if we wanted to"); - } - } - - curr = bundle->conn_list.head; - while(curr) { - struct connectdata *check = curr->ptr; - /* Get next node now. We might remove a dead `check` connection which - * would invalidate `curr` as well. */ - curr = curr->next; - /* Note that if we use an HTTP proxy in normal mode (no tunneling), we - * check connections to that proxy and not to the actual remote server. - */ - if(check->connect_only || check->bits.close) - /* connect-only or to-be-closed connections will not be reused */ - continue; + if(needle->localdev || needle->localport) { + /* If we are bound to a specific local end (IP+port), we must not + reuse a random other one, although if we did not ask for a + particular one we can reuse one that was bound. + + This comparison is a bit rough and too strict. Since the input + parameters can be specified in numerous ways and still end up the + same it would take a lot of processing to make it really accurate. + Instead, this matching will assume that reuses of bound connections + will most likely also reuse the exact same binding parameters and + missing out a few edge cases should not hurt anyone very much. + */ + if((conn->localport != needle->localport) || + (conn->localportrange != needle->localportrange) || + (needle->localdev && + (!conn->localdev || strcmp(conn->localdev, needle->localdev)))) + return FALSE; + } + + if(needle->bits.conn_to_host != conn->bits.conn_to_host) + /* do not mix connections that use the "connect to host" feature and + * connections that do not use this feature */ + return FALSE; - if(data->set.ipver != CURL_IPRESOLVE_WHATEVER - && data->set.ipver != check->ip_version) { - /* skip because the connection is not via the requested IP version */ - continue; - } + if(needle->bits.conn_to_port != conn->bits.conn_to_port) + /* do not mix connections that use the "connect to port" feature and + * connections that do not use this feature */ + return FALSE; - if(!canmultiplex) { - if(Curl_resolver_asynch() && - /* remote_ip[0] is NUL only if the resolving of the name has not - completed yet and until then we do not reuse this connection */ - !check->primary.remote_ip[0]) - continue; + if(!Curl_conn_is_connected(conn, FIRSTSOCKET) || + conn->bits.asks_multiplex) { + /* Not yet connected, or not yet decided if it multiplexes. The later + * happens for HTTP/2 Upgrade: requests that need a response. */ + if(match->may_multiplex) { + match->seen_pending_conn = TRUE; + /* Do not pick a connection that has not connected yet */ + infof(data, "Connection #%" FMT_OFF_T + " is not open enough, cannot reuse", conn->connection_id); } + /* Do not pick a connection that has not connected yet */ + return FALSE; + } + /* `conn` is connected. If it has transfers, can we add ours to it? */ - if(CONN_INUSE(check)) { - if(!canmultiplex) { - /* transfer cannot be multiplexed and check is in use */ - continue; - } - else { - /* Could multiplex, but not when check belongs to another multi */ - struct Curl_llist_element *e = check->easyq.head; - struct Curl_easy *entry = e->ptr; - if(entry->multi != data->multi) - continue; - } + if(CONN_INUSE(conn)) { + if(!conn->bits.multiplex) { + /* conn busy and conn cannot take more transfers */ + match->seen_single_use_conn = TRUE; + return FALSE; } - - if(!Curl_conn_is_connected(check, FIRSTSOCKET)) { - foundPendingCandidate = TRUE; - /* Do not pick a connection that has not connected yet */ - infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T - " is not open enough, cannot reuse", check->connection_id); - continue; + match->seen_multiplex_conn = TRUE; + if(!match->may_multiplex) + /* conn busy and transfer cannot be multiplexed */ + return FALSE; + else { + /* transfer and conn multiplex. Are they on the same multi? */ + struct Curl_llist_node *e = Curl_llist_head(&conn->easyq); + struct Curl_easy *entry = Curl_node_elem(e); + if(entry->multi != data->multi) + return FALSE; } + } + /* `conn` is connected and we could add the transfer to it, if + * all the other criteria do match. */ - /* `check` is connected. if it is in use and does not support multiplex, - * we cannot use it. */ - if(!check->bits.multiplex && CONN_INUSE(check)) - continue; - + /* Does `conn` use the correct protocol? */ #ifdef USE_UNIX_SOCKETS - if(needle->unix_domain_socket) { - if(!check->unix_domain_socket) - continue; - if(strcmp(needle->unix_domain_socket, check->unix_domain_socket)) - continue; - if(needle->bits.abstract_unix_socket != - check->bits.abstract_unix_socket) - continue; - } - else if(check->unix_domain_socket) - continue; -#endif - - if((needle->handler->flags&PROTOPT_SSL) != - (check->handler->flags&PROTOPT_SSL)) - /* do not do mixed SSL and non-SSL connections */ - if(get_protocol_family(check->handler) != - needle->handler->protocol || !check->bits.tls_upgraded) - /* except protocols that have been upgraded via TLS */ - continue; - - if(needle->bits.conn_to_host != check->bits.conn_to_host) - /* do not mix connections that use the "connect to host" feature and - * connections that do not use this feature */ - continue; - - if(needle->bits.conn_to_port != check->bits.conn_to_port) - /* do not mix connections that use the "connect to port" feature and - * connections that do not use this feature */ - continue; + if(needle->unix_domain_socket) { + if(!conn->unix_domain_socket) + return FALSE; + if(strcmp(needle->unix_domain_socket, conn->unix_domain_socket)) + return FALSE; + if(needle->bits.abstract_unix_socket != conn->bits.abstract_unix_socket) + return FALSE; + } + else if(conn->unix_domain_socket) + return FALSE; +#endif + + if((needle->handler->flags&PROTOPT_SSL) != + (conn->handler->flags&PROTOPT_SSL)) + /* do not do mixed SSL and non-SSL connections */ + if(get_protocol_family(conn->handler) != + needle->handler->protocol || !conn->bits.tls_upgraded) + /* except protocols that have been upgraded via TLS */ + return FALSE; #ifndef CURL_DISABLE_PROXY - if(needle->bits.httpproxy != check->bits.httpproxy || - needle->bits.socksproxy != check->bits.socksproxy) - continue; - - if(needle->bits.socksproxy && - !socks_proxy_info_matches(&needle->socks_proxy, - &check->socks_proxy)) - continue; - - if(needle->bits.httpproxy) { - if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy) - continue; - - if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy)) - continue; - - if(IS_HTTPS_PROXY(needle->http_proxy.proxytype)) { - /* https proxies come in different types, http/1.1, h2, ... */ - if(needle->http_proxy.proxytype != check->http_proxy.proxytype) - continue; - /* match SSL config to proxy */ - if(!Curl_ssl_conn_config_match(data, check, TRUE)) { - DEBUGF(infof(data, - "Connection #%" CURL_FORMAT_CURL_OFF_T - " has different SSL proxy parameters, cannot reuse", - check->connection_id)); - continue; - } - /* the SSL config to the server, which may apply here is checked - * further below */ + if(needle->bits.httpproxy != conn->bits.httpproxy || + needle->bits.socksproxy != conn->bits.socksproxy) + return FALSE; + + if(needle->bits.socksproxy && + !socks_proxy_info_matches(&needle->socks_proxy, + &conn->socks_proxy)) + return FALSE; + + if(needle->bits.httpproxy) { + if(needle->bits.tunnel_proxy != conn->bits.tunnel_proxy) + return FALSE; + + if(!proxy_info_matches(&needle->http_proxy, &conn->http_proxy)) + return FALSE; + + if(IS_HTTPS_PROXY(needle->http_proxy.proxytype)) { + /* https proxies come in different types, http/1.1, h2, ... */ + if(needle->http_proxy.proxytype != conn->http_proxy.proxytype) + return FALSE; + /* match SSL config to proxy */ + if(!Curl_ssl_conn_config_match(data, conn, TRUE)) { + DEBUGF(infof(data, + "Connection #%" FMT_OFF_T + " has different SSL proxy parameters, cannot reuse", + conn->connection_id)); + return FALSE; } + /* the SSL config to the server, which may apply here is checked + * further below */ } + } #endif - if(h2upgrade && !check->httpversion && canmultiplex) { - if(data->set.pipewait) { - infof(data, "Server upgrade does not support multiplex yet, wait"); - *waitpipe = TRUE; - CONNCACHE_UNLOCK(data); - return FALSE; /* no reuse */ - } - infof(data, "Server upgrade cannot be used"); - continue; /* cannot be used atm */ - } - - if(needle->localdev || needle->localport) { - /* If we are bound to a specific local end (IP+port), we must not - reuse a random other one, although if we did not ask for a - particular one we can reuse one that was bound. - - This comparison is a bit rough and too strict. Since the input - parameters can be specified in numerous ways and still end up the - same it would take a lot of processing to make it really accurate. - Instead, this matching will assume that reuses of bound connections - will most likely also reuse the exact same binding parameters and - missing out a few edge cases should not hurt anyone very much. - */ - if((check->localport != needle->localport) || - (check->localportrange != needle->localportrange) || - (needle->localdev && - (!check->localdev || strcmp(check->localdev, needle->localdev)))) - continue; - } - - if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { - /* This protocol requires credentials per connection, - so verify that we are using the same name and password as well */ - if(Curl_timestrcmp(needle->user, check->user) || - Curl_timestrcmp(needle->passwd, check->passwd) || - Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) || - Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) { - /* one of them was different */ - continue; - } + if(match->may_multiplex && + (data->state.httpwant == CURL_HTTP_VERSION_2_0) && + (needle->handler->protocol & CURLPROTO_HTTP) && + !conn->httpversion) { + if(data->set.pipewait) { + infof(data, "Server upgrade does not support multiplex yet, wait"); + match->found = NULL; + match->wait_pipe = TRUE; + return TRUE; /* stop searching, we want to wait */ } + infof(data, "Server upgrade cannot be used"); + return FALSE; + } - /* GSS delegation differences do not actually affect every connection - and auth method, but this check takes precaution before efficiency */ - if(needle->gssapi_delegation != check->gssapi_delegation) - continue; + if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { + /* This protocol requires credentials per connection, + so verify that we are using the same name and password as well */ + if(Curl_timestrcmp(needle->user, conn->user) || + Curl_timestrcmp(needle->passwd, conn->passwd) || + Curl_timestrcmp(needle->sasl_authzid, conn->sasl_authzid) || + Curl_timestrcmp(needle->oauth_bearer, conn->oauth_bearer)) { + /* one of them was different */ + return FALSE; + } + } - /* If looking for HTTP and the HTTP version we want is less - * than the HTTP version of the check connection, continue looking */ - if((needle->handler->protocol & PROTO_FAMILY_HTTP) && - (((check->httpversion >= 20) && - (data->state.httpwant < CURL_HTTP_VERSION_2_0)) - || ((check->httpversion >= 30) && - (data->state.httpwant < CURL_HTTP_VERSION_3)))) - continue; + /* GSS delegation differences do not actually affect every connection + and auth method, but this check takes precaution before efficiency */ + if(needle->gssapi_delegation != conn->gssapi_delegation) + return FALSE; + + /* If looking for HTTP and the HTTP version we want is less + * than the HTTP version of conn, continue looking */ + if((needle->handler->protocol & PROTO_FAMILY_HTTP) && + (((conn->httpversion >= 20) && + (data->state.httpwant < CURL_HTTP_VERSION_2_0)) + || ((conn->httpversion >= 30) && + (data->state.httpwant < CURL_HTTP_VERSION_3)))) + return FALSE; #ifdef USE_SSH - else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) { - if(!ssh_config_matches(needle, check)) - continue; - } + else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) { + if(!ssh_config_matches(needle, conn)) + return FALSE; + } #endif #ifndef CURL_DISABLE_FTP - else if(get_protocol_family(needle->handler) & PROTO_FAMILY_FTP) { - /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ - if(Curl_timestrcmp(needle->proto.ftpc.account, - check->proto.ftpc.account) || - Curl_timestrcmp(needle->proto.ftpc.alternative_to_user, - check->proto.ftpc.alternative_to_user) || - (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) || - (needle->proto.ftpc.ccc != check->proto.ftpc.ccc)) - continue; - } + else if(get_protocol_family(needle->handler) & PROTO_FAMILY_FTP) { + /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ + if(Curl_timestrcmp(needle->proto.ftpc.account, + conn->proto.ftpc.account) || + Curl_timestrcmp(needle->proto.ftpc.alternative_to_user, + conn->proto.ftpc.alternative_to_user) || + (needle->proto.ftpc.use_ssl != conn->proto.ftpc.use_ssl) || + (needle->proto.ftpc.ccc != conn->proto.ftpc.ccc)) + return FALSE; + } #endif - /* Additional match requirements if talking TLS OR - * not talking to an HTTP proxy OR using a tunnel through a proxy */ - if((needle->handler->flags&PROTOPT_SSL) + /* Additional match requirements if talking TLS OR + * not talking to an HTTP proxy OR using a tunnel through a proxy */ + if((needle->handler->flags&PROTOPT_SSL) #ifndef CURL_DISABLE_PROXY - || !needle->bits.httpproxy || needle->bits.tunnel_proxy -#endif - ) { - /* Talking the same protocol scheme or a TLS upgraded protocol in the - * same protocol family? */ - if(!strcasecompare(needle->handler->scheme, check->handler->scheme) && - (get_protocol_family(check->handler) != - needle->handler->protocol || !check->bits.tls_upgraded)) - continue; - - /* If needle has "conn_to_*" set, check must match this */ - if((needle->bits.conn_to_host && !strcasecompare( - needle->conn_to_host.name, check->conn_to_host.name)) || - (needle->bits.conn_to_port && - needle->conn_to_port != check->conn_to_port)) - continue; - - /* hostname and port must match */ - if(!strcasecompare(needle->host.name, check->host.name) || - needle->remote_port != check->remote_port) - continue; - - /* If talking TLS, check needs to use the same SSL options. */ - if((needle->handler->flags & PROTOPT_SSL) && - !Curl_ssl_conn_config_match(data, check, FALSE)) { - DEBUGF(infof(data, - "Connection #%" CURL_FORMAT_CURL_OFF_T - " has different SSL parameters, cannot reuse", - check->connection_id)); - continue; - } + || !needle->bits.httpproxy || needle->bits.tunnel_proxy +#endif + ) { + /* Talking the same protocol scheme or a TLS upgraded protocol in the + * same protocol family? */ + if(!strcasecompare(needle->handler->scheme, conn->handler->scheme) && + (get_protocol_family(conn->handler) != + needle->handler->protocol || !conn->bits.tls_upgraded)) + return FALSE; + + /* If needle has "conn_to_*" set, conn must match this */ + if((needle->bits.conn_to_host && !strcasecompare( + needle->conn_to_host.name, conn->conn_to_host.name)) || + (needle->bits.conn_to_port && + needle->conn_to_port != conn->conn_to_port)) + return FALSE; + + /* hostname and port must match */ + if(!strcasecompare(needle->host.name, conn->host.name) || + needle->remote_port != conn->remote_port) + return FALSE; + + /* If talking TLS, conn needs to use the same SSL options. */ + if((needle->handler->flags & PROTOPT_SSL) && + !Curl_ssl_conn_config_match(data, conn, FALSE)) { + DEBUGF(infof(data, + "Connection #%" FMT_OFF_T + " has different SSL parameters, cannot reuse", + conn->connection_id)); + return FALSE; } + } #if defined(USE_NTLM) - /* If we are looking for an HTTP+NTLM connection, check if this is - already authenticating with the right credentials. If not, keep - looking so that we can reuse NTLM connections if - possible. (Especially we must not reuse the same connection if - partway through a handshake!) */ - if(wantNTLMhttp) { - if(Curl_timestrcmp(needle->user, check->user) || - Curl_timestrcmp(needle->passwd, check->passwd)) { - - /* we prefer a credential match, but this is at least a connection - that can be reused and "upgraded" to NTLM */ - if(check->http_ntlm_state == NTLMSTATE_NONE) - chosen = check; - continue; - } - } - else if(check->http_ntlm_state != NTLMSTATE_NONE) { - /* Connection is using NTLM auth but we do not want NTLM */ - continue; - } + /* If we are looking for an HTTP+NTLM connection, check if this is + already authenticating with the right credentials. If not, keep + looking so that we can reuse NTLM connections if + possible. (Especially we must not reuse the same connection if + partway through a handshake!) */ + if(match->want_ntlm_http) { + if(Curl_timestrcmp(needle->user, conn->user) || + Curl_timestrcmp(needle->passwd, conn->passwd)) { + + /* we prefer a credential match, but this is at least a connection + that can be reused and "upgraded" to NTLM */ + if(conn->http_ntlm_state == NTLMSTATE_NONE) + match->found = conn; + return FALSE; + } + } + else if(conn->http_ntlm_state != NTLMSTATE_NONE) { + /* Connection is using NTLM auth but we do not want NTLM */ + return FALSE; + } #ifndef CURL_DISABLE_PROXY - /* Same for Proxy NTLM authentication */ - if(wantProxyNTLMhttp) { - /* Both check->http_proxy.user and check->http_proxy.passwd can be - * NULL */ - if(!check->http_proxy.user || !check->http_proxy.passwd) - continue; - - if(Curl_timestrcmp(needle->http_proxy.user, - check->http_proxy.user) || - Curl_timestrcmp(needle->http_proxy.passwd, - check->http_proxy.passwd)) - continue; - } - else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { - /* Proxy connection is using NTLM auth but we do not want NTLM */ - continue; - } -#endif - if(wantNTLMhttp || wantProxyNTLMhttp) { - /* Credentials are already checked, we may use this connection. - * With NTLM being weird as it is, we MUST use a - * connection where it has already been fully negotiated. - * If it has not, we keep on looking for a better one. */ - chosen = check; - - if((wantNTLMhttp && - (check->http_ntlm_state != NTLMSTATE_NONE)) || - (wantProxyNTLMhttp && - (check->proxy_ntlm_state != NTLMSTATE_NONE))) { - /* We must use this connection, no other */ - *force_reuse = TRUE; - break; - } - /* Continue look up for a better connection */ - continue; + /* Same for Proxy NTLM authentication */ + if(match->want_proxy_ntlm_http) { + /* Both conn->http_proxy.user and conn->http_proxy.passwd can be + * NULL */ + if(!conn->http_proxy.user || !conn->http_proxy.passwd) + return FALSE; + + if(Curl_timestrcmp(needle->http_proxy.user, + conn->http_proxy.user) || + Curl_timestrcmp(needle->http_proxy.passwd, + conn->http_proxy.passwd)) + return FALSE; + } + else if(conn->proxy_ntlm_state != NTLMSTATE_NONE) { + /* Proxy connection is using NTLM auth but we do not want NTLM */ + return FALSE; + } +#endif + if(match->want_ntlm_http || match->want_proxy_ntlm_http) { + /* Credentials are already checked, we may use this connection. + * With NTLM being weird as it is, we MUST use a + * connection where it has already been fully negotiated. + * If it has not, we keep on looking for a better one. */ + match->found = conn; + + if((match->want_ntlm_http && + (conn->http_ntlm_state != NTLMSTATE_NONE)) || + (match->want_proxy_ntlm_http && + (conn->proxy_ntlm_state != NTLMSTATE_NONE))) { + /* We must use this connection, no other */ + match->force_reuse = TRUE; + return TRUE; } + /* Continue look up for a better connection */ + return FALSE; + } #endif - if(CONN_INUSE(check)) { - DEBUGASSERT(canmultiplex); - DEBUGASSERT(check->bits.multiplex); - /* If multiplexed, make sure we do not go over concurrency limit */ - if(CONN_INUSE(check) >= - Curl_multi_max_concurrent_streams(data->multi)) { - infof(data, "client side MAX_CONCURRENT_STREAMS reached" - ", skip (%zu)", CONN_INUSE(check)); - continue; - } - if(CONN_INUSE(check) >= - Curl_conn_get_max_concurrent(data, check, FIRSTSOCKET)) { - infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)", - CONN_INUSE(check)); - continue; - } - /* When not multiplexed, we have a match here! */ - infof(data, "Multiplexed connection found"); + if(CONN_INUSE(conn)) { + DEBUGASSERT(match->may_multiplex); + DEBUGASSERT(conn->bits.multiplex); + /* If multiplexed, make sure we do not go over concurrency limit */ + if(CONN_INUSE(conn) >= + Curl_multi_max_concurrent_streams(data->multi)) { + infof(data, "client side MAX_CONCURRENT_STREAMS reached" + ", skip (%zu)", CONN_INUSE(conn)); + return FALSE; } - else if(prune_if_dead(check, data)) { - /* disconnect it, do not treat as aborted */ - Curl_disconnect(data, check, FALSE); - continue; + if(CONN_INUSE(conn) >= + Curl_conn_get_max_concurrent(data, conn, FIRSTSOCKET)) { + infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)", + CONN_INUSE(conn)); + return FALSE; } + /* When not multiplexed, we have a match here! */ + infof(data, "Multiplexed connection found"); + } + else if(Curl_conn_seems_dead(conn, data, NULL)) { + /* removed and disconnect. Do not treat as aborted. */ + Curl_cpool_disconnect(data, conn, FALSE); + return FALSE; + } - /* We have found a connection. Let's stop searching. */ - chosen = check; - break; - } /* loop over connection bundle */ + /* We have found a connection. Let's stop searching. */ + match->found = conn; + return TRUE; +} - if(chosen) { - /* mark it as used before releasing the lock */ - Curl_attach_connection(data, chosen); - CONNCACHE_UNLOCK(data); - *usethis = chosen; - return TRUE; /* yes, we found one to use! */ +static bool url_match_result(bool result, void *userdata) +{ + struct url_conn_match *match = userdata; + (void)result; + if(match->found) { + /* Attach it now while still under lock, so the connection does + * no longer appear idle and can be reaped. */ + Curl_attach_connection(match->data, match->found); + return TRUE; } - CONNCACHE_UNLOCK(data); - - if(foundPendingCandidate && data->set.pipewait) { - infof(data, + else if(match->seen_single_use_conn && !match->seen_multiplex_conn) { + /* We've seen a single-use, existing connection to the destination and + * no multiplexed one. It seems safe to assume that the server does + * not support multiplexing. */ + match->wait_pipe = FALSE; + } + else if(match->seen_pending_conn && match->data->set.pipewait) { + infof(match->data, "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set"); - *waitpipe = TRUE; + match->wait_pipe = TRUE; } + match->force_reuse = FALSE; + return FALSE; +} - return FALSE; /* no matching connecting exists */ +/* + * Given one filled in connection struct (named needle), this function should + * detect if there already is one that has all the significant details + * exactly the same and thus should be used instead. + * + * If there is a match, this function returns TRUE - and has marked the + * connection as 'in-use'. It must later be called with ConnectionDone() to + * return back to 'idle' (unused) state. + * + * The force_reuse flag is set if the connection must be used. + */ +static bool +ConnectionExists(struct Curl_easy *data, + struct connectdata *needle, + struct connectdata **usethis, + bool *force_reuse, + bool *waitpipe) +{ + struct url_conn_match match; + bool result; + + memset(&match, 0, sizeof(match)); + match.data = data; + match.needle = needle; + match.may_multiplex = Curl_xfer_may_multiplex(data, needle); + +#ifdef USE_NTLM + match.want_ntlm_http = ((data->state.authhost.want & CURLAUTH_NTLM) && + (needle->handler->protocol & PROTO_FAMILY_HTTP)); +#ifndef CURL_DISABLE_PROXY + match.want_proxy_ntlm_http = + (needle->bits.proxy_user_passwd && + (data->state.authproxy.want & CURLAUTH_NTLM) && + (needle->handler->protocol & PROTO_FAMILY_HTTP)); +#endif +#endif + + /* Find a connection in the pool that matches what "data + needle" + * requires. If a suitable candidate is found, it is attached to "data". */ + result = Curl_cpool_find(data, needle->destination, needle->destination_len, + url_match_conn, url_match_result, &match); + + /* wait_pipe is TRUE if we encounter a bundle that is undecided. There + * is no matching connection then, yet. */ + *usethis = match.found; + *force_reuse = match.force_reuse; + *waitpipe = match.wait_pipe; + return result; } /* @@ -1967,7 +1930,7 @@ static CURLcode setup_range(struct Curl_easy *data) free(s->range); if(s->resume_from) - s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from); + s->range = aprintf("%" FMT_OFF_T "-", s->resume_from); else s->range = strdup(data->set.str[STRING_SET_RANGE]); @@ -1999,6 +1962,8 @@ static CURLcode setup_connection_internals(struct Curl_easy *data, struct connectdata *conn) { const struct Curl_handler *p; + const char *hostname; + int port; CURLcode result; /* Perform setup complement if some. */ @@ -2018,6 +1983,34 @@ static CURLcode setup_connection_internals(struct Curl_easy *data, was very likely already set to the proxy port */ conn->primary.remote_port = p->defport; + /* Now create the destination name */ +#ifndef CURL_DISABLE_PROXY + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + hostname = conn->http_proxy.host.name; + port = conn->primary.remote_port; + } + else +#endif + { + port = conn->remote_port; + if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else + hostname = conn->host.name; + } + +#ifdef USE_IPV6 + conn->destination = aprintf("%u/%d/%s", conn->scope_id, port, hostname); +#else + conn->destination = aprintf("%d/%s", port, hostname); +#endif + if(!conn->destination) + return CURLE_OUT_OF_MEMORY; + + conn->destination_len = strlen(conn->destination) + 1; + Curl_strntolower(conn->destination, conn->destination, + conn->destination_len - 1); + return CURLE_OK; } @@ -2341,7 +2334,7 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data, return result; } -/* create_conn helper to parse and init proxy values. to be called after unix +/* create_conn helper to parse and init proxy values. to be called after Unix socket init but before any proxy vars are evaluated. */ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, struct connectdata *conn) @@ -2408,7 +2401,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, Curl_safefree(no_proxy); #ifdef USE_UNIX_SOCKETS - /* For the time being do not mix proxy and unix domain sockets. See #1274 */ + /* For the time being do not mix proxy and Unix domain sockets. See #1274 */ if(proxy && conn->unix_domain_socket) { free(proxy); proxy = NULL; @@ -3101,140 +3094,82 @@ static CURLcode resolve_unix(struct Curl_easy *data, return longpath ? CURLE_COULDNT_RESOLVE_HOST : CURLE_OUT_OF_MEMORY; } - hostaddr->inuse++; + hostaddr->refcount = 1; /* connection is the only one holding this */ conn->dns_entry = hostaddr; return CURLE_OK; } #endif -#ifndef CURL_DISABLE_PROXY -static CURLcode resolve_proxy(struct Curl_easy *data, - struct connectdata *conn, - bool *async) +/************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ +static CURLcode resolve_server(struct Curl_easy *data, + struct connectdata *conn, + bool *async) { - struct Curl_dns_entry *hostaddr = NULL; - struct hostname *host; + struct hostname *ehost; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const char *peertype = "host"; int rc; +#ifdef USE_UNIX_SOCKETS + char *unix_path = conn->unix_domain_socket; - DEBUGASSERT(conn->dns_entry == NULL); - - host = conn->bits.socksproxy ? &conn->socks_proxy.host : - &conn->http_proxy.host; - - conn->hostname_resolve = strdup(host->name); - if(!conn->hostname_resolve) - return CURLE_OUT_OF_MEMORY; +#ifndef CURL_DISABLE_PROXY + if(!unix_path && CONN_IS_PROXIED(conn) && conn->socks_proxy.host.name && + !strncmp(UNIX_SOCKET_PREFIX"/", + conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) + unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; +#endif - rc = Curl_resolv_timeout(data, conn->hostname_resolve, - conn->primary.remote_port, &hostaddr, timeout_ms); - conn->dns_entry = hostaddr; - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - else if(rc == CURLRESOLV_TIMEDOUT) - return CURLE_OPERATION_TIMEDOUT; - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", host->dispname); - return CURLE_COULDNT_RESOLVE_PROXY; + if(unix_path) { + /* TODO, this only works if previous transport is TRNSPRT_TCP. Check it? */ + conn->transport = TRNSPRT_UNIX; + return resolve_unix(data, conn, unix_path); } - - return CURLE_OK; -} #endif -static CURLcode resolve_host(struct Curl_easy *data, - struct connectdata *conn, - bool *async) -{ - struct Curl_dns_entry *hostaddr = NULL; - struct hostname *connhost; - timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - int rc; - DEBUGASSERT(conn->dns_entry == NULL); - connhost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host; - - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - conn->primary.remote_port = conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port; +#ifndef CURL_DISABLE_PROXY + if(CONN_IS_PROXIED(conn)) { + ehost = conn->bits.socksproxy ? &conn->socks_proxy.host : + &conn->http_proxy.host; + peertype = "proxy"; + } + else +#endif + { + ehost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host; + /* If not connecting via a proxy, extract the port from the URL, if it is + * there, thus overriding any defaults that might have been set above. */ + conn->primary.remote_port = conn->bits.conn_to_port ? conn->conn_to_port : + conn->remote_port; + } /* Resolve target host right on */ - conn->hostname_resolve = strdup(connhost->name); + conn->hostname_resolve = strdup(ehost->name); if(!conn->hostname_resolve) return CURLE_OUT_OF_MEMORY; rc = Curl_resolv_timeout(data, conn->hostname_resolve, - conn->primary.remote_port, &hostaddr, timeout_ms); - conn->dns_entry = hostaddr; + conn->primary.remote_port, + &conn->dns_entry, timeout_ms); if(rc == CURLRESOLV_PENDING) *async = TRUE; else if(rc == CURLRESOLV_TIMEDOUT) { - failf(data, "Failed to resolve host '%s' with timeout after %" - CURL_FORMAT_TIMEDIFF_T " ms", connhost->dispname, + failf(data, "Failed to resolve %s '%s' with timeout after %" + FMT_TIMEDIFF_T " ms", peertype, ehost->dispname, Curl_timediff(Curl_now(), data->progress.t_startsingle)); return CURLE_OPERATION_TIMEDOUT; } - else if(!hostaddr) { - failf(data, "Could not resolve host: %s", connhost->dispname); + else if(!conn->dns_entry) { + failf(data, "Could not resolve %s: %s", peertype, ehost->dispname); return CURLE_COULDNT_RESOLVE_HOST; } return CURLE_OK; } -/* Perform a fresh resolve */ -static CURLcode resolve_fresh(struct Curl_easy *data, - struct connectdata *conn, - bool *async) -{ -#ifdef USE_UNIX_SOCKETS - char *unix_path = conn->unix_domain_socket; - -#ifndef CURL_DISABLE_PROXY - if(!unix_path && conn->socks_proxy.host.name && - !strncmp(UNIX_SOCKET_PREFIX"/", - conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) - unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; -#endif - - if(unix_path) { - conn->transport = TRNSPRT_UNIX; - return resolve_unix(data, conn, unix_path); - } -#endif - -#ifndef CURL_DISABLE_PROXY - if(CONN_IS_PROXIED(conn)) - return resolve_proxy(data, conn, async); -#endif - - return resolve_host(data, conn, async); -} - -/************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ -static CURLcode resolve_server(struct Curl_easy *data, - struct connectdata *conn, - bool *async) -{ - DEBUGASSERT(conn); - DEBUGASSERT(data); - - /* Resolve the name of the server or proxy */ - if(conn->bits.reuse) { - /* We are reusing the connection - no need to resolve anything, and - idnconvert_hostname() was called already in create_conn() for the reuse - case. */ - *async = FALSE; - return CURLE_OK; - } - - return resolve_fresh(data, conn, async); -} - /* * Cleanup the connection `temp`, just allocated for `data`, before using the * previously `existing` one for `data`. All relevant info is copied over @@ -3275,7 +3210,7 @@ static void reuse_conn(struct Curl_easy *data, } #endif - /* Finding a connection for reuse in the cache matches, among other + /* Finding a connection for reuse in the cpool matches, among other * things on the "remote-relevant" hostname. This is not necessarily * the authority of the URL, e.g. conn->host. For example: * - we use a proxy (not tunneling). we want to send all requests @@ -3337,8 +3272,6 @@ static CURLcode create_conn(struct Curl_easy *data, bool connections_available = TRUE; bool force_reuse = FALSE; bool waitpipe = FALSE; - size_t max_host_connections = Curl_multi_max_host_connections(data->multi); - size_t max_total_connections = Curl_multi_max_total_connections(data->multi); *async = FALSE; *in_connect = NULL; @@ -3398,7 +3331,7 @@ static CURLcode create_conn(struct Curl_easy *data, } #endif - /* After the unix socket init but before the proxy vars are used, parse and + /* After the Unix socket init but before the proxy vars are used, parse and initialize the proxy vars */ #ifndef CURL_DISABLE_PROXY result = create_conn_helper_init_proxy(data, conn); @@ -3503,13 +3436,15 @@ static CURLcode create_conn(struct Curl_easy *data, /* this is supposed to be the connect function so we better at least check that the file is present here! */ DEBUGASSERT(conn->handler->connect_it); - Curl_persistconninfo(data, conn, NULL); + data->info.conn_scheme = conn->handler->scheme; + /* conn_protocol can only provide "old" protocols */ + data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK; result = conn->handler->connect_it(data, &done); /* Setup a "faked" transfer that will do nothing */ if(!result) { Curl_attach_connection(data, conn); - result = Curl_conncache_add_conn(data); + result = Curl_cpool_add_conn(data, conn); if(result) goto out; @@ -3545,7 +3480,8 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; - prune_dead_connections(data); + /* FIXME: do we really want to run this every time we add a transfer? */ + Curl_cpool_prune_dead(data); /************************************************************* * Check the current list of connections to see if we can @@ -3604,43 +3540,14 @@ static CURLcode create_conn(struct Curl_easy *data, "soon", and we wait for that */ connections_available = FALSE; else { - /* this gets a lock on the conncache */ - struct connectbundle *bundle = - Curl_conncache_find_bundle(data, conn, data->state.conn_cache); - - if(max_host_connections > 0 && bundle && - (bundle->num_connections >= max_host_connections)) { - struct connectdata *conn_candidate; - - /* The bundle is full. Extract the oldest connection. */ - conn_candidate = Curl_conncache_extract_bundle(data, bundle); - CONNCACHE_UNLOCK(data); - - if(conn_candidate) - Curl_disconnect(data, conn_candidate, FALSE); - else { - infof(data, "No more connections allowed to host: %zu", - max_host_connections); - connections_available = FALSE; - } - } - else - CONNCACHE_UNLOCK(data); - - } - - if(connections_available && - (max_total_connections > 0) && - (Curl_conncache_size(data) >= max_total_connections)) { - struct connectdata *conn_candidate; - - /* The cache is full. Let's see if we can kill a connection. */ - conn_candidate = Curl_conncache_extract_oldest(data); - if(conn_candidate) - Curl_disconnect(data, conn_candidate, FALSE); - else + switch(Curl_cpool_check_limits(data, conn)) { + case CPOOL_LIMIT_DEST: + infof(data, "No more connections allowed to host"); + connections_available = FALSE; + break; + case CPOOL_LIMIT_TOTAL: #ifndef CURL_DISABLE_DOH - if(data->set.dohfor) + if(data->set.dohfor_mid >= 0) infof(data, "Allowing DoH to override max connection limit"); else #endif @@ -3648,6 +3555,10 @@ static CURLcode create_conn(struct Curl_easy *data, infof(data, "No connections available in cache"); connections_available = FALSE; } + break; + default: + break; + } } if(!connections_available) { @@ -3671,7 +3582,7 @@ static CURLcode create_conn(struct Curl_easy *data, } Curl_attach_connection(data, conn); - result = Curl_conncache_add_conn(data); + result = Curl_cpool_add_conn(data, conn); if(result) goto out; } @@ -3708,16 +3619,35 @@ static CURLcode create_conn(struct Curl_easy *data, /* Continue connectdata initialization here. */ - /************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ - result = resolve_server(data, conn, async); - if(result) - goto out; + if(conn->bits.reuse) { + /* We are reusing the connection - no need to resolve anything, and + idnconvert_hostname() was called already in create_conn() for the reuse + case. */ + *async = FALSE; + } + else { + /************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ + result = resolve_server(data, conn, async); + if(result) + goto out; + } + + /* persist the scheme and handler the transfer is using */ + data->info.conn_scheme = conn->handler->scheme; + /* conn_protocol can only provide "old" protocols */ + data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK; + data->info.used_proxy = +#ifdef CURL_DISABLE_PROXY + 0 +#else + conn->bits.proxy +#endif + ; /* Everything general done, inform filters that they need - * to prepare for a data transfer. - */ + * to prepare for a data transfer. */ result = Curl_conn_ev_data_setup(data); out: @@ -3743,18 +3673,6 @@ CURLcode Curl_setup_conn(struct Curl_easy *data, return result; } -#ifndef CURL_DISABLE_PROXY - /* set proxy_connect_closed to false unconditionally already here since it - is used strictly to provide extra information to a parent function in the - case of proxy CONNECT failures and we must make sure we do not have it - lingering set from a previous invoke */ - conn->bits.proxy_connect_closed = FALSE; -#endif - -#ifdef CURL_DO_LINEEND_CONV - data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ -#endif /* CURL_DO_LINEEND_CONV */ - /* set start time here for timeout purposes in the connect procedure, it is later set again for the progress meter purpose */ conn->now = Curl_now(); @@ -3803,8 +3721,7 @@ CURLcode Curl_connect(struct Curl_easy *data, /* We are not allowed to return failure with memory left allocated in the connectdata struct, free those here */ Curl_detach_connection(data); - Curl_conncache_remove_conn(data, conn, TRUE); - Curl_disconnect(data, conn, TRUE); + Curl_cpool_disconnect(data, conn, TRUE); } return result; diff --git a/lib/url.h b/lib/url.h index 55f9b1585..47c1db44f 100644 --- a/lib/url.h +++ b/lib/url.h @@ -37,8 +37,8 @@ void Curl_freeset(struct Curl_easy *data); CURLcode Curl_uc_to_curlcode(CURLUcode uc); CURLcode Curl_close(struct Curl_easy **datap); /* opposite of curl_open() */ CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect); -void Curl_disconnect(struct Curl_easy *data, - struct connectdata *, bool aborted); +bool Curl_on_disconnect(struct Curl_easy *data, + struct connectdata *, bool aborted); CURLcode Curl_setup_conn(struct Curl_easy *data, bool *protocol_done); void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn); @@ -65,6 +65,21 @@ void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn, int sockindex); #endif +/** + * Return TRUE iff the given connection is considered dead. + * @param nowp NULL or pointer to time being checked against. + */ +bool Curl_conn_seems_dead(struct connectdata *conn, + struct Curl_easy *data, + struct curltime *nowp); + +/** + * Perform upkeep operations on the connection. + */ +CURLcode Curl_conn_upkeep(struct Curl_easy *data, + struct connectdata *conn, + struct curltime *now); + #if defined(USE_HTTP2) || defined(USE_HTTP3) void Curl_data_priority_clear_state(struct Curl_easy *data); #else diff --git a/lib/urlapi.c b/lib/urlapi.c index b71be3847..3d4a3f94b 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -41,13 +41,13 @@ #include "curl_memory.h" #include "memdebug.h" - /* MSDOS/Windows style drive prefix, eg c: in c:foo */ + /* MS-DOS/Windows style drive prefix, eg c: in c:foo */ #define STARTS_WITH_DRIVE_PREFIX(str) \ ((('a' <= str[0] && str[0] <= 'z') || \ ('A' <= str[0] && str[0] <= 'Z')) && \ (str[1] == ':')) - /* MSDOS/Windows style drive prefix, optionally with + /* MS-DOS/Windows style drive prefix, optionally with * a '|' instead of ':', followed by a slash or NUL */ #define STARTS_WITH_URL_DRIVE_PREFIX(str) \ ((('a' <= (str)[0] && (str)[0] <= 'z') || \ @@ -1121,7 +1121,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) * This catches both "file:/c:" and "file:c:" */ if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || STARTS_WITH_URL_DRIVE_PREFIX(path)) { - /* File drive letters are only accepted in MSDOS/Windows */ + /* File drive letters are only accepted in MS-DOS/Windows */ result = CURLUE_BAD_FILE_URL; goto fail; } @@ -1991,7 +1991,23 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, /* Skip hostname check, it is allowed to be empty. */ } else { - if(!n || hostname_check(u, (char *)newp, n)) { + bool bad = FALSE; + if(!n) + bad = TRUE; /* empty hostname is not okay */ + else if(!urlencode) { + /* if the host name part was not URL encoded here, it was set ready + URL encoded so we need to decode it to check */ + size_t dlen; + char *decoded = NULL; + CURLcode result = + Curl_urldecode(newp, n, &decoded, &dlen, REJECT_CTRL); + if(result || hostname_check(u, decoded, dlen)) + bad = TRUE; + free(decoded); + } + else if(hostname_check(u, (char *)newp, n)) + bad = TRUE; + if(bad) { Curl_dyn_free(&enc); return CURLUE_BAD_HOSTNAME; } diff --git a/lib/urldata.h b/lib/urldata.h index f34aa591c..3eb7b845e 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -77,6 +77,10 @@ struct curl_trc_featt; #define CURLPROTO_WSS 0 #endif +/* the default protocols accepting a redirect to */ +#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \ + CURLPROTO_FTPS) + /* This should be undefined once we need bit 32 or higher */ #define PROTO_TYPE_SMALL @@ -159,6 +163,7 @@ typedef ssize_t (Curl_send)(struct Curl_easy *data, /* transfer */ int sockindex, /* socketindex */ const void *buf, /* data to write */ size_t len, /* max amount to write */ + bool eos, /* last chunk */ CURLcode *err); /* error to return */ /* return the count of bytes read, or -1 on error */ @@ -272,11 +277,11 @@ struct ssl_peer { char *sni; /* SNI version of hostname or NULL if not usable */ ssl_peer_type type; /* type of the peer information */ int port; /* port we are talking to */ - int transport; /* TCP or QUIC */ + int transport; /* one of TRNSPRT_* defines */ }; struct ssl_primary_config { - char *CApath; /* certificate dir (does not work on windows) */ + char *CApath; /* certificate dir (does not work on Windows) */ char *CAfile; /* certificate to verify peer against */ char *issuercert; /* optional issuer certificate filename */ char *clientcert; @@ -441,7 +446,7 @@ struct ntlmdata { unsigned int flags; unsigned char nonce[8]; unsigned int target_info_len; - void *target_info; /* TargetInfo received in the ntlm type-2 message */ + void *target_info; /* TargetInfo received in the NTLM type-2 message */ #endif }; #endif @@ -454,6 +459,7 @@ struct negotiatedata { gss_ctx_id_t context; gss_name_t spn; gss_buffer_desc output_token; + struct dynbuf channel_binding_data; #else #ifdef USE_WINDOWS_SSPI #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS @@ -495,9 +501,6 @@ struct ConnectBits { This is implicit when SSL-protocols are used through proxies, but can also be enabled explicitly by apps */ - BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection - in a CONNECT request with auth, so that - libcurl should reconnect and continue. */ BIT(proxy); /* if set, this transfer is done through a proxy - any type */ #endif /* always modify bits.close with the connclose() and connkeep() macros! */ @@ -532,6 +535,7 @@ struct ConnectBits { #endif BIT(bound); /* set true if bind() has already been done on this socket/ connection */ + BIT(asks_multiplex); /* connection asks for multiplexing, but is not yet */ BIT(multiplex); /* connection is multiplexed */ BIT(tcp_fastopen); /* use TCP Fast Open */ BIT(tls_enable_alpn); /* TLS ALPN extension? */ @@ -549,6 +553,7 @@ struct ConnectBits { BIT(aborted); /* connection was aborted, e.g. in unclean state */ BIT(shutdown_handler); /* connection shutdown: handler shut down */ BIT(shutdown_filters); /* connection shutdown: filters shut down */ + BIT(in_cpool); /* connection is kept in a connection pool */ }; struct hostname { @@ -617,27 +622,6 @@ struct easy_pollset { unsigned char actions[MAX_SOCKSPEREASYHANDLE]; }; -enum doh_slots { - /* Explicit values for first two symbols so as to match hard-coded - * constants in existing code - */ - DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */ - DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */ - - /* Space here for (possibly build-specific) additional slot definitions */ -#ifdef USE_HTTPSRR - DOH_PROBE_SLOT_HTTPS = 2, /* for HTTPS RR */ -#endif - - /* for example */ - /* #ifdef WANT_DOH_FOOBAR_TXT */ - /* DOH_PROBE_SLOT_FOOBAR_TXT, */ - /* #endif */ - - /* AFTER all slot definitions, establish how many we have */ - DOH_PROBE_SLOTS -}; - /* * Specific protocol handler. */ @@ -757,7 +741,7 @@ struct Curl_handler { HTTP proxy as HTTP proxies may know this protocol and act as a gateway */ #define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */ -#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ascii) in +#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ASCII) in username and password */ #define PROTOPT_NOTCPPROXY (1<<14) /* this protocol cannot proxy over TCP */ @@ -796,20 +780,22 @@ struct ldapconninfo; * unique for an entire connection. */ struct connectdata { - struct Curl_llist_element bundle_node; /* conncache */ + struct Curl_llist_node cpool_node; /* conncache lists */ curl_closesocket_callback fclosesocket; /* function closing the socket(s) */ void *closesocket_client; - /* This is used by the connection cache logic. If this returns TRUE, this + /* This is used by the connection pool logic. If this returns TRUE, this handle is still used by one or more easy handles and can only used by any other easy handle without careful consideration (== only for multiplexing) and it cannot be used by another multi handle! */ -#define CONN_INUSE(c) ((c)->easyq.size) +#define CONN_INUSE(c) Curl_llist_count(&(c)->easyq) /**** Fields set when inited and not modified again */ curl_off_t connection_id; /* Contains a unique number to make it easier to track the connections in the log output */ + char *destination; /* string carrying normalized hostname+port+scope */ + size_t destination_len; /* strlen(destination) + 1 */ /* 'dns_entry' is the particular host we use. This points to an entry in the DNS cache and it will not get pruned while locked. It gets unlocked in @@ -831,7 +817,8 @@ struct connectdata { struct proxy_info http_proxy; #endif /* 'primary' and 'secondary' get filled with IP quadruple - (local/remote numerical ip address and port) whenever a is *attempted*. + (local/remote numerical ip address and port) whenever a connect is + *attempted*. When more than one address is tried for a connection these will hold data for the last attempt. When the connection is actually established these are updated with data which comes directly from the socket. */ @@ -844,7 +831,7 @@ struct connectdata { char *oauth_bearer; /* OAUTH2 bearer, allocated */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ - struct curltime lastused; /* when returned to the connection cache */ + struct curltime lastused; /* when returned to the connection poolas idle */ curl_socket_t sock[2]; /* two sockets, the second is used for the data transfer when doing FTP */ Curl_recv *recv[2]; @@ -964,7 +951,6 @@ struct connectdata { unsigned int unused:1; /* avoids empty union */ } proto; - struct connectbundle *bundle; /* The bundle we are member of */ #ifdef USE_UNIX_SOCKETS char *unix_domain_socket; #endif @@ -1043,7 +1029,7 @@ struct PureInfo { even when the session handle is no longer associated with a connection, and also allow curl_easy_reset() to clear this information from the session handle without disturbing information which is still alive, and - that might be reused, in the connection cache. */ + that might be reused, in the connection pool. */ struct ip_quadruple primary; int conn_remote_port; /* this is the "remote port", which is the port number of the used URL, independent of proxy or @@ -1058,14 +1044,23 @@ struct PureInfo { BIT(used_proxy); /* the transfer used a proxy */ }; +struct pgrs_measure { + struct curltime start; /* when measure started */ + curl_off_t start_size; /* the 'cur_size' the measure started at */ +}; + +struct pgrs_dir { + curl_off_t total_size; /* total expected bytes */ + curl_off_t cur_size; /* transferred bytes so far */ + curl_off_t speed; /* bytes per second transferred */ + struct pgrs_measure limit; +}; struct Progress { time_t lastshow; /* time() of the last displayed progress meter or NULL to force redraw at next call */ - curl_off_t size_dl; /* total expected size */ - curl_off_t size_ul; /* total expected size */ - curl_off_t downloaded; /* transferred so far */ - curl_off_t uploaded; /* transferred so far */ + struct pgrs_dir ul; + struct pgrs_dir dl; curl_off_t current_speed; /* uses the currently fastest transfer */ @@ -1074,14 +1069,12 @@ struct Progress { timediff_t timespent; - curl_off_t dlspeed; - curl_off_t ulspeed; - timediff_t t_postqueue; timediff_t t_nslookup; timediff_t t_connect; timediff_t t_appconnect; timediff_t t_pretransfer; + timediff_t t_posttransfer; timediff_t t_starttransfer; timediff_t t_redirect; @@ -1090,14 +1083,6 @@ struct Progress { struct curltime t_startop; struct curltime t_acceptdata; - - /* upload speed limit */ - struct curltime ul_limit_start; - curl_off_t ul_limit_size; - /* download speed limit */ - struct curltime dl_limit_start; - curl_off_t dl_limit_size; - #define CURR_TIME (5 + 1) /* 6 entries for 5 seconds */ curl_off_t speeder[ CURR_TIME ]; @@ -1194,7 +1179,7 @@ typedef enum { * One instance for each timeout an easy handle can set. */ struct time_node { - struct Curl_llist_element list; + struct Curl_llist_node list; struct curltime time; expire_id eid; }; @@ -1212,8 +1197,6 @@ struct urlpieces { }; struct UrlState { - /* Points to the connection cache */ - struct conncache *conn_cache; /* buffers to store authentication data in, as parsed from input options */ struct curltime keeps_speed; /* for the progress meter really */ @@ -1238,7 +1221,6 @@ struct UrlState { struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ long sessionage; /* number of the most recent session */ int os_errno; /* filled in with errno whenever an error occurs */ - char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */ long followlocation; /* redirect counter */ int requests; /* request counter: redirects + authentication retakes */ #ifdef HAVE_SIGNAL @@ -1266,12 +1248,6 @@ struct UrlState { /* a place to store the most recently set (S)FTP entrypath */ char *most_recent_ftp_entrypath; -#if !defined(_WIN32) && !defined(MSDOS) && !defined(__EMX__) -/* do FTP line-end conversions on most platforms */ -#define CURL_DO_LINEEND_CONV - /* for FTP downloads: how many CRLFs did we converted to LFs? */ - curl_off_t crlf_conversions; -#endif char *range; /* range, if used. See README for detailed specification on this syntax. */ curl_off_t resume_from; /* continue [ftp] transfer from here */ @@ -1364,9 +1340,6 @@ struct UrlState { unsigned char select_bits; /* != 0 -> bitmask of socket events for this transfer overriding anything the socket may report */ -#ifdef DEBUGBUILD - BIT(conncache_lock); -#endif /* when curl_easy_perform() is called, the multi handle is "owned" by the easy handle so curl_easy_cleanup() on such an easy handle will also close the multi handle! */ @@ -1422,7 +1395,7 @@ enum dupstring { STRING_KEY, /* private key filename */ STRING_KEY_PASSWD, /* plain text private key password */ STRING_KEY_TYPE, /* format for private key (default: PEM) */ - STRING_SSL_CAPATH, /* CA directory name (does not work on windows) */ + STRING_SSL_CAPATH, /* CA directory name (does not work on Windows) */ STRING_SSL_CAFILE, /* certificate file to verify peer against */ STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ @@ -1436,7 +1409,7 @@ enum dupstring { STRING_KEY_PROXY, /* private key filename */ STRING_KEY_PASSWD_PROXY, /* plain text private key password */ STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ - STRING_SSL_CAPATH_PROXY, /* CA directory name (does not work on windows) */ + STRING_SSL_CAPATH_PROXY, /* CA directory name (does not work on Windows) */ STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ @@ -1493,7 +1466,7 @@ enum dupstring { #ifdef USE_SSH STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ - STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ + STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ASCII hex */ STRING_SSH_HOST_PUBLIC_KEY_SHA256, /* sha256 of host public key in base64 */ STRING_SSH_KNOWNHOSTS, /* filename of knownhosts file */ #endif @@ -1751,7 +1724,7 @@ struct UserDefined { long upkeep_interval_ms; /* Time between calls for connection upkeep. */ multidone_func fmultidone; #ifndef CURL_DISABLE_DOH - struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ + curl_off_t dohfor_mid; /* this is a DoH request for that transfer */ #endif CURLU *uh; /* URL handle for the current parsed URL */ #ifndef CURL_DISABLE_HTTP @@ -1902,22 +1875,23 @@ struct Curl_easy { /* First a simple identifier to easier detect if a user mix up this easy handle with a multi handle. Set this to CURLEASY_MAGIC_NUMBER */ unsigned int magic; - /* once an easy handle is tied to a connection cache + /* once an easy handle is tied to a connection pool a non-negative number to distinguish this transfer from - other using the same cache. For easier tracking + other using the same pool. For easier tracking in log output. This may wrap around after LONG_MAX to 0 again, so it - has no uniqueness guarantee for very large processings. */ + has no uniqueness guarantee for very large processings. + Note: it has no uniqueness either IFF more than one connection pool + is used by the libcurl application. */ curl_off_t id; - - /* first, two fields for the linked list of these */ - struct Curl_easy *next; - struct Curl_easy *prev; + /* once an easy handle is added to a multi, either explicitly by the + * libcurl application or implicitly during `curl_easy_perform()`, + * a unique identifier inside this one multi instance. */ + curl_off_t mid; struct connectdata *conn; - struct Curl_llist_element connect_queue; /* for the pending and msgsent - lists */ - struct Curl_llist_element conn_queue; /* list per connectdata */ + struct Curl_llist_node multi_queue; /* for multihandle list management */ + struct Curl_llist_node conn_queue; /* list per connectdata */ CURLMstate mstate; /* the handle's state */ CURLcode result; /* previous result */ diff --git a/lib/vauth/.checksrc b/lib/vauth/.checksrc new file mode 100644 index 000000000..9066946c8 --- /dev/null +++ b/lib/vauth/.checksrc @@ -0,0 +1,2 @@ +enable STRERROR +enable STRNCPY diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c index f00e6651f..4fc5b1c28 100644 --- a/lib/vauth/digest.c +++ b/lib/vauth/digest.c @@ -142,7 +142,7 @@ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, } #if !defined(USE_WINDOWS_SSPI) -/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string */ +/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ASCII string */ static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ unsigned char *dest) /* 33 bytes */ { @@ -151,7 +151,7 @@ static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]); } -/* Convert sha256 or SHA-512/256 chunk to RFC7616 -suitable ascii string */ +/* Convert sha256 or SHA-512/256 chunk to RFC7616 -suitable ASCII string */ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */ unsigned char *dest) /* 65 bytes */ { diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c index 181356671..39a0c306d 100644 --- a/lib/vauth/digest_sspi.c +++ b/lib/vauth/digest_sspi.c @@ -60,12 +60,13 @@ bool Curl_auth_is_digest_supported(void) SECURITY_STATUS status; /* Query the security package for Digest */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), - &SecurityPackage); + status = + Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); /* Release the package buffer as it is not required anymore */ if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); } return (status == SEC_E_OK ? TRUE : FALSE); @@ -119,8 +120,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, } /* Query the security package for DigestSSP */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), - &SecurityPackage); + status = + Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); if(status != SEC_E_OK) { failf(data, "SSPI: could not get auth info"); return CURLE_AUTH_ERROR; @@ -129,7 +131,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate our response buffer */ output_token = malloc(token_max); @@ -160,7 +162,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, p_identity = NULL; /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, + status = Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_DIGEST), SECPKG_CRED_OUTBOUND, NULL, p_identity, NULL, NULL, @@ -190,20 +192,20 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, resp_buf.cbBuffer = curlx_uztoul(token_max); /* Generate our response message */ - status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, + status = Curl_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, 0, 0, 0, &chlg_desc, 0, &context, &resp_desc, &attrs, &expiry); if(status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); + Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { #if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; #endif - s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_pSecFn->FreeCredentialsHandle(&credentials); Curl_sspi_free_identity(p_identity); free(spn); free(output_token); @@ -223,8 +225,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, Curl_bufref_set(out, output_token, resp_buf.cbBuffer, curl_free); /* Free our handles */ - s_pSecFn->DeleteSecurityContext(&context); - s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_pSecFn->DeleteSecurityContext(&context); + Curl_pSecFn->FreeCredentialsHandle(&credentials); /* Free the identity structure */ Curl_sspi_free_identity(p_identity); @@ -410,8 +412,9 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, (void) data; /* Query the security package for DigestSSP */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), - &SecurityPackage); + status = + Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); if(status != SEC_E_OK) { failf(data, "SSPI: could not get auth info"); return CURLE_AUTH_ERROR; @@ -420,7 +423,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate the output buffer according to the max token size as indicated by the security package */ @@ -436,7 +439,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, (userp && digest->user && Curl_timestrcmp(userp, digest->user)) || (passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) { if(digest->http_context) { - s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); } Curl_safefree(digest->user); @@ -463,13 +466,14 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, chlg_buf[4].pvBuffer = output_token; chlg_buf[4].cbBuffer = curlx_uztoul(token_max); - status = s_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, 0); + status = Curl_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, + 0); if(status == SEC_E_OK) output_token_len = chlg_buf[4].cbBuffer; else { /* delete the context so a new one can be made */ infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx", (long)status); - s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); } } @@ -529,7 +533,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, } /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, + status = Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_DIGEST), SECPKG_CRED_OUTBOUND, NULL, p_identity, NULL, NULL, @@ -565,7 +569,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, spn = curlx_convert_UTF8_to_tchar((char *) uripath); if(!spn) { - s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_pSecFn->FreeCredentialsHandle(&credentials); Curl_sspi_free_identity(p_identity); free(output_token); @@ -579,7 +583,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; /* Generate our response message */ - status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, + status = Curl_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, ISC_REQ_USE_HTTP_STYLE, 0, 0, &chlg_desc, 0, @@ -589,13 +593,13 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, if(status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); + Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { #if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; #endif - s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_pSecFn->FreeCredentialsHandle(&credentials); Curl_sspi_free_identity(p_identity); free(output_token); @@ -615,7 +619,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, output_token_len = resp_buf.cbBuffer; - s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_pSecFn->FreeCredentialsHandle(&credentials); Curl_sspi_free_identity(p_identity); } @@ -660,7 +664,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest) /* Delete security context */ if(digest->http_context) { - s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); } diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c index 430eb3ef0..b168a27ad 100644 --- a/lib/vauth/krb5_sspi.c +++ b/lib/vauth/krb5_sspi.c @@ -55,13 +55,13 @@ bool Curl_auth_is_gssapi_supported(void) SECURITY_STATUS status; /* Query the security package for Kerberos */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + status = Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_KERBEROS), &SecurityPackage); /* Release the package buffer as it is not required anymore */ if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); } return (status == SEC_E_OK ? TRUE : FALSE); @@ -118,7 +118,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, if(!krb5->output_token) { /* Query the security package for Kerberos */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + status = Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_KERBEROS), &SecurityPackage); if(status != SEC_E_OK) { @@ -129,7 +129,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, krb5->token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate our response buffer */ krb5->output_token = malloc(krb5->token_max); @@ -158,7 +158,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, + status = Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_KERBEROS), SECPKG_CRED_OUTBOUND, NULL, @@ -197,7 +197,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, resp_buf.cbBuffer = curlx_uztoul(krb5->token_max); /* Generate our challenge-response message */ - status = s_pSecFn->InitializeSecurityContext(krb5->credentials, + status = Curl_pSecFn->InitializeSecurityContext(krb5->credentials, chlg ? krb5->context : NULL, krb5->spn, (mutual_auth ? @@ -215,7 +215,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, return CURLE_AUTH_ERROR; if(memcmp(&context, krb5->context, sizeof(context))) { - s_pSecFn->DeleteSecurityContext(krb5->context); + Curl_pSecFn->DeleteSecurityContext(krb5->context); memcpy(krb5->context, &context, sizeof(context)); } @@ -282,7 +282,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, } /* Get our response size information */ - status = s_pSecFn->QueryContextAttributes(krb5->context, + status = Curl_pSecFn->QueryContextAttributes(krb5->context, SECPKG_ATTR_SIZES, &sizes); @@ -304,7 +304,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, input_buf[1].cbBuffer = 0; /* Decrypt the inbound challenge and obtain the qop */ - status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); + status = Curl_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); if(status != SEC_E_OK) { infof(data, "GSSAPI handshake failure (empty security message)"); return CURLE_BAD_CONTENT_ENCODING; @@ -323,7 +323,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, ((unsigned long)indata[2] << 8) | indata[3]; /* Free the challenge as it is not required anymore */ - s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); + Curl_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); /* Process the security layer */ if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { @@ -392,7 +392,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, wrap_buf[2].cbBuffer = sizes.cbBlockSize; /* Encrypt the data */ - status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT, + status = Curl_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT, &wrap_desc, 0); if(status != SEC_E_OK) { free(padding); @@ -448,14 +448,14 @@ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) { /* Free our security context */ if(krb5->context) { - s_pSecFn->DeleteSecurityContext(krb5->context); + Curl_pSecFn->DeleteSecurityContext(krb5->context); free(krb5->context); krb5->context = NULL; } /* Free our credentials handle */ if(krb5->credentials) { - s_pSecFn->FreeCredentialsHandle(krb5->credentials); + Curl_pSecFn->FreeCredentialsHandle(krb5->credentials); free(krb5->credentials); krb5->credentials = NULL; } diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c index abebdeda7..0050b4132 100644 --- a/lib/vauth/ntlm.c +++ b/lib/vauth/ntlm.c @@ -59,10 +59,6 @@ /* "NTLMSSP" signature is always in ASCII regardless of the platform */ #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" -/* The fixed hostname we provide, in order to not leak our real local host - name. Copy the name used by Firefox. */ -#define NTLM_HOSTNAME "WORKSTATION" - #if DEBUG_ME # define DEBUG_OUT(x) x static void ntlm_print_flags(FILE *handle, unsigned long flags) @@ -490,7 +486,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, unsigned char *ptr_ntresp = &ntresp[0]; unsigned char *ntlmv2resp = NULL; bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; - char host[HOSTNAME_MAX + 1] = ""; + /* The fixed hostname we provide, in order to not leak our real local host + name. Copy the name used by Firefox. */ + static const char host[] = "WORKSTATION"; const char *user; const char *domain = ""; size_t hostoff = 0; @@ -515,21 +513,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, user = userp; userlen = strlen(user); - -#ifndef NTLM_HOSTNAME - /* Get the machine's un-qualified hostname as NTLM does not like the fully - qualified domain name */ - if(Curl_gethostname(host, sizeof(host))) { - infof(data, "gethostname() failed, continuing without"); - hostlen = 0; - } - else { - hostlen = strlen(host); - } -#else - (void)msnprintf(host, sizeof(host), "%s", NTLM_HOSTNAME); - hostlen = sizeof(NTLM_HOSTNAME)-1; -#endif + hostlen = sizeof(host) - 1; if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { unsigned char ntbuffer[0x18]; diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c index 7d1d04e00..55ec8201d 100644 --- a/lib/vauth/ntlm_sspi.c +++ b/lib/vauth/ntlm_sspi.c @@ -55,12 +55,12 @@ bool Curl_auth_is_ntlm_supported(void) SECURITY_STATUS status; /* Query the security package for NTLM */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), + status = Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), &SecurityPackage); /* Release the package buffer as it is not required anymore */ if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); } return (status == SEC_E_OK ? TRUE : FALSE); @@ -103,7 +103,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, Curl_auth_cleanup_ntlm(ntlm); /* Query the security package for NTLM */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), + status = Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), &SecurityPackage); if(status != SEC_E_OK) { failf(data, "SSPI: could not get auth info"); @@ -113,7 +113,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, ntlm->token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate our output buffer */ ntlm->output_token = malloc(ntlm->token_max); @@ -141,7 +141,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, + status = Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_NTLM), SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity, NULL, NULL, @@ -167,7 +167,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max); /* Generate our type-1 message */ - status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, + status = Curl_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, NULL, 0, @@ -175,7 +175,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, &attrs, &expiry); if(status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); + Curl_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); else if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) @@ -282,7 +282,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, SEC_CHANNEL_BINDINGS channelBindings; SecPkgContext_Bindings pkgBindings; pkgBindings.Bindings = &channelBindings; - status = s_pSecFn->QueryContextAttributes( + status = Curl_pSecFn->QueryContextAttributes( ntlm->sslContext, SECPKG_ATTR_ENDPOINT_BINDINGS, &pkgBindings @@ -305,7 +305,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max); /* Generate our type-3 message */ - status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, + status = Curl_pSecFn->InitializeSecurityContext(ntlm->credentials, ntlm->context, ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, @@ -343,14 +343,14 @@ void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) { /* Free our security context */ if(ntlm->context) { - s_pSecFn->DeleteSecurityContext(ntlm->context); + Curl_pSecFn->DeleteSecurityContext(ntlm->context); free(ntlm->context); ntlm->context = NULL; } /* Free our credentials handle */ if(ntlm->credentials) { - s_pSecFn->FreeCredentialsHandle(ntlm->credentials); + Curl_pSecFn->FreeCredentialsHandle(ntlm->credentials); free(ntlm->credentials); ntlm->credentials = NULL; } diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c index 23822838b..f48d9b700 100644 --- a/lib/vauth/spnego_gssapi.c +++ b/lib/vauth/spnego_gssapi.c @@ -91,6 +91,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + gss_channel_bindings_t chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; + struct gss_channel_bindings_struct chan; (void) user; (void) password; @@ -148,13 +150,21 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, input_token.length = chlglen; } + /* Set channel binding data if available */ + if(nego->channel_binding_data.leng > 0) { + memset(&chan, 0, sizeof(struct gss_channel_bindings_struct)); + chan.application_data.length = nego->channel_binding_data.leng; + chan.application_data.value = nego->channel_binding_data.bufr; + chan_bindings = &chan; + } + /* Generate our challenge-response message */ major_status = Curl_gss_init_sec_context(data, &minor_status, &nego->context, nego->spn, &Curl_spnego_mech_oid, - GSS_C_NO_CHANNEL_BINDINGS, + chan_bindings, &input_token, &output_token, TRUE, diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c index a2c7072c5..38b26ab90 100644 --- a/lib/vauth/spnego_sspi.c +++ b/lib/vauth/spnego_sspi.c @@ -57,13 +57,13 @@ bool Curl_auth_is_spnego_supported(void) SECURITY_STATUS status; /* Query the security package for Negotiate */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + status = Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NEGOTIATE), &SecurityPackage); /* Release the package buffer as it is not required anymore */ if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); } @@ -128,7 +128,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, if(!nego->output_token) { /* Query the security package for Negotiate */ - nego->status = (DWORD)s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + nego->status = (DWORD)Curl_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NEGOTIATE), &SecurityPackage); if(nego->status != SEC_E_OK) { @@ -139,7 +139,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, nego->token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); + Curl_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate our output buffer */ nego->output_token = malloc(nego->token_max); @@ -169,7 +169,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, /* Acquire our credentials handle */ nego->status = (DWORD) - s_pSecFn->AcquireCredentialsHandle(NULL, + Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)TEXT(SP_NAME_NEGOTIATE), SECPKG_CRED_OUTBOUND, NULL, nego->p_identity, NULL, NULL, @@ -218,7 +218,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, SEC_CHANNEL_BINDINGS channelBindings; SecPkgContext_Bindings pkgBindings; pkgBindings.Bindings = &channelBindings; - nego->status = (DWORD)s_pSecFn->QueryContextAttributes( + nego->status = (DWORD)Curl_pSecFn->QueryContextAttributes( nego->sslContext, SECPKG_ATTR_ENDPOINT_BINDINGS, &pkgBindings @@ -242,16 +242,16 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, resp_buf.cbBuffer = curlx_uztoul(nego->token_max); /* Generate our challenge-response message */ - nego->status = (DWORD)s_pSecFn->InitializeSecurityContext(nego->credentials, - chlg ? nego->context : - NULL, - nego->spn, - ISC_REQ_CONFIDENTIALITY, - 0, SECURITY_NATIVE_DREP, - chlg ? &chlg_desc : NULL, - 0, nego->context, - &resp_desc, &attrs, - &expiry); + nego->status = + (DWORD)Curl_pSecFn->InitializeSecurityContext(nego->credentials, + chlg ? nego->context : NULL, + nego->spn, + ISC_REQ_CONFIDENTIALITY, + 0, SECURITY_NATIVE_DREP, + chlg ? &chlg_desc : NULL, + 0, nego->context, + &resp_desc, &attrs, + &expiry); /* Free the decoded challenge as it is not required anymore */ free(chlg); @@ -269,7 +269,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, if(nego->status == SEC_I_COMPLETE_NEEDED || nego->status == SEC_I_COMPLETE_AND_CONTINUE) { - nego->status = (DWORD)s_pSecFn->CompleteAuthToken(nego->context, + nego->status = (DWORD)Curl_pSecFn->CompleteAuthToken(nego->context, &resp_desc); if(GSS_ERROR(nego->status)) { char buffer[STRERROR_LEN]; @@ -333,14 +333,14 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) { /* Free our security context */ if(nego->context) { - s_pSecFn->DeleteSecurityContext(nego->context); + Curl_pSecFn->DeleteSecurityContext(nego->context); free(nego->context); nego->context = NULL; } /* Free our credentials handle */ if(nego->credentials) { - s_pSecFn->FreeCredentialsHandle(nego->credentials); + Curl_pSecFn->FreeCredentialsHandle(nego->credentials); free(nego->credentials); nego->credentials = NULL; } diff --git a/lib/version.c b/lib/version.c index c0d822dc8..4f6d23dc1 100644 --- a/lib/version.c +++ b/lib/version.c @@ -581,7 +581,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp) int features = 0; #if defined(USE_SSH) - static char ssh_buffer[80]; + static char ssh_buf[80]; /* 'ssh_buffer' clashes with libssh/libssh.h */ #endif #ifdef USE_SSL #ifdef CURL_WITH_MULTI_SSL @@ -622,8 +622,8 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #endif #if defined(USE_SSH) - Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer)); - version_info.libssh_version = ssh_buffer; + Curl_ssh_version(ssh_buf, sizeof(ssh_buf)); + version_info.libssh_version = ssh_buf; #endif #ifdef HAVE_BROTLI diff --git a/lib/version_win32.c b/lib/version_win32.c index 10fd0b1f1..25ec82746 100644 --- a/lib/version_win32.c +++ b/lib/version_win32.c @@ -55,7 +55,7 @@ struct OUR_OSVERSIONINFOEXW { /* * curlx_verify_windows_version() * - * This is used to verify if we are running on a specific windows version. + * This is used to verify if we are running on a specific Windows version. * * Parameters: * diff --git a/lib/version_win32.h b/lib/version_win32.h index 95c066112..95a9e7f21 100644 --- a/lib/version_win32.h +++ b/lib/version_win32.h @@ -44,7 +44,7 @@ typedef enum { PLATFORM_WINNT } PlatformIdentifier; -/* This is used to verify if we are running on a specific windows version */ +/* This is used to verify if we are running on a specific Windows version */ bool curlx_verify_windows_version(const unsigned int majorVersion, const unsigned int minorVersion, const unsigned int buildVersion, diff --git a/lib/vquic/.checksrc b/lib/vquic/.checksrc new file mode 100644 index 000000000..9066946c8 --- /dev/null +++ b/lib/vquic/.checksrc @@ -0,0 +1,2 @@ +enable STRERROR +enable STRNCPY diff --git a/lib/vquic/curl_msh3.c b/lib/vquic/curl_msh3.c index b707a6ebe..ac7865c1a 100644 --- a/lib/vquic/curl_msh3.c +++ b/lib/vquic/curl_msh3.c @@ -119,16 +119,38 @@ struct cf_msh3_ctx { struct cf_call_data call_data; struct curltime connect_started; /* time the current attempt started */ struct curltime handshake_at; /* time connect handshake finished */ - struct Curl_hash streams; /* hash `data->id` to `stream_ctx` */ + struct Curl_hash streams; /* hash `data->mid` to `stream_ctx` */ /* Flags written by msh3/msquic thread */ bool handshake_complete; bool handshake_succeeded; bool connected; + BIT(initialized); /* Flags written by curl thread */ BIT(verbose); BIT(active); }; +static void h3_stream_hash_free(void *stream); + +static void cf_msh3_ctx_init(struct cf_msh3_ctx *ctx, + const struct Curl_addrinfo *ai) +{ + DEBUGASSERT(!ctx->initialized); + Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + Curl_sock_assign_addr(&ctx->addr, ai, TRNSPRT_QUIC); + ctx->sock[SP_LOCAL] = CURL_SOCKET_BAD; + ctx->sock[SP_REMOTE] = CURL_SOCKET_BAD; + ctx->initialized = TRUE; +} + +static void cf_msh3_ctx_free(struct cf_msh3_ctx *ctx) +{ + if(ctx && ctx->initialized) { + Curl_hash_destroy(&ctx->streams); + } + free(ctx); +} + static struct cf_msh3_ctx *h3_get_msh3_ctx(struct Curl_easy *data); /* How to access `call_data` from a cf_msh3 filter */ @@ -158,7 +180,7 @@ struct stream_ctx { }; #define H3_STREAM_CTX(ctx,data) ((struct stream_ctx *)((data && ctx)? \ - Curl_hash_offt_get(&(ctx)->streams, (data)->id) : NULL)) + Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL)) static void h3_stream_ctx_free(struct stream_ctx *stream) { @@ -191,7 +213,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT); CURL_TRC_CF(data, cf, "data setup"); - if(!Curl_hash_offt_set(&ctx->streams, data->id, stream)) { + if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) { h3_stream_ctx_free(stream); return CURLE_OUT_OF_MEMORY; } @@ -207,7 +229,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) (void)cf; if(stream) { CURL_TRC_CF(data, cf, "easy handle is done"); - Curl_hash_offt_remove(&ctx->streams, data->id); + Curl_hash_offt_remove(&ctx->streams, data->mid); } } @@ -593,7 +615,8 @@ static ssize_t cf_msh3_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_msh3_ctx *ctx = cf->ctx; struct stream_ctx *stream = H3_STREAM_CTX(ctx, data); @@ -603,7 +626,6 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data, size_t nheader, i; ssize_t nwritten = -1; struct cf_call_data save; - bool eos; CF_DATA_SAVE(save, cf, data); @@ -646,21 +668,6 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data, nva[i].ValueLength = e->valuelen; } - switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: - /* known request body size or -1 */ - eos = FALSE; - break; - default: - /* there is not request body */ - eos = TRUE; - stream->upload_done = TRUE; - break; - } - CURL_TRC_CF(data, cf, "req: send %zu headers", nheader); stream->req = MsH3RequestOpen(ctx->qconn, &msh3_request_if, data, nva, nheader, @@ -813,7 +820,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, CURLcode result; bool verify; - Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + DEBUGASSERT(ctx->initialized); conn_config = Curl_ssl_cf_get_primary_config(cf); if(!conn_config) return CURLE_FAILED_INIT; @@ -904,7 +911,6 @@ static CURLcode cf_msh3_connect(struct Curl_cfilter *cf, CURL_TRC_CF(data, cf, "handshake succeeded"); cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; - cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; cf->connected = TRUE; cf->conn->alpn = CURL_HTTP_VERSION_3; *done = TRUE; @@ -940,7 +946,6 @@ static void cf_msh3_close(struct Curl_cfilter *cf, struct Curl_easy *data) MsH3ApiClose(ctx->api); ctx->api = NULL; } - Curl_hash_destroy(&ctx->streams); if(ctx->active) { /* We share our socket at cf->conn->sock[cf->sockindex] when active. @@ -979,10 +984,11 @@ static void cf_msh3_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) CF_DATA_SAVE(save, cf, data); cf_msh3_close(cf, data); - free(cf->ctx); - cf->ctx = NULL; + if(cf->ctx) { + cf_msh3_ctx_free(cf->ctx); + cf->ctx = NULL; + } /* no CF_DATA_RESTORE(cf, save); its gone */ - } static CURLcode cf_msh3_query(struct Curl_cfilter *cf, @@ -1081,9 +1087,7 @@ CURLcode Curl_cf_msh3_create(struct Curl_cfilter **pcf, result = CURLE_OUT_OF_MEMORY; goto out; } - Curl_sock_assign_addr(&ctx->addr, ai, TRNSPRT_QUIC); - ctx->sock[SP_LOCAL] = CURL_SOCKET_BAD; - ctx->sock[SP_REMOTE] = CURL_SOCKET_BAD; + cf_msh3_ctx_init(ctx, ai); result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); @@ -1091,7 +1095,7 @@ CURLcode Curl_cf_msh3_create(struct Curl_cfilter **pcf, *pcf = (!result)? cf : NULL; if(result) { Curl_safefree(cf); - Curl_safefree(ctx); + cf_msh3_ctx_free(ctx); } return result; diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index 1f67f2362..b0a100eb6 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -132,12 +132,13 @@ struct cf_ngtcp2_ctx { struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ struct dynbuf scratch; /* temp buffer for header construction */ - struct Curl_hash streams; /* hash `data->id` to `h3_stream_ctx` */ + struct Curl_hash streams; /* hash `data->mid` to `h3_stream_ctx` */ size_t max_stream_window; /* max flow window for one stream */ uint64_t max_idle_ms; /* max idle time for QUIC connection */ uint64_t used_bidi_streams; /* bidi streams we have opened */ uint64_t max_bidi_streams; /* max bidi streams we can open */ int qlogfd; + BIT(initialized); BIT(shutdown_started); /* queued shutdown packets */ }; @@ -146,6 +147,34 @@ struct cf_ngtcp2_ctx { #define CF_CTX_CALL_DATA(cf) \ ((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data +static void h3_stream_hash_free(void *stream); + +static void cf_ngtcp2_ctx_init(struct cf_ngtcp2_ctx *ctx) +{ + DEBUGASSERT(!ctx->initialized); + ctx->qlogfd = -1; + ctx->version = NGTCP2_PROTO_VER_MAX; + ctx->max_stream_window = H3_STREAM_WINDOW_SIZE; + ctx->max_idle_ms = CURL_QUIC_MAX_IDLE_MS; + Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, + H3_STREAM_POOL_SPARES); + Curl_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); + Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + ctx->initialized = TRUE; +} + +static void cf_ngtcp2_ctx_free(struct cf_ngtcp2_ctx *ctx) +{ + if(ctx && ctx->initialized) { + Curl_bufcp_free(&ctx->stream_bufcp); + Curl_dyn_free(&ctx->scratch); + Curl_hash_clean(&ctx->streams); + Curl_hash_destroy(&ctx->streams); + Curl_ssl_peer_cleanup(&ctx->peer); + } + free(ctx); +} + struct pkt_io_ctx; static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -174,7 +203,7 @@ struct h3_stream_ctx { }; #define H3_STREAM_CTX(ctx,data) ((struct h3_stream_ctx *)(\ - data? Curl_hash_offt_get(&(ctx)->streams, (data)->id) : NULL)) + data? Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL)) #define H3_STREAM_CTX_ID(ctx,id) ((struct h3_stream_ctx *)(\ Curl_hash_offt_get(&(ctx)->streams, (id)))) @@ -197,10 +226,8 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - if(!data) { - failf(data, "initialization failure, transfer not http initialized"); + if(!data) return CURLE_FAILED_INIT; - } if(stream) return CURLE_OK; @@ -216,7 +243,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, stream->sendbuf_len_in_flight = 0; Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - if(!Curl_hash_offt_set(&ctx->streams, data->id, stream)) { + if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) { h3_stream_ctx_free(stream); return CURLE_OUT_OF_MEMORY; } @@ -241,7 +268,7 @@ static void cf_ngtcp2_stream_close(struct Curl_cfilter *cf, NGHTTP3_H3_REQUEST_CANCELLED); result = cf_progress_egress(cf, data, NULL); if(result) - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cancel stream -> %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cancel stream -> %d", stream->id, result); } } @@ -252,10 +279,10 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); (void)cf; if(stream) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] easy handle is done", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] easy handle is done", stream->id); cf_ngtcp2_stream_close(cf, data, stream); - Curl_hash_offt_remove(&ctx->streams, data->id); + Curl_hash_offt_remove(&ctx->streams, data->mid); } } @@ -265,7 +292,6 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, struct h3_stream_ctx **pstream) { struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *sdata; struct h3_stream_ctx *stream; (void)cf; @@ -275,8 +301,10 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, return data; } else { + struct Curl_llist_node *e; DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn != data->conn) continue; stream = H3_STREAM_CTX(ctx, sdata); @@ -490,12 +518,12 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, if(!data) data = CF_DATA_CURRENT(cf); if(data) - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read_stream(len=%zu) -> %zd", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read_stream(len=%zu) -> %zd", stream_id, buflen, nconsumed); if(nconsumed < 0) { struct h3_stream_ctx *stream = H3_STREAM_CTX_ID(ctx, stream_id); if(data && stream) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] error on known stream, " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] error on known stream, " "reset=%d, closed=%d", stream_id, stream->reset, stream->closed); } @@ -555,8 +583,8 @@ static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags, } rv = nghttp3_conn_close_stream(ctx->h3conn, stream_id, app_error_code); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] quic close(app_error=%" - CURL_PRIu64 ") -> %d", stream_id, (curl_uint64_t)app_error_code, + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] quic close(app_error=%" + FMT_PRIu64 ") -> %d", stream_id, (curl_uint64_t)app_error_code, rv); if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { cf_ngtcp2_h3_err_set(cf, data, rv); @@ -581,7 +609,7 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t sid, (void)data; rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] reset -> %d", stream_id, rv); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reset -> %d", stream_id, rv); if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -619,8 +647,8 @@ static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn, (void)tconn; ctx->max_bidi_streams = max_streams; if(data) - CURL_TRC_CF(data, cf, "max bidi streams now %" CURL_PRIu64 - ", used %" CURL_PRIu64, (curl_uint64_t)ctx->max_bidi_streams, + CURL_TRC_CF(data, cf, "max bidi streams now %" FMT_PRIu64 + ", used %" FMT_PRIu64, (curl_uint64_t)ctx->max_bidi_streams, (curl_uint64_t)ctx->used_bidi_streams); return 0; } @@ -646,8 +674,7 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t sid, } s_data = get_stream_easy(cf, data, stream_id, &stream); if(s_data && stream && stream->quic_flow_blocked) { - CURL_TRC_CF(s_data, cf, "[%" CURL_PRId64 "] unblock quic flow", - stream_id); + CURL_TRC_CF(s_data, cf, "[%" FMT_PRId64 "] unblock quic flow", stream_id); stream->quic_flow_blocked = FALSE; h3_drain_stream(cf, s_data); } @@ -705,6 +732,11 @@ static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_encryption_level level, return 0; } +#if defined(_MSC_VER) && defined(_DLL) +# pragma warning(push) +# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ +#endif + static ngtcp2_callbacks ng_callbacks = { ngtcp2_crypto_client_initial_cb, NULL, /* recv_client_initial */ @@ -748,6 +780,10 @@ static ngtcp2_callbacks ng_callbacks = { NULL, /* early_data_rejected */ }; +#if defined(_MSC_VER) && defined(_DLL) +# pragma warning(pop) +#endif + /** * Connection maintenance like timeouts on packet ACKs etc. are done by us, not * the OS like for TCP. POLL events on the socket therefore are not @@ -858,11 +894,11 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t sid, if(stream->error3 != NGHTTP3_H3_NO_ERROR) { stream->reset = TRUE; stream->send_closed = TRUE; - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] RESET: error %" CURL_PRIu64, + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] RESET: error %" FMT_PRIu64, stream->id, stream->error3); } else { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] CLOSED", stream->id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] CLOSED", stream->id); } h3_drain_stream(cf, data); return 0; @@ -878,7 +914,7 @@ static void h3_xfer_write_resp_hd(struct Curl_cfilter *cf, if(!stream->xfer_result) { stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos); if(stream->xfer_result) - CURL_TRC_CF(data, cf, "[%"CURL_PRId64"] error %d writing %zu " + CURL_TRC_CF(data, cf, "[%"FMT_PRId64"] error %d writing %zu " "bytes of headers", stream->id, stream->xfer_result, blen); } } @@ -894,7 +930,7 @@ static void h3_xfer_write_resp(struct Curl_cfilter *cf, stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos); /* If the transfer write is errored, we do not want any more data */ if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%"CURL_PRId64"] error %d writing %zu bytes " + CURL_TRC_CF(data, cf, "[%"FMT_PRId64"] error %d writing %zu bytes " "of data", stream->id, stream->xfer_result, blen); } } @@ -917,12 +953,12 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id, h3_xfer_write_resp(cf, data, stream, (char *)buf, blen, FALSE); if(blen) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] ACK %zu bytes of DATA", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] ACK %zu bytes of DATA", stream->id, blen); ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream->id, blen); ngtcp2_conn_extend_max_offset(ctx->qconn, blen); } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] DATA len=%zu", stream->id, blen); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] DATA len=%zu", stream->id, blen); return 0; } @@ -960,7 +996,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t sid, /* add a CRLF only if we have received some headers */ h3_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), stream->closed); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] end_headers, status=%d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] end_headers, status=%d", stream_id, stream->status_code); if(stream->status_code / 100 != 1) { stream->resp_hds_complete = TRUE; @@ -1008,7 +1044,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t sid, if(!result) h3_xfer_write_resp_hd(cf, data, stream, Curl_dyn_ptr(&ctx->scratch), Curl_dyn_len(&ctx->scratch), FALSE); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] status: %s", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] status: %s", stream_id, Curl_dyn_ptr(&ctx->scratch)); if(result) { return -1; @@ -1016,7 +1052,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t sid, } else { /* store as an HTTP1-style header */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] header: %.*s: %.*s", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] header: %.*s: %.*s", stream_id, (int)h3name.len, h3name.base, (int)h3val.len, h3val.base); Curl_dyn_reset(&ctx->scratch); @@ -1049,7 +1085,7 @@ static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id, rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id, app_error_code); if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; + return NGHTTP3_ERR_CALLBACK_FAILURE; } return 0; @@ -1068,9 +1104,9 @@ static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t sid, rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, 0, stream_id, app_error_code); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] reset -> %d", stream_id, rv); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reset -> %d", stream_id, rv); if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; + return NGHTTP3_ERR_CALLBACK_FAILURE; } return 0; @@ -1163,14 +1199,13 @@ static ssize_t recv_closed_stream(struct Curl_cfilter *cf, (void)cf; if(stream->reset) { - failf(data, - "HTTP/3 stream %" CURL_PRId64 " reset by server", stream->id); + failf(data, "HTTP/3 stream %" FMT_PRId64 " reset by server", stream->id); *err = data->req.bytecount? CURLE_PARTIAL_FILE : CURLE_HTTP3; goto out; } else if(!stream->resp_hds_complete) { failf(data, - "HTTP/3 stream %" CURL_PRId64 " was closed cleanly, but before " + "HTTP/3 stream %" FMT_PRId64 " was closed cleanly, but before " "getting all response header fields, treated as error", stream->id); *err = CURLE_HTTP3; @@ -1217,7 +1252,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] xfer write failed", stream->id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id); cf_ngtcp2_stream_close(cf, data, stream); *err = stream->xfer_result; nread = -1; @@ -1242,7 +1277,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, nread = -1; } } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_recv(blen=%zu) -> %zd, %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %zd, %d", stream? stream->id : -1, blen, nread, *err); CF_DATA_RESTORE(cf, save); return nread; @@ -1275,7 +1310,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) { int rv = nghttp3_conn_resume_stream(conn, stream_id); if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; + return NGHTTP3_ERR_CALLBACK_FAILURE; } } return 0; @@ -1333,14 +1368,13 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id, } else if(!nwritten) { /* Not EOF, and nothing to give, we signal WOULDBLOCK. */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read req body -> AGAIN", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> AGAIN", stream->id); return NGHTTP3_ERR_WOULDBLOCK; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read req body -> " - "%d vecs%s with %zu (buffered=%zu, left=%" - CURL_FORMAT_CURL_OFF_T ")", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> " + "%d vecs%s with %zu (buffered=%zu, left=%" FMT_OFF_T ")", stream->id, (int)nvecs, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"", nwritten, Curl_bufq_len(&stream->sendbuf), @@ -1454,12 +1488,12 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, if(rc) { switch(rc) { case NGHTTP3_ERR_CONN_CLOSING: - CURL_TRC_CF(data, cf, "h3sid[%" CURL_PRId64 "] failed to send, " + CURL_TRC_CF(data, cf, "h3sid[%" FMT_PRId64 "] failed to send, " "connection is closing", stream->id); break; default: - CURL_TRC_CF(data, cf, "h3sid[%" CURL_PRId64 "] failed to send -> " - "%d (%s)", stream->id, rc, ngtcp2_strerror(rc)); + CURL_TRC_CF(data, cf, "h3sid[%" FMT_PRId64 "] failed to send -> " + "%d (%s)", stream->id, rc, nghttp3_strerror(rc)); break; } *err = CURLE_SEND_ERROR; @@ -1468,10 +1502,10 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, } if(Curl_trc_is_verbose(data)) { - infof(data, "[HTTP/3] [%" CURL_PRId64 "] OPENED stream for %s", + infof(data, "[HTTP/3] [%" FMT_PRId64 "] OPENED stream for %s", stream->id, data->state.url); for(i = 0; i < nheader; ++i) { - infof(data, "[HTTP/3] [%" CURL_PRId64 "] [%.*s: %.*s]", stream->id, + infof(data, "[HTTP/3] [%" FMT_PRId64 "] [%.*s: %.*s]", stream->id, (int)nva[i].namelen, nva[i].name, (int)nva[i].valuelen, nva[i].value); } @@ -1484,7 +1518,8 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, } static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); @@ -1500,6 +1535,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, pktx_init(&pktx, cf, data); *err = CURLE_OK; + (void)eos; /* TODO: use for stream EOF and block handling */ result = cf_progress_ingress(cf, data, &pktx); if(result) { *err = result; @@ -1521,7 +1557,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, stream = H3_STREAM_CTX(ctx, data); } else if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] xfer write failed", stream->id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] xfer write failed", stream->id); cf_ngtcp2_stream_close(cf, data, stream); *err = stream->xfer_result; sent = -1; @@ -1534,13 +1570,13 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, * body. This happens on 30x or 40x responses. * We silently discard the data sent, since this is not a transport * error situation. */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] discarding data" + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] discarding data" "on closed stream with response", stream->id); *err = CURLE_OK; sent = (ssize_t)len; goto out; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] send_body(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send_body(len=%zu) " "-> stream closed", stream->id, len); *err = CURLE_HTTP3; sent = -1; @@ -1554,7 +1590,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, } else { sent = Curl_bufq_write(&stream->sendbuf, buf, len, err); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_send, add to " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send, add to " "sendbuf(len=%zu) -> %zd, %d", stream->id, len, sent, *err); if(sent < 0) { @@ -1576,7 +1612,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, *err = result; sent = -1; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_send(len=%zu) -> %zd, %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %zd, %d", stream? stream->id : -1, len, sent, *err); CF_DATA_RESTORE(cf, save); return sent; @@ -1589,7 +1625,6 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf, cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; - cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); } @@ -1723,7 +1758,7 @@ static ssize_t read_pkt_to_send(void *userp, struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, x->data); DEBUGASSERT(ndatalen == -1); nghttp3_conn_block_stream(ctx->h3conn, stream_id); - CURL_TRC_CF(x->data, x->cf, "[%" CURL_PRId64 "] block quic flow", + CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] block quic flow", (curl_int64_t)stream_id); DEBUGASSERT(stream); if(stream) @@ -1960,27 +1995,22 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf, return result; } -static void cf_ngtcp2_ctx_clear(struct cf_ngtcp2_ctx *ctx) +static void cf_ngtcp2_ctx_close(struct cf_ngtcp2_ctx *ctx) { struct cf_call_data save = ctx->call_data; + if(!ctx->initialized) + return; if(ctx->qlogfd != -1) { close(ctx->qlogfd); } + ctx->qlogfd = -1; Curl_vquic_tls_cleanup(&ctx->tls); vquic_ctx_free(&ctx->q); if(ctx->h3conn) nghttp3_conn_del(ctx->h3conn); if(ctx->qconn) ngtcp2_conn_del(ctx->qconn); - Curl_bufcp_free(&ctx->stream_bufcp); - Curl_dyn_free(&ctx->scratch); - Curl_hash_clean(&ctx->streams); - Curl_hash_destroy(&ctx->streams); - Curl_ssl_peer_cleanup(&ctx->peer); - - memset(ctx, 0, sizeof(*ctx)); - ctx->qlogfd = -1; ctx->call_data = save; } @@ -2027,7 +2057,7 @@ static CURLcode cf_ngtcp2_shutdown(struct Curl_cfilter *cf, (uint8_t *)buffer, sizeof(buffer), &ctx->last_error, pktx.ts); CURL_TRC_CF(data, cf, "start shutdown(err_type=%d, err_code=%" - CURL_PRIu64 ") -> %d", ctx->last_error.type, + FMT_PRIu64 ") -> %d", ctx->last_error.type, (curl_uint64_t)ctx->last_error.error_code, (int)nwritten); if(nwritten > 0) { Curl_bufq_write(&ctx->q.sendbuf, (const unsigned char *)buffer, @@ -2085,7 +2115,7 @@ static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data) CF_DATA_SAVE(save, cf, data); if(ctx && ctx->qconn) { cf_ngtcp2_conn_close(cf, data); - cf_ngtcp2_ctx_clear(ctx); + cf_ngtcp2_ctx_close(ctx); CURL_TRC_CF(data, cf, "close"); } cf->connected = FALSE; @@ -2094,18 +2124,11 @@ static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data) static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); CURL_TRC_CF(data, cf, "destroy"); - if(ctx) { - cf_ngtcp2_ctx_clear(ctx); - free(ctx); + if(cf->ctx) { + cf_ngtcp2_ctx_free(cf->ctx); + cf->ctx = NULL; } - cf->ctx = NULL; - /* No CF_DATA_RESTORE(cf, save) possible */ - (void)save; } #ifdef USE_OPENSSL @@ -2187,14 +2210,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, const struct Curl_sockaddr_ex *sockaddr = NULL; int qfd; - ctx->version = NGTCP2_PROTO_VER_MAX; - ctx->max_stream_window = H3_STREAM_WINDOW_SIZE; - ctx->max_idle_ms = CURL_QUIC_MAX_IDLE_MS; - Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, - H3_STREAM_POOL_SPARES); - Curl_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); - Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); - + DEBUGASSERT(ctx->initialized); result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC); if(result) return result; @@ -2389,7 +2405,7 @@ static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf, } else /* transport params not arrived yet? take our default. */ *pres1 = (int)Curl_multi_max_concurrent_streams(data->multi); - CURL_TRC_CF(data, cf, "query conn[%" CURL_FORMAT_CURL_OFF_T "]: " + CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " "MAX_CONCURRENT -> %d (%zu in use)", cf->conn->connection_id, *pres1, CONN_INUSE(cf->conn)); CF_DATA_RESTORE(cf, save); @@ -2509,8 +2525,7 @@ CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, result = CURLE_OUT_OF_MEMORY; goto out; } - ctx->qlogfd = -1; - cf_ngtcp2_ctx_clear(ctx); + cf_ngtcp2_ctx_init(ctx); result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); if(result) @@ -2531,7 +2546,7 @@ CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, if(udp_cf) Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE); Curl_safefree(cf); - Curl_safefree(ctx); + cf_ngtcp2_ctx_free(ctx); } return result; } diff --git a/lib/vquic/curl_osslq.c b/lib/vquic/curl_osslq.c index dafde44f2..ffe3ca0c1 100644 --- a/lib/vquic/curl_osslq.c +++ b/lib/vquic/curl_osslq.c @@ -290,9 +290,10 @@ struct cf_osslq_ctx { struct curltime first_byte_at; /* when first byte was recvd */ struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ - struct Curl_hash streams; /* hash `data->id` to `h3_stream_ctx` */ + struct Curl_hash streams; /* hash `data->mid` to `h3_stream_ctx` */ size_t max_stream_window; /* max flow window for one stream */ uint64_t max_idle_ms; /* max idle time for QUIC connection */ + BIT(initialized); BIT(got_first_byte); /* if first byte was received */ BIT(x509_store_setup); /* if x509 store has been set up */ BIT(protocol_shutdown); /* QUIC connection is shut down */ @@ -300,19 +301,35 @@ struct cf_osslq_ctx { BIT(need_send); /* QUIC connection needs to send */ }; -static void cf_osslq_ctx_clear(struct cf_osslq_ctx *ctx) +static void h3_stream_hash_free(void *stream); + +static void cf_osslq_ctx_init(struct cf_osslq_ctx *ctx) +{ + DEBUGASSERT(!ctx->initialized); + Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, + H3_STREAM_POOL_SPARES); + Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + ctx->initialized = TRUE; +} + +static void cf_osslq_ctx_free(struct cf_osslq_ctx *ctx) +{ + if(ctx && ctx->initialized) { + Curl_bufcp_free(&ctx->stream_bufcp); + Curl_hash_clean(&ctx->streams); + Curl_hash_destroy(&ctx->streams); + Curl_ssl_peer_cleanup(&ctx->peer); + } + free(ctx); +} + +static void cf_osslq_ctx_close(struct cf_osslq_ctx *ctx) { struct cf_call_data save = ctx->call_data; cf_osslq_h3conn_cleanup(&ctx->h3); Curl_vquic_tls_cleanup(&ctx->tls); vquic_ctx_free(&ctx->q); - Curl_bufcp_free(&ctx->stream_bufcp); - Curl_hash_clean(&ctx->streams); - Curl_hash_destroy(&ctx->streams); - Curl_ssl_peer_cleanup(&ctx->peer); - - memset(ctx, 0, sizeof(*ctx)); ctx->call_data = save; } @@ -401,7 +418,7 @@ static void cf_osslq_close(struct Curl_cfilter *cf, struct Curl_easy *data) (SSL_SHUTDOWN_FLAG_NO_BLOCK | SSL_SHUTDOWN_FLAG_RAPID), NULL, 0); } - cf_osslq_ctx_clear(ctx); + cf_osslq_ctx_close(ctx); } cf->connected = FALSE; @@ -417,8 +434,9 @@ static void cf_osslq_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) CURL_TRC_CF(data, cf, "destroy"); if(ctx) { CURL_TRC_CF(data, cf, "cf_osslq_destroy()"); - cf_osslq_ctx_clear(ctx); - free(ctx); + if(ctx->tls.ossl.ssl) + cf_osslq_ctx_close(ctx); + cf_osslq_ctx_free(ctx); } cf->ctx = NULL; /* No CF_DATA_RESTORE(cf, save) possible */ @@ -435,7 +453,7 @@ static CURLcode cf_osslq_h3conn_add_stream(struct cf_osslq_h3conn *h3, if(h3->remote_ctrl_n >= ARRAYSIZE(h3->remote_ctrl)) { /* rejected, we are full */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] rejecting remote stream", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] rejecting remote stream", stream_id); SSL_free(stream_ssl); return CURLE_FAILED_INIT; @@ -446,12 +464,12 @@ static CURLcode cf_osslq_h3conn_add_stream(struct cf_osslq_h3conn *h3, nstream->id = stream_id; nstream->ssl = stream_ssl; Curl_bufq_initp(&nstream->recvbuf, &ctx->stream_bufcp, 1, BUFQ_OPT_NONE); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] accepted remote uni stream", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] accepted remote uni stream", stream_id); break; } default: - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] reject remote non-uni-read" + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reject remote non-uni-read" " stream", stream_id); SSL_free(stream_ssl); return CURLE_FAILED_INIT; @@ -546,7 +564,6 @@ static CURLcode cf_osslq_verify_peer(struct Curl_cfilter *cf, cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; - cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); } @@ -573,7 +590,7 @@ struct h3_stream_ctx { }; #define H3_STREAM_CTX(ctx,data) ((struct h3_stream_ctx *)(\ - data? Curl_hash_offt_get(&(ctx)->streams, (data)->id) : NULL)) + data? Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL)) static void h3_stream_ctx_free(struct h3_stream_ctx *stream) { @@ -596,10 +613,8 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - if(!data) { - failf(data, "initialization failure, transfer not http initialized"); + if(!data) return CURLE_FAILED_INIT; - } if(stream) return CURLE_OK; @@ -620,7 +635,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, stream->recv_buf_nonflow = 0; Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - if(!Curl_hash_offt_set(&ctx->streams, data->id, stream)) { + if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) { h3_stream_ctx_free(stream); return CURLE_OUT_OF_MEMORY; } @@ -635,7 +650,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) (void)cf; if(stream) { - CURL_TRC_CF(data, cf, "[%"CURL_PRId64"] easy handle is done", + CURL_TRC_CF(data, cf, "[%"FMT_PRId64"] easy handle is done", stream->s.id); if(ctx->h3.conn && !stream->closed) { nghttp3_conn_shutdown_stream_read(ctx->h3.conn, stream->s.id); @@ -645,7 +660,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) stream->closed = TRUE; } - Curl_hash_offt_remove(&ctx->streams, data->id); + Curl_hash_offt_remove(&ctx->streams, data->mid); } } @@ -655,7 +670,6 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf, { struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - struct Curl_easy *sdata; if(stream && stream->s.id == stream_id) { return &stream->s; @@ -670,8 +684,10 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf, return &ctx->h3.s_qpack_dec; } else { + struct Curl_llist_node *e; DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn != data->conn) continue; stream = H3_STREAM_CTX(ctx, sdata); @@ -732,11 +748,11 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, if(stream->error3 != NGHTTP3_H3_NO_ERROR) { stream->reset = TRUE; stream->send_closed = TRUE; - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] RESET: error %" CURL_PRIu64, + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] RESET: error %" FMT_PRIu64, stream->s.id, stream->error3); } else { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] CLOSED", stream->s.id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] CLOSED", stream->s.id); } h3_drain_stream(cf, data); return 0; @@ -796,12 +812,12 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id, result = write_resp_raw(cf, data, buf, buflen, TRUE); if(result) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] DATA len=%zu, ERROR %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] DATA len=%zu, ERROR %d", stream->s.id, buflen, result); return NGHTTP3_ERR_CALLBACK_FAILURE; } stream->download_recvd += (curl_off_t)buflen; - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] DATA len=%zu, total=%zd", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] DATA len=%zu, total=%zd", stream->s.id, buflen, stream->download_recvd); h3_drain_stream(cf, data); return 0; @@ -819,7 +835,7 @@ static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id, (void)conn; (void)stream_id; if(stream) - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] deferred consume %zu bytes", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] deferred consume %zu bytes", stream->s.id, consumed); return 0; } @@ -857,7 +873,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t sid, return -1; ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", stream->status_code); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] status: %s", stream_id, line); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] status: %s", stream_id, line); result = write_resp_raw(cf, data, line, ncopy, FALSE); if(result) { return -1; @@ -865,7 +881,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t sid, } else { /* store as an HTTP1-style header */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] header: %.*s: %.*s", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] header: %.*s: %.*s", stream_id, (int)h3name.len, h3name.base, (int)h3val.len, h3val.base); result = write_resp_raw(cf, data, h3name.base, h3name.len, FALSE); @@ -910,7 +926,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t sid, return -1; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] end_headers, status=%d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] end_headers, status=%d", stream_id, stream->status_code); if(stream->status_code / 100 != 1) { stream->resp_hds_complete = TRUE; @@ -934,7 +950,7 @@ static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t sid, if(!stream || !stream->s.ssl) return 0; - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] stop_sending", stream_id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] stop_sending", stream_id); cf_osslq_stream_close(&stream->s); return 0; } @@ -954,7 +970,7 @@ static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t sid, SSL_STREAM_RESET_ARGS args = {0}; args.quic_error_code = app_error_code; rv = !SSL_stream_reset(stream->s.ssl, &args, sizeof(args)); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] reset -> %d", stream_id, rv); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] reset -> %d", stream_id, rv); if(!rv) { return NGHTTP3_ERR_CALLBACK_FAILURE; } @@ -1014,14 +1030,13 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id, } else if(!nwritten) { /* Not EOF, and nothing to give, we signal WOULDBLOCK. */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read req body -> AGAIN", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> AGAIN", stream->s.id); return NGHTTP3_ERR_WOULDBLOCK; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read req body -> " - "%d vecs%s with %zu (buffered=%zu, left=%" - CURL_FORMAT_CURL_OFF_T ")", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read req body -> " + "%d vecs%s with %zu (buffered=%zu, left=%" FMT_OFF_T ")", stream->s.id, (int)nvecs, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"", nwritten, Curl_bufq_len(&stream->sendbuf), @@ -1147,9 +1162,7 @@ static CURLcode cf_osslq_ctx_start(struct Curl_cfilter *cf, BIO *bio = NULL; BIO_ADDR *baddr = NULL; - Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, - H3_STREAM_POOL_SPARES); - Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + DEBUGASSERT(ctx->initialized); result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC); if(result) goto out; @@ -1263,7 +1276,7 @@ static ssize_t h3_quic_recv(void *reader_ctx, return -1; } else if(detail == SSL_ERROR_ZERO_RETURN) { - CURL_TRC_CF(x->data, x->cf, "[%" CURL_PRId64 "] h3_quic_recv -> EOS", + CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] h3_quic_recv -> EOS", x->s->id); x->s->recvd_eos = TRUE; return 0; @@ -1272,8 +1285,8 @@ static ssize_t h3_quic_recv(void *reader_ctx, SSL_STREAM_STATE_RESET_REMOTE) { uint64_t app_error_code = NGHTTP3_H3_NO_ERROR; SSL_get_stream_read_error_code(x->s->ssl, &app_error_code); - CURL_TRC_CF(x->data, x->cf, "[%" CURL_PRId64 "] h3_quic_recv -> RESET, " - "rv=%d, app_err=%" CURL_PRIu64, + CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRId64 "] h3_quic_recv -> RESET, " + "rv=%d, app_err=%" FMT_PRIu64, x->s->id, rv, (curl_uint64_t)app_error_code); if(app_error_code != NGHTTP3_H3_NO_ERROR) { x->s->reset = TRUE; @@ -1329,7 +1342,7 @@ static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, while(Curl_bufq_peek(&s->recvbuf, &buf, &blen)) { nread = nghttp3_conn_read_stream(ctx->h3.conn, s->id, buf, blen, 0); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] forward %zu bytes " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] forward %zu bytes " "to nghttp3 -> %zd", s->id, blen, nread); if(nread < 0) { failf(data, "nghttp3_conn_read_stream(len=%zu) error: %s", @@ -1368,7 +1381,7 @@ static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, rv = nghttp3_conn_close_stream(ctx->h3.conn, s->id, NGHTTP3_H3_NO_ERROR); s->closed = TRUE; - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] close nghttp3 stream -> %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] close nghttp3 stream -> %d", s->id, rv); if(rv < 0 && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { failf(data, "nghttp3_conn_close_stream returned error: %s", @@ -1381,7 +1394,7 @@ static CURLcode cf_osslq_stream_recv(struct cf_osslq_stream *s, } out: if(result) - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_osslq_stream_recv -> %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_osslq_stream_recv -> %d", s->id, result); return result; } @@ -1422,11 +1435,12 @@ static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, } if(ctx->h3.conn) { - struct Curl_easy *sdata; + struct Curl_llist_node *e; struct h3_stream_ctx *stream; /* PULL all open streams */ DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn == data->conn && CURL_WANT_RECV(sdata)) { stream = H3_STREAM_CTX(ctx, sdata); if(stream && !stream->closed && @@ -1449,11 +1463,12 @@ static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_osslq_ctx *ctx = cf->ctx; - struct Curl_easy *sdata; struct h3_stream_ctx *stream; if(ctx->h3.conn) { - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + struct Curl_llist_node *e; + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn == data->conn) { stream = H3_STREAM_CTX(ctx, sdata); if(stream && stream->s.ssl && stream->s.send_blocked && @@ -1505,7 +1520,7 @@ static CURLcode h3_send_streams(struct Curl_cfilter *cf, s = cf_osslq_get_qstream(cf, data, stream_id); if(!s) { failf(data, "nghttp3_conn_writev_stream gave unknown stream %" - CURL_PRId64, (curl_int64_t)stream_id); + FMT_PRId64, (curl_int64_t)stream_id); result = CURLE_SEND_ERROR; goto out; } @@ -1526,7 +1541,7 @@ static CURLcode h3_send_streams(struct Curl_cfilter *cf, if(ok) { /* As OpenSSL buffers the data, we count this as acknowledged * from nghttp3's point of view */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] send %zu bytes to QUIC ok", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send %zu bytes to QUIC ok", s->id, vec[i].len); acked_len += vec[i].len; } @@ -1536,14 +1551,14 @@ static CURLcode h3_send_streams(struct Curl_cfilter *cf, case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: /* QUIC blocked us from writing more */ - CURL_TRC_CF(data, cf, "[%"CURL_PRId64 "] send %zu bytes to " + CURL_TRC_CF(data, cf, "[%"FMT_PRId64 "] send %zu bytes to " "QUIC blocked", s->id, vec[i].len); written = 0; nghttp3_conn_block_stream(ctx->h3.conn, s->id); s->send_blocked = blocked = TRUE; break; default: - failf(data, "[%"CURL_PRId64 "] send %zu bytes to QUIC, SSL error %d", + failf(data, "[%"FMT_PRId64 "] send %zu bytes to QUIC, SSL error %d", s->id, vec[i].len, detail); result = cf_osslq_ssl_err(cf, data, detail, CURLE_HTTP3); goto out; @@ -1569,13 +1584,13 @@ static CURLcode h3_send_streams(struct Curl_cfilter *cf, result = CURLE_SEND_ERROR; goto out; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] forwarded %zu/%zu h3 bytes " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] forwarded %zu/%zu h3 bytes " "to QUIC, eos=%d", s->id, acked_len, total_len, eos); } if(eos && !s->send_blocked && !eos_written) { /* wrote everything and H3 indicates end of stream */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] closing QUIC stream", s->id); + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] closing QUIC stream", s->id); SSL_stream_conclude(s->ssl, 0); } } @@ -1868,11 +1883,11 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, if(rc) { switch(rc) { case NGHTTP3_ERR_CONN_CLOSING: - CURL_TRC_CF(data, cf, "h3sid[%"CURL_PRId64"] failed to send, " + CURL_TRC_CF(data, cf, "h3sid[%"FMT_PRId64"] failed to send, " "connection is closing", stream->s.id); break; default: - CURL_TRC_CF(data, cf, "h3sid[%"CURL_PRId64 "] failed to send -> %d (%s)", + CURL_TRC_CF(data, cf, "h3sid[%"FMT_PRId64 "] failed to send -> %d (%s)", stream->s.id, rc, nghttp3_strerror(rc)); break; } @@ -1882,10 +1897,10 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, } if(Curl_trc_is_verbose(data)) { - infof(data, "[HTTP/3] [%" CURL_PRId64 "] OPENED stream for %s", + infof(data, "[HTTP/3] [%" FMT_PRId64 "] OPENED stream for %s", stream->s.id, data->state.url); for(i = 0; i < nheader; ++i) { - infof(data, "[HTTP/3] [%" CURL_PRId64 "] [%.*s: %.*s]", + infof(data, "[HTTP/3] [%" FMT_PRId64 "] [%.*s: %.*s]", stream->s.id, (int)nva[i].namelen, nva[i].name, (int)nva[i].valuelen, nva[i].value); @@ -1899,7 +1914,8 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, } static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_osslq_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); @@ -1907,6 +1923,7 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, ssize_t nwritten; CURLcode result; + (void)eos; /* TODO: use to end stream */ CF_DATA_SAVE(save, cf, data); DEBUGASSERT(cf->connected); DEBUGASSERT(ctx->tls.ossl.ssl); @@ -1942,13 +1959,13 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, * body. This happens on 30x or 40x responses. * We silently discard the data sent, since this is not a transport * error situation. */ - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] discarding data" + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] discarding data" "on closed stream with response", stream->s.id); *err = CURLE_OK; nwritten = (ssize_t)len; goto out; } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] send_body(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] send_body(len=%zu) " "-> stream closed", stream->s.id, len); *err = CURLE_HTTP3; nwritten = -1; @@ -1956,7 +1973,7 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, } else { nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_send, add to " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send, add to " "sendbuf(len=%zu) -> %zd, %d", stream->s.id, len, nwritten, *err); if(nwritten < 0) { @@ -1974,7 +1991,7 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, out: result = check_and_set_expiry(cf, data); - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_send(len=%zu) -> %zd, %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %zd, %d", stream? stream->s.id : -1, len, nwritten, *err); CF_DATA_RESTORE(cf, save); return nwritten; @@ -1990,14 +2007,14 @@ static ssize_t recv_closed_stream(struct Curl_cfilter *cf, (void)cf; if(stream->reset) { failf(data, - "HTTP/3 stream %" CURL_PRId64 " reset by server", + "HTTP/3 stream %" FMT_PRId64 " reset by server", stream->s.id); *err = data->req.bytecount? CURLE_PARTIAL_FILE : CURLE_HTTP3; goto out; } else if(!stream->resp_hds_complete) { failf(data, - "HTTP/3 stream %" CURL_PRId64 + "HTTP/3 stream %" FMT_PRId64 " was closed cleanly, but before getting" " all response header fields, treated as error", stream->s.id); @@ -2037,7 +2054,7 @@ static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, nread = Curl_bufq_read(&stream->recvbuf, (unsigned char *)buf, len, err); if(nread < 0) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read recvbuf(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read recvbuf(len=%zu) " "-> %zd, %d", stream->s.id, len, nread, *err); goto out; } @@ -2055,7 +2072,7 @@ static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, nread = Curl_bufq_read(&stream->recvbuf, (unsigned char *)buf, len, err); if(nread < 0) { - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] read recvbuf(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] read recvbuf(len=%zu) " "-> %zd, %d", stream->s.id, len, nread, *err); goto out; } @@ -2085,7 +2102,7 @@ static ssize_t cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data, nread = -1; } } - CURL_TRC_CF(data, cf, "[%" CURL_PRId64 "] cf_recv(len=%zu) -> %zd, %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(len=%zu) -> %zd, %d", stream? stream->s.id : -1, len, nread, *err); CF_DATA_RESTORE(cf, save); return nread; @@ -2325,7 +2342,7 @@ CURLcode Curl_cf_osslq_create(struct Curl_cfilter **pcf, result = CURLE_OUT_OF_MEMORY; goto out; } - cf_osslq_ctx_clear(ctx); + cf_osslq_ctx_init(ctx); result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); if(result) @@ -2346,7 +2363,7 @@ CURLcode Curl_cf_osslq_create(struct Curl_cfilter **pcf, if(udp_cf) Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE); Curl_safefree(cf); - Curl_safefree(ctx); + cf_osslq_ctx_free(ctx); } return result; } diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index 6f01c19aa..9182fe9e4 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -98,14 +98,17 @@ struct cf_quiche_ctx { struct curltime handshake_at; /* time connect handshake finished */ struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ - struct Curl_hash streams; /* hash `data->id` to `stream_ctx` */ + struct Curl_hash streams; /* hash `data->mid` to `stream_ctx` */ curl_off_t data_recvd; + BIT(initialized); BIT(goaway); /* got GOAWAY from server */ BIT(x509_store_setup); /* if x509 store has been set up */ BIT(shutdown_started); /* queued shutdown packets */ }; #ifdef DEBUG_QUICHE +/* initialize debug log callback only once */ +static int debug_log_init = 0; static void quiche_debug_log(const char *line, void *argp) { (void)argp; @@ -113,17 +116,27 @@ static void quiche_debug_log(const char *line, void *argp) } #endif -static void cf_quiche_ctx_clear(struct cf_quiche_ctx *ctx) +static void h3_stream_hash_free(void *stream); + +static void cf_quiche_ctx_init(struct cf_quiche_ctx *ctx) { - if(ctx) { - if(ctx->h3c) - quiche_h3_conn_free(ctx->h3c); - if(ctx->h3config) - quiche_h3_config_free(ctx->h3config); - if(ctx->qconn) - quiche_conn_free(ctx->qconn); - if(ctx->cfg) - quiche_config_free(ctx->cfg); + DEBUGASSERT(!ctx->initialized); +#ifdef DEBUG_QUICHE + if(!debug_log_init) { + quiche_enable_debug_logging(quiche_debug_log, NULL); + debug_log_init = 1; + } +#endif + Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, + H3_STREAM_POOL_SPARES); + Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); + ctx->data_recvd = 0; + ctx->initialized = TRUE; +} + +static void cf_quiche_ctx_free(struct cf_quiche_ctx *ctx) +{ + if(ctx && ctx->initialized) { /* quiche just freed it */ ctx->tls.ossl.ssl = NULL; Curl_vquic_tls_cleanup(&ctx->tls); @@ -132,9 +145,20 @@ static void cf_quiche_ctx_clear(struct cf_quiche_ctx *ctx) Curl_bufcp_free(&ctx->stream_bufcp); Curl_hash_clean(&ctx->streams); Curl_hash_destroy(&ctx->streams); - - memset(ctx, 0, sizeof(*ctx)); } + free(ctx); +} + +static void cf_quiche_ctx_close(struct cf_quiche_ctx *ctx) +{ + if(ctx->h3c) + quiche_h3_conn_free(ctx->h3c); + if(ctx->h3config) + quiche_h3_config_free(ctx->h3config); + if(ctx->qconn) + quiche_conn_free(ctx->qconn); + if(ctx->cfg) + quiche_config_free(ctx->cfg); } static CURLcode cf_flush_egress(struct Curl_cfilter *cf, @@ -148,7 +172,6 @@ struct stream_ctx { struct bufq recvbuf; /* h3 response */ struct h1_req_parser h1; /* h1 request parsing */ curl_uint64_t error3; /* HTTP/3 stream error code */ - curl_off_t upload_left; /* number of request bytes left to upload */ BIT(opened); /* TRUE after stream has been opened */ BIT(closed); /* TRUE on stream close */ BIT(reset); /* TRUE on stream reset */ @@ -159,7 +182,7 @@ struct stream_ctx { }; #define H3_STREAM_CTX(ctx,data) ((struct stream_ctx *)(\ - data? Curl_hash_offt_get(&(ctx)->streams, (data)->id) : NULL)) + data? Curl_hash_offt_get(&(ctx)->streams, (data)->mid) : NULL)) static void h3_stream_ctx_free(struct stream_ctx *stream) { @@ -178,17 +201,17 @@ static void check_resumes(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; - struct Curl_easy *sdata; - struct stream_ctx *stream; + struct Curl_llist_node *e; DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn == data->conn) { - stream = H3_STREAM_CTX(ctx, sdata); + struct stream_ctx *stream = H3_STREAM_CTX(ctx, sdata); if(stream && stream->quic_flow_blocked) { stream->quic_flow_blocked = FALSE; Curl_expire(data, 0, EXPIRE_RUN_NOW); - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] unblock", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] unblock", stream->id); } } } @@ -212,7 +235,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT); Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - if(!Curl_hash_offt_set(&ctx->streams, data->id, stream)) { + if(!Curl_hash_offt_set(&ctx->streams, data->mid, stream)) { h3_stream_ctx_free(stream); return CURLE_OUT_OF_MEMORY; } @@ -228,7 +251,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) (void)cf; if(stream) { - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] easy handle is done", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] easy handle is done", stream->id); if(ctx->qconn && !stream->closed) { quiche_conn_stream_shutdown(ctx->qconn, stream->id, QUICHE_SHUTDOWN_READ, CURL_H3_NO_ERROR); @@ -242,7 +265,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) if(result) CURL_TRC_CF(data, cf, "data_done, flush egress -> %d", result); } - Curl_hash_offt_remove(&ctx->streams, data->id); + Curl_hash_offt_remove(&ctx->streams, data->mid); } } @@ -255,7 +278,7 @@ static void drain_stream(struct Curl_cfilter *cf, (void)cf; bits = CURL_CSELECT_IN; - if(stream && !stream->send_closed && stream->upload_left) + if(stream && !stream->send_closed) bits |= CURL_CSELECT_OUT; if(data->state.select_bits != bits) { data->state.select_bits = bits; @@ -269,7 +292,6 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, struct stream_ctx **pstream) { struct cf_quiche_ctx *ctx = cf->ctx; - struct Curl_easy *sdata; struct stream_ctx *stream; (void)cf; @@ -279,8 +301,10 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, return data; } else { + struct Curl_llist_node *e; DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata->conn != data->conn) continue; stream = H3_STREAM_CTX(ctx, sdata); @@ -297,11 +321,12 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, static void cf_quiche_expire_conn_closed(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct Curl_easy *sdata; + struct Curl_llist_node *e; DEBUGASSERT(data->multi); CURL_TRC_CF(data, cf, "conn closed, expire all transfers"); - for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + for(e = Curl_llist_head(&data->multi->process); e; e = Curl_node_next(e)) { + struct Curl_easy *sdata = Curl_node_elem(e); if(sdata == data || sdata->conn != data->conn) continue; CURL_TRC_CF(sdata, cf, "conn closed, expire transfer"); @@ -357,7 +382,7 @@ static int cb_each_header(uint8_t *name, size_t name_len, return CURLE_OK; if((name_len == 7) && !strncmp(HTTP_PSEUDO_STATUS, (char *)name, 7)) { - CURL_TRC_CF(x->data, x->cf, "[%" CURL_PRIu64 "] status: %.*s", + CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRIu64 "] status: %.*s", stream->id, (int)value_len, value); result = write_resp_raw(x->cf, x->data, "HTTP/3 ", sizeof("HTTP/3 ") - 1); if(!result) @@ -366,7 +391,7 @@ static int cb_each_header(uint8_t *name, size_t name_len, result = write_resp_raw(x->cf, x->data, " \r\n", 3); } else { - CURL_TRC_CF(x->data, x->cf, "[%" CURL_PRIu64 "] header: %.*s: %.*s", + CURL_TRC_CF(x->data, x->cf, "[%" FMT_PRIu64 "] header: %.*s: %.*s", stream->id, (int)name_len, name, (int)value_len, value); result = write_resp_raw(x->cf, x->data, name, name_len); @@ -378,7 +403,7 @@ static int cb_each_header(uint8_t *name, size_t name_len, result = write_resp_raw(x->cf, x->data, "\r\n", 2); } if(result) { - CURL_TRC_CF(x->data, x->cf, "[%"CURL_PRIu64"] on header error %d", + CURL_TRC_CF(x->data, x->cf, "[%"FMT_PRIu64"] on header error %d", stream->id, result); } return result; @@ -435,9 +460,9 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf, stream_resp_read, &cb_ctx, &result); if(nwritten < 0 && result != CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] recv_body error %zd", + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] recv_body error %zd", stream->id, nwritten); - failf(data, "Error %d in HTTP/3 response body for stream[%"CURL_PRIu64"]", + failf(data, "Error %d in HTTP/3 response body for stream[%"FMT_PRIu64"]", result, stream->id); stream->closed = TRUE; stream->reset = TRUE; @@ -489,10 +514,10 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf, rc = quiche_h3_event_for_each_header(ev, cb_each_header, &cb_ctx); if(rc) { failf(data, "Error %d in HTTP/3 response header for stream[%" - CURL_PRIu64"]", rc, stream->id); + FMT_PRIu64"]", rc, stream->id); return CURLE_RECV_ERROR; } - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] <- [HEADERS]", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] <- [HEADERS]", stream->id); break; case QUICHE_H3_EVENT_DATA: @@ -502,7 +527,7 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf, break; case QUICHE_H3_EVENT_RESET: - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] RESET", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] RESET", stream->id); stream->closed = TRUE; stream->reset = TRUE; stream->send_closed = TRUE; @@ -510,7 +535,7 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf, break; case QUICHE_H3_EVENT_FINISHED: - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] CLOSED", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] CLOSED", stream->id); if(!stream->resp_hds_complete) { result = write_resp_raw(cf, data, "\r\n", 2); if(result) @@ -522,11 +547,11 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf, break; case QUICHE_H3_EVENT_GOAWAY: - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] <- [GOAWAY]", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] <- [GOAWAY]", stream->id); break; default: - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] recv, unhandled event %d", + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] recv, unhandled event %d", stream->id, quiche_h3_event_type(ev)); break; } @@ -549,13 +574,13 @@ static CURLcode cf_poll_events(struct Curl_cfilter *cf, break; } else if(stream3_id < 0) { - CURL_TRC_CF(data, cf, "error poll: %"CURL_PRId64, stream3_id); + CURL_TRC_CF(data, cf, "error poll: %"FMT_PRId64, stream3_id); return CURLE_HTTP3; } sdata = get_stream_easy(cf, data, stream3_id, &stream); if(!sdata || !stream) { - CURL_TRC_CF(data, cf, "discard event %s for unknown [%"CURL_PRId64"]", + CURL_TRC_CF(data, cf, "discard event %s for unknown [%"FMT_PRId64"]", cf_ev_name(ev), stream3_id); } else { @@ -563,7 +588,7 @@ static CURLcode cf_poll_events(struct Curl_cfilter *cf, drain_stream(cf, sdata); if(result) { CURL_TRC_CF(data, cf, "error processing event %s " - "for [%"CURL_PRIu64"] -> %d", cf_ev_name(ev), + "for [%"FMT_PRIu64"] -> %d", cf_ev_name(ev), stream3_id, result); if(data == sdata) { /* Only report this error to the caller if it is about the @@ -793,19 +818,19 @@ static ssize_t recv_closed_stream(struct Curl_cfilter *cf, DEBUGASSERT(stream); if(stream->reset) { failf(data, - "HTTP/3 stream %" CURL_PRIu64 " reset by server", stream->id); + "HTTP/3 stream %" FMT_PRIu64 " reset by server", stream->id); *err = data->req.bytecount? CURLE_PARTIAL_FILE : CURLE_HTTP3; - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] cf_recv, was reset -> %d", + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_recv, was reset -> %d", stream->id, *err); } else if(!stream->resp_got_header) { failf(data, - "HTTP/3 stream %" CURL_PRIu64 " was closed cleanly, but before " + "HTTP/3 stream %" FMT_PRIu64 " was closed cleanly, but before " "getting all response header fields, treated as error", stream->id); /* *err = CURLE_PARTIAL_FILE; */ *err = CURLE_HTTP3; - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] cf_recv, closed incomplete" + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_recv, closed incomplete" " -> %d", stream->id, *err); } else { @@ -833,7 +858,7 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, if(!Curl_bufq_is_empty(&stream->recvbuf)) { nread = Curl_bufq_read(&stream->recvbuf, (unsigned char *)buf, len, err); - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] read recvbuf(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] read recvbuf(len=%zu) " "-> %zd, %d", stream->id, len, nread, *err); if(nread < 0) goto out; @@ -850,7 +875,7 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, if(nread < 0 && !Curl_bufq_is_empty(&stream->recvbuf)) { nread = Curl_bufq_read(&stream->recvbuf, (unsigned char *)buf, len, err); - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] read recvbuf(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] read recvbuf(len=%zu) " "-> %zd, %d", stream->id, len, nread, *err); if(nread < 0) goto out; @@ -884,19 +909,70 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } if(nread > 0) ctx->data_recvd += nread; - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] cf_recv(total=%" - CURL_FORMAT_CURL_OFF_T ") -> %zd, %d", + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] cf_recv(total=%" + FMT_OFF_T ") -> %zd, %d", stream->id, ctx->data_recvd, nread, *err); return nread; } +static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct stream_ctx *stream, + const void *buf, size_t len, bool eos, + CURLcode *err) +{ + struct cf_quiche_ctx *ctx = cf->ctx; + ssize_t nwritten; + + nwritten = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id, + (uint8_t *)buf, len, eos); + if(nwritten == QUICHE_H3_ERR_DONE || (nwritten == 0 && len > 0)) { + /* TODO: we seem to be blocked on flow control and should HOLD + * sending. But when do we open again? */ + if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) { + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " + "-> window exhausted", stream->id, len); + stream->quic_flow_blocked = TRUE; + } + *err = CURLE_AGAIN; + return -1; + } + else if(nwritten == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE) { + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " + "-> invalid stream state", stream->id, len); + *err = CURLE_HTTP3; + return -1; + } + else if(nwritten == QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE) { + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " + "-> exceeds size", stream->id, len); + *err = CURLE_SEND_ERROR; + return -1; + } + else if(nwritten < 0) { + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " + "-> quiche err %zd", stream->id, len, nwritten); + *err = CURLE_SEND_ERROR; + return -1; + } + else { + if(eos && (len == (size_t)nwritten)) + stream->send_closed = TRUE; + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send body(len=%zu, " + "eos=%d) -> %zd", + stream->id, len, stream->send_closed, nwritten); + *err = CURLE_OK; + return nwritten; + } +} + /* Index where :authority header field will appear in request header field list. */ #define AUTHORITY_DST_IDX 3 static ssize_t h3_open_stream(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, + const char *buf, size_t len, bool eos, CURLcode *err) { struct cf_quiche_ctx *ctx = cf->ctx; @@ -952,23 +1028,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, nva[i].value_len = e->valuelen; } - switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: - if(data->state.infilesize != -1) - stream->upload_left = data->state.infilesize; - else - /* data sending without specifying the data amount up front */ - stream->upload_left = -1; /* unknown */ - break; - default: - stream->upload_left = 0; /* no request body */ - break; - } - - if(stream->upload_left == 0) + if(eos && ((size_t)nwritten == len)) stream->send_closed = TRUE; stream3_id = quiche_h3_send_request(ctx->h3c, ctx->qconn, nva, nheader, @@ -977,14 +1037,14 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, if(QUICHE_H3_ERR_STREAM_BLOCKED == stream3_id) { /* quiche seems to report this error if the connection window is * exhausted. Which happens frequently and intermittent. */ - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] blocked", stream->id); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] blocked", stream->id); stream->quic_flow_blocked = TRUE; *err = CURLE_AGAIN; nwritten = -1; goto out; } else { - CURL_TRC_CF(data, cf, "send_request(%s) -> %" CURL_PRIu64, + CURL_TRC_CF(data, cf, "send_request(%s) -> %" FMT_PRIu64, data->state.url, stream3_id); } *err = CURLE_SEND_ERROR; @@ -1000,15 +1060,31 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, stream->reset = FALSE; if(Curl_trc_is_verbose(data)) { - infof(data, "[HTTP/3] [%" CURL_PRIu64 "] OPENED stream for %s", + infof(data, "[HTTP/3] [%" FMT_PRIu64 "] OPENED stream for %s", stream->id, data->state.url); for(i = 0; i < nheader; ++i) { - infof(data, "[HTTP/3] [%" CURL_PRIu64 "] [%.*s: %.*s]", stream->id, + infof(data, "[HTTP/3] [%" FMT_PRIu64 "] [%.*s: %.*s]", stream->id, (int)nva[i].name_len, nva[i].name, (int)nva[i].value_len, nva[i].value); } } + if(nwritten > 0 && ((size_t)nwritten < len)) { + /* after the headers, there was request BODY data */ + size_t hds_len = (size_t)nwritten; + ssize_t bwritten; + + bwritten = cf_quiche_send_body(cf, data, stream, + buf + hds_len, len - hds_len, eos, err); + if((bwritten < 0) && (CURLE_AGAIN != *err)) { + /* real error, fail */ + nwritten = -1; + } + else if(bwritten > 0) { + nwritten += bwritten; + } + } + out: free(nva); Curl_dynhds_free(&h2_headers); @@ -1016,7 +1092,8 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, } static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, CURLcode *err) + const void *buf, size_t len, bool eos, + CURLcode *err) { struct cf_quiche_ctx *ctx = cf->ctx; struct stream_ctx *stream = H3_STREAM_CTX(ctx, data); @@ -1032,7 +1109,7 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, } if(!stream || !stream->opened) { - nwritten = h3_open_stream(cf, data, buf, len, err); + nwritten = h3_open_stream(cf, data, buf, len, eos, err); if(nwritten < 0) goto out; stream = H3_STREAM_CTX(ctx, data); @@ -1047,70 +1124,20 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, * sending the 30x response. * This is sort of a race: had the transfer loop called recv first, * it would see the response and stop/discard sending on its own- */ - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] discarding data" + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] discarding data" "on closed stream with response", stream->id); *err = CURLE_OK; nwritten = (ssize_t)len; goto out; } - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send_body(len=%zu) " + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> stream closed", stream->id, len); *err = CURLE_HTTP3; nwritten = -1; goto out; } else { - bool eof = (stream->upload_left >= 0 && - (curl_off_t)len >= stream->upload_left); - nwritten = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id, - (uint8_t *)buf, len, eof); - if(nwritten == QUICHE_H3_ERR_DONE || (nwritten == 0 && len > 0)) { - /* TODO: we seem to be blocked on flow control and should HOLD - * sending. But when do we open again? */ - if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) { - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send_body(len=%zu) " - "-> window exhausted", stream->id, len); - stream->quic_flow_blocked = TRUE; - } - *err = CURLE_AGAIN; - nwritten = -1; - goto out; - } - else if(nwritten == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE) { - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send_body(len=%zu) " - "-> invalid stream state", stream->id, len); - *err = CURLE_HTTP3; - nwritten = -1; - goto out; - } - else if(nwritten == QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE) { - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send_body(len=%zu) " - "-> exceeds size", stream->id, len); - *err = CURLE_SEND_ERROR; - nwritten = -1; - goto out; - } - else if(nwritten < 0) { - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send_body(len=%zu) " - "-> quiche err %zd", stream->id, len, nwritten); - *err = CURLE_SEND_ERROR; - nwritten = -1; - goto out; - } - else { - /* quiche accepted all or at least a part of the buf */ - if(stream->upload_left > 0) { - stream->upload_left = (nwritten < stream->upload_left)? - (stream->upload_left - nwritten) : 0; - } - if(stream->upload_left == 0) - stream->send_closed = TRUE; - - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] send body(len=%zu, " - "left=%" CURL_FORMAT_CURL_OFF_T ") -> %zd", - stream->id, len, stream->upload_left, nwritten); - *err = CURLE_OK; - } + nwritten = cf_quiche_send_body(cf, data, stream, buf, len, eos, err); } out: @@ -1119,8 +1146,8 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, *err = result; nwritten = -1; } - CURL_TRC_CF(data, cf, "[%" CURL_PRIu64 "] cf_send(len=%zu) -> %zd, %d", - stream? stream->id : (uint64_t)~0, len, nwritten, *err); + CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_send(len=%zu) -> %zd, %d", + stream? stream->id : (curl_uint64_t)~0, len, nwritten, *err); return nwritten; } @@ -1215,10 +1242,9 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, ssize_t sent; stream->send_closed = TRUE; - stream->upload_left = 0; body[0] = 'X'; - sent = cf_quiche_send(cf, data, body, 0, &result); - CURL_TRC_CF(data, cf, "[%"CURL_PRIu64"] DONE_SEND -> %zd, %d", + sent = cf_quiche_send(cf, data, body, 0, TRUE, &result); + CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] DONE_SEND -> %zd, %d", stream->id, sent, result); } break; @@ -1238,8 +1264,8 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, return result; } -static CURLcode cf_connect_start(struct Curl_cfilter *cf, - struct Curl_easy *data) +static CURLcode cf_quiche_ctx_open(struct Curl_cfilter *cf, + struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; int rv; @@ -1247,19 +1273,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, const struct Curl_sockaddr_ex *sockaddr; DEBUGASSERT(ctx->q.sockfd != CURL_SOCKET_BAD); - -#ifdef DEBUG_QUICHE - /* initialize debug log callback only once */ - static int debug_log_init = 0; - if(!debug_log_init) { - quiche_enable_debug_logging(quiche_debug_log, NULL); - debug_log_init = 1; - } -#endif - Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, - H3_STREAM_POOL_SPARES); - Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free); - ctx->data_recvd = 0; + DEBUGASSERT(ctx->initialized); result = vquic_ctx_init(&ctx->q); if(result) @@ -1366,7 +1380,6 @@ static CURLcode cf_quiche_verify_peer(struct Curl_cfilter *cf, cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; - cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); } @@ -1401,7 +1414,7 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, } if(!ctx->qconn) { - result = cf_connect_start(cf, data); + result = cf_quiche_ctx_open(cf, data); if(result) goto out; ctx->started_at = ctx->q.last_op; @@ -1513,23 +1526,20 @@ static CURLcode cf_quiche_shutdown(struct Curl_cfilter *cf, static void cf_quiche_close(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct cf_quiche_ctx *ctx = cf->ctx; - - if(ctx) { + if(cf->ctx) { bool done; (void)cf_quiche_shutdown(cf, data, &done); - cf_quiche_ctx_clear(ctx); + cf_quiche_ctx_close(cf->ctx); } } static void cf_quiche_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct cf_quiche_ctx *ctx = cf->ctx; - (void)data; - cf_quiche_ctx_clear(ctx); - free(ctx); - cf->ctx = NULL; + if(cf->ctx) { + cf_quiche_ctx_free(cf->ctx); + cf->ctx = NULL; + } } static CURLcode cf_quiche_query(struct Curl_cfilter *cf, @@ -1545,7 +1555,7 @@ static CURLcode cf_quiche_query(struct Curl_cfilter *cf, max_streams += quiche_conn_peer_streams_left_bidi(ctx->qconn); } *pres1 = (max_streams > INT_MAX)? INT_MAX : (int)max_streams; - CURL_TRC_CF(data, cf, "query conn[%" CURL_FORMAT_CURL_OFF_T "]: " + CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " "MAX_CONCURRENT -> %d (%zu in use)", cf->conn->connection_id, *pres1, CONN_INUSE(cf->conn)); return CURLE_OK; @@ -1650,6 +1660,7 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, result = CURLE_OUT_OF_MEMORY; goto out; } + cf_quiche_ctx_init(ctx); result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); if(result) @@ -1669,7 +1680,7 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, if(udp_cf) Curl_conn_cf_discard_sub(cf, udp_cf, data, TRUE); Curl_safefree(cf); - Curl_safefree(ctx); + cf_quiche_ctx_free(ctx); } return result; diff --git a/lib/vquic/vquic-tls.c b/lib/vquic/vquic-tls.c index 6aa6613af..cc8c22d77 100644 --- a/lib/vquic/vquic-tls.c +++ b/lib/vquic/vquic-tls.c @@ -162,7 +162,7 @@ static CURLcode Curl_wssl_init_ctx(struct curl_tls_ctx *ctx, #ifdef CURL_CA_FALLBACK else { /* verifying the peer without any CA certificates will not work so - use wolfssl's built-in default as fallback */ + use wolfSSL's built-in default as fallback */ wolfSSL_CTX_set_default_verify_paths(ctx->wssl.ctx); } #endif diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index 2bb06d463..4648b5a07 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -22,7 +22,7 @@ * ***************************************************************************/ -/* WIP, experimental: use recvmmsg() on linux +/* WIP, experimental: use recvmmsg() on Linux * we have no configure check, yet * and also it is only available for _GNU_SOURCE, which * we do not use otherwise. @@ -720,7 +720,7 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data, const struct connectdata *conn) { if(conn->transport == TRNSPRT_UNIX) { - /* cannot do QUIC over a unix domain socket */ + /* cannot do QUIC over a Unix domain socket */ return CURLE_QUIC_CONNECT_ERROR; } if(!(conn->handler->flags & PROTOPT_SSL)) { diff --git a/lib/vssh/.checksrc b/lib/vssh/.checksrc new file mode 100644 index 000000000..9066946c8 --- /dev/null +++ b/lib/vssh/.checksrc @@ -0,0 +1,2 @@ +enable STRERROR +enable STRNCPY diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 20a05636d..230fddcef 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -31,11 +31,6 @@ #include -/* in 0.10.0 or later, ignore deprecated warnings */ -#define SSH_SUPPRESS_DEPRECATED -#include -#include - #ifdef HAVE_NETINET_IN_H #include #endif @@ -1241,7 +1236,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(attrs) { curl_off_t size = attrs->size; if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + failf(data, "Bad file size (%" FMT_OFF_T ")", size); MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); break; } @@ -1626,7 +1621,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sftp_attributes_free(attrs); if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + failf(data, "Bad file size (%" FMT_OFF_T ")", size); return CURLE_BAD_DOWNLOAD_RESUME; } if(data->state.use_range) { @@ -1656,9 +1651,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) to = size - 1; } if(from > size) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", from, size); + failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" + FMT_OFF_T ")", from, size); return CURLE_BAD_DOWNLOAD_RESUME; } if(from > to) { @@ -1687,10 +1681,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(data->state.resume_from < 0) { /* We are supposed to download the last abs(from) bytes */ if((curl_off_t)size < -data->state.resume_from) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, size); + failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" + FMT_OFF_T ")", data->state.resume_from, size); return CURLE_BAD_DOWNLOAD_RESUME; } /* download from where? */ @@ -1698,8 +1690,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { if((curl_off_t)size < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + failf(data, "Offset (%" FMT_OFF_T + ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, size); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -2404,12 +2396,13 @@ static CURLcode scp_done(struct Curl_easy *data, CURLcode status, } static ssize_t scp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, CURLcode *err) { int rc; struct connectdata *conn = data->conn; (void) sockindex; /* we only support SCP on the fixed known primary socket */ (void) err; + (void)eos; rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len); @@ -2552,11 +2545,13 @@ static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, /* return number of sent bytes */ static ssize_t sftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, + CURLcode *err) { ssize_t nwrite; struct connectdata *conn = data->conn; (void)sockindex; + (void)eos; /* limit the writes to the maximum specified in Section 3 of * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index 1b566d1ab..83e356c0e 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -30,9 +30,6 @@ #include -#include -#include - #ifdef HAVE_FCNTL_H #include #endif @@ -1786,7 +1783,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } #if SIZEOF_TIME_T > SIZEOF_LONG if(date > 0xffffffff) { - /* if 'long' cannot old >32bit, this date cannot be sent */ + /* if 'long' cannot old >32-bit, this date cannot be sent */ failf(data, "date overflow"); fail = TRUE; } @@ -2069,7 +2066,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) else { curl_off_t size = attrs.filesize; if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + failf(data, "Bad file size (%" FMT_OFF_T ")", size); return CURLE_BAD_DOWNLOAD_RESUME; } data->state.resume_from = attrs.filesize; @@ -2510,7 +2507,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) curl_off_t size = attrs.filesize; if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + failf(data, "Bad file size (%" FMT_OFF_T ")", size); return CURLE_BAD_DOWNLOAD_RESUME; } if(data->state.use_range) { @@ -2538,10 +2535,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) to = size - 1; } if(from > size) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", from, - (curl_off_t)attrs.filesize); + failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" + FMT_OFF_T ")", from, (curl_off_t)attrs.filesize); return CURLE_BAD_DOWNLOAD_RESUME; } if(from > to) { @@ -2566,9 +2561,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(data->state.resume_from < 0) { /* We are supposed to download the last abs(from) bytes */ if((curl_off_t)attrs.filesize < -data->state.resume_from) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", + failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" + FMT_OFF_T ")", data->state.resume_from, (curl_off_t)attrs.filesize); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -2577,8 +2571,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } else { if((curl_off_t)attrs.filesize < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + failf(data, "Offset (%" FMT_OFF_T + ") was beyond file size (%" FMT_OFF_T ")", data->state.resume_from, (curl_off_t)attrs.filesize); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -3229,7 +3223,7 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, /* swap in the TLS writer function for this call only, and then swap back the SSH one again */ conn->send[0] = ssh->tls_send; - result = Curl_conn_send(data, socknum, buffer, length, &nwrite); + result = Curl_conn_send(data, socknum, buffer, length, FALSE, &nwrite); conn->send[0] = backup; if(result == CURLE_AGAIN) return -EAGAIN; /* magic return code for libssh2 */ @@ -3540,12 +3534,13 @@ static CURLcode scp_done(struct Curl_easy *data, CURLcode status, } static ssize_t scp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, CURLcode *err) { ssize_t nwrite; struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; /* we only support SCP on the fixed known primary socket */ + (void)eos; /* libssh2_channel_write() returns int! */ nwrite = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len); @@ -3678,12 +3673,13 @@ static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, /* return number of sent bytes */ static ssize_t sftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, CURLcode *err) { ssize_t nwrite; struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; + (void)eos; nwrite = libssh2_sftp_write(sshc->sftp_handle, mem, len); diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h index 64ef33298..2ed78649b 100644 --- a/lib/vssh/ssh.h +++ b/lib/vssh/ssh.h @@ -30,6 +30,8 @@ #include #include #elif defined(USE_LIBSSH) +/* in 0.10.0 or later, ignore deprecated warnings */ +#define SSH_SUPPRESS_DEPRECATED #include #include #elif defined(USE_WOLFSSH) diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 1ed24fe4e..1d01bcdb7 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -28,8 +28,6 @@ #include -#include -#include #include "urldata.h" #include "cfilters.h" #include "connect.h" @@ -220,13 +218,15 @@ static void state(struct Curl_easy *data, sshstate nowstate) } static ssize_t wscp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, + CURLcode *err) { ssize_t nwrite = 0; (void)data; (void)sockindex; /* we only support SCP on the fixed known primary socket */ (void)mem; (void)len; + (void)eos; (void)err; return nwrite; @@ -247,13 +247,14 @@ static ssize_t wscp_recv(struct Curl_easy *data, int sockindex, /* return number of sent bytes */ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, - const void *mem, size_t len, CURLcode *err) + const void *mem, size_t len, bool eos, CURLcode *err) { struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; word32 offset[2]; int rc; (void)sockindex; + (void)eos; offset[0] = (word32)sshc->offset&0xFFFFFFFF; offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF; @@ -280,7 +281,7 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, return -1; } DEBUGASSERT(rc == (int)len); - infof(data, "sent %zu bytes SFTP from offset %" CURL_FORMAT_CURL_OFF_T, + infof(data, "sent %zu bytes SFTP from offset %" FMT_OFF_T, len, sshc->offset); sshc->offset += len; return (ssize_t)rc; @@ -577,7 +578,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) else { curl_off_t size = ((curl_off_t)attrs.sz[1] << 32) | attrs.sz[0]; if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + failf(data, "Bad file size (%" FMT_OFF_T ")", size); return CURLE_BAD_DOWNLOAD_RESUME; } data->state.resume_from = size; @@ -768,7 +769,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) data->req.maxdownload = size; Curl_pgrsSetDownloadSize(data, size); - infof(data, "SFTP download %" CURL_FORMAT_CURL_OFF_T " bytes", size); + infof(data, "SFTP download %" FMT_OFF_T " bytes", size); /* We cannot seek with wolfSSH so resuming and range requests are not possible */ diff --git a/lib/vtls/.checksrc b/lib/vtls/.checksrc new file mode 100644 index 000000000..9066946c8 --- /dev/null +++ b/lib/vtls/.checksrc @@ -0,0 +1,2 @@ +enable STRERROR +enable STRNCPY diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c index 47c5528c2..0199d6b42 100644 --- a/lib/vtls/bearssl.c +++ b/lib/vtls/bearssl.c @@ -361,6 +361,56 @@ static const br_x509_class x509_vtable = { x509_get_pkey }; +static CURLcode +bearssl_set_ssl_version_min_max(struct Curl_easy *data, + br_ssl_engine_context *ssl_eng, + struct ssl_primary_config *conn_config) +{ + unsigned version_min, version_max; + + switch(conn_config->version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + version_min = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + version_min = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + version_min = BR_TLS12; + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "BearSSL: does not support TLS 1.3"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "BearSSL: unsupported minimum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; + } + + switch(conn_config->version_max) { + case CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_TLSv1_3: + case CURL_SSLVERSION_MAX_TLSv1_2: + version_max = BR_TLS12; + break; + case CURL_SSLVERSION_MAX_TLSv1_1: + version_max = BR_TLS11; + break; + case CURL_SSLVERSION_MAX_TLSv1_0: + version_max = BR_TLS10; + break; + default: + failf(data, "BearSSL: unsupported maximum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; + } + + br_ssl_engine_set_versions(ssl_eng, version_min, version_max); + + return CURLE_OK; +} + static const uint16_t ciphertable[] = { /* RFC 2246 TLS 1.0 */ BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */ @@ -495,41 +545,11 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, const bool verifypeer = conn_config->verifypeer; const bool verifyhost = conn_config->verifyhost; CURLcode ret; - unsigned version_min, version_max; int session_set = 0; DEBUGASSERT(backend); CURL_TRC_CF(data, cf, "connect_step1"); - switch(conn_config->version) { - case CURL_SSLVERSION_SSLv2: - failf(data, "BearSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv3: - failf(data, "BearSSL does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_0: - version_min = BR_TLS10; - version_max = BR_TLS10; - break; - case CURL_SSLVERSION_TLSv1_1: - version_min = BR_TLS11; - version_max = BR_TLS11; - break; - case CURL_SSLVERSION_TLSv1_2: - version_min = BR_TLS12; - version_max = BR_TLS12; - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - version_min = BR_TLS10; - version_max = BR_TLS12; - break; - default: - failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - if(verifypeer) { if(ca_info_blob) { struct cafile_source source; @@ -564,7 +584,11 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, /* initialize SSL context */ br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal, backend->anchors, backend->anchors_len); - br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max); + + ret = bearssl_set_ssl_version_min_max(data, &backend->ctx.eng, conn_config); + if(ret != CURLE_OK) + return ret; + br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf, sizeof(backend->buf), 1); @@ -648,28 +672,6 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, return CURLE_OK; } -static void bearssl_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - if(!cf->connected) { - curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); - if(sock != CURL_SOCKET_BAD) { - struct ssl_connect_data *connssl = cf->ctx; - struct bearssl_ssl_backend_data *backend = - (struct bearssl_ssl_backend_data *)connssl->backend; - unsigned state = br_ssl_engine_current_state(&backend->ctx.eng); - - if(state & BR_SSL_SENDREC) { - Curl_pollset_set_out_only(data, ps, sock); - } - else { - Curl_pollset_set_in_only(data, ps, sock); - } - } - } -} - static CURLcode bearssl_run_until(struct Curl_cfilter *cf, struct Curl_easy *data, unsigned target) @@ -686,6 +688,7 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, DEBUGASSERT(backend); + connssl->io_need = CURL_SSL_IO_NEED_NONE; for(;;) { state = br_ssl_engine_current_state(&backend->ctx.eng); if(state & BR_SSL_CLOSED) { @@ -710,7 +713,9 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, failf(data, "SSL: X.509 verification: " "chain could not be linked to a trust anchor"); return CURLE_PEER_FAILED_VERIFICATION; + default:; } + failf(data, "BearSSL: connection error 0x%04x", err); /* X.509 errors are documented to have the range 32..63 */ if(err >= 32 && err < 64) return CURLE_PEER_FAILED_VERIFICATION; @@ -720,7 +725,8 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, return CURLE_OK; if(state & BR_SSL_SENDREC) { buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len); - ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, &result); + ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, FALSE, + &result); CURL_TRC_CF(data, cf, "ssl_send(len=%zu) -> %zd, %d", len, ret, result); if(ret <= 0) { if(result == CURLE_AGAIN) @@ -1089,8 +1095,10 @@ static CURLcode bearssl_shutdown(struct Curl_cfilter *cf, if(result == CURLE_OK) { *done = TRUE; } - else if(result == CURLE_AGAIN) + else if(result == CURLE_AGAIN) { + CURL_TRC_CF(data, cf, "shutdown EAGAIN, io_need=%x", connssl->io_need); result = CURLE_OK; + } else CURL_TRC_CF(data, cf, "shutdown error: %d", result); @@ -1131,7 +1139,12 @@ static CURLcode bearssl_sha256sum(const unsigned char *input, const struct Curl_ssl Curl_ssl_bearssl = { { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ - SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY, + + SSLSUPP_CAINFO_BLOB | + SSLSUPP_SSL_CTX | + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST, + sizeof(struct bearssl_ssl_backend_data), Curl_none_init, /* init */ @@ -1144,7 +1157,7 @@ const struct Curl_ssl Curl_ssl_bearssl = { Curl_none_cert_status_request, /* cert_status_request */ bearssl_connect, /* connect */ bearssl_connect_nonblocking, /* connect_nonblocking */ - bearssl_adjust_pollset, /* adjust_pollset */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ bearssl_get_internals, /* get_internals */ bearssl_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -1157,6 +1170,7 @@ const struct Curl_ssl Curl_ssl_bearssl = { NULL, /* disassociate_connection */ bearssl_recv, /* recv decrypted data */ bearssl_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif /* USE_BEARSSL */ diff --git a/lib/vtls/cipher_suite.c b/lib/vtls/cipher_suite.c index 83ac5ddfa..c025b53e9 100644 --- a/lib/vtls/cipher_suite.c +++ b/lib/vtls/cipher_suite.c @@ -23,7 +23,8 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ + defined(USE_BEARSSL) || defined(USE_RUSTLS) #include "cipher_suite.h" #include "curl_printf.h" #include "strcase.h" @@ -163,24 +164,24 @@ enum { CS_TXT_LEN, }; -#define CS_ZIP_IDX(a, b, c, d, e, f, g, h) \ -{ \ - (uint8_t) ((a) << 2 | ((b) & 0x3F) >> 4), \ - (uint8_t) ((b) << 4 | ((c) & 0x3F) >> 2), \ - (uint8_t) ((c) << 6 | ((d) & 0x3F)), \ - (uint8_t) ((e) << 2 | ((f) & 0x3F) >> 4), \ - (uint8_t) ((f) << 4 | ((g) & 0x3F) >> 2), \ - (uint8_t) ((g) << 6 | ((h) & 0x3F)) \ +#define CS_ZIP_IDX(a, b, c, d, e, f, g, h) \ +{ \ + (uint8_t) ((((a) << 2) & 0xFF) | ((b) & 0x3F) >> 4), \ + (uint8_t) ((((b) << 4) & 0xFF) | ((c) & 0x3F) >> 2), \ + (uint8_t) ((((c) << 6) & 0xFF) | ((d) & 0x3F)), \ + (uint8_t) ((((e) << 2) & 0xFF) | ((f) & 0x3F) >> 4), \ + (uint8_t) ((((f) << 4) & 0xFF) | ((g) & 0x3F) >> 2), \ + (uint8_t) ((((g) << 6) & 0xFF) | ((h) & 0x3F)) \ } -#define CS_ENTRY(id, a, b, c, d, e, f, g, h) \ -{ \ - id, \ - CS_ZIP_IDX( \ - CS_TXT_IDX_ ## a, CS_TXT_IDX_ ## b, \ - CS_TXT_IDX_ ## c, CS_TXT_IDX_ ## d, \ - CS_TXT_IDX_ ## e, CS_TXT_IDX_ ## f, \ - CS_TXT_IDX_ ## g, CS_TXT_IDX_ ## h \ - ) \ +#define CS_ENTRY(id, a, b, c, d, e, f, g, h) \ +{ \ + id, \ + CS_ZIP_IDX( \ + CS_TXT_IDX_ ## a, CS_TXT_IDX_ ## b, \ + CS_TXT_IDX_ ## c, CS_TXT_IDX_ ## d, \ + CS_TXT_IDX_ ## e, CS_TXT_IDX_ ## f, \ + CS_TXT_IDX_ ## g, CS_TXT_IDX_ ## h \ + ) \ } struct cs_entry { @@ -190,6 +191,28 @@ struct cs_entry { /* !checksrc! disable COMMANOSPACE all */ static const struct cs_entry cs_list [] = { + /* TLS 1.3 ciphers */ +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) + CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,), + CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,), + CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,), + CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,), + CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,), +#endif + /* TLS 1.2 ciphers */ + CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,), + CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,), +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) CS_ENTRY(0x002F, TLS,RSA,WITH,AES,128,CBC,SHA,), CS_ENTRY(0x002F, AES128,SHA,,,,,,), CS_ENTRY(0x0035, TLS,RSA,WITH,AES,256,CBC,SHA,), @@ -234,26 +257,15 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0xC029, ECDH,RSA,AES128,SHA256,,,,), CS_ENTRY(0xC02A, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA384), CS_ENTRY(0xC02A, ECDH,RSA,AES256,SHA384,,,,), - CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,), CS_ENTRY(0xC02D, TLS,ECDH,ECDSA,WITH,AES,128,GCM,SHA256), CS_ENTRY(0xC02D, ECDH,ECDSA,AES128,GCM,SHA256,,,), CS_ENTRY(0xC02E, TLS,ECDH,ECDSA,WITH,AES,256,GCM,SHA384), CS_ENTRY(0xC02E, ECDH,ECDSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,), CS_ENTRY(0xC031, TLS,ECDH,RSA,WITH,AES,128,GCM,SHA256), CS_ENTRY(0xC031, ECDH,RSA,AES128,GCM,SHA256,,,), CS_ENTRY(0xC032, TLS,ECDH,RSA,WITH,AES,256,GCM,SHA384), CS_ENTRY(0xC032, ECDH,RSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,), - CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,), +#endif #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) CS_ENTRY(0x0001, TLS,RSA,WITH,NULL,MD5,,,), CS_ENTRY(0x0001, NULL,MD5,,,,,,), @@ -327,11 +339,6 @@ static const struct cs_entry cs_list [] = { CS_ENTRY(0x00B8, RSA,PSK,NULL,SHA256,,,,), CS_ENTRY(0x00B9, TLS,RSA,PSK,WITH,NULL,SHA384,,), CS_ENTRY(0x00B9, RSA,PSK,NULL,SHA384,,,,), - CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,), - CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,), - CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,), - CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,), - CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,), CS_ENTRY(0xC001, TLS,ECDH,ECDSA,WITH,NULL,SHA,,), CS_ENTRY(0xC001, ECDH,ECDSA,NULL,SHA,,,,), CS_ENTRY(0xC006, TLS,ECDHE,ECDSA,WITH,NULL,SHA,,), @@ -881,4 +888,4 @@ int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, } #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) */ + defined(USE_BEARSSL) || defined(USE_RUSTLS) */ diff --git a/lib/vtls/cipher_suite.h b/lib/vtls/cipher_suite.h index 1dd4d7b40..6d980103a 100644 --- a/lib/vtls/cipher_suite.h +++ b/lib/vtls/cipher_suite.h @@ -26,7 +26,8 @@ #include "curl_setup.h" -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ + defined(USE_BEARSSL) || defined(USE_RUSTLS) #include /* Lookup IANA id for cipher suite string, returns 0 if not recognized */ @@ -43,5 +44,5 @@ int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, bool prefer_rfc); #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) */ + defined(USE_BEARSSL) || defined(USE_RUSTLS) */ #endif /* HEADER_CURL_CIPHER_SUITE_H */ diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 39c22c200..ad9a6b926 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -102,7 +102,7 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen) CURLcode result; DEBUGASSERT(data); - nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result); + nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &result); CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %zd, err=%d", blen, nwritten, result); backend->gtls.io_result = result; @@ -340,7 +340,7 @@ static CURLcode handshake(struct Curl_cfilter *cf, if(!strerr) strerr = gnutls_strerror(rc); - failf(data, "gnutls_handshake() failed: %s", strerr); + failf(data, "GnuTLS, handshake failed: %s", strerr); return CURLE_SSL_CONNECT_ERROR; } @@ -350,7 +350,7 @@ static CURLcode handshake(struct Curl_cfilter *cf, } } -static gnutls_x509_crt_fmt_t do_file_type(const char *type) +static gnutls_x509_crt_fmt_t gnutls_do_file_type(const char *type) { if(!type || !type[0]) return GNUTLS_X509_FMT_PEM; @@ -368,11 +368,11 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type) #define GNUTLS_SRP "+SRP" static CURLcode -set_ssl_version_min_max(struct Curl_easy *data, - struct ssl_peer *peer, - struct ssl_primary_config *conn_config, - const char **prioritylist, - const char *tls13support) +gnutls_set_ssl_version_min_max(struct Curl_easy *data, + struct ssl_peer *peer, + struct ssl_primary_config *conn_config, + const char **prioritylist, + const char *tls13support) { long ssl_version = conn_config->version; long ssl_version_max = conn_config->version_max; @@ -850,6 +850,13 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, init_flags |= GNUTLS_NO_TICKETS; #endif +#if defined(GNUTLS_NO_STATUS_REQUEST) + if(!config->verifystatus) + /* Disable the "status_request" TLS extension, enabled by default since + GnuTLS 3.8.0. */ + init_flags |= GNUTLS_NO_STATUS_REQUEST; +#endif + rc = gnutls_init(>ls->session, init_flags); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_init() failed: %d", rc); @@ -890,8 +897,8 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, } /* At this point we know we have a supported TLS version, so set it */ - result = set_ssl_version_min_max(data, peer, - config, &prioritylist, tls13support); + result = gnutls_set_ssl_version_min_max(data, peer, + config, &prioritylist, tls13support); if(result) return result; @@ -939,7 +946,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, gtls->shared_creds->creds, config->clientcert, ssl_config->key ? ssl_config->key : config->clientcert, - do_file_type(ssl_config->cert_type), + gnutls_do_file_type(ssl_config->cert_type), ssl_config->key_passwd, supported_key_encryption_algorithms); if(rc != GNUTLS_E_SUCCESS) { @@ -954,7 +961,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf, gtls->shared_creds->creds, config->clientcert, ssl_config->key ? ssl_config->key : config->clientcert, - do_file_type(ssl_config->cert_type) ) != + gnutls_do_file_type(ssl_config->cert_type) ) != GNUTLS_E_SUCCESS) { failf(data, "error reading X.509 key or certificate file"); return CURLE_SSL_CONNECT_ERROR; @@ -1295,9 +1302,18 @@ Curl_gtls_verifyserver(struct Curl_easy *data, /* verify_status is a bitmask of gnutls_certificate_status bits */ if(verify_status & GNUTLS_CERT_INVALID) { if(config->verifypeer) { - failf(data, "server certificate verification failed. CAfile: %s " - "CRLfile: %s", config->CAfile ? config->CAfile: - "none", + const char *cause = "certificate error, no details available"; + if(verify_status & GNUTLS_CERT_EXPIRED) + cause = "certificate has expired"; + else if(verify_status & GNUTLS_CERT_SIGNER_NOT_FOUND) + cause = "certificate signer not trusted"; + else if(verify_status & GNUTLS_CERT_INSECURE_ALGORITHM) + cause = "certificate uses insecure algorithm"; + else if(verify_status & GNUTLS_CERT_INVALID_OCSP_STATUS) + cause = "attached OCSP status response is invalid"; + failf(data, "server verification failed: %s. (CAfile: %s " + "CRLfile: %s)", cause, + config->CAfile ? config->CAfile: "none", ssl_config->primary.CRLfile ? ssl_config->primary.CRLfile : "none"); return CURLE_PEER_FAILED_VERIFICATION; @@ -1312,104 +1328,97 @@ Curl_gtls_verifyserver(struct Curl_easy *data, infof(data, " server certificate verification SKIPPED"); if(config->verifystatus) { - if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { - gnutls_datum_t status_request; - gnutls_ocsp_resp_t ocsp_resp; + gnutls_datum_t status_request; + gnutls_ocsp_resp_t ocsp_resp; + gnutls_ocsp_cert_status_t status; + gnutls_x509_crl_reason_t reason; - gnutls_ocsp_cert_status_t status; - gnutls_x509_crl_reason_t reason; + rc = gnutls_ocsp_status_request_get(session, &status_request); - rc = gnutls_ocsp_status_request_get(session, &status_request); + if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + failf(data, "No OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } - infof(data, " server certificate status verification FAILED"); + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } - if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - failf(data, "No OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } + gnutls_ocsp_resp_init(&ocsp_resp); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } + rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } - gnutls_ocsp_resp_init(&ocsp_resp); + (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, + &status, NULL, NULL, NULL, &reason); - rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } + switch(status) { + case GNUTLS_OCSP_CERT_GOOD: + break; - (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); + case GNUTLS_OCSP_CERT_REVOKED: { + const char *crl_reason; - switch(status) { - case GNUTLS_OCSP_CERT_GOOD: + switch(reason) { + default: + case GNUTLS_X509_CRLREASON_UNSPECIFIED: + crl_reason = "unspecified reason"; break; - case GNUTLS_OCSP_CERT_REVOKED: { - const char *crl_reason; - - switch(reason) { - default: - case GNUTLS_X509_CRLREASON_UNSPECIFIED: - crl_reason = "unspecified reason"; - break; - - case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: - crl_reason = "private key compromised"; - break; - - case GNUTLS_X509_CRLREASON_CACOMPROMISE: - crl_reason = "CA compromised"; - break; - - case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: - crl_reason = "affiliation has changed"; - break; + case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: + crl_reason = "private key compromised"; + break; - case GNUTLS_X509_CRLREASON_SUPERSEDED: - crl_reason = "certificate superseded"; - break; + case GNUTLS_X509_CRLREASON_CACOMPROMISE: + crl_reason = "CA compromised"; + break; - case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: - crl_reason = "operation has ceased"; - break; + case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: + crl_reason = "affiliation has changed"; + break; - case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: - crl_reason = "certificate is on hold"; - break; + case GNUTLS_X509_CRLREASON_SUPERSEDED: + crl_reason = "certificate superseded"; + break; - case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: - crl_reason = "will be removed from delta CRL"; - break; + case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: + crl_reason = "operation has ceased"; + break; - case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: - crl_reason = "privilege withdrawn"; - break; + case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: + crl_reason = "certificate is on hold"; + break; - case GNUTLS_X509_CRLREASON_AACOMPROMISE: - crl_reason = "AA compromised"; - break; - } + case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: + crl_reason = "will be removed from delta CRL"; + break; - failf(data, "Server certificate was revoked: %s", crl_reason); + case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: + crl_reason = "privilege withdrawn"; break; - } - default: - case GNUTLS_OCSP_CERT_UNKNOWN: - failf(data, "Server certificate status is unknown"); + case GNUTLS_X509_CRLREASON_AACOMPROMISE: + crl_reason = "AA compromised"; break; } - gnutls_ocsp_resp_deinit(ocsp_resp); + failf(data, "Server certificate was revoked: %s", crl_reason); + break; + } - return CURLE_SSL_INVALIDCERTSTATUS; + default: + case GNUTLS_OCSP_CERT_UNKNOWN: + failf(data, "Server certificate status is unknown"); + break; } - else - infof(data, " server certificate status verification OK"); + + gnutls_ocsp_resp_deinit(ocsp_resp); + if(status != GNUTLS_OCSP_CERT_GOOD) + return CURLE_SSL_INVALIDCERTSTATUS; } else infof(data, " server certificate status verification SKIPPED"); @@ -1769,28 +1778,44 @@ static bool gtls_data_pending(struct Curl_cfilter *cf, static ssize_t gtls_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *mem, - size_t len, + const void *buf, + size_t blen, CURLcode *curlcode) { struct ssl_connect_data *connssl = cf->ctx; struct gtls_ssl_backend_data *backend = (struct gtls_ssl_backend_data *)connssl->backend; ssize_t rc; + size_t nwritten, total_written = 0; (void)data; DEBUGASSERT(backend); - backend->gtls.io_result = CURLE_OK; - rc = gnutls_record_send(backend->gtls.session, mem, len); + while(blen) { + backend->gtls.io_result = CURLE_OK; + rc = gnutls_record_send(backend->gtls.session, buf, blen); - if(rc < 0) { - *curlcode = (rc == GNUTLS_E_AGAIN)? - CURLE_AGAIN : - (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR); + if(rc < 0) { + if(total_written && (rc == GNUTLS_E_AGAIN)) { + *curlcode = CURLE_OK; + rc = (ssize_t)total_written; + goto out; + } + *curlcode = (rc == GNUTLS_E_AGAIN)? + CURLE_AGAIN : + (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR); - rc = -1; + rc = -1; + goto out; + } + nwritten = (size_t)rc; + total_written += nwritten; + DEBUGASSERT(nwritten <= blen); + buf = (char *)buf + nwritten; + blen -= nwritten; } + rc = total_written; +out: return rc; } @@ -1828,6 +1853,7 @@ static CURLcode gtls_shutdown(struct Curl_cfilter *cf, CURL_TRC_CF(data, cf, "SSL shutdown, gnutls_bye EAGAIN"); connssl->io_need = gnutls_record_get_direction(backend->gtls.session)? CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; + backend->gtls.sent_shutdown = FALSE; result = CURLE_OK; goto out; } @@ -2019,6 +2045,7 @@ const struct Curl_ssl Curl_ssl_gnutls = { NULL, /* disassociate_connection */ gtls_recv, /* recv decrypted data */ gtls_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif /* USE_GNUTLS */ diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 2b6042df3..1c00cbe1d 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -200,7 +200,8 @@ static int mbedtls_bio_cf_write(void *bio, if(!data) return 0; - nwritten = Curl_conn_cf_send(cf->next, data, (char *)buf, blen, &result); + nwritten = Curl_conn_cf_send(cf->next, data, (char *)buf, blen, FALSE, + &result); CURL_TRC_CF(data, cf, "mbedtls_bio_cf_out_write(len=%zu) -> %zd, err=%d", blen, nwritten, result); if(nwritten < 0 && CURLE_AGAIN == result) { @@ -258,138 +259,91 @@ static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = #define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) -#if MBEDTLS_VERSION_NUMBER >= 0x03020000 -static CURLcode mbedtls_version_from_curl( - mbedtls_ssl_protocol_version* mbedver, long version) +static CURLcode +mbed_set_ssl_version_min_max(struct Curl_easy *data, + struct mbed_ssl_backend_data *backend, + struct ssl_primary_config *conn_config) { - switch(version) { + /* TLS 1.0 and TLS 1.1 were dropped with mbedTLS 3.0.0 (2021). So, since + * then, and before the introduction of TLS 1.3 in 3.6.0 (2024), this + * function basically always sets TLS 1.2 as min/max, unless given + * unsupported option values. */ + +#if MBEDTLS_VERSION_NUMBER < 0x03020000 + int ver_min = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ + int ver_max = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ +#else + /* mbedTLS 3.2.0 (2022) introduced new methods for setting TLS version */ + mbedtls_ssl_protocol_version ver_min = MBEDTLS_SSL_VERSION_TLS1_2; + mbedtls_ssl_protocol_version ver_max = MBEDTLS_SSL_VERSION_TLS1_2; +#endif + + switch(conn_config->version) { + case CURL_SSLVERSION_DEFAULT: +#if MBEDTLS_VERSION_NUMBER < 0x03000000 + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + ver_min = MBEDTLS_SSL_MINOR_VERSION_1; + break; + case CURL_SSLVERSION_TLSv1_1: + ver_min = MBEDTLS_SSL_MINOR_VERSION_2; + break; +#else + case CURL_SSLVERSION_TLSv1: case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: +#endif case CURL_SSLVERSION_TLSv1_2: - *mbedver = MBEDTLS_SSL_VERSION_TLS1_2; - return CURLE_OK; + /* ver_min = MBEDTLS_SSL_VERSION_TLS1_2; */ + break; case CURL_SSLVERSION_TLSv1_3: #ifdef TLS13_SUPPORT - *mbedver = MBEDTLS_SSL_VERSION_TLS1_3; - return CURLE_OK; -#else + ver_min = MBEDTLS_SSL_VERSION_TLS1_3; break; #endif + default: + failf(data, "mbedTLS: unsupported minimum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } - return CURLE_SSL_CONNECT_ERROR; -} -#else -static CURLcode mbedtls_version_from_curl(int *mbedver, long version) -{ -#if MBEDTLS_VERSION_NUMBER >= 0x03000000 - switch(version) { - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - *mbedver = MBEDTLS_SSL_MINOR_VERSION_3; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - break; - } -#else - switch(version) { - case CURL_SSLVERSION_TLSv1_0: - *mbedver = MBEDTLS_SSL_MINOR_VERSION_1; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1: - *mbedver = MBEDTLS_SSL_MINOR_VERSION_2; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2: - *mbedver = MBEDTLS_SSL_MINOR_VERSION_3; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - break; - } -#endif - - return CURLE_SSL_CONNECT_ERROR; -} -#endif - -static CURLcode -set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); -#if MBEDTLS_VERSION_NUMBER >= 0x03020000 - mbedtls_ssl_protocol_version mbedtls_ver_min = MBEDTLS_SSL_VERSION_TLS1_2; + switch(conn_config->version_max) { + case CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_TLSv1_3: #ifdef TLS13_SUPPORT - mbedtls_ssl_protocol_version mbedtls_ver_max = MBEDTLS_SSL_VERSION_TLS1_3; -#else - mbedtls_ssl_protocol_version mbedtls_ver_max = MBEDTLS_SSL_VERSION_TLS1_2; -#endif -#elif MBEDTLS_VERSION_NUMBER >= 0x03000000 - int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3; - int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_3; -#else - int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1; - int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1; + ver_max = MBEDTLS_SSL_VERSION_TLS1_3; + break; #endif - long ssl_version = conn_config->version; - long ssl_version_max = conn_config->version_max; - CURLcode result = CURLE_OK; - - DEBUGASSERT(backend); - - switch(ssl_version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ssl_version = CURL_SSLVERSION_TLSv1_0; - break; - } - - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: -#ifdef TLS13_SUPPORT - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; + case CURL_SSLVERSION_MAX_TLSv1_2: + /* ver_max = MBEDTLS_SSL_VERSION_TLS1_2; */ + break; +#if MBEDTLS_VERSION_NUMBER < 0x03000000 + case CURL_SSLVERSION_MAX_TLSv1_1: + ver_max = MBEDTLS_SSL_MINOR_VERSION_2; + break; + case CURL_SSLVERSION_MAX_TLSv1_0: + ver_max = MBEDTLS_SSL_MINOR_VERSION_1; + break; #else - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + case CURL_SSLVERSION_MAX_TLSv1_1: + case CURL_SSLVERSION_MAX_TLSv1_0: #endif - break; - } - - result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version); - if(result) { - failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); - return result; - } - result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16); - if(result) { - failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); - return result; + default: + failf(data, "mbedTLS: unsupported maximum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } -#if MBEDTLS_VERSION_NUMBER >= 0x03020000 - mbedtls_ssl_conf_min_tls_version(&backend->config, mbedtls_ver_min); - mbedtls_ssl_conf_max_tls_version(&backend->config, mbedtls_ver_max); -#else +#if MBEDTLS_VERSION_NUMBER < 0x03020000 mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - mbedtls_ver_min); + ver_min); mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - mbedtls_ver_max); -#endif - -#ifdef TLS13_SUPPORT - if(mbedtls_ver_min == MBEDTLS_SSL_VERSION_TLS1_3) { - mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED); - } - else { - mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL); - } + ver_max); #else - mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL); + mbedtls_ssl_conf_min_tls_version(&backend->config, ver_min); + mbedtls_ssl_conf_max_tls_version(&backend->config, ver_max); #endif - return result; + return CURLE_OK; } /* TLS_ECJPAKE_WITH_AES_128_CCM_8 (0xC0FF) is marked experimental @@ -428,11 +382,13 @@ mbed_cipher_suite_walk_str(const char **str, const char **end) static CURLcode mbed_set_selected_ciphers(struct Curl_easy *data, struct mbed_ssl_backend_data *backend, - const char *ciphers) + const char *ciphers12, + const char *ciphers13) { + const char *ciphers = ciphers12; const int *supported; int *selected; - size_t supported_len, count = 0, i; + size_t supported_len, count = 0, default13_count = 0, i, j; const char *ptr, *end; supported = mbedtls_ssl_list_ciphersuites(); @@ -443,6 +399,26 @@ mbed_set_selected_ciphers(struct Curl_easy *data, if(!selected) return CURLE_OUT_OF_MEMORY; +#ifndef TLS13_SUPPORT + (void) ciphers13, (void) j; +#else + if(!ciphers13) { + /* Add default TLSv1.3 ciphers to selection */ + for(j = 0; j < supported_len; j++) { + uint16_t id = (uint16_t) supported[j]; + if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) != 0) + continue; + + selected[count++] = id; + } + + default13_count = count; + } + else + ciphers = ciphers13; + +add_ciphers: +#endif for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); @@ -462,14 +438,38 @@ mbed_set_selected_ciphers(struct Curl_easy *data, /* No duplicates allowed (so selected cannot overflow) */ for(i = 0; i < count && selected[i] != id; i++); if(i < count) { - infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", - (int) (end - ptr), ptr); + if(i >= default13_count) + infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); continue; } selected[count++] = id; } +#ifdef TLS13_SUPPORT + if(ciphers == ciphers13 && ciphers12) { + ciphers = ciphers12; + goto add_ciphers; + } + + if(!ciphers12) { + /* Add default TLSv1.2 ciphers to selection */ + for(j = 0; j < supported_len; j++) { + uint16_t id = (uint16_t) supported[j]; + if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) == 0) + continue; + + /* No duplicates allowed (so selected cannot overflow) */ + for(i = 0; i < count && selected[i] != id; i++); + if(i < count) + continue; + + selected[count++] = id; + } + } +#endif + selected[count] = 0; if(count == 0) { @@ -485,19 +485,79 @@ mbed_set_selected_ciphers(struct Curl_easy *data, return CURLE_OK; } -#ifdef TLS13_SUPPORT -static int mbed_no_verify(void *udata, mbedtls_x509_crt *crt, +static void +mbed_dump_cert_info(struct Curl_easy *data, const mbedtls_x509_crt *crt) +{ +#if defined(CURL_DISABLE_VERBOSE_STRINGS) || \ + (MBEDTLS_VERSION_NUMBER >= 0x03000000 && defined(MBEDTLS_X509_REMOVE_INFO)) + (void) data, (void) crt; +#else + const size_t bufsize = 16384; + char *p, *buffer = malloc(bufsize); + + if(buffer && mbedtls_x509_crt_info(buffer, bufsize, " ", crt) > 0) { + infof(data, "Server certificate:"); + for(p = buffer; *p; p += *p != '\0') { + size_t s = strcspn(p, "\n"); + infof(data, "%.*s", (int) s, p); + p += s; + } + } + else + infof(data, "Unable to dump certificate information"); + + free(buffer); +#endif +} + +static void +mbed_extract_certinfo(struct Curl_easy *data, const mbedtls_x509_crt *crt) +{ + CURLcode result; + const mbedtls_x509_crt *cur; + int i; + + for(i = 0, cur = crt; cur; ++i, cur = cur->next); + result = Curl_ssl_init_certinfo(data, i); + + for(i = 0, cur = crt; result == CURLE_OK && cur; ++i, cur = cur->next) { + const char *beg = (const char *) cur->raw.p; + const char *end = beg + cur->raw.len; + result = Curl_extract_certinfo(data, i, beg, end); + } +} + +static int mbed_verify_cb(void *ptr, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { - (void)udata; - (void)crt; - (void)depth; - /* we clear any faults the mbedtls' own verification found. - * See */ - *flags = 0; + struct Curl_cfilter *cf = (struct Curl_cfilter *) ptr; + struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); + struct Curl_easy *data = CF_DATA_CURRENT(cf); + + if(depth == 0) { + if(data->set.verbose) + mbed_dump_cert_info(data, crt); + if(data->set.ssl.certinfo) + mbed_extract_certinfo(data, crt); + } + + if(!conn_config->verifypeer) + *flags = 0; + else if(!conn_config->verifyhost) + *flags &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; + + if(*flags) { +#if MBEDTLS_VERSION_NUMBER < 0x03000000 || !defined(MBEDTLS_X509_REMOVE_INFO) + char buf[128]; + mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags); + failf(data, "mbedTLS: %s", buf); +#else + failf(data, "mbedTLS: cerificate verification error 0x%08x", *flags); +#endif + } + return 0; } -#endif static CURLcode mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) @@ -755,16 +815,12 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) failf(data, "mbedTLS: ssl_config failed"); return CURLE_SSL_CONNECT_ERROR; } -#ifdef TLS13_SUPPORT - if(!verifypeer) { - /* Default verify behaviour changed in mbedtls v3.6.0 with TLS v1.3. - * On 1.3 connections, the handshake fails by default without trust - * anchors. We override this questionable change by installing our - * own verify callback that clears all errors. */ - mbedtls_ssl_conf_verify(&backend->config, mbed_no_verify, cf); - } -#endif + /* Always let mbedTLS verify certificates, if verifypeer or verifyhost are + * disabled we clear the corresponding error flags in the verify callback + * function. That is also where we log verification errors. */ + mbedtls_ssl_conf_verify(&backend->config, mbed_verify_cb, cf); + mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_init(&backend->ssl); backend->initialized = TRUE; @@ -773,29 +829,9 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) mbedtls_ssl_conf_cert_profile(&backend->config, &mbedtls_x509_crt_profile_fr); - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if MBEDTLS_VERSION_NUMBER < 0x03000000 - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_1); - infof(data, "mbedTLS: Set min SSL version to TLS 1.0"); - break; -#endif - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(cf, data); - if(result != CURLE_OK) - return result; - break; - } - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } + ret = mbed_set_ssl_version_min_max(data, backend, conn_config); + if(ret != CURLE_OK) + return ret; mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, &backend->ctr_drbg); @@ -813,9 +849,17 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) mbedtls_bio_cf_read, NULL /* rev_timeout() */); +#ifndef TLS13_SUPPORT if(conn_config->cipher_list) { CURLcode result = mbed_set_selected_ciphers(data, backend, - conn_config->cipher_list); + conn_config->cipher_list, + NULL); +#else + if(conn_config->cipher_list || conn_config->cipher_list13) { + CURLcode result = mbed_set_selected_ciphers(data, backend, + conn_config->cipher_list, + conn_config->cipher_list13); +#endif if(result != CURLE_OK) { failf(data, "mbedTLS: failed to set cipher suites"); return result; @@ -923,60 +967,6 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_OK; } -static int count_server_cert(const mbedtls_x509_crt *peercert) -{ - int count = 1; - - DEBUGASSERT(peercert); - - while(peercert->next) { - ++count; - peercert = peercert->next; - } - return count; -} - -static CURLcode collect_server_cert_single(struct Curl_easy *data, - const mbedtls_x509_crt *server_cert, - int idx) -{ - const char *beg, *end; - - DEBUGASSERT(server_cert); - - beg = (const char *)server_cert->raw.p; - end = beg + server_cert->raw.len; - return Curl_extract_certinfo(data, idx, beg, end); -} - -static CURLcode collect_server_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - const struct mbedtls_x509_crt *peercert) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - const bool show_verbose_server_cert = data->set.verbose; -#else - const bool show_verbose_server_cert = false; -#endif - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result = CURLE_PEER_FAILED_VERIFICATION; - int i, count; - - if(!show_verbose_server_cert && !ssl_config->certinfo) - return CURLE_OK; - - if(!peercert) - return result; - - count = count_server_cert(peercert); - result = Curl_ssl_init_certinfo(data, count); - for(i = 0 ; !result && peercert ; i++) { - result = collect_server_cert_single(data, peercert, i); - peercert = peercert->next; - } - return result; -} - static CURLcode mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -984,8 +974,6 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) struct ssl_connect_data *connssl = cf->ctx; struct mbed_ssl_backend_data *backend = (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - const mbedtls_x509_crt *peercert; #ifndef CURL_DISABLE_PROXY const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]: @@ -1029,69 +1017,22 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) cipher_id = (uint16_t) mbedtls_ssl_get_ciphersuite_id_from_ssl(&backend->ssl); mbed_cipher_suite_get_str(cipher_id, cipher_str, sizeof(cipher_str), true); - infof(data, "mbedTLS: Handshake complete, cipher is %s", cipher_str); + infof(data, "mbedTLS: %s Handshake complete, cipher is %s", + mbedtls_ssl_get_version(&backend->ssl), cipher_str); } #else - infof(data, "mbedTLS: Handshake complete"); + infof(data, "mbedTLS: %s Handshake complete", + mbedtls_ssl_get_version(&backend->ssl)); #endif - ret = mbedtls_ssl_get_verify_result(&backend->ssl); - - if(!conn_config->verifyhost) - /* Ignore hostname errors if verifyhost is disabled */ - ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; - - if(ret && conn_config->verifypeer) { - if(ret & MBEDTLS_X509_BADCERT_EXPIRED) - failf(data, "Cert verify failed: BADCERT_EXPIRED"); - - else if(ret & MBEDTLS_X509_BADCERT_REVOKED) - failf(data, "Cert verify failed: BADCERT_REVOKED"); - - else if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) - failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); - - else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) - failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); - - else if(ret & MBEDTLS_X509_BADCERT_FUTURE) - failf(data, "Cert verify failed: BADCERT_FUTURE"); - - return CURLE_PEER_FAILED_VERIFICATION; - } - - peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); - - if(peercert) { - const CURLcode result = collect_server_cert(cf, data, peercert); - if(result) - return result; - } - - if(peercert && data->set.verbose) { -#ifndef MBEDTLS_X509_REMOVE_INFO - const size_t bufsize = 16384; - char *buffer = malloc(bufsize); - - if(!buffer) - return CURLE_OUT_OF_MEMORY; - - if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) - infof(data, "Dumping cert info: %s", buffer); - else - infof(data, "Unable to dump certificate information"); - - free(buffer); -#else - infof(data, "Unable to dump certificate information"); -#endif - } if(pinnedpubkey) { int size; CURLcode result; + const mbedtls_x509_crt *peercert; mbedtls_x509_crt *p = NULL; unsigned char *pubkey = NULL; + peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); #if MBEDTLS_VERSION_NUMBER == 0x03000000 if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) { @@ -1668,7 +1609,11 @@ const struct Curl_ssl Curl_ssl_mbedtls = { SSLSUPP_CERTINFO | SSLSUPP_PINNEDPUBKEY | SSLSUPP_SSL_CTX | - SSLSUPP_HTTPS_PROXY, +#ifdef TLS13_SUPPORT + SSLSUPP_TLS13_CIPHERSUITES | +#endif + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST, sizeof(struct mbed_ssl_backend_data), @@ -1695,6 +1640,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = { NULL, /* disassociate_connection */ mbed_recv, /* recv decrypted data */ mbed_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif /* USE_MBEDTLS */ diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 8a65491b2..b2f9e718c 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -314,29 +314,36 @@ typedef unsigned long sslerr_t; #define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) #endif /* !LIBRESSL_VERSION_NUMBER */ -#define push_certinfo(_label, _num) \ -do { \ - long info_len = BIO_get_mem_data(mem, &ptr); \ - Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ - if(1 != BIO_reset(mem)) \ - break; \ -} while(0) +static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl); + +static CURLcode push_certinfo(struct Curl_easy *data, + BIO *mem, const char *label, int num) + WARN_UNUSED_RESULT; -static void pubkey_show(struct Curl_easy *data, - BIO *mem, - int num, - const char *type, - const char *name, - const BIGNUM *bn) +static CURLcode push_certinfo(struct Curl_easy *data, + BIO *mem, const char *label, int num) { char *ptr; + long len = BIO_get_mem_data(mem, &ptr); + CURLcode result = Curl_ssl_push_certinfo_len(data, num, label, ptr, len); + (void)BIO_reset(mem); + return result; +} + +static CURLcode pubkey_show(struct Curl_easy *data, + BIO *mem, + int num, + const char *type, + const char *name, + const BIGNUM *bn) +{ char namebuf[32]; msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); if(bn) BN_print(mem, bn); - push_certinfo(namebuf, num); + return push_certinfo(data, mem, namebuf, num); } #ifdef HAVE_OPAQUE_RSA_DSA_DH @@ -368,15 +375,16 @@ static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) return 0; } -static void X509V3_ext(struct Curl_easy *data, - int certnum, - CONST_EXTS STACK_OF(X509_EXTENSION) *exts) +static CURLcode X509V3_ext(struct Curl_easy *data, + int certnum, + CONST_EXTS STACK_OF(X509_EXTENSION) *exts) { int i; + CURLcode result = CURLE_OK; if((int)sk_X509_EXTENSION_num(exts) <= 0) /* no extensions, bail out */ - return; + return result; for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; @@ -386,7 +394,7 @@ static void X509V3_ext(struct Curl_easy *data, BIO *bio_out = BIO_new(BIO_s_mem()); if(!bio_out) - return; + return result; obj = X509_EXTENSION_get_object(ext); @@ -396,13 +404,16 @@ static void X509V3_ext(struct Curl_easy *data, ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); BIO_get_mem_ptr(bio_out, &biomem); - Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, - biomem->length); + result = Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, + biomem->length); BIO_free(bio_out); + if(result) + break; } + return result; } -CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) +static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl) { CURLcode result; STACK_OF(X509) *sk; @@ -420,38 +431,43 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) numcerts = sk_X509_num(sk); result = Curl_ssl_init_certinfo(data, (int)numcerts); - if(result) { + if(result) return result; - } mem = BIO_new(BIO_s_mem()); - if(!mem) { - return CURLE_OUT_OF_MEMORY; - } + if(!mem) + result = CURLE_OUT_OF_MEMORY; - for(i = 0; i < (int)numcerts; i++) { + for(i = 0; !result && (i < (int)numcerts); i++) { ASN1_INTEGER *num; X509 *x = sk_X509_value(sk, (ossl_valsize_t)i); EVP_PKEY *pubkey = NULL; int j; - char *ptr; const ASN1_BIT_STRING *psig = NULL; X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Subject", i); + result = push_certinfo(data, mem, "Subject", i); + if(result) + break; X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Issuer", i); + result = push_certinfo(data, mem, "Issuer", i); + if(result) + break; BIO_printf(mem, "%lx", X509_get_version(x)); - push_certinfo("Version", i); + result = push_certinfo(data, mem, "Version", i); + if(result) + break; num = X509_get_serialNumber(x); if(num->type == V_ASN1_NEG_INTEGER) BIO_puts(mem, "-"); for(j = 0; j < num->length; j++) BIO_printf(mem, "%02x", num->data[j]); - push_certinfo("Serial Number", i); + result = push_certinfo(data, mem, "Serial Number", i); + if(result) + break; #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) { @@ -464,7 +480,9 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) const ASN1_OBJECT *sigalgoid = NULL; X509_ALGOR_get0(&sigalgoid, NULL, NULL, sigalg); i2a_ASN1_OBJECT(mem, sigalgoid); - push_certinfo("Signature Algorithm", i); + result = push_certinfo(data, mem, "Signature Algorithm", i); + if(result) + break; } xpubkey = X509_get_X509_PUBKEY(x); @@ -472,11 +490,15 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); if(pubkeyoid) { i2a_ASN1_OBJECT(mem, pubkeyoid); - push_certinfo("Public Key Algorithm", i); + result = push_certinfo(data, mem, "Public Key Algorithm", i); + if(result) + break; } } - X509V3_ext(data, i, X509_get0_extensions(x)); + result = X509V3_ext(data, i, X509_get0_extensions(x)); + if(result) + break; } #else { @@ -484,22 +506,32 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) X509_CINF *cinf = x->cert_info; i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); - push_certinfo("Signature Algorithm", i); + result = push_certinfo(data, mem, "Signature Algorithm", i); - i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); - push_certinfo("Public Key Algorithm", i); + if(!result) { + i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); + result = push_certinfo(data, mem, "Public Key Algorithm", i); + } - X509V3_ext(data, i, cinf->extensions); + if(!result) + result = X509V3_ext(data, i, cinf->extensions); + + if(result) + break; psig = x->signature; } #endif ASN1_TIME_print(mem, X509_get0_notBefore(x)); - push_certinfo("Start date", i); + result = push_certinfo(data, mem, "Start date", i); + if(result) + break; ASN1_TIME_print(mem, X509_get0_notAfter(x)); - push_certinfo("Expire date", i); + result = push_certinfo(data, mem, "Expire date", i); + if(result) + break; pubkey = X509_get_pubkey(x); if(!pubkey) @@ -512,8 +544,7 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) pktype = pubkey->type; #endif switch(pktype) { - case EVP_PKEY_RSA: - { + case EVP_PKEY_RSA: { #ifndef HAVE_EVP_PKEY_GET_PARAMS RSA *rsa; #ifdef HAVE_OPAQUE_EVP_PKEY @@ -537,7 +568,9 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) #else BIO_printf(mem, "%d", rsa->n ? BN_num_bits(rsa->n) : 0); #endif /* HAVE_OPAQUE_RSA_DSA_DH */ - push_certinfo("RSA Public Key", i); + result = push_certinfo(data, mem, "RSA Public Key", i); + if(result) + break; print_pubkey_BN(rsa, n, i); print_pubkey_BN(rsa, e, i); FREE_PKEY_PARAM_BIGNUM(n); @@ -585,8 +618,7 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) #endif /* !OPENSSL_NO_DSA */ break; } - case EVP_PKEY_DH: - { + case EVP_PKEY_DH: { #ifndef HAVE_EVP_PKEY_GET_PARAMS DH *dh; #ifdef HAVE_OPAQUE_EVP_PKEY @@ -629,19 +661,25 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) EVP_PKEY_free(pubkey); } - if(psig) { + if(!result && psig) { for(j = 0; j < psig->length; j++) BIO_printf(mem, "%02x:", psig->data[j]); - push_certinfo("Signature", i); + result = push_certinfo(data, mem, "Signature", i); } - PEM_write_bio_X509(mem, x); - push_certinfo("Cert", i); + if(!result) { + PEM_write_bio_X509(mem, x); + result = push_certinfo(data, mem, "Cert", i); + } } BIO_free(mem); - return CURLE_OK; + if(result) + /* cleanup all leftovers */ + Curl_ssl_free_certinfo(data); + + return result; } #endif /* quiche or OpenSSL */ @@ -723,7 +761,8 @@ static int ossl_bio_cf_out_write(BIO *bio, const char *buf, int blen) if(blen < 0) return 0; - nwritten = Curl_conn_cf_send(cf->next, data, buf, (size_t)blen, &result); + nwritten = Curl_conn_cf_send(cf->next, data, buf, (size_t)blen, FALSE, + &result); CURL_TRC_CF(data, cf, "ossl_bio_cf_out_write(len=%d) -> %d, err=%d", blen, (int)nwritten, result); BIO_clear_retry_flags(bio); @@ -997,12 +1036,6 @@ static CURLcode ossl_seed(struct Curl_easy *data) return CURLE_SSL_CONNECT_ERROR; #else -#ifdef RANDOM_FILE - RAND_load_file(RANDOM_FILE, RAND_LOAD_LENGTH); - if(rand_enough()) - return CURLE_OK; -#endif - /* fallback to a custom seeding of the PRNG using a hash based on a current time */ do { @@ -1049,7 +1082,7 @@ static CURLcode ossl_seed(struct Curl_easy *data) #ifndef SSL_FILETYPE_PKCS12 #define SSL_FILETYPE_PKCS12 43 #endif -static int do_file_type(const char *type) +static int ossl_do_file_type(const char *type) { if(!type || !type[0]) return SSL_FILETYPE_PEM; @@ -1271,7 +1304,7 @@ int cert_stuff(struct Curl_easy *data, char error_buffer[256]; bool check_privkey = TRUE; - int file_type = do_file_type(cert_type); + int file_type = ossl_do_file_type(cert_type); if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE)) { SSL *ssl; @@ -1512,7 +1545,7 @@ int cert_stuff(struct Curl_easy *data, key_blob = cert_blob; } else - file_type = do_file_type(key_type); + file_type = ossl_do_file_type(key_type); switch(file_type) { case SSL_FILETYPE_PEM: @@ -1646,22 +1679,6 @@ int cert_stuff(struct Curl_easy *data, return 1; } -CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data, SSL_CTX *ctx, - char *cert_file, - const struct curl_blob *cert_blob, - const char *cert_type, char *key_file, - const struct curl_blob *key_blob, - const char *key_type, char *key_passwd) -{ - int rv = cert_stuff(data, ctx, cert_file, cert_blob, cert_type, key_file, - key_blob, key_type, key_passwd); - if(rv != 1) { - return CURLE_SSL_CERTPROBLEM; - } - - return CURLE_OK; -} - /* returns non-zero on failure */ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) { @@ -1878,7 +1895,7 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf, struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; CURLcode result = CURLE_OK; char buf[1024]; - int nread, err; + int nread = -1, err; unsigned long sslerr; size_t i; @@ -1919,15 +1936,26 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf, goto out; } } - if(send_shutdown && SSL_shutdown(octx->ssl) == 1) { + } + + /* SSL should now have started the shutdown from our side. Since it + * was not complete, we are lacking the close notify from the server. */ + if(send_shutdown) { + ERR_clear_error(); + if(SSL_shutdown(octx->ssl) == 1) { CURL_TRC_CF(data, cf, "SSL shutdown finished"); *done = TRUE; goto out; } + if(SSL_ERROR_WANT_WRITE == SSL_get_error(octx->ssl, nread)) { + CURL_TRC_CF(data, cf, "SSL shutdown still wants to send"); + connssl->io_need = CURL_SSL_IO_NEED_SEND; + goto out; + } + /* Having sent the close notify, we use SSL_read() to get the + * missing close notify from the server. */ } - /* SSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ for(i = 0; i < 10; ++i) { ERR_clear_error(); nread = SSL_read(octx->ssl, buf, (int)sizeof(buf)); @@ -1935,11 +1963,6 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf, if(nread <= 0) break; } - if(SSL_get_shutdown(octx->ssl) & SSL_RECEIVED_SHUTDOWN) { - CURL_TRC_CF(data, cf, "SSL shutdown received, finished"); - *done = TRUE; - goto out; - } err = SSL_get_error(octx->ssl, nread); switch(err) { case SSL_ERROR_ZERO_RETURN: /* no more data */ @@ -2003,7 +2026,7 @@ static void ossl_session_free(void *sessionid, size_t idsize) { /* free the ID */ (void)idsize; - SSL_SESSION_free(sessionid); + free(sessionid); } /* @@ -2077,8 +2100,9 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, This function is now used from ngtcp2 (QUIC) as well. */ -CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - struct ssl_peer *peer, X509 *server_cert) +static CURLcode ossl_verifyhost(struct Curl_easy *data, + struct connectdata *conn, + struct ssl_peer *peer, X509 *server_cert) { bool matched = FALSE; int target; /* target type, GEN_DNS or GEN_IPADD */ @@ -2868,6 +2892,9 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf, { const struct ssl_config_data *config; CURLcode result = CURLE_OK; + size_t der_session_size; + unsigned char *der_session_buf; + unsigned char *der_session_ptr; if(!cf || !data) goto out; @@ -2875,16 +2902,32 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf, config = Curl_ssl_cf_get_config(cf, data); if(config->primary.cache_session) { + der_session_size = i2d_SSL_SESSION(session, NULL); + if(der_session_size == 0) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + der_session_buf = der_session_ptr = malloc(der_session_size); + if(!der_session_buf) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + der_session_size = i2d_SSL_SESSION(session, &der_session_ptr); + if(der_session_size == 0) { + result = CURLE_OUT_OF_MEMORY; + free(der_session_buf); + goto out; + } + Curl_ssl_sessionid_lock(data); - result = Curl_ssl_set_sessionid(cf, data, peer, session, 0, - ossl_session_free); - session = NULL; /* call has taken ownership */ + result = Curl_ssl_set_sessionid(cf, data, peer, der_session_buf, + der_session_size, ossl_session_free); Curl_ssl_sessionid_unlock(data); } out: - if(session) - ossl_session_free(session, 0); return result; } @@ -2901,7 +2944,7 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) connssl = cf? cf->ctx : NULL; data = connssl? CF_DATA_CURRENT(cf) : NULL; Curl_ossl_add_session(cf, data, &connssl->peer, ssl_sessionid); - return 1; + return 0; } static CURLcode load_cacert_from_memory(X509_STORE *store, @@ -3451,7 +3494,9 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, const char *ciphers; SSL_METHOD_QUAL SSL_METHOD *req_method = NULL; ctx_option_t ctx_options = 0; - void *ssl_sessionid = NULL; + SSL_SESSION *ssl_session = NULL; + const unsigned char *der_sessionid = NULL; + size_t der_sessionid_size = 0; struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); const long int ssl_version_min = conn_config->version; @@ -3631,6 +3676,11 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, SSL_CTX_set_options(octx->ssl_ctx, ctx_options); +#ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER + /* We do retry writes sometimes from another buffer address */ + SSL_CTX_set_mode(octx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); +#endif + #ifdef HAS_ALPN if(alpn && alpn_len) { if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) { @@ -3897,7 +3947,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, if(data->set.tls_ech & CURLECH_HARD) return CURLE_SSL_CONNECT_ERROR; } - Curl_resolv_unlock(data, dns); + Curl_resolv_unlink(data, &dns); } } # ifdef OPENSSL_IS_BORINGSSL @@ -3931,18 +3981,29 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, octx->reused_session = FALSE; if(ssl_config->primary.cache_session && transport == TRNSPRT_TCP) { Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(cf, data, peer, &ssl_sessionid, NULL)) { + if(!Curl_ssl_getsessionid(cf, data, peer, (void **)&der_sessionid, + &der_sessionid_size)) { /* we got a session id, use it! */ - if(!SSL_set_session(octx->ssl, ssl_sessionid)) { - Curl_ssl_sessionid_unlock(data); - failf(data, "SSL: SSL_set_session failed: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CONNECT_ERROR; + ssl_session = d2i_SSL_SESSION(NULL, &der_sessionid, + (long)der_sessionid_size); + if(ssl_session) { + if(!SSL_set_session(octx->ssl, ssl_session)) { + Curl_ssl_sessionid_unlock(data); + SSL_SESSION_free(ssl_session); + failf(data, "SSL: SSL_set_session failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; + } + SSL_SESSION_free(ssl_session); + /* Informational message */ + infof(data, "SSL reusing session ID"); + octx->reused_session = TRUE; + } + else { + Curl_ssl_sessionid_unlock(data); + return CURLE_SSL_CONNECT_ERROR; } - /* Informational message */ - infof(data, "SSL reusing session ID"); - octx->reused_session = TRUE; } Curl_ssl_sessionid_unlock(data); } @@ -4110,30 +4171,34 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, <0 is "handshake was not successful, because a fatal error occurred" */ if(1 != err) { int detail = SSL_get_error(octx->ssl, err); + CURL_TRC_CF(data, cf, "SSL_connect() -> err=%d, detail=%d", err, detail); if(SSL_ERROR_WANT_READ == detail) { + CURL_TRC_CF(data, cf, "SSL_connect() -> want recv"); connssl->io_need = CURL_SSL_IO_NEED_RECV; return CURLE_OK; } if(SSL_ERROR_WANT_WRITE == detail) { + CURL_TRC_CF(data, cf, "SSL_connect() -> want send"); connssl->io_need = CURL_SSL_IO_NEED_SEND; return CURLE_OK; } #ifdef SSL_ERROR_WANT_ASYNC if(SSL_ERROR_WANT_ASYNC == detail) { + CURL_TRC_CF(data, cf, "SSL_connect() -> want async"); + connssl->io_need = CURL_SSL_IO_NEED_RECV; connssl->connecting_state = ssl_connect_2; return CURLE_OK; } #endif #ifdef SSL_ERROR_WANT_RETRY_VERIFY if(SSL_ERROR_WANT_RETRY_VERIFY == detail) { + CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify"); + connssl->io_need = CURL_SSL_IO_NEED_RECV; connssl->connecting_state = ssl_connect_2; return CURLE_OK; } #endif - if(octx->io_result == CURLE_AGAIN) { - return CURLE_OK; - } else { /* untreated error */ sslerr_t errdetail; @@ -4488,7 +4553,7 @@ CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf, if(data->set.ssl.certinfo) /* asked to gather certificate info */ - (void)Curl_ossl_certchain(data, octx->ssl); + (void)ossl_certchain(data, octx->ssl); octx->server_cert = SSL_get1_peer_certificate(octx->ssl); if(!octx->server_cert) { @@ -4525,7 +4590,7 @@ CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf, BIO_free(mem); if(conn_config->verifyhost) { - result = Curl_ossl_verifyhost(data, conn, peer, octx->server_cert); + result = ossl_verifyhost(data, conn, peer, octx->server_cert); if(result) { X509_free(octx->server_cert); octx->server_cert = NULL; @@ -4721,6 +4786,7 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); int what; + connssl->io_need = CURL_SSL_IO_NEED_NONE; /* check if the connection has already been established */ if(ssl_connection_complete == connssl->state) { *done = TRUE; @@ -4867,6 +4933,7 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, ERR_clear_error(); + connssl->io_need = CURL_SSL_IO_NEED_NONE; memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; rc = SSL_write(octx->ssl, mem, memlen); @@ -4875,10 +4942,11 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, switch(err) { case SSL_ERROR_WANT_READ: + connssl->io_need = CURL_SSL_IO_NEED_RECV; + *curlcode = CURLE_AGAIN; + rc = -1; + goto out; case SSL_ERROR_WANT_WRITE: - /* The operation did not complete; the same TLS/SSL I/O function - should be called again later. This is basically an EWOULDBLOCK - equivalent. */ *curlcode = CURLE_AGAIN; rc = -1; goto out; @@ -4950,6 +5018,7 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, ERR_clear_error(); + connssl->io_need = CURL_SSL_IO_NEED_NONE; buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; nread = (ssize_t)SSL_read(octx->ssl, buf, buffsize); @@ -4968,8 +5037,11 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, connclose(conn, "TLS close_notify"); break; case SSL_ERROR_WANT_READ: + *curlcode = CURLE_AGAIN; + nread = -1; + goto out; case SSL_ERROR_WANT_WRITE: - /* there is data pending, re-invoke SSL_read() */ + connssl->io_need = CURL_SSL_IO_NEED_SEND; *curlcode = CURLE_AGAIN; nread = -1; goto out; @@ -5032,6 +5104,91 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, return nread; } +static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex, + struct dynbuf *binding) +{ + /* required for X509_get_signature_nid support */ +#if OPENSSL_VERSION_NUMBER > 0x10100000L + X509 *cert; + int algo_nid; + const EVP_MD *algo_type; + const char *algo_name; + unsigned int length; + unsigned char buf[EVP_MAX_MD_SIZE]; + + const char prefix[] = "tls-server-end-point:"; + struct connectdata *conn = data->conn; + struct Curl_cfilter *cf = conn->cfilter[sockindex]; + struct ossl_ctx *octx = NULL; + + do { + const struct Curl_cftype *cft = cf->cft; + struct ssl_connect_data *connssl = cf->ctx; + + if(cft->name && !strcmp(cft->name, "SSL")) { + octx = (struct ossl_ctx *)connssl->backend; + break; + } + + if(cf->next) + cf = cf->next; + + } while(cf->next); + + if(!octx) { + failf(data, + "Failed to find SSL backend for endpoint"); + return CURLE_SSL_ENGINE_INITFAILED; + } + + cert = SSL_get1_peer_certificate(octx->ssl); + if(!cert) { + /* No server certificate, don't do channel binding */ + return CURLE_OK; + } + + if(!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &algo_nid, NULL)) { + failf(data, + "Unable to find digest NID for certificate signature algorithm"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + /* https://datatracker.ietf.org/doc/html/rfc5929#section-4.1 */ + if(algo_nid == NID_md5 || algo_nid == NID_sha1) { + algo_type = EVP_sha256(); + } + else { + algo_type = EVP_get_digestbynid(algo_nid); + if(!algo_type) { + algo_name = OBJ_nid2sn(algo_nid); + failf(data, "Could not find digest algorithm %s (NID %d)", + algo_name ? algo_name : "(null)", algo_nid); + return CURLE_SSL_INVALIDCERTSTATUS; + } + } + + if(!X509_digest(cert, algo_type, buf, &length)) { + failf(data, "X509_digest() failed"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + /* Append "tls-server-end-point:" */ + if(Curl_dyn_addn(binding, prefix, sizeof(prefix) - 1) != CURLE_OK) + return CURLE_OUT_OF_MEMORY; + /* Append digest */ + if(Curl_dyn_addn(binding, buf, length)) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +#else + /* No X509_get_signature_nid support */ + (void)data; /* unused */ + (void)sockindex; /* unused */ + (void)binding; /* unused */ + return CURLE_OK; +#endif +} + static size_t ossl_version(char *buffer, size_t size) { #ifdef LIBRESSL_VERSION_NUMBER @@ -5189,7 +5346,8 @@ const struct Curl_ssl Curl_ssl_openssl = { SSLSUPP_ECH | #endif SSLSUPP_CA_CACHE | - SSLSUPP_HTTPS_PROXY, + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST, sizeof(struct ossl_ctx), @@ -5220,6 +5378,7 @@ const struct Curl_ssl Curl_ssl_openssl = { NULL, /* remote of data from this connection */ ossl_recv, /* recv decrypted data */ ossl_send, /* send data to encrypt */ + ossl_get_channel_binding /* get_channel_binding */ }; #endif /* USE_OPENSSL */ diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h index b0d78478a..7aba947d1 100644 --- a/lib/vtls/openssl.h +++ b/lib/vtls/openssl.h @@ -74,19 +74,8 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, #define SSL_get1_peer_certificate SSL_get_peer_certificate #endif -CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - struct ssl_peer *peer, X509 *server_cert); extern const struct Curl_ssl Curl_ssl_openssl; -CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data, - SSL_CTX *ctx, char *cert_file, - const struct curl_blob *cert_blob, - const char *cert_type, char *key_file, - const struct curl_blob *key_blob, - const char *key_type, char *key_passwd); - -CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl); - /** * Setup the OpenSSL X509_STORE in `ssl_ctx` for the cfilter `cf` and * easy handle `data`. Will allow reuse of a shared cache if suitable diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index bdcd08ab9..cc8641009 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -41,6 +41,8 @@ #include "strerror.h" #include "multiif.h" #include "connect.h" /* for the connect timeout */ +#include "cipher_suite.h" +#include "rand.h" struct rustls_ssl_backend_data { @@ -115,7 +117,8 @@ write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) CURLcode result; int ret = 0; ssize_t nwritten = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, - (const char *)buf, len, &result); + (const char *)buf, len, FALSE, + &result); if(nwritten < 0) { nwritten = 0; if(CURLE_AGAIN == result) @@ -174,14 +177,14 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf, /* * On each run: - * - Read a chunk of bytes from the socket into rustls' TLS input buffer. - * - Tell rustls to process any new packets. - * - Read out as many plaintext bytes from rustls as possible, until hitting + * - Read a chunk of bytes from the socket into Rustls' TLS input buffer. + * - Tell Rustls to process any new packets. + * - Read out as many plaintext bytes from Rustls as possible, until hitting * error, EOF, or EAGAIN/EWOULDBLOCK, or plainbuf/plainlen is filled up. * * it is okay to call this function with plainbuf == NULL and plainlen == 0. In - * that case, it will copy bytes from the socket into rustls' TLS input - * buffer, and process packets, but will not consume bytes from rustls' + * that case, it will copy bytes from the socket into Rustls' TLS input + * buffer, and process packets, but will not consume bytes from Rustls' * plaintext output buffer. */ static ssize_t @@ -305,13 +308,13 @@ static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data, /* * On each call: - * - Copy `plainlen` bytes into rustls' plaintext input buffer (if > 0). - * - Fully drain rustls' plaintext output buffer into the socket until + * - Copy `plainlen` bytes into Rustls' plaintext input buffer (if > 0). + * - Fully drain Rustls' plaintext output buffer into the socket until * we get either an error or EAGAIN/EWOULDBLOCK. * * it is okay to call this function with plainbuf == NULL and plainlen == 0. - * In that case, it will not read anything into rustls' plaintext input buffer. - * It will only drain rustls' plaintext output buffer into the socket. + * In that case, it will not read anything into Rustls' plaintext input buffer. + * It will only drain Rustls' plaintext output buffer into the socket. */ static ssize_t cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -356,7 +359,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, } if(blen > 0) { - CURL_TRC_CF(data, cf, "cf_send: adding %zu plain bytes to rustls", blen); + CURL_TRC_CF(data, cf, "cf_send: adding %zu plain bytes to Rustls", blen); rresult = rustls_connection_write(rconn, buf, blen, &plainwritten); if(rresult != RUSTLS_RESULT_OK) { rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); @@ -375,9 +378,9 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, if(*err) { if(CURLE_AGAIN == *err) { /* The TLS bytes may have been partially written, but we fail the - * complete send() and remember how much we already added to rustls. */ + * complete send() and remember how much we already added to Rustls. */ CURL_TRC_CF(data, cf, "cf_send: EAGAIN, remember we added %zu plain" - " bytes already to rustls", blen); + " bytes already to Rustls", blen); backend->plain_out_buffered = plainwritten; if(nwritten) { *err = CURLE_OK; @@ -394,7 +397,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, return nwritten; } -/* A server certificate verify callback for rustls that always returns +/* A server certificate verify callback for Rustls that always returns RUSTLS_RESULT_OK, or in other words disable certificate verification. */ static uint32_t cr_verify_none(void *userdata UNUSED_PARAM, @@ -403,20 +406,121 @@ cr_verify_none(void *userdata UNUSED_PARAM, return RUSTLS_RESULT_OK; } -static bool -cr_hostname_is_ip(const char *hostname) +static int +read_file_into(const char *filename, + struct dynbuf *out) { - struct in_addr in; -#ifdef USE_IPV6 - struct in6_addr in6; - if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) { - return true; + FILE *f = fopen(filename, FOPEN_READTEXT); + if(!f) { + return 0; } -#endif /* USE_IPV6 */ - if(Curl_inet_pton(AF_INET, hostname, &in) > 0) { - return true; + + while(!feof(f)) { + uint8_t buf[256]; + size_t rr = fread(buf, 1, sizeof(buf), f); + if(rr == 0 || + CURLE_OK != Curl_dyn_addn(out, buf, rr)) { + fclose(f); + return 0; + } } - return false; + + return fclose(f) == 0; +} + +static void +cr_get_selected_ciphers(struct Curl_easy *data, + const char *ciphers12, + const char *ciphers13, + const struct rustls_supported_ciphersuite **selected, + size_t *selected_size) +{ + size_t supported_len = *selected_size; + size_t default_len = rustls_default_ciphersuites_len(); + const struct rustls_supported_ciphersuite *entry; + const char *ciphers = ciphers12; + size_t count = 0, default13_count = 0, i, j; + const char *ptr, *end; + + DEBUGASSERT(default_len <= supported_len); + + if(!ciphers13) { + /* Add default TLSv1.3 ciphers to selection */ + for(j = 0; j < default_len; j++) { + struct rustls_str s; + entry = rustls_default_ciphersuites_get_entry(j); + s = rustls_supported_ciphersuite_get_name(entry); + if(s.len < 5 || strncmp(s.data, "TLS13", 5) != 0) + continue; + + selected[count++] = entry; + } + + default13_count = count; + + if(!ciphers) + ciphers = ""; + } + else + ciphers = ciphers13; + +add_ciphers: + for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { + uint16_t id = Curl_cipher_suite_walk_str(&ptr, &end); + + /* Check if cipher is supported */ + if(id) { + for(i = 0; i < supported_len; i++) { + entry = rustls_all_ciphersuites_get_entry(i); + if(rustls_supported_ciphersuite_get_suite(entry) == id) + break; + } + if(i == supported_len) + id = 0; + } + if(!id) { + if(ptr[0] != '\0') + infof(data, "rustls: unknown cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); + continue; + } + + /* No duplicates allowed (so selected cannot overflow) */ + for(i = 0; i < count && selected[i] != entry; i++); + if(i < count) { + if(i >= default13_count) + infof(data, "rustls: duplicate cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); + continue; + } + + selected[count++] = entry; + } + + if(ciphers == ciphers13 && ciphers12) { + ciphers = ciphers12; + goto add_ciphers; + } + + if(!ciphers12) { + /* Add default TLSv1.2 ciphers to selection */ + for(j = 0; j < default_len; j++) { + struct rustls_str s; + entry = rustls_default_ciphersuites_get_entry(j); + s = rustls_supported_ciphersuite_get_name(entry); + if(s.len < 5 || strncmp(s.data, "TLS13", 5) == 0) + continue; + + /* No duplicates allowed (so selected cannot overflow) */ + for(i = 0; i < count && selected[i] != entry; i++); + if(i < count) + continue; + + selected[count++] = entry; + } + } + + *selected_size = count; } static CURLcode @@ -436,7 +540,6 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ (ca_info_blob ? NULL : conn_config->CAfile); const bool verifypeer = conn_config->verifypeer; - const char *hostname = connssl->peer.hostname; char errorbuf[256]; size_t errorlen; rustls_result result; @@ -444,7 +547,75 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, DEBUGASSERT(backend); rconn = backend->conn; - config_builder = rustls_client_config_builder_new(); + { + uint16_t tls_versions[2] = { + RUSTLS_TLS_VERSION_TLSV1_2, + RUSTLS_TLS_VERSION_TLSV1_3, + }; + size_t tls_versions_len = 2; + const struct rustls_supported_ciphersuite **cipher_suites; + size_t cipher_suites_len = rustls_default_ciphersuites_len(); + + switch(conn_config->version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + break; + case CURL_SSLVERSION_TLSv1_3: + tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3; + tls_versions_len = 1; + break; + default: + failf(data, "rustls: unsupported minimum TLS version value"); + return CURLE_SSL_ENGINE_INITFAILED; + } + + switch(conn_config->version_max) { + case CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_TLSv1_3: + break; + case CURL_SSLVERSION_MAX_TLSv1_2: + if(tls_versions[0] == RUSTLS_TLS_VERSION_TLSV1_2) { + tls_versions_len = 1; + break; + } + FALLTHROUGH(); + case CURL_SSLVERSION_MAX_TLSv1_1: + case CURL_SSLVERSION_MAX_TLSv1_0: + default: + failf(data, "rustls: unsupported maximum TLS version value"); + return CURLE_SSL_ENGINE_INITFAILED; + } + + cipher_suites = malloc(sizeof(cipher_suites) * (cipher_suites_len)); + if(!cipher_suites) + return CURLE_OUT_OF_MEMORY; + + cr_get_selected_ciphers(data, + conn_config->cipher_list, + conn_config->cipher_list13, + cipher_suites, &cipher_suites_len); + if(cipher_suites_len == 0) { + failf(data, "rustls: no supported cipher in list"); + free(cipher_suites); + return CURLE_SSL_CIPHER; + } + + result = rustls_client_config_builder_new_custom(cipher_suites, + cipher_suites_len, + tls_versions, + tls_versions_len, + &config_builder); + free(cipher_suites); + if(result != RUSTLS_RESULT_OK) { + failf(data, "rustls: failed to create client config"); + return CURLE_SSL_ENGINE_INITFAILED; + } + } + if(connssl->alpn) { struct alpn_proto_buf proto; rustls_slice_bytes alpn[ALPN_ENTRIES_MAX]; @@ -462,14 +633,6 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, if(!verifypeer) { rustls_client_config_builder_dangerous_set_certificate_verifier( config_builder, cr_verify_none); - /* rustls does not support IP addresses (as of 0.19.0), and will reject - * connections created with an IP address, even when certificate - * verification is turned off. Set a placeholder hostname and disable - * SNI. */ - if(cr_hostname_is_ip(hostname)) { - rustls_client_config_builder_set_enable_sni(config_builder, false); - hostname = "example.invalid"; - } } else if(ca_info_blob || ssl_cafile) { roots_builder = rustls_root_cert_store_builder_new(); @@ -511,6 +674,29 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, } verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots); + rustls_root_cert_store_free(roots); + + if(conn_config->CRLfile) { + struct dynbuf crl_contents; + Curl_dyn_init(&crl_contents, SIZE_MAX); + if(!read_file_into(conn_config->CRLfile, &crl_contents)) { + failf(data, "rustls: failed to read revocation list file"); + Curl_dyn_free(&crl_contents); + rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); + return CURLE_SSL_CRL_BADFILE; + } + + result = rustls_web_pki_server_cert_verifier_builder_add_crl( + verifier_builder, + Curl_dyn_uptr(&crl_contents), + Curl_dyn_len(&crl_contents)); + Curl_dyn_free(&crl_contents); + if(result != RUSTLS_RESULT_OK) { + failf(data, "rustls: failed to parse revocation list"); + rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); + return CURLE_SSL_CRL_BADFILE; + } + } result = rustls_web_pki_server_cert_verifier_builder_build( verifier_builder, &server_cert_verifier); @@ -525,6 +711,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, rustls_client_config_builder_set_server_verifier(config_builder, server_cert_verifier); + rustls_server_cert_verifier_free(server_cert_verifier); } backend->config = rustls_client_config_builder_build(config_builder); @@ -602,13 +789,12 @@ cr_connect_common(struct Curl_cfilter *cf, /* Read/write data until the handshake is done or the socket would block. */ for(;;) { /* - * Connection has been established according to rustls. Set send/recv + * Connection has been established according to Rustls. Set send/recv * handlers, and update the state machine. */ connssl->io_need = CURL_SSL_IO_NEED_NONE; if(!rustls_connection_is_handshaking(rconn)) { - infof(data, "Done handshaking"); - /* rustls claims it is no longer handshaking *before* it has + /* Rustls claims it is no longer handshaking *before* it has * send its FINISHED message off. We attempt to let it write * one more time. Oh my. */ @@ -622,6 +808,22 @@ cr_connect_common(struct Curl_cfilter *cf, return tmperr; } /* REALLY Done with the handshake. */ + { + uint16_t proto = rustls_connection_get_protocol_version(rconn); + const rustls_supported_ciphersuite *rcipher = + rustls_connection_get_negotiated_ciphersuite(rconn); + uint16_t cipher = rcipher ? + rustls_supported_ciphersuite_get_suite(rcipher) : 0; + char buf[64] = ""; + const char *ver = "TLS version unknown"; + if(proto == RUSTLS_TLS_VERSION_TLSV1_3) + ver = "TLSv1.3"; + if(proto == RUSTLS_TLS_VERSION_TLSV1_2) + ver = "TLSv1.2"; + Curl_cipher_suite_get_str(cipher, buf, sizeof(buf), true); + infof(data, "rustls: handshake complete, %s, cipher: %s", + ver, buf); + } connssl->state = ssl_connection_complete; *done = TRUE; return CURLE_OK; @@ -654,8 +856,8 @@ cr_connect_common(struct Curl_cfilter *cf, return CURLE_SSL_CONNECT_ERROR; } if(blocking && 0 == what) { - failf(data, "rustls connection timeout after %" - CURL_FORMAT_TIMEDIFF_T " ms", socket_check_timeout); + failf(data, "rustls: connection timeout after %" FMT_TIMEDIFF_T " ms", + socket_check_timeout); return CURLE_OPERATION_TIMEDOUT; } if(0 == what) { @@ -825,7 +1027,9 @@ static size_t cr_version(char *buffer, size_t size) const struct Curl_ssl Curl_ssl_rustls = { { CURLSSLBACKEND_RUSTLS, "rustls" }, SSLSUPP_CAINFO_BLOB | /* supports */ - SSLSUPP_HTTPS_PROXY, + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST | + SSLSUPP_TLS13_CIPHERSUITES, sizeof(struct rustls_ssl_backend_data), Curl_none_init, /* init */ @@ -834,7 +1038,7 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_check_cxn, /* check_cxn */ cr_shutdown, /* shutdown */ cr_data_pending, /* data_pending */ - Curl_none_random, /* random */ + Curl_weak_random, /* random */ Curl_none_cert_status_request, /* cert_status_request */ cr_connect_blocking, /* connect */ cr_connect_nonblocking, /* connect_nonblocking */ @@ -851,6 +1055,7 @@ const struct Curl_ssl Curl_ssl_rustls = { NULL, /* disassociate_connection */ cr_recv, /* recv decrypted data */ cr_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif /* USE_RUSTLS */ diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index f9bb2f824..a9dcbe45a 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -968,7 +968,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, #endif sspi_status = - s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, + Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &credentials, NULL, NULL, &backend->cred->cred_handle, @@ -1015,7 +1015,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf, #endif sspi_status = - s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, + Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &schannel_cred, NULL, NULL, &backend->cred->cred_handle, @@ -1083,7 +1083,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) #ifdef HAS_ALPN /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above. - Also it does not seem to be supported for Wine, see curl bug #983. */ + Also it does not seem to be supported for WINE, see curl bug #983. */ backend->use_alpn = connssl->alpn && !GetProcAddress(GetModuleHandle(TEXT("ntdll")), "wine_get_version") && @@ -1099,7 +1099,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) * do it following a more manual process. */ backend->use_manual_cred_validation = true; #else -#error "compiler too old to support requisite manual cert verify for Win CE" +#error "compiler too old to support Windows CE requisite manual cert verify" #endif #else #ifdef HAS_MANUAL_VERIFY_API @@ -1242,10 +1242,10 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx At the moment we do not pass inbuf unless we are using ALPN since we only - use it for that, and Wine (for which we currently disable ALPN) is giving + use it for that, and WINE (for which we currently disable ALPN) is giving us problems with inbuf regardless. https://github.com/curl/curl/issues/983 */ - sspi_status = s_pSecFn->InitializeSecurityContext( + sspi_status = Curl_pSecFn->InitializeSecurityContext( &backend->cred->cred_handle, NULL, backend->cred->sni_hostname, backend->req_flags, 0, 0, (backend->use_alpn ? &inbuf_desc : NULL), @@ -1287,9 +1287,9 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) /* send initial handshake data which is now stored in output buffer */ written = Curl_conn_cf_send(cf->next, data, - outbuf.pvBuffer, outbuf.cbBuffer, + outbuf.pvBuffer, outbuf.cbBuffer, FALSE, &result); - s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); + Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { failf(data, "schannel: failed to send initial handshake data: " "sent %zd of %lu bytes", written, outbuf.cbBuffer); @@ -1436,7 +1436,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) memcpy(inbuf[0].pvBuffer, backend->encdata_buffer, backend->encdata_offset); - sspi_status = s_pSecFn->InitializeSecurityContext( + sspi_status = Curl_pSecFn->InitializeSecurityContext( &backend->cred->cred_handle, &backend->ctxt->ctxt_handle, backend->cred->sni_hostname, backend->req_flags, 0, 0, &inbuf_desc, 0, NULL, @@ -1477,7 +1477,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) /* send handshake token to server */ written = Curl_conn_cf_send(cf->next, data, outbuf[i].pvBuffer, outbuf[i].cbBuffer, - &result); + FALSE, &result); if((result != CURLE_OK) || (outbuf[i].cbBuffer != (size_t) written)) { failf(data, "schannel: failed to send next handshake data: " @@ -1488,7 +1488,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) /* free obsolete buffer */ if(outbuf[i].pvBuffer) { - s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); + Curl_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); } } } @@ -1684,7 +1684,7 @@ static void schannel_session_free(void *sessionid, size_t idsize) if(cred) { cred->refcount--; if(cred->refcount == 0) { - s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); + Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle); curlx_unicodefree(cred->sni_hostname); #ifdef HAS_CLIENT_CERT_PATH if(cred->client_cert_store) { @@ -1739,7 +1739,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) #ifdef HAS_ALPN if(backend->use_alpn) { sspi_status = - s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, + Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result); @@ -1787,7 +1787,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) if(data->set.ssl.certinfo) { int certs_count = 0; sspi_status = - s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, + Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); @@ -1955,7 +1955,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, /* check if the maximum stream sizes were queried */ if(backend->stream_sizes.cbMaximumMessage == 0) { - sspi_status = s_pSecFn->QueryContextAttributes( + sspi_status = Curl_pSecFn->QueryContextAttributes( &backend->ctxt->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &backend->stream_sizes); @@ -1994,7 +1994,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, memcpy(outbuf[1].pvBuffer, buf, len); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ - sspi_status = s_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0, + sspi_status = Curl_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0, &outbuf_desc, 0); /* check if the message was encrypted */ @@ -2054,7 +2054,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, this_write = Curl_conn_cf_send(cf->next, data, ptr + written, len - written, - &result); + FALSE, &result); if(result == CURLE_AGAIN) continue; else if(result != CURLE_OK) { @@ -2211,7 +2211,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx */ - sspi_status = s_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle, + sspi_status = Curl_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle, &inbuf_desc, 0, NULL); /* check if everything went fine (server may want to renegotiate @@ -2498,7 +2498,7 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut)); InitSecBufferDesc(&BuffDesc, &Buffer, 1); - sspi_status = s_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle, + sspi_status = Curl_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle, &BuffDesc); if(sspi_status != SEC_E_OK) { @@ -2513,7 +2513,7 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - sspi_status = s_pSecFn->InitializeSecurityContext( + sspi_status = Curl_pSecFn->InitializeSecurityContext( &backend->cred->cred_handle, &backend->ctxt->ctxt_handle, backend->cred->sni_hostname, @@ -2531,8 +2531,8 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, /* send close message which is in output buffer */ ssize_t written = Curl_conn_cf_send(cf->next, data, outbuf.pvBuffer, outbuf.cbBuffer, - &result); - s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); + FALSE, &result); + Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); if(!result) { if(written < (ssize_t)outbuf.cbBuffer) { /* TODO: handle partial sends */ @@ -2605,7 +2605,7 @@ static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data) /* free SSPI Schannel API security context handle */ if(backend->ctxt) { DEBUGF(infof(data, "schannel: clear security context handle")); - s_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle); + Curl_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle); Curl_safefree(backend->ctxt); } @@ -2682,7 +2682,7 @@ static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf, struct Curl_asn1Element *pubkey; sspi_status = - s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, + Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); @@ -2846,9 +2846,6 @@ HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, } if(ca_info_blob) { - if(!share->CAinfo_blob_digest) { - return NULL; - } if(share->CAinfo_blob_size != ca_info_blob->len) { return NULL; } @@ -2856,10 +2853,9 @@ HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, ca_info_blob->len, info_blob_digest, CURL_SHA256_DIGEST_LENGTH); - if(memcmp(share->CAinfo_blob_digest, - info_blob_digest, + if(memcmp(share->CAinfo_blob_digest, info_blob_digest, CURL_SHA256_DIGEST_LENGTH)) { - return NULL; + return NULL; } } else { @@ -2882,7 +2878,6 @@ static void schannel_cert_share_free(void *key, size_t key_len, void *p) if(share->cert_store) { CertCloseStore(share->cert_store, 0); } - free(share->CAinfo_blob_digest); free(share->CAfile); free(share); } @@ -2895,7 +2890,6 @@ bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, struct Curl_multi *multi = data->multi; const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; struct schannel_cert_share *share; - unsigned char *CAinfo_blob_digest = NULL; size_t CAinfo_blob_size = 0; char *CAfile = NULL; @@ -2923,13 +2917,9 @@ bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, } if(ca_info_blob) { - CAinfo_blob_digest = malloc(CURL_SHA256_DIGEST_LENGTH); - if(!CAinfo_blob_digest) { - return false; - } schannel_sha256sum((const unsigned char *)ca_info_blob->data, ca_info_blob->len, - CAinfo_blob_digest, + share->CAinfo_blob_digest, CURL_SHA256_DIGEST_LENGTH); CAinfo_blob_size = ca_info_blob->len; } @@ -2946,12 +2936,10 @@ bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, if(share->cert_store) { CertCloseStore(share->cert_store, 0); } - free(share->CAinfo_blob_digest); free(share->CAfile); share->time = Curl_now(); share->cert_store = cert_store; - share->CAinfo_blob_digest = CAinfo_blob_digest; share->CAinfo_blob_size = CAinfo_blob_size; share->CAfile = CAfile; return true; @@ -2969,7 +2957,8 @@ const struct Curl_ssl Curl_ssl_schannel = { #endif SSLSUPP_TLS13_CIPHERSUITES | SSLSUPP_CA_CACHE | - SSLSUPP_HTTPS_PROXY, + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST, sizeof(struct schannel_ssl_backend_data), @@ -2996,6 +2985,7 @@ const struct Curl_ssl Curl_ssl_schannel = { NULL, /* disassociate_connection */ schannel_recv, /* recv decrypted data */ schannel_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif /* USE_SCHANNEL */ diff --git a/lib/vtls/schannel_int.h b/lib/vtls/schannel_int.h index b04f1804b..800fdf88e 100644 --- a/lib/vtls/schannel_int.h +++ b/lib/vtls/schannel_int.h @@ -28,6 +28,8 @@ #ifdef USE_SCHANNEL +#include "vtls.h" + #if (defined(__MINGW32__) || defined(CERT_CHAIN_REVOCATION_CHECK_CHAIN)) \ && !defined(CURL_WINDOWS_APP) #define HAS_MANUAL_VERIFY_API @@ -165,7 +167,7 @@ struct schannel_ssl_backend_data { #define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share" struct schannel_cert_share { - unsigned char *CAinfo_blob_digest; /* CA info blob digest */ + unsigned char CAinfo_blob_digest[CURL_SHA256_DIGEST_LENGTH]; size_t CAinfo_blob_size; /* CA info blob size */ char *CAfile; /* CAfile path used to generate certificate store */ diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 96ad0e517..11e61b689 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -83,7 +83,7 @@ static int is_cr_or_lf(char c) /* Search the substring needle,needlelen into string haystack,haystacklen * Strings do not need to be terminated by a '\0'. - * Similar of OSX/Linux memmem (not available on Visual Studio). + * Similar of macOS/Linux memmem (not available on Visual Studio). * Return position of beginning of first occurrence or NULL if not found */ static const char *c_memmem(const void *haystack, size_t haystacklen, @@ -452,7 +452,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data, } dns_w = entry->pwszDNSName; /* pwszDNSName is in ia5 string format and hence does not contain any - * non-ascii characters. */ + * non-ASCII characters. */ while(*dns_w != '\0') { *current_pos++ = (TCHAR)(*dns_w++); } @@ -483,7 +483,7 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf, DWORD actual_len = 0; sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + Curl_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); @@ -612,7 +612,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, DEBUGASSERT(BACKEND); sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + Curl_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index c2803e8bf..0eb079bbb 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -216,7 +216,7 @@ static const uint16_t default_ciphers[] = { #define SECTRANSP_PINNEDPUBKEY_V1 1 #endif -/* version 2 supports MacOSX 10.7+ */ +/* version 2 supports macOS 10.7+ */ #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) #define SECTRANSP_PINNEDPUBKEY_V2 1 #endif @@ -310,7 +310,8 @@ static OSStatus sectransp_bio_cf_out_write(SSLConnectionRef connection, OSStatus rtn = noErr; DEBUGASSERT(data); - nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, &result); + nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, FALSE, + &result); CURL_TRC_CF(data, cf, "bio_send(len=%zu) -> %zd, result=%d", *dataLength, nwritten, result); if(nwritten <= 0) { @@ -591,7 +592,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, cPassword, kCFStringEncodingUTF8) : NULL; CFDataRef pkcs_data = NULL; - /* We can import P12 files on iOS or OS X 10.7 or later: */ + /* We can import P12 files on iOS or macOS 10.7 or later: */ /* These constants are documented as having first appeared in 10.6 but they raise linker errors when used on that cat for some reason. */ #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS @@ -717,134 +718,89 @@ CF_INLINE bool is_file(const char *filename) return false; } -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS -static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver, - long ssl_version) +static CURLcode +sectransp_set_ssl_version_min_max(struct Curl_easy *data, + struct st_ssl_backend_data *backend, + struct ssl_primary_config *conn_config) { - switch(ssl_version) { +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + OSStatus err; + SSLProtocol ver_min; + SSLProtocol ver_max; + +#if CURL_SUPPORT_MAC_10_7 + if(!&SSLSetProtocolVersionMax) + goto legacy; +#endif + + switch(conn_config->version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: case CURL_SSLVERSION_TLSv1_0: - *darwinver = kTLSProtocol1; - return CURLE_OK; + ver_min = kTLSProtocol1; + break; case CURL_SSLVERSION_TLSv1_1: - *darwinver = kTLSProtocol11; - return CURLE_OK; + ver_min = kTLSProtocol11; + break; case CURL_SSLVERSION_TLSv1_2: - *darwinver = kTLSProtocol12; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - *darwinver = kTLSProtocol13; - return CURLE_OK; - } -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ + ver_min = kTLSProtocol12; break; + case CURL_SSLVERSION_TLSv1_3: + default: + failf(data, "SSL: unsupported minimum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } - return CURLE_SSL_CONNECT_ERROR; -} -#endif -static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct st_ssl_backend_data *backend = - (struct st_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - long ssl_version = conn_config->version; - long ssl_version_max = conn_config->version_max; - long max_supported_version_by_os; - - DEBUGASSERT(backend); + switch(conn_config->version_max) { + case CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_TLSv1_3: + case CURL_SSLVERSION_MAX_TLSv1_2: + ver_max = kTLSProtocol12; + break; + case CURL_SSLVERSION_MAX_TLSv1_1: + ver_max = kTLSProtocol11; + break; + case CURL_SSLVERSION_MAX_TLSv1_0: + ver_max = kTLSProtocol1; + break; + default: + failf(data, "SSL: unsupported maximum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; + } - /* macOS 10.5-10.7 supported TLS 1.0 only. - macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2. - macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3; + err = SSLSetProtocolVersionMin(backend->ssl_ctx, ver_min); + if(err != noErr) { + failf(data, "SSL: failed to set minimum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } - else { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; + err = SSLSetProtocolVersionMax(backend->ssl_ctx, ver_max); + if(err != noErr) { + failf(data, "SSL: failed to set maximum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } -#else - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ - switch(ssl_version) { + return CURLE_OK; +#endif +#if CURL_SUPPORT_MAC_10_7 + goto legacy; +legacy: + switch(conn_config->version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - ssl_version = CURL_SSLVERSION_TLSv1_0; - break; - } - - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = max_supported_version_by_os; + case CURL_SSLVERSION_TLSv1_0: break; + default: + failf(data, "SSL: unsupported minimum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(&SSLSetProtocolVersionMax) { - SSLProtocol darwin_ver_min = kTLSProtocol1; - SSLProtocol darwin_ver_max = kTLSProtocol1; - CURLcode result = sectransp_version_from_curl(&darwin_ver_min, - ssl_version); - if(result) { - failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); - return result; - } - result = sectransp_version_from_curl(&darwin_ver_max, - ssl_version_max >> 16); - if(result) { - failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); - return result; - } + /* only TLS 1.0 is supported, disable SSL 3.0 and SSL 2.0 */ + SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); + SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol1, true); - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min); - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max); - return result; - } - else { -#if CURL_SUPPORT_MAC_10_8 - long i = ssl_version; - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - for(; i <= (ssl_version_max >> 16); i++) { - switch(i) { - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); - break; - case CURL_SSLVERSION_TLSv1_2: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - } - return CURLE_OK; -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - failf(data, "Secure Transport: cannot set SSL protocol"); - return CURLE_SSL_CONNECT_ERROR; + return CURLE_OK; +#endif } static int sectransp_cipher_suite_get_str(uint16_t id, char *buf, @@ -927,7 +883,7 @@ static SSLCipherSuite * sectransp_get_supported_ciphers(SSLContextRef ssl_ctx, /* There is a known bug in early versions of Mountain Lion where ST's ECC ciphers (cipher suite 0xC001 through 0xC032) simply do not work. Work around the problem here by disabling those ciphers if we are - running in an affected version of OS X. */ + running in an affected version of macOS. */ if(maj == 12 && min <= 3) { size_t i = 0, j = 0; for(; i < *len; i++) { @@ -1131,112 +1087,9 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */ - /* check to see if we have been told to use an explicit SSL/TLS version */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(&SSLSetProtocolVersionMax) { - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1); -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13); - } - else { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); - } -#else - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - result = set_ssl_version_min_max(cf, data); - if(result != CURLE_OK) - return result; - break; - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { -#if CURL_SUPPORT_MAC_10_8 - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - result = set_ssl_version_min_max(cf, data); - if(result != CURLE_OK) - return result; - break; - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) { - failf(data, "Your version of the OS does not support to set maximum" - " SSL/TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - failf(data, "Your version of the OS does not support TLSv1.1"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_2: - failf(data, "Your version of the OS does not support TLSv1.2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv2: - case CURL_SSLVERSION_SSLv3: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + result = sectransp_set_ssl_version_min_max(data, backend, conn_config); + if(result != CURLE_OK) + return result; #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ defined(HAVE_BUILTIN_AVAILABLE) @@ -2255,9 +2108,6 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf, else infof(data, VTLS_INFOF_NO_ALPN); - Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); - /* chosenProtocol is a reference to the string within alpnArr and does not need to be freed separately */ if(alpnArr) @@ -2887,7 +2737,8 @@ const struct Curl_ssl Curl_ssl_sectransp = { #ifdef SECTRANSP_PINNEDPUBKEY SSLSUPP_PINNEDPUBKEY | #endif /* SECTRANSP_PINNEDPUBKEY */ - SSLSUPP_HTTPS_PROXY, + SSLSUPP_HTTPS_PROXY | + SSLSUPP_CIPHER_LIST, sizeof(struct st_ssl_backend_data), @@ -2914,6 +2765,7 @@ const struct Curl_ssl Curl_ssl_sectransp = { NULL, /* disassociate_connection */ sectransp_recv, /* recv decrypted data */ sectransp_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #ifdef __GNUC__ diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index e601f4b16..36a422678 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -71,6 +71,7 @@ #include "connect.h" #include "select.h" #include "strdup.h" +#include "rand.h" /* The last #include files should be: */ #include "curl_memory.h" @@ -138,6 +139,9 @@ static const struct alpn_spec ALPN_SPEC_H11 = { { ALPN_HTTP_1_1 }, 1 }; #ifdef USE_HTTP2 +static const struct alpn_spec ALPN_SPEC_H2 = { + { ALPN_H2 }, 1 +}; static const struct alpn_spec ALPN_SPEC_H2_H11 = { { ALPN_H2, ALPN_HTTP_1_1 }, 2 }; @@ -148,6 +152,8 @@ static const struct alpn_spec *alpn_get_spec(int httpwant, bool use_alpn) if(!use_alpn) return NULL; #ifdef USE_HTTP2 + if(httpwant == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) + return &ALPN_SPEC_H2; if(httpwant >= CURL_HTTP_VERSION_2) return &ALPN_SPEC_H2_H11; #else @@ -574,10 +580,9 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf, } } - DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d", - no_match? "Did not find": "Found", - Curl_ssl_cf_is_proxy(cf) ? "proxy" : "host", - cf->conn->handler->scheme, peer->hostname, peer->port)); + CURL_TRC_CF(data, cf, "%s cached session ID for %s://%s:%d", + no_match? "No": "Found", + cf->conn->handler->scheme, peer->hostname, peer->port); return no_match; } @@ -745,6 +750,14 @@ CURLcode Curl_ssl_set_sessionid(struct Curl_cfilter *cf, return CURLE_OK; } +CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, + struct dynbuf *binding) +{ + if(Curl_ssl->get_channel_binding) + return Curl_ssl->get_channel_binding(data, sockindex, binding); + return CURLE_OK; +} + void Curl_ssl_close_all(struct Curl_easy *data) { /* kill the session ID cache if not shared */ @@ -771,13 +784,13 @@ void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, if(sock != CURL_SOCKET_BAD) { if(connssl->io_need & CURL_SSL_IO_NEED_SEND) { Curl_pollset_set_out_only(data, ps, sock); - CURL_TRC_CF(data, cf, "adjust_pollset, POLLOUT fd=%" - CURL_FORMAT_SOCKET_T, sock); + CURL_TRC_CF(data, cf, "adjust_pollset, POLLOUT fd=%" FMT_SOCKET_T, + sock); } else { Curl_pollset_set_in_only(data, ps, sock); - CURL_TRC_CF(data, cf, "adjust_pollset, POLLIN fd=%" - CURL_FORMAT_SOCKET_T, sock); + CURL_TRC_CF(data, cf, "adjust_pollset, POLLIN fd=%" FMT_SOCKET_T, + sock); } } } @@ -888,7 +901,9 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, CURLcode result = CURLE_OK; struct dynbuf build; - Curl_dyn_init(&build, 10000); + DEBUGASSERT(certnum < ci->num_of_certs); + + Curl_dyn_init(&build, CURL_X509_STR_MAX); if(Curl_dyn_add(&build, label) || Curl_dyn_addn(&build, ":", 1) || @@ -907,11 +922,16 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, return result; } +/* get 32 bits of random */ CURLcode Curl_ssl_random(struct Curl_easy *data, unsigned char *entropy, size_t length) { - return Curl_ssl->random(data, entropy, length); + DEBUGASSERT(length == sizeof(int)); + if(Curl_ssl->random) + return Curl_ssl->random(data, entropy, length); + else + return CURLE_NOT_BUILT_IN; } /* @@ -1181,16 +1201,6 @@ int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data) return -1; } -CURLcode Curl_none_random(struct Curl_easy *data UNUSED_PARAM, - unsigned char *entropy UNUSED_PARAM, - size_t length UNUSED_PARAM) -{ - (void)data; - (void)entropy; - (void)length; - return CURLE_NOT_BUILT_IN; -} - void Curl_none_close_all(struct Curl_easy *data UNUSED_PARAM) { (void)data; @@ -1317,7 +1327,7 @@ static const struct Curl_ssl Curl_ssl_multi = { Curl_none_check_cxn, /* check_cxn */ Curl_none_shutdown, /* shutdown */ Curl_none_data_pending, /* data_pending */ - Curl_none_random, /* random */ + NULL, /* random */ Curl_none_cert_status_request, /* cert_status_request */ multissl_connect, /* connect */ multissl_connect_nonblocking, /* connect_nonblocking */ @@ -1334,6 +1344,7 @@ static const struct Curl_ssl Curl_ssl_multi = { NULL, /* disassociate_connection */ multissl_recv_plain, /* recv decrypted data */ multissl_send_plain, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; const struct Curl_ssl *Curl_ssl = @@ -1567,69 +1578,70 @@ CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, struct Curl_cfilter *cf, int transport) { const char *ehostname, *edispname; - int eport; + CURLcode result = CURLE_OUT_OF_MEMORY; + /* We expect a clean struct, e.g. called only ONCE */ + DEBUGASSERT(peer); + DEBUGASSERT(!peer->hostname); + DEBUGASSERT(!peer->dispname); + DEBUGASSERT(!peer->sni); /* We need the hostname for SNI negotiation. Once handshaked, this remains * the SNI hostname for the TLS connection. When the connection is reused, * the settings in cf->conn might change. We keep a copy of the hostname we * use for SNI. */ + peer->transport = transport; #ifndef CURL_DISABLE_PROXY if(Curl_ssl_cf_is_proxy(cf)) { ehostname = cf->conn->http_proxy.host.name; edispname = cf->conn->http_proxy.host.dispname; - eport = cf->conn->http_proxy.port; + peer->port = cf->conn->http_proxy.port; } else #endif { ehostname = cf->conn->host.name; edispname = cf->conn->host.dispname; - eport = cf->conn->remote_port; + peer->port = cf->conn->remote_port; } - /* change if ehostname changed */ - DEBUGASSERT(!ehostname || ehostname[0]); - if(ehostname && (!peer->hostname - || strcmp(ehostname, peer->hostname))) { - Curl_ssl_peer_cleanup(peer); - peer->hostname = strdup(ehostname); - if(!peer->hostname) { - Curl_ssl_peer_cleanup(peer); - return CURLE_OUT_OF_MEMORY; - } - if(!edispname || !strcmp(ehostname, edispname)) - peer->dispname = peer->hostname; - else { - peer->dispname = strdup(edispname); - if(!peer->dispname) { - Curl_ssl_peer_cleanup(peer); - return CURLE_OUT_OF_MEMORY; - } - } + /* hostname MUST exist and not be empty */ + if(!ehostname || !ehostname[0]) { + result = CURLE_FAILED_INIT; + goto out; + } - peer->type = get_peer_type(peer->hostname); - if(peer->type == CURL_SSL_PEER_DNS && peer->hostname[0]) { - /* not an IP address, normalize according to RCC 6066 ch. 3, - * max len of SNI is 2^16-1, no trailing dot */ - size_t len = strlen(peer->hostname); - if(len && (peer->hostname[len-1] == '.')) - len--; - if(len < USHRT_MAX) { - peer->sni = calloc(1, len + 1); - if(!peer->sni) { - Curl_ssl_peer_cleanup(peer); - return CURLE_OUT_OF_MEMORY; - } - Curl_strntolower(peer->sni, peer->hostname, len); - peer->sni[len] = 0; - } + peer->hostname = strdup(ehostname); + if(!peer->hostname) + goto out; + if(!edispname || !strcmp(ehostname, edispname)) + peer->dispname = peer->hostname; + else { + peer->dispname = strdup(edispname); + if(!peer->dispname) + goto out; + } + peer->type = get_peer_type(peer->hostname); + if(peer->type == CURL_SSL_PEER_DNS) { + /* not an IP address, normalize according to RCC 6066 ch. 3, + * max len of SNI is 2^16-1, no trailing dot */ + size_t len = strlen(peer->hostname); + if(len && (peer->hostname[len-1] == '.')) + len--; + if(len < USHRT_MAX) { + peer->sni = calloc(1, len + 1); + if(!peer->sni) + goto out; + Curl_strntolower(peer->sni, peer->hostname, len); + peer->sni[len] = 0; } - } - peer->port = eport; - peer->transport = transport; - return CURLE_OK; + result = CURLE_OK; + +out: + if(result) + Curl_ssl_peer_cleanup(peer); + return result; } static void ssl_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) @@ -1668,22 +1680,29 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, return CURLE_OK; } + if(!cf->next) { + *done = FALSE; + return CURLE_FAILED_INIT; + } + + if(!cf->next->connected) { + result = cf->next->cft->do_connect(cf->next, data, blocking, done); + if(result || !*done) + return result; + } + CF_DATA_SAVE(save, cf, data); CURL_TRC_CF(data, cf, "cf_connect()"); - (void)connssl; DEBUGASSERT(data->conn); DEBUGASSERT(data->conn == cf->conn); DEBUGASSERT(connssl); - DEBUGASSERT(cf->conn->host.name); - - result = cf->next->cft->do_connect(cf->next, data, blocking, done); - if(result || !*done) - goto out; *done = FALSE; - result = Curl_ssl_peer_init(&connssl->peer, cf, TRNSPRT_TCP); - if(result) - goto out; + if(!connssl->peer.hostname) { + result = Curl_ssl_peer_init(&connssl->peer, cf, TRNSPRT_TCP); + if(result) + goto out; + } if(blocking) { result = ssl_connect(cf, data); @@ -1721,11 +1740,12 @@ static bool ssl_cf_data_pending(struct Curl_cfilter *cf, static ssize_t ssl_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, - CURLcode *err) + bool eos, CURLcode *err) { struct cf_call_data save; ssize_t nwritten; + (void)eos; /* unused */ CF_DATA_SAVE(save, cf, data); *err = CURLE_OK; nwritten = Curl_ssl->send_plain(cf, data, buf, len, err); @@ -2200,7 +2220,6 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, const unsigned char *proto, size_t proto_len) { - int can_multi = 0; unsigned char *palpn = #ifndef CURL_DISABLE_PROXY (cf->conn->bits.tunnel_proxy && Curl_ssl_cf_is_proxy(cf))? @@ -2219,14 +2238,12 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, else if(proto_len == ALPN_H2_LENGTH && !memcmp(ALPN_H2, proto, ALPN_H2_LENGTH)) { *palpn = CURL_HTTP_VERSION_2; - can_multi = 1; } #endif #ifdef USE_HTTP3 else if(proto_len == ALPN_H3_LENGTH && !memcmp(ALPN_H3, proto, ALPN_H3_LENGTH)) { *palpn = CURL_HTTP_VERSION_3; - can_multi = 1; } #endif else { @@ -2245,9 +2262,6 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, } out: - if(!Curl_ssl_cf_is_proxy(cf)) - Curl_multiuse_state(data, can_multi? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); return CURLE_OK; } diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index 8fe2bc7ce..1c2538b2e 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -39,6 +39,7 @@ struct Curl_ssl_session; #define SSLSUPP_CAINFO_BLOB (1<<6) #define SSLSUPP_ECH (1<<7) #define SSLSUPP_CA_CACHE (1<<8) +#define SSLSUPP_CIPHER_LIST (1<<9) /* supports TLS 1.0-1.2 ciphersuites */ #define ALPN_ACCEPTED "ALPN: server accepted " @@ -131,6 +132,7 @@ CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t); void Curl_ssl_version(char *buffer, size_t size); /* Certificate information list handling. */ +#define CURL_X509_STR_MAX 100000 void Curl_ssl_free_certinfo(struct Curl_easy *data); CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num); @@ -181,6 +183,25 @@ bool Curl_ssl_cert_status_request(void); bool Curl_ssl_false_start(struct Curl_easy *data); +/* The maximum size of the SSL channel binding is 85 bytes, as defined in + * RFC 5929, Section 4.1. The 'tls-server-end-point:' prefix is 21 bytes long, + * and SHA-512 is the longest supported hash algorithm, with a digest length of + * 64 bytes. + * The maximum size of the channel binding is therefore 21 + 64 = 85 bytes. + */ +#define SSL_CB_MAX_SIZE 85 + +/* Return the tls-server-end-point channel binding, including the + * 'tls-server-end-point:' prefix. + * If successful, the data is written to the dynbuf, and CURLE_OK is returned. + * The dynbuf MUST HAVE a minimum toobig size of SSL_CB_MAX_SIZE. + * If the dynbuf is too small, CURLE_OUT_OF_MEMORY is returned. + * If channel binding is not supported, binding stays empty and CURLE_OK is + * returned. + */ +CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, + struct dynbuf *binding); + #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data, diff --git a/lib/vtls/vtls_int.h b/lib/vtls/vtls_int.h index 1472a0ca5..836bfad70 100644 --- a/lib/vtls/vtls_int.h +++ b/lib/vtls/vtls_int.h @@ -158,6 +158,9 @@ struct Curl_ssl { ssize_t (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, const void *mem, size_t len, CURLcode *code); + CURLcode (*get_channel_binding)(struct Curl_easy *data, int sockindex, + struct dynbuf *binding); + }; extern const struct Curl_ssl *Curl_ssl; @@ -168,8 +171,6 @@ void Curl_none_cleanup(void); CURLcode Curl_none_shutdown(struct Curl_cfilter *cf, struct Curl_easy *data, bool send_shutdown, bool *done); int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data); -CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy, - size_t length); void Curl_none_close_all(struct Curl_easy *data); void Curl_none_session_free(void *ptr); bool Curl_none_data_pending(struct Curl_cfilter *cf, @@ -222,7 +223,7 @@ CURLcode Curl_ssl_set_sessionid(struct Curl_cfilter *cf, #include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "bearssl.h" /* BearSSL versions */ -#include "rustls.h" /* rustls versions */ +#include "rustls.h" /* Rustls versions */ #endif /* USE_SSL */ diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 2b467c935..bd7963ec3 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -36,6 +36,10 @@ #include #include +#if LIBWOLFSSL_VERSION_HEX < 0x03004006 /* wolfSSL 3.4.6 (2015) */ +#error "wolfSSL version should be at least 3.4.6" +#endif + /* To determine what functions are available we rely on one or both of: - the user's options.h generated by wolfSSL - the symbols detected by curl's configure @@ -201,7 +205,7 @@ wolfssl_log_tls12_secret(SSL *ssl) } #endif /* OPENSSL_EXTRA */ -static int do_file_type(const char *type) +static int wolfssl_do_file_type(const char *type) { if(!type || !type[0]) return SSL_FILETYPE_PEM; @@ -287,17 +291,32 @@ static int wolfssl_bio_cf_out_write(WOLFSSL_BIO *bio, struct wolfssl_ctx *backend = (struct wolfssl_ctx *)connssl->backend; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; + ssize_t nwritten, skiplen = 0; CURLcode result = CURLE_OK; DEBUGASSERT(data); - nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result); + if(backend->shutting_down && backend->io_send_blocked_len && + (backend->io_send_blocked_len < blen)) { + /* bug in wolfSSL: + * It adds the close notify message again every time we retry + * sending during shutdown. */ + CURL_TRC_CF(data, cf, "bio_write, shutdown restrict send of %d" + " to %d bytes", blen, backend->io_send_blocked_len); + skiplen = (ssize_t)(blen - backend->io_send_blocked_len); + blen = backend->io_send_blocked_len; + } + nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &result); backend->io_result = result; CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %zd, %d", blen, nwritten, result); wolfSSL_BIO_clear_retry_flags(bio); - if(nwritten < 0 && CURLE_AGAIN == result) + if(nwritten < 0 && CURLE_AGAIN == result) { BIO_set_retry_write(bio); + if(backend->shutting_down && !backend->io_send_blocked_len) + backend->io_send_blocked_len = blen; + } + else if(!result && skiplen) + nwritten += skiplen; return (int)nwritten; } @@ -581,7 +600,10 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, !ssl_config->native_ca_store; cached_store = cache_criteria_met ? get_cached_x509_store(cf, data) : NULL; - if(cached_store && wolfSSL_X509_STORE_up_ref(cached_store)) { + if(cached_store && wolfSSL_CTX_get_cert_store(wssl->ctx) == cached_store) { + /* The cached store is already in use, do nothing. */ + } + else if(cached_store && wolfSSL_X509_STORE_up_ref(cached_store)) { wolfSSL_CTX_set_cert_store(wssl->ctx, cached_store); } else if(cache_criteria_met) { @@ -608,6 +630,75 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, return result; } +#ifdef WOLFSSL_TLS13 +static size_t +wssl_get_default_ciphers(bool tls13, char *buf, size_t size) +{ + size_t len = 0; + char *term = buf; + int i; + char *str; + size_t n; + + for(i = 0; (str = wolfSSL_get_cipher_list(i)); i++) { + if((strncmp(str, "TLS13", 5) == 0) != tls13) + continue; + + n = strlen(str); + if(buf && len + n + 1 <= size) { + memcpy(buf + len, str, n); + term = buf + len + n; + *term = ':'; + } + len += n + 1; + } + + if(buf) + *term = '\0'; + + return len > 0 ? len - 1 : 0; +} +#endif + +#if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */ +static int +wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) +{ + int res; + switch(version) { + default: + case TLS1_VERSION: + res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1); + if(res == WOLFSSL_SUCCESS) + return res; + FALLTHROUGH(); + case TLS1_1_VERSION: + res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_1); + if(res == WOLFSSL_SUCCESS) + return res; + FALLTHROUGH(); + case TLS1_2_VERSION: + res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_2); +#ifdef WOLFSSL_TLS13 + if(res == WOLFSSL_SUCCESS) + return res; + FALLTHROUGH(); + case TLS1_3_VERSION: + res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3); +#endif + } + return res; +} +static int +wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) +{ + (void) ctx, (void) version; + return WOLFSSL_NOT_IMPLEMENTED; +} +#define wolfSSL_CTX_set_min_proto_version wssl_legacy_CTX_set_min_proto_version +#define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version +#endif + /* * This function loads all the client/CA certificates and CRLs. Setup the TLS * layer and do all necessary magic. @@ -615,6 +706,7 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, static CURLcode wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) { + int res; char *ciphers, *curves; struct ssl_connect_data *connssl = cf->ctx; struct wolfssl_ctx *backend = @@ -625,12 +717,6 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) #ifdef WOLFSSL_HAVE_KYBER word16 pqkem = 0; size_t idx = 0; -#endif -#ifdef HAVE_SNI - bool sni = FALSE; -#define use_sni(x) sni = (x) -#else -#define use_sni(x) Curl_nop_stmt #endif DEBUGASSERT(backend); @@ -638,106 +724,80 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) if(connssl->state == ssl_connection_complete) return CURLE_OK; - if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) { - failf(data, "wolfSSL does not support to set maximum SSL/TLS version"); - return CURLE_SSL_CONNECT_ERROR; +#if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */ + req_method = wolfSSLv23_client_method(); +#else + req_method = wolfTLS_client_method(); +#endif + if(!req_method) { + failf(data, "wolfSSL: could not create a client method"); + return CURLE_OUT_OF_MEMORY; + } + + if(backend->ctx) + wolfSSL_CTX_free(backend->ctx); + + backend->ctx = wolfSSL_CTX_new(req_method); + if(!backend->ctx) { + failf(data, "wolfSSL: could not create a context"); + return CURLE_OUT_OF_MEMORY; } - /* check to see if we have been told to use an explicit SSL/TLS version */ switch(conn_config->version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: -#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ - /* minimum protocol version is set later after the CTX object is created */ - req_method = SSLv23_client_method(); -#else - infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " - "TLS 1.0 is used exclusively"); - req_method = TLSv1_client_method(); -#endif - use_sni(TRUE); - break; case CURL_SSLVERSION_TLSv1_0: -#if defined(WOLFSSL_ALLOW_TLSV10) && !defined(NO_OLD_TLS) - req_method = TLSv1_client_method(); - use_sni(TRUE); + res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_VERSION); break; -#else - failf(data, "wolfSSL does not support TLS 1.0"); - return CURLE_NOT_BUILT_IN; -#endif case CURL_SSLVERSION_TLSv1_1: -#ifndef NO_OLD_TLS - req_method = TLSv1_1_client_method(); - use_sni(TRUE); + res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_1_VERSION); break; -#else - failf(data, "wolfSSL does not support TLS 1.1"); - return CURLE_NOT_BUILT_IN; -#endif case CURL_SSLVERSION_TLSv1_2: -#ifndef WOLFSSL_NO_TLS12 - req_method = TLSv1_2_client_method(); - use_sni(TRUE); -#else - failf(data, "wolfSSL does not support TLS 1.2"); - return CURLE_NOT_BUILT_IN; -#endif + res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_2_VERSION); break; - case CURL_SSLVERSION_TLSv1_3: #ifdef WOLFSSL_TLS13 - req_method = wolfTLSv1_3_client_method(); - use_sni(TRUE); + case CURL_SSLVERSION_TLSv1_3: + res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_3_VERSION); break; -#else - failf(data, "wolfSSL: TLS 1.3 is not yet supported"); - return CURLE_SSL_CONNECT_ERROR; #endif default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + failf(data, "wolfSSL: unsupported minimum TLS version value"); return CURLE_SSL_CONNECT_ERROR; } - - if(!req_method) { - failf(data, "SSL: could not create a method"); - return CURLE_OUT_OF_MEMORY; - } - - if(backend->ctx) - wolfSSL_CTX_free(backend->ctx); - backend->ctx = wolfSSL_CTX_new(req_method); - - if(!backend->ctx) { - failf(data, "SSL: could not create a context"); - return CURLE_OUT_OF_MEMORY; + if(res != WOLFSSL_SUCCESS) { + failf(data, "wolfSSL: failed set the minimum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ - /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is - * whatever minimum version of TLS was built in and at least TLS 1.0. For - * later library versions that could change (eg TLS 1.0 built in but - * defaults to TLS 1.1) so we have this short circuit evaluation to find - * the minimum supported TLS version. - */ - if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) && - (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) && - (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1) + switch(conn_config->version_max) { #ifdef WOLFSSL_TLS13 - && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1) -#endif - ) { - failf(data, "SSL: could not set the minimum protocol version"); - return CURLE_SSL_CONNECT_ERROR; - } + case CURL_SSLVERSION_MAX_TLSv1_3: + res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION); + break; #endif - FALLTHROUGH(); - default: + case CURL_SSLVERSION_MAX_TLSv1_2: + res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_2_VERSION); + break; + case CURL_SSLVERSION_MAX_TLSv1_1: + res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_1_VERSION); + break; + case CURL_SSLVERSION_MAX_TLSv1_0: + res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_VERSION); break; + case CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_MAX_NONE: + res = WOLFSSL_SUCCESS; + break; + default: + failf(data, "wolfSSL: unsupported maximum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; + } + if(res != WOLFSSL_SUCCESS) { + failf(data, "wolfSSL: failed set the maximum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } +#ifndef WOLFSSL_TLS13 ciphers = conn_config->cipher_list; if(ciphers) { if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) { @@ -746,6 +806,44 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) } infof(data, "Cipher selection: %s", ciphers); } +#else + if(conn_config->cipher_list || conn_config->cipher_list13) { + const char *ciphers12 = conn_config->cipher_list; + const char *ciphers13 = conn_config->cipher_list13; + + /* Set ciphers to a combination of ciphers_list and ciphers_list13. + * If cipher_list is not set use the default TLSv1.2 (1.1, 1.0) ciphers. + * If cipher_list13 is not set use the default TLSv1.3 ciphers. */ + size_t len13 = ciphers13 ? strlen(ciphers13) + : wssl_get_default_ciphers(true, NULL, 0); + size_t len12 = ciphers12 ? strlen(ciphers12) + : wssl_get_default_ciphers(false, NULL, 0); + + ciphers = malloc(len13 + 1 + len12 + 1); + if(!ciphers) + return CURLE_OUT_OF_MEMORY; + + if(ciphers13) + memcpy(ciphers, ciphers13, len13); + else + wssl_get_default_ciphers(true, ciphers, len13 + 1); + ciphers[len13] = ':'; + + if(ciphers12) + memcpy(ciphers + len13 + 1, ciphers12, len12); + else + wssl_get_default_ciphers(false, ciphers + len13 + 1, len12 + 1); + ciphers[len13 + 1 + len12] = '\0'; + + if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + free(ciphers); + return CURLE_SSL_CIPHER; + } + infof(data, "Cipher selection: %s", ciphers); + free(ciphers); + } +#endif curves = conn_config->curves; if(curves) { @@ -768,40 +866,89 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) } } -#ifndef NO_FILESYSTEM /* Load the client certificate, and private key */ - if(ssl_config->primary.clientcert) { - char *key_file = ssl_config->key; - int file_type = do_file_type(ssl_config->cert_type); - - if(file_type == WOLFSSL_FILETYPE_PEM) { - if(wolfSSL_CTX_use_certificate_chain_file(backend->ctx, - ssl_config->primary.clientcert) - != 1) { - failf(data, "unable to use client certificate"); - return CURLE_SSL_CONNECT_ERROR; - } +#ifndef NO_FILESYSTEM + if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) { + const char *cert_file = ssl_config->primary.clientcert; + const char *key_file = ssl_config->key; + const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; + const struct curl_blob *key_blob = ssl_config->key_blob; + int file_type = wolfssl_do_file_type(ssl_config->cert_type); + int rc; + + switch(file_type) { + case WOLFSSL_FILETYPE_PEM: + rc = cert_blob ? + wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx, + cert_blob->data, + (long)cert_blob->len) : + wolfSSL_CTX_use_certificate_chain_file(backend->ctx, cert_file); + break; + case WOLFSSL_FILETYPE_ASN1: + rc = cert_blob ? + wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data, + (long)cert_blob->len, file_type) : + wolfSSL_CTX_use_certificate_file(backend->ctx, cert_file, file_type); + break; + default: + failf(data, "unknown cert type"); + return CURLE_BAD_FUNCTION_ARGUMENT; } - else if(file_type == WOLFSSL_FILETYPE_ASN1) { - if(wolfSSL_CTX_use_certificate_file(backend->ctx, - ssl_config->primary.clientcert, - file_type) != 1) { - failf(data, "unable to use client certificate"); - return CURLE_SSL_CONNECT_ERROR; - } + if(rc != 1) { + failf(data, "unable to use client certificate"); + return CURLE_SSL_CONNECT_ERROR; } - else { + + if(!key_blob && !key_file) { + key_blob = cert_blob; + key_file = cert_file; + } + else + file_type = wolfssl_do_file_type(ssl_config->key_type); + + rc = key_blob ? + wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data, + (long)key_blob->len, file_type) : + wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file, file_type); + if(rc != 1) { + failf(data, "unable to set private key"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#else /* NO_FILESYSTEM */ + if(ssl_config->primary.cert_blob) { + const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; + const struct curl_blob *key_blob = ssl_config->key_blob; + int file_type = wolfssl_do_file_type(ssl_config->cert_type); + int rc; + + switch(file_type) { + case WOLFSSL_FILETYPE_PEM: + rc = wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx, + cert_blob->data, + (long)cert_blob->len); + break; + case WOLFSSL_FILETYPE_ASN1: + rc = wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data, + (long)cert_blob->len, file_type); + break; + default: failf(data, "unknown cert type"); return CURLE_BAD_FUNCTION_ARGUMENT; } + if(rc != 1) { + failf(data, "unable to use client certificate"); + return CURLE_SSL_CONNECT_ERROR; + } - if(!key_file) - key_file = ssl_config->primary.clientcert; + if(!key_blob) + key_blob = cert_blob; else - file_type = do_file_type(ssl_config->key_type); + file_type = wolfssl_do_file_type(ssl_config->key_type); - if(wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file, - file_type) != 1) { + if(wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data, + (long)key_blob->len, + file_type) != 1) { failf(data, "unable to set private key"); return CURLE_SSL_CONNECT_ERROR; } @@ -817,7 +964,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) SSL_VERIFY_NONE, NULL); #ifdef HAVE_SNI - if(sni && connssl->peer.sni) { + if(connssl->peer.sni) { size_t sni_len = strlen(connssl->peer.sni); if((sni_len < USHRT_MAX)) { if(wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, @@ -988,7 +1135,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) if(data->set.tls_ech & CURLECH_HARD) return CURLE_SSL_CONNECT_ERROR; } - Curl_resolv_unlock(data, dns); + Curl_resolv_unlink(data, &dns); } } @@ -1029,15 +1176,15 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) static char *wolfssl_strerror(unsigned long error, char *buf, unsigned long size) { - DEBUGASSERT(size); + DEBUGASSERT(size > 40); *buf = '\0'; wolfSSL_ERR_error_string_n(error, buf, size); if(!*buf) { const char *msg = error ? "Unknown error" : "No error"; - strncpy(buf, msg, size - 1); - buf[size - 1] = '\0'; + /* the string fits because the assert above assures this */ + strcpy(buf, msg); } return buf; @@ -1148,7 +1295,6 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) } #endif } -#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ else if(ASN_NO_SIGNER_E == detail) { if(conn_config->verifypeer) { failf(data, " CA signer not available for verification"); @@ -1161,7 +1307,14 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) "continuing anyway"); } } -#endif + else if(ASN_AFTER_DATE_E == detail) { + failf(data, "server verification failed: certificate has expired."); + return CURLE_PEER_FAILED_VERIFICATION; + } + else if(ASN_BEFORE_DATE_E == detail) { + failf(data, "server verification failed: certificate not valid yet."); + return CURLE_PEER_FAILED_VERIFICATION; + } #ifdef USE_ECH else if(-1 == detail) { /* try access a retry_config ECHConfigList for tracing */ @@ -1379,7 +1532,10 @@ static CURLcode wolfssl_shutdown(struct Curl_cfilter *cf, struct wolfssl_ctx *wctx = (struct wolfssl_ctx *)connssl->backend; CURLcode result = CURLE_OK; char buf[1024]; - int nread, err; + char error_buffer[256]; + int nread = -1, err; + size_t i; + int detail; DEBUGASSERT(wctx); if(!wctx->handle || cf->shutdown) { @@ -1387,6 +1543,7 @@ static CURLcode wolfssl_shutdown(struct Curl_cfilter *cf, goto out; } + wctx->shutting_down = TRUE; connssl->io_need = CURL_SSL_IO_NEED_NONE; *done = FALSE; if(!(wolfSSL_get_shutdown(wctx->handle) & SSL_SENT_SHUTDOWN)) { @@ -1395,6 +1552,7 @@ static CURLcode wolfssl_shutdown(struct Curl_cfilter *cf, ERR_clear_error(); nread = wolfSSL_read(wctx->handle, buf, (int)sizeof(buf)); err = wolfSSL_get_error(wctx->handle, nread); + CURL_TRC_CF(data, cf, "wolfSSL_read, nread=%d, err=%d", nread, err); if(!nread && err == SSL_ERROR_ZERO_RETURN) { bool input_pending; /* Yes, it did. */ @@ -1415,49 +1573,55 @@ static CURLcode wolfssl_shutdown(struct Curl_cfilter *cf, } } - if(send_shutdown && wolfSSL_shutdown(wctx->handle) == 1) { - CURL_TRC_CF(data, cf, "SSL shutdown finished"); - *done = TRUE; - goto out; - } - else { - size_t i; - /* SSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ - for(i = 0; i < 10; ++i) { - ERR_clear_error(); - nread = wolfSSL_read(wctx->handle, buf, (int)sizeof(buf)); - if(nread <= 0) - break; - } - err = wolfSSL_get_error(wctx->handle, nread); - switch(err) { - case SSL_ERROR_ZERO_RETURN: /* no more data */ - CURL_TRC_CF(data, cf, "SSL shutdown received"); + /* SSL should now have started the shutdown from our side. Since it + * was not complete, we are lacking the close notify from the server. */ + if(send_shutdown) { + ERR_clear_error(); + if(wolfSSL_shutdown(wctx->handle) == 1) { + CURL_TRC_CF(data, cf, "SSL shutdown finished"); *done = TRUE; - break; - case SSL_ERROR_NONE: /* just did not get anything */ - case SSL_ERROR_WANT_READ: - /* SSL has send its notify and now wants to read the reply - * from the server. We are not really interested in that. */ - CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - break; - case SSL_ERROR_WANT_WRITE: - CURL_TRC_CF(data, cf, "SSL shutdown send blocked"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - break; - default: { - char error_buffer[256]; - int detail = wolfSSL_get_error(wctx->handle, err); - CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)", - wolfssl_strerror((unsigned long)err, error_buffer, - sizeof(error_buffer)), - detail); - result = CURLE_RECV_ERROR; - break; + goto out; } + if(SSL_ERROR_WANT_WRITE == wolfSSL_get_error(wctx->handle, nread)) { + CURL_TRC_CF(data, cf, "SSL shutdown still wants to send"); + connssl->io_need = CURL_SSL_IO_NEED_SEND; + goto out; } + /* Having sent the close notify, we use wolfSSL_read() to get the + * missing close notify from the server. */ + } + + for(i = 0; i < 10; ++i) { + ERR_clear_error(); + nread = wolfSSL_read(wctx->handle, buf, (int)sizeof(buf)); + if(nread <= 0) + break; + } + err = wolfSSL_get_error(wctx->handle, nread); + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + CURL_TRC_CF(data, cf, "SSL shutdown received"); + *done = TRUE; + break; + case SSL_ERROR_NONE: /* just did not get anything */ + case SSL_ERROR_WANT_READ: + /* SSL has send its notify and now wants to read the reply + * from the server. We are not really interested in that. */ + CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive"); + connssl->io_need = CURL_SSL_IO_NEED_RECV; + break; + case SSL_ERROR_WANT_WRITE: + CURL_TRC_CF(data, cf, "SSL shutdown send blocked"); + connssl->io_need = CURL_SSL_IO_NEED_SEND; + break; + default: + detail = wolfSSL_get_error(wctx->handle, err); + CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)", + wolfssl_strerror((unsigned long)err, error_buffer, + sizeof(error_buffer)), + detail); + result = CURLE_RECV_ERROR; + break; } out: @@ -1771,7 +1935,11 @@ const struct Curl_ssl Curl_ssl_wolfssl = { SSLSUPP_ECH | #endif SSLSUPP_SSL_CTX | - SSLSUPP_CA_CACHE, +#ifdef WOLFSSL_TLS13 + SSLSUPP_TLS13_CIPHERSUITES | +#endif + SSLSUPP_CA_CACHE | + SSLSUPP_CIPHER_LIST, sizeof(struct wolfssl_ctx), @@ -1798,6 +1966,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = { NULL, /* disassociate_connection */ wolfssl_recv, /* recv decrypted data */ wolfssl_send, /* send data to encrypt */ + NULL, /* get_channel_binding */ }; #endif diff --git a/lib/vtls/wolfssl.h b/lib/vtls/wolfssl.h index d75bdaa1e..318d8b4ab 100644 --- a/lib/vtls/wolfssl.h +++ b/lib/vtls/wolfssl.h @@ -39,7 +39,9 @@ struct wolfssl_ctx { WOLFSSL_CTX *ctx; WOLFSSL *handle; CURLcode io_result; /* result of last BIO cfilter operation */ + int io_send_blocked_len; /* length of last BIO write that EAGAINed */ BIT(x509_store_setup); /* x509 store has been set up */ + BIT(shutting_down); /* TLS is being shut down */ }; CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c index 7f04af3b9..4c93ce78d 100644 --- a/lib/vtls/x509asn1.c +++ b/lib/vtls/x509asn1.c @@ -99,10 +99,6 @@ #define CURL_ASN1_CHARACTER_STRING 29 #define CURL_ASN1_BMP_STRING 30 -/* Max sixes */ - -#define MAX_X509_STR 10000 -#define MAX_X509_CERT 100000 #ifdef WANT_EXTRACT_CERTINFO /* ASN.1 OID table entry. */ @@ -463,7 +459,7 @@ static CURLcode OID2str(struct dynbuf *store, if(beg < end) { if(symbolic) { struct dynbuf buf; - Curl_dyn_init(&buf, MAX_X509_STR); + Curl_dyn_init(&buf, CURL_X509_STR_MAX); result = encodeOID(&buf, beg, end); if(!result) { @@ -685,7 +681,7 @@ static CURLcode encodeDN(struct dynbuf *store, struct Curl_asn1Element *dn) CURLcode result = CURLE_OK; bool added = FALSE; struct dynbuf temp; - Curl_dyn_init(&temp, MAX_X509_STR); + Curl_dyn_init(&temp, CURL_X509_STR_MAX); for(p1 = dn->beg; p1 < dn->end;) { p1 = getASN1Element(&rdn, p1, dn->end); @@ -949,7 +945,7 @@ static CURLcode do_pubkey_field(struct Curl_easy *data, int certnum, CURLcode result; struct dynbuf out; - Curl_dyn_init(&out, MAX_X509_STR); + Curl_dyn_init(&out, CURL_X509_STR_MAX); /* Generate a certificate information record for the public key. */ @@ -1093,7 +1089,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(certnum) return CURLE_OK; - Curl_dyn_init(&out, MAX_X509_STR); + Curl_dyn_init(&out, CURL_X509_STR_MAX); /* Prepare the certificate information for curl_easy_getinfo(). */ /* Extract the certificate ASN.1 elements. */ diff --git a/lib/ws.c b/lib/ws.c index 3c2d94950..670694470 100644 --- a/lib/ws.c +++ b/lib/ws.c @@ -37,6 +37,7 @@ #include "ws.h" #include "easyif.h" #include "transfer.h" +#include "select.h" #include "nonblock.h" /* The last 3 #include files should be in this order */ @@ -127,7 +128,7 @@ static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data, } else { CURL_TRC_WRITE(data, "websocket, decoded %s [%s%s payload=%" - CURL_FORMAT_CURL_OFF_T "/%" CURL_FORMAT_CURL_OFF_T "]", + FMT_OFF_T "/%" FMT_OFF_T "]", msg, ws_frame_name_of_op(dec->head[0]), (dec->head[0] & WSBIT_FIN)? "" : " NON-FINAL", dec->payload_offset, dec->payload_len); @@ -136,6 +137,9 @@ static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data, } } +static CURLcode ws_send_raw_blocking(CURL *data, struct websocket *ws, + const char *buffer, size_t buflen); + typedef ssize_t ws_write_payload(const unsigned char *buf, size_t buflen, int frame_age, int frame_flags, curl_off_t payload_offset, @@ -278,7 +282,7 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec, dec->payload_offset += (curl_off_t)nwritten; remain = dec->payload_len - dec->payload_offset; CURL_TRC_WRITE(data, "websocket, passed %zd bytes payload, %" - CURL_FORMAT_CURL_OFF_T " remain", nwritten, remain); + FMT_OFF_T " remain", nwritten, remain); } return remain? CURLE_AGAIN : CURLE_OK; @@ -488,8 +492,7 @@ static const struct Curl_cwtype ws_cw_decode = { static void ws_enc_info(struct ws_encoder *enc, struct Curl_easy *data, const char *msg) { - infof(data, "WS-ENC: %s [%s%s%s payload=%" CURL_FORMAT_CURL_OFF_T - "/%" CURL_FORMAT_CURL_OFF_T "]", + infof(data, "WS-ENC: %s [%s%s%s payload=%" FMT_OFF_T "/%" FMT_OFF_T "]", msg, ws_frame_name_of_op(enc->firstbyte), (enc->firstbyte & WSBIT_OPCODE_MASK) == WSBIT_OPCODE_CONT ? " CONT" : "", @@ -547,20 +550,20 @@ static ssize_t ws_enc_write_head(struct Curl_easy *data, if(payload_len < 0) { failf(data, "WS: starting new frame with negative payload length %" - CURL_FORMAT_CURL_OFF_T, payload_len); + FMT_OFF_T, payload_len); *err = CURLE_SEND_ERROR; return -1; } if(enc->payload_remain > 0) { /* trying to write a new frame before the previous one is finished */ - failf(data, "WS: starting new frame with %zd bytes from last one" + failf(data, "WS: starting new frame with %zd bytes from last one " "remaining to be sent", (ssize_t)enc->payload_remain); *err = CURLE_SEND_ERROR; return -1; } - opcode = ws_frame_flags2op((int)flags); + opcode = ws_frame_flags2op((int)flags & ~CURLWS_CONT); if(!opcode) { failf(data, "WS: provided flags not recognized '%x'", flags); *err = CURLE_SEND_ERROR; @@ -773,7 +776,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data, } } #endif - DEBUGF(infof(data, "WS, using chunk size %zu", chunk_size)); + CURL_TRC_WS(data, "WS, using chunk size %zu", chunk_size); Curl_bufq_init2(&ws->recvbuf, chunk_size, WS_CHUNK_COUNT, BUFQ_OPT_SOFT_LIMIT); Curl_bufq_init2(&ws->sendbuf, chunk_size, WS_CHUNK_COUNT, @@ -970,8 +973,8 @@ CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer, infof(data, "connection expectedly closed?"); return CURLE_GOT_NOTHING; } - DEBUGF(infof(data, "curl_ws_recv, added %zu bytes from network", - Curl_bufq_len(&ws->recvbuf))); + CURL_TRC_WS(data, "curl_ws_recv, added %zu bytes from network", + Curl_bufq_len(&ws->recvbuf)); } result = ws_dec_pass(&ws->dec, data, &ws->recvbuf, @@ -1001,14 +1004,14 @@ CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer, ctx.payload_len, ctx.bufidx); *metap = &ws->frame; *nread = ws->frame.len; - /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %" - CURL_FORMAT_CURL_OFF_T ", %" CURL_FORMAT_CURL_OFF_T " left)", - buflen, *nread, ws->frame.offset, ws->frame.bytesleft); */ + CURL_TRC_WS(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %" + FMT_OFF_T ", %" FMT_OFF_T " left)", + buflen, *nread, ws->frame.offset, ws->frame.bytesleft); return CURLE_OK; } static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, - bool complete) + bool blocking) { if(!Curl_bufq_is_empty(&ws->sendbuf)) { CURLcode result; @@ -1016,30 +1019,26 @@ static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, size_t outlen, n; while(Curl_bufq_peek(&ws->sendbuf, &out, &outlen)) { - if(data->set.connect_only) + if(blocking) { + result = ws_send_raw_blocking(data, ws, (char *)out, outlen); + n = result? 0 : outlen; + } + else if(data->set.connect_only || Curl_is_in_callback(data)) result = Curl_senddata(data, out, outlen, &n); else { - result = Curl_xfer_send(data, out, outlen, &n); + result = Curl_xfer_send(data, out, outlen, FALSE, &n); if(!result && !n && outlen) result = CURLE_AGAIN; } - if(result) { - if(result == CURLE_AGAIN) { - if(!complete) { - infof(data, "WS: flush EAGAIN, %zu bytes remain in buffer", - Curl_bufq_len(&ws->sendbuf)); - return result; - } - /* TODO: the current design does not allow for buffered writes. - * We need to flush the buffer now. There is no ws_flush() later */ - n = 0; - continue; - } - else if(result) { - failf(data, "WS: flush, write error %d", result); - return result; - } + if(result == CURLE_AGAIN) { + CURL_TRC_WS(data, "flush EAGAIN, %zu bytes remain in buffer", + Curl_bufq_len(&ws->sendbuf)); + return result; + } + else if(result) { + failf(data, "WS: flush, write error %d", result); + return result; } else { infof(data, "WS: flushed %zu bytes", n); @@ -1050,6 +1049,83 @@ static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, return CURLE_OK; } +static CURLcode ws_send_raw_blocking(CURL *data, struct websocket *ws, + const char *buffer, size_t buflen) +{ + CURLcode result = CURLE_OK; + size_t nwritten; + + (void)ws; + while(buflen) { + result = Curl_xfer_send(data, buffer, buflen, FALSE, &nwritten); + if(result) + return result; + DEBUGASSERT(nwritten <= buflen); + buffer += nwritten; + buflen -= nwritten; + if(buflen) { + curl_socket_t sock = data->conn->sock[FIRSTSOCKET]; + timediff_t left_ms; + int ev; + + CURL_TRC_WS(data, "ws_send_raw_blocking() partial, %zu left to send", + buflen); + left_ms = Curl_timeleft(data, NULL, FALSE); + if(left_ms < 0) { + failf(data, "Timeout waiting for socket becoming writable"); + return CURLE_SEND_ERROR; + } + + /* POLLOUT socket */ + if(sock == CURL_SOCKET_BAD) + return CURLE_SEND_ERROR; + ev = Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, sock, + left_ms? left_ms : 500); + if(ev < 0) { + failf(data, "Error while waiting for socket becoming writable"); + return CURLE_SEND_ERROR; + } + } + } + return result; +} + +static CURLcode ws_send_raw(CURL *data, const void *buffer, + size_t buflen, size_t *pnwritten) +{ + struct websocket *ws = data->conn->proto.ws; + CURLcode result; + + if(!ws) { + failf(data, "Not a websocket transfer"); + return CURLE_SEND_ERROR; + } + if(!buflen) + return CURLE_OK; + + if(Curl_is_in_callback(data)) { + /* When invoked from inside callbacks, we do a blocking send as the + * callback will probably not implement partial writes that may then + * mess up the ws framing subsequently. + * We need any pending data to be flushed before sending. */ + result = ws_flush(data, ws, TRUE); + if(result) + return result; + result = ws_send_raw_blocking(data, ws, buffer, buflen); + } + else { + /* We need any pending data to be sent or EAGAIN this call. */ + result = ws_flush(data, ws, FALSE); + if(result) + return result; + result = Curl_senddata(data, buffer, buflen, pnwritten); + } + + CURL_TRC_WS(data, "ws_send_raw(len=%zu) -> %d, %zu", + buflen, result, *pnwritten); + return result; +} + CURL_EXTERN CURLcode curl_ws_send(CURL *data, const void *buffer, size_t buflen, size_t *sent, curl_off_t fragsize, @@ -1057,60 +1133,53 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *data, const void *buffer, { struct websocket *ws; ssize_t n; - size_t nwritten, space; + size_t space, payload_added; CURLcode result; + CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T + ", flags=%x), raw=%d", + buflen, fragsize, flags, data->set.ws_raw_mode); *sent = 0; if(!data->conn && data->set.connect_only) { result = Curl_connect_only_attach(data); if(result) - return result; + goto out; } if(!data->conn) { failf(data, "No associated connection"); - return CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; + goto out; } if(!data->conn->proto.ws) { failf(data, "Not a websocket transfer"); - return CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; + goto out; } ws = data->conn->proto.ws; + /* try flushing any content still waiting to be sent. */ + result = ws_flush(data, ws, FALSE); + if(result) + goto out; + if(data->set.ws_raw_mode) { + /* In raw mode, we write directly to the connection */ if(fragsize || flags) { - DEBUGF(infof(data, "ws_send: " - "fragsize and flags cannot be non-zero in raw mode")); + failf(data, "ws_send, raw mode: fragsize and flags cannot be non-zero"); return CURLE_BAD_FUNCTION_ARGUMENT; } - if(!buflen) - /* nothing to do */ - return CURLE_OK; - /* raw mode sends exactly what was requested, and this is from within - the write callback */ - if(Curl_is_in_callback(data)) { - result = Curl_xfer_send(data, buffer, buflen, &nwritten); - } - else - result = Curl_senddata(data, buffer, buflen, &nwritten); - - infof(data, "WS: wanted to send %zu bytes, sent %zu bytes", - buflen, nwritten); - *sent = nwritten; - return result; + result = ws_send_raw(data, buffer, buflen, sent); + goto out; } /* Not RAW mode, buf we do the frame encoding */ - result = ws_flush(data, ws, FALSE); - if(result) - return result; - - /* TODO: the current design does not allow partial writes, afaict. - * It is not clear how the application is supposed to react. */ space = Curl_bufq_space(&ws->sendbuf); - DEBUGF(infof(data, "curl_ws_send(len=%zu), sendbuf len=%zu space %zu", - buflen, Curl_bufq_len(&ws->sendbuf), space)); - if(space < 14) - return CURLE_AGAIN; + CURL_TRC_WS(data, "curl_ws_send(len=%zu), sendbuf=%zu space_left=%zu", + buflen, Curl_bufq_len(&ws->sendbuf), space); + if(space < 14) { + result = CURLE_AGAIN; + goto out; + } if(flags & CURLWS_OFFSET) { if(fragsize) { @@ -1118,12 +1187,12 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *data, const void *buffer, n = ws_enc_write_head(data, &ws->enc, flags, fragsize, &ws->sendbuf, &result); if(n < 0) - return result; + goto out; } else { if((curl_off_t)buflen > ws->enc.payload_remain) { infof(data, "WS: unaligned frame size (sending %zu instead of %" - CURL_FORMAT_CURL_OFF_T ")", + FMT_OFF_T ")", buflen, ws->enc.payload_remain); } } @@ -1132,16 +1201,66 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *data, const void *buffer, n = ws_enc_write_head(data, &ws->enc, flags, (curl_off_t)buflen, &ws->sendbuf, &result); if(n < 0) - return result; + goto out; } n = ws_enc_write_payload(&ws->enc, data, buffer, buflen, &ws->sendbuf, &result); if(n < 0) - return result; + goto out; + payload_added = (size_t)n; + + while(!result && (buflen || !Curl_bufq_is_empty(&ws->sendbuf))) { + /* flush, blocking when in callback */ + result = ws_flush(data, ws, Curl_is_in_callback(data)); + if(!result) { + DEBUGASSERT(payload_added <= buflen); + /* all buffered data sent. Try sending the rest if there is any. */ + *sent += payload_added; + buffer = (const char *)buffer + payload_added; + buflen -= payload_added; + payload_added = 0; + if(buflen) { + n = ws_enc_write_payload(&ws->enc, data, + buffer, buflen, &ws->sendbuf, &result); + if(n < 0) + goto out; + payload_added = Curl_bufq_len(&ws->sendbuf); + } + } + else if(result == CURLE_AGAIN) { + /* partially sent. how much of the call data has been part of it? what + * should we report to out caller so it can retry/send the rest? */ + if(payload_added < buflen) { + /* We did not add everything the caller wanted. Return just + * the partial write to our buffer. */ + *sent = payload_added; + result = CURLE_OK; + goto out; + } + else if(!buflen) { + /* We have no payload to report a partial write. EAGAIN would make + * the caller repeat this and add the frame again. + * Flush blocking seems the only way out of this. */ + *sent = (size_t)n; + result = ws_flush(data, ws, TRUE); + goto out; + } + /* We added the complete data to our sendbuf. Report one byte less as + * sent. This parital success should make the caller invoke us again + * with the last byte. */ + *sent = payload_added - 1; + result = Curl_bufq_unwrite(&ws->sendbuf, 1); + if(!result) + result = CURLE_AGAIN; + } + } - *sent = (size_t)n; - return ws_flush(data, ws, TRUE); +out: + CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T + ", flags=%x, raw=%d) -> %d, %zu", + buflen, fragsize, flags, data->set.ws_raw_mode, result, *sent); + return result; } static void ws_free(struct connectdata *conn) @@ -1156,7 +1275,7 @@ static void ws_free(struct connectdata *conn) static CURLcode ws_setup_conn(struct Curl_easy *data, struct connectdata *conn) { - /* websockets is 1.1 only (for now) */ + /* WebSockets is 1.1 only (for now) */ data->state.httpwant = CURL_HTTP_VERSION_1_1; return Curl_http_setup_conn(data, conn); } diff --git a/libcurl.pc.in b/libcurl.pc.in index 0eb180485..8f6f9b4f5 100644 --- a/libcurl.pc.in +++ b/libcurl.pc.in @@ -35,6 +35,7 @@ Description: Library to transfer files with ftp, http, etc. Version: @CURLVERSION@ Requires: @LIBCURL_PC_REQUIRES@ Requires.private: @LIBCURL_PC_REQUIRES_PRIVATE@ -Libs: -L${libdir} -lcurl @LIBCURL_NO_SHARED@ -Libs.private: @LIBCURL_LIBS@ -Cflags: -I${includedir} @CPPFLAG_CURL_STATICLIB@ +Libs: -L${libdir} -lcurl @LIBCURL_PC_LIBS@ +Libs.private: @LIBCURL_PC_LIBS_PRIVATE@ +Cflags: -I${includedir} @LIBCURL_PC_CFLAGS@ +Cflags.private: @LIBCURL_PC_CFLAGS_PRIVATE@ diff --git a/m4/curl-amissl.m4 b/m4/curl-amissl.m4 index 48067e720..b41720721 100644 --- a/m4/curl-amissl.m4 +++ b/m4/curl-amissl.m4 @@ -52,7 +52,6 @@ if test "$HAVE_PROTO_BSDSOCKET_H" = "1"; then LIBS="-lamisslstubs -lamisslauto $LIBS" AC_DEFINE(USE_AMISSL, 1, [if AmiSSL is in use]) AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]) - AC_DEFINE_UNQUOTED(HAVE_OPENSSL3, 1, [Define to 1 if using OpenSSL 3 or later.]) AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \ openssl/pem.h openssl/ssl.h openssl/err.h) ],[ diff --git a/m4/curl-bearssl.m4 b/m4/curl-bearssl.m4 index f2d661de1..02a80e8c1 100644 --- a/m4/curl-bearssl.m4 +++ b/m4/curl-bearssl.m4 @@ -43,14 +43,14 @@ if test "x$OPT_BEARSSL" != xno; then AC_CHECK_LIB(bearssl, br_ssl_client_init_full, dnl libbearssl found, set the variable - [ - AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled]) - AC_SUBST(USE_BEARSSL, [1]) - BEARSSL_ENABLED=1 - USE_BEARSSL="yes" - ssl_msg="BearSSL" - test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], [], -lbearssl) + [ + AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled]) + AC_SUBST(USE_BEARSSL, [1]) + BEARSSL_ENABLED=1 + USE_BEARSSL="yes" + ssl_msg="BearSSL" + test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], [], -lbearssl) fi addld="" @@ -66,22 +66,22 @@ if test "x$OPT_BEARSSL" != xno; then LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi AC_CHECK_LIB(bearssl, br_ssl_client_init_full, - [ - AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled]) - AC_SUBST(USE_BEARSSL, [1]) - BEARSSL_ENABLED=1 - USE_BEARSSL="yes" - ssl_msg="BearSSL" - test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], - [ - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags - ], -lbearssl) + [ + AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled]) + AC_SUBST(USE_BEARSSL, [1]) + BEARSSL_ENABLED=1 + USE_BEARSSL="yes" + ssl_msg="BearSSL" + test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + ], -lbearssl) fi if test "x$USE_BEARSSL" = "xyes"; then diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4 index 001e5f4aa..240aa2b0b 100644 --- a/m4/curl-compilers.m4 +++ b/m4/curl-compilers.m4 @@ -148,7 +148,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_DEC_C], [ CURL_CHECK_DEF([__DECC], [], [silent]) CURL_CHECK_DEF([__DECC_VER], [], [silent]) if test "$curl_cv_have_def___DECC" = "yes" && - test "$curl_cv_have_def___DECC_VER" = "yes"; then + test "$curl_cv_have_def___DECC_VER" = "yes"; then AC_MSG_RESULT([yes]) compiler_id="DEC_C" flags_dbg_yes="-g2" @@ -185,7 +185,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [ compiler_id="GNU_C" AC_MSG_CHECKING([compiler version]) # strip '-suffix' parts, e.g. Ubuntu Windows cross-gcc returns '10-win32' - gccver=`$CC -dumpversion | sed -E 's/-.+$//'` + gccver=`$CC -dumpversion | "$SED" 's/-.\{1,\}$//'` gccvhi=`echo $gccver | cut -d . -f1` if echo $gccver | grep -F '.' >/dev/null; then gccvlo=`echo $gccver | cut -d . -f2` @@ -569,7 +569,7 @@ AC_DEFUN([CURL_SET_COMPILER_BASIC_OPTS], [ # INTEL_UNIX_C) # - dnl On unix this compiler uses gcc's header files, so + dnl On Unix this compiler uses gcc's header files, so dnl we select ANSI C89 dialect plus GNU extensions. tmp_CFLAGS="$tmp_CFLAGS -std=gnu89" dnl Change some warnings into errors @@ -852,13 +852,13 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [enum-conversion]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sometimes-uninitialized]) case $host_os in - cygwin* | mingw*) - dnl skip missing-variable-declarations warnings for cygwin and - dnl mingw because the libtool wrapper executable causes them - ;; - *) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-variable-declarations]) - ;; + cygwin* | mingw*) + dnl skip missing-variable-declarations warnings for Cygwin and + dnl MinGW because the libtool wrapper executable causes them + ;; + *) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-variable-declarations]) + ;; esac fi # @@ -1032,7 +1032,7 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ # dnl Only gcc 4.5 or later if test "$compiler_num" -ge "405"; then - dnl Only windows targets + dnl Only Windows targets if test "$curl_cv_native_windows" = "yes"; then tmp_CFLAGS="$tmp_CFLAGS -Wno-pedantic-ms-format" fi @@ -1068,7 +1068,7 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [duplicated-branches]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [restrict]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [alloc-zero]) - tmp_CFLAGS="$tmp_CFLAGS -Wformat-overflow=2" + tmp_CFLAGS="$tmp_CFLAGS -Wno-format-overflow" tmp_CFLAGS="$tmp_CFLAGS -Wformat-truncation=2" tmp_CFLAGS="$tmp_CFLAGS -Wimplicit-fallthrough" fi @@ -1424,10 +1424,10 @@ AC_DEFUN([CURL_CHECK_COMPILER_SYMBOL_HIDING], [ $tmp_EXTERN char *dummy(char *buff); char *dummy(char *buff) { - if(buff) - return ++buff; - else - return buff; + if(buff) + return ++buff; + else + return buff; } ]],[[ char b[16]; diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4 index c65120271..77aa65272 100644 --- a/m4/curl-functions.m4 +++ b/m4/curl-functions.m4 @@ -1475,35 +1475,35 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [ AC_MSG_CHECKING([if getaddrinfo is threadsafe]) case $host_os in aix[[1234]].* | aix5.[[01]].*) - dnl aix 5.1 and older + dnl AIX 5.1 and older tst_tsafe_getaddrinfo="no" ;; aix*) - dnl aix 5.2 and newer + dnl AIX 5.2 and newer tst_tsafe_getaddrinfo="yes" ;; darwin[[12345]].*) - dnl darwin 5.0 and mac os x 10.1.X and older + dnl Darwin 5.0 and macOS 10.1.X and older tst_tsafe_getaddrinfo="no" ;; darwin*) - dnl darwin 6.0 and mac os x 10.2.X and newer + dnl Darwin 6.0 and macOS 10.2.X and newer tst_tsafe_getaddrinfo="yes" ;; freebsd[[1234]].* | freebsd5.[[1234]]*) - dnl freebsd 5.4 and older + dnl FreeBSD 5.4 and older tst_tsafe_getaddrinfo="no" ;; freebsd*) - dnl freebsd 5.5 and newer + dnl FreeBSD 5.5 and newer tst_tsafe_getaddrinfo="yes" ;; hpux[[123456789]].* | hpux10.* | hpux11.0* | hpux11.10*) - dnl hpux 11.10 and older + dnl HP-UX 11.10 and older tst_tsafe_getaddrinfo="no" ;; hpux*) - dnl hpux 11.11 and newer + dnl HP-UX 11.11 and newer tst_tsafe_getaddrinfo="yes" ;; midnightbsd*) @@ -1511,19 +1511,19 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [ tst_tsafe_getaddrinfo="yes" ;; netbsd[[123]].*) - dnl netbsd 3.X and older + dnl NetBSD 3.X and older tst_tsafe_getaddrinfo="no" ;; netbsd*) - dnl netbsd 4.X and newer + dnl NetBSD 4.X and newer tst_tsafe_getaddrinfo="yes" ;; *bsd*) - dnl All other bsd's + dnl All other BSD's tst_tsafe_getaddrinfo="no" ;; solaris2*) - dnl solaris which have it + dnl Solaris which have it tst_tsafe_getaddrinfo="yes" ;; esac @@ -3470,42 +3470,46 @@ AC_DEFUN([CURL_CHECK_FUNC_POLL], [ fi # dnl only do runtime verification when not cross-compiling - if test "x$cross_compiling" != "xyes" && - test "$tst_compi_poll" = "yes"; then - AC_MSG_CHECKING([if poll seems to work]) - CURL_RUN_IFELSE([ - AC_LANG_PROGRAM([[ - $curl_includes_stdlib - $curl_includes_poll - $curl_includes_time - ]],[[ - /* detect the original poll() breakage */ - if(0 != poll(0, 0, 10)) - exit(1); /* fail */ - else { - /* detect the 10.12 poll() breakage */ - struct timeval before, after; - int rc; - size_t us; - - gettimeofday(&before, NULL); - rc = poll(NULL, 0, 500); - gettimeofday(&after, NULL); - - us = (after.tv_sec - before.tv_sec) * 1000000 + - (after.tv_usec - before.tv_usec); - - if(us < 400000) - exit(1); - } - ]]) - ],[ - AC_MSG_RESULT([yes]) - tst_works_poll="yes" - ],[ - AC_MSG_RESULT([no]) - tst_works_poll="no" - ]) + if test "$tst_compi_poll" = "yes"; then + if test "x$cross_compiling" != "xyes"; then + AC_MSG_CHECKING([if poll seems to work]) + CURL_RUN_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_stdlib + $curl_includes_poll + ]],[[ + /* detect the original poll() breakage */ + if(0 != poll(0, 0, 10)) { + return 1; /* fail */ + } + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_works_poll="yes" + ],[ + AC_MSG_RESULT([no]) + tst_works_poll="no" + ]) + else + AC_MSG_CHECKING([if native poll seems to be supported]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $curl_includes_stdlib + ]],[[ + #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L + return 0; + #else + #error force compilation error + #endif + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_works_poll="yes" + ],[ + AC_MSG_RESULT([no]) + tst_works_poll="no" + ]) + fi fi # if test "$tst_compi_poll" = "yes" && @@ -4870,11 +4874,11 @@ dnl CURL_LIBRARY_PATH variable. It keeps the LD_LIBRARY_PATH dnl changes contained within this macro. AC_DEFUN([CURL_RUN_IFELSE], [ - case $host_os in - darwin*) + case $host_os in + darwin*) AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4) - ;; - *) + ;; + *) oldcc=$CC old=$LD_LIBRARY_PATH CC="sh ./run-compiler" @@ -4883,8 +4887,8 @@ AC_DEFUN([CURL_RUN_IFELSE], [ AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4) LD_LIBRARY_PATH=$old # restore CC=$oldcc - ;; - esac + ;; + esac ]) dnl CURL_COVERAGE @@ -4901,8 +4905,8 @@ AC_DEFUN([CURL_COVERAGE],[ dnl check if enabled by argument AC_ARG_ENABLE(code-coverage, - AS_HELP_STRING([--enable-code-coverage], [Provide code coverage]), - coverage="$enableval") + AS_HELP_STRING([--enable-code-coverage], [Provide code coverage]), + coverage="$enableval") dnl if not gcc switch off again AS_IF([ test "$GCC" != "yes" ], coverage="no" ) @@ -4981,19 +4985,19 @@ AC_DEFUN([CURL_SIZEOF], [ r=0 dnl Check the sizes in a reasonable order for typesize in 8 4 2 16 1; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include $2 ]], - [switch(0) { - case 0: - case (sizeof($1) == $typesize):; - } + [switch(0) { + case 0: + case (sizeof($1) == $typesize):; + } ]) ], [ - r=$typesize], + r=$typesize], [ - r=0]) + r=0]) dnl get out of the loop once matched if test $r -gt 0; then break; diff --git a/m4/curl-gnutls.m4 b/m4/curl-gnutls.m4 index 6a297f684..93c3946a9 100644 --- a/m4/curl-gnutls.m4 +++ b/m4/curl-gnutls.m4 @@ -93,24 +93,24 @@ if test "x$OPT_GNUTLS" != xno; then LIBS="$addlib $LIBS" LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi dnl this function is selected since it was introduced in 3.1.10 AC_CHECK_LIB(gnutls, gnutls_x509_crt_get_dn2, - [ - AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled]) - AC_SUBST(USE_GNUTLS, [1]) - GNUTLS_ENABLED=1 - USE_GNUTLS="yes" - ssl_msg="GnuTLS" - QUIC_ENABLED=yes - test gnutls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], - [ - LIBS="$CLEANLIBS" - CPPFLAGS="$CLEANCPPFLAGS" - ]) + [ + AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled]) + AC_SUBST(USE_GNUTLS, [1]) + GNUTLS_ENABLED=1 + USE_GNUTLS="yes" + ssl_msg="GnuTLS" + QUIC_ENABLED=yes + test gnutls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + LIBS="$CLEANLIBS" + CPPFLAGS="$CLEANCPPFLAGS" + ]) if test "x$USE_GNUTLS" = "xyes"; then AC_MSG_NOTICE([detected GnuTLS version $version]) @@ -160,10 +160,10 @@ dnl We require GnuTLS with SRP support. dnl --- if test "$GNUTLS_ENABLED" = "1"; then AC_CHECK_LIB(gnutls, gnutls_srp_verifier, - [ - AC_DEFINE(HAVE_GNUTLS_SRP, 1, [if you have the function gnutls_srp_verifier]) - AC_SUBST(HAVE_GNUTLS_SRP, [1]) - ]) + [ + AC_DEFINE(HAVE_GNUTLS_SRP, 1, [if you have the function gnutls_srp_verifier]) + AC_SUBST(HAVE_GNUTLS_SRP, [1]) + ]) fi ]) diff --git a/m4/curl-mbedtls.m4 b/m4/curl-mbedtls.m4 index 8504015da..bf14c6c89 100644 --- a/m4/curl-mbedtls.m4 +++ b/m4/curl-mbedtls.m4 @@ -43,14 +43,14 @@ if test "x$OPT_MBEDTLS" != xno; then AC_CHECK_LIB(mbedtls, mbedtls_havege_init, dnl libmbedtls found, set the variable - [ - AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) - AC_SUBST(USE_MBEDTLS, [1]) - MBEDTLS_ENABLED=1 - USE_MBEDTLS="yes" - ssl_msg="mbedTLS" - test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], [], -lmbedx509 -lmbedcrypto) + [ + AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) + AC_SUBST(USE_MBEDTLS, [1]) + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], [], -lmbedx509 -lmbedcrypto) fi addld="" @@ -66,22 +66,22 @@ if test "x$OPT_MBEDTLS" != xno; then LDFLAGS="$LDFLAGS $addld" if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" + CPPFLAGS="$CPPFLAGS $addcflags" fi AC_CHECK_LIB(mbedtls, mbedtls_ssl_init, - [ - AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) - AC_SUBST(USE_MBEDTLS, [1]) - MBEDTLS_ENABLED=1 - USE_MBEDTLS="yes" - ssl_msg="mbedTLS" - test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], - [ - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags - ], -lmbedx509 -lmbedcrypto) + [ + AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled]) + AC_SUBST(USE_MBEDTLS, [1]) + MBEDTLS_ENABLED=1 + USE_MBEDTLS="yes" + ssl_msg="mbedTLS" + test mbedtls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + ], -lmbedx509 -lmbedcrypto) fi if test "x$USE_MBEDTLS" = "xyes"; then diff --git a/m4/curl-openssl.m4 b/m4/curl-openssl.m4 index 76107c21a..ad32b2ef0 100644 --- a/m4/curl-openssl.m4 +++ b/m4/curl-openssl.m4 @@ -38,7 +38,7 @@ if test "x$OPT_OPENSSL" != xno; then CLEANCPPFLAGS="$CPPFLAGS" CLEANLIBS="$LIBS" - dnl This is for Msys/Mingw + dnl This is for MSYS/MinGW case $host in *-*-msys* | *-*-mingw*) AC_MSG_CHECKING([for gdi32]) @@ -61,48 +61,48 @@ if test "x$OPT_OPENSSL" != xno; then esac case "$OPT_OPENSSL" in - yes) - dnl --with-openssl (without path) used - PKGTEST="yes" - PREFIX_OPENSSL= - ;; - *) - dnl check the given --with-openssl spot - PKGTEST="no" - PREFIX_OPENSSL=$OPT_OPENSSL - - dnl Try pkg-config even when cross-compiling. Since we - dnl specify PKG_CONFIG_LIBDIR we're only looking where - dnl the user told us to look - OPENSSL_PCDIR="$OPT_OPENSSL/lib/pkgconfig" - if test -f "$OPENSSL_PCDIR/openssl.pc"; then - AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$OPENSSL_PCDIR"]) + yes) + dnl --with-openssl (without path) used PKGTEST="yes" - fi - - if test "$PKGTEST" != "yes"; then - # try lib64 instead - OPENSSL_PCDIR="$OPT_OPENSSL/lib64/pkgconfig" + PREFIX_OPENSSL= + ;; + *) + dnl check the given --with-openssl spot + PKGTEST="no" + PREFIX_OPENSSL=$OPT_OPENSSL + + dnl Try pkg-config even when cross-compiling. Since we + dnl specify PKG_CONFIG_LIBDIR we're only looking where + dnl the user told us to look + OPENSSL_PCDIR="$OPT_OPENSSL/lib/pkgconfig" if test -f "$OPENSSL_PCDIR/openssl.pc"; then AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$OPENSSL_PCDIR"]) PKGTEST="yes" fi - fi - if test "$PKGTEST" != "yes"; then - if test ! -f "$PREFIX_OPENSSL/include/openssl/ssl.h"; then - AC_MSG_ERROR([$PREFIX_OPENSSL is a bad --with-openssl prefix!]) + if test "$PKGTEST" != "yes"; then + # try lib64 instead + OPENSSL_PCDIR="$OPT_OPENSSL/lib64/pkgconfig" + if test -f "$OPENSSL_PCDIR/openssl.pc"; then + AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$OPENSSL_PCDIR"]) + PKGTEST="yes" + fi fi - fi - dnl in case pkg-config comes up empty, use what we got - dnl via --with-openssl - LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" - if test "$PREFIX_OPENSSL" != "/usr" ; then - SSL_LDFLAGS="-L$LIB_OPENSSL" - SSL_CPPFLAGS="-I$PREFIX_OPENSSL/include" - fi - ;; + if test "$PKGTEST" != "yes"; then + if test ! -f "$PREFIX_OPENSSL/include/openssl/ssl.h"; then + AC_MSG_ERROR([$PREFIX_OPENSSL is a bad --with-openssl prefix!]) + fi + fi + + dnl in case pkg-config comes up empty, use what we got + dnl via --with-openssl + LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff" + if test "$PREFIX_OPENSSL" != "/usr" ; then + SSL_LDFLAGS="-L$LIB_OPENSSL" + SSL_CPPFLAGS="-I$PREFIX_OPENSSL/include" + fi + ;; esac if test "$PKGTEST" = "yes"; then @@ -141,63 +141,60 @@ if test "x$OPT_OPENSSL" != xno; then LDFLAGS="$LDFLAGS $SSL_LDFLAGS" AC_CHECK_LIB(crypto, HMAC_Update,[ - HAVECRYPTO="yes" - LIBS="-lcrypto $LIBS" - ],[ - if test -n "$LIB_OPENSSL" ; then - LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL" - fi - if test "$PKGCONFIG" = "no" -a -n "$PREFIX_OPENSSL" ; then - # only set this if pkg-config wasn't used - CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include" - fi - # Linking previously failed, try extra paths from --with-openssl or - # pkg-config. Use a different function name to avoid reusing the earlier - # cached result. - AC_CHECK_LIB(crypto, HMAC_Init_ex,[ - HAVECRYPTO="yes" - LIBS="-lcrypto $LIBS"], [ - - dnl still no, but what about with -ldl? - AC_MSG_CHECKING([OpenSSL linking with -ldl]) - LIBS="-lcrypto $CLEANLIBS -ldl" - AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ - #include - ]], [[ - ERR_clear_error(); - ]]) ], - [ - AC_MSG_RESULT(yes) - HAVECRYPTO="yes" - ], - [ - AC_MSG_RESULT(no) - dnl ok, so what about both -ldl and -lpthread? - dnl This may be necessary for static libraries. - - AC_MSG_CHECKING([OpenSSL linking with -ldl and -lpthread]) - LIBS="-lcrypto $CLEANLIBS -ldl -lpthread" - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]], [[ - ERR_clear_error(); - ]])], - [ - AC_MSG_RESULT(yes) - HAVECRYPTO="yes" - ], - [ - AC_MSG_RESULT(no) - LDFLAGS="$CLEANLDFLAGS" - CPPFLAGS="$CLEANCPPFLAGS" - LIBS="$CLEANLIBS" - - ]) - - ]) - - ]) + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS" + ],[ + if test -n "$LIB_OPENSSL" ; then + LDFLAGS="$CLEANLDFLAGS -L$LIB_OPENSSL" + fi + if test "$PKGCONFIG" = "no" -a -n "$PREFIX_OPENSSL" ; then + # only set this if pkg-config wasn't used + CPPFLAGS="$CLEANCPPFLAGS -I$PREFIX_OPENSSL/include" + fi + # Linking previously failed, try extra paths from --with-openssl or + # pkg-config. Use a different function name to avoid reusing the earlier + # cached result. + AC_CHECK_LIB(crypto, HMAC_Init_ex,[ + HAVECRYPTO="yes" + LIBS="-lcrypto $LIBS"], [ + + dnl still no, but what about with -ldl? + AC_MSG_CHECKING([OpenSSL linking with -ldl]) + LIBS="-lcrypto $CLEANLIBS -ldl" + AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ + #include + ]], [[ + ERR_clear_error(); + ]]) ], + [ + AC_MSG_RESULT(yes) + HAVECRYPTO="yes" + ], + [ + AC_MSG_RESULT(no) + dnl ok, so what about both -ldl and -lpthread? + dnl This may be necessary for static libraries. + + AC_MSG_CHECKING([OpenSSL linking with -ldl and -lpthread]) + LIBS="-lcrypto $CLEANLIBS -ldl -lpthread" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #include + ]], [[ + ERR_clear_error(); + ]])], + [ + AC_MSG_RESULT(yes) + HAVECRYPTO="yes" + ], + [ + AC_MSG_RESULT(no) + LDFLAGS="$CLEANLDFLAGS" + CPPFLAGS="$CLEANCPPFLAGS" + LIBS="$CLEANLIBS" + ]) + ]) + ]) ]) if test X"$HAVECRYPTO" = X"yes"; then @@ -207,18 +204,18 @@ if test "x$OPT_OPENSSL" != xno; then AC_CHECK_LIB(ssl, SSL_connect) if test "$ac_cv_lib_ssl_SSL_connect" != yes; then - dnl we didn't find the SSL lib, try the RSAglue/rsaref stuff - AC_MSG_CHECKING(for ssl with RSAglue/rsaref libs in use); - OLIBS=$LIBS - LIBS="-lRSAglue -lrsaref $LIBS" - AC_CHECK_LIB(ssl, SSL_connect) - if test "$ac_cv_lib_ssl_SSL_connect" != yes; then - dnl still no SSL_connect - AC_MSG_RESULT(no) - LIBS=$OLIBS - else - AC_MSG_RESULT(yes) - fi + dnl we didn't find the SSL lib, try the RSAglue/rsaref stuff + AC_MSG_CHECKING(for ssl with RSAglue/rsaref libs in use); + OLIBS=$LIBS + LIBS="-lRSAglue -lrsaref $LIBS" + AC_CHECK_LIB(ssl, SSL_connect) + if test "$ac_cv_lib_ssl_SSL_connect" != yes; then + dnl still no SSL_connect + AC_MSG_RESULT(no) + LIBS=$OLIBS + else + AC_MSG_RESULT(yes) + fi else @@ -247,7 +244,7 @@ if test "x$OPT_OPENSSL" != xno; then fi if test X"$OPENSSL_ENABLED" != X"1"; then - LIBS="$CLEANLIBS" + LIBS="$CLEANLIBS" fi if test X"$OPT_OPENSSL" != Xoff && @@ -261,42 +258,42 @@ if test "x$OPT_OPENSSL" != xno; then AC_MSG_CHECKING([for BoringSSL]) AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]],[[ - #ifndef OPENSSL_IS_BORINGSSL - #error not boringssl - #endif - ]]) + AC_LANG_PROGRAM([[ + #include + ]],[[ + #ifndef OPENSSL_IS_BORINGSSL + #error not boringssl + #endif + ]]) ],[ - AC_MSG_RESULT([yes]) - ssl_msg="BoringSSL" - OPENSSL_IS_BORINGSSL=1 + AC_MSG_RESULT([yes]) + ssl_msg="BoringSSL" + OPENSSL_IS_BORINGSSL=1 ],[ - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) ]) AC_MSG_CHECKING([for AWS-LC]) AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]],[[ - #ifndef OPENSSL_IS_AWSLC - #error not AWS-LC - #endif - ]]) + AC_LANG_PROGRAM([[ + #include + ]],[[ + #ifndef OPENSSL_IS_AWSLC + #error not AWS-LC + #endif + ]]) ],[ - AC_MSG_RESULT([yes]) - ssl_msg="AWS-LC" - OPENSSL_IS_BORINGSSL=1 + AC_MSG_RESULT([yes]) + ssl_msg="AWS-LC" + OPENSSL_IS_BORINGSSL=1 ],[ - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) ]) AC_MSG_CHECKING([for LibreSSL]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ -#include + #include ]],[[ int dummy = LIBRESSL_VERSION_NUMBER; ]]) @@ -312,7 +309,7 @@ if test "x$OPT_OPENSSL" != xno; then AC_MSG_CHECKING([for OpenSSL >= v3]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ -#include + #include ]],[[ #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) return 0; @@ -322,8 +319,6 @@ if test "x$OPT_OPENSSL" != xno; then ]]) ],[ AC_MSG_RESULT([yes]) - AC_DEFINE_UNQUOTED(HAVE_OPENSSL3, 1, - [Define to 1 if using OpenSSL 3 or later.]) ssl_msg="OpenSSL v3+" ],[ AC_MSG_RESULT([no]) @@ -341,14 +336,14 @@ if test "x$OPT_OPENSSL" != xno; then if test "$OPENSSL_ENABLED" = "1"; then if test -n "$LIB_OPENSSL"; then - dnl when the ssl shared libs were found in a path that the run-time - dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH - dnl to prevent further configure tests to fail due to this - if test "x$cross_compiling" != "xyes"; then - CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_OPENSSL" - export CURL_LIBRARY_PATH - AC_MSG_NOTICE([Added $LIB_OPENSSL to CURL_LIBRARY_PATH]) - fi + dnl when the ssl shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to CURL_LIBRARY_PATH + dnl to prevent further configure tests to fail due to this + if test "x$cross_compiling" != "xyes"; then + CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$LIB_OPENSSL" + export CURL_LIBRARY_PATH + AC_MSG_NOTICE([Added $LIB_OPENSSL to CURL_LIBRARY_PATH]) + fi fi check_for_ca_bundle=1 LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE openssl" @@ -358,38 +353,12 @@ if test "x$OPT_OPENSSL" != xno; then fi if test X"$OPT_OPENSSL" != Xno && - test "$OPENSSL_ENABLED" != "1"; then + test "$OPENSSL_ENABLED" != "1"; then AC_MSG_NOTICE([OPT_OPENSSL: $OPT_OPENSSL]) AC_MSG_NOTICE([OPENSSL_ENABLED: $OPENSSL_ENABLED]) AC_MSG_ERROR([--with-openssl was given but OpenSSL could not be detected]) fi -dnl ********************************************************************** -dnl Check for the random seed preferences -dnl ********************************************************************** - -if test X"$OPENSSL_ENABLED" = X"1"; then - dnl Check for user-specified random device - AC_ARG_WITH(random, - AS_HELP_STRING([--with-random=FILE], - [read randomness from FILE (default=/dev/urandom)]), - [ RANDOM_FILE="$withval" ], - [ - if test x$cross_compiling != xyes; then - dnl Check for random device - AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] ) - else - AC_MSG_WARN([skipped the /dev/urandom detection when cross-compiling]) - fi - ] - ) - if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then - AC_SUBST(RANDOM_FILE) - AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE", - [a suitable file to read random data from]) - fi -fi - dnl --- dnl We require OpenSSL with SRP support. dnl --- @@ -397,7 +366,7 @@ if test "$OPENSSL_ENABLED" = "1"; then AC_MSG_CHECKING([for SRP support in OpenSSL]) AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ -#include + #include ]],[[ SSL_CTX_set_srp_username(NULL, ""); SSL_CTX_set_srp_password(NULL, ""); @@ -432,7 +401,7 @@ if test "$OPENSSL_ENABLED" = "1"; then AC_MSG_CHECKING([for QUIC support and OpenSSL >= 3.3]) AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ -#include + #include ]],[[ #if (OPENSSL_VERSION_NUMBER < 0x30300000L) #error need at least version 3.3.0 @@ -441,8 +410,7 @@ if test "$OPENSSL_ENABLED" = "1"; then ]]) ],[ AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_OPENSSL_QUIC, 1, [if you have the functions OSSL_QUIC_client_method]) - AC_SUBST(HAVE_OPENSSL_QUIC, [1]) + have_openssl_quic=1 ],[ AC_MSG_RESULT([no]) ]) diff --git a/m4/curl-rustls.m4 b/m4/curl-rustls.m4 index c9f9caedd..4d2aabfbc 100644 --- a/m4/curl-rustls.m4 +++ b/m4/curl-rustls.m4 @@ -24,7 +24,7 @@ AC_DEFUN([CURL_WITH_RUSTLS], [ dnl ---------------------------------------------------- -dnl check for rustls +dnl check for Rustls dnl ---------------------------------------------------- if test "x$OPT_RUSTLS" != xno; then @@ -90,14 +90,14 @@ if test "x$OPT_RUSTLS" != xno; then AC_CHECK_LIB(rustls, rustls_connection_read, [ - AC_DEFINE(USE_RUSTLS, 1, [if rustls is enabled]) + AC_DEFINE(USE_RUSTLS, 1, [if Rustls is enabled]) AC_SUBST(USE_RUSTLS, [1]) RUSTLS_ENABLED=1 USE_RUSTLS="yes" ssl_msg="rustls" test rustls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes ], - AC_MSG_ERROR([--with-rustls was specified but could not find rustls.]), + AC_MSG_ERROR([--with-rustls was specified but could not find Rustls.]), -lpthread -ldl -lm) LIB_RUSTLS="$PREFIX_RUSTLS/lib$libsuff" @@ -138,18 +138,18 @@ if test "x$OPT_RUSTLS" != xno; then dnl don't need any. LIBS="$SSL_LIBS $LIBS" ssl_msg="rustls" - AC_DEFINE(USE_RUSTLS, 1, [if rustls is enabled]) + AC_DEFINE(USE_RUSTLS, 1, [if Rustls is enabled]) AC_SUBST(USE_RUSTLS, [1]) USE_RUSTLS="yes" RUSTLS_ENABLED=1 test rustls != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes else - AC_MSG_ERROR([pkg-config: Could not find rustls]) + AC_MSG_ERROR([pkg-config: Could not find Rustls]) fi else dnl we did not use pkg-config, so we need to add the - dnl rustls lib to LIBS + dnl Rustls lib to LIBS LIBS="-lrustls -lpthread -ldl -lm $LIBS" fi @@ -158,7 +158,7 @@ if test "x$OPT_RUSTLS" != xno; then LDFLAGS="$CLAN_LDFLAGS $SSL_LDFLAGS" if test "x$USE_RUSTLS" = "xyes"; then - AC_MSG_NOTICE([detected rustls]) + AC_MSG_NOTICE([detected Rustls]) check_for_ca_bundle=1 if test -n "$LIB_RUSTLS"; then @@ -186,5 +186,4 @@ if test "x$OPT_RUSTLS" != xno; then fi ]) - RUSTLS_ENABLED diff --git a/m4/curl-sysconfig.m4 b/m4/curl-sysconfig.m4 index f92fc1899..7da71346c 100644 --- a/m4/curl-sysconfig.m4 +++ b/m4/curl-sysconfig.m4 @@ -28,14 +28,14 @@ case $host_os in darwin*) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ -#include -#include + #include + #include ]],[[ -#if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) - return 0; -#else -#error Not macOS -#endif + #if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) + return 0; + #else + #error Not macOS + #endif ]]) ],[ build_for_macos="yes" diff --git a/m4/curl-wolfssl.m4 b/m4/curl-wolfssl.m4 index cb3dc2902..b3f65ceef 100644 --- a/m4/curl-wolfssl.m4 +++ b/m4/curl-wolfssl.m4 @@ -80,8 +80,8 @@ if test "x$OPT_WOLFSSL" != xno; then LDFLAGS="$LDFLAGS $addld" AC_MSG_NOTICE([Add $addld to LDFLAGS]) if test "$addcflags" != "-I/usr/include"; then - CPPFLAGS="$CPPFLAGS $addcflags" - AC_MSG_NOTICE([Add $addcflags to CPPFLAGS]) + CPPFLAGS="$CPPFLAGS $addcflags" + AC_MSG_NOTICE([Add $addcflags to CPPFLAGS]) fi my_ac_save_LIBS="$LIBS" @@ -101,21 +101,21 @@ if test "x$OPT_WOLFSSL" != xno; then return wolfSSL_Init(); ]]) ],[ - AC_MSG_RESULT(yes) - AC_DEFINE(USE_WOLFSSL, 1, [if wolfSSL is enabled]) - AC_SUBST(USE_WOLFSSL, [1]) - WOLFSSL_ENABLED=1 - USE_WOLFSSL="yes" - ssl_msg="wolfSSL" - QUIC_ENABLED=yes - test wolfssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes - ], - [ - AC_MSG_RESULT(no) - CPPFLAGS=$_cppflags - LDFLAGS=$_ldflags - wolfssllibpath="" - ]) + AC_MSG_RESULT(yes) + AC_DEFINE(USE_WOLFSSL, 1, [if wolfSSL is enabled]) + AC_SUBST(USE_WOLFSSL, [1]) + WOLFSSL_ENABLED=1 + USE_WOLFSSL="yes" + ssl_msg="wolfSSL" + QUIC_ENABLED=yes + test wolfssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes + ], + [ + AC_MSG_RESULT(no) + CPPFLAGS=$_cppflags + LDFLAGS=$_ldflags + wolfssllibpath="" + ]) LIBS="$my_ac_save_LIBS" fi @@ -138,18 +138,18 @@ if test "x$OPT_WOLFSSL" != xno; then dnl OpenSSL API root as well AC_CHECK_FUNC(wolfSSL_DES_ecb_encrypt, [ - AC_DEFINE(HAVE_WOLFSSL_DES_ECB_ENCRYPT, 1, - [if you have wolfSSL_DES_ecb_encrypt]) - WOLFSSL_NTLM=1 + AC_DEFINE(HAVE_WOLFSSL_DES_ECB_ENCRYPT, 1, + [if you have wolfSSL_DES_ecb_encrypt]) + WOLFSSL_NTLM=1 ] ) dnl if this symbol is present, we can make use of BIO filter chains AC_CHECK_FUNC(wolfSSL_BIO_set_shutdown, [ - AC_DEFINE(HAVE_WOLFSSL_FULL_BIO, 1, - [if you have wolfSSL_BIO_set_shutdown]) - WOLFSSL_FULL_BIO=1 + AC_DEFINE(HAVE_WOLFSSL_FULL_BIO, 1, + [if you have wolfSSL_BIO_set_shutdown]) + WOLFSSL_FULL_BIO=1 ] ) @@ -166,7 +166,7 @@ if test "x$OPT_WOLFSSL" != xno; then fi LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE wolfssl" else - AC_MSG_ERROR([--with-wolfssl but wolfSSL was not found or doesn't work]) + AC_MSG_ERROR([--with-wolfssl but wolfSSL was not found or doesn't work]) fi fi dnl wolfSSL not disabled diff --git a/m4/xc-val-flgs.m4 b/m4/xc-val-flgs.m4 index af7a3d2d8..e2225c2e5 100644 --- a/m4/xc-val-flgs.m4 +++ b/m4/xc-val-flgs.m4 @@ -211,7 +211,7 @@ AC_DEFUN([XC_CHECK_USER_FLAGS], [ test $xc_bad_var_cflags = yes || test $xc_bad_var_ldflags = yes || test $xc_bad_var_cppflags = yes; then - AC_MSG_ERROR([Can not continue. Fix errors mentioned immediately above this line.]) + AC_MSG_ERROR([Can not continue. Fix errors mentioned immediately above this line.]) fi ]) @@ -239,6 +239,6 @@ AC_DEFUN([XC_CHECK_BUILD_FLAGS], [ test $xc_bad_var_cflags = yes || test $xc_bad_var_ldflags = yes || test $xc_bad_var_cppflags = yes; then - AC_MSG_WARN([Continuing even with errors mentioned immediately above this line.]) + AC_MSG_WARN([Continuing even with errors mentioned immediately above this line.]) fi ]) diff --git a/packages/Makefile.in b/packages/Makefile.in index bf43b8db8..329dec0cc 100644 --- a/packages/Makefile.in +++ b/packages/Makefile.in @@ -222,11 +222,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -272,7 +272,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -288,8 +287,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -322,10 +323,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -336,6 +335,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -344,6 +344,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/packages/OS400/make-tests.sh b/packages/OS400/make-tests.sh index 8ff64d2fb..3a2125965 100755 --- a/packages/OS400/make-tests.sh +++ b/packages/OS400/make-tests.sh @@ -139,13 +139,6 @@ build_all_programs() cd libtest || exit 1 get_make_vars Makefile.inc - # Special case: redefine chkhostname compilation parameters. - - # shellcheck disable=SC2034 - chkhostname_SOURCES=chkhostname.c - # shellcheck disable=SC2034 - chkhostname_LDADD=curl_gethostname.o - # shellcheck disable=SC2153 build_all_programs "" "${TARGETLIB}/${SRVPGM}" ) diff --git a/packages/OS400/makefile.sh b/packages/OS400/makefile.sh index fb1f14671..7f7584521 100755 --- a/packages/OS400/makefile.sh +++ b/packages/OS400/makefile.sh @@ -65,7 +65,7 @@ fi # Copy some documentation files if needed. for TEXT in "${TOPDIR}/COPYING" "${SCRIPTDIR}/README.OS400" \ - "${TOPDIR}/CHANGES" "${TOPDIR}/docs/THANKS" "${TOPDIR}/docs/FAQ" \ + "${TOPDIR}/CHANGES.md" "${TOPDIR}/docs/THANKS" "${TOPDIR}/docs/FAQ" \ "${TOPDIR}/docs/FEATURES" "${TOPDIR}/docs/SSLCERTS.md" \ "${TOPDIR}/docs/RESOURCES" "${TOPDIR}/docs/VERSIONS.md" \ "${TOPDIR}/docs/HISTORY.md" diff --git a/packages/vms/Makefile.in b/packages/vms/Makefile.in index b25a55bfb..eb3e27bde 100644 --- a/packages/vms/Makefile.in +++ b/packages/vms/Makefile.in @@ -164,11 +164,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -214,7 +214,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -230,8 +229,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -264,10 +265,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -278,6 +277,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -286,6 +286,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/packages/vms/build_libcurl_pc.com b/packages/vms/build_libcurl_pc.com index 294ae084f..de7db2695 100644 --- a/packages/vms/build_libcurl_pc.com +++ b/packages/vms/build_libcurl_pc.com @@ -178,7 +178,7 @@ $ then $ write pco "Version: ''curl_version'" $ goto pc_file_loop $ endif -$ if f$locate("@LIBCURL_LIBS@", line_in) .lt line_in_len +$ if f$locate("@LIBCURL_PC_LIBS_PRIVATE@", line_in) .lt line_in_len $ then $ if arch_name .eqs. "VAX" $ then @@ -188,7 +188,7 @@ $ write pco "Libs.private: -lssl -lcrypto -lgssapi -lz" $ endif $ goto pc_file_loop $ endif -$ if f$locate("@CPPFLAG_CURL_STATICLIB@", line_in) .lt line_in_len +$ if f$locate("@LIBCURL_PC_CFLAGS@", line_in) .lt line_in_len $ then $ write pco "Cflags: -I${includedir} -DCURL_STATICLIB" $ goto pc_file_loop diff --git a/packages/vms/build_vms.com b/packages/vms/build_vms.com index 1b023649f..d8f89f6ef 100644 --- a/packages/vms/build_vms.com +++ b/packages/vms/build_vms.com @@ -20,10 +20,10 @@ $! $! 64 Compile with 64-bit pointers. $! Note, you must match the pointer size that the OpenSSL $! shared image expects. -$! Currently curl is not building properly with 64 bit pointers -$! on VMS because it is trying to cast pointers to 32 bit +$! Currently curl is not building properly with 64-bit pointers +$! on VMS because it is trying to cast pointers to 32-bit $! integers and some OpenVMS library routines called by curl -$! do not yet support 64 bit pointers. +$! do not yet support 64-bit pointers. $! CCQUAL=x Add "x" to the C compiler qualifiers. $! Default qualifiers are: $! /standard=relaxed @@ -638,21 +638,21 @@ $ libzshr_line = "" $ try_shr = "gnv$libzshr" $ if build_64 $ then -$! First look for 64 bit +$! First look for 64-bit $ if f$search("''try_shr'64") .eqs. "" $ then -$! Second look for the J.F. Pieronne 64 bit shared image +$! Second look for the J.F. Pieronne 64-bit shared image $ try_shr = "LIBZ_SHR64" $ if f$search(try_shr) .eqs. "" then nozlib = 1 $ endif $ else -$! First look for 32 bit +$! First look for 32-bit $ if f$search("''try_shr'32") .eqs. "" $ then -$! Second look for old 32 bit image +$! Second look for old 32-bit image $ if f$search(try_shr) .eqs. "" $ then -$! Third look for the J.F. Pieronne 32 bit shared image +$! Third look for the J.F. Pieronne 32-bit shared image $ try_shr = "LIBZ_SHR32" $ if f$search(try_shr) .eqs. "" then nozlib = 1 $ endif diff --git a/packages/vms/config_h.com b/packages/vms/config_h.com index b54a1a0f9..8d231f4c9 100644 --- a/packages/vms/config_h.com +++ b/packages/vms/config_h.com @@ -1319,7 +1319,7 @@ $ search/out=nl: 'tfile1' - $ severity = '$severity' $! $! -$! Of course the 64 bit stuff is different +$! Of course the 64-bit stuff is different $!--------------------------------------------------------- $ if severity .ne. 1 .and. key64 $ then diff --git a/packages/vms/curl_crtl_init.c b/packages/vms/curl_crtl_init.c index 6ae7e8c3a..a94fb6664 100644 --- a/packages/vms/curl_crtl_init.c +++ b/packages/vms/curl_crtl_init.c @@ -89,89 +89,87 @@ int decc$feature_set_value (int index, int mode, int value); #endif int SYS$TRNLNM( - const unsigned long * attr, - const struct dsc$descriptor_s * table_dsc, - struct dsc$descriptor_s * name_dsc, - const unsigned char * acmode, - const struct itmlst_3 * item_list); + const unsigned long *attr, + const struct dsc$descriptor_s *table_dsc, + struct dsc$descriptor_s *name_dsc, + const unsigned char *acmode, + const struct itmlst_3 *item_list); int SYS$CRELNM( - const unsigned long * attr, - const struct dsc$descriptor_s * table_dsc, - const struct dsc$descriptor_s * name_dsc, - const unsigned char * acmode, - const struct itmlst_3 * item_list); + const unsigned long *attr, + const struct dsc$descriptor_s *table_dsc, + const struct dsc$descriptor_s *name_dsc, + const unsigned char *acmode, + const struct itmlst_3 *item_list); /* Take all the fun out of simply looking up a logical name */ -static int sys_trnlnm - (const char * logname, - char * value, - int value_len) +static int sys_trnlnm(const char *logname, + char *value, + int value_len) { - const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV"); - const unsigned long attr = LNM$M_CASE_BLIND; - struct dsc$descriptor_s name_dsc; - int status; - unsigned short result; - struct itmlst_3 itlst[2]; + const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV"); + const unsigned long attr = LNM$M_CASE_BLIND; + struct dsc$descriptor_s name_dsc; + int status; + unsigned short result; + struct itmlst_3 itlst[2]; - itlst[0].buflen = value_len; - itlst[0].itmcode = LNM$_STRING; - itlst[0].bufadr = value; - itlst[0].retlen = &result; + itlst[0].buflen = value_len; + itlst[0].itmcode = LNM$_STRING; + itlst[0].bufadr = value; + itlst[0].retlen = &result; - itlst[1].buflen = 0; - itlst[1].itmcode = 0; + itlst[1].buflen = 0; + itlst[1].itmcode = 0; - name_dsc.dsc$w_length = strlen(logname); - name_dsc.dsc$a_pointer = (char *)logname; - name_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - name_dsc.dsc$b_class = DSC$K_CLASS_S; + name_dsc.dsc$w_length = strlen(logname); + name_dsc.dsc$a_pointer = (char *)logname; + name_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + name_dsc.dsc$b_class = DSC$K_CLASS_S; - status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst); + status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst); - if($VMS_STATUS_SUCCESS(status)) { + if($VMS_STATUS_SUCCESS(status)) { - /* Null terminate and return the string */ - /*--------------------------------------*/ - value[result] = '\0'; - } + /* Null terminate and return the string */ + /*--------------------------------------*/ + value[result] = '\0'; + } - return status; + return status; } /* How to simply create a logical name */ -static int sys_crelnm - (const char * logname, - const char * value) +static int sys_crelnm(const char *logname, + const char *value) { - int ret_val; - const char * proc_table = "LNM$PROCESS_TABLE"; - struct dsc$descriptor_s proc_table_dsc; - struct dsc$descriptor_s logname_dsc; - struct itmlst_3 item_list[2]; + int ret_val; + const char *proc_table = "LNM$PROCESS_TABLE"; + struct dsc$descriptor_s proc_table_dsc; + struct dsc$descriptor_s logname_dsc; + struct itmlst_3 item_list[2]; - proc_table_dsc.dsc$a_pointer = (char *) proc_table; - proc_table_dsc.dsc$w_length = strlen(proc_table); - proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - proc_table_dsc.dsc$b_class = DSC$K_CLASS_S; + proc_table_dsc.dsc$a_pointer = (char *) proc_table; + proc_table_dsc.dsc$w_length = strlen(proc_table); + proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + proc_table_dsc.dsc$b_class = DSC$K_CLASS_S; - logname_dsc.dsc$a_pointer = (char *) logname; - logname_dsc.dsc$w_length = strlen(logname); - logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - logname_dsc.dsc$b_class = DSC$K_CLASS_S; + logname_dsc.dsc$a_pointer = (char *) logname; + logname_dsc.dsc$w_length = strlen(logname); + logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + logname_dsc.dsc$b_class = DSC$K_CLASS_S; - item_list[0].buflen = strlen(value); - item_list[0].itmcode = LNM$_STRING; - item_list[0].bufadr = (char *)value; - item_list[0].retlen = NULL; + item_list[0].buflen = strlen(value); + item_list[0].itmcode = LNM$_STRING; + item_list[0].bufadr = (char *)value; + item_list[0].retlen = NULL; - item_list[1].buflen = 0; - item_list[1].itmcode = 0; + item_list[1].buflen = 0; + item_list[1].itmcode = 0; - ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list); + ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list); - return ret_val; + return ret_val; } @@ -183,111 +181,112 @@ static int sys_crelnm #ifdef __VAX static void set_feature_default(const char *name, const char *value) { - sys_crelnm(name, value); + sys_crelnm(name, value); } #else static void set_feature_default(const char *name, int value) { - int index; + int index; - index = decc$feature_get_index(name); + index = decc$feature_get_index(name); - if(index > 0) - decc$feature_set_value (index, 0, value); + if(index > 0) + decc$feature_set_value (index, 0, value); } #endif static void set_features(void) { - int status; - char unix_shell_name[255]; - int use_unix_settings = 1; + int status; + char unix_shell_name[255]; + int use_unix_settings = 1; - status = sys_trnlnm("GNV$UNIX_SHELL", - unix_shell_name, sizeof unix_shell_name -1); - if(!$VMS_STATUS_SUCCESS(status)) { - use_unix_settings = 0; - } + status = sys_trnlnm("GNV$UNIX_SHELL", + unix_shell_name, sizeof(unix_shell_name) -1); + if(!$VMS_STATUS_SUCCESS(status)) { + use_unix_settings = 0; + } - /* ACCESS should check ACLs or it is lying. */ - set_feature_default("DECC$ACL_ACCESS_CHECK", ENABLE); + /* ACCESS should check ACLs or it is lying. */ + set_feature_default("DECC$ACL_ACCESS_CHECK", ENABLE); - /* We always want the new parse style */ - set_feature_default ("DECC$ARGV_PARSE_STYLE" , ENABLE); + /* We always want the new parse style */ + set_feature_default("DECC$ARGV_PARSE_STYLE", ENABLE); - /* Unless we are in POSIX compliant mode, we want the old POSIX root - * enabled. - */ - set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE); + /* Unless we are in POSIX compliant mode, we want the old POSIX root + * enabled. + */ + set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE); - /* EFS charset, means UTF-8 support */ - /* VTF-7 support is controlled by a feature setting called UTF8 */ - set_feature_default ("DECC$EFS_CHARSET", ENABLE); - set_feature_default ("DECC$EFS_CASE_PRESERVE", ENABLE); + /* EFS charset, means UTF-8 support */ + /* VTF-7 support is controlled by a feature setting called UTF8 */ + set_feature_default("DECC$EFS_CHARSET", ENABLE); + set_feature_default("DECC$EFS_CASE_PRESERVE", ENABLE); - /* Support timestamps when available */ - set_feature_default ("DECC$EFS_FILE_TIMESTAMPS", ENABLE); + /* Support timestamps when available */ + set_feature_default("DECC$EFS_FILE_TIMESTAMPS", ENABLE); - /* Cache environment variables - performance improvements */ - set_feature_default ("DECC$ENABLE_GETENV_CACHE", ENABLE); + /* Cache environment variables - performance improvements */ + set_feature_default("DECC$ENABLE_GETENV_CACHE", ENABLE); - /* Start out with new file attribute inheritance */ + /* Start out with new file attribute inheritance */ #ifdef __VAX - set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", "2"); + set_feature_default("DECC$EXEC_FILEATTR_INHERITANCE", "2"); #else - set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", 2); + set_feature_default("DECC$EXEC_FILEATTR_INHERITANCE", 2); #endif - /* Don't display trailing dot after files without type */ - set_feature_default ("DECC$READDIR_DROPDOTNOTYPE", ENABLE); + /* Don't display trailing dot after files without type */ + set_feature_default("DECC$READDIR_DROPDOTNOTYPE", ENABLE); - /* For standard output channels buffer output until terminator */ - /* Gets rid of output logs with single character lines in them. */ - set_feature_default ("DECC$STDIO_CTX_EOL", ENABLE); + /* For standard output channels buffer output until terminator */ + /* Gets rid of output logs with single character lines in them. */ + set_feature_default("DECC$STDIO_CTX_EOL", ENABLE); - /* Fix mv aa.bb aa */ - set_feature_default ("DECC$RENAME_NO_INHERIT", ENABLE); + /* Fix mv aa.bb aa */ + set_feature_default("DECC$RENAME_NO_INHERIT", ENABLE); - if(use_unix_settings) { + if(use_unix_settings) { - /* POSIX requires that open files be able to be removed */ - set_feature_default ("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE); + /* POSIX requires that open files be able to be removed */ + set_feature_default("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE); - /* Default to outputting Unix filenames in VMS routines */ - set_feature_default ("DECC$FILENAME_UNIX_ONLY", ENABLE); - /* FILENAME_UNIX_ONLY Implicitly sets */ - /* decc$disable_to_vms_logname_translation */ + /* Default to outputting Unix filenames in VMS routines */ + set_feature_default("DECC$FILENAME_UNIX_ONLY", ENABLE); + /* FILENAME_UNIX_ONLY Implicitly sets */ + /* decc$disable_to_vms_logname_translation */ - set_feature_default ("DECC$FILE_PERMISSION_UNIX", ENABLE); + set_feature_default("DECC$FILE_PERMISSION_UNIX", ENABLE); - set_feature_default ("DECC$FILE_SHARING", ENABLE); + set_feature_default("DECC$FILE_SHARING", ENABLE); - set_feature_default ("DECC$FILE_OWNER_UNIX", ENABLE); - set_feature_default ("DECC$POSIX_SEEK_STREAM_FILE", ENABLE); + set_feature_default("DECC$FILE_OWNER_UNIX", ENABLE); + set_feature_default("DECC$POSIX_SEEK_STREAM_FILE", ENABLE); - } else { - set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE); - } + } + else { + set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE); + } - /* When reporting Unix filenames, glob the same way */ - set_feature_default ("DECC$GLOB_UNIX_STYLE", ENABLE); + /* When reporting Unix filenames, glob the same way */ + set_feature_default("DECC$GLOB_UNIX_STYLE", ENABLE); - /* The VMS version numbers on Unix filenames is incompatible with most */ - /* ported packages. */ - set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE); + /* The VMS version numbers on Unix filenames is incompatible with most */ + /* ported packages. */ + set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE); - /* The VMS version numbers on Unix filenames is incompatible with most */ - /* ported packages. */ - set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE); + /* The VMS version numbers on Unix filenames is incompatible with most */ + /* ported packages. */ + set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE); - /* Set strtol to proper behavior */ - set_feature_default("DECC$STRTOL_ERANGE", ENABLE); + /* Set strtol to proper behavior */ + set_feature_default("DECC$STRTOL_ERANGE", ENABLE); - /* Commented here to prevent future bugs: A program or user should */ - /* never ever enable DECC$POSIX_STYLE_UID. */ - /* It will probably break all code that accesses UIDs */ - /* do_not_set_default ("DECC$POSIX_STYLE_UID", TRUE); */ + /* Commented here to prevent future bugs: A program or user should */ + /* never ever enable DECC$POSIX_STYLE_UID. */ + /* It will probably break all code that accesses UIDs */ + /* do_not_set_default ("DECC$POSIX_STYLE_UID", TRUE); */ } @@ -308,7 +307,7 @@ static void set_features(void) # endif #endif /* Set our contribution to the LIB$INITIALIZE array */ -void (* const iniarray[])(void) = {set_features, } ; +void (* const iniarray[])(void) = {set_features }; #ifndef __VAX # if __INITIAL_POINTER_SIZE # pragma __pointer_size __restore diff --git a/packages/vms/gnv_link_curl.com b/packages/vms/gnv_link_curl.com index 552d7d45d..2acd49a6a 100644 --- a/packages/vms/gnv_link_curl.com +++ b/packages/vms/gnv_link_curl.com @@ -123,7 +123,7 @@ $ endif $ endif $! $! Create the a new option file with special fixup for HP SSL -$! For a shared image, we always want ZLIB and 32 bit HPSSL +$! For a shared image, we always want ZLIB and 32-bit HPSSL $! $ if f$search("gnv$libzshr32") .eqs. "" $ then diff --git a/packages/vms/readme b/packages/vms/readme index eaf23e942..042a22b80 100644 --- a/packages/vms/readme +++ b/packages/vms/readme @@ -173,7 +173,7 @@ the GNV tool kit, building a shared libcurl, and producing a PCSI kit for distribution. The curl_gnv_build_steps.text is included in the release notes file of the PCSI kit. -The building with 64 bit pointers does not currently work. +The building with 64-bit pointers does not currently work. The build procedure will detect if HP OpenSSL, LDAP, and Kerberos are installed and default to building with them. diff --git a/packages/vms/report_openssl_version.c b/packages/vms/report_openssl_version.c index 158303011..d08fe713b 100644 --- a/packages/vms/report_openssl_version.c +++ b/packages/vms/report_openssl_version.c @@ -36,65 +36,64 @@ #include unsigned long LIB$SET_SYMBOL( - const struct dsc$descriptor_s * symbol, - const struct dsc$descriptor_s * value, - const unsigned long * table_type); - -int main(int argc, char ** argv) { - - -void * libptr; -const char * (*ssl_version)(int t); -const char * version; - - if(argc < 1) { - puts("report_openssl_version filename"); - exit(1); - } - - libptr = dlopen(argv[1], 0); - - ssl_version = (const char * (*)(int))dlsym(libptr, "SSLeay_version"); - if(ssl_version == NULL) { - ssl_version = (const char * (*)(int))dlsym(libptr, "ssleay_version"); - if(ssl_version == NULL) { - ssl_version = (const char * (*)(int))dlsym(libptr, "SSLEAY_VERSION"); - } - } - - dlclose(libptr); - - if(ssl_version == NULL) { - puts("Unable to lookup version of OpenSSL"); - exit(1); - } - - version = ssl_version(SSLEAY_VERSION); - - puts(version); - - /* Was a symbol argument given? */ - if(argc > 1) { - int status; - struct dsc$descriptor_s symbol_dsc; - struct dsc$descriptor_s value_dsc; - const unsigned long table_type = LIB$K_CLI_LOCAL_SYM; - - symbol_dsc.dsc$a_pointer = argv[2]; - symbol_dsc.dsc$w_length = strlen(argv[2]); - symbol_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - symbol_dsc.dsc$b_class = DSC$K_CLASS_S; - - value_dsc.dsc$a_pointer = (char *)version; /* Cast ok */ - value_dsc.dsc$w_length = strlen(version); - value_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - value_dsc.dsc$b_class = DSC$K_CLASS_S; - - status = LIB$SET_SYMBOL(&symbol_dsc, &value_dsc, &table_type); - if(!$VMS_STATUS_SUCCESS(status)) { - exit(status); - } - } - - exit(0); + const struct dsc$descriptor_s * symbol, + const struct dsc$descriptor_s * value, + const unsigned long *table_type); + +int main(int argc, char **argv) +{ + void *libptr; + const char * (*ssl_version)(int t); + const char *version; + + if(argc < 1) { + puts("report_openssl_version filename"); + exit(1); + } + + libptr = dlopen(argv[1], 0); + + ssl_version = (const char * (*)(int))dlsym(libptr, "SSLeay_version"); + if(!ssl_version) { + ssl_version = (const char * (*)(int))dlsym(libptr, "ssleay_version"); + if(!ssl_version) { + ssl_version = (const char * (*)(int))dlsym(libptr, "SSLEAY_VERSION"); + } + } + + dlclose(libptr); + + if(!ssl_version) { + puts("Unable to lookup version of OpenSSL"); + exit(1); + } + + version = ssl_version(SSLEAY_VERSION); + + puts(version); + + /* Was a symbol argument given? */ + if(argc > 1) { + int status; + struct dsc$descriptor_s symbol_dsc; + struct dsc$descriptor_s value_dsc; + const unsigned long table_type = LIB$K_CLI_LOCAL_SYM; + + symbol_dsc.dsc$a_pointer = argv[2]; + symbol_dsc.dsc$w_length = strlen(argv[2]); + symbol_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + symbol_dsc.dsc$b_class = DSC$K_CLASS_S; + + value_dsc.dsc$a_pointer = (char *)version; /* Cast ok */ + value_dsc.dsc$w_length = strlen(version); + value_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + value_dsc.dsc$b_class = DSC$K_CLASS_S; + + status = LIB$SET_SYMBOL(&symbol_dsc, &value_dsc, &table_type); + if(!$VMS_STATUS_SUCCESS(status)) { + exit(status); + } + } + + exit(0); } diff --git a/packages/vms/setup_gnv_curl_build.com b/packages/vms/setup_gnv_curl_build.com index 1685b6a2f..49882463f 100644 --- a/packages/vms/setup_gnv_curl_build.com +++ b/packages/vms/setup_gnv_curl_build.com @@ -66,9 +66,9 @@ $! Set the compiler options for GNV CC wrapper to inherit. $ cc :== cc'clist''cnames'/nested_include_directory=none $ cxx :== cxx'clist''cnames'/nested_include_directory=none $ pointer_size = "32" -$! Note 64 bit pointers requires all libraries to either have -$! 64 bit pointers or have #pragma directives. -$! Currently building curl on VMS with 64 bit pointers does not work. +$! Note 64-bit pointers requires all libraries to either have +$! 64-bit pointers or have #pragma directives. +$! Currently building curl on VMS with 64-bit pointers does not work. $! $! A logical name to make it easier to find some of the hacks. $ define/job gnv_hacks 'base_dir' diff --git a/projects/checksrc.bat b/projects/checksrc.bat index af0ff1ee4..b80d771e1 100644 --- a/projects/checksrc.bat +++ b/projects/checksrc.bat @@ -115,7 +115,7 @@ rem *************************************************************************** if "%CHECK_SRC%" == "TRUE" ( rem Check the src directory if exist %SRC_DIR%\src ( - for /f "delims=" %%i in ('dir "%SRC_DIR%\src\*.c.*" /b 2^>NUL') do @perl "%SRC_DIR%\scripts\checksrc.pl" "-D%SRC_DIR%\src" -Wtool_hugehelp.c "%%i" + for /f "delims=" %%i in ('dir "%SRC_DIR%\src\*.c.*" /b 2^>NUL') do @perl "%SRC_DIR%\scripts\checksrc.pl" "-D%SRC_DIR%\src" -Wtool_ca_embed.c -Wtool_hugehelp.c "%%i" for /f "delims=" %%i in ('dir "%SRC_DIR%\src\*.h.*" /b 2^>NUL') do @perl "%SRC_DIR%\scripts\checksrc.pl" "-D%SRC_DIR%\src" "%%i" ) ) diff --git a/projects/wolfssl_options.h b/projects/wolfssl_options.h index 3ef23fbcd..ebc35d851 100644 --- a/projects/wolfssl_options.h +++ b/projects/wolfssl_options.h @@ -29,7 +29,7 @@ build-wolfssl will copy to the wolfSSL include directories and will result in maximum compatibility. These are the configure options that were used to build wolfSSL v5.1.1 in -mingw and generate the options in this file: +MinGW and generate the options in this file: C_EXTRA_FLAGS="\ -Wno-attributes \ @@ -75,7 +75,7 @@ create the thread local storage and that could be a problem for LoadLibrary. Regarding the options that were added via C_EXTRA_FLAGS: FP_MAX_BITS=16384 -https://www.yassl.com/forums/topic423-cacertorgs-ca-cert-verify-failed-but-withdisablefastmath-it-works.html +https://www.wolfssl.com/documentation/manuals/wolfssl/chapter02.html "Since root.crt uses a 4096-bit RSA key, you'll need to increase the fastmath buffer size. You can do this using the define: FP_MAX_BITS and setting it to 8192." diff --git a/projects/wolfssl_override.props b/projects/wolfssl_override.props index fab60f3c9..b81ba13d9 100644 --- a/projects/wolfssl_override.props +++ b/projects/wolfssl_override.props @@ -16,7 +16,7 @@ file by using the CustomAfterMicrosoftCommonTargets property. --> $(SolutionDir)\wolfssl\options.h;%(ForcedIncludeFiles); _UNICODE;UNICODE;WOLFSSL_USER_SETTINGS;CYASSL_USER_SETTINGS;%(UndefinePreprocessorDefinitions); diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 772c7bd8d..546041074 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = coverage.sh completion.pl firefox-db2pem.sh checksrc.pl \ mk-ca-bundle.pl schemetable.c cd2nroff nroff2cd cdall cd2cd managen \ - dmaketgz + dmaketgz maketgz release-tools.sh verify-release cmakelint.sh ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ diff --git a/scripts/Makefile.in b/scripts/Makefile.in index a89ada3d2..07d12e1a3 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -188,11 +188,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -238,7 +238,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -254,8 +253,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -288,10 +289,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -302,6 +301,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -310,6 +310,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -395,7 +396,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = coverage.sh completion.pl firefox-db2pem.sh checksrc.pl \ mk-ca-bundle.pl schemetable.c cd2nroff nroff2cd cdall cd2cd managen \ - dmaketgz + dmaketgz maketgz release-tools.sh verify-release cmakelint.sh @USE_ZSH_COMPLETION_TRUE@ZSH_COMPLETION_FUNCTION_FILENAME = _curl @USE_FISH_COMPLETION_TRUE@FISH_COMPLETION_FUNCTION_FILENAME = curl.fish diff --git a/scripts/cd2nroff b/scripts/cd2nroff index 00b2cc05e..d5ebecd75 100755 --- a/scripts/cd2nroff +++ b/scripts/cd2nroff @@ -304,7 +304,7 @@ sub single { print STDERR "$f:$line:1:ERROR: no 'Source:' in $f\n"; return 2; } - if(!$addedin) { + if(($source eq "libcurl") && !$addedin) { print STDERR "$f:$line:1:ERROR: no 'Added-in:' in $f\n"; return 2; } diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 75f68fbaa..2316268df 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -50,6 +50,7 @@ my %warnings_extended = ( 'COPYRIGHTYEAR' => 'copyright year incorrect', 'STRERROR', => 'strerror() detected', + 'STRNCPY', => 'strncpy() detected', 'STDERR', => 'stderr detected', ); @@ -115,9 +116,20 @@ sub readskiplist { # and since that's already handled via !checksrc! commands there is probably # little use to add it. sub readlocalfile { + my ($file) = @_; my $i = 0; + my $rcfile; - open(my $rcfile, "<", "$dir/.checksrc") or return; + if(($dir eq ".") && $file =~ /\//) { + my $ldir; + if($file =~ /(.*)\//) { + $ldir = $1; + open($rcfile, "<", "$dir/$ldir/.checksrc") or return; + } + } + else { + open($rcfile, "<", "$dir/.checksrc") or return; + } while(<$rcfile>) { $windows_os ? $_ =~ s/\r?\n$// : chomp; @@ -264,7 +276,7 @@ sub checkwarn { } readskiplist(); -readlocalfile(); +readlocalfile($file); do { if("$wlist" !~ / $file /) { @@ -740,6 +752,18 @@ sub scanfile { } } } + if($warnings{"STRNCPY"}) { + # scan for use of banned strncpy. This is not a BANNEDFUNC to + # allow for individual enable/disable of this warning. + if($l =~ /^(.*\W)(strncpy)\s*\(/x) { + if($1 !~ /^ *\#/) { + # skip preprocessor lines + checkwarn("STRNCPY", + $line, length($1), $file, $ol, + "use of $2 is banned"); + } + } + } if($warnings{"STDERR"}) { # scan for use of banned stderr. This is not a BANNEDFUNC to # allow for individual enable/disable of this warning. diff --git a/scripts/cmakelint.sh b/scripts/cmakelint.sh new file mode 100644 index 000000000..4eb54e145 --- /dev/null +++ b/scripts/cmakelint.sh @@ -0,0 +1,50 @@ +#!/bin/sh +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Dan Fandrich, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +# Run cmakelint on the curl source code. It will check all files given on the +# command-line, or else all relevant files in git, or if not in a git +# repository, all files starting in the tree rooted in the current directory. +# +# cmakelint can be installed from PyPi with the command "python3 -m pip install +# cmakelint". +# +# The xargs invocation is portable, but does not preserve spaces in file names. +# If such a file is ever added, then this can be portably fixed by switching to +# "xargs -I{}" and appending {} to the end of the xargs arguments (which will +# call cmakelint once per file) or by using the GNU extension "xargs -d'\n'". +{ + if [ -n "$1" ]; then + for A in "$@"; do printf "%s\n" "$A"; done + elif git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + git ls-files + else + # strip off the leading ./ to make the grep regexes work properly + find . -type f | sed 's@^\./@@' + fi +} | grep -E '(/CMake|\.cmake$)' | grep -v -E '(\.h\.cmake|\.in)$' \ + | xargs \ + cmakelint \ + --spaces=2 --linelength=132 \ + --filter=-whitespace/indent,-convention/filename,-package/stdargs diff --git a/scripts/dmaketgz b/scripts/dmaketgz index 25874793b..e58544275 100644 --- a/scripts/dmaketgz +++ b/scripts/dmaketgz @@ -30,23 +30,25 @@ set -eu version="${1:-}" if [ -z "$version" ]; then - echo "Specify a version number!" - exit + echo "Specify a version number!" + exit fi timestamp="${2:-$(date -u +%s)}" -make distclean +if test -f Makefile; then + make distclean +fi docker build \ --build-arg SOURCE_DATE_EPOCH="$timestamp" \ --build-arg UID="$(id -u)" \ --build-arg GID="$(id -g)" \ -t curl/curl . -docker run --rm -it -u "$(id -u):$(id -g)" \ +docker run --rm -u "$(id -u):$(id -g)" \ -v "$(pwd):/usr/src" -w /usr/src curl/curl sh -c " set -e autoreconf -fi ./configure --without-ssl --without-libpsl make -sj8 - ./maketgz $version" + ./scripts/maketgz $version" diff --git a/scripts/firefox-db2pem.sh b/scripts/firefox-db2pem.sh index a45a881db..57252b405 100755 --- a/scripts/firefox-db2pem.sh +++ b/scripts/firefox-db2pem.sh @@ -26,6 +26,9 @@ # It extracts all ca certs it finds in the local Firefox database and converts # them all into PEM format. # +# It uses the "certutil" command line tool from the NSS project to perform the +# conversion. On Debian it comes in the "libnss3-tools" package. +# set -eu diff --git a/maketgz b/scripts/maketgz old mode 100755 new mode 100644 similarity index 90% rename from maketgz rename to scripts/maketgz index 0492371a9..af62708bc --- a/maketgz +++ b/scripts/maketgz @@ -1,6 +1,6 @@ #!/bin/sh # Script to build release-archives with. Note that this requires a checkout -# from git and you should first run ./buildconf and build curl once. +# from git and you should first run autoreconf -fi and build curl once. # #*************************************************************************** # _ _ ____ _ @@ -32,17 +32,24 @@ export LC_ALL=C export TZ=UTC version="${1:-}" +cmd="${2:-}" if [ -z "$version" ]; then echo "Specify a version number!" exit fi -if [ "only" = "${2:-}" ]; then +echo "$cmd" + +only="" +if [ "only" = "$cmd" ]; then echo "Setup version number only!" only=1 -else - only= +fi + +commit="" +if [ "commit" = "$cmd" ]; then + commit=1 fi libversion="$version" @@ -87,7 +94,7 @@ datestamp=$(date -d "@$timestamp" +"%F") filestamp=$(date -d "@$timestamp" +"%Y%m%d%H%M.%S") # Replace version number in header file: -sed -i.bak \ +sed -i \ -e "s/^#define LIBCURL_VERSION .*/#define LIBCURL_VERSION \"$libversion\"/g" \ -e "s/^#define LIBCURL_VERSION_NUM .*/#define LIBCURL_VERSION_NUM 0x$numeric/g" \ -e "s/^#define LIBCURL_VERSION_MAJOR .*/#define LIBCURL_VERSION_MAJOR $major/g" \ @@ -95,11 +102,9 @@ sed -i.bak \ -e "s/^#define LIBCURL_VERSION_PATCH .*/#define LIBCURL_VERSION_PATCH $patch/g" \ -e "s/^#define LIBCURL_TIMESTAMP .*/#define LIBCURL_TIMESTAMP \"$datestamp\"/g" \ "$HEADER" -rm -f "$HEADER.bak" # Replace version number in header file: -sed -i.bak "s/#define CURL_VERSION .*/#define CURL_VERSION \"$curlversion\"/g" "$CHEADER" -rm -f "$CHEADER.bak" +sed -i "s/#define CURL_VERSION .*/#define CURL_VERSION \"$curlversion\"/g" "$CHEADER" if test -n "$only"; then # done! @@ -133,6 +138,11 @@ findprog() { echo "Re-running config.status" ./config.status --recheck >/dev/null +echo "Recreate the built-in manual (with correct version)" +export CURL_MAKETGZ_VERSION="$version" +rm -f docs/cmdline-opts/curl.txt +make -C src + ############################################################################ # # automake is needed to run to make a non-GNU Makefile.in if Makefile.am has @@ -146,11 +156,13 @@ else automake --include-deps Makefile >/dev/null fi -echo "produce CHANGES" -git log --pretty=fuller --no-color --date=short --decorate=full -1000 | ./scripts/log2changes.pl > CHANGES.dist +if test -n "$commit"; then + echo "produce docs/tarball-commit.txt" + git rev-parse HEAD >docs/tarball-commit.txt.dist +fi echo "produce RELEASE-TOOLS.md" -./scripts/release-tools.sh "$timestamp" "$version" > docs/RELEASE-TOOLS.md.dist +./scripts/release-tools.sh "$timestamp" "$version" "$commit" > docs/RELEASE-TOOLS.md.dist ############################################################################ # diff --git a/scripts/managen b/scripts/managen index 7cdb65817..df7663cd3 100755 --- a/scripts/managen +++ b/scripts/managen @@ -58,7 +58,7 @@ my $date = strftime "%Y-%m-%d", @ts; my $year = strftime "%Y", @ts; my $version = "unknown"; my $globals; - +my $error = 0; my $indent = 4; # get the long name version, return the manpage string @@ -127,7 +127,8 @@ sub justline { sub lastline { my ($lvl, @line) = @_; - prefixline($lvl * $indent); + $line[0] =~ s/^( +)//; + prefixline($lvl * $indent + length($1)); my $prev = 0; for(@line) { printf "%s%s", $prev?" ":"", $_; @@ -193,6 +194,12 @@ sub printdesc { # quoted, do not right-justify chomp $l; lastline($baselvl + $lvl + 1, $l); + my $w = ($baselvl + $lvl + 1) * $indent + length($l); + if ($w > $colwidth) { + print STDERR "ERROR: $w columns is too long\n"; + print STDERR "$l\n"; + $error++; + } } else { $para .= $l; @@ -367,7 +374,9 @@ sub render { elsif($d =~ /^ (.*)/) { my $word = $1; if(!$quote && $manpage) { + push @desc, "\n" if($blankline); push @desc, ".nf\n"; + $blankline = 0; } $quote = 1; $d = "$word\n"; @@ -465,6 +474,20 @@ sub render { return @desc; } +sub maybespace { + my ($string) = @_; + + if(($string =~ /(.* )(.*)/) && + (length($2) <= 20)) { + return $1; + } + if(($string =~ /(.*:)(.*)/) && + (length($2) <= 20)) { + return $1; + } + return $string; +} + sub single { my ($dir, $manpage, $f, $standalone)=@_; my $fh; @@ -780,16 +803,44 @@ sub single { $e =~ s!\$URL!https://example.com!g; # convert single backslahes to doubles $e =~ s/\\/\\\\/g; - print " curl $e\n"; + print "curl $e\n"; } print ".fi\n"; } else { my @ex; push @ex, "[0q]Example$s:\n"; + # + # long ASCII examples are wrapped. Preferably at the last space + # before the margin. Or at a colon. Otherwise it just cuts at the + # exact boundary. + # foreach my $e (@examples) { $e =~ s!\$URL!https://example.com!g; - push @ex, "[0q] curl $e\n"; + my $maxwidth = 60; # plus the " curl " 18 col prefix + if(length($e) > $maxwidth) { + # a long example, shorten it + my $p = substr($e, 0, $maxwidth); + $p = maybespace($p); + push @ex, "[0q] curl ".$p."\\"; + $e = substr($e, length($p)); + do { + my $r = substr($e, 0, $maxwidth); + if(length($e) > $maxwidth) { + $r = maybespace($r); + } + my $slash =""; + $e = substr($e, length($r)); + if(length($e) > 0) { + $slash = "\\"; + } + + push @ex, "[0q] $r$slash" if($r); + } while(length($e)); + } + else { + push @ex, "[0q] curl $e\n"; + } } printdesc($manpage, 2, @ex); } @@ -1205,16 +1256,24 @@ elsif($cmd eq "-c") { my @files = @ARGV; # the rest are the files -open(INC, "<$include/curl/curlver.h"); -while() { - if($_ =~ /^#define LIBCURL_VERSION \"([0-9.]*)/) { - $version = $1; - last; +# can be overriden for releases +if($ENV{'CURL_MAKETGZ_VERSION'}) { + $version = $ENV{'CURL_MAKETGZ_VERSION'}; +} +else { + open(INC, "<$include/curl/curlver.h"); + while() { + if($_ =~ /^#define LIBCURL_VERSION \"([0-9.]*)/) { + $version = $1; + last; + } } + close(INC); } -close(INC); # learn all existing options indexoptions($dir, @files); getargs($dir, $cmd, @files); + +exit $error; diff --git a/scripts/mk-ca-bundle.pl b/scripts/mk-ca-bundle.pl index 097171059..07eabbe85 100755 --- a/scripts/mk-ca-bundle.pl +++ b/scripts/mk-ca-bundle.pl @@ -408,6 +408,8 @@ (%) ## ## Certificate data from Mozilla ${datesrc}: ${currentdate} GMT ## +## Find updated versions here: https://curl.se/docs/caextract.html +## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates ## file (certdata.txt). This file can be found in the mozilla source tree: diff --git a/scripts/release-tools.sh b/scripts/release-tools.sh new file mode 100644 index 000000000..4c4ed7d80 --- /dev/null +++ b/scripts/release-tools.sh @@ -0,0 +1,79 @@ +#!/bin/sh +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +set -eu + +# this should ideally be passed in +timestamp=${1:-unknown} +version=${2:-unknown} +tag=$(echo "curl-$version" | tr '.' '_') +commit=${3} +if [ -n "$commit" ] && [ -r "docs/tarball-commit.txt.dist" ]; then + # If commit is given, then the tag likely doesn't actually exist + tag="$(cat docs/tarball-commit.txt.dist)" +fi + +cat </dev/null; then + echo "Error: could not find dpkg" >&2 + exit 1 +fi + +debian() { + echo "- $1: $(dpkg -l "$1" | grep ^ii | awk '{print $3}')" +} +debian autoconf +debian automake +debian libtool +debian make +debian perl +debian git + +cat < 4)" }, + {"smb", "#if !defined(CURL_DISABLE_SMB) && \\\n" + " defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" }, {"smbs", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \\\n" " defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" }, {"smtp", "#ifndef CURL_DISABLE_SMTP" }, @@ -112,10 +112,10 @@ static void showtable(int try, int init, int shift) printf(" static const struct Curl_handler * const protocols[%d] = {", try); /* generate table */ - for(i=0; i < try; i++) { + for(i = 0; i < try; i++) { int match = 0; int j; - for(j=0; scheme[j].n; j++) { + for(j = 0; scheme[j].n; j++) { if(ix[j] == i) { printf("\n"); printf("%s\n", scheme[j].ifdef); @@ -154,7 +154,7 @@ int main(void) unsigned int v = calc(scheme[i].n, add, shift); int j; int badcombo = 0; - for(j=0; j < i; j++) { + for(j = 0; j < i; j++) { if(num[j] == v) { /* @@ -183,9 +183,8 @@ int main(void) /* check for dupes */ for(i = 0; scheme[i].n && good; ++i) { int j; - for(j=0; j < i; j++) { + for(j = 0; j < i; j++) { if(ix[j] == ix[i]) { - /* printf("NOPE, try %u causes dupes (%d and %d)\n", try, j, i); */ good = 0; break; } diff --git a/scripts/verify-release b/scripts/verify-release new file mode 100644 index 000000000..2f7a0bf89 --- /dev/null +++ b/scripts/verify-release @@ -0,0 +1,80 @@ +#!/bin/sh + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +# This script remakes a provided curl release and verifies that the newly +# built version is identical to the original file. +# +# It is designed to be invoked in a clean directory with the path to the +# release tarball as an argument. +# + +set -eu + +tarball="${1:-}" + +if [ -z "$tarball" ]; then + echo "Provide a curl release tarball name as argument" + exit +fi + +i="0" + +# shellcheck disable=SC2034 +for dl in curl-*; do + i=$((i + 1)) +done + +if test "$i" -gt 1; then + echo "multiple curl-* entries found, disambiguate please" + exit +fi + +mkdir -p _tarballs +rm -rf _tarballs/* + +# checksum the original tarball to compare with later +sha256sum "$tarball" >_tarballs/checksum + +# extract the release contents +tar xf "$tarball" + +curlver=$(grep '#define LIBCURL_VERSION ' curl-*/include/curl/curlver.h | sed 's/[^0-9.]//g') + +echo "version $curlver" + +timestamp=$(grep -Eo 'SOURCE_DATE_EPOCH=[0-9]*' curl-"$curlver"/docs/RELEASE-TOOLS.md | cut -d= -f2) + +pwd=$(pwd) +cd "curl-$curlver" +./configure --without-ssl --without-libpsl +./scripts/dmaketgz "$curlver" "$timestamp" + +mv curl-"$curlver"* ../_tarballs/ +cd "$pwd" +cd "_tarballs" + +# compare the new tarball against the original +sha256sum -c checksum diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f3019c7b..ca40bac11 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,44 +22,61 @@ # ########################################################################### set(EXE_NAME curl) -add_definitions(-DBUILDING_CURL) +add_definitions("-DBUILDING_CURL") if(ENABLE_CURL_MANUAL AND HAVE_MANUAL_TOOLS) add_definitions("-DUSE_MANUAL") add_custom_command( - OUTPUT tool_hugehelp.c - COMMAND ${CMAKE_COMMAND} -E echo "#include \"tool_setup.h\"" > tool_hugehelp.c - COMMAND ${CMAKE_COMMAND} -E echo "#ifndef HAVE_LIBZ" >> tool_hugehelp.c - COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> tool_hugehelp.c - - COMMAND ${CMAKE_COMMAND} -E echo "#else" >> tool_hugehelp.c - COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> tool_hugehelp.c - COMMAND ${CMAKE_COMMAND} -E echo "#endif /* HAVE_LIBZ */" >> tool_hugehelp.c + OUTPUT "tool_hugehelp.c" + COMMAND ${CMAKE_COMMAND} -E echo "#include \"tool_setup.h\"" > "tool_hugehelp.c" + COMMAND ${CMAKE_COMMAND} -E echo "#ifndef HAVE_LIBZ" >> "tool_hugehelp.c" + COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" + < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> "tool_hugehelp.c" + + COMMAND ${CMAKE_COMMAND} -E echo "#else" >> "tool_hugehelp.c" + COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c + < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> "tool_hugehelp.c" + COMMAND ${CMAKE_COMMAND} -E echo "#endif /* HAVE_LIBZ */" >> "tool_hugehelp.c" DEPENDS - generate-curl.1 + "generate-curl.1" "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.1" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" "${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h" VERBATIM) else() add_custom_command( - OUTPUT tool_hugehelp.c - COMMAND ${CMAKE_COMMAND} -E echo "#include \"tool_hugehelp.h\"" > tool_hugehelp.c + OUTPUT "tool_hugehelp.c" + COMMAND ${CMAKE_COMMAND} -E echo "#include \"tool_hugehelp.h\"" > "tool_hugehelp.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h" VERBATIM) - endif() +# Get 'CURL_CFILES', 'CURLX_CFILES', 'CURL_HFILES', 'CURLTOOL_LIBCURL_CFILES' variables transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +if(CURL_CA_EMBED_SET) + if(PERL_FOUND) + add_definitions("-DCURL_CA_EMBED") + add_custom_command( + OUTPUT "tool_ca_embed.c" + COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mk-file-embed.pl" --var curl_ca_embed + < "${CURL_CA_EMBED}" > "tool_ca_embed.c" + DEPENDS + "${CURL_CA_EMBED}" + "${CMAKE_CURRENT_SOURCE_DIR}/mk-file-embed.pl" + VERBATIM) + list(APPEND CURL_CFILES "tool_ca_embed.c") + else() + message(WARNING "Perl not found. Will not embed the CA bundle.") + endif() +endif() if(WIN32) - list(APPEND CURL_CFILES curl.rc) + list(APPEND CURL_CFILES "curl.rc") endif() -# CURL_CFILES, CURLX_CFILES, CURL_HFILES, CURLTOOL_LIBCURL_CFILES -# come from Makefile.inc if(BUILD_STATIC_CURL) set(CURLX_CFILES ${CURLTOOL_LIBCURL_CFILES}) endif() @@ -67,18 +84,18 @@ endif() if(ENABLE_CURLDEBUG) # We must compile this source separately to avoid memdebug.h redefinitions # applying to them. - set_source_files_properties(../lib/curl_multibyte.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) + set_source_files_properties("../lib/curl_multibyte.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) endif() add_executable( ${EXE_NAME} ${CURL_CFILES} ${CURLX_CFILES} ${CURL_HFILES} - ) +) add_executable( ${PROJECT_NAME}::${EXE_NAME} ALIAS ${EXE_NAME} - ) +) add_library( curltool # special libcurltool library just for unittests @@ -86,7 +103,7 @@ add_library( EXCLUDE_FROM_ALL ${CURL_CFILES} ${CURLTOOL_LIBCURL_CFILES} ${CURL_HFILES} ) -target_compile_definitions(curltool PUBLIC UNITTESTS CURL_STATICLIB) +target_compile_definitions(curltool PUBLIC "UNITTESTS" "CURL_STATICLIB") target_link_libraries(curltool PRIVATE ${CURL_LIBS}) if(CURL_HAS_LTO) @@ -96,7 +113,7 @@ if(CURL_HAS_LTO) endif() if(ENABLE_UNICODE AND MINGW) - target_link_libraries(${EXE_NAME} -municode) + target_link_libraries(${EXE_NAME} "-municode") endif() source_group("curlX source files" FILES ${CURLX_CFILES}) @@ -104,26 +121,19 @@ source_group("curl source files" FILES ${CURL_CFILES}) source_group("curl header files" FILES ${CURL_HFILES}) include_directories( - ${CURL_SOURCE_DIR}/lib # for "curl_setup_once.h" - ${CURL_BINARY_DIR}/lib # for "curl_config.h" - ${CURL_BINARY_DIR}/include # for "curl/curl.h" + "${CURL_BINARY_DIR}/lib" # for "curl_config.h" + "${CURL_SOURCE_DIR}/lib" # for "curl_setup.h" # This is needed as tool_hugehelp.c is generated in the binary dir - ${CURL_SOURCE_DIR}/src # for "tool_hugehelp.h" - ) + "${CURL_SOURCE_DIR}/src" # for "tool_hugehelp.h" +) # Build curl executable target_link_libraries(${EXE_NAME} ${LIB_SELECTED_FOR_EXE} ${CURL_LIBS}) ################################################################################ -#set_target_properties(${EXE_NAME} ARCHIVE_OUTPUT_DIRECTORY "blah blah blah") -#set_target_properties(${EXE_NAME} RUNTIME_OUTPUT_DIRECTORY "blah blah blah") -#set_target_properties(${EXE_NAME} LIBRARY_OUTPUT_DIRECTORY "blah blah blah") - -#include(ModuleInstall OPTIONAL) - install(TARGETS ${EXE_NAME} EXPORT ${TARGETS_EXPORT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) export(TARGETS ${EXE_NAME} - FILE ${PROJECT_BINARY_DIR}/curl-target.cmake - NAMESPACE ${PROJECT_NAME}:: + FILE "${PROJECT_BINARY_DIR}/curl-target.cmake" + NAMESPACE ${PROJECT_NAME}:: ) diff --git a/src/Makefile.am b/src/Makefile.am index 4ce83c923..c1c223b26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,6 +50,11 @@ AM_CPPFLAGS += -DCURL_STATICLIB endif AM_CPPFLAGS += -DBUILDING_CURL +AM_LDFLAGS = +if USE_UNICODE +AM_LDFLAGS += -municode +endif + include Makefile.inc # CURL_FILES comes from Makefile.inc @@ -67,11 +72,7 @@ CFLAGS += @CURL_CFLAG_EXTRAS@ # Prevent LIBS from being used for all link targets LIBS = $(BLANK_AT_MAKETIME) -if USE_EXPLICIT_LIB_DEPS -curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ -else -curl_LDADD = $(top_builddir)/lib/libcurl.la @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@ -endif +curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # if unit tests are enabled, build a static library to link them with if BUILD_UNITTESTS @@ -84,11 +85,8 @@ libcurltool_la_SOURCES = $(CURL_FILES) endif CLEANFILES = tool_hugehelp.c -# Use the C locale to ensure that only ASCII characters appear in the -# embedded text. -NROFF=env LC_ALL=C @NROFF@ @MANOPT@ 2>/dev/null # figured out by the configure script -EXTRA_DIST = mkhelp.pl \ +EXTRA_DIST = mk-file-embed.pl mkhelp.pl \ Makefile.mk curl.rc Makefile.inc CMakeLists.txt .checksrc # Use absolute directory to disable VPATH @@ -108,6 +106,7 @@ CS_ = $(CS_0) if USE_MANUAL # Here are the stuff to create a built-in manual +AM_CPPFLAGS += -DUSE_MANUAL $(ASCIIPAGE): cd $(top_builddir)/docs && $(MAKE) @@ -135,11 +134,25 @@ $(HUGE): echo '#include "tool_hugehelp.h"' >> $(HUGE) endif -# ignore tool_hugehelp.c since it is generated source code and it plays -# by slightly different rules! +CA_EMBED_CSOURCE = tool_ca_embed.c +CURL_CFILES += $(CA_EMBED_CSOURCE) +CLEANFILES += $(CA_EMBED_CSOURCE) +if CURL_CA_EMBED_SET +AM_CPPFLAGS += -DCURL_CA_EMBED +MK_FILE_EMBED = $(top_srcdir)/src/mk-file-embed.pl +$(CA_EMBED_CSOURCE): $(MK_FILE_EMBED) + $(PERL) $(MK_FILE_EMBED) --var curl_ca_embed < $(CURL_CA_EMBED) > $(CA_EMBED_CSOURCE) +else +$(CA_EMBED_CSOURCE): + echo 'extern const void *curl_ca_embed; const void *curl_ca_embed;' > $(CA_EMBED_CSOURCE) +endif + +# ignore generated C files since they play by slightly different rules! checksrc: $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \ - -W$(srcdir)/tool_hugehelp.c $(srcdir)/*.[ch]) + -W$(srcdir)/$(HUGE) \ + -W$(srcdir)/$(CA_EMBED_CSOURCE) \ + $(srcdir)/*.[ch]) if DEBUGBUILD # for debug builds, we scan the sources on all regular make invokes diff --git a/src/Makefile.in b/src/Makefile.in index 921927077..efbc0935e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -122,7 +122,12 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = curl$(EXEEXT) @USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_1 = -DCURL_STATICLIB -@HAVE_WINDRES_TRUE@am__append_2 = $(CURL_RCFILES) +@USE_UNICODE_TRUE@am__append_2 = -municode +@HAVE_WINDRES_TRUE@am__append_3 = $(CURL_RCFILES) + +# Here are the stuff to create a built-in manual +@USE_MANUAL_TRUE@am__append_4 = -DUSE_MANUAL +@CURL_CA_EMBED_SET_TRUE@am__append_5 = -DCURL_CA_EMBED subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/curl-amissl.m4 \ @@ -172,22 +177,23 @@ am__libcurltool_la_SOURCES_DIST = slist_wc.c terminal.c tool_binmode.c \ tool_paramhlp.c tool_parsecfg.c tool_progress.c tool_setopt.c \ tool_sleep.c tool_stderr.c tool_strdup.c tool_urlglob.c \ tool_util.c tool_vms.c tool_writeout.c tool_writeout_json.c \ - tool_xattr.c var.c ../lib/base64.c ../lib/curl_multibyte.c \ - ../lib/dynbuf.c ../lib/nonblock.c ../lib/strtoofft.c \ - ../lib/timediff.c ../lib/version_win32.c ../lib/warnless.c \ - slist_wc.h terminal.h tool_binmode.h tool_bname.h \ - tool_cb_dbg.h tool_cb_hdr.h tool_cb_prg.h tool_cb_rea.h \ - tool_cb_see.h tool_cb_soc.h tool_cb_wrt.h tool_cfgable.h \ - tool_dirhie.h tool_doswin.h tool_easysrc.h tool_filetime.h \ - tool_findfile.h tool_formparse.h tool_getparam.h \ - tool_getpass.h tool_help.h tool_helpers.h tool_hugehelp.h \ - tool_ipfs.h tool_libinfo.h tool_main.h tool_msgs.h \ - tool_operate.h tool_operhlp.h tool_paramhlp.h tool_parsecfg.h \ - tool_progress.h tool_sdecls.h tool_setopt.h tool_setup.h \ - tool_sleep.h tool_stderr.h tool_strdup.h tool_urlglob.h \ - tool_util.h tool_version.h tool_vms.h tool_writeout.h \ - tool_writeout_json.h tool_xattr.h var.h -am__objects_1 = libcurltool_la-slist_wc.lo libcurltool_la-terminal.lo \ + tool_xattr.c var.c tool_ca_embed.c ../lib/base64.c \ + ../lib/curl_multibyte.c ../lib/dynbuf.c ../lib/nonblock.c \ + ../lib/strtoofft.c ../lib/timediff.c ../lib/version_win32.c \ + ../lib/warnless.c slist_wc.h terminal.h tool_binmode.h \ + tool_bname.h tool_cb_dbg.h tool_cb_hdr.h tool_cb_prg.h \ + tool_cb_rea.h tool_cb_see.h tool_cb_soc.h tool_cb_wrt.h \ + tool_cfgable.h tool_dirhie.h tool_doswin.h tool_easysrc.h \ + tool_filetime.h tool_findfile.h tool_formparse.h \ + tool_getparam.h tool_getpass.h tool_help.h tool_helpers.h \ + tool_hugehelp.h tool_ipfs.h tool_libinfo.h tool_main.h \ + tool_msgs.h tool_operate.h tool_operhlp.h tool_paramhlp.h \ + tool_parsecfg.h tool_progress.h tool_sdecls.h tool_setopt.h \ + tool_setup.h tool_sleep.h tool_stderr.h tool_strdup.h \ + tool_urlglob.h tool_util.h tool_version.h tool_vms.h \ + tool_writeout.h tool_writeout_json.h tool_xattr.h var.h +am__objects_1 = libcurltool_la-tool_ca_embed.lo +am__objects_2 = libcurltool_la-slist_wc.lo libcurltool_la-terminal.lo \ libcurltool_la-tool_binmode.lo libcurltool_la-tool_bname.lo \ libcurltool_la-tool_cb_dbg.lo libcurltool_la-tool_cb_hdr.lo \ libcurltool_la-tool_cb_prg.lo libcurltool_la-tool_cb_rea.lo \ @@ -211,9 +217,10 @@ am__objects_1 = libcurltool_la-slist_wc.lo libcurltool_la-terminal.lo \ libcurltool_la-tool_util.lo libcurltool_la-tool_vms.lo \ libcurltool_la-tool_writeout.lo \ libcurltool_la-tool_writeout_json.lo \ - libcurltool_la-tool_xattr.lo libcurltool_la-var.lo + libcurltool_la-tool_xattr.lo libcurltool_la-var.lo \ + $(am__objects_1) am__dirstamp = $(am__leading_dot)dirstamp -am__objects_2 = ../lib/libcurltool_la-base64.lo \ +am__objects_3 = ../lib/libcurltool_la-base64.lo \ ../lib/libcurltool_la-curl_multibyte.lo \ ../lib/libcurltool_la-dynbuf.lo \ ../lib/libcurltool_la-nonblock.lo \ @@ -221,9 +228,9 @@ am__objects_2 = ../lib/libcurltool_la-base64.lo \ ../lib/libcurltool_la-timediff.lo \ ../lib/libcurltool_la-version_win32.lo \ ../lib/libcurltool_la-warnless.lo -am__objects_3 = -am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3) -@BUILD_UNITTESTS_TRUE@am_libcurltool_la_OBJECTS = $(am__objects_4) +am__objects_4 = +am__objects_5 = $(am__objects_2) $(am__objects_3) $(am__objects_4) +@BUILD_UNITTESTS_TRUE@am_libcurltool_la_OBJECTS = $(am__objects_5) libcurltool_la_OBJECTS = $(am_libcurltool_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -245,22 +252,24 @@ am__curl_SOURCES_DIST = slist_wc.c terminal.c tool_binmode.c \ tool_paramhlp.c tool_parsecfg.c tool_progress.c tool_setopt.c \ tool_sleep.c tool_stderr.c tool_strdup.c tool_urlglob.c \ tool_util.c tool_vms.c tool_writeout.c tool_writeout_json.c \ - tool_xattr.c var.c ../lib/base64.c ../lib/curl_multibyte.c \ - ../lib/dynbuf.c ../lib/nonblock.c ../lib/strtoofft.c \ - ../lib/timediff.c ../lib/version_win32.c ../lib/warnless.c \ - slist_wc.h terminal.h tool_binmode.h tool_bname.h \ - tool_cb_dbg.h tool_cb_hdr.h tool_cb_prg.h tool_cb_rea.h \ - tool_cb_see.h tool_cb_soc.h tool_cb_wrt.h tool_cfgable.h \ - tool_dirhie.h tool_doswin.h tool_easysrc.h tool_filetime.h \ - tool_findfile.h tool_formparse.h tool_getparam.h \ - tool_getpass.h tool_help.h tool_helpers.h tool_hugehelp.h \ - tool_ipfs.h tool_libinfo.h tool_main.h tool_msgs.h \ - tool_operate.h tool_operhlp.h tool_paramhlp.h tool_parsecfg.h \ - tool_progress.h tool_sdecls.h tool_setopt.h tool_setup.h \ - tool_sleep.h tool_stderr.h tool_strdup.h tool_urlglob.h \ - tool_util.h tool_version.h tool_vms.h tool_writeout.h \ - tool_writeout_json.h tool_xattr.h var.h curl.rc -am__objects_5 = slist_wc.$(OBJEXT) terminal.$(OBJEXT) \ + tool_xattr.c var.c tool_ca_embed.c ../lib/base64.c \ + ../lib/curl_multibyte.c ../lib/dynbuf.c ../lib/nonblock.c \ + ../lib/strtoofft.c ../lib/timediff.c ../lib/version_win32.c \ + ../lib/warnless.c slist_wc.h terminal.h tool_binmode.h \ + tool_bname.h tool_cb_dbg.h tool_cb_hdr.h tool_cb_prg.h \ + tool_cb_rea.h tool_cb_see.h tool_cb_soc.h tool_cb_wrt.h \ + tool_cfgable.h tool_dirhie.h tool_doswin.h tool_easysrc.h \ + tool_filetime.h tool_findfile.h tool_formparse.h \ + tool_getparam.h tool_getpass.h tool_help.h tool_helpers.h \ + tool_hugehelp.h tool_ipfs.h tool_libinfo.h tool_main.h \ + tool_msgs.h tool_operate.h tool_operhlp.h tool_paramhlp.h \ + tool_parsecfg.h tool_progress.h tool_sdecls.h tool_setopt.h \ + tool_setup.h tool_sleep.h tool_stderr.h tool_strdup.h \ + tool_urlglob.h tool_util.h tool_version.h tool_vms.h \ + tool_writeout.h tool_writeout_json.h tool_xattr.h var.h \ + curl.rc +am__objects_6 = tool_ca_embed.$(OBJEXT) +am__objects_7 = slist_wc.$(OBJEXT) terminal.$(OBJEXT) \ tool_binmode.$(OBJEXT) tool_bname.$(OBJEXT) \ tool_cb_dbg.$(OBJEXT) tool_cb_hdr.$(OBJEXT) \ tool_cb_prg.$(OBJEXT) tool_cb_rea.$(OBJEXT) \ @@ -280,21 +289,18 @@ am__objects_5 = slist_wc.$(OBJEXT) terminal.$(OBJEXT) \ tool_stderr.$(OBJEXT) tool_strdup.$(OBJEXT) \ tool_urlglob.$(OBJEXT) tool_util.$(OBJEXT) tool_vms.$(OBJEXT) \ tool_writeout.$(OBJEXT) tool_writeout_json.$(OBJEXT) \ - tool_xattr.$(OBJEXT) var.$(OBJEXT) -am__objects_6 = ../lib/base64.$(OBJEXT) \ + tool_xattr.$(OBJEXT) var.$(OBJEXT) $(am__objects_6) +am__objects_8 = ../lib/base64.$(OBJEXT) \ ../lib/curl_multibyte.$(OBJEXT) ../lib/dynbuf.$(OBJEXT) \ ../lib/nonblock.$(OBJEXT) ../lib/strtoofft.$(OBJEXT) \ ../lib/timediff.$(OBJEXT) ../lib/version_win32.$(OBJEXT) \ ../lib/warnless.$(OBJEXT) -am__objects_7 = $(am__objects_5) $(am__objects_6) $(am__objects_3) -am__objects_8 = curl.$(OBJEXT) -@HAVE_WINDRES_TRUE@am__objects_9 = $(am__objects_8) -am_curl_OBJECTS = $(am__objects_7) $(am__objects_9) +am__objects_9 = $(am__objects_7) $(am__objects_8) $(am__objects_4) +am__objects_10 = curl.$(OBJEXT) +@HAVE_WINDRES_TRUE@am__objects_11 = $(am__objects_10) +am_curl_OBJECTS = $(am__objects_9) $(am__objects_11) curl_OBJECTS = $(am_curl_OBJECTS) -@USE_EXPLICIT_LIB_DEPS_FALSE@curl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(top_builddir)/lib/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@curl_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(top_builddir)/lib/libcurl.la +curl_DEPENDENCIES = $(top_builddir)/lib/libcurl.la curl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(curl_LDFLAGS) $(LDFLAGS) -o $@ @@ -330,6 +336,7 @@ am__depfiles_remade = ../lib/$(DEPDIR)/base64.Po \ ./$(DEPDIR)/libcurltool_la-terminal.Plo \ ./$(DEPDIR)/libcurltool_la-tool_binmode.Plo \ ./$(DEPDIR)/libcurltool_la-tool_bname.Plo \ + ./$(DEPDIR)/libcurltool_la-tool_ca_embed.Plo \ ./$(DEPDIR)/libcurltool_la-tool_cb_dbg.Plo \ ./$(DEPDIR)/libcurltool_la-tool_cb_hdr.Plo \ ./$(DEPDIR)/libcurltool_la-tool_cb_prg.Plo \ @@ -371,27 +378,27 @@ am__depfiles_remade = ../lib/$(DEPDIR)/base64.Po \ ./$(DEPDIR)/libcurltool_la-tool_xattr.Plo \ ./$(DEPDIR)/libcurltool_la-var.Plo ./$(DEPDIR)/slist_wc.Po \ ./$(DEPDIR)/terminal.Po ./$(DEPDIR)/tool_binmode.Po \ - ./$(DEPDIR)/tool_bname.Po ./$(DEPDIR)/tool_cb_dbg.Po \ - ./$(DEPDIR)/tool_cb_hdr.Po ./$(DEPDIR)/tool_cb_prg.Po \ - ./$(DEPDIR)/tool_cb_rea.Po ./$(DEPDIR)/tool_cb_see.Po \ - ./$(DEPDIR)/tool_cb_soc.Po ./$(DEPDIR)/tool_cb_wrt.Po \ - ./$(DEPDIR)/tool_cfgable.Po ./$(DEPDIR)/tool_dirhie.Po \ - ./$(DEPDIR)/tool_doswin.Po ./$(DEPDIR)/tool_easysrc.Po \ - ./$(DEPDIR)/tool_filetime.Po ./$(DEPDIR)/tool_findfile.Po \ - ./$(DEPDIR)/tool_formparse.Po ./$(DEPDIR)/tool_getparam.Po \ - ./$(DEPDIR)/tool_getpass.Po ./$(DEPDIR)/tool_help.Po \ - ./$(DEPDIR)/tool_helpers.Po ./$(DEPDIR)/tool_hugehelp.Po \ - ./$(DEPDIR)/tool_ipfs.Po ./$(DEPDIR)/tool_libinfo.Po \ - ./$(DEPDIR)/tool_listhelp.Po ./$(DEPDIR)/tool_main.Po \ - ./$(DEPDIR)/tool_msgs.Po ./$(DEPDIR)/tool_operate.Po \ - ./$(DEPDIR)/tool_operhlp.Po ./$(DEPDIR)/tool_paramhlp.Po \ - ./$(DEPDIR)/tool_parsecfg.Po ./$(DEPDIR)/tool_progress.Po \ - ./$(DEPDIR)/tool_setopt.Po ./$(DEPDIR)/tool_sleep.Po \ - ./$(DEPDIR)/tool_stderr.Po ./$(DEPDIR)/tool_strdup.Po \ - ./$(DEPDIR)/tool_urlglob.Po ./$(DEPDIR)/tool_util.Po \ - ./$(DEPDIR)/tool_vms.Po ./$(DEPDIR)/tool_writeout.Po \ - ./$(DEPDIR)/tool_writeout_json.Po ./$(DEPDIR)/tool_xattr.Po \ - ./$(DEPDIR)/var.Po + ./$(DEPDIR)/tool_bname.Po ./$(DEPDIR)/tool_ca_embed.Po \ + ./$(DEPDIR)/tool_cb_dbg.Po ./$(DEPDIR)/tool_cb_hdr.Po \ + ./$(DEPDIR)/tool_cb_prg.Po ./$(DEPDIR)/tool_cb_rea.Po \ + ./$(DEPDIR)/tool_cb_see.Po ./$(DEPDIR)/tool_cb_soc.Po \ + ./$(DEPDIR)/tool_cb_wrt.Po ./$(DEPDIR)/tool_cfgable.Po \ + ./$(DEPDIR)/tool_dirhie.Po ./$(DEPDIR)/tool_doswin.Po \ + ./$(DEPDIR)/tool_easysrc.Po ./$(DEPDIR)/tool_filetime.Po \ + ./$(DEPDIR)/tool_findfile.Po ./$(DEPDIR)/tool_formparse.Po \ + ./$(DEPDIR)/tool_getparam.Po ./$(DEPDIR)/tool_getpass.Po \ + ./$(DEPDIR)/tool_help.Po ./$(DEPDIR)/tool_helpers.Po \ + ./$(DEPDIR)/tool_hugehelp.Po ./$(DEPDIR)/tool_ipfs.Po \ + ./$(DEPDIR)/tool_libinfo.Po ./$(DEPDIR)/tool_listhelp.Po \ + ./$(DEPDIR)/tool_main.Po ./$(DEPDIR)/tool_msgs.Po \ + ./$(DEPDIR)/tool_operate.Po ./$(DEPDIR)/tool_operhlp.Po \ + ./$(DEPDIR)/tool_paramhlp.Po ./$(DEPDIR)/tool_parsecfg.Po \ + ./$(DEPDIR)/tool_progress.Po ./$(DEPDIR)/tool_setopt.Po \ + ./$(DEPDIR)/tool_sleep.Po ./$(DEPDIR)/tool_stderr.Po \ + ./$(DEPDIR)/tool_strdup.Po ./$(DEPDIR)/tool_urlglob.Po \ + ./$(DEPDIR)/tool_util.Po ./$(DEPDIR)/tool_vms.Po \ + ./$(DEPDIR)/tool_writeout.Po ./$(DEPDIR)/tool_writeout_json.Po \ + ./$(DEPDIR)/tool_xattr.Po ./$(DEPDIR)/var.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -462,11 +469,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -512,7 +519,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -528,8 +534,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -564,10 +572,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -578,6 +584,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -586,6 +593,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -707,7 +715,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc # $(top_srcdir)/src is for curl's src/tool_setup.h and "curl-private" files AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ -I$(top_builddir)/src -I$(top_srcdir)/lib -I$(top_srcdir)/src \ - $(am__append_1) -DBUILDING_CURL + $(am__append_1) -DBUILDING_CURL $(am__append_4) \ + $(am__append_5) +AM_LDFLAGS = $(am__append_2) # libcurl sources to include in curltool lib we use for test binaries CURLTOOL_LIBCURL_CFILES = \ @@ -738,52 +748,18 @@ CURLX_HFILES = \ ../lib/version_win32.h \ ../lib/warnless.h -CURL_CFILES = \ - slist_wc.c \ - terminal.c \ - tool_binmode.c \ - tool_bname.c \ - tool_cb_dbg.c \ - tool_cb_hdr.c \ - tool_cb_prg.c \ - tool_cb_rea.c \ - tool_cb_see.c \ - tool_cb_soc.c \ - tool_cb_wrt.c \ - tool_cfgable.c \ - tool_dirhie.c \ - tool_doswin.c \ - tool_easysrc.c \ - tool_filetime.c \ - tool_findfile.c \ - tool_formparse.c \ - tool_getparam.c \ - tool_getpass.c \ - tool_help.c \ - tool_helpers.c \ - tool_hugehelp.c \ - tool_ipfs.c \ - tool_libinfo.c \ - tool_listhelp.c \ - tool_main.c \ - tool_msgs.c \ - tool_operate.c \ - tool_operhlp.c \ - tool_paramhlp.c \ - tool_parsecfg.c \ - tool_progress.c \ - tool_setopt.c \ - tool_sleep.c \ - tool_stderr.c \ - tool_strdup.c \ - tool_urlglob.c \ - tool_util.c \ - tool_vms.c \ - tool_writeout.c \ - tool_writeout_json.c \ - tool_xattr.c \ - var.c - +CURL_CFILES = slist_wc.c terminal.c tool_binmode.c tool_bname.c \ + tool_cb_dbg.c tool_cb_hdr.c tool_cb_prg.c tool_cb_rea.c \ + tool_cb_see.c tool_cb_soc.c tool_cb_wrt.c tool_cfgable.c \ + tool_dirhie.c tool_doswin.c tool_easysrc.c tool_filetime.c \ + tool_findfile.c tool_formparse.c tool_getparam.c \ + tool_getpass.c tool_help.c tool_helpers.c tool_hugehelp.c \ + tool_ipfs.c tool_libinfo.c tool_listhelp.c tool_main.c \ + tool_msgs.c tool_operate.c tool_operhlp.c tool_paramhlp.c \ + tool_parsecfg.c tool_progress.c tool_setopt.c tool_sleep.c \ + tool_stderr.c tool_strdup.c tool_urlglob.c tool_util.c \ + tool_vms.c tool_writeout.c tool_writeout_json.c tool_xattr.c \ + var.c $(CA_EMBED_CSOURCE) CURL_HFILES = \ slist_wc.h \ terminal.h \ @@ -838,10 +814,9 @@ CURL_RCFILES = curl.rc CURL_FILES = $(CURL_CFILES) $(CURLX_CFILES) $(CURL_HFILES) # CURL_FILES comes from Makefile.inc -curl_SOURCES = $(CURL_FILES) $(am__append_2) +curl_SOURCES = $(CURL_FILES) $(am__append_3) curl_LDFLAGS = $(AM_LDFLAGS) $(CURL_LDFLAGS_BIN) -@USE_EXPLICIT_LIB_DEPS_FALSE@curl_LDADD = $(top_builddir)/lib/libcurl.la @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@ -@USE_EXPLICIT_LIB_DEPS_TRUE@curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ +curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # if unit tests are enabled, build a static library to link them with @BUILD_UNITTESTS_TRUE@noinst_LTLIBRARIES = libcurltool.la @@ -851,11 +826,8 @@ curl_LDFLAGS = $(AM_LDFLAGS) $(CURL_LDFLAGS_BIN) @BUILD_UNITTESTS_TRUE@libcurltool_la_CFLAGS = @BUILD_UNITTESTS_TRUE@libcurltool_la_LDFLAGS = -static $(LINKFLAGS) @BUILD_UNITTESTS_TRUE@libcurltool_la_SOURCES = $(CURL_FILES) -CLEANFILES = tool_hugehelp.c -# Use the C locale to ensure that only ASCII characters appear in the -# embedded text. -NROFF = env LC_ALL=C @NROFF@ @MANOPT@ 2>/dev/null # figured out by the configure script -EXTRA_DIST = mkhelp.pl \ +CLEANFILES = tool_hugehelp.c $(CA_EMBED_CSOURCE) +EXTRA_DIST = mk-file-embed.pl mkhelp.pl \ Makefile.mk curl.rc Makefile.inc CMakeLists.txt .checksrc @@ -871,6 +843,8 @@ CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; CS_1 = CS_ = $(CS_0) +CA_EMBED_CSOURCE = tool_ca_embed.c +@CURL_CA_EMBED_SET_TRUE@MK_FILE_EMBED = $(top_srcdir)/src/mk-file-embed.pl # disable the tests that are mostly causing false positives TIDYFLAGS = -checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference @@ -1043,6 +1017,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-terminal.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_binmode.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_bname.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_ca_embed.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_cb_dbg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_cb_hdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurltool_la-tool_cb_prg.Plo@am__quote@ # am--include-marker @@ -1087,6 +1062,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terminal.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_binmode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_bname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_ca_embed.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_cb_dbg.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_cb_hdr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_cb_prg.Po@am__quote@ # am--include-marker @@ -1466,6 +1442,13 @@ libcurltool_la-var.lo: var.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurltool_la_CPPFLAGS) $(CPPFLAGS) $(libcurltool_la_CFLAGS) $(CFLAGS) -c -o libcurltool_la-var.lo `test -f 'var.c' || echo '$(srcdir)/'`var.c +libcurltool_la-tool_ca_embed.lo: tool_ca_embed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurltool_la_CPPFLAGS) $(CPPFLAGS) $(libcurltool_la_CFLAGS) $(CFLAGS) -MT libcurltool_la-tool_ca_embed.lo -MD -MP -MF $(DEPDIR)/libcurltool_la-tool_ca_embed.Tpo -c -o libcurltool_la-tool_ca_embed.lo `test -f 'tool_ca_embed.c' || echo '$(srcdir)/'`tool_ca_embed.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurltool_la-tool_ca_embed.Tpo $(DEPDIR)/libcurltool_la-tool_ca_embed.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tool_ca_embed.c' object='libcurltool_la-tool_ca_embed.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurltool_la_CPPFLAGS) $(CPPFLAGS) $(libcurltool_la_CFLAGS) $(CFLAGS) -c -o libcurltool_la-tool_ca_embed.lo `test -f 'tool_ca_embed.c' || echo '$(srcdir)/'`tool_ca_embed.c + ../lib/libcurltool_la-base64.lo: ../lib/base64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurltool_la_CPPFLAGS) $(CPPFLAGS) $(libcurltool_la_CFLAGS) $(CFLAGS) -MT ../lib/libcurltool_la-base64.lo -MD -MP -MF ../lib/$(DEPDIR)/libcurltool_la-base64.Tpo -c -o ../lib/libcurltool_la-base64.lo `test -f '../lib/base64.c' || echo '$(srcdir)/'`../lib/base64.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/libcurltool_la-base64.Tpo ../lib/$(DEPDIR)/libcurltool_la-base64.Plo @@ -1680,6 +1663,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurltool_la-terminal.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_binmode.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_bname.Plo + -rm -f ./$(DEPDIR)/libcurltool_la-tool_ca_embed.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_dbg.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_hdr.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_prg.Plo @@ -1724,6 +1708,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/terminal.Po -rm -f ./$(DEPDIR)/tool_binmode.Po -rm -f ./$(DEPDIR)/tool_bname.Po + -rm -f ./$(DEPDIR)/tool_ca_embed.Po -rm -f ./$(DEPDIR)/tool_cb_dbg.Po -rm -f ./$(DEPDIR)/tool_cb_hdr.Po -rm -f ./$(DEPDIR)/tool_cb_prg.Po @@ -1829,6 +1814,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurltool_la-terminal.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_binmode.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_bname.Plo + -rm -f ./$(DEPDIR)/libcurltool_la-tool_ca_embed.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_dbg.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_hdr.Plo -rm -f ./$(DEPDIR)/libcurltool_la-tool_cb_prg.Plo @@ -1873,6 +1859,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/terminal.Po -rm -f ./$(DEPDIR)/tool_binmode.Po -rm -f ./$(DEPDIR)/tool_bname.Po + -rm -f ./$(DEPDIR)/tool_ca_embed.Po -rm -f ./$(DEPDIR)/tool_cb_dbg.Po -rm -f ./$(DEPDIR)/tool_cb_hdr.Po -rm -f ./$(DEPDIR)/tool_cb_prg.Po @@ -1955,8 +1942,6 @@ uninstall-am: uninstall-binPROGRAMS .DELETE_ON_ERROR: @HAVE_WINDRES_TRUE@$(CURL_RCFILES): tool_version.h -# Here are the stuff to create a built-in manual - @USE_MANUAL_TRUE@$(ASCIIPAGE): @USE_MANUAL_TRUE@ cd $(top_builddir)/docs && $(MAKE) @@ -1977,12 +1962,17 @@ uninstall-am: uninstall-binPROGRAMS # built-in manual has been disabled, make a blank file @USE_MANUAL_FALSE@$(HUGE): @USE_MANUAL_FALSE@ echo '#include "tool_hugehelp.h"' >> $(HUGE) +@CURL_CA_EMBED_SET_TRUE@$(CA_EMBED_CSOURCE): $(MK_FILE_EMBED) +@CURL_CA_EMBED_SET_TRUE@ $(PERL) $(MK_FILE_EMBED) --var curl_ca_embed < $(CURL_CA_EMBED) > $(CA_EMBED_CSOURCE) +@CURL_CA_EMBED_SET_FALSE@$(CA_EMBED_CSOURCE): +@CURL_CA_EMBED_SET_FALSE@ echo 'extern const void *curl_ca_embed; const void *curl_ca_embed;' > $(CA_EMBED_CSOURCE) -# ignore tool_hugehelp.c since it is generated source code and it plays -# by slightly different rules! +# ignore generated C files since they play by slightly different rules! checksrc: $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \ - -W$(srcdir)/tool_hugehelp.c $(srcdir)/*.[ch]) + -W$(srcdir)/$(HUGE) \ + -W$(srcdir)/$(CA_EMBED_CSOURCE) \ + $(srcdir)/*.[ch]) # for debug builds, we scan the sources on all regular make invokes @DEBUGBUILD_TRUE@all-local: checksrc diff --git a/src/Makefile.mk b/src/Makefile.mk index 83dd65d16..f25fc02a2 100644 --- a/src/Makefile.mk +++ b/src/Makefile.mk @@ -45,6 +45,11 @@ TARGETS := curl$(BIN_EXT) CURL_CFILES += $(notdir $(CURLX_CFILES)) +ifneq ($(CURL_CA_EMBED),) +CPPFLAGS += -DCURL_CA_EMBED +CURL_CFILES += tool_ca_embed.c +endif + curl_OBJECTS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(strip $(CURL_CFILES))) ifdef MAP CURL_MAP := curl.map @@ -57,31 +62,31 @@ TOCLEAN := $(curl_OBJECTS) ### Rules -ifneq ($(wildcard tool_hugehelp.c.cvs),) -PERL ?= perl -NROFF ?= groff +PERL ?= perl +ifneq ($(wildcard tool_hugehelp.c.cvs),) TOCLEAN += tool_hugehelp.c - -ifneq ($(shell $(call WHICH, $(NROFF))),) -$(PROOT)/docs/curl.1: $(wildcard $(PROOT)/docs/cmdline-opts/*.d) - cd $(PROOT)/docs/cmdline-opts && \ - $(PERL) gen.pl mainpage $(notdir $^) > ../curl.1 - +# Load DPAGES +include $(PROOT)/docs/cmdline-opts/Makefile.inc +$(PROOT)/docs/cmdline-opts/curl.txt: $(addprefix $(PROOT)/docs/cmdline-opts/,$(DPAGES)) $(PROOT)/scripts/managen + cd $(PROOT)/docs/cmdline-opts && $(PERL) ../../scripts/managen ascii $(DPAGES) > curl.txt # Necessary for the generated tools_hugehelp.c CPPFLAGS += -DUSE_MANUAL - ifdef ZLIB _MKHELPOPT += -c endif -tool_hugehelp.c: $(PROOT)/docs/curl.1 mkhelp.pl - $(NROFF) -man -Tascii $(MANOPT) $< | \ - $(PERL) mkhelp.pl $(_MKHELPOPT) $< > $@ +tool_hugehelp.c: $(PROOT)/docs/cmdline-opts/curl.txt mkhelp.pl + $(PERL) mkhelp.pl $(_MKHELPOPT) < $< > $@ else tool_hugehelp.c: @echo Creating $@ @$(call COPY, $@.cvs, $@) endif + +ifneq ($(CURL_CA_EMBED),) +TOCLEAN += tool_ca_embed.c +tool_ca_embed.c: mk-file-embed.pl + $(PERL) mk-file-embed.pl --var curl_ca_embed < $(CURL_CA_EMBED) > $@ endif $(TARGETS): $(curl_OBJECTS) $(PROOT)/lib/libcurl.a diff --git a/tests/data/CMakeLists.txt b/src/mk-file-embed.pl similarity index 65% rename from tests/data/CMakeLists.txt rename to src/mk-file-embed.pl index ed0b88f18..3447aa947 100644 --- a/tests/data/CMakeLists.txt +++ b/src/mk-file-embed.pl @@ -1,3 +1,4 @@ +#!/usr/bin/env perl #*************************************************************************** # _ _ ____ _ # Project ___| | | | _ \| | @@ -21,6 +22,35 @@ # SPDX-License-Identifier: curl # ########################################################################### -# Loads 'TESTCASES' from for the 'make show' target in runtests.pl -transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +my $varname = "var"; +if($ARGV[0] eq "--var") { + shift; + $varname = shift @ARGV; +} + +print <) { + my $line = $_; + foreach my $n (split //, $line) { + my $ord = ord($n); + printf("%s,", $ord); + if($ord == 10) { + printf("\n"); + } + } +} + +print <) { my $line = $_; push @out, $line; @@ -53,6 +45,8 @@ */ #ifdef USE_MANUAL #include "tool_hugehelp.h" +#include "tool_help.h" + HEAD ; if($c) { @@ -111,23 +105,25 @@ (void) opaque; free(ptr); } + +#define HEADERLEN 10 + /* Decompress and send to stdout a gzip-compressed buffer */ void hugehelp(void) { unsigned char *buf; - int status, headerlen; + int status; z_stream z; /* Make sure no gzip options are set */ if(hugehelpgz[3] & 0xfe) return; - headerlen = 10; memset(&z, 0, sizeof(z_stream)); z.zalloc = (alloc_func)zalloc_func; z.zfree = (free_func)zfree_func; - z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen); - z.next_in = (unsigned char *)hugehelpgz + headerlen; + z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN); + z.next_in = (unsigned char *)hugehelpgz + HEADERLEN; if(inflateInit2(&z, -MAX_WBITS) != Z_OK) return; @@ -144,7 +140,49 @@ break; } else - break; /* Error */ + break; /* error */ + } + free(buf); + } + inflateEnd(&z); +} +/* Show the help text for the 'arg' curl argument on stdout */ +void showhelp(const char *trigger, const char *arg, const char *endarg) +{ + unsigned char *buf; + int status; + z_stream z; + struct scan_ctx ctx; + inithelpscan(&ctx, trigger, arg, endarg); + + /* Make sure no gzip options are set */ + if(hugehelpgz[3] & 0xfe) + return; + + memset(&z, 0, sizeof(z_stream)); + z.zalloc = (alloc_func)zalloc_func; + z.zfree = (free_func)zfree_func; + z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN); + z.next_in = (unsigned char *)hugehelpgz + HEADERLEN; + + if(inflateInit2(&z, -MAX_WBITS) != Z_OK) + return; + + buf = malloc(BUF_SIZE); + if(buf) { + while(1) { + z.avail_out = BUF_SIZE; + z.next_out = buf; + status = inflate(&z, Z_SYNC_FLUSH); + if(status == Z_OK || status == Z_STREAM_END) { + size_t len = BUF_SIZE - z.avail_out; + if(!helpscan(buf, len, &ctx)) + break; + if(status == Z_STREAM_END) + break; + } + else + break; /* error */ } free(buf); } @@ -188,6 +226,21 @@ while(curlman[i]) puts(curlman[i++]); } + +/* Show the help text for the 'arg' curl argument on stdout */ +void showhelp(const char *trigger, const char *arg, const char *endarg) +{ + int i = 0; + struct scan_ctx ctx; + inithelpscan(&ctx, trigger, arg, endarg); + while(curlman[i]) { + size_t len = strlen(curlman[i]); + if(!helpscan((unsigned char *)curlman[i], len, &ctx) || + !helpscan((unsigned char *)"\\n", 1, &ctx)) + break; + i++; + } +} ENDLINE ; diff --git a/src/tool_ca_embed.c b/src/tool_ca_embed.c new file mode 100644 index 000000000..9b7b593f8 --- /dev/null +++ b/src/tool_ca_embed.c @@ -0,0 +1 @@ +extern const void *curl_ca_embed; const void *curl_ca_embed; diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c index dd2a124ad..6d2a61783 100644 --- a/src/tool_cb_dbg.c +++ b/src/tool_cb_dbg.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index 96b6fabb7..969acac1e 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -28,8 +28,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 4c3d3cdb5..5acd3fcc7 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -35,7 +33,8 @@ #include "memdebug.h" /* keep this as LAST include */ -#define MAX_BARLENGTH 256 +#define MAX_BARLENGTH 400 +#define MIN_BARLENGTH 20 /* 200 values generated by this perl code: @@ -119,6 +118,17 @@ static void fly(struct ProgressData *bar, bool moved) # define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) #endif +static void update_width(struct ProgressData *bar) +{ + int cols = get_terminal_columns(); + if(cols > MAX_BARLENGTH) + bar->width = MAX_BARLENGTH; + else if(cols > MIN_BARLENGTH) + bar->width = (int)cols; + else + bar->width = MIN_BARLENGTH; +} + int tool_progress_cb(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) @@ -172,6 +182,7 @@ int tool_progress_cb(void *clientp, if(tvdiff(now, bar->prevtime) < 100L) /* limit progress-bar updating to 10 Hz */ return 0; + update_width(bar); fly(bar, point != bar->prev); } } @@ -179,6 +190,7 @@ int tool_progress_cb(void *clientp, /* simply count invokes */ bar->calls++; + update_width(bar); if((total > 0) && (point != bar->prev)) { char line[MAX_BARLENGTH + 1]; char format[40]; @@ -223,7 +235,6 @@ int tool_progress_cb(void *clientp, void progressbarinit(struct ProgressData *bar, struct OperationConfig *config) { - unsigned int cols; memset(bar, 0, sizeof(struct ProgressData)); /* pass the resume from value through to the progress function so it can @@ -231,11 +242,7 @@ void progressbarinit(struct ProgressData *bar, if(config->use_resume) bar->initial_size = config->resume_from; - cols = get_terminal_columns(); - if(cols > MAX_BARLENGTH) - bar->width = MAX_BARLENGTH; - else if(cols > 20) - bar->width = (int)cols; + update_width(bar); bar->out = tool_stderr; bar->tick = 150; diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c index 1e23895ca..0fe401430 100644 --- a/src/tool_cb_rea.c +++ b/src/tool_cb_rea.c @@ -27,8 +27,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_cb_see.c b/src/tool_cb_see.c index 7ce678aab..a425ebe9d 100644 --- a/src/tool_cb_see.c +++ b/src/tool_cb_see.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -54,13 +52,13 @@ int tool_seek_cb(void *userdata, curl_off_t offset, int whence) #if(SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES) /* The offset check following here is only interesting if curl_off_t is - larger than off_t and we are not using the WIN32 large file support - macros that provide the support to do 64bit seeks correctly */ + larger than off_t and we are not using the Win32 large file support + macros that provide the support to do 64-bit seeks correctly */ if(offset > OUR_MAX_SEEK_O) { /* Some precaution code to work around problems with different data sizes - to allow seeking >32bit even if off_t is 32bit. Should be very rare and - is really valid on weirdo-systems. */ + to allow seeking >32-bit even if off_t is 32-bit. Should be very rare + and is really valid on weirdo-systems. */ curl_off_t left = offset; if(whence != SEEK_SET) diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index ccc010917..660000b69 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -30,8 +30,6 @@ #include -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -98,7 +96,7 @@ bool tool_create_output_file(struct OutStruct *outs, (errno == EEXIST || errno == EISDIR) && /* because we keep having files that already exist */ next_num < 100 /* and we have not reached the retry limit */ ) { - curlx_msnprintf(newname + len + 1, 12, "%d", next_num); + msnprintf(newname + len + 1, 12, "%d", next_num); next_num++; do { fd = open(newname, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE); @@ -219,7 +217,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) #ifdef _WIN32 fhnd = _get_osfhandle(fileno(outs->stream)); - /* if windows console then UTF-8 must be converted to UTF-16 */ + /* if Windows console then UTF-8 must be converted to UTF-16 */ if(isatty(fileno(outs->stream)) && GetConsoleScreenBufferInfo((HANDLE)fhnd, &console_info)) { wchar_t *wc_buf; diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index a887881da..729cd5241 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -111,7 +111,7 @@ struct OperationConfig { bool sasl_ir; /* Enable/disable SASL initial response */ bool proxytunnel; bool ftp_append; /* APPE on ftp */ - bool use_ascii; /* select ascii or text transfer */ + bool use_ascii; /* select ASCII or text transfer */ bool autoreferer; /* automatically set referer */ bool failonerror; /* fail on (HTTP) errors */ bool failwithbody; /* fail on (HTTP) errors but still store body */ @@ -302,6 +302,7 @@ struct OperationConfig { struct State state; /* for create_transfer() */ bool rm_partial; /* on error, remove partially written output files */ + bool skip_existing; #ifdef USE_ECH char *ech; /* Config set by --ech keywords */ char *ech_config; /* Config set by "--ech esl:" option */ @@ -315,6 +316,7 @@ struct GlobalConfig { bool silent; /* do not show messages, --silent given */ bool noprogress; /* do not show progress bar */ bool isatty; /* Updated internally if output is a tty */ + unsigned char verbosity; /* How verbose we should be */ char *trace_dump; /* file to dump the network trace to */ FILE *trace_stream; bool trace_fopened; diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c index 0efdc398c..772664c5f 100644 --- a/src/tool_dirhie.c +++ b/src/tool_dirhie.c @@ -29,8 +29,6 @@ # include #endif -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_dirhie.h" diff --git a/src/tool_doswin.c b/src/tool_doswin.c index 38ef0a01e..321e44f9c 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -297,11 +297,11 @@ SANITIZEcode truncate_dryrun(const char *path, const size_t truncate_pos) */ /* -Extra sanitization MSDOS for file_name. +Extra sanitization MS-DOS for file_name. This is a supporting function for sanitize_file_name. -Warning: This is an MSDOS legacy function and was purposely written in a way +Warning: This is an MS-DOS legacy function and was purposely written in a way that some path information may pass through. For example drive letter names (C:, D:, etc) are allowed to pass through. For sanitizing a filename use sanitize_file_name. @@ -449,7 +449,7 @@ Rename file_name if it is a reserved dos device name. This is a supporting function for sanitize_file_name. -Warning: This is an MSDOS legacy function and was purposely written in a way +Warning: This is an MS-DOS legacy function and was purposely written in a way that some path information may pass through. For example drive letter names (C:, D:, etc) are allowed to pass through. For sanitizing a filename use sanitize_file_name. @@ -558,7 +558,7 @@ SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized, } /* This is the legacy portion from rename_if_dos_device_name that checks for - reserved device names. It only works on MSDOS. On Windows XP the stat + reserved device names. It only works on MS-DOS. On Windows XP the stat check errors with EINVAL if the device name is reserved. On Windows Vista/7/8 it sets mode S_IFREG (regular file or device). According to MSDN stat doc the latter behavior is correct, but that does not help us @@ -603,7 +603,7 @@ char **__crt0_glob_function(char *arg) /* * Function to find CACert bundle on a Win32 platform using SearchPath. * (SearchPath is already declared via inclusions done in setup header file) - * (Use the ASCII version instead of the unicode one!) + * (Use the ASCII version instead of the Unicode one!) * The order of the directories it searches is: * 1. application's directory * 2. current working directory diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c index 6ef2be721..a623f1961 100644 --- a/src/tool_easysrc.c +++ b/src/tool_easysrc.c @@ -27,8 +27,6 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -113,7 +111,7 @@ CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...) char *bufp; va_list ap; va_start(ap, fmt); - bufp = curlx_mvaprintf(fmt, ap); + bufp = vaprintf(fmt, ap); va_end(ap); if(!bufp) { ret = CURLE_OUT_OF_MEMORY; diff --git a/src/tool_filetime.c b/src/tool_filetime.c index 549b8bea5..a80019f15 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -38,7 +38,7 @@ int getfiletime(const char *filename, struct GlobalConfig *global, { int rc = 1; -/* Windows stat() may attempt to adjust the unix GMT file time by a daylight +/* Windows stat() may attempt to adjust the Unix GMT file time by a daylight saving time offset and since it is GMT that is bad behavior. When we have access to a 64-bit type we can bypass stat and get the times directly. */ #if defined(_WIN32) && !defined(CURL_WINDOWS_APP) @@ -92,14 +92,14 @@ void setfiletime(curl_off_t filetime, const char *filename, struct GlobalConfig *global) { if(filetime >= 0) { -/* Windows utime() may attempt to adjust the unix GMT file time by a daylight +/* Windows utime() may attempt to adjust the Unix GMT file time by a daylight saving time offset and since it is GMT that is bad behavior. When we have access to a 64-bit type we can bypass utime and set the times directly. */ #if defined(_WIN32) && !defined(CURL_WINDOWS_APP) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); - /* 910670515199 is the maximum unix filetime that can be used as a + /* 910670515199 is the maximum Unix filetime that can be used as a Windows FILETIME without overflow: 30827-12-31T23:59:59. */ if(filetime > CURL_OFF_T_C(910670515199)) { warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T diff --git a/src/tool_findfile.c b/src/tool_findfile.c index a1544a563..672fc7b99 100644 --- a/src/tool_findfile.c +++ b/src/tool_findfile.c @@ -35,7 +35,7 @@ #include #endif -#include +#include #include "tool_findfile.h" @@ -51,7 +51,7 @@ struct finder { in the findfile() function */ static const struct finder conf_list[] = { { "CURL_HOME", NULL, FALSE }, - { "XDG_CONFIG_HOME", NULL, FALSE }, /* index == 1, used in the code */ + { "XDG_CONFIG_HOME", NULL, TRUE }, { "HOME", NULL, FALSE }, #ifdef _WIN32 { "USERPROFILE", NULL, FALSE }, @@ -72,9 +72,9 @@ static char *checkhome(const char *home, const char *fname, bool dotscore) for(i = 0; i < (dotscore ? 2 : 1); i++) { char *c; if(dotscore) - c = curl_maprintf("%s" DIR_CHAR "%c%s", home, pref[i], &fname[1]); + c = aprintf("%s" DIR_CHAR "%c%s", home, pref[i], &fname[1]); else - c = curl_maprintf("%s" DIR_CHAR "%s", home, fname); + c = aprintf("%s" DIR_CHAR "%s", home, fname); if(c) { int fd = open(c, O_RDONLY); if(fd >= 0) { @@ -97,12 +97,11 @@ static char *checkhome(const char *home, const char *fname, bool dotscore) * * 1. Iterate over the environment variables in order, and if set, check for * the given file to be accessed there, then it is a match. - * 2. Non-windows: try getpwuid + * 2. Non-Windows: try getpwuid */ char *findfile(const char *fname, int dotscore) { int i; - bool xdg = FALSE; DEBUGASSERT(fname && fname[0]); DEBUGASSERT((dotscore != 1) || (fname[0] == '.')); @@ -114,21 +113,19 @@ char *findfile(const char *fname, int dotscore) if(home) { char *path; const char *filename = fname; - if(i == 1 /* XDG_CONFIG_HOME */) - xdg = TRUE; if(!home[0]) { curl_free(home); continue; } if(conf_list[i].append) { - char *c = curl_maprintf("%s%s", home, conf_list[i].append); + char *c = aprintf("%s%s", home, conf_list[i].append); curl_free(home); if(!c) return NULL; home = c; } if(conf_list[i].withoutdot) { - if(!dotscore || xdg) { + if(!dotscore) { /* this is not looking for .curlrc, or the XDG_CONFIG_HOME was defined so we skip the extended check */ curl_free(home); diff --git a/src/tool_formparse.c b/src/tool_formparse.c index 61f88396c..15918d3ee 100644 --- a/src/tool_formparse.c +++ b/src/tool_formparse.c @@ -25,8 +25,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 4c9392cc6..be41aa35d 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -25,8 +25,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_binmode.h" @@ -71,304 +69,16 @@ static ParameterError getstr(char **str, const char *val, bool allowblank) return PARAM_OK; } -/* one enum for every command line option. The name is the verbatim long - option name, but in uppercase with periods and minuses replaced with - underscores using a "C_" prefix. */ -typedef enum { - C_ABSTRACT_UNIX_SOCKET, - C_ALPN, - C_ALT_SVC, - C_ANYAUTH, - C_APPEND, - C_AWS_SIGV4, - C_BASIC, - C_BUFFER, - C_CA_NATIVE, - C_CACERT, - C_CAPATH, - C_CERT, - C_CERT_STATUS, - C_CERT_TYPE, - C_CIPHERS, - C_CLOBBER, - C_COMPRESSED, - C_COMPRESSED_SSH, - C_CONFIG, - C_CONNECT_TIMEOUT, - C_CONNECT_TO, - C_CONTINUE_AT, - C_COOKIE, - C_COOKIE_JAR, - C_CREATE_DIRS, - C_CREATE_FILE_MODE, - C_CRLF, - C_CRLFILE, - C_CURVES, - C_DATA, - C_DATA_ASCII, - C_DATA_BINARY, - C_DATA_RAW, - C_DATA_URLENCODE, - C_DELEGATION, - C_DIGEST, - C_DISABLE, - C_DISABLE_EPRT, - C_DISABLE_EPSV, - C_DISALLOW_USERNAME_IN_URL, - C_DNS_INTERFACE, - C_DNS_IPV4_ADDR, - C_DNS_IPV6_ADDR, - C_DNS_SERVERS, - C_DOH_CERT_STATUS, - C_DOH_INSECURE, - C_DOH_URL, - C_DUMP_HEADER, - C_ECH, - C_EGD_FILE, - C_ENGINE, - C_EPRT, - C_EPSV, - C_ETAG_COMPARE, - C_ETAG_SAVE, - C_EXPECT100_TIMEOUT, - C_FAIL, - C_FAIL_EARLY, - C_FAIL_WITH_BODY, - C_FALSE_START, - C_FORM, - C_FORM_ESCAPE, - C_FORM_STRING, - C_FTP_ACCOUNT, - C_FTP_ALTERNATIVE_TO_USER, - C_FTP_CREATE_DIRS, - C_FTP_METHOD, - C_FTP_PASV, - C_FTP_PORT, - C_FTP_PRET, - C_FTP_SKIP_PASV_IP, - C_FTP_SSL, - C_FTP_SSL_CCC, - C_FTP_SSL_CCC_MODE, - C_FTP_SSL_CONTROL, - C_FTP_SSL_REQD, - C_GET, - C_GLOBOFF, - C_HAPPY_EYEBALLS_TIMEOUT_MS, - C_HAPROXY_CLIENTIP, - C_HAPROXY_PROTOCOL, - C_HEAD, - C_HEADER, - C_HELP, - C_HOSTPUBMD5, - C_HOSTPUBSHA256, - C_HSTS, - C_HTTP0_9, - C_HTTP1_0, - C_HTTP1_1, - C_HTTP2, - C_HTTP2_PRIOR_KNOWLEDGE, - C_HTTP3, - C_HTTP3_ONLY, - C_IGNORE_CONTENT_LENGTH, - C_INCLUDE, - C_INSECURE, - C_INTERFACE, - C_IPFS_GATEWAY, - C_IPV4, - C_IPV6, - C_JSON, - C_JUNK_SESSION_COOKIES, - C_KEEPALIVE, - C_KEEPALIVE_CNT, - C_KEEPALIVE_TIME, - C_KEY, - C_KEY_TYPE, - C_KRB, - C_KRB4, - C_LIBCURL, - C_LIMIT_RATE, - C_LIST_ONLY, - C_LOCAL_PORT, - C_LOCATION, - C_LOCATION_TRUSTED, - C_LOGIN_OPTIONS, - C_MAIL_AUTH, - C_MAIL_FROM, - C_MAIL_RCPT, - C_MAIL_RCPT_ALLOWFAILS, - C_MANUAL, - C_MAX_FILESIZE, - C_MAX_REDIRS, - C_MAX_TIME, - C_METALINK, - C_MPTCP, - C_NEGOTIATE, - C_NETRC, - C_NETRC_FILE, - C_NETRC_OPTIONAL, - C_NEXT, - C_NOPROXY, - C_NPN, - C_NTLM, - C_NTLM_WB, - C_OAUTH2_BEARER, - C_OUTPUT, - C_OUTPUT_DIR, - C_PARALLEL, - C_PARALLEL_IMMEDIATE, - C_PARALLEL_MAX, - C_PASS, - C_PATH_AS_IS, - C_PINNEDPUBKEY, - C_POST301, - C_POST302, - C_POST303, - C_PREPROXY, - C_PROGRESS_BAR, - C_PROGRESS_METER, - C_PROTO, - C_PROTO_DEFAULT, - C_PROTO_REDIR, - C_PROXY, - C_PROXY_ANYAUTH, - C_PROXY_BASIC, - C_PROXY_CA_NATIVE, - C_PROXY_CACERT, - C_PROXY_CAPATH, - C_PROXY_CERT, - C_PROXY_CERT_TYPE, - C_PROXY_CIPHERS, - C_PROXY_CRLFILE, - C_PROXY_DIGEST, - C_PROXY_HEADER, - C_PROXY_HTTP2, - C_PROXY_INSECURE, - C_PROXY_KEY, - C_PROXY_KEY_TYPE, - C_PROXY_NEGOTIATE, - C_PROXY_NTLM, - C_PROXY_PASS, - C_PROXY_PINNEDPUBKEY, - C_PROXY_SERVICE_NAME, - C_PROXY_SSL_ALLOW_BEAST, - C_PROXY_SSL_AUTO_CLIENT_CERT, - C_PROXY_TLS13_CIPHERS, - C_PROXY_TLSAUTHTYPE, - C_PROXY_TLSPASSWORD, - C_PROXY_TLSUSER, - C_PROXY_TLSV1, - C_PROXY_USER, - C_PROXY1_0, - C_PROXYTUNNEL, - C_PUBKEY, - C_QUOTE, - C_RANDOM_FILE, - C_RANGE, - C_RATE, - C_RAW, - C_REFERER, - C_REMOTE_HEADER_NAME, - C_REMOTE_NAME, - C_REMOTE_NAME_ALL, - C_REMOTE_TIME, - C_REMOVE_ON_ERROR, - C_REQUEST, - C_REQUEST_TARGET, - C_RESOLVE, - C_RETRY, - C_RETRY_ALL_ERRORS, - C_RETRY_CONNREFUSED, - C_RETRY_DELAY, - C_RETRY_MAX_TIME, - C_SASL_AUTHZID, - C_SASL_IR, - C_SERVICE_NAME, - C_SESSIONID, - C_SHOW_ERROR, - C_SILENT, - C_SOCKS4, - C_SOCKS4A, - C_SOCKS5, - C_SOCKS5_BASIC, - C_SOCKS5_GSSAPI, - C_SOCKS5_GSSAPI_NEC, - C_SOCKS5_GSSAPI_SERVICE, - C_SOCKS5_HOSTNAME, - C_SPEED_LIMIT, - C_SPEED_TIME, - C_SSL, - C_SSL_ALLOW_BEAST, - C_SSL_AUTO_CLIENT_CERT, - C_SSL_NO_REVOKE, - C_SSL_REQD, - C_SSL_REVOKE_BEST_EFFORT, - C_SSLV2, - C_SSLV3, - C_STDERR, - C_STYLED_OUTPUT, - C_SUPPRESS_CONNECT_HEADERS, - C_TCP_FASTOPEN, - C_TCP_NODELAY, - C_TELNET_OPTION, - C_TEST_EVENT, - C_TFTP_BLKSIZE, - C_TFTP_NO_OPTIONS, - C_TIME_COND, - C_TLS_MAX, - C_TLS13_CIPHERS, - C_TLSAUTHTYPE, - C_TLSPASSWORD, - C_TLSUSER, - C_TLSV1, - C_TLSV1_0, - C_TLSV1_1, - C_TLSV1_2, - C_TLSV1_3, - C_TR_ENCODING, - C_TRACE, - C_TRACE_ASCII, - C_TRACE_CONFIG, - C_TRACE_IDS, - C_TRACE_TIME, - C_IP_TOS, - C_UNIX_SOCKET, - C_UPLOAD_FILE, - C_URL, - C_URL_QUERY, - C_USE_ASCII, - C_USER, - C_USER_AGENT, - C_VARIABLE, - C_VERBOSE, - C_VERSION, - C_VLAN_PRIORITY, - C_WDEBUG, - C_WRITE_OUT, - C_XATTR -} cmdline_t; - -struct LongShort { - const char *lname; /* long name option */ - enum { - ARG_NONE, /* stand-alone but not a boolean */ - ARG_BOOL, /* accepts a --no-[name] prefix */ - ARG_STRG, /* requires an argument */ - ARG_FILE /* requires an argument, usually a filename */ - } desc; - char letter; /* short name option or ' ' */ - cmdline_t cmd; -}; - /* this array MUST be alphasorted based on the 'lname' */ static const struct LongShort aliases[]= { {"abstract-unix-socket", ARG_FILE, ' ', C_ABSTRACT_UNIX_SOCKET}, - {"alpn", ARG_BOOL, ' ', C_ALPN}, + {"alpn", ARG_BOOL|ARG_NO, ' ', C_ALPN}, {"alt-svc", ARG_STRG, ' ', C_ALT_SVC}, {"anyauth", ARG_BOOL, ' ', C_ANYAUTH}, {"append", ARG_BOOL, 'a', C_APPEND}, {"aws-sigv4", ARG_STRG, ' ', C_AWS_SIGV4}, {"basic", ARG_BOOL, ' ', C_BASIC}, - {"buffer", ARG_BOOL, 'N', C_BUFFER}, + {"buffer", ARG_BOOL|ARG_NO, 'N', C_BUFFER}, {"ca-native", ARG_BOOL, ' ', C_CA_NATIVE}, {"cacert", ARG_FILE, ' ', C_CACERT}, {"capath", ARG_FILE, ' ', C_CAPATH}, @@ -376,7 +86,7 @@ static const struct LongShort aliases[]= { {"cert-status", ARG_BOOL, ' ', C_CERT_STATUS}, {"cert-type", ARG_STRG, ' ', C_CERT_TYPE}, {"ciphers", ARG_STRG, ' ', C_CIPHERS}, - {"clobber", ARG_BOOL, ' ', C_CLOBBER}, + {"clobber", ARG_BOOL|ARG_NO, ' ', C_CLOBBER}, {"compressed", ARG_BOOL, ' ', C_COMPRESSED}, {"compressed-ssh", ARG_BOOL, ' ', C_COMPRESSED_SSH}, {"config", ARG_FILE, 'K', C_CONFIG}, @@ -408,6 +118,7 @@ static const struct LongShort aliases[]= { {"doh-cert-status", ARG_BOOL, ' ', C_DOH_CERT_STATUS}, {"doh-insecure", ARG_BOOL, ' ', C_DOH_INSECURE}, {"doh-url" , ARG_STRG, ' ', C_DOH_URL}, + {"dump-ca-embed", ARG_NONE, ' ', C_DUMP_CA_EMBED}, {"dump-header", ARG_FILE, 'D', C_DUMP_HEADER}, {"ech", ARG_STRG, ' ', C_ECH}, {"egd-file", ARG_STRG, ' ', C_EGD_FILE}, @@ -456,7 +167,7 @@ static const struct LongShort aliases[]= { {"http3", ARG_NONE, ' ', C_HTTP3}, {"http3-only", ARG_NONE, ' ', C_HTTP3_ONLY}, {"ignore-content-length", ARG_BOOL, ' ', C_IGNORE_CONTENT_LENGTH}, - {"include", ARG_BOOL, 'i', C_INCLUDE}, + {"include", ARG_BOOL, ' ', C_INCLUDE}, {"insecure", ARG_BOOL, 'k', C_INSECURE}, {"interface", ARG_STRG, ' ', C_INTERFACE}, {"ip-tos", ARG_STRG, ' ', C_IP_TOS}, @@ -465,7 +176,7 @@ static const struct LongShort aliases[]= { {"ipv6", ARG_NONE, '6', C_IPV6}, {"json", ARG_STRG, ' ', C_JSON}, {"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES}, - {"keepalive", ARG_BOOL, ' ', C_KEEPALIVE}, + {"keepalive", ARG_BOOL|ARG_NO, ' ', C_KEEPALIVE}, {"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT}, {"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME}, {"key", ARG_FILE, ' ', C_KEY}, @@ -495,7 +206,7 @@ static const struct LongShort aliases[]= { {"netrc-optional", ARG_BOOL, ' ', C_NETRC_OPTIONAL}, {"next", ARG_NONE, ':', C_NEXT}, {"noproxy", ARG_STRG, ' ', C_NOPROXY}, - {"npn", ARG_BOOL, ' ', C_NPN}, + {"npn", ARG_BOOL|ARG_NO, ' ', C_NPN}, {"ntlm", ARG_BOOL, ' ', C_NTLM}, {"ntlm-wb", ARG_BOOL, ' ', C_NTLM_WB}, {"oauth2-bearer", ARG_STRG, ' ', C_OAUTH2_BEARER}, @@ -512,7 +223,7 @@ static const struct LongShort aliases[]= { {"post303", ARG_BOOL, ' ', C_POST303}, {"preproxy", ARG_STRG, ' ', C_PREPROXY}, {"progress-bar", ARG_BOOL, '#', C_PROGRESS_BAR}, - {"progress-meter", ARG_BOOL, ' ', C_PROGRESS_METER}, + {"progress-meter", ARG_BOOL|ARG_NO, ' ', C_PROGRESS_METER}, {"proto", ARG_STRG, ' ', C_PROTO}, {"proto-default", ARG_STRG, ' ', C_PROTO_DEFAULT}, {"proto-redir", ARG_STRG, ' ', C_PROTO_REDIR}, @@ -570,9 +281,11 @@ static const struct LongShort aliases[]= { {"sasl-authzid", ARG_STRG, ' ', C_SASL_AUTHZID}, {"sasl-ir", ARG_BOOL, ' ', C_SASL_IR}, {"service-name", ARG_STRG, ' ', C_SERVICE_NAME}, - {"sessionid", ARG_BOOL, ' ', C_SESSIONID}, + {"sessionid", ARG_BOOL|ARG_NO, ' ', C_SESSIONID}, {"show-error", ARG_BOOL, 'S', C_SHOW_ERROR}, + {"show-headers", ARG_BOOL, 'i', C_SHOW_HEADERS}, {"silent", ARG_BOOL, 's', C_SILENT}, + {"skip-existing", ARG_BOOL, ' ', C_SKIP_EXISTING}, {"socks4", ARG_STRG, ' ', C_SOCKS4}, {"socks4a", ARG_STRG, ' ', C_SOCKS4A}, {"socks5", ARG_STRG, ' ', C_SOCKS5}, @@ -705,11 +418,11 @@ void parse_cert_parameter(const char *cert_parameter, } break; case ':': - /* Since we live in a world of weirdness and confusion, the win32 + /* Since we live in a world of weirdness and confusion, the Windows dudes can use : when using drive letters and thus c:\file:password needs to work. In order not to break compatibility, we still use : as separator, but we try to detect when it is used for a filename! On - windows. */ + Windows. */ #ifdef _WIN32 if((param_place == &cert_parameter[1]) && (cert_parameter[2] == '\\' || cert_parameter[2] == '/') && @@ -846,6 +559,9 @@ static void cleanarg(argv_item_t str) #define cleanarg(x) #endif +/* the maximum size we allow the dynbuf generated string */ +#define MAX_DATAURLENCODE (500*1024*1024) + /* --data-urlencode */ static ParameterError data_urlencode(struct GlobalConfig *global, char *nextarg, @@ -921,15 +637,22 @@ static ParameterError data_urlencode(struct GlobalConfig *global, char *n; replace_url_encoded_space_by_plus(enc); if(nlen > 0) { /* only append '=' if we have a name */ - n = aprintf("%.*s=%s", (int)nlen, nextarg, enc); - curl_free(enc); - if(!n) + struct curlx_dynbuf dyn; + curlx_dyn_init(&dyn, MAX_DATAURLENCODE); + if(curlx_dyn_addn(&dyn, nextarg, nlen) || + curlx_dyn_addn(&dyn, "=", 1) || + curlx_dyn_add(&dyn, enc)) { + curl_free(enc); return PARAM_NO_MEM; + } + curl_free(enc); + n = curlx_dyn_ptr(&dyn); + size = curlx_dyn_len(&dyn); } - else + else { n = enc; - - size = strlen(n); + size = strlen(n); + } postdata = n; } else @@ -1015,7 +738,7 @@ static int findarg(const void *a, const void *b) return strcmp(aa->lname, bb->lname); } -static const struct LongShort *single(char letter) +const struct LongShort *findshortopt(char letter) { static const struct LongShort *singles[128 - ' ']; /* ASCII => pointer */ static bool singles_done = FALSE; @@ -1230,6 +953,20 @@ static ParameterError set_rate(struct GlobalConfig *global, if(div) { char unit = div[1]; + curl_off_t numunits; + char *endp; + + if(curlx_strtoofft(&div[1], &endp, 10, &numunits)) { + /* if it fails, there is no legit number specified */ + if(endp == &div[1]) + /* if endp did not move, accept it as a 1 */ + numunits = 1; + else + return PARAM_BAD_USE; + } + else + unit = *endp; + switch(unit) { case 's': /* per second */ numerator = 1000; @@ -1247,6 +984,14 @@ static ParameterError set_rate(struct GlobalConfig *global, err = PARAM_BAD_USE; break; } + + if((LONG_MAX / numerator) < numunits) { + /* overflow, too large number */ + errorf(global, "too large --rate unit"); + err = PARAM_NUMBER_TOO_LARGE; + } + /* this typecast is okay based on the check above */ + numerator *= (long)numunits; } if(err) @@ -1259,6 +1004,15 @@ static ParameterError set_rate(struct GlobalConfig *global, return err; } +const struct LongShort *findlongopt(const char *opt) +{ + struct LongShort key; + key.lname = opt; + + return bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]), + sizeof(aliases[0]), findarg); +} + ParameterError getparameter(const char *flag, /* f or -long-flag */ char *nextarg, /* NULL if unset */ @@ -1273,6 +1027,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ time_t now; bool longopt = FALSE; bool singleopt = FALSE; /* when true means '-o foo' used '-ofoo' */ + size_t nopts = 0; /* options processed in `flag`*/ ParameterError err = PARAM_OK; bool toggle = TRUE; /* how to switch boolean options, on or off. Controlled by using --OPTION or --no-OPTION */ @@ -1300,7 +1055,6 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ const char *word = ('-' == flag[0]) ? flag + 2 : flag; bool noflagged = FALSE; bool expand = FALSE; - struct LongShort key; if(!strncmp(word, "no-", 3)) { /* disable this option but ignore the "no-" part when looking for it */ @@ -1313,10 +1067,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ word += 7; expand = TRUE; } - key.lname = word; - a = bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]), - sizeof(aliases[0]), findarg); + a = findlongopt(word); if(a) { longopt = TRUE; } @@ -1324,7 +1076,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ err = PARAM_OPTION_UNKNOWN; goto error; } - if(noflagged && (a->desc != ARG_BOOL)) { + if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) { /* --no- prefixed an option that is not boolean! */ err = PARAM_NO_NOT_BOOLEAN; goto error; @@ -1333,8 +1085,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ struct curlx_dynbuf nbuf; bool replaced; - if((a->desc != ARG_STRG) && - (a->desc != ARG_FILE)) { + if((ARGTYPE(a->desc) != ARG_STRG) && + (ARGTYPE(a->desc) != ARG_FILE)) { /* --expand on an option that is not a string or a filename */ err = PARAM_EXPAND_ERROR; goto error; @@ -1361,15 +1113,15 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ cmdline_t cmd; if(!longopt && !a) { - a = single(*parse); + a = findshortopt(*parse); if(!a) { err = PARAM_OPTION_UNKNOWN; break; } } letter = a->letter; - cmd = a->cmd; - if(a->desc >= ARG_STRG) { + cmd = (cmdline_t)a->cmd; + if(ARGTYPE(a->desc) >= ARG_STRG) { /* this option requires an extra parameter */ if(!longopt && parse[1]) { nextarg = (char *)&parse[1]; /* this is the actual extra parameter */ @@ -1386,19 +1138,19 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ *usedarg = TRUE; /* mark it as used */ } - if((a->desc == ARG_FILE) && + if((ARGTYPE(a->desc) == ARG_FILE) && (nextarg[0] == '-') && nextarg[1]) { /* if the filename looks like a command line option */ warnf(global, "The filename argument '%s' looks like a flag.", nextarg); } else if(!strncmp("\xe2\x80\x9c", nextarg, 3)) { - warnf(global, "The argument '%s' starts with a unicode quote where " + warnf(global, "The argument '%s' starts with a Unicode quote where " "maybe an ASCII \" was intended?", nextarg); } } - else if((a->desc == ARG_NONE) && !toggle) { + else if((ARGTYPE(a->desc) == ARG_NONE) && !toggle) { err = PARAM_NO_PREFIX; break; } @@ -2103,6 +1855,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ case C_URL_QUERY: /* --url-query */ err = url_query(nextarg, global, config); break; + case C_DUMP_CA_EMBED: /* --dump-ca-embed */ + err = PARAM_CA_EMBED_REQUESTED; + break; case C_DUMP_HEADER: /* --dump-header */ err = getstr(&config->headerfile, nextarg, DENY_BLANK); break; @@ -2410,7 +2165,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ &config->mimecurrent, (cmd == C_FORM_STRING)?TRUE:FALSE)) /* literal string */ err = PARAM_BAD_USE; - else if(SetHTTPrequest(config, HTTPREQ_MIMEPOST, &config->httpreq)) + else if(SetHTTPrequest(config, TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) err = PARAM_BAD_USE; break; case C_GLOBOFF: /* --globoff */ @@ -2477,6 +2232,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } break; case C_INCLUDE: /* --include */ + case C_SHOW_HEADERS: /* --show-headers */ config->show_headers = toggle; /* show the headers as well in the general output stream */ break; @@ -2487,7 +2243,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ config->no_body = toggle; config->show_headers = toggle; if(SetHTTPrequest(config, - (config->no_body)?HTTPREQ_HEAD:HTTPREQ_GET, + (config->no_body)?TOOL_HTTPREQ_HEAD:TOOL_HTTPREQ_GET, &config->httpreq)) err = PARAM_BAD_USE; break; @@ -2679,6 +2435,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ case C_SILENT: /* --silent */ global->silent = toggle; break; + case C_SKIP_EXISTING: /* --skip-existing */ + config->skip_existing = toggle; + break; case C_SHOW_ERROR: /* --show-error */ global->showerror = toggle; break; @@ -2730,8 +2489,27 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ cleanarg(clearthis); break; case C_VERBOSE: /* --verbose */ - if(toggle) { - /* the '%' thing here will cause the trace get sent to stderr */ + /* This option is a super-boolean with side effect when applied + * more than once in the same argument flag, like `-vvv`. */ + if(!toggle) { + global->verbosity = 0; + if(set_trace_config(global, "-all")) + err = PARAM_NO_MEM; + global->tracetype = TRACE_NONE; + break; + } + else if(!nopts) { + /* fist `-v` in an argument resets to base verbosity */ + global->verbosity = 0; + if(set_trace_config(global, "-all")) { + err = PARAM_NO_MEM; + break; + } + } + /* the '%' thing here will cause the trace get sent to stderr */ + switch(global->verbosity) { + case 0: + global->verbosity = 1; Curl_safefree(global->trace_dump); global->trace_dump = strdup("%"); if(!global->trace_dump) @@ -2739,13 +2517,30 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ else { if(global->tracetype && (global->tracetype != TRACE_PLAIN)) warnf(global, - "-v, --verbose overrides an earlier trace/verbose option"); + "-v, --verbose overrides an earlier trace option"); global->tracetype = TRACE_PLAIN; } + break; + case 1: + global->verbosity = 2; + if(set_trace_config(global, "ids,time,protocol")) + err = PARAM_NO_MEM; + break; + case 2: + global->verbosity = 3; + global->tracetype = TRACE_ASCII; + if(set_trace_config(global, "ssl,read,write")) + err = PARAM_NO_MEM; + break; + case 3: + global->verbosity = 4; + if(set_trace_config(global, "network")) + err = PARAM_NO_MEM; + break; + default: + /* no effect for now */ + break; } - else - /* verbose is disabled here */ - global->tracetype = TRACE_NONE; break; case C_VERSION: /* --version */ if(toggle) /* --no-version yields no output! */ @@ -2874,7 +2669,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ break; } a = NULL; - + ++nopts; /* processed one option from `flag` input, loop for more */ } while(!longopt && !singleopt && *++parse && !*usedarg && !err); error: @@ -2974,7 +2769,8 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, if(result && result != PARAM_HELP_REQUESTED && result != PARAM_MANUAL_REQUESTED && result != PARAM_VERSION_INFO_REQUESTED && - result != PARAM_ENGINES_REQUESTED) { + result != PARAM_ENGINES_REQUESTED && + result != PARAM_CA_EMBED_REQUESTED) { const char *reason = param2text(result); if(orig_opt && strcmp(":", orig_opt)) diff --git a/src/tool_getparam.h b/src/tool_getparam.h index 12a971d02..9d6c72ef8 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -25,6 +25,302 @@ ***************************************************************************/ #include "tool_setup.h" +/* one enum for every command line option. The name is the verbatim long + option name, but in uppercase with periods and minuses replaced with + underscores using a "C_" prefix. */ +typedef enum { + C_ABSTRACT_UNIX_SOCKET, + C_ALPN, + C_ALT_SVC, + C_ANYAUTH, + C_APPEND, + C_AWS_SIGV4, + C_BASIC, + C_BUFFER, + C_CA_NATIVE, + C_CACERT, + C_CAPATH, + C_CERT, + C_CERT_STATUS, + C_CERT_TYPE, + C_CIPHERS, + C_CLOBBER, + C_COMPRESSED, + C_COMPRESSED_SSH, + C_CONFIG, + C_CONNECT_TIMEOUT, + C_CONNECT_TO, + C_CONTINUE_AT, + C_COOKIE, + C_COOKIE_JAR, + C_CREATE_DIRS, + C_CREATE_FILE_MODE, + C_CRLF, + C_CRLFILE, + C_CURVES, + C_DATA, + C_DATA_ASCII, + C_DATA_BINARY, + C_DATA_RAW, + C_DATA_URLENCODE, + C_DELEGATION, + C_DIGEST, + C_DISABLE, + C_DISABLE_EPRT, + C_DISABLE_EPSV, + C_DISALLOW_USERNAME_IN_URL, + C_DNS_INTERFACE, + C_DNS_IPV4_ADDR, + C_DNS_IPV6_ADDR, + C_DNS_SERVERS, + C_DOH_CERT_STATUS, + C_DOH_INSECURE, + C_DOH_URL, + C_DUMP_CA_EMBED, + C_DUMP_HEADER, + C_ECH, + C_EGD_FILE, + C_ENGINE, + C_EPRT, + C_EPSV, + C_ETAG_COMPARE, + C_ETAG_SAVE, + C_EXPECT100_TIMEOUT, + C_FAIL, + C_FAIL_EARLY, + C_FAIL_WITH_BODY, + C_FALSE_START, + C_FORM, + C_FORM_ESCAPE, + C_FORM_STRING, + C_FTP_ACCOUNT, + C_FTP_ALTERNATIVE_TO_USER, + C_FTP_CREATE_DIRS, + C_FTP_METHOD, + C_FTP_PASV, + C_FTP_PORT, + C_FTP_PRET, + C_FTP_SKIP_PASV_IP, + C_FTP_SSL, + C_FTP_SSL_CCC, + C_FTP_SSL_CCC_MODE, + C_FTP_SSL_CONTROL, + C_FTP_SSL_REQD, + C_GET, + C_GLOBOFF, + C_HAPPY_EYEBALLS_TIMEOUT_MS, + C_HAPROXY_CLIENTIP, + C_HAPROXY_PROTOCOL, + C_HEAD, + C_HEADER, + C_HELP, + C_HOSTPUBMD5, + C_HOSTPUBSHA256, + C_HSTS, + C_HTTP0_9, + C_HTTP1_0, + C_HTTP1_1, + C_HTTP2, + C_HTTP2_PRIOR_KNOWLEDGE, + C_HTTP3, + C_HTTP3_ONLY, + C_IGNORE_CONTENT_LENGTH, + C_INCLUDE, + C_INSECURE, + C_INTERFACE, + C_IPFS_GATEWAY, + C_IPV4, + C_IPV6, + C_JSON, + C_JUNK_SESSION_COOKIES, + C_KEEPALIVE, + C_KEEPALIVE_CNT, + C_KEEPALIVE_TIME, + C_KEY, + C_KEY_TYPE, + C_KRB, + C_KRB4, + C_LIBCURL, + C_LIMIT_RATE, + C_LIST_ONLY, + C_LOCAL_PORT, + C_LOCATION, + C_LOCATION_TRUSTED, + C_LOGIN_OPTIONS, + C_MAIL_AUTH, + C_MAIL_FROM, + C_MAIL_RCPT, + C_MAIL_RCPT_ALLOWFAILS, + C_MANUAL, + C_MAX_FILESIZE, + C_MAX_REDIRS, + C_MAX_TIME, + C_METALINK, + C_MPTCP, + C_NEGOTIATE, + C_NETRC, + C_NETRC_FILE, + C_NETRC_OPTIONAL, + C_NEXT, + C_NOPROXY, + C_NPN, + C_NTLM, + C_NTLM_WB, + C_OAUTH2_BEARER, + C_OUTPUT, + C_OUTPUT_DIR, + C_PARALLEL, + C_PARALLEL_IMMEDIATE, + C_PARALLEL_MAX, + C_PASS, + C_PATH_AS_IS, + C_PINNEDPUBKEY, + C_POST301, + C_POST302, + C_POST303, + C_PREPROXY, + C_PROGRESS_BAR, + C_PROGRESS_METER, + C_PROTO, + C_PROTO_DEFAULT, + C_PROTO_REDIR, + C_PROXY, + C_PROXY_ANYAUTH, + C_PROXY_BASIC, + C_PROXY_CA_NATIVE, + C_PROXY_CACERT, + C_PROXY_CAPATH, + C_PROXY_CERT, + C_PROXY_CERT_TYPE, + C_PROXY_CIPHERS, + C_PROXY_CRLFILE, + C_PROXY_DIGEST, + C_PROXY_HEADER, + C_PROXY_HTTP2, + C_PROXY_INSECURE, + C_PROXY_KEY, + C_PROXY_KEY_TYPE, + C_PROXY_NEGOTIATE, + C_PROXY_NTLM, + C_PROXY_PASS, + C_PROXY_PINNEDPUBKEY, + C_PROXY_SERVICE_NAME, + C_PROXY_SSL_ALLOW_BEAST, + C_PROXY_SSL_AUTO_CLIENT_CERT, + C_PROXY_TLS13_CIPHERS, + C_PROXY_TLSAUTHTYPE, + C_PROXY_TLSPASSWORD, + C_PROXY_TLSUSER, + C_PROXY_TLSV1, + C_PROXY_USER, + C_PROXY1_0, + C_PROXYTUNNEL, + C_PUBKEY, + C_QUOTE, + C_RANDOM_FILE, + C_RANGE, + C_RATE, + C_RAW, + C_REFERER, + C_REMOTE_HEADER_NAME, + C_REMOTE_NAME, + C_REMOTE_NAME_ALL, + C_REMOTE_TIME, + C_REMOVE_ON_ERROR, + C_REQUEST, + C_REQUEST_TARGET, + C_RESOLVE, + C_RETRY, + C_RETRY_ALL_ERRORS, + C_RETRY_CONNREFUSED, + C_RETRY_DELAY, + C_RETRY_MAX_TIME, + C_SASL_AUTHZID, + C_SASL_IR, + C_SERVICE_NAME, + C_SESSIONID, + C_SHOW_ERROR, + C_SHOW_HEADERS, + C_SILENT, + C_SKIP_EXISTING, + C_SOCKS4, + C_SOCKS4A, + C_SOCKS5, + C_SOCKS5_BASIC, + C_SOCKS5_GSSAPI, + C_SOCKS5_GSSAPI_NEC, + C_SOCKS5_GSSAPI_SERVICE, + C_SOCKS5_HOSTNAME, + C_SPEED_LIMIT, + C_SPEED_TIME, + C_SSL, + C_SSL_ALLOW_BEAST, + C_SSL_AUTO_CLIENT_CERT, + C_SSL_NO_REVOKE, + C_SSL_REQD, + C_SSL_REVOKE_BEST_EFFORT, + C_SSLV2, + C_SSLV3, + C_STDERR, + C_STYLED_OUTPUT, + C_SUPPRESS_CONNECT_HEADERS, + C_TCP_FASTOPEN, + C_TCP_NODELAY, + C_TELNET_OPTION, + C_TEST_EVENT, + C_TFTP_BLKSIZE, + C_TFTP_NO_OPTIONS, + C_TIME_COND, + C_TLS_MAX, + C_TLS13_CIPHERS, + C_TLSAUTHTYPE, + C_TLSPASSWORD, + C_TLSUSER, + C_TLSV1, + C_TLSV1_0, + C_TLSV1_1, + C_TLSV1_2, + C_TLSV1_3, + C_TR_ENCODING, + C_TRACE, + C_TRACE_ASCII, + C_TRACE_CONFIG, + C_TRACE_IDS, + C_TRACE_TIME, + C_IP_TOS, + C_UNIX_SOCKET, + C_UPLOAD_FILE, + C_URL, + C_URL_QUERY, + C_USE_ASCII, + C_USER, + C_USER_AGENT, + C_VARIABLE, + C_VERBOSE, + C_VERSION, + C_VLAN_PRIORITY, + C_WDEBUG, + C_WRITE_OUT, + C_XATTR +} cmdline_t; + +#define ARG_NONE 0 /* stand-alone but not a boolean */ +#define ARG_BOOL 1 /* accepts a --no-[name] prefix */ +#define ARG_STRG 2 /* requires an argument */ +#define ARG_FILE 3 /* requires an argument, usually a filename */ + +#define ARG_TYPEMASK 0x03 +#define ARGTYPE(x) ((x) & ARG_TYPEMASK) + +#define ARG_NO 0x80 /* set if the option is documented as --no-* */ + +struct LongShort { + const char *lname; /* long name option */ + unsigned char desc; /* type, see ARG_* */ + char letter; /* short name option or ' ' */ + unsigned short cmd; +}; + typedef enum { PARAM_OK = 0, PARAM_OPTION_AMBIGUOUS, @@ -35,6 +331,7 @@ typedef enum { PARAM_MANUAL_REQUESTED, PARAM_VERSION_INFO_REQUESTED, PARAM_ENGINES_REQUESTED, + PARAM_CA_EMBED_REQUESTED, PARAM_GOT_EXTRA_PARAMETER, PARAM_BAD_NUMERIC, PARAM_NEGATIVE_NUMERIC, @@ -56,6 +353,9 @@ typedef enum { struct GlobalConfig; struct OperationConfig; +const struct LongShort *findlongopt(const char *opt); +const struct LongShort *findshortopt(char letter); + ParameterError getparameter(const char *flag, char *nextarg, argv_item_t cleararg, bool *usedarg, diff --git a/src/tool_help.c b/src/tool_help.c index a12626eff..8c655c4b2 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -22,8 +22,7 @@ * ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ + #include "curlx.h" #include "tool_help.h" @@ -31,6 +30,8 @@ #include "tool_util.h" #include "tool_version.h" #include "tool_cb_prg.h" +#include "tool_hugehelp.h" +#include "tool_getparam.h" #include "terminal.h" #include "memdebug.h" /* keep this as LAST include */ @@ -160,18 +161,90 @@ static void get_categories_list(unsigned int width) } } +#ifdef USE_MANUAL + +void inithelpscan(struct scan_ctx *ctx, + const char *trigger, + const char *arg, + const char *endarg) +{ + ctx->trigger = trigger; + ctx->tlen = strlen(trigger); + ctx->arg = arg; + ctx->flen = strlen(arg); + ctx->endarg = endarg; + ctx->elen = strlen(endarg); + DEBUGASSERT((ctx->elen < sizeof(ctx->rbuf)) || + (ctx->flen < sizeof(ctx->rbuf))); + ctx->show = 0; + ctx->olen = 0; + memset(ctx->rbuf, 0, sizeof(ctx->rbuf)); +} + +bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx) +{ + size_t i; + for(i = 0; i < len; i++) { + if(!ctx->show) { + /* wait for the trigger */ + memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->tlen - 1); + ctx->rbuf[ctx->tlen - 1] = buf[i]; + if(!memcmp(ctx->rbuf, ctx->trigger, ctx->tlen)) + ctx->show++; + continue; + } + /* past the trigger */ + if(ctx->show == 1) { + memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->flen - 1); + ctx->rbuf[ctx->flen - 1] = buf[i]; + if(!memcmp(ctx->rbuf, ctx->arg, ctx->flen)) { + /* match, now output until endarg */ + fputs(&ctx->arg[1], stdout); + ctx->show++; + } + continue; + } + /* show until the end */ + memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->elen - 1); + ctx->rbuf[ctx->elen - 1] = buf[i]; + if(!memcmp(ctx->rbuf, ctx->endarg, ctx->elen)) + return FALSE; + + if(buf[i] == '\n') { + DEBUGASSERT(ctx->olen < sizeof(ctx->obuf)); + if(ctx->olen == sizeof(ctx->obuf)) + return FALSE; /* bail out */ + ctx->obuf[ctx->olen++] = 0; + ctx->olen = 0; + puts(ctx->obuf); + } + else { + DEBUGASSERT(ctx->olen < sizeof(ctx->obuf)); + if(ctx->olen == sizeof(ctx->obuf)) + return FALSE; /* bail out */ + ctx->obuf[ctx->olen++] = buf[i]; + } + } + return TRUE; +} + +#endif void tool_help(char *category) { unsigned int cols = get_terminal_columns(); - puts("Usage: curl [options...] "); /* If no category was provided */ if(!category) { const char *category_note = "\nThis is not the full help; this " "menu is split into categories.\nUse \"--help category\" to get " "an overview of all categories, which are:"; - const char *category_note2 = "For all options use the manual" - " or \"--help all\"."; + const char *category_note2 = + "Use \"--help all\" to list all options" +#ifdef USE_MANUAL + "\nUse \"--help [option]\" to view documentation for a given option" +#endif + ; + puts("Usage: curl [options...] "); print_category(CURLHELP_IMPORTANT, cols); puts(category_note); get_categories_list(cols); @@ -184,6 +257,48 @@ void tool_help(char *category) /* Lets handle the string "category" differently to not print an errormsg */ else if(curl_strequal(category, "category")) get_categories(); + else if(category[0] == '-') { +#ifdef USE_MANUAL + /* command line option help */ + const struct LongShort *a = NULL; + if(category[1] == '-') { + char *lookup = &category[2]; + bool noflagged = FALSE; + if(!strncmp(lookup, "no-", 3)) { + lookup += 3; + noflagged = TRUE; + } + a = findlongopt(lookup); + if(a && noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) + /* a --no- prefix for a non-boolean is not specifying a proper + option */ + a = NULL; + } + else if(!category[2]) + a = findshortopt(category[1]); + if(!a) { + fprintf(tool_stderr, "Incorrect option name to show help for," + " see curl -h\n"); + } + else { + char cmdbuf[80]; + if(a->letter != ' ') + msnprintf(cmdbuf, sizeof(cmdbuf), "\n -%c, --", a->letter); + else if(a->desc & ARG_NO) + msnprintf(cmdbuf, sizeof(cmdbuf), "\n --no-%s", a->lname); + else + msnprintf(cmdbuf, sizeof(cmdbuf), "\n %s", category); + if(a->cmd == C_XATTR) + /* this is the last option, which then ends when FILES starts */ + showhelp("\nALL OPTIONS\n", cmdbuf, "\nFILES"); + else + showhelp("\nALL OPTIONS\n", cmdbuf, "\n -"); + } +#else + fprintf(tool_stderr, "Cannot comply. " + "This curl was built without built-in manual\n"); +#endif + } /* Otherwise print category and handle the case if the cat was not found */ else if(get_category_content(category, cols)) { puts("Unknown category provided, here is a list of all categories:\n"); @@ -244,10 +359,28 @@ void tool_version_info(void) puts(""); /* newline */ } if(feature_names[0]) { - printf("Features:"); - for(builtin = feature_names; *builtin; ++builtin) - printf(" %s", *builtin); - puts(""); /* newline */ + const char **feat_ext; + size_t feat_ext_count = feature_count; +#ifdef CURL_CA_EMBED + ++feat_ext_count; +#endif + feat_ext = malloc(sizeof(*feature_names) * (feat_ext_count + 1)); + if(feat_ext) { + memcpy((void *)feat_ext, feature_names, + sizeof(*feature_names) * feature_count); + feat_ext_count = feature_count; +#ifdef CURL_CA_EMBED + feat_ext[feat_ext_count++] = "CAcert"; +#endif + feat_ext[feat_ext_count] = NULL; + qsort((void *)feat_ext, feat_ext_count, sizeof(*feat_ext), + struplocompare4sort); + printf("Features:"); + for(builtin = feat_ext; *builtin; ++builtin) + printf(" %s", *builtin); + puts(""); /* newline */ + free((void *)feat_ext); + } } if(strcmp(CURL_VERSION, curlinfo->version)) { printf("WARNING: curl and libcurl versions do not match. " diff --git a/src/tool_help.h b/src/tool_help.h index 299da1db8..4b4071537 100644 --- a/src/tool_help.h +++ b/src/tool_help.h @@ -28,6 +28,24 @@ void tool_help(char *category); void tool_list_engines(void); void tool_version_info(void); +struct scan_ctx { + const char *trigger; + size_t tlen; + const char *arg; + size_t flen; + const char *endarg; + size_t elen; + size_t olen; + char rbuf[40]; + char obuf[160]; + unsigned char show; /* start as at 0. + trigger match moves it to 1 + arg match moves it to 2 + endarg stops the search */ +}; +void inithelpscan(struct scan_ctx *ctx, const char *trigger, + const char *arg, const char *endarg); +bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx); struct helptxt { const char *opt; diff --git a/src/tool_helpers.c b/src/tool_helpers.c index 0f9ac45a8..2e15144b7 100644 --- a/src/tool_helpers.c +++ b/src/tool_helpers.c @@ -25,8 +25,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -96,7 +94,7 @@ int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) "PUT (-T, --upload-file)" }; - if((*store == HTTPREQ_UNSPEC) || + if((*store == TOOL_HTTPREQ_UNSPEC) || (*store == req)) { *store = req; return 0; diff --git a/src/tool_hugehelp.c b/src/tool_hugehelp.c index 13ebe95ad..543c745ed 100644 --- a/src/tool_hugehelp.c +++ b/src/tool_hugehelp.c @@ -5,6 +5,8 @@ */ #ifdef USE_MANUAL #include "tool_hugehelp.h" +#include "tool_help.h" + static const char * const curlman[] = { "\t _ _ ____ _", " ___| | | | _ \\| |", @@ -75,13 +77,12 @@ static const char * const curlman[] = { " the variable \"name\" inserted, or a blank if the name does not exist as a", " variable. Insert \"{{\" verbatim in the string by prefixing it with a", " backslash, like \"\\{{\".", - "\n You an access and expand environment variables by first importing them.", - " You can select to either require the environment variable to be set or you", - " can provide a default value in case it is not already set. Plain", - " --variable %name imports the variable called 'name' but exits with an", - " error if that environment variable is not already set. To provide a", - " default value if it is not set, use --variable %name=content or --variable", - " %name@content.", + "\n You access and expand environment variables by first importing them. You", + " select to either require the environment variable to be set or you can", + " provide a default value in case it is not already set. Plain \"--variable", + " %name\" imports the variable called \"name\" but exits with an error if that", + " environment variable is not already set. To provide a default value if it", + " is not set, use \"--variable %name=content\" or \"--variable %name@content\".", "\n Example. Get the USER environment variable into the URL, fail if USER is", " not set:", "\n\t--variable '%USER'", @@ -180,7 +181,7 @@ static const char * const curlman[] = { " is your friend. You can also disable the progress meter completely with", " the --silent option.", "\nVERSION", - "\n This man page describes curl 8.9.1. If you use a later version, chances", + "\n This man page describes curl 8.10.0. If you use a later version, chances", " are this man page does not fully document it. If you use an earlier", " version, this document tries to include version information about which", " specific version that introduced changes.", @@ -210,6 +211,7 @@ static const char * const curlman[] = { " --parallel-immediate, --parallel-max, --parallel, --progress-bar, --rate,", " --show-error, --stderr, --styled-output, --trace-ascii, --trace-config,", " --trace-ids, --trace-time, --trace and --verbose.", + "\nALL OPTIONS", "\n --abstract-unix-socket ", "\t (HTTP) Connect through an abstract Unix domain socket, instead of", "\t using the network. Note: netstat shows the path of an abstract", @@ -269,7 +271,8 @@ static const char * const curlman[] = { "\t omitted from the endpoint. If --aws-sigv4 is provided several", "\t times, the last set value is used.", "\n\t Example:", - "\t curl --aws-sigv4 \"aws:amz:us-east-2:es\" --user \"key:secret\" https://example.com", + "\t curl --aws-sigv4 \"aws:amz:us-east-2:es\" --user \"key:secret\" \\", + "\t\t https://example.com", "\n\t Added in 7.75.0. See also --basic and --user.", "\n --basic", "\t (HTTP) Use HTTP Basic authentication with the remote host. This", @@ -294,7 +297,8 @@ static const char * const curlman[] = { "\t times has no extra effect. Disable it again with --no-ca-native.", "\n\t Example:", "\t curl --ca-native https://example.com", - "\n\t Added in 8.2.0. See also --cacert, --capath and --insecure.", + "\n\t Added in 8.2.0. See also --cacert, --capath, --dump-ca-embed and", + "\t --insecure.", "\n --cacert ", "\t (TLS) Use the specified certificate file to verify the peer. The", "\t file may contain multiple CA certificates. The certificate(s) must", @@ -304,7 +308,7 @@ static const char * const curlman[] = { "\t it is set and the TLS backend is not Schannel, and uses the given", "\t path as a path to a CA cert bundle. This option overrides that", "\t variable.", - "\n\t The windows version of curl automatically looks for a CA certs", + "\n\t The Windows version of curl automatically looks for a CA certs", "\t file named 'curl-ca-bundle.crt', either in the same directory as", "\t curl.exe, or in the Current Working Directory, or in any folder", "\t along your PATH.", @@ -322,7 +326,7 @@ static const char * const curlman[] = { "\t value is used.", "\n\t Example:", "\t curl --cacert CA-file.txt https://example.com", - "\n\t See also --capath and --insecure.", + "\n\t See also --capath, --dump-ca-embed and --insecure.", "\n --capath ", "\t (TLS) Use the specified certificate directory to verify the peer.", "\t Multiple paths can be provided by separated with colon (\":\") (e.g.", @@ -336,7 +340,7 @@ static const char * const curlman[] = { "\t --capath is provided several times, the last set value is used.", "\n\t Example:", "\t curl --capath /local/directory https://example.com", - "\n\t See also --cacert and --insecure.", + "\n\t See also --cacert, --dump-ca-embed and --insecure.", "\n -E, --cert ", "\t (TLS) Use the specified client certificate file when getting a", "\t file with HTTPS, FTPS or another SSL-based protocol. The", @@ -401,15 +405,17 @@ static const char * const curlman[] = { "\n\t Example:", "\t curl --cert-type PEM --cert file https://example.com", "\n\t See also --cert, --key and --key-type.", - "\n --ciphers ", - "\t (TLS) Specifies which ciphers to use in the connection. The list", - "\t of ciphers must specify valid ciphers. Read up on SSL cipher list", - "\t details on this URL:", + "\n --ciphers ", + "\t (TLS) Specifies which cipher suites to use in the connection if it", + "\t negotiates TLS 1.2 (1.1, 1.0). The list of ciphers suites must", + "\t specify valid ciphers. Read up on cipher suite details on this", + "\t URL:", "\n\t https://curl.se/docs/ssl-ciphers.html If --ciphers is provided", "\t several times, the last set value is used.", "\n\t Example:", - "\t curl --ciphers ECDHE-ECDSA-AES256-CCM8 https://example.com", - "\n\t See also --tlsv1.3, --tls13-ciphers and --proxy-ciphers.", + "\t curl --ciphers ECDHE-ECDSA-AES128-GCM-SHA256:\\", + "\t\t ECDHE-RSA-AES128-GCM-SHA256 https://example.com", + "\n\t See also --tls13-ciphers, --proxy-ciphers and --curves.", "\n --compressed", "\t (HTTP) Request a compressed response using one of the algorithms", "\t curl supports, and automatically decompress the content.", @@ -527,7 +533,8 @@ static const char * const curlman[] = { "\n\t\tcurl --connect-to ::127.0.0.1: http://example.com/", "\n\t --connect-to can be used several times in a command line", "\n\t Example:", - "\t curl --connect-to example.com:443:example.net:8443 https://example.com", + "\t curl --connect-to example.com:443:example.net:8443 \\", + "\t\t https://example.com", "\n\t See also --resolve and --header.", "\n -C, --continue-at ", "\t Resume a previous transfer from the given byte offset. The given", @@ -544,21 +551,22 @@ static const char * const curlman[] = { "\t curl -C 400 https://example.com", "\n\t See also --range.", "\n -b, --cookie ", - "\t (HTTP) Pass the data to the HTTP server in the Cookie header. It", - "\t is supposedly the data previously received from the server in a", - "\t \"Set-Cookie:\" line. The data should be in the format", - "\t \"NAME1=VALUE1; NAME2=VALUE2\" or as a single filename.", - "\n\t When given a set of specific cookies and not a filename, it makes", - "\t curl use the cookie header with this content explicitly in all", - "\t outgoing request(s). If multiple requests are done due to", - "\t authentication, followed redirects or similar, they all get this", - "\t cookie header passed on.", - "\n\t If no \"=\" symbol is used in the argument, it is instead treated as", - "\t a filename to read previously stored cookie from. This option also", - "\t activates the cookie engine which makes curl record incoming", - "\t cookies, which may be handy if you are using this in combination", - "\t with the --location option or do multiple URL transfers on the", - "\t same invoke.", + "\t (HTTP) This option has two slightly separate cookie sending", + "\t functions.", + "\n\t Either: pass the exact data to send to the HTTP server in the", + "\t Cookie header. It is supposedly data previously received from the", + "\t server in a \"Set-Cookie:\" line. The data should be in the format", + "\t \"NAME1=VALUE1; NAME2=VALUE2\". When given a set of specific", + "\t cookies, curl populates its cookie header with this content", + "\t explicitly in all outgoing request(s). If multiple requests are", + "\t done due to authentication, followed redirects or similar, they", + "\t all get this cookie header passed on.", + "\n\t Or: If no \"=\" symbol is used in the argument, it is instead", + "\t treated as a filename to read previously stored cookie from. This", + "\t option also activates the cookie engine which makes curl record", + "\t incoming cookies, which may be handy if you are using this in", + "\t combination with the --location option or do multiple URL", + "\t transfers on the same invoke.", "\n\t If the filename is a single minus (\"-\"), curl reads the contents", "\t from stdin. If the filename is an empty string (\"\") and is the", "\t only cookie input, curl activates the cookie engine without any", @@ -618,7 +626,7 @@ static const char * const curlman[] = { "\t combined with the path possibly set with --output-dir. If the", "\t combined output filename uses no directory, or if the directories", "\t it mentions already exist, no directories are created.", - "\n\t Created directories are made with mode 0750 on unix style file", + "\n\t Created directories are made with mode 0750 on Unix-style file", "\t systems.", "\n\t To create remote directories when using FTP or SFTP, try", "\t --ftp-create-dirs. Providing --create-dirs multiple times has no", @@ -709,9 +717,9 @@ static const char * const curlman[] = { "\t (HTTP) Post data exactly as specified with no extra processing", "\t whatsoever.", "\n\t If you start the data with the letter @, the rest should be a", - "\t filename. Data is posted in a similar manner as --data does,", - "\t except that newlines and carriage returns are preserved and", - "\t conversions are never done.", + "\t filename. \"@-\" makes curl read the data from stdin. Data is posted", + "\t in a similar manner as --data does, except that newlines and", + "\t carriage returns are preserved and conversions are never done.", "\n\t Like --data the default content-type sent to the server is", "\t application/x-www-form-urlencoded. If you want the data to be", "\t treated as arbitrary binary data by the server then set the", @@ -749,7 +757,8 @@ static const char * const curlman[] = { "\t\tname part is expected to be URL-encoded already.", "\n\t @filename", "\n\t\tload data from the given file (including any newlines),", - "\t\tURL-encode that data and pass it on in the POST.", + "\t\tURL-encode that data and pass it on in the POST. Using \"@-\"", + "\t\tmakes curl read the data from stdin.", "\n\t name@filename", "\n\t\tload data from the given file (including any newlines),", "\t\tURL-encode that data and pass it on in the POST. The name part", @@ -888,7 +897,8 @@ static const char * const curlman[] = { "\t GnuTLS backends. Providing --doh-cert-status multiple times has no", "\t extra effect. Disable it again with --no-doh-cert-status.", "\n\t Example:", - "\t curl --doh-cert-status --doh-url https://doh.example https://example.com", + "\t curl --doh-cert-status --doh-url https://doh.example \\", + "\t\t https://example.com", "\n\t Added in 7.76.0. See also --doh-insecure.", "\n --doh-insecure", "\t By default, every connection curl makes to a DoH server is", @@ -902,7 +912,8 @@ static const char * const curlman[] = { "\t multiple times has no extra effect. Disable it again with", "\t --no-doh-insecure.", "\n\t Example:", - "\t curl --doh-insecure --doh-url https://doh.example https://example.com", + "\t curl --doh-insecure --doh-url https://doh.example \\", + "\t\t https://example.com", "\n\t Added in 7.76.0. See also --doh-url, --insecure and", "\t --proxy-insecure.", "\n --doh-url ", @@ -913,17 +924,34 @@ static const char * const curlman[] = { "\t DoH since the name lookups take place over SSL. However, the", "\t certificate verification settings are not inherited but are", "\t controlled separately via --doh-insecure and --doh-cert-status.", + "\n\t By default, DoH is bypassed when initially looking up DNS records", + "\t of the DoH server. You can specify the IP address(es) of the DoH", + "\t server with --resolve to avoid this.", "\n\t This option is unset if an empty string \"\" is used as the URL.", "\t (Added in 7.85.0) If --doh-url is provided several times, the last", "\t set value is used.", - "\n\t Example:", + "\n\t Examples:", "\t curl --doh-url https://doh.example https://example.com", + "\t curl --doh-url https://doh.example --resolve \\", + "\t\t doh.example:443:192.0.2.1 https://example.com", "\n\t Added in 7.62.0. See also --doh-insecure.", + "\n --dump-ca-embed", + "\t (TLS) Write the CA bundle embedded in curl to standard output,", + "\t then quit.", + "\n\t If curl was not built with a default CA bundle embedded, the", + "\t output is empty. Providing --dump-ca-embed multiple times has no", + "\t extra effect. Disable it again with --no-dump-ca-embed.", + "\n\t Example:", + "\t curl --dump-ca-embed", + "\n\t Added in 8.10.0. See also --ca-native, --cacert, --capath,", + "\t --proxy-ca-native, --proxy-cacert and --proxy-capath.", "\n -D, --dump-header ", "\t (HTTP FTP) Write the received protocol headers to the specified", "\t file. If no headers are received, the use of this option creates", - "\t an empty file. Specify \"-\" as file name (a single minus) to have", - "\t it written to stdout.", + "\t an empty file. Specify \"-\" as filename (a single minus) to have it", + "\t written to stdout.", + "\n\t Starting in curl 8.10.0, specify \"%\" (a single percent sign) as", + "\t filename writes the output to stderr.", "\n\t When used in FTP, the FTP server response lines are considered", "\t being \"headers\" and thus are saved there.", "\n\t Having multiple transfers in one set of operations (i.e. the URLs", @@ -1006,10 +1034,10 @@ static const char * const curlman[] = { "\t header in its request. By default curl waits one second. This", "\t option accepts decimal values. When curl stops waiting, it", "\t continues as if a response was received.", - "\n\t The decimal value needs to provided using a dot (\".\") as decimal", - "\t separator - not the local version even if it might be using", - "\t another separator. If --expect100-timeout is provided several", - "\t times, the last set value is used.", + "\n\t The decimal value needs to be provided using a dot (\".\") as", + "\t decimal separator - not the local version even if it might be", + "\t using another separator. If --expect100-timeout is provided", + "\t several times, the last set value is used.", "\n\t Example:", "\t curl --expect100-timeout 2.5 -T file https://example.com", "\n\t See also --connect-timeout.", @@ -1075,7 +1103,7 @@ static const char * const curlman[] = { "\t verifying the server's Finished message, thus saving a round trip", "\t when performing a full handshake.", "\n\t This functionality is currently only implemented in the Secure", - "\t Transport (on iOS 7.0 or later, or OS X 10.9 or later) backend.", + "\t Transport (on iOS 7.0 or later, or macOS 10.9 or later) backend.", "\t Providing --false-start multiple times has no extra effect.", "\t Disable it again with --no-false-start.", "\n\t Example:", @@ -1123,15 +1151,18 @@ static const char * const curlman[] = { "\n\t\tcurl -F \"file=@localfile;filename=nameinpost\" example.com", "\n\t If filename/path contains ',' or ';', it must be quoted by", "\t double-quotes like:", - "\n\t\tcurl -F \"file=@\\\"local,file\\\";filename=\\\"name;in;post\\\"\" example.com", + "\n\t\tcurl -F \"file=@\\\"local,file\\\";filename=\\\"name;in;post\\\"\" \\", + "\t\t https://example.com", "\n\t or", - "\n\t\tcurl -F 'file=@\"local,file\";filename=\"name;in;post\"' example.com", + "\n\t\tcurl -F 'file=@\"local,file\";filename=\"name;in;post\"' \\", + "\t\t https://example.com", "\n\t Note that if a filename/path is quoted by double-quotes, any", "\t double-quote or backslash within the filename must be escaped by", "\t backslash.", "\n\t Quoting must also be applied to non-file data if it contains", "\t semicolons, leading/trailing spaces or leading double quotes:", - "\n\t\tcurl -F 'colors=\"red; green; blue\";type=text/x-myapp' example.com", + "\n\t\tcurl -F 'colors=\"red; green; blue\";type=text/x-myapp' \\", + "\t\t https://example.com", "\n\t You can add custom headers to the field by setting headers=, like", "\n\t\tcurl -F \"submit=OK;headers=\\\"X-submit-type: OK\\\"\" example.com", "\n\t or", @@ -1175,7 +1206,8 @@ static const char * const curlman[] = { "\n\t See further examples and details in the MANUAL. --form can be used", "\t several times in a command line", "\n\t Example:", - "\t curl --form \"name=curl\" --form \"file=@loadthis\" https://example.com", + "\t curl --form \"name=curl\" --form \"file=@loadthis\" \\", + "\t\t https://example.com", "\n\t This option is mutually exclusive with --data, --head and", "\t --upload-file. See also --data, --form-string and --form-escape.", "\n --form-escape", @@ -1184,7 +1216,8 @@ static const char * const curlman[] = { "\t --form-escape is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --form-escape -F 'field\\name=curl' -F 'file=@load\"this' https://example.com", + "\t curl --form-escape -F 'field\\name=curl' -F 'file=@load\"this' \\", + "\t\t https://example.com", "\n\t Added in 7.81.0. See also --form.", "\n --form-string ", "\t (HTTP SMTP IMAP) Similar to --form except that the value string", @@ -1472,16 +1505,27 @@ static const char * const curlman[] = { "\t curl -H \"Host:\" https://example.com", "\t curl -H @headers.txt https://example.com", "\n\t See also --user-agent and --referer.", - "\n -h, --help ", - "\t Usage help. List all curl command line options within the given", - "\t category.", + "\n -h, --help ", + "\t Usage help. Provide help for the subject given as an optional", + "\t argument.", "\n\t If no argument is provided, curl displays the most important", "\t command line arguments.", - "\n\t For category all, curl displays help for all options.", - "\n\t If category is specified, curl displays all available help", + "\n\t The argument can either be a category or a command line option.", + "\t When a category is provided, curl shows all command line options", + "\t within the given category. Specify category \"all\" to list all", + "\t available options.", + "\n\t If \"category\" is specified, curl displays all available help", "\t categories.", - "\n\t Example:", + "\n\t If the provided subject is instead an existing command line", + "\t option, specified either in its short form with a single dash and", + "\t a single letter, or in the long form with two dashes and a longer", + "\t name, curl displays a help text for that option in the terminal.", + "\n\t The help output is extensive for some options.", + "\n\t If the provided command line option is not known, curl says so.", + "\n\t Examples:", "\t curl --help all", + "\t curl --help --insecure", + "\t curl --help -f", "\n\t See also --verbose.", "\n --hostpubmd5 ", "\t (SFTP SCP) Pass a string containing 32 hexadecimal digits. The", @@ -1490,7 +1534,8 @@ static const char * const curlman[] = { "\t checksums match. If --hostpubmd5 is provided several times, the", "\t last set value is used.", "\n\t Example:", - "\t curl --hostpubmd5 e5c1c49020640a5ab0f2034854c321a8 sftp://example.com/", + "\t curl --hostpubmd5 e5c1c49020640a5ab0f2034854c321a8 \\", + "\t\t sftp://example.com/", "\n\t See also --hostpubsha256.", "\n --hostpubsha256 ", "\t (SFTP SCP) Pass a string containing a Base64-encoded SHA256 hash", @@ -1500,7 +1545,8 @@ static const char * const curlman[] = { "\t not work with other SSH backends. If --hostpubsha256 is provided", "\t several times, the last set value is used.", "\n\t Example:", - "\t curl --hostpubsha256 NDVkMTQxMGQ1ODdmMjQ3MjczYjAyOTY5MmRkMjVmNDQ= sftp://example.com/", + "\t curl --hostpubsha256 NDVkMTQxMGQ1ODdmMjQ3MjczYjAyOTY5MmRkMjVmNDQ=\\", + "\t\t sftp://example.com/", "\n\t Added in 7.80.0. See also --hostpubmd5.", "\n --hsts ", "\t (HTTPS) Enable HSTS for the transfer. If the filename points to an", @@ -1568,8 +1614,12 @@ static const char * const curlman[] = { "\t HTTP/1.1 Upgrade. It requires prior knowledge that the server", "\t supports HTTP/2 straight away. HTTPS requests still do HTTP/2 the", "\t standard way with negotiated protocol version in the TLS", - "\t handshake. Providing --http2-prior-knowledge multiple times has no", - "\t extra effect. Disable it again with --no-http2-prior-knowledge.", + "\t handshake.", + "\n\t Since 8.10.0 if this option is set for an HTTPS request then the", + "\t application layer protocol version (ALPN) offered to the server is", + "\t only HTTP/2. Prior to that both HTTP/1.1 and HTTP/2 were offered.", + "\t Providing --http2-prior-knowledge multiple times has no extra", + "\t effect. Disable it again with --no-http2-prior-knowledge.", "\n\t Example:", "\t curl --http2-prior-knowledge https://example.com", "\n\t --http2-prior-knowledge requires that libcurl is built to support", @@ -1577,15 +1627,17 @@ static const char * const curlman[] = { "\t --http1.0, --http2 and --http3. See also --http2 and --http3.", "\n --http3", "\t (HTTP) Attempt HTTP/3 to the host in the URL, but fallback to", - "\t earlier HTTP versions if the HTTP/3 connection establishment", - "\t fails. HTTP/3 is only available for HTTPS and not for HTTP URLs.", + "\t earlier HTTP versions if the HTTP/3 connection establishment fails", + "\t or is slow. HTTP/3 is only available for HTTPS and not for HTTP", + "\t URLs.", "\n\t This option allows a user to avoid using the Alt-Svc method of", - "\t upgrading to HTTP/3 when you know that the target speaks HTTP/3 on", - "\t the given host and port.", + "\t upgrading to HTTP/3 when you know or suspect that the target", + "\t speaks HTTP/3 on the given host and port.", "\n\t When asked to use HTTP/3, curl issues a separate attempt to use", "\t older HTTP versions with a slight delay, so if the HTTP/3 transfer", "\t fails or is slow, curl still tries to proceed with an older HTTP", - "\t version.", + "\t version. The fallback performs the regular negotiation between", + "\t HTTP/1 and HTTP/2.", "\n\t Use --http3-only for similar functionality without a fallback.", "\t Providing --http3 multiple times has no extra effect.", "\n\t Example:", @@ -1624,17 +1676,6 @@ static const char * const curlman[] = { "\n\t Example:", "\t curl --ignore-content-length https://example.com", "\n\t See also --ftp-skip-pasv-ip.", - "\n -i, --include", - "\t (HTTP FTP) Include response headers in the output. HTTP response", - "\t headers can include things like server name, cookies, date of the", - "\t document, HTTP version and more... With non-HTTP protocols, the", - "\t \"headers\" are other server communication.", - "\n\t To view the request headers, consider the --verbose option.", - "\t Providing --include multiple times has no extra effect. Disable it", - "\t again with --no-include.", - "\n\t Example:", - "\t curl -i https://example.com", - "\n\t See also --verbose.", "\n -k, --insecure", "\t (TLS SFTP SCP) By default, every secure connection curl makes is", "\t verified to be secure before the transfer takes place. This option", @@ -1707,7 +1748,8 @@ static const char * const curlman[] = { "\t holding the gateway URL exists.", "\n\t If you run a local IPFS node, this gateway is by default available", "\t under \"http://localhost:8080\". A full example URL would look like:", - "\n\t\tcurl --ipfs-gateway http://localhost:8080 ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi", + "\n\t\tcurl --ipfs-gateway http://localhost:8080 \\", + "\t\t ipfs://bafybeigagd5nmnn2iys2f3", "\n\t There are many public IPFS gateways. See for example:", "\t https://ipfs.github.io/public-gateway-checker/", "\n\t If you opt to go for a remote gateway you need to be aware that", @@ -1921,12 +1963,12 @@ static const char * const curlman[] = { "\t (HTTP) If the server reports that the requested page has moved to", "\t a different location (indicated with a Location: header and a 3XX", "\t response code), this option makes curl redo the request on the new", - "\t place. If used together with --include or --head, headers from all", - "\t requested pages are shown.", - "\n\t When authentication is used, curl only sends its credentials to", - "\t the initial host. If a redirect takes curl to a different host, it", - "\t does not get the user+password pass on. See also", - "\t --location-trusted on how to change this.", + "\t place. If used together with --show-headers or --head, headers", + "\t from all requested pages are shown.", + "\n\t When authentication is used, or send cookie with \"-H Cookie:\",", + "\t curl only sends its credentials to the initial host. If a redirect", + "\t takes curl to a different host, it does not get the credentials", + "\t pass on. See --location-trusted on how to change this.", "\n\t Limit the amount of redirects to follow by using the --max-redirs", "\t option.", "\n\t When curl follows a redirect and if the request is a POST, it", @@ -1944,15 +1986,20 @@ static const char * const curlman[] = { "\t curl -L https://example.com", "\n\t See also --resolve and --alt-svc.", "\n --location-trusted", - "\t (HTTP) Like --location, but allows sending the name + password to", - "\t all hosts that the site may redirect to. This may or may not", - "\t introduce a security breach if the site redirects you to a site to", - "\t which you send your authentication info (which is clear-text in", - "\t the case of HTTP Basic authentication). Providing", - "\t --location-trusted multiple times has no extra effect. Disable it", - "\t again with --no-location-trusted.", - "\n\t Example:", + "\t (HTTP) Instructs curl to like --location follow HTTP redirects,", + "\t but permits it to send credentials and other secrets along to", + "\t other hosts than the initial one.", + "\n\t This may or may not introduce a security breach if the site", + "\t redirects you to a site to which you send this sensitive data to.", + "\t Another host means that one or more of hostname, protocol scheme", + "\t or port number changed.", + "\n\t This option also allows curl to pass long cookies set explicitly", + "\t with --header. Providing --location-trusted multiple times has no", + "\t extra effect. Disable it again with --no-location-trusted.", + "\n\t Examples:", "\t curl --location-trusted -u user:password https://example.com", + "\t curl --location-trusted -H \"Cookie: session=abc\" \\", + "\t\t https://example.com", "\n\t See also --user.", "\n --login-options ", "\t (IMAP LDAP POP3 SMTP) Specify the login options to use during", @@ -2015,7 +2062,8 @@ static const char * const curlman[] = { "\t --mail-rcpt-allowfails multiple times has no extra effect. Disable", "\t it again with --no-mail-rcpt-allowfails.", "\n\t Example:", - "\t curl --mail-rcpt-allowfails --mail-rcpt dest@example.com smtp://example.com", + "\t curl --mail-rcpt-allowfails --mail-rcpt dest@example.com \\", + "\t\t smtp://example.com", "\n\t Added in 7.69.0. See also --mail-rcpt.", "\n -M, --manual", "\t Manual. Display the huge help text.", @@ -2023,9 +2071,11 @@ static const char * const curlman[] = { "\t curl --manual", "\n\t See also --verbose, --libcurl and --trace.", "\n --max-filesize ", - "\t (FTP HTTP MQTT) Specify the maximum size (in bytes) of a file to", - "\t download. If the file requested is larger than this value, the", - "\t transfer does not start and curl returns with exit code 63.", + "\t (FTP HTTP MQTT) When set to a non-zero value, it specifies the", + "\t maximum size (in bytes) of a file to download. If the file", + "\t requested is larger than this value, the transfer does not start", + "\t and curl returns with exit code 63.", + "\n\t Setting the maximum value to zero disables the limit.", "\n\t A size modifier may be used. For example, Appending 'k' or 'K'", "\t counts the number as kilobytes, 'm' or 'M' makes it megabytes,", "\t while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.", @@ -2054,7 +2104,7 @@ static const char * const curlman[] = { "\n\t If you enable retrying the transfer (--retry) then the maximum", "\t time counter is reset each time the transfer is retried. You can", "\t use --retry-max-time to limit the retry time.", - "\n\t The decimal value needs to provided using a dot (.) as decimal", + "\n\t The decimal value needs to be provided using a dot (.) as decimal", "\t separator - not the local version even if it might be using", "\t another separator. If --max-time is provided several times, the", "\t last set value is used.", @@ -2361,7 +2411,8 @@ static const char * const curlman[] = { "\t use of --next. Providing --parallel multiple times has no extra", "\t effect. Disable it again with --no-parallel.", "\n\t Example:", - "\t curl --parallel https://example.com -o file1 https://example.com -o file2", + "\t curl --parallel https://example.com -o file1 https://example.com \\", + "\t\t -o file2", "\n\t Added in 7.66.0. See also --next, --verbose, --parallel-max and", "\t --parallel-immediate.", "\n --parallel-immediate", @@ -2377,7 +2428,8 @@ static const char * const curlman[] = { "\t use of --next. Providing --parallel-immediate multiple times has", "\t no extra effect. Disable it again with --no-parallel-immediate.", "\n\t Example:", - "\t curl --parallel-immediate -Z https://example.com -o file1 https://example.com -o file2", + "\t curl --parallel-immediate -Z https://example.com -o file1 \\", + "\t\t https://example.com -o file2", "\n\t Added in 7.68.0. See also --parallel and --parallel-max.", "\n --parallel-max ", "\t When asked to do parallel transfers, using --parallel, this option", @@ -2426,7 +2478,8 @@ static const char * const curlman[] = { "\t several times, the last set value is used.", "\n\t Examples:", "\t curl --pinnedpubkey keyfile https://example.com", - "\t curl --pinnedpubkey 'sha256//ce118b51897f4452dc' https://example.com", + "\t curl --pinnedpubkey 'sha256//ce118b51897f4452dc' \\", + "\t\t https://example.com", "\n\t See also --hostpubsha256.", "\n --post301", "\t (HTTP) Respect RFC 7231/6.4.2 and do not convert POST requests", @@ -2478,7 +2531,8 @@ static const char * const curlman[] = { "\t such as @ by using %40 or pass in a colon with %3a. If --preproxy", "\t is provided several times, the last set value is used.", "\n\t Example:", - "\t curl --preproxy socks5://proxy.example -x http://http.example https://example.com", + "\t curl --preproxy socks5://proxy.example -x http://http.example \\", + "\t\t https://example.com", "\n\t See also --proxy and --socks5.", "\n -#, --progress-bar", "\t Make curl display transfer progress as a simple progress bar", @@ -2557,7 +2611,7 @@ static const char * const curlman[] = { "\t for the host part. e.g. socks5h://localhost/path/to/socket.sock", "\n\t HTTPS proxy support works set with the https:// protocol prefix", "\t for OpenSSL and GnuTLS. It also works for BearSSL, mbedTLS,", - "\t rustls, Schannel, Secure Transport and wolfSSL (added in 7.87.0).", + "\t Rustls, Schannel, Secure Transport and wolfSSL (added in 7.87.0).", "\n\t Unrecognized and unsupported proxy protocols cause an error.", "\t Ancient curl versions ignored unknown schemes and used http://", "\t instead.", @@ -2589,7 +2643,8 @@ static const char * const curlman[] = { "\t request/response round-trip. Providing --proxy-anyauth multiple", "\t times has no extra effect.", "\n\t Example:", - "\t curl --proxy-anyauth --proxy-user user:passwd -x proxy https://example.com", + "\t curl --proxy-anyauth --proxy-user user:passwd -x proxy \\", + "\t\t https://example.com", "\n\t See also --proxy, --proxy-basic and --proxy-digest.", "\n --proxy-basic", "\t Use HTTP Basic authentication when communicating with the given", @@ -2597,7 +2652,8 @@ static const char * const curlman[] = { "\t Basic is the default authentication method curl uses with proxies.", "\t Providing --proxy-basic multiple times has no extra effect.", "\n\t Example:", - "\t curl --proxy-basic --proxy-user user:passwd -x proxy https://example.com", + "\t curl --proxy-basic --proxy-user user:passwd -x proxy \\", + "\t\t https://example.com", "\n\t See also --proxy, --proxy-anyauth and --proxy-digest.", "\n --proxy-ca-native", "\t (TLS) Use the CA store from the native operating system to verify", @@ -2612,7 +2668,8 @@ static const char * const curlman[] = { "\t --no-proxy-ca-native.", "\n\t Example:", "\t curl --proxy-ca-native https://example.com", - "\n\t Added in 8.2.0. See also --cacert, --capath and --insecure.", + "\n\t Added in 8.2.0. See also --cacert, --capath, --dump-ca-embed and", + "\t --insecure.", "\n --proxy-cacert ", "\t Use the specified certificate file to verify the HTTPS proxy. The", "\t file may contain multiple CA certificates. The certificate(s) must", @@ -2623,8 +2680,10 @@ static const char * const curlman[] = { "\t --proxy-cacert is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-cacert CA-file.txt -x https://proxy https://example.com", - "\n\t See also --proxy-capath, --cacert, --capath and --proxy.", + "\t curl --proxy-cacert CA-file.txt -x https://proxy \\", + "\t\t https://example.com", + "\n\t See also --proxy-capath, --cacert, --capath, --dump-ca-embed and", + "\t --proxy.", "\n --proxy-capath ", "\t Same as --capath but used in HTTPS proxy context.", "\n\t Use the specified certificate directory to verify the proxy.", @@ -2639,8 +2698,9 @@ static const char * const curlman[] = { "\t --proxy-capath is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-capath /local/directory -x https://proxy https://example.com", - "\n\t See also --proxy-cacert, --proxy and --capath.", + "\t curl --proxy-capath /local/directory -x https://proxy \\", + "\t\t https://example.com", + "\n\t See also --proxy-cacert, --proxy, --capath and --dump-ca-embed.", "\n --proxy-cert ", "\t Use the specified client certificate file when communicating with", "\t an HTTPS proxy. The certificate must be in PKCS#12 format if using", @@ -2663,18 +2723,22 @@ static const char * const curlman[] = { "\t --proxy-cert-type is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-cert-type PEM --proxy-cert file -x https://proxy https://example.com", + "\t curl --proxy-cert-type PEM --proxy-cert file -x https://proxy \\", + "\t\t https://example.com", "\n\t See also --proxy-cert and --proxy-key.", "\n --proxy-ciphers ", - "\t Same as --ciphers but used in HTTPS proxy context.", - "\n\t Specifies which ciphers to use in the connection to the HTTPS", - "\t proxy. The list of ciphers must specify valid ciphers. Read up on", - "\t SSL cipher list details on this URL:", + "\t (TLS) Same as --ciphers but used in HTTPS proxy context.", + "\n\t Specify which cipher suites to use in the connection to your HTTPS", + "\t proxy when it negotiates TLS 1.2 (1.1, 1.0). The list of ciphers", + "\t suites must specify valid ciphers. Read up on cipher suite details", + "\t on this URL:", "\n\t https://curl.se/docs/ssl-ciphers.html If --proxy-ciphers is", "\t provided several times, the last set value is used.", "\n\t Example:", - "\t curl --proxy-ciphers ECDHE-ECDSA-AES256-CCM8 -x https://proxy https://example.com", - "\n\t See also --ciphers, --curves and --proxy.", + "\t curl --proxy-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:\\", + "\t\t ECDHE-RSA-AES128-GCM-SHA256 -x https://proxy \\", + "\t\t https://example.com", + "\n\t See also --proxy-tls13-ciphers, --ciphers and --proxy.", "\n --proxy-crlfile ", "\t Provide filename for a PEM formatted file with a Certificate", "\t Revocation List that specifies peer certificates that are", @@ -2683,14 +2747,16 @@ static const char * const curlman[] = { "\t --proxy-crlfile is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-crlfile rejects.txt -x https://proxy https://example.com", + "\t curl --proxy-crlfile rejects.txt -x https://proxy \\", + "\t\t https://example.com", "\n\t See also --crlfile and --proxy.", "\n --proxy-digest", "\t Use HTTP Digest authentication when communicating with the given", "\t proxy. Use --digest for enabling HTTP Digest with a remote host.", "\t Providing --proxy-digest multiple times has no extra effect.", "\n\t Example:", - "\t curl --proxy-digest --proxy-user user:passwd -x proxy https://example.com", + "\t curl --proxy-digest --proxy-user user:passwd -x proxy \\", + "\t\t https://example.com", "\n\t See also --proxy, --proxy-anyauth and --proxy-basic.", "\n --proxy-header
", "\t (HTTP) Extra header to include in the request when sending HTTP to", @@ -2711,8 +2777,10 @@ static const char * const curlman[] = { "\t multiple headers. --proxy-header can be used several times in a", "\t command line", "\n\t Examples:", - "\t curl --proxy-header \"X-First-Name: Joe\" -x http://proxy https://example.com", - "\t curl --proxy-header \"User-Agent: surprise\" -x http://proxy https://example.com", + "\t curl --proxy-header \"X-First-Name: Joe\" -x http://proxy \\", + "\t\t https://example.com", + "\t curl --proxy-header \"User-Agent: surprise\" -x http://proxy \\", + "\t\t https://example.com", "\t curl --proxy-header \"Host:\" -x http://proxy https://example.com", "\n\t See also --proxy.", "\n --proxy-http2", @@ -2758,7 +2826,8 @@ static const char * const curlman[] = { "\t --proxy-key-type is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-key-type DER --proxy-key here -x https://proxy https://example.com", + "\t curl --proxy-key-type DER --proxy-key here -x https://proxy \\", + "\t\t https://example.com", "\n\t See also --proxy-key and --proxy.", "\n --proxy-negotiate", "\t Use HTTP Negotiate (SPNEGO) authentication when communicating with", @@ -2766,14 +2835,16 @@ static const char * const curlman[] = { "\t (SPNEGO) with a remote host. Providing --proxy-negotiate multiple", "\t times has no extra effect.", "\n\t Example:", - "\t curl --proxy-negotiate --proxy-user user:passwd -x proxy https://example.com", + "\t curl --proxy-negotiate --proxy-user user:passwd -x proxy \\", + "\t\t https://example.com", "\n\t See also --proxy-anyauth, --proxy-basic and --proxy-service-name.", "\n --proxy-ntlm", "\t Use HTTP NTLM authentication when communicating with the given", "\t proxy. Use --ntlm for enabling NTLM with a remote host. Providing", "\t --proxy-ntlm multiple times has no extra effect.", "\n\t Example:", - "\t curl --proxy-ntlm --proxy-user user:passwd -x http://proxy https://example.com", + "\t curl --proxy-ntlm --proxy-user user:passwd -x http://proxy \\", + "\t\t https://example.com", "\n\t See also --proxy-negotiate, --proxy-anyauth and --proxy-user.", "\n --proxy-pass ", "\t Passphrase for the private key for HTTPS proxy client certificate.", @@ -2781,7 +2852,8 @@ static const char * const curlman[] = { "\t --proxy-pass is provided several times, the last set value is", "\t used.", "\n\t Example:", - "\t curl --proxy-pass secret --proxy-key here -x https://proxy https://example.com", + "\t curl --proxy-pass secret --proxy-key here -x https://proxy \\", + "\t\t https://example.com", "\n\t See also --proxy and --proxy-key.", "\n --proxy-pinnedpubkey ", "\t (TLS) Use the specified public key file (or hashes) to verify the", @@ -2792,18 +2864,22 @@ static const char * const curlman[] = { "\t certificate indicating its identity. A public key is extracted", "\t from this certificate and if it does not exactly match the public", "\t key provided to this option, curl aborts the connection before", - "\t sending or receiving any data. If --proxy-pinnedpubkey is provided", - "\t several times, the last set value is used.", + "\t sending or receiving any data.", + "\n\t Before curl 8.10.0 this option did not work due to a bug. If", + "\t --proxy-pinnedpubkey is provided several times, the last set value", + "\t is used.", "\n\t Examples:", "\t curl --proxy-pinnedpubkey keyfile https://example.com", - "\t curl --proxy-pinnedpubkey 'sha256//ce118b51897f4452dc' https://example.com", + "\t curl --proxy-pinnedpubkey 'sha256//ce118b51897f4452dc' \\", + "\t\t https://example.com", "\n\t See also --pinnedpubkey and --proxy.", "\n --proxy-service-name ", "\t Set the service name for SPNEGO when doing proxy authentication.", "\t If --proxy-service-name is provided several times, the last set", "\t value is used.", "\n\t Example:", - "\t curl --proxy-service-name \"shrubbery\" -x proxy https://example.com", + "\t curl --proxy-service-name \"shrubbery\" -x proxy \\", + "\t\t https://example.com", "\n\t See also --service-name, --proxy and --proxy-negotiate.", "\n --proxy-ssl-allow-beast", "\t Do not work around a security flaw in the TLS1.0 protocol known as", @@ -2826,23 +2902,27 @@ static const char * const curlman[] = { "\t --proxy-ssl-auto-client-cert multiple times has no extra effect.", "\t Disable it again with --no-proxy-ssl-auto-client-cert.", "\n\t Example:", - "\t curl --proxy-ssl-auto-client-cert -x https://proxy https://example.com", + "\t curl --proxy-ssl-auto-client-cert -x https://proxy \\", + "\t\t https://example.com", "\n\t Added in 7.77.0. See also --ssl-auto-client-cert and --proxy.", - "\n --proxy-tls13-ciphers ", - "\t (TLS) Specify which cipher suites to use in the connection to your", - "\t HTTPS proxy when it negotiates TLS 1.3. The list of ciphers suites", - "\t must specify valid ciphers. Read up on TLS 1.3 cipher suite", - "\t details on this URL:", + "\n --proxy-tls13-ciphers ", + "\t (TLS) Same as --tls13-ciphers but used in HTTPS proxy context.", + "\n\t Specify which cipher suites to use in the connection to your HTTPS", + "\t proxy when it negotiates TLS 1.3. The list of ciphers suites must", + "\t specify valid ciphers. Read up on TLS 1.3 cipher suite details on", + "\t this URL:", "\n\t https://curl.se/docs/ssl-ciphers.html", - "\n\t This option is currently used only when curl is built to use", - "\t OpenSSL 1.1.1 or later. If you are using a different SSL backend", - "\t you can try setting TLS 1.3 cipher suites by using the", - "\t --proxy-ciphers option. If --proxy-tls13-ciphers is provided", - "\t several times, the last set value is used.", + "\n\t This option is used when curl is built to use OpenSSL 1.1.1 or", + "\t later, Schannel, wolfSSL, or mbedTLS 3.6.0 or later.", + "\n\t Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites", + "\t where set by using the --proxy-ciphers option. If", + "\t --proxy-tls13-ciphers is provided several times, the last set", + "\t value is used.", "\n\t Example:", - "\t curl --proxy-tls13-ciphers TLS_AES_128_GCM_SHA256 -x proxy https://example.com", - "\n\t Added in 7.61.0. See also --tls13-ciphers, --curves and", - "\t --proxy-ciphers.", + "\t curl --proxy-tls13-ciphers TLS_AES_128_GCM_SHA256 -x proxy \\", + "\t\t https://example.com", + "\n\t Added in 7.61.0. See also --proxy-ciphers, --tls13-ciphers and", + "\t --proxy.", "\n --proxy-tlsauthtype ", "\t Set TLS authentication type with HTTPS proxy. The only supported", "\t option is \"SRP\", for TLS-SRP (RFC 5054). This option works only if", @@ -2862,7 +2942,8 @@ static const char * const curlman[] = { "\t --proxy-tlspassword is provided several times, the last set value", "\t is used.", "\n\t Example:", - "\t curl --proxy-tlspassword passwd -x https://proxy https://example.com", + "\t curl --proxy-tlspassword passwd -x https://proxy \\", + "\t\t https://example.com", "\n\t See also --proxy and --proxy-tlsuser.", "\n --proxy-tlsuser ", "\t Set username for use for HTTPS proxy with the TLS authentication", @@ -3066,6 +3147,10 @@ static const char * const curlman[] = { "\t unrestricted.", "\n\t When retrying transfers, enabled with --retry, the separate retry", "\t delay logic is used and not this setting.", + "\n\t Starting in version 8.10.0, you can specify number of time units", + "\t in the rate expression. Make curl do no more than 5 transfers per", + "\t 15 seconds with \"5/15s\" or limit it to 3 transfers per 4 hours", + "\t with \"3/4h\". No spaces allowed.", "\n\t This option is global and does not need to be specified for each", "\t use of --next. If --rate is provided several times, the last set", "\t value is used.", @@ -3139,8 +3224,14 @@ static const char * const curlman[] = { "\t other URL encoded parts of the name, they end up as-is as", "\t filename.", "\n\t You may use this option as many times as the number of URLs you", - "\t have. --remote-name is associated with a single URL. Use it once", - "\t per URL when you use several URLs in a command line.", + "\t have.", + "\n\t Before curl 8.10.0, curl returned an error if the URL ended with a", + "\t slash, which means that there is no filename part in the URL.", + "\t Starting in 8.10.0, curl sets the filename to the last directory", + "\t part of the URL or if that also is missing to \"curl_response\"", + "\t (without extension) for this situation. --remote-name is", + "\t associated with a single URL. Use it once per URL when you use", + "\t several URLs in a command line.", "\n\t Examples:", "\t curl -O https://example.com/filename", "\t curl -O https://example.com/filename -O https://example.com/file2", @@ -3153,7 +3244,8 @@ static const char * const curlman[] = { "\t multiple times has no extra effect. Disable it again with", "\t --no-remote-name-all.", "\n\t Example:", - "\t curl --remote-name-all ftp://example.com/file1 ftp://example.com/file2", + "\t curl --remote-name-all ftp://example.com/file1 \\", + "\t\t ftp://example.com/file2", "\n\t See also --remote-name.", "\n -R, --remote-time", "\t Makes curl attempt to figure out the timestamp of the remote file", @@ -3369,6 +3461,21 @@ static const char * const curlman[] = { "\n\t Example:", "\t curl --show-error --silent https://example.com", "\n\t See also --no-progress-meter.", + "\n -i, --show-headers", + "\t (HTTP FTP) Show response headers in the output. HTTP response", + "\t headers can include things like server name, cookies, date of the", + "\t document, HTTP version and more. With non-HTTP protocols, the", + "\t \"headers\" are other server communication.", + "\n\t To view the request headers, consider the --verbose option.", + "\n\t Prior to 7.75.0 curl did not print the headers if --fail was used", + "\t in combination with this option and there was error reported by", + "\t server.", + "\n\t This option was called --include before 8.10.0. The previous name", + "\t remains functional. Providing --show-headers multiple times has no", + "\t extra effect. Disable it again with --no-show-headers.", + "\n\t Example:", + "\t curl -i https://example.com", + "\n\t See also --verbose.", "\n -s, --silent", "\t Silent or quiet mode. Do not show progress meter or error", "\t messages. Makes Curl mute. It still outputs the data you ask for,", @@ -3379,11 +3486,23 @@ static const char * const curlman[] = { "\n\t Example:", "\t curl -s https://example.com", "\n\t See also --verbose, --stderr and --no-progress-meter.", + "\n --skip-existing", + "\t If there is a local file present when a download is requested, the", + "\t operation is skipped. Note that curl cannot know if the local file", + "\t was previously downloaded fine, or if it is incomplete etc, it", + "\t just knows if there is a filename present in the file system or", + "\t not and it skips the transfer if it is. Providing --skip-existing", + "\t multiple times has no extra effect. Disable it again with", + "\t --no-skip-existing.", + "\n\t Example:", + "\t curl --skip-existing --output local/dir/file https://example.com", + "\n\t Added in 8.10.0. See also --output, --remote-name and", + "\t --no-clobber.", "\n --socks4 ", "\t Use the specified SOCKS4 proxy. If the port number is not", "\t specified, it is assumed at port 1080. Using this socket type make", "\t curl resolve the hostname and passing the address on to the proxy.", - "\n\t To specify proxy on a unix domain socket, use localhost for host,", + "\n\t To specify proxy on a Unix domain socket, use localhost for host,", "\t e.g. \"socks4://localhost/path/to/socket.sock\"", "\n\t This option overrides any previous use of --proxy, as they are", "\t mutually exclusive.", @@ -3401,7 +3520,7 @@ static const char * const curlman[] = { "\t Use the specified SOCKS4a proxy. If the port number is not", "\t specified, it is assumed at port 1080. This asks the proxy to", "\t resolve the hostname.", - "\n\t To specify proxy on a unix domain socket, use localhost for host,", + "\n\t To specify proxy on a Unix domain socket, use localhost for host,", "\t e.g. \"socks4a://localhost/path/to/socket.sock\"", "\n\t This option overrides any previous use of --proxy, as they are", "\t mutually exclusive.", @@ -3418,7 +3537,7 @@ static const char * const curlman[] = { "\n --socks5 ", "\t Use the specified SOCKS5 proxy - but resolve the hostname locally.", "\t If the port number is not specified, it is assumed at port 1080.", - "\n\t To specify proxy on a unix domain socket, use localhost for host,", + "\n\t To specify proxy on a Unix domain socket, use localhost for host,", "\t e.g. \"socks5://localhost/path/to/socket.sock\"", "\n\t This option overrides any previous use of --proxy, as they are", "\t mutually exclusive.", @@ -3461,20 +3580,22 @@ static const char * const curlman[] = { "\t multiple times has no extra effect. Disable it again with", "\t --no-socks5-gssapi-nec.", "\n\t Example:", - "\t curl --socks5-gssapi-nec --socks5 hostname:4096 https://example.com", + "\t curl --socks5-gssapi-nec --socks5 hostname:4096 \\", + "\t\t https://example.com", "\n\t See also --socks5.", "\n --socks5-gssapi-service ", "\t Set the service name for a socks server. Default is", "\t rcmd/server-fqdn. If --socks5-gssapi-service is provided several", "\t times, the last set value is used.", "\n\t Example:", - "\t curl --socks5-gssapi-service sockd --socks5 hostname:4096 https://example.com", + "\t curl --socks5-gssapi-service sockd --socks5 hostname:4096 \\", + "\t\t https://example.com", "\n\t See also --socks5.", "\n --socks5-hostname ", "\t Use the specified SOCKS5 proxy (and let the proxy resolve the", "\t hostname). If the port number is not specified, it is assumed at", "\t port 1080.", - "\n\t To specify proxy on a unix domain socket, use localhost for host,", + "\n\t To specify proxy on a Unix domain socket, use localhost for host,", "\t e.g. \"socks5h://localhost/path/to/socket.sock\"", "\n\t This option overrides any previous use of --proxy, as they are", "\t mutually exclusive.", @@ -3632,14 +3753,15 @@ static const char * const curlman[] = { "\n --suppress-connect-headers", "\t When --proxytunnel is used and a CONNECT request is made do not", "\t output proxy CONNECT response headers. This option is meant to be", - "\t used with --dump-header or --include which are used to show", + "\t used with --dump-header or --show-headers which are used to show", "\t protocol headers in the output. It has no effect on debug options", "\t such as --verbose or --trace, or any statistics. Providing", "\t --suppress-connect-headers multiple times has no extra effect.", "\t Disable it again with --no-suppress-connect-headers.", "\n\t Example:", - "\t curl --suppress-connect-headers --include -x proxy https://example.com", - "\n\t See also --dump-header, --include and --proxytunnel.", + "\t curl --suppress-connect-headers --show-headers -x proxy \\", + "\t\t https://example.com", + "\n\t See also --dump-header, --show-headers and --proxytunnel.", "\n --tcp-fastopen", "\t Enable use of TCP Fast Open (RFC 7413). TCP Fast Open is a TCP", "\t extension that allows data to get sent earlier over the connection", @@ -3734,15 +3856,15 @@ static const char * const curlman[] = { "\t negotiates TLS 1.3. The list of ciphers suites must specify valid", "\t ciphers. Read up on TLS 1.3 cipher suite details on this URL:", "\n\t https://curl.se/docs/ssl-ciphers.html", - "\n\t This option is currently used only when curl is built to use", - "\t OpenSSL 1.1.1 or later, or Schannel. If you are using a different", - "\t SSL backend you can try setting TLS 1.3 cipher suites by using the", - "\t --ciphers option. If --tls13-ciphers is provided several times,", - "\t the last set value is used.", + "\n\t This option is used when curl is built to use OpenSSL 1.1.1 or", + "\t later, Schannel, wolfSSL, or mbedTLS 3.6.0 or later.", + "\n\t Before curl 8.10.0 with mbedTLS or wolfSSL, TLS 1.3 cipher suites", + "\t where set by using the --ciphers option. If --tls13-ciphers is", + "\t provided several times, the last set value is used.", "\n\t Example:", "\t curl --tls13-ciphers TLS_AES_128_GCM_SHA256 https://example.com", - "\n\t Added in 7.61.0. See also --ciphers, --curves and", - "\t --proxy-tls13-ciphers.", + "\n\t Added in 7.61.0. See also --ciphers, --proxy-tls13-ciphers and", + "\t --curves.", "\n --tlsauthtype ", "\t (TLS) Set TLS authentication type. Currently, the only supported", "\t option is \"SRP\", for TLS-SRP (RFC 5054). If --tlsuser and", @@ -3973,7 +4095,7 @@ static const char * const curlman[] = { "\n -B, --use-ascii", "\t (FTP LDAP) Enable ASCII transfer mode. For FTP, this can also be", "\t enforced by using a URL that ends with \";type=A\". This option", - "\t causes data sent to stdout to be in text mode for win32 systems.", + "\t causes data sent to stdout to be in text mode for Win32 systems.", "\t Providing --use-ascii multiple times has no extra effect. Disable", "\t it again with --no-use-ascii.", "\n\t Example:", @@ -4060,7 +4182,8 @@ static const char * const curlman[] = { "\n\t\texpands the variable base64 encoded", "\n\t --variable can be used several times in a command line", "\n\t Example:", - "\t curl --variable name=smith --expand-url \"https://example.com/{{name}}\"", + "\t curl --variable name=smith --expand-url \"https:\\", + "\t\t //example.com/{{name}}\"", "\n\t Added in 8.3.0. See also --config.", "\n -v, --verbose", "\t Makes curl verbose during the operation. Useful for debugging and", @@ -4068,10 +4191,27 @@ static const char * const curlman[] = { "\t means header data sent by curl, < means header data received by", "\t curl that is hidden in normal cases, and a line starting with *", "\t means additional info provided by curl.", - "\n\t If you only want HTTP headers in the output, --include or", + "\n\t If you only want HTTP headers in the output, --show-headers or", "\t --dump-header might be more suitable options.", - "\n\t If you think this option still does not give you enough details,", - "\t consider using --trace or --trace-ascii instead.", + "\n\t Since curl 8.10, mentioning this option several times in the same", + "\t argument increases the level of the trace output. However, as", + "\t before, a single --verbose or --no-verbose reverts any additions", + "\t by previous \"-vv\" again. This means that \"-vv -v\" is equivalent to", + "\t a single -v. This avoids unwanted verbosity when the option is", + "\t mentioned in the command line and curl config files.", + "\n\t Using it twice, e.g. \"-vv\", outputs time (--trace-time) and", + "\t transfer ids (--trace-ids), as well as enable tracing for all", + "\t protocols (--trace-config protocol).", + "\n\t Adding a third verbose outputs transfer content (--trace-ascii %)", + "\t and enable tracing of more components (--trace-config", + "\t read,write,ssl).", + "\n\t A forth time adds tracing of all network components.", + "\t (--trace-config network).", + "\n\t Any addition of the verbose option after that has no effect.", + "\n\t If you think this option does not give you the right details,", + "\t consider using --trace or --trace-ascii instead. Or use it only", + "\t once and use --trace-config to trace the specific components you", + "\t wish to see.", "\n\t Note that verbose output of curl activities and network traffic", "\t might contain sensitive data, including usernames, credentials or", "\t secret data content. Be aware and be careful when sharing trace", @@ -4082,7 +4222,7 @@ static const char * const curlman[] = { "\n\t Example:", "\t curl --verbose https://example.com", "\n\t This option is mutually exclusive with --trace and --trace-ascii.", - "\t See also --include, --silent, --trace and --trace-ascii.", + "\t See also --show-headers, --silent, --trace and --trace-ascii.", "\n -V, --version", "\t Displays information about curl and the libcurl version it uses.", "\n\t The first line includes the full version of curl, libcurl and", @@ -4140,7 +4280,8 @@ static const char * const curlman[] = { "\n\t NTLM", "\n\t\tNTLM authentication is supported.", "\n\t NTLM_WB", - "\n\t\tNTLM delegation to winbind helper is supported.", + "\n\t\tNTLM delegation to winbind helper is supported. This feature", + "\t\twas removed from curl in 8.8.0.", "\n\t PSL", "\n\t\tPSL is short for Public Suffix List and means that this curl", "\t\thas been built with knowledge about \"public suffixes\".", @@ -4340,6 +4481,9 @@ static const char * const curlman[] = { "\n\t time_namelookup", "\n\t\tThe time, in seconds, it took from the start until the name", "\t\tresolving was completed.", + "\n\t time_posttransfer", + "\n\t\tThe time it took from the start until the last byte is sent by", + "\t\tlibcurl. In microseconds. (Added in 8.10.0)", "\n\t time_pretransfer", "\n\t\tThe time, in seconds, it took from the start until the file", "\t\ttransfer was just about to begin. This includes all", @@ -4511,7 +4655,7 @@ static const char * const curlman[] = { "\t(in hex). Do note that these files can become rather large. Works with", "\tthe ngtcp2 and quiche QUIC backends.", "\n SHELL", - "\n\tUsed on VMS when trying to detect if using a DCL or a unix shell.", + "\n\tUsed on VMS when trying to detect if using a DCL or a Unix shell.", "\n SSL_CERT_DIR ", "\n\tIf set, it is used as the --capath value. This environment variable is", "\tignored if Schannel is used as the TLS backend.", @@ -4779,6 +4923,21 @@ void hugehelp(void) while(curlman[i]) puts(curlman[i++]); } + +/* Show the help text for the 'arg' curl argument on stdout */ +void showhelp(const char *trigger, const char *arg, const char *endarg) +{ + int i = 0; + struct scan_ctx ctx; + inithelpscan(&ctx, trigger, arg, endarg); + while(curlman[i]) { + size_t len = strlen(curlman[i]); + if(!helpscan((unsigned char *)curlman[i], len, &ctx) || + !helpscan((unsigned char *)"\n", 1, &ctx)) + break; + i++; + } +} #endif /* USE_MANUAL */ #else /* @@ -4786,6035 +4945,6186 @@ void hugehelp(void) */ #ifdef USE_MANUAL #include "tool_hugehelp.h" +#include "tool_help.h" + #include #include "memdebug.h" /* keep this as LAST include */ static const unsigned char hugehelpgz[] = { /* This mumbo-jumbo is the huge help text compressed with gzip. - Thanks to this operation, the size of this data shrank from 249565 - to 72262 bytes. You can disable the use of compressed help + Thanks to this operation, the size of this data shrank from 255490 + to 74049 bytes. You can disable the use of compressed help texts by NOT passing -c to the mkhelp.pl tool. */ 0x1f, 0x8b, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0xec, 0xfd, - 0x7b, 0x5f, 0x1b, 0x57, 0xb2, 0x2f, 0x0e, 0xff, 0xed, 0xbc, 0x8a, 0xde, - 0x9a, 0xb3, 0x0f, 0xb0, 0x47, 0x12, 0x37, 0xdb, 0x71, 0x88, 0x93, 0x5f, - 0x08, 0xc6, 0x31, 0x7b, 0x6c, 0xc3, 0x18, 0x9c, 0x64, 0xf6, 0x24, 0x1f, - 0x7f, 0x1a, 0xa9, 0x05, 0x1d, 0x4b, 0x6a, 0x4d, 0x77, 0x0b, 0xcc, 0xcc, - 0x99, 0xe7, 0xb5, 0x3f, 0x75, 0x5f, 0xb5, 0x5a, 0x2d, 0x90, 0x1d, 0x3c, - 0xe7, 0x3a, 0x17, 0x0c, 0x52, 0xf7, 0xba, 0xd6, 0xaa, 0x55, 0xd7, 0x6f, - 0x25, 0x89, 0xfe, 0xe7, 0x1d, 0xfd, 0xff, 0x1d, 0xfc, 0x07, 0xfe, 0xfd, - 0x42, 0x3e, 0x7b, 0xf7, 0xee, 0x7f, 0x24, 0xfc, 0x5f, 0xf8, 0xee, 0x17, - 0xf8, 0x97, 0xbf, 0xd8, 0x4c, 0xc2, 0x17, 0xff, 0xe3, 0xdd, 0x46, 0xa2, - 0x5f, 0xfc, 0x8f, 0x64, 0x9d, 0xbe, 0x78, 0x27, 0x6f, 0x3c, 0xc5, 0xdf, - 0xdf, 0x49, 0x6b, 0xbf, 0x60, 0x6b, 0xf8, 0x63, 0x13, 0xbf, 0xff, 0xe5, - 0x1d, 0xfe, 0x0a, 0x9f, 0x7c, 0xf1, 0x7a, 0xff, 0xd5, 0xe1, 0x17, 0xf4, - 0xc8, 0x60, 0x5e, 0x8e, 0x93, 0x5e, 0x52, 0x97, 0xe9, 0xb4, 0x1a, 0x65, - 0x65, 0x92, 0x26, 0x6f, 0xdf, 0xbc, 0xfc, 0xe2, 0x8b, 0xd3, 0xbf, 0xbc, - 0x3e, 0x3e, 0x39, 0x3d, 0x3a, 0x75, 0x0f, 0xfd, 0xb5, 0x98, 0xd5, 0x79, - 0x31, 0xad, 0x60, 0x24, 0xf0, 0x48, 0xf5, 0xeb, 0x17, 0x5f, 0x3c, 0x3b, - 0x3c, 0x3d, 0x78, 0x73, 0x74, 0x72, 0x76, 0x74, 0xfc, 0xda, 0x3d, 0x97, - 0x57, 0xd0, 0x48, 0x5d, 0x14, 0xe3, 0x24, 0x19, 0x15, 0xa5, 0xb5, 0x5c, - 0xe6, 0xd3, 0x8b, 0x64, 0x98, 0xd6, 0x29, 0x7c, 0x5c, 0x16, 0x93, 0x04, - 0xbf, 0x2a, 0xe0, 0xc9, 0xa4, 0xca, 0xca, 0x2b, 0xe8, 0x78, 0x5e, 0xe1, - 0x03, 0xd8, 0x72, 0x3f, 0x49, 0x8e, 0x6a, 0x6a, 0xaf, 0x9a, 0xcf, 0x66, - 0x45, 0x59, 0x57, 0x49, 0x7d, 0x99, 0x55, 0x59, 0x32, 0x2b, 0x8b, 0xba, - 0x18, 0x14, 0xe3, 0x6a, 0x2f, 0x49, 0x9e, 0x1d, 0x1d, 0x9c, 0x75, 0x93, - 0xe7, 0x47, 0x2f, 0x0f, 0xbb, 0x49, 0xf2, 0xfc, 0xec, 0xa4, 0x8b, 0x3f, - 0x4e, 0xe1, 0xf7, 0x1f, 0x8e, 0x4f, 0x5e, 0x1c, 0xbe, 0xe9, 0xca, 0xbf, - 0xf8, 0xc9, 0x8b, 0x33, 0xf8, 0x9a, 0xda, 0xc3, 0xdf, 0xe0, 0x93, 0xa3, - 0x57, 0xfb, 0xf0, 0x3c, 0xfd, 0x03, 0x7f, 0xbd, 0x7c, 0x46, 0x7f, 0xe1, - 0x3f, 0xf0, 0xd7, 0xab, 0x3f, 0x9f, 0x41, 0xbb, 0xc9, 0xc9, 0xf1, 0xc9, - 0x6e, 0x97, 0x7e, 0x62, 0x0b, 0x6f, 0xce, 0x5e, 0xc1, 0x23, 0xf8, 0x93, - 0xff, 0x3a, 0x95, 0xf6, 0x4e, 0x0f, 0xe0, 0xe3, 0x53, 0xea, 0xfd, 0xf4, - 0xd5, 0xf7, 0xf4, 0xe3, 0x14, 0x7f, 0xf2, 0x07, 0xd4, 0xd7, 0xd9, 0xe1, - 0xcb, 0xd7, 0x87, 0xd0, 0xe2, 0x19, 0x3d, 0xf5, 0xd3, 0x69, 0x92, 0x4e, - 0x87, 0xf0, 0xcf, 0x69, 0xdf, 0xad, 0x18, 0x2e, 0x59, 0x32, 0x2b, 0xae, - 0xb3, 0x32, 0x1b, 0x26, 0xc9, 0xf9, 0x4d, 0x92, 0x8c, 0xf3, 0x73, 0xfe, - 0x06, 0x57, 0x30, 0x49, 0xc7, 0xf0, 0x9b, 0xae, 0x63, 0xaf, 0xcc, 0xc6, - 0x69, 0x8d, 0x0f, 0x8e, 0xb2, 0xb4, 0x9e, 0x97, 0x19, 0xae, 0x57, 0x72, - 0x9a, 0x65, 0xd4, 0x9e, 0xbc, 0xb8, 0xbe, 0xbb, 0x41, 0xaf, 0x0e, 0xb3, - 0x3a, 0xcd, 0xc7, 0x15, 0x74, 0x46, 0xbb, 0x8a, 0x4f, 0x9c, 0x5d, 0x66, - 0xb8, 0xca, 0x49, 0x75, 0x33, 0xad, 0xd3, 0x0f, 0xdc, 0xb5, 0xac, 0x6b, - 0x6f, 0x98, 0xcd, 0xb2, 0xe9, 0x30, 0x9b, 0xd6, 0xfd, 0xe4, 0x2f, 0xc5, - 0x3c, 0x19, 0xe5, 0x30, 0x56, 0xd8, 0x22, 0x6e, 0x05, 0xba, 0x1c, 0x66, - 0xd5, 0xa0, 0xcc, 0x89, 0x0c, 0x60, 0xd0, 0x53, 0x6a, 0xef, 0xcd, 0xf3, - 0x83, 0x64, 0xf7, 0xab, 0x27, 0x8f, 0x65, 0x42, 0x47, 0xa3, 0xe4, 0x06, - 0x5e, 0x85, 0x26, 0xaf, 0xf2, 0x61, 0x96, 0x30, 0x3d, 0x25, 0xd7, 0x79, - 0x7d, 0x59, 0xcc, 0x6b, 0xfc, 0x73, 0x9c, 0xa5, 0x43, 0xdc, 0x69, 0xeb, - 0x75, 0x6f, 0x73, 0x33, 0xa9, 0x06, 0x97, 0xd9, 0x24, 0xeb, 0xca, 0x72, - 0x5c, 0xcc, 0xb3, 0xaa, 0xca, 0x2a, 0x6a, 0xef, 0xfa, 0x32, 0xad, 0xed, - 0x51, 0x6a, 0xfa, 0x3a, 0xc5, 0xf1, 0x1d, 0xd5, 0x48, 0x14, 0x30, 0x8c, - 0x61, 0x36, 0x4a, 0xe7, 0x63, 0xa4, 0x91, 0x82, 0xf6, 0x37, 0x39, 0x87, - 0x7e, 0xd2, 0xaa, 0x9a, 0x4f, 0xb2, 0x2a, 0x29, 0xe0, 0x99, 0x12, 0x66, - 0x78, 0x9e, 0x56, 0xd9, 0x90, 0xda, 0x83, 0x91, 0x17, 0xa3, 0x3a, 0x9b, - 0xf6, 0xe6, 0xf0, 0x49, 0x72, 0x59, 0x54, 0xf5, 0x34, 0x9d, 0x20, 0x69, - 0x65, 0xa3, 0xfc, 0x03, 0xae, 0xe5, 0x73, 0x5c, 0xf1, 0xec, 0x43, 0x3a, - 0x99, 0x8d, 0x61, 0x40, 0xb8, 0x88, 0xfa, 0x50, 0x95, 0x54, 0x75, 0x5a, - 0xd6, 0x34, 0x78, 0x9c, 0x10, 0xb5, 0xd7, 0x19, 0xd5, 0xb3, 0x7e, 0x87, - 0x07, 0xae, 0xbd, 0xea, 0x28, 0x91, 0x24, 0x65, 0x59, 0x70, 0x39, 0x07, - 0xe9, 0x34, 0xa9, 0x66, 0xd9, 0x20, 0x1f, 0xdd, 0x00, 0x15, 0xc0, 0x2e, - 0xa7, 0x93, 0x62, 0x0e, 0x4f, 0x15, 0x23, 0x22, 0x7b, 0x1c, 0x1a, 0x0c, - 0x17, 0x68, 0xa2, 0x98, 0x4c, 0x90, 0x4a, 0xc6, 0xf9, 0x34, 0xeb, 0xe3, - 0x7e, 0xc1, 0xe3, 0x65, 0x86, 0xfb, 0x5d, 0xc3, 0x32, 0xf1, 0x34, 0xf2, - 0x29, 0x2c, 0x65, 0x95, 0xfd, 0x6d, 0x0e, 0x9b, 0x95, 0xa7, 0xe3, 0x04, - 0x5e, 0x98, 0xc2, 0x21, 0xc2, 0xcf, 0xb1, 0x0d, 0xee, 0x26, 0x47, 0x2a, - 0x29, 0xca, 0x21, 0x9e, 0xae, 0xe9, 0x18, 0xd6, 0x94, 0x46, 0x06, 0x13, - 0x4f, 0x92, 0x5e, 0x6f, 0x96, 0x96, 0x40, 0x57, 0xd9, 0xb8, 0xdf, 0x3a, - 0xbe, 0x68, 0x10, 0x89, 0x9e, 0x7c, 0xfc, 0x80, 0xc7, 0x3a, 0x81, 0xc5, - 0x1a, 0xf2, 0xdf, 0x38, 0x14, 0x98, 0x0d, 0xf7, 0x03, 0x93, 0xa0, 0xf6, - 0x70, 0x10, 0xd1, 0x3c, 0x1c, 0xb9, 0xa7, 0x75, 0x9d, 0x4d, 0x66, 0xbc, - 0x63, 0x65, 0x86, 0xc3, 0x19, 0x14, 0x30, 0xfa, 0x01, 0xf7, 0x01, 0x3b, - 0x0e, 0xdb, 0x3a, 0x2c, 0x70, 0x99, 0x27, 0xb0, 0xb1, 0x39, 0xec, 0x83, - 0x11, 0x7f, 0xd5, 0x4d, 0xaa, 0x02, 0x5b, 0x4f, 0x99, 0x41, 0x5c, 0x64, - 0x35, 0xed, 0xc7, 0x04, 0x47, 0x30, 0x02, 0x1a, 0xad, 0x98, 0xb9, 0xf0, - 0x22, 0xe0, 0xc6, 0x0a, 0x77, 0x19, 0xc2, 0x5b, 0xd3, 0xa2, 0xa6, 0xc9, - 0x5b, 0xab, 0xd2, 0x2d, 0xf4, 0x09, 0xc3, 0x64, 0x86, 0x93, 0xd5, 0xf3, - 0x59, 0x72, 0x09, 0x7f, 0x56, 0x97, 0xe9, 0x7b, 0x24, 0x87, 0xb3, 0x4b, - 0x38, 0x21, 0xf9, 0x04, 0xe9, 0x19, 0x1a, 0xc7, 0xf5, 0xc9, 0x86, 0xfd, - 0xe4, 0xc0, 0x06, 0x2c, 0x33, 0xa0, 0xc5, 0x2b, 0xa6, 0xe3, 0x9b, 0xe4, - 0x1c, 0xfe, 0x18, 0x16, 0x53, 0x3e, 0x8e, 0x48, 0x3e, 0xb4, 0x5e, 0x6e, - 0x47, 0xf8, 0x48, 0x27, 0xc8, 0xee, 0xc6, 0x8d, 0xdd, 0xc6, 0xc5, 0xbc, - 0x2a, 0x06, 0x29, 0x1f, 0x30, 0xfc, 0x14, 0x9a, 0xc5, 0x61, 0x43, 0xab, - 0xd4, 0xde, 0x2c, 0x2b, 0xe1, 0xf5, 0x09, 0xb4, 0x72, 0x9e, 0xd5, 0xd7, - 0x19, 0x2c, 0x54, 0x95, 0xe1, 0x46, 0xd6, 0x19, 0x2f, 0x6d, 0x39, 0x9f, - 0x56, 0xb2, 0xd4, 0x27, 0x72, 0x02, 0x61, 0x5c, 0x47, 0x27, 0x57, 0x8f, - 0x93, 0xbf, 0x17, 0xd4, 0xfe, 0x50, 0x49, 0x44, 0x8f, 0x25, 0xf6, 0x93, - 0xc0, 0xb9, 0x4e, 0x67, 0xd0, 0x2a, 0xb4, 0x3f, 0x00, 0x8a, 0x4a, 0x2f, - 0x60, 0xe1, 0xf2, 0x8b, 0x29, 0x70, 0x96, 0x97, 0xf9, 0xfb, 0x4c, 0x28, - 0xee, 0x8b, 0x2f, 0x1e, 0x74, 0x2e, 0xeb, 0x7a, 0x06, 0x07, 0xf6, 0xaf, - 0xa3, 0xec, 0xc9, 0xd6, 0xde, 0xde, 0xee, 0xbf, 0xef, 0x3c, 0xca, 0xea, - 0xcb, 0xad, 0x5f, 0x37, 0x3b, 0xdc, 0xe9, 0x21, 0xac, 0xf5, 0x4d, 0x7d, - 0x89, 0x5b, 0x22, 0x1c, 0x60, 0xa8, 0x64, 0x1d, 0xcf, 0x13, 0x77, 0x10, - 0x79, 0x0f, 0x4e, 0x2e, 0x6d, 0x7c, 0xc7, 0xd4, 0xc6, 0xa7, 0xb5, 0x4c, - 0x72, 0xd8, 0x9f, 0xb4, 0xbc, 0x80, 0x83, 0x35, 0xad, 0xbb, 0xf1, 0x39, - 0xa3, 0x9b, 0x06, 0xe7, 0x81, 0xef, 0xd6, 0x25, 0xb0, 0x43, 0xf8, 0x0c, - 0x0f, 0x3f, 0x5c, 0x1c, 0x83, 0x4b, 0x58, 0x87, 0x1f, 0x5e, 0x1e, 0x7f, - 0xff, 0xfd, 0xd1, 0xeb, 0x1f, 0xda, 0xcf, 0x60, 0x20, 0x04, 0xde, 0x22, - 0xe8, 0x0c, 0xd6, 0x12, 0xc9, 0x41, 0x4f, 0x24, 0xb2, 0xe2, 0xeb, 0x32, - 0x27, 0x12, 0x1b, 0xe7, 0x15, 0x7e, 0x85, 0x4b, 0x26, 0x9c, 0xef, 0xbc, - 0x4c, 0x07, 0xc8, 0x63, 0xca, 0x04, 0xa8, 0xf3, 0x02, 0x7e, 0xe3, 0xef, - 0xe8, 0xf3, 0xf7, 0x59, 0x0d, 0xc4, 0xf3, 0x13, 0x4c, 0x1b, 0x99, 0x77, - 0x8d, 0x44, 0xd4, 0xb9, 0x18, 0x17, 0xe7, 0xe7, 0xd0, 0x54, 0xa7, 0xb9, - 0x43, 0xd4, 0x36, 0x6f, 0x46, 0x7d, 0x59, 0x66, 0x59, 0x32, 0xcc, 0x47, - 0x40, 0xec, 0x30, 0xe1, 0x84, 0xf9, 0xce, 0x18, 0x36, 0x81, 0x1a, 0xd9, - 0x73, 0x7b, 0x50, 0xe5, 0x75, 0xd6, 0xff, 0x07, 0xec, 0x6a, 0xb7, 0xbe, - 0x2e, 0xba, 0xf4, 0xe2, 0x3f, 0xfb, 0xb0, 0x92, 0xb2, 0x15, 0xcf, 0x0a, - 0xe1, 0x0f, 0x34, 0xc6, 0x11, 0x5c, 0x22, 0x33, 0xa0, 0x6b, 0x58, 0xb7, - 0x32, 0x1f, 0xe0, 0xa9, 0xc8, 0x33, 0x9a, 0x1f, 0x5f, 0xbb, 0x7f, 0xfd, - 0x15, 0x57, 0x2d, 0x9f, 0x52, 0xfb, 0x23, 0x6a, 0x1e, 0xf9, 0x9a, 0xb0, - 0x41, 0x6c, 0x75, 0x13, 0x4f, 0xd7, 0x5f, 0xb7, 0x7b, 0xdb, 0x5b, 0x5b, - 0xbf, 0xf6, 0xeb, 0x0f, 0xb5, 0xf4, 0xf2, 0x13, 0x0e, 0x5a, 0x59, 0xfa, - 0xdf, 0xb3, 0xb2, 0xc8, 0xaa, 0xbb, 0xda, 0xd8, 0xda, 0x5a, 0xd6, 0x0a, - 0xf0, 0x85, 0x12, 0xef, 0xfa, 0xb2, 0x98, 0x5f, 0x5c, 0x12, 0xd1, 0xd0, - 0xa0, 0x81, 0xd4, 0xef, 0x6a, 0x33, 0xed, 0xfd, 0xdd, 0xb7, 0xf7, 0x3a, - 0xab, 0xf0, 0x86, 0x0c, 0xf3, 0x47, 0xfe, 0x49, 0xe7, 0x48, 0x24, 0x8a, - 0x6c, 0xd8, 0xa5, 0x7b, 0xe2, 0x46, 0x48, 0x82, 0xf8, 0x42, 0x95, 0x01, - 0xf5, 0x02, 0x2f, 0x85, 0x25, 0x05, 0xc2, 0xcc, 0x3e, 0xc0, 0xe3, 0x75, - 0x41, 0xed, 0x65, 0xe9, 0xe0, 0x92, 0xef, 0x12, 0xbf, 0x01, 0x7e, 0x14, - 0x69, 0x39, 0xb8, 0xcc, 0xaf, 0x60, 0x81, 0xbe, 0xfa, 0xea, 0x71, 0x0f, - 0x7e, 0x7c, 0xf5, 0xeb, 0xe6, 0x55, 0x31, 0x86, 0xf5, 0x7a, 0xf8, 0xeb, - 0x26, 0x12, 0xd5, 0x3f, 0xd2, 0xee, 0x79, 0x77, 0xf0, 0xcf, 0xfe, 0x65, - 0x3d, 0x19, 0x77, 0x96, 0x5c, 0x09, 0x70, 0xbd, 0x64, 0x33, 0x64, 0x08, - 0x70, 0x29, 0x00, 0xcb, 0x22, 0xe1, 0x09, 0xd6, 0x40, 0x88, 0x0b, 0xb9, - 0x25, 0xb0, 0xbb, 0x04, 0x07, 0x79, 0x93, 0xbc, 0x86, 0x05, 0x83, 0xcd, - 0x3c, 0x27, 0x96, 0x5b, 0xf2, 0xd5, 0x4f, 0xeb, 0xb7, 0x6c, 0x80, 0x61, - 0xfb, 0xf6, 0xb6, 0x6d, 0xed, 0x97, 0x3f, 0x09, 0x0b, 0xba, 0xb7, 0x13, - 0x6d, 0x11, 0x72, 0x65, 0x23, 0x16, 0x18, 0xda, 0x3f, 0xfe, 0xe9, 0xd6, - 0x97, 0x78, 0x36, 0xf2, 0xae, 0xf7, 0xc8, 0xe0, 0x90, 0x03, 0x37, 0x0f, - 0x35, 0xb0, 0x03, 0xe0, 0xf9, 0x5d, 0x5c, 0x71, 0xe6, 0x64, 0x65, 0x71, - 0x9e, 0x9e, 0x03, 0xbf, 0xbc, 0x4c, 0xaf, 0x32, 0x9c, 0xdb, 0x6c, 0x4e, - 0x37, 0x7a, 0x32, 0x9a, 0xa3, 0xb4, 0xa3, 0xdc, 0x29, 0xc7, 0xab, 0x60, - 0x7e, 0x0e, 0x67, 0xf4, 0x6f, 0xf3, 0xa2, 0xce, 0xe8, 0xce, 0x48, 0xaf, - 0x0a, 0x60, 0x63, 0x74, 0x55, 0x56, 0x97, 0xd9, 0x78, 0xcc, 0x9c, 0x16, - 0x3b, 0xcd, 0x71, 0xe1, 0xe0, 0xe4, 0xd8, 0x15, 0x0d, 0xec, 0xa0, 0x9f, - 0x30, 0x0f, 0x07, 0x5a, 0x82, 0xab, 0xe3, 0xa2, 0xc0, 0xa5, 0xc4, 0xa5, - 0xa5, 0xed, 0x84, 0xd5, 0xbe, 0x04, 0xf6, 0x39, 0x20, 0xc2, 0x63, 0x16, - 0x22, 0x17, 0x2c, 0xed, 0x4a, 0x3a, 0xee, 0xf2, 0xd9, 0xc3, 0x17, 0x64, - 0x8d, 0x92, 0xb5, 0xff, 0xbe, 0xd6, 0x4d, 0xd6, 0xfe, 0xbf, 0x35, 0xe2, - 0x3a, 0x6b, 0xff, 0xb1, 0x26, 0xa7, 0xf9, 0x14, 0xfa, 0x43, 0x2a, 0x19, - 0x8d, 0x12, 0x3d, 0xe8, 0x3c, 0x84, 0x5e, 0x0f, 0xff, 0x86, 0xcf, 0xe1, - 0xc1, 0x1f, 0xf7, 0xdf, 0x1c, 0xed, 0x7f, 0xff, 0xf2, 0xd0, 0xcb, 0xd5, - 0x26, 0xe4, 0x46, 0x0b, 0x76, 0x95, 0x96, 0x39, 0xac, 0x0f, 0x8e, 0x76, - 0x3d, 0x1d, 0x22, 0x1f, 0x85, 0xa5, 0x78, 0xd2, 0xdf, 0xed, 0x6f, 0x6d, - 0xf4, 0x41, 0xda, 0xab, 0xfd, 0x03, 0x26, 0x8c, 0xf4, 0x7a, 0xfa, 0x29, - 0x31, 0x8e, 0x6f, 0xe0, 0x82, 0xab, 0x91, 0x8b, 0xc0, 0xe8, 0x1b, 0x5f, - 0x7d, 0x87, 0xbb, 0x9c, 0xac, 0xc3, 0xbe, 0xc1, 0xc9, 0xe8, 0xe0, 0x1f, - 0x1d, 0x22, 0x46, 0xbc, 0xbd, 0xaa, 0x7a, 0x28, 0x1c, 0x2e, 0x1f, 0xe1, - 0x8d, 0xc8, 0x72, 0xba, 0xdc, 0x57, 0xc3, 0xb4, 0xba, 0x4c, 0xd6, 0x7b, - 0x1b, 0x1b, 0x32, 0xed, 0x1f, 0xb5, 0x55, 0xe9, 0xab, 0xd2, 0x66, 0xb2, - 0x0f, 0x33, 0x98, 0x0c, 0x8f, 0x9b, 0x39, 0x3a, 0x72, 0x57, 0xe8, 0x9a, - 0xd6, 0x9a, 0x29, 0xa9, 0xf3, 0x8f, 0x7f, 0xe0, 0x60, 0xfe, 0xf9, 0xcf, - 0x0e, 0xf6, 0x65, 0x82, 0x83, 0x3c, 0x4e, 0x82, 0x19, 0x32, 0x79, 0x11, - 0xce, 0x86, 0x72, 0x5f, 0x75, 0x7a, 0x3d, 0x6e, 0xbc, 0xd7, 0x91, 0xfb, - 0x19, 0x0f, 0x46, 0x25, 0xb7, 0x8c, 0x8c, 0x02, 0x36, 0xc2, 0xda, 0xb3, - 0x99, 0x77, 0xb0, 0xc9, 0x0e, 0x8c, 0x08, 0xf8, 0x1f, 0xf1, 0x00, 0xbe, - 0x8a, 0xcf, 0xc7, 0xe9, 0xf4, 0x3d, 0x4e, 0x96, 0x68, 0x8a, 0xba, 0x1d, - 0x22, 0x9d, 0x20, 0xc7, 0xc8, 0x3e, 0x20, 0x6f, 0x4e, 0x91, 0x7e, 0xa8, - 0x3d, 0x6d, 0x0b, 0x24, 0x50, 0x6a, 0x25, 0xc1, 0x49, 0xc0, 0xf0, 0xe1, - 0x54, 0x9e, 0xc3, 0xbd, 0x3d, 0x31, 0x11, 0x0c, 0x96, 0x91, 0xe9, 0x10, - 0x98, 0x2c, 0x4f, 0x80, 0xfe, 0x82, 0xfb, 0x49, 0xaf, 0x5d, 0xbe, 0x44, - 0xe0, 0xae, 0xa8, 0xc6, 0xb0, 0xa8, 0x42, 0x69, 0x9d, 0x5f, 0xa0, 0x39, - 0x27, 0x34, 0xc2, 0x62, 0xa6, 0x83, 0x01, 0xca, 0x6e, 0x44, 0x6f, 0x3c, - 0x71, 0xe0, 0x48, 0xd3, 0xab, 0xbc, 0x2c, 0xa6, 0x78, 0x29, 0x3a, 0x4a, - 0xc0, 0xfb, 0x6a, 0x94, 0x97, 0x30, 0x60, 0x90, 0x58, 0x0a, 0x11, 0x55, - 0x61, 0x30, 0x93, 0x86, 0x90, 0x97, 0x8d, 0x41, 0x78, 0xc1, 0x6d, 0xcd, - 0x72, 0x3a, 0x05, 0x25, 0x1c, 0xe4, 0xbc, 0xcc, 0x68, 0xdc, 0x6d, 0x2d, - 0xe3, 0xa3, 0xe7, 0x19, 0xd1, 0x02, 0x2e, 0x99, 0x9e, 0x61, 0xe2, 0x9c, - 0x33, 0xbb, 0xc5, 0x54, 0x14, 0xc7, 0x45, 0x1a, 0xcf, 0x49, 0x98, 0xc1, - 0x67, 0x50, 0x3a, 0xc2, 0x59, 0xe3, 0x3e, 0x11, 0x0f, 0x4e, 0xc7, 0x70, - 0xce, 0x86, 0x37, 0x24, 0x6d, 0xc1, 0xe9, 0x3c, 0x19, 0xa7, 0x42, 0x6e, - 0x8e, 0x46, 0xff, 0x5d, 0x36, 0x7f, 0x62, 0xfa, 0x5f, 0x58, 0xfa, 0x84, - 0x2e, 0x55, 0x20, 0x87, 0x35, 0x7c, 0x68, 0x2d, 0x21, 0x4e, 0x0e, 0xfb, - 0xa4, 0xd7, 0x33, 0xae, 0x14, 0xb3, 0xed, 0xb2, 0x44, 0x01, 0x62, 0x24, - 0xe2, 0x46, 0x34, 0xb5, 0xd0, 0xda, 0xc2, 0xb8, 0x78, 0x58, 0x67, 0x45, - 0xe2, 0xb4, 0x18, 0x6a, 0x4f, 0xe7, 0xc7, 0xd3, 0x83, 0x76, 0x73, 0x93, - 0x61, 0xe0, 0x9d, 0x2e, 0x5d, 0x22, 0xcd, 0x39, 0xd8, 0x19, 0x8c, 0x0f, - 0x21, 0xb5, 0x47, 0x0f, 0x7c, 0x27, 0x0f, 0xc8, 0x9e, 0x1f, 0x0a, 0x27, - 0x4e, 0x7e, 0xc8, 0x98, 0x1f, 0xbe, 0x3d, 0x3d, 0x7c, 0xd3, 0xbe, 0xdf, - 0xc8, 0xee, 0x0a, 0x5e, 0x1a, 0x60, 0x97, 0xa0, 0xab, 0x80, 0x92, 0x86, - 0xa3, 0xe2, 0x37, 0x72, 0xd6, 0x9f, 0x64, 0x70, 0x78, 0x2d, 0xb8, 0xa1, - 0xad, 0xfd, 0x3b, 0x3e, 0xb4, 0x86, 0x9f, 0xc9, 0x51, 0x42, 0x4e, 0xf4, - 0x4d, 0x42, 0xf7, 0x41, 0xd5, 0xbc, 0xdb, 0x66, 0xf9, 0xe6, 0x3f, 0xfe, - 0x81, 0x2f, 0xfc, 0xf3, 0x9f, 0x9b, 0x70, 0x7e, 0x2f, 0x8b, 0xa1, 0xbf, - 0x14, 0xb8, 0x01, 0x24, 0x35, 0x23, 0x44, 0x55, 0xe4, 0x8c, 0xb5, 0xa5, - 0x42, 0x3b, 0x23, 0x60, 0xef, 0x53, 0x11, 0xf4, 0x69, 0x4f, 0x88, 0x84, - 0x26, 0xa9, 0xc8, 0x98, 0xd1, 0x61, 0x0d, 0x67, 0x79, 0x52, 0x94, 0xfc, - 0xe7, 0x55, 0x36, 0xcd, 0x71, 0x05, 0x60, 0xda, 0xb8, 0xd8, 0xa4, 0x05, - 0x72, 0x13, 0x70, 0xd6, 0x26, 0x41, 0xb5, 0x54, 0x71, 0x1e, 0xd4, 0x86, - 0x7c, 0x4c, 0x8c, 0xf8, 0x12, 0x84, 0x25, 0xe0, 0xe9, 0x20, 0xb0, 0x09, - 0x8d, 0x74, 0xf0, 0x8d, 0x4e, 0x97, 0x48, 0x93, 0x5a, 0x00, 0xf5, 0x54, - 0xaf, 0xa0, 0xc0, 0x44, 0x52, 0x1c, 0x7a, 0xf2, 0x9f, 0xa7, 0xc7, 0xaf, - 0xa9, 0x3d, 0xba, 0x83, 0x86, 0x76, 0xb2, 0xb9, 0xa1, 0xdf, 0xaa, 0x62, - 0x8a, 0x0d, 0xe1, 0x95, 0x05, 0xb7, 0x61, 0x31, 0xcc, 0x44, 0xfd, 0xf0, - 0x4f, 0x25, 0x1d, 0x58, 0x90, 0x0e, 0xf1, 0x1b, 0xd4, 0x45, 0x1f, 0x3f, - 0x64, 0x02, 0xe5, 0xc7, 0x73, 0x11, 0xfe, 0x3a, 0xe7, 0x8f, 0x1f, 0x22, - 0x4b, 0x03, 0x76, 0x3b, 0x9b, 0xc1, 0xd5, 0xe8, 0xd6, 0x0a, 0x39, 0xb0, - 0xad, 0x0c, 0xad, 0x78, 0x05, 0x5f, 0x40, 0xaf, 0x70, 0x37, 0xd0, 0x09, - 0xe7, 0x03, 0x59, 0x8c, 0x8b, 0xa0, 0x12, 0x0c, 0x49, 0x66, 0x60, 0x02, - 0x29, 0xf3, 0x8b, 0x4b, 0x14, 0x7f, 0x90, 0x9a, 0x8b, 0x51, 0x12, 0x1f, - 0xa8, 0xbe, 0x63, 0xe3, 0x3a, 0x79, 0x6a, 0xef, 0xb2, 0x18, 0xd3, 0x82, - 0x4e, 0xf1, 0x4e, 0x3e, 0xbf, 0xa1, 0xfb, 0x17, 0x77, 0x4d, 0xc5, 0x29, - 0x1e, 0xff, 0x90, 0xaf, 0x7f, 0x63, 0xf8, 0x83, 0x14, 0x0f, 0x02, 0x1d, - 0xbe, 0x98, 0xa8, 0xf7, 0x48, 0x80, 0x69, 0xb2, 0x69, 0x98, 0x19, 0x5d, - 0x46, 0x7a, 0xaa, 0xff, 0xdb, 0x8b, 0xe3, 0x57, 0x87, 0x9b, 0xfd, 0x2a, - 0x1b, 0x94, 0xf0, 0x34, 0xd1, 0x78, 0x1a, 0xc6, 0x2a, 0x8c, 0x87, 0x9e, - 0x84, 0x7b, 0xeb, 0x03, 0xac, 0xd7, 0x2b, 0x20, 0x1f, 0xa4, 0x35, 0x62, - 0x60, 0x78, 0xce, 0x5d, 0x0f, 0x74, 0xba, 0x71, 0xab, 0x27, 0xaa, 0xae, - 0x8a, 0x8a, 0xd3, 0x93, 0xb1, 0x8b, 0x91, 0x81, 0x34, 0xa9, 0x29, 0x31, - 0xfa, 0x93, 0xe3, 0xd3, 0x33, 0x32, 0x54, 0x35, 0xce, 0xcc, 0xbf, 0xe3, - 0xb8, 0xdc, 0x89, 0xb1, 0x2f, 0x60, 0x14, 0xdf, 0xfd, 0xe3, 0x1f, 0xf8, - 0x2d, 0x9c, 0x0f, 0x19, 0xb7, 0x7b, 0x8e, 0x6c, 0x5e, 0x70, 0x49, 0xc0, - 0x63, 0x7b, 0x38, 0x92, 0x3d, 0xa0, 0x04, 0xb8, 0xf1, 0xbe, 0x78, 0xd0, - 0x76, 0xd6, 0x78, 0xbd, 0x0e, 0xda, 0x25, 0x01, 0xbb, 0x00, 0x2a, 0x22, - 0x0a, 0xb4, 0x17, 0x25, 0xb1, 0x6c, 0x00, 0xeb, 0x7d, 0xfc, 0xf6, 0xec, - 0xe4, 0xed, 0x99, 0x19, 0x63, 0x70, 0x9b, 0x6a, 0xd8, 0x46, 0x96, 0x77, - 0xae, 0xf3, 0x4a, 0xad, 0x2c, 0xa8, 0xd7, 0x90, 0x58, 0x89, 0x22, 0x66, - 0x36, 0xc8, 0x40, 0x7a, 0x1d, 0xb2, 0x7d, 0x0e, 0x16, 0x1c, 0x44, 0x00, - 0x38, 0x0f, 0x74, 0xbe, 0xe8, 0x70, 0x9c, 0xab, 0x0e, 0x08, 0x44, 0x3d, - 0x1f, 0x20, 0x69, 0xc1, 0x43, 0xf8, 0x17, 0x9c, 0x38, 0xd0, 0xb3, 0xaf, - 0x64, 0xe5, 0xe9, 0x75, 0xd9, 0xb1, 0x31, 0xe8, 0xb1, 0x63, 0xda, 0xd9, - 0xae, 0xdc, 0xf6, 0xd4, 0x55, 0xaf, 0xc7, 0x07, 0x4d, 0xd5, 0xbb, 0x5e, - 0xaf, 0xcc, 0x26, 0x70, 0xaa, 0x7a, 0xc4, 0xf0, 0xc5, 0xd0, 0xd0, 0xa7, - 0xa1, 0xab, 0x35, 0x31, 0xb9, 0x80, 0xb1, 0x4d, 0x83, 0xb6, 0xc6, 0xba, - 0x19, 0xb2, 0x3e, 0x35, 0x5a, 0x2e, 0xb3, 0x3a, 0xf0, 0xf1, 0xae, 0xf2, - 0x49, 0x3e, 0x4e, 0x4b, 0x38, 0x50, 0x53, 0x50, 0xde, 0x2b, 0xa7, 0xf7, - 0xa9, 0x5d, 0x83, 0xe4, 0x3b, 0x96, 0x85, 0xf0, 0xc4, 0xe0, 0x84, 0xb4, - 0xbd, 0x89, 0xb7, 0x5c, 0x90, 0x54, 0xc0, 0x97, 0x05, 0x1c, 0x31, 0x20, - 0x72, 0x3c, 0xcf, 0xb6, 0xb0, 0x70, 0xc6, 0x81, 0xfe, 0xe1, 0xf6, 0x85, - 0xee, 0x3b, 0x89, 0xda, 0x72, 0x84, 0x0c, 0x6b, 0x11, 0x52, 0x54, 0x5a, - 0x97, 0xe5, 0x07, 0x7a, 0xe3, 0xf5, 0xa0, 0xb5, 0x16, 0xa9, 0x83, 0xcf, - 0x15, 0x2e, 0x19, 0x99, 0xf0, 0xf8, 0xf7, 0xae, 0xda, 0x70, 0x90, 0x04, - 0xc6, 0xf9, 0x20, 0xaf, 0x61, 0x42, 0x69, 0xf5, 0x5e, 0x48, 0x18, 0xc6, - 0x4d, 0x3c, 0x04, 0xa8, 0x21, 0x1f, 0xd0, 0xe1, 0x6f, 0xb3, 0xe0, 0xc0, - 0x64, 0x4e, 0xde, 0x1c, 0x9f, 0x1d, 0x1f, 0x1c, 0xbf, 0x6c, 0x15, 0x41, - 0x13, 0x52, 0x10, 0x8b, 0xb9, 0x33, 0x0a, 0x56, 0x2c, 0x25, 0x21, 0x6f, - 0x44, 0x32, 0x43, 0x2e, 0x97, 0x80, 0x08, 0x37, 0x41, 0x23, 0x2c, 0x9b, - 0xed, 0x70, 0xbb, 0x40, 0xb4, 0xe0, 0x79, 0xa1, 0xb2, 0x93, 0x0f, 0xe6, - 0xb0, 0xde, 0x70, 0x2d, 0xe7, 0x40, 0x77, 0x93, 0xf4, 0x86, 0x2f, 0x21, - 0xee, 0x83, 0xd6, 0x14, 0x2d, 0x9a, 0xb2, 0xae, 0x68, 0xc7, 0x85, 0x73, - 0xf6, 0x12, 0xd7, 0x06, 0xb5, 0xb1, 0x71, 0x51, 0xbc, 0x9f, 0xcf, 0x92, - 0xeb, 0xa2, 0x1c, 0xaa, 0x94, 0x58, 0x4c, 0x69, 0x0a, 0x30, 0x2f, 0x9c, - 0x43, 0x8a, 0x9a, 0xab, 0xbc, 0x8c, 0xe6, 0x5f, 0x78, 0xf9, 0x0d, 0x52, - 0x21, 0xee, 0x20, 0xae, 0xa9, 0x23, 0x3c, 0x18, 0x58, 0xd8, 0x36, 0x3f, - 0x06, 0x96, 0xa8, 0x88, 0x26, 0xf1, 0x39, 0xb4, 0x40, 0xa2, 0x7d, 0xf4, - 0x01, 0x93, 0xe2, 0xf8, 0x86, 0x95, 0x43, 0xe2, 0x0a, 0xe5, 0x7c, 0x3a, - 0xa5, 0x07, 0x81, 0xb1, 0xbe, 0xca, 0x07, 0x65, 0x51, 0x15, 0xa3, 0x1a, - 0x14, 0xd6, 0xe9, 0xb0, 0xb8, 0xae, 0x12, 0x19, 0x21, 0x6e, 0xf5, 0x14, - 0xa4, 0xbf, 0x2b, 0x24, 0xce, 0xd7, 0x07, 0x5f, 0x3c, 0x00, 0xfe, 0x5d, - 0x16, 0xa8, 0x34, 0xc2, 0x3c, 0xde, 0xdb, 0x68, 0xcf, 0x4e, 0xd6, 0x4f, - 0x37, 0x60, 0xbc, 0x8d, 0x35, 0xc7, 0xb7, 0x9f, 0x13, 0x07, 0x3c, 0x53, - 0x82, 0x3e, 0x51, 0x83, 0x27, 0x6f, 0x2a, 0xf0, 0xbf, 0x71, 0xc1, 0xf7, - 0x67, 0x7d, 0x9d, 0xa5, 0xef, 0xc5, 0x62, 0xf5, 0x60, 0x8c, 0xca, 0x20, - 0xda, 0x19, 0xf0, 0x21, 0x5c, 0x00, 0x31, 0xb3, 0xf2, 0xa8, 0xce, 0x5e, - 0xaa, 0x95, 0x99, 0x6d, 0xe1, 0xdc, 0xf9, 0x9b, 0x0c, 0x98, 0x10, 0xbc, - 0x27, 0x2b, 0xf4, 0x85, 0x19, 0xc6, 0xdb, 0xc6, 0x46, 0x06, 0x55, 0x1a, - 0x42, 0x20, 0x0c, 0x6f, 0x0c, 0x24, 0xde, 0x24, 0x47, 0x56, 0x79, 0x05, - 0x68, 0x4e, 0xe9, 0xfb, 0x2f, 0x1e, 0xd0, 0xab, 0x38, 0x3c, 0x14, 0xe5, - 0xb7, 0xfa, 0x5f, 0x75, 0x93, 0xed, 0xfe, 0x16, 0xfe, 0xd8, 0xee, 0x26, - 0x3b, 0xf4, 0xf2, 0x6e, 0xc2, 0xf6, 0x66, 0xde, 0x63, 0x21, 0x17, 0x3b, - 0x92, 0x64, 0xd3, 0xb9, 0xcc, 0x60, 0x44, 0x45, 0x59, 0xa2, 0xb8, 0xba, - 0x84, 0x9e, 0x89, 0xcf, 0xbd, 0xda, 0x97, 0xe1, 0xbf, 0xb5, 0xfd, 0x00, - 0xc2, 0x03, 0x71, 0xa8, 0x6c, 0x5a, 0x9b, 0x55, 0x34, 0xc1, 0xa1, 0xc2, - 0x16, 0x4e, 0xc7, 0x45, 0x8a, 0xe2, 0x34, 0x3e, 0x5c, 0xb1, 0x69, 0x0e, - 0xa8, 0xb0, 0xff, 0xc5, 0x83, 0xbb, 0x96, 0x14, 0xdd, 0x05, 0x6e, 0xc5, - 0xb8, 0x39, 0xa0, 0x51, 0x1c, 0x6a, 0x01, 0x0a, 0x3a, 0xd3, 0x31, 0x37, - 0x09, 0x2d, 0x76, 0x79, 0x15, 0x5d, 0x83, 0xa1, 0x29, 0x74, 0x39, 0x2c, - 0xac, 0x3c, 0x7e, 0x98, 0xd8, 0xfa, 0xed, 0xf6, 0x93, 0x67, 0x32, 0x58, - 0x26, 0x46, 0xb4, 0x69, 0xd2, 0x23, 0x20, 0xb9, 0x83, 0x62, 0x8b, 0xd7, - 0xdf, 0x39, 0xda, 0xe6, 0x81, 0x51, 0x3f, 0xe0, 0x0b, 0xb3, 0x2e, 0x66, - 0xf9, 0x00, 0x05, 0x1f, 0x24, 0xac, 0xf9, 0x4c, 0x5e, 0xdd, 0x9c, 0x15, - 0x15, 0xa9, 0x05, 0xfa, 0xde, 0x0c, 0x94, 0xeb, 0x1c, 0x54, 0x3a, 0x32, - 0x38, 0xf2, 0x4b, 0x7d, 0x19, 0xd2, 0x03, 0xea, 0x05, 0xc6, 0x69, 0x42, - 0xae, 0x1a, 0x4f, 0x92, 0xf5, 0x9b, 0xac, 0x56, 0x0d, 0x10, 0x9d, 0x24, - 0xbc, 0x12, 0x7e, 0x88, 0x62, 0x04, 0x98, 0x15, 0xb3, 0x5d, 0x73, 0xf1, - 0x4c, 0x32, 0x20, 0x6f, 0xb3, 0xd9, 0xc2, 0xb7, 0xb8, 0xea, 0x81, 0x7a, - 0x75, 0x69, 0xbe, 0x78, 0xd0, 0x5c, 0x6c, 0xf4, 0xbc, 0x70, 0x17, 0xe8, - 0xbd, 0x80, 0xe3, 0x0e, 0xfc, 0x1b, 0x6e, 0x8b, 0x57, 0x70, 0x88, 0xd3, - 0x0b, 0x6a, 0xcb, 0x0e, 0x0c, 0xa9, 0x8b, 0xf9, 0x04, 0xe8, 0x12, 0xd8, - 0x63, 0x42, 0x46, 0x7e, 0xbc, 0xcf, 0x70, 0x00, 0xa4, 0x92, 0x65, 0xe9, - 0x04, 0x5e, 0xf8, 0xe2, 0x01, 0xc8, 0x03, 0x79, 0xca, 0x26, 0xd6, 0xb0, - 0x7f, 0x42, 0x0e, 0x79, 0x6d, 0xfd, 0x9e, 0x9e, 0x2c, 0xec, 0x0c, 0x7e, - 0x88, 0xb4, 0x6c, 0xcf, 0x2b, 0x15, 0x9e, 0x1e, 0x2c, 0x3e, 0x7c, 0x7a, - 0xfa, 0xc2, 0x36, 0x71, 0x07, 0xf8, 0xe5, 0x2c, 0x98, 0xb2, 0xf5, 0x2d, - 0x60, 0x0b, 0x8b, 0xaf, 0xc1, 0x87, 0xc9, 0xfa, 0xb0, 0x4c, 0x81, 0xd7, - 0x3c, 0xda, 0x20, 0x7b, 0x32, 0xef, 0x79, 0xd4, 0x9e, 0xb6, 0xf0, 0xea, - 0xfb, 0xb6, 0xb3, 0x0b, 0x1f, 0xdb, 0xa3, 0xdb, 0x44, 0x87, 0x4c, 0x05, - 0x34, 0x69, 0x1d, 0xbb, 0x35, 0xa1, 0xe7, 0xff, 0xad, 0x52, 0x4a, 0x90, - 0xd1, 0x90, 0x9e, 0xa6, 0xfc, 0x4c, 0xbc, 0x93, 0x28, 0x32, 0xd1, 0xa3, - 0x68, 0x41, 0x76, 0x7b, 0x89, 0x77, 0xdc, 0x83, 0x45, 0x3a, 0x67, 0x57, - 0x18, 0xf4, 0xf1, 0x1c, 0x1d, 0x19, 0xf4, 0x1e, 0x5e, 0x25, 0xe3, 0x29, - 0x88, 0x79, 0x74, 0xad, 0x90, 0x7b, 0xa5, 0xa2, 0xce, 0xc8, 0x92, 0x93, - 0x0e, 0x88, 0xa5, 0x56, 0xc8, 0xab, 0x91, 0x3e, 0xf9, 0x86, 0xc6, 0xab, - 0x14, 0x3b, 0xae, 0xa0, 0x0f, 0xb2, 0x22, 0xd7, 0x74, 0xca, 0xc9, 0x7f, - 0x42, 0xa6, 0x0b, 0x9a, 0x20, 0xdf, 0xaa, 0x15, 0xfb, 0x8f, 0x48, 0x1c, - 0xe7, 0x91, 0xd3, 0x9b, 0x61, 0x87, 0xcf, 0xdc, 0xea, 0xcb, 0x19, 0xc6, - 0x8f, 0xc2, 0xde, 0x52, 0x63, 0xbc, 0x70, 0xba, 0x63, 0x3f, 0x9d, 0xf2, - 0x52, 0xfd, 0x94, 0x9d, 0x9f, 0x16, 0x68, 0xe9, 0x75, 0xfb, 0x83, 0x5c, - 0x6f, 0x73, 0xbb, 0x8f, 0x1e, 0x3e, 0x54, 0x5e, 0xc7, 0xb9, 0x8a, 0xcc, - 0x28, 0xe3, 0xe3, 0x5d, 0x10, 0x1e, 0x3b, 0xe5, 0xcb, 0xf8, 0x87, 0x37, - 0x87, 0xf0, 0xec, 0xab, 0xc3, 0xb3, 0xc3, 0x37, 0xee, 0x46, 0x9e, 0x16, - 0xe5, 0x04, 0x2e, 0xc9, 0x1b, 0xe0, 0x28, 0xd5, 0x6c, 0x9c, 0xde, 0xa0, - 0x1e, 0x02, 0x2c, 0xec, 0xa2, 0x24, 0x09, 0x80, 0x8c, 0x28, 0xc9, 0x70, - 0x4e, 0x0a, 0x46, 0x01, 0x12, 0x2d, 0xf3, 0xe0, 0x2e, 0x2c, 0x1b, 0xdd, - 0xfe, 0x2a, 0x6d, 0x51, 0x7b, 0xc1, 0xcb, 0x64, 0xae, 0x58, 0x91, 0xf4, - 0xba, 0x4e, 0x82, 0x22, 0xc7, 0x86, 0x88, 0x98, 0xc0, 0x21, 0x26, 0x24, - 0x42, 0xd0, 0x29, 0x1b, 0x67, 0x23, 0xd0, 0x6d, 0x13, 0xd8, 0xb3, 0xbe, - 0x39, 0x10, 0x17, 0x86, 0xa2, 0xa3, 0x24, 0xce, 0x6b, 0xad, 0x92, 0x63, - 0x02, 0xa5, 0x06, 0xd6, 0x1d, 0x50, 0xf6, 0x86, 0x0d, 0x00, 0xc2, 0x1a, - 0x92, 0x55, 0x2e, 0x13, 0x27, 0xef, 0x88, 0x5c, 0x6f, 0xc9, 0xfa, 0xfb, - 0x6e, 0xf2, 0xaa, 0x9b, 0xfc, 0xd0, 0x4d, 0xce, 0xba, 0xc9, 0xc9, 0x06, - 0x3b, 0xbd, 0xb6, 0xb7, 0x76, 0x1e, 0xb2, 0xfb, 0x8e, 0x5d, 0x73, 0x6a, - 0x85, 0xdb, 0x7e, 0x8f, 0x47, 0x9d, 0xbf, 0xc5, 0xc6, 0xa1, 0xc1, 0xed, - 0x57, 0x2c, 0xa4, 0xe2, 0xc7, 0x0f, 0x9f, 0x3c, 0xfa, 0xf2, 0xb1, 0x7c, - 0xe3, 0x05, 0xb8, 0x30, 0x4e, 0x78, 0x4c, 0xa5, 0x5d, 0x1e, 0x34, 0xc8, - 0x34, 0xf9, 0x34, 0x45, 0x3d, 0x47, 0x15, 0x7d, 0x72, 0x36, 0xe5, 0xec, - 0xd0, 0x64, 0xe3, 0x26, 0x37, 0xa3, 0x02, 0x17, 0x3a, 0x95, 0xd0, 0xed, - 0xa3, 0x1b, 0xc0, 0x97, 0x96, 0xd8, 0x3a, 0xd2, 0x73, 0x72, 0x78, 0xa2, - 0x5c, 0x46, 0x62, 0x89, 0xf5, 0x46, 0xdd, 0x69, 0x6f, 0x24, 0xa1, 0xb2, - 0x71, 0x21, 0xaf, 0x58, 0xca, 0xa7, 0xd1, 0x34, 0x17, 0x18, 0x0d, 0x50, - 0x41, 0xd0, 0x24, 0x23, 0x52, 0x31, 0x87, 0xeb, 0x12, 0xbe, 0x86, 0x87, - 0x40, 0x60, 0xe2, 0xd7, 0x9c, 0x6c, 0x3d, 0x61, 0x83, 0x93, 0x35, 0x24, - 0xed, 0xc0, 0x00, 0xe1, 0xcf, 0x19, 0x50, 0x4b, 0x46, 0x23, 0x8a, 0xdd, - 0xb6, 0xe4, 0xb5, 0x4c, 0x93, 0xe6, 0x5b, 0x74, 0x2f, 0xd2, 0x85, 0x4e, - 0xca, 0x11, 0xfc, 0x05, 0x2a, 0x46, 0x42, 0x66, 0x23, 0x20, 0x96, 0x8a, - 0xac, 0xba, 0x24, 0x5c, 0x9b, 0xc5, 0x1c, 0x48, 0x8c, 0xae, 0x42, 0x51, - 0x2f, 0xa4, 0x43, 0xd5, 0xb1, 0x0b, 0xd1, 0xf9, 0x54, 0x33, 0x20, 0x33, - 0x6e, 0x78, 0x27, 0x59, 0xff, 0x76, 0xa3, 0xbb, 0xa0, 0x29, 0x88, 0x18, - 0xaf, 0x07, 0x97, 0x36, 0x50, 0x05, 0x3b, 0xd6, 0x97, 0xa1, 0x5d, 0x3c, - 0xbb, 0xc2, 0xe6, 0x70, 0xcd, 0xe8, 0xe8, 0x85, 0xfd, 0x09, 0x82, 0xe0, - 0x0c, 0x96, 0x90, 0x1d, 0xd2, 0xd3, 0x1b, 0x19, 0xb0, 0x5b, 0x14, 0x25, - 0x0a, 0xdd, 0xa5, 0xa6, 0x6f, 0x3b, 0xe3, 0x48, 0x89, 0xb0, 0x49, 0xe7, - 0x20, 0xee, 0xaa, 0x3a, 0x54, 0x8c, 0x64, 0xd2, 0x17, 0x24, 0x05, 0xd3, - 0x0a, 0x76, 0xc9, 0xe3, 0x2a, 0x8f, 0xf7, 0xe0, 0x69, 0xa5, 0x54, 0x68, - 0x0f, 0x96, 0x17, 0x04, 0x32, 0x3a, 0x12, 0x6a, 0xa0, 0x23, 0x53, 0xb5, - 0x52, 0x44, 0x83, 0x20, 0x78, 0x47, 0x40, 0x18, 0x82, 0x53, 0x80, 0xb2, - 0xaa, 0x33, 0xff, 0xb2, 0x7e, 0x55, 0xc1, 0xc2, 0xe2, 0x79, 0x27, 0x09, - 0x09, 0x6d, 0xce, 0x87, 0x6f, 0x4e, 0x2d, 0x42, 0x83, 0x96, 0x0d, 0xc4, - 0x28, 0x90, 0xd3, 0x2f, 0x90, 0x26, 0x33, 0x16, 0x1a, 0x2a, 0x3e, 0x1e, - 0x4f, 0xfa, 0x5f, 0xf5, 0xb7, 0xfb, 0x36, 0x51, 0x72, 0x6c, 0x82, 0x26, - 0x97, 0x62, 0x8f, 0x72, 0x95, 0x74, 0xc9, 0x64, 0x8e, 0x46, 0x7f, 0x66, - 0x2e, 0x25, 0x3b, 0xa6, 0x12, 0xdf, 0xa8, 0x69, 0x49, 0x68, 0xcb, 0xbf, - 0xc1, 0x0f, 0x06, 0x73, 0x36, 0xba, 0xa1, 0x39, 0x1e, 0x1a, 0x77, 0xad, - 0x4f, 0xd1, 0xbb, 0x52, 0x02, 0x9f, 0xe4, 0x25, 0xb1, 0x5e, 0xf8, 0x80, - 0xda, 0x8b, 0x35, 0xf9, 0xab, 0xf0, 0xf4, 0xe4, 0xd3, 0xc1, 0x78, 0x3e, - 0xcc, 0xec, 0x6a, 0x83, 0x0f, 0xd0, 0x25, 0xca, 0x1b, 0x2c, 0x87, 0x0e, - 0xa4, 0x9e, 0xc1, 0x65, 0x30, 0xe3, 0x8f, 0x40, 0x10, 0xd2, 0xc7, 0x99, - 0x19, 0x4f, 0xeb, 0xb2, 0x18, 0xce, 0x07, 0xa8, 0x25, 0x5d, 0x92, 0x7b, - 0xa5, 0xe1, 0xa6, 0x4f, 0xc7, 0xd7, 0xc8, 0x25, 0xc6, 0x30, 0xb4, 0x29, - 0xb7, 0x46, 0x8b, 0x8b, 0x2b, 0x51, 0xd5, 0xbc, 0x56, 0xda, 0x60, 0x4e, - 0x66, 0x57, 0x51, 0x13, 0xf4, 0x2a, 0x51, 0xd5, 0x1e, 0xff, 0xe8, 0x57, - 0xd9, 0x26, 0x8e, 0x31, 0x84, 0x5f, 0xa8, 0x46, 0x13, 0xe6, 0xc0, 0x26, - 0x19, 0x5d, 0x46, 0x59, 0x47, 0x76, 0x5a, 0xd0, 0x40, 0xe0, 0x84, 0x14, - 0xd7, 0xa6, 0x43, 0xcb, 0x38, 0x44, 0x25, 0x1f, 0xc0, 0x18, 0x69, 0xf6, - 0x7b, 0x0b, 0xdd, 0xc2, 0xfa, 0x55, 0x9b, 0xd0, 0x22, 0xb6, 0x47, 0xae, - 0xa7, 0x2f, 0xbe, 0x38, 0xa6, 0x70, 0x1d, 0x51, 0xfe, 0x8e, 0x45, 0xd8, - 0xa6, 0x8b, 0x57, 0x74, 0x0d, 0x72, 0x13, 0xe3, 0x79, 0xaf, 0xaf, 0x0b, - 0xb2, 0xf6, 0x13, 0x6f, 0x7d, 0x45, 0x2e, 0xfe, 0x91, 0xb7, 0xcf, 0x57, - 0x89, 0xd9, 0x8d, 0xd5, 0xe0, 0x9a, 0x0e, 0x87, 0x39, 0xe9, 0x68, 0x63, - 0x35, 0x01, 0x93, 0x1b, 0x4d, 0x98, 0xde, 0x84, 0xf7, 0xde, 0x1c, 0xc3, - 0x35, 0xb9, 0xd8, 0xec, 0x4c, 0xca, 0x28, 0xbc, 0x71, 0x7c, 0x48, 0x76, - 0x71, 0xb6, 0xb2, 0xc2, 0xa9, 0x43, 0xaf, 0xef, 0x50, 0x6c, 0xd1, 0xe6, - 0xf2, 0x45, 0xbb, 0x8e, 0xf8, 0x81, 0xfb, 0x61, 0x89, 0x61, 0xbd, 0xa0, - 0xad, 0x0e, 0x3b, 0x2d, 0x7a, 0xd8, 0x4e, 0x07, 0xb9, 0xd8, 0x24, 0xd1, - 0xe3, 0x29, 0x73, 0x00, 0x36, 0x33, 0x4c, 0xbc, 0x7b, 0xa7, 0x4b, 0x0a, - 0x2b, 0xba, 0x41, 0xe6, 0x1a, 0x32, 0xd2, 0x94, 0xdc, 0x31, 0x66, 0x89, - 0x2c, 0x89, 0xea, 0x83, 0xcf, 0x6b, 0xe5, 0xfc, 0x15, 0xcf, 0xbb, 0x0b, - 0xfb, 0x86, 0xcf, 0x5e, 0x5c, 0x92, 0xa7, 0x9f, 0x1e, 0xce, 0xcd, 0x85, - 0x00, 0x3c, 0x0e, 0x54, 0x99, 0x8c, 0x6c, 0x65, 0x62, 0xab, 0x2b, 0xca, - 0xbe, 0x90, 0xc6, 0xb8, 0xc0, 0x5d, 0x66, 0x9f, 0x17, 0x8d, 0x9b, 0x86, - 0x4d, 0xfc, 0x43, 0x82, 0xa7, 0x7c, 0x7c, 0x8a, 0xb4, 0x47, 0xbb, 0x50, - 0x59, 0x57, 0x6e, 0x5c, 0xd1, 0xb0, 0x54, 0xd8, 0xa3, 0xb5, 0x51, 0xda, - 0xd3, 0xcd, 0x64, 0xd3, 0x19, 0x5c, 0x69, 0xb8, 0x17, 0xc4, 0xcb, 0x39, - 0x46, 0xa5, 0xb1, 0xa5, 0xe6, 0xdf, 0x09, 0xeb, 0x43, 0xc6, 0x35, 0x50, - 0x03, 0x33, 0xb2, 0xb0, 0xf0, 0x7e, 0x93, 0xc7, 0x94, 0x6f, 0xac, 0x16, - 0x17, 0x9a, 0xf9, 0x5d, 0xcd, 0xf7, 0x49, 0x11, 0x4e, 0x22, 0x10, 0xe8, - 0x88, 0x7a, 0xc7, 0xb0, 0x3b, 0xec, 0xdc, 0xef, 0x5d, 0x25, 0xc8, 0xc8, - 0x81, 0xed, 0xe0, 0x66, 0xf7, 0x8e, 0x5f, 0x5e, 0x29, 0x4b, 0x9e, 0x82, - 0x3e, 0x31, 0x45, 0xb7, 0x6d, 0x97, 0x1b, 0x39, 0x2f, 0x0a, 0x38, 0xb5, - 0x61, 0x5a, 0x24, 0x44, 0x64, 0x53, 0x64, 0xa4, 0xea, 0x3f, 0x82, 0x8b, - 0x85, 0x1d, 0x4c, 0xd8, 0xf2, 0x0d, 0xda, 0xa5, 0xd3, 0x0b, 0x75, 0x41, - 0x08, 0xcf, 0x0d, 0x8f, 0x4e, 0x0b, 0x79, 0x9a, 0x36, 0x88, 0x82, 0x16, - 0xba, 0x8e, 0x7f, 0xb1, 0xa7, 0x27, 0x98, 0xae, 0xc4, 0x7d, 0x84, 0xf6, - 0x03, 0x71, 0x73, 0xa2, 0xe7, 0x27, 0x58, 0x78, 0xa1, 0xb9, 0x0e, 0xb4, - 0xf4, 0xa2, 0xb8, 0x46, 0xd5, 0xbd, 0xcb, 0xce, 0xa2, 0xbc, 0x92, 0x08, - 0x00, 0xd4, 0x5a, 0x41, 0x3f, 0x83, 0x75, 0xa4, 0x50, 0x12, 0xfa, 0x90, - 0x8c, 0x96, 0x78, 0xfc, 0x1d, 0x8b, 0x97, 0xbe, 0x6c, 0x0b, 0x47, 0xde, - 0x52, 0x45, 0x46, 0x79, 0x18, 0x38, 0xee, 0x44, 0x5e, 0xd1, 0x36, 0x75, - 0x59, 0x48, 0xae, 0xd4, 0x4b, 0x46, 0xc6, 0xab, 0x12, 0x0f, 0x5c, 0xcd, - 0x27, 0x09, 0xe7, 0xc3, 0xc7, 0x8f, 0x96, 0x42, 0xcd, 0x0e, 0x2c, 0x38, - 0xb9, 0xf5, 0xe4, 0x57, 0xba, 0xb0, 0x91, 0x83, 0x6c, 0x56, 0x9b, 0x8b, - 0x3a, 0xa2, 0x21, 0x5c, 0x71, 0xf4, 0x78, 0xc2, 0xb5, 0x99, 0x24, 0x3f, - 0xd0, 0x2f, 0xfa, 0x80, 0x90, 0x6b, 0x9d, 0xb2, 0x8f, 0x2c, 0x2f, 0x95, - 0xa6, 0x70, 0x0c, 0xa8, 0x53, 0x90, 0x66, 0x8a, 0xc6, 0x3e, 0x50, 0x7c, - 0xb2, 0x52, 0x66, 0xe1, 0x8e, 0x35, 0x92, 0xff, 0x78, 0x2c, 0xac, 0x30, - 0x50, 0x8a, 0x5c, 0x44, 0x18, 0x10, 0x44, 0xfd, 0xed, 0xb1, 0x37, 0x09, - 0x1d, 0x22, 0x3d, 0xbc, 0x5d, 0x6e, 0xba, 0xfc, 0x81, 0x44, 0xc7, 0x75, - 0xc5, 0xdb, 0xa4, 0x21, 0x50, 0x3d, 0xa3, 0xe0, 0xae, 0xff, 0x74, 0x92, - 0x7e, 0xe8, 0xfa, 0xc7, 0xba, 0x8d, 0x3b, 0x9c, 0xbe, 0x44, 0x11, 0x57, - 0xdb, 0xc3, 0x5d, 0xea, 0x91, 0xdd, 0x9b, 0xbe, 0x02, 0x65, 0x04, 0xfe, - 0x90, 0x5f, 0x6f, 0x80, 0xa8, 0x44, 0xa0, 0xa1, 0x4f, 0x6a, 0x0c, 0x1e, - 0xe9, 0xa5, 0xd5, 0x20, 0xcf, 0xdd, 0xdf, 0x20, 0x1a, 0x8f, 0xf2, 0x0b, - 0x6d, 0x8f, 0x3f, 0xcb, 0x87, 0xc8, 0xa5, 0xe4, 0x0f, 0x94, 0xc8, 0xed, - 0x2f, 0x3e, 0x1a, 0x3d, 0x74, 0x3d, 0x16, 0x95, 0x9e, 0xee, 0x5e, 0x2f, - 0x3d, 0xaf, 0xf0, 0xeb, 0xba, 0x37, 0x9f, 0xe6, 0x1f, 0x7a, 0x15, 0xab, - 0x28, 0x4f, 0x67, 0x69, 0x7d, 0xf9, 0xed, 0x17, 0x0f, 0xf0, 0x91, 0x75, - 0x14, 0xe5, 0x36, 0x34, 0x88, 0xc9, 0x02, 0x2e, 0xf0, 0xde, 0x93, 0x57, - 0x93, 0xe4, 0x2d, 0xbc, 0x0b, 0xdc, 0x60, 0x82, 0x5b, 0xc5, 0x4d, 0x74, - 0x4d, 0xc2, 0x41, 0xdf, 0x2a, 0x35, 0x14, 0xac, 0x5f, 0x70, 0xf0, 0x6b, - 0xd4, 0x6f, 0xfa, 0xc9, 0xeb, 0xa2, 0xce, 0xf6, 0xe8, 0x6f, 0xa4, 0x15, - 0xa2, 0x5c, 0xb1, 0x71, 0xe1, 0x08, 0xd8, 0xe0, 0x8f, 0x92, 0xb2, 0xf4, - 0xc4, 0x0d, 0xc9, 0x20, 0x9b, 0x8e, 0xde, 0xef, 0x3a, 0xdd, 0xe4, 0x92, - 0x8f, 0x0a, 0xf7, 0xc2, 0xb3, 0xb0, 0x78, 0x20, 0x6c, 0x9d, 0xa4, 0x60, - 0xe0, 0x59, 0xdc, 0x10, 0x47, 0x13, 0xd0, 0x89, 0x12, 0xcb, 0x8f, 0x39, - 0xf8, 0xe9, 0xf6, 0x59, 0xb2, 0x3a, 0x12, 0x05, 0x49, 0xf7, 0x92, 0x8c, - 0x48, 0x82, 0x41, 0x70, 0xc1, 0xab, 0xae, 0xdc, 0xfe, 0x15, 0xf9, 0xd2, - 0xd4, 0xff, 0xc7, 0x67, 0x0b, 0x96, 0xfd, 0x81, 0xf7, 0x71, 0xf0, 0x5f, - 0x12, 0x57, 0xdb, 0xde, 0x1b, 0xff, 0x43, 0xcb, 0xd1, 0xe2, 0x03, 0x90, - 0xf6, 0x4e, 0xb3, 0x8c, 0xe5, 0xc0, 0x9e, 0x7f, 0x37, 0x6c, 0xf2, 0xb8, - 0xee, 0x55, 0x57, 0x83, 0xe4, 0x29, 0xca, 0xd1, 0xc8, 0x73, 0xfc, 0xde, - 0x9e, 0x6e, 0x24, 0x87, 0xd3, 0x20, 0x3b, 0xea, 0xb3, 0x7c, 0xec, 0x59, - 0xbe, 0xa3, 0x50, 0x0b, 0x79, 0x15, 0x83, 0x4f, 0x73, 0xd1, 0xf4, 0xf1, - 0x2a, 0xa7, 0x86, 0xc8, 0xf1, 0x4d, 0x4a, 0xba, 0xbc, 0x0d, 0x0c, 0x7b, - 0x20, 0x2f, 0x75, 0xc5, 0xa3, 0xca, 0x16, 0x6d, 0x5a, 0x85, 0x64, 0x9f, - 0x4e, 0x2c, 0x5e, 0x8e, 0x2a, 0x9b, 0xca, 0x4a, 0xaa, 0x36, 0xc8, 0x8b, - 0xc8, 0x8d, 0xc0, 0xda, 0xa1, 0x91, 0x7d, 0x68, 0xfa, 0x90, 0x0d, 0x85, - 0xf9, 0x0f, 0xfb, 0x56, 0x2f, 0x51, 0xeb, 0x39, 0x87, 0x9b, 0x8c, 0x1b, - 0x9a, 0x14, 0x43, 0x8a, 0xa0, 0xd3, 0x15, 0x3f, 0xb5, 0xc0, 0x99, 0x4e, - 0x27, 0x09, 0x2d, 0xac, 0x63, 0x18, 0x12, 0x86, 0xc3, 0x4c, 0x2f, 0xea, - 0xcb, 0x0d, 0x9e, 0x13, 0x45, 0x8c, 0xa8, 0x09, 0x0c, 0x7a, 0x36, 0x2f, - 0x21, 0x37, 0x8c, 0x0e, 0x24, 0xda, 0xb0, 0xdf, 0xe6, 0x55, 0x4d, 0xe1, - 0x7f, 0xb2, 0x74, 0x32, 0xda, 0x29, 0x30, 0xa7, 0x49, 0x51, 0xde, 0x68, - 0xcf, 0xb4, 0x7e, 0x30, 0x07, 0x61, 0x8a, 0x42, 0x09, 0x4d, 0x9a, 0xa1, - 0x16, 0xd9, 0x88, 0x10, 0xfc, 0x5d, 0x6c, 0x17, 0x1b, 0x8f, 0x65, 0x6d, - 0x64, 0xea, 0x15, 0x19, 0x9c, 0x03, 0x95, 0x71, 0xac, 0x9e, 0x34, 0x4b, - 0x37, 0x3e, 0x0f, 0xba, 0xef, 0x76, 0x5e, 0x1d, 0x33, 0x72, 0x12, 0x9b, - 0xfd, 0x73, 0x88, 0xa8, 0x37, 0x9a, 0xde, 0x4e, 0xa8, 0xd2, 0x2a, 0xfc, - 0x1f, 0xa3, 0x7e, 0x6e, 0x21, 0xcc, 0x7d, 0xf5, 0x38, 0x7d, 0xd9, 0x7f, - 0xfc, 0x10, 0xd5, 0x05, 0x47, 0xa9, 0xc0, 0x1a, 0x8b, 0xf1, 0x95, 0x32, - 0x26, 0x89, 0xaf, 0xec, 0xd5, 0x45, 0x20, 0xdb, 0xe9, 0x4d, 0x3a, 0x07, - 0x75, 0xc5, 0xf3, 0xa1, 0xe7, 0xf9, 0x05, 0xfa, 0xee, 0x48, 0xb4, 0x9a, - 0x63, 0x50, 0x6f, 0x9d, 0x4b, 0x08, 0x24, 0x3b, 0x9b, 0xf1, 0xd3, 0x02, - 0x05, 0x7c, 0x74, 0xfb, 0x01, 0x2b, 0x27, 0x8b, 0x8c, 0x5c, 0xbe, 0x4a, - 0x19, 0x74, 0x32, 0x07, 0xd4, 0xcc, 0x34, 0x13, 0xfd, 0x0b, 0x6d, 0xf9, - 0x09, 0x46, 0xc9, 0xc1, 0x15, 0x96, 0xe6, 0x13, 0x22, 0x6f, 0xb1, 0x8e, - 0x69, 0x5c, 0x67, 0xc5, 0xb1, 0x9a, 0x20, 0xc1, 0x73, 0x43, 0x1c, 0x3c, - 0xc1, 0xc1, 0xa7, 0x48, 0xca, 0xa2, 0xe1, 0x4a, 0x2c, 0xe6, 0x65, 0x36, - 0x78, 0x1f, 0x84, 0x70, 0xd5, 0x18, 0x7b, 0x97, 0xc0, 0x69, 0x28, 0x34, - 0x15, 0x3e, 0x9f, 0x57, 0xdc, 0xd0, 0xac, 0xa8, 0xaa, 0x1c, 0xc3, 0x9b, - 0xf2, 0x29, 0xe8, 0x19, 0x6a, 0x23, 0xfb, 0x00, 0x67, 0x41, 0x39, 0x65, - 0x02, 0x4c, 0x77, 0x3a, 0x04, 0x46, 0x9e, 0xcf, 0x64, 0x34, 0x81, 0x9a, - 0x58, 0xb6, 0x7a, 0xa0, 0x2e, 0x37, 0xd1, 0x2a, 0x2b, 0x31, 0x9c, 0xa6, - 0x41, 0xab, 0x69, 0x5d, 0xaf, 0xae, 0x68, 0x2c, 0x78, 0xa9, 0x23, 0x95, - 0x70, 0x43, 0xc3, 0x42, 0xc3, 0x91, 0xce, 0xd3, 0x2a, 0x1f, 0xe0, 0x25, - 0x32, 0xcc, 0x41, 0xf3, 0xa9, 0xf1, 0xb7, 0x69, 0x3d, 0x9e, 0x74, 0x65, - 0xd7, 0xa6, 0xd9, 0x45, 0x51, 0xe3, 0x65, 0xa8, 0xd4, 0xce, 0x36, 0x75, - 0xdb, 0x3b, 0xb5, 0x06, 0x47, 0x72, 0xac, 0x58, 0x49, 0xb0, 0x17, 0x31, - 0x96, 0x49, 0x20, 0x2e, 0x59, 0xe4, 0xba, 0xc2, 0x53, 0x73, 0x14, 0xe0, - 0xe0, 0x60, 0xa3, 0x88, 0x6d, 0xca, 0x03, 0x8b, 0xb5, 0x2c, 0xd5, 0xb3, - 0x13, 0xb6, 0xbe, 0xce, 0xe5, 0x72, 0xe3, 0x18, 0x6f, 0xf6, 0xa4, 0x8d, - 0xd1, 0xf5, 0x2f, 0xfb, 0x8d, 0xc7, 0x14, 0x95, 0x00, 0xf2, 0x58, 0x53, - 0x18, 0x31, 0x88, 0x04, 0x43, 0xd6, 0x2f, 0xc8, 0x19, 0x43, 0xb6, 0x08, - 0xb9, 0x1d, 0xd2, 0x12, 0x6d, 0x26, 0xe4, 0xcd, 0x09, 0x86, 0x70, 0xd9, - 0x6f, 0x1c, 0x23, 0x0f, 0x91, 0xde, 0x13, 0xd3, 0x41, 0xb0, 0x18, 0x8c, - 0x24, 0x7c, 0x5e, 0x16, 0x82, 0x38, 0x16, 0x70, 0x3d, 0x0c, 0x9a, 0x91, - 0xd5, 0x9c, 0x33, 0x4b, 0xe5, 0x60, 0xce, 0x78, 0xa1, 0x42, 0xf8, 0x32, - 0x1d, 0x48, 0xe4, 0x67, 0xdc, 0x10, 0xba, 0xf8, 0x88, 0x16, 0xb2, 0xd1, - 0x08, 0x0e, 0xc8, 0x1d, 0x57, 0x88, 0xb4, 0xc6, 0x5d, 0xc1, 0x1e, 0xef, - 0xcd, 0xae, 0x87, 0xab, 0x5d, 0x1c, 0x70, 0xa5, 0x7d, 0xb8, 0xd1, 0x06, - 0xba, 0xba, 0xf5, 0xb2, 0xcf, 0xbc, 0xfb, 0x7a, 0x32, 0x53, 0xfc, 0x3a, - 0x9d, 0xa1, 0x3f, 0x46, 0x0e, 0x27, 0x9a, 0x52, 0xd0, 0x0e, 0xbd, 0xa1, - 0xb1, 0x7f, 0x99, 0x06, 0x7b, 0xcb, 0x32, 0x75, 0x93, 0x88, 0x0b, 0x22, - 0x17, 0x15, 0x3b, 0x42, 0xe2, 0x1b, 0x52, 0x5b, 0x0a, 0x5c, 0xda, 0x70, - 0xf7, 0xb1, 0xab, 0xdf, 0x51, 0x35, 0xda, 0x43, 0x35, 0xc6, 0x56, 0xed, - 0x03, 0xee, 0xfc, 0xd2, 0x0b, 0x4a, 0xc1, 0x3e, 0x26, 0xab, 0xab, 0x86, - 0xb6, 0x01, 0x6b, 0x81, 0x2c, 0x79, 0x58, 0x04, 0x00, 0x7c, 0x31, 0x1a, - 0xa7, 0x17, 0xf8, 0x40, 0x7e, 0x31, 0x2d, 0x24, 0xb3, 0x42, 0xa5, 0x0d, - 0xb8, 0x26, 0xc8, 0xc4, 0xce, 0x46, 0xe1, 0x2a, 0x59, 0x67, 0xab, 0x02, - 0x8e, 0xe1, 0x18, 0x46, 0x7e, 0x7a, 0xfa, 0x62, 0xa3, 0x1f, 0x6f, 0x29, - 0x4d, 0x28, 0xb8, 0x8e, 0x65, 0x6a, 0xb4, 0xaf, 0x78, 0x4d, 0x35, 0x77, - 0x34, 0x79, 0x26, 0xc6, 0x9b, 0x5c, 0x45, 0x6a, 0x21, 0x17, 0x50, 0x00, - 0xb8, 0xad, 0xdb, 0x37, 0x9d, 0x57, 0xb8, 0x47, 0xab, 0xc5, 0x0e, 0x4d, - 0x1b, 0xc3, 0x68, 0x21, 0x62, 0x73, 0x71, 0xe3, 0x29, 0x66, 0x34, 0x70, - 0x61, 0x58, 0xdc, 0x39, 0x08, 0x9b, 0x4e, 0x7a, 0xb8, 0xae, 0x7a, 0x55, - 0x7e, 0x71, 0xf5, 0x10, 0x24, 0x2a, 0x16, 0x7b, 0xca, 0xed, 0xbf, 0xee, - 0xcd, 0xca, 0xab, 0x61, 0xb9, 0xf3, 0xd7, 0xbd, 0x32, 0xbb, 0xf8, 0xeb, - 0x5e, 0x55, 0x5e, 0xfd, 0xfa, 0xeb, 0xaf, 0xb1, 0xc4, 0x08, 0x07, 0x20, - 0xd9, 0xff, 0xe9, 0x34, 0xf9, 0xf1, 0x21, 0x85, 0x87, 0x53, 0xfa, 0x49, - 0x93, 0x07, 0x49, 0xf8, 0x9b, 0xde, 0xfa, 0x3a, 0x4d, 0xb1, 0x1a, 0x53, - 0x57, 0x41, 0x7e, 0xe3, 0x10, 0x6e, 0x8d, 0x94, 0xd1, 0xa0, 0x70, 0xa6, - 0xb5, 0xf3, 0x1b, 0x95, 0x5e, 0x2e, 0x0a, 0xa0, 0x8f, 0xcb, 0x09, 0x37, - 0x44, 0xe7, 0x98, 0xf6, 0x9c, 0x8c, 0xdf, 0xf3, 0xfa, 0x82, 0xb8, 0x75, - 0x63, 0x14, 0xc2, 0x93, 0x7d, 0xef, 0x30, 0x2b, 0x52, 0xfa, 0xb4, 0x6f, - 0x52, 0xc8, 0xb5, 0x6f, 0x26, 0x9b, 0x20, 0x06, 0xa5, 0x20, 0xdb, 0x80, - 0xa4, 0x9f, 0xce, 0x80, 0x93, 0x92, 0x72, 0x91, 0x72, 0x43, 0x14, 0xae, - 0x82, 0xb7, 0xdc, 0xbc, 0xc4, 0xb8, 0x57, 0x8c, 0xb8, 0x19, 0x4b, 0x22, - 0xc0, 0x3a, 0x77, 0xd0, 0xc3, 0xb0, 0x92, 0x0d, 0x19, 0xa7, 0x5c, 0x14, - 0x17, 0x3e, 0x9c, 0x51, 0x1a, 0x9a, 0xe4, 0x75, 0xad, 0xc1, 0xb2, 0x1c, - 0x77, 0x37, 0xa4, 0xee, 0xfd, 0x90, 0x89, 0x3e, 0x89, 0x17, 0xfa, 0x05, - 0x23, 0x03, 0x84, 0x5f, 0x32, 0x1d, 0x37, 0xcb, 0x3a, 0x89, 0xc5, 0x0d, - 0xc9, 0x55, 0xa4, 0xf6, 0x16, 0x8c, 0x0e, 0x44, 0xf1, 0x6c, 0x5c, 0xcc, - 0x81, 0x92, 0xd7, 0xa5, 0xed, 0x68, 0xbc, 0xa2, 0xcf, 0x4a, 0xaf, 0xb7, - 0x0d, 0x99, 0x9f, 0xb4, 0x41, 0x27, 0x22, 0x5c, 0x1b, 0x5d, 0x45, 0x22, - 0xb5, 0x89, 0xd3, 0xee, 0xd8, 0xfc, 0x0e, 0x99, 0xda, 0x3a, 0xe9, 0xc0, - 0xaf, 0x7b, 0xe9, 0xe4, 0xef, 0x7b, 0xf3, 0x0a, 0xf4, 0xbc, 0xaa, 0xee, - 0xed, 0xec, 0x65, 0x55, 0x47, 0x39, 0x65, 0xe7, 0x7d, 0x76, 0xb3, 0xc7, - 0xe1, 0x38, 0x9d, 0xd5, 0xe4, 0x99, 0x2f, 0x1f, 0xf5, 0xb7, 0x22, 0x79, - 0xc6, 0xf3, 0x4b, 0x62, 0xf4, 0x7a, 0x80, 0xe8, 0x8b, 0x85, 0xb3, 0x41, - 0x26, 0xf2, 0xe4, 0x7b, 0x7e, 0x29, 0x26, 0x48, 0x0d, 0xef, 0x27, 0x7a, - 0x20, 0xce, 0x86, 0x69, 0x45, 0x12, 0x9c, 0x2c, 0xb7, 0x1a, 0x4b, 0x3b, - 0x39, 0xeb, 0xe8, 0x1a, 0x6c, 0xc8, 0x7e, 0xf0, 0x86, 0xb0, 0x39, 0x27, - 0xdf, 0x10, 0x2d, 0x3d, 0xc6, 0x84, 0x00, 0x27, 0xe6, 0xe0, 0x10, 0x6e, - 0xc8, 0xac, 0x13, 0x39, 0x3b, 0x20, 0x88, 0xc7, 0x96, 0x92, 0x8e, 0x85, - 0x4a, 0xd6, 0x55, 0x5e, 0xcc, 0xab, 0xf1, 0x8d, 0x04, 0xe5, 0x89, 0xe1, - 0x82, 0x49, 0x89, 0x6c, 0x04, 0x89, 0x50, 0x7b, 0xc8, 0x43, 0x68, 0xce, - 0x46, 0xc6, 0x0a, 0x54, 0x34, 0x47, 0x43, 0x0f, 0x0a, 0xea, 0x2a, 0x45, - 0x38, 0xc1, 0x82, 0x1c, 0x81, 0xbc, 0x60, 0x26, 0x55, 0x6c, 0xac, 0x70, - 0x9b, 0x7a, 0xce, 0xcb, 0x5b, 0xd0, 0xb8, 0x4a, 0x49, 0x33, 0x98, 0x16, - 0xaa, 0xa9, 0xac, 0x78, 0x95, 0xce, 0x89, 0xa0, 0xf7, 0x66, 0x69, 0x55, - 0x61, 0x7c, 0x89, 0x35, 0xfe, 0x11, 0x77, 0x29, 0xbd, 0x60, 0x54, 0x30, - 0x48, 0x7b, 0x1c, 0xf6, 0x21, 0x94, 0x70, 0xf6, 0xf2, 0x94, 0x09, 0x01, - 0x37, 0xf0, 0x60, 0x1f, 0x4e, 0x29, 0x45, 0x2e, 0xda, 0x19, 0x97, 0x18, - 0x11, 0x11, 0x2f, 0xd0, 0xf1, 0x71, 0x03, 0xf7, 0xe0, 0x84, 0xf6, 0x08, - 0xb6, 0x08, 0x94, 0x99, 0xa0, 0x16, 0xcc, 0x32, 0x5c, 0x89, 0xef, 0x9d, - 0x33, 0x8a, 0x26, 0x11, 0x9c, 0x40, 0xb0, 0x54, 0xc8, 0x3c, 0xad, 0x9b, - 0x70, 0xd8, 0xf0, 0x92, 0x36, 0x89, 0xeb, 0x62, 0xcc, 0x2a, 0x06, 0xc5, - 0x12, 0x69, 0x78, 0x82, 0x0b, 0x70, 0x51, 0x1d, 0xde, 0x51, 0x58, 0x2d, - 0xfe, 0xd7, 0x11, 0xe6, 0xb7, 0x84, 0x11, 0x35, 0x87, 0xbd, 0x06, 0x6f, - 0x5c, 0x4f, 0xe1, 0xe4, 0xc2, 0xe8, 0x02, 0xd7, 0x0a, 0xed, 0xb0, 0xbf, - 0x93, 0xb4, 0x17, 0x1e, 0xfa, 0x34, 0xc4, 0xcd, 0x50, 0xd7, 0x18, 0xf1, - 0x41, 0xd6, 0x42, 0x22, 0x56, 0xbe, 0x78, 0x5f, 0x8a, 0xac, 0x78, 0x5d, - 0x8c, 0x47, 0xf0, 0xd7, 0x42, 0xf0, 0x3b, 0x99, 0xa6, 0x7f, 0x98, 0xce, - 0x31, 0x2c, 0xc1, 0x7f, 0xf7, 0x88, 0x02, 0xe3, 0x49, 0x52, 0x61, 0x11, - 0x44, 0xd9, 0x9f, 0x76, 0x89, 0x76, 0x7a, 0xdf, 0xdf, 0x29, 0x5a, 0xfe, - 0xa7, 0x68, 0xd5, 0x61, 0x61, 0x81, 0x93, 0x29, 0x13, 0xce, 0xf6, 0x1a, - 0x53, 0xea, 0x9c, 0x46, 0x07, 0xd8, 0x12, 0x48, 0x8a, 0x17, 0xad, 0xbc, - 0xdb, 0x4f, 0xdd, 0x82, 0x98, 0x70, 0x8d, 0x38, 0xee, 0x47, 0x6a, 0xb0, - 0xe6, 0x6e, 0x67, 0x8e, 0xa1, 0xd7, 0x15, 0x38, 0xde, 0x93, 0xfe, 0x4e, - 0x83, 0xe1, 0x81, 0xc2, 0x9b, 0x95, 0xa4, 0x12, 0x0c, 0x52, 0x32, 0x50, - 0x30, 0xef, 0xc3, 0x88, 0x79, 0xd4, 0xae, 0x1c, 0xe5, 0xe3, 0x73, 0x6c, - 0x7d, 0xf8, 0xb6, 0x8d, 0xfa, 0x5d, 0x06, 0x22, 0x3e, 0x89, 0xda, 0x0a, - 0x1a, 0x1b, 0x89, 0x12, 0x03, 0xb9, 0x3b, 0x4a, 0x27, 0x7f, 0xb0, 0x28, - 0x61, 0xf0, 0x0c, 0xaa, 0x08, 0x28, 0xb9, 0xe0, 0x22, 0xd8, 0xe1, 0x87, - 0x85, 0x76, 0x8d, 0x51, 0x76, 0x5e, 0xe6, 0x3f, 0x59, 0xaf, 0x36, 0x58, - 0x39, 0xe0, 0x86, 0xce, 0x49, 0x75, 0x3f, 0x39, 0x7c, 0x95, 0xb0, 0x87, - 0x08, 0x45, 0x44, 0x71, 0xab, 0x6b, 0x6c, 0x61, 0x44, 0x12, 0x69, 0x88, - 0x60, 0xa7, 0x31, 0x8c, 0x94, 0x7d, 0x21, 0x85, 0x90, 0x33, 0xb8, 0xc1, - 0x88, 0xeb, 0x9b, 0x19, 0x2b, 0xa5, 0x16, 0x68, 0x02, 0x6a, 0x34, 0xd9, - 0xaa, 0x30, 0x18, 0x52, 0xda, 0xc2, 0xa6, 0x74, 0xcf, 0x38, 0x49, 0x0f, - 0xf4, 0xa6, 0x8b, 0x69, 0xfe, 0x77, 0x21, 0xa2, 0xd6, 0xd0, 0x6e, 0x64, - 0x54, 0xc3, 0x64, 0xed, 0xe0, 0xed, 0x9b, 0x97, 0xef, 0x0e, 0xf6, 0xdf, - 0x7d, 0xff, 0xf6, 0xf5, 0xb3, 0x97, 0x87, 0x6b, 0x94, 0x25, 0xc1, 0x6a, - 0x21, 0xc9, 0x2f, 0xc8, 0xbf, 0x25, 0x4e, 0x8a, 0xe2, 0x74, 0x28, 0x9b, - 0x00, 0x65, 0x44, 0x51, 0xd1, 0x02, 0x8d, 0x8b, 0xce, 0x2c, 0xde, 0x65, - 0x0a, 0xa8, 0x14, 0xe9, 0x80, 0x36, 0x99, 0xc2, 0x9c, 0xe9, 0x57, 0x16, - 0x21, 0x60, 0xa1, 0x69, 0x5d, 0x61, 0x7d, 0xd0, 0x16, 0xa2, 0x69, 0x16, - 0x32, 0x73, 0xbd, 0x4e, 0x2a, 0xc9, 0xc4, 0x7c, 0x10, 0x25, 0x46, 0x38, - 0xf9, 0xe5, 0x5a, 0x8f, 0xbb, 0xb3, 0x54, 0x4b, 0x0a, 0x9f, 0x57, 0xe9, - 0x13, 0x8a, 0x96, 0xaa, 0x34, 0x33, 0x52, 0x3b, 0xaf, 0x1c, 0x39, 0xc8, - 0x7a, 0xe0, 0xbb, 0x48, 0xe2, 0x32, 0xac, 0x41, 0x59, 0xaf, 0x61, 0x68, - 0x02, 0x67, 0x31, 0x58, 0xe2, 0x05, 0x25, 0x70, 0x58, 0x24, 0x56, 0xa2, - 0x5a, 0x17, 0x79, 0xc5, 0xb2, 0x0f, 0x19, 0x05, 0x34, 0xe6, 0x22, 0xec, - 0x1c, 0xcc, 0x4b, 0xba, 0xe0, 0x92, 0x9f, 0x80, 0x5b, 0xe1, 0xc1, 0x7d, - 0x16, 0x78, 0x64, 0x51, 0x5a, 0x76, 0x2b, 0xda, 0x9d, 0x41, 0xa0, 0xe4, - 0x86, 0x52, 0x72, 0xd2, 0x90, 0xeb, 0xf6, 0x64, 0xff, 0xec, 0x85, 0xce, - 0x78, 0x3d, 0x3f, 0xe6, 0xf4, 0xee, 0x49, 0x3a, 0x80, 0xdf, 0x88, 0x57, - 0x6c, 0x90, 0x4a, 0x1a, 0x53, 0x1b, 0x1f, 0x6d, 0x90, 0x7b, 0x4e, 0xd9, - 0x62, 0xc1, 0x61, 0x7f, 0x68, 0x96, 0xe8, 0x3a, 0x4e, 0x53, 0xfb, 0x15, - 0x27, 0x69, 0x2a, 0x84, 0x5f, 0x8d, 0x38, 0x8e, 0x7c, 0xf0, 0xfe, 0x3a, - 0x2d, 0x87, 0x6c, 0x70, 0x83, 0xb5, 0x3c, 0xcf, 0xc7, 0x79, 0xad, 0xfe, - 0x60, 0x96, 0xd8, 0x68, 0x5d, 0x90, 0x8d, 0x66, 0xd3, 0x8b, 0x7c, 0x8a, - 0x42, 0x17, 0xf2, 0xfd, 0x3c, 0x32, 0x9c, 0x4a, 0x66, 0x87, 0x29, 0x5e, - 0xce, 0x0c, 0x61, 0x66, 0x55, 0x4a, 0x6f, 0xe0, 0x7c, 0x6b, 0xe6, 0xae, - 0x44, 0x4b, 0xa2, 0x98, 0xbb, 0x13, 0x69, 0xcb, 0xaa, 0x37, 0x1b, 0x6b, - 0xf1, 0x78, 0xab, 0x73, 0x43, 0x7f, 0xca, 0x6e, 0x80, 0x26, 0x71, 0xa7, - 0x62, 0x1e, 0x40, 0x4c, 0xa0, 0x2b, 0x9e, 0x5b, 0x0e, 0xda, 0xbe, 0xcc, - 0xc4, 0xd3, 0x4e, 0xba, 0x9b, 0x0a, 0x1c, 0x6a, 0x7a, 0xe6, 0x77, 0xd5, - 0xfc, 0x8c, 0x6f, 0xc3, 0x75, 0xe4, 0x39, 0x0d, 0x75, 0x63, 0x5b, 0xa3, - 0x27, 0x41, 0x36, 0xa5, 0x61, 0x6f, 0x89, 0x57, 0xd6, 0x9e, 0xcd, 0xdd, - 0x85, 0xf5, 0xa5, 0xac, 0x68, 0x29, 0xee, 0xf0, 0x70, 0xf7, 0x7c, 0xd9, - 0x7f, 0xbc, 0x45, 0x97, 0xcf, 0xed, 0xad, 0xda, 0x7e, 0x09, 0x31, 0x46, - 0x7b, 0xc6, 0x2e, 0xc6, 0xe6, 0x6e, 0x7d, 0x6d, 0x7a, 0x32, 0x1f, 0x77, - 0x6f, 0x70, 0xc1, 0x40, 0x0b, 0xb5, 0xfc, 0xd9, 0x25, 0xb7, 0x96, 0xa8, - 0xc8, 0x41, 0x27, 0xad, 0x2c, 0xd0, 0x4c, 0x13, 0xed, 0x0f, 0x2c, 0x05, - 0x2d, 0xb7, 0x31, 0xba, 0xc0, 0xe4, 0x74, 0xda, 0x1b, 0x6c, 0x46, 0x31, - 0x1e, 0x1f, 0x09, 0xf2, 0x6a, 0x62, 0xf4, 0x32, 0x3c, 0x0b, 0xf1, 0x48, - 0x23, 0xca, 0x09, 0x56, 0x16, 0xe5, 0xa5, 0x8b, 0x83, 0x7d, 0xd2, 0x74, - 0xef, 0x30, 0x3c, 0x46, 0xd7, 0xd4, 0xed, 0x97, 0x13, 0x7d, 0xfb, 0x14, - 0x78, 0xc0, 0x1d, 0x77, 0x93, 0x27, 0x18, 0xc7, 0x32, 0x80, 0x38, 0x9b, - 0xb4, 0xd9, 0xe7, 0x86, 0x5e, 0xe9, 0x55, 0x84, 0x3d, 0x98, 0x2f, 0xd4, - 0xab, 0x58, 0x21, 0xfb, 0x82, 0x36, 0x95, 0x53, 0x32, 0xd6, 0x3b, 0x7b, - 0x1d, 0xb8, 0x9a, 0xd6, 0xb3, 0xfe, 0x85, 0x34, 0xd4, 0xc1, 0x06, 0xb6, - 0xf7, 0xf0, 0xe7, 0x0e, 0xfd, 0xdc, 0xed, 0x6c, 0x2c, 0xdc, 0x67, 0x15, - 0x5b, 0xba, 0x16, 0x2e, 0xb2, 0xae, 0x33, 0x5e, 0xe7, 0xa3, 0x00, 0x22, - 0xd1, 0xe0, 0x2f, 0x2a, 0x51, 0xf1, 0x61, 0x72, 0x1c, 0x71, 0xc2, 0x66, - 0x6e, 0x14, 0x4d, 0x82, 0x79, 0x1d, 0x26, 0x81, 0x51, 0xd1, 0xd9, 0xd0, - 0xb9, 0x75, 0x06, 0xef, 0xca, 0xec, 0x12, 0x9d, 0xd0, 0xc9, 0xbc, 0x66, - 0x4a, 0x45, 0xa2, 0x26, 0xe9, 0x88, 0x66, 0x27, 0x3d, 0xf4, 0xc5, 0x48, - 0xa8, 0xc2, 0xbe, 0x6c, 0x00, 0x59, 0xa8, 0x53, 0xf4, 0xd7, 0xe9, 0x83, - 0x3d, 0x43, 0xb9, 0xa0, 0x31, 0x23, 0x13, 0x20, 0xe3, 0x3b, 0x52, 0x7d, - 0xcf, 0xa1, 0x00, 0xa8, 0x99, 0x0f, 0x78, 0x01, 0x27, 0xff, 0x80, 0x80, - 0x94, 0x0f, 0xd0, 0x00, 0x88, 0x61, 0x3e, 0x97, 0x9c, 0xb1, 0xab, 0x62, - 0x16, 0x91, 0x90, 0xa5, 0xef, 0x85, 0x4f, 0x82, 0xe5, 0x48, 0x04, 0x89, - 0x8a, 0x71, 0x02, 0x9a, 0x52, 0x44, 0xc3, 0xa8, 0xef, 0x4f, 0x30, 0xb2, - 0xbd, 0x48, 0x1b, 0x4b, 0x64, 0x6a, 0x9a, 0xe1, 0x66, 0xd6, 0x25, 0xd2, - 0x80, 0x1b, 0xf3, 0xa7, 0xa8, 0x85, 0xc6, 0xc1, 0xf9, 0x9d, 0xba, 0xaf, - 0xb4, 0xbc, 0x49, 0x36, 0xa1, 0xcd, 0xb0, 0xa5, 0x2b, 0x9e, 0x1a, 0x5a, - 0x98, 0xf6, 0x53, 0x73, 0x48, 0x42, 0x1f, 0x09, 0x75, 0x6e, 0x75, 0xfe, - 0x6a, 0xda, 0xd2, 0xaf, 0x0b, 0x47, 0x69, 0x41, 0xce, 0x23, 0x0b, 0x6d, - 0x7c, 0xa6, 0xe8, 0xf2, 0x66, 0xd3, 0x42, 0x88, 0xfb, 0x75, 0xf7, 0xba, - 0x78, 0xfa, 0x04, 0x98, 0x85, 0x62, 0xe4, 0x4f, 0x39, 0xfc, 0x24, 0x9d, - 0x4a, 0x86, 0x2e, 0xd1, 0x06, 0x45, 0x00, 0x86, 0x28, 0xee, 0x7e, 0xe2, - 0xe4, 0x45, 0xdf, 0xa1, 0x5a, 0x86, 0xe9, 0xbc, 0xfc, 0xe9, 0xe0, 0xf4, - 0x0f, 0xdb, 0x3b, 0x72, 0x66, 0x88, 0x42, 0x98, 0x68, 0x96, 0xdd, 0xbb, - 0x18, 0xd7, 0x66, 0x67, 0x2c, 0x3c, 0xce, 0xf0, 0x16, 0x34, 0x18, 0x66, - 0xcc, 0x8d, 0xab, 0x12, 0xd9, 0xa1, 0xae, 0x92, 0x9c, 0x49, 0x8d, 0x68, - 0xd1, 0xc5, 0xd1, 0x20, 0x96, 0xe4, 0x6f, 0x73, 0xcc, 0xbc, 0x97, 0x1b, - 0x41, 0x01, 0x3f, 0x2c, 0xcc, 0x8c, 0x4d, 0x98, 0x4e, 0xa8, 0xf2, 0xf2, - 0xa6, 0xa2, 0x1e, 0xa4, 0x2d, 0x02, 0xb5, 0x18, 0xce, 0xf8, 0xce, 0xcc, - 0xaf, 0x68, 0xe9, 0xdf, 0x23, 0x6e, 0x88, 0x19, 0x61, 0xf1, 0x30, 0xf3, - 0xfe, 0xc4, 0x1b, 0x04, 0x47, 0x03, 0x7f, 0x99, 0xb2, 0x09, 0x95, 0xa8, - 0x45, 0xe9, 0x80, 0xef, 0xee, 0x5e, 0x0f, 0x1b, 0xb2, 0xeb, 0x46, 0x23, - 0x36, 0x28, 0x8d, 0x03, 0x6e, 0x1d, 0x45, 0x8c, 0x19, 0x07, 0xe7, 0x18, - 0xcf, 0xca, 0x53, 0xd1, 0xb7, 0x09, 0x65, 0xa3, 0x8a, 0x00, 0x48, 0x89, - 0xfd, 0x86, 0xe8, 0x80, 0xc6, 0x0a, 0xda, 0x35, 0xc6, 0xa0, 0x70, 0x5e, - 0x1d, 0xf3, 0xdc, 0x26, 0xc0, 0x3d, 0x51, 0x46, 0xed, 0xfc, 0x02, 0xff, - 0x92, 0x14, 0xce, 0x01, 0xb5, 0xb2, 0xcc, 0x26, 0x4f, 0x53, 0x24, 0x90, - 0xb8, 0x9a, 0xfd, 0x76, 0x0c, 0xb3, 0x71, 0x3e, 0xc9, 0xc9, 0x05, 0x7c, - 0xaa, 0xb9, 0x40, 0xdc, 0x71, 0xd4, 0x33, 0x5f, 0x8c, 0x2e, 0xdb, 0xdc, - 0x0d, 0x41, 0x04, 0xbf, 0x2a, 0xf9, 0xe5, 0xee, 0x11, 0x18, 0x9e, 0x86, - 0xf3, 0x3d, 0x07, 0x1e, 0x13, 0xcb, 0x82, 0x0d, 0x56, 0x8d, 0xf8, 0x3d, - 0x65, 0x5a, 0x8a, 0x93, 0x8b, 0xb5, 0x83, 0x0b, 0xce, 0x9f, 0x7f, 0x3f, - 0xa8, 0xb6, 0xb7, 0xcd, 0x16, 0x97, 0x5e, 0xa5, 0x30, 0x8f, 0x73, 0x74, - 0xc5, 0x92, 0x58, 0x96, 0x0a, 0xb5, 0x6f, 0x27, 0x6f, 0xdf, 0x1c, 0x25, - 0xeb, 0x08, 0xca, 0x93, 0x7c, 0xf9, 0x68, 0x7b, 0x67, 0x43, 0xaf, 0x28, - 0x8b, 0x84, 0x57, 0xf0, 0x8b, 0x74, 0xf1, 0xf0, 0x20, 0x53, 0xa9, 0x59, - 0xa8, 0x71, 0x0d, 0x0e, 0x33, 0x34, 0x06, 0x02, 0x6d, 0xec, 0xab, 0xd5, - 0xf1, 0x3c, 0x83, 0x31, 0x4d, 0x03, 0x0e, 0x8e, 0x5c, 0x68, 0x34, 0x42, - 0xd8, 0x21, 0xa4, 0x73, 0xb2, 0x1f, 0x80, 0xf8, 0x66, 0xe1, 0x59, 0x7e, - 0x7c, 0x6c, 0x2d, 0x8c, 0x3f, 0x0b, 0x66, 0x46, 0x65, 0x99, 0xdd, 0xe0, - 0xfc, 0xe9, 0xf5, 0x64, 0x19, 0x9c, 0x38, 0x4c, 0xba, 0x4f, 0xa5, 0xdd, - 0x76, 0xf0, 0xb8, 0x4e, 0xc9, 0x6d, 0x7a, 0x9d, 0x36, 0x1a, 0xb2, 0xb5, - 0x14, 0xc2, 0xee, 0x81, 0xda, 0x16, 0x89, 0xb9, 0xd2, 0x54, 0xd2, 0x39, - 0x7c, 0xfd, 0xc3, 0x6d, 0x0d, 0x7d, 0x1e, 0x41, 0x7f, 0x41, 0x8a, 0x0e, - 0xd6, 0x5d, 0xba, 0x40, 0x55, 0xbd, 0x21, 0xb6, 0x16, 0x32, 0xd4, 0xe9, - 0x28, 0xb5, 0xec, 0xe2, 0xa6, 0x32, 0x00, 0x3a, 0xb6, 0xa6, 0x13, 0xb1, - 0x38, 0x8e, 0x5c, 0x87, 0x6c, 0xa3, 0xef, 0x45, 0x0e, 0xef, 0x4a, 0xac, - 0x9f, 0x9e, 0x39, 0xd5, 0x01, 0x75, 0xfb, 0x77, 0x34, 0x4f, 0x32, 0x1a, - 0x20, 0xce, 0xdd, 0x75, 0xd3, 0xd7, 0x80, 0x51, 0x8a, 0x1f, 0x36, 0xaf, - 0x0f, 0xab, 0xd4, 0xcc, 0xe6, 0xcd, 0x04, 0x36, 0x50, 0x7d, 0xcb, 0xd9, - 0xa2, 0xe0, 0xc2, 0x4a, 0x09, 0xde, 0x2b, 0x1b, 0x64, 0xc3, 0xcc, 0x52, - 0xe4, 0x85, 0xae, 0xfa, 0x9b, 0x1d, 0x09, 0x0c, 0xa1, 0x70, 0x29, 0xc6, - 0x19, 0x32, 0x18, 0x08, 0x8c, 0x98, 0x99, 0x93, 0x6e, 0x29, 0x99, 0x52, - 0xd3, 0x7c, 0xf0, 0x1e, 0x17, 0x68, 0x99, 0xe8, 0x7f, 0xb0, 0xc8, 0x05, - 0x9d, 0x98, 0xe5, 0xae, 0xb3, 0xf3, 0x1b, 0x55, 0x8a, 0xd5, 0xcc, 0x88, - 0x21, 0x88, 0x1c, 0x44, 0x5a, 0x34, 0xb8, 0xb0, 0x98, 0x7f, 0x92, 0xf5, - 0x97, 0x92, 0x3c, 0x71, 0xf2, 0xfc, 0xe7, 0x70, 0x0b, 0xa8, 0x1e, 0xf0, - 0x75, 0x30, 0xcf, 0xf2, 0xd6, 0x72, 0x7a, 0x7b, 0xb0, 0xd3, 0xa6, 0x26, - 0xbf, 0x93, 0x23, 0x7a, 0x43, 0x42, 0x82, 0x03, 0x44, 0x49, 0xd2, 0x79, - 0x4a, 0x0f, 0x70, 0x43, 0x63, 0x81, 0x0a, 0xfa, 0xf6, 0x17, 0xfe, 0x94, - 0x08, 0x03, 0xfe, 0xa8, 0x2f, 0xe7, 0x93, 0x73, 0xd8, 0x9f, 0x69, 0xfd, - 0x6d, 0x87, 0xbd, 0xa3, 0x14, 0xe2, 0xbf, 0x30, 0x6a, 0xc4, 0xf4, 0xb1, - 0xdb, 0x81, 0x98, 0xbb, 0x28, 0x6d, 0x0d, 0x92, 0xaa, 0xf8, 0x13, 0xea, - 0xa3, 0xcb, 0xbf, 0xd3, 0xfd, 0xc5, 0xab, 0x22, 0x91, 0x88, 0xbc, 0x59, - 0xa2, 0x4e, 0x83, 0x78, 0x50, 0xfe, 0xf2, 0xea, 0x2f, 0xbf, 0x7c, 0xb5, - 0xfb, 0x30, 0xfd, 0x32, 0x1d, 0x3c, 0x1e, 0x3d, 0x49, 0x1f, 0x0d, 0x1f, - 0x7d, 0xf9, 0xd5, 0xce, 0x93, 0x47, 0xe9, 0x97, 0x0f, 0x47, 0xe9, 0xe3, - 0xed, 0x6c, 0xfb, 0xab, 0xd1, 0xce, 0xee, 0x70, 0x38, 0xca, 0x9e, 0x0c, - 0xbf, 0x4c, 0x3b, 0x7d, 0x35, 0x1a, 0xe8, 0xc8, 0xc5, 0x0f, 0xc4, 0x86, - 0x6e, 0x58, 0x97, 0xd3, 0x17, 0xfb, 0xbd, 0xed, 0xe4, 0x32, 0xfb, 0x60, - 0xa7, 0x83, 0x55, 0xc5, 0xb0, 0x9a, 0x55, 0xe6, 0x66, 0x14, 0x0b, 0xf6, - 0x82, 0x82, 0x06, 0xe2, 0x45, 0x88, 0x1e, 0x93, 0x85, 0xd6, 0x35, 0xac, - 0x24, 0x84, 0xcc, 0x36, 0x4b, 0x04, 0x2f, 0x37, 0x21, 0x99, 0xfa, 0x4b, - 0x14, 0xbd, 0x5e, 0xa5, 0x98, 0xc1, 0xa2, 0xab, 0x21, 0x0f, 0x9d, 0xb2, - 0xdf, 0x44, 0x3e, 0x94, 0xbf, 0xaa, 0xee, 0x42, 0x43, 0x3f, 0x94, 0xc5, - 0x7c, 0x76, 0x52, 0x8c, 0xf3, 0xc1, 0x4d, 0xd7, 0xb0, 0x00, 0x7d, 0xb3, - 0xee, 0x01, 0xfb, 0xde, 0xae, 0x72, 0xff, 0xe0, 0x21, 0xb3, 0xd9, 0xbc, - 0xca, 0x24, 0xba, 0x49, 0x64, 0xe1, 0x6a, 0xd1, 0xf5, 0xa2, 0x92, 0x67, - 0x38, 0xeb, 0x9f, 0x24, 0x7f, 0x62, 0xfb, 0xf8, 0x83, 0x8e, 0x35, 0xcb, - 0x06, 0xf0, 0x7f, 0xfa, 0x6b, 0x35, 0x19, 0x54, 0x19, 0x70, 0x57, 0xde, - 0x66, 0x69, 0x14, 0x7e, 0xa3, 0x4f, 0x83, 0x0e, 0x87, 0xcf, 0x61, 0x04, - 0x99, 0x46, 0x54, 0xb0, 0xdc, 0xf9, 0x23, 0xab, 0x65, 0x92, 0x60, 0x8f, - 0xdf, 0x5a, 0x44, 0xaf, 0x66, 0xf8, 0x44, 0x5b, 0x6f, 0x08, 0x47, 0x61, - 0xda, 0x07, 0xee, 0xfb, 0x53, 0x6e, 0xe2, 0x8d, 0x84, 0x79, 0xac, 0xa7, - 0xef, 0xd3, 0x7e, 0x72, 0x7c, 0x70, 0x7a, 0x82, 0x8d, 0xcf, 0x10, 0x3a, - 0x60, 0x83, 0x0c, 0x6b, 0xd9, 0x07, 0x10, 0x91, 0x2a, 0x8e, 0xa7, 0x6f, - 0x8b, 0x00, 0xc2, 0xc5, 0xd3, 0x20, 0x53, 0x8d, 0x5b, 0xd0, 0xf1, 0x48, - 0xca, 0x51, 0x4a, 0x00, 0x39, 0xe9, 0x38, 0x1f, 0x46, 0x7a, 0x20, 0x70, - 0x15, 0x60, 0x84, 0xc3, 0x8d, 0x10, 0x4f, 0xd2, 0x4d, 0x04, 0xb2, 0xc2, - 0xc5, 0x98, 0x20, 0x5d, 0x5e, 0xa0, 0x4f, 0xa5, 0x4a, 0x5c, 0x8e, 0xbb, - 0xf4, 0xb0, 0x48, 0xf1, 0x68, 0x5b, 0x46, 0xc5, 0x0e, 0xde, 0x27, 0x48, - 0x1e, 0xe6, 0xf2, 0xd3, 0xc2, 0xb5, 0x87, 0x81, 0x9a, 0x63, 0x4e, 0xaf, - 0xd6, 0xec, 0xef, 0x70, 0x29, 0xb1, 0xf6, 0xab, 0xce, 0x9e, 0x28, 0x06, - 0x82, 0x6c, 0x1c, 0x9a, 0x47, 0x4b, 0xaf, 0x0b, 0x47, 0xd7, 0xa0, 0x55, - 0x32, 0x9f, 0x67, 0x28, 0xdb, 0x89, 0x2b, 0x82, 0x46, 0xaa, 0xf2, 0x4d, - 0x20, 0x63, 0xb1, 0xe1, 0x8b, 0xc5, 0xb2, 0x8a, 0x42, 0x28, 0xe2, 0xfd, - 0x77, 0x99, 0xdf, 0x21, 0x90, 0x62, 0x89, 0xfb, 0xe7, 0x56, 0x0b, 0x7a, - 0x68, 0xf2, 0x6e, 0x22, 0xd7, 0xbe, 0x57, 0xf3, 0x0d, 0x81, 0x38, 0x94, - 0x0d, 0x67, 0xf3, 0x73, 0xbc, 0x0c, 0x23, 0x0a, 0x26, 0x51, 0xe3, 0x29, - 0xfe, 0x8c, 0xd4, 0x27, 0x04, 0xf0, 0x61, 0x29, 0x64, 0xa4, 0x96, 0x2e, - 0x39, 0xae, 0x2d, 0x42, 0x7a, 0x1f, 0xb5, 0x92, 0x6e, 0xf2, 0x0c, 0x51, - 0x2d, 0x13, 0x10, 0x51, 0x44, 0x02, 0x04, 0x32, 0x3b, 0x01, 0xed, 0x06, - 0xb9, 0x96, 0x93, 0x3f, 0xb1, 0xd5, 0xc8, 0xed, 0xad, 0x9a, 0x2b, 0x75, - 0x27, 0x19, 0xb7, 0x01, 0x6b, 0xd0, 0x6d, 0x81, 0xc4, 0xb0, 0x07, 0xf7, - 0x22, 0x75, 0x2b, 0x61, 0x95, 0x12, 0x84, 0x49, 0xe6, 0x31, 0x16, 0x66, - 0x4c, 0x96, 0x61, 0x82, 0x0f, 0x46, 0x33, 0x62, 0xdd, 0x30, 0xb2, 0x06, - 0x47, 0x92, 0x51, 0x8b, 0x20, 0xbb, 0x97, 0x90, 0xd0, 0xc7, 0x02, 0x10, - 0xcc, 0xc9, 0x4c, 0x7e, 0xa6, 0x68, 0x13, 0x37, 0x48, 0x42, 0x1b, 0xbc, - 0x94, 0x0b, 0x52, 0xe2, 0xbd, 0x29, 0xd6, 0xd6, 0x05, 0xaa, 0x80, 0x32, - 0xec, 0x8f, 0x63, 0x6b, 0x77, 0x71, 0xb4, 0x7c, 0x46, 0x60, 0x94, 0x4f, - 0x29, 0xac, 0x1b, 0x36, 0x5e, 0x3e, 0x88, 0x09, 0x43, 0xe4, 0x8f, 0x4a, - 0xae, 0x37, 0x7d, 0x49, 0xe5, 0x29, 0xb5, 0xaf, 0x06, 0x5b, 0x49, 0x5f, - 0xf2, 0x06, 0x72, 0xf5, 0x7a, 0x84, 0x96, 0x59, 0xac, 0x51, 0x89, 0x5f, - 0x78, 0x8f, 0x7c, 0xd7, 0x4f, 0x28, 0x6b, 0x7e, 0x3e, 0x43, 0x52, 0xc0, - 0x93, 0xc9, 0x9f, 0xfb, 0x86, 0xe4, 0xda, 0x64, 0x5a, 0x81, 0x45, 0x7c, - 0xfb, 0xe6, 0xe5, 0x9e, 0xcc, 0xbc, 0x35, 0xd1, 0xa4, 0xaa, 0xc6, 0x3a, - 0x49, 0x4a, 0x36, 0x49, 0xd4, 0x8e, 0xa8, 0x73, 0xc0, 0x3d, 0xfe, 0x3c, - 0x61, 0xb6, 0xda, 0xc5, 0xe1, 0xc1, 0xb3, 0x17, 0x87, 0x3d, 0xf8, 0x79, - 0xba, 0xdf, 0xdb, 0x3f, 0x3c, 0xdd, 0x79, 0xf4, 0xb8, 0x77, 0x70, 0xf0, - 0xea, 0xc9, 0x6a, 0x7b, 0x58, 0x8f, 0xab, 0xab, 0xed, 0xfe, 0x6e, 0x97, - 0x7f, 0xdd, 0xde, 0xb5, 0x56, 0x79, 0x43, 0xd9, 0x01, 0xac, 0x13, 0xb4, - 0x5d, 0x2d, 0x26, 0x24, 0x16, 0xea, 0x84, 0x24, 0x1a, 0x40, 0x6f, 0x14, - 0x09, 0x87, 0xe5, 0x27, 0x02, 0xfb, 0x95, 0x3b, 0x89, 0xd2, 0x46, 0x47, - 0x8d, 0x30, 0x17, 0xe7, 0xad, 0xb0, 0x64, 0x5e, 0xd6, 0x07, 0x63, 0xa7, - 0x09, 0x02, 0x43, 0x70, 0xcb, 0x1e, 0xf0, 0x44, 0xd7, 0xe9, 0x8d, 0x76, - 0x25, 0x91, 0x30, 0x22, 0xde, 0xa0, 0x40, 0xaa, 0x71, 0xb4, 0x1a, 0xf3, - 0x41, 0x91, 0xb8, 0x0c, 0xac, 0x29, 0x17, 0xcf, 0x0d, 0x3d, 0x2d, 0x22, - 0x9d, 0x53, 0xe5, 0x3a, 0x66, 0xdd, 0x44, 0xa1, 0x8c, 0xd8, 0x6b, 0x4a, - 0x73, 0x64, 0x9b, 0x38, 0xc5, 0x23, 0xf0, 0xfb, 0x13, 0xc6, 0x9b, 0xc1, - 0x90, 0xa5, 0xb4, 0x34, 0x8d, 0x00, 0x05, 0xec, 0xf4, 0xc6, 0xe2, 0x6d, - 0x1a, 0x38, 0x2d, 0xeb, 0x55, 0x9d, 0x8f, 0xc7, 0x1b, 0x6e, 0xc1, 0xbe, - 0xd6, 0xfc, 0xf5, 0x1c, 0x6f, 0x21, 0x0d, 0x16, 0x97, 0xc8, 0x60, 0x85, - 0x6b, 0xa2, 0x8b, 0x2e, 0x2c, 0x46, 0x20, 0x95, 0xa3, 0x51, 0xb2, 0x70, - 0x49, 0x4b, 0x18, 0x9b, 0xdd, 0xd1, 0x8d, 0x4b, 0x9a, 0x42, 0xd3, 0xe7, - 0x53, 0x13, 0x02, 0xe5, 0x86, 0x99, 0x2a, 0x04, 0x87, 0xf8, 0xef, 0x04, - 0xd4, 0x68, 0x2a, 0x20, 0x37, 0x89, 0x45, 0x93, 0xa6, 0x1a, 0x31, 0xda, - 0xe5, 0xb4, 0xc4, 0xa9, 0xe0, 0xaf, 0x7e, 0x1d, 0xae, 0x56, 0xed, 0x90, - 0x62, 0x20, 0x0b, 0xf9, 0x85, 0xf4, 0x04, 0x34, 0x53, 0xd0, 0x57, 0x1c, - 0x11, 0xe9, 0x26, 0xe4, 0xee, 0x46, 0x33, 0x31, 0x06, 0xaa, 0x6a, 0x89, - 0x8d, 0x80, 0xab, 0x7e, 0xf9, 0xbd, 0x28, 0xe9, 0x2e, 0x0f, 0x2c, 0xb7, - 0x89, 0x6f, 0xc7, 0x85, 0xf5, 0x5b, 0x72, 0xd4, 0x42, 0xc7, 0xab, 0x71, - 0x46, 0x7b, 0xbe, 0x57, 0x55, 0x97, 0x2d, 0xe7, 0x06, 0x3f, 0x56, 0x55, - 0xed, 0x40, 0x43, 0x0e, 0x39, 0x7c, 0x1d, 0xc3, 0xbf, 0x51, 0x93, 0xee, - 0xe5, 0x53, 0xca, 0x7c, 0xb7, 0x35, 0x11, 0xbe, 0x97, 0x57, 0x12, 0x41, - 0x66, 0xcb, 0xae, 0xf1, 0x95, 0x75, 0xe2, 0x16, 0xbf, 0xb1, 0xd5, 0xd1, - 0xca, 0xcb, 0xd2, 0x17, 0x1c, 0x7b, 0x78, 0xdb, 0x3a, 0xe3, 0x38, 0x17, - 0x44, 0x11, 0x91, 0x44, 0x64, 0xb1, 0x17, 0x56, 0x1b, 0x93, 0x7b, 0xf9, - 0xde, 0x6b, 0xca, 0x22, 0xcd, 0x55, 0x59, 0x69, 0xc5, 0x69, 0x08, 0xd5, - 0x2a, 0x01, 0x80, 0xd1, 0x6e, 0xd2, 0x4c, 0xfe, 0xd4, 0xe5, 0x58, 0xc0, - 0x51, 0x7e, 0x11, 0xb9, 0xed, 0x43, 0x14, 0x3d, 0xe5, 0xe3, 0x99, 0x83, - 0x1e, 0x0f, 0x97, 0xf8, 0x6a, 0xc5, 0x56, 0xc7, 0x21, 0xbd, 0xe2, 0xa4, - 0x90, 0xb8, 0x72, 0x0e, 0x2c, 0xe7, 0x29, 0x86, 0xc7, 0x30, 0xb2, 0xd9, - 0x02, 0x01, 0xad, 0x55, 0x64, 0x40, 0x74, 0xfc, 0x10, 0x6a, 0x74, 0x24, - 0x7c, 0x86, 0x40, 0x8c, 0xe2, 0x3b, 0xa1, 0x05, 0x30, 0x56, 0x17, 0xe8, - 0xd8, 0x61, 0x8f, 0x70, 0x02, 0x91, 0xc3, 0x14, 0x54, 0xdb, 0x6f, 0xd0, - 0xe1, 0xa5, 0x25, 0x72, 0x08, 0x33, 0x6e, 0x88, 0xd7, 0x78, 0x39, 0x93, - 0x21, 0xf8, 0x6b, 0x40, 0x57, 0x20, 0x9c, 0x30, 0x4a, 0xa2, 0xeb, 0xb2, - 0xe7, 0x86, 0x9c, 0xc0, 0x64, 0x87, 0x63, 0xbc, 0x0c, 0x45, 0xc5, 0x2d, - 0x94, 0x42, 0x1c, 0x56, 0x61, 0x25, 0x40, 0x62, 0x62, 0x14, 0x16, 0x2c, - 0x60, 0x06, 0x2f, 0xca, 0x0d, 0xdb, 0x99, 0x36, 0x20, 0xd8, 0xbe, 0x09, - 0xef, 0xc2, 0x74, 0xf0, 0x7c, 0x9a, 0x13, 0x9c, 0xb3, 0x9a, 0x21, 0x25, - 0x01, 0x53, 0x18, 0x16, 0x72, 0xe7, 0xaa, 0xe8, 0x1a, 0xb4, 0x10, 0x7a, - 0x96, 0x98, 0x92, 0x79, 0x74, 0x0d, 0xb3, 0x69, 0x15, 0xd9, 0xfe, 0x08, - 0x16, 0x57, 0xb3, 0x0d, 0xab, 0x10, 0x2a, 0xed, 0xed, 0x60, 0xba, 0x70, - 0x8e, 0x37, 0xd0, 0x15, 0x55, 0xba, 0x64, 0x50, 0xba, 0xa4, 0x4b, 0x41, - 0x3c, 0x3e, 0x47, 0x1c, 0x30, 0x19, 0x09, 0xe6, 0xf7, 0x09, 0xa8, 0x48, - 0xc3, 0x6c, 0xaa, 0xf9, 0x88, 0xae, 0x3b, 0xcd, 0x4b, 0xb4, 0xed, 0x8b, - 0x14, 0xab, 0x2c, 0x7c, 0x1e, 0x7c, 0x37, 0x61, 0x6f, 0x28, 0x1b, 0x9c, - 0xb1, 0x22, 0xc4, 0xe8, 0x23, 0x6b, 0xb1, 0xbe, 0xb7, 0x61, 0x21, 0x67, - 0x6e, 0xc3, 0xe0, 0x8b, 0x6f, 0x36, 0x18, 0x0b, 0x2a, 0x38, 0x08, 0x9c, - 0xa5, 0x07, 0xf8, 0xfb, 0xb8, 0xa0, 0x35, 0x12, 0xc8, 0x51, 0x59, 0x7e, - 0x6e, 0x48, 0x80, 0x47, 0xd7, 0x3b, 0x94, 0xc6, 0x48, 0x37, 0x0a, 0xba, - 0xea, 0x7e, 0x8a, 0x1e, 0xd5, 0xa7, 0x98, 0xb0, 0x82, 0x95, 0x81, 0x0d, - 0xc1, 0x2a, 0xeb, 0x78, 0x38, 0x5a, 0xb3, 0xe0, 0x82, 0x28, 0xfc, 0xcb, - 0x2f, 0xdd, 0xe4, 0x97, 0x0e, 0xfc, 0x1f, 0xdd, 0x4d, 0xbf, 0x00, 0xd1, - 0xfd, 0x52, 0xf2, 0x96, 0xff, 0x72, 0xd5, 0x4f, 0xf6, 0x1d, 0x48, 0xa4, - 0xca, 0xbe, 0x68, 0x28, 0xe3, 0xa4, 0x02, 0xf5, 0x4c, 0x30, 0xfa, 0xab, - 0x77, 0x48, 0xc5, 0x0b, 0xca, 0x99, 0x0d, 0xd3, 0x62, 0xda, 0x63, 0xb4, - 0x4b, 0x58, 0xb1, 0xf9, 0x64, 0xca, 0xf1, 0xac, 0x42, 0x94, 0x7c, 0x40, - 0x88, 0x9d, 0xae, 0xfd, 0x61, 0x2d, 0x6c, 0xa2, 0xe9, 0x85, 0x70, 0x65, - 0xeb, 0x33, 0x51, 0xea, 0x2d, 0x7b, 0xa5, 0x4d, 0xf4, 0x38, 0x46, 0x35, - 0x50, 0x40, 0x0f, 0x0a, 0x67, 0xb4, 0x45, 0xf4, 0x87, 0xd9, 0xe5, 0x4d, - 0x85, 0xf2, 0x8b, 0x1d, 0xc7, 0x64, 0xe1, 0x5c, 0xa0, 0xa5, 0x39, 0x8a, - 0x5e, 0x13, 0x64, 0xec, 0x4a, 0x33, 0x06, 0x38, 0x6b, 0x88, 0x49, 0x8f, - 0xdd, 0x83, 0xec, 0x11, 0xdc, 0xde, 0x4a, 0x26, 0xd9, 0x45, 0x2a, 0x58, - 0x13, 0xeb, 0x94, 0x6d, 0xc0, 0x0d, 0x51, 0x9c, 0xd3, 0x46, 0x33, 0x6f, - 0x28, 0x4e, 0x81, 0xaa, 0x8b, 0xc0, 0x1f, 0x91, 0xa9, 0x4f, 0xf2, 0x29, - 0xa8, 0x7f, 0x9d, 0x5e, 0x87, 0xbe, 0x0a, 0x29, 0x42, 0xc4, 0x18, 0x63, - 0x26, 0xe2, 0xd2, 0x08, 0xb4, 0x8f, 0x10, 0x8b, 0x2e, 0xe9, 0xca, 0x82, - 0xa2, 0x19, 0xc0, 0x7e, 0x11, 0xf1, 0x24, 0x57, 0x4e, 0x67, 0x93, 0x97, - 0xdc, 0x52, 0xcc, 0x5f, 0x30, 0xa9, 0x49, 0xdf, 0x41, 0xf2, 0x0d, 0xae, - 0xd9, 0x5e, 0x8f, 0xc3, 0xdc, 0x68, 0x71, 0x59, 0x3e, 0xe4, 0x68, 0x8e, - 0x1b, 0x44, 0x4a, 0x98, 0x8d, 0x03, 0x74, 0x75, 0x18, 0x2c, 0xf6, 0x49, - 0x01, 0x7e, 0x1c, 0xb9, 0xc7, 0x00, 0xf3, 0xa7, 0x05, 0x79, 0xa7, 0x06, - 0x14, 0x10, 0x82, 0x81, 0x38, 0x8a, 0xb4, 0xc0, 0x91, 0xfb, 0x0c, 0x3a, - 0xfd, 0xa0, 0x81, 0x0f, 0x19, 0x09, 0xfe, 0x88, 0x24, 0xfc, 0xe0, 0x0f, - 0x30, 0xa2, 0x9e, 0xde, 0x60, 0x89, 0x98, 0x87, 0x7a, 0xf4, 0x45, 0x6d, - 0xd2, 0x91, 0x50, 0x4a, 0x68, 0xcf, 0xdd, 0x62, 0x1d, 0xf8, 0x54, 0x00, - 0x22, 0xe0, 0x0b, 0xec, 0x00, 0xf9, 0x8c, 0x20, 0x26, 0xc3, 0x0b, 0x70, - 0x7d, 0xf7, 0xd2, 0x0b, 0x94, 0x15, 0xe1, 0x6b, 0x90, 0xd0, 0x40, 0x6f, - 0xc0, 0xbf, 0x36, 0xb7, 0xfb, 0x5b, 0x32, 0x00, 0x5c, 0x03, 0x02, 0xc9, - 0x37, 0xe7, 0x21, 0x4e, 0xb8, 0x2e, 0x8a, 0xd6, 0xfe, 0x16, 0xb3, 0xe3, - 0xb1, 0x9b, 0xde, 0x31, 0xfc, 0x20, 0x83, 0x29, 0xbc, 0x2e, 0x13, 0x86, - 0xf9, 0x4e, 0x0b, 0x02, 0x9f, 0x01, 0xc1, 0x6c, 0x3c, 0x8e, 0xe0, 0xa7, - 0x3b, 0x61, 0xea, 0x53, 0xca, 0x67, 0xc8, 0x9a, 0x2b, 0x20, 0x61, 0x88, - 0x16, 0x99, 0x88, 0x6b, 0x31, 0x55, 0xb3, 0x0c, 0x2c, 0xfc, 0xba, 0xe0, - 0xba, 0x61, 0xd8, 0xac, 0x4a, 0x0d, 0xac, 0xf3, 0x6c, 0x70, 0xca, 0x91, - 0x06, 0x46, 0xa9, 0x56, 0xc6, 0x0a, 0x72, 0x74, 0x93, 0x58, 0x78, 0x57, - 0xce, 0x7e, 0x4e, 0xba, 0x81, 0x31, 0x32, 0x0a, 0xef, 0x9e, 0x6b, 0x4e, - 0x08, 0x96, 0x17, 0x4c, 0x83, 0xe6, 0xb4, 0xbd, 0x33, 0x1f, 0x0d, 0xa2, - 0x8f, 0x48, 0x92, 0x46, 0xc5, 0xfd, 0x67, 0x92, 0x21, 0x6f, 0x87, 0xd5, - 0xf8, 0x9b, 0xb0, 0xa3, 0x31, 0xe1, 0xa0, 0x6b, 0x2a, 0x33, 0xc9, 0x5c, - 0xaa, 0x28, 0x6e, 0x6f, 0x24, 0x9d, 0xff, 0x46, 0x51, 0x6c, 0x8c, 0xea, - 0x88, 0x2b, 0x50, 0x0e, 0x3a, 0xf2, 0xed, 0x0e, 0x7e, 0xfb, 0xf3, 0xb3, - 0x1f, 0xde, 0x1d, 0x1c, 0xbf, 0x7e, 0x7e, 0xf4, 0x03, 0x3f, 0x23, 0x8f, - 0x24, 0xeb, 0x3e, 0x30, 0x1b, 0x43, 0x3f, 0xe5, 0xa5, 0x5d, 0x7c, 0xa9, - 0xad, 0xb5, 0x87, 0x1b, 0x1a, 0x07, 0xb3, 0x97, 0x74, 0x08, 0xe0, 0xf4, - 0xe4, 0xcd, 0x31, 0x42, 0xc4, 0xfd, 0xfb, 0x2f, 0x8d, 0x27, 0x1f, 0x45, - 0x4f, 0xee, 0x9f, 0x9c, 0x3c, 0xdb, 0x3f, 0xdb, 0x5f, 0x78, 0xea, 0xf1, - 0xf2, 0xf6, 0xf6, 0x31, 0x08, 0x42, 0xcc, 0x63, 0xcf, 0x80, 0x28, 0x9a, - 0xaf, 0x7e, 0xb9, 0x01, 0x1c, 0x60, 0xda, 0xb3, 0xd7, 0x51, 0x75, 0xbf, - 0xc8, 0xea, 0xd9, 0xf5, 0x3c, 0x27, 0xee, 0x45, 0x95, 0x35, 0x70, 0x2d, - 0x2f, 0x0b, 0x1f, 0xab, 0x26, 0x6f, 0x3f, 0xd9, 0x00, 0x1e, 0x6a, 0x41, - 0x3d, 0x62, 0x0f, 0xcc, 0x29, 0xa2, 0x81, 0x94, 0x14, 0xe0, 0x7b, 0xd2, - 0x9f, 0x6d, 0x55, 0x08, 0xdd, 0xe7, 0x3b, 0x46, 0x69, 0x85, 0xe1, 0x3d, - 0x86, 0x08, 0x8c, 0x71, 0x95, 0xf1, 0x39, 0x77, 0x24, 0x55, 0x30, 0x0b, - 0x36, 0x19, 0xc9, 0x45, 0xc0, 0x5c, 0x2a, 0xd6, 0x8d, 0xd8, 0xd8, 0xb2, - 0xc1, 0xbc, 0x56, 0xb8, 0x5c, 0xda, 0xf0, 0x61, 0x60, 0xf7, 0x21, 0x4a, - 0x0a, 0xc5, 0x04, 0x65, 0xa9, 0xa2, 0x72, 0x1a, 0x09, 0x21, 0xfb, 0x57, - 0x6b, 0x3b, 0xdc, 0x79, 0x36, 0x03, 0xb3, 0x08, 0xbe, 0xe3, 0x4f, 0xba, - 0x1a, 0xf6, 0xa5, 0x9c, 0x8e, 0x2a, 0x1e, 0xa0, 0x96, 0x75, 0x8c, 0x21, - 0x78, 0x1a, 0x4b, 0x58, 0x45, 0xf1, 0xc4, 0xd2, 0x8b, 0x44, 0x16, 0xc0, - 0xdc, 0xa4, 0x31, 0xb2, 0x49, 0xf6, 0x03, 0xf5, 0x4b, 0xd2, 0xe4, 0xd2, - 0x7c, 0x49, 0x95, 0x3a, 0xc5, 0x42, 0x7e, 0x57, 0xd6, 0xa4, 0xbf, 0xb6, - 0x56, 0x0e, 0x5e, 0x92, 0x63, 0xee, 0x54, 0x21, 0x49, 0x93, 0x84, 0x61, - 0x60, 0x12, 0xe4, 0x53, 0x86, 0x48, 0x52, 0xc3, 0xd0, 0xab, 0xf4, 0x43, - 0x3e, 0x99, 0x4f, 0x18, 0x8c, 0x09, 0xb3, 0xb1, 0xf9, 0x5b, 0xb1, 0x03, - 0xe3, 0x6d, 0xc1, 0x21, 0x36, 0x38, 0xa4, 0xb5, 0xca, 0x59, 0x86, 0x38, - 0xb9, 0x16, 0x2e, 0xae, 0xbe, 0x8f, 0xcd, 0x66, 0x60, 0x81, 0x49, 0x1e, - 0x00, 0xb3, 0xf5, 0x71, 0xb8, 0x9c, 0x53, 0x34, 0x3f, 0x33, 0xe8, 0x11, - 0x43, 0x62, 0x59, 0x85, 0x0c, 0xa9, 0x7b, 0x60, 0x57, 0x09, 0x8b, 0xb5, - 0xb0, 0xa7, 0x79, 0x31, 0xe4, 0xeb, 0x83, 0xb3, 0x8c, 0x80, 0x8f, 0xb1, - 0x07, 0x95, 0xfc, 0xe3, 0x84, 0xca, 0xdc, 0x16, 0x1b, 0x8e, 0x08, 0x8c, - 0x58, 0x02, 0x04, 0xf4, 0xf6, 0x7c, 0x62, 0xd8, 0x12, 0x7d, 0x35, 0x59, - 0xba, 0x0f, 0x05, 0xb4, 0x93, 0xaf, 0xfc, 0x86, 0xed, 0x4f, 0xe3, 0x33, - 0x40, 0x08, 0x43, 0xd4, 0xa0, 0xfe, 0x06, 0xdd, 0xdc, 0xfa, 0xba, 0x49, - 0xbb, 0xb0, 0xc8, 0x7c, 0x37, 0x72, 0xb4, 0x1a, 0xfa, 0x4f, 0x2c, 0x88, - 0x90, 0xfc, 0x79, 0xc4, 0x26, 0x39, 0xe7, 0x98, 0x0d, 0x17, 0xe7, 0x6a, - 0xa2, 0xd1, 0x8b, 0x24, 0xe0, 0x74, 0x38, 0xd3, 0xaa, 0x5b, 0x3b, 0x5a, - 0x3a, 0x66, 0x99, 0x40, 0x9a, 0x98, 0xe4, 0x94, 0x0d, 0x43, 0x26, 0xb4, - 0x4b, 0xae, 0x79, 0xf6, 0xfa, 0x34, 0x11, 0x70, 0xc0, 0x60, 0xc7, 0x55, - 0xf5, 0x15, 0xdf, 0x39, 0xc3, 0x9a, 0x42, 0x6c, 0x98, 0x25, 0xd1, 0x3e, - 0xf9, 0xf3, 0xdb, 0xa3, 0x83, 0xc4, 0xd5, 0x24, 0x51, 0xb0, 0x03, 0x4c, - 0x5c, 0xed, 0x27, 0x51, 0xd8, 0x51, 0x83, 0x90, 0x3e, 0x2e, 0xfe, 0x28, - 0xbe, 0x18, 0x62, 0xb2, 0xaf, 0x16, 0xe9, 0x3e, 0xea, 0x69, 0x67, 0xab, - 0x95, 0xf4, 0x6f, 0x7d, 0x67, 0xb7, 0xbf, 0xfd, 0x70, 0xb5, 0x03, 0x33, - 0x49, 0x3f, 0xd0, 0x5b, 0x8b, 0x27, 0xa6, 0x48, 0x9e, 0xbe, 0x38, 0x3e, - 0x3d, 0xdb, 0xde, 0x3b, 0x39, 0x7e, 0x03, 0x3f, 0xf1, 0xf7, 0x1d, 0xfa, - 0x7d, 0x47, 0x0e, 0x0f, 0x42, 0x86, 0xf9, 0x3c, 0x5e, 0x34, 0x66, 0x51, - 0xfc, 0xe4, 0x48, 0xdc, 0xde, 0x49, 0xd2, 0x71, 0x2d, 0x74, 0x40, 0xf1, - 0xc8, 0xd1, 0xd1, 0x27, 0x3d, 0x84, 0xb8, 0x97, 0x8e, 0x6b, 0xbb, 0xa3, - 0x71, 0x99, 0x8d, 0xb8, 0x68, 0x3d, 0x5e, 0x16, 0x6c, 0x01, 0x5d, 0xa6, - 0x0c, 0xaf, 0x18, 0xdc, 0x4f, 0x9a, 0xfe, 0xeb, 0x2d, 0xb8, 0x86, 0xfd, - 0x9a, 0xbc, 0x3e, 0x3e, 0x4b, 0x52, 0x32, 0x22, 0x24, 0x72, 0x3f, 0x70, - 0xed, 0xa1, 0x4d, 0xf6, 0xb7, 0x70, 0xc9, 0x07, 0x27, 0x8f, 0x6b, 0x8e, - 0x38, 0xcd, 0x07, 0x68, 0x66, 0x93, 0x72, 0x26, 0xd0, 0xbd, 0x04, 0x2b, - 0xf8, 0xfa, 0xa8, 0x1b, 0xb9, 0x85, 0xbc, 0x57, 0x67, 0x23, 0x24, 0xe7, - 0x28, 0x8a, 0x47, 0xea, 0x2e, 0x35, 0x43, 0x7f, 0x55, 0x42, 0xe0, 0x55, - 0xea, 0x10, 0xb9, 0x76, 0x64, 0xad, 0x14, 0x29, 0x07, 0xab, 0xf9, 0xdc, - 0x88, 0x5b, 0x16, 0x68, 0x4b, 0x81, 0x3c, 0x50, 0x39, 0xc1, 0xf1, 0x4b, - 0x38, 0xd7, 0x8d, 0x66, 0x46, 0xc3, 0x44, 0x78, 0x1e, 0x7d, 0x5d, 0xd6, - 0x8e, 0x1c, 0x83, 0x8e, 0x2c, 0x2f, 0x5b, 0x66, 0x18, 0x05, 0x2b, 0x74, - 0x60, 0x3d, 0x68, 0xba, 0x14, 0x77, 0x33, 0xaf, 0x34, 0xe1, 0x9b, 0xf6, - 0x18, 0xb3, 0x52, 0xca, 0xfc, 0x82, 0xa0, 0xdc, 0xac, 0xbc, 0x13, 0x05, - 0x2c, 0xb8, 0x8e, 0x35, 0x11, 0x22, 0x3c, 0x11, 0xd4, 0xc1, 0x7a, 0x21, - 0xcc, 0x9f, 0x62, 0x75, 0x4b, 0xd5, 0x76, 0x78, 0x14, 0xdd, 0x84, 0xf8, - 0x64, 0xad, 0x9b, 0xaa, 0x3c, 0x6a, 0x92, 0xd6, 0x02, 0x16, 0xc5, 0x61, - 0x1a, 0x96, 0x36, 0x6b, 0x24, 0x88, 0x40, 0x45, 0x06, 0x5c, 0x4e, 0xb3, - 0xa3, 0xf8, 0x0e, 0x69, 0x88, 0x0b, 0xb4, 0x20, 0xf7, 0xb2, 0xc4, 0xaa, - 0xce, 0xf6, 0xce, 0x97, 0xfd, 0x2d, 0xf8, 0x2f, 0x2c, 0xb9, 0x46, 0x6b, - 0x48, 0x99, 0x0c, 0x5a, 0x5e, 0x89, 0x07, 0xd1, 0x17, 0x64, 0xbf, 0xf4, - 0x44, 0x15, 0x25, 0x15, 0x9c, 0x89, 0x2e, 0x31, 0x87, 0xcf, 0xe6, 0x58, - 0xbc, 0xcf, 0xeb, 0x0b, 0xc7, 0x31, 0x09, 0x6b, 0x14, 0x4e, 0x83, 0x8d, - 0x28, 0x0e, 0x01, 0x43, 0xf9, 0xd7, 0x2d, 0x33, 0x29, 0x0e, 0xcd, 0xd3, - 0x5f, 0xf8, 0xc6, 0xf7, 0xf6, 0xac, 0xa5, 0xbd, 0xa4, 0x1d, 0x0f, 0x7b, - 0xe5, 0x81, 0x33, 0xfe, 0x4f, 0x28, 0xd6, 0x45, 0xdb, 0x11, 0x46, 0xaa, - 0xe9, 0xf4, 0x1f, 0x3d, 0xdc, 0x85, 0x31, 0xb6, 0x0f, 0x31, 0x7a, 0xc7, - 0x1b, 0x5e, 0x7e, 0x0f, 0x2a, 0xc3, 0x92, 0x55, 0x7b, 0xf8, 0x70, 0x77, - 0x4f, 0xff, 0x06, 0x7e, 0xb2, 0xf7, 0x04, 0x3e, 0x58, 0x8d, 0x95, 0xc6, - 0x00, 0x0d, 0xec, 0x1b, 0x50, 0xb6, 0x7a, 0xd0, 0x8d, 0xb3, 0x85, 0x93, - 0xa7, 0xc5, 0x68, 0x04, 0xf7, 0xc3, 0xb7, 0xe6, 0x51, 0x98, 0xe3, 0x51, - 0xb2, 0x04, 0x42, 0x87, 0x1e, 0x69, 0xe1, 0x3d, 0x2c, 0x16, 0x10, 0xf0, - 0x62, 0xc2, 0x6f, 0x8b, 0x8a, 0xe1, 0x52, 0x4e, 0xf8, 0x73, 0xf3, 0xf8, - 0xc1, 0x78, 0x07, 0xc6, 0xda, 0xc8, 0x21, 0xea, 0x90, 0xe6, 0xe9, 0xaa, - 0xab, 0xde, 0xe7, 0xb3, 0x19, 0xa9, 0x4b, 0x54, 0x1b, 0x27, 0xce, 0xde, - 0xc7, 0x26, 0x42, 0x40, 0x9a, 0xc5, 0x02, 0x50, 0x82, 0x2e, 0x4b, 0xc7, - 0xe7, 0xd9, 0xa8, 0x60, 0xdc, 0xd0, 0xbc, 0x8a, 0x30, 0x30, 0x8d, 0x9c, - 0xd9, 0xf1, 0x88, 0x70, 0x27, 0x29, 0x33, 0xe4, 0xa3, 0x11, 0xef, 0x1d, - 0x99, 0x97, 0x04, 0xd0, 0x80, 0x2f, 0xcd, 0x90, 0x35, 0x1e, 0x6c, 0xa0, - 0xa7, 0x47, 0xff, 0x75, 0x18, 0x05, 0x7e, 0x6a, 0xfe, 0x32, 0x69, 0xc9, - 0x21, 0xdd, 0x31, 0xe9, 0xf4, 0x0e, 0x92, 0x5e, 0x47, 0xb1, 0xd3, 0x11, - 0x49, 0xdd, 0xe2, 0xa0, 0x63, 0xdf, 0x0e, 0xe9, 0x07, 0x02, 0x65, 0x07, - 0xa2, 0xc4, 0xe6, 0x25, 0xc8, 0x77, 0x3a, 0x58, 0xc6, 0x41, 0x8b, 0x93, - 0xac, 0x43, 0x39, 0x3c, 0x4b, 0xf2, 0xe1, 0x9d, 0x60, 0x85, 0x7a, 0x33, - 0x9f, 0xa2, 0x5a, 0xcd, 0x48, 0x23, 0xd6, 0xd0, 0x88, 0x71, 0x37, 0x18, - 0x23, 0x71, 0x6e, 0x39, 0xbc, 0x9e, 0x02, 0x5a, 0x63, 0xff, 0x3f, 0x2d, - 0x90, 0xa4, 0x21, 0x42, 0xc0, 0x42, 0xdc, 0x29, 0x32, 0x1c, 0x24, 0x0f, - 0xb7, 0xb6, 0x56, 0xa4, 0x6b, 0x4c, 0x78, 0x57, 0x42, 0x3e, 0x67, 0x42, - 0x2e, 0xde, 0xe7, 0x59, 0xf2, 0x14, 0x9d, 0x29, 0xff, 0xa3, 0x0d, 0x24, - 0x67, 0x23, 0x39, 0x49, 0xc5, 0x77, 0x66, 0x10, 0x14, 0xf8, 0x07, 0x25, - 0xf1, 0xaa, 0xaf, 0x40, 0xb4, 0xa3, 0x03, 0x6e, 0x4c, 0xce, 0x0b, 0xd5, - 0xa7, 0xd4, 0xfd, 0x26, 0x5f, 0x11, 0x4c, 0x77, 0x2c, 0x4a, 0x13, 0xb5, - 0xe5, 0x72, 0x6c, 0x03, 0xb8, 0xbe, 0x91, 0xab, 0xb6, 0x4e, 0x71, 0x96, - 0xc2, 0xae, 0x4f, 0xb3, 0xba, 0xc7, 0xbd, 0xec, 0x75, 0x12, 0xb1, 0xcc, - 0x28, 0xe6, 0x15, 0x0f, 0xcf, 0x72, 0x76, 0xe8, 0xd2, 0xa0, 0x97, 0x25, - 0x70, 0x8b, 0x03, 0x96, 0xa5, 0x21, 0x2c, 0xed, 0xb9, 0xfd, 0xcd, 0x8f, - 0xfb, 0x2f, 0xdf, 0x1e, 0x6e, 0x7f, 0x9d, 0xe0, 0x5f, 0x3b, 0xfc, 0xd7, - 0x0e, 0x95, 0x9f, 0xe0, 0x2b, 0x2c, 0xa4, 0x85, 0xfa, 0x50, 0x39, 0xb2, - 0x51, 0x30, 0xdd, 0x70, 0xc1, 0x0e, 0x04, 0x1d, 0x51, 0xa8, 0x91, 0x84, - 0x17, 0x94, 0x6d, 0xef, 0x5c, 0xb6, 0x4d, 0xdf, 0x67, 0x28, 0x06, 0xc2, - 0x7f, 0x70, 0xbe, 0x4b, 0xc3, 0x47, 0x93, 0x9d, 0x90, 0xd5, 0x93, 0x88, - 0x6f, 0xba, 0x62, 0xad, 0x36, 0x8a, 0x83, 0xb4, 0xcf, 0x39, 0x67, 0x40, - 0x58, 0x85, 0xa6, 0xf7, 0xeb, 0xf5, 0xb9, 0x5e, 0x6d, 0x30, 0x9d, 0x3a, - 0x4f, 0x8c, 0xe1, 0x90, 0x3a, 0xc1, 0x18, 0x7e, 0xce, 0xfd, 0x85, 0x15, - 0xe7, 0x2f, 0x77, 0xc5, 0x84, 0x41, 0x2e, 0x59, 0xbe, 0x4f, 0x2a, 0x8f, - 0x31, 0xda, 0x55, 0x27, 0x28, 0xdc, 0x28, 0x08, 0x5a, 0x41, 0xa3, 0xd5, - 0x54, 0x02, 0x47, 0x09, 0x14, 0x67, 0x4c, 0x7e, 0x06, 0x67, 0x6d, 0x05, - 0xed, 0xbc, 0xf3, 0x4d, 0x27, 0xa9, 0x6e, 0x26, 0xe7, 0x8c, 0x47, 0x4d, - 0xdc, 0x40, 0x08, 0x29, 0xc4, 0x3d, 0x33, 0x3b, 0x32, 0x48, 0xad, 0x60, - 0x50, 0xd5, 0x40, 0x09, 0x33, 0x4d, 0x52, 0x04, 0x5f, 0x3a, 0x8c, 0x12, - 0xb7, 0x6b, 0x42, 0xb4, 0x90, 0xc1, 0xa8, 0x5b, 0xc6, 0xb9, 0x3a, 0xf1, - 0x58, 0x48, 0x43, 0x08, 0xa2, 0x9c, 0xd6, 0x9a, 0xfa, 0xa7, 0x9b, 0xa1, - 0x71, 0xc5, 0x12, 0x45, 0xc7, 0xe0, 0x1d, 0x66, 0xe1, 0x1c, 0x60, 0x7a, - 0x34, 0x62, 0x4b, 0x16, 0x13, 0xe3, 0xb6, 0xb2, 0xff, 0x8a, 0x2e, 0xa3, - 0xc2, 0x1f, 0x2a, 0x26, 0x37, 0x86, 0xff, 0xc2, 0x3e, 0x1e, 0xcb, 0x28, - 0xa6, 0x0a, 0x40, 0xc5, 0xe4, 0x5c, 0x18, 0xab, 0xf3, 0x2b, 0x48, 0x3c, - 0xae, 0x1a, 0x04, 0x6c, 0xe0, 0x05, 0xd7, 0x6a, 0xf4, 0xa5, 0xf9, 0x02, - 0x84, 0x14, 0xe9, 0xfc, 0x81, 0xef, 0x90, 0xcd, 0x82, 0x6d, 0x69, 0x0b, - 0xd6, 0x6e, 0x59, 0x3b, 0x01, 0x79, 0x60, 0x7a, 0x67, 0x93, 0x6e, 0xb2, - 0xde, 0xe9, 0x75, 0x36, 0xcc, 0x97, 0x9b, 0x0e, 0xab, 0xa8, 0x54, 0x43, - 0xd5, 0x44, 0x86, 0x09, 0xae, 0x92, 0x60, 0x2c, 0xce, 0x19, 0xa5, 0xda, - 0x0b, 0xbe, 0xd0, 0x2c, 0xa6, 0xf8, 0x48, 0x0c, 0x4d, 0x18, 0x24, 0x69, - 0x04, 0xb2, 0xea, 0xc4, 0x86, 0xbb, 0x9a, 0x02, 0x69, 0x1b, 0x13, 0x9d, - 0x12, 0xd9, 0x98, 0x50, 0x31, 0x55, 0x05, 0x67, 0x59, 0x7f, 0xaf, 0x80, - 0x6a, 0x96, 0x2a, 0xa6, 0x2b, 0x14, 0x6e, 0x90, 0x46, 0x32, 0x76, 0x68, - 0x79, 0x3a, 0xcc, 0x40, 0x70, 0xd7, 0x66, 0x63, 0x73, 0x01, 0x13, 0xbf, - 0xb3, 0x28, 0x81, 0xf5, 0xc0, 0x88, 0x50, 0xe0, 0xbe, 0x19, 0x67, 0x1b, - 0x26, 0x73, 0x26, 0xaf, 0xb3, 0x9a, 0xfc, 0x19, 0x9b, 0xaf, 0x8a, 0xbf, - 0xe7, 0xe3, 0x71, 0xaa, 0xed, 0xbb, 0x84, 0x0e, 0xc9, 0xb4, 0x6d, 0x0e, - 0x32, 0x88, 0xd7, 0xe2, 0x03, 0xd5, 0x15, 0xa9, 0x2c, 0xa5, 0x9a, 0xfd, - 0x82, 0x53, 0xaa, 0x85, 0x91, 0xbc, 0x2e, 0x74, 0xe8, 0xea, 0x5c, 0xcc, - 0xc8, 0x9c, 0x5d, 0x67, 0x53, 0xe6, 0xd3, 0xa9, 0x24, 0xf8, 0x50, 0xb9, - 0x1c, 0x89, 0xe5, 0x34, 0x0a, 0x55, 0x95, 0xc0, 0xfa, 0xe9, 0xfd, 0xa6, - 0x51, 0x08, 0x06, 0x8b, 0xfb, 0xc0, 0x21, 0xfa, 0xea, 0xf3, 0x6e, 0xee, - 0x12, 0xb6, 0xcc, 0x6b, 0xcb, 0x88, 0xe9, 0x82, 0x1c, 0xac, 0x06, 0x7c, - 0x41, 0xc7, 0x8b, 0x52, 0x36, 0xc3, 0x01, 0xb3, 0xe0, 0x5f, 0x82, 0xa9, - 0x23, 0xe0, 0x23, 0xbe, 0x6a, 0x18, 0x52, 0x0f, 0x34, 0x06, 0xc2, 0x51, - 0x47, 0x6d, 0x81, 0xed, 0x1e, 0x7a, 0x5c, 0x87, 0x43, 0x09, 0xe9, 0xa0, - 0x94, 0x63, 0x8c, 0x4c, 0xd7, 0x77, 0xd0, 0x09, 0x1e, 0x06, 0x48, 0x5e, - 0x91, 0x75, 0x86, 0xaa, 0xe2, 0xe5, 0x10, 0x64, 0x5c, 0x59, 0xb1, 0x6a, - 0x7e, 0xce, 0xef, 0x55, 0xb4, 0x81, 0x6c, 0x53, 0xc3, 0x8a, 0x7b, 0x7b, - 0x36, 0x5d, 0xdd, 0xce, 0xc6, 0xa6, 0x61, 0x88, 0x6a, 0xc5, 0x55, 0x72, - 0x39, 0xa2, 0x9b, 0x45, 0xe9, 0xf3, 0x02, 0x36, 0x2e, 0xa6, 0x2a, 0x45, - 0xf9, 0x77, 0x56, 0x68, 0x76, 0xfc, 0x88, 0x21, 0x61, 0x36, 0xe4, 0x32, - 0x44, 0xfa, 0x3c, 0xfa, 0xb1, 0x02, 0x4a, 0x09, 0xbb, 0x3b, 0xaa, 0x42, - 0xbd, 0x1a, 0xdc, 0x43, 0xa0, 0x8d, 0x60, 0x19, 0xf4, 0xdb, 0x18, 0x19, - 0x2c, 0xa3, 0x9a, 0x10, 0xac, 0xa9, 0x4d, 0xa2, 0xdd, 0x8d, 0x03, 0xf2, - 0x89, 0xf6, 0x4e, 0x50, 0x43, 0x3e, 0xc1, 0xb2, 0x07, 0x83, 0xe4, 0x94, - 0xb0, 0xc7, 0x93, 0x97, 0x79, 0x55, 0x6f, 0x68, 0xb0, 0x0d, 0x5b, 0xe5, - 0x87, 0x59, 0x8d, 0xb7, 0x42, 0xb0, 0xd1, 0x0c, 0x73, 0x58, 0xab, 0x92, - 0xb0, 0xdc, 0x64, 0xf2, 0x86, 0x76, 0xd9, 0x2c, 0xee, 0x4a, 0x9a, 0x18, - 0xc3, 0x9a, 0x2b, 0x95, 0x54, 0x4e, 0x67, 0x97, 0x63, 0x28, 0xa9, 0xb7, - 0x6c, 0xbd, 0x63, 0xbd, 0x93, 0x52, 0xf2, 0xf4, 0x9c, 0x47, 0xe3, 0xe7, - 0x22, 0xb0, 0x38, 0x09, 0xc7, 0x43, 0x69, 0x2a, 0xd1, 0xa8, 0x2d, 0x1e, - 0x21, 0x49, 0x35, 0x1b, 0x98, 0x0a, 0xda, 0xd4, 0xc5, 0x8c, 0x42, 0x9b, - 0xa9, 0xe2, 0xa1, 0xf2, 0x91, 0x68, 0x69, 0x3f, 0x5d, 0x65, 0x69, 0x08, - 0x76, 0xe7, 0x88, 0xc6, 0x77, 0x97, 0x64, 0x77, 0x2e, 0xa3, 0x58, 0x1a, - 0x60, 0xb7, 0xf4, 0xe1, 0xde, 0xe0, 0xe3, 0x5e, 0xa5, 0x1a, 0x6c, 0xff, - 0x99, 0x4e, 0x57, 0x8d, 0xe3, 0x0b, 0x74, 0xc6, 0x2a, 0xd2, 0x6f, 0xf3, - 0xe9, 0xfb, 0x9e, 0x54, 0x20, 0xe8, 0x05, 0x16, 0x4c, 0x4b, 0x37, 0xe8, - 0xc6, 0x6f, 0x3c, 0x6d, 0x17, 0x33, 0xcd, 0xdf, 0x58, 0xe8, 0x75, 0x4b, - 0x63, 0xb7, 0x84, 0x09, 0xb9, 0x75, 0x0d, 0x29, 0x9e, 0xf4, 0xd8, 0x98, - 0xfb, 0x11, 0xb6, 0xa2, 0x87, 0x56, 0x4c, 0x02, 0x46, 0x59, 0x1f, 0x43, - 0xcb, 0xc7, 0x56, 0x51, 0x88, 0x5e, 0x8f, 0x0f, 0x28, 0x3a, 0xfc, 0x54, - 0xfd, 0xed, 0x31, 0x92, 0x61, 0x10, 0x04, 0x90, 0x77, 0x12, 0xdc, 0xb4, - 0xd5, 0x0a, 0x13, 0x1d, 0x4e, 0xce, 0xb4, 0xc6, 0x1a, 0x27, 0x14, 0x22, - 0xaa, 0xe9, 0xd7, 0xa1, 0xe8, 0x40, 0x1f, 0x8b, 0xfe, 0x4e, 0x13, 0x36, - 0xfa, 0x86, 0x8e, 0xf1, 0x5c, 0xbc, 0x9f, 0x16, 0xd7, 0x54, 0xa3, 0xcc, - 0x39, 0x94, 0x44, 0xcc, 0x49, 0xaa, 0xc2, 0x5b, 0xb1, 0x6a, 0x02, 0xc5, - 0xb9, 0x22, 0xe9, 0xf2, 0x26, 0x11, 0x8b, 0x3f, 0x5c, 0x0b, 0x06, 0x42, - 0x19, 0x4f, 0x48, 0xef, 0xb9, 0x05, 0xd4, 0x08, 0xd3, 0x7e, 0x8c, 0xb5, - 0x0d, 0x1c, 0x3b, 0x57, 0x14, 0x08, 0xe1, 0xfa, 0x55, 0x56, 0xc7, 0xf7, - 0xba, 0x79, 0x5c, 0x63, 0x89, 0xa1, 0x8b, 0x5e, 0xe0, 0xae, 0xbb, 0xa4, - 0xab, 0xe6, 0x75, 0x24, 0xe5, 0xb2, 0xee, 0xb8, 0xf4, 0x1a, 0x6c, 0x2c, - 0x32, 0x16, 0x52, 0x45, 0x52, 0x29, 0x04, 0x05, 0x97, 0x5f, 0x74, 0xe3, - 0x4b, 0x88, 0x6f, 0xea, 0x35, 0x08, 0xbb, 0xfa, 0x38, 0x4c, 0x67, 0xe9, - 0xc5, 0x17, 0x5d, 0x7a, 0xc9, 0xf7, 0xc8, 0x60, 0x15, 0x34, 0xd7, 0xe3, - 0x2f, 0x1b, 0x43, 0xf5, 0x60, 0x15, 0x67, 0x97, 0x79, 0xd5, 0x5a, 0x9a, - 0xf9, 0x0e, 0xd1, 0x85, 0x6f, 0xa3, 0xa6, 0x3a, 0x20, 0x42, 0xa5, 0xe2, - 0x01, 0x38, 0x36, 0x77, 0x46, 0xde, 0x6c, 0x6d, 0x44, 0xbb, 0x20, 0xe3, - 0x9f, 0x75, 0xa4, 0x91, 0x7f, 0x0d, 0x39, 0x4f, 0x5e, 0xc2, 0xf5, 0x94, - 0x4a, 0xd9, 0xc8, 0x51, 0x95, 0xc8, 0xa4, 0x24, 0x14, 0x6f, 0x12, 0x6f, - 0xe0, 0xf5, 0x65, 0x31, 0x8e, 0x3c, 0x5b, 0x8d, 0xe2, 0x00, 0x0c, 0x5b, - 0x8f, 0x95, 0x83, 0x28, 0x9e, 0x85, 0x28, 0x9b, 0xe3, 0xfd, 0x58, 0xe0, - 0xa3, 0x8a, 0x92, 0x88, 0x88, 0x5c, 0xa2, 0x5b, 0x29, 0xce, 0x7a, 0x16, - 0x1c, 0x5e, 0x46, 0x45, 0x4d, 0xe1, 0x68, 0x97, 0x9c, 0x23, 0x27, 0x45, - 0x27, 0xb4, 0xe6, 0xb0, 0x5c, 0xd6, 0x4c, 0xa7, 0x4c, 0x02, 0x57, 0x39, - 0x82, 0x45, 0x2a, 0x21, 0x67, 0xd9, 0x90, 0x2f, 0x4a, 0xe2, 0x10, 0xa4, - 0x7f, 0x08, 0xae, 0xbd, 0x24, 0x28, 0x1b, 0xb8, 0x24, 0x46, 0x7d, 0x5c, - 0x62, 0x30, 0x45, 0x95, 0xd7, 0x73, 0x61, 0x06, 0xb1, 0x43, 0xc0, 0x93, - 0xdb, 0xed, 0x39, 0x21, 0x4e, 0x8d, 0xff, 0x78, 0x87, 0xc0, 0x80, 0x45, - 0xb0, 0x1e, 0x79, 0xec, 0x97, 0x39, 0xc2, 0x6e, 0x7d, 0x01, 0x58, 0x35, - 0x92, 0x72, 0x0f, 0x46, 0x52, 0x7d, 0x14, 0xaf, 0x5e, 0x81, 0x4f, 0xf7, - 0x98, 0x20, 0x7a, 0xa0, 0xe9, 0x55, 0x4e, 0xd3, 0x55, 0xbd, 0x0c, 0x25, - 0xff, 0xdf, 0x04, 0x32, 0xcd, 0xb4, 0xd3, 0x50, 0xa9, 0x2e, 0xc4, 0x58, - 0x48, 0xe5, 0x28, 0x6a, 0xcc, 0xe1, 0x22, 0x4d, 0x33, 0xcc, 0x9b, 0x4f, - 0xcb, 0x1b, 0xf1, 0x2d, 0xf9, 0x4c, 0xfb, 0xcb, 0x1c, 0xd6, 0xb9, 0x1c, - 0x5c, 0x12, 0x0c, 0x09, 0x99, 0x89, 0xb3, 0xa1, 0x55, 0x24, 0x96, 0x42, - 0xe7, 0x7c, 0x46, 0xb8, 0x55, 0xd9, 0x0a, 0x6d, 0x81, 0x58, 0x1e, 0xea, - 0x8b, 0xf0, 0x1c, 0xee, 0x9b, 0x1b, 0x9e, 0x1b, 0x5f, 0xdc, 0x10, 0xa9, - 0x5b, 0xc6, 0x73, 0x18, 0xc0, 0x00, 0xb3, 0xfa, 0x02, 0xd5, 0xd0, 0x1e, - 0x8b, 0x1c, 0xce, 0x6d, 0xe0, 0xd2, 0xf4, 0x35, 0x62, 0x36, 0x6b, 0x34, - 0x24, 0xdd, 0x98, 0xf6, 0x43, 0x4c, 0x76, 0x5a, 0x44, 0x29, 0x7c, 0x5c, - 0x67, 0xb5, 0x39, 0x76, 0x8b, 0xd7, 0x95, 0x29, 0x84, 0xa0, 0x5d, 0x81, - 0x70, 0x9c, 0x16, 0xd1, 0x54, 0xc9, 0x5f, 0x2c, 0x70, 0x8e, 0xb2, 0xdf, - 0x07, 0x72, 0x96, 0xa3, 0x15, 0xc1, 0xe7, 0x26, 0xe9, 0x50, 0xd3, 0xc7, - 0x27, 0x54, 0x73, 0x73, 0xeb, 0xcb, 0x47, 0x5b, 0xa4, 0x1f, 0x22, 0x5c, - 0x32, 0xab, 0x2e, 0x1e, 0x03, 0x80, 0x73, 0xdb, 0x82, 0xfa, 0x54, 0xe8, - 0x9a, 0x1b, 0x20, 0x5b, 0xdc, 0x07, 0xbb, 0xec, 0x54, 0x34, 0x45, 0xb3, - 0x1f, 0xe9, 0x41, 0x18, 0x9e, 0xda, 0x25, 0x54, 0xe3, 0x1b, 0x3d, 0x65, - 0xa3, 0x7a, 0xe6, 0x29, 0xac, 0xdf, 0x48, 0x64, 0x09, 0xdf, 0x2c, 0x8b, - 0x1e, 0xfd, 0xd8, 0x3c, 0x16, 0xd7, 0xd7, 0xed, 0xd6, 0x63, 0xd7, 0xb5, - 0x51, 0x8b, 0x21, 0x07, 0x6c, 0xae, 0x9e, 0xdd, 0xd0, 0x98, 0xa1, 0x1c, - 0x39, 0x47, 0x3a, 0x8d, 0x83, 0x86, 0x2d, 0xf7, 0x68, 0x57, 0x9e, 0xe2, - 0x4f, 0x15, 0x87, 0x08, 0x72, 0x13, 0x63, 0x7c, 0x31, 0x88, 0x42, 0x60, - 0x45, 0x4d, 0xc2, 0x65, 0x47, 0x09, 0xda, 0xce, 0x79, 0x57, 0xd8, 0x58, - 0xa9, 0x15, 0xf9, 0x64, 0x23, 0x54, 0xa5, 0xb6, 0xb0, 0xf9, 0x80, 0xb1, - 0xe2, 0xea, 0x15, 0x46, 0x59, 0xf3, 0x28, 0x5d, 0x33, 0xaf, 0xa5, 0xc4, - 0x57, 0xae, 0x06, 0xa6, 0x52, 0x34, 0x49, 0x63, 0x6b, 0x38, 0xc6, 0x35, - 0xf9, 0xc2, 0xc2, 0x4f, 0x39, 0x64, 0xb5, 0x16, 0x2a, 0x21, 0x77, 0x3a, - 0x61, 0xaf, 0x3b, 0xe8, 0xd2, 0x70, 0x56, 0x34, 0x80, 0x66, 0xeb, 0xf1, - 0xc3, 0x87, 0xd1, 0xf5, 0x19, 0x10, 0x7c, 0xc8, 0x13, 0x4f, 0xce, 0xdb, - 0x29, 0xcd, 0x61, 0x50, 0x23, 0xe3, 0xb6, 0x22, 0xee, 0xe4, 0xe9, 0x31, - 0xf3, 0x50, 0x3f, 0x89, 0xf9, 0x78, 0x73, 0x59, 0x6f, 0x4b, 0xf0, 0x6b, - 0xe3, 0xe5, 0x66, 0xad, 0x5c, 0x21, 0x95, 0xa2, 0xd9, 0xd7, 0xd6, 0x97, - 0x5f, 0x7e, 0x99, 0xf4, 0xce, 0x98, 0x70, 0x58, 0xae, 0x59, 0x8c, 0x40, - 0x9e, 0x66, 0xd7, 0x2b, 0xc0, 0x29, 0x36, 0x4f, 0x4a, 0x20, 0x9b, 0xf1, - 0xc8, 0xa3, 0xce, 0xbe, 0x12, 0x78, 0xfa, 0x2b, 0x4c, 0xc2, 0x61, 0xc9, - 0x63, 0xa4, 0x1e, 0x36, 0x50, 0xc2, 0xca, 0x9c, 0x04, 0xd6, 0x32, 0xab, - 0xe7, 0xe5, 0x34, 0x99, 0x8d, 0xe7, 0x95, 0x7f, 0x48, 0x25, 0x5d, 0xb1, - 0xdb, 0xd3, 0x2d, 0x9d, 0x8d, 0xe6, 0x63, 0x49, 0x5a, 0x7d, 0xf5, 0xe3, - 0x69, 0xb2, 0x7e, 0x7c, 0xba, 0xb9, 0xfb, 0x15, 0x61, 0xf6, 0x34, 0xce, - 0xea, 0x78, 0x74, 0x4f, 0x68, 0x6d, 0xd0, 0xd2, 0x5d, 0xeb, 0x0c, 0x7d, - 0xc1, 0xb2, 0xb2, 0x64, 0xba, 0x42, 0x48, 0x37, 0x6c, 0x1d, 0xd7, 0x0b, - 0x88, 0x96, 0x0d, 0xdf, 0x5e, 0x44, 0x61, 0x93, 0x69, 0x65, 0x49, 0x50, - 0xce, 0x85, 0x91, 0x51, 0x7a, 0x93, 0x41, 0x62, 0x48, 0xb1, 0x95, 0x38, - 0x2b, 0x52, 0xdd, 0x3d, 0x57, 0x6a, 0x9b, 0x43, 0xf5, 0x98, 0xc5, 0x16, - 0x34, 0xfa, 0x19, 0x82, 0x00, 0xc2, 0xe2, 0xc4, 0x69, 0xc2, 0xa6, 0x11, - 0xfb, 0x68, 0x0d, 0x17, 0x10, 0x21, 0xe9, 0x88, 0xe6, 0x69, 0x90, 0xf1, - 0x7f, 0xce, 0x7c, 0x55, 0xe9, 0xa2, 0xcc, 0x7e, 0x43, 0x75, 0xfe, 0x63, - 0x10, 0x86, 0x1c, 0x56, 0x0a, 0xa3, 0xae, 0x84, 0x75, 0x9f, 0x97, 0xa8, - 0xaa, 0x50, 0x22, 0xd7, 0x42, 0x5a, 0x9f, 0x19, 0xcc, 0xe5, 0x29, 0xa9, - 0x55, 0xad, 0xd5, 0xda, 0xd0, 0x3f, 0x6f, 0x05, 0xed, 0x2c, 0x3e, 0x60, - 0x62, 0xd0, 0xd6, 0xe9, 0x00, 0xc5, 0x64, 0x32, 0xea, 0x14, 0x09, 0xc2, - 0x38, 0x3c, 0x79, 0xb8, 0xb3, 0xd3, 0x4d, 0x1e, 0x21, 0xd0, 0xba, 0x81, - 0x0f, 0x85, 0x5c, 0xa1, 0x05, 0x04, 0xa2, 0x00, 0x72, 0xcc, 0x11, 0x2b, - 0x12, 0x44, 0x35, 0xd1, 0x92, 0x0a, 0x7b, 0x1d, 0x09, 0x0f, 0xe8, 0xfc, - 0xbc, 0xf3, 0xe8, 0xd1, 0xf6, 0x57, 0x7b, 0x27, 0xbd, 0x47, 0x3b, 0xdb, - 0x9d, 0x0d, 0x91, 0xc3, 0x43, 0xdc, 0xf5, 0x22, 0xd4, 0x44, 0x92, 0x0f, - 0xd9, 0x84, 0x4e, 0xc9, 0x81, 0x1a, 0x72, 0x66, 0x99, 0x9d, 0x9d, 0xea, - 0x1d, 0x27, 0x2f, 0x9a, 0x37, 0xbf, 0x7a, 0xc7, 0x8e, 0x8e, 0x8e, 0x88, - 0x91, 0x04, 0x21, 0xe4, 0x4c, 0x98, 0xb6, 0x92, 0xc2, 0xa4, 0x81, 0x10, - 0xad, 0xb5, 0x8f, 0x02, 0x0a, 0xa2, 0xb9, 0x91, 0x1f, 0x71, 0x2c, 0xb9, - 0xc1, 0xc9, 0xfa, 0xe1, 0xc1, 0x06, 0x6f, 0x41, 0x14, 0x5d, 0xa3, 0xa0, - 0xc2, 0x3c, 0xd2, 0xae, 0x94, 0x06, 0xb0, 0x9b, 0x65, 0x5a, 0x4c, 0xc9, - 0xd6, 0x8c, 0xee, 0x7e, 0x54, 0xcc, 0xe9, 0xa9, 0x4d, 0x71, 0xd7, 0x28, - 0x84, 0xa9, 0x14, 0x1e, 0x5d, 0x52, 0x09, 0x60, 0x11, 0x33, 0x48, 0x26, - 0x49, 0x69, 0x7f, 0x6c, 0x87, 0xa2, 0x12, 0xc9, 0x3a, 0xd7, 0x60, 0xe0, - 0x34, 0x28, 0x21, 0x3e, 0x1d, 0xfc, 0x5a, 0x6b, 0x14, 0xcf, 0x42, 0x18, - 0xcf, 0xa7, 0xa1, 0x6f, 0x71, 0x0f, 0x4c, 0x08, 0x2b, 0x22, 0xe4, 0xee, - 0x36, 0x01, 0x23, 0xe3, 0x7c, 0xb8, 0x61, 0x57, 0x0b, 0x15, 0x91, 0xe3, - 0xcd, 0x1b, 0x42, 0xa8, 0xa8, 0x28, 0x9e, 0x91, 0xa9, 0x58, 0xdc, 0x83, - 0x7a, 0x2c, 0x75, 0xa3, 0x11, 0x75, 0x02, 0xeb, 0xcb, 0x69, 0xa8, 0x84, - 0x5a, 0x24, 0xf0, 0x6d, 0x25, 0xea, 0x32, 0x94, 0xcd, 0x11, 0x95, 0xf5, - 0x3a, 0xbd, 0x11, 0xc6, 0x93, 0x9c, 0x97, 0x40, 0x46, 0x58, 0x8e, 0xb0, - 0xa0, 0x04, 0x4a, 0xf2, 0x63, 0xf1, 0xad, 0x8f, 0xfc, 0x1b, 0x18, 0xc1, - 0x38, 0xc0, 0xea, 0xe3, 0x3d, 0xfc, 0xe2, 0xec, 0xd5, 0x4b, 0x29, 0x0b, - 0xc5, 0x90, 0x16, 0x98, 0x31, 0x23, 0xee, 0x80, 0x6a, 0x7e, 0x3e, 0xc9, - 0x71, 0xc3, 0xea, 0xda, 0x92, 0x8d, 0xf4, 0x2e, 0x6f, 0xea, 0xb6, 0xe4, - 0x07, 0x52, 0x3b, 0x89, 0x39, 0x13, 0xe5, 0x6f, 0x75, 0x25, 0xba, 0x22, - 0xd8, 0xe6, 0x6c, 0xa0, 0x0c, 0x51, 0x21, 0x80, 0x10, 0x7d, 0xb3, 0xf9, - 0xa1, 0x77, 0x7d, 0x7d, 0xdd, 0xc3, 0x81, 0x61, 0x90, 0xb7, 0x20, 0x70, - 0xf4, 0xb1, 0x2c, 0xf8, 0x4c, 0xb8, 0x6b, 0x8f, 0xbe, 0x0d, 0x07, 0x09, - 0x3b, 0xed, 0x95, 0xe9, 0xb5, 0x56, 0x0d, 0xa3, 0x8a, 0x08, 0x0e, 0x0e, - 0x91, 0xeb, 0x4b, 0xb8, 0xfa, 0xd5, 0x8c, 0xfe, 0x95, 0x8a, 0xed, 0x52, - 0x03, 0xe2, 0x2c, 0xd7, 0x2f, 0xad, 0x43, 0x61, 0xa1, 0xe4, 0x3b, 0x5f, - 0x44, 0x05, 0x04, 0x67, 0xac, 0x21, 0x2b, 0x7e, 0xce, 0x79, 0x89, 0xc2, - 0x19, 0xfa, 0x77, 0x50, 0x0b, 0x40, 0x8d, 0x55, 0x36, 0x8a, 0x6d, 0x9c, - 0xe6, 0xde, 0x72, 0x86, 0x09, 0x1a, 0x2a, 0xbf, 0x11, 0x2c, 0x13, 0x28, - 0x8e, 0xbf, 0x7d, 0xf3, 0x52, 0xd0, 0x46, 0x1c, 0xd3, 0x67, 0x72, 0xe6, - 0x2a, 0xf1, 0xb8, 0x51, 0x40, 0x2f, 0x63, 0xae, 0x57, 0x84, 0x77, 0x11, - 0x36, 0x2b, 0x2d, 0xda, 0x42, 0xb9, 0xa3, 0x29, 0x45, 0xcb, 0x58, 0xa7, - 0x54, 0xbb, 0x87, 0xca, 0x9a, 0x21, 0x73, 0x80, 0xea, 0x4a, 0x15, 0x1e, - 0x3d, 0x72, 0x21, 0x0a, 0xb4, 0xeb, 0x9c, 0xbb, 0xc9, 0x2c, 0xcf, 0x08, - 0xfc, 0x3b, 0x10, 0x30, 0x59, 0x81, 0x27, 0x59, 0x79, 0xa1, 0x49, 0x24, - 0xbc, 0xb4, 0xc6, 0x82, 0xb9, 0xa1, 0xff, 0xde, 0x63, 0xa7, 0x20, 0xf1, - 0xda, 0x39, 0xa1, 0x36, 0x33, 0x4d, 0xac, 0x61, 0x11, 0x32, 0xb2, 0x54, - 0x0e, 0xd3, 0x29, 0x4c, 0x30, 0xa1, 0xaa, 0x64, 0xd5, 0x7b, 0x20, 0xd8, - 0x6f, 0xc6, 0xc5, 0xbc, 0xba, 0x59, 0x4b, 0xa4, 0xe0, 0x23, 0x37, 0xc4, - 0x25, 0xaf, 0x6a, 0x0a, 0xc6, 0xc0, 0xbd, 0x18, 0x5c, 0x82, 0xf6, 0x2b, - 0x09, 0x1a, 0x84, 0xa4, 0x49, 0xa9, 0x2a, 0x6b, 0xae, 0xc5, 0xff, 0xee, - 0x1b, 0x6b, 0x78, 0x3f, 0xa4, 0xf2, 0x53, 0x70, 0x84, 0x07, 0x07, 0x9d, - 0x64, 0x95, 0x7c, 0xd7, 0xd5, 0x3a, 0xf1, 0xc4, 0x6a, 0x82, 0x1b, 0xc9, - 0x41, 0x79, 0x45, 0xae, 0x4a, 0x6b, 0x0b, 0x2d, 0x56, 0x0c, 0xa4, 0xd9, - 0x53, 0x1f, 0x61, 0x30, 0x79, 0x9a, 0x97, 0x2a, 0xc8, 0xd1, 0xfa, 0x4e, - 0xa2, 0xbe, 0xb7, 0x13, 0xa9, 0x57, 0xec, 0xbf, 0x52, 0x7b, 0xa2, 0x80, - 0x82, 0x8e, 0x8a, 0xe2, 0x3c, 0x2d, 0xd7, 0xa2, 0x15, 0xc2, 0x4a, 0x1c, - 0x38, 0x42, 0xf2, 0x05, 0x8b, 0x58, 0x46, 0x2d, 0x7c, 0xc7, 0x4f, 0xf7, - 0xb5, 0x4c, 0x16, 0xb3, 0x1e, 0xbc, 0xa6, 0xc7, 0xc3, 0x90, 0xf7, 0x86, - 0xfd, 0x78, 0x3f, 0x6c, 0xa2, 0xb9, 0x3f, 0x88, 0xbd, 0xd7, 0x94, 0x40, - 0x61, 0x23, 0x41, 0xfc, 0x45, 0x2a, 0xa9, 0x24, 0x0d, 0x03, 0x63, 0xb3, - 0x24, 0x0d, 0xc5, 0xf2, 0x68, 0xd1, 0x4b, 0x88, 0x51, 0x2c, 0x1c, 0x6a, - 0x21, 0x4b, 0x2f, 0x4e, 0x25, 0x5a, 0x92, 0xc6, 0x49, 0x33, 0x7f, 0x80, - 0xd6, 0xfb, 0x58, 0x72, 0x46, 0xdd, 0x11, 0xc0, 0xf3, 0xaf, 0x91, 0x89, - 0x1e, 0x01, 0x80, 0x56, 0x8e, 0x9d, 0x78, 0x71, 0x36, 0xac, 0xb8, 0xaf, - 0x93, 0x62, 0x6a, 0x65, 0x50, 0x85, 0x5b, 0xd9, 0x65, 0xba, 0x00, 0xa6, - 0x54, 0x58, 0x06, 0xba, 0xcb, 0x00, 0x94, 0x42, 0xeb, 0xae, 0x98, 0xdf, - 0x80, 0xa5, 0xf7, 0xae, 0x14, 0x58, 0x0c, 0xd1, 0x86, 0xf9, 0x04, 0x9b, - 0xca, 0x38, 0xdd, 0xf2, 0x48, 0x70, 0x5e, 0x66, 0x16, 0x7d, 0x11, 0xb4, - 0xb4, 0x99, 0x8a, 0xb0, 0x81, 0x30, 0xf3, 0x69, 0x64, 0x9f, 0xe0, 0xba, - 0xe0, 0xc4, 0x08, 0x75, 0x27, 0xef, 0xcb, 0x8b, 0x31, 0x4c, 0x3a, 0x74, - 0x7a, 0xf0, 0xaf, 0xbb, 0xdd, 0x19, 0xf1, 0xd3, 0xf8, 0x67, 0x5d, 0x14, - 0xe3, 0x6f, 0x06, 0x93, 0x21, 0x76, 0xb4, 0xca, 0xfb, 0xdf, 0xd9, 0x11, - 0x5a, 0x7e, 0x0d, 0x9f, 0x2d, 0x20, 0xc2, 0x4e, 0xe6, 0xb5, 0x40, 0x35, - 0x60, 0x45, 0x36, 0xd0, 0x83, 0x08, 0x6d, 0x5a, 0x8d, 0xcd, 0x56, 0x38, - 0xf0, 0x92, 0x0e, 0x99, 0x77, 0xa7, 0xb9, 0xf2, 0x12, 0x0a, 0xfa, 0x26, - 0x16, 0xd7, 0x88, 0x3f, 0x77, 0xc3, 0xdd, 0x62, 0xec, 0x35, 0x6e, 0x48, - 0xe9, 0xce, 0x64, 0x63, 0xfa, 0x80, 0xd4, 0x94, 0x45, 0x09, 0x60, 0x01, - 0x77, 0x95, 0xeb, 0x2d, 0x51, 0xbd, 0xcd, 0x1c, 0xf5, 0x5f, 0x24, 0x52, - 0x6e, 0xa2, 0x1f, 0x37, 0x15, 0xca, 0xd8, 0xdc, 0x47, 0x54, 0x9d, 0x6b, - 0xf8, 0xbb, 0xd5, 0x8d, 0x20, 0xd1, 0xba, 0xb8, 0x13, 0x27, 0xd5, 0x54, - 0x9a, 0x77, 0x90, 0x5b, 0x0e, 0xb9, 0xec, 0x5a, 0xd6, 0xe3, 0x84, 0xae, - 0x69, 0xa2, 0x5c, 0x77, 0xe2, 0x7c, 0x6e, 0x22, 0x6d, 0x66, 0x48, 0xe7, - 0x56, 0x94, 0x4e, 0xbb, 0x53, 0xb0, 0xbe, 0x75, 0x55, 0xe0, 0x62, 0x7c, - 0x36, 0xae, 0xde, 0xa7, 0x14, 0x17, 0xa9, 0xe8, 0x50, 0x54, 0x01, 0x21, - 0xce, 0x12, 0xc5, 0x26, 0x08, 0xfd, 0x51, 0x6a, 0x19, 0x00, 0xee, 0x0e, - 0x59, 0x41, 0x57, 0x2d, 0x5b, 0x54, 0x2d, 0x50, 0x2c, 0xdf, 0xc6, 0x2b, - 0x99, 0x59, 0x2e, 0x70, 0x53, 0x89, 0xe2, 0x41, 0x61, 0x0c, 0x79, 0xd1, - 0xd0, 0xd1, 0x1b, 0x33, 0x95, 0xca, 0x0a, 0x3b, 0xb2, 0x13, 0x9d, 0x02, - 0xe1, 0x65, 0xf2, 0x2f, 0x89, 0x4f, 0xeb, 0x18, 0x62, 0xa8, 0x5b, 0x2f, - 0x73, 0x89, 0x63, 0x3e, 0x88, 0x69, 0x16, 0xf0, 0x55, 0xad, 0x2c, 0x8e, - 0x69, 0x21, 0x5b, 0xf5, 0x91, 0x07, 0x01, 0xc1, 0xab, 0xbf, 0x2e, 0x53, - 0x12, 0xc6, 0x7c, 0x9e, 0xd7, 0x25, 0x09, 0x3e, 0x2a, 0x00, 0xf1, 0x0b, - 0xaa, 0x96, 0xe8, 0x28, 0x38, 0x96, 0x4f, 0x1d, 0x54, 0x01, 0xc4, 0x34, - 0x0c, 0x5f, 0x3c, 0x55, 0x89, 0xd8, 0x92, 0x32, 0x04, 0xac, 0xc1, 0xe2, - 0xf6, 0x7b, 0xfc, 0x51, 0xef, 0x05, 0xff, 0xdb, 0x39, 0x90, 0xb7, 0xce, - 0xe0, 0xad, 0xbd, 0xc5, 0xa9, 0xf9, 0x57, 0x3b, 0x1f, 0x57, 0xde, 0x8c, - 0xdd, 0x17, 0x18, 0x5b, 0x12, 0xd2, 0x5d, 0x2d, 0xd3, 0xd4, 0x7a, 0x42, - 0xaf, 0x21, 0xcf, 0x91, 0x53, 0x33, 0x34, 0x21, 0x09, 0x29, 0x48, 0x8f, - 0x7a, 0xe3, 0x9c, 0x68, 0x8e, 0x8e, 0xab, 0x82, 0xf5, 0xbb, 0x4f, 0xbb, - 0x34, 0xbd, 0x0a, 0x9b, 0x6d, 0x1e, 0xf9, 0xd8, 0xe6, 0x62, 0xc7, 0xfe, - 0xf6, 0xd3, 0xac, 0x47, 0x63, 0x7c, 0x23, 0x99, 0xa5, 0xb2, 0xcf, 0xf3, - 0x3a, 0x09, 0xa1, 0x3d, 0xbc, 0xe5, 0x1f, 0x29, 0x7f, 0xfb, 0x31, 0x44, - 0xf9, 0xdd, 0x8b, 0x25, 0x56, 0x3e, 0xf2, 0xce, 0x0b, 0xed, 0x76, 0xb0, - 0x1e, 0x77, 0x71, 0xf7, 0xbd, 0xe5, 0xde, 0xf8, 0x2e, 0xad, 0xf1, 0x7f, - 0x9d, 0xd5, 0x17, 0x36, 0x5e, 0xd2, 0x70, 0xbf, 0xdc, 0xba, 0xb0, 0x5d, - 0xe3, 0x39, 0x26, 0x30, 0x70, 0x82, 0x8e, 0xae, 0xb0, 0x4a, 0xf9, 0xe6, - 0xfd, 0xf0, 0x2c, 0xc8, 0x0a, 0x40, 0x13, 0x79, 0xcf, 0xb2, 0x12, 0xcf, - 0x74, 0x15, 0x14, 0x0f, 0xac, 0xb0, 0x17, 0xfc, 0x03, 0x48, 0x82, 0x07, - 0x3f, 0x1c, 0x11, 0x96, 0x02, 0xdc, 0x4f, 0xd3, 0x5a, 0x94, 0x00, 0x1e, - 0x20, 0x2a, 0x7d, 0x65, 0x00, 0x52, 0xa7, 0x10, 0xe4, 0x20, 0xfa, 0x07, - 0x77, 0xb2, 0x45, 0x1a, 0x32, 0x9e, 0x60, 0x48, 0x4a, 0x22, 0xee, 0x97, - 0x86, 0x18, 0x48, 0x35, 0x1c, 0xa5, 0x0e, 0xd5, 0xc7, 0xaf, 0x05, 0x75, - 0xa7, 0xe6, 0x1e, 0x16, 0xdc, 0xd0, 0x1c, 0xca, 0xa1, 0x96, 0x14, 0xfb, - 0x1c, 0xcc, 0xe2, 0xe1, 0x48, 0x56, 0x37, 0xd3, 0x3a, 0xfd, 0x90, 0x55, - 0x9a, 0x90, 0x29, 0xdd, 0x61, 0xa8, 0xbb, 0xd3, 0xb7, 0x3c, 0x12, 0x0b, - 0xab, 0xc2, 0xa2, 0xd0, 0x52, 0xd5, 0xdd, 0x7e, 0xf2, 0x9f, 0x8a, 0x8f, - 0x08, 0xdc, 0x9a, 0x6d, 0xa9, 0xe8, 0xbf, 0x7f, 0xb0, 0x80, 0xe2, 0x12, - 0x14, 0x4c, 0xad, 0xdd, 0x40, 0xfe, 0x7c, 0x8c, 0x87, 0x84, 0x19, 0x77, - 0xbe, 0xd3, 0xb0, 0x48, 0xd4, 0x7d, 0x50, 0xb2, 0x7c, 0x20, 0x56, 0xc5, - 0xf7, 0xa2, 0x75, 0xf3, 0x68, 0x25, 0x89, 0xc2, 0xcd, 0x87, 0xf7, 0x78, - 0x90, 0xa2, 0x76, 0x7e, 0x9e, 0xc1, 0xd4, 0xfe, 0x4d, 0xa6, 0xf3, 0xcd, - 0xf2, 0xf9, 0xd8, 0xa0, 0x68, 0xa1, 0x67, 0x1c, 0xeb, 0x9b, 0x92, 0x81, - 0x5f, 0x56, 0x37, 0xe4, 0xd1, 0xe3, 0x08, 0xa1, 0x85, 0x10, 0xb3, 0x49, - 0xf9, 0x6b, 0x1c, 0x4f, 0x65, 0xb1, 0x9b, 0x42, 0xb4, 0x6c, 0x28, 0x22, - 0x71, 0xef, 0xee, 0xb5, 0xa4, 0x4d, 0x6b, 0x0c, 0x80, 0xbc, 0xb4, 0x51, - 0xb1, 0x32, 0x20, 0x95, 0x07, 0xc4, 0x95, 0xe8, 0x71, 0xc4, 0x92, 0xfb, - 0x00, 0xc4, 0x50, 0x5b, 0xb1, 0xeb, 0xd0, 0xfa, 0x50, 0x3d, 0x68, 0x3a, - 0x10, 0xe3, 0x68, 0x38, 0x0a, 0xae, 0x7b, 0x2f, 0x75, 0xa2, 0x43, 0x36, - 0x47, 0x14, 0xd0, 0xe1, 0x4a, 0x9d, 0xf1, 0xe6, 0xe8, 0x7d, 0xbc, 0xd1, - 0x6d, 0xce, 0x23, 0x15, 0x2d, 0xdf, 0x08, 0x22, 0xaf, 0x93, 0x50, 0xe1, - 0x0b, 0x4d, 0x35, 0x7e, 0x39, 0xfe, 0x27, 0x8f, 0x84, 0xb7, 0xd4, 0x56, - 0x11, 0x5a, 0xe0, 0xea, 0xa4, 0xea, 0x70, 0x61, 0x40, 0x08, 0x06, 0xb2, - 0x24, 0x4c, 0x08, 0xbd, 0x9e, 0x28, 0xb1, 0x40, 0xe2, 0xea, 0xc7, 0xb5, - 0x54, 0x16, 0x26, 0xa0, 0x10, 0xda, 0x93, 0x6f, 0xc2, 0x95, 0xcf, 0x4e, - 0x11, 0x05, 0x5a, 0x72, 0x60, 0xcd, 0x2e, 0xdf, 0x07, 0x85, 0x24, 0xdd, - 0x3d, 0xa4, 0xef, 0xbb, 0xf6, 0x6f, 0x81, 0xfd, 0xdd, 0x97, 0x06, 0xd3, - 0x6c, 0x97, 0xe6, 0x72, 0x95, 0x8e, 0x57, 0x64, 0xea, 0xe1, 0xc5, 0x6f, - 0xf8, 0x5f, 0x62, 0x99, 0x1f, 0xfb, 0xae, 0xd1, 0xc5, 0x47, 0xbf, 0x49, - 0x6f, 0x51, 0x74, 0xc4, 0xca, 0x17, 0x8a, 0x97, 0xc4, 0x23, 0x95, 0x24, - 0x1b, 0x67, 0x17, 0x7c, 0xa1, 0x3e, 0x7d, 0x79, 0xf8, 0xe3, 0xe1, 0x4b, - 0xbd, 0x5c, 0x7e, 0x38, 0x3d, 0xdd, 0x7c, 0x9f, 0x95, 0xe7, 0x59, 0x59, - 0x54, 0x6c, 0xbc, 0xa7, 0xaf, 0x49, 0xa6, 0x0e, 0xa0, 0xfa, 0x2e, 0x3e, - 0x4f, 0x5a, 0xd2, 0x7c, 0x4e, 0xcd, 0xfe, 0x82, 0x11, 0xb1, 0xa1, 0x9f, - 0x74, 0xd7, 0x41, 0x99, 0x91, 0x9d, 0x3c, 0x0d, 0xc9, 0x73, 0x88, 0x27, - 0x8c, 0xa7, 0xe2, 0x19, 0xab, 0xfb, 0x9c, 0xaf, 0x8b, 0x24, 0x1f, 0x86, - 0xa6, 0x8f, 0xce, 0x08, 0xf5, 0x93, 0x1e, 0x96, 0xce, 0x08, 0x2c, 0x07, - 0xa7, 0x46, 0xab, 0x21, 0x5e, 0xf6, 0xe3, 0x3f, 0xf5, 0xf6, 0x4f, 0x7b, - 0xcf, 0x0e, 0x5f, 0x1e, 0xfe, 0xb0, 0x7f, 0x76, 0x68, 0xa5, 0x0e, 0x49, - 0x62, 0xe4, 0x53, 0x01, 0x2d, 0xfc, 0x49, 0xe6, 0x66, 0x05, 0xdd, 0xea, - 0x9c, 0x0b, 0x39, 0x5b, 0x95, 0x8d, 0x14, 0x59, 0x6d, 0xcd, 0x69, 0x37, - 0x40, 0x96, 0xe3, 0x89, 0xf4, 0xaf, 0xa3, 0x49, 0xc7, 0xd7, 0xe9, 0x4d, - 0x45, 0x0c, 0x6e, 0x8a, 0x59, 0xc7, 0xb9, 0x41, 0xdb, 0xf0, 0x1c, 0x1c, - 0xa0, 0x95, 0x5b, 0x1e, 0x27, 0x47, 0x46, 0xab, 0xbf, 0xba, 0xd7, 0xf2, - 0xee, 0x00, 0x94, 0x26, 0xb1, 0x87, 0x5e, 0x3a, 0xb8, 0xda, 0x2b, 0xca, - 0x21, 0x0a, 0x82, 0x2f, 0xa4, 0x53, 0x55, 0xe3, 0x40, 0x35, 0x54, 0xc3, - 0x2c, 0x12, 0x43, 0x0c, 0x94, 0x8a, 0xeb, 0xbc, 0x3d, 0xa3, 0x27, 0x9a, - 0xb9, 0x05, 0x16, 0xdd, 0x11, 0x7f, 0x2c, 0x72, 0xec, 0xe0, 0x32, 0xc3, - 0x1c, 0x2a, 0x74, 0x3a, 0x54, 0x84, 0x39, 0x66, 0x62, 0xb3, 0x55, 0x25, - 0xa3, 0xf2, 0x3a, 0x1c, 0xac, 0x84, 0xe5, 0x51, 0x71, 0x3b, 0x29, 0xe0, - 0x28, 0x21, 0x28, 0xa5, 0x7e, 0xc8, 0x26, 0xe2, 0x60, 0xa0, 0x46, 0x88, - 0xbd, 0x0f, 0xfb, 0x98, 0x52, 0xb5, 0x23, 0x2d, 0x87, 0x17, 0x0a, 0xbd, - 0x15, 0xce, 0x5d, 0x80, 0x5f, 0x59, 0x8a, 0xa4, 0x0d, 0xa2, 0x11, 0xc3, - 0xc0, 0x6b, 0x71, 0x4f, 0xe1, 0x0b, 0x56, 0x77, 0xf4, 0x63, 0x0a, 0xb5, - 0xc9, 0x08, 0x3e, 0xcd, 0x38, 0xd2, 0x62, 0x1b, 0x91, 0x1a, 0xb8, 0x52, - 0xb4, 0x2e, 0xb6, 0x69, 0x84, 0x02, 0xb8, 0x0d, 0xf7, 0x6b, 0xd9, 0x35, - 0x18, 0x40, 0x19, 0x0f, 0x93, 0x8d, 0x14, 0x58, 0x55, 0xd2, 0xf9, 0x5b, - 0x37, 0x24, 0xf9, 0xdb, 0x41, 0x30, 0x0c, 0xa6, 0x00, 0xc6, 0xe3, 0x9c, - 0x6d, 0xad, 0x46, 0xb5, 0x6e, 0x40, 0x61, 0x28, 0x07, 0x26, 0xbd, 0x19, - 0xe8, 0x47, 0x28, 0xc3, 0x9b, 0x52, 0xa8, 0x1b, 0xe3, 0x79, 0x90, 0x2d, - 0xa7, 0x96, 0x88, 0x3a, 0x7e, 0x18, 0x53, 0x2a, 0x04, 0xca, 0xd1, 0xaa, - 0xa2, 0x45, 0xfe, 0x29, 0x8f, 0x24, 0x52, 0x65, 0x18, 0xae, 0x44, 0x11, - 0x43, 0x71, 0x39, 0x33, 0x03, 0x27, 0xb9, 0x0f, 0xf7, 0x78, 0x80, 0x40, - 0x58, 0x4e, 0x04, 0x7f, 0x5b, 0x35, 0x0a, 0x0c, 0x47, 0xef, 0x8e, 0x2d, - 0xb5, 0xdc, 0xcb, 0x66, 0x65, 0x1d, 0x42, 0x0a, 0x36, 0x02, 0x22, 0x9b, - 0x44, 0x82, 0x58, 0xbe, 0xc4, 0xe1, 0xc9, 0x9b, 0x33, 0x96, 0x79, 0x5f, - 0xd2, 0x6f, 0xb2, 0x05, 0xe2, 0x3f, 0xe2, 0x5a, 0xd0, 0x2e, 0x93, 0x86, - 0x33, 0x00, 0x43, 0x46, 0x8a, 0x46, 0xdf, 0x4e, 0xb5, 0xb2, 0x98, 0xec, - 0x2d, 0xb2, 0xd5, 0xc9, 0xac, 0x0e, 0xfe, 0x5f, 0xea, 0x48, 0x6d, 0x58, - 0x94, 0x90, 0xc8, 0x52, 0x3b, 0xa6, 0x3c, 0x4b, 0x39, 0xbe, 0x90, 0x18, - 0xa5, 0x11, 0x67, 0x79, 0xcd, 0xd1, 0x56, 0xf8, 0x50, 0x52, 0x0a, 0xa6, - 0x22, 0xb0, 0x64, 0xe1, 0x02, 0x34, 0x76, 0xcd, 0x45, 0x51, 0x88, 0xe2, - 0xa0, 0x18, 0x69, 0x1a, 0x34, 0x8d, 0x58, 0xe3, 0x63, 0xba, 0x92, 0xcd, - 0x90, 0xf9, 0xfa, 0x4e, 0x94, 0x91, 0xce, 0xd1, 0x32, 0x6a, 0x84, 0x90, - 0x5a, 0x51, 0x02, 0x6b, 0x5c, 0xb1, 0xbb, 0x44, 0x2b, 0x8b, 0xa6, 0x1c, - 0x5b, 0xce, 0x90, 0x19, 0xe7, 0x64, 0x4e, 0x92, 0x86, 0x52, 0xa9, 0xcf, - 0x22, 0xe9, 0x89, 0x7a, 0x63, 0xf0, 0x0c, 0x64, 0x6d, 0x83, 0xec, 0x83, - 0xbb, 0x14, 0x6b, 0xb1, 0x94, 0xe9, 0x6a, 0xc9, 0x60, 0xdc, 0xb9, 0x4c, - 0x54, 0x00, 0x27, 0xb9, 0x28, 0x05, 0x10, 0x51, 0xd8, 0x62, 0x5e, 0x02, - 0x36, 0x22, 0x8a, 0x0d, 0xd1, 0x91, 0x41, 0x23, 0x66, 0x54, 0x93, 0xef, - 0x2a, 0x02, 0xa1, 0x70, 0x05, 0x6f, 0x8e, 0x4e, 0xae, 0x1e, 0xc7, 0xc1, - 0x43, 0x06, 0xa5, 0xc8, 0x19, 0xf9, 0x6a, 0x0b, 0xd7, 0x65, 0x0f, 0x81, - 0x7f, 0xc8, 0xe9, 0xb5, 0x1b, 0xa6, 0x34, 0x6c, 0x90, 0x9e, 0xe3, 0x08, - 0x4f, 0xb6, 0x82, 0x8b, 0x6b, 0x51, 0x08, 0xe9, 0x3c, 0xbb, 0x4c, 0xaf, - 0x72, 0xc4, 0x8f, 0x54, 0x4b, 0x92, 0x26, 0x5b, 0xc8, 0x65, 0x01, 0x04, - 0x31, 0x20, 0x34, 0x7e, 0x64, 0x84, 0xf8, 0x06, 0xc5, 0xe3, 0x28, 0x3e, - 0x14, 0xad, 0x95, 0x64, 0x9b, 0x4a, 0x6c, 0x0d, 0xc5, 0xa9, 0x16, 0x04, - 0xd3, 0x3b, 0x70, 0xe0, 0x83, 0x72, 0xee, 0xe8, 0x89, 0xb4, 0xba, 0x6a, - 0x54, 0xab, 0xf6, 0x4b, 0x95, 0xb4, 0xd5, 0xac, 0xfe, 0x24, 0x1e, 0xbf, - 0xb8, 0xfc, 0x4b, 0x2e, 0x6e, 0xdf, 0xfb, 0x2a, 0x61, 0x30, 0xe1, 0x85, - 0xea, 0x4a, 0xf8, 0xaf, 0x4e, 0xbd, 0x85, 0x09, 0x54, 0x57, 0x6d, 0x4c, - 0x40, 0x79, 0x80, 0xaa, 0x97, 0x87, 0x27, 0xa7, 0x3f, 0xda, 0xc9, 0xe7, - 0x83, 0xcf, 0x89, 0x35, 0xba, 0xf0, 0x78, 0x84, 0xd4, 0x9c, 0x17, 0x1f, - 0x7c, 0x3b, 0xf7, 0x72, 0xf0, 0x17, 0xce, 0x3d, 0xb5, 0x2d, 0x27, 0x3e, - 0x39, 0xd9, 0x3f, 0xfd, 0x51, 0x8c, 0xa2, 0x76, 0xe2, 0x9b, 0x07, 0xde, - 0x7c, 0x28, 0x35, 0x10, 0x16, 0xbe, 0xed, 0x8f, 0x0b, 0xcc, 0x79, 0xa5, - 0xe3, 0x02, 0x7d, 0x2e, 0x1e, 0x17, 0x5d, 0x8c, 0xdb, 0x8e, 0x0b, 0x90, - 0xc7, 0xb2, 0xe3, 0x82, 0x2f, 0xe1, 0x19, 0xa1, 0x1c, 0xfb, 0xf8, 0xa0, - 0xd8, 0x05, 0xa0, 0x07, 0x85, 0xc7, 0x10, 0x92, 0xa2, 0xef, 0x3c, 0x29, - 0x30, 0x60, 0xce, 0x94, 0x93, 0x83, 0x62, 0x32, 0x51, 0x7c, 0x52, 0xd4, - 0xba, 0xbd, 0xec, 0xa4, 0xe8, 0xd9, 0x92, 0x98, 0x50, 0x32, 0xcf, 0xda, - 0x61, 0xe1, 0x3d, 0x77, 0xf4, 0xd2, 0x82, 0xf7, 0x19, 0x91, 0xd7, 0x32, - 0xe0, 0xf1, 0x26, 0xdc, 0xe7, 0xdd, 0x78, 0x9f, 0x6d, 0x0b, 0x7c, 0xd7, - 0x81, 0x80, 0x01, 0x7c, 0xdc, 0x81, 0xb0, 0x78, 0xa5, 0xd6, 0x03, 0x81, - 0x02, 0x7b, 0x4f, 0xc5, 0x3d, 0x90, 0x7c, 0x7b, 0x16, 0x03, 0x7f, 0xf8, - 0x21, 0x17, 0x5a, 0xe4, 0xf8, 0x76, 0x54, 0x32, 0xd4, 0x35, 0xc8, 0x40, - 0x75, 0x62, 0xcd, 0x11, 0xb4, 0x1d, 0x6d, 0x84, 0xd7, 0xef, 0x1c, 0x93, - 0xca, 0x04, 0x92, 0x03, 0xed, 0x74, 0x73, 0x8e, 0xb6, 0xb3, 0xfa, 0xd7, - 0x94, 0xc1, 0x89, 0x29, 0x58, 0x19, 0x9d, 0x28, 0x2b, 0xca, 0x52, 0x27, - 0x25, 0x26, 0xf3, 0x4f, 0x08, 0xce, 0x51, 0xcd, 0x7a, 0x72, 0xb1, 0x35, - 0xf9, 0x53, 0xdb, 0xd8, 0xdb, 0x79, 0x95, 0xb9, 0x4a, 0x84, 0x63, 0xad, - 0xc6, 0xab, 0xda, 0xda, 0xbf, 0x7b, 0x9b, 0x5a, 0x47, 0xb5, 0x52, 0x18, - 0xcd, 0xe3, 0xed, 0x46, 0x18, 0x0d, 0xdd, 0xce, 0x61, 0xbb, 0xa6, 0x55, - 0xcf, 0x2a, 0xf0, 0x26, 0x4f, 0xed, 0x57, 0x55, 0x5c, 0x9f, 0xbd, 0x3e, - 0xe5, 0x40, 0x9a, 0x90, 0x20, 0x8d, 0xb8, 0x42, 0x96, 0x07, 0x5d, 0x5f, - 0x96, 0xc5, 0xfc, 0xe2, 0xd2, 0xe1, 0x00, 0x58, 0x13, 0x51, 0xc5, 0x69, - 0xe7, 0x89, 0x4b, 0x05, 0x5c, 0x21, 0x2b, 0xc9, 0x06, 0x55, 0x93, 0x2b, - 0x30, 0x8c, 0x21, 0x59, 0x67, 0x9d, 0xd1, 0x45, 0x90, 0x30, 0x4c, 0x8d, - 0x9c, 0x64, 0x18, 0x90, 0x58, 0x60, 0xac, 0x40, 0x9c, 0x55, 0xb1, 0xb1, - 0xe2, 0x2a, 0x54, 0xf2, 0x24, 0x34, 0xc9, 0xa9, 0xb4, 0xeb, 0x02, 0xd6, - 0x1b, 0xa5, 0x3f, 0x6e, 0x48, 0x0c, 0x54, 0xbc, 0x10, 0x77, 0x86, 0x42, - 0x91, 0x02, 0x69, 0x15, 0x2b, 0x3f, 0x26, 0x14, 0x2a, 0xee, 0x28, 0xab, - 0x2f, 0x6f, 0xc3, 0x1d, 0x68, 0x3e, 0x2e, 0xb8, 0x94, 0x95, 0x42, 0x64, - 0x9e, 0x37, 0x0a, 0xf2, 0x61, 0x64, 0xb1, 0x56, 0x4c, 0x18, 0xf4, 0xd2, - 0xd2, 0x92, 0xef, 0xfc, 0x29, 0xc6, 0x16, 0x67, 0x57, 0x0f, 0x7b, 0xb8, - 0x02, 0x6a, 0xc9, 0xe0, 0xcf, 0x1e, 0xd3, 0x67, 0x31, 0x71, 0xd8, 0x93, - 0x4f, 0x65, 0xc5, 0x22, 0xd2, 0xf8, 0x9e, 0xe0, 0xe5, 0x0a, 0x8d, 0x1c, - 0xc0, 0x68, 0xc4, 0xa3, 0x13, 0x4b, 0x2d, 0xa5, 0x93, 0x39, 0x49, 0xdf, - 0x8b, 0xcc, 0xf3, 0x30, 0x89, 0x88, 0x47, 0xae, 0x27, 0x2d, 0x72, 0xa5, - 0x98, 0x55, 0x46, 0x5b, 0x22, 0x55, 0xd6, 0x99, 0x66, 0x23, 0xe1, 0x6d, - 0xc2, 0x2d, 0x0b, 0x05, 0x68, 0x10, 0x73, 0x14, 0x09, 0x84, 0xdb, 0x6f, - 0x88, 0x9e, 0xdc, 0xab, 0xbd, 0xc5, 0x30, 0xf1, 0xf1, 0xbc, 0x7c, 0xbe, - 0xca, 0xbd, 0x42, 0xc5, 0xc7, 0xdd, 0x6c, 0x6f, 0xf5, 0xb7, 0xfb, 0x3b, - 0xfd, 0xdd, 0xbb, 0x77, 0xdb, 0x5e, 0xb9, 0xb7, 0xdd, 0x36, 0xfa, 0x59, - 0x61, 0xb7, 0x1f, 0xdf, 0xd7, 0x6e, 0x3f, 0xfe, 0x9f, 0xb2, 0xdb, 0x8f, - 0x97, 0xed, 0xf6, 0xe3, 0x7f, 0xcd, 0x6e, 0x4b, 0x37, 0x3b, 0xe9, 0xd6, - 0xc3, 0xbd, 0x87, 0xd9, 0xc3, 0x9d, 0xbd, 0xbd, 0x47, 0x8f, 0xb7, 0x57, - 0xd9, 0xf3, 0xc7, 0xff, 0x92, 0x3d, 0x7f, 0xb8, 0xb8, 0xe7, 0xa2, 0x84, - 0xd9, 0x8e, 0x67, 0x55, 0x83, 0xf9, 0xf3, 0x66, 0x69, 0x2d, 0x09, 0xdc, - 0x34, 0x7d, 0x85, 0x6d, 0xce, 0x92, 0xdd, 0x14, 0x25, 0x2b, 0x48, 0x12, - 0x4c, 0x94, 0xb3, 0xc0, 0xdb, 0xa8, 0xed, 0x04, 0xc2, 0x81, 0xc9, 0x86, - 0xcd, 0x6c, 0x14, 0x35, 0x65, 0x51, 0x59, 0xe7, 0x78, 0x12, 0x20, 0x94, - 0x2a, 0x86, 0xee, 0xe2, 0x50, 0x12, 0x07, 0x84, 0x8d, 0x6d, 0xd0, 0x45, - 0xd4, 0x0d, 0x56, 0xf7, 0xe0, 0x7b, 0x3f, 0x3a, 0x89, 0x73, 0xdf, 0x43, - 0x6f, 0xc1, 0xa1, 0x46, 0x08, 0xcf, 0xfd, 0xc4, 0x51, 0x8f, 0x4e, 0xf7, - 0x1e, 0x89, 0xa7, 0x6a, 0xa1, 0x1e, 0xed, 0x66, 0xfb, 0xab, 0x9d, 0xfe, - 0xf6, 0xe3, 0x27, 0x08, 0x03, 0xd5, 0x0d, 0xbf, 0xef, 0xac, 0x60, 0xd8, - 0xf6, 0x8d, 0x6c, 0x09, 0x90, 0xd4, 0xa3, 0xbb, 0x39, 0x8e, 0xbe, 0x63, - 0xb4, 0xb7, 0x8c, 0xf8, 0xee, 0x9b, 0xfa, 0x8a, 0xcb, 0xc5, 0xea, 0x4b, - 0xa7, 0x64, 0x22, 0xac, 0x1a, 0xc5, 0x71, 0x50, 0x87, 0xb1, 0xf4, 0xd5, - 0x67, 0xc5, 0x0b, 0x22, 0xce, 0x1e, 0xda, 0x2f, 0x7b, 0x54, 0xd1, 0xd3, - 0x20, 0x97, 0xa9, 0x6c, 0x53, 0xae, 0x4e, 0x3e, 0x7e, 0x59, 0x69, 0x12, - 0xdf, 0x93, 0xb9, 0xae, 0xc5, 0x65, 0x8c, 0x3e, 0x77, 0xf1, 0x26, 0x2f, - 0xff, 0x2c, 0x54, 0x6f, 0xc2, 0x61, 0x2d, 0x96, 0x70, 0xd2, 0x1a, 0x4e, - 0x72, 0x16, 0x29, 0x92, 0xde, 0x4a, 0x38, 0x85, 0x0a, 0x4e, 0x9a, 0x0b, - 0x67, 0x05, 0x3f, 0xac, 0x7c, 0x53, 0x70, 0x17, 0xfd, 0x1f, 0x55, 0xbc, - 0x29, 0x12, 0xd8, 0x63, 0x02, 0x6a, 0xab, 0x4f, 0xf1, 0x09, 0x16, 0x85, - 0xb8, 0xd1, 0x3b, 0xb8, 0x7e, 0x63, 0x04, 0xfc, 0x89, 0x97, 0xce, 0xe1, - 0x6f, 0x85, 0x71, 0x5e, 0x31, 0xf0, 0xfd, 0x71, 0x43, 0x62, 0xc7, 0x16, - 0x17, 0x2a, 0x4f, 0xfb, 0x0f, 0xb9, 0x89, 0xef, 0x6f, 0x8c, 0xd3, 0x76, - 0x31, 0x9f, 0x98, 0x53, 0xef, 0x03, 0xe6, 0x2a, 0x9f, 0x65, 0x81, 0xdf, - 0x11, 0x64, 0x8c, 0x88, 0xf4, 0x54, 0x56, 0xe7, 0x5d, 0x35, 0x97, 0xb0, - 0xf8, 0x2d, 0xc4, 0xb0, 0xe0, 0xc1, 0xc0, 0x24, 0xd1, 0x8c, 0x40, 0x7a, - 0xfb, 0x2d, 0x99, 0xa6, 0x75, 0x36, 0x1e, 0x57, 0x01, 0x73, 0x80, 0xd0, - 0xd5, 0x5a, 0x08, 0x07, 0x0e, 0x51, 0x36, 0x93, 0x18, 0x2d, 0x0a, 0x3a, - 0x53, 0x76, 0x6c, 0x15, 0x0b, 0x08, 0x73, 0xd7, 0x85, 0x4c, 0xfc, 0xb4, - 0xff, 0xe6, 0xf5, 0xd1, 0xeb, 0x1f, 0xf6, 0x5c, 0xa8, 0xbb, 0xb7, 0xc9, - 0xeb, 0x1c, 0x91, 0xa2, 0x68, 0x86, 0x01, 0x3e, 0x8e, 0xa3, 0x66, 0x2d, - 0x64, 0x82, 0x40, 0xea, 0xe6, 0x7c, 0x34, 0xc3, 0x0a, 0x2f, 0x60, 0xc8, - 0xd2, 0xb1, 0x05, 0xde, 0x08, 0x07, 0x12, 0x7d, 0xed, 0x75, 0xe4, 0xd0, - 0x89, 0x8a, 0xf6, 0x84, 0x4f, 0xcf, 0xe7, 0xc1, 0xef, 0x21, 0xa8, 0x99, - 0x3c, 0x98, 0x26, 0xe7, 0x4a, 0x04, 0x39, 0xd8, 0x3b, 0x42, 0x5a, 0x37, - 0x78, 0xa9, 0x8d, 0xe0, 0x36, 0x23, 0x81, 0x1a, 0x08, 0x7c, 0xa1, 0x4b, - 0x23, 0xf3, 0xe6, 0x9c, 0x97, 0xd3, 0xb8, 0xcd, 0xeb, 0xf7, 0x11, 0xb8, - 0x80, 0x89, 0x29, 0x91, 0x6b, 0x40, 0xa8, 0x5c, 0xe3, 0xa1, 0x71, 0x0e, - 0x07, 0x0d, 0x8b, 0x19, 0x79, 0x4d, 0xe2, 0x95, 0x8e, 0x4e, 0x04, 0x8e, - 0xeb, 0xe9, 0xdb, 0x37, 0x2f, 0xa3, 0x8a, 0x23, 0xa1, 0xc6, 0x55, 0x12, - 0x2f, 0x3d, 0xee, 0x45, 0xf1, 0x62, 0x23, 0x71, 0x8e, 0x45, 0xc1, 0x12, - 0x2b, 0x84, 0x34, 0xae, 0x32, 0xad, 0x4a, 0x26, 0x58, 0x8f, 0x71, 0x56, - 0x66, 0xc0, 0xc8, 0xb7, 0xd0, 0x3f, 0x52, 0x35, 0xe5, 0x5d, 0x2c, 0xfc, - 0x92, 0xa1, 0x99, 0x29, 0xaf, 0x26, 0xfd, 0x10, 0x25, 0x8d, 0x66, 0x0a, - 0x2d, 0x0e, 0x41, 0xe3, 0xb0, 0x72, 0x01, 0x08, 0xd1, 0x8d, 0xec, 0x4f, - 0x43, 0x8b, 0x98, 0x87, 0x1b, 0x82, 0x04, 0xd2, 0x10, 0xfc, 0x51, 0x3a, - 0x82, 0xa6, 0x85, 0xa3, 0x30, 0x3b, 0x8f, 0xb7, 0x47, 0x17, 0x5d, 0x40, - 0x02, 0xe2, 0x41, 0x31, 0x14, 0x70, 0xc5, 0xe9, 0xa1, 0x82, 0xa5, 0xce, - 0x1e, 0xc0, 0x84, 0x0b, 0xab, 0xbf, 0xe0, 0xd2, 0x6b, 0x3e, 0x11, 0x2e, - 0xaa, 0x70, 0xd8, 0x38, 0xb4, 0x5c, 0x64, 0xdb, 0x97, 0x7b, 0x82, 0xb5, - 0xb9, 0xcc, 0x10, 0x1b, 0x64, 0x28, 0xf1, 0x67, 0x21, 0x26, 0x1d, 0xcd, - 0x3a, 0x65, 0x81, 0x59, 0x31, 0xbe, 0xb0, 0xd3, 0x55, 0x9e, 0x36, 0xe9, - 0x4b, 0xe4, 0x85, 0x76, 0x1e, 0xdc, 0x3c, 0x93, 0xf3, 0x29, 0xc1, 0x3b, - 0x8e, 0xc8, 0x60, 0x18, 0x41, 0x64, 0x21, 0x34, 0x8c, 0xa5, 0xfa, 0x8a, - 0x2f, 0x8c, 0xf0, 0x50, 0xe5, 0x3a, 0x75, 0xfc, 0xf6, 0xc9, 0xa3, 0xfe, - 0xd6, 0x86, 0x18, 0x01, 0x84, 0x84, 0xee, 0x80, 0x33, 0xfe, 0x1d, 0xca, - 0xff, 0xef, 0xbd, 0x1c, 0x1e, 0xef, 0xac, 0x70, 0x39, 0x3c, 0x23, 0xb7, - 0xe0, 0x7c, 0x32, 0x13, 0xd8, 0xcd, 0x76, 0xb8, 0x98, 0x84, 0x0c, 0xd5, - 0x3f, 0x71, 0xf5, 0x0c, 0x8e, 0xce, 0x15, 0xf8, 0x40, 0xf3, 0xe0, 0x04, - 0xb0, 0x2e, 0x0b, 0xda, 0x8f, 0x0b, 0xb7, 0x70, 0x58, 0x37, 0x43, 0xd1, - 0x45, 0xe5, 0xbf, 0x4c, 0x58, 0xb0, 0x50, 0x7b, 0xb6, 0x80, 0x3b, 0x43, - 0x6e, 0x84, 0x6e, 0x60, 0xfb, 0xc7, 0x2d, 0x2a, 0x90, 0x0d, 0x55, 0xc5, - 0xe0, 0x84, 0xaa, 0x4c, 0xad, 0x38, 0x31, 0x64, 0xca, 0x06, 0x1d, 0x56, - 0x4c, 0x5f, 0x30, 0x08, 0x80, 0xa5, 0x70, 0x29, 0x01, 0x8b, 0x01, 0x17, - 0x93, 0xd3, 0xeb, 0x15, 0x69, 0x53, 0x79, 0x40, 0x10, 0x7d, 0x24, 0xcd, - 0x82, 0xe1, 0xbe, 0x34, 0xb1, 0x54, 0xdd, 0x6a, 0x48, 0x63, 0x1d, 0x99, - 0x71, 0x47, 0x8a, 0x04, 0xcd, 0xf9, 0x69, 0x2a, 0x72, 0xc6, 0xa5, 0x6b, - 0xb4, 0xe3, 0x17, 0xe9, 0x15, 0xbe, 0x10, 0xc4, 0x13, 0x43, 0x99, 0xc3, - 0x32, 0xc3, 0xd3, 0x2c, 0x51, 0x0c, 0xc4, 0x00, 0x76, 0x93, 0xac, 0xe7, - 0x7d, 0x58, 0x08, 0xa5, 0xdb, 0x90, 0x6b, 0x8c, 0x8f, 0xa3, 0xe7, 0xf8, - 0x03, 0x26, 0x0d, 0xa6, 0x30, 0x9b, 0x8d, 0xae, 0x28, 0x3a, 0x15, 0xa7, - 0x5f, 0xca, 0x56, 0x19, 0xc8, 0x4a, 0x37, 0x89, 0x2a, 0x0f, 0x69, 0xb2, - 0x09, 0x17, 0x67, 0x19, 0x6b, 0x91, 0xf9, 0x98, 0x60, 0xee, 0xef, 0x00, - 0x2c, 0x28, 0x3a, 0xae, 0x17, 0xae, 0x65, 0xbc, 0x0a, 0x88, 0x47, 0xf4, - 0x5a, 0x2b, 0x9c, 0x67, 0xd2, 0x2b, 0x68, 0xe5, 0x17, 0xad, 0xd6, 0x02, - 0x76, 0xa3, 0xd7, 0x04, 0x30, 0xe4, 0xe4, 0x29, 0xbb, 0x72, 0xfd, 0x69, - 0x88, 0x2a, 0x22, 0x32, 0x08, 0x2a, 0xe6, 0xcc, 0x1c, 0x1e, 0x80, 0xaa, - 0x71, 0x38, 0x1d, 0x94, 0x37, 0x33, 0x5c, 0x3e, 0x29, 0xe9, 0xfc, 0x02, - 0x83, 0x56, 0x37, 0x7c, 0xe6, 0x0b, 0xa3, 0xca, 0x5b, 0x04, 0x0f, 0x72, - 0x6a, 0xed, 0x44, 0xdc, 0x28, 0x1a, 0x16, 0x39, 0x82, 0x61, 0x45, 0x21, - 0x3a, 0xec, 0xc6, 0xc1, 0x9e, 0xe4, 0x89, 0x8b, 0x12, 0x8b, 0x54, 0xe3, - 0x23, 0x64, 0x78, 0x4d, 0x93, 0x1f, 0xde, 0x1c, 0xee, 0x9f, 0x1e, 0xd2, - 0x58, 0x4c, 0xc3, 0xf8, 0x42, 0x9d, 0x44, 0x73, 0x7a, 0x72, 0x3f, 0xb4, - 0xc2, 0x45, 0x1c, 0x04, 0x83, 0x03, 0x77, 0x5f, 0x12, 0xf2, 0x3c, 0xe2, - 0x0c, 0x3e, 0xc1, 0x8f, 0xaa, 0x6f, 0xf6, 0x81, 0x8c, 0x03, 0x3d, 0xfb, - 0xeb, 0x67, 0x12, 0xd4, 0x68, 0xb2, 0xe3, 0x88, 0x7d, 0xfa, 0xd1, 0x6b, - 0xf6, 0x82, 0xc8, 0x3a, 0x0f, 0x58, 0x01, 0xd0, 0xe2, 0x19, 0x97, 0x69, - 0x39, 0x6c, 0x8e, 0x8c, 0xca, 0xa6, 0xe8, 0x00, 0x14, 0x55, 0x9c, 0x86, - 0xa5, 0xc3, 0xed, 0xd3, 0x73, 0xac, 0x21, 0xa0, 0xab, 0x18, 0x23, 0x37, - 0x49, 0x34, 0x27, 0x94, 0xfa, 0xed, 0xfe, 0x2e, 0x8b, 0x5b, 0x2c, 0x2f, - 0x04, 0x7d, 0x95, 0x2f, 0x62, 0x12, 0xaf, 0x50, 0xce, 0x9a, 0x05, 0x49, - 0x0a, 0xcd, 0xbd, 0x0f, 0xa0, 0xcd, 0x03, 0xda, 0x0c, 0xca, 0x2f, 0xbf, - 0xa5, 0xea, 0x57, 0x36, 0x18, 0xef, 0x3d, 0x3d, 0x7f, 0xfc, 0x10, 0xb6, - 0xf3, 0x5b, 0x1a, 0x3c, 0x28, 0x1e, 0x55, 0xf6, 0xf8, 0x61, 0xa2, 0x31, - 0x75, 0x71, 0x4b, 0x11, 0x30, 0x3a, 0xee, 0x39, 0x7c, 0x6d, 0xe1, 0x55, - 0xd3, 0xbd, 0xa7, 0xcc, 0x72, 0xa9, 0x1d, 0x2b, 0xfd, 0xc3, 0x09, 0x8a, - 0x05, 0x07, 0xdf, 0xf4, 0x4a, 0xcb, 0x3b, 0xea, 0xcc, 0x08, 0x28, 0xee, - 0x1d, 0x3e, 0xd8, 0x49, 0x24, 0xfb, 0x90, 0xa4, 0x8c, 0x96, 0x29, 0xac, - 0xd3, 0x0a, 0x85, 0x7c, 0x69, 0x5a, 0x22, 0x55, 0x9e, 0x70, 0xa9, 0x44, - 0xf5, 0xd2, 0xcd, 0x38, 0x44, 0x6f, 0x0b, 0x45, 0x57, 0xbd, 0x42, 0xc7, - 0x09, 0x39, 0x5f, 0x30, 0xa3, 0x1b, 0xc7, 0xc2, 0x9e, 0x18, 0xac, 0x9c, - 0x72, 0xf8, 0x0e, 0x7a, 0x79, 0xf7, 0xe6, 0xf0, 0xcf, 0x6f, 0x8f, 0xde, - 0x1c, 0x3e, 0x4b, 0xd6, 0xb7, 0xb7, 0xb6, 0x37, 0xa2, 0x08, 0xab, 0x8c, - 0x63, 0xb9, 0xee, 0xbb, 0x22, 0x2a, 0x36, 0x8b, 0x84, 0xbc, 0xca, 0x15, - 0xf8, 0xa4, 0xff, 0xa4, 0xe5, 0x06, 0x64, 0x27, 0x8a, 0x1c, 0xf0, 0x0b, - 0x0e, 0x9f, 0x6c, 0x01, 0x2b, 0x78, 0x96, 0x61, 0x20, 0x2e, 0x23, 0x36, - 0xf1, 0x2d, 0xb4, 0x9e, 0xb2, 0x5c, 0xca, 0x92, 0xc0, 0x43, 0xac, 0xdd, - 0x04, 0x72, 0x78, 0x5e, 0x68, 0xd4, 0x37, 0x43, 0x86, 0x11, 0x41, 0x2a, - 0x59, 0x0f, 0xe9, 0xb2, 0x62, 0xf7, 0x63, 0xa1, 0x95, 0x76, 0x46, 0xc1, - 0x3c, 0x47, 0x77, 0x1d, 0xec, 0x5d, 0xa8, 0x1e, 0x32, 0xd2, 0xad, 0x69, - 0xab, 0x0b, 0x45, 0x88, 0x39, 0x9a, 0xd2, 0xc8, 0x3e, 0x62, 0x14, 0x95, - 0x66, 0x37, 0xc9, 0x0f, 0x29, 0x5e, 0x22, 0x44, 0xd8, 0x69, 0x36, 0x81, - 0xae, 0xaa, 0x02, 0x83, 0xea, 0x3c, 0x14, 0x19, 0x7f, 0x62, 0x24, 0xc8, - 0xf1, 0x56, 0x7c, 0xfb, 0x24, 0x70, 0xc7, 0x0c, 0x31, 0x1c, 0x56, 0xb0, - 0xb2, 0xa8, 0xa0, 0xee, 0xe9, 0x4b, 0x77, 0xac, 0x19, 0xf8, 0xcf, 0x3c, - 0xbe, 0xba, 0x6c, 0x9f, 0x63, 0x83, 0xb5, 0xed, 0x4d, 0x1e, 0xd4, 0x26, - 0xd5, 0x75, 0x5b, 0x15, 0x6e, 0x19, 0x5e, 0xe8, 0x09, 0x5a, 0x98, 0x0c, - 0x95, 0x67, 0xf4, 0xd4, 0x4b, 0x34, 0x0c, 0x46, 0x71, 0x9a, 0x8d, 0xad, - 0xa0, 0x41, 0x30, 0x26, 0x10, 0xf7, 0x2e, 0x92, 0x00, 0x45, 0x6b, 0x82, - 0x3e, 0x17, 0x97, 0xe7, 0xcc, 0xf2, 0x45, 0xb8, 0xb9, 0xb7, 0xec, 0xc4, - 0xd5, 0xb7, 0xc8, 0x72, 0x49, 0xef, 0x72, 0xdd, 0x78, 0x2a, 0x47, 0x4a, - 0x9f, 0x11, 0x94, 0x38, 0xec, 0xff, 0x90, 0x8a, 0x47, 0x28, 0x2a, 0xa6, - 0xe2, 0xc5, 0xf0, 0xfb, 0x55, 0x14, 0xc6, 0xcb, 0xae, 0xa8, 0xf1, 0x18, - 0x08, 0x90, 0x0a, 0x06, 0x28, 0x60, 0x12, 0x46, 0x14, 0x6e, 0xc4, 0x88, - 0x2f, 0xf2, 0x3a, 0x57, 0x2a, 0xa0, 0xa4, 0x29, 0x3b, 0xf6, 0xce, 0xb5, - 0x69, 0x06, 0x4b, 0x1d, 0xed, 0x67, 0x33, 0x74, 0x2b, 0x3d, 0x8d, 0xd3, - 0x2b, 0x58, 0xbd, 0xd5, 0x22, 0xa7, 0xa2, 0xf2, 0xb6, 0x0c, 0x06, 0x10, - 0x76, 0xb3, 0x4e, 0x2f, 0x7a, 0x52, 0xf8, 0x20, 0x3e, 0xb3, 0x1c, 0x0b, - 0xf9, 0x0a, 0xd5, 0x15, 0xca, 0x5e, 0xb0, 0x10, 0x1f, 0x8e, 0x8a, 0xd4, - 0xe4, 0x7d, 0xad, 0x2a, 0x61, 0x3e, 0x89, 0xc3, 0xb3, 0xf4, 0xc2, 0x57, - 0x4f, 0x6b, 0x60, 0xc6, 0x33, 0x54, 0xfb, 0x8d, 0x05, 0x45, 0x42, 0xdb, - 0xa0, 0x8d, 0xc1, 0x23, 0x47, 0xa3, 0xde, 0x6b, 0x58, 0xff, 0xde, 0x2b, - 0x4a, 0x0a, 0x10, 0x69, 0xc3, 0xc3, 0x01, 0xb1, 0x4d, 0x91, 0x00, 0x91, - 0xb1, 0x0f, 0x5d, 0x27, 0x2c, 0xfd, 0xa1, 0x39, 0xa2, 0x1c, 0xdb, 0x8d, - 0x59, 0x07, 0x84, 0x22, 0x51, 0x91, 0xfa, 0xea, 0x4c, 0x71, 0x01, 0xbf, - 0x93, 0x82, 0xe0, 0xb4, 0xe6, 0xa0, 0x43, 0xf0, 0x4d, 0xa3, 0x6a, 0x74, - 0x21, 0x97, 0x6e, 0x98, 0x55, 0xb9, 0xf5, 0x9c, 0xec, 0x7b, 0x81, 0x99, - 0x37, 0x3b, 0x2d, 0x2d, 0x8b, 0x29, 0xad, 0x82, 0x44, 0xed, 0x47, 0xfa, - 0x56, 0x92, 0xe3, 0x85, 0xfb, 0xc9, 0xe2, 0xa3, 0xdc, 0xc4, 0xb5, 0xa2, - 0x30, 0xae, 0x84, 0xff, 0x42, 0x3e, 0x84, 0xcb, 0xa8, 0x79, 0xd0, 0x66, - 0x71, 0x0c, 0x38, 0xa5, 0xb5, 0x88, 0xd3, 0x71, 0xb6, 0x2f, 0x9e, 0x0f, - 0xdd, 0x4d, 0x32, 0x3d, 0x54, 0x3a, 0x75, 0x92, 0x8b, 0xa9, 0x51, 0x07, - 0x47, 0x5e, 0xcd, 0xcf, 0xb9, 0x92, 0x54, 0xad, 0xfb, 0xa9, 0x7e, 0x9b, - 0x88, 0x2e, 0x5a, 0xe1, 0xe1, 0x85, 0x92, 0xc3, 0xde, 0x7c, 0x12, 0x39, - 0xfb, 0x6e, 0xf0, 0x8f, 0x3b, 0x90, 0x5b, 0xbc, 0x32, 0xd6, 0xbc, 0x8a, - 0xc2, 0x6a, 0x32, 0xa5, 0xe3, 0xf8, 0x30, 0x6c, 0x70, 0x18, 0x13, 0x3b, - 0x3d, 0xd1, 0x42, 0xe9, 0xa7, 0x9c, 0x84, 0x3d, 0x15, 0xfa, 0x66, 0x32, - 0x5e, 0xd0, 0xbc, 0xac, 0x74, 0xe1, 0x54, 0x9e, 0x20, 0x61, 0x4c, 0xd4, - 0xec, 0x74, 0x70, 0x89, 0x24, 0x5d, 0x66, 0x63, 0xba, 0xe5, 0x98, 0x86, - 0xbb, 0x56, 0x68, 0x9d, 0x13, 0x1f, 0x79, 0xfc, 0x61, 0x4f, 0x63, 0x48, - 0x71, 0x6b, 0x94, 0xf3, 0x16, 0x25, 0x61, 0x50, 0xf1, 0x30, 0x62, 0x4d, - 0xcd, 0x23, 0x6d, 0xc6, 0xb7, 0x89, 0xcd, 0xf3, 0x73, 0x5c, 0x27, 0xd6, - 0x38, 0x1d, 0xc6, 0x7b, 0xd8, 0x33, 0xd9, 0xff, 0xb0, 0x4d, 0x94, 0x57, - 0xb1, 0xbd, 0xb5, 0xb5, 0xac, 0x54, 0x96, 0xf1, 0xa6, 0xb8, 0x62, 0x56, - 0x5c, 0x32, 0x2b, 0x54, 0xcc, 0x32, 0x14, 0x82, 0xeb, 0x34, 0xaf, 0xa3, - 0x22, 0x7b, 0xd8, 0x87, 0xd6, 0x41, 0x70, 0xca, 0xe7, 0x75, 0x40, 0x2c, - 0xcb, 0xa8, 0x82, 0x16, 0xb9, 0x04, 0x0e, 0x69, 0x58, 0xd5, 0x5e, 0xfc, - 0x9a, 0x08, 0x26, 0xa2, 0xb9, 0x51, 0xb6, 0x40, 0x15, 0x0e, 0x93, 0xb7, - 0x0b, 0x8b, 0x2d, 0x16, 0x07, 0x51, 0xa9, 0xde, 0x49, 0xe4, 0xd9, 0x12, - 0xaa, 0x61, 0x85, 0xb3, 0xac, 0xca, 0x55, 0x28, 0x9d, 0xe5, 0xf0, 0xd4, - 0x08, 0xf1, 0xb7, 0xe2, 0x36, 0xb9, 0x58, 0x8d, 0x4b, 0x56, 0xd0, 0x42, - 0x5d, 0x5c, 0x86, 0x37, 0x10, 0x1c, 0x3c, 0x5d, 0x99, 0x89, 0x20, 0x02, - 0x10, 0x68, 0xa9, 0xc7, 0xe5, 0x32, 0xf4, 0x1b, 0x75, 0xb8, 0xd6, 0x3b, - 0xfd, 0x4e, 0x54, 0x88, 0x2b, 0xc2, 0x23, 0xc2, 0x70, 0x33, 0xb1, 0x4b, - 0x85, 0x6a, 0x5c, 0x56, 0x88, 0x4b, 0x10, 0x37, 0xb9, 0x14, 0x97, 0x16, - 0x11, 0x3f, 0xcf, 0x22, 0x76, 0xaf, 0x25, 0xb9, 0x5c, 0x4d, 0x2e, 0xbb, - 0x65, 0x17, 0x08, 0xa4, 0x1d, 0xf7, 0xd2, 0x85, 0x2e, 0xff, 0x0e, 0x7a, - 0x5f, 0xe8, 0x6c, 0xa7, 0xff, 0xc8, 0x10, 0xbd, 0x56, 0x8d, 0x5d, 0xf6, - 0x25, 0xb1, 0x94, 0xd0, 0x47, 0x68, 0x29, 0x42, 0x8d, 0x2c, 0xa2, 0xea, - 0xe7, 0xa8, 0xa2, 0xb9, 0x28, 0x2d, 0x4a, 0x93, 0xd9, 0xd9, 0x21, 0xa6, - 0xa6, 0x59, 0xe2, 0xb6, 0x95, 0xe7, 0xc5, 0xf0, 0x26, 0x51, 0xe4, 0x46, - 0xad, 0x0d, 0x81, 0x92, 0x0d, 0x51, 0x39, 0x71, 0xb2, 0x60, 0xee, 0x10, - 0x06, 0x84, 0x7b, 0xa8, 0x77, 0xb8, 0x34, 0x83, 0x7d, 0x90, 0x52, 0x49, - 0x95, 0x38, 0x0c, 0xc3, 0xe1, 0x82, 0x78, 0x4b, 0xc8, 0x38, 0x9f, 0x6a, - 0xaa, 0x01, 0x67, 0xe8, 0xf1, 0x31, 0x51, 0x8e, 0xa9, 0x8e, 0x0c, 0xd6, - 0x56, 0x39, 0x4d, 0x84, 0xea, 0x9c, 0x53, 0x92, 0xf8, 0x80, 0xcb, 0x21, - 0x98, 0x99, 0x48, 0x93, 0xc0, 0x53, 0x9d, 0xc2, 0x88, 0x2b, 0x48, 0xa3, - 0xc9, 0x91, 0x88, 0x0c, 0x16, 0x4e, 0x62, 0x91, 0x18, 0xa1, 0x9c, 0x95, - 0x4e, 0x4d, 0x2c, 0x56, 0x40, 0xa8, 0xcb, 0x1b, 0x76, 0x2a, 0x60, 0xd4, - 0xf2, 0x86, 0xa6, 0x5a, 0x3e, 0xfc, 0xf0, 0x41, 0xe6, 0x1e, 0x8e, 0x34, - 0x65, 0xeb, 0x37, 0xb0, 0x6e, 0x5d, 0x51, 0x6b, 0x39, 0x76, 0x58, 0x7a, - 0x81, 0x4a, 0x5b, 0xd3, 0xde, 0xd3, 0xed, 0xcb, 0x6b, 0x5b, 0x1b, 0xfc, - 0xba, 0x65, 0x20, 0x19, 0xe6, 0x8d, 0x4c, 0x45, 0xe4, 0x45, 0xda, 0x33, - 0xd8, 0x2e, 0x81, 0x8e, 0x8d, 0xfc, 0x42, 0xd4, 0x6a, 0x94, 0x3b, 0x49, - 0x86, 0xad, 0xc6, 0x6e, 0xe8, 0xf9, 0x1d, 0x72, 0xb2, 0x51, 0x0e, 0x72, - 0x12, 0x99, 0x80, 0x71, 0x61, 0xbd, 0x8b, 0xa4, 0x60, 0xd0, 0x58, 0x46, - 0x53, 0xe7, 0x72, 0x4e, 0x1c, 0xd6, 0xc7, 0xf0, 0x0d, 0xbc, 0x18, 0xb4, - 0x6a, 0xc4, 0xad, 0xa3, 0x64, 0x49, 0xc2, 0xa4, 0xc9, 0x0c, 0xd9, 0x12, - 0x5a, 0xee, 0x21, 0x6d, 0xf5, 0x68, 0x33, 0x16, 0xb0, 0x45, 0x28, 0xcd, - 0x22, 0xab, 0x2f, 0x8b, 0xa1, 0xd9, 0x2c, 0x78, 0x9f, 0xe1, 0x1e, 0x18, - 0x69, 0x57, 0x52, 0x2e, 0x9a, 0x4c, 0x76, 0xc5, 0x00, 0x28, 0x84, 0x8d, - 0xe8, 0x54, 0xd8, 0xc6, 0xd2, 0xa3, 0x7a, 0xd5, 0x9c, 0x82, 0xb1, 0x29, - 0xb7, 0x34, 0xde, 0x1d, 0xcc, 0xe1, 0xab, 0xc6, 0xec, 0xa3, 0xa2, 0xb0, - 0x36, 0xac, 0x6b, 0x2a, 0x59, 0xd3, 0x04, 0x7d, 0x81, 0xe4, 0xd6, 0x56, - 0xe5, 0x43, 0x2b, 0xad, 0x8e, 0x51, 0xc2, 0x59, 0x6f, 0xd0, 0xf4, 0xc3, - 0xad, 0x6d, 0x1a, 0xde, 0xc3, 0xad, 0x2f, 0x37, 0xda, 0xe2, 0x40, 0xc9, - 0x20, 0xd2, 0xee, 0xb9, 0x6c, 0x38, 0x2d, 0x17, 0xbd, 0x96, 0x4d, 0xa7, - 0x0e, 0xb6, 0x75, 0x3b, 0x2f, 0xa1, 0xde, 0xee, 0x48, 0x6e, 0x09, 0x16, - 0xf6, 0xb6, 0xcc, 0x16, 0x8d, 0xf1, 0x8e, 0x76, 0x4c, 0xd2, 0x41, 0x42, - 0x31, 0x90, 0x85, 0x2d, 0x95, 0x78, 0x51, 0xfc, 0x90, 0x09, 0x53, 0xef, - 0xda, 0xf0, 0x91, 0x48, 0xd3, 0x38, 0x42, 0x7c, 0x1a, 0x4b, 0x3a, 0x06, - 0x8c, 0x4c, 0x14, 0x4d, 0x19, 0x2a, 0x1f, 0xf5, 0x5b, 0xf5, 0x7f, 0x10, - 0xbd, 0xf5, 0xdb, 0x2a, 0xdf, 0xaa, 0x42, 0x3c, 0x2c, 0xda, 0xec, 0xae, - 0x0d, 0x1b, 0x90, 0x64, 0xc1, 0x58, 0x4c, 0xad, 0x0b, 0xad, 0x66, 0x85, - 0x90, 0x50, 0x9b, 0x32, 0x90, 0xae, 0x34, 0xb1, 0xf4, 0xed, 0x9b, 0x97, - 0x5d, 0xba, 0x42, 0xcf, 0xd1, 0xa1, 0x9d, 0xd1, 0x31, 0xb3, 0x53, 0x66, - 0x0d, 0x31, 0xce, 0x5a, 0xa5, 0x06, 0x17, 0xf1, 0xd6, 0x97, 0x99, 0xc0, - 0x38, 0xa1, 0x43, 0x15, 0x8d, 0xbb, 0x9a, 0xae, 0x6a, 0x21, 0x01, 0x8c, - 0xb4, 0x06, 0x5f, 0xad, 0x59, 0x8d, 0x05, 0x22, 0x5a, 0x5a, 0x81, 0x72, - 0x42, 0xfa, 0x20, 0x55, 0xb4, 0x0a, 0xfc, 0x59, 0xa0, 0xaf, 0x89, 0x11, - 0xf4, 0x93, 0x43, 0x02, 0x04, 0x90, 0xf3, 0xea, 0xc1, 0x81, 0x3a, 0x97, - 0x39, 0x08, 0x43, 0xd3, 0x0e, 0x29, 0x40, 0x41, 0xf6, 0x76, 0x87, 0x22, - 0xc4, 0x9d, 0x9b, 0xd2, 0x60, 0x55, 0x56, 0x1a, 0x00, 0xc5, 0x4d, 0x06, - 0xe4, 0x90, 0xab, 0x0b, 0x2b, 0xe1, 0x1b, 0x40, 0x1a, 0x82, 0xdf, 0x18, - 0xd9, 0x18, 0x71, 0xe9, 0x6e, 0x54, 0x28, 0xcd, 0x22, 0x35, 0xd2, 0x09, - 0x46, 0x88, 0xd2, 0x9f, 0xb4, 0x3e, 0x56, 0xa1, 0x4b, 0x6e, 0x05, 0xae, - 0x38, 0x15, 0x4a, 0x7a, 0x3b, 0x4b, 0x9e, 0x72, 0x8b, 0xeb, 0xf4, 0x86, - 0x50, 0x7f, 0x7d, 0xed, 0x30, 0x5b, 0x8e, 0x0b, 0xa1, 0xd2, 0xf9, 0xd4, - 0x48, 0x0a, 0xd7, 0x03, 0x18, 0x3b, 0xee, 0x3a, 0xb6, 0x65, 0x51, 0xc2, - 0x8b, 0xe7, 0xc2, 0xc2, 0xe6, 0xa5, 0xf8, 0x35, 0x93, 0xb0, 0xe6, 0x3a, - 0x92, 0x51, 0xad, 0x72, 0xa4, 0x86, 0x0a, 0x51, 0xb8, 0x62, 0xb1, 0x58, - 0x90, 0x1a, 0x7a, 0xf8, 0xbe, 0x5a, 0xd3, 0x34, 0x3f, 0x09, 0x21, 0x90, - 0x8b, 0xe2, 0x2f, 0x18, 0x50, 0x4e, 0x00, 0x15, 0x02, 0x8f, 0xcc, 0x73, - 0xad, 0xaf, 0x0b, 0x7f, 0x5f, 0xc0, 0x02, 0x5e, 0xb2, 0xdb, 0x8e, 0x78, - 0x62, 0x66, 0x0c, 0x25, 0x70, 0xc9, 0x8b, 0x71, 0x71, 0x8e, 0xd2, 0x1b, - 0x11, 0x97, 0x14, 0x8c, 0x29, 0xc9, 0x99, 0x1f, 0xc4, 0xb4, 0x94, 0xe0, - 0x97, 0x61, 0x09, 0xd8, 0xb3, 0xb0, 0xc4, 0xdf, 0xe6, 0x5b, 0xb2, 0x45, - 0xb0, 0x98, 0xf7, 0xf3, 0xac, 0x59, 0x9d, 0x02, 0xcf, 0x8b, 0xf9, 0xc0, - 0x71, 0x33, 0xa5, 0xf5, 0x28, 0x86, 0x23, 0x1c, 0xff, 0xa4, 0x8d, 0x0b, - 0x7e, 0x7c, 0x94, 0x75, 0xc4, 0x62, 0xee, 0xe0, 0x84, 0xd2, 0x71, 0x9b, - 0x3f, 0x41, 0x3f, 0x83, 0x05, 0x57, 0x17, 0x5d, 0x0b, 0x5c, 0xb1, 0xf2, - 0xaa, 0x05, 0x7e, 0x18, 0x71, 0x37, 0xfb, 0x38, 0x12, 0xb3, 0xde, 0x30, - 0xaa, 0x6c, 0x7c, 0x66, 0x14, 0x15, 0x8b, 0x19, 0xc6, 0x35, 0xdf, 0x68, - 0x56, 0x2c, 0xac, 0xe5, 0x86, 0xc6, 0x8d, 0x41, 0x91, 0x09, 0xde, 0x17, - 0x61, 0x09, 0x43, 0x9a, 0xdb, 0xe4, 0x24, 0x53, 0x2c, 0xa5, 0x0f, 0x3a, - 0x80, 0x56, 0x89, 0x40, 0x65, 0x25, 0x92, 0xad, 0x45, 0x56, 0xe2, 0x00, - 0x02, 0x7f, 0xb8, 0x09, 0xc7, 0x50, 0xbf, 0x4f, 0xbc, 0xac, 0x24, 0x53, - 0x5b, 0x10, 0x98, 0x4c, 0x5e, 0x32, 0x51, 0x89, 0x24, 0xa5, 0x18, 0xe7, - 0x50, 0x61, 0x39, 0x03, 0x5a, 0x3e, 0x72, 0x5e, 0x91, 0x29, 0xf1, 0x34, - 0xb2, 0x4d, 0x22, 0xad, 0x0d, 0xef, 0x00, 0x9d, 0x1a, 0xd4, 0x3e, 0x41, - 0xbb, 0xd1, 0x42, 0xaa, 0xe0, 0x13, 0x51, 0xaf, 0x66, 0xa0, 0xd4, 0x18, - 0x3b, 0x4f, 0x09, 0x1b, 0x2e, 0x39, 0x55, 0x36, 0x50, 0xcb, 0x4c, 0x61, - 0xd4, 0x08, 0x8b, 0x5d, 0x74, 0x82, 0x46, 0x45, 0xe9, 0xcc, 0x3e, 0x04, - 0xd6, 0x97, 0x97, 0x30, 0x73, 0x98, 0xf4, 0x94, 0x50, 0xf9, 0x34, 0xb1, - 0x06, 0x25, 0xf2, 0x8a, 0x5d, 0x7c, 0x1e, 0x93, 0x61, 0xd9, 0x65, 0xef, - 0x2e, 0xc5, 0x25, 0x79, 0xae, 0xcd, 0x80, 0x8e, 0x3b, 0x93, 0x3e, 0x16, - 0x88, 0xef, 0x2e, 0xba, 0x0f, 0x43, 0x58, 0x59, 0x16, 0x08, 0xc2, 0x40, - 0x33, 0xcb, 0x95, 0xdb, 0xec, 0x3b, 0x3d, 0x5b, 0x23, 0x3c, 0xee, 0x3c, - 0x30, 0x4d, 0x51, 0x60, 0x5c, 0x65, 0x3d, 0x82, 0x93, 0xf2, 0x66, 0x5d, - 0xb4, 0x5a, 0xd1, 0x57, 0x82, 0x34, 0xa5, 0x08, 0xb7, 0xb8, 0xd6, 0xe4, - 0x17, 0xb2, 0x92, 0xc5, 0x7d, 0x90, 0x1e, 0xc2, 0x73, 0xce, 0x30, 0x42, - 0x49, 0x3a, 0x72, 0x9a, 0x52, 0x7e, 0x89, 0x21, 0x57, 0xf9, 0xd1, 0x2a, - 0x09, 0xd6, 0x40, 0x57, 0x9b, 0x56, 0x31, 0x93, 0x1c, 0xb7, 0xa4, 0x20, - 0x88, 0x1b, 0xed, 0xdd, 0x38, 0xf8, 0xf3, 0x7c, 0x9a, 0x57, 0x97, 0x88, - 0xf5, 0x88, 0xd9, 0x47, 0x17, 0x59, 0x57, 0x80, 0x01, 0x85, 0x2c, 0x40, - 0xf5, 0x85, 0x0b, 0x8d, 0x8a, 0xaf, 0xe5, 0x33, 0x55, 0x1c, 0xb8, 0xaa, - 0x35, 0x02, 0xc3, 0xf0, 0x23, 0x54, 0x68, 0x35, 0x4c, 0xc5, 0xef, 0x42, - 0x33, 0x1b, 0xb2, 0x72, 0xe1, 0x74, 0x2d, 0xf1, 0x74, 0x56, 0xa4, 0xfd, - 0xd4, 0x85, 0x0f, 0x9d, 0x11, 0xdc, 0x2c, 0xc6, 0xe3, 0xad, 0xe3, 0x86, - 0x1e, 0x9f, 0xe2, 0x2e, 0x11, 0xdf, 0x40, 0x5b, 0x51, 0xc9, 0xc1, 0x7f, - 0xf0, 0xe9, 0xcf, 0x68, 0x5d, 0xe8, 0x7f, 0x65, 0x5f, 0x6c, 0x24, 0x1a, - 0x7d, 0xb7, 0x90, 0x32, 0x13, 0x6f, 0xd9, 0x0a, 0x11, 0x4a, 0x4a, 0xd1, - 0x3e, 0x2b, 0x6b, 0x09, 0x13, 0xb7, 0x66, 0xef, 0xa2, 0xe6, 0xd0, 0xff, - 0x4a, 0x9a, 0x70, 0x3d, 0x98, 0xc1, 0x4b, 0x68, 0xb5, 0xa0, 0xf4, 0x30, - 0x22, 0xbc, 0xe7, 0x5d, 0x01, 0xb1, 0x63, 0x9f, 0x82, 0xc2, 0xad, 0x44, - 0xd1, 0x12, 0x08, 0x15, 0x9e, 0x1c, 0xbd, 0xda, 0x47, 0xfd, 0x58, 0x0c, - 0xce, 0xf4, 0xb9, 0xc5, 0x4a, 0x8c, 0x52, 0x90, 0x18, 0x40, 0xe6, 0xc8, - 0x60, 0x15, 0x18, 0x31, 0x53, 0x70, 0x60, 0x7b, 0x5a, 0xba, 0x8b, 0x7a, - 0x20, 0xa9, 0x9d, 0x18, 0x8e, 0x47, 0x8c, 0x65, 0x40, 0x58, 0x91, 0xfe, - 0x04, 0x10, 0x36, 0x46, 0x84, 0x5d, 0x84, 0x82, 0x25, 0x04, 0x5b, 0xab, - 0xd9, 0x18, 0x81, 0xbe, 0x7a, 0x2c, 0x2e, 0x8b, 0x1c, 0x83, 0x25, 0xda, - 0x24, 0x68, 0x31, 0x7c, 0x63, 0x09, 0x06, 0xf4, 0xce, 0xee, 0x93, 0x27, - 0xde, 0xac, 0x4d, 0xb3, 0x66, 0xd1, 0x01, 0xe7, 0x9e, 0x78, 0xf0, 0x7b, - 0x11, 0x09, 0xd1, 0x76, 0x56, 0x54, 0x19, 0x67, 0xf6, 0x58, 0x4f, 0x38, - 0x5e, 0x95, 0x79, 0xe4, 0x4c, 0x90, 0x29, 0x13, 0x89, 0x70, 0x92, 0xc7, - 0x12, 0x86, 0x26, 0xfe, 0x32, 0x56, 0xa0, 0x14, 0x57, 0x15, 0x1c, 0x2d, - 0x06, 0xe7, 0xcf, 0xea, 0x01, 0x21, 0xb7, 0x72, 0xba, 0x29, 0xcd, 0x71, - 0x4d, 0x36, 0x69, 0xcd, 0x61, 0x16, 0xb1, 0x14, 0x92, 0x4a, 0xd8, 0x03, - 0x16, 0x22, 0xcb, 0x3f, 0xc4, 0xf5, 0xf4, 0x88, 0xc2, 0xe0, 0x42, 0xf8, - 0x8e, 0xa0, 0x59, 0x18, 0x0d, 0x96, 0xa0, 0x01, 0x2f, 0x14, 0xa6, 0xc0, - 0x83, 0xea, 0x50, 0xa3, 0xbe, 0xf2, 0xd8, 0x2d, 0x8d, 0xb2, 0x91, 0x96, - 0x60, 0x7d, 0xb8, 0xa1, 0xa7, 0x1c, 0xef, 0x3e, 0xcc, 0x81, 0xe4, 0xe1, - 0xa8, 0x0e, 0x30, 0x84, 0xb2, 0xbe, 0xc6, 0x70, 0xdb, 0xef, 0x68, 0x41, - 0x9f, 0x6a, 0x69, 0x16, 0x41, 0x8a, 0xfa, 0x4e, 0x6e, 0x20, 0xc5, 0x1c, - 0xb5, 0x11, 0x81, 0x36, 0x02, 0x82, 0x54, 0x40, 0x07, 0x62, 0x24, 0xd6, - 0x34, 0x3c, 0xc9, 0xeb, 0x46, 0x02, 0xa8, 0xa4, 0x9c, 0x42, 0xe3, 0xda, - 0x18, 0x19, 0x35, 0x34, 0x5a, 0x07, 0x7d, 0xca, 0xd8, 0xb7, 0x4e, 0xd9, - 0xcf, 0xb6, 0x12, 0x47, 0x0a, 0xba, 0x2a, 0xd0, 0x0e, 0xc2, 0x4f, 0xcb, - 0xec, 0x7d, 0xb5, 0x9e, 0x37, 0x5c, 0x08, 0x88, 0x97, 0x28, 0x54, 0x2f, - 0xf4, 0x91, 0x71, 0xa9, 0x39, 0x59, 0xa4, 0xb8, 0xbd, 0xfa, 0x34, 0x24, - 0xa0, 0xa7, 0x09, 0xfb, 0xc7, 0x14, 0x7e, 0x51, 0x64, 0x3c, 0x08, 0x36, - 0x28, 0xf0, 0x32, 0xc1, 0x54, 0xd0, 0x4a, 0x41, 0x35, 0x6c, 0xcd, 0xf6, - 0xc8, 0x1d, 0x46, 0xa8, 0x1d, 0xdd, 0xd8, 0xbc, 0x20, 0xd1, 0xfa, 0xe7, - 0x73, 0x5a, 0x7d, 0xf6, 0xf0, 0x26, 0x5a, 0x91, 0x4a, 0x32, 0xe7, 0xcf, - 0x6f, 0x12, 0x8b, 0x4e, 0xd5, 0x4c, 0x05, 0x51, 0xaf, 0xc8, 0x86, 0x5a, - 0xe5, 0x7f, 0xcf, 0x24, 0xdc, 0x80, 0x8c, 0xb8, 0xa9, 0x85, 0x29, 0xa0, - 0x1c, 0x86, 0x0c, 0x31, 0x79, 0x06, 0xd4, 0xc0, 0x25, 0xc8, 0x99, 0x04, - 0x55, 0x5f, 0x8b, 0x30, 0x64, 0x05, 0x3e, 0x96, 0xac, 0x0f, 0x65, 0x76, - 0x31, 0x47, 0x50, 0x31, 0x01, 0x26, 0xb2, 0xda, 0xdb, 0xe1, 0xa9, 0x59, - 0x3e, 0x73, 0x20, 0xa6, 0xa2, 0x87, 0x6c, 0x04, 0x79, 0x1e, 0xb8, 0xc3, - 0x6f, 0x52, 0x30, 0x5e, 0xe7, 0xc7, 0x35, 0xd0, 0x45, 0xbc, 0x77, 0x4a, - 0x19, 0xfe, 0x4c, 0xbd, 0xf2, 0x35, 0xc9, 0x19, 0x0f, 0x1e, 0xd9, 0xf3, - 0xd7, 0x49, 0x14, 0x23, 0x48, 0xb7, 0x0f, 0xcd, 0x58, 0x42, 0xeb, 0xa8, - 0xa6, 0x96, 0x41, 0x08, 0x04, 0x7f, 0xa4, 0xe9, 0x53, 0x7c, 0x73, 0x76, - 0xb9, 0x08, 0x9d, 0xa2, 0xdb, 0xb2, 0xd7, 0x00, 0x26, 0x44, 0x48, 0xc1, - 0x15, 0xae, 0x31, 0xb1, 0x49, 0x1a, 0x1e, 0x63, 0xe3, 0x5b, 0x14, 0xd5, - 0x0d, 0xf1, 0x94, 0x85, 0x92, 0xe1, 0x15, 0x45, 0xbd, 0x00, 0x3d, 0x4d, - 0xb4, 0x5a, 0x58, 0x43, 0x72, 0xed, 0xca, 0x4d, 0xbe, 0x06, 0xcc, 0x08, - 0xd7, 0x71, 0x2d, 0xae, 0x83, 0x49, 0x67, 0x52, 0x35, 0x49, 0x62, 0xba, - 0x3d, 0xa6, 0xe5, 0x50, 0x16, 0x2d, 0xd4, 0xdd, 0xa0, 0xb2, 0xdc, 0x65, - 0x0a, 0x1c, 0xe9, 0xb7, 0xd9, 0x45, 0x12, 0x37, 0x44, 0x25, 0x22, 0x5d, - 0xad, 0xee, 0xe7, 0x89, 0x74, 0xf8, 0xcd, 0x77, 0xd1, 0x5b, 0x6d, 0xe5, - 0xc4, 0xa5, 0x24, 0xc4, 0xe0, 0x22, 0x6f, 0x9d, 0x1e, 0x87, 0x71, 0x1a, - 0x1c, 0x4a, 0x75, 0x59, 0x20, 0xf7, 0xc0, 0xd5, 0xc7, 0x43, 0x7e, 0x5d, - 0x24, 0xee, 0x0c, 0x56, 0xaa, 0x30, 0x7a, 0x64, 0xf2, 0x68, 0x58, 0x5c, - 0x7a, 0xae, 0xb8, 0x9c, 0xe2, 0x1f, 0xd8, 0x16, 0xb6, 0xf4, 0xcd, 0xf6, - 0xf6, 0x4a, 0x85, 0xce, 0xc3, 0x78, 0x90, 0x4d, 0xdf, 0xb0, 0x6b, 0xc8, - 0x71, 0x00, 0x8d, 0x27, 0xa3, 0x6e, 0xfb, 0x9c, 0x0c, 0x4a, 0x57, 0xb6, - 0xd5, 0x8f, 0xa5, 0x12, 0x9f, 0xee, 0x15, 0xc6, 0x73, 0x68, 0x65, 0x2f, - 0xb9, 0xf1, 0x53, 0x36, 0xc7, 0xe3, 0x6a, 0x46, 0x53, 0xe9, 0xa0, 0x4b, - 0xe7, 0xe6, 0x9b, 0xa7, 0x97, 0xf3, 0x0b, 0x2a, 0xbc, 0x87, 0x9e, 0x9d, - 0xce, 0x6d, 0xf3, 0x40, 0x3d, 0x99, 0xd4, 0x64, 0x36, 0x34, 0xc6, 0xe5, - 0xae, 0x19, 0x60, 0x29, 0xbe, 0x0e, 0xcd, 0xf9, 0x7f, 0x1e, 0xd7, 0x7a, - 0xe9, 0x20, 0xdc, 0xe5, 0x37, 0x9d, 0x2e, 0x2f, 0x80, 0x00, 0x8d, 0x2a, - 0x06, 0x60, 0x5d, 0xc4, 0xa3, 0xbc, 0xce, 0xce, 0xbf, 0xf9, 0x0e, 0x2d, - 0x17, 0x1f, 0xfa, 0x97, 0xf5, 0x64, 0xfc, 0x35, 0xbd, 0x8b, 0x2b, 0xb0, - 0x89, 0x7f, 0x76, 0x92, 0x45, 0x11, 0x04, 0x0e, 0xb4, 0x6f, 0xc0, 0x21, - 0x66, 0xbb, 0x97, 0x47, 0x45, 0xd1, 0xf6, 0x6e, 0x3c, 0x47, 0x97, 0x86, - 0xaf, 0x90, 0xc7, 0x54, 0x1c, 0x8a, 0x22, 0x8c, 0x78, 0xcf, 0x28, 0x6c, - 0x28, 0xba, 0x1d, 0xdc, 0x2d, 0x49, 0xae, 0x6f, 0xb6, 0x27, 0x2b, 0x07, - 0xfe, 0xa6, 0xcb, 0xb8, 0xd3, 0x78, 0xa3, 0xc7, 0x13, 0x65, 0x72, 0xb7, - 0x8a, 0x2c, 0x5f, 0xdb, 0x1b, 0xf8, 0x03, 0x0e, 0x08, 0x5c, 0x45, 0x6d, - 0x23, 0x46, 0x2f, 0x89, 0x3e, 0xba, 0x49, 0x21, 0x2e, 0xea, 0xe9, 0x86, - 0x9b, 0xbb, 0xbb, 0xc6, 0x61, 0x5a, 0x6b, 0x5f, 0xaf, 0x89, 0x8a, 0x69, - 0x89, 0xbb, 0xc9, 0xdf, 0xe6, 0x45, 0xed, 0x8b, 0x4b, 0x0c, 0x8b, 0x39, - 0xa6, 0x9c, 0xd3, 0xc7, 0x8c, 0x36, 0xde, 0x36, 0xbe, 0x5f, 0x3a, 0x34, - 0xc2, 0x2e, 0xfe, 0xf5, 0x4b, 0x27, 0x0c, 0xf2, 0x17, 0x5a, 0xe7, 0xaf, - 0xf3, 0xe9, 0xd7, 0x38, 0xd0, 0x5f, 0x3a, 0x77, 0x6f, 0xcc, 0x1a, 0x37, - 0xe8, 0xda, 0x73, 0xcd, 0x45, 0xad, 0x75, 0xd6, 0x5a, 0x1a, 0x73, 0x60, - 0x7b, 0x14, 0x96, 0xdc, 0x5c, 0x05, 0xe4, 0x2f, 0x61, 0x8a, 0x8d, 0xe9, - 0x75, 0x5d, 0x0d, 0x5e, 0xff, 0x05, 0x2e, 0x16, 0x8a, 0xe0, 0xd5, 0x38, - 0xad, 0x2e, 0x59, 0xe7, 0xca, 0xa7, 0x8d, 0x3a, 0xc1, 0x1a, 0x50, 0x9e, - 0x51, 0x31, 0x42, 0xb7, 0x80, 0xf6, 0xa2, 0xf2, 0xd9, 0x3f, 0x43, 0x93, - 0x1c, 0x8d, 0x4a, 0xe8, 0x31, 0x74, 0x6a, 0x50, 0x6a, 0xd2, 0x64, 0xea, - 0xba, 0xe0, 0x9b, 0x8a, 0xa8, 0x47, 0xd0, 0xb0, 0x47, 0xbc, 0x4d, 0x71, - 0xb4, 0x42, 0x95, 0x4d, 0x72, 0x4a, 0x96, 0x83, 0x81, 0x8f, 0x33, 0x12, - 0xdc, 0x36, 0x91, 0x29, 0x12, 0xce, 0x42, 0x35, 0x4b, 0x51, 0x47, 0x46, - 0x25, 0x82, 0xbf, 0x92, 0x19, 0xf1, 0xec, 0x63, 0x22, 0x5b, 0xc3, 0x56, - 0xca, 0xea, 0x9b, 0x0e, 0x5c, 0xd4, 0x5f, 0xa3, 0x15, 0x23, 0x9b, 0x7e, - 0x9d, 0x9c, 0x8f, 0xe7, 0xb0, 0xf4, 0xe1, 0x68, 0x7c, 0xe8, 0x4d, 0x6e, - 0x60, 0x8c, 0x6b, 0xb7, 0x1c, 0x8f, 0x74, 0x38, 0xd4, 0x50, 0x0e, 0x0d, - 0x46, 0x16, 0xe6, 0xc5, 0xa7, 0xc2, 0x11, 0xbe, 0x7c, 0x2f, 0x74, 0x1f, - 0x33, 0x20, 0x92, 0xbe, 0xbf, 0x39, 0xfe, 0xd3, 0xd7, 0xfa, 0xd0, 0x2f, - 0x9d, 0x9f, 0x7b, 0xfc, 0x29, 0x41, 0xe2, 0xee, 0x25, 0xc7, 0x7f, 0x5a, - 0x85, 0x94, 0x5a, 0x5a, 0xfa, 0x8e, 0x7f, 0x21, 0xb2, 0x4a, 0xda, 0x34, - 0xee, 0xcc, 0x46, 0x96, 0x24, 0xef, 0xb3, 0x1b, 0xc2, 0xa4, 0xa2, 0xc0, - 0x1f, 0x0c, 0xf1, 0x45, 0xfc, 0xe3, 0xc2, 0xe2, 0x49, 0xa8, 0x96, 0x00, - 0x8b, 0x27, 0xe7, 0x08, 0x73, 0x4e, 0xf6, 0x3f, 0xe5, 0xc9, 0x54, 0xc5, - 0xef, 0x6f, 0xb2, 0xd3, 0xb4, 0xb7, 0x37, 0x02, 0x44, 0xdf, 0x8c, 0xd3, - 0x46, 0x19, 0x21, 0x16, 0x71, 0x93, 0x43, 0xf4, 0xef, 0x87, 0x8a, 0x04, - 0x6c, 0x10, 0xe5, 0xdf, 0xe8, 0xce, 0xa7, 0x36, 0x49, 0xe8, 0x5d, 0xfb, - 0xc3, 0x9a, 0x46, 0x48, 0x4f, 0x26, 0xc4, 0xe4, 0xc9, 0x2f, 0xc5, 0xd5, - 0x45, 0xbe, 0xf6, 0x16, 0x40, 0x71, 0x4f, 0x0b, 0xa4, 0xc8, 0xa8, 0x18, - 0x4b, 0x09, 0x19, 0x20, 0x14, 0xd0, 0x69, 0xa9, 0x49, 0x15, 0x8f, 0xe9, - 0xfe, 0xc3, 0x99, 0x0b, 0xc8, 0xbd, 0xf6, 0x19, 0xcb, 0xe7, 0xf9, 0x94, - 0xeb, 0x10, 0xba, 0x30, 0x19, 0xca, 0x4b, 0x06, 0xb2, 0xfb, 0x1a, 0x74, - 0xb0, 0xf3, 0x8c, 0x6c, 0x11, 0x8a, 0xf9, 0xdc, 0x0b, 0x90, 0xcf, 0x9a, - 0x48, 0xd2, 0x24, 0x55, 0x8a, 0xdd, 0x16, 0xe8, 0xfc, 0x7e, 0xf2, 0x82, - 0x4c, 0x05, 0x6c, 0x3d, 0xd2, 0x08, 0x7d, 0x12, 0x6c, 0x35, 0x2c, 0x28, - 0xd4, 0x7b, 0xd3, 0x0b, 0x8e, 0x68, 0xfa, 0x0f, 0xa2, 0xb0, 0xe3, 0xe1, - 0x51, 0x64, 0x52, 0x9c, 0x8f, 0xac, 0x3a, 0x68, 0xbe, 0x0f, 0x7e, 0x96, - 0x40, 0xe6, 0xde, 0xf6, 0x9e, 0xd4, 0x2e, 0xaf, 0xac, 0x5d, 0x6d, 0xc2, - 0x03, 0xab, 0x86, 0x98, 0x6c, 0x5e, 0xb6, 0xa8, 0x8d, 0x1d, 0x6b, 0x03, - 0x3e, 0x35, 0x8f, 0xb5, 0x35, 0x26, 0x6e, 0x3a, 0xcd, 0xc4, 0x53, 0x23, - 0x47, 0x50, 0xd3, 0x26, 0xe4, 0x7d, 0x62, 0x05, 0x4d, 0x5c, 0xd4, 0x02, - 0x8d, 0xca, 0xf8, 0x92, 0x35, 0x65, 0xd0, 0x5a, 0x54, 0x11, 0x8f, 0xca, - 0x30, 0x5e, 0x7b, 0x7c, 0xeb, 0x28, 0x8e, 0x72, 0x31, 0xc1, 0xc8, 0xfb, - 0xe1, 0x9e, 0xf8, 0x02, 0x09, 0x06, 0x93, 0x20, 0x30, 0x45, 0xac, 0x12, - 0xc1, 0x3b, 0x54, 0x1e, 0xb0, 0x2a, 0xaf, 0x51, 0xc5, 0x7a, 0x6b, 0x1c, - 0xf8, 0x0e, 0x31, 0x20, 0xb1, 0xd1, 0x30, 0xc9, 0xad, 0xaf, 0xa9, 0xea, - 0x89, 0x4d, 0xa7, 0xec, 0xe9, 0x65, 0x03, 0x40, 0x8a, 0xc0, 0x9e, 0x4e, - 0x09, 0xdd, 0x33, 0x67, 0x6f, 0xa0, 0x3b, 0x07, 0x91, 0xab, 0x3a, 0x0c, - 0xe1, 0x5c, 0xc7, 0xa0, 0xb8, 0x36, 0x84, 0xd4, 0xad, 0x95, 0x34, 0xc2, - 0x2a, 0x42, 0xc8, 0x51, 0x4e, 0x93, 0xb5, 0x6f, 0x36, 0xd6, 0x42, 0x45, - 0xb5, 0xa6, 0x80, 0x15, 0xc3, 0xe4, 0xaa, 0xb3, 0xc2, 0x12, 0x3d, 0x49, - 0xc5, 0x9e, 0x60, 0x00, 0x49, 0x46, 0x9b, 0xc1, 0x4e, 0xd9, 0x2a, 0x50, - 0x3c, 0x57, 0x90, 0xc9, 0xa7, 0x44, 0xe8, 0x8c, 0xdb, 0xca, 0x34, 0xe5, - 0xad, 0x9a, 0x5c, 0x67, 0xab, 0xda, 0xf3, 0xc2, 0x18, 0x1d, 0x1f, 0xb4, - 0xd8, 0x8a, 0xbd, 0xe5, 0xa8, 0x56, 0x5d, 0xb2, 0x0a, 0x22, 0x5e, 0x43, - 0xfe, 0x5a, 0xfb, 0x66, 0x9d, 0x99, 0x6e, 0xb0, 0x19, 0xb8, 0x6e, 0xd6, - 0x92, 0x5f, 0x90, 0xcc, 0xd8, 0x68, 0x02, 0xcf, 0xba, 0xce, 0x84, 0x86, - 0x9a, 0x4f, 0x24, 0x4f, 0xd1, 0xca, 0xf8, 0x2d, 0xd9, 0x8d, 0xe5, 0x91, - 0xa7, 0x9b, 0xf4, 0x51, 0x43, 0x66, 0x6a, 0xbe, 0x08, 0x2b, 0x4a, 0xff, - 0x7e, 0x87, 0x4f, 0xa8, 0x24, 0xb8, 0x96, 0xf4, 0xfb, 0xa0, 0x03, 0x56, - 0x93, 0x26, 0x5a, 0x8d, 0xe2, 0xfc, 0xd0, 0x75, 0x65, 0xb0, 0xde, 0x1a, - 0xb5, 0x2d, 0x35, 0x29, 0xcc, 0x11, 0x24, 0xb6, 0x12, 0xfe, 0xba, 0xfc, - 0x06, 0x13, 0xd1, 0xf6, 0x35, 0xa8, 0x52, 0x83, 0x2e, 0x19, 0xa4, 0x99, - 0xd9, 0x82, 0xd8, 0x22, 0x70, 0x39, 0x9f, 0x9c, 0xe7, 0x12, 0xf7, 0xcd, - 0x15, 0x35, 0x28, 0xdc, 0x2a, 0x1b, 0x57, 0x52, 0xe0, 0x05, 0xef, 0x20, - 0x31, 0x0e, 0xba, 0xda, 0x11, 0x68, 0xb3, 0x67, 0x83, 0x99, 0x49, 0xa2, - 0x32, 0x96, 0xde, 0xa1, 0x74, 0x94, 0x58, 0xac, 0x56, 0xf2, 0x25, 0x76, - 0x61, 0x08, 0xc2, 0xea, 0x16, 0x95, 0xba, 0x62, 0xc9, 0x93, 0x1e, 0x7e, - 0x6d, 0x47, 0xa8, 0x4a, 0x94, 0x08, 0x1b, 0x4e, 0xd1, 0xae, 0x0a, 0x1a, - 0x3d, 0x8a, 0x56, 0x0d, 0x53, 0x23, 0x9e, 0x2a, 0x61, 0xed, 0xd2, 0x0b, - 0x2f, 0x44, 0xa5, 0xb6, 0xa4, 0x60, 0x15, 0x0a, 0x99, 0xf3, 0xd1, 0x3c, - 0x3c, 0xc4, 0x24, 0x5e, 0xfe, 0x20, 0x24, 0x13, 0x07, 0xe7, 0x3b, 0x02, - 0x44, 0x92, 0x8b, 0x9a, 0x30, 0x92, 0xbe, 0x7c, 0xec, 0x06, 0xda, 0xae, - 0xe7, 0x35, 0x38, 0x91, 0x4e, 0xa6, 0x39, 0x74, 0x21, 0x68, 0xa1, 0xa0, - 0x30, 0x91, 0x54, 0x67, 0x62, 0x46, 0x92, 0x16, 0x8a, 0xf6, 0xf4, 0xf9, - 0xb5, 0x6e, 0x7a, 0xb3, 0x87, 0x26, 0xfd, 0x39, 0x99, 0x57, 0x5f, 0xe1, - 0xae, 0x98, 0x06, 0x97, 0x92, 0x20, 0x9a, 0x1a, 0x47, 0xf3, 0x92, 0xd8, - 0xb0, 0x7c, 0xcb, 0xf7, 0x98, 0x22, 0x23, 0x8a, 0xe8, 0xf6, 0x6a, 0xff, - 0xf5, 0xdb, 0xfd, 0x97, 0x7d, 0x35, 0x3c, 0x2a, 0xcd, 0xde, 0x0f, 0x12, - 0x3d, 0x35, 0x19, 0x55, 0x0a, 0x91, 0x8f, 0x54, 0x9c, 0x4f, 0x87, 0xc8, - 0x41, 0x3b, 0xf7, 0x58, 0x03, 0x84, 0x31, 0xd3, 0xef, 0xae, 0x01, 0xd2, - 0x80, 0xd2, 0x55, 0xcb, 0x6b, 0x4f, 0x12, 0xf7, 0xc4, 0x37, 0x80, 0x9f, - 0xb0, 0x28, 0x1b, 0x9c, 0x03, 0xe1, 0x33, 0x6f, 0x97, 0xcd, 0x27, 0xe9, - 0x8c, 0x76, 0x63, 0x23, 0x39, 0x41, 0xbc, 0x66, 0x1c, 0x2d, 0xa5, 0x6a, - 0xe2, 0x75, 0x1d, 0xa8, 0x2b, 0x94, 0x74, 0x12, 0xa9, 0x82, 0x0c, 0x8b, - 0x6a, 0x3e, 0xe2, 0xa4, 0x5b, 0x13, 0x95, 0xb9, 0x1b, 0xfe, 0xd0, 0xcc, - 0x29, 0xa4, 0x54, 0xa1, 0xc5, 0x7e, 0x80, 0x07, 0xd8, 0x50, 0xdc, 0xe3, - 0xfa, 0x99, 0x6e, 0x90, 0xb7, 0xc6, 0xac, 0x7e, 0x7c, 0x1d, 0xe4, 0x96, - 0x1d, 0xd6, 0x8e, 0x58, 0x6d, 0x81, 0xa9, 0xfd, 0x62, 0x3b, 0xbe, 0xe6, - 0x74, 0x19, 0x5c, 0xfc, 0x0e, 0x6e, 0xf7, 0xda, 0x6a, 0x21, 0x92, 0x4f, - 0x9a, 0x90, 0x51, 0x52, 0x00, 0xcc, 0xcd, 0x50, 0x36, 0x8b, 0xad, 0xe5, - 0xfc, 0xc7, 0x32, 0x63, 0x79, 0x72, 0x6a, 0x2a, 0xb4, 0xbe, 0xae, 0x65, - 0x3a, 0x0c, 0x94, 0x5c, 0xa7, 0xcf, 0x2d, 0x99, 0xb1, 0x3c, 0xe8, 0xb5, - 0xc3, 0x24, 0xae, 0x17, 0xa8, 0x59, 0xd5, 0x20, 0x3a, 0xe2, 0xaa, 0x52, - 0xfa, 0xf4, 0x4b, 0xd1, 0x33, 0x92, 0xef, 0x84, 0xc7, 0x3d, 0xd5, 0xe4, - 0x71, 0xe5, 0x40, 0x5d, 0x0d, 0x5b, 0x4e, 0x44, 0xb1, 0xe8, 0x18, 0x74, - 0x94, 0x9a, 0x56, 0x79, 0x20, 0x54, 0x0d, 0x09, 0xdd, 0x16, 0x51, 0xc9, - 0x84, 0x49, 0x96, 0x4e, 0x79, 0xc7, 0xdf, 0x5a, 0xd0, 0x33, 0x99, 0x15, - 0xd1, 0x26, 0x2c, 0x26, 0x5e, 0x3f, 0x4b, 0x52, 0x9b, 0x24, 0x26, 0x89, - 0x41, 0xed, 0x6e, 0x14, 0x79, 0x19, 0xad, 0x88, 0x39, 0xf9, 0x72, 0x5c, - 0x68, 0x38, 0x8f, 0x84, 0x47, 0xc0, 0x32, 0xff, 0x60, 0x40, 0x85, 0x10, - 0xe9, 0xd0, 0xc1, 0xb7, 0x17, 0x17, 0x02, 0xd7, 0x9b, 0x7c, 0xa7, 0xfa, - 0x46, 0xf2, 0x34, 0x19, 0x65, 0x69, 0x4d, 0x51, 0x0d, 0xc5, 0x48, 0xbb, - 0xee, 0x37, 0xf6, 0xc9, 0x33, 0x97, 0x06, 0x25, 0x06, 0x11, 0xe3, 0xe3, - 0xb8, 0x8b, 0x36, 0xad, 0x86, 0x8c, 0x3a, 0x5d, 0x11, 0x08, 0x39, 0x26, - 0xa6, 0x7a, 0xd6, 0xc3, 0xdb, 0x06, 0x83, 0x3d, 0xa2, 0x6a, 0x0c, 0x9c, - 0x9b, 0x2a, 0x5e, 0x6b, 0x4a, 0xd0, 0xd4, 0xe0, 0xbe, 0xb4, 0x7a, 0xcf, - 0xa6, 0xa4, 0x8e, 0xbe, 0x98, 0x70, 0xef, 0xe9, 0xa8, 0xe6, 0xbb, 0x9d, - 0x51, 0xd2, 0xc2, 0x1d, 0x61, 0xe0, 0xbe, 0xe4, 0x8d, 0x22, 0xc0, 0x0b, - 0x3d, 0x96, 0x82, 0x2d, 0xd8, 0xb0, 0x5e, 0x16, 0xa3, 0xd1, 0x02, 0x1c, - 0xc8, 0xfe, 0xc1, 0x41, 0x40, 0x15, 0xe5, 0x6c, 0x28, 0x3f, 0xf8, 0xcf, - 0x96, 0x31, 0xec, 0x3b, 0xe9, 0x4c, 0xca, 0x7e, 0x59, 0x9c, 0x17, 0x75, - 0x67, 0xd5, 0x32, 0xae, 0x65, 0xbc, 0xd2, 0x41, 0x90, 0xeb, 0xd5, 0x05, - 0x63, 0x35, 0x3f, 0x95, 0x39, 0x45, 0x0b, 0x8f, 0xd6, 0x1b, 0x1f, 0xe1, - 0x06, 0x2b, 0x11, 0xc0, 0x9e, 0xdf, 0x9e, 0x1e, 0xbe, 0xe1, 0x85, 0x3d, - 0xd9, 0x3f, 0x3d, 0x75, 0x30, 0xb6, 0x12, 0xd1, 0xa3, 0xd3, 0xe4, 0x58, - 0x26, 0xf1, 0x10, 0xf1, 0xb2, 0x59, 0xe4, 0xb0, 0xe4, 0x20, 0x11, 0x83, - 0xc5, 0x13, 0x73, 0x36, 0x9f, 0xc0, 0x15, 0x0c, 0xda, 0xdf, 0x10, 0xa3, - 0x61, 0x96, 0xb8, 0x2d, 0x85, 0x02, 0x28, 0x65, 0xfd, 0x39, 0xa6, 0xef, - 0xab, 0x6f, 0x41, 0x3c, 0xb9, 0x2e, 0x59, 0xbd, 0xab, 0xfb, 0xd7, 0x39, - 0x3d, 0x3a, 0x3b, 0x94, 0x1d, 0x7c, 0x7b, 0xf6, 0xa2, 0xa3, 0xa0, 0x14, - 0x8d, 0x22, 0x38, 0x05, 0x09, 0x58, 0x40, 0xd1, 0x99, 0x85, 0x29, 0x1a, - 0x5c, 0xb5, 0x98, 0xf1, 0x5b, 0x93, 0xe2, 0x2d, 0x1e, 0x78, 0xd9, 0xf2, - 0x36, 0xa2, 0x82, 0xef, 0x35, 0x2c, 0x78, 0x59, 0x9f, 0x9d, 0xb7, 0x8f, - 0x76, 0xcb, 0x16, 0x12, 0x69, 0xaf, 0xb6, 0xad, 0xc4, 0xc5, 0x17, 0xef, - 0x02, 0xcd, 0x2c, 0x14, 0xb4, 0xe7, 0xba, 0xc9, 0xd1, 0xf9, 0xc4, 0x4f, - 0xd0, 0x57, 0x88, 0xff, 0xbe, 0x7d, 0xf3, 0x72, 0xd3, 0x72, 0xa8, 0x18, - 0x52, 0x38, 0xe5, 0x1c, 0x37, 0x95, 0x9a, 0x95, 0xe7, 0x50, 0xfc, 0xa9, - 0x79, 0xb1, 0xa9, 0x4c, 0xbb, 0x85, 0x74, 0xa9, 0x9d, 0x5f, 0x18, 0x23, - 0x8c, 0x2d, 0x2d, 0x87, 0x06, 0xce, 0x49, 0x9c, 0x2e, 0x84, 0x8a, 0xe4, - 0x21, 0xc6, 0xaa, 0x2f, 0xc1, 0x6a, 0x31, 0xd4, 0xa9, 0xc4, 0x04, 0xea, - 0x45, 0x1e, 0x01, 0xa7, 0xf2, 0xfc, 0x84, 0xc1, 0xe7, 0x54, 0xee, 0xca, - 0x57, 0x67, 0x6f, 0xd6, 0x6d, 0x6e, 0xd6, 0x27, 0x6f, 0xba, 0xbc, 0x35, - 0x49, 0xf0, 0xe3, 0x40, 0xaa, 0x17, 0xab, 0x55, 0xdf, 0xb1, 0xed, 0x51, - 0xbd, 0xf5, 0xa5, 0x95, 0x9d, 0xb9, 0xa4, 0x39, 0x19, 0x1e, 0xa9, 0x04, - 0x7b, 0x4b, 0x58, 0x78, 0x4b, 0x89, 0x6c, 0x6c, 0x5f, 0x42, 0x6d, 0x9f, - 0xf2, 0xbf, 0x11, 0x6f, 0x38, 0x60, 0x24, 0x07, 0xb1, 0xac, 0xcb, 0x83, - 0x34, 0x34, 0x2d, 0x50, 0x23, 0x09, 0xae, 0x25, 0x85, 0x4b, 0xaa, 0x19, - 0x9a, 0x32, 0x0a, 0xc4, 0x0f, 0x0e, 0xed, 0xac, 0x9f, 0x6e, 0x98, 0x47, - 0x01, 0xad, 0x1d, 0xd2, 0x8e, 0xea, 0xd0, 0x1e, 0xde, 0xcd, 0x15, 0x67, - 0x09, 0x6a, 0xb4, 0x86, 0x99, 0x1b, 0xf5, 0x9b, 0x49, 0x82, 0x36, 0x64, - 0x70, 0x3d, 0x94, 0x14, 0x6b, 0xf3, 0x3c, 0x1e, 0xfc, 0xf4, 0x2c, 0x24, - 0xf7, 0xd1, 0x05, 0x42, 0xe3, 0x23, 0xd2, 0x34, 0xa5, 0x3a, 0x54, 0x0e, - 0x61, 0xac, 0x88, 0x07, 0xcf, 0x09, 0xd2, 0x3c, 0x9b, 0x25, 0x97, 0x39, - 0xbc, 0x5a, 0x0e, 0x2e, 0x19, 0x5a, 0x0a, 0x43, 0x63, 0x41, 0x1a, 0xc0, - 0xa4, 0xbc, 0xe9, 0x8d, 0x71, 0xc0, 0xbe, 0x85, 0x1c, 0x61, 0x02, 0x39, - 0xfa, 0xd3, 0xa1, 0x85, 0xed, 0x2f, 0x77, 0x9f, 0x24, 0x55, 0x7a, 0x53, - 0xb1, 0x09, 0xd5, 0x15, 0x3f, 0xa3, 0x6a, 0x62, 0x22, 0x67, 0xab, 0x81, - 0xc4, 0x70, 0x44, 0xce, 0xe7, 0x56, 0xaf, 0xa5, 0x42, 0x93, 0x05, 0x59, - 0x77, 0x05, 0x9b, 0xd6, 0x6a, 0x3d, 0x84, 0x69, 0x02, 0xb5, 0xe1, 0x04, - 0x19, 0xae, 0xa9, 0xef, 0xc2, 0xbc, 0x4f, 0x8f, 0xfe, 0xeb, 0xb0, 0x9b, - 0xbc, 0x39, 0x3c, 0x7b, 0xd3, 0x4d, 0x4e, 0xcf, 0x8e, 0xdf, 0xa0, 0x2b, - 0x9d, 0xc5, 0x23, 0x9c, 0x67, 0x25, 0x5d, 0x90, 0xf3, 0x8f, 0x96, 0x22, - 0x8e, 0x4d, 0x0c, 0x71, 0x7c, 0xea, 0x50, 0xab, 0xb2, 0xe6, 0x74, 0xd9, - 0xf4, 0x44, 0x46, 0x0e, 0x60, 0x62, 0x6d, 0x03, 0xe5, 0x1d, 0x08, 0x83, - 0xc5, 0x1d, 0xc5, 0xd1, 0x06, 0xbf, 0x39, 0xf5, 0x5f, 0xc3, 0xee, 0x03, - 0x07, 0xd4, 0xd3, 0x77, 0x13, 0x92, 0xcc, 0x34, 0x06, 0x97, 0x40, 0xe5, - 0x1f, 0x04, 0xdf, 0x5d, 0x47, 0x31, 0x91, 0x81, 0xaf, 0xaf, 0x73, 0xe1, - 0x4c, 0xdd, 0x45, 0x25, 0x83, 0x84, 0x22, 0xe0, 0x36, 0x2c, 0x2c, 0x94, - 0x06, 0x5b, 0x15, 0x93, 0x8c, 0xe8, 0x97, 0xcc, 0xa9, 0xca, 0x5f, 0x28, - 0x2c, 0x9f, 0xeb, 0x2f, 0xb1, 0x32, 0xdf, 0xa1, 0x15, 0xee, 0x44, 0x71, - 0x5e, 0xd1, 0x82, 0x65, 0x53, 0xa0, 0x40, 0x2a, 0xfc, 0xda, 0xd1, 0xfe, - 0x3a, 0x51, 0xc2, 0xb4, 0x3b, 0x4b, 0xf7, 0x59, 0x92, 0xa2, 0x6a, 0x61, - 0x09, 0xd2, 0x8d, 0xcd, 0x7b, 0x91, 0x1d, 0xc0, 0xc2, 0x6e, 0xe3, 0x8f, - 0x9d, 0xcd, 0x60, 0xbb, 0x6c, 0x69, 0x81, 0x26, 0xfd, 0xe9, 0xaf, 0xdb, - 0x66, 0xdf, 0xdd, 0xc4, 0x02, 0x3b, 0xc2, 0x6c, 0xda, 0x1e, 0xa1, 0x21, - 0x79, 0x66, 0x84, 0x48, 0xe2, 0x9e, 0x03, 0x91, 0xf4, 0x1d, 0x01, 0x95, - 0x5b, 0x0a, 0x28, 0x0b, 0x72, 0x21, 0xc5, 0x19, 0xd9, 0xb7, 0x3c, 0xd8, - 0xf0, 0xec, 0x12, 0xe3, 0x18, 0xdb, 0x79, 0x53, 0x92, 0x15, 0xb8, 0x84, - 0xf9, 0xc2, 0x2d, 0x12, 0xcb, 0xd0, 0x16, 0x30, 0x80, 0xc2, 0x08, 0xe5, - 0xf0, 0xa7, 0x94, 0xb9, 0x91, 0x17, 0x84, 0x01, 0x16, 0x10, 0xd2, 0x67, - 0xde, 0x9a, 0xf8, 0x26, 0xa3, 0xec, 0x23, 0xd2, 0x72, 0x93, 0x6c, 0x4a, - 0xc1, 0x2c, 0xc3, 0x30, 0x15, 0x2c, 0x8b, 0x32, 0xe6, 0xe8, 0x2e, 0xbc, - 0x1b, 0x87, 0x05, 0xc7, 0xfc, 0xe1, 0x78, 0x08, 0x5d, 0x1a, 0x1d, 0x36, - 0x66, 0x2d, 0x0d, 0xe1, 0x16, 0xd2, 0x90, 0x18, 0xc6, 0x39, 0x0b, 0xd5, - 0x0d, 0x81, 0xee, 0x1a, 0x1d, 0xc1, 0x89, 0x5f, 0x35, 0xe6, 0x60, 0xb5, - 0x95, 0xa0, 0x41, 0xf1, 0xa7, 0x0a, 0x28, 0xe5, 0xaa, 0x0e, 0x68, 0x99, - 0x01, 0x39, 0x8c, 0xd2, 0x10, 0xc2, 0x8b, 0x27, 0xf3, 0xe9, 0x18, 0x83, - 0xd2, 0x1b, 0x50, 0xd2, 0x2a, 0xbc, 0xc4, 0x61, 0xbe, 0xb2, 0x91, 0xf7, - 0x53, 0xd5, 0xc1, 0x00, 0xe6, 0xef, 0xbc, 0x29, 0xa9, 0xcf, 0x8f, 0x45, - 0x7b, 0x57, 0xf2, 0x3b, 0xe9, 0xfa, 0x95, 0x6c, 0x42, 0xa2, 0x12, 0x31, - 0xca, 0xa6, 0x52, 0xee, 0x88, 0x54, 0xe5, 0x56, 0x16, 0x0e, 0x3b, 0x94, - 0x63, 0x75, 0x8f, 0xa2, 0xdc, 0x44, 0xc2, 0xce, 0xa8, 0x70, 0x65, 0x02, - 0x77, 0x27, 0x3d, 0x1c, 0x72, 0x49, 0x9c, 0x34, 0x4c, 0x33, 0x84, 0x76, - 0xdb, 0xaa, 0x80, 0x6b, 0x01, 0xb6, 0x4c, 0x91, 0xc7, 0x27, 0x9c, 0x50, - 0xe4, 0x62, 0x66, 0x29, 0xff, 0x41, 0xc5, 0xf1, 0xb8, 0x62, 0x8e, 0x74, - 0x42, 0x36, 0x0e, 0xf5, 0x8a, 0xb1, 0xdc, 0xbc, 0x56, 0x2d, 0xc0, 0xfa, - 0x28, 0x3c, 0x26, 0xe7, 0xa6, 0x97, 0xb5, 0x86, 0x16, 0xc5, 0xa7, 0x8e, - 0x34, 0xb1, 0x46, 0x37, 0xc0, 0xbf, 0xe6, 0xb3, 0x70, 0xd3, 0x3b, 0x74, - 0x58, 0x6d, 0x4b, 0xc3, 0x00, 0xfc, 0xa0, 0xea, 0xa2, 0x1f, 0x56, 0xd7, - 0x5f, 0x91, 0x85, 0x65, 0x47, 0x8d, 0xf4, 0x7e, 0x37, 0x68, 0x49, 0xbc, - 0x4c, 0x18, 0x15, 0x11, 0x31, 0x94, 0xb1, 0x6f, 0x41, 0x55, 0x90, 0x10, - 0x0f, 0x7b, 0x10, 0x26, 0xe8, 0xc6, 0x11, 0x63, 0xba, 0x3f, 0xc0, 0xf5, - 0x5c, 0x7f, 0x3b, 0xcd, 0x3f, 0x90, 0xa9, 0x55, 0xf1, 0x32, 0xc2, 0xf3, - 0xd6, 0x8b, 0x22, 0x71, 0x22, 0x8e, 0xaf, 0xef, 0x8d, 0xd2, 0x30, 0xb0, - 0xa2, 0x6a, 0xfc, 0x92, 0x47, 0x0d, 0xb3, 0x36, 0x26, 0x37, 0x7d, 0xfc, - 0xac, 0x3f, 0x2c, 0x26, 0x64, 0x37, 0x8f, 0x5b, 0x99, 0x50, 0xf2, 0xae, - 0xb2, 0xc5, 0x1e, 0xbe, 0x45, 0x39, 0xe4, 0xb4, 0xef, 0xb3, 0x1c, 0xf6, - 0x2d, 0x44, 0x22, 0x1f, 0x9d, 0x84, 0x5d, 0x12, 0x77, 0x73, 0xa5, 0x05, - 0xbf, 0x02, 0xe2, 0x9c, 0x5c, 0x96, 0x8a, 0xbe, 0x95, 0xc4, 0x9c, 0x31, - 0x96, 0x3c, 0x30, 0x1f, 0x93, 0x9c, 0x78, 0xac, 0xa8, 0x0c, 0x2e, 0x8b, - 0x7c, 0x90, 0xa1, 0x08, 0xd4, 0x56, 0xca, 0x80, 0x6a, 0x6c, 0x58, 0xf5, - 0x5f, 0xab, 0xf6, 0xe0, 0x1f, 0x55, 0x31, 0x9b, 0x4b, 0x93, 0xf1, 0x9b, - 0x72, 0x42, 0x0e, 0x7d, 0xf9, 0x93, 0x05, 0x13, 0x1b, 0xb5, 0xcd, 0xde, - 0x71, 0x0d, 0xcf, 0x78, 0xd0, 0x28, 0xb3, 0x61, 0x75, 0x31, 0x84, 0x65, - 0xe2, 0x2b, 0x7f, 0xfc, 0x23, 0x32, 0x83, 0x07, 0x8d, 0x70, 0x10, 0xa9, - 0x0b, 0x9a, 0x74, 0xf6, 0xfe, 0x4a, 0x2e, 0xa2, 0x5f, 0x7b, 0x7f, 0x85, - 0xbf, 0x7f, 0xed, 0x04, 0xc3, 0xb6, 0xd4, 0x3a, 0x31, 0xc8, 0x85, 0x07, - 0xb2, 0xac, 0x5d, 0x3a, 0x25, 0xa0, 0x2c, 0xfa, 0x48, 0x92, 0xb3, 0x83, - 0x13, 0x26, 0x62, 0x44, 0xd7, 0xe0, 0x88, 0x46, 0x98, 0x18, 0x9e, 0x56, - 0x16, 0x86, 0x53, 0xf4, 0x8d, 0x3f, 0x20, 0xc0, 0x36, 0xd9, 0xd8, 0xd4, - 0x3f, 0xdf, 0x0d, 0xc1, 0x2f, 0xd7, 0xa2, 0x77, 0xa6, 0x20, 0x59, 0x5e, - 0xa0, 0xad, 0x98, 0x61, 0x6d, 0x31, 0x88, 0x1a, 0x05, 0x14, 0x96, 0x59, - 0xf9, 0x33, 0x06, 0xc2, 0x41, 0xef, 0xdb, 0x35, 0x0c, 0x87, 0x83, 0x6b, - 0xd8, 0xf9, 0x90, 0x05, 0x84, 0x92, 0x7c, 0x3a, 0x20, 0xd8, 0x20, 0x95, - 0xe8, 0xca, 0xbc, 0x7a, 0x8f, 0x93, 0x92, 0x9c, 0x17, 0x09, 0xf5, 0x22, - 0xc0, 0x91, 0x82, 0x8c, 0xed, 0x37, 0x74, 0xc9, 0xa0, 0xe3, 0x5f, 0x3d, - 0x1f, 0x0b, 0x92, 0x8b, 0x81, 0x77, 0x2e, 0x15, 0x5c, 0x5c, 0xb2, 0xd2, - 0x27, 0x49, 0x2e, 0x27, 0x49, 0x8f, 0x99, 0xf3, 0x32, 0xe0, 0xa7, 0x13, - 0x3e, 0xdd, 0x77, 0x3c, 0xe3, 0x51, 0x72, 0x17, 0x1e, 0x6d, 0xd5, 0x7a, - 0xe9, 0x5a, 0x10, 0xac, 0xb9, 0xb8, 0x82, 0x88, 0x93, 0x3b, 0xca, 0x2c, - 0x2a, 0xec, 0xc3, 0x91, 0x4f, 0x69, 0x72, 0x02, 0xd2, 0xb4, 0x23, 0x5f, - 0x09, 0x90, 0xc3, 0x1b, 0x31, 0x61, 0x38, 0x0f, 0xbc, 0x3e, 0x51, 0xe2, - 0x44, 0x08, 0x59, 0xca, 0xd2, 0xb3, 0x9a, 0x1e, 0x56, 0xf0, 0x06, 0xcf, - 0x3f, 0xde, 0xf5, 0xc3, 0x12, 0x7a, 0xc2, 0xd8, 0x45, 0xc1, 0x32, 0x52, - 0x93, 0x09, 0x25, 0x2a, 0xaa, 0xde, 0x1b, 0xfa, 0xb2, 0x94, 0x84, 0x20, - 0x24, 0x8f, 0xd9, 0x55, 0x58, 0x71, 0xd9, 0x5b, 0xa4, 0x10, 0xfa, 0x65, - 0x3e, 0xd3, 0x3c, 0x9d, 0xeb, 0x29, 0x1a, 0x80, 0xc5, 0x54, 0xc9, 0xa3, - 0xa4, 0x9b, 0x63, 0xb1, 0xfe, 0x81, 0x4e, 0xba, 0x35, 0x2d, 0x21, 0x44, - 0x71, 0x37, 0xd3, 0x11, 0xcd, 0xc9, 0xda, 0x7a, 0x4b, 0x43, 0x7b, 0x2b, - 0xdc, 0xd2, 0xd8, 0xeb, 0x2a, 0xb7, 0x74, 0x10, 0x6b, 0x42, 0xf9, 0x89, - 0x34, 0x5c, 0xd8, 0xf4, 0x01, 0xc2, 0x8c, 0xd2, 0xa7, 0x3d, 0x8d, 0xb5, - 0x97, 0x9a, 0x2c, 0x02, 0x81, 0xa5, 0x98, 0x15, 0x84, 0x07, 0xed, 0xd9, - 0xa8, 0xb3, 0x08, 0x19, 0x8a, 0xae, 0x26, 0xd4, 0x1b, 0x5e, 0x28, 0xa7, - 0x76, 0x92, 0xe9, 0x00, 0xed, 0xec, 0x95, 0xae, 0xa9, 0xed, 0x91, 0x4b, - 0xdd, 0x57, 0x7e, 0x5b, 0xb9, 0x9a, 0xcd, 0xf1, 0x9d, 0x8f, 0x8c, 0xf8, - 0x48, 0xd9, 0x9f, 0xa4, 0xf0, 0x91, 0xd1, 0x24, 0xb0, 0x7a, 0x7f, 0x79, - 0x31, 0xa0, 0x27, 0xb3, 0x79, 0x3b, 0x63, 0x95, 0x89, 0xbf, 0xca, 0xe7, - 0x5d, 0xeb, 0xed, 0xb9, 0x1c, 0x8a, 0x41, 0x7c, 0x6e, 0x49, 0x8b, 0x8a, - 0x84, 0xc4, 0x10, 0xb4, 0x04, 0x84, 0xd4, 0xf2, 0x6a, 0x5c, 0x7c, 0x25, - 0x1f, 0x49, 0x4d, 0x29, 0x2e, 0x3f, 0x54, 0xb2, 0xdc, 0x68, 0xb0, 0x8b, - 0x21, 0x1e, 0x38, 0xc8, 0x8c, 0xfd, 0x45, 0x73, 0x8a, 0xdf, 0xae, 0xa5, - 0x55, 0x81, 0x3e, 0x3a, 0x09, 0xac, 0xd1, 0xf0, 0xdd, 0x24, 0x18, 0x0d, - 0x63, 0x65, 0x52, 0x5c, 0xa0, 0xbd, 0x6a, 0xdc, 0x1b, 0x0c, 0x06, 0x4d, - 0x75, 0xe5, 0xe0, 0xe0, 0x20, 0x59, 0x3f, 0xa0, 0xda, 0x7a, 0x07, 0x42, - 0x27, 0x07, 0x97, 0x18, 0x61, 0x38, 0x06, 0xb6, 0x72, 0x39, 0x07, 0x02, - 0xc1, 0x73, 0x4a, 0x7b, 0x78, 0x7a, 0xfa, 0x72, 0x93, 0xf2, 0x53, 0xc6, - 0xe9, 0x8d, 0x82, 0x12, 0x89, 0x69, 0xbb, 0x61, 0x93, 0xed, 0x4b, 0xc4, - 0x50, 0x22, 0x75, 0xd5, 0xd9, 0x41, 0xc5, 0x57, 0xac, 0xdd, 0xf8, 0x14, - 0x22, 0x08, 0xfd, 0x58, 0xfd, 0xc8, 0xc9, 0x7c, 0xea, 0xb2, 0x96, 0x51, - 0xa1, 0x99, 0x66, 0x8a, 0x6f, 0x27, 0x62, 0xa7, 0x64, 0x63, 0xbd, 0xde, - 0x3f, 0xc3, 0xb4, 0x95, 0xda, 0x92, 0x18, 0xc9, 0xf8, 0x12, 0xe2, 0x35, - 0x5c, 0x7d, 0xb2, 0x34, 0xc8, 0x14, 0xbe, 0x0e, 0x3a, 0x2b, 0x67, 0x0c, - 0x4e, 0x43, 0x82, 0x63, 0x6b, 0x4a, 0x54, 0x58, 0xb6, 0x25, 0x09, 0x80, - 0x4b, 0xd5, 0x02, 0xde, 0xf6, 0xa8, 0xf4, 0x94, 0xee, 0x3d, 0x37, 0xb8, - 0xc2, 0xb6, 0x4b, 0xcf, 0xa3, 0xa5, 0x01, 0xa6, 0x6e, 0xcb, 0xe1, 0x61, - 0xc7, 0x78, 0xe4, 0xd5, 0x1e, 0x73, 0xd3, 0x45, 0x22, 0xa0, 0x2f, 0x40, - 0xae, 0x25, 0x69, 0x7d, 0x53, 0x56, 0xe0, 0xdb, 0xf8, 0x46, 0xa9, 0x85, - 0xef, 0x20, 0x81, 0xb0, 0x3c, 0xcf, 0xf5, 0x82, 0x23, 0xed, 0x36, 0x24, - 0x9c, 0xb2, 0x42, 0xe1, 0xa3, 0xb1, 0x2b, 0xa0, 0x1e, 0xa4, 0x1d, 0x16, - 0x0b, 0xf4, 0xc8, 0x31, 0xc2, 0x87, 0x69, 0xc5, 0xae, 0x70, 0x66, 0x01, - 0xeb, 0xd6, 0x5a, 0x98, 0xad, 0xcc, 0x30, 0x99, 0x55, 0x83, 0x7d, 0xa5, - 0x55, 0x87, 0x9d, 0xa4, 0xd6, 0x3a, 0x1a, 0xa0, 0xd3, 0x40, 0x4c, 0xcd, - 0x51, 0xe3, 0x67, 0xfc, 0x3e, 0x61, 0x46, 0xd0, 0x68, 0x04, 0xf6, 0x44, - 0x3a, 0x0a, 0x0d, 0x87, 0x96, 0x6f, 0x23, 0x0d, 0x5e, 0xcc, 0x95, 0xd2, - 0xe4, 0xef, 0xce, 0x96, 0x5b, 0xdc, 0xbc, 0xd5, 0xa8, 0x84, 0x07, 0x21, - 0x93, 0xff, 0x04, 0xfa, 0x89, 0x29, 0xb3, 0x31, 0x47, 0x3e, 0xb1, 0x9e, - 0x3c, 0xde, 0xa8, 0x4c, 0x60, 0x3c, 0xc1, 0x9c, 0xa2, 0x74, 0xf4, 0xc6, - 0xc5, 0x45, 0x4e, 0xe6, 0x6d, 0x2e, 0xda, 0x19, 0x05, 0xb9, 0xc8, 0xf5, - 0xbe, 0xcf, 0x47, 0x59, 0xc1, 0x75, 0x23, 0xd4, 0x02, 0x26, 0x19, 0x94, - 0x34, 0x8c, 0x01, 0xb0, 0xfd, 0xc4, 0xe1, 0x75, 0x98, 0xc0, 0x01, 0x8b, - 0x9b, 0x0f, 0x40, 0x5d, 0x1c, 0xdc, 0xf4, 0x29, 0x43, 0x5f, 0xaf, 0x34, - 0x0b, 0x3a, 0xc9, 0x47, 0xb1, 0x53, 0xc5, 0xd5, 0xef, 0x91, 0xe8, 0x33, - 0x59, 0x0e, 0x9e, 0xcb, 0xa2, 0x75, 0xc0, 0x2d, 0xc2, 0x7d, 0x15, 0x5c, - 0x6a, 0x34, 0xbb, 0xe2, 0x3e, 0xcb, 0x18, 0x56, 0xf0, 0x9f, 0xb8, 0x2a, - 0xae, 0x3f, 0xa0, 0xa9, 0xc0, 0x52, 0x76, 0x24, 0xc3, 0x97, 0xbd, 0x5d, - 0x96, 0x9d, 0xd2, 0x82, 0x51, 0x4e, 0x65, 0x10, 0x39, 0xea, 0x26, 0x24, - 0x4f, 0x47, 0xa8, 0x0e, 0x1a, 0x24, 0x41, 0xc5, 0x86, 0x25, 0x10, 0x09, - 0x37, 0x7a, 0xa1, 0x8e, 0x71, 0x5d, 0x38, 0xfb, 0x14, 0xc7, 0x8c, 0x51, - 0xd6, 0x84, 0xe0, 0xe8, 0x83, 0xcc, 0xaa, 0x80, 0x69, 0xa6, 0x6f, 0xa9, - 0x59, 0x9d, 0x32, 0xc9, 0xf4, 0x5b, 0x09, 0x3c, 0x42, 0xc7, 0xf5, 0x75, - 0x8e, 0x58, 0x3d, 0x5a, 0x76, 0xde, 0x09, 0xf5, 0xbc, 0x66, 0x0e, 0x76, - 0x36, 0xa8, 0x08, 0x4c, 0x41, 0x85, 0x15, 0xe4, 0xa2, 0xdc, 0x16, 0x68, - 0xb9, 0x54, 0x6c, 0x66, 0xa7, 0x66, 0xd8, 0x58, 0x5b, 0xea, 0xca, 0x72, - 0x20, 0x89, 0xa8, 0x18, 0x9c, 0xea, 0x26, 0xc1, 0xc8, 0x21, 0xc7, 0x45, - 0x8e, 0xb7, 0x2b, 0xf3, 0xa1, 0xbd, 0x6a, 0x3c, 0xe8, 0x8b, 0xc3, 0xfd, - 0x67, 0x01, 0x0b, 0xc9, 0x93, 0x1c, 0x9a, 0x9a, 0xef, 0xc5, 0x16, 0x75, - 0xb1, 0x20, 0xe0, 0x36, 0xcd, 0xb3, 0xd8, 0xd5, 0x9d, 0x08, 0xb7, 0xf8, - 0x50, 0x6f, 0x98, 0x74, 0xea, 0xa2, 0x18, 0x6b, 0xd0, 0x0e, 0xfc, 0x99, - 0x5e, 0x64, 0xdf, 0x14, 0xe3, 0x61, 0x67, 0xc5, 0x06, 0x8e, 0x9a, 0x6d, - 0x7c, 0x6c, 0x4d, 0x6b, 0x5d, 0x2b, 0x21, 0xeb, 0x0b, 0x22, 0xeb, 0x71, - 0x71, 0x5e, 0x8c, 0x44, 0x8a, 0x3b, 0xe5, 0x0a, 0x78, 0xe8, 0x23, 0x57, - 0x70, 0x62, 0x02, 0x06, 0x38, 0x27, 0x91, 0x4e, 0x13, 0x55, 0x25, 0xd8, - 0x98, 0xec, 0x96, 0x15, 0x25, 0x82, 0x38, 0xf4, 0x08, 0x6e, 0xe8, 0x46, - 0x34, 0x75, 0xd5, 0x94, 0x1d, 0xd0, 0x83, 0x05, 0xce, 0xa2, 0x76, 0x49, - 0x35, 0x3f, 0xab, 0xe4, 0x1f, 0xff, 0xfc, 0xeb, 0xaf, 0xc1, 0x0a, 0x7f, - 0x49, 0x79, 0xb5, 0x2e, 0x1b, 0x12, 0x6e, 0x98, 0x6c, 0x3c, 0x62, 0xa3, - 0x0f, 0x69, 0x13, 0x88, 0x85, 0xdc, 0x77, 0xf1, 0xf8, 0xec, 0xbb, 0xd0, - 0xd6, 0x30, 0xaa, 0x8f, 0x78, 0x13, 0x7b, 0x10, 0x24, 0xd8, 0x39, 0xbb, - 0x00, 0xd5, 0x56, 0xab, 0xd0, 0x51, 0x38, 0x33, 0x72, 0x48, 0x78, 0xf3, - 0xc6, 0x19, 0xa5, 0xac, 0xbc, 0xba, 0xcf, 0x9d, 0x14, 0xc2, 0x3b, 0x92, - 0x4b, 0x59, 0x34, 0xb7, 0x06, 0xc5, 0xf1, 0x32, 0x2e, 0xd3, 0xae, 0xe2, - 0x9c, 0xef, 0x3b, 0x33, 0x64, 0xa5, 0xb5, 0x5b, 0x79, 0x1a, 0x62, 0x54, - 0xb7, 0x64, 0xce, 0xfc, 0xe3, 0xaf, 0xbf, 0xfe, 0x13, 0xfe, 0xd3, 0x59, - 0x56, 0xe2, 0x36, 0x56, 0x8c, 0xed, 0xa6, 0xba, 0x84, 0x83, 0x76, 0xd3, - 0xcb, 0x6e, 0xb2, 0x73, 0xe0, 0x5a, 0x95, 0x42, 0x49, 0xf5, 0x26, 0x55, - 0xf2, 0x74, 0xa2, 0x46, 0xd1, 0x17, 0xf8, 0x4c, 0x72, 0x28, 0xcf, 0x68, - 0x2d, 0xc7, 0x74, 0x7c, 0x51, 0x94, 0x30, 0xf2, 0x89, 0x38, 0x81, 0x63, - 0x0f, 0xac, 0x19, 0x01, 0x13, 0x4a, 0xfc, 0x53, 0x0b, 0xdc, 0xd5, 0x43, - 0xc9, 0x3b, 0xf5, 0x45, 0x9d, 0x32, 0x95, 0x23, 0x86, 0xf3, 0x74, 0x8c, - 0x1a, 0x32, 0x5a, 0xc5, 0xd0, 0xa6, 0x86, 0xc6, 0x88, 0x8b, 0x9c, 0x73, - 0xf0, 0xe5, 0x8d, 0x10, 0x78, 0x2e, 0xf9, 0xc1, 0xca, 0xee, 0x02, 0xa7, - 0x15, 0x03, 0x0b, 0x85, 0x8a, 0xe5, 0x63, 0x50, 0xa5, 0x19, 0xbe, 0xad, - 0x6f, 0x35, 0x29, 0xa9, 0xad, 0xd8, 0x28, 0x0a, 0x34, 0x2b, 0x96, 0x13, - 0x19, 0x39, 0x73, 0x1e, 0xcb, 0xca, 0x40, 0x5a, 0x83, 0xa5, 0xe9, 0xb2, - 0x39, 0x36, 0xf5, 0xba, 0x5e, 0x84, 0x2e, 0x43, 0x9c, 0x6c, 0x92, 0x0e, - 0xb3, 0xc4, 0xd7, 0x27, 0x72, 0xe5, 0xca, 0x24, 0xb8, 0x28, 0xc5, 0x00, - 0xa7, 0x6c, 0xac, 0xc2, 0xb5, 0xc3, 0x53, 0x71, 0x08, 0xcd, 0x9c, 0xf9, - 0x0a, 0x07, 0x17, 0xcb, 0x5c, 0x52, 0x22, 0x3a, 0xe7, 0x96, 0x92, 0xaf, - 0xcd, 0xc3, 0x14, 0x7b, 0xb4, 0x35, 0xb6, 0x61, 0xa1, 0xd6, 0x20, 0xea, - 0x2e, 0x01, 0xac, 0x51, 0x4d, 0x45, 0x05, 0xb4, 0xc6, 0x0d, 0xa4, 0xf0, - 0x4e, 0x8a, 0x89, 0xa7, 0xcd, 0xb5, 0xdd, 0x15, 0xa7, 0xc6, 0xf3, 0x83, - 0xe4, 0xf1, 0xa3, 0x47, 0x8f, 0xd8, 0xc7, 0xd9, 0x39, 0xa2, 0x9e, 0xde, - 0x1c, 0x1e, 0x1c, 0xbf, 0x7a, 0x75, 0xf8, 0xfa, 0xd9, 0xe1, 0x33, 0x83, - 0x6d, 0xd0, 0xa1, 0xda, 0xe6, 0x9f, 0x93, 0xa0, 0x3b, 0x50, 0xa3, 0xf3, - 0xf6, 0xa3, 0xad, 0xde, 0xce, 0xa3, 0xad, 0x04, 0xe8, 0x29, 0xe5, 0x0c, - 0x62, 0x9c, 0x54, 0x3a, 0x46, 0xb0, 0x85, 0xe4, 0x72, 0x3e, 0x49, 0x09, - 0x87, 0x1a, 0x8d, 0x1e, 0x95, 0x01, 0x4b, 0x4e, 0xb3, 0x9a, 0x0a, 0x0a, - 0x27, 0x94, 0x6c, 0xd7, 0xd1, 0x9c, 0x05, 0xae, 0x5b, 0x14, 0x82, 0x0b, - 0x44, 0x21, 0x21, 0x7a, 0xdb, 0xd9, 0xc2, 0x2e, 0x40, 0x88, 0xc9, 0x11, - 0x04, 0xe5, 0x43, 0xc2, 0xba, 0x58, 0x89, 0xa5, 0x17, 0xc2, 0x1b, 0x51, - 0xdd, 0x2a, 0xda, 0x9e, 0x5d, 0x44, 0x25, 0x9b, 0x54, 0x16, 0xf0, 0xb1, - 0xfc, 0x30, 0x7c, 0x3e, 0xe4, 0xd5, 0xe5, 0x7d, 0x3e, 0xda, 0xda, 0x5a, - 0x8d, 0xd3, 0x4f, 0xd2, 0x0f, 0xf4, 0x9e, 0x42, 0xb1, 0xb6, 0xc3, 0xc2, - 0x61, 0x4f, 0x54, 0x64, 0x83, 0x3d, 0x04, 0xa0, 0x10, 0x3f, 0xcd, 0x67, - 0x0d, 0xac, 0x4a, 0x54, 0x5d, 0x2c, 0xf4, 0xe6, 0xe8, 0x04, 0x69, 0xf5, - 0xc5, 0xfe, 0x09, 0xbe, 0x95, 0x9c, 0xbc, 0x39, 0xfe, 0xf9, 0x2f, 0x21, - 0x31, 0xfe, 0x6a, 0xdb, 0x92, 0x26, 0x98, 0x0f, 0x2b, 0x88, 0x3e, 0x48, - 0xaf, 0x53, 0xc9, 0xf6, 0x16, 0xeb, 0x45, 0xc3, 0x6a, 0x81, 0xde, 0x77, - 0x2a, 0x82, 0x14, 0xaa, 0xc8, 0xc5, 0x47, 0x04, 0x61, 0x71, 0x25, 0xf1, - 0xc9, 0x50, 0xca, 0x86, 0x92, 0x4e, 0x0b, 0x72, 0x68, 0xae, 0x3a, 0x09, - 0xf4, 0x40, 0x36, 0x7a, 0xa0, 0x85, 0x87, 0x74, 0x47, 0x5c, 0x70, 0x3d, - 0xaf, 0xa9, 0x22, 0x25, 0x63, 0x12, 0xdd, 0x5f, 0xb7, 0xfa, 0xfd, 0x9d, - 0x47, 0x8f, 0x7e, 0x45, 0x5b, 0xaa, 0x62, 0x5d, 0x49, 0x29, 0x81, 0x44, - 0xb5, 0x4c, 0x05, 0x28, 0x2c, 0x11, 0x49, 0x1a, 0x83, 0xc5, 0x58, 0x64, - 0x71, 0x75, 0xc4, 0xce, 0x6f, 0xac, 0x2b, 0x42, 0x58, 0x1c, 0x12, 0xaf, - 0x90, 0xcc, 0x96, 0x90, 0x0f, 0x43, 0xf2, 0x15, 0xa6, 0x99, 0x48, 0xd0, - 0xe2, 0xdf, 0xb3, 0xb2, 0xd0, 0x72, 0x03, 0x04, 0x88, 0x8e, 0x49, 0x06, - 0xb5, 0x16, 0x47, 0x02, 0x65, 0x69, 0xca, 0x46, 0x6a, 0xab, 0x7e, 0xa6, - 0x23, 0x82, 0x3b, 0x48, 0x4a, 0x97, 0xa4, 0x57, 0x45, 0x8e, 0x89, 0xb3, - 0x37, 0x01, 0xfd, 0x9d, 0x2a, 0xae, 0xcf, 0x19, 0xf0, 0x90, 0xae, 0x8e, - 0x62, 0x50, 0x63, 0xe8, 0x9f, 0xb4, 0xd2, 0x6f, 0xe1, 0x6f, 0xba, 0xa4, - 0x8b, 0x6b, 0x2a, 0x2b, 0x4a, 0xc3, 0x78, 0x88, 0x8c, 0xf5, 0x43, 0x6a, - 0xd0, 0x90, 0xc3, 0xfc, 0xc2, 0x8c, 0x64, 0xeb, 0x20, 0xee, 0x63, 0x9c, - 0x56, 0x29, 0x66, 0x6e, 0x72, 0xc0, 0x13, 0xbe, 0x0c, 0xf1, 0x11, 0x5c, - 0x21, 0x4e, 0x1b, 0xb3, 0x75, 0xe1, 0x00, 0x03, 0x5c, 0x91, 0xae, 0x17, - 0x7e, 0x29, 0x29, 0x84, 0x50, 0x28, 0x89, 0x07, 0x60, 0x7d, 0x04, 0x58, - 0x51, 0xc9, 0x23, 0xa3, 0x26, 0x12, 0xc6, 0xaf, 0x1a, 0x48, 0xc0, 0x09, - 0xd7, 0x34, 0x11, 0x6f, 0x7a, 0x89, 0x1c, 0xcd, 0x60, 0x0e, 0xb0, 0x11, - 0x52, 0x0a, 0x65, 0xb3, 0x29, 0x84, 0xa8, 0xa0, 0xc2, 0x19, 0x5c, 0xc6, - 0x97, 0x37, 0x40, 0xb9, 0x6c, 0x5d, 0xb8, 0x75, 0x0a, 0x69, 0x2a, 0x30, - 0x5f, 0xba, 0xfb, 0xcf, 0x51, 0xa1, 0xa5, 0x65, 0xd2, 0xbd, 0x86, 0xd5, - 0xda, 0xde, 0x31, 0xe8, 0x84, 0x63, 0x95, 0x9e, 0xbb, 0xb4, 0x1f, 0x5a, - 0x94, 0x44, 0x12, 0x48, 0x78, 0x38, 0x9a, 0x97, 0xc0, 0x1e, 0x1a, 0x3b, - 0x47, 0x1c, 0x9b, 0x91, 0x59, 0xb4, 0x60, 0x48, 0x28, 0x39, 0xaa, 0x75, - 0x8a, 0x95, 0x3f, 0xa3, 0x76, 0xce, 0xf2, 0x91, 0xea, 0x1a, 0x79, 0x6d, - 0x5e, 0x64, 0x57, 0x10, 0x39, 0x14, 0x31, 0x16, 0x89, 0x8b, 0xd3, 0xec, - 0x47, 0xe3, 0xf4, 0x22, 0xe2, 0x6b, 0xf1, 0xc9, 0xff, 0x8c, 0xb8, 0x96, - 0x0b, 0x7d, 0xfd, 0xb7, 0xa3, 0x93, 0x45, 0xbc, 0xf7, 0x9d, 0xc5, 0x02, - 0xb6, 0x1f, 0x6e, 0x16, 0x38, 0x95, 0xae, 0x42, 0x83, 0x49, 0x51, 0x8a, - 0xc0, 0x9d, 0x7c, 0x49, 0x43, 0x70, 0x3d, 0x4b, 0x8a, 0xb2, 0xcd, 0xcc, - 0x56, 0x6b, 0x3e, 0x33, 0x56, 0x5d, 0x30, 0x7f, 0xad, 0xa0, 0xda, 0x3a, - 0x29, 0x25, 0x55, 0xd0, 0x65, 0x25, 0x40, 0xd7, 0x58, 0x55, 0x0d, 0x3d, - 0xc3, 0x12, 0xf3, 0x0b, 0x23, 0xc8, 0x1b, 0x70, 0x8a, 0x91, 0x0f, 0x96, - 0x00, 0xf0, 0x5b, 0xfc, 0xa5, 0xcb, 0x6a, 0xdf, 0xcc, 0x4a, 0x38, 0x79, - 0x65, 0x3e, 0xbe, 0xb1, 0x2b, 0x9b, 0x0c, 0xcf, 0x9a, 0xe1, 0x45, 0x81, - 0x38, 0xae, 0x4e, 0x6f, 0x11, 0x10, 0x97, 0x41, 0x3f, 0xcf, 0x07, 0x9a, - 0xa5, 0xca, 0xd8, 0xa2, 0x95, 0xaa, 0xa7, 0xbc, 0x20, 0xcd, 0xa8, 0xb7, - 0xf6, 0x45, 0xbe, 0xdf, 0x7a, 0x54, 0xcd, 0x3e, 0x56, 0x23, 0x9d, 0x50, - 0xa9, 0x66, 0x25, 0xf0, 0xdf, 0xad, 0xdb, 0x68, 0xe9, 0xa8, 0x2b, 0x4a, - 0x67, 0xa3, 0x48, 0x4e, 0xf2, 0xfc, 0xe8, 0xe5, 0xe1, 0x06, 0xdc, 0x46, - 0x19, 0x95, 0xfe, 0x0e, 0x39, 0x9a, 0x9c, 0x9e, 0xf3, 0x6f, 0xa4, 0x65, - 0x5b, 0x11, 0x45, 0x09, 0xc7, 0xf6, 0xf1, 0xa2, 0x62, 0xf1, 0x25, 0x5d, - 0xd4, 0xf0, 0x07, 0x98, 0x86, 0x78, 0x67, 0x50, 0x75, 0xd3, 0x5c, 0x22, - 0x0d, 0xfc, 0x52, 0xda, 0xa4, 0x54, 0x6e, 0xcd, 0x09, 0x66, 0xdc, 0xad, - 0xbe, 0xab, 0x64, 0x53, 0xf8, 0x08, 0x4c, 0x1c, 0xa8, 0x24, 0x71, 0x72, - 0x04, 0x58, 0x5e, 0x01, 0xbf, 0xb8, 0xa9, 0x02, 0xde, 0x81, 0x06, 0x64, - 0x09, 0xb0, 0x05, 0x1f, 0xdb, 0x49, 0x31, 0x74, 0x85, 0x9d, 0xb8, 0x50, - 0x76, 0xb3, 0x24, 0x99, 0xe6, 0x75, 0xdc, 0x87, 0xc6, 0x7c, 0xe9, 0xa0, - 0x3d, 0x5b, 0xb7, 0xf7, 0x68, 0x35, 0x61, 0x06, 0x96, 0x0d, 0xb7, 0x0c, - 0x96, 0xfd, 0xbc, 0xa8, 0x0c, 0x73, 0xbb, 0x04, 0x06, 0xd9, 0x4b, 0xab, - 0x41, 0x9e, 0xeb, 0xc6, 0xbe, 0xd0, 0x8d, 0xc5, 0x78, 0x67, 0xfe, 0x77, - 0xf3, 0xbb, 0x26, 0xfc, 0x36, 0xe3, 0xdb, 0x60, 0xe2, 0xc2, 0x06, 0x0c, - 0x0a, 0x67, 0x22, 0x6f, 0xd0, 0x89, 0x05, 0x81, 0x60, 0x48, 0xd8, 0x0c, - 0xf9, 0x94, 0x33, 0xed, 0xf8, 0xd6, 0x27, 0x90, 0xaf, 0x9f, 0x2c, 0x92, - 0x83, 0x76, 0x44, 0x14, 0x01, 0x35, 0xbf, 0xe8, 0x19, 0x34, 0xae, 0x2c, - 0x15, 0x27, 0xc4, 0x58, 0xa1, 0x78, 0x20, 0xfa, 0x98, 0xcf, 0x96, 0xad, - 0xbc, 0x1c, 0x04, 0xed, 0xd1, 0x08, 0x0d, 0x94, 0xe7, 0xd5, 0xd1, 0xab, - 0x43, 0x49, 0xee, 0x47, 0xdc, 0x29, 0xcc, 0x9e, 0xe2, 0x1a, 0x14, 0x8a, - 0xc9, 0x45, 0x39, 0x08, 0x0a, 0x13, 0x68, 0x4e, 0x3a, 0x61, 0x1e, 0x99, - 0xd8, 0x4c, 0x9c, 0x23, 0x9c, 0x90, 0xeb, 0xe9, 0xc4, 0x53, 0xd3, 0x1e, - 0x06, 0x8e, 0x37, 0x15, 0xee, 0x49, 0x15, 0x8d, 0x79, 0x45, 0x28, 0x73, - 0xa2, 0x4e, 0x8c, 0x7f, 0xd2, 0x20, 0x14, 0x25, 0x70, 0x0c, 0xec, 0x0f, - 0xb4, 0x96, 0xa3, 0x3a, 0x71, 0xb6, 0x40, 0x2e, 0xe5, 0x8d, 0xb7, 0xb0, - 0x38, 0x12, 0xa2, 0x09, 0xd8, 0x84, 0xd1, 0x8b, 0x4f, 0x29, 0x10, 0xe6, - 0x46, 0x47, 0xa9, 0x46, 0x6e, 0x63, 0x3c, 0x11, 0x99, 0xdb, 0x21, 0xbc, - 0xbc, 0x5c, 0x69, 0x05, 0xbc, 0x06, 0x6f, 0x8a, 0x79, 0x54, 0x25, 0x18, - 0x33, 0xc3, 0x51, 0x13, 0xf3, 0xc9, 0xe1, 0xfc, 0x34, 0xf1, 0x2c, 0xf3, - 0xb5, 0x71, 0xc0, 0x77, 0x5a, 0x69, 0xd0, 0x69, 0x4b, 0xc4, 0x58, 0x31, - 0xd5, 0x50, 0x9c, 0x6b, 0x0b, 0x77, 0xed, 0x0a, 0x7e, 0xc6, 0x07, 0x7e, - 0x06, 0xcd, 0xdb, 0x78, 0x15, 0x86, 0xc4, 0x5d, 0x97, 0xd6, 0xe5, 0x50, - 0x72, 0xb0, 0x5b, 0xdf, 0x6e, 0xec, 0x7e, 0x41, 0xfb, 0x08, 0x6c, 0x0e, - 0x85, 0x80, 0x30, 0x5a, 0x35, 0x48, 0x11, 0x83, 0xf7, 0xb9, 0x3a, 0x85, - 0xaa, 0x7a, 0x3e, 0xa2, 0x11, 0xa6, 0xe6, 0x6e, 0x94, 0x11, 0x69, 0x54, - 0x24, 0x2e, 0x7c, 0x9f, 0x17, 0xd3, 0x82, 0x73, 0x49, 0x26, 0x50, 0x39, - 0x22, 0x9e, 0xda, 0xf8, 0xc6, 0x8d, 0xba, 0x32, 0x5b, 0x0b, 0xe2, 0xc0, - 0xe0, 0x46, 0x23, 0x56, 0x59, 0x46, 0xb2, 0x0e, 0x39, 0x99, 0xaf, 0x15, - 0xe1, 0x3c, 0xc0, 0x72, 0x0e, 0x0b, 0xf2, 0x4a, 0xbd, 0xc9, 0x26, 0xc5, - 0x95, 0xab, 0xc1, 0x8e, 0xb3, 0x93, 0xa5, 0xc0, 0xa0, 0x0e, 0xd1, 0xd2, - 0x53, 0x1d, 0x04, 0xc7, 0xfb, 0xc6, 0xf5, 0x1e, 0x25, 0x31, 0x57, 0x50, - 0x5a, 0x39, 0x44, 0x03, 0x81, 0x8a, 0x0d, 0xd6, 0x85, 0xa4, 0xbf, 0x2e, - 0x01, 0x8b, 0x4f, 0xf7, 0xe0, 0x84, 0x27, 0x9d, 0x17, 0x45, 0x55, 0xef, - 0x75, 0xb8, 0x78, 0x40, 0xd8, 0xfe, 0x4c, 0x12, 0x7e, 0x74, 0xeb, 0x75, - 0x20, 0x6c, 0x1f, 0x04, 0x5e, 0x24, 0x21, 0x0b, 0x1c, 0x51, 0x57, 0xdb, - 0x0d, 0x18, 0x20, 0x29, 0xb4, 0x94, 0x65, 0x33, 0xe7, 0xd7, 0xd0, 0x0f, - 0x04, 0x00, 0x07, 0x4b, 0xd6, 0xc2, 0x30, 0x7e, 0xee, 0x1d, 0x50, 0x4f, - 0xbd, 0x17, 0xd4, 0xce, 0xd7, 0x1d, 0x29, 0xca, 0xa2, 0xd9, 0x70, 0xcd, - 0x07, 0xf6, 0x2c, 0x60, 0x94, 0xb6, 0x90, 0xcd, 0xc2, 0x54, 0x35, 0x82, - 0xc8, 0x93, 0x63, 0xa8, 0x65, 0x4c, 0x84, 0x27, 0x3f, 0x1c, 0x6e, 0xaa, - 0xa0, 0xab, 0x18, 0xfd, 0x96, 0x9b, 0x61, 0xa2, 0x06, 0xca, 0xdf, 0xd0, - 0x65, 0xaf, 0x18, 0xf5, 0x28, 0x6b, 0x18, 0x24, 0x85, 0xf7, 0x28, 0x5c, - 0x53, 0x64, 0x8a, 0x50, 0x02, 0xe1, 0xd3, 0xd1, 0x99, 0x1c, 0x0e, 0xc5, - 0x2c, 0x53, 0x29, 0x8c, 0x91, 0x69, 0x4d, 0xee, 0x22, 0xd2, 0x5d, 0xd9, - 0xb3, 0x5a, 0x52, 0xf8, 0xe2, 0x34, 0xbb, 0xe6, 0xac, 0x4f, 0x64, 0x4c, - 0x9a, 0x6d, 0x6f, 0x98, 0x91, 0xa1, 0x36, 0x83, 0x96, 0x7d, 0x9d, 0xb0, - 0xab, 0x9d, 0x23, 0x16, 0xe6, 0x33, 0x36, 0xe6, 0xc0, 0xb0, 0xc4, 0xa4, - 0x4c, 0x9e, 0x2f, 0x6a, 0x4d, 0x13, 0xb2, 0x80, 0xb9, 0x03, 0xb7, 0x9d, - 0x28, 0xcd, 0x93, 0x20, 0x8d, 0xd3, 0xb8, 0xa0, 0xa0, 0xce, 0x40, 0x39, - 0xc4, 0x22, 0x80, 0xa9, 0x73, 0x5a, 0x79, 0xc9, 0xea, 0x44, 0x42, 0xe8, - 0xd0, 0x17, 0x73, 0x8c, 0xee, 0x25, 0xd1, 0x5e, 0xd1, 0x90, 0x84, 0xa3, - 0x53, 0x61, 0xc8, 0x3a, 0x63, 0x08, 0x00, 0xba, 0x40, 0xcc, 0x85, 0xbe, - 0x90, 0xb7, 0x7a, 0xd6, 0x0c, 0x06, 0xa5, 0x3a, 0x8a, 0x14, 0x6a, 0xa4, - 0x51, 0xeb, 0xc0, 0xf6, 0xbf, 0x0b, 0x90, 0x1c, 0x55, 0x7d, 0x83, 0x37, - 0x71, 0x40, 0x1c, 0x9a, 0x9a, 0xa2, 0x15, 0x12, 0xfe, 0x43, 0x24, 0x3a, - 0x6d, 0x94, 0x68, 0xa4, 0x84, 0x3c, 0x24, 0x85, 0x1e, 0x38, 0xa3, 0xe1, - 0xbb, 0x9e, 0x0f, 0x03, 0x54, 0x97, 0x5d, 0x3a, 0xf4, 0x3b, 0xc4, 0x69, - 0x00, 0x06, 0xc8, 0x65, 0x41, 0x9f, 0x63, 0x0c, 0x0c, 0x72, 0xf1, 0x42, - 0x70, 0xe1, 0x23, 0x80, 0x18, 0x88, 0xdc, 0x3d, 0x98, 0xf8, 0x24, 0x01, - 0x0d, 0x68, 0x9c, 0xd7, 0xa4, 0xda, 0x51, 0xa5, 0x55, 0x31, 0xe8, 0xa3, - 0x7e, 0x2b, 0x10, 0x13, 0x82, 0x7d, 0x48, 0x67, 0x85, 0xec, 0x45, 0x9a, - 0x43, 0x46, 0x37, 0x05, 0x67, 0xee, 0x0a, 0xdf, 0xd8, 0xd3, 0x30, 0x71, - 0x52, 0x65, 0x3b, 0xcf, 0x61, 0x38, 0x7b, 0x1d, 0xb8, 0x42, 0x3a, 0x67, - 0x05, 0xfc, 0x2b, 0x87, 0xe0, 0x19, 0x9c, 0xa4, 0x3d, 0xae, 0x9b, 0xd7, - 0x39, 0x65, 0x3c, 0x2b, 0xfc, 0x73, 0x52, 0xa0, 0xe8, 0x5d, 0x5f, 0x32, - 0x3c, 0x05, 0xe3, 0x22, 0x69, 0x91, 0x77, 0xba, 0x35, 0x95, 0xd2, 0xe3, - 0x5a, 0x05, 0xfe, 0xd6, 0x60, 0x38, 0x5a, 0x2d, 0x12, 0x1a, 0xae, 0x70, - 0x66, 0x05, 0x31, 0x17, 0xa8, 0x88, 0x3f, 0x4d, 0x43, 0x86, 0xb8, 0x86, - 0x2d, 0x2a, 0xb0, 0xdf, 0x87, 0x9b, 0x28, 0x70, 0x16, 0x07, 0x87, 0xdb, - 0x0d, 0x73, 0x69, 0xa6, 0x6f, 0xef, 0x25, 0x0c, 0x78, 0x95, 0x0d, 0x3b, - 0x81, 0xc7, 0x90, 0xf7, 0x87, 0x98, 0x62, 0xa3, 0x69, 0x75, 0xb5, 0x68, - 0xe6, 0xb6, 0xfe, 0x8d, 0x79, 0xf1, 0x5d, 0x75, 0x0d, 0x71, 0x4e, 0x85, - 0x32, 0x30, 0xf6, 0x7d, 0x38, 0xb8, 0x22, 0xe9, 0xce, 0x32, 0xd5, 0x17, - 0x6a, 0xe3, 0xea, 0x1c, 0x91, 0xa7, 0x4b, 0xa4, 0xbd, 0x03, 0x5c, 0xc5, - 0x90, 0xb0, 0x8c, 0x28, 0x96, 0x5c, 0x50, 0x7e, 0x58, 0x95, 0x62, 0x1f, - 0x48, 0x8d, 0x04, 0x89, 0x3e, 0x28, 0x33, 0x0e, 0x3a, 0xd2, 0x8a, 0x9f, - 0x06, 0xa6, 0xd0, 0x4d, 0x18, 0x3c, 0x48, 0x26, 0x5c, 0x63, 0xf1, 0xab, - 0x58, 0xbc, 0xc7, 0x54, 0x6a, 0xa7, 0x3f, 0xe1, 0xe9, 0x19, 0x13, 0xed, - 0x16, 0x91, 0xa8, 0xcb, 0x65, 0x15, 0x2b, 0x29, 0xb1, 0x2b, 0xb5, 0x17, - 0xc8, 0xb8, 0xab, 0x6c, 0x24, 0xe5, 0xe3, 0x51, 0xc0, 0x8d, 0x90, 0xd3, - 0xb5, 0x52, 0xa0, 0x60, 0x85, 0x48, 0xfd, 0x15, 0x96, 0xc5, 0x23, 0x4d, - 0xde, 0x84, 0xf3, 0x40, 0x3c, 0xac, 0xac, 0x85, 0x11, 0x0d, 0x52, 0xae, - 0xf9, 0x2b, 0xc8, 0xca, 0x5a, 0xfd, 0x3d, 0x80, 0x34, 0x84, 0xc9, 0xf6, - 0x83, 0xe8, 0xa8, 0xea, 0xfb, 0xa7, 0xe6, 0x68, 0x37, 0xdc, 0x42, 0x74, - 0x59, 0x3c, 0x47, 0x6b, 0x6e, 0xef, 0x35, 0xf0, 0x8b, 0xbd, 0xe4, 0x3f, - 0x8b, 0xec, 0x6e, 0x37, 0x0f, 0xbc, 0xf5, 0x16, 0x54, 0x8d, 0xde, 0xfe, - 0x05, 0xb1, 0xe2, 0x9b, 0xac, 0xea, 0xcd, 0xe8, 0x7c, 0x6f, 0xee, 0x6c, - 0x6d, 0x6d, 0xad, 0xf4, 0x3e, 0xdf, 0x94, 0x2b, 0x3c, 0xf9, 0x9d, 0xca, - 0x57, 0xb7, 0x57, 0x57, 0x69, 0xa4, 0x1c, 0xf6, 0xd2, 0x8b, 0xcc, 0xf2, - 0xc9, 0x38, 0x33, 0xd6, 0x52, 0xca, 0x2e, 0x59, 0x12, 0x1f, 0xcf, 0x92, - 0xa7, 0xa8, 0x01, 0x5f, 0x14, 0xe5, 0xcd, 0xb7, 0x0a, 0x32, 0x8e, 0xf7, - 0x06, 0x7e, 0xd5, 0x4f, 0xa8, 0xc4, 0x1d, 0xd1, 0xa5, 0x46, 0x51, 0x85, - 0x25, 0x0d, 0xb5, 0x71, 0x1d, 0x0c, 0x12, 0xe7, 0xec, 0xe8, 0xde, 0x72, - 0xbb, 0x71, 0x51, 0x1b, 0x97, 0x59, 0xe4, 0xed, 0x19, 0x0a, 0x64, 0x1e, - 0x2b, 0x4a, 0xcc, 0x1f, 0x11, 0x51, 0x15, 0xf4, 0x6f, 0x60, 0x93, 0xb1, - 0x1a, 0x47, 0xa3, 0xd0, 0xe6, 0x22, 0x11, 0x5d, 0xbb, 0xc6, 0xa1, 0x37, - 0x35, 0x30, 0x9a, 0x34, 0x32, 0x19, 0x9c, 0x96, 0xcc, 0xc1, 0x0d, 0x31, - 0xbc, 0xcb, 0x69, 0xa8, 0xea, 0xa1, 0xd0, 0xe4, 0x35, 0x37, 0x42, 0x3a, - 0xaf, 0xae, 0x06, 0x18, 0x35, 0x1d, 0xcd, 0x3d, 0xcf, 0xee, 0x48, 0x21, - 0xa3, 0xc1, 0x40, 0x3b, 0x8b, 0x1b, 0x28, 0xba, 0x54, 0x30, 0xaf, 0xc0, - 0x4a, 0xcc, 0xe6, 0xe7, 0x93, 0xe1, 0xa3, 0xe4, 0x29, 0xfc, 0x50, 0x85, - 0x89, 0x52, 0xfd, 0x4e, 0x0f, 0x30, 0xfe, 0x9d, 0x92, 0xee, 0x53, 0xbb, - 0x9a, 0xc5, 0x75, 0x47, 0x87, 0x68, 0x77, 0xa7, 0xcd, 0x48, 0x18, 0xd5, - 0xaf, 0xe3, 0x97, 0x54, 0x24, 0x39, 0x67, 0x9b, 0xc8, 0xf6, 0xce, 0x93, - 0x04, 0x4d, 0x6c, 0xc9, 0xab, 0x67, 0x8f, 0xe4, 0x4a, 0xaa, 0xe6, 0x13, - 0x93, 0xfd, 0x38, 0xad, 0x8d, 0x39, 0x83, 0xe2, 0x2d, 0x72, 0xf1, 0x44, - 0x84, 0x4c, 0xea, 0x6a, 0x18, 0xdd, 0x28, 0xc4, 0xd1, 0x39, 0xef, 0x43, - 0xc8, 0x63, 0xc5, 0xd7, 0x35, 0x83, 0xc1, 0x29, 0xeb, 0xd2, 0x1b, 0xba, - 0x66, 0x40, 0xdd, 0xef, 0x4b, 0x38, 0xac, 0x5b, 0x87, 0x3b, 0x03, 0x62, - 0xc5, 0x0b, 0xf1, 0x29, 0x06, 0xb1, 0xd0, 0x4b, 0xf6, 0x68, 0xb0, 0x3d, - 0x78, 0xf8, 0xd5, 0xd6, 0xce, 0xd6, 0xe3, 0x87, 0x5b, 0xe9, 0xa3, 0xf4, - 0x7c, 0x6b, 0xb4, 0xb3, 0xb5, 0xfb, 0xf0, 0xc9, 0xa3, 0x87, 0x83, 0xdd, - 0x9d, 0xed, 0xf4, 0x49, 0x52, 0xad, 0x12, 0xa3, 0x26, 0x0d, 0x56, 0x97, - 0xe9, 0xce, 0xa3, 0xc7, 0xcd, 0x4d, 0xe5, 0x4f, 0x93, 0xa7, 0xfc, 0xef, - 0xe2, 0xd6, 0xd2, 0xce, 0xa2, 0xa4, 0xbb, 0xb8, 0xb3, 0x69, 0xf2, 0x3d, - 0x61, 0x61, 0xf4, 0xd4, 0x19, 0x7a, 0xfa, 0x62, 0x1f, 0xdb, 0x42, 0x75, - 0xea, 0x32, 0x12, 0x1e, 0x65, 0xb3, 0x78, 0xaf, 0x74, 0x9b, 0x70, 0x9f, - 0xfa, 0xc9, 0x81, 0xdf, 0xa7, 0xc6, 0x36, 0x35, 0xac, 0xc0, 0x7e, 0xaf, - 0xe8, 0x6f, 0xe8, 0x26, 0xd3, 0x2d, 0x8a, 0x80, 0x92, 0xc5, 0xfa, 0x12, - 0x4a, 0x83, 0xaa, 0x37, 0x48, 0xc2, 0x23, 0x9c, 0x8a, 0x8c, 0x5f, 0x55, - 0xd5, 0x25, 0xd7, 0xb5, 0x69, 0x24, 0xa6, 0x92, 0x57, 0x89, 0x9f, 0xe2, - 0x7b, 0xe8, 0xf4, 0xf4, 0x85, 0xc2, 0x20, 0x57, 0x0d, 0xa2, 0x90, 0x75, - 0xfc, 0x7c, 0x6e, 0x9f, 0xa8, 0x9b, 0xd7, 0xcf, 0x7e, 0x7c, 0xff, 0xea, - 0xec, 0xcf, 0x1f, 0x5e, 0xfd, 0xf0, 0xe7, 0xed, 0xe3, 0x67, 0xc3, 0xc9, - 0xab, 0xdf, 0xfe, 0xbc, 0xfb, 0xea, 0xb7, 0xc1, 0xdf, 0xff, 0xf2, 0xdb, - 0xfe, 0xcd, 0xf1, 0xd9, 0x5f, 0x1e, 0xbd, 0x9a, 0xbc, 0x79, 0xff, 0xea, - 0xb7, 0x1f, 0x27, 0xaf, 0x9f, 0xfd, 0xf9, 0x9b, 0x5b, 0x88, 0xc4, 0xe3, - 0x3d, 0x34, 0xad, 0x62, 0x81, 0x0c, 0x03, 0xc9, 0xa0, 0x11, 0xb1, 0xb5, - 0x8c, 0xf4, 0xe9, 0x46, 0x72, 0x48, 0xd1, 0xa4, 0xc9, 0x8b, 0xd3, 0xb3, - 0x53, 0xb3, 0x68, 0x5b, 0x1c, 0x92, 0x7a, 0x52, 0x4d, 0x2e, 0x9e, 0x81, - 0x40, 0x54, 0x57, 0x82, 0xeb, 0x29, 0xa1, 0x3c, 0x1f, 0x38, 0x88, 0x39, - 0xe1, 0x36, 0xa8, 0x8c, 0x59, 0x66, 0x70, 0x64, 0x96, 0xdf, 0x20, 0xb1, - 0x27, 0xc9, 0x3e, 0x0b, 0x24, 0x29, 0x33, 0x65, 0x98, 0x98, 0x41, 0x8a, - 0x6a, 0xaf, 0xbc, 0xd8, 0xdc, 0x4c, 0x5e, 0x69, 0x49, 0xe6, 0x22, 0x89, - 0x47, 0xc2, 0x76, 0x29, 0x2e, 0x01, 0x65, 0xd8, 0x00, 0x86, 0x17, 0x4e, - 0xfc, 0xd7, 0xb1, 0x68, 0x2d, 0x2c, 0x42, 0xf2, 0x8d, 0xd4, 0xf9, 0xc4, - 0x05, 0x80, 0xf5, 0x65, 0xc6, 0xee, 0x62, 0xa1, 0xa8, 0x16, 0x8c, 0x9c, - 0x14, 0xcb, 0x02, 0x51, 0x19, 0xa6, 0xe6, 0xf9, 0x06, 0xff, 0x93, 0x9b, - 0x34, 0x5b, 0x89, 0xe6, 0xb3, 0x8b, 0x32, 0x1d, 0xca, 0xa9, 0x70, 0x65, - 0x33, 0x0a, 0x57, 0x33, 0x87, 0x2b, 0xc7, 0x27, 0x87, 0xa4, 0x20, 0x52, - 0x0b, 0xb2, 0x6a, 0x70, 0x2b, 0xc1, 0x35, 0x42, 0xf3, 0x21, 0xd8, 0xa8, - 0x21, 0xe8, 0xdb, 0xe8, 0x2d, 0x47, 0x7a, 0x1f, 0x71, 0x40, 0x95, 0xc8, - 0x74, 0x0a, 0x44, 0x9e, 0x8b, 0x59, 0x53, 0xba, 0x65, 0xd7, 0x41, 0x02, - 0xaa, 0x2d, 0xe2, 0x4d, 0x08, 0x44, 0x79, 0x58, 0x8a, 0x53, 0xcb, 0x6c, - 0xe8, 0x74, 0x02, 0xbc, 0x61, 0xb2, 0x8e, 0x0e, 0x94, 0x44, 0xc0, 0x7f, - 0x36, 0x9c, 0x43, 0x4a, 0x30, 0x9d, 0x37, 0x15, 0x21, 0xdf, 0xd4, 0x89, - 0x90, 0xdc, 0x42, 0x70, 0xc4, 0x88, 0x7c, 0xae, 0x54, 0x04, 0x0b, 0xc3, - 0x58, 0xbd, 0x6e, 0xfd, 0xeb, 0xd8, 0x00, 0x1e, 0x61, 0x59, 0xc8, 0x09, - 0xa3, 0xc6, 0x38, 0xda, 0x3d, 0xc0, 0x00, 0x73, 0xca, 0xc5, 0x38, 0xe4, - 0x48, 0x09, 0xa6, 0xb4, 0x84, 0x76, 0xf0, 0x91, 0x2c, 0xa4, 0x64, 0xa6, - 0x55, 0xf2, 0xe5, 0xd1, 0xf6, 0x95, 0xf4, 0x7f, 0xa7, 0xe8, 0xd7, 0x3c, - 0xd1, 0xdc, 0x24, 0x6c, 0xd7, 0xea, 0x85, 0xeb, 0x30, 0x26, 0xbb, 0x69, - 0xbb, 0xae, 0x8b, 0x70, 0x40, 0xa1, 0x8d, 0xad, 0xfe, 0x57, 0x91, 0xfb, - 0x63, 0x9f, 0xfc, 0x4c, 0x86, 0x9e, 0xab, 0xa5, 0xcf, 0x10, 0xdc, 0xbd, - 0x59, 0xfa, 0x0f, 0x1f, 0xd8, 0xc4, 0x2f, 0x08, 0x8b, 0x2e, 0xd4, 0x69, - 0xb3, 0x78, 0x1b, 0x11, 0xaa, 0x25, 0x0b, 0x90, 0xeb, 0x87, 0x58, 0x08, - 0x8f, 0xab, 0xfb, 0xa3, 0xd1, 0x1c, 0x41, 0x53, 0x33, 0x40, 0x49, 0x57, - 0xa3, 0x4b, 0xd5, 0x3b, 0x50, 0x3c, 0xc7, 0x6c, 0xfe, 0x4e, 0x9b, 0xb5, - 0x2d, 0x38, 0x61, 0x85, 0x95, 0x20, 0x2e, 0xb4, 0x42, 0xe7, 0x00, 0xcb, - 0xf4, 0xb1, 0x4f, 0xbf, 0xb8, 0x9e, 0xca, 0x29, 0x21, 0xa0, 0x38, 0x29, - 0xbd, 0xbd, 0x30, 0x21, 0x62, 0x1c, 0x12, 0xca, 0xa2, 0xa0, 0x9b, 0x1a, - 0x9f, 0xec, 0xaa, 0xff, 0xa2, 0x77, 0xe0, 0x71, 0x7f, 0x6b, 0xa3, 0x25, - 0x0a, 0x55, 0x96, 0xf6, 0x13, 0x8a, 0x35, 0x2c, 0x09, 0x50, 0x96, 0x06, - 0xef, 0xe0, 0xfa, 0xd2, 0xeb, 0x6a, 0x8e, 0x8d, 0x26, 0x71, 0xe0, 0x5b, - 0xdb, 0xfd, 0xed, 0xae, 0xfc, 0xba, 0x23, 0xe2, 0x38, 0xfe, 0xbe, 0xab, - 0x34, 0xb3, 0xd5, 0xb5, 0x07, 0xb7, 0x22, 0xba, 0xa1, 0x04, 0x5b, 0x06, - 0x5c, 0xb6, 0x72, 0x79, 0xf0, 0x4c, 0x12, 0x05, 0x0e, 0x6a, 0x8e, 0x6c, - 0xce, 0x8c, 0x4c, 0x4d, 0x88, 0x6a, 0x82, 0x42, 0xb9, 0x1f, 0x71, 0xb7, - 0x3d, 0xe5, 0x35, 0x82, 0xff, 0xa5, 0xeb, 0x25, 0x41, 0xbd, 0x7a, 0x33, - 0x38, 0x9f, 0xc2, 0x9d, 0xeb, 0x85, 0xad, 0xdd, 0x1f, 0xa2, 0x95, 0xad, - 0xa1, 0xfe, 0xb1, 0xd3, 0xf5, 0x24, 0xb1, 0x83, 0xd8, 0x61, 0x45, 0xd9, - 0x43, 0xfb, 0x28, 0x90, 0xd6, 0x85, 0x56, 0x21, 0xd3, 0x55, 0x16, 0x49, - 0x4c, 0x12, 0xd1, 0xc2, 0x86, 0x46, 0xd0, 0x58, 0xd2, 0x47, 0x74, 0x8c, - 0xe1, 0xef, 0x25, 0xdb, 0xe1, 0x76, 0x63, 0xbb, 0x1f, 0x0a, 0x9c, 0xc4, - 0xc8, 0x01, 0x3c, 0x7c, 0xb9, 0x99, 0x44, 0xb9, 0x7a, 0xf3, 0xb2, 0x8a, - 0x63, 0xd1, 0xa4, 0x9f, 0x55, 0x02, 0xee, 0x57, 0x58, 0xf5, 0xed, 0x7b, - 0x5f, 0xf5, 0xad, 0xfb, 0x5c, 0x75, 0xa2, 0xdd, 0xe6, 0xaa, 0xf3, 0x01, - 0x74, 0x0d, 0x2f, 0xac, 0x39, 0xb1, 0x90, 0x1d, 0xaf, 0xe0, 0xd1, 0x9d, - 0xdb, 0xf5, 0xf8, 0x0f, 0xb4, 0x0c, 0x53, 0x50, 0xba, 0x38, 0x02, 0x5e, - 0xde, 0xd1, 0x8b, 0xbd, 0x51, 0x9c, 0xc4, 0xd9, 0x79, 0xc9, 0x23, 0x42, - 0xed, 0x84, 0x14, 0x9c, 0x66, 0x4f, 0x16, 0x33, 0xec, 0xba, 0x0a, 0xd1, - 0x53, 0x24, 0x82, 0xc8, 0x85, 0xad, 0x0e, 0x1c, 0xb6, 0x22, 0x99, 0x9f, - 0x5f, 0x06, 0x33, 0xaf, 0xb4, 0x5c, 0xc9, 0x5b, 0x7e, 0x7e, 0xcf, 0x1e, - 0x15, 0x77, 0xef, 0x42, 0xfd, 0x34, 0x12, 0xc9, 0xe5, 0x75, 0xc2, 0xdb, - 0x91, 0x99, 0xe7, 0xb5, 0x4b, 0x46, 0xd0, 0x88, 0xcb, 0x8a, 0x6b, 0x60, - 0x4f, 0x71, 0xba, 0x12, 0xca, 0xd5, 0xdf, 0x41, 0x13, 0xac, 0x64, 0x36, - 0xb2, 0xef, 0xe2, 0x12, 0x0b, 0xea, 0x59, 0x28, 0x9a, 0xc8, 0xe7, 0x43, - 0x2d, 0x2f, 0xdb, 0x80, 0xdf, 0xc4, 0x24, 0x48, 0x71, 0xa8, 0x95, 0x72, - 0xc3, 0x90, 0x91, 0x1a, 0x57, 0x43, 0x0f, 0x81, 0x34, 0x11, 0xdc, 0x07, - 0xe8, 0xfc, 0x1b, 0x57, 0x57, 0xd0, 0x79, 0x7f, 0x09, 0x17, 0xdf, 0xb9, - 0x17, 0x7a, 0xdf, 0xb9, 0x85, 0xda, 0xf5, 0x89, 0xa0, 0x7f, 0xd0, 0x8c, - 0x55, 0x09, 0xa1, 0x94, 0x1b, 0xd2, 0x40, 0x28, 0xf9, 0x57, 0x50, 0x59, - 0x95, 0xd2, 0xda, 0xaa, 0xb0, 0xd2, 0x89, 0x59, 0x72, 0x64, 0xe4, 0xcc, - 0xb4, 0xb1, 0x2a, 0x3c, 0x41, 0xb7, 0x1f, 0x9b, 0xf8, 0xd4, 0x84, 0x33, - 0xe3, 0x1b, 0x93, 0xaf, 0x03, 0x94, 0x16, 0x5d, 0x5f, 0xe9, 0x78, 0x36, - 0x8d, 0x8f, 0x4e, 0xb3, 0xf1, 0xe8, 0x28, 0x1d, 0x55, 0xd5, 0x1c, 0xf1, - 0x11, 0x50, 0x04, 0xc0, 0x03, 0x11, 0x99, 0x1a, 0x85, 0x38, 0x85, 0xd4, - 0xd8, 0xe6, 0x86, 0xd3, 0x8c, 0xdc, 0x41, 0xf4, 0x2d, 0x72, 0x19, 0xa1, - 0xdf, 0x3e, 0xc5, 0xc2, 0xb8, 0x35, 0xa6, 0xee, 0x13, 0xc7, 0x12, 0x02, - 0xb2, 0x9c, 0x08, 0x1c, 0x51, 0x4d, 0x76, 0x23, 0xed, 0x0a, 0x31, 0x80, - 0xd1, 0xb7, 0x94, 0x5e, 0xa7, 0xa0, 0x90, 0x12, 0x91, 0xbb, 0xa0, 0x09, - 0x16, 0x4f, 0x86, 0x85, 0x3e, 0xee, 0xb2, 0x6e, 0x2c, 0x35, 0xf3, 0x3a, - 0xbd, 0xb1, 0x7d, 0x30, 0x3e, 0x30, 0x0c, 0x75, 0x52, 0xdc, 0x15, 0x1a, - 0xca, 0xf2, 0x84, 0x93, 0xe2, 0x2a, 0x17, 0x35, 0xd9, 0xf3, 0xe2, 0x96, - 0xad, 0x7c, 0x51, 0xde, 0xea, 0x7c, 0x6f, 0x6b, 0x7a, 0x05, 0xa2, 0x5f, - 0x18, 0xcd, 0x9d, 0x87, 0x60, 0xe1, 0x0d, 0xdb, 0xb0, 0x25, 0x67, 0x82, - 0xcc, 0xf4, 0x3e, 0x57, 0x24, 0x3a, 0x17, 0x8d, 0x33, 0x71, 0xdb, 0x2d, - 0xe2, 0x88, 0x38, 0xbe, 0x68, 0xb7, 0xda, 0x05, 0xa2, 0xa6, 0xe4, 0xd4, - 0x2a, 0x2e, 0xf9, 0xb3, 0xa0, 0x02, 0xb6, 0x46, 0xf2, 0xd2, 0x40, 0x77, - 0x83, 0x3d, 0x9b, 0xed, 0x87, 0x53, 0x8b, 0x90, 0x17, 0x58, 0x91, 0x11, - 0x0c, 0x98, 0x00, 0x18, 0x8c, 0x45, 0x63, 0xfd, 0xab, 0x3c, 0x2b, 0x1b, - 0xe2, 0x56, 0x95, 0x84, 0x74, 0x1a, 0x69, 0x3a, 0x32, 0x8e, 0x58, 0x9c, - 0x2f, 0x32, 0x3f, 0x81, 0x4b, 0x24, 0xf7, 0xb9, 0x3e, 0x8d, 0x9a, 0x12, - 0xd5, 0x92, 0x37, 0x33, 0xe1, 0x48, 0xaf, 0x2f, 0x9a, 0x1a, 0xf2, 0x6f, - 0xfd, 0x84, 0xa5, 0x83, 0x16, 0x27, 0x97, 0x3a, 0xa2, 0xb5, 0x4e, 0x11, - 0x2a, 0xec, 0xa4, 0xd1, 0xb9, 0x1b, 0x25, 0xd9, 0x1f, 0xd7, 0xbd, 0xd3, - 0xab, 0x81, 0x15, 0x67, 0xd5, 0xc0, 0x29, 0xbe, 0x9a, 0x24, 0x3a, 0x5e, - 0x46, 0x75, 0xad, 0x29, 0x01, 0x48, 0x12, 0x01, 0xf9, 0x50, 0x70, 0x7f, - 0xe0, 0x06, 0x48, 0xdf, 0x57, 0x36, 0x61, 0x8d, 0x96, 0xc6, 0x27, 0x18, - 0x92, 0xe9, 0x92, 0xbd, 0x56, 0x71, 0x58, 0x14, 0x63, 0x90, 0x55, 0xef, - 0x45, 0xbf, 0x57, 0xa5, 0x7c, 0x73, 0xd7, 0x6a, 0x54, 0x22, 0xfb, 0x91, - 0x80, 0x50, 0x0e, 0xd2, 0xb4, 0x00, 0xec, 0x48, 0x9f, 0x46, 0x68, 0xed, - 0x32, 0x12, 0xb3, 0x2a, 0x73, 0xf5, 0x8e, 0x89, 0x49, 0x0c, 0xb3, 0x31, - 0xd6, 0x94, 0x04, 0x2a, 0xc9, 0x47, 0xd1, 0xde, 0xa8, 0x82, 0xee, 0x76, - 0x02, 0xaf, 0x3f, 0x34, 0x3c, 0xc0, 0x02, 0xaa, 0x09, 0x97, 0xb9, 0x89, - 0x80, 0xac, 0x14, 0xc4, 0x21, 0x06, 0x99, 0xf9, 0x93, 0xa7, 0x32, 0x00, - 0x97, 0xb2, 0xa3, 0x52, 0xb3, 0x95, 0xe1, 0xcc, 0x94, 0x08, 0x7b, 0xec, - 0x4b, 0x25, 0x9f, 0x95, 0x56, 0xa8, 0x68, 0x94, 0x08, 0x33, 0xcd, 0x0d, - 0x61, 0xdd, 0x85, 0xec, 0x5a, 0x52, 0xbe, 0xa9, 0xb9, 0x7b, 0xb9, 0x15, - 0x77, 0xef, 0x64, 0x08, 0xbb, 0x9f, 0x72, 0x2b, 0xee, 0xb6, 0xdd, 0x8a, - 0xb7, 0x55, 0xa6, 0x5d, 0x54, 0x7e, 0x58, 0x9a, 0x5c, 0x4d, 0x98, 0xf4, - 0xb7, 0x62, 0x4f, 0x82, 0xa0, 0xf6, 0x9b, 0x4a, 0x62, 0x9f, 0x64, 0x4c, - 0x85, 0x20, 0xf3, 0x77, 0xa6, 0xe3, 0x1b, 0x3b, 0x31, 0xdf, 0xe8, 0x05, - 0x24, 0x67, 0xbd, 0x17, 0xb5, 0xa8, 0x91, 0x15, 0x87, 0x77, 0xd4, 0xab, - 0xe1, 0x41, 0x4c, 0xf4, 0xc2, 0x49, 0x98, 0x91, 0x04, 0xcb, 0x28, 0xec, - 0x91, 0x71, 0x14, 0x78, 0x5e, 0x79, 0x49, 0xcc, 0x4a, 0x8c, 0x27, 0xa0, - 0x18, 0x45, 0x74, 0x63, 0x0e, 0x31, 0x4b, 0xee, 0x0b, 0x8c, 0x21, 0xe6, - 0x0c, 0xa2, 0x38, 0x3c, 0xd7, 0x4a, 0xde, 0xdd, 0x38, 0x89, 0x4d, 0x20, - 0x49, 0xab, 0xe0, 0xdd, 0x8c, 0xca, 0xf1, 0xfe, 0x6f, 0xc7, 0x4b, 0xa2, - 0x5b, 0xc6, 0x7b, 0x61, 0xa5, 0x20, 0xa4, 0x54, 0xf4, 0xf8, 0xf3, 0xdb, - 0xa3, 0x83, 0x98, 0x1f, 0x4b, 0x4a, 0x88, 0x45, 0x8b, 0xb8, 0x3c, 0x8c, - 0x20, 0x33, 0x73, 0xc8, 0x84, 0xde, 0x18, 0x18, 0xad, 0xc0, 0x96, 0xe5, - 0x06, 0xe7, 0x2f, 0x3c, 0xde, 0x40, 0x71, 0x3d, 0x55, 0xb8, 0x59, 0x3d, - 0x43, 0xf1, 0xa9, 0x6f, 0x3b, 0xf6, 0x2b, 0x9d, 0x79, 0x66, 0x21, 0xf7, - 0x72, 0xf0, 0xb9, 0xa9, 0x3b, 0x4f, 0x3f, 0x3f, 0x76, 0x0b, 0x0b, 0x58, - 0x94, 0x02, 0x8c, 0x07, 0xdc, 0xad, 0x4a, 0xde, 0xaa, 0xbf, 0x2f, 0x91, - 0x89, 0xbb, 0xb7, 0xb2, 0x01, 0x13, 0x0e, 0xbc, 0xa9, 0xfc, 0xc9, 0x6d, - 0xa7, 0xff, 0x56, 0x6b, 0x4b, 0x8f, 0xab, 0x62, 0xf4, 0xc4, 0x30, 0xd9, - 0x63, 0x43, 0xa9, 0xc3, 0xd4, 0x64, 0xae, 0xe0, 0xb5, 0xbf, 0x23, 0x7a, - 0x43, 0x12, 0xc4, 0xe5, 0xb5, 0x97, 0x0c, 0xae, 0x6e, 0x71, 0xba, 0x01, - 0xd5, 0x4e, 0xeb, 0xfb, 0xe4, 0x03, 0x0c, 0x28, 0x0c, 0x71, 0xc1, 0x64, - 0xcd, 0x54, 0xab, 0x5b, 0x39, 0xe7, 0xf8, 0xe6, 0xfd, 0x19, 0x19, 0x8b, - 0xb7, 0xfb, 0x1f, 0x2c, 0x40, 0xa5, 0xcc, 0x48, 0x36, 0xb6, 0xf8, 0x18, - 0x81, 0x12, 0x6b, 0x74, 0x8c, 0xad, 0xb1, 0xfd, 0x94, 0x22, 0xec, 0x4b, - 0x76, 0xca, 0xef, 0xc0, 0xb1, 0xba, 0x48, 0xcf, 0x6f, 0xea, 0x2c, 0x72, - 0x88, 0x3e, 0x37, 0x96, 0x11, 0xc5, 0x34, 0xbc, 0xcf, 0x67, 0x0c, 0x75, - 0x70, 0xf4, 0x5f, 0x87, 0xc1, 0xaf, 0x0a, 0xfb, 0x3e, 0xca, 0x2f, 0xd0, - 0x79, 0x13, 0x70, 0xf6, 0x2c, 0x58, 0x55, 0x40, 0x56, 0x14, 0xcd, 0x44, - 0x0a, 0x66, 0xba, 0xa2, 0x74, 0x0b, 0x05, 0x9a, 0x83, 0x1b, 0xc7, 0xf1, - 0x33, 0x38, 0xc1, 0x4a, 0x71, 0xd7, 0x69, 0x44, 0x71, 0x26, 0x07, 0x5c, - 0xde, 0xcc, 0x70, 0x61, 0x23, 0x4b, 0x55, 0xeb, 0xd6, 0x2d, 0x0f, 0x80, - 0xfe, 0x48, 0x89, 0xbc, 0xb5, 0xf5, 0xdb, 0xcf, 0x5d, 0xfb, 0x80, 0x56, - 0xc3, 0x5f, 0x5e, 0x44, 0xc6, 0x20, 0xfa, 0xcc, 0x91, 0x7a, 0x25, 0x2c, - 0xaa, 0x11, 0x00, 0x8d, 0x77, 0x15, 0x07, 0xc0, 0x06, 0xcb, 0x70, 0x88, - 0xa0, 0x61, 0xb6, 0xca, 0xc5, 0x7a, 0xfb, 0xad, 0x65, 0x8a, 0xf5, 0xd9, - 0x01, 0xf9, 0x23, 0xb8, 0x25, 0x09, 0x01, 0xe3, 0xc0, 0x11, 0x49, 0x19, - 0x47, 0x3f, 0x02, 0x88, 0x6d, 0x45, 0xf1, 0x3e, 0x47, 0x6b, 0xfe, 0x90, - 0xca, 0xae, 0xfb, 0x20, 0xcc, 0x10, 0x91, 0x1a, 0x5b, 0x27, 0xe9, 0xe6, - 0x42, 0x2c, 0x47, 0x44, 0xe6, 0xff, 0x49, 0x42, 0xfb, 0xc4, 0xe0, 0x1c, - 0x17, 0xac, 0xb4, 0x2a, 0xe8, 0x3c, 0xa4, 0x0e, 0x85, 0xb2, 0x48, 0xa8, - 0x18, 0x0f, 0x22, 0x82, 0xc8, 0xe8, 0x87, 0x12, 0x2a, 0xc9, 0x55, 0x8e, - 0xb5, 0x45, 0x62, 0x4b, 0x8b, 0x34, 0xd3, 0x95, 0xa2, 0x1d, 0x24, 0xc0, - 0xd1, 0x13, 0x21, 0x2a, 0xd9, 0x62, 0x94, 0x16, 0xf8, 0xb0, 0x2e, 0xc5, - 0xc7, 0x80, 0x5e, 0x2c, 0xc5, 0x34, 0x90, 0xc6, 0x6e, 0x25, 0x9b, 0x7c, - 0x35, 0x0a, 0x69, 0xc4, 0x00, 0xbc, 0x67, 0xc2, 0xa8, 0x1c, 0x26, 0x33, - 0x96, 0xe5, 0x4d, 0x82, 0xa3, 0xf8, 0xfb, 0x60, 0x53, 0xef, 0xa2, 0xb5, - 0x07, 0x53, 0xbd, 0x19, 0x70, 0xc0, 0xdf, 0x92, 0x2e, 0xbe, 0xd1, 0xf8, - 0x15, 0x55, 0xd3, 0xcd, 0x59, 0x76, 0xc7, 0xfa, 0xe1, 0xfc, 0x96, 0x1c, - 0x76, 0xef, 0x46, 0xa4, 0x60, 0xbb, 0x2a, 0xa1, 0xb8, 0xc7, 0x7e, 0x74, - 0x11, 0x04, 0x5f, 0x92, 0xdd, 0xd6, 0xc4, 0x60, 0x44, 0xd3, 0xe6, 0x1e, - 0x34, 0xb6, 0xbd, 0xaa, 0x33, 0xc1, 0x45, 0x32, 0xf1, 0xbb, 0x19, 0x7a, - 0x8a, 0xfe, 0x7f, 0x1f, 0x4e, 0xc5, 0x31, 0x4d, 0x5e, 0x94, 0xb1, 0x4a, - 0x8c, 0x26, 0x45, 0xb9, 0xb2, 0xa8, 0x66, 0x17, 0x87, 0x25, 0xea, 0x7a, - 0x70, 0x3e, 0x99, 0x6a, 0x84, 0x33, 0xb4, 0x56, 0x49, 0x29, 0xe2, 0x80, - 0x28, 0x6d, 0xf5, 0x16, 0xf3, 0x5a, 0xcb, 0x1c, 0x65, 0x1c, 0x53, 0x97, - 0xfa, 0x02, 0xa5, 0xee, 0x05, 0x2b, 0xac, 0x16, 0x42, 0x65, 0xb9, 0x2a, - 0xa9, 0x54, 0xb5, 0xae, 0xa9, 0xde, 0x8b, 0x09, 0x93, 0xc1, 0x15, 0x49, - 0xc3, 0x0f, 0xa2, 0xa5, 0x42, 0x3c, 0x8a, 0x24, 0xe5, 0xbb, 0x08, 0xc0, - 0xe9, 0x58, 0x72, 0x47, 0xcb, 0xe7, 0x24, 0x07, 0xfb, 0x0b, 0x80, 0xd8, - 0x12, 0x36, 0x58, 0x1b, 0x5f, 0xc0, 0xef, 0x70, 0xdd, 0xf1, 0x70, 0xb2, - 0x95, 0x89, 0xd7, 0x92, 0xab, 0xd9, 0x20, 0xa3, 0x28, 0xe6, 0xa5, 0x46, - 0x22, 0xd3, 0xe5, 0x22, 0xb5, 0x33, 0xa4, 0x5c, 0xc6, 0x9e, 0xd1, 0x2c, - 0x2e, 0x65, 0xbf, 0xca, 0x36, 0x81, 0x09, 0x54, 0x9b, 0x55, 0x35, 0xc6, - 0x96, 0x2b, 0xaa, 0xbe, 0xe7, 0xeb, 0xd5, 0x3e, 0xd7, 0x7a, 0xb5, 0x40, - 0x99, 0x4d, 0xd0, 0x85, 0x85, 0x4b, 0x88, 0x57, 0x85, 0x0a, 0x5d, 0xbe, - 0x73, 0x71, 0x66, 0x9e, 0x66, 0xfa, 0xfe, 0x6b, 0xf6, 0x8e, 0x31, 0xf6, - 0xac, 0x05, 0x59, 0xd3, 0xdc, 0x42, 0x71, 0x56, 0x94, 0x6f, 0x35, 0x2a, - 0xe5, 0x92, 0xb2, 0x4a, 0x03, 0x56, 0x17, 0xad, 0x0a, 0x3f, 0xd6, 0xe9, - 0x57, 0xd5, 0x65, 0x87, 0x6c, 0x52, 0xe7, 0xf6, 0x40, 0xd7, 0xea, 0x53, - 0x36, 0x4a, 0xad, 0xe9, 0xc6, 0x99, 0x03, 0x2e, 0x2f, 0x5d, 0xc8, 0x4b, - 0xb5, 0x10, 0xfb, 0xa7, 0x42, 0x75, 0xa0, 0x5a, 0x9e, 0x7b, 0x74, 0xa4, - 0xf4, 0x4c, 0x2f, 0x31, 0xff, 0xca, 0x61, 0x0c, 0x94, 0x8d, 0x85, 0x6f, - 0xca, 0x39, 0x2e, 0x83, 0xb2, 0xf7, 0x2a, 0x54, 0x47, 0x8d, 0xb0, 0x42, - 0xa4, 0x5e, 0x96, 0x38, 0xb6, 0xe9, 0xb8, 0xa9, 0x6c, 0x1f, 0x25, 0x50, - 0x68, 0x50, 0x86, 0xae, 0x21, 0x3f, 0xea, 0x7c, 0xac, 0xf3, 0x73, 0x4e, - 0xf0, 0xab, 0x51, 0x11, 0xe3, 0x40, 0xd8, 0xc0, 0x8b, 0x38, 0x20, 0x8f, - 0xe3, 0xe3, 0x05, 0xc0, 0x74, 0xae, 0x48, 0xa5, 0x04, 0xf1, 0x85, 0x71, - 0xd9, 0x2a, 0xce, 0x84, 0x4e, 0xc9, 0x1f, 0x0c, 0x5b, 0x97, 0x0f, 0x08, - 0xad, 0x55, 0x65, 0xa3, 0x7e, 0x83, 0x37, 0x6b, 0x1f, 0xf7, 0x91, 0xf0, - 0xd2, 0x5c, 0xe9, 0x25, 0x97, 0xba, 0xf6, 0xb9, 0x12, 0x97, 0xe6, 0x00, - 0x57, 0x7d, 0x07, 0x79, 0xf4, 0x20, 0xa5, 0xc3, 0x26, 0x99, 0xbd, 0x29, - 0xc2, 0x39, 0x07, 0xe1, 0x53, 0xc1, 0x30, 0xb9, 0x66, 0x87, 0x04, 0x70, - 0x9c, 0xb0, 0x6f, 0x9f, 0x2f, 0x70, 0xc3, 0xc6, 0x0e, 0x35, 0x7b, 0x03, - 0x22, 0x89, 0xbd, 0xdf, 0x0f, 0xc5, 0x28, 0xb1, 0xd6, 0x78, 0xd9, 0x00, - 0xe5, 0x94, 0x3b, 0x3c, 0x02, 0x56, 0x23, 0xb8, 0x12, 0xa5, 0x60, 0x0b, - 0xd0, 0x57, 0x27, 0xa1, 0x12, 0x81, 0x4f, 0x4d, 0xcc, 0x07, 0x5d, 0xf3, - 0x2d, 0x13, 0x9a, 0x78, 0x54, 0x41, 0x4b, 0x8a, 0x72, 0x48, 0x9d, 0x32, - 0xc3, 0x05, 0x1d, 0xfd, 0x9b, 0x4c, 0xed, 0x8b, 0x07, 0x0f, 0x8e, 0x6c, - 0x3c, 0x09, 0x77, 0x4a, 0xbd, 0x72, 0xf1, 0x64, 0x0b, 0xdd, 0xe2, 0x28, - 0x6d, 0x87, 0x53, 0x43, 0xbc, 0x92, 0x95, 0xd9, 0x07, 0x16, 0x92, 0x62, - 0x53, 0xb3, 0xc0, 0x32, 0x2e, 0x24, 0x47, 0xbb, 0x4b, 0xfa, 0x6e, 0xf2, - 0xf0, 0x51, 0xdf, 0x21, 0x7e, 0xfa, 0x61, 0x84, 0x74, 0x3e, 0x74, 0x87, - 0xe8, 0x12, 0xd8, 0x88, 0xf9, 0x71, 0xeb, 0xe1, 0xdb, 0x7f, 0x7b, 0x8a, - 0x9f, 0xb4, 0xcd, 0x40, 0x6b, 0x70, 0x2f, 0x5f, 0x56, 0xb9, 0x14, 0x65, - 0x55, 0x10, 0x01, 0x52, 0x35, 0x2d, 0x95, 0x78, 0x9f, 0xf4, 0xbf, 0x72, - 0xf5, 0xde, 0x09, 0x2d, 0x53, 0x51, 0x0e, 0x6c, 0x51, 0xdc, 0x9a, 0xb8, - 0x25, 0xa1, 0xdd, 0xb6, 0x18, 0x9d, 0xb0, 0x22, 0x5a, 0x65, 0xc9, 0x8a, - 0xeb, 0xb1, 0xea, 0xc5, 0xab, 0x82, 0xcb, 0x62, 0xd1, 0x8b, 0x0b, 0x60, - 0x40, 0x01, 0xdb, 0x53, 0x73, 0xf8, 0x63, 0x1a, 0x52, 0xf4, 0xaa, 0xc0, - 0xc1, 0xe0, 0x7f, 0x3f, 0xe5, 0x53, 0xd0, 0x00, 0x88, 0xdd, 0x3d, 0x20, - 0xc8, 0x4d, 0x1a, 0x2e, 0xde, 0x21, 0xe3, 0x2b, 0x4f, 0xc1, 0xf9, 0xc8, - 0xc5, 0xdd, 0x44, 0xf1, 0x7a, 0x0e, 0xf4, 0x8a, 0xa0, 0x5f, 0x9f, 0xbd, - 0x3e, 0xed, 0xa1, 0x83, 0xab, 0xc7, 0x26, 0x10, 0x72, 0x55, 0xe5, 0x18, - 0xdb, 0x35, 0x2c, 0x2e, 0x7b, 0x12, 0xf0, 0x53, 0x31, 0xc0, 0xcb, 0x83, - 0xe3, 0x69, 0xf2, 0x12, 0xae, 0xe3, 0x0f, 0xb7, 0xe3, 0x42, 0x5b, 0xca, - 0x12, 0x0c, 0xe1, 0xc7, 0x37, 0xcf, 0x41, 0x58, 0xfa, 0x31, 0x2f, 0x51, - 0x4b, 0x85, 0x16, 0xde, 0x80, 0x98, 0xa1, 0x45, 0x8e, 0xe0, 0xb6, 0xba, - 0x4e, 0x09, 0x3f, 0x64, 0x03, 0xa5, 0x27, 0x4c, 0xc9, 0xec, 0x5a, 0x4c, - 0x8a, 0x56, 0x1c, 0xa3, 0xb4, 0x14, 0x0c, 0x69, 0xaf, 0x04, 0xae, 0x36, - 0xcb, 0xb9, 0xbe, 0x5f, 0xaa, 0x75, 0x2a, 0x0e, 0xf6, 0x4f, 0xde, 0xbd, - 0x3e, 0x3c, 0x7b, 0xf7, 0x66, 0xff, 0x27, 0xe4, 0x87, 0xb3, 0x54, 0xea, - 0xca, 0x50, 0x55, 0xa1, 0xa2, 0x54, 0x0e, 0x0b, 0x7a, 0x5f, 0x42, 0x15, - 0x7b, 0x1f, 0x94, 0x45, 0x51, 0x47, 0x48, 0x9f, 0x61, 0xdd, 0xef, 0x2c, - 0x58, 0xf4, 0x3b, 0x90, 0x3e, 0x5d, 0x37, 0x84, 0xe8, 0x79, 0x27, 0x9c, - 0x4d, 0x78, 0xbe, 0x43, 0xc7, 0x64, 0x1b, 0xa3, 0xd4, 0xb6, 0xfa, 0xdb, - 0x9d, 0x8f, 0x7a, 0x15, 0xb8, 0x42, 0x36, 0x9d, 0xed, 0x56, 0x5b, 0xab, - 0x22, 0xe1, 0x4c, 0xab, 0xf0, 0x7a, 0xe0, 0x9e, 0xb3, 0x5e, 0x5d, 0x54, - 0xc9, 0xd3, 0xb8, 0xd2, 0xd1, 0xfe, 0x78, 0x4c, 0x38, 0x08, 0x70, 0xf4, - 0xb0, 0x80, 0x20, 0x6a, 0x2a, 0xa7, 0x92, 0x5b, 0xbb, 0x7e, 0x76, 0x7c, - 0xba, 0xc1, 0xf2, 0x0c, 0xe3, 0x15, 0xe0, 0x79, 0x38, 0x2b, 0x53, 0x04, - 0xd1, 0x4a, 0x0e, 0xc6, 0x14, 0x58, 0x69, 0xd7, 0x25, 0xa6, 0xe0, 0x7b, - 0x58, 0x0e, 0x81, 0xde, 0x90, 0x80, 0x16, 0x96, 0x2f, 0xb5, 0x6b, 0x0b, - 0x44, 0x4a, 0x31, 0x1b, 0x0e, 0xe4, 0x94, 0x81, 0x6c, 0x85, 0x41, 0x0c, - 0x6c, 0x07, 0x6f, 0xdd, 0xce, 0xa3, 0x47, 0x94, 0x09, 0x13, 0x0a, 0x28, - 0x18, 0x13, 0x55, 0xae, 0x79, 0x70, 0xba, 0xd5, 0x85, 0x1f, 0xdb, 0xf8, - 0x63, 0xa7, 0x8b, 0x7f, 0xef, 0xe2, 0xaf, 0x0f, 0xf1, 0xc7, 0x23, 0xfa, - 0xfb, 0x31, 0xfe, 0xfa, 0x25, 0xfc, 0xba, 0xff, 0x7c, 0x1b, 0x1e, 0x83, - 0x9f, 0x3b, 0xf4, 0x73, 0x97, 0x3e, 0xda, 0x51, 0x0f, 0x0b, 0xfc, 0x4a, - 0x9f, 0xef, 0xec, 0xe2, 0xcf, 0xdd, 0x6d, 0xfa, 0x76, 0x97, 0x3e, 0xda, - 0xa5, 0x8f, 0x1e, 0xf2, 0x47, 0x0f, 0xe9, 0xa3, 0x87, 0xf0, 0xd1, 0xe1, - 0x73, 0xf8, 0xe0, 0xc7, 0xe3, 0xa3, 0x83, 0xc3, 0xde, 0xfe, 0xb3, 0x57, - 0x47, 0x67, 0xd2, 0xd0, 0xe1, 0xc1, 0x19, 0x3c, 0x09, 0x3f, 0xd1, 0x68, - 0x7b, 0x70, 0xd8, 0x4d, 0x5e, 0xc2, 0xff, 0x93, 0x97, 0xc7, 0x3f, 0x1d, - 0x1c, 0x9f, 0x9e, 0x75, 0xf1, 0x97, 0x67, 0x87, 0x2f, 0xf7, 0xff, 0x02, - 0x9f, 0x9d, 0xbd, 0x78, 0x73, 0xfc, 0xf6, 0x87, 0x17, 0x27, 0x6f, 0xe1, - 0xe3, 0xe4, 0xcd, 0xe1, 0xcb, 0xa3, 0xfd, 0xef, 0x8f, 0x5e, 0x1e, 0x9d, - 0xfd, 0x45, 0x1a, 0x7a, 0x75, 0xf4, 0x1a, 0x5f, 0x11, 0x22, 0xe7, 0x1d, - 0xbc, 0x0b, 0x84, 0xbf, 0x51, 0x90, 0xcb, 0xea, 0x8b, 0xdc, 0x1d, 0xa4, - 0x29, 0x1d, 0xc0, 0xaa, 0xad, 0x12, 0xb1, 0x43, 0xac, 0x38, 0x72, 0x3b, - 0xd5, 0x83, 0x19, 0x48, 0x0a, 0xe4, 0x62, 0x90, 0x1b, 0xfc, 0x6a, 0x9c, - 0x4e, 0xd9, 0x30, 0x05, 0xe7, 0xd9, 0x91, 0xe2, 0xa8, 0xea, 0x5d, 0x00, - 0x03, 0x47, 0xc7, 0xe3, 0x53, 0x10, 0xdb, 0x95, 0x1a, 0x8f, 0x4e, 0x9e, - 0x03, 0xc9, 0x9d, 0xc6, 0x18, 0xd8, 0xfa, 0xa0, 0x84, 0x2b, 0x0a, 0x41, - 0x3e, 0x17, 0xa1, 0xec, 0xe8, 0xe4, 0xf5, 0xa9, 0x98, 0x78, 0x31, 0x81, - 0x32, 0x02, 0x07, 0x30, 0xf9, 0x31, 0x04, 0xfd, 0x44, 0x3a, 0x16, 0x27, - 0x0a, 0x05, 0x37, 0x15, 0xb6, 0xfa, 0xee, 0x87, 0xfd, 0xb3, 0xc3, 0x9f, - 0xf6, 0xff, 0xa2, 0x25, 0x14, 0xaf, 0xf2, 0xb2, 0x98, 0xb2, 0x7f, 0xfe, - 0x2a, 0x2d, 0x73, 0x51, 0x60, 0x49, 0xe4, 0xc2, 0xac, 0x0d, 0xa4, 0x6b, - 0x31, 0xa9, 0x76, 0xfe, 0x7f, 0x9b, 0x7d, 0x9c, 0xd9, 0xa6, 0x0c, 0xb8, - 0xe3, 0xeb, 0xab, 0x5e, 0x16, 0x63, 0xad, 0xa9, 0x68, 0x13, 0x42, 0x7d, - 0x85, 0xa3, 0x28, 0x1d, 0x2f, 0x43, 0x91, 0x01, 0x19, 0x9d, 0x16, 0x17, - 0xa7, 0x99, 0xe2, 0xa2, 0x8a, 0x11, 0x4a, 0x5f, 0xe6, 0xa8, 0x0b, 0x8b, - 0x98, 0x49, 0xe3, 0xd2, 0x8f, 0xf3, 0x29, 0xaa, 0xf1, 0x04, 0x9c, 0x04, - 0x9b, 0x48, 0x2d, 0x21, 0x03, 0xda, 0x7b, 0xb2, 0xf5, 0x64, 0xab, 0xd3, - 0x4f, 0xf6, 0xb9, 0x58, 0x85, 0xca, 0xb8, 0x04, 0x36, 0x46, 0xd1, 0xeb, - 0xe3, 0xa2, 0x78, 0xdf, 0x2c, 0x50, 0x1d, 0x6f, 0x57, 0x6b, 0x93, 0x09, - 0x3e, 0x02, 0x9f, 0x9e, 0xa7, 0xa3, 0x9b, 0xf3, 0x2c, 0xbf, 0x48, 0x2f, - 0x86, 0x8f, 0xa6, 0x93, 0xe9, 0x74, 0x27, 0xbf, 0xa9, 0x76, 0x46, 0xbb, - 0xc3, 0xa2, 0x2c, 0xbe, 0xbc, 0x81, 0x1b, 0xff, 0xea, 0xa6, 0xdc, 0x99, - 0xfc, 0x3d, 0x2d, 0xaf, 0xf3, 0xe1, 0x45, 0x3a, 0x4c, 0xaf, 0x27, 0x29, - 0xa2, 0x69, 0xdc, 0x0c, 0xcf, 0xff, 0x9e, 0x07, 0xde, 0x81, 0x02, 0x2b, - 0x27, 0xe7, 0x50, 0x61, 0x12, 0x8b, 0x8b, 0x4f, 0x64, 0xd7, 0x65, 0x24, - 0x95, 0x85, 0xc9, 0x30, 0x77, 0xd1, 0xd9, 0x08, 0x4d, 0x2b, 0x01, 0xe3, - 0xc8, 0xfa, 0x17, 0x70, 0xe3, 0xcc, 0xcf, 0xfb, 0x79, 0xb1, 0xc9, 0x6d, - 0xe9, 0x6c, 0x7a, 0x44, 0x01, 0x59, 0xb9, 0x19, 0xaf, 0x7f, 0x21, 0x7e, - 0xb5, 0x8b, 0x42, 0x82, 0x62, 0x35, 0x02, 0x5c, 0x17, 0xe1, 0xc6, 0x92, - 0xb4, 0x58, 0xe7, 0x4f, 0xaf, 0x53, 0x2d, 0x69, 0xec, 0x70, 0xc1, 0x24, - 0xac, 0x17, 0x2d, 0xbb, 0x2c, 0xd5, 0x73, 0x9a, 0x07, 0xb7, 0xa1, 0xc2, - 0xce, 0x84, 0xa1, 0xbb, 0xb1, 0xae, 0x2b, 0x29, 0x93, 0xa8, 0x5d, 0xd1, - 0xe2, 0x72, 0x43, 0x3a, 0x59, 0xd6, 0x69, 0xb1, 0x59, 0xb2, 0xfa, 0x63, - 0xaa, 0x2e, 0x46, 0xae, 0x60, 0xe6, 0x36, 0x8a, 0x2b, 0xf1, 0xf8, 0x2a, - 0xad, 0xd8, 0x36, 0xc0, 0x4d, 0xd5, 0x7a, 0x6d, 0x68, 0x65, 0xcb, 0x49, - 0xdb, 0x3b, 0xcf, 0xbc, 0xee, 0x20, 0x70, 0x44, 0x2c, 0xff, 0x68, 0x66, - 0xa2, 0x40, 0xe0, 0x69, 0xb5, 0x23, 0x87, 0xb1, 0xc9, 0xd2, 0x54, 0x64, - 0x42, 0xe2, 0xca, 0x0e, 0x29, 0xd2, 0x28, 0x1c, 0xb4, 0x19, 0x25, 0x47, - 0x17, 0x12, 0x33, 0x23, 0x22, 0x11, 0x0e, 0xa7, 0x91, 0xe2, 0x69, 0x88, - 0x76, 0x7f, 0xe1, 0xd7, 0x6f, 0x14, 0xcc, 0xac, 0x66, 0x64, 0x07, 0x3c, - 0x64, 0xd7, 0x8c, 0x11, 0xc0, 0xc0, 0x23, 0xa8, 0x3b, 0x03, 0xe9, 0x26, - 0x58, 0xa8, 0xf3, 0x22, 0x0d, 0x76, 0x93, 0x81, 0xa6, 0x48, 0xc1, 0x66, - 0x5c, 0x14, 0x89, 0xec, 0x59, 0x87, 0xd6, 0x1c, 0xa3, 0xed, 0x3b, 0x6e, - 0xd1, 0xcf, 0x42, 0xd8, 0x13, 0x8d, 0x9a, 0x96, 0x5a, 0x9d, 0x5a, 0xa4, - 0x33, 0xdf, 0x44, 0x91, 0x17, 0xb8, 0x0c, 0x7d, 0xb2, 0x5c, 0x57, 0x14, - 0x98, 0xc6, 0x1f, 0x82, 0xf6, 0x8e, 0x76, 0x6a, 0xc2, 0x60, 0x99, 0xca, - 0xee, 0x22, 0x35, 0x5c, 0x69, 0x92, 0x97, 0x76, 0xdd, 0x20, 0x46, 0x7c, - 0x91, 0x78, 0x44, 0xbf, 0xce, 0x06, 0x97, 0x9b, 0x56, 0x72, 0x6f, 0x13, - 0x1f, 0x50, 0xbe, 0xb1, 0xf9, 0x07, 0x69, 0xaf, 0x77, 0x55, 0xf5, 0xac, - 0x25, 0x2f, 0xec, 0xf8, 0xf3, 0x78, 0x47, 0xd1, 0xb6, 0x8f, 0x28, 0xc8, - 0xb2, 0x70, 0x19, 0x34, 0x4e, 0x7d, 0xe3, 0x3a, 0xd0, 0x33, 0xbf, 0x78, - 0x2d, 0x2c, 0xc4, 0x71, 0x52, 0xa6, 0x0e, 0xdd, 0x07, 0x70, 0xa2, 0x41, - 0x8a, 0xd4, 0x8b, 0xe0, 0x21, 0x59, 0xe5, 0x66, 0x57, 0x0f, 0x83, 0x73, - 0xb8, 0x89, 0x8c, 0xc4, 0xde, 0x3e, 0x4e, 0xca, 0x63, 0x19, 0x99, 0xeb, - 0xcc, 0xaa, 0x2d, 0xa1, 0x1b, 0x3c, 0x7e, 0x8b, 0xba, 0x3b, 0xc6, 0x90, - 0xb3, 0x64, 0xd2, 0x30, 0x85, 0x43, 0x97, 0x4b, 0x23, 0x61, 0x5b, 0xe0, - 0x39, 0xef, 0x58, 0x27, 0x68, 0xec, 0x8e, 0xd0, 0xc1, 0x16, 0x97, 0x6f, - 0xd3, 0xd7, 0x43, 0x0d, 0x3d, 0x76, 0xeb, 0xd6, 0x0c, 0xa4, 0x6c, 0xf1, - 0xca, 0x3e, 0x96, 0xf5, 0x7b, 0x1c, 0xad, 0xdf, 0xe3, 0x7b, 0x5d, 0x3f, - 0xdc, 0x10, 0x97, 0x9b, 0x5a, 0xaa, 0xa6, 0x52, 0xf2, 0x91, 0x15, 0x33, - 0xca, 0x50, 0x52, 0x21, 0x78, 0xb9, 0xc5, 0xb5, 0xaf, 0x3a, 0x4d, 0x30, - 0x35, 0x9f, 0x5b, 0x1d, 0x60, 0xe5, 0x35, 0x34, 0xde, 0x30, 0xdc, 0x18, - 0x3a, 0xb1, 0x33, 0x41, 0x58, 0xcc, 0x61, 0x47, 0x80, 0xf4, 0x22, 0xf4, - 0x3c, 0xcb, 0x67, 0x9b, 0x01, 0x27, 0x10, 0x7d, 0x61, 0x36, 0x2f, 0x67, - 0x45, 0x45, 0x00, 0x48, 0x93, 0x74, 0x70, 0x7c, 0xca, 0x17, 0x35, 0xd9, - 0xbe, 0x58, 0x43, 0x1f, 0x16, 0xac, 0xf7, 0xb4, 0xc5, 0xd6, 0xe1, 0x3a, - 0xfe, 0x6e, 0x5f, 0x22, 0x35, 0x72, 0x4f, 0xc4, 0xf0, 0xf0, 0xe3, 0x88, - 0xa1, 0xf7, 0x5b, 0x05, 0xad, 0x46, 0x05, 0x28, 0x03, 0x80, 0x90, 0x54, - 0x52, 0x31, 0x5b, 0xc8, 0x7f, 0x9e, 0x1e, 0xbf, 0x96, 0x82, 0x91, 0x28, - 0x6a, 0xc4, 0xd8, 0xa9, 0x12, 0x00, 0x14, 0x82, 0x38, 0x14, 0xdc, 0x58, - 0xfa, 0x08, 0xb5, 0x1c, 0x28, 0x22, 0xe5, 0x12, 0x34, 0xe1, 0xc1, 0xbc, - 0x16, 0x1b, 0xb2, 0xcb, 0x31, 0xe6, 0x14, 0x6a, 0xf8, 0xa7, 0x54, 0x57, - 0xa3, 0xe4, 0x0c, 0x92, 0x70, 0x21, 0x88, 0x9d, 0x7f, 0x4d, 0xcb, 0x8b, - 0x5f, 0xe9, 0x4f, 0xc9, 0x50, 0xed, 0x58, 0x79, 0x69, 0x50, 0x48, 0xf6, - 0x10, 0x18, 0x75, 0x2c, 0x66, 0xcc, 0x4d, 0xec, 0xbd, 0x13, 0x3d, 0xcb, - 0xd9, 0x01, 0x6d, 0x4f, 0x79, 0x71, 0x82, 0x73, 0x41, 0x22, 0x2b, 0xba, - 0x99, 0x88, 0x29, 0x57, 0x9f, 0x18, 0x97, 0xd6, 0xcf, 0x84, 0xfb, 0x90, - 0x32, 0x4d, 0x68, 0x8d, 0x94, 0xd0, 0xec, 0xf9, 0x50, 0x58, 0x5e, 0x9c, - 0x8b, 0x0d, 0xd9, 0x4d, 0xaa, 0xb8, 0x87, 0x74, 0xe7, 0x50, 0x20, 0x8c, - 0x71, 0x3b, 0x93, 0xef, 0xba, 0x9a, 0x02, 0x58, 0xc5, 0xb5, 0xd4, 0x84, - 0xe9, 0x58, 0x36, 0x0a, 0xd7, 0x9f, 0x1b, 0xba, 0xa2, 0x50, 0x68, 0xf6, - 0xeb, 0x26, 0x74, 0xbd, 0x49, 0x75, 0x0d, 0xf8, 0xbc, 0xba, 0x4c, 0xd6, - 0x7b, 0x1b, 0x28, 0x85, 0x52, 0xff, 0xd7, 0x21, 0xd9, 0x53, 0x42, 0x32, - 0x5a, 0x1a, 0x91, 0xe4, 0xfa, 0xe4, 0xa4, 0x10, 0x7b, 0x48, 0xf8, 0xc6, - 0x6c, 0xc3, 0x58, 0xb2, 0x96, 0x1b, 0x5a, 0x1b, 0x15, 0xc5, 0x79, 0x5a, - 0xae, 0x29, 0x36, 0x07, 0xa1, 0x2e, 0x68, 0xf5, 0x37, 0x73, 0x55, 0x13, - 0x6d, 0x7c, 0xc7, 0x8f, 0x8a, 0x1d, 0xbe, 0x68, 0xa0, 0xdc, 0xda, 0x48, - 0x1a, 0x03, 0xe9, 0x92, 0x64, 0xaf, 0x4d, 0xf4, 0x96, 0x24, 0xcc, 0x58, - 0x6e, 0x0b, 0x55, 0x3c, 0x63, 0xa7, 0x6d, 0x41, 0xa0, 0x6a, 0x53, 0x07, - 0x7f, 0x62, 0x35, 0x0c, 0xd0, 0x38, 0xdf, 0x75, 0x20, 0x6c, 0xc3, 0x61, - 0xce, 0x41, 0x06, 0xdc, 0xfb, 0x2c, 0x47, 0x50, 0x31, 0x92, 0x34, 0x81, - 0xdf, 0xa0, 0xdd, 0x9f, 0xa1, 0x31, 0x24, 0x68, 0xc5, 0x2a, 0x61, 0x89, - 0x33, 0x23, 0x60, 0x71, 0x38, 0xc7, 0xca, 0x99, 0xc3, 0x51, 0x8a, 0xac, - 0xf4, 0x15, 0x22, 0x0b, 0xaa, 0x9e, 0x2b, 0xf5, 0xb5, 0x86, 0xd9, 0xd4, - 0x8e, 0xb7, 0x61, 0x09, 0xda, 0x75, 0x8c, 0xd7, 0xa2, 0xae, 0x80, 0xbc, - 0xb7, 0x98, 0x1d, 0xf4, 0x91, 0xd9, 0xd9, 0xdc, 0xda, 0xda, 0x3f, 0x92, - 0xce, 0x10, 0x14, 0xef, 0xf7, 0x9d, 0xbd, 0xa4, 0x33, 0x28, 0x80, 0x8b, - 0x75, 0x92, 0x7f, 0xae, 0xdd, 0x6d, 0x81, 0x68, 0xbe, 0xbc, 0x66, 0x9f, - 0x7d, 0x7c, 0x33, 0xdf, 0x21, 0x58, 0x4f, 0x8a, 0xe6, 0xf1, 0x15, 0x9f, - 0xef, 0xb5, 0x8a, 0x1c, 0x4f, 0x13, 0xfc, 0x16, 0xf3, 0x8d, 0x3e, 0x31, - 0x30, 0x1f, 0x2d, 0xc5, 0xab, 0x14, 0xf8, 0x8e, 0xe3, 0xa5, 0x9e, 0x10, - 0x7c, 0x5b, 0x23, 0x28, 0xdf, 0x63, 0x59, 0x47, 0x0d, 0xd1, 0x17, 0x65, - 0x7a, 0xad, 0x8c, 0xf9, 0x37, 0xbc, 0xa5, 0x7f, 0x9b, 0x4f, 0xdf, 0xf7, - 0xe0, 0x6a, 0x42, 0x57, 0x6f, 0x4f, 0xbc, 0xc3, 0x8b, 0x30, 0xdb, 0x9a, - 0x9e, 0x67, 0xf9, 0x79, 0x74, 0x60, 0xe4, 0x71, 0xcd, 0x02, 0x93, 0xe8, - 0x1f, 0x4b, 0x2c, 0x6c, 0xc4, 0x95, 0xb1, 0x86, 0x8b, 0x01, 0x3b, 0x79, - 0x35, 0xa0, 0xf0, 0x5e, 0x4c, 0xb6, 0xee, 0x48, 0xdf, 0xda, 0x58, 0x47, - 0xf5, 0x0f, 0xbc, 0xe2, 0xd8, 0x9b, 0x67, 0x3e, 0x35, 0xa9, 0x8c, 0x81, - 0xb8, 0x34, 0xa4, 0xd9, 0x4e, 0xd1, 0x67, 0xac, 0xef, 0xa3, 0x2d, 0x11, - 0x39, 0x1c, 0x25, 0x31, 0x02, 0x8b, 0xce, 0x51, 0x49, 0x3d, 0x2f, 0x8b, - 0xeb, 0x8a, 0x62, 0x33, 0xa4, 0x53, 0x3d, 0x2d, 0x95, 0x44, 0x0d, 0xdb, - 0x14, 0x44, 0x14, 0x61, 0x34, 0x15, 0xd5, 0xf3, 0x06, 0xe3, 0x82, 0x0c, - 0x8f, 0x14, 0x1a, 0xd1, 0x8f, 0x5c, 0xcc, 0xba, 0xa8, 0x6d, 0xeb, 0xb7, - 0x92, 0xd3, 0xf9, 0xce, 0x02, 0x2f, 0x6d, 0x2d, 0xdf, 0x7e, 0xc9, 0xb7, - 0x8e, 0xa5, 0x77, 0xae, 0x93, 0x5c, 0x1d, 0x69, 0x80, 0x5f, 0x30, 0x18, - 0x53, 0xfc, 0xa3, 0xf7, 0x5b, 0x1a, 0x6a, 0xd7, 0xbe, 0xcf, 0xe0, 0xd0, - 0x8c, 0xb1, 0x2c, 0xee, 0x00, 0x6b, 0x4b, 0x0b, 0xe6, 0xe7, 0xb7, 0xda, - 0x4e, 0x2d, 0x15, 0xb7, 0x3e, 0xe4, 0x93, 0xf9, 0xc4, 0x01, 0x4b, 0xd9, - 0x6b, 0xa8, 0x19, 0x9c, 0xc3, 0xd8, 0xb0, 0xe2, 0x93, 0xdc, 0x33, 0x5c, - 0xd2, 0x18, 0x4d, 0xb4, 0x06, 0xcf, 0x38, 0x2d, 0x42, 0x44, 0x84, 0x86, - 0xa8, 0x94, 0xc5, 0x6c, 0xa6, 0xe6, 0x8a, 0x05, 0xe8, 0x40, 0x07, 0xe0, - 0x47, 0x7c, 0x6b, 0x7c, 0x13, 0xfb, 0x62, 0xe1, 0x85, 0xdf, 0x24, 0xa2, - 0x4b, 0xd7, 0x39, 0xcc, 0x04, 0xb7, 0xaa, 0x35, 0x56, 0x4d, 0xb2, 0x04, - 0xc4, 0xb4, 0x4e, 0xe4, 0x40, 0x9f, 0x92, 0xb9, 0x1a, 0x93, 0x02, 0xfe, - 0xe3, 0xfb, 0xd3, 0x67, 0x9b, 0x24, 0xd7, 0xe1, 0x5f, 0x62, 0x46, 0xe7, - 0x86, 0xbe, 0xfd, 0x86, 0x2c, 0xab, 0xdb, 0x8f, 0x77, 0xbe, 0xfa, 0xaa, - 0x9b, 0x9c, 0x16, 0xe3, 0xb4, 0x84, 0xc6, 0xb6, 0xb7, 0xfb, 0xa0, 0x61, - 0xd0, 0xf2, 0xc2, 0x45, 0x8d, 0x26, 0x9c, 0xfd, 0xa3, 0x9f, 0xe1, 0x83, - 0x17, 0x27, 0xbd, 0xb7, 0x3f, 0xd3, 0xc7, 0x14, 0x6e, 0xd1, 0x12, 0x9b, - 0xb9, 0x50, 0x22, 0x86, 0x28, 0x25, 0xac, 0x6b, 0xc3, 0x9a, 0x86, 0x28, - 0xf0, 0x53, 0x07, 0x77, 0x40, 0xe7, 0x49, 0xe3, 0x78, 0x14, 0xb6, 0x17, - 0x8f, 0xf3, 0x57, 0x9a, 0x75, 0x1d, 0xef, 0x6c, 0x08, 0x7d, 0x5a, 0x5d, - 0x93, 0x5b, 0xc9, 0xa0, 0x17, 0x77, 0xb3, 0xfb, 0x69, 0x56, 0xbd, 0x78, - 0xef, 0x42, 0x0a, 0x85, 0x7d, 0xde, 0x42, 0xaf, 0xf4, 0xe4, 0x53, 0x41, - 0xa2, 0x6e, 0x10, 0x2c, 0x67, 0xef, 0xa6, 0x71, 0xf4, 0x21, 0xfb, 0x07, - 0x50, 0x60, 0x28, 0x33, 0xaa, 0x2b, 0x97, 0x0f, 0xa9, 0x6e, 0xa4, 0x04, - 0x12, 0xc8, 0xbd, 0xcb, 0x0d, 0x2d, 0xd0, 0xb7, 0xf8, 0x93, 0xb9, 0x61, - 0x35, 0x22, 0xbb, 0xa4, 0xe1, 0xf0, 0x82, 0xbc, 0xd1, 0x37, 0x30, 0x52, - 0x22, 0xba, 0x00, 0xb2, 0x1c, 0x40, 0xe2, 0x98, 0xfa, 0xc4, 0x1d, 0x83, - 0x12, 0x52, 0x75, 0x03, 0x82, 0xcc, 0x84, 0x90, 0x63, 0x41, 0x6b, 0x8f, - 0x0b, 0xab, 0x77, 0xe0, 0x84, 0xbd, 0xfb, 0xd3, 0xe1, 0xe1, 0xc9, 0xd1, - 0xb3, 0x97, 0x87, 0x02, 0x09, 0x64, 0x1f, 0xbd, 0x3e, 0xfb, 0xf1, 0x65, - 0x07, 0xf1, 0x5d, 0x06, 0xef, 0xb3, 0xda, 0xa0, 0x3f, 0xd6, 0xd1, 0x08, - 0x41, 0xad, 0x30, 0x81, 0x73, 0x43, 0x9e, 0xc6, 0x85, 0xc2, 0x81, 0x60, - 0x85, 0xa0, 0xbb, 0x0a, 0xc9, 0x49, 0xb4, 0xcc, 0xc4, 0xcc, 0xb4, 0x1c, - 0x82, 0x87, 0x36, 0x64, 0x6a, 0x7f, 0x6a, 0xd2, 0x6a, 0xa2, 0x59, 0x4a, - 0xc8, 0x0c, 0x12, 0x06, 0x1d, 0x27, 0x95, 0x28, 0xab, 0xa9, 0xa4, 0x62, - 0x59, 0xbc, 0x27, 0x37, 0x4d, 0xcd, 0xc2, 0xbd, 0x85, 0x9b, 0xd2, 0x3e, - 0x84, 0x9d, 0x52, 0x70, 0x59, 0x07, 0x3a, 0x4e, 0x25, 0xa7, 0xa1, 0x83, - 0x85, 0x55, 0x8e, 0x45, 0xa7, 0x61, 0x36, 0xc0, 0x59, 0x2c, 0x30, 0x15, - 0xe6, 0xfa, 0xb4, 0x0f, 0xa0, 0xb1, 0x0d, 0x19, 0xd3, 0x4f, 0xb0, 0x57, - 0x58, 0xcc, 0x9e, 0x4c, 0x58, 0x9f, 0x7c, 0x22, 0x17, 0x66, 0x58, 0xa4, - 0x4d, 0x58, 0x83, 0x8d, 0x6e, 0xf2, 0x55, 0xb2, 0x4e, 0x8b, 0x48, 0x7f, - 0xa2, 0x78, 0xfc, 0x68, 0x73, 0x7b, 0x2b, 0x59, 0x97, 0x05, 0xdc, 0xe8, - 0x0a, 0x81, 0x50, 0xcc, 0x0b, 0x8d, 0x5b, 0x91, 0x46, 0x48, 0xcc, 0xc2, - 0xe2, 0x42, 0x17, 0x1c, 0x0f, 0x12, 0xd9, 0x8d, 0x25, 0x71, 0x57, 0xce, - 0x71, 0x27, 0x3a, 0x4b, 0x1d, 0x81, 0xeb, 0x8b, 0x94, 0x83, 0x5b, 0x4a, - 0x4c, 0xdd, 0xc9, 0x3f, 0x62, 0x06, 0xa2, 0x81, 0x3f, 0xc6, 0x1a, 0x23, - 0x2e, 0x92, 0x24, 0x8f, 0xb7, 0xe8, 0x76, 0x55, 0x9c, 0x77, 0x68, 0x40, - 0xef, 0xc9, 0xc6, 0x11, 0xbc, 0xc5, 0x3a, 0xf4, 0x3b, 0xcd, 0x43, 0x8d, - 0x8e, 0x76, 0x56, 0xc4, 0xee, 0xf6, 0xcb, 0xd0, 0x5d, 0xe0, 0x50, 0x6a, - 0x24, 0xfa, 0xa0, 0xd7, 0x84, 0x4e, 0xea, 0x26, 0x79, 0x0a, 0x3f, 0xbe, - 0xf5, 0x91, 0x5b, 0xa7, 0x2f, 0x36, 0x40, 0x4c, 0xc8, 0xaf, 0x30, 0x60, - 0x07, 0x1f, 0x50, 0xb5, 0xa9, 0xaf, 0xf5, 0x62, 0x04, 0x7b, 0x50, 0xe6, - 0xcf, 0xe8, 0x86, 0x98, 0x65, 0x75, 0x65, 0xb5, 0xd2, 0xf1, 0x35, 0x0a, - 0x79, 0x21, 0x07, 0xa9, 0x24, 0x56, 0x08, 0x62, 0x19, 0x05, 0xe2, 0x9c, - 0xbe, 0xe8, 0x92, 0x79, 0x1f, 0xcd, 0x23, 0x6e, 0x7b, 0xd8, 0x7b, 0x50, - 0x07, 0x68, 0x6e, 0xde, 0x2d, 0x8f, 0xbd, 0x44, 0xd4, 0x35, 0xcc, 0x87, - 0x94, 0x50, 0x29, 0x69, 0x53, 0x82, 0x73, 0xbd, 0x47, 0xcb, 0x88, 0xde, - 0x82, 0xaa, 0xba, 0xdc, 0xcc, 0x87, 0xef, 0xca, 0x2a, 0x35, 0x50, 0xb1, - 0xf0, 0xe9, 0x10, 0x3f, 0x4d, 0x3a, 0x7d, 0x7b, 0x42, 0x7e, 0xc7, 0xcf, - 0x5b, 0x10, 0x1d, 0x38, 0x0a, 0x54, 0x31, 0xe5, 0x8f, 0xe1, 0x14, 0x9d, - 0x9e, 0xbe, 0x44, 0xb7, 0x79, 0x99, 0x62, 0x4c, 0x8e, 0xb2, 0xc8, 0x6c, - 0x7a, 0x41, 0x66, 0xe6, 0xd9, 0xfb, 0x41, 0xb5, 0xbd, 0x6d, 0xfb, 0x6d, - 0xee, 0x03, 0x43, 0xfc, 0x3f, 0xf9, 0xd3, 0xc1, 0xe9, 0x1f, 0xe0, 0x89, - 0xb7, 0x6f, 0x8e, 0x92, 0x75, 0xc4, 0xc7, 0x4f, 0xbe, 0x7c, 0xb4, 0xbd, - 0xb3, 0x11, 0xe9, 0x26, 0x91, 0xa3, 0x58, 0x6f, 0xb0, 0xb0, 0x23, 0x84, - 0x98, 0xc5, 0xb7, 0x8a, 0x6b, 0x90, 0xdd, 0xc4, 0x28, 0x62, 0x2b, 0x28, - 0x4b, 0x40, 0x2c, 0x76, 0x79, 0x01, 0x1d, 0x1e, 0xe1, 0x5e, 0x47, 0x6a, - 0xa5, 0x48, 0x49, 0x0c, 0x43, 0x46, 0x77, 0xe3, 0xe3, 0x4b, 0x35, 0xfe, - 0x6c, 0xf1, 0x4e, 0x95, 0x99, 0xe1, 0x22, 0xf4, 0x7a, 0xb2, 0x0c, 0x4e, - 0x71, 0xc0, 0x43, 0x00, 0x2d, 0x4b, 0xb7, 0x1d, 0xde, 0x75, 0x5c, 0xa9, - 0xeb, 0xb4, 0x79, 0x39, 0x13, 0x67, 0xe2, 0x76, 0x60, 0x9a, 0xbd, 0x9a, - 0x1c, 0xa7, 0x71, 0x4b, 0xd4, 0xd4, 0xe1, 0xeb, 0x1f, 0x3a, 0xc9, 0x2d, - 0x0d, 0xb5, 0xec, 0x62, 0x63, 0x1b, 0xe1, 0xe4, 0x50, 0x30, 0x0d, 0x41, - 0xb5, 0x71, 0x31, 0x66, 0xa0, 0xe1, 0x53, 0x29, 0x87, 0xc6, 0x13, 0x5a, - 0xd4, 0x00, 0x30, 0xa1, 0x9a, 0x62, 0x6b, 0x25, 0xb0, 0x0f, 0x8f, 0x8b, - 0x8b, 0xed, 0x5b, 0x97, 0x3c, 0xd8, 0xac, 0x1e, 0x6c, 0xa0, 0x44, 0x47, - 0x01, 0x9e, 0x0a, 0x0b, 0xa3, 0x06, 0x40, 0x32, 0xe2, 0xb3, 0x1e, 0xcc, - 0x1b, 0x4a, 0x3b, 0xca, 0xde, 0x0e, 0xab, 0xd1, 0xaa, 0x71, 0x72, 0x1a, - 0x37, 0x06, 0x8f, 0xc0, 0xd0, 0x70, 0xbb, 0xd5, 0x6c, 0xc2, 0x3b, 0xb2, - 0x23, 0x26, 0x05, 0x8f, 0xbe, 0xc3, 0x80, 0x96, 0x21, 0xe8, 0xae, 0x2f, - 0xd8, 0xdd, 0xd8, 0xcd, 0xe7, 0x83, 0xa1, 0xa1, 0xe0, 0x22, 0x1f, 0xea, - 0xc7, 0x1d, 0x92, 0x95, 0x68, 0x25, 0xfe, 0x65, 0x1b, 0x2e, 0x42, 0x7b, - 0xe6, 0xea, 0x6d, 0xda, 0x77, 0x4f, 0xf1, 0xa7, 0x63, 0x56, 0x04, 0xc8, - 0xe0, 0x96, 0x51, 0x96, 0x03, 0x9f, 0xea, 0x07, 0x2c, 0x12, 0x03, 0x59, - 0xc4, 0x26, 0x84, 0x5d, 0x51, 0xa3, 0x0d, 0xf2, 0xf3, 0x47, 0x8c, 0x4c, - 0x99, 0xcf, 0x0e, 0xdf, 0x74, 0x93, 0x93, 0xc3, 0x57, 0x22, 0x1f, 0x00, - 0xd9, 0x31, 0x34, 0x9e, 0x4a, 0xd2, 0xbc, 0xb4, 0xd3, 0xd8, 0x39, 0x4a, - 0x8c, 0x0c, 0x5e, 0xe2, 0xc5, 0x4e, 0xab, 0x6a, 0x3e, 0x21, 0x95, 0xce, - 0x76, 0x81, 0xa7, 0xf2, 0x19, 0x91, 0xd3, 0xad, 0x0f, 0x18, 0xff, 0xa7, - 0xec, 0x43, 0x58, 0xf7, 0xf2, 0x3c, 0x79, 0x4a, 0x48, 0xbd, 0x51, 0x61, - 0x3a, 0x41, 0xf4, 0xf9, 0x53, 0x56, 0xc2, 0x8d, 0x5f, 0x54, 0x49, 0xa3, - 0x72, 0x98, 0xc5, 0xe9, 0x49, 0xb9, 0x3a, 0x6a, 0xa0, 0x81, 0x98, 0x4a, - 0xd1, 0x61, 0x72, 0xe2, 0x1d, 0xbe, 0x97, 0x02, 0xeb, 0xae, 0x51, 0xd1, - 0xb2, 0xb5, 0x6e, 0xb2, 0x86, 0x10, 0x9d, 0xf8, 0x2f, 0xd5, 0x9e, 0x19, - 0xb2, 0xa3, 0x6d, 0xad, 0x1b, 0xce, 0xc1, 0x9a, 0x6c, 0xda, 0x1a, 0x48, - 0xd6, 0xd2, 0x0e, 0x19, 0xeb, 0xc8, 0xa1, 0x9d, 0x4a, 0xdf, 0x01, 0x24, - 0x88, 0xcc, 0xf1, 0xc4, 0x34, 0x24, 0x74, 0xbc, 0x52, 0x4b, 0x96, 0x35, - 0x14, 0x2a, 0x94, 0x8b, 0x46, 0x01, 0x8b, 0xd0, 0x7a, 0xdd, 0xfb, 0x6d, - 0xa2, 0x7d, 0xd2, 0x03, 0xf5, 0x71, 0x9b, 0x05, 0xcd, 0x73, 0x89, 0xb6, - 0xa5, 0x68, 0x4c, 0xfc, 0x50, 0x7b, 0x7e, 0xac, 0x4f, 0x8f, 0xd5, 0xe0, - 0x29, 0xdd, 0x18, 0x97, 0xb8, 0x6d, 0x26, 0x94, 0x0c, 0xcb, 0x18, 0xd9, - 0x2e, 0x45, 0x45, 0xca, 0x7a, 0xda, 0xe6, 0x53, 0x87, 0x7e, 0xbd, 0xcf, - 0x25, 0x92, 0xbd, 0x0c, 0x46, 0xfe, 0x88, 0x1b, 0xba, 0x73, 0xd9, 0x48, - 0xc3, 0xf5, 0x54, 0x9c, 0xed, 0x8c, 0xcf, 0x0b, 0xed, 0x83, 0x29, 0xc3, - 0xd2, 0x78, 0x8f, 0x7d, 0x8e, 0x07, 0x28, 0xb6, 0x63, 0x68, 0x6f, 0x42, - 0xd5, 0xc9, 0x42, 0x29, 0x0d, 0xcd, 0x6c, 0xa3, 0x83, 0xcc, 0xdb, 0xc6, - 0x6e, 0x52, 0x53, 0x09, 0x70, 0x19, 0x60, 0x7d, 0x09, 0x01, 0x78, 0x64, - 0x40, 0xc3, 0xa5, 0x0e, 0xa0, 0x27, 0x38, 0x80, 0x1a, 0xed, 0x85, 0x6f, - 0xff, 0x5b, 0xbb, 0x97, 0x40, 0xb1, 0xa8, 0xad, 0xde, 0x21, 0x52, 0x87, - 0xf7, 0x3e, 0x07, 0xb3, 0x3e, 0x99, 0xe0, 0x43, 0x7d, 0x0e, 0xa4, 0xae, - 0x82, 0x84, 0xcf, 0xec, 0x43, 0xad, 0x84, 0xe2, 0xb3, 0x95, 0x3e, 0x13, - 0xb1, 0x58, 0xf1, 0x1a, 0xaa, 0x0b, 0xd0, 0x1f, 0x7c, 0x52, 0xc8, 0x7e, - 0x8f, 0x4a, 0x6d, 0xf4, 0x48, 0x26, 0x7b, 0x0a, 0x53, 0xcc, 0x86, 0xdf, - 0xc6, 0xd8, 0x4d, 0xde, 0xf8, 0x61, 0xf1, 0xc0, 0xf4, 0xb8, 0xd9, 0xc1, - 0xcd, 0x04, 0x4e, 0xe6, 0x65, 0x5e, 0x9e, 0x50, 0x9e, 0x29, 0x94, 0x15, - 0x66, 0x56, 0x40, 0x06, 0xc0, 0xca, 0xa2, 0x10, 0x0d, 0x04, 0x9f, 0xe7, - 0x4c, 0xe5, 0x09, 0x72, 0x8d, 0xfb, 0xe4, 0xe0, 0xb5, 0x54, 0x89, 0x86, - 0x8b, 0x82, 0xcc, 0xf2, 0x99, 0x04, 0x39, 0xf2, 0x08, 0x38, 0xa4, 0x82, - 0xb2, 0x43, 0x68, 0xef, 0x6d, 0x94, 0x7c, 0xc0, 0x35, 0xa0, 0x05, 0xbf, - 0x33, 0x7e, 0x83, 0xb5, 0x12, 0xcf, 0xa1, 0x89, 0xeb, 0x7c, 0x58, 0x5f, - 0xf6, 0x31, 0x69, 0x83, 0x82, 0x83, 0xf3, 0x9a, 0xf2, 0x70, 0x35, 0x57, - 0x09, 0xfe, 0x6c, 0x16, 0xb7, 0x3b, 0xcf, 0xbc, 0x55, 0x9a, 0x6d, 0x84, - 0xb4, 0x6c, 0x5c, 0xa3, 0x29, 0x4b, 0x11, 0x90, 0x99, 0x4d, 0x9a, 0x94, - 0xe3, 0xb4, 0xc9, 0xfa, 0x43, 0xd7, 0xe0, 0x03, 0x53, 0x38, 0x99, 0xa3, - 0x51, 0xfe, 0x21, 0x88, 0x4e, 0x5a, 0x94, 0xae, 0x2f, 0xe7, 0x0b, 0x8f, - 0xc4, 0xda, 0xfb, 0x35, 0x14, 0x42, 0xd6, 0xfe, 0xb4, 0x86, 0x7e, 0xf7, - 0xa9, 0xd4, 0xfe, 0x14, 0x75, 0x10, 0xa4, 0x9e, 0xf7, 0x39, 0x90, 0x2b, - 0xb6, 0x0f, 0xdc, 0x6f, 0x6d, 0xb2, 0xa6, 0xf5, 0x5d, 0x92, 0xb5, 0x57, - 0x6b, 0x96, 0x38, 0x51, 0xc3, 0x70, 0x24, 0xd3, 0x8a, 0x32, 0xb7, 0xf0, - 0x32, 0x5c, 0xbb, 0xa0, 0x76, 0x93, 0xb5, 0x1f, 0xd6, 0x82, 0x09, 0xd3, - 0x67, 0x64, 0xd9, 0xd4, 0x78, 0x94, 0xf0, 0xc0, 0xfa, 0x7b, 0xe8, 0x03, - 0x6e, 0xbd, 0x1f, 0x30, 0x8e, 0x0a, 0x2e, 0xb3, 0x0d, 0x36, 0x27, 0x6e, - 0x6f, 0xed, 0x3c, 0x84, 0x25, 0x24, 0xde, 0x48, 0x59, 0x9f, 0xea, 0xce, - 0xdc, 0x7e, 0x1f, 0xa6, 0x86, 0x0f, 0xf5, 0x83, 0xd9, 0x1c, 0x2b, 0x2a, - 0xfd, 0xa9, 0x9b, 0xec, 0x4e, 0x68, 0xf7, 0xb6, 0x7f, 0x88, 0x2b, 0x4c, - 0x01, 0x49, 0xd1, 0x16, 0xe3, 0xfc, 0xb1, 0x5e, 0xe5, 0x40, 0x5d, 0x60, - 0xc8, 0x9f, 0xf0, 0xe0, 0x5c, 0x98, 0x48, 0x63, 0x5b, 0x2c, 0x4b, 0xaf, - 0x39, 0xf2, 0xa0, 0x0d, 0x4e, 0x38, 0x1f, 0x44, 0xe0, 0x5f, 0xb9, 0xa0, - 0x1c, 0x30, 0x4a, 0x8c, 0x0c, 0x62, 0x7c, 0x92, 0x14, 0x71, 0xca, 0xf2, - 0x82, 0x60, 0xd5, 0xcd, 0xb4, 0xa9, 0x5a, 0x5e, 0xc3, 0xcb, 0xc4, 0x56, - 0xe8, 0x50, 0x04, 0x1a, 0x58, 0x24, 0x76, 0xc8, 0x87, 0xc6, 0x8a, 0xd4, - 0xe9, 0x95, 0xa2, 0xd2, 0x29, 0x25, 0xa0, 0x18, 0xba, 0xd1, 0x20, 0x1b, - 0x12, 0x38, 0x32, 0x59, 0xc2, 0x38, 0x0c, 0x65, 0x50, 0xe6, 0x33, 0x32, - 0xa8, 0xca, 0xbc, 0x7b, 0x36, 0x6f, 0x49, 0x20, 0x1f, 0xdf, 0x50, 0x4d, - 0x79, 0x87, 0xd7, 0x89, 0x1a, 0x9c, 0x2a, 0xcc, 0x7e, 0x0c, 0xbc, 0x50, - 0xb8, 0x4e, 0x84, 0x41, 0x26, 0xbc, 0xc7, 0x8e, 0xf4, 0xfd, 0x89, 0x78, - 0xd5, 0x02, 0xf7, 0xb1, 0x4e, 0xb6, 0x61, 0x57, 0xef, 0xf6, 0x38, 0xc4, - 0x2f, 0x6c, 0x7d, 0xe4, 0x0b, 0xaf, 0x56, 0xe3, 0x6e, 0xf8, 0x74, 0xb7, - 0xb1, 0x4d, 0x72, 0xb7, 0xd1, 0x27, 0x5e, 0xe1, 0x1d, 0x77, 0xa9, 0x93, - 0xaa, 0xf6, 0x09, 0xd7, 0x98, 0x14, 0x72, 0x72, 0x7c, 0xb2, 0x9b, 0x48, - 0x7e, 0x88, 0x14, 0xf4, 0xe0, 0xdc, 0x1e, 0x29, 0xa0, 0x4e, 0x1e, 0x78, - 0xfa, 0xd6, 0xa7, 0x63, 0x00, 0xdb, 0x1b, 0x04, 0x66, 0x85, 0x3a, 0x32, - 0x3b, 0xe8, 0x31, 0x19, 0x0c, 0xb8, 0xdd, 0xab, 0xf4, 0xe6, 0x3c, 0x8b, - 0xb3, 0x2e, 0x95, 0xdf, 0x69, 0x64, 0x1c, 0xe7, 0x3b, 0x23, 0x47, 0xad, - 0x02, 0x49, 0x4f, 0xe0, 0x9e, 0x81, 0x4b, 0xac, 0x07, 0x6f, 0x4a, 0x78, - 0x7b, 0xc0, 0xab, 0x03, 0x0a, 0xd6, 0xa1, 0xb8, 0xcc, 0x11, 0x86, 0x43, - 0x23, 0x7a, 0xf5, 0x25, 0x0b, 0xc3, 0x13, 0x94, 0x9e, 0x16, 0x02, 0xb7, - 0x91, 0xbc, 0x53, 0x87, 0x53, 0x42, 0xd1, 0x69, 0x05, 0xc1, 0x8d, 0x4f, - 0x52, 0xad, 0x20, 0xe2, 0x52, 0x2d, 0x88, 0xd5, 0xa2, 0x0c, 0x10, 0x9b, - 0x60, 0x07, 0x29, 0xa3, 0xa8, 0xc2, 0x88, 0x5e, 0xbf, 0x3c, 0x3d, 0x8b, - 0xb2, 0x35, 0xcf, 0xd9, 0xb8, 0x68, 0x5e, 0x6f, 0xef, 0xf0, 0xf6, 0x65, - 0x0e, 0x5e, 0x1e, 0x9d, 0x9e, 0x29, 0xdd, 0xa1, 0xe1, 0x67, 0x2f, 0x39, - 0xc5, 0xbc, 0x98, 0xe7, 0x0e, 0x0d, 0x6e, 0x2c, 0x10, 0x42, 0xe3, 0x1b, - 0x49, 0x2e, 0x65, 0xad, 0x28, 0x2f, 0xe3, 0x8a, 0xeb, 0x38, 0x84, 0xaf, - 0x1d, 0xa4, 0xfc, 0xb0, 0x90, 0xb2, 0xc8, 0x9c, 0x48, 0x57, 0xcd, 0xcf, - 0x7b, 0xba, 0x20, 0xb9, 0xd8, 0x36, 0xab, 0x9b, 0xc9, 0x79, 0x81, 0x21, - 0x70, 0x20, 0x34, 0xbc, 0xaf, 0xa2, 0x54, 0x17, 0xdd, 0x78, 0x9c, 0xdc, - 0x69, 0x73, 0xe7, 0xd9, 0xe4, 0x55, 0x71, 0xb1, 0x4b, 0xa2, 0x02, 0x76, - 0xd9, 0x1b, 0x09, 0x48, 0xd8, 0x13, 0xac, 0x7a, 0x97, 0xc4, 0x4d, 0x84, - 0xdc, 0x47, 0xc1, 0xa4, 0x6f, 0xb0, 0x5c, 0x99, 0x24, 0x2a, 0x84, 0x54, - 0x5c, 0xc1, 0x8d, 0xf0, 0x24, 0xb1, 0x3a, 0x45, 0x34, 0x86, 0xb8, 0x22, - 0x45, 0x08, 0x9f, 0xa8, 0x98, 0x85, 0xfa, 0x3c, 0x18, 0x62, 0xa7, 0x84, - 0xbc, 0xa8, 0xe6, 0x9f, 0x78, 0x79, 0xca, 0x0c, 0xad, 0x34, 0x57, 0x51, - 0x2a, 0x08, 0x70, 0xef, 0x8c, 0xd0, 0xde, 0xc9, 0x9d, 0x86, 0x47, 0x4a, - 0x73, 0xac, 0x9a, 0x2b, 0xc5, 0x0d, 0xe1, 0xd6, 0x37, 0x48, 0xc6, 0xf0, - 0x24, 0x3d, 0x89, 0xbc, 0x39, 0x3c, 0x7b, 0x13, 0x16, 0x2e, 0x3a, 0x50, - 0x26, 0x8e, 0x35, 0x17, 0x50, 0xd7, 0x0f, 0x88, 0x28, 0xe3, 0x88, 0x7f, - 0x1b, 0x24, 0x16, 0x19, 0x48, 0x2f, 0xb2, 0x1e, 0xe2, 0x0b, 0x08, 0xd6, - 0xa6, 0x87, 0x00, 0x10, 0x12, 0xa5, 0xd2, 0xd4, 0xc8, 0xe3, 0x29, 0xc3, - 0x38, 0x47, 0x5c, 0xaa, 0x28, 0x79, 0xf9, 0x08, 0x23, 0x8f, 0x9b, 0xa6, - 0x49, 0x67, 0x9b, 0xbc, 0x61, 0xb3, 0x47, 0x44, 0x71, 0x14, 0x80, 0x39, - 0xc6, 0x38, 0x42, 0x3d, 0x56, 0x55, 0xad, 0xc9, 0x61, 0x28, 0x4a, 0xb8, - 0x6a, 0xd3, 0x7c, 0x14, 0xf8, 0x1c, 0x1a, 0x10, 0xb9, 0x3a, 0x5b, 0xad, - 0x68, 0x4c, 0xe4, 0x1a, 0x6f, 0xe6, 0x1a, 0xb8, 0x22, 0x17, 0x40, 0x9a, - 0x6f, 0x8f, 0x9e, 0xbd, 0x0c, 0x07, 0x54, 0x56, 0x97, 0xd1, 0xd1, 0x2d, - 0x33, 0x8d, 0x23, 0x8f, 0xc2, 0xdd, 0x47, 0xbb, 0xa9, 0xe9, 0x6a, 0xf3, - 0x69, 0xfe, 0x37, 0xbc, 0x2a, 0x48, 0x09, 0x1b, 0xe5, 0x2c, 0x12, 0x5e, - 0x06, 0xb9, 0xa9, 0x4a, 0xfc, 0xca, 0x6a, 0x6d, 0x12, 0x1f, 0xce, 0xd8, - 0x92, 0xe5, 0x6a, 0xbc, 0x78, 0x59, 0x4d, 0xe7, 0x8f, 0xf4, 0x39, 0x5a, - 0x7b, 0x77, 0xc9, 0xd1, 0xda, 0xed, 0xa2, 0xd2, 0x05, 0x3b, 0xd6, 0x82, - 0x95, 0xfc, 0xb7, 0x39, 0x86, 0x81, 0xb6, 0x56, 0xc1, 0x25, 0x00, 0xfb, - 0x71, 0x8f, 0x54, 0xaf, 0xa7, 0x54, 0x40, 0xce, 0xf9, 0x65, 0x52, 0x0f, - 0x77, 0xa8, 0xa1, 0x25, 0xea, 0x51, 0x2c, 0xb5, 0xe0, 0xdc, 0xfa, 0xf3, - 0x37, 0xc7, 0xaf, 0x7a, 0x67, 0xc7, 0x1b, 0x74, 0x9c, 0x39, 0x3e, 0x39, - 0x09, 0x48, 0x47, 0x5a, 0xd6, 0xcf, 0x07, 0x6a, 0xb3, 0x99, 0xc7, 0x8c, - 0xfd, 0xeb, 0xd5, 0x86, 0xaf, 0x67, 0x4b, 0x2f, 0x87, 0x72, 0x80, 0x1a, - 0x1e, 0x36, 0x65, 0xc1, 0x1b, 0x09, 0x11, 0x03, 0x8c, 0x06, 0x29, 0xde, - 0x5f, 0x9a, 0x65, 0x29, 0x48, 0xf9, 0x75, 0x1d, 0xa2, 0xbb, 0x79, 0x74, - 0x84, 0xb9, 0x50, 0x20, 0xee, 0x86, 0x79, 0x8a, 0xea, 0x02, 0x98, 0x6b, - 0x5a, 0x96, 0xc5, 0xb5, 0x09, 0x38, 0x78, 0x17, 0x00, 0x91, 0x84, 0x8a, - 0x72, 0xde, 0x13, 0x01, 0xcd, 0x62, 0x39, 0x0f, 0x20, 0x27, 0xe8, 0x9f, - 0x21, 0x92, 0x3d, 0xfc, 0xbf, 0xac, 0x5e, 0xab, 0x49, 0x24, 0x32, 0xab, - 0x37, 0x63, 0xf0, 0x3f, 0xc6, 0xb0, 0xee, 0x3a, 0x42, 0x69, 0xa4, 0xb7, - 0xbb, 0xb5, 0x6a, 0x5d, 0xcc, 0x50, 0x4d, 0x97, 0x86, 0xfc, 0xb2, 0xeb, - 0xaa, 0x16, 0xc4, 0xa8, 0x2d, 0x23, 0xcf, 0x42, 0x04, 0x33, 0xc1, 0xc5, - 0x38, 0x09, 0xe5, 0xa0, 0x46, 0x43, 0x80, 0xf6, 0x29, 0x1e, 0xfa, 0x2b, - 0x7f, 0x5c, 0x53, 0xe0, 0x18, 0x23, 0x0a, 0x5e, 0xad, 0x13, 0xed, 0x22, - 0x59, 0x0f, 0x95, 0x16, 0x15, 0xc2, 0xe3, 0xa5, 0x7c, 0xb7, 0x67, 0x55, - 0xea, 0xf8, 0x98, 0xef, 0xfe, 0xfc, 0xb3, 0x46, 0x04, 0xc9, 0xd5, 0x88, - 0x0a, 0xf6, 0x46, 0xb7, 0x25, 0xdd, 0x53, 0x92, 0xb3, 0x86, 0x85, 0x1f, - 0x9a, 0x85, 0xfc, 0x4c, 0x33, 0xa9, 0xc1, 0x24, 0x59, 0xd5, 0x5a, 0x90, - 0xbb, 0x2e, 0x40, 0xa5, 0xbf, 0xd4, 0x22, 0x39, 0x21, 0x4f, 0x1d, 0x48, - 0x52, 0x8b, 0x72, 0x6b, 0xe0, 0x0e, 0x5d, 0x03, 0x01, 0x5c, 0x37, 0x9e, - 0x3c, 0xb3, 0x43, 0x10, 0xd2, 0xaf, 0xa7, 0x31, 0x5a, 0x53, 0x6c, 0x4b, - 0x52, 0x60, 0x67, 0xf5, 0x0d, 0xd0, 0xa1, 0xad, 0x28, 0xf0, 0x8e, 0x78, - 0xce, 0xa0, 0xcc, 0xc4, 0x2a, 0xe4, 0x04, 0x28, 0x2e, 0x92, 0x92, 0xe3, - 0xa7, 0x14, 0x90, 0xd9, 0x67, 0x33, 0xb6, 0x96, 0x6d, 0x90, 0x74, 0x71, - 0x55, 0x61, 0xfd, 0x92, 0x4b, 0xcd, 0x08, 0xcd, 0xa3, 0x67, 0xd3, 0x83, - 0x94, 0x45, 0xa2, 0x9a, 0xe0, 0xea, 0x92, 0x40, 0x76, 0xf9, 0x47, 0x0c, - 0x71, 0x03, 0x39, 0x7c, 0x98, 0x70, 0x78, 0x1e, 0x29, 0x64, 0xd3, 0x10, - 0x3d, 0x1f, 0x59, 0x5e, 0x74, 0x33, 0x7b, 0x1a, 0xd3, 0x8c, 0x57, 0x06, - 0x82, 0xd3, 0x14, 0xe2, 0x27, 0xe3, 0xf8, 0x49, 0x59, 0x8a, 0x97, 0x24, - 0xc6, 0x52, 0x74, 0xd5, 0x04, 0x95, 0x41, 0x64, 0x0b, 0xae, 0xc4, 0x06, - 0xa2, 0x61, 0x90, 0x4b, 0x04, 0x7d, 0x6b, 0x0e, 0x23, 0x87, 0x5d, 0x3c, - 0xf4, 0x60, 0x6b, 0x0d, 0x94, 0x10, 0x0b, 0x23, 0xef, 0x57, 0x1c, 0x83, - 0x2f, 0xeb, 0xc2, 0x9e, 0xc1, 0x51, 0x1c, 0x83, 0x4e, 0x56, 0x4c, 0x0a, - 0x64, 0xec, 0x06, 0x80, 0x81, 0xca, 0x42, 0x1f, 0xa3, 0xb2, 0x18, 0x71, - 0xe1, 0x12, 0xac, 0x2a, 0xaf, 0x82, 0xae, 0xe0, 0xfa, 0x09, 0x4d, 0x06, - 0x93, 0xfd, 0xee, 0xd6, 0x36, 0x68, 0x87, 0x5b, 0x3b, 0x14, 0x7c, 0x07, - 0xbf, 0xec, 0xf6, 0x2d, 0x19, 0x33, 0x3c, 0x4d, 0x36, 0x22, 0x84, 0xe4, - 0x60, 0xbb, 0x13, 0x91, 0xdf, 0xee, 0x87, 0x0f, 0xfc, 0x45, 0xd7, 0xc5, - 0xe4, 0x91, 0xd9, 0x7c, 0xa8, 0x85, 0x1a, 0x5a, 0x86, 0xa6, 0x21, 0xef, - 0x16, 0x98, 0x83, 0xf7, 0x9a, 0xc2, 0x79, 0x8b, 0xac, 0x45, 0xf8, 0x42, - 0xbe, 0x6a, 0x0c, 0x5e, 0xac, 0x75, 0x66, 0x05, 0x27, 0x6a, 0x96, 0x2b, - 0x65, 0xd7, 0x7c, 0x84, 0x27, 0xef, 0x0c, 0x4e, 0x9b, 0xab, 0xa2, 0xe0, - 0x79, 0xdc, 0xfa, 0xd0, 0x38, 0x8f, 0xe7, 0x37, 0xf1, 0x28, 0x80, 0xd7, - 0xc9, 0xd9, 0x0e, 0xd5, 0x2b, 0xc8, 0x9e, 0x82, 0x5c, 0x63, 0x8f, 0xaa, - 0xd5, 0x00, 0x4d, 0xe2, 0x3a, 0x29, 0x29, 0xf1, 0xdf, 0x8a, 0x23, 0xc3, - 0x7f, 0xed, 0x7a, 0xc5, 0x5a, 0x21, 0x92, 0x88, 0x4f, 0xca, 0x39, 0xb5, - 0x15, 0x90, 0xa0, 0x39, 0xad, 0x7e, 0xa0, 0xcf, 0xba, 0x1a, 0x61, 0xae, - 0x06, 0x2d, 0x99, 0x41, 0xaa, 0x6c, 0xac, 0x25, 0xb8, 0xc9, 0xaa, 0x1b, - 0x5d, 0xe0, 0xca, 0xa3, 0xda, 0x2e, 0x70, 0xd3, 0xd0, 0x57, 0xce, 0x85, - 0xb6, 0x5a, 0x30, 0xb7, 0x71, 0xf2, 0x97, 0x2b, 0x2a, 0x86, 0x12, 0x25, - 0xcd, 0xcb, 0x94, 0x8e, 0xeb, 0x5e, 0x75, 0x35, 0x88, 0x2e, 0x6d, 0x7f, - 0x1e, 0x23, 0x3e, 0xfe, 0x12, 0xf5, 0x9d, 0xf0, 0x0c, 0xa7, 0x5e, 0x6a, - 0x26, 0xbb, 0x15, 0xd1, 0xbc, 0x94, 0x92, 0x70, 0x7f, 0x4c, 0x02, 0x23, - 0x30, 0x3e, 0x3e, 0x66, 0xd6, 0xe3, 0xb9, 0x3f, 0xdc, 0xff, 0x75, 0xc6, - 0x32, 0x96, 0x1d, 0x39, 0x78, 0x41, 0x11, 0x2b, 0xf0, 0xf3, 0x42, 0xa3, - 0xbf, 0xcd, 0xa9, 0x90, 0x63, 0xc5, 0xa9, 0xe1, 0x7c, 0x40, 0x0a, 0x1b, - 0x3a, 0xad, 0x30, 0x1e, 0xfb, 0xbc, 0xa4, 0xa2, 0x50, 0x72, 0x54, 0xa9, - 0xd9, 0xc0, 0x1d, 0xc4, 0x3d, 0x9b, 0x4a, 0x7f, 0x3a, 0x22, 0x76, 0x82, - 0x50, 0x8d, 0x2f, 0x0a, 0x55, 0x22, 0xc3, 0x59, 0x83, 0xdb, 0x92, 0x0a, - 0x90, 0xac, 0x8b, 0xbf, 0x04, 0x63, 0x04, 0xd0, 0x32, 0xdd, 0xab, 0x61, - 0xff, 0x42, 0x4d, 0x61, 0xf1, 0xc9, 0x62, 0xe1, 0x5e, 0x29, 0xe5, 0xa0, - 0x95, 0x8b, 0xe0, 0x3f, 0xdf, 0xa7, 0x15, 0x65, 0x14, 0x35, 0x5a, 0xde, - 0x68, 0x0f, 0x3e, 0x5b, 0x60, 0x8a, 0xed, 0x20, 0x96, 0x1f, 0x0b, 0x77, - 0xd2, 0x6c, 0xf6, 0x6e, 0xb9, 0x20, 0x1a, 0x44, 0x6f, 0x4e, 0xec, 0x7d, - 0xcf, 0x76, 0x75, 0xe5, 0xea, 0x36, 0x8e, 0xba, 0x2e, 0xf2, 0x69, 0x4f, - 0xcf, 0xf3, 0x53, 0xf9, 0xc5, 0xb2, 0xf1, 0xb0, 0x54, 0xe3, 0xcb, 0x67, - 0xf0, 0x83, 0x0d, 0x0f, 0x5c, 0x57, 0x32, 0xf8, 0xab, 0xc8, 0x42, 0x83, - 0x2d, 0x04, 0x96, 0xa0, 0x00, 0x70, 0xc9, 0x70, 0x5e, 0xda, 0x02, 0xaa, - 0xaa, 0x12, 0x2d, 0x75, 0x93, 0x73, 0xd1, 0x6b, 0x2d, 0xad, 0xa9, 0x83, - 0x39, 0x60, 0x91, 0x06, 0x35, 0x4e, 0x9e, 0x73, 0x41, 0x18, 0x48, 0x94, - 0xaa, 0x5b, 0xf0, 0x10, 0x9a, 0xdd, 0x26, 0xfb, 0xb5, 0xf9, 0x2d, 0xe9, - 0x96, 0xc6, 0x59, 0x76, 0x79, 0x86, 0x21, 0xb6, 0x9e, 0xaa, 0x53, 0x5a, - 0x96, 0x37, 0x0f, 0x4b, 0x0b, 0xde, 0xb0, 0x51, 0x71, 0x41, 0x15, 0x4d, - 0xcf, 0x09, 0xf2, 0x89, 0x9e, 0x8d, 0xa2, 0xdd, 0x51, 0x36, 0xa1, 0xe2, - 0x65, 0xa4, 0xe4, 0x51, 0xad, 0xf9, 0x64, 0x67, 0xf7, 0x09, 0x86, 0xa6, - 0xd1, 0xef, 0x8f, 0xb6, 0xbe, 0xda, 0x49, 0x82, 0x53, 0x19, 0x84, 0xce, - 0xc3, 0xb3, 0xe7, 0xb0, 0x82, 0x25, 0x70, 0xe7, 0x46, 0xfa, 0x50, 0x5a, - 0xa7, 0x58, 0x1a, 0xf4, 0x3d, 0x6c, 0x61, 0x9e, 0xd5, 0xa3, 0x7e, 0x51, - 0x5e, 0x60, 0x4e, 0xd1, 0x26, 0x02, 0x88, 0x6c, 0xd2, 0x0b, 0x3d, 0x38, - 0x08, 0x97, 0xa0, 0x79, 0x62, 0xde, 0x77, 0xaf, 0x9a, 0xd4, 0xb3, 0xde, - 0xd6, 0x96, 0x12, 0x01, 0xe9, 0xda, 0x54, 0x8b, 0x18, 0xc1, 0x0d, 0x70, - 0x73, 0x0d, 0x4b, 0x76, 0x71, 0x2f, 0x93, 0xce, 0xfe, 0xdb, 0xb3, 0x17, - 0xdf, 0xfc, 0xf1, 0xe5, 0xf1, 0x0f, 0x47, 0xaf, 0x3b, 0x92, 0x67, 0xa6, - 0x2b, 0x6d, 0x32, 0x5a, 0xd7, 0x61, 0x6d, 0xb0, 0xbb, 0x78, 0x8c, 0x34, - 0xbe, 0x4e, 0xa2, 0xc8, 0xe9, 0xfe, 0xe9, 0xcb, 0x8d, 0xa4, 0x43, 0x2d, - 0x50, 0x7f, 0x1d, 0xd3, 0xec, 0xc4, 0xdc, 0x2d, 0x99, 0xea, 0x5e, 0x9f, - 0x1d, 0x5e, 0xa1, 0x77, 0x96, 0xda, 0xc3, 0xf7, 0x17, 0xb6, 0xef, 0x40, - 0xe4, 0x31, 0xf1, 0xc5, 0xc9, 0x88, 0xd2, 0xf7, 0x14, 0xf1, 0x95, 0x2c, - 0x82, 0x86, 0x74, 0xc9, 0x17, 0x9f, 0xd7, 0x2a, 0x0c, 0x48, 0x18, 0x88, - 0x9e, 0x19, 0x32, 0xbc, 0x06, 0xc3, 0x4f, 0xc8, 0xe3, 0x4f, 0x64, 0x2a, - 0x49, 0x4d, 0xbe, 0x13, 0xe6, 0x7d, 0xc1, 0x34, 0xc5, 0xa0, 0x5c, 0x2a, - 0x84, 0xd0, 0x62, 0x46, 0x28, 0xbd, 0x02, 0xd6, 0x5f, 0xb9, 0x45, 0xe1, - 0x85, 0xe8, 0x24, 0xeb, 0x59, 0xff, 0xa2, 0xcf, 0x91, 0x29, 0xb8, 0x00, - 0x75, 0x18, 0x4c, 0x35, 0x2d, 0x0a, 0xb4, 0xa5, 0x6e, 0x34, 0x34, 0x0f, - 0x7f, 0x48, 0xef, 0xca, 0xfe, 0xfd, 0x1d, 0x21, 0x3d, 0x71, 0x47, 0x6b, - 0xb4, 0xff, 0xff, 0xb1, 0x96, 0xe4, 0x93, 0x74, 0xf6, 0x51, 0x5c, 0x05, - 0xd5, 0xf1, 0x1e, 0xee, 0x5b, 0xf2, 0x54, 0x72, 0x76, 0xac, 0x2e, 0x0f, - 0x71, 0x90, 0xd3, 0x00, 0x2e, 0xa0, 0xba, 0xa6, 0x3c, 0xe7, 0xb0, 0xe0, - 0x02, 0x16, 0x41, 0x88, 0x31, 0xb1, 0x6d, 0x6a, 0x7a, 0x72, 0x05, 0x4d, - 0x62, 0x9d, 0xb5, 0xfe, 0xfa, 0x86, 0x15, 0x54, 0x74, 0x68, 0x9c, 0x6b, - 0x01, 0x7a, 0x51, 0xfa, 0xcd, 0xc7, 0xca, 0x0d, 0x71, 0xb5, 0x36, 0xb8, - 0x95, 0xc6, 0xe9, 0x8d, 0x76, 0x97, 0x4e, 0xa5, 0x6a, 0x9b, 0xa6, 0xbd, - 0x88, 0x4f, 0x3c, 0x4c, 0xeb, 0xf3, 0xc5, 0x27, 0x84, 0x3e, 0x70, 0x45, - 0xbf, 0xf3, 0xb1, 0xef, 0xbd, 0x33, 0xae, 0x51, 0x88, 0x87, 0xfa, 0xce, - 0x9a, 0x49, 0xd4, 0x4e, 0x39, 0x98, 0x85, 0x90, 0x2a, 0xf8, 0x1b, 0x15, - 0x9d, 0x78, 0x93, 0x48, 0xf5, 0xb9, 0x73, 0x93, 0xd4, 0x1e, 0xa0, 0xcb, - 0x1c, 0xd2, 0x23, 0xd9, 0xcb, 0x24, 0xe3, 0x92, 0x33, 0x19, 0x95, 0x7d, - 0x27, 0xe5, 0x4a, 0x8c, 0xff, 0xa1, 0xc7, 0x56, 0x8c, 0x86, 0x36, 0x88, - 0x06, 0x5f, 0xb2, 0x71, 0xf5, 0xf5, 0xa3, 0x3e, 0x3e, 0xc3, 0xfa, 0xe1, - 0xbe, 0xc4, 0xeb, 0x47, 0x4f, 0xdc, 0xbe, 0x7e, 0x81, 0xc6, 0xd9, 0xe8, - 0xa8, 0xab, 0x48, 0x29, 0x2f, 0x25, 0x43, 0x95, 0xc0, 0x7d, 0x82, 0xdf, - 0x11, 0x29, 0xa2, 0xcd, 0x27, 0x18, 0xea, 0x81, 0xf8, 0xde, 0x64, 0xb3, - 0x8c, 0xd7, 0xdb, 0x07, 0x4b, 0xc7, 0x0e, 0xdb, 0x24, 0x54, 0x87, 0xa4, - 0xdf, 0x62, 0xbc, 0x1f, 0x90, 0xb7, 0xf2, 0x59, 0xee, 0x0b, 0xbd, 0xb1, - 0xc1, 0x4e, 0xac, 0x98, 0x6a, 0x3e, 0x0e, 0xa0, 0x2c, 0x31, 0xde, 0xd8, - 0xfa, 0x8f, 0x6f, 0x9e, 0xff, 0xc5, 0x38, 0xf7, 0x86, 0x44, 0x27, 0x36, - 0x9a, 0xf6, 0xe1, 0x11, 0xce, 0x21, 0xad, 0x85, 0x89, 0xc3, 0x64, 0xf1, - 0xee, 0x0c, 0x33, 0xb7, 0xab, 0x60, 0x58, 0x50, 0xd4, 0xef, 0x3a, 0xbc, - 0x80, 0x46, 0xe8, 0x53, 0xb1, 0xc8, 0xec, 0xf6, 0x1f, 0x91, 0x69, 0x15, - 0xee, 0xc9, 0x47, 0xbb, 0x3b, 0xdb, 0x1b, 0xb7, 0x4c, 0x20, 0x09, 0x6b, - 0x28, 0xa6, 0xf8, 0xec, 0xc3, 0x8c, 0x6e, 0xd5, 0xf5, 0xc3, 0x9f, 0x4f, - 0x5e, 0xaf, 0x3a, 0x81, 0xc8, 0x9f, 0x1e, 0x74, 0x56, 0x6d, 0x9b, 0x5a, - 0x66, 0x7c, 0x20, 0xaa, 0x98, 0x6b, 0x19, 0x3c, 0x9d, 0xe7, 0x65, 0x8e, - 0x17, 0x4c, 0x87, 0x66, 0xd8, 0x79, 0x59, 0x4c, 0x87, 0x20, 0xab, 0x1d, - 0x23, 0x58, 0x46, 0x86, 0xd7, 0xa7, 0xa7, 0x18, 0xb3, 0x81, 0x0a, 0x93, - 0x5b, 0x8c, 0xaa, 0xf9, 0xc8, 0x5a, 0x3c, 0xa1, 0xe9, 0x88, 0xec, 0xa7, - 0x88, 0x22, 0xbb, 0x40, 0xee, 0xb7, 0x50, 0x7b, 0x8f, 0x94, 0x87, 0x91, - 0x54, 0xb1, 0x6e, 0x10, 0xba, 0xfb, 0x32, 0xa2, 0x74, 0xda, 0x0b, 0xd5, - 0x36, 0x24, 0x6f, 0xbc, 0x70, 0xe9, 0xb5, 0x81, 0xfc, 0xba, 0xae, 0x50, - 0x84, 0x87, 0x95, 0x03, 0xd1, 0x09, 0x85, 0x10, 0x12, 0xba, 0x06, 0xc5, - 0x14, 0xbd, 0x29, 0x01, 0x03, 0x07, 0x65, 0xaa, 0x4c, 0xcb, 0x1b, 0x59, - 0x41, 0x36, 0x6d, 0x52, 0x2c, 0x7a, 0x32, 0xa2, 0x37, 0x07, 0x27, 0x67, - 0xc9, 0xd9, 0xb1, 0xb7, 0xd6, 0x73, 0xaa, 0x29, 0xd2, 0x77, 0x03, 0xd7, - 0x37, 0x4b, 0x12, 0x57, 0x45, 0x07, 0xb7, 0xe3, 0x32, 0xbd, 0xca, 0x09, - 0x49, 0x80, 0xf7, 0x87, 0x77, 0x28, 0xb1, 0xf8, 0xe0, 0x84, 0x0b, 0xef, - 0x58, 0x8e, 0xa3, 0xde, 0xcf, 0x6d, 0x0b, 0xd4, 0x0c, 0xf3, 0xe0, 0x5c, - 0x08, 0x01, 0xb3, 0x33, 0xab, 0x8e, 0x84, 0xe9, 0x39, 0xd8, 0x61, 0xf6, - 0xf7, 0x44, 0xa8, 0xda, 0x52, 0x80, 0x4e, 0xe2, 0xe6, 0x80, 0x17, 0xe6, - 0xc3, 0x96, 0x13, 0x7d, 0x34, 0xe2, 0x9a, 0x8a, 0x7e, 0x65, 0x04, 0xda, - 0x58, 0x96, 0x05, 0xd7, 0x45, 0x2d, 0x9b, 0x26, 0x6e, 0x52, 0x9c, 0xc3, - 0x38, 0xbd, 0x08, 0x37, 0x62, 0x33, 0xcc, 0x95, 0x11, 0xbf, 0x65, 0x87, - 0x08, 0xf0, 0x74, 0x61, 0x97, 0x38, 0xc1, 0x42, 0xd0, 0x93, 0x42, 0x00, - 0x0c, 0x03, 0x28, 0xa1, 0x9b, 0x39, 0x27, 0xdb, 0x21, 0xdb, 0xd9, 0xac, - 0x54, 0x3b, 0x33, 0x79, 0x1b, 0x9a, 0xae, 0x58, 0x5b, 0x6a, 0x6e, 0xeb, - 0x0a, 0xdf, 0x4b, 0xf2, 0xcf, 0x12, 0xca, 0x5f, 0xe5, 0xa8, 0xf9, 0xb1, - 0xf8, 0x13, 0x38, 0xcc, 0xaa, 0x3a, 0xba, 0x78, 0x96, 0x9e, 0x40, 0x5f, - 0xfb, 0xa8, 0x99, 0x74, 0x61, 0xed, 0xe9, 0x39, 0x7c, 0xd5, 0xb5, 0xf4, - 0x79, 0x81, 0x86, 0xe1, 0x54, 0x7a, 0x9c, 0x22, 0x16, 0xd5, 0x64, 0xcc, - 0xfe, 0xb9, 0xd4, 0x1f, 0x65, 0xa9, 0xf5, 0x8e, 0x89, 0x50, 0x5b, 0xcb, - 0xc2, 0x70, 0xba, 0x2e, 0x8e, 0x87, 0xef, 0x40, 0xd4, 0x3c, 0x32, 0xc7, - 0x16, 0x3e, 0x50, 0xae, 0x1c, 0xf9, 0x9d, 0x9e, 0x52, 0x8c, 0xc6, 0xb7, - 0x0d, 0x20, 0xe0, 0xe4, 0xd5, 0x9f, 0xcf, 0xce, 0x36, 0x62, 0x7d, 0x51, - 0x03, 0x76, 0xe8, 0xb5, 0x75, 0x94, 0xaf, 0xe9, 0xd5, 0x0d, 0x96, 0xd7, - 0x24, 0x2e, 0xb2, 0x88, 0xe3, 0x73, 0x82, 0xad, 0x8d, 0xbf, 0x0f, 0x16, - 0x5a, 0x24, 0x5f, 0x0f, 0xe1, 0xcb, 0x14, 0x4d, 0xf2, 0x82, 0x47, 0x4a, - 0xb5, 0xa0, 0x0c, 0x93, 0xdf, 0x39, 0x49, 0x97, 0x6a, 0x65, 0x2f, 0xe2, - 0xa1, 0x7d, 0x20, 0xd8, 0xca, 0x61, 0x96, 0x3c, 0x36, 0x73, 0xd5, 0x3e, - 0x0f, 0x58, 0x4b, 0xea, 0x95, 0xaa, 0x68, 0x4a, 0x08, 0x9e, 0x0f, 0x33, - 0xe9, 0xba, 0x60, 0x19, 0x8d, 0x96, 0xc1, 0x70, 0x19, 0xc3, 0xaa, 0xd0, - 0x98, 0x19, 0x17, 0x34, 0xe3, 0xa3, 0x66, 0xd6, 0x26, 0x6b, 0x16, 0x30, - 0xe3, 0x22, 0x61, 0x42, 0xc4, 0x8c, 0xd9, 0x49, 0x60, 0x2d, 0x24, 0x6a, - 0x26, 0x0a, 0x9a, 0x09, 0x31, 0x33, 0x77, 0xc7, 0xb7, 0xbc, 0x3e, 0x3e, - 0x3b, 0xdc, 0xd3, 0x2c, 0x1b, 0x01, 0x58, 0x7b, 0x88, 0xfa, 0xe1, 0xb5, - 0xc6, 0x4a, 0xf3, 0x9a, 0xb3, 0x77, 0x91, 0xd7, 0x8e, 0xf3, 0xe9, 0xb9, - 0x5c, 0xc9, 0xc2, 0x5e, 0x75, 0x05, 0xda, 0x1b, 0xef, 0x46, 0xf6, 0x82, - 0x47, 0x72, 0x4b, 0xc3, 0xfb, 0x68, 0x1a, 0x60, 0xd8, 0x2b, 0x8e, 0xa8, - 0xd3, 0x0d, 0x23, 0x95, 0x6d, 0x3e, 0x13, 0x39, 0xdd, 0x6f, 0x35, 0x83, - 0xe1, 0x90, 0xfc, 0x49, 0xc1, 0x14, 0x56, 0xd9, 0x0f, 0x77, 0x16, 0x1f, - 0xa6, 0xbd, 0x64, 0x36, 0x2b, 0x73, 0x8a, 0x46, 0xe2, 0x38, 0x9a, 0x43, - 0x93, 0x1c, 0x05, 0x6b, 0x0d, 0xd9, 0xae, 0x54, 0xad, 0x75, 0xa1, 0x3a, - 0x6a, 0x57, 0x70, 0xd5, 0x21, 0x4d, 0x41, 0x70, 0x47, 0xe2, 0xf3, 0x25, - 0x75, 0x45, 0xdd, 0x2c, 0x8d, 0x70, 0x59, 0x38, 0xd7, 0x21, 0x68, 0x25, - 0x3a, 0xc3, 0x6c, 0x85, 0x4f, 0x9e, 0x02, 0x31, 0xc6, 0xb0, 0x01, 0x8c, - 0x0a, 0xa6, 0xe7, 0xd5, 0x12, 0x7e, 0xc8, 0x90, 0xa6, 0x56, 0x3c, 0x36, - 0x6f, 0xd4, 0x85, 0x1a, 0xb1, 0xfb, 0x22, 0x9a, 0x35, 0x0d, 0x67, 0xce, - 0x3f, 0x22, 0x65, 0x23, 0x58, 0xf3, 0x55, 0x23, 0x3f, 0xdd, 0x0c, 0xce, - 0x0e, 0x8e, 0x7e, 0x3b, 0x42, 0xff, 0xd1, 0xad, 0x10, 0xa3, 0xa1, 0x17, - 0x20, 0x64, 0x01, 0x39, 0xde, 0x49, 0xc2, 0xee, 0xa1, 0xed, 0x47, 0x5b, - 0xbe, 0xee, 0x35, 0xcd, 0x61, 0x21, 0x40, 0x1e, 0x87, 0xd0, 0xdb, 0x66, - 0x49, 0x59, 0x82, 0xeb, 0x30, 0x0a, 0x8e, 0xa3, 0xf8, 0xfa, 0x6e, 0x37, - 0x65, 0x71, 0x3e, 0xa3, 0xba, 0x67, 0x7d, 0xec, 0xfa, 0xe5, 0x5a, 0x6d, - 0x43, 0x83, 0x11, 0x9a, 0x56, 0x7b, 0xd2, 0x75, 0xb9, 0x33, 0x6d, 0xc9, - 0x77, 0x16, 0x2c, 0x49, 0x99, 0x41, 0x53, 0x0d, 0x2d, 0x4b, 0x02, 0xb6, - 0x10, 0x5d, 0x69, 0x14, 0x40, 0x1a, 0x17, 0xec, 0xac, 0x43, 0xe5, 0xaf, - 0x13, 0xde, 0x3a, 0x35, 0xa4, 0x9c, 0x33, 0xdc, 0xe4, 0x6f, 0xc5, 0xb9, - 0xe6, 0x27, 0x63, 0x39, 0x20, 0x8a, 0x87, 0x1b, 0x31, 0xb6, 0xe3, 0x9c, - 0xd2, 0x82, 0xe7, 0x99, 0xe8, 0x28, 0xd0, 0x41, 0x64, 0x6a, 0x21, 0x54, - 0x49, 0x8a, 0x6b, 0x49, 0x2e, 0xa8, 0xca, 0x3c, 0xe7, 0x00, 0xfb, 0x18, - 0xd8, 0x94, 0x40, 0x1e, 0xaa, 0x44, 0x6b, 0x30, 0x33, 0xb6, 0x5c, 0x33, - 0x22, 0x2e, 0xe3, 0x70, 0x6f, 0x8c, 0xf8, 0xb8, 0x59, 0x0c, 0xc7, 0x4b, - 0xd6, 0xd1, 0xd2, 0x0e, 0x5f, 0x6d, 0x58, 0xd6, 0x44, 0x66, 0xd4, 0x1d, - 0x04, 0x6f, 0xe6, 0xcf, 0x59, 0xc9, 0xe5, 0xbd, 0xc8, 0x31, 0xc1, 0xab, - 0x81, 0xdf, 0x35, 0x78, 0x45, 0x25, 0xd1, 0x25, 0x43, 0x41, 0x30, 0x1a, - 0x68, 0x01, 0x09, 0xc6, 0x32, 0xa0, 0xde, 0xc2, 0x7e, 0xc0, 0xe4, 0xc7, - 0xe6, 0x2d, 0xa3, 0xef, 0x92, 0x38, 0x15, 0x36, 0xb3, 0xf9, 0x09, 0x05, - 0x85, 0x94, 0x48, 0xe3, 0x20, 0xe2, 0x90, 0x49, 0x61, 0x91, 0xb0, 0xf2, - 0x63, 0x7f, 0x83, 0x2e, 0x0f, 0x79, 0x4f, 0x29, 0x93, 0xf2, 0x98, 0xd0, - 0xcf, 0xa9, 0x61, 0xa6, 0x24, 0x6d, 0x91, 0xb3, 0xde, 0xca, 0x38, 0x09, - 0x34, 0xd3, 0x88, 0xaf, 0x16, 0x83, 0xa0, 0x52, 0x3c, 0x4b, 0x36, 0x83, - 0x2a, 0xa4, 0xb8, 0x34, 0xa8, 0x01, 0xc4, 0x36, 0xa5, 0xfb, 0x2c, 0x22, - 0x5d, 0xb5, 0x9c, 0x0c, 0xea, 0x64, 0x7b, 0x85, 0x78, 0x3c, 0x7b, 0x78, - 0xa7, 0xff, 0xd5, 0xce, 0xaa, 0xa9, 0xd7, 0xe4, 0xf5, 0xa7, 0xd7, 0xd0, - 0x6e, 0xab, 0x21, 0x13, 0x7e, 0xcf, 0x02, 0x9f, 0xcc, 0xea, 0x14, 0x49, - 0x74, 0x31, 0x3c, 0x9b, 0x00, 0xf8, 0x15, 0x2a, 0x82, 0x63, 0xa4, 0x16, - 0x00, 0x34, 0x5f, 0xc9, 0xdb, 0x01, 0x28, 0x5a, 0x8e, 0x92, 0x7d, 0xa1, - 0x86, 0xe6, 0xa8, 0xca, 0x67, 0x1e, 0x5c, 0xa0, 0x65, 0x70, 0xa9, 0xc0, - 0xad, 0x54, 0x11, 0xd3, 0xe5, 0xb2, 0x9f, 0xea, 0x7c, 0xc1, 0xda, 0xaa, - 0x4f, 0xfa, 0x5b, 0x1b, 0x6a, 0x6a, 0xd1, 0x96, 0x3f, 0xa3, 0xa5, 0x45, - 0xbb, 0xa0, 0x0b, 0x7b, 0x35, 0xb4, 0x5f, 0xa0, 0xa3, 0xf1, 0x38, 0x0b, - 0x91, 0xfc, 0x93, 0x59, 0x3d, 0x90, 0x28, 0x52, 0x4e, 0xd6, 0xa8, 0x34, - 0x32, 0x0a, 0x6f, 0x99, 0x57, 0x24, 0xe0, 0xa7, 0x70, 0x8b, 0x63, 0xca, - 0xea, 0xfa, 0xab, 0x93, 0x33, 0xc4, 0x69, 0xc7, 0xd5, 0x88, 0xd2, 0x51, - 0xe9, 0x73, 0x17, 0xb3, 0x3c, 0x45, 0x1d, 0x20, 0x9b, 0x56, 0xc2, 0xe8, - 0xc9, 0xb6, 0x6c, 0x11, 0x84, 0xf8, 0x28, 0x71, 0x3b, 0xf1, 0x92, 0x99, - 0x12, 0x21, 0x59, 0xb1, 0xb0, 0xbc, 0x13, 0xbd, 0x2b, 0xc8, 0x32, 0xec, - 0x7c, 0xee, 0x6a, 0x1b, 0x46, 0x05, 0xb0, 0xbe, 0xa4, 0xec, 0x56, 0x81, - 0xab, 0x64, 0xb3, 0x3d, 0xfb, 0x69, 0x35, 0x48, 0xc5, 0x99, 0x36, 0x32, - 0x0c, 0xd1, 0x4b, 0x5d, 0x02, 0x3d, 0xaa, 0x97, 0xd9, 0x14, 0xf8, 0xe4, - 0xc0, 0xc5, 0x7a, 0x13, 0x09, 0xe6, 0x13, 0xdc, 0x2d, 0x64, 0x10, 0xe3, - 0x5c, 0x51, 0x50, 0x2d, 0x2c, 0x86, 0x4f, 0xbf, 0x0d, 0x99, 0x47, 0x51, - 0xe5, 0xf8, 0x41, 0x3a, 0xcd, 0x88, 0x00, 0x75, 0xcf, 0x78, 0x51, 0x30, - 0xeb, 0x22, 0x9b, 0x66, 0xa3, 0x9c, 0xa0, 0x86, 0x73, 0x97, 0xde, 0x7b, - 0x4d, 0x99, 0x36, 0x8d, 0xa6, 0x28, 0xca, 0xcc, 0xa6, 0x25, 0xf2, 0xea, - 0x98, 0x95, 0x49, 0x0a, 0x43, 0xe4, 0x40, 0xc7, 0xae, 0x88, 0x77, 0x48, - 0xfa, 0x93, 0xe2, 0x1c, 0xb7, 0xbf, 0xd1, 0x2e, 0x32, 0x28, 0xca, 0xf2, - 0x23, 0x2f, 0xa1, 0xf0, 0x25, 0x8e, 0xad, 0xd3, 0x35, 0xfb, 0x29, 0x7f, - 0x9e, 0xb3, 0x16, 0x3a, 0xc8, 0xc6, 0xe3, 0x39, 0x95, 0x81, 0x21, 0xd3, - 0x01, 0xd6, 0x9c, 0x22, 0x9c, 0x14, 0x8c, 0x44, 0x0a, 0xe9, 0xc8, 0x21, - 0x31, 0xd0, 0x06, 0x4d, 0xe8, 0xc2, 0x68, 0xe2, 0x50, 0xc0, 0x52, 0xd6, - 0x1b, 0x11, 0x06, 0xbb, 0xad, 0x78, 0x4f, 0x5e, 0xf9, 0x3c, 0x6f, 0x0e, - 0xd0, 0x08, 0x58, 0x03, 0x85, 0xe1, 0xe2, 0x56, 0x2a, 0x40, 0xd2, 0x75, - 0xa6, 0x31, 0xce, 0x25, 0xe6, 0xdb, 0x3d, 0xea, 0x3f, 0xee, 0x27, 0xc7, - 0x94, 0x8b, 0x8c, 0xcb, 0xeb, 0xc8, 0x90, 0x83, 0xe6, 0xd4, 0x43, 0x8f, - 0xb1, 0x25, 0x53, 0xc3, 0xb0, 0xf3, 0x10, 0xff, 0xa6, 0x80, 0x88, 0x00, - 0x2c, 0xb5, 0x7d, 0xd6, 0xb1, 0x1c, 0x0f, 0x65, 0x2e, 0xbf, 0x7d, 0x16, - 0xb5, 0xeb, 0xaf, 0x07, 0xad, 0xed, 0xc0, 0x69, 0x2c, 0xf4, 0x08, 0x0b, - 0x5f, 0x94, 0xb3, 0xc4, 0x01, 0xe1, 0xca, 0x49, 0x68, 0xff, 0x89, 0x19, - 0x40, 0x67, 0x9e, 0x19, 0xc7, 0xd1, 0x4e, 0xe9, 0x04, 0x43, 0xff, 0xa9, - 0x0c, 0x17, 0x1c, 0x88, 0x8a, 0xd3, 0x00, 0x13, 0xbe, 0xa9, 0xa9, 0x01, - 0x8f, 0x9b, 0x16, 0x1f, 0xd8, 0x65, 0x75, 0x43, 0x92, 0x66, 0x29, 0xe1, - 0x96, 0x5a, 0xc2, 0x89, 0xdf, 0x4f, 0xd6, 0xc3, 0xb1, 0xe1, 0x3b, 0x18, - 0x0e, 0x3e, 0xf2, 0xe9, 0xb8, 0xa4, 0x23, 0xe0, 0x74, 0x05, 0xe8, 0x65, - 0xc6, 0x7c, 0xac, 0xd0, 0x61, 0x24, 0xf5, 0x4a, 0xd2, 0xd8, 0x6b, 0xfd, - 0x32, 0x59, 0x3f, 0x3d, 0x79, 0x7d, 0xf8, 0xc3, 0xf1, 0xc6, 0x12, 0xf7, - 0xa5, 0x27, 0x31, 0x4b, 0x7d, 0x4a, 0x35, 0xef, 0x56, 0x92, 0x9e, 0x48, - 0x15, 0xf9, 0xe1, 0xf4, 0xb4, 0xb7, 0x7f, 0x72, 0x94, 0x50, 0x5e, 0x31, - 0xfc, 0xab, 0x7b, 0xd5, 0xf7, 0x95, 0xd1, 0xf4, 0x82, 0x0e, 0x11, 0xa1, - 0x9c, 0x34, 0x44, 0x96, 0x18, 0x75, 0xd6, 0x49, 0x4b, 0x9b, 0xd4, 0x0c, - 0x36, 0x47, 0x23, 0x8c, 0x4c, 0xa3, 0x2d, 0x6e, 0x30, 0x14, 0x92, 0x02, - 0xa5, 0x68, 0x56, 0x34, 0xe8, 0xdc, 0x84, 0x3d, 0xcf, 0x2e, 0x9c, 0x88, - 0x56, 0xd1, 0x39, 0x8f, 0x50, 0x08, 0x69, 0xcd, 0xa2, 0x4f, 0xc3, 0xe9, - 0xc2, 0x19, 0x51, 0xd0, 0xce, 0x2c, 0x2b, 0x11, 0xd9, 0xfe, 0x54, 0x74, - 0xde, 0x34, 0x59, 0xeb, 0xcd, 0x93, 0xbd, 0xb5, 0xc0, 0x92, 0xb3, 0x29, - 0x95, 0x4d, 0x4d, 0x8d, 0xbb, 0xb3, 0xf1, 0x97, 0x2c, 0x5d, 0xea, 0xfa, - 0x22, 0xd1, 0x91, 0x73, 0x6a, 0xdd, 0x40, 0x18, 0x20, 0xc6, 0x82, 0x0c, - 0x18, 0x99, 0x4b, 0xae, 0xd9, 0x06, 0xa6, 0x9f, 0x6d, 0xe7, 0xb2, 0x10, - 0xcd, 0x8f, 0xc5, 0xf5, 0x0b, 0x0d, 0xe2, 0x74, 0x56, 0xbb, 0xe1, 0xce, - 0x31, 0xac, 0x00, 0xc5, 0x70, 0x60, 0x32, 0x24, 0x8e, 0x83, 0x0a, 0x43, - 0xde, 0x1c, 0x89, 0x81, 0x21, 0xb8, 0x7b, 0x6b, 0x58, 0x49, 0x71, 0x4a, - 0x6f, 0x80, 0xe8, 0x31, 0x50, 0xcb, 0x8e, 0xd6, 0x94, 0xaf, 0x06, 0xa9, - 0x5c, 0x2f, 0x7d, 0xfa, 0x5e, 0x0c, 0x20, 0x71, 0x99, 0x06, 0xae, 0xd0, - 0xe0, 0xc2, 0xec, 0x0d, 0x1d, 0x8f, 0x1d, 0xba, 0x0b, 0x8b, 0xed, 0xaa, - 0x2e, 0xd7, 0x0c, 0xe0, 0x23, 0x21, 0xff, 0x9c, 0x40, 0x86, 0xe6, 0x1b, - 0x5c, 0xfa, 0xb7, 0xd3, 0xfc, 0x43, 0x3f, 0x00, 0x9c, 0x54, 0x6a, 0x90, - 0xe4, 0xc2, 0x4e, 0x2c, 0x9b, 0x64, 0x72, 0x6d, 0xd3, 0x9e, 0x35, 0x5d, - 0xb5, 0x14, 0x5e, 0x46, 0xe3, 0x5e, 0x7f, 0xb4, 0x11, 0x7c, 0xeb, 0xa3, - 0x7a, 0xb6, 0xbe, 0xcd, 0x17, 0xb9, 0xd4, 0xc7, 0xb0, 0x68, 0x3e, 0x9a, - 0x9e, 0x46, 0xf7, 0x1f, 0x58, 0x8d, 0x61, 0x12, 0x63, 0x09, 0x4e, 0xd5, - 0x0a, 0x91, 0x93, 0xe7, 0x15, 0x6d, 0xc3, 0xf4, 0x4a, 0x78, 0x8a, 0xf2, - 0xb2, 0x38, 0x30, 0x8c, 0xa4, 0x5a, 0x20, 0x4e, 0x84, 0xa7, 0x60, 0x45, - 0x75, 0x3d, 0xaf, 0x17, 0x5c, 0xc7, 0x53, 0x41, 0x23, 0x47, 0x8f, 0xee, - 0x78, 0x48, 0x32, 0x33, 0xfc, 0x71, 0x51, 0x16, 0xf3, 0x59, 0x0f, 0xb3, - 0x9c, 0x71, 0x7e, 0x1b, 0x02, 0x7a, 0x11, 0xc3, 0x01, 0x1b, 0x1e, 0xb0, - 0x38, 0x00, 0x5e, 0x1c, 0xbf, 0x3a, 0xec, 0x98, 0xe7, 0x92, 0x2a, 0x41, - 0x49, 0xd2, 0x7d, 0xbc, 0x41, 0x4a, 0x76, 0xc7, 0x86, 0x05, 0x9f, 0xc0, - 0x2d, 0x17, 0x02, 0xd8, 0x75, 0x7b, 0x1b, 0xdb, 0x4a, 0x40, 0x65, 0x04, - 0x57, 0x3b, 0xdc, 0x4b, 0x84, 0x1e, 0xc2, 0xa2, 0xbe, 0xa3, 0xbf, 0xbb, - 0x16, 0xc6, 0x1b, 0x02, 0xb7, 0x28, 0x50, 0x1d, 0x85, 0xf7, 0x63, 0xae, - 0xcd, 0x18, 0xca, 0x73, 0xe2, 0xaa, 0x47, 0x30, 0x3a, 0xd2, 0x3c, 0x6d, - 0x0d, 0x37, 0x98, 0xf8, 0x20, 0xe5, 0xfd, 0x04, 0xf8, 0x1b, 0xdc, 0x0f, - 0x24, 0x0b, 0xe4, 0x94, 0x52, 0xa5, 0xa9, 0x55, 0x68, 0x14, 0x90, 0x30, - 0x41, 0x8e, 0xa1, 0x4d, 0x95, 0x62, 0x91, 0x8b, 0x90, 0x56, 0xe9, 0xec, - 0xfd, 0xf0, 0x19, 0x12, 0x99, 0x9a, 0x82, 0x25, 0x6d, 0x80, 0x63, 0x20, - 0xd9, 0x11, 0x44, 0x86, 0x53, 0x26, 0x37, 0xe3, 0x17, 0x6b, 0x93, 0x1b, - 0x84, 0xbc, 0x5d, 0x73, 0xa2, 0x95, 0xb1, 0x8f, 0x35, 0x10, 0x90, 0x41, - 0x78, 0x5f, 0x13, 0x2c, 0x58, 0x4a, 0x14, 0xd1, 0xf2, 0x72, 0x75, 0x41, - 0x78, 0x83, 0x4b, 0x7a, 0x81, 0x6f, 0xf8, 0x98, 0x70, 0xeb, 0xf0, 0x67, - 0x70, 0xc7, 0x53, 0x9b, 0x5f, 0x2c, 0x86, 0x83, 0xf3, 0xcc, 0xda, 0x00, - 0x44, 0xc3, 0xfd, 0xb7, 0x72, 0x14, 0x10, 0x35, 0x76, 0x17, 0x2b, 0xc2, - 0xfe, 0x56, 0x2d, 0x4f, 0xde, 0xac, 0xb6, 0xdc, 0x5a, 0x6c, 0x99, 0x9a, - 0xec, 0x31, 0x3b, 0xf1, 0xe0, 0x65, 0xfc, 0x39, 0x37, 0x85, 0xd6, 0x65, - 0x0f, 0xdd, 0x61, 0xaf, 0x74, 0x59, 0x81, 0x1a, 0xe5, 0x17, 0xc2, 0xd8, - 0x22, 0xf7, 0xbf, 0x6b, 0xfa, 0xa9, 0x12, 0x75, 0x13, 0x02, 0xc8, 0x71, - 0x33, 0x8b, 0xd7, 0x3b, 0xd5, 0x72, 0x80, 0xb5, 0xf5, 0xd6, 0xa5, 0xd1, - 0x67, 0x08, 0xc7, 0x4c, 0x87, 0x1d, 0xee, 0x30, 0x57, 0xb3, 0x4e, 0xef, - 0x30, 0x86, 0x71, 0x84, 0x89, 0xad, 0xa7, 0xe7, 0x55, 0x31, 0x9e, 0xd7, - 0xe4, 0x65, 0x44, 0x9f, 0x3e, 0x02, 0xf9, 0x98, 0xcf, 0xf0, 0x08, 0xae, - 0xbe, 0x73, 0x8e, 0x28, 0x3c, 0xbf, 0x59, 0x98, 0x2a, 0xe7, 0x76, 0x9a, - 0xf7, 0x43, 0xad, 0x40, 0x7e, 0x9d, 0x3e, 0x97, 0x41, 0xcf, 0xf5, 0xb1, - 0xd2, 0x4e, 0xaf, 0x04, 0x20, 0xca, 0x64, 0x15, 0x21, 0x88, 0xf2, 0x92, - 0x1a, 0xde, 0x5d, 0x25, 0xe1, 0xd8, 0xba, 0x97, 0x8d, 0x0d, 0xd4, 0x85, - 0xd1, 0xe0, 0xa1, 0xb0, 0x39, 0x6e, 0x77, 0xce, 0xe7, 0x0b, 0x9e, 0x69, - 0x49, 0xf2, 0xa4, 0x6d, 0x16, 0x1e, 0x00, 0x6b, 0x90, 0x5e, 0x44, 0x10, - 0xa0, 0xe9, 0xd8, 0x4a, 0xf8, 0xa2, 0x9d, 0x6f, 0x98, 0x32, 0x8b, 0xab, - 0x34, 0x3e, 0x58, 0x98, 0x4f, 0x28, 0x85, 0xd7, 0xe6, 0x16, 0x6a, 0x6c, - 0xe0, 0x32, 0x40, 0xdf, 0x86, 0x3c, 0xba, 0xda, 0x81, 0x0c, 0x47, 0x60, - 0x85, 0xad, 0xb3, 0x21, 0xac, 0x7a, 0x44, 0x97, 0x9f, 0xd0, 0xf8, 0x80, - 0xf6, 0x35, 0x46, 0xdb, 0x87, 0x68, 0x07, 0x72, 0xd1, 0x1d, 0xdb, 0xeb, - 0x4a, 0x8e, 0x77, 0x10, 0x25, 0x7d, 0xa9, 0x60, 0x97, 0x66, 0x2e, 0x11, - 0xbb, 0x51, 0xd4, 0xb1, 0x95, 0xcd, 0x42, 0x14, 0x88, 0x62, 0x40, 0xb5, - 0xbf, 0xa3, 0x00, 0x36, 0xd1, 0x5a, 0xd3, 0x00, 0xab, 0xc3, 0x7c, 0x7e, - 0xea, 0xf2, 0xc6, 0xb1, 0x11, 0x0d, 0x2f, 0xee, 0xb2, 0xcd, 0xcc, 0xc9, - 0xf8, 0x9c, 0x06, 0x97, 0x10, 0x0e, 0xef, 0x42, 0xf8, 0x5e, 0x57, 0x02, - 0x89, 0xcd, 0x7f, 0x62, 0x9e, 0xf5, 0xc4, 0xe9, 0xdf, 0x66, 0x5a, 0x2b, - 0xf9, 0x92, 0x44, 0x33, 0x00, 0x48, 0xb3, 0x70, 0x4d, 0x58, 0x54, 0x33, - 0xb6, 0x82, 0x3d, 0xf7, 0xbf, 0x08, 0x4b, 0xf5, 0xa1, 0x66, 0x3b, 0x5e, - 0xc5, 0xee, 0x51, 0x36, 0x83, 0x59, 0x60, 0x1e, 0xce, 0x9a, 0x34, 0x41, - 0xcd, 0xb1, 0x2f, 0xa6, 0x44, 0x38, 0x52, 0x98, 0x24, 0x2f, 0x9d, 0x59, - 0x04, 0x43, 0x6a, 0xe7, 0xa0, 0x68, 0x12, 0x34, 0xd8, 0x95, 0xd6, 0xfc, - 0xd1, 0x44, 0x43, 0xab, 0x3b, 0xe4, 0xad, 0xd8, 0x64, 0x16, 0xf0, 0x3b, - 0x93, 0x4b, 0xb9, 0xdc, 0x9c, 0xe3, 0xef, 0x7f, 0x90, 0x5e, 0xc3, 0x80, - 0x12, 0xcb, 0x03, 0x4c, 0xbc, 0x2b, 0x8e, 0xfe, 0x22, 0xff, 0x9b, 0x1d, - 0x5f, 0xfa, 0xab, 0x97, 0x56, 0x83, 0x3c, 0x97, 0x53, 0x8c, 0xae, 0x48, - 0x0c, 0xff, 0x0b, 0x17, 0x36, 0xba, 0xa5, 0x6c, 0x55, 0xb5, 0x16, 0xd1, - 0xb0, 0xa0, 0x14, 0x78, 0x8d, 0x7c, 0xe7, 0x84, 0x0c, 0x0a, 0x0f, 0xa7, - 0x98, 0x03, 0x0d, 0xf6, 0x89, 0x02, 0xf5, 0xd0, 0x8b, 0x1d, 0x2a, 0x02, - 0x5c, 0x5f, 0x5f, 0x6f, 0xf7, 0xa3, 0xd0, 0x1a, 0x5e, 0xe8, 0x1e, 0x56, - 0xa2, 0xad, 0x6a, 0x62, 0x07, 0xf0, 0xcc, 0x4e, 0xbf, 0xad, 0x8c, 0x2a, - 0x3d, 0x79, 0x4f, 0x00, 0xa7, 0x6d, 0x10, 0xa1, 0xab, 0x8c, 0xc5, 0x1f, - 0xe1, 0xa3, 0xdb, 0x5a, 0x69, 0x7e, 0x05, 0x47, 0x6f, 0x73, 0xb9, 0x5d, - 0x6b, 0x09, 0x37, 0x2d, 0x7a, 0xe9, 0x78, 0xe6, 0x13, 0x70, 0x4e, 0x37, - 0x8c, 0x09, 0x21, 0x89, 0xec, 0xbf, 0x3c, 0x79, 0x4d, 0x18, 0x3d, 0x66, - 0xb7, 0xea, 0xf3, 0x67, 0x98, 0x7e, 0x39, 0x65, 0x63, 0xa0, 0x2b, 0xf5, - 0x60, 0xf2, 0xaf, 0x2f, 0x02, 0xea, 0xf4, 0x4c, 0x4a, 0xb3, 0x0c, 0xd0, - 0x4f, 0x7c, 0x73, 0x9a, 0xee, 0x88, 0x0d, 0x23, 0xf6, 0x12, 0xfc, 0x13, - 0x15, 0x06, 0x49, 0xa4, 0x1c, 0x9e, 0xa1, 0x43, 0xc4, 0xaf, 0x49, 0x15, - 0x7b, 0x22, 0xf9, 0xa0, 0x18, 0xc9, 0xa7, 0x5a, 0xe7, 0x8c, 0x4d, 0x0f, - 0x16, 0xb4, 0x20, 0xf6, 0x0a, 0x71, 0x97, 0xd1, 0x52, 0x2a, 0x22, 0x68, - 0xe5, 0xf3, 0x07, 0x1d, 0x7c, 0x5a, 0xae, 0x9e, 0x51, 0x44, 0xff, 0xc0, - 0xe4, 0x13, 0xe6, 0x97, 0x24, 0xfe, 0x69, 0xdd, 0x4c, 0xb5, 0xb7, 0x6b, - 0xd0, 0xb0, 0x12, 0x16, 0x2e, 0x32, 0x55, 0x90, 0x66, 0x0d, 0x5e, 0x66, - 0x1a, 0x89, 0x6d, 0xbc, 0x13, 0xc9, 0x92, 0xf0, 0xed, 0x8f, 0xa9, 0x78, - 0x8a, 0xed, 0xdc, 0x71, 0x33, 0x48, 0x67, 0xb7, 0x95, 0x14, 0xd6, 0x67, - 0x96, 0x62, 0xa6, 0x2c, 0x82, 0xa6, 0x00, 0x9d, 0xb4, 0xe0, 0xa5, 0xe0, - 0xad, 0x35, 0x9b, 0xb6, 0xa1, 0x82, 0xbf, 0xee, 0xf2, 0xd7, 0xe7, 0xf3, - 0x91, 0x15, 0x77, 0x7f, 0xe6, 0x63, 0x53, 0x13, 0xfe, 0x86, 0x18, 0x56, - 0xa1, 0x85, 0x50, 0xb8, 0x10, 0xaa, 0x1a, 0x44, 0xd1, 0xf0, 0x3f, 0xd5, - 0x04, 0x5d, 0x0e, 0x7d, 0xd5, 0xaa, 0xb6, 0x70, 0x83, 0x09, 0x0f, 0x77, - 0x71, 0xc0, 0x2e, 0x65, 0x9b, 0x1b, 0x27, 0x03, 0x1b, 0x37, 0xc9, 0x2d, - 0x8a, 0x38, 0x67, 0xb9, 0x17, 0x84, 0x4c, 0x26, 0x2e, 0x61, 0xfa, 0x8a, - 0x30, 0x0c, 0xe8, 0x8d, 0xca, 0x21, 0x57, 0xa3, 0xe5, 0x68, 0x70, 0x39, - 0x9f, 0xbe, 0x87, 0xfe, 0xb8, 0x56, 0x84, 0x64, 0xf1, 0xe5, 0x9a, 0x62, - 0x0b, 0xab, 0x3c, 0xa8, 0x0d, 0xf0, 0x3e, 0x80, 0x70, 0xa7, 0xa0, 0x11, - 0x5d, 0xa1, 0x14, 0xf1, 0x56, 0x53, 0x5a, 0x9c, 0x65, 0xd0, 0x62, 0x75, - 0x5d, 0x01, 0x0f, 0x5b, 0x95, 0xcf, 0x40, 0xa9, 0xdc, 0xb6, 0xa3, 0xd5, - 0xb0, 0x05, 0x44, 0x64, 0x0b, 0x54, 0x2b, 0x2f, 0xfc, 0xfe, 0x32, 0x7e, - 0xdc, 0xd0, 0x9d, 0x84, 0x2b, 0xfd, 0xad, 0x5a, 0xc2, 0xef, 0x02, 0xa3, - 0x06, 0x7b, 0xe7, 0x0e, 0xb8, 0x16, 0xda, 0x18, 0xc0, 0xdd, 0x66, 0x48, - 0x8b, 0x62, 0x93, 0x5a, 0x84, 0x87, 0x0d, 0xdc, 0xa2, 0xd7, 0xe3, 0xfd, - 0xee, 0x72, 0xe6, 0x30, 0x96, 0x33, 0x11, 0x94, 0xec, 0x1e, 0x85, 0xdb, - 0xe9, 0xe2, 0xc9, 0x57, 0x52, 0xa2, 0x8f, 0x82, 0x2b, 0xe2, 0x4f, 0x7b, - 0x74, 0xd1, 0x3b, 0xe1, 0x42, 0x4c, 0x15, 0x09, 0x17, 0x6b, 0x77, 0xd6, - 0x7d, 0x44, 0xf3, 0x21, 0x47, 0xa5, 0xc4, 0x29, 0x90, 0x5b, 0x80, 0x91, - 0xcd, 0xc8, 0x14, 0x4e, 0x74, 0x2f, 0x09, 0xc8, 0xec, 0x72, 0x93, 0xec, - 0x45, 0x0f, 0x22, 0x79, 0x41, 0xb2, 0x85, 0x00, 0xa5, 0xa8, 0xc3, 0x81, - 0x23, 0x1d, 0x47, 0xc1, 0xa6, 0x41, 0x8d, 0x2b, 0x4e, 0x0b, 0x66, 0x03, - 0x22, 0xd1, 0x74, 0x11, 0x73, 0xc6, 0x22, 0x28, 0x0c, 0xbf, 0x70, 0x7b, - 0x6b, 0x4b, 0x12, 0xb3, 0x38, 0x60, 0x4c, 0x6b, 0xaf, 0x53, 0x36, 0x17, - 0xbd, 0x49, 0x09, 0x66, 0xbe, 0x70, 0x74, 0x3b, 0x71, 0xae, 0x42, 0x9b, - 0x9c, 0x35, 0x76, 0x39, 0x0f, 0x41, 0xe2, 0xb4, 0x9e, 0xb2, 0x7b, 0xa2, - 0xac, 0x93, 0x0d, 0x4f, 0x50, 0x24, 0x2c, 0xaf, 0x86, 0x9f, 0x80, 0xf5, - 0xeb, 0x5a, 0x28, 0x3f, 0xdd, 0x4b, 0x8d, 0x8d, 0x72, 0x7b, 0x48, 0x5e, - 0xfa, 0xa0, 0x60, 0x35, 0x88, 0xdc, 0xba, 0xfc, 0xdd, 0x54, 0x2e, 0x2d, - 0xdd, 0x49, 0xe6, 0xda, 0xa3, 0x92, 0x1e, 0x4b, 0x87, 0x94, 0x59, 0x7d, - 0x87, 0x53, 0xcb, 0x57, 0x53, 0xdf, 0x6d, 0x18, 0x9b, 0xa5, 0x2d, 0x75, - 0x28, 0x1a, 0x5d, 0xfa, 0xc3, 0x61, 0xa8, 0x97, 0x2d, 0x0c, 0x59, 0xbc, - 0x5f, 0x01, 0x2c, 0x54, 0x22, 0xd7, 0xc9, 0x4a, 0xa6, 0x00, 0xae, 0x1e, - 0x93, 0xd9, 0x19, 0x56, 0x42, 0x32, 0x5c, 0x16, 0xfc, 0x69, 0x13, 0x17, - 0x34, 0xf1, 0x59, 0x08, 0xc6, 0xa1, 0x78, 0x32, 0xb9, 0x18, 0xb1, 0x04, - 0x88, 0xe0, 0xa4, 0x61, 0xad, 0x5d, 0x58, 0x83, 0x7b, 0xf4, 0x27, 0x78, - 0x60, 0xe2, 0xdb, 0x29, 0x20, 0x8c, 0x7b, 0x45, 0xd0, 0xb9, 0x16, 0x24, - 0xe4, 0x08, 0xc1, 0xd4, 0x6f, 0xf2, 0xb4, 0x29, 0xf4, 0x51, 0xbf, 0x53, - 0x14, 0x77, 0xe5, 0xa2, 0x7c, 0x7d, 0xf2, 0x3a, 0xce, 0x78, 0x6e, 0x00, - 0xc7, 0xb2, 0x8f, 0x37, 0xa4, 0xb4, 0x01, 0xb5, 0x3d, 0x46, 0x27, 0xef, - 0x17, 0x11, 0xd9, 0xf0, 0x89, 0x7c, 0x8d, 0x21, 0xce, 0x54, 0x88, 0xd9, - 0x89, 0x91, 0xf4, 0x29, 0xca, 0x11, 0x2a, 0x47, 0x46, 0x35, 0xc3, 0xec, - 0xb0, 0x2e, 0x4a, 0x92, 0x92, 0x1c, 0xcb, 0x92, 0x64, 0x2c, 0x4a, 0x06, - 0xa1, 0xf0, 0x35, 0x0a, 0x58, 0xd4, 0xaf, 0xcf, 0x31, 0x61, 0x41, 0x52, - 0x9b, 0x8c, 0xc5, 0xc8, 0x20, 0x45, 0x06, 0x21, 0x52, 0x3e, 0xd3, 0x87, - 0x24, 0xba, 0x6d, 0x25, 0x21, 0xb2, 0xc9, 0x42, 0xa6, 0x5e, 0xb8, 0xfb, - 0xf4, 0x5a, 0xb7, 0x2b, 0x88, 0x76, 0xd3, 0xbb, 0x25, 0xbb, 0xe9, 0x52, - 0xc1, 0x2e, 0x42, 0xc3, 0xbb, 0x5b, 0xb2, 0x23, 0x11, 0xb1, 0xad, 0xe0, - 0x0b, 0x7c, 0x67, 0xb7, 0xef, 0x24, 0xb3, 0x3a, 0xb6, 0xc7, 0x16, 0xe4, - 0x24, 0x3e, 0xd7, 0x62, 0x24, 0x72, 0x9d, 0x3e, 0x9d, 0xd0, 0xd3, 0x26, - 0x93, 0x49, 0xed, 0x70, 0x34, 0x48, 0xb0, 0x18, 0x58, 0x36, 0xb9, 0x09, - 0xdc, 0x47, 0x04, 0x8b, 0x4d, 0x10, 0xad, 0x29, 0x57, 0xee, 0x11, 0x9b, - 0x81, 0x4b, 0x81, 0x43, 0xe1, 0xd0, 0x98, 0x15, 0xa3, 0xf1, 0xe8, 0x34, - 0xaa, 0x9c, 0x90, 0xf0, 0xc8, 0x92, 0xf3, 0x79, 0x58, 0x50, 0xbc, 0x12, - 0x4e, 0xb8, 0x6a, 0x99, 0xb8, 0x48, 0x59, 0x2d, 0x16, 0xa5, 0xe6, 0x8a, - 0xde, 0x43, 0x5d, 0xfb, 0xb8, 0xc1, 0x3b, 0x29, 0xab, 0xd1, 0x7f, 0xaf, - 0xe0, 0xba, 0xd2, 0xab, 0x5d, 0x46, 0x8f, 0xbf, 0x6c, 0x5c, 0x46, 0x62, - 0x41, 0x50, 0xa4, 0x29, 0xda, 0x05, 0x4f, 0x3f, 0x72, 0x94, 0xf2, 0xa1, - 0x07, 0x2b, 0xd5, 0xf9, 0xe0, 0xa0, 0xd6, 0x2a, 0xbd, 0x90, 0x90, 0x13, - 0x68, 0xd1, 0x83, 0xa3, 0x67, 0xb0, 0x07, 0x68, 0x4e, 0xbf, 0xe8, 0x27, - 0xdf, 0xbb, 0x90, 0x7e, 0x03, 0x51, 0xd0, 0x28, 0x29, 0x76, 0x8c, 0x53, - 0x99, 0x98, 0x90, 0x4b, 0x81, 0xaf, 0x66, 0x1e, 0x06, 0x84, 0x63, 0x59, - 0x31, 0xde, 0x88, 0x91, 0xc6, 0x2e, 0x43, 0x7a, 0x37, 0x71, 0x4b, 0x84, - 0x34, 0xb8, 0x9c, 0xc3, 0x19, 0x41, 0xee, 0x95, 0xd6, 0x75, 0x36, 0x99, - 0x31, 0xfa, 0x07, 0x86, 0xf7, 0x93, 0xc8, 0x12, 0x0f, 0x8e, 0x6d, 0xb1, - 0x8c, 0x1b, 0x9f, 0x4d, 0xcc, 0xe7, 0x00, 0x92, 0x97, 0xc0, 0x9c, 0xe3, - 0xe3, 0xe4, 0xc0, 0x40, 0xb2, 0x4a, 0xc5, 0xf6, 0x22, 0x6e, 0x97, 0xeb, - 0x7c, 0x3c, 0x0c, 0xc9, 0xa4, 0x72, 0x82, 0x9d, 0xe9, 0x19, 0x1a, 0x1a, - 0x1a, 0xe3, 0xcd, 0xc9, 0x62, 0x41, 0xb0, 0xce, 0x64, 0x7e, 0x92, 0xa4, - 0xe6, 0x6a, 0x3e, 0xc0, 0x00, 0xfe, 0xcf, 0x23, 0x9e, 0xf5, 0xc2, 0xae, - 0xa9, 0x78, 0x16, 0xa4, 0x33, 0xb7, 0x43, 0x49, 0xd8, 0xa3, 0x76, 0x52, - 0x0f, 0xcd, 0x2c, 0xbd, 0x7c, 0x6f, 0xb9, 0x7b, 0x5b, 0x48, 0xdd, 0x1a, - 0xbc, 0x93, 0xca, 0x43, 0xd7, 0x2b, 0x5d, 0xbc, 0xae, 0xf6, 0xb8, 0x8e, - 0x9e, 0x7c, 0xa9, 0xc9, 0x53, 0x3e, 0x31, 0x1f, 0x6e, 0x08, 0x2b, 0x47, - 0xbc, 0x0c, 0x07, 0x68, 0x3e, 0xea, 0xa9, 0xf9, 0x73, 0xc8, 0x39, 0x3b, - 0x40, 0xc1, 0x9c, 0xe8, 0x8e, 0xdb, 0xc4, 0x82, 0x35, 0x0a, 0xd4, 0x82, - 0x55, 0x93, 0x26, 0xd4, 0x0a, 0xa3, 0x7d, 0x03, 0xb5, 0x9a, 0x6d, 0xc4, - 0xc9, 0xab, 0xe8, 0x01, 0x64, 0x20, 0x7a, 0x24, 0x11, 0x2a, 0xad, 0x92, - 0x57, 0x2e, 0xbf, 0xab, 0xf3, 0x1f, 0x1d, 0xcc, 0x15, 0x29, 0x41, 0x03, - 0xcd, 0xca, 0xae, 0x64, 0xb2, 0xbb, 0x9a, 0x89, 0x5c, 0x0e, 0x97, 0x47, - 0x21, 0x65, 0x29, 0xac, 0xda, 0x00, 0xb4, 0xea, 0xb5, 0xd0, 0x8c, 0x87, - 0xd3, 0x4f, 0x0e, 0xc9, 0x90, 0x3a, 0xb5, 0xd2, 0x2c, 0x8a, 0xc1, 0xc4, - 0x73, 0xe2, 0x74, 0x7c, 0x6c, 0x9a, 0x33, 0xad, 0xc4, 0x95, 0x99, 0x5a, - 0x3a, 0x95, 0x4c, 0x54, 0x70, 0x97, 0x7d, 0x76, 0x86, 0x16, 0x80, 0x23, - 0x40, 0x0b, 0x12, 0x20, 0x42, 0xa9, 0xe9, 0x9a, 0x2b, 0x4b, 0xc6, 0x41, - 0xed, 0x1d, 0x12, 0x8e, 0x71, 0x7b, 0x3a, 0x11, 0xfe, 0x02, 0x97, 0x83, - 0x74, 0xdf, 0xc2, 0xd4, 0xc2, 0x5f, 0x7b, 0x4f, 0xb6, 0x3a, 0x32, 0xd7, - 0xce, 0xf5, 0xf5, 0x75, 0x3f, 0x7a, 0x8c, 0x9c, 0x07, 0xe6, 0xdc, 0xa7, - 0xef, 0xe1, 0xaf, 0xf0, 0x48, 0x5b, 0x8c, 0x45, 0x03, 0x16, 0xc2, 0x3b, - 0x64, 0xd5, 0x1d, 0xab, 0x01, 0xad, 0x7a, 0x4a, 0xc3, 0xa4, 0x99, 0x66, - 0xd6, 0x3b, 0xd3, 0xe2, 0x1d, 0xfd, 0xda, 0x91, 0x3b, 0xac, 0xf3, 0xfa, - 0xf8, 0xdd, 0xc9, 0x9b, 0xe3, 0x9f, 0xff, 0xd2, 0xe1, 0xcc, 0x5b, 0xe5, - 0x1e, 0x39, 0x83, 0xc6, 0xf9, 0x5e, 0xd4, 0x20, 0x2c, 0x95, 0x60, 0xb9, - 0x0f, 0x0e, 0x7b, 0x10, 0x0a, 0x52, 0x3b, 0x6b, 0x25, 0xbe, 0xae, 0x69, - 0x21, 0xfd, 0xd2, 0x96, 0xe1, 0x71, 0xed, 0x74, 0x4c, 0xe9, 0xd3, 0xe9, - 0x24, 0x21, 0x80, 0x3d, 0xd4, 0x5b, 0xcf, 0x1c, 0xf9, 0x89, 0xb3, 0x74, - 0xb1, 0x64, 0x77, 0x33, 0x36, 0xf4, 0xe0, 0xe8, 0xd9, 0x1b, 0x05, 0xb4, - 0xa8, 0x05, 0x97, 0x27, 0x75, 0xea, 0x0a, 0x0a, 0x90, 0x7b, 0x38, 0x2b, - 0xd3, 0x59, 0xab, 0x31, 0x96, 0x10, 0x23, 0x77, 0x8c, 0xc4, 0x78, 0x6b, - 0xaf, 0xce, 0x3a, 0xe3, 0xeb, 0x3d, 0x68, 0x20, 0xdc, 0x39, 0xa1, 0x69, - 0x51, 0xd6, 0xbb, 0xe8, 0xba, 0x21, 0x85, 0x50, 0x31, 0xa0, 0xf2, 0x69, - 0x14, 0x7c, 0x34, 0x99, 0x61, 0x21, 0x0b, 0x14, 0x4d, 0x9d, 0x6d, 0x3a, - 0xe9, 0x6c, 0x7f, 0xb5, 0xd3, 0xdf, 0x7e, 0xfc, 0x04, 0x8b, 0x63, 0x6f, - 0x6e, 0x3f, 0xee, 0x88, 0xa6, 0x2c, 0x75, 0xdb, 0xc7, 0x63, 0x57, 0xd0, - 0x50, 0x0c, 0x4f, 0x51, 0x90, 0xbf, 0xbe, 0xde, 0xd1, 0x08, 0x55, 0xe5, - 0x0e, 0xb7, 0xd5, 0x02, 0x0f, 0x53, 0xfb, 0x24, 0x97, 0x9d, 0xf4, 0x40, - 0x44, 0x2b, 0xd3, 0xe8, 0xac, 0x6c, 0x30, 0xf9, 0x10, 0xb0, 0xab, 0x31, - 0x50, 0x24, 0x0a, 0x40, 0x42, 0xe7, 0xcd, 0xeb, 0xb3, 0x97, 0xaf, 0x16, - 0xa2, 0x29, 0x90, 0xfd, 0xb4, 0x7c, 0x61, 0xc8, 0x28, 0x86, 0x55, 0x03, - 0x87, 0x23, 0xbf, 0x98, 0x8a, 0xd1, 0xf8, 0x55, 0x3e, 0x28, 0x8b, 0xaa, - 0x18, 0x85, 0x7a, 0x1a, 0x66, 0xed, 0x3d, 0x3a, 0x02, 0x65, 0xe1, 0x3a, - 0x3b, 0xd7, 0xb8, 0xbe, 0x3e, 0xb9, 0x48, 0xf3, 0xca, 0x61, 0xf9, 0xc3, - 0x2c, 0xf3, 0xac, 0xa6, 0x0a, 0x57, 0x8a, 0xbf, 0xd0, 0xc5, 0x30, 0x56, - 0x7c, 0x3c, 0x13, 0x10, 0x7d, 0x36, 0xef, 0x61, 0x5f, 0x83, 0x31, 0xdd, - 0xd6, 0xc9, 0x2c, 0x2b, 0xe8, 0x2e, 0x31, 0xf7, 0x81, 0x5d, 0xb5, 0x2e, - 0xac, 0x95, 0x00, 0x5a, 0x35, 0xf0, 0x23, 0x2f, 0x91, 0x15, 0xa2, 0x8a, - 0x20, 0xbe, 0xa6, 0xf7, 0x18, 0x3a, 0x81, 0xb4, 0xa6, 0x59, 0x79, 0xb2, - 0xef, 0x1c, 0xbc, 0x41, 0xb6, 0xbf, 0x73, 0x3c, 0xfd, 0xc3, 0xa2, 0xe4, - 0xac, 0x02, 0x02, 0x0c, 0x91, 0xd0, 0x8e, 0x6c, 0x3a, 0x28, 0xe6, 0x25, - 0x26, 0x7b, 0xe3, 0x78, 0x6e, 0x18, 0x7c, 0xff, 0x92, 0xdd, 0xcc, 0xb2, - 0x46, 0xb4, 0x90, 0x41, 0x42, 0x16, 0x20, 0x12, 0x29, 0x34, 0x4c, 0x2b, - 0x15, 0x6e, 0xe2, 0x05, 0xf4, 0x11, 0x5e, 0xf1, 0xe0, 0xd1, 0x21, 0x03, - 0x91, 0x86, 0x44, 0x3e, 0xcb, 0x2f, 0x18, 0x74, 0xcd, 0x07, 0xa7, 0x13, - 0x16, 0x71, 0x10, 0x49, 0xa9, 0x77, 0x11, 0x17, 0x4a, 0xe1, 0x0e, 0x71, - 0x27, 0x1c, 0xb2, 0x37, 0xf5, 0x56, 0x43, 0x09, 0x1e, 0x02, 0x7a, 0x69, - 0xe8, 0x3d, 0xf0, 0xc9, 0xef, 0xae, 0x5b, 0x49, 0x8d, 0x7c, 0x04, 0xa0, - 0x88, 0xbc, 0xf1, 0xb1, 0x86, 0xeb, 0xb3, 0x85, 0x80, 0x48, 0xef, 0xc4, - 0x6e, 0x2b, 0xd8, 0x26, 0x11, 0x55, 0x3e, 0x1e, 0x8b, 0xfe, 0x1a, 0xd2, - 0x32, 0x47, 0xa1, 0x0b, 0x12, 0x6b, 0xd5, 0x5f, 0x38, 0x6c, 0xbc, 0x68, - 0xfe, 0xc4, 0xf5, 0xae, 0xcf, 0xa3, 0x43, 0xf7, 0x2c, 0x43, 0x38, 0x5c, - 0x2f, 0x8d, 0x05, 0x9e, 0xf9, 0xa4, 0xff, 0xc4, 0xe9, 0xdc, 0x87, 0xa2, - 0x48, 0xd3, 0x16, 0x4e, 0xc8, 0x4f, 0x29, 0x72, 0x63, 0x55, 0xdf, 0x8c, - 0x33, 0x5b, 0x19, 0xd4, 0x74, 0xe4, 0x8a, 0xbb, 0x4c, 0x89, 0xcd, 0x36, - 0x90, 0x26, 0x1a, 0x44, 0x45, 0xc0, 0x03, 0xce, 0x65, 0x9b, 0x7d, 0x00, - 0x81, 0xa7, 0xd6, 0xfb, 0x0b, 0x65, 0x64, 0xba, 0xe0, 0xe9, 0x53, 0x3c, - 0x6f, 0xd7, 0x96, 0x65, 0x83, 0x69, 0x02, 0x0b, 0xe6, 0x34, 0x9e, 0xe3, - 0xbd, 0x90, 0x05, 0xb6, 0xf3, 0x69, 0x50, 0x33, 0xb4, 0x10, 0x51, 0xe4, - 0x9b, 0xdf, 0x87, 0x02, 0x57, 0x60, 0xa7, 0x77, 0x9e, 0x81, 0x86, 0x50, - 0x26, 0x4f, 0x6b, 0x14, 0xcc, 0x17, 0x91, 0x67, 0x0c, 0x78, 0x26, 0xd1, - 0xac, 0x24, 0x87, 0xfe, 0xfd, 0x3d, 0xbf, 0x7b, 0x46, 0x32, 0x3d, 0x9e, - 0xa7, 0x63, 0xc4, 0xac, 0x48, 0x92, 0x9d, 0xfe, 0xd6, 0x6d, 0xc8, 0x33, - 0x1c, 0xcc, 0x25, 0x2f, 0xcb, 0xdb, 0x81, 0x33, 0x92, 0x93, 0x21, 0x98, - 0xa8, 0x1b, 0xf6, 0x08, 0x8b, 0x46, 0x12, 0xf0, 0x21, 0xf1, 0x64, 0xc6, - 0x19, 0xef, 0x08, 0xfd, 0xa9, 0x57, 0x62, 0xaf, 0xc7, 0x80, 0x70, 0x65, - 0x14, 0x77, 0xa1, 0x9e, 0x75, 0x17, 0xde, 0x1b, 0x4d, 0x06, 0x57, 0x2d, - 0x04, 0x4a, 0x96, 0x1a, 0x14, 0x47, 0xdc, 0x68, 0x30, 0x20, 0x48, 0x7b, - 0x52, 0x7f, 0x08, 0x40, 0xe6, 0xf1, 0x97, 0x8f, 0xb6, 0xfa, 0xae, 0x3e, - 0x74, 0xbc, 0xb2, 0xb7, 0xa5, 0x00, 0xc4, 0xf7, 0x1f, 0x5f, 0x80, 0x91, - 0x5b, 0xf0, 0x76, 0xf2, 0x88, 0x3b, 0xea, 0x4c, 0x9e, 0xbf, 0xfb, 0xaa, - 0xff, 0xfd, 0xa3, 0x51, 0xef, 0x61, 0x7f, 0xfb, 0x3f, 0xff, 0xf6, 0xaa, - 0xf3, 0x09, 0x31, 0x93, 0x42, 0x2e, 0x43, 0x65, 0xa2, 0xb4, 0x64, 0x45, - 0x37, 0x98, 0x55, 0x3d, 0xe8, 0xff, 0x4f, 0x25, 0x02, 0x47, 0xc9, 0x17, - 0x62, 0x79, 0x0f, 0xb5, 0x11, 0x3d, 0x34, 0x6b, 0x55, 0x0f, 0xe1, 0xb1, - 0x7e, 0x40, 0xcf, 0x2e, 0x33, 0x9f, 0xea, 0x82, 0xde, 0xff, 0x73, 0x59, - 0xd1, 0x51, 0x86, 0x17, 0x82, 0x1d, 0x1c, 0xbd, 0x06, 0xaa, 0xae, 0xbf, - 0x62, 0x18, 0x66, 0x13, 0xfb, 0xd3, 0xe0, 0x09, 0x57, 0xf6, 0x5d, 0xc1, - 0x8c, 0x92, 0xce, 0x1f, 0x3a, 0x1a, 0x0f, 0xa0, 0x57, 0x64, 0x6a, 0x82, - 0x54, 0xae, 0x79, 0x03, 0xa1, 0x6e, 0x11, 0x90, 0x41, 0xda, 0x14, 0x30, - 0xf3, 0x4a, 0x6e, 0x82, 0x32, 0x23, 0x84, 0xc3, 0x61, 0x12, 0xca, 0xa8, - 0x6b, 0x3c, 0x7b, 0xa2, 0x85, 0x74, 0x42, 0x74, 0x07, 0x0c, 0xcb, 0x03, - 0x9c, 0xd0, 0xa4, 0x90, 0x49, 0x10, 0x62, 0x58, 0x3e, 0x0d, 0xbe, 0xfc, - 0x0e, 0xee, 0x11, 0x6c, 0xd1, 0x3f, 0xe0, 0x96, 0xec, 0x82, 0x58, 0xf7, - 0x4f, 0xef, 0x28, 0xef, 0xa0, 0xf9, 0xa1, 0x83, 0x03, 0x7c, 0xf7, 0x87, - 0x6d, 0x2c, 0x6b, 0xa8, 0x65, 0x75, 0x0b, 0xb2, 0x60, 0x1a, 0x35, 0x05, - 0xc9, 0x1b, 0x6d, 0x3e, 0x2d, 0x8d, 0x23, 0xc2, 0x57, 0x17, 0x15, 0x8c, - 0x7f, 0xf6, 0xf1, 0xe7, 0x5f, 0xb7, 0x7b, 0x8f, 0x7e, 0x0d, 0x62, 0x13, - 0x76, 0xf2, 0x87, 0xed, 0x77, 0x7f, 0xd8, 0xe9, 0x38, 0x4c, 0x28, 0x07, - 0xf1, 0xea, 0x32, 0xc1, 0x2a, 0xca, 0x0a, 0x54, 0x35, 0x35, 0x8d, 0x13, - 0x69, 0x61, 0xa3, 0x61, 0xde, 0x95, 0xd3, 0xd5, 0x31, 0x92, 0xa3, 0xa9, - 0xc8, 0x68, 0x9d, 0x5c, 0xcd, 0xd0, 0xc1, 0xd8, 0x4b, 0x7e, 0x2f, 0x2a, - 0x23, 0xbb, 0x18, 0x00, 0x11, 0x44, 0x7b, 0x1c, 0x17, 0x22, 0x9c, 0x2b, - 0xdc, 0x74, 0x98, 0x31, 0x4c, 0x25, 0x4d, 0x93, 0x28, 0x92, 0xa0, 0x48, - 0xce, 0xcf, 0x13, 0x17, 0x40, 0xf0, 0x45, 0x08, 0xda, 0xc4, 0xce, 0xd8, - 0x76, 0xa0, 0xcc, 0xa2, 0xb0, 0x50, 0x10, 0xfd, 0x9e, 0x46, 0x16, 0xe2, - 0x5b, 0x89, 0x09, 0x80, 0x76, 0x89, 0x98, 0xc7, 0x8d, 0xca, 0xc4, 0xa3, - 0xbc, 0xc4, 0x1b, 0x11, 0xda, 0xc8, 0xab, 0x40, 0x0a, 0xfc, 0xa9, 0xc5, - 0xf8, 0x60, 0x24, 0x18, 0x8a, 0x17, 0x8a, 0xa7, 0x9b, 0x9e, 0x17, 0x57, - 0x41, 0x3a, 0xb7, 0xa8, 0x0b, 0x9a, 0x26, 0x1d, 0x50, 0x60, 0x6e, 0x5a, - 0xf5, 0x02, 0x04, 0x4c, 0x9d, 0xa7, 0x9f, 0xa1, 0x47, 0x9b, 0xe0, 0xf9, - 0xd3, 0x9c, 0x9b, 0x27, 0x9d, 0x99, 0x21, 0x3b, 0xb0, 0x7a, 0x94, 0xf2, - 0x68, 0xa8, 0xf4, 0x85, 0xfa, 0xb5, 0x18, 0x85, 0x8a, 0x60, 0x65, 0x1d, - 0x22, 0xb1, 0x88, 0xb5, 0x37, 0x70, 0x4a, 0x38, 0x58, 0xb9, 0xaf, 0xb7, - 0x80, 0x21, 0x4a, 0xaa, 0xd3, 0xa5, 0x4a, 0xd6, 0x7a, 0x6b, 0x98, 0x1c, - 0xa5, 0x4a, 0x39, 0x96, 0x47, 0xde, 0xe0, 0x40, 0x51, 0xaf, 0xce, 0x04, - 0xa6, 0x21, 0xac, 0x41, 0x19, 0x31, 0x0b, 0x2c, 0xa4, 0xc3, 0x04, 0x28, - 0xc4, 0x62, 0x98, 0x67, 0x55, 0xd8, 0x7e, 0x43, 0xc5, 0x0b, 0xad, 0x6c, - 0x0e, 0xb3, 0xab, 0xcd, 0xe9, 0x7c, 0x3c, 0xde, 0x6b, 0x5d, 0xa2, 0x9e, - 0x7b, 0x42, 0xa3, 0x7f, 0xd9, 0x60, 0x24, 0xf1, 0xb7, 0x4b, 0x5f, 0x83, - 0x37, 0xbe, 0x58, 0x2c, 0x7b, 0x11, 0x6a, 0x44, 0xd3, 0x7d, 0xa3, 0x31, - 0x3b, 0x93, 0x7c, 0x3a, 0xaf, 0x24, 0x1d, 0x97, 0xcc, 0x41, 0x91, 0x33, - 0xdf, 0xa0, 0x96, 0x69, 0xc6, 0x0c, 0xe3, 0x6f, 0xfa, 0xa7, 0x1a, 0xfb, - 0xb8, 0xd2, 0x16, 0x9a, 0x72, 0xb5, 0xb4, 0xad, 0xbe, 0xce, 0x58, 0x58, - 0x88, 0xb6, 0xa2, 0x31, 0x81, 0x92, 0xc5, 0x8b, 0xf0, 0xae, 0x36, 0xfc, - 0x16, 0x96, 0xbf, 0xf9, 0xdb, 0x2c, 0xbb, 0xc0, 0xb9, 0xf4, 0x4c, 0x78, - 0x94, 0x36, 0xd1, 0x7c, 0x62, 0x21, 0x67, 0x8a, 0xc7, 0x29, 0x93, 0x01, - 0x8a, 0xed, 0x93, 0x32, 0x84, 0xa5, 0x2e, 0x30, 0x99, 0x06, 0x61, 0x61, - 0x88, 0x8e, 0x83, 0xe8, 0x83, 0x1b, 0xe2, 0xf9, 0x10, 0x9d, 0x95, 0x85, - 0x08, 0xa2, 0xdb, 0x33, 0x0d, 0x8b, 0xe5, 0x09, 0x6c, 0xee, 0xb1, 0x8f, - 0x65, 0x93, 0x6d, 0xaf, 0xae, 0xcc, 0x04, 0x57, 0x1b, 0x9e, 0x7e, 0xb7, - 0xd3, 0x16, 0xa5, 0xe4, 0x0e, 0x5f, 0x62, 0xf1, 0xb2, 0xfc, 0x9f, 0x05, - 0x17, 0xfa, 0x12, 0x07, 0x7a, 0x12, 0x07, 0x06, 0x2f, 0xba, 0x73, 0x83, - 0x24, 0x47, 0xbb, 0x89, 0x67, 0x3a, 0x79, 0x0a, 0x3f, 0x5a, 0xca, 0xb4, - 0xf8, 0xec, 0x84, 0x60, 0x96, 0x12, 0xc7, 0x7b, 0x0c, 0x1d, 0x84, 0xc6, - 0xee, 0x61, 0xd7, 0x0b, 0xb8, 0xd1, 0xe0, 0x18, 0xc0, 0x57, 0x8f, 0x7b, - 0x99, 0x45, 0x52, 0x4a, 0x28, 0x7c, 0x22, 0x0f, 0x84, 0x6e, 0x55, 0xbc, - 0xc3, 0x33, 0x87, 0xf3, 0x23, 0x52, 0x21, 0x45, 0x4f, 0x1e, 0x8d, 0xb0, - 0x04, 0xc5, 0xd3, 0x1a, 0x17, 0x0b, 0x9a, 0xcf, 0x92, 0x39, 0x50, 0xfb, - 0xd8, 0xb1, 0x55, 0xa9, 0xac, 0xe3, 0xcb, 0x95, 0x7b, 0x59, 0x30, 0xa9, - 0x11, 0xb0, 0xc0, 0x0f, 0xc3, 0x71, 0x72, 0x0a, 0x31, 0xe8, 0x36, 0xe2, - 0x07, 0x25, 0x14, 0x80, 0x92, 0x22, 0xac, 0x30, 0x4b, 0xcc, 0x35, 0x59, - 0x43, 0xd7, 0xf2, 0x1f, 0xa1, 0x64, 0x97, 0xdb, 0x85, 0xcf, 0x16, 0xa9, - 0xec, 0xfa, 0xe8, 0xd4, 0x93, 0x19, 0x50, 0xed, 0xf1, 0x6a, 0x8e, 0x89, - 0x2f, 0x9b, 0x5e, 0x72, 0xbf, 0xa5, 0x91, 0xab, 0xbc, 0x85, 0xc0, 0xfe, - 0xab, 0xeb, 0x82, 0xec, 0x42, 0x8a, 0x8c, 0x80, 0xe8, 0x08, 0x08, 0x14, - 0x63, 0x99, 0x06, 0xbf, 0x03, 0xf6, 0x1b, 0x02, 0xf3, 0x2a, 0x35, 0x3e, - 0x99, 0x25, 0xcd, 0xf0, 0x9f, 0x2e, 0x28, 0xf9, 0x10, 0x64, 0x6d, 0xcc, - 0x91, 0x9c, 0x60, 0x61, 0x3d, 0x4c, 0x96, 0x38, 0xd1, 0x57, 0x2d, 0xdf, - 0x1b, 0xeb, 0xb5, 0xaa, 0x69, 0x91, 0x41, 0x43, 0xe6, 0xf8, 0xf7, 0x7c, - 0x66, 0x6e, 0x01, 0xc2, 0x98, 0x9a, 0xaa, 0x50, 0xe6, 0x86, 0x12, 0xe7, - 0x68, 0x7a, 0xfc, 0x62, 0x4a, 0x96, 0xe4, 0xd4, 0xc1, 0x32, 0x14, 0x13, - 0x9d, 0x62, 0x53, 0xee, 0x7d, 0x2a, 0xb8, 0x02, 0x6f, 0x51, 0x70, 0x6c, - 0x2e, 0xe8, 0x25, 0x68, 0xa0, 0xc7, 0xc2, 0xdc, 0x14, 0xb2, 0x2a, 0x01, - 0x4f, 0x18, 0xfd, 0x99, 0xab, 0x1f, 0x30, 0x34, 0x30, 0xca, 0xa7, 0x79, - 0x65, 0x61, 0xb1, 0x08, 0xe4, 0x18, 0x96, 0x26, 0x3c, 0x26, 0xb4, 0xb8, - 0xc4, 0x49, 0xc8, 0xb9, 0xc9, 0x51, 0x30, 0x2e, 0x8d, 0x94, 0x3a, 0x1e, - 0x52, 0xe6, 0xbe, 0xac, 0xa1, 0x6b, 0x90, 0x91, 0x17, 0x49, 0x7e, 0x1d, - 0x32, 0x4c, 0x4d, 0x03, 0x71, 0xc3, 0xcc, 0x79, 0xf5, 0x9c, 0x65, 0x96, - 0xa0, 0xb1, 0xda, 0xe8, 0x7d, 0x58, 0xaa, 0xe7, 0xe7, 0x67, 0x2e, 0x83, - 0x1f, 0x79, 0x15, 0x23, 0x50, 0x33, 0xd0, 0xab, 0xdb, 0x87, 0x68, 0x25, - 0xb9, 0xc4, 0x34, 0x21, 0x64, 0xfb, 0x88, 0x01, 0x5d, 0x0d, 0x4c, 0xfd, - 0xe6, 0x3c, 0xdc, 0x3a, 0x94, 0x5c, 0x25, 0x50, 0x89, 0xfe, 0xe7, 0xae, - 0xcd, 0xe5, 0xd5, 0xf7, 0xb0, 0x39, 0xab, 0xe7, 0xb2, 0xdd, 0x06, 0x57, - 0xec, 0x12, 0xaf, 0x6f, 0x39, 0xdc, 0xd6, 0xeb, 0x2d, 0x97, 0xcd, 0xf6, - 0xad, 0x37, 0x51, 0xf3, 0xdc, 0xa3, 0x47, 0xf2, 0xb1, 0x1e, 0xfc, 0x90, - 0x46, 0xf2, 0x81, 0x83, 0xbc, 0x1c, 0xd0, 0x50, 0xb4, 0xfe, 0xfe, 0xd6, - 0xb1, 0x2f, 0xf2, 0xc9, 0x04, 0xa4, 0x2e, 0x0f, 0x5e, 0xb2, 0xf8, 0x95, - 0x8b, 0x35, 0x63, 0x82, 0x6c, 0xa7, 0xf2, 0x46, 0xbe, 0x82, 0xc6, 0x64, - 0x57, 0x89, 0x01, 0x67, 0x9b, 0x78, 0x33, 0x22, 0x55, 0x3d, 0x23, 0x7f, - 0x37, 0xb0, 0x7f, 0xc2, 0x7c, 0xf5, 0x59, 0xbf, 0x11, 0x8f, 0x11, 0x39, - 0x45, 0xca, 0x4d, 0xd0, 0xe9, 0x10, 0xe3, 0x41, 0x9a, 0xab, 0xbb, 0x92, - 0x21, 0x60, 0xf3, 0x91, 0x9c, 0xdd, 0x40, 0x99, 0x86, 0x08, 0x27, 0x21, - 0x1f, 0x94, 0x5c, 0x2d, 0x9b, 0xff, 0xc1, 0x50, 0x47, 0x38, 0x3f, 0x9d, - 0xca, 0x4e, 0x09, 0x3a, 0x83, 0x0b, 0x04, 0x92, 0xd5, 0xff, 0xde, 0x21, - 0xa4, 0xa8, 0x67, 0xdf, 0xeb, 0x50, 0x40, 0xfd, 0x12, 0xad, 0xc9, 0x13, - 0x24, 0x02, 0xc7, 0x21, 0x52, 0x21, 0x42, 0x90, 0xf4, 0x35, 0x74, 0x82, - 0xca, 0x42, 0xe9, 0x10, 0x78, 0xc0, 0xee, 0x24, 0x91, 0x39, 0x8b, 0xee, - 0x30, 0x5a, 0xe9, 0x28, 0x25, 0x1f, 0xeb, 0x6a, 0x63, 0x58, 0xcc, 0xa2, - 0xff, 0x00, 0x28, 0xde, 0xaf, 0x1f, 0xe6, 0x85, 0x89, 0xf6, 0x82, 0x25, - 0x47, 0xa7, 0x7c, 0x26, 0xca, 0xbc, 0x7a, 0x2f, 0x38, 0x17, 0x5a, 0x74, - 0x4a, 0xe6, 0x2f, 0x15, 0xd0, 0xac, 0xc6, 0x16, 0xf2, 0xc1, 0xf9, 0xec, - 0x7f, 0xca, 0xd9, 0x0c, 0x64, 0x77, 0x4f, 0x98, 0xe2, 0xad, 0xa4, 0xbe, - 0xc2, 0x71, 0x75, 0x03, 0xe9, 0xfd, 0xd7, 0xfd, 0x9d, 0x5d, 0x38, 0xba, - 0x4f, 0x1a, 0x77, 0x76, 0x23, 0xce, 0xdd, 0x1f, 0xda, 0xc5, 0x53, 0x89, - 0x27, 0xd9, 0x81, 0x0a, 0x71, 0xd1, 0x84, 0xea, 0x3d, 0xdf, 0xbf, 0xc3, - 0x22, 0x9c, 0x1b, 0x77, 0x32, 0xd9, 0x85, 0x15, 0x1a, 0xe9, 0xb6, 0x64, - 0xd0, 0xa3, 0x2f, 0xb3, 0xc4, 0x3a, 0xb6, 0x1e, 0x4d, 0x2c, 0x54, 0x1f, - 0x08, 0x14, 0xca, 0xdd, 0xb4, 0xc3, 0x23, 0x30, 0xda, 0x0a, 0x07, 0x2d, - 0x40, 0x07, 0xc0, 0xde, 0x93, 0xdd, 0xad, 0x2d, 0x75, 0xcc, 0x13, 0xcc, - 0x54, 0x55, 0x3b, 0x78, 0x00, 0x12, 0x91, 0xfa, 0xff, 0x92, 0xf2, 0x8c, - 0x31, 0x2b, 0xbc, 0x47, 0x84, 0x95, 0x65, 0xe4, 0x83, 0xfd, 0x60, 0xc8, - 0xe9, 0x12, 0xe2, 0x59, 0x5a, 0xee, 0xd3, 0x53, 0xca, 0xe3, 0x25, 0x94, - 0xe2, 0xc8, 0x02, 0x04, 0x8a, 0xa7, 0xb3, 0xcb, 0x32, 0xad, 0xac, 0x30, - 0xee, 0xe9, 0xe9, 0x8b, 0x84, 0xe2, 0x4d, 0x4e, 0xe0, 0x4b, 0xfe, 0xca, - 0xd5, 0x8c, 0x71, 0x55, 0x6e, 0x35, 0x17, 0x8f, 0x1a, 0xf9, 0x6c, 0x58, - 0x4c, 0xd4, 0x3a, 0xa7, 0x7c, 0x4a, 0x35, 0xda, 0xd5, 0x91, 0x4d, 0xf0, - 0xe9, 0x96, 0x4c, 0x48, 0x4c, 0x4a, 0xec, 0xa5, 0x55, 0x4f, 0xc5, 0xf1, - 0x67, 0x85, 0x26, 0x29, 0xa3, 0x2c, 0x07, 0x9d, 0xfd, 0x6d, 0x8e, 0x38, - 0x11, 0x5c, 0x1d, 0x6b, 0xb3, 0xdf, 0xdf, 0x24, 0xcb, 0xda, 0x26, 0xfe, - 0xab, 0x29, 0xde, 0xac, 0xce, 0x90, 0xf9, 0x06, 0x5b, 0xeb, 0x6b, 0x40, - 0x09, 0x86, 0xe2, 0x8f, 0xa5, 0xa6, 0x69, 0xf5, 0xb7, 0x79, 0x5a, 0x11, - 0x54, 0x19, 0x0a, 0x50, 0x19, 0x12, 0x2f, 0xc7, 0x7d, 0xc6, 0xb6, 0x62, - 0x0d, 0xca, 0x27, 0xef, 0x4c, 0x1c, 0x67, 0x17, 0x23, 0xcb, 0xd6, 0x52, - 0xe3, 0x92, 0x8a, 0x49, 0x20, 0xab, 0xd2, 0x6a, 0x95, 0x78, 0xa0, 0x48, - 0x00, 0x6e, 0x8b, 0x9d, 0x0a, 0x93, 0x5d, 0xe2, 0x76, 0x58, 0xce, 0x0a, - 0x99, 0x17, 0xba, 0x11, 0x09, 0x43, 0xd4, 0x06, 0xef, 0xda, 0x38, 0xeb, - 0xb8, 0xcd, 0xfa, 0x00, 0xcb, 0x0a, 0xff, 0xcb, 0xea, 0xc1, 0x26, 0x79, - 0x2f, 0x86, 0x6d, 0x15, 0x18, 0x28, 0x81, 0xac, 0xc7, 0xda, 0x5a, 0xd8, - 0xbd, 0x1c, 0x2e, 0xaa, 0xe1, 0x6c, 0x7e, 0x4e, 0xe5, 0xe7, 0x2f, 0x69, - 0x89, 0xa3, 0xa2, 0xce, 0x6f, 0xa5, 0xc8, 0x59, 0x38, 0xe0, 0xe2, 0x40, - 0xb4, 0x7a, 0xf4, 0xc9, 0x3a, 0xec, 0x08, 0xbf, 0xb9, 0x81, 0x0b, 0x48, - 0xc0, 0xba, 0x1e, 0xc8, 0x7a, 0x96, 0xa1, 0xb6, 0x61, 0xa0, 0x30, 0xe7, - 0x14, 0x89, 0x92, 0xd6, 0xea, 0x91, 0xa4, 0x36, 0x1a, 0x31, 0x1c, 0x21, - 0x45, 0x8b, 0x7b, 0x8b, 0x4a, 0xd9, 0x63, 0x41, 0x67, 0x64, 0x32, 0x58, - 0x52, 0x99, 0x5d, 0x06, 0x14, 0xe0, 0x41, 0x36, 0xd3, 0x70, 0x05, 0xa3, - 0xef, 0xf5, 0xf1, 0x43, 0xf2, 0x93, 0x32, 0x63, 0xb9, 0x4c, 0x77, 0x1e, - 0x3d, 0x56, 0x93, 0x29, 0x91, 0x92, 0x94, 0x87, 0x24, 0x27, 0xf2, 0x1a, - 0x7f, 0xbf, 0xb9, 0xb9, 0x26, 0x30, 0x30, 0x1a, 0x58, 0x83, 0xdf, 0x7d, - 0xbd, 0x16, 0x01, 0x4f, 0xa8, 0x97, 0x4e, 0x31, 0x79, 0x31, 0x22, 0x95, - 0x6a, 0x96, 0x9f, 0xbe, 0xf4, 0x42, 0x82, 0xe8, 0x1a, 0xe2, 0x9f, 0xd1, - 0x4a, 0x39, 0x22, 0xd1, 0xfa, 0xfa, 0xdc, 0x52, 0x52, 0x88, 0x9a, 0xc3, - 0x70, 0x03, 0x45, 0xf8, 0xa6, 0xfa, 0xf1, 0xba, 0xde, 0x56, 0x33, 0x9c, - 0x28, 0x6c, 0x60, 0xf9, 0x8b, 0x02, 0x2a, 0x81, 0x8b, 0xeb, 0x9a, 0x24, - 0xf9, 0x9e, 0x80, 0xfe, 0x1c, 0x1c, 0x8b, 0xe4, 0x8d, 0x70, 0xc8, 0x01, - 0x33, 0xa0, 0xc6, 0xea, 0x06, 0x3e, 0x4c, 0xae, 0x86, 0x70, 0x64, 0x14, - 0x0b, 0xc1, 0x23, 0x0a, 0x7a, 0x98, 0x15, 0x46, 0x57, 0x0c, 0x05, 0x69, - 0x70, 0x2e, 0x94, 0x9f, 0x8c, 0xc0, 0xa8, 0x5c, 0xb4, 0xf1, 0x86, 0xd2, - 0x54, 0x96, 0x5c, 0x30, 0xb0, 0x04, 0x19, 0x85, 0x6a, 0x88, 0x76, 0x23, - 0xdf, 0xb8, 0xa8, 0x28, 0xf3, 0x33, 0x93, 0xc1, 0x3c, 0x14, 0xb8, 0x0d, - 0x75, 0x14, 0xa4, 0x18, 0x52, 0xad, 0xa8, 0x8e, 0x48, 0x77, 0x14, 0xde, - 0x44, 0xe8, 0xae, 0x8c, 0xf7, 0xcc, 0x1b, 0x1a, 0x96, 0x54, 0x87, 0x03, - 0x34, 0xb5, 0x89, 0xf4, 0x24, 0xd7, 0xe1, 0x9e, 0x1a, 0x30, 0x61, 0x4c, - 0xb8, 0xab, 0xa4, 0xcd, 0xfe, 0x30, 0x9d, 0xc3, 0x4e, 0xa3, 0xd9, 0xa6, - 0x18, 0x8f, 0xe0, 0x53, 0xf8, 0x0d, 0x88, 0x6d, 0x88, 0xbb, 0xdf, 0xb5, - 0x2a, 0xf6, 0xae, 0x8c, 0x3d, 0xe6, 0xfc, 0x1f, 0x9f, 0x6a, 0x29, 0xd6, - 0xfe, 0x97, 0x7f, 0xdc, 0xcc, 0x8f, 0x4f, 0xe1, 0xb7, 0x3f, 0x76, 0xad, - 0xba, 0xfd, 0x17, 0xea, 0xf2, 0x47, 0xda, 0x5b, 0xd2, 0x79, 0x57, 0x7b, - 0x96, 0x40, 0x9e, 0x85, 0xde, 0x7f, 0x67, 0xe7, 0xc7, 0xb4, 0x6a, 0x44, - 0xbb, 0x88, 0x8c, 0x43, 0x54, 0x4a, 0xcc, 0xb0, 0x51, 0x5b, 0xbd, 0xc1, - 0x2c, 0x3e, 0x5f, 0x6d, 0xd3, 0xa8, 0x1b, 0xf8, 0xff, 0x2a, 0xb6, 0xcb, - 0xc6, 0x5b, 0x76, 0x9a, 0x07, 0xd9, 0xf6, 0xf6, 0x93, 0xf3, 0x47, 0xdb, - 0x4f, 0xbe, 0xfa, 0x72, 0xf4, 0xf0, 0xe1, 0xa3, 0x9d, 0xe1, 0x60, 0x6d, - 0xb5, 0xdb, 0x0e, 0xad, 0x97, 0xd0, 0x18, 0xb7, 0x13, 0xd8, 0x25, 0x97, - 0xff, 0x89, 0xfc, 0xea, 0x6f, 0xa8, 0x7c, 0x64, 0xcd, 0x85, 0x2e, 0xbe, - 0xdc, 0xd9, 0xdd, 0xde, 0x7c, 0xdc, 0x7f, 0xd8, 0xdf, 0x51, 0x61, 0x89, - 0x01, 0xea, 0x18, 0x4b, 0xb8, 0x4e, 0x38, 0x09, 0xd5, 0xd2, 0x79, 0xad, - 0xae, 0x0c, 0x97, 0x2a, 0x72, 0xc5, 0x8b, 0xd8, 0xd6, 0x11, 0x12, 0x6d, - 0xa9, 0x7e, 0xd1, 0x76, 0x80, 0x89, 0x54, 0xb4, 0x8e, 0x69, 0x31, 0xed, - 0x41, 0xc7, 0xea, 0x08, 0x53, 0x78, 0x67, 0xc2, 0xa2, 0x3c, 0xcf, 0xff, - 0x36, 0xcf, 0x6b, 0x10, 0x0a, 0xc5, 0x20, 0x99, 0x9d, 0xe3, 0x33, 0x65, - 0x71, 0x5d, 0x09, 0xc2, 0x55, 0xa1, 0xea, 0xa0, 0x14, 0xd7, 0xf2, 0x08, - 0x4a, 0x8a, 0xd2, 0xe3, 0xd1, 0xac, 0xa9, 0x92, 0x60, 0x4e, 0x3c, 0x1a, - 0x1f, 0xa9, 0xb0, 0x66, 0xe2, 0x74, 0x80, 0x7c, 0xea, 0x05, 0x28, 0x2d, - 0x57, 0xe8, 0xb3, 0x49, 0xe3, 0x12, 0x11, 0x3e, 0xbc, 0x54, 0x32, 0x70, - 0x29, 0xa0, 0x95, 0x22, 0xf7, 0xe4, 0x03, 0xce, 0x03, 0xe2, 0xd8, 0x92, - 0x08, 0x76, 0x93, 0x2f, 0x8d, 0x08, 0xd5, 0x92, 0xc3, 0x01, 0xb3, 0x14, - 0xb5, 0x55, 0x2a, 0x56, 0xcd, 0xc1, 0x8a, 0xb2, 0x5c, 0x12, 0x1e, 0xe6, - 0x60, 0x23, 0xdb, 0xa2, 0x42, 0x65, 0x13, 0x3f, 0x21, 0x97, 0x7e, 0xd9, - 0x25, 0xce, 0x0d, 0xde, 0x71, 0x83, 0x4b, 0xaf, 0x0e, 0x01, 0xb3, 0x37, - 0x4c, 0x3a, 0xc8, 0x13, 0x57, 0x0d, 0xaa, 0xe2, 0x5a, 0x53, 0xdd, 0x50, - 0x68, 0x4a, 0xe4, 0xb1, 0x26, 0x48, 0xa6, 0x3e, 0xb9, 0x02, 0x99, 0xee, - 0x7e, 0x0e, 0x32, 0xdd, 0xf9, 0x7f, 0x64, 0x7a, 0x6f, 0x64, 0xba, 0x73, - 0xdf, 0x64, 0xba, 0xb3, 0x0a, 0x99, 0xee, 0xfc, 0x6e, 0x32, 0xdd, 0x5e, - 0x99, 0x4c, 0x77, 0x23, 0x32, 0xfd, 0x31, 0x2f, 0xc6, 0x64, 0x6f, 0x88, - 0xc8, 0xf4, 0xe1, 0x3d, 0x93, 0x29, 0x56, 0xb7, 0x8b, 0x88, 0x74, 0x3f, - 0xc8, 0x69, 0x86, 0xe6, 0x17, 0x08, 0xc2, 0x28, 0x22, 0x90, 0x84, 0xa7, - 0x09, 0xa6, 0xfa, 0xdd, 0x98, 0x26, 0x3e, 0x27, 0x51, 0xec, 0xde, 0x37, - 0x51, 0xec, 0xae, 0x42, 0x14, 0xbb, 0xf7, 0xc9, 0xbb, 0xb6, 0x97, 0x12, - 0x45, 0x99, 0x71, 0xb0, 0xe0, 0x5f, 0x35, 0x1a, 0x13, 0xda, 0xfe, 0x95, - 0x9c, 0x89, 0x7b, 0x28, 0x8e, 0xfc, 0x1a, 0xf0, 0x3f, 0x58, 0xbc, 0x36, - 0xc5, 0xe4, 0xf4, 0xf8, 0xe0, 0x4f, 0xa7, 0x1a, 0x00, 0x6d, 0x78, 0xdf, - 0x22, 0xa4, 0x32, 0xe2, 0x32, 0x45, 0x3a, 0x73, 0x7d, 0x34, 0x0d, 0x56, - 0xa2, 0xbc, 0x35, 0x0b, 0x59, 0xa5, 0x2c, 0x70, 0x3d, 0xe3, 0x54, 0x56, - 0x4d, 0xf0, 0x49, 0xc9, 0x15, 0x16, 0x21, 0x12, 0x52, 0xef, 0xd4, 0xa7, - 0x0f, 0xbc, 0xd6, 0x12, 0x57, 0xd3, 0x24, 0x3c, 0xbd, 0x5e, 0x5f, 0x96, - 0x84, 0x0e, 0xc7, 0x8f, 0x6f, 0x84, 0xd7, 0x75, 0x28, 0x32, 0x0c, 0xd7, - 0x50, 0x3f, 0x79, 0x41, 0xf0, 0x8a, 0xb0, 0x1c, 0x89, 0x46, 0xd3, 0x9a, - 0x59, 0xc7, 0x3e, 0xd4, 0xa0, 0x98, 0xb6, 0xba, 0x1e, 0xe2, 0x6a, 0x76, - 0xab, 0xc8, 0xe6, 0xde, 0xfc, 0x83, 0x39, 0x73, 0x34, 0x3c, 0x24, 0x1d, - 0x93, 0x3f, 0x1c, 0x83, 0xf4, 0xa5, 0x5d, 0x7d, 0xab, 0x62, 0xff, 0x74, - 0x55, 0x0c, 0xde, 0x57, 0x0f, 0xa1, 0x09, 0x62, 0xc7, 0xf8, 0x7b, 0x8a, - 0x7f, 0x88, 0xdc, 0x87, 0x1f, 0x3c, 0xc2, 0xf6, 0x11, 0xc4, 0x95, 0xfe, - 0xb8, 0xa4, 0xde, 0x88, 0x85, 0x72, 0xa9, 0x43, 0xbf, 0x55, 0x03, 0xd9, - 0x29, 0x03, 0xea, 0x55, 0x63, 0xb4, 0xa0, 0x65, 0x60, 0xd6, 0x4c, 0x28, - 0x85, 0x16, 0x26, 0xe4, 0x8a, 0x4a, 0x28, 0xab, 0x87, 0x1e, 0xa8, 0xad, - 0x87, 0x0d, 0xf7, 0x24, 0x8b, 0xc0, 0xa2, 0x0c, 0xe6, 0x15, 0x73, 0x0d, - 0xe7, 0xb3, 0x14, 0xcb, 0x83, 0x90, 0x0a, 0x2f, 0x62, 0x37, 0xc9, 0x5d, - 0xd1, 0x24, 0x50, 0xa3, 0xe7, 0x93, 0x4c, 0x6b, 0x61, 0x6f, 0x6f, 0x3d, - 0x31, 0xef, 0xc8, 0x5b, 0xc5, 0x14, 0xb2, 0x40, 0x41, 0x4e, 0x19, 0x64, - 0x84, 0x61, 0x1f, 0xad, 0x1e, 0x77, 0x23, 0x5b, 0x85, 0xae, 0x30, 0x69, - 0xe8, 0xcd, 0x4b, 0x84, 0x35, 0x2e, 0x44, 0x03, 0xc5, 0x89, 0x2d, 0xa2, - 0xd0, 0x60, 0x09, 0x2d, 0x32, 0x09, 0x29, 0xaa, 0x0c, 0x08, 0xd8, 0x96, - 0x80, 0xa1, 0x91, 0xe2, 0x12, 0x96, 0xfb, 0x5d, 0x28, 0x41, 0xfa, 0xef, - 0x0f, 0xb7, 0x88, 0xac, 0xf4, 0x5d, 0x8c, 0x16, 0x18, 0x17, 0x62, 0x8a, - 0xfd, 0xf7, 0xdd, 0xd4, 0x44, 0x7a, 0x39, 0x6d, 0x16, 0x10, 0x77, 0xdf, - 0xde, 0x54, 0x3b, 0xce, 0x46, 0x25, 0x4c, 0xcd, 0x1a, 0x16, 0xdf, 0xfb, - 0x90, 0x48, 0xec, 0x00, 0xfe, 0x63, 0x1f, 0xaf, 0x1e, 0x65, 0xae, 0x69, - 0x5f, 0xd4, 0xbc, 0x72, 0x91, 0x3f, 0x74, 0x1b, 0x59, 0xfb, 0x4d, 0xd0, - 0x41, 0x75, 0xd5, 0x39, 0xac, 0xeb, 0xe0, 0x14, 0x4c, 0x2b, 0x29, 0xdb, - 0x45, 0x43, 0x09, 0x9f, 0x27, 0xd6, 0x90, 0x0b, 0xbb, 0xf3, 0xd8, 0xbb, - 0xdd, 0x85, 0x8a, 0x79, 0xe9, 0xb8, 0x9b, 0x44, 0x39, 0x71, 0xb4, 0xbf, - 0xd6, 0x22, 0x34, 0x88, 0x35, 0xf0, 0xae, 0xab, 0xd8, 0xfb, 0x87, 0xed, - 0xae, 0xfd, 0x61, 0xcd, 0x6d, 0x34, 0x9a, 0xb9, 0xca, 0x82, 0xea, 0x52, - 0xa9, 0x96, 0x3d, 0x28, 0x33, 0x09, 0xa2, 0xc4, 0xca, 0xbd, 0x94, 0xa4, - 0x33, 0xcb, 0xca, 0x01, 0x26, 0x7b, 0x5d, 0x64, 0x56, 0xb5, 0x2d, 0xf8, - 0x11, 0xa4, 0xba, 0x01, 0x55, 0x36, 0xe8, 0x13, 0x6e, 0x4e, 0xd3, 0x85, - 0xaa, 0x9e, 0x94, 0x54, 0xca, 0x1f, 0xe0, 0x2b, 0x9a, 0x65, 0x46, 0x59, - 0x40, 0xd5, 0x2c, 0x1d, 0x60, 0x61, 0xba, 0x7c, 0x86, 0x58, 0xe3, 0xdf, - 0x14, 0xdf, 0xf4, 0x36, 0x1c, 0x9c, 0x04, 0x96, 0x4f, 0xae, 0x04, 0x5d, - 0x95, 0x30, 0x10, 0xe1, 0x10, 0x5e, 0x72, 0x78, 0xb0, 0xa4, 0x14, 0x51, - 0x0a, 0x1c, 0x83, 0x55, 0x10, 0x6c, 0x6f, 0x54, 0x62, 0x00, 0x43, 0x22, - 0xdc, 0xed, 0x94, 0x12, 0xa5, 0xc1, 0x42, 0x8c, 0xc6, 0x14, 0x02, 0x85, - 0x36, 0x9b, 0x04, 0x83, 0xfe, 0x93, 0xea, 0x66, 0x72, 0x5e, 0x30, 0xa0, - 0x62, 0x5d, 0x7c, 0x36, 0xc7, 0x48, 0x9b, 0x67, 0xa4, 0x41, 0x54, 0x4b, - 0x53, 0xca, 0x3e, 0x06, 0x65, 0xc5, 0xa7, 0x43, 0x32, 0xbc, 0xc4, 0xf2, - 0xd3, 0xf4, 0x87, 0xdb, 0x63, 0x11, 0xdc, 0xd1, 0xa0, 0x40, 0xed, 0xa1, - 0xc4, 0x32, 0xb8, 0xbb, 0x15, 0x98, 0x6a, 0xf2, 0xd4, 0x98, 0xfb, 0xb7, - 0xbe, 0xc2, 0x31, 0x6c, 0x0f, 0x55, 0x2b, 0xd7, 0x2f, 0xa5, 0x50, 0x1c, - 0xe3, 0x1a, 0x72, 0xa8, 0x9d, 0x52, 0x0a, 0x2f, 0x8a, 0x3e, 0x16, 0x38, - 0x5a, 0x86, 0x8c, 0x81, 0xd3, 0xd1, 0xb2, 0x91, 0x98, 0x53, 0x09, 0xa2, - 0xb2, 0xcb, 0x01, 0x00, 0x14, 0x6b, 0x12, 0x40, 0xbb, 0x10, 0x72, 0x82, - 0x20, 0xb9, 0xf0, 0x3b, 0x86, 0xd3, 0x0a, 0x59, 0x19, 0xcc, 0xfd, 0xad, - 0x76, 0x58, 0xb2, 0x06, 0x23, 0x59, 0xeb, 0x06, 0x6c, 0xb5, 0xf1, 0x8d, - 0x5e, 0x67, 0x1a, 0x77, 0xfa, 0xf7, 0xac, 0x2c, 0xf8, 0xd9, 0x10, 0x68, - 0xa0, 0xb5, 0x4c, 0x60, 0xc8, 0xfb, 0x57, 0x69, 0x3e, 0xa6, 0x2d, 0xb0, - 0x0f, 0xb1, 0x67, 0xb5, 0xb6, 0xfc, 0x11, 0xc3, 0xbb, 0x4e, 0x30, 0xf6, - 0xcb, 0xd0, 0xde, 0x42, 0x39, 0x4e, 0x62, 0xbf, 0xe9, 0x70, 0x98, 0x0b, - 0xfa, 0xa0, 0x00, 0xd6, 0x87, 0x15, 0x60, 0x48, 0x0d, 0x04, 0x56, 0xa4, - 0x16, 0x70, 0x09, 0xd6, 0x7d, 0x1e, 0xa4, 0x39, 0x62, 0x10, 0xac, 0x38, - 0x54, 0x58, 0x11, 0x16, 0x6a, 0x91, 0xf7, 0x18, 0x3d, 0xf6, 0xe0, 0x59, - 0x36, 0xbd, 0x69, 0x8c, 0xa0, 0x8b, 0x82, 0x67, 0x71, 0x25, 0x16, 0x42, - 0xad, 0x32, 0x44, 0xa5, 0x21, 0x2a, 0x09, 0x07, 0xb0, 0xe1, 0x40, 0x0b, - 0x8a, 0xf0, 0x61, 0x83, 0xd1, 0xf6, 0xbf, 0xf1, 0x93, 0x14, 0xf1, 0x73, - 0x61, 0xae, 0xeb, 0x54, 0xb1, 0xc9, 0xa1, 0x7b, 0x71, 0x27, 0x6d, 0x93, - 0xa4, 0x62, 0xe6, 0x24, 0xda, 0x54, 0xf3, 0xf3, 0xdf, 0xa4, 0x32, 0x31, - 0xca, 0xef, 0xa5, 0xcc, 0x51, 0xa4, 0x45, 0xdc, 0x1e, 0x78, 0x82, 0x9d, - 0x01, 0xc0, 0x2e, 0x1e, 0xc0, 0x4f, 0x8c, 0x7a, 0x0c, 0x11, 0xc2, 0x4d, - 0xd2, 0xa0, 0x4e, 0x99, 0x4d, 0x59, 0x5c, 0xeb, 0x9e, 0xd1, 0x30, 0xb4, - 0xd0, 0x1b, 0x61, 0x9a, 0x3c, 0x61, 0x0c, 0xf8, 0x05, 0xb6, 0x65, 0xe0, - 0x42, 0xc1, 0x96, 0x70, 0x88, 0x4f, 0xe3, 0xe4, 0xf5, 0x10, 0x60, 0x00, - 0x58, 0x97, 0x8e, 0x52, 0xf7, 0x8f, 0xf8, 0x0f, 0xaf, 0x86, 0x22, 0x4a, - 0xd0, 0x27, 0x48, 0x9b, 0xf4, 0x84, 0x7f, 0xef, 0x1b, 0xfc, 0x84, 0x5f, - 0xe4, 0xb3, 0x76, 0xc7, 0x7b, 0x6f, 0xa7, 0xcc, 0x4b, 0x89, 0x0f, 0x29, - 0xec, 0xbd, 0x23, 0x9d, 0x99, 0x55, 0x14, 0x96, 0x9c, 0x73, 0x4d, 0x20, - 0x61, 0x19, 0x00, 0x5a, 0x00, 0x46, 0x9f, 0xcf, 0x38, 0x44, 0xa3, 0x4a, - 0x47, 0x98, 0x45, 0x89, 0xb0, 0x8f, 0x37, 0x09, 0x9b, 0x5d, 0x49, 0xe9, - 0xe6, 0x0c, 0x8a, 0x90, 0xb3, 0x0b, 0xf2, 0x4f, 0xcd, 0x95, 0xd8, 0xd1, - 0xab, 0xfc, 0x60, 0x88, 0xb5, 0xbd, 0x4a, 0x54, 0xb0, 0xdd, 0xea, 0x18, - 0xb7, 0xa7, 0xd6, 0xd8, 0xf9, 0x4f, 0xae, 0x11, 0x2d, 0x08, 0x6b, 0x85, - 0xaf, 0x71, 0xc3, 0x95, 0x3a, 0xb8, 0x43, 0x4e, 0x7c, 0x21, 0x45, 0xcb, - 0x2a, 0xb7, 0x23, 0xee, 0x4c, 0x54, 0x81, 0xec, 0x41, 0x84, 0x4c, 0x2e, - 0x96, 0x7f, 0xc9, 0x3f, 0x88, 0x9d, 0x27, 0x5d, 0x3a, 0x5f, 0x96, 0x6c, - 0x50, 0x69, 0x3a, 0xe3, 0x03, 0x81, 0x88, 0x90, 0xf8, 0x70, 0x89, 0x59, - 0x4e, 0x2b, 0x8a, 0x7c, 0x01, 0x22, 0x99, 0x8a, 0xcd, 0x5c, 0x64, 0x2c, - 0x5d, 0x52, 0x1a, 0x17, 0x27, 0xb8, 0x3e, 0xc0, 0x8b, 0x9a, 0x20, 0xe8, - 0xe5, 0xa6, 0x8e, 0x6b, 0xb0, 0xb3, 0x33, 0x92, 0xf6, 0xf5, 0xb3, 0x88, - 0x3e, 0x0d, 0x82, 0xe9, 0x56, 0x40, 0x85, 0x2b, 0x8b, 0x36, 0x75, 0xc1, - 0x65, 0x53, 0x42, 0x76, 0x09, 0x7c, 0x12, 0x20, 0x4e, 0x1c, 0x47, 0xd7, - 0x4f, 0x03, 0x67, 0xff, 0x36, 0x28, 0x49, 0xb6, 0x75, 0x23, 0xf1, 0x91, - 0xd8, 0x34, 0x51, 0xfe, 0x24, 0xdc, 0x60, 0xb2, 0xdb, 0x54, 0x83, 0xcb, - 0x2c, 0x94, 0xea, 0xd8, 0x27, 0xa0, 0x9b, 0xb9, 0x10, 0xaf, 0x62, 0x10, - 0xe1, 0x27, 0x0e, 0x4f, 0x3e, 0xe2, 0x1a, 0x52, 0xa3, 0x2e, 0xb1, 0xb2, - 0x68, 0x92, 0xa7, 0x0c, 0xbd, 0x1c, 0xbe, 0x7b, 0xfb, 0xfa, 0xf4, 0xed, - 0xc9, 0xc9, 0xf1, 0x9b, 0xb3, 0xc3, 0x67, 0x98, 0x84, 0x7a, 0x76, 0x7c, - 0x70, 0xfc, 0xb2, 0xed, 0xe2, 0x0e, 0x18, 0x40, 0x5c, 0xd1, 0xbd, 0x71, - 0xb2, 0x9d, 0x62, 0x92, 0xac, 0xe3, 0x3a, 0x6e, 0xf8, 0x78, 0x2f, 0x0b, - 0x02, 0xf1, 0x6e, 0xbe, 0xae, 0xda, 0x8e, 0x2e, 0xe6, 0x9c, 0x6d, 0xea, - 0xc6, 0xcc, 0xe9, 0x79, 0x1a, 0x12, 0xdf, 0xcc, 0x19, 0xa6, 0x28, 0x16, - 0xce, 0x6c, 0xa1, 0xa3, 0x20, 0x38, 0xce, 0x41, 0x72, 0xf6, 0x2b, 0xff, - 0xf9, 0x3c, 0xb6, 0x51, 0x37, 0xcc, 0x77, 0x46, 0x41, 0x50, 0xbe, 0x85, - 0x7a, 0x22, 0xba, 0x21, 0x4a, 0x6a, 0x50, 0x0d, 0x53, 0xd7, 0x12, 0x69, - 0x80, 0x84, 0x81, 0x58, 0x16, 0x10, 0x51, 0xa0, 0x98, 0xfa, 0xe2, 0x43, - 0x4e, 0x10, 0x18, 0x66, 0xd3, 0x9c, 0xef, 0x62, 0x97, 0xce, 0x87, 0xef, - 0x95, 0x19, 0x2b, 0x60, 0x12, 0x88, 0x3d, 0xcc, 0xa8, 0x22, 0x5a, 0xb4, - 0x57, 0x12, 0x3e, 0xa5, 0xaf, 0x48, 0x59, 0x9d, 0xeb, 0x58, 0x1a, 0x60, - 0xa0, 0x05, 0x54, 0x28, 0xa8, 0xb4, 0xf5, 0xc2, 0xd2, 0x75, 0x65, 0x88, - 0xc4, 0x92, 0x49, 0xb5, 0xc6, 0x25, 0x60, 0x05, 0xdf, 0x8d, 0xda, 0x65, - 0x32, 0x44, 0x2b, 0x61, 0x57, 0x82, 0xb0, 0x77, 0xd1, 0x4b, 0x16, 0x57, - 0xda, 0xa1, 0x41, 0x50, 0x33, 0xd4, 0x9f, 0xe8, 0x6c, 0x0c, 0x1c, 0x4e, - 0x7d, 0x76, 0x09, 0x00, 0x1a, 0x87, 0xf0, 0x1c, 0x47, 0x10, 0x2d, 0x9c, - 0xd8, 0xbc, 0x5c, 0xd2, 0xf2, 0xe3, 0x47, 0xfd, 0x9d, 0x8d, 0x28, 0xe8, - 0x1f, 0x63, 0x3d, 0x61, 0x1d, 0xfe, 0x88, 0xff, 0xea, 0x05, 0x83, 0xbf, - 0xbb, 0x5d, 0xd1, 0x80, 0x11, 0x57, 0x3c, 0x2a, 0x14, 0x8c, 0x27, 0x27, - 0xce, 0x45, 0x51, 0x88, 0x84, 0xab, 0xe5, 0x55, 0x62, 0x02, 0xe6, 0xa9, - 0x7f, 0xb6, 0x60, 0x5a, 0xdf, 0xc9, 0x37, 0x8d, 0xb5, 0x5d, 0x8d, 0x09, - 0x2a, 0xd1, 0x7e, 0xe8, 0x9a, 0xc6, 0xb7, 0x9a, 0x65, 0xc8, 0x79, 0xac, - 0x17, 0xed, 0x27, 0x5e, 0x21, 0xd7, 0xab, 0x69, 0xc1, 0x74, 0x12, 0xd9, - 0x4e, 0x58, 0xd6, 0x44, 0xb8, 0xa1, 0xa2, 0x21, 0xa3, 0x86, 0xf7, 0x8a, - 0x52, 0x89, 0x46, 0x6c, 0x09, 0x49, 0xcd, 0x28, 0x68, 0x78, 0x69, 0x41, - 0x2f, 0x44, 0x93, 0x6a, 0x68, 0x7a, 0xab, 0x69, 0xaf, 0x4b, 0x8c, 0x2b, - 0xde, 0xb0, 0x42, 0xec, 0xb7, 0x61, 0x5a, 0x31, 0xdb, 0x8a, 0x49, 0xcd, - 0x4b, 0xec, 0x2b, 0xac, 0xef, 0xf8, 0xbd, 0x42, 0xd4, 0x7b, 0x85, 0x4f, - 0xc0, 0x56, 0x11, 0xde, 0x8d, 0xce, 0x56, 0x60, 0xee, 0x23, 0xeb, 0x51, - 0x07, 0x4c, 0x65, 0xc6, 0x28, 0x71, 0x05, 0x97, 0x5c, 0x9c, 0xcf, 0x12, - 0xc9, 0x82, 0x9f, 0x50, 0x46, 0x60, 0x3f, 0xa1, 0xc2, 0xdf, 0x61, 0xa8, - 0xf6, 0xc2, 0x26, 0xba, 0xfc, 0x37, 0xeb, 0x62, 0x93, 0x3b, 0xec, 0xe3, - 0x3f, 0x5f, 0x78, 0x13, 0x9c, 0x6c, 0x8a, 0x8a, 0x1f, 0x5c, 0x13, 0x85, - 0x02, 0x35, 0x2c, 0x31, 0xd1, 0xc8, 0xc6, 0x31, 0x71, 0x6f, 0xd2, 0xa2, - 0xf4, 0x48, 0x71, 0xd9, 0x7a, 0x9f, 0x2d, 0x67, 0x7d, 0x4b, 0x40, 0xb9, - 0x14, 0x5b, 0xa1, 0x09, 0x62, 0x3e, 0x62, 0xec, 0x4b, 0x95, 0xf3, 0x34, - 0xaf, 0x6a, 0x14, 0x92, 0xd4, 0x55, 0xda, 0x55, 0x0f, 0x6b, 0x70, 0xb0, - 0x62, 0xf3, 0xe2, 0x8a, 0x8d, 0xc1, 0x07, 0xbe, 0x74, 0x99, 0xb4, 0x6f, - 0xa7, 0x70, 0x2a, 0x8b, 0x8b, 0x29, 0x28, 0xd2, 0x43, 0x19, 0x51, 0x74, - 0x83, 0x8a, 0x01, 0xca, 0x9d, 0x68, 0xba, 0x45, 0x05, 0x91, 0x81, 0x25, - 0x29, 0xb9, 0x8f, 0x07, 0x54, 0xc0, 0x97, 0xef, 0x32, 0x83, 0xb7, 0xe7, - 0xda, 0xaa, 0x43, 0x77, 0x53, 0xf3, 0x35, 0x2e, 0x61, 0xff, 0x2c, 0x6c, - 0x09, 0x49, 0x46, 0x96, 0x8b, 0x7f, 0xa1, 0xbd, 0xac, 0x1d, 0xd9, 0x22, - 0x44, 0x55, 0xb6, 0xc3, 0x5b, 0x30, 0xa6, 0x16, 0x57, 0xb6, 0x8b, 0x90, - 0x2d, 0x18, 0x74, 0xa1, 0x1f, 0x10, 0x2c, 0x72, 0x3a, 0x5a, 0x6d, 0xad, - 0xe0, 0xfb, 0x1a, 0xa4, 0xc1, 0xc0, 0x15, 0x71, 0x06, 0x23, 0x36, 0x6f, - 0x8d, 0x12, 0x60, 0x45, 0x1b, 0x56, 0xc5, 0x3e, 0x06, 0x08, 0x59, 0xf2, - 0x82, 0x46, 0xc7, 0xf3, 0xad, 0x26, 0x71, 0xf9, 0x24, 0x0c, 0x71, 0xee, - 0x73, 0x30, 0x30, 0xcb, 0x62, 0x05, 0xed, 0x98, 0xd4, 0x67, 0x0c, 0xcf, - 0xa7, 0xea, 0x3c, 0xe2, 0xc3, 0x10, 0x83, 0x04, 0xbe, 0xc2, 0x54, 0x1a, - 0x85, 0xe0, 0xc3, 0x03, 0x04, 0x71, 0xa2, 0x04, 0xd2, 0x38, 0xe7, 0x6e, - 0x54, 0x6c, 0x7d, 0x54, 0xd0, 0x80, 0x54, 0x75, 0xdd, 0x7e, 0xa8, 0x35, - 0x4f, 0x48, 0x30, 0xa4, 0x6a, 0xa5, 0xca, 0x79, 0x24, 0x4d, 0x90, 0xf0, - 0x77, 0xe6, 0x48, 0xe7, 0x89, 0x5a, 0xaa, 0x6d, 0xb7, 0x29, 0xbe, 0x1d, - 0xd1, 0x05, 0x42, 0x46, 0xa6, 0xb0, 0x61, 0x7e, 0xc3, 0x7b, 0x38, 0xfe, - 0x77, 0xb4, 0x90, 0x2e, 0x35, 0x90, 0xfa, 0x00, 0x7c, 0x1e, 0x1e, 0x31, - 0xb9, 0x10, 0xc4, 0xec, 0x53, 0x60, 0xc8, 0xba, 0x4d, 0xda, 0xc9, 0x35, - 0xda, 0x14, 0xad, 0x22, 0xb8, 0xb3, 0xad, 0xb6, 0x92, 0x79, 0x57, 0xa0, - 0xb0, 0x35, 0xc7, 0xcf, 0xd8, 0x1a, 0x73, 0x35, 0x16, 0x72, 0xe1, 0xec, - 0x6e, 0xb8, 0x80, 0x71, 0x0a, 0x24, 0x46, 0x76, 0xc5, 0x80, 0x28, 0xb0, - 0xd4, 0x7f, 0x0c, 0x55, 0x4f, 0x7c, 0x98, 0x92, 0x10, 0xbd, 0x5e, 0xd4, - 0x12, 0x8e, 0x44, 0xe5, 0x6e, 0x32, 0x12, 0x4d, 0x26, 0x58, 0xdd, 0x26, - 0x65, 0x26, 0xab, 0x58, 0x04, 0x20, 0x5b, 0xf6, 0x90, 0x1b, 0xc8, 0x51, - 0x81, 0xd9, 0x22, 0xdd, 0x98, 0x65, 0x5e, 0x35, 0x26, 0x6e, 0xf6, 0x36, - 0x69, 0xc1, 0xc4, 0x85, 0x8f, 0xae, 0xba, 0x26, 0xab, 0xcd, 0x33, 0x8f, - 0xad, 0xc5, 0xab, 0xd9, 0xbe, 0xe8, 0xf2, 0x89, 0x92, 0xf2, 0x29, 0xff, - 0xda, 0x8b, 0xbf, 0xf0, 0x99, 0x40, 0x29, 0xc8, 0x21, 0x9f, 0xd7, 0x05, - 0x5a, 0x6c, 0xa5, 0x4e, 0xcc, 0x2c, 0xa7, 0x12, 0x51, 0x29, 0x91, 0x4e, - 0x2e, 0x10, 0x05, 0x0b, 0x18, 0x19, 0x06, 0x4b, 0xe2, 0x12, 0xb9, 0xd0, - 0x8e, 0x31, 0x9f, 0x6a, 0x38, 0x97, 0xdd, 0x5c, 0x1c, 0xe2, 0xe8, 0xef, - 0x7f, 0x22, 0x63, 0x3e, 0x11, 0xcc, 0xf3, 0x89, 0xe5, 0x87, 0x94, 0x07, - 0xb9, 0xdd, 0x37, 0x2d, 0x43, 0x33, 0x81, 0x93, 0x39, 0x1d, 0xf6, 0xe0, - 0x8c, 0xcc, 0x5a, 0x8c, 0x92, 0x61, 0x42, 0xab, 0xa3, 0x03, 0xde, 0xbd, - 0x0b, 0xd6, 0xa6, 0xfe, 0x4d, 0xf4, 0x16, 0x60, 0x12, 0x86, 0x68, 0xbf, - 0x0f, 0xfb, 0xb5, 0x9a, 0xc5, 0xbe, 0x1b, 0x6f, 0x4b, 0xb4, 0x51, 0x71, - 0x52, 0xbc, 0x7f, 0x2c, 0x08, 0x77, 0xcc, 0x5e, 0xbf, 0xe7, 0x77, 0x1b, - 0x5b, 0x42, 0xbe, 0xd4, 0x78, 0x0f, 0x9c, 0xf8, 0x40, 0xbb, 0x10, 0x39, - 0xd9, 0xde, 0x32, 0xd8, 0x18, 0x0f, 0x84, 0x0d, 0xc1, 0x53, 0x01, 0x3b, - 0xf2, 0xdd, 0x08, 0xe8, 0x78, 0xc2, 0xf9, 0x5b, 0xac, 0x25, 0xca, 0xcd, - 0xcc, 0x0f, 0x34, 0xcc, 0x7c, 0xed, 0xf0, 0x35, 0x01, 0x3e, 0x9a, 0xdb, - 0xc3, 0x31, 0xe4, 0x08, 0x16, 0xb8, 0x50, 0x7c, 0xc5, 0x2f, 0xcf, 0xef, - 0xc5, 0xb7, 0xf0, 0x6d, 0x7d, 0x9e, 0x6d, 0x6c, 0x2b, 0x00, 0xd5, 0xba, - 0x91, 0x83, 0xb4, 0xc7, 0x5e, 0xc6, 0xb6, 0x08, 0xd3, 0x83, 0x7d, 0x41, - 0x01, 0x0c, 0x75, 0xb2, 0xc4, 0x25, 0x29, 0xd7, 0x1c, 0xfa, 0x39, 0x6f, - 0x40, 0x7a, 0x99, 0x90, 0xf4, 0xcb, 0x61, 0xa6, 0x81, 0x25, 0x3a, 0x21, - 0xb2, 0x1f, 0x27, 0x88, 0xb0, 0xcc, 0x44, 0xeb, 0x9e, 0x62, 0x2f, 0xd2, - 0x8d, 0x31, 0x2f, 0xb2, 0xed, 0x2a, 0xd8, 0x37, 0xf9, 0x60, 0x28, 0xe2, - 0x0c, 0x4b, 0x37, 0x69, 0x4e, 0x23, 0x1b, 0x13, 0xaf, 0x5b, 0xab, 0x8e, - 0xb1, 0x18, 0x84, 0x19, 0xc5, 0xa3, 0x74, 0x10, 0xe5, 0x5f, 0x37, 0x86, - 0xbd, 0x56, 0x51, 0x71, 0x88, 0x2b, 0x8f, 0x51, 0x1b, 0xd5, 0xd9, 0x24, - 0xc1, 0x94, 0x88, 0x50, 0xd4, 0x4a, 0xab, 0x9d, 0xc4, 0x5d, 0x1b, 0xde, - 0x0c, 0x89, 0x88, 0x1a, 0x1e, 0x28, 0x3e, 0x93, 0x05, 0x51, 0xf4, 0x49, - 0x7f, 0x17, 0x24, 0x51, 0xd2, 0x1c, 0x24, 0x7e, 0xd0, 0x7f, 0xf7, 0x88, - 0x0a, 0x69, 0xd2, 0x3d, 0xc1, 0xeb, 0xa3, 0xaa, 0xa4, 0x76, 0xe9, 0xf1, - 0x3b, 0xb1, 0xbf, 0x20, 0x0a, 0xd3, 0xdc, 0x47, 0xa0, 0xd7, 0xcc, 0x59, - 0xfa, 0x42, 0x37, 0x59, 0xae, 0xf2, 0xad, 0x2b, 0x80, 0x84, 0x6d, 0xb3, - 0x8d, 0xd9, 0xac, 0xb4, 0xba, 0xa3, 0xb6, 0x0b, 0xfd, 0x36, 0x46, 0xd6, - 0x20, 0x93, 0xfb, 0xad, 0xc2, 0xd7, 0xe8, 0x62, 0x95, 0xb3, 0x63, 0x0f, - 0xaf, 0x56, 0x99, 0x6f, 0xa7, 0x91, 0x28, 0x30, 0x48, 0x51, 0x8e, 0xa3, - 0x7a, 0x42, 0x29, 0xc5, 0x3d, 0xf3, 0x39, 0x59, 0xc0, 0xfb, 0xd3, 0xce, - 0xf0, 0xe9, 0x08, 0x03, 0x64, 0x51, 0xa3, 0xf5, 0xa1, 0xbe, 0x5a, 0x4f, - 0x5e, 0x03, 0xaf, 0x17, 0x0f, 0xc3, 0x59, 0x54, 0x77, 0x1c, 0x63, 0x9d, - 0x24, 0xd0, 0x3a, 0x2c, 0x2d, 0x6c, 0x88, 0x6b, 0xb3, 0x62, 0x24, 0x2e, - 0xf7, 0xc9, 0x7a, 0xb5, 0x91, 0x50, 0x65, 0x3d, 0xf3, 0xd4, 0x4b, 0x20, - 0xb6, 0x14, 0x32, 0xf3, 0xe4, 0x1c, 0xcb, 0x66, 0x8c, 0x3c, 0x18, 0x4a, - 0x8c, 0xd6, 0xa8, 0x5b, 0x99, 0xe2, 0x28, 0x42, 0xb2, 0xcb, 0x5b, 0x0d, - 0xe7, 0x47, 0x98, 0xad, 0x96, 0x84, 0xe4, 0x68, 0x0a, 0x56, 0x31, 0xae, - 0xf2, 0xd4, 0x21, 0x08, 0xea, 0x16, 0xfe, 0x6d, 0x9e, 0x83, 0x98, 0x41, - 0x21, 0xc4, 0x5c, 0xc1, 0x47, 0xd6, 0x92, 0x41, 0xf8, 0x02, 0xf2, 0x0d, - 0xaf, 0x4e, 0xe8, 0x1b, 0xce, 0xae, 0xe4, 0xa6, 0xc4, 0x38, 0x54, 0xf2, - 0xfa, 0x5d, 0xf9, 0x29, 0xa1, 0xc0, 0xac, 0x48, 0x39, 0x11, 0x54, 0xf0, - 0x6a, 0x04, 0x46, 0x1d, 0x1d, 0xec, 0x73, 0xc5, 0x9b, 0x1a, 0x6b, 0x7b, - 0x7c, 0x30, 0x62, 0xfb, 0x58, 0xc6, 0x2c, 0x64, 0xd6, 0x5d, 0x4e, 0x7a, - 0x31, 0x3c, 0x9b, 0x7f, 0x29, 0x4a, 0x6e, 0xa7, 0xbc, 0xe5, 0x2a, 0xbc, - 0x8c, 0xcb, 0xa8, 0x00, 0xf7, 0x5e, 0x67, 0xd7, 0x15, 0xfc, 0x62, 0x69, - 0x68, 0x4e, 0x44, 0xb0, 0x3e, 0x55, 0x3c, 0x70, 0x72, 0x2f, 0x31, 0x6b, - 0xed, 0xe0, 0xb8, 0x74, 0xab, 0xd8, 0x69, 0x6c, 0x2f, 0x40, 0x94, 0x0f, - 0xee, 0x22, 0xba, 0x51, 0x59, 0x84, 0x5f, 0xef, 0xec, 0x75, 0x80, 0x5a, - 0xd7, 0xd1, 0x12, 0x21, 0xb0, 0x8b, 0xd8, 0xc0, 0xf6, 0x1e, 0xfe, 0xdc, - 0xa1, 0x9f, 0xbb, 0x08, 0x82, 0xd8, 0x20, 0xf1, 0x8a, 0x2b, 0x47, 0x2e, - 0xd0, 0x76, 0xd7, 0x83, 0xbc, 0x8d, 0x92, 0x06, 0xba, 0x31, 0xb3, 0x19, - 0x78, 0x2f, 0x44, 0x6b, 0x93, 0x20, 0x10, 0xa6, 0x48, 0xad, 0x72, 0xb9, - 0x9d, 0xf3, 0xcc, 0x89, 0x1f, 0x58, 0xd5, 0xc1, 0x20, 0x0d, 0x29, 0x13, - 0xff, 0x5d, 0x99, 0x91, 0x97, 0x3b, 0x99, 0xd7, 0x5c, 0x15, 0x17, 0x2d, - 0x05, 0x63, 0x33, 0x48, 0x49, 0x0f, 0x64, 0x3a, 0xf2, 0x21, 0x61, 0x7e, - 0xfb, 0x44, 0x3f, 0x51, 0x5b, 0xad, 0xdd, 0x12, 0x20, 0xd3, 0x5f, 0x33, - 0x88, 0x9d, 0x56, 0x0a, 0x60, 0xc8, 0x7b, 0x8c, 0xa9, 0x91, 0xdd, 0x86, - 0x87, 0x7c, 0xda, 0x22, 0xe1, 0x7e, 0x51, 0x38, 0x03, 0xb0, 0xd7, 0x9c, - 0xac, 0x0f, 0xe3, 0x1b, 0x4e, 0x87, 0xb6, 0x14, 0x36, 0x4f, 0xbc, 0x06, - 0xb4, 0xed, 0x54, 0x44, 0xfd, 0x8e, 0xf8, 0x8e, 0x25, 0x77, 0x10, 0xba, - 0x4d, 0x93, 0xe1, 0x78, 0x7b, 0x84, 0x33, 0xe1, 0x73, 0xcd, 0x7b, 0x5d, - 0x54, 0x0d, 0xf0, 0x94, 0xc9, 0xda, 0x69, 0x53, 0x3b, 0x48, 0xeb, 0x19, - 0xa6, 0x47, 0xff, 0x15, 0x67, 0x98, 0x3a, 0xda, 0x34, 0x7c, 0x7d, 0xd9, - 0xff, 0xdf, 0x77, 0x90, 0xf5, 0xf8, 0xfa, 0x50, 0x17, 0xee, 0xa9, 0x79, - 0x7c, 0xe9, 0xd2, 0xc0, 0x9f, 0x7f, 0x15, 0x99, 0xee, 0xd7, 0xe5, 0xb7, - 0x07, 0xd5, 0x3b, 0x4e, 0x16, 0x6f, 0x91, 0x65, 0xd2, 0xb3, 0x55, 0x9d, - 0x8e, 0xee, 0x95, 0xc6, 0xf9, 0x61, 0x42, 0x97, 0xd3, 0xf3, 0xa7, 0x83, - 0xd3, 0x3f, 0x6c, 0xef, 0xc8, 0x09, 0xa2, 0x73, 0xe3, 0xa0, 0xa8, 0x9a, - 0xb6, 0x34, 0x4a, 0xdf, 0x09, 0x07, 0x2e, 0x3c, 0x4e, 0xfe, 0x2a, 0xce, - 0x01, 0x66, 0x1c, 0x46, 0xb6, 0x5d, 0x9b, 0x45, 0xc8, 0x6a, 0x92, 0x99, - 0xa1, 0x61, 0xd1, 0x78, 0xc5, 0x68, 0x02, 0xf8, 0x39, 0xe8, 0x53, 0x25, - 0x31, 0x23, 0x12, 0xb1, 0x22, 0xaf, 0x8f, 0x62, 0xbe, 0xf4, 0xa5, 0x44, - 0x2d, 0xaf, 0x29, 0x66, 0x12, 0xd4, 0x8d, 0x12, 0x7c, 0x2e, 0x63, 0xaf, - 0x3d, 0xf0, 0x84, 0xf5, 0xf3, 0x70, 0x15, 0xc9, 0x4d, 0x84, 0xdb, 0x13, - 0xae, 0x21, 0x63, 0xa0, 0xde, 0x42, 0x60, 0x17, 0x51, 0x50, 0xb2, 0x7b, - 0x72, 0xb4, 0xaa, 0xa5, 0x10, 0x9f, 0xbf, 0xb3, 0xc2, 0xb9, 0xeb, 0x85, - 0x28, 0xe0, 0x77, 0x50, 0x6b, 0x37, 0x5a, 0x37, 0xaf, 0x0b, 0x60, 0xf3, - 0xbd, 0xfa, 0x66, 0x96, 0xb5, 0xd0, 0x2c, 0x7d, 0x9e, 0x3c, 0xc5, 0x9f, - 0xbe, 0x7e, 0x22, 0x7e, 0x18, 0x4a, 0xf5, 0xd8, 0xe4, 0xdb, 0x28, 0x37, - 0x8e, 0x9f, 0x5d, 0x8c, 0xa3, 0x04, 0xc2, 0xea, 0x62, 0xae, 0x58, 0x37, - 0x39, 0x7c, 0xfd, 0x03, 0x8d, 0xeb, 0x04, 0x28, 0x93, 0x3d, 0x49, 0x66, - 0x9b, 0xc5, 0x0e, 0xab, 0xb6, 0xcc, 0x59, 0x1e, 0x09, 0x27, 0x27, 0x59, - 0x75, 0x0a, 0xca, 0xf8, 0x92, 0x64, 0x19, 0x16, 0x7b, 0x69, 0xb1, 0x05, - 0xe1, 0x11, 0x3b, 0x54, 0x67, 0xe2, 0x35, 0xa3, 0x85, 0x12, 0xc5, 0x69, - 0x92, 0x8e, 0xcf, 0xd2, 0x21, 0x33, 0xad, 0x8a, 0xd6, 0x89, 0x91, 0x2a, - 0x0e, 0xb1, 0x9f, 0xb4, 0x70, 0x33, 0x91, 0x47, 0xd2, 0x64, 0xf6, 0x7e, - 0x50, 0x6d, 0x6f, 0xef, 0x25, 0x6f, 0xdf, 0x1c, 0xb1, 0xa4, 0x8d, 0x93, - 0x6b, 0x68, 0xa1, 0xb2, 0xe4, 0x4d, 0xe1, 0x28, 0x50, 0x24, 0x2f, 0x7e, - 0xb8, 0xd7, 0x9d, 0x74, 0x74, 0xb7, 0x70, 0x64, 0xef, 0x7f, 0x9c, 0xeb, - 0xfc, 0xe3, 0x19, 0xab, 0x75, 0x84, 0x2c, 0xe2, 0x5e, 0x49, 0x96, 0x5b, - 0xf1, 0xa4, 0xca, 0xe7, 0x3a, 0x9a, 0x67, 0x3e, 0xbb, 0xc4, 0x50, 0xa1, - 0xa7, 0x0e, 0x7c, 0xdb, 0x49, 0x46, 0xf2, 0xed, 0x8a, 0xa2, 0xd1, 0xa9, - 0x82, 0x0e, 0x5b, 0xb4, 0x83, 0xbc, 0x2f, 0x05, 0x42, 0x43, 0x4e, 0xac, - 0x4b, 0xae, 0xd3, 0x12, 0xb2, 0x2d, 0xb4, 0x7d, 0xa6, 0x21, 0x40, 0x88, - 0x39, 0x20, 0x4d, 0x31, 0x1f, 0xd6, 0xd0, 0x5e, 0x58, 0xf4, 0x7c, 0xa8, - 0xdf, 0xf5, 0x93, 0x37, 0x18, 0xb5, 0x38, 0x9f, 0x05, 0x75, 0x0f, 0x75, - 0x46, 0xfe, 0x96, 0x1b, 0x72, 0xd5, 0x8a, 0xe9, 0x22, 0x7e, 0xfb, 0xe6, - 0xa5, 0x46, 0x48, 0xe9, 0xba, 0x92, 0x19, 0xb6, 0xca, 0x36, 0x87, 0xc5, - 0xa0, 0xda, 0xac, 0xaa, 0xb1, 0x2e, 0x42, 0xff, 0xb2, 0x9e, 0x8c, 0xf9, - 0x0e, 0x6f, 0x59, 0xbf, 0xe4, 0xb3, 0x3a, 0x19, 0x5d, 0x47, 0x87, 0x07, - 0xcf, 0x5e, 0x1c, 0xf6, 0xe0, 0xe7, 0xe9, 0x7e, 0x6f, 0xff, 0xf0, 0x74, - 0xe7, 0xd1, 0xe3, 0xde, 0xc1, 0xc1, 0xab, 0x27, 0x9f, 0x48, 0x27, 0xd2, - 0x2a, 0x89, 0xd0, 0xf3, 0xf2, 0x4a, 0x3c, 0x2b, 0x4b, 0x44, 0xe8, 0x72, - 0x1c, 0x2a, 0xc2, 0x7e, 0xeb, 0xad, 0x3a, 0x99, 0x03, 0x33, 0x23, 0x5e, - 0x90, 0x26, 0xee, 0xc2, 0x23, 0x27, 0x00, 0xab, 0x71, 0x6a, 0x68, 0x4a, - 0x0e, 0x02, 0x87, 0xe3, 0x86, 0xde, 0x64, 0x57, 0x1a, 0x7b, 0x9f, 0xbc, - 0xa4, 0x80, 0x2c, 0x36, 0xaa, 0x07, 0x20, 0x6b, 0xce, 0xb4, 0x8d, 0x73, - 0x4b, 0xcd, 0x5d, 0x11, 0x8c, 0xea, 0x94, 0x11, 0x33, 0x24, 0x61, 0xb0, - 0x84, 0x36, 0x11, 0xad, 0xa0, 0xe5, 0xde, 0xd7, 0xda, 0x28, 0xfe, 0xc6, - 0x6f, 0x65, 0x25, 0x3d, 0x9b, 0x36, 0x5d, 0x6f, 0xa4, 0xf0, 0xeb, 0x49, - 0x68, 0x3d, 0x0a, 0x2d, 0xac, 0x44, 0x1a, 0xb8, 0x4d, 0x48, 0x8b, 0x4c, - 0xca, 0x9f, 0xcc, 0x4a, 0xa4, 0xa3, 0x32, 0xfb, 0x8d, 0xa2, 0x17, 0x3e, - 0x5d, 0xd1, 0xd2, 0x96, 0x96, 0x13, 0x03, 0x1b, 0xc0, 0x1a, 0x56, 0xcb, - 0x67, 0x8a, 0xe8, 0x1b, 0xdb, 0x07, 0x3f, 0xc5, 0x6a, 0x69, 0xf0, 0xc0, - 0x2d, 0x56, 0x4b, 0xed, 0x46, 0xfc, 0xd8, 0x2d, 0x56, 0xcb, 0x45, 0x63, - 0xa3, 0xb4, 0x76, 0x3f, 0xd6, 0x46, 0x69, 0xec, 0x5f, 0x67, 0x6e, 0x6c, - 0x33, 0xf0, 0x33, 0xca, 0x56, 0xf2, 0x94, 0xff, 0xdd, 0xfc, 0xce, 0x9d, - 0x4a, 0x49, 0x36, 0x3a, 0xa4, 0x69, 0xc9, 0x73, 0x18, 0x04, 0x26, 0x75, - 0x49, 0x85, 0x09, 0xab, 0x83, 0x9d, 0xb6, 0x47, 0xb3, 0x9a, 0x79, 0x85, - 0xd5, 0x4e, 0x91, 0xea, 0x96, 0x28, 0x9c, 0xa7, 0xa5, 0x54, 0xc4, 0xd9, - 0xe8, 0x99, 0xeb, 0x49, 0xf1, 0xbf, 0x73, 0x5f, 0xab, 0xc0, 0x49, 0x8c, - 0x85, 0xd5, 0xb6, 0xe9, 0xe9, 0x1c, 0xe8, 0x68, 0x09, 0xe2, 0xa5, 0x9e, - 0x26, 0xa3, 0x16, 0xe4, 0x08, 0x78, 0xec, 0x14, 0xc5, 0x93, 0xd0, 0x4f, - 0x93, 0x83, 0xe3, 0xd7, 0xaf, 0x0f, 0x0f, 0xce, 0x9a, 0x49, 0x50, 0x86, - 0xd4, 0xed, 0x91, 0x98, 0xa5, 0x97, 0x4a, 0x4c, 0x27, 0x41, 0x8f, 0x33, - 0xef, 0x28, 0x85, 0x03, 0x91, 0x32, 0x36, 0x35, 0x18, 0xda, 0x74, 0x80, - 0x98, 0xd6, 0x4a, 0x5d, 0x4c, 0x5c, 0xc2, 0x62, 0x90, 0x16, 0x38, 0x5d, - 0xa3, 0x42, 0x91, 0x87, 0x58, 0x10, 0x07, 0xf8, 0x4a, 0x57, 0x38, 0x8c, - 0x74, 0x38, 0xdc, 0x14, 0xc4, 0x57, 0x6b, 0xda, 0xbc, 0x8c, 0x01, 0x9d, - 0x9d, 0x84, 0xff, 0x61, 0xaf, 0x18, 0xf5, 0x28, 0x34, 0x7e, 0x92, 0x96, - 0xef, 0x31, 0x83, 0xcf, 0x83, 0xa1, 0x63, 0xf1, 0x10, 0x92, 0xfa, 0xa1, - 0x49, 0xa9, 0x71, 0xc7, 0xf1, 0xf0, 0xa9, 0xd6, 0x5a, 0x92, 0xf0, 0x3f, - 0xe9, 0x9d, 0x79, 0xd1, 0xb4, 0xde, 0xb3, 0x8c, 0x32, 0x7c, 0x71, 0x9a, - 0x5d, 0x63, 0x0f, 0x0c, 0x31, 0x31, 0xc0, 0x6a, 0x8a, 0x18, 0x48, 0x0f, - 0xf3, 0xab, 0xe7, 0xe5, 0xd4, 0x81, 0xe9, 0xdf, 0x30, 0x93, 0xc3, 0x2a, - 0x40, 0x09, 0x55, 0x73, 0xa9, 0xf0, 0x46, 0x15, 0xa8, 0x73, 0x5d, 0x82, - 0x17, 0xbc, 0xd5, 0xcd, 0xa0, 0x92, 0xb8, 0x12, 0x16, 0x0a, 0xa1, 0xe4, - 0xb2, 0x15, 0xc2, 0x63, 0xa6, 0x19, 0xa7, 0xb3, 0x05, 0x2c, 0x36, 0xf4, - 0xf0, 0x57, 0xf6, 0x0e, 0x86, 0xb0, 0xcb, 0x66, 0xa4, 0xcd, 0x08, 0x97, - 0x46, 0x05, 0x85, 0x1a, 0xd3, 0x1e, 0x52, 0xea, 0xef, 0x82, 0x80, 0x7e, - 0xb1, 0x9b, 0xef, 0xc2, 0x8d, 0x44, 0xc1, 0xe2, 0x16, 0x39, 0x54, 0x9b, - 0x2f, 0x0b, 0x16, 0x05, 0x97, 0x51, 0x16, 0x4d, 0x2b, 0x0f, 0x73, 0x86, - 0x82, 0x1c, 0x91, 0x7c, 0x8a, 0xb8, 0x69, 0x64, 0xb5, 0x92, 0xb2, 0x93, - 0xdf, 0xf5, 0x12, 0x97, 0xa9, 0xa3, 0xbe, 0xac, 0x74, 0xe8, 0xd6, 0xbf, - 0x62, 0x0b, 0x7f, 0x55, 0xc3, 0x81, 0x6a, 0x1b, 0x74, 0xf0, 0xb1, 0x36, - 0xa2, 0x45, 0xd5, 0x00, 0x4c, 0x81, 0xe9, 0x81, 0x7a, 0x36, 0x29, 0x38, - 0xba, 0x69, 0x2d, 0xb6, 0xc3, 0xd6, 0xe0, 0x07, 0x71, 0x28, 0x6a, 0xac, - 0x4e, 0x79, 0x5f, 0xc0, 0xaa, 0x05, 0x7a, 0x1b, 0xcd, 0x77, 0x7e, 0xee, - 0x3d, 0xc7, 0x64, 0xb1, 0xde, 0x6b, 0x58, 0xdb, 0xbd, 0xe4, 0x3f, 0x0b, - 0xc4, 0xbd, 0xfc, 0x10, 0xb9, 0x33, 0x57, 0x48, 0x66, 0x8f, 0x5a, 0x44, - 0x7f, 0x7a, 0x6f, 0xff, 0x82, 0x08, 0x16, 0xce, 0x13, 0xe8, 0xa0, 0xd5, - 0xef, 0x6f, 0xf4, 0x05, 0x9c, 0xd7, 0xbd, 0xd5, 0x5a, 0xb9, 0xa3, 0xbc, - 0x83, 0xb4, 0x8b, 0x65, 0xbb, 0x22, 0xee, 0xfa, 0xba, 0x59, 0xfe, 0xac, - 0x4d, 0xa6, 0x70, 0xf1, 0x58, 0xec, 0x0c, 0x65, 0xb8, 0x06, 0x85, 0xa8, - 0xc4, 0x38, 0x67, 0xaa, 0xd3, 0x49, 0x4d, 0x6c, 0x2b, 0x62, 0xb0, 0x38, - 0x2d, 0xe0, 0x51, 0x0c, 0x50, 0x22, 0x2b, 0x33, 0x5b, 0xd1, 0xe0, 0xac, - 0x48, 0x70, 0x4c, 0x44, 0x58, 0xc1, 0x63, 0xc0, 0x11, 0xc5, 0x2c, 0x83, - 0x21, 0x8b, 0x66, 0xeb, 0x02, 0x96, 0x62, 0xa8, 0x2c, 0x8e, 0x9e, 0x9c, - 0x72, 0x6d, 0xc9, 0x97, 0x61, 0xa2, 0x1f, 0x55, 0x33, 0x6b, 0x79, 0xf2, - 0x65, 0x68, 0x70, 0x95, 0x5b, 0x95, 0x7b, 0x5e, 0xe1, 0xee, 0x8c, 0x5f, - 0xb0, 0x02, 0x06, 0xcb, 0x2a, 0xb4, 0xf9, 0x12, 0x06, 0xb2, 0x57, 0xfd, - 0x05, 0xaf, 0xc6, 0x76, 0x13, 0xfe, 0xa8, 0x85, 0x06, 0xd4, 0xa5, 0xd1, - 0xd4, 0x92, 0xf4, 0xf3, 0x55, 0xd5, 0xa4, 0x43, 0x2c, 0x69, 0x91, 0xc8, - 0x3b, 0x4e, 0x13, 0x72, 0xf7, 0x0a, 0x0c, 0xde, 0x10, 0x3d, 0x24, 0xa1, - 0x47, 0xd4, 0x6b, 0x0f, 0x45, 0x12, 0xa7, 0x40, 0x11, 0x23, 0x44, 0x31, - 0x19, 0x99, 0x46, 0xbf, 0x59, 0xaf, 0x9e, 0xdb, 0x15, 0xf3, 0x68, 0xf5, - 0x1e, 0x73, 0x9c, 0xc2, 0x45, 0xc4, 0x7d, 0xc9, 0x6d, 0x5b, 0xd5, 0xd9, - 0xcc, 0xa5, 0x57, 0x8a, 0x61, 0x8e, 0x4c, 0xba, 0xc2, 0xe7, 0x31, 0x14, - 0x79, 0x70, 0x99, 0x0d, 0xde, 0xbb, 0xe2, 0xba, 0x3f, 0x31, 0x2e, 0x49, - 0x04, 0xcb, 0x27, 0xc6, 0x2a, 0xe1, 0x73, 0x14, 0xa1, 0x6d, 0x7e, 0x09, - 0x6f, 0xd0, 0xe8, 0xfa, 0x02, 0x98, 0x32, 0xef, 0x2a, 0xdc, 0xd0, 0x6b, - 0x15, 0x59, 0x24, 0xbc, 0x55, 0x44, 0xd2, 0x5f, 0x73, 0x4a, 0x5a, 0x05, - 0x89, 0x12, 0x6e, 0x94, 0x3d, 0x51, 0x05, 0x42, 0xfa, 0xbc, 0x7b, 0xde, - 0xac, 0xb3, 0x24, 0xf8, 0x70, 0x30, 0x51, 0x28, 0x01, 0xa0, 0xb5, 0x9d, - 0x34, 0xd6, 0x4f, 0x60, 0x99, 0x43, 0x48, 0x8a, 0x00, 0xdc, 0xf9, 0x16, - 0xe9, 0xcc, 0xa1, 0xc5, 0x3b, 0x71, 0xa5, 0x5a, 0xd2, 0x86, 0xe1, 0x97, - 0xe2, 0xf7, 0x2a, 0x43, 0xdb, 0x94, 0x5b, 0x85, 0xd4, 0x72, 0xf1, 0x0f, - 0x12, 0xcd, 0xf1, 0xad, 0x39, 0xa5, 0x9b, 0x07, 0x31, 0xab, 0x8b, 0x39, - 0x42, 0x3f, 0xe3, 0x7a, 0x8d, 0xe6, 0x25, 0x43, 0x11, 0x8a, 0xe2, 0xba, - 0x77, 0xbb, 0xae, 0x8a, 0x2d, 0xb3, 0xa2, 0xaa, 0xbb, 0xb2, 0xff, 0xe6, - 0xf5, 0xd1, 0xeb, 0x1f, 0xf6, 0x6c, 0xbd, 0xeb, 0x36, 0xa2, 0x68, 0xd2, - 0x51, 0xb1, 0x18, 0xdf, 0x13, 0x80, 0x6a, 0x16, 0x65, 0x6b, 0xa3, 0xff, - 0xfb, 0xc2, 0xba, 0x8c, 0x5a, 0x5d, 0x85, 0x75, 0xd8, 0x08, 0x7e, 0x87, - 0xb5, 0xe4, 0x76, 0xbf, 0x25, 0x01, 0x48, 0xc1, 0x8f, 0x6f, 0x6f, 0x45, - 0xf2, 0x26, 0xc6, 0x4b, 0x15, 0x61, 0xcc, 0x94, 0xca, 0xc8, 0x46, 0x91, - 0x11, 0x8f, 0xcd, 0x7c, 0x0b, 0x44, 0x2a, 0x71, 0x13, 0xf4, 0x7a, 0xd3, - 0xc3, 0x19, 0xd9, 0x60, 0xa9, 0xd3, 0x20, 0x51, 0x5b, 0xbe, 0x33, 0x83, - 0x98, 0xb5, 0xbb, 0x03, 0x5b, 0x0c, 0x5e, 0xf1, 0xe4, 0x3e, 0xb3, 0xf9, - 0x02, 0xbb, 0xa0, 0x78, 0xc6, 0xdf, 0x63, 0xcf, 0x82, 0x46, 0xd8, 0x54, - 0xb6, 0x5c, 0x2f, 0xb5, 0x47, 0x22, 0x9b, 0xab, 0xec, 0x56, 0x0c, 0x4b, - 0xc7, 0x3b, 0x23, 0xfe, 0x65, 0xb2, 0x14, 0xf2, 0xce, 0x45, 0xab, 0x12, - 0x67, 0x3d, 0xc4, 0xaf, 0xa2, 0xdf, 0xbf, 0x9f, 0xb0, 0xf1, 0x95, 0xed, - 0xb0, 0x6c, 0xf0, 0x44, 0x5b, 0x25, 0x07, 0x50, 0x3a, 0x8c, 0x21, 0x5a, - 0x70, 0xab, 0x94, 0xe6, 0xec, 0xf7, 0x68, 0x28, 0x61, 0x14, 0x75, 0x8c, - 0x30, 0x5d, 0x6a, 0xd0, 0xb4, 0x89, 0xc5, 0x76, 0xf6, 0x95, 0xbd, 0xbd, - 0xf6, 0xfe, 0x2d, 0xf6, 0xcc, 0x7b, 0x31, 0x68, 0x5a, 0x47, 0x08, 0x38, - 0x75, 0xdf, 0xdb, 0x7f, 0xcb, 0xce, 0x5b, 0x71, 0xa1, 0x86, 0x51, 0x22, - 0xc8, 0x69, 0xeb, 0xa7, 0x27, 0xaf, 0x0f, 0x7f, 0x38, 0xde, 0x58, 0xd5, - 0x3e, 0x11, 0x2e, 0x59, 0x8e, 0x6f, 0xf3, 0xb1, 0xed, 0x51, 0x39, 0xa3, - 0xa4, 0x61, 0xa5, 0x90, 0xe0, 0xaa, 0xd7, 0xf1, 0x88, 0xac, 0xfb, 0x36, - 0xbb, 0x45, 0x0b, 0x5b, 0x75, 0xcd, 0xdf, 0x63, 0xc8, 0x5b, 0x68, 0xf5, - 0x3e, 0xcd, 0x17, 0x6a, 0xb5, 0xb8, 0x2d, 0xf8, 0x0d, 0x23, 0x1d, 0xf2, - 0x41, 0xa3, 0x92, 0x76, 0xa8, 0x2a, 0xd4, 0x8c, 0x80, 0x6b, 0x2b, 0x94, - 0x26, 0x7c, 0xb4, 0xc5, 0x96, 0x77, 0xbb, 0x2d, 0x89, 0xea, 0xd2, 0x90, - 0x86, 0x67, 0x5b, 0x44, 0xcd, 0xc7, 0x3b, 0xc1, 0x1b, 0xb1, 0x4c, 0x30, - 0xbe, 0x97, 0x22, 0x5d, 0xae, 0xa9, 0xdb, 0x96, 0xff, 0x13, 0x75, 0x16, - 0x5f, 0x60, 0xeb, 0x36, 0x73, 0x52, 0x8c, 0x70, 0x49, 0x1f, 0xb5, 0xa0, - 0x7b, 0x3a, 0x4c, 0xcf, 0x10, 0xcf, 0x62, 0xfe, 0x41, 0xfa, 0x2c, 0x12, - 0x72, 0xd9, 0x79, 0xe5, 0x2e, 0xb4, 0xe5, 0x91, 0x2b, 0xd4, 0x9b, 0xbf, - 0xa8, 0x6e, 0x65, 0x65, 0x0b, 0xbc, 0x6c, 0x01, 0x45, 0xb4, 0xdd, 0xe9, - 0xdd, 0x2c, 0x8b, 0xf4, 0xf1, 0xbc, 0x2c, 0x06, 0x14, 0xbd, 0x3f, 0x56, - 0x76, 0x87, 0x53, 0xe6, 0x5f, 0x02, 0x5b, 0xe9, 0xe2, 0x74, 0x63, 0xdc, - 0xca, 0x5b, 0x60, 0x2b, 0x35, 0x82, 0xf0, 0xff, 0xc1, 0x56, 0xfe, 0x1f, - 0x06, 0x5b, 0xe9, 0x9d, 0xf2, 0xff, 0x2a, 0x1c, 0xc4, 0xc5, 0xce, 0x56, - 0x47, 0x43, 0x5c, 0x7c, 0xf7, 0xf7, 0x63, 0x22, 0x46, 0xcd, 0x2d, 0x97, - 0x33, 0xfc, 0x35, 0x96, 0x3c, 0xc5, 0x9f, 0xde, 0xb3, 0x2f, 0xf5, 0xee, - 0xf3, 0x41, 0xc6, 0x35, 0x7f, 0x89, 0x4d, 0xf2, 0xc5, 0x9f, 0xf8, 0x42, - 0x0b, 0xc2, 0xe4, 0x1a, 0x65, 0xed, 0xe2, 0xbc, 0xed, 0x66, 0x67, 0x1f, - 0x11, 0xe6, 0xf3, 0x89, 0x91, 0x12, 0x51, 0x77, 0x9d, 0xea, 0xb2, 0x9c, - 0x9f, 0xc3, 0xc1, 0xbd, 0xe9, 0x7c, 0xa4, 0x48, 0xe0, 0x9b, 0xe9, 0xb6, - 0xf2, 0x3c, 0xbb, 0xa8, 0x9a, 0x8b, 0x5b, 0x8d, 0x7b, 0x14, 0xdc, 0x85, - 0x15, 0xe9, 0xd4, 0xbf, 0x24, 0x98, 0xcb, 0x54, 0xb0, 0x36, 0xa5, 0x34, - 0x01, 0xb2, 0xee, 0x73, 0xbe, 0x67, 0x32, 0x1a, 0xa7, 0xd7, 0xaa, 0x59, - 0xc3, 0x99, 0xdf, 0xee, 0x6f, 0xb9, 0xf4, 0x39, 0x41, 0x27, 0x10, 0xb6, - 0xff, 0xfd, 0xe1, 0xfe, 0xe9, 0x59, 0x9b, 0xb8, 0xe7, 0xa0, 0xb3, 0x4c, - 0xeb, 0xd2, 0x58, 0x2d, 0x17, 0xfb, 0x62, 0xe2, 0x3b, 0x27, 0x9c, 0x84, - 0x60, 0x09, 0xbc, 0x6a, 0x6e, 0x04, 0x5d, 0x4d, 0x6b, 0x7c, 0xe3, 0x70, - 0x79, 0xb4, 0xe8, 0x1d, 0x96, 0xfc, 0x35, 0x0a, 0x4b, 0xa3, 0x84, 0x08, - 0x43, 0x73, 0xcb, 0xc8, 0x09, 0x90, 0x9e, 0x73, 0x4c, 0x1c, 0x74, 0x0e, - 0x5a, 0xf1, 0x44, 0x74, 0xc1, 0xaa, 0xc0, 0x72, 0x39, 0x63, 0xf6, 0x5e, - 0x10, 0xc3, 0x6a, 0x94, 0x3c, 0x6f, 0xcd, 0x42, 0x43, 0xb3, 0x22, 0x67, - 0x98, 0x57, 0x18, 0xa3, 0x21, 0x98, 0x52, 0xc8, 0x70, 0x70, 0xac, 0xb8, - 0x40, 0x6a, 0xaa, 0xf4, 0x33, 0x0e, 0x15, 0x03, 0x54, 0xaa, 0x61, 0x63, - 0x22, 0xb4, 0xc8, 0x90, 0x17, 0xf8, 0xb2, 0xa6, 0xe6, 0xf5, 0x9b, 0xf6, - 0x05, 0xbf, 0x54, 0xe3, 0xa2, 0x00, 0x6e, 0x23, 0x76, 0x05, 0x7c, 0x4b, - 0xf7, 0x4a, 0x14, 0x24, 0x4b, 0x52, 0xa2, 0xb7, 0x84, 0x61, 0x8e, 0xd3, - 0x0b, 0x76, 0x9b, 0x54, 0xef, 0x59, 0x52, 0x13, 0xbe, 0x48, 0x58, 0xd5, - 0x4b, 0x5c, 0xb3, 0x0d, 0x6a, 0x49, 0x22, 0x03, 0x5c, 0xbb, 0xe2, 0xdb, - 0xf4, 0x0f, 0x2e, 0xa3, 0xbc, 0x3b, 0xe3, 0xb2, 0x3f, 0xd2, 0x9a, 0xd1, - 0x68, 0x7e, 0xa5, 0xc3, 0xd8, 0x18, 0xd1, 0xa7, 0xc9, 0x1b, 0xcd, 0x56, - 0x6e, 0x61, 0x6c, 0xf8, 0xe4, 0xbc, 0x2e, 0x7a, 0x2c, 0xc9, 0x51, 0xf4, - 0x48, 0xd3, 0xd4, 0xd9, 0xf6, 0xcc, 0xaa, 0x66, 0x4f, 0xb6, 0x47, 0x4a, - 0x01, 0x17, 0xc3, 0x67, 0x71, 0x4a, 0x32, 0x85, 0x5e, 0xf3, 0x67, 0x1a, - 0x33, 0xd4, 0x4f, 0x92, 0x64, 0xa9, 0x44, 0xde, 0x3a, 0x98, 0xd5, 0xa0, - 0x03, 0x85, 0xb1, 0xac, 0xb4, 0x6b, 0x8d, 0x1e, 0x56, 0xde, 0xba, 0xe6, - 0xc8, 0x3e, 0x62, 0xff, 0x7c, 0xd9, 0xa5, 0x2f, 0x1b, 0x96, 0xe9, 0xd6, - 0xb6, 0x97, 0xef, 0x6a, 0x3d, 0xae, 0xb6, 0x77, 0x43, 0x98, 0x8f, 0xfc, - 0x32, 0xc7, 0xb2, 0x9b, 0x2e, 0xe4, 0x87, 0xc5, 0x4a, 0xb5, 0x93, 0x88, - 0xdc, 0xc7, 0x71, 0x33, 0xf4, 0x6c, 0xa5, 0xb1, 0xee, 0x6a, 0xc2, 0x74, - 0x52, 0x06, 0x7c, 0x83, 0x86, 0x93, 0xc5, 0x64, 0x67, 0x62, 0xb4, 0x88, - 0x3d, 0xaf, 0xcc, 0x5e, 0x19, 0xd0, 0x6e, 0x1c, 0xda, 0x63, 0xb1, 0x3d, - 0xdc, 0x95, 0x3a, 0xba, 0x5c, 0x98, 0x8f, 0xc4, 0xf9, 0x84, 0x40, 0x1f, - 0x8e, 0xf4, 0x41, 0xc7, 0x24, 0x8e, 0x80, 0x58, 0xf0, 0x36, 0xa2, 0xbd, - 0xca, 0x98, 0xb9, 0x25, 0xad, 0xa5, 0xfd, 0xfb, 0x42, 0x7e, 0xda, 0x3c, - 0x78, 0x39, 0x5b, 0xd2, 0x25, 0xd7, 0x75, 0x2e, 0x38, 0x1b, 0xe3, 0x1b, - 0xd5, 0x4f, 0x17, 0x1d, 0x10, 0xa1, 0x0c, 0xb4, 0x66, 0x70, 0x6f, 0xf7, - 0xe1, 0xbf, 0x28, 0x8e, 0x11, 0x77, 0x0d, 0x00, 0xe0, 0x64, 0x38, 0x92, - 0xf8, 0x50, 0x97, 0x58, 0xe0, 0x11, 0xac, 0x43, 0x9e, 0xaf, 0x78, 0x40, - 0x31, 0x10, 0x3b, 0xa4, 0x03, 0x2f, 0x2e, 0x87, 0x6e, 0x22, 0x1d, 0x2f, - 0xe1, 0xbd, 0x41, 0x15, 0x58, 0x88, 0x65, 0x52, 0xd0, 0x0a, 0x8e, 0x75, - 0x6a, 0xa7, 0x24, 0x3e, 0xc6, 0x9f, 0x0b, 0x14, 0x64, 0xa1, 0x3b, 0x98, - 0xd3, 0xbb, 0xfd, 0xc3, 0xd3, 0x77, 0xdb, 0x3b, 0x4f, 0xde, 0xfd, 0x70, - 0xf0, 0xea, 0xdd, 0xe9, 0x8b, 0x7d, 0xc4, 0x14, 0x5f, 0x41, 0x2e, 0xe1, - 0xb3, 0x44, 0x37, 0x02, 0xe2, 0x50, 0x90, 0xa3, 0x27, 0x71, 0xe5, 0x8c, - 0x70, 0x82, 0x51, 0x5f, 0x5d, 0xfa, 0x48, 0xc2, 0xa1, 0xe2, 0x52, 0x46, - 0x7e, 0x99, 0x16, 0xcf, 0x19, 0x0a, 0x73, 0xad, 0xf1, 0x9e, 0xb8, 0x21, - 0x4d, 0x4b, 0x06, 0x3d, 0x48, 0xfc, 0xc6, 0xab, 0xbd, 0x7c, 0x30, 0x98, - 0x35, 0x1a, 0x5f, 0x8c, 0x60, 0x56, 0x61, 0x05, 0x3b, 0xa7, 0x6f, 0x4e, - 0x3a, 0x5d, 0xba, 0x25, 0xa1, 0xe5, 0x1e, 0xfc, 0x95, 0xac, 0x23, 0x9e, - 0xec, 0xa3, 0xad, 0x47, 0x0f, 0x37, 0xfa, 0x2d, 0x49, 0x57, 0xdc, 0xa0, - 0x8f, 0x60, 0x07, 0xa9, 0x24, 0x2b, 0x19, 0x17, 0xc9, 0x95, 0xfc, 0x66, - 0x72, 0xa5, 0x41, 0x69, 0xc3, 0x32, 0x88, 0x65, 0x37, 0xb0, 0x9f, 0x75, - 0x1c, 0x68, 0x19, 0x29, 0xf3, 0xcb, 0xcd, 0x92, 0xbe, 0x81, 0x95, 0xe2, - 0x80, 0x3f, 0xa9, 0xca, 0xf1, 0x62, 0x5f, 0x38, 0xb7, 0x7b, 0x89, 0x06, - 0x86, 0x46, 0xe7, 0x9a, 0x10, 0xee, 0x3e, 0x73, 0x29, 0xcb, 0x8d, 0xe9, - 0x5a, 0x30, 0xf7, 0x53, 0x4e, 0x08, 0x77, 0x74, 0x12, 0x12, 0xca, 0x25, - 0x5e, 0x32, 0x44, 0x49, 0xb5, 0x90, 0x90, 0xa6, 0xe7, 0x9a, 0x11, 0x20, - 0xf2, 0xbf, 0x2e, 0x4e, 0x39, 0x72, 0x42, 0xc4, 0x44, 0x07, 0xec, 0xd4, - 0x3b, 0x51, 0x17, 0xb6, 0x88, 0x66, 0xc8, 0xc9, 0x0a, 0xb7, 0xe2, 0x1a, - 0x91, 0x88, 0xae, 0xf4, 0x43, 0x8c, 0x7e, 0x39, 0xdd, 0x84, 0xa0, 0xf6, - 0x4f, 0xa4, 0x1b, 0x6b, 0xe0, 0x5f, 0x40, 0x37, 0xd6, 0x57, 0x6c, 0xa3, - 0xfb, 0xdd, 0xb6, 0x1f, 0x59, 0xdb, 0x45, 0x2a, 0xa1, 0x15, 0x6f, 0x6a, - 0x97, 0x56, 0x4e, 0x7c, 0x24, 0xd5, 0x9b, 0x17, 0x8c, 0x70, 0x81, 0x62, - 0xb8, 0xa2, 0x42, 0x44, 0x31, 0x72, 0xb1, 0x6a, 0x56, 0xb7, 0xcb, 0x5f, - 0x12, 0x1b, 0x6a, 0x1b, 0xd9, 0xf4, 0x13, 0x4f, 0x1d, 0x4b, 0xe8, 0xc3, - 0x96, 0x87, 0x26, 0xba, 0x9c, 0x50, 0x5c, 0xed, 0x4c, 0x22, 0x95, 0x40, - 0x2b, 0x2c, 0x15, 0x78, 0xa7, 0x94, 0x2e, 0xc2, 0x67, 0x76, 0x4c, 0x69, - 0x37, 0xd5, 0x84, 0xce, 0xcd, 0xfd, 0xed, 0xeb, 0x72, 0x0e, 0x70, 0xb5, - 0x1d, 0x6c, 0xdd, 0x18, 0xb1, 0x40, 0x72, 0xb9, 0xd3, 0xae, 0x60, 0x2d, - 0x3e, 0xf0, 0x61, 0xf5, 0x36, 0xad, 0x36, 0x9d, 0xad, 0xaf, 0x4b, 0x9c, - 0x2a, 0xb2, 0x46, 0xdc, 0x0c, 0x61, 0x40, 0x5c, 0xe6, 0x17, 0x70, 0x5f, - 0x2d, 0x3f, 0x88, 0x57, 0xdb, 0x7c, 0x04, 0x25, 0x6a, 0x64, 0xd9, 0x09, - 0x5c, 0x22, 0x84, 0x73, 0x03, 0xf7, 0x63, 0x17, 0xe7, 0xb6, 0x7e, 0xc7, - 0x1e, 0xe8, 0x5a, 0xbf, 0xed, 0xc6, 0xe6, 0xf5, 0xa7, 0xc1, 0xbe, 0x0e, - 0x3b, 0xd2, 0xe2, 0xc3, 0xb5, 0x93, 0x15, 0xe3, 0x7a, 0xb0, 0xcc, 0x1b, - 0xc2, 0x12, 0x9b, 0xe6, 0x1a, 0xb3, 0xd7, 0x90, 0x2c, 0xc6, 0xd0, 0x36, - 0x21, 0xc7, 0x18, 0x64, 0xb6, 0x93, 0xa3, 0x1e, 0x63, 0x5b, 0x49, 0x7a, - 0xbc, 0x95, 0x64, 0x26, 0x47, 0x21, 0x86, 0xe7, 0x65, 0x39, 0x3a, 0xf8, - 0xa5, 0x26, 0x94, 0xf9, 0x66, 0xa0, 0xc7, 0x36, 0xff, 0x07, 0x23, 0x6f, - 0x1b, 0xa8, 0x09, 0x16, 0x77, 0x52, 0x84, 0x42, 0xa0, 0xfe, 0x31, 0x2c, - 0xb3, 0xbb, 0xe2, 0xfd, 0x94, 0xc2, 0x9c, 0x18, 0x5c, 0x93, 0x3c, 0x9d, - 0x1e, 0xb3, 0x83, 0xd2, 0x0d, 0x03, 0x38, 0x57, 0x23, 0x63, 0xdc, 0x81, - 0x87, 0x38, 0x45, 0x7f, 0x2f, 0xe9, 0xf4, 0xde, 0x26, 0x7b, 0x1d, 0x5d, - 0x87, 0xe3, 0xa9, 0xa4, 0x82, 0x63, 0xfc, 0x3f, 0xd5, 0x45, 0xcd, 0xf9, - 0x4a, 0xa8, 0x14, 0xa6, 0xee, 0x92, 0xc0, 0x71, 0x5c, 0x55, 0xac, 0x10, - 0x2a, 0xc8, 0xa1, 0x7b, 0xce, 0x7a, 0x2a, 0x39, 0x84, 0xa4, 0x25, 0x60, - 0x14, 0xa2, 0xfa, 0xc1, 0x15, 0xfa, 0x2b, 0x9b, 0x32, 0x94, 0x0b, 0x83, - 0x69, 0x53, 0xed, 0x87, 0x41, 0x99, 0x0d, 0x19, 0x18, 0xb2, 0xf2, 0x0d, - 0x15, 0x55, 0x95, 0x9f, 0x83, 0x00, 0x74, 0xa1, 0x02, 0x72, 0x85, 0x61, - 0x1b, 0xe7, 0x9a, 0x7b, 0x45, 0x2b, 0xd5, 0x28, 0x1d, 0x2f, 0x99, 0xf8, - 0x66, 0x39, 0xa2, 0xb8, 0x48, 0xae, 0xb4, 0x83, 0xf2, 0xf9, 0x55, 0x8e, - 0x2d, 0x66, 0x12, 0xd2, 0x32, 0x29, 0x68, 0x09, 0x15, 0x92, 0x1d, 0xce, - 0x33, 0x25, 0xeb, 0x9d, 0x62, 0x8a, 0x21, 0xda, 0x5d, 0xab, 0x3c, 0x64, - 0x7b, 0x13, 0x3c, 0x70, 0xc0, 0x33, 0x2f, 0x33, 0x04, 0x0a, 0xbd, 0xca, - 0x74, 0x5f, 0xc4, 0xf0, 0x6e, 0x00, 0xcc, 0x08, 0x6c, 0x3c, 0xc9, 0xb1, - 0xba, 0x2d, 0xed, 0xe2, 0x34, 0xb3, 0x9a, 0x0e, 0xaa, 0x70, 0x53, 0x77, - 0x09, 0x9e, 0x51, 0x8e, 0xee, 0x8b, 0xeb, 0x66, 0x7b, 0x5b, 0xa2, 0x5e, - 0xe2, 0x9f, 0x53, 0x68, 0x0f, 0xac, 0x74, 0x4f, 0xdd, 0x26, 0x9f, 0xe0, - 0x4c, 0x44, 0x62, 0x8d, 0xd9, 0x26, 0xb2, 0xb2, 0xa7, 0x0e, 0x0b, 0xed, - 0xdb, 0xe5, 0xb9, 0xb8, 0xec, 0x3d, 0x14, 0x33, 0x20, 0x63, 0xde, 0x4b, - 0xa2, 0x55, 0x04, 0x03, 0x15, 0x1b, 0xf4, 0x9c, 0x3f, 0x3e, 0xaf, 0x9d, - 0x3b, 0x1e, 0xf9, 0x33, 0xbd, 0x16, 0x43, 0x3e, 0x65, 0x6a, 0xbe, 0x50, - 0xfd, 0x6c, 0x40, 0x91, 0x59, 0xf5, 0x35, 0x12, 0x96, 0x98, 0xe8, 0x15, - 0x2a, 0xbf, 0x01, 0x98, 0xe4, 0x0b, 0x21, 0x9a, 0x30, 0x29, 0xc1, 0xd2, - 0x04, 0xbc, 0x54, 0x03, 0xe1, 0xcd, 0x04, 0x84, 0x9f, 0x59, 0x8a, 0xc6, - 0x3a, 0x1b, 0x7c, 0xd1, 0x42, 0x74, 0x4e, 0x48, 0x92, 0x50, 0x18, 0xb6, - 0x24, 0xb6, 0x83, 0x36, 0x10, 0xbd, 0x2d, 0x87, 0x4a, 0x9f, 0xdd, 0x5e, - 0x16, 0x38, 0x8f, 0xcd, 0xdc, 0x0b, 0x73, 0xc7, 0x86, 0x3e, 0xd1, 0xad, - 0xd9, 0x5d, 0x44, 0xbd, 0xc9, 0x22, 0x76, 0x3f, 0xeb, 0xb6, 0xa1, 0x36, - 0x31, 0x4a, 0x90, 0x87, 0xa5, 0xe1, 0x82, 0x2c, 0x78, 0x70, 0xac, 0x65, - 0x6f, 0xb7, 0x74, 0x08, 0xfc, 0x89, 0x6f, 0x08, 0x57, 0x0c, 0xe6, 0x8a, - 0x79, 0xc2, 0xf1, 0x16, 0x38, 0x04, 0x02, 0x45, 0x98, 0x4a, 0x67, 0xf0, - 0x61, 0x2a, 0x10, 0x85, 0x93, 0x74, 0x98, 0x35, 0x43, 0x09, 0xdc, 0x68, - 0x1a, 0x31, 0xec, 0x4c, 0x32, 0x16, 0xce, 0x68, 0x51, 0x67, 0xea, 0x2a, - 0x10, 0xc4, 0x5c, 0xe2, 0x22, 0x94, 0x7f, 0xab, 0x56, 0x98, 0x50, 0x70, - 0x41, 0x43, 0x0a, 0x88, 0x64, 0x95, 0xd0, 0x69, 0x42, 0x18, 0x14, 0x2f, - 0x34, 0x15, 0x4f, 0x4d, 0x00, 0xb1, 0x0a, 0x23, 0x6e, 0x0e, 0x96, 0x64, - 0x44, 0xf8, 0x78, 0x9c, 0x89, 0x81, 0xf5, 0x68, 0xa0, 0xb3, 0xd8, 0xd2, - 0xd5, 0xdc, 0xc1, 0x80, 0x66, 0x12, 0x60, 0x2f, 0x45, 0xa7, 0x93, 0xf0, - 0xb0, 0x90, 0x33, 0xd2, 0xbd, 0x76, 0xa1, 0x39, 0xd9, 0x3d, 0x0b, 0x67, - 0x5e, 0x6a, 0xee, 0x93, 0x05, 0xbe, 0xbf, 0xc8, 0x54, 0x6e, 0x70, 0x05, - 0xd2, 0x95, 0x9e, 0xef, 0x23, 0x96, 0x58, 0x5c, 0xba, 0x21, 0x90, 0x6c, - 0xfd, 0x14, 0xa1, 0xaa, 0x4e, 0x0f, 0x4e, 0x36, 0x92, 0x93, 0xe0, 0x52, - 0xd4, 0x88, 0xb2, 0x3e, 0xe1, 0xb3, 0x79, 0x28, 0x30, 0xc9, 0xb7, 0x92, - 0x18, 0xb3, 0x45, 0x37, 0x2c, 0xd1, 0xb3, 0x65, 0x3e, 0x50, 0xe4, 0xba, - 0xcf, 0x5a, 0x88, 0xb8, 0x4b, 0x1a, 0xa3, 0x42, 0x89, 0x0b, 0xd3, 0xfb, - 0x20, 0x25, 0x44, 0x4a, 0xf1, 0xb8, 0xdb, 0x82, 0xa0, 0xb0, 0x0b, 0xa9, - 0x62, 0x84, 0x6c, 0xbb, 0x25, 0xc8, 0x10, 0x7f, 0xbf, 0xc8, 0xa6, 0x78, - 0xc9, 0x90, 0xc5, 0xd7, 0x98, 0xae, 0x90, 0x3a, 0x55, 0xc4, 0xa8, 0x33, - 0x25, 0x78, 0xd4, 0xe6, 0x42, 0xe7, 0x32, 0xa8, 0x9c, 0xd0, 0x45, 0xe5, - 0x64, 0x58, 0x88, 0xaf, 0xab, 0xac, 0x01, 0xb7, 0x1d, 0xa6, 0x7a, 0x29, - 0x5c, 0x01, 0x5e, 0x83, 0x33, 0x0c, 0xae, 0xc6, 0x87, 0xab, 0xea, 0x72, - 0x07, 0x78, 0xdc, 0x4e, 0xff, 0x49, 0x10, 0x87, 0x85, 0xdb, 0xa2, 0x3c, - 0x51, 0x83, 0xe4, 0x34, 0xd2, 0xec, 0x92, 0xa8, 0x15, 0x83, 0x24, 0xe0, - 0x5b, 0xd4, 0x3c, 0xa2, 0xb7, 0xc5, 0x4f, 0xfd, 0x8e, 0x72, 0xae, 0xdc, - 0x3e, 0xed, 0x19, 0xfc, 0x9e, 0x54, 0x4b, 0xeb, 0xb6, 0x46, 0x65, 0x5a, - 0xc3, 0x55, 0xf9, 0x67, 0x64, 0x83, 0x7f, 0x9b, 0xe3, 0x5a, 0x3e, 0x15, - 0x29, 0x40, 0xa9, 0x8c, 0x88, 0xec, 0x39, 0x86, 0xad, 0xc3, 0xcb, 0x53, - 0x42, 0xb2, 0x4e, 0xcb, 0xf3, 0x1c, 0xd6, 0xb6, 0xbc, 0x09, 0xb9, 0x00, - 0x1a, 0xf8, 0xa9, 0x6c, 0x04, 0xdf, 0x22, 0x17, 0x3a, 0xfc, 0xa2, 0xc2, - 0x02, 0x7a, 0xa1, 0xfa, 0xc9, 0x9f, 0xa9, 0x17, 0x79, 0x4f, 0xd1, 0x35, - 0x49, 0x8e, 0xfc, 0xfe, 0xf0, 0xf9, 0xf1, 0x9b, 0xc3, 0x46, 0x48, 0xa9, - 0x8f, 0x4c, 0x96, 0x11, 0xfd, 0x86, 0xf6, 0x5d, 0x29, 0x30, 0xc4, 0xa9, - 0x16, 0x39, 0x0a, 0x6e, 0x70, 0xfa, 0x7f, 0x7a, 0x66, 0x03, 0x22, 0xe8, - 0xba, 0x29, 0x0f, 0xc4, 0x5a, 0xeb, 0xd2, 0x38, 0xcf, 0x35, 0xb3, 0x08, - 0xfd, 0x44, 0x68, 0xf5, 0x2a, 0x88, 0x7f, 0x27, 0x61, 0x50, 0x94, 0x17, - 0xc2, 0xf9, 0x37, 0xd2, 0x51, 0x8a, 0x48, 0x79, 0x28, 0x54, 0x52, 0x7d, - 0x22, 0x6b, 0x2f, 0xd4, 0x0a, 0xcf, 0x3f, 0x70, 0xd5, 0x55, 0x89, 0x0b, - 0x1a, 0x22, 0x5c, 0xc5, 0x5a, 0xcf, 0xe2, 0x0c, 0x68, 0x19, 0xf1, 0xe2, - 0xdf, 0x48, 0xac, 0xbf, 0xb0, 0x06, 0x9a, 0xb2, 0x22, 0x9d, 0x31, 0x89, - 0x22, 0x7f, 0x62, 0x5f, 0xdc, 0xd0, 0x91, 0x07, 0x0a, 0xc5, 0x74, 0x52, - 0x1c, 0x04, 0x53, 0xf2, 0x9b, 0xe0, 0x73, 0x90, 0x14, 0x19, 0x22, 0x4b, - 0x7d, 0x64, 0xae, 0x74, 0xb6, 0x5e, 0x6d, 0x2c, 0x0c, 0x3a, 0xec, 0xa2, - 0x65, 0x59, 0xae, 0xfd, 0x71, 0xcd, 0xc2, 0xc0, 0x55, 0x6a, 0x76, 0x90, - 0x8e, 0x6c, 0x0e, 0x4a, 0xfd, 0x8d, 0x82, 0x88, 0x0e, 0x22, 0x6f, 0x13, - 0x9d, 0xeb, 0xc3, 0xba, 0x00, 0x6d, 0x69, 0x60, 0xbe, 0x2c, 0x38, 0x2f, - 0x45, 0x7f, 0x09, 0x90, 0x70, 0x55, 0x17, 0x08, 0x2b, 0x5f, 0x4b, 0xb9, - 0xa1, 0x51, 0x9a, 0x8f, 0x29, 0xa2, 0xd8, 0x96, 0x92, 0x56, 0x4c, 0x03, - 0xba, 0x93, 0xcc, 0x62, 0xb9, 0xb4, 0xda, 0x87, 0xce, 0x10, 0xdf, 0xc4, - 0xe3, 0xd6, 0x36, 0x7b, 0x99, 0x3c, 0x3a, 0x7d, 0x61, 0x17, 0xf2, 0xea, - 0x3d, 0x6c, 0xdb, 0x7f, 0x6c, 0xf4, 0x5d, 0x31, 0xc8, 0xeb, 0x1c, 0x2b, - 0xd6, 0x4b, 0x9b, 0xe2, 0x56, 0x95, 0x2c, 0xa8, 0x44, 0x07, 0x45, 0x92, - 0x7d, 0x31, 0x35, 0x60, 0x75, 0x9b, 0x5b, 0xd7, 0xa1, 0x14, 0xc2, 0x38, - 0xcb, 0x2c, 0xa0, 0x54, 0x92, 0xd8, 0x78, 0xce, 0xe1, 0x9e, 0x7e, 0xbd, - 0xe6, 0xec, 0x93, 0xc7, 0x9d, 0xa9, 0x6e, 0xa6, 0x35, 0x72, 0x33, 0xe1, - 0xb8, 0x83, 0xa2, 0xa4, 0x7b, 0x9c, 0xe9, 0xdb, 0x9d, 0xa6, 0x8a, 0x0b, - 0x84, 0x25, 0x5f, 0x3d, 0xfa, 0x4a, 0x9d, 0x18, 0x23, 0xca, 0xdd, 0x42, - 0xca, 0xc7, 0x87, 0x79, 0xd8, 0x15, 0x85, 0xd8, 0xe8, 0x38, 0xc5, 0x31, - 0xa3, 0x8d, 0xe0, 0x3e, 0x62, 0xa4, 0x4c, 0x46, 0x50, 0x29, 0xca, 0x2a, - 0x4f, 0xdd, 0xdb, 0x96, 0xb6, 0x8d, 0x9f, 0x51, 0xda, 0xbd, 0xaa, 0xa7, - 0x2a, 0x38, 0x62, 0xac, 0xe3, 0x94, 0x52, 0xee, 0x70, 0x3d, 0x9e, 0x23, - 0xf6, 0x33, 0xef, 0x12, 0xf9, 0xad, 0x61, 0xf9, 0xf1, 0x26, 0x09, 0xdc, - 0xe1, 0x6f, 0x31, 0x57, 0x60, 0xce, 0xaa, 0x14, 0xad, 0x01, 0x28, 0x74, - 0xc0, 0x44, 0x60, 0x51, 0x76, 0x92, 0x3c, 0x97, 0x0b, 0xaf, 0x0a, 0x05, - 0xeb, 0xe0, 0x38, 0x51, 0x7b, 0x14, 0x25, 0x04, 0x9a, 0x2e, 0x17, 0xfd, - 0xc0, 0x37, 0x09, 0x1e, 0x32, 0xe1, 0x72, 0x2d, 0x15, 0xe9, 0x48, 0x82, - 0x8b, 0xe9, 0x80, 0x31, 0x65, 0xc3, 0x9f, 0x5b, 0x4d, 0x34, 0x2d, 0x0c, - 0x2e, 0x3e, 0x27, 0x44, 0x9a, 0x0e, 0x8e, 0x47, 0x5a, 0x81, 0x78, 0xf4, - 0xea, 0x23, 0x4a, 0x91, 0xb7, 0xa3, 0xda, 0xc6, 0xb7, 0x29, 0x23, 0xff, - 0x67, 0xf2, 0xb1, 0x12, 0x5d, 0x95, 0x69, 0xf8, 0x0d, 0x31, 0xfe, 0x94, - 0x98, 0x0c, 0xdd, 0x0a, 0x4a, 0x40, 0x7c, 0x92, 0x71, 0x8a, 0xa0, 0x76, - 0x3d, 0x38, 0xbf, 0x09, 0x1f, 0x12, 0xfd, 0x4c, 0x87, 0x22, 0x46, 0x52, - 0x47, 0xd9, 0x07, 0x12, 0x8e, 0x7c, 0x65, 0x01, 0x1a, 0x2f, 0x45, 0xf9, - 0x40, 0x8b, 0x54, 0xf4, 0xa0, 0xce, 0x14, 0xaa, 0x96, 0xaa, 0x08, 0x66, - 0xca, 0x33, 0x70, 0x7f, 0xde, 0x81, 0xaa, 0x8b, 0x4f, 0xac, 0xef, 0x22, - 0xae, 0x15, 0x72, 0xd0, 0x19, 0x25, 0xfb, 0x31, 0xd2, 0x3b, 0x45, 0xa4, - 0x3e, 0x70, 0x9d, 0x18, 0xf6, 0xfb, 0xba, 0x77, 0x3c, 0x22, 0xbe, 0x9a, - 0xca, 0x0e, 0x97, 0x17, 0xe5, 0x2c, 0xb9, 0x00, 0x59, 0x71, 0x16, 0xad, - 0x02, 0x7f, 0x1e, 0xad, 0x02, 0xc7, 0xcb, 0xd2, 0x93, 0x47, 0xcf, 0x8c, - 0x2c, 0x69, 0xa6, 0x34, 0x7b, 0x72, 0x41, 0x71, 0xfd, 0x03, 0x3f, 0x7d, - 0x13, 0x61, 0xed, 0x55, 0xa7, 0xd2, 0xc9, 0x72, 0xf1, 0x57, 0xb6, 0x60, - 0x32, 0x06, 0xfe, 0x54, 0x9b, 0x21, 0x32, 0x1e, 0xc2, 0x9b, 0x93, 0x94, - 0xa9, 0xf4, 0x02, 0x4e, 0xb7, 0xb6, 0x69, 0xa2, 0xd0, 0xe5, 0xa4, 0x18, - 0x32, 0x3e, 0x68, 0x3c, 0x1b, 0xfc, 0x58, 0x67, 0x23, 0x55, 0x4c, 0xaa, - 0x30, 0x7e, 0x7a, 0xe1, 0x1c, 0x63, 0xc1, 0x94, 0x2b, 0x38, 0xd3, 0xfb, - 0x03, 0xce, 0x12, 0xc4, 0x76, 0xe8, 0x39, 0x3f, 0xa0, 0x69, 0x52, 0x0c, - 0x6a, 0x37, 0x1e, 0x7a, 0x80, 0xf9, 0x66, 0x18, 0x12, 0xc6, 0x87, 0x90, - 0xfa, 0x1c, 0x0f, 0x09, 0x3f, 0x5e, 0x20, 0x33, 0xf8, 0x90, 0x59, 0x6e, - 0xfb, 0xda, 0x72, 0x13, 0x0f, 0x1e, 0x34, 0xd6, 0x96, 0x5a, 0x8f, 0x56, - 0xf6, 0x3c, 0x58, 0xbf, 0x1a, 0x74, 0x88, 0x1f, 0xb9, 0x16, 0x5a, 0x97, - 0x55, 0xda, 0xd3, 0x29, 0x8c, 0x11, 0x6d, 0x1b, 0x33, 0x57, 0xde, 0xd1, - 0x88, 0xb8, 0x14, 0xf7, 0x3b, 0x3f, 0x9b, 0xf1, 0x94, 0x75, 0x9c, 0xea, - 0x66, 0x82, 0x92, 0x96, 0x67, 0x79, 0x03, 0x42, 0x12, 0xa7, 0x10, 0x43, - 0xaa, 0x7f, 0x04, 0xe2, 0x1f, 0x3f, 0x62, 0x29, 0x3d, 0x0f, 0x5c, 0x83, - 0x89, 0x15, 0xea, 0x9b, 0x15, 0xf9, 0x54, 0x43, 0x78, 0x88, 0xa3, 0xb8, - 0x11, 0xb8, 0xe2, 0x7b, 0xcc, 0x55, 0xde, 0x23, 0x4e, 0xbb, 0xdd, 0x74, - 0xef, 0x70, 0xcd, 0x74, 0x68, 0xf2, 0x65, 0xb8, 0x44, 0x65, 0x44, 0x9a, - 0x1d, 0xe3, 0x10, 0xaf, 0x64, 0xad, 0x39, 0x54, 0x81, 0x87, 0x16, 0xb7, - 0x19, 0x28, 0x54, 0xfa, 0x6d, 0x67, 0x21, 0x93, 0xdb, 0x58, 0x48, 0x54, - 0x5f, 0xc6, 0x33, 0x12, 0xdd, 0xdb, 0xc5, 0x0d, 0x4f, 0xda, 0x58, 0x89, - 0xe7, 0x25, 0x96, 0x77, 0x9a, 0x62, 0x06, 0xe2, 0x03, 0x66, 0x27, 0xd0, - 0x6c, 0x83, 0x97, 0x18, 0x2b, 0x69, 0xe5, 0x24, 0xc6, 0x48, 0x94, 0x09, - 0x7d, 0x0c, 0x1f, 0x99, 0x51, 0xed, 0x76, 0x9a, 0x3d, 0xfc, 0x6a, 0x73, - 0xd7, 0xdb, 0x97, 0x11, 0x7c, 0xcf, 0xab, 0x62, 0x3c, 0xaf, 0x19, 0x16, - 0x8d, 0x63, 0xe8, 0xec, 0x12, 0x66, 0x97, 0x3b, 0xb4, 0xa0, 0x02, 0x94, - 0x2d, 0xbc, 0xae, 0x75, 0xc9, 0x99, 0x38, 0x92, 0x42, 0xc5, 0x24, 0xa3, - 0x5d, 0xca, 0x77, 0xa1, 0x57, 0xba, 0x71, 0x9c, 0xa4, 0xe5, 0x31, 0x31, - 0x17, 0xb8, 0x95, 0x34, 0xa9, 0x27, 0xc2, 0x18, 0xd6, 0x30, 0x43, 0x79, - 0x49, 0xa8, 0x91, 0x40, 0xca, 0xe2, 0xad, 0xd1, 0x41, 0xd8, 0x61, 0xb2, - 0xa1, 0x4e, 0x22, 0x72, 0x80, 0x3f, 0xc3, 0xc8, 0xb8, 0xd8, 0x98, 0xed, - 0xec, 0xc2, 0x89, 0x8d, 0x6e, 0x0e, 0x6b, 0x2f, 0x22, 0xef, 0xd0, 0x2e, - 0x7e, 0xdc, 0xd6, 0x74, 0x98, 0x2b, 0xd6, 0x2b, 0xba, 0x89, 0x7b, 0x69, - 0x52, 0xb6, 0xf6, 0xd6, 0x75, 0xc8, 0xa2, 0x64, 0x29, 0x43, 0x7d, 0xd2, - 0x96, 0x5f, 0x4f, 0xf6, 0x2d, 0x8c, 0x00, 0x95, 0x97, 0xb1, 0x9d, 0x49, - 0x55, 0x58, 0xe4, 0x9a, 0x8b, 0x92, 0x96, 0x2d, 0x67, 0x39, 0xbd, 0x25, - 0x5b, 0xb9, 0xa1, 0x44, 0x71, 0x6b, 0x9d, 0x67, 0x87, 0x2f, 0x0f, 0x69, - 0x91, 0x3a, 0xc9, 0xa2, 0x16, 0x35, 0x2a, 0x8a, 0x45, 0x45, 0x4a, 0x8c, - 0x30, 0xa6, 0xaa, 0xe3, 0x5c, 0x8b, 0x49, 0x6f, 0x01, 0xf1, 0xe4, 0x19, - 0xd6, 0xe7, 0x18, 0x50, 0x10, 0xb2, 0x86, 0x49, 0x34, 0x8b, 0xbd, 0x0b, - 0x6a, 0x7d, 0x04, 0x9b, 0xff, 0x90, 0x00, 0x49, 0x93, 0x93, 0x32, 0xb7, - 0xc2, 0x74, 0x05, 0xeb, 0xa0, 0xb9, 0xd4, 0x8f, 0xbb, 0x4c, 0xb9, 0xc0, - 0x90, 0x45, 0xdd, 0xb1, 0xa0, 0x35, 0x6a, 0xe0, 0xa2, 0x16, 0xe3, 0xa1, - 0x45, 0xe1, 0x59, 0xf2, 0xbf, 0x2a, 0xaa, 0x5f, 0x2c, 0x7a, 0x36, 0xc2, - 0x29, 0xc2, 0xc2, 0x23, 0x0e, 0xa9, 0x0e, 0x8f, 0x0f, 0x4f, 0x52, 0x42, - 0x80, 0x89, 0x0d, 0x92, 0x7d, 0xda, 0x6a, 0xc4, 0x86, 0x24, 0x75, 0xf6, - 0x30, 0x18, 0x1a, 0xb8, 0xbc, 0x28, 0xb8, 0x65, 0x8a, 0x00, 0x15, 0x47, - 0x5a, 0x57, 0x91, 0xdb, 0xd6, 0xaf, 0x67, 0x14, 0xba, 0xdf, 0xe6, 0xb1, - 0xfd, 0x3d, 0x91, 0xfb, 0xbe, 0x23, 0x8c, 0x5f, 0xcd, 0x41, 0x87, 0x5b, - 0xc9, 0x54, 0x93, 0x5d, 0x0c, 0x7b, 0x62, 0x30, 0xa1, 0x21, 0x97, 0x5d, - 0x6e, 0x0d, 0xf8, 0xdd, 0x53, 0xfa, 0xc7, 0xa3, 0x6b, 0xb0, 0x18, 0x4e, - 0x72, 0x63, 0xf2, 0xfc, 0xe8, 0xe5, 0xe1, 0x06, 0x7a, 0x49, 0xd9, 0x96, - 0x4f, 0x3e, 0xa0, 0xf3, 0x9b, 0x9a, 0x97, 0x09, 0xb9, 0xe5, 0x7a, 0xde, - 0x47, 0x53, 0x8e, 0x40, 0x36, 0x80, 0xa4, 0x2a, 0x42, 0x7d, 0x31, 0x20, - 0xa7, 0xc7, 0x06, 0x5b, 0x58, 0xd4, 0xb7, 0xb7, 0xb9, 0xdd, 0xdf, 0xee, - 0x46, 0xba, 0xb7, 0x45, 0xab, 0x93, 0xbb, 0x81, 0x20, 0xf8, 0xb8, 0x57, - 0x91, 0x72, 0xdf, 0x70, 0xac, 0xa7, 0x9c, 0xa1, 0x70, 0x8c, 0xe9, 0xe8, - 0x04, 0xfd, 0xec, 0x3a, 0xbd, 0x31, 0x99, 0x7f, 0xab, 0xf7, 0xf0, 0xab, - 0xaf, 0xf0, 0x38, 0x06, 0xd3, 0x31, 0xf3, 0x15, 0xd4, 0xcc, 0x1e, 0x6d, - 0x6d, 0xd1, 0x04, 0x2a, 0x79, 0x18, 0xfe, 0xee, 0x7d, 0xd5, 0xf6, 0x78, - 0x95, 0xc1, 0x76, 0x0f, 0x17, 0x9e, 0xef, 0xc1, 0x07, 0x8b, 0x0f, 0xd3, - 0x9e, 0x36, 0x1f, 0xfd, 0x0a, 0xdb, 0x5e, 0x7c, 0x96, 0x1e, 0xe1, 0x65, - 0x29, 0x46, 0x23, 0x24, 0x04, 0x7c, 0x50, 0xeb, 0x2e, 0x5e, 0xa7, 0xe5, - 0xd0, 0xe6, 0xb1, 0xd5, 0xed, 0x6d, 0x2f, 0x9b, 0x08, 0xb1, 0x0c, 0xec, - 0x96, 0xb6, 0x03, 0x8f, 0x19, 0xe8, 0x82, 0x9c, 0xbf, 0x2f, 0xef, 0x6f, - 0x43, 0xf7, 0xdb, 0x5f, 0x7d, 0xd5, 0xc5, 0x61, 0x3c, 0x5a, 0x98, 0xe2, - 0x75, 0x11, 0x6a, 0xb6, 0xd1, 0xa3, 0x6e, 0x5b, 0x2b, 0x68, 0x4a, 0xb1, - 0x00, 0x50, 0xc5, 0x4c, 0xbe, 0x49, 0x92, 0xd7, 0xc7, 0x67, 0x87, 0x28, - 0xa9, 0x88, 0xe9, 0xb6, 0xca, 0xc4, 0x26, 0xe1, 0x34, 0x4d, 0x2c, 0xf0, - 0x83, 0x81, 0x62, 0xa2, 0xa3, 0xb3, 0x39, 0x33, 0x2d, 0xeb, 0x60, 0x5d, - 0xed, 0xe2, 0xfd, 0x66, 0x65, 0x6e, 0xe4, 0x72, 0x24, 0x00, 0xe2, 0xaa, - 0x47, 0x41, 0x57, 0xc8, 0x9d, 0x91, 0xd8, 0xff, 0x0d, 0x73, 0x74, 0x4a, - 0x36, 0xb9, 0x51, 0x01, 0xab, 0x42, 0xd5, 0x5b, 0x1c, 0x03, 0x19, 0x0d, - 0x0a, 0x04, 0xfe, 0x33, 0x8b, 0x5c, 0x00, 0x5b, 0x57, 0x24, 0x3f, 0xfd, - 0x28, 0x97, 0xf0, 0x63, 0x12, 0xd8, 0x85, 0xf5, 0xa3, 0x92, 0xca, 0x02, - 0xea, 0x83, 0x63, 0x64, 0x50, 0xc3, 0xfc, 0x02, 0x0d, 0xaa, 0xbe, 0x6a, - 0xe7, 0x3a, 0xd0, 0xc5, 0x06, 0x5b, 0x7f, 0x24, 0x42, 0xcf, 0x2a, 0xde, - 0xad, 0x55, 0xc0, 0xf7, 0xeb, 0x35, 0x89, 0x9f, 0x7a, 0xb0, 0x86, 0xca, - 0xff, 0x1a, 0x6c, 0x4b, 0x36, 0x1e, 0x9a, 0xfc, 0xcc, 0xcf, 0xf4, 0xf8, - 0x2b, 0x3e, 0x2b, 0xa4, 0x21, 0x7f, 0x20, 0x8b, 0x5b, 0xca, 0x75, 0xd5, - 0xa9, 0x5b, 0x1c, 0x8e, 0xf6, 0xcb, 0x06, 0x45, 0xce, 0xc8, 0x53, 0x3c, - 0x31, 0x7a, 0xb9, 0xeb, 0x17, 0x7a, 0xad, 0x31, 0x5f, 0x68, 0x61, 0x3e, - 0x75, 0x6e, 0x1e, 0xc6, 0xbc, 0xa3, 0x8c, 0x88, 0x69, 0xfc, 0x1a, 0x90, - 0xf4, 0x28, 0xbf, 0x98, 0x97, 0x26, 0x3b, 0x3e, 0x78, 0x85, 0x76, 0x0e, - 0x3d, 0x9a, 0x6a, 0x04, 0xab, 0x0c, 0x5d, 0x85, 0xd1, 0x4f, 0x23, 0xdc, - 0x68, 0xa9, 0x68, 0x34, 0x24, 0xcb, 0xa8, 0x52, 0x84, 0x21, 0xd4, 0xa8, - 0x19, 0x16, 0xb9, 0xea, 0x45, 0x46, 0x60, 0x35, 0x3a, 0x01, 0xd1, 0xae, - 0xd9, 0x5b, 0x73, 0xa1, 0x0a, 0x15, 0x51, 0x44, 0x81, 0xd5, 0x45, 0x85, - 0x65, 0xd0, 0xb0, 0x88, 0xf9, 0x30, 0xc4, 0x1e, 0xfd, 0xaa, 0xec, 0x66, - 0x08, 0xea, 0xc1, 0xb8, 0x48, 0x87, 0x95, 0x05, 0xd9, 0x1a, 0xfc, 0x01, - 0x57, 0x3c, 0xe4, 0xd2, 0xaf, 0xbc, 0x2b, 0x61, 0x03, 0x64, 0xed, 0x61, - 0x57, 0x7d, 0x11, 0x4a, 0x26, 0x54, 0x34, 0x31, 0x04, 0xc0, 0x42, 0xe1, - 0x29, 0xb8, 0xa6, 0x85, 0x54, 0x4a, 0xec, 0x13, 0xc3, 0xc2, 0x1b, 0xaa, - 0x01, 0x26, 0x98, 0x7d, 0xa8, 0xe1, 0xcf, 0x8c, 0xaa, 0x44, 0xd9, 0x35, - 0x7e, 0x7a, 0xf4, 0x5f, 0x87, 0x51, 0x95, 0x3a, 0x1e, 0xf9, 0x67, 0xa8, - 0x52, 0xc7, 0x0d, 0xef, 0xec, 0xf4, 0x1e, 0x3e, 0x5c, 0x11, 0xfa, 0x4a, - 0xcc, 0x4f, 0xbd, 0x54, 0xa3, 0x6a, 0xd3, 0x19, 0x4e, 0xc8, 0x09, 0x06, - 0x68, 0x5f, 0x9d, 0xc0, 0x42, 0xa9, 0xdf, 0x06, 0x3f, 0x69, 0x89, 0x29, - 0x80, 0x47, 0xf2, 0xc9, 0x7c, 0x12, 0xcc, 0x77, 0x23, 0x7a, 0x61, 0x3a, - 0xb8, 0x61, 0x17, 0x3e, 0x83, 0xd8, 0xaa, 0xff, 0x1e, 0x97, 0xae, 0x87, - 0x04, 0xcd, 0x0d, 0x05, 0xae, 0x1d, 0x4a, 0xdc, 0xe2, 0x5e, 0x91, 0x51, - 0x8e, 0xef, 0xca, 0x64, 0x3e, 0x85, 0xf3, 0xb8, 0x8e, 0x39, 0x02, 0x2c, - 0x29, 0xd1, 0x81, 0x1d, 0x1a, 0xc2, 0x8e, 0x48, 0x85, 0x30, 0x38, 0x84, - 0x42, 0xf7, 0x15, 0xe4, 0xe2, 0xec, 0x21, 0x69, 0x97, 0x10, 0xe9, 0xd1, - 0x8d, 0x6c, 0x1d, 0xa6, 0x64, 0x0f, 0xd3, 0x86, 0xe0, 0x2f, 0xf1, 0xa4, - 0x67, 0x6e, 0xeb, 0xe4, 0x1c, 0xea, 0x6e, 0xbd, 0x7d, 0xf3, 0x52, 0x5c, - 0x9f, 0xa9, 0xb3, 0x5b, 0x22, 0xfe, 0xf5, 0x38, 0x23, 0x65, 0x6a, 0x44, - 0x66, 0x39, 0x06, 0xda, 0x0d, 0xf6, 0x50, 0x5a, 0x0a, 0x44, 0x6c, 0xa3, - 0xd4, 0x45, 0xf5, 0x58, 0xa1, 0xa6, 0x0d, 0x93, 0xac, 0xf3, 0xb1, 0xa0, - 0xab, 0x47, 0xa3, 0x23, 0x87, 0x13, 0x0e, 0x9d, 0xc5, 0x13, 0x35, 0x1c, - 0xe5, 0x0c, 0xfd, 0x2d, 0xcc, 0x8d, 0x16, 0x82, 0xd6, 0x04, 0x73, 0x4d, - 0x9a, 0x98, 0x18, 0x4d, 0xdc, 0x14, 0x57, 0xe8, 0x02, 0x2d, 0xeb, 0xe8, - 0xb0, 0xc8, 0xc6, 0x4d, 0x3a, 0x3b, 0x73, 0xd0, 0x59, 0x44, 0x0b, 0x9e, - 0x6a, 0xa1, 0xc1, 0xce, 0xeb, 0xcd, 0xb7, 0x1d, 0x09, 0x80, 0x78, 0x2d, - 0xea, 0xbf, 0xa9, 0xcc, 0xbc, 0xad, 0x21, 0xd5, 0xe2, 0x2d, 0xb3, 0xe2, - 0xd4, 0xed, 0x28, 0x62, 0x42, 0x84, 0x88, 0x78, 0xfc, 0x84, 0x51, 0x91, - 0x80, 0x5b, 0xc2, 0x19, 0x5d, 0xe7, 0x2b, 0x77, 0x03, 0x56, 0x69, 0x6d, - 0xb2, 0x26, 0x02, 0x09, 0xf0, 0x78, 0x50, 0x98, 0xe0, 0xb3, 0xb5, 0xcb, - 0xb5, 0x64, 0x1d, 0xf6, 0xb9, 0xe4, 0x8a, 0x2a, 0xc9, 0xda, 0x10, 0x5e, - 0xd9, 0x5c, 0x1f, 0xa6, 0x5c, 0xe8, 0x86, 0x05, 0x82, 0x9d, 0x87, 0x98, - 0x73, 0x3c, 0x2f, 0xa9, 0xed, 0x0d, 0x0f, 0xa0, 0x6e, 0xc8, 0x9a, 0x3a, - 0x96, 0xae, 0x54, 0x74, 0x4d, 0x3a, 0x38, 0x27, 0x37, 0xd1, 0x2e, 0x19, - 0x94, 0x8d, 0x46, 0x43, 0xed, 0x5c, 0xd1, 0xf3, 0xe0, 0x63, 0xec, 0xc2, - 0x11, 0x8a, 0xc6, 0x98, 0xd6, 0x28, 0xc0, 0x5a, 0xb9, 0xbd, 0xed, 0xad, - 0x80, 0xe0, 0x85, 0x2f, 0xf1, 0x4c, 0xba, 0x96, 0x21, 0xc7, 0x60, 0xb7, - 0xb5, 0x01, 0x5d, 0x19, 0x91, 0xea, 0x0e, 0x30, 0x79, 0x24, 0x8f, 0x45, - 0x14, 0xa9, 0x84, 0x19, 0x67, 0xe3, 0x74, 0x46, 0xaa, 0x44, 0x8e, 0xae, - 0x79, 0x71, 0x97, 0x67, 0x57, 0x79, 0x31, 0xaf, 0xe2, 0xb2, 0xd0, 0x40, - 0x66, 0x46, 0x46, 0x71, 0xa2, 0xc2, 0x68, 0x3e, 0x95, 0x00, 0x77, 0x29, - 0xfc, 0x38, 0xc9, 0xc7, 0xe3, 0x5c, 0x24, 0x1e, 0x42, 0xe9, 0x00, 0x2d, - 0x95, 0xc3, 0xa4, 0x2d, 0xc2, 0xc0, 0x28, 0x59, 0xc3, 0x4f, 0xf4, 0xc0, - 0x63, 0x83, 0x24, 0xce, 0x4e, 0xc4, 0xb8, 0x8f, 0x44, 0x01, 0x02, 0xc5, - 0x16, 0x1f, 0x67, 0x6e, 0x55, 0xb1, 0x7c, 0x85, 0xfb, 0x83, 0xf4, 0xaa, - 0x22, 0xfe, 0x7c, 0x0a, 0xfd, 0x81, 0x74, 0x39, 0x70, 0xa3, 0x24, 0xf7, - 0x36, 0xc6, 0x8f, 0x50, 0xc0, 0x8e, 0x6d, 0x40, 0x57, 0xaf, 0x1e, 0xf3, - 0x77, 0xd2, 0x33, 0x5d, 0xb9, 0xe3, 0x44, 0x96, 0xe1, 0x17, 0x75, 0xd7, - 0xb1, 0x52, 0xf8, 0xb8, 0xb8, 0xe0, 0x42, 0x1f, 0x24, 0xef, 0x23, 0xf1, - 0x70, 0x45, 0x25, 0x76, 0xeb, 0xd6, 0x0e, 0xe9, 0xe5, 0xbe, 0x4b, 0x51, - 0x6b, 0x25, 0x6a, 0x0e, 0xfe, 0x5b, 0x38, 0x52, 0x4b, 0x6f, 0x82, 0xd5, - 0xf2, 0xdc, 0xaa, 0x85, 0x0b, 0x01, 0xda, 0xdf, 0xd9, 0x6c, 0xad, 0xd1, - 0x97, 0xf4, 0xfb, 0xfd, 0x96, 0xa7, 0x77, 0x37, 0x2f, 0x3f, 0xe2, 0xe9, - 0xed, 0x87, 0x9b, 0x93, 0xa5, 0x8f, 0x2f, 0xa4, 0x77, 0xa0, 0x62, 0x18, - 0xa5, 0x77, 0x8c, 0xb1, 0x3e, 0x25, 0xb7, 0xc4, 0xd7, 0x0f, 0xed, 0x54, - 0x8f, 0x36, 0xc9, 0xdd, 0x41, 0xd7, 0x11, 0x16, 0xd5, 0x4f, 0x12, 0xd9, - 0x6b, 0x78, 0xd0, 0x56, 0x18, 0x98, 0x0c, 0xc7, 0x6c, 0xae, 0x47, 0x24, - 0x69, 0x09, 0xf8, 0xa0, 0xaa, 0x53, 0x2c, 0x37, 0x8e, 0x1c, 0x3a, 0x33, - 0xa2, 0xf3, 0xb9, 0x42, 0xd8, 0x9c, 0xa6, 0x4b, 0x08, 0x70, 0x9c, 0xba, - 0xaa, 0x84, 0xc9, 0x81, 0x12, 0x64, 0xc8, 0x27, 0xa7, 0x2f, 0xa7, 0x3f, - 0x28, 0xa9, 0xa6, 0xe3, 0x1a, 0xe1, 0x37, 0xbb, 0xc8, 0x74, 0xaf, 0x9b, - 0xb5, 0x7c, 0xe0, 0xa3, 0xfb, 0x4b, 0xad, 0xc2, 0xf6, 0xef, 0xb8, 0xfd, - 0xaf, 0x57, 0xbb, 0xf5, 0xeb, 0xb2, 0xa7, 0x93, 0xd5, 0x45, 0xa6, 0xcc, - 0xc5, 0x32, 0xc3, 0xf0, 0x9e, 0x32, 0x79, 0x0a, 0x17, 0x5b, 0x0c, 0xae, - 0xa8, 0xd9, 0x9e, 0xf4, 0x04, 0x3e, 0x82, 0xd5, 0xbc, 0x54, 0xfa, 0xa5, - 0x55, 0x56, 0x8b, 0x42, 0xc8, 0xb1, 0xe6, 0x7c, 0x83, 0x73, 0xcb, 0xc8, - 0xad, 0x5d, 0x80, 0xb7, 0x81, 0x21, 0x52, 0x26, 0x1c, 0xbb, 0xd3, 0xe6, - 0x25, 0x96, 0x82, 0x0b, 0x9b, 0x6b, 0x65, 0xac, 0xd4, 0xb2, 0xd9, 0x4c, - 0x04, 0x61, 0x51, 0x05, 0xd8, 0xf5, 0xd7, 0xe8, 0xdb, 0xef, 0x74, 0x1c, - 0x96, 0x4f, 0x98, 0x0b, 0x8d, 0x94, 0xbe, 0x10, 0x87, 0xa9, 0x41, 0x2f, - 0xc5, 0x01, 0x01, 0x5a, 0x9e, 0xce, 0x38, 0x27, 0xbf, 0xc9, 0x6e, 0x43, - 0x2c, 0xd3, 0x5d, 0x70, 0x68, 0x02, 0xde, 0x5e, 0x2f, 0x65, 0x40, 0x8a, - 0x4f, 0x44, 0x53, 0x61, 0x93, 0x82, 0x8c, 0xa5, 0x59, 0x8f, 0x92, 0xd9, - 0xcc, 0x18, 0x04, 0xcb, 0x6e, 0x42, 0xae, 0x3e, 0x2d, 0xd7, 0x26, 0x52, - 0x75, 0x58, 0x23, 0x78, 0x5e, 0x9d, 0xc3, 0x36, 0x09, 0xe3, 0x16, 0x32, - 0xa7, 0x5b, 0x42, 0xc0, 0xc3, 0xc5, 0xf1, 0x49, 0x69, 0xca, 0xda, 0x43, - 0x47, 0xe9, 0x68, 0x04, 0x8b, 0xa6, 0x15, 0xbb, 0x3a, 0x77, 0xa7, 0x2a, - 0xdf, 0xfa, 0xbe, 0x2c, 0x4d, 0xef, 0xe5, 0x47, 0xb4, 0x73, 0xfb, 0x3b, - 0x0b, 0x94, 0x8d, 0x46, 0xfa, 0x5e, 0x8a, 0xe8, 0x7a, 0xc2, 0x4f, 0x64, - 0x6f, 0x84, 0xca, 0xff, 0x93, 0xa9, 0x1c, 0xfd, 0xfd, 0xf2, 0x0d, 0x65, - 0xed, 0x46, 0xa4, 0x7e, 0x86, 0x71, 0xa6, 0x46, 0x44, 0xf4, 0xa8, 0x98, - 0xb9, 0x0d, 0xc0, 0x79, 0x6e, 0x81, 0x78, 0xa4, 0x1b, 0xf5, 0x1a, 0x39, - 0x09, 0x07, 0xcc, 0x5d, 0x7a, 0x70, 0x96, 0x41, 0x86, 0xe4, 0x32, 0xf3, - 0x86, 0x9a, 0xe4, 0x62, 0xd3, 0x34, 0xda, 0x83, 0x72, 0x9f, 0x1c, 0xac, - 0x52, 0xa9, 0xab, 0x81, 0x7d, 0x00, 0x11, 0x6a, 0x7d, 0x44, 0xed, 0x2e, - 0x5c, 0x16, 0xf6, 0x92, 0x43, 0x2d, 0xe0, 0x72, 0x21, 0x1a, 0xf0, 0x21, - 0x84, 0x85, 0x85, 0xc6, 0x66, 0x68, 0xc4, 0x1b, 0x99, 0x87, 0x52, 0x0d, - 0xab, 0x3c, 0xaa, 0x45, 0xa9, 0xcf, 0x6c, 0x57, 0x55, 0x7a, 0xc5, 0xfc, - 0xdb, 0x5b, 0xa5, 0x23, 0x5f, 0x3e, 0xb0, 0x51, 0xfd, 0x3a, 0x18, 0x64, - 0xe3, 0x48, 0x43, 0xe5, 0x63, 0x1c, 0x27, 0xd5, 0xe3, 0x02, 0xc6, 0xbe, - 0x6a, 0x65, 0xc0, 0x28, 0x08, 0xd1, 0x7d, 0x6e, 0x82, 0xa4, 0xf8, 0xc9, - 0x07, 0x86, 0x81, 0x82, 0x53, 0x0c, 0xfb, 0x27, 0x25, 0xed, 0xb9, 0x1a, - 0x65, 0xa5, 0x23, 0xf2, 0x06, 0x6b, 0x37, 0x66, 0xb6, 0xe6, 0x52, 0x90, - 0x00, 0xd6, 0x7a, 0xbc, 0x2e, 0x51, 0xb1, 0x9b, 0x06, 0x51, 0x55, 0x8b, - 0x9f, 0x27, 0xc5, 0x00, 0x66, 0x0c, 0xab, 0xd0, 0x03, 0x5e, 0x3f, 0x46, - 0x3f, 0x67, 0x50, 0x66, 0xb0, 0x11, 0xcb, 0xee, 0x15, 0x8a, 0x19, 0x80, - 0x7c, 0x60, 0x32, 0xaf, 0x9a, 0x4c, 0xa3, 0xed, 0x0b, 0x62, 0x83, 0xc5, - 0x15, 0x84, 0x69, 0x72, 0xc8, 0xb3, 0x53, 0x5b, 0x0c, 0x2c, 0x22, 0xe4, - 0x28, 0xbb, 0x4d, 0xe2, 0x9a, 0x4d, 0x78, 0x95, 0x38, 0x1d, 0x5b, 0xaa, - 0x2c, 0x26, 0xff, 0xde, 0xab, 0x58, 0x20, 0x83, 0xee, 0xd6, 0x6f, 0xb2, - 0x7a, 0x23, 0x18, 0x10, 0xe2, 0x98, 0x58, 0xed, 0xbd, 0x8b, 0x71, 0x4d, - 0x51, 0x34, 0x13, 0x25, 0x78, 0xbb, 0x28, 0x2c, 0x91, 0xb2, 0xe0, 0xbe, - 0xe6, 0x50, 0x62, 0x10, 0x65, 0x66, 0x99, 0xc3, 0x81, 0x50, 0xbf, 0x76, - 0x24, 0x3c, 0xa9, 0x95, 0xc0, 0x0a, 0x47, 0x05, 0x32, 0xa7, 0x3f, 0x3b, - 0xfa, 0x5a, 0x87, 0x0d, 0x26, 0xb1, 0x3c, 0x2c, 0x4c, 0x1f, 0xb9, 0x73, - 0xac, 0xd7, 0xdb, 0x6b, 0xff, 0xd1, 0xa1, 0xae, 0x33, 0x04, 0x8f, 0x5d, - 0xb7, 0x21, 0x58, 0x96, 0x07, 0x0c, 0x71, 0x9c, 0x0f, 0x72, 0x45, 0x20, - 0x33, 0xbb, 0x0a, 0xba, 0xa0, 0x36, 0x16, 0x32, 0xbb, 0x0f, 0x3f, 0x64, - 0xe5, 0x20, 0x47, 0x23, 0xca, 0x6f, 0xf3, 0x21, 0xbc, 0x46, 0x17, 0x01, - 0x9b, 0xa2, 0x47, 0x0d, 0x34, 0x8a, 0x24, 0x13, 0x4f, 0x3c, 0x1a, 0x0e, - 0x1a, 0x15, 0xb7, 0xfa, 0xc9, 0x7e, 0x52, 0x16, 0x17, 0x73, 0x57, 0xf1, - 0x08, 0x63, 0xa0, 0x39, 0x2e, 0x82, 0xa2, 0xdb, 0x74, 0x1d, 0xd0, 0x3b, - 0x9f, 0x3c, 0x7b, 0xf9, 0x92, 0x63, 0x1b, 0x42, 0x74, 0x3c, 0x3b, 0x13, - 0x08, 0x2f, 0x56, 0xc3, 0xa7, 0x13, 0x34, 0x73, 0xe0, 0x3d, 0x12, 0x5d, - 0x5c, 0x68, 0x1f, 0xd3, 0x18, 0x7c, 0x8c, 0x0e, 0xc0, 0x24, 0x7a, 0x1c, - 0x69, 0xa9, 0x28, 0x5e, 0x20, 0xed, 0xc3, 0xf5, 0x56, 0x8c, 0xea, 0xeb, - 0x74, 0xa1, 0x46, 0xd7, 0x22, 0x2f, 0x6c, 0x43, 0xb5, 0x13, 0x25, 0xfd, - 0x96, 0xc0, 0xc3, 0x05, 0x59, 0x65, 0xa1, 0xdd, 0x5b, 0x45, 0x97, 0xe3, - 0xff, 0x6c, 0x63, 0xef, 0x9b, 0xe2, 0x44, 0x59, 0xf0, 0x5d, 0x18, 0x53, - 0x56, 0xbe, 0x7e, 0xdc, 0x8d, 0x3f, 0x97, 0xbd, 0x28, 0x31, 0xef, 0x57, - 0x22, 0x33, 0x09, 0x66, 0x56, 0xac, 0xc9, 0x2e, 0x3c, 0x81, 0x21, 0x96, - 0x7d, 0x38, 0x29, 0x73, 0x18, 0xf4, 0xcd, 0x67, 0x9a, 0x39, 0xbd, 0x4e, - 0x16, 0xc1, 0xe0, 0x79, 0x24, 0x0b, 0xa6, 0x58, 0xf5, 0x34, 0x7a, 0x4c, - 0xd9, 0xa5, 0x03, 0x4b, 0xd0, 0x62, 0x35, 0x30, 0x49, 0x43, 0x2e, 0x1e, - 0xf5, 0x37, 0x56, 0xe7, 0xb1, 0x8b, 0x81, 0x53, 0x7d, 0x4b, 0xbf, 0xc0, - 0x10, 0xd7, 0x70, 0x4b, 0xb0, 0xdf, 0x4c, 0x1b, 0x49, 0x13, 0x97, 0x4a, - 0xeb, 0x98, 0x1e, 0x49, 0x40, 0x04, 0xe2, 0x4c, 0x49, 0x15, 0x97, 0x6c, - 0x40, 0x0b, 0x10, 0x92, 0x8d, 0x6e, 0x83, 0x37, 0x4c, 0x01, 0x28, 0xa7, - 0x57, 0x05, 0x7d, 0xc3, 0x26, 0x8b, 0x46, 0x82, 0x04, 0xde, 0x03, 0x41, - 0xd5, 0x69, 0x63, 0xf5, 0x67, 0x61, 0xbd, 0x02, 0xc7, 0x2b, 0x42, 0x6e, - 0x17, 0x4c, 0x40, 0x82, 0x57, 0x0c, 0x60, 0x26, 0xb0, 0x09, 0x0f, 0x77, - 0x05, 0x97, 0x62, 0x17, 0x99, 0x03, 0x02, 0x36, 0x83, 0xf6, 0x8b, 0x11, - 0x4e, 0x0e, 0x6d, 0xa6, 0x79, 0x11, 0x10, 0xab, 0x77, 0x5c, 0xde, 0x79, - 0x6a, 0x0c, 0x41, 0xdb, 0x5f, 0x41, 0x1c, 0x70, 0x97, 0x70, 0xf5, 0x39, - 0xf8, 0x63, 0x70, 0x89, 0x10, 0x0f, 0x0d, 0xf4, 0x43, 0x92, 0x50, 0x82, - 0x29, 0xa6, 0xf5, 0x28, 0x49, 0x66, 0xb9, 0x13, 0x01, 0x71, 0x73, 0x86, - 0xc3, 0x5c, 0x25, 0x09, 0xcf, 0x50, 0xfa, 0xd1, 0x75, 0xa8, 0x6c, 0x83, - 0xba, 0xae, 0x12, 0x7f, 0x47, 0x48, 0xa8, 0x7d, 0x2a, 0xa0, 0x9e, 0x8d, - 0xd9, 0x26, 0xca, 0xe9, 0xe4, 0x7a, 0xf3, 0xf3, 0x6e, 0xbb, 0x38, 0xac, - 0x2c, 0x2f, 0xed, 0x38, 0x05, 0x57, 0x4d, 0x93, 0x48, 0x38, 0x60, 0xe9, - 0x33, 0xaf, 0xe9, 0x16, 0xfa, 0xf7, 0x9d, 0xad, 0xb0, 0xcf, 0x92, 0x51, - 0x82, 0x4d, 0x18, 0xc6, 0xd1, 0x2c, 0x95, 0xb0, 0x9d, 0x44, 0x8b, 0x04, - 0x4e, 0xc4, 0x54, 0x8d, 0x41, 0xb7, 0x53, 0x4e, 0x63, 0x57, 0xe3, 0xbe, - 0xb2, 0x16, 0xeb, 0xaa, 0x11, 0x79, 0x47, 0x94, 0xe1, 0x49, 0x2c, 0x95, - 0x8a, 0x53, 0xc2, 0x9c, 0x52, 0xad, 0x44, 0x68, 0xb6, 0x19, 0x36, 0xc9, - 0xc1, 0xb6, 0xea, 0xc5, 0x79, 0x95, 0xf5, 0x1b, 0x82, 0x1c, 0xe7, 0x3b, - 0x14, 0x83, 0x9c, 0xdc, 0x9a, 0x1a, 0xfd, 0x28, 0xb9, 0x3f, 0x2c, 0x6f, - 0x61, 0xa6, 0x45, 0x4e, 0x05, 0x10, 0x34, 0x82, 0x73, 0x26, 0x3a, 0x8f, - 0x59, 0xb5, 0x71, 0x68, 0x91, 0x1d, 0x70, 0xc1, 0x73, 0x7b, 0xbb, 0xa8, - 0x7d, 0xbc, 0x94, 0xe3, 0x05, 0x06, 0xb6, 0xd2, 0xa3, 0xb7, 0x7d, 0xbf, - 0x73, 0x2b, 0xf7, 0x44, 0xa4, 0x8c, 0x6e, 0x74, 0x50, 0x4d, 0x09, 0x6f, - 0xe1, 0xde, 0x11, 0x95, 0xeb, 0xeb, 0x22, 0xf0, 0x32, 0x27, 0x89, 0x8a, - 0xa6, 0x8a, 0x35, 0x89, 0x72, 0x86, 0x40, 0xa0, 0x66, 0xcb, 0x29, 0xef, - 0x0e, 0x1b, 0x4a, 0x86, 0x59, 0xaa, 0xe9, 0xd7, 0x46, 0x07, 0xf9, 0xa8, - 0xb1, 0x57, 0xd7, 0x59, 0xa9, 0x4e, 0x59, 0x83, 0x2c, 0x47, 0xf3, 0x3c, - 0xd3, 0x64, 0x38, 0xbd, 0x85, 0x19, 0x01, 0x1c, 0x88, 0x2d, 0xe7, 0x2b, - 0x59, 0x81, 0x6d, 0xdc, 0x3e, 0x0e, 0x56, 0x5d, 0x98, 0x06, 0x91, 0x36, - 0xc1, 0xdb, 0x0a, 0xfb, 0x36, 0x02, 0xa2, 0x78, 0x46, 0xdc, 0xeb, 0x4e, - 0x0f, 0xb1, 0xdc, 0x3a, 0x74, 0x4d, 0xfb, 0x2b, 0x8e, 0x4f, 0x48, 0xdb, - 0xa5, 0x1a, 0xaf, 0xd1, 0xfd, 0x16, 0xbe, 0x6c, 0x74, 0x71, 0x87, 0x5d, - 0xa0, 0x31, 0xd9, 0x96, 0x18, 0x01, 0xa0, 0x95, 0xed, 0x25, 0x9f, 0xef, - 0xac, 0x74, 0x03, 0xbf, 0x71, 0x37, 0x30, 0x4e, 0x50, 0x8a, 0xfe, 0x85, - 0x1c, 0x13, 0x27, 0xa0, 0x92, 0xbf, 0x29, 0xa3, 0x9c, 0x09, 0xce, 0x36, - 0xc1, 0x05, 0xa9, 0xa1, 0xd7, 0xb6, 0x3b, 0xd5, 0xed, 0x27, 0x87, 0xd6, - 0x73, 0x56, 0x9b, 0x7a, 0x7d, 0x68, 0xb7, 0x38, 0x78, 0x7a, 0x14, 0xa2, - 0xdc, 0xad, 0x64, 0x7a, 0x12, 0x5c, 0x92, 0x12, 0xb6, 0xc5, 0xee, 0x64, - 0xbe, 0xc7, 0x2f, 0x32, 0xab, 0xbc, 0xc2, 0x05, 0xbf, 0x6d, 0x24, 0xb1, - 0x21, 0xa7, 0x6d, 0x6a, 0x9f, 0x65, 0x3f, 0xb1, 0xa9, 0x95, 0xf6, 0x92, - 0x6c, 0xd6, 0x40, 0x91, 0xa3, 0xa2, 0x58, 0x4d, 0x31, 0xf6, 0x87, 0x8a, - 0x0f, 0x39, 0x36, 0x81, 0xfe, 0x9f, 0x61, 0x74, 0xb6, 0xaf, 0xb2, 0x5e, - 0x31, 0xed, 0x91, 0xea, 0xa3, 0xa5, 0x6a, 0xf0, 0x43, 0x95, 0xa2, 0x78, - 0xdd, 0x60, 0xa9, 0x4d, 0x3f, 0x12, 0x05, 0x89, 0x0f, 0x24, 0x0d, 0x52, - 0xe3, 0x9b, 0xa8, 0x06, 0x76, 0x68, 0x88, 0x38, 0xa7, 0xda, 0xc3, 0x51, - 0x54, 0xd1, 0x36, 0x39, 0x91, 0x2f, 0x48, 0x66, 0x62, 0x42, 0x42, 0x3b, - 0x4c, 0x86, 0x69, 0x3c, 0xec, 0xb7, 0x09, 0x5a, 0xf1, 0x38, 0x63, 0x31, - 0x21, 0xd5, 0xf8, 0x02, 0xcd, 0x22, 0xe4, 0x30, 0xae, 0x94, 0xed, 0xac, - 0x36, 0xc0, 0xe1, 0xbc, 0xf4, 0x26, 0xe3, 0x86, 0xda, 0xa9, 0x79, 0x3b, - 0x72, 0x5b, 0xa6, 0x28, 0x06, 0x5e, 0xcc, 0x31, 0x05, 0x91, 0x53, 0x3d, - 0x22, 0x75, 0xc8, 0x00, 0x9e, 0x3d, 0xac, 0x8e, 0x4f, 0x22, 0x6b, 0xac, - 0xe0, 0x1d, 0x10, 0xd1, 0xab, 0xe3, 0xf3, 0x34, 0xda, 0xbd, 0x9b, 0x44, - 0xfc, 0x20, 0x80, 0x4c, 0x64, 0x96, 0x2b, 0x41, 0xf0, 0x3c, 0xd9, 0x6d, - 0xd8, 0x68, 0x31, 0x48, 0x5c, 0x69, 0xe4, 0xe7, 0x6e, 0x08, 0x1e, 0x4a, - 0x9e, 0x72, 0x72, 0xfd, 0xb7, 0x0b, 0x97, 0x80, 0x24, 0xdd, 0x8b, 0x68, - 0xc7, 0x15, 0x57, 0xd0, 0xe9, 0xa0, 0x7a, 0x72, 0x73, 0x2f, 0x68, 0xe0, - 0x64, 0x5a, 0x25, 0x27, 0x2e, 0xdf, 0xe9, 0x70, 0xb5, 0x9e, 0x63, 0xdc, - 0xb1, 0x99, 0xd2, 0x90, 0xdb, 0xe3, 0x35, 0xa2, 0x7e, 0x83, 0xc8, 0xeb, - 0x15, 0x72, 0x9e, 0x90, 0xab, 0xa0, 0x88, 0x00, 0xfb, 0x87, 0xbc, 0x1e, - 0x55, 0x78, 0x12, 0x53, 0xaa, 0x74, 0x94, 0x25, 0x17, 0xf3, 0xb4, 0x1c, - 0x52, 0xcd, 0x16, 0xe4, 0x27, 0x5c, 0xa8, 0x83, 0xea, 0x77, 0x51, 0x4c, - 0xe0, 0xcc, 0x12, 0x36, 0xa8, 0xfa, 0x71, 0x31, 0xad, 0xcb, 0x62, 0x1c, - 0x85, 0x59, 0x07, 0xd8, 0x1f, 0x0a, 0xee, 0xf2, 0xa6, 0x8a, 0x01, 0xdc, - 0x14, 0x20, 0xaa, 0x5a, 0x7a, 0x5b, 0x58, 0x84, 0xb0, 0x0a, 0x31, 0x10, - 0x1b, 0xfa, 0xb9, 0xcd, 0x22, 0x4a, 0x46, 0x54, 0x8b, 0x10, 0x3f, 0x8b, - 0xe0, 0x2e, 0xad, 0x51, 0x45, 0x33, 0xd0, 0xcc, 0x3e, 0x68, 0xa1, 0x91, - 0xeb, 0x28, 0x4f, 0x58, 0x6c, 0x84, 0x5c, 0x9e, 0xeb, 0x2c, 0x8a, 0xca, - 0xed, 0xcc, 0x91, 0xf5, 0x3f, 0x1c, 0x9e, 0x61, 0xa6, 0xc0, 0x83, 0x37, - 0x5a, 0xd0, 0x83, 0x86, 0xc0, 0x3e, 0x7f, 0xb9, 0x33, 0xd9, 0x6c, 0x82, - 0xf7, 0xa8, 0xe2, 0x0a, 0x11, 0xab, 0x45, 0x95, 0x3a, 0x9d, 0x2a, 0x26, - 0xdb, 0x83, 0x07, 0x07, 0x30, 0xab, 0x22, 0x48, 0xb6, 0x70, 0x22, 0xbd, - 0x49, 0xb8, 0xb2, 0x92, 0x28, 0xc9, 0xc9, 0xdb, 0x33, 0x6a, 0x01, 0x03, - 0xd6, 0xce, 0x0e, 0xbb, 0xc8, 0x14, 0x38, 0xbe, 0xb3, 0xcc, 0xc6, 0x24, - 0x8d, 0xd5, 0xd9, 0xe0, 0x72, 0x5a, 0xa0, 0x77, 0x86, 0x32, 0x9f, 0x90, - 0x75, 0xff, 0x94, 0x9d, 0x3f, 0xdb, 0xff, 0x91, 0x2b, 0x47, 0x60, 0x31, - 0xbd, 0x37, 0xc7, 0x27, 0xcf, 0x8f, 0x5e, 0x3f, 0xeb, 0x26, 0x07, 0xc7, - 0x27, 0x7f, 0x81, 0x26, 0x5e, 0x1d, 0xff, 0x88, 0x51, 0x28, 0x1c, 0xc4, - 0xcc, 0x00, 0xea, 0x0f, 0x5e, 0x23, 0x24, 0x27, 0x2a, 0xc7, 0x62, 0x62, - 0x75, 0x4e, 0x9a, 0x20, 0x4c, 0xf6, 0x31, 0xdb, 0x2c, 0xb1, 0xb8, 0x50, - 0x58, 0x0e, 0x68, 0xed, 0xc5, 0xe1, 0xfe, 0x33, 0x0c, 0x49, 0x39, 0x39, - 0x3e, 0xe5, 0xa1, 0xe2, 0x90, 0xc3, 0x4c, 0xc8, 0x35, 0x29, 0xe6, 0x0f, - 0xd2, 0x86, 0x24, 0x34, 0x56, 0x50, 0x86, 0xe0, 0x10, 0x11, 0xf6, 0x25, - 0x6e, 0x8c, 0x17, 0x05, 0xa5, 0x47, 0x22, 0xa0, 0x07, 0x11, 0x44, 0x44, - 0x04, 0x5f, 0x27, 0x21, 0xa1, 0x5c, 0x8a, 0x87, 0xd1, 0x42, 0x0c, 0xdf, - 0xcd, 0x88, 0x84, 0x56, 0x8b, 0x86, 0xd3, 0x8d, 0xa0, 0x35, 0x13, 0xf2, - 0x44, 0xd0, 0x73, 0xd7, 0xa9, 0xc4, 0xcc, 0x80, 0x4c, 0x83, 0x12, 0x30, - 0x10, 0xfc, 0x73, 0x72, 0x46, 0xf1, 0xb9, 0x47, 0xaa, 0x19, 0x45, 0xc2, - 0x13, 0x5d, 0x92, 0xa9, 0x95, 0xe8, 0xc1, 0x45, 0x48, 0xac, 0x13, 0xa9, - 0x10, 0xfb, 0x33, 0x7f, 0x4c, 0x1d, 0x62, 0x44, 0x2e, 0x1a, 0xb0, 0xe6, - 0x98, 0x25, 0x9a, 0x71, 0xc1, 0x24, 0x5a, 0x5f, 0x39, 0xf2, 0x5c, 0x36, - 0xf6, 0x92, 0xe8, 0x72, 0x66, 0x81, 0x25, 0x67, 0x81, 0x3e, 0xa3, 0x43, - 0x4d, 0xa6, 0x77, 0x35, 0xf6, 0x2b, 0xa9, 0x5b, 0xf2, 0xaa, 0x20, 0x35, - 0x50, 0x10, 0xaf, 0xee, 0x83, 0xd6, 0xb7, 0xc9, 0x45, 0x08, 0x1c, 0xb9, - 0xd9, 0xb1, 0xd2, 0x10, 0xbc, 0x06, 0x6c, 0xc4, 0x12, 0x14, 0xc2, 0x07, - 0x70, 0xf8, 0xa6, 0x12, 0xa2, 0x81, 0x85, 0xd3, 0x7a, 0xcc, 0x81, 0xab, - 0x24, 0xc2, 0xb2, 0x0a, 0xce, 0x58, 0x53, 0x92, 0x8d, 0xcd, 0x3c, 0x90, - 0x19, 0xa4, 0x83, 0x01, 0x6c, 0x90, 0x8b, 0xc5, 0x26, 0x92, 0xdf, 0xdd, - 0xfa, 0x10, 0xe2, 0x70, 0x50, 0x23, 0xaa, 0x92, 0x1e, 0x07, 0x81, 0x73, - 0x62, 0xbb, 0x72, 0x90, 0xe7, 0xcb, 0x19, 0x88, 0xcf, 0x8e, 0x31, 0xee, - 0x61, 0xce, 0x28, 0x20, 0xd4, 0x97, 0x47, 0x40, 0x9a, 0xe2, 0xbc, 0x7f, - 0xc0, 0xf8, 0x9a, 0x1c, 0x00, 0x4e, 0xfa, 0x1f, 0xad, 0x23, 0xb4, 0xa1, - 0x3d, 0x9d, 0x1c, 0x9f, 0xec, 0x2e, 0xeb, 0x0a, 0xbf, 0x73, 0x41, 0xe0, - 0xaa, 0x8a, 0x3b, 0x96, 0x22, 0x9d, 0x51, 0xfc, 0xf3, 0x9b, 0xc3, 0xb3, - 0x37, 0x76, 0x7b, 0xbe, 0xda, 0x5f, 0x98, 0x80, 0x34, 0x8a, 0x5f, 0xf9, - 0xf1, 0xfb, 0xe1, 0xcb, 0xe8, 0x2d, 0x72, 0xf3, 0xd5, 0xf2, 0x65, 0xc0, - 0xef, 0xee, 0x18, 0xdb, 0x8b, 0xc3, 0x97, 0x27, 0x32, 0xb6, 0x1f, 0xdf, - 0x3c, 0xff, 0x4b, 0x1c, 0x62, 0xa3, 0x6c, 0xb8, 0xd5, 0xb9, 0xfa, 0xc9, - 0xd1, 0x97, 0x0d, 0x25, 0xee, 0x67, 0x8e, 0xbd, 0x3d, 0x3b, 0xbc, 0xdb, - 0x35, 0xf2, 0x73, 0xf2, 0xfa, 0x25, 0x2c, 0xe5, 0x2a, 0x59, 0x8e, 0x32, - 0xf6, 0x1e, 0x87, 0x12, 0x3b, 0xf1, 0xcc, 0x7f, 0x9c, 0x3c, 0x45, 0xf3, - 0x52, 0xec, 0xa5, 0x23, 0x88, 0x95, 0x29, 0x33, 0x02, 0x29, 0x72, 0x2f, - 0x0f, 0x27, 0xeb, 0xf8, 0xf4, 0x86, 0x5f, 0x3e, 0x67, 0xb6, 0xc6, 0xef, - 0x42, 0xd8, 0x8b, 0x05, 0x3c, 0x4f, 0x83, 0x03, 0x02, 0x43, 0xef, 0xea, - 0x7c, 0x80, 0x82, 0x11, 0x43, 0xc0, 0x61, 0x4e, 0x21, 0x1d, 0x19, 0x64, - 0x21, 0x72, 0x0a, 0x60, 0xe1, 0x2a, 0x05, 0x1c, 0x8a, 0x2f, 0x00, 0xbd, - 0x97, 0x51, 0x76, 0xa3, 0x33, 0x53, 0x8d, 0xa9, 0x36, 0xb6, 0x5d, 0xce, - 0x14, 0x88, 0xcb, 0xa2, 0x78, 0xc3, 0xf2, 0xcb, 0x7e, 0x37, 0x51, 0x0b, - 0x58, 0x32, 0x43, 0x45, 0x6e, 0x86, 0xfa, 0x44, 0x39, 0xed, 0xf2, 0x25, - 0xd1, 0x39, 0x3e, 0x39, 0x3b, 0x3a, 0x7e, 0x7d, 0x9a, 0xfc, 0x47, 0xe7, - 0x36, 0x99, 0xc2, 0x44, 0x0a, 0x65, 0x3f, 0x64, 0x49, 0x23, 0x99, 0x82, - 0x44, 0x0a, 0xcd, 0x49, 0xf8, 0xfc, 0x32, 0x85, 0x17, 0x2a, 0xcc, 0xb9, - 0x17, 0x6d, 0x6f, 0x2b, 0xe0, 0xb7, 0x43, 0xc4, 0xff, 0x1d, 0x41, 0x62, - 0x71, 0x47, 0x9d, 0xff, 0xe8, 0x20, 0x75, 0xea, 0x0a, 0xae, 0xa8, 0x4d, - 0x34, 0xc2, 0xc7, 0x31, 0x3e, 0x04, 0x56, 0xf1, 0xe9, 0x5f, 0xff, 0xf8, - 0x2b, 0xe2, 0x56, 0x10, 0x6c, 0xc5, 0x1e, 0xc8, 0x03, 0xe5, 0x5f, 0xbb, - 0xf8, 0xf3, 0xd7, 0x7e, 0xbf, 0xdf, 0xa8, 0xa1, 0x69, 0xfc, 0x02, 0xbf, - 0x47, 0xbf, 0x8a, 0x94, 0xd2, 0x34, 0x75, 0x1d, 0xdb, 0x61, 0x80, 0x1a, - 0xb4, 0xf9, 0xcf, 0xd2, 0xbc, 0x8c, 0x8b, 0xa5, 0xe3, 0x4d, 0xde, 0x35, - 0x74, 0x18, 0xbe, 0xc2, 0x2c, 0x25, 0xcc, 0x48, 0x6f, 0xbd, 0xda, 0x50, - 0xa4, 0x1a, 0x27, 0x4f, 0x49, 0x9f, 0x61, 0x5f, 0x44, 0xd9, 0xe0, 0x06, - 0x82, 0xf0, 0x34, 0x55, 0x39, 0x22, 0x91, 0x19, 0x0e, 0x6d, 0xb8, 0x62, - 0xc5, 0x90, 0xf5, 0x56, 0xbf, 0x1f, 0x15, 0xe3, 0x64, 0x45, 0x2f, 0x21, - 0xd1, 0x82, 0x38, 0xf6, 0x66, 0x56, 0x0f, 0x36, 0x71, 0x3e, 0x55, 0x12, - 0x1d, 0x4e, 0xb7, 0xc1, 0x51, 0x05, 0xeb, 0x18, 0xd4, 0x84, 0x22, 0xd5, - 0x3d, 0xc6, 0x81, 0x56, 0xca, 0x3b, 0xcf, 0x22, 0xeb, 0x97, 0x59, 0x49, - 0x42, 0x43, 0xb6, 0x98, 0x86, 0x8d, 0xa1, 0x45, 0x7f, 0xc2, 0xfd, 0x0a, - 0x6f, 0x00, 0x09, 0x2a, 0xa2, 0xd2, 0x8d, 0xde, 0xe4, 0x31, 0xc9, 0x61, - 0xca, 0x04, 0xf2, 0x67, 0xbd, 0x70, 0x83, 0xd9, 0x45, 0xbd, 0x43, 0xb6, - 0x2e, 0x3a, 0x02, 0x51, 0xa9, 0xa9, 0x33, 0x44, 0x5c, 0xd2, 0xcc, 0x5b, - 0xb5, 0x4b, 0xe3, 0x8c, 0x7c, 0xf2, 0xac, 0xc3, 0xe3, 0x41, 0x92, 0x44, - 0x56, 0x44, 0xef, 0x9a, 0xbf, 0x3f, 0x00, 0x00, 0x61, 0xc7, 0x4a, 0x72, - 0x64, 0x0d, 0xc4, 0x07, 0xc3, 0x66, 0xda, 0xac, 0x05, 0x03, 0x05, 0x69, - 0x27, 0x64, 0xb0, 0x2c, 0x92, 0x41, 0x1f, 0x1d, 0x28, 0xe3, 0xe1, 0x20, - 0xe5, 0x9a, 0xe3, 0x9a, 0x5a, 0x23, 0x1b, 0xce, 0x47, 0xac, 0xe0, 0x12, - 0x63, 0x81, 0xd4, 0x35, 0xa4, 0x39, 0x74, 0x16, 0x13, 0x6c, 0x74, 0x8b, - 0x70, 0x80, 0xb6, 0x37, 0x83, 0x87, 0x18, 0x3a, 0x59, 0x37, 0x3c, 0xc4, - 0x94, 0xee, 0xe2, 0xf4, 0x4d, 0x8d, 0x4f, 0xd2, 0x80, 0x81, 0x5e, 0x2f, - 0x9f, 0x5d, 0x3d, 0x0c, 0xf6, 0x57, 0xfa, 0xfb, 0xb1, 0x62, 0x51, 0xd4, - 0x3e, 0xb1, 0x78, 0x4e, 0x57, 0x01, 0x73, 0xa9, 0xa3, 0x93, 0x66, 0x1d, - 0xb5, 0xef, 0x6f, 0x24, 0x9b, 0x58, 0xaf, 0x00, 0xde, 0x25, 0x31, 0x85, - 0xae, 0xfd, 0x71, 0xad, 0xe5, 0x5c, 0x71, 0xd6, 0x0c, 0x19, 0x1e, 0x50, - 0x9f, 0x94, 0xe5, 0xb6, 0xe4, 0xef, 0xb5, 0x2a, 0x0a, 0xa8, 0x43, 0x8e, - 0xb9, 0xbe, 0x2d, 0x11, 0x6e, 0x1b, 0x0b, 0x98, 0x07, 0x1c, 0xa9, 0x4b, - 0x91, 0x35, 0x06, 0xd8, 0x2e, 0xd8, 0x53, 0xe3, 0x02, 0x53, 0x35, 0xe6, - 0x53, 0x4a, 0xd9, 0xb0, 0xb0, 0xc4, 0x10, 0xf2, 0xa5, 0xa3, 0x1c, 0x17, - 0xe4, 0x83, 0x41, 0xd1, 0x87, 0x72, 0x2f, 0xc4, 0x35, 0x50, 0xcd, 0xc9, - 0xe4, 0x5e, 0x21, 0x87, 0xcc, 0x17, 0x41, 0xad, 0x69, 0x3d, 0x39, 0x0a, - 0x95, 0x08, 0xda, 0x51, 0x12, 0x51, 0x87, 0xa3, 0x24, 0xf2, 0x1c, 0x18, - 0x07, 0xb8, 0xa6, 0x33, 0x57, 0x68, 0x80, 0x9d, 0xce, 0x11, 0x15, 0x7a, - 0x50, 0x87, 0x08, 0xd8, 0x21, 0x60, 0x8a, 0xc0, 0x5f, 0x8c, 0x59, 0xa2, - 0x09, 0x22, 0x95, 0x21, 0x1e, 0xc5, 0xf4, 0xc2, 0x2e, 0x40, 0xad, 0x5f, - 0xa7, 0x9f, 0x74, 0x15, 0x2e, 0x9b, 0xa3, 0x8b, 0x19, 0x77, 0x15, 0xe6, - 0xea, 0x98, 0x40, 0xd7, 0x4a, 0xff, 0x8a, 0xb0, 0xad, 0xd0, 0x22, 0x30, - 0xa1, 0x20, 0x72, 0x13, 0xdb, 0x16, 0xaf, 0xe9, 0x88, 0xb0, 0xf0, 0x71, - 0xaa, 0x86, 0xaf, 0x76, 0xad, 0x54, 0x8f, 0x61, 0x81, 0x2e, 0x7f, 0xe7, - 0x31, 0x86, 0x69, 0xb5, 0xbc, 0x4e, 0x51, 0xec, 0x40, 0x1c, 0x9a, 0x8a, - 0x1e, 0x5e, 0x93, 0xe4, 0xb7, 0x47, 0x68, 0x3a, 0x08, 0x67, 0x44, 0x52, - 0xf0, 0xdc, 0x39, 0xf8, 0x3d, 0xc9, 0x4e, 0xda, 0xaa, 0xbb, 0x99, 0xf6, - 0x1e, 0x3e, 0xdc, 0xdd, 0xdb, 0xde, 0x41, 0xd0, 0xe0, 0x2d, 0xd0, 0x5b, - 0x57, 0x0d, 0x79, 0xd6, 0x85, 0x92, 0x88, 0xe7, 0x71, 0xdd, 0xab, 0xae, - 0x06, 0xee, 0x32, 0x43, 0x42, 0x7f, 0x0a, 0xeb, 0xfc, 0xad, 0x09, 0x94, - 0x1a, 0xdf, 0x4b, 0x45, 0x3f, 0xc4, 0xb6, 0x03, 0xe4, 0x14, 0xb2, 0x15, - 0x1c, 0x34, 0x0c, 0x13, 0x16, 0xe1, 0x97, 0x30, 0xa2, 0x80, 0xc1, 0x0e, - 0x04, 0x4c, 0x87, 0xbc, 0x4e, 0x04, 0x0d, 0xab, 0xd2, 0x74, 0x05, 0x05, - 0xb0, 0x21, 0xcf, 0x09, 0x5b, 0x8b, 0x14, 0x1d, 0xe1, 0x82, 0xeb, 0x17, - 0x24, 0xf3, 0x59, 0xdf, 0xe0, 0x11, 0xcd, 0x98, 0xa2, 0xef, 0x41, 0x7f, - 0x5b, 0x49, 0x84, 0xea, 0x43, 0x8a, 0x6f, 0xe8, 0x46, 0x6c, 0x00, 0x51, - 0xa5, 0x5a, 0x39, 0xb2, 0x88, 0x28, 0x61, 0xd3, 0xd3, 0xf9, 0xf1, 0x85, - 0xc0, 0x88, 0x6d, 0x7b, 0x16, 0xb5, 0x0b, 0x44, 0xdf, 0x0d, 0x28, 0x15, - 0x0f, 0x3f, 0x7c, 0x30, 0x76, 0x19, 0x94, 0x1e, 0x2e, 0x85, 0x21, 0x42, - 0xe0, 0xc3, 0xad, 0x27, 0xdd, 0xe4, 0xe1, 0xce, 0x57, 0x5d, 0xcc, 0x86, - 0xe9, 0x62, 0x7a, 0xcd, 0x0e, 0xfe, 0xba, 0x8b, 0x0f, 0x3d, 0xda, 0x7a, - 0x18, 0x5e, 0xd5, 0xbb, 0x6f, 0x98, 0x45, 0x41, 0x9f, 0x1a, 0x4a, 0x9b, - 0x9e, 0x17, 0xec, 0xc6, 0xe5, 0xfd, 0x81, 0xf1, 0x44, 0xcb, 0xc9, 0x29, - 0x30, 0x1c, 0x46, 0x4d, 0xf1, 0xfb, 0x1c, 0x65, 0x1a, 0x6e, 0x05, 0x0a, - 0xad, 0x50, 0x77, 0x04, 0xfe, 0x52, 0x5f, 0x02, 0x7d, 0x50, 0x5e, 0x98, - 0xac, 0x10, 0x85, 0x12, 0x16, 0x73, 0x8a, 0x24, 0x64, 0x35, 0x3a, 0x67, - 0x04, 0xb5, 0x60, 0xf5, 0xe5, 0x00, 0xdc, 0x1c, 0x23, 0x72, 0x53, 0x2a, - 0xa2, 0xb7, 0x8d, 0x6b, 0x4e, 0x4c, 0x4e, 0xcb, 0xc0, 0x73, 0x08, 0x47, - 0x99, 0x4d, 0x28, 0x1e, 0x87, 0xc3, 0x4d, 0x1d, 0x58, 0x56, 0x66, 0xeb, - 0x55, 0x07, 0x27, 0x99, 0x8c, 0xa0, 0x4f, 0x9c, 0x59, 0x6c, 0x09, 0x51, - 0x2c, 0xa4, 0xdc, 0xba, 0x43, 0x35, 0x25, 0x07, 0x28, 0x79, 0x60, 0x3e, - 0x30, 0x5d, 0x82, 0x81, 0x23, 0xc0, 0x64, 0x8c, 0xf0, 0x49, 0xc7, 0x17, - 0x45, 0x09, 0xfb, 0x36, 0xe9, 0x3b, 0xe4, 0x5f, 0x6d, 0x6f, 0x92, 0x7e, - 0x60, 0xf3, 0x31, 0xde, 0xde, 0x14, 0x7f, 0xe9, 0x70, 0x9f, 0x8a, 0x5a, - 0x0e, 0xa7, 0x05, 0xa9, 0x33, 0xdb, 0xe0, 0xe1, 0x79, 0xd1, 0x9a, 0xa2, - 0xdc, 0x73, 0x8b, 0xb3, 0xa0, 0x69, 0xbc, 0xa1, 0x0e, 0xf6, 0xf1, 0x4e, - 0xd8, 0x73, 0xe9, 0x28, 0x12, 0xea, 0x87, 0xb2, 0x03, 0xed, 0xcc, 0x75, - 0x6a, 0x18, 0x97, 0x99, 0x96, 0xbd, 0xc5, 0x8a, 0x01, 0x6a, 0x22, 0x66, - 0x3d, 0xc2, 0x47, 0x3f, 0xe3, 0x86, 0x87, 0x04, 0x43, 0xe4, 0x50, 0x8f, - 0x29, 0xc3, 0xd0, 0x25, 0xdc, 0xd1, 0x33, 0x9f, 0x23, 0xa5, 0x82, 0x1a, - 0xfe, 0x72, 0x55, 0xb9, 0xd8, 0xaf, 0x70, 0xcc, 0x51, 0xd0, 0xf5, 0xc2, - 0x16, 0xd9, 0x4a, 0x2d, 0xeb, 0xd8, 0x32, 0xda, 0xcd, 0x80, 0xf7, 0xb3, - 0x5d, 0xb7, 0x19, 0x6d, 0x4c, 0x3c, 0xb3, 0x2e, 0x40, 0x4c, 0xc7, 0x7b, - 0xdc, 0x47, 0x38, 0xf7, 0x97, 0x00, 0x75, 0x73, 0x68, 0x4c, 0x35, 0xce, - 0x86, 0x17, 0xd9, 0x65, 0x3a, 0x99, 0x64, 0x65, 0x87, 0xc8, 0x4c, 0x43, - 0xa7, 0xfb, 0x58, 0x5f, 0x82, 0x4c, 0x1b, 0xe6, 0x5b, 0x8d, 0x00, 0x97, - 0x31, 0x9a, 0x44, 0xef, 0xf1, 0x64, 0x5d, 0x4a, 0x13, 0x90, 0x59, 0x85, - 0x56, 0x9e, 0x90, 0x98, 0x70, 0x65, 0xca, 0xc1, 0x06, 0x7b, 0x75, 0xa9, - 0x10, 0x22, 0x12, 0xa8, 0xf1, 0xf9, 0x60, 0x61, 0xc1, 0x2b, 0xca, 0x42, - 0x90, 0xf8, 0x66, 0xc6, 0x6b, 0xd5, 0xaa, 0x6f, 0x17, 0x94, 0x20, 0xa6, - 0xe5, 0x59, 0x92, 0xe1, 0x1c, 0x23, 0x75, 0xac, 0x82, 0x18, 0xe7, 0x69, - 0xfa, 0xe1, 0xb2, 0xcc, 0xa5, 0x97, 0x2b, 0x11, 0x03, 0x19, 0xef, 0x51, - 0x1f, 0x23, 0x0b, 0x77, 0x5f, 0x5c, 0xc7, 0x5c, 0x7c, 0x56, 0x47, 0x04, - 0xa7, 0x8f, 0xb4, 0x36, 0x38, 0x19, 0x97, 0xc0, 0x09, 0xc6, 0xa2, 0xf9, - 0x51, 0x4a, 0x00, 0x8c, 0x2e, 0x54, 0xa1, 0xa0, 0xfb, 0x88, 0xe0, 0x37, - 0x92, 0x6a, 0x50, 0xe6, 0x33, 0x02, 0x02, 0x45, 0xc0, 0xd2, 0xac, 0x51, - 0xfa, 0x58, 0xd7, 0x84, 0xe0, 0x46, 0x16, 0x62, 0x88, 0xc8, 0xd6, 0x66, - 0x71, 0x3f, 0x13, 0x50, 0x55, 0x2d, 0xe1, 0x6c, 0x11, 0x96, 0x4a, 0xb8, - 0x19, 0x1a, 0xd9, 0x2d, 0x8c, 0x6a, 0x9c, 0xbe, 0xbf, 0x71, 0x02, 0x0f, - 0x82, 0xea, 0x8c, 0x31, 0x02, 0xc1, 0x25, 0xa5, 0xe0, 0xab, 0x97, 0xac, - 0x17, 0xdf, 0x88, 0x97, 0x54, 0xe2, 0xfa, 0xbb, 0x41, 0xd8, 0xae, 0x1d, - 0x82, 0xa4, 0xbd, 0xc8, 0x11, 0x5c, 0xcd, 0x35, 0x74, 0x4b, 0xe8, 0x4d, - 0x85, 0x5d, 0x5d, 0x41, 0xba, 0x88, 0x2c, 0xfe, 0x5e, 0xee, 0x2f, 0x4e, - 0xae, 0x56, 0xef, 0x02, 0xeb, 0xf0, 0x2a, 0xe7, 0xc8, 0x8c, 0x1a, 0x49, - 0xa0, 0x01, 0x23, 0x89, 0x52, 0xc4, 0x60, 0x42, 0x12, 0x9b, 0x90, 0x48, - 0x55, 0x12, 0xf5, 0xc7, 0xb0, 0x23, 0xe8, 0x05, 0xb0, 0x20, 0x8a, 0xc8, - 0xd0, 0x12, 0xeb, 0x66, 0x16, 0xa8, 0xcb, 0x39, 0xc3, 0xc0, 0x50, 0xaf, - 0x6e, 0x3a, 0x5c, 0xd0, 0x29, 0xf9, 0x1f, 0xc9, 0x2c, 0x47, 0x14, 0x68, - 0x98, 0xcb, 0xb7, 0x06, 0xdb, 0xc5, 0x0c, 0x9a, 0x6c, 0xb8, 0x0e, 0x96, - 0x0b, 0xd1, 0x7b, 0x93, 0x9f, 0x32, 0xb4, 0x09, 0x80, 0xe8, 0x89, 0xa1, - 0xc0, 0xf3, 0x0b, 0xaa, 0x78, 0xef, 0xad, 0xc7, 0x38, 0x8d, 0x2a, 0x93, - 0x7a, 0x42, 0x68, 0x99, 0xd5, 0x81, 0x5e, 0xe5, 0xa9, 0x36, 0x24, 0x32, - 0x5f, 0x4e, 0x10, 0x16, 0xe7, 0x1a, 0x74, 0xe8, 0xe2, 0x64, 0x2c, 0x74, - 0x8c, 0x13, 0x35, 0xa8, 0x7d, 0x3a, 0x3b, 0x7c, 0x08, 0x94, 0xee, 0xf5, - 0x18, 0xf0, 0x09, 0x58, 0x02, 0x2f, 0x14, 0x6c, 0x94, 0x2c, 0x84, 0xe8, - 0xad, 0x4d, 0x72, 0x5a, 0x43, 0x56, 0x9e, 0xaa, 0xe5, 0x78, 0xf1, 0xa6, - 0x16, 0x97, 0x29, 0x57, 0x7f, 0x62, 0x44, 0x45, 0xbe, 0xb6, 0xa9, 0x39, - 0x12, 0xa1, 0x23, 0x97, 0x8d, 0xe3, 0xde, 0x01, 0x5d, 0x8a, 0x69, 0x46, - 0x49, 0x86, 0xdc, 0x83, 0x01, 0x6a, 0x88, 0x6f, 0x89, 0x87, 0x70, 0xd3, - 0x83, 0x0e, 0x00, 0x0f, 0xce, 0x29, 0x92, 0x93, 0x2f, 0x64, 0x1d, 0x11, - 0xe6, 0x88, 0x62, 0xa4, 0xe0, 0x1c, 0x25, 0x6d, 0x59, 0x0c, 0xb9, 0xb1, - 0xd5, 0xf3, 0x4b, 0xde, 0xb9, 0xa9, 0xf2, 0x49, 0x8e, 0x12, 0x0f, 0x6c, - 0xdf, 0x89, 0x98, 0xa1, 0xa2, 0xb4, 0x49, 0x3e, 0x58, 0xe6, 0x17, 0xc3, - 0xe2, 0x38, 0x1d, 0xa0, 0x61, 0x9f, 0x8d, 0x57, 0xc0, 0x91, 0x29, 0x09, - 0x43, 0x61, 0x2d, 0x2a, 0x3a, 0x58, 0xce, 0x46, 0x85, 0x23, 0x52, 0xc7, - 0xc6, 0x04, 0xf5, 0x27, 0x10, 0x86, 0xda, 0xa4, 0x99, 0x8a, 0x39, 0x5f, - 0x4a, 0x8b, 0x60, 0x01, 0x5c, 0xaa, 0x40, 0x97, 0x76, 0x0b, 0x8c, 0xc7, - 0xee, 0xce, 0x0c, 0x63, 0x33, 0x5d, 0x80, 0x69, 0x82, 0xe7, 0xc0, 0x23, - 0x02, 0x0e, 0x4d, 0x7d, 0xe2, 0x6a, 0x3e, 0xfa, 0xf0, 0x61, 0x23, 0x11, - 0xe1, 0x83, 0xc9, 0x2f, 0x0b, 0x46, 0x75, 0x76, 0xe1, 0xb5, 0xb8, 0x2b, - 0xe3, 0x7b, 0xe9, 0xbe, 0xca, 0x89, 0x34, 0xdb, 0x5d, 0xe5, 0x86, 0x7d, - 0xd4, 0x36, 0x9e, 0xd5, 0x6a, 0x86, 0x34, 0xab, 0x59, 0xeb, 0x05, 0xe9, - 0x2f, 0x5f, 0x94, 0xfa, 0x41, 0x69, 0x61, 0xa7, 0x19, 0x09, 0xf5, 0x71, - 0x24, 0x16, 0x3b, 0x83, 0x39, 0x9e, 0x09, 0xe5, 0x46, 0xfa, 0xa2, 0x72, - 0x5a, 0x56, 0x72, 0x88, 0xc0, 0x90, 0x6f, 0x0e, 0x9f, 0xbf, 0x3d, 0x3d, - 0x7c, 0x46, 0xe9, 0x65, 0x69, 0x93, 0x56, 0xf8, 0x04, 0xd6, 0x45, 0x41, - 0x87, 0x50, 0xc7, 0x71, 0xfb, 0x9d, 0x1e, 0x05, 0x02, 0xc8, 0x0b, 0x8b, - 0x5b, 0xe4, 0x46, 0xbf, 0x04, 0x12, 0xf2, 0x63, 0x73, 0x49, 0x9a, 0xcd, - 0xae, 0xb0, 0x45, 0xd1, 0x28, 0x3e, 0x45, 0x30, 0x8a, 0x52, 0x7c, 0x22, - 0xea, 0xf0, 0x3b, 0xc5, 0xf2, 0xee, 0x53, 0xc9, 0x70, 0xfb, 0x36, 0x04, - 0x92, 0x68, 0x02, 0xe7, 0x38, 0xcb, 0x66, 0x72, 0xb7, 0xa5, 0x13, 0x60, - 0x27, 0x6c, 0x63, 0x63, 0xc3, 0x84, 0x6a, 0x4c, 0x14, 0x28, 0x24, 0x57, - 0x6b, 0x84, 0xfc, 0x66, 0x7c, 0x0c, 0xd7, 0x4d, 0xae, 0x28, 0x31, 0x28, - 0x34, 0x37, 0x72, 0x1d, 0xeb, 0x6d, 0x8b, 0x67, 0xce, 0xc3, 0xc8, 0xca, - 0x95, 0x28, 0xb2, 0x36, 0xf7, 0x6b, 0x12, 0xb7, 0x03, 0xc6, 0x15, 0xf6, - 0xb3, 0xb1, 0x90, 0x88, 0x99, 0x4b, 0xaa, 0xb2, 0x2b, 0x8a, 0x95, 0x09, - 0x0a, 0xdd, 0xc8, 0xd6, 0x8a, 0x54, 0x1e, 0xca, 0xa0, 0xa1, 0xed, 0x71, - 0x2a, 0x1f, 0xbe, 0xce, 0x8b, 0x84, 0x74, 0xfb, 0xf7, 0xac, 0xb4, 0x6c, - 0xd0, 0xa0, 0xfa, 0x89, 0x70, 0xe7, 0xb0, 0x6f, 0x75, 0xbc, 0x34, 0x60, - 0xab, 0x88, 0x1c, 0xa9, 0x18, 0x9f, 0x0b, 0x7a, 0xde, 0x77, 0xf2, 0xe8, - 0x93, 0x28, 0xa7, 0x41, 0x22, 0xa6, 0xc2, 0x34, 0xa8, 0x84, 0xe3, 0x4b, - 0x69, 0xf5, 0xf0, 0xeb, 0x52, 0x21, 0x05, 0xc8, 0xb9, 0xd3, 0x80, 0x1a, - 0x44, 0x6d, 0xd1, 0xdd, 0x6a, 0x22, 0x93, 0xf5, 0x83, 0x68, 0x4e, 0xee, - 0xa8, 0x32, 0xe3, 0x98, 0xc8, 0x94, 0x4c, 0x47, 0xe8, 0x96, 0x5d, 0x47, - 0xc0, 0x20, 0x19, 0xc8, 0x06, 0x7d, 0x4e, 0x06, 0x2b, 0x89, 0x44, 0x94, - 0x6e, 0x5d, 0xcc, 0xb4, 0xaa, 0x8a, 0xea, 0x7b, 0xe6, 0x40, 0x38, 0xd2, - 0xbb, 0x60, 0x17, 0xe0, 0x4a, 0xcc, 0x07, 0x76, 0x0b, 0x4b, 0x26, 0x04, - 0x37, 0x22, 0xbc, 0xd7, 0xc4, 0x14, 0x6e, 0x84, 0x51, 0xdd, 0x26, 0x98, - 0xac, 0x2a, 0x3e, 0x91, 0xe0, 0xe7, 0x22, 0x00, 0x5e, 0xc6, 0x44, 0x44, - 0xb7, 0xba, 0x9a, 0x1f, 0x80, 0x6a, 0xba, 0x21, 0x2c, 0x14, 0xe5, 0x0d, - 0xc2, 0x8a, 0xa4, 0x71, 0x6b, 0x72, 0x32, 0x53, 0x15, 0x8f, 0x8d, 0x29, - 0x1a, 0x5e, 0xce, 0x8b, 0x21, 0xc1, 0x15, 0x72, 0x87, 0xa1, 0x20, 0x66, - 0xc0, 0x33, 0x85, 0x9e, 0xd7, 0xaa, 0x90, 0xfa, 0x9d, 0x63, 0xa8, 0x27, - 0x07, 0xff, 0x9a, 0x0e, 0x24, 0xa9, 0x63, 0x81, 0x05, 0x02, 0xd1, 0x22, - 0xcd, 0x86, 0xd0, 0x59, 0x12, 0xaf, 0xd4, 0x9e, 0xe6, 0x54, 0x61, 0x4f, - 0xa1, 0xb6, 0xe3, 0x9f, 0xd5, 0x2f, 0x12, 0xf5, 0xb4, 0xbb, 0x65, 0xa4, - 0xba, 0xbd, 0xf5, 0x29, 0xb4, 0x5a, 0xa5, 0x5c, 0xbb, 0xea, 0xf2, 0xef, - 0xf9, 0x30, 0x79, 0xaa, 0x05, 0x35, 0x1d, 0x96, 0xb7, 0x42, 0x67, 0xc3, - 0x23, 0xc0, 0x3c, 0xfe, 0x2e, 0xe2, 0xa2, 0x3e, 0x08, 0x97, 0xbb, 0xbc, - 0x8c, 0x9a, 0x96, 0x44, 0x31, 0x25, 0xa7, 0xfb, 0x08, 0x3b, 0x73, 0xf2, - 0x72, 0xff, 0xe8, 0xb5, 0x65, 0xb1, 0x39, 0xcc, 0xfc, 0xae, 0x94, 0xfe, - 0xb1, 0xab, 0x8d, 0x6b, 0xf0, 0x71, 0x5c, 0x41, 0xa3, 0x26, 0x8f, 0xf5, - 0x24, 0x3e, 0x44, 0xfc, 0x7e, 0x00, 0xbd, 0x91, 0x8a, 0xe6, 0xc1, 0x91, - 0x7a, 0x5a, 0x42, 0x37, 0xca, 0xd7, 0x89, 0x2b, 0x05, 0x7a, 0x4c, 0xf1, - 0x08, 0x00, 0x04, 0xee, 0xce, 0x5c, 0x21, 0x98, 0x12, 0x99, 0x50, 0x54, - 0x35, 0x34, 0x4b, 0xa4, 0xe3, 0x2e, 0x17, 0x66, 0x40, 0x89, 0xd3, 0x35, - 0x46, 0x89, 0xb6, 0x86, 0x5e, 0x61, 0xd1, 0x41, 0xdc, 0xbc, 0x70, 0xd0, - 0xa8, 0x4a, 0x20, 0x1b, 0xd7, 0x04, 0x53, 0x51, 0x6f, 0xdb, 0x44, 0x51, - 0x0a, 0xd5, 0x26, 0x4e, 0x70, 0x6e, 0x6b, 0x14, 0x9a, 0x72, 0x5e, 0x7c, - 0xe8, 0xba, 0x28, 0x43, 0x83, 0x88, 0xb3, 0x98, 0xd0, 0x0b, 0xe0, 0x12, - 0xa4, 0x5a, 0x28, 0xd2, 0x61, 0xc1, 0xc5, 0x5e, 0xb1, 0x9e, 0x2b, 0x42, - 0x1f, 0x4d, 0xe0, 0x1a, 0x81, 0x46, 0x04, 0x27, 0x4c, 0x60, 0x5a, 0x89, - 0x4a, 0xd8, 0x17, 0x1d, 0x11, 0xc2, 0x2a, 0x26, 0x8a, 0x4f, 0xaa, 0x69, - 0x19, 0xf5, 0x42, 0x3d, 0x4d, 0xd2, 0x25, 0xbe, 0x66, 0x27, 0x3c, 0xa1, - 0x21, 0x25, 0xce, 0xc8, 0x2d, 0x2e, 0xf2, 0x69, 0x2f, 0xc4, 0xab, 0x38, - 0x5a, 0xce, 0x65, 0x76, 0x87, 0x53, 0x89, 0x67, 0x54, 0x10, 0x5b, 0x27, - 0xb7, 0x12, 0xf9, 0x31, 0x91, 0x36, 0xeb, 0x47, 0xb4, 0x61, 0x5d, 0x4b, - 0xbb, 0x2b, 0x0a, 0x9e, 0x2d, 0xa1, 0x94, 0x4d, 0xac, 0x6b, 0x69, 0x70, - 0x85, 0xa5, 0xca, 0xcb, 0x5b, 0x56, 0xc8, 0x57, 0xa0, 0x73, 0xeb, 0x1a, - 0xd6, 0xe3, 0xae, 0xb2, 0xa8, 0x56, 0x17, 0x55, 0x92, 0x9d, 0xac, 0x2e, - 0x6a, 0x5f, 0x02, 0x14, 0x16, 0x6a, 0x9d, 0x7e, 0x9e, 0x42, 0x05, 0x51, - 0x37, 0x08, 0x2b, 0x3f, 0xdc, 0x94, 0x93, 0xb9, 0x12, 0x47, 0x0b, 0xf5, - 0xd3, 0xef, 0xaa, 0x6d, 0x7e, 0x4a, 0xb8, 0xf5, 0x97, 0xc5, 0xb5, 0x0f, - 0x1e, 0x25, 0x35, 0x2d, 0xe4, 0xf2, 0xc2, 0x03, 0x18, 0xb4, 0xce, 0x81, - 0x4b, 0x4e, 0x5c, 0xc1, 0xd7, 0x42, 0xc0, 0x26, 0xcc, 0xb7, 0x22, 0xd8, - 0x3d, 0xe0, 0x04, 0x7a, 0x6b, 0x11, 0x06, 0xee, 0xe7, 0x4e, 0xc9, 0xf7, - 0x72, 0x77, 0x98, 0x49, 0x72, 0x3f, 0x12, 0x77, 0x68, 0xf0, 0x8e, 0x0d, - 0x0b, 0x1d, 0xeb, 0x72, 0xad, 0xb8, 0x55, 0x04, 0xf4, 0x7e, 0x41, 0x38, - 0xf3, 0x93, 0xac, 0x0e, 0x49, 0xaf, 0x55, 0xd7, 0x5a, 0x92, 0x97, 0xb8, - 0x55, 0x32, 0xbf, 0xfd, 0x6d, 0x9e, 0x33, 0x50, 0xc3, 0x10, 0x85, 0x42, - 0x35, 0xb6, 0xf1, 0x8e, 0x24, 0xda, 0x1e, 0x05, 0x33, 0x0a, 0x22, 0x97, - 0x0f, 0xe9, 0x95, 0x9d, 0x82, 0xcb, 0x9a, 0x03, 0xbd, 0x0f, 0x70, 0x0a, - 0x93, 0x39, 0x62, 0x8f, 0x1c, 0x61, 0x23, 0x54, 0x41, 0x84, 0x0d, 0x25, - 0x82, 0xc1, 0x87, 0xc6, 0x1a, 0xad, 0x7b, 0x8a, 0xbb, 0xa1, 0xc0, 0xce, - 0x45, 0xcd, 0x26, 0x6c, 0x50, 0xff, 0xc9, 0xd9, 0x29, 0xce, 0x5a, 0xe8, - 0x14, 0xc4, 0x97, 0x74, 0xbc, 0x59, 0xd5, 0x43, 0x94, 0x0e, 0x5c, 0x0a, - 0x66, 0x30, 0xb7, 0x98, 0x5f, 0xf5, 0x2d, 0x49, 0x1e, 0x6e, 0x01, 0x29, - 0xb2, 0x38, 0x56, 0xf2, 0x9c, 0xb5, 0x14, 0x3e, 0x30, 0x7b, 0xba, 0xce, - 0xd4, 0x8a, 0x46, 0xc1, 0x6c, 0xf1, 0x32, 0xe2, 0x29, 0xf0, 0x72, 0x44, - 0xd4, 0x59, 0xf5, 0x63, 0x55, 0x5a, 0x76, 0xca, 0x68, 0xc5, 0x49, 0x24, - 0x77, 0xa2, 0xf6, 0x2f, 0x90, 0x0a, 0xb5, 0x75, 0x2b, 0x99, 0x54, 0xab, - 0xd1, 0x04, 0x06, 0xbc, 0x14, 0x15, 0xe5, 0xf6, 0xc3, 0x0a, 0xc2, 0x04, - 0xe4, 0x18, 0x2f, 0xa5, 0x15, 0xae, 0x3c, 0xf1, 0x70, 0x59, 0xf5, 0x91, - 0x05, 0x0f, 0xfa, 0xe9, 0xf1, 0xc1, 0x9f, 0x4e, 0x1f, 0x26, 0x0b, 0xc5, - 0x47, 0x7e, 0x7f, 0xf5, 0x11, 0x0e, 0xf5, 0x10, 0x48, 0x0e, 0x18, 0x14, - 0x85, 0xea, 0x63, 0x61, 0x37, 0xe4, 0x1b, 0xce, 0x0f, 0xe1, 0xbd, 0xb7, - 0xe6, 0x51, 0xd5, 0xba, 0x46, 0xea, 0x23, 0x53, 0x27, 0x7b, 0x61, 0x94, - 0xa5, 0x95, 0x0a, 0xac, 0x0a, 0x84, 0xe4, 0xe2, 0x72, 0xb1, 0x83, 0x82, - 0x72, 0xe8, 0xe6, 0xd3, 0xfc, 0x03, 0x70, 0x14, 0x74, 0xe4, 0xc8, 0x10, - 0x58, 0xba, 0xa5, 0x50, 0x75, 0xf2, 0x98, 0x13, 0x3f, 0xc1, 0xdf, 0x84, - 0x8e, 0xb3, 0xfe, 0x45, 0x3f, 0xe9, 0xf0, 0x1a, 0xc2, 0xde, 0xd8, 0x83, - 0x9b, 0x18, 0x61, 0xb5, 0x59, 0x17, 0x9b, 0xdc, 0x4c, 0x1f, 0xff, 0xe9, - 0xb4, 0x59, 0xf0, 0x31, 0x5b, 0xab, 0xa4, 0xb2, 0x41, 0xe4, 0x10, 0x36, - 0x2c, 0x02, 0xcd, 0x40, 0x0d, 0x35, 0x54, 0x58, 0xe1, 0xb8, 0x21, 0x38, - 0x32, 0xcd, 0x48, 0xc0, 0xb8, 0x51, 0x3c, 0x41, 0x1f, 0x06, 0xe3, 0x79, - 0x05, 0x52, 0xd7, 0x12, 0x86, 0x89, 0x89, 0xb4, 0xa0, 0x1a, 0x8c, 0xe7, - 0xd8, 0xb2, 0x33, 0x45, 0xa2, 0xbb, 0xd6, 0x6a, 0x90, 0xa6, 0x89, 0x90, - 0x82, 0xaf, 0xbc, 0xe2, 0xab, 0xed, 0x59, 0xd5, 0x4e, 0x9b, 0x6e, 0x88, - 0x32, 0x61, 0xff, 0x70, 0x40, 0xbd, 0xd4, 0x12, 0x26, 0x51, 0x2e, 0x1c, - 0xe5, 0x01, 0x58, 0x0a, 0x34, 0x51, 0x92, 0xd6, 0xe0, 0x10, 0x31, 0x2c, - 0x24, 0x65, 0x98, 0x62, 0xca, 0x65, 0x4d, 0xc2, 0x95, 0x22, 0x15, 0x4f, - 0x36, 0xe3, 0x62, 0xd6, 0x53, 0x31, 0xb9, 0x51, 0x20, 0x80, 0x42, 0x2c, - 0x91, 0xce, 0x67, 0xf8, 0x1f, 0xec, 0x95, 0x17, 0x6a, 0x88, 0x3b, 0x57, - 0x67, 0x61, 0x78, 0x6c, 0x5d, 0x2b, 0x87, 0xd0, 0x83, 0x1b, 0x41, 0x77, - 0xb1, 0xc0, 0x4f, 0x24, 0x84, 0x68, 0x0c, 0x72, 0xcb, 0xf3, 0x1a, 0xde, - 0x06, 0x01, 0xf9, 0x91, 0x88, 0x0d, 0xcd, 0xeb, 0x82, 0x3b, 0x50, 0xca, - 0xdf, 0x7b, 0xb8, 0xf5, 0xd5, 0xe3, 0x15, 0x4b, 0x25, 0xd3, 0x9b, 0xe9, - 0x42, 0xb9, 0x19, 0xfe, 0xa3, 0xa7, 0x2d, 0x36, 0x38, 0x43, 0x7a, 0x2b, - 0x6b, 0x58, 0xe0, 0x0c, 0xe9, 0xef, 0x61, 0x0d, 0x9e, 0x37, 0x18, 0x73, - 0x10, 0xee, 0xc0, 0x16, 0x15, 0xb8, 0x46, 0xaa, 0xc4, 0x97, 0x8d, 0xd1, - 0x7d, 0x69, 0xe3, 0x0a, 0x9f, 0xf5, 0xb4, 0xa7, 0xff, 0xeb, 0x1e, 0x77, - 0x7f, 0xda, 0xe5, 0xb8, 0x5b, 0x74, 0x4f, 0x38, 0x7f, 0xba, 0xbd, 0x2b, - 0x1e, 0xf7, 0xf4, 0x5f, 0x71, 0xde, 0xb5, 0x6b, 0x0b, 0xdc, 0x89, 0xdc, - 0x19, 0x9b, 0x8d, 0xf3, 0x36, 0x55, 0x0f, 0xa3, 0x3f, 0xf5, 0x9a, 0x5f, - 0x8a, 0xe6, 0x1e, 0x3b, 0xce, 0x01, 0x27, 0x86, 0x47, 0xa1, 0x35, 0x87, - 0xa4, 0x86, 0x95, 0x3f, 0xf9, 0x76, 0xf4, 0xe5, 0xfc, 0xf0, 0xf9, 0xb7, - 0xf7, 0xd9, 0x1a, 0xdf, 0x7a, 0xf8, 0xdd, 0x91, 0xf9, 0x8c, 0xe2, 0xbd, - 0xf4, 0xf0, 0xc9, 0xe7, 0xff, 0xe3, 0x8e, 0xff, 0xa3, 0xdb, 0xca, 0x92, - 0x85, 0xc3, 0x4f, 0xab, 0xf4, 0x48, 0x96, 0xb5, 0x47, 0x82, 0x54, 0xeb, - 0x35, 0xcd, 0x67, 0x6b, 0x7c, 0x13, 0xa7, 0x3e, 0xfb, 0x50, 0xc7, 0xbc, - 0x6a, 0x1a, 0x17, 0x56, 0x28, 0x58, 0xf6, 0x19, 0xce, 0xf7, 0xa3, 0xff, - 0x33, 0x6e, 0xf3, 0x47, 0x2b, 0x1e, 0xef, 0x47, 0xff, 0xb7, 0x9f, 0x6e, - 0x7f, 0xaf, 0x47, 0x15, 0x48, 0x97, 0x55, 0x79, 0x75, 0x65, 0x5e, 0xd9, - 0xe9, 0xf6, 0x9c, 0xca, 0x8a, 0xc2, 0xeb, 0x2f, 0x9f, 0xed, 0x9f, 0xc4, - 0x1c, 0xe1, 0xd1, 0xe7, 0x33, 0xb5, 0x4b, 0xfb, 0x3c, 0x58, 0x39, 0xfe, - 0x7b, 0x5f, 0x22, 0xf2, 0xde, 0xea, 0x3c, 0x21, 0x1c, 0x7e, 0xcf, 0x12, - 0x1e, 0xa6, 0x0d, 0x56, 0xd0, 0x3b, 0x4f, 0x2b, 0x2d, 0xc7, 0x85, 0x2c, - 0x40, 0x2b, 0x70, 0x6e, 0x86, 0xf2, 0xb8, 0x0d, 0x83, 0x23, 0xc7, 0xc8, - 0x09, 0x62, 0x36, 0xc5, 0x55, 0x91, 0xab, 0x9e, 0xb9, 0x85, 0x93, 0xf0, - 0xfa, 0x56, 0x93, 0xe1, 0xd6, 0xf6, 0x10, 0x26, 0x42, 0xc0, 0xff, 0x5c, - 0xd4, 0x4a, 0x3f, 0xd2, 0x05, 0x79, 0xa4, 0x17, 0xa0, 0xb2, 0xcd, 0x72, - 0x26, 0x0c, 0x38, 0xe4, 0x78, 0x42, 0x7e, 0x38, 0x3d, 0xed, 0xed, 0x9f, - 0x1c, 0x2d, 0x5a, 0x45, 0xf1, 0x99, 0xe6, 0x88, 0xc8, 0x1e, 0x1d, 0xa5, - 0x78, 0xfb, 0x25, 0xf8, 0x38, 0x84, 0xb7, 0x15, 0xb6, 0x4f, 0x9a, 0xb5, - 0xdd, 0xfc, 0x54, 0xe6, 0xfe, 0xa8, 0xb9, 0x63, 0xbc, 0x0e, 0x61, 0x81, - 0x74, 0x11, 0x1a, 0x6b, 0xd0, 0xbe, 0x4f, 0x9e, 0xa9, 0x7b, 0x18, 0xcd, - 0x25, 0x8d, 0xb4, 0xef, 0x4e, 0xb2, 0x9e, 0x07, 0x70, 0x4c, 0x0a, 0x8e, - 0x09, 0x61, 0x2f, 0x82, 0xd7, 0x63, 0x3b, 0x63, 0x80, 0x3f, 0x1b, 0x7d, - 0x13, 0x32, 0x17, 0xd7, 0x5e, 0x2c, 0xdc, 0xbc, 0xaf, 0x66, 0xd6, 0x69, - 0x50, 0xce, 0x2d, 0xbb, 0xec, 0x76, 0xb8, 0xcd, 0x3e, 0x19, 0x11, 0xd0, - 0x32, 0x2b, 0x65, 0x43, 0xb5, 0xf7, 0x66, 0x4a, 0x31, 0xd2, 0x37, 0x35, - 0x7c, 0xdf, 0xec, 0x4a, 0x24, 0x21, 0x23, 0xf8, 0x5c, 0x34, 0xd1, 0x83, - 0xbd, 0x16, 0xdb, 0x70, 0x25, 0xf8, 0x36, 0x06, 0x8e, 0xed, 0xb6, 0xc4, - 0x2a, 0x34, 0x93, 0xff, 0x80, 0x85, 0xc5, 0x3a, 0x13, 0xa8, 0x07, 0xaa, - 0xf3, 0x12, 0x58, 0x9b, 0x99, 0x0e, 0xb1, 0x42, 0x07, 0xd5, 0x77, 0xda, - 0xfe, 0xea, 0x31, 0xe6, 0x96, 0xa6, 0x37, 0x8c, 0xcd, 0x8a, 0x11, 0x9a, - 0xfc, 0xe6, 0xc3, 0xfe, 0xee, 0xe6, 0xc3, 0xfe, 0x43, 0x36, 0xeb, 0x6a, - 0x76, 0x83, 0x85, 0x6f, 0x49, 0x1f, 0x12, 0xd9, 0x24, 0x43, 0x7a, 0x7d, - 0x78, 0x90, 0x30, 0x06, 0x0b, 0x95, 0x23, 0x8d, 0x5d, 0x00, 0x8e, 0x27, - 0x7b, 0x4a, 0x15, 0x86, 0xdd, 0x32, 0x75, 0x29, 0x37, 0xc9, 0x4d, 0xcf, - 0xa7, 0xd6, 0x23, 0x5e, 0xbe, 0x9c, 0x00, 0x28, 0xa1, 0x9a, 0xd1, 0x88, - 0x78, 0x15, 0x64, 0xda, 0x6e, 0x69, 0x22, 0x4a, 0xba, 0x75, 0xb1, 0xef, - 0x17, 0x44, 0x60, 0xa1, 0x93, 0x8f, 0xa0, 0x2c, 0x5a, 0x85, 0xcf, 0x46, - 0x5d, 0x6a, 0x0c, 0x6f, 0x5a, 0xca, 0x15, 0xa1, 0x5b, 0xbe, 0x4e, 0xc4, - 0x5a, 0xae, 0xb9, 0x40, 0x09, 0x4b, 0x23, 0xae, 0x12, 0x1f, 0x56, 0xa4, - 0x90, 0xe0, 0xc4, 0x90, 0xa9, 0x31, 0x98, 0xa8, 0x51, 0xbb, 0x37, 0xfa, - 0xdb, 0x70, 0xda, 0x8f, 0xee, 0xda, 0xe6, 0x10, 0x3e, 0x9f, 0xff, 0xb0, - 0xbd, 0x3f, 0xb2, 0xb9, 0x7f, 0x86, 0x95, 0xb5, 0x3b, 0x7a, 0xb5, 0x42, - 0xc1, 0x9e, 0xd9, 0x91, 0x6b, 0x11, 0x23, 0xee, 0x03, 0xe4, 0x25, 0x7d, - 0xa8, 0x32, 0x7a, 0x20, 0x74, 0xed, 0x64, 0xa3, 0x1f, 0x09, 0xe7, 0x0d, - 0xe9, 0x7c, 0xb9, 0x78, 0x9e, 0x68, 0xf8, 0xd2, 0xbf, 0x46, 0x48, 0xbf, - 0xfc, 0xdf, 0x43, 0x09, 0x8f, 0x75, 0xf0, 0x86, 0x0a, 0xfe, 0x28, 0xac, - 0xba, 0x37, 0x7a, 0xdd, 0x22, 0xab, 0x5f, 0xfe, 0x5f, 0x2d, 0xac, 0x2f, - 0xd7, 0xc5, 0xdb, 0x94, 0x71, 0x77, 0x6e, 0x3e, 0xb3, 0x0c, 0x1e, 0x3a, - 0xfa, 0x7d, 0xc2, 0x78, 0xbb, 0x0c, 0xfe, 0x17, 0xd2, 0xdb, 0x67, 0x59, - 0x36, 0x64, 0x08, 0xe5, 0xe4, 0x29, 0xfd, 0xe1, 0x13, 0x56, 0x2c, 0xb6, - 0x05, 0xa9, 0x0f, 0x63, 0xf9, 0x03, 0x0e, 0xbd, 0x24, 0x8c, 0xd1, 0x2b, - 0x20, 0x91, 0x4d, 0xa5, 0x00, 0x89, 0x03, 0xe7, 0xde, 0xd0, 0xe4, 0x5b, - 0x74, 0x73, 0x73, 0x58, 0x48, 0xc0, 0xd8, 0x92, 0xa0, 0x1b, 0x3a, 0xec, - 0x54, 0xb4, 0x41, 0xeb, 0x40, 0x72, 0x69, 0x68, 0x17, 0x3e, 0x12, 0x00, - 0x48, 0x7d, 0x8a, 0x3f, 0x8f, 0x9b, 0x9f, 0x13, 0xec, 0x1e, 0xe4, 0xf1, - 0xbb, 0x5b, 0x89, 0xe1, 0x9a, 0x27, 0x91, 0x48, 0x9f, 0xf8, 0xd2, 0x3a, - 0x7e, 0xd6, 0x9f, 0xb5, 0xb4, 0x8e, 0xef, 0x68, 0x77, 0x6b, 0x2b, 0x1e, - 0xf8, 0xaa, 0x21, 0x21, 0xe1, 0x95, 0x6e, 0x1b, 0xdc, 0x75, 0x33, 0x55, - 0xe0, 0xa6, 0x1b, 0x77, 0xd3, 0x08, 0x70, 0x8a, 0x37, 0x16, 0x11, 0xd3, - 0xa3, 0xad, 0xf5, 0x23, 0x0e, 0x5b, 0xaa, 0x20, 0xee, 0x1c, 0x42, 0x22, - 0x02, 0x69, 0xe2, 0x37, 0x81, 0x37, 0xab, 0xdb, 0x28, 0x63, 0x4b, 0x06, - 0x56, 0xdd, 0xd9, 0x23, 0x8e, 0xca, 0xb0, 0x57, 0xfc, 0x32, 0x76, 0x23, - 0xe4, 0xaf, 0xc6, 0xfe, 0x6c, 0xab, 0xd3, 0xce, 0x00, 0xa0, 0xa3, 0x95, - 0x6d, 0x63, 0x97, 0x92, 0x24, 0x5d, 0xf9, 0xa4, 0x3f, 0xa2, 0xd2, 0x02, - 0xe9, 0x87, 0xdd, 0x7e, 0x18, 0x9d, 0xb0, 0x41, 0xf2, 0x60, 0x23, 0x5f, - 0x3c, 0xe5, 0xe2, 0x06, 0x15, 0x55, 0x9b, 0x30, 0xd6, 0x91, 0xd5, 0x03, - 0xb9, 0xc2, 0xa4, 0x3c, 0x2c, 0xe6, 0x9d, 0x01, 0x17, 0x2e, 0x05, 0xa2, - 0x0c, 0x98, 0x31, 0xcc, 0xa2, 0xbc, 0x71, 0x77, 0x9f, 0xcb, 0x14, 0xd3, - 0xd8, 0x24, 0xc5, 0x0d, 0x51, 0x8e, 0x12, 0xad, 0xc7, 0x67, 0x13, 0x2b, - 0xee, 0x8f, 0x0c, 0x25, 0x8e, 0x8b, 0x28, 0x2f, 0x90, 0x62, 0x90, 0x2c, - 0xaa, 0xb1, 0xab, 0xfc, 0x4b, 0x38, 0x0e, 0x84, 0x10, 0x41, 0x50, 0x0c, - 0x68, 0xc6, 0x00, 0x6e, 0xfb, 0x53, 0x5a, 0x62, 0x62, 0xe6, 0x9e, 0x85, - 0xe4, 0x6b, 0x80, 0x2c, 0xc1, 0xe8, 0x13, 0x3e, 0x43, 0x06, 0x03, 0xcf, - 0x62, 0x00, 0x5c, 0xcb, 0x8c, 0x16, 0x2c, 0x11, 0xec, 0x0a, 0x93, 0xc8, - 0x03, 0xca, 0xba, 0x78, 0xea, 0x11, 0x17, 0x4c, 0x22, 0x18, 0x67, 0x17, - 0x65, 0x3a, 0xd4, 0xf4, 0x50, 0xd2, 0x40, 0xb9, 0x65, 0x57, 0x73, 0xcb, - 0x88, 0xa7, 0xbc, 0x31, 0xa4, 0x0c, 0xac, 0xcb, 0xb5, 0x79, 0xf6, 0xf2, - 0x34, 0xe4, 0x21, 0x87, 0xe7, 0x11, 0xc5, 0x17, 0x18, 0x58, 0x4d, 0xa5, - 0x04, 0x08, 0xc8, 0x5c, 0x6a, 0x7d, 0x69, 0xb8, 0xde, 0xe9, 0xd9, 0xfe, - 0x9b, 0x33, 0x7c, 0x19, 0xc3, 0x35, 0xf0, 0x5f, 0x18, 0x14, 0x21, 0x87, - 0x58, 0xaa, 0x16, 0x82, 0xbe, 0x50, 0x5a, 0xb0, 0x95, 0xff, 0xc5, 0x68, - 0x41, 0xd8, 0x6d, 0x01, 0xd5, 0x49, 0x35, 0xa6, 0x6d, 0xda, 0x5b, 0x18, - 0x6e, 0xa3, 0x0a, 0xaf, 0x03, 0x02, 0x96, 0x1c, 0x4b, 0x19, 0x7a, 0x9f, - 0xb6, 0x4e, 0x41, 0x8d, 0x19, 0x83, 0xa9, 0x9e, 0xd1, 0x9a, 0x19, 0x7e, - 0x00, 0xb1, 0x4d, 0xb7, 0x8e, 0x52, 0xec, 0xd4, 0xb2, 0xab, 0x41, 0xb8, - 0xbb, 0xca, 0xc6, 0x55, 0x80, 0xbc, 0x07, 0x35, 0xa9, 0xbc, 0x99, 0xf9, - 0xd2, 0xe2, 0xc3, 0x65, 0x39, 0x44, 0x94, 0x24, 0x23, 0x49, 0x9d, 0xb8, - 0xed, 0x49, 0x9c, 0x7b, 0xf5, 0x64, 0x9b, 0xab, 0xbb, 0x1d, 0x31, 0xff, - 0xa5, 0xa0, 0x7d, 0xcd, 0x08, 0xd0, 0x4a, 0x1e, 0x52, 0xb8, 0x0f, 0x2b, - 0xb5, 0x51, 0x0b, 0x18, 0x7d, 0x9a, 0x69, 0xe0, 0xbf, 0x96, 0x8c, 0xd3, - 0x42, 0xa7, 0x58, 0x2d, 0x1d, 0x55, 0xf9, 0xf1, 0x30, 0x9d, 0x85, 0xe0, - 0xda, 0x2c, 0xd4, 0xfa, 0xe3, 0x1c, 0x1c, 0x3a, 0xe4, 0x99, 0x02, 0xb6, - 0xa5, 0x01, 0x31, 0x9a, 0x01, 0x5e, 0x28, 0x43, 0x46, 0xcb, 0x17, 0x87, - 0x1d, 0xcf, 0xbd, 0xe2, 0xe6, 0xf5, 0x57, 0xb7, 0xfa, 0x83, 0x41, 0xd6, - 0xbe, 0x1a, 0x98, 0xa0, 0x42, 0x35, 0xa1, 0x11, 0xf5, 0x02, 0x53, 0xd4, - 0xa6, 0x24, 0x04, 0xda, 0x7e, 0x08, 0xe8, 0x83, 0x3c, 0xcd, 0x62, 0x05, - 0xc8, 0x59, 0x0a, 0xba, 0x8d, 0xb1, 0x03, 0x2a, 0x72, 0x21, 0xab, 0xb2, - 0xbc, 0x24, 0xc9, 0x9d, 0x11, 0xb0, 0xd6, 0xd1, 0x9c, 0xf0, 0x91, 0x35, - 0x47, 0xbb, 0xcd, 0x0c, 0x51, 0x8d, 0xef, 0x80, 0x12, 0x6b, 0x8b, 0x90, - 0x12, 0x35, 0xb1, 0xa9, 0x25, 0x56, 0x77, 0xc0, 0x05, 0x62, 0x67, 0xb3, - 0x62, 0xb6, 0x7b, 0x77, 0x64, 0x94, 0x10, 0x1f, 0xde, 0x59, 0x7a, 0xee, - 0x85, 0xbb, 0x0c, 0xf2, 0xd9, 0x65, 0xe6, 0x42, 0xbb, 0xf1, 0x51, 0xd2, - 0xb1, 0x7b, 0xe7, 0x99, 0xd5, 0xd8, 0x59, 0x07, 0x5a, 0xdf, 0xc0, 0x98, - 0x93, 0x60, 0x3b, 0x4d, 0x4b, 0xca, 0x0f, 0xa1, 0xcd, 0x85, 0xe6, 0x30, - 0x0c, 0x72, 0x34, 0xc6, 0x22, 0x0a, 0x02, 0x46, 0x02, 0x6f, 0x00, 0xf5, - 0x25, 0x26, 0xee, 0x72, 0x43, 0xbc, 0x33, 0xb0, 0x1e, 0xdf, 0x1f, 0xee, - 0x9f, 0x9e, 0x05, 0x46, 0xef, 0x68, 0x5a, 0x52, 0xc8, 0xe4, 0xae, 0xc2, - 0xa3, 0x3d, 0x4e, 0x6f, 0xb0, 0x04, 0x0b, 0xd2, 0xce, 0xbc, 0x72, 0x95, - 0xca, 0x79, 0x08, 0x95, 0x6e, 0x37, 0x1e, 0x6a, 0x66, 0x01, 0x14, 0xa8, - 0x4d, 0x75, 0x21, 0x35, 0x9b, 0xcb, 0x12, 0xc7, 0x44, 0xb4, 0xc1, 0x24, - 0x13, 0x61, 0x7c, 0xe3, 0x21, 0xdd, 0xbc, 0x44, 0xa0, 0xb1, 0x71, 0xa2, - 0x35, 0x8c, 0x29, 0x86, 0x81, 0xba, 0xd4, 0x4a, 0x49, 0x44, 0xa3, 0xc4, - 0x87, 0x70, 0xd6, 0xb8, 0xb4, 0x31, 0x04, 0x9d, 0x74, 0x36, 0x4d, 0x10, - 0x3d, 0xab, 0xa4, 0x27, 0xb5, 0x5a, 0xe2, 0x42, 0x56, 0x9a, 0x5f, 0x91, - 0x31, 0xa2, 0xca, 0x4e, 0xc5, 0x75, 0x8a, 0x6f, 0xe9, 0x6a, 0x0b, 0x98, - 0x62, 0x40, 0xb4, 0x0a, 0x09, 0x82, 0x5c, 0xa9, 0x81, 0x0b, 0x7a, 0x49, - 0xf4, 0x8e, 0x16, 0xa4, 0x1f, 0xdf, 0xf0, 0xa9, 0x5c, 0x40, 0x4d, 0x6c, - 0xdd, 0xf6, 0x7b, 0x36, 0x7a, 0xc4, 0x5d, 0xdc, 0x49, 0xda, 0xfe, 0xe1, - 0xd5, 0xee, 0x4e, 0x89, 0x79, 0x6b, 0xbc, 0xca, 0x74, 0xae, 0x64, 0x1f, - 0x13, 0xfa, 0xbc, 0x2e, 0x7a, 0x83, 0x31, 0xa6, 0x12, 0xf4, 0x40, 0xc4, - 0x88, 0xa8, 0x7d, 0xfd, 0x14, 0x77, 0x79, 0x9a, 0x8d, 0x37, 0x92, 0xfd, - 0x08, 0xc6, 0x9b, 0xe0, 0xaa, 0xf8, 0xf8, 0x10, 0x76, 0x43, 0xc2, 0x0d, - 0xc0, 0xd0, 0xa1, 0x05, 0xc6, 0x62, 0xcb, 0x9c, 0x50, 0xde, 0x88, 0xfa, - 0xbd, 0xe6, 0xf2, 0x38, 0x5a, 0x00, 0x4a, 0x38, 0xab, 0x5a, 0x4d, 0x4e, - 0x43, 0x5d, 0x20, 0x1f, 0x37, 0x8b, 0x1a, 0xa1, 0xc6, 0x8f, 0xa3, 0xea, - 0xeb, 0x7a, 0x62, 0x26, 0x2b, 0xfc, 0xbc, 0xd2, 0xb1, 0x34, 0xad, 0xa8, - 0x1a, 0x7e, 0x49, 0xac, 0xfe, 0x34, 0x1a, 0x2a, 0xb2, 0x3f, 0x82, 0x8c, - 0x26, 0x0c, 0x04, 0x85, 0x2b, 0x21, 0x8b, 0x61, 0x7e, 0x95, 0x62, 0x51, - 0x30, 0x50, 0xb2, 0xc7, 0xd2, 0x4e, 0xaa, 0x79, 0xda, 0x01, 0x50, 0xbe, - 0x11, 0x8d, 0xd7, 0xb2, 0xaa, 0x6d, 0x61, 0x79, 0x40, 0x45, 0x1a, 0x80, - 0xbb, 0x6a, 0xac, 0x55, 0x4b, 0xcb, 0x2b, 0xd0, 0x50, 0x73, 0x2c, 0xab, - 0x25, 0x2a, 0x7d, 0xd9, 0x88, 0xb5, 0x75, 0x94, 0xb5, 0x38, 0x84, 0x40, - 0x4f, 0x94, 0xaf, 0x83, 0x58, 0x73, 0x4b, 0x08, 0xc9, 0xe6, 0x17, 0xad, - 0x3f, 0xbe, 0x22, 0x1b, 0x35, 0xb8, 0xcc, 0x40, 0x7b, 0xec, 0x07, 0x66, - 0xe0, 0xd2, 0x43, 0x1b, 0x1c, 0x81, 0x55, 0xf1, 0xd3, 0x97, 0x8e, 0x23, - 0x90, 0xa8, 0xe1, 0xea, 0x1c, 0x60, 0xa2, 0x9e, 0xf2, 0x02, 0x85, 0xca, - 0x78, 0x9f, 0x48, 0xaa, 0x30, 0x31, 0x03, 0xe6, 0x05, 0xcd, 0x0d, 0xb4, - 0x69, 0xdc, 0x0f, 0xc4, 0x7c, 0xd4, 0xe4, 0xdd, 0x5b, 0x16, 0x7a, 0x5f, - 0x0d, 0x25, 0xa2, 0x1c, 0xfb, 0xea, 0xa8, 0x76, 0xd7, 0x35, 0x05, 0x64, - 0x27, 0x21, 0x8b, 0x88, 0xfc, 0x86, 0xa5, 0xab, 0xbb, 0x04, 0x51, 0x05, - 0x84, 0x5f, 0x10, 0x46, 0x91, 0x8c, 0x4d, 0x0e, 0x5d, 0x2e, 0x88, 0x9a, - 0x24, 0x1a, 0x41, 0x06, 0x21, 0x0c, 0x15, 0xc7, 0x4c, 0x86, 0x62, 0xde, - 0x0d, 0x69, 0x28, 0x56, 0xf2, 0x90, 0x09, 0xd0, 0xf5, 0x6b, 0xe9, 0xdb, - 0x2c, 0x77, 0x1b, 0x74, 0x9b, 0xca, 0xa4, 0xff, 0x7a, 0x59, 0x91, 0x0b, - 0x38, 0xff, 0xc6, 0x86, 0xf8, 0x3b, 0x65, 0x45, 0x9c, 0x9a, 0x96, 0x7a, - 0xa0, 0x2b, 0x8d, 0xe0, 0x39, 0x96, 0x0b, 0xba, 0xa8, 0x7b, 0xe1, 0xba, - 0x60, 0x38, 0x27, 0xa6, 0x90, 0x0a, 0xac, 0x3e, 0xf3, 0x5e, 0x44, 0x18, - 0xab, 0xe0, 0xd4, 0x4c, 0x84, 0x11, 0xe6, 0x54, 0x03, 0xa8, 0xca, 0xc6, - 0xa3, 0x90, 0x71, 0x40, 0x88, 0x11, 0x93, 0x49, 0x36, 0xb4, 0xf0, 0x68, - 0xfa, 0x14, 0xbb, 0xd7, 0xc0, 0x62, 0x18, 0x46, 0x37, 0x61, 0x84, 0x32, - 0x24, 0x02, 0x74, 0x09, 0x77, 0x19, 0x3b, 0xef, 0xb4, 0x1b, 0xd0, 0xf9, - 0xe0, 0x33, 0xa4, 0x9f, 0x53, 0x3e, 0x68, 0xb8, 0x04, 0xa0, 0x01, 0x9c, - 0x72, 0xfc, 0x9a, 0x2b, 0x4f, 0x38, 0xbe, 0x26, 0xc7, 0x09, 0x45, 0x42, - 0xdb, 0x3e, 0x42, 0x0f, 0x0a, 0x74, 0x0e, 0x9b, 0x7f, 0x89, 0x79, 0x3d, - 0x26, 0xd7, 0xa2, 0x30, 0x13, 0x17, 0x79, 0xd3, 0x7d, 0xbb, 0x4e, 0x19, - 0xa7, 0x89, 0xe5, 0x5a, 0x27, 0xd8, 0x3a, 0x4d, 0x03, 0x89, 0xbd, 0xdd, - 0x25, 0xa6, 0x2a, 0xc7, 0x6a, 0x02, 0xa9, 0x3f, 0xc2, 0x4b, 0x42, 0xf6, - 0xb5, 0xb7, 0x3b, 0xcf, 0x30, 0x75, 0xbb, 0x80, 0xa0, 0xd7, 0x2a, 0x98, - 0xde, 0x76, 0x3f, 0x33, 0x1f, 0x80, 0x7b, 0xbc, 0xaa, 0x11, 0xff, 0xb1, - 0x58, 0x7a, 0x43, 0x27, 0x47, 0xa4, 0xa9, 0xdc, 0xc1, 0x57, 0x35, 0xc3, - 0x10, 0x4d, 0xc3, 0x21, 0x5a, 0x3d, 0x23, 0x8b, 0x4b, 0x26, 0xee, 0xc9, - 0x49, 0x4e, 0xc1, 0xa8, 0x9b, 0xc5, 0x68, 0x44, 0x78, 0xa0, 0x18, 0x79, - 0x5c, 0x97, 0xf9, 0xf9, 0x5c, 0x9c, 0x48, 0xb3, 0x22, 0x47, 0xa8, 0x63, - 0x11, 0xaa, 0x5c, 0x66, 0xb4, 0xf5, 0x95, 0x70, 0x6f, 0x88, 0x7f, 0x8c, - 0x38, 0x8f, 0x6d, 0x3e, 0xa6, 0x5b, 0xa6, 0x76, 0xff, 0x32, 0xd7, 0x62, - 0x4f, 0xab, 0xec, 0x5f, 0xf3, 0x9d, 0x15, 0x2f, 0xce, 0xad, 0xc6, 0xc5, - 0x29, 0xdc, 0x79, 0xc9, 0x26, 0xef, 0x74, 0xb9, 0xbf, 0xab, 0x1d, 0xd9, - 0x57, 0xe0, 0x61, 0x1b, 0xd1, 0xe1, 0x57, 0x1b, 0x3f, 0x52, 0x3f, 0x5c, - 0x5e, 0x06, 0x09, 0x25, 0x36, 0x04, 0x78, 0xfe, 0x6a, 0x87, 0xbd, 0x8d, - 0x1c, 0x9e, 0x28, 0xf5, 0xe7, 0x1a, 0xb5, 0xce, 0xc3, 0xad, 0x8e, 0x2c, - 0x8e, 0x5e, 0x22, 0x9e, 0x78, 0x9d, 0x0f, 0x33, 0x6c, 0xd9, 0x99, 0x46, - 0x1a, 0x76, 0x11, 0x4a, 0x22, 0x24, 0x9f, 0xe8, 0xe3, 0xed, 0x2f, 0x1f, - 0x6f, 0x34, 0x63, 0xc9, 0x71, 0xe8, 0xc9, 0x1d, 0xde, 0xe6, 0x8f, 0x08, - 0x2a, 0xa0, 0xe6, 0x96, 0x2f, 0xb4, 0x3e, 0x21, 0xdc, 0x52, 0x32, 0xe2, - 0xc7, 0xf9, 0xb9, 0xfa, 0xe9, 0xad, 0x24, 0xbb, 0xda, 0x29, 0xc8, 0x46, - 0xe1, 0x59, 0x8a, 0x55, 0x9c, 0x08, 0x0e, 0x91, 0xe0, 0x11, 0x31, 0xcf, - 0x3e, 0x77, 0xb4, 0xdb, 0xc5, 0xdf, 0xea, 0x71, 0x75, 0xb5, 0x1d, 0x7e, - 0x43, 0xd0, 0xe1, 0x20, 0x06, 0xea, 0x87, 0x3b, 0xd1, 0xa6, 0xe3, 0x0c, - 0xf0, 0x41, 0x29, 0xec, 0x05, 0x7f, 0xed, 0xe8, 0x8e, 0xef, 0xea, 0x8e, - 0xef, 0xfe, 0x8e, 0x1d, 0xdf, 0xfd, 0x94, 0x1d, 0xdf, 0xfd, 0xe8, 0x1d, - 0xff, 0xf2, 0xd1, 0xe3, 0x27, 0x6d, 0x3b, 0xbe, 0x7b, 0xbf, 0x3b, 0xbe, - 0x7b, 0xe7, 0x8e, 0xef, 0xfe, 0xab, 0x76, 0x7c, 0xe7, 0x33, 0xec, 0xb8, - 0xe6, 0x33, 0x3c, 0x45, 0x3e, 0xf0, 0xad, 0x66, 0xed, 0x4a, 0x4a, 0x08, - 0x42, 0x29, 0x20, 0xae, 0x88, 0xc0, 0x70, 0xc9, 0xa3, 0x1a, 0xd7, 0xe5, - 0x82, 0x94, 0x05, 0x38, 0x9e, 0x4c, 0x90, 0xae, 0x2a, 0x4c, 0xb3, 0x34, - 0x5a, 0x9a, 0xcc, 0xc6, 0xc8, 0x08, 0xd7, 0x7a, 0x6b, 0xea, 0xe1, 0x54, - 0xbb, 0xa5, 0xc2, 0x97, 0x70, 0x37, 0xc5, 0xbc, 0xfe, 0x17, 0xd4, 0x0d, - 0xb5, 0xc9, 0xdf, 0x91, 0x4b, 0x68, 0xe6, 0xe6, 0x8f, 0xcf, 0x25, 0xe4, - 0xf6, 0x05, 0x11, 0xa6, 0xfe, 0x50, 0x7f, 0x54, 0xba, 0x89, 0xba, 0xac, - 0x34, 0x8d, 0x45, 0x37, 0xec, 0x06, 0x2e, 0x45, 0x29, 0x36, 0x12, 0x25, - 0x12, 0x5a, 0x3d, 0x2b, 0x9d, 0xeb, 0x39, 0x56, 0x09, 0x18, 0x15, 0x53, - 0xcc, 0xbf, 0xb9, 0x19, 0x13, 0xb2, 0x16, 0x22, 0xcd, 0x96, 0x0c, 0xc7, - 0xc5, 0x7e, 0x3e, 0x06, 0x95, 0x0a, 0xe6, 0x61, 0x9f, 0x2e, 0xd4, 0x97, - 0xf0, 0x2f, 0xbc, 0xaa, 0x7c, 0xaf, 0xb4, 0x4b, 0x40, 0x9a, 0x8c, 0xd2, - 0x35, 0xa1, 0x72, 0x4c, 0x3a, 0x0b, 0x7a, 0x4e, 0x51, 0x5d, 0xec, 0x60, - 0xa0, 0xbb, 0x45, 0x1a, 0xd5, 0x42, 0x11, 0xaa, 0x13, 0xdb, 0x20, 0x2b, - 0x49, 0xf0, 0x97, 0xbb, 0x5f, 0xaa, 0x9d, 0xa9, 0x6f, 0x5c, 0x31, 0xae, - 0x0a, 0x45, 0x97, 0xa6, 0xed, 0xd5, 0x82, 0x5d, 0x28, 0x21, 0x10, 0x0e, - 0x17, 0x08, 0xb1, 0x22, 0xda, 0x6b, 0x43, 0x83, 0x74, 0x26, 0x86, 0xa6, - 0xcf, 0x45, 0x52, 0x2d, 0x89, 0x6f, 0xcd, 0x7d, 0x6a, 0xaf, 0x60, 0xf0, - 0x09, 0x6a, 0xb6, 0x6f, 0xf4, 0x2e, 0xda, 0xf3, 0xfd, 0xf7, 0x8e, 0x56, - 0x13, 0x11, 0x1e, 0x37, 0x41, 0x40, 0x08, 0x7c, 0x9c, 0x09, 0x51, 0xc8, - 0x32, 0x50, 0x22, 0x6c, 0x21, 0xa5, 0x3e, 0xa9, 0x83, 0x27, 0xa2, 0x25, - 0xca, 0x59, 0x14, 0xdd, 0xbc, 0x46, 0x15, 0x61, 0x1c, 0x9c, 0xde, 0x52, - 0xea, 0x1b, 0x91, 0x40, 0x0e, 0x0f, 0xce, 0x16, 0x93, 0xef, 0xa3, 0x6a, - 0x9e, 0x32, 0x03, 0xf6, 0x68, 0x87, 0x57, 0x24, 0x53, 0x56, 0xfa, 0xec, - 0x2f, 0x6c, 0x2b, 0xc2, 0xee, 0xd5, 0x52, 0x83, 0xca, 0xc1, 0xda, 0xa8, - 0xf3, 0x74, 0x38, 0x9f, 0xcc, 0xb4, 0x78, 0xaa, 0x14, 0xa3, 0x51, 0x10, - 0x1a, 0xc1, 0x37, 0x62, 0x80, 0x23, 0xf3, 0xf3, 0x53, 0xf2, 0x5a, 0x88, - 0x5b, 0xa2, 0x20, 0x01, 0xe9, 0x5c, 0xad, 0xaa, 0x06, 0x9e, 0x75, 0x54, - 0xc7, 0xa5, 0x06, 0x91, 0x6a, 0x87, 0xd9, 0xf9, 0xfc, 0x42, 0xd9, 0x7e, - 0xe5, 0x40, 0x36, 0x45, 0x61, 0xd0, 0x43, 0x2f, 0x83, 0xc1, 0xba, 0x5d, - 0x19, 0xd7, 0x84, 0xe4, 0x78, 0x8a, 0x0a, 0xcd, 0x9e, 0x15, 0x9c, 0xee, - 0x25, 0x11, 0x76, 0x4b, 0x36, 0x63, 0x65, 0x91, 0xf5, 0x4e, 0x34, 0x9a, - 0x65, 0x3d, 0xdc, 0x41, 0x86, 0xcb, 0xc6, 0x15, 0xd6, 0xbb, 0xf7, 0x41, - 0x36, 0x77, 0x25, 0xe6, 0xe8, 0x36, 0xae, 0xeb, 0x1a, 0x71, 0x79, 0xb5, - 0x4c, 0x6d, 0x46, 0xa6, 0xf5, 0x60, 0xd6, 0xc3, 0x02, 0xf2, 0xc5, 0x4c, - 0xcb, 0x9e, 0x09, 0xbf, 0xd4, 0xe3, 0x7b, 0x76, 0x70, 0x92, 0x3c, 0xa7, - 0x7c, 0x71, 0xd4, 0x9d, 0x93, 0x75, 0x14, 0x2f, 0xbe, 0x7c, 0xb8, 0xbd, - 0x4b, 0x88, 0x23, 0xfa, 0x1d, 0x7d, 0xc5, 0x97, 0x18, 0x7e, 0x68, 0xe7, - 0x36, 0x9b, 0x56, 0x94, 0x15, 0x89, 0x4c, 0x4d, 0xa2, 0xdf, 0x28, 0x3b, - 0x13, 0x28, 0x06, 0x51, 0xa1, 0x89, 0x67, 0x65, 0x69, 0x09, 0x6a, 0x6e, - 0x49, 0x11, 0x32, 0x4d, 0x5b, 0x82, 0x88, 0x35, 0xae, 0x98, 0x28, 0x5c, - 0x99, 0xc8, 0x26, 0x83, 0x26, 0x9a, 0xec, 0x1f, 0xfc, 0x69, 0xc3, 0x10, - 0xa4, 0xd4, 0x9e, 0x49, 0x08, 0xbd, 0xe2, 0xb9, 0xc1, 0xe2, 0x04, 0x8a, - 0x30, 0x16, 0x62, 0x4e, 0xb3, 0xa1, 0x13, 0xd7, 0x62, 0x3b, 0x92, 0x5f, - 0x93, 0x26, 0x85, 0xc4, 0xa5, 0x32, 0x57, 0xe5, 0x4c, 0xbe, 0xc5, 0xdb, - 0x29, 0x22, 0xea, 0x7b, 0xa5, 0x2d, 0x1f, 0xc1, 0xbf, 0x59, 0x8f, 0x70, - 0xd9, 0xa2, 0x5d, 0x9d, 0x16, 0x04, 0x86, 0x22, 0x5c, 0x1d, 0xc1, 0xbb, - 0xb4, 0xe6, 0x1a, 0xec, 0xd0, 0xbb, 0xd7, 0xc7, 0xcf, 0x0e, 0x5f, 0xee, - 0xff, 0x25, 0x78, 0x4f, 0x09, 0xc3, 0x91, 0x96, 0x10, 0x06, 0xf2, 0x2e, - 0x4b, 0xab, 0x9b, 0x77, 0x70, 0xa9, 0xc3, 0xb7, 0xeb, 0xbb, 0x1b, 0xe8, - 0xfd, 0x9a, 0x6a, 0xa1, 0xc7, 0x8b, 0x2c, 0xae, 0xd5, 0xc1, 0x88, 0x99, - 0xae, 0xe2, 0x85, 0x07, 0x70, 0xc4, 0xfa, 0x97, 0x91, 0x09, 0xf0, 0x3c, - 0x20, 0x8c, 0xe1, 0x1e, 0xdd, 0xb8, 0x9a, 0x0e, 0x66, 0x59, 0x41, 0x74, - 0x34, 0xba, 0x40, 0x45, 0xfe, 0xab, 0x09, 0x55, 0x2f, 0xae, 0x65, 0xcc, - 0xd0, 0x56, 0xf8, 0xd5, 0x74, 0x71, 0xf3, 0x64, 0xea, 0xf7, 0x93, 0x28, - 0xeb, 0x1a, 0xbc, 0x7b, 0xeb, 0xb4, 0xe7, 0x55, 0x93, 0xa9, 0xcf, 0xe7, - 0xa3, 0x51, 0x48, 0x8c, 0xad, 0xf1, 0xcc, 0xd6, 0xd9, 0x78, 0x9a, 0xd5, - 0x02, 0x8e, 0x90, 0x3c, 0x85, 0x7f, 0xbf, 0x01, 0xa1, 0x4a, 0x81, 0xcd, - 0xd3, 0x4a, 0x97, 0xb2, 0x0a, 0x02, 0x09, 0xbe, 0x60, 0x7c, 0xb7, 0xaf, - 0x68, 0xba, 0xd9, 0xd0, 0x9e, 0x04, 0x66, 0xbd, 0xa7, 0xf7, 0xfb, 0xd9, - 0x5f, 0x4e, 0x0e, 0xbf, 0x79, 0x8a, 0x02, 0xc7, 0xb7, 0x54, 0x16, 0x21, - 0x93, 0xb4, 0xe9, 0x20, 0x82, 0xdc, 0xcc, 0xcc, 0xd4, 0xf9, 0xf3, 0xb3, - 0xa3, 0xd3, 0x93, 0x97, 0xc7, 0x07, 0xdf, 0x3c, 0xfd, 0x19, 0xad, 0x09, - 0x20, 0xa1, 0xde, 0xc4, 0x6f, 0xd9, 0xc7, 0x89, 0x96, 0xc2, 0xd0, 0x57, - 0x5f, 0x1f, 0xfe, 0xf4, 0xee, 0xf0, 0xf5, 0x8f, 0xdf, 0x3c, 0xbd, 0x4a, - 0xcb, 0x2e, 0xcd, 0x40, 0xdf, 0xc3, 0x24, 0xfc, 0xe9, 0x55, 0x5e, 0x16, - 0x53, 0xf4, 0x57, 0x81, 0xc8, 0x58, 0xe6, 0xb8, 0xf8, 0x21, 0x9c, 0x2c, - 0x5e, 0x02, 0x1f, 0x53, 0xf6, 0x3b, 0xa0, 0x7d, 0x6b, 0x99, 0xfa, 0x55, - 0xbd, 0xbd, 0xb5, 0x25, 0x8b, 0x76, 0xa7, 0xf7, 0x11, 0x98, 0xc5, 0x28, - 0xbf, 0x08, 0xe7, 0x0a, 0x0d, 0x57, 0xe7, 0xe3, 0xf7, 0x55, 0xfe, 0xf7, - 0x2c, 0x79, 0x4a, 0xb2, 0xae, 0x16, 0x47, 0x38, 0x7b, 0xee, 0x4b, 0x98, - 0x9f, 0x11, 0x70, 0xed, 0xf7, 0x2f, 0xff, 0x74, 0x7a, 0xf4, 0x5f, 0x87, - 0x4a, 0xfb, 0xeb, 0x54, 0xe7, 0x0d, 0xe7, 0xf2, 0x68, 0x7b, 0x07, 0xef, - 0xae, 0x31, 0x82, 0xe3, 0x97, 0x1b, 0x91, 0x68, 0x27, 0xf0, 0x9a, 0xe7, - 0xb0, 0x9c, 0xef, 0x13, 0xea, 0x87, 0xeb, 0xb3, 0x46, 0x68, 0xd2, 0x56, - 0xeb, 0x47, 0x2d, 0x77, 0x8c, 0xdb, 0x22, 0xbc, 0x55, 0x24, 0x83, 0xd2, - 0xe1, 0x24, 0xf2, 0x78, 0x2c, 0xc0, 0xf5, 0x7b, 0x0f, 0xc0, 0x89, 0x83, - 0x91, 0x48, 0x9e, 0x70, 0xab, 0xf7, 0x7d, 0x34, 0x54, 0x34, 0xed, 0xd6, - 0x5a, 0x17, 0xa2, 0x10, 0xc4, 0xe8, 0x22, 0x1f, 0x1f, 0x0d, 0x15, 0x75, - 0xb4, 0xbd, 0xb5, 0xf3, 0x30, 0xa9, 0xdb, 0xeb, 0xc5, 0xb5, 0x94, 0x9b, - 0xc7, 0x57, 0xe1, 0x44, 0x35, 0x41, 0x45, 0x1a, 0x9f, 0x47, 0xbb, 0x25, - 0x5e, 0x61, 0x14, 0xd8, 0xd1, 0xb8, 0x4b, 0x8b, 0xa4, 0x47, 0x46, 0xb1, - 0xfd, 0x45, 0x23, 0xcd, 0x27, 0x38, 0xe9, 0xac, 0x4a, 0xd4, 0x43, 0xeb, - 0x0c, 0x8c, 0x5c, 0x0d, 0x77, 0x9c, 0x5d, 0x90, 0xcb, 0x89, 0x17, 0xb9, - 0xb2, 0x42, 0x13, 0x92, 0xb5, 0x03, 0xb2, 0x37, 0x28, 0xfc, 0x04, 0x99, - 0xca, 0x7b, 0xc3, 0x65, 0x70, 0x0c, 0xa0, 0x4b, 0xdd, 0xb7, 0xd1, 0x28, - 0x04, 0x83, 0xb0, 0x6e, 0x01, 0x77, 0x6b, 0x2c, 0x96, 0x2d, 0xb2, 0x18, - 0x13, 0x1a, 0x4c, 0x31, 0x5e, 0x84, 0x3b, 0x4a, 0x86, 0xad, 0x0c, 0x37, - 0xb1, 0xb8, 0xe6, 0x77, 0xed, 0xad, 0x1b, 0x83, 0xec, 0xec, 0xf6, 0x57, - 0x3b, 0xfd, 0xed, 0xc7, 0x4f, 0x10, 0x5a, 0x7b, 0x73, 0xc9, 0xae, 0xca, - 0x1c, 0x75, 0x4b, 0xff, 0xde, 0xf5, 0x85, 0xe5, 0x92, 0xa7, 0xf8, 0xab, - 0x2f, 0x51, 0x92, 0xd0, 0xde, 0xbe, 0x51, 0xb1, 0x39, 0x75, 0x55, 0x8e, - 0x03, 0xdc, 0x0e, 0x46, 0xd4, 0xb3, 0xda, 0xc2, 0x5e, 0x6d, 0x8d, 0x5a, - 0x94, 0xab, 0xc2, 0x83, 0x54, 0x91, 0xea, 0x03, 0x0f, 0x75, 0xb9, 0x7a, - 0xf2, 0xf4, 0x96, 0xb6, 0x02, 0xfc, 0x97, 0xc6, 0x24, 0x33, 0x3c, 0xd5, - 0x19, 0xc3, 0x52, 0x20, 0xa6, 0x2b, 0xc9, 0x7b, 0x64, 0x6b, 0x15, 0xbe, - 0x96, 0x5a, 0x7d, 0x28, 0x94, 0xb7, 0xe8, 0x29, 0x2e, 0x1c, 0x42, 0x95, - 0x96, 0xe1, 0xda, 0xb3, 0x5b, 0xd0, 0xf4, 0x2f, 0xd0, 0x63, 0x49, 0x34, - 0x06, 0xc9, 0x97, 0xa8, 0x11, 0xb9, 0x36, 0x8c, 0xab, 0xb2, 0x84, 0xe6, - 0xba, 0xcc, 0xa8, 0xd2, 0x55, 0x1a, 0xd5, 0x37, 0x77, 0x15, 0x42, 0x22, - 0x6e, 0x72, 0x21, 0x4c, 0x8b, 0xa7, 0x21, 0xa6, 0x60, 0x1a, 0xc8, 0xfa, - 0x04, 0xc7, 0xbf, 0x21, 0x7c, 0x84, 0xeb, 0x5d, 0x5a, 0xb9, 0x44, 0x33, - 0x69, 0xc4, 0xa2, 0x03, 0xb4, 0x86, 0xef, 0xaa, 0xd8, 0xc0, 0x22, 0x83, - 0x54, 0xde, 0xa0, 0x46, 0xdd, 0x22, 0x28, 0x3e, 0x78, 0xed, 0x91, 0x57, - 0x4e, 0x51, 0x94, 0x51, 0x24, 0x8f, 0x68, 0xc9, 0x04, 0x43, 0x6f, 0x88, - 0x65, 0x5d, 0xd6, 0x7b, 0x1b, 0x56, 0x8c, 0x20, 0xaf, 0x83, 0x96, 0x44, - 0x8e, 0x6b, 0x69, 0xb7, 0x18, 0xcc, 0x27, 0x5c, 0x70, 0x43, 0x4a, 0x36, - 0x72, 0xc4, 0x44, 0xd8, 0x6c, 0xd9, 0x67, 0xea, 0x68, 0x93, 0xe3, 0x27, - 0x8d, 0x2d, 0xe6, 0x01, 0x7d, 0x31, 0x6e, 0x08, 0x95, 0xee, 0xec, 0x3a, - 0x80, 0x9a, 0x79, 0x1d, 0xd8, 0x1a, 0x72, 0x40, 0x56, 0xa1, 0x0a, 0x03, - 0x45, 0x6c, 0x51, 0x09, 0x5d, 0xad, 0xa7, 0xd4, 0xe5, 0xad, 0x50, 0xf8, - 0x92, 0x14, 0xc4, 0x1a, 0x0a, 0x7d, 0x13, 0xb1, 0xca, 0x11, 0xd2, 0x28, - 0x1d, 0x48, 0xe1, 0x87, 0xb2, 0xc0, 0x48, 0x22, 0xda, 0xb9, 0x61, 0xd1, - 0x00, 0x4e, 0xb5, 0x3a, 0x32, 0x4c, 0xbb, 0x06, 0x32, 0x19, 0xb3, 0x73, - 0x3b, 0x3b, 0xf7, 0x01, 0x65, 0xdd, 0xa8, 0x56, 0xf4, 0xf7, 0xa4, 0xf3, - 0x13, 0xb4, 0xb6, 0xb5, 0x0d, 0x64, 0x31, 0x4b, 0x76, 0xb6, 0x76, 0xb6, - 0x93, 0xed, 0x9d, 0xbd, 0xed, 0x27, 0x7b, 0x5b, 0x5b, 0x77, 0xd7, 0x2f, - 0x82, 0x97, 0x7b, 0xbf, 0xe7, 0x6d, 0x3a, 0xe9, 0x2b, 0xc9, 0x5e, 0x40, - 0x72, 0x17, 0x3d, 0xc2, 0x4d, 0xb6, 0x70, 0xa2, 0xb8, 0x3c, 0xa6, 0x19, - 0x0c, 0x31, 0x7c, 0x36, 0x79, 0xfa, 0xe3, 0xe1, 0x9b, 0xd3, 0xa3, 0xe3, - 0xd7, 0xdf, 0x7a, 0x27, 0x8e, 0x7c, 0x86, 0x24, 0x03, 0xb2, 0x07, 0x72, - 0x55, 0xc1, 0xa8, 0x0b, 0x6e, 0x47, 0xf2, 0xaa, 0x5a, 0xcc, 0x15, 0x15, - 0x59, 0x01, 0x21, 0x0b, 0x1f, 0x92, 0xc3, 0x38, 0x18, 0x64, 0xb3, 0x9a, - 0xf8, 0xab, 0x3c, 0xa5, 0x85, 0x36, 0xd0, 0x17, 0x49, 0xd6, 0xca, 0xad, - 0xae, 0xfc, 0xb2, 0xad, 0xbf, 0x90, 0xec, 0xc0, 0xbf, 0xee, 0x36, 0x00, - 0xd3, 0x7c, 0x1c, 0x60, 0xc5, 0xa8, 0x82, 0x46, 0x13, 0xe4, 0x28, 0xf4, - 0x57, 0x49, 0x6b, 0xa5, 0x49, 0xbe, 0xed, 0xb4, 0xc0, 0xd0, 0x9f, 0xdf, - 0x1e, 0x1d, 0xf4, 0xd8, 0x27, 0x4f, 0xbc, 0x75, 0x13, 0x4e, 0xb5, 0xc5, - 0xcb, 0x6a, 0xdf, 0x0a, 0x59, 0x09, 0xf2, 0x1d, 0xe5, 0x68, 0xce, 0x18, - 0x72, 0x16, 0x05, 0x33, 0x86, 0xe8, 0x76, 0x21, 0x43, 0xfa, 0x0e, 0xcc, - 0x2b, 0x7e, 0x1e, 0x9e, 0xc1, 0xc9, 0x86, 0xef, 0xb7, 0xdb, 0xbe, 0xdf, - 0x0e, 0xdf, 0xef, 0xb4, 0x7d, 0xbf, 0x13, 0xbe, 0xdf, 0x6d, 0xfb, 0x7e, - 0x37, 0xaa, 0xdf, 0xa5, 0xbb, 0xfb, 0x79, 0xeb, 0x77, 0x59, 0x37, 0xb8, - 0x73, 0x77, 0xd1, 0xb0, 0x7b, 0x78, 0x37, 0x18, 0xac, 0x6f, 0x35, 0xb3, - 0xeb, 0x1b, 0x4b, 0x0d, 0xed, 0x4b, 0x2c, 0xed, 0x86, 0xda, 0x1f, 0x5b, - 0xc7, 0xb7, 0xba, 0xc1, 0x7a, 0xde, 0x75, 0x43, 0x90, 0x82, 0xae, 0x46, - 0x76, 0xf6, 0xce, 0xf6, 0xae, 0x46, 0xe2, 0x25, 0x4f, 0xd1, 0x6d, 0x18, - 0x9d, 0x91, 0x50, 0x75, 0x4d, 0xea, 0x94, 0xd3, 0x93, 0x30, 0x10, 0x32, - 0x9c, 0x5b, 0xe5, 0xb6, 0x85, 0xd0, 0x05, 0x07, 0xcb, 0x65, 0x39, 0x7e, - 0x1c, 0xa5, 0x86, 0xbd, 0xd3, 0x49, 0xc2, 0xbe, 0xe8, 0xce, 0xd4, 0xde, - 0xa5, 0x51, 0x92, 0xb2, 0x2d, 0x29, 0x1d, 0xb6, 0x4b, 0xb1, 0x00, 0x35, - 0x5e, 0x30, 0xa1, 0x62, 0x94, 0x40, 0x16, 0xd0, 0x91, 0xb4, 0x18, 0x8d, - 0xcb, 0x74, 0xdb, 0x42, 0x44, 0xaf, 0xb7, 0x6f, 0x5e, 0xaa, 0xfa, 0xa4, - 0x1b, 0x81, 0x6b, 0xdb, 0xaf, 0xb2, 0x4d, 0xb8, 0x1a, 0xaa, 0x4d, 0x0a, - 0x9a, 0x95, 0xc6, 0x2f, 0xeb, 0xc9, 0x78, 0x49, 0x18, 0x03, 0x6e, 0x71, - 0xc9, 0x75, 0x56, 0xd8, 0x70, 0x46, 0x01, 0x79, 0xbe, 0x26, 0xa0, 0x79, - 0x45, 0xd4, 0x67, 0xc4, 0x0d, 0xa1, 0x79, 0x05, 0xc3, 0x65, 0x90, 0xfe, - 0xb7, 0x59, 0x71, 0xa8, 0xd1, 0xc0, 0x83, 0x57, 0xaa, 0x3a, 0x92, 0x0d, - 0xf3, 0x19, 0x19, 0x9a, 0xe6, 0xee, 0x84, 0x58, 0x5d, 0x61, 0x80, 0xd0, - 0x88, 0x86, 0x32, 0x68, 0x6a, 0x10, 0x06, 0xa4, 0x57, 0x82, 0xfb, 0xda, - 0xb6, 0x1a, 0x15, 0x65, 0x49, 0x58, 0x21, 0x37, 0x8b, 0x5b, 0x97, 0x45, - 0xf7, 0xe1, 0xea, 0x4d, 0x72, 0xb8, 0xf5, 0x5c, 0xfd, 0x3e, 0x48, 0x9a, - 0xb8, 0x23, 0x18, 0xf7, 0xbb, 0xfd, 0xc3, 0xd3, 0x77, 0xdb, 0x3b, 0x4f, - 0xde, 0xfd, 0x70, 0xf0, 0xea, 0xdd, 0xe9, 0x8b, 0xfd, 0x9d, 0x47, 0x8f, - 0xef, 0x34, 0xea, 0x0a, 0x8e, 0xa5, 0x59, 0x76, 0xf9, 0x86, 0xd0, 0x80, - 0x68, 0x37, 0xcb, 0xae, 0xcc, 0x79, 0x5e, 0x92, 0x0a, 0x10, 0xf9, 0x94, - 0x38, 0xbe, 0x2a, 0x1a, 0x8f, 0x3f, 0x1d, 0x18, 0xce, 0x46, 0x90, 0x52, - 0x4f, 0xf1, 0x67, 0x7c, 0x36, 0x32, 0x0e, 0x22, 0x69, 0x86, 0xbc, 0x91, - 0x02, 0x8e, 0x38, 0x67, 0x4c, 0x2c, 0xa2, 0x56, 0x71, 0x35, 0x23, 0xbb, - 0x5a, 0xa2, 0x6c, 0x53, 0xa2, 0xae, 0xce, 0xe9, 0x9b, 0x93, 0x4e, 0x57, - 0xdc, 0xfb, 0xd0, 0x6e, 0x0f, 0xfe, 0x4e, 0xd8, 0x60, 0x97, 0x3c, 0xda, - 0x7a, 0xf4, 0x70, 0xc3, 0x72, 0x0a, 0x60, 0x58, 0x04, 0x3e, 0xd9, 0xf4, - 0x8d, 0x85, 0x24, 0xf8, 0x32, 0xca, 0xeb, 0xa3, 0x8c, 0xd8, 0x78, 0x36, - 0x82, 0xa8, 0xd3, 0x95, 0xfc, 0xa9, 0x85, 0x12, 0x0f, 0xbe, 0x08, 0x2c, - 0x0d, 0x2c, 0x86, 0xa8, 0xc6, 0xb0, 0x11, 0x29, 0xd0, 0xa4, 0x51, 0x26, - 0x73, 0xb8, 0x2a, 0x40, 0x1d, 0x32, 0xab, 0xed, 0x82, 0xa7, 0x90, 0xc5, - 0x3f, 0x9d, 0x98, 0x2c, 0x84, 0x01, 0xee, 0x1b, 0xf7, 0xd3, 0xc3, 0x62, - 0x05, 0xac, 0x7e, 0x98, 0xce, 0x71, 0x95, 0xdb, 0xde, 0x76, 0x64, 0xeb, - 0x67, 0xf6, 0x79, 0x72, 0x2c, 0x7c, 0x27, 0x38, 0x86, 0x95, 0xe4, 0x14, - 0xd9, 0x2a, 0x4f, 0x51, 0xb6, 0x4b, 0x4f, 0x59, 0x4f, 0x58, 0xa0, 0xa9, - 0x24, 0xa4, 0xa4, 0x5b, 0x61, 0x60, 0x32, 0xec, 0x6b, 0x34, 0xcf, 0x62, - 0xaa, 0x3a, 0xd7, 0x1b, 0x6d, 0xe0, 0x23, 0xa9, 0xa6, 0xe7, 0x06, 0xde, - 0xd7, 0xc8, 0x33, 0xb9, 0x65, 0x02, 0x2d, 0xb1, 0xd8, 0xb2, 0x12, 0x76, - 0x85, 0x6d, 0x45, 0xc2, 0xcc, 0x3c, 0x50, 0x65, 0x18, 0xf8, 0xe7, 0xca, - 0x9b, 0xf3, 0x9d, 0xcc, 0xae, 0x87, 0x6e, 0x02, 0x0c, 0xc7, 0xfa, 0x89, - 0x7b, 0x42, 0x2f, 0xfb, 0xc4, 0x63, 0xb7, 0x1b, 0x8a, 0x14, 0xc0, 0x27, - 0x93, 0xd2, 0x47, 0xc2, 0x76, 0xdc, 0xd7, 0x6e, 0xb8, 0xed, 0x08, 0xa7, - 0x98, 0xb8, 0x98, 0xcb, 0x8e, 0x6b, 0xdb, 0x9d, 0x50, 0xda, 0x37, 0xe0, - 0x8a, 0x84, 0xad, 0xd1, 0xd3, 0xa1, 0x5b, 0xfc, 0x79, 0x00, 0x86, 0xee, - 0x69, 0x53, 0xb4, 0x0d, 0xdd, 0x98, 0x20, 0xbe, 0xf8, 0x3d, 0xa1, 0xfa, - 0xa5, 0x35, 0x16, 0x09, 0xad, 0xea, 0x48, 0x3e, 0x87, 0x19, 0x7f, 0xe0, - 0xdb, 0xd8, 0x32, 0x38, 0xb4, 0x86, 0x59, 0xca, 0x85, 0x48, 0x34, 0x38, - 0x9a, 0x83, 0xd9, 0xd9, 0x96, 0x46, 0xb9, 0x19, 0x5c, 0xc5, 0xca, 0x89, - 0xb9, 0x14, 0x4a, 0x0f, 0xbb, 0x7d, 0x99, 0x5f, 0xe0, 0x45, 0x1a, 0xf9, - 0x3e, 0xdd, 0x88, 0xda, 0x41, 0x3f, 0x23, 0xd3, 0xf4, 0x5d, 0x0b, 0x77, - 0xb5, 0x7d, 0x97, 0x70, 0x08, 0x4f, 0xdc, 0x47, 0x0c, 0xc6, 0x62, 0x16, - 0xb2, 0xa3, 0xc8, 0xdb, 0x85, 0xc5, 0xc5, 0x54, 0xa3, 0xdb, 0x82, 0x2e, - 0x44, 0x0c, 0xf5, 0x7b, 0xf6, 0x1c, 0x71, 0x37, 0x2a, 0x8b, 0xa6, 0xa1, - 0x33, 0xd4, 0xb2, 0xda, 0x6c, 0xca, 0xb9, 0xf6, 0x19, 0xbd, 0xa1, 0x92, - 0x27, 0x26, 0x77, 0xf1, 0x26, 0xfa, 0xfd, 0xfb, 0xc2, 0x0a, 0x35, 0xa0, - 0xa7, 0x5d, 0xf3, 0x1a, 0x48, 0xaa, 0xa4, 0xce, 0x1a, 0x79, 0x3a, 0x6a, - 0x09, 0x50, 0xbc, 0x67, 0x2a, 0x1b, 0xfb, 0x0e, 0xef, 0xb1, 0x77, 0x81, - 0x34, 0x58, 0x96, 0x20, 0xc2, 0xe0, 0xda, 0xd8, 0x79, 0xc1, 0x25, 0x4d, - 0x50, 0xaf, 0xc2, 0xe0, 0x9d, 0xaa, 0x26, 0x27, 0x55, 0x8c, 0x38, 0xdd, - 0x88, 0xb5, 0x84, 0x4d, 0x2a, 0x53, 0x2c, 0xd4, 0xc0, 0x51, 0x06, 0x2a, - 0xe4, 0x6b, 0x6d, 0x4c, 0x2b, 0x8d, 0x89, 0x47, 0x2d, 0x35, 0xcd, 0x33, - 0xd2, 0x37, 0x17, 0x6b, 0x71, 0xc8, 0xd2, 0xde, 0x0f, 0xdd, 0xf5, 0xb7, - 0x56, 0x3e, 0x99, 0x4d, 0x95, 0x01, 0xc9, 0xe5, 0xe3, 0xf6, 0x77, 0xfb, - 0x7f, 0xa9, 0xfd, 0xdd, 0xfe, 0x5f, 0x7a, 0x7f, 0xb7, 0xef, 0x69, 0x7f, - 0xb7, 0x3f, 0x6a, 0x7f, 0xc3, 0x99, 0xc7, 0x89, 0x34, 0x76, 0x7b, 0xe7, - 0xe3, 0x76, 0x7b, 0xe7, 0x7f, 0xa9, 0xdd, 0xde, 0xf9, 0x5f, 0x7a, 0xb7, - 0x77, 0xee, 0x69, 0xb7, 0x77, 0xee, 0x6f, 0xb7, 0x77, 0x3f, 0x6e, 0xb7, - 0x77, 0x7f, 0xe7, 0x6e, 0xff, 0x4f, 0x34, 0x7d, 0x85, 0x8a, 0xb3, 0xaa, - 0x3a, 0x5b, 0xa9, 0x02, 0x9f, 0x7a, 0x80, 0x36, 0x7e, 0x7c, 0x40, 0x74, - 0xef, 0xaa, 0x2d, 0xfd, 0x52, 0x17, 0xf6, 0x7e, 0x76, 0x73, 0xf7, 0x63, - 0x76, 0x73, 0x67, 0xd9, 0x6e, 0x96, 0xbd, 0x0c, 0x68, 0x3c, 0x8c, 0x52, - 0x4a, 0xc0, 0xab, 0x6f, 0x25, 0x65, 0x74, 0x2d, 0x34, 0xcf, 0xa3, 0x95, - 0x4f, 0x16, 0xa7, 0x77, 0x28, 0xef, 0x38, 0xc8, 0x7e, 0x49, 0xf4, 0x83, - 0x4d, 0xd1, 0x94, 0x14, 0xa9, 0xd5, 0xa0, 0x25, 0x6d, 0xb4, 0xa6, 0x8c, - 0x46, 0xbe, 0x49, 0x46, 0xd0, 0x7c, 0xaa, 0x1d, 0x48, 0xa1, 0x19, 0x2a, - 0xff, 0x46, 0x95, 0x47, 0x34, 0x78, 0x5d, 0x2b, 0xfb, 0xe5, 0x8d, 0x6c, - 0x20, 0x37, 0xf8, 0x7b, 0x42, 0x57, 0x77, 0x2d, 0xde, 0xb1, 0x05, 0xae, - 0xeb, 0x15, 0xcb, 0xc5, 0xea, 0x2a, 0xba, 0xb5, 0x4f, 0x11, 0xcb, 0xc8, - 0x45, 0x9e, 0x9e, 0xa6, 0x57, 0x19, 0x17, 0xbd, 0x9b, 0x8f, 0xb9, 0x56, - 0x31, 0xa2, 0x19, 0x61, 0xc4, 0x0f, 0xc3, 0x68, 0x51, 0xc9, 0x51, 0xe4, - 0x49, 0x54, 0x6f, 0x94, 0xd7, 0x0f, 0x88, 0xff, 0xa2, 0x30, 0xdf, 0xb0, - 0x95, 0xfc, 0x45, 0x12, 0xc7, 0x4f, 0x81, 0xce, 0xa9, 0x04, 0x21, 0x15, - 0xa7, 0x9f, 0x62, 0xb2, 0x86, 0x2b, 0xf0, 0xe1, 0xfc, 0x23, 0x12, 0x65, - 0xc6, 0xf5, 0xf2, 0x90, 0x87, 0x71, 0x43, 0x9d, 0x5e, 0x87, 0xe2, 0xb3, - 0x2c, 0x8c, 0x15, 0x59, 0x18, 0x86, 0xdb, 0x48, 0xf1, 0x0e, 0x7e, 0x8b, - 0xa2, 0x7c, 0x5c, 0xec, 0x2a, 0x43, 0x07, 0x75, 0xfe, 0xbd, 0x13, 0x52, - 0xe2, 0x7d, 0x03, 0xf6, 0xbe, 0x7f, 0xdd, 0x02, 0x6c, 0x17, 0x0f, 0x5e, - 0x08, 0x0d, 0xe3, 0xe7, 0x71, 0x29, 0xb8, 0x02, 0x22, 0x30, 0x83, 0xab, - 0xbc, 0xa6, 0xe2, 0x6c, 0xb8, 0x18, 0xd3, 0xac, 0x66, 0xf5, 0x13, 0x56, - 0x6e, 0x34, 0x52, 0x54, 0x41, 0x4e, 0x97, 0xc6, 0x94, 0x77, 0x82, 0x03, - 0xc2, 0x88, 0x25, 0x5a, 0x0e, 0x5a, 0x2f, 0xbf, 0x56, 0xaa, 0xc6, 0x61, - 0xbd, 0xae, 0x32, 0x1b, 0x32, 0x94, 0x7c, 0x15, 0xcc, 0x0c, 0x55, 0x06, - 0x1f, 0x4b, 0x81, 0x42, 0x6c, 0x0e, 0xc3, 0x52, 0x93, 0xe4, 0x7b, 0xd8, - 0xe3, 0x6b, 0x32, 0xa7, 0x50, 0xca, 0x2b, 0x96, 0x2b, 0xc6, 0xea, 0x56, - 0x63, 0xc9, 0xe7, 0xc0, 0xe2, 0x1e, 0x9c, 0x02, 0x8b, 0xbb, 0x29, 0x77, - 0x45, 0x71, 0x21, 0x35, 0xf5, 0xa8, 0x8a, 0x48, 0xf5, 0x2f, 0x09, 0xf6, - 0x15, 0x6a, 0xfa, 0x6c, 0x85, 0x43, 0xb8, 0x7d, 0x98, 0xda, 0x1d, 0x81, - 0xbe, 0xac, 0x7a, 0x98, 0xe9, 0x80, 0x41, 0x5b, 0x42, 0xf4, 0xb7, 0x0f, - 0xff, 0x0e, 0xf1, 0xdf, 0x46, 0x02, 0xb1, 0x41, 0x0b, 0xbb, 0xec, 0xa5, - 0xd5, 0x20, 0xcf, 0xa3, 0xa0, 0x4d, 0xf7, 0x79, 0xd7, 0xfe, 0xe4, 0x40, - 0x8f, 0x6e, 0x78, 0x2f, 0x1f, 0x56, 0xc1, 0x5f, 0xaa, 0x1f, 0xc6, 0xbe, - 0xa1, 0xd0, 0xce, 0xff, 0x8d, 0xe7, 0x94, 0x42, 0x26, 0xdc, 0x39, 0x5d, - 0x38, 0xa2, 0x67, 0x02, 0xde, 0x51, 0xe5, 0x93, 0x7c, 0x9c, 0x96, 0xd4, - 0xa9, 0x85, 0x6e, 0xa2, 0x49, 0x11, 0x54, 0x70, 0x34, 0xa7, 0x16, 0x8a, - 0xb7, 0x77, 0x99, 0x7d, 0x60, 0x54, 0x40, 0x5e, 0x12, 0x2b, 0x5e, 0x86, - 0xb1, 0xa5, 0xc2, 0xff, 0xf7, 0x4f, 0x0f, 0x8e, 0x8e, 0xf8, 0x21, 0xcd, - 0x51, 0xc4, 0x85, 0xe5, 0xa8, 0x52, 0x2e, 0xf6, 0x91, 0x54, 0x58, 0x4b, - 0x3d, 0x2b, 0xad, 0x78, 0x66, 0xf0, 0xa1, 0xf2, 0x59, 0x87, 0xa3, 0x01, - 0xba, 0x3f, 0x86, 0x1c, 0x92, 0x9b, 0x2a, 0xe5, 0xf3, 0x31, 0x9f, 0xc2, - 0xc8, 0x72, 0x2c, 0xb3, 0x7d, 0x39, 0x9f, 0xa4, 0xd3, 0xea, 0xff, 0x31, - 0x9a, 0xfb, 0x0f, 0x01, 0x17, 0x3b, 0x9f, 0x3b, 0x37, 0xb7, 0x62, 0x2b, - 0x05, 0x77, 0xc3, 0x27, 0x19, 0x95, 0x5c, 0x37, 0x2b, 0xf2, 0x1d, 0x17, - 0x1f, 0xbd, 0x68, 0xec, 0x30, 0x6b, 0x07, 0x9d, 0xe7, 0x38, 0xe8, 0x7b, - 0xd1, 0xc0, 0x11, 0x67, 0x29, 0xd0, 0x3b, 0x0d, 0xc6, 0xc1, 0x1c, 0xa7, - 0x61, 0xc4, 0x45, 0x83, 0x21, 0x7f, 0x31, 0x2f, 0xc5, 0x18, 0xc8, 0x99, - 0xbd, 0xcc, 0x44, 0x34, 0x86, 0x7a, 0x5f, 0x72, 0x71, 0x7b, 0x55, 0x06, - 0x67, 0x81, 0x42, 0x3d, 0xcc, 0x1d, 0x66, 0xa9, 0xba, 0x5c, 0xb2, 0x9b, - 0xf2, 0x1a, 0x4a, 0xf5, 0x69, 0x85, 0xec, 0x03, 0x89, 0x3e, 0xe1, 0x72, - 0x6e, 0x57, 0xf0, 0x15, 0x49, 0x3d, 0x18, 0xe8, 0x81, 0x15, 0xe3, 0x52, - 0x0b, 0x75, 0x25, 0x92, 0x42, 0x80, 0x35, 0xca, 0x80, 0x13, 0xa2, 0x25, - 0x57, 0x89, 0x7a, 0xd8, 0x92, 0x35, 0x58, 0xa9, 0x35, 0xc9, 0x41, 0xcc, - 0xa4, 0x6c, 0x13, 0x73, 0x39, 0x4f, 0x6d, 0x61, 0x44, 0x4e, 0x4d, 0xf3, - 0x85, 0x53, 0x78, 0x8e, 0xf6, 0x18, 0xe3, 0x34, 0x02, 0x19, 0xa8, 0x2b, - 0xaf, 0x03, 0x2c, 0xb9, 0x43, 0x0b, 0xda, 0x41, 0x02, 0xe9, 0x04, 0x20, - 0xfe, 0xf4, 0xaa, 0xc8, 0x87, 0x22, 0x22, 0x3b, 0xfe, 0x9d, 0x50, 0x79, - 0x9b, 0xc0, 0xb9, 0x91, 0x6f, 0xa4, 0x54, 0x89, 0x24, 0xc4, 0x9a, 0x64, - 0x99, 0x8b, 0x5c, 0x21, 0x42, 0x7f, 0x47, 0x2f, 0x60, 0xf8, 0x0a, 0x46, - 0xaf, 0x58, 0xbc, 0xeb, 0xa4, 0xb0, 0x45, 0xfc, 0xfc, 0x07, 0xa5, 0x49, - 0x24, 0x04, 0xa3, 0x6f, 0x95, 0xc6, 0xe2, 0x73, 0xc2, 0x4e, 0xac, 0x34, - 0xca, 0xd0, 0xbe, 0x33, 0x18, 0x32, 0x6e, 0x1e, 0xd6, 0xaa, 0x8b, 0x47, - 0x63, 0x73, 0x67, 0x95, 0x3c, 0x88, 0x27, 0xfd, 0xdd, 0x46, 0x1a, 0xc4, - 0xdd, 0xc4, 0x6e, 0xb7, 0xe9, 0x49, 0x49, 0x6a, 0x72, 0x15, 0x87, 0xad, - 0x50, 0x4c, 0x92, 0xf7, 0xfe, 0x12, 0xd7, 0x83, 0x95, 0x2a, 0xc9, 0x81, - 0x44, 0x85, 0x36, 0xf5, 0x08, 0x08, 0x17, 0xd4, 0x3e, 0x29, 0xd3, 0x35, - 0x84, 0x48, 0x4a, 0x34, 0xea, 0x67, 0x17, 0x9a, 0x1a, 0xaa, 0x86, 0x52, - 0x5c, 0x5b, 0x72, 0xdd, 0xa7, 0x28, 0x1a, 0xd2, 0xde, 0x2a, 0x1c, 0x0e, - 0xbb, 0x8d, 0xb9, 0x9d, 0x9c, 0xf0, 0x95, 0xb6, 0x72, 0xa7, 0xb1, 0x95, - 0x6d, 0xdc, 0x2d, 0xde, 0xca, 0x00, 0xd7, 0x68, 0x7b, 0x99, 0xf2, 0x74, - 0x31, 0x0b, 0x03, 0x85, 0x1c, 0xdd, 0x31, 0xd9, 0x32, 0x5c, 0x47, 0xbb, - 0x3b, 0xc3, 0x76, 0x39, 0xb8, 0xc6, 0x7f, 0xd5, 0xa6, 0x2d, 0xee, 0x19, - 0x47, 0xf8, 0xdd, 0x93, 0x76, 0xe8, 0x24, 0xc4, 0x3b, 0x77, 0x8d, 0x3a, - 0xfe, 0xc8, 0x6d, 0x5b, 0x71, 0x9b, 0x10, 0xde, 0xb4, 0x27, 0xd5, 0x8c, - 0x9e, 0x22, 0x3e, 0xe9, 0xb7, 0x91, 0xf2, 0x7e, 0xc0, 0xe7, 0x2c, 0xd1, - 0x6a, 0x33, 0x12, 0xe2, 0xe0, 0x30, 0x51, 0x0d, 0x14, 0x55, 0xf3, 0x0f, - 0x91, 0x35, 0x91, 0x06, 0x1f, 0x7c, 0xf6, 0x22, 0xe3, 0x88, 0xf6, 0xe0, - 0xbb, 0x6c, 0xbd, 0xd2, 0x9b, 0xa1, 0x34, 0x01, 0xb0, 0xf1, 0x23, 0x6e, - 0x74, 0xdf, 0x0b, 0xff, 0xd3, 0xc3, 0xe9, 0xad, 0xb6, 0x62, 0xe9, 0x79, - 0x85, 0x8b, 0x56, 0xfb, 0x56, 0x74, 0xc9, 0xce, 0x50, 0x0f, 0x98, 0xcf, - 0xc6, 0x45, 0x3a, 0xec, 0x51, 0x08, 0x99, 0x17, 0xe7, 0xdf, 0xd2, 0xe7, - 0x8d, 0x38, 0xbf, 0xff, 0x7f, 0x7b, 0xdf, 0xda, 0xd5, 0xc6, 0x91, 0xb5, - 0xfb, 0x19, 0x7e, 0x45, 0x8f, 0xd6, 0xeb, 0x15, 0x78, 0x47, 0x92, 0x31, - 0xbe, 0xfb, 0x78, 0x66, 0x82, 0x81, 0x24, 0x9c, 0xc1, 0xc0, 0x20, 0xec, - 0x64, 0x4e, 0x92, 0xc5, 0x6a, 0xa0, 0x81, 0x1e, 0x0b, 0x89, 0x51, 0x4b, - 0xc6, 0x24, 0x2b, 0xe7, 0xb7, 0xbf, 0xf5, 0x3c, 0xfb, 0x52, 0x55, 0x8d, - 0x20, 0x64, 0xe2, 0xac, 0xf3, 0xe5, 0x7c, 0xe1, 0x22, 0x75, 0xd7, 0x75, - 0xd7, 0xae, 0x7d, 0x7d, 0x36, 0x01, 0x60, 0x35, 0xb0, 0x74, 0xac, 0x35, - 0x52, 0x69, 0x9e, 0x7a, 0xb7, 0xbf, 0x9d, 0xdb, 0xa5, 0x26, 0xe6, 0x2b, - 0x97, 0xa7, 0x05, 0xf5, 0xba, 0x6e, 0xc7, 0x0d, 0xe2, 0x3d, 0x8d, 0x05, - 0x2c, 0x2f, 0xe5, 0x50, 0x25, 0xd2, 0x4f, 0xec, 0xcc, 0x84, 0x6f, 0xbc, - 0x0d, 0xf9, 0x5b, 0xed, 0x28, 0x80, 0x92, 0x48, 0x93, 0x64, 0x08, 0x20, - 0xc5, 0xe3, 0xc3, 0xbc, 0x90, 0x46, 0x0d, 0x5c, 0xff, 0x44, 0x29, 0x78, - 0x44, 0xc7, 0x08, 0x00, 0x05, 0xce, 0x67, 0x3d, 0xc4, 0x71, 0x68, 0x86, - 0x0c, 0xa9, 0x7c, 0xb8, 0xec, 0xa6, 0x4b, 0x4a, 0x5c, 0x92, 0xe9, 0x3a, - 0x56, 0xe0, 0x3b, 0x06, 0x40, 0xbb, 0x41, 0x4e, 0x0d, 0xaa, 0xa5, 0xc8, - 0xee, 0x96, 0x8b, 0x98, 0xa8, 0x08, 0xe1, 0x24, 0x8a, 0x49, 0x27, 0xd0, - 0xd7, 0xe8, 0x83, 0xba, 0x9e, 0xae, 0xc7, 0xb3, 0x49, 0x4a, 0x01, 0xb1, - 0x07, 0x4b, 0x83, 0x4d, 0xd6, 0x32, 0xd5, 0x36, 0x66, 0x8d, 0x1f, 0x2b, - 0x86, 0x44, 0x87, 0x93, 0xa2, 0xb0, 0xf1, 0xe7, 0x56, 0xe2, 0x23, 0xe9, - 0xbb, 0x34, 0xd4, 0x67, 0x5d, 0x23, 0xf9, 0x87, 0x6b, 0x9c, 0xb0, 0x1d, - 0x09, 0x95, 0x86, 0x80, 0x24, 0x51, 0x9d, 0x5a, 0xf6, 0x73, 0x58, 0x9d, - 0x06, 0xfa, 0x0a, 0xe4, 0x8b, 0x37, 0x11, 0x63, 0x9b, 0xac, 0xce, 0x44, - 0xa0, 0x40, 0xf4, 0x93, 0x1f, 0x96, 0x93, 0xdc, 0x39, 0xdd, 0xd3, 0x38, - 0x06, 0x74, 0x8d, 0x00, 0x07, 0xdb, 0xd0, 0x56, 0x37, 0x13, 0xc1, 0x69, - 0xd3, 0x8e, 0xe2, 0xc9, 0xe2, 0xe7, 0x2c, 0xf5, 0xce, 0x04, 0xb8, 0xe3, - 0x20, 0xb8, 0x07, 0xb2, 0x8d, 0xe6, 0x4e, 0xc3, 0x5d, 0xf6, 0x8e, 0xa8, - 0xde, 0x2d, 0x79, 0xe1, 0x5c, 0x86, 0xc7, 0x0a, 0x64, 0x2d, 0xb6, 0x39, - 0xe8, 0x64, 0xf5, 0xa8, 0xc8, 0x8e, 0x72, 0x99, 0xc6, 0x38, 0x8b, 0xae, - 0xb8, 0x36, 0x64, 0x18, 0xf1, 0xb4, 0x42, 0xb8, 0x49, 0xd6, 0x7a, 0xa7, - 0xcf, 0xc6, 0xb5, 0x6d, 0x01, 0xf1, 0x5c, 0x16, 0x44, 0x33, 0x4b, 0x1d, - 0x8c, 0x64, 0x6c, 0xbd, 0xa0, 0x1b, 0x8c, 0xca, 0xe3, 0x0f, 0x7c, 0x14, - 0x0c, 0x81, 0x65, 0x72, 0x83, 0xd8, 0xe5, 0x88, 0x6b, 0xee, 0x72, 0x1c, - 0x0d, 0xf0, 0x50, 0xc9, 0x48, 0x94, 0x92, 0xbf, 0xa5, 0x6c, 0x51, 0xaa, - 0x0d, 0x4b, 0x3b, 0x70, 0x5c, 0x56, 0x54, 0x95, 0x78, 0x36, 0x23, 0xdf, - 0x70, 0xf0, 0xcd, 0xa4, 0x72, 0x49, 0x92, 0xd8, 0xa8, 0x75, 0xbc, 0x96, - 0x80, 0xe8, 0x4b, 0x62, 0x20, 0x59, 0xec, 0xbd, 0x3b, 0x50, 0x8f, 0xfb, - 0xfc, 0xa8, 0xbe, 0x7f, 0xb6, 0xeb, 0x18, 0xd1, 0xb4, 0x9c, 0x33, 0x0c, - 0x41, 0x26, 0xe2, 0xa5, 0x87, 0xb3, 0xe8, 0x0e, 0x00, 0x95, 0xc7, 0xcc, - 0x09, 0x30, 0x0a, 0x4b, 0xbd, 0x89, 0xa7, 0xf2, 0xb7, 0xff, 0x2c, 0x6f, - 0x5d, 0x96, 0xf5, 0xc4, 0x17, 0x93, 0x88, 0x1f, 0x25, 0xd5, 0x6a, 0x79, - 0x34, 0xb1, 0x6d, 0x60, 0x55, 0x29, 0xd5, 0xf7, 0x2d, 0x70, 0x4c, 0x5c, - 0xfd, 0x9e, 0x36, 0xcc, 0x2b, 0xf3, 0x48, 0x4c, 0xae, 0x46, 0xfd, 0x79, - 0x9f, 0x26, 0xdc, 0x9f, 0xd1, 0x01, 0xd2, 0xa5, 0x07, 0x5b, 0x22, 0xbc, - 0xe4, 0x94, 0x4a, 0x78, 0xba, 0xf6, 0x1c, 0xa5, 0x1a, 0xbc, 0xda, 0x68, - 0x49, 0x8d, 0xb4, 0x4e, 0x33, 0x19, 0x50, 0x44, 0x6f, 0x52, 0x68, 0x67, - 0x7c, 0xea, 0x23, 0x61, 0xca, 0x6d, 0x62, 0x16, 0xd7, 0xf3, 0x92, 0x30, - 0x4c, 0x29, 0xe4, 0xc9, 0x2e, 0xd9, 0xcc, 0x18, 0x1b, 0x26, 0xa8, 0x47, - 0x42, 0x0b, 0xaf, 0xa4, 0x6e, 0xae, 0x6e, 0xba, 0x68, 0xc0, 0x29, 0x10, - 0xb8, 0xd1, 0xd1, 0x91, 0xa2, 0x20, 0x3c, 0x7d, 0xbc, 0xba, 0x5a, 0x88, - 0xb5, 0x44, 0x2a, 0x04, 0x68, 0xea, 0x29, 0x9a, 0xb6, 0x14, 0x6a, 0x59, - 0x9c, 0x88, 0xd1, 0xc3, 0x18, 0x4f, 0x3b, 0x8f, 0x96, 0x8e, 0x89, 0xb3, - 0x8c, 0x02, 0xbc, 0xc5, 0xd1, 0xf8, 0xe4, 0x3a, 0xb6, 0x18, 0xb6, 0x77, - 0x02, 0xfe, 0x15, 0x0e, 0xb9, 0x42, 0x07, 0x31, 0x5e, 0xa1, 0x6c, 0x8a, - 0x88, 0xac, 0x17, 0xcb, 0x4f, 0x53, 0xda, 0x3d, 0x06, 0xc1, 0x8f, 0x40, - 0x2c, 0x23, 0xfe, 0x09, 0x49, 0xe2, 0x74, 0x36, 0x61, 0xb9, 0x60, 0xca, - 0xf1, 0x81, 0xdf, 0x5c, 0x95, 0xd7, 0xfd, 0x36, 0x7d, 0x19, 0x61, 0x86, - 0xb9, 0x8e, 0x8f, 0x59, 0xf0, 0xc0, 0x23, 0x13, 0xf4, 0x68, 0x62, 0x21, - 0x85, 0x3b, 0x20, 0x09, 0x00, 0xb8, 0xb3, 0x04, 0xe6, 0xc5, 0x1e, 0x88, - 0x09, 0xc0, 0xa0, 0x87, 0xf2, 0xd0, 0x8d, 0xf0, 0xfd, 0x9c, 0x44, 0xaa, - 0xbb, 0x23, 0x5a, 0x0f, 0x6e, 0x0f, 0xb4, 0xce, 0x1f, 0xeb, 0xd4, 0x17, - 0x67, 0xdf, 0x3f, 0xea, 0x3d, 0x5a, 0x59, 0x59, 0xf9, 0xb1, 0x7f, 0x39, - 0x3a, 0xeb, 0x28, 0xb0, 0x4e, 0xf8, 0xd9, 0xcf, 0x12, 0xaf, 0xf2, 0x7b, - 0x3e, 0x99, 0x78, 0xe7, 0x67, 0xfc, 0x7a, 0xd4, 0xc5, 0xcf, 0xd5, 0x5f, - 0x3a, 0xf7, 0xe8, 0x93, 0xaf, 0xe9, 0xef, 0xb9, 0xfa, 0xcc, 0xfd, 0xe4, - 0x85, 0xb3, 0x8a, 0xd9, 0x78, 0xa0, 0x80, 0x2e, 0x83, 0xc3, 0x0d, 0xc2, - 0x0e, 0x22, 0x17, 0x28, 0x2f, 0xca, 0x5b, 0xa1, 0xdf, 0xd7, 0xe1, 0x87, - 0xa9, 0xf0, 0x0e, 0x79, 0x8e, 0xa5, 0x27, 0xa5, 0x4d, 0x8f, 0xcf, 0x5b, - 0xce, 0x2a, 0xb5, 0xd7, 0xe1, 0x09, 0x58, 0x1b, 0x04, 0xb8, 0x87, 0x88, - 0xc9, 0x02, 0x08, 0x25, 0x8c, 0x7d, 0x49, 0x0a, 0x0c, 0x36, 0x45, 0x07, - 0x43, 0x0e, 0x23, 0xee, 0x44, 0xfd, 0xa7, 0x73, 0xaa, 0x9f, 0x84, 0xd6, - 0x97, 0x0d, 0xc5, 0x9c, 0xa5, 0x51, 0x69, 0x05, 0x0b, 0x74, 0x71, 0x36, - 0x83, 0xdb, 0xe4, 0xa8, 0x04, 0xff, 0x33, 0x86, 0x04, 0xbc, 0xf0, 0xbe, - 0x55, 0xc9, 0xf3, 0x0c, 0xf2, 0x6a, 0xa2, 0xf7, 0xcd, 0x91, 0x4a, 0x80, - 0xd2, 0x3d, 0xd3, 0x4c, 0x42, 0x5b, 0x1b, 0x5b, 0xeb, 0x41, 0x42, 0x42, - 0x5a, 0x4d, 0x97, 0xb8, 0x52, 0x5d, 0x01, 0x90, 0xea, 0x0a, 0x2c, 0x99, - 0x8f, 0x88, 0x27, 0x75, 0x2a, 0xf9, 0x4a, 0x65, 0xcc, 0x47, 0x74, 0x26, - 0xdc, 0x15, 0x33, 0xd3, 0x55, 0xdd, 0x68, 0xd9, 0x23, 0x13, 0xfa, 0x8a, - 0xe2, 0x6b, 0x0c, 0xd5, 0xe5, 0x4b, 0x4b, 0x8c, 0x81, 0x56, 0x5f, 0x09, - 0x2c, 0xdc, 0xa5, 0x4b, 0xee, 0x66, 0x57, 0x25, 0x5d, 0x47, 0xa3, 0x19, - 0x79, 0x0e, 0xd7, 0xae, 0x1b, 0x47, 0xa4, 0x95, 0x57, 0xa5, 0x38, 0x8c, - 0xc5, 0xb8, 0x96, 0x31, 0xf5, 0xcd, 0x86, 0xd8, 0xc5, 0xb7, 0x95, 0xc4, - 0x72, 0x4e, 0xc7, 0x3d, 0x4f, 0x01, 0xf1, 0x52, 0xdb, 0x6d, 0xbd, 0x7f, - 0x5c, 0x38, 0x46, 0xae, 0x58, 0x57, 0xe4, 0xd6, 0xd1, 0xed, 0x34, 0xbc, - 0x0e, 0xa9, 0x2a, 0x20, 0x0c, 0xa6, 0x67, 0x58, 0x03, 0x8a, 0xd3, 0x66, - 0x46, 0x6a, 0x4d, 0x3a, 0x10, 0x89, 0x29, 0x4f, 0xa3, 0x72, 0x50, 0xcd, - 0x62, 0x77, 0xe4, 0x60, 0x0e, 0xdd, 0x42, 0x2a, 0xa7, 0xd4, 0xc7, 0x33, - 0xd8, 0x54, 0x03, 0x19, 0x04, 0x32, 0x17, 0xca, 0xd0, 0xca, 0xe1, 0xb8, - 0x39, 0x78, 0x5d, 0xf9, 0xfd, 0x1c, 0xc6, 0x0a, 0xec, 0x60, 0xf5, 0x72, - 0x9b, 0x75, 0x32, 0x3e, 0x7d, 0x74, 0xad, 0x11, 0xa6, 0x22, 0x35, 0x82, - 0x10, 0x9b, 0xeb, 0x70, 0x91, 0x5f, 0xd0, 0xac, 0x08, 0xa3, 0xe2, 0x9f, - 0x6c, 0xb8, 0x20, 0xb0, 0xcf, 0x94, 0x8f, 0xc9, 0xb6, 0xee, 0x59, 0x1f, - 0xfa, 0x93, 0x1d, 0xbc, 0x56, 0x3e, 0x66, 0x68, 0xa2, 0x17, 0xce, 0x65, - 0x60, 0xdb, 0xaf, 0x71, 0x24, 0x4d, 0xd1, 0x09, 0x72, 0xc4, 0x32, 0x94, - 0x5c, 0x60, 0xaa, 0xd4, 0xd5, 0x71, 0xa5, 0x89, 0x55, 0x25, 0x36, 0x44, - 0xcc, 0x7a, 0xa5, 0x90, 0xf8, 0x9f, 0x55, 0xfd, 0xc0, 0xcd, 0xdb, 0x75, - 0x90, 0xff, 0xca, 0xee, 0xd9, 0x44, 0xba, 0x2e, 0xa4, 0x1b, 0x2c, 0xbd, - 0xe6, 0x71, 0x34, 0xd7, 0xa3, 0x29, 0x5c, 0xf8, 0x8d, 0x5a, 0x2b, 0x28, - 0x81, 0x52, 0x34, 0x2f, 0xa7, 0x1a, 0xdf, 0xed, 0xf4, 0x23, 0x1c, 0x03, - 0xc3, 0x55, 0xb6, 0x2f, 0x56, 0xd7, 0x51, 0x15, 0x93, 0xe4, 0x5f, 0xe5, - 0x0c, 0xc2, 0x6e, 0x66, 0x15, 0xe0, 0x0b, 0xe3, 0xf6, 0x5f, 0xfc, 0xf9, - 0x8b, 0x62, 0xe9, 0x72, 0x38, 0x6b, 0x96, 0x35, 0x2c, 0x78, 0x02, 0xae, - 0x64, 0xee, 0x54, 0xb1, 0x25, 0x7a, 0xc8, 0x56, 0xcc, 0x3c, 0x6a, 0x7a, - 0x84, 0xa2, 0x93, 0xde, 0x13, 0xa8, 0xba, 0x2a, 0x99, 0x17, 0xc5, 0x5d, - 0x3d, 0x57, 0x8d, 0x86, 0x1c, 0xc3, 0xf6, 0x05, 0xa1, 0xcc, 0x8e, 0x18, - 0x99, 0x20, 0x24, 0xab, 0x8b, 0x12, 0x06, 0xee, 0xf1, 0xa8, 0x25, 0xb7, - 0x62, 0xed, 0xfa, 0xd9, 0xc6, 0x98, 0xe9, 0xea, 0x36, 0x72, 0xb9, 0x29, - 0x22, 0xdd, 0x9d, 0x4c, 0x11, 0x5b, 0xc6, 0x0e, 0x22, 0x35, 0xfa, 0xd7, - 0x73, 0x2a, 0xe2, 0x3b, 0x7f, 0x91, 0x15, 0xe0, 0x71, 0x55, 0x9e, 0x6a, - 0x6f, 0x85, 0x73, 0xf1, 0xf0, 0x74, 0x3c, 0xbe, 0xab, 0xb7, 0x2f, 0xef, - 0x75, 0xed, 0x25, 0x2f, 0xf1, 0x05, 0x2a, 0x01, 0xbf, 0xe1, 0xa5, 0xce, - 0x9f, 0x39, 0xb3, 0x07, 0xab, 0x2b, 0x61, 0x38, 0x9d, 0xfb, 0x21, 0x93, - 0xbc, 0x68, 0xa3, 0x7e, 0xb6, 0xe8, 0x4d, 0x4e, 0xcf, 0x59, 0x54, 0x79, - 0xdf, 0x50, 0xe5, 0x6d, 0xd4, 0xf6, 0x90, 0x00, 0x4e, 0x0a, 0xbe, 0xa4, - 0x82, 0x40, 0x88, 0xbb, 0x25, 0xda, 0xe9, 0xa4, 0x82, 0xf7, 0x57, 0xe0, - 0x61, 0xbc, 0x0d, 0xb8, 0x8e, 0xd8, 0x61, 0x91, 0x3f, 0x8d, 0xe1, 0x54, - 0x23, 0x16, 0xca, 0x3a, 0x49, 0x32, 0x07, 0x4a, 0xe1, 0x8e, 0x72, 0x3a, - 0x44, 0xbf, 0x25, 0x45, 0x77, 0xfe, 0x17, 0x02, 0x59, 0xff, 0xb2, 0xd6, - 0xe9, 0x17, 0x73, 0xc2, 0x0e, 0x89, 0x46, 0xa9, 0x98, 0x11, 0xe6, 0x07, - 0x56, 0xf7, 0x94, 0x9a, 0x7e, 0x20, 0x33, 0x4d, 0xc1, 0x1f, 0xa8, 0x49, - 0x40, 0x0a, 0x0f, 0xb4, 0xfa, 0x78, 0xd5, 0x38, 0x58, 0x33, 0x27, 0x6c, - 0xc6, 0x67, 0x7d, 0x5b, 0x16, 0xec, 0x7c, 0x6c, 0x41, 0x4f, 0xc3, 0x6c, - 0x1b, 0x7e, 0xbc, 0xbd, 0x3b, 0xad, 0x17, 0x6f, 0x6e, 0x62, 0x0a, 0x3e, - 0xdc, 0xdf, 0x5c, 0xdb, 0x78, 0xbb, 0x39, 0x1f, 0x17, 0x34, 0x91, 0x34, - 0xbc, 0x75, 0xee, 0xdc, 0x4c, 0x77, 0x6e, 0x12, 0x84, 0x8e, 0xf0, 0xf3, - 0x95, 0x45, 0xbd, 0xb6, 0xc4, 0x0f, 0x93, 0xfa, 0x63, 0xf4, 0xb1, 0xb8, - 0xd5, 0x92, 0xe0, 0x70, 0xb1, 0xd8, 0xf3, 0x8e, 0x52, 0x4c, 0xc0, 0x14, - 0xb8, 0x37, 0x0f, 0x4a, 0xee, 0x17, 0xbb, 0x5e, 0xc1, 0x06, 0x1c, 0x79, - 0x3a, 0x39, 0xb6, 0x32, 0xdf, 0xf8, 0x5b, 0xb3, 0x7a, 0xcb, 0x61, 0x22, - 0xe7, 0x40, 0xde, 0x6c, 0x90, 0xd7, 0x7c, 0xed, 0x9a, 0xd3, 0x34, 0x29, - 0xb9, 0xa7, 0xe6, 0x8e, 0xc0, 0xa3, 0x2e, 0x2e, 0xa7, 0x8d, 0x56, 0x01, - 0x49, 0x42, 0x78, 0x9d, 0x43, 0xf9, 0x0c, 0xac, 0xe0, 0x36, 0x1e, 0x68, - 0x2c, 0x47, 0x61, 0x18, 0x76, 0x44, 0x52, 0x79, 0x44, 0x6d, 0x95, 0xc2, - 0x2f, 0x43, 0x3a, 0x47, 0x99, 0x19, 0xa0, 0xde, 0x37, 0x4a, 0x45, 0x4c, - 0x8f, 0xbd, 0xb8, 0x1c, 0x07, 0x61, 0x83, 0x5e, 0x0a, 0x8b, 0x47, 0x2a, - 0xe5, 0x15, 0x31, 0xa5, 0xa7, 0x83, 0x8c, 0xa1, 0xda, 0x79, 0x7e, 0x83, - 0xdc, 0x01, 0xbe, 0x94, 0xe1, 0x08, 0x74, 0x05, 0x8a, 0xdd, 0x06, 0x1e, - 0xae, 0x6c, 0xa5, 0x40, 0x95, 0x10, 0xd0, 0x37, 0xb3, 0x1e, 0xac, 0x52, - 0xf4, 0x39, 0xd7, 0x92, 0x9b, 0x24, 0xd2, 0xa0, 0xf9, 0xbc, 0x8d, 0xf5, - 0xab, 0xcb, 0x15, 0xa9, 0xb7, 0xcc, 0xf9, 0x0c, 0xc2, 0xdc, 0x50, 0x52, - 0x47, 0x1d, 0xd0, 0xc7, 0xf0, 0x9f, 0xaa, 0x11, 0x4d, 0x79, 0x61, 0x3a, - 0x5a, 0x35, 0xac, 0x48, 0x5d, 0x87, 0x69, 0x43, 0x32, 0xf5, 0x6b, 0xe4, - 0xfc, 0xea, 0x4d, 0x8f, 0x0c, 0xe6, 0x70, 0x4e, 0x29, 0x9b, 0x09, 0xb9, - 0x34, 0x2e, 0x2e, 0x52, 0x8b, 0x93, 0x79, 0x44, 0x27, 0x30, 0xab, 0x13, - 0x09, 0xee, 0x3c, 0xf6, 0xe0, 0x63, 0x2d, 0x8b, 0x29, 0x1b, 0x78, 0x31, - 0xe6, 0xad, 0xa5, 0xc6, 0xa8, 0xe3, 0x61, 0x55, 0x32, 0x19, 0x9d, 0x48, - 0xa3, 0xd1, 0xe9, 0xa9, 0x52, 0x15, 0x8f, 0xb5, 0x54, 0x62, 0x23, 0x5c, - 0x3d, 0x32, 0x92, 0x01, 0x58, 0x6f, 0xb0, 0x05, 0x29, 0x72, 0x1a, 0x04, - 0x27, 0xf3, 0x24, 0x93, 0x90, 0x47, 0x95, 0x93, 0xaa, 0xd9, 0x5f, 0xd8, - 0x9d, 0xb0, 0x83, 0x5b, 0x35, 0x1a, 0x51, 0x32, 0x45, 0xdc, 0xfe, 0x7b, - 0x35, 0x39, 0xaa, 0x26, 0xe3, 0xa6, 0x78, 0xff, 0xd4, 0x36, 0xba, 0x74, - 0xd4, 0x2c, 0x95, 0x9c, 0x0d, 0x45, 0x86, 0xda, 0x93, 0x0c, 0x36, 0xf5, - 0xce, 0x8b, 0x2d, 0xc6, 0x91, 0xb6, 0x52, 0xf1, 0x59, 0x15, 0xdc, 0x48, - 0xef, 0xe1, 0x83, 0x40, 0x2c, 0xa1, 0xb1, 0xd3, 0x4c, 0x08, 0xd4, 0x1e, - 0x18, 0x84, 0x4d, 0x99, 0x8c, 0x00, 0xb6, 0x81, 0xd2, 0x8e, 0xe8, 0x29, - 0x2e, 0x93, 0x71, 0x1e, 0xd4, 0x34, 0x5b, 0x52, 0x80, 0x4f, 0xc0, 0x50, - 0x62, 0x2e, 0xd5, 0x48, 0xeb, 0x47, 0xd4, 0xd8, 0xf8, 0x76, 0x5e, 0x41, - 0x04, 0xcd, 0x81, 0xf9, 0x06, 0xf8, 0xa1, 0xf3, 0x16, 0x65, 0xe7, 0x60, - 0xfb, 0x6d, 0xb7, 0x7d, 0x0a, 0xec, 0x16, 0x4f, 0x2c, 0x96, 0x7a, 0xb4, - 0xa9, 0xed, 0xfa, 0x5c, 0xe2, 0x64, 0x2d, 0xf4, 0x4e, 0x7c, 0xf4, 0x5c, - 0x97, 0xae, 0x17, 0x4a, 0x50, 0xa3, 0xa8, 0x9b, 0x95, 0xdc, 0xf2, 0xec, - 0x82, 0x00, 0xc8, 0xa7, 0xe1, 0x36, 0xd2, 0x64, 0x18, 0x84, 0xf7, 0x70, - 0xc8, 0x15, 0xfe, 0x99, 0xfc, 0xf3, 0x66, 0x89, 0xaf, 0xd8, 0x91, 0x6c, - 0x00, 0x4e, 0x76, 0x55, 0x93, 0xac, 0x37, 0xc6, 0x57, 0xa3, 0xde, 0x36, - 0x8a, 0x55, 0x14, 0xdb, 0xe3, 0xb3, 0xb0, 0x14, 0x3b, 0x9c, 0x55, 0x68, - 0xee, 0xdd, 0xde, 0x8e, 0x5e, 0x7e, 0xef, 0x98, 0x11, 0xb5, 0x17, 0x04, - 0xa8, 0xe3, 0xfa, 0x12, 0xb2, 0x1c, 0x9e, 0x59, 0x2e, 0x54, 0xdb, 0xc7, - 0x91, 0xe3, 0xbd, 0xa7, 0xfd, 0x87, 0xb9, 0x6c, 0x7e, 0xb7, 0xf6, 0x76, - 0x6f, 0x7b, 0xf3, 0x07, 0x49, 0xa5, 0x8a, 0xf0, 0xe2, 0xe1, 0xdf, 0x2f, - 0x53, 0x75, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x85, 0xde, 0xaf, 0x5b, 0xec, - 0x51, 0xec, 0xb0, 0x46, 0x3d, 0x83, 0xc1, 0xde, 0x56, 0xcf, 0xea, 0x59, - 0x92, 0x47, 0x1c, 0xd5, 0x23, 0xd8, 0x24, 0xc8, 0xf8, 0xaa, 0x09, 0x46, - 0x12, 0x89, 0x41, 0x1a, 0x7a, 0xff, 0xb4, 0x5b, 0xec, 0x58, 0x82, 0x64, - 0x57, 0x76, 0x8f, 0x3a, 0xc6, 0x46, 0x7d, 0x46, 0x7d, 0xb5, 0x5d, 0x93, - 0xd2, 0x2d, 0x01, 0xdc, 0xd2, 0x69, 0x35, 0x1c, 0x26, 0x70, 0x3d, 0x0c, - 0xeb, 0x18, 0x8a, 0x77, 0x20, 0xdd, 0xfe, 0x94, 0xf3, 0xca, 0xe9, 0xe4, - 0xae, 0xa4, 0x28, 0x2e, 0x81, 0x87, 0xa4, 0xd6, 0xc0, 0x6b, 0x2d, 0x1e, - 0x26, 0xfb, 0xab, 0xdc, 0x95, 0x47, 0x2c, 0x09, 0xc3, 0x7c, 0x05, 0xdb, - 0xe5, 0xac, 0x78, 0xd5, 0x31, 0x37, 0x42, 0x23, 0xc5, 0xda, 0xff, 0x90, - 0xd4, 0x1f, 0xae, 0xf6, 0xe4, 0x95, 0x46, 0x4f, 0xdc, 0x53, 0xf1, 0x88, - 0xd7, 0x5c, 0xae, 0x79, 0xac, 0xd9, 0x25, 0xdc, 0x2b, 0xcf, 0x30, 0xfb, - 0x2c, 0xf5, 0x47, 0xfc, 0x2c, 0x83, 0x84, 0x2c, 0x41, 0x5b, 0xbd, 0x35, - 0x3e, 0xa9, 0x32, 0xba, 0x47, 0xd0, 0x64, 0x85, 0x80, 0x3d, 0xb2, 0xd5, - 0x68, 0x5b, 0xc5, 0xb7, 0xa3, 0x61, 0x09, 0x13, 0xba, 0xb1, 0x14, 0x6d, - 0xa3, 0x8b, 0x52, 0x36, 0x52, 0xcb, 0x22, 0xf9, 0xd4, 0xca, 0x44, 0x24, - 0xd6, 0xb9, 0x7f, 0xcf, 0x60, 0x4e, 0x87, 0xc8, 0x6e, 0x70, 0x26, 0x8a, - 0xed, 0x96, 0x8a, 0x6e, 0xb1, 0x76, 0x12, 0x1a, 0xeb, 0x19, 0xfc, 0x5b, - 0x4b, 0x5f, 0x95, 0x6c, 0x47, 0xfb, 0x2e, 0x57, 0x58, 0x95, 0xa8, 0x71, - 0x9b, 0x11, 0xe3, 0x27, 0xdc, 0xeb, 0xd7, 0x51, 0x91, 0x99, 0x8e, 0xf3, - 0x25, 0x5b, 0xea, 0x74, 0x96, 0x05, 0xb0, 0x42, 0xea, 0x94, 0x34, 0x49, - 0x45, 0x40, 0x1d, 0xdd, 0x18, 0x5b, 0x03, 0x9b, 0xb4, 0xd0, 0x9c, 0xa8, - 0x3b, 0x54, 0x41, 0xfa, 0xde, 0xdb, 0x25, 0x71, 0xcd, 0x03, 0xa9, 0x71, - 0x8d, 0xec, 0x5d, 0xe5, 0x88, 0xb1, 0x04, 0x3d, 0xac, 0x7a, 0xf5, 0xb4, - 0xc8, 0x4c, 0x97, 0xa0, 0x55, 0xfa, 0x94, 0x97, 0x3a, 0x45, 0x27, 0x66, - 0x47, 0x26, 0x63, 0xfc, 0xa3, 0x68, 0x71, 0xad, 0xe8, 0x08, 0x35, 0xac, - 0xac, 0x3c, 0xef, 0xdc, 0x8f, 0x16, 0x75, 0x4d, 0x12, 0x24, 0x37, 0xfd, - 0xc8, 0x95, 0x61, 0xc3, 0x51, 0x2a, 0x5e, 0x7f, 0xff, 0xe0, 0x47, 0xaa, - 0x10, 0xb8, 0x09, 0x1f, 0x7e, 0x99, 0x86, 0xa6, 0x31, 0xbc, 0xdc, 0x11, - 0x97, 0x94, 0x54, 0x3a, 0x7c, 0x58, 0x43, 0x89, 0x3a, 0xdc, 0xf1, 0x8e, - 0xab, 0x3b, 0x9d, 0x62, 0x49, 0x05, 0x18, 0x9a, 0x1a, 0x3a, 0x99, 0x89, - 0x46, 0xcd, 0xf1, 0xa7, 0xb2, 0xc0, 0xd9, 0xda, 0x0a, 0x48, 0x47, 0xa7, - 0xd7, 0x59, 0x5e, 0x56, 0x85, 0x39, 0x02, 0x9d, 0x32, 0x9e, 0xc4, 0x2e, - 0x3f, 0x8b, 0x83, 0x8a, 0x3e, 0x7f, 0x75, 0x2b, 0xd1, 0x53, 0xa5, 0x11, - 0xf6, 0xd4, 0xc5, 0xe1, 0x5e, 0x12, 0x31, 0x25, 0x50, 0xc5, 0xd4, 0x30, - 0x76, 0x54, 0x55, 0x28, 0x81, 0x0b, 0x53, 0xac, 0xf5, 0xfe, 0x4f, 0xf8, - 0xb9, 0xd2, 0x7b, 0x29, 0x18, 0x3b, 0xcc, 0x29, 0x6d, 0x8e, 0xc7, 0xb4, - 0x94, 0x1f, 0xe4, 0xc5, 0x2a, 0x2d, 0x76, 0x4a, 0x62, 0x0c, 0xc1, 0x17, - 0xe7, 0x5b, 0x58, 0xa5, 0x06, 0x95, 0x0f, 0x2e, 0x46, 0x8e, 0x88, 0x00, - 0x15, 0xeb, 0x18, 0xfa, 0xaa, 0x8a, 0xb0, 0x2a, 0xa8, 0xd6, 0x40, 0xb5, - 0x53, 0x94, 0x58, 0x6a, 0xd4, 0xc3, 0xd8, 0x71, 0x93, 0x40, 0x08, 0x89, - 0x4b, 0xf5, 0x2a, 0x15, 0x7b, 0xed, 0x29, 0x71, 0xd9, 0xc4, 0xd6, 0xed, - 0x2a, 0xf6, 0xba, 0xb4, 0x82, 0x18, 0x5c, 0x6a, 0x04, 0xfd, 0x4d, 0x7d, - 0xda, 0x33, 0x1e, 0x34, 0x53, 0x37, 0xd6, 0x12, 0xf2, 0x2d, 0xd1, 0x82, - 0x8e, 0xee, 0x28, 0xe9, 0xf4, 0x7a, 0xd5, 0xa7, 0xcb, 0xd0, 0x4a, 0xaf, - 0xd3, 0x8d, 0x51, 0x90, 0x1c, 0xa4, 0xbe, 0x21, 0x48, 0x95, 0x4d, 0xd1, - 0xf9, 0xf9, 0x67, 0x7c, 0xf4, 0xcb, 0x2f, 0x9d, 0x08, 0xdf, 0x95, 0x0d, - 0x15, 0xe2, 0xf6, 0x84, 0x22, 0xea, 0x4d, 0xc4, 0x2f, 0x98, 0x00, 0xcc, - 0xe8, 0x22, 0x17, 0x0d, 0x0f, 0x64, 0xdf, 0xb2, 0xde, 0x45, 0xdf, 0xd3, - 0x3b, 0xdc, 0x92, 0xd8, 0xdc, 0xb3, 0x77, 0xb3, 0xbd, 0x42, 0x11, 0x2d, - 0xf5, 0xbc, 0x9b, 0xf5, 0x45, 0x0f, 0x2f, 0x90, 0x63, 0xd4, 0xb2, 0x27, - 0x27, 0x15, 0xe2, 0x04, 0xda, 0xf2, 0xd7, 0x21, 0x42, 0x96, 0x62, 0x40, - 0xb7, 0x30, 0xfe, 0x72, 0x08, 0x77, 0xd4, 0xf5, 0x8d, 0x14, 0xca, 0x64, - 0x96, 0x0f, 0x64, 0x4d, 0x2e, 0xc4, 0xf5, 0x92, 0x35, 0x88, 0xaa, 0x2b, - 0x61, 0x9d, 0x78, 0x9a, 0x3a, 0x8c, 0x79, 0xac, 0x3e, 0xd5, 0x66, 0xcd, - 0xb1, 0x85, 0x2d, 0x82, 0x5e, 0x25, 0x48, 0x3f, 0xae, 0x1e, 0x27, 0xd7, - 0x6a, 0x9c, 0x9b, 0x09, 0xfb, 0x3a, 0x24, 0x19, 0x0e, 0x6e, 0x89, 0xdb, - 0x66, 0x69, 0x0c, 0xe9, 0xd4, 0xcc, 0x5a, 0xf3, 0x56, 0xcc, 0xcb, 0xab, - 0x56, 0x26, 0x46, 0xce, 0x98, 0xa2, 0x12, 0x9f, 0x78, 0x90, 0xb2, 0x07, - 0x43, 0xe0, 0x6c, 0x7d, 0xfd, 0x65, 0x0c, 0x44, 0xdc, 0xf1, 0x34, 0x49, - 0x21, 0xb5, 0x91, 0x94, 0x2c, 0x72, 0x75, 0xa8, 0x57, 0x70, 0x21, 0x74, - 0x2a, 0x43, 0xfc, 0x3f, 0x9f, 0x36, 0x62, 0x01, 0x54, 0xd9, 0x94, 0x24, - 0xfc, 0x2c, 0x15, 0x5b, 0x85, 0x50, 0x71, 0x14, 0xfd, 0x55, 0x53, 0xb1, - 0xa2, 0x3f, 0xac, 0x34, 0xbf, 0x4e, 0x71, 0x3a, 0x1b, 0x1d, 0x2b, 0x08, - 0x56, 0x0c, 0x0c, 0x05, 0xa1, 0x12, 0x49, 0x28, 0xdf, 0x3d, 0x3b, 0x81, - 0x8c, 0xfd, 0xa2, 0x15, 0x75, 0x54, 0xeb, 0x55, 0x06, 0x7f, 0x34, 0x3d, - 0x83, 0x70, 0xef, 0xc2, 0xa0, 0xa8, 0x62, 0xab, 0xb6, 0x2e, 0xbc, 0x30, - 0x2e, 0x12, 0x07, 0xd9, 0x28, 0x00, 0x22, 0x82, 0xde, 0xc4, 0xda, 0x2f, - 0x72, 0x91, 0x9e, 0xad, 0x91, 0xc4, 0xf0, 0x45, 0x8b, 0x5a, 0xd0, 0x0f, - 0x51, 0x58, 0x22, 0x19, 0x72, 0x62, 0x31, 0x4b, 0x42, 0xff, 0x18, 0xf9, - 0x67, 0xd0, 0x44, 0x45, 0x85, 0x5d, 0x2f, 0x1d, 0x21, 0x40, 0x58, 0x43, - 0x75, 0x3a, 0xed, 0x4d, 0xc7, 0x3d, 0xb1, 0xd1, 0x51, 0x09, 0xe9, 0x17, - 0xef, 0x5b, 0xf3, 0x2c, 0xce, 0x03, 0x77, 0xc2, 0xc0, 0x46, 0xb0, 0xaf, - 0x2b, 0x20, 0x5c, 0x5c, 0x23, 0xe8, 0x7a, 0xd8, 0x34, 0xb5, 0x21, 0x0a, - 0x3b, 0x91, 0xc5, 0x87, 0x6d, 0x5f, 0x4d, 0x35, 0x46, 0xce, 0xb6, 0x45, - 0x6b, 0x31, 0xb4, 0xd0, 0x66, 0x61, 0x96, 0xce, 0x20, 0xad, 0xe0, 0x9e, - 0x5b, 0xb0, 0xeb, 0x1f, 0xc4, 0x30, 0x54, 0xdf, 0x2f, 0x97, 0xc4, 0xa2, - 0x13, 0x82, 0x1a, 0x0f, 0x50, 0x2c, 0x61, 0x0d, 0xf2, 0xee, 0xbf, 0x9a, - 0xf1, 0x08, 0xef, 0x1a, 0x70, 0xd2, 0x34, 0x32, 0x4c, 0xd5, 0x63, 0xfe, - 0xf7, 0x60, 0x77, 0xc7, 0x24, 0x22, 0xc8, 0x3f, 0xf8, 0x3d, 0x99, 0x05, - 0xe2, 0xb0, 0x26, 0x10, 0x06, 0x10, 0x5a, 0x88, 0xc1, 0xc5, 0xf6, 0x3e, - 0xec, 0x54, 0x4b, 0x41, 0xdc, 0x3e, 0x0e, 0xff, 0x2c, 0x17, 0x2d, 0x93, - 0xe9, 0xd1, 0xb3, 0x27, 0x78, 0x4b, 0xe6, 0xdd, 0x3a, 0xed, 0x50, 0x18, - 0x9f, 0x3d, 0xb1, 0x37, 0xe6, 0xb3, 0xc3, 0xcf, 0x61, 0x38, 0xcf, 0x2e, - 0x9a, 0xbf, 0x34, 0x17, 0x62, 0x89, 0x52, 0x86, 0x8d, 0x47, 0x3a, 0x73, - 0x24, 0x8a, 0x87, 0xce, 0xa8, 0x7f, 0x3d, 0x9e, 0x2f, 0x97, 0x75, 0x3f, - 0x76, 0x63, 0x90, 0x91, 0xbc, 0xfa, 0x96, 0xc6, 0x14, 0x8e, 0xc6, 0x02, - 0xbb, 0xa4, 0xee, 0x67, 0x2b, 0xfa, 0x84, 0xe9, 0x6e, 0x88, 0x41, 0x16, - 0xc0, 0xd0, 0xa3, 0xd9, 0xd9, 0x99, 0x85, 0xbc, 0x1b, 0x43, 0xad, 0x64, - 0x83, 0xcb, 0xe9, 0x17, 0xf0, 0x5a, 0x33, 0x04, 0x1e, 0x1c, 0x83, 0x17, - 0xb7, 0xb4, 0x76, 0x3e, 0x1e, 0x9f, 0x30, 0xe2, 0x55, 0x6a, 0x5a, 0xd0, - 0x1e, 0x1e, 0xc5, 0x5c, 0x15, 0x6c, 0x24, 0x01, 0x5b, 0x65, 0x24, 0x49, - 0x12, 0xa2, 0xbd, 0x30, 0x9c, 0x36, 0x0c, 0x33, 0x30, 0x84, 0xd7, 0xfa, - 0x4c, 0xf6, 0x90, 0x64, 0x0f, 0x89, 0x8f, 0x29, 0x55, 0x83, 0xec, 0x2c, - 0x9d, 0xd7, 0x61, 0x91, 0x46, 0x12, 0xb6, 0x10, 0xb4, 0xc0, 0xa1, 0xb0, - 0x22, 0x4d, 0x4e, 0x2a, 0x75, 0x48, 0xad, 0x11, 0xfd, 0x77, 0x3a, 0x22, - 0x8b, 0x6f, 0x0d, 0xaf, 0x22, 0x6e, 0x3f, 0xca, 0x91, 0x3a, 0xb0, 0x44, - 0x74, 0x16, 0xad, 0x4c, 0x50, 0x3e, 0x98, 0x0f, 0x98, 0x63, 0x90, 0x47, - 0xdb, 0x94, 0x46, 0x44, 0x74, 0x33, 0x54, 0xe6, 0xc4, 0xd3, 0x90, 0x60, - 0x37, 0x7b, 0xc0, 0x3b, 0x39, 0x18, 0xe0, 0x5c, 0x48, 0x37, 0xf3, 0xe5, - 0x76, 0xc6, 0xe9, 0xe4, 0xf1, 0x13, 0x62, 0xe5, 0x89, 0xf8, 0x0d, 0x14, - 0xed, 0xf1, 0xac, 0x1a, 0x9c, 0xcc, 0x31, 0xd6, 0x75, 0x47, 0x53, 0x5e, - 0x81, 0xd3, 0x03, 0x00, 0x5b, 0x51, 0xdf, 0x8a, 0x1c, 0xf7, 0xff, 0x43, - 0xec, 0xff, 0x58, 0x94, 0x75, 0x5b, 0xce, 0xdf, 0x50, 0xf2, 0xe1, 0xae, - 0x08, 0xc7, 0x18, 0x68, 0x78, 0x17, 0x73, 0xd2, 0x3e, 0x7f, 0x7b, 0xa8, - 0xfd, 0x1c, 0x60, 0x01, 0x8f, 0x72, 0x6c, 0xa5, 0xf3, 0xdc, 0xd0, 0x8e, - 0xf4, 0x1c, 0x74, 0xbd, 0x22, 0x40, 0xb7, 0x15, 0x24, 0x99, 0xbd, 0x2d, - 0x7c, 0xed, 0xbd, 0xf2, 0xb5, 0x08, 0x44, 0xb8, 0xa1, 0x71, 0xa8, 0x69, - 0x8e, 0x8d, 0x22, 0xf1, 0x09, 0x15, 0xaa, 0x10, 0x6c, 0x00, 0x0a, 0x0e, - 0xd9, 0x46, 0x87, 0x5f, 0x93, 0x4a, 0xef, 0x62, 0x88, 0x16, 0x06, 0xe1, - 0x29, 0xa5, 0x8a, 0x60, 0x8d, 0xeb, 0xd5, 0x5e, 0xb5, 0xdc, 0xe4, 0x6e, - 0x04, 0xbc, 0x89, 0xec, 0x51, 0x94, 0x9d, 0xc7, 0x40, 0xc5, 0x08, 0x2c, - 0xe6, 0x5a, 0xb3, 0x88, 0x71, 0x08, 0x42, 0xbb, 0x1f, 0xa2, 0x82, 0x02, - 0x37, 0x62, 0x75, 0x3c, 0x9b, 0xa6, 0x28, 0xba, 0x07, 0x2c, 0xcd, 0x27, - 0x45, 0x99, 0x39, 0x8a, 0xa5, 0xcc, 0x93, 0xd8, 0xd9, 0xaf, 0x58, 0xef, - 0xb4, 0xb7, 0x11, 0x44, 0x85, 0x57, 0x9d, 0xe5, 0x2c, 0xcb, 0x66, 0x22, - 0xdf, 0xb9, 0x95, 0x36, 0x6b, 0x34, 0x30, 0x88, 0xc9, 0x49, 0xde, 0xa4, - 0xb4, 0xb8, 0xa7, 0xde, 0xf4, 0x06, 0xcd, 0x49, 0x6b, 0xb8, 0xd2, 0xcd, - 0xc9, 0x9e, 0x09, 0x13, 0x36, 0xd7, 0x49, 0xa5, 0x52, 0xb3, 0x23, 0x50, - 0x64, 0x8b, 0x38, 0x46, 0x64, 0xcc, 0xdc, 0xe1, 0x7f, 0x25, 0xe1, 0x3b, - 0x49, 0x5f, 0x7a, 0x44, 0x8e, 0xbd, 0x3a, 0x42, 0x73, 0x6b, 0x57, 0x63, - 0x82, 0x2e, 0xa7, 0xb2, 0x89, 0xbe, 0x61, 0x5b, 0x65, 0x22, 0x4a, 0x39, - 0x9c, 0xf6, 0x9a, 0x8f, 0xc7, 0x44, 0x2e, 0x56, 0x80, 0x0c, 0x53, 0x1a, - 0xd6, 0xc2, 0x57, 0x83, 0x8f, 0xc7, 0xaf, 0xec, 0x3e, 0x49, 0xdc, 0xad, - 0x2e, 0xfb, 0x34, 0xd7, 0xa3, 0xe3, 0xf3, 0x8d, 0x9d, 0x01, 0xde, 0x27, - 0xd5, 0x73, 0x20, 0x94, 0x93, 0x82, 0xee, 0x84, 0x2f, 0x83, 0xd4, 0x3b, - 0x9e, 0x35, 0xaa, 0xfc, 0x84, 0x01, 0xa0, 0xd8, 0x5a, 0xd3, 0xd7, 0x37, - 0xf5, 0xcb, 0x42, 0xb0, 0x3b, 0x17, 0xec, 0x6b, 0x93, 0x23, 0x24, 0xc5, - 0x59, 0x58, 0xad, 0xea, 0x48, 0x12, 0x73, 0xd6, 0x2b, 0x31, 0x15, 0x1d, - 0x27, 0xe2, 0x7c, 0x31, 0xc2, 0x93, 0xd8, 0xc2, 0x24, 0xe6, 0x21, 0x9b, - 0x54, 0x13, 0xf6, 0x68, 0x58, 0xb7, 0xa7, 0x19, 0x4b, 0x66, 0xc8, 0xf7, - 0x9e, 0xec, 0xcb, 0x62, 0xa2, 0x68, 0x47, 0xa3, 0xe9, 0xac, 0x99, 0xf5, - 0xc0, 0x01, 0xd7, 0x83, 0x98, 0x8c, 0x86, 0x38, 0x55, 0xd6, 0x00, 0x4b, - 0xd1, 0x9b, 0x1c, 0x67, 0x84, 0x6c, 0xcc, 0x63, 0x1b, 0x55, 0x61, 0x93, - 0x40, 0x85, 0x46, 0x70, 0x7a, 0x17, 0x96, 0x58, 0xd3, 0x6c, 0xf3, 0xcd, - 0xfa, 0xc6, 0xd6, 0xfa, 0xb2, 0xf6, 0xb0, 0x01, 0x21, 0x62, 0xce, 0x72, - 0x96, 0x71, 0x9f, 0xa5, 0x3b, 0xe9, 0x8d, 0x8f, 0xab, 0xc9, 0x4b, 0x0c, - 0xab, 0x40, 0x69, 0x1c, 0x43, 0xaf, 0x58, 0xa0, 0x98, 0x4a, 0xbe, 0xf0, - 0xc1, 0x24, 0xce, 0x70, 0x69, 0x5f, 0x20, 0x16, 0x35, 0x11, 0x55, 0x58, - 0xd3, 0x9b, 0x86, 0x5f, 0x34, 0xde, 0x3b, 0x81, 0x0d, 0x19, 0xf2, 0x0d, - 0x06, 0x88, 0xbb, 0xfa, 0x4f, 0xc6, 0x0c, 0xd7, 0xbf, 0xc1, 0xb0, 0xc2, - 0x2f, 0x9f, 0x22, 0x29, 0x82, 0x75, 0x39, 0x6c, 0x7d, 0xce, 0x9a, 0xb2, - 0x19, 0xca, 0xe8, 0x2b, 0x5d, 0x97, 0x1e, 0x6e, 0xf5, 0xc1, 0x1a, 0xf0, - 0xaa, 0xe6, 0x54, 0xbe, 0x34, 0xbe, 0xe1, 0x51, 0x02, 0x4d, 0x21, 0x51, - 0x6e, 0x0b, 0x5e, 0xcd, 0x79, 0x7d, 0x7f, 0xed, 0xad, 0xd7, 0xed, 0xb3, - 0x35, 0xc0, 0xba, 0x27, 0xeb, 0x10, 0x3e, 0x66, 0xd7, 0x36, 0x8e, 0xaf, - 0x07, 0x83, 0xde, 0xda, 0xde, 0x16, 0x46, 0xa2, 0x7f, 0x32, 0x4f, 0xcf, - 0x42, 0xf3, 0xec, 0xb1, 0x6f, 0x06, 0x07, 0x24, 0x5d, 0xfc, 0xbe, 0x63, - 0x56, 0x20, 0x02, 0x82, 0x31, 0x32, 0x4b, 0x7e, 0xd5, 0x9f, 0x74, 0x7c, - 0x5c, 0x9b, 0x68, 0xfa, 0xc2, 0x63, 0x7f, 0xe1, 0xf1, 0xfd, 0x5e, 0x18, - 0x88, 0xd1, 0x2b, 0xdf, 0xfb, 0x79, 0x08, 0x36, 0x7c, 0x58, 0x6a, 0x26, - 0xb8, 0x80, 0xb3, 0xb1, 0x93, 0xbf, 0xe7, 0x8a, 0x61, 0xf8, 0x26, 0x28, - 0xa0, 0x0a, 0xa2, 0xab, 0x82, 0x5a, 0xe2, 0x43, 0x88, 0x22, 0xd2, 0xde, - 0xc7, 0x67, 0x68, 0xc2, 0x62, 0x41, 0xb1, 0xd8, 0xf8, 0x2c, 0x9a, 0x88, - 0xec, 0x49, 0x37, 0xcf, 0x87, 0xa7, 0x53, 0xff, 0x52, 0x6b, 0x73, 0xe7, - 0xad, 0xf7, 0x36, 0xe0, 0xc0, 0x15, 0xdd, 0x7a, 0xde, 0x60, 0x63, 0xa1, - 0xfa, 0x70, 0x69, 0x10, 0x3b, 0x5c, 0xe2, 0x31, 0xbb, 0x1a, 0x96, 0x29, - 0x70, 0xe2, 0x66, 0x14, 0x5b, 0x58, 0xfd, 0xfa, 0x8d, 0xb5, 0x1c, 0x08, - 0xe0, 0x27, 0x34, 0xea, 0xd5, 0x60, 0x21, 0xb9, 0xa5, 0xa7, 0xb9, 0x58, - 0xfa, 0x58, 0x23, 0x64, 0xec, 0xa7, 0xfa, 0xb2, 0xcb, 0xf8, 0x28, 0x18, - 0x93, 0x96, 0x25, 0x7a, 0x34, 0x26, 0xa7, 0x87, 0x16, 0xa4, 0x27, 0x3f, - 0xfc, 0x73, 0xe7, 0xf1, 0x16, 0xe2, 0xc6, 0x60, 0xb0, 0x7d, 0xcb, 0x34, - 0x5c, 0x1a, 0xc9, 0x10, 0x11, 0x4c, 0x16, 0x3c, 0xd8, 0x7e, 0x8b, 0xf7, - 0xe8, 0xc7, 0xb8, 0xc7, 0x9a, 0xe1, 0xb9, 0xc3, 0x6f, 0xdf, 0xf8, 0x2b, - 0x27, 0x15, 0x70, 0xb8, 0x4d, 0x05, 0xbf, 0xaa, 0x47, 0x47, 0x35, 0x0a, - 0x1a, 0x57, 0xc3, 0x4b, 0xc5, 0x28, 0x6b, 0x37, 0xb0, 0x27, 0xe3, 0x0c, - 0xbf, 0xf8, 0xf5, 0xb9, 0x33, 0xa7, 0xbd, 0xd9, 0xd1, 0x30, 0x2c, 0xd4, - 0x60, 0x16, 0xe4, 0xcb, 0x4f, 0xc5, 0x36, 0x8d, 0x90, 0x8c, 0x03, 0xa5, - 0x60, 0x4f, 0x71, 0x55, 0x64, 0x65, 0x09, 0x28, 0x5f, 0xc8, 0xa9, 0x57, - 0x08, 0x23, 0x42, 0x7e, 0x8b, 0x14, 0xd1, 0xb9, 0x94, 0x46, 0x1b, 0x36, - 0x5a, 0x35, 0x6e, 0x34, 0x1b, 0xec, 0xed, 0x6c, 0x7e, 0xbd, 0x4b, 0x06, - 0xcc, 0xbf, 0xee, 0x33, 0x75, 0x5d, 0x61, 0x60, 0xdd, 0x39, 0xd2, 0x09, - 0x37, 0x0c, 0xfa, 0x21, 0x2f, 0x8e, 0xe4, 0xea, 0x15, 0x6f, 0xb9, 0x35, - 0xd1, 0x8d, 0xd5, 0x55, 0xf4, 0x18, 0x0e, 0xba, 0x5a, 0x39, 0x92, 0xc5, - 0x22, 0xa5, 0x7e, 0xc6, 0xb8, 0x88, 0x78, 0xad, 0xf0, 0x4d, 0x49, 0x6f, - 0xb7, 0x30, 0x0b, 0x45, 0xd6, 0xe3, 0x33, 0xfb, 0x7b, 0xc5, 0xd2, 0x40, - 0x2a, 0x75, 0xef, 0x4b, 0x28, 0x3f, 0x0b, 0x17, 0xc0, 0x7b, 0xb4, 0x7c, - 0x93, 0xcb, 0x25, 0x8d, 0x69, 0xc8, 0xd4, 0x42, 0x5a, 0x0b, 0x14, 0x0c, - 0xfa, 0x2d, 0xf9, 0x32, 0xda, 0x26, 0x47, 0x37, 0x3e, 0xed, 0xcc, 0x7b, - 0xde, 0x80, 0xde, 0x8d, 0x6a, 0xe8, 0xe1, 0x44, 0x81, 0x95, 0x3f, 0x9d, - 0x45, 0x84, 0x6e, 0xd5, 0xe7, 0x96, 0x3c, 0xfc, 0x69, 0xc0, 0x9c, 0x90, - 0x46, 0x5f, 0xf8, 0xa4, 0x29, 0x26, 0x4d, 0xce, 0xf9, 0xf2, 0x1b, 0xfe, - 0xa7, 0x66, 0x7a, 0x92, 0x9f, 0xab, 0x79, 0xc7, 0x0a, 0x4f, 0xc9, 0x59, - 0x4a, 0xd0, 0x32, 0xf4, 0xcc, 0xf2, 0x28, 0xe9, 0x1e, 0xcc, 0x9d, 0xc6, - 0xad, 0x52, 0x36, 0xc5, 0xd6, 0x39, 0x6e, 0x82, 0xe1, 0xa5, 0x8a, 0xbc, - 0x17, 0xe5, 0x68, 0x56, 0xc6, 0x4a, 0x2f, 0x1f, 0x87, 0xe5, 0x28, 0xf0, - 0xd0, 0x7a, 0xcc, 0x82, 0xe7, 0xaf, 0xed, 0x2f, 0x73, 0x5a, 0xad, 0x21, - 0x66, 0x0e, 0xfe, 0x81, 0xf7, 0xdb, 0x6b, 0x3b, 0x85, 0x3f, 0x07, 0x94, - 0x1c, 0xc2, 0x1b, 0xd3, 0x54, 0xb0, 0xb5, 0xb9, 0xb9, 0x59, 0xbc, 0x58, - 0x59, 0xed, 0x3f, 0xfa, 0x47, 0xa6, 0xc9, 0x04, 0xcd, 0x64, 0x78, 0x62, - 0xc8, 0xc5, 0x61, 0xde, 0x9b, 0x90, 0x46, 0x50, 0x94, 0x62, 0x88, 0xfb, - 0xb2, 0x1b, 0x73, 0x21, 0x04, 0xf7, 0x11, 0x67, 0x83, 0xde, 0x5e, 0x49, - 0xdc, 0x30, 0x98, 0xd7, 0x69, 0x5e, 0x4c, 0xb4, 0x12, 0xec, 0xd6, 0x62, - 0x82, 0x82, 0xe5, 0x12, 0xa1, 0x12, 0x47, 0x4d, 0xf5, 0x7c, 0x85, 0xf6, - 0xde, 0xe7, 0xea, 0x3d, 0xcc, 0x27, 0xf8, 0x87, 0x21, 0x08, 0xe6, 0xdd, - 0x3c, 0xb9, 0x5f, 0x9a, 0xdd, 0xcb, 0x96, 0x85, 0xa5, 0xbe, 0xec, 0x4d, - 0xc7, 0x8e, 0x13, 0x7a, 0x05, 0x4d, 0x84, 0x5e, 0x02, 0x44, 0x89, 0x16, - 0xaf, 0x45, 0xf9, 0xf8, 0x6b, 0x34, 0xb6, 0x58, 0x98, 0xbf, 0xd5, 0xda, - 0xc8, 0x14, 0x14, 0xc1, 0x1b, 0xd2, 0xa8, 0xa8, 0xa2, 0x3c, 0xa5, 0x3c, - 0x55, 0x6a, 0xc6, 0x2d, 0xfc, 0x67, 0x96, 0x35, 0xa0, 0xd7, 0x47, 0x5f, - 0x65, 0x6b, 0xbc, 0x2f, 0xfe, 0x18, 0x73, 0x49, 0x12, 0xca, 0x2e, 0x34, - 0x6f, 0x1a, 0xb4, 0x14, 0xa4, 0xd3, 0xf8, 0x2a, 0xb8, 0x07, 0x12, 0x8f, - 0x05, 0xcb, 0x2e, 0x8d, 0x66, 0x17, 0x47, 0xf0, 0x03, 0x9e, 0x46, 0xdb, - 0x6b, 0xbf, 0x48, 0x9b, 0x37, 0x59, 0x35, 0x51, 0x60, 0xcb, 0x88, 0xab, - 0x3e, 0x0c, 0x33, 0xc6, 0x8e, 0x74, 0x64, 0x00, 0x1d, 0x22, 0xda, 0x9a, - 0xcf, 0x8e, 0xf8, 0x04, 0x2a, 0xb9, 0x6b, 0xfe, 0x95, 0x36, 0x9a, 0x86, - 0x87, 0x24, 0x23, 0xea, 0x7c, 0x69, 0x49, 0x2b, 0x92, 0x25, 0x4c, 0xcf, - 0x6a, 0x15, 0x34, 0x10, 0x4d, 0x43, 0xd2, 0x64, 0xff, 0x9b, 0x2d, 0xd1, - 0x8b, 0x15, 0x1d, 0x86, 0xdc, 0x88, 0xd0, 0x5a, 0xaf, 0x93, 0xd3, 0xa2, - 0xd9, 0xa5, 0xad, 0xd8, 0x9a, 0x39, 0x63, 0x0d, 0x74, 0x41, 0x9a, 0x2c, - 0x69, 0x68, 0x39, 0x6a, 0xa6, 0xf5, 0x74, 0xa6, 0xe8, 0x3f, 0xd1, 0xb1, - 0x29, 0x64, 0x46, 0x97, 0x2a, 0xd6, 0x34, 0x49, 0x84, 0xf4, 0x34, 0xa9, - 0xd3, 0x1a, 0x96, 0x1d, 0x2c, 0x92, 0x80, 0x3e, 0x1c, 0xd1, 0x3a, 0x15, - 0x84, 0xce, 0xab, 0xb0, 0xb2, 0x6b, 0xe6, 0xad, 0x8f, 0xa3, 0x61, 0x7f, - 0xe9, 0xe2, 0x3e, 0xf8, 0xd9, 0xbe, 0x3c, 0xa4, 0xc1, 0x4f, 0xb4, 0xd6, - 0xb1, 0x0d, 0xb3, 0x2c, 0xd4, 0x96, 0x25, 0x0d, 0x3d, 0xe0, 0x94, 0xff, - 0x05, 0x57, 0x9b, 0xcc, 0x9b, 0x35, 0xeb, 0xd0, 0xcc, 0x83, 0xbe, 0x67, - 0xbe, 0xf8, 0xab, 0xa3, 0xea, 0x8a, 0xca, 0x58, 0x8c, 0xeb, 0xfb, 0x61, - 0x64, 0x0e, 0x22, 0x58, 0x43, 0x42, 0xbf, 0x67, 0x0c, 0xe4, 0x41, 0xb9, - 0x21, 0x6e, 0xca, 0x0f, 0x13, 0xb5, 0x95, 0x05, 0xe5, 0x54, 0xdd, 0xad, - 0xf2, 0x79, 0xa6, 0xe8, 0x69, 0x07, 0xb5, 0x04, 0x23, 0x9b, 0xff, 0xc2, - 0xca, 0x1e, 0x0a, 0xb4, 0x44, 0x68, 0xa6, 0x9c, 0x9c, 0x44, 0xeb, 0xd7, - 0x91, 0x26, 0xb1, 0xc7, 0x30, 0xe7, 0x73, 0x30, 0x0a, 0x55, 0x8a, 0x1f, - 0xfc, 0x2c, 0x60, 0x14, 0x32, 0xfd, 0x07, 0xf2, 0xd2, 0xcf, 0xbf, 0x78, - 0x78, 0x96, 0x62, 0x43, 0xb4, 0x4c, 0x6c, 0x56, 0xe7, 0x00, 0xc1, 0xef, - 0x88, 0x88, 0xa7, 0x81, 0x70, 0x34, 0x2d, 0x62, 0x79, 0x01, 0xcc, 0x3c, - 0xcd, 0x85, 0x7c, 0x20, 0xef, 0x8a, 0x6d, 0xd5, 0x42, 0xbd, 0x34, 0xfe, - 0x47, 0x15, 0x7e, 0x7a, 0x2f, 0x52, 0xf7, 0x85, 0x3d, 0x30, 0x4e, 0xc3, - 0xf0, 0x55, 0x8d, 0x5c, 0xca, 0xe2, 0x66, 0xa2, 0x0d, 0x5c, 0x5c, 0x05, - 0xcb, 0xe6, 0xc6, 0xb4, 0xda, 0x6c, 0xee, 0xa2, 0x88, 0xce, 0x12, 0xab, - 0x8f, 0x0e, 0x12, 0x12, 0x48, 0x0f, 0x4a, 0x6b, 0x96, 0xe7, 0x42, 0x26, - 0xdb, 0x35, 0x75, 0xcc, 0xec, 0xed, 0x7a, 0x60, 0xb4, 0x37, 0x3d, 0x54, - 0x30, 0xbb, 0xcb, 0x96, 0xc1, 0x54, 0x7f, 0x11, 0x2b, 0x94, 0x4a, 0xc8, - 0xe9, 0x13, 0x14, 0x28, 0xf5, 0x1b, 0x88, 0x51, 0x23, 0x65, 0xd4, 0xc2, - 0xa7, 0x10, 0x46, 0xa7, 0x20, 0xe2, 0x69, 0x3d, 0x32, 0x28, 0x03, 0xcd, - 0x97, 0x74, 0x4a, 0x8b, 0x18, 0x1d, 0x63, 0x25, 0x23, 0x4f, 0x22, 0xf2, - 0x3d, 0x93, 0x95, 0x4d, 0x6a, 0xa3, 0xca, 0x71, 0xa1, 0xd5, 0x7a, 0x39, - 0x5b, 0xf1, 0x3a, 0x8d, 0x44, 0xa2, 0x95, 0xc5, 0x18, 0x82, 0x2d, 0x9b, - 0x75, 0x17, 0x83, 0x9a, 0xad, 0x36, 0xc4, 0x28, 0xb0, 0xa0, 0xd9, 0x71, - 0x04, 0x53, 0x8e, 0xfe, 0xe0, 0xa4, 0xf8, 0xa6, 0x17, 0xc0, 0x08, 0xed, - 0xbd, 0x95, 0x64, 0x4b, 0x9c, 0x0e, 0xa8, 0xe1, 0x4e, 0x61, 0x59, 0x53, - 0x19, 0x7d, 0xa6, 0x69, 0x72, 0x1a, 0xb0, 0x81, 0x51, 0x47, 0xbe, 0x6f, - 0xa1, 0x12, 0x7d, 0x8f, 0x02, 0x8f, 0x39, 0x7e, 0x52, 0x41, 0xdd, 0xd3, - 0x9b, 0x8e, 0xa5, 0xc0, 0x87, 0x39, 0xba, 0x14, 0x49, 0x25, 0x5b, 0xd2, - 0x74, 0xe5, 0xcd, 0xc9, 0xaa, 0x16, 0x03, 0x63, 0xe4, 0xbc, 0xc5, 0x2c, - 0x00, 0x25, 0xce, 0x20, 0x9d, 0x82, 0x20, 0xd6, 0xd9, 0x77, 0x7f, 0xfd, - 0xab, 0xec, 0x06, 0xd1, 0xf2, 0x98, 0xd6, 0x98, 0x44, 0xf2, 0x49, 0xbe, - 0x56, 0x56, 0xde, 0x22, 0x37, 0x77, 0xea, 0xc0, 0x1c, 0x9d, 0x2d, 0x88, - 0x60, 0x4c, 0x20, 0x17, 0x48, 0x74, 0x1c, 0x07, 0x73, 0x55, 0x4a, 0xce, - 0x53, 0xac, 0x1f, 0x7f, 0x55, 0xc6, 0x9a, 0x80, 0x1a, 0x21, 0x07, 0x2e, - 0x1a, 0x56, 0xa4, 0x95, 0x57, 0x93, 0x70, 0x42, 0xd9, 0x81, 0xb1, 0x27, - 0x10, 0xb6, 0x80, 0x74, 0x53, 0x34, 0x38, 0xa9, 0x77, 0x1e, 0xfd, 0x65, - 0x92, 0x83, 0xd5, 0x6d, 0xd5, 0x5c, 0xf9, 0xe0, 0xd7, 0x11, 0xd9, 0x5b, - 0x59, 0x2c, 0x39, 0xba, 0xfa, 0x72, 0xee, 0xf4, 0xda, 0xd9, 0x3d, 0xd8, - 0x7c, 0x85, 0x10, 0x50, 0x4f, 0xda, 0xe0, 0x02, 0xf7, 0x9a, 0xeb, 0x8b, - 0xa3, 0xf1, 0x50, 0x0b, 0xe5, 0x71, 0x3c, 0xe1, 0xf2, 0xd3, 0x0f, 0xe9, - 0x15, 0xd2, 0x2a, 0x68, 0x6e, 0x00, 0x9c, 0xeb, 0x18, 0xed, 0x03, 0x38, - 0x23, 0x28, 0x4e, 0xa8, 0x01, 0xa3, 0xfa, 0x1f, 0xc1, 0x36, 0xc6, 0xc7, - 0x82, 0x2f, 0x0f, 0xb4, 0xbd, 0xb0, 0x96, 0x0f, 0x24, 0x82, 0xc2, 0x49, - 0x26, 0x88, 0x07, 0x0c, 0x2c, 0x13, 0x63, 0xb5, 0x1e, 0xb2, 0xcc, 0xda, - 0xaf, 0x49, 0xbe, 0xac, 0x4a, 0x54, 0x84, 0xcb, 0xa7, 0x04, 0xc2, 0xb0, - 0x26, 0x0b, 0xb5, 0xe0, 0xbd, 0x3d, 0x02, 0x60, 0xaa, 0xae, 0x33, 0x71, - 0x5d, 0x69, 0x34, 0x6f, 0x8c, 0x44, 0x7c, 0xa0, 0x84, 0x4b, 0x19, 0x40, - 0x9a, 0x3c, 0x89, 0x01, 0x05, 0xb3, 0x11, 0x34, 0x6f, 0x96, 0x88, 0x88, - 0x0e, 0x52, 0x88, 0xd9, 0x1a, 0xa0, 0x3b, 0xff, 0xfe, 0x8d, 0x68, 0x25, - 0x49, 0x59, 0x33, 0x54, 0x4f, 0xa7, 0xe8, 0xae, 0x9c, 0x9d, 0xa3, 0x4a, - 0x2b, 0xaa, 0x87, 0xdb, 0xc1, 0x8c, 0xd9, 0x96, 0xcd, 0x53, 0xa4, 0x95, - 0xd2, 0xe8, 0x77, 0x81, 0x17, 0x68, 0x01, 0xaf, 0x2a, 0x88, 0x78, 0x57, - 0xc1, 0xc3, 0xbb, 0x11, 0x67, 0x5f, 0x38, 0xa5, 0x6a, 0x37, 0x84, 0xbc, - 0x93, 0xf8, 0x86, 0xa8, 0xc8, 0x2e, 0x2c, 0x2c, 0xa5, 0x91, 0xf9, 0x2f, - 0x02, 0x9b, 0x5a, 0x74, 0xff, 0xc8, 0xe8, 0xb0, 0x3e, 0x31, 0x0b, 0xd0, - 0x7c, 0xc4, 0x0b, 0x45, 0xbb, 0xd1, 0x14, 0x12, 0xcb, 0xcd, 0x49, 0xa4, - 0x37, 0x2c, 0x07, 0x0c, 0x6c, 0x09, 0xde, 0x21, 0x65, 0xef, 0xb0, 0x9a, - 0xe1, 0x92, 0x32, 0x99, 0xac, 0xbc, 0x18, 0xc3, 0xaa, 0x05, 0xf1, 0xc7, - 0x1f, 0x6c, 0xe2, 0xb6, 0xa3, 0x05, 0xb2, 0x9f, 0xa4, 0x99, 0xe3, 0xf2, - 0xf8, 0x3c, 0xec, 0xf8, 0x52, 0x0e, 0x0f, 0x91, 0x0c, 0x1e, 0x57, 0xcd, - 0x21, 0xe2, 0xf5, 0x6d, 0x06, 0xeb, 0xf2, 0x59, 0xef, 0x00, 0x98, 0xe6, - 0x9a, 0x84, 0xa2, 0x57, 0x25, 0xf2, 0x33, 0x15, 0x5e, 0xb3, 0xab, 0x18, - 0xef, 0x61, 0xc1, 0x60, 0x98, 0x0a, 0xc7, 0xcb, 0x36, 0x96, 0xa7, 0xe6, - 0xa2, 0x39, 0xb3, 0xf6, 0x24, 0x12, 0xe2, 0x02, 0xa9, 0x98, 0x67, 0xd9, - 0x48, 0x9e, 0xf7, 0x9f, 0x3f, 0x8d, 0x43, 0x41, 0x10, 0x85, 0xe9, 0x76, - 0x78, 0x2d, 0x4c, 0xb9, 0x9a, 0x30, 0x01, 0x07, 0xdf, 0x14, 0xd4, 0xf5, - 0x74, 0x34, 0x71, 0xd9, 0x6e, 0x6b, 0xcc, 0x78, 0xec, 0xa1, 0x78, 0x40, - 0x10, 0x9d, 0xac, 0xcd, 0xc2, 0x4e, 0x71, 0x51, 0xa6, 0x89, 0xe8, 0x09, - 0xd0, 0x88, 0xd5, 0x7e, 0x96, 0x54, 0x84, 0x24, 0x20, 0x5b, 0x81, 0xab, - 0x16, 0x34, 0xa3, 0x16, 0xac, 0xaa, 0x3e, 0x4d, 0x0a, 0x3c, 0x84, 0xa7, - 0x87, 0x8a, 0xcc, 0xae, 0xf7, 0xe0, 0xb8, 0xb0, 0x2a, 0x4d, 0x09, 0x32, - 0x78, 0x68, 0x21, 0xcf, 0x0e, 0xd3, 0xc0, 0x0b, 0xe3, 0xa2, 0xb1, 0xee, - 0x82, 0x46, 0x30, 0x89, 0xc0, 0x32, 0x13, 0x87, 0x2b, 0xf8, 0x18, 0x69, - 0xe4, 0xe2, 0xc8, 0xee, 0x80, 0x24, 0xb4, 0x4f, 0x9b, 0x15, 0x21, 0x22, - 0xcd, 0x3d, 0xb3, 0x7d, 0x39, 0x9d, 0x5e, 0x1e, 0x86, 0x8d, 0x9b, 0x5c, - 0x1f, 0x02, 0x60, 0xc1, 0xd6, 0xc3, 0xc2, 0x8a, 0x0b, 0xa2, 0x2e, 0xc8, - 0x8c, 0xe4, 0xf4, 0x22, 0x02, 0x1f, 0x9a, 0x82, 0x84, 0x18, 0x0d, 0xc7, - 0x62, 0x3c, 0x1d, 0x8b, 0xe8, 0xa6, 0xb3, 0xd1, 0xa4, 0x7e, 0xe4, 0x98, - 0xe4, 0xf8, 0x9d, 0x32, 0x8c, 0x43, 0x73, 0xe9, 0xaf, 0x89, 0xeb, 0x7e, - 0x7c, 0xf4, 0x2f, 0x48, 0x14, 0x1a, 0x95, 0x1d, 0xc8, 0x98, 0xa2, 0x9a, - 0x03, 0x4a, 0xba, 0xcc, 0xe6, 0x91, 0x81, 0x2a, 0xab, 0xe1, 0x00, 0xfb, - 0x9e, 0xbf, 0x87, 0xbc, 0x2d, 0x32, 0x72, 0x92, 0x0b, 0x05, 0x61, 0x69, - 0x52, 0x5e, 0x03, 0x5a, 0xa8, 0x46, 0x9a, 0xac, 0x95, 0x1f, 0xa1, 0x9c, - 0x86, 0xd4, 0xdf, 0x05, 0x37, 0x51, 0xb9, 0x64, 0x28, 0xe4, 0x1b, 0x81, - 0x78, 0xa2, 0x4b, 0x8d, 0x32, 0x3d, 0x98, 0x89, 0x12, 0x98, 0xac, 0x7c, - 0x38, 0xf8, 0x8f, 0x85, 0xc6, 0xb8, 0x74, 0x26, 0xaf, 0xd1, 0xa8, 0x98, - 0xd4, 0x17, 0x08, 0x5d, 0x07, 0x41, 0xa4, 0x9a, 0xa0, 0xef, 0xae, 0xc4, - 0x7f, 0x08, 0x8d, 0x6a, 0xa4, 0xb8, 0x0c, 0x07, 0x57, 0x6d, 0x19, 0x26, - 0x05, 0x5f, 0xaa, 0x55, 0x49, 0xbd, 0xaa, 0x19, 0xd4, 0xb6, 0xf9, 0x09, - 0x05, 0x84, 0xc4, 0xc1, 0x3e, 0x43, 0xf9, 0x4c, 0x46, 0x84, 0xa4, 0x75, - 0x7f, 0x2b, 0x10, 0x23, 0x56, 0xe0, 0x6c, 0x32, 0x9e, 0x5d, 0x4a, 0x2e, - 0x68, 0x4c, 0x95, 0x88, 0x97, 0x86, 0x9c, 0x98, 0x40, 0xde, 0x56, 0x3e, - 0x56, 0xd2, 0xd9, 0x39, 0xbd, 0xd0, 0x42, 0xb4, 0xfb, 0x46, 0x01, 0x86, - 0x1b, 0xc5, 0xb5, 0xec, 0x27, 0xe5, 0x51, 0x0e, 0xd3, 0xa3, 0x99, 0x9c, - 0xcd, 0x64, 0xf3, 0x24, 0xf5, 0x59, 0x44, 0x2f, 0xfa, 0x08, 0x4e, 0x19, - 0xc5, 0x1a, 0x5d, 0xdc, 0x82, 0x10, 0xb1, 0x10, 0x53, 0x02, 0x2c, 0x6f, - 0x3f, 0xcc, 0x33, 0x50, 0xd0, 0x52, 0x13, 0xb1, 0x58, 0x5b, 0x5d, 0x93, - 0x9b, 0xdd, 0x64, 0x0c, 0xec, 0x91, 0x1d, 0xa2, 0x3f, 0xe9, 0x4e, 0x67, - 0x41, 0x76, 0x1b, 0xc7, 0xb6, 0x44, 0x8a, 0x0a, 0x1a, 0xea, 0x02, 0x6d, - 0xc8, 0xcb, 0x12, 0xca, 0x43, 0x62, 0x6f, 0x95, 0x64, 0xce, 0x7a, 0x8e, - 0x16, 0x19, 0xd9, 0xf0, 0xf0, 0x99, 0x3b, 0xf9, 0xbc, 0x5f, 0x67, 0x31, - 0x5a, 0x02, 0xa6, 0x1d, 0xce, 0x32, 0x87, 0xf6, 0x41, 0xfa, 0xf1, 0xc6, - 0xfb, 0x50, 0x5d, 0x37, 0x2d, 0x56, 0xb6, 0x12, 0x59, 0x19, 0xad, 0x29, - 0x87, 0xf5, 0xa5, 0x0d, 0x62, 0x2b, 0xe8, 0x36, 0x41, 0x6e, 0x26, 0x7c, - 0xaa, 0xe1, 0x00, 0x28, 0x54, 0x46, 0x06, 0x8c, 0x41, 0xd6, 0x21, 0xc7, - 0x07, 0xb7, 0xe0, 0x09, 0x61, 0x5a, 0xd3, 0x0b, 0xa6, 0x67, 0x7a, 0xbc, - 0xfa, 0x99, 0xb6, 0xf6, 0x3e, 0x3e, 0xc1, 0x56, 0xc0, 0x04, 0xde, 0xcf, - 0x3a, 0xc7, 0x65, 0x68, 0xdd, 0x4b, 0x57, 0xbc, 0x1e, 0xa3, 0xa1, 0x40, - 0x0a, 0xcd, 0xa5, 0xfd, 0x51, 0x18, 0x8c, 0x9d, 0x59, 0x7b, 0x5a, 0x04, - 0x21, 0x5d, 0x4f, 0x45, 0x69, 0x90, 0x9b, 0x51, 0x77, 0x2f, 0xd3, 0xd3, - 0x94, 0x47, 0x58, 0x88, 0xb0, 0xac, 0x13, 0x88, 0x97, 0x2b, 0x95, 0x5c, - 0x66, 0x61, 0x3c, 0x87, 0x2e, 0x32, 0xec, 0xf8, 0xe0, 0x2c, 0xd9, 0x23, - 0x91, 0x1c, 0x9a, 0x18, 0x24, 0x62, 0xd4, 0x49, 0x58, 0x66, 0x4f, 0xa6, - 0xe8, 0x47, 0xaf, 0x59, 0x22, 0x47, 0xc8, 0xc2, 0xba, 0x18, 0xe1, 0x72, - 0x84, 0x8b, 0x11, 0xa9, 0x1c, 0x81, 0x39, 0xba, 0x24, 0x11, 0x31, 0x82, - 0x6f, 0x13, 0x23, 0x38, 0x78, 0x59, 0xaf, 0xd6, 0xf8, 0x83, 0x7e, 0x6e, - 0x2b, 0xa9, 0xc5, 0xc2, 0x75, 0x95, 0x74, 0x7d, 0xda, 0x67, 0x06, 0x2d, - 0x59, 0x5d, 0xf2, 0x78, 0x64, 0x8e, 0x84, 0xf1, 0x14, 0x37, 0xea, 0x88, - 0xc7, 0x03, 0x3a, 0x57, 0x3b, 0x86, 0xe4, 0x83, 0xac, 0x8d, 0x92, 0x2b, - 0x81, 0x40, 0xc6, 0x92, 0x85, 0x59, 0x04, 0xe4, 0x25, 0xe8, 0xae, 0x31, - 0xd0, 0x83, 0xb2, 0xfa, 0xb4, 0x9c, 0xce, 0x1a, 0xf1, 0xee, 0x6e, 0x0d, - 0x28, 0x35, 0x83, 0x53, 0x69, 0x67, 0x2d, 0x2a, 0x7f, 0x9c, 0x4f, 0xdf, - 0x1a, 0x6d, 0xcd, 0xdf, 0x3f, 0xd6, 0x23, 0x07, 0x9e, 0x2d, 0xba, 0x5e, - 0x64, 0x5a, 0xad, 0xc3, 0x2b, 0xad, 0xb1, 0x16, 0x62, 0xbb, 0x2d, 0x29, - 0x90, 0x08, 0x4d, 0x42, 0x02, 0x14, 0x34, 0x05, 0xc3, 0x62, 0xdf, 0x10, - 0x25, 0x8b, 0x87, 0xae, 0x3b, 0x12, 0x50, 0x01, 0xe3, 0x7f, 0x68, 0x41, - 0x52, 0xda, 0x97, 0x72, 0xe3, 0x9f, 0x8d, 0x3d, 0x90, 0x3a, 0x44, 0x1c, - 0x5b, 0xec, 0x34, 0x79, 0x37, 0x51, 0x8f, 0x48, 0x44, 0xf0, 0x6a, 0x8f, - 0xac, 0x3a, 0x4e, 0x54, 0x85, 0x44, 0xfb, 0x20, 0x55, 0x4b, 0x3d, 0xc1, - 0x9f, 0xaa, 0xc9, 0x58, 0xd5, 0x8f, 0x5b, 0x65, 0x1c, 0x72, 0xb2, 0xc3, - 0xa6, 0x19, 0x82, 0x4d, 0xd5, 0xa7, 0xd7, 0x61, 0xc6, 0x8d, 0x56, 0x6c, - 0x3b, 0x90, 0xab, 0xb3, 0x61, 0xc0, 0x28, 0x36, 0x5d, 0x28, 0x57, 0xbc, - 0x68, 0xf2, 0x22, 0x42, 0xb3, 0x58, 0x3a, 0x2a, 0xac, 0x00, 0xab, 0x06, - 0x25, 0xc7, 0x23, 0xb4, 0xc0, 0x26, 0xbd, 0x76, 0x91, 0xb1, 0x3a, 0x17, - 0x03, 0xfb, 0xb0, 0xd3, 0x9a, 0xd3, 0x84, 0x65, 0xee, 0xe2, 0xd3, 0xa2, - 0xd8, 0x2d, 0x44, 0xad, 0xae, 0x9f, 0x0d, 0x98, 0x9a, 0x6a, 0xf8, 0x7e, - 0x9f, 0x73, 0x6e, 0x8a, 0x47, 0xb6, 0x1c, 0x56, 0xb9, 0x3b, 0xd1, 0x11, - 0x45, 0x1d, 0x91, 0x17, 0x53, 0xa4, 0x81, 0x62, 0xa5, 0x2f, 0x75, 0xe0, - 0x20, 0x16, 0x01, 0x8d, 0x21, 0xe6, 0x10, 0x41, 0x11, 0x60, 0xd1, 0x63, - 0xc6, 0xc8, 0x96, 0x45, 0x67, 0x67, 0x77, 0x6f, 0x7f, 0xf7, 0xbb, 0x7f, - 0x76, 0x20, 0xe0, 0xc0, 0x23, 0x68, 0x10, 0x08, 0x27, 0xaa, 0x15, 0x00, - 0x3d, 0xc1, 0xb0, 0x8d, 0xa0, 0x7b, 0x66, 0xbb, 0xfc, 0x3c, 0x2e, 0xb7, - 0x91, 0xe1, 0xa1, 0xc6, 0x18, 0x32, 0x4e, 0x15, 0x92, 0x43, 0xca, 0x9f, - 0xe4, 0xe6, 0xe3, 0x21, 0xf5, 0x64, 0xa9, 0x5e, 0xcf, 0xaa, 0x28, 0x8b, - 0xe4, 0x24, 0xb4, 0xcb, 0x8b, 0xd0, 0x08, 0x7b, 0x69, 0x6c, 0x28, 0xe9, - 0xb0, 0xf0, 0x7f, 0xea, 0xf1, 0x1b, 0x0a, 0x9e, 0x81, 0x3b, 0x4a, 0x52, - 0x78, 0xf8, 0x3b, 0x46, 0x9e, 0x32, 0x38, 0x42, 0xc7, 0x2f, 0x94, 0xcc, - 0x00, 0xc7, 0xd2, 0x07, 0x59, 0x5c, 0x31, 0x01, 0x8f, 0xe6, 0xd6, 0x33, - 0x56, 0x37, 0x1d, 0xf7, 0x7d, 0x1e, 0x50, 0x6f, 0x9d, 0x5a, 0xf7, 0xe5, - 0xdf, 0x57, 0x2e, 0x21, 0xdc, 0x10, 0xeb, 0x73, 0x02, 0x7c, 0x96, 0xae, - 0x08, 0x84, 0xbf, 0xe4, 0x6a, 0x52, 0x69, 0x30, 0xdc, 0x50, 0x76, 0x41, - 0x65, 0x97, 0xc3, 0xad, 0xb7, 0x43, 0x98, 0x36, 0xae, 0xa6, 0x5f, 0xbd, - 0x8d, 0xb4, 0xc3, 0xf4, 0x3a, 0xd2, 0x2e, 0xff, 0xd3, 0xfb, 0xc8, 0x98, - 0xe1, 0x67, 0x14, 0x6f, 0x9c, 0x78, 0x97, 0xc8, 0x57, 0xa0, 0x76, 0xc3, - 0x63, 0x38, 0x72, 0xc8, 0x0f, 0xf6, 0xd5, 0x71, 0x2b, 0x9b, 0x00, 0x5c, - 0x78, 0xdf, 0x4c, 0xa8, 0x36, 0xc4, 0x10, 0xa0, 0x85, 0x8c, 0x03, 0x09, - 0x48, 0x26, 0xb3, 0x06, 0x9e, 0x47, 0x17, 0xe0, 0xb2, 0xc5, 0x63, 0xdb, - 0x99, 0xbb, 0x4d, 0x14, 0x41, 0xa5, 0xdd, 0xc3, 0x93, 0x30, 0x08, 0x60, - 0xb0, 0x58, 0x57, 0xd3, 0xf1, 0x14, 0xe9, 0x84, 0x17, 0x61, 0x1a, 0xc2, - 0x25, 0x92, 0xe8, 0x60, 0xe1, 0xb2, 0xf6, 0x06, 0xcf, 0xbb, 0xab, 0x42, - 0xaa, 0x67, 0xa2, 0x40, 0xb1, 0x2e, 0x35, 0x00, 0x74, 0x1e, 0x8a, 0xb9, - 0xc8, 0x38, 0x85, 0xd7, 0xb0, 0x86, 0x3d, 0x8b, 0x31, 0x60, 0x02, 0x9c, - 0xae, 0x32, 0x6c, 0x3a, 0x2e, 0xf9, 0x6c, 0xee, 0xa8, 0x7c, 0x50, 0xda, - 0x51, 0x1c, 0xd0, 0xdc, 0x96, 0xec, 0xca, 0xba, 0xb3, 0xa9, 0x38, 0xbd, - 0xd4, 0xe0, 0x9f, 0x09, 0x19, 0x69, 0x9b, 0x82, 0x5b, 0x73, 0xdf, 0x26, - 0x1d, 0xbb, 0x2a, 0x5b, 0x2e, 0xb6, 0x84, 0xd8, 0x92, 0xdf, 0xbb, 0x5c, - 0x81, 0x55, 0x9f, 0xdc, 0xd8, 0xc7, 0x12, 0x1e, 0xb0, 0xb3, 0xb8, 0x38, - 0xf2, 0x58, 0xa2, 0xd5, 0x06, 0x3e, 0xdd, 0xcc, 0x26, 0x1a, 0x66, 0x68, - 0x08, 0x56, 0x74, 0x22, 0x85, 0x16, 0xec, 0xad, 0x7e, 0xf1, 0x86, 0x73, - 0x81, 0x4b, 0x5d, 0x42, 0xcc, 0xf2, 0x5e, 0xf3, 0x75, 0xb0, 0x3e, 0x0d, - 0xc5, 0xaa, 0xdd, 0xe5, 0xdd, 0x7d, 0xca, 0x5b, 0x77, 0xf4, 0x78, 0xdb, - 0x9d, 0xa6, 0x57, 0x9a, 0xc9, 0xb8, 0xb8, 0xbe, 0xe4, 0xf6, 0x4a, 0xad, - 0x42, 0x37, 0xaf, 0x2e, 0x3d, 0x1d, 0xc9, 0xed, 0x75, 0xeb, 0xe5, 0x85, - 0xcd, 0xb8, 0x79, 0x73, 0x89, 0xdb, 0x01, 0xa3, 0xf8, 0x4a, 0x34, 0x53, - 0xa6, 0xd7, 0x8c, 0x6b, 0x1e, 0x9c, 0x91, 0x26, 0xd6, 0xa6, 0xde, 0xbe, - 0xf4, 0xe2, 0x4f, 0x5d, 0x1e, 0x38, 0x38, 0xe6, 0xf4, 0x98, 0x73, 0xbd, - 0x3f, 0x4b, 0x24, 0x22, 0xf1, 0xfd, 0x7d, 0xe6, 0x3e, 0x0d, 0x6b, 0x58, - 0x61, 0x19, 0x6a, 0xab, 0xc0, 0x20, 0xce, 0x99, 0x6e, 0x91, 0x3a, 0x60, - 0xcc, 0x5a, 0x25, 0x2d, 0x84, 0xdb, 0x2c, 0xc8, 0x7d, 0x90, 0x63, 0xd5, - 0x1b, 0x29, 0x9f, 0x58, 0xd6, 0xa3, 0x80, 0x84, 0xdf, 0x3a, 0x19, 0x70, - 0xb0, 0xc3, 0xa0, 0xf1, 0xb6, 0x54, 0xb9, 0x42, 0xca, 0x33, 0x13, 0x9e, - 0x92, 0x14, 0x80, 0x2c, 0x0f, 0xc9, 0xe8, 0x1b, 0x7f, 0xc8, 0x3c, 0x37, - 0x14, 0x40, 0x11, 0x42, 0x3e, 0xad, 0x87, 0xc6, 0x82, 0xc2, 0xf6, 0x3f, - 0x1c, 0x0c, 0xbe, 0x79, 0x58, 0x4d, 0x8f, 0xbd, 0xbc, 0xc8, 0xc3, 0x98, - 0x0f, 0xad, 0x50, 0x08, 0x82, 0x98, 0xa0, 0xf7, 0x44, 0xc1, 0xeb, 0xde, - 0xf9, 0xa5, 0x3b, 0x53, 0xfb, 0xe9, 0x38, 0x5b, 0x83, 0x94, 0x31, 0x16, - 0x0c, 0x3e, 0xd6, 0x31, 0xfa, 0x10, 0xe3, 0x08, 0xb3, 0x01, 0x4a, 0x9d, - 0x98, 0xf5, 0xbd, 0xa8, 0x70, 0xb5, 0x10, 0x25, 0x39, 0x0a, 0xdc, 0xfa, - 0xaa, 0x8e, 0x82, 0xec, 0xe6, 0x0f, 0x06, 0xa2, 0xc9, 0x30, 0x74, 0x35, - 0xbb, 0xcc, 0xc7, 0x93, 0xad, 0x59, 0x3d, 0x4d, 0x57, 0x2c, 0x59, 0xb0, - 0x64, 0x38, 0x59, 0xc0, 0x21, 0x23, 0xdb, 0x6f, 0xed, 0xf3, 0x12, 0x12, - 0xb0, 0x30, 0xa4, 0xdf, 0xd9, 0xa9, 0x78, 0x73, 0x17, 0x32, 0xa3, 0x3f, - 0x54, 0xe3, 0x19, 0x03, 0x6f, 0xa4, 0x1c, 0xb6, 0xe6, 0x77, 0x9d, 0xd5, - 0x30, 0x7c, 0x19, 0x61, 0x7a, 0x94, 0x1c, 0x74, 0x65, 0xaa, 0xed, 0x55, - 0xcf, 0x5b, 0x51, 0xcb, 0xb4, 0x87, 0x8d, 0x6b, 0x61, 0x37, 0xcf, 0xff, - 0xc9, 0x4a, 0x5d, 0x1e, 0x2b, 0x05, 0x53, 0xc4, 0x8c, 0x20, 0x4b, 0x76, - 0x87, 0xc2, 0xea, 0x50, 0x8f, 0x3e, 0x22, 0x84, 0x32, 0x5f, 0x04, 0x13, - 0xa5, 0x6e, 0x92, 0xc1, 0x7c, 0x5a, 0x85, 0x25, 0x8f, 0x26, 0x7b, 0x7b, - 0xb1, 0x16, 0x0f, 0x7e, 0x75, 0xd9, 0x50, 0x59, 0x35, 0x9e, 0xae, 0x7e, - 0x42, 0xd9, 0xd3, 0xae, 0x13, 0x6e, 0x97, 0xf9, 0x7a, 0x71, 0xa1, 0x04, - 0xd7, 0xc3, 0xb7, 0x61, 0x61, 0x21, 0x96, 0xa1, 0xe7, 0xba, 0x8e, 0xca, - 0xa1, 0x7e, 0xad, 0x4e, 0x11, 0x59, 0x5a, 0x55, 0xd4, 0xc2, 0x4a, 0x76, - 0xb2, 0x59, 0x74, 0x5a, 0x59, 0x31, 0xb2, 0xed, 0x1a, 0x62, 0x4c, 0x46, - 0x09, 0xec, 0x5a, 0x62, 0x62, 0x9b, 0x11, 0x2c, 0x99, 0x47, 0x93, 0xad, - 0x0c, 0xfb, 0xb8, 0x95, 0x40, 0xb2, 0xc5, 0x99, 0x7b, 0x48, 0x32, 0xfa, - 0x98, 0x50, 0x68, 0xc2, 0x3d, 0x0a, 0x6e, 0x64, 0x6a, 0x79, 0xbf, 0x4d, - 0x07, 0x6d, 0xba, 0x14, 0x07, 0x34, 0xb3, 0x9c, 0x85, 0x19, 0x70, 0xfc, - 0xec, 0x43, 0xd4, 0x7d, 0x04, 0xda, 0x8b, 0xf3, 0x25, 0x88, 0x4d, 0xd8, - 0x72, 0x75, 0x4e, 0xca, 0x15, 0x92, 0xcd, 0x87, 0x97, 0x7a, 0x7e, 0xc3, - 0xdf, 0x9c, 0x8d, 0x6b, 0xb8, 0xf4, 0x41, 0x46, 0x2c, 0x56, 0x48, 0x7d, - 0x91, 0x72, 0x54, 0x37, 0x38, 0x50, 0x80, 0xa9, 0x68, 0x9b, 0xaa, 0xa8, - 0x72, 0xdc, 0xae, 0xcc, 0xb1, 0xf2, 0x70, 0x26, 0x09, 0xaa, 0x08, 0x68, - 0x20, 0x4e, 0xd3, 0x7b, 0x34, 0xf9, 0xa2, 0xff, 0x28, 0x6f, 0x11, 0x29, - 0x11, 0x6e, 0xf8, 0x46, 0x1e, 0xfe, 0xef, 0x6a, 0xcd, 0xc0, 0x02, 0xac, - 0xc5, 0x08, 0x3a, 0x23, 0x00, 0xb8, 0x06, 0x58, 0x15, 0x31, 0x81, 0x44, - 0x4e, 0xb6, 0xa6, 0x73, 0x63, 0xea, 0x8d, 0xe6, 0x35, 0x81, 0xc5, 0x5a, - 0xd7, 0x7f, 0x7f, 0xdf, 0x90, 0xc1, 0x67, 0xdd, 0xda, 0x04, 0x9e, 0xfb, - 0xfb, 0x16, 0x20, 0x51, 0x3c, 0xe6, 0x68, 0x1c, 0xf3, 0xdb, 0xdb, 0x92, - 0x1c, 0xe7, 0xe4, 0xf9, 0xd0, 0x02, 0xc5, 0x8c, 0x98, 0xb5, 0x2c, 0x8e, - 0x7a, 0x5b, 0x3b, 0x13, 0xfe, 0x71, 0x00, 0xa8, 0x3a, 0x74, 0x4d, 0xcc, - 0x97, 0x6f, 0xbe, 0x00, 0x43, 0x71, 0xb8, 0xbb, 0x64, 0x1c, 0x12, 0xeb, - 0x78, 0x35, 0xfa, 0x95, 0x5d, 0x8c, 0xc6, 0x7f, 0xda, 0xfc, 0x7f, 0xd7, - 0x92, 0x10, 0xdd, 0xca, 0x9a, 0xcb, 0x61, 0xc7, 0xfe, 0xa3, 0xf6, 0x4e, - 0x83, 0x58, 0x49, 0x9c, 0x1c, 0x6d, 0xd2, 0xfe, 0xff, 0x4c, 0x34, 0xf6, - 0x53, 0x50, 0x03, 0xa3, 0xaf, 0x0e, 0xff, 0xc1, 0xcf, 0xf6, 0x7b, 0x46, - 0x5c, 0xfd, 0xfa, 0xb1, 0x8d, 0x16, 0xe2, 0x62, 0x09, 0xec, 0x62, 0x39, - 0xef, 0xc4, 0x7b, 0xc9, 0x9c, 0x8c, 0x37, 0xfb, 0x99, 0x7f, 0x98, 0xef, - 0xee, 0xe4, 0xb7, 0xf7, 0xd2, 0x3e, 0xe4, 0xf3, 0x4e, 0x79, 0xbb, 0x43, - 0xeb, 0x31, 0xe9, 0x52, 0x05, 0xac, 0x7b, 0x2d, 0xe0, 0x3d, 0x0e, 0xfe, - 0xe7, 0x59, 0xc1, 0xf9, 0xdc, 0xe0, 0xb3, 0xaf, 0xe0, 0xdd, 0x5c, 0xe2, - 0x37, 0xcc, 0x45, 0x58, 0x47, 0xda, 0x86, 0xdc, 0xf1, 0xc6, 0x38, 0x24, - 0x5e, 0xca, 0xa8, 0x56, 0x29, 0x2f, 0x72, 0x0d, 0x0a, 0x3d, 0xa1, 0x59, - 0xe3, 0x1a, 0xc5, 0x7f, 0xca, 0x33, 0xaa, 0x5b, 0x98, 0xc6, 0xe7, 0x5e, - 0xb9, 0x3b, 0x98, 0xc9, 0x7c, 0x2a, 0xf8, 0xcf, 0xc8, 0xa0, 0xcd, 0x63, - 0xe6, 0x31, 0x99, 0xcf, 0x4c, 0xe2, 0xbf, 0xce, 0x77, 0x6e, 0xa7, 0x8a, - 0x8c, 0x13, 0xdd, 0x39, 0xb5, 0xb0, 0xa5, 0xa9, 0xf4, 0xc1, 0x58, 0x9c, - 0x4f, 0xa9, 0xf1, 0x5f, 0x94, 0x48, 0x93, 0xa1, 0xba, 0xc5, 0x4a, 0x8f, - 0x8f, 0x90, 0x71, 0xbe, 0x1b, 0x11, 0xd5, 0x99, 0x76, 0x51, 0xe2, 0x07, - 0x23, 0xf5, 0xb1, 0x4a, 0x62, 0x9a, 0xa4, 0x35, 0x0f, 0x45, 0x50, 0xd5, - 0x71, 0x3c, 0xa9, 0x83, 0xe4, 0x5e, 0xe8, 0xbb, 0x85, 0x40, 0x3f, 0xe7, - 0xd1, 0x12, 0x2d, 0x39, 0xe7, 0xa6, 0x4f, 0x7e, 0x1e, 0xcf, 0x15, 0x7b, - 0x5a, 0xb4, 0xa3, 0xd0, 0x9c, 0xd7, 0x72, 0xbf, 0x5f, 0x8f, 0x67, 0x8c, - 0xd1, 0x47, 0xcd, 0x2b, 0xf8, 0xdf, 0x0d, 0xee, 0x48, 0x2c, 0xac, 0x85, - 0x99, 0x5d, 0x5f, 0xb5, 0xed, 0x28, 0x9f, 0xc2, 0xe4, 0x93, 0x90, 0x8d, - 0x68, 0xee, 0x4b, 0x02, 0x36, 0xdc, 0xb5, 0x06, 0x47, 0x62, 0x14, 0xcb, - 0x61, 0x47, 0xec, 0x17, 0x3d, 0x1a, 0xad, 0xc3, 0xe1, 0x4c, 0x75, 0x1b, - 0xcf, 0x15, 0x30, 0x67, 0xc9, 0x75, 0x25, 0x70, 0xb3, 0x02, 0xd2, 0x1b, - 0xee, 0x78, 0xc4, 0x98, 0x1d, 0x64, 0x86, 0xff, 0xfa, 0x44, 0xbc, 0xb0, - 0x16, 0xe7, 0xa1, 0x11, 0x1e, 0xa2, 0x48, 0xc4, 0xd4, 0x90, 0xc4, 0x4b, - 0x91, 0x44, 0x7b, 0x14, 0xb2, 0x31, 0xb9, 0x57, 0xef, 0xee, 0x78, 0x0f, - 0xc6, 0x54, 0x47, 0x93, 0xc1, 0x9d, 0x95, 0x9a, 0xb2, 0xda, 0x70, 0x1a, - 0xe5, 0x3a, 0x17, 0x4b, 0x7d, 0x6e, 0x48, 0xf5, 0x55, 0xf1, 0xc5, 0x83, - 0x9f, 0x33, 0xf3, 0xea, 0x2f, 0x3f, 0x8c, 0xbe, 0xb8, 0x1f, 0x2c, 0x4e, - 0x5e, 0x7a, 0xe6, 0x5c, 0xb2, 0x8a, 0x25, 0xe0, 0xfd, 0x53, 0x19, 0x34, - 0x8f, 0x04, 0x28, 0xa2, 0x29, 0xa9, 0xcb, 0xc6, 0x72, 0x65, 0x12, 0x41, - 0xdc, 0x2d, 0x92, 0x28, 0x61, 0xda, 0x27, 0xa0, 0x3b, 0x31, 0x1a, 0xe3, - 0xa2, 0x9a, 0x96, 0x92, 0x4c, 0x6e, 0xf1, 0xc1, 0x4c, 0xc4, 0xc2, 0x0a, - 0x48, 0xb4, 0x06, 0x7a, 0xa8, 0x03, 0x63, 0xa5, 0xff, 0x7f, 0x9d, 0x8e, - 0xf4, 0xa9, 0x21, 0xe8, 0x3b, 0x92, 0x2a, 0x1b, 0x8c, 0xd6, 0x5f, 0x85, - 0x6f, 0xfe, 0x74, 0x72, 0xd6, 0x97, 0x03, 0xd1, 0x0f, 0x1d, 0x77, 0x62, - 0x53, 0x14, 0xf1, 0xba, 0xaa, 0x25, 0xc2, 0xd6, 0xd8, 0x35, 0xa3, 0x98, - 0x02, 0x70, 0x20, 0x00, 0x27, 0x29, 0xeb, 0x2e, 0xad, 0xab, 0x6d, 0xb2, - 0x73, 0x41, 0x2d, 0x25, 0x3c, 0xd1, 0x49, 0x46, 0xd7, 0xb7, 0xf0, 0x38, - 0x19, 0xb6, 0x02, 0xfa, 0x79, 0x5a, 0xb7, 0x85, 0xd6, 0x5d, 0x2a, 0x52, - 0x8b, 0xcd, 0x31, 0x99, 0x5e, 0x97, 0x21, 0x2a, 0x57, 0xe5, 0x84, 0x20, - 0xf1, 0x85, 0x18, 0x84, 0x9a, 0x19, 0xb9, 0xc1, 0xcd, 0x52, 0xa6, 0x5c, - 0xf9, 0x3b, 0xab, 0xaa, 0xdc, 0x9e, 0x6e, 0x9c, 0x40, 0xa3, 0x30, 0xe9, - 0x98, 0x6d, 0xdd, 0x1d, 0x91, 0x2f, 0xdd, 0xf5, 0x64, 0xeb, 0x60, 0x6a, - 0xbc, 0x17, 0xe5, 0x68, 0x10, 0x8c, 0xa8, 0x6f, 0x29, 0xa5, 0xb7, 0xab, - 0xaa, 0x7c, 0xb5, 0xb5, 0xbd, 0x39, 0x10, 0xa2, 0xfa, 0xbf, 0x0f, 0xfb, - 0xe8, 0x73, 0x72, 0x2c, 0xff, 0x6e, 0xe8, 0x25, 0xa9, 0x65, 0x94, 0x84, - 0x9a, 0x04, 0x49, 0xda, 0x3e, 0x22, 0xf0, 0x81, 0x81, 0x47, 0x6f, 0xee, - 0xbc, 0xdf, 0xda, 0xdf, 0xdd, 0x79, 0xbb, 0xb9, 0x73, 0x20, 0x0d, 0x1c, - 0xdc, 0x02, 0xcb, 0xd2, 0x44, 0x84, 0xa5, 0x28, 0xf9, 0x5b, 0xac, 0x88, - 0xe2, 0xa1, 0xa0, 0x66, 0xdd, 0xe5, 0xa5, 0xfd, 0xdb, 0xf7, 0xf6, 0xe4, - 0x19, 0x3e, 0x62, 0xf1, 0x07, 0x74, 0x4f, 0x5e, 0x42, 0x61, 0x3e, 0x41, - 0xa4, 0x47, 0x5f, 0x9d, 0x0b, 0x34, 0x28, 0x75, 0x18, 0x8d, 0x88, 0xb8, - 0x4d, 0x04, 0x92, 0x30, 0xe1, 0x19, 0x9b, 0x3b, 0x5d, 0x54, 0x0c, 0x61, - 0x29, 0x61, 0xe1, 0x01, 0x08, 0x3e, 0x08, 0xe9, 0x74, 0x51, 0x2a, 0x52, - 0x48, 0x02, 0xe5, 0x1d, 0xa0, 0x3c, 0x4c, 0xef, 0x14, 0xcf, 0x5d, 0xe8, - 0x53, 0x90, 0x56, 0xe3, 0x75, 0x21, 0xc4, 0xc0, 0x6c, 0xa4, 0xc2, 0xc2, - 0xab, 0xd5, 0x66, 0x29, 0xcf, 0x7b, 0x74, 0x92, 0x87, 0x5b, 0xc8, 0xe7, - 0xdf, 0x9b, 0x69, 0x26, 0x6c, 0xf6, 0x8f, 0xaf, 0x21, 0xa7, 0xfd, 0xf5, - 0xfb, 0x57, 0xa0, 0xe2, 0x1f, 0xc3, 0x7e, 0x0f, 0x2a, 0x05, 0x06, 0x91, - 0x67, 0x23, 0xcc, 0x22, 0x92, 0xf7, 0xb0, 0x31, 0x38, 0x5c, 0xda, 0x26, - 0xdd, 0x9d, 0x87, 0xf4, 0xfe, 0x7d, 0x86, 0x46, 0x07, 0xda, 0xea, 0xf7, - 0x48, 0x19, 0xb5, 0xd6, 0x7e, 0xfc, 0x2c, 0xcd, 0xe7, 0x4d, 0x76, 0x1d, - 0x7e, 0xbc, 0x2a, 0x52, 0xc0, 0xf5, 0xc5, 0x85, 0x32, 0xfe, 0x9b, 0x24, - 0x19, 0x78, 0x0e, 0x1e, 0xb5, 0xc8, 0x4c, 0xb1, 0x94, 0x7c, 0x1c, 0x16, - 0x11, 0x20, 0xb4, 0xaf, 0xa4, 0x83, 0x2d, 0x2e, 0x20, 0x1f, 0xcc, 0x60, - 0xdf, 0x81, 0xf0, 0xde, 0x55, 0xec, 0x77, 0x24, 0xc6, 0xca, 0x2c, 0xd7, - 0xb6, 0xb7, 0x7f, 0xf7, 0xd4, 0x6a, 0x11, 0x5f, 0xf5, 0xf5, 0x9e, 0xdb, - 0xe3, 0xe4, 0x59, 0x49, 0x2c, 0xd2, 0xee, 0x76, 0x76, 0xb5, 0xb7, 0xd7, - 0x73, 0x71, 0x70, 0xc2, 0x65, 0x8c, 0x8e, 0x9b, 0x87, 0x92, 0xc6, 0xd9, - 0xfc, 0x35, 0x74, 0x9d, 0x7e, 0x21, 0x11, 0x58, 0xaa, 0x23, 0x0b, 0xf6, - 0x28, 0x91, 0x2d, 0xc6, 0x5e, 0x10, 0x89, 0x99, 0x2d, 0x92, 0x3f, 0x0a, - 0xbe, 0xa9, 0xc8, 0x66, 0x05, 0x72, 0x2a, 0x61, 0xc0, 0x99, 0xd4, 0xcd, - 0x87, 0xe2, 0x8b, 0xff, 0xfe, 0x82, 0x27, 0x43, 0x4c, 0x57, 0x06, 0x94, - 0xcf, 0xbb, 0x98, 0xbd, 0x23, 0x32, 0x0b, 0xc1, 0x0f, 0x12, 0x97, 0x3e, - 0x52, 0xaf, 0xac, 0x94, 0xe8, 0xc3, 0xf6, 0xa8, 0x5f, 0x19, 0x5b, 0x60, - 0xf0, 0x56, 0x65, 0x8e, 0x1e, 0x4a, 0xec, 0x5a, 0xcb, 0xc4, 0x69, 0x22, - 0x7a, 0xbf, 0xa0, 0x6b, 0x3a, 0x2a, 0x9f, 0xbb, 0xa4, 0xeb, 0x69, 0x53, - 0x0d, 0x4f, 0xc1, 0x28, 0xc5, 0x1c, 0x76, 0x0b, 0x88, 0x94, 0x42, 0xe2, - 0x37, 0x8a, 0xfb, 0xeb, 0xe2, 0xab, 0x9e, 0xcb, 0x8a, 0x65, 0x09, 0xe8, - 0x60, 0x5e, 0x5c, 0xb8, 0x11, 0x31, 0x7d, 0xe3, 0x40, 0x4a, 0x59, 0xf4, - 0xba, 0xf1, 0xb8, 0x67, 0xd9, 0x9a, 0xbf, 0x88, 0x35, 0x30, 0x2d, 0xf1, - 0xa0, 0xbc, 0xfa, 0x93, 0xa1, 0x6e, 0xcb, 0xfa, 0xde, 0x40, 0xc3, 0xd6, - 0x6f, 0x6f, 0xbe, 0x1f, 0x7a, 0x70, 0xc0, 0x7a, 0x06, 0x44, 0x48, 0x7a, - 0x01, 0xee, 0x58, 0x79, 0x18, 0x7b, 0x81, 0xb8, 0xe9, 0xcf, 0x3c, 0x12, - 0xf8, 0x54, 0xa5, 0xd4, 0xca, 0xfd, 0x06, 0x63, 0x44, 0xe4, 0x84, 0x2e, - 0x3b, 0x52, 0x15, 0x37, 0x69, 0x90, 0xbe, 0x13, 0x5e, 0x46, 0x47, 0x8e, - 0x11, 0x91, 0x08, 0x98, 0xd1, 0x35, 0x2e, 0xd7, 0x2f, 0x62, 0xc2, 0x99, - 0x72, 0xec, 0xc9, 0x9e, 0x4a, 0xbe, 0x0c, 0xb6, 0x3e, 0xb2, 0x9a, 0x12, - 0x16, 0x4a, 0x10, 0x18, 0xfd, 0x70, 0x4c, 0x46, 0x7a, 0x84, 0x2c, 0xc9, - 0x4a, 0xca, 0x2e, 0xa6, 0x8d, 0xce, 0xc9, 0xcd, 0x12, 0xce, 0xbb, 0xbe, - 0xb5, 0xb1, 0x4f, 0xc1, 0x40, 0x45, 0x62, 0x80, 0x44, 0x32, 0xd8, 0x9f, - 0xb0, 0xaf, 0x28, 0x7d, 0x14, 0xe6, 0x0f, 0x6b, 0xba, 0x88, 0xf7, 0xb1, - 0x62, 0xcd, 0x54, 0x3d, 0xe2, 0xaa, 0xc2, 0x76, 0x1c, 0xa5, 0xe5, 0x28, - 0x50, 0x67, 0x87, 0xa1, 0xb2, 0x5e, 0xf8, 0x5b, 0x46, 0xb1, 0xb8, 0x60, - 0x15, 0x82, 0x44, 0x3e, 0x52, 0x59, 0x15, 0x46, 0xe7, 0x40, 0xb2, 0x0d, - 0x53, 0x28, 0x35, 0xf3, 0x43, 0xbe, 0x7f, 0xde, 0x7f, 0x81, 0xb0, 0x02, - 0x88, 0x1d, 0xcc, 0xca, 0xb7, 0x58, 0x8e, 0xc5, 0x85, 0xce, 0xa3, 0x97, - 0xab, 0xfd, 0x47, 0xcf, 0x5e, 0xf4, 0x57, 0xfa, 0x2b, 0x0f, 0x1f, 0x3d, - 0xeb, 0x68, 0x5c, 0x03, 0x4f, 0x9a, 0x44, 0xd1, 0xf9, 0xc4, 0x73, 0xc4, - 0x1e, 0x7b, 0xb1, 0x63, 0xfc, 0x6c, 0x6f, 0x6f, 0x63, 0xed, 0x60, 0xad, - 0x78, 0x1d, 0x68, 0x07, 0xdc, 0x23, 0x8d, 0xe3, 0x57, 0xb5, 0x28, 0x83, - 0x4f, 0x53, 0xdf, 0x17, 0x83, 0x32, 0xa6, 0x93, 0x6b, 0x11, 0xb9, 0x59, - 0x09, 0xcb, 0x4d, 0x75, 0xe7, 0x63, 0xc8, 0xde, 0x5e, 0xec, 0xca, 0xe5, - 0xb1, 0xcb, 0x49, 0x7d, 0x01, 0x80, 0x57, 0x7c, 0x1f, 0x1b, 0x85, 0x2e, - 0x85, 0x01, 0xcf, 0x46, 0x91, 0xeb, 0xad, 0xef, 0x6e, 0xbf, 0x7b, 0xbb, - 0x33, 0x28, 0x5e, 0x4b, 0xc4, 0x4a, 0xa0, 0x8f, 0xab, 0xfa, 0x04, 0xa5, - 0xdd, 0x16, 0x17, 0x84, 0x47, 0xa9, 0x97, 0x2f, 0xee, 0x65, 0xa2, 0xcb, - 0x39, 0xce, 0x82, 0xf8, 0xf1, 0x64, 0xbc, 0x76, 0x03, 0x5b, 0x83, 0x8b, - 0x0b, 0x6c, 0xd1, 0x61, 0x02, 0x31, 0x06, 0x4d, 0x8b, 0xff, 0x28, 0x0c, - 0xe2, 0x0c, 0xcb, 0xd7, 0x3b, 0x2a, 0x69, 0x09, 0x30, 0x53, 0xc0, 0xd6, - 0xa9, 0xd6, 0xbb, 0xe7, 0x10, 0x24, 0x17, 0x5a, 0x02, 0xa7, 0xa0, 0x5d, - 0xa1, 0x8e, 0x29, 0x85, 0x3b, 0xec, 0xbd, 0x50, 0x97, 0x80, 0x9a, 0x5c, - 0x49, 0xb9, 0x3f, 0x4e, 0x2d, 0x9c, 0x9b, 0xc3, 0xf5, 0xb5, 0xc3, 0x37, - 0xef, 0x76, 0x36, 0xb6, 0x37, 0xad, 0xf6, 0x5a, 0x9c, 0x97, 0xa0, 0xf1, - 0x19, 0xe0, 0xa0, 0x70, 0xa1, 0xa0, 0xba, 0x54, 0x13, 0xd5, 0x34, 0x1c, - 0xdf, 0x61, 0x1e, 0xc3, 0x03, 0xb3, 0x95, 0x3a, 0x5f, 0x27, 0xb8, 0x64, - 0x3c, 0xfc, 0xae, 0xd5, 0x62, 0x92, 0x8a, 0x9e, 0x8e, 0xea, 0x9b, 0xdd, - 0xb7, 0x9b, 0x4e, 0x07, 0x3e, 0x9e, 0x26, 0x89, 0x9f, 0x8d, 0xe0, 0x5e, - 0x2c, 0x8d, 0x71, 0x5e, 0x1d, 0x7f, 0x68, 0x32, 0x52, 0xe0, 0x2a, 0x30, - 0xf8, 0x23, 0x5c, 0x7f, 0xf3, 0xe8, 0xc0, 0x17, 0xaf, 0x16, 0xe8, 0xa2, - 0x7a, 0x34, 0x93, 0xc5, 0x63, 0x63, 0xc5, 0x77, 0x1b, 0x5f, 0x1f, 0xae, - 0xef, 0xee, 0x7c, 0xb5, 0xf5, 0x35, 0x47, 0x93, 0x0c, 0x6e, 0x30, 0xd8, - 0x3e, 0x7c, 0xb3, 0xb6, 0xfe, 0xf7, 0xcd, 0x9d, 0x8d, 0xe2, 0x75, 0x32, - 0x01, 0x1d, 0xab, 0x46, 0xa9, 0xe7, 0x48, 0x10, 0x39, 0xfe, 0x46, 0xc7, - 0x32, 0xf5, 0x3b, 0xb1, 0x00, 0x94, 0x82, 0x5f, 0x4d, 0x29, 0xa3, 0x2d, - 0x2e, 0x38, 0x48, 0x85, 0xab, 0x07, 0x7c, 0xf3, 0x42, 0xfd, 0x4b, 0x96, - 0xfe, 0xc4, 0x90, 0x48, 0xed, 0xdf, 0x4f, 0x49, 0xb2, 0x23, 0x8b, 0x0b, - 0x37, 0xf0, 0x2b, 0xed, 0x5e, 0x9d, 0x9f, 0x22, 0xe7, 0x19, 0x72, 0x72, - 0x3b, 0xb9, 0x33, 0x2e, 0x8c, 0x48, 0x7a, 0xf1, 0xd2, 0x62, 0x5c, 0x6c, - 0x8f, 0xae, 0x87, 0x7f, 0xee, 0x03, 0xd5, 0x92, 0x41, 0xac, 0xf7, 0x22, - 0x45, 0xe4, 0x24, 0xd1, 0xcb, 0x40, 0x14, 0x93, 0xa9, 0xa5, 0x74, 0x7e, - 0x11, 0xa1, 0xcd, 0x02, 0x97, 0xb8, 0x8e, 0x37, 0x9f, 0x1a, 0xc4, 0xc0, - 0x44, 0x19, 0x0a, 0x67, 0xc3, 0xd0, 0x90, 0xee, 0xc0, 0xa7, 0xda, 0x45, - 0x72, 0x97, 0x5f, 0x61, 0x9e, 0xe5, 0xa4, 0x69, 0x80, 0xee, 0x73, 0x36, - 0x9a, 0x4d, 0x87, 0x2c, 0xdf, 0x12, 0x8e, 0xe5, 0xc9, 0x94, 0x98, 0x59, - 0xe3, 0xc0, 0x54, 0xf9, 0xed, 0x64, 0xd6, 0xf0, 0xcb, 0x46, 0xc9, 0x13, - 0x5a, 0x04, 0x02, 0x43, 0xc5, 0x8f, 0x89, 0x75, 0x0f, 0x92, 0xde, 0x78, - 0x78, 0xda, 0x00, 0x3e, 0x84, 0xf2, 0xea, 0x3c, 0xc2, 0x9c, 0x5a, 0x1c, - 0x89, 0xe5, 0x12, 0x91, 0xf0, 0x44, 0x70, 0xb8, 0xa8, 0xd2, 0x62, 0x7b, - 0x57, 0x5e, 0xa5, 0x87, 0x38, 0x97, 0xf4, 0x7f, 0xf5, 0x17, 0x17, 0xb6, - 0x01, 0xb8, 0xa2, 0x0c, 0x80, 0x5e, 0x47, 0x12, 0x84, 0xd6, 0x06, 0x10, - 0xce, 0xec, 0xd8, 0x92, 0x85, 0x6a, 0x42, 0xfd, 0xec, 0xac, 0xe8, 0x3d, - 0xd5, 0x22, 0x5a, 0x09, 0x2e, 0xbb, 0x74, 0xc4, 0x52, 0x3d, 0x62, 0xff, - 0xd8, 0xde, 0xfd, 0x7a, 0x63, 0x6b, 0x9f, 0xf3, 0x48, 0xaa, 0x00, 0xde, - 0xa0, 0xdf, 0x1c, 0x41, 0x46, 0x41, 0x43, 0x8c, 0x20, 0xbb, 0xb1, 0xb2, - 0xcf, 0x9d, 0x64, 0xa7, 0xe8, 0xb4, 0x1a, 0xfe, 0x1c, 0x7b, 0xb4, 0xaa, - 0xe1, 0xd2, 0x5d, 0xe0, 0x72, 0x27, 0x33, 0x40, 0x02, 0xff, 0x9b, 0xc8, - 0x5d, 0x2a, 0xba, 0x01, 0xb5, 0xc8, 0xdf, 0xe8, 0x2a, 0x1f, 0xf3, 0x7a, - 0x8c, 0x02, 0xdf, 0x73, 0x62, 0xa9, 0xd7, 0x8a, 0xdc, 0xe8, 0xb9, 0x77, - 0x79, 0x96, 0xcf, 0xe2, 0xc2, 0x52, 0x68, 0xf3, 0xbc, 0xfa, 0x14, 0xae, - 0xb0, 0x8d, 0x31, 0x68, 0x31, 0x46, 0xc4, 0x36, 0x8a, 0xe7, 0xa1, 0x17, - 0xf3, 0x31, 0x36, 0x2d, 0x48, 0xb6, 0x04, 0xbc, 0x85, 0x84, 0x11, 0x96, - 0xfa, 0x5b, 0xcf, 0x9f, 0x5f, 0xa4, 0x97, 0x7a, 0x74, 0x36, 0x3d, 0xbe, - 0x5c, 0xa5, 0x38, 0xff, 0xef, 0x59, 0x10, 0x18, 0xab, 0xe2, 0x1f, 0xef, - 0xb6, 0xd6, 0x53, 0x54, 0x0d, 0x6a, 0xbd, 0xdf, 0x6c, 0x6e, 0x03, 0x2b, - 0xe2, 0x9d, 0x96, 0x82, 0x7a, 0xff, 0x76, 0xd0, 0xe6, 0x51, 0x08, 0x85, - 0x0c, 0x2a, 0x58, 0x60, 0x91, 0x56, 0xaf, 0x63, 0x63, 0x7d, 0xbb, 0x20, - 0xa4, 0xff, 0x8c, 0x60, 0x08, 0xe7, 0xd5, 0xd0, 0xb0, 0x04, 0xc0, 0x78, - 0xd6, 0x37, 0xf7, 0x0f, 0x0e, 0x6d, 0xf3, 0x7e, 0x9d, 0x5b, 0xd3, 0x10, - 0xfc, 0x07, 0x72, 0x6b, 0x1f, 0x12, 0x94, 0x75, 0xab, 0x7a, 0xfa, 0xff, - 0xfa, 0x0a, 0x09, 0x83, 0xfa, 0xfb, 0xe6, 0x3f, 0x03, 0x91, 0xcb, 0xa0, - 0x2c, 0x8b, 0x48, 0x07, 0xc6, 0xf2, 0x18, 0xa2, 0x16, 0xb7, 0xba, 0x6e, - 0xd3, 0xac, 0xbd, 0xd8, 0x35, 0xbe, 0xc4, 0xaa, 0x95, 0xe8, 0x30, 0xc8, - 0xe8, 0x44, 0xaa, 0xd3, 0x34, 0x18, 0x5c, 0x31, 0x69, 0xb6, 0x97, 0x58, - 0x85, 0x34, 0x67, 0x55, 0x0f, 0xb6, 0x32, 0x48, 0x16, 0xe9, 0xd5, 0x5a, - 0xdd, 0xb4, 0x8d, 0x32, 0x7b, 0xb3, 0x1c, 0x5e, 0xff, 0x54, 0xf9, 0x6c, - 0x14, 0x5b, 0x8f, 0xcd, 0x4c, 0x2a, 0x75, 0x75, 0x2b, 0x7d, 0x78, 0x15, - 0x29, 0xbe, 0xa3, 0x32, 0xcf, 0x18, 0x49, 0x94, 0x06, 0x2c, 0x82, 0x92, - 0x55, 0x61, 0x9c, 0x41, 0xf4, 0xf8, 0xe0, 0x41, 0x44, 0x02, 0xff, 0x10, - 0x93, 0x9c, 0xb2, 0x4c, 0xdc, 0xf4, 0x0e, 0x41, 0xd5, 0x1f, 0x0f, 0x9e, - 0xdf, 0xae, 0x8f, 0x26, 0x15, 0x98, 0xee, 0x12, 0x1e, 0x79, 0xd4, 0x5f, - 0x0d, 0x67, 0xf6, 0xd3, 0x72, 0xb7, 0x78, 0x33, 0x06, 0x6a, 0x40, 0x92, - 0xa6, 0xc7, 0x73, 0x00, 0x3e, 0x19, 0x3e, 0x33, 0xdb, 0xc4, 0x60, 0x73, - 0x3f, 0x68, 0x02, 0xb2, 0x03, 0x7f, 0xbc, 0x40, 0x47, 0xe1, 0xa6, 0x6b, - 0x72, 0x5d, 0xf7, 0x36, 0x99, 0x8e, 0x52, 0x13, 0x29, 0x53, 0x04, 0xa6, - 0x99, 0x69, 0x12, 0x3c, 0x27, 0x9d, 0xff, 0x4a, 0x46, 0xfd, 0xc3, 0xda, - 0xa5, 0xa4, 0xf5, 0x80, 0x81, 0x6c, 0x94, 0xd3, 0xd2, 0xc4, 0xd4, 0x36, - 0x8f, 0x4d, 0x0e, 0x62, 0xe4, 0xc7, 0x29, 0xba, 0x6f, 0x2b, 0x32, 0x98, - 0xd0, 0x35, 0x10, 0x31, 0x2c, 0x9e, 0xdd, 0x18, 0xbe, 0x84, 0xa7, 0x2c, - 0xba, 0xdb, 0x58, 0x19, 0xbd, 0x25, 0xf4, 0x8a, 0xf2, 0x1d, 0x7e, 0x1e, - 0xec, 0x06, 0xa1, 0x34, 0xfc, 0xb1, 0xf9, 0xd5, 0xd6, 0x77, 0x66, 0x20, - 0x3b, 0x88, 0x26, 0x1e, 0x05, 0x95, 0x00, 0x9e, 0x44, 0xae, 0x64, 0x58, - 0xa1, 0x8d, 0xc4, 0x58, 0x60, 0x00, 0xd4, 0x52, 0xdf, 0x47, 0x80, 0xf3, - 0x17, 0x15, 0x80, 0xcd, 0xaf, 0x66, 0x69, 0xd7, 0x31, 0x6d, 0x74, 0x19, - 0xb6, 0x32, 0xcb, 0x01, 0x4d, 0x05, 0x37, 0xf2, 0xac, 0xd5, 0xe2, 0x20, - 0x03, 0x0a, 0xb3, 0xd3, 0x28, 0x72, 0xfd, 0x20, 0xda, 0x41, 0xa5, 0x50, - 0x0c, 0xf5, 0x85, 0x04, 0x93, 0x26, 0x08, 0x38, 0xdd, 0xc4, 0x70, 0x01, - 0xf1, 0x4f, 0xb2, 0xaf, 0x0b, 0x46, 0x3d, 0x4b, 0x3c, 0xa8, 0xe9, 0x7a, - 0x0e, 0xbd, 0xe7, 0xaf, 0xe7, 0xc3, 0x36, 0xa4, 0x6d, 0x49, 0x4a, 0x63, - 0x2a, 0x12, 0x0e, 0x00, 0x40, 0x71, 0x13, 0xad, 0x33, 0x6c, 0xe3, 0x5b, - 0x2b, 0x58, 0x33, 0x13, 0x40, 0x6a, 0xa6, 0xad, 0x65, 0x9d, 0x49, 0x4a, - 0xbb, 0xed, 0x92, 0x58, 0x50, 0xcc, 0xa5, 0x2c, 0xab, 0x49, 0xd6, 0xa5, - 0xe6, 0x77, 0x6b, 0xbd, 0x69, 0x35, 0x7f, 0x73, 0x2e, 0x83, 0x6c, 0x32, - 0x40, 0xc1, 0x69, 0x9e, 0xb4, 0x5f, 0x82, 0xdd, 0x32, 0x5c, 0x38, 0x81, - 0x79, 0x56, 0x12, 0xdd, 0xda, 0xeb, 0xc9, 0x83, 0xe9, 0x4b, 0xe5, 0xbd, - 0xdf, 0x2a, 0x93, 0xd7, 0x9e, 0xde, 0xf7, 0xad, 0xa7, 0xe9, 0x4b, 0xe7, - 0xf7, 0x7e, 0xab, 0x67, 0x1a, 0xf8, 0xe2, 0xe2, 0xe6, 0x77, 0x5b, 0x07, - 0x41, 0xb3, 0xda, 0x48, 0xa8, 0x77, 0xa2, 0x47, 0x35, 0xc8, 0x1c, 0x23, - 0xf0, 0x31, 0x54, 0x8e, 0xb3, 0x2c, 0x6f, 0x03, 0xea, 0x86, 0x87, 0xa2, - 0x31, 0x30, 0xc8, 0x7a, 0x22, 0x55, 0x40, 0xe1, 0xbd, 0x90, 0xa0, 0x2d, - 0xc9, 0xf0, 0x90, 0x14, 0x26, 0x26, 0xb2, 0x9a, 0xb9, 0x89, 0x45, 0x73, - 0x25, 0x97, 0x4f, 0x01, 0x6e, 0xb5, 0x45, 0xc4, 0x0d, 0xd5, 0x12, 0x3c, - 0x15, 0xd4, 0x4f, 0xb5, 0x94, 0x4a, 0x69, 0xf2, 0xb1, 0x65, 0x5f, 0x1b, - 0x14, 0x01, 0xeb, 0x3e, 0x08, 0xe4, 0xa3, 0xa6, 0xba, 0x36, 0x9a, 0x07, - 0x8d, 0x27, 0x56, 0x20, 0x9e, 0x4a, 0x4c, 0xaa, 0x63, 0x1e, 0x78, 0xfc, - 0x51, 0x0c, 0xe1, 0xcb, 0x32, 0xe9, 0x59, 0xc4, 0xe5, 0x38, 0x4c, 0xe2, - 0xc4, 0x39, 0x9d, 0xd8, 0x96, 0x12, 0x18, 0x00, 0x3b, 0x6d, 0x8f, 0x20, - 0x45, 0x8c, 0x32, 0xe2, 0x26, 0x59, 0x3b, 0x87, 0x87, 0xa8, 0x76, 0x12, - 0x71, 0x5b, 0xdd, 0xea, 0x9f, 0xab, 0x0f, 0x92, 0x4f, 0xee, 0x2f, 0x4b, - 0xdb, 0xc0, 0x90, 0xfb, 0xaa, 0xac, 0x87, 0x72, 0x39, 0x69, 0xb2, 0x69, - 0xfd, 0x93, 0x49, 0x8b, 0x40, 0x8c, 0x83, 0x85, 0xe5, 0xa2, 0x1c, 0x8a, - 0x7f, 0x4b, 0x0e, 0x80, 0x96, 0xe1, 0xbb, 0x2a, 0x85, 0xd3, 0x69, 0x45, - 0x56, 0x7d, 0x07, 0x58, 0xcd, 0x6b, 0x5e, 0xea, 0x75, 0x3c, 0xf1, 0x4c, - 0x77, 0xf3, 0x20, 0xc6, 0xd0, 0x2f, 0xab, 0xaf, 0x92, 0x02, 0x6f, 0x7b, - 0xaa, 0x06, 0xdd, 0xb7, 0x02, 0x7e, 0x2d, 0xd5, 0x59, 0xd0, 0x16, 0x45, - 0xd3, 0xea, 0x13, 0xb8, 0x73, 0xcd, 0xbc, 0x01, 0xab, 0x36, 0x89, 0xd4, - 0x27, 0xae, 0x83, 0x54, 0x83, 0x67, 0x21, 0x8f, 0x0b, 0x47, 0xf1, 0x59, - 0x5c, 0x20, 0xfb, 0x85, 0xcc, 0x35, 0xe6, 0x42, 0x74, 0xb5, 0x8e, 0xc5, - 0xf8, 0xa8, 0x44, 0x65, 0x26, 0xc2, 0xbe, 0x96, 0x23, 0x51, 0x93, 0x7d, - 0x39, 0x15, 0xd9, 0x4f, 0xe7, 0x15, 0x48, 0x7f, 0x61, 0xdd, 0x6d, 0x97, - 0x0a, 0xeb, 0x98, 0xb2, 0x05, 0xb1, 0x05, 0x09, 0xeb, 0x61, 0xf8, 0xc2, - 0xb1, 0x3f, 0xcd, 0xd2, 0x01, 0x8d, 0x05, 0x31, 0xa2, 0xb5, 0x67, 0x73, - 0x5b, 0x93, 0x52, 0xa1, 0xb1, 0xb1, 0x34, 0x1c, 0xf5, 0xae, 0xd6, 0x9e, - 0x67, 0xdb, 0x98, 0xc4, 0xb4, 0xb2, 0x41, 0x79, 0xe6, 0x45, 0x78, 0xe6, - 0xdb, 0x0a, 0x38, 0xa2, 0x6a, 0x06, 0x9e, 0x54, 0x97, 0x43, 0x1d, 0xba, - 0x7e, 0xc2, 0x88, 0x7b, 0x01, 0xe0, 0xa5, 0x66, 0xed, 0x3d, 0x06, 0x5d, - 0xd0, 0x3d, 0x0f, 0x2f, 0xd1, 0x57, 0x60, 0x88, 0x62, 0x8d, 0x03, 0x33, - 0x1c, 0xd5, 0x4e, 0x18, 0x9a, 0xcb, 0x27, 0x9f, 0x21, 0x29, 0x59, 0xd2, - 0x6a, 0xed, 0x03, 0x7b, 0xc9, 0x33, 0x94, 0x93, 0x88, 0x4f, 0x4c, 0x69, - 0x36, 0x11, 0xe8, 0xe2, 0x44, 0x55, 0x20, 0x3a, 0x50, 0x39, 0xb2, 0x4a, - 0x9a, 0x13, 0xe4, 0xb7, 0xf5, 0x8b, 0xb7, 0x63, 0x5a, 0xf6, 0x18, 0x42, - 0x2d, 0xa2, 0xd4, 0xa4, 0xd6, 0xc9, 0x13, 0x91, 0x46, 0xa4, 0xb8, 0xa4, - 0x96, 0x3a, 0x88, 0xcf, 0x71, 0x25, 0x88, 0x97, 0x61, 0x39, 0xb9, 0x9e, - 0x18, 0xcd, 0xb3, 0xb6, 0x92, 0xcc, 0x0e, 0x39, 0xbe, 0x5c, 0xd4, 0x7e, - 0xf1, 0xed, 0xb9, 0x48, 0x73, 0x65, 0x3d, 0xb5, 0xeb, 0x5a, 0x5c, 0x29, - 0x6e, 0x51, 0xb7, 0x45, 0x67, 0x08, 0xb6, 0x1a, 0x73, 0x61, 0xc4, 0x93, - 0xa0, 0x01, 0xc9, 0xc0, 0x6e, 0x9a, 0x04, 0xc7, 0xa1, 0x1b, 0xcb, 0x10, - 0x48, 0x79, 0x4a, 0xb8, 0x06, 0xc8, 0x37, 0x1d, 0x3a, 0x46, 0x0b, 0x9e, - 0x2e, 0xa6, 0x0e, 0xe4, 0x58, 0x92, 0xcb, 0x86, 0xfc, 0x48, 0x87, 0x7c, - 0xc5, 0xcd, 0xdd, 0x5b, 0x1b, 0x0c, 0x6c, 0x6b, 0xd7, 0xe3, 0x2e, 0xc6, - 0x6d, 0xd4, 0x30, 0x4b, 0x96, 0x88, 0x53, 0x60, 0x7d, 0x29, 0xc9, 0x1d, - 0x5e, 0x5c, 0x5c, 0x88, 0x39, 0x16, 0x6c, 0x1b, 0xfc, 0x61, 0x43, 0x60, - 0xc6, 0xf3, 0xc9, 0xf8, 0x6c, 0xa4, 0x46, 0xb8, 0x2d, 0x8c, 0xaf, 0x4c, - 0x5c, 0x18, 0x5b, 0x19, 0xb1, 0x22, 0x58, 0x19, 0xfb, 0xae, 0xf3, 0x5b, - 0x1a, 0x4e, 0x3f, 0x5d, 0xe2, 0xf0, 0x5b, 0xaf, 0x8f, 0xdb, 0x33, 0x7a, - 0x2f, 0x03, 0xee, 0xfe, 0xe6, 0x19, 0xbd, 0xbf, 0x31, 0xa3, 0x27, 0x59, - 0xdb, 0xc5, 0xea, 0xea, 0x73, 0x45, 0x91, 0xd2, 0xe5, 0x4a, 0xa8, 0x3e, - 0x69, 0x1d, 0xcf, 0xf5, 0x98, 0x35, 0x99, 0x6c, 0x3b, 0x34, 0x81, 0x91, - 0x37, 0xfc, 0x54, 0x1b, 0x56, 0xf0, 0x0d, 0xca, 0x10, 0x72, 0x9e, 0x8b, - 0x78, 0xd0, 0xfd, 0xa4, 0xab, 0x44, 0x1b, 0xc8, 0x10, 0x09, 0xc3, 0x57, - 0x28, 0x48, 0x37, 0x9e, 0x46, 0x77, 0xb5, 0x75, 0x67, 0x8d, 0x83, 0x5d, - 0x28, 0xd4, 0xa7, 0xe6, 0x25, 0xac, 0x91, 0x7b, 0x0d, 0xab, 0x0b, 0xe1, - 0x89, 0xa2, 0x4b, 0x46, 0xf9, 0x8b, 0x00, 0xa1, 0x88, 0x9c, 0xb9, 0xc0, - 0xb6, 0x0c, 0xcb, 0x6b, 0x45, 0xb1, 0xa0, 0x62, 0xd5, 0x14, 0x62, 0x62, - 0x0f, 0x67, 0xe2, 0xac, 0x1a, 0xc1, 0xf6, 0x2d, 0x31, 0x8e, 0x66, 0x9c, - 0x86, 0x79, 0x49, 0x0d, 0xc7, 0x1e, 0x76, 0xa0, 0xbd, 0x35, 0xe2, 0x6c, - 0x95, 0x51, 0x66, 0xd0, 0x11, 0x2d, 0xbf, 0x2b, 0x87, 0xfd, 0xdc, 0xd6, - 0xc4, 0x17, 0x00, 0xda, 0x97, 0x54, 0xd8, 0xea, 0x27, 0xcb, 0x62, 0x87, - 0xd6, 0x6b, 0x5e, 0x4a, 0xd2, 0x31, 0x70, 0xb8, 0xe5, 0x59, 0x6d, 0x0f, - 0x3c, 0x6c, 0x0f, 0x2c, 0xa3, 0x1c, 0x2a, 0x26, 0xd0, 0x2e, 0x5d, 0xa5, - 0x59, 0xa8, 0xce, 0xa9, 0x10, 0x64, 0x96, 0xb5, 0x63, 0x0d, 0xbc, 0xbc, - 0x31, 0x20, 0xcf, 0xcb, 0x79, 0x68, 0xbc, 0x29, 0x56, 0x07, 0x14, 0xe7, - 0x32, 0x3f, 0xd8, 0xdf, 0x3c, 0xd8, 0x67, 0x46, 0x80, 0x9d, 0xbe, 0x65, - 0x9c, 0x4a, 0x41, 0x60, 0x51, 0x26, 0xa1, 0x37, 0xaa, 0x1d, 0x47, 0x29, - 0x00, 0xe5, 0xbb, 0x25, 0xff, 0xda, 0x2b, 0x96, 0x51, 0xaa, 0x0c, 0xc0, - 0x43, 0xf4, 0x33, 0x66, 0xb4, 0xba, 0xaa, 0xbb, 0x1e, 0xa6, 0x77, 0x56, - 0xe9, 0x45, 0xa1, 0xc9, 0xf9, 0x2a, 0x69, 0x44, 0xe0, 0x0f, 0xa9, 0x39, - 0xae, 0x37, 0xb2, 0xe4, 0xbe, 0x8d, 0xb3, 0xd4, 0x55, 0xbb, 0xde, 0xa4, - 0x47, 0xb7, 0xb1, 0xb1, 0xfd, 0x84, 0x0d, 0x1d, 0xb1, 0x3a, 0xc0, 0x93, - 0x95, 0x15, 0x1a, 0x22, 0x8e, 0x02, 0x33, 0x32, 0x39, 0x43, 0x9a, 0xc2, - 0xb4, 0x01, 0xf5, 0xc1, 0x75, 0xa7, 0x5c, 0xd5, 0x40, 0x0e, 0xee, 0xf5, - 0xb0, 0x0a, 0x09, 0x9a, 0x1f, 0x27, 0x80, 0x83, 0xfc, 0x2d, 0x01, 0x37, - 0x74, 0x1d, 0xb2, 0x33, 0xc6, 0xa1, 0x0a, 0x1e, 0x87, 0xd6, 0x0f, 0xc8, - 0xec, 0x45, 0xb4, 0xcb, 0x68, 0x1d, 0x44, 0x20, 0x54, 0xe6, 0x6c, 0x6f, - 0xf5, 0x69, 0xbc, 0xf3, 0xdc, 0xb7, 0x10, 0x4b, 0xd5, 0x6b, 0xe9, 0xb8, - 0xaf, 0x3c, 0x94, 0xc3, 0x18, 0xd2, 0xf5, 0x25, 0x3c, 0x3d, 0x10, 0x1d, - 0xf4, 0x4a, 0x22, 0x25, 0x0f, 0x0e, 0x76, 0xf7, 0x6d, 0x73, 0xac, 0x03, - 0x9c, 0xb9, 0x7d, 0xa0, 0xd7, 0xe9, 0xd8, 0xdf, 0x2b, 0xc4, 0xe7, 0x44, - 0xf1, 0xbb, 0xec, 0x44, 0xd8, 0xf3, 0x20, 0xf6, 0x5d, 0x39, 0x35, 0x82, - 0x95, 0x89, 0x6d, 0x57, 0xd4, 0xcc, 0xd0, 0xa3, 0x25, 0x99, 0x9a, 0x7c, - 0x93, 0x53, 0x0d, 0x28, 0x7b, 0xd7, 0xa5, 0x46, 0xe5, 0x8b, 0x7a, 0xa9, - 0xba, 0x6e, 0x85, 0x8f, 0x19, 0x2e, 0x11, 0x1e, 0xac, 0xc3, 0xf9, 0x90, - 0x9c, 0xdf, 0x52, 0xe2, 0xb1, 0x5c, 0x9c, 0xa4, 0x5d, 0x41, 0xaf, 0x0f, - 0x13, 0x71, 0x55, 0x9c, 0xb3, 0xdb, 0x6d, 0x6f, 0x77, 0xff, 0xc0, 0xef, - 0x36, 0xf4, 0xc1, 0x0f, 0x8a, 0x16, 0x41, 0x23, 0x77, 0x9c, 0x0a, 0x74, - 0xc4, 0x0f, 0x69, 0x5c, 0xaa, 0x14, 0x5b, 0x18, 0xdf, 0xd3, 0xd7, 0xba, - 0x50, 0xdc, 0xc3, 0x71, 0x12, 0x53, 0x56, 0x92, 0x24, 0x8c, 0x0f, 0xc8, - 0xc4, 0x63, 0x0d, 0x02, 0x8e, 0xe6, 0xd1, 0x8d, 0xc3, 0x08, 0x9e, 0xb9, - 0xbf, 0x39, 0x38, 0x50, 0x3d, 0x0b, 0x7f, 0xde, 0x18, 0x94, 0xa0, 0xdb, - 0xea, 0x87, 0x66, 0x39, 0x58, 0x5c, 0x00, 0xf7, 0x41, 0xf2, 0x00, 0xac, - 0x82, 0x68, 0xd4, 0xa3, 0xb3, 0xac, 0xb7, 0xc7, 0x76, 0x98, 0x04, 0xdb, - 0x52, 0x37, 0x95, 0x87, 0x88, 0x1f, 0x74, 0xb4, 0xcd, 0x4e, 0x10, 0x1b, - 0x64, 0x34, 0x0a, 0x8d, 0xc9, 0xb7, 0x9f, 0xf8, 0x51, 0x04, 0xcf, 0xd6, - 0x97, 0xb7, 0x04, 0xc3, 0x78, 0xc8, 0x0f, 0xbd, 0x5c, 0x3d, 0x59, 0xaa, - 0xec, 0xa3, 0x21, 0x54, 0xb1, 0x89, 0xa7, 0x6a, 0xc6, 0x36, 0x49, 0x21, - 0x19, 0x01, 0x3e, 0xb6, 0xcc, 0x28, 0xca, 0x17, 0x29, 0x6d, 0x3c, 0x06, - 0x21, 0xbe, 0x29, 0x4f, 0x62, 0x06, 0xa1, 0xcc, 0x33, 0x63, 0xa0, 0xea, - 0xc4, 0xa0, 0x4c, 0x51, 0x4e, 0x86, 0x08, 0x91, 0x0b, 0x87, 0x77, 0x22, - 0x90, 0x40, 0x9a, 0x42, 0xa8, 0xcd, 0x91, 0x29, 0xc3, 0x36, 0x73, 0x9c, - 0xc8, 0x9f, 0xe5, 0x89, 0x32, 0xd4, 0x28, 0x46, 0xc2, 0x52, 0xee, 0x0c, - 0xb5, 0x5f, 0xec, 0xc1, 0x67, 0xc5, 0x3b, 0xbf, 0xf9, 0x9b, 0xb6, 0x04, - 0xa2, 0x45, 0x64, 0x82, 0x03, 0x4e, 0xd5, 0xa8, 0x44, 0xcd, 0x4f, 0x08, - 0x01, 0x1c, 0xd5, 0xa0, 0x7c, 0x42, 0x2f, 0xed, 0xbd, 0x26, 0x8c, 0x15, - 0x88, 0x5a, 0xe9, 0xb7, 0x4f, 0x48, 0x16, 0x56, 0xd3, 0xc7, 0xb9, 0x19, - 0x0e, 0x93, 0x56, 0xa3, 0x3a, 0x91, 0x2e, 0xbc, 0xee, 0x4f, 0xc6, 0xf5, - 0xac, 0x15, 0xf0, 0xce, 0x35, 0x5d, 0x01, 0x14, 0xfe, 0x08, 0x74, 0x0c, - 0xf9, 0x23, 0x34, 0x43, 0xcf, 0xaa, 0x9b, 0x77, 0xb2, 0xc8, 0x44, 0x2e, - 0x59, 0x5a, 0x97, 0xdd, 0x03, 0x60, 0x9e, 0x80, 0x7c, 0x7c, 0xbf, 0x9d, - 0xab, 0x67, 0x63, 0xd0, 0x04, 0x60, 0xad, 0x1a, 0x7e, 0x54, 0x32, 0x82, - 0x34, 0x28, 0xbd, 0x53, 0xe7, 0xe8, 0x4f, 0x9e, 0x5a, 0x2b, 0xa7, 0x80, - 0xf8, 0xf3, 0x66, 0xe2, 0x11, 0x0f, 0xa7, 0x5b, 0x2a, 0xb2, 0xd4, 0xfe, - 0x54, 0x26, 0xf8, 0x27, 0xdc, 0xf5, 0x09, 0x36, 0xf2, 0x60, 0x0c, 0x3d, - 0x07, 0xd1, 0x13, 0x9e, 0xae, 0xde, 0x97, 0xd0, 0xbb, 0xc4, 0xcc, 0xe7, - 0x5f, 0xc5, 0x3a, 0xb8, 0x06, 0x76, 0x78, 0x51, 0x7e, 0xaa, 0x2f, 0x66, - 0x17, 0xe1, 0x7a, 0x60, 0xd2, 0xac, 0x35, 0xfd, 0x82, 0x3a, 0xa7, 0x24, - 0x46, 0x5b, 0x5d, 0x92, 0xc8, 0x86, 0xc6, 0xae, 0x1a, 0x59, 0xde, 0x71, - 0x60, 0x34, 0x02, 0xdc, 0x41, 0x41, 0x9b, 0xba, 0x55, 0x29, 0x90, 0xbb, - 0xe5, 0xe2, 0x82, 0x88, 0x5a, 0x11, 0xf0, 0x2c, 0xd6, 0x7b, 0xa1, 0xe8, - 0xa2, 0x4f, 0xca, 0x77, 0x86, 0xa6, 0x2e, 0x97, 0xe4, 0xbf, 0x28, 0xd3, - 0x84, 0x5e, 0xc0, 0x87, 0x17, 0x17, 0x04, 0xf1, 0x88, 0xd9, 0xe3, 0xc4, - 0xd9, 0xfd, 0x93, 0x8e, 0xf6, 0x25, 0xad, 0x10, 0xaa, 0xa2, 0x22, 0xb2, - 0x10, 0x30, 0xb8, 0x59, 0xfc, 0xd2, 0xd3, 0x55, 0x0d, 0x09, 0xd0, 0x6b, - 0xc0, 0x8e, 0xb8, 0x48, 0x8d, 0x61, 0xfd, 0x80, 0x04, 0x7a, 0xd6, 0xd5, - 0x08, 0x10, 0x2b, 0x96, 0x6a, 0xb5, 0x55, 0xa8, 0x1c, 0x66, 0x87, 0xf9, - 0xe9, 0x63, 0x3b, 0xcc, 0x93, 0xeb, 0x4b, 0x9a, 0x75, 0xcf, 0x20, 0x1c, - 0xb6, 0xa9, 0xf0, 0x29, 0xd8, 0xc6, 0xba, 0x1c, 0x0e, 0x48, 0x3e, 0x37, - 0xdf, 0x28, 0x9b, 0xc4, 0xcb, 0xc5, 0x57, 0xd2, 0x7b, 0xad, 0x12, 0xf3, - 0x86, 0x19, 0x7e, 0x71, 0x49, 0xda, 0x63, 0xcf, 0xf4, 0x31, 0xfa, 0x7a, - 0x47, 0x9a, 0x99, 0x75, 0xdb, 0xc3, 0x94, 0x9b, 0x4c, 0x5c, 0xb4, 0x9b, - 0x5f, 0xae, 0xd9, 0x24, 0x35, 0xd7, 0x9e, 0x7e, 0x99, 0xe9, 0xa6, 0xe0, - 0xc9, 0x71, 0xef, 0x39, 0x83, 0xfa, 0xf2, 0xdc, 0x49, 0xfa, 0x19, 0xee, - 0x94, 0x3d, 0x64, 0xf9, 0xa6, 0x49, 0xbe, 0x11, 0x81, 0x2e, 0x81, 0x9e, - 0xb6, 0xb3, 0x21, 0x64, 0xb5, 0xbe, 0x96, 0x41, 0xbe, 0x58, 0x73, 0x62, - 0xed, 0x08, 0xd3, 0x19, 0x9f, 0x8d, 0xea, 0x9f, 0xaa, 0x93, 0x78, 0x91, - 0xb0, 0xc6, 0x53, 0x98, 0xa1, 0x3d, 0xf9, 0x98, 0xbb, 0x4e, 0xf2, 0xd5, - 0x18, 0x4b, 0xe4, 0xbc, 0x23, 0xa6, 0x4e, 0x5c, 0x6b, 0xf2, 0xd4, 0x13, - 0xde, 0xe2, 0x26, 0x25, 0xe1, 0x66, 0xc0, 0x14, 0x88, 0x91, 0x9c, 0xf3, - 0x9d, 0x67, 0xe4, 0xcf, 0xba, 0xe2, 0xb4, 0x48, 0x48, 0xb5, 0x22, 0xb2, - 0x9c, 0x86, 0xe0, 0x0d, 0x57, 0xe2, 0xdb, 0x2b, 0x5b, 0x97, 0xf7, 0xb3, - 0x67, 0xb7, 0x58, 0x51, 0xd8, 0xd5, 0x26, 0x37, 0xda, 0x1e, 0x7d, 0xae, - 0x74, 0x18, 0x8b, 0xf6, 0x5a, 0x02, 0x47, 0x37, 0xad, 0xb6, 0x6c, 0x2c, - 0x4d, 0xd4, 0x50, 0xd2, 0x9f, 0x72, 0x29, 0xed, 0x9a, 0x49, 0x93, 0x41, - 0xbf, 0x2e, 0x6a, 0x23, 0xf1, 0x67, 0xd8, 0xe4, 0xaf, 0xe8, 0x20, 0x8b, - 0x12, 0xe0, 0xa8, 0x38, 0xc8, 0xc0, 0xbf, 0xf8, 0xe0, 0x4b, 0xee, 0x98, - 0x71, 0x73, 0xd7, 0x23, 0xe6, 0x3e, 0xfc, 0x7c, 0x25, 0x4a, 0x35, 0x27, - 0x88, 0xc2, 0x12, 0x70, 0xd2, 0xf9, 0xcf, 0x62, 0xef, 0xb6, 0x86, 0x00, - 0x83, 0x1f, 0xca, 0xd7, 0x6d, 0x2e, 0xfa, 0x7c, 0x35, 0xe1, 0x2b, 0x07, - 0xe9, 0x35, 0x5d, 0x6c, 0x6d, 0xd8, 0x33, 0x8f, 0x6d, 0x1e, 0x56, 0x74, - 0x8f, 0xea, 0x7a, 0x53, 0x2c, 0xe1, 0x85, 0x65, 0x7b, 0x0a, 0xfb, 0xba, - 0x33, 0x16, 0x48, 0x75, 0xa6, 0xdb, 0xe4, 0x5f, 0x3f, 0x4f, 0x28, 0xde, - 0x04, 0x36, 0xcb, 0x49, 0x57, 0xca, 0x2b, 0x96, 0x60, 0xf9, 0xff, 0x9b, - 0xd9, 0x24, 0x58, 0xa7, 0xad, 0xf9, 0x9b, 0xb7, 0xf0, 0x42, 0x77, 0xca, - 0xed, 0x12, 0x49, 0xf1, 0x47, 0xe5, 0x42, 0x8c, 0x84, 0xca, 0x8c, 0x0a, - 0xf6, 0x32, 0x96, 0x38, 0x5c, 0x34, 0xb3, 0x51, 0x3c, 0x39, 0x22, 0x63, - 0x2b, 0xf6, 0xd7, 0x49, 0x5a, 0xbc, 0x6b, 0x30, 0xf8, 0xc6, 0xd4, 0x69, - 0xb3, 0xd5, 0xac, 0x64, 0x14, 0xd5, 0x9c, 0xcf, 0xa6, 0xbc, 0xc6, 0x7d, - 0x0a, 0x19, 0x54, 0x06, 0xdf, 0x58, 0xcd, 0x0e, 0x2d, 0xc5, 0x84, 0xf5, - 0x30, 0x3c, 0x51, 0x61, 0xb8, 0xd5, 0x62, 0x87, 0xbf, 0x9a, 0x8c, 0xc5, - 0x80, 0x01, 0x95, 0x57, 0xdf, 0xe5, 0xdd, 0x86, 0xd0, 0xe2, 0x89, 0x06, - 0x40, 0x64, 0xe4, 0xfd, 0xe2, 0x89, 0xae, 0x04, 0x25, 0xc7, 0xa0, 0x08, - 0x15, 0x73, 0x15, 0x9f, 0x17, 0x38, 0x3f, 0x6f, 0xeb, 0x46, 0x8c, 0xf9, - 0x81, 0x5c, 0xf6, 0x0f, 0x06, 0x7b, 0xc5, 0xfa, 0xa0, 0xfa, 0xb7, 0x86, - 0xc5, 0xd8, 0x11, 0x7f, 0xf1, 0x6c, 0xde, 0x83, 0x03, 0xb5, 0x27, 0x6c, - 0x79, 0x8c, 0xbf, 0x3f, 0xff, 0x9c, 0x44, 0x63, 0x16, 0x3c, 0x51, 0xca, - 0x31, 0x16, 0x1e, 0xfa, 0x61, 0x5c, 0xf5, 0x17, 0x2f, 0x4c, 0xa0, 0x3c, - 0x9f, 0x8d, 0x3e, 0xf8, 0x95, 0xaf, 0x55, 0x68, 0x6c, 0x0b, 0xec, 0xe1, - 0x97, 0x42, 0x40, 0x89, 0x69, 0xc5, 0x23, 0x6e, 0xbb, 0xaa, 0x8b, 0xb9, - 0xbd, 0x26, 0xb0, 0x8f, 0x99, 0x4f, 0xf4, 0xe5, 0x8a, 0xf2, 0x7e, 0x2d, - 0x2c, 0xf0, 0xa1, 0xba, 0x4e, 0x21, 0x4b, 0x25, 0xc8, 0xf0, 0xb2, 0x1e, - 0x41, 0xbd, 0x8b, 0x8f, 0xd8, 0xcb, 0x3c, 0x23, 0x23, 0x41, 0x59, 0xe7, - 0x4e, 0x26, 0x5c, 0x53, 0xd0, 0x99, 0xec, 0x49, 0xec, 0xe8, 0x00, 0xae, - 0x82, 0x0b, 0xa5, 0x9d, 0x5a, 0x7c, 0x05, 0x0f, 0xdb, 0x7a, 0xbd, 0x3e, - 0xff, 0x58, 0x68, 0x0e, 0x95, 0x45, 0xe6, 0x89, 0x25, 0xe2, 0xad, 0xe4, - 0x85, 0x46, 0xe0, 0x68, 0x95, 0x87, 0xf4, 0xe5, 0x27, 0xf2, 0x72, 0xab, - 0x50, 0x80, 0xb7, 0xe3, 0xfa, 0x6a, 0xeb, 0x1e, 0x7c, 0xf9, 0x94, 0xd6, - 0xde, 0xd4, 0x14, 0xe1, 0x96, 0x88, 0xd4, 0x14, 0x81, 0xe0, 0x01, 0x35, - 0x42, 0x58, 0xc6, 0x88, 0x9b, 0x20, 0xcc, 0x06, 0x21, 0x01, 0x6e, 0x16, - 0xaa, 0xc2, 0x10, 0x97, 0xdb, 0x8d, 0x10, 0xb4, 0x42, 0x48, 0x12, 0x50, - 0x66, 0x84, 0x90, 0x62, 0x06, 0xb9, 0x19, 0xe2, 0x25, 0x08, 0x8e, 0x3e, - 0xfa, 0x34, 0x2e, 0xc0, 0xc5, 0x6f, 0xc6, 0x2f, 0x48, 0x23, 0x70, 0x16, - 0xb0, 0xc6, 0x58, 0x04, 0x02, 0x0d, 0xc3, 0x61, 0xec, 0x89, 0xd4, 0x81, - 0xba, 0x56, 0xa3, 0x47, 0x5f, 0x7c, 0xfe, 0xb5, 0x47, 0xd7, 0x8a, 0xa3, - 0x89, 0xaf, 0x59, 0x44, 0x72, 0x98, 0x73, 0x5b, 0x09, 0x79, 0xa9, 0x6c, - 0x09, 0x16, 0x62, 0x07, 0x42, 0xc8, 0xd6, 0xf3, 0x05, 0xd7, 0xf3, 0x78, - 0x88, 0x9a, 0x97, 0x3d, 0xee, 0x55, 0x4a, 0x20, 0x75, 0x13, 0x65, 0x60, - 0xda, 0x1c, 0x35, 0x4f, 0xdc, 0xbc, 0xc7, 0x09, 0x40, 0x9a, 0x34, 0x47, - 0x56, 0x3f, 0x1e, 0x12, 0xb9, 0x57, 0xab, 0x8c, 0xfb, 0x56, 0x9e, 0x96, - 0x53, 0x17, 0x65, 0xcd, 0xfa, 0xb9, 0xc2, 0xee, 0x1d, 0x32, 0x9d, 0x57, - 0xa0, 0x14, 0x1a, 0x38, 0x0b, 0xd7, 0x9f, 0x55, 0x3b, 0x61, 0x0c, 0x52, - 0x29, 0x10, 0x5f, 0xe6, 0x19, 0xfd, 0x0e, 0x87, 0x1a, 0x11, 0x4a, 0xd1, - 0x96, 0xd0, 0x58, 0x75, 0x38, 0xf5, 0xbf, 0xa8, 0x5c, 0x05, 0xb2, 0xa2, - 0x6f, 0xc0, 0x6a, 0x5e, 0x35, 0xaa, 0xee, 0x19, 0x8c, 0xf1, 0xe2, 0x42, - 0xd8, 0x7c, 0x71, 0xd6, 0x21, 0x42, 0x8a, 0x06, 0xbd, 0x11, 0x28, 0x40, - 0xed, 0x44, 0xa1, 0xcb, 0x37, 0xef, 0xbe, 0x1e, 0xb8, 0x2f, 0x92, 0xc5, - 0xf1, 0x3e, 0x41, 0x27, 0x26, 0xa6, 0x22, 0xa4, 0x61, 0x23, 0x14, 0x11, - 0x38, 0xc4, 0xe0, 0xd8, 0xcc, 0x8e, 0x2e, 0xe0, 0xd4, 0x1b, 0x49, 0x1a, - 0x85, 0x23, 0x03, 0x85, 0x67, 0x21, 0x67, 0x7e, 0x21, 0xfe, 0x1e, 0x94, - 0xba, 0x60, 0x8d, 0x0b, 0xc4, 0x53, 0x8e, 0x8a, 0xaf, 0xeb, 0xe9, 0x37, - 0xb3, 0xa3, 0x57, 0xee, 0xc6, 0x3b, 0x0b, 0xed, 0xcd, 0x8e, 0x58, 0xdc, - 0x11, 0xad, 0xca, 0x0f, 0xb6, 0xd7, 0x2c, 0x2e, 0xae, 0xbd, 0x3b, 0xf8, - 0x66, 0x77, 0x5f, 0x07, 0xb6, 0x51, 0x8e, 0xc2, 0xc2, 0x15, 0x83, 0x69, - 0x35, 0x0a, 0xcc, 0xef, 0xcc, 0x68, 0x85, 0xe1, 0xc6, 0x38, 0x66, 0xe3, - 0x89, 0xe2, 0x79, 0x10, 0x59, 0xf2, 0x7c, 0x3c, 0x8c, 0xf1, 0xaa, 0xb4, - 0xfb, 0x22, 0x09, 0x64, 0x2c, 0xd1, 0x83, 0x6c, 0x2f, 0xc3, 0x4f, 0xb4, - 0x00, 0xec, 0xe2, 0xe0, 0x9b, 0xb5, 0x9d, 0xbf, 0x0f, 0xcc, 0x4f, 0xfc, - 0xed, 0xb7, 0xdf, 0xe6, 0x5e, 0x47, 0x0a, 0xe9, 0x4d, 0xb5, 0xb8, 0x38, - 0xd8, 0xdc, 0x2c, 0xd6, 0xb6, 0x07, 0xbb, 0xf2, 0xf5, 0xe9, 0xf4, 0xb2, - 0x58, 0x7a, 0xb4, 0x1c, 0xe4, 0x5d, 0xc4, 0xd0, 0x86, 0xbf, 0x16, 0x17, - 0xff, 0x07, 0xfe, 0x37, 0x69, 0x77, 0xdd, 0xce, 0x03, 0x00, + 0x7b, 0x7b, 0x1b, 0xd7, 0xb1, 0x2f, 0x08, 0xff, 0x2d, 0x7f, 0x8a, 0x3e, + 0xc8, 0xec, 0x43, 0x72, 0x07, 0x00, 0x6f, 0x92, 0x2c, 0x33, 0xb2, 0xc7, + 0x34, 0x45, 0x59, 0xdc, 0x91, 0x44, 0x46, 0xa4, 0xe2, 0x64, 0xc7, 0x7e, + 0xf4, 0x34, 0x80, 0x06, 0xd9, 0x16, 0x80, 0x46, 0xba, 0x1b, 0xa4, 0x98, + 0x9c, 0xbc, 0x9f, 0xfd, 0xad, 0xfb, 0xaa, 0xd5, 0x68, 0x90, 0x90, 0x2c, + 0x65, 0x66, 0xce, 0x4c, 0x2e, 0x14, 0x09, 0x74, 0xaf, 0x6b, 0xad, 0x5a, + 0x75, 0xfd, 0x55, 0x92, 0xe8, 0x7f, 0xde, 0xd1, 0xff, 0xdf, 0xc1, 0x7f, + 0xe0, 0xdf, 0xaf, 0xe4, 0xb3, 0x77, 0xef, 0xfe, 0x57, 0xc2, 0xff, 0x85, + 0xef, 0x7e, 0x86, 0x7f, 0xf9, 0x8b, 0xed, 0x24, 0x7c, 0xf1, 0xbf, 0xde, + 0x6d, 0x25, 0xfa, 0xc5, 0xff, 0x4a, 0x36, 0xe9, 0x8b, 0x77, 0xf2, 0xc6, + 0x53, 0xfc, 0xfd, 0x9d, 0xb4, 0xf6, 0x33, 0xb6, 0x86, 0x3f, 0xb6, 0xf1, + 0xfb, 0x9f, 0xdf, 0xe1, 0xaf, 0xf0, 0xc9, 0x57, 0xaf, 0x0f, 0x5f, 0x1d, + 0x7f, 0x45, 0x8f, 0x0c, 0x17, 0xe5, 0x24, 0xe9, 0x25, 0x75, 0x99, 0xce, + 0xaa, 0x71, 0x56, 0x26, 0x69, 0xf2, 0xf6, 0xcd, 0xcb, 0xaf, 0xbe, 0x3a, + 0xff, 0xeb, 0xeb, 0xd3, 0xb3, 0xf3, 0x93, 0x73, 0xf7, 0xd0, 0xdf, 0x8a, + 0x79, 0x9d, 0x17, 0xb3, 0x0a, 0x46, 0x02, 0x8f, 0x54, 0xbf, 0x7c, 0xf5, + 0xd5, 0xb3, 0xe3, 0xf3, 0xa3, 0x37, 0x27, 0x67, 0x17, 0x27, 0xa7, 0xaf, + 0xdd, 0x73, 0x79, 0x05, 0x8d, 0xd4, 0x45, 0x31, 0x49, 0x92, 0x71, 0x51, + 0x5a, 0xcb, 0x65, 0x3e, 0xbb, 0x4c, 0x46, 0x69, 0x9d, 0xc2, 0xc7, 0x65, + 0x31, 0x4d, 0xf0, 0xab, 0x02, 0x9e, 0x4c, 0xaa, 0xac, 0xbc, 0x86, 0x8e, + 0x17, 0x15, 0x3e, 0x80, 0x2d, 0xf7, 0x93, 0xe4, 0xa4, 0xa6, 0xf6, 0xaa, + 0xc5, 0x7c, 0x5e, 0x94, 0x75, 0x95, 0xd4, 0x57, 0x59, 0x95, 0x25, 0xf3, + 0xb2, 0xa8, 0x8b, 0x61, 0x31, 0xa9, 0x0e, 0x92, 0xe4, 0xd9, 0xc9, 0xd1, + 0x45, 0x37, 0x79, 0x7e, 0xf2, 0xf2, 0xb8, 0x9b, 0x24, 0xcf, 0x2f, 0xce, + 0xba, 0xf8, 0xe3, 0x1c, 0x7e, 0xff, 0xf1, 0xf4, 0xec, 0xc5, 0xf1, 0x9b, + 0xae, 0xfc, 0x8b, 0x9f, 0xbc, 0xb8, 0x80, 0xaf, 0xa9, 0x3d, 0xfc, 0x0d, + 0x3e, 0x39, 0x79, 0x75, 0x08, 0xcf, 0xd3, 0x3f, 0xf0, 0xd7, 0xcb, 0x67, + 0xf4, 0x17, 0xfe, 0x03, 0x7f, 0xbd, 0xfa, 0xd3, 0x05, 0xb4, 0x9b, 0x9c, + 0x9d, 0x9e, 0xed, 0x77, 0xe9, 0x27, 0xb6, 0xf0, 0xe6, 0xe2, 0x15, 0x3c, + 0x82, 0x3f, 0xf9, 0xaf, 0x73, 0x69, 0xef, 0xfc, 0x08, 0x3e, 0x3e, 0xa7, + 0xde, 0xcf, 0x5f, 0xfd, 0x40, 0x3f, 0xce, 0xf1, 0x27, 0x7f, 0x40, 0x7d, + 0x5d, 0x1c, 0xbf, 0x7c, 0x7d, 0x0c, 0x2d, 0x5e, 0xd0, 0x53, 0x3f, 0x9d, + 0x27, 0xe9, 0x6c, 0x04, 0xff, 0x9c, 0xf7, 0xdd, 0x8a, 0xe1, 0x92, 0x25, + 0xf3, 0xe2, 0x26, 0x2b, 0xb3, 0x51, 0x92, 0x0c, 0x6e, 0x93, 0x64, 0x92, + 0x0f, 0xf8, 0x1b, 0x5c, 0xc1, 0x24, 0x9d, 0xc0, 0x6f, 0xba, 0x8e, 0xbd, + 0x32, 0x9b, 0xa4, 0x35, 0x3e, 0x38, 0xce, 0xd2, 0x7a, 0x51, 0x66, 0xb8, + 0x5e, 0xc9, 0x79, 0x96, 0x51, 0x7b, 0xf2, 0xe2, 0xe6, 0xfe, 0x16, 0xbd, + 0x3a, 0xca, 0xea, 0x34, 0x9f, 0x54, 0xd0, 0x19, 0xed, 0x2a, 0x3e, 0x71, + 0x71, 0x95, 0xe1, 0x2a, 0x27, 0xd5, 0xed, 0xac, 0x4e, 0x3f, 0x70, 0xd7, + 0xb2, 0xae, 0xbd, 0x51, 0x36, 0xcf, 0x66, 0xa3, 0x6c, 0x56, 0xf7, 0x93, + 0xbf, 0x16, 0x8b, 0x64, 0x9c, 0xc3, 0x58, 0x61, 0x8b, 0xb8, 0x15, 0xe8, + 0x72, 0x94, 0x55, 0xc3, 0x32, 0x27, 0x32, 0x80, 0x41, 0xcf, 0xa8, 0xbd, + 0x37, 0xcf, 0x8f, 0x92, 0xfd, 0x6f, 0x9e, 0x3c, 0x96, 0x09, 0x9d, 0x8c, + 0x93, 0x5b, 0x78, 0x15, 0x9a, 0xbc, 0xce, 0x47, 0x59, 0xc2, 0xf4, 0x94, + 0xdc, 0xe4, 0xf5, 0x55, 0xb1, 0xa8, 0xf1, 0xcf, 0x49, 0x96, 0x8e, 0x70, + 0xa7, 0xad, 0xd7, 0x83, 0xed, 0xed, 0xa4, 0x1a, 0x5e, 0x65, 0xd3, 0xac, + 0x2b, 0xcb, 0x71, 0xb9, 0xc8, 0xaa, 0x2a, 0xab, 0xa8, 0xbd, 0x9b, 0xab, + 0xb4, 0xb6, 0x47, 0xa9, 0xe9, 0x9b, 0x14, 0xc7, 0x77, 0x52, 0x23, 0x51, + 0xc0, 0x30, 0x46, 0xd9, 0x38, 0x5d, 0x4c, 0x90, 0x46, 0x0a, 0xda, 0xdf, + 0x64, 0x00, 0xfd, 0xa4, 0x55, 0xb5, 0x98, 0x66, 0x55, 0x52, 0xc0, 0x33, + 0x25, 0xcc, 0x70, 0x90, 0x56, 0xd9, 0x88, 0xda, 0x83, 0x91, 0x17, 0xe3, + 0x3a, 0x9b, 0xf5, 0x16, 0xf0, 0x49, 0x72, 0x55, 0x54, 0xf5, 0x2c, 0x9d, + 0x22, 0x69, 0x65, 0xe3, 0xfc, 0x03, 0xae, 0xe5, 0x73, 0x5c, 0xf1, 0xec, + 0x43, 0x3a, 0x9d, 0x4f, 0x60, 0x40, 0xb8, 0x88, 0xfa, 0x50, 0x95, 0x54, + 0x75, 0x5a, 0xd6, 0x34, 0x78, 0x9c, 0x10, 0xb5, 0xd7, 0x19, 0xd7, 0xf3, + 0x7e, 0x87, 0x07, 0xae, 0xbd, 0xea, 0x28, 0x91, 0x24, 0x65, 0x59, 0x70, + 0x39, 0x87, 0xe9, 0x2c, 0xa9, 0xe6, 0xd9, 0x30, 0x1f, 0xdf, 0x02, 0x15, + 0xc0, 0x2e, 0xa7, 0xd3, 0x62, 0x01, 0x4f, 0x15, 0x63, 0x22, 0x7b, 0x1c, + 0x1a, 0x0c, 0x17, 0x68, 0xa2, 0x98, 0x4e, 0x91, 0x4a, 0x26, 0xf9, 0x2c, + 0xeb, 0xe3, 0x7e, 0xc1, 0xe3, 0x65, 0x86, 0xfb, 0x5d, 0xc3, 0x32, 0xf1, + 0x34, 0xf2, 0x19, 0x2c, 0x65, 0x95, 0xfd, 0x7d, 0x01, 0x9b, 0x95, 0xa7, + 0x93, 0x04, 0x5e, 0x98, 0xc1, 0x21, 0xc2, 0xcf, 0xb1, 0x0d, 0xee, 0x26, + 0x47, 0x2a, 0x29, 0xca, 0x11, 0x9e, 0xae, 0xd9, 0x04, 0xd6, 0x94, 0x46, + 0x06, 0x13, 0x4f, 0x92, 0x5e, 0x6f, 0x9e, 0x96, 0x40, 0x57, 0xd9, 0xa4, + 0xdf, 0x3a, 0xbe, 0x68, 0x10, 0x89, 0x9e, 0x7c, 0xfc, 0x80, 0xc7, 0x3a, + 0x85, 0xc5, 0x1a, 0xf1, 0xdf, 0x38, 0x14, 0x98, 0x0d, 0xf7, 0x03, 0x93, + 0xa0, 0xf6, 0x70, 0x10, 0xd1, 0x3c, 0x1c, 0xb9, 0xa7, 0x75, 0x9d, 0x4d, + 0xe7, 0xbc, 0x63, 0x65, 0x86, 0xc3, 0x19, 0x16, 0x30, 0xfa, 0x21, 0xf7, + 0x01, 0x3b, 0x0e, 0xdb, 0x3a, 0x2a, 0x70, 0x99, 0xa7, 0xb0, 0xb1, 0x39, + 0xec, 0x83, 0x11, 0x7f, 0xd5, 0x4d, 0xaa, 0x02, 0x5b, 0x4f, 0x99, 0x41, + 0x5c, 0x66, 0x35, 0xed, 0xc7, 0x14, 0x47, 0x30, 0x06, 0x1a, 0xad, 0x98, + 0xb9, 0xf0, 0x22, 0xe0, 0xc6, 0x0a, 0x77, 0x19, 0xc1, 0x5b, 0xb3, 0xa2, + 0xa6, 0xc9, 0x5b, 0xab, 0xd2, 0x2d, 0xf4, 0x09, 0xc3, 0x64, 0x86, 0x93, + 0xd5, 0x8b, 0x79, 0x72, 0x05, 0x7f, 0x56, 0x57, 0xe9, 0x7b, 0x24, 0x87, + 0x8b, 0x2b, 0x38, 0x21, 0xf9, 0x14, 0xe9, 0x19, 0x1a, 0xc7, 0xf5, 0xc9, + 0x46, 0xfd, 0xe4, 0xc8, 0x06, 0x2c, 0x33, 0xa0, 0xc5, 0x2b, 0x66, 0x93, + 0xdb, 0x64, 0x00, 0x7f, 0x8c, 0x8a, 0x19, 0x1f, 0x47, 0x24, 0x1f, 0x5a, + 0x2f, 0xb7, 0x23, 0x7c, 0xa4, 0x13, 0x64, 0x77, 0x93, 0xc6, 0x6e, 0xe3, + 0x62, 0x5e, 0x17, 0xc3, 0x94, 0x0f, 0x18, 0x7e, 0x0a, 0xcd, 0xe2, 0xb0, + 0xa1, 0x55, 0x6a, 0x6f, 0x9e, 0x95, 0xf0, 0xfa, 0x14, 0x5a, 0x19, 0x64, + 0xf5, 0x4d, 0x06, 0x0b, 0x55, 0x65, 0xb8, 0x91, 0x75, 0xc6, 0x4b, 0x5b, + 0x2e, 0x66, 0x95, 0x2c, 0xf5, 0x99, 0x9c, 0x40, 0x18, 0xd7, 0xc9, 0xd9, + 0xf5, 0xe3, 0xe4, 0x1f, 0x05, 0xb5, 0x3f, 0x52, 0x12, 0xd1, 0x63, 0x89, + 0xfd, 0x24, 0x70, 0xae, 0xd3, 0x39, 0xb4, 0x0a, 0xed, 0x0f, 0x81, 0xa2, + 0xd2, 0x4b, 0x58, 0xb8, 0xfc, 0x72, 0x06, 0x9c, 0xe5, 0x65, 0xfe, 0x3e, + 0x13, 0x8a, 0xfb, 0xea, 0xab, 0x07, 0x9d, 0xab, 0xba, 0x9e, 0xc3, 0x81, + 0xfd, 0xdb, 0x38, 0x7b, 0xb2, 0x73, 0x70, 0xb0, 0xff, 0x1f, 0x7b, 0x8f, + 0xb2, 0xfa, 0x6a, 0xe7, 0x97, 0xed, 0x0e, 0x77, 0x7a, 0x0c, 0x6b, 0x7d, + 0x5b, 0x5f, 0xe1, 0x96, 0x08, 0x07, 0x18, 0x29, 0x59, 0xc7, 0xf3, 0xc4, + 0x1d, 0x44, 0xde, 0x83, 0x93, 0x4b, 0x1b, 0xdf, 0x31, 0xb5, 0xf1, 0x69, + 0x2d, 0x93, 0x1c, 0xf6, 0x27, 0x2d, 0x2f, 0xe1, 0x60, 0xcd, 0xea, 0x6e, + 0x7c, 0xce, 0xe8, 0xa6, 0xc1, 0x79, 0xe0, 0xbb, 0x75, 0x09, 0xec, 0x10, + 0x3e, 0xc3, 0xc3, 0x0f, 0x17, 0xc7, 0xf0, 0x0a, 0xd6, 0xe1, 0xc7, 0x97, + 0xa7, 0x3f, 0xfc, 0x70, 0xf2, 0xfa, 0xc7, 0xf6, 0x33, 0x18, 0x08, 0x81, + 0xb7, 0x08, 0x3a, 0x83, 0xb5, 0x44, 0x72, 0xd0, 0x13, 0x89, 0xac, 0xf8, + 0xa6, 0xcc, 0x89, 0xc4, 0x26, 0x79, 0x85, 0x5f, 0xe1, 0x92, 0x09, 0xe7, + 0x1b, 0x94, 0xe9, 0x10, 0x79, 0x4c, 0x99, 0x00, 0x75, 0x5e, 0xc2, 0x6f, + 0xfc, 0x1d, 0x7d, 0xfe, 0x3e, 0xab, 0x81, 0x78, 0x7e, 0x82, 0x69, 0x23, + 0xf3, 0xae, 0x91, 0x88, 0x3a, 0x97, 0x93, 0x62, 0x30, 0x80, 0xa6, 0x3a, + 0xcd, 0x1d, 0xa2, 0xb6, 0x79, 0x33, 0xea, 0xab, 0x32, 0xcb, 0x92, 0x51, + 0x3e, 0x06, 0x62, 0x87, 0x09, 0x27, 0xcc, 0x77, 0x26, 0xb0, 0x09, 0xd4, + 0xc8, 0x81, 0xdb, 0x83, 0x2a, 0xaf, 0xb3, 0xfe, 0x3f, 0x61, 0x57, 0xbb, + 0xf5, 0x4d, 0xd1, 0xa5, 0x17, 0xff, 0xd5, 0x87, 0x95, 0x94, 0xad, 0x78, + 0x56, 0x08, 0x7f, 0xa0, 0x31, 0x8e, 0xe1, 0x12, 0x99, 0x03, 0x5d, 0xc3, + 0xba, 0x95, 0xf9, 0x10, 0x4f, 0x45, 0x9e, 0xd1, 0xfc, 0xf8, 0xda, 0xfd, + 0xdb, 0x2f, 0xb8, 0x6a, 0xf9, 0x8c, 0xda, 0x1f, 0x53, 0xf3, 0xc8, 0xd7, + 0x84, 0x0d, 0x62, 0xab, 0xdb, 0x78, 0xba, 0xfe, 0xb6, 0xdb, 0xdb, 0xdd, + 0xd9, 0xf9, 0xa5, 0x5f, 0x7f, 0xa8, 0xa5, 0x97, 0x9f, 0x70, 0xd0, 0xca, + 0xd2, 0xff, 0x91, 0x95, 0x45, 0x56, 0xdd, 0xd7, 0xc6, 0xce, 0xce, 0xaa, + 0x56, 0x80, 0x2f, 0x94, 0x78, 0xd7, 0x97, 0xc5, 0xe2, 0xf2, 0x8a, 0x88, + 0x86, 0x06, 0x0d, 0xa4, 0x7e, 0x5f, 0x9b, 0x69, 0xef, 0x1f, 0xbe, 0xbd, + 0xd7, 0x59, 0x85, 0x37, 0x64, 0x98, 0x3f, 0xf2, 0x4f, 0x3a, 0x47, 0x22, + 0x51, 0x64, 0xa3, 0x2e, 0xdd, 0x13, 0xb7, 0x42, 0x12, 0xc4, 0x17, 0xaa, + 0x0c, 0xa8, 0x17, 0x78, 0x29, 0x2c, 0x29, 0x10, 0x66, 0xf6, 0x01, 0x1e, + 0xaf, 0x0b, 0x6a, 0x2f, 0x4b, 0x87, 0x57, 0x7c, 0x97, 0xf8, 0x0d, 0xf0, + 0xa3, 0x48, 0xcb, 0xe1, 0x55, 0x7e, 0x0d, 0x0b, 0xf4, 0xcd, 0x37, 0x8f, + 0x7b, 0xf0, 0xe3, 0x9b, 0x5f, 0xb6, 0xaf, 0x8b, 0x09, 0xac, 0xd7, 0xc3, + 0x5f, 0xb6, 0x91, 0xa8, 0xfe, 0x99, 0x76, 0x07, 0xdd, 0xe1, 0xbf, 0xfa, + 0x57, 0xf5, 0x74, 0xd2, 0x59, 0x71, 0x25, 0xc0, 0xf5, 0x92, 0xcd, 0x91, + 0x21, 0xc0, 0xa5, 0x00, 0x2c, 0x8b, 0x84, 0x27, 0x58, 0x03, 0x21, 0x2e, + 0xe4, 0x96, 0xc0, 0xee, 0x12, 0x1c, 0xe4, 0x6d, 0xf2, 0x1a, 0x16, 0x0c, + 0x36, 0x73, 0x40, 0x2c, 0xb7, 0xe4, 0xab, 0x9f, 0xd6, 0x6f, 0xd5, 0x00, + 0xc3, 0xf6, 0x1d, 0xec, 0xda, 0xda, 0xaf, 0x7e, 0x12, 0x16, 0xf4, 0x60, + 0x2f, 0xda, 0x22, 0xe4, 0xca, 0x46, 0x2c, 0x30, 0xb4, 0x7f, 0xfe, 0xcb, + 0xad, 0x2f, 0xf1, 0x6c, 0xe4, 0x5d, 0xef, 0x91, 0xc1, 0x21, 0x07, 0x6e, + 0x1e, 0x6a, 0x60, 0x07, 0xc0, 0xf3, 0xbb, 0xb8, 0xe2, 0xcc, 0xc9, 0xca, + 0x62, 0x90, 0x0e, 0x80, 0x5f, 0x5e, 0xa5, 0xd7, 0x19, 0xce, 0x6d, 0xbe, + 0xa0, 0x1b, 0x3d, 0x19, 0x2f, 0x50, 0xda, 0x51, 0xee, 0x94, 0xe3, 0x55, + 0xb0, 0x18, 0xc0, 0x19, 0xfd, 0xfb, 0xa2, 0xa8, 0x33, 0xba, 0x33, 0xd2, + 0xeb, 0x02, 0xd8, 0x18, 0x5d, 0x95, 0xd5, 0x55, 0x36, 0x99, 0x30, 0xa7, + 0xc5, 0x4e, 0x73, 0x5c, 0x38, 0x38, 0x39, 0x76, 0x45, 0x03, 0x3b, 0xe8, + 0x27, 0xcc, 0xc3, 0x81, 0x96, 0xe0, 0xea, 0xb8, 0x2c, 0x70, 0x29, 0x71, + 0x69, 0x69, 0x3b, 0x61, 0xb5, 0xaf, 0x80, 0x7d, 0x0e, 0x89, 0xf0, 0x98, + 0x85, 0xc8, 0x05, 0x4b, 0xbb, 0x92, 0x4e, 0xba, 0x7c, 0xf6, 0xf0, 0x05, + 0x59, 0xa3, 0x64, 0xe3, 0x7f, 0x6e, 0x74, 0x93, 0x8d, 0xff, 0x73, 0x83, + 0xb8, 0xce, 0xc6, 0x7f, 0x6e, 0xc8, 0x69, 0x3e, 0x87, 0xfe, 0x90, 0x4a, + 0xc6, 0xe3, 0x44, 0x0f, 0x3a, 0x0f, 0xa1, 0xd7, 0xc3, 0xbf, 0xe1, 0x73, + 0x78, 0xf0, 0xcf, 0x87, 0x6f, 0x4e, 0x0e, 0x7f, 0x78, 0x79, 0xec, 0xe5, + 0x6a, 0x13, 0x72, 0xa3, 0x05, 0xbb, 0x4e, 0xcb, 0x1c, 0xd6, 0x07, 0x47, + 0xbb, 0x99, 0x8e, 0x90, 0x8f, 0xc2, 0x52, 0x3c, 0xe9, 0xef, 0xf7, 0x77, + 0xb6, 0xfa, 0x20, 0xed, 0xd5, 0xfe, 0x01, 0x13, 0x46, 0x7a, 0x3d, 0xfd, + 0x94, 0x18, 0xc7, 0xb7, 0x70, 0xc1, 0xd5, 0xc8, 0x45, 0x60, 0xf4, 0x8d, + 0xaf, 0xbe, 0xc7, 0x5d, 0x4e, 0x36, 0x61, 0xdf, 0xe0, 0x64, 0x74, 0xf0, + 0x8f, 0x0e, 0x11, 0x23, 0xde, 0x5e, 0x55, 0x3d, 0x12, 0x0e, 0x97, 0x8f, + 0xf1, 0x46, 0x64, 0x39, 0x5d, 0xee, 0xab, 0x51, 0x5a, 0x5d, 0x25, 0x9b, + 0xbd, 0xad, 0x2d, 0x99, 0xf6, 0x9f, 0xb5, 0x55, 0xe9, 0xab, 0xd2, 0x66, + 0xb2, 0x0f, 0x73, 0x98, 0x0c, 0x8f, 0x9b, 0x39, 0x3a, 0x72, 0x57, 0xe8, + 0x9a, 0xd6, 0x9a, 0x29, 0xa9, 0xf3, 0xcf, 0x7f, 0xe2, 0x60, 0xfe, 0xf5, + 0xaf, 0x0e, 0xf6, 0x65, 0x82, 0x83, 0x3c, 0x4e, 0x82, 0x19, 0x32, 0x79, + 0x11, 0xce, 0x46, 0x72, 0x5f, 0x75, 0x7a, 0x3d, 0x6e, 0xbc, 0xd7, 0x91, + 0xfb, 0x19, 0x0f, 0x46, 0x25, 0xb7, 0x8c, 0x8c, 0x02, 0x36, 0xc2, 0xda, + 0xb3, 0x99, 0x77, 0xb0, 0xc9, 0x0e, 0x8c, 0x08, 0xf8, 0x1f, 0xf1, 0x00, + 0xbe, 0x8a, 0x07, 0x93, 0x74, 0xf6, 0x1e, 0x27, 0x4b, 0x34, 0x45, 0xdd, + 0x8e, 0x90, 0x4e, 0x90, 0x63, 0x64, 0x1f, 0x90, 0x37, 0xa7, 0x48, 0x3f, + 0xd4, 0x9e, 0xb6, 0x05, 0x12, 0x28, 0xb5, 0x92, 0xe0, 0x24, 0x60, 0xf8, + 0x70, 0x2a, 0x07, 0x70, 0x6f, 0x4f, 0x4d, 0x04, 0x83, 0x65, 0x64, 0x3a, + 0x04, 0x26, 0xcb, 0x13, 0xa0, 0xbf, 0xe0, 0x7e, 0xd2, 0x6b, 0x97, 0x2f, + 0x11, 0xb8, 0x2b, 0xaa, 0x09, 0x2c, 0xaa, 0x50, 0x5a, 0xe7, 0x67, 0x68, + 0xce, 0x09, 0x8d, 0xe9, 0x70, 0x88, 0x82, 0x1b, 0xd2, 0x05, 0x4f, 0x1a, + 0xb8, 0xd1, 0xec, 0x3a, 0x2f, 0x8b, 0x19, 0x5e, 0x88, 0x8e, 0x0a, 0xf0, + 0xae, 0x1a, 0xe7, 0x25, 0x0c, 0x16, 0xa4, 0x95, 0x82, 0xc5, 0x54, 0x18, + 0xc7, 0xb4, 0x4f, 0xed, 0x88, 0x74, 0x33, 0x01, 0xa1, 0x05, 0xb7, 0x33, + 0xcb, 0x99, 0xfa, 0x4b, 0x38, 0xc1, 0x79, 0x99, 0xf1, 0x80, 0xdb, 0xda, + 0x25, 0xb6, 0x33, 0xc8, 0x88, 0x0c, 0x70, 0xb5, 0x90, 0x61, 0xe2, 0x0e, + 0xeb, 0x19, 0x96, 0x0b, 0x4c, 0x84, 0x70, 0x78, 0x6d, 0xb2, 0x20, 0x29, + 0x06, 0x9e, 0x01, 0x8e, 0x9a, 0xd3, 0x1d, 0xcf, 0x97, 0xfc, 0x04, 0x0e, + 0xd7, 0xe8, 0x16, 0x1b, 0xea, 0x27, 0x67, 0x93, 0x14, 0x1e, 0xc1, 0x8d, + 0xd4, 0x7e, 0xa8, 0xbd, 0xff, 0x90, 0xed, 0x99, 0x9a, 0xd2, 0x17, 0xc6, + 0x81, 0xf7, 0x28, 0x50, 0x80, 0xec, 0x20, 0x31, 0x6f, 0xd8, 0x9a, 0x9a, + 0x2f, 0x5d, 0x12, 0x61, 0xca, 0x12, 0xa5, 0x85, 0xb1, 0x93, 0x0e, 0x5b, + 0x27, 0xa4, 0x42, 0x87, 0x1f, 0x4f, 0x72, 0x51, 0xac, 0x9c, 0x0c, 0xb6, + 0x98, 0x73, 0x7b, 0xf2, 0x2a, 0xbc, 0xd2, 0xa5, 0x0b, 0xc3, 0x8d, 0x9f, + 0xc7, 0xae, 0x07, 0xae, 0x83, 0x4b, 0xb5, 0xf4, 0xed, 0xf7, 0xfa, 0xad, + 0x6c, 0xef, 0xb1, 0x30, 0xdd, 0xe4, 0xc7, 0x8c, 0x59, 0xdf, 0xdb, 0xf3, + 0xe3, 0x37, 0xab, 0x46, 0x3d, 0x83, 0x7d, 0xa0, 0x5d, 0x02, 0xce, 0x08, + 0x6a, 0x09, 0xe8, 0x63, 0x38, 0x32, 0x7e, 0x23, 0x67, 0x55, 0x49, 0xc6, + 0x86, 0x37, 0x80, 0xeb, 0x7a, 0xe3, 0x3f, 0xf0, 0xa1, 0x0d, 0xfc, 0x4c, + 0x4e, 0x0d, 0x32, 0x9d, 0x6f, 0x13, 0x62, 0xfd, 0x55, 0xf3, 0x1a, 0x9b, + 0xe7, 0xdb, 0xff, 0xfc, 0x27, 0xbe, 0xf0, 0xaf, 0x7f, 0x6d, 0xc3, 0x51, + 0xbd, 0x2a, 0x46, 0x9e, 0xff, 0x73, 0x03, 0x48, 0x59, 0x46, 0x77, 0xaa, + 0xb3, 0x19, 0x17, 0x4b, 0x85, 0x56, 0xc6, 0xc0, 0xc9, 0x67, 0x22, 0xd3, + 0x93, 0xb4, 0x47, 0xf7, 0xec, 0x34, 0x15, 0x71, 0x32, 0xda, 0xdc, 0x70, + 0x6c, 0xa7, 0x45, 0xc9, 0x7f, 0x5e, 0x67, 0xb3, 0x1c, 0x57, 0x00, 0xa6, + 0x8d, 0x6b, 0x4d, 0x0a, 0x1f, 0x37, 0x01, 0xc7, 0x6a, 0x1a, 0xb4, 0x48, + 0x95, 0xdc, 0x41, 0x43, 0xc8, 0x27, 0xc4, 0x73, 0xaf, 0x40, 0x2e, 0x02, + 0xf6, 0x0d, 0xb2, 0x99, 0x9c, 0xb4, 0x0e, 0xbe, 0xd1, 0xe9, 0xd2, 0xd9, + 0xa3, 0x16, 0x40, 0x13, 0xd5, 0xdb, 0x26, 0xf0, 0x8b, 0x14, 0x87, 0x9e, + 0xfc, 0xd7, 0xf9, 0xe9, 0x6b, 0x6a, 0x8f, 0xae, 0x9b, 0x91, 0x1d, 0x62, + 0x6e, 0xe8, 0xd7, 0xaa, 0x98, 0x61, 0x43, 0x78, 0x3b, 0xc1, 0xc5, 0x57, + 0x8c, 0x32, 0xd1, 0x34, 0xfc, 0x53, 0x49, 0x07, 0x16, 0x84, 0x28, 0x80, + 0xd4, 0xce, 0xc7, 0x0f, 0x85, 0x16, 0xe9, 0xf1, 0x5c, 0xe4, 0xbc, 0xce, + 0xe0, 0xf1, 0x43, 0xe4, 0x5e, 0xc0, 0x59, 0xe7, 0x73, 0xb8, 0x05, 0xdd, + 0x5a, 0x21, 0xb3, 0xb5, 0x95, 0xa1, 0x15, 0xaf, 0xe0, 0x0b, 0xe8, 0x15, + 0xae, 0x01, 0x3a, 0xd1, 0x7c, 0x75, 0x14, 0x93, 0x22, 0x48, 0xff, 0x23, + 0x3a, 0xa7, 0x4c, 0x20, 0x65, 0x7e, 0x79, 0x85, 0x92, 0x0e, 0x12, 0x73, + 0x31, 0x96, 0x0f, 0x03, 0xdb, 0x0a, 0x1c, 0x5b, 0x27, 0x4f, 0xed, 0x5d, + 0x15, 0x13, 0x5a, 0xd0, 0x19, 0x5e, 0xbf, 0x83, 0x5b, 0xba, 0x6a, 0x71, + 0xd7, 0x54, 0x72, 0xe2, 0xf1, 0x8f, 0xf8, 0xa6, 0x37, 0xde, 0x3e, 0x4c, + 0xf1, 0x1c, 0xd0, 0xd1, 0x8b, 0x89, 0xfa, 0x80, 0x64, 0x95, 0x26, 0x47, + 0x86, 0x99, 0xd1, 0xbd, 0xa3, 0xa7, 0xf9, 0xff, 0x78, 0x71, 0xfa, 0xea, + 0x78, 0xbb, 0x5f, 0x65, 0xc3, 0x12, 0x9e, 0x26, 0x1a, 0x4f, 0xc3, 0x58, + 0x79, 0x9e, 0x72, 0xee, 0x81, 0x7f, 0xc2, 0x7a, 0xbd, 0x02, 0xf2, 0x41, + 0x5a, 0x23, 0x96, 0x95, 0xd6, 0x89, 0xef, 0x81, 0x58, 0x0d, 0x6e, 0xf5, + 0x54, 0x35, 0x53, 0xd1, 0x66, 0x7a, 0x32, 0x76, 0xb1, 0x27, 0x90, 0xd2, + 0x34, 0x23, 0x9e, 0x7e, 0x76, 0x7a, 0x7e, 0x41, 0x36, 0xa9, 0xc6, 0x99, + 0xf9, 0x0f, 0x1c, 0x97, 0x3b, 0x31, 0xf6, 0x05, 0x8c, 0xe2, 0xfb, 0x7f, + 0xfe, 0x13, 0xbf, 0x85, 0xf3, 0x21, 0xe3, 0x76, 0xcf, 0x91, 0x79, 0x0b, + 0xee, 0x03, 0x78, 0xec, 0x00, 0x47, 0x72, 0x00, 0x94, 0x00, 0x97, 0xdb, + 0x57, 0x0f, 0xda, 0xce, 0x1a, 0xaf, 0xd7, 0x51, 0xfb, 0xa5, 0x6f, 0xfc, + 0xbe, 0x22, 0xa2, 0x40, 0xd3, 0x50, 0x12, 0x8b, 0x01, 0xb0, 0xde, 0xa7, + 0x6f, 0x2f, 0xce, 0xde, 0x5e, 0x98, 0xdd, 0x05, 0xb7, 0xa9, 0x86, 0x6d, + 0x64, 0xd1, 0xe6, 0x26, 0xaf, 0xd4, 0xa0, 0x82, 0x2a, 0x0c, 0x49, 0x90, + 0x28, 0x4d, 0x66, 0xc3, 0x0c, 0x04, 0xd5, 0x11, 0x9b, 0xe2, 0x60, 0xc1, + 0xe1, 0xb6, 0x87, 0xf3, 0x40, 0xe7, 0x8b, 0x0e, 0xc7, 0x40, 0xd5, 0x3d, + 0x20, 0xea, 0xc5, 0x10, 0x49, 0x0b, 0x1e, 0xc2, 0xbf, 0xe0, 0xc4, 0x81, + 0x4a, 0x7d, 0x2d, 0x2b, 0x4f, 0xaf, 0xcb, 0x8e, 0x4d, 0x40, 0x65, 0x9d, + 0xd0, 0xce, 0x76, 0xe5, 0x62, 0xa7, 0xae, 0x7a, 0x3d, 0x3e, 0x68, 0xaa, + 0xc9, 0xf5, 0x7a, 0x65, 0x36, 0x85, 0x53, 0xd5, 0xa3, 0x1b, 0x56, 0x6c, + 0x0a, 0x7d, 0x1a, 0xba, 0x1a, 0x0e, 0x93, 0x4b, 0x18, 0xdb, 0x2c, 0x28, + 0x66, 0xac, 0x86, 0x21, 0xeb, 0x53, 0xfb, 0xe4, 0x2a, 0x03, 0x03, 0x1f, + 0xef, 0x2a, 0x9f, 0xe6, 0x93, 0xb4, 0x84, 0x03, 0x35, 0x03, 0x3d, 0xbd, + 0x72, 0x2a, 0x9e, 0x9a, 0x30, 0x48, 0x94, 0x63, 0xb1, 0x07, 0x4f, 0x0c, + 0x4e, 0x48, 0xdb, 0x9b, 0x7a, 0x23, 0x05, 0x09, 0x00, 0xac, 0x33, 0xc0, + 0x11, 0x03, 0x22, 0xc7, 0xf3, 0x6c, 0x0b, 0x0b, 0x67, 0x1c, 0xe8, 0x1f, + 0x2e, 0x5b, 0xe8, 0xbe, 0x93, 0xa8, 0xd9, 0x46, 0xc8, 0xb0, 0x16, 0x79, + 0x44, 0x05, 0x73, 0x59, 0x7e, 0xa0, 0x37, 0x5e, 0x0f, 0x5a, 0x6b, 0x11, + 0x30, 0xf8, 0x5c, 0xe1, 0x92, 0x91, 0xb5, 0x8e, 0x7f, 0xef, 0xaa, 0xb9, + 0x06, 0x49, 0x60, 0x92, 0x0f, 0xf3, 0x1a, 0x26, 0x94, 0x56, 0xef, 0x85, + 0x84, 0x61, 0xdc, 0xc4, 0x43, 0x80, 0x1a, 0xf2, 0x21, 0x1d, 0xfe, 0x36, + 0x63, 0x0d, 0x4c, 0xe6, 0xec, 0xcd, 0xe9, 0xc5, 0xe9, 0xd1, 0xe9, 0xcb, + 0x56, 0x69, 0x33, 0x21, 0x5d, 0xb0, 0x58, 0x38, 0xfb, 0x5f, 0xc5, 0x02, + 0x11, 0xf2, 0x46, 0x24, 0x33, 0xe4, 0x72, 0x09, 0x48, 0x6b, 0x53, 0xb4, + 0xb7, 0xb2, 0x85, 0xae, 0x62, 0x69, 0x82, 0xe7, 0x85, 0x7a, 0x4d, 0x3e, + 0x5c, 0xc0, 0x7a, 0xc3, 0x75, 0x9c, 0x03, 0xdd, 0x4d, 0xd3, 0x5b, 0xbe, + 0x84, 0xb8, 0x0f, 0x5a, 0x53, 0x34, 0x5e, 0xca, 0xba, 0xa2, 0xc9, 0x16, + 0xce, 0xd9, 0x4b, 0x5c, 0x1b, 0x94, 0x23, 0x26, 0x45, 0xf1, 0x7e, 0x31, + 0x4f, 0x6e, 0x8a, 0x72, 0xa4, 0x02, 0x61, 0x31, 0xa3, 0x29, 0xc0, 0xbc, + 0x70, 0x0e, 0x29, 0x2a, 0xa9, 0xf2, 0x32, 0x5a, 0x7a, 0xe1, 0xe5, 0x37, + 0x48, 0x85, 0xb8, 0x83, 0xb8, 0xa6, 0x8e, 0xf0, 0x60, 0x60, 0x61, 0xdb, + 0xfc, 0x18, 0x58, 0x7e, 0x22, 0x9a, 0xc4, 0xe7, 0xd0, 0xd8, 0x88, 0xa6, + 0xd0, 0x07, 0x4c, 0x8a, 0x93, 0x5b, 0xd6, 0x03, 0x89, 0x2b, 0x94, 0x8b, + 0xd9, 0x8c, 0x1e, 0x04, 0xc6, 0xfa, 0x2a, 0x1f, 0x96, 0x45, 0x55, 0x8c, + 0x6b, 0xd0, 0x4d, 0x67, 0xa3, 0xe2, 0xa6, 0x4a, 0x64, 0x84, 0xb8, 0xd5, + 0x33, 0x10, 0xf4, 0xae, 0x91, 0x38, 0x5f, 0x1f, 0x7d, 0xf5, 0x00, 0xf8, + 0x77, 0x59, 0xa0, 0x7e, 0x08, 0xf3, 0x78, 0x6f, 0xa3, 0xbd, 0x38, 0xdb, + 0x3c, 0xdf, 0x82, 0xf1, 0x36, 0xd6, 0x1c, 0xdf, 0x7e, 0x4e, 0x1c, 0xf0, + 0x42, 0x09, 0xfa, 0x4c, 0x6d, 0x9b, 0x22, 0xc9, 0x80, 0x22, 0x57, 0xf0, + 0xfd, 0x59, 0xdf, 0x64, 0xe9, 0x7b, 0x31, 0x4e, 0x3d, 0x98, 0xa0, 0xde, + 0x87, 0x26, 0x05, 0x7c, 0x08, 0x17, 0x40, 0x2c, 0xaa, 0x3c, 0xaa, 0x8b, + 0x97, 0x6a, 0x50, 0x66, 0xb3, 0x37, 0x77, 0xfe, 0x26, 0x03, 0x26, 0x04, + 0xef, 0xc9, 0x0a, 0x7d, 0x65, 0x36, 0xf0, 0xb6, 0xb1, 0x91, 0xed, 0x94, + 0x86, 0x10, 0x08, 0xc3, 0xdb, 0xfd, 0x88, 0x37, 0xc9, 0x91, 0x55, 0x5e, + 0x01, 0x4a, 0x52, 0xfa, 0xfe, 0xab, 0x07, 0xf4, 0x2a, 0x0e, 0x0f, 0xa5, + 0xf6, 0x9d, 0xfe, 0x37, 0xdd, 0x64, 0xb7, 0xbf, 0x83, 0x3f, 0x76, 0xbb, + 0xc9, 0x1e, 0xbd, 0xbc, 0x9f, 0xb0, 0x69, 0x99, 0xf7, 0x58, 0xc8, 0xc5, + 0x8e, 0x24, 0x99, 0x6f, 0xae, 0x32, 0x18, 0x51, 0x51, 0x96, 0x28, 0xa1, + 0xae, 0xa0, 0x67, 0xe2, 0x73, 0xaf, 0x0e, 0x65, 0xf8, 0x6f, 0x6d, 0x3f, + 0x80, 0xf0, 0x40, 0x1c, 0x2a, 0x9b, 0x86, 0x65, 0x15, 0x4d, 0x70, 0xa8, + 0xb0, 0x85, 0xb3, 0x49, 0x91, 0xa2, 0xf4, 0x8c, 0x0f, 0x57, 0x6c, 0x85, + 0x03, 0x2a, 0xec, 0x7f, 0xf5, 0xe0, 0xbe, 0x25, 0x45, 0xcf, 0x80, 0x5b, + 0x31, 0x6e, 0x0e, 0x68, 0x14, 0x87, 0x5a, 0x80, 0x2e, 0xce, 0x74, 0xcc, + 0x4d, 0x42, 0x8b, 0x5d, 0x5e, 0x45, 0xd7, 0x60, 0x68, 0x0a, 0xbd, 0x0b, + 0x4b, 0x2b, 0x8f, 0x1f, 0x26, 0xb6, 0x7e, 0xfb, 0xfd, 0xe4, 0x99, 0x0c, + 0x96, 0x89, 0x11, 0xcd, 0x97, 0xf4, 0x08, 0xc8, 0xea, 0xa0, 0xc3, 0xe2, + 0xf5, 0x37, 0x40, 0x33, 0x3c, 0x30, 0xea, 0x07, 0x7c, 0x61, 0xd6, 0xc5, + 0x3c, 0x1f, 0xa2, 0xe0, 0x83, 0x84, 0xb5, 0x98, 0xcb, 0xab, 0xdb, 0xf3, + 0xa2, 0x22, 0x2d, 0x40, 0xdf, 0x9b, 0x83, 0x1e, 0x9d, 0x83, 0xf6, 0x46, + 0xb6, 0x45, 0x7e, 0xa9, 0x2f, 0x43, 0x7a, 0x40, 0xbd, 0xc0, 0x38, 0x4d, + 0xc6, 0x55, 0x3b, 0x49, 0xb2, 0x79, 0x9b, 0xd5, 0xaa, 0xec, 0xa1, 0x3f, + 0x84, 0x57, 0xc2, 0x0f, 0x51, 0xf4, 0xfd, 0x79, 0x31, 0xdf, 0x37, 0x6f, + 0xce, 0x34, 0x03, 0xf2, 0x36, 0xf3, 0x2c, 0x7c, 0x8b, 0xab, 0x1e, 0xa8, + 0x57, 0x97, 0xe6, 0xab, 0x07, 0xcd, 0xc5, 0x46, 0x27, 0x0b, 0x77, 0x81, + 0x8e, 0x0a, 0x38, 0xee, 0xc0, 0xbf, 0xe1, 0xb6, 0x78, 0x05, 0x87, 0x38, + 0xbd, 0xa4, 0xb6, 0xec, 0xc0, 0x90, 0x66, 0x98, 0x4f, 0x81, 0x2e, 0x81, + 0x3d, 0x26, 0x64, 0xcf, 0xc7, 0xfb, 0x0c, 0x07, 0x40, 0xda, 0x57, 0x96, + 0x4e, 0xe1, 0x85, 0xaf, 0x1e, 0x80, 0x3c, 0x90, 0xa7, 0x6c, 0x4d, 0x0d, + 0xfb, 0x27, 0xe4, 0x90, 0xd7, 0xd6, 0xef, 0xf9, 0xd9, 0xd2, 0xce, 0xe0, + 0x87, 0x48, 0xcb, 0xf6, 0xbc, 0x52, 0xe1, 0xf9, 0xd1, 0xf2, 0xc3, 0xe7, + 0xe7, 0x2f, 0x6c, 0x13, 0xf7, 0x80, 0x5f, 0xce, 0x83, 0xd5, 0x5a, 0xdf, + 0x02, 0xb6, 0xb0, 0xfc, 0x1a, 0x7c, 0x98, 0x6c, 0x8e, 0xca, 0x14, 0x78, + 0xcd, 0xa3, 0x2d, 0x32, 0x1d, 0xf3, 0x9e, 0x47, 0xed, 0x69, 0x0b, 0xaf, + 0x7e, 0x68, 0x3b, 0xbb, 0xf0, 0xb1, 0x3d, 0xba, 0x4b, 0x74, 0xc8, 0x54, + 0x40, 0x93, 0xd6, 0xb1, 0x5b, 0x13, 0x7a, 0xfe, 0xdf, 0x2a, 0xa5, 0x04, + 0x19, 0x0d, 0xe9, 0x69, 0xc6, 0xcf, 0xc4, 0x3b, 0x89, 0x22, 0x13, 0x3d, + 0x8a, 0x9a, 0x96, 0xdb, 0x4b, 0xbc, 0xe3, 0x1e, 0x2c, 0xd3, 0x39, 0x7b, + 0xbd, 0xa0, 0x8f, 0xe7, 0xe8, 0xb3, 0xa0, 0xf7, 0xf0, 0x2a, 0x99, 0xcc, + 0x40, 0xcc, 0xa3, 0x6b, 0x85, 0x3c, 0x29, 0x15, 0x75, 0x46, 0x46, 0x9b, + 0x74, 0x48, 0x2c, 0xb5, 0x42, 0x5e, 0x8d, 0xf4, 0xc9, 0x37, 0x34, 0x5e, + 0xa5, 0xd8, 0x71, 0x05, 0x7d, 0x90, 0xc1, 0xb8, 0xa6, 0x53, 0x4e, 0xae, + 0x12, 0xb2, 0x52, 0xd0, 0x04, 0xf9, 0x56, 0xad, 0xd8, 0x55, 0x44, 0xe2, + 0x38, 0x8f, 0x9c, 0xde, 0x0c, 0x3b, 0x7c, 0xe1, 0x56, 0x5f, 0xce, 0x30, + 0x7e, 0x14, 0xf6, 0x96, 0x1a, 0xe3, 0x85, 0xd3, 0x1d, 0xfb, 0xe9, 0x9c, + 0x97, 0xea, 0xa7, 0x6c, 0x70, 0x5e, 0xa0, 0x51, 0xd7, 0xed, 0x0f, 0x72, + 0xbd, 0xed, 0xdd, 0x3e, 0x3a, 0xf3, 0x50, 0x65, 0x9d, 0xe4, 0x2a, 0x32, + 0xa3, 0x8c, 0x8f, 0x77, 0x41, 0x78, 0xec, 0x9c, 0x2f, 0xe3, 0x1f, 0xdf, + 0x1c, 0xc3, 0xb3, 0xaf, 0x8e, 0x2f, 0x8e, 0xdf, 0xb8, 0x1b, 0x79, 0x56, + 0x94, 0x53, 0xb8, 0x24, 0x6f, 0x81, 0xa3, 0x54, 0xf3, 0x49, 0x7a, 0x8b, + 0x7a, 0x08, 0xb0, 0xb0, 0xcb, 0x92, 0x24, 0x00, 0xb2, 0x97, 0x24, 0xa3, + 0x05, 0x29, 0x18, 0x05, 0x48, 0xb4, 0xcc, 0x83, 0xbb, 0xb0, 0x6c, 0x74, + 0xfb, 0xab, 0xb4, 0x45, 0xed, 0x05, 0x87, 0x92, 0x79, 0x5d, 0x45, 0xd2, + 0xeb, 0x3a, 0x09, 0x8a, 0x7c, 0x18, 0x22, 0x62, 0x02, 0x87, 0x98, 0x92, + 0x08, 0x41, 0xa7, 0x6c, 0x92, 0x8d, 0x41, 0xb5, 0x4d, 0x60, 0xcf, 0xfa, + 0xe6, 0x2b, 0x5c, 0x1a, 0x8a, 0x8e, 0x92, 0x38, 0xaf, 0xb5, 0x4a, 0x3e, + 0x08, 0x94, 0x1a, 0x58, 0x77, 0x40, 0xd9, 0x1b, 0x36, 0x00, 0x08, 0x6b, + 0x44, 0x06, 0xb8, 0x4c, 0xfc, 0xb9, 0x63, 0xf2, 0xb2, 0x25, 0x9b, 0xef, + 0xbb, 0xc9, 0xab, 0x6e, 0xf2, 0x63, 0x37, 0xb9, 0xe8, 0x26, 0x67, 0x5b, + 0xec, 0xdf, 0xda, 0xdd, 0xd9, 0x7b, 0xc8, 0x9e, 0x3a, 0xf6, 0xc2, 0xa9, + 0xc1, 0x6d, 0xf7, 0x3d, 0x1e, 0x75, 0xfe, 0x16, 0x1b, 0x87, 0x06, 0x77, + 0x5f, 0xa9, 0x42, 0xbe, 0xbb, 0xf3, 0xf0, 0xc9, 0xa3, 0xaf, 0x1f, 0xcb, + 0x37, 0x5e, 0x80, 0x0b, 0xe3, 0x84, 0xc7, 0x54, 0xda, 0xe5, 0x41, 0x83, + 0x4c, 0x93, 0xcf, 0x52, 0xd4, 0x73, 0x54, 0xd9, 0x27, 0xbf, 0x52, 0xce, + 0xbe, 0x4b, 0xb6, 0x63, 0x72, 0x33, 0x2a, 0x70, 0xa1, 0xff, 0x08, 0x3d, + 0x3c, 0xba, 0x01, 0x7c, 0x69, 0x21, 0x7d, 0xa2, 0x13, 0x62, 0x40, 0xbe, + 0x4d, 0x94, 0xcb, 0x48, 0x2c, 0xb1, 0xde, 0xa8, 0x3b, 0xed, 0xad, 0x6b, + 0x76, 0x04, 0x18, 0x1a, 0x4b, 0xf9, 0x34, 0x9a, 0xe6, 0x02, 0xa3, 0xad, + 0x29, 0x08, 0x9a, 0x64, 0x2f, 0x2a, 0x16, 0x70, 0x5d, 0xc2, 0xd7, 0xf0, + 0x10, 0x08, 0x4c, 0xfc, 0x9a, 0x93, 0xad, 0xa7, 0x6c, 0x5b, 0xb2, 0x86, + 0xa4, 0x1d, 0x18, 0x20, 0xfc, 0x39, 0x07, 0x6a, 0xc9, 0x68, 0x44, 0xb1, + 0x87, 0x96, 0x1c, 0x94, 0x69, 0xd2, 0x7c, 0x8b, 0xee, 0x45, 0xba, 0xd0, + 0x49, 0x39, 0x82, 0xbf, 0x40, 0xc5, 0x60, 0x43, 0x11, 0x10, 0x4b, 0x45, + 0x06, 0x5c, 0x12, 0xae, 0xcd, 0x38, 0x0e, 0x24, 0x46, 0x57, 0xa1, 0xa8, + 0x17, 0xd2, 0xa1, 0xea, 0xd8, 0x85, 0xe8, 0x7c, 0xaa, 0x19, 0x90, 0xc5, + 0x36, 0xbc, 0x93, 0x6c, 0x7e, 0xb7, 0xd5, 0x5d, 0xd2, 0x14, 0x44, 0x8c, + 0xd7, 0x83, 0x4b, 0x1b, 0xa8, 0x82, 0x1d, 0xeb, 0xcb, 0xd0, 0x2e, 0x9e, + 0x5d, 0x61, 0x73, 0xb8, 0x66, 0x74, 0xf4, 0xc2, 0xfe, 0x04, 0x41, 0x70, + 0x0e, 0x4b, 0xc8, 0xbe, 0xe7, 0xd9, 0xad, 0x0c, 0xd8, 0x2d, 0x8a, 0x12, + 0x85, 0xee, 0x52, 0xd3, 0x8d, 0x9d, 0x71, 0x50, 0x44, 0xd8, 0xa4, 0x01, + 0x88, 0xbb, 0xaa, 0x0e, 0x15, 0x63, 0x99, 0xf4, 0x25, 0x49, 0xc1, 0xb4, + 0x82, 0x5d, 0x72, 0xae, 0xca, 0xe3, 0x3d, 0x78, 0x5a, 0x29, 0x15, 0xda, + 0x83, 0xe5, 0x05, 0x81, 0x8c, 0x8e, 0x84, 0x5a, 0xff, 0xc9, 0x2a, 0xad, + 0x14, 0xd1, 0x20, 0x08, 0xde, 0x11, 0x10, 0x86, 0xe0, 0x14, 0xa0, 0xac, + 0xea, 0x2c, 0xbd, 0xac, 0x5f, 0x55, 0xb0, 0xb0, 0x78, 0xde, 0x49, 0x42, + 0x42, 0xf3, 0xf2, 0xf1, 0x9b, 0x73, 0x0b, 0xc6, 0xa0, 0x65, 0x03, 0x31, + 0x0a, 0xe4, 0xf4, 0xcb, 0x4c, 0x5c, 0xf7, 0x03, 0x3c, 0x9a, 0x74, 0x3c, + 0x9e, 0xf4, 0x77, 0x77, 0x40, 0x89, 0xd4, 0x89, 0x92, 0x3d, 0x0b, 0x34, + 0xb9, 0x14, 0x7b, 0x94, 0xab, 0xa4, 0x4b, 0xd6, 0x71, 0xb4, 0xef, 0x33, + 0x73, 0x29, 0xd9, 0x07, 0x95, 0x84, 0x46, 0x9d, 0x96, 0x84, 0x66, 0xfb, + 0x5b, 0xfc, 0x60, 0x48, 0x9e, 0xba, 0x84, 0x2c, 0xef, 0xd0, 0x78, 0x70, + 0x39, 0x23, 0xaf, 0xcf, 0x40, 0x37, 0xcb, 0x33, 0x5e, 0x12, 0xeb, 0x85, + 0x0f, 0xa8, 0xbd, 0x58, 0x93, 0x6b, 0x0a, 0x4f, 0x4f, 0x3e, 0x1b, 0x4e, + 0x16, 0xa3, 0xcc, 0xae, 0x36, 0xf8, 0x00, 0xbd, 0x9f, 0xbc, 0xc1, 0x72, + 0xe8, 0x40, 0xea, 0x19, 0x5e, 0x05, 0x8b, 0xfd, 0x18, 0x04, 0x21, 0x7d, + 0x9c, 0x99, 0xf1, 0xac, 0x2e, 0x8b, 0xd1, 0x62, 0x88, 0x5a, 0xd2, 0x15, + 0x79, 0x52, 0x1a, 0x1e, 0xf9, 0x74, 0x72, 0x83, 0x5c, 0x62, 0x02, 0x43, + 0x9b, 0x71, 0x6b, 0xb4, 0xb8, 0xb8, 0x12, 0x55, 0xcd, 0x6b, 0xa5, 0x0d, + 0xe6, 0x64, 0x65, 0x15, 0x35, 0x41, 0xaf, 0x12, 0x55, 0xed, 0xf1, 0x8f, + 0x7e, 0x95, 0x6d, 0xe3, 0x18, 0x43, 0xa4, 0x85, 0x6a, 0x34, 0x61, 0x0e, + 0x6c, 0x92, 0xd1, 0x65, 0x94, 0x75, 0x64, 0xff, 0x04, 0x0d, 0x04, 0x4e, + 0x48, 0x71, 0x63, 0x3a, 0xb4, 0x8c, 0x43, 0x54, 0xf2, 0x21, 0x8c, 0x91, + 0x66, 0x7f, 0xb0, 0xd4, 0x2d, 0xac, 0x5f, 0xb5, 0x0d, 0x2d, 0x62, 0x7b, + 0xe4, 0x65, 0xfa, 0xea, 0xab, 0x53, 0x8a, 0xcc, 0x11, 0xe5, 0xef, 0x54, + 0x84, 0x6d, 0xba, 0x78, 0x45, 0xd7, 0x20, 0x8f, 0x30, 0x9e, 0xf7, 0xfa, + 0xa6, 0x20, 0xc3, 0x3e, 0xf1, 0xd6, 0x57, 0xe4, 0xcd, 0x1f, 0x7b, 0x53, + 0x7c, 0x15, 0x2c, 0xc5, 0x89, 0xd8, 0x7e, 0xd3, 0xd1, 0x28, 0x27, 0x1d, + 0x6d, 0xa2, 0x46, 0x5f, 0xf2, 0x98, 0x09, 0xd3, 0x9b, 0xf2, 0xde, 0x9b, + 0x0f, 0xb8, 0x26, 0x6f, 0x9a, 0x9d, 0x49, 0x19, 0x85, 0xb7, 0x83, 0x8f, + 0xc8, 0x04, 0xce, 0x06, 0x63, 0x38, 0x75, 0xe8, 0xe0, 0x1d, 0x89, 0xed, + 0xd9, 0xbc, 0xbb, 0x68, 0xd7, 0x11, 0x97, 0x6f, 0x3f, 0x2c, 0x31, 0xac, + 0x17, 0xb4, 0xd5, 0x61, 0xff, 0x44, 0x0f, 0xdb, 0xe9, 0x20, 0x17, 0x9b, + 0x26, 0x7a, 0x3c, 0x65, 0x0e, 0xc0, 0x66, 0x46, 0x89, 0xf7, 0xe4, 0x74, + 0x49, 0x61, 0x45, 0x8f, 0xc7, 0x42, 0xa3, 0x43, 0x9a, 0x92, 0x3b, 0x86, + 0x27, 0x91, 0x25, 0x51, 0xdd, 0xed, 0x79, 0xad, 0x9c, 0xbf, 0xe2, 0x79, + 0x77, 0x61, 0xdf, 0xf0, 0xd9, 0xcb, 0x2b, 0x72, 0xea, 0xd3, 0xc3, 0xb9, + 0x79, 0x0b, 0x80, 0xc7, 0x81, 0x2a, 0x93, 0x91, 0xad, 0x4c, 0x6c, 0x75, + 0x45, 0xd9, 0x17, 0xd2, 0x98, 0x14, 0xb8, 0xcb, 0xec, 0xde, 0xa2, 0x71, + 0xd3, 0xb0, 0x89, 0x7f, 0x48, 0x9c, 0x94, 0x0f, 0x45, 0x91, 0xf6, 0x68, + 0x17, 0x2a, 0xeb, 0xca, 0x8d, 0x2b, 0x1a, 0x96, 0x0a, 0x7b, 0xb4, 0x36, + 0x4a, 0x7b, 0xba, 0x99, 0x6c, 0x3a, 0x83, 0x2b, 0x0d, 0xf7, 0x82, 0x78, + 0x39, 0x87, 0xa3, 0x34, 0xb6, 0xd4, 0x5c, 0x39, 0x61, 0x7d, 0xc8, 0xb8, + 0x06, 0x6a, 0x60, 0x46, 0x16, 0x16, 0xde, 0x6f, 0x72, 0x8e, 0xf2, 0x8d, + 0xd5, 0xe2, 0x2d, 0x33, 0x17, 0xab, 0xb9, 0x39, 0x29, 0x98, 0x49, 0x04, + 0x02, 0x1d, 0x51, 0xef, 0x14, 0x76, 0x87, 0xfd, 0xf8, 0xbd, 0xeb, 0x04, + 0x19, 0x39, 0xb0, 0x1d, 0xdc, 0xec, 0xde, 0xe9, 0xcb, 0x6b, 0x65, 0xc9, + 0x33, 0xd0, 0x27, 0x66, 0xe8, 0xa1, 0xed, 0x72, 0x23, 0x83, 0xa2, 0x80, + 0x53, 0x1b, 0xa6, 0x45, 0x42, 0x44, 0x36, 0x43, 0x46, 0xaa, 0xae, 0x22, + 0xb8, 0x58, 0xd8, 0x97, 0x84, 0x2d, 0xdf, 0xa2, 0x5d, 0x3a, 0xbd, 0x4c, + 0xc5, 0xb9, 0x25, 0x3c, 0x37, 0x3c, 0x3a, 0x2b, 0xe4, 0x69, 0xda, 0x20, + 0x8a, 0x4f, 0xe8, 0x3a, 0xfe, 0xc5, 0x4e, 0x9d, 0x60, 0xba, 0x12, 0x4f, + 0x11, 0xda, 0x0f, 0xc4, 0x1b, 0x82, 0x4e, 0x9e, 0x60, 0xe1, 0x85, 0xe6, + 0x3a, 0xd0, 0xd2, 0x8b, 0xe2, 0x06, 0x55, 0xf7, 0x2e, 0xfb, 0x85, 0xf2, + 0x4a, 0x9c, 0xfd, 0xa8, 0xb5, 0x82, 0x7e, 0x06, 0xeb, 0x48, 0x51, 0x23, + 0xf4, 0x21, 0x19, 0x2d, 0xf1, 0xf8, 0x3b, 0x16, 0x2f, 0x7d, 0xd9, 0x16, + 0x8e, 0xbd, 0xa5, 0x8a, 0x8c, 0xf2, 0x30, 0x70, 0xdc, 0x89, 0xbc, 0xa2, + 0x6d, 0xea, 0xb2, 0x90, 0x5c, 0xa9, 0x43, 0x8c, 0x8c, 0x57, 0x25, 0x1e, + 0xb8, 0x9a, 0x4f, 0x12, 0xce, 0x87, 0x8f, 0x1f, 0x2d, 0x85, 0x9a, 0x1d, + 0x58, 0x70, 0x72, 0xeb, 0xc9, 0xaf, 0x74, 0x61, 0x23, 0x87, 0xd9, 0xbc, + 0x36, 0x6f, 0x74, 0x44, 0x43, 0xb8, 0xe2, 0xe8, 0xdc, 0x84, 0x6b, 0x33, + 0x49, 0x7e, 0xa4, 0x5f, 0xf4, 0x01, 0x21, 0xd7, 0x3a, 0x65, 0x77, 0x58, + 0x5e, 0x2a, 0x4d, 0xe1, 0x18, 0x50, 0xa7, 0x20, 0xcd, 0x14, 0x8d, 0x7d, + 0xa0, 0xf8, 0x64, 0xa5, 0xcc, 0xc2, 0x1d, 0x6b, 0x24, 0xff, 0xc9, 0x44, + 0x58, 0x61, 0xa0, 0x14, 0xb9, 0x88, 0x30, 0xf6, 0x87, 0xfa, 0x3b, 0x60, + 0xbf, 0x27, 0x3a, 0x44, 0x7a, 0x78, 0xbb, 0xdc, 0x76, 0xf9, 0x03, 0x09, + 0x84, 0xeb, 0x8a, 0x5f, 0x54, 0xa3, 0x9d, 0x7a, 0x46, 0xc1, 0x5d, 0xff, + 0xe9, 0x34, 0xfd, 0xd0, 0xf5, 0x8f, 0x75, 0x1b, 0x77, 0x38, 0x7d, 0x89, + 0x22, 0xae, 0xb6, 0x87, 0xbb, 0xd4, 0x23, 0xbb, 0x37, 0x7d, 0x05, 0xca, + 0x08, 0xfc, 0x21, 0xbf, 0xde, 0x02, 0x51, 0x89, 0x40, 0x43, 0x9f, 0xd4, + 0x18, 0x27, 0xd2, 0x4b, 0xab, 0x61, 0x9e, 0xbb, 0xbf, 0x41, 0x34, 0x1e, + 0xe7, 0x97, 0xda, 0x1e, 0x7f, 0x96, 0x8f, 0x90, 0x4b, 0xc9, 0x1f, 0x28, + 0x91, 0xdb, 0x5f, 0x7c, 0x34, 0x7a, 0xe8, 0x65, 0x2c, 0x2a, 0x3c, 0xdd, + 0x87, 0x2f, 0x5f, 0x26, 0x11, 0x83, 0xef, 0xf5, 0xd2, 0x41, 0x85, 0xcf, + 0xd6, 0xbd, 0xc5, 0x2c, 0xff, 0xd0, 0xab, 0x58, 0x5f, 0x79, 0x3a, 0x4f, + 0xeb, 0xab, 0xef, 0xbe, 0x7a, 0x80, 0x8f, 0x6c, 0xa2, 0x5c, 0xb7, 0xa5, + 0xc1, 0x4b, 0x16, 0x68, 0x81, 0x97, 0xa0, 0xbc, 0x9a, 0x24, 0x6f, 0xe1, + 0x5d, 0x60, 0x0d, 0x53, 0xdc, 0x37, 0x6e, 0xa2, 0x6b, 0xe2, 0x0e, 0xfa, + 0x54, 0xa9, 0xa1, 0x60, 0x0a, 0x03, 0x2e, 0x50, 0xa3, 0xb2, 0xd3, 0x4f, + 0x5e, 0x17, 0x75, 0x76, 0x40, 0x7f, 0x23, 0xe1, 0x10, 0x19, 0x8b, 0xc1, + 0x0b, 0x47, 0xc0, 0xd6, 0x7f, 0x14, 0x9b, 0xa5, 0x27, 0x6e, 0x48, 0x06, + 0xd9, 0x74, 0xf0, 0x7e, 0xdf, 0xe9, 0x26, 0x57, 0x7c, 0x6e, 0xb8, 0x17, + 0x9e, 0x85, 0xc5, 0x01, 0x61, 0xeb, 0x24, 0x12, 0x03, 0x03, 0xe3, 0x86, + 0x38, 0x8a, 0x80, 0x8e, 0x97, 0x98, 0x81, 0xcc, 0xb1, 0x4f, 0x57, 0xd1, + 0x8a, 0xd5, 0x91, 0xe8, 0x47, 0xba, 0xa4, 0x64, 0x44, 0x12, 0x04, 0x82, + 0xab, 0x5f, 0x75, 0x45, 0x14, 0xa8, 0xc8, 0xb1, 0xa6, 0x0e, 0x41, 0x3e, + 0x68, 0xb0, 0x07, 0x0f, 0xbc, 0xc3, 0x83, 0xff, 0x92, 0x78, 0xda, 0xf6, + 0xde, 0xf8, 0x1f, 0x5a, 0x8e, 0x16, 0x87, 0x80, 0xb4, 0x77, 0x9e, 0x65, + 0x2c, 0x14, 0xf6, 0xfc, 0xbb, 0x7d, 0xdb, 0xe4, 0x49, 0xdd, 0xab, 0xae, + 0x87, 0xc9, 0x53, 0x14, 0xaa, 0x91, 0x01, 0xf9, 0xbd, 0x3d, 0xdf, 0x4a, + 0x8e, 0x67, 0x41, 0x90, 0xd4, 0x67, 0x99, 0x07, 0xb0, 0xa5, 0x9d, 0x42, + 0x2c, 0xe4, 0x55, 0x0c, 0x3a, 0xcd, 0x45, 0xed, 0xc7, 0x7b, 0x9d, 0x1a, + 0x22, 0x87, 0x37, 0x69, 0xec, 0xf2, 0x36, 0x70, 0xef, 0xa1, 0xbc, 0xd4, + 0x95, 0xc0, 0x2d, 0x36, 0x6f, 0xd3, 0x2a, 0x24, 0x87, 0x74, 0x7c, 0xf1, + 0xa6, 0x54, 0x41, 0x55, 0x56, 0x52, 0x55, 0x43, 0x5e, 0x44, 0x6e, 0x04, + 0xd6, 0x0e, 0x2d, 0xee, 0x23, 0x53, 0x8e, 0x6c, 0x28, 0xcc, 0x8c, 0x40, + 0x03, 0x03, 0xf6, 0x75, 0x85, 0x2a, 0xd0, 0x00, 0xae, 0x35, 0x6e, 0x68, + 0x5a, 0x8c, 0x28, 0x72, 0x4e, 0x57, 0xfc, 0xdc, 0x02, 0x66, 0x3a, 0x9d, + 0x24, 0xb4, 0xb0, 0x89, 0xe1, 0x47, 0x18, 0x06, 0x33, 0xbb, 0xac, 0xaf, + 0xb6, 0x78, 0x4e, 0x14, 0x29, 0xa2, 0xf6, 0x30, 0xe8, 0xd9, 0x5c, 0x86, + 0xdc, 0x30, 0x7a, 0x93, 0x68, 0xc3, 0x7e, 0x5d, 0x54, 0x35, 0x85, 0xfd, + 0xc9, 0xd2, 0xc9, 0x68, 0x67, 0xc0, 0xa9, 0xa6, 0x45, 0x79, 0xab, 0x3d, + 0xd3, 0xfa, 0xc1, 0x1c, 0x84, 0x43, 0x0a, 0x25, 0x34, 0x69, 0x86, 0x5a, + 0x64, 0x8b, 0x42, 0x70, 0x7e, 0xb1, 0x91, 0x6c, 0x32, 0x91, 0xb5, 0x91, + 0xa9, 0x57, 0x64, 0x7d, 0x0e, 0x54, 0xc6, 0x31, 0x7a, 0xd2, 0x2c, 0x5d, + 0xff, 0x3c, 0xe8, 0xbe, 0xdb, 0x79, 0xf5, 0xd2, 0xc8, 0x49, 0x6c, 0xf6, + 0xcf, 0xa1, 0xa1, 0xde, 0x82, 0x7a, 0x37, 0xa1, 0x4a, 0xab, 0xf0, 0x7f, + 0x8c, 0xf6, 0xb9, 0x83, 0x30, 0x0f, 0xd5, 0xfd, 0xf4, 0x75, 0xff, 0xf1, + 0xc3, 0xfe, 0x6e, 0xdf, 0x53, 0x2a, 0xf0, 0xc9, 0x62, 0x72, 0xad, 0x5c, + 0x4a, 0xe2, 0x2a, 0x7b, 0x75, 0x11, 0xc8, 0x76, 0x76, 0x9b, 0x2e, 0x40, + 0x77, 0xf1, 0x7c, 0xe8, 0x79, 0x7e, 0x89, 0x8e, 0x3c, 0x92, 0xb3, 0x16, + 0x18, 0xcc, 0x5b, 0xe7, 0x12, 0xfa, 0xc8, 0x9e, 0x67, 0xfc, 0xb4, 0x40, + 0x69, 0x1f, 0x7d, 0x80, 0xc0, 0xd7, 0xc9, 0x3c, 0x23, 0x37, 0xb1, 0x52, + 0x06, 0x9d, 0xcc, 0x21, 0x35, 0x33, 0xcb, 0x44, 0x19, 0x43, 0xc3, 0x7e, + 0x82, 0xd1, 0x71, 0x70, 0x9f, 0xa5, 0xf9, 0x94, 0xc8, 0x5b, 0x4c, 0x65, + 0x1a, 0xcf, 0x59, 0x71, 0x8c, 0x26, 0x88, 0xf3, 0xdc, 0x10, 0x07, 0x4e, + 0x70, 0xd0, 0x29, 0x92, 0xb2, 0xa8, 0xbb, 0x12, 0x83, 0x79, 0x95, 0x0d, + 0xdf, 0x07, 0x89, 0x5c, 0xd5, 0xc7, 0xde, 0x15, 0x70, 0x1a, 0x0a, 0x49, + 0x85, 0xcf, 0x17, 0x15, 0x37, 0x34, 0x2f, 0xaa, 0x2a, 0xc7, 0xb0, 0xa6, + 0x7c, 0x06, 0x4a, 0x87, 0x1a, 0xcc, 0x3e, 0xc0, 0x59, 0x50, 0x4e, 0x99, + 0x00, 0xd3, 0x9d, 0x8d, 0x80, 0xab, 0xe7, 0x73, 0x19, 0x4d, 0xa0, 0x26, + 0x16, 0xb4, 0x1e, 0xa8, 0xff, 0x4d, 0x54, 0xcc, 0x4a, 0xac, 0xa8, 0x69, + 0x50, 0x71, 0x5a, 0xd7, 0xab, 0x2b, 0xea, 0x8b, 0xc5, 0x68, 0x50, 0x43, + 0xa3, 0x42, 0xc3, 0x90, 0x06, 0x69, 0x95, 0x0f, 0xf1, 0x46, 0x19, 0xe5, + 0xa0, 0x06, 0xd5, 0xf8, 0xdb, 0xac, 0x9e, 0x4c, 0xbb, 0xb2, 0x6b, 0xb3, + 0xec, 0xb2, 0xa8, 0xf1, 0x66, 0x54, 0x6a, 0x67, 0x03, 0xbb, 0xed, 0x9d, + 0x9a, 0x86, 0x23, 0xa1, 0x56, 0x4c, 0x26, 0xd8, 0x8b, 0x58, 0xce, 0x24, + 0x00, 0x97, 0xcc, 0x73, 0x5d, 0xe1, 0xa9, 0x39, 0x4a, 0x73, 0x70, 0xb0, + 0x51, 0xde, 0x36, 0x4d, 0x82, 0x65, 0x5c, 0x16, 0xf1, 0xd9, 0x23, 0x5b, + 0xdf, 0xe4, 0x72, 0xd3, 0x71, 0x6c, 0x37, 0xbb, 0xd5, 0x26, 0x18, 0x07, + 0x20, 0xfb, 0x8d, 0xc7, 0x14, 0x35, 0x02, 0x8d, 0x4c, 0x29, 0x33, 0x90, + 0x0f, 0x46, 0xac, 0x6c, 0x90, 0x67, 0x86, 0x0c, 0x13, 0x72, 0x3b, 0xa4, + 0x25, 0x1a, 0x50, 0xc8, 0xb5, 0x13, 0xac, 0xe2, 0xb2, 0xdf, 0x38, 0x46, + 0x1e, 0x22, 0xbd, 0x27, 0x76, 0x84, 0x60, 0x3e, 0x18, 0x4b, 0xd8, 0xbc, + 0x2c, 0x04, 0x71, 0x2c, 0xe0, 0x7a, 0x18, 0x34, 0x23, 0xab, 0xb9, 0x60, + 0x96, 0xca, 0x41, 0x9c, 0xf1, 0x42, 0x85, 0xb0, 0x65, 0x3a, 0x90, 0xc8, + 0xcf, 0xb8, 0x21, 0xf4, 0xf7, 0x11, 0x2d, 0x64, 0xe3, 0x31, 0x1c, 0x90, + 0x7b, 0xae, 0x10, 0x69, 0x8d, 0xbb, 0x82, 0x3d, 0x3e, 0x98, 0xdf, 0x8c, + 0xd6, 0xbb, 0x38, 0xe0, 0x4a, 0xfb, 0x70, 0xab, 0x0d, 0x74, 0x75, 0xeb, + 0x65, 0x9f, 0x79, 0xf7, 0xf5, 0x64, 0xa6, 0xf8, 0x75, 0x3a, 0x47, 0xe7, + 0x8c, 0x1c, 0x4e, 0xb4, 0xab, 0xa0, 0x51, 0x7a, 0x4b, 0x63, 0xfe, 0x32, + 0x0d, 0xf2, 0x96, 0x65, 0xea, 0x26, 0x11, 0x17, 0x44, 0x2e, 0x5a, 0x89, + 0xab, 0xc5, 0x37, 0xa4, 0x86, 0x15, 0xb8, 0xb4, 0xe1, 0xee, 0x63, 0xbf, + 0xbf, 0xa3, 0x6a, 0x34, 0x8e, 0x6a, 0x6c, 0xad, 0x1a, 0x0b, 0xdc, 0xf9, + 0xa5, 0x17, 0x94, 0x82, 0x7d, 0x2c, 0x56, 0x57, 0xad, 0x6e, 0x43, 0x56, + 0x09, 0x59, 0xf2, 0xb0, 0x70, 0x00, 0xf8, 0x62, 0x3c, 0x49, 0x2f, 0xf1, + 0x81, 0xfc, 0x72, 0x56, 0x48, 0x46, 0x85, 0x4a, 0x1b, 0x70, 0x4d, 0x90, + 0xbd, 0x9d, 0x2d, 0xc4, 0x55, 0xb2, 0xc9, 0x26, 0x06, 0x1c, 0xc3, 0x29, + 0x8c, 0xfc, 0xfc, 0xfc, 0xc5, 0x56, 0x3f, 0xde, 0x52, 0x9a, 0x50, 0xf0, + 0x23, 0xcb, 0xd4, 0x68, 0x5f, 0xf1, 0x9a, 0x6a, 0xee, 0x68, 0xf2, 0x4c, + 0x2c, 0x39, 0xb9, 0xca, 0xd7, 0x42, 0x2e, 0xa0, 0x0d, 0x70, 0x5b, 0x77, + 0x6f, 0x3a, 0xaf, 0x70, 0x8f, 0x56, 0x8b, 0xbd, 0x9b, 0x36, 0x86, 0xf1, + 0x52, 0xa4, 0xe6, 0xf2, 0xc6, 0x53, 0xac, 0x68, 0xe0, 0xc2, 0xb0, 0xb8, + 0x0b, 0x90, 0x3c, 0x9d, 0xf4, 0x70, 0x53, 0xf5, 0xaa, 0xfc, 0xf2, 0xfa, + 0x21, 0x48, 0x54, 0x2c, 0xf6, 0x94, 0xbb, 0x7f, 0x3b, 0x98, 0x97, 0xd7, + 0xa3, 0x72, 0xef, 0x6f, 0x07, 0x65, 0x76, 0xf9, 0xb7, 0x83, 0xaa, 0xbc, + 0xfe, 0xe5, 0x97, 0x5f, 0x62, 0x89, 0x11, 0x0e, 0x40, 0x72, 0xf8, 0xd3, + 0x79, 0xf2, 0xe7, 0x87, 0x14, 0x16, 0x4e, 0x69, 0x27, 0x4d, 0x1e, 0x24, + 0x61, 0x6f, 0x7a, 0xeb, 0xeb, 0x34, 0xc5, 0x84, 0x4c, 0x5d, 0x05, 0xf9, + 0x8d, 0x43, 0xb7, 0x35, 0x6c, 0x46, 0x83, 0xc1, 0x99, 0xd6, 0x06, 0xb7, + 0x2a, 0xbd, 0x5c, 0x16, 0x40, 0x1f, 0x57, 0x53, 0x6e, 0x88, 0xce, 0x31, + 0xed, 0x39, 0x59, 0xc2, 0x17, 0xf5, 0x25, 0x71, 0xeb, 0xc6, 0x28, 0x84, + 0x27, 0xfb, 0xde, 0x61, 0x56, 0xa4, 0x01, 0x6a, 0xdf, 0xa4, 0x9d, 0x6b, + 0xdf, 0x4c, 0x36, 0x41, 0x0c, 0x4a, 0x41, 0xb6, 0x01, 0xb1, 0x3f, 0x9d, + 0x03, 0x27, 0x25, 0x4d, 0x23, 0xe5, 0x86, 0x28, 0x76, 0x05, 0x6f, 0xb9, + 0x45, 0x39, 0x24, 0x1b, 0x1a, 0xe8, 0x26, 0x92, 0x00, 0xb0, 0xc9, 0x1d, + 0xf4, 0x30, 0xc6, 0x64, 0x4b, 0xc6, 0x29, 0x17, 0xc5, 0xa5, 0x0f, 0x63, + 0x94, 0x86, 0xa6, 0x79, 0x5d, 0x6b, 0x90, 0x2c, 0x3e, 0x06, 0x5b, 0x4b, + 0xdd, 0xfb, 0x21, 0x13, 0x7d, 0x12, 0x2f, 0xf4, 0x0b, 0x46, 0xd6, 0x08, + 0xbf, 0x64, 0x3a, 0x6e, 0x96, 0x75, 0x12, 0x0b, 0x22, 0x92, 0xab, 0x48, + 0x8d, 0x2f, 0x18, 0x19, 0x88, 0xe2, 0xd9, 0xa4, 0x58, 0x00, 0x25, 0x6f, + 0x4a, 0xdb, 0xd1, 0x78, 0x45, 0xb9, 0x95, 0x5e, 0xef, 0x1a, 0xb2, 0x86, + 0x0a, 0xca, 0xa0, 0x13, 0x11, 0xae, 0x8d, 0xae, 0x22, 0x91, 0xda, 0xc4, + 0x69, 0x77, 0x6c, 0x7e, 0x83, 0x4c, 0x6d, 0x9d, 0x74, 0xe0, 0xd7, 0x83, + 0x74, 0xfa, 0x8f, 0x83, 0x45, 0x05, 0x4a, 0x5f, 0x55, 0xf7, 0xf6, 0x0e, + 0xb2, 0xaa, 0xa3, 0x9c, 0xb2, 0xf3, 0x3e, 0xbb, 0x3d, 0xe0, 0xd8, 0x9c, + 0x4e, 0xf2, 0xf3, 0x57, 0x0f, 0xa0, 0x91, 0xb5, 0xa4, 0x9a, 0xaf, 0x1f, + 0xa1, 0x41, 0xd4, 0x9d, 0x26, 0xcf, 0x35, 0x89, 0xdd, 0xeb, 0x31, 0xa2, + 0x2f, 0x96, 0x4e, 0x08, 0x59, 0xcd, 0x93, 0x1f, 0xf8, 0xa5, 0x98, 0x2c, + 0x35, 0xb8, 0x9f, 0xa8, 0x82, 0xf8, 0x1b, 0x26, 0x15, 0x49, 0x68, 0xb2, + 0xdc, 0x6d, 0x2c, 0xf3, 0xe4, 0xac, 0xb6, 0x6b, 0x0c, 0x22, 0xbb, 0xc6, + 0x1b, 0x22, 0xe7, 0x82, 0xdc, 0x45, 0xb4, 0x01, 0x18, 0x26, 0x02, 0xfc, + 0x98, 0xe3, 0x45, 0xb8, 0x21, 0x33, 0x58, 0xe4, 0xec, 0x93, 0x20, 0x4e, + 0x5b, 0x4a, 0x32, 0x16, 0xaa, 0x5a, 0xd7, 0x79, 0xb1, 0xa8, 0x26, 0xb7, + 0x12, 0xa7, 0x27, 0xb6, 0x0c, 0x26, 0x28, 0x32, 0x1b, 0x24, 0x42, 0xf3, + 0x21, 0x0b, 0xa1, 0x39, 0x1b, 0x19, 0x2b, 0xd0, 0xd2, 0x02, 0x6d, 0x3f, + 0x28, 0xae, 0xab, 0x2c, 0xe1, 0xc4, 0x0b, 0xf2, 0x0d, 0xf2, 0x82, 0x99, + 0x6c, 0xb1, 0xb5, 0xc6, 0x9d, 0xea, 0xf9, 0x2f, 0x6f, 0x41, 0xe3, 0x42, + 0x25, 0xfd, 0x60, 0x56, 0xa8, 0xbe, 0xb2, 0xe6, 0x85, 0xba, 0x20, 0xb2, + 0x3e, 0x98, 0xa7, 0x55, 0x85, 0x21, 0x27, 0xd6, 0xf8, 0x47, 0xdc, 0xa8, + 0xf4, 0x82, 0x51, 0xc1, 0x30, 0xed, 0x71, 0x24, 0x88, 0x50, 0xc2, 0xc5, + 0xcb, 0x73, 0x26, 0x04, 0xdc, 0xc0, 0xa3, 0x43, 0x38, 0xab, 0x14, 0xcc, + 0x68, 0x27, 0x5d, 0xc2, 0x46, 0x44, 0xc8, 0x40, 0x5f, 0xc8, 0x2d, 0xdc, + 0x86, 0x53, 0xda, 0x23, 0xd8, 0x22, 0x50, 0x69, 0x82, 0x72, 0x30, 0xcf, + 0x70, 0x25, 0x7e, 0x70, 0xfe, 0x29, 0x9a, 0x44, 0xf0, 0x0b, 0xc1, 0x52, + 0x21, 0x0b, 0xb5, 0x6e, 0xc2, 0x91, 0xc3, 0xab, 0xda, 0xe4, 0xae, 0xcb, + 0x09, 0x2b, 0x1a, 0x14, 0x5e, 0xa4, 0x11, 0x0b, 0x2e, 0xe6, 0x45, 0x35, + 0x79, 0x47, 0x61, 0xb5, 0xb8, 0x64, 0xc7, 0x98, 0xdd, 0x12, 0x46, 0xd4, + 0x1c, 0xf6, 0x06, 0xbc, 0x71, 0x33, 0x83, 0xf3, 0x0b, 0xa3, 0x0b, 0xbc, + 0x2b, 0xb4, 0xc3, 0x2e, 0x50, 0xd2, 0x61, 0x78, 0xe8, 0xb3, 0x10, 0x4a, + 0x43, 0x5d, 0x63, 0x10, 0x08, 0x19, 0x10, 0x89, 0x58, 0xf9, 0xfa, 0x7d, + 0x29, 0x12, 0xe3, 0x4d, 0x31, 0x19, 0xc3, 0x5f, 0x4b, 0xa1, 0xef, 0x64, + 0xad, 0xfe, 0x71, 0xb6, 0xc0, 0x48, 0x05, 0xff, 0xdd, 0x23, 0x0a, 0x8b, + 0x27, 0x79, 0x85, 0x05, 0x11, 0x65, 0x82, 0xda, 0x25, 0x9a, 0xee, 0x7d, + 0x7f, 0xe7, 0xe8, 0x0c, 0x98, 0xa1, 0xa1, 0x87, 0x45, 0x06, 0x4e, 0xa5, + 0x4c, 0x38, 0xd7, 0x6b, 0x42, 0x89, 0x73, 0x1a, 0x30, 0x60, 0x4b, 0x20, + 0x09, 0x5e, 0xb4, 0xf2, 0x6e, 0x3f, 0x75, 0x0b, 0x62, 0xc2, 0x35, 0xe2, + 0xf8, 0x3c, 0xb2, 0x83, 0x35, 0x77, 0x37, 0x8b, 0x0c, 0xbd, 0xae, 0xc1, + 0xf1, 0x9e, 0xf4, 0xf7, 0x90, 0xe1, 0x79, 0x32, 0x07, 0xbd, 0x37, 0x2b, + 0xd9, 0x6a, 0x35, 0x4c, 0xd1, 0x50, 0x41, 0xea, 0xc2, 0x62, 0x3a, 0xc7, + 0x96, 0xb3, 0xe9, 0x40, 0xd6, 0x45, 0x8f, 0x35, 0x06, 0xd2, 0xa3, 0xf2, + 0xe5, 0x8e, 0x04, 0xbe, 0xcf, 0xc6, 0x89, 0xef, 0xda, 0x8e, 0x85, 0x4b, + 0x4c, 0xc4, 0x27, 0x51, 0x99, 0x41, 0xc3, 0x24, 0x91, 0x68, 0x38, 0x07, + 0xee, 0x08, 0x90, 0xef, 0x58, 0x74, 0x34, 0x78, 0x06, 0x35, 0x08, 0x14, + 0x6c, 0x70, 0x75, 0x8c, 0x2b, 0xc0, 0x0e, 0xb8, 0xc6, 0x28, 0x69, 0x2f, + 0xf3, 0x9f, 0x6c, 0x56, 0x5b, 0xac, 0x3b, 0x70, 0x43, 0x03, 0xd2, 0xec, + 0xcf, 0x8e, 0x5f, 0x25, 0xec, 0x4d, 0x42, 0x09, 0x52, 0x5c, 0xf0, 0x1a, + 0x87, 0x18, 0xd1, 0x4a, 0x88, 0x08, 0xe7, 0x31, 0x8c, 0x95, 0xaf, 0x21, + 0xe9, 0x90, 0xe3, 0xb8, 0xc1, 0xa1, 0xeb, 0xdb, 0x39, 0xeb, 0xac, 0x16, + 0x94, 0x02, 0x5a, 0x36, 0x99, 0xb2, 0x30, 0x70, 0x52, 0xda, 0xc2, 0xa6, + 0x74, 0x33, 0x39, 0x77, 0x0f, 0xd4, 0xaa, 0xcb, 0x59, 0xfe, 0x0f, 0xa1, + 0xae, 0xd6, 0x30, 0x70, 0xe4, 0x60, 0xa3, 0x64, 0xe3, 0xe8, 0xed, 0x9b, + 0x97, 0xef, 0x8e, 0x0e, 0xdf, 0xfd, 0xf0, 0xf6, 0xf5, 0xb3, 0x97, 0xc7, + 0x1b, 0x94, 0x3c, 0xc1, 0x5a, 0x23, 0x89, 0x37, 0xc8, 0xd8, 0x25, 0xa6, + 0x8a, 0x62, 0x7a, 0x28, 0xc9, 0x00, 0x45, 0x48, 0xd1, 0xe0, 0x02, 0xf1, + 0x8b, 0x4a, 0x2d, 0x9e, 0x68, 0x0a, 0xbe, 0x14, 0xe1, 0x01, 0x8d, 0x54, + 0x1c, 0x12, 0x4d, 0xbf, 0xb2, 0x84, 0x01, 0x0b, 0x4d, 0xeb, 0x0a, 0xeb, + 0x83, 0xa6, 0x12, 0xcd, 0xbe, 0x90, 0x99, 0xeb, 0x3d, 0x53, 0x49, 0x08, + 0xfe, 0x83, 0x28, 0x5f, 0xc2, 0x89, 0x37, 0xc6, 0x07, 0x9c, 0x55, 0x5b, + 0x32, 0xfb, 0xbc, 0xc6, 0x9f, 0x50, 0x64, 0x55, 0xa5, 0x09, 0x93, 0xda, + 0x79, 0xe5, 0xc8, 0x41, 0xd6, 0x03, 0xdf, 0x45, 0x0a, 0x95, 0x61, 0x0d, + 0xcb, 0x7a, 0x03, 0xc3, 0x18, 0x38, 0xc9, 0xc1, 0xf2, 0x31, 0x28, 0xaf, + 0xc3, 0xa2, 0xb6, 0x12, 0x55, 0xca, 0xc8, 0x83, 0x96, 0x7d, 0xc8, 0x28, + 0xf8, 0x31, 0x17, 0x59, 0xe8, 0x68, 0x51, 0xd2, 0xcd, 0x97, 0xfc, 0x04, + 0x6c, 0x0c, 0x4f, 0xf4, 0xb3, 0xc0, 0x3c, 0x8b, 0xd2, 0x92, 0x5e, 0xd1, + 0x46, 0x0d, 0xf2, 0x26, 0x37, 0x94, 0x92, 0x43, 0x87, 0xdc, 0xbc, 0x67, + 0x87, 0x17, 0x2f, 0x74, 0xc6, 0x9b, 0xf9, 0x29, 0x67, 0x7d, 0x4f, 0xd3, + 0x21, 0xfc, 0x46, 0x4c, 0x64, 0x8b, 0x34, 0xd6, 0x98, 0xda, 0xf8, 0xcc, + 0x83, 0x58, 0x74, 0xce, 0x06, 0x0d, 0x0e, 0x11, 0x44, 0xab, 0x45, 0xd7, + 0xb1, 0xa0, 0xda, 0xaf, 0x38, 0x09, 0x5b, 0x21, 0x54, 0x6b, 0xcc, 0x31, + 0xe7, 0xc3, 0xf7, 0x37, 0x69, 0x39, 0x62, 0x7b, 0x1c, 0xac, 0xe5, 0x20, + 0x9f, 0xe4, 0xb5, 0xfa, 0x8e, 0x59, 0xa0, 0xa3, 0x75, 0x41, 0xfe, 0x9a, + 0xcd, 0x2e, 0xf3, 0x19, 0xca, 0x64, 0x78, 0x21, 0xe4, 0x91, 0x5d, 0x55, + 0xb2, 0x3e, 0x4c, 0x2f, 0x73, 0x56, 0x0a, 0xb3, 0xba, 0x52, 0x26, 0x04, + 0xa7, 0x61, 0x33, 0xdb, 0x25, 0x5a, 0x12, 0xbd, 0xdd, 0x9d, 0x48, 0x5b, + 0x56, 0xbd, 0xf2, 0x58, 0xc9, 0xc7, 0xeb, 0x9e, 0x1b, 0xfa, 0x63, 0x76, + 0x0b, 0x34, 0x89, 0x3b, 0x15, 0xf3, 0x00, 0x62, 0x02, 0x5d, 0xf1, 0xf2, + 0x72, 0x80, 0xf7, 0x55, 0x26, 0x5e, 0x79, 0x52, 0xed, 0x54, 0x12, 0x51, + 0xcb, 0x34, 0xbf, 0xab, 0xd6, 0x69, 0x7c, 0x1b, 0xee, 0x29, 0xcf, 0x69, + 0xa8, 0x1b, 0xdb, 0x1a, 0x3d, 0x09, 0xb2, 0x29, 0x0d, 0x73, 0x4c, 0xbc, + 0xb2, 0xf6, 0x6c, 0xee, 0x6e, 0xb2, 0xaf, 0x65, 0x45, 0x4b, 0x71, 0x9d, + 0x87, 0x4b, 0xe9, 0xeb, 0xfe, 0xe3, 0x1d, 0xba, 0x95, 0xee, 0x6e, 0xd5, + 0xf6, 0x4b, 0x88, 0x31, 0xda, 0x33, 0x76, 0x47, 0x36, 0x77, 0xeb, 0x0f, + 0xa6, 0x46, 0xf3, 0x71, 0xf7, 0xf6, 0x18, 0x0c, 0xca, 0x50, 0xc3, 0xa0, + 0xdd, 0x7e, 0x1b, 0x89, 0xca, 0x22, 0x74, 0xd2, 0xca, 0x02, 0xad, 0x38, + 0xd1, 0xfe, 0xc0, 0x52, 0xd0, 0x72, 0x1b, 0xa3, 0x0b, 0x4c, 0x4e, 0xa7, + 0xbd, 0xc5, 0x56, 0x16, 0xe3, 0xf1, 0x91, 0x9c, 0xaf, 0x16, 0x48, 0x2f, + 0xe2, 0xb3, 0x8c, 0x8f, 0x34, 0xa2, 0x9c, 0x60, 0x6d, 0x49, 0x5f, 0xba, + 0x38, 0x3a, 0x24, 0x45, 0xf8, 0x1e, 0xbb, 0x64, 0x74, 0x7d, 0xb5, 0xdf, + 0x59, 0x2c, 0xc2, 0xb7, 0xdc, 0x56, 0xc4, 0xdb, 0x9e, 0x02, 0x53, 0xb8, + 0xe7, 0xb2, 0xf2, 0x14, 0xe4, 0x78, 0x08, 0x50, 0x6b, 0x93, 0x58, 0xfb, + 0xdc, 0xd0, 0x2b, 0xbd, 0x9b, 0xb0, 0x07, 0x73, 0xa4, 0x7a, 0x95, 0x2c, + 0xa4, 0x6e, 0xd0, 0x2e, 0x73, 0x3e, 0xc7, 0x66, 0xe7, 0xa0, 0x03, 0x77, + 0xd5, 0x66, 0xd6, 0xbf, 0x94, 0x86, 0x3a, 0xd8, 0xc0, 0xee, 0x01, 0xfe, + 0xdc, 0xa3, 0x9f, 0xfb, 0x9d, 0xad, 0xa5, 0x0b, 0xae, 0x62, 0xcb, 0xd8, + 0xd2, 0xcd, 0xd6, 0x75, 0xb7, 0x75, 0x3e, 0x0e, 0x60, 0x13, 0x0d, 0x86, + 0xa3, 0xb2, 0x17, 0x9f, 0x2e, 0xc7, 0x22, 0xa7, 0x6c, 0x16, 0x47, 0x21, + 0x26, 0x98, 0xe3, 0x61, 0x12, 0x18, 0x52, 0x9d, 0x8d, 0x9c, 0x1b, 0x68, + 0xf8, 0xae, 0xcc, 0xae, 0xd0, 0x83, 0x9d, 0x2c, 0x6a, 0x26, 0x5d, 0xa4, + 0x72, 0x92, 0xa3, 0x68, 0x76, 0xd2, 0x43, 0x5f, 0x8c, 0x8a, 0x2a, 0x3f, + 0xc8, 0x06, 0x90, 0x45, 0x3b, 0x45, 0x67, 0x9f, 0x3e, 0xd8, 0x33, 0x34, + 0x0c, 0x1a, 0x33, 0x72, 0x05, 0x32, 0xd6, 0xe3, 0x31, 0xe8, 0x39, 0xb4, + 0x00, 0x35, 0x0b, 0x02, 0x73, 0xe0, 0xcc, 0x21, 0x10, 0xa5, 0xf2, 0x21, + 0x1a, 0x0c, 0x31, 0x46, 0xe8, 0x8a, 0x33, 0x7b, 0x55, 0x20, 0x23, 0x9a, + 0xb2, 0x34, 0xbf, 0xf0, 0x49, 0xb0, 0x34, 0x89, 0x64, 0x51, 0x31, 0x9e, + 0x40, 0x53, 0xac, 0x68, 0x38, 0x01, 0xfc, 0x91, 0x46, 0x3e, 0x18, 0xe9, + 0x6d, 0x89, 0x4c, 0x4d, 0x13, 0xe2, 0xcc, 0x1a, 0x45, 0x1a, 0x73, 0x63, + 0xfe, 0x14, 0xf2, 0xd0, 0x38, 0x49, 0xbf, 0x51, 0x57, 0x96, 0x96, 0xb7, + 0xc9, 0x86, 0xb4, 0x1d, 0xb6, 0x74, 0xcd, 0x63, 0xc4, 0x52, 0xe0, 0x7a, + 0xc7, 0xe8, 0x18, 0x1f, 0x64, 0xb1, 0xcf, 0x2d, 0xd7, 0xdf, 0x4c, 0xd1, + 0xfa, 0x65, 0xe9, 0x6c, 0x2d, 0x49, 0x82, 0x64, 0xe2, 0x8d, 0x0f, 0x19, + 0x5d, 0xef, 0x6c, 0x9b, 0x08, 0x51, 0xc4, 0xee, 0xe6, 0x17, 0x57, 0xa1, + 0x20, 0xba, 0x50, 0xc4, 0xfd, 0x39, 0x07, 0xb3, 0xa4, 0x33, 0x49, 0xed, + 0x25, 0x62, 0xa1, 0x78, 0xc2, 0x10, 0x13, 0xde, 0x4f, 0x9c, 0x44, 0xe9, + 0x3b, 0x54, 0xd3, 0x32, 0x1d, 0xa0, 0x3f, 0x1e, 0x9d, 0xff, 0x6e, 0x77, + 0x4f, 0x0e, 0x11, 0x91, 0x0c, 0x53, 0xd1, 0xaa, 0x9b, 0x19, 0xa3, 0xe4, + 0xec, 0xd0, 0x85, 0xc7, 0x19, 0x17, 0x83, 0x06, 0xc3, 0xac, 0xbb, 0x71, + 0x99, 0x22, 0xc3, 0xd4, 0x55, 0x92, 0x43, 0xaa, 0xf1, 0x31, 0xba, 0x38, + 0x1a, 0x12, 0x93, 0xfc, 0x7d, 0x81, 0x29, 0xfb, 0x72, 0x67, 0x28, 0x52, + 0x88, 0x05, 0xad, 0xb1, 0x0d, 0xd4, 0x89, 0x5d, 0x5e, 0x22, 0x55, 0xb8, + 0x84, 0xb4, 0x45, 0xe4, 0x16, 0xcb, 0x1b, 0xdf, 0xaa, 0xf9, 0x35, 0x2d, + 0xfd, 0x7b, 0x04, 0x1c, 0x31, 0x2b, 0x2e, 0x9e, 0x6e, 0xde, 0x9f, 0x78, + 0x83, 0xe0, 0xac, 0xe0, 0x2f, 0x33, 0xb6, 0xc1, 0x12, 0xf9, 0x28, 0x1d, + 0xf0, 0xed, 0xde, 0xeb, 0x61, 0x43, 0x76, 0x21, 0x69, 0xfc, 0x07, 0x25, + 0x85, 0xc0, 0xbd, 0xa4, 0x50, 0x33, 0x93, 0xe0, 0x5d, 0xe3, 0x59, 0x79, + 0x2a, 0xfa, 0x2e, 0xa1, 0x54, 0x56, 0x11, 0x11, 0x09, 0x11, 0xc0, 0xa0, + 0x20, 0xd0, 0xce, 0x41, 0xbb, 0xc6, 0xe0, 0x15, 0xce, 0x2d, 0x64, 0xae, + 0xdf, 0x04, 0xd8, 0x29, 0x4a, 0xb1, 0x9d, 0x9f, 0xe1, 0x5f, 0x92, 0xd3, + 0x39, 0x3c, 0x57, 0x96, 0xd9, 0x24, 0x6e, 0x8a, 0x2b, 0x12, 0x5f, 0xb5, + 0xdf, 0x8e, 0x51, 0x36, 0xc9, 0xa7, 0x39, 0xf9, 0x90, 0xcf, 0x35, 0xb3, + 0x88, 0x3b, 0x8e, 0x7a, 0xe6, 0xab, 0xd3, 0xa5, 0xa9, 0xbb, 0x21, 0x88, + 0x68, 0x58, 0x25, 0x3f, 0xdf, 0x3f, 0x02, 0x03, 0xe2, 0x70, 0xce, 0xeb, + 0xc0, 0x74, 0x62, 0x69, 0xb1, 0xc1, 0xbb, 0x11, 0xf8, 0xa7, 0x4c, 0x4b, + 0xf1, 0x92, 0xb1, 0xfe, 0x70, 0xc9, 0x89, 0xf7, 0xef, 0x87, 0xd5, 0xee, + 0xae, 0x19, 0xf3, 0xd2, 0xeb, 0x14, 0xe6, 0x31, 0x40, 0x5f, 0x2e, 0x09, + 0x6e, 0xa9, 0x50, 0xfb, 0x6e, 0xf2, 0xf6, 0xcd, 0x49, 0xb2, 0x89, 0x68, + 0x3e, 0xc9, 0xd7, 0x8f, 0x76, 0xf7, 0xb6, 0xf4, 0xce, 0xb2, 0xb8, 0x7a, + 0x45, 0xcd, 0x48, 0x97, 0x0f, 0x0f, 0x72, 0x99, 0x9a, 0xc5, 0x1e, 0xd7, + 0xe0, 0x28, 0x43, 0x6b, 0x22, 0xd0, 0xc6, 0xa1, 0x9a, 0x2d, 0x07, 0x19, + 0x8c, 0x69, 0x16, 0x00, 0x74, 0xe4, 0x86, 0xa3, 0x11, 0xc2, 0x0e, 0x21, + 0x9d, 0x93, 0xe9, 0x01, 0x04, 0x3c, 0x0b, 0xf6, 0xf2, 0xe3, 0x63, 0x73, + 0x63, 0xfc, 0x59, 0xb0, 0x53, 0x2a, 0x0f, 0xed, 0x06, 0xef, 0x51, 0xaf, + 0x27, 0xcb, 0xe0, 0x04, 0x66, 0xd2, 0x8e, 0x2a, 0xed, 0xb6, 0x83, 0xc7, + 0x75, 0x46, 0x7e, 0xd7, 0x9b, 0xb4, 0xd1, 0x90, 0xad, 0xa5, 0x10, 0x76, + 0x0f, 0x14, 0xbb, 0x48, 0x10, 0x96, 0xa6, 0x92, 0xce, 0xf1, 0xeb, 0x1f, + 0xef, 0x6a, 0xe8, 0xcb, 0xa8, 0x02, 0x4b, 0x72, 0x76, 0x30, 0x0f, 0xd3, + 0x8d, 0x6a, 0x59, 0xde, 0x03, 0x8d, 0x5e, 0x62, 0xbb, 0x2e, 0x1e, 0xa5, + 0x96, 0x5d, 0xdc, 0x56, 0x06, 0x40, 0xc7, 0xd6, 0xb4, 0x26, 0x16, 0xd8, + 0x91, 0xeb, 0x90, 0x71, 0xf5, 0xbd, 0x48, 0xea, 0x5d, 0x89, 0x1c, 0xd4, + 0x33, 0xa7, 0x5a, 0xa2, 0x6e, 0xff, 0x9e, 0x66, 0x5d, 0x46, 0x03, 0xc4, + 0xb9, 0xbb, 0x6e, 0x42, 0xf8, 0x29, 0x46, 0x23, 0x9b, 0xdb, 0x88, 0x95, + 0x6e, 0x66, 0xf3, 0x66, 0x3d, 0x1b, 0xaa, 0x46, 0xe6, 0xcc, 0x58, 0x70, + 0x83, 0xa5, 0x84, 0x0b, 0x96, 0x0d, 0xb3, 0x51, 0x66, 0xb9, 0xf5, 0x42, + 0x57, 0xfd, 0xed, 0x8e, 0x44, 0x96, 0x50, 0xf0, 0x15, 0x03, 0x14, 0x19, + 0x7e, 0x04, 0xc6, 0xdf, 0x2c, 0x48, 0xfb, 0x94, 0xbc, 0xab, 0x59, 0x3e, + 0x7c, 0x8f, 0x0b, 0xb4, 0x4a, 0x39, 0x38, 0x5a, 0xe6, 0x82, 0x4e, 0xee, + 0x72, 0xd7, 0xd9, 0xe0, 0x56, 0xd5, 0x66, 0xb5, 0x50, 0x62, 0x40, 0x23, + 0x87, 0xa4, 0x16, 0x0d, 0x2e, 0x2c, 0x96, 0xa3, 0x64, 0xf3, 0xa5, 0xa4, + 0x62, 0x9c, 0x3d, 0xff, 0x4b, 0xb8, 0x05, 0x54, 0x53, 0xf8, 0x43, 0xb0, + 0xec, 0xf2, 0xd6, 0x72, 0x8a, 0x7c, 0x30, 0xf1, 0xa6, 0x26, 0xe1, 0x93, + 0x27, 0x7b, 0x4b, 0x02, 0x8c, 0x03, 0xb6, 0x49, 0xd2, 0x79, 0x4a, 0x0f, + 0x70, 0x43, 0x13, 0xc1, 0x18, 0xfa, 0xee, 0x67, 0xfe, 0x94, 0x08, 0x03, + 0xfe, 0xa8, 0xaf, 0x16, 0xd3, 0x01, 0xec, 0xcf, 0xac, 0xfe, 0xae, 0xc3, + 0xee, 0x55, 0x4a, 0x18, 0x58, 0x1a, 0x35, 0x82, 0x01, 0xd9, 0xed, 0x40, + 0xcc, 0x5d, 0xd4, 0xba, 0x06, 0x49, 0x55, 0xfc, 0x09, 0xf5, 0xd1, 0xe5, + 0xdf, 0xe9, 0xfe, 0xe2, 0x55, 0x91, 0xb8, 0x46, 0xde, 0x2c, 0x51, 0xb8, + 0x41, 0x3c, 0x28, 0x7f, 0x7e, 0xf5, 0xd7, 0x9f, 0xbf, 0xd9, 0x7f, 0x98, + 0x7e, 0x9d, 0x0e, 0x1f, 0x8f, 0x9f, 0xa4, 0x8f, 0x46, 0x8f, 0xbe, 0xfe, + 0x66, 0xef, 0xc9, 0xa3, 0xf4, 0xeb, 0x87, 0xe3, 0xf4, 0xf1, 0x6e, 0xb6, + 0xfb, 0xcd, 0x78, 0x6f, 0x7f, 0x34, 0x1a, 0x67, 0x4f, 0x46, 0x5f, 0xa7, + 0x9d, 0xbe, 0x9a, 0x15, 0x74, 0xe4, 0xe2, 0x48, 0x62, 0x1b, 0x39, 0xac, + 0xcb, 0xf9, 0x8b, 0xc3, 0xde, 0x6e, 0x72, 0x95, 0x7d, 0xb0, 0xd3, 0xc1, + 0xca, 0x64, 0x58, 0xcd, 0x2a, 0x73, 0x33, 0x8a, 0x25, 0x7d, 0x81, 0x4f, + 0x03, 0xf1, 0x22, 0xc4, 0xa2, 0xc9, 0x42, 0xeb, 0x1a, 0x56, 0x12, 0x90, + 0x66, 0x9b, 0x25, 0x92, 0x98, 0x9b, 0x90, 0x4c, 0xfd, 0x25, 0xca, 0x62, + 0xaf, 0x52, 0xcc, 0x87, 0xd1, 0xd5, 0x90, 0x87, 0xce, 0xd9, 0xf1, 0x22, + 0x1f, 0xca, 0x5f, 0x55, 0x77, 0xa9, 0xa1, 0x1f, 0xcb, 0x62, 0x31, 0x3f, + 0x2b, 0x26, 0xf9, 0xf0, 0xb6, 0x6b, 0x20, 0x82, 0xbe, 0x59, 0xf7, 0x80, + 0x7d, 0x6f, 0x57, 0xb9, 0x7f, 0xf0, 0x98, 0xd9, 0x6c, 0x5e, 0x65, 0x12, + 0x1e, 0x25, 0xc2, 0x71, 0xb5, 0xec, 0xbb, 0x51, 0x51, 0x34, 0x9c, 0xf5, + 0x4f, 0x12, 0x48, 0xb1, 0x7d, 0xfc, 0x41, 0xc7, 0x9a, 0x65, 0x03, 0xf8, + 0x3f, 0xfd, 0xb5, 0x9e, 0x50, 0xaa, 0x0c, 0xb8, 0x2b, 0x6f, 0xb3, 0x34, + 0x0a, 0xbf, 0xd1, 0xa7, 0x41, 0xa9, 0xc3, 0xe7, 0x30, 0x04, 0x4d, 0x43, + 0x32, 0x58, 0xee, 0xfc, 0x33, 0xeb, 0x69, 0x92, 0xae, 0x8f, 0xdf, 0x5a, + 0x7c, 0xb0, 0xe6, 0x0b, 0x45, 0x5b, 0x6f, 0xd0, 0x48, 0x61, 0xda, 0x47, + 0xee, 0xfb, 0x73, 0x6e, 0xe2, 0x8d, 0xc4, 0x89, 0x6c, 0xa6, 0xef, 0xd3, + 0x7e, 0x72, 0x7a, 0x74, 0x7e, 0x86, 0x8d, 0xcf, 0x11, 0x88, 0x60, 0x8b, + 0x4c, 0x6f, 0xd9, 0x07, 0x10, 0x91, 0x2a, 0x8e, 0xce, 0x6f, 0x0b, 0x21, + 0xc2, 0xc5, 0xd3, 0x90, 0x55, 0x0d, 0x7c, 0xd0, 0xf1, 0x48, 0x02, 0x53, + 0x4a, 0xc8, 0x3a, 0xe9, 0x24, 0x1f, 0x45, 0x8a, 0x21, 0x70, 0x15, 0x60, + 0x84, 0xa3, 0xad, 0x10, 0x90, 0xd2, 0x4d, 0x04, 0xfe, 0xc2, 0x05, 0xa9, + 0x20, 0x5d, 0x5e, 0xa2, 0x3b, 0xa6, 0x4a, 0x5c, 0xc6, 0xbc, 0xf4, 0xb0, + 0x4c, 0xf1, 0x68, 0x96, 0x46, 0x4d, 0x0f, 0xde, 0x27, 0x2c, 0x1f, 0xe6, + 0xf2, 0xb3, 0xc2, 0xb5, 0x87, 0x61, 0x9f, 0x13, 0x4e, 0xd6, 0xd6, 0x5c, + 0xf2, 0x70, 0x29, 0xb1, 0x3a, 0xac, 0x7e, 0xa2, 0x28, 0x88, 0x82, 0xac, + 0x20, 0x9a, 0x95, 0x4b, 0xaf, 0x0b, 0x47, 0xd7, 0x10, 0x58, 0xb2, 0xbc, + 0x67, 0x28, 0xdb, 0x89, 0x17, 0x83, 0x46, 0xaa, 0xf2, 0x4d, 0x20, 0x63, + 0x31, 0xff, 0x8b, 0x4d, 0xb3, 0x8a, 0x62, 0x30, 0xe2, 0xfd, 0x77, 0x79, + 0xe4, 0x21, 0x12, 0x63, 0x85, 0xe7, 0xe8, 0x4e, 0xe3, 0x7b, 0x68, 0xf2, + 0x7e, 0x22, 0xd7, 0xbe, 0xd7, 0x73, 0x2b, 0x81, 0x38, 0x94, 0x8d, 0xe6, + 0x8b, 0x01, 0x5e, 0x86, 0x11, 0x05, 0x93, 0xa8, 0xf1, 0x14, 0x7f, 0x46, + 0xea, 0x13, 0x22, 0xff, 0xb0, 0x14, 0x32, 0x56, 0x5b, 0x98, 0x1c, 0xd7, + 0x16, 0x21, 0xbd, 0x8f, 0x5a, 0x49, 0x37, 0x79, 0x86, 0x70, 0x98, 0x09, + 0x88, 0x28, 0x22, 0x01, 0x02, 0x99, 0x9d, 0x81, 0x76, 0x83, 0x5c, 0xcb, + 0xc9, 0x9f, 0xd8, 0x6a, 0xe4, 0x37, 0x57, 0x55, 0x96, 0xba, 0x93, 0xfc, + 0xdd, 0x00, 0x52, 0xe8, 0xb6, 0x40, 0x22, 0xe2, 0x83, 0x67, 0x92, 0xba, + 0x95, 0xb8, 0x4c, 0x89, 0xe2, 0x24, 0x03, 0x1a, 0x0b, 0x33, 0x26, 0xcb, + 0x30, 0xc1, 0x07, 0xb3, 0x1a, 0xb1, 0x6e, 0x18, 0x59, 0x83, 0x23, 0xc9, + 0xa8, 0x45, 0x90, 0x3d, 0x48, 0x48, 0xe8, 0x63, 0x01, 0x08, 0xe6, 0x64, + 0x46, 0x41, 0xd3, 0xbc, 0x89, 0x1b, 0x24, 0xa1, 0x0d, 0x5e, 0xca, 0x25, + 0x29, 0xf1, 0xb3, 0x69, 0xda, 0xd6, 0x05, 0xaa, 0x80, 0x32, 0xec, 0x8f, + 0x63, 0x6b, 0xf7, 0x71, 0xb4, 0x7c, 0x4e, 0x28, 0x96, 0x4f, 0x31, 0x48, + 0x3c, 0xa6, 0x06, 0x11, 0x3a, 0x2a, 0xb9, 0xd3, 0xf8, 0x49, 0x38, 0x65, + 0xb9, 0x40, 0x65, 0xe1, 0xd5, 0x9f, 0x2b, 0xfe, 0x9e, 0x41, 0x16, 0x72, + 0x98, 0xa5, 0x84, 0x24, 0xa9, 0x67, 0xb6, 0x62, 0x57, 0xc1, 0x6e, 0x7f, + 0x2f, 0xd9, 0xa4, 0xcc, 0x6d, 0x4c, 0x7c, 0x15, 0x53, 0x13, 0x87, 0xa7, + 0x93, 0x95, 0x5e, 0xc6, 0x22, 0x5d, 0x38, 0xaf, 0x8a, 0xea, 0x07, 0xc2, + 0xa9, 0xe4, 0xc1, 0x7e, 0x42, 0x19, 0xfb, 0x98, 0xb6, 0x86, 0x1d, 0xfb, + 0x01, 0xda, 0xf5, 0x9a, 0xb0, 0xff, 0x59, 0x37, 0xe8, 0xed, 0x9b, 0x97, + 0x07, 0xb2, 0x4e, 0xad, 0x49, 0x2e, 0x55, 0x35, 0xd1, 0x25, 0xa1, 0x44, + 0x97, 0x44, 0xed, 0x92, 0x32, 0x34, 0xa2, 0x88, 0x2f, 0x13, 0xd5, 0xab, + 0x5d, 0x1c, 0x1f, 0x3d, 0x7b, 0x71, 0xdc, 0x83, 0x9f, 0xe7, 0x87, 0xbd, + 0xc3, 0xe3, 0xf3, 0xdd, 0xbd, 0x27, 0xbd, 0x1f, 0x8f, 0x5e, 0xf5, 0x40, + 0xd4, 0xd8, 0x7b, 0xf4, 0xf8, 0x80, 0x43, 0x0e, 0xf8, 0x99, 0x37, 0x6d, + 0x4f, 0xac, 0x47, 0x19, 0xf5, 0xa4, 0xda, 0xdd, 0xd7, 0x2e, 0xbb, 0xe6, + 0x83, 0xd6, 0x31, 0x48, 0x90, 0xcf, 0x02, 0x18, 0x79, 0x15, 0x48, 0xa5, + 0x98, 0x92, 0xac, 0xa9, 0xf3, 0x96, 0xe8, 0x04, 0xbd, 0xa6, 0x24, 0x48, + 0x97, 0x9f, 0x08, 0x3c, 0x5d, 0x2e, 0x3a, 0xca, 0x6c, 0x1d, 0x37, 0x82, + 0x6f, 0x9c, 0x93, 0xc4, 0xf2, 0x8d, 0x59, 0xc9, 0x8c, 0x7d, 0x35, 0x88, + 0x5d, 0xc1, 0x2d, 0x7b, 0x4c, 0x16, 0x5d, 0xce, 0x37, 0xda, 0x95, 0xc4, + 0xe7, 0x88, 0xcc, 0x84, 0x52, 0xae, 0x46, 0xf7, 0x6a, 0x24, 0x0a, 0xc5, + 0x07, 0x33, 0xcc, 0xa7, 0xdc, 0x66, 0xb7, 0xf4, 0xb4, 0xc8, 0x89, 0x4e, + 0x3f, 0xec, 0x98, 0x0d, 0x15, 0x25, 0x3d, 0xe2, 0xd9, 0x29, 0xcd, 0x91, + 0x4d, 0xf1, 0x14, 0x1f, 0xc1, 0xef, 0x4f, 0x19, 0x12, 0x07, 0x03, 0xa9, + 0xd2, 0xd2, 0xd4, 0x0c, 0x94, 0xda, 0xd3, 0x5b, 0x8b, 0x02, 0x6a, 0x40, + 0xc9, 0x6c, 0x56, 0x75, 0x3e, 0x99, 0x6c, 0xb9, 0x05, 0xfb, 0x83, 0xa6, + 0xd8, 0xe7, 0x78, 0xb5, 0x69, 0x08, 0xbb, 0xc4, 0x2b, 0x2b, 0x9e, 0x14, + 0xdd, 0x9e, 0x61, 0x31, 0x02, 0x45, 0x9d, 0x8c, 0x93, 0xa5, 0x9b, 0x5f, + 0x82, 0xeb, 0xec, 0xe2, 0x6f, 0xdc, 0xfc, 0x14, 0x30, 0xbf, 0x98, 0x99, + 0x64, 0x29, 0xd7, 0xd6, 0x4c, 0x51, 0x42, 0xc4, 0x6d, 0x28, 0xb8, 0x4b, + 0x02, 0x81, 0xa5, 0x0e, 0x07, 0x8a, 0xb0, 0x92, 0x38, 0xd6, 0x2e, 0x67, + 0x4e, 0xce, 0x04, 0x0d, 0xf6, 0x0f, 0xe1, 0xbe, 0xd6, 0x0e, 0x29, 0x32, + 0xb3, 0x90, 0x5f, 0x48, 0xf9, 0x40, 0xdb, 0x07, 0x7d, 0xc5, 0x71, 0x9a, + 0x6e, 0x42, 0xee, 0xc2, 0x35, 0x43, 0x66, 0xa0, 0xaa, 0x96, 0x58, 0x0d, + 0x90, 0x1f, 0x56, 0x5f, 0xb6, 0x92, 0x91, 0xf3, 0xc0, 0xd2, 0xaf, 0xf8, + 0xca, 0x5d, 0x5a, 0xbf, 0x15, 0x27, 0x32, 0x74, 0xbc, 0x1e, 0xbb, 0xb5, + 0xe7, 0x7b, 0x55, 0x75, 0xd5, 0x72, 0x6e, 0xf0, 0x63, 0xd5, 0xff, 0x8e, + 0x34, 0x10, 0x92, 0x83, 0xea, 0x31, 0x28, 0x1d, 0xd5, 0xf3, 0x1e, 0xec, + 0x3f, 0x26, 0xe7, 0xdb, 0x9a, 0x50, 0xca, 0x10, 0xbb, 0x42, 0x69, 0xd5, + 0x6d, 0xd9, 0x35, 0xea, 0xb3, 0x4e, 0xdc, 0xe2, 0x37, 0xb6, 0x3a, 0x5a, + 0x79, 0x59, 0xfa, 0x82, 0x23, 0x22, 0xef, 0x5a, 0x67, 0x1c, 0xe7, 0x92, + 0x7c, 0x23, 0xe2, 0x8d, 0x2c, 0xf6, 0xd2, 0x6a, 0x1b, 0xd3, 0x5f, 0x12, + 0x70, 0x9a, 0xab, 0xb2, 0xd6, 0x8a, 0xd3, 0x10, 0xaa, 0x75, 0xc2, 0x12, + 0xa3, 0xdd, 0xa4, 0x99, 0xfc, 0xb1, 0xcb, 0x11, 0x8a, 0xe3, 0xfc, 0x32, + 0x8a, 0x16, 0x08, 0xb1, 0xfd, 0x94, 0x32, 0x68, 0x71, 0x01, 0x78, 0xb8, + 0xc4, 0x45, 0x2c, 0x06, 0x40, 0x0e, 0x34, 0x16, 0x57, 0x88, 0x44, 0xbb, + 0x73, 0xb8, 0x3b, 0x4f, 0x31, 0x3c, 0x86, 0xf1, 0xd6, 0x16, 0x9e, 0x68, + 0xad, 0x22, 0x03, 0xa2, 0xe3, 0x87, 0xc0, 0xa7, 0x63, 0xe1, 0x33, 0x84, + 0xb3, 0x14, 0x5f, 0x1d, 0x2d, 0xf0, 0xb5, 0xba, 0x40, 0xa7, 0x0e, 0x1e, + 0x85, 0x73, 0x9c, 0x1c, 0xc2, 0xa1, 0x1a, 0x94, 0x83, 0x61, 0x40, 0x5a, + 0x22, 0x3f, 0x34, 0x43, 0x9b, 0x78, 0x35, 0x9a, 0xf3, 0x2b, 0x82, 0x57, + 0x08, 0x14, 0x10, 0x82, 0x32, 0xa3, 0x3c, 0xbf, 0x2e, 0xfb, 0x87, 0xc8, + 0xf7, 0x4c, 0xc6, 0x3d, 0x86, 0xf4, 0x50, 0x8c, 0xde, 0x42, 0x29, 0xc4, + 0x21, 0x27, 0x56, 0x82, 0x75, 0x26, 0x96, 0x66, 0x41, 0x26, 0x66, 0x7c, + 0xa5, 0xdc, 0x90, 0xa6, 0x69, 0x03, 0x82, 0x41, 0x9d, 0x20, 0x39, 0x4c, + 0xb1, 0xcf, 0x67, 0x39, 0x81, 0x4b, 0xab, 0x6d, 0x53, 0x72, 0x44, 0x85, + 0x61, 0x21, 0x77, 0xae, 0x8a, 0xae, 0xa1, 0x1f, 0xa1, 0xff, 0x8a, 0x29, + 0x99, 0x47, 0xd7, 0xb0, 0xc5, 0x56, 0x91, 0x41, 0x91, 0x40, 0x7a, 0x35, + 0x21, 0xb2, 0x0a, 0x01, 0xdc, 0xde, 0xb8, 0xa6, 0x0b, 0xe7, 0x78, 0x03, + 0x5d, 0x51, 0xa5, 0xcb, 0x57, 0xa5, 0xbb, 0xbc, 0x14, 0xfc, 0xe5, 0x01, + 0x42, 0x95, 0xc9, 0x48, 0x30, 0x05, 0x51, 0x70, 0x4f, 0x1a, 0xb6, 0x58, + 0x4d, 0x99, 0x74, 0xdd, 0x69, 0xea, 0xa4, 0x6d, 0x5f, 0xa4, 0xad, 0x65, + 0xe1, 0xf3, 0xe0, 0x21, 0x0a, 0x7b, 0x43, 0x09, 0xeb, 0x0c, 0x67, 0x21, + 0x96, 0x24, 0x59, 0x8b, 0xcd, 0x83, 0x2d, 0x0b, 0x81, 0x73, 0x1b, 0x06, + 0x5f, 0x7c, 0xbb, 0xc5, 0x70, 0x55, 0xc1, 0xeb, 0xe0, 0xcc, 0x47, 0xc0, + 0xdf, 0x27, 0x05, 0xad, 0x91, 0x00, 0xa0, 0xca, 0xf2, 0x73, 0x43, 0x02, + 0x83, 0xba, 0xd9, 0xa1, 0x4c, 0x4b, 0xba, 0x51, 0xd0, 0x21, 0xf8, 0x53, + 0xf4, 0xa8, 0x3e, 0xc5, 0x84, 0x15, 0x4c, 0x17, 0x6c, 0x5d, 0x56, 0x91, + 0xc8, 0x83, 0xe3, 0x9a, 0x59, 0x18, 0xe4, 0xeb, 0x9f, 0x7f, 0xee, 0x26, + 0x3f, 0x77, 0xe0, 0xff, 0xe8, 0xd4, 0xfa, 0x19, 0x88, 0xee, 0xe7, 0x92, + 0xb7, 0xfc, 0xe7, 0xeb, 0x7e, 0x72, 0xe8, 0x20, 0x2b, 0x55, 0xa0, 0x46, + 0xeb, 0x1b, 0xa7, 0x3a, 0xa8, 0xbb, 0x83, 0xb1, 0x68, 0xbd, 0xdb, 0x2b, + 0x5e, 0x50, 0xce, 0xb7, 0x98, 0x15, 0xb3, 0x1e, 0x63, 0x6f, 0xc2, 0x8a, + 0x2d, 0xa6, 0x33, 0x8e, 0xb2, 0x15, 0xa2, 0xe4, 0x03, 0x42, 0xec, 0x74, + 0xe3, 0x77, 0x1b, 0x61, 0x13, 0x4d, 0xd9, 0x84, 0x2b, 0x5b, 0x9f, 0x89, + 0xb2, 0x83, 0xd9, 0x19, 0x6e, 0xa2, 0xc7, 0x29, 0xea, 0x96, 0x82, 0xcb, + 0x50, 0x38, 0x4b, 0x30, 0x02, 0x54, 0xcc, 0xaf, 0x6e, 0x2b, 0x94, 0x5f, + 0xec, 0x38, 0x26, 0x4b, 0xe7, 0x02, 0xcd, 0xd7, 0x51, 0x34, 0x9d, 0xe0, + 0x74, 0x57, 0x9a, 0xc7, 0xc0, 0xb9, 0x4c, 0x4c, 0x7a, 0xec, 0x84, 0x64, + 0xbf, 0xe3, 0xee, 0x4e, 0x32, 0xcd, 0x2e, 0x53, 0x81, 0xc3, 0xd8, 0xa4, + 0x1c, 0x08, 0x6e, 0x88, 0xe2, 0xae, 0xb6, 0x9a, 0xd9, 0x4c, 0x71, 0x62, + 0x56, 0x5d, 0x04, 0xfe, 0x88, 0x4c, 0x7d, 0x9a, 0xcf, 0x40, 0xa7, 0xec, + 0xf4, 0x3a, 0xf4, 0x55, 0x48, 0x5c, 0x22, 0xc6, 0x18, 0x33, 0x11, 0x97, + 0xdc, 0xa0, 0x7d, 0x84, 0x08, 0x79, 0xc9, 0xa8, 0x1e, 0x30, 0x5b, 0x0d, + 0xd0, 0xc3, 0x08, 0xca, 0x12, 0x14, 0x05, 0x9d, 0xbc, 0xa4, 0xbf, 0x62, + 0x56, 0x85, 0x49, 0x4d, 0xfa, 0x0e, 0x92, 0x6f, 0x70, 0x00, 0xf7, 0x7a, + 0x1c, 0x76, 0x47, 0x8b, 0xcb, 0xf2, 0x21, 0x07, 0x91, 0xdc, 0x22, 0x98, + 0xc3, 0x7c, 0x12, 0x80, 0xb4, 0xc3, 0x60, 0xb1, 0x4f, 0x0a, 0x38, 0xe4, + 0x48, 0x42, 0x86, 0xbb, 0x3f, 0x2f, 0xc8, 0xe5, 0x35, 0xa4, 0x38, 0x14, + 0x8c, 0xff, 0x51, 0x30, 0x08, 0xce, 0x27, 0x60, 0x08, 0xec, 0x07, 0x0d, + 0x08, 0xcb, 0x48, 0x3f, 0x40, 0x5c, 0xe3, 0x07, 0xbf, 0x83, 0x11, 0xf5, + 0xf4, 0x06, 0x4b, 0xc4, 0xe6, 0xd4, 0xa3, 0x2f, 0x6a, 0x93, 0x8e, 0x84, + 0x52, 0x42, 0x7b, 0xee, 0x16, 0xeb, 0xc0, 0xa7, 0x82, 0x61, 0x01, 0x5f, + 0x60, 0x07, 0xc8, 0x67, 0x04, 0xbf, 0x19, 0x5e, 0x80, 0xeb, 0xbb, 0x97, + 0x5e, 0xa2, 0xac, 0x08, 0x5f, 0x83, 0x84, 0x06, 0xea, 0x05, 0xfe, 0xb5, + 0x0d, 0x4a, 0x93, 0x0c, 0x00, 0xd7, 0x80, 0x20, 0xfb, 0xcd, 0x23, 0x89, + 0x13, 0xae, 0x8b, 0xa2, 0xb5, 0xbf, 0xe5, 0x04, 0x7e, 0xec, 0xa6, 0x77, + 0x0a, 0x3f, 0xc8, 0x0a, 0x0b, 0xaf, 0xcb, 0x84, 0x61, 0xbe, 0xb3, 0x82, + 0xf0, 0x71, 0x40, 0x30, 0x9b, 0x4c, 0x22, 0x30, 0xec, 0x4e, 0x98, 0xfa, + 0x8c, 0xb2, 0x2c, 0xb2, 0xe6, 0x0a, 0x48, 0x58, 0xa4, 0x45, 0x4a, 0xe2, + 0x5a, 0xcc, 0xd4, 0xd6, 0x03, 0x0b, 0xbf, 0x29, 0xd0, 0x73, 0x18, 0xc6, + 0xab, 0x52, 0x03, 0xab, 0x46, 0x5b, 0x9c, 0x08, 0xa5, 0xf1, 0x58, 0xea, + 0x21, 0x63, 0xad, 0x3b, 0xba, 0x49, 0x2c, 0xaa, 0x2c, 0x67, 0xe7, 0x29, + 0xdd, 0xc0, 0x18, 0x90, 0x85, 0x77, 0xcf, 0x0d, 0xe7, 0x2c, 0xcb, 0x0b, + 0xa6, 0x96, 0x73, 0x32, 0xe1, 0x85, 0x0f, 0x42, 0xd1, 0x47, 0x24, 0x75, + 0xa4, 0xe2, 0xfe, 0x33, 0x49, 0xe2, 0xb7, 0xc3, 0x6a, 0xfc, 0x4d, 0xd8, + 0xd1, 0x84, 0x50, 0xd9, 0x35, 0xdb, 0x9a, 0x64, 0x2e, 0xd5, 0x27, 0x77, + 0xb7, 0x92, 0xce, 0xff, 0x41, 0xc1, 0x73, 0x0c, 0x3c, 0x89, 0x2b, 0x50, + 0x0e, 0x3b, 0xf2, 0xed, 0x1e, 0x7e, 0xfb, 0x97, 0x67, 0x3f, 0xbe, 0x3b, + 0x3a, 0x7d, 0xfd, 0xfc, 0xe4, 0x47, 0x7e, 0x46, 0x1e, 0x49, 0x36, 0x7d, + 0xa0, 0x38, 0x86, 0xa2, 0xca, 0x4b, 0xfb, 0xf8, 0x52, 0x5b, 0x6b, 0x0f, + 0xb7, 0x34, 0xfc, 0xe6, 0x20, 0xe9, 0x10, 0x06, 0xeb, 0xd9, 0x9b, 0x53, + 0x44, 0xb1, 0xfb, 0x8f, 0x9f, 0x1b, 0x4f, 0x3e, 0x8a, 0x9e, 0x3c, 0x3c, + 0x3b, 0x7b, 0x76, 0x78, 0x71, 0xb8, 0xf4, 0xd4, 0xe3, 0xd5, 0xed, 0x1d, + 0x62, 0xa8, 0x85, 0xd8, 0xdc, 0x9e, 0x01, 0x51, 0x34, 0x5f, 0xfd, 0x7a, + 0x0b, 0x38, 0xc0, 0xac, 0x67, 0xaf, 0xa3, 0x55, 0xe0, 0x32, 0xab, 0xe7, + 0x37, 0x8b, 0x9c, 0xb8, 0x17, 0xd5, 0xf9, 0xc0, 0xb5, 0xbc, 0x2a, 0x7c, + 0x88, 0x9c, 0xbc, 0xfd, 0x64, 0x0b, 0x78, 0xa8, 0xc5, 0x12, 0x89, 0x91, + 0x31, 0xa7, 0xb8, 0x09, 0x52, 0x52, 0x80, 0xef, 0x49, 0x7f, 0xb6, 0x55, + 0x21, 0xa1, 0x80, 0xef, 0x18, 0xa5, 0x15, 0x86, 0x20, 0x19, 0x21, 0x76, + 0xc7, 0x75, 0xc6, 0xe7, 0xdc, 0x91, 0x54, 0x31, 0x33, 0x63, 0x45, 0x23, + 0x56, 0x8f, 0x99, 0xb2, 0xc5, 0xe2, 0x66, 0x1f, 0xb2, 0xe1, 0xa2, 0x56, + 0x34, 0x5f, 0xda, 0xf0, 0x51, 0x60, 0xf7, 0x21, 0x38, 0x0b, 0xc5, 0x04, + 0x65, 0xa9, 0xa2, 0x72, 0x1a, 0x09, 0x21, 0xfb, 0x57, 0x13, 0x3e, 0xdc, + 0x79, 0x36, 0x03, 0x33, 0x33, 0xbe, 0xe3, 0x4f, 0xba, 0x1a, 0x6d, 0xa6, + 0x9c, 0x8e, 0xea, 0x2f, 0xa0, 0x96, 0x75, 0x8a, 0x91, 0x7f, 0x1a, 0xc2, + 0x58, 0x45, 0xf1, 0xcd, 0xd2, 0x8b, 0x84, 0x2b, 0xc0, 0xdc, 0xa4, 0x31, + 0x32, 0x74, 0xf6, 0x03, 0xf5, 0x4b, 0x2a, 0xe7, 0xca, 0x2c, 0x4e, 0x95, + 0x3a, 0xc5, 0xec, 0x7e, 0x5f, 0x2e, 0xa7, 0xbf, 0xb6, 0xd6, 0x8e, 0x99, + 0x92, 0x63, 0xee, 0x54, 0x21, 0x49, 0xde, 0x84, 0x61, 0x60, 0x6a, 0xe6, + 0x53, 0x46, 0x71, 0xaa, 0x44, 0x40, 0x7f, 0x95, 0x7e, 0xc8, 0xa7, 0x8b, + 0x29, 0xe3, 0x45, 0x61, 0x8e, 0x38, 0x7f, 0x2b, 0xc6, 0x65, 0xbc, 0x2d, + 0x38, 0x90, 0x07, 0x87, 0xb4, 0x51, 0x79, 0xab, 0x13, 0xa5, 0xfc, 0xc2, + 0xc5, 0xd5, 0xf7, 0xb1, 0xe2, 0x8c, 0x7d, 0x30, 0xcd, 0x03, 0x7c, 0xb7, + 0x19, 0xa9, 0xe6, 0xa0, 0xcd, 0x64, 0x8a, 0xcb, 0xc4, 0xa8, 0x5d, 0x56, + 0xaf, 0x43, 0xaa, 0x30, 0xd8, 0x55, 0xc2, 0x62, 0x2d, 0xec, 0x69, 0x5e, + 0x8c, 0xf8, 0xfa, 0xe0, 0xdc, 0x27, 0xe0, 0x63, 0xec, 0x96, 0x25, 0xa7, + 0x3b, 0x01, 0x46, 0xb7, 0xc5, 0xaa, 0x23, 0x48, 0x24, 0x16, 0x24, 0x01, + 0xbd, 0x3d, 0x9f, 0x1a, 0xfc, 0x45, 0x5f, 0xed, 0xa0, 0xee, 0x43, 0xc1, + 0x15, 0xe5, 0x2b, 0xbf, 0x61, 0x50, 0xd4, 0xa0, 0x0f, 0x10, 0xc2, 0x10, + 0xd8, 0xa8, 0xbf, 0x45, 0x37, 0xb7, 0xbe, 0x6e, 0xd2, 0x2e, 0x2c, 0x32, + 0xdf, 0x8d, 0x1c, 0x24, 0x87, 0x4e, 0x19, 0x8b, 0x5d, 0x24, 0x27, 0x21, + 0xb1, 0x49, 0xce, 0x84, 0x66, 0xc3, 0xc5, 0x40, 0x4d, 0x34, 0x7a, 0x91, + 0x04, 0x28, 0x11, 0x67, 0xaf, 0x75, 0x6b, 0x47, 0x4b, 0xc7, 0x2c, 0x13, + 0x48, 0x13, 0x53, 0xaf, 0xb2, 0x51, 0xc8, 0xcf, 0x76, 0x29, 0x3f, 0xcf, + 0x5e, 0x9f, 0x27, 0x82, 0x5f, 0x18, 0x8c, 0xc3, 0xaa, 0xbe, 0xe2, 0x3b, + 0x17, 0x58, 0xe1, 0x88, 0xad, 0xbd, 0x24, 0xda, 0x27, 0x7f, 0x7a, 0x7b, + 0x72, 0x94, 0xb8, 0x0a, 0x29, 0x8a, 0xc7, 0x80, 0xe9, 0xb4, 0xfd, 0x24, + 0x0a, 0x6e, 0x6a, 0x10, 0xd2, 0xc7, 0x45, 0x39, 0xc5, 0x17, 0x43, 0x4c, + 0xf6, 0xd5, 0x32, 0xdd, 0x47, 0x3d, 0xed, 0xed, 0xb4, 0x92, 0xfe, 0x9d, + 0xef, 0xec, 0xf7, 0x77, 0x1f, 0xae, 0x77, 0x60, 0xa6, 0xe9, 0x07, 0x7a, + 0x6b, 0xf9, 0xc4, 0x14, 0xc9, 0xd3, 0x17, 0xa7, 0xe7, 0x17, 0xbb, 0x07, + 0x67, 0xa7, 0x6f, 0xe0, 0x27, 0xfe, 0xbe, 0x47, 0xbf, 0xef, 0xc9, 0xe1, + 0x41, 0x54, 0x33, 0x9f, 0x5d, 0x8c, 0xc6, 0x2c, 0x0a, 0xdb, 0x1c, 0x8b, + 0x2f, 0x3d, 0x49, 0x3a, 0xae, 0x85, 0x0e, 0x28, 0x1e, 0x39, 0x7a, 0x0f, + 0xa5, 0x87, 0x10, 0x4c, 0xd3, 0x71, 0x6d, 0x77, 0x34, 0x1c, 0xb4, 0x11, + 0x8e, 0xad, 0xc7, 0xcb, 0x22, 0x38, 0xa0, 0xcb, 0x94, 0x11, 0x20, 0x83, + 0x4f, 0x4b, 0x93, 0x92, 0x03, 0xf1, 0x50, 0xf5, 0x2d, 0x01, 0x76, 0x7a, + 0x7d, 0x7a, 0x91, 0xa4, 0x64, 0x44, 0x48, 0xe4, 0x7e, 0xe0, 0x4a, 0x48, + 0xdb, 0xec, 0xc4, 0xe1, 0x02, 0x14, 0x4e, 0x1e, 0xd7, 0xcc, 0x75, 0x9a, + 0x0f, 0xd0, 0xcc, 0x36, 0xe5, 0x70, 0xa0, 0xcf, 0x0a, 0x56, 0xf0, 0xf5, + 0x49, 0x37, 0xf2, 0x35, 0x79, 0x57, 0xd1, 0x56, 0x48, 0x16, 0x52, 0xa0, + 0x91, 0xd4, 0x5d, 0x6a, 0x06, 0x50, 0xab, 0x84, 0xc0, 0xab, 0xd4, 0x21, + 0x72, 0xed, 0xc8, 0x5a, 0x29, 0x98, 0x0f, 0xd6, 0x16, 0xba, 0x15, 0x5f, + 0x2f, 0xd0, 0x96, 0x62, 0x8d, 0xa0, 0x72, 0x82, 0xe3, 0x97, 0x18, 0xb1, + 0x5b, 0xcd, 0xd7, 0x86, 0x89, 0xf0, 0x3c, 0xfa, 0xba, 0xac, 0x1d, 0x39, + 0x06, 0x1d, 0x59, 0x5e, 0xb6, 0xcc, 0x30, 0x50, 0x57, 0xe8, 0xc0, 0x7a, + 0xd0, 0xf4, 0x2d, 0xee, 0x66, 0x51, 0x69, 0x1a, 0x3a, 0xed, 0x31, 0x66, + 0xc9, 0x94, 0xf9, 0x25, 0xa1, 0xcd, 0x59, 0xb1, 0x29, 0x8a, 0x82, 0x70, + 0x1d, 0x6b, 0x62, 0x46, 0x78, 0x22, 0xa8, 0x83, 0xf5, 0x52, 0x76, 0x01, + 0x85, 0x08, 0x97, 0xaa, 0xed, 0xf0, 0x28, 0xba, 0x09, 0xf1, 0x49, 0xb3, + 0xe9, 0x2b, 0x8f, 0x9a, 0xa6, 0xb5, 0xe0, 0x59, 0x71, 0xec, 0x87, 0x25, + 0xf3, 0x1a, 0x09, 0x22, 0x96, 0x92, 0x61, 0xab, 0xd3, 0xec, 0x28, 0x68, + 0x44, 0x1a, 0xe2, 0x72, 0x31, 0xc8, 0xbd, 0x2c, 0xd1, 0xab, 0xb3, 0xbb, + 0xf7, 0x75, 0x1f, 0xa1, 0xc3, 0x60, 0xc9, 0x35, 0x04, 0x44, 0x8a, 0x76, + 0xd0, 0xf2, 0x4a, 0x90, 0x89, 0xbe, 0x20, 0xfb, 0xa5, 0x27, 0xaa, 0x28, + 0xa9, 0xfc, 0x4d, 0x74, 0x89, 0x39, 0x08, 0x39, 0xc7, 0xe2, 0x7d, 0xb6, + 0x61, 0x38, 0x8e, 0x49, 0x58, 0xa3, 0x70, 0x1a, 0x6c, 0x44, 0x71, 0x5c, + 0x19, 0xca, 0xbf, 0x6e, 0x99, 0x49, 0x71, 0x68, 0x9e, 0xfe, 0xc2, 0x37, + 0x7e, 0x70, 0x60, 0x2d, 0x1d, 0x24, 0xed, 0x90, 0xdd, 0x6b, 0x0f, 0x9c, + 0x21, 0x8a, 0x42, 0xe9, 0x30, 0xda, 0x8e, 0x30, 0x52, 0x4d, 0xf2, 0xff, + 0xe8, 0xe1, 0x2e, 0x8d, 0xb1, 0x7d, 0x88, 0xd1, 0x3b, 0xde, 0xf0, 0xf2, + 0x5b, 0xb0, 0x22, 0x56, 0xac, 0xda, 0xc3, 0x87, 0xfb, 0x07, 0xfa, 0x37, + 0xf0, 0x93, 0x83, 0x27, 0xf0, 0xc1, 0xbd, 0x79, 0x97, 0x2b, 0xc1, 0x23, + 0xd8, 0x43, 0xa0, 0xcc, 0xf5, 0xa8, 0x1b, 0x67, 0x32, 0x27, 0x4f, 0x8b, + 0xf1, 0x18, 0x6e, 0x89, 0xef, 0xcc, 0xaf, 0xb0, 0xc0, 0x03, 0x65, 0x69, + 0x8d, 0x0e, 0xe6, 0xd2, 0x22, 0x87, 0x58, 0x38, 0x20, 0x84, 0xc8, 0x84, + 0xdf, 0x16, 0x45, 0xc3, 0xe5, 0xbb, 0xf0, 0xe7, 0xe6, 0x4c, 0x84, 0xf1, + 0x0e, 0x8d, 0xc1, 0x91, 0xe3, 0xcb, 0x41, 0xe2, 0xd3, 0x85, 0x57, 0xbd, + 0xcf, 0xe7, 0x73, 0x52, 0x9a, 0xa8, 0x5e, 0x4f, 0x8c, 0x2c, 0x80, 0x4d, + 0x84, 0x58, 0x37, 0x0b, 0x33, 0xa0, 0xe4, 0x61, 0x96, 0x91, 0x07, 0xd9, + 0xb8, 0x28, 0xb5, 0x40, 0x86, 0x07, 0xeb, 0x34, 0xa2, 0x66, 0x9f, 0x26, + 0x42, 0xb1, 0xa4, 0xcc, 0x96, 0x4f, 0xc6, 0xbc, 0x83, 0x64, 0x64, 0x12, + 0xb0, 0x05, 0xbe, 0x3a, 0x43, 0x46, 0x7b, 0xb0, 0x84, 0x9e, 0x9f, 0xfc, + 0xf7, 0x71, 0x14, 0x53, 0xaa, 0xb9, 0xd5, 0xa4, 0x2b, 0x87, 0x24, 0xcc, + 0xa4, 0xd3, 0x3b, 0x4a, 0x7a, 0x1d, 0x05, 0x79, 0x47, 0xc8, 0x77, 0x8b, + 0xb9, 0x8e, 0x3d, 0x3c, 0xa4, 0x25, 0x08, 0xe6, 0x1e, 0x08, 0x14, 0xdb, + 0x57, 0x20, 0xe5, 0xe9, 0x60, 0x19, 0xb0, 0x2d, 0x4e, 0x00, 0x0f, 0x25, + 0xfa, 0x2c, 0xc3, 0x88, 0x77, 0x82, 0xd5, 0xea, 0xed, 0x7c, 0x86, 0xca, + 0x35, 0xa3, 0xa0, 0x58, 0x43, 0x63, 0xc6, 0x04, 0x61, 0x30, 0xc7, 0x85, + 0xe5, 0x17, 0x7b, 0x0a, 0x68, 0x4d, 0x3c, 0xf8, 0xb4, 0x18, 0x95, 0x86, + 0x20, 0x01, 0x0b, 0x71, 0xaf, 0xe0, 0x70, 0x94, 0x3c, 0xdc, 0xd9, 0x59, + 0x93, 0xae, 0x31, 0x19, 0x5f, 0x09, 0x79, 0xc0, 0x84, 0x5c, 0xbc, 0xcf, + 0xb3, 0xe4, 0x29, 0xba, 0x54, 0xfe, 0x57, 0x1b, 0x80, 0xcf, 0x56, 0x12, + 0xdf, 0xe1, 0x6c, 0xd1, 0x47, 0x3d, 0x26, 0xa9, 0x26, 0x28, 0x0b, 0xe2, + 0x7d, 0x6e, 0x25, 0xdf, 0x12, 0x69, 0x4f, 0xc1, 0x79, 0x65, 0x09, 0xb5, + 0x94, 0x84, 0x4d, 0x96, 0x38, 0xfa, 0x01, 0xc5, 0xb6, 0x46, 0xe4, 0x6d, + 0x30, 0xa5, 0xf8, 0xbe, 0x41, 0xf2, 0x70, 0x1a, 0xb3, 0xd0, 0x93, 0xa8, + 0x72, 0x12, 0x00, 0xc3, 0xdd, 0xc9, 0x09, 0xc5, 0xfd, 0xd5, 0x90, 0x0e, + 0x58, 0x5a, 0x42, 0x7f, 0xc4, 0x06, 0x5d, 0x86, 0xb1, 0x15, 0x1b, 0x30, + 0x66, 0xae, 0xb6, 0x47, 0x6d, 0x3c, 0x4d, 0x3a, 0xe7, 0x59, 0xdd, 0xe3, + 0x96, 0x0f, 0x3a, 0x49, 0x28, 0x7a, 0x28, 0x7e, 0x27, 0xc9, 0x48, 0x1a, + 0x98, 0x6a, 0x28, 0x51, 0xd6, 0x72, 0xaf, 0x60, 0x21, 0xd3, 0xdd, 0x6f, + 0xff, 0x7c, 0xf8, 0xf2, 0xed, 0xf1, 0xee, 0x1f, 0x40, 0x60, 0x81, 0x3f, + 0xf7, 0xf8, 0xcf, 0x3d, 0x04, 0x5f, 0xfb, 0x89, 0x03, 0xc8, 0x99, 0x01, + 0x70, 0xb1, 0xd1, 0x5a, 0x02, 0x20, 0x15, 0x4b, 0x45, 0x23, 0xff, 0x71, + 0x00, 0x48, 0x41, 0x6c, 0x56, 0x9b, 0x17, 0xf3, 0xc5, 0x84, 0x23, 0xd8, + 0x50, 0x37, 0xb1, 0x95, 0xe6, 0xb9, 0x6b, 0xf4, 0x39, 0xe7, 0x01, 0x68, + 0x19, 0x0d, 0x0d, 0xcb, 0x51, 0xc4, 0xfe, 0x9c, 0xb3, 0x1a, 0x02, 0x56, + 0x81, 0xde, 0xba, 0x9b, 0x95, 0x24, 0xd3, 0x98, 0xff, 0x46, 0xe1, 0x55, + 0x9d, 0xa7, 0x93, 0xf0, 0x69, 0x46, 0x0b, 0xb6, 0x05, 0xc6, 0x09, 0xd8, + 0x5d, 0x35, 0x7a, 0x90, 0x13, 0x97, 0x6f, 0xa0, 0xca, 0x03, 0xa7, 0xf2, + 0x41, 0xb8, 0xd5, 0xb4, 0xb4, 0x89, 0x14, 0xe3, 0x20, 0xe1, 0xc1, 0x6d, + 0x21, 0x51, 0x04, 0x39, 0x26, 0x4c, 0x7b, 0x06, 0x32, 0xc1, 0x81, 0xa1, + 0x2d, 0xb3, 0xf3, 0x6d, 0x27, 0xa9, 0x6e, 0xa7, 0x83, 0x62, 0xe2, 0x7c, + 0x95, 0xa6, 0xda, 0x87, 0x38, 0x6c, 0x81, 0xe3, 0x50, 0x29, 0x54, 0xc1, + 0x9f, 0x9c, 0x45, 0xd6, 0xcc, 0x9a, 0xe6, 0xc9, 0xf1, 0x59, 0xe8, 0x35, + 0x81, 0x74, 0xc8, 0xc0, 0xd8, 0xa7, 0xe3, 0xd2, 0xe2, 0x55, 0x43, 0xc3, + 0x23, 0x45, 0x20, 0xd1, 0xa9, 0x19, 0xb6, 0x75, 0x4f, 0x24, 0xc4, 0x57, + 0xc2, 0xfa, 0x3c, 0x1c, 0x09, 0x86, 0xb7, 0x58, 0x68, 0xfd, 0x0c, 0x0e, + 0x29, 0x83, 0x5d, 0xeb, 0x56, 0xf3, 0x1b, 0x24, 0xdd, 0x0d, 0x32, 0xd2, + 0x69, 0x6e, 0x13, 0x43, 0xb4, 0x21, 0xad, 0xc6, 0xa5, 0x47, 0x87, 0x08, + 0xc1, 0x62, 0x3a, 0x10, 0xa6, 0x1c, 0xe8, 0x80, 0x62, 0x84, 0x27, 0x56, + 0xba, 0xd1, 0xce, 0x2f, 0x0a, 0x48, 0xe8, 0xce, 0x0b, 0x9e, 0x3a, 0x2e, + 0x3f, 0xe0, 0x01, 0xb2, 0xaa, 0xc8, 0x33, 0xc4, 0xd6, 0xb8, 0x25, 0x7b, + 0xb9, 0xac, 0xa0, 0x80, 0x57, 0xb0, 0x29, 0x9a, 0x8d, 0xc2, 0xc9, 0x66, + 0xa7, 0xd7, 0xd9, 0x32, 0x6f, 0x70, 0x3a, 0xaa, 0xa2, 0x7a, 0x14, 0x55, + 0x13, 0xf1, 0x26, 0x38, 0x5b, 0x82, 0xb9, 0x39, 0x67, 0x28, 0x6e, 0x2f, + 0x3a, 0x43, 0xb3, 0x98, 0x8a, 0x24, 0xa1, 0x3d, 0xe1, 0xec, 0x92, 0x4e, + 0x21, 0x4b, 0x4f, 0x2c, 0x5c, 0xcf, 0xcc, 0x3d, 0xbb, 0x63, 0x15, 0x60, + 0x55, 0xf4, 0x96, 0x7d, 0xf0, 0x2a, 0xac, 0xa6, 0xd7, 0x62, 0x16, 0x45, + 0xe1, 0x06, 0xc9, 0xb1, 0xa8, 0xe9, 0xc8, 0x5e, 0x92, 0xe9, 0x18, 0x6f, + 0x40, 0x23, 0x90, 0xee, 0x0f, 0xf1, 0x2f, 0x8b, 0x33, 0xd8, 0x0c, 0xec, + 0x05, 0x45, 0xf6, 0xdb, 0x49, 0xb6, 0x65, 0x52, 0x6b, 0xf2, 0x3a, 0xab, + 0xc9, 0x23, 0xb2, 0xfd, 0xaa, 0xf8, 0x47, 0x3e, 0x99, 0xa4, 0xda, 0xbe, + 0xcb, 0x33, 0x91, 0x14, 0xe1, 0xe6, 0x20, 0x83, 0x80, 0x2e, 0x5e, 0x54, + 0x5d, 0x91, 0xca, 0x92, 0xc4, 0xd9, 0xb3, 0x38, 0xa3, 0x82, 0x1f, 0xc9, + 0xeb, 0x42, 0x87, 0xae, 0xee, 0xc9, 0x8c, 0x0c, 0xe2, 0x75, 0x36, 0x63, + 0x11, 0x3f, 0x95, 0x44, 0x24, 0xaa, 0x09, 0x24, 0x21, 0xa6, 0x46, 0xa9, + 0xaa, 0x54, 0x58, 0x3f, 0xbd, 0x5f, 0x35, 0x8e, 0xc1, 0xb0, 0x7f, 0x1f, + 0x38, 0xd8, 0x62, 0x7d, 0xde, 0xcd, 0x5d, 0xa2, 0xa9, 0x79, 0x6d, 0x19, + 0x16, 0x5e, 0xe0, 0x91, 0xd5, 0x05, 0x20, 0xa8, 0x7f, 0x51, 0xae, 0x69, + 0xb8, 0x63, 0x2c, 0x26, 0x99, 0xe0, 0xf7, 0x08, 0xd0, 0x89, 0x45, 0x14, + 0x86, 0x0a, 0x04, 0x9d, 0x83, 0xc0, 0xe2, 0x51, 0xdf, 0x60, 0xcb, 0x89, + 0x5c, 0xe8, 0xe9, 0x68, 0x24, 0x41, 0x21, 0x94, 0x2b, 0x8d, 0x01, 0xf3, + 0xfa, 0x0e, 0xba, 0xd1, 0xc3, 0x00, 0xc9, 0xaf, 0xb2, 0xc9, 0x10, 0x5c, + 0xbc, 0x1c, 0x02, 0xff, 0x2b, 0x2b, 0x56, 0x2d, 0x06, 0xfc, 0x5e, 0x45, + 0x1b, 0xc8, 0x56, 0x39, 0xac, 0x20, 0x78, 0x60, 0xd3, 0xd5, 0xed, 0x6c, + 0x6c, 0x1a, 0x46, 0xce, 0x56, 0x5c, 0xf5, 0x97, 0x03, 0xcd, 0x59, 0x18, + 0x1f, 0x14, 0xb0, 0x71, 0x31, 0x55, 0x69, 0x29, 0x03, 0x67, 0xc7, 0x66, + 0xd7, 0x91, 0x98, 0x22, 0xe6, 0x23, 0xae, 0xb5, 0xa4, 0xcf, 0xa3, 0x27, + 0x2c, 0xa0, 0xaf, 0xb0, 0xc3, 0xa4, 0x2a, 0x94, 0x6d, 0x70, 0x0f, 0x81, + 0x36, 0x7c, 0xe6, 0x7c, 0xd8, 0xc6, 0xc8, 0xe4, 0x19, 0x15, 0xbe, 0x60, + 0x5d, 0x6f, 0x1a, 0xed, 0x6e, 0x9c, 0x27, 0x40, 0xb4, 0x77, 0x86, 0x3a, + 0xf6, 0x19, 0xd6, 0x76, 0x18, 0x26, 0xe7, 0x04, 0xb0, 0x9e, 0xbc, 0xcc, + 0xab, 0x7a, 0x4b, 0xc3, 0x75, 0xd8, 0xae, 0x3f, 0xca, 0x6a, 0xbc, 0x25, + 0x82, 0x95, 0x67, 0x94, 0xc3, 0x5a, 0x95, 0xa3, 0x2a, 0x4c, 0xde, 0x20, + 0x3d, 0x9b, 0xc5, 0x6a, 0x49, 0x97, 0x63, 0xec, 0x76, 0xa5, 0x92, 0xca, + 0x69, 0xfd, 0x72, 0x0c, 0x25, 0x67, 0x98, 0xed, 0x7f, 0xac, 0xb9, 0x52, + 0xea, 0xa0, 0x9e, 0xf3, 0x68, 0xfc, 0x5c, 0xd4, 0x16, 0x27, 0xe1, 0xbc, + 0xbb, 0x34, 0x95, 0x68, 0xd4, 0x16, 0xd1, 0x90, 0xa4, 0x9a, 0xc6, 0x4c, + 0xf2, 0x4a, 0x5d, 0xcc, 0x29, 0xe2, 0x9a, 0x2a, 0x38, 0x2a, 0x1f, 0x89, + 0x96, 0xf6, 0xd3, 0x95, 0x9e, 0x86, 0x50, 0x38, 0x40, 0x94, 0xc1, 0xfb, + 0xa4, 0xc2, 0x81, 0x8c, 0x62, 0x65, 0xdc, 0xdf, 0xca, 0x87, 0x7b, 0xc3, + 0x8f, 0x7b, 0x95, 0xca, 0xcc, 0xfd, 0x57, 0x3a, 0x5b, 0x37, 0xbc, 0x30, + 0xd0, 0x19, 0xab, 0x57, 0xbf, 0x2e, 0x66, 0xef, 0x7b, 0x52, 0x66, 0xa1, + 0x17, 0x58, 0x30, 0x2d, 0xdd, 0xb0, 0x1b, 0xbf, 0xf1, 0xb4, 0x5d, 0x44, + 0x35, 0x8f, 0x65, 0xa1, 0x57, 0x28, 0x8d, 0xdd, 0xf2, 0x38, 0xe4, 0xf2, + 0x35, 0x38, 0x7c, 0xd2, 0x84, 0x63, 0xee, 0x47, 0x98, 0x91, 0x1e, 0x32, + 0x32, 0x09, 0xd8, 0x6b, 0x7d, 0x8c, 0x78, 0x9f, 0x58, 0xd9, 0x24, 0x7a, + 0x3d, 0x3e, 0xa0, 0x28, 0x92, 0xe9, 0xa5, 0xde, 0x63, 0x84, 0x46, 0x27, + 0x0b, 0x03, 0xef, 0x24, 0x4c, 0x6d, 0x2b, 0x88, 0x26, 0xe2, 0x9f, 0x9c, + 0x69, 0x0d, 0x81, 0x4e, 0x28, 0x72, 0x55, 0xf3, 0xc6, 0x43, 0x65, 0x85, + 0x3e, 0x16, 0x31, 0xe6, 0x18, 0xc9, 0x59, 0x11, 0x3a, 0xc6, 0x73, 0xf1, + 0x7e, 0x56, 0xdc, 0x50, 0x21, 0x36, 0xe7, 0x92, 0x12, 0x39, 0x07, 0x8e, + 0xbd, 0xb7, 0x83, 0xd5, 0x04, 0xf3, 0x73, 0x4d, 0x70, 0xb7, 0xb7, 0x89, + 0xf8, 0x0c, 0xe0, 0x5a, 0x30, 0x70, 0xcd, 0x78, 0x42, 0x7a, 0xcf, 0x2d, + 0xc1, 0x5d, 0x98, 0xe6, 0x64, 0xac, 0x6d, 0xe8, 0xd8, 0xb9, 0xc2, 0x57, + 0x08, 0xd7, 0x27, 0xd9, 0xd6, 0xdf, 0xeb, 0xe6, 0xb3, 0x8d, 0x25, 0x86, + 0x2e, 0xfa, 0x91, 0xbb, 0xee, 0x92, 0xae, 0x9a, 0xd7, 0x91, 0xd4, 0x04, + 0xbb, 0xe7, 0xd2, 0x6b, 0xb0, 0xb1, 0xc8, 0xdc, 0x48, 0x15, 0x56, 0xa5, + 0xda, 0x15, 0x5c, 0x7e, 0xd1, 0x8d, 0x2f, 0x91, 0xc7, 0xa9, 0x03, 0xc1, + 0x0a, 0x57, 0x1f, 0x07, 0xfa, 0xac, 0xbc, 0xf8, 0xa2, 0x4b, 0x2f, 0xf9, + 0x01, 0x19, 0xac, 0x22, 0x03, 0x7b, 0x90, 0x69, 0x63, 0xa8, 0x1e, 0x65, + 0xe3, 0xe2, 0x2a, 0xaf, 0x5a, 0x4b, 0x4d, 0xdf, 0x23, 0xba, 0xf0, 0x6d, + 0x44, 0x72, 0x65, 0x03, 0xae, 0xa3, 0x1c, 0x19, 0x90, 0x81, 0x63, 0x73, + 0x17, 0xe4, 0x0f, 0xd7, 0x46, 0xbc, 0x00, 0x1b, 0x3a, 0xd2, 0xd8, 0xc1, + 0x86, 0x9c, 0x27, 0x2f, 0xe1, 0x7a, 0x4a, 0xe5, 0x6f, 0xe4, 0xa8, 0x4a, + 0x64, 0x52, 0xf7, 0x8a, 0x37, 0x89, 0x37, 0xf0, 0xe6, 0xaa, 0x98, 0x44, + 0xbe, 0xb1, 0x46, 0x05, 0x04, 0xc6, 0xe6, 0xc7, 0xf2, 0x48, 0x14, 0x11, + 0x43, 0x94, 0xcd, 0x11, 0x83, 0x2c, 0xf0, 0x51, 0xd1, 0x4c, 0x84, 0x7d, + 0x2e, 0xd1, 0x31, 0x15, 0x67, 0x67, 0x0b, 0xd8, 0x30, 0xa3, 0xbd, 0xa6, + 0x70, 0xb4, 0x4b, 0x4e, 0xdd, 0x93, 0xca, 0x1a, 0x5a, 0x43, 0x59, 0x2e, + 0x6b, 0xa6, 0x53, 0x26, 0x81, 0xeb, 0x1c, 0x41, 0x30, 0x95, 0x90, 0xb3, + 0x6c, 0xc4, 0x17, 0x25, 0x71, 0x88, 0x4b, 0x42, 0xe1, 0x66, 0xf0, 0x7e, + 0x91, 0xac, 0x0d, 0x34, 0x13, 0xe3, 0x46, 0xae, 0x30, 0x1c, 0xa3, 0xca, + 0xeb, 0x85, 0x30, 0x83, 0xd8, 0xa5, 0xe0, 0xc9, 0xed, 0xee, 0x54, 0x15, + 0x67, 0x02, 0xf8, 0x78, 0x97, 0xc2, 0x90, 0x45, 0xb0, 0x1e, 0xf9, 0xfc, + 0x57, 0xb9, 0xd2, 0xee, 0x7c, 0x01, 0x58, 0x35, 0x92, 0x72, 0x0f, 0x46, + 0x52, 0x7d, 0x14, 0xaf, 0x5e, 0x83, 0x4f, 0xf7, 0x98, 0x20, 0x7a, 0xa0, + 0xf9, 0x55, 0xce, 0x9f, 0x6f, 0x0a, 0x1a, 0x48, 0xfe, 0xbf, 0x8a, 0x11, + 0xc0, 0x29, 0x28, 0x5a, 0x64, 0x23, 0x44, 0x69, 0x48, 0x79, 0x2c, 0x6a, + 0xcc, 0x21, 0x3d, 0xcd, 0x32, 0xcc, 0xef, 0x4f, 0xcb, 0x5b, 0xf1, 0x4e, + 0x79, 0x44, 0x80, 0xab, 0x1c, 0xd6, 0xb9, 0x1c, 0x5e, 0x11, 0x7e, 0x0a, + 0x19, 0x9a, 0xb3, 0x51, 0x3f, 0x36, 0x5a, 0xc8, 0x19, 0xe1, 0x56, 0x65, + 0x2b, 0xb4, 0x05, 0x62, 0x79, 0xa8, 0x36, 0xc2, 0x73, 0xb8, 0x6f, 0xb1, + 0xfe, 0xa4, 0xe3, 0x8b, 0x1b, 0x22, 0x75, 0xcb, 0x78, 0x0e, 0x03, 0x2d, + 0x60, 0xb2, 0x61, 0xa0, 0x1a, 0xda, 0x63, 0x91, 0xc3, 0xb9, 0x0d, 0x5c, + 0x9a, 0xbe, 0xc6, 0xdc, 0x66, 0x8d, 0x86, 0xa4, 0x1b, 0xd3, 0x7e, 0x88, + 0xc9, 0xce, 0x8a, 0x28, 0xb3, 0x90, 0x4b, 0xc9, 0x36, 0xc7, 0x6e, 0x11, + 0xbf, 0x32, 0x85, 0x10, 0xf6, 0x2b, 0xd0, 0x94, 0xb3, 0x22, 0x9a, 0x2a, + 0x79, 0x9c, 0x05, 0xa6, 0x52, 0xf6, 0xfb, 0x48, 0xce, 0x72, 0xb4, 0x22, + 0xf8, 0xdc, 0x34, 0x1d, 0x69, 0x56, 0xfb, 0x94, 0x0a, 0x8b, 0xee, 0x7c, + 0xfd, 0x68, 0x87, 0x42, 0xe3, 0xdf, 0x12, 0x0c, 0x34, 0xaa, 0x2e, 0x1e, + 0xab, 0x80, 0x53, 0xee, 0x82, 0xfa, 0x54, 0xe8, 0x9a, 0x1b, 0xc4, 0x5c, + 0xdc, 0x07, 0x3b, 0xfd, 0x54, 0x34, 0x45, 0x93, 0x21, 0xe9, 0x41, 0x18, + 0xe0, 0xda, 0x25, 0x65, 0xf4, 0x56, 0x4f, 0xd9, 0xb8, 0x9e, 0x7b, 0x0a, + 0xeb, 0x37, 0xf2, 0x6b, 0xc2, 0x37, 0xab, 0xe2, 0x4f, 0x3f, 0x36, 0xbd, + 0xc6, 0xf5, 0x75, 0xb7, 0xfd, 0xd9, 0x75, 0x6d, 0xd4, 0x62, 0x08, 0x07, + 0xdb, 0xeb, 0x27, 0x5d, 0x34, 0x66, 0x28, 0x47, 0xce, 0x91, 0x4e, 0xe3, + 0xa0, 0x61, 0xcb, 0x3d, 0xda, 0x95, 0xa7, 0xf8, 0x53, 0xc5, 0x21, 0x82, + 0x12, 0xc5, 0x28, 0x61, 0x0c, 0xc3, 0x10, 0xb8, 0x54, 0x93, 0x70, 0xd9, + 0xd5, 0x82, 0xd6, 0x77, 0xde, 0x15, 0x36, 0x74, 0x6a, 0xd9, 0x41, 0xd9, + 0x08, 0x55, 0xa9, 0x2d, 0xf0, 0x3e, 0x80, 0xc3, 0xb8, 0xa2, 0x8c, 0x51, + 0x32, 0x3f, 0x4a, 0xd7, 0xcc, 0x6b, 0x29, 0x1f, 0x97, 0x4b, 0x9e, 0xa9, + 0x14, 0x4d, 0xd2, 0xd8, 0x06, 0x8e, 0x71, 0x43, 0xbe, 0xb0, 0x00, 0x56, + 0x0e, 0x7a, 0xad, 0x85, 0x4a, 0xc8, 0x21, 0x4f, 0x00, 0xf3, 0x0e, 0x92, + 0x35, 0x9c, 0x15, 0x0d, 0xc1, 0xd9, 0x79, 0xfc, 0xf0, 0x61, 0x74, 0x7d, + 0x06, 0xcb, 0x06, 0xf9, 0xf2, 0xc9, 0xfd, 0x3b, 0xa3, 0x39, 0x0c, 0x6b, + 0x64, 0xdc, 0x56, 0x94, 0x9e, 0x7c, 0x45, 0x66, 0x25, 0xea, 0x27, 0x31, + 0x1f, 0x6f, 0x2e, 0xeb, 0x5d, 0x79, 0x87, 0x6d, 0xbc, 0xdc, 0x2c, 0xdb, + 0x6b, 0xe4, 0x6c, 0x34, 0xfb, 0xda, 0xf9, 0xfa, 0xeb, 0xaf, 0x93, 0xde, + 0x05, 0x13, 0x0e, 0xcb, 0x35, 0xcb, 0x31, 0xcc, 0xb3, 0xec, 0x66, 0x0d, + 0x80, 0xc8, 0xe6, 0x49, 0x09, 0x64, 0x33, 0x19, 0x7b, 0x34, 0xdd, 0x57, + 0x02, 0xbb, 0x7f, 0x8d, 0xb9, 0x41, 0x2c, 0x79, 0x8c, 0xd5, 0x47, 0x07, + 0x4a, 0x58, 0x99, 0x93, 0xc0, 0x5a, 0x66, 0xf5, 0xa2, 0x9c, 0x25, 0xf3, + 0xc9, 0xa2, 0xf2, 0x0f, 0xa9, 0xa4, 0x2b, 0x36, 0x7f, 0xba, 0xa5, 0xb3, + 0xf1, 0x62, 0x22, 0xb9, 0xb4, 0xaf, 0xfe, 0x7c, 0x9e, 0x6c, 0x9e, 0x9e, + 0x6f, 0xef, 0x7f, 0x43, 0x60, 0x43, 0x8d, 0xb3, 0x3a, 0x19, 0x7f, 0x26, + 0xfc, 0x39, 0x68, 0xe9, 0xbe, 0x75, 0x86, 0xbe, 0x60, 0x59, 0x59, 0x32, + 0x5d, 0x23, 0x28, 0x1c, 0xb6, 0x8e, 0x8b, 0x22, 0x44, 0xcb, 0x86, 0x6f, + 0x2f, 0xc3, 0xc7, 0xc9, 0xb4, 0xb2, 0x24, 0x28, 0xe7, 0xc2, 0xc8, 0x28, + 0xeb, 0xca, 0x90, 0x3a, 0xa4, 0xa2, 0x4c, 0x9c, 0xac, 0xa9, 0xae, 0xa2, + 0x6b, 0x35, 0xcf, 0xa1, 0x7a, 0xcc, 0x62, 0x0b, 0xda, 0xfe, 0x0c, 0xd8, + 0x00, 0xe1, 0x7b, 0xe2, 0xec, 0x65, 0xd3, 0x88, 0x7d, 0xbc, 0x87, 0x0b, + 0xa9, 0x90, 0x2c, 0x49, 0xf3, 0x52, 0xc8, 0xf8, 0xbf, 0x64, 0x1a, 0xad, + 0x74, 0x51, 0x66, 0xbf, 0xa2, 0x3a, 0xff, 0x31, 0xd0, 0x48, 0x94, 0x98, + 0x26, 0x59, 0x43, 0x84, 0x0e, 0x13, 0xd6, 0x9d, 0x92, 0x88, 0xda, 0xf2, + 0xcb, 0xb2, 0x3a, 0x60, 0x8e, 0xcb, 0x53, 0x52, 0x90, 0x5b, 0x4b, 0xd2, + 0xa1, 0x87, 0xdf, 0xaa, 0xf6, 0x59, 0x84, 0xc1, 0xd4, 0xec, 0xe1, 0xe9, + 0x10, 0xc5, 0x64, 0x32, 0xea, 0x14, 0x09, 0xa2, 0x4b, 0x3c, 0x79, 0xb8, + 0xb7, 0xd7, 0x4d, 0x1e, 0x21, 0x80, 0xbc, 0x81, 0x24, 0x85, 0x6c, 0xa3, + 0x25, 0xa4, 0xa4, 0x00, 0xde, 0xcc, 0x5e, 0x0f, 0x2d, 0x6b, 0xaf, 0xa5, + 0x22, 0x0e, 0x3a, 0x12, 0x60, 0xd0, 0xf9, 0xcb, 0xde, 0xa3, 0x47, 0xbb, + 0xdf, 0x1c, 0x9c, 0xf5, 0x1e, 0xed, 0xed, 0x76, 0xb6, 0x44, 0x0e, 0x0f, + 0x91, 0xdb, 0xcb, 0x08, 0x18, 0x49, 0x3e, 0x62, 0x9b, 0x3a, 0xe5, 0x2c, + 0xaa, 0x65, 0xdb, 0x12, 0x4e, 0x3b, 0xd5, 0x3b, 0xce, 0xa9, 0xb4, 0x78, + 0x80, 0xea, 0x1d, 0x3b, 0x2e, 0x3a, 0x22, 0x46, 0x12, 0xd4, 0x91, 0x33, + 0x61, 0xda, 0x4a, 0x0a, 0x93, 0x06, 0x42, 0xb4, 0xd6, 0x3e, 0x0a, 0xd0, + 0x88, 0xe6, 0x46, 0x4e, 0x9a, 0x89, 0xa4, 0x2c, 0x27, 0x9b, 0xc7, 0x47, + 0x5b, 0xbc, 0x05, 0x51, 0x7c, 0x8e, 0x82, 0x25, 0xf3, 0x48, 0xbb, 0x52, + 0xf2, 0xc0, 0x6e, 0x96, 0x59, 0x31, 0x23, 0x2b, 0x33, 0x06, 0x0c, 0xa0, + 0x62, 0x4e, 0x4f, 0x6d, 0x8b, 0xfb, 0x45, 0x53, 0xff, 0xbc, 0xaf, 0x68, + 0xb9, 0xc2, 0xc1, 0x32, 0xb6, 0x91, 0x4c, 0x92, 0x72, 0x02, 0xd9, 0x0e, + 0x45, 0x75, 0xa0, 0x75, 0xae, 0xc1, 0xc0, 0x69, 0x90, 0x47, 0x7c, 0x3a, + 0xf8, 0xb5, 0xd6, 0x38, 0xa0, 0xa5, 0x40, 0xa0, 0x4f, 0x83, 0x0d, 0xe3, + 0x1e, 0x98, 0x10, 0xd6, 0xc4, 0xfc, 0xdd, 0x6f, 0xb0, 0x74, 0xcd, 0x2c, + 0x94, 0xb3, 0x31, 0xea, 0x6a, 0x35, 0x26, 0x72, 0xda, 0x79, 0x43, 0x08, + 0x55, 0x4e, 0xc5, 0x33, 0x32, 0x13, 0x8b, 0x7b, 0x50, 0x8f, 0xa5, 0x38, + 0x36, 0x82, 0x61, 0x60, 0x11, 0x3d, 0x0d, 0xb6, 0xf0, 0x1e, 0x36, 0xef, + 0x08, 0xeb, 0x46, 0x36, 0xc0, 0x9b, 0xf4, 0x56, 0x18, 0x4f, 0x32, 0x28, + 0x81, 0x8c, 0xb0, 0xe6, 0x62, 0x41, 0x29, 0x9e, 0x04, 0xd7, 0xc2, 0xb7, + 0x3e, 0xf2, 0x6f, 0x60, 0x04, 0x93, 0x50, 0x2e, 0x00, 0xef, 0xe1, 0x17, + 0x17, 0xaf, 0x5e, 0x4a, 0xed, 0x2b, 0x46, 0xda, 0xc0, 0x9c, 0x1b, 0x71, + 0x07, 0x54, 0x8b, 0xc1, 0x34, 0xc7, 0x0d, 0xab, 0x6b, 0x4b, 0x57, 0xd2, + 0xbb, 0xbc, 0xa9, 0xdb, 0x3a, 0x57, 0x61, 0x12, 0x70, 0xfa, 0xe5, 0x6f, + 0x4d, 0x5c, 0x72, 0x95, 0xbe, 0xcd, 0xd9, 0x40, 0x89, 0xab, 0x42, 0x00, + 0x21, 0x7e, 0x67, 0xfb, 0x43, 0xef, 0xe6, 0xe6, 0xa6, 0x87, 0x03, 0xc3, + 0x30, 0x71, 0x01, 0x06, 0xe9, 0x63, 0xed, 0xf3, 0xb9, 0x70, 0xd7, 0x1e, + 0x7d, 0x1b, 0x0e, 0x12, 0x76, 0xda, 0x2b, 0xd3, 0x1b, 0x2d, 0x8d, 0x46, + 0x95, 0x1e, 0x1c, 0x8e, 0x23, 0xd7, 0xcd, 0x70, 0x45, 0xba, 0x19, 0xa5, + 0x2c, 0x15, 0xdb, 0xa5, 0x86, 0xd4, 0x59, 0xb6, 0x60, 0x5a, 0x87, 0xea, + 0x49, 0xc9, 0xf7, 0xbe, 0x38, 0x0c, 0x08, 0xce, 0x58, 0x28, 0x57, 0x7c, + 0x97, 0x8b, 0x12, 0x85, 0x33, 0xf4, 0xef, 0xa0, 0x16, 0x80, 0x1a, 0xab, + 0x6c, 0x14, 0xdb, 0x38, 0xad, 0x12, 0x8e, 0x33, 0x4c, 0xd0, 0x50, 0xf9, + 0x8d, 0x60, 0x99, 0x40, 0x71, 0xfc, 0xed, 0x9b, 0x97, 0x02, 0x82, 0xe2, + 0x98, 0x3e, 0x93, 0x33, 0x25, 0x3a, 0xd0, 0x46, 0x01, 0xbd, 0x4c, 0xb8, + 0x28, 0x13, 0xde, 0x45, 0xd8, 0xac, 0xb4, 0x68, 0x0b, 0xe5, 0x8e, 0xa6, + 0x54, 0x66, 0x63, 0x9d, 0x52, 0xed, 0x1e, 0x2a, 0x6b, 0x86, 0xdc, 0x03, + 0x2a, 0x9e, 0x55, 0x78, 0xd8, 0xcb, 0xa5, 0x38, 0x52, 0x11, 0xab, 0x78, + 0x6f, 0xe7, 0x79, 0x46, 0xa0, 0xe6, 0x81, 0x80, 0xc9, 0x0a, 0x3c, 0xcd, + 0xca, 0x4b, 0x4d, 0x43, 0x11, 0xe7, 0xa9, 0xb2, 0x60, 0x6e, 0xe8, 0x7f, + 0xf6, 0xd8, 0x3f, 0x48, 0xbc, 0x76, 0x41, 0x38, 0xd4, 0x4c, 0x13, 0x1b, + 0x58, 0x69, 0x8d, 0x2c, 0x95, 0xa3, 0x74, 0x06, 0x13, 0x4c, 0xa8, 0xf4, + 0x5a, 0xf5, 0x1e, 0x08, 0xf6, 0xdb, 0x49, 0xb1, 0xa8, 0x6e, 0x37, 0x12, + 0xa9, 0x6a, 0xc9, 0x0d, 0x71, 0x5d, 0xaf, 0x9a, 0x02, 0x39, 0x70, 0x2f, + 0x86, 0x57, 0xa0, 0xfd, 0x4a, 0x8a, 0x07, 0x41, 0x80, 0x52, 0xb2, 0xcb, + 0x86, 0x6b, 0xf1, 0x7f, 0xfa, 0xc6, 0x1a, 0xde, 0x0f, 0x29, 0x6f, 0x55, + 0x9b, 0x0f, 0x39, 0x80, 0x6f, 0x4b, 0x5e, 0xca, 0xf7, 0xc2, 0xd1, 0x4a, + 0x0a, 0x81, 0x72, 0x6e, 0x24, 0x87, 0x30, 0xa6, 0x0e, 0x4b, 0x32, 0x48, + 0x59, 0x5b, 0x68, 0xb1, 0x62, 0x04, 0xd0, 0x9e, 0x7a, 0x0a, 0x83, 0xc9, + 0xd3, 0xbc, 0x54, 0x41, 0x8e, 0xd6, 0x77, 0x12, 0xf5, 0xbd, 0x9d, 0x49, + 0x51, 0x66, 0xff, 0x95, 0xda, 0x13, 0x05, 0xcd, 0x74, 0x5c, 0x14, 0x83, + 0xb4, 0xdc, 0x88, 0x56, 0x08, 0x2b, 0x8c, 0xe0, 0x08, 0xc9, 0x2b, 0x2c, + 0x62, 0x19, 0xb5, 0xf0, 0x3d, 0x3f, 0xdd, 0xd7, 0x5a, 0x60, 0xcc, 0x7a, + 0xf0, 0x9a, 0x9e, 0x8c, 0x82, 0xbf, 0x15, 0xfb, 0xd1, 0x3c, 0x7a, 0xae, + 0x2d, 0x20, 0xd9, 0x43, 0x88, 0x11, 0xd8, 0x94, 0x40, 0x61, 0x23, 0x41, + 0xfc, 0x45, 0x2a, 0xa9, 0x24, 0x91, 0x03, 0xa3, 0xbb, 0x24, 0x91, 0xc5, + 0xfc, 0xd3, 0xe8, 0x25, 0xc4, 0x08, 0x18, 0x0e, 0xd3, 0x90, 0xa5, 0x17, + 0xa7, 0x12, 0x2d, 0x49, 0xe3, 0xa4, 0x99, 0x3f, 0x40, 0xeb, 0x98, 0xac, + 0x38, 0xa3, 0xee, 0x08, 0xe0, 0xf9, 0xd7, 0xd8, 0x46, 0x0f, 0x4c, 0x40, + 0x2b, 0xc7, 0x4e, 0xbc, 0x38, 0x9f, 0x56, 0xfc, 0xd9, 0x49, 0x31, 0xb3, + 0x5a, 0xaf, 0xc2, 0xad, 0xec, 0x32, 0x5d, 0xc2, 0x78, 0x2a, 0x66, 0x49, + 0x94, 0xe0, 0x27, 0x11, 0x08, 0xcc, 0x07, 0x43, 0xc5, 0xc2, 0x21, 0x4b, + 0xef, 0x5d, 0xa9, 0x22, 0x19, 0xe2, 0x15, 0xf3, 0x29, 0x36, 0x95, 0x71, + 0xc2, 0xe6, 0x89, 0xc0, 0xcf, 0xcc, 0xad, 0xfc, 0x45, 0xd0, 0xd2, 0xe6, + 0x2a, 0xc2, 0x06, 0xc2, 0x8c, 0xa2, 0x2b, 0xb4, 0xf8, 0x39, 0x31, 0x42, + 0xdd, 0xc9, 0xcf, 0xe5, 0xc5, 0x18, 0x25, 0x1d, 0x3a, 0x3d, 0xf8, 0xd7, + 0xfd, 0xee, 0x8c, 0xf8, 0x69, 0xfc, 0xb3, 0x2e, 0x8a, 0xc9, 0xb7, 0xc3, + 0xe9, 0x08, 0x3b, 0x5a, 0xe7, 0xfd, 0xef, 0xed, 0x08, 0xad, 0xbe, 0x86, + 0x2f, 0x96, 0xa0, 0x6c, 0xa7, 0x8b, 0x5a, 0x10, 0x24, 0xb0, 0xec, 0x1c, + 0xe8, 0x41, 0x84, 0x9f, 0xad, 0xc6, 0x66, 0xab, 0x8e, 0x78, 0x45, 0x87, + 0xcc, 0xbb, 0xd3, 0x5c, 0xd9, 0x0c, 0xc5, 0xa2, 0x13, 0x8b, 0x6b, 0xc4, + 0x9f, 0xbb, 0xe1, 0x6e, 0x31, 0xf6, 0x1a, 0x37, 0xa4, 0x74, 0x67, 0xb2, + 0x31, 0x7d, 0x40, 0x6a, 0xca, 0xb2, 0x04, 0xb0, 0x04, 0x18, 0xcb, 0x75, + 0xa4, 0xa8, 0xa8, 0x68, 0x8e, 0xfa, 0x2f, 0x12, 0x29, 0x37, 0xd1, 0x8f, + 0x9b, 0x0a, 0xe5, 0x79, 0x3e, 0x47, 0x5c, 0x9e, 0x6b, 0xf8, 0xfb, 0xf5, + 0x8d, 0x20, 0xd1, 0xba, 0xb8, 0x13, 0x27, 0x55, 0x62, 0x9a, 0x77, 0x90, + 0x5b, 0x0e, 0xb9, 0xec, 0x5a, 0xd6, 0xe3, 0x8c, 0xae, 0x69, 0xa2, 0x5c, + 0x77, 0xe2, 0x7c, 0x76, 0x23, 0x6d, 0x66, 0x48, 0x08, 0x57, 0x34, 0x51, + 0xbb, 0x53, 0xb0, 0x88, 0x77, 0x55, 0xe0, 0x62, 0x7c, 0x31, 0xae, 0x0e, + 0xba, 0xc2, 0xf7, 0xbd, 0x8e, 0x0f, 0x14, 0x59, 0xe6, 0xf1, 0xca, 0xae, + 0x9f, 0xf1, 0x39, 0xad, 0xe8, 0x5e, 0xf2, 0xc2, 0x56, 0x62, 0x79, 0x69, + 0x08, 0x16, 0x3a, 0x93, 0xba, 0xcd, 0x5a, 0xb9, 0x13, 0xf9, 0x86, 0x95, + 0x4e, 0x14, 0x0b, 0xb9, 0xf1, 0xd4, 0x40, 0x6f, 0xc6, 0x79, 0x85, 0xf1, + 0xd2, 0xbd, 0x8b, 0x52, 0x1b, 0x32, 0x2d, 0xf6, 0x2d, 0x30, 0xdf, 0xa9, + 0xac, 0xc0, 0x25, 0xfb, 0xd9, 0x29, 0xda, 0x5e, 0xd6, 0xe7, 0x25, 0xb1, + 0x72, 0xed, 0x39, 0x86, 0xf1, 0xf5, 0x62, 0x99, 0xf8, 0xee, 0x83, 0x24, + 0xa7, 0x82, 0x9c, 0x29, 0x46, 0xf7, 0x4b, 0x6c, 0x5a, 0xd0, 0x57, 0xdd, + 0xe8, 0x41, 0x86, 0xf0, 0x1a, 0xb2, 0x0b, 0xfe, 0x81, 0x31, 0x0f, 0xf2, + 0xba, 0x24, 0xd9, 0x48, 0x65, 0x24, 0x7e, 0x41, 0x35, 0x17, 0x1d, 0x05, + 0x87, 0x0a, 0xaa, 0x0f, 0x2b, 0xe0, 0xb1, 0x86, 0xe1, 0x8b, 0x33, 0x2b, + 0x11, 0x73, 0x53, 0x86, 0x50, 0x3b, 0xd0, 0xd3, 0xf4, 0x80, 0x3f, 0xea, + 0xbd, 0xe0, 0x7f, 0x3b, 0x47, 0xf2, 0xd6, 0x05, 0xbc, 0x75, 0xb0, 0x3c, + 0x35, 0xff, 0x6a, 0xe7, 0xe3, 0x2a, 0xbb, 0xb1, 0x87, 0x03, 0xc3, 0x4f, + 0x42, 0x4e, 0xad, 0xa5, 0xb3, 0x5a, 0x4f, 0xe8, 0x58, 0xe4, 0x39, 0x72, + 0xfe, 0x87, 0x66, 0x3d, 0x21, 0xb7, 0x57, 0x6e, 0xd0, 0x38, 0x4a, 0x9a, + 0x08, 0xe4, 0x0a, 0x80, 0xfd, 0x66, 0x86, 0x20, 0x4d, 0xaf, 0xc3, 0x89, + 0x9b, 0x5c, 0x21, 0x36, 0xcb, 0x18, 0x67, 0xb8, 0xfb, 0xc0, 0xeb, 0x81, + 0x98, 0xdc, 0x4a, 0xfa, 0xaa, 0xec, 0xf3, 0xa2, 0x4e, 0x42, 0xf4, 0x0f, + 0x6f, 0xf9, 0x47, 0x8a, 0xe8, 0x7e, 0x0c, 0x51, 0x12, 0xf9, 0x72, 0x75, + 0x99, 0x8f, 0xbc, 0x16, 0x43, 0xbb, 0x1d, 0xac, 0x4b, 0x5e, 0xdc, 0x7f, + 0xb5, 0xb9, 0x37, 0xbe, 0x4f, 0x6b, 0xfc, 0x5f, 0x67, 0xfd, 0x85, 0x8d, + 0x97, 0x34, 0x5c, 0x41, 0x77, 0x2e, 0x6c, 0x37, 0x70, 0x1a, 0x95, 0x29, + 0x38, 0x0b, 0x48, 0x57, 0x58, 0x15, 0x01, 0x73, 0x90, 0xa8, 0xfd, 0x1d, + 0xb9, 0x8f, 0x15, 0xc2, 0x26, 0xf2, 0x9e, 0x67, 0x25, 0x9e, 0xe9, 0x2a, + 0xe8, 0x26, 0x58, 0x5c, 0x30, 0xb8, 0x10, 0x90, 0x04, 0x8f, 0x7e, 0x3c, + 0x21, 0xc0, 0x06, 0xb8, 0xc2, 0x66, 0xb5, 0xe8, 0x09, 0x3c, 0x40, 0xd4, + 0x0b, 0xcb, 0x00, 0x12, 0x4f, 0x11, 0xce, 0x41, 0x3b, 0x08, 0x1e, 0x67, + 0x0b, 0x4e, 0x64, 0x24, 0xc4, 0x90, 0xf9, 0x44, 0xf2, 0x55, 0x6a, 0x28, + 0x2b, 0x66, 0x5b, 0x12, 0x57, 0xdf, 0x45, 0xe8, 0x4a, 0x41, 0x25, 0x11, + 0x34, 0x4e, 0x2c, 0x42, 0x2c, 0xdb, 0xa1, 0xc5, 0x14, 0x37, 0x82, 0x35, + 0x0d, 0x67, 0x39, 0x0f, 0x47, 0xb2, 0xba, 0x9d, 0xd5, 0xe9, 0x87, 0xac, + 0xd2, 0xac, 0x4f, 0x8d, 0xcf, 0xfc, 0xea, 0xc1, 0x03, 0xa7, 0x92, 0x79, + 0xb8, 0x17, 0xd6, 0x96, 0x45, 0xe7, 0xa5, 0xea, 0xc3, 0xfd, 0xe4, 0xbf, + 0x14, 0xd9, 0x11, 0x98, 0x34, 0x9b, 0x5b, 0xd1, 0xc5, 0xff, 0x60, 0x09, + 0x2a, 0x26, 0xe8, 0xa0, 0x5a, 0x97, 0x82, 0x5c, 0xfe, 0x18, 0x3d, 0x09, + 0x33, 0xee, 0x7c, 0xaf, 0x41, 0x94, 0xa8, 0x1e, 0xa1, 0xf0, 0xf9, 0x40, + 0x0c, 0x8f, 0xef, 0x45, 0x31, 0xe7, 0xd1, 0x4a, 0xa6, 0x86, 0x9b, 0x0f, + 0xef, 0xf1, 0x30, 0x45, 0x05, 0x7e, 0x90, 0xc1, 0xd4, 0xfe, 0x87, 0x4c, + 0xe7, 0xdb, 0xd5, 0xf3, 0xb1, 0x41, 0xd1, 0x42, 0xd3, 0x84, 0xf8, 0xee, + 0xb1, 0xd5, 0x0d, 0xc9, 0xfa, 0x38, 0x42, 0x68, 0x41, 0x22, 0x3c, 0x25, + 0x24, 0x47, 0x42, 0xae, 0x0c, 0x2e, 0x43, 0x88, 0x96, 0x6d, 0x49, 0x24, + 0x11, 0xde, 0xbf, 0x96, 0xb4, 0x69, 0x8d, 0x01, 0x90, 0x23, 0x37, 0xaa, + 0xd3, 0x06, 0xa4, 0xf2, 0x80, 0xb8, 0x12, 0x3d, 0x8e, 0x28, 0x78, 0x1f, + 0x80, 0x18, 0x6a, 0x2b, 0xfa, 0x1d, 0x5a, 0x1f, 0xa9, 0x93, 0x4d, 0x07, + 0x62, 0x1c, 0x0d, 0x47, 0x41, 0x75, 0xfb, 0x84, 0x01, 0xb9, 0x94, 0x91, + 0x28, 0xe6, 0xc3, 0x55, 0x79, 0xe3, 0xcd, 0xd1, 0xab, 0x78, 0xab, 0xdb, + 0x9c, 0x47, 0x5a, 0x2b, 0xeb, 0x56, 0x8a, 0xc8, 0xd9, 0x85, 0xa2, 0xe6, + 0x41, 0x34, 0xe8, 0xf4, 0xa5, 0x34, 0x22, 0xc9, 0x11, 0xd0, 0xc2, 0x3a, + 0x92, 0x84, 0x5b, 0xc4, 0x7f, 0xc7, 0xf8, 0xfd, 0xf0, 0x43, 0x71, 0x36, + 0x1e, 0xfc, 0x85, 0xa5, 0x03, 0xe1, 0xda, 0x43, 0x0b, 0x5c, 0xce, 0x55, + 0x3d, 0x39, 0x8c, 0x55, 0xc1, 0xc0, 0x9d, 0x04, 0x57, 0xa1, 0x97, 0x1a, + 0x65, 0x3b, 0x48, 0xb0, 0xff, 0xa4, 0x96, 0xba, 0xcc, 0x14, 0x16, 0x4b, + 0x3b, 0xf9, 0x6d, 0x10, 0x14, 0xd8, 0xdb, 0xa2, 0x18, 0x50, 0x0e, 0x9c, + 0xda, 0xa5, 0x22, 0xa1, 0xb8, 0xac, 0x7b, 0x8e, 0xa7, 0xe2, 0xbe, 0x5d, + 0x5f, 0x62, 0x9a, 0x9f, 0x4b, 0x35, 0x6a, 0xb6, 0x4b, 0x73, 0xb9, 0xc6, + 0x7c, 0xad, 0xb5, 0xae, 0x82, 0xf0, 0xe2, 0xb7, 0xfc, 0x2f, 0x31, 0xda, + 0x8f, 0x7d, 0xd7, 0xe8, 0xe2, 0xa3, 0xdf, 0xa4, 0xb7, 0x28, 0xec, 0x62, + 0xed, 0x6b, 0xc8, 0x8b, 0xf8, 0x91, 0xae, 0x93, 0x4d, 0xb2, 0x4b, 0xbe, + 0x86, 0x9f, 0xbe, 0x3c, 0xfe, 0xf3, 0xf1, 0x4b, 0xbd, 0x92, 0x7e, 0x3c, + 0x3f, 0xdf, 0x7e, 0x9f, 0x95, 0x83, 0xac, 0x2c, 0x2a, 0xf6, 0x0a, 0xd0, + 0xd7, 0x24, 0xac, 0x87, 0xaa, 0x02, 0x2e, 0xf0, 0x4f, 0x5a, 0xd2, 0x54, + 0x53, 0x4d, 0x4c, 0x83, 0x11, 0x19, 0x2e, 0x5d, 0x89, 0x8e, 0x48, 0x32, + 0xc0, 0xa7, 0x21, 0xaf, 0x0f, 0xf1, 0x93, 0xf1, 0x54, 0x3c, 0x63, 0x3b, + 0x02, 0xa7, 0x12, 0x23, 0xc9, 0x87, 0xa1, 0xe9, 0xa3, 0x73, 0x42, 0x39, + 0xa5, 0x87, 0xa5, 0x33, 0xc2, 0xf1, 0xc1, 0xa9, 0xd1, 0x6a, 0x88, 0xfb, + 0xfe, 0xf4, 0x8f, 0xbd, 0xc3, 0xf3, 0xde, 0xb3, 0xe3, 0x97, 0xc7, 0x3f, + 0x1e, 0x5e, 0x1c, 0x5b, 0x6d, 0x48, 0x92, 0x33, 0xf9, 0x54, 0x40, 0x0b, + 0x7f, 0x94, 0xb9, 0x59, 0x05, 0xbc, 0x3a, 0xe7, 0xca, 0xd7, 0x56, 0x77, + 0x24, 0x45, 0x06, 0x5d, 0x73, 0x2e, 0x10, 0x90, 0xe5, 0x64, 0x2a, 0xfd, + 0xeb, 0x68, 0xd2, 0xc9, 0x4d, 0x7a, 0x5b, 0x11, 0x5b, 0x9c, 0x61, 0x42, + 0x74, 0x6e, 0xa8, 0x3b, 0x3c, 0x07, 0x87, 0xb5, 0xe5, 0x96, 0xc7, 0x49, + 0x9f, 0xd1, 0xea, 0xaf, 0xef, 0x0e, 0xbd, 0x3f, 0xb2, 0xa5, 0x49, 0xec, + 0xa1, 0x97, 0x0e, 0xae, 0xf6, 0x9a, 0xd2, 0x8b, 0x82, 0xfe, 0x0b, 0xe9, + 0x54, 0xd5, 0x24, 0x50, 0x0d, 0x95, 0x7b, 0x8b, 0x84, 0x17, 0xc3, 0xcb, + 0xe2, 0x5c, 0x92, 0x67, 0xf4, 0x44, 0xd2, 0xc8, 0x62, 0xb0, 0xb0, 0x91, + 0xf8, 0x63, 0x91, 0x7e, 0x87, 0x57, 0x19, 0x26, 0x76, 0xa1, 0x37, 0xa3, + 0xd2, 0xfc, 0x96, 0x18, 0xa2, 0x9d, 0x0b, 0xdb, 0x71, 0x14, 0x14, 0xd6, + 0x93, 0xc5, 0xed, 0xa4, 0x48, 0xa6, 0x84, 0x50, 0x9e, 0xfa, 0x21, 0xc5, + 0x49, 0xe3, 0xf7, 0xe3, 0xd8, 0x7d, 0x17, 0x4f, 0x32, 0xa3, 0xfa, 0x4f, + 0x5a, 0x3f, 0x30, 0xd4, 0xc4, 0x2b, 0x9c, 0x1f, 0x02, 0xbf, 0xb2, 0xec, + 0x4d, 0x1b, 0x44, 0x23, 0x38, 0x82, 0xd7, 0xe2, 0x33, 0xc5, 0x45, 0x58, + 0xa1, 0xd6, 0x8f, 0xa9, 0x69, 0x27, 0x23, 0xf8, 0x34, 0xab, 0x4b, 0x8b, + 0xd1, 0x45, 0x8a, 0x06, 0x4b, 0x7d, 0xbf, 0xd8, 0x58, 0x12, 0x2a, 0x06, + 0x37, 0xfc, 0xba, 0x65, 0x80, 0x2b, 0x94, 0xf1, 0x30, 0xd9, 0x48, 0x45, + 0x5a, 0x25, 0x9d, 0xbf, 0x77, 0x03, 0xfe, 0x80, 0x1d, 0x04, 0x83, 0x87, + 0x0a, 0x38, 0x41, 0xce, 0x8b, 0xd7, 0x6a, 0xad, 0xeb, 0x06, 0x80, 0x88, + 0xd2, 0xf2, 0x79, 0x02, 0x1e, 0x49, 0xa8, 0x5b, 0x9c, 0x52, 0x0c, 0x1d, + 0x43, 0x8d, 0x90, 0x91, 0xa8, 0x96, 0x50, 0x3d, 0x7e, 0x18, 0x6b, 0xe4, + 0x09, 0x24, 0xa5, 0x15, 0x90, 0x8b, 0x1c, 0x5f, 0x1e, 0xe4, 0xa4, 0xca, + 0x30, 0x0e, 0x8a, 0x42, 0x91, 0xe2, 0xca, 0x6f, 0x86, 0x9b, 0xf2, 0x39, + 0xfc, 0xee, 0x01, 0x9d, 0x61, 0x35, 0x11, 0xfc, 0x7d, 0xdd, 0xf0, 0x32, + 0x1c, 0xbd, 0x3b, 0xb6, 0xd4, 0x72, 0x2f, 0x9b, 0x97, 0x75, 0x88, 0x55, + 0xd8, 0x0a, 0x60, 0x71, 0x12, 0x62, 0x62, 0x89, 0x18, 0xc7, 0x67, 0x6f, + 0x2e, 0x58, 0x2e, 0x7a, 0x49, 0xbf, 0xc9, 0x16, 0x88, 0x63, 0x8a, 0x8b, + 0x67, 0xab, 0xcf, 0x97, 0x4a, 0xd0, 0x51, 0x8c, 0x91, 0x25, 0xb9, 0x68, + 0x58, 0xef, 0x4c, 0x6b, 0xad, 0xc9, 0xde, 0x22, 0x5b, 0x9d, 0xce, 0xeb, + 0xe0, 0x58, 0xa6, 0x8e, 0xd4, 0x38, 0x46, 0x59, 0x92, 0x2c, 0xeb, 0x63, + 0x36, 0xb6, 0x54, 0x2e, 0x0c, 0xc9, 0x57, 0x1a, 0xca, 0x96, 0xd7, 0x1c, + 0xc6, 0x85, 0x0f, 0x25, 0xa5, 0xc0, 0x3d, 0x02, 0x4b, 0x16, 0x2e, 0x40, + 0x63, 0xd7, 0x24, 0x17, 0x85, 0x64, 0x0e, 0xea, 0x94, 0x66, 0x68, 0xd3, + 0x88, 0x35, 0xf0, 0xa6, 0x2b, 0x69, 0x12, 0x99, 0xaf, 0x78, 0x45, 0xc9, + 0xf2, 0x1c, 0x86, 0xa3, 0xa6, 0x0b, 0xa9, 0x9e, 0x25, 0x30, 0xce, 0x15, + 0xfb, 0x61, 0x34, 0x09, 0x2f, 0xe5, 0xa0, 0x75, 0xb6, 0x18, 0x0d, 0xc8, + 0x4e, 0x25, 0x0d, 0xa5, 0x52, 0xa0, 0x46, 0x72, 0x26, 0xf5, 0xc6, 0xe0, + 0x19, 0xc8, 0xda, 0x06, 0xd9, 0x07, 0x77, 0x29, 0xd6, 0x7d, 0x29, 0x09, + 0xd7, 0x72, 0xcd, 0xb8, 0x73, 0x99, 0xa8, 0x60, 0x61, 0x72, 0x11, 0x0e, + 0x20, 0xa2, 0xb0, 0xc5, 0xbc, 0x04, 0x6c, 0x9d, 0x14, 0xe3, 0xa4, 0x23, + 0x83, 0x46, 0x30, 0xaa, 0x66, 0xe9, 0x55, 0x84, 0x8f, 0xe1, 0x2a, 0xfe, + 0x9c, 0x9c, 0x5d, 0x3f, 0x8e, 0xa3, 0x92, 0x0c, 0xe5, 0x91, 0xc1, 0x02, + 0xd4, 0xc8, 0xae, 0xcb, 0x1e, 0x22, 0x0a, 0x91, 0xd3, 0x6b, 0x37, 0x4c, + 0x69, 0xd8, 0x20, 0x3d, 0xc7, 0xa1, 0xa3, 0x6c, 0x5e, 0x17, 0x9f, 0xa5, + 0x10, 0xd2, 0x20, 0xbb, 0x4a, 0xaf, 0x73, 0x84, 0xb6, 0x54, 0xfb, 0x93, + 0x66, 0x71, 0xc8, 0x65, 0x01, 0x04, 0x31, 0xa4, 0xea, 0x03, 0xc8, 0x08, + 0xf1, 0x0d, 0x0a, 0xf4, 0x51, 0xe8, 0x2a, 0x5a, 0x2b, 0x49, 0x81, 0x95, + 0xa0, 0x1d, 0x0a, 0x80, 0x2d, 0x08, 0x96, 0x78, 0xe8, 0x70, 0x11, 0xe5, + 0xdc, 0xd1, 0x13, 0x69, 0x75, 0xdd, 0x28, 0xef, 0xed, 0x97, 0x2a, 0x69, + 0x2b, 0xf2, 0xfd, 0x49, 0x3c, 0x7e, 0x79, 0xf9, 0x57, 0x5c, 0xdc, 0xbe, + 0xf7, 0x75, 0xe2, 0x6b, 0xc2, 0x0b, 0xd5, 0xb5, 0xf0, 0x5f, 0x9d, 0x7a, + 0x0b, 0x13, 0xa8, 0xae, 0xdb, 0x98, 0x80, 0xf2, 0x00, 0x55, 0x4a, 0x8f, + 0xcf, 0xce, 0xff, 0x6c, 0x27, 0x9f, 0x0f, 0x3e, 0x67, 0xec, 0xe8, 0xc2, + 0xe3, 0x11, 0x6a, 0x64, 0xb7, 0xc9, 0xc1, 0xb7, 0x73, 0x2f, 0x07, 0x7f, + 0xe9, 0xdc, 0x53, 0xdb, 0x72, 0xe2, 0x93, 0xb3, 0xc3, 0xf3, 0x3f, 0x0b, + 0xb2, 0x82, 0x9d, 0xf8, 0xe6, 0x81, 0x37, 0xe7, 0x4c, 0x0d, 0x84, 0x85, + 0x6f, 0xfb, 0xe3, 0x02, 0x73, 0x5e, 0xeb, 0xb8, 0x40, 0x9f, 0xcb, 0xc7, + 0x45, 0x17, 0xe3, 0xae, 0xe3, 0x02, 0xe4, 0xb1, 0xea, 0xb8, 0xe0, 0x4b, + 0x78, 0x46, 0x28, 0xfd, 0x3f, 0x3e, 0x28, 0x76, 0x01, 0xe8, 0x41, 0xe1, + 0x31, 0x84, 0x4c, 0xed, 0x7b, 0x4f, 0x0a, 0x0c, 0x98, 0x53, 0xf0, 0xe4, + 0xa0, 0x98, 0x4c, 0x14, 0x9f, 0x14, 0x35, 0x9b, 0xaf, 0x3a, 0x29, 0x7a, + 0xb6, 0x24, 0xd8, 0x94, 0x8c, 0xba, 0x76, 0x58, 0x78, 0xcf, 0x1d, 0xbd, + 0xb4, 0x40, 0x91, 0x46, 0xe4, 0xb5, 0x0a, 0x68, 0xbd, 0x89, 0x44, 0x7a, + 0x3f, 0x14, 0x69, 0xdb, 0x02, 0xdf, 0x77, 0x20, 0x60, 0x00, 0x1f, 0x77, + 0x20, 0x2c, 0x10, 0xaa, 0xf5, 0x40, 0xa0, 0xc0, 0xde, 0x53, 0x71, 0x0f, + 0x24, 0xdf, 0x9e, 0x05, 0xd7, 0x1f, 0x7f, 0xc8, 0x85, 0x16, 0x39, 0x70, + 0x1e, 0x95, 0x0c, 0xf5, 0x39, 0x32, 0x86, 0x9e, 0xd8, 0x80, 0x04, 0x08, + 0x48, 0x1b, 0xe1, 0xf5, 0x1b, 0x60, 0xb6, 0x9a, 0xa0, 0x85, 0xa0, 0x75, + 0x6f, 0xc1, 0x61, 0x7c, 0x56, 0x30, 0x1c, 0xdf, 0xa7, 0xdc, 0xae, 0x8c, + 0x4e, 0x94, 0x15, 0xa1, 0xa9, 0x93, 0x12, 0x11, 0x06, 0xa6, 0x84, 0x34, + 0xa9, 0xc6, 0x40, 0xb9, 0xd8, 0x9a, 0xfc, 0xa9, 0x6d, 0xec, 0xed, 0xbc, + 0xca, 0x7c, 0x30, 0xc2, 0xb1, 0xd6, 0xe3, 0x55, 0x6d, 0xed, 0xdf, 0xbf, + 0x4d, 0xad, 0xa3, 0x5a, 0x2b, 0x3e, 0xe7, 0xf1, 0x6e, 0x23, 0x3e, 0x87, + 0x6e, 0xe7, 0xb0, 0x5d, 0xb3, 0xaa, 0x67, 0xc5, 0x8a, 0x93, 0xa7, 0xf6, + 0xab, 0x2a, 0xae, 0xcf, 0x5e, 0x9f, 0x73, 0x84, 0x4e, 0x48, 0xc2, 0x46, + 0xc8, 0x23, 0x4b, 0xb7, 0xae, 0xaf, 0xca, 0x62, 0x71, 0x79, 0xe5, 0xc0, + 0x09, 0xac, 0x89, 0xb6, 0x2c, 0x64, 0x29, 0xc2, 0x4e, 0x88, 0x0f, 0x59, + 0x49, 0x96, 0xab, 0xba, 0xe0, 0x42, 0xb8, 0x3a, 0x86, 0x64, 0x93, 0x75, + 0x46, 0x17, 0x9a, 0xc2, 0x08, 0x3a, 0x72, 0x92, 0x61, 0x40, 0x62, 0x81, + 0xb1, 0x0a, 0x79, 0x56, 0xb5, 0xc7, 0x8a, 0xc9, 0x50, 0x89, 0x97, 0xd0, + 0x24, 0xe7, 0xe8, 0x6e, 0x0a, 0x8e, 0x70, 0x94, 0x57, 0xb9, 0x25, 0xc1, + 0x55, 0xf1, 0x42, 0xdc, 0x1b, 0x63, 0x45, 0x0a, 0xa4, 0xd5, 0xf0, 0xfc, + 0x98, 0x18, 0xab, 0xb8, 0xa3, 0xac, 0xbe, 0xba, 0x0b, 0x0c, 0xa1, 0xf9, + 0xb8, 0x40, 0x66, 0x56, 0x8a, 0xde, 0x39, 0x68, 0x54, 0x24, 0xc4, 0x90, + 0x65, 0xad, 0x10, 0x31, 0xec, 0xa5, 0xa5, 0x65, 0xf5, 0xf9, 0x53, 0x8c, + 0x2d, 0xce, 0xaf, 0x1f, 0xf6, 0x70, 0x05, 0xd4, 0x92, 0xc1, 0x9f, 0x3d, + 0xa6, 0xcf, 0x62, 0xe2, 0xb0, 0x27, 0x9f, 0xca, 0x8a, 0x45, 0xa4, 0xf1, + 0x43, 0xce, 0xc0, 0x07, 0x69, 0x08, 0x73, 0x3c, 0x39, 0xb3, 0x9c, 0x55, + 0x3a, 0x99, 0xd3, 0xf4, 0xbd, 0xc8, 0x3c, 0x0f, 0x93, 0x88, 0x78, 0xe4, + 0x7a, 0xd2, 0xa2, 0x5e, 0x0a, 0xa7, 0x65, 0xb4, 0x25, 0x52, 0x65, 0x9d, + 0x69, 0x9a, 0x13, 0xde, 0x26, 0xdc, 0xb2, 0x50, 0x80, 0x46, 0x47, 0x47, + 0x21, 0x46, 0xb8, 0xfd, 0x06, 0x36, 0xca, 0xbd, 0xda, 0x5b, 0x0c, 0x74, + 0x1f, 0xcf, 0xcb, 0x27, 0xc2, 0x7c, 0x56, 0xb0, 0xfb, 0xb8, 0x9b, 0xdd, + 0x9d, 0xfe, 0x6e, 0x7f, 0xaf, 0xbf, 0x7f, 0xff, 0x6e, 0xdb, 0x2b, 0x9f, + 0x6d, 0xb7, 0x8d, 0x7e, 0xd6, 0xd8, 0xed, 0xc7, 0x9f, 0x6b, 0xb7, 0x1f, + 0xff, 0x5f, 0xb2, 0xdb, 0x8f, 0x57, 0xed, 0xf6, 0xe3, 0x7f, 0xcf, 0x6e, + 0x4b, 0x37, 0x7b, 0xe9, 0xce, 0xc3, 0x83, 0x87, 0xd9, 0xc3, 0xbd, 0x83, + 0x83, 0x47, 0x8f, 0x77, 0xd7, 0xd9, 0xf3, 0xc7, 0xff, 0x96, 0x3d, 0x7f, + 0xb8, 0xbc, 0xe7, 0xa2, 0x84, 0xd9, 0x8e, 0x67, 0x55, 0x83, 0xf9, 0xf3, + 0x66, 0x69, 0x05, 0x0b, 0xdc, 0x34, 0x7d, 0x85, 0x6d, 0xce, 0x92, 0x36, + 0x15, 0x65, 0x41, 0x48, 0x76, 0x4d, 0x94, 0x0c, 0xc1, 0xdb, 0xa8, 0xed, + 0x04, 0xc2, 0x81, 0xc9, 0x86, 0xcd, 0x6c, 0x54, 0x75, 0x65, 0x51, 0x59, + 0xe7, 0x78, 0x16, 0xd0, 0x9d, 0x2a, 0x46, 0x15, 0xe3, 0x18, 0x15, 0x87, + 0xd1, 0x8d, 0x6d, 0xd0, 0x45, 0xd4, 0x0d, 0x56, 0xf7, 0xe0, 0xb1, 0x3f, + 0x39, 0x8b, 0x93, 0xea, 0x43, 0x6f, 0xc1, 0x0d, 0x47, 0xe0, 0xd3, 0xfd, + 0xc4, 0x51, 0x8f, 0x4e, 0xf7, 0x33, 0x12, 0x4f, 0xd5, 0x42, 0x3d, 0xda, + 0xcd, 0xee, 0x37, 0x7b, 0xfd, 0xdd, 0xc7, 0x4f, 0x10, 0xa1, 0xaa, 0x1b, + 0x7e, 0xdf, 0x5b, 0xc3, 0xb0, 0xed, 0x1b, 0xd9, 0x11, 0x8c, 0xab, 0x47, + 0xf7, 0x73, 0x1c, 0x7d, 0xc7, 0x68, 0x6f, 0x15, 0xf1, 0x7d, 0x6e, 0xea, + 0x2b, 0xae, 0x96, 0xab, 0x4d, 0x9d, 0x93, 0x89, 0xb0, 0x6a, 0x14, 0x03, + 0x42, 0x1d, 0xc6, 0xf2, 0x62, 0x9f, 0x15, 0x2f, 0x88, 0x38, 0x7b, 0x68, + 0xbf, 0xec, 0x51, 0x05, 0x53, 0x43, 0x83, 0xa6, 0x32, 0x55, 0xb9, 0xba, + 0x06, 0xf9, 0x65, 0xa5, 0x49, 0x7c, 0x4f, 0xe6, 0xba, 0x11, 0x97, 0x6d, + 0xfa, 0xd2, 0xc5, 0xaa, 0xbc, 0xfc, 0xb3, 0x54, 0xad, 0x0a, 0x87, 0xb5, + 0x5c, 0xb2, 0x4a, 0x6b, 0x56, 0xc9, 0x59, 0xa4, 0x10, 0x7d, 0x2b, 0x59, + 0x15, 0x2a, 0x56, 0x69, 0x92, 0x9d, 0xd5, 0x22, 0xb1, 0x72, 0x55, 0xc1, + 0x5d, 0xf4, 0xbf, 0x55, 0xb1, 0xaa, 0x48, 0x60, 0x8f, 0x09, 0xa8, 0xad, + 0x74, 0xc6, 0x27, 0x58, 0x14, 0xe2, 0x46, 0xef, 0xe1, 0xfa, 0x8d, 0x11, + 0xf0, 0x27, 0x5e, 0x3a, 0x87, 0xbf, 0x15, 0x61, 0xfa, 0x5e, 0x4c, 0x37, + 0x1f, 0x57, 0xff, 0xb8, 0x21, 0xb7, 0x63, 0xbb, 0x4b, 0x05, 0xb8, 0xfd, + 0x87, 0xdc, 0xc4, 0x0f, 0xb7, 0xc6, 0x6f, 0xbb, 0x98, 0xae, 0xcc, 0x99, + 0xfd, 0x01, 0x14, 0x96, 0x4f, 0x34, 0x3b, 0x5c, 0x15, 0x78, 0x23, 0x22, + 0x40, 0x95, 0xd8, 0x79, 0x6f, 0xcd, 0x9d, 0x2c, 0xde, 0x0b, 0x31, 0x2f, + 0x78, 0x9c, 0x32, 0xc9, 0x63, 0x23, 0x14, 0xe1, 0x7e, 0x4b, 0x22, 0x6b, + 0x9d, 0x4d, 0x26, 0x55, 0x80, 0x34, 0x20, 0xe0, 0xb7, 0x16, 0xf2, 0x81, + 0xa3, 0x94, 0xcd, 0x25, 0x51, 0x84, 0x62, 0xda, 0x94, 0x29, 0x5b, 0x49, + 0x05, 0x02, 0x05, 0x76, 0xe1, 0x16, 0x3f, 0x1d, 0xbe, 0x79, 0x7d, 0xf2, + 0xfa, 0xc7, 0x03, 0x17, 0x49, 0xef, 0x2d, 0xf3, 0x3a, 0x47, 0xa4, 0x2b, + 0x9a, 0x61, 0x40, 0xb6, 0xe3, 0xa0, 0x5c, 0x0b, 0xb7, 0x20, 0xfc, 0xbc, + 0x05, 0x1f, 0xd0, 0xb0, 0xc2, 0x4b, 0x20, 0xb7, 0x74, 0x78, 0x81, 0x43, + 0xc2, 0xb1, 0x44, 0x3f, 0x7d, 0x1d, 0xb9, 0x75, 0x84, 0xd1, 0xb1, 0xcd, + 0x3e, 0x7c, 0x3a, 0x58, 0x04, 0xef, 0x87, 0xc0, 0x7a, 0xf2, 0x60, 0x9a, + 0xfc, 0x2b, 0x11, 0x68, 0x63, 0xef, 0x0e, 0x69, 0xdd, 0xe0, 0x95, 0x96, + 0x82, 0xbb, 0x4c, 0x05, 0x6a, 0x26, 0xf0, 0xe5, 0x3d, 0x8d, 0xd8, 0x9b, + 0x73, 0x5e, 0x4d, 0xe9, 0x36, 0xaf, 0xcf, 0x41, 0xe6, 0xec, 0x50, 0x32, + 0x52, 0xd7, 0xa8, 0x53, 0xb9, 0xd2, 0x43, 0x17, 0x1c, 0x73, 0x1a, 0x96, + 0x34, 0xf2, 0xa0, 0xc4, 0xeb, 0x1d, 0x9d, 0x0b, 0x1c, 0xdd, 0xd3, 0xb7, + 0x6f, 0x5e, 0x46, 0x85, 0x51, 0x42, 0xa9, 0xaf, 0x24, 0xde, 0x00, 0xdc, + 0x91, 0xe2, 0xc5, 0x56, 0xe2, 0x9c, 0x8c, 0x6c, 0xc4, 0xe1, 0x10, 0x70, + 0x02, 0x58, 0xd4, 0x8a, 0x6c, 0x02, 0x49, 0x19, 0xa7, 0x7e, 0x06, 0x28, + 0x7f, 0x0b, 0x1e, 0x24, 0xb5, 0x53, 0xde, 0xc5, 0x30, 0xc7, 0x0c, 0x4d, + 0x4e, 0x79, 0x35, 0xed, 0x87, 0x50, 0x6c, 0x34, 0x59, 0x68, 0x0d, 0x0b, + 0x1a, 0x87, 0x55, 0x35, 0x40, 0x24, 0x71, 0x64, 0x85, 0x1a, 0x9c, 0xc4, + 0xfc, 0xdc, 0x60, 0x2a, 0x90, 0x92, 0xe0, 0x8f, 0xd2, 0x91, 0x35, 0x43, + 0x7c, 0x91, 0x4e, 0xec, 0x00, 0x01, 0xe9, 0xd2, 0x0b, 0x70, 0x43, 0x3c, + 0x28, 0x46, 0x2c, 0xae, 0x38, 0x07, 0x55, 0x20, 0xdf, 0xd9, 0x1b, 0x98, + 0x70, 0x95, 0xf9, 0x17, 0x5c, 0x76, 0xce, 0x67, 0xdb, 0x45, 0xd5, 0x1d, + 0x1b, 0x47, 0x97, 0x0b, 0x8c, 0xfb, 0xaa, 0x54, 0xb0, 0x36, 0x57, 0x19, + 0x02, 0x90, 0x8c, 0x24, 0x82, 0x2d, 0x04, 0xbe, 0xa3, 0x89, 0xa7, 0x2c, + 0x30, 0xf5, 0xc6, 0xd7, 0x9f, 0xba, 0xce, 0xd3, 0x26, 0x95, 0x89, 0xec, + 0xd0, 0xce, 0x8f, 0x7f, 0xb8, 0x0d, 0x7c, 0x0e, 0xe7, 0x88, 0x42, 0xca, + 0xad, 0xda, 0x92, 0x48, 0x15, 0x91, 0xea, 0x2b, 0x08, 0x90, 0x8d, 0xe9, + 0xff, 0x88, 0x2d, 0x3b, 0x67, 0xc0, 0x66, 0x86, 0x9e, 0x50, 0xd3, 0xc4, + 0xb8, 0x21, 0x1c, 0x48, 0xed, 0xd7, 0x26, 0x1c, 0x86, 0x93, 0x58, 0x37, + 0x33, 0xc4, 0x50, 0x1a, 0x1b, 0x6f, 0x89, 0x40, 0xf9, 0xe4, 0x26, 0x51, + 0x50, 0x4e, 0xab, 0x97, 0x8b, 0xdc, 0x69, 0x15, 0x5b, 0x59, 0xcc, 0x08, + 0x3c, 0x73, 0x4c, 0x96, 0xcf, 0x08, 0x44, 0x0c, 0xc1, 0x73, 0x2c, 0x19, + 0x5a, 0x9c, 0x7a, 0x84, 0x39, 0x2b, 0x72, 0x81, 0xbb, 0x32, 0x9e, 0x3c, + 0xea, 0xef, 0x6c, 0x89, 0x35, 0x43, 0xe8, 0xff, 0x1e, 0xc8, 0xe8, 0x8f, + 0xb0, 0x62, 0x54, 0x2d, 0xec, 0x60, 0xd5, 0xf9, 0xbf, 0x5f, 0x50, 0xbd, + 0xe3, 0xe5, 0xb0, 0x72, 0xcc, 0x46, 0xdc, 0x77, 0x04, 0x94, 0x8a, 0x12, + 0x31, 0x48, 0xc3, 0xfd, 0xdd, 0x35, 0xed, 0x5f, 0x7b, 0x6b, 0xdd, 0xa3, + 0x8b, 0xe9, 0xbc, 0x37, 0x4c, 0x7b, 0x19, 0xa8, 0x16, 0x23, 0x9f, 0xc0, + 0xf9, 0x13, 0xd7, 0x3d, 0xc1, 0xc5, 0x3a, 0xc2, 0xca, 0x2d, 0x8b, 0xd9, + 0x08, 0xc6, 0x48, 0x8f, 0x8d, 0x44, 0x70, 0xb1, 0x9b, 0x0d, 0xe8, 0x73, + 0x36, 0x4a, 0xc9, 0xaf, 0x4e, 0x89, 0xf0, 0xbe, 0xd4, 0x34, 0x5c, 0x1b, + 0x75, 0x13, 0x85, 0x0a, 0xcb, 0x5c, 0x4b, 0x91, 0x0f, 0x96, 0xae, 0xa5, + 0xfa, 0x4d, 0x60, 0x20, 0xd0, 0xa5, 0xf4, 0x68, 0x5d, 0xfa, 0x13, 0x29, + 0x09, 0xfc, 0x18, 0xfb, 0x85, 0x24, 0xd3, 0xf4, 0xb6, 0xf8, 0x39, 0x7d, + 0x2e, 0x8f, 0xba, 0x6f, 0xf3, 0x9e, 0xfb, 0x22, 0x5a, 0xd2, 0x88, 0xf1, + 0x23, 0xdf, 0x7f, 0xd2, 0x27, 0x0d, 0xa5, 0x99, 0x6b, 0x00, 0x2f, 0x60, + 0x74, 0x01, 0x16, 0x37, 0xb0, 0x9c, 0x5b, 0xbe, 0x00, 0x38, 0xe5, 0xb6, + 0x1b, 0x33, 0x7e, 0xf7, 0x78, 0xf8, 0xc8, 0xe5, 0xe9, 0xea, 0x47, 0x3e, + 0x5b, 0xf7, 0x59, 0x57, 0x47, 0x27, 0x20, 0x8e, 0xad, 0x28, 0x4d, 0x09, + 0xb9, 0x71, 0xdc, 0xf6, 0x1b, 0x14, 0xa7, 0xf9, 0x37, 0x03, 0x46, 0x9e, + 0xe5, 0xca, 0xc4, 0x15, 0x97, 0x38, 0x9b, 0xe2, 0x84, 0x70, 0x90, 0xa2, + 0xba, 0x7d, 0x26, 0x4a, 0x5b, 0x86, 0x0b, 0x73, 0x13, 0xe7, 0xe6, 0x88, + 0x40, 0x45, 0x8c, 0x29, 0x70, 0x8b, 0x8a, 0x1f, 0x85, 0xd5, 0x6c, 0x38, + 0x8d, 0x91, 0xe3, 0x93, 0x37, 0x63, 0x98, 0xa2, 0x2d, 0xba, 0xbb, 0x28, + 0x65, 0xc8, 0xfc, 0x73, 0xab, 0x20, 0x8a, 0xce, 0x31, 0x37, 0x00, 0xe9, + 0xc6, 0x08, 0x9a, 0x37, 0xa8, 0x1b, 0xb2, 0xbb, 0x3b, 0xff, 0xd1, 0x71, + 0x3d, 0x60, 0x24, 0xec, 0x90, 0xa1, 0xec, 0x2e, 0x11, 0x7d, 0x5c, 0x3d, + 0x96, 0x36, 0x18, 0x41, 0x9f, 0xa2, 0x48, 0x4c, 0xa6, 0x53, 0xee, 0x34, + 0x2b, 0x2d, 0x31, 0x21, 0x80, 0xae, 0x60, 0xb7, 0x8c, 0xa3, 0xa1, 0x70, + 0xbc, 0xca, 0x4d, 0x83, 0x2a, 0x22, 0xf9, 0x54, 0x8c, 0xeb, 0xa7, 0x19, + 0xe4, 0xea, 0xe6, 0xc6, 0xa1, 0x77, 0x64, 0x8d, 0x3b, 0x52, 0x4f, 0x6c, + 0xc1, 0x4f, 0x53, 0x3d, 0x44, 0xae, 0x72, 0xa5, 0x1d, 0xbf, 0x48, 0xaf, + 0xf1, 0x85, 0xa0, 0x2e, 0x18, 0x90, 0x24, 0x96, 0x39, 0x9f, 0x65, 0xcc, + 0x0e, 0x61, 0x4b, 0x02, 0xaa, 0x55, 0xb2, 0x99, 0xf7, 0x61, 0xe9, 0x95, + 0xfd, 0x06, 0x50, 0x01, 0x7c, 0x1c, 0x23, 0x39, 0x3e, 0x60, 0x76, 0x70, + 0x0a, 0xb3, 0xd9, 0xea, 0x8a, 0xe1, 0xa1, 0xe2, 0x3c, 0x6b, 0x21, 0x0e, + 0x43, 0x53, 0xea, 0x26, 0x51, 0x91, 0x32, 0xcd, 0x2a, 0xe3, 0x3a, 0x4e, + 0x9c, 0x3b, 0xc5, 0x3c, 0xdc, 0x91, 0xe8, 0x17, 0xe4, 0xe3, 0xae, 0x17, + 0xae, 0xa5, 0xbe, 0x0e, 0x5a, 0x4f, 0xf4, 0x5a, 0x2b, 0xe6, 0x6f, 0xd2, + 0x2b, 0x68, 0xe5, 0x97, 0xbd, 0x48, 0x82, 0x6a, 0xa5, 0xac, 0x17, 0x84, + 0xa2, 0xe4, 0x29, 0x87, 0x56, 0xf8, 0xf3, 0x17, 0x15, 0x67, 0x65, 0xa4, + 0x64, 0x4c, 0x8e, 0x3b, 0x3e, 0x02, 0xd5, 0xff, 0x78, 0x36, 0x2c, 0x6f, + 0xe7, 0xb8, 0x7c, 0x52, 0x52, 0xfe, 0x05, 0x86, 0x9e, 0x6f, 0xf9, 0x14, + 0x37, 0x2e, 0x40, 0x61, 0x11, 0x75, 0x28, 0x2d, 0x69, 0x27, 0xe2, 0xd6, + 0xd4, 0xe0, 0xe6, 0x31, 0x0c, 0x2b, 0x0a, 0x99, 0x63, 0xb7, 0x2a, 0xf6, + 0x24, 0x4f, 0x5c, 0xc2, 0x51, 0xe4, 0x47, 0xc8, 0x11, 0x92, 0x26, 0x3f, + 0xbe, 0x39, 0x3e, 0x3c, 0x3f, 0xa6, 0xb1, 0x98, 0xc6, 0xff, 0x95, 0x3a, + 0x6d, 0x17, 0xf4, 0xe4, 0x61, 0x68, 0x85, 0xeb, 0xbd, 0x08, 0xd8, 0x0e, + 0xee, 0xbe, 0x64, 0xde, 0x7a, 0x68, 0x29, 0x7c, 0x82, 0x1f, 0xd5, 0x58, + 0x89, 0x07, 0x32, 0x0e, 0x8c, 0xb4, 0xd9, 0xbc, 0x90, 0xd0, 0x64, 0xd3, + 0xe2, 0xc6, 0x1c, 0x63, 0x13, 0xbd, 0x66, 0x2f, 0x88, 0xd6, 0xf1, 0x80, + 0x15, 0x72, 0xad, 0xb3, 0x73, 0x05, 0x37, 0x53, 0x73, 0x64, 0x54, 0x61, + 0x49, 0x07, 0xa0, 0x05, 0x08, 0x68, 0x58, 0x3a, 0xdc, 0x3e, 0x3d, 0xc7, + 0x1a, 0x3b, 0x86, 0x6e, 0x60, 0xfc, 0x35, 0x5d, 0x07, 0x52, 0xeb, 0x76, + 0x9f, 0x15, 0x1f, 0x66, 0xdf, 0xc1, 0x7e, 0xc4, 0xc2, 0x30, 0x29, 0x3a, + 0xa8, 0xf1, 0xcc, 0x83, 0x4e, 0x83, 0xee, 0x97, 0x07, 0xd0, 0xe6, 0x11, + 0x6d, 0x06, 0x01, 0x49, 0xdc, 0x51, 0x20, 0x30, 0x1b, 0x4e, 0x0e, 0x9e, + 0x0e, 0x1e, 0x3f, 0x84, 0xed, 0xfc, 0x8e, 0x06, 0x9f, 0x0c, 0x60, 0x2b, + 0x1e, 0x3f, 0x4c, 0x34, 0xc6, 0x35, 0x6e, 0x29, 0xaa, 0xa1, 0x80, 0x7b, + 0x0e, 0x5f, 0x5b, 0xb8, 0xe3, 0xec, 0xe0, 0x29, 0x33, 0x79, 0x6a, 0xc7, + 0xaa, 0x84, 0x71, 0x26, 0x72, 0xc1, 0xc1, 0x70, 0xbd, 0xd2, 0x12, 0x0c, + 0x3b, 0x73, 0x42, 0x84, 0x7c, 0x87, 0x0f, 0x76, 0x12, 0x49, 0x33, 0x26, + 0x49, 0xbf, 0x65, 0x0a, 0x9b, 0xb4, 0x42, 0x01, 0x18, 0x81, 0x96, 0x48, + 0x8d, 0x19, 0xb8, 0x54, 0x62, 0x0a, 0xd1, 0xcd, 0x38, 0x46, 0xef, 0x27, + 0x45, 0x3b, 0xbe, 0x42, 0x47, 0x26, 0x39, 0x43, 0x11, 0xba, 0x01, 0xc7, + 0xc2, 0x9e, 0x51, 0x2c, 0xb2, 0x74, 0xfc, 0x0e, 0x7a, 0x79, 0xf7, 0xe6, + 0xf8, 0x4f, 0x6f, 0x4f, 0xde, 0x1c, 0x3f, 0x4b, 0x36, 0x77, 0x77, 0x76, + 0xb7, 0xa2, 0x88, 0xc7, 0x8c, 0x63, 0x2b, 0x3f, 0x77, 0x45, 0x66, 0x6c, + 0x16, 0x09, 0x79, 0x1d, 0x09, 0xeb, 0x49, 0xff, 0x49, 0x8b, 0x80, 0xc5, + 0x4e, 0x4d, 0x39, 0xe0, 0x97, 0x1c, 0xce, 0xdc, 0x82, 0x4a, 0xf2, 0x2c, + 0xc3, 0x70, 0x7a, 0x86, 0x66, 0xe3, 0x7b, 0x6f, 0x33, 0x35, 0x11, 0x01, + 0x04, 0xda, 0x87, 0x54, 0x40, 0xf9, 0xac, 0xcc, 0x0b, 0xcd, 0xdd, 0x60, + 0x6c, 0x40, 0x22, 0x48, 0x25, 0xeb, 0x11, 0x5d, 0x8f, 0x1c, 0x0e, 0x50, + 0x68, 0x51, 0xae, 0x71, 0x30, 0x97, 0xd3, 0xed, 0x0a, 0x7b, 0x17, 0x0a, + 0x0d, 0x8d, 0x75, 0x6b, 0xda, 0x4a, 0xc8, 0x11, 0x34, 0x96, 0x81, 0x2d, + 0x53, 0xcc, 0x06, 0xaa, 0x2b, 0xf3, 0xdb, 0xe4, 0xc7, 0x14, 0x2f, 0x11, + 0x22, 0xec, 0x34, 0x9b, 0x42, 0x57, 0x55, 0x81, 0x41, 0xae, 0x1e, 0x73, + 0x90, 0x3f, 0x31, 0x12, 0xe4, 0xf8, 0x47, 0xbe, 0x7d, 0x12, 0xb8, 0x63, + 0x46, 0x18, 0x9e, 0x2e, 0xa0, 0x78, 0x54, 0xd0, 0xfb, 0xfc, 0xa5, 0x3b, + 0xd6, 0x8c, 0xf0, 0x69, 0x11, 0x18, 0xba, 0x6c, 0x5f, 0x62, 0x83, 0xb5, + 0xed, 0x6d, 0x1e, 0xd4, 0x36, 0x95, 0x80, 0x5c, 0x17, 0x93, 0x1d, 0x5e, + 0xe8, 0x09, 0x2c, 0xa0, 0x0c, 0x95, 0x67, 0xf4, 0xd4, 0xcb, 0x50, 0x8c, + 0x3a, 0x73, 0x9e, 0x4d, 0xac, 0xf6, 0x49, 0x30, 0xee, 0x11, 0xf7, 0x2e, + 0x12, 0x5b, 0x8a, 0xa0, 0x6c, 0x93, 0x7d, 0x44, 0x8a, 0x5c, 0x2f, 0xe3, + 0x4a, 0xbe, 0xe5, 0xa0, 0x0a, 0x7d, 0x8b, 0x3c, 0x09, 0xf4, 0xee, 0xbc, + 0xcc, 0x29, 0x09, 0x45, 0x3f, 0xa3, 0x7a, 0x03, 0xb0, 0xff, 0x23, 0xaa, + 0x33, 0xa3, 0xf0, 0xb7, 0x0a, 0x0c, 0xc5, 0xef, 0x57, 0x51, 0x58, 0x3d, + 0xbb, 0x86, 0x27, 0x13, 0x20, 0x40, 0xaa, 0x2d, 0xa2, 0xc8, 0x68, 0x18, + 0xe1, 0xbb, 0x15, 0x43, 0x3b, 0xc9, 0xeb, 0x06, 0x7b, 0xed, 0x8e, 0xbd, + 0x0b, 0x35, 0x30, 0x07, 0x82, 0x8e, 0xf6, 0x8b, 0x39, 0x9e, 0x94, 0x9e, + 0x26, 0xa0, 0x66, 0x96, 0x6b, 0x46, 0x32, 0xde, 0x55, 0x02, 0x3b, 0xab, + 0xd3, 0xcb, 0x9e, 0xd4, 0x48, 0x89, 0xcf, 0x2c, 0xc7, 0x26, 0xbf, 0x42, + 0x93, 0x01, 0xe5, 0x20, 0x59, 0xc8, 0x1d, 0x47, 0x29, 0x2b, 0x4a, 0x87, + 0x16, 0xa0, 0x31, 0x1f, 0xe1, 0xf1, 0x45, 0x7a, 0xe9, 0x0b, 0x2d, 0x36, + 0x0a, 0x4b, 0x70, 0x3d, 0x87, 0x5b, 0x0b, 0x52, 0x86, 0xb6, 0x17, 0x20, + 0x8a, 0x4c, 0x61, 0x01, 0x7b, 0xaf, 0x61, 0xfd, 0x7b, 0xaf, 0x28, 0xb5, + 0x47, 0x91, 0xe3, 0x1d, 0xee, 0x17, 0xdb, 0xf8, 0x09, 0xfe, 0x1c, 0xfb, + 0xd0, 0x75, 0xc2, 0x2a, 0x41, 0x9a, 0x0c, 0xce, 0xb9, 0x16, 0x98, 0x3b, + 0x44, 0x70, 0x31, 0x15, 0x99, 0x90, 0x9c, 0x69, 0x3c, 0x00, 0xf5, 0x52, + 0x50, 0xaa, 0x96, 0x27, 0x75, 0x50, 0xdd, 0x69, 0x54, 0xb8, 0x32, 0x24, + 0xcd, 0x8e, 0xb2, 0x2a, 0xb7, 0x9e, 0x93, 0x43, 0x2f, 0xa2, 0xf3, 0x66, + 0xa7, 0xa5, 0xe5, 0x22, 0xa6, 0x55, 0x90, 0xe1, 0xfd, 0x48, 0xdf, 0x0a, + 0x0a, 0x86, 0x70, 0x3f, 0x59, 0x7c, 0x94, 0x9b, 0xb8, 0xac, 0x1c, 0xc6, + 0x79, 0xf1, 0x5f, 0xc8, 0x87, 0x70, 0x19, 0x15, 0xf0, 0xc0, 0x3c, 0x00, + 0x01, 0x90, 0xb8, 0x16, 0x71, 0x3a, 0x4e, 0xeb, 0xc7, 0xf3, 0xa1, 0xbb, + 0x49, 0xea, 0x5c, 0xa5, 0x53, 0x27, 0xb9, 0x98, 0x1a, 0x25, 0xa0, 0x7d, + 0x43, 0x89, 0xe6, 0xa2, 0x73, 0xb5, 0xee, 0xa7, 0xfa, 0x51, 0x23, 0xba, + 0x68, 0xad, 0x21, 0x21, 0x94, 0x1c, 0xf6, 0xe6, 0x93, 0xc8, 0xd9, 0x77, + 0x83, 0x7f, 0xdc, 0x03, 0xd1, 0xe4, 0x75, 0xfd, 0xe6, 0x55, 0x14, 0x56, + 0x93, 0x29, 0x1d, 0xc7, 0x87, 0x61, 0xbc, 0xa3, 0x98, 0xd8, 0xe9, 0x89, + 0x16, 0x4a, 0x3f, 0x67, 0xb4, 0x85, 0x99, 0xd0, 0x37, 0x93, 0xf1, 0x92, + 0xae, 0x67, 0x55, 0x4e, 0x67, 0xf2, 0x04, 0x09, 0x63, 0x9a, 0x9f, 0x3c, + 0xbc, 0x42, 0x92, 0x2e, 0xb3, 0x09, 0xdd, 0x72, 0x4c, 0xc3, 0x08, 0xcb, + 0xca, 0x01, 0xe3, 0x9c, 0xb6, 0xcc, 0xe3, 0x0f, 0x7b, 0xea, 0xee, 0x78, + 0xd0, 0x1c, 0xad, 0x51, 0xce, 0x3e, 0x96, 0xb4, 0x5f, 0x05, 0xbe, 0x89, + 0x75, 0x43, 0x0f, 0xa9, 0x1b, 0xdf, 0x26, 0x36, 0xcf, 0x2f, 0x71, 0x9d, + 0x58, 0xe3, 0x74, 0x18, 0x3f, 0xc3, 0x9e, 0xc9, 0xfe, 0x87, 0x6d, 0xa2, + 0x3c, 0xa7, 0xdd, 0x9d, 0x9d, 0x55, 0x55, 0xf5, 0x8c, 0x37, 0xc5, 0xc5, + 0xf5, 0xe2, 0xea, 0x7a, 0xa1, 0xb8, 0x9e, 0xc1, 0x8d, 0xdc, 0xa4, 0x79, + 0x1d, 0xd5, 0xe3, 0xc4, 0x3e, 0xb4, 0x58, 0x8a, 0x53, 0x3e, 0x6f, 0x02, + 0x34, 0x61, 0x46, 0xc5, 0xf6, 0xc8, 0x45, 0x77, 0x4c, 0xc3, 0xaa, 0x0e, + 0xe2, 0xd7, 0x44, 0x30, 0x11, 0xcd, 0x6d, 0xc6, 0x05, 0x30, 0xec, 0x30, + 0x79, 0x0f, 0x8d, 0xd9, 0x81, 0xa8, 0x84, 0x2b, 0xeb, 0x9d, 0x44, 0x9e, + 0x2d, 0xa1, 0x53, 0x56, 0x63, 0xcf, 0x0a, 0xe2, 0x85, 0x2a, 0x7b, 0x0e, + 0x38, 0x91, 0xa0, 0xbd, 0x2b, 0x6e, 0x93, 0xeb, 0x5a, 0xb9, 0xe4, 0x21, + 0xad, 0xe9, 0xc7, 0x15, 0xbb, 0x03, 0xc1, 0x91, 0x25, 0x4a, 0x8d, 0x12, + 0x11, 0x52, 0x48, 0xd4, 0x95, 0x16, 0xc6, 0x12, 0x97, 0x90, 0x4b, 0xb1, + 0x91, 0xea, 0x7a, 0x89, 0x54, 0xee, 0xeb, 0xf4, 0x3b, 0xce, 0x24, 0xd0, + 0x5a, 0xc0, 0x8f, 0x2e, 0x5c, 0x22, 0x38, 0x42, 0x48, 0x8d, 0x6b, 0xf7, + 0x69, 0x85, 0x4c, 0xae, 0xde, 0x67, 0x69, 0xf1, 0x5a, 0x1f, 0x50, 0x8a, + 0xf8, 0xb9, 0x2a, 0x7e, 0x89, 0xdd, 0xb6, 0x4b, 0x84, 0x42, 0xc7, 0xf1, + 0x0b, 0xdd, 0xbc, 0x4b, 0x9d, 0xed, 0xf5, 0x1f, 0x19, 0x84, 0xdf, 0xba, + 0x39, 0x05, 0xbe, 0x8a, 0x9e, 0x12, 0xfc, 0x18, 0x6d, 0x54, 0xa8, 0x99, + 0x45, 0xd4, 0xfd, 0x1c, 0x55, 0x35, 0x17, 0x3d, 0x49, 0xe9, 0x6b, 0x7b, + 0x7b, 0xc4, 0xdc, 0x14, 0x16, 0xc2, 0xb6, 0x74, 0x50, 0x60, 0x31, 0x0e, + 0x31, 0xbd, 0x68, 0xb9, 0x17, 0x94, 0x70, 0x88, 0xda, 0x89, 0xa3, 0x05, + 0xb3, 0x87, 0x30, 0x22, 0x5c, 0x5e, 0xbd, 0xcb, 0xa5, 0x19, 0xec, 0x83, + 0x94, 0x4b, 0x2a, 0xdb, 0x63, 0xa0, 0x2d, 0x97, 0xc4, 0x63, 0x02, 0xc4, + 0xc4, 0x4c, 0x53, 0x80, 0x38, 0xdf, 0x96, 0x8f, 0x8b, 0x72, 0x4e, 0x75, + 0x2d, 0xb2, 0xd6, 0xca, 0xe9, 0x5b, 0xf9, 0x35, 0x03, 0x98, 0x8f, 0x8a, + 0x21, 0x97, 0x41, 0x31, 0x68, 0x58, 0x83, 0x72, 0xd0, 0x29, 0x8c, 0xb9, + 0xe8, 0x3c, 0x9a, 0xff, 0x69, 0xff, 0x61, 0xe1, 0x24, 0x46, 0x90, 0x4b, + 0x12, 0xb0, 0xf2, 0xa9, 0x30, 0x01, 0x8a, 0x00, 0x77, 0x75, 0xcb, 0x6e, + 0x3e, 0xcc, 0x26, 0xd8, 0xd2, 0xc4, 0xe9, 0x87, 0x1f, 0x3e, 0xc8, 0xdc, + 0xc3, 0xd1, 0x26, 0x78, 0x8e, 0x06, 0xb8, 0x35, 0x27, 0x3d, 0xfa, 0xe3, + 0x87, 0x05, 0x57, 0xb0, 0x18, 0x08, 0xef, 0x3d, 0xdd, 0xc2, 0xbc, 0xb6, + 0xb5, 0xd5, 0x5b, 0xb0, 0xcc, 0x40, 0x03, 0xb9, 0x92, 0xa9, 0x88, 0xdc, + 0x48, 0x7b, 0x06, 0xdb, 0x25, 0x58, 0xd1, 0x91, 0xa7, 0x96, 0x5a, 0x8d, + 0x32, 0xa1, 0xc9, 0xc0, 0xd5, 0xd8, 0x0d, 0x3d, 0xc7, 0x23, 0x4e, 0x02, + 0xcc, 0x41, 0x5e, 0x22, 0x77, 0x0c, 0x2e, 0xac, 0x77, 0x5a, 0x16, 0x8c, + 0x12, 0xcd, 0xe5, 0x13, 0xb8, 0x02, 0x1c, 0x87, 0xdb, 0x32, 0x5e, 0x0b, + 0x2f, 0x06, 0xad, 0x1a, 0x71, 0xed, 0x28, 0xf5, 0x99, 0x40, 0xa8, 0x32, + 0x83, 0xb2, 0x85, 0x96, 0x7b, 0x48, 0x5b, 0x3d, 0xda, 0x8c, 0x25, 0x30, + 0x21, 0x4a, 0x7f, 0xca, 0xea, 0xab, 0x62, 0x64, 0xb6, 0x0b, 0xde, 0x67, + 0xb8, 0x0f, 0xc6, 0xda, 0x95, 0x54, 0x98, 0x27, 0xd3, 0x5d, 0x31, 0x04, + 0x0a, 0x61, 0x87, 0x16, 0x55, 0xc1, 0xb2, 0xb4, 0xc5, 0x5e, 0xb5, 0xa0, + 0x24, 0x09, 0xca, 0x14, 0x8f, 0x77, 0x07, 0x0f, 0x70, 0x35, 0x61, 0xaf, + 0x31, 0x85, 0x9b, 0x62, 0x29, 0x64, 0xc1, 0x40, 0x20, 0xac, 0x1b, 0x24, + 0x37, 0x21, 0xf0, 0x28, 0x15, 0x4e, 0x8b, 0x33, 0x4f, 0x50, 0xd2, 0xd9, + 0x6c, 0xd0, 0xf4, 0xc3, 0x9d, 0x5d, 0x1a, 0xde, 0xc3, 0x9d, 0xaf, 0xb7, + 0xda, 0xe2, 0xb3, 0xc9, 0x30, 0xd2, 0x1e, 0x51, 0xd0, 0x30, 0x98, 0x2f, + 0x5b, 0xcc, 0x9b, 0x6e, 0x56, 0x6c, 0xeb, 0x6e, 0x5e, 0x42, 0xbd, 0xdd, + 0x93, 0x74, 0x16, 0x1c, 0x46, 0x6d, 0x19, 0x67, 0x9a, 0x7b, 0x11, 0xed, + 0x98, 0xa4, 0x69, 0xe1, 0x66, 0xaf, 0xd8, 0x52, 0x89, 0xe3, 0xc6, 0x0f, + 0x99, 0x30, 0xf5, 0xce, 0x0d, 0x1f, 0x89, 0x54, 0x8d, 0x23, 0xc4, 0xa7, + 0xb1, 0x0a, 0x6c, 0x00, 0xc5, 0x45, 0x11, 0x95, 0x6b, 0x63, 0xa0, 0x9e, + 0xab, 0xbe, 0x48, 0xa2, 0xb7, 0x7e, 0x5b, 0xb1, 0x6c, 0x55, 0x8c, 0x47, + 0x45, 0x9b, 0xfd, 0xb5, 0x61, 0x0b, 0x92, 0xec, 0x34, 0x8b, 0x75, 0x77, + 0x29, 0x0f, 0xac, 0x18, 0x12, 0x4c, 0x5b, 0x06, 0x52, 0x96, 0x26, 0x7c, + 0xbf, 0x7d, 0xf3, 0xb2, 0x4b, 0x57, 0xe9, 0x00, 0x03, 0x4d, 0xb2, 0x7e, + 0xe4, 0x27, 0xb4, 0x86, 0x18, 0x58, 0xb1, 0x52, 0xc3, 0x8b, 0x44, 0xd1, + 0xa0, 0x84, 0x4c, 0xb8, 0x6d, 0x18, 0xe2, 0x80, 0x46, 0x5e, 0x4d, 0x23, + 0xb7, 0x50, 0x1d, 0x86, 0x56, 0x84, 0xaf, 0x36, 0xac, 0xa8, 0x0a, 0x11, + 0x2d, 0xad, 0x40, 0x39, 0x25, 0xbd, 0x90, 0xea, 0x83, 0x05, 0xfe, 0x2c, + 0x59, 0xed, 0xc4, 0x08, 0xfa, 0xc9, 0x31, 0xc1, 0x7b, 0xc8, 0x79, 0xf5, + 0x68, 0x60, 0x9d, 0xab, 0x1c, 0x84, 0xa2, 0x59, 0x87, 0x14, 0xa1, 0x20, + 0x83, 0xbb, 0x43, 0x11, 0xf2, 0x41, 0x4c, 0x79, 0x08, 0xb5, 0x95, 0x62, + 0x44, 0xf2, 0x26, 0x03, 0x72, 0x50, 0xf5, 0x85, 0x55, 0xfd, 0x0e, 0x90, + 0x2b, 0x21, 0x92, 0x03, 0xd9, 0x18, 0x71, 0xe9, 0x6e, 0x54, 0x5b, 0xd1, + 0x22, 0xa8, 0xd2, 0x29, 0x46, 0x6e, 0xd3, 0x9f, 0xb4, 0x3e, 0x56, 0xce, + 0x4f, 0x6e, 0x05, 0x2e, 0x4f, 0x37, 0x33, 0x8e, 0xe2, 0x2c, 0x7a, 0xca, + 0x2d, 0x6e, 0xd2, 0x5b, 0x82, 0xf9, 0xf6, 0x85, 0x06, 0x6d, 0x39, 0x2e, + 0x85, 0x4a, 0x17, 0x33, 0x23, 0x29, 0x5c, 0x0f, 0x60, 0xec, 0xb8, 0xeb, + 0xd8, 0x96, 0x45, 0xef, 0x2f, 0x9f, 0x0b, 0x4b, 0x67, 0xc1, 0xd0, 0xa2, + 0x5b, 0x25, 0x61, 0xcd, 0x41, 0x26, 0xe3, 0x5a, 0xe5, 0x48, 0x0d, 0x15, + 0xa3, 0x70, 0xc5, 0x62, 0xa1, 0x30, 0x35, 0xf8, 0xf0, 0x7d, 0xb5, 0xa1, + 0xe9, 0xb7, 0x12, 0xda, 0x23, 0x17, 0x05, 0xba, 0x86, 0x19, 0x6e, 0x46, + 0xf0, 0xd0, 0x79, 0xae, 0xf5, 0x4d, 0xe1, 0xef, 0x0b, 0x58, 0xc0, 0x2b, + 0x76, 0xa1, 0x13, 0x4f, 0xcc, 0x8c, 0xa1, 0x04, 0x2e, 0x79, 0x39, 0x29, + 0x06, 0x28, 0xf9, 0x10, 0x71, 0x49, 0x85, 0xa8, 0x92, 0xc2, 0x6b, 0x82, + 0xb8, 0x96, 0x12, 0xde, 0x3a, 0x2c, 0x01, 0x7b, 0x18, 0x56, 0xb8, 0x8f, + 0x7d, 0x4b, 0xb6, 0x08, 0x96, 0x8b, 0x32, 0xc8, 0x9a, 0xe5, 0x68, 0xf0, + 0xbc, 0x58, 0x54, 0x0a, 0x6e, 0xa6, 0xb4, 0x1e, 0xb9, 0x0f, 0xc3, 0xf1, + 0x4f, 0xda, 0xb8, 0xe0, 0xc7, 0x67, 0x3f, 0x44, 0x2c, 0xe6, 0x1e, 0x4e, + 0x28, 0x1d, 0xb7, 0xf9, 0x15, 0xf4, 0x33, 0x58, 0x70, 0xf5, 0x0b, 0xb7, + 0xe0, 0x93, 0x2b, 0xaf, 0x5a, 0xe2, 0x87, 0x11, 0x77, 0xb3, 0x8f, 0x23, + 0x31, 0xeb, 0x0d, 0xc3, 0x48, 0xc7, 0x67, 0x46, 0x61, 0xf0, 0x98, 0x61, + 0xdc, 0xf0, 0x8d, 0x16, 0xaa, 0xfd, 0x2d, 0xdf, 0xd0, 0xb8, 0x31, 0x28, + 0x32, 0xc1, 0xfb, 0x22, 0x2c, 0x61, 0xaa, 0x41, 0x9b, 0x9c, 0x64, 0x0a, + 0xa6, 0xf4, 0x41, 0x07, 0xd0, 0x4a, 0x8f, 0xa8, 0xac, 0x44, 0x65, 0x9f, + 0x44, 0x56, 0xe2, 0x90, 0x1e, 0x7f, 0xb8, 0x09, 0xb8, 0x54, 0xbf, 0x4f, + 0xbc, 0xac, 0x24, 0x53, 0x5b, 0x12, 0x98, 0x4c, 0x5e, 0x32, 0x51, 0x89, + 0x24, 0xa5, 0x18, 0xd8, 0x54, 0x71, 0x78, 0x43, 0x79, 0x0c, 0xe4, 0xbc, + 0x22, 0x53, 0xe2, 0x69, 0x64, 0xdb, 0x44, 0x5a, 0x1b, 0x7a, 0x09, 0x3a, + 0x37, 0xa8, 0x7d, 0xc2, 0x72, 0xa4, 0x85, 0x54, 0xc1, 0x27, 0xa2, 0x5e, + 0xcd, 0x0c, 0xab, 0x31, 0xa7, 0x85, 0x12, 0xa9, 0x5c, 0xd2, 0xb8, 0x6c, + 0xa0, 0x96, 0x97, 0x33, 0x70, 0x10, 0x3e, 0x41, 0xe3, 0xa2, 0x74, 0xe6, + 0x1f, 0x42, 0xe7, 0xcc, 0x4b, 0x98, 0x39, 0xfa, 0xdf, 0x09, 0x86, 0x53, + 0x13, 0xde, 0x50, 0x22, 0xaf, 0xd8, 0xd5, 0xe7, 0x11, 0x56, 0x56, 0x5d, + 0xf6, 0xee, 0x52, 0x5c, 0xe1, 0x2d, 0x6f, 0x86, 0x58, 0xdd, 0x9b, 0x8c, + 0xb5, 0x44, 0x7c, 0xf7, 0xd1, 0x7d, 0x18, 0xc2, 0xda, 0xb2, 0x40, 0x10, + 0x06, 0x9a, 0xd9, 0xe7, 0xdc, 0x66, 0xdf, 0xe9, 0xdb, 0x1a, 0x6d, 0x75, + 0xef, 0x81, 0x69, 0x8a, 0x02, 0x93, 0x2a, 0xeb, 0x11, 0x7e, 0x9c, 0x37, + 0xef, 0xa2, 0xf5, 0x8a, 0xbe, 0x12, 0x68, 0x39, 0x85, 0xb4, 0xc6, 0xb5, + 0x26, 0xff, 0x90, 0x55, 0x39, 0xef, 0x83, 0xf4, 0x10, 0x9e, 0x73, 0x06, + 0x12, 0x4a, 0x9e, 0x93, 0xd3, 0x94, 0xf2, 0x4b, 0x8c, 0xb1, 0xcc, 0x8f, + 0x56, 0x49, 0xb0, 0x0a, 0xba, 0x72, 0xd6, 0x8a, 0x80, 0xe6, 0xb8, 0x25, + 0x05, 0x24, 0xdd, 0x6a, 0xef, 0xc6, 0xc1, 0x9f, 0xe7, 0xb3, 0xbc, 0xba, + 0xc2, 0xf8, 0x07, 0xcc, 0x0a, 0xbc, 0xcc, 0xba, 0x82, 0x04, 0x2a, 0x64, + 0x01, 0x2a, 0x30, 0x5c, 0x68, 0xc8, 0x27, 0xe1, 0x86, 0x51, 0xc5, 0x01, + 0x4e, 0x88, 0xc0, 0x3c, 0xf1, 0x23, 0x54, 0x9b, 0x39, 0x4c, 0xc5, 0xef, + 0x42, 0x33, 0x4b, 0xb9, 0x72, 0x61, 0xae, 0x2d, 0x71, 0xae, 0x56, 0xfc, + 0xf1, 0xdc, 0x05, 0xf4, 0x5d, 0x10, 0xbe, 0x34, 0xc6, 0xc9, 0x6e, 0xe2, + 0x86, 0x9e, 0x9e, 0xc3, 0x26, 0x91, 0xa6, 0x95, 0xa0, 0xcd, 0xa8, 0x64, + 0xb0, 0xd4, 0x69, 0x3a, 0x84, 0x2f, 0x76, 0x77, 0xfa, 0xdf, 0xd8, 0x17, + 0xa0, 0x61, 0x4b, 0x54, 0xec, 0x52, 0x2a, 0x5b, 0xbc, 0x65, 0x6b, 0xc4, + 0x0c, 0x2a, 0x45, 0xfb, 0x6c, 0xc9, 0x15, 0x4c, 0xdc, 0x9a, 0xbd, 0x8f, + 0x9a, 0x43, 0xff, 0x6b, 0x69, 0xc2, 0xf5, 0x70, 0x0e, 0x2f, 0xa1, 0xf5, + 0x82, 0xd2, 0x36, 0x89, 0xf0, 0x9e, 0x77, 0x05, 0xb5, 0x92, 0x7d, 0x0b, + 0x0a, 0x9e, 0x14, 0xc5, 0x69, 0x60, 0x6d, 0x80, 0xe4, 0xe4, 0xd5, 0x21, + 0xea, 0xc7, 0x62, 0x78, 0xa6, 0xcf, 0x2d, 0x4a, 0x63, 0x9c, 0x82, 0xc4, + 0x00, 0x32, 0x47, 0x36, 0xa5, 0x82, 0xa4, 0x02, 0x80, 0x3f, 0xc9, 0x46, + 0x3d, 0xad, 0xd5, 0x47, 0x3d, 0x90, 0xd4, 0x4e, 0x0c, 0xc7, 0x43, 0x44, + 0x33, 0x02, 0xb4, 0x48, 0x7f, 0x82, 0x00, 0x1d, 0x43, 0x40, 0x2f, 0x63, + 0x3f, 0x13, 0x64, 0xb5, 0xd2, 0x68, 0x8c, 0xf2, 0xec, 0x91, 0xf5, 0x2c, + 0x96, 0x13, 0x96, 0x68, 0x9b, 0x80, 0x02, 0xf1, 0x8d, 0x15, 0xa0, 0xef, + 0x7b, 0xfb, 0x4f, 0x9e, 0x78, 0xf3, 0x36, 0xcd, 0x9a, 0x45, 0x07, 0x9c, + 0x7b, 0xe2, 0xab, 0x5d, 0x58, 0x55, 0xd5, 0x29, 0xd6, 0x95, 0xe5, 0x8c, + 0x3b, 0xeb, 0x09, 0xc7, 0xab, 0x32, 0x8f, 0x9c, 0x09, 0x32, 0x69, 0x22, + 0x11, 0x4e, 0xf3, 0x58, 0xc2, 0xd0, 0x84, 0x7c, 0x06, 0x07, 0x95, 0x4a, + 0xcc, 0x82, 0x8a, 0xc7, 0xd5, 0x38, 0xb2, 0x7a, 0x48, 0x50, 0xcd, 0x9c, + 0x06, 0x4e, 0x73, 0xdc, 0x90, 0x4d, 0xda, 0x70, 0x08, 0x64, 0x2c, 0x85, + 0xa4, 0x12, 0xfe, 0x80, 0x95, 0x07, 0xf3, 0x0f, 0x71, 0x01, 0x4d, 0x0e, + 0x7d, 0x9a, 0x25, 0xdf, 0x53, 0x3c, 0x09, 0xc3, 0x3f, 0x13, 0x16, 0xe8, + 0xa5, 0xc2, 0x87, 0x78, 0x88, 0x2c, 0x6a, 0xd4, 0x97, 0x1a, 0xbc, 0xa3, + 0x51, 0x36, 0xd6, 0x12, 0x48, 0x17, 0x37, 0xf4, 0x54, 0xaa, 0xe3, 0xe6, + 0x40, 0xf2, 0x70, 0x54, 0x87, 0x18, 0xd4, 0x5c, 0xdf, 0x60, 0x18, 0xfc, + 0xf7, 0xb4, 0xa0, 0x4f, 0xb5, 0x16, 0x93, 0xe0, 0xbe, 0x7d, 0x2f, 0x37, + 0x90, 0x82, 0x0c, 0xdb, 0x88, 0x40, 0x1b, 0x01, 0x41, 0x2a, 0x60, 0x7d, + 0x31, 0xf4, 0x72, 0x1a, 0x9e, 0xe4, 0x75, 0x23, 0x01, 0x54, 0x52, 0xc1, + 0xa1, 0x71, 0x6d, 0x8c, 0x8c, 0x1a, 0x1a, 0x33, 0x83, 0xbe, 0x65, 0xec, + 0x5b, 0xa7, 0xec, 0x67, 0x5b, 0x89, 0x43, 0x05, 0x5d, 0x16, 0x68, 0x07, + 0xe1, 0xa7, 0x65, 0xf6, 0xbe, 0x3c, 0xd7, 0x1b, 0xae, 0xfc, 0xc5, 0x4b, + 0x14, 0x90, 0xb3, 0x7c, 0x94, 0x6a, 0x6a, 0xce, 0x16, 0xb5, 0xd8, 0x69, + 0x38, 0x0f, 0xc7, 0x12, 0x35, 0x71, 0x3e, 0x99, 0xc2, 0x2f, 0x8b, 0x8c, + 0x07, 0xc1, 0x06, 0x05, 0x5e, 0x26, 0x98, 0x0a, 0x5a, 0x29, 0xa8, 0xe0, + 0xb5, 0xd9, 0x20, 0xb9, 0xc3, 0x08, 0x4d, 0xa7, 0x1b, 0x9b, 0x17, 0x24, + 0x8b, 0x66, 0xb0, 0xa0, 0xd5, 0x97, 0x60, 0x30, 0x2d, 0x41, 0x27, 0x88, + 0x16, 0x83, 0xdb, 0xc4, 0xa2, 0xea, 0xd4, 0x84, 0x28, 0xea, 0x15, 0xd9, + 0x52, 0xab, 0xfc, 0x1f, 0x99, 0x84, 0x1d, 0x90, 0x31, 0x37, 0xb5, 0x70, + 0x05, 0x94, 0xc3, 0x90, 0x21, 0x26, 0xcf, 0x80, 0x1a, 0x66, 0x62, 0x93, + 0x44, 0x6a, 0x51, 0x7d, 0x2d, 0x02, 0x8d, 0x16, 0xbc, 0x68, 0xb2, 0x3e, + 0x94, 0xd9, 0xe5, 0x02, 0x21, 0x02, 0x05, 0x30, 0x8c, 0x2a, 0x36, 0xf2, + 0x5e, 0xea, 0x53, 0xf3, 0x7c, 0xee, 0x50, 0x8b, 0x45, 0x0f, 0xd9, 0x0a, + 0xf2, 0x3c, 0x70, 0x87, 0x5f, 0xd9, 0xd9, 0x59, 0xe8, 0xfc, 0x68, 0x00, + 0x2a, 0xde, 0x3b, 0xa5, 0x0c, 0x7f, 0xa6, 0x5e, 0xf9, 0x9a, 0xe6, 0x5c, + 0x00, 0x02, 0xd9, 0xf3, 0x1f, 0x92, 0x28, 0x5e, 0x97, 0x6e, 0x1f, 0x9a, + 0xb1, 0x44, 0x8a, 0x52, 0x11, 0x3d, 0x83, 0xf6, 0x08, 0x7e, 0x49, 0xd3, + 0xa7, 0xf8, 0xe6, 0xec, 0x72, 0xd5, 0x49, 0x85, 0xb3, 0x66, 0xef, 0x01, + 0x4c, 0x88, 0xa0, 0xc1, 0x31, 0x56, 0x96, 0xd9, 0x24, 0x0d, 0x8f, 0x8b, + 0x61, 0x58, 0x34, 0xd5, 0x2d, 0xf1, 0x94, 0x26, 0x7f, 0xe7, 0x22, 0xd7, + 0x70, 0x46, 0xf3, 0xa9, 0x96, 0x07, 0x6c, 0x48, 0xae, 0x5d, 0xb9, 0xc9, + 0x37, 0x80, 0x19, 0xe1, 0x3a, 0x6e, 0xc4, 0x85, 0x6f, 0xe9, 0x4c, 0xaa, + 0x26, 0x49, 0x4c, 0xb7, 0xc7, 0xb4, 0x1c, 0xea, 0x20, 0x86, 0x42, 0x3b, + 0x09, 0xde, 0x88, 0x65, 0x0a, 0x1c, 0xe9, 0xd7, 0xf9, 0x65, 0x12, 0x37, + 0x44, 0x35, 0x61, 0x31, 0x7e, 0xe7, 0x01, 0x5f, 0x36, 0xcf, 0x13, 0xe9, + 0xf0, 0xdb, 0xef, 0xa3, 0xb7, 0x5a, 0xee, 0x9d, 0x6d, 0xa9, 0x01, 0x33, + 0xbc, 0xcc, 0x5b, 0xa7, 0xc7, 0x21, 0xd5, 0x06, 0x53, 0x54, 0x5d, 0x15, + 0xc8, 0x3d, 0x70, 0xf5, 0xf1, 0x90, 0x63, 0x19, 0xf1, 0x70, 0x06, 0x2b, + 0x55, 0x18, 0x7d, 0xf8, 0x6f, 0x34, 0x2c, 0xae, 0x35, 0x59, 0x5c, 0xcd, + 0xf0, 0x0f, 0x6c, 0x0b, 0x5b, 0xfa, 0x76, 0xb7, 0x35, 0x74, 0x75, 0x7b, + 0xf5, 0x78, 0x90, 0x4d, 0xdf, 0xb2, 0x8b, 0xc8, 0x71, 0x00, 0x8d, 0x2b, + 0x93, 0x98, 0x65, 0x8a, 0x4d, 0xa2, 0x2b, 0x5b, 0x83, 0x06, 0xb9, 0xa6, + 0xaf, 0x7b, 0x85, 0x71, 0x56, 0x5a, 0xd9, 0x4b, 0x6e, 0xfc, 0x94, 0xed, + 0xf1, 0xb8, 0x9a, 0xd1, 0x54, 0x3a, 0xe8, 0xda, 0xb9, 0xfd, 0xf6, 0xe9, + 0xd5, 0xe2, 0x92, 0x2a, 0x6d, 0xa2, 0x87, 0xa7, 0x73, 0xd7, 0x3c, 0x34, + 0x84, 0x5a, 0x0c, 0x8d, 0xb9, 0xb0, 0x0a, 0x75, 0x79, 0x90, 0xe1, 0x20, + 0xba, 0x0e, 0x2d, 0x08, 0x60, 0x10, 0x17, 0x77, 0xea, 0x20, 0x78, 0xed, + 0xb7, 0x9d, 0x2e, 0x2f, 0x80, 0x60, 0x05, 0x2b, 0xa2, 0x67, 0x5d, 0xc4, + 0xa3, 0xbc, 0xc9, 0x06, 0xdf, 0x7e, 0x8f, 0x96, 0x8b, 0x0f, 0xfd, 0xab, + 0x7a, 0x3a, 0xf9, 0x03, 0xbd, 0x8b, 0x2b, 0xb0, 0x8d, 0x7f, 0x76, 0x92, + 0x65, 0x11, 0x04, 0x0e, 0xb4, 0x6f, 0xc0, 0x41, 0xe4, 0xbb, 0x97, 0xc7, + 0x45, 0xd1, 0xf6, 0x6e, 0x3c, 0x47, 0x07, 0x8f, 0xa1, 0x18, 0xe7, 0x54, + 0x0d, 0x8e, 0x22, 0x8d, 0x78, 0xcf, 0x28, 0x7c, 0x28, 0xba, 0x1d, 0xdc, + 0x2d, 0x49, 0x2e, 0x70, 0xb6, 0x27, 0x2b, 0x07, 0xfe, 0xb6, 0xcb, 0x40, + 0xf3, 0x78, 0xa3, 0xc7, 0x13, 0x65, 0x72, 0xb7, 0x12, 0x4c, 0x7f, 0xb0, + 0x37, 0xf0, 0x07, 0x1c, 0x10, 0xb8, 0x8a, 0xda, 0x46, 0x8c, 0x5e, 0x12, + 0x7d, 0x74, 0x9b, 0x42, 0x5d, 0xd4, 0xe3, 0x0d, 0x37, 0x77, 0x77, 0x83, + 0xc3, 0xb5, 0x36, 0xfe, 0xb0, 0x21, 0x2a, 0xa6, 0x25, 0xd4, 0x27, 0x7f, + 0x5f, 0x14, 0xb5, 0xaf, 0x26, 0x33, 0x2a, 0x16, 0x08, 0x05, 0x41, 0x1f, + 0x73, 0x79, 0x81, 0xb6, 0xf1, 0xfd, 0xdc, 0xa1, 0x11, 0x76, 0xf1, 0xaf, + 0x9f, 0x3b, 0x61, 0x90, 0x3f, 0xd3, 0x3a, 0xff, 0x21, 0x9f, 0xfd, 0x01, + 0x07, 0xfa, 0x73, 0xa7, 0x23, 0xc1, 0xde, 0x77, 0x65, 0x8d, 0xc4, 0x1b, + 0xb5, 0xc1, 0x1d, 0xb8, 0xf6, 0x5d, 0xf3, 0x51, 0xeb, 0x9d, 0x8d, 0x35, + 0x1a, 0x77, 0xd0, 0x9a, 0x14, 0x85, 0xdf, 0x5c, 0x25, 0xe4, 0x3f, 0x61, + 0x09, 0x1a, 0xd3, 0xef, 0xba, 0xa2, 0xdc, 0xfe, 0x0b, 0x5c, 0x4c, 0x14, + 0xd1, 0xab, 0x49, 0x5a, 0x5d, 0xb1, 0x4e, 0x96, 0xcf, 0x1a, 0x85, 0xc3, + 0x35, 0xf9, 0x23, 0xa3, 0xea, 0xa4, 0x6e, 0x81, 0xed, 0x45, 0xe5, 0xc3, + 0x7f, 0x82, 0x26, 0x39, 0x6a, 0x95, 0x50, 0x9f, 0xe8, 0x54, 0xa1, 0x54, + 0xa5, 0x20, 0x08, 0x75, 0xc1, 0x37, 0x19, 0x51, 0x97, 0xc0, 0xe3, 0xb3, + 0x1b, 0xad, 0x11, 0xd5, 0x50, 0x65, 0xd3, 0x9c, 0x92, 0x5c, 0x61, 0xe0, + 0x93, 0x8c, 0x04, 0xbb, 0x6d, 0x64, 0x9a, 0x84, 0x8f, 0x52, 0xcd, 0x53, + 0xd4, 0xa1, 0x51, 0xc9, 0xe0, 0xaf, 0x64, 0x46, 0x3c, 0xfb, 0x98, 0x08, + 0x37, 0xb0, 0x95, 0xb2, 0xfa, 0xb6, 0x03, 0x17, 0xf9, 0x1f, 0xd0, 0xca, + 0x91, 0xcd, 0xfe, 0x90, 0x0c, 0x26, 0x0b, 0xd8, 0x8a, 0x70, 0x74, 0x3e, + 0xf4, 0xa6, 0xb7, 0x30, 0x46, 0xdb, 0x84, 0xd5, 0x7b, 0xa0, 0xa7, 0x29, + 0x1d, 0x8d, 0x34, 0x02, 0x44, 0xa3, 0xa6, 0x85, 0xd7, 0xf1, 0x21, 0x72, + 0xe7, 0x44, 0xbe, 0x97, 0x63, 0x12, 0xf3, 0x2b, 0x12, 0xd6, 0xbf, 0x3d, + 0xfd, 0xe3, 0x1f, 0xf4, 0xa1, 0x9f, 0x3b, 0x7f, 0xe9, 0xf1, 0xa7, 0x84, + 0x87, 0x7d, 0x90, 0x9c, 0xfe, 0x11, 0x29, 0xef, 0x5e, 0x96, 0xb0, 0xdc, + 0xd2, 0xf7, 0xfc, 0x0b, 0x51, 0x5d, 0xd2, 0xa6, 0xa0, 0x67, 0x36, 0xb2, + 0x24, 0x79, 0x9f, 0xdd, 0x12, 0xb4, 0x1c, 0xc5, 0x0b, 0x61, 0x64, 0x30, + 0xb0, 0xad, 0x69, 0x61, 0x61, 0x28, 0x54, 0x6b, 0x84, 0xa5, 0x99, 0x01, + 0x96, 0x41, 0x20, 0x73, 0xa1, 0xb2, 0x70, 0xaa, 0xf2, 0xf9, 0x77, 0xd9, + 0x78, 0xda, 0xea, 0x5b, 0x29, 0x54, 0xd1, 0x0c, 0x28, 0x47, 0x91, 0x22, + 0x96, 0x88, 0x93, 0x63, 0x0c, 0x0b, 0x08, 0x15, 0x4b, 0xd8, 0x7e, 0xca, + 0xbf, 0x55, 0x1a, 0xee, 0xcd, 0x32, 0xf2, 0xc6, 0xef, 0x36, 0x34, 0xb0, + 0x7a, 0x3a, 0xa5, 0x3b, 0x81, 0xdc, 0x58, 0x5c, 0x7d, 0xe8, 0x0f, 0xde, + 0x60, 0x28, 0x5e, 0x6d, 0x41, 0x06, 0x1a, 0x17, 0x13, 0x29, 0x31, 0x05, + 0x74, 0x03, 0x2a, 0x30, 0x35, 0xa9, 0xd2, 0x34, 0x5d, 0x97, 0x38, 0x73, + 0x29, 0x82, 0xa1, 0x7d, 0xc6, 0xe2, 0x7c, 0x3e, 0xe3, 0x3a, 0xa5, 0x2e, + 0xba, 0x86, 0xe0, 0x05, 0x80, 0x0a, 0xff, 0x10, 0xf2, 0x2c, 0x14, 0xe7, + 0xbd, 0xa7, 0x36, 0xaf, 0x90, 0x03, 0xd6, 0xa4, 0x5c, 0x0a, 0xf9, 0x96, + 0xd2, 0x1a, 0xfd, 0xe4, 0x05, 0x59, 0x16, 0xd8, 0xd8, 0xa4, 0x19, 0x26, + 0x24, 0x07, 0x6b, 0x34, 0x51, 0xa8, 0x07, 0xa9, 0xf7, 0x21, 0x91, 0xf8, + 0xef, 0x44, 0xbf, 0xc7, 0xb3, 0xa4, 0xb0, 0xc4, 0x38, 0x1f, 0x59, 0x75, + 0x50, 0x94, 0x1f, 0xfc, 0x45, 0xe2, 0x9f, 0x7b, 0xbb, 0x07, 0xac, 0x71, + 0x11, 0xca, 0x25, 0x7f, 0xa6, 0x4d, 0x78, 0x54, 0xe5, 0x10, 0xca, 0xcd, + 0xcb, 0x16, 0xb5, 0xb1, 0x67, 0x6d, 0xe0, 0x29, 0x51, 0x0f, 0xb7, 0x35, + 0x26, 0x5e, 0x3d, 0x4d, 0xa8, 0x55, 0x9b, 0x48, 0xd0, 0xea, 0xa6, 0xe4, + 0xac, 0x62, 0x7d, 0x4e, 0x3c, 0xda, 0x82, 0x8b, 0xcc, 0x30, 0xb1, 0x35, + 0x25, 0xc2, 0x5b, 0x30, 0x12, 0x8f, 0xca, 0x00, 0x9e, 0x7b, 0x7c, 0x49, + 0x29, 0x88, 0x7a, 0x31, 0xc5, 0x2c, 0x81, 0xd1, 0x81, 0xb8, 0x0e, 0x09, + 0xcd, 0x96, 0x90, 0x6c, 0x45, 0x0a, 0x13, 0x39, 0x3d, 0x54, 0x26, 0xb1, + 0x2a, 0xd0, 0xe4, 0x23, 0x10, 0x98, 0x86, 0xae, 0x35, 0x0e, 0x6c, 0x88, + 0xf8, 0x91, 0x98, 0x74, 0x98, 0xe4, 0x36, 0x37, 0x54, 0x53, 0xc5, 0xa6, + 0x53, 0x76, 0x0c, 0xb3, 0xbd, 0x20, 0x45, 0x7c, 0x5e, 0xa7, 0xb3, 0x1e, + 0x98, 0x6f, 0x38, 0xd0, 0x9d, 0xc3, 0xc7, 0x56, 0x95, 0x87, 0x40, 0xee, + 0x63, 0x44, 0x6c, 0x1b, 0x42, 0xea, 0xd6, 0x4a, 0x1a, 0x61, 0x8d, 0x22, + 0x40, 0x0d, 0xa4, 0xc9, 0xc6, 0xb7, 0x5b, 0x1b, 0xa1, 0xe2, 0x62, 0x53, + 0x1e, 0x8b, 0x31, 0xb2, 0xd5, 0xb7, 0x61, 0xf9, 0xda, 0xa4, 0x91, 0x4f, + 0x31, 0xee, 0x24, 0xa3, 0xcd, 0x60, 0x1f, 0x6e, 0x15, 0x28, 0x9e, 0x2b, + 0x4c, 0xe5, 0x33, 0x22, 0x74, 0x06, 0x6d, 0x66, 0x9a, 0xf2, 0x46, 0x50, + 0xae, 0xc3, 0x57, 0x1d, 0x78, 0xd9, 0x8d, 0x8e, 0x0f, 0x1a, 0x78, 0xc5, + 0x3c, 0x73, 0x52, 0xab, 0xea, 0x59, 0x05, 0x89, 0xb0, 0x21, 0xae, 0x6d, + 0x7c, 0xbb, 0xc9, 0x3c, 0x38, 0x98, 0x18, 0x5c, 0x37, 0xe1, 0x46, 0xe4, + 0x67, 0x5d, 0x67, 0x42, 0x43, 0xcd, 0x27, 0x92, 0xa7, 0x68, 0x94, 0xfc, + 0x8e, 0xcc, 0xcc, 0xf2, 0xc8, 0xd3, 0x6d, 0xfa, 0xa8, 0x21, 0x62, 0x35, + 0x5f, 0x84, 0x15, 0xa5, 0x7f, 0xbf, 0xc7, 0x27, 0x54, 0x70, 0xdc, 0x48, + 0xfa, 0x7d, 0x50, 0x19, 0xab, 0x69, 0x13, 0x74, 0x4a, 0xe1, 0xba, 0xe8, + 0xf6, 0x32, 0x4c, 0x7f, 0x0d, 0xf6, 0x96, 0x9a, 0x35, 0xe6, 0x37, 0x12, + 0xd3, 0x0a, 0x7f, 0x5d, 0x7e, 0x8b, 0x51, 0x20, 0x87, 0x1a, 0x8b, 0xa9, + 0xb1, 0x9a, 0x8c, 0xd0, 0xce, 0x6c, 0x41, 0x4c, 0x17, 0xb8, 0x9c, 0x4f, + 0x06, 0xb9, 0x84, 0x8b, 0x73, 0xc5, 0x1d, 0x8a, 0xd2, 0xca, 0x26, 0x95, + 0x14, 0x80, 0xc2, 0x3b, 0x48, 0x6c, 0x89, 0xae, 0xb6, 0x0c, 0x9a, 0xf8, + 0xd9, 0xbe, 0x66, 0x82, 0xab, 0x8c, 0xa5, 0x77, 0x2c, 0x1d, 0x25, 0x16, + 0xe2, 0x95, 0x7c, 0x8d, 0x5d, 0x18, 0x7c, 0xb8, 0x7a, 0x51, 0xa5, 0xee, + 0x60, 0xf2, 0xa4, 0x87, 0x5f, 0xdb, 0x11, 0xaa, 0x42, 0xf6, 0x57, 0xec, + 0x43, 0xed, 0xaa, 0xdc, 0xd1, 0xa3, 0x20, 0xd7, 0x30, 0x35, 0xe2, 0xa9, + 0x12, 0x0d, 0x2f, 0xbd, 0xf0, 0x42, 0x54, 0x6a, 0x7a, 0x0a, 0x46, 0xa4, + 0x00, 0x80, 0x11, 0xcd, 0xc3, 0x23, 0xc5, 0xa2, 0x2c, 0x00, 0x32, 0x35, + 0x71, 0x70, 0xbe, 0x23, 0x40, 0x42, 0xb9, 0xac, 0x09, 0xea, 0xec, 0xeb, + 0xc7, 0x6e, 0xa0, 0xed, 0x6a, 0x61, 0x83, 0x13, 0xe9, 0x64, 0x9a, 0x43, + 0x17, 0x82, 0x16, 0x0a, 0x0a, 0x13, 0x49, 0x75, 0x26, 0x66, 0x53, 0x69, + 0xa1, 0x68, 0x4f, 0x9f, 0x7f, 0xd0, 0x4d, 0x6f, 0xf6, 0xd0, 0xa4, 0x3f, + 0x27, 0x22, 0xeb, 0x2b, 0xdc, 0x15, 0xd3, 0xe0, 0x4a, 0x12, 0x44, 0xcb, + 0xe4, 0x78, 0x51, 0x12, 0x1b, 0x96, 0x6f, 0xf9, 0x1e, 0x53, 0x80, 0x53, + 0x91, 0xe4, 0x5e, 0x1d, 0xbe, 0x7e, 0x7b, 0xf8, 0xb2, 0xaf, 0x76, 0x4a, + 0xa5, 0xd9, 0xcf, 0x53, 0x86, 0x82, 0x9a, 0x8c, 0x2a, 0x09, 0xc9, 0x47, + 0x2a, 0xfd, 0xa7, 0x23, 0xe4, 0xa0, 0x9d, 0x7b, 0x33, 0xae, 0x3f, 0xb6, + 0x52, 0x10, 0x97, 0x4d, 0xb8, 0xbf, 0x52, 0x50, 0x03, 0x17, 0x5b, 0xcd, + 0xb5, 0x3d, 0x49, 0x5e, 0x15, 0x87, 0x02, 0x7e, 0xc2, 0xf2, 0x6d, 0xf0, + 0x28, 0x84, 0xcf, 0xbc, 0x31, 0x37, 0x9f, 0xa6, 0x73, 0xda, 0x93, 0xad, + 0xe4, 0x0c, 0xc1, 0xd7, 0x71, 0xb4, 0x94, 0x6b, 0x8d, 0x97, 0x76, 0xa0, + 0xb1, 0x50, 0xf8, 0x4d, 0x64, 0x0b, 0xb2, 0x46, 0x46, 0x41, 0x62, 0x41, + 0x7e, 0xe6, 0x6e, 0xf8, 0x43, 0xb3, 0xc1, 0x90, 0x26, 0xa6, 0x39, 0x6c, + 0xa1, 0x90, 0x43, 0x5c, 0x65, 0xd7, 0x0d, 0xf2, 0xce, 0x80, 0xd7, 0x8f, + 0xaf, 0x96, 0xde, 0xb2, 0xcf, 0xda, 0x11, 0xeb, 0x36, 0x30, 0xb5, 0x9f, + 0x6d, 0xdf, 0x37, 0x9c, 0xc2, 0x83, 0x8b, 0xdf, 0xc1, 0x4d, 0xdf, 0xf8, + 0x18, 0x34, 0x89, 0x27, 0x4d, 0x14, 0x38, 0x29, 0x16, 0xe8, 0xe6, 0x29, + 0x5b, 0xc6, 0x86, 0x76, 0xfe, 0x63, 0x95, 0x9d, 0x3d, 0x39, 0x37, 0xed, + 0x5b, 0x5f, 0xd7, 0x52, 0x3d, 0x56, 0x9d, 0x40, 0x17, 0x81, 0x5b, 0x32, + 0x3b, 0x7b, 0x50, 0x89, 0x47, 0x49, 0x5c, 0x5b, 0x54, 0x21, 0x12, 0x40, + 0x8c, 0xc4, 0xb5, 0x25, 0x2c, 0x84, 0x97, 0xa2, 0x82, 0x24, 0xdf, 0x0b, + 0xbf, 0x7b, 0xaa, 0x48, 0x10, 0xca, 0x8d, 0xba, 0x1a, 0xf9, 0x9c, 0x88, + 0xce, 0xd1, 0x31, 0x34, 0x38, 0xb5, 0xca, 0xf2, 0x40, 0x28, 0x0d, 0x12, + 0x3d, 0x1e, 0x51, 0xed, 0x94, 0x69, 0x96, 0xce, 0x78, 0xdf, 0xdf, 0x5a, + 0xdc, 0x34, 0x59, 0x24, 0xd1, 0x9c, 0x2c, 0xd6, 0x61, 0x3f, 0x4b, 0xd2, + 0xa8, 0x24, 0x9c, 0x89, 0x71, 0x2a, 0x6f, 0x15, 0x4c, 0x1d, 0x0d, 0x90, + 0x39, 0xb9, 0x81, 0x5c, 0x74, 0x39, 0x8f, 0x84, 0x47, 0xc0, 0xf2, 0xff, + 0x70, 0x48, 0x45, 0x53, 0xe9, 0xe8, 0xc1, 0xb7, 0x97, 0x97, 0x82, 0xc0, + 0x9d, 0x7c, 0xaf, 0xba, 0x47, 0xf2, 0x34, 0x19, 0x67, 0x69, 0x4d, 0x01, + 0x11, 0xc5, 0x58, 0xbb, 0xee, 0x37, 0xf6, 0xc9, 0x33, 0x9a, 0x06, 0x3d, + 0xba, 0x1a, 0x4b, 0x1f, 0xc5, 0x69, 0xb4, 0x69, 0xb5, 0x81, 0xd4, 0xe9, + 0x9a, 0xd8, 0xe6, 0x31, 0x31, 0xd5, 0xf3, 0x1e, 0xde, 0x3c, 0x18, 0x27, + 0x12, 0x95, 0x65, 0xe1, 0x84, 0x5a, 0x71, 0x78, 0x53, 0x8e, 0xa7, 0xc6, + 0x05, 0xa6, 0xd5, 0x7b, 0xb6, 0x42, 0x75, 0xf4, 0xc5, 0x84, 0x7b, 0x4f, + 0xc7, 0x35, 0xdf, 0xf3, 0x0c, 0x7c, 0x18, 0xee, 0x0b, 0xc3, 0xeb, 0x26, + 0x47, 0x16, 0x61, 0xd8, 0xe8, 0xe1, 0x14, 0xb8, 0xd0, 0x86, 0xe1, 0xb3, + 0x18, 0x8f, 0x97, 0x10, 0x7e, 0x0e, 0x8f, 0x8e, 0x02, 0x50, 0x30, 0x27, + 0x54, 0xf9, 0xc1, 0x7f, 0xbe, 0x9c, 0xcb, 0xe6, 0x5a, 0xbb, 0x4e, 0x3a, + 0xd3, 0xb2, 0x5f, 0x16, 0x83, 0xa2, 0xee, 0xac, 0x5b, 0xf2, 0xb9, 0x8c, + 0x57, 0x3a, 0x08, 0x75, 0xbd, 0xba, 0x60, 0xf8, 0xf5, 0xa7, 0x32, 0xa7, + 0x68, 0xe1, 0xd1, 0xf0, 0xe3, 0x83, 0xe3, 0x60, 0x25, 0x02, 0x7e, 0xfb, + 0xdb, 0xf3, 0xe3, 0x37, 0xbc, 0xb0, 0x67, 0x87, 0xe7, 0xe7, 0x0e, 0x99, + 0x5a, 0x82, 0x81, 0x74, 0x9a, 0x1c, 0x06, 0x25, 0xce, 0x25, 0x5e, 0x36, + 0x0b, 0x3e, 0x96, 0x34, 0x26, 0x62, 0xb3, 0x78, 0x62, 0x2e, 0x16, 0x53, + 0xb8, 0x8e, 0x41, 0x13, 0x1c, 0x61, 0x20, 0xcd, 0x0a, 0x8f, 0xa7, 0x50, + 0x00, 0x21, 0x4f, 0x3c, 0x47, 0x14, 0x0e, 0x75, 0x4b, 0x88, 0x13, 0xd8, + 0x61, 0x4e, 0x74, 0x75, 0xff, 0x3a, 0xe7, 0x27, 0x17, 0xc7, 0xb2, 0x83, + 0x6f, 0x2f, 0x5e, 0x74, 0x14, 0x61, 0xa6, 0x51, 0x0d, 0xab, 0x20, 0x61, + 0x0b, 0x28, 0x3a, 0xb3, 0x08, 0x47, 0x43, 0xa0, 0x17, 0x0f, 0x40, 0x2b, + 0xb6, 0x85, 0x25, 0xee, 0xac, 0x5a, 0xde, 0xf8, 0x2a, 0x68, 0xab, 0xa1, + 0xf4, 0xe9, 0x11, 0xc5, 0xab, 0xfa, 0xec, 0xbc, 0x7d, 0xb4, 0x5f, 0xb6, + 0x90, 0x48, 0xcb, 0x59, 0x74, 0xc4, 0xc5, 0xd7, 0xef, 0x12, 0xcd, 0xb8, + 0x82, 0xeb, 0xbe, 0xc6, 0x7a, 0x74, 0x3e, 0xf1, 0x13, 0x74, 0x33, 0xe2, + 0xbf, 0x6f, 0xdf, 0xbc, 0xdc, 0xb6, 0x34, 0x2c, 0x46, 0x09, 0x4f, 0x39, + 0x4d, 0x4e, 0x25, 0x68, 0xe5, 0x39, 0x14, 0xba, 0x6a, 0x0e, 0xf0, 0xec, + 0x83, 0x64, 0x77, 0x46, 0x09, 0x0b, 0xc2, 0x18, 0x05, 0x2a, 0x41, 0xf1, + 0x76, 0x89, 0xd3, 0x85, 0x28, 0x93, 0x3c, 0x84, 0x67, 0x59, 0xad, 0x98, + 0x08, 0xbd, 0x58, 0xc2, 0x09, 0xf5, 0x3a, 0x8f, 0xb0, 0x90, 0x79, 0x7e, + 0xc2, 0xe0, 0x73, 0x2a, 0x8d, 0x97, 0xc0, 0x64, 0x81, 0x3a, 0x8b, 0x32, + 0xa7, 0x78, 0xf9, 0xd8, 0x53, 0x1e, 0x2f, 0xc9, 0x92, 0xb7, 0x5c, 0xf3, + 0x0c, 0x3f, 0x0e, 0x77, 0x7e, 0xb9, 0xb2, 0xfd, 0x3d, 0xdb, 0xee, 0x87, + 0xb0, 0xba, 0x0a, 0x7c, 0x99, 0x4d, 0x41, 0xde, 0x25, 0x9b, 0xe4, 0x36, + 0x99, 0x2e, 0x96, 0x23, 0xca, 0xa3, 0x4e, 0xc3, 0xae, 0x4b, 0x94, 0xee, + 0x53, 0xfe, 0x37, 0xe2, 0x0d, 0x47, 0x0c, 0xc8, 0x22, 0x46, 0x79, 0x79, + 0x90, 0x86, 0xa6, 0x95, 0xaa, 0x24, 0x47, 0xb6, 0xa4, 0x48, 0x4b, 0xb5, + 0x60, 0x53, 0x52, 0x82, 0xb8, 0xd0, 0xa1, 0x9d, 0xcd, 0xf3, 0x2d, 0x73, + 0x46, 0xa0, 0xe5, 0x43, 0xda, 0x51, 0x7d, 0xda, 0x23, 0x36, 0xba, 0x2a, + 0x4d, 0x41, 0xa5, 0xd6, 0x08, 0x75, 0xa3, 0x7e, 0x33, 0x4f, 0xd0, 0x86, + 0x0c, 0x6f, 0x46, 0x92, 0xa5, 0x6d, 0x4e, 0xcb, 0xa3, 0x9f, 0x9e, 0x85, + 0xfc, 0x40, 0xba, 0x40, 0x68, 0x7c, 0x44, 0x9a, 0xa6, 0x60, 0x87, 0x62, + 0x40, 0x8c, 0x9a, 0xf2, 0xe0, 0x39, 0x55, 0x29, 0xc8, 0xe6, 0xc9, 0x55, + 0x0e, 0xaf, 0x96, 0xc3, 0x2b, 0x46, 0x8b, 0xc3, 0xa8, 0x5a, 0x90, 0x06, + 0x30, 0xaf, 0x6f, 0x76, 0x6b, 0x1c, 0xb0, 0x6f, 0xd1, 0x4a, 0x98, 0x83, + 0x8e, 0xae, 0x78, 0x68, 0x61, 0xf7, 0xeb, 0xfd, 0x27, 0x49, 0x95, 0xde, + 0x56, 0x6c, 0x5d, 0x75, 0x85, 0x12, 0xa9, 0xac, 0xa0, 0x48, 0xdb, 0x6a, + 0x2c, 0x31, 0x34, 0x8f, 0xc1, 0xc2, 0x0a, 0x37, 0x55, 0x68, 0xbe, 0x20, + 0xc3, 0xaf, 0xc0, 0x4d, 0x5b, 0xf9, 0x96, 0x30, 0x4d, 0xa0, 0x36, 0x9c, + 0x20, 0x23, 0xb0, 0xf5, 0x5d, 0x84, 0xf8, 0xf9, 0xc9, 0x7f, 0x1f, 0x77, + 0x93, 0x37, 0xc7, 0x17, 0x6f, 0xba, 0xc9, 0xf9, 0xc5, 0xe9, 0x1b, 0xf4, + 0xc2, 0xb3, 0x78, 0x84, 0xf3, 0xac, 0xa4, 0x0b, 0xf2, 0x1b, 0xd2, 0x52, + 0xc4, 0x61, 0x8d, 0x21, 0x04, 0x50, 0x7d, 0x71, 0x55, 0xd6, 0x9c, 0x2e, + 0x9b, 0xa1, 0xc8, 0xe0, 0x01, 0x4c, 0xac, 0x6d, 0xa0, 0xbc, 0x03, 0x61, + 0xb0, 0xb8, 0xa3, 0x38, 0xda, 0xe0, 0x72, 0xa7, 0xfe, 0x6b, 0xd8, 0x7d, + 0xe0, 0x80, 0x7a, 0xfa, 0x6e, 0x43, 0x9e, 0x9a, 0x86, 0xef, 0x52, 0x9d, + 0x88, 0x07, 0xc1, 0xed, 0xd7, 0x51, 0x98, 0x73, 0xe0, 0xeb, 0x9b, 0x5c, + 0x64, 0x57, 0x77, 0x51, 0xc9, 0x20, 0xa1, 0xe0, 0xb9, 0x2d, 0x8b, 0x28, + 0xa5, 0xc1, 0x56, 0xc5, 0x34, 0x23, 0xfa, 0x25, 0xd3, 0xaa, 0xf2, 0x17, + 0x8a, 0xe8, 0xe7, 0x42, 0x6c, 0xac, 0xd8, 0x77, 0x68, 0x85, 0x3b, 0x51, + 0x88, 0x58, 0xb4, 0x60, 0xd9, 0x0c, 0x28, 0x90, 0x8a, 0x44, 0x77, 0xb4, + 0xbf, 0x4e, 0x94, 0x73, 0xed, 0xce, 0xd2, 0xe7, 0xac, 0x32, 0x53, 0xb5, + 0xb0, 0x04, 0xe9, 0xc6, 0xe6, 0xbd, 0xcc, 0x0e, 0x60, 0x61, 0x77, 0xf1, + 0xc7, 0xde, 0x76, 0xb0, 0x63, 0xb6, 0xb4, 0x40, 0x93, 0xfe, 0xf4, 0xd7, + 0x6d, 0xb3, 0xef, 0x6f, 0x62, 0x89, 0x1d, 0x61, 0x42, 0x6e, 0x8f, 0xa0, + 0xcd, 0x3c, 0x33, 0xc2, 0xe2, 0x00, 0x9e, 0x03, 0x91, 0xf4, 0x1d, 0xd5, + 0x1e, 0xb0, 0x2c, 0x52, 0x16, 0xe4, 0x42, 0x96, 0x34, 0xb2, 0x6f, 0x79, + 0xb0, 0xe1, 0x14, 0x26, 0xc6, 0x31, 0xb1, 0xf3, 0xa6, 0x24, 0x2b, 0x88, + 0x0b, 0x8b, 0xa5, 0x5b, 0x24, 0x96, 0xa1, 0x2d, 0xd6, 0x00, 0x85, 0x11, + 0x82, 0x01, 0x48, 0x29, 0xe9, 0x23, 0x2f, 0x08, 0xd6, 0x2f, 0x14, 0x3d, + 0x98, 0x7b, 0xcb, 0xe2, 0x9b, 0x8c, 0x12, 0x97, 0x48, 0xd7, 0x4d, 0xb2, + 0x19, 0xc5, 0xc1, 0x8c, 0xc2, 0x54, 0xb0, 0xd2, 0xd1, 0x84, 0x03, 0xc3, + 0xf0, 0x6e, 0x1c, 0x15, 0x1c, 0x2e, 0x88, 0xe3, 0x21, 0xc0, 0x78, 0xf4, + 0xe5, 0x38, 0x94, 0x20, 0xbd, 0xcf, 0xa4, 0x21, 0x31, 0x92, 0x73, 0x22, + 0xab, 0x1b, 0x02, 0xdd, 0x35, 0x3a, 0x82, 0x33, 0xbf, 0x6a, 0xcc, 0xc1, + 0x6a, 0xab, 0x2a, 0x85, 0xe2, 0x4f, 0x15, 0x0a, 0x0f, 0xa8, 0x3a, 0xa0, + 0x95, 0x43, 0xe4, 0x30, 0x4a, 0x43, 0x58, 0x31, 0x20, 0x59, 0xcc, 0x26, + 0x18, 0xcf, 0xde, 0x40, 0x87, 0x57, 0xe1, 0x25, 0x8e, 0x10, 0x96, 0x8d, + 0xfc, 0x3c, 0x85, 0x5a, 0xac, 0x66, 0xc4, 0xbd, 0x37, 0x25, 0xf5, 0xf9, + 0xb1, 0x05, 0x1c, 0x94, 0xfc, 0xce, 0xba, 0x7e, 0x25, 0x9b, 0x28, 0xc7, + 0x44, 0x8c, 0xb2, 0xa9, 0x94, 0x76, 0xc2, 0x61, 0x5b, 0xc6, 0xc2, 0x05, + 0x53, 0x0c, 0x58, 0xd9, 0x36, 0x12, 0x36, 0x56, 0x5d, 0x47, 0x31, 0xb3, + 0xa0, 0x5a, 0x4d, 0x2e, 0x0d, 0xc5, 0x49, 0xc3, 0x34, 0x43, 0x68, 0x37, + 0x0e, 0xac, 0xf5, 0x51, 0xad, 0x78, 0xb9, 0x4a, 0x31, 0x81, 0x29, 0xe7, + 0x22, 0xb9, 0x70, 0x5b, 0x4a, 0x9d, 0x50, 0x71, 0x3c, 0x2e, 0x82, 0x25, + 0x9d, 0x90, 0xa5, 0x43, 0x3d, 0x64, 0x2c, 0x37, 0x6f, 0x54, 0x4b, 0x58, + 0x44, 0x8a, 0x78, 0xcb, 0xe9, 0xed, 0x65, 0xad, 0x51, 0x49, 0xf1, 0xa9, + 0x23, 0x4d, 0xac, 0xd1, 0x0d, 0xf0, 0xaf, 0xc5, 0x3c, 0xdc, 0xf4, 0x0e, + 0xf0, 0x59, 0xdb, 0xd2, 0x08, 0x02, 0x3f, 0xa8, 0xba, 0xe8, 0x87, 0xd5, + 0xf5, 0x57, 0x64, 0x61, 0x89, 0x55, 0x63, 0xbd, 0xdf, 0x0d, 0x2d, 0x16, + 0x2f, 0x13, 0x06, 0x3a, 0x45, 0x58, 0x74, 0xec, 0x5b, 0x80, 0x19, 0x24, + 0x3a, 0xc4, 0x1e, 0x84, 0x09, 0xba, 0x71, 0xc4, 0x65, 0x1a, 0x1e, 0xe0, + 0x7a, 0x6e, 0xbe, 0x9d, 0xe5, 0x1f, 0xc8, 0xec, 0xaa, 0x90, 0x1b, 0xe1, + 0x79, 0xeb, 0x45, 0xc1, 0x75, 0x11, 0x9a, 0xdb, 0xf7, 0x46, 0x19, 0x1c, + 0x58, 0x7d, 0x39, 0x7e, 0xc9, 0x83, 0xff, 0x59, 0x1b, 0xd3, 0xdb, 0x3e, + 0x7e, 0xd6, 0x1f, 0x15, 0x53, 0xb2, 0xa1, 0xc7, 0xad, 0x4c, 0x29, 0xff, + 0x57, 0xd9, 0x62, 0xef, 0x2b, 0xa9, 0x75, 0xc8, 0xfb, 0x3e, 0xcf, 0x61, + 0xdf, 0x42, 0x10, 0xf3, 0xc9, 0x59, 0xd8, 0x25, 0xf1, 0x44, 0x57, 0x5a, + 0xc3, 0x2f, 0xc0, 0x47, 0xca, 0x65, 0xa9, 0x20, 0x7a, 0x49, 0xcc, 0x19, + 0x63, 0xc9, 0x83, 0x70, 0xee, 0xd0, 0xa1, 0xc7, 0x8a, 0xca, 0xf0, 0xaa, + 0xc8, 0x87, 0x19, 0x8a, 0x40, 0x6d, 0xd5, 0x49, 0xa8, 0x6c, 0x8e, 0x55, + 0x0a, 0xb7, 0x02, 0x2e, 0xfe, 0x51, 0x15, 0xb3, 0xb9, 0xda, 0x20, 0xbf, + 0x29, 0x27, 0xe4, 0xd8, 0x57, 0x34, 0x5a, 0x32, 0xb4, 0x51, 0xdb, 0xec, + 0x38, 0xd7, 0xc8, 0x8e, 0x07, 0x8d, 0xca, 0x39, 0x56, 0xea, 0x46, 0x58, + 0x26, 0xbe, 0xf2, 0xfb, 0xdf, 0x23, 0x33, 0x78, 0xd0, 0x88, 0x24, 0x91, + 0x02, 0xc1, 0x49, 0xe7, 0xe0, 0x6f, 0xe4, 0x2e, 0xfa, 0xa5, 0xf7, 0x37, + 0xf8, 0xfb, 0x97, 0x4e, 0x30, 0x72, 0x4b, 0xf9, 0x22, 0x43, 0x6d, 0x78, + 0x20, 0xcb, 0xda, 0xa5, 0x53, 0x02, 0xca, 0xa2, 0x0f, 0x42, 0xb9, 0x38, + 0x3a, 0x63, 0x22, 0x46, 0x80, 0x0e, 0x0e, 0x86, 0x84, 0x89, 0xe1, 0x69, + 0x65, 0x61, 0x38, 0x45, 0xb7, 0xf9, 0x03, 0xc2, 0x5d, 0x94, 0x8d, 0x4d, + 0xfd, 0xf3, 0xdd, 0x10, 0x37, 0x73, 0x23, 0x7a, 0x67, 0x0a, 0x92, 0xe5, + 0x25, 0xda, 0x8d, 0x19, 0xa9, 0x1a, 0xe3, 0xaf, 0x51, 0x40, 0x61, 0x99, + 0x95, 0x3f, 0x63, 0x2c, 0x1d, 0xf4, 0xc4, 0xdd, 0xc0, 0x70, 0x38, 0x2e, + 0x87, 0x1d, 0x11, 0x59, 0x00, 0x39, 0xc9, 0x67, 0x43, 0x42, 0x1e, 0x52, + 0x89, 0xae, 0xcc, 0xab, 0xf7, 0x38, 0x29, 0x49, 0x97, 0x91, 0x28, 0x31, + 0xc2, 0x2c, 0x29, 0xc8, 0xf0, 0x7e, 0xcb, 0x60, 0x72, 0x59, 0x40, 0xa4, + 0x58, 0x92, 0x5c, 0x0c, 0x8f, 0x77, 0xa5, 0xe0, 0xe2, 0xf2, 0x9c, 0x3e, + 0x49, 0x72, 0x39, 0x4b, 0x7a, 0xcc, 0x9c, 0x57, 0x61, 0x47, 0x9d, 0xf1, + 0xe9, 0xbe, 0xe7, 0x19, 0x0f, 0x7c, 0xbd, 0xf4, 0x68, 0xab, 0xd6, 0x4b, + 0xd7, 0x82, 0x40, 0x46, 0xc6, 0x45, 0x81, 0x9c, 0xdc, 0x51, 0x66, 0x51, + 0xad, 0x2e, 0x0e, 0x9a, 0x4a, 0x93, 0x33, 0x90, 0xa6, 0x1d, 0xf9, 0x4a, + 0x6c, 0x1d, 0xde, 0x88, 0x09, 0x23, 0x82, 0xe0, 0xf5, 0x89, 0x12, 0x27, + 0xa2, 0x42, 0x53, 0x82, 0x9f, 0x95, 0xe9, 0xb1, 0x1a, 0x56, 0x78, 0xfe, + 0xf1, 0xae, 0x1f, 0x95, 0xd0, 0x13, 0x86, 0x3d, 0x0a, 0x1c, 0x92, 0x9a, + 0x4c, 0x28, 0xc7, 0xd1, 0x20, 0x02, 0xad, 0x2f, 0xcb, 0x66, 0x08, 0x42, + 0xf2, 0x84, 0xdd, 0x86, 0x15, 0xd7, 0xbf, 0x46, 0x0a, 0xa1, 0x5f, 0x16, + 0x73, 0x4d, 0xf1, 0xb9, 0x99, 0xa1, 0x19, 0x58, 0x4c, 0x95, 0x3c, 0x4a, + 0xba, 0x39, 0x96, 0x4b, 0x9a, 0xe8, 0xa4, 0x5b, 0x33, 0x1a, 0x42, 0x00, + 0x78, 0x33, 0x93, 0xd1, 0x1c, 0xae, 0xad, 0xb7, 0x34, 0xb4, 0xb7, 0xc6, + 0x2d, 0x8d, 0xbd, 0xae, 0x73, 0x4b, 0x07, 0xb1, 0x26, 0x54, 0x94, 0x49, + 0xc3, 0x85, 0x4d, 0x1f, 0x20, 0x66, 0x30, 0x7d, 0xda, 0xd3, 0x30, 0x7d, + 0x29, 0xb3, 0x24, 0x28, 0x5a, 0x0a, 0x7b, 0xc1, 0x28, 0x9d, 0x8e, 0x8d, + 0x3a, 0x8b, 0x90, 0x01, 0x63, 0x6b, 0x4e, 0xbe, 0x81, 0xff, 0x72, 0x56, + 0x28, 0x99, 0x0e, 0xd0, 0xda, 0x5e, 0xe9, 0x9a, 0xda, 0x1e, 0xb9, 0xec, + 0x7f, 0xe5, 0xb7, 0x95, 0x2b, 0xde, 0x1e, 0xdf, 0xf9, 0xc8, 0x88, 0x4f, + 0x94, 0xfd, 0x49, 0xf6, 0x1f, 0x19, 0x4d, 0x02, 0xab, 0xf7, 0x97, 0x17, + 0xa3, 0xf3, 0x32, 0x9b, 0xb7, 0x33, 0x56, 0x99, 0xf8, 0xab, 0x7c, 0xde, + 0xb5, 0xde, 0x9e, 0x06, 0xa2, 0xb0, 0xe2, 0x03, 0xcb, 0x77, 0x54, 0x30, + 0x25, 0xc6, 0x93, 0x26, 0x2c, 0xa5, 0x96, 0x57, 0xe3, 0x7a, 0x4a, 0xf9, + 0x58, 0xca, 0xc4, 0x71, 0x45, 0xb1, 0x92, 0xe5, 0x46, 0x03, 0x20, 0x0d, + 0xa1, 0xc4, 0x41, 0x66, 0xec, 0x2f, 0x9b, 0x53, 0xfc, 0x76, 0xad, 0x2c, + 0xf4, 0xf5, 0xd1, 0xf9, 0x63, 0x8d, 0x86, 0xef, 0x27, 0xc1, 0x68, 0x18, + 0x6b, 0x93, 0xe2, 0x12, 0xed, 0x55, 0x93, 0xde, 0x70, 0x38, 0x6c, 0xaa, + 0x2b, 0x47, 0x47, 0x47, 0xc9, 0xe6, 0x11, 0x95, 0xcb, 0x3c, 0x12, 0x3a, + 0x39, 0xba, 0xc2, 0xe0, 0xc4, 0x09, 0xb0, 0x95, 0xab, 0x05, 0x10, 0x08, + 0x9e, 0x53, 0xda, 0xc3, 0xf3, 0xf3, 0x97, 0xdb, 0x94, 0xda, 0x32, 0x49, + 0x6f, 0x15, 0xd7, 0x48, 0x4c, 0xdb, 0x0d, 0x9b, 0x6c, 0x5f, 0xa2, 0x87, + 0x88, 0x2c, 0x6b, 0x75, 0x53, 0xf1, 0x15, 0x6b, 0x37, 0x3e, 0x45, 0x17, + 0x42, 0x3f, 0x56, 0x12, 0x76, 0xba, 0x98, 0xb9, 0x84, 0x67, 0x54, 0x68, + 0x66, 0x99, 0x42, 0xe4, 0x89, 0xd8, 0x29, 0x89, 0x5c, 0xaf, 0x0f, 0x2f, + 0x30, 0xe3, 0xa5, 0xb6, 0xfc, 0x47, 0x32, 0xbe, 0x84, 0xd8, 0x0d, 0x57, + 0x72, 0x30, 0x0d, 0x32, 0x45, 0xe6, 0x24, 0x60, 0x56, 0xce, 0x18, 0xdf, + 0x86, 0x04, 0xc7, 0xd6, 0x6c, 0xaa, 0xb0, 0x6c, 0x2b, 0x72, 0x07, 0x57, + 0xaa, 0x05, 0xbc, 0xed, 0x51, 0x35, 0x39, 0xdd, 0x7b, 0x6e, 0x70, 0x8d, + 0x6d, 0x97, 0x9e, 0xc7, 0x2b, 0x63, 0x53, 0xdd, 0x96, 0xc3, 0xc3, 0x8e, + 0xf1, 0xc8, 0xab, 0x3d, 0xe6, 0xa6, 0xcb, 0x44, 0x40, 0x5f, 0x80, 0x5c, + 0x4b, 0xd2, 0xfa, 0xb6, 0xac, 0xc0, 0x77, 0xf1, 0x8d, 0x52, 0x0b, 0xdf, + 0x41, 0x02, 0x61, 0x79, 0x9e, 0x0b, 0x87, 0x47, 0xda, 0x6d, 0xc8, 0x55, + 0x65, 0x85, 0xc2, 0x07, 0x72, 0x57, 0x40, 0x3d, 0x48, 0x3b, 0x2c, 0x16, + 0xe8, 0x91, 0x63, 0x90, 0x10, 0xd3, 0x8a, 0x5d, 0x2d, 0xdc, 0x02, 0xd6, + 0xad, 0xb5, 0xd6, 0x62, 0x99, 0x61, 0x1e, 0xac, 0xc6, 0x09, 0x4b, 0xab, + 0x0e, 0x7e, 0xc9, 0xe0, 0x8e, 0x71, 0x80, 0x4e, 0x03, 0x31, 0x35, 0x47, + 0x8d, 0x9f, 0xf1, 0xfb, 0x04, 0x37, 0x41, 0xa3, 0x11, 0xe4, 0x14, 0xe9, + 0x28, 0x34, 0x1c, 0x5a, 0xbe, 0x8b, 0x34, 0x78, 0x31, 0xd7, 0xca, 0xb0, + 0xbf, 0x3f, 0xd1, 0x6e, 0x79, 0xf3, 0xd6, 0xa3, 0x12, 0x1e, 0x84, 0x4c, + 0xfe, 0x13, 0xe8, 0x27, 0xa6, 0xcc, 0xc6, 0x1c, 0xf9, 0xc4, 0x7a, 0xf2, + 0x78, 0xa3, 0x32, 0x81, 0xf1, 0x04, 0x73, 0x8a, 0xd2, 0xd1, 0x9b, 0x14, + 0x97, 0x39, 0x99, 0xb7, 0xb9, 0x0e, 0x6f, 0x14, 0xf0, 0x22, 0xd7, 0xfb, + 0x21, 0x1f, 0x65, 0xc5, 0xc8, 0x8e, 0x00, 0x0f, 0x98, 0x64, 0x50, 0xd2, + 0x30, 0x06, 0xc0, 0xf6, 0x13, 0x07, 0xf5, 0x61, 0x02, 0x07, 0x2c, 0x6e, + 0x3e, 0x04, 0x75, 0x71, 0x78, 0xdb, 0xa7, 0xe4, 0x7e, 0xbd, 0xd2, 0x2c, + 0x00, 0x25, 0x1f, 0xc7, 0x4e, 0x15, 0x57, 0x92, 0x4b, 0x22, 0xd1, 0x64, + 0x39, 0x78, 0x2e, 0xcb, 0xd6, 0x01, 0xb7, 0x08, 0x9f, 0xab, 0x86, 0x5a, + 0xa3, 0xd9, 0x35, 0xf7, 0x59, 0xc6, 0xb0, 0x86, 0xff, 0xc4, 0x15, 0x66, + 0xfe, 0x11, 0x4d, 0x05, 0x96, 0xed, 0x23, 0xc9, 0xc1, 0xec, 0xed, 0xb2, + 0xc4, 0x96, 0x96, 0x82, 0x03, 0x54, 0xd9, 0x94, 0x23, 0x70, 0x42, 0xde, + 0x75, 0x04, 0x08, 0xa1, 0xa1, 0x12, 0x54, 0x3f, 0x5c, 0x82, 0x92, 0x08, + 0x15, 0xa7, 0x59, 0x9a, 0xbc, 0x2e, 0x9c, 0x7d, 0x8a, 0xe3, 0xc7, 0x28, + 0xe1, 0x42, 0x4a, 0x63, 0x80, 0xcc, 0xaa, 0x98, 0x6b, 0xa6, 0x6f, 0xa9, + 0x59, 0x9d, 0x92, 0xd0, 0xf4, 0x5b, 0x09, 0x42, 0x42, 0xc7, 0xf5, 0x4d, + 0x8e, 0x70, 0x3f, 0x6c, 0xd5, 0x0f, 0xb8, 0x3a, 0x78, 0x4f, 0xd0, 0x9a, + 0x39, 0xe4, 0xda, 0xa0, 0x22, 0x30, 0x05, 0x15, 0x56, 0x63, 0x8f, 0xd2, + 0x62, 0xa0, 0xe5, 0x52, 0x51, 0xca, 0x9d, 0x9a, 0x61, 0x63, 0x6d, 0x29, + 0x15, 0xcd, 0xe1, 0x24, 0xa2, 0x62, 0x70, 0x96, 0x9c, 0xc4, 0x29, 0x87, + 0xf4, 0x18, 0x39, 0xde, 0xae, 0x72, 0x8f, 0xf6, 0xaa, 0xb1, 0xa1, 0x2f, + 0x8e, 0x0f, 0x9f, 0x05, 0x38, 0x25, 0x4f, 0x72, 0x68, 0x6a, 0xfe, 0x2c, + 0xb6, 0xa8, 0xcb, 0x25, 0x01, 0xb7, 0x69, 0x9e, 0xc5, 0xae, 0xee, 0x05, + 0xc9, 0xc5, 0x87, 0x7a, 0xa3, 0xa4, 0x53, 0x17, 0xc5, 0x44, 0x03, 0x78, + 0xe0, 0xcf, 0xf4, 0x32, 0xfb, 0xb6, 0x98, 0x8c, 0x3a, 0x6b, 0x36, 0x70, + 0xd2, 0x6c, 0xe3, 0x63, 0xcb, 0xd4, 0xeb, 0x5a, 0x09, 0x59, 0x5f, 0x12, + 0x59, 0x4f, 0x8a, 0x41, 0x31, 0x16, 0x29, 0xee, 0x9c, 0x8b, 0x5a, 0xa2, + 0x8f, 0x5c, 0xf1, 0x8d, 0x09, 0x53, 0x60, 0x40, 0x22, 0x9d, 0xe6, 0xb8, + 0x4a, 0xe0, 0x31, 0xd9, 0x2d, 0x2b, 0xca, 0x21, 0x71, 0xc0, 0x13, 0xdc, + 0xd0, 0x6d, 0x03, 0x36, 0xdf, 0x61, 0x44, 0x58, 0x10, 0x2d, 0x6a, 0x97, + 0x54, 0xc6, 0xb7, 0x4a, 0xfe, 0xf9, 0xaf, 0xbf, 0xfd, 0x12, 0xac, 0xf0, + 0x57, 0x94, 0x92, 0xeb, 0x12, 0x29, 0xe1, 0x86, 0xc9, 0x26, 0x63, 0x36, + 0xfa, 0x90, 0x36, 0x81, 0x70, 0xca, 0x7d, 0x17, 0xaa, 0xcf, 0xbe, 0x0b, + 0x6d, 0x0d, 0x23, 0xfc, 0x88, 0x37, 0xb1, 0x07, 0x41, 0x02, 0x9f, 0xb3, + 0x4b, 0x50, 0x6d, 0xb5, 0xb0, 0x24, 0x85, 0x36, 0x23, 0x87, 0x84, 0x37, + 0x6f, 0x9d, 0x51, 0x4a, 0x03, 0x0c, 0xa3, 0xb4, 0x4b, 0x21, 0xbc, 0x13, + 0xb9, 0x94, 0x45, 0x73, 0x6b, 0x50, 0x1c, 0x2f, 0xe3, 0x2a, 0xed, 0x2a, + 0x4e, 0x17, 0xbf, 0x37, 0xb9, 0x56, 0x5a, 0xbb, 0x93, 0xa7, 0x21, 0xcc, + 0x75, 0x4b, 0xd2, 0xcd, 0x3f, 0xff, 0xf6, 0xcb, 0xbf, 0xe0, 0x3f, 0x9d, + 0x55, 0x55, 0xab, 0x63, 0xc5, 0xd8, 0x6e, 0xaa, 0x2b, 0x38, 0x68, 0xb7, + 0xbd, 0xec, 0x36, 0x1b, 0x00, 0xd7, 0xaa, 0x14, 0x85, 0xaa, 0x37, 0xad, + 0x92, 0xa7, 0x53, 0x35, 0x8a, 0xbe, 0xc0, 0x67, 0x92, 0x63, 0x79, 0x46, + 0xcb, 0xb3, 0xa6, 0x93, 0xcb, 0xa2, 0x84, 0x91, 0x4f, 0xc5, 0x09, 0x1c, + 0x7b, 0x60, 0xcd, 0x08, 0x98, 0x50, 0xce, 0xa0, 0x5a, 0xe0, 0xae, 0x1f, + 0x4a, 0xca, 0xaa, 0xaf, 0xd3, 0x96, 0xa9, 0x1c, 0x31, 0x5a, 0xa4, 0x13, + 0xd4, 0x90, 0xd1, 0x2a, 0x86, 0x36, 0x35, 0x34, 0x46, 0x5c, 0xe6, 0x9c, + 0xbe, 0x2f, 0x6f, 0x84, 0x20, 0x74, 0x49, 0x2d, 0x56, 0x76, 0x17, 0x38, + 0xad, 0x18, 0x58, 0x28, 0x60, 0x2c, 0x9f, 0x80, 0x2a, 0xcd, 0x08, 0x70, + 0x7d, 0x2b, 0x33, 0x4b, 0x6d, 0xc5, 0x46, 0x51, 0xa0, 0x59, 0xb1, 0x9c, + 0xc8, 0xc8, 0x99, 0xf3, 0x58, 0xc2, 0x06, 0xd2, 0x1a, 0x2c, 0x4d, 0x97, + 0xcd, 0xb1, 0xa9, 0xd7, 0xf5, 0x22, 0x60, 0x1a, 0xe2, 0x64, 0xd3, 0x74, + 0x94, 0x25, 0xbe, 0xe4, 0x98, 0xab, 0x40, 0x28, 0xc1, 0x45, 0x29, 0x06, + 0x38, 0x65, 0x13, 0x15, 0xae, 0x1d, 0x14, 0x8b, 0x03, 0x79, 0xe6, 0xa4, + 0x59, 0x38, 0xb8, 0x58, 0xb9, 0x96, 0x72, 0xd8, 0x73, 0x81, 0x53, 0x9f, + 0x65, 0x11, 0xd2, 0xb1, 0x07, 0x6c, 0x63, 0x1b, 0x16, 0x6a, 0x0d, 0xa2, + 0xee, 0x52, 0xcd, 0x69, 0x2a, 0x93, 0xaa, 0x98, 0xd8, 0xb8, 0x81, 0x14, + 0xea, 0x49, 0xf1, 0xf1, 0xb4, 0xb9, 0xb6, 0xbb, 0xe2, 0xd4, 0x78, 0x7e, + 0x94, 0x3c, 0x7e, 0xf4, 0xe8, 0x11, 0xfb, 0x38, 0x3b, 0x27, 0xd4, 0xd3, + 0x9b, 0xe3, 0xa3, 0xd3, 0x57, 0xaf, 0x8e, 0x5f, 0x3f, 0x3b, 0x7e, 0x66, + 0x88, 0x0f, 0x3a, 0x54, 0xdb, 0x7c, 0x42, 0x85, 0x4b, 0x87, 0x6a, 0x74, + 0xde, 0x7d, 0xb4, 0xd3, 0xdb, 0x7b, 0xb4, 0x93, 0x00, 0x3d, 0xa5, 0x9c, + 0x7c, 0x8c, 0x93, 0x4a, 0x27, 0x88, 0xd3, 0x90, 0x5c, 0x2d, 0xa6, 0x29, + 0x41, 0x59, 0xa3, 0xd1, 0xa3, 0x32, 0x6c, 0xca, 0x59, 0x56, 0x53, 0x8d, + 0xf0, 0x84, 0xf2, 0xf4, 0x3a, 0x9a, 0xbf, 0xc0, 0xa5, 0xc8, 0x42, 0x70, + 0x81, 0x28, 0x24, 0x44, 0x6f, 0x7b, 0x3b, 0xd8, 0x05, 0x08, 0x31, 0x39, + 0xe2, 0xa7, 0x7c, 0x48, 0x58, 0x17, 0x2b, 0xb1, 0x82, 0x4a, 0x78, 0x23, + 0x2a, 0x45, 0x47, 0xdb, 0xb3, 0x8f, 0x80, 0x66, 0xd3, 0xca, 0x02, 0x3e, + 0x56, 0x1f, 0x86, 0x2f, 0x07, 0xde, 0xba, 0xba, 0xcf, 0x47, 0x3b, 0x3b, + 0xeb, 0x71, 0xfa, 0x69, 0xfa, 0x81, 0xde, 0x53, 0x34, 0xd7, 0x76, 0x44, + 0x39, 0xec, 0x89, 0x8b, 0x21, 0x90, 0x87, 0x00, 0x14, 0xe2, 0xa7, 0xf9, + 0xbc, 0x01, 0x77, 0x89, 0xaa, 0x8b, 0x85, 0xde, 0x9c, 0x9c, 0x21, 0xad, + 0xbe, 0x38, 0x3c, 0xc3, 0xb7, 0x92, 0xb3, 0x37, 0xa7, 0x7f, 0xf9, 0x6b, + 0xc8, 0xa9, 0xbf, 0xde, 0xb5, 0x04, 0x0a, 0xe6, 0xc3, 0x8a, 0xc3, 0x0f, + 0xd2, 0xeb, 0x4c, 0x12, 0xc5, 0xc5, 0x7a, 0xd1, 0xb0, 0x5a, 0xa0, 0xf7, + 0x9d, 0xea, 0x9a, 0x85, 0xc2, 0x90, 0xf1, 0x11, 0x41, 0x64, 0x5d, 0xc9, + 0x89, 0x32, 0x80, 0xb3, 0x91, 0x64, 0xe2, 0x82, 0x1c, 0x9a, 0x67, 0xa1, + 0x6c, 0x0b, 0xd9, 0xe8, 0x81, 0x16, 0x1e, 0xd2, 0x1d, 0x71, 0xc9, 0x25, + 0xfa, 0x66, 0x0a, 0xb6, 0x8c, 0xf9, 0x77, 0x7f, 0xdb, 0xe9, 0xf7, 0xf7, + 0x1e, 0x3d, 0xfa, 0x05, 0x6d, 0xa9, 0x0a, 0x93, 0x25, 0x25, 0x10, 0x12, + 0xd5, 0x32, 0x15, 0x9e, 0xb0, 0x44, 0x30, 0x6a, 0x0c, 0x16, 0x63, 0x91, + 0xc5, 0x95, 0x06, 0x1c, 0xdc, 0x5a, 0x57, 0x04, 0xd2, 0x38, 0x22, 0x5e, + 0x21, 0x59, 0x2e, 0x21, 0x37, 0x86, 0xe4, 0x2b, 0x4c, 0x39, 0x91, 0xa0, + 0xc5, 0x7f, 0x64, 0x65, 0xa1, 0x15, 0x0b, 0x08, 0x53, 0x1d, 0x13, 0x0e, + 0x6a, 0xad, 0x77, 0x06, 0xca, 0xd2, 0x8c, 0x8d, 0xd4, 0x56, 0xd0, 0x50, + 0x47, 0x04, 0x77, 0x90, 0x54, 0x20, 0xe2, 0xca, 0x31, 0x18, 0x90, 0x10, + 0x52, 0x9c, 0x91, 0xa1, 0x2f, 0x28, 0x5b, 0x98, 0xaf, 0x8e, 0x62, 0x58, + 0x63, 0xe8, 0x9f, 0xb4, 0xd2, 0x6f, 0xe1, 0x6f, 0xba, 0xa4, 0xcb, 0x6b, + 0x2a, 0x2b, 0x4a, 0xc3, 0x78, 0x88, 0x8c, 0xf5, 0x43, 0x6a, 0x90, 0x8f, + 0xa3, 0xfc, 0xd2, 0x8c, 0x64, 0x9b, 0x20, 0xee, 0x63, 0x9c, 0x56, 0x29, + 0x66, 0x6e, 0x72, 0xc0, 0x13, 0x34, 0x0d, 0xf1, 0x11, 0x5c, 0x21, 0xce, + 0x28, 0xb3, 0x75, 0xe1, 0x00, 0x03, 0x5c, 0x91, 0xae, 0x17, 0x7e, 0x29, + 0x41, 0x84, 0x80, 0x2c, 0x89, 0x07, 0x60, 0x89, 0x05, 0x58, 0x51, 0x49, + 0x31, 0xa3, 0x26, 0x12, 0x86, 0xbe, 0x1a, 0x4a, 0xc0, 0x09, 0x97, 0x26, + 0x12, 0x6f, 0x7a, 0x89, 0x1c, 0xcd, 0x10, 0x12, 0xb0, 0x11, 0x52, 0x0a, + 0x65, 0xb3, 0x29, 0x84, 0xa8, 0xa0, 0xd2, 0x2e, 0x5c, 0x99, 0x9b, 0x37, + 0x40, 0xb9, 0x6c, 0x5d, 0xb8, 0x75, 0x0a, 0x29, 0x2b, 0x30, 0x5f, 0xba, + 0xfb, 0x07, 0xa8, 0xd0, 0xd2, 0x32, 0xe9, 0x5e, 0xc3, 0x6a, 0xed, 0xee, + 0x19, 0xea, 0xc2, 0xa9, 0x4a, 0xcf, 0x5d, 0xda, 0x0f, 0x2d, 0xcf, 0x23, + 0xc9, 0x24, 0x3c, 0x1c, 0xcd, 0x51, 0x60, 0x0f, 0x8d, 0x9d, 0x23, 0x8e, + 0xcd, 0xc8, 0x2c, 0x5a, 0x30, 0x24, 0x97, 0x9c, 0xd4, 0x3a, 0xc5, 0xca, + 0x9f, 0x51, 0x3b, 0x67, 0xf9, 0x58, 0x75, 0x8d, 0xbc, 0x36, 0x2f, 0xb2, + 0xab, 0x71, 0x1e, 0xea, 0x92, 0x8b, 0xc4, 0xc5, 0x19, 0xfa, 0xe3, 0x49, + 0x7a, 0x19, 0xf1, 0xb5, 0xf8, 0xe4, 0x37, 0x22, 0xd8, 0x3e, 0x67, 0x00, + 0xdb, 0x52, 0x5f, 0xff, 0xc7, 0xc9, 0xd9, 0x32, 0x64, 0xfc, 0xde, 0x72, + 0x4d, 0xea, 0x0f, 0xb7, 0x4b, 0x9c, 0x4a, 0x57, 0xa1, 0xc1, 0xa4, 0x28, + 0x5d, 0xe0, 0x5e, 0xbe, 0xa4, 0x21, 0xb8, 0x9e, 0x25, 0x45, 0x99, 0x67, + 0x66, 0xab, 0x35, 0x9f, 0x19, 0xab, 0x2e, 0x98, 0xcb, 0x56, 0x50, 0x89, + 0xac, 0x94, 0x12, 0x2c, 0xe8, 0xb2, 0x12, 0xac, 0x6c, 0x2c, 0x94, 0x88, + 0x9e, 0x61, 0x89, 0xf9, 0x85, 0x11, 0xe4, 0x0d, 0x24, 0xc6, 0xc8, 0x07, + 0x4b, 0x18, 0xfa, 0x2d, 0xfe, 0xd2, 0x55, 0x55, 0xa0, 0xe6, 0x25, 0x9c, + 0xbc, 0x32, 0x9f, 0xdc, 0xda, 0x95, 0x4d, 0x86, 0x67, 0xcd, 0xf6, 0xa2, + 0x40, 0x1c, 0x57, 0x7a, 0xbb, 0x08, 0xa0, 0xcd, 0xa0, 0x9f, 0xe7, 0x43, + 0x4d, 0x60, 0x65, 0x58, 0xd2, 0x4a, 0xd5, 0x53, 0x5e, 0x90, 0x66, 0xd4, + 0x5b, 0xfb, 0x22, 0x7f, 0xde, 0xe2, 0x72, 0xcd, 0x3e, 0xd6, 0x23, 0x9d, + 0x50, 0x5e, 0x67, 0x2d, 0xfc, 0xe0, 0x9d, 0xbb, 0x68, 0xe9, 0xa4, 0x2b, + 0x4a, 0x67, 0xa3, 0xb2, 0x4f, 0xf2, 0xfc, 0xe4, 0xe5, 0xf1, 0x16, 0xdc, + 0x46, 0x19, 0x2a, 0x3e, 0x75, 0xc8, 0xd7, 0xe4, 0x54, 0x9d, 0xff, 0x41, + 0x5a, 0xb6, 0xd5, 0x45, 0x95, 0x70, 0x6c, 0x1f, 0x2f, 0x2a, 0x16, 0x5f, + 0xd2, 0x45, 0x0d, 0xba, 0x80, 0x69, 0x88, 0x77, 0x06, 0x55, 0x37, 0xcd, + 0x2b, 0xd2, 0xc0, 0x2f, 0xa5, 0x4d, 0xca, 0x02, 0xd7, 0x74, 0x61, 0x86, + 0xec, 0xea, 0xbb, 0x62, 0x38, 0x85, 0x8f, 0xc0, 0xc4, 0x81, 0x4a, 0x42, + 0x27, 0x47, 0x80, 0xe5, 0x15, 0xf0, 0x8b, 0xdb, 0x2a, 0x40, 0x25, 0x68, + 0x40, 0x96, 0x60, 0x62, 0xf0, 0xb1, 0x9d, 0x16, 0x23, 0x57, 0x9f, 0x8d, + 0xc4, 0x83, 0xa5, 0xfa, 0x82, 0x9a, 0xdd, 0xf1, 0x39, 0x34, 0xe6, 0x2b, + 0x87, 0x0a, 0xda, 0xba, 0xbd, 0x27, 0xeb, 0x09, 0x33, 0xb0, 0x6c, 0xb8, + 0x65, 0xb0, 0xec, 0x83, 0xa2, 0x32, 0xd8, 0xee, 0x12, 0x18, 0x64, 0x2f, + 0xad, 0x86, 0x79, 0xae, 0x1b, 0xfb, 0x42, 0x37, 0x16, 0xe3, 0x9d, 0xf9, + 0xdf, 0xed, 0xef, 0x9b, 0x08, 0xde, 0x0c, 0x8d, 0x83, 0x89, 0x0b, 0x5b, + 0x30, 0x28, 0x9c, 0x89, 0xbc, 0x41, 0x27, 0x16, 0x04, 0x82, 0x11, 0xc1, + 0x3a, 0xe4, 0x33, 0xce, 0xba, 0xe3, 0x5b, 0x9f, 0xf0, 0xc1, 0x7e, 0xb2, + 0x48, 0x0e, 0xda, 0x11, 0x51, 0x04, 0xd4, 0xfc, 0xa2, 0x67, 0xd0, 0xb8, + 0xb2, 0x14, 0xad, 0x10, 0x63, 0x85, 0x42, 0x89, 0xe8, 0x63, 0x3e, 0x73, + 0xb6, 0xf2, 0x72, 0x10, 0xb4, 0x47, 0x23, 0x34, 0x3c, 0x9f, 0x57, 0x27, + 0xaf, 0x8e, 0x05, 0x17, 0x00, 0x21, 0xab, 0x30, 0x93, 0x8a, 0xcb, 0x58, + 0x28, 0x9c, 0x17, 0xe5, 0x20, 0x28, 0xc2, 0xa0, 0x39, 0xe9, 0x84, 0x79, + 0x64, 0x62, 0x33, 0x71, 0x8e, 0x70, 0x02, 0xbf, 0xa7, 0x13, 0x4f, 0x4d, + 0x7b, 0x04, 0x39, 0xde, 0x54, 0xb8, 0x27, 0x55, 0x34, 0xe6, 0x15, 0xa1, + 0xcc, 0x89, 0x3a, 0x31, 0xfe, 0x49, 0x83, 0x50, 0x80, 0xc1, 0x09, 0xb0, + 0x3f, 0xd0, 0x5a, 0x4e, 0xea, 0xc4, 0xd9, 0x02, 0x53, 0xf6, 0x1c, 0xc1, + 0x2d, 0x2c, 0x8e, 0x84, 0x68, 0x02, 0x36, 0x61, 0xf4, 0xe2, 0x53, 0x0a, + 0x84, 0xb9, 0xd1, 0x51, 0xaa, 0x91, 0xdb, 0x18, 0x4f, 0x44, 0xe6, 0x76, + 0x08, 0x2f, 0x2f, 0x57, 0x9d, 0x01, 0xaf, 0xc1, 0xdb, 0x62, 0x11, 0x15, + 0xfe, 0xc6, 0x2c, 0x71, 0xd4, 0xc4, 0x7c, 0xa2, 0x38, 0x3f, 0x4d, 0x3c, + 0xcb, 0x7c, 0x6d, 0x1c, 0xf0, 0x9d, 0x56, 0x1a, 0x74, 0xda, 0x12, 0x31, + 0x56, 0xcc, 0x34, 0x14, 0xe7, 0xc6, 0xc2, 0x5d, 0xbb, 0x02, 0xbd, 0xf1, + 0x81, 0x9f, 0x41, 0xf3, 0x36, 0x5e, 0x85, 0x21, 0x89, 0xd7, 0xa5, 0x78, + 0x39, 0x80, 0x1d, 0xec, 0xd6, 0xb7, 0x1b, 0xbb, 0x5f, 0xd0, 0x3e, 0x02, + 0x9b, 0x43, 0x21, 0x20, 0x8c, 0x74, 0x0d, 0x52, 0xc4, 0xf0, 0x7d, 0xae, + 0x4e, 0xa1, 0xaa, 0x5e, 0x8c, 0x69, 0x84, 0xa9, 0xb9, 0x1b, 0x65, 0x44, + 0x1a, 0x15, 0x89, 0x0b, 0x2f, 0xf5, 0x09, 0x2d, 0x38, 0x97, 0x64, 0x02, + 0x95, 0x23, 0xe2, 0xa9, 0x4d, 0x6e, 0xdd, 0xa8, 0x2b, 0xb3, 0xb5, 0x20, + 0x84, 0x0c, 0x6e, 0x34, 0xc2, 0x9c, 0x65, 0x24, 0xeb, 0x90, 0x93, 0xf9, + 0x46, 0x41, 0xd2, 0x03, 0xa2, 0xe7, 0xa8, 0x20, 0xaf, 0xd4, 0x9b, 0x6c, + 0x5a, 0x10, 0x8a, 0xbe, 0x5b, 0x35, 0x59, 0x0a, 0x0c, 0xea, 0x10, 0x2d, + 0x3d, 0xd5, 0x41, 0x70, 0xbc, 0x6f, 0x5c, 0xbc, 0x55, 0x92, 0x74, 0x05, + 0xe0, 0x95, 0x43, 0x34, 0x10, 0xe3, 0xd8, 0x10, 0x61, 0x48, 0xfa, 0xeb, + 0x12, 0x36, 0xf9, 0xec, 0x00, 0x4e, 0x78, 0xd2, 0x79, 0x51, 0x54, 0xf5, + 0x41, 0x87, 0xeb, 0x0f, 0x84, 0xed, 0xcf, 0x24, 0xe1, 0x47, 0xb7, 0x5e, + 0x07, 0xc2, 0xf6, 0x41, 0xe0, 0x45, 0x12, 0xb2, 0xc0, 0x11, 0x75, 0xb5, + 0xdd, 0x80, 0x01, 0xcd, 0x42, 0xeb, 0xd2, 0x36, 0xf3, 0x7f, 0x0d, 0x18, + 0x41, 0xb0, 0x73, 0xb0, 0x0a, 0x35, 0x0c, 0xe3, 0x2f, 0xbd, 0x23, 0xea, + 0xa9, 0xf7, 0x82, 0xda, 0xf9, 0x43, 0x47, 0xea, 0xba, 0x68, 0x4e, 0x5c, + 0xf3, 0x81, 0x03, 0x0b, 0x18, 0xa5, 0x2d, 0x64, 0xb3, 0x30, 0x15, 0x9e, + 0x20, 0xf2, 0xe4, 0x18, 0x6a, 0x19, 0x13, 0x41, 0xd2, 0x8f, 0x46, 0xdb, + 0x2a, 0xe8, 0x2a, 0xcc, 0xbf, 0xe5, 0x66, 0x98, 0xa8, 0x81, 0xf2, 0x37, + 0x74, 0xd9, 0x2b, 0xc6, 0x3d, 0xca, 0x20, 0x06, 0x49, 0xe1, 0x3d, 0x0a, + 0xd7, 0x14, 0x99, 0x22, 0x94, 0x40, 0xd0, 0x76, 0x74, 0x26, 0x47, 0x23, + 0x31, 0xcb, 0x54, 0x8a, 0x80, 0x14, 0x15, 0xbb, 0xd4, 0x15, 0x91, 0x5d, + 0x39, 0xb0, 0x72, 0x54, 0xf8, 0xe2, 0x2c, 0xbb, 0xe1, 0x0c, 0x50, 0x64, + 0x4c, 0x9a, 0x79, 0x6f, 0x70, 0x93, 0xa1, 0xbc, 0x83, 0x56, 0x72, 0x9e, + 0xb2, 0xab, 0x9d, 0x23, 0x16, 0x16, 0x73, 0x36, 0xe6, 0xc0, 0xb0, 0xc4, + 0xa4, 0x4c, 0x9e, 0x2f, 0x6a, 0x4d, 0x13, 0xb2, 0x80, 0xb9, 0x03, 0xb7, + 0x9d, 0x2a, 0xcd, 0x93, 0x20, 0x8d, 0xd3, 0xb8, 0xa4, 0xa0, 0xce, 0x40, + 0x39, 0xc4, 0x22, 0x80, 0xa9, 0x73, 0x8a, 0x79, 0xc9, 0xea, 0x44, 0x42, + 0xc0, 0xd2, 0x97, 0x0b, 0x8c, 0xee, 0x25, 0xd1, 0x5e, 0x81, 0x94, 0x84, + 0xa3, 0x53, 0x7d, 0xd7, 0x3a, 0x63, 0x38, 0x00, 0xba, 0x40, 0xcc, 0x85, + 0xbe, 0x94, 0xc3, 0x7a, 0xd1, 0x0c, 0x06, 0xa5, 0x72, 0xa8, 0x14, 0x6a, + 0xa4, 0x51, 0xeb, 0xc0, 0xf6, 0xbf, 0x0f, 0x68, 0x1d, 0x55, 0x7d, 0x8b, + 0x37, 0x71, 0x00, 0x2b, 0x9a, 0x99, 0xa2, 0x15, 0x92, 0xff, 0x43, 0x24, + 0x3a, 0x6d, 0x94, 0x68, 0xa4, 0x04, 0x5a, 0x24, 0xb5, 0x22, 0x38, 0xa3, + 0xe1, 0xfb, 0x9e, 0x0f, 0x03, 0x54, 0x97, 0x5d, 0x3a, 0xf2, 0x3b, 0xc4, + 0x69, 0x00, 0x86, 0xe5, 0x65, 0x41, 0x9f, 0x13, 0x0c, 0x0c, 0x72, 0xf1, + 0x42, 0x70, 0xe1, 0x23, 0xf6, 0x18, 0x88, 0xdc, 0x3d, 0x98, 0xf8, 0x34, + 0x01, 0x0d, 0x68, 0x92, 0xd7, 0xa4, 0xda, 0x51, 0xd9, 0x64, 0x31, 0xe8, + 0xa3, 0x7e, 0x2b, 0x70, 0x13, 0x02, 0x9b, 0x48, 0x67, 0x85, 0xec, 0x45, + 0x9a, 0x43, 0x46, 0x37, 0x05, 0x67, 0xf1, 0x0a, 0xdf, 0x38, 0xd0, 0x30, + 0x71, 0x52, 0x65, 0x3b, 0xcf, 0x61, 0x38, 0x07, 0x1d, 0xb8, 0x42, 0x3a, + 0x17, 0x05, 0xfc, 0x2b, 0x87, 0xe0, 0x19, 0x9c, 0xa4, 0x03, 0x2e, 0xbd, + 0xd7, 0x39, 0x67, 0x28, 0x2c, 0xfc, 0x73, 0x5a, 0xa0, 0xe8, 0x5d, 0x5f, + 0x31, 0x54, 0x05, 0x43, 0x2a, 0x89, 0xd5, 0x95, 0x6f, 0x4d, 0xa5, 0xf4, + 0xb8, 0xdc, 0x81, 0xbf, 0x35, 0x18, 0xc9, 0x56, 0x8b, 0x39, 0x86, 0x2b, + 0x9c, 0x59, 0x41, 0xcc, 0x05, 0x2a, 0xe2, 0x4f, 0xb3, 0x90, 0x2d, 0xae, + 0x61, 0x8b, 0x8a, 0x09, 0xf8, 0xe1, 0x36, 0x0a, 0x9c, 0xc5, 0xc1, 0xe1, + 0x76, 0xc3, 0x5c, 0x9a, 0xa9, 0xdc, 0x07, 0x09, 0x63, 0x65, 0x65, 0xa3, + 0x4e, 0xe0, 0x31, 0xe4, 0xfd, 0x21, 0xa6, 0xd8, 0x68, 0x5a, 0x5d, 0x2d, + 0x9a, 0xc5, 0xad, 0x7f, 0x63, 0x8e, 0x7c, 0x57, 0x5d, 0x43, 0x9c, 0x53, + 0xa1, 0x0c, 0x8c, 0x7d, 0x1f, 0x0e, 0xe9, 0x48, 0xba, 0xb3, 0xac, 0xf5, + 0xa5, 0x42, 0xd7, 0x3a, 0x47, 0xe4, 0xe9, 0x12, 0x69, 0xef, 0xb0, 0x5a, + 0x31, 0x24, 0x2c, 0x23, 0x8a, 0x25, 0x17, 0x94, 0x1f, 0x56, 0xa5, 0x38, + 0x08, 0x52, 0x5f, 0x41, 0xa2, 0x0f, 0xca, 0x8c, 0x83, 0x8e, 0xb4, 0x70, + 0xaf, 0x01, 0x2b, 0x74, 0x13, 0xc6, 0x1d, 0x92, 0x09, 0xd7, 0x58, 0x3f, + 0x2b, 0x16, 0xef, 0x31, 0xad, 0xda, 0xe9, 0x4f, 0x78, 0x7a, 0x26, 0x44, + 0xbb, 0x45, 0x24, 0xea, 0x72, 0x65, 0xc6, 0x4a, 0xea, 0x65, 0x4b, 0xdd, + 0x06, 0x32, 0xee, 0x2a, 0x1b, 0x49, 0xf9, 0x78, 0x14, 0x70, 0x23, 0xe4, + 0x74, 0xad, 0x14, 0x28, 0x58, 0x21, 0xc8, 0x7f, 0x85, 0x95, 0xf5, 0x48, + 0x93, 0x37, 0xe1, 0x3c, 0x10, 0x0f, 0x2b, 0x6b, 0x61, 0x44, 0xc3, 0x94, + 0x0b, 0x78, 0x0b, 0x28, 0xb3, 0x7c, 0xe7, 0x00, 0x1b, 0xc2, 0x64, 0xfb, + 0x41, 0x74, 0x54, 0xf5, 0xfd, 0x53, 0xf3, 0xb5, 0x1b, 0x6e, 0x21, 0xba, + 0x2c, 0x9e, 0xa3, 0x35, 0xb7, 0xf7, 0x1a, 0xf8, 0xc5, 0x41, 0xf2, 0x5f, + 0x45, 0x76, 0xbf, 0x9b, 0x07, 0xde, 0x7a, 0x0b, 0xaa, 0x46, 0xef, 0xf0, + 0x92, 0x58, 0xf1, 0x6d, 0x56, 0xf5, 0xe6, 0x74, 0xbe, 0xb7, 0xf7, 0x76, + 0x76, 0x76, 0xd6, 0x7a, 0x9f, 0x6f, 0xca, 0x35, 0x9e, 0xfc, 0x5e, 0xe5, + 0xab, 0xbb, 0x0b, 0xb4, 0x34, 0x52, 0x0e, 0x7b, 0xe9, 0x65, 0x66, 0xf9, + 0x64, 0x9c, 0x19, 0x6b, 0x29, 0x65, 0x57, 0x2c, 0x89, 0x4f, 0xe6, 0xc9, + 0x53, 0x41, 0xc0, 0xfb, 0x4e, 0xe1, 0xc9, 0xf1, 0xda, 0xc0, 0x6f, 0x4c, + 0xeb, 0xe0, 0x3f, 0x9d, 0xcf, 0xdb, 0x30, 0xf3, 0x04, 0x67, 0x5d, 0xea, + 0xaa, 0x30, 0x45, 0xab, 0x49, 0xa2, 0x89, 0xc8, 0xc1, 0x65, 0x71, 0x5c, + 0x62, 0x91, 0x37, 0x67, 0x28, 0x04, 0x7a, 0xac, 0x27, 0x31, 0x7b, 0x44, + 0x2c, 0x56, 0x50, 0xbf, 0x81, 0x4b, 0xc6, 0x5a, 0x1c, 0xb1, 0x69, 0x6d, + 0xae, 0xf2, 0xe6, 0x74, 0xeb, 0x83, 0x6e, 0x87, 0x2c, 0x27, 0xfa, 0x25, + 0x28, 0xcb, 0x04, 0xd5, 0xfd, 0xcb, 0x42, 0x3c, 0xb7, 0x31, 0x8d, 0x04, + 0x26, 0x16, 0xe0, 0xef, 0xd3, 0xf0, 0x42, 0xcb, 0x70, 0x81, 0xae, 0x6f, + 0xc4, 0x75, 0xdc, 0xd6, 0x50, 0x15, 0xe2, 0x61, 0xe2, 0x94, 0x26, 0x6b, + 0x34, 0x14, 0x85, 0x0d, 0xfd, 0x24, 0x1d, 0x68, 0x8f, 0x85, 0x15, 0x2e, + 0x8b, 0x06, 0x7f, 0xca, 0x8a, 0x5a, 0xc5, 0x32, 0x69, 0xdf, 0x2d, 0x6d, + 0x47, 0xdf, 0xef, 0xf0, 0xc2, 0x9a, 0x67, 0x45, 0x93, 0xee, 0xdc, 0xd2, + 0x12, 0x9f, 0x71, 0xe5, 0xcf, 0x70, 0x77, 0xf5, 0x38, 0x52, 0x23, 0x79, + 0xe6, 0x9b, 0x66, 0x90, 0xcc, 0x60, 0x77, 0xd2, 0xcd, 0x8f, 0xd0, 0x11, + 0x69, 0xa1, 0x3f, 0x70, 0x04, 0x64, 0xb2, 0xba, 0x20, 0x47, 0xd7, 0xb9, + 0x7c, 0x64, 0x5f, 0x72, 0x11, 0xf7, 0x60, 0x31, 0x15, 0x23, 0x40, 0x05, + 0x3b, 0x8e, 0xbd, 0x1d, 0x11, 0x0c, 0x97, 0xdd, 0x7d, 0xa1, 0xb0, 0x17, + 0x79, 0x10, 0x09, 0x68, 0x57, 0x97, 0x77, 0x82, 0xd7, 0x56, 0x68, 0x02, + 0x61, 0x5a, 0xf0, 0x6d, 0xc1, 0x80, 0x48, 0xf9, 0x01, 0x15, 0xdb, 0x51, + 0x36, 0x68, 0xaa, 0xe7, 0x29, 0x93, 0x3a, 0xa3, 0xb3, 0x28, 0x7e, 0xa7, + 0xda, 0x7a, 0xb8, 0x13, 0x11, 0x40, 0x27, 0xfd, 0x08, 0x36, 0x0a, 0x5e, + 0x72, 0x75, 0x9d, 0xb9, 0xbc, 0x28, 0x03, 0xc3, 0xb0, 0x5d, 0x6a, 0x79, + 0xc7, 0x22, 0x5f, 0x7d, 0x44, 0x3e, 0xc1, 0xb6, 0x84, 0xb2, 0x1d, 0x01, + 0x47, 0x2a, 0xc1, 0xe1, 0x18, 0xab, 0xe2, 0x1e, 0x2f, 0x37, 0x8d, 0xc6, + 0xa8, 0x26, 0xfa, 0xb4, 0x67, 0x45, 0xb4, 0xdb, 0xbe, 0x1c, 0x2f, 0xf3, + 0x11, 0x51, 0xe9, 0x83, 0x95, 0x0f, 0x4e, 0xe4, 0x7c, 0x31, 0x98, 0x8e, + 0x1e, 0x25, 0x4f, 0xe1, 0x87, 0xea, 0xed, 0x94, 0x71, 0x7a, 0x7e, 0x84, + 0x69, 0x18, 0x84, 0x00, 0x91, 0x9a, 0x84, 0x28, 0x1e, 0x64, 0x22, 0x8b, + 0xfd, 0xbd, 0x36, 0x5b, 0x75, 0x54, 0x89, 0x91, 0x5f, 0x52, 0xc9, 0x78, + 0xc0, 0xa6, 0xb9, 0xdd, 0xbd, 0x27, 0x09, 0x5a, 0x7a, 0x93, 0x57, 0xcf, + 0x1e, 0x89, 0x64, 0x54, 0x2d, 0xa6, 0xa6, 0x82, 0x70, 0x76, 0x25, 0x5f, + 0x50, 0x8a, 0x18, 0xca, 0x65, 0x40, 0x11, 0xc5, 0xab, 0xab, 0xd1, 0x9c, + 0xe3, 0x10, 0xce, 0xe9, 0x9c, 0x60, 0x21, 0x9d, 0x1a, 0x5f, 0xd7, 0x44, + 0x1a, 0x67, 0x33, 0x92, 0xde, 0xd0, 0x43, 0x58, 0x0f, 0xaf, 0xfa, 0x12, + 0x95, 0xed, 0xd6, 0xe1, 0xde, 0xb8, 0x6c, 0x71, 0x86, 0x7d, 0x8a, 0x5d, + 0x36, 0xf4, 0x92, 0x3d, 0x1a, 0xee, 0x0e, 0x1f, 0x7e, 0xb3, 0xb3, 0xb7, + 0xf3, 0xf8, 0xe1, 0x4e, 0xfa, 0x28, 0x1d, 0xec, 0x8c, 0xf7, 0x76, 0xf6, + 0x1f, 0x3e, 0x79, 0xf4, 0x70, 0xb8, 0xbf, 0xb7, 0x9b, 0x3e, 0x11, 0x5c, + 0x89, 0x6a, 0x9d, 0x80, 0x49, 0x69, 0xb6, 0xba, 0x4a, 0xf7, 0x1e, 0x3d, + 0x6e, 0x6e, 0x2d, 0x7f, 0x0a, 0xd7, 0x02, 0xfd, 0xbb, 0xbc, 0xc1, 0xb4, + 0xbf, 0x78, 0x0a, 0x97, 0xf7, 0x37, 0x4d, 0x7e, 0x20, 0x90, 0x96, 0x9e, + 0x7a, 0xe6, 0xcf, 0x5f, 0x1c, 0x62, 0x5b, 0xa8, 0xdb, 0x5f, 0x45, 0x9a, + 0x8c, 0x6c, 0x19, 0xef, 0x98, 0x6e, 0x16, 0xee, 0x56, 0x3f, 0x39, 0xf2, + 0xbb, 0xd5, 0xd8, 0xac, 0x86, 0x4b, 0xc2, 0xef, 0x18, 0xfd, 0xcd, 0x67, + 0x9d, 0x37, 0x2a, 0x02, 0xfc, 0x16, 0x53, 0x60, 0x28, 0x75, 0xab, 0xae, + 0x49, 0x89, 0xd5, 0x71, 0xf6, 0x1a, 0xfc, 0xaa, 0xaa, 0xae, 0xb8, 0x3e, + 0x53, 0x23, 0x4b, 0x9a, 0x5c, 0x9c, 0xfc, 0x14, 0x0b, 0x45, 0xe7, 0xe7, + 0x2f, 0x14, 0xce, 0xbb, 0x6a, 0x90, 0x86, 0xac, 0xe3, 0x97, 0xf3, 0x41, + 0x46, 0xdd, 0xbc, 0x7e, 0xf6, 0xe7, 0xf7, 0xaf, 0x2e, 0xfe, 0xf4, 0xe1, + 0xd5, 0x8f, 0x7f, 0xda, 0x3d, 0x7d, 0x36, 0x9a, 0xbe, 0xfa, 0xf5, 0x4f, + 0xfb, 0xaf, 0x7e, 0x1d, 0xfe, 0xe3, 0xaf, 0xbf, 0x1e, 0xde, 0x9e, 0x5e, + 0xfc, 0xf5, 0xd1, 0xab, 0xe9, 0x9b, 0xf7, 0xaf, 0x7e, 0xfd, 0xf3, 0xf4, + 0xf5, 0xb3, 0x3f, 0x7d, 0x2b, 0x50, 0x3b, 0xab, 0x49, 0xc5, 0x43, 0x90, + 0x34, 0x0d, 0xb5, 0x81, 0x24, 0x03, 0xe1, 0xa0, 0x5d, 0xbb, 0xb5, 0x1c, + 0xfb, 0xf9, 0x56, 0x72, 0x4c, 0x01, 0xce, 0xc9, 0x8b, 0xf3, 0x8b, 0x73, + 0x73, 0xb2, 0x58, 0x68, 0x9c, 0xf2, 0x41, 0x53, 0xd5, 0xe6, 0x20, 0xa3, + 0xd7, 0x95, 0xa0, 0xd4, 0x6a, 0x95, 0x7b, 0xbd, 0x55, 0xa8, 0x0d, 0x2a, + 0xce, 0x97, 0x19, 0x5a, 0x9e, 0xa5, 0xdc, 0x48, 0x38, 0x54, 0x72, 0xc8, + 0x32, 0x72, 0xca, 0x82, 0x02, 0x4c, 0xcc, 0x00, 0x72, 0xb5, 0x57, 0x5e, + 0x72, 0x6e, 0x26, 0xaf, 0xb4, 0xd0, 0x78, 0x91, 0xc4, 0x23, 0x61, 0x53, + 0x69, 0x3e, 0x46, 0xcd, 0xd6, 0xe0, 0x2a, 0x0c, 0xfd, 0x9e, 0x6e, 0x30, + 0xc7, 0xcc, 0xb5, 0x4c, 0x0e, 0x89, 0xdc, 0x52, 0xbd, 0x16, 0x17, 0x00, + 0xd6, 0x97, 0x66, 0x9d, 0xba, 0xf0, 0x3c, 0xaa, 0x6c, 0x24, 0xe7, 0xc5, + 0x12, 0x93, 0x54, 0xac, 0xae, 0x79, 0xbe, 0xc1, 0x25, 0xea, 0x26, 0xcd, + 0x86, 0xcb, 0xc5, 0xfc, 0xb2, 0x4c, 0x47, 0x72, 0x36, 0x5c, 0x11, 0x98, + 0xc2, 0x55, 0x80, 0xa2, 0xb5, 0xc7, 0xb2, 0x35, 0xa8, 0xef, 0x52, 0x0b, + 0xb2, 0x6a, 0x20, 0x14, 0x81, 0x88, 0x71, 0x25, 0x12, 0x1b, 0xfa, 0x3f, + 0x80, 0x30, 0x17, 0x64, 0x24, 0xcc, 0xc7, 0x1c, 0xe3, 0x27, 0x6a, 0x86, + 0xc2, 0xea, 0xe7, 0x62, 0x69, 0x97, 0x6e, 0xf9, 0x56, 0x92, 0x7b, 0x54, + 0x01, 0xf7, 0xc3, 0x52, 0x9c, 0x5b, 0xb2, 0x4d, 0xa7, 0xe3, 0xaa, 0xca, + 0x6f, 0xa2, 0x4f, 0x2f, 0x11, 0x6c, 0xaa, 0x2d, 0xe7, 0x23, 0x15, 0x84, + 0xf2, 0x6d, 0xad, 0xf7, 0x60, 0xb7, 0x7c, 0xc8, 0xb7, 0x22, 0x70, 0x6d, + 0xc4, 0xf1, 0x57, 0x2a, 0x82, 0x85, 0x61, 0xe4, 0xe9, 0xe8, 0x32, 0x8d, + 0x7c, 0x32, 0x11, 0xbc, 0x8a, 0x9c, 0x33, 0x6a, 0x8c, 0x13, 0x30, 0x02, + 0xa8, 0x35, 0x67, 0x01, 0x4d, 0x42, 0xda, 0x9e, 0x20, 0xa4, 0x4b, 0xb4, + 0x11, 0x1f, 0xcc, 0x42, 0x0a, 0xc1, 0x5a, 0x7d, 0x6a, 0x1e, 0x6d, 0x5f, + 0x49, 0xff, 0x37, 0x6a, 0x23, 0xcd, 0x73, 0xcd, 0x4d, 0xc2, 0x76, 0xad, + 0x5f, 0x8e, 0x11, 0xd3, 0x04, 0x9a, 0xee, 0x94, 0xba, 0x08, 0x07, 0x14, + 0xda, 0xd8, 0xe9, 0x7f, 0x13, 0x79, 0xe4, 0x0e, 0xc9, 0xf5, 0x69, 0x58, + 0xd0, 0x5a, 0xc8, 0x0f, 0x4b, 0x15, 0x34, 0x0b, 0x5a, 0xe2, 0x03, 0xdb, + 0xf8, 0x05, 0x41, 0x25, 0x86, 0xea, 0x83, 0x16, 0x02, 0x26, 0x7a, 0x9e, + 0x24, 0xa6, 0x72, 0x35, 0x1c, 0x8b, 0x2a, 0x73, 0x55, 0xac, 0x34, 0xc0, + 0x28, 0x18, 0x0f, 0x0c, 0xfe, 0xd4, 0x55, 0x9c, 0x53, 0x8b, 0x43, 0x9d, + 0xa3, 0x9c, 0x8a, 0x1e, 0x99, 0xb4, 0x59, 0xa9, 0x85, 0x73, 0xa8, 0x58, + 0x24, 0xe2, 0xb2, 0x41, 0x74, 0x0e, 0xb0, 0xf8, 0x24, 0x87, 0x99, 0x80, + 0xc8, 0x24, 0xa7, 0x84, 0x70, 0x0c, 0xa5, 0xa0, 0xfc, 0xd2, 0x84, 0x88, + 0x71, 0x48, 0x74, 0x95, 0x42, 0xc4, 0x6a, 0xc8, 0xbc, 0xab, 0x69, 0x8d, + 0x0e, 0xab, 0xc7, 0xfd, 0x9d, 0xad, 0x96, 0xc0, 0x68, 0x59, 0xda, 0x4f, + 0x28, 0x3d, 0xb2, 0x22, 0x66, 0x5e, 0x1a, 0xbc, 0x87, 0xf7, 0x4b, 0xaf, + 0xeb, 0xf9, 0xda, 0x9a, 0xc4, 0x81, 0x6f, 0xed, 0xf6, 0x77, 0xbb, 0xf2, + 0xeb, 0x9e, 0x68, 0x88, 0xf8, 0xfb, 0xbe, 0xd2, 0xcc, 0x4e, 0xd7, 0x1e, + 0xdc, 0x89, 0xe8, 0x86, 0x72, 0xbe, 0x19, 0x3e, 0x5c, 0x69, 0x26, 0xd9, + 0xc5, 0xca, 0x17, 0x3e, 0x96, 0x55, 0xd3, 0xb6, 0x73, 0x66, 0x64, 0x6a, + 0xd5, 0x56, 0xab, 0x28, 0xaa, 0xa2, 0x88, 0x22, 0xef, 0x29, 0xaf, 0x91, + 0x8f, 0x22, 0x5d, 0xaf, 0x88, 0x33, 0xd7, 0x9b, 0xc1, 0xb9, 0xb9, 0xee, + 0x5d, 0x2f, 0x6c, 0xed, 0xf3, 0x41, 0xad, 0xd9, 0x1a, 0xea, 0x1f, 0x7b, + 0x5d, 0x4f, 0x12, 0x7b, 0x08, 0x6d, 0x57, 0x94, 0x3d, 0x14, 0xde, 0x81, + 0xb4, 0x2e, 0xb5, 0xa6, 0x9e, 0xae, 0xb2, 0xc8, 0x63, 0x92, 0x1b, 0x19, + 0x36, 0x34, 0xc2, 0x6c, 0x93, 0x3e, 0xa2, 0x63, 0x0c, 0x7f, 0xaf, 0xd8, + 0x0e, 0xb7, 0x1b, 0xbb, 0xfd, 0x50, 0xae, 0x27, 0x06, 0xb3, 0xe0, 0xe1, + 0xcb, 0xcd, 0x24, 0x0a, 0xff, 0x9b, 0x97, 0x55, 0x1c, 0x1e, 0x29, 0xfd, + 0xac, 0x93, 0x03, 0xb2, 0xc6, 0xaa, 0xef, 0x7e, 0xf6, 0x55, 0xdf, 0xf9, + 0x9c, 0xab, 0x4e, 0xb4, 0xdb, 0x5c, 0x75, 0x3e, 0x80, 0xae, 0xe1, 0xa5, + 0x35, 0x27, 0x16, 0xb2, 0xe7, 0xdd, 0x82, 0x74, 0xe7, 0x76, 0x3d, 0x24, + 0x09, 0x2d, 0xc3, 0x0c, 0x14, 0x6a, 0x4e, 0xca, 0x90, 0x77, 0xf4, 0x62, + 0x6f, 0x94, 0xda, 0x71, 0xae, 0x07, 0x72, 0xd2, 0x51, 0x3b, 0x21, 0x2b, + 0xac, 0xd9, 0x93, 0x85, 0xb1, 0xbb, 0xae, 0x42, 0x40, 0x1f, 0x89, 0x20, + 0x72, 0x61, 0xab, 0x4f, 0x91, 0x0d, 0x9b, 0x16, 0x7a, 0x22, 0x83, 0x59, + 0x54, 0x5a, 0x7c, 0xe7, 0x2d, 0x3f, 0x7f, 0x60, 0x8f, 0x4a, 0x04, 0xc2, + 0x52, 0x35, 0x40, 0x12, 0xcc, 0xe5, 0x75, 0x82, 0x80, 0x92, 0x99, 0xe7, + 0xb5, 0xcb, 0x8f, 0xd1, 0x20, 0xe0, 0x8a, 0x2b, 0xbb, 0xcf, 0x70, 0xba, + 0x12, 0x5d, 0xd8, 0xdf, 0x43, 0x95, 0x5d, 0x92, 0x6d, 0xd9, 0x9d, 0x76, + 0x85, 0xe5, 0x21, 0x2d, 0x3a, 0x52, 0xa4, 0xf4, 0x91, 0x16, 0x4d, 0x6e, + 0xa0, 0xc3, 0x62, 0x5e, 0xae, 0xf8, 0x78, 0x4b, 0xb9, 0x61, 0xc8, 0x6f, + 0x82, 0xab, 0xa1, 0x87, 0x40, 0x9a, 0x08, 0x1e, 0x2d, 0xf4, 0x47, 0x4f, + 0xaa, 0x6b, 0xe8, 0xbc, 0xbf, 0x82, 0x8b, 0xef, 0x7d, 0x16, 0x7a, 0xdf, + 0xbb, 0x83, 0xda, 0xf5, 0x89, 0xa0, 0x85, 0xd0, 0x8c, 0x55, 0x15, 0xa1, + 0x2c, 0x30, 0xd2, 0x43, 0x28, 0x1f, 0x5d, 0x40, 0x83, 0x95, 0xd2, 0xda, + 0x6a, 0x0b, 0x73, 0x91, 0xdc, 0xf6, 0x23, 0x23, 0x67, 0xa6, 0x8d, 0x55, + 0xe1, 0x09, 0xba, 0xfb, 0xd8, 0xc4, 0xa7, 0x26, 0x9c, 0x19, 0xdf, 0x98, + 0x7c, 0x1d, 0xd0, 0xdd, 0xe8, 0xfa, 0x4a, 0x27, 0xf3, 0x59, 0x7c, 0x74, + 0x9a, 0x8d, 0x47, 0x47, 0xe9, 0xa4, 0xaa, 0x16, 0x68, 0x97, 0x43, 0x11, + 0x00, 0x0f, 0x44, 0x64, 0xfd, 0x16, 0xe2, 0x14, 0x52, 0x63, 0x33, 0x30, + 0x4e, 0x33, 0xf2, 0x50, 0xd2, 0xb7, 0xc8, 0x65, 0x84, 0x7e, 0xfb, 0x14, + 0x9e, 0xe5, 0xd6, 0x98, 0xba, 0x4f, 0x1c, 0x4b, 0x08, 0x60, 0x87, 0x22, + 0x70, 0x68, 0x4d, 0x48, 0x5a, 0x70, 0x23, 0xed, 0x0a, 0x21, 0xaa, 0xd1, + 0xdd, 0x99, 0xde, 0xa4, 0xa0, 0x96, 0x12, 0x91, 0xbb, 0x38, 0x1e, 0x16, + 0x4f, 0x46, 0x85, 0x3e, 0xee, 0x12, 0xc1, 0x2c, 0x5b, 0xf8, 0x26, 0xbd, + 0xb5, 0x7d, 0x30, 0x3e, 0x30, 0x0a, 0x55, 0x7f, 0xdc, 0x15, 0x1a, 0x8a, + 0x4c, 0x85, 0x93, 0xb2, 0x54, 0xbc, 0xea, 0x9c, 0xc4, 0x1e, 0x42, 0x3e, + 0xd8, 0xe1, 0xe2, 0x97, 0x8e, 0x7d, 0xe6, 0xec, 0x60, 0x10, 0xf7, 0x89, + 0x8c, 0x37, 0xa4, 0x92, 0x64, 0x33, 0x37, 0x44, 0x5f, 0x95, 0x8b, 0xb2, + 0x1b, 0x5d, 0x2c, 0x96, 0x8c, 0x68, 0xf3, 0xf0, 0xe5, 0xd9, 0xeb, 0x2d, + 0xcc, 0x2e, 0xa0, 0x82, 0x2f, 0x51, 0xd9, 0x8a, 0x90, 0x58, 0x4e, 0xae, + 0x44, 0xa5, 0xd0, 0x33, 0x5a, 0x69, 0x7a, 0x12, 0x57, 0x98, 0x82, 0xda, + 0x6c, 0x7b, 0x18, 0x0d, 0x99, 0x96, 0xea, 0x86, 0x80, 0x18, 0xa5, 0xe5, + 0xb6, 0x2a, 0x58, 0x2b, 0x78, 0xf9, 0x3d, 0x61, 0x4e, 0x6b, 0x27, 0x23, + 0xb5, 0x36, 0xbf, 0xc6, 0xd1, 0x5e, 0x1a, 0xd1, 0xbd, 0x47, 0x7d, 0xe9, + 0x0d, 0x23, 0xcb, 0x15, 0x27, 0x9f, 0xfc, 0x63, 0x3e, 0x49, 0x2b, 0x3a, + 0xfd, 0x8d, 0x93, 0x7f, 0xd7, 0x5d, 0xe9, 0x8e, 0x6a, 0x2c, 0x4e, 0xec, + 0xb4, 0x8b, 0x7d, 0x4d, 0xf9, 0xb0, 0x55, 0x28, 0xf4, 0x27, 0x5e, 0xd5, + 0x08, 0x0d, 0xa1, 0xa7, 0x81, 0xee, 0x07, 0x47, 0x12, 0x5b, 0xee, 0x67, + 0x96, 0x9a, 0x22, 0x78, 0x3e, 0x63, 0x18, 0x30, 0x21, 0x9f, 0xd8, 0x45, + 0x84, 0x35, 0xeb, 0x72, 0xad, 0x99, 0x2c, 0xd4, 0x57, 0x49, 0x69, 0x57, + 0x6d, 0xd5, 0x99, 0x80, 0x2c, 0xb2, 0x9e, 0x79, 0xbb, 0xab, 0xba, 0x58, + 0x50, 0x80, 0x07, 0x62, 0x74, 0xf5, 0x6d, 0x38, 0xa8, 0x15, 0x92, 0xb7, + 0x3b, 0x98, 0xbb, 0xc7, 0x7a, 0x57, 0x33, 0xd7, 0xc2, 0xdb, 0xca, 0x6a, + 0x6b, 0x3b, 0x89, 0xa8, 0xc5, 0xd7, 0xac, 0xf1, 0x20, 0x5a, 0x69, 0x0c, + 0x8d, 0x14, 0xa4, 0xc5, 0xba, 0x5b, 0x34, 0x39, 0x9c, 0xd4, 0xbd, 0xf3, + 0xeb, 0xa1, 0x95, 0x57, 0xd6, 0xf8, 0x45, 0xbe, 0x8e, 0x35, 0x49, 0x45, + 0x86, 0xc7, 0x8e, 0x3a, 0x8a, 0xdd, 0x40, 0x1a, 0xa1, 0x39, 0x54, 0x0b, + 0xbc, 0xee, 0xea, 0x88, 0x4f, 0x31, 0x20, 0x97, 0xc5, 0x8c, 0xa6, 0xef, + 0x2b, 0x6d, 0x41, 0xbc, 0xf3, 0xec, 0x57, 0xb8, 0x62, 0x6f, 0x72, 0x1c, + 0xae, 0xc8, 0x7e, 0x8c, 0xea, 0xbd, 0x18, 0x39, 0xd4, 0x32, 0xb1, 0xbd, + 0x6f, 0x65, 0x67, 0x91, 0x07, 0x4b, 0xa0, 0x36, 0x07, 0x4f, 0x5b, 0x62, + 0x44, 0x64, 0x54, 0x40, 0xf8, 0xfb, 0xe6, 0x36, 0xa9, 0xa5, 0x7e, 0x42, + 0x9c, 0x72, 0x94, 0x4d, 0xb0, 0x4c, 0x2c, 0x10, 0x91, 0x6c, 0x9f, 0x51, + 0x85, 0x58, 0x29, 0x04, 0x50, 0x96, 0xb2, 0x16, 0xc3, 0x76, 0xa9, 0x8b, + 0x82, 0x59, 0xaa, 0x80, 0x1f, 0x15, 0xc4, 0x26, 0x87, 0x99, 0xc5, 0x79, + 0xcc, 0x64, 0x00, 0x6e, 0xa3, 0x4c, 0x75, 0xe0, 0x7c, 0x0c, 0x23, 0x2d, + 0x31, 0x4b, 0x54, 0x2a, 0xfa, 0x48, 0x60, 0x97, 0xb2, 0x60, 0xda, 0x4b, + 0x89, 0x78, 0xf6, 0x97, 0x88, 0xe3, 0x51, 0xa1, 0x58, 0x6f, 0xa6, 0x64, + 0xdf, 0x63, 0x42, 0x22, 0x5a, 0xd1, 0x3a, 0x36, 0x8d, 0x42, 0x82, 0xa6, + 0x11, 0xa7, 0x61, 0x34, 0x2d, 0xe8, 0x0e, 0xd4, 0xdc, 0x67, 0x91, 0x36, + 0xf6, 0xef, 0x65, 0x41, 0xfb, 0x9f, 0x22, 0x6d, 0xec, 0xb7, 0x49, 0x1b, + 0x77, 0xd5, 0xaf, 0x5e, 0x56, 0x2a, 0x59, 0x4a, 0x5f, 0x4f, 0x48, 0xf7, + 0xd2, 0x46, 0x4f, 0xe2, 0x1d, 0x0f, 0x9b, 0xca, 0x77, 0x9f, 0x64, 0x77, + 0x45, 0x1b, 0xf4, 0xb2, 0x88, 0xe3, 0x54, 0x7b, 0x31, 0xa7, 0xea, 0x05, + 0x00, 0x77, 0x95, 0x37, 0xb4, 0xf4, 0x59, 0x62, 0xd6, 0xdf, 0x70, 0x20, + 0xf4, 0x92, 0xe3, 0x73, 0x24, 0xbc, 0x8b, 0x59, 0x57, 0xb0, 0x3b, 0xc3, + 0x1e, 0x19, 0xa1, 0xc1, 0xf3, 0x11, 0xf7, 0xb2, 0x73, 0xd1, 0x37, 0xc6, + 0x85, 0x64, 0x3b, 0xe3, 0xa8, 0x74, 0x07, 0x06, 0x64, 0x36, 0x3a, 0x9e, + 0xbb, 0xf2, 0x20, 0x6e, 0x84, 0x15, 0xb2, 0xe7, 0xca, 0x93, 0xba, 0xf1, + 0x35, 0x2f, 0xe8, 0xc3, 0x55, 0x08, 0x64, 0x88, 0x8a, 0x76, 0x7f, 0x19, + 0x7e, 0x25, 0xb3, 0x31, 0x6e, 0x45, 0xcc, 0xca, 0x00, 0x93, 0x05, 0x2e, + 0x50, 0x18, 0x53, 0xe0, 0x4c, 0xc1, 0xa8, 0x76, 0x07, 0x7b, 0x8a, 0xee, + 0x35, 0x1f, 0x70, 0x21, 0x65, 0x63, 0xa5, 0xae, 0xcf, 0x9f, 0xde, 0x9e, + 0x1c, 0x45, 0x79, 0x56, 0x9a, 0xfd, 0x65, 0x81, 0x61, 0x2e, 0xe5, 0x2a, + 0xe8, 0x22, 0x1c, 0x1d, 0xa5, 0x77, 0x14, 0x06, 0x26, 0xb1, 0xdd, 0x3e, + 0xde, 0x2e, 0x0a, 0x26, 0xb1, 0xac, 0x89, 0xe2, 0x66, 0xa6, 0xc8, 0xd2, + 0x7a, 0x86, 0xe2, 0x53, 0xdf, 0x76, 0xec, 0xd7, 0x3a, 0xf3, 0xcc, 0x42, + 0x3e, 0xcb, 0xc1, 0xe7, 0xa6, 0xee, 0x3d, 0xfd, 0xfc, 0xd8, 0x1d, 0x2c, + 0x60, 0x59, 0xee, 0x30, 0x1e, 0x70, 0xbf, 0x8a, 0x7e, 0xa7, 0x5d, 0x64, + 0x85, 0xae, 0xd1, 0xbd, 0x93, 0x0d, 0x98, 0x38, 0xe2, 0x5d, 0x10, 0x4f, + 0xee, 0x3a, 0xfd, 0x77, 0x5a, 0xb1, 0x7a, 0x5c, 0x0c, 0xa7, 0x27, 0x06, + 0xdf, 0x1e, 0x1b, 0xa0, 0x1d, 0x7c, 0x2e, 0x73, 0x05, 0xaf, 0x55, 0x9f, + 0xd0, 0x1b, 0x82, 0x05, 0x21, 0xaf, 0xbd, 0xe4, 0x9a, 0x0a, 0x16, 0x92, + 0x1f, 0x00, 0x2c, 0xb5, 0x0a, 0x58, 0x3e, 0xc4, 0x2b, 0x26, 0xa4, 0x00, + 0x90, 0x95, 0x58, 0xad, 0x99, 0xe5, 0x82, 0x53, 0x19, 0x0e, 0xe7, 0x64, + 0x84, 0xdf, 0xed, 0x7f, 0xb0, 0x58, 0xb4, 0x32, 0x23, 0x9d, 0xc3, 0x42, + 0xe1, 0x04, 0x35, 0xb0, 0xd1, 0x31, 0xb6, 0xc6, 0x76, 0x69, 0x4a, 0xa6, + 0x29, 0x39, 0xfe, 0x66, 0x0f, 0x8e, 0xd5, 0x65, 0x3a, 0xb8, 0xad, 0xb3, + 0x28, 0x3c, 0xf9, 0xb9, 0xb1, 0x8c, 0x28, 0x7c, 0xe9, 0x7d, 0x3e, 0x67, + 0x54, 0x93, 0x93, 0xff, 0x3e, 0x0e, 0x0e, 0x7a, 0xd8, 0xf7, 0x71, 0x7e, + 0x89, 0xae, 0xb1, 0x00, 0xa9, 0x69, 0x71, 0xe9, 0x82, 0xa7, 0xa4, 0xc0, + 0x45, 0x52, 0x56, 0xd7, 0x95, 0xae, 0x5c, 0x2a, 0xe3, 0x1e, 0x9c, 0x64, + 0x8e, 0x9f, 0xc1, 0x09, 0x56, 0x8a, 0xbb, 0x49, 0x23, 0x8a, 0x33, 0xd1, + 0xe2, 0xea, 0x76, 0x8e, 0x0b, 0x1b, 0x29, 0x01, 0xad, 0x5b, 0xb7, 0x5a, + 0x09, 0x68, 0x31, 0x09, 0xde, 0xa5, 0x03, 0xb4, 0xb6, 0x7e, 0xf7, 0xb9, + 0x6b, 0x1f, 0xd0, 0x7a, 0x50, 0xeb, 0xcb, 0x20, 0x38, 0x44, 0x9f, 0xef, + 0xbb, 0x4b, 0x1e, 0x79, 0xac, 0xd1, 0x9c, 0x04, 0x6f, 0xeb, 0x0f, 0xc1, + 0x24, 0xdd, 0x45, 0x63, 0x09, 0x26, 0xef, 0x33, 0x84, 0x84, 0x67, 0x86, + 0x2e, 0x62, 0xd5, 0xc8, 0x92, 0x4a, 0x2b, 0xe7, 0x2c, 0xf5, 0x61, 0x31, + 0x79, 0x7e, 0x4b, 0xf6, 0xd4, 0x7b, 0xe1, 0x28, 0x7c, 0xb2, 0x4a, 0x28, + 0x92, 0xb5, 0x1f, 0x9d, 0xf7, 0xe0, 0x8a, 0x31, 0xa6, 0x4c, 0x74, 0x24, + 0x8a, 0x2a, 0xf7, 0xa0, 0xd9, 0x0a, 0x55, 0x9d, 0x09, 0xd2, 0x95, 0x09, + 0x6e, 0xcd, 0x60, 0x62, 0x74, 0xa5, 0xfb, 0x00, 0x39, 0x51, 0x4a, 0xdd, + 0x8d, 0x65, 0x65, 0x39, 0xed, 0xb2, 0x74, 0x35, 0x72, 0xcd, 0xac, 0x0c, + 0x4b, 0xd4, 0xf5, 0x70, 0x8b, 0x32, 0xd5, 0x08, 0x39, 0x6a, 0xa3, 0x92, + 0xba, 0xd4, 0x01, 0x23, 0xdc, 0x8a, 0x6f, 0xe6, 0xb5, 0x16, 0xb1, 0xca, + 0x38, 0x4a, 0x32, 0xf5, 0xd5, 0x6a, 0xdd, 0x0b, 0x56, 0x65, 0x2f, 0x04, + 0x3f, 0x73, 0x89, 0x5a, 0x29, 0x71, 0x5e, 0x53, 0x35, 0x1f, 0x93, 0x19, + 0x82, 0x27, 0x8f, 0x86, 0x1f, 0x24, 0x08, 0x05, 0xed, 0x94, 0x0b, 0xd3, + 0x77, 0x11, 0xa0, 0xf0, 0xb1, 0xa0, 0x92, 0x16, 0x47, 0x4a, 0x8e, 0x0e, + 0x97, 0x20, 0xce, 0x25, 0x10, 0xb4, 0x36, 0x53, 0x01, 0x7e, 0x87, 0xeb, + 0x0e, 0x73, 0x12, 0x23, 0x0d, 0xaf, 0x25, 0xd7, 0x2a, 0x42, 0x97, 0x49, + 0xb1, 0x28, 0x35, 0xb6, 0x9c, 0x78, 0x88, 0x54, 0x46, 0x91, 0x62, 0x28, + 0x07, 0x46, 0xbc, 0xb8, 0x94, 0xfd, 0x2a, 0xdb, 0x1e, 0x15, 0xc3, 0x6a, + 0xbb, 0xaa, 0x26, 0xd8, 0x72, 0x45, 0xa5, 0x18, 0x7d, 0xf1, 0xe2, 0xe7, + 0x5a, 0xbc, 0x18, 0x28, 0xb3, 0x09, 0xa3, 0xb1, 0xc4, 0x6b, 0x78, 0x55, + 0x28, 0x78, 0xe5, 0x9d, 0x8b, 0x1c, 0xf4, 0x34, 0xd3, 0xf7, 0x5f, 0xb3, + 0x73, 0x89, 0xd1, 0x84, 0x2d, 0x6c, 0x9e, 0xe6, 0x16, 0x2a, 0xf5, 0xa2, + 0x18, 0xa3, 0x01, 0x1e, 0x57, 0x94, 0x27, 0x1c, 0xd0, 0xd7, 0x68, 0x55, + 0xf8, 0xb1, 0x4e, 0xbf, 0xaa, 0xae, 0x3a, 0x64, 0xd2, 0x19, 0xd8, 0x03, + 0x5d, 0x2b, 0x56, 0xda, 0xa8, 0xab, 0xa7, 0x1b, 0x67, 0xfe, 0xab, 0xbc, + 0x74, 0xd1, 0x23, 0xd5, 0x52, 0x34, 0xa7, 0xca, 0x4e, 0x81, 0x6a, 0x79, + 0xee, 0xd1, 0x91, 0xd2, 0x33, 0xbd, 0xc2, 0x7a, 0x2a, 0x87, 0x31, 0x50, + 0x36, 0x96, 0x35, 0x2a, 0x17, 0xb8, 0x0c, 0xea, 0xe8, 0xaa, 0x42, 0xa9, + 0xdc, 0x08, 0xfd, 0x45, 0xaa, 0xa1, 0x89, 0x5f, 0x98, 0x8e, 0x9b, 0x8a, + 0x70, 0x51, 0x4a, 0x8c, 0x46, 0x36, 0xe8, 0x1a, 0xf2, 0xa3, 0xce, 0x45, + 0xb9, 0x18, 0x70, 0xca, 0x66, 0x8d, 0xf2, 0x36, 0x87, 0x36, 0x07, 0x5e, + 0xc4, 0x21, 0x96, 0x9c, 0xf1, 0x20, 0x90, 0xb4, 0x0b, 0xc5, 0x9e, 0x25, + 0xd0, 0x36, 0x8c, 0xb4, 0xd7, 0x5b, 0x2b, 0x74, 0x4a, 0xee, 0x54, 0xd8, + 0xba, 0x7c, 0x48, 0xf8, 0xbb, 0x7a, 0x05, 0xc6, 0xee, 0x85, 0xd0, 0xc7, + 0xe7, 0x48, 0x61, 0x6a, 0xae, 0xf4, 0x0a, 0xde, 0xad, 0x7d, 0xae, 0xc5, + 0xae, 0x39, 0x64, 0x59, 0xdf, 0x41, 0x1e, 0x3d, 0x4c, 0xe9, 0xb0, 0x49, + 0xae, 0x76, 0x8a, 0x00, 0xdd, 0x41, 0xc6, 0x50, 0x78, 0x53, 0xae, 0xc2, + 0x22, 0xf1, 0x0f, 0x67, 0xac, 0x83, 0x72, 0x94, 0xac, 0xa1, 0x9d, 0x87, + 0x02, 0xce, 0x01, 0x63, 0xc6, 0xde, 0xef, 0x87, 0xca, 0xa4, 0x58, 0x78, + 0xbe, 0x6c, 0xc0, 0xac, 0x4a, 0xc0, 0x5a, 0x04, 0x95, 0x47, 0x61, 0x8c, + 0x4a, 0xc1, 0x96, 0x72, 0xa1, 0x3e, 0x36, 0x25, 0x02, 0x9f, 0x6c, 0x9a, + 0x0f, 0xbb, 0xe6, 0x9a, 0x25, 0x7c, 0xf8, 0xa8, 0x3e, 0x9a, 0x94, 0x59, + 0x91, 0x2a, 0x74, 0x86, 0xf4, 0x3a, 0xfe, 0x1f, 0x32, 0xb5, 0xaf, 0x1e, + 0x3c, 0x38, 0xb1, 0xf1, 0x24, 0xdc, 0x29, 0xf5, 0xda, 0x08, 0x12, 0xe4, + 0xb8, 0x7b, 0x87, 0x3c, 0x44, 0xbc, 0x92, 0x75, 0x96, 0x07, 0x16, 0xd1, + 0x61, 0x53, 0xb3, 0x18, 0x2d, 0x2e, 0x13, 0x48, 0xbb, 0x4b, 0x6a, 0x4d, + 0xf2, 0xf0, 0x51, 0xdf, 0x61, 0xb8, 0xfa, 0x61, 0x84, 0x04, 0x4d, 0xf4, + 0x26, 0xe8, 0x12, 0xd8, 0x88, 0xf9, 0x71, 0xeb, 0xe1, 0xbb, 0xff, 0xf1, + 0x14, 0x3f, 0x69, 0x9b, 0x81, 0x16, 0x64, 0x5f, 0xbd, 0xac, 0x72, 0x29, + 0xca, 0xaa, 0x20, 0xa6, 0xa7, 0x0a, 0xd4, 0x2a, 0xd8, 0x3c, 0xe9, 0x7f, + 0xd3, 0xdf, 0xa1, 0x44, 0x6b, 0x60, 0xd4, 0xa4, 0x8c, 0x3d, 0x58, 0x8a, + 0x9c, 0x74, 0x6b, 0xe2, 0x96, 0x24, 0x0e, 0x9c, 0x0c, 0x2b, 0xa2, 0x35, + 0xb4, 0xac, 0x74, 0x22, 0x4b, 0xd8, 0xbc, 0x2a, 0xb8, 0x2c, 0x16, 0xd7, + 0xb9, 0x04, 0xef, 0x14, 0xd0, 0x5a, 0x15, 0x95, 0x21, 0xa6, 0x21, 0xc5, + 0x23, 0x0b, 0x1c, 0x0c, 0xfe, 0xf7, 0x53, 0x3e, 0x03, 0x41, 0x8f, 0xd8, + 0xdd, 0x03, 0x02, 0x51, 0xa5, 0xe1, 0xe2, 0x1d, 0x32, 0xb9, 0xf6, 0x14, + 0x9c, 0x8f, 0x5d, 0xd8, 0x4a, 0x14, 0xfa, 0xe6, 0x60, 0xcc, 0x08, 0xcc, + 0xf7, 0xd9, 0xeb, 0xf3, 0x1e, 0xfa, 0x87, 0x7a, 0xac, 0xe9, 0x92, 0xa7, + 0x27, 0xc7, 0x00, 0xa9, 0x51, 0x71, 0xd5, 0x93, 0x78, 0x99, 0x8a, 0x21, + 0x7b, 0x1e, 0x9c, 0xce, 0x92, 0x97, 0x70, 0x1d, 0x7f, 0xb8, 0x1b, 0xe9, + 0xdb, 0x92, 0xd0, 0x60, 0x08, 0x7f, 0x7e, 0xf3, 0x1c, 0x84, 0xa5, 0x3f, + 0xe7, 0x25, 0x2a, 0x23, 0xd0, 0xc2, 0x1b, 0x10, 0x33, 0xb4, 0x78, 0x15, + 0xdc, 0x56, 0x37, 0x29, 0x21, 0xc2, 0x6c, 0xa1, 0xf4, 0x84, 0x49, 0xb6, + 0x5d, 0x0b, 0xe9, 0xd0, 0x7a, 0x72, 0x64, 0x12, 0xc7, 0x24, 0x85, 0x4a, + 0x00, 0x88, 0x25, 0x1e, 0x95, 0x4a, 0x0e, 0xd1, 0x93, 0x47, 0x87, 0x67, + 0xef, 0x5e, 0x1f, 0x5f, 0xbc, 0x7b, 0x73, 0xf8, 0x13, 0xf2, 0xc3, 0x79, + 0x2a, 0x95, 0x82, 0xa8, 0x5a, 0x14, 0x5b, 0xba, 0x71, 0x74, 0x20, 0xde, + 0x27, 0x54, 0xbe, 0xf9, 0x41, 0x59, 0x14, 0x75, 0x84, 0xdd, 0x1a, 0xd6, + 0xfd, 0xde, 0x42, 0x54, 0xbf, 0x01, 0xbb, 0xd5, 0x75, 0x43, 0x18, 0xad, + 0xf7, 0x02, 0x14, 0x85, 0xe7, 0x3b, 0x74, 0x4c, 0xd0, 0x9f, 0x00, 0xff, + 0xdd, 0xed, 0x7c, 0xd4, 0xab, 0xc0, 0x15, 0xb2, 0xd9, 0x7c, 0xbf, 0xda, + 0x59, 0x17, 0xdb, 0x68, 0x56, 0x85, 0xd7, 0x03, 0xf7, 0x9c, 0xf7, 0xea, + 0xa2, 0x4a, 0x9e, 0xc6, 0xb5, 0xab, 0x0e, 0x27, 0x13, 0x42, 0xb6, 0x80, + 0xa3, 0x87, 0xe5, 0x21, 0x31, 0xa4, 0xe0, 0x5c, 0xb2, 0xa5, 0x37, 0x2f, + 0x4e, 0xcf, 0xb7, 0x58, 0x9e, 0x61, 0x04, 0x0a, 0x3c, 0x0f, 0x17, 0x65, + 0x8a, 0xb0, 0x68, 0xc9, 0xd1, 0x84, 0xa2, 0x13, 0xed, 0xba, 0x44, 0x50, + 0x05, 0x1f, 0xa8, 0x2b, 0x60, 0x2a, 0x12, 0x0f, 0xc2, 0xf2, 0xa5, 0x76, + 0x6d, 0x71, 0x3c, 0x29, 0xe6, 0x37, 0x82, 0x9c, 0x32, 0x94, 0xad, 0x30, + 0xd0, 0x88, 0xdd, 0xe0, 0xec, 0xda, 0x7b, 0xf4, 0x88, 0x72, 0x9b, 0x42, + 0x49, 0x0c, 0x63, 0xa2, 0xca, 0x35, 0x8f, 0xce, 0x77, 0xba, 0xf0, 0x63, + 0x17, 0x7f, 0x80, 0xda, 0x0b, 0x3f, 0xf7, 0xf1, 0xd7, 0x87, 0xf8, 0xe3, + 0x11, 0xfd, 0xfd, 0x18, 0x7f, 0xfd, 0x1a, 0x7e, 0x3d, 0x7c, 0xbe, 0x0b, + 0x8f, 0xc1, 0xcf, 0x3d, 0xfa, 0xb9, 0x4f, 0x1f, 0xed, 0xa9, 0xe9, 0x1e, + 0x7e, 0xa5, 0xcf, 0xf7, 0xf6, 0xf1, 0xe7, 0xfe, 0x2e, 0x7d, 0xbb, 0x4f, + 0x1f, 0xed, 0xd3, 0x47, 0x0f, 0xf9, 0xa3, 0x87, 0xf4, 0xd1, 0x43, 0xf8, + 0xe8, 0xf8, 0x39, 0x7c, 0xf0, 0xe7, 0xd3, 0x93, 0xa3, 0xe3, 0xde, 0xe1, + 0xb3, 0x57, 0x27, 0x17, 0xd2, 0xd0, 0xf1, 0xd1, 0x05, 0x3c, 0x09, 0x3f, + 0xd1, 0x36, 0x77, 0x74, 0xdc, 0x4d, 0x5e, 0xc2, 0xff, 0x93, 0x97, 0xa7, + 0x3f, 0x1d, 0x9d, 0x9e, 0x5f, 0x74, 0xf1, 0x97, 0x67, 0xc7, 0x2f, 0x0f, + 0xff, 0x0a, 0x9f, 0x5d, 0xbc, 0x78, 0x73, 0xfa, 0xf6, 0xc7, 0x17, 0x67, + 0x6f, 0xe1, 0xe3, 0xe4, 0xcd, 0xf1, 0xcb, 0x93, 0xc3, 0x1f, 0x4e, 0x5e, + 0x9e, 0x5c, 0xfc, 0x55, 0x1a, 0x7a, 0x75, 0xf2, 0x1a, 0x5f, 0x11, 0x22, + 0xe7, 0x1d, 0xbc, 0xaf, 0xac, 0x42, 0xa3, 0xd0, 0x9a, 0x55, 0x8c, 0xb9, + 0x3f, 0xd2, 0x51, 0x3a, 0x80, 0x55, 0x5b, 0x27, 0xe0, 0x85, 0x58, 0x71, + 0xe4, 0xcf, 0xa8, 0x87, 0x73, 0x90, 0x14, 0xc8, 0x38, 0x2d, 0x37, 0xf8, + 0xf5, 0x24, 0x9d, 0xb1, 0xfd, 0x01, 0xce, 0xb3, 0x23, 0xc5, 0x71, 0xd5, + 0xbb, 0x04, 0x06, 0x8e, 0x7e, 0xbb, 0xa7, 0x20, 0xb6, 0x2b, 0x35, 0x9e, + 0x9c, 0x3d, 0x07, 0x92, 0x3b, 0x8f, 0x51, 0xcd, 0xf5, 0x41, 0x89, 0xf6, + 0x13, 0x82, 0x7c, 0x2e, 0x42, 0xd9, 0xc9, 0xd9, 0xeb, 0x73, 0xb1, 0xe4, + 0x61, 0x4a, 0x6c, 0x04, 0xf7, 0x60, 0xf2, 0x63, 0x88, 0x99, 0x89, 0x74, + 0x2c, 0x4e, 0xfd, 0x0a, 0x38, 0x7e, 0xd8, 0xea, 0xbb, 0x1f, 0x0f, 0x2f, + 0x8e, 0x7f, 0x3a, 0xfc, 0xab, 0x16, 0xc8, 0xbc, 0xce, 0xcb, 0x62, 0xc6, + 0x2e, 0x90, 0xeb, 0xb4, 0xcc, 0x25, 0xa8, 0x88, 0x44, 0x2e, 0xcc, 0xc3, + 0x41, 0xba, 0x16, 0xcb, 0x59, 0xe7, 0xff, 0xb7, 0xdd, 0xc7, 0x99, 0x6d, + 0xcb, 0x80, 0x3b, 0xbe, 0x7a, 0xee, 0x55, 0x31, 0xd1, 0x8a, 0x99, 0x36, + 0x21, 0xd4, 0x57, 0x38, 0x08, 0xd1, 0xf1, 0x32, 0x14, 0x19, 0x90, 0xd1, + 0x69, 0xa5, 0x79, 0x9a, 0x29, 0x2e, 0xaa, 0xd8, 0x1a, 0xf4, 0x65, 0x0e, + 0x5a, 0xb0, 0x80, 0x93, 0x34, 0x2e, 0xec, 0xb9, 0x98, 0xa1, 0x05, 0x9f, + 0xa0, 0xb0, 0x60, 0x13, 0xa9, 0x25, 0x64, 0x40, 0x07, 0x4f, 0x76, 0x9e, + 0xec, 0x74, 0xfa, 0xc9, 0x21, 0x97, 0x1f, 0x51, 0x19, 0x97, 0xe0, 0xe3, + 0x28, 0x10, 0x7c, 0x52, 0x14, 0xef, 0x9b, 0xd5, 0xca, 0xe3, 0xed, 0x6a, + 0x6d, 0x52, 0x8b, 0x4a, 0xe2, 0x93, 0xf0, 0xe5, 0x20, 0x1d, 0xdf, 0x0e, + 0xb2, 0xfc, 0x32, 0xbd, 0x1c, 0x3d, 0x9a, 0x4d, 0x67, 0xb3, 0xbd, 0xfc, + 0xb6, 0xda, 0x1b, 0xef, 0x07, 0xf6, 0x80, 0x32, 0x29, 0x67, 0x54, 0x51, + 0x35, 0x19, 0x8b, 0x22, 0x4f, 0x64, 0x63, 0xa5, 0xb3, 0xca, 0x02, 0x49, + 0x98, 0x81, 0xe8, 0x80, 0x85, 0x6c, 0x95, 0x46, 0xb1, 0xd7, 0xfe, 0x25, + 0x5c, 0x2a, 0x8b, 0x41, 0x3f, 0x2f, 0xb6, 0xb9, 0x2d, 0x1d, 0x70, 0x8f, + 0x36, 0x39, 0x2b, 0xb7, 0xe3, 0x25, 0x2e, 0xc4, 0xe9, 0x72, 0x59, 0x48, + 0xd8, 0xa8, 0x46, 0x4a, 0xeb, 0x3c, 0x6f, 0x2d, 0xb3, 0x8e, 0xd5, 0xfa, + 0xf4, 0x26, 0xd5, 0x9a, 0xd4, 0x0e, 0xcc, 0x4d, 0x02, 0x5f, 0xd1, 0x46, + 0xc7, 0x82, 0x3b, 0x27, 0x9f, 0x70, 0x1b, 0x2a, 0xcf, 0x4c, 0x19, 0x6f, + 0x1d, 0x0b, 0xf3, 0x92, 0xbe, 0x88, 0x0a, 0x14, 0xad, 0x1f, 0x37, 0xa4, + 0x93, 0x65, 0xb5, 0x15, 0x9b, 0x25, 0xfb, 0x2d, 0xe6, 0x57, 0x63, 0x6c, + 0x07, 0xa6, 0xdb, 0xa3, 0x44, 0x12, 0x8f, 0xaf, 0xd2, 0x32, 0x7b, 0x43, + 0xdc, 0x37, 0x2d, 0xb2, 0x87, 0xf6, 0x92, 0x9c, 0x14, 0xba, 0x41, 0xe6, + 0xd5, 0x03, 0xc1, 0x90, 0x62, 0x11, 0x47, 0xd3, 0x49, 0x05, 0xb7, 0x50, + 0x4b, 0x54, 0x39, 0x60, 0x54, 0x16, 0x98, 0xa2, 0x70, 0x16, 0x2e, 0xc7, + 0x91, 0x22, 0x19, 0xc2, 0x59, 0x62, 0xbf, 0x59, 0x21, 0x51, 0x25, 0x22, + 0xf5, 0xe0, 0x70, 0x1a, 0x79, 0xb9, 0x06, 0x43, 0xf8, 0x57, 0x7e, 0xfd, + 0x56, 0x11, 0xe8, 0x6a, 0x86, 0xe3, 0xc0, 0x73, 0x74, 0xc3, 0xc0, 0x0e, + 0x9c, 0xce, 0x82, 0xea, 0x31, 0x50, 0x67, 0x82, 0x95, 0x56, 0x2f, 0xd3, + 0x60, 0x1a, 0x19, 0x6a, 0x5e, 0x1b, 0x6c, 0xc6, 0x65, 0x91, 0xc8, 0x9e, + 0x75, 0x68, 0xcd, 0x31, 0x2a, 0xbd, 0xe3, 0x16, 0xfd, 0x22, 0x04, 0x06, + 0xd1, 0xa8, 0x69, 0xa9, 0xd5, 0x3d, 0x41, 0x6a, 0xf1, 0x6d, 0xe4, 0xf3, + 0xc3, 0x65, 0xe8, 0x93, 0x0d, 0xb2, 0xa2, 0xd0, 0x2d, 0xfe, 0x10, 0x14, + 0x74, 0xb4, 0x38, 0x12, 0x70, 0xce, 0x4c, 0x76, 0x17, 0xa9, 0xe1, 0x5a, + 0x33, 0xf3, 0xb4, 0xeb, 0x06, 0x31, 0xe2, 0x8b, 0xc4, 0x06, 0xfa, 0x75, + 0x36, 0xbc, 0xda, 0xb6, 0x3a, 0x89, 0xdb, 0xf8, 0x80, 0xb2, 0x86, 0xed, + 0xdf, 0x49, 0x7b, 0xbd, 0xeb, 0xaa, 0x67, 0x2d, 0x79, 0x79, 0xc6, 0x1f, + 0xb9, 0x7b, 0x2a, 0xed, 0x7d, 0x44, 0x15, 0x9d, 0x25, 0x7e, 0xdf, 0x38, + 0xd8, 0x0d, 0x8e, 0xaf, 0xe7, 0x79, 0x99, 0xf3, 0x2f, 0x45, 0x3a, 0x52, + 0x26, 0x0c, 0xb1, 0x7c, 0x38, 0xd1, 0x8b, 0xd4, 0x40, 0x42, 0x1f, 0x92, + 0xe1, 0x6d, 0x7e, 0xfd, 0x30, 0xb8, 0xf9, 0x9a, 0x70, 0x56, 0xec, 0xb7, + 0xe1, 0x4c, 0x4a, 0x16, 0x83, 0xb9, 0x50, 0xb0, 0x9a, 0x0b, 0xba, 0xc1, + 0x77, 0xb3, 0xac, 0x9e, 0x63, 0x94, 0x35, 0x0b, 0x1f, 0x0d, 0xa3, 0x26, + 0x74, 0xb9, 0x32, 0x56, 0xb4, 0x25, 0x8c, 0xe1, 0x9e, 0x75, 0x82, 0xc6, + 0xee, 0x09, 0xae, 0x6b, 0x71, 0xde, 0x35, 0xad, 0xf6, 0xd4, 0xd0, 0x63, + 0xb7, 0x6e, 0xcd, 0x50, 0xc3, 0x16, 0xff, 0xda, 0x63, 0x59, 0xbf, 0xc7, + 0xd1, 0xfa, 0x3d, 0xfe, 0xac, 0xeb, 0x87, 0x1b, 0xe2, 0x12, 0x8a, 0x4b, + 0x55, 0x46, 0x4a, 0x3e, 0xb2, 0x62, 0x29, 0x19, 0x49, 0xb2, 0x00, 0x2f, + 0xb7, 0x38, 0x69, 0x55, 0x6d, 0x09, 0x61, 0x6f, 0x03, 0x2b, 0xe4, 0xac, + 0xbc, 0x86, 0xc6, 0x1b, 0x86, 0x1b, 0xe3, 0x5d, 0x76, 0xa6, 0x88, 0x65, + 0x3a, 0xea, 0x08, 0xfa, 0x61, 0x04, 0x79, 0x68, 0x59, 0x88, 0x73, 0xe0, + 0x04, 0xa2, 0x12, 0xcc, 0x17, 0xe5, 0xbc, 0xa8, 0x08, 0xb5, 0x6a, 0x9a, + 0x0e, 0x4f, 0xcf, 0xf9, 0x2e, 0x26, 0xf3, 0x16, 0x2b, 0xe1, 0xa3, 0x82, + 0x55, 0x9b, 0xb6, 0xe8, 0x33, 0x5c, 0xc7, 0xdf, 0xec, 0x15, 0xa2, 0x46, + 0x3e, 0x13, 0x31, 0x3c, 0xfc, 0x38, 0x62, 0xe8, 0xfd, 0x5a, 0x41, 0xab, + 0x51, 0xd5, 0xd0, 0x80, 0xfa, 0x24, 0xe5, 0x6f, 0xcc, 0xdc, 0xf1, 0x5f, + 0xe7, 0xa7, 0xaf, 0xa5, 0xca, 0x27, 0x4a, 0x13, 0x31, 0xe0, 0xad, 0x04, + 0x8f, 0x04, 0x0f, 0xbf, 0x22, 0x52, 0x4b, 0x1f, 0xa1, 0x00, 0x07, 0x85, + 0x2b, 0x60, 0xc6, 0xe0, 0x70, 0x21, 0xf1, 0x1b, 0x73, 0x97, 0x18, 0xce, + 0x79, 0xef, 0xf0, 0x4f, 0x99, 0x45, 0xe9, 0x87, 0x54, 0x9b, 0xee, 0x81, + 0xc0, 0xac, 0xfe, 0x2d, 0x2d, 0x2f, 0x7f, 0xa1, 0x3f, 0x25, 0xad, 0xb8, + 0x63, 0xf5, 0xc1, 0x41, 0xe7, 0x38, 0xf0, 0x41, 0x52, 0xdb, 0xd8, 0x7b, + 0x27, 0x7a, 0x96, 0xe3, 0xe7, 0xdb, 0x9e, 0xf2, 0xe2, 0x04, 0x67, 0x4b, + 0x44, 0x86, 0x72, 0xb3, 0x02, 0x13, 0xc0, 0x02, 0x31, 0x2e, 0x2d, 0x7a, + 0x0a, 0xf7, 0x21, 0xe5, 0x62, 0xd0, 0x1a, 0x29, 0xa1, 0xd9, 0xf3, 0x6c, + 0x7d, 0xc0, 0xe7, 0xc4, 0x4d, 0xd4, 0x10, 0xcf, 0x12, 0xc6, 0xd6, 0x0c, + 0x39, 0xea, 0xa1, 0xaa, 0x1b, 0xa7, 0x4a, 0x26, 0xdf, 0x77, 0x35, 0x61, + 0xae, 0x8a, 0x0b, 0xe0, 0x09, 0xd3, 0xb1, 0x7c, 0x0d, 0x2e, 0x1a, 0x38, + 0x72, 0x95, 0xbc, 0xd0, 0xb2, 0x47, 0xa9, 0x96, 0x96, 0x7e, 0xc9, 0x79, + 0x99, 0x9b, 0xbd, 0x2d, 0x14, 0x34, 0xa9, 0xff, 0x9b, 0x90, 0xa2, 0x2b, + 0xce, 0xf5, 0x96, 0x46, 0x04, 0x11, 0x21, 0x39, 0x2b, 0xc4, 0xe4, 0x11, + 0xbe, 0x31, 0xf3, 0x2f, 0xd6, 0x19, 0xe6, 0x86, 0x36, 0xc6, 0x45, 0x31, + 0x48, 0xcb, 0x0d, 0x05, 0x54, 0x21, 0xa8, 0x0c, 0x2d, 0xd9, 0x67, 0x4e, + 0x47, 0xa2, 0x8d, 0xef, 0xf9, 0x51, 0x31, 0xb5, 0x17, 0x0d, 0x68, 0x62, + 0x1b, 0x49, 0x63, 0x20, 0x5d, 0x12, 0xde, 0xb5, 0x89, 0xde, 0x8a, 0x94, + 0x12, 0xcb, 0xfe, 0xa0, 0x32, 0x75, 0xec, 0x7e, 0x2b, 0x08, 0x09, 0x6f, + 0xe6, 0x30, 0x6b, 0xa2, 0xac, 0xd7, 0xae, 0x43, 0xce, 0x1b, 0x8d, 0x72, + 0x76, 0x17, 0x73, 0xef, 0xf3, 0x1c, 0x91, 0xe0, 0x48, 0xd2, 0x04, 0x7e, + 0x83, 0xa6, 0x7d, 0xc6, 0x33, 0x91, 0xf0, 0x03, 0x2b, 0x5f, 0x26, 0xfe, + 0x8a, 0x00, 0xa0, 0xe2, 0x7c, 0x27, 0x17, 0x0e, 0xfc, 0x2a, 0x32, 0xc4, + 0x57, 0x08, 0x07, 0xa9, 0xaa, 0xac, 0x14, 0x45, 0x1b, 0x65, 0x33, 0x3b, + 0xde, 0x06, 0x00, 0x69, 0xd7, 0x31, 0x5e, 0x8b, 0xba, 0x02, 0xf2, 0xde, + 0x72, 0xfe, 0xcc, 0x47, 0xa6, 0xd4, 0x73, 0x6b, 0x1b, 0xff, 0x4c, 0x3a, + 0x23, 0xd0, 0xad, 0xdf, 0x77, 0x0e, 0x92, 0xce, 0x10, 0x03, 0xfe, 0x3a, + 0xc9, 0xbf, 0x36, 0xee, 0x37, 0x32, 0x34, 0x5f, 0xde, 0xb0, 0xcf, 0x3e, + 0xbe, 0x99, 0xef, 0x11, 0x61, 0x29, 0x45, 0x0b, 0xf8, 0x9a, 0xcf, 0xf7, + 0x5a, 0x45, 0x8e, 0xa7, 0x09, 0x7e, 0x8b, 0x19, 0x39, 0x9f, 0x18, 0xba, + 0x8e, 0xc6, 0xe0, 0x75, 0x6a, 0xb3, 0xc7, 0x91, 0x2f, 0x4f, 0x08, 0x73, + 0xaf, 0x11, 0xb6, 0xee, 0x01, 0xc8, 0xa3, 0x86, 0xe8, 0x8b, 0x32, 0xbd, + 0x51, 0xc6, 0xfc, 0x2b, 0xde, 0xd2, 0xbf, 0x2e, 0x66, 0xef, 0x7b, 0x70, + 0x35, 0x61, 0xa4, 0x43, 0x6f, 0x08, 0x8a, 0x94, 0x61, 0x71, 0x7a, 0x6c, + 0x74, 0x4d, 0x60, 0xb3, 0x0c, 0x36, 0x3a, 0x30, 0xf2, 0xb8, 0xe6, 0x49, + 0x49, 0x1c, 0x87, 0xa5, 0xde, 0x35, 0x22, 0x84, 0x58, 0x89, 0xc5, 0xd0, + 0x8b, 0xbc, 0x1a, 0x52, 0x00, 0x2c, 0x66, 0x9a, 0x77, 0xa4, 0x6f, 0x6d, + 0xac, 0xa3, 0xfa, 0x07, 0x5e, 0x71, 0xec, 0xb0, 0x33, 0xb7, 0x99, 0x94, + 0x33, 0x49, 0x2b, 0x51, 0x5e, 0x67, 0xd9, 0x0d, 0x52, 0x3e, 0xbf, 0x8f, + 0xe6, 0x42, 0xe4, 0x70, 0x94, 0xe6, 0x07, 0x2c, 0x3a, 0x47, 0x3d, 0x74, + 0x50, 0x16, 0x37, 0x15, 0x79, 0xd9, 0xa5, 0x53, 0x3d, 0x2d, 0x95, 0xc4, + 0xd5, 0xda, 0x14, 0x44, 0x14, 0x61, 0x08, 0x1c, 0xd5, 0xf3, 0x86, 0x93, + 0x82, 0x6c, 0x8b, 0xe4, 0xe4, 0xee, 0x47, 0x41, 0x1b, 0xba, 0xa8, 0x6d, + 0xeb, 0xb7, 0x56, 0x79, 0x8c, 0x7b, 0xab, 0xf2, 0xb4, 0xb5, 0x7c, 0xf7, + 0x25, 0xdf, 0x3a, 0x96, 0xde, 0x40, 0x27, 0xb9, 0x3e, 0x3c, 0x04, 0xbf, + 0x60, 0xd8, 0xb3, 0xf8, 0x47, 0xef, 0xd7, 0x34, 0x14, 0x1c, 0x7e, 0x9f, + 0xc1, 0xa1, 0x99, 0x60, 0x2d, 0xe3, 0x21, 0x16, 0x04, 0x17, 0xa0, 0xd6, + 0xef, 0xb4, 0x9d, 0x5a, 0xca, 0xa4, 0x7d, 0xc8, 0xa7, 0x8b, 0xa9, 0x43, + 0x03, 0xb3, 0xd7, 0x50, 0x33, 0x18, 0xc0, 0xd8, 0xb0, 0x4c, 0x97, 0xdc, + 0x33, 0x5c, 0x87, 0x1a, 0xad, 0xb0, 0x16, 0xca, 0x38, 0x2b, 0x42, 0x36, + 0x99, 0x06, 0x1b, 0x94, 0xc5, 0x7c, 0xae, 0x16, 0x89, 0x25, 0xbc, 0x47, + 0x87, 0xba, 0x48, 0x7c, 0x6b, 0x72, 0x1b, 0xbb, 0x5b, 0xe1, 0x85, 0x5f, + 0x25, 0x36, 0x47, 0xd7, 0x39, 0xcc, 0x04, 0xb7, 0xaa, 0x35, 0xea, 0x48, + 0xe2, 0xe8, 0xc5, 0x7a, 0x4e, 0xe4, 0x40, 0x9f, 0x92, 0x45, 0x1a, 0xc3, + 0xe6, 0xff, 0xf3, 0x87, 0xf3, 0x67, 0xdb, 0x24, 0xd7, 0xe1, 0x5f, 0x62, + 0x29, 0xe7, 0x86, 0xbe, 0xfb, 0x96, 0x8c, 0xa7, 0xbb, 0x8f, 0xf7, 0xbe, + 0xf9, 0xa6, 0x9b, 0x9c, 0x17, 0x93, 0xb4, 0x84, 0xc6, 0x76, 0x77, 0xfb, + 0xa0, 0x61, 0xd0, 0xf2, 0xc2, 0x45, 0x8d, 0x56, 0x9a, 0xc3, 0x93, 0xbf, + 0xc0, 0x07, 0x2f, 0xce, 0x7a, 0x6f, 0xff, 0x42, 0x1f, 0x4f, 0xc9, 0x69, + 0xbb, 0x1c, 0x65, 0xb7, 0x54, 0xd7, 0x87, 0x28, 0x25, 0xac, 0x6b, 0xc3, + 0x60, 0x86, 0xd0, 0xfd, 0x33, 0x87, 0xf5, 0x40, 0xe7, 0x49, 0x23, 0x32, + 0x14, 0x6b, 0x19, 0x8f, 0xf3, 0x37, 0x9a, 0x9d, 0x1c, 0xef, 0x6c, 0x08, + 0x62, 0x59, 0x5f, 0x93, 0x5b, 0xcb, 0x66, 0x17, 0x77, 0xb3, 0xff, 0x69, + 0x86, 0xbb, 0x78, 0xef, 0x42, 0x92, 0x81, 0x7d, 0xde, 0x42, 0xaf, 0xf4, + 0xe4, 0x53, 0x81, 0x0f, 0x6f, 0x10, 0x2c, 0xe7, 0xb7, 0xa6, 0x71, 0x1c, + 0x19, 0xbb, 0x00, 0x50, 0x60, 0x28, 0x33, 0x2a, 0x06, 0x98, 0x8f, 0xa8, + 0xd8, 0xa7, 0xc4, 0x0a, 0xc8, 0xbd, 0xcb, 0x0d, 0x2d, 0xd1, 0xb7, 0xb8, + 0x8c, 0xb9, 0x61, 0xb5, 0x13, 0xbb, 0xb4, 0xda, 0xf0, 0x82, 0xbc, 0xd1, + 0x37, 0x04, 0x59, 0x22, 0xba, 0x80, 0x8c, 0x1d, 0x90, 0xfd, 0x98, 0xfa, + 0xc4, 0xe3, 0x82, 0x12, 0x52, 0x75, 0x0b, 0x82, 0xcc, 0xb4, 0x92, 0x90, + 0x79, 0xa9, 0x87, 0x2a, 0x6c, 0xa5, 0x03, 0x27, 0xec, 0xdd, 0x1f, 0x8f, + 0x8f, 0xcf, 0x4e, 0x9e, 0xbd, 0x3c, 0x16, 0x1c, 0x27, 0xfb, 0xe8, 0xf5, + 0xc5, 0x9f, 0x5f, 0x76, 0x10, 0x94, 0x67, 0xf8, 0x3e, 0x53, 0x18, 0x8b, + 0x2a, 0xd9, 0x44, 0x23, 0x04, 0xb5, 0xc2, 0x04, 0xce, 0x0d, 0x79, 0x1a, + 0x17, 0x0a, 0x07, 0x82, 0x15, 0x82, 0xee, 0x2a, 0x8e, 0x2a, 0xd1, 0x32, + 0x13, 0x33, 0xd3, 0x32, 0x7f, 0x81, 0xd4, 0xbc, 0x25, 0x53, 0xfb, 0x63, + 0x93, 0x56, 0x13, 0xcd, 0xe3, 0x41, 0x66, 0x90, 0x30, 0x52, 0x3c, 0xa9, + 0x44, 0x59, 0x4d, 0x75, 0x30, 0xcb, 0xe2, 0x3d, 0x79, 0x62, 0x6a, 0x16, + 0xee, 0x2d, 0x70, 0x90, 0xf6, 0x21, 0xec, 0x94, 0x22, 0x02, 0x3b, 0xa4, + 0x78, 0xaa, 0x13, 0x0e, 0x1d, 0x2c, 0xad, 0x72, 0x2c, 0x3a, 0x8d, 0xb2, + 0x21, 0xce, 0x62, 0x89, 0xa9, 0x30, 0xd7, 0xa7, 0x7d, 0x00, 0x8d, 0x6d, + 0xc4, 0x40, 0x8c, 0x02, 0x98, 0xc3, 0x62, 0xf6, 0x74, 0xca, 0xfa, 0xe4, + 0x13, 0xb9, 0x30, 0xc3, 0x22, 0x6d, 0xc3, 0x1a, 0x6c, 0x75, 0x93, 0x6f, + 0x92, 0x4d, 0x5a, 0x44, 0xfa, 0x13, 0xc5, 0xe3, 0x47, 0xdb, 0xbb, 0x3b, + 0xc9, 0xa6, 0x2c, 0xe0, 0x56, 0x57, 0x08, 0x84, 0xc2, 0x5a, 0x68, 0xdc, + 0x8a, 0xb3, 0x42, 0x62, 0x16, 0x56, 0x84, 0xba, 0xe4, 0x90, 0x8f, 0xc8, + 0x34, 0x2c, 0xa9, 0xad, 0x72, 0x8e, 0x3b, 0xd1, 0x59, 0xea, 0x08, 0xc6, + 0x62, 0xa4, 0x1c, 0xdc, 0x51, 0x17, 0xec, 0x5e, 0xfe, 0x11, 0x33, 0x10, + 0x8d, 0xed, 0x31, 0xd6, 0x18, 0x71, 0x91, 0x24, 0x79, 0xbc, 0x43, 0xb7, + 0xab, 0x82, 0xf3, 0x43, 0x03, 0x7a, 0x4f, 0x36, 0x8e, 0xe0, 0x1d, 0xd6, + 0xa1, 0xdf, 0x68, 0x1e, 0x6a, 0x74, 0xb4, 0xb7, 0x26, 0xe0, 0xba, 0x5f, + 0x86, 0xee, 0x12, 0x87, 0x52, 0x23, 0xd1, 0x07, 0xbd, 0x26, 0x74, 0x52, + 0xb7, 0xc9, 0x53, 0xf8, 0xf1, 0x9d, 0x0f, 0xce, 0x3a, 0x7f, 0xb1, 0x85, + 0xb9, 0x2e, 0xd7, 0x18, 0x93, 0x83, 0x0f, 0xa8, 0xda, 0xd4, 0xd7, 0x22, + 0x3f, 0x02, 0x18, 0x29, 0xf3, 0x67, 0x48, 0x4a, 0xcc, 0x43, 0xba, 0xb6, + 0x02, 0xf7, 0xf8, 0x1a, 0x45, 0xb5, 0x90, 0x0f, 0x54, 0xa2, 0xee, 0x05, + 0x66, 0x8e, 0x62, 0x6d, 0xce, 0x5f, 0x74, 0xc9, 0x82, 0x8f, 0xe6, 0x11, + 0xb7, 0x3d, 0xec, 0x20, 0xa8, 0x03, 0x9e, 0x3a, 0xef, 0x96, 0x07, 0xcc, + 0x22, 0xea, 0x1a, 0xe5, 0x23, 0x4a, 0x39, 0x94, 0xc4, 0x22, 0x01, 0x27, + 0x3f, 0xa0, 0x65, 0x44, 0x87, 0x40, 0x55, 0x5d, 0x6d, 0xe7, 0xa3, 0x77, + 0x65, 0x95, 0x1a, 0x12, 0x5c, 0xf8, 0x74, 0x84, 0x9f, 0x26, 0x9d, 0xbe, + 0x3d, 0x21, 0xbf, 0xe3, 0xe7, 0x2d, 0x98, 0x07, 0x1c, 0xcf, 0xa7, 0x85, + 0x00, 0x4e, 0xe1, 0x14, 0x9d, 0x9f, 0xbf, 0x44, 0xcf, 0x78, 0x99, 0x62, + 0xd8, 0x8d, 0xb2, 0xc8, 0x6c, 0x76, 0x49, 0x66, 0xe6, 0xf9, 0xfb, 0x61, + 0xb5, 0xbb, 0x6b, 0xfb, 0x6d, 0x1e, 0x02, 0x2b, 0xd3, 0x70, 0xf6, 0xc7, + 0xa3, 0xf3, 0xdf, 0xc1, 0x13, 0x6f, 0xdf, 0x9c, 0x24, 0x9b, 0x58, 0xd4, + 0x20, 0xf9, 0xfa, 0xd1, 0xee, 0xde, 0x56, 0xa4, 0x9b, 0x44, 0xbe, 0x60, + 0xbd, 0xc1, 0xc2, 0x8e, 0x10, 0xcc, 0x19, 0xdf, 0x2a, 0xae, 0x41, 0xf6, + 0x04, 0xa3, 0x88, 0xad, 0xe0, 0x25, 0x01, 0x66, 0xda, 0x45, 0x78, 0x77, + 0x78, 0x84, 0x07, 0x1d, 0x41, 0x38, 0x92, 0x3a, 0x26, 0x06, 0x67, 0xef, + 0xc6, 0xc7, 0x97, 0x6a, 0xfc, 0xd9, 0xf2, 0x9d, 0x2a, 0x33, 0xc3, 0x45, + 0xe8, 0xf5, 0x64, 0x19, 0x9c, 0xe2, 0x80, 0x87, 0x00, 0x5a, 0x96, 0x6e, + 0x3b, 0xbc, 0xeb, 0xb8, 0x52, 0x37, 0x69, 0xf3, 0x72, 0x26, 0xce, 0xc4, + 0xed, 0xc0, 0x34, 0x7b, 0x35, 0xf9, 0x46, 0xe3, 0x96, 0xa8, 0xa9, 0xe3, + 0xd7, 0x3f, 0x76, 0x92, 0x3b, 0x1a, 0x6a, 0xd9, 0xc5, 0xc6, 0x36, 0xc2, + 0xc9, 0xa1, 0x78, 0x19, 0xc2, 0xd7, 0xe3, 0x0a, 0xda, 0x40, 0xc3, 0xe7, + 0x52, 0xc3, 0xce, 0xf2, 0xc9, 0x96, 0x73, 0x04, 0x38, 0x4a, 0x52, 0x62, + 0xf7, 0xf0, 0xb8, 0xb8, 0xf0, 0xbd, 0x4d, 0xc9, 0x14, 0xcd, 0xea, 0xe1, + 0x16, 0x4a, 0x74, 0x88, 0x15, 0x6c, 0xf0, 0x29, 0x6a, 0x00, 0x24, 0x23, + 0x3e, 0xeb, 0xc1, 0xbc, 0xa1, 0xb4, 0xa3, 0xec, 0xed, 0xb0, 0xc2, 0xba, + 0x1a, 0x0a, 0xa7, 0xa1, 0x61, 0xf0, 0x08, 0x0c, 0x0d, 0xb7, 0x5b, 0xcd, + 0x26, 0xbc, 0x23, 0x7b, 0x62, 0x52, 0xf0, 0x28, 0x35, 0x8c, 0x42, 0x1a, + 0xe2, 0xea, 0xfa, 0x02, 0xb8, 0x8e, 0xdd, 0x7c, 0x39, 0xb8, 0x16, 0x8a, + 0x1f, 0xf2, 0xd1, 0x7c, 0xdc, 0x21, 0x59, 0x89, 0xd6, 0xe2, 0x5f, 0xb6, + 0xe1, 0x22, 0xb4, 0x67, 0xae, 0x48, 0xaa, 0x7d, 0xf7, 0x14, 0x7f, 0x3a, + 0x66, 0x45, 0x90, 0x05, 0x6e, 0x19, 0x65, 0x39, 0xf0, 0xa9, 0x7e, 0x40, + 0xeb, 0x30, 0x64, 0x4c, 0x6c, 0x42, 0xd8, 0x15, 0x35, 0xda, 0x20, 0x3f, + 0x7f, 0xc4, 0xc8, 0x94, 0xf9, 0xec, 0xf8, 0x4d, 0x37, 0x39, 0x3b, 0x7e, + 0x25, 0xf2, 0x01, 0x90, 0x1d, 0xe3, 0x19, 0xaa, 0x24, 0xcd, 0x4b, 0x3b, + 0x8b, 0xfd, 0x9f, 0xc4, 0xc8, 0xe0, 0x25, 0x5e, 0xec, 0xb4, 0xaa, 0x16, + 0x53, 0x52, 0xe9, 0x6c, 0x17, 0x78, 0x2a, 0x5f, 0x10, 0xee, 0xde, 0xfa, + 0x80, 0xf1, 0x7f, 0xca, 0x3e, 0x84, 0x75, 0x2f, 0x07, 0xc9, 0x53, 0x82, + 0x57, 0x8e, 0xaa, 0x09, 0x0a, 0xe6, 0xcd, 0x1f, 0xb3, 0x12, 0x6e, 0xfc, + 0xa2, 0x4a, 0x1a, 0xe5, 0xde, 0x2c, 0x14, 0x4f, 0x12, 0x97, 0xa8, 0x81, + 0x06, 0xcc, 0x2d, 0x05, 0x80, 0xc9, 0x89, 0x77, 0x68, 0x58, 0x8a, 0x86, + 0xbc, 0x41, 0x95, 0xe6, 0x36, 0xba, 0xc9, 0x06, 0xe2, 0xaa, 0xe2, 0xbf, + 0x54, 0x30, 0x68, 0xc4, 0x8e, 0xb6, 0x8d, 0x6e, 0x38, 0x07, 0x1b, 0xb2, + 0x69, 0x1b, 0x20, 0x59, 0x4b, 0x3b, 0x64, 0xac, 0x23, 0x9f, 0x75, 0x2a, + 0x7d, 0x07, 0x18, 0x1d, 0x32, 0xc7, 0x13, 0xd3, 0x10, 0x74, 0xad, 0x4a, + 0x2d, 0x59, 0xd6, 0x50, 0x28, 0x2b, 0x2f, 0x1a, 0x05, 0x2c, 0x42, 0xeb, + 0x75, 0xef, 0xb7, 0x89, 0xf6, 0x49, 0x0f, 0xd4, 0xc7, 0x6d, 0x16, 0x34, + 0xcf, 0x75, 0xf5, 0x56, 0xe2, 0x15, 0xf1, 0x43, 0xed, 0xb9, 0x95, 0x3e, + 0xb5, 0x52, 0xe3, 0xa3, 0x74, 0x63, 0x5c, 0x6a, 0xb3, 0x99, 0x50, 0x32, + 0xac, 0x3d, 0x65, 0xbb, 0x14, 0x55, 0x96, 0xeb, 0x69, 0x9b, 0x4f, 0x1d, + 0x64, 0xf9, 0x21, 0xd7, 0xb5, 0xf6, 0x32, 0x18, 0xf9, 0x23, 0x6e, 0xe9, + 0xce, 0x65, 0x23, 0x0d, 0x17, 0xc1, 0x71, 0xb6, 0x33, 0x3e, 0x2f, 0xb4, + 0x0f, 0xa6, 0x0c, 0x4b, 0xe3, 0x3d, 0xf6, 0x39, 0x1e, 0xa1, 0xd8, 0x8e, + 0xd1, 0xbb, 0x09, 0x95, 0x94, 0x0b, 0xf5, 0x4f, 0x34, 0x47, 0x89, 0x0e, + 0x32, 0x6f, 0x1b, 0xbb, 0x49, 0x4d, 0x25, 0xc0, 0x65, 0x80, 0xf5, 0x25, + 0xd8, 0xe6, 0xb1, 0xa1, 0x43, 0x97, 0x3a, 0x80, 0x9e, 0x60, 0xcc, 0x69, + 0x40, 0x17, 0xbe, 0xfd, 0x3f, 0xda, 0xbd, 0x04, 0x0a, 0x20, 0x6e, 0x45, + 0x2a, 0x91, 0x3a, 0xbc, 0xf7, 0x39, 0x98, 0xf5, 0xc9, 0x04, 0x1f, 0x8a, + 0xaa, 0x20, 0x75, 0x15, 0x24, 0x7c, 0x66, 0x1f, 0x6a, 0x25, 0x14, 0x9f, + 0x77, 0xf2, 0x85, 0x88, 0xc5, 0x2a, 0x0e, 0x51, 0x31, 0x87, 0xfe, 0x70, + 0xbd, 0x23, 0xdd, 0x04, 0xb9, 0xa3, 0xfa, 0x28, 0x3d, 0x92, 0xc9, 0x9e, + 0xc2, 0x14, 0xb3, 0xd1, 0x77, 0x31, 0xba, 0x91, 0x37, 0x7e, 0x58, 0xc8, + 0x2f, 0x3d, 0x6e, 0x76, 0x70, 0x33, 0x81, 0x93, 0x79, 0x99, 0x97, 0x27, + 0xd4, 0xd4, 0x0a, 0xb5, 0xa0, 0x99, 0x15, 0x90, 0x01, 0xb0, 0xb2, 0x40, + 0x43, 0xab, 0x5c, 0xc0, 0x73, 0xa6, 0x9a, 0x12, 0xb9, 0x86, 0x76, 0x72, + 0x7c, 0x5a, 0xaa, 0x44, 0xc3, 0x95, 0x5c, 0xe6, 0xf9, 0x5c, 0xe2, 0x18, + 0x79, 0x04, 0x1c, 0x35, 0x41, 0x58, 0xb0, 0xb4, 0xf7, 0x36, 0x4a, 0x3e, + 0xe0, 0x1a, 0xb3, 0x82, 0xdf, 0x19, 0xbf, 0xc1, 0x02, 0x97, 0x03, 0x68, + 0xe2, 0x26, 0x1f, 0xd5, 0x57, 0xc0, 0x9a, 0x04, 0xf1, 0x3c, 0xaf, 0x29, + 0x49, 0x53, 0xb3, 0x4e, 0xe0, 0xcf, 0x66, 0x45, 0xc2, 0x41, 0xe6, 0xad, + 0xd2, 0x6c, 0x23, 0xa4, 0x65, 0xe3, 0xc2, 0x5a, 0x59, 0x8a, 0x28, 0xda, + 0x6c, 0xd2, 0xa4, 0x6c, 0x95, 0x6d, 0xd6, 0x1f, 0xba, 0x06, 0xb6, 0x97, + 0xc2, 0xc9, 0x1c, 0x8f, 0xf3, 0x0f, 0x41, 0x74, 0xd2, 0x4a, 0x82, 0x7d, + 0x39, 0x5f, 0x78, 0x24, 0x36, 0xde, 0x6f, 0xa0, 0x10, 0xb2, 0xf1, 0xc7, + 0x0d, 0xf4, 0xbb, 0xcf, 0xa4, 0x60, 0xab, 0xa8, 0x83, 0x20, 0xf5, 0xbc, + 0xcf, 0x81, 0x5c, 0xb1, 0x7d, 0xe0, 0x7e, 0x1b, 0xd3, 0x0d, 0x4b, 0x0a, + 0xde, 0x78, 0xb5, 0x61, 0xb9, 0x11, 0x35, 0x0c, 0x47, 0x72, 0x66, 0x28, + 0x07, 0x07, 0x2f, 0xc3, 0x8d, 0x4b, 0x6a, 0x37, 0xd9, 0xf8, 0x71, 0x23, + 0x98, 0x30, 0x7d, 0x6e, 0x8d, 0x4d, 0x8d, 0x47, 0x09, 0x0f, 0x6c, 0xbe, + 0x87, 0x3e, 0xe0, 0xd6, 0xfb, 0x11, 0x43, 0xa5, 0xe0, 0x32, 0xdb, 0x62, + 0x73, 0xe2, 0xee, 0xce, 0xde, 0x43, 0x58, 0x42, 0xe2, 0x8d, 0x94, 0xbf, + 0xa7, 0xee, 0xcc, 0xdd, 0xf7, 0x61, 0x6a, 0xf8, 0x50, 0x3f, 0x98, 0xcd, + 0xb1, 0x0c, 0xd6, 0x1f, 0xbb, 0xc9, 0xfe, 0x94, 0x76, 0x6f, 0xf7, 0xc7, + 0xb8, 0x2c, 0x18, 0x90, 0x14, 0x6d, 0x31, 0xce, 0x1f, 0x8b, 0x8c, 0x0e, + 0xd5, 0x05, 0x86, 0xfc, 0x09, 0x0f, 0xce, 0xa5, 0x89, 0x34, 0xb6, 0xc5, + 0xb2, 0xf4, 0x9a, 0x5f, 0x0d, 0xda, 0xe0, 0x94, 0x53, 0x3e, 0x04, 0xb3, + 0x97, 0xab, 0x00, 0x02, 0xa3, 0xc4, 0xe0, 0x1f, 0x46, 0xf0, 0x48, 0x31, + 0x65, 0x36, 0x2f, 0x08, 0x0b, 0xdf, 0x4c, 0x9b, 0xaa, 0xe5, 0x35, 0xbc, + 0x4c, 0x6c, 0x85, 0x0e, 0x95, 0xbb, 0x81, 0x45, 0x62, 0x87, 0x7c, 0x68, + 0x02, 0xce, 0xa7, 0x56, 0xaf, 0x14, 0xe9, 0x94, 0x72, 0x4c, 0x0c, 0xff, + 0x67, 0x98, 0x8d, 0x08, 0xd1, 0x9a, 0x2c, 0x61, 0x1c, 0x86, 0x32, 0x2c, + 0xf3, 0x39, 0x19, 0x54, 0x65, 0xde, 0x3d, 0x9b, 0xb7, 0x64, 0x17, 0x4f, + 0x40, 0x97, 0x40, 0x15, 0x34, 0xa0, 0x95, 0xa2, 0x06, 0xa7, 0x0a, 0xb3, + 0x1f, 0x03, 0x2f, 0x14, 0xae, 0x13, 0xa1, 0x74, 0x09, 0xef, 0xb1, 0x23, + 0xfd, 0xf9, 0x44, 0xbc, 0x6a, 0x89, 0xfb, 0x58, 0x27, 0xbb, 0xb0, 0xab, + 0xf7, 0x7b, 0x1c, 0xe2, 0x17, 0x76, 0x3e, 0xf2, 0x85, 0x57, 0xeb, 0x71, + 0x37, 0x7c, 0xba, 0xdb, 0xd8, 0x26, 0xb9, 0xdb, 0xe8, 0x13, 0xaf, 0xf0, + 0x4e, 0xba, 0xd4, 0x49, 0x55, 0xfb, 0xd4, 0x59, 0xcc, 0xfb, 0x38, 0x3b, + 0x3d, 0xdb, 0x4f, 0x24, 0x05, 0x44, 0xaa, 0xb0, 0x70, 0xfa, 0x8e, 0x54, + 0xbd, 0x27, 0x0f, 0x3c, 0x7d, 0xeb, 0x33, 0x2e, 0x80, 0xed, 0x0d, 0x03, + 0xb3, 0x42, 0x1d, 0x99, 0x1d, 0xf4, 0xd7, 0x79, 0x86, 0x49, 0xfa, 0xaf, + 0xd2, 0xdb, 0x41, 0x16, 0xe7, 0xcf, 0x29, 0xbf, 0xd3, 0xe0, 0x37, 0xce, + 0x5c, 0x45, 0x8e, 0x5a, 0x05, 0x92, 0x9e, 0xc2, 0x3d, 0x03, 0x97, 0x58, + 0x0f, 0xde, 0x94, 0x08, 0xf6, 0x80, 0xe8, 0x06, 0x14, 0xac, 0x43, 0x71, + 0xc9, 0x21, 0x0c, 0x18, 0x46, 0xf4, 0xea, 0xeb, 0x4c, 0x86, 0x27, 0x70, + 0x44, 0x2e, 0x36, 0x1b, 0xc9, 0x3b, 0x75, 0x48, 0x1e, 0x14, 0x80, 0x56, + 0x10, 0x46, 0xfc, 0x34, 0xd5, 0xb2, 0x2f, 0x2e, 0x9b, 0x82, 0x58, 0x2d, + 0xca, 0x00, 0xb1, 0x09, 0x76, 0x98, 0x32, 0xe6, 0x28, 0x8c, 0xe8, 0xf5, + 0x4b, 0x2c, 0x9c, 0xea, 0xf2, 0xee, 0x06, 0x6c, 0x5c, 0x34, 0xaf, 0xb7, + 0x77, 0x78, 0xfb, 0xda, 0x14, 0x2f, 0x4f, 0xce, 0x2f, 0x94, 0xee, 0xd0, + 0xf0, 0x73, 0x90, 0x9c, 0x63, 0xea, 0xcb, 0x73, 0x87, 0x97, 0x36, 0x11, + 0x90, 0x9d, 0xc9, 0xad, 0xa4, 0x09, 0xb2, 0x56, 0x94, 0x97, 0xc1, 0xbc, + 0x8e, 0x9d, 0xe0, 0x10, 0xfe, 0xe0, 0xea, 0x00, 0x8c, 0x0a, 0xa9, 0x65, + 0xcd, 0x35, 0x55, 0xaa, 0xc5, 0xa0, 0xa7, 0x0b, 0x92, 0x8b, 0x6d, 0xb3, + 0xba, 0x9d, 0x0e, 0x0a, 0x0c, 0x81, 0x03, 0xa1, 0xe1, 0x7d, 0x15, 0x65, + 0xb3, 0xe8, 0xc6, 0xe3, 0xe4, 0xce, 0x9b, 0x3b, 0xcf, 0x26, 0xaf, 0x8a, + 0x2b, 0x94, 0x12, 0x15, 0xb0, 0xcb, 0xde, 0x48, 0x40, 0xc2, 0x9e, 0x60, + 0xd5, 0xbb, 0x24, 0x6e, 0x62, 0x9d, 0x04, 0x14, 0x4c, 0xfa, 0x06, 0x5c, + 0x95, 0x49, 0x2e, 0x42, 0x48, 0xaa, 0x14, 0x50, 0x01, 0x4f, 0x12, 0xeb, + 0x53, 0x44, 0x63, 0x88, 0x6b, 0x52, 0x84, 0xf0, 0x89, 0x8a, 0x59, 0xa8, + 0x4f, 0x75, 0x21, 0x76, 0x4a, 0xd8, 0x84, 0x6a, 0xfe, 0x89, 0x97, 0xa7, + 0xcc, 0xd0, 0x4a, 0x73, 0x1d, 0x65, 0x7b, 0x00, 0xf7, 0xce, 0x08, 0xa2, + 0x9f, 0xdc, 0x69, 0x78, 0xa4, 0x34, 0x8d, 0xaa, 0xb9, 0x52, 0xdc, 0x10, + 0x6e, 0x7d, 0x83, 0x64, 0x0c, 0x71, 0xd1, 0x93, 0xc8, 0x9b, 0xe3, 0x8b, + 0x37, 0x61, 0xe1, 0xa2, 0x03, 0x65, 0xe2, 0x58, 0x73, 0x01, 0x75, 0xfd, + 0x80, 0x88, 0x32, 0x0e, 0xea, 0xb7, 0x41, 0x62, 0x65, 0x88, 0xf4, 0x32, + 0xeb, 0x61, 0xa6, 0xb8, 0xa0, 0x51, 0xfa, 0x64, 0x6e, 0x21, 0x51, 0xaa, + 0x27, 0x8e, 0x3c, 0x9e, 0x72, 0x45, 0x73, 0x44, 0x6e, 0x8a, 0xd2, 0x50, + 0x4f, 0x30, 0xb8, 0xb8, 0x69, 0x9a, 0x74, 0xb6, 0xc9, 0x5b, 0x36, 0x7b, + 0x44, 0x14, 0x47, 0x01, 0x98, 0x13, 0x8c, 0x23, 0xd4, 0x63, 0x55, 0xd5, + 0x9a, 0xff, 0x85, 0xa2, 0x84, 0x2b, 0x11, 0xce, 0x47, 0x81, 0xcf, 0xa1, + 0xa1, 0xc7, 0xab, 0xb3, 0xd5, 0x2a, 0xfd, 0x44, 0xae, 0xf1, 0x66, 0x3a, + 0x81, 0xab, 0x4c, 0x02, 0xa4, 0xf9, 0xf6, 0xe4, 0xd9, 0xcb, 0x70, 0x40, + 0x65, 0x75, 0x19, 0xd2, 0xde, 0x92, 0xcf, 0x38, 0xf2, 0x28, 0xdc, 0x7d, + 0xb4, 0x9b, 0x9a, 0x91, 0xb6, 0x98, 0xe5, 0x7f, 0xc7, 0xab, 0x82, 0x94, + 0xb0, 0x71, 0xce, 0x22, 0xe1, 0x55, 0x90, 0x9b, 0xaa, 0xc4, 0xaf, 0xac, + 0x16, 0x94, 0xf1, 0xe1, 0x8c, 0x2d, 0x79, 0xe3, 0xc6, 0x8b, 0x57, 0x15, + 0xe2, 0xfe, 0x48, 0x9f, 0xa3, 0xb5, 0x77, 0x9f, 0x1c, 0xad, 0xdd, 0x2e, + 0x2b, 0x5d, 0xb0, 0x63, 0x2d, 0x98, 0xc2, 0x7f, 0x5f, 0x60, 0x18, 0x68, + 0x6b, 0xe9, 0x62, 0xaa, 0x3a, 0x30, 0xe9, 0x91, 0xea, 0xf5, 0x94, 0xaa, + 0xfe, 0x39, 0xbf, 0x4c, 0xea, 0x01, 0x01, 0x35, 0xb4, 0x44, 0x3d, 0x8a, + 0xa5, 0x56, 0x09, 0xdc, 0x7c, 0xfe, 0xe6, 0xf4, 0x55, 0xef, 0xe2, 0x74, + 0x8b, 0x8e, 0x33, 0x87, 0x20, 0x27, 0x01, 0x25, 0x47, 0x6b, 0x31, 0xfa, + 0x58, 0x6c, 0x36, 0xf3, 0x98, 0xb1, 0x7f, 0xb3, 0xda, 0xf2, 0x45, 0x88, + 0xe9, 0xe5, 0x50, 0xc3, 0x51, 0xc3, 0xc3, 0x66, 0x2c, 0x78, 0x23, 0x21, + 0x62, 0x80, 0xd1, 0x30, 0xc5, 0xfb, 0x4b, 0x13, 0x29, 0xa5, 0xbc, 0x41, + 0x5d, 0x87, 0x00, 0x6e, 0x1e, 0x1d, 0x65, 0xcf, 0x17, 0x88, 0xa0, 0x60, + 0x9e, 0xa2, 0xba, 0x00, 0xe6, 0x9a, 0x96, 0x65, 0x71, 0x63, 0x02, 0x0e, + 0xde, 0x05, 0x40, 0x24, 0xa1, 0x0c, 0xa0, 0xf7, 0x44, 0x40, 0xb3, 0x58, + 0x83, 0x05, 0xc8, 0x09, 0xfa, 0x67, 0x28, 0x61, 0x5f, 0xb3, 0x41, 0x56, + 0xaf, 0xd5, 0x24, 0x12, 0x99, 0xd5, 0x9b, 0x61, 0xf6, 0x1f, 0x63, 0x58, + 0x77, 0x1d, 0xa1, 0x34, 0xd2, 0xdb, 0xdf, 0x59, 0xb7, 0x98, 0x69, 0x28, + 0x81, 0x4c, 0x43, 0x7e, 0xd9, 0x75, 0xa5, 0x26, 0x62, 0xfc, 0x8d, 0xb1, + 0x67, 0x21, 0x92, 0xfd, 0xee, 0x62, 0x9c, 0x84, 0x72, 0x50, 0xa3, 0xa1, + 0x32, 0x04, 0x29, 0x1e, 0xfa, 0x6b, 0x7f, 0x5c, 0x53, 0xe0, 0x18, 0x84, + 0x1c, 0x35, 0xab, 0x13, 0xed, 0x22, 0xd9, 0x0c, 0xe5, 0x31, 0x15, 0x8c, + 0xe1, 0xa5, 0x7c, 0x77, 0x60, 0xa5, 0x05, 0xf9, 0x98, 0xef, 0xff, 0xe5, + 0x2f, 0x1a, 0x11, 0x24, 0x57, 0x23, 0x2a, 0xd8, 0x5b, 0xdd, 0x96, 0x8c, + 0x4e, 0xc9, 0xbf, 0x1a, 0x15, 0x7e, 0x68, 0x16, 0xf2, 0x33, 0xcb, 0xa4, + 0x70, 0x96, 0x24, 0x4e, 0x9f, 0x48, 0xd1, 0x47, 0x18, 0x29, 0xe8, 0xf4, + 0x54, 0x31, 0x43, 0xd9, 0x11, 0xd6, 0x09, 0xe8, 0x69, 0xb4, 0x0e, 0x97, + 0x8c, 0x97, 0x92, 0xea, 0xf2, 0xa1, 0x84, 0x5f, 0x09, 0x18, 0x6d, 0x63, + 0x15, 0x98, 0x2f, 0x62, 0x1b, 0xb3, 0x18, 0xd3, 0x27, 0x36, 0x2a, 0xa9, + 0x8c, 0xca, 0xd1, 0xff, 0xec, 0x6d, 0x17, 0x37, 0x3f, 0x8f, 0xa3, 0xd3, + 0x7b, 0x81, 0xe1, 0xc4, 0xf8, 0x89, 0xd5, 0x7f, 0x61, 0x3f, 0xd3, 0x8c, + 0x0a, 0x4e, 0x61, 0xac, 0x1e, 0x72, 0xa9, 0x61, 0x99, 0x89, 0x1d, 0xa9, + 0x52, 0x6b, 0x43, 0x3e, 0xcb, 0xf1, 0x6f, 0x0a, 0xde, 0xe4, 0x99, 0xa6, + 0x56, 0x98, 0x43, 0xe8, 0x3d, 0xac, 0x18, 0xa1, 0xfb, 0xba, 0x5d, 0x92, + 0xd2, 0x20, 0x11, 0x24, 0xc7, 0xa5, 0x7a, 0x64, 0x5d, 0x67, 0x8a, 0xa6, + 0x80, 0x19, 0x7d, 0x33, 0x36, 0xcd, 0x04, 0x2a, 0xea, 0x69, 0xa4, 0x33, + 0x5e, 0x24, 0x08, 0x3e, 0x52, 0x88, 0xf7, 0x8c, 0xa3, 0x2a, 0x65, 0x5d, + 0x5e, 0x92, 0x70, 0x4b, 0x31, 0x57, 0x53, 0x54, 0x11, 0x91, 0x59, 0xb8, + 0x6a, 0x29, 0x88, 0x76, 0x40, 0x8e, 0x12, 0xf4, 0xb8, 0x39, 0x0c, 0x14, + 0x76, 0xfc, 0xd0, 0x83, 0xad, 0xe5, 0x6c, 0x42, 0x84, 0x8c, 0xbc, 0x5f, + 0x71, 0x64, 0x3e, 0x37, 0x2c, 0xfe, 0xc2, 0x71, 0x1c, 0x99, 0x4e, 0xb6, + 0x4d, 0x0a, 0x6f, 0xa4, 0xb9, 0x87, 0xbb, 0xa6, 0x6a, 0xa4, 0x5c, 0x2e, + 0xd5, 0xa0, 0xf9, 0xf1, 0xf8, 0xc2, 0xc4, 0x5f, 0xc1, 0xc3, 0x13, 0x4a, + 0x0d, 0x86, 0xfc, 0xfd, 0x9d, 0x5d, 0xd0, 0x19, 0x77, 0xf6, 0x28, 0x24, + 0x0f, 0x7e, 0xd9, 0xef, 0x5b, 0x16, 0x66, 0x78, 0x9a, 0x2c, 0x47, 0x08, + 0xb9, 0xc0, 0xd6, 0x28, 0xa2, 0xc9, 0xfd, 0x0f, 0x1f, 0xf8, 0x0b, 0x4f, + 0x00, 0x64, 0x4c, 0x1f, 0x69, 0xd1, 0x8d, 0x96, 0xa1, 0x69, 0x20, 0xbc, + 0x85, 0xeb, 0xe0, 0x6d, 0xa7, 0x30, 0xd8, 0x22, 0x81, 0x11, 0x7e, 0x8c, + 0x2f, 0x00, 0x84, 0xd7, 0x6d, 0x8d, 0x05, 0xca, 0xc4, 0x69, 0xc5, 0xd2, + 0xa6, 0xec, 0x9a, 0x8f, 0xfb, 0xe4, 0x9d, 0xc1, 0x69, 0x73, 0x81, 0x1b, + 0x3c, 0xa5, 0x3b, 0x1f, 0x1a, 0xa7, 0x74, 0x70, 0x1b, 0x8f, 0x02, 0x38, + 0xa0, 0x9c, 0x78, 0x73, 0x6c, 0x6b, 0x81, 0x92, 0xb4, 0x3e, 0xa0, 0xc2, + 0x43, 0x40, 0x77, 0xb8, 0x4e, 0xca, 0x47, 0xf9, 0x6f, 0xc5, 0x09, 0xe1, + 0xbf, 0xf6, 0xbd, 0xba, 0xad, 0x10, 0x38, 0xc4, 0x3d, 0xe5, 0xca, 0xb4, + 0x15, 0x90, 0x50, 0x3a, 0xad, 0x20, 0xa0, 0xcf, 0xba, 0x72, 0x6f, 0xae, + 0x9c, 0x30, 0x19, 0x47, 0xaa, 0x6c, 0xa2, 0xd5, 0xd4, 0xc9, 0xd6, 0x1b, + 0x5d, 0xeb, 0xca, 0xb9, 0xda, 0xae, 0x75, 0xd3, 0xdb, 0xd7, 0x4e, 0x82, + 0xb6, 0xb2, 0x3e, 0x77, 0xf1, 0xf7, 0x97, 0x6b, 0xaa, 0x8b, 0x12, 0x3b, + 0xcd, 0xcb, 0x94, 0x4e, 0xea, 0x5e, 0x75, 0x3d, 0x8c, 0xae, 0x72, 0x7f, + 0x1e, 0x57, 0xa0, 0x2b, 0x05, 0x4e, 0x40, 0x9a, 0x91, 0x9f, 0xb0, 0x9c, + 0x40, 0xc6, 0x06, 0xb1, 0xc3, 0x29, 0xbb, 0x84, 0xe1, 0x41, 0x5c, 0x70, + 0x99, 0xad, 0x35, 0x56, 0x2f, 0x2a, 0xe2, 0x4a, 0x74, 0xe0, 0xa4, 0xac, + 0x58, 0x06, 0x5f, 0x50, 0x25, 0x24, 0xaa, 0xfd, 0x61, 0xd7, 0x04, 0x7f, + 0xcb, 0xc8, 0x02, 0x66, 0xf9, 0x50, 0x36, 0x86, 0x15, 0xfe, 0xbc, 0xc5, + 0x93, 0xc2, 0xc9, 0x0b, 0x8d, 0x2b, 0x67, 0x9d, 0xa8, 0x2e, 0x8b, 0xd1, + 0x82, 0x94, 0xd7, 0x84, 0xd3, 0xf5, 0x31, 0xcc, 0x7b, 0x50, 0x72, 0x19, + 0x38, 0x4b, 0xcd, 0xaa, 0xf2, 0xda, 0x72, 0x4a, 0x94, 0xcd, 0x88, 0xf7, + 0x37, 0xa5, 0x2f, 0x69, 0x06, 0xec, 0x5e, 0xa1, 0x92, 0x6f, 0x66, 0x2b, + 0x0e, 0x65, 0x92, 0x38, 0x58, 0x17, 0xe1, 0xba, 0xd9, 0xa0, 0x3c, 0x0b, + 0x63, 0x97, 0x7c, 0x11, 0x31, 0xa5, 0xa0, 0xd9, 0xb6, 0x94, 0x10, 0x54, + 0x60, 0x6c, 0x1a, 0x49, 0xdf, 0x75, 0x78, 0x92, 0xd5, 0xf0, 0x2a, 0xd3, + 0x60, 0x3a, 0x78, 0xd6, 0x09, 0x39, 0x1a, 0x6c, 0xd0, 0x86, 0xdd, 0x42, + 0x3b, 0xaf, 0x50, 0x03, 0xba, 0x73, 0xc4, 0x88, 0xb9, 0xa2, 0x8a, 0x46, + 0x9a, 0xd1, 0xc1, 0xc8, 0x3e, 0x60, 0xc0, 0x73, 0x6e, 0xb5, 0xd9, 0xa3, + 0xb8, 0xd2, 0x76, 0x2a, 0x37, 0xe6, 0xbd, 0x3e, 0x9c, 0xf3, 0x3a, 0xd4, + 0xae, 0xcd, 0xde, 0x67, 0x95, 0x69, 0x8e, 0xa2, 0xb7, 0x20, 0x61, 0xfe, + 0x00, 0x67, 0x78, 0x53, 0x94, 0x6b, 0x44, 0x86, 0x2e, 0x37, 0xf1, 0x02, + 0xa3, 0xc5, 0xe9, 0x2a, 0xd5, 0x58, 0xc3, 0x6f, 0xd3, 0xc1, 0xb0, 0x23, + 0x19, 0x67, 0x6b, 0x97, 0x68, 0x72, 0xe7, 0xea, 0x32, 0x9f, 0xf5, 0x94, + 0x93, 0x3d, 0x95, 0x5f, 0x2c, 0x01, 0x11, 0xeb, 0x8d, 0xbe, 0x7c, 0x06, + 0x3f, 0xd8, 0x10, 0xc3, 0xc5, 0x51, 0x83, 0xff, 0x8e, 0x2c, 0x56, 0xd8, + 0x42, 0x60, 0x86, 0x0a, 0x6d, 0x96, 0x8c, 0x16, 0xa5, 0x49, 0xa5, 0xaa, + 0xba, 0x45, 0x92, 0x43, 0x93, 0x67, 0xd3, 0x6b, 0x2d, 0xad, 0xa9, 0xc3, + 0xdd, 0x51, 0x9b, 0xa9, 0xb5, 0x51, 0xc1, 0x23, 0x22, 0x57, 0x3c, 0x4a, + 0xaa, 0x6b, 0xf1, 0x10, 0x9a, 0xdd, 0x26, 0x87, 0xb5, 0xf9, 0x71, 0x49, + 0x04, 0xc1, 0x59, 0x76, 0x79, 0x86, 0x21, 0xd7, 0x80, 0x4a, 0xac, 0x5a, + 0x62, 0x3b, 0x0f, 0x4b, 0x8b, 0xe9, 0xb0, 0x91, 0x75, 0x49, 0x35, 0x4f, + 0x07, 0x04, 0x66, 0x44, 0xcf, 0x46, 0xd1, 0xff, 0x28, 0xab, 0x51, 0x05, + 0x3e, 0x52, 0x7a, 0x13, 0x8a, 0x2d, 0xd8, 0xdb, 0x7f, 0x82, 0xa1, 0x7a, + 0xf4, 0xfb, 0xa3, 0x9d, 0x6f, 0xf6, 0x92, 0xe0, 0x64, 0x07, 0x21, 0xfc, + 0xf8, 0xe2, 0x39, 0xac, 0x60, 0x09, 0xf7, 0x52, 0x23, 0x9d, 0x0a, 0xce, + 0x2c, 0xd6, 0xb7, 0x7d, 0x0f, 0x5b, 0x98, 0x67, 0xf5, 0xb8, 0x5f, 0x94, + 0x97, 0x98, 0x63, 0xb5, 0x8d, 0x98, 0x29, 0xdb, 0xf4, 0x42, 0x2f, 0x4b, + 0xcb, 0x2b, 0xd0, 0xc4, 0x31, 0xd5, 0xbd, 0x57, 0x4d, 0xeb, 0x79, 0x6f, + 0x67, 0xa7, 0x81, 0xe3, 0xba, 0x47, 0x20, 0x79, 0xb4, 0xb9, 0x86, 0x3e, + 0xbb, 0xbc, 0x97, 0x49, 0xe7, 0xf0, 0xed, 0xc5, 0x8b, 0x6f, 0x7f, 0xff, + 0xf2, 0xf4, 0xc7, 0x93, 0xd7, 0x1d, 0xc9, 0xbb, 0xd3, 0x95, 0xb6, 0x43, + 0xdc, 0x75, 0xf0, 0x22, 0xec, 0x3e, 0x9f, 0xe0, 0xa9, 0xd9, 0x24, 0x73, + 0xd6, 0xf9, 0xe1, 0xf9, 0xcb, 0xad, 0xa4, 0x43, 0x2d, 0x50, 0x7f, 0x1d, + 0xd3, 0x74, 0xe5, 0xec, 0x49, 0x72, 0xbe, 0xd7, 0xef, 0x47, 0xd7, 0xe8, + 0xad, 0xa6, 0xf6, 0xf0, 0xfd, 0xa5, 0xed, 0x3b, 0x12, 0xb1, 0x54, 0x7c, + 0x93, 0x41, 0x0e, 0xa4, 0x52, 0x49, 0xcb, 0x38, 0x29, 0x5d, 0x8a, 0x4d, + 0xc8, 0x6b, 0x15, 0x83, 0x24, 0x2c, 0x46, 0x0f, 0x21, 0x19, 0xa2, 0x83, + 0x21, 0x2c, 0x40, 0x17, 0x24, 0x32, 0x15, 0xaa, 0xca, 0xa4, 0x00, 0x45, + 0xc1, 0x54, 0xc7, 0x70, 0x53, 0x2a, 0x7e, 0xd1, 0x62, 0x46, 0xb8, 0xbe, + 0x02, 0xef, 0x5f, 0xb9, 0x45, 0xe1, 0x85, 0xe8, 0x24, 0x9b, 0x59, 0xff, + 0xb2, 0xcf, 0x91, 0x3a, 0xb8, 0x00, 0x75, 0x18, 0x4c, 0x35, 0x2b, 0x0a, + 0xb4, 0x2d, 0x6f, 0x35, 0x34, 0x31, 0x7f, 0x48, 0xef, 0x4b, 0x78, 0xfe, + 0x0d, 0x21, 0x4e, 0x71, 0x47, 0x1b, 0xb4, 0xff, 0xff, 0xb9, 0x91, 0xe4, + 0xd3, 0x74, 0xfe, 0x51, 0x5c, 0x05, 0xcd, 0x13, 0x3d, 0xdc, 0xb7, 0xe4, + 0xa9, 0xe4, 0x30, 0x59, 0x3d, 0x1f, 0xe2, 0x20, 0xe7, 0x01, 0x4f, 0x41, + 0x75, 0x6f, 0x79, 0xce, 0xa1, 0x9c, 0x05, 0xf8, 0x85, 0x10, 0x73, 0x13, + 0x90, 0x84, 0x1b, 0x9e, 0x6d, 0x01, 0xd0, 0xd8, 0x64, 0x2b, 0x48, 0x7d, + 0xcb, 0x0a, 0x3b, 0x3a, 0x78, 0x06, 0x53, 0xf4, 0x60, 0x8e, 0xcc, 0x08, + 0x62, 0x3e, 0x67, 0xb9, 0xf9, 0x33, 0x91, 0x38, 0x11, 0x8f, 0x58, 0xba, + 0x4b, 0xe5, 0x2a, 0xb4, 0x34, 0x20, 0x89, 0x11, 0x08, 0xd3, 0xfa, 0x72, + 0xf1, 0x1a, 0xa1, 0x0f, 0x5c, 0xd1, 0xef, 0x7d, 0x2e, 0x40, 0xef, 0x82, + 0x0b, 0x6d, 0xe2, 0xa1, 0xbe, 0xb7, 0xd6, 0x12, 0xb5, 0x53, 0x0e, 0xe7, + 0x21, 0xc4, 0x0c, 0xfe, 0x46, 0x4d, 0x2f, 0xde, 0x24, 0xd2, 0xfd, 0xee, + 0xdd, 0x24, 0xb5, 0x8f, 0xe8, 0x32, 0x87, 0x74, 0x51, 0x29, 0x2c, 0xc7, + 0xe3, 0x92, 0x33, 0x19, 0x20, 0x63, 0x91, 0xb6, 0xa9, 0x4f, 0x76, 0x86, + 0x84, 0x1e, 0x5b, 0x61, 0x29, 0xda, 0x50, 0x29, 0x7c, 0xdd, 0xd1, 0xf5, + 0xd7, 0x8f, 0xfa, 0xf8, 0x02, 0xeb, 0x87, 0xfb, 0x12, 0xaf, 0x1f, 0x3d, + 0x71, 0xf7, 0xfa, 0x05, 0x1a, 0x67, 0x23, 0xac, 0xae, 0x22, 0xa5, 0x00, + 0x95, 0x8c, 0xce, 0x82, 0xf2, 0x15, 0x7c, 0x47, 0xa4, 0x88, 0x36, 0xb0, + 0xe0, 0xb8, 0x00, 0xe2, 0x7b, 0x93, 0xcd, 0x33, 0x5e, 0x6f, 0x1f, 0x3c, + 0x1e, 0x3b, 0xb0, 0x13, 0x27, 0xb2, 0xe2, 0x6f, 0x31, 0xc4, 0x11, 0x08, + 0x88, 0xf9, 0x3c, 0xf7, 0xe5, 0x0a, 0xd9, 0x80, 0x29, 0x56, 0x5d, 0x35, + 0xa7, 0x07, 0x1c, 0x9a, 0x18, 0x62, 0x6d, 0xf3, 0xcf, 0x6f, 0x9e, 0xff, + 0xd5, 0x38, 0xf7, 0x96, 0x44, 0x6b, 0x36, 0x9a, 0xf6, 0xe1, 0x22, 0xce, + 0x41, 0xaf, 0xd5, 0xb5, 0xc3, 0x64, 0xf1, 0xee, 0x0c, 0x33, 0xb7, 0xab, + 0x60, 0x54, 0x50, 0x14, 0xf4, 0x26, 0xbc, 0x80, 0x46, 0xf9, 0x73, 0xb1, + 0x50, 0xed, 0xf7, 0x1f, 0x91, 0xa9, 0x19, 0xee, 0xc9, 0x47, 0xfb, 0x7b, + 0xbb, 0x5b, 0x77, 0x4c, 0x20, 0x09, 0x6b, 0x28, 0xae, 0x09, 0x90, 0x19, + 0xe9, 0x56, 0xdd, 0x3c, 0xfe, 0xcb, 0xd9, 0xeb, 0x75, 0x27, 0x10, 0xc5, + 0x17, 0x04, 0x6d, 0x5d, 0xdb, 0xa6, 0x96, 0x59, 0xfe, 0xa5, 0xb2, 0xcf, + 0x96, 0xd1, 0xd4, 0x79, 0x5e, 0xe6, 0x78, 0xc1, 0x74, 0x68, 0x86, 0x9d, + 0x97, 0xc5, 0x6c, 0x04, 0x92, 0xdb, 0x29, 0xe2, 0x83, 0x64, 0x78, 0x7d, + 0x7a, 0x8a, 0x31, 0x9b, 0xb0, 0x30, 0xb9, 0xe5, 0x28, 0xa3, 0x8f, 0xac, + 0xde, 0x13, 0x9a, 0x8e, 0xc8, 0x7e, 0x86, 0xf8, 0xa8, 0x4b, 0xe4, 0x7e, + 0x07, 0xb5, 0xf7, 0x48, 0x1c, 0x1f, 0x4b, 0x29, 0xf6, 0x06, 0xa1, 0xbb, + 0x2f, 0x23, 0x4a, 0xa7, 0xbd, 0x90, 0x80, 0x75, 0xcd, 0xa3, 0x2f, 0x5c, + 0xba, 0x71, 0x20, 0xbf, 0xae, 0x2b, 0x2d, 0xe1, 0x91, 0xf4, 0x40, 0x74, + 0x42, 0x21, 0x84, 0x84, 0xae, 0x61, 0x31, 0x43, 0xef, 0x52, 0x80, 0xfd, + 0x41, 0x99, 0x2a, 0xd3, 0x82, 0x48, 0x56, 0xc8, 0x4d, 0x9b, 0x14, 0x0b, + 0xa7, 0x8c, 0xe8, 0xcd, 0xd1, 0xd9, 0x45, 0x72, 0x71, 0xea, 0xbd, 0x17, + 0x9c, 0x7a, 0x8b, 0xf4, 0xdd, 0x40, 0xac, 0xcd, 0x92, 0xc4, 0xd5, 0xdd, + 0xc1, 0xed, 0xb8, 0x4a, 0xaf, 0x73, 0x42, 0x56, 0xe0, 0xfd, 0xe1, 0x1d, + 0x4a, 0x2c, 0x5e, 0x3a, 0xe1, 0x52, 0x3d, 0x96, 0xf3, 0xa9, 0xf7, 0x73, + 0xdb, 0x02, 0x35, 0xc3, 0x5e, 0x38, 0x37, 0x44, 0xf0, 0xfb, 0xcc, 0x66, + 0x25, 0x61, 0x8b, 0x0e, 0x50, 0x97, 0xb5, 0xcc, 0x08, 0x82, 0x5a, 0x0a, + 0xd7, 0x49, 0x1c, 0x21, 0xf0, 0xc2, 0x7c, 0xd4, 0x72, 0xa2, 0x4f, 0xc6, + 0x5c, 0x60, 0xd3, 0xaf, 0x8c, 0x80, 0xf6, 0xca, 0xb2, 0xe0, 0xba, 0xa8, + 0xa5, 0xd7, 0xc4, 0x4d, 0x8a, 0xfb, 0x98, 0xa4, 0x97, 0xe1, 0x46, 0x6c, + 0x86, 0xfd, 0x32, 0x3c, 0xb6, 0xec, 0x10, 0x41, 0x79, 0x2e, 0xed, 0x12, + 0x27, 0x9c, 0x08, 0x60, 0x54, 0x08, 0x08, 0x62, 0xcc, 0x28, 0x74, 0xbb, + 0xe7, 0x64, 0x4b, 0x25, 0xb6, 0x6c, 0xd9, 0xb6, 0xc2, 0xe4, 0x6d, 0x68, + 0xba, 0x62, 0x6d, 0xa9, 0xca, 0xad, 0x2b, 0xfc, 0x59, 0x92, 0xa1, 0x56, + 0x50, 0xfe, 0x3a, 0x47, 0xcd, 0x8f, 0xc5, 0x9f, 0xc0, 0x51, 0x56, 0xd5, + 0xd1, 0xc5, 0x23, 0x25, 0x12, 0x57, 0x9d, 0x43, 0x5f, 0x33, 0xa9, 0x99, + 0x8a, 0x62, 0xad, 0xea, 0x69, 0x7c, 0xd5, 0x35, 0x50, 0x01, 0xc1, 0xc4, + 0x61, 0x80, 0x01, 0x9c, 0x28, 0xd6, 0x12, 0x65, 0x14, 0xfc, 0x85, 0xd4, + 0xd2, 0x65, 0xd9, 0xf5, 0x9e, 0xe9, 0x50, 0x5b, 0xab, 0x82, 0x93, 0xba, + 0x2e, 0xba, 0x89, 0x6f, 0x42, 0xd4, 0x3f, 0x32, 0xc7, 0x1c, 0x3e, 0x50, + 0x06, 0x21, 0x79, 0xe3, 0x9e, 0x52, 0xe4, 0xca, 0x77, 0x0d, 0xa0, 0x5b, + 0x18, 0xe3, 0x9f, 0x2e, 0x2e, 0x8c, 0x4d, 0x70, 0x1c, 0x50, 0xca, 0xf5, + 0xb7, 0xa8, 0x40, 0x1b, 0x5d, 0xef, 0x6c, 0xaa, 0x55, 0xe2, 0xf3, 0x74, + 0xa4, 0x21, 0x4f, 0xd4, 0x05, 0xda, 0xdc, 0x13, 0x8e, 0xe7, 0x61, 0x19, + 0x8f, 0x00, 0x90, 0x29, 0x28, 0xad, 0x08, 0x01, 0x4e, 0x1e, 0x1d, 0x2e, + 0xa0, 0xce, 0x04, 0xfb, 0x76, 0x1e, 0x43, 0xda, 0xf2, 0x39, 0x90, 0x61, + 0xc4, 0xf5, 0xed, 0x82, 0xc0, 0x4f, 0x49, 0x80, 0x41, 0x41, 0x6c, 0x41, + 0x8e, 0xfb, 0x40, 0x00, 0x9f, 0xa3, 0x2c, 0x79, 0x6c, 0xf6, 0xbd, 0x73, + 0x73, 0xdb, 0x84, 0xd0, 0x2d, 0x96, 0x66, 0x60, 0xb8, 0x34, 0xf9, 0x48, + 0x4f, 0xa0, 0x28, 0x09, 0x7d, 0xf7, 0x50, 0x66, 0x2c, 0x06, 0xcf, 0x52, + 0x75, 0x5b, 0x89, 0x82, 0xf4, 0x91, 0x3e, 0x5d, 0x17, 0xaf, 0xa4, 0x01, + 0x4b, 0x18, 0xb1, 0x64, 0x70, 0x21, 0x1a, 0xb6, 0xe4, 0xe2, 0x96, 0x7c, + 0xe0, 0xd2, 0xc6, 0x74, 0xc3, 0x62, 0x96, 0x5c, 0x30, 0x52, 0x08, 0x5a, + 0xb2, 0xb2, 0x7c, 0xb0, 0xd0, 0x12, 0xb8, 0x14, 0xc5, 0x2d, 0x85, 0xb0, + 0xa5, 0xfb, 0x43, 0x8c, 0x5e, 0x9f, 0x5e, 0x1c, 0x1f, 0x68, 0xa2, 0x93, + 0xc0, 0xd8, 0x3d, 0x44, 0x95, 0xf4, 0x46, 0xc3, 0xd5, 0x79, 0x43, 0xd9, + 0xc1, 0xeb, 0xaa, 0xd1, 0x4a, 0x4d, 0x15, 0x33, 0xb6, 0xe9, 0x6e, 0x77, + 0x05, 0x27, 0x1b, 0xaf, 0x63, 0x0e, 0x44, 0x88, 0x44, 0xa5, 0x86, 0x03, + 0xd8, 0x94, 0xce, 0x40, 0x61, 0x4c, 0x3f, 0xba, 0xe5, 0xa4, 0x25, 0x2e, + 0xe6, 0xa2, 0x1a, 0x78, 0x3a, 0x61, 0xc8, 0x21, 0x12, 0x79, 0xa3, 0x9d, + 0x3a, 0x47, 0xd2, 0xc0, 0x87, 0x89, 0x0e, 0x98, 0xb3, 0xcb, 0x9c, 0xa2, + 0x91, 0x38, 0x26, 0xea, 0x30, 0x3b, 0xc7, 0xc1, 0x50, 0x4f, 0x76, 0x3e, + 0xd5, 0xa4, 0x5d, 0xb4, 0x94, 0x9a, 0x32, 0x5c, 0x09, 0x4b, 0xd3, 0x49, + 0xdc, 0xf9, 0xfb, 0x72, 0x79, 0x75, 0x51, 0x37, 0x2b, 0x83, 0x8c, 0x96, + 0x98, 0x48, 0x88, 0x1b, 0x8a, 0x18, 0x06, 0xbb, 0x3c, 0x92, 0xa7, 0x40, + 0x8c, 0x31, 0x72, 0x03, 0x63, 0xaf, 0xe9, 0x41, 0xb1, 0x9c, 0x2b, 0x3a, + 0xe7, 0x6a, 0xe9, 0x64, 0x8b, 0x4a, 0x5d, 0xa8, 0x49, 0xb7, 0x2f, 0xd2, + 0x60, 0xb3, 0xd6, 0xbc, 0x55, 0xe7, 0xec, 0x26, 0x52, 0xd6, 0x81, 0x95, + 0x6d, 0xf5, 0xa8, 0xd0, 0x65, 0xe4, 0x9c, 0x0e, 0xe8, 0x3a, 0x25, 0x00, + 0xa6, 0x86, 0x61, 0xd5, 0xcb, 0x2c, 0xdd, 0x70, 0x4a, 0x2d, 0xf3, 0x01, + 0xda, 0x7e, 0xb4, 0xe3, 0xeb, 0xc5, 0xd3, 0x1c, 0x96, 0x72, 0x14, 0x70, + 0x08, 0xbd, 0x5d, 0x16, 0xce, 0x25, 0xbe, 0x11, 0x03, 0x11, 0x39, 0x90, + 0xb2, 0xef, 0x76, 0x53, 0x16, 0xe7, 0x0b, 0x6a, 0x98, 0xd6, 0xc7, 0xbe, + 0x5f, 0xae, 0xf5, 0x36, 0x34, 0x58, 0xfc, 0x69, 0xb5, 0xa7, 0x5d, 0x97, + 0xbe, 0xd4, 0x96, 0xff, 0x68, 0xf1, 0xaa, 0x94, 0x9c, 0x35, 0xd3, 0xe8, + 0xbe, 0x24, 0xc0, 0x3b, 0xd1, 0x2d, 0x4a, 0x31, 0xbc, 0x71, 0x55, 0xd1, + 0x3a, 0x94, 0x27, 0x3b, 0xe3, 0xad, 0x53, 0xdb, 0xcd, 0x80, 0x41, 0x3d, + 0x7f, 0x2d, 0x06, 0x9a, 0x22, 0x8e, 0x35, 0x8b, 0x28, 0x24, 0x71, 0xcc, + 0x08, 0x9a, 0x0b, 0xca, 0xcc, 0x46, 0xe3, 0x07, 0xa9, 0x45, 0xd0, 0x41, + 0x64, 0xdd, 0x21, 0x6f, 0x28, 0x85, 0x16, 0x25, 0x97, 0x05, 0xbe, 0xc6, + 0x69, 0xd8, 0x91, 0x6d, 0x9a, 0x70, 0x36, 0xaa, 0x44, 0x8b, 0x46, 0x33, + 0x82, 0x5f, 0x33, 0x28, 0x31, 0xe3, 0x88, 0x7b, 0x0c, 0xba, 0xb9, 0x5d, + 0x8e, 0x88, 0x4c, 0x36, 0xd1, 0xad, 0x01, 0x5f, 0x6d, 0x85, 0x42, 0x48, + 0x46, 0xdd, 0x41, 0xd6, 0x67, 0xfe, 0x9c, 0x95, 0x5c, 0x83, 0x8c, 0x8d, + 0xdd, 0xb4, 0x1a, 0xf8, 0x5d, 0x83, 0x57, 0x54, 0x12, 0xe0, 0x33, 0x12, + 0x10, 0xa9, 0xa1, 0x56, 0x63, 0x60, 0x38, 0x09, 0xea, 0x2d, 0xec, 0x07, + 0x4c, 0x7e, 0x62, 0xae, 0x49, 0xfa, 0x2e, 0x89, 0xb3, 0x91, 0xb3, 0x78, + 0x7e, 0x21, 0x29, 0x75, 0xe0, 0x11, 0x44, 0x15, 0x3c, 0x76, 0x04, 0x8c, + 0x78, 0xb3, 0xbf, 0x45, 0x97, 0x87, 0xbc, 0xa7, 0x94, 0x49, 0xa9, 0x64, + 0xb0, 0xa8, 0x3d, 0x8d, 0xf4, 0xe5, 0xb2, 0xe8, 0x18, 0x2f, 0x61, 0xb5, + 0xa6, 0x04, 0x1d, 0x6b, 0xcc, 0x57, 0x8b, 0xa1, 0x80, 0x29, 0x6a, 0x28, + 0x5f, 0xac, 0xea, 0x5e, 0x91, 0x06, 0x35, 0x86, 0xdb, 0xa6, 0xf4, 0x39, + 0xab, 0x5e, 0x57, 0x2d, 0x27, 0x83, 0x3a, 0xd9, 0x5d, 0x23, 0x24, 0xd2, + 0x1e, 0xde, 0xeb, 0x7f, 0xb3, 0xb7, 0x6e, 0xf6, 0x3b, 0x05, 0x5e, 0xd0, + 0x6b, 0x68, 0x2a, 0xd6, 0xa8, 0x15, 0xbf, 0x67, 0x81, 0x4f, 0x66, 0x75, + 0x8a, 0x24, 0xba, 0xec, 0x36, 0x21, 0x34, 0x7b, 0x45, 0xeb, 0xe0, 0x30, + 0xb5, 0x25, 0x98, 0xd2, 0x57, 0xf2, 0x76, 0x80, 0xe3, 0x96, 0xa3, 0x64, + 0x5f, 0xa8, 0x6d, 0x3b, 0x2a, 0x45, 0x9a, 0x07, 0x7f, 0x73, 0x19, 0xdc, + 0x4f, 0x70, 0x2b, 0x55, 0xc4, 0x74, 0xb9, 0x36, 0xa9, 0xe2, 0x03, 0x63, + 0x01, 0xd8, 0x27, 0xfd, 0x9d, 0x2d, 0xb5, 0xee, 0x68, 0xcb, 0x5f, 0xd0, + 0xb8, 0xa3, 0x5d, 0xd0, 0x85, 0xbd, 0x1e, 0xa6, 0x32, 0xd0, 0xd1, 0x64, + 0x92, 0x85, 0x64, 0x8a, 0xe9, 0xbc, 0x1e, 0x4a, 0x20, 0x2f, 0xe7, 0xcb, + 0x54, 0x1a, 0x9c, 0x86, 0xb7, 0xcc, 0x2b, 0xd2, 0x29, 0x52, 0xb8, 0xc5, + 0x31, 0x6b, 0x78, 0xf3, 0xd5, 0xd9, 0x05, 0xa2, 0xe1, 0xe3, 0x6a, 0x44, + 0x19, 0xc1, 0xf4, 0xb9, 0x0b, 0x1b, 0x9f, 0xa1, 0xda, 0x81, 0x9e, 0x35, + 0x66, 0xf4, 0x64, 0xce, 0xb6, 0x20, 0x4e, 0x7c, 0x94, 0xb8, 0x9d, 0xb8, + 0xba, 0x4c, 0x6f, 0x91, 0xc4, 0x64, 0x58, 0xde, 0xa9, 0xde, 0x15, 0x64, + 0x8c, 0x0e, 0x31, 0x0c, 0x66, 0x8e, 0x46, 0x9d, 0xb3, 0xbe, 0xaa, 0x92, + 0x00, 0x0a, 0xca, 0x9e, 0x02, 0x76, 0x8a, 0x6b, 0x9c, 0x90, 0xb3, 0xa6, + 0x64, 0x18, 0x25, 0x99, 0x3a, 0x0c, 0x03, 0xd4, 0x68, 0xb3, 0x19, 0xf0, + 0xc9, 0xa1, 0x0b, 0xb7, 0x27, 0x12, 0xcc, 0xa7, 0xb8, 0x5b, 0xc8, 0x20, + 0x26, 0xb9, 0x62, 0xcd, 0x5a, 0x64, 0x12, 0x9f, 0x7d, 0x1b, 0x32, 0x8f, + 0xa2, 0xca, 0xf1, 0x83, 0x74, 0x96, 0x11, 0x01, 0xea, 0x9e, 0xf1, 0xa2, + 0x60, 0xe2, 0x4b, 0x36, 0xcb, 0xc6, 0x39, 0x01, 0x3a, 0xe7, 0x2e, 0xc3, + 0xfa, 0x86, 0x92, 0x9d, 0x1a, 0x4d, 0x51, 0xa0, 0x5f, 0xa3, 0x2c, 0x12, + 0x67, 0x51, 0x48, 0x24, 0x28, 0xc7, 0x9a, 0x76, 0x45, 0xbc, 0x43, 0xd2, + 0x9f, 0x16, 0x03, 0xdc, 0xfe, 0x46, 0xbb, 0xc8, 0x9f, 0x28, 0xd1, 0x92, + 0xdc, 0xa9, 0xc2, 0x97, 0x38, 0xbc, 0x51, 0xd7, 0xec, 0xa7, 0xfc, 0x79, + 0x2e, 0xc2, 0x7b, 0x36, 0x99, 0x70, 0x71, 0x26, 0xb2, 0x56, 0x60, 0x4d, + 0x28, 0x82, 0xaa, 0xc1, 0x60, 0xb0, 0x90, 0x11, 0x1e, 0x72, 0x33, 0x6d, + 0xd0, 0x84, 0xe1, 0x8c, 0x56, 0x15, 0x85, 0x85, 0x65, 0x55, 0x15, 0xc1, + 0xc6, 0xdb, 0x2a, 0xe1, 0xe4, 0x95, 0x4f, 0xb5, 0xe7, 0x80, 0x97, 0x00, + 0xf7, 0x50, 0x18, 0xfa, 0x70, 0xa5, 0x02, 0x24, 0x5d, 0x67, 0x1a, 0x66, + 0x5e, 0x62, 0xca, 0xe3, 0xa3, 0xfe, 0xe3, 0x7e, 0x72, 0x4a, 0xe9, 0xe0, + 0xb8, 0xbc, 0x8e, 0x0c, 0x39, 0x6e, 0x51, 0xc3, 0x21, 0xba, 0xa0, 0xf0, + 0xcd, 0x0c, 0x46, 0xd0, 0x17, 0x52, 0x30, 0x15, 0x46, 0x04, 0x60, 0x29, + 0x94, 0xb3, 0x89, 0xb5, 0x6d, 0x28, 0x79, 0xfc, 0xed, 0xb3, 0xa8, 0x5d, + 0x7f, 0x3d, 0x88, 0x53, 0x46, 0x32, 0x89, 0xe8, 0x11, 0x16, 0xbe, 0x28, + 0x6d, 0x8c, 0x63, 0xf2, 0x95, 0x93, 0xd0, 0xfe, 0x13, 0x33, 0x80, 0xce, + 0x3c, 0x33, 0x8e, 0x03, 0xce, 0xd2, 0x29, 0x66, 0x5f, 0x50, 0x4d, 0x2b, + 0x38, 0x10, 0x15, 0x67, 0x62, 0x26, 0x7c, 0x53, 0x53, 0x03, 0x1e, 0xba, + 0x2e, 0x3e, 0xb0, 0xf7, 0x54, 0xe2, 0x4b, 0x96, 0xd4, 0x7e, 0x57, 0xf0, + 0x38, 0xf1, 0xfb, 0xc9, 0xaa, 0x3f, 0x36, 0x7c, 0x0f, 0xc3, 0xc1, 0x47, + 0x3e, 0x1d, 0xfd, 0x75, 0x0c, 0x9c, 0xae, 0x00, 0xbd, 0xcc, 0x98, 0x8f, + 0x55, 0x63, 0x8c, 0xa4, 0x5e, 0xc9, 0xdb, 0x7b, 0xad, 0x5f, 0x26, 0x9b, + 0xe7, 0x67, 0xaf, 0x8f, 0x7f, 0x3c, 0xdd, 0x5a, 0xe1, 0x31, 0xf5, 0x24, + 0x66, 0xd9, 0x67, 0xa9, 0xa6, 0x3e, 0x4b, 0xde, 0x19, 0xa9, 0x22, 0x3f, + 0x9e, 0x9f, 0xf7, 0x0e, 0xcf, 0x4e, 0x12, 0x4a, 0xed, 0x86, 0x7f, 0x75, + 0xaf, 0xfa, 0xbe, 0xcc, 0x98, 0x5e, 0xd0, 0x21, 0x28, 0x97, 0xf3, 0xb6, + 0xc8, 0xf8, 0xa3, 0xfe, 0x41, 0x69, 0x69, 0x9b, 0x9a, 0xc1, 0xe6, 0x68, + 0x84, 0x91, 0x35, 0xb6, 0xc5, 0xf3, 0x86, 0x42, 0x52, 0xa0, 0x14, 0x4d, + 0x4c, 0x4f, 0x61, 0xe7, 0xdf, 0x53, 0xfc, 0x13, 0x05, 0xb7, 0x7a, 0x5a, + 0x45, 0xcb, 0x00, 0xa2, 0x51, 0xa4, 0x35, 0x8b, 0x3e, 0x0d, 0x3f, 0x0f, + 0x27, 0xa5, 0x41, 0x3b, 0xf3, 0xac, 0xc4, 0xfa, 0x01, 0xe7, 0xa2, 0xf3, + 0xa6, 0xc9, 0x46, 0x6f, 0x91, 0x1c, 0x6c, 0x04, 0x96, 0x9c, 0xcd, 0xa8, + 0xb6, 0x6b, 0x6a, 0xdc, 0x9d, 0xed, 0xcd, 0x64, 0x5c, 0x53, 0x6f, 0x1b, + 0x89, 0x8e, 0x9c, 0xd6, 0xec, 0x06, 0xc2, 0x18, 0x3d, 0x96, 0x3c, 0xca, + 0xe0, 0x68, 0x72, 0xcd, 0x36, 0x60, 0x15, 0x6d, 0x3b, 0x57, 0x45, 0xc9, + 0x7e, 0x2c, 0xb4, 0x62, 0x68, 0x10, 0xa7, 0xb3, 0xde, 0x0d, 0x37, 0x48, + 0x2b, 0x04, 0xd7, 0x87, 0x97, 0xeb, 0x09, 0x89, 0xe3, 0xa0, 0xc2, 0x90, + 0x03, 0x49, 0x02, 0x8e, 0xa8, 0xa8, 0x80, 0x35, 0xac, 0xa4, 0x38, 0xa3, + 0x37, 0x40, 0xf4, 0x18, 0xaa, 0x19, 0x49, 0x0b, 0xdf, 0x57, 0xc3, 0x54, + 0xae, 0x97, 0x3e, 0x7d, 0x2f, 0xb9, 0xbb, 0x71, 0x31, 0x0c, 0xae, 0x83, + 0xe1, 0x32, 0x1d, 0x0c, 0xa0, 0x90, 0x7d, 0xc8, 0x4b, 0x8b, 0xed, 0x4a, + 0x43, 0xd7, 0x8c, 0xa1, 0x24, 0x59, 0x17, 0x9c, 0xc3, 0x87, 0xb6, 0x22, + 0x5c, 0xfa, 0xb7, 0xb3, 0xfc, 0x43, 0x3f, 0x60, 0xcc, 0x54, 0x6a, 0x03, + 0xe5, 0x2a, 0x49, 0x2c, 0x9b, 0x64, 0x72, 0x6d, 0xd3, 0x9e, 0x35, 0xbd, + 0xc3, 0x94, 0x59, 0x49, 0xe3, 0xde, 0x7c, 0xb4, 0x15, 0xac, 0x35, 0xe3, + 0x7a, 0xbe, 0xb9, 0xcb, 0x17, 0xb9, 0x54, 0x21, 0xb1, 0x80, 0x4a, 0x9a, + 0x9e, 0x26, 0x58, 0x1c, 0x59, 0x21, 0x64, 0x12, 0x63, 0x09, 0xd1, 0xd6, + 0xaa, 0xa5, 0x93, 0xb3, 0x17, 0xcd, 0xd1, 0xf4, 0x4a, 0x78, 0x8a, 0x52, + 0xe3, 0x38, 0x0a, 0x8f, 0xa4, 0x5a, 0x8a, 0x24, 0xaa, 0xb8, 0xc4, 0x57, + 0xb2, 0x99, 0xd7, 0x4b, 0xde, 0xea, 0x99, 0x60, 0xbe, 0xa3, 0x13, 0x79, + 0x32, 0x22, 0x99, 0x19, 0xfe, 0xb8, 0x2c, 0x8b, 0xc5, 0xbc, 0x87, 0x89, + 0xe6, 0x38, 0xbf, 0x2d, 0xc1, 0x1d, 0x89, 0x41, 0x97, 0x0d, 0x75, 0x59, + 0x7c, 0x0e, 0x2f, 0x4e, 0x5f, 0x1d, 0x77, 0xcc, 0x59, 0x4a, 0x65, 0x95, + 0x04, 0xf7, 0x20, 0xde, 0x20, 0x25, 0xbb, 0x53, 0x43, 0xdc, 0x4f, 0xe0, + 0x96, 0x0b, 0x39, 0x04, 0xba, 0xbd, 0x8d, 0x6d, 0x25, 0xac, 0x38, 0x42, + 0x0c, 0x1e, 0x1d, 0x24, 0x42, 0x0f, 0x61, 0x51, 0xdf, 0xd1, 0xdf, 0x5d, + 0x8b, 0xa4, 0x0e, 0x51, 0x72, 0x94, 0x2b, 0x80, 0xc2, 0xfb, 0x29, 0xd7, + 0x4e, 0xb4, 0x8a, 0x67, 0xb4, 0xea, 0x11, 0x92, 0x91, 0x34, 0x4f, 0x5b, + 0xc3, 0x0d, 0x26, 0x3e, 0x4e, 0xfc, 0x30, 0x01, 0xfe, 0x06, 0xf7, 0x03, + 0xc9, 0x02, 0x39, 0x65, 0xb5, 0x69, 0x76, 0x1b, 0x1a, 0x05, 0x24, 0x26, + 0x93, 0xc3, 0x98, 0x53, 0xa5, 0xd8, 0x5a, 0xc2, 0x8a, 0xbc, 0x8b, 0x01, + 0x3e, 0x43, 0x22, 0x53, 0xeb, 0xb3, 0x64, 0x6e, 0x70, 0x68, 0x29, 0xfb, + 0x9e, 0xc8, 0x56, 0xcb, 0xe4, 0x66, 0xfc, 0x62, 0x63, 0x7a, 0x8b, 0xa8, + 0xc3, 0x1b, 0x4e, 0xb4, 0x32, 0xf6, 0xb1, 0xc1, 0x41, 0x60, 0x1b, 0x02, + 0xc7, 0x4b, 0xb9, 0x3a, 0x5a, 0xab, 0xad, 0x2e, 0x08, 0xf2, 0x71, 0x45, + 0x2f, 0xf0, 0x0d, 0x1f, 0x13, 0x6e, 0x1d, 0xfe, 0x0c, 0x11, 0x00, 0xd4, + 0xe6, 0x57, 0xcb, 0x11, 0xf9, 0x3c, 0xb3, 0x36, 0x0c, 0xd7, 0x70, 0xff, + 0x35, 0x83, 0x98, 0xcc, 0xae, 0xd4, 0xb4, 0x7a, 0x53, 0x63, 0xf7, 0xb1, + 0x22, 0xec, 0x6f, 0xdd, 0x1a, 0xea, 0xcd, 0x92, 0xd0, 0xad, 0x15, 0xa1, + 0xa9, 0xc9, 0x1e, 0xb3, 0x13, 0x8f, 0x1f, 0xc7, 0x9f, 0x73, 0x53, 0x68, + 0xca, 0xf6, 0xe8, 0x29, 0xf6, 0x4a, 0x97, 0x15, 0xa8, 0x71, 0x7e, 0x29, + 0x8c, 0x2d, 0x8a, 0x38, 0x70, 0x4d, 0x3f, 0x55, 0xa2, 0x6e, 0xa2, 0x30, + 0x39, 0x6e, 0x66, 0xc1, 0x91, 0xe7, 0x5a, 0x5b, 0xaf, 0xb6, 0xde, 0xba, + 0x34, 0xfa, 0x0c, 0x11, 0xb1, 0xe9, 0xb0, 0xc3, 0x1d, 0xe6, 0x0a, 0xc0, + 0xe9, 0x1d, 0xc6, 0x48, 0x9a, 0x30, 0xb1, 0xcd, 0x74, 0x50, 0x15, 0x93, + 0x45, 0x4d, 0x8e, 0x4d, 0x0c, 0x23, 0xc0, 0xe0, 0x3a, 0x73, 0x53, 0x9e, + 0xc0, 0xd5, 0x37, 0xe0, 0xf0, 0xcd, 0xc1, 0xed, 0xd2, 0x54, 0x39, 0xa2, + 0xcf, 0x1c, 0x2e, 0x6a, 0x05, 0xf2, 0xeb, 0xf4, 0xa5, 0x0c, 0x7a, 0xae, + 0x8f, 0xb5, 0x76, 0x7a, 0x2d, 0x0c, 0x57, 0x26, 0xab, 0x08, 0xc4, 0x95, + 0x97, 0xd4, 0x20, 0x07, 0x2b, 0x89, 0x88, 0xd7, 0xbd, 0x6c, 0x6c, 0xa0, + 0x2e, 0x8c, 0xc6, 0x2b, 0x85, 0xcd, 0x71, 0xbb, 0x33, 0x58, 0x2c, 0x39, + 0xc3, 0x25, 0xcf, 0x96, 0xb6, 0x59, 0x78, 0x00, 0xac, 0x41, 0x7a, 0x19, + 0xa1, 0xb0, 0xa6, 0x13, 0xab, 0xbc, 0x8b, 0x76, 0xbe, 0x51, 0xca, 0x2c, + 0xae, 0xd2, 0x60, 0x6c, 0x61, 0x3e, 0xa1, 0xae, 0x5c, 0x9b, 0x27, 0xaa, + 0xb1, 0x81, 0xab, 0x30, 0x95, 0x1b, 0xf2, 0xe8, 0x7a, 0x07, 0x32, 0x1c, + 0x81, 0x35, 0xb6, 0xce, 0x86, 0xb0, 0xee, 0x11, 0x5d, 0x7d, 0x42, 0xe3, + 0x03, 0xda, 0x57, 0x90, 0x79, 0x8f, 0x4f, 0x10, 0xc8, 0x45, 0x77, 0xec, + 0xa0, 0x2b, 0x69, 0xf6, 0x41, 0x94, 0xf4, 0xa5, 0x7c, 0x5d, 0xa6, 0xbf, + 0x84, 0x47, 0x47, 0x21, 0xde, 0x56, 0x9c, 0x0c, 0x81, 0x38, 0x8a, 0x21, + 0x15, 0x28, 0x8f, 0x62, 0xe6, 0x44, 0x6b, 0x4d, 0x03, 0xb2, 0x11, 0xf3, + 0xf9, 0x99, 0x4b, 0xdd, 0xc7, 0x46, 0x34, 0x96, 0xbb, 0xcb, 0x36, 0x33, + 0x27, 0xe3, 0x73, 0x26, 0x62, 0x42, 0x50, 0xc8, 0x4b, 0x11, 0x83, 0x5d, + 0x89, 0xda, 0x36, 0xff, 0x89, 0x39, 0xf3, 0x13, 0xa7, 0x7f, 0x9b, 0x69, + 0xad, 0xe4, 0x4b, 0x12, 0xcd, 0x00, 0x20, 0xcd, 0xc2, 0x35, 0x61, 0x21, + 0xe4, 0xd8, 0x0a, 0xf6, 0xdc, 0xff, 0x2a, 0x2c, 0xd5, 0x87, 0x9a, 0xed, + 0x78, 0x15, 0x7b, 0x64, 0xd9, 0x0c, 0x66, 0xb1, 0x80, 0x38, 0x6b, 0xd2, + 0x04, 0x15, 0xe6, 0xa0, 0x98, 0x11, 0xe1, 0x48, 0xf9, 0x97, 0xbc, 0x74, + 0x66, 0x11, 0x4c, 0x66, 0x5c, 0x80, 0xa2, 0x49, 0xe8, 0x6c, 0xd7, 0x5a, + 0x59, 0x49, 0x73, 0x3d, 0xad, 0xba, 0x93, 0xb7, 0x62, 0x93, 0x59, 0xc0, + 0xef, 0x4c, 0x2e, 0xd1, 0xd1, 0x24, 0x1e, 0x25, 0xc9, 0x8f, 0xd2, 0x6b, + 0x18, 0x50, 0x62, 0xa9, 0x98, 0x89, 0xf7, 0xfb, 0xd1, 0x5f, 0xe4, 0xec, + 0xb3, 0xe3, 0x4b, 0x7f, 0xf5, 0xd2, 0x6a, 0x98, 0xe7, 0x72, 0x8a, 0xd1, + 0xfb, 0x89, 0x11, 0x87, 0xe1, 0xc2, 0x46, 0xb7, 0x94, 0xad, 0xaa, 0x56, + 0x7c, 0x1a, 0x15, 0x5c, 0x96, 0x5d, 0xd2, 0x0c, 0x38, 0x27, 0x86, 0x62, + 0xf1, 0x29, 0xcc, 0x41, 0xe3, 0x8b, 0xa2, 0xd8, 0x40, 0x74, 0x9c, 0x87, + 0xba, 0x0b, 0x37, 0x37, 0x37, 0xbb, 0xfd, 0x28, 0x9a, 0x87, 0x17, 0xba, + 0x87, 0x65, 0x5d, 0xab, 0x9a, 0xd8, 0x01, 0x3c, 0xb3, 0xd7, 0x6f, 0xab, + 0x49, 0x4a, 0x4f, 0x7e, 0x26, 0x8c, 0xd9, 0x36, 0x94, 0xd6, 0x75, 0xc6, + 0xe2, 0x8f, 0xf0, 0xc9, 0x5d, 0xad, 0x34, 0xbf, 0x82, 0xa3, 0xb7, 0xbd, + 0xda, 0xae, 0xb5, 0x82, 0x9b, 0x16, 0xbd, 0x74, 0x32, 0xf7, 0x39, 0x50, + 0xe7, 0x5b, 0xc6, 0x84, 0x90, 0x44, 0x0e, 0x5f, 0x9e, 0xbd, 0x26, 0x98, + 0x24, 0xb3, 0x5b, 0xf5, 0xf9, 0x33, 0xcc, 0x80, 0x9d, 0xb1, 0x31, 0xd0, + 0x15, 0xd4, 0x30, 0xf9, 0xd7, 0x57, 0xd4, 0x74, 0x7a, 0x26, 0x65, 0xba, + 0x06, 0xf4, 0x2d, 0xbe, 0x39, 0x4d, 0x77, 0xc4, 0x86, 0x11, 0xfe, 0x0a, + 0xfe, 0x89, 0xca, 0xaf, 0x24, 0x52, 0x74, 0xd0, 0x00, 0x3a, 0xe2, 0xd7, + 0xa4, 0x26, 0x36, 0x91, 0x7c, 0x50, 0x8c, 0xe4, 0x53, 0xad, 0x26, 0xc7, + 0xa6, 0x07, 0x8b, 0x93, 0x10, 0x7b, 0x85, 0xb8, 0xcb, 0x68, 0x29, 0x35, + 0x50, 0xba, 0xf2, 0x29, 0x9c, 0x0e, 0xc1, 0x2e, 0x57, 0xcf, 0x28, 0x02, + 0xb0, 0x60, 0xa6, 0x0f, 0xf3, 0x4b, 0x12, 0xff, 0x46, 0xc5, 0x70, 0x81, + 0x82, 0xb7, 0xda, 0xdb, 0x35, 0x4e, 0x59, 0x09, 0x0b, 0x17, 0x99, 0xca, + 0x31, 0xb3, 0x06, 0x2f, 0x33, 0x8d, 0xc4, 0x36, 0xde, 0x89, 0xcf, 0x11, + 0x82, 0x8e, 0xed, 0xdc, 0x73, 0x33, 0x48, 0x67, 0x77, 0xd5, 0xe7, 0xd5, + 0x67, 0x56, 0xc2, 0xd6, 0x2c, 0xe3, 0xd6, 0x00, 0x9d, 0xb4, 0x40, 0xd6, + 0xe0, 0xad, 0x35, 0x9f, 0xb5, 0x01, 0xb3, 0xbf, 0xee, 0xf2, 0xd7, 0x83, + 0xc5, 0xd8, 0x8a, 0xaf, 0x3f, 0xf3, 0x6e, 0xee, 0x84, 0xbf, 0x21, 0x86, + 0x55, 0xa8, 0x9f, 0xbe, 0x58, 0xd4, 0xf3, 0x45, 0xad, 0x06, 0x51, 0x34, + 0xfc, 0xcf, 0x34, 0x47, 0x9a, 0xa3, 0x6d, 0xb5, 0x44, 0x2c, 0xdc, 0x60, + 0xc2, 0xc3, 0x5d, 0xe8, 0xb1, 0xcb, 0x9a, 0xe7, 0xc6, 0xc9, 0xc0, 0xc6, + 0x4d, 0x72, 0x8b, 0x22, 0xce, 0x59, 0xa2, 0x0b, 0x81, 0xc3, 0x89, 0x4b, + 0x98, 0xbe, 0x22, 0x18, 0x09, 0x7a, 0xa3, 0x72, 0xe0, 0xe1, 0x68, 0x39, + 0x1a, 0x5e, 0x2d, 0x66, 0xef, 0xa1, 0x3f, 0x2e, 0xd7, 0x21, 0x89, 0x94, + 0xb9, 0x66, 0x22, 0xc0, 0x2a, 0x0f, 0x6b, 0xab, 0x39, 0x10, 0x70, 0xd0, + 0x53, 0xd0, 0x88, 0xae, 0x51, 0x8a, 0x78, 0xab, 0xf9, 0x43, 0xce, 0x32, + 0x68, 0x6e, 0x7f, 0x57, 0x43, 0xc5, 0x56, 0xe5, 0x0b, 0x50, 0x2a, 0xb7, + 0xed, 0x68, 0x35, 0x6c, 0x01, 0x11, 0xd9, 0x12, 0xd5, 0xca, 0x0b, 0xbf, + 0xbd, 0x58, 0x22, 0x37, 0x74, 0x2f, 0xe1, 0x4a, 0x7f, 0xeb, 0x16, 0x4a, + 0xbc, 0xc4, 0x40, 0xc5, 0xde, 0xc0, 0x61, 0x07, 0x43, 0x1b, 0x43, 0xb8, + 0xdb, 0x0c, 0xec, 0x52, 0x6c, 0x52, 0xcb, 0x08, 0xbd, 0x81, 0x5b, 0xf4, + 0x7a, 0xbc, 0xdf, 0x5d, 0x4e, 0xde, 0xc6, 0x8a, 0x32, 0x92, 0x50, 0xd2, + 0xa3, 0x08, 0x3f, 0x5d, 0x3c, 0xf9, 0x4a, 0x0a, 0x21, 0x52, 0x70, 0x45, + 0xfc, 0x69, 0x8f, 0x2e, 0x7a, 0x27, 0x5c, 0x88, 0xa9, 0x22, 0xe1, 0xca, + 0xe7, 0xce, 0xba, 0x8f, 0x80, 0x4a, 0xe4, 0xa8, 0x94, 0x38, 0x05, 0x72, + 0x0b, 0x30, 0xb8, 0x1c, 0x99, 0xc2, 0x89, 0xee, 0x25, 0x07, 0x9c, 0x3d, + 0x6e, 0x92, 0x40, 0xea, 0x71, 0x3c, 0x2f, 0x49, 0xb6, 0x10, 0xac, 0x1a, + 0x75, 0x38, 0x70, 0x70, 0xe5, 0x38, 0xd8, 0x34, 0xa8, 0x71, 0x85, 0xca, + 0xc1, 0x44, 0x26, 0x24, 0x9a, 0x2e, 0xc2, 0xfe, 0x58, 0x04, 0x85, 0x41, + 0x48, 0xee, 0xee, 0xec, 0x48, 0x16, 0x1c, 0xc7, 0xa8, 0x69, 0xd6, 0x24, + 0xa5, 0xce, 0xd1, 0x9b, 0x94, 0xcd, 0xe7, 0xab, 0x30, 0xb7, 0x13, 0xe7, + 0x3a, 0xb4, 0xc9, 0x29, 0x7a, 0x57, 0x8b, 0x10, 0x97, 0x4e, 0xeb, 0x29, + 0xbb, 0x27, 0xca, 0x3a, 0xd9, 0xf0, 0x04, 0xc8, 0x43, 0xe1, 0x26, 0xe5, + 0x09, 0x58, 0xbf, 0xae, 0x65, 0x0f, 0xd0, 0xbd, 0xd4, 0xd8, 0x28, 0xb7, + 0x87, 0xe4, 0xa5, 0x0f, 0x0a, 0x56, 0x83, 0xc8, 0xad, 0xcb, 0xdf, 0x4c, + 0xe5, 0xd2, 0xd2, 0xbd, 0x64, 0xae, 0x3d, 0x2a, 0xe9, 0xb1, 0x74, 0x48, + 0xc9, 0xed, 0xf7, 0x38, 0xb5, 0x7c, 0x69, 0xf2, 0xfd, 0x86, 0xb1, 0x59, + 0xda, 0x52, 0x87, 0xa2, 0xd1, 0xa5, 0x3f, 0x1c, 0x06, 0x3c, 0xda, 0xc2, + 0x90, 0xc5, 0xfb, 0x15, 0xf0, 0x5a, 0x25, 0x58, 0x9e, 0xac, 0x64, 0x8a, + 0xa1, 0xeb, 0x61, 0xb1, 0x9d, 0x61, 0x25, 0x64, 0x1e, 0x66, 0xc1, 0x9f, + 0x36, 0x75, 0x41, 0x13, 0x5f, 0x84, 0x60, 0x1c, 0x90, 0x2a, 0x93, 0x8b, + 0x11, 0x4b, 0x40, 0x69, 0x4e, 0x1a, 0xd6, 0xda, 0xa5, 0x35, 0xf8, 0x8c, + 0xfe, 0x04, 0x8f, 0x0d, 0x7d, 0x37, 0x05, 0x84, 0x71, 0xaf, 0x89, 0xfb, + 0xd7, 0x02, 0x46, 0x1d, 0x81, 0xc8, 0xfa, 0x4d, 0x9e, 0x35, 0x85, 0x3e, + 0xea, 0x77, 0x86, 0xe2, 0xae, 0x5c, 0x94, 0xaf, 0xcf, 0x5e, 0xc7, 0x49, + 0xe7, 0x0d, 0xec, 0x5e, 0xf6, 0xf1, 0xa2, 0x4e, 0xc0, 0x0d, 0x01, 0xb5, + 0x3d, 0x46, 0x27, 0xef, 0x57, 0x11, 0xd9, 0xf0, 0x89, 0x7c, 0x8d, 0x51, + 0xd5, 0x54, 0xee, 0xda, 0x89, 0x91, 0xf4, 0x29, 0xca, 0x11, 0x2a, 0x47, + 0x46, 0x95, 0xd9, 0xec, 0xb0, 0x2e, 0x4b, 0x92, 0x92, 0x89, 0xcc, 0x92, + 0x64, 0x2c, 0x4a, 0x06, 0xa1, 0xf0, 0x35, 0x0a, 0x58, 0xd4, 0xaf, 0x4f, + 0x6b, 0x61, 0x41, 0x52, 0x9b, 0x8c, 0xc5, 0xc8, 0x20, 0x45, 0x06, 0x21, + 0x52, 0x3e, 0xd3, 0x87, 0x5c, 0x46, 0xe1, 0xbd, 0x42, 0x64, 0x93, 0x85, + 0xcc, 0xbc, 0x70, 0xf7, 0xe9, 0x15, 0x85, 0xd7, 0x10, 0xed, 0x66, 0xf7, + 0x4b, 0x76, 0xb3, 0x95, 0x82, 0x5d, 0x04, 0x48, 0x78, 0xbf, 0x64, 0x47, + 0x22, 0x62, 0x5b, 0xcd, 0x1d, 0xf8, 0xce, 0x6e, 0xdf, 0x69, 0x66, 0xd5, + 0x82, 0x4f, 0x2d, 0xc8, 0x49, 0x7c, 0xae, 0xc5, 0x58, 0xe4, 0x3a, 0x7d, + 0x3a, 0xa1, 0xa7, 0x4d, 0x26, 0x93, 0x0a, 0xed, 0x68, 0x90, 0x60, 0x31, + 0xb0, 0x6c, 0x72, 0x13, 0xb8, 0x8f, 0x08, 0x99, 0x9c, 0x50, 0x72, 0x53, + 0x2e, 0x9e, 0x24, 0x36, 0x03, 0x97, 0x75, 0x87, 0xc2, 0xa1, 0x31, 0x2b, + 0x4e, 0xfb, 0xd5, 0x69, 0x54, 0x39, 0x81, 0x11, 0x92, 0x25, 0xe7, 0xcb, + 0xb0, 0xa0, 0x78, 0x25, 0x9c, 0x70, 0xd5, 0x32, 0x71, 0x91, 0xb2, 0x5a, + 0x2c, 0x4a, 0xcd, 0x15, 0x5d, 0x2b, 0xb0, 0xf9, 0x6e, 0x8b, 0x52, 0xdc, + 0xe0, 0xbd, 0x94, 0xd5, 0xe8, 0xbf, 0x57, 0x70, 0xf5, 0xee, 0xf5, 0x2e, + 0xa3, 0xc7, 0x5f, 0x37, 0x2e, 0x23, 0xb1, 0x20, 0x28, 0xd8, 0x17, 0xed, + 0x82, 0xa7, 0x1f, 0x39, 0x4a, 0xf9, 0xc8, 0xe3, 0xc5, 0xea, 0x7c, 0x70, + 0x50, 0x1b, 0x95, 0x5e, 0x48, 0xc8, 0x09, 0xb4, 0xee, 0xc4, 0xc9, 0x33, + 0xd8, 0x03, 0x34, 0xa7, 0x5f, 0xf6, 0x93, 0x1f, 0x5c, 0x16, 0x01, 0x88, + 0x5e, 0x5a, 0x83, 0x8e, 0xa3, 0xa4, 0xd8, 0x31, 0x4e, 0x95, 0x7a, 0x42, + 0xfa, 0x06, 0xbe, 0x9a, 0x79, 0x24, 0x16, 0x8e, 0x65, 0xc5, 0x78, 0x23, + 0x06, 0x7b, 0xbb, 0x0a, 0xb9, 0xf4, 0xc4, 0x2d, 0x11, 0x2a, 0xe2, 0x6a, + 0x01, 0x67, 0x04, 0xb9, 0x57, 0x5a, 0xd7, 0xd9, 0x74, 0xce, 0x91, 0xbc, + 0x98, 0x51, 0x40, 0x22, 0x4b, 0x3c, 0x38, 0xb6, 0xc5, 0x32, 0x74, 0x7f, + 0x36, 0x35, 0x9f, 0x03, 0x48, 0x5e, 0x82, 0x34, 0x8f, 0x8f, 0x93, 0x03, + 0x03, 0xc9, 0x2a, 0x15, 0xdb, 0x8b, 0xb8, 0x5d, 0x6e, 0x72, 0xac, 0x7e, + 0xa2, 0xf9, 0xab, 0x72, 0x82, 0x9d, 0xe9, 0xb9, 0xb6, 0x38, 0x61, 0x21, + 0xdc, 0x19, 0x23, 0x6b, 0x93, 0xf9, 0x49, 0x12, 0xbf, 0xab, 0xc5, 0x10, + 0x73, 0x06, 0xbe, 0x8c, 0x78, 0xd6, 0x0b, 0xbb, 0xa6, 0xe2, 0x59, 0x90, + 0xce, 0xdc, 0x0e, 0x25, 0x61, 0x8f, 0xda, 0x49, 0x3d, 0x34, 0xb3, 0xf2, + 0xf2, 0xbd, 0xe3, 0xee, 0x6d, 0x21, 0x75, 0x6b, 0xf0, 0x5e, 0x2a, 0x0f, + 0x5d, 0xaf, 0x75, 0xf1, 0xba, 0x0a, 0xef, 0x3a, 0x7a, 0xf2, 0xa5, 0x26, + 0x4f, 0xf9, 0xc4, 0x7c, 0xb8, 0x25, 0xb8, 0x22, 0xf1, 0x32, 0x1c, 0xa1, + 0xf9, 0xa8, 0xa7, 0xe6, 0xcf, 0x11, 0xa7, 0x09, 0x49, 0xb6, 0x3c, 0x5b, + 0x09, 0x59, 0xb0, 0x46, 0x81, 0x5a, 0xe0, 0x82, 0xd2, 0x84, 0x5a, 0x61, + 0xc0, 0x75, 0xa0, 0x56, 0xb3, 0x8d, 0x38, 0x79, 0x15, 0x3d, 0x80, 0x5c, + 0x0b, 0x00, 0x49, 0x84, 0xaa, 0xdb, 0xe4, 0x95, 0x4b, 0x29, 0xeb, 0xfc, + 0x67, 0x07, 0xd3, 0x53, 0x4a, 0xd0, 0x40, 0xb3, 0xb2, 0x2b, 0x29, 0xff, + 0xae, 0x6c, 0x25, 0x17, 0x1d, 0xe6, 0x51, 0x48, 0x65, 0x10, 0x2b, 0xf8, + 0x00, 0xad, 0x7a, 0x2d, 0x34, 0xe3, 0xe1, 0xf4, 0x93, 0x63, 0x32, 0xa4, + 0xce, 0xac, 0x3a, 0x8e, 0xc2, 0x60, 0xf1, 0x9c, 0xa8, 0xe4, 0x10, 0x35, + 0xcd, 0xc9, 0x5d, 0xe2, 0xca, 0x4c, 0x2d, 0x83, 0x4b, 0x26, 0x2a, 0xd0, + 0xd7, 0x3e, 0x90, 0x3f, 0x20, 0x07, 0x28, 0x4e, 0x52, 0x28, 0xe8, 0x5d, + 0x73, 0x71, 0xcf, 0x38, 0xa8, 0xbd, 0x43, 0xc2, 0x31, 0x6e, 0x4f, 0x27, + 0x02, 0xbb, 0xe0, 0x8a, 0x9c, 0xee, 0x5b, 0x98, 0x5a, 0xf8, 0xeb, 0xe0, + 0xc9, 0x4e, 0x47, 0xe6, 0xda, 0xb9, 0xb9, 0xb9, 0xe9, 0x47, 0x8f, 0x91, + 0xf3, 0xc0, 0x9c, 0xfb, 0xf4, 0x3d, 0xfc, 0x15, 0x1e, 0x69, 0x8b, 0xb1, + 0x68, 0x60, 0x70, 0x78, 0x87, 0xac, 0xba, 0x63, 0x35, 0xa0, 0x55, 0x4f, + 0x69, 0x98, 0x34, 0xd3, 0xcc, 0x66, 0x67, 0x56, 0xbc, 0xa3, 0x5f, 0x3b, + 0x72, 0x87, 0x75, 0x5e, 0x9f, 0xbe, 0x3b, 0x7b, 0x73, 0xfa, 0x97, 0xbf, + 0x76, 0x38, 0xd9, 0x57, 0xb9, 0x47, 0xce, 0xb8, 0x7d, 0xbe, 0x17, 0x35, + 0x08, 0x4b, 0xbd, 0x5d, 0xee, 0x83, 0xc3, 0x1e, 0x84, 0x82, 0xd4, 0xce, + 0x5a, 0x89, 0xaf, 0x6b, 0x56, 0x48, 0xbf, 0xb4, 0x65, 0x78, 0x5c, 0x3b, + 0x9d, 0x80, 0x51, 0x21, 0xd3, 0x49, 0x42, 0x00, 0x7b, 0xa8, 0x6a, 0x9f, + 0x39, 0xf2, 0x13, 0x67, 0xe9, 0x72, 0x61, 0xf4, 0x46, 0x64, 0x68, 0x72, + 0x74, 0xf2, 0xec, 0x8d, 0xa2, 0x87, 0xd4, 0x02, 0x8d, 0x94, 0x3a, 0x75, + 0x05, 0x05, 0xc8, 0x03, 0x9c, 0x95, 0xe9, 0xac, 0xd5, 0x04, 0xab, 0xb8, + 0x91, 0x3b, 0x46, 0x62, 0xbc, 0x2d, 0xf3, 0x23, 0x58, 0x67, 0x7c, 0xc9, + 0x0d, 0x0d, 0x84, 0x1b, 0x10, 0x44, 0x07, 0x25, 0xda, 0x8b, 0xae, 0x1b, + 0xb2, 0x16, 0x15, 0x86, 0x2b, 0x9f, 0x45, 0xc1, 0x47, 0xd3, 0x39, 0xd6, + 0x12, 0x41, 0xd1, 0xd4, 0xd9, 0xa6, 0x93, 0xce, 0xee, 0x37, 0x7b, 0xfd, + 0xdd, 0xc7, 0x4f, 0xb0, 0x04, 0xf9, 0xf6, 0xee, 0xe3, 0x8e, 0x68, 0xca, + 0x4c, 0x5a, 0xa4, 0xce, 0xdb, 0x8a, 0x88, 0xe1, 0x29, 0x0a, 0xf2, 0xd7, + 0xd7, 0x3b, 0x1a, 0xa1, 0xaa, 0xdc, 0xe1, 0xae, 0x8a, 0xeb, 0x61, 0x6a, + 0x9f, 0xe4, 0xb2, 0x93, 0x1e, 0x88, 0x68, 0x65, 0x1a, 0x9d, 0xb5, 0x0d, + 0x26, 0x1f, 0x02, 0x7c, 0x38, 0x06, 0x8a, 0x44, 0x01, 0x48, 0xe8, 0xbc, + 0x79, 0x7d, 0xf1, 0xf2, 0xd5, 0x52, 0x34, 0x05, 0xb2, 0x9f, 0x96, 0x2f, + 0x0c, 0x86, 0xc6, 0x80, 0x81, 0xe0, 0x70, 0xe4, 0x97, 0x33, 0x31, 0x1a, + 0xbf, 0xca, 0x87, 0x65, 0x51, 0x15, 0xe3, 0x50, 0xd2, 0xc4, 0xac, 0xbd, + 0x27, 0x27, 0xa0, 0x2c, 0xdc, 0x64, 0x03, 0x8d, 0xeb, 0xeb, 0x93, 0x8b, + 0x34, 0xaf, 0x5c, 0x39, 0x05, 0x98, 0x65, 0x9e, 0xd5, 0x54, 0x64, 0x4c, + 0x21, 0x1f, 0xba, 0x18, 0xc6, 0x8a, 0x8f, 0x67, 0x52, 0xc7, 0x80, 0xcd, + 0x7b, 0xd8, 0xd7, 0x70, 0x42, 0xb7, 0x75, 0x32, 0xcf, 0x0a, 0xba, 0x4b, + 0xcc, 0x7d, 0x60, 0x57, 0xad, 0x0b, 0x6b, 0x25, 0x8c, 0x5c, 0x0d, 0xfc, + 0xc8, 0x4b, 0x64, 0x85, 0xa8, 0x22, 0x88, 0xaf, 0xe9, 0x3d, 0x86, 0x4e, + 0x20, 0xad, 0x69, 0x22, 0xa0, 0xec, 0x3b, 0x07, 0x6f, 0x90, 0xed, 0x6f, + 0x80, 0xa7, 0x7f, 0x54, 0x94, 0x9c, 0x55, 0x40, 0xc8, 0x2a, 0x12, 0xda, + 0x91, 0xcd, 0x86, 0xc5, 0xa2, 0xc4, 0xfc, 0x72, 0x1c, 0xcf, 0x2d, 0xd7, + 0x3f, 0xb8, 0x62, 0x37, 0xb3, 0xac, 0x11, 0x2d, 0x64, 0x90, 0x90, 0x25, + 0x0b, 0x4a, 0x6a, 0x3d, 0xd3, 0x4a, 0x85, 0x9b, 0x78, 0x09, 0x65, 0x8b, + 0x57, 0x3c, 0x78, 0x74, 0xc8, 0x40, 0xa4, 0x21, 0x91, 0xcf, 0xf2, 0x4b, + 0xc6, 0xbd, 0xf3, 0xc1, 0xe9, 0x04, 0x07, 0x1d, 0x44, 0x52, 0xea, 0x5d, + 0xc4, 0x85, 0x52, 0xb8, 0x43, 0xdc, 0x09, 0x87, 0xec, 0xcd, 0xbc, 0xd5, + 0x50, 0x82, 0x87, 0x80, 0x5e, 0x1a, 0x7a, 0x0f, 0x7c, 0xf2, 0x9b, 0x4b, + 0x87, 0x52, 0x23, 0x6b, 0x81, 0xa2, 0x98, 0xfc, 0x80, 0x6f, 0x7c, 0xac, + 0xe1, 0xfa, 0x62, 0x29, 0x20, 0xd2, 0x3b, 0xb1, 0xdb, 0x6a, 0xe6, 0x49, + 0x44, 0x95, 0x8f, 0xc7, 0xa2, 0xbf, 0x46, 0xb4, 0xcc, 0x51, 0xe8, 0x82, + 0xc4, 0x5a, 0xf5, 0x97, 0x0e, 0x1b, 0x2f, 0x9a, 0x3f, 0x71, 0xbd, 0x9b, + 0x41, 0x74, 0xe8, 0x9e, 0x65, 0x88, 0x48, 0xec, 0xa5, 0xb1, 0xc0, 0x33, + 0x9f, 0xf4, 0x9f, 0x38, 0x9d, 0xfb, 0x58, 0x14, 0x69, 0xda, 0xc2, 0x29, + 0xf9, 0x29, 0x45, 0x6e, 0xac, 0xea, 0xdb, 0x49, 0x66, 0x2b, 0x83, 0x9a, + 0x8e, 0x5c, 0x71, 0x57, 0x29, 0xb1, 0xd9, 0x06, 0xb8, 0x45, 0x83, 0xa8, + 0x18, 0x31, 0x2d, 0xb8, 0x6c, 0xb3, 0x0f, 0x20, 0xf0, 0xd4, 0x7a, 0x7f, + 0xa1, 0x8c, 0x4c, 0x17, 0x3c, 0x7d, 0x8a, 0xe7, 0xed, 0xc6, 0xb2, 0x6c, + 0x30, 0x4f, 0x60, 0xc9, 0x9c, 0xc6, 0x73, 0xfc, 0x2c, 0x64, 0x81, 0xed, + 0x7c, 0x04, 0x65, 0xf8, 0x80, 0x11, 0x5c, 0x88, 0x28, 0xf2, 0xcd, 0xef, + 0x43, 0x81, 0x2b, 0xb0, 0xd7, 0x1b, 0x64, 0xa0, 0x21, 0x94, 0xc9, 0xd3, + 0x1a, 0x05, 0xf3, 0x65, 0xb0, 0x1b, 0xc3, 0xba, 0x49, 0x34, 0x2b, 0xc9, + 0x01, 0xb0, 0xff, 0xc0, 0xef, 0x5e, 0x90, 0x4c, 0x8f, 0xe7, 0xe9, 0x14, + 0x61, 0x32, 0x92, 0x64, 0xaf, 0xbf, 0x73, 0x17, 0xd8, 0x0d, 0x07, 0x73, + 0xc9, 0xcb, 0xf2, 0x76, 0xe0, 0x8c, 0xe4, 0x64, 0x08, 0x26, 0xea, 0x86, + 0x3d, 0xc2, 0xa2, 0x91, 0xa4, 0x5e, 0x86, 0x78, 0x32, 0xe3, 0x24, 0x7b, + 0x44, 0x5f, 0xd5, 0x2b, 0xb1, 0xd7, 0x23, 0x95, 0x5f, 0x39, 0x58, 0x14, + 0xde, 0x18, 0x85, 0xf7, 0x46, 0x93, 0xc1, 0x55, 0x0b, 0x81, 0x92, 0xa5, + 0x06, 0xc5, 0x11, 0x37, 0x1a, 0x0e, 0xa9, 0xaa, 0x00, 0xa9, 0x3f, 0x84, + 0x59, 0xf3, 0xf8, 0xeb, 0x47, 0x3b, 0x7d, 0x57, 0xa2, 0x3b, 0x5e, 0xd9, + 0xbb, 0x52, 0x00, 0xe2, 0xfb, 0x8f, 0x2f, 0xc0, 0xc8, 0x2d, 0x78, 0x37, + 0x79, 0xc4, 0x1d, 0x75, 0xa6, 0xcf, 0xdf, 0x7d, 0xd3, 0xff, 0xe1, 0xd1, + 0xb8, 0xf7, 0xb0, 0xbf, 0xfb, 0x5f, 0x7f, 0x7f, 0xd5, 0xf9, 0x84, 0x98, + 0x49, 0x21, 0x97, 0x91, 0x32, 0x51, 0x5a, 0xb2, 0xa2, 0x1b, 0xcc, 0xaa, + 0xbe, 0xee, 0xc2, 0x4f, 0x25, 0xa2, 0x6b, 0xc9, 0x17, 0x62, 0x79, 0x0f, + 0xe5, 0x29, 0x3d, 0x3a, 0x6e, 0x55, 0x8f, 0xe0, 0xb1, 0x7e, 0x00, 0x30, + 0x2f, 0x33, 0x9f, 0xea, 0x82, 0xde, 0xff, 0x81, 0xac, 0xe8, 0x38, 0xc3, + 0x0b, 0xc1, 0x0e, 0x8e, 0x5e, 0x03, 0x55, 0xd7, 0x5f, 0x31, 0x8c, 0x74, + 0x8a, 0xfd, 0x69, 0xf0, 0x04, 0x37, 0x74, 0xeb, 0xf1, 0x93, 0x92, 0xce, + 0xef, 0x3a, 0x1a, 0x0f, 0xa0, 0x57, 0x64, 0x6a, 0x82, 0x54, 0x3e, 0x73, + 0x39, 0xb1, 0x82, 0x2e, 0x71, 0x61, 0xee, 0x27, 0x13, 0x30, 0xf3, 0x4a, + 0x6e, 0x82, 0x32, 0x23, 0x90, 0xc9, 0x51, 0x12, 0x2a, 0xd9, 0x6b, 0x3c, + 0x7b, 0xa2, 0xb5, 0x8c, 0x42, 0x74, 0x07, 0x0c, 0xcb, 0x63, 0xaa, 0xd0, + 0xa4, 0x90, 0x49, 0xbc, 0x44, 0x28, 0xb6, 0x7c, 0x16, 0x7c, 0xf9, 0x1d, + 0xdc, 0x23, 0xd8, 0xa2, 0x7f, 0xc2, 0x2d, 0xd9, 0x05, 0xb1, 0xee, 0x5f, + 0xde, 0x51, 0xde, 0x41, 0xf3, 0x43, 0x07, 0x07, 0xf8, 0xee, 0x77, 0xbb, + 0x58, 0x59, 0x52, 0x2b, 0x1b, 0x17, 0x64, 0xc1, 0x34, 0x6a, 0x0a, 0x92, + 0x37, 0xda, 0x7c, 0x5a, 0x1a, 0x47, 0x18, 0xb4, 0x2e, 0x2a, 0x18, 0xff, + 0xea, 0xe3, 0xcf, 0xbf, 0xed, 0xf6, 0x1e, 0xfd, 0x12, 0xc4, 0x26, 0xec, + 0xe4, 0x77, 0xbb, 0xef, 0x7e, 0xb7, 0xd7, 0x71, 0x30, 0x54, 0x0e, 0x65, + 0xd7, 0x65, 0x82, 0x55, 0x94, 0x15, 0xa8, 0x6a, 0x6a, 0x1a, 0x27, 0xd2, + 0xc2, 0x46, 0xc3, 0xbc, 0x2b, 0xa7, 0xab, 0x63, 0x24, 0x47, 0x53, 0x91, + 0xd1, 0x52, 0xc5, 0x9a, 0xa1, 0x83, 0xb1, 0x97, 0xfc, 0x5e, 0x54, 0xc9, + 0x77, 0x39, 0x00, 0x22, 0x88, 0xf6, 0x38, 0x2e, 0x04, 0x99, 0x57, 0xc4, + 0xef, 0x30, 0x63, 0x98, 0x4a, 0x9a, 0x26, 0x51, 0x24, 0x41, 0x91, 0x0c, + 0x06, 0x89, 0x0b, 0x20, 0xf8, 0x2a, 0x04, 0x6d, 0x62, 0x67, 0x6c, 0x3b, + 0x50, 0x66, 0x51, 0x58, 0x28, 0x88, 0x7e, 0x4f, 0x23, 0x0b, 0xf1, 0xad, + 0xc4, 0x04, 0x40, 0xbb, 0x44, 0xd8, 0xe9, 0x46, 0x71, 0xe8, 0x71, 0x5e, + 0xe2, 0x8d, 0x08, 0x6d, 0xe4, 0x55, 0x20, 0x05, 0xfe, 0xd4, 0x62, 0x7c, + 0x30, 0x12, 0x0c, 0xc5, 0x0b, 0x85, 0x34, 0x4e, 0x07, 0xc5, 0x75, 0x90, + 0xce, 0x2d, 0xea, 0x82, 0xa6, 0x49, 0x07, 0x14, 0x98, 0x9b, 0x16, 0x1e, + 0x01, 0x01, 0x53, 0xe7, 0xe9, 0x67, 0xe8, 0x01, 0x2e, 0x78, 0xfe, 0x34, + 0xe7, 0xe6, 0x49, 0x67, 0x66, 0xc8, 0x0e, 0xac, 0x1e, 0xa5, 0x3c, 0x5a, + 0x61, 0x80, 0x42, 0xfd, 0x5a, 0x0c, 0x7c, 0x45, 0xc8, 0xbe, 0x0e, 0x14, + 0x5a, 0xc4, 0xda, 0x5b, 0x38, 0x25, 0x1c, 0xac, 0xdc, 0xd7, 0x5b, 0xc0, + 0xe0, 0x3b, 0xd5, 0xe9, 0x52, 0x25, 0x1b, 0xbd, 0x0d, 0x4c, 0x8e, 0x52, + 0xa5, 0x1c, 0x2b, 0x54, 0x6f, 0x71, 0xa0, 0xa8, 0x57, 0x67, 0x02, 0xd3, + 0x10, 0xd6, 0xa0, 0x8c, 0x98, 0x05, 0x16, 0xd2, 0x61, 0x02, 0xee, 0x64, + 0x31, 0xca, 0xb3, 0x2a, 0x6c, 0xbf, 0xa1, 0x7e, 0x86, 0x56, 0xb6, 0x47, + 0xd9, 0xf5, 0xf6, 0x6c, 0x31, 0x99, 0x1c, 0xb4, 0x2e, 0x51, 0xcf, 0x3d, + 0xa1, 0xd1, 0xbf, 0x6c, 0x30, 0x92, 0xf8, 0xdb, 0x95, 0xaf, 0xc1, 0x1b, + 0x5f, 0x2d, 0x57, 0x1e, 0x09, 0x65, 0xba, 0xe9, 0xbe, 0xd1, 0x98, 0x9d, + 0x69, 0x3e, 0x5b, 0x54, 0x92, 0x8e, 0x4b, 0xe6, 0xa0, 0xc8, 0x99, 0x6f, + 0x68, 0xd7, 0x34, 0x63, 0xae, 0xa4, 0x60, 0xfa, 0xa7, 0x1a, 0xfb, 0xb8, + 0xd8, 0x19, 0x9a, 0x72, 0xb5, 0xba, 0xb0, 0xbe, 0xce, 0xf0, 0x5b, 0x08, + 0xf0, 0xa2, 0x31, 0x81, 0x92, 0xc5, 0x8b, 0x08, 0xbb, 0x36, 0xfc, 0x16, + 0x96, 0xbf, 0xfd, 0xeb, 0x3c, 0xbb, 0xc4, 0xb9, 0xf4, 0x4c, 0x78, 0x94, + 0x36, 0xd1, 0x7c, 0x62, 0x21, 0x67, 0x0a, 0x7e, 0x2a, 0x93, 0x01, 0x8a, + 0xed, 0x93, 0x32, 0x84, 0xd5, 0x46, 0x30, 0x99, 0x06, 0x91, 0x68, 0x88, + 0x8e, 0x83, 0xe8, 0x83, 0x1b, 0xe2, 0xf9, 0x10, 0x9d, 0x95, 0xa5, 0x08, + 0xa2, 0xbb, 0x33, 0x0d, 0x8b, 0xd5, 0x09, 0x6c, 0xee, 0xb1, 0x8f, 0x65, + 0x93, 0x6d, 0xaf, 0xae, 0xcd, 0x04, 0xd7, 0x1b, 0x9e, 0x7e, 0xb7, 0xd7, + 0x16, 0xa5, 0xe4, 0x0e, 0x5f, 0x62, 0xf1, 0xb2, 0xfc, 0x9f, 0x25, 0x17, + 0xfa, 0x0a, 0x07, 0x7a, 0x12, 0x07, 0x06, 0x2f, 0xbb, 0x73, 0x83, 0x24, + 0x47, 0xbb, 0x89, 0x67, 0x3a, 0x79, 0x0a, 0x3f, 0x5a, 0x2a, 0xe5, 0xf8, + 0xec, 0x84, 0x60, 0x96, 0x12, 0xc7, 0x7b, 0x8c, 0x56, 0x84, 0xc6, 0xee, + 0x51, 0xd7, 0x0b, 0xb8, 0xd1, 0xe0, 0xf0, 0xea, 0x09, 0x3e, 0xd6, 0x32, + 0x8b, 0xa4, 0x94, 0x50, 0x7b, 0x46, 0x1e, 0x08, 0xdd, 0xaa, 0x78, 0x87, + 0x67, 0x0e, 0xe7, 0x47, 0xa4, 0xc2, 0x20, 0xa2, 0xfc, 0x68, 0x04, 0x5f, + 0x28, 0x9e, 0xd6, 0xb8, 0x5e, 0xd3, 0x62, 0x9e, 0x2c, 0x80, 0xda, 0x27, + 0x8e, 0xad, 0x4a, 0x71, 0x23, 0x5f, 0x31, 0xde, 0xcb, 0x82, 0x49, 0x8d, + 0x80, 0x05, 0x7e, 0x18, 0x8e, 0x93, 0x53, 0x88, 0x41, 0xb7, 0x11, 0x3f, + 0x28, 0xa1, 0x00, 0x94, 0x14, 0x61, 0xb5, 0x71, 0x62, 0xae, 0xc9, 0x1a, + 0xba, 0x56, 0x60, 0x09, 0x55, 0xd3, 0xdc, 0x2e, 0x7c, 0xb1, 0x48, 0x65, + 0xd7, 0x47, 0xa7, 0x9e, 0xce, 0x81, 0x6a, 0x4f, 0xd7, 0x73, 0x4c, 0x7c, + 0xdd, 0xf4, 0x92, 0xfb, 0x2d, 0x8d, 0x5c, 0xe5, 0x2d, 0x04, 0xf6, 0xdf, + 0x5d, 0x17, 0x64, 0x17, 0x52, 0x64, 0x04, 0xb7, 0x47, 0x70, 0xa7, 0xb8, + 0xd2, 0x78, 0xf0, 0x3b, 0x60, 0xbf, 0x21, 0x30, 0xaf, 0x52, 0xe3, 0x93, + 0x59, 0xd2, 0x0c, 0x87, 0xe4, 0x92, 0x92, 0x0f, 0x41, 0xd6, 0xc6, 0x1c, + 0xc9, 0x29, 0xd6, 0x36, 0xc4, 0x64, 0x89, 0x33, 0x7d, 0xd5, 0xf2, 0xbd, + 0x19, 0x87, 0x95, 0xaf, 0x5b, 0x06, 0x1c, 0x59, 0xe0, 0xdf, 0x8b, 0xb9, + 0xb9, 0x05, 0x08, 0xd6, 0x6a, 0xa6, 0x42, 0x99, 0x1b, 0x4a, 0x9c, 0xa3, + 0xe9, 0xc1, 0xa2, 0x29, 0x59, 0x92, 0x53, 0x07, 0xcb, 0x50, 0xcf, 0x75, + 0x86, 0x4d, 0xb9, 0xf7, 0xa9, 0xe6, 0x0d, 0xbc, 0x35, 0x51, 0x64, 0x16, + 0x34, 0x7f, 0xa1, 0x81, 0x1e, 0x6b, 0xa3, 0x53, 0xc8, 0xaa, 0x04, 0x3c, + 0x61, 0xf4, 0x67, 0xae, 0x7e, 0xc0, 0xd0, 0xc0, 0x38, 0x9f, 0xe5, 0x95, + 0x85, 0xc5, 0x22, 0x76, 0x64, 0x58, 0x9a, 0xf0, 0x98, 0xd0, 0xe2, 0x0a, + 0x27, 0x21, 0xe7, 0x26, 0x47, 0xc1, 0xb8, 0x34, 0x52, 0xea, 0x78, 0x44, + 0x99, 0xfb, 0xb2, 0x86, 0xae, 0x41, 0x06, 0x7b, 0x24, 0xf9, 0x75, 0xc4, + 0x98, 0x38, 0x0d, 0xc4, 0x0d, 0x33, 0xe7, 0xd5, 0x0b, 0x96, 0x59, 0x82, + 0xc6, 0x6a, 0xa3, 0xf7, 0x61, 0xa9, 0x9e, 0x9f, 0x5f, 0xb8, 0x0c, 0x7e, + 0xe4, 0x55, 0x0c, 0xf7, 0x4d, 0x56, 0x23, 0xbf, 0x0f, 0xd1, 0x4a, 0x72, + 0x95, 0x6f, 0xd4, 0x75, 0xa2, 0x88, 0x01, 0x5d, 0x0d, 0x4c, 0xfd, 0xe6, + 0x3c, 0xdc, 0x3a, 0x54, 0xbd, 0x25, 0x50, 0x89, 0xfe, 0x97, 0x2e, 0x8f, + 0xe6, 0xd5, 0xf7, 0xb0, 0x39, 0xeb, 0xe7, 0xb2, 0xdd, 0x85, 0x96, 0xeb, + 0x12, 0xaf, 0xef, 0x38, 0xdc, 0xd6, 0xeb, 0x1d, 0x97, 0xcd, 0x6e, 0xeb, + 0x97, 0x0c, 0xaa, 0xa4, 0xf7, 0x51, 0xf3, 0xf4, 0xa3, 0x5f, 0xf2, 0xb1, + 0x1e, 0xff, 0x90, 0x4c, 0xf2, 0x81, 0x43, 0xbd, 0x1c, 0xb6, 0x51, 0xb4, + 0x0b, 0xfe, 0xee, 0xb1, 0x2f, 0xf2, 0xe9, 0x14, 0x64, 0x2f, 0x0f, 0x61, + 0xb2, 0xfc, 0x95, 0x8b, 0x38, 0x63, 0xb2, 0x6c, 0xa7, 0xf5, 0x46, 0xd6, + 0x42, 0xde, 0xc0, 0xad, 0x36, 0x69, 0x89, 0xf3, 0xa9, 0x90, 0x43, 0x93, + 0xd7, 0x1b, 0x2e, 0x01, 0x02, 0x9b, 0xf5, 0xb9, 0xbf, 0x11, 0xa7, 0x11, + 0x69, 0x45, 0xea, 0x7e, 0xd0, 0x19, 0x11, 0x13, 0x42, 0x9a, 0xab, 0xd3, + 0x92, 0xb1, 0x67, 0xf3, 0xb1, 0x9c, 0xe0, 0x40, 0x9f, 0x06, 0x45, 0x27, + 0x81, 0x1f, 0x94, 0x62, 0x2d, 0x24, 0xf0, 0xc1, 0xb0, 0x47, 0x38, 0x4b, + 0x9d, 0xea, 0x7f, 0x09, 0x46, 0x83, 0x0b, 0x07, 0x92, 0xd5, 0xff, 0xc1, + 0xe1, 0xa4, 0xa8, 0x7f, 0xdf, 0x6b, 0x52, 0x70, 0x06, 0x24, 0x66, 0x93, + 0x27, 0x48, 0x64, 0x8e, 0x43, 0xa4, 0x8a, 0x90, 0x20, 0xef, 0x6b, 0x00, + 0x05, 0xd5, 0xe7, 0xd2, 0x21, 0xf0, 0x80, 0xdd, 0x79, 0x22, 0xa3, 0x16, + 0xdd, 0x64, 0xb4, 0xd2, 0x51, 0x62, 0x3e, 0x16, 0x38, 0xc7, 0xe0, 0x98, + 0x65, 0x2f, 0x02, 0xd0, 0xbd, 0x5f, 0x3f, 0xcc, 0x0e, 0x13, 0x1d, 0x06, + 0x6b, 0xbf, 0xce, 0xf8, 0x64, 0x94, 0x79, 0xf5, 0x5e, 0xc0, 0x04, 0xb5, + 0xfa, 0x97, 0xcc, 0x5f, 0x4a, 0xd1, 0x59, 0xb1, 0x33, 0xe4, 0x86, 0x8b, + 0xf9, 0xff, 0x25, 0x27, 0x34, 0x90, 0xdd, 0x67, 0x82, 0x71, 0x6f, 0x25, + 0xf5, 0x35, 0x0e, 0xad, 0x1b, 0x48, 0xef, 0xbf, 0xef, 0x3e, 0xc1, 0x2b, + 0xf1, 0xa9, 0x57, 0x9e, 0x60, 0x38, 0xc0, 0x4f, 0x1a, 0xf7, 0x77, 0x23, + 0xe6, 0xdd, 0x1f, 0xdd, 0xe5, 0xb3, 0x89, 0xe7, 0xd9, 0x01, 0x0c, 0x71, + 0xe9, 0x8a, 0xea, 0x3d, 0xdf, 0xc5, 0xa3, 0x22, 0x9c, 0x1e, 0x77, 0x3e, + 0xd9, 0x9d, 0x15, 0x1a, 0xe9, 0xb6, 0x64, 0xd3, 0xa3, 0x5f, 0xb3, 0xc4, + 0xb2, 0xc2, 0x1e, 0xd2, 0x2b, 0x94, 0x7d, 0x08, 0x74, 0xca, 0xdd, 0xb4, + 0x43, 0x25, 0x30, 0xf2, 0x0a, 0x07, 0x30, 0x40, 0x07, 0xc0, 0xea, 0x93, + 0xfd, 0x9d, 0x1d, 0x75, 0xd2, 0x13, 0xe4, 0x54, 0x55, 0x3b, 0xa8, 0x00, + 0x12, 0x97, 0xfa, 0xff, 0x96, 0x6a, 0x99, 0x31, 0x43, 0xfc, 0x8c, 0x68, + 0x2b, 0xab, 0x88, 0x08, 0xfb, 0xc1, 0xf0, 0xd3, 0x15, 0x24, 0xb4, 0xb2, + 0xfa, 0xaa, 0xa7, 0x94, 0xc7, 0x2b, 0x28, 0xc5, 0x91, 0x05, 0x08, 0x17, + 0x4f, 0xe7, 0x57, 0x65, 0x5a, 0x59, 0x9d, 0xe2, 0xf3, 0xf3, 0x17, 0x09, + 0xc5, 0x9e, 0x9c, 0xc1, 0x97, 0xfc, 0x95, 0x2b, 0xe1, 0xe3, 0x8a, 0x0e, + 0x6b, 0x5e, 0x1e, 0x35, 0xf2, 0xc5, 0x70, 0x99, 0xa8, 0x75, 0x4e, 0xff, + 0x94, 0xe2, 0xc0, 0xeb, 0xa3, 0x9c, 0xe0, 0xd3, 0x2d, 0x59, 0x91, 0x98, + 0xa0, 0xd8, 0x4b, 0xab, 0x9e, 0x8a, 0xe6, 0xcf, 0x0a, 0x4d, 0x58, 0x46, + 0xb9, 0x0e, 0x3a, 0xfb, 0xfb, 0x02, 0x31, 0x23, 0xb8, 0x58, 0xd9, 0x76, + 0xbf, 0xbf, 0x4d, 0x56, 0xb6, 0x6d, 0xfc, 0x57, 0xd3, 0xbd, 0x59, 0xb5, + 0x21, 0x53, 0x0e, 0xb6, 0xd6, 0xd7, 0xe0, 0x12, 0x0c, 0xcb, 0x9f, 0x48, + 0x89, 0xd9, 0xea, 0xef, 0x8b, 0xb4, 0x22, 0xd8, 0x32, 0x14, 0xa6, 0x32, + 0x24, 0x5e, 0x8e, 0x01, 0x8d, 0xed, 0xc6, 0x1a, 0xa0, 0x4f, 0x9e, 0x9a, + 0x38, 0xe6, 0x2e, 0x06, 0xb6, 0xad, 0xa5, 0xe4, 0x28, 0x55, 0xf1, 0x40, + 0x86, 0xa5, 0xc5, 0x43, 0xf1, 0x40, 0x91, 0x30, 0xdc, 0x16, 0x47, 0x15, + 0x26, 0xbb, 0xc2, 0x05, 0xb1, 0x9a, 0x21, 0x32, 0x47, 0x8c, 0xea, 0x0a, + 0x10, 0x5b, 0xd4, 0x06, 0xef, 0xdb, 0x38, 0xeb, 0xb8, 0xcd, 0x12, 0x01, + 0xcb, 0x0a, 0xff, 0xcb, 0xea, 0xe1, 0x36, 0x79, 0x32, 0x46, 0x6d, 0xa5, + 0x2f, 0x28, 0x99, 0xac, 0xc7, 0x9a, 0x5b, 0xd8, 0xbd, 0x1c, 0xae, 0xab, + 0xd1, 0x7c, 0x31, 0xc0, 0xdd, 0x7d, 0x7a, 0x45, 0x4b, 0x1c, 0xd5, 0xd8, + 0x7e, 0x2b, 0x35, 0xe7, 0xc2, 0x01, 0x17, 0x67, 0x62, 0x62, 0xd4, 0xb3, + 0x09, 0x3b, 0xc2, 0x6f, 0x6e, 0xe1, 0x02, 0x12, 0xae, 0xaf, 0xc7, 0xd1, + 0x9e, 0x67, 0xa8, 0x79, 0x18, 0x40, 0xcc, 0x80, 0xa2, 0x52, 0xd2, 0x5a, + 0xbd, 0x93, 0xd4, 0x46, 0x23, 0x9e, 0x23, 0xa4, 0x6b, 0x71, 0x6f, 0x8a, + 0x56, 0x72, 0x8b, 0x34, 0x83, 0xf5, 0xb5, 0x91, 0xc9, 0x60, 0x85, 0x6b, + 0x76, 0x1f, 0x50, 0xb0, 0x07, 0xd9, 0x4f, 0xc3, 0x45, 0x8c, 0x7e, 0xd8, + 0xc7, 0x0f, 0xc9, 0x67, 0xca, 0x8c, 0xe5, 0x2a, 0xdd, 0x7b, 0xf4, 0x58, + 0xcd, 0xa7, 0x44, 0x4a, 0x52, 0xad, 0x93, 0x1c, 0xca, 0x1b, 0xfc, 0xfd, + 0xf6, 0xf6, 0x86, 0x40, 0xc2, 0x68, 0x90, 0x0d, 0x7e, 0xf7, 0x87, 0x8d, + 0x08, 0x84, 0x42, 0x3d, 0x76, 0x0a, 0x09, 0x8c, 0xd1, 0xa9, 0x54, 0x42, + 0xfe, 0xfc, 0xa5, 0x17, 0x15, 0x44, 0xef, 0x10, 0x5f, 0x8d, 0x20, 0xc3, + 0xab, 0x0f, 0xda, 0x97, 0x4b, 0x97, 0x0a, 0x4f, 0xd4, 0x1c, 0x86, 0x1e, + 0x28, 0xc0, 0x38, 0xe6, 0x33, 0x99, 0xf3, 0xd6, 0x4a, 0xb8, 0x13, 0x85, + 0x0d, 0x2d, 0x97, 0x51, 0x00, 0x26, 0x70, 0x71, 0x5d, 0x93, 0x24, 0xeb, + 0x8f, 0x93, 0x28, 0xc6, 0x5e, 0x73, 0x48, 0x38, 0xfc, 0x80, 0x19, 0x50, + 0x63, 0x75, 0x03, 0x1f, 0x26, 0xb7, 0x43, 0x38, 0x32, 0x8a, 0x8b, 0xe0, + 0xd1, 0x05, 0x3d, 0xe4, 0x0a, 0x23, 0x2d, 0x86, 0x4a, 0x40, 0x38, 0x17, + 0xca, 0x55, 0x46, 0x5c, 0x56, 0xae, 0xa1, 0x79, 0x4b, 0x29, 0x2b, 0x2b, + 0x2e, 0x18, 0x58, 0x82, 0x8c, 0xc2, 0x36, 0x44, 0xd3, 0x91, 0x6f, 0x5c, + 0x84, 0x94, 0xf9, 0x9c, 0xc9, 0x78, 0x1e, 0xea, 0x0d, 0x87, 0x32, 0x0e, + 0x52, 0x9a, 0xaa, 0x56, 0x84, 0x47, 0xa4, 0x3b, 0x0a, 0x75, 0x22, 0x70, + 0x59, 0x86, 0x9b, 0xe6, 0x0d, 0x0d, 0x4b, 0xaa, 0xc3, 0x01, 0x9a, 0xda, + 0x46, 0x7a, 0x92, 0xeb, 0xf0, 0x40, 0x8d, 0x99, 0x30, 0x26, 0xdc, 0x55, + 0xd2, 0x6c, 0x7f, 0x9c, 0x2d, 0x60, 0xa7, 0xd1, 0x84, 0x53, 0x4c, 0xc6, + 0xf0, 0x29, 0xfc, 0x06, 0xc4, 0x36, 0xc2, 0xdd, 0xef, 0xe2, 0x59, 0x1b, + 0x52, 0x5d, 0xe3, 0x0b, 0xbc, 0x9c, 0xb9, 0xa2, 0xc3, 0x34, 0x1d, 0x9e, + 0x9e, 0x6b, 0x65, 0xdc, 0xfe, 0xd7, 0xbf, 0xdf, 0xce, 0x4f, 0xcf, 0xe1, + 0xb7, 0xdf, 0x77, 0x93, 0x73, 0x84, 0xfb, 0x9d, 0x65, 0x6a, 0x02, 0x65, + 0xda, 0x5b, 0xd1, 0x79, 0x57, 0x7b, 0x96, 0xa0, 0x9e, 0xa5, 0xde, 0x7f, + 0x63, 0xe7, 0xa7, 0xb4, 0x6a, 0x44, 0xbb, 0x88, 0x92, 0x43, 0x54, 0xca, + 0x60, 0xa4, 0x71, 0xa9, 0xfb, 0x06, 0xb3, 0xf8, 0x72, 0xa5, 0x66, 0xa3, + 0x6e, 0xe0, 0xff, 0xeb, 0xd8, 0x31, 0x1b, 0x6f, 0xd9, 0x69, 0x1e, 0x66, + 0xbb, 0xbb, 0x4f, 0x06, 0x8f, 0x76, 0x9f, 0x7c, 0xf3, 0xf5, 0xf8, 0xe1, + 0xc3, 0x47, 0x7b, 0xa3, 0xe1, 0xc6, 0xc7, 0xd4, 0x31, 0x41, 0x7b, 0x26, + 0x34, 0xc9, 0xad, 0x05, 0xa6, 0xc9, 0xd5, 0x97, 0x22, 0x4f, 0xfb, 0x1b, + 0xaa, 0xe9, 0x59, 0x73, 0xb5, 0x8d, 0xaf, 0xf7, 0xf6, 0x77, 0xb7, 0x1f, + 0xf7, 0x1f, 0xf6, 0xf7, 0x54, 0x64, 0x62, 0xc8, 0x3a, 0x06, 0x34, 0xae, + 0x13, 0x4e, 0x4b, 0xb5, 0x04, 0x5f, 0x8d, 0xb8, 0x90, 0x4a, 0x51, 0xae, + 0x76, 0x14, 0x5b, 0x3f, 0x42, 0xea, 0x2d, 0x95, 0x8f, 0xda, 0x0d, 0xc0, + 0x91, 0x8a, 0xdf, 0x81, 0x30, 0xb7, 0xd0, 0xb1, 0xba, 0xc6, 0x14, 0x63, + 0x9a, 0xd0, 0x29, 0x07, 0xf9, 0xdf, 0x17, 0x79, 0x0d, 0xa2, 0xa1, 0x98, + 0x28, 0xb3, 0x01, 0x3e, 0x53, 0x16, 0x37, 0x95, 0x60, 0x5e, 0x15, 0xaa, + 0x1a, 0x72, 0x0d, 0xb3, 0x08, 0x53, 0x49, 0x71, 0x7b, 0x3c, 0xa4, 0x36, + 0x95, 0x77, 0xcc, 0x89, 0x53, 0xe3, 0x23, 0x15, 0x16, 0xb2, 0x9c, 0x0d, + 0x91, 0x5b, 0xbd, 0x00, 0x05, 0xe6, 0x1a, 0xbd, 0x38, 0x69, 0x5c, 0xa7, + 0xc2, 0x07, 0x9c, 0x4a, 0x4e, 0x2e, 0x85, 0xb8, 0x52, 0x2c, 0x9f, 0x7c, + 0xc0, 0x99, 0x41, 0x1c, 0x6d, 0x12, 0x01, 0x71, 0xf2, 0xd5, 0x11, 0xe1, + 0x5c, 0x72, 0x80, 0x60, 0x96, 0xa2, 0xe6, 0x4a, 0x15, 0xc4, 0x39, 0x7c, + 0x51, 0x96, 0x4b, 0x02, 0xc6, 0x1c, 0x90, 0x64, 0x5b, 0x9c, 0xa8, 0x6c, + 0xe2, 0x27, 0x64, 0xd7, 0xaf, 0xba, 0xca, 0xb9, 0xc1, 0x7b, 0xee, 0x71, + 0xe9, 0xd5, 0x61, 0x62, 0xf6, 0x46, 0x49, 0x07, 0x39, 0xe3, 0xba, 0x61, + 0x56, 0x5c, 0xea, 0xab, 0x1b, 0xea, 0x7c, 0x89, 0x54, 0xd6, 0x84, 0xcd, + 0xd4, 0x27, 0xd7, 0x20, 0xd3, 0xfd, 0x2f, 0x41, 0xa6, 0x7b, 0xff, 0x1f, + 0x99, 0x7e, 0x36, 0x32, 0xdd, 0xfb, 0xdc, 0x64, 0xba, 0xb7, 0x0e, 0x99, + 0xee, 0xfd, 0x66, 0x32, 0xdd, 0x5d, 0x9b, 0x4c, 0xf7, 0x23, 0x32, 0xfd, + 0x73, 0x5e, 0x4c, 0xc8, 0xf6, 0x10, 0x91, 0xe9, 0xc3, 0xcf, 0x4c, 0xa6, + 0x58, 0x5c, 0x30, 0x22, 0xd2, 0xc3, 0x20, 0xad, 0x19, 0xbe, 0x5f, 0x20, + 0x08, 0xa3, 0x88, 0x40, 0x12, 0x9e, 0x26, 0x98, 0xea, 0xf7, 0x63, 0x9a, + 0xf8, 0x92, 0x44, 0xb1, 0xff, 0xb9, 0x89, 0x62, 0x7f, 0x1d, 0xa2, 0xd8, + 0xff, 0x9c, 0xbc, 0x6b, 0x77, 0x25, 0x51, 0x94, 0x19, 0x87, 0x0f, 0xfe, + 0x4d, 0xe3, 0x33, 0xa1, 0xed, 0x5f, 0xc8, 0xbd, 0x78, 0x80, 0x42, 0xc9, + 0x2f, 0x01, 0x11, 0x84, 0x85, 0x6c, 0x53, 0x4f, 0xce, 0x4f, 0x8f, 0xfe, + 0x78, 0xae, 0x21, 0xd1, 0x86, 0x00, 0x2e, 0xa2, 0x2a, 0x63, 0x30, 0x53, + 0xec, 0x33, 0xa3, 0xc6, 0x6b, 0xf8, 0x12, 0x65, 0xb2, 0x59, 0x10, 0x2b, + 0xe5, 0x85, 0xeb, 0x19, 0x1f, 0xa2, 0xce, 0x2e, 0x88, 0xa5, 0xe4, 0x1c, + 0x8b, 0x30, 0x0a, 0xa9, 0x77, 0xea, 0xd3, 0x87, 0x62, 0x6b, 0x9d, 0xad, + 0x59, 0x12, 0x9e, 0xde, 0xac, 0xaf, 0x4a, 0xc2, 0x8b, 0xe3, 0xc7, 0xb7, + 0xc2, 0xeb, 0x3a, 0x14, 0x19, 0x86, 0x6b, 0xa8, 0x9f, 0xbc, 0x20, 0xc0, + 0x45, 0x58, 0x8e, 0x44, 0xe3, 0x6b, 0xcd, 0xb8, 0x63, 0x1f, 0x6a, 0x98, + 0x4c, 0x5b, 0x71, 0x11, 0x71, 0x3e, 0xbb, 0x55, 0x64, 0xd3, 0x6f, 0xfe, + 0xc1, 0xdc, 0x3b, 0x1a, 0x30, 0x92, 0x4e, 0xc8, 0x43, 0x4e, 0x85, 0xfb, + 0xb8, 0x5d, 0x7d, 0xab, 0x62, 0x8f, 0x75, 0x55, 0x0c, 0xdf, 0x57, 0x0f, + 0xa1, 0x09, 0x62, 0xc7, 0xf8, 0x7b, 0x8a, 0x7f, 0x88, 0xf4, 0x87, 0x1f, + 0x3c, 0xc2, 0xf6, 0x11, 0xd6, 0x95, 0xfe, 0xb8, 0xa2, 0xde, 0x88, 0x85, + 0x72, 0xa5, 0x49, 0xbf, 0x55, 0x43, 0xd9, 0x29, 0x83, 0xee, 0x55, 0xc3, + 0xb4, 0xe0, 0x67, 0x60, 0x1e, 0x4d, 0xa8, 0xc7, 0x16, 0x26, 0xe4, 0x2a, + 0x5b, 0x28, 0xab, 0x87, 0x1e, 0xa8, 0xad, 0x87, 0x0d, 0x87, 0x25, 0x0b, + 0xc2, 0xa2, 0x12, 0xe6, 0x52, 0x9e, 0xd5, 0x79, 0x31, 0xc5, 0xfe, 0x20, + 0xa4, 0xc2, 0x8b, 0xd8, 0x4d, 0x72, 0x57, 0xb9, 0x09, 0x94, 0xe9, 0xc5, + 0x34, 0xd3, 0x02, 0xe5, 0xbb, 0x3b, 0x4f, 0xcc, 0x5f, 0xf2, 0x56, 0x51, + 0x86, 0x2c, 0x74, 0x90, 0x93, 0x08, 0x19, 0x73, 0xd8, 0xc7, 0xaf, 0xc7, + 0xdd, 0xc8, 0x56, 0xa1, 0x73, 0x4c, 0x1a, 0x7a, 0xf3, 0x12, 0x81, 0x8e, + 0x0b, 0xd1, 0x43, 0x71, 0x62, 0xcb, 0xb8, 0x34, 0x5a, 0xb3, 0x30, 0x57, + 0x9c, 0x19, 0x10, 0xb3, 0x2d, 0x25, 0x43, 0x63, 0xc7, 0x25, 0x50, 0xf7, + 0xfb, 0x50, 0x01, 0xf6, 0x3f, 0x1e, 0xee, 0x10, 0x59, 0xe9, 0xbb, 0x18, + 0x3f, 0x30, 0x29, 0xc4, 0x2c, 0xfb, 0x1f, 0xfb, 0xa9, 0x09, 0xf6, 0x72, + 0xda, 0x2c, 0x44, 0xee, 0x73, 0xfb, 0x57, 0xed, 0x38, 0x1b, 0x95, 0x30, + 0x35, 0x6b, 0xa0, 0x7c, 0xef, 0x43, 0x22, 0xd1, 0x04, 0xf8, 0x8f, 0x7d, + 0xfc, 0x11, 0x92, 0x7a, 0x38, 0x77, 0xbd, 0x1e, 0x77, 0xa2, 0xbc, 0xe4, + 0x77, 0xdd, 0x46, 0x36, 0x7f, 0x13, 0x8c, 0x50, 0x5d, 0x78, 0x0e, 0x03, + 0x3b, 0x38, 0x0b, 0xd3, 0x4a, 0x2a, 0x88, 0xd1, 0x80, 0xc2, 0xe7, 0x89, + 0x35, 0xe4, 0xc2, 0xf1, 0x3c, 0x26, 0x6f, 0x77, 0xa9, 0x78, 0x5f, 0x3a, + 0xe9, 0x26, 0x51, 0xae, 0x1c, 0xed, 0xb2, 0xb5, 0x08, 0x0d, 0x62, 0x39, + 0xbe, 0x9b, 0x2a, 0xf6, 0x0a, 0x62, 0xbb, 0x1b, 0xbf, 0xdb, 0x70, 0xdb, + 0x8d, 0x26, 0xaf, 0xb2, 0xa0, 0x12, 0x59, 0xaa, 0x71, 0x0f, 0xcb, 0x4c, + 0x82, 0x2b, 0xb1, 0x96, 0x32, 0x25, 0xef, 0xcc, 0xb3, 0x72, 0x88, 0x49, + 0x60, 0x97, 0x99, 0x15, 0x90, 0x0b, 0x9e, 0x05, 0xa9, 0x7a, 0x40, 0x15, + 0x0f, 0xfa, 0x84, 0xa7, 0xd3, 0x74, 0xad, 0xaa, 0x6f, 0x25, 0x95, 0xb2, + 0x08, 0xf8, 0x8a, 0x66, 0x9f, 0x51, 0x76, 0x50, 0x35, 0x4f, 0x87, 0x58, + 0x23, 0x2f, 0x9f, 0x23, 0x06, 0xf9, 0xb7, 0xc5, 0xb7, 0xbd, 0x2d, 0x07, + 0x33, 0x81, 0x95, 0xad, 0x2b, 0x41, 0x5d, 0x25, 0x6c, 0x44, 0x38, 0x8a, + 0x57, 0x1c, 0x36, 0x2c, 0xa9, 0x46, 0x94, 0x1a, 0xc7, 0x20, 0x16, 0x04, + 0xe7, 0x1b, 0x95, 0x1e, 0xc0, 0x50, 0x09, 0x77, 0x47, 0xa5, 0x44, 0x6f, + 0xb0, 0x10, 0xe3, 0x09, 0x85, 0x46, 0xa1, 0xfd, 0x26, 0xc1, 0x64, 0x80, + 0xa4, 0xba, 0x9d, 0x0e, 0x0a, 0x06, 0x5a, 0xac, 0x8b, 0x2f, 0xe6, 0x2a, + 0x69, 0xf3, 0x95, 0x34, 0x88, 0x6a, 0x65, 0xaa, 0xd9, 0x47, 0x16, 0x00, + 0x6d, 0xc0, 0x4e, 0xac, 0x3e, 0x53, 0xbf, 0xbb, 0x3b, 0x46, 0xc1, 0x1d, + 0x0d, 0x0a, 0xe0, 0x1e, 0x49, 0x8c, 0x83, 0xbb, 0x61, 0x81, 0xb5, 0x26, + 0x4f, 0x8d, 0xc5, 0x7f, 0xe7, 0xcb, 0x4c, 0xc3, 0xf6, 0x50, 0x21, 0x79, + 0xfd, 0x52, 0x6a, 0xd6, 0x31, 0xde, 0x21, 0x87, 0xe0, 0x29, 0xa5, 0xf0, + 0xa2, 0xe8, 0x63, 0x81, 0xaf, 0x65, 0xc8, 0x1e, 0x38, 0x4d, 0x2d, 0x1b, + 0x8b, 0x69, 0x95, 0xa0, 0x2b, 0xbb, 0x1c, 0x18, 0x40, 0x31, 0x28, 0x01, + 0xcc, 0x0b, 0xa1, 0x28, 0x08, 0xaa, 0x0b, 0xbf, 0x63, 0x98, 0xad, 0x90, + 0xad, 0xc1, 0x77, 0x80, 0x95, 0x31, 0x4b, 0x36, 0x60, 0x24, 0x1b, 0xdd, + 0x80, 0xb9, 0x36, 0xb9, 0xd5, 0x4b, 0x4d, 0xe3, 0x51, 0xa9, 0xec, 0x49, + 0xa2, 0x25, 0x34, 0x95, 0x26, 0xb9, 0xc6, 0x09, 0x0c, 0xf9, 0xf0, 0x3a, + 0xcd, 0x27, 0xb4, 0x05, 0xf6, 0x21, 0xf6, 0xac, 0x96, 0x97, 0xdf, 0x63, + 0xd8, 0xd7, 0x19, 0xd5, 0xea, 0x55, 0x7f, 0x6a, 0xa8, 0x0c, 0x4a, 0x4c, + 0x38, 0x1d, 0x8d, 0x72, 0x41, 0x25, 0xe4, 0xba, 0x0f, 0x6e, 0x05, 0x18, + 0x6a, 0x03, 0x01, 0x17, 0xa9, 0x05, 0x5c, 0x82, 0x4d, 0x9f, 0x1f, 0x69, + 0x4e, 0x19, 0x04, 0x31, 0x0e, 0x95, 0x57, 0x84, 0x91, 0x5a, 0x44, 0x3e, + 0x46, 0x95, 0x3d, 0x78, 0x96, 0xcd, 0x6e, 0x1b, 0x23, 0xe8, 0xa2, 0xf8, + 0x59, 0x5c, 0x8b, 0xb5, 0x50, 0x0b, 0x1e, 0x51, 0xc9, 0x88, 0x4a, 0xc2, + 0x04, 0x6c, 0x38, 0xd0, 0x82, 0x22, 0x7f, 0xd8, 0x60, 0xb4, 0xfd, 0x6f, + 0xfd, 0x24, 0x45, 0x08, 0x5d, 0x9a, 0xeb, 0x26, 0x15, 0x8f, 0x72, 0xa8, + 0x5f, 0xdc, 0x49, 0xdb, 0x24, 0xa9, 0xce, 0x3c, 0x09, 0x38, 0xd5, 0x62, + 0xf0, 0xab, 0x94, 0x87, 0x46, 0x29, 0xbe, 0x94, 0x39, 0x8a, 0xcc, 0x88, + 0xdb, 0x03, 0x4f, 0xb0, 0x63, 0x00, 0xd8, 0xc5, 0x03, 0xf8, 0x89, 0xd1, + 0x90, 0x21, 0x72, 0xb8, 0x49, 0x1a, 0xd4, 0x29, 0xb3, 0x29, 0x8b, 0x77, + 0x3d, 0x30, 0x1a, 0x86, 0x16, 0x7a, 0x63, 0x4c, 0x9f, 0x27, 0xec, 0x01, + 0xbf, 0xc0, 0xb6, 0x0c, 0x5d, 0x62, 0x3c, 0x96, 0x88, 0x88, 0x4f, 0xe3, + 0xe4, 0xf5, 0x10, 0x60, 0x60, 0x58, 0x97, 0x8e, 0x52, 0xf7, 0xf7, 0xf8, + 0x0f, 0xaf, 0x86, 0x22, 0x4d, 0xd0, 0x27, 0x48, 0x9b, 0xf4, 0x84, 0x7f, + 0xef, 0x5b, 0xfc, 0x84, 0x5f, 0xe4, 0xb3, 0x76, 0xcf, 0x7b, 0x6f, 0x67, + 0xcc, 0x4b, 0x89, 0x0f, 0x29, 0x1c, 0xbe, 0x23, 0x9d, 0xb9, 0xd4, 0x65, + 0x4e, 0x35, 0x17, 0x5d, 0x13, 0x4b, 0x58, 0x12, 0x80, 0x16, 0x80, 0xd1, + 0xe7, 0x73, 0x0e, 0xdd, 0xa8, 0xd2, 0x31, 0x66, 0x57, 0x22, 0x1c, 0xe4, + 0x6d, 0xc2, 0x26, 0x58, 0x52, 0xbd, 0x39, 0xb3, 0x22, 0xe4, 0xf2, 0x82, + 0x14, 0x54, 0x73, 0x71, 0x69, 0xf4, 0x33, 0x3f, 0x18, 0x61, 0x99, 0xb1, + 0x12, 0xd5, 0x6c, 0xb7, 0x3a, 0xc6, 0xed, 0xa9, 0x35, 0x0e, 0x07, 0x20, + 0x37, 0x89, 0xd6, 0xa6, 0xb5, 0xea, 0xe3, 0xb8, 0xe1, 0x4a, 0x1d, 0xdc, + 0x21, 0x27, 0xc4, 0x90, 0xba, 0xa5, 0xe5, 0x95, 0x09, 0x8f, 0x26, 0x2a, + 0x86, 0xf6, 0x20, 0x42, 0x2c, 0x17, 0x2f, 0x80, 0xe4, 0x25, 0xc4, 0x8e, + 0x94, 0x2e, 0x9d, 0x2f, 0x4b, 0x42, 0xa8, 0x34, 0xcd, 0xf1, 0x81, 0x40, + 0x47, 0x48, 0xdc, 0xb8, 0xc4, 0x32, 0xa7, 0x15, 0x45, 0xc4, 0x00, 0x91, + 0xcc, 0xc4, 0x7e, 0x2e, 0x92, 0x96, 0x2e, 0x29, 0x8d, 0x8b, 0x13, 0x5f, + 0x1f, 0xe0, 0x45, 0x4d, 0xd0, 0xf4, 0x72, 0x53, 0xf3, 0x70, 0x9c, 0xcc, + 0xa8, 0xfb, 0xfa, 0x45, 0x04, 0xa0, 0x06, 0xc1, 0x74, 0x2b, 0xa0, 0xc2, + 0xb5, 0x45, 0x9b, 0xba, 0xe0, 0x72, 0x2a, 0x21, 0xeb, 0x04, 0x3e, 0x09, + 0xd0, 0x27, 0x8e, 0xa3, 0xeb, 0xa7, 0x81, 0xb3, 0x7f, 0x17, 0x54, 0x25, + 0xdb, 0xba, 0xb1, 0xf8, 0x4b, 0x6c, 0x9a, 0x28, 0x85, 0x12, 0x9e, 0x30, + 0x59, 0x6f, 0xb8, 0xd4, 0xb6, 0xc1, 0xe3, 0x12, 0x00, 0xce, 0x42, 0x88, + 0x57, 0xb1, 0x89, 0xf0, 0x13, 0x87, 0x33, 0x1f, 0x71, 0x0d, 0x29, 0x97, + 0x97, 0x58, 0x85, 0x36, 0xc9, 0x5f, 0x86, 0x5e, 0x8e, 0xdf, 0xbd, 0x7d, + 0x7d, 0xfe, 0xf6, 0xec, 0xec, 0xf4, 0xcd, 0xc5, 0xf1, 0x33, 0x4c, 0x4e, + 0xbd, 0x38, 0x3d, 0x3a, 0x7d, 0xd9, 0x76, 0x71, 0x07, 0x6c, 0x20, 0x2a, + 0x8d, 0xd7, 0x3c, 0xd9, 0x4e, 0x3d, 0x49, 0x36, 0x71, 0x1d, 0xb7, 0x7c, + 0x1c, 0x98, 0x85, 0x85, 0x78, 0x97, 0x5f, 0x57, 0x2d, 0x48, 0x97, 0x0b, + 0xce, 0x42, 0x75, 0x63, 0xe6, 0xb4, 0x3d, 0x0d, 0x95, 0x6f, 0xe6, 0x12, + 0x53, 0x5c, 0x0b, 0x67, 0xbc, 0xd0, 0x51, 0x10, 0x7c, 0xe7, 0x20, 0x3f, + 0xfb, 0x95, 0xff, 0x72, 0xde, 0xdb, 0xa8, 0x1b, 0xe6, 0x3b, 0xe3, 0x20, + 0x2e, 0xdf, 0x41, 0x3d, 0x11, 0xdd, 0x10, 0x25, 0x35, 0xa8, 0x86, 0xa9, + 0x6b, 0x85, 0x34, 0x40, 0xc2, 0x40, 0x2c, 0x0b, 0x88, 0x28, 0x50, 0xcc, + 0x7c, 0x51, 0x22, 0x27, 0x08, 0x8c, 0xb2, 0x59, 0xce, 0x77, 0xb1, 0x4b, + 0xf3, 0xc3, 0xf7, 0xca, 0x8c, 0xd5, 0x30, 0x09, 0xd0, 0x1e, 0x65, 0x54, + 0x69, 0x2d, 0xda, 0x2b, 0x09, 0xa8, 0xd2, 0x57, 0xa4, 0xdc, 0xce, 0x4d, + 0x2c, 0x0d, 0x30, 0x00, 0x03, 0xaa, 0x15, 0x54, 0x65, 0x7b, 0x69, 0xe9, + 0xba, 0x32, 0x44, 0x62, 0xc9, 0xa4, 0x60, 0xe3, 0x12, 0xb0, 0x9a, 0xef, + 0x46, 0xed, 0x32, 0x1c, 0xa2, 0x95, 0xb0, 0x2b, 0x41, 0xd8, 0xbb, 0x68, + 0x27, 0xcb, 0x2b, 0xed, 0x50, 0x22, 0xa8, 0x19, 0xea, 0x4f, 0x34, 0x37, + 0x06, 0x14, 0xa7, 0x3e, 0xbb, 0x04, 0x0c, 0x8d, 0x43, 0x78, 0x8e, 0x23, + 0x88, 0x16, 0x4e, 0x2c, 0x5f, 0x2e, 0x99, 0xf9, 0xf1, 0xa3, 0xfe, 0xde, + 0x56, 0x94, 0x0c, 0x80, 0x31, 0xa0, 0xb0, 0x0e, 0xbf, 0xc7, 0x7f, 0xf5, + 0x82, 0xc1, 0xdf, 0xdd, 0xae, 0x68, 0xf0, 0x88, 0x2b, 0x2a, 0x25, 0x6c, + 0x54, 0xea, 0x9b, 0x25, 0x97, 0x45, 0x21, 0x12, 0xae, 0x96, 0x5d, 0x89, + 0x09, 0x98, 0xa7, 0xfe, 0xc5, 0x82, 0x6c, 0x7d, 0x27, 0xdf, 0x36, 0xd6, + 0x76, 0x3d, 0x26, 0xa8, 0x44, 0xfb, 0xa1, 0x6b, 0x1a, 0xdf, 0x7a, 0xf6, + 0x21, 0xe7, 0xbd, 0x5e, 0xb6, 0xa2, 0x78, 0xb5, 0x5c, 0xaf, 0xa6, 0x25, + 0x03, 0x4a, 0x64, 0x41, 0x61, 0x59, 0x13, 0x61, 0x88, 0x8a, 0x86, 0x8c, + 0x1a, 0xde, 0x2b, 0x4a, 0x25, 0x1a, 0xb1, 0x28, 0x24, 0x35, 0xa3, 0xa3, + 0xe1, 0xa5, 0x05, 0xbd, 0x10, 0x4d, 0xaa, 0xb9, 0xe9, 0xad, 0xa6, 0xc3, + 0xae, 0x30, 0xb1, 0x78, 0xf3, 0x0a, 0xb1, 0xdf, 0x86, 0x81, 0xc5, 0x2c, + 0x2c, 0x26, 0x35, 0xaf, 0xb0, 0xb2, 0xb0, 0xbe, 0xe3, 0xf7, 0x0a, 0xd1, + 0xf0, 0x15, 0x56, 0x01, 0x5b, 0x45, 0xd8, 0x37, 0x3a, 0x5b, 0x81, 0xb9, + 0x8f, 0xad, 0x47, 0x1d, 0x30, 0x95, 0x1f, 0xa3, 0x84, 0x16, 0x5c, 0x72, + 0x71, 0x44, 0x4b, 0x54, 0x0b, 0x7e, 0x42, 0x99, 0x82, 0xfd, 0x84, 0x6a, + 0x90, 0x87, 0xa1, 0xda, 0x0b, 0xdb, 0xe8, 0xfe, 0xdf, 0xae, 0x8b, 0x6d, + 0xee, 0xb0, 0x8f, 0xff, 0x7c, 0xe5, 0x0d, 0x71, 0xb2, 0x29, 0x2a, 0x7e, + 0x70, 0xad, 0x14, 0x0a, 0xda, 0xb0, 0x84, 0x45, 0x23, 0x1b, 0xc7, 0xc4, + 0xbd, 0x61, 0x8b, 0xd2, 0x26, 0xc5, 0x7d, 0xeb, 0xfd, 0xb7, 0x9c, 0x0d, + 0x2e, 0x81, 0xe6, 0x52, 0x84, 0x85, 0x26, 0x88, 0x79, 0x8a, 0xb1, 0x5f, + 0x55, 0xca, 0xbd, 0x2e, 0xaa, 0x1a, 0x85, 0x24, 0x75, 0x9b, 0x76, 0xd5, + 0xdb, 0x1a, 0x9c, 0xad, 0xd8, 0xbc, 0xb8, 0x65, 0x63, 0x50, 0x82, 0xaf, + 0x5d, 0x86, 0xed, 0xdb, 0x19, 0x9c, 0xca, 0xe2, 0x72, 0x06, 0x8a, 0xf4, + 0x48, 0x46, 0x14, 0xdd, 0xa0, 0x62, 0x86, 0x72, 0x27, 0x9a, 0x6e, 0x51, + 0x41, 0x6a, 0x60, 0x49, 0x4a, 0xee, 0xe3, 0x21, 0xd5, 0x12, 0xe6, 0xbb, + 0xcc, 0x60, 0xef, 0xb9, 0xcc, 0xeb, 0xc8, 0xdd, 0xd4, 0x7c, 0x8d, 0x4b, + 0x3a, 0x00, 0x0b, 0x5b, 0x42, 0x92, 0x91, 0xe5, 0xe2, 0xdf, 0x68, 0x35, + 0x6b, 0x47, 0xbc, 0x08, 0x71, 0x96, 0xed, 0xb0, 0x17, 0x8c, 0xb5, 0xc5, + 0x15, 0xef, 0x22, 0xc4, 0x0b, 0x06, 0x63, 0xe8, 0x07, 0x64, 0x8b, 0x9c, + 0x8e, 0x56, 0x5b, 0x2b, 0xf8, 0xbe, 0x06, 0x6c, 0x30, 0xa0, 0x45, 0x9c, + 0xd9, 0x88, 0xcd, 0x5b, 0xa3, 0x04, 0x64, 0xd1, 0x86, 0x61, 0x71, 0x88, + 0xc1, 0x42, 0x96, 0xd4, 0xa0, 0x51, 0xf3, 0x7c, 0xab, 0x49, 0xbc, 0x3e, + 0x09, 0x43, 0x9c, 0x13, 0x1d, 0xcc, 0xcc, 0xb2, 0x58, 0x41, 0x3b, 0x26, + 0xf5, 0x19, 0xc3, 0xf6, 0xa9, 0x6a, 0x8f, 0x78, 0x32, 0xc4, 0x20, 0x81, + 0xaf, 0x30, 0x95, 0x46, 0xa1, 0xf9, 0xf0, 0x00, 0x41, 0x9f, 0x28, 0x81, + 0x34, 0xce, 0xb9, 0x1b, 0x15, 0xdb, 0x20, 0x15, 0x4c, 0x20, 0x55, 0x5d, + 0xb7, 0x1f, 0xca, 0xde, 0x13, 0x42, 0x0c, 0xa9, 0x5a, 0xa9, 0x72, 0x1e, + 0x49, 0x1f, 0x24, 0x5c, 0x9e, 0x05, 0xd2, 0x79, 0xa2, 0xf6, 0x6a, 0xdb, + 0x6d, 0x8a, 0x7b, 0x47, 0xd4, 0x81, 0x90, 0xa9, 0x29, 0x6c, 0x98, 0xdf, + 0xf0, 0x7e, 0x8e, 0xff, 0x27, 0xda, 0x49, 0x57, 0x9a, 0x49, 0x7d, 0x60, + 0x3e, 0x0f, 0x8f, 0x98, 0x5c, 0x08, 0x6b, 0xf6, 0xa9, 0x31, 0x64, 0xe3, + 0x26, 0xed, 0xe4, 0x06, 0x6d, 0x8a, 0x56, 0x9c, 0xdc, 0x59, 0x58, 0x5b, + 0xc9, 0xbc, 0x2b, 0x10, 0xd9, 0x9a, 0xfb, 0x67, 0x6c, 0x8d, 0xb9, 0x1a, + 0x0b, 0xb9, 0x70, 0x76, 0xb7, 0x5c, 0x08, 0x39, 0x85, 0x16, 0x23, 0xbb, + 0x62, 0xa0, 0x14, 0x58, 0xea, 0xdf, 0x87, 0x6a, 0x28, 0x3e, 0x64, 0x49, + 0x88, 0x5e, 0x2f, 0x6a, 0x09, 0x4d, 0xa2, 0x32, 0x38, 0x19, 0x89, 0x26, + 0x53, 0xac, 0x7a, 0x93, 0x32, 0x93, 0x55, 0x8c, 0x02, 0x90, 0x2d, 0x7b, + 0xc8, 0x0d, 0xe4, 0xa8, 0xc0, 0x6c, 0x91, 0x6e, 0xcc, 0x3e, 0xaf, 0x1a, + 0x13, 0x37, 0x7b, 0x97, 0xb4, 0x60, 0xe2, 0xc2, 0x47, 0x57, 0x63, 0x93, + 0xd5, 0xe6, 0x99, 0xc7, 0x36, 0xe3, 0xf5, 0x6c, 0x5f, 0x74, 0xf9, 0x44, + 0xc9, 0xfa, 0x94, 0x97, 0xed, 0xc5, 0x5f, 0xf8, 0x4c, 0x20, 0x16, 0xe4, + 0x90, 0x2f, 0xea, 0x02, 0x2d, 0xb6, 0x52, 0x3f, 0x66, 0x9e, 0x53, 0xe9, + 0xa8, 0x94, 0x48, 0x27, 0x17, 0xe8, 0x82, 0x25, 0xec, 0x0c, 0x83, 0x2b, + 0x71, 0x09, 0x5e, 0x68, 0xc7, 0x58, 0xcc, 0x34, 0xb4, 0xcb, 0x6e, 0x2e, + 0x0e, 0x77, 0xf4, 0xf7, 0x3f, 0x91, 0x31, 0x9f, 0x08, 0xe6, 0xf9, 0xc4, + 0xf2, 0x43, 0x2a, 0x84, 0xdc, 0xee, 0xdb, 0x96, 0xb9, 0x99, 0xc0, 0xc9, + 0x9c, 0x8d, 0x7a, 0x70, 0x46, 0xe6, 0x2d, 0x46, 0xc9, 0x30, 0xa1, 0xf5, + 0x51, 0x03, 0xef, 0xdf, 0x05, 0x6b, 0x53, 0xff, 0x26, 0x7a, 0x0b, 0xf0, + 0x09, 0x23, 0xb4, 0xe2, 0xf3, 0x7e, 0x7d, 0xac, 0xdd, 0xbe, 0x1b, 0x6f, + 0x4e, 0xb4, 0x5d, 0x71, 0xca, 0xbc, 0x7f, 0x2c, 0x88, 0x78, 0xcc, 0x64, + 0x7f, 0xe0, 0x77, 0x1b, 0x1b, 0x43, 0x7e, 0xd5, 0x78, 0x27, 0x9c, 0x10, + 0x41, 0x7b, 0x11, 0x39, 0xdc, 0xde, 0x32, 0x14, 0x19, 0x0f, 0x84, 0xcd, + 0xc1, 0x33, 0x81, 0x42, 0xf2, 0xdd, 0x08, 0x24, 0x79, 0xc2, 0xd9, 0x5d, + 0xac, 0x2b, 0xca, 0xfd, 0xcc, 0x0f, 0x34, 0x8c, 0x7d, 0xed, 0xe0, 0x36, + 0x01, 0x5c, 0x9a, 0xdb, 0xc3, 0x31, 0xe4, 0x08, 0x25, 0xb8, 0x54, 0x9a, + 0xc5, 0x2f, 0xcf, 0x6f, 0x45, 0xbf, 0xf0, 0x6d, 0x7d, 0xc9, 0xcd, 0x6c, + 0x2b, 0x12, 0xd5, 0xba, 0x9d, 0xc3, 0xb4, 0xc7, 0x7e, 0xc7, 0xb6, 0xc8, + 0xd3, 0xa3, 0x43, 0x41, 0x0a, 0x0c, 0xb5, 0xb4, 0xc4, 0x49, 0x29, 0x57, + 0x1e, 0x7a, 0x3e, 0x6f, 0x41, 0x92, 0x99, 0x92, 0x24, 0xcc, 0xe1, 0xa7, + 0x81, 0x3d, 0x3a, 0x81, 0xb2, 0x1f, 0xa7, 0x8f, 0xb0, 0xfc, 0x44, 0xab, + 0x9f, 0x62, 0x2f, 0xd2, 0x8d, 0x31, 0x32, 0xb2, 0xf3, 0x2a, 0x20, 0x38, + 0xf9, 0x63, 0x28, 0x12, 0x0d, 0xcb, 0x3b, 0x69, 0xde, 0x23, 0x1b, 0x16, + 0x6f, 0x5a, 0x2b, 0x93, 0xb1, 0x48, 0x84, 0x59, 0xc7, 0xe3, 0x74, 0x18, + 0xe5, 0x68, 0x37, 0x86, 0xbd, 0x51, 0x51, 0x01, 0x89, 0x6b, 0x8f, 0x63, + 0x1b, 0xd5, 0xe2, 0x24, 0x21, 0x95, 0x48, 0x51, 0x54, 0x4c, 0xab, 0xaf, + 0xc4, 0x5d, 0x1b, 0x26, 0x0d, 0x89, 0x8b, 0x1a, 0x36, 0x28, 0xfe, 0x93, + 0x25, 0xb1, 0xf4, 0x49, 0x7f, 0x1f, 0xa4, 0x52, 0xd2, 0x22, 0x24, 0xae, + 0xd0, 0x7f, 0xf7, 0x88, 0x8a, 0x6d, 0xd2, 0x9d, 0xc1, 0xeb, 0xa3, 0x6a, + 0xa5, 0x76, 0xe9, 0x31, 0x3e, 0xb1, 0xbf, 0x20, 0x16, 0xd3, 0xdc, 0xc7, + 0xa0, 0xe3, 0x2c, 0x58, 0x12, 0x43, 0x97, 0x59, 0xae, 0xb2, 0xae, 0x2b, + 0x92, 0x84, 0x6d, 0xb3, 0xbd, 0xd9, 0x2c, 0xb6, 0xba, 0xa3, 0xb6, 0x0b, + 0xfd, 0x36, 0xa6, 0xd6, 0x20, 0x93, 0xcf, 0x5b, 0xa9, 0xaf, 0xd1, 0xc5, + 0x3a, 0x27, 0xc8, 0x1e, 0x5e, 0xaf, 0x7a, 0xdf, 0x1e, 0x26, 0x10, 0x44, + 0xb5, 0x5a, 0x53, 0x14, 0xea, 0x28, 0x5b, 0x6c, 0x98, 0xa2, 0x4a, 0x84, + 0x47, 0x67, 0xb4, 0x98, 0xce, 0xb1, 0x65, 0xba, 0xd6, 0xa3, 0x6c, 0xb1, + 0x25, 0xb0, 0x40, 0x1d, 0x05, 0xb6, 0x12, 0x01, 0x88, 0x2c, 0xab, 0xbd, + 0x3e, 0x36, 0x98, 0x8b, 0xfe, 0x84, 0x48, 0xed, 0xe5, 0x53, 0x72, 0x11, + 0x15, 0x2d, 0xc7, 0xb0, 0x28, 0x89, 0xcc, 0x0e, 0x6b, 0x0e, 0x3b, 0xe5, + 0xda, 0xac, 0x18, 0xc6, 0xcb, 0x7d, 0xb2, 0x59, 0x6d, 0x25, 0x54, 0x96, + 0xcf, 0x9c, 0xfa, 0x12, 0xb9, 0x2d, 0x55, 0xd0, 0x3c, 0x9d, 0xc7, 0x02, + 0x1c, 0xc3, 0x16, 0x86, 0xfa, 0xa4, 0x75, 0x89, 0xc5, 0xfd, 0x54, 0xbb, + 0x14, 0x49, 0xda, 0x25, 0xbd, 0x86, 0x83, 0x25, 0xbc, 0x58, 0xeb, 0x49, + 0x72, 0xe0, 0x05, 0xeb, 0x21, 0xd7, 0x79, 0xea, 0xe0, 0x07, 0x75, 0x6f, + 0xff, 0xbe, 0xc8, 0x41, 0x16, 0xa1, 0x98, 0x63, 0x2e, 0xff, 0x23, 0x6b, + 0xc9, 0x08, 0x7e, 0x01, 0x36, 0x87, 0x57, 0x27, 0xf4, 0x0d, 0x87, 0x5a, + 0x92, 0x59, 0x62, 0x10, 0x2b, 0x79, 0xfd, 0xbe, 0x84, 0x96, 0x50, 0x9d, + 0x56, 0x44, 0xa1, 0x08, 0x67, 0x78, 0x3d, 0xca, 0xa3, 0x8e, 0x8e, 0x0e, + 0xb9, 0x5c, 0x4e, 0x8d, 0x85, 0x41, 0x3e, 0x18, 0x15, 0x7e, 0x24, 0xdf, + 0x76, 0xad, 0x2a, 0x11, 0x7e, 0x24, 0x65, 0xc6, 0xd0, 0x6f, 0xbe, 0xb1, + 0x28, 0x71, 0x9e, 0x72, 0xa2, 0x2b, 0x6b, 0x93, 0x56, 0x59, 0xc1, 0xf3, + 0xbd, 0xde, 0xaf, 0x0b, 0xfc, 0xd5, 0xca, 0x20, 0x9f, 0x88, 0x9e, 0x7d, + 0x1a, 0x7a, 0xb8, 0x01, 0xbc, 0xd4, 0xad, 0x75, 0x89, 0xe3, 0xb2, 0xb0, + 0x62, 0xeb, 0xb1, 0xad, 0x02, 0x75, 0x20, 0xb8, 0x9c, 0xe8, 0x3e, 0x66, + 0x35, 0x60, 0xb3, 0x73, 0xd0, 0x01, 0x62, 0xde, 0x44, 0x6b, 0x86, 0x40, + 0x3a, 0x62, 0x03, 0xbb, 0x07, 0xf8, 0x73, 0x8f, 0x7e, 0xee, 0x23, 0xc0, + 0x62, 0xe3, 0x04, 0x54, 0x5c, 0x95, 0x72, 0x89, 0xf4, 0xbb, 0x1e, 0x40, + 0x6e, 0x9c, 0x34, 0x90, 0x93, 0x99, 0x3d, 0xc1, 0x7b, 0x21, 0xfa, 0x9b, + 0xc4, 0x88, 0x30, 0x45, 0x6a, 0x95, 0x4b, 0xf9, 0x0c, 0x32, 0x27, 0xbc, + 0x60, 0xc5, 0x08, 0x83, 0x4b, 0xa4, 0x2c, 0xff, 0x77, 0x65, 0x46, 0x9e, + 0xf2, 0x64, 0x51, 0x73, 0xc5, 0x5d, 0xb4, 0x36, 0x4c, 0xcc, 0xa8, 0x25, + 0x3d, 0x90, 0xf9, 0xc9, 0x07, 0x97, 0xf9, 0xed, 0x13, 0x1d, 0x47, 0xed, + 0xbd, 0x76, 0xbb, 0x80, 0x5e, 0x70, 0xc3, 0x00, 0x79, 0x5a, 0x85, 0x80, + 0xe1, 0xf4, 0x31, 0x3a, 0x47, 0x76, 0x1b, 0x1e, 0xf2, 0xc9, 0x90, 0x84, + 0x29, 0x46, 0x21, 0x11, 0xc0, 0x96, 0x73, 0xb2, 0x60, 0x4c, 0x6e, 0x39, + 0xd5, 0xda, 0x52, 0xe2, 0x3c, 0x6d, 0x1b, 0x88, 0xb7, 0x53, 0x33, 0xf5, + 0x3b, 0x62, 0x4b, 0x96, 0x2c, 0x42, 0xc8, 0x39, 0x4d, 0x7e, 0xe4, 0x6d, + 0x1a, 0xce, 0x0d, 0x90, 0x57, 0xe2, 0x08, 0xf0, 0xb2, 0x59, 0x22, 0x93, + 0xb5, 0xc3, 0xa8, 0xb6, 0x94, 0xd6, 0x23, 0x4e, 0x8f, 0xfe, 0x3b, 0x8e, + 0x38, 0x75, 0xb4, 0x6d, 0xd8, 0xfd, 0xb2, 0xff, 0x9f, 0x7e, 0xce, 0xe3, + 0x45, 0xec, 0x7a, 0x79, 0x4d, 0x3a, 0x13, 0x90, 0x2a, 0x7f, 0xce, 0x9b, + 0xa7, 0x9a, 0xae, 0x1a, 0xfc, 0xf9, 0x37, 0x11, 0x14, 0x7f, 0x59, 0x7d, + 0xe7, 0x50, 0x89, 0xe5, 0x64, 0xf9, 0xee, 0x59, 0x25, 0x92, 0x5b, 0xa1, + 0xeb, 0xe8, 0x36, 0x6a, 0x1c, 0x2b, 0xa6, 0x7f, 0x39, 0x54, 0x7f, 0x3c, + 0x3a, 0xff, 0xdd, 0xee, 0x9e, 0x1c, 0x2c, 0x3a, 0x4e, 0x0e, 0xfd, 0xaa, + 0x69, 0xa6, 0xa3, 0x2c, 0xa1, 0x70, 0x0e, 0xc3, 0xe3, 0xe4, 0x0a, 0xe3, + 0x84, 0x63, 0x86, 0x7e, 0x64, 0xb3, 0xb8, 0x19, 0x9b, 0xac, 0x0c, 0x9a, + 0xd9, 0x30, 0x96, 0xed, 0x62, 0x0c, 0x60, 0x80, 0x9f, 0x83, 0xaa, 0x56, + 0x12, 0x8f, 0x22, 0x89, 0x2d, 0x72, 0x28, 0x29, 0xcc, 0x4c, 0x5f, 0xaa, + 0xe2, 0xf2, 0x9a, 0x62, 0xc2, 0x42, 0xdd, 0xa8, 0xfa, 0xe7, 0x12, 0x03, + 0xdb, 0x63, 0x5a, 0x58, 0xf5, 0x0f, 0x17, 0x98, 0xdc, 0x5f, 0xb8, 0x3d, + 0xe1, 0xf2, 0x32, 0xbe, 0xea, 0x8d, 0x0f, 0x76, 0x7d, 0x05, 0xfd, 0xbd, + 0x27, 0x27, 0xae, 0x5a, 0x89, 0x2a, 0xfa, 0x1b, 0x8b, 0xaa, 0xbb, 0x5e, + 0x88, 0x02, 0x96, 0x88, 0xf8, 0x53, 0xd4, 0x8b, 0x90, 0x90, 0x18, 0x9a, + 0xef, 0xd5, 0xb7, 0xf3, 0xac, 0x85, 0x66, 0xe9, 0xf3, 0xe4, 0x29, 0xfe, + 0xf4, 0x25, 0x1b, 0xf1, 0xc3, 0x50, 0x1d, 0xc8, 0x26, 0xdf, 0x46, 0xb9, + 0x71, 0x80, 0xee, 0x72, 0xa0, 0x26, 0x10, 0x56, 0x17, 0x53, 0xd2, 0xba, + 0xc9, 0xf1, 0xeb, 0x1f, 0x69, 0x5c, 0x67, 0x40, 0x99, 0xec, 0xa4, 0x32, + 0xb3, 0x2f, 0x76, 0x58, 0xb5, 0x25, 0xe8, 0xf2, 0x48, 0x38, 0x07, 0xca, + 0x0a, 0x62, 0x50, 0x62, 0x99, 0xe4, 0xe4, 0xb0, 0x14, 0x4d, 0x8b, 0x2d, + 0xa0, 0x92, 0xd8, 0xa1, 0xfa, 0x29, 0x6f, 0x18, 0xa0, 0x94, 0x28, 0x4e, + 0x73, 0x81, 0x7c, 0x32, 0x10, 0x59, 0x80, 0x55, 0x52, 0x4f, 0x8c, 0x54, + 0x71, 0x88, 0xfd, 0xa4, 0x85, 0xc9, 0x89, 0x14, 0x93, 0x26, 0xf3, 0xf7, + 0xc3, 0x6a, 0x77, 0xf7, 0x20, 0x79, 0xfb, 0xe6, 0x84, 0x05, 0x77, 0x9c, + 0x5c, 0x43, 0xb5, 0x95, 0x25, 0x6f, 0x8a, 0x54, 0x81, 0x22, 0x79, 0xf1, + 0xc3, 0x75, 0xef, 0x64, 0xaa, 0xfb, 0x45, 0x2a, 0x7b, 0xff, 0xe3, 0xbc, + 0xf2, 0x1f, 0xcf, 0x6f, 0xad, 0x23, 0x64, 0x11, 0x6b, 0x90, 0xec, 0xc7, + 0xf3, 0xdd, 0xac, 0xac, 0x23, 0x82, 0xe5, 0xd3, 0x1d, 0xcd, 0x36, 0x9f, + 0x5f, 0x61, 0x2c, 0xd2, 0x53, 0x87, 0xfa, 0xcd, 0xda, 0xb0, 0x13, 0x9e, + 0xe4, 0x99, 0x35, 0xa5, 0x27, 0x85, 0x2b, 0x92, 0x0c, 0x4b, 0x7a, 0x99, + 0x0c, 0x59, 0x59, 0xa5, 0xd2, 0x76, 0xae, 0xa8, 0x40, 0x96, 0xcf, 0x87, + 0x7b, 0x47, 0x18, 0xae, 0x4d, 0x3a, 0xe7, 0x53, 0x80, 0xe9, 0xb2, 0x8a, + 0x5a, 0x5a, 0x31, 0x99, 0xee, 0xf6, 0xf7, 0x92, 0xcd, 0xdd, 0xfe, 0x2e, + 0xf0, 0xc1, 0x5d, 0x52, 0x21, 0x2f, 0x34, 0x22, 0x09, 0x8f, 0x97, 0x8c, + 0x59, 0x0d, 0xb0, 0xb9, 0x49, 0x47, 0x1a, 0x7b, 0x0c, 0x9b, 0x96, 0x8f, + 0xf4, 0xb1, 0x7e, 0xf2, 0x06, 0x03, 0x2a, 0x17, 0x18, 0x88, 0x13, 0x8d, + 0xd8, 0x1c, 0xef, 0x0e, 0xcd, 0x08, 0xc8, 0xe2, 0xed, 0x9b, 0x97, 0x1a, + 0xb9, 0xa5, 0xdb, 0x41, 0xe6, 0xe1, 0x2a, 0xdb, 0x1e, 0x15, 0xc3, 0x6a, + 0xbb, 0xaa, 0x26, 0xba, 0x6a, 0xfd, 0xab, 0x7a, 0x3a, 0x61, 0xb9, 0xa0, + 0x65, 0xd9, 0x93, 0x2f, 0xea, 0xfc, 0x74, 0x1d, 0x1d, 0x1f, 0x3d, 0x7b, + 0x71, 0xdc, 0x83, 0x9f, 0xe7, 0x87, 0xbd, 0xc3, 0xe3, 0xf3, 0xdd, 0xbd, + 0x27, 0xbd, 0x1f, 0x8f, 0x5e, 0xf5, 0xce, 0x5f, 0x1c, 0xee, 0x3d, 0x7a, + 0x7c, 0xc0, 0x94, 0xc5, 0xcf, 0xbc, 0x69, 0x7b, 0xe2, 0x33, 0x10, 0x63, + 0x3d, 0xa9, 0x76, 0xf7, 0x75, 0x3c, 0x5d, 0x47, 0x56, 0x8e, 0x40, 0x9b, + 0xc4, 0x59, 0x4e, 0x42, 0xf1, 0xdb, 0xef, 0xbc, 0x89, 0x2a, 0x73, 0xb8, + 0x6d, 0xc4, 0x83, 0xd2, 0xc4, 0x5d, 0xb4, 0xe4, 0xd7, 0x60, 0xa5, 0x53, + 0xad, 0x66, 0xc9, 0x51, 0xe0, 0xac, 0xe2, 0x65, 0xcb, 0xae, 0x35, 0xa9, + 0x20, 0x79, 0x49, 0x31, 0x66, 0xec, 0x27, 0x08, 0x98, 0xdd, 0x9c, 0x48, + 0x1c, 0xa7, 0xce, 0x9a, 0x07, 0x26, 0xf8, 0x09, 0x28, 0xd5, 0x67, 0x44, + 0xb2, 0x69, 0x09, 0x6d, 0x22, 0x18, 0x43, 0x8b, 0xbc, 0xa1, 0x65, 0x60, + 0xbc, 0xa4, 0xd1, 0xca, 0xc2, 0x7a, 0x36, 0x6d, 0xba, 0x56, 0xc9, 0x6e, + 0xa1, 0xa7, 0xae, 0xf5, 0xd8, 0xb5, 0xb0, 0x30, 0x69, 0xe0, 0x2e, 0x99, + 0x31, 0xb2, 0x92, 0x7f, 0x32, 0x0b, 0x93, 0x8e, 0xca, 0xec, 0x57, 0x0a, + 0xc8, 0xf8, 0x6d, 0x6a, 0x61, 0x98, 0xf9, 0x6a, 0x92, 0x60, 0x6b, 0x5e, + 0xc3, 0x10, 0xfb, 0x4c, 0x21, 0x8c, 0x63, 0x93, 0xe7, 0xa7, 0x18, 0x62, + 0x0d, 0x0f, 0xb9, 0xc5, 0x10, 0xab, 0xdd, 0x88, 0x83, 0xbe, 0xc5, 0x10, + 0xbb, 0x6c, 0x3f, 0x95, 0xd6, 0x3e, 0x8f, 0x01, 0x55, 0x1a, 0xfb, 0x77, + 0x5b, 0x50, 0xdb, 0xfc, 0x17, 0x0c, 0x2e, 0x96, 0x3c, 0xe5, 0x7f, 0xb7, + 0xbf, 0x77, 0x27, 0x54, 0x32, 0xaa, 0x8e, 0x69, 0x72, 0xf2, 0x1c, 0xc6, + 0xb8, 0x49, 0x39, 0x56, 0xe1, 0xfd, 0x1a, 0x3f, 0x40, 0x9b, 0xa4, 0x09, + 0xdc, 0xbc, 0xce, 0x6a, 0x61, 0x49, 0x75, 0x63, 0x14, 0xc5, 0xd4, 0xf2, + 0x46, 0xe2, 0xc4, 0xfb, 0xcc, 0xf5, 0xa4, 0xb0, 0xe7, 0xb9, 0x2f, 0xd1, + 0xe0, 0xa4, 0xd6, 0xc2, 0x4a, 0xfa, 0xf4, 0x74, 0x0e, 0x74, 0xcc, 0x04, + 0xe8, 0x53, 0x4f, 0x96, 0xd1, 0x0c, 0x72, 0x07, 0x3c, 0x82, 0x0a, 0x5e, + 0x4a, 0xa0, 0xaf, 0xc9, 0xd1, 0xe9, 0xeb, 0xd7, 0xc7, 0x47, 0x17, 0xcd, + 0x4c, 0x2f, 0x03, 0x28, 0xf7, 0x00, 0xd4, 0xd2, 0x4b, 0x25, 0x46, 0x9f, + 0xa0, 0x62, 0x9a, 0xf3, 0x97, 0xa2, 0x9d, 0x48, 0x4f, 0x9c, 0x19, 0xfa, + 0x6e, 0x3a, 0x44, 0x28, 0x6f, 0xa5, 0x31, 0x26, 0x31, 0x61, 0x37, 0x48, + 0x11, 0x9c, 0x93, 0x52, 0xa1, 0xd8, 0x45, 0xec, 0x88, 0xe3, 0x97, 0xa5, + 0x2b, 0x1c, 0x46, 0x3a, 0x1a, 0x6d, 0x0b, 0xd0, 0xad, 0x35, 0x6d, 0x4e, + 0xd4, 0x00, 0x4a, 0x4f, 0x0a, 0xc8, 0xa8, 0x57, 0x8c, 0x7b, 0x14, 0xf9, + 0x3f, 0x4d, 0xcb, 0xf7, 0x98, 0xa6, 0xe8, 0x31, 0xe0, 0xb1, 0x66, 0x0a, + 0x69, 0x1e, 0xd0, 0xa4, 0x94, 0xf6, 0xe3, 0x70, 0xff, 0x54, 0x4b, 0x4c, + 0x49, 0x74, 0xa3, 0xf4, 0xce, 0x7c, 0x69, 0x56, 0x1f, 0x58, 0xda, 0x1c, + 0xbe, 0x38, 0xcb, 0x6e, 0xb0, 0x07, 0x46, 0xd3, 0x18, 0x62, 0x11, 0x49, + 0xcc, 0x13, 0x80, 0xf9, 0xd5, 0x8b, 0x72, 0xe6, 0x6a, 0x08, 0xdc, 0x32, + 0xc3, 0xc3, 0xe2, 0x47, 0x09, 0x15, 0xb1, 0xa9, 0xf0, 0x56, 0x16, 0x84, + 0x77, 0x5d, 0x82, 0x17, 0xbc, 0xd5, 0xcd, 0x98, 0x99, 0xb8, 0x00, 0x18, + 0x0a, 0xc2, 0xe4, 0x91, 0x16, 0xc2, 0x63, 0x06, 0x1a, 0xe7, 0xec, 0x05, + 0x08, 0x3a, 0x0c, 0x60, 0xa8, 0xec, 0x1d, 0x8c, 0xd0, 0x97, 0xcd, 0x48, + 0x9b, 0x01, 0x3c, 0x8d, 0xc2, 0x11, 0x35, 0x66, 0x75, 0xa4, 0xd4, 0xdf, + 0x25, 0xe1, 0x1b, 0x63, 0x37, 0xdf, 0x87, 0xdb, 0x89, 0x62, 0xe1, 0x2d, + 0x30, 0xaa, 0x36, 0x57, 0x1d, 0x2c, 0x0a, 0x2e, 0xa3, 0x2c, 0x9a, 0x16, + 0x5c, 0xe6, 0x04, 0x0c, 0x39, 0x22, 0xf9, 0x0c, 0xe1, 0xe2, 0xc8, 0xde, + 0x26, 0xd5, 0x36, 0xbf, 0xef, 0x25, 0x2e, 0x1d, 0x49, 0x5d, 0x75, 0xe9, + 0xc8, 0xad, 0x7f, 0xc5, 0x4e, 0x8b, 0xaa, 0x86, 0x03, 0xd5, 0x36, 0xe8, + 0xe0, 0x42, 0x6e, 0x04, 0xc3, 0xaa, 0x4d, 0x9b, 0xe2, 0xee, 0x03, 0xf5, + 0x6c, 0x53, 0xec, 0x77, 0xd3, 0x00, 0x6e, 0x87, 0xad, 0xc1, 0x0f, 0xe2, + 0x48, 0xdb, 0x58, 0xa5, 0xf3, 0xee, 0x8d, 0x75, 0xeb, 0x12, 0x37, 0x9a, + 0xef, 0xfc, 0xa5, 0xf7, 0x1c, 0x33, 0xe2, 0x7a, 0xaf, 0x61, 0x6d, 0x0f, + 0x92, 0xff, 0x2a, 0x10, 0xee, 0xf3, 0x43, 0xe4, 0xad, 0xbd, 0x83, 0xf7, + 0xdd, 0xd1, 0x2e, 0x06, 0x0d, 0xf4, 0x0e, 0x2f, 0x89, 0x6c, 0xe1, 0x54, + 0x81, 0x36, 0x5c, 0x7d, 0xae, 0xa6, 0x5f, 0xc0, 0xd9, 0x3d, 0x58, 0x6e, + 0xeb, 0x13, 0x2a, 0x5c, 0x48, 0xbb, 0x58, 0xb9, 0x2c, 0xe2, 0xb4, 0xaf, + 0x9b, 0x15, 0xe0, 0xda, 0x64, 0x0d, 0x17, 0x7a, 0xc6, 0x7e, 0x5f, 0x46, + 0xa9, 0x50, 0xb9, 0x16, 0x43, 0xba, 0xa9, 0x54, 0x29, 0x35, 0xb1, 0xab, + 0xa0, 0xc9, 0xe2, 0x93, 0x81, 0x47, 0x31, 0x16, 0x8b, 0xa4, 0x77, 0x36, + 0xf6, 0xc1, 0xb9, 0x91, 0x38, 0xa0, 0x88, 0xc8, 0x82, 0x43, 0x84, 0x83, + 0xa7, 0x59, 0x36, 0x43, 0x76, 0xcd, 0xd6, 0x0e, 0xac, 0x46, 0x51, 0x59, + 0xca, 0x00, 0x79, 0x1e, 0xdb, 0xb2, 0x4d, 0xc3, 0x44, 0x3f, 0xaa, 0x6c, + 0xd8, 0xea, 0x6c, 0xd3, 0xd0, 0xe0, 0x3a, 0xf7, 0x2c, 0xf7, 0x6c, 0xb7, + 0xe9, 0x5d, 0xc5, 0x1b, 0xfc, 0x0b, 0x56, 0xc3, 0x61, 0x55, 0x91, 0x3a, + 0x5f, 0xc5, 0x41, 0xf6, 0xaa, 0xbf, 0xe4, 0xb4, 0xd9, 0x6d, 0xa2, 0x3e, + 0xb5, 0xd0, 0x80, 0x3a, 0x66, 0x9a, 0x66, 0x6e, 0xfd, 0x7c, 0x5d, 0x55, + 0xed, 0x18, 0xab, 0x7a, 0x24, 0xf2, 0x8e, 0xd3, 0xc6, 0xdc, 0x1d, 0x03, + 0x83, 0x37, 0x20, 0x13, 0xc9, 0x5d, 0x12, 0x75, 0xdf, 0x23, 0xb0, 0xc4, + 0xd9, 0x5e, 0xc4, 0x14, 0x51, 0x7c, 0x46, 0x06, 0x22, 0x29, 0xc9, 0x21, + 0x2e, 0x9a, 0xdb, 0x15, 0x2b, 0x6e, 0xf5, 0x1e, 0xd3, 0xb9, 0xc2, 0xa5, + 0xc4, 0x7d, 0xc9, 0xcd, 0x5b, 0xd5, 0xd9, 0xdc, 0xe5, 0x93, 0x4a, 0xba, + 0x1d, 0x59, 0x9e, 0x85, 0xe7, 0x63, 0xd4, 0xf5, 0xf0, 0x2a, 0x1b, 0xbe, + 0x77, 0xf5, 0x85, 0x7f, 0x62, 0x38, 0x96, 0x08, 0x93, 0x50, 0x8c, 0x67, + 0xc2, 0xf3, 0x28, 0x18, 0xdd, 0xbc, 0x2b, 0xde, 0xc0, 0xd2, 0xf5, 0x35, + 0x40, 0x65, 0xde, 0x55, 0xb8, 0xad, 0x37, 0x2a, 0x52, 0x3d, 0xbd, 0x95, + 0x46, 0xf2, 0x7d, 0x73, 0xca, 0xd2, 0x05, 0x19, 0x13, 0x6e, 0x97, 0x03, + 0x51, 0x11, 0x02, 0x5e, 0x80, 0x7b, 0xde, 0x8c, 0xc8, 0x24, 0x04, 0x71, + 0xdc, 0x54, 0xa8, 0x82, 0xa0, 0xe5, 0xad, 0x34, 0xac, 0x51, 0x90, 0xa9, + 0x43, 0xf4, 0x8d, 0xa0, 0xfb, 0xf9, 0x16, 0xe9, 0xcc, 0xa1, 0x61, 0x3e, + 0x71, 0xd5, 0x6a, 0xd2, 0x86, 0x7d, 0x9a, 0x42, 0x15, 0x2b, 0x03, 0x1c, + 0x55, 0x05, 0x1c, 0x0d, 0x04, 0xe2, 0xfe, 0x24, 0x9a, 0xe3, 0x1b, 0x74, + 0x46, 0xb7, 0x10, 0xc2, 0x76, 0x83, 0x46, 0x3e, 0xa4, 0x92, 0x09, 0xc9, + 0x78, 0x51, 0x32, 0x0e, 0xa3, 0x28, 0xc4, 0x07, 0x77, 0xab, 0xbf, 0xd8, + 0x32, 0xeb, 0xbe, 0xba, 0x2b, 0x87, 0x6f, 0x5e, 0x9f, 0xbc, 0xfe, 0xf1, + 0xc0, 0xd6, 0xbb, 0x6e, 0x23, 0x8a, 0x26, 0x1d, 0x15, 0xcb, 0xa1, 0x4c, + 0x01, 0x9f, 0x67, 0x59, 0xda, 0x36, 0xfa, 0xff, 0x5c, 0x70, 0x9f, 0x51, + 0xab, 0xeb, 0xb0, 0x0e, 0x1b, 0xc1, 0x6f, 0x30, 0x38, 0x8a, 0xf0, 0xbd, + 0xc2, 0xfb, 0x4a, 0xb8, 0x59, 0xf0, 0xe3, 0xbb, 0x3b, 0xc1, 0xcc, 0x89, + 0xf1, 0x92, 0x41, 0xc5, 0x4c, 0xbb, 0x0c, 0xe8, 0x14, 0x19, 0x15, 0xd9, + 0xec, 0xb8, 0x44, 0xa4, 0x12, 0x1c, 0x12, 0xec, 0x31, 0xce, 0x4f, 0x1b, + 0xd9, 0x84, 0xa9, 0xd3, 0x20, 0x5d, 0x5b, 0x82, 0x37, 0x63, 0xb7, 0xb5, + 0x3b, 0x35, 0x5b, 0x0c, 0x70, 0xf1, 0xe4, 0xbe, 0xb0, 0x45, 0x04, 0xbb, + 0xa0, 0xd0, 0xcd, 0xdf, 0xb0, 0x43, 0xd8, 0x08, 0x9b, 0xee, 0x56, 0x6b, + 0xaa, 0xf6, 0x48, 0x64, 0x03, 0x96, 0xdd, 0x8a, 0xd1, 0xf8, 0x78, 0x67, + 0xc4, 0x4b, 0x4e, 0x96, 0x4b, 0xde, 0xb9, 0x68, 0x55, 0xe2, 0x04, 0x8f, + 0xf8, 0x55, 0x0c, 0x6b, 0xe8, 0x27, 0x6c, 0x0c, 0x66, 0xbb, 0x30, 0x1b, + 0x60, 0xd1, 0x76, 0xca, 0xb1, 0xa2, 0x0e, 0x5a, 0x89, 0x16, 0xdc, 0x8a, + 0xc5, 0x39, 0x7f, 0x02, 0x1a, 0x50, 0x18, 0x48, 0x1e, 0x83, 0x69, 0x57, + 0x1a, 0x58, 0x6d, 0x62, 0xb1, 0xdd, 0x7f, 0x6d, 0x9f, 0xb5, 0xbd, 0x7f, + 0x87, 0x7d, 0xf5, 0xb3, 0x18, 0x58, 0xad, 0x23, 0xc4, 0xd9, 0xba, 0x7f, + 0xfb, 0x3f, 0xda, 0xa2, 0xd5, 0x70, 0x07, 0x34, 0xf6, 0xdf, 0xec, 0x95, + 0x0d, 0x63, 0x45, 0x90, 0xd6, 0x36, 0xcf, 0xcf, 0x5e, 0x1f, 0xff, 0x78, + 0xba, 0xb5, 0xae, 0xdd, 0x22, 0x5c, 0xb5, 0x1c, 0xd0, 0xe7, 0x83, 0xf9, + 0xa3, 0xba, 0x4e, 0x49, 0xc3, 0x7a, 0x21, 0x71, 0x64, 0xaf, 0xe3, 0x11, + 0x59, 0xf7, 0x6d, 0xf6, 0x8c, 0x16, 0xe6, 0xea, 0x9a, 0xff, 0x8c, 0x31, + 0x7e, 0xa1, 0xd5, 0xcf, 0x6f, 0xd6, 0x50, 0x6b, 0xc6, 0x5d, 0xd1, 0x7e, + 0x18, 0xbb, 0x91, 0x0f, 0x1b, 0x85, 0xc5, 0x43, 0x91, 0xa5, 0x66, 0xc8, + 0x5f, 0x5b, 0xdd, 0x38, 0xe1, 0xa9, 0x2d, 0xf6, 0xbe, 0xbb, 0x2d, 0x4d, + 0x54, 0xa6, 0x87, 0x34, 0x3f, 0xdb, 0x28, 0x6a, 0x3e, 0xde, 0x0f, 0xde, + 0x8e, 0x55, 0x42, 0xf2, 0x67, 0xa9, 0x59, 0xe6, 0x9a, 0xba, 0x6b, 0x13, + 0xd6, 0xd4, 0x85, 0x56, 0xec, 0x85, 0xab, 0x3a, 0x76, 0x97, 0xb1, 0x29, + 0x86, 0xfa, 0xa4, 0x8f, 0x5a, 0x60, 0x4e, 0x1d, 0xb8, 0x69, 0x88, 0xd3, + 0x31, 0x0f, 0x26, 0x7d, 0x16, 0x89, 0xbd, 0xec, 0x5e, 0x73, 0x57, 0xdc, + 0xea, 0x88, 0x1c, 0xea, 0xcd, 0x5f, 0x5d, 0x77, 0x32, 0xb7, 0x25, 0xee, + 0xb6, 0x04, 0xa7, 0xda, 0xee, 0xad, 0x6f, 0xd6, 0x8a, 0xfa, 0x78, 0xee, + 0x16, 0x23, 0xab, 0x7e, 0x6e, 0xe6, 0x76, 0x8f, 0xdb, 0xe8, 0xdf, 0x82, + 0xe2, 0xe9, 0x42, 0x95, 0x63, 0x18, 0xcf, 0x3b, 0x50, 0x3c, 0x35, 0x70, + 0xf2, 0xff, 0x43, 0xf1, 0xfc, 0xdf, 0x13, 0xc5, 0xf3, 0x07, 0x81, 0x57, + 0xa2, 0x56, 0x41, 0x59, 0xde, 0xe9, 0xef, 0x34, 0x34, 0x89, 0x51, 0x2e, + 0x65, 0x2d, 0xa9, 0xb2, 0xea, 0x68, 0x91, 0x69, 0x4d, 0xca, 0xc1, 0xe2, + 0xb2, 0x45, 0x1a, 0x69, 0x42, 0x4c, 0xae, 0x25, 0x74, 0xde, 0x5f, 0xdf, + 0xad, 0xdd, 0x8c, 0xf5, 0x89, 0x40, 0x93, 0xcb, 0xef, 0x7e, 0x2e, 0xb8, + 0xc9, 0xa8, 0xd1, 0xd5, 0xb2, 0x8c, 0xbf, 0x24, 0x93, 0xa7, 0xf8, 0xd3, + 0xc7, 0x34, 0x5c, 0x71, 0x04, 0x64, 0x3e, 0xcc, 0xb8, 0xc0, 0x32, 0xb1, + 0x5f, 0x16, 0x2e, 0x12, 0x5f, 0xd5, 0x42, 0x98, 0x67, 0xa3, 0x86, 0x60, + 0x9c, 0x0c, 0xdf, 0xec, 0xec, 0x23, 0xe2, 0x9e, 0x3e, 0x31, 0x46, 0x24, + 0xea, 0xae, 0x53, 0x5d, 0x95, 0x8b, 0x01, 0xb0, 0x82, 0xdb, 0xce, 0x27, + 0x89, 0x1d, 0xbe, 0xb1, 0x6e, 0x2b, 0x2f, 0xb5, 0x6b, 0xb0, 0xb9, 0xc4, + 0xd5, 0xa4, 0x47, 0x31, 0x6f, 0x58, 0x04, 0x50, 0x3d, 0x5c, 0x02, 0x6d, + 0x4d, 0x94, 0x9c, 0x52, 0x06, 0x06, 0x79, 0x16, 0x38, 0x95, 0x36, 0x19, + 0x4f, 0xd2, 0x1b, 0xd5, 0xe4, 0x81, 0x97, 0xec, 0xc2, 0x51, 0x08, 0x99, + 0x89, 0x02, 0xfc, 0x20, 0x97, 0xca, 0x0f, 0xc7, 0x87, 0xe7, 0x17, 0x6d, + 0x82, 0xa5, 0xc3, 0x26, 0x33, 0x2d, 0x4f, 0x43, 0xd8, 0x5c, 0xec, 0x8f, + 0xa9, 0x0b, 0x9c, 0xcb, 0x13, 0x82, 0x45, 0xf0, 0x22, 0xbb, 0x15, 0xf8, + 0x3a, 0x2d, 0xab, 0x8e, 0xc3, 0xe5, 0xd1, 0xa2, 0x83, 0x5b, 0x52, 0x03, + 0x29, 0x5a, 0x8f, 0x72, 0x4d, 0x0c, 0x2e, 0x2f, 0x23, 0x07, 0x44, 0x3a, + 0xe0, 0x50, 0x41, 0xe8, 0x1c, 0xb4, 0xf0, 0xa9, 0xe8, 0x9e, 0x55, 0x81, + 0x15, 0x8a, 0x26, 0xec, 0x39, 0x21, 0x46, 0xd8, 0xa8, 0x32, 0xdf, 0x9a, + 0xe0, 0x87, 0x66, 0x4c, 0x4e, 0xde, 0xaf, 0x30, 0x46, 0x45, 0x40, 0xbb, + 0x90, 0x91, 0x71, 0xc4, 0xc0, 0x8e, 0x99, 0x46, 0xfd, 0x8c, 0x43, 0x79, + 0x06, 0x95, 0x9c, 0xd8, 0x78, 0x09, 0x2d, 0x32, 0x9a, 0x08, 0xbe, 0xac, + 0x59, 0x8f, 0xfd, 0xa6, 0x3d, 0xc3, 0x2f, 0xd5, 0xa4, 0x28, 0x80, 0x8b, + 0x89, 0x1d, 0x03, 0xdf, 0xd2, 0xbd, 0x12, 0x85, 0xcc, 0xf2, 0xbf, 0xe8, + 0x2d, 0x61, 0xc4, 0x93, 0xf4, 0x92, 0x5d, 0x36, 0xd5, 0x7b, 0x96, 0x06, + 0x85, 0xdf, 0x12, 0x24, 0xf8, 0x0a, 0x17, 0x71, 0x83, 0x5a, 0x92, 0xc8, + 0xe0, 0xd7, 0xae, 0x68, 0x37, 0x3d, 0x94, 0xab, 0x28, 0xef, 0xde, 0x30, + 0xf7, 0x8f, 0xb4, 0x9e, 0x34, 0x9a, 0x5f, 0xeb, 0x48, 0x36, 0x46, 0xf4, + 0x69, 0x9a, 0x7a, 0xb3, 0x95, 0x3b, 0xd8, 0x1b, 0x3e, 0xb9, 0xa8, 0x8b, + 0x1e, 0xcb, 0x89, 0x14, 0x37, 0xd3, 0x34, 0xad, 0xb6, 0x3d, 0xb3, 0xae, + 0x99, 0x95, 0xed, 0x9f, 0x52, 0x33, 0xc7, 0xa0, 0x6f, 0x9c, 0x52, 0x4e, + 0x01, 0xeb, 0xfc, 0x99, 0xc6, 0x4c, 0xf5, 0x93, 0x24, 0x59, 0x29, 0xf5, + 0xb7, 0x0e, 0x66, 0x3d, 0x6c, 0x46, 0x61, 0x2c, 0x6b, 0xed, 0x5a, 0xa3, + 0x87, 0xb5, 0xb7, 0xae, 0x39, 0xb2, 0x8f, 0x96, 0x46, 0x7d, 0xbd, 0xab, + 0xaf, 0x1b, 0xf6, 0xf0, 0xd6, 0x1e, 0x56, 0xef, 0x6d, 0x14, 0x76, 0x72, + 0x67, 0x98, 0x53, 0xfc, 0xe4, 0xff, 0x6d, 0x82, 0x9d, 0x88, 0xcb, 0xee, + 0xf6, 0xf7, 0xe3, 0x00, 0x27, 0x1d, 0xa6, 0x74, 0xe5, 0x12, 0x1f, 0xee, + 0x09, 0x70, 0x42, 0xae, 0xc6, 0xcc, 0x70, 0x3f, 0x8e, 0x74, 0x12, 0xbb, + 0x6e, 0xc8, 0xbf, 0xf9, 0xa4, 0x48, 0xa7, 0x15, 0xb1, 0xa3, 0xb4, 0x92, + 0xa2, 0x26, 0x2f, 0x15, 0xb6, 0xf6, 0x49, 0x44, 0x30, 0x2e, 0xf8, 0x6f, + 0x80, 0xc9, 0x24, 0x06, 0xec, 0x53, 0xe1, 0x0d, 0x8c, 0x1c, 0xab, 0x32, + 0x08, 0x18, 0xfa, 0x7e, 0xff, 0x71, 0x9f, 0xf2, 0x69, 0xe9, 0xe9, 0x36, + 0x51, 0x51, 0x24, 0x45, 0xa2, 0x72, 0x7d, 0x0b, 0x5f, 0xb0, 0xd6, 0x1a, + 0x4b, 0x22, 0xeb, 0x2a, 0x7e, 0x24, 0xae, 0x2e, 0x26, 0xd5, 0xae, 0xf8, + 0xa0, 0x0a, 0x1b, 0x57, 0x90, 0xaa, 0x96, 0xb8, 0x2e, 0x85, 0x16, 0x69, + 0xd1, 0x11, 0x63, 0x4a, 0x6b, 0x57, 0x16, 0x5b, 0xb4, 0xc5, 0xdf, 0x20, + 0xe4, 0xc4, 0x3d, 0xc2, 0x64, 0xdf, 0x1d, 0x1e, 0x9f, 0xbf, 0xdb, 0xdd, + 0x7b, 0xf2, 0xee, 0xc7, 0xa3, 0x57, 0xef, 0x42, 0x8c, 0xd7, 0x47, 0x1e, + 0x4f, 0x44, 0x0e, 0xd9, 0x8d, 0x93, 0x8c, 0x9a, 0x4b, 0x41, 0x29, 0x1d, + 0x71, 0xf7, 0xf7, 0x25, 0x72, 0xc0, 0xd3, 0x28, 0x23, 0xb6, 0x06, 0xd0, + 0xe2, 0x3e, 0x35, 0xcd, 0x2f, 0xf4, 0x20, 0x6d, 0xad, 0xd7, 0xd2, 0xf9, + 0xbc, 0x30, 0xaf, 0x35, 0x46, 0x1b, 0x01, 0xe3, 0xc2, 0xfa, 0x75, 0xce, + 0xdf, 0x9c, 0x75, 0xba, 0x74, 0xed, 0x42, 0xcb, 0x3d, 0xf8, 0x2b, 0xd9, + 0x44, 0x04, 0xe0, 0x47, 0x3b, 0x8f, 0x1e, 0x6e, 0xf5, 0x5b, 0x92, 0xe2, + 0xb8, 0x41, 0x9f, 0x29, 0x00, 0x62, 0x4e, 0x56, 0x32, 0x86, 0x95, 0x2b, + 0xdb, 0xce, 0xc4, 0x4d, 0x83, 0xd2, 0x86, 0x65, 0x10, 0xab, 0xae, 0x74, + 0x3f, 0xeb, 0x38, 0x72, 0x35, 0xb2, 0x3d, 0xac, 0xb6, 0xab, 0xfa, 0x06, + 0xd6, 0x0a, 0xac, 0xfe, 0xa4, 0x4a, 0xd5, 0xcb, 0x7d, 0xe1, 0xdc, 0x3e, + 0x4b, 0x78, 0x35, 0x34, 0xba, 0xd0, 0xe4, 0x7d, 0xf7, 0x99, 0x4b, 0x2f, + 0x6f, 0x4c, 0xd7, 0xa2, 0xe3, 0x9f, 0x72, 0xf2, 0xbe, 0xa3, 0x93, 0x90, + 0xfc, 0xcf, 0xd5, 0x1d, 0x5d, 0xe0, 0x57, 0x0b, 0x09, 0x69, 0x2a, 0xb5, + 0x59, 0x2b, 0x22, 0x07, 0xf2, 0xf2, 0x94, 0x23, 0x2f, 0x4a, 0x4c, 0x74, + 0xc0, 0x68, 0xbd, 0x17, 0x78, 0x69, 0x8b, 0x68, 0x86, 0x9c, 0x14, 0x72, + 0x27, 0x06, 0x15, 0xc9, 0xfc, 0x4a, 0x3f, 0xc4, 0xff, 0x57, 0xd3, 0x4d, + 0xc8, 0x12, 0xf8, 0x44, 0xba, 0xb1, 0x06, 0xfe, 0x0d, 0x74, 0x63, 0x7d, + 0xc5, 0x86, 0xc5, 0xcf, 0x64, 0xaa, 0x92, 0x15, 0x5e, 0xa6, 0x15, 0x5a, + 0xf7, 0xa6, 0xea, 0x6a, 0x85, 0xe1, 0xc7, 0x52, 0x87, 0x7b, 0xc9, 0x72, + 0x18, 0xe8, 0x86, 0xeb, 0x61, 0x44, 0x74, 0x23, 0x41, 0x31, 0x9a, 0x87, + 0xef, 0xb2, 0xc5, 0xc4, 0xfc, 0xdb, 0x46, 0x3c, 0xfd, 0xc4, 0xd3, 0xc8, + 0x0a, 0x2a, 0xb1, 0x45, 0xa2, 0x89, 0xae, 0x26, 0x17, 0x57, 0x05, 0x95, + 0x08, 0x26, 0x50, 0x0c, 0x8b, 0x0c, 0xde, 0xb7, 0xa6, 0x8b, 0xf0, 0x85, + 0xfd, 0x6b, 0xda, 0x4d, 0x35, 0xa5, 0xd3, 0xf3, 0x9b, 0xdd, 0xa0, 0x6b, + 0xf0, 0x81, 0xeb, 0xdd, 0x60, 0xa6, 0xc7, 0xc0, 0x0b, 0x12, 0xf7, 0x9d, + 0xd2, 0x06, 0x6b, 0xf1, 0x81, 0x8f, 0xac, 0x37, 0xc1, 0xb5, 0xa9, 0x82, + 0x7d, 0x5d, 0xe2, 0x54, 0xb1, 0x50, 0xe2, 0x66, 0x48, 0xca, 0xb8, 0xca, + 0x2f, 0xe1, 0x1e, 0x5b, 0x7d, 0x1c, 0xaf, 0x77, 0xf9, 0x20, 0x4a, 0xf0, + 0xcb, 0xaa, 0x73, 0xb8, 0x42, 0xb6, 0xe7, 0x06, 0x3e, 0x8f, 0x49, 0x9f, + 0xdb, 0xfa, 0x0d, 0x7b, 0xa0, 0x6b, 0xfd, 0xb6, 0x1b, 0x7b, 0x06, 0x9e, + 0x06, 0xd7, 0x00, 0xec, 0x48, 0x8b, 0x2b, 0xda, 0x4e, 0x56, 0x8c, 0xc4, + 0xc2, 0xc2, 0x5e, 0x88, 0xb4, 0x6c, 0xda, 0x82, 0xcc, 0x18, 0x44, 0xa5, + 0xb2, 0x18, 0x8c, 0x28, 0x64, 0x82, 0x27, 0xe7, 0xe7, 0x67, 0x27, 0x3d, + 0x46, 0x23, 0x13, 0x28, 0x03, 0x2b, 0xae, 0x4d, 0xfe, 0x4e, 0x8c, 0x38, + 0xcc, 0x72, 0x8c, 0x53, 0x90, 0x8a, 0x5e, 0xe6, 0x5c, 0x82, 0x1e, 0xdb, + 0x5c, 0x37, 0x8c, 0x98, 0x6e, 0x30, 0x34, 0x58, 0x9a, 0x4b, 0x31, 0x25, + 0x81, 0xfa, 0x27, 0xb0, 0xcc, 0xee, 0xa2, 0xf7, 0x53, 0x0a, 0x73, 0x62, + 0x38, 0x54, 0x12, 0xe7, 0x3d, 0xca, 0x0a, 0x25, 0x77, 0x06, 0x38, 0xb5, + 0x46, 0x5e, 0xbf, 0x83, 0x7b, 0x71, 0xf6, 0x83, 0x83, 0xa4, 0xd3, 0x7b, + 0x9b, 0x1c, 0x74, 0x74, 0x1d, 0x4e, 0x67, 0x92, 0xb0, 0x5f, 0xa9, 0x0c, + 0x9a, 0xf3, 0xc5, 0x50, 0x29, 0xb0, 0xe0, 0x15, 0xc1, 0x19, 0xb9, 0x9a, + 0x66, 0x21, 0xfa, 0x91, 0xa3, 0x11, 0x9d, 0xb1, 0x57, 0x32, 0x36, 0x49, + 0x85, 0xc0, 0xc0, 0x4a, 0x75, 0xe7, 0x2b, 0x58, 0x5b, 0x36, 0x63, 0xf0, + 0x1d, 0x06, 0x41, 0xa7, 0x9a, 0x1d, 0xc3, 0x32, 0x1b, 0x31, 0x94, 0x67, + 0xe5, 0x1b, 0x2a, 0xaa, 0x2a, 0x1f, 0x80, 0x18, 0x74, 0xa9, 0x08, 0x47, + 0x15, 0x46, 0x9f, 0x0c, 0x34, 0xa5, 0x8d, 0x56, 0xaa, 0xd2, 0x44, 0x34, + 0x86, 0xa6, 0x11, 0xbc, 0x04, 0x33, 0x48, 0x51, 0xa8, 0x27, 0xd7, 0x49, + 0x42, 0xff, 0xf4, 0x75, 0x8e, 0x2d, 0x66, 0x12, 0x99, 0x33, 0x2d, 0x68, + 0x09, 0x15, 0x4a, 0x1f, 0xce, 0x33, 0xa5, 0x46, 0x9e, 0x63, 0x42, 0x27, + 0x9a, 0x89, 0xab, 0x3c, 0xe4, 0xe4, 0x13, 0xa0, 0x73, 0xc0, 0xa1, 0x2f, + 0x33, 0x84, 0x76, 0xbd, 0xce, 0x74, 0x5f, 0xc4, 0x4f, 0x60, 0x90, 0xd9, + 0x08, 0x45, 0x3d, 0xcd, 0xb1, 0x4e, 0x31, 0xed, 0xe2, 0x2c, 0xb3, 0x5a, + 0x1c, 0xaa, 0xec, 0x51, 0x77, 0x09, 0x9e, 0x51, 0x0e, 0x58, 0x8c, 0x2b, + 0xa0, 0x7b, 0x43, 0xa5, 0x5e, 0xe5, 0x5f, 0x0c, 0x7b, 0x51, 0xfb, 0x20, + 0x56, 0x7a, 0xa0, 0xbe, 0x9e, 0xfb, 0xc3, 0xd2, 0x96, 0x7c, 0x6f, 0x48, + 0xac, 0x31, 0xdb, 0x44, 0x56, 0xf6, 0xd4, 0xa1, 0xd7, 0x7d, 0xb7, 0x3a, + 0xf3, 0x99, 0x1d, 0x9f, 0x62, 0x5d, 0xe4, 0x5a, 0x05, 0x92, 0xbf, 0x16, + 0x01, 0x77, 0xc5, 0x76, 0x42, 0x17, 0x56, 0x90, 0xd7, 0x2e, 0xaa, 0x00, + 0xf9, 0x33, 0xbd, 0x16, 0x83, 0x74, 0x65, 0x6a, 0x15, 0xd1, 0x2c, 0xfc, + 0x21, 0x05, 0x98, 0xd5, 0x37, 0x48, 0x58, 0x62, 0xe0, 0xd7, 0x12, 0x07, + 0x0d, 0x88, 0x2b, 0x5f, 0xc6, 0xd2, 0x44, 0x4a, 0x89, 0xff, 0x26, 0xa8, + 0xac, 0x1a, 0x08, 0x6f, 0x2e, 0xc5, 0x13, 0x98, 0xa5, 0x68, 0xf8, 0xb6, + 0x01, 0x4e, 0x2d, 0x05, 0x19, 0x85, 0x1c, 0x10, 0x05, 0xce, 0x4b, 0x62, + 0xf3, 0x6a, 0x03, 0x83, 0xdd, 0x52, 0xd3, 0xf4, 0xd9, 0xdd, 0x55, 0x19, + 0x01, 0xd8, 0xcc, 0x67, 0x61, 0xee, 0xd8, 0xd0, 0x27, 0x46, 0x94, 0x76, + 0x97, 0x71, 0x8a, 0xb2, 0x88, 0xdd, 0xcf, 0xbb, 0x6d, 0x38, 0x5b, 0x8c, + 0xeb, 0xe4, 0x81, 0x84, 0x82, 0x6e, 0x6f, 0x2d, 0x7b, 0x73, 0xa8, 0xab, + 0x9c, 0x90, 0xf8, 0x86, 0x70, 0xc5, 0x60, 0xae, 0x98, 0x95, 0x1d, 0x6f, + 0x81, 0x83, 0x83, 0x50, 0x4c, 0xb0, 0x74, 0x0e, 0x1f, 0xa6, 0x02, 0x2a, + 0x39, 0x4d, 0x47, 0x59, 0x33, 0x16, 0xc2, 0x8d, 0xa6, 0x11, 0x96, 0xcf, + 0x24, 0x63, 0x51, 0x99, 0x16, 0x3c, 0xa7, 0x7e, 0x08, 0xc1, 0x38, 0x26, + 0x2e, 0x42, 0xd9, 0xce, 0x6a, 0xa3, 0x09, 0x85, 0x32, 0x34, 0x26, 0x82, + 0x48, 0x56, 0x09, 0x9d, 0x26, 0x84, 0x71, 0xfe, 0x42, 0x53, 0xf1, 0xd4, + 0x04, 0xc2, 0xac, 0x30, 0xe2, 0xe6, 0x98, 0x4f, 0xc6, 0xf0, 0x8f, 0xc7, + 0x99, 0x18, 0xbc, 0x92, 0xc6, 0x6e, 0x8b, 0x89, 0x5e, 0xc3, 0x46, 0x19, + 0x82, 0x4e, 0x72, 0x06, 0xa4, 0x7c, 0x78, 0x12, 0x1e, 0x16, 0x72, 0x46, + 0xba, 0xd7, 0x2e, 0x34, 0x03, 0xbe, 0x67, 0x11, 0xda, 0x2b, 0xad, 0x88, + 0xb2, 0xc0, 0x9f, 0x2f, 0xc0, 0x96, 0x1b, 0x5c, 0x83, 0x74, 0xa5, 0xe7, + 0xcf, 0x11, 0x12, 0x2d, 0x1e, 0xe8, 0x10, 0x0f, 0xb7, 0x79, 0x8e, 0xe0, + 0x62, 0xe7, 0x47, 0x67, 0x5b, 0xc9, 0x59, 0xf0, 0x80, 0x6a, 0x60, 0x5c, + 0x9f, 0x10, 0xf5, 0x3c, 0x78, 0x9b, 0xa4, 0x93, 0x49, 0xa8, 0xdc, 0xb2, + 0xd7, 0x98, 0xe8, 0xd9, 0x92, 0x39, 0x28, 0x18, 0xdf, 0x27, 0x62, 0x44, + 0xdc, 0x25, 0x8d, 0x71, 0xbc, 0xc4, 0xe3, 0xea, 0x5d, 0xa6, 0x12, 0xe9, + 0xa5, 0x08, 0xea, 0x6d, 0xb1, 0x5c, 0xd8, 0x85, 0x54, 0x9f, 0x42, 0xb6, + 0xdd, 0x12, 0x2b, 0x89, 0xbf, 0x5f, 0x66, 0x33, 0xbc, 0x64, 0xc8, 0x90, + 0x6c, 0x4c, 0x57, 0x48, 0x9d, 0x2a, 0x99, 0xd4, 0x99, 0x12, 0x3c, 0xea, + 0x74, 0xa1, 0x73, 0x19, 0x54, 0x4e, 0x78, 0xb0, 0x72, 0x32, 0x2c, 0x52, + 0xd9, 0x55, 0x44, 0x81, 0xdb, 0x0e, 0x33, 0xd9, 0x14, 0x1c, 0x02, 0xaf, + 0xc1, 0x39, 0xc6, 0x88, 0xe3, 0xc3, 0x55, 0x75, 0xb5, 0x87, 0xf9, 0x97, + 0xfd, 0x27, 0x41, 0x1c, 0x16, 0x6e, 0x8b, 0xf2, 0x44, 0x0d, 0x92, 0xd3, + 0x58, 0x13, 0x66, 0xa2, 0x56, 0x0c, 0x00, 0x82, 0x6f, 0xd1, 0x7b, 0x9d, + 0xae, 0xbf, 0xb1, 0x18, 0x2f, 0xb7, 0x4f, 0x7b, 0x06, 0xbf, 0x27, 0xd5, + 0xca, 0xaa, 0xbb, 0x51, 0x91, 0xdd, 0x70, 0x55, 0xfe, 0x09, 0xd9, 0xe0, + 0xdf, 0x17, 0xb8, 0x96, 0x4f, 0x45, 0x0a, 0x50, 0x2a, 0x23, 0x22, 0x7b, + 0x8e, 0xd1, 0xf7, 0xf0, 0xf2, 0x8c, 0xb0, 0xc7, 0xd3, 0x72, 0x90, 0xc3, + 0xda, 0x96, 0xb7, 0x21, 0xbd, 0x41, 0xe3, 0x57, 0x95, 0x8d, 0xe0, 0x5b, + 0xe4, 0xf1, 0x87, 0x5f, 0x54, 0x58, 0x40, 0xe7, 0x56, 0x3f, 0xf9, 0x13, + 0xf5, 0x22, 0xef, 0x29, 0x1e, 0x2a, 0xc9, 0x91, 0x3f, 0x1c, 0x3f, 0x3f, + 0x7d, 0x73, 0xdc, 0x88, 0x8c, 0xf5, 0x01, 0xd6, 0x32, 0xa2, 0x5f, 0x31, + 0xbb, 0x55, 0x0a, 0x43, 0x71, 0xf6, 0x48, 0x8e, 0x82, 0x1b, 0x9c, 0xfe, + 0x9f, 0x9e, 0xd9, 0x80, 0x08, 0x6c, 0x70, 0xc6, 0x03, 0xb1, 0xd6, 0xba, + 0x34, 0xce, 0x81, 0x26, 0x4b, 0xa1, 0xfb, 0x09, 0x6d, 0x5f, 0x05, 0xf1, + 0xef, 0x24, 0x0c, 0x8a, 0x52, 0x5d, 0x38, 0xa5, 0x48, 0x3a, 0x4a, 0x11, + 0xdb, 0x10, 0x85, 0x4a, 0xaa, 0x2b, 0x65, 0xed, 0x85, 0x7a, 0xef, 0xf9, + 0x07, 0xae, 0x99, 0x2b, 0x21, 0x4d, 0x23, 0x04, 0x07, 0xd9, 0xe8, 0x59, + 0x58, 0x04, 0x2d, 0x23, 0x5e, 0xfc, 0x5b, 0x89, 0xf5, 0x17, 0xd6, 0x40, + 0xb3, 0x70, 0xa4, 0x33, 0x26, 0x51, 0xe4, 0x4f, 0xec, 0xe2, 0x1b, 0x39, + 0xf2, 0x40, 0xa1, 0x98, 0x4e, 0x8a, 0x03, 0xca, 0x4a, 0x7e, 0x15, 0x34, + 0x14, 0x92, 0x22, 0x43, 0x80, 0xac, 0x0f, 0x30, 0x96, 0xce, 0x36, 0xab, + 0xad, 0xa5, 0x41, 0x87, 0x5d, 0xb4, 0x24, 0xd2, 0x8d, 0xdf, 0x6f, 0x58, + 0x34, 0xbb, 0x4a, 0xcd, 0x0e, 0x84, 0x93, 0x8d, 0x42, 0xa9, 0xbf, 0x51, + 0x10, 0x3f, 0x43, 0xe4, 0x6d, 0xa2, 0x73, 0x7d, 0x58, 0x17, 0xa0, 0x2d, + 0xb3, 0xcd, 0x97, 0x76, 0xe7, 0xa5, 0xe8, 0xaf, 0x80, 0x7e, 0xae, 0xea, + 0x02, 0x0b, 0x01, 0xd4, 0x52, 0x26, 0x6a, 0x9c, 0xe6, 0x13, 0x0a, 0x8c, + 0xb6, 0xa5, 0xa4, 0x15, 0xd3, 0xb8, 0xf4, 0x24, 0xb3, 0x30, 0x34, 0xad, + 0xcf, 0xa2, 0x33, 0xc4, 0x37, 0xf1, 0xb8, 0xb5, 0xcd, 0x5e, 0x26, 0x8f, + 0xbe, 0x64, 0xd8, 0x85, 0xbc, 0x7a, 0x0f, 0xdb, 0xf6, 0x9f, 0x5b, 0x7d, + 0x57, 0xca, 0xf3, 0x26, 0xaf, 0x80, 0x63, 0x49, 0x9b, 0xe2, 0xad, 0x95, + 0xc4, 0xae, 0x44, 0x07, 0x45, 0x92, 0x7d, 0x31, 0x33, 0x28, 0x7c, 0x9b, + 0x5b, 0xd7, 0xe1, 0x4a, 0xc2, 0x38, 0xcb, 0x2c, 0xe0, 0x8a, 0x92, 0xd8, + 0x38, 0xe0, 0xa8, 0x55, 0xbf, 0x5e, 0x0b, 0xb6, 0x85, 0xe3, 0xce, 0x54, + 0xb7, 0xb3, 0x1a, 0xb9, 0x99, 0x70, 0xdc, 0x61, 0x51, 0xd2, 0x3d, 0xce, + 0xf4, 0xed, 0x4e, 0x53, 0xc5, 0x85, 0xdd, 0x92, 0x6f, 0x1e, 0x7d, 0x23, + 0xdb, 0x03, 0x13, 0x9d, 0xb1, 0x8f, 0x86, 0x1e, 0xe6, 0x61, 0x57, 0xe4, + 0x56, 0xd0, 0x71, 0x8a, 0xdb, 0x46, 0x1b, 0xc1, 0x7d, 0xc4, 0xc0, 0x9e, + 0x8c, 0x80, 0x69, 0x94, 0x55, 0x9e, 0xbb, 0xb7, 0xcd, 0x29, 0x84, 0x9f, + 0x11, 0x9a, 0x81, 0xaa, 0xa7, 0x2a, 0x38, 0x62, 0xb0, 0xe6, 0x8c, 0xb2, + 0x08, 0x71, 0x3d, 0x9e, 0x23, 0x5a, 0xb7, 0x38, 0x44, 0xd0, 0x1d, 0x0e, + 0xcb, 0x8f, 0x37, 0x49, 0xe0, 0x0e, 0x7f, 0x8f, 0xb9, 0x02, 0x73, 0x56, + 0xa5, 0x68, 0x8d, 0x97, 0xa1, 0x03, 0x26, 0x02, 0x8b, 0xb2, 0x93, 0xe4, + 0xb9, 0x5c, 0x78, 0x55, 0x28, 0x34, 0x08, 0xc7, 0x89, 0xda, 0xa3, 0xa0, + 0x26, 0xd0, 0x74, 0xb9, 0x4c, 0x0b, 0xbe, 0x29, 0xf8, 0x4a, 0x54, 0x60, + 0xa7, 0x22, 0x1d, 0x49, 0x90, 0x4c, 0x1d, 0x94, 0xa9, 0x6c, 0xf8, 0x73, + 0xab, 0x65, 0xa7, 0x65, 0xdd, 0xc5, 0x21, 0x85, 0xd8, 0xe0, 0xc1, 0x9f, + 0x49, 0x2b, 0x10, 0x8f, 0x5e, 0xdd, 0x48, 0x29, 0xf2, 0x76, 0x54, 0xdb, + 0xf8, 0x36, 0xe5, 0x5a, 0x0d, 0x99, 0x7c, 0xac, 0x44, 0x57, 0x65, 0x1a, + 0x2d, 0x44, 0x8c, 0x3f, 0x25, 0x26, 0x43, 0xb7, 0x82, 0x12, 0x10, 0x9f, + 0x64, 0x9c, 0x22, 0xa8, 0x5d, 0x0f, 0x06, 0xb7, 0xe1, 0x43, 0xa2, 0x9f, + 0xd9, 0x48, 0xc4, 0x48, 0xea, 0x28, 0xfb, 0x40, 0xc2, 0x91, 0xaf, 0x05, + 0x41, 0xe3, 0xa5, 0xa0, 0x24, 0x68, 0x91, 0xca, 0x54, 0xd4, 0x99, 0x82, + 0x0b, 0x53, 0xf5, 0xc7, 0x4c, 0x79, 0x06, 0xee, 0xcf, 0x3b, 0x50, 0x75, + 0xf1, 0x89, 0xcd, 0x7d, 0x04, 0x19, 0x43, 0x0e, 0x3a, 0xa7, 0xfc, 0x45, + 0xc6, 0xe6, 0xa7, 0x90, 0xda, 0x07, 0xae, 0x13, 0x43, 0xeb, 0xdf, 0xf4, + 0x9e, 0x4c, 0x44, 0xc1, 0x53, 0xd9, 0xe1, 0xea, 0xb2, 0x9c, 0x27, 0x97, + 0x20, 0x2b, 0xce, 0xa3, 0x55, 0xe0, 0xcf, 0xa3, 0x55, 0xe0, 0x80, 0x5f, + 0x7a, 0xf2, 0xe4, 0x99, 0x91, 0x25, 0xcd, 0x94, 0x66, 0x4f, 0xfe, 0x28, + 0xae, 0x58, 0xe1, 0xa7, 0x6f, 0x22, 0xac, 0xbd, 0xea, 0x54, 0x3a, 0x59, + 0x2e, 0xfe, 0xca, 0x16, 0x4c, 0xc6, 0xc0, 0x9f, 0x6a, 0x33, 0x44, 0xc6, + 0x23, 0x78, 0x73, 0x9a, 0x32, 0x95, 0x5e, 0xc2, 0xe9, 0xd6, 0x36, 0x4d, + 0x14, 0xba, 0x9a, 0x16, 0x23, 0x46, 0x74, 0x8d, 0x67, 0x83, 0x1f, 0xeb, + 0x6c, 0xa4, 0xee, 0x4c, 0x15, 0xc6, 0x4f, 0x2f, 0x0c, 0x30, 0x74, 0x4d, + 0xb9, 0x82, 0x33, 0xc0, 0x3f, 0xe0, 0xc4, 0x47, 0x6c, 0x87, 0x9e, 0xf3, + 0x03, 0x9a, 0x25, 0xc5, 0xb0, 0x76, 0xe3, 0xa1, 0x07, 0x98, 0x6f, 0x86, + 0x21, 0x61, 0xd8, 0x09, 0xa9, 0xcf, 0xf1, 0x90, 0xf0, 0xe3, 0x25, 0x32, + 0x83, 0x0f, 0x99, 0xe5, 0xb6, 0xaf, 0x2d, 0x37, 0xf1, 0xe0, 0x41, 0x63, + 0x6d, 0xa9, 0xf5, 0x68, 0x65, 0x07, 0xc1, 0xfa, 0xd5, 0xa0, 0x43, 0xfc, + 0xc8, 0xb5, 0xd0, 0xba, 0xac, 0xd2, 0x9e, 0x4e, 0x61, 0x82, 0xf8, 0xe8, + 0x98, 0x80, 0xf3, 0x8e, 0x46, 0xc4, 0x85, 0xd4, 0xdf, 0xf9, 0xd9, 0x4c, + 0x66, 0xac, 0xe3, 0x54, 0xb7, 0x53, 0x94, 0xb4, 0x3c, 0xcb, 0x1b, 0x12, + 0xf6, 0x3b, 0x45, 0x44, 0x52, 0xc5, 0x2a, 0x10, 0xff, 0xf8, 0x11, 0xcb, + 0x4c, 0x7a, 0xe0, 0x1a, 0x4c, 0xac, 0xc0, 0xe2, 0xbc, 0xc8, 0x67, 0x1a, + 0x19, 0x44, 0x1c, 0xc5, 0x8d, 0xc0, 0x15, 0x4d, 0x64, 0xae, 0xf2, 0x1e, + 0x91, 0xf5, 0xed, 0xa6, 0x7b, 0x87, 0x6b, 0xa6, 0x43, 0x93, 0x2f, 0xc3, + 0x25, 0x2a, 0x23, 0xd2, 0x24, 0x1f, 0x87, 0x2f, 0x26, 0x6b, 0xcd, 0x8e, + 0x55, 0x1e, 0x5a, 0xdc, 0x66, 0xa0, 0x50, 0xe9, 0xb7, 0x9d, 0x85, 0x4c, + 0xef, 0x62, 0x21, 0x51, 0x45, 0x20, 0xcf, 0x48, 0x74, 0x6f, 0x97, 0x37, + 0x3c, 0x69, 0x63, 0x25, 0x9e, 0x97, 0x58, 0x2a, 0x6d, 0x8a, 0x89, 0x94, + 0x0f, 0x98, 0x9d, 0x40, 0xb3, 0x0d, 0x5e, 0x62, 0xac, 0xa4, 0x95, 0x93, + 0x18, 0x23, 0x51, 0x26, 0xf4, 0x31, 0x7c, 0x64, 0x7e, 0x33, 0xd2, 0xd9, + 0xc3, 0xaf, 0x36, 0x77, 0xbd, 0x7d, 0x19, 0x73, 0x79, 0x50, 0x15, 0x93, + 0x45, 0xcd, 0x20, 0x74, 0x1c, 0xa0, 0x67, 0x97, 0xf0, 0xa2, 0x2c, 0xb9, + 0x24, 0x92, 0x0a, 0x50, 0xb6, 0xf0, 0xba, 0xd6, 0x25, 0x27, 0x14, 0x49, + 0x26, 0x18, 0x93, 0x8c, 0x76, 0x29, 0xdf, 0x85, 0x5e, 0xe9, 0xc6, 0x71, + 0x92, 0x96, 0x47, 0x2e, 0x5d, 0xe2, 0x56, 0xd2, 0xa4, 0x9e, 0x08, 0x63, + 0x58, 0xa3, 0x0c, 0xe5, 0x25, 0xa1, 0x46, 0x82, 0x84, 0x8b, 0xb7, 0x46, + 0x07, 0x61, 0x87, 0xc9, 0x86, 0x3a, 0x8d, 0xc8, 0x01, 0xfe, 0x0c, 0x23, + 0xe3, 0xf2, 0x70, 0xb6, 0xb3, 0x4b, 0x27, 0x36, 0xba, 0x39, 0xac, 0xbd, + 0x88, 0xbc, 0x43, 0xbb, 0xf8, 0x71, 0x5b, 0xd3, 0x61, 0xae, 0x58, 0x61, + 0xea, 0x36, 0xee, 0xa5, 0x49, 0xd9, 0xda, 0x5b, 0xd7, 0xe1, 0xbf, 0x92, + 0xa5, 0x0c, 0xf5, 0x49, 0x5b, 0x7e, 0x3d, 0xd9, 0x77, 0x30, 0x02, 0x54, + 0x5e, 0x26, 0x76, 0x26, 0x55, 0x61, 0x91, 0x6b, 0x2e, 0xca, 0xc3, 0xb6, + 0x34, 0xec, 0xf4, 0x8e, 0x04, 0xec, 0x86, 0x12, 0xc5, 0xad, 0x75, 0x9e, + 0x1d, 0xbf, 0x3c, 0xa6, 0x45, 0xea, 0x24, 0xcb, 0x5a, 0xd4, 0xb8, 0x28, + 0x96, 0x15, 0x29, 0x31, 0xc2, 0x98, 0xaa, 0x8e, 0x73, 0x2d, 0xa6, 0xbd, + 0x25, 0x40, 0x97, 0x67, 0x58, 0x51, 0x65, 0x48, 0x31, 0xd3, 0x1a, 0x32, + 0xd1, 0x88, 0x1e, 0xd1, 0x3a, 0x03, 0x51, 0xa1, 0x83, 0x87, 0x84, 0xf9, + 0x93, 0x9c, 0x95, 0xb9, 0x95, 0x12, 0x2c, 0x58, 0x07, 0xcd, 0xa5, 0xe2, + 0xdf, 0x55, 0xca, 0x25, 0xa1, 0x2c, 0x98, 0x8f, 0x05, 0xad, 0x71, 0x23, + 0xf0, 0xa4, 0x98, 0x8c, 0x2c, 0xb8, 0xcf, 0xf0, 0x0c, 0x54, 0x51, 0xfd, + 0x6a, 0xd9, 0xb3, 0x11, 0x4e, 0x11, 0x96, 0x8a, 0x71, 0xb8, 0x80, 0x78, + 0x7c, 0x78, 0x92, 0x1c, 0xb1, 0xcc, 0x66, 0x4d, 0xb2, 0x4f, 0x5b, 0x6d, + 0xdf, 0x90, 0x77, 0xcf, 0x1e, 0x06, 0xc3, 0x6f, 0x97, 0x17, 0x05, 0x0e, + 0x4e, 0x81, 0xb5, 0xe2, 0xc0, 0xf0, 0x2a, 0x72, 0xde, 0xfa, 0xf5, 0x8c, + 0x42, 0x48, 0xda, 0xfc, 0xb6, 0xbf, 0x25, 0xdd, 0xc0, 0x77, 0x84, 0xc1, + 0xb1, 0x39, 0xe8, 0x70, 0x6b, 0x99, 0x6a, 0xb2, 0xcb, 0x51, 0x4f, 0x0c, + 0x26, 0x34, 0xe4, 0xb2, 0xcb, 0xad, 0x01, 0xbf, 0x7b, 0x4a, 0xff, 0x78, + 0xc0, 0x10, 0x16, 0xc3, 0x49, 0x6e, 0x4c, 0x9e, 0x9f, 0xbc, 0x3c, 0xde, + 0x42, 0x2f, 0x29, 0xdb, 0xf2, 0xc9, 0x07, 0x34, 0xb8, 0xad, 0x79, 0x99, + 0x90, 0x5b, 0x6e, 0xe6, 0x7d, 0x34, 0xe5, 0x08, 0x0a, 0x05, 0x48, 0xaa, + 0x22, 0xd4, 0x17, 0x43, 0x72, 0x7a, 0x6c, 0xb1, 0x85, 0x45, 0x7d, 0x7b, + 0xdb, 0x84, 0x12, 0xe5, 0x75, 0x6f, 0x0b, 0xae, 0x27, 0x77, 0x03, 0x01, + 0x1e, 0x72, 0xaf, 0x22, 0xe5, 0xbe, 0xe1, 0x10, 0x52, 0x39, 0x43, 0xe1, + 0x18, 0xd3, 0xd1, 0x09, 0xfa, 0xd9, 0x4d, 0x7a, 0x6b, 0x32, 0xff, 0x4e, + 0xef, 0xe1, 0x37, 0xdf, 0xe0, 0x71, 0x0c, 0xa6, 0x63, 0xe6, 0x2b, 0xa8, + 0x99, 0x3d, 0xda, 0xd9, 0xa1, 0x09, 0x54, 0xf2, 0x30, 0xfc, 0xdd, 0xfb, + 0xa6, 0xed, 0xf1, 0x2a, 0x83, 0xed, 0x1e, 0x2d, 0x3d, 0xdf, 0x83, 0x0f, + 0x96, 0x1f, 0xa6, 0x3d, 0x6d, 0x3e, 0xfa, 0x0d, 0xb6, 0xbd, 0xfc, 0x2c, + 0x3d, 0xc2, 0xcb, 0x52, 0x8c, 0xc7, 0x48, 0x08, 0xf8, 0xa0, 0x56, 0xca, + 0xbc, 0x49, 0xcb, 0x91, 0xcd, 0x63, 0xa7, 0xdb, 0xdb, 0x5d, 0x35, 0x11, + 0x62, 0x19, 0xd8, 0x2d, 0x6d, 0x07, 0x1e, 0x33, 0xd0, 0x05, 0x19, 0x86, + 0x40, 0xde, 0xdf, 0x85, 0xee, 0x77, 0xbf, 0xf9, 0xa6, 0x8b, 0xc3, 0x78, + 0xb4, 0x34, 0xc5, 0x9b, 0x22, 0x54, 0xd9, 0xa3, 0x47, 0xdd, 0xb6, 0x56, + 0xd0, 0x94, 0x42, 0x1a, 0xa0, 0x8a, 0x99, 0x7c, 0x9b, 0x24, 0xaf, 0x4f, + 0x2f, 0x8e, 0x51, 0x52, 0x11, 0xd3, 0x6d, 0x95, 0x89, 0x4d, 0xc2, 0x69, + 0x9a, 0x58, 0x92, 0x09, 0x4e, 0xbb, 0xea, 0xe8, 0x6c, 0xce, 0x4c, 0xcb, + 0x3a, 0x58, 0x57, 0xbb, 0x78, 0xbf, 0x59, 0x61, 0x22, 0xb9, 0x1c, 0x09, + 0x50, 0xb6, 0xea, 0x51, 0x48, 0x26, 0x72, 0x67, 0x24, 0xf6, 0xff, 0x81, + 0x89, 0x45, 0x25, 0x9b, 0xdc, 0xa8, 0xe4, 0x58, 0xa1, 0xea, 0x2d, 0x8e, + 0x81, 0x8c, 0x06, 0x05, 0xe2, 0x29, 0x9a, 0x45, 0x2e, 0xc0, 0xe3, 0x2b, + 0x40, 0xa2, 0x7e, 0x94, 0x4b, 0x54, 0x33, 0x09, 0xec, 0xc2, 0xfa, 0x51, + 0x49, 0x65, 0x01, 0xf5, 0xc1, 0x29, 0x32, 0xa8, 0x51, 0x7e, 0x89, 0x06, + 0x55, 0x5f, 0x67, 0x75, 0x13, 0xe8, 0x62, 0x8b, 0xad, 0x3f, 0x1c, 0xbf, + 0x17, 0x6a, 0x14, 0x6e, 0x54, 0xc0, 0xf7, 0xeb, 0x0d, 0x89, 0x9e, 0x7a, + 0xb0, 0x81, 0xca, 0xff, 0x06, 0x6c, 0x4b, 0x36, 0x19, 0x99, 0xfc, 0xcc, + 0xcf, 0xf4, 0xf8, 0x2b, 0x3e, 0x2b, 0xa4, 0x21, 0x7f, 0x20, 0x8b, 0x5b, + 0x8a, 0xa6, 0xc2, 0x59, 0x8f, 0xba, 0xc5, 0xe1, 0x68, 0xbf, 0x6c, 0x50, + 0xe4, 0x94, 0x42, 0x09, 0x56, 0xe4, 0x97, 0xbb, 0x7e, 0xa1, 0x37, 0x1a, + 0xf3, 0x85, 0x16, 0x16, 0x33, 0xe7, 0xe6, 0x61, 0x28, 0x41, 0x4a, 0xe0, + 0x98, 0xc5, 0xaf, 0x01, 0x49, 0x8f, 0xf3, 0xcb, 0x45, 0x69, 0xb2, 0xe3, + 0x83, 0x57, 0x68, 0xe7, 0xd0, 0xa3, 0xa9, 0x46, 0xb0, 0xca, 0x00, 0x63, + 0x18, 0x6b, 0x36, 0x42, 0xf7, 0x96, 0x1a, 0x54, 0x23, 0xb2, 0x8c, 0x2a, + 0x45, 0x18, 0xe8, 0x8e, 0x9a, 0x61, 0x91, 0xab, 0x5e, 0x66, 0x84, 0xbf, + 0xa3, 0x13, 0x10, 0xed, 0x9a, 0xbd, 0x35, 0x97, 0xaa, 0x50, 0x11, 0x45, + 0x14, 0x58, 0x0f, 0x56, 0x58, 0x06, 0x0d, 0x8b, 0x98, 0x0f, 0x23, 0x17, + 0xd2, 0xaf, 0xca, 0x6e, 0x46, 0xa0, 0x1e, 0x4c, 0x8a, 0x74, 0x54, 0x59, + 0xec, 0xae, 0xa1, 0x38, 0x70, 0xf8, 0x1f, 0x17, 0xeb, 0xe5, 0x5d, 0x09, + 0x1b, 0x20, 0x6b, 0x0f, 0xbb, 0xea, 0xcb, 0x86, 0x32, 0xa1, 0xa2, 0x89, + 0x21, 0xe0, 0x40, 0x0a, 0x4f, 0xc1, 0x35, 0x2d, 0xa4, 0xb6, 0x65, 0x9f, + 0x18, 0x16, 0xde, 0x50, 0x0d, 0x8c, 0xc6, 0xec, 0x43, 0x0d, 0x7f, 0x66, + 0x54, 0xd7, 0xcb, 0xae, 0xf1, 0xf3, 0x93, 0xff, 0x3e, 0x8e, 0xea, 0x0a, + 0xf2, 0xc8, 0xbf, 0x40, 0x5d, 0x41, 0x6e, 0x78, 0x6f, 0xaf, 0xf7, 0xf0, + 0xe1, 0x9a, 0x98, 0x5e, 0x62, 0x7e, 0xea, 0xa5, 0x1a, 0xa6, 0x9b, 0xce, + 0x71, 0x42, 0x4e, 0x30, 0x40, 0xfb, 0xea, 0x14, 0x16, 0x4a, 0xfd, 0x36, + 0xf8, 0x49, 0x4b, 0x4c, 0x01, 0x3c, 0x92, 0x4f, 0x17, 0xd3, 0x60, 0xbe, + 0x1b, 0xd3, 0x0b, 0xb3, 0xe1, 0x2d, 0xbb, 0xf0, 0x19, 0x32, 0x58, 0xfd, + 0xf7, 0xb8, 0x74, 0x3d, 0x24, 0x68, 0x6e, 0x28, 0x70, 0xed, 0x50, 0x94, + 0x18, 0xf7, 0x8a, 0x8c, 0x72, 0x7c, 0x57, 0x26, 0x8b, 0x19, 0x9c, 0xc7, + 0x4d, 0x4c, 0x3d, 0x60, 0x49, 0x89, 0x0e, 0xec, 0xc8, 0x40, 0x83, 0x44, + 0x2a, 0x84, 0xc1, 0x21, 0x60, 0xbd, 0xaf, 0xf9, 0x17, 0x27, 0x3b, 0x49, + 0xbb, 0x54, 0x37, 0x00, 0xdd, 0xc8, 0xd6, 0x61, 0x4a, 0xf6, 0x30, 0x6d, + 0x08, 0xfe, 0x12, 0x4f, 0x7a, 0xe6, 0xb6, 0x4e, 0xce, 0xa1, 0xee, 0xd6, + 0xdb, 0x37, 0x2f, 0xc5, 0xf5, 0x99, 0x3a, 0xbb, 0x25, 0x82, 0x91, 0x4f, + 0x32, 0x52, 0xa6, 0xc6, 0x64, 0x96, 0x63, 0x58, 0xe3, 0x60, 0x0f, 0xa5, + 0xa5, 0x40, 0x40, 0x3a, 0xca, 0xb7, 0x54, 0x8f, 0x15, 0x6a, 0xda, 0x30, + 0xc9, 0x3a, 0x9f, 0x08, 0x06, 0x7e, 0x34, 0x3a, 0x72, 0x38, 0xe1, 0xd0, + 0x59, 0x3c, 0x51, 0xc3, 0x51, 0xce, 0x38, 0xec, 0xc2, 0xdc, 0x68, 0x21, + 0x68, 0x4d, 0x30, 0x85, 0xa5, 0x09, 0xed, 0xd1, 0x84, 0x7f, 0x71, 0xa5, + 0x49, 0xd0, 0xb2, 0x8e, 0x0e, 0x8b, 0x6c, 0xd2, 0xa4, 0xb3, 0x0b, 0x87, + 0x06, 0x46, 0xb4, 0xe0, 0xa9, 0x16, 0x1a, 0xec, 0xbc, 0xde, 0x7e, 0xdb, + 0x91, 0x00, 0x88, 0xd7, 0xa2, 0xfe, 0x9b, 0xca, 0xcc, 0xdb, 0x1a, 0x32, + 0x38, 0xde, 0x32, 0x2b, 0x4e, 0xdd, 0x8e, 0x62, 0x74, 0x6a, 0x08, 0xb4, + 0xc7, 0x4f, 0x18, 0xe8, 0x09, 0xb8, 0x25, 0x9c, 0xd1, 0x4d, 0xbe, 0x72, + 0xb7, 0x60, 0x95, 0x36, 0xa6, 0x1b, 0x22, 0x90, 0x00, 0x8f, 0x07, 0x85, + 0x09, 0x3e, 0xdb, 0xb8, 0xda, 0x48, 0x36, 0x61, 0x9f, 0x4b, 0xae, 0x81, + 0x93, 0x6c, 0x8c, 0xe0, 0x95, 0xed, 0xcd, 0x51, 0xca, 0xa5, 0x89, 0x58, + 0x20, 0xd8, 0x7b, 0x88, 0x49, 0xd3, 0x8b, 0x92, 0xda, 0xde, 0xf2, 0x68, + 0xf6, 0x06, 0x58, 0xaa, 0x63, 0xe9, 0x4a, 0x0d, 0xde, 0xa4, 0x83, 0x73, + 0x72, 0x13, 0xed, 0x92, 0x41, 0xd9, 0x68, 0x34, 0x54, 0x3b, 0x16, 0x3d, + 0x0f, 0x3e, 0xc6, 0x2e, 0x1c, 0xa1, 0x68, 0xa4, 0x69, 0x8d, 0x02, 0xac, + 0x15, 0x48, 0xdc, 0xdd, 0x09, 0xa0, 0x64, 0xf8, 0x12, 0xcf, 0xa4, 0x6b, + 0x09, 0x7d, 0x8c, 0x21, 0x5c, 0x1b, 0x76, 0x97, 0x11, 0xa9, 0xee, 0x00, + 0x93, 0x47, 0xf2, 0x58, 0x44, 0x91, 0x4a, 0x98, 0x71, 0x36, 0x49, 0xe7, + 0xa4, 0x4a, 0xe4, 0xe8, 0x9a, 0x17, 0x77, 0x79, 0x76, 0x9d, 0x17, 0x8b, + 0x2a, 0x2e, 0xe4, 0x0d, 0x64, 0x66, 0x64, 0x14, 0xe7, 0x3f, 0x8c, 0x17, + 0x33, 0xc9, 0xfa, 0x93, 0x52, 0x9d, 0xd3, 0x7c, 0x32, 0xc9, 0x45, 0xe2, + 0x21, 0xb0, 0x11, 0xd0, 0x52, 0x25, 0x64, 0xfa, 0xc4, 0x38, 0xa3, 0x50, + 0xb2, 0x86, 0x9f, 0xe8, 0x81, 0xc7, 0x06, 0x49, 0x9c, 0x9d, 0x8a, 0x71, + 0x1f, 0x89, 0x02, 0x04, 0x8a, 0x1d, 0x3e, 0xce, 0xdc, 0xaa, 0x42, 0x24, + 0x0b, 0xf7, 0x07, 0xe9, 0x55, 0x45, 0xfc, 0xc5, 0x0c, 0xfa, 0x03, 0xe9, + 0x72, 0xe8, 0x46, 0x49, 0xee, 0x6d, 0x8c, 0x1f, 0xa1, 0x80, 0x1d, 0xdb, + 0x80, 0xae, 0x5e, 0x3d, 0xe6, 0xef, 0xa4, 0x67, 0xba, 0x72, 0xc7, 0x89, + 0x2c, 0xc3, 0x2f, 0xea, 0xae, 0x63, 0x6d, 0xf7, 0x49, 0x71, 0xc9, 0x45, + 0x59, 0x48, 0xde, 0x47, 0xe2, 0xe1, 0x1a, 0x58, 0xec, 0xd6, 0xad, 0x1d, + 0x60, 0xcd, 0x39, 0xae, 0x16, 0x99, 0x54, 0x67, 0x16, 0x6a, 0xc6, 0x01, + 0xeb, 0x5d, 0x57, 0x2e, 0x4c, 0x91, 0x23, 0x1c, 0x23, 0x43, 0xaa, 0x62, + 0x82, 0x8e, 0x50, 0x5d, 0xca, 0xd8, 0x8a, 0xd0, 0x8f, 0x2a, 0xcf, 0x17, + 0x5c, 0x02, 0x9a, 0x81, 0xe3, 0x66, 0xc9, 0x23, 0x57, 0x81, 0x1d, 0x97, + 0x4e, 0x84, 0xb8, 0x47, 0xb6, 0xfd, 0x7c, 0x5d, 0x75, 0x1e, 0x6d, 0xef, + 0x3e, 0xaa, 0x3a, 0x24, 0x15, 0x4d, 0xa8, 0x44, 0x67, 0xce, 0x5e, 0xf2, + 0xfd, 0xc6, 0xfb, 0x89, 0x9c, 0x85, 0xca, 0x79, 0x88, 0x3b, 0xfb, 0xdb, + 0x0f, 0xaf, 0x3a, 0xe8, 0x94, 0x54, 0x13, 0xb3, 0x6c, 0xea, 0x97, 0xaa, + 0x9e, 0xae, 0xc5, 0xd3, 0x39, 0xfa, 0x71, 0x89, 0xa7, 0xac, 0xbc, 0x0a, + 0xd7, 0x0b, 0xb0, 0xaf, 0x96, 0x6e, 0x44, 0x68, 0x7f, 0x6f, 0xbb, 0xb5, + 0xac, 0x64, 0xd2, 0xef, 0xf7, 0x5b, 0x9e, 0xde, 0xdf, 0xbe, 0xfa, 0x88, + 0xa7, 0x77, 0x1f, 0x6e, 0x4f, 0x57, 0x3e, 0xbe, 0x94, 0x30, 0x83, 0x9a, + 0x71, 0x94, 0x30, 0x43, 0xfb, 0xc5, 0x2d, 0xf1, 0xfd, 0x4b, 0xa4, 0xda, + 0x23, 0x2a, 0x75, 0x97, 0xf0, 0x4d, 0x84, 0x29, 0xf6, 0x93, 0x04, 0x38, + 0x1b, 0xce, 0xb8, 0xd5, 0xb2, 0x26, 0xcb, 0x39, 0xfb, 0x2b, 0x10, 0xa1, + 0x5c, 0x22, 0x5e, 0xa8, 0x50, 0x1a, 0x0b, 0xce, 0x63, 0x87, 0xfa, 0x8d, + 0x88, 0x8b, 0xae, 0x76, 0x3b, 0xa7, 0x55, 0x13, 0xaa, 0x1f, 0xa7, 0x1a, + 0xeb, 0xc9, 0xe4, 0x48, 0x11, 0xf2, 0x64, 0x90, 0xd7, 0x9b, 0x2b, 0xe3, + 0xea, 0x59, 0x4d, 0x27, 0x35, 0xc2, 0xab, 0x76, 0xf1, 0xd6, 0xb9, 0x69, + 0x96, 0x9f, 0x82, 0x8f, 0x3e, 0x5f, 0xca, 0x1a, 0xb6, 0x7f, 0x8f, 0xf8, + 0x73, 0xb3, 0x9e, 0xd8, 0x53, 0x97, 0x3d, 0x9d, 0xac, 0x2e, 0x32, 0x65, + 0x84, 0x96, 0x19, 0xc6, 0x37, 0x95, 0xc9, 0x53, 0xb8, 0xd9, 0x63, 0xc0, + 0x4c, 0xcd, 0xa5, 0xa5, 0x27, 0xf0, 0x11, 0x2c, 0x40, 0xa7, 0xe2, 0x3f, + 0xad, 0xb2, 0x9a, 0x54, 0x42, 0x4e, 0x3c, 0xa7, 0x5c, 0x0c, 0x2c, 0x83, + 0xba, 0x76, 0x71, 0xee, 0x06, 0x70, 0x49, 0x19, 0x86, 0xec, 0x4f, 0x84, + 0x83, 0x99, 0xf5, 0xdd, 0xe6, 0x5a, 0xe5, 0x35, 0x35, 0xed, 0x86, 0x1a, + 0x85, 0x6c, 0xdd, 0x64, 0x59, 0x0d, 0x18, 0xc0, 0x1f, 0x30, 0xb8, 0xa1, + 0xd3, 0x71, 0x98, 0x4c, 0x61, 0x2e, 0x34, 0x52, 0xfa, 0x42, 0x3c, 0xc6, + 0x06, 0xa1, 0x15, 0x47, 0x44, 0x68, 0x45, 0x45, 0xbb, 0x3a, 0xf8, 0x4d, + 0xf6, 0x9b, 0x62, 0x65, 0xf9, 0x82, 0x63, 0x33, 0xf0, 0xfa, 0x7e, 0x29, + 0x03, 0x52, 0x9c, 0x29, 0x9a, 0x0a, 0xdb, 0x54, 0x64, 0x2c, 0xcd, 0x12, + 0xaa, 0xcc, 0x67, 0x27, 0x20, 0x59, 0x03, 0xa1, 0xa0, 0xaf, 0x53, 0x2b, + 0x0c, 0x8a, 0x5a, 0x11, 0xd6, 0x08, 0x9e, 0x57, 0xef, 0xb8, 0x4d, 0xc2, + 0xb8, 0x85, 0xcc, 0xe9, 0x8e, 0x48, 0xf8, 0x70, 0x73, 0xae, 0x25, 0x40, + 0x2f, 0xf1, 0x0b, 0xe9, 0xa1, 0xa3, 0x74, 0x34, 0x86, 0x45, 0xd3, 0x22, + 0x73, 0x9d, 0xfb, 0xd3, 0xc1, 0xef, 0x7c, 0x5f, 0x96, 0xa6, 0xf7, 0xf2, + 0x23, 0xda, 0xb9, 0xfb, 0x9d, 0x25, 0xca, 0x46, 0x2f, 0x45, 0x2f, 0x45, + 0xac, 0x44, 0xe1, 0x27, 0xb2, 0x37, 0x42, 0xe5, 0xff, 0xc5, 0x54, 0x8e, + 0x01, 0x0f, 0xf2, 0x0d, 0x65, 0x43, 0x47, 0xa4, 0x7e, 0x81, 0x81, 0xb6, + 0x46, 0x44, 0xf4, 0xa8, 0xd8, 0xf9, 0x2d, 0x3f, 0x6e, 0x61, 0x91, 0x88, + 0xa4, 0x1c, 0xf6, 0x1a, 0xa9, 0x19, 0x47, 0xcc, 0x5d, 0x7a, 0x70, 0x96, + 0x41, 0x88, 0xce, 0xe9, 0x35, 0x43, 0xbf, 0x72, 0xc1, 0x79, 0x1a, 0xee, + 0x42, 0x55, 0xc6, 0x1d, 0x3c, 0x56, 0xa9, 0xab, 0x81, 0x7d, 0x00, 0x11, + 0x6a, 0x49, 0x4f, 0xed, 0x2e, 0x5c, 0x16, 0xf6, 0x92, 0x43, 0x99, 0xe0, + 0x02, 0x35, 0x1a, 0xf1, 0x22, 0x84, 0x85, 0xb5, 0xf1, 0xe6, 0x68, 0xc5, + 0x1c, 0x9b, 0x8b, 0x56, 0x2d, 0xcb, 0x3c, 0xaa, 0x65, 0xb1, 0xd7, 0x8c, + 0x77, 0x55, 0x7a, 0xcd, 0xfc, 0xdb, 0x9b, 0xe5, 0xa3, 0x60, 0x06, 0x60, + 0xa3, 0xfa, 0x75, 0xb0, 0x48, 0xc7, 0xa1, 0x96, 0xca, 0xc7, 0x38, 0x50, + 0xac, 0xc7, 0x35, 0xb7, 0x7d, 0xa1, 0xd5, 0x80, 0x29, 0x11, 0xc2, 0x1b, + 0xdd, 0x04, 0x49, 0xf3, 0x95, 0x0f, 0x0c, 0xbf, 0x06, 0xa7, 0x18, 0xf6, + 0x2f, 0x9d, 0x20, 0xdc, 0xe8, 0x2d, 0x17, 0x50, 0xad, 0x74, 0x44, 0xde, + 0x62, 0xef, 0xc6, 0xcc, 0xe6, 0x6c, 0x8a, 0x92, 0xc0, 0xf2, 0xa4, 0x37, + 0x25, 0x6a, 0xb6, 0xb3, 0x20, 0xab, 0xa3, 0x71, 0x16, 0xab, 0xcc, 0x26, + 0xc5, 0x10, 0x66, 0x0c, 0xab, 0xd0, 0x03, 0x5e, 0x3f, 0x41, 0x47, 0x6f, + 0xd0, 0xe6, 0xb0, 0x11, 0xcb, 0x9a, 0x16, 0x8a, 0x19, 0x82, 0x7c, 0x60, + 0x42, 0xbf, 0xda, 0x8c, 0xa3, 0xed, 0x0b, 0x62, 0x83, 0x05, 0x56, 0x84, + 0x69, 0x72, 0xcc, 0xb7, 0xd3, 0xdb, 0x0c, 0xdc, 0x23, 0xe4, 0x7e, 0xbb, + 0x4d, 0xe2, 0xd2, 0x62, 0x78, 0x95, 0x38, 0x23, 0x83, 0x14, 0x06, 0x4d, + 0xfe, 0xa3, 0x57, 0xb1, 0x44, 0x0a, 0xdd, 0x6d, 0xde, 0x66, 0xf5, 0x56, + 0xb0, 0xa0, 0xc4, 0x41, 0xc1, 0xda, 0x7b, 0x17, 0x03, 0xbb, 0xa2, 0x70, + 0x2e, 0x4a, 0x9c, 0x77, 0x61, 0x68, 0x22, 0x34, 0xc1, 0x7d, 0xcd, 0xb1, + 0xd4, 0x20, 0xca, 0xcc, 0x33, 0x87, 0xdb, 0xa1, 0x8e, 0xfd, 0x48, 0x78, + 0x52, 0x33, 0x89, 0xd5, 0x37, 0x0b, 0x64, 0x4e, 0x7f, 0x76, 0xf4, 0xb5, + 0x0e, 0x5b, 0x8c, 0x62, 0x85, 0x40, 0x98, 0x3e, 0x72, 0xe7, 0xd8, 0xb0, + 0x61, 0xaf, 0xfd, 0x67, 0x87, 0xba, 0xce, 0x10, 0x10, 0x78, 0xd3, 0x86, + 0x60, 0x69, 0x2e, 0x30, 0xc4, 0x49, 0x3e, 0xcc, 0x15, 0x49, 0xce, 0x0c, + 0x4b, 0xe8, 0x83, 0xdb, 0x5a, 0xca, 0x98, 0x3f, 0xfe, 0x90, 0x95, 0xc3, + 0x1c, 0xad, 0x48, 0xbf, 0x2e, 0x46, 0xf0, 0x1a, 0x5d, 0x04, 0x6c, 0x8b, + 0x1f, 0x37, 0xd0, 0x43, 0x92, 0x4c, 0x42, 0x11, 0xd0, 0x72, 0xd2, 0x28, + 0x0c, 0xd7, 0x4f, 0x0e, 0x93, 0xb2, 0xb8, 0x5c, 0xb8, 0xfa, 0x5b, 0x18, + 0x04, 0xce, 0x81, 0x21, 0x14, 0xde, 0xa7, 0xeb, 0x80, 0xe1, 0x09, 0xc9, + 0xb3, 0x97, 0x2f, 0x39, 0xb8, 0x23, 0xa4, 0x07, 0xb0, 0x37, 0x85, 0x30, + 0x80, 0x35, 0x7e, 0x3c, 0x41, 0x3b, 0x0f, 0xde, 0x23, 0xd1, 0xc5, 0x85, + 0x06, 0x42, 0x4d, 0x42, 0xc0, 0xf0, 0x08, 0x04, 0x27, 0xc0, 0x91, 0x96, + 0x8a, 0xc6, 0x06, 0x02, 0x3c, 0x5c, 0x6f, 0xc5, 0xb8, 0xbe, 0x49, 0x97, + 0x4a, 0xc9, 0x2d, 0xf3, 0xc2, 0x36, 0x74, 0x42, 0xb1, 0x52, 0xdc, 0x11, + 0x79, 0xb9, 0x24, 0xab, 0x2c, 0xb5, 0x7b, 0xa7, 0xe8, 0x72, 0xfa, 0x5f, + 0x6d, 0xec, 0x7d, 0x5b, 0xbc, 0x48, 0x4b, 0xce, 0x1b, 0x63, 0xca, 0xca, + 0xd7, 0x4f, 0xbb, 0xf1, 0xe7, 0xb2, 0x17, 0x25, 0xe6, 0x0e, 0x4b, 0x68, + 0x2a, 0x41, 0x07, 0x8b, 0x39, 0xdd, 0xc5, 0x67, 0x30, 0x6c, 0xb6, 0x8f, + 0xa7, 0x65, 0x0e, 0x83, 0xc1, 0x09, 0x99, 0x66, 0xa4, 0x6f, 0x92, 0x49, + 0x34, 0xb8, 0x5e, 0xc9, 0x84, 0x2b, 0x66, 0x4d, 0x0d, 0x9f, 0x53, 0x76, + 0xe9, 0x40, 0x28, 0xb4, 0x36, 0x12, 0x4c, 0xd2, 0xd0, 0xa8, 0xc7, 0xfd, + 0xad, 0xf5, 0x79, 0xec, 0x72, 0xe4, 0x58, 0xdf, 0xf2, 0x4f, 0x30, 0xc6, + 0x37, 0xdc, 0x12, 0xec, 0x38, 0xd4, 0x46, 0xd2, 0xc4, 0x55, 0x8c, 0x73, + 0x4c, 0x8f, 0x24, 0x20, 0x02, 0xe6, 0x26, 0xcd, 0xed, 0x8a, 0x2d, 0x88, + 0x01, 0x0a, 0xb4, 0xd1, 0x6d, 0x70, 0x07, 0x2a, 0x90, 0xe8, 0xec, 0xba, + 0xa0, 0x6f, 0xd8, 0x66, 0xd3, 0xc8, 0x10, 0x09, 0x89, 0xd1, 0x64, 0xde, + 0x6a, 0x61, 0xf5, 0x17, 0x61, 0xbd, 0x02, 0xc7, 0x2b, 0x42, 0x72, 0x1b, + 0x4c, 0x40, 0xa2, 0x77, 0x0c, 0x10, 0x28, 0xb0, 0x09, 0x0f, 0x55, 0x06, + 0x97, 0x62, 0x17, 0x99, 0x03, 0x82, 0x70, 0x83, 0xfa, 0x8f, 0x21, 0x5e, + 0x0e, 0x1d, 0xa8, 0x79, 0x11, 0x10, 0xab, 0x77, 0x5c, 0xde, 0xb9, 0xaa, + 0x0c, 0x15, 0xdd, 0x5f, 0x41, 0x1c, 0x71, 0x98, 0x70, 0x91, 0x44, 0xf8, + 0x63, 0x78, 0x85, 0xd0, 0x19, 0x0d, 0x14, 0x4b, 0x92, 0x50, 0x82, 0x2d, + 0xaa, 0xf5, 0x28, 0x49, 0xe2, 0xbd, 0x13, 0x01, 0x71, 0x73, 0x46, 0xa3, + 0x5c, 0x25, 0x09, 0xcf, 0x50, 0xfa, 0xd1, 0x75, 0xa8, 0x6c, 0x83, 0xba, + 0xae, 0x12, 0x7f, 0x47, 0x48, 0xae, 0x41, 0x2a, 0xe0, 0xac, 0x8d, 0xd9, + 0x26, 0xca, 0xe9, 0xe4, 0x7a, 0xf3, 0xf3, 0x6e, 0xbb, 0x38, 0xac, 0x92, + 0x34, 0xed, 0x38, 0x45, 0x97, 0xcd, 0x92, 0x48, 0x38, 0x60, 0xe9, 0x33, + 0xaf, 0xe9, 0x16, 0xfa, 0x8f, 0xbd, 0x9d, 0xb0, 0xcf, 0x92, 0x52, 0x83, + 0x4d, 0x18, 0x26, 0xd5, 0x3c, 0x95, 0xb8, 0xa5, 0x44, 0x6b, 0x59, 0x4e, + 0xc5, 0x56, 0x8f, 0x51, 0xc7, 0x54, 0x7b, 0x7d, 0x6e, 0xde, 0x0d, 0x65, + 0x2d, 0xd6, 0x55, 0x23, 0xf4, 0x90, 0x28, 0xc3, 0x93, 0x58, 0x2a, 0x05, + 0xce, 0x84, 0x39, 0xa5, 0x5a, 0x30, 0xd3, 0xec, 0x0e, 0x6c, 0x93, 0x84, + 0x6d, 0xd5, 0x8b, 0x33, 0x14, 0xaf, 0x5c, 0xce, 0xb9, 0x17, 0xa3, 0xa8, + 0x39, 0x5d, 0xec, 0xd2, 0x97, 0x78, 0x41, 0x9e, 0xd8, 0xc8, 0xcc, 0x2b, + 0x9a, 0x27, 0x05, 0xa2, 0xf5, 0x95, 0xc1, 0xa6, 0x73, 0x2a, 0x9e, 0xa1, + 0xea, 0xf2, 0xca, 0xe2, 0xd2, 0x06, 0x89, 0x8e, 0x5d, 0x3e, 0x7a, 0xba, + 0x51, 0xa2, 0x5b, 0x36, 0xae, 0x44, 0x23, 0x0a, 0x01, 0x22, 0xa1, 0x11, + 0x09, 0x41, 0x60, 0x63, 0x40, 0x43, 0xcc, 0x52, 0x86, 0x64, 0xa3, 0x4e, + 0x78, 0x12, 0x82, 0x89, 0x4f, 0x8a, 0x18, 0x8e, 0x6a, 0x9a, 0x73, 0xd0, + 0x36, 0x52, 0x78, 0x87, 0x22, 0x3e, 0xd4, 0x6b, 0xd2, 0x11, 0x4e, 0xa7, + 0xc0, 0xc5, 0x6c, 0xca, 0x47, 0x13, 0xcd, 0x56, 0x22, 0x1e, 0x5f, 0xa1, + 0xd6, 0x04, 0x24, 0xda, 0x45, 0xaa, 0xc6, 0xb0, 0x58, 0x46, 0x8e, 0xaa, + 0xde, 0x17, 0xc3, 0x3c, 0x14, 0x0f, 0x0c, 0xe8, 0x67, 0x24, 0xd0, 0x52, + 0x32, 0x4f, 0x4e, 0x25, 0x44, 0x86, 0x19, 0xd9, 0x66, 0x68, 0xd4, 0xc1, + 0x69, 0x62, 0x58, 0x3c, 0x91, 0xb1, 0x79, 0x29, 0x3c, 0xe0, 0x6e, 0x75, + 0xe6, 0x74, 0xe5, 0xad, 0x12, 0x2e, 0x89, 0xb5, 0x1e, 0xbd, 0xeb, 0xfb, + 0xbd, 0x3b, 0x6f, 0x28, 0x44, 0x79, 0xe9, 0x46, 0xcc, 0xd0, 0x0c, 0x1d, + 0x2d, 0x37, 0x64, 0xd2, 0x5c, 0xd1, 0x5e, 0xaa, 0x30, 0xe8, 0x47, 0xcc, + 0xad, 0xa3, 0x2a, 0xca, 0x62, 0xb2, 0xa4, 0xc4, 0x34, 0x50, 0x5a, 0xd8, + 0x3c, 0xcf, 0x27, 0x80, 0x8d, 0x51, 0xa3, 0x2c, 0xd5, 0x4c, 0x7f, 0x3b, + 0x6b, 0xf9, 0xb8, 0xb1, 0x69, 0x37, 0x94, 0xbd, 0x47, 0xec, 0xc9, 0xa0, + 0xfe, 0xd1, 0x07, 0xc4, 0xe7, 0x3e, 0x70, 0xc8, 0xc2, 0x0c, 0x2d, 0x0e, + 0xf0, 0x99, 0x93, 0xe2, 0x44, 0x66, 0x1f, 0xd2, 0x2e, 0x72, 0x44, 0xf4, + 0xd2, 0x34, 0x88, 0x7d, 0x10, 0x14, 0xb4, 0x5c, 0x91, 0x76, 0x48, 0x29, + 0x68, 0x16, 0x8f, 0x7a, 0xa7, 0x87, 0x18, 0x0d, 0x6c, 0xc9, 0xf3, 0x62, + 0x04, 0x73, 0xa1, 0x36, 0xc1, 0x25, 0x5e, 0xa3, 0xcf, 0x5b, 0x03, 0xb7, + 0xd1, 0xc5, 0x3d, 0xb6, 0x97, 0xc6, 0x64, 0x5b, 0x02, 0x51, 0x80, 0x56, + 0x76, 0x25, 0x81, 0xbc, 0xfd, 0xdb, 0xbd, 0xb5, 0x64, 0x9d, 0x37, 0x4e, + 0xd6, 0xc1, 0x69, 0x4a, 0x35, 0xcf, 0x90, 0xce, 0xe4, 0x54, 0x01, 0x72, + 0x6d, 0x66, 0x94, 0x9e, 0xc3, 0x89, 0x4d, 0xb8, 0x2c, 0x35, 0xf4, 0xda, + 0x26, 0xbd, 0xb8, 0x5d, 0xe5, 0x2c, 0x0e, 0x4e, 0xa0, 0x54, 0x07, 0x23, + 0xed, 0x19, 0xc7, 0xe9, 0x8f, 0x43, 0x42, 0x45, 0x7a, 0x9d, 0xe6, 0x13, + 0x5e, 0x4a, 0xf3, 0x7e, 0x4b, 0x84, 0x20, 0x47, 0x2e, 0xb0, 0xc4, 0x74, + 0x99, 0x59, 0x0d, 0xa3, 0x8a, 0xb9, 0x99, 0x8e, 0x24, 0x36, 0x99, 0xb5, + 0x4d, 0xed, 0x8b, 0xec, 0x2a, 0x36, 0xb5, 0xd6, 0x8e, 0x92, 0x21, 0x1b, + 0xe8, 0x72, 0x5c, 0x14, 0xeb, 0x99, 0x20, 0xfc, 0xd1, 0xe2, 0xa3, 0x8e, + 0x4d, 0xa0, 0xab, 0x71, 0x14, 0x9d, 0xf0, 0xeb, 0xac, 0x57, 0xcc, 0x7a, + 0x74, 0xdf, 0x68, 0xd1, 0x27, 0xfc, 0x50, 0xe5, 0x55, 0x5e, 0x37, 0x58, + 0x6a, 0xbb, 0x94, 0x44, 0x15, 0xe5, 0x63, 0xe9, 0x2e, 0x2e, 0x76, 0x3a, + 0xb9, 0x86, 0x88, 0x8b, 0xaa, 0xeb, 0x05, 0x85, 0x42, 0x6d, 0x93, 0x73, + 0x46, 0x83, 0x0c, 0x2c, 0xc6, 0x3a, 0xb4, 0x78, 0x65, 0x98, 0x31, 0xc6, + 0x77, 0x4f, 0xb0, 0x3f, 0x4c, 0x32, 0x16, 0xc8, 0x52, 0x0d, 0x65, 0xd1, + 0x84, 0x55, 0x8e, 0x18, 0x4c, 0xd9, 0xa2, 0x6d, 0x03, 0x1c, 0x2d, 0x4a, + 0xef, 0x9d, 0x68, 0x28, 0xf8, 0x9a, 0x22, 0x26, 0x72, 0x49, 0x8a, 0x02, + 0xf7, 0xe5, 0x02, 0xb3, 0x5d, 0x39, 0xab, 0x28, 0x52, 0x3c, 0x0d, 0x12, + 0xdd, 0x03, 0x43, 0xf9, 0x7c, 0xc5, 0xc6, 0x0a, 0xde, 0x03, 0xaa, 0xbe, + 0x3e, 0xc2, 0x54, 0xa3, 0xdd, 0xfb, 0x49, 0xc4, 0x0f, 0x02, 0xc8, 0x44, + 0x66, 0xb9, 0x16, 0x7c, 0xd4, 0x93, 0xfd, 0x86, 0x35, 0x1c, 0xf3, 0x11, + 0x94, 0x46, 0xfe, 0xd2, 0x0d, 0x71, 0x6a, 0xc9, 0x53, 0xc6, 0x71, 0xf8, + 0x6e, 0xe9, 0x2a, 0x10, 0x7c, 0x07, 0x11, 0xa2, 0xb9, 0x5e, 0x91, 0x0a, + 0x15, 0x92, 0xc9, 0x18, 0xed, 0x05, 0x0d, 0x9c, 0x8c, 0xd8, 0x55, 0x62, + 0x85, 0x15, 0xe1, 0x82, 0x1d, 0x60, 0x88, 0xbb, 0x19, 0x2d, 0x91, 0xe7, + 0xe3, 0x65, 0xa2, 0x2e, 0xaa, 0xc8, 0xc1, 0x1a, 0x9c, 0x27, 0xc8, 0x55, + 0x50, 0x18, 0x83, 0xfd, 0x43, 0x8e, 0x8f, 0xc6, 0x12, 0x12, 0x08, 0xab, + 0x74, 0x9c, 0x25, 0x97, 0x8b, 0xb4, 0x1c, 0x51, 0xc5, 0x23, 0xe4, 0x27, + 0x5c, 0xe6, 0x06, 0x53, 0xc5, 0xa9, 0x70, 0x1d, 0xb9, 0x5a, 0x82, 0xb1, + 0x05, 0xad, 0x57, 0x65, 0x31, 0x89, 0x22, 0xfa, 0xa5, 0x9a, 0xce, 0xc5, + 0xc5, 0x19, 0xc5, 0x11, 0x7a, 0xa3, 0xd0, 0x10, 0xee, 0x0b, 0x50, 0x0a, + 0x2c, 0x93, 0x32, 0x2c, 0x42, 0x58, 0x85, 0x18, 0x4a, 0x10, 0x43, 0x2a, + 0xcc, 0xf6, 0x4c, 0xe6, 0x6a, 0x4b, 0x46, 0xb8, 0x88, 0x80, 0x60, 0xad, + 0x51, 0x05, 0xce, 0xd0, 0x24, 0x52, 0x68, 0xa1, 0x91, 0x56, 0x2b, 0x4f, + 0x58, 0x18, 0x8e, 0x5c, 0xa1, 0x9b, 0x2c, 0x16, 0xca, 0x1d, 0xcd, 0x49, + 0x1c, 0x3f, 0x1e, 0x5f, 0x60, 0x52, 0xca, 0x83, 0x37, 0x5a, 0x0e, 0x87, + 0x86, 0xc0, 0xe1, 0x25, 0x72, 0x73, 0xb2, 0x81, 0x0a, 0x6f, 0x53, 0xc5, + 0xba, 0x22, 0x56, 0x8b, 0xc6, 0x8b, 0x74, 0xa6, 0xa8, 0x82, 0x0f, 0x1e, + 0x1c, 0xc1, 0xac, 0x8a, 0xa0, 0x43, 0xc0, 0x89, 0xf4, 0xc6, 0xf7, 0xca, + 0x0a, 0x0a, 0x25, 0x67, 0x6f, 0x2f, 0xa8, 0x05, 0x8c, 0x8d, 0xbc, 0x38, + 0xee, 0x22, 0x53, 0xe0, 0x50, 0xe2, 0x32, 0x9b, 0x90, 0x54, 0x56, 0x67, + 0xc3, 0xab, 0x59, 0x81, 0x8e, 0x40, 0x4a, 0xb2, 0x43, 0xd6, 0xfd, 0x53, + 0x36, 0x78, 0x76, 0xf8, 0x67, 0xae, 0xb5, 0x82, 0xe5, 0x30, 0xdf, 0x9c, + 0x9e, 0x3d, 0x3f, 0x79, 0xfd, 0xac, 0x9b, 0x1c, 0x9d, 0x9e, 0xfd, 0x15, + 0x9a, 0x78, 0x75, 0xfa, 0x67, 0x0c, 0x78, 0xe2, 0x78, 0x79, 0x2e, 0x39, + 0xf0, 0xe0, 0x35, 0x82, 0xd5, 0xa2, 0x19, 0x42, 0x8c, 0xd9, 0xce, 0x1d, + 0x16, 0xc4, 0xf6, 0x3e, 0x26, 0x36, 0x26, 0x16, 0x82, 0x0c, 0xcb, 0x01, + 0xad, 0xbd, 0x38, 0x3e, 0x7c, 0x86, 0xd1, 0x4f, 0x67, 0xa7, 0xe7, 0x3c, + 0x54, 0x1c, 0x72, 0x98, 0x09, 0x79, 0xc1, 0xc5, 0xd0, 0x44, 0x7a, 0xa7, + 0x44, 0x61, 0x0b, 0xb8, 0x15, 0x1c, 0x22, 0x42, 0x85, 0xc5, 0x8d, 0xf1, + 0x02, 0xa1, 0xf4, 0x48, 0x04, 0xf4, 0x20, 0x42, 0x23, 0x89, 0x00, 0x18, + 0x25, 0xfa, 0x98, 0x0b, 0x59, 0x31, 0x3c, 0x8d, 0x21, 0x14, 0x1a, 0x91, + 0xd0, 0x6a, 0xd1, 0x70, 0xba, 0x11, 0xe8, 0x6c, 0x42, 0x3e, 0x1f, 0x7a, + 0xee, 0x26, 0x95, 0xf0, 0x2c, 0x90, 0x6c, 0x50, 0xd7, 0x00, 0x82, 0x7f, + 0x4e, 0x6e, 0x3f, 0x3e, 0xf7, 0x48, 0x35, 0xe3, 0x48, 0x84, 0xa2, 0x4b, + 0x32, 0xb5, 0x02, 0x57, 0xb8, 0x08, 0x89, 0x75, 0x22, 0xa5, 0x9f, 0xff, + 0xc2, 0x1f, 0x53, 0x87, 0x18, 0xfc, 0x8d, 0xa6, 0xc2, 0x05, 0x26, 0x24, + 0x67, 0x5c, 0x6e, 0x8c, 0xd6, 0x57, 0x8e, 0x3c, 0xd7, 0x83, 0xbe, 0x22, + 0xba, 0x9c, 0x5b, 0x0c, 0xd3, 0x45, 0xa0, 0xcf, 0xe8, 0x50, 0x93, 0x93, + 0x43, 0xdd, 0x2a, 0x4a, 0xea, 0x96, 0x27, 0x2d, 0xa0, 0x20, 0x14, 0x2f, + 0xae, 0xfb, 0xa0, 0x6a, 0x4e, 0x2e, 0xa2, 0xe0, 0xd8, 0xcd, 0x8e, 0xd5, + 0xb3, 0xe0, 0x9f, 0x61, 0x73, 0xa1, 0xe0, 0x68, 0x3e, 0x80, 0xc3, 0x37, + 0x93, 0x68, 0x20, 0x2c, 0x41, 0xd8, 0x63, 0x0e, 0x5c, 0x25, 0x1e, 0x6a, + 0xcd, 0xf9, 0xfd, 0xcd, 0x1c, 0x61, 0x6c, 0xe6, 0x81, 0xcc, 0x20, 0x1d, + 0x0e, 0x61, 0x83, 0x5c, 0xd8, 0x3f, 0x91, 0xfc, 0xfe, 0xce, 0x87, 0x10, + 0xf2, 0x85, 0xba, 0x67, 0x95, 0xf4, 0x38, 0xdf, 0x80, 0x31, 0x14, 0x94, + 0x83, 0x3c, 0x5f, 0xcd, 0x40, 0x7c, 0x22, 0x96, 0x71, 0x0f, 0x73, 0xfb, + 0x01, 0xa1, 0xbe, 0x3c, 0x01, 0xd2, 0x94, 0x38, 0x91, 0x07, 0x8c, 0x13, + 0xcb, 0xb9, 0x06, 0xa4, 0x69, 0xd3, 0x3a, 0x42, 0x1b, 0xda, 0xd3, 0xd9, + 0xe9, 0xd9, 0xfe, 0xaa, 0xae, 0xf0, 0x3b, 0x97, 0x6f, 0xa0, 0x46, 0x0f, + 0xc7, 0x52, 0xa4, 0x33, 0x0a, 0xb5, 0x7f, 0x73, 0x7c, 0xf1, 0xc6, 0x6e, + 0xcf, 0x57, 0x87, 0x4b, 0x13, 0x90, 0x46, 0xf1, 0x2b, 0x3f, 0x7e, 0x3f, + 0x7c, 0x19, 0xbd, 0xb9, 0xf1, 0x5f, 0xad, 0x5e, 0x06, 0xfc, 0xee, 0x9e, + 0xb1, 0xbd, 0x38, 0x7e, 0x79, 0x26, 0x63, 0xfb, 0xf3, 0x9b, 0xe7, 0x7f, + 0x8d, 0xa3, 0xb9, 0x94, 0x0d, 0xb7, 0xba, 0xb1, 0x3f, 0x39, 0xd0, 0xb7, + 0xa1, 0xca, 0xfd, 0x85, 0xc3, 0xbc, 0x2f, 0x8e, 0xef, 0x77, 0x42, 0xfd, + 0x25, 0x79, 0xfd, 0x12, 0x96, 0x72, 0x9d, 0x84, 0x5a, 0x19, 0x7b, 0x8f, + 0xa3, 0xd6, 0x9d, 0x78, 0xe6, 0x3f, 0x4e, 0x9e, 0xa2, 0x21, 0x2f, 0xf6, + 0x87, 0x12, 0x9a, 0xcf, 0x8c, 0x19, 0x01, 0xb2, 0xe7, 0x6b, 0x8d, 0x7c, + 0x87, 0x27, 0xf0, 0xe9, 0x2d, 0xbf, 0x7c, 0xce, 0x41, 0x80, 0xdf, 0x85, + 0x08, 0x2b, 0x8b, 0xad, 0x9f, 0x05, 0x57, 0x0f, 0x46, 0x79, 0xd6, 0xf9, + 0x10, 0x05, 0x23, 0x2e, 0xae, 0x89, 0xe9, 0xab, 0x74, 0x64, 0x90, 0x85, + 0xa8, 0xf2, 0x0e, 0x7a, 0xbc, 0x22, 0x5c, 0xc5, 0x17, 0x80, 0xe9, 0xef, + 0x20, 0xbb, 0xd1, 0x99, 0x21, 0x63, 0x45, 0x12, 0x2e, 0x67, 0x8a, 0xf9, + 0x66, 0x51, 0xbc, 0x61, 0x63, 0x67, 0x0f, 0xa7, 0xa8, 0x05, 0x2c, 0x99, + 0xa1, 0x3a, 0x37, 0x47, 0x7d, 0xa2, 0x9c, 0x75, 0xf9, 0x92, 0xe8, 0x9c, + 0x9e, 0x5d, 0x9c, 0x9c, 0xbe, 0x3e, 0x4f, 0xfe, 0xb3, 0x73, 0x97, 0x4c, + 0x61, 0x22, 0x85, 0xb2, 0x1f, 0x52, 0xea, 0x49, 0xa6, 0x20, 0x91, 0x42, + 0xd3, 0x5f, 0xbe, 0xbc, 0x4c, 0xe1, 0x85, 0x0a, 0x73, 0xa3, 0x46, 0xdb, + 0xdb, 0x8a, 0x71, 0xe8, 0xaa, 0x47, 0xfc, 0x86, 0x78, 0xc4, 0xb8, 0xa3, + 0xce, 0x7f, 0x76, 0x90, 0x3a, 0x75, 0x05, 0xd7, 0xd4, 0x26, 0x1a, 0x99, + 0x0a, 0x18, 0x8a, 0x04, 0xab, 0xf8, 0xf4, 0x6f, 0xbf, 0xff, 0x05, 0x21, + 0x52, 0x08, 0x21, 0xe5, 0x00, 0xe4, 0x81, 0xf2, 0x6f, 0x5d, 0xfc, 0xf9, + 0x4b, 0xbf, 0xdf, 0x6f, 0x54, 0xa3, 0x35, 0x7e, 0x81, 0xdf, 0xa3, 0x07, + 0x4b, 0x8a, 0xd2, 0x9a, 0xd2, 0x8e, 0xed, 0x30, 0x16, 0x12, 0x7a, 0x57, + 0xe6, 0x69, 0x5e, 0x92, 0x81, 0xc6, 0x30, 0x19, 0xf0, 0x26, 0xef, 0x5a, + 0xb0, 0x0f, 0x5f, 0x61, 0x96, 0x7d, 0x68, 0xa4, 0xb7, 0x59, 0x6d, 0x29, + 0x28, 0x92, 0x93, 0xa7, 0xa4, 0xcf, 0xb0, 0x2f, 0xa2, 0x6c, 0x70, 0x03, + 0x41, 0x78, 0x9a, 0xa9, 0x1c, 0x91, 0xc8, 0x0c, 0x47, 0x36, 0x5c, 0xb1, + 0x65, 0xc8, 0x7a, 0xab, 0x87, 0x95, 0xca, 0xda, 0xb2, 0xa2, 0x97, 0x90, + 0x68, 0x41, 0x1c, 0x7b, 0x3b, 0xab, 0x87, 0xdb, 0x38, 0x9f, 0x2a, 0x89, + 0x0e, 0xa7, 0xdb, 0xe0, 0xa8, 0x06, 0x7d, 0x8c, 0x9f, 0x43, 0x49, 0x11, + 0x1e, 0x4e, 0x43, 0xeb, 0x4c, 0x0e, 0xb2, 0xc8, 0xce, 0x68, 0xb6, 0x92, + 0xd0, 0x90, 0x2d, 0xa6, 0xc1, 0xb0, 0x68, 0x99, 0xac, 0x70, 0xbf, 0xc2, + 0x1b, 0x40, 0x82, 0x0a, 0xde, 0x75, 0xab, 0x37, 0x79, 0x4c, 0x72, 0x98, + 0x9d, 0x83, 0xfc, 0x59, 0x2f, 0xdc, 0x60, 0x7c, 0x51, 0x3f, 0x9c, 0xad, + 0x8b, 0x8e, 0x40, 0x54, 0x6a, 0xea, 0x0c, 0xc1, 0xbd, 0x34, 0xc9, 0x5b, + 0x3d, 0x00, 0x38, 0x23, 0x9f, 0xa7, 0xed, 0xa0, 0x9f, 0x90, 0x24, 0x91, + 0x15, 0xd1, 0xbb, 0x16, 0x59, 0x11, 0xb0, 0xa6, 0xb0, 0x63, 0x25, 0x39, + 0xb2, 0xbb, 0xe2, 0x83, 0x61, 0x33, 0x6d, 0xd6, 0x02, 0xb7, 0x83, 0xb4, + 0x13, 0x92, 0xa5, 0x96, 0xc9, 0xa0, 0x8f, 0xae, 0xaa, 0xc9, 0x68, 0x98, + 0x96, 0xa3, 0xc0, 0xfc, 0x6d, 0xc3, 0xf9, 0x88, 0x15, 0x5c, 0x94, 0x2f, + 0x90, 0xba, 0x46, 0xcf, 0x87, 0xce, 0x62, 0x82, 0x8d, 0x6e, 0x11, 0xce, + 0x05, 0xf0, 0x0e, 0x87, 0x10, 0xae, 0x29, 0xeb, 0x86, 0x87, 0x98, 0x32, + 0xab, 0x9c, 0xbe, 0xa9, 0xa1, 0x70, 0x1a, 0x9a, 0xd1, 0xeb, 0xe5, 0xf3, + 0xeb, 0x87, 0xc1, 0xd2, 0x4d, 0x7f, 0x3f, 0x56, 0xd8, 0x93, 0xda, 0xe7, + 0xb0, 0x2f, 0xe8, 0x2a, 0x60, 0x2e, 0x75, 0x72, 0xd6, 0xac, 0x3c, 0xf8, + 0xc3, 0xad, 0x24, 0xae, 0xeb, 0x15, 0xc0, 0xbb, 0x24, 0x36, 0xd1, 0x8d, + 0xdf, 0x6f, 0xb4, 0x9c, 0x2b, 0x4e, 0xd0, 0xe2, 0x08, 0xba, 0x42, 0xb7, + 0x33, 0xe0, 0x0c, 0x6c, 0x54, 0x51, 0xec, 0x26, 0x72, 0xcc, 0xcd, 0x5d, + 0x09, 0xa6, 0xdc, 0x5a, 0x82, 0xd7, 0xe0, 0xa0, 0x70, 0x8a, 0x61, 0xb2, + 0x52, 0x06, 0x02, 0x73, 0x36, 0x29, 0x30, 0x2b, 0x68, 0x31, 0xa3, 0xec, + 0x20, 0x8b, 0x80, 0x75, 0x41, 0x73, 0x32, 0xca, 0x49, 0x41, 0xc6, 0x65, + 0x14, 0x7d, 0x28, 0xcd, 0x67, 0xa6, 0x95, 0xcb, 0xc9, 0xb9, 0x51, 0x21, + 0x87, 0xcc, 0x97, 0x61, 0xd9, 0x69, 0x3d, 0x39, 0xe0, 0x99, 0x08, 0xda, + 0x51, 0x12, 0x51, 0x87, 0xa3, 0x24, 0xf2, 0xd1, 0x18, 0x07, 0xb8, 0xa1, + 0x33, 0x57, 0x68, 0x2c, 0xa7, 0xce, 0x11, 0x15, 0x7a, 0x50, 0x87, 0x08, + 0x43, 0x24, 0xc0, 0xd7, 0xc0, 0x5f, 0x0c, 0x8f, 0xa3, 0xb9, 0x48, 0x95, + 0x81, 0x6b, 0xc5, 0xf4, 0xc2, 0xce, 0x56, 0xad, 0xf8, 0xa8, 0x9f, 0x74, + 0x35, 0x38, 0x91, 0x03, 0xd9, 0x61, 0xe5, 0xa9, 0xd8, 0xa4, 0x67, 0x02, + 0x5d, 0x2b, 0xa2, 0x2d, 0xc2, 0xb6, 0xa2, 0xd8, 0xc0, 0x84, 0x82, 0xc8, + 0x4d, 0x6c, 0x5b, 0xfc, 0xd3, 0x63, 0xaa, 0x12, 0x81, 0x53, 0x35, 0x28, + 0xbf, 0x1b, 0xa5, 0x7a, 0x8c, 0x40, 0x75, 0xa9, 0x62, 0x8f, 0x31, 0x20, + 0xae, 0xe5, 0x75, 0x4a, 0x98, 0x00, 0xe2, 0x50, 0xd4, 0x83, 0xf0, 0x9a, + 0xe4, 0x59, 0x3e, 0x42, 0xd3, 0x41, 0x38, 0x23, 0x92, 0xed, 0xe9, 0xce, + 0xc1, 0x6f, 0xc9, 0xab, 0xd3, 0x56, 0xdd, 0xcd, 0x74, 0xf0, 0xf0, 0xe1, + 0xfe, 0xc1, 0xee, 0x1e, 0x02, 0x5e, 0xef, 0x80, 0xde, 0xba, 0x6e, 0x74, + 0xbd, 0x2e, 0x94, 0x04, 0xd7, 0x4f, 0xea, 0x5e, 0x75, 0x3d, 0x74, 0x97, + 0x19, 0x12, 0xfa, 0x53, 0x58, 0xe7, 0xef, 0x4c, 0xa0, 0xd4, 0x50, 0x72, + 0x2a, 0x8a, 0x23, 0xb6, 0x1d, 0x20, 0xa7, 0x90, 0x18, 0xe3, 0x50, 0x88, + 0x98, 0xb0, 0x08, 0x2a, 0x87, 0xc1, 0x2b, 0x0c, 0xe1, 0x22, 0xc0, 0x87, + 0xe4, 0x75, 0x22, 0xc0, 0x6b, 0x95, 0x7a, 0x30, 0x14, 0x2b, 0x89, 0x1c, + 0x26, 0x6c, 0x2d, 0x52, 0x20, 0x8e, 0x4b, 0xae, 0xec, 0x91, 0x2c, 0xe6, + 0x7d, 0x43, 0xe2, 0x34, 0x63, 0x8a, 0xbe, 0x07, 0xfd, 0xed, 0x24, 0x11, + 0x80, 0x14, 0x47, 0xae, 0x5a, 0x37, 0x62, 0x03, 0x88, 0xea, 0x3c, 0xcb, + 0x91, 0x45, 0xf0, 0x12, 0x9b, 0x9e, 0xce, 0x8f, 0x2f, 0x04, 0x06, 0x07, + 0x3c, 0xb0, 0x00, 0x71, 0x20, 0xfa, 0x6e, 0x00, 0x44, 0x79, 0xf8, 0xe1, + 0x83, 0xb1, 0xcb, 0xa0, 0xf4, 0x70, 0x91, 0x18, 0x11, 0x02, 0x1f, 0xee, + 0x3c, 0xe9, 0x26, 0x0f, 0xf7, 0xbe, 0xe9, 0x62, 0xe2, 0x55, 0x17, 0x33, + 0xb9, 0xf6, 0xf0, 0xd7, 0x7d, 0x7c, 0xe8, 0xd1, 0xce, 0xc3, 0xf0, 0xaa, + 0xde, 0x7d, 0xa3, 0x2c, 0x8a, 0x2f, 0xd6, 0xa8, 0xed, 0x74, 0x50, 0xb0, + 0xc3, 0x9c, 0xf7, 0x07, 0xc6, 0x13, 0x2d, 0x27, 0x67, 0x5b, 0x71, 0xc4, + 0x3e, 0xa5, 0x8a, 0x70, 0x38, 0x6e, 0xb8, 0x15, 0x28, 0x88, 0x45, 0x9d, + 0x12, 0xf8, 0x4b, 0x7d, 0x05, 0xf4, 0x41, 0x29, 0x88, 0xb2, 0x42, 0x14, + 0xb4, 0x59, 0x2c, 0x28, 0x66, 0x93, 0xd5, 0xe8, 0x9c, 0xc1, 0xfa, 0x82, + 0xd5, 0x97, 0x63, 0xbd, 0x73, 0x0c, 0xfe, 0x4e, 0xa9, 0xec, 0xe4, 0x2e, + 0xae, 0x39, 0x31, 0xb9, 0x4a, 0x74, 0x52, 0x0e, 0x96, 0x29, 0xb3, 0x29, + 0x45, 0x3e, 0x71, 0x64, 0xb3, 0xc3, 0x65, 0xcb, 0x6c, 0xbd, 0x82, 0x6f, + 0x4c, 0x47, 0xd0, 0x27, 0xce, 0x2c, 0xb6, 0x84, 0x28, 0xea, 0x54, 0x6e, + 0xdd, 0x91, 0x9a, 0x92, 0x43, 0x31, 0x04, 0x60, 0x3e, 0x30, 0x5d, 0x42, + 0x1c, 0x4c, 0x06, 0xe9, 0xf0, 0x3d, 0xc6, 0x52, 0xa5, 0x93, 0xcb, 0xa2, + 0x84, 0x7d, 0x9b, 0xb2, 0x1d, 0x2f, 0x48, 0x6d, 0xd8, 0xde, 0x34, 0xfd, + 0xc0, 0xe6, 0x63, 0xbc, 0xbd, 0x29, 0xd2, 0xd5, 0x41, 0x8c, 0x15, 0xb5, + 0x1c, 0x4e, 0xcb, 0x87, 0x60, 0xb6, 0xc1, 0xc3, 0xf3, 0xa2, 0x35, 0x25, + 0x54, 0xe4, 0x16, 0xd1, 0x42, 0xd3, 0x78, 0x43, 0x1d, 0x1c, 0xe2, 0x9d, + 0x70, 0xe0, 0x32, 0x9f, 0x24, 0xa8, 0x12, 0x65, 0x07, 0xda, 0x99, 0x9b, + 0xd4, 0xe0, 0x54, 0x33, 0x2d, 0x1a, 0x8d, 0x35, 0x2f, 0xd4, 0x44, 0xcc, + 0x7a, 0x84, 0x0f, 0xb4, 0xc7, 0x0d, 0x0f, 0xb9, 0xac, 0xc8, 0xa1, 0x1e, + 0x53, 0x32, 0xab, 0xcb, 0xed, 0xa4, 0x67, 0xbe, 0x44, 0xf6, 0x0e, 0x35, + 0xfc, 0xf5, 0xba, 0x72, 0xb1, 0x5f, 0xe1, 0x98, 0xa3, 0xa0, 0x03, 0x86, + 0x2d, 0xb2, 0x95, 0x5a, 0xd6, 0xb1, 0x65, 0xb4, 0x9b, 0x01, 0xef, 0x67, + 0xbb, 0x6e, 0x33, 0xae, 0x9b, 0x78, 0x66, 0x5d, 0x80, 0x98, 0x8e, 0xf7, + 0xb8, 0x0f, 0xa6, 0x6f, 0x85, 0xb6, 0xd5, 0xfa, 0x92, 0x9d, 0x6a, 0x92, + 0x8d, 0x2e, 0xb3, 0xab, 0x74, 0x3a, 0xcd, 0xca, 0x0e, 0x91, 0x99, 0x46, + 0xe9, 0xf7, 0xb1, 0x42, 0x0a, 0x99, 0x36, 0xcc, 0x8b, 0x1d, 0x21, 0x7c, + 0x63, 0xdc, 0x8e, 0xde, 0xe3, 0xc9, 0xa6, 0x14, 0xd7, 0x20, 0xb3, 0x0a, + 0xad, 0x3c, 0x81, 0x7e, 0xe1, 0xca, 0x94, 0xc3, 0xad, 0xae, 0x7a, 0x96, + 0xd9, 0xc2, 0x62, 0x7c, 0x3e, 0x58, 0x58, 0xf0, 0x8a, 0xb2, 0x60, 0x2f, + 0xbe, 0x99, 0xf1, 0x5a, 0xb5, 0xda, 0xf5, 0x05, 0xe5, 0x22, 0x6a, 0xe1, + 0xa2, 0x64, 0xb4, 0xc0, 0x98, 0x28, 0xab, 0xb6, 0xc7, 0x29, 0xc1, 0x7e, + 0xb8, 0x2c, 0x73, 0xe9, 0xe5, 0x4a, 0xc4, 0x40, 0xc6, 0x7b, 0xd4, 0xc7, + 0xc8, 0xc2, 0xdd, 0x17, 0x27, 0x3d, 0x97, 0x6b, 0xd6, 0x11, 0xc1, 0xe9, + 0x23, 0xad, 0x0d, 0x4e, 0xc6, 0x15, 0x70, 0x82, 0x89, 0x68, 0x7e, 0x94, + 0x7d, 0x02, 0xa3, 0x0b, 0x75, 0x54, 0xe8, 0x3e, 0x22, 0xa4, 0x97, 0xa4, + 0x1a, 0x96, 0xf9, 0x9c, 0x30, 0x67, 0x11, 0x1b, 0x37, 0x6b, 0x14, 0x0e, + 0xd7, 0x35, 0x21, 0x64, 0x9b, 0xa5, 0x68, 0x2d, 0xb2, 0xb5, 0x59, 0x84, + 0xd5, 0x14, 0x54, 0x55, 0xcb, 0x6d, 0x5c, 0x46, 0x40, 0x13, 0x6e, 0x86, + 0x46, 0x76, 0x0b, 0x58, 0x9b, 0xa4, 0xef, 0x6f, 0x9d, 0xc0, 0x83, 0xf8, + 0x4d, 0x13, 0x8c, 0xf5, 0x70, 0xf9, 0x4f, 0xf8, 0xea, 0x15, 0xeb, 0xc5, + 0xb7, 0xe2, 0x2b, 0x95, 0x14, 0x92, 0x6e, 0x10, 0xb6, 0x6b, 0x07, 0x56, + 0x6a, 0x2f, 0x72, 0xac, 0x5c, 0x73, 0x0d, 0xdd, 0x12, 0x7a, 0x53, 0x61, + 0x57, 0x57, 0x90, 0x2e, 0x22, 0x4b, 0xf5, 0x90, 0xfb, 0x8b, 0xf3, 0xf8, + 0xd5, 0xbb, 0xc0, 0x3a, 0xbc, 0xca, 0x39, 0x32, 0xa3, 0x46, 0xbe, 0x71, + 0x80, 0xe3, 0xa2, 0x6c, 0x44, 0x98, 0x90, 0x44, 0x81, 0x24, 0x52, 0x57, + 0x47, 0xfd, 0x31, 0xec, 0x08, 0x7a, 0x01, 0x2c, 0x88, 0x62, 0x5f, 0x64, + 0x22, 0xc1, 0x2c, 0x50, 0x97, 0x0b, 0x46, 0x1c, 0xa2, 0x5e, 0xdd, 0x74, + 0xa4, 0x74, 0xd5, 0xff, 0x4a, 0xe6, 0x39, 0xc2, 0x8e, 0xc3, 0x5c, 0xbe, + 0x33, 0x84, 0x38, 0x66, 0xd0, 0x64, 0xc3, 0x75, 0x08, 0x70, 0x08, 0x14, + 0x9d, 0xfc, 0x94, 0xa1, 0x4d, 0x00, 0x44, 0x4f, 0x0c, 0xba, 0x5e, 0x5c, + 0x5e, 0x92, 0xed, 0xc8, 0x59, 0x8f, 0x71, 0x1a, 0x55, 0x26, 0x95, 0xb6, + 0xd0, 0x32, 0xab, 0x03, 0xbd, 0xce, 0x53, 0x6d, 0x48, 0x64, 0xbe, 0x9c, + 0xd0, 0x52, 0x06, 0x1a, 0xde, 0xe9, 0x22, 0x92, 0x2c, 0x48, 0x8f, 0x73, + 0x82, 0xa8, 0x7d, 0x3a, 0x3b, 0x7c, 0x08, 0x94, 0xee, 0xf5, 0x18, 0xc4, + 0x65, 0xbc, 0x1a, 0x48, 0x56, 0xc1, 0x46, 0xc9, 0x42, 0x88, 0xde, 0xda, + 0x24, 0xa7, 0x35, 0x64, 0xe5, 0x99, 0x5a, 0x8e, 0x97, 0x6f, 0x6a, 0x71, + 0x99, 0x72, 0x5d, 0x34, 0x06, 0xef, 0xe4, 0x6b, 0x9b, 0x9a, 0xeb, 0x4a, + 0xb8, 0x46, 0xe6, 0x72, 0xde, 0x8c, 0x7b, 0x07, 0x20, 0x33, 0xa6, 0x19, + 0x25, 0x19, 0x72, 0x0f, 0x06, 0x54, 0x2b, 0xbe, 0x25, 0x1e, 0xc2, 0x4d, + 0x0f, 0x3a, 0x00, 0x3c, 0xb8, 0xa0, 0x98, 0x59, 0xbe, 0x90, 0x75, 0x44, + 0x98, 0x8e, 0x8c, 0x31, 0x99, 0x0b, 0x94, 0xb4, 0x65, 0x31, 0xe4, 0xc6, + 0x56, 0xcf, 0x2f, 0x79, 0xe7, 0x66, 0xca, 0x27, 0x39, 0x1e, 0x3f, 0xb0, + 0x7d, 0x27, 0x62, 0x86, 0x1a, 0xec, 0x26, 0xf9, 0x60, 0x61, 0x6c, 0x0c, + 0x40, 0xe4, 0xc4, 0x8b, 0x86, 0x7d, 0x36, 0x5e, 0x01, 0x47, 0xa6, 0x24, + 0x0c, 0x85, 0xb5, 0xa8, 0xe8, 0x60, 0x39, 0x1b, 0x15, 0x8e, 0x48, 0x1d, + 0x1b, 0x53, 0xd4, 0x9f, 0x40, 0x18, 0x6a, 0x93, 0x66, 0x2a, 0xe6, 0x7c, + 0x29, 0x2d, 0x82, 0x85, 0xca, 0xa9, 0x02, 0x5d, 0xda, 0x2d, 0x30, 0x99, + 0xb8, 0x3b, 0x33, 0x8c, 0xcd, 0x74, 0x01, 0xa6, 0x09, 0x9e, 0x03, 0x8f, + 0x08, 0x38, 0x34, 0xf5, 0x89, 0xab, 0xf9, 0xe8, 0xc3, 0x87, 0xad, 0x44, + 0x84, 0x0f, 0x26, 0xbf, 0x2c, 0x18, 0xd5, 0xd9, 0x85, 0xd7, 0xe2, 0xae, + 0x8c, 0xef, 0xa5, 0xcf, 0x55, 0x10, 0xa7, 0xd9, 0xee, 0x3a, 0x37, 0xec, + 0xa3, 0xb6, 0xf1, 0xac, 0x57, 0xef, 0xa6, 0x59, 0xff, 0x5d, 0x2f, 0x48, + 0x7f, 0xf9, 0xa2, 0xd4, 0x0f, 0x4a, 0x0b, 0x3b, 0xcd, 0x48, 0xa8, 0x8f, + 0x63, 0xde, 0xd8, 0x19, 0xcc, 0x91, 0x63, 0x28, 0x37, 0xd2, 0x17, 0x95, + 0xd3, 0xb2, 0x92, 0x63, 0xc4, 0x20, 0x7d, 0x73, 0xfc, 0xfc, 0xed, 0xf9, + 0xf1, 0x33, 0xca, 0x64, 0x4c, 0x9b, 0xb4, 0xc2, 0x27, 0xb0, 0x2e, 0x0a, + 0x3a, 0x84, 0x3a, 0x8e, 0xbb, 0xef, 0xf4, 0x28, 0x10, 0x40, 0x5e, 0x58, + 0xde, 0x22, 0x37, 0xfa, 0x15, 0xe8, 0xa3, 0x1f, 0x9b, 0xb5, 0xd3, 0x6c, + 0x76, 0x8d, 0x2d, 0x8a, 0x46, 0xf1, 0x29, 0x82, 0x51, 0x94, 0x4c, 0x15, + 0x51, 0x87, 0xdf, 0x29, 0x96, 0x77, 0x9f, 0x4a, 0x36, 0xdd, 0x77, 0x21, + 0x90, 0x44, 0x83, 0xd0, 0x26, 0x59, 0x36, 0x97, 0xbb, 0x2d, 0x9d, 0x02, + 0x3b, 0x61, 0x1b, 0x1b, 0x1b, 0x26, 0x54, 0x63, 0xa2, 0x70, 0x21, 0xb9, + 0x5a, 0x23, 0x90, 0x41, 0xe3, 0x63, 0xb8, 0x6e, 0x72, 0x45, 0x89, 0x41, + 0xa1, 0xb9, 0x91, 0x9b, 0x58, 0xa1, 0x5e, 0x3c, 0x73, 0x1e, 0xb1, 0x58, + 0xae, 0x44, 0x91, 0xb5, 0xb9, 0x5f, 0x93, 0xb8, 0x1d, 0x06, 0xb3, 0xb0, + 0x9f, 0xad, 0xa5, 0x9c, 0xdf, 0x5c, 0xb2, 0xe2, 0x5d, 0x59, 0xb7, 0x4c, + 0x00, 0x0f, 0xc7, 0xb6, 0x56, 0xa4, 0xf2, 0x50, 0x88, 0x1c, 0x6d, 0x8f, + 0x53, 0xf9, 0xf0, 0x75, 0x5e, 0x24, 0xa4, 0xdb, 0x7f, 0x64, 0xa5, 0x25, + 0x1e, 0x07, 0xd5, 0x4f, 0x84, 0x3b, 0x07, 0xb3, 0xac, 0xe3, 0xa5, 0x01, + 0x5b, 0x0d, 0xf1, 0x48, 0xc5, 0xf8, 0x52, 0x55, 0x0e, 0x7c, 0x27, 0x8f, + 0x3e, 0x89, 0x72, 0x1a, 0x24, 0x62, 0x2a, 0x4c, 0x83, 0x4a, 0x38, 0x92, + 0x97, 0x56, 0x0f, 0xbf, 0x2e, 0x15, 0xbd, 0x82, 0x9c, 0x3b, 0x0d, 0x54, + 0x4b, 0xd4, 0x16, 0xdd, 0xad, 0x26, 0x32, 0x59, 0x3f, 0x88, 0xe6, 0xe4, + 0x8e, 0x2a, 0x33, 0x8e, 0x3e, 0x4d, 0xc9, 0x74, 0x84, 0x6e, 0xd9, 0x4d, + 0xc4, 0xa6, 0x92, 0x81, 0x6c, 0xd1, 0xe7, 0x64, 0xb0, 0x92, 0x98, 0x4f, + 0xe9, 0xd6, 0x45, 0xa7, 0xab, 0xaa, 0xa8, 0xbe, 0x67, 0x0e, 0x87, 0x23, + 0xbd, 0x0b, 0x76, 0x01, 0xae, 0xc4, 0x7c, 0x68, 0xb7, 0xb0, 0xe4, 0x9c, + 0x70, 0x23, 0xc2, 0x7b, 0x4d, 0x4c, 0xe1, 0x46, 0x18, 0x40, 0x70, 0x8a, + 0x79, 0xd1, 0xe2, 0x13, 0x09, 0x7e, 0x2e, 0xc2, 0x7a, 0x66, 0xf8, 0x4d, + 0x74, 0xab, 0xab, 0xf9, 0x01, 0xa8, 0xa6, 0x1b, 0x02, 0x70, 0x51, 0xde, + 0x20, 0x58, 0x52, 0x1a, 0xb7, 0xe6, 0xc1, 0x33, 0x55, 0xf1, 0xd8, 0x98, + 0xa2, 0xe1, 0xe5, 0xbc, 0x18, 0x11, 0x32, 0xa6, 0xe4, 0xaf, 0x5a, 0xb0, + 0x64, 0x80, 0xce, 0x85, 0x9e, 0x37, 0xaa, 0x80, 0x32, 0x90, 0x63, 0x50, + 0x2d, 0x87, 0x59, 0x9b, 0x0e, 0x24, 0x49, 0x7a, 0x81, 0x05, 0x02, 0xd1, + 0x22, 0xcd, 0x86, 0x20, 0x65, 0x12, 0xaf, 0xd4, 0x9e, 0xe6, 0x54, 0x61, + 0x4f, 0xa1, 0xb6, 0xe3, 0x5f, 0xd4, 0x2f, 0x12, 0xf5, 0xb4, 0xbf, 0x63, + 0xa4, 0xba, 0xbb, 0xf3, 0x29, 0xb4, 0x5a, 0xa5, 0x5c, 0x77, 0xed, 0xea, + 0x1f, 0xf9, 0x28, 0x79, 0xaa, 0xa5, 0x66, 0x1d, 0x6c, 0xbc, 0xa2, 0xb4, + 0xc3, 0x23, 0xc0, 0x3c, 0xfe, 0x21, 0xe2, 0xa2, 0x3e, 0x08, 0x97, 0xbb, + 0xbc, 0x8c, 0x9a, 0x96, 0x44, 0x31, 0x25, 0xe7, 0x87, 0x88, 0x70, 0x74, + 0xf6, 0xf2, 0xf0, 0xe4, 0xb5, 0xe5, 0x0b, 0xba, 0xf2, 0x0c, 0x5d, 0x56, + 0xd3, 0xc2, 0xd5, 0xc6, 0x55, 0x24, 0x39, 0xae, 0xa0, 0x51, 0x04, 0xca, + 0x7a, 0x12, 0x1f, 0x22, 0x7e, 0x3f, 0x84, 0xde, 0x48, 0x45, 0xf3, 0x38, + 0x5c, 0x3d, 0x2d, 0x31, 0x1d, 0x65, 0x46, 0xc5, 0xb5, 0x2e, 0x3d, 0x7c, + 0x7d, 0x84, 0x35, 0x03, 0x77, 0x67, 0xae, 0x68, 0x5f, 0x89, 0x4c, 0x28, + 0xaa, 0xa7, 0x9b, 0x25, 0xd2, 0x71, 0x97, 0x6b, 0x80, 0xa0, 0xc4, 0xe9, + 0x1a, 0xa3, 0x94, 0x66, 0x03, 0x4a, 0xb1, 0xe8, 0x20, 0x6e, 0x5e, 0x38, + 0x68, 0x54, 0xe7, 0x92, 0x8d, 0x6b, 0x02, 0xdf, 0xa9, 0xb7, 0x6d, 0xa2, + 0x80, 0x98, 0x6a, 0x13, 0x27, 0xe4, 0xc0, 0x0d, 0x0a, 0x4d, 0x19, 0x14, + 0x1f, 0xba, 0x2e, 0xca, 0xd0, 0xd0, 0x08, 0x2d, 0x32, 0xf4, 0x12, 0xb8, + 0x04, 0xa9, 0x16, 0x0a, 0xaa, 0x59, 0x70, 0x19, 0x64, 0xac, 0x74, 0x8c, + 0x28, 0x5b, 0x53, 0xb8, 0x46, 0xa0, 0x11, 0x81, 0xa4, 0x13, 0x44, 0x60, + 0xa2, 0x12, 0xf6, 0x45, 0x47, 0x84, 0xb0, 0x8e, 0x89, 0xe2, 0x93, 0xca, + 0x96, 0x45, 0xbd, 0x50, 0x4f, 0xd3, 0x74, 0x85, 0xaf, 0xd9, 0x09, 0x4f, + 0x68, 0x48, 0x89, 0x73, 0x9f, 0x8b, 0xcb, 0x7c, 0xd6, 0x0b, 0xf1, 0x2a, + 0x8e, 0x96, 0x73, 0x99, 0xdd, 0xf1, 0x4c, 0xe2, 0x19, 0x15, 0x2f, 0xd9, + 0xc9, 0xad, 0x44, 0x7e, 0x4c, 0xa4, 0xcd, 0x52, 0x25, 0x6d, 0xb0, 0xea, + 0xd2, 0xee, 0x9a, 0x82, 0x67, 0x4b, 0x28, 0x65, 0x13, 0x56, 0x5d, 0x1a, + 0x5c, 0x63, 0xa9, 0xf2, 0xf2, 0x8e, 0x15, 0xf2, 0xd5, 0x13, 0xdd, 0xba, + 0x86, 0xf5, 0xb8, 0xaf, 0xbc, 0xaf, 0xd5, 0xf7, 0x95, 0xb4, 0x32, 0xab, + 0xef, 0xdb, 0x97, 0x00, 0x85, 0xa5, 0x9a, 0xbd, 0x5f, 0xa6, 0x26, 0x46, + 0xd4, 0x0d, 0x56, 0x30, 0x18, 0x6d, 0xcb, 0xc9, 0x5c, 0x8b, 0xa3, 0x59, + 0x55, 0xc5, 0xa8, 0xb4, 0x90, 0x6f, 0x54, 0x97, 0xe4, 0x9c, 0x4a, 0x24, + 0x5c, 0x15, 0x37, 0x3e, 0x78, 0x94, 0xd4, 0xb4, 0x90, 0x35, 0x0d, 0x0f, + 0x60, 0xe8, 0x3a, 0x07, 0x2e, 0x39, 0x71, 0x05, 0x5f, 0x0b, 0x01, 0x9b, + 0x30, 0xdf, 0x8a, 0x10, 0x1e, 0x81, 0x13, 0xe8, 0xad, 0x45, 0x70, 0xcb, + 0x5f, 0x1a, 0xfc, 0xc0, 0xcb, 0xdd, 0x61, 0x26, 0xc9, 0xe7, 0x91, 0xb8, + 0x43, 0x83, 0xf7, 0x6c, 0x58, 0xe8, 0x58, 0x97, 0x6b, 0xcd, 0xad, 0xa2, + 0x9a, 0x02, 0x97, 0x54, 0xd2, 0x60, 0x9a, 0xd5, 0x21, 0xbd, 0x38, 0xb7, + 0x9d, 0x91, 0x0a, 0x07, 0x1e, 0x43, 0x4e, 0x00, 0xd9, 0x71, 0x03, 0x5a, + 0x6a, 0x2b, 0x68, 0xe0, 0x99, 0x59, 0xd7, 0x62, 0x0d, 0xda, 0x27, 0x9a, + 0x73, 0x76, 0xbd, 0xea, 0xc3, 0x94, 0x03, 0xa5, 0x11, 0x7c, 0x42, 0x70, + 0x9c, 0x73, 0x33, 0x2c, 0x8a, 0xf7, 0x39, 0x52, 0x34, 0x21, 0x77, 0x8a, + 0x05, 0x3c, 0x06, 0xa3, 0xeb, 0x4a, 0x37, 0x8a, 0xec, 0xc1, 0x32, 0x0d, + 0x05, 0xf7, 0x11, 0x88, 0x10, 0x83, 0x72, 0x59, 0x49, 0x13, 0x72, 0x6c, + 0x47, 0xd0, 0xf7, 0x1d, 0x19, 0x52, 0x87, 0x04, 0x38, 0x09, 0xd5, 0x30, + 0x7b, 0x9c, 0x06, 0x60, 0x06, 0x17, 0x19, 0xc8, 0x38, 0xd7, 0x79, 0x76, + 0x13, 0x09, 0x54, 0xd2, 0xc4, 0x92, 0x9f, 0x0d, 0x63, 0x48, 0xd0, 0x16, + 0x17, 0x3b, 0xd9, 0x08, 0x54, 0x11, 0xc9, 0x8d, 0x9d, 0x60, 0x62, 0xa2, + 0xd1, 0xba, 0xea, 0x73, 0xb8, 0xbb, 0x99, 0x2d, 0xe8, 0x5a, 0x91, 0xa0, + 0x8f, 0x44, 0x4d, 0x36, 0xb0, 0x24, 0xa8, 0xa5, 0x0d, 0xe3, 0x91, 0xe6, + 0x14, 0x3b, 0x23, 0xaf, 0x98, 0x4e, 0xca, 0x8c, 0x5f, 0x65, 0x52, 0x29, + 0x33, 0x45, 0xeb, 0x19, 0xdc, 0x46, 0x30, 0xf9, 0x2d, 0x47, 0x06, 0x5f, + 0x13, 0x9c, 0xa6, 0x5e, 0x4f, 0x37, 0x4c, 0xc5, 0x63, 0x4e, 0xf8, 0xe9, + 0x8b, 0x8f, 0x5a, 0x31, 0x07, 0x42, 0x62, 0x8a, 0xfa, 0x35, 0x14, 0x9a, + 0x26, 0x9d, 0xb4, 0x9c, 0x1b, 0x9d, 0x65, 0xcb, 0xc1, 0x81, 0x05, 0xd1, + 0x2b, 0x72, 0xcd, 0xa4, 0x4d, 0xdf, 0xe2, 0x9d, 0x47, 0x27, 0x5f, 0xef, + 0x9c, 0xc8, 0x06, 0xea, 0xe9, 0xa8, 0xba, 0x76, 0xce, 0xe4, 0x51, 0x3e, + 0x73, 0x64, 0x9c, 0xfe, 0xfb, 0x22, 0x67, 0xc4, 0x9c, 0x11, 0xaa, 0x4c, + 0x6a, 0x8a, 0x66, 0x7e, 0x95, 0xe8, 0x69, 0xa3, 0x50, 0x5f, 0x81, 0x46, + 0xf4, 0x01, 0xef, 0xc2, 0xc7, 0xaa, 0xbe, 0xa4, 0x41, 0x1c, 0xe1, 0x28, + 0xa7, 0x0b, 0x04, 0x81, 0x3a, 0xc1, 0x46, 0xa8, 0x94, 0x13, 0x9f, 0x2c, + 0x01, 0x43, 0x45, 0x53, 0xa6, 0xd6, 0xb5, 0x46, 0x5e, 0xa5, 0x08, 0xfb, + 0x45, 0xcd, 0x0e, 0x9e, 0xc9, 0x2d, 0x87, 0x02, 0x48, 0x28, 0x03, 0x74, + 0x0a, 0xc2, 0x7d, 0x3a, 0xd9, 0xae, 0xea, 0x11, 0xca, 0xce, 0x2e, 0x15, + 0x3c, 0x18, 0x23, 0x2d, 0xea, 0xe0, 0x2d, 0xc9, 0xe5, 0x8e, 0xbd, 0x50, + 0xdc, 0x7d, 0x6c, 0x02, 0x71, 0x64, 0x06, 0x1f, 0x98, 0xb7, 0x49, 0x67, + 0x6a, 0xd5, 0xfb, 0x60, 0xb6, 0x28, 0xaa, 0xf1, 0x14, 0x78, 0x39, 0x22, + 0xde, 0x5d, 0xf5, 0x63, 0x43, 0x93, 0xf0, 0x31, 0x23, 0x08, 0x27, 0xaf, + 0xdf, 0x5b, 0x3e, 0x65, 0x89, 0x1e, 0xa8, 0xad, 0x3b, 0x29, 0xa1, 0xfa, + 0x28, 0x4a, 0x20, 0x02, 0xa8, 0x81, 0xbc, 0x34, 0x09, 0x6a, 0x25, 0x27, + 0xed, 0x55, 0xef, 0xf3, 0x79, 0x8f, 0x52, 0x1a, 0x4d, 0x86, 0x61, 0x71, + 0x98, 0xf3, 0xeb, 0xa2, 0x4c, 0x5e, 0x75, 0x6e, 0x91, 0xf9, 0x21, 0xb5, + 0x84, 0x15, 0x51, 0x49, 0x05, 0x15, 0xac, 0x1b, 0x98, 0x56, 0x04, 0xe2, + 0x8f, 0x1d, 0xcd, 0xe3, 0xb2, 0x24, 0xec, 0x75, 0x4b, 0x67, 0x48, 0x81, + 0xe4, 0x2d, 0x53, 0x75, 0x31, 0xf4, 0x29, 0xc2, 0x50, 0x5a, 0xd9, 0xd1, + 0xa5, 0x02, 0x51, 0x96, 0x2a, 0x93, 0x20, 0x82, 0x7f, 0xd7, 0xd2, 0xf0, + 0x38, 0x05, 0x15, 0x79, 0xb6, 0x80, 0xa3, 0x25, 0x59, 0x3d, 0x74, 0xaa, + 0x22, 0x55, 0x83, 0xc0, 0xae, 0x2a, 0x35, 0x03, 0xeb, 0x34, 0x43, 0x02, + 0xa0, 0xce, 0x32, 0x9f, 0xf9, 0x94, 0x5f, 0x29, 0x5d, 0xa6, 0x27, 0x81, + 0x6d, 0xb7, 0x84, 0xd6, 0x8b, 0x13, 0xab, 0x1a, 0xa5, 0x39, 0xe8, 0x9e, + 0x87, 0x86, 0x1b, 0xc9, 0x54, 0x2d, 0x8b, 0xfd, 0x79, 0x93, 0x6e, 0xa2, + 0x0e, 0xee, 0xb9, 0x95, 0xfd, 0xa3, 0x96, 0x38, 0xc7, 0x4b, 0xbf, 0x0d, + 0x47, 0x8d, 0x32, 0xa5, 0xee, 0x35, 0x57, 0x8a, 0x72, 0xa6, 0x3c, 0x96, + 0x89, 0x51, 0xdc, 0xb3, 0x89, 0xb5, 0xda, 0x6d, 0x49, 0x60, 0x74, 0xf5, + 0x7f, 0x67, 0x85, 0xc2, 0x39, 0x04, 0xb2, 0xc4, 0xca, 0x54, 0x0f, 0x57, + 0x55, 0x27, 0x5b, 0x0a, 0x7b, 0x3a, 0x3f, 0x3d, 0xfa, 0xe3, 0xf9, 0xc3, + 0x64, 0xa9, 0x38, 0xd9, 0x6f, 0xaf, 0x4e, 0xc6, 0xf1, 0x79, 0x02, 0xd9, + 0x05, 0x83, 0xa2, 0xfc, 0x2a, 0x2c, 0xff, 0x8a, 0xc2, 0x9e, 0x73, 0x1e, + 0xfb, 0x90, 0x1b, 0x0b, 0x83, 0xd1, 0xba, 0x87, 0x1a, 0xd8, 0xa0, 0x91, + 0x51, 0x85, 0x31, 0x3c, 0xad, 0x64, 0x64, 0x55, 0xa2, 0x04, 0xaa, 0x82, + 0x8b, 0x21, 0x15, 0x94, 0x62, 0xfe, 0x76, 0x96, 0x7f, 0x00, 0x92, 0xc7, + 0x5b, 0x4a, 0x86, 0xc0, 0x26, 0x09, 0xda, 0x2a, 0x0a, 0x73, 0x22, 0x21, + 0x10, 0x7f, 0x13, 0xf6, 0x9a, 0xf5, 0x2f, 0xfb, 0x49, 0x87, 0xd7, 0x10, + 0x36, 0xcf, 0x1e, 0xdc, 0xc6, 0xb0, 0xd8, 0xed, 0xba, 0xd8, 0xe6, 0x66, + 0xfa, 0xf8, 0x4f, 0xa7, 0xcd, 0xed, 0x8a, 0xc9, 0xcc, 0x25, 0x95, 0x15, + 0xa4, 0x28, 0x1e, 0xbb, 0x36, 0x15, 0xa0, 0x21, 0xd4, 0x58, 0x63, 0x2b, + 0xd1, 0x2d, 0xc1, 0x95, 0x2a, 0x45, 0x63, 0xb0, 0x3f, 0x32, 0xf6, 0x0f, + 0x70, 0x11, 0x57, 0x79, 0x48, 0x0c, 0x6e, 0x16, 0x04, 0xaf, 0x16, 0x68, + 0xcf, 0x99, 0x2c, 0xb0, 0x65, 0xe7, 0x3f, 0x8a, 0x90, 0xce, 0xd2, 0x44, + 0x48, 0xc1, 0x57, 0x66, 0xf3, 0x35, 0x79, 0x25, 0xb8, 0x40, 0x9f, 0x83, + 0xe9, 0x86, 0xd0, 0x40, 0x0e, 0xea, 0x09, 0xa8, 0xd8, 0x5a, 0xe2, 0x2c, + 0x4a, 0x15, 0xa7, 0xe4, 0x2d, 0x43, 0x08, 0x21, 0x4a, 0xd2, 0x1a, 0x5d, + 0xa2, 0x3b, 0x87, 0x4c, 0x3a, 0x5f, 0xa6, 0x5d, 0x0d, 0xdf, 0xea, 0x90, + 0x22, 0x28, 0x53, 0x5f, 0x46, 0x14, 0x0d, 0xf2, 0xec, 0x27, 0xa1, 0xe8, + 0x2d, 0x85, 0x60, 0x24, 0x43, 0x9d, 0xc1, 0x63, 0x71, 0x28, 0x95, 0x50, + 0x43, 0xdc, 0xb9, 0x46, 0x78, 0x84, 0xc7, 0x36, 0xb5, 0xb2, 0x18, 0x3d, + 0xb8, 0x15, 0x0c, 0x4e, 0x16, 0xad, 0x8f, 0x84, 0x10, 0x8d, 0x41, 0x54, + 0x33, 0x5e, 0xc3, 0xbb, 0x20, 0xa2, 0x3f, 0x12, 0xd0, 0xa8, 0xc9, 0x4d, + 0xb8, 0x03, 0xa5, 0xfc, 0x83, 0x87, 0x3b, 0xdf, 0x3c, 0x5e, 0xef, 0xca, + 0xe2, 0x37, 0xd3, 0xa5, 0x72, 0x74, 0xfc, 0x47, 0x4f, 0x5b, 0x6c, 0x70, + 0x86, 0xf4, 0x4e, 0xd6, 0xb0, 0xc4, 0x19, 0xd2, 0xdf, 0xc2, 0x1a, 0x3c, + 0x6f, 0x30, 0xe6, 0x20, 0xdc, 0x81, 0xcd, 0xe0, 0x20, 0xdd, 0x54, 0x89, + 0x2f, 0x2b, 0xa7, 0xfb, 0xd2, 0xc6, 0x15, 0xbe, 0xe8, 0x69, 0x4f, 0xff, + 0xef, 0x7b, 0xdc, 0xfd, 0x69, 0x97, 0xe3, 0x6e, 0x21, 0x99, 0xe1, 0xfc, + 0xe9, 0xf6, 0xae, 0x79, 0xdc, 0xd3, 0x7f, 0xc7, 0x79, 0xd7, 0xae, 0x2d, + 0xda, 0x32, 0xf2, 0x41, 0x6f, 0x37, 0xce, 0xdb, 0x4c, 0xc3, 0x42, 0xfc, + 0xa9, 0x57, 0xf8, 0x05, 0xb4, 0xd1, 0xdb, 0x71, 0x0e, 0x30, 0x6a, 0x3c, + 0x0a, 0xad, 0x49, 0x28, 0x35, 0x2e, 0xfd, 0xc9, 0xb7, 0xa3, 0x2f, 0xe7, + 0x87, 0xcf, 0xbf, 0xbd, 0xcf, 0x9a, 0x63, 0xeb, 0xe1, 0x77, 0x47, 0xe6, + 0x0b, 0xda, 0x64, 0xa4, 0x87, 0x4f, 0x3e, 0xff, 0x1f, 0x77, 0xfc, 0x1f, + 0xdd, 0x55, 0xb6, 0x34, 0x1c, 0x7e, 0x5a, 0xa5, 0x47, 0xb2, 0xac, 0x3d, + 0x92, 0xef, 0x5b, 0xaf, 0x69, 0x3e, 0x5b, 0x93, 0xdb, 0x18, 0x19, 0xc4, + 0xc7, 0xa7, 0xe7, 0x55, 0xd3, 0x22, 0xbc, 0x46, 0x41, 0xd3, 0x2f, 0x70, + 0xbe, 0x1f, 0xfd, 0xef, 0x71, 0x9b, 0x3f, 0x5a, 0xf3, 0x78, 0x3f, 0xfa, + 0x7f, 0xfb, 0xe9, 0xf6, 0xf7, 0x7a, 0x54, 0xa1, 0x7c, 0x55, 0x15, 0x78, + 0x57, 0x06, 0x9e, 0x0d, 0x2d, 0xcf, 0xa9, 0xec, 0x38, 0xbc, 0xfe, 0xf2, + 0xd9, 0xe1, 0x59, 0xcc, 0x11, 0x1e, 0x7d, 0x39, 0xff, 0xa8, 0xb4, 0xcf, + 0x83, 0x95, 0xe3, 0x7f, 0xf0, 0x35, 0x22, 0xf3, 0xae, 0xcf, 0x13, 0xc2, + 0xe1, 0xf7, 0x2c, 0xe1, 0x61, 0xda, 0x60, 0x05, 0xbd, 0x41, 0x5a, 0x69, + 0xb9, 0x4e, 0x64, 0x01, 0x5a, 0xa1, 0x7b, 0xdb, 0x8a, 0x73, 0x37, 0xbd, + 0x44, 0x1c, 0xd8, 0x2c, 0x15, 0x35, 0x28, 0x18, 0x96, 0xe2, 0xab, 0x98, + 0x5b, 0x38, 0x09, 0xaf, 0x6f, 0x35, 0x9b, 0xee, 0x6c, 0x0f, 0x51, 0x94, + 0x04, 0x1c, 0xd8, 0x85, 0x1a, 0xf6, 0x23, 0x13, 0x05, 0x8f, 0xf4, 0xb2, + 0xaa, 0xd2, 0x79, 0xce, 0x84, 0x01, 0x87, 0x1c, 0x4f, 0xc8, 0x8f, 0xe7, + 0xe7, 0xbd, 0xc3, 0xb3, 0x93, 0x65, 0x57, 0x16, 0x3e, 0xd3, 0x1c, 0x11, + 0x39, 0x11, 0x63, 0x85, 0xd2, 0x2d, 0xc1, 0xc7, 0x01, 0xa0, 0xae, 0xb1, + 0x7d, 0xd2, 0xac, 0xed, 0xe6, 0xa7, 0x32, 0xf7, 0x47, 0xcd, 0x1d, 0xe3, + 0x75, 0x08, 0x0b, 0xa4, 0x8b, 0xd0, 0x58, 0x83, 0xf6, 0x7d, 0xf2, 0x4c, + 0xdd, 0xc3, 0x6c, 0xaf, 0x68, 0xa4, 0x7d, 0x77, 0x92, 0xcd, 0x3c, 0x80, + 0x67, 0x53, 0x44, 0x63, 0x88, 0x55, 0x14, 0x38, 0x3b, 0xdb, 0x19, 0xc3, + 0xc3, 0xdb, 0xea, 0x9b, 0x90, 0xb9, 0xbc, 0xf6, 0xe2, 0x96, 0xe4, 0x7d, + 0x35, 0x5b, 0x7c, 0x83, 0x72, 0xee, 0xd8, 0x65, 0xb7, 0xc3, 0x6d, 0x4e, + 0xa5, 0x88, 0x80, 0x56, 0xb9, 0x96, 0x1a, 0x16, 0x27, 0x6f, 0x31, 0x10, + 0xcf, 0x6a, 0xd3, 0xf0, 0xe4, 0x9b, 0x5d, 0x8b, 0x24, 0x64, 0x04, 0x5f, + 0x8a, 0x26, 0x7a, 0xb0, 0xd7, 0x62, 0x5e, 0xa8, 0x14, 0xce, 0x49, 0x8b, + 0x67, 0xb8, 0x2d, 0x51, 0x1f, 0x0e, 0x3b, 0x7d, 0x59, 0x58, 0xac, 0x33, + 0x41, 0xe9, 0xa1, 0x3a, 0x70, 0x81, 0xb5, 0x99, 0xbf, 0x07, 0x2b, 0x78, + 0x51, 0xfd, 0xc7, 0xdd, 0x6f, 0x1e, 0x23, 0x20, 0x40, 0x7a, 0x2b, 0xee, + 0x80, 0x4a, 0xdf, 0x7c, 0xd8, 0xdf, 0xdf, 0x7e, 0xd8, 0x7f, 0xc8, 0x16, + 0x16, 0x4d, 0x49, 0xb3, 0x98, 0x5b, 0xe9, 0x43, 0xc2, 0x51, 0x65, 0x48, + 0xaf, 0x8f, 0x8f, 0x12, 0x86, 0x28, 0xa3, 0x72, 0xe5, 0xb1, 0xdf, 0xd6, + 0xf1, 0x64, 0x4f, 0xa9, 0xc2, 0xb0, 0x5b, 0xa6, 0x2e, 0xe5, 0xa8, 0xb9, + 0xe9, 0xc5, 0xcc, 0x7a, 0xc4, 0xcb, 0x97, 0xb3, 0xb6, 0x23, 0xef, 0x82, + 0x9f, 0xb5, 0x4e, 0xdb, 0x2d, 0x4d, 0x44, 0x49, 0x77, 0x2e, 0xf6, 0x67, + 0x36, 0x42, 0x35, 0x3b, 0xf9, 0x08, 0xca, 0xa2, 0x55, 0x58, 0x41, 0x5d, + 0x0c, 0xe9, 0xf3, 0xdb, 0x69, 0x4c, 0xfd, 0x98, 0x4d, 0x27, 0xa7, 0xd6, + 0xf1, 0x90, 0xaf, 0x13, 0x71, 0x74, 0x6a, 0x1a, 0x67, 0xc2, 0x32, 0x89, + 0xab, 0xd7, 0x8b, 0x75, 0xab, 0x24, 0xae, 0x3c, 0x24, 0xd9, 0x0d, 0xa7, + 0xea, 0x8f, 0xec, 0x8d, 0xff, 0x3e, 0x9a, 0xf5, 0xa3, 0x1b, 0xb7, 0x39, + 0x84, 0x2f, 0x17, 0xfa, 0xd1, 0xde, 0x1f, 0xb9, 0x4b, 0xbf, 0xd8, 0xfa, + 0xda, 0x7d, 0x7d, 0x87, 0x74, 0xbe, 0x2c, 0x9e, 0xab, 0x60, 0xb4, 0x49, + 0x29, 0x53, 0x01, 0x1d, 0x9a, 0x3e, 0x54, 0x79, 0x3d, 0x10, 0xbd, 0x76, + 0xb2, 0xd5, 0x8f, 0x04, 0xf5, 0x86, 0xa4, 0xbe, 0x5a, 0x54, 0x4f, 0x34, + 0xfe, 0xf4, 0xdf, 0x23, 0xb0, 0x5f, 0xfd, 0x3f, 0x43, 0x21, 0x8f, 0xf5, + 0xf1, 0x86, 0x3a, 0xfe, 0x28, 0xac, 0xba, 0x37, 0x80, 0xdd, 0x21, 0xb7, + 0x5f, 0xfd, 0xbf, 0x5a, 0x70, 0x5f, 0xad, 0x97, 0xb7, 0x29, 0xe6, 0xee, + 0xdc, 0x7c, 0x61, 0x79, 0x3c, 0x74, 0xf4, 0xdb, 0x04, 0xf3, 0x76, 0x79, + 0xfc, 0xaf, 0xa4, 0xc3, 0xcf, 0xb3, 0x6c, 0xc4, 0xd5, 0x06, 0x92, 0xa7, + 0xf4, 0x87, 0xcf, 0x38, 0x0c, 0xfe, 0x11, 0xa0, 0x38, 0x4c, 0xc6, 0x0a, + 0x35, 0x6b, 0x24, 0xe3, 0x97, 0x5e, 0x01, 0xe9, 0x6c, 0x26, 0xc5, 0xca, + 0x5c, 0x21, 0x8f, 0x2d, 0x45, 0x4f, 0xc0, 0x38, 0x25, 0x8e, 0xeb, 0x0b, + 0x70, 0x94, 0x12, 0x35, 0x49, 0x87, 0x9d, 0x0a, 0x3c, 0x69, 0xcd, 0x68, + 0x92, 0xe1, 0x7d, 0xfc, 0x5f, 0xc0, 0xea, 0xf6, 0x18, 0x2d, 0x3c, 0x6e, + 0x7e, 0x4e, 0xc0, 0xd7, 0x90, 0xd3, 0xef, 0xef, 0x24, 0x56, 0x04, 0x23, + 0x89, 0xc4, 0xfb, 0xc4, 0x97, 0xe1, 0xf3, 0xb3, 0xfe, 0xa2, 0x65, 0xf8, + 0x7c, 0x47, 0xfb, 0x3b, 0x3b, 0xf1, 0xc0, 0xd7, 0x8d, 0xe9, 0x0b, 0xaf, + 0x74, 0xdb, 0x2a, 0x43, 0x34, 0x73, 0xbd, 0x6e, 0xbb, 0x71, 0x37, 0x8d, + 0x08, 0xd5, 0x78, 0x63, 0xb1, 0xba, 0x4a, 0xb4, 0xb5, 0x7e, 0xc4, 0x61, + 0x4b, 0xb5, 0xe0, 0x0b, 0xc7, 0x00, 0x8a, 0x70, 0x9a, 0xf8, 0x4d, 0xe0, + 0xcd, 0xea, 0x36, 0xfd, 0x6a, 0x68, 0x6c, 0xd5, 0x9d, 0x3d, 0xe1, 0xb0, + 0x3a, 0x7b, 0xc5, 0x2f, 0x63, 0x37, 0x02, 0x70, 0x6c, 0xec, 0xcf, 0xae, + 0xfa, 0x95, 0xad, 0x56, 0x42, 0xb4, 0xb2, 0x6d, 0xec, 0x52, 0x50, 0x2e, + 0x2a, 0x9f, 0xb5, 0x4d, 0x54, 0x5a, 0x20, 0xfd, 0xb0, 0x67, 0x1a, 0xc3, + 0xcb, 0xb6, 0x48, 0x36, 0x6c, 0x00, 0x7e, 0xa4, 0x5c, 0x08, 0xa9, 0xa2, + 0xca, 0x54, 0xc6, 0x3a, 0xb2, 0x7a, 0x28, 0x57, 0x98, 0x94, 0x92, 0xc7, + 0xc4, 0x61, 0xe0, 0xc2, 0xa5, 0x20, 0x4d, 0x02, 0x33, 0x86, 0x59, 0x94, + 0xb7, 0xee, 0xee, 0x73, 0xa9, 0xbe, 0x1a, 0x5c, 0xaa, 0xc0, 0x4f, 0xca, + 0x51, 0xa2, 0xf5, 0xf8, 0x62, 0xc2, 0xc5, 0xe7, 0x23, 0x43, 0x09, 0xc4, + 0x25, 0xca, 0x0b, 0xa4, 0x18, 0x24, 0x8b, 0x4a, 0x46, 0xbc, 0x89, 0xc9, + 0xb9, 0x04, 0xc4, 0x43, 0x10, 0x3f, 0x84, 0xa5, 0x83, 0x26, 0x0d, 0xe0, + 0xb6, 0x3f, 0xa5, 0x25, 0x66, 0xd6, 0x1f, 0x58, 0x4e, 0x95, 0xc6, 0xb7, + 0x30, 0xd2, 0x2c, 0x22, 0xc4, 0x64, 0x30, 0xf0, 0x2c, 0xc6, 0x8a, 0x37, + 0x68, 0x0b, 0x01, 0x83, 0xc2, 0xae, 0x10, 0x05, 0x24, 0x14, 0x24, 0x91, + 0x50, 0xab, 0x85, 0x62, 0xd9, 0x26, 0x8b, 0xf9, 0x65, 0x99, 0x8e, 0x34, + 0xbf, 0x9f, 0xb4, 0x51, 0x6e, 0xd9, 0xd5, 0xe7, 0x34, 0xe2, 0x29, 0x6f, + 0x0d, 0xea, 0x08, 0x6b, 0x78, 0x6e, 0x5f, 0xbc, 0x3c, 0x0f, 0x40, 0x12, + 0xe1, 0x79, 0x04, 0xbc, 0x07, 0x06, 0x56, 0x53, 0xd9, 0x21, 0xaa, 0xf9, + 0x21, 0x75, 0x41, 0x35, 0xde, 0xfa, 0xfc, 0xe2, 0xf0, 0xcd, 0x05, 0xbe, + 0x8c, 0xf1, 0x76, 0xf8, 0x2f, 0x0c, 0x8a, 0xa0, 0x9f, 0x2c, 0xd7, 0x16, + 0x51, 0xbb, 0x08, 0xd7, 0x41, 0x0b, 0x3f, 0xa3, 0xa2, 0x83, 0xbb, 0x2d, + 0xa8, 0x68, 0xa9, 0xba, 0xac, 0x67, 0xbd, 0xa5, 0xe1, 0xaa, 0xcb, 0xdd, + 0x62, 0x5b, 0x0d, 0x33, 0x5f, 0x92, 0xe4, 0x65, 0xe8, 0x7d, 0xda, 0x3a, + 0xc5, 0xff, 0x67, 0x10, 0xbd, 0x7a, 0x4e, 0x6b, 0x66, 0x00, 0x30, 0xc4, + 0x36, 0xdd, 0x3a, 0x4a, 0x61, 0x74, 0x83, 0xc7, 0x00, 0xe1, 0xee, 0x3a, + 0x9b, 0x54, 0xa1, 0x3a, 0x0c, 0xa8, 0x4c, 0xe5, 0x2d, 0x9f, 0x2f, 0x0c, + 0x1f, 0x88, 0x10, 0x07, 0x1a, 0x49, 0xa0, 0x94, 0xe5, 0x28, 0x59, 0xf9, + 0xb8, 0xed, 0x49, 0x9c, 0x3c, 0xfb, 0x64, 0x97, 0x2b, 0xc1, 0x9e, 0x30, + 0xff, 0xa5, 0xac, 0x2b, 0x4d, 0xe9, 0xd2, 0xaa, 0x5f, 0x52, 0xe4, 0x17, + 0xab, 0xba, 0x52, 0x0b, 0x98, 0x3e, 0x90, 0x69, 0xe6, 0x96, 0x96, 0x97, + 0xd5, 0xa2, 0xe8, 0xd9, 0x0c, 0xf8, 0x0f, 0xa8, 0xf5, 0x93, 0x51, 0x3a, + 0x0f, 0xd9, 0x11, 0x59, 0xa8, 0x0b, 0xcc, 0x49, 0x94, 0x74, 0xc8, 0x33, + 0x45, 0xdc, 0x4c, 0x43, 0x71, 0x05, 0x46, 0xe8, 0xa2, 0x14, 0x47, 0x81, + 0x70, 0x71, 0x3b, 0x9e, 0x7b, 0x25, 0xce, 0xeb, 0xb2, 0x6e, 0xf5, 0x87, + 0xc3, 0xac, 0x7d, 0x35, 0x30, 0x16, 0x02, 0x63, 0xe0, 0x33, 0x84, 0x2d, + 0xc2, 0x50, 0x86, 0x19, 0x09, 0x81, 0xb6, 0x1f, 0x82, 0xda, 0x23, 0x4f, + 0xb3, 0x58, 0x01, 0x72, 0x96, 0xd6, 0xa7, 0xc0, 0xf0, 0x16, 0x15, 0xb9, + 0x90, 0x55, 0x59, 0x62, 0xa9, 0x24, 0x3f, 0x0a, 0xae, 0xf9, 0x78, 0x41, + 0xa5, 0x04, 0x14, 0x64, 0xa3, 0xcd, 0x24, 0x51, 0x4d, 0xee, 0xc1, 0x82, + 0x6c, 0x0b, 0x71, 0x15, 0x95, 0xb1, 0xa9, 0x31, 0x56, 0xf7, 0xa0, 0xbe, + 0x62, 0x67, 0xf3, 0x62, 0xbe, 0x7f, 0x7f, 0x68, 0xab, 0x10, 0x5f, 0x97, + 0x02, 0xc1, 0x84, 0xdc, 0x99, 0xbb, 0x0c, 0xf3, 0xf9, 0x55, 0xe6, 0x72, + 0x73, 0xf0, 0x51, 0xd2, 0xb7, 0x7b, 0x83, 0xcc, 0xea, 0xf1, 0x6d, 0x02, + 0xad, 0x6f, 0x61, 0x58, 0x54, 0xb0, 0xa3, 0xa6, 0x25, 0x25, 0xf8, 0xd1, + 0xe6, 0x42, 0x73, 0x18, 0xc7, 0x3e, 0x9e, 0x60, 0xbd, 0x21, 0x41, 0x93, + 0x82, 0x37, 0x80, 0xfa, 0x42, 0xdc, 0x1e, 0x37, 0xc4, 0x3b, 0x03, 0xeb, + 0xf1, 0xc3, 0xf1, 0xe1, 0xf9, 0x45, 0x60, 0xf4, 0x8e, 0xa6, 0x25, 0x07, + 0x58, 0xee, 0x2a, 0x3c, 0xda, 0x93, 0xf4, 0x16, 0xcb, 0xb5, 0x21, 0xed, + 0x18, 0x2e, 0x33, 0x8e, 0x81, 0x87, 0x50, 0xe9, 0x76, 0xe3, 0xa1, 0x66, + 0x16, 0x40, 0x99, 0x36, 0x14, 0x66, 0xa3, 0xe9, 0xb8, 0x96, 0xf9, 0x2b, + 0xa2, 0x0d, 0x66, 0x09, 0x0a, 0xe3, 0x9b, 0x8c, 0x42, 0xd0, 0x60, 0x6c, + 0xa8, 0x68, 0x8d, 0x43, 0x8d, 0x71, 0xfc, 0xae, 0xb4, 0xaa, 0x22, 0xd1, + 0x28, 0xf1, 0x21, 0x9c, 0x35, 0x2e, 0x6d, 0x8c, 0x21, 0x2a, 0x9d, 0xcd, + 0x12, 0x84, 0x3f, 0x2c, 0xe9, 0x49, 0xad, 0xac, 0xbc, 0x94, 0x56, 0xec, + 0x57, 0x64, 0x82, 0x00, 0xec, 0x33, 0x71, 0xa3, 0xe2, 0x5b, 0xba, 0xda, + 0x82, 0x86, 0x1b, 0x20, 0x09, 0x43, 0x86, 0x37, 0x17, 0x35, 0xe2, 0xe2, + 0x9f, 0x12, 0x60, 0xc6, 0xa1, 0xea, 0x43, 0x84, 0x17, 0xa1, 0x53, 0xb9, + 0x04, 0x7b, 0xdb, 0xba, 0xed, 0x9f, 0xd9, 0x00, 0x12, 0x77, 0x71, 0x2f, + 0x69, 0xfb, 0x87, 0xd7, 0xbb, 0x3b, 0x25, 0x68, 0xb9, 0xf1, 0x2a, 0xd3, + 0xb9, 0x92, 0x7d, 0x4c, 0xe8, 0x8b, 0x1a, 0x83, 0x6c, 0x30, 0x17, 0xac, + 0x07, 0x22, 0x46, 0x44, 0xed, 0x9b, 0xe7, 0xb8, 0xcb, 0xb3, 0x6c, 0xb2, + 0x95, 0x1c, 0x46, 0x15, 0x2f, 0x08, 0x6f, 0x90, 0x8f, 0x0f, 0x81, 0xef, + 0x24, 0xdc, 0x00, 0x0c, 0x1d, 0x5a, 0x60, 0x30, 0xcd, 0xcc, 0x09, 0xe5, + 0x8d, 0xb4, 0x8d, 0x1b, 0x2e, 0xa5, 0xa7, 0xc5, 0x22, 0x85, 0xb3, 0xaa, + 0xed, 0xe4, 0x3c, 0xd4, 0x10, 0xf4, 0x89, 0x0f, 0xa8, 0x11, 0x6a, 0xbc, + 0x2a, 0xaa, 0xbe, 0xae, 0x27, 0x66, 0xb2, 0xc2, 0xcf, 0x2b, 0x1d, 0x4b, + 0xd3, 0xa2, 0xaa, 0xf1, 0xf3, 0xc4, 0xea, 0xcf, 0xa3, 0xa1, 0x22, 0xfb, + 0xa3, 0xea, 0x0a, 0x04, 0x62, 0xa3, 0x78, 0x53, 0x64, 0x3d, 0xcc, 0xaf, + 0x53, 0x2c, 0x20, 0x0a, 0x4a, 0xf6, 0x24, 0xb5, 0x98, 0x54, 0x4d, 0xfe, + 0xd7, 0xda, 0x2b, 0x8d, 0xb0, 0xd0, 0x96, 0x55, 0xfd, 0x4c, 0xe1, 0xa1, + 0x2d, 0x2d, 0xaf, 0x41, 0x43, 0xcd, 0xb1, 0xac, 0x97, 0x69, 0xfa, 0x75, + 0x23, 0x59, 0xc2, 0x51, 0xd6, 0xf2, 0x10, 0x02, 0x3d, 0x51, 0xc2, 0x25, + 0x82, 0x85, 0xae, 0x20, 0x24, 0x9b, 0x5f, 0xb4, 0xfe, 0xf8, 0x8a, 0x6c, + 0xd4, 0xf0, 0x2a, 0x03, 0xed, 0xb1, 0x1f, 0x98, 0x81, 0xcb, 0xef, 0x6f, + 0x70, 0x04, 0x56, 0xc5, 0xcf, 0x5f, 0x3a, 0x8e, 0x40, 0xa2, 0x86, 0x2b, + 0x09, 0x84, 0x99, 0xd6, 0xca, 0x0b, 0x14, 0xeb, 0xe8, 0x7d, 0x22, 0x58, + 0x0f, 0xc4, 0x0c, 0x98, 0x17, 0x34, 0x37, 0xd0, 0xa6, 0xf1, 0x79, 0xaa, + 0xb1, 0x44, 0x4d, 0xde, 0xbf, 0x65, 0xa1, 0xf7, 0xf5, 0x60, 0x7e, 0xca, + 0x89, 0xaf, 0xa4, 0x6e, 0x77, 0x5d, 0x53, 0x40, 0x76, 0x12, 0xb2, 0x88, + 0xc8, 0x6f, 0x58, 0xba, 0xba, 0x4f, 0x10, 0xd5, 0xda, 0x29, 0x4b, 0xc2, + 0x28, 0x92, 0xb1, 0xc9, 0xa1, 0xab, 0x05, 0x51, 0x93, 0x44, 0x23, 0xcc, + 0x37, 0xc4, 0x11, 0xe4, 0xb0, 0xde, 0xda, 0x00, 0x61, 0x1b, 0xd2, 0x50, + 0xac, 0xe4, 0x69, 0x48, 0x68, 0xc0, 0xdf, 0x60, 0xb9, 0xdb, 0xb0, 0x37, + 0x55, 0x26, 0xfd, 0xf7, 0xcb, 0x8a, 0x48, 0x77, 0x65, 0xf6, 0x2b, 0x1b, + 0xe5, 0xef, 0x95, 0x15, 0x71, 0x6a, 0x5a, 0x15, 0x89, 0xae, 0x34, 0xc2, + 0x57, 0x5a, 0x2d, 0xe8, 0xa2, 0xee, 0x85, 0xeb, 0x82, 0x11, 0xc7, 0x88, + 0x01, 0x30, 0xb6, 0x12, 0x0d, 0xc0, 0xa5, 0x10, 0x22, 0xb2, 0x82, 0x53, + 0x33, 0x15, 0x46, 0x98, 0x53, 0xb9, 0xbc, 0x2a, 0x9b, 0x8c, 0x43, 0xca, + 0x18, 0x41, 0xfe, 0x4c, 0xa7, 0xd9, 0xc8, 0xf2, 0x5b, 0xe8, 0x53, 0xec, + 0x5e, 0x33, 0x43, 0x60, 0x18, 0xdd, 0x84, 0xb3, 0x18, 0x90, 0x08, 0xd0, + 0x3d, 0xdc, 0x65, 0xf0, 0xd3, 0xf3, 0x6e, 0x80, 0x57, 0x85, 0xcf, 0x90, + 0x7e, 0xce, 0xf9, 0xa0, 0xe1, 0x12, 0x80, 0x06, 0x70, 0xce, 0xb1, 0x6c, + 0xae, 0x94, 0xf1, 0xe4, 0x86, 0x9c, 0x28, 0x94, 0xca, 0x62, 0xfb, 0x08, + 0x3d, 0x68, 0x4d, 0x10, 0xd8, 0xfc, 0x2b, 0x4c, 0xcc, 0x34, 0xb9, 0x16, + 0x85, 0x99, 0xb8, 0x20, 0xac, 0xee, 0x1b, 0x45, 0xfe, 0x9b, 0x5c, 0xeb, + 0x04, 0x5b, 0xa7, 0x69, 0x20, 0xb1, 0xb7, 0xbb, 0xc7, 0x54, 0xe5, 0x58, + 0x4f, 0x20, 0xf5, 0x47, 0x78, 0x45, 0xce, 0x95, 0xf6, 0x76, 0xef, 0x19, + 0xa6, 0x6e, 0x97, 0x20, 0x50, 0x5b, 0x05, 0xd3, 0xbb, 0xee, 0x67, 0xe6, + 0x03, 0x70, 0x8f, 0x57, 0x35, 0x02, 0xf8, 0x16, 0x2b, 0x6f, 0xe8, 0xe4, + 0x84, 0x34, 0x95, 0x7b, 0xf8, 0xaa, 0xa6, 0x88, 0xa3, 0x69, 0x38, 0xa4, + 0x1b, 0x65, 0x64, 0x71, 0xc9, 0xc4, 0x55, 0x29, 0x35, 0x4a, 0xb6, 0x8b, + 0xf1, 0x98, 0x00, 0x9d, 0x31, 0x38, 0xbe, 0x2e, 0xf3, 0xc1, 0x42, 0x1c, + 0x4a, 0xf3, 0x22, 0x47, 0xac, 0x7a, 0xab, 0x49, 0x62, 0xe9, 0x12, 0xd6, + 0x57, 0xc2, 0xbd, 0x21, 0x80, 0x3d, 0x02, 0xf5, 0xb6, 0xf9, 0x9b, 0xee, + 0x98, 0xda, 0xe7, 0x97, 0xb9, 0x96, 0x7b, 0x5a, 0x67, 0xff, 0x9a, 0xef, + 0xac, 0x79, 0x71, 0xee, 0x34, 0x2e, 0x4e, 0xe1, 0xce, 0x2b, 0x36, 0x79, + 0xaf, 0xcb, 0xfd, 0x5d, 0xef, 0xc9, 0xbe, 0x02, 0x0f, 0xdb, 0x8a, 0x0e, + 0xbf, 0x8f, 0x6f, 0x87, 0xcb, 0xcb, 0x30, 0xfd, 0xc4, 0x86, 0x00, 0xcf, + 0x5f, 0xef, 0xb1, 0xe7, 0x91, 0x43, 0x15, 0xa5, 0x54, 0xab, 0x2a, 0xae, + 0x9b, 0x11, 0x6a, 0xdd, 0xd7, 0xcc, 0xe2, 0xe8, 0x25, 0xe2, 0x89, 0x37, + 0xf9, 0x28, 0xc3, 0x96, 0x9d, 0x69, 0xa4, 0x61, 0x17, 0xa1, 0x2c, 0x70, + 0xf2, 0x8f, 0x3e, 0xde, 0xfd, 0xfa, 0xf1, 0x56, 0x33, 0xdd, 0x01, 0x87, + 0x9e, 0xdc, 0xe3, 0x79, 0xfe, 0x88, 0x00, 0x03, 0x6a, 0x6e, 0xf5, 0x42, + 0xeb, 0x13, 0xc2, 0x2d, 0x05, 0xd2, 0x64, 0x92, 0x0f, 0xd4, 0x67, 0x3f, + 0x58, 0xe4, 0x13, 0x02, 0x1b, 0x51, 0x3b, 0x05, 0xd9, 0x28, 0x3c, 0x4b, + 0xb1, 0xe2, 0x4c, 0xc1, 0x21, 0x12, 0x3c, 0x22, 0xe6, 0xe5, 0xe7, 0x8e, + 0xf6, 0xbb, 0xf8, 0x5b, 0x3d, 0xa9, 0xae, 0x77, 0xc3, 0x6f, 0x88, 0x1a, + 0xef, 0xa3, 0xd4, 0xf9, 0xc3, 0xbd, 0x68, 0xd3, 0x71, 0x06, 0xf8, 0xa0, + 0xd4, 0xc0, 0x84, 0xbf, 0xf6, 0x74, 0xc7, 0xf7, 0x75, 0xc7, 0xf7, 0x7f, + 0xc3, 0x8e, 0xef, 0x7f, 0xca, 0x8e, 0xef, 0x7f, 0xf4, 0x8e, 0x7f, 0xfd, + 0xe8, 0xf1, 0x93, 0xb6, 0x1d, 0xdf, 0xff, 0xbc, 0x3b, 0xbe, 0x7f, 0xef, + 0x8e, 0xef, 0xff, 0xbb, 0x76, 0x7c, 0xef, 0x0b, 0xec, 0xb8, 0xa6, 0xdc, + 0x3c, 0x45, 0x3e, 0xf0, 0x9d, 0xc2, 0x2e, 0x48, 0xd6, 0x12, 0x62, 0xe1, + 0x20, 0x30, 0x94, 0xe0, 0x28, 0xca, 0xa3, 0x1a, 0xe3, 0xe5, 0x02, 0x96, + 0xa5, 0xf2, 0x07, 0x99, 0x20, 0x5d, 0x01, 0xb5, 0x66, 0x15, 0xd1, 0x34, + 0x99, 0x4f, 0x90, 0x11, 0x6e, 0xf4, 0x36, 0xd4, 0xc3, 0xa9, 0x76, 0x4b, + 0xc5, 0x9f, 0xe2, 0x6e, 0x8a, 0x45, 0xfd, 0x6f, 0x28, 0xb1, 0x6d, 0x93, + 0xbf, 0x27, 0x19, 0xdc, 0xcc, 0xcd, 0x1f, 0x9f, 0x0c, 0xce, 0xed, 0x4b, + 0xde, 0x66, 0xfd, 0xa1, 0xfe, 0xa8, 0x8c, 0x28, 0x75, 0x59, 0x69, 0xa6, + 0x95, 0x6e, 0xd8, 0x2d, 0x5c, 0x8a, 0x92, 0xa4, 0x12, 0x65, 0x82, 0x5b, + 0xe9, 0x47, 0x9d, 0xeb, 0x00, 0xcb, 0xbc, 0x8c, 0x8b, 0x19, 0xa6, 0x88, + 0xdd, 0x4e, 0x08, 0x1a, 0x11, 0xa1, 0xc2, 0x4b, 0xc6, 0x53, 0x64, 0x3f, + 0x5f, 0x94, 0x8c, 0xda, 0xc8, 0x68, 0xeb, 0x4b, 0x28, 0x18, 0x5e, 0x55, + 0xbe, 0x57, 0xda, 0x25, 0x20, 0x4d, 0x86, 0x59, 0x9c, 0x52, 0xe5, 0x42, + 0x2b, 0x09, 0x8f, 0xcf, 0x29, 0x2c, 0x97, 0x1d, 0x0c, 0x74, 0xb7, 0x48, + 0xa3, 0x5a, 0xe9, 0x47, 0x75, 0x62, 0x1b, 0x64, 0x25, 0x08, 0x2d, 0x72, + 0xf7, 0x4b, 0x61, 0x50, 0xf5, 0x8d, 0x6b, 0x86, 0x53, 0xa1, 0xe5, 0x01, + 0x68, 0x7b, 0xb5, 0xb6, 0x25, 0x4a, 0x08, 0x04, 0xa4, 0x08, 0x42, 0xac, + 0x88, 0xf6, 0xda, 0xd0, 0x30, 0x9d, 0x8b, 0xa1, 0xe9, 0x4b, 0x91, 0x54, + 0x4b, 0xe6, 0x72, 0x73, 0x9f, 0xda, 0x4b, 0xd0, 0x7c, 0x82, 0x9a, 0xed, + 0x1b, 0xbd, 0x8f, 0xf6, 0x7c, 0xff, 0xbd, 0x93, 0xf5, 0x44, 0x84, 0xc7, + 0x4d, 0x14, 0x27, 0xaa, 0x1e, 0xc1, 0x84, 0xd8, 0x48, 0xd9, 0xec, 0xe1, + 0x16, 0x52, 0x76, 0x9e, 0x3a, 0x78, 0x22, 0x5a, 0xa2, 0xa4, 0x73, 0xd1, + 0xcd, 0x6b, 0x54, 0x11, 0x26, 0xc1, 0xe9, 0x9d, 0xb2, 0x6d, 0x12, 0xa1, + 0x9c, 0x8e, 0x8f, 0x2e, 0x96, 0xd1, 0x53, 0xa2, 0xc2, 0xd7, 0x32, 0x03, + 0xf6, 0x68, 0x87, 0x57, 0xe2, 0x24, 0xe9, 0xfe, 0xd2, 0xb6, 0x22, 0x6e, + 0x6a, 0x2d, 0xe5, 0x1a, 0x1d, 0x2e, 0x99, 0xac, 0xe5, 0x68, 0x31, 0x9d, + 0x6b, 0x99, 0xf1, 0x84, 0x93, 0xbc, 0x7d, 0xca, 0xac, 0x94, 0xef, 0x4b, + 0xcb, 0x2c, 0x40, 0x57, 0xe0, 0x03, 0x21, 0x86, 0x89, 0x82, 0x04, 0x2c, + 0x8f, 0x78, 0x16, 0xe7, 0x67, 0x9f, 0xd4, 0x71, 0x55, 0x5e, 0xa4, 0xda, + 0x51, 0x36, 0x58, 0x5c, 0x2a, 0xdb, 0xaf, 0x1c, 0x4a, 0xb2, 0x28, 0x0c, + 0x7a, 0xe8, 0xa5, 0xc0, 0x19, 0x96, 0xb8, 0x94, 0x24, 0x41, 0x8e, 0xa7, + 0xa8, 0xd0, 0xec, 0x59, 0xc1, 0xe9, 0x5e, 0x11, 0x6d, 0xb7, 0x62, 0x33, + 0xd6, 0x16, 0x59, 0xef, 0x85, 0x13, 0x5b, 0xd5, 0xc3, 0x3d, 0x64, 0xb8, + 0x6a, 0x5c, 0x8d, 0x15, 0xef, 0x7d, 0x90, 0x1d, 0xfe, 0x88, 0x88, 0x1e, + 0xb7, 0x89, 0xcd, 0xe4, 0x7a, 0x0f, 0x94, 0xc0, 0xd4, 0x67, 0x64, 0x5b, + 0x0f, 0xe7, 0xbd, 0x31, 0x70, 0xf4, 0x62, 0xae, 0x15, 0x43, 0x85, 0x7f, + 0xea, 0x71, 0xbe, 0x38, 0x3a, 0x4b, 0x9e, 0x13, 0x00, 0x08, 0xea, 0xd2, + 0xc9, 0x26, 0x8a, 0x1b, 0x5f, 0x3f, 0xdc, 0xdd, 0x27, 0x08, 0x29, 0xfd, + 0x8e, 0xbe, 0x92, 0x34, 0x4c, 0xf8, 0xd0, 0xce, 0x31, 0xd7, 0x45, 0xd4, + 0xda, 0x8a, 0x14, 0x19, 0x47, 0x09, 0xc5, 0x40, 0x41, 0x08, 0xf3, 0x4f, + 0x3c, 0x2c, 0x4b, 0x4b, 0x50, 0x7b, 0x4b, 0x8a, 0x98, 0x69, 0xda, 0x16, + 0x44, 0xcc, 0x71, 0x75, 0xb8, 0x31, 0x5d, 0x34, 0x9d, 0x38, 0xcd, 0x34, + 0x39, 0x3c, 0xfa, 0xe3, 0x96, 0x41, 0x02, 0xaa, 0x7d, 0x93, 0x20, 0xd7, + 0xc5, 0x93, 0x83, 0xd5, 0x66, 0x14, 0x32, 0x32, 0xc4, 0xa3, 0x66, 0x23, + 0x27, 0xbe, 0xc5, 0x76, 0x25, 0xbf, 0x26, 0x4d, 0x8a, 0x89, 0xab, 0x4c, + 0xaf, 0xcb, 0xa9, 0x7c, 0x8b, 0x77, 0x53, 0x48, 0xd4, 0xf7, 0x5a, 0xfb, + 0x3e, 0x86, 0x7f, 0xb3, 0x1e, 0x01, 0x6d, 0x46, 0xbb, 0x3a, 0x2b, 0x08, + 0xdd, 0x4a, 0xb8, 0x3c, 0xa2, 0x31, 0x6a, 0xb9, 0x52, 0xd8, 0xa1, 0x77, + 0xaf, 0x4f, 0x9f, 0x1d, 0xbf, 0x3c, 0xfc, 0x6b, 0xf0, 0xa6, 0x52, 0xda, + 0x27, 0x2d, 0x21, 0x16, 0xbb, 0xcc, 0xd2, 0xea, 0xf6, 0x1d, 0x5c, 0xf2, + 0xf0, 0xed, 0xe6, 0xfe, 0x16, 0x7a, 0xc3, 0x66, 0x5a, 0x3f, 0xf3, 0x32, + 0x8b, 0x8b, 0x2f, 0x31, 0x04, 0xb2, 0x2b, 0x61, 0xe4, 0x11, 0x79, 0xa5, + 0x3a, 0x67, 0xe0, 0x45, 0x83, 0x00, 0x19, 0x89, 0x7b, 0x74, 0xeb, 0x8a, + 0xf4, 0x98, 0xa5, 0x05, 0xe1, 0x2e, 0xe9, 0x42, 0x15, 0x79, 0xb0, 0x26, + 0x98, 0x54, 0x31, 0xa6, 0x08, 0x37, 0x64, 0xac, 0x42, 0xfc, 0x6a, 0xb6, + 0xbc, 0x79, 0x32, 0xf5, 0xcf, 0x93, 0xdb, 0xed, 0x1a, 0xbc, 0x7f, 0xeb, + 0xb4, 0xe7, 0x75, 0xd1, 0x31, 0x06, 0x8b, 0xf1, 0x38, 0x24, 0xcd, 0xd6, + 0x78, 0x70, 0xeb, 0x6c, 0x32, 0xcb, 0x6a, 0x41, 0xbb, 0x49, 0x9e, 0xc2, + 0xbf, 0xdf, 0x82, 0x90, 0xa5, 0x95, 0x2a, 0xd2, 0x4a, 0x97, 0xb2, 0x0a, + 0x02, 0x0a, 0xbe, 0x60, 0x7c, 0xb8, 0xaf, 0xf0, 0xe8, 0xd9, 0xc8, 0x9e, + 0x04, 0xd6, 0x7d, 0xa0, 0xf7, 0xfd, 0xc5, 0x5f, 0xcf, 0x8e, 0xbf, 0x7d, + 0x8a, 0x02, 0xc8, 0x77, 0x54, 0xe7, 0x46, 0xeb, 0xa7, 0x06, 0x91, 0xe4, + 0x76, 0x6e, 0xa6, 0xcf, 0xbf, 0x3c, 0x3b, 0x39, 0x3f, 0x7b, 0x79, 0x7a, + 0xf4, 0xed, 0xd3, 0xbf, 0xa0, 0x75, 0x01, 0x24, 0xd6, 0xdb, 0xf8, 0x2d, + 0xfb, 0x38, 0xd1, 0xda, 0x46, 0xfa, 0xea, 0xeb, 0xe3, 0x9f, 0xde, 0x1d, + 0xbf, 0xfe, 0xf3, 0xb7, 0x4f, 0xaf, 0xd3, 0xb2, 0x4b, 0x33, 0xd0, 0xf7, + 0x10, 0x55, 0x65, 0x76, 0x9d, 0x97, 0xc5, 0x0c, 0xfd, 0x57, 0x20, 0x42, + 0x96, 0x39, 0x2e, 0x7e, 0x08, 0x2f, 0x8b, 0x97, 0xc0, 0xc7, 0x98, 0xfd, + 0x06, 0xac, 0xf6, 0x5a, 0xa6, 0x7e, 0x5d, 0xef, 0xee, 0xec, 0xc8, 0xa2, + 0xdd, 0xeb, 0x8d, 0x04, 0x66, 0x31, 0xce, 0x2f, 0xc3, 0xb9, 0x42, 0x43, + 0xd6, 0x60, 0xf2, 0xbe, 0xca, 0xff, 0x91, 0x25, 0x4f, 0x49, 0xf6, 0xd5, + 0x6a, 0x37, 0x17, 0x84, 0x5a, 0xa2, 0x50, 0x3b, 0x17, 0x84, 0x44, 0xfe, + 0xc3, 0xcb, 0x3f, 0x9e, 0x9f, 0xfc, 0xf7, 0xb1, 0xd2, 0xfe, 0x26, 0x95, + 0xef, 0xc4, 0xb9, 0x3c, 0xda, 0xdd, 0xc3, 0xbb, 0x6c, 0x82, 0xd5, 0x4e, + 0xca, 0xad, 0x48, 0xd4, 0x13, 0xbc, 0xe4, 0x01, 0x2c, 0xe7, 0xfb, 0x84, + 0xfa, 0x09, 0x99, 0xf6, 0x56, 0x1e, 0xc0, 0x8a, 0xb7, 0xa9, 0x25, 0x8f, + 0x81, 0xb8, 0x84, 0xb7, 0x8a, 0xa4, 0x50, 0x3a, 0xe0, 0x5b, 0x1e, 0x8f, + 0x85, 0xbd, 0xfe, 0xe0, 0x11, 0x95, 0x71, 0x30, 0x12, 0xd9, 0xc3, 0x38, + 0xb4, 0x0c, 0xee, 0xe7, 0xa2, 0xa3, 0xa2, 0x69, 0xb7, 0x16, 0x2f, 0x12, + 0x05, 0x21, 0x86, 0x8b, 0xfa, 0xf8, 0xe8, 0xa8, 0xa8, 0xa3, 0xdd, 0x9d, + 0xbd, 0x87, 0x49, 0xdd, 0x5e, 0x00, 0x74, 0x79, 0xa7, 0xe8, 0x55, 0x38, + 0x51, 0x4d, 0x94, 0xa8, 0xc6, 0xe7, 0xd1, 0x6e, 0x89, 0x97, 0x18, 0x05, + 0x78, 0x34, 0xf6, 0xd2, 0x22, 0xe9, 0x91, 0xd1, 0x62, 0x2d, 0xa2, 0xa1, + 0xe6, 0x53, 0x9c, 0x74, 0x56, 0x25, 0xea, 0xb1, 0x75, 0x06, 0x47, 0x2e, + 0x24, 0x3f, 0xc9, 0x2e, 0xc9, 0x05, 0xc5, 0x8b, 0x5c, 0x59, 0xe5, 0x20, + 0xc9, 0xe8, 0x01, 0x59, 0x7c, 0x56, 0xdc, 0x10, 0x06, 0x36, 0xef, 0x0d, + 0xd7, 0x35, 0x33, 0xc4, 0x45, 0x75, 0xe7, 0x46, 0xa3, 0x10, 0x50, 0xd9, + 0xba, 0x05, 0xad, 0xb3, 0xb1, 0x58, 0xb6, 0xc8, 0x62, 0x5c, 0x68, 0x30, + 0xc5, 0x78, 0x11, 0xee, 0xa9, 0x01, 0xb9, 0x36, 0x7e, 0xd0, 0xf2, 0x9a, + 0xdf, 0xb7, 0xb7, 0x6e, 0x0c, 0xb2, 0xb3, 0xbb, 0xdf, 0xec, 0xf5, 0x77, + 0x1f, 0x3f, 0xc1, 0x5a, 0x09, 0xdb, 0x2b, 0x76, 0x55, 0xe6, 0xa8, 0x5b, + 0xfa, 0x8f, 0xae, 0xaf, 0x14, 0x9a, 0x3c, 0xc5, 0x5f, 0xbf, 0x5b, 0xc2, + 0x0f, 0x7a, 0xa3, 0x62, 0x34, 0xd7, 0x03, 0x17, 0x45, 0xcb, 0xf0, 0xd3, + 0x30, 0xda, 0x9e, 0xd5, 0x18, 0xf6, 0x72, 0x6b, 0x14, 0xa3, 0x5c, 0x15, + 0x1e, 0x75, 0x90, 0x54, 0x21, 0x78, 0x88, 0x00, 0xd6, 0x08, 0x2d, 0x7e, + 0x65, 0x5b, 0x01, 0xcf, 0x51, 0x63, 0x94, 0x19, 0x6f, 0xf0, 0x82, 0x91, + 0x54, 0x10, 0xa4, 0x9b, 0xe4, 0x3f, 0xb2, 0xbd, 0x0a, 0x5f, 0x4b, 0xad, + 0xe0, 0x1f, 0xca, 0x5b, 0xf4, 0x14, 0x57, 0x82, 0xaa, 0xa8, 0xbf, 0x7c, + 0x6c, 0xb7, 0xa0, 0xe9, 0x63, 0xa0, 0xd7, 0x92, 0xa8, 0x0c, 0x92, 0x30, + 0x51, 0x23, 0x72, 0x6d, 0x18, 0x57, 0x65, 0xc9, 0xce, 0x75, 0x99, 0x51, + 0xe9, 0xc2, 0x34, 0x02, 0xc6, 0x70, 0x25, 0x9f, 0x22, 0x6e, 0x72, 0x29, + 0x4c, 0x8b, 0xa7, 0x21, 0xa6, 0x61, 0x1a, 0xc8, 0xe6, 0x14, 0xc7, 0xbf, + 0x25, 0x7c, 0x84, 0xcb, 0x18, 0x1b, 0xa6, 0x87, 0x99, 0x38, 0x62, 0xd1, + 0x01, 0x5a, 0xc3, 0x77, 0x55, 0x6c, 0x60, 0x91, 0x41, 0x4a, 0x29, 0x51, + 0xa3, 0x6e, 0x11, 0xb4, 0xe0, 0x43, 0xed, 0xa1, 0xb4, 0xa8, 0xd6, 0xb7, + 0x82, 0xcf, 0x44, 0x4b, 0x26, 0xa0, 0xa8, 0x23, 0xac, 0xd3, 0xb5, 0xd9, + 0xdb, 0xb2, 0xea, 0x32, 0x79, 0x1d, 0xb4, 0x26, 0x72, 0x64, 0xc7, 0xd8, + 0x4d, 0xa1, 0x06, 0x2f, 0x47, 0x50, 0x84, 0xcd, 0x96, 0x7d, 0xa6, 0x8e, + 0xb6, 0x39, 0x9e, 0xd2, 0xd8, 0x62, 0x1e, 0xe0, 0x74, 0xe3, 0x86, 0x50, + 0x09, 0xcf, 0x6e, 0x02, 0x4a, 0xa5, 0xd7, 0x89, 0xad, 0x21, 0x87, 0x4c, + 0x18, 0xca, 0xea, 0x50, 0x04, 0x97, 0x21, 0x76, 0x30, 0x00, 0x38, 0x6d, + 0x85, 0x22, 0xee, 0xa4, 0x20, 0xd6, 0x50, 0x28, 0x9c, 0x88, 0x55, 0x8e, + 0x90, 0xc6, 0xe9, 0x50, 0x2a, 0xf9, 0x94, 0x05, 0x46, 0x16, 0xd1, 0xce, + 0x8d, 0x8a, 0x06, 0x12, 0xb6, 0x15, 0x06, 0x63, 0xda, 0x35, 0xd4, 0xe0, + 0x98, 0x9d, 0xdb, 0xd9, 0xf9, 0x1c, 0xb5, 0x09, 0x1a, 0xe5, 0xe7, 0xfe, + 0x91, 0x74, 0x7e, 0x82, 0xd6, 0x76, 0x76, 0x81, 0x2c, 0xe6, 0xc9, 0xde, + 0xce, 0xde, 0x6e, 0xb2, 0xbb, 0x77, 0xb0, 0xfb, 0xe4, 0x60, 0x67, 0xe7, + 0xfe, 0x82, 0x74, 0xf0, 0x72, 0xef, 0xb7, 0xbc, 0x7d, 0x0f, 0xe2, 0x89, + 0x63, 0x2c, 0x40, 0x72, 0x97, 0x3d, 0x02, 0xc2, 0xb7, 0xf0, 0xa2, 0xb8, + 0xde, 0xb1, 0x19, 0x10, 0x31, 0x9c, 0x36, 0x79, 0xfa, 0xe7, 0xe3, 0x37, + 0xe7, 0x27, 0xa7, 0xaf, 0xbf, 0xf3, 0x4e, 0x1d, 0xf9, 0x0c, 0x49, 0x06, + 0x64, 0x0f, 0xe4, 0xaa, 0x02, 0x3a, 0x1a, 0xdc, 0x90, 0xe4, 0x65, 0xb5, + 0x18, 0x2c, 0xaa, 0x9a, 0x05, 0x42, 0x16, 0x3e, 0x24, 0x87, 0x71, 0x38, + 0xcc, 0xe6, 0x35, 0xf1, 0x57, 0x45, 0x16, 0xcb, 0x43, 0xdd, 0x25, 0xb2, + 0x5e, 0xee, 0x74, 0xe5, 0x97, 0x5d, 0xfd, 0x85, 0x64, 0x07, 0xfe, 0x75, + 0xbf, 0x81, 0x80, 0xe9, 0xe3, 0x02, 0x2b, 0x86, 0x89, 0x35, 0x9a, 0x20, + 0xc7, 0xa1, 0xbf, 0x4a, 0x5a, 0x4b, 0x07, 0xf3, 0x6d, 0xa7, 0x15, 0xe3, + 0xfe, 0xf4, 0xf6, 0xe4, 0xa8, 0xc7, 0x3e, 0x7a, 0xe2, 0xad, 0xdb, 0x70, + 0xaa, 0x2d, 0x7e, 0x56, 0xfb, 0x56, 0x0c, 0x62, 0x90, 0xef, 0x28, 0x7f, + 0x73, 0xce, 0x18, 0xe2, 0x28, 0x98, 0x71, 0xcd, 0x05, 0x17, 0x42, 0xa4, + 0xef, 0xc0, 0xbc, 0xe2, 0xe7, 0xe1, 0x19, 0x9c, 0x6c, 0xf8, 0x7e, 0xb7, + 0xed, 0xfb, 0xdd, 0xf0, 0xfd, 0x5e, 0xdb, 0xf7, 0x7b, 0xe1, 0xfb, 0xfd, + 0xb6, 0xef, 0xf7, 0xa3, 0x82, 0x8c, 0xba, 0xbb, 0x5f, 0xb6, 0x20, 0xa3, + 0x75, 0x83, 0x3b, 0x77, 0x1f, 0x0d, 0xbb, 0x87, 0xf7, 0x83, 0x01, 0xfb, + 0x4e, 0xb3, 0xbb, 0xbe, 0xb1, 0xd2, 0xf0, 0xbe, 0xc2, 0xf2, 0x6e, 0x65, + 0x58, 0x62, 0x6b, 0xf9, 0x4e, 0x37, 0x58, 0xd3, 0xbb, 0x6e, 0x08, 0x52, + 0xa1, 0xdb, 0xc8, 0xce, 0xde, 0xd9, 0xdd, 0xd7, 0xc8, 0xbc, 0xe4, 0x29, + 0xba, 0x11, 0xa3, 0x33, 0x12, 0xca, 0x68, 0xb2, 0x15, 0x89, 0x9f, 0x84, + 0x81, 0x90, 0x21, 0xdd, 0x4a, 0x71, 0x2e, 0x85, 0x32, 0x38, 0x9c, 0x45, + 0xcb, 0xff, 0xe3, 0xa8, 0x35, 0xec, 0x9d, 0x4e, 0x12, 0xf6, 0x45, 0x77, + 0xa6, 0xf6, 0x2e, 0x8d, 0x92, 0x94, 0x6d, 0x09, 0xeb, 0xb0, 0x5d, 0x0a, + 0xee, 0xaa, 0xf1, 0x83, 0x09, 0x55, 0x17, 0x06, 0xb2, 0x80, 0x8e, 0xa4, + 0xc5, 0x68, 0x5c, 0xa6, 0xdb, 0x16, 0x22, 0x7a, 0xbd, 0x7d, 0xf3, 0x52, + 0xd5, 0x27, 0xdd, 0x08, 0x5c, 0xdb, 0x7e, 0x95, 0x6d, 0xc3, 0xd5, 0x50, + 0x6d, 0x53, 0x10, 0xad, 0x34, 0x7e, 0x55, 0x4f, 0x27, 0x2b, 0xf2, 0xeb, + 0xd9, 0xe4, 0x16, 0x6a, 0xba, 0x46, 0x5b, 0x43, 0x61, 0xc6, 0x68, 0x47, + 0xc1, 0x38, 0x19, 0x24, 0xf4, 0xdd, 0x80, 0x55, 0x45, 0x22, 0x4a, 0x37, + 0x51, 0x1f, 0x72, 0x37, 0xb9, 0x29, 0x26, 0x63, 0x78, 0x8e, 0x24, 0x92, + 0xe9, 0x20, 0x1b, 0xe1, 0x2c, 0xf6, 0xfb, 0x8f, 0xfb, 0x3b, 0xac, 0x55, + 0xd4, 0x01, 0x64, 0xef, 0x07, 0x96, 0x48, 0xa8, 0x3f, 0xc6, 0x78, 0xe2, + 0x5b, 0x54, 0xdf, 0xc2, 0x17, 0xac, 0xb5, 0xc6, 0x62, 0xc8, 0x82, 0x5a, + 0xa9, 0xf4, 0x32, 0xe3, 0x13, 0xe0, 0x03, 0xf9, 0xb2, 0x10, 0x97, 0x19, + 0x6c, 0x09, 0x1c, 0xc9, 0x1e, 0x93, 0xc6, 0x17, 0xcb, 0x8c, 0x89, 0xbb, + 0x81, 0x29, 0xbc, 0x3b, 0x3c, 0x3e, 0x7f, 0xb7, 0xbb, 0xf7, 0xe4, 0xdd, + 0x8f, 0x47, 0xaf, 0xde, 0x9d, 0xbf, 0x38, 0xdc, 0x7b, 0xf4, 0x78, 0x1d, + 0x73, 0xaf, 0xd9, 0x7b, 0xc3, 0x35, 0x11, 0xe6, 0xd6, 0xb5, 0x64, 0xa5, + 0xe6, 0xb4, 0x9c, 0xb7, 0x09, 0x06, 0x74, 0x9d, 0x55, 0xfe, 0x68, 0x60, + 0x6c, 0x1b, 0x61, 0x4d, 0x3d, 0xc5, 0x9f, 0xf1, 0xc1, 0xc8, 0x38, 0xa2, + 0xa4, 0x19, 0xff, 0x46, 0xda, 0x37, 0xe2, 0xf2, 0x95, 0x54, 0x62, 0x4d, + 0x74, 0x2a, 0xae, 0x4d, 0x67, 0xf7, 0x4a, 0x94, 0x86, 0x4a, 0x74, 0xd4, + 0x39, 0x7f, 0x73, 0xd6, 0xe9, 0x8a, 0xaf, 0x1f, 0xda, 0xed, 0xc1, 0xdf, + 0x09, 0x5b, 0xeb, 0x92, 0x47, 0x3b, 0x8f, 0x1e, 0x6e, 0x59, 0x82, 0x01, + 0x0c, 0x8b, 0xa0, 0x84, 0x9b, 0x8e, 0xb2, 0x90, 0x1d, 0x5f, 0x46, 0x49, + 0x7e, 0x94, 0x2a, 0x1b, 0xcf, 0x46, 0xa0, 0x76, 0xba, 0x92, 0x4c, 0xb5, + 0x54, 0xb0, 0xc7, 0x97, 0xf4, 0xa6, 0x81, 0xc5, 0x05, 0x07, 0x30, 0x86, + 0x44, 0xca, 0xed, 0x69, 0xc8, 0xc9, 0x02, 0xee, 0x09, 0xd0, 0x85, 0xfe, + 0xff, 0xed, 0x7d, 0x6b, 0x53, 0x1b, 0x49, 0xb6, 0xed, 0x67, 0xf8, 0x15, + 0x35, 0x8a, 0xeb, 0x30, 0x9c, 0x91, 0x64, 0x8c, 0xdf, 0xbe, 0x9e, 0x9e, + 0xc1, 0x40, 0x77, 0x73, 0x06, 0x03, 0x63, 0x61, 0x77, 0xcf, 0x9d, 0x9e, + 0x20, 0x0a, 0x28, 0x40, 0x63, 0x21, 0x31, 0x2a, 0xc9, 0x98, 0xee, 0x98, + 0xfb, 0xdb, 0x6f, 0xae, 0xb5, 0x1f, 0x99, 0x59, 0x12, 0x18, 0x77, 0xe3, + 0x73, 0x26, 0xe2, 0x9e, 0x2f, 0x3c, 0xa4, 0xaa, 0x7c, 0xee, 0xdc, 0xb9, + 0x9f, 0x6b, 0xbb, 0x09, 0x77, 0xc6, 0x6d, 0x28, 0x54, 0x6b, 0x13, 0xd3, + 0x85, 0xf0, 0xf2, 0x29, 0xce, 0xfa, 0xec, 0x00, 0xf9, 0xd1, 0xf9, 0x6e, + 0x38, 0xc5, 0x2a, 0xcf, 0x7b, 0xbb, 0x1b, 0x6f, 0x81, 0x74, 0x66, 0x5f, + 0x27, 0xe1, 0x22, 0xed, 0x04, 0x63, 0xb8, 0x95, 0x90, 0xa2, 0x5b, 0x95, + 0x52, 0x94, 0xef, 0xd2, 0x2b, 0x51, 0x12, 0x66, 0x68, 0xaa, 0x88, 0xb9, + 0xea, 0x5e, 0xe6, 0x5d, 0x01, 0x3b, 0x25, 0xb4, 0x67, 0x36, 0x87, 0x5d, + 0xaa, 0x47, 0x37, 0x80, 0x93, 0x4c, 0xcd, 0x4b, 0x06, 0xde, 0xb5, 0x30, + 0x34, 0xbd, 0x62, 0x22, 0x2d, 0x89, 0xcc, 0x72, 0x2b, 0x50, 0x0b, 0xdf, + 0x8a, 0x42, 0x38, 0x79, 0xa4, 0xca, 0x38, 0xf0, 0xaf, 0xc8, 0x2a, 0xbc, + 0x93, 0x8b, 0xcb, 0xe3, 0x64, 0x02, 0x02, 0xae, 0xfd, 0x2b, 0xf7, 0x84, + 0x2f, 0xa7, 0xb9, 0xc8, 0xc9, 0x6e, 0x18, 0x84, 0x80, 0x9c, 0x4c, 0x32, + 0xf9, 0xb8, 0x1d, 0x77, 0xb5, 0x1b, 0xc9, 0x76, 0xc4, 0x53, 0x4c, 0x06, + 0x96, 0xa4, 0xca, 0xcd, 0xdb, 0x9d, 0x58, 0xa8, 0x3d, 0x02, 0x8e, 0xc4, + 0xad, 0xb1, 0xd3, 0x61, 0x5b, 0xfc, 0x75, 0x90, 0x87, 0xee, 0x68, 0x53, + 0xac, 0x0d, 0xdb, 0x98, 0x28, 0xbb, 0xa4, 0x7b, 0xc2, 0x6a, 0xd4, 0x13, + 0x94, 0x7c, 0xae, 0x27, 0x99, 0x70, 0x1e, 0x66, 0xfc, 0x49, 0xee, 0x66, + 0x4f, 0xe7, 0xb0, 0x8a, 0x94, 0xa5, 0x94, 0x95, 0xb2, 0x48, 0x69, 0x89, + 0x6c, 0x17, 0x43, 0x1a, 0x13, 0x35, 0xa4, 0x26, 0x61, 0x22, 0xe3, 0x32, + 0xae, 0x3e, 0xec, 0xf6, 0x59, 0xff, 0x14, 0xd7, 0x68, 0xe6, 0x08, 0x4d, + 0x46, 0x34, 0x1f, 0xc2, 0x39, 0xb3, 0x4b, 0x7f, 0x6e, 0xe1, 0x3e, 0x3e, + 0xfc, 0x9c, 0x64, 0x18, 0x9e, 0xb8, 0x8b, 0x80, 0x8c, 0xd9, 0x94, 0xe4, + 0x84, 0x22, 0x6f, 0x96, 0x14, 0x67, 0xf3, 0x8e, 0x6e, 0x8a, 0xc0, 0x50, + 0x19, 0x34, 0xdd, 0xb3, 0x6f, 0x01, 0xc8, 0x51, 0x7b, 0x68, 0x0d, 0xcf, + 0xd0, 0x9c, 0xd5, 0x16, 0x3b, 0xce, 0x65, 0x9a, 0xde, 0x1b, 0xeb, 0x32, + 0x23, 0xd3, 0x4b, 0x36, 0x31, 0xdd, 0xbf, 0x45, 0x2f, 0xbb, 0x03, 0xb7, + 0xbb, 0x25, 0x39, 0x50, 0xa4, 0x64, 0x67, 0x8d, 0xa4, 0x1d, 0x33, 0x03, + 0x18, 0x7a, 0x3f, 0x8b, 0x80, 0x1f, 0xe0, 0x1e, 0x3b, 0x88, 0xa4, 0x21, + 0x22, 0x04, 0x09, 0xa3, 0x38, 0xac, 0xce, 0xca, 0x8f, 0x00, 0x61, 0xe6, + 0xeb, 0xc0, 0x34, 0x1d, 0xd6, 0x41, 0x68, 0xa5, 0x87, 0x2a, 0xaf, 0x1f, + 0xd0, 0x08, 0xbc, 0x0c, 0x9b, 0x34, 0x2e, 0x51, 0x76, 0x47, 0x42, 0x0e, + 0x4c, 0xc2, 0xb7, 0x4a, 0xc7, 0x5e, 0xe8, 0x18, 0x47, 0xad, 0x74, 0xb5, + 0x33, 0x53, 0x36, 0x67, 0x2b, 0x2b, 0xe9, 0xd2, 0xde, 0x0d, 0xdd, 0x75, + 0x57, 0x6e, 0x7d, 0x32, 0x9b, 0xfa, 0x02, 0xc8, 0xe5, 0xcb, 0xf6, 0xf7, + 0xe1, 0xbf, 0xd5, 0xfe, 0x3e, 0xfc, 0xb7, 0xde, 0xdf, 0x87, 0x77, 0xb4, + 0xbf, 0x0f, 0xbf, 0x68, 0x7f, 0xe3, 0x99, 0xc7, 0x44, 0x1a, 0xbb, 0xbd, + 0xfa, 0x65, 0xbb, 0xbd, 0xfa, 0x6f, 0xb5, 0xdb, 0xab, 0xff, 0xd6, 0xbb, + 0xbd, 0x7a, 0x47, 0xbb, 0xbd, 0x7a, 0x77, 0xbb, 0xfd, 0xe8, 0xcb, 0x76, + 0xfb, 0xd1, 0x6f, 0xdc, 0xed, 0xff, 0x46, 0xbb, 0x57, 0xc4, 0xc1, 0x36, + 0xc5, 0xd9, 0x0b, 0xcf, 0xa4, 0x79, 0x08, 0x30, 0xf0, 0xe3, 0x01, 0xcd, + 0x29, 0xa8, 0xe7, 0xe5, 0x62, 0xda, 0xc2, 0xde, 0xcd, 0x6e, 0x3e, 0xfa, + 0x92, 0xdd, 0x5c, 0xbd, 0x6e, 0x37, 0xc7, 0x9d, 0x2a, 0xd0, 0x78, 0x1c, + 0x25, 0x17, 0x22, 0x3a, 0x56, 0x4a, 0x81, 0xdd, 0x82, 0x6d, 0x1e, 0x26, + 0x3e, 0x5d, 0x9c, 0xce, 0xa6, 0xbe, 0x93, 0x94, 0x6e, 0x50, 0x63, 0x41, + 0xd8, 0x14, 0xcb, 0x4f, 0xd1, 0xca, 0x3b, 0x56, 0xa0, 0xcc, 0x2a, 0x84, + 0x59, 0x18, 0x9c, 0xa6, 0x07, 0x4d, 0x87, 0xd6, 0x81, 0x96, 0x0d, 0x63, + 0x31, 0x4f, 0xd6, 0x91, 0xb2, 0x48, 0x76, 0xab, 0xd3, 0xda, 0x6f, 0xa4, + 0x06, 0x25, 0x83, 0xbf, 0xa3, 0x5a, 0x19, 0x49, 0x8b, 0x9f, 0xd9, 0x82, + 0xa4, 0xeb, 0x5b, 0x16, 0xff, 0xb6, 0x55, 0x4c, 0xd6, 0xbe, 0x04, 0xbc, + 0x51, 0x12, 0x86, 0xda, 0x2b, 0x11, 0x01, 0x5b, 0x4a, 0xb6, 0x0b, 0x33, + 0x38, 0x00, 0x70, 0x84, 0x98, 0x1f, 0xc1, 0xd7, 0x62, 0x01, 0x69, 0xa2, + 0xa6, 0x73, 0xca, 0x5c, 0xbf, 0x40, 0xfc, 0xa7, 0x23, 0x77, 0x0c, 0x7b, + 0x01, 0x77, 0x90, 0x38, 0x3e, 0x0d, 0x74, 0xce, 0x82, 0xb2, 0x10, 0xe6, + 0xfa, 0x43, 0x64, 0x6e, 0x24, 0xe5, 0x9a, 0x12, 0xe7, 0x88, 0x86, 0x9c, + 0x49, 0xf5, 0x53, 0xf0, 0x30, 0x2d, 0x68, 0xd1, 0x69, 0x31, 0x58, 0xcb, + 0x63, 0x5a, 0xc1, 0xc2, 0x10, 0x6b, 0xa3, 0xa5, 0x98, 0xe4, 0x2d, 0x86, + 0xf8, 0x24, 0x81, 0xac, 0x82, 0x23, 0xd4, 0xba, 0xd7, 0x8a, 0xf9, 0xf1, + 0x69, 0x03, 0xfe, 0x7e, 0xfa, 0xba, 0x47, 0xdb, 0xce, 0x1e, 0xbc, 0x18, + 0x27, 0x26, 0xcf, 0x63, 0x29, 0xa4, 0x9e, 0x6d, 0x60, 0x06, 0x1f, 0xfb, + 0x13, 0x96, 0xda, 0xc4, 0x62, 0x0c, 0xab, 0x89, 0xa8, 0x9f, 0x61, 0xe5, + 0x4e, 0x4e, 0x0c, 0x6e, 0x50, 0x72, 0xa7, 0x91, 0xff, 0x4e, 0x6c, 0x20, + 0x84, 0x2b, 0x71, 0x39, 0xb8, 0x5e, 0xe9, 0x5a, 0x99, 0x1a, 0x87, 0xda, + 0x1b, 0xe3, 0xea, 0x58, 0x4a, 0x1f, 0xd4, 0xd1, 0xcc, 0x50, 0x57, 0xe1, + 0x63, 0x2d, 0x37, 0x8b, 0xe6, 0x10, 0xa3, 0x0a, 0xe3, 0x5b, 0x51, 0x5e, + 0xd2, 0x9c, 0xc2, 0xfc, 0x57, 0x14, 0x9f, 0x47, 0xad, 0xc2, 0x81, 0x26, + 0x77, 0xa0, 0x54, 0x93, 0x98, 0xd1, 0xb0, 0x9b, 0x7a, 0x57, 0x8c, 0x4e, + 0xb5, 0x42, 0x2a, 0x4b, 0x84, 0xd4, 0xff, 0x25, 0x91, 0xbf, 0x4a, 0x4d, + 0x5f, 0xad, 0x0c, 0x94, 0xb4, 0x1f, 0xa6, 0xf6, 0x99, 0xa8, 0x5f, 0x51, + 0x3d, 0xdc, 0x74, 0x20, 0x08, 0x2e, 0x31, 0x14, 0x3c, 0x8d, 0x05, 0x8f, + 0xc1, 0xe0, 0x4e, 0x02, 0xb9, 0x41, 0x0b, 0x5d, 0x76, 0xca, 0xfa, 0xa8, + 0xdf, 0xcf, 0x22, 0x38, 0x93, 0xcf, 0xdb, 0xfe, 0xaf, 0x44, 0x79, 0xb4, + 0xe3, 0x7b, 0xfd, 0xe3, 0x3a, 0x3a, 0x4b, 0xed, 0xc3, 0xdc, 0x31, 0x14, + 0xdb, 0xf9, 0xff, 0xf1, 0x9c, 0x32, 0x5e, 0x22, 0x39, 0xa7, 0x33, 0x47, + 0x74, 0x5f, 0x91, 0x3c, 0xea, 0xfe, 0x79, 0x7f, 0x50, 0xb2, 0x0c, 0x4d, + 0x8c, 0xe3, 0x84, 0x49, 0x31, 0xa8, 0xe0, 0x08, 0xa7, 0x18, 0x19, 0x10, + 0xdf, 0x59, 0xf5, 0x49, 0xe0, 0x02, 0x65, 0x49, 0xbc, 0x14, 0x25, 0xe2, + 0x18, 0x95, 0xff, 0xaf, 0xf5, 0xd6, 0xb7, 0xb6, 0xe4, 0x21, 0x4b, 0x58, + 0xc4, 0xc2, 0x4a, 0x88, 0xa9, 0x94, 0x6e, 0x2a, 0xea, 0x73, 0x54, 0x91, + 0x19, 0x7b, 0x29, 0xe4, 0xe8, 0x40, 0x95, 0xb3, 0x1e, 0x8e, 0x46, 0xd0, + 0xfd, 0x11, 0x6f, 0x48, 0x1f, 0x55, 0x29, 0xe7, 0x63, 0x3a, 0x0c, 0x23, + 0xeb, 0x0f, 0x03, 0xdd, 0x9f, 0x4d, 0xcf, 0xcb, 0x61, 0xfd, 0x3f, 0x8c, + 0xe6, 0xee, 0xe3, 0xc1, 0xd5, 0xce, 0x97, 0x9c, 0x9b, 0x1b, 0x81, 0x96, + 0x62, 0x2c, 0xc6, 0xaf, 0x32, 0x2a, 0x25, 0xdd, 0xdc, 0x92, 0xef, 0x24, + 0xc1, 0xd2, 0xb3, 0xc6, 0x0e, 0xb7, 0x76, 0xf0, 0x3c, 0xe7, 0x11, 0xe0, + 0xb3, 0x06, 0x8e, 0x3c, 0x65, 0x81, 0xef, 0x34, 0x18, 0x87, 0x70, 0x9c, + 0x86, 0x11, 0x17, 0x06, 0x43, 0xf9, 0x62, 0xaa, 0x55, 0x57, 0x34, 0xcd, + 0x57, 0x98, 0x88, 0x05, 0x54, 0xaf, 0x69, 0x62, 0x6e, 0xa7, 0xae, 0xc2, + 0x59, 0x60, 0x9c, 0x87, 0xfb, 0xc2, 0x3c, 0x6f, 0x37, 0x48, 0x5e, 0x15, + 0x92, 0xff, 0xc4, 0x6d, 0x23, 0x0e, 0xad, 0x98, 0x8a, 0xa0, 0xa1, 0x27, + 0x52, 0x9c, 0xf3, 0x63, 0xf8, 0x8a, 0x52, 0x0f, 0xa2, 0x3c, 0x50, 0xff, + 0xb3, 0xf4, 0x38, 0x57, 0x92, 0x14, 0xd0, 0xd6, 0x98, 0x0e, 0xa7, 0x44, + 0xcb, 0x22, 0x21, 0xe6, 0x5e, 0x2b, 0xee, 0x87, 0x95, 0xba, 0xaf, 0x09, + 0x89, 0x95, 0x16, 0xe1, 0x13, 0x2e, 0x97, 0x52, 0x5b, 0x1c, 0x51, 0xa2, + 0xa6, 0xa5, 0x85, 0x7e, 0x64, 0x8e, 0xfe, 0x98, 0x40, 0x37, 0x06, 0x32, + 0x30, 0x3f, 0x5e, 0x2b, 0xb0, 0xe4, 0x16, 0x17, 0xb4, 0x05, 0x02, 0x69, + 0x45, 0x84, 0xfe, 0xf2, 0xe3, 0xa8, 0x7f, 0xac, 0x22, 0x72, 0xc2, 0xbf, + 0x25, 0x8e, 0x3d, 0x72, 0x6e, 0xf0, 0x8d, 0x92, 0x95, 0x73, 0x62, 0xa0, + 0x49, 0x55, 0x25, 0x61, 0x2b, 0x24, 0xf4, 0x03, 0xbe, 0x80, 0xd8, 0x15, + 0x84, 0xae, 0x78, 0xb0, 0x2b, 0xea, 0x7c, 0x35, 0xc3, 0x54, 0xbe, 0xda, + 0x41, 0x69, 0x12, 0x09, 0xf1, 0xf5, 0xbd, 0x6e, 0x64, 0x7e, 0x4e, 0x04, + 0xff, 0xb4, 0xcc, 0xd2, 0xb5, 0x3f, 0x1b, 0x09, 0x99, 0x37, 0x1f, 0xd6, + 0xaa, 0x8d, 0xa3, 0xf1, 0x60, 0xf5, 0x36, 0x5e, 0xb2, 0xe7, 0xdd, 0x47, + 0x8d, 0x9c, 0x88, 0xcf, 0x13, 0xbb, 0xdf, 0xa6, 0x7b, 0x63, 0xaa, 0xc9, + 0x75, 0x1e, 0xb3, 0xc2, 0x80, 0xa4, 0xd4, 0xf5, 0x4b, 0xae, 0x17, 0x56, + 0x6a, 0x4c, 0x07, 0x12, 0xcb, 0x26, 0xdb, 0x11, 0x50, 0x2e, 0x68, 0x7d, + 0x32, 0xed, 0x35, 0xc6, 0x47, 0x6a, 0x28, 0xea, 0x57, 0x17, 0x9a, 0x1a, + 0xaa, 0x86, 0x51, 0xdc, 0xbc, 0x4c, 0xbb, 0x5f, 0xa3, 0x68, 0x68, 0x7b, + 0xb7, 0xe1, 0x70, 0xe8, 0x36, 0xe7, 0x76, 0x7a, 0xc2, 0x6f, 0xb5, 0x95, + 0xab, 0x8d, 0xad, 0x9c, 0xc7, 0xdd, 0xf2, 0xad, 0x8c, 0xd8, 0x8d, 0xbe, + 0x97, 0xa5, 0x4c, 0x17, 0x29, 0x19, 0x10, 0x72, 0x6c, 0xc7, 0x74, 0xcb, + 0xb0, 0x8e, 0x7e, 0x77, 0xc6, 0xed, 0x4a, 0xb0, 0x1b, 0xff, 0xab, 0x36, + 0x6d, 0x76, 0xcf, 0x24, 0xbc, 0xef, 0x8e, 0xb4, 0xc3, 0x44, 0x42, 0xfc, + 0xec, 0xae, 0xb1, 0xe3, 0x2f, 0xdc, 0xb6, 0x5b, 0x6e, 0xd3, 0x74, 0xd8, + 0xff, 0xd4, 0xd1, 0x32, 0x47, 0xaf, 0x00, 0x56, 0xfa, 0x4d, 0xa6, 0xbc, + 0xaf, 0xcb, 0x39, 0x2b, 0xac, 0x0c, 0x8d, 0xc6, 0x37, 0x24, 0x00, 0xa9, + 0x8e, 0x90, 0x6a, 0xc9, 0x88, 0x60, 0x4d, 0xd4, 0xe0, 0x63, 0x1a, 0xa3, + 0xca, 0x38, 0xaa, 0x3d, 0xa4, 0x5d, 0xce, 0xbd, 0xd2, 0x9b, 0x71, 0x34, + 0x11, 0xbd, 0xf1, 0x0b, 0x6e, 0xf4, 0xb4, 0x17, 0xf9, 0xd5, 0xc1, 0xf4, + 0x6e, 0xb7, 0x62, 0xe5, 0x61, 0x8d, 0x45, 0x9b, 0xa4, 0xad, 0xd8, 0x92, + 0xed, 0x43, 0x0f, 0x98, 0x5e, 0xa0, 0x1a, 0x59, 0x87, 0xf1, 0x63, 0xa9, + 0x38, 0xff, 0x8e, 0x9f, 0x37, 0x82, 0xfc, 0x92, 0x82, 0x6a, 0x1a, 0x82, + 0xaf, 0xe6, 0xa9, 0x77, 0x6f, 0xb7, 0x73, 0xbb, 0xd4, 0xd8, 0x7c, 0xe5, + 0x5a, 0x7e, 0x8d, 0x70, 0xd8, 0xfd, 0x66, 0xd0, 0x20, 0xde, 0xd3, 0x40, + 0xc0, 0xf2, 0x42, 0x0e, 0x55, 0x22, 0xfd, 0xc4, 0xce, 0x4c, 0xf8, 0xc6, + 0xdb, 0x90, 0xbf, 0xd5, 0x8e, 0x02, 0x5c, 0x89, 0x34, 0x43, 0x26, 0x16, + 0x6d, 0x63, 0x52, 0x48, 0xad, 0x06, 0xae, 0xbf, 0x8e, 0xa6, 0x12, 0x1a, + 0x23, 0x68, 0x14, 0x38, 0x9f, 0xfd, 0x01, 0x8e, 0x43, 0x3d, 0x60, 0x3c, + 0xe5, 0x83, 0x65, 0x37, 0x5d, 0x52, 0xe2, 0x92, 0xb4, 0xd7, 0x91, 0xa2, + 0xe0, 0x31, 0xfa, 0xd9, 0x0d, 0x72, 0x6a, 0x50, 0x2d, 0x27, 0x49, 0x05, + 0x36, 0x1c, 0x1a, 0x57, 0x11, 0xc2, 0x49, 0x14, 0x93, 0x0e, 0x8a, 0x6e, + 0x7e, 0x50, 0xd7, 0xd3, 0xd5, 0x68, 0x3a, 0x4e, 0x29, 0x20, 0xf6, 0x60, + 0x39, 0xb1, 0xc9, 0x5a, 0xa6, 0xda, 0xc6, 0xb4, 0xf6, 0x63, 0xc5, 0x78, + 0xe8, 0x70, 0x52, 0x26, 0x1e, 0x7f, 0xa2, 0x2b, 0x14, 0x5f, 0x28, 0x0d, + 0x08, 0x5a, 0xd7, 0x48, 0xfe, 0xe1, 0x1a, 0x27, 0x6c, 0x47, 0xe2, 0xa4, + 0x21, 0x20, 0x49, 0x48, 0xa7, 0x16, 0x71, 0x1e, 0x54, 0x27, 0x81, 0xbe, + 0x02, 0xf9, 0xe2, 0x4d, 0x04, 0xd8, 0x26, 0xab, 0x33, 0x16, 0x5c, 0x10, + 0xfd, 0xe4, 0xa7, 0xe5, 0x24, 0x91, 0x4e, 0xf7, 0x34, 0x8e, 0x01, 0x5d, + 0x23, 0xc0, 0xc1, 0x36, 0xb4, 0xd1, 0xcd, 0x58, 0x40, 0xdb, 0xb4, 0xa3, + 0x78, 0xb2, 0xf8, 0xf9, 0x39, 0x20, 0x89, 0x99, 0x0d, 0x77, 0x14, 0x04, + 0xf7, 0x40, 0xb6, 0xd1, 0xdc, 0x69, 0x20, 0xcc, 0xde, 0x11, 0xd5, 0xbb, + 0x25, 0x2f, 0x83, 0xce, 0xd8, 0x58, 0xc1, 0xaf, 0xc5, 0x36, 0x07, 0x9d, + 0xac, 0x3f, 0x2c, 0xb2, 0xa3, 0x5c, 0xa6, 0x01, 0xce, 0xa2, 0x2b, 0xae, + 0x0d, 0x18, 0x43, 0x3c, 0xa9, 0x10, 0x6e, 0x92, 0xb5, 0xde, 0xea, 0xb2, + 0x71, 0x6d, 0x5b, 0x10, 0x3d, 0x97, 0x05, 0xde, 0xcc, 0xf2, 0x08, 0x23, + 0x19, 0x5b, 0x2f, 0xe8, 0x06, 0xa3, 0xf2, 0xf8, 0x03, 0x1f, 0x05, 0xe3, + 0x5f, 0x99, 0xd9, 0x20, 0x76, 0x39, 0x02, 0x9e, 0xbb, 0x1c, 0x47, 0x03, + 0x3c, 0x54, 0x32, 0x12, 0xa5, 0x24, 0x6f, 0x29, 0x5b, 0x94, 0xda, 0xf1, + 0xd2, 0x0e, 0x1c, 0x97, 0x15, 0x55, 0xa5, 0x0b, 0xa9, 0x20, 0x98, 0x1d, + 0xb9, 0x04, 0x91, 0x24, 0x47, 0x15, 0xb6, 0x02, 0x5f, 0x4b, 0x80, 0xf7, + 0x25, 0x31, 0x90, 0x2c, 0xf6, 0xde, 0xed, 0xab, 0xc7, 0x7d, 0x7e, 0x48, + 0xdf, 0x5f, 0x9b, 0x05, 0x8e, 0x68, 0x5a, 0xce, 0x19, 0x86, 0xc0, 0x14, + 0xf1, 0xd2, 0xc3, 0x59, 0x74, 0x07, 0x80, 0xca, 0x63, 0xe6, 0x04, 0x18, + 0x86, 0xa5, 0xde, 0xc4, 0x53, 0xf9, 0xdb, 0xbf, 0x97, 0xb7, 0x2e, 0xca, + 0xfe, 0xd8, 0x17, 0x93, 0xf0, 0x1f, 0xa5, 0xc4, 0x85, 0x09, 0x07, 0x8a, + 0xb6, 0x0d, 0xac, 0x2a, 0xa5, 0xfa, 0xae, 0xf2, 0x46, 0x75, 0xf5, 0x7b, + 0x0e, 0x31, 0xaf, 0xcc, 0x43, 0x31, 0xb9, 0x1a, 0xf5, 0xe7, 0x7d, 0x9a, + 0x70, 0x7f, 0xaa, 0xa5, 0x6d, 0xe1, 0xc1, 0x16, 0x18, 0x26, 0x39, 0xa5, + 0x12, 0x9b, 0xae, 0x3d, 0x47, 0xa9, 0x06, 0xaf, 0xd6, 0x5a, 0x6b, 0x43, + 0x48, 0x42, 0x89, 0x12, 0x0c, 0x28, 0x42, 0x39, 0x29, 0xce, 0x33, 0x3e, + 0xf5, 0x91, 0x30, 0xff, 0x36, 0x31, 0x8b, 0xeb, 0x79, 0x49, 0x18, 0xa6, + 0x94, 0x65, 0x66, 0x97, 0x6c, 0x66, 0x84, 0x0d, 0x13, 0x08, 0x24, 0xa1, + 0x85, 0x97, 0x52, 0x05, 0x5d, 0x37, 0x5d, 0x34, 0xe0, 0x14, 0x15, 0xdc, + 0xe8, 0xe8, 0x50, 0x21, 0x11, 0x9e, 0x3c, 0x5a, 0x5d, 0x2d, 0xc4, 0x5a, + 0x22, 0xa5, 0x03, 0x34, 0x0f, 0x15, 0x4d, 0x5b, 0x3e, 0xb5, 0x2c, 0x4e, + 0x04, 0xec, 0x61, 0x78, 0x9b, 0x9d, 0xc7, 0x34, 0x79, 0x12, 0xe5, 0xd4, + 0x8b, 0xc3, 0xd1, 0xf1, 0x55, 0x6c, 0x31, 0x6c, 0xef, 0x18, 0xfc, 0x2b, + 0x1c, 0x72, 0xc5, 0x11, 0x62, 0xbc, 0x02, 0x7a, 0x70, 0x98, 0xbd, 0x58, + 0x6a, 0x92, 0xd2, 0xee, 0x11, 0x08, 0x7e, 0x08, 0x62, 0x19, 0xf2, 0x4f, + 0x48, 0x12, 0x27, 0xd3, 0x31, 0x6b, 0x01, 0x53, 0x8e, 0x0f, 0xfc, 0xe6, + 0xb2, 0xbc, 0xea, 0x36, 0xe9, 0xcb, 0x08, 0x33, 0xcc, 0x75, 0x74, 0xc4, + 0x4a, 0x08, 0x1e, 0x99, 0xa0, 0x47, 0x13, 0x0b, 0x29, 0xdc, 0x01, 0x19, + 0x00, 0x00, 0xa1, 0x25, 0x4a, 0x2f, 0xf6, 0x40, 0x4c, 0x00, 0x86, 0x43, + 0x94, 0x87, 0x6e, 0x84, 0xef, 0xe7, 0x64, 0x51, 0xdd, 0x1c, 0xce, 0xba, + 0x7f, 0x7d, 0x94, 0x75, 0xfe, 0x58, 0xab, 0x7f, 0x7e, 0xfa, 0xb7, 0x87, + 0x9d, 0x87, 0x2b, 0x2b, 0x2b, 0x7f, 0xef, 0x5e, 0x0c, 0x4f, 0x5b, 0x8a, + 0xb2, 0x13, 0x7e, 0x76, 0xb3, 0xac, 0xab, 0xfc, 0x9e, 0x4f, 0x26, 0xde, + 0xfa, 0x05, 0xbf, 0x1e, 0xb6, 0xf1, 0x73, 0xf5, 0x5f, 0xad, 0x5b, 0xf4, + 0xc9, 0xd7, 0xf4, 0xf7, 0x5c, 0x7d, 0xe6, 0x76, 0xf2, 0xc2, 0x69, 0xc5, + 0x54, 0x3c, 0x50, 0x40, 0x9b, 0x91, 0xe1, 0x86, 0x67, 0x07, 0x91, 0x0b, + 0x94, 0x17, 0xe5, 0xad, 0xd0, 0xef, 0xab, 0xf0, 0xc3, 0x54, 0x78, 0xc7, + 0x3f, 0xc7, 0xd2, 0x93, 0xd2, 0x26, 0x47, 0x67, 0x0d, 0x67, 0x95, 0xda, + 0xeb, 0xf0, 0x04, 0xac, 0x0d, 0x82, 0xe2, 0x43, 0xf8, 0x64, 0x41, 0x87, + 0x12, 0xc6, 0xbe, 0x24, 0x95, 0x07, 0xeb, 0xa2, 0x85, 0x21, 0x87, 0x11, + 0xb7, 0xa2, 0xfe, 0xd3, 0x3a, 0xd1, 0x4f, 0x42, 0xeb, 0xcb, 0x06, 0x69, + 0xce, 0x52, 0xbe, 0xb4, 0x82, 0x05, 0xba, 0x38, 0x9d, 0xc2, 0x6d, 0x72, + 0x58, 0x82, 0xff, 0x19, 0x43, 0x02, 0x78, 0x78, 0xd7, 0xca, 0xe7, 0x79, + 0x3a, 0x79, 0x35, 0xd6, 0xfb, 0xe6, 0x50, 0x25, 0x40, 0xe9, 0x9e, 0x39, + 0x26, 0xa1, 0xad, 0x8d, 0xad, 0xf5, 0x20, 0x21, 0x21, 0xa7, 0xa6, 0x4d, + 0x90, 0xa9, 0xb6, 0xa0, 0x49, 0xb5, 0x05, 0xa3, 0xcc, 0x47, 0xc4, 0x93, + 0x3a, 0x91, 0x64, 0xa5, 0x32, 0x26, 0x23, 0x3a, 0x13, 0x6e, 0x8b, 0x99, + 0xe9, 0xb2, 0x5f, 0x6b, 0x3d, 0x24, 0x13, 0xfa, 0x8a, 0xe2, 0x3b, 0x0c, + 0xd5, 0xe5, 0x4b, 0xcb, 0x8a, 0x81, 0x56, 0x2f, 0xb5, 0xa3, 0x55, 0xa0, + 0x14, 0x74, 0x7a, 0xb1, 0xab, 0x92, 0xae, 0xa3, 0xd1, 0x8c, 0x3c, 0x87, + 0x6b, 0xd7, 0x8e, 0x23, 0xd2, 0x4a, 0xc1, 0x52, 0x35, 0x26, 0x1c, 0xec, + 0x89, 0x36, 0x60, 0x09, 0x1e, 0x36, 0xc4, 0x36, 0xbe, 0xad, 0x24, 0xbc, + 0x73, 0x32, 0xea, 0x78, 0xfe, 0xc7, 0x89, 0x37, 0xd4, 0xd0, 0xfb, 0x47, + 0x85, 0x03, 0xe6, 0x8a, 0x75, 0x45, 0x6e, 0x1d, 0xdd, 0x4e, 0x03, 0xef, + 0x90, 0x12, 0x03, 0xc2, 0x60, 0xbc, 0x36, 0xab, 0x82, 0xb6, 0x99, 0x91, + 0x3a, 0xad, 0xa7, 0xda, 0xc8, 0xa1, 0x72, 0x84, 0xcd, 0x62, 0x77, 0xe8, + 0xc8, 0x0e, 0xed, 0x42, 0x4a, 0xaa, 0xf4, 0x8f, 0xa6, 0xb0, 0xa9, 0x06, + 0x32, 0x08, 0x64, 0x2e, 0x94, 0xc1, 0x4c, 0x82, 0xba, 0xc6, 0xcd, 0xc1, + 0xeb, 0xca, 0xef, 0xe7, 0x30, 0x56, 0x00, 0x09, 0xab, 0x97, 0xdb, 0xac, + 0x93, 0xf1, 0xe9, 0xc3, 0x2b, 0x8d, 0x30, 0x15, 0xa9, 0x11, 0x84, 0x28, + 0xa5, 0x72, 0x69, 0x56, 0x84, 0x51, 0xf1, 0x77, 0x36, 0x5c, 0x2d, 0xf6, + 0x7b, 0x17, 0xc9, 0x98, 0x6c, 0xeb, 0x76, 0x49, 0xb2, 0x41, 0x11, 0x33, + 0xfc, 0xd7, 0x3c, 0x19, 0x33, 0x34, 0xd1, 0x09, 0xe7, 0x32, 0xb0, 0xed, + 0x57, 0x38, 0x92, 0xa6, 0xe8, 0x04, 0x39, 0x62, 0x19, 0x4a, 0x2e, 0x00, + 0x56, 0xfa, 0xd5, 0x51, 0xa5, 0x59, 0x55, 0x25, 0x36, 0x44, 0xcc, 0x7a, + 0xa5, 0x90, 0xf8, 0xef, 0x55, 0xfd, 0xc0, 0xcd, 0xdb, 0x76, 0xc4, 0xff, + 0xca, 0xee, 0xd9, 0x44, 0xba, 0x2e, 0xa4, 0x1b, 0x2c, 0xbd, 0x26, 0x71, + 0xd4, 0x57, 0xc3, 0x09, 0x5c, 0xf8, 0xb5, 0x5a, 0x2b, 0x28, 0x81, 0x52, + 0x34, 0x2f, 0x27, 0x5a, 0x0d, 0xc1, 0xe9, 0x47, 0x38, 0x06, 0x86, 0xab, + 0x6c, 0x5f, 0xac, 0xae, 0xc3, 0x2a, 0x66, 0xc8, 0xbf, 0xcc, 0x19, 0x84, + 0xdd, 0xcc, 0x2a, 0xc0, 0x17, 0xc6, 0xed, 0xef, 0xff, 0xfe, 0x7e, 0xb1, + 0x74, 0x31, 0x98, 0xd6, 0xcb, 0x1a, 0x16, 0x3c, 0x06, 0x57, 0x32, 0x77, + 0xaa, 0xd8, 0x12, 0x3d, 0x64, 0x2b, 0xa6, 0x1d, 0xd5, 0x1d, 0xe2, 0xd2, + 0x49, 0xef, 0x09, 0x6e, 0x5d, 0x95, 0xcc, 0x8b, 0xe2, 0xae, 0x9e, 0xab, + 0x5a, 0x43, 0x8e, 0x61, 0xfb, 0x82, 0x50, 0x66, 0x47, 0x8c, 0x4c, 0x10, + 0x92, 0xd5, 0x79, 0x09, 0x03, 0xf7, 0x68, 0xd8, 0x90, 0x5b, 0xb1, 0x76, + 0xdd, 0x6c, 0x63, 0xcc, 0x74, 0x75, 0x1d, 0xb9, 0xcc, 0x8a, 0x48, 0x37, + 0x67, 0x52, 0xc4, 0x96, 0xb1, 0x83, 0xc8, 0x8b, 0xfe, 0x7c, 0x42, 0x45, + 0x7c, 0xe7, 0x0f, 0xb2, 0x02, 0x3c, 0xae, 0xca, 0x53, 0xed, 0xad, 0x70, + 0x2e, 0x1e, 0x9c, 0x8c, 0x46, 0x37, 0xf5, 0xf6, 0xa7, 0x5b, 0x5d, 0x7b, + 0xc9, 0x4b, 0x7c, 0x81, 0x4a, 0xc0, 0x17, 0xbc, 0xd4, 0xfa, 0x3d, 0x67, + 0x76, 0x6f, 0x75, 0x25, 0x0c, 0xa7, 0x75, 0x3b, 0x98, 0x92, 0xe7, 0x4d, + 0x08, 0xd0, 0x06, 0xbd, 0xc9, 0xe9, 0x39, 0x8d, 0x2a, 0xef, 0x6b, 0xaa, + 0xbc, 0xb5, 0xda, 0x1e, 0x12, 0xf4, 0x49, 0x01, 0x9b, 0x54, 0x04, 0x08, + 0x71, 0xb7, 0x44, 0x3b, 0x9d, 0x54, 0x9c, 0xff, 0x16, 0x3c, 0x8c, 0xb7, + 0x01, 0xd7, 0x11, 0x3b, 0x2c, 0xf2, 0xa7, 0x31, 0x9c, 0x6a, 0xc8, 0x0a, + 0x5a, 0xc2, 0x77, 0xad, 0xa8, 0x88, 0x50, 0x16, 0x4f, 0x87, 0xe8, 0xb7, + 0xa4, 0xe8, 0xd6, 0xff, 0x46, 0x20, 0xeb, 0x1f, 0xd6, 0x5a, 0xdd, 0x62, + 0x4e, 0xd8, 0x21, 0xa1, 0x29, 0x15, 0x30, 0xc2, 0xfc, 0xc0, 0xea, 0x9e, + 0x52, 0xd3, 0x0f, 0x0b, 0x7c, 0x83, 0x3f, 0x50, 0x93, 0x80, 0x14, 0x1e, + 0x18, 0xe5, 0xa3, 0x55, 0xe3, 0x60, 0xf5, 0x9c, 0xb0, 0x19, 0x9f, 0xf5, + 0x75, 0x29, 0xb0, 0xf3, 0x81, 0x06, 0x3d, 0x07, 0xb3, 0x69, 0xf8, 0xf1, + 0xf6, 0x6e, 0xb4, 0x5e, 0xbc, 0x9e, 0x05, 0x18, 0x7c, 0xf0, 0x76, 0x73, + 0x6d, 0xe3, 0xcd, 0xe6, 0x7c, 0x90, 0xd0, 0x44, 0xd2, 0xf0, 0xd6, 0xb9, + 0x73, 0x53, 0xdd, 0xb9, 0x71, 0x10, 0x3a, 0xc2, 0xcf, 0x97, 0x16, 0xf5, + 0xda, 0x10, 0x3f, 0x4c, 0xea, 0x8f, 0xd1, 0xc7, 0xe2, 0x56, 0x4b, 0x82, + 0xc3, 0xc5, 0x62, 0xcf, 0x3b, 0x4a, 0x01, 0x02, 0x53, 0x14, 0xdf, 0x3c, + 0x28, 0xb9, 0x5b, 0xec, 0x7a, 0x39, 0x1b, 0x70, 0xe4, 0xc9, 0xf8, 0xc8, + 0xca, 0xd2, 0xe3, 0x6f, 0x4d, 0xe9, 0x2d, 0x07, 0x89, 0x9c, 0x03, 0x79, + 0xb3, 0x46, 0x52, 0xf3, 0x95, 0x6b, 0x4e, 0x93, 0xa4, 0x16, 0x9f, 0x9a, + 0x3b, 0x02, 0x8f, 0x3a, 0xbf, 0x98, 0xd4, 0x5a, 0x12, 0x24, 0x09, 0xe1, + 0x75, 0x0e, 0xe5, 0x33, 0xb0, 0x4a, 0xdc, 0x78, 0xa0, 0xb6, 0x1c, 0x85, + 0x41, 0xd8, 0x11, 0xc9, 0xe3, 0x11, 0xb5, 0x55, 0xaa, 0xc0, 0x0c, 0xe8, + 0x1c, 0x65, 0x66, 0x80, 0x7a, 0xdf, 0x28, 0x15, 0x31, 0x37, 0xf6, 0xfc, + 0x62, 0x14, 0x84, 0x0d, 0x7a, 0x29, 0x2c, 0x1e, 0xa9, 0x94, 0x57, 0x0a, + 0xaf, 0x17, 0x1f, 0x57, 0xcd, 0x42, 0xb5, 0xf3, 0xfc, 0x06, 0xb9, 0x03, + 0x7c, 0x29, 0xc3, 0x11, 0x68, 0x0b, 0x2e, 0xbb, 0x0d, 0x3c, 0x5c, 0xd9, + 0x4a, 0x81, 0x2a, 0x21, 0xa0, 0x6f, 0x66, 0x3d, 0x58, 0x09, 0xe9, 0x33, + 0xae, 0x25, 0x37, 0x49, 0xa4, 0x41, 0xf3, 0x79, 0x1b, 0xeb, 0x57, 0x97, + 0x2b, 0xf2, 0x6e, 0x99, 0xf0, 0x19, 0x84, 0xb9, 0x81, 0xe4, 0x8d, 0x3a, + 0xba, 0x8f, 0x81, 0x41, 0x55, 0x43, 0x9a, 0xf2, 0xc2, 0x74, 0xb4, 0x9c, + 0x58, 0x91, 0xba, 0x0e, 0xd3, 0x86, 0x64, 0xea, 0x57, 0x48, 0xf8, 0xd5, + 0x9b, 0x1e, 0xe9, 0xcb, 0xe1, 0x9c, 0x52, 0x36, 0x13, 0x72, 0xa9, 0x5d, + 0x5c, 0xa4, 0x16, 0x27, 0xf3, 0x88, 0x4e, 0x60, 0x96, 0x2a, 0x12, 0x10, + 0x7a, 0xec, 0xc1, 0xc7, 0xbe, 0x2c, 0xa6, 0x6c, 0xe0, 0xf9, 0x88, 0xb7, + 0x96, 0x1a, 0xa3, 0x8e, 0x06, 0x55, 0xc9, 0x4c, 0x74, 0xc2, 0x8e, 0x46, + 0xa7, 0xa7, 0x4a, 0x55, 0x3c, 0xd6, 0x52, 0xa2, 0x8d, 0xd8, 0xf5, 0x48, + 0x47, 0x06, 0x7a, 0xbd, 0x61, 0x16, 0xa4, 0x30, 0x6a, 0x10, 0x9c, 0xcc, + 0x93, 0x4c, 0x42, 0x1e, 0x56, 0x4e, 0xaa, 0x66, 0x7f, 0x61, 0x77, 0xc2, + 0x0e, 0xae, 0xd5, 0x68, 0x44, 0xc9, 0x14, 0x71, 0xfb, 0xcf, 0xd5, 0xf8, + 0xb0, 0x1a, 0x8f, 0xea, 0xe2, 0xfd, 0x13, 0xdb, 0xe8, 0xd2, 0x21, 0xb4, + 0x54, 0x72, 0x36, 0x08, 0x19, 0x6a, 0x4f, 0x32, 0xd8, 0xd4, 0x3b, 0x2f, + 0xb6, 0x18, 0x87, 0xdd, 0x4a, 0xc5, 0x67, 0x55, 0x70, 0x23, 0xbd, 0x87, + 0x0f, 0x02, 0xb1, 0x84, 0xc6, 0x4e, 0x32, 0x21, 0x50, 0x7b, 0x60, 0x10, + 0x36, 0x65, 0x32, 0xa2, 0xd9, 0x06, 0x4a, 0x3b, 0xa4, 0xa7, 0xb8, 0x4c, + 0xc6, 0xb9, 0xdf, 0xa7, 0xd9, 0x92, 0x02, 0x7c, 0x82, 0x84, 0x12, 0xeb, + 0x7e, 0x0f, 0xb5, 0x98, 0x44, 0x1f, 0x1b, 0xdf, 0xcc, 0x2b, 0x88, 0x88, + 0x39, 0x30, 0xdf, 0x00, 0x4c, 0x74, 0xde, 0xa2, 0xec, 0xec, 0x6f, 0xbf, + 0x69, 0x37, 0x4f, 0x81, 0xdd, 0xe2, 0x89, 0xc5, 0x52, 0x8f, 0x36, 0xb5, + 0x5d, 0x9f, 0x4b, 0x9c, 0xac, 0x85, 0xde, 0x89, 0x8f, 0x9e, 0xeb, 0xd2, + 0xf6, 0xaa, 0x09, 0x6a, 0x14, 0x75, 0xb3, 0x92, 0x5b, 0x9e, 0x5d, 0x10, + 0x00, 0xf9, 0xd4, 0xdc, 0x46, 0x9a, 0x0c, 0x83, 0xf0, 0x1e, 0x0e, 0xb9, + 0x62, 0x41, 0x93, 0x7f, 0xce, 0xd6, 0xfb, 0x8a, 0x1d, 0xc9, 0x06, 0xe0, + 0x64, 0x57, 0x7d, 0x92, 0xf5, 0xc6, 0xe8, 0x72, 0xd8, 0xd9, 0x46, 0xe5, + 0x8a, 0x62, 0x7b, 0x74, 0x1a, 0x96, 0x62, 0x87, 0xb3, 0x0a, 0xcd, 0xbd, + 0xdb, 0xdb, 0xd1, 0xcb, 0xef, 0x1d, 0x33, 0xa2, 0xf6, 0x82, 0x00, 0x75, + 0xd4, 0xbf, 0x80, 0x2c, 0x87, 0x67, 0x96, 0x0b, 0xd5, 0xf6, 0x71, 0xe4, + 0x78, 0xef, 0x69, 0xff, 0x61, 0x2e, 0x9b, 0x3f, 0xae, 0xbd, 0xd9, 0xdb, + 0xde, 0xfc, 0x49, 0x52, 0xa9, 0x22, 0xd6, 0x78, 0xf8, 0xf7, 0x4f, 0xa9, + 0xba, 0x89, 0x20, 0x38, 0x38, 0xb6, 0x42, 0xef, 0x57, 0x0d, 0xf6, 0x28, + 0x76, 0x58, 0xa3, 0x9e, 0x5e, 0x6f, 0x6f, 0xab, 0x63, 0x85, 0x2e, 0xc9, + 0x23, 0x0e, 0xfb, 0x43, 0xd8, 0x24, 0xc8, 0xf8, 0xaa, 0x31, 0x46, 0x12, + 0x89, 0x41, 0x1a, 0x7a, 0xff, 0xa4, 0x5d, 0xec, 0x58, 0x76, 0x64, 0x5b, + 0x76, 0x8f, 0x3a, 0xc6, 0x46, 0xff, 0x94, 0xfa, 0x6a, 0xb3, 0x58, 0xa5, + 0x5b, 0x02, 0xb8, 0xa5, 0x93, 0x6a, 0x30, 0x48, 0xb0, 0x7a, 0x18, 0xd6, + 0x31, 0x10, 0xef, 0x40, 0xba, 0xfd, 0x29, 0xe7, 0x95, 0xd3, 0xc9, 0x5d, + 0x49, 0x21, 0x5c, 0x02, 0x0f, 0x49, 0xad, 0x81, 0x57, 0x5a, 0x49, 0x4c, + 0xf6, 0x57, 0xb9, 0x2b, 0x8f, 0x58, 0x12, 0x86, 0xf9, 0x12, 0xb6, 0xcb, + 0x69, 0xf1, 0xb2, 0x65, 0x6e, 0x84, 0x5a, 0xaa, 0xb8, 0x7f, 0x95, 0xd4, + 0x1f, 0xae, 0xf6, 0xf8, 0xa5, 0x46, 0x4f, 0xdc, 0x52, 0xf1, 0x88, 0xd7, + 0x5c, 0xae, 0x79, 0xac, 0xd9, 0x25, 0xdc, 0x29, 0x4f, 0x31, 0xfb, 0x2c, + 0xf5, 0x47, 0xfc, 0x2c, 0xbd, 0x84, 0x2c, 0x41, 0x5b, 0x9d, 0x35, 0x3e, + 0xa9, 0x32, 0xba, 0x47, 0xd0, 0x64, 0x15, 0x82, 0x3d, 0xb2, 0xd5, 0x68, + 0x5b, 0xc5, 0xb7, 0xc3, 0x41, 0x09, 0x13, 0xba, 0xb1, 0x14, 0x6d, 0xa3, + 0x8d, 0xba, 0x36, 0x52, 0xd8, 0x22, 0xf9, 0xd4, 0x6a, 0x46, 0x24, 0xd6, + 0xb9, 0x7f, 0x4e, 0x61, 0x4e, 0x87, 0xc8, 0x6e, 0x58, 0x26, 0x8a, 0xf4, + 0x96, 0x8a, 0x6e, 0xb1, 0x90, 0x92, 0xa4, 0x74, 0xea, 0x23, 0x0d, 0x7d, + 0x55, 0x12, 0x20, 0xed, 0xbb, 0x5c, 0x61, 0x55, 0xa2, 0xc6, 0x6d, 0x46, + 0x80, 0x9f, 0x70, 0xaf, 0x5f, 0x45, 0x45, 0x66, 0x32, 0xca, 0x97, 0x6c, + 0xa9, 0xd5, 0x5a, 0x16, 0xb4, 0x0a, 0x29, 0x5a, 0x52, 0x27, 0xe5, 0x01, + 0x75, 0x74, 0x23, 0x6c, 0x0d, 0x6c, 0xd2, 0x42, 0x73, 0xa2, 0xee, 0x50, + 0x05, 0xe9, 0x7a, 0x6f, 0x17, 0x04, 0x39, 0x0f, 0xa4, 0xc6, 0x35, 0xb2, + 0x77, 0x95, 0x23, 0xc6, 0xda, 0xf4, 0xb0, 0xea, 0xf5, 0x27, 0x45, 0x66, + 0xba, 0x04, 0xad, 0xd2, 0xa7, 0xbc, 0xd4, 0x2a, 0x5a, 0x31, 0x3b, 0x32, + 0x19, 0xe3, 0xd7, 0xa2, 0xc5, 0xb5, 0xa2, 0x25, 0xd4, 0xb0, 0xb2, 0xf2, + 0xac, 0x75, 0x3b, 0x5a, 0xd4, 0x35, 0x49, 0x60, 0xdc, 0xf4, 0x23, 0x57, + 0x86, 0x0d, 0x44, 0xa9, 0x78, 0xf5, 0xb7, 0x7b, 0x7f, 0xa7, 0x0a, 0x81, + 0x9b, 0xf0, 0xc1, 0x9f, 0xd2, 0xd0, 0x34, 0x86, 0x97, 0x3b, 0xdc, 0x92, + 0x92, 0x4a, 0x8b, 0x0f, 0x6b, 0x28, 0x51, 0x8b, 0x3b, 0xde, 0x72, 0x75, + 0xa7, 0x55, 0x2c, 0xa9, 0x00, 0x43, 0x53, 0x43, 0x2b, 0x33, 0xd1, 0xa8, + 0x39, 0xfe, 0x44, 0x16, 0x38, 0x5b, 0x5b, 0x41, 0xe8, 0x68, 0x75, 0x5a, + 0xcb, 0xcb, 0xaa, 0x30, 0x47, 0xd4, 0x53, 0xc6, 0x93, 0xd8, 0xe5, 0x67, + 0x71, 0x50, 0xd1, 0xe7, 0xaf, 0x6e, 0x25, 0x7a, 0xaa, 0x34, 0xc2, 0x9e, + 0xba, 0x38, 0xdc, 0x4b, 0x22, 0xa6, 0x04, 0xaa, 0x98, 0x18, 0xc0, 0x8e, + 0xaa, 0x0a, 0x25, 0x40, 0x61, 0x8a, 0xb5, 0xce, 0xff, 0x09, 0x3f, 0x57, + 0x3a, 0x2f, 0x04, 0x60, 0x87, 0x39, 0xa5, 0xf5, 0xd1, 0x88, 0x96, 0xf2, + 0xfd, 0xbc, 0x72, 0xa5, 0xc5, 0x4e, 0x49, 0x8c, 0x21, 0xf8, 0xe2, 0x7c, + 0x0b, 0xab, 0x14, 0xa4, 0xf2, 0xc1, 0xc5, 0xc8, 0x11, 0x11, 0xa0, 0x62, + 0x51, 0x43, 0x5f, 0x55, 0x11, 0x56, 0x05, 0xe2, 0x1a, 0x90, 0x76, 0x0a, + 0x19, 0x4b, 0x8d, 0x7a, 0x10, 0x3b, 0xae, 0x13, 0xfc, 0x20, 0x71, 0xa9, + 0x5e, 0xa6, 0x62, 0xaf, 0x3d, 0x25, 0x2e, 0x9b, 0xd8, 0xba, 0x5d, 0xc5, + 0x5e, 0xb0, 0x56, 0xe0, 0x83, 0x4b, 0x8d, 0xa0, 0x9f, 0xd5, 0xa7, 0x3d, + 0xe3, 0x41, 0x33, 0x75, 0x63, 0x61, 0x21, 0xdf, 0x12, 0xad, 0xee, 0xe8, + 0x8e, 0x92, 0x56, 0xa7, 0x53, 0x7d, 0xba, 0x08, 0xad, 0x74, 0x5a, 0xed, + 0x18, 0x05, 0xc9, 0x41, 0xea, 0x1b, 0x02, 0x5b, 0x59, 0x17, 0xad, 0x5f, + 0x7e, 0xc1, 0x47, 0xff, 0xfa, 0x57, 0x2b, 0x62, 0x77, 0x65, 0x43, 0x85, + 0xb8, 0x3d, 0xa6, 0x88, 0x3a, 0x0b, 0xf7, 0x05, 0x13, 0x80, 0x19, 0x5d, + 0xe4, 0xa2, 0xe1, 0x81, 0x54, 0xf6, 0xb7, 0x7b, 0x21, 0xfa, 0x9e, 0xde, + 0xe1, 0x96, 0xc4, 0xe6, 0x9e, 0xbd, 0xd9, 0xf6, 0x0a, 0x85, 0xb7, 0xd4, + 0xf3, 0x6e, 0xd6, 0x17, 0x3d, 0xbc, 0x80, 0x8d, 0x51, 0xcb, 0x9e, 0x9c, + 0x54, 0x88, 0x13, 0x68, 0xcb, 0x5f, 0x87, 0x08, 0x59, 0x8a, 0x01, 0xdd, + 0xc2, 0xf8, 0xcb, 0x01, 0xdc, 0x51, 0x57, 0x33, 0x29, 0x94, 0xc9, 0x2c, + 0xef, 0xc9, 0x9a, 0x9c, 0x8b, 0xeb, 0x25, 0x6b, 0x10, 0x25, 0x58, 0xc2, + 0x3a, 0xf1, 0x34, 0xb5, 0x18, 0xf3, 0x58, 0x7d, 0xea, 0x9b, 0x35, 0xc7, + 0x16, 0xb6, 0x08, 0x7a, 0x95, 0xc0, 0xfc, 0xb8, 0x7a, 0x9c, 0x5c, 0xab, + 0x71, 0x6e, 0x26, 0xec, 0xeb, 0x90, 0x64, 0x38, 0xb8, 0x25, 0xae, 0x9b, + 0xa5, 0x31, 0xa4, 0x13, 0x33, 0x6b, 0xcd, 0x5b, 0x31, 0xaf, 0xb5, 0x5a, + 0x99, 0x18, 0x39, 0x65, 0x8a, 0x4a, 0x7c, 0xe2, 0x5e, 0xca, 0x1e, 0x0c, + 0x8e, 0xb3, 0xf1, 0xf5, 0x9f, 0x62, 0x20, 0xe2, 0x8e, 0xa7, 0x49, 0x0a, + 0xa9, 0x0d, 0xa5, 0x7e, 0x91, 0xab, 0x43, 0x9d, 0x82, 0x0b, 0xa1, 0x53, + 0x19, 0xe0, 0xff, 0xf9, 0xb4, 0x11, 0xab, 0xa1, 0xca, 0xa6, 0x24, 0xe1, + 0x67, 0xa9, 0xd8, 0x2a, 0x84, 0x8a, 0xa3, 0xe8, 0xaf, 0x9a, 0x8a, 0x15, + 0xfd, 0x61, 0xa5, 0xf9, 0x75, 0x8a, 0x93, 0xe9, 0xf0, 0x48, 0x11, 0xb0, + 0x62, 0x60, 0x28, 0x08, 0x95, 0x30, 0x42, 0xf9, 0xee, 0xd9, 0x09, 0x64, + 0xec, 0x17, 0xad, 0xa8, 0xc3, 0xbe, 0x5e, 0x65, 0xf0, 0x47, 0xd3, 0x33, + 0x08, 0xf7, 0x2e, 0x0c, 0x8a, 0x2a, 0xb6, 0x6a, 0xeb, 0xc2, 0x0b, 0xe3, + 0x22, 0x71, 0x90, 0xb5, 0xa2, 0x1f, 0x22, 0xe8, 0x4d, 0xac, 0xfd, 0x22, + 0x17, 0xe9, 0xd9, 0x1a, 0x4a, 0x0c, 0x5f, 0xb4, 0xa8, 0x05, 0xfd, 0x10, + 0x55, 0x26, 0x92, 0x21, 0x27, 0x16, 0xb3, 0x24, 0xf4, 0x8f, 0x91, 0x7f, + 0x86, 0x4b, 0x54, 0x54, 0xd8, 0xf5, 0xd2, 0x11, 0x02, 0x84, 0x35, 0x54, + 0x27, 0x93, 0xce, 0x64, 0xd4, 0x11, 0x1b, 0x1d, 0x95, 0x90, 0x6e, 0xf1, + 0xbe, 0x31, 0xcf, 0xe2, 0x2c, 0x70, 0x27, 0x0c, 0x6c, 0x08, 0xfb, 0xba, + 0xa2, 0xc1, 0xc5, 0x35, 0x82, 0xae, 0x87, 0x4d, 0x53, 0x1b, 0xa2, 0xb0, + 0x13, 0x59, 0x7c, 0xd8, 0xf6, 0xd5, 0x54, 0x63, 0xe4, 0x6c, 0x5b, 0xb4, + 0x16, 0x43, 0x0b, 0x6d, 0x16, 0x66, 0xe9, 0x0c, 0xd2, 0x0a, 0xee, 0xb9, + 0x05, 0xbb, 0xfe, 0x41, 0x0c, 0x03, 0xf5, 0xfd, 0x72, 0x49, 0x2c, 0x3a, + 0x21, 0xa8, 0xf1, 0x40, 0xc4, 0x12, 0xd6, 0x20, 0xef, 0xfe, 0xa3, 0x1e, + 0x0d, 0xf1, 0xae, 0xa1, 0x26, 0x4d, 0x22, 0xc3, 0x54, 0x3d, 0xe6, 0x3f, + 0x7b, 0xbb, 0x3b, 0x26, 0x11, 0x41, 0xfe, 0xc1, 0xef, 0xf1, 0x74, 0x50, + 0xb9, 0xb4, 0x82, 0x30, 0x80, 0xd0, 0x42, 0x0c, 0x2e, 0xb6, 0xf7, 0x61, + 0xa7, 0x5a, 0x0a, 0xe2, 0xf6, 0x51, 0xf8, 0x67, 0xb9, 0x68, 0x98, 0x4c, + 0x0f, 0x9f, 0x3e, 0xc6, 0x5b, 0x32, 0xef, 0xc6, 0x69, 0x87, 0xc2, 0xf8, + 0xf4, 0xb1, 0xbd, 0x31, 0x9f, 0x1d, 0xde, 0x85, 0xe1, 0x3c, 0xbb, 0x68, + 0xfe, 0x50, 0x9f, 0x8b, 0x25, 0x4a, 0x19, 0x36, 0x1e, 0x69, 0x89, 0x44, + 0x21, 0xc8, 0xb1, 0xb9, 0xc9, 0xc9, 0xd9, 0xf5, 0xe7, 0xa3, 0xfa, 0x72, + 0x89, 0xf7, 0x63, 0x3b, 0x86, 0x1a, 0xc9, 0xab, 0x6f, 0x68, 0x52, 0xe1, + 0x98, 0x2c, 0xbc, 0x4b, 0x4a, 0x81, 0x36, 0x62, 0x50, 0x98, 0xf4, 0x86, + 0x48, 0x64, 0xc1, 0x0c, 0x3d, 0x9c, 0x9e, 0x9e, 0x5a, 0xe0, 0xbb, 0xb1, + 0xd5, 0x4a, 0xb6, 0xb9, 0x9c, 0xdc, 0x87, 0xef, 0x9a, 0x81, 0xf0, 0xe0, + 0x1b, 0xbc, 0xbe, 0xa5, 0xb5, 0xb3, 0xd1, 0xe8, 0x98, 0x71, 0xaf, 0x52, + 0xe6, 0x82, 0x56, 0xf1, 0x28, 0xec, 0xaa, 0x78, 0x23, 0x69, 0xd8, 0x2a, + 0x29, 0x49, 0xaa, 0x10, 0xad, 0x86, 0xe1, 0xcc, 0x61, 0x98, 0x81, 0x2d, + 0xbc, 0xd2, 0x67, 0xb2, 0x87, 0x24, 0x87, 0x48, 0x3c, 0x4d, 0xa9, 0x32, + 0x64, 0x27, 0xea, 0xac, 0x1f, 0x16, 0x69, 0x28, 0xc1, 0x0b, 0x41, 0x17, + 0x1c, 0x08, 0x43, 0xd2, 0x14, 0xa5, 0x52, 0x87, 0xd4, 0x18, 0xd1, 0x7f, + 0xa4, 0x23, 0xb2, 0x28, 0xd7, 0xf0, 0x2a, 0xa2, 0xf7, 0xa3, 0x34, 0xa9, + 0x03, 0x6b, 0x08, 0xd0, 0x12, 0x36, 0xc2, 0x9c, 0x40, 0x51, 0x0b, 0xcc, + 0x0d, 0xed, 0xf2, 0xbf, 0x90, 0xfd, 0x0c, 0xc6, 0x6f, 0x91, 0xf8, 0x1b, + 0x12, 0x3c, 0x67, 0x0f, 0x7b, 0x27, 0x1f, 0x03, 0xa2, 0x0b, 0xa9, 0xa7, + 0x21, 0xbd, 0x4b, 0x31, 0x2f, 0x47, 0x89, 0x41, 0x48, 0xc0, 0x10, 0x0f, + 0x78, 0x71, 0x26, 0x93, 0x1a, 0x66, 0x48, 0x57, 0x94, 0x8f, 0x88, 0x2e, + 0x67, 0x12, 0x7f, 0x68, 0x70, 0x8c, 0x02, 0x8b, 0x56, 0x30, 0x88, 0xa5, + 0x23, 0x63, 0x40, 0x82, 0x46, 0x07, 0x1a, 0x46, 0xf4, 0xf7, 0xa3, 0x4b, + 0x34, 0xdc, 0x8e, 0x86, 0x26, 0x31, 0x22, 0xb5, 0x13, 0x33, 0x41, 0x0c, + 0x35, 0x65, 0x68, 0xef, 0x70, 0x14, 0x53, 0x3f, 0xc6, 0x5a, 0x2c, 0x93, + 0xd8, 0xd0, 0xb6, 0xe0, 0xd6, 0xd0, 0x55, 0xac, 0xbe, 0xdd, 0xea, 0x7c, + 0xfc, 0xd8, 0x12, 0xe9, 0x4c, 0x75, 0x21, 0xd9, 0x23, 0xee, 0x36, 0xbe, + 0x0c, 0xa4, 0xde, 0x12, 0x46, 0x1a, 0xc4, 0x8d, 0xc0, 0x4b, 0x85, 0xe1, + 0x7b, 0x79, 0x5b, 0x1b, 0xc9, 0x47, 0x4b, 0x93, 0xa7, 0x9b, 0x12, 0xce, + 0x15, 0x6c, 0x18, 0x88, 0x48, 0x86, 0x84, 0x42, 0x7e, 0x5e, 0xbf, 0x25, + 0xc1, 0x69, 0x31, 0xba, 0xe0, 0xda, 0xc6, 0x30, 0x88, 0xf4, 0xf0, 0x47, + 0x7c, 0x3e, 0x8d, 0xcf, 0x65, 0xd4, 0x45, 0x8c, 0xff, 0xe1, 0xe9, 0xa1, + 0x32, 0x73, 0xd9, 0x27, 0x26, 0x36, 0x6b, 0x95, 0xcb, 0xcc, 0xda, 0x85, + 0x23, 0xc9, 0x29, 0x76, 0xe1, 0x52, 0x1a, 0x72, 0xb8, 0x9c, 0x46, 0x91, + 0x78, 0x41, 0x5e, 0x58, 0xe3, 0x97, 0x92, 0x78, 0xd2, 0x65, 0xa9, 0x49, + 0x7e, 0x59, 0x21, 0x86, 0x1b, 0xf6, 0x1d, 0x8d, 0xea, 0xc6, 0x03, 0xec, + 0x9c, 0x06, 0xac, 0xd2, 0x4c, 0x07, 0xe6, 0x46, 0xad, 0x63, 0x23, 0x3a, + 0x70, 0xfb, 0x66, 0xb9, 0x1b, 0xd9, 0x8d, 0x18, 0x06, 0x02, 0x45, 0x8d, + 0x8f, 0x9b, 0x29, 0x15, 0x75, 0x1c, 0x93, 0x31, 0xe3, 0xa5, 0x3c, 0x46, + 0xb2, 0xb8, 0xb7, 0x1c, 0xe5, 0xd1, 0x24, 0xda, 0xdc, 0x47, 0x26, 0x01, + 0x2f, 0x42, 0xe9, 0x59, 0x14, 0x7c, 0x51, 0x34, 0x47, 0x67, 0x09, 0x84, + 0xe5, 0x71, 0x9b, 0x12, 0x7a, 0xbb, 0xae, 0x93, 0x81, 0x72, 0x92, 0xcc, + 0x2f, 0xb2, 0x82, 0xd2, 0xc7, 0xac, 0x1f, 0x1d, 0x7b, 0x62, 0x47, 0x12, + 0xe6, 0xee, 0x19, 0x1f, 0x59, 0x94, 0xfb, 0xc2, 0x9c, 0x4e, 0xed, 0xd1, + 0xd8, 0xd1, 0xf0, 0x2a, 0x46, 0xc1, 0xab, 0x1f, 0xcf, 0x89, 0x5c, 0xa8, + 0xa6, 0x3c, 0x99, 0x98, 0x52, 0x94, 0xa1, 0xa8, 0x37, 0xd9, 0x06, 0x03, + 0xed, 0xf2, 0xb3, 0x1a, 0xa1, 0x57, 0xa8, 0x95, 0xdb, 0x73, 0x1e, 0x7d, + 0xa6, 0x8e, 0xed, 0xb6, 0x3b, 0x8a, 0xf3, 0x72, 0xba, 0x1e, 0x73, 0xdd, + 0x08, 0x55, 0x8d, 0xc0, 0x8f, 0xbb, 0x62, 0x33, 0xd6, 0x98, 0x13, 0xcb, + 0xd8, 0x61, 0xf4, 0x89, 0x95, 0x1c, 0x6c, 0x46, 0x9b, 0x7b, 0xa8, 0x7f, + 0x1a, 0x03, 0x79, 0x94, 0xed, 0x95, 0x57, 0x80, 0xbb, 0xec, 0xd7, 0x67, + 0x62, 0x2a, 0xa9, 0xfe, 0x27, 0x21, 0xe7, 0x2b, 0x17, 0x68, 0xb0, 0xe5, + 0xfc, 0x82, 0x6a, 0x31, 0x37, 0xc5, 0x43, 0xc7, 0xb0, 0xe4, 0x9b, 0x44, + 0x19, 0xed, 0xf3, 0xcb, 0x13, 0x73, 0xe6, 0xc0, 0x90, 0x78, 0x4c, 0x74, + 0x23, 0xf9, 0x6f, 0xb6, 0x8e, 0x57, 0x72, 0x69, 0xb6, 0xbd, 0xa2, 0x48, + 0xbb, 0x11, 0x57, 0x9d, 0x35, 0x21, 0x42, 0xd0, 0x7b, 0x15, 0x82, 0x22, + 0x70, 0xe9, 0x86, 0x86, 0xae, 0xa7, 0x69, 0x79, 0x8a, 0xdc, 0x29, 0xa4, + 0xa8, 0x7a, 0xb3, 0x61, 0xae, 0x38, 0xc4, 0x23, 0x63, 0x04, 0xea, 0x54, + 0xe1, 0x17, 0xdf, 0x95, 0xdc, 0x00, 0x9e, 0x85, 0xae, 0x88, 0xf7, 0x90, + 0xc8, 0xed, 0x55, 0x83, 0x33, 0x68, 0x47, 0x8c, 0xac, 0xc8, 0xd4, 0xc5, + 0x3e, 0xf2, 0x08, 0x40, 0x3a, 0x41, 0x1e, 0xb9, 0x52, 0xe0, 0x01, 0x9c, + 0x84, 0xd0, 0xee, 0x87, 0x68, 0xd3, 0x40, 0xe4, 0x41, 0x75, 0x34, 0x9d, + 0xa4, 0xa8, 0xdb, 0xfb, 0x2c, 0xed, 0x29, 0x45, 0xdd, 0x39, 0x8a, 0xa5, + 0x2c, 0xf8, 0xa0, 0xf5, 0xb6, 0x62, 0xbd, 0xe4, 0xce, 0x46, 0xd0, 0x2e, + 0x5e, 0xb6, 0x96, 0xb3, 0xc4, 0xbc, 0xb1, 0x7c, 0xe7, 0x8e, 0x9d, 0xac, + 0x51, 0x61, 0xf6, 0x59, 0x93, 0xd2, 0xe2, 0x9e, 0xdd, 0x1c, 0x68, 0x4e, + 0x5a, 0x03, 0x43, 0x8d, 0x17, 0x4a, 0xa2, 0x7f, 0xd8, 0x5c, 0xc7, 0x95, + 0x2a, 0xda, 0x0e, 0x5a, 0x93, 0x2d, 0xe2, 0x08, 0xc1, 0x74, 0x73, 0x87, + 0xff, 0xad, 0x44, 0xfc, 0x25, 0x7d, 0x39, 0xef, 0xb1, 0x68, 0xc0, 0xfa, + 0xda, 0xae, 0x46, 0x04, 0x69, 0x4f, 0xd5, 0x19, 0x7d, 0xc3, 0xb6, 0xca, + 0xb4, 0x9a, 0x72, 0x30, 0xe9, 0xd4, 0x1f, 0x8f, 0x88, 0x74, 0xae, 0x98, + 0x3a, 0x66, 0x67, 0x58, 0x0b, 0x5f, 0xf5, 0x3e, 0x1e, 0xbd, 0x34, 0xe1, + 0x33, 0x89, 0xd0, 0xf0, 0xdb, 0xa0, 0xbe, 0x1a, 0x1e, 0x9d, 0x6d, 0xec, + 0xf4, 0xf0, 0x3e, 0x49, 0x9f, 0x03, 0xa1, 0x6a, 0x15, 0x6e, 0x62, 0x7c, + 0x19, 0x14, 0x65, 0xc8, 0x31, 0x62, 0x2f, 0x09, 0x03, 0x40, 0xb1, 0xc6, + 0xba, 0xab, 0x6f, 0xea, 0x97, 0x85, 0x60, 0xfd, 0x2e, 0xd8, 0xd7, 0xa6, + 0x7a, 0x08, 0x2a, 0x82, 0x70, 0x77, 0x35, 0xab, 0x48, 0x98, 0x6a, 0xa7, + 0xc4, 0x54, 0x74, 0x9c, 0x48, 0x0d, 0xc0, 0x08, 0x8f, 0x63, 0x0b, 0xe3, + 0x08, 0x5d, 0x60, 0x8a, 0x50, 0xd8, 0xa3, 0x41, 0xbf, 0x39, 0xcd, 0x58, + 0x72, 0x47, 0xbe, 0x77, 0x7c, 0x00, 0xde, 0x6e, 0x68, 0x47, 0x03, 0x70, + 0xad, 0x99, 0xf5, 0xc0, 0x06, 0xd7, 0x83, 0x66, 0x8d, 0x86, 0x38, 0x55, + 0xd6, 0x10, 0x4c, 0x01, 0xdf, 0x1c, 0x9a, 0x88, 0xbc, 0xcc, 0xc3, 0xa1, + 0xd5, 0xc6, 0x23, 0xb1, 0x4d, 0xb5, 0xc8, 0x7a, 0x0b, 0x4b, 0xac, 0x89, + 0xb8, 0xf9, 0x7a, 0x7d, 0x63, 0x6b, 0x7d, 0x59, 0x7b, 0xd8, 0x80, 0xc6, + 0x31, 0x67, 0x39, 0xcb, 0xb8, 0xcf, 0xd2, 0x9d, 0xf4, 0xc6, 0xc7, 0x55, + 0xb6, 0x13, 0xf1, 0xa2, 0x16, 0x71, 0x02, 0x5a, 0x1f, 0x34, 0x5b, 0xf2, + 0x85, 0x0f, 0xa6, 0xa4, 0x06, 0x49, 0xee, 0x1c, 0xe1, 0xeb, 0x89, 0x5e, + 0x53, 0x4d, 0x8e, 0x34, 0x46, 0x02, 0x8d, 0x77, 0x8e, 0x21, 0xf5, 0x42, + 0x19, 0xc2, 0x00, 0x71, 0x45, 0xfe, 0xce, 0x38, 0xe2, 0xfa, 0xf7, 0x18, + 0x56, 0xf8, 0xe5, 0x53, 0x24, 0x45, 0xb0, 0xae, 0x8f, 0xad, 0xcf, 0x69, + 0x5d, 0xd6, 0x03, 0x19, 0x7d, 0xa5, 0xeb, 0xd2, 0x81, 0x5d, 0xb1, 0xb7, + 0x06, 0x88, 0xbb, 0x39, 0x95, 0x73, 0x8d, 0x6f, 0x78, 0x60, 0x11, 0x85, + 0x96, 0x11, 0x34, 0x5d, 0xab, 0x06, 0xbf, 0xfe, 0x76, 0xed, 0x8d, 0xd7, + 0xfd, 0xb4, 0x35, 0xc0, 0xba, 0x27, 0xeb, 0x10, 0x3e, 0x66, 0xd7, 0x36, + 0x8e, 0xef, 0x7a, 0xbd, 0xce, 0xda, 0xde, 0x16, 0x46, 0xa2, 0x7f, 0x32, + 0xb5, 0xd7, 0xa2, 0x79, 0xed, 0xb1, 0xef, 0x7b, 0xfb, 0x24, 0x5d, 0xfc, + 0xbe, 0x61, 0x56, 0x20, 0x02, 0x82, 0xb7, 0x12, 0x58, 0x63, 0xd5, 0x9f, + 0x74, 0x3c, 0x6d, 0x9b, 0x68, 0xfa, 0xc2, 0x23, 0x7f, 0xe1, 0xd1, 0xed, + 0x5e, 0xe8, 0x89, 0x9d, 0x3c, 0xdf, 0xfb, 0x79, 0xa0, 0x57, 0x7c, 0x58, + 0xca, 0xad, 0xb8, 0x4c, 0xb5, 0xb1, 0x93, 0xbf, 0xe7, 0xb6, 0xa4, 0xf0, + 0x4d, 0xd1, 0x31, 0xd0, 0x6d, 0xd5, 0xea, 0x12, 0xb7, 0x63, 0xf4, 0x86, + 0xec, 0x7d, 0x7c, 0x8a, 0x26, 0x2c, 0x7c, 0x1c, 0x8b, 0x8d, 0xcf, 0xa2, + 0x55, 0xd9, 0x9e, 0x74, 0x8f, 0x5e, 0x78, 0x3a, 0x75, 0x49, 0x37, 0x36, + 0x77, 0xde, 0x7a, 0x6f, 0xa3, 0x7c, 0x80, 0xa2, 0xe1, 0xcf, 0x1b, 0xac, + 0x03, 0x96, 0xe0, 0xd2, 0x60, 0xad, 0x01, 0x51, 0x26, 0xda, 0x1a, 0xc9, + 0x2d, 0xe5, 0x07, 0xcc, 0x8e, 0xbe, 0xb0, 0xfa, 0xdd, 0x6b, 0x6b, 0x39, + 0x10, 0xc0, 0xcf, 0x68, 0xd4, 0xab, 0x49, 0x43, 0x58, 0x4c, 0x4f, 0x73, + 0xb1, 0xf4, 0xb1, 0x8f, 0x28, 0xd3, 0x9f, 0xfb, 0x17, 0x6d, 0x86, 0x54, + 0xc2, 0xfe, 0xbc, 0x2c, 0x62, 0x71, 0xc4, 0xb3, 0x08, 0x2d, 0x48, 0x4f, + 0x7e, 0xf8, 0xe7, 0xce, 0xe3, 0x0d, 0x64, 0x8e, 0x5e, 0x6f, 0xfb, 0x9a, + 0x69, 0xb8, 0x48, 0x92, 0x81, 0xa8, 0x98, 0x40, 0xb8, 0xbf, 0xfd, 0x06, + 0xef, 0xd1, 0xf5, 0x79, 0x8b, 0x35, 0xc3, 0x73, 0x07, 0x3f, 0xbc, 0xf6, + 0x57, 0x8e, 0x2b, 0xe0, 0xf6, 0x9b, 0xd5, 0x2e, 0x6c, 0xcf, 0xf0, 0xb0, + 0x8f, 0x8a, 0xe8, 0xd5, 0xe0, 0x42, 0x41, 0xef, 0x62, 0x13, 0xaa, 0xf3, + 0x29, 0xf3, 0x0f, 0x2d, 0xe0, 0xd8, 0x88, 0x01, 0x4b, 0x1d, 0xa3, 0x42, + 0x64, 0xb0, 0xa7, 0x3c, 0x8f, 0x50, 0xc6, 0x7b, 0x32, 0xb3, 0xf0, 0x8b, + 0x23, 0x3a, 0x73, 0x76, 0xb6, 0x37, 0x3d, 0x1c, 0x84, 0xa5, 0xed, 0x4d, + 0x83, 0x58, 0xfa, 0xa9, 0xd8, 0xa6, 0xa7, 0x83, 0xc1, 0xe6, 0x51, 0x27, + 0x15, 0x79, 0x5e, 0xb2, 0x56, 0x16, 0x72, 0x7a, 0x17, 0x52, 0x8a, 0x45, + 0x05, 0x44, 0xee, 0x68, 0x5d, 0x48, 0xa3, 0x35, 0x1b, 0xad, 0x6a, 0xb7, + 0xcc, 0xf7, 0xf6, 0x76, 0x36, 0xbf, 0xdb, 0x25, 0xcb, 0xe6, 0x5f, 0xb7, + 0x59, 0x2c, 0xdd, 0x13, 0x00, 0x6a, 0x3a, 0x9c, 0x12, 0xb7, 0x18, 0x46, + 0x28, 0x5e, 0x35, 0xc9, 0x65, 0x2d, 0x21, 0x39, 0xd6, 0x44, 0x3b, 0xd6, + 0x73, 0xd2, 0x83, 0xdb, 0x6b, 0x6b, 0xad, 0x5a, 0x96, 0xa7, 0x95, 0x0a, + 0x3d, 0xa3, 0x22, 0x22, 0x42, 0xc3, 0x01, 0x2e, 0xbd, 0x5d, 0xc3, 0x5e, + 0x14, 0xbe, 0x93, 0xcf, 0xbc, 0xdd, 0x2b, 0x96, 0x7a, 0xac, 0x84, 0x58, + 0xbc, 0x95, 0x7c, 0x21, 0x96, 0x46, 0x81, 0x8b, 0x7a, 0x79, 0x96, 0x2f, + 0x26, 0x8d, 0x69, 0x5c, 0xe6, 0x42, 0x5a, 0x7d, 0x18, 0x2c, 0xfd, 0x0d, + 0x39, 0x39, 0xda, 0xe6, 0x1d, 0x60, 0x9c, 0xdd, 0xd9, 0xfd, 0xbc, 0x01, + 0xbd, 0x1b, 0xf6, 0x61, 0xec, 0x23, 0xce, 0xb4, 0xfc, 0xe9, 0x4c, 0x25, + 0x74, 0xab, 0x8e, 0xfd, 0xe4, 0xe1, 0x4f, 0x3d, 0x26, 0x9e, 0xd5, 0xfa, + 0xc2, 0x27, 0xcd, 0x63, 0xab, 0x73, 0x5e, 0x99, 0xcb, 0x04, 0x3f, 0xd7, + 0x93, 0xe3, 0xfc, 0x24, 0xce, 0x3b, 0x88, 0x78, 0x4a, 0x4e, 0x5f, 0x02, + 0xc9, 0xa3, 0xa7, 0x9c, 0x87, 0x4f, 0xf7, 0x60, 0xee, 0x34, 0xae, 0x15, + 0xce, 0x29, 0xe8, 0xce, 0xf1, 0x45, 0x0e, 0x2e, 0x54, 0x48, 0x3e, 0x2f, + 0x87, 0xd3, 0x32, 0xd6, 0x92, 0xfa, 0x38, 0x28, 0x87, 0x81, 0xeb, 0xf6, + 0x01, 0xea, 0x73, 0x55, 0xbc, 0xb2, 0xbf, 0xcc, 0x33, 0xbe, 0x86, 0xc0, + 0x5c, 0x38, 0x21, 0xdf, 0x6f, 0xaf, 0xed, 0x14, 0xfe, 0x1c, 0xa0, 0xb8, + 0x08, 0xa0, 0x4e, 0x73, 0xc8, 0xd6, 0xe6, 0xe6, 0x66, 0xf1, 0x7c, 0x65, + 0xb5, 0xfb, 0xf0, 0x2f, 0x99, 0x02, 0x14, 0x14, 0x9a, 0xc1, 0xb1, 0x61, + 0xa3, 0x87, 0x79, 0x6f, 0x42, 0x7e, 0x41, 0xd9, 0x1b, 0xda, 0x95, 0xda, + 0x31, 0xe1, 0x4a, 0xc0, 0x65, 0x71, 0x36, 0x18, 0x52, 0x22, 0xd9, 0x61, + 0x06, 0x24, 0x3d, 0xc9, 0xcb, 0x17, 0x57, 0x82, 0x0e, 0x5d, 0x04, 0x3e, + 0x79, 0xaa, 0x69, 0x3c, 0x71, 0xd4, 0x3c, 0xfc, 0x2b, 0xe4, 0x0a, 0xcf, + 0x34, 0x44, 0x21, 0x9f, 0xe0, 0x57, 0x83, 0x29, 0xcd, 0xbb, 0x79, 0x7c, + 0xbb, 0x5c, 0xde, 0x17, 0x0d, 0x03, 0x6e, 0xff, 0xa2, 0x33, 0x19, 0x39, + 0x18, 0xf1, 0x25, 0x74, 0x17, 0x1a, 0x3a, 0x10, 0x8a, 0x5e, 0xbc, 0x12, + 0x75, 0xe5, 0x9b, 0x68, 0xcb, 0xb5, 0x5c, 0x22, 0xab, 0xe6, 0x93, 0xa9, + 0x34, 0x02, 0x6a, 0xa6, 0xa1, 0x97, 0x6a, 0x91, 0x80, 0x08, 0xe5, 0x4e, + 0xfa, 0x86, 0x51, 0xa9, 0xab, 0xd2, 0x38, 0xde, 0x17, 0xa7, 0xaf, 0xc5, + 0x3d, 0x10, 0x2f, 0x33, 0x34, 0x6f, 0x8a, 0xb7, 0x94, 0xc0, 0xd4, 0x20, + 0x4e, 0xf8, 0x20, 0x13, 0xb7, 0x28, 0x8d, 0x79, 0xc3, 0xe9, 0xf9, 0x21, + 0x82, 0x0d, 0x4e, 0xa2, 0x83, 0xa7, 0x5b, 0xa4, 0xcd, 0x9b, 0x74, 0x9b, + 0xe8, 0xbd, 0x65, 0xac, 0xdc, 0x30, 0x08, 0x33, 0xc6, 0x8e, 0xb4, 0x64, + 0x00, 0x2d, 0x22, 0x66, 0x5b, 0x60, 0x00, 0x41, 0x50, 0x54, 0xd6, 0xd7, + 0x24, 0x4f, 0x6d, 0x34, 0x8d, 0x41, 0x4b, 0x46, 0xd4, 0xfa, 0x93, 0x65, + 0xc6, 0x09, 0x14, 0x01, 0xad, 0x19, 0xb0, 0x93, 0x69, 0xae, 0xa3, 0x22, + 0x8a, 0xcc, 0xb6, 0x44, 0x57, 0x79, 0x8c, 0x4a, 0xe0, 0x46, 0x84, 0xd6, + 0x3a, 0xad, 0x9c, 0x16, 0xcd, 0xf9, 0x65, 0xe5, 0x1d, 0x73, 0x8b, 0xaf, + 0x35, 0x59, 0xd2, 0x8e, 0x7b, 0x58, 0x4f, 0xfa, 0x93, 0xa9, 0x42, 0x8c, + 0xc5, 0xe8, 0x09, 0x21, 0x33, 0xc6, 0x6d, 0x60, 0x4d, 0x93, 0x6c, 0x6b, + 0xcf, 0xc5, 0x3c, 0xe9, 0x4f, 0xc4, 0xc4, 0xa7, 0xc8, 0x32, 0x87, 0x34, + 0x7e, 0x07, 0x31, 0xf5, 0x32, 0xac, 0xec, 0x9a, 0xd9, 0xf5, 0xe2, 0x68, + 0xd8, 0x5f, 0xba, 0xb8, 0xf7, 0x7e, 0xb1, 0x2f, 0x0f, 0xe8, 0x4f, 0x10, + 0x3d, 0x77, 0x64, 0xc3, 0x2c, 0x0b, 0x35, 0x95, 0x4b, 0x43, 0xf7, 0x38, + 0xe5, 0x7f, 0xc0, 0x9f, 0x2f, 0xf3, 0x66, 0x95, 0x4c, 0x34, 0x73, 0xaf, + 0xeb, 0xe9, 0x75, 0xfe, 0xea, 0xb0, 0xba, 0xa4, 0xfa, 0x16, 0x83, 0x87, + 0x7f, 0x1a, 0x9a, 0x17, 0x1a, 0x46, 0x94, 0xd0, 0xef, 0x29, 0xa3, 0x05, + 0x51, 0xd0, 0x8c, 0x9b, 0xf2, 0xd3, 0x58, 0x4d, 0xf1, 0x41, 0x9d, 0xd5, + 0x98, 0x0e, 0xf9, 0x3c, 0x53, 0x0d, 0xb5, 0x83, 0xbe, 0x64, 0x3c, 0x98, + 0x93, 0xd4, 0x0a, 0xad, 0x0a, 0x7e, 0x4d, 0x68, 0xa6, 0x1c, 0x1f, 0x47, + 0x03, 0xfb, 0xa1, 0x22, 0x65, 0xc4, 0x5c, 0x8a, 0x33, 0x30, 0x0a, 0x55, + 0xa3, 0xef, 0xfd, 0x22, 0x88, 0x37, 0x32, 0xfd, 0x7b, 0xf2, 0xd2, 0x2f, + 0xff, 0xf2, 0x18, 0x50, 0x05, 0xa0, 0xc9, 0x0a, 0x8b, 0x16, 0x5e, 0x49, + 0x05, 0x19, 0x36, 0x48, 0xbb, 0xa1, 0xff, 0x61, 0x38, 0x29, 0x62, 0x01, + 0x13, 0xcc, 0x3c, 0x4d, 0xb8, 0xbe, 0x27, 0xef, 0x8a, 0xeb, 0xc6, 0xe2, + 0x49, 0x35, 0xc8, 0x50, 0x4d, 0x04, 0x74, 0x91, 0xa6, 0x3e, 0x52, 0x7b, + 0x60, 0x94, 0xe6, 0xfa, 0xa8, 0xe2, 0xb9, 0x94, 0x05, 0xe7, 0x45, 0x47, + 0x9b, 0xf8, 0x23, 0x97, 0x2d, 0x56, 0xc2, 0xca, 0x41, 0xba, 0x1f, 0x34, + 0x7a, 0x64, 0x03, 0x1f, 0x62, 0xda, 0x1b, 0x48, 0x48, 0x70, 0x83, 0x28, + 0xdf, 0x59, 0x32, 0x1d, 0x99, 0x6c, 0xdb, 0x14, 0x38, 0x73, 0xea, 0xe9, + 0x81, 0xd1, 0xde, 0x0c, 0x53, 0x1e, 0xb1, 0x11, 0xdc, 0x32, 0xf8, 0x03, + 0xcf, 0x63, 0x4d, 0x64, 0x89, 0x6b, 0x7f, 0x8c, 0x92, 0xc8, 0x7e, 0x03, + 0x31, 0x34, 0xad, 0x8c, 0x7a, 0xfb, 0x04, 0xe2, 0xeb, 0x04, 0x44, 0x3c, + 0xe9, 0x0f, 0x0d, 0x2f, 0x45, 0x93, 0xb2, 0x9d, 0xd2, 0x22, 0x10, 0xd0, + 0xa8, 0xed, 0xfe, 0x00, 0x0d, 0x76, 0xb4, 0x3d, 0x93, 0x95, 0x4d, 0xaa, + 0x31, 0xcb, 0x71, 0xa1, 0x53, 0x6c, 0x39, 0x5b, 0xf1, 0x7e, 0x1a, 0xee, + 0x48, 0xbb, 0x8c, 0x31, 0x04, 0x5b, 0x36, 0xeb, 0x2e, 0x66, 0x4e, 0x58, + 0xf5, 0x99, 0x61, 0x60, 0x41, 0xd3, 0xa3, 0x88, 0xd8, 0x1e, 0x83, 0x4e, + 0x92, 0x72, 0xbf, 0x5e, 0x62, 0x27, 0xb4, 0xf7, 0x46, 0x32, 0xba, 0x71, + 0x3a, 0xa0, 0xb8, 0x3b, 0x85, 0x65, 0x4d, 0x65, 0xf4, 0x99, 0xe6, 0xe2, + 0x46, 0xc7, 0x4c, 0x11, 0xf9, 0xbe, 0x79, 0x67, 0xba, 0x9e, 0x6a, 0x12, + 0x13, 0x89, 0x43, 0x4b, 0x5e, 0x65, 0x14, 0x06, 0x4b, 0x29, 0x21, 0x64, + 0xde, 0x74, 0x85, 0x6b, 0xca, 0x96, 0x34, 0x5d, 0x79, 0x8b, 0xe4, 0x50, + 0x1b, 0x83, 0x31, 0x72, 0xde, 0x62, 0x16, 0xe5, 0x16, 0x67, 0x90, 0x4e, + 0x41, 0x60, 0x31, 0xed, 0xbb, 0x6f, 0xbe, 0x91, 0xdd, 0x20, 0x24, 0x27, + 0x73, 0xa7, 0x93, 0x70, 0x61, 0x49, 0x0a, 0xcd, 0x0a, 0xe8, 0xe4, 0x56, + 0x52, 0x1d, 0x98, 0x43, 0x40, 0x06, 0x11, 0x8c, 0x28, 0x15, 0x84, 0xd2, + 0xe7, 0x71, 0xb0, 0x78, 0x08, 0x49, 0xac, 0x74, 0x8f, 0x03, 0x34, 0x60, + 0xaf, 0x42, 0xaa, 0x61, 0xb8, 0xe0, 0xa2, 0x61, 0x45, 0x1a, 0xc9, 0x7b, + 0x09, 0x27, 0x94, 0x1d, 0x18, 0x79, 0x96, 0x72, 0x03, 0xad, 0x3b, 0x85, + 0x9c, 0x64, 0xc0, 0x6d, 0x1d, 0x9d, 0xf2, 0x92, 0xe8, 0xd9, 0x6e, 0x54, + 0x75, 0xfa, 0xe0, 0xd7, 0x11, 0xd9, 0x5b, 0x59, 0x2c, 0x1d, 0xf7, 0x4f, + 0x18, 0xe8, 0x03, 0x5f, 0x74, 0xea, 0x59, 0xdf, 0xd9, 0xdd, 0xdf, 0x7c, + 0x89, 0x38, 0x73, 0xcf, 0x0c, 0xe3, 0x02, 0x77, 0xea, 0xab, 0xf3, 0x43, + 0x24, 0xa6, 0xc9, 0xa5, 0x8b, 0xf1, 0x84, 0xcb, 0x4f, 0x3f, 0xf4, 0xda, + 0xad, 0xe2, 0x2c, 0xb6, 0x6c, 0x8d, 0x39, 0xd1, 0x17, 0x5d, 0xa0, 0xf3, + 0x04, 0x55, 0x0b, 0x55, 0xa6, 0x54, 0x63, 0xa4, 0xab, 0x63, 0x74, 0x74, + 0xc4, 0xba, 0x04, 0x80, 0xf4, 0x0c, 0x6b, 0x79, 0x4f, 0xc2, 0xb4, 0x9c, + 0x64, 0x82, 0x78, 0xc0, 0xe8, 0x55, 0xb1, 0x71, 0x7b, 0x89, 0x88, 0xc4, + 0x23, 0xa1, 0x48, 0x02, 0xac, 0x7b, 0x56, 0x84, 0xcb, 0xa7, 0x04, 0x8c, + 0xb9, 0x66, 0x24, 0x36, 0x6a, 0x08, 0x78, 0x98, 0xd1, 0x24, 0x73, 0x91, + 0x69, 0xca, 0x40, 0x0c, 0x77, 0xbe, 0xa7, 0x84, 0x4b, 0x19, 0x40, 0x9a, + 0x3c, 0x8e, 0x5e, 0xa2, 0xe9, 0x10, 0xba, 0x3a, 0x8b, 0xd0, 0xc4, 0x28, + 0x0c, 0x88, 0xd9, 0x9a, 0x05, 0x30, 0xff, 0xfe, 0x8d, 0x90, 0x48, 0x49, + 0xe1, 0xc4, 0x23, 0x78, 0x18, 0x21, 0x8a, 0x2b, 0x67, 0xe7, 0xa8, 0xc2, + 0x67, 0x52, 0x32, 0xab, 0xe2, 0xed, 0x60, 0x36, 0x70, 0x4b, 0x19, 0x2c, + 0xd2, 0x5a, 0x8c, 0x2c, 0xe1, 0x00, 0x27, 0xf3, 0x02, 0x5e, 0xd5, 0x4a, + 0x05, 0x6d, 0xad, 0x50, 0x10, 0xce, 0x99, 0x95, 0xf7, 0x10, 0x4e, 0xa9, + 0xda, 0x0d, 0x71, 0x35, 0x25, 0x88, 0x2a, 0xaa, 0xbe, 0x0b, 0x0b, 0x4b, + 0x69, 0xfa, 0x4f, 0xd0, 0x35, 0xcd, 0xde, 0x05, 0x1c, 0x9d, 0x83, 0xfe, + 0xb1, 0xd9, 0x8c, 0xe6, 0xc3, 0xea, 0x28, 0xa4, 0x96, 0xe6, 0xa9, 0x59, + 0x02, 0x60, 0x22, 0xbd, 0x61, 0x39, 0x60, 0x92, 0x4b, 0x40, 0x55, 0x29, + 0x7b, 0x87, 0xd5, 0x0c, 0x97, 0x94, 0xc9, 0x64, 0xe5, 0xf9, 0x08, 0x76, + 0xb0, 0xc1, 0x20, 0xe9, 0xa6, 0x4e, 0x2a, 0x83, 0xc0, 0xea, 0x54, 0x9e, + 0x67, 0x83, 0x38, 0x2a, 0x8f, 0xce, 0xc2, 0x8e, 0x2f, 0xe5, 0x18, 0x34, + 0xc9, 0xe0, 0x71, 0xd5, 0x1c, 0x20, 0x29, 0xc8, 0x66, 0xb0, 0x2e, 0x9f, + 0x75, 0xf6, 0x51, 0x38, 0x41, 0x3d, 0x64, 0x7a, 0x55, 0x22, 0x09, 0x5c, + 0x31, 0x7c, 0xdb, 0x5a, 0x48, 0x22, 0x2c, 0x18, 0x74, 0xf2, 0x70, 0xbc, + 0x6c, 0x63, 0x79, 0x6a, 0xce, 0xeb, 0x53, 0x6b, 0x4f, 0xc2, 0xad, 0xce, + 0x91, 0xef, 0x7d, 0x9a, 0x8d, 0xe4, 0x59, 0xf7, 0xd9, 0x93, 0x38, 0x14, + 0x44, 0x6a, 0x99, 0x6e, 0x87, 0xd7, 0xc2, 0x94, 0xab, 0x31, 0xb3, 0xfc, + 0xf0, 0x4d, 0x41, 0x5d, 0x4f, 0x47, 0x13, 0x97, 0xed, 0xba, 0xc6, 0x8c, + 0xc7, 0x1e, 0x88, 0xe3, 0x04, 0x29, 0x10, 0xda, 0x2c, 0x2c, 0x1b, 0xe7, + 0x65, 0x8a, 0x76, 0x91, 0xa0, 0x19, 0x59, 0xb5, 0x79, 0xc9, 0x77, 0x4a, + 0xb2, 0x3e, 0xd4, 0xd7, 0xb6, 0xa0, 0x69, 0xfb, 0x60, 0x55, 0x7d, 0xf3, + 0x7e, 0xc9, 0xd5, 0xc2, 0x48, 0x43, 0xda, 0x33, 0xe4, 0x1e, 0x1c, 0x15, + 0x56, 0x07, 0x2e, 0x29, 0x3f, 0x10, 0x5a, 0xc8, 0x53, 0x50, 0x35, 0xba, + 0xcb, 0xb8, 0xa8, 0x25, 0xbb, 0x20, 0x71, 0x9e, 0xcd, 0x8a, 0xc0, 0x32, + 0x95, 0x78, 0x0e, 0xf0, 0x31, 0xd2, 0xc8, 0xf9, 0xa1, 0xdd, 0x01, 0x49, + 0xfc, 0xb0, 0x36, 0x2b, 0x42, 0x44, 0x9a, 0xe0, 0x6a, 0xfb, 0x72, 0x32, + 0xb9, 0x38, 0x08, 0x1b, 0x37, 0xbe, 0x3a, 0x00, 0x8a, 0x8b, 0xad, 0x87, + 0xe5, 0x2e, 0x14, 0x84, 0x76, 0x91, 0x19, 0xc9, 0xe9, 0x45, 0x9a, 0x0f, + 0x34, 0x05, 0xf1, 0xaa, 0x0f, 0x46, 0x62, 0x6e, 0x1d, 0x89, 0xe8, 0xa6, + 0xb3, 0x51, 0xe4, 0x10, 0x24, 0xb2, 0xe5, 0x20, 0xc1, 0x32, 0x8c, 0x03, + 0x8b, 0x1b, 0x5a, 0x93, 0xf8, 0xa0, 0xd1, 0xe1, 0x3f, 0x20, 0x51, 0x68, + 0xea, 0x47, 0x20, 0x63, 0x8a, 0x6a, 0x8e, 0x5a, 0xeb, 0x32, 0x9b, 0x87, + 0x1f, 0xab, 0xac, 0x86, 0x03, 0xec, 0x7b, 0xfe, 0x1e, 0xf2, 0xb6, 0xc8, + 0xc8, 0x49, 0xc2, 0x25, 0x84, 0xa5, 0x71, 0x79, 0x05, 0xfc, 0x32, 0x06, + 0x56, 0x98, 0x9f, 0x9f, 0x72, 0x1a, 0xf0, 0x05, 0x16, 0xdc, 0xa8, 0xe5, + 0x92, 0xa1, 0x90, 0x6f, 0x44, 0xfb, 0x8a, 0x9e, 0x38, 0xca, 0xf4, 0x60, + 0x26, 0x4a, 0x60, 0xb2, 0xf2, 0xe1, 0xe0, 0x3f, 0x12, 0x1a, 0xe3, 0xd2, + 0x99, 0xbc, 0x46, 0x33, 0x64, 0x52, 0xc4, 0x24, 0x74, 0x1d, 0x04, 0x91, + 0x6a, 0x8c, 0xbe, 0xdb, 0x12, 0x64, 0xa6, 0xf5, 0x6e, 0x24, 0x1d, 0x45, + 0x86, 0x83, 0xab, 0xb6, 0x0c, 0x93, 0x42, 0x4c, 0x86, 0xd5, 0x61, 0xbe, + 0xec, 0x33, 0x72, 0x76, 0xf3, 0x13, 0x4a, 0x94, 0x49, 0xfc, 0xce, 0x14, + 0x05, 0x7a, 0x19, 0x76, 0x96, 0x56, 0x1a, 0xaf, 0x40, 0x8c, 0x58, 0x81, + 0xd3, 0xf1, 0x68, 0x7a, 0x21, 0x09, 0xe7, 0x31, 0x1f, 0x2b, 0x5e, 0x1a, + 0x72, 0x62, 0xe0, 0xc8, 0xd6, 0x2a, 0xd5, 0x82, 0x99, 0xc1, 0xe9, 0x85, + 0x16, 0xa2, 0xa5, 0x38, 0x0a, 0x30, 0xdc, 0x28, 0xae, 0x65, 0x37, 0x29, + 0xc0, 0x74, 0x90, 0x1e, 0xcd, 0xe4, 0x6c, 0x26, 0x9b, 0x27, 0xf8, 0x0a, + 0x22, 0x7a, 0xd1, 0xab, 0x70, 0xc2, 0x50, 0x79, 0xcf, 0xf1, 0x52, 0x18, + 0x9a, 0x85, 0x98, 0x77, 0x64, 0xe0, 0x20, 0x61, 0x9e, 0x81, 0x82, 0x96, + 0xea, 0x08, 0xf8, 0xdc, 0xe8, 0x9a, 0xdc, 0x6c, 0x96, 0x31, 0xb0, 0x47, + 0x76, 0x88, 0xfe, 0xa4, 0x3b, 0x9d, 0x05, 0xd9, 0x6d, 0x1c, 0xdb, 0x12, + 0x29, 0x2a, 0x68, 0xa8, 0x0b, 0xb4, 0x3a, 0x2f, 0x4b, 0xbc, 0x20, 0x89, + 0xbd, 0x51, 0x04, 0x3e, 0xeb, 0x39, 0x5a, 0x64, 0x64, 0xc3, 0xc3, 0x67, + 0xee, 0x16, 0xf4, 0x7e, 0x9d, 0xc5, 0x0c, 0xae, 0x32, 0x4b, 0xc3, 0x0d, + 0xb4, 0x0f, 0xd2, 0x8f, 0x37, 0xde, 0x87, 0xea, 0xaa, 0x6e, 0xb0, 0xb2, + 0x95, 0xc8, 0xca, 0x68, 0x4d, 0x39, 0xe8, 0x5f, 0xd8, 0x20, 0xb6, 0xf6, + 0x18, 0x1b, 0x41, 0x8c, 0x66, 0x8b, 0xed, 0x51, 0x3c, 0x9e, 0x0c, 0x7d, + 0x87, 0xac, 0x43, 0x8e, 0x0f, 0x6e, 0xc1, 0x63, 0x62, 0x41, 0xa7, 0x17, + 0x4c, 0xc7, 0xf4, 0x78, 0xf5, 0x4c, 0x6d, 0xed, 0x7d, 0x7c, 0x8c, 0xad, + 0x80, 0xd1, 0xbc, 0x9b, 0x75, 0x8e, 0xcb, 0xd0, 0xba, 0x97, 0xae, 0x78, + 0x3d, 0x46, 0x43, 0x81, 0x94, 0xb2, 0x4c, 0xfb, 0xa3, 0x30, 0x18, 0x3b, + 0xb3, 0xf6, 0xb4, 0xd2, 0x4a, 0xba, 0x9e, 0x0a, 0x05, 0x23, 0x37, 0xa3, + 0xee, 0x5e, 0xa6, 0xa7, 0x29, 0x8f, 0xb0, 0x3c, 0x04, 0x59, 0x27, 0x10, + 0x2f, 0x57, 0x2a, 0xb9, 0xcc, 0xc2, 0x78, 0x0e, 0x5c, 0x64, 0xd8, 0xf1, + 0xc1, 0x59, 0x46, 0x59, 0x22, 0x39, 0xd4, 0x31, 0x06, 0xcd, 0xa8, 0x93, + 0xd8, 0xef, 0x9e, 0xb1, 0xd5, 0x8d, 0x7e, 0xb6, 0x44, 0x8e, 0x90, 0x85, + 0x75, 0x31, 0xc2, 0xe5, 0x08, 0x17, 0x23, 0x52, 0x39, 0x02, 0x73, 0x74, + 0x49, 0x22, 0x02, 0x91, 0x5f, 0x27, 0x46, 0x70, 0xf0, 0xb2, 0x5e, 0x8d, + 0xf1, 0x07, 0xfd, 0xdc, 0x56, 0xb2, 0x16, 0xfc, 0x48, 0x5d, 0x25, 0x5d, + 0x9f, 0xe6, 0x99, 0x41, 0x4b, 0xca, 0x2b, 0x92, 0x23, 0x73, 0x28, 0x8c, + 0x27, 0x39, 0xb0, 0x69, 0x94, 0xdb, 0xec, 0xaa, 0xdb, 0x8a, 0x43, 0xf2, + 0x41, 0x6a, 0x58, 0xc9, 0x95, 0x40, 0xb4, 0x74, 0xc9, 0xea, 0x4f, 0x82, + 0x24, 0x15, 0x74, 0xd7, 0x18, 0x1f, 0x42, 0x59, 0x7d, 0x52, 0x4e, 0xa6, + 0xb5, 0xf8, 0x83, 0xb7, 0x7a, 0x94, 0x9a, 0xc1, 0xa9, 0xb4, 0xb3, 0x06, + 0x95, 0x3f, 0xca, 0xa7, 0x6f, 0x8d, 0x36, 0xe6, 0xef, 0x1f, 0xeb, 0x91, + 0x03, 0xcf, 0x16, 0x5d, 0x2f, 0x32, 0xad, 0xc6, 0xe1, 0x95, 0xd6, 0x58, + 0x6d, 0xb5, 0xd9, 0x96, 0x94, 0x60, 0x85, 0x26, 0x21, 0x71, 0x0d, 0x9a, + 0xe7, 0xe5, 0x65, 0xe2, 0x5a, 0xb8, 0x49, 0xc3, 0x25, 0xd9, 0x92, 0x38, + 0x0c, 0x18, 0xff, 0x43, 0x0b, 0x82, 0x9b, 0xb1, 0x94, 0x1b, 0xff, 0x6c, + 0xec, 0x81, 0xd4, 0x21, 0xe2, 0xd8, 0x62, 0xa7, 0x08, 0x01, 0x89, 0x7a, + 0x44, 0x22, 0x82, 0x1f, 0x7c, 0x68, 0x25, 0xb8, 0xa2, 0x2a, 0x24, 0xda, + 0x07, 0xa9, 0x5a, 0x2a, 0x96, 0xfe, 0x5c, 0x8d, 0x47, 0xaa, 0x7e, 0x5c, + 0x2b, 0xe3, 0x90, 0x93, 0x1d, 0xd4, 0xf5, 0x00, 0x6c, 0xaa, 0x7f, 0x72, + 0x15, 0x66, 0x5c, 0x6b, 0x4d, 0xc8, 0x7d, 0xb9, 0x3a, 0x6b, 0x46, 0xa5, + 0x33, 0x6e, 0x8a, 0x94, 0x2b, 0x7e, 0x37, 0x79, 0x11, 0x91, 0x9f, 0x05, + 0xeb, 0x76, 0x5d, 0x54, 0x2c, 0x4d, 0x96, 0x1c, 0x8f, 0xd0, 0x02, 0x9b, + 0xf4, 0x02, 0x69, 0xc6, 0xea, 0x5c, 0x0c, 0xec, 0xc2, 0x4e, 0x6b, 0x4e, + 0x13, 0x06, 0x50, 0xc5, 0xa7, 0x45, 0xb1, 0x5b, 0x88, 0x5a, 0x5d, 0x37, + 0x1b, 0x30, 0x35, 0xd5, 0xf0, 0xfd, 0x5b, 0xce, 0xb9, 0x2e, 0x1e, 0xda, + 0x72, 0x78, 0xc8, 0x60, 0x5c, 0x18, 0x51, 0x47, 0xe4, 0xc5, 0x14, 0xce, + 0xa4, 0x58, 0xe9, 0x4a, 0xa5, 0x49, 0x88, 0x45, 0x80, 0x7c, 0x89, 0x89, + 0x8a, 0x50, 0x04, 0x58, 0x56, 0x9d, 0x81, 0xf8, 0x65, 0xd1, 0xda, 0xd9, + 0xdd, 0x7b, 0xbb, 0xfb, 0xe3, 0x5f, 0x5b, 0x10, 0x70, 0xe0, 0x43, 0x34, + 0x9c, 0x95, 0x63, 0xd5, 0x0a, 0x00, 0xd1, 0x62, 0x00, 0x6a, 0xd0, 0x3d, + 0xb3, 0x5d, 0x7e, 0x16, 0x97, 0xdb, 0xc8, 0xf0, 0x40, 0x03, 0x99, 0x19, + 0x0c, 0x0f, 0xc9, 0x21, 0xe5, 0x4f, 0x72, 0xf3, 0xf1, 0x90, 0x7a, 0x46, + 0x66, 0xa7, 0x63, 0x75, 0xda, 0x45, 0x72, 0x12, 0xda, 0xe5, 0x45, 0x68, + 0x84, 0xbd, 0x34, 0xb2, 0x52, 0x0c, 0xb0, 0xf0, 0x7f, 0xea, 0xf0, 0x1b, + 0x0a, 0x9e, 0x81, 0x3b, 0x0a, 0xf2, 0x44, 0xf8, 0x3b, 0x86, 0xb7, 0x33, + 0x9c, 0x42, 0xc7, 0x2f, 0x94, 0xcc, 0x28, 0xea, 0xd2, 0x07, 0x59, 0x5c, + 0x32, 0xcb, 0x97, 0xe6, 0xd6, 0x53, 0xd6, 0x4f, 0x1e, 0x75, 0x7d, 0x1e, + 0x50, 0x6f, 0x9d, 0x5a, 0xdf, 0xca, 0xbf, 0x2f, 0x5d, 0x42, 0x98, 0x11, + 0xeb, 0x73, 0x02, 0x7c, 0x9a, 0xae, 0x08, 0x84, 0xbf, 0xe4, 0x6a, 0x52, + 0x69, 0x30, 0xdc, 0x50, 0x76, 0x41, 0x65, 0x97, 0xc3, 0xb5, 0xb7, 0x43, + 0x98, 0x36, 0xae, 0xa6, 0xcf, 0xde, 0x46, 0xda, 0x61, 0x7a, 0x1d, 0x69, + 0x97, 0xbf, 0xf6, 0x3e, 0x32, 0x66, 0x78, 0x87, 0xe2, 0x8d, 0x13, 0xef, + 0x12, 0xf9, 0x0a, 0xd4, 0x6e, 0x78, 0x0c, 0x87, 0x8e, 0x2b, 0xc4, 0xbe, + 0x5a, 0x6e, 0x65, 0x13, 0x14, 0x1d, 0xef, 0x9b, 0xa8, 0x0d, 0x06, 0x4b, + 0x04, 0x48, 0xa2, 0x51, 0x20, 0x01, 0x81, 0x4b, 0xd0, 0xec, 0x96, 0xe8, + 0x02, 0x5c, 0xb6, 0xa4, 0x0f, 0x3b, 0x73, 0xd7, 0x89, 0x22, 0xa8, 0xe5, + 0x7d, 0x70, 0x1c, 0x06, 0x01, 0xa0, 0x27, 0xeb, 0x6a, 0x32, 0x9a, 0x20, + 0x67, 0xf9, 0x3c, 0x4c, 0x43, 0xb8, 0x44, 0x92, 0x82, 0x20, 0x5c, 0xd6, + 0xde, 0xe0, 0x79, 0x77, 0x55, 0x48, 0xf5, 0x4c, 0x94, 0x40, 0xd7, 0xa5, + 0x06, 0x4a, 0xd7, 0x03, 0x31, 0x17, 0x19, 0xa7, 0xb0, 0x55, 0x18, 0xc3, + 0x9e, 0xc5, 0xd0, 0x31, 0xa9, 0xce, 0xa0, 0x32, 0x6c, 0x3a, 0x2e, 0xf9, + 0x6c, 0xee, 0xa8, 0x7c, 0x50, 0xda, 0x51, 0x1c, 0xd0, 0xdc, 0x96, 0xec, + 0xca, 0xba, 0xb1, 0xa9, 0x38, 0xbd, 0xd4, 0xe0, 0x9f, 0x09, 0x19, 0x69, + 0x9b, 0x02, 0x8e, 0x75, 0xdb, 0x26, 0x1d, 0x20, 0x2f, 0x5b, 0x2e, 0xb6, + 0x84, 0x68, 0x94, 0xdf, 0xba, 0x5c, 0x81, 0x55, 0x1f, 0xcf, 0xec, 0x63, + 0x09, 0x0f, 0xd8, 0x69, 0x5c, 0x1c, 0x79, 0x2c, 0xd1, 0x6a, 0x03, 0x9f, + 0xae, 0xa7, 0x63, 0x8d, 0x4e, 0x34, 0x98, 0x3c, 0x3a, 0x91, 0x42, 0x0b, + 0xf6, 0x56, 0xb7, 0x78, 0xcd, 0xb9, 0xc0, 0x07, 0x2f, 0x41, 0x69, 0x79, + 0xaf, 0xf9, 0x3a, 0x58, 0x9f, 0x06, 0x95, 0xd7, 0xec, 0xf2, 0xe6, 0x3e, + 0xe5, 0xad, 0x1b, 0x7a, 0xbc, 0xee, 0x4e, 0xd3, 0x2b, 0xcd, 0x64, 0x5c, + 0x5c, 0x5f, 0x72, 0x7b, 0xa5, 0x56, 0xa1, 0xd9, 0xab, 0x4b, 0x4f, 0x47, + 0x72, 0x7b, 0x5d, 0x7b, 0x79, 0x61, 0x33, 0x66, 0x6f, 0x2e, 0x71, 0x3b, + 0x60, 0x14, 0xdf, 0x8a, 0x66, 0xca, 0x1c, 0xbe, 0x51, 0x9f, 0x07, 0x67, + 0xd8, 0xb6, 0xaa, 0xac, 0xd1, 0xea, 0x9b, 0x5e, 0xfc, 0xa9, 0xcb, 0x03, + 0x07, 0xc7, 0x9c, 0x1e, 0x73, 0xae, 0xf7, 0xa7, 0x89, 0x44, 0x24, 0xbe, + 0xbf, 0x3b, 0xee, 0xd3, 0xa3, 0xff, 0x25, 0xae, 0xa2, 0x6f, 0x65, 0x5e, + 0xc4, 0x39, 0xd3, 0x2e, 0x52, 0x07, 0x8c, 0x59, 0xab, 0xa4, 0x85, 0x70, + 0x9b, 0x05, 0xb9, 0x0f, 0x72, 0xac, 0x7a, 0x23, 0xe5, 0x13, 0x4b, 0xad, + 0x96, 0x4a, 0x04, 0xd7, 0x4e, 0x06, 0x1c, 0xec, 0x20, 0x68, 0xbc, 0x0d, + 0x55, 0xae, 0x90, 0x02, 0xf0, 0xc4, 0xc0, 0x25, 0x05, 0x20, 0x95, 0x4c, + 0xd2, 0x86, 0x47, 0x1f, 0x32, 0xcf, 0x0d, 0x05, 0x50, 0x64, 0xa8, 0x4c, + 0xfa, 0x03, 0x63, 0x41, 0x61, 0xfb, 0x1f, 0xf4, 0x7a, 0xdf, 0x3f, 0xa8, + 0x26, 0x47, 0x5e, 0xc3, 0xe8, 0x41, 0x04, 0x5d, 0x50, 0xbc, 0x15, 0x81, + 0x65, 0xd1, 0x7b, 0xa2, 0xe0, 0x75, 0xef, 0xfc, 0xd2, 0x9d, 0xa9, 0xdd, + 0x74, 0x9c, 0x8d, 0x41, 0xca, 0x18, 0x0b, 0xc6, 0x2c, 0xeb, 0x18, 0x7d, + 0x88, 0x71, 0x84, 0xd9, 0x00, 0xa5, 0x18, 0xd5, 0xfa, 0x5e, 0x54, 0xb8, + 0x1a, 0xb0, 0xb5, 0x1c, 0x05, 0x6e, 0x7d, 0x55, 0x47, 0x41, 0x76, 0xf3, + 0x07, 0x03, 0xd1, 0x64, 0x10, 0xba, 0x9a, 0x5e, 0xe4, 0xe3, 0xc9, 0xd6, + 0xac, 0x3f, 0x49, 0x57, 0x2c, 0x59, 0xb0, 0x64, 0x38, 0x59, 0x88, 0x22, + 0x13, 0x67, 0xae, 0xed, 0xf3, 0x22, 0x8c, 0xce, 0x38, 0x52, 0xda, 0xab, + 0xf7, 0xe3, 0xdd, 0x34, 0x7b, 0xa1, 0xda, 0x0d, 0xa6, 0x28, 0x71, 0x3c, + 0x92, 0x0c, 0x14, 0x5a, 0xd0, 0xa8, 0x37, 0x5a, 0xb9, 0xcf, 0xfb, 0x47, + 0xe3, 0x91, 0x0e, 0x3d, 0x97, 0xb6, 0x1e, 0xae, 0x34, 0x28, 0xe6, 0x02, + 0xa2, 0xf8, 0xec, 0x38, 0x7e, 0xc5, 0xec, 0xc5, 0xad, 0xbc, 0x90, 0x79, + 0x1f, 0xa0, 0xa3, 0x4f, 0x19, 0x01, 0xc4, 0x38, 0x1e, 0xcb, 0x66, 0x3d, + 0x45, 0xa6, 0x8a, 0x9f, 0x10, 0x0f, 0xf0, 0x93, 0xfc, 0x8b, 0x85, 0x30, + 0xa4, 0x4e, 0x92, 0x35, 0x41, 0x13, 0xb9, 0x87, 0xbd, 0x6b, 0x19, 0x4b, + 0xcf, 0x76, 0xcc, 0x0a, 0xfb, 0x1e, 0xe9, 0x51, 0xa2, 0xac, 0x1b, 0x21, + 0xe5, 0xec, 0x32, 0x87, 0xf9, 0xa3, 0x3f, 0xfc, 0x88, 0xe8, 0xcf, 0x7c, + 0x37, 0x4c, 0xa6, 0x9b, 0xa5, 0xc7, 0xf9, 0x87, 0x46, 0x73, 0x45, 0xa2, + 0xc4, 0xda, 0x97, 0x50, 0x82, 0xea, 0xa2, 0xa6, 0xd6, 0x6c, 0x97, 0x8b, + 0x3a, 0x2c, 0x85, 0xb8, 0xda, 0x7e, 0x82, 0xda, 0xcc, 0x4e, 0x8e, 0x0b, + 0x25, 0x99, 0x1f, 0xbe, 0x0d, 0x0b, 0x0b, 0x8a, 0x35, 0x63, 0xeb, 0x3a, + 0x2c, 0x07, 0xfa, 0xb5, 0x7a, 0x67, 0x64, 0x69, 0x55, 0x63, 0x44, 0x9e, + 0x4c, 0x36, 0x8b, 0x56, 0x23, 0x07, 0x50, 0xe8, 0x4f, 0xa3, 0xa3, 0xc9, + 0xb1, 0x41, 0x68, 0xac, 0x00, 0x60, 0xd6, 0xb8, 0x64, 0x1e, 0x75, 0xb6, + 0x32, 0xec, 0xe3, 0x5a, 0x02, 0xc9, 0x16, 0x67, 0xee, 0x69, 0xcd, 0xe8, + 0x63, 0x4c, 0xe9, 0xcd, 0x68, 0xd7, 0xec, 0x03, 0xdd, 0x26, 0x1d, 0x34, + 0xe9, 0x52, 0x3c, 0xe1, 0xc4, 0x74, 0x10, 0xae, 0xc4, 0xf1, 0xb3, 0x0f, + 0xb1, 0x3b, 0x20, 0x51, 0x40, 0xbc, 0x40, 0x41, 0x7e, 0xc3, 0x96, 0xab, + 0x97, 0x54, 0xee, 0xb2, 0x6c, 0x3e, 0x94, 0x2e, 0x72, 0x51, 0x63, 0x76, + 0x36, 0xae, 0x6a, 0xd3, 0x19, 0x1a, 0x91, 0xa7, 0x71, 0xf4, 0x22, 0xe5, + 0xa8, 0x92, 0xb2, 0xaf, 0x70, 0x7a, 0xd1, 0x48, 0x56, 0x51, 0xf7, 0xb9, + 0x5e, 0xab, 0x64, 0x91, 0xf5, 0x4c, 0x24, 0x55, 0x59, 0xd4, 0x20, 0xeb, + 0x26, 0xb7, 0x68, 0x32, 0x1c, 0xe5, 0xbc, 0x45, 0xa4, 0x74, 0xb8, 0x05, + 0x1e, 0xa8, 0x23, 0xbf, 0xa9, 0x35, 0x83, 0x46, 0xb1, 0x16, 0x23, 0xc4, + 0x96, 0xc0, 0x7d, 0x1b, 0x3c, 0x5f, 0x44, 0x40, 0x13, 0x81, 0xdd, 0x9a, + 0xce, 0xad, 0xba, 0x33, 0xcd, 0x6b, 0xa2, 0x9e, 0xb5, 0xae, 0xff, 0xfe, + 0xb6, 0x21, 0x83, 0xe1, 0xbb, 0xd9, 0x0b, 0xcc, 0xff, 0xb7, 0x2d, 0x40, + 0xa2, 0x01, 0xcd, 0x51, 0x7d, 0xe6, 0xb7, 0xb7, 0x25, 0x88, 0x0e, 0xc9, + 0xf3, 0x1a, 0x4f, 0x99, 0x60, 0x34, 0x48, 0xc4, 0x80, 0xad, 0x9d, 0x69, + 0x21, 0x38, 0x00, 0xd4, 0x61, 0xda, 0xa6, 0x6f, 0xc8, 0x37, 0xf7, 0xc1, + 0x50, 0x1c, 0xdc, 0x33, 0x19, 0x87, 0x04, 0x5d, 0x5e, 0x0e, 0x3f, 0xb3, + 0x8b, 0xd1, 0x0b, 0x41, 0xe7, 0xc3, 0x6f, 0x5a, 0x12, 0x62, 0xf9, 0x59, + 0x73, 0x39, 0xc8, 0xe2, 0xaf, 0x6a, 0xef, 0x24, 0xc8, 0xb7, 0x44, 0x05, + 0xd3, 0x26, 0xed, 0xff, 0x3b, 0xa2, 0xb1, 0x9f, 0x83, 0x3e, 0x1a, 0x9d, + 0x86, 0xf8, 0x0f, 0x0e, 0xbf, 0xdf, 0x32, 0xe2, 0xea, 0xf3, 0xc7, 0x36, + 0x9a, 0xaa, 0x8b, 0x25, 0xb0, 0x8b, 0xe5, 0xbc, 0x13, 0xef, 0x25, 0xf3, + 0x76, 0xce, 0xf6, 0x33, 0xff, 0x30, 0xdf, 0xdc, 0xc9, 0x97, 0xf7, 0xd2, + 0x3c, 0xe4, 0xf3, 0x4e, 0x79, 0xb3, 0x43, 0xeb, 0x31, 0xe9, 0x52, 0x25, + 0xbd, 0x5b, 0x2d, 0xe0, 0x2d, 0x0e, 0xfe, 0xdd, 0xac, 0xe0, 0x7c, 0x6e, + 0x70, 0xe7, 0x2b, 0x78, 0x33, 0x97, 0xf8, 0x82, 0xb9, 0x08, 0xeb, 0x48, + 0xdb, 0x90, 0x3b, 0xde, 0x18, 0x87, 0x04, 0x6e, 0x19, 0xd5, 0x2a, 0xe5, + 0x45, 0xae, 0x41, 0xa1, 0x27, 0x34, 0x6b, 0x5c, 0xa3, 0xf8, 0xb5, 0x3c, + 0xa3, 0xba, 0x86, 0x69, 0xdc, 0xf5, 0xca, 0xdd, 0xc0, 0x4c, 0xe6, 0x53, + 0xc1, 0xaf, 0x23, 0x83, 0x26, 0x8f, 0x99, 0xc7, 0x64, 0xee, 0x98, 0xc4, + 0x3f, 0xcf, 0x77, 0xae, 0xa7, 0x8a, 0x8c, 0x13, 0xdd, 0x38, 0xb5, 0xb0, + 0xa5, 0xa9, 0xf4, 0xc1, 0xa0, 0xa0, 0x4f, 0xa9, 0x17, 0x42, 0xb4, 0x59, + 0x93, 0xa1, 0xda, 0xc5, 0x4a, 0x87, 0x8f, 0x90, 0x71, 0xbe, 0x1b, 0x12, + 0xc3, 0x9e, 0x06, 0x5a, 0xa2, 0xa5, 0x23, 0x75, 0xb3, 0x4a, 0x82, 0xab, + 0xa4, 0x35, 0x8f, 0x89, 0x50, 0x1d, 0x76, 0x34, 0xee, 0x07, 0xc9, 0xbd, + 0xd0, 0x77, 0x0b, 0x01, 0xba, 0xcf, 0xc3, 0x36, 0x1a, 0x72, 0xce, 0x6c, + 0x70, 0xc0, 0x3c, 0x9e, 0x2b, 0x86, 0xbd, 0x68, 0xd0, 0xa1, 0x5d, 0xb1, + 0x11, 0x07, 0xc0, 0xfc, 0xd9, 0x05, 0xa9, 0xf0, 0x87, 0x40, 0x00, 0x03, + 0x77, 0x13, 0x53, 0x6f, 0x61, 0xf6, 0xdf, 0x97, 0x4d, 0x83, 0xce, 0xa7, + 0x30, 0xf9, 0x24, 0x76, 0x24, 0xda, 0x1d, 0x93, 0xc8, 0x11, 0xf7, 0xf1, + 0x41, 0xb5, 0x8a, 0x62, 0x39, 0x0c, 0x9a, 0xdd, 0xa2, 0x43, 0xeb, 0x79, + 0x38, 0x9c, 0xa9, 0x6e, 0xe3, 0x49, 0x0b, 0xe6, 0xb5, 0xb9, 0xaa, 0x04, + 0x5c, 0x5b, 0x20, 0xc9, 0xc3, 0x1d, 0x8f, 0x60, 0xb7, 0xfd, 0xcc, 0x03, + 0xd1, 0x3f, 0x16, 0x77, 0xb0, 0x05, 0x9c, 0x68, 0xa8, 0x89, 0x28, 0x12, + 0x31, 0xab, 0x25, 0x71, 0x97, 0x24, 0x61, 0x27, 0x85, 0xc1, 0x11, 0x2c, + 0xdc, 0x3a, 0xf0, 0x84, 0xc1, 0xdd, 0xd1, 0x76, 0x71, 0x63, 0x5d, 0xba, + 0xac, 0x12, 0xa6, 0x86, 0xdb, 0xce, 0xad, 0x1c, 0x31, 0x37, 0xb6, 0xfb, + 0xb2, 0xb8, 0x7f, 0xef, 0x97, 0xcc, 0xce, 0xfb, 0xaf, 0x9f, 0x86, 0xf7, + 0x6f, 0x07, 0x02, 0x96, 0x17, 0xda, 0xc2, 0xe6, 0x79, 0xe4, 0xfd, 0xa7, + 0x32, 0x68, 0x1e, 0x09, 0x2c, 0x4e, 0x5d, 0x52, 0xa9, 0x8e, 0xc5, 0x19, + 0x25, 0x94, 0xb9, 0x5d, 0x24, 0xe1, 0xca, 0x34, 0x94, 0x40, 0x77, 0x62, + 0x58, 0xc8, 0x79, 0x35, 0x29, 0x05, 0x34, 0xc3, 0x02, 0x95, 0x99, 0x43, + 0x86, 0x15, 0x90, 0xb0, 0x11, 0xf4, 0xd0, 0x0f, 0x8c, 0x95, 0x81, 0x08, + 0xeb, 0xf4, 0xe8, 0x4f, 0xac, 0x5e, 0x88, 0xe3, 0x46, 0xb3, 0xc1, 0x68, + 0x86, 0x56, 0xb0, 0xfa, 0x4f, 0xc7, 0xa7, 0x5d, 0x39, 0x10, 0xdd, 0xd0, + 0x71, 0x2b, 0x36, 0x45, 0x11, 0xaf, 0xad, 0x5a, 0x22, 0x8c, 0x9e, 0x6d, + 0xb3, 0xce, 0x29, 0xdc, 0x10, 0x22, 0x81, 0xe2, 0xea, 0x6a, 0xeb, 0x6a, + 0x24, 0x6d, 0x9d, 0x53, 0x4b, 0x09, 0x4f, 0xb4, 0x92, 0xd1, 0x75, 0x2d, + 0x4e, 0x4f, 0x86, 0xad, 0xf0, 0xa5, 0x9e, 0x09, 0x6f, 0x31, 0x7e, 0x17, + 0x8a, 0x4b, 0x65, 0x73, 0x4c, 0xa6, 0xd7, 0x66, 0xac, 0xcc, 0x65, 0x39, + 0x1e, 0x0a, 0xd4, 0x02, 0x2d, 0x53, 0xf5, 0x94, 0xdc, 0x60, 0xb6, 0x70, + 0x33, 0x57, 0xfe, 0xc6, 0x1a, 0x52, 0xd7, 0xa7, 0x4b, 0x27, 0x40, 0x50, + 0x4c, 0x9a, 0x66, 0x5b, 0x37, 0xa7, 0x06, 0x48, 0x77, 0x1d, 0xd9, 0x3a, + 0xd8, 0x3c, 0x6f, 0x45, 0x39, 0x1a, 0x8d, 0x23, 0xea, 0x5b, 0x4a, 0xe9, + 0xcd, 0x1a, 0x52, 0xdf, 0x6e, 0x6d, 0x6f, 0xf6, 0x84, 0xa8, 0xfe, 0xef, + 0x83, 0x2e, 0xfa, 0x1c, 0x1f, 0xc9, 0xbf, 0x1b, 0x7a, 0x49, 0x26, 0xa0, + 0x14, 0x6d, 0xc5, 0xcd, 0xb7, 0x8f, 0x08, 0xf0, 0x62, 0x50, 0xf9, 0x9b, + 0x3b, 0xef, 0xb7, 0xde, 0xee, 0xee, 0xbc, 0xd9, 0xdc, 0xd9, 0x97, 0x06, + 0xf6, 0xaf, 0x01, 0xa1, 0xaa, 0x23, 0x9e, 0x5c, 0x94, 0xfc, 0x2d, 0x68, + 0x45, 0xd1, 0x9f, 0x50, 0xa1, 0xf3, 0xe2, 0xc2, 0xfe, 0xed, 0x7a, 0x7b, + 0xf2, 0x0c, 0x1f, 0xb1, 0x40, 0x08, 0xfa, 0x49, 0x2f, 0xa0, 0x30, 0x1f, + 0x23, 0xe4, 0xa4, 0xab, 0x5e, 0x0e, 0x5a, 0xb6, 0x88, 0xec, 0xc1, 0x00, + 0x52, 0x44, 0xb4, 0x30, 0x57, 0x1b, 0x9b, 0x3b, 0x59, 0x54, 0xc4, 0x74, + 0x29, 0xd8, 0xe3, 0x91, 0x10, 0x3e, 0x08, 0xe9, 0x74, 0x31, 0xe2, 0x6f, + 0xc0, 0x24, 0x79, 0x2d, 0x04, 0x19, 0x33, 0x53, 0xc5, 0x85, 0x18, 0xfa, + 0x14, 0x5c, 0xe9, 0x78, 0x5d, 0x08, 0x31, 0x30, 0x2d, 0xaa, 0xb0, 0x38, + 0x6f, 0x35, 0x9e, 0xca, 0xf3, 0x1e, 0x26, 0xe5, 0x71, 0x1f, 0xf2, 0xf9, + 0xdf, 0xcc, 0x34, 0x13, 0x36, 0xfb, 0xef, 0xaf, 0x20, 0xa7, 0x7d, 0xf3, + 0xb7, 0x97, 0xa0, 0xe2, 0xbf, 0x87, 0xfd, 0xee, 0x55, 0x0a, 0x83, 0x24, + 0xcf, 0x46, 0x50, 0x59, 0xe4, 0x1d, 0x62, 0x63, 0x70, 0xb8, 0xb4, 0x4d, + 0xfa, 0x5d, 0x0f, 0xe8, 0x86, 0xbc, 0x83, 0x46, 0x7b, 0xda, 0xea, 0xdf, + 0x90, 0xed, 0x6a, 0xad, 0xfd, 0xfd, 0x4e, 0x9a, 0xcf, 0x9b, 0x6c, 0x7b, + 0xb1, 0x85, 0xaa, 0x48, 0xcb, 0x4b, 0x2c, 0x2e, 0x94, 0xf1, 0xdf, 0x24, + 0xdb, 0xc1, 0xd3, 0x07, 0xa9, 0x45, 0x66, 0x8a, 0xa5, 0x24, 0x06, 0xb1, + 0x64, 0x0a, 0x81, 0xcc, 0x25, 0x2f, 0x6d, 0x71, 0x01, 0x89, 0x69, 0x56, + 0xe4, 0x02, 0xf5, 0x2c, 0xda, 0x5a, 0xe9, 0x02, 0x39, 0xbd, 0x32, 0xcb, + 0xb5, 0xed, 0xed, 0xdf, 0x3c, 0xb5, 0xbe, 0x88, 0xaf, 0xfa, 0x7a, 0xc7, + 0xed, 0x71, 0xf2, 0xac, 0x64, 0x38, 0x69, 0x77, 0x3b, 0xbb, 0xda, 0xdb, + 0xab, 0xb9, 0xa8, 0x5f, 0xe1, 0x32, 0x46, 0xc7, 0xf5, 0x03, 0xc9, 0x40, + 0xad, 0xbf, 0x09, 0x5d, 0xa7, 0x5f, 0x48, 0x28, 0x98, 0xea, 0xc8, 0x82, + 0xb4, 0x4c, 0x30, 0x90, 0x91, 0x97, 0x7f, 0x63, 0x8a, 0x8d, 0xa4, 0xbe, + 0x82, 0x6f, 0x2a, 0x8e, 0x63, 0x81, 0x74, 0x50, 0x18, 0x70, 0xc6, 0xfd, + 0xfa, 0x43, 0x71, 0xff, 0x3f, 0xee, 0xf3, 0x64, 0x88, 0xe9, 0xca, 0xca, + 0x82, 0xf0, 0x2e, 0x66, 0xef, 0x08, 0x11, 0x43, 0x14, 0x86, 0x04, 0xc8, + 0x0f, 0xd5, 0x3d, 0x2c, 0x05, 0x49, 0xb1, 0x3d, 0xea, 0xe0, 0xc6, 0x16, + 0x18, 0x98, 0x5f, 0x99, 0x63, 0x25, 0x13, 0xa9, 0xdb, 0x52, 0x82, 0xea, + 0x58, 0xab, 0x44, 0xb0, 0x84, 0x1d, 0x83, 0xd4, 0x7d, 0xe3, 0xfd, 0x49, + 0x5d, 0x0d, 0x4e, 0xc0, 0x28, 0xc5, 0x1c, 0x76, 0x0d, 0x64, 0x9e, 0x16, + 0x00, 0xa9, 0x15, 0xe5, 0xdc, 0xc5, 0x57, 0x3d, 0x97, 0x15, 0x8b, 0xb0, + 0xd0, 0xd3, 0xbd, 0xb8, 0x30, 0x13, 0xba, 0x3d, 0x73, 0x20, 0x03, 0xc3, + 0x61, 0x32, 0x93, 0x07, 0x60, 0xcb, 0xd6, 0xfc, 0x41, 0xac, 0x81, 0x69, + 0x41, 0x1b, 0xe5, 0xd5, 0x9f, 0xac, 0xc6, 0x80, 0xac, 0xef, 0x0c, 0xf6, + 0xbf, 0x7e, 0x3b, 0xfb, 0x7e, 0xe8, 0xc1, 0xcb, 0x73, 0x30, 0x32, 0x43, + 0xf2, 0x1c, 0x70, 0xc7, 0xca, 0xc3, 0xd8, 0x0b, 0x04, 0x70, 0xdf, 0xf1, + 0x48, 0xe0, 0xdc, 0x95, 0xc2, 0x52, 0xb7, 0x1b, 0x8c, 0x11, 0x91, 0x13, + 0xba, 0xec, 0x48, 0x55, 0xcc, 0xd2, 0x20, 0x9d, 0x38, 0xbc, 0x8c, 0x0e, + 0x1d, 0xde, 0x22, 0x11, 0x30, 0xa3, 0x8f, 0x5e, 0xae, 0x5f, 0x04, 0xa7, + 0x33, 0x5b, 0xda, 0xb3, 0x4e, 0x95, 0x7c, 0x19, 0xf5, 0x7d, 0x68, 0x15, + 0x74, 0x2c, 0xa6, 0x21, 0x30, 0xfa, 0xc1, 0x88, 0x8c, 0xf4, 0x10, 0xe9, + 0x9a, 0x95, 0x14, 0x99, 0x4d, 0x1b, 0x9d, 0x93, 0x24, 0x26, 0x9c, 0x77, + 0x7d, 0x6b, 0xe3, 0x2d, 0x05, 0x03, 0x15, 0x89, 0x01, 0x89, 0xcb, 0xac, + 0x03, 0x82, 0x5c, 0xa3, 0xd0, 0x5b, 0x98, 0x3f, 0xac, 0xe9, 0x22, 0xde, + 0xc7, 0xfa, 0x5c, 0x13, 0x75, 0xcd, 0xab, 0x0a, 0xdb, 0x72, 0x94, 0x99, + 0xc3, 0x40, 0x9d, 0x2d, 0xc6, 0xec, 0x9a, 0x1a, 0xa8, 0xa3, 0x58, 0x5c, + 0xb0, 0x7a, 0x68, 0x22, 0x1f, 0xa9, 0xac, 0x0a, 0xa3, 0x73, 0x20, 0xd9, + 0x9a, 0xb9, 0x9c, 0x9a, 0x82, 0x22, 0xdf, 0x3f, 0xeb, 0x3e, 0x47, 0x7c, + 0x03, 0xc4, 0x0e, 0x02, 0x0a, 0x58, 0x50, 0xc9, 0xe2, 0x42, 0xeb, 0xe1, + 0x8b, 0xd5, 0xee, 0xc3, 0xa7, 0xc8, 0x31, 0x5e, 0x79, 0xf0, 0xf0, 0x69, + 0x4b, 0x03, 0x2c, 0x78, 0xd2, 0x24, 0x9c, 0xcf, 0x27, 0x9e, 0x23, 0x93, + 0xd9, 0x8b, 0x2d, 0xe3, 0x67, 0x7b, 0x7b, 0x1b, 0x6b, 0xfb, 0x6b, 0xc5, + 0xab, 0x40, 0x3b, 0xe0, 0x1e, 0x69, 0x42, 0x81, 0xaa, 0x45, 0x19, 0x58, + 0xa4, 0x3a, 0xe1, 0x18, 0x1d, 0x32, 0x19, 0x5f, 0x89, 0xc8, 0xcd, 0xba, + 0x7f, 0x6e, 0xaa, 0x3b, 0x1b, 0x41, 0xf6, 0xf6, 0xd2, 0x7e, 0x2e, 0x8f, + 0x5d, 0x8c, 0xfb, 0xe7, 0x80, 0xb3, 0xc6, 0xf7, 0xb1, 0x51, 0xe8, 0x52, + 0x18, 0xf0, 0x74, 0x18, 0xb9, 0xde, 0xfa, 0xee, 0xf6, 0xbb, 0x37, 0x3b, + 0xbd, 0xe2, 0x95, 0x84, 0xce, 0x04, 0xfa, 0xb8, 0xec, 0x1f, 0xa3, 0x90, + 0xe5, 0xe2, 0x82, 0xf0, 0xa8, 0x76, 0xd1, 0xc8, 0xc4, 0x48, 0x74, 0x39, + 0x87, 0x88, 0x10, 0x87, 0xa2, 0x8c, 0xd7, 0x6e, 0x60, 0x6b, 0x70, 0x71, + 0x81, 0x2d, 0x26, 0x10, 0x5d, 0xa5, 0x96, 0xc0, 0xa3, 0x52, 0x1b, 0x88, + 0xf9, 0x14, 0xcb, 0xd7, 0x39, 0x2c, 0x35, 0x05, 0x5c, 0x4c, 0x01, 0x5b, + 0x27, 0x82, 0xa6, 0x24, 0x43, 0x90, 0xa4, 0x6c, 0x89, 0xe0, 0x82, 0x76, + 0x85, 0xaa, 0xcd, 0x14, 0xee, 0xb0, 0xf7, 0x42, 0x5d, 0x82, 0xc7, 0x72, + 0x29, 0xc5, 0x4d, 0x39, 0xb5, 0x70, 0x6e, 0x0e, 0xd6, 0xd7, 0x0e, 0x5e, + 0xbf, 0xdb, 0xd9, 0xd8, 0xde, 0xb4, 0x4a, 0x93, 0x71, 0x5e, 0x82, 0x3d, + 0x6a, 0xf0, 0xaa, 0xc2, 0x85, 0x82, 0xea, 0x52, 0x8d, 0x55, 0xd3, 0x70, + 0x68, 0x8a, 0x79, 0x0c, 0x0f, 0xcc, 0x56, 0xaa, 0x1a, 0x1e, 0xe3, 0x92, + 0xf1, 0x38, 0xc0, 0x46, 0x8b, 0x49, 0x16, 0x7d, 0x3a, 0xaa, 0xef, 0x77, + 0xdf, 0x6c, 0x3a, 0x1d, 0xf8, 0x78, 0xea, 0x24, 0x90, 0x37, 0x42, 0x19, + 0x12, 0x9d, 0xec, 0xac, 0x3a, 0xfa, 0x50, 0x67, 0xa4, 0xc0, 0x55, 0x60, + 0x14, 0x4a, 0xb8, 0xfe, 0xe6, 0xd1, 0x81, 0x2f, 0x5e, 0x5f, 0xa0, 0x97, + 0xfa, 0xc3, 0xa9, 0x2c, 0x1e, 0x1b, 0x2b, 0x7e, 0xdc, 0xf8, 0xee, 0x60, + 0x7d, 0x77, 0xe7, 0xdb, 0xad, 0xef, 0x38, 0x9a, 0x64, 0x70, 0xbd, 0xde, + 0xf6, 0xc1, 0xeb, 0xb5, 0xf5, 0x3f, 0x6f, 0xee, 0x6c, 0x14, 0xaf, 0x92, + 0x09, 0xe8, 0x58, 0x35, 0x5c, 0x3e, 0x07, 0xb1, 0xc8, 0xa1, 0x43, 0x5a, + 0x06, 0x32, 0xd0, 0x8a, 0xe5, 0xee, 0x14, 0xe4, 0x6f, 0x42, 0x19, 0x6d, + 0x71, 0xc1, 0xf1, 0x35, 0x5c, 0x3d, 0xe0, 0x9b, 0xe7, 0xea, 0x5f, 0xb2, + 0x3c, 0x2c, 0xc6, 0x66, 0x6a, 0xff, 0x7e, 0x4a, 0x92, 0x1d, 0x59, 0x5c, + 0x98, 0x41, 0xeb, 0xb5, 0x7b, 0x75, 0x7e, 0xae, 0x9e, 0xa7, 0xea, 0xc9, + 0xed, 0xe4, 0xce, 0xb8, 0x30, 0x22, 0xe9, 0xc5, 0x0b, 0x29, 0x72, 0xb1, + 0x3d, 0xcc, 0x1f, 0xfe, 0xb9, 0x0f, 0x54, 0x4b, 0x7a, 0xb1, 0xba, 0x95, + 0x94, 0xcc, 0x94, 0x8c, 0x33, 0x83, 0x8c, 0x4d, 0xa6, 0x96, 0xd2, 0xf9, + 0x79, 0x84, 0x70, 0x0c, 0x5c, 0xe2, 0x2a, 0xde, 0x7c, 0x6a, 0x10, 0x03, + 0x13, 0x65, 0x4c, 0x9e, 0x0d, 0x43, 0x63, 0xcb, 0x03, 0x9f, 0x6a, 0x96, + 0x04, 0x5f, 0x7e, 0x89, 0x79, 0x96, 0xe3, 0xba, 0x06, 0x30, 0xd1, 0xe9, + 0x70, 0x3a, 0x19, 0xb0, 0x58, 0x55, 0x38, 0x96, 0xc7, 0x13, 0x22, 0x8c, + 0x8d, 0x02, 0x53, 0xe5, 0xb7, 0xe3, 0x69, 0xcd, 0x2f, 0x6b, 0x25, 0x4f, + 0x68, 0x11, 0x88, 0x50, 0x15, 0x3f, 0x26, 0xd6, 0x3d, 0x48, 0x7a, 0xa3, + 0xc1, 0x49, 0x0d, 0xe4, 0x13, 0xca, 0xab, 0xf3, 0x08, 0x73, 0x62, 0x01, + 0x2d, 0x96, 0xd4, 0x44, 0xc2, 0x13, 0xc1, 0xe1, 0xbc, 0x4a, 0x4b, 0x8b, + 0x5e, 0x7a, 0x4d, 0x32, 0xa2, 0xfa, 0xd2, 0xff, 0xd5, 0x5d, 0x5c, 0xd8, + 0x06, 0x56, 0x8c, 0x32, 0x00, 0x7a, 0x1d, 0x05, 0xd6, 0x4d, 0x2a, 0xa1, + 0x08, 0x67, 0x76, 0x24, 0xdd, 0x42, 0x35, 0xa1, 0x6e, 0x76, 0x56, 0xf4, + 0x9e, 0x6a, 0x10, 0xad, 0x44, 0xb9, 0x5d, 0x38, 0x3e, 0xb3, 0x1e, 0xb1, + 0xbf, 0x6c, 0xef, 0x7e, 0xb7, 0xb1, 0xf5, 0x96, 0xf3, 0x48, 0x6a, 0x9e, + 0xce, 0xd0, 0x6f, 0x0e, 0x7e, 0xa3, 0x78, 0x27, 0x46, 0x90, 0xed, 0x58, + 0xc7, 0xec, 0x46, 0xb2, 0x53, 0x2c, 0x6e, 0x8d, 0xc3, 0x8e, 0x3d, 0xea, + 0x8e, 0x6b, 0x77, 0x81, 0xcb, 0x1d, 0x4f, 0x01, 0xc4, 0xf6, 0x4f, 0x22, + 0x8f, 0xa9, 0xe8, 0x06, 0xc0, 0x25, 0x7f, 0xa3, 0xad, 0x7c, 0xcc, 0xab, + 0xcf, 0x0a, 0xf2, 0xd0, 0x71, 0xe1, 0xa8, 0x74, 0x55, 0x96, 0x04, 0x98, + 0xa7, 0x1b, 0x2d, 0x2e, 0x2c, 0x85, 0x36, 0xcf, 0xaa, 0x4f, 0xe1, 0x0a, + 0xdb, 0x18, 0x81, 0x16, 0x63, 0x68, 0x6e, 0xad, 0x50, 0x24, 0x7a, 0x31, + 0x1f, 0x61, 0xd3, 0x82, 0x64, 0x4b, 0x78, 0x6f, 0x48, 0x18, 0x61, 0xa9, + 0x7f, 0xf0, 0x44, 0xfe, 0x45, 0x7a, 0xa9, 0x87, 0xa7, 0x93, 0xa3, 0x8b, + 0x55, 0x8a, 0xf3, 0xff, 0x9c, 0x06, 0x81, 0xb1, 0x2a, 0xfe, 0xf2, 0x6e, + 0x6b, 0x3d, 0x05, 0x04, 0xa1, 0xd6, 0xfb, 0xfd, 0xe6, 0x36, 0x40, 0x2b, + 0xde, 0x69, 0xe1, 0xbb, 0xf7, 0x6f, 0x7a, 0x4d, 0x1e, 0x85, 0x98, 0xcc, + 0xa0, 0x82, 0x05, 0x16, 0x69, 0xd5, 0x89, 0x36, 0xd6, 0xb7, 0x0b, 0x16, + 0x30, 0x11, 0x54, 0x86, 0xb3, 0x6a, 0x60, 0xa0, 0x06, 0x60, 0x3c, 0xeb, + 0x9b, 0x6f, 0xf7, 0x0f, 0x6c, 0xf3, 0x3e, 0xcf, 0xad, 0x69, 0x08, 0xfe, + 0x8a, 0xdc, 0xda, 0x87, 0x04, 0x65, 0xdd, 0x6a, 0x3c, 0xff, 0x77, 0x5f, + 0x21, 0x61, 0x50, 0x7f, 0xde, 0xfc, 0x6b, 0x20, 0x72, 0x19, 0x94, 0xa5, + 0x33, 0xe9, 0xc0, 0x58, 0x0c, 0x48, 0xd4, 0xe2, 0x46, 0xd7, 0x4d, 0x9a, + 0xb5, 0x17, 0xdb, 0xc6, 0x97, 0x58, 0xa3, 0x17, 0x1d, 0x06, 0x19, 0x9d, + 0x48, 0x7b, 0x9a, 0x8f, 0x83, 0x2b, 0x26, 0x4d, 0x3b, 0x13, 0xab, 0x90, + 0x26, 0xcf, 0xea, 0xc1, 0x56, 0x06, 0xc9, 0x92, 0xe4, 0x8a, 0x15, 0x49, + 0xdb, 0x28, 0xd3, 0x48, 0xcb, 0xc1, 0xd5, 0xcf, 0x95, 0xcf, 0x46, 0xb1, + 0x01, 0xd9, 0xcc, 0xb8, 0x52, 0x57, 0xb7, 0xd2, 0x87, 0xd7, 0xcc, 0xe3, + 0x3b, 0x2a, 0xf3, 0x8c, 0x90, 0xcd, 0x69, 0x08, 0x27, 0x28, 0xd0, 0x17, + 0xc6, 0x19, 0x44, 0x8f, 0x0f, 0x1e, 0xcd, 0x24, 0x38, 0x14, 0x31, 0xdb, + 0x2a, 0x4b, 0x09, 0x4e, 0xef, 0x10, 0xd4, 0x38, 0xf3, 0x28, 0xfe, 0xed, + 0xfe, 0xe1, 0xb8, 0x02, 0xd3, 0x5d, 0xc2, 0x23, 0x0f, 0xbb, 0xab, 0xe1, + 0xcc, 0x7e, 0x5a, 0x6e, 0x17, 0xaf, 0x47, 0x80, 0x2f, 0x48, 0xf2, 0x05, + 0x79, 0x0e, 0xc0, 0x27, 0xc3, 0x67, 0x66, 0x9b, 0xe8, 0x6d, 0xbe, 0x0d, + 0x9a, 0x80, 0xec, 0xc0, 0xd7, 0x17, 0xe8, 0x28, 0xdc, 0xb4, 0x4d, 0xae, + 0x6b, 0x5f, 0x27, 0xd3, 0x51, 0x6a, 0x22, 0x65, 0x8a, 0xc0, 0x34, 0x35, + 0x4d, 0x82, 0xe7, 0xa4, 0xf5, 0xbf, 0x92, 0x51, 0xff, 0xb4, 0x76, 0x21, + 0xf9, 0x45, 0x60, 0x20, 0x1b, 0xe5, 0xa4, 0x34, 0x31, 0xb5, 0xc9, 0x63, + 0x93, 0x83, 0x18, 0xf9, 0x71, 0x8a, 0x65, 0xde, 0x08, 0x51, 0x26, 0x86, + 0x0e, 0x44, 0x0c, 0x0b, 0xac, 0x37, 0x86, 0x2f, 0xe1, 0x29, 0x8b, 0xee, + 0x36, 0x56, 0x46, 0x6f, 0x99, 0xc5, 0xa2, 0x7c, 0x87, 0x9f, 0xfb, 0xbb, + 0x41, 0x28, 0x0d, 0x7f, 0x6c, 0x7e, 0xbb, 0xf5, 0xa3, 0x19, 0xc8, 0xf6, + 0xa3, 0x89, 0x47, 0xd1, 0x2d, 0x00, 0x6c, 0x91, 0x2b, 0x19, 0x56, 0x56, + 0x28, 0x31, 0x16, 0x18, 0xdc, 0xbe, 0x54, 0x33, 0x93, 0x32, 0x21, 0x8b, + 0x8a, 0x1d, 0xe7, 0x57, 0xb3, 0xb4, 0xeb, 0xe0, 0x3a, 0xba, 0x0c, 0x5b, + 0x99, 0xe5, 0x80, 0xa6, 0x82, 0x99, 0x84, 0x6f, 0xb5, 0x38, 0xc8, 0x80, + 0xc2, 0xec, 0x34, 0x9c, 0x5d, 0x3f, 0x88, 0x76, 0x50, 0x29, 0x8b, 0x45, + 0x7d, 0x21, 0x01, 0xc7, 0x09, 0x02, 0x4e, 0x3b, 0x31, 0x5c, 0x40, 0xfc, + 0x93, 0x34, 0xf0, 0x82, 0xe1, 0xd7, 0x12, 0x98, 0x6a, 0xba, 0x9e, 0xa3, + 0x06, 0xfa, 0xeb, 0xf9, 0xb0, 0xad, 0xae, 0x80, 0x64, 0xc7, 0x31, 0x27, + 0x0a, 0x07, 0x00, 0x10, 0xe0, 0x89, 0xd6, 0x19, 0xb6, 0xf1, 0x8d, 0x95, + 0xe7, 0x52, 0x2c, 0x51, 0xe6, 0xcf, 0x65, 0x9d, 0x49, 0x6e, 0xbd, 0xed, + 0x92, 0x58, 0x50, 0xcc, 0xa5, 0x2c, 0xab, 0x49, 0xd6, 0xa5, 0xe6, 0x77, + 0x6b, 0xbd, 0x6e, 0x34, 0x3f, 0x3b, 0x97, 0x5e, 0x36, 0x19, 0xc0, 0xf1, + 0xd4, 0x8f, 0x9b, 0x2f, 0xc1, 0x6e, 0x19, 0xc1, 0x80, 0x47, 0x70, 0x15, + 0xc8, 0x83, 0xe9, 0x4b, 0xe5, 0xad, 0xdf, 0x2a, 0x93, 0xd7, 0x9e, 0xdc, + 0xf6, 0xad, 0x27, 0xe9, 0x4b, 0x67, 0xb7, 0x7e, 0xab, 0x63, 0x1a, 0xf8, + 0xe2, 0xe2, 0xe6, 0x8f, 0x5b, 0xfb, 0x41, 0xb3, 0xda, 0x48, 0xa8, 0x77, + 0xac, 0x47, 0x35, 0xc8, 0x1c, 0x43, 0xf0, 0x31, 0xd4, 0xc9, 0xb4, 0x74, + 0x73, 0x2b, 0x4b, 0x00, 0x0f, 0x45, 0x6d, 0x38, 0x96, 0xfd, 0xb1, 0xd4, + 0x3c, 0x86, 0xf7, 0x42, 0x82, 0xb6, 0x24, 0xd5, 0x44, 0x72, 0xa9, 0x98, + 0x51, 0x6b, 0xe6, 0x26, 0x96, 0x08, 0x97, 0xa4, 0x42, 0x05, 0xf2, 0xd6, + 0x16, 0x11, 0x37, 0x24, 0xe8, 0xcc, 0x00, 0x1b, 0x51, 0x4b, 0xa9, 0x80, + 0xec, 0x8e, 0x2c, 0x0d, 0xdc, 0x30, 0x11, 0x58, 0xe5, 0x46, 0xd0, 0x2a, + 0x35, 0xe7, 0xb6, 0xd6, 0x84, 0x6c, 0x3c, 0xb1, 0x02, 0xf1, 0x54, 0x82, + 0x63, 0x1d, 0x7c, 0xc1, 0xe3, 0x8f, 0x62, 0x2c, 0x61, 0x96, 0xd2, 0xcf, + 0x92, 0x55, 0x47, 0x61, 0x12, 0xc7, 0xce, 0xe9, 0xc4, 0xb6, 0x94, 0xe0, + 0x11, 0xd8, 0x69, 0x7b, 0x08, 0x29, 0x62, 0x98, 0x11, 0x37, 0xc9, 0xda, + 0x39, 0x3c, 0x44, 0xb5, 0xe3, 0x88, 0x3b, 0xeb, 0x56, 0xff, 0x5c, 0x7d, + 0x90, 0xc4, 0x76, 0x7f, 0x59, 0xda, 0x06, 0xfc, 0xdd, 0xb7, 0x65, 0x7f, + 0x20, 0x97, 0x93, 0x66, 0xbd, 0xf6, 0x7f, 0x36, 0x69, 0x11, 0x60, 0x77, + 0xb0, 0xb0, 0x9c, 0x97, 0x03, 0xf1, 0x6f, 0xc9, 0x01, 0xd0, 0xa2, 0xa3, + 0x97, 0xa5, 0x70, 0x3a, 0xad, 0x3f, 0xad, 0xef, 0x00, 0x99, 0x7e, 0xcd, + 0x0b, 0x5b, 0x8f, 0xc6, 0x9e, 0x72, 0x6f, 0x1e, 0xc4, 0x18, 0xfa, 0x65, + 0xd5, 0xa4, 0xd2, 0x32, 0x03, 0x9e, 0x33, 0x42, 0xf7, 0xad, 0x40, 0xfd, + 0x4b, 0x2d, 0x2a, 0xb4, 0x45, 0xd1, 0xb4, 0xfa, 0x04, 0xee, 0xdc, 0x67, + 0x02, 0x83, 0xd5, 0xd6, 0x45, 0x0e, 0x16, 0xd7, 0x81, 0xce, 0x05, 0x16, + 0xa4, 0x10, 0x1c, 0x03, 0xe5, 0xf6, 0x82, 0x1c, 0x3d, 0x42, 0xad, 0x32, + 0x2c, 0x44, 0x5b, 0xab, 0xf6, 0x8c, 0x0e, 0x4b, 0xd4, 0xa1, 0x23, 0x6c, + 0x6d, 0x39, 0x14, 0x35, 0xd9, 0x97, 0xd3, 0xc2, 0x33, 0x65, 0x5e, 0x81, + 0xf4, 0x17, 0xd6, 0xdd, 0x76, 0xa9, 0x88, 0x94, 0x29, 0x5b, 0x10, 0x5b, + 0x90, 0xb0, 0x1e, 0x86, 0x2f, 0x1c, 0xf9, 0xd3, 0x2c, 0x94, 0x52, 0x5b, + 0x10, 0x23, 0x5a, 0x7b, 0x3a, 0xb7, 0x35, 0x29, 0x8c, 0x1c, 0x1b, 0x4b, + 0xe3, 0x62, 0x6f, 0x6a, 0xed, 0x59, 0xb6, 0x8d, 0x49, 0x70, 0x2d, 0x1b, + 0x94, 0x67, 0x9e, 0x87, 0x67, 0x7e, 0xa8, 0x00, 0x81, 0xaa, 0x66, 0xe0, + 0x71, 0x75, 0x31, 0xd0, 0xa1, 0xeb, 0x27, 0x8c, 0x4c, 0x15, 0x00, 0x61, + 0xc1, 0xfd, 0xb6, 0x1e, 0x83, 0x2e, 0xe8, 0x9e, 0x87, 0x17, 0xe8, 0x2b, + 0x30, 0x44, 0xb1, 0xc6, 0x81, 0x19, 0x0e, 0xfb, 0x4e, 0x18, 0x9a, 0x54, + 0x28, 0x9f, 0x21, 0x3b, 0x5a, 0xf2, 0x7b, 0xed, 0x03, 0x7b, 0xc9, 0x53, + 0xa5, 0x93, 0x88, 0x4f, 0x4c, 0x69, 0x3a, 0x3e, 0x22, 0xc9, 0x24, 0xaa, + 0x02, 0x61, 0x8a, 0x04, 0xd3, 0x1c, 0x6f, 0x8d, 0x91, 0x68, 0xd7, 0x2d, + 0xde, 0x8c, 0x68, 0xd9, 0x63, 0x2c, 0xb7, 0x88, 0x52, 0xe3, 0xbe, 0x4e, + 0x9e, 0xd0, 0x38, 0x22, 0xc5, 0xc5, 0x66, 0x48, 0x7c, 0x0e, 0x70, 0x41, + 0xe0, 0x0e, 0x4b, 0x0e, 0xf6, 0x0c, 0x6d, 0x9e, 0xb5, 0x95, 0x64, 0x76, + 0x48, 0x36, 0xe6, 0xa2, 0x76, 0x8b, 0x1f, 0xce, 0x44, 0x9a, 0x2b, 0xfb, + 0x13, 0xbb, 0xae, 0xc5, 0x95, 0xe2, 0x16, 0x75, 0x5b, 0x74, 0xc6, 0x82, + 0xab, 0x31, 0x17, 0x46, 0x3c, 0x09, 0x1a, 0x90, 0x54, 0xf0, 0xba, 0x4e, + 0x00, 0x25, 0xda, 0xb1, 0xe8, 0x8a, 0x14, 0xe3, 0x85, 0x6b, 0x80, 0x7c, + 0xd3, 0x31, 0x6c, 0xb4, 0xbc, 0xf3, 0x62, 0xea, 0x40, 0x8e, 0x05, 0x08, + 0x6d, 0xc8, 0x0f, 0x75, 0xc8, 0x97, 0xdc, 0xdc, 0xbd, 0xb5, 0x5e, 0xcf, + 0xb6, 0x76, 0x3d, 0xee, 0x62, 0xdc, 0x46, 0x0d, 0xb3, 0x64, 0x41, 0x4c, + 0x2d, 0x23, 0xc2, 0xa9, 0xe0, 0xc5, 0xc5, 0x85, 0x98, 0xec, 0xc1, 0xb6, + 0xc1, 0x1f, 0x36, 0xa4, 0x9c, 0x42, 0x3e, 0x19, 0x9f, 0xcd, 0x25, 0x57, + 0xc6, 0x16, 0xc6, 0x57, 0x26, 0x2e, 0x8c, 0xad, 0x8c, 0x58, 0x11, 0xb8, + 0x54, 0x84, 0x0d, 0x36, 0x7e, 0x4b, 0xc3, 0xe9, 0xa7, 0x0b, 0x1c, 0x7e, + 0xeb, 0xf5, 0x51, 0x73, 0x46, 0xef, 0x65, 0xc0, 0xed, 0x2f, 0x9e, 0xd1, + 0xfb, 0x99, 0x19, 0x3d, 0xce, 0xda, 0x2e, 0x56, 0x57, 0x9f, 0x29, 0x9c, + 0x95, 0x2e, 0x57, 0x42, 0xf5, 0x49, 0xeb, 0x78, 0xae, 0xc3, 0xf4, 0xcd, + 0x64, 0xdb, 0xa1, 0x09, 0x0c, 0xbd, 0xe1, 0x27, 0xda, 0xb0, 0xa2, 0x80, + 0x50, 0x86, 0x90, 0xf3, 0x5c, 0xc4, 0x83, 0xee, 0x27, 0x5d, 0x25, 0xda, + 0x40, 0x86, 0xc8, 0x5c, 0xbe, 0x44, 0xf9, 0xcd, 0xd1, 0x24, 0xba, 0xab, + 0xad, 0x3b, 0x6b, 0x1c, 0xec, 0x42, 0x51, 0x4a, 0x35, 0x41, 0x62, 0x8d, + 0xdc, 0x6b, 0x50, 0x9d, 0x0b, 0x4f, 0x14, 0x5d, 0x32, 0xca, 0x5f, 0xc4, + 0x36, 0x45, 0xe4, 0xcc, 0x39, 0xb6, 0x65, 0x50, 0x5e, 0x29, 0x9c, 0x06, + 0x15, 0xab, 0xba, 0x10, 0x13, 0x7b, 0x38, 0x13, 0xa7, 0xd5, 0x10, 0xb6, + 0x6f, 0x89, 0x71, 0x34, 0xe3, 0x34, 0xcc, 0x4b, 0x6a, 0x38, 0xf6, 0xb0, + 0x03, 0xed, 0xad, 0x16, 0x67, 0xab, 0x8c, 0x32, 0xc3, 0xb0, 0x68, 0xf8, + 0x5d, 0x39, 0xec, 0x67, 0xb6, 0x26, 0xbe, 0x00, 0xd0, 0xbe, 0xa4, 0x9e, + 0x60, 0x37, 0x59, 0x16, 0x3b, 0xb4, 0x5e, 0xe1, 0x57, 0xb2, 0x9f, 0x81, + 0x23, 0x2e, 0xcf, 0x6a, 0x7b, 0xe0, 0x61, 0x7b, 0x60, 0x19, 0xe5, 0x40, + 0xc1, 0x89, 0x76, 0xe9, 0x2a, 0xcd, 0x42, 0x75, 0x4e, 0x84, 0x20, 0xb3, + 0xf4, 0x21, 0x6b, 0xe0, 0xc5, 0xcc, 0x80, 0x3c, 0x41, 0xe8, 0x81, 0xf1, + 0xa6, 0x58, 0x0b, 0x55, 0x9c, 0xcb, 0xfc, 0xe0, 0xed, 0xe6, 0xfe, 0x5b, + 0xa6, 0x26, 0xd8, 0xe9, 0x5b, 0xc6, 0xa9, 0x14, 0x28, 0x18, 0x65, 0x12, + 0x7a, 0xa3, 0xda, 0x71, 0x94, 0x72, 0x77, 0xbe, 0x5b, 0xf2, 0xaf, 0xbd, + 0x62, 0xa9, 0xad, 0xca, 0x00, 0x62, 0xe6, 0x40, 0xca, 0x8c, 0x56, 0x57, + 0x75, 0xd7, 0xc3, 0xf4, 0x4e, 0x2b, 0xbd, 0x28, 0x14, 0x25, 0x40, 0x25, + 0x8d, 0x88, 0x40, 0xc2, 0xc8, 0x07, 0xbb, 0x91, 0x25, 0x09, 0x6f, 0x94, + 0xe5, 0xd0, 0xda, 0xf5, 0x26, 0x3d, 0xba, 0x8d, 0x8d, 0xed, 0x27, 0x6c, + 0xe8, 0x90, 0x55, 0x50, 0x1e, 0xaf, 0xac, 0xd0, 0x10, 0x71, 0x18, 0x98, + 0x91, 0xc9, 0x19, 0xd2, 0x14, 0xa6, 0x0d, 0xcc, 0x11, 0xae, 0x3b, 0xe5, + 0xaa, 0x1a, 0x72, 0x70, 0xa7, 0x83, 0x55, 0x48, 0x60, 0x05, 0x39, 0x01, + 0x1c, 0xe4, 0x1f, 0x88, 0xfc, 0xa1, 0xeb, 0x90, 0x9d, 0x31, 0x0e, 0x55, + 0x80, 0x41, 0xb4, 0x4e, 0x4a, 0x66, 0x2f, 0xa2, 0x5d, 0x46, 0xab, 0xbe, + 0x02, 0x2a, 0x33, 0x67, 0x7b, 0xab, 0x4f, 0xe2, 0x9d, 0xe7, 0xbe, 0x05, + 0xd6, 0x8b, 0xd4, 0x34, 0x2a, 0xfa, 0x2a, 0xbe, 0xf5, 0x50, 0x0e, 0x63, + 0x48, 0x57, 0x17, 0xf0, 0xf4, 0x40, 0x74, 0xd0, 0x2b, 0x89, 0x94, 0xdc, + 0xdb, 0xdf, 0x7d, 0x6b, 0x9b, 0x63, 0x1d, 0xe0, 0xcc, 0xbd, 0x05, 0x8c, + 0x9e, 0x8e, 0xfd, 0xbd, 0x62, 0x8d, 0x8e, 0x15, 0x48, 0xcc, 0x4e, 0x84, + 0x3d, 0x0f, 0x62, 0xdf, 0x95, 0x53, 0x23, 0xa0, 0x9d, 0xd8, 0x76, 0x85, + 0xef, 0x0c, 0x3d, 0x5a, 0xb6, 0xab, 0xc9, 0x37, 0x39, 0xd5, 0x80, 0xb2, + 0x77, 0x5d, 0x6a, 0x54, 0xbe, 0xa8, 0x97, 0xaa, 0xeb, 0x56, 0xf8, 0x98, + 0xe1, 0x12, 0xe1, 0xc1, 0x7e, 0x38, 0x1f, 0x92, 0x7c, 0x5c, 0x4a, 0x3c, + 0x96, 0x8b, 0x93, 0xb4, 0x2b, 0xe8, 0xf5, 0x61, 0x22, 0xae, 0x8a, 0x73, + 0x76, 0xbb, 0xed, 0xed, 0xbe, 0xdd, 0xf7, 0xbb, 0x0d, 0x7d, 0xf0, 0x83, + 0xa2, 0x41, 0xd0, 0x48, 0x62, 0xa7, 0x02, 0x1d, 0x81, 0x4c, 0x22, 0x0c, + 0xad, 0xd8, 0xc2, 0xf8, 0x9e, 0xbe, 0xd6, 0x86, 0xe2, 0x1e, 0x8e, 0x93, + 0x96, 0xd6, 0x88, 0xd9, 0xca, 0xf8, 0x80, 0x4c, 0xdc, 0xea, 0x35, 0xe8, + 0x68, 0x1e, 0xce, 0x1c, 0x46, 0xf0, 0xcc, 0xb7, 0x9b, 0xbd, 0x7d, 0xd5, + 0xb3, 0xf0, 0xe7, 0xcc, 0xa0, 0x04, 0x98, 0x57, 0x3f, 0x34, 0xcb, 0xc1, + 0xe2, 0x02, 0xb8, 0x0f, 0x92, 0x07, 0x60, 0x15, 0x44, 0xa3, 0x1e, 0x9d, + 0x65, 0xbd, 0x3d, 0xb2, 0xc3, 0x24, 0x20, 0x9b, 0xba, 0xa9, 0x3c, 0x44, + 0xfc, 0xa0, 0xa5, 0x6d, 0xb6, 0x82, 0xd8, 0x20, 0xa3, 0x51, 0x8c, 0x4e, + 0xbe, 0xfd, 0xd8, 0x8f, 0x22, 0x78, 0xb6, 0xbe, 0xbc, 0x25, 0xf0, 0xcb, + 0x03, 0x7e, 0xd8, 0xb1, 0x8d, 0x25, 0x4b, 0x95, 0x7d, 0x34, 0xa8, 0x2c, + 0x36, 0xf1, 0x44, 0xcd, 0xd8, 0x26, 0x29, 0x24, 0x23, 0xc0, 0xc7, 0x96, + 0xa2, 0x45, 0xf9, 0x22, 0xa5, 0x8d, 0x47, 0x20, 0xc4, 0xd7, 0xe5, 0x71, + 0x4c, 0x65, 0x94, 0x79, 0x66, 0x0c, 0x54, 0x9d, 0x18, 0x94, 0x29, 0xca, + 0xf1, 0x00, 0x21, 0x72, 0xe1, 0xf0, 0x8e, 0x05, 0x9b, 0x48, 0x73, 0x19, + 0xb5, 0x39, 0x32, 0x65, 0xd8, 0x66, 0x8e, 0x12, 0xf9, 0xb3, 0x3c, 0x56, + 0x86, 0x1a, 0xc5, 0x48, 0x58, 0xca, 0x9d, 0xa1, 0x76, 0x8b, 0x3d, 0xf8, + 0xac, 0x78, 0xe7, 0xd7, 0x7f, 0xd4, 0x96, 0x40, 0xb4, 0x88, 0x4c, 0x70, + 0xe4, 0xab, 0x7e, 0x38, 0x3d, 0x8c, 0x55, 0xe0, 0x9f, 0x89, 0x1a, 0x94, + 0x4f, 0xe8, 0x85, 0xbd, 0x57, 0x87, 0xb1, 0x02, 0xda, 0x2b, 0xfd, 0xf6, + 0x31, 0xc9, 0xc2, 0x2a, 0x98, 0x39, 0x37, 0xc3, 0x61, 0xd2, 0xda, 0x7b, + 0xc7, 0xd2, 0x85, 0x57, 0x39, 0xcb, 0xb8, 0x9e, 0xb5, 0x02, 0xde, 0xb9, + 0xa6, 0x2b, 0x80, 0x02, 0x47, 0x81, 0x8e, 0x21, 0x7f, 0x84, 0x66, 0xe8, + 0x59, 0x75, 0xf3, 0x4e, 0x16, 0x99, 0xc8, 0x25, 0xd3, 0x52, 0x39, 0x56, + 0x37, 0x4a, 0xdb, 0x03, 0xf9, 0xf8, 0x7e, 0x3b, 0x57, 0xcf, 0xc6, 0xa0, + 0x99, 0xc8, 0x82, 0x65, 0x12, 0x04, 0x41, 0x46, 0x90, 0x06, 0xa5, 0x77, + 0xe2, 0x1c, 0xfd, 0xf1, 0x13, 0x6b, 0xe5, 0x04, 0x58, 0x83, 0xde, 0x4c, + 0x3c, 0xe2, 0xe1, 0x74, 0x4b, 0xe5, 0xa9, 0xbe, 0x3f, 0x95, 0x09, 0xfe, + 0x09, 0x77, 0x7d, 0x8c, 0x8d, 0xdc, 0x1f, 0x41, 0xcf, 0x41, 0xf4, 0x84, + 0xe7, 0xcd, 0x77, 0x25, 0xf4, 0x2e, 0x31, 0xf3, 0xf9, 0x57, 0xb1, 0xea, + 0xb7, 0xa1, 0x2e, 0x9e, 0x97, 0x9f, 0xfa, 0xe7, 0xd3, 0xf3, 0x70, 0x3d, + 0x30, 0x7b, 0xd7, 0x9a, 0x7e, 0x4e, 0x9d, 0x53, 0x32, 0xb4, 0xad, 0xe0, + 0x52, 0x64, 0x43, 0x23, 0x57, 0x8d, 0x2c, 0x01, 0x3a, 0x30, 0x1a, 0x41, + 0x10, 0xa1, 0xa0, 0x4d, 0xdd, 0xaa, 0x14, 0xec, 0xdf, 0x72, 0x71, 0x41, + 0x44, 0xad, 0x88, 0xbc, 0x16, 0xeb, 0x5a, 0x51, 0x74, 0xd1, 0x27, 0xe5, + 0x3b, 0x03, 0x82, 0x97, 0x4b, 0xf2, 0x1f, 0x94, 0x69, 0x42, 0x2f, 0xe0, + 0xc3, 0x8b, 0x0b, 0x02, 0xbd, 0xc4, 0x34, 0x76, 0x02, 0xfe, 0xfe, 0x4e, + 0x47, 0xfb, 0x82, 0x56, 0x08, 0x55, 0x51, 0x11, 0x59, 0x08, 0x3c, 0xde, + 0x2c, 0x7e, 0xe9, 0xc9, 0xaa, 0x86, 0x04, 0xe8, 0x35, 0x60, 0x47, 0x5c, + 0xa4, 0xc6, 0xb0, 0x7e, 0x80, 0x24, 0x3d, 0x6d, 0x6b, 0x04, 0x88, 0x95, + 0x86, 0xb6, 0x4a, 0x34, 0x54, 0x0e, 0xb3, 0xc3, 0xfc, 0xe4, 0x91, 0x1d, + 0xe6, 0xf1, 0xd5, 0x05, 0xcd, 0xba, 0xa7, 0x10, 0x0e, 0x9b, 0x54, 0xf8, + 0x04, 0x6c, 0x63, 0x5d, 0x0e, 0x07, 0x24, 0x9f, 0xd9, 0x37, 0xca, 0x3a, + 0xf1, 0x72, 0xf1, 0x95, 0xf4, 0x5e, 0xab, 0xc4, 0xbc, 0x61, 0x86, 0x5f, + 0x5c, 0x92, 0xf6, 0xd8, 0x53, 0x7d, 0x8c, 0xbe, 0xde, 0xa1, 0x66, 0x66, + 0x5d, 0xf7, 0x30, 0xe5, 0x26, 0x13, 0x17, 0xed, 0xe6, 0x97, 0x6b, 0x36, + 0xc9, 0x11, 0xb6, 0xa7, 0x5f, 0x64, 0xba, 0x29, 0x78, 0x72, 0xdc, 0x7b, + 0xce, 0xa0, 0x7f, 0x71, 0xe6, 0x24, 0xfd, 0x14, 0x77, 0xca, 0x1e, 0xd2, + 0x8d, 0xd3, 0x6c, 0xe3, 0x08, 0x85, 0x97, 0x60, 0x60, 0xdb, 0xd9, 0x10, + 0xb2, 0x5a, 0x5f, 0xcb, 0xb0, 0x67, 0xac, 0x39, 0xb1, 0x76, 0x84, 0xe9, + 0x8c, 0x4e, 0x87, 0xfd, 0x9f, 0xab, 0xe3, 0x78, 0x91, 0xb0, 0xa2, 0x5d, + 0x98, 0xa1, 0x3d, 0xf9, 0x88, 0xbb, 0x4e, 0xf2, 0xd5, 0x18, 0x4b, 0x24, + 0xdf, 0x23, 0xa6, 0x4e, 0x5c, 0x6b, 0xf2, 0xd4, 0x63, 0xde, 0xe2, 0x26, + 0x25, 0xe1, 0x66, 0xc0, 0x14, 0xa4, 0x08, 0x58, 0xc6, 0x77, 0x9e, 0x92, + 0x3f, 0xeb, 0x8a, 0xd3, 0x22, 0x21, 0x55, 0xd9, 0xc8, 0x72, 0x6a, 0xa2, + 0x48, 0x5c, 0x8a, 0x6f, 0xaf, 0x6c, 0x5c, 0xde, 0x4f, 0x9f, 0x5e, 0x63, + 0x45, 0x61, 0x57, 0x9b, 0xdc, 0x68, 0x7b, 0xf4, 0x99, 0xd2, 0x61, 0x2c, + 0x51, 0x6e, 0x09, 0x1c, 0xed, 0xb4, 0xb6, 0xbc, 0xb1, 0x34, 0x51, 0x43, + 0x49, 0x7f, 0xca, 0xa5, 0xb4, 0x6b, 0x26, 0x4d, 0x06, 0xfd, 0xba, 0xe8, + 0x1b, 0x89, 0x3f, 0xc5, 0x26, 0x7f, 0x4b, 0x07, 0x59, 0x94, 0x00, 0x87, + 0xc5, 0x7e, 0x86, 0x42, 0xc6, 0x07, 0x5f, 0x70, 0xc7, 0x8c, 0x9b, 0xbb, + 0x1e, 0x31, 0xf7, 0xe1, 0x67, 0x2b, 0x51, 0xaa, 0x39, 0x46, 0x14, 0x96, + 0xa0, 0xa4, 0xce, 0x7f, 0x16, 0x7b, 0xb7, 0x35, 0x00, 0x8e, 0xfd, 0x40, + 0xbe, 0x6e, 0x72, 0xd1, 0x67, 0xab, 0x09, 0x5f, 0xd9, 0x4f, 0xaf, 0xe9, + 0x62, 0x6b, 0xc3, 0x9e, 0x79, 0x64, 0xf3, 0xb0, 0x12, 0xa3, 0x54, 0xd7, + 0xeb, 0x62, 0x09, 0x2f, 0x2c, 0xdb, 0x53, 0xd8, 0xd7, 0x9d, 0x91, 0x60, + 0xbb, 0x33, 0xdd, 0x26, 0xff, 0xfa, 0x59, 0x42, 0xf1, 0x26, 0xb0, 0x59, + 0x72, 0xbc, 0x52, 0x5e, 0xb1, 0x04, 0xcb, 0xff, 0x1f, 0xcd, 0x26, 0xc1, + 0x5a, 0x54, 0xf5, 0x1f, 0xbd, 0x85, 0xe7, 0xba, 0x53, 0x6e, 0x97, 0x48, + 0x4a, 0xdd, 0x2a, 0x17, 0x62, 0x24, 0x54, 0x66, 0x54, 0xb0, 0x97, 0xb1, + 0xc4, 0xe1, 0xa2, 0x99, 0x0e, 0xe3, 0xc9, 0x11, 0x19, 0x5b, 0x41, 0xc8, + 0x8e, 0xd3, 0x22, 0x85, 0xbd, 0xde, 0xf7, 0xa6, 0x4e, 0x9b, 0xad, 0x66, + 0x25, 0xa3, 0xa8, 0xfa, 0x6c, 0x3a, 0xe1, 0x35, 0xee, 0x53, 0xc8, 0x30, + 0x3b, 0xf8, 0xc6, 0x6a, 0x76, 0x68, 0x29, 0x26, 0xac, 0x87, 0xe1, 0x89, + 0x0a, 0xc3, 0xad, 0x16, 0x3b, 0xfc, 0xe5, 0x78, 0x24, 0x06, 0x0c, 0xa8, + 0xbc, 0xfa, 0x2e, 0xef, 0x36, 0x84, 0x16, 0x8f, 0x35, 0x00, 0x22, 0x23, + 0xef, 0xe7, 0x8f, 0x75, 0x25, 0x28, 0x39, 0x06, 0x45, 0xa8, 0x98, 0xab, + 0xf8, 0x3c, 0xc7, 0xf9, 0x79, 0xd3, 0xaf, 0xc5, 0x98, 0x1f, 0xc8, 0xe5, + 0xed, 0x7e, 0x6f, 0xaf, 0x58, 0xef, 0x55, 0xff, 0xd4, 0xb0, 0x18, 0x3b, + 0xe2, 0xcf, 0x9f, 0xce, 0x7b, 0xb0, 0xa7, 0xf6, 0x84, 0x2d, 0x8f, 0xf1, + 0xf7, 0xe7, 0x9f, 0x91, 0x68, 0xcc, 0x82, 0x27, 0x4a, 0x39, 0xc6, 0xc2, + 0x43, 0x3f, 0x88, 0xab, 0xfe, 0xfc, 0xb9, 0x09, 0x94, 0x67, 0xd3, 0xe1, + 0x07, 0xbf, 0xf2, 0xb5, 0x80, 0x8e, 0x6d, 0x81, 0x3d, 0xfc, 0x42, 0x08, + 0x28, 0x31, 0xad, 0x78, 0xc4, 0x6d, 0x5b, 0x75, 0x31, 0xb7, 0xd7, 0x04, + 0xf6, 0x31, 0xf5, 0x89, 0xbe, 0x58, 0x51, 0xde, 0xaf, 0x15, 0x0e, 0x3e, + 0x54, 0x57, 0x29, 0x76, 0xaa, 0x04, 0x19, 0x5e, 0xf4, 0x87, 0x50, 0xef, + 0xe2, 0x23, 0xf6, 0x32, 0xcf, 0xc8, 0x50, 0xe0, 0xde, 0xb9, 0x93, 0x09, + 0xd7, 0x14, 0x98, 0x28, 0x7b, 0x12, 0x3b, 0xda, 0x83, 0xab, 0xe0, 0x5c, + 0x69, 0xa7, 0x2f, 0xbe, 0x82, 0x07, 0x4d, 0xbd, 0x5e, 0x9f, 0x7f, 0x24, + 0x34, 0x87, 0xa2, 0x28, 0xf3, 0xc4, 0x12, 0xf1, 0x56, 0xf2, 0x42, 0x23, + 0x82, 0xb5, 0xca, 0x43, 0xfa, 0xf2, 0x63, 0x79, 0xb9, 0x51, 0xb1, 0xc0, + 0xdb, 0x71, 0x7d, 0xb5, 0x71, 0x0f, 0xbe, 0x78, 0x42, 0x6b, 0x6f, 0x6a, + 0x8a, 0x70, 0x4b, 0x44, 0x6a, 0x8a, 0x40, 0xf0, 0x80, 0x1a, 0x21, 0x2c, + 0x63, 0xc4, 0x4d, 0x10, 0x66, 0x83, 0x90, 0x00, 0x37, 0x0b, 0x55, 0x61, + 0x88, 0xcb, 0xf5, 0x46, 0x08, 0x5a, 0x21, 0x24, 0x09, 0x28, 0x33, 0x42, + 0x48, 0x55, 0x85, 0xdc, 0x0c, 0xf1, 0x02, 0x04, 0x47, 0x1f, 0x7d, 0x1a, + 0x17, 0xe0, 0xe2, 0x37, 0xe3, 0x17, 0xa4, 0x11, 0x38, 0x0b, 0x58, 0x23, + 0x2d, 0x22, 0x92, 0x86, 0xe1, 0x30, 0xf6, 0x44, 0x4a, 0x58, 0x5d, 0xa9, + 0xd1, 0xa3, 0x2b, 0x3e, 0xff, 0xbe, 0x47, 0xd7, 0x8a, 0xa3, 0x89, 0xaf, + 0x59, 0x44, 0x72, 0x98, 0x73, 0x53, 0x09, 0x79, 0xa1, 0x6c, 0x09, 0x16, + 0x62, 0x47, 0x64, 0xc8, 0xd6, 0xf3, 0x39, 0xd7, 0xf3, 0x68, 0x80, 0x0a, + 0xbf, 0x1d, 0xee, 0x55, 0x4a, 0x20, 0xfd, 0x3a, 0xca, 0xc0, 0xb4, 0x39, + 0x6a, 0x9e, 0xb8, 0x79, 0x8f, 0x13, 0xa4, 0x36, 0x69, 0x8e, 0xac, 0x7e, + 0x34, 0x20, 0x84, 0x70, 0x2d, 0xc0, 0xd5, 0xbe, 0x95, 0x27, 0xe5, 0xc4, + 0x45, 0x59, 0xb3, 0x7e, 0xae, 0xb0, 0x7b, 0xc7, 0x6e, 0xe7, 0x15, 0x28, + 0x15, 0x0f, 0x4e, 0xc3, 0xf5, 0x67, 0x85, 0x5a, 0x18, 0x83, 0x54, 0x0a, + 0xd6, 0x98, 0x79, 0x46, 0x7f, 0xc4, 0xa1, 0x46, 0x84, 0x52, 0xb4, 0x25, + 0xd4, 0x56, 0xdd, 0x4e, 0xfd, 0x2f, 0x2a, 0x57, 0x81, 0xac, 0xe8, 0x1b, + 0xb0, 0x72, 0x5d, 0xb5, 0xaa, 0x7b, 0x86, 0xa7, 0xbc, 0xb8, 0x10, 0x36, + 0x5f, 0x9c, 0x75, 0x88, 0x90, 0xa2, 0x41, 0x6f, 0x08, 0x0a, 0x50, 0x3b, + 0x51, 0xe8, 0xf2, 0xf5, 0xbb, 0xef, 0x7a, 0xee, 0x8b, 0x84, 0xb8, 0x59, + 0x7d, 0x82, 0x4e, 0x5c, 0x49, 0xc5, 0xbf, 0x2b, 0x27, 0x14, 0x11, 0x38, + 0xc4, 0xe0, 0x58, 0x4f, 0x0f, 0xcf, 0xe1, 0xd4, 0x1b, 0x4a, 0x1a, 0x85, + 0x43, 0x14, 0x85, 0x67, 0x21, 0x67, 0xde, 0x17, 0x7f, 0x0f, 0x6a, 0x6e, + 0xb0, 0xd8, 0x06, 0xe2, 0x29, 0x87, 0xc5, 0x77, 0xfd, 0xc9, 0xf7, 0xd3, + 0xc3, 0x97, 0xee, 0xc6, 0x3b, 0x0d, 0xed, 0x4d, 0x0f, 0x59, 0xc4, 0x16, + 0xad, 0xca, 0x0f, 0xb6, 0x57, 0x2f, 0x2e, 0xae, 0xbd, 0xdb, 0xff, 0x7e, + 0xf7, 0xad, 0x0e, 0x6c, 0xa3, 0x1c, 0x86, 0x85, 0x2b, 0x7a, 0x93, 0x6a, + 0x18, 0x98, 0xdf, 0xa9, 0xd1, 0x0a, 0xc3, 0x8d, 0x71, 0xcc, 0x46, 0x63, + 0x05, 0x16, 0x21, 0xc4, 0xe5, 0xd9, 0x68, 0x10, 0xe3, 0x55, 0x69, 0xf7, + 0x45, 0x12, 0xc8, 0x48, 0xa2, 0x07, 0xd9, 0x5e, 0x06, 0xe4, 0x68, 0x01, + 0xd8, 0xc5, 0xfe, 0xf7, 0x6b, 0x3b, 0x7f, 0xee, 0x99, 0x9f, 0xf8, 0x87, + 0x1f, 0x7e, 0xc8, 0xbd, 0x8e, 0x14, 0xd2, 0xeb, 0x6a, 0x71, 0xb1, 0xb7, + 0xb9, 0x59, 0xac, 0x6d, 0xf7, 0x76, 0xe5, 0xeb, 0x93, 0xc9, 0x45, 0xb1, + 0xf4, 0x70, 0x39, 0xc8, 0xbb, 0x88, 0xa1, 0x0d, 0x7f, 0x2d, 0x2e, 0xfe, + 0x3f, 0xab, 0x3b, 0x83, 0x2b, 0x02, 0xe6, 0x03, 0x00, }; #define BUF_SIZE 0x10000 static voidpf zalloc_func(voidpf opaque, unsigned int items, unsigned int size) @@ -10828,23 +11138,25 @@ static void zfree_func(voidpf opaque, voidpf ptr) (void) opaque; free(ptr); } + +#define HEADERLEN 10 + /* Decompress and send to stdout a gzip-compressed buffer */ void hugehelp(void) { unsigned char *buf; - int status, headerlen; + int status; z_stream z; /* Make sure no gzip options are set */ if(hugehelpgz[3] & 0xfe) return; - headerlen = 10; memset(&z, 0, sizeof(z_stream)); z.zalloc = (alloc_func)zalloc_func; z.zfree = (free_func)zfree_func; - z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen); - z.next_in = (unsigned char *)hugehelpgz + headerlen; + z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN); + z.next_in = (unsigned char *)hugehelpgz + HEADERLEN; if(inflateInit2(&z, -MAX_WBITS) != Z_OK) return; @@ -10861,7 +11173,49 @@ void hugehelp(void) break; } else - break; /* Error */ + break; /* error */ + } + free(buf); + } + inflateEnd(&z); +} +/* Show the help text for the 'arg' curl argument on stdout */ +void showhelp(const char *trigger, const char *arg, const char *endarg) +{ + unsigned char *buf; + int status; + z_stream z; + struct scan_ctx ctx; + inithelpscan(&ctx, trigger, arg, endarg); + + /* Make sure no gzip options are set */ + if(hugehelpgz[3] & 0xfe) + return; + + memset(&z, 0, sizeof(z_stream)); + z.zalloc = (alloc_func)zalloc_func; + z.zfree = (free_func)zfree_func; + z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN); + z.next_in = (unsigned char *)hugehelpgz + HEADERLEN; + + if(inflateInit2(&z, -MAX_WBITS) != Z_OK) + return; + + buf = malloc(BUF_SIZE); + if(buf) { + while(1) { + z.avail_out = BUF_SIZE; + z.next_out = buf; + status = inflate(&z, Z_SYNC_FLUSH); + if(status == Z_OK || status == Z_STREAM_END) { + size_t len = BUF_SIZE - z.avail_out; + if(!helpscan(buf, len, &ctx)) + break; + if(status == Z_STREAM_END) + break; + } + else + break; /* error */ } free(buf); } diff --git a/src/tool_hugehelp.h b/src/tool_hugehelp.h index ce9af0c54..f00f88702 100644 --- a/src/tool_hugehelp.h +++ b/src/tool_hugehelp.h @@ -25,6 +25,8 @@ ***************************************************************************/ #include "tool_setup.h" +void showhelp(const char *trigger, const char *arg, const char *endarg); + #ifdef USE_MANUAL void hugehelp(void); #else diff --git a/src/tool_ipfs.c b/src/tool_ipfs.c index 62ef9f604..09bff4906 100644 --- a/src/tool_ipfs.c +++ b/src/tool_ipfs.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "dynbuf.h" diff --git a/src/tool_libinfo.c b/src/tool_libinfo.c index 2b74e4e5e..4bc22217f 100644 --- a/src/tool_libinfo.c +++ b/src/tool_libinfo.c @@ -25,8 +25,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_libinfo.h" @@ -124,6 +122,7 @@ static struct feature_name_presentp { static const char *fnames[sizeof(maybe_feature) / sizeof(maybe_feature[0])]; const char * const *feature_names = fnames; +size_t feature_count; /* * libcurl_info_init: retrieves runtime information about libcurl, @@ -182,6 +181,7 @@ CURLcode get_libcurl_info(void) *p->feature_presentp = TRUE; break; } + ++feature_count; } return CURLE_OK; diff --git a/src/tool_libinfo.h b/src/tool_libinfo.h index e69f35829..ad9c195dc 100644 --- a/src/tool_libinfo.h +++ b/src/tool_libinfo.h @@ -34,6 +34,7 @@ extern const char * const *built_in_protos; extern size_t proto_count; extern const char * const *feature_names; +extern size_t feature_count; extern const char *proto_file; extern const char *proto_ftp; diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index a825a0315..fa29a51c1 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -69,8 +69,8 @@ const struct helptxt helptext[] = { {" --cert-type ", "Certificate type (DER/PEM/ENG/P12)", CURLHELP_TLS}, - {" --ciphers ", - "SSL ciphers to use", + {" --ciphers ", + "TLS 1.2 (1.1, 1.0) ciphers to use", CURLHELP_TLS}, {" --compressed", "Request compressed response", @@ -165,6 +165,9 @@ const struct helptxt helptext[] = { {" --doh-url ", "Resolve hostnames over DoH", CURLHELP_DNS}, + {" --dump-ca-embed", + "Write the embedded CA bundle to standard output", + CURLHELP_HTTP | CURLHELP_PROXY | CURLHELP_TLS}, {"-D, --dump-header ", "Write the received headers to ", CURLHELP_HTTP | CURLHELP_FTP}, @@ -263,7 +266,7 @@ const struct helptxt helptext[] = { {"-H, --header
", "Pass custom header(s) to server", CURLHELP_HTTP | CURLHELP_IMAP | CURLHELP_SMTP}, - {"-h, --help ", + {"-h, --help ", "Get help for commands", CURLHELP_IMPORTANT | CURLHELP_CURL}, {" --hostpubmd5 ", @@ -299,9 +302,6 @@ const struct helptxt helptext[] = { {" --ignore-content-length", "Ignore the size of the remote resource", CURLHELP_HTTP | CURLHELP_FTP}, - {"-i, --include", - "Include response headers in output", - CURLHELP_IMPORTANT | CURLHELP_VERBOSE}, {"-k, --insecure", "Allow insecure server connections", CURLHELP_TLS | CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_SSH}, @@ -357,7 +357,7 @@ const struct helptxt helptext[] = { "Follow redirects", CURLHELP_HTTP}, {" --location-trusted", - "As --location, but send auth to other hosts", + "As --location, but send secrets to other hosts", CURLHELP_HTTP | CURLHELP_AUTH}, {" --login-options ", "Server login options", @@ -515,7 +515,7 @@ const struct helptxt helptext[] = { "Client certificate type for HTTPS proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-ciphers ", - "SSL ciphers to use for proxy", + "TLS 1.2 (1.1, 1.0) ciphers to use for proxy", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-crlfile ", "Set a CRL list for proxy", @@ -559,7 +559,7 @@ const struct helptxt helptext[] = { {" --proxy-ssl-auto-client-cert", "Auto client certificate for proxy", CURLHELP_PROXY | CURLHELP_TLS}, - {" --proxy-tls13-ciphers ", + {" --proxy-tls13-ciphers ", "TLS 1.3 proxy cipher suites", CURLHELP_PROXY | CURLHELP_TLS}, {" --proxy-tlsauthtype ", @@ -656,9 +656,15 @@ const struct helptxt helptext[] = { {"-S, --show-error", "Show error even when -s is used", CURLHELP_CURL | CURLHELP_GLOBAL}, + {"-i, --show-headers", + "Show response headers in output", + CURLHELP_IMPORTANT | CURLHELP_VERBOSE | CURLHELP_OUTPUT}, {"-s, --silent", "Silent mode", CURLHELP_IMPORTANT | CURLHELP_VERBOSE}, + {" --skip-existing", + "Skip download if local file already exists", + CURLHELP_CURL | CURLHELP_OUTPUT}, {" --socks4 ", "SOCKS4 proxy on given host + port", CURLHELP_PROXY}, diff --git a/src/tool_main.c b/src/tool_main.c index 9d7d1991a..01993123e 100644 --- a/src/tool_main.c +++ b/src/tool_main.c @@ -35,8 +35,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_msgs.c b/src/tool_msgs.c index 47e625c1e..58b935e96 100644 --- a/src/tool_msgs.c +++ b/src/tool_msgs.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -55,7 +53,7 @@ static void voutf(struct GlobalConfig *config, char *ptr; char *print_buffer; - print_buffer = curlx_mvaprintf(fmt, ap); + print_buffer = vaprintf(fmt, ap); if(!print_buffer) return; len = strlen(print_buffer); diff --git a/src/tool_operate.c b/src/tool_operate.c index f6ae64dd3..41fd6718c 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -49,8 +49,17 @@ # include #endif -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ +#ifdef HAVE_UV_H +/* Hack for Unity mode */ +#ifdef HEADER_CURL_MEMDEBUG_H +#undef HEADER_CURL_MEMDEBUG_H +#undef freeaddrinfo +#undef getaddrinfo +#endif +/* this is for libuv-enabled debug builds only */ +#include +#endif + #include "curlx.h" #include "tool_binmode.h" @@ -94,6 +103,10 @@ #include "memdebug.h" /* keep this as LAST include */ +#ifdef CURL_CA_EMBED +extern const unsigned char curl_ca_embed[]; +#endif + #ifndef O_BINARY /* since O_BINARY as used in bitmasks, setting it to zero makes it usable in source code but yet it does not ruin anything */ @@ -456,6 +469,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(per->infdopen) close(per->infd); + if(per->skip) + goto skip; + #ifdef __VMS if(is_vms_shell()) { /* VMS DCL shell behavior */ @@ -727,7 +743,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); setfiletime(filetime, outs->filename, global); } - +skip: /* Write the --write-out data before cleanup but after result is final */ if(config->writeout) ourWriteOut(config, per, result); @@ -824,14 +840,14 @@ static CURLcode single_transfer(struct GlobalConfig *global, httpgetfields = state->httpgetfields = config->postfields; config->postfields = NULL; if(SetHTTPrequest(config, - (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET), + (config->no_body?TOOL_HTTPREQ_HEAD:TOOL_HTTPREQ_GET), &config->httpreq)) { result = CURLE_FAILED_INIT; } } } else { - if(SetHTTPrequest(config, HTTPREQ_SIMPLEPOST, &config->httpreq)) + if(SetHTTPrequest(config, TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) result = CURLE_FAILED_INIT; } if(result) { @@ -933,6 +949,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, urlnum = state->urlnum; if(state->up < state->infilenum) { + char ssl_ver[80] = "no ssl"; struct per_transfer *per = NULL; struct OutStruct *outs; struct OutStruct *heads; @@ -1034,7 +1051,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, result = CURLE_OUT_OF_MEMORY; break; } - if(SetHTTPrequest(config, HTTPREQ_PUT, &config->httpreq)) { + if(SetHTTPrequest(config, TOOL_HTTPREQ_PUT, &config->httpreq)) { Curl_safefree(per->uploadfile); curl_easy_cleanup(curl); result = CURLE_FAILED_INIT; @@ -1053,7 +1070,12 @@ static CURLcode single_transfer(struct GlobalConfig *global, /* Single header file for all URLs */ if(config->headerfile) { /* open file for output: */ - if(strcmp(config->headerfile, "-")) { + if(!strcmp(config->headerfile, "%")) { + heads->stream = stderr; + /* use binary mode for protocol header output */ + set_binmode(heads->stream); + } + else if(strcmp(config->headerfile, "-")) { FILE *newfile; /* @@ -1143,9 +1165,13 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } if(!*per->outfile && !config->content_disposition) { - errorf(global, "Remote filename has no length"); - result = CURLE_WRITE_ERROR; - break; + free(per->outfile); + per->outfile = strdup("curl_response"); + if(!per->outfile) { + result = CURLE_OUT_OF_MEMORY; + break; + } + warnf(global, "No remote file name, uses \"%s\"", per->outfile); } } else if(state->urls) { @@ -1184,6 +1210,15 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } + if(per->outfile && config->skip_existing) { + struct_stat fileinfo; + if(!stat(per->outfile, &fileinfo)) { + /* file is present */ + notef(global, "skips transfer, \"%s\" exists locally", + per->outfile); + per->skip = TRUE; + } + } if((urlnode->flags & GETOUT_USEREMOTE) && config->content_disposition) { /* Our header callback MIGHT set the filename */ @@ -1486,7 +1521,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_TIMEOUT_MS, config->timeout_ms); switch(config->httpreq) { - case HTTPREQ_SIMPLEPOST: + case TOOL_HTTPREQ_SIMPLEPOST: if(config->resume_from) { errorf(global, "cannot mix --continue-at with --data"); result = CURLE_FAILED_INIT; @@ -1498,7 +1533,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, (curl_off_t)curlx_dyn_len(&config->postdata)); } break; - case HTTPREQ_MIMEPOST: + case TOOL_HTTPREQ_MIMEPOST: /* free previous remainders */ curl_mime_free(config->mimepost); config->mimepost = NULL; @@ -1624,6 +1659,14 @@ static CURLcode single_transfer(struct GlobalConfig *global, my_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L); } + { + /* get current SSL backend, chop off multissl */ + const char *v = curl_version_info(CURLVERSION_NOW)->ssl_version; + if(v) + msnprintf(ssl_ver, sizeof(ssl_ver), + "%.*s", (int) strcspn(v, " "), v); + } + if(config->cacert) my_setopt_str(curl, CURLOPT_CAINFO, config->cacert); if(config->proxy_cacert) @@ -1632,9 +1675,10 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->capath) { result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl", - capath_from_env? - "SSL_CERT_DIR environment variable":"--capath"); + warnf(global, "ignoring %s, not supported by libcurl with %s", + capath_from_env ? + "SSL_CERT_DIR environment variable" : "--capath", + ssl_ver); } else if(result) break; @@ -1649,14 +1693,47 @@ static CURLcode single_transfer(struct GlobalConfig *global, if((result == CURLE_NOT_BUILT_IN) || (result == CURLE_UNKNOWN_OPTION)) { if(config->proxy_capath) { - warnf(global, - "ignoring --proxy-capath, not supported by libcurl"); + warnf(global, "ignoring %s, not supported by libcurl with %s", + config->proxy_capath ? + "--proxy-capath" : "--capath", + ssl_ver); } } else if(result) break; } +#ifdef CURL_CA_EMBED + if(!config->cacert && !config->capath) { + struct curl_blob blob; + blob.data = (void *)curl_ca_embed; + blob.len = strlen((const char *)curl_ca_embed); + blob.flags = CURL_BLOB_NOCOPY; + notef(config->global, + "Using embedded CA bundle (%zu bytes)", + blob.len); + result = curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); + if(result == CURLE_NOT_BUILT_IN) { + warnf(global, "ignoring %s, not supported by libcurl with %s", + "embedded CA bundle", ssl_ver); + } + } + if(!config->proxy_cacert && !config->proxy_capath) { + struct curl_blob blob; + blob.data = (void *)curl_ca_embed; + blob.len = strlen((const char *)curl_ca_embed); + blob.flags = CURL_BLOB_NOCOPY; + notef(config->global, + "Using embedded CA bundle, for proxies (%zu bytes)", + blob.len); + result = curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); + if(result == CURLE_NOT_BUILT_IN) { + warnf(global, "ignoring %s, not supported by libcurl with %s", + "embedded CA bundle", ssl_ver); + } + } +#endif + if(config->crlfile) my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile); if(config->proxy_crlfile) @@ -1664,8 +1741,20 @@ static CURLcode single_transfer(struct GlobalConfig *global, else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */ my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile); - if(config->pinnedpubkey) - my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey); + if(config->pinnedpubkey) { + result = res_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, + config->pinnedpubkey); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--pinnedpubkey", ssl_ver); + } + if(config->proxy_pinnedpubkey) { + result = res_setopt_str(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, + config->proxy_pinnedpubkey); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--proxy-pinnedpubkey", ssl_ver); + } if(config->ssl_ec_curves) my_setopt_str(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves); @@ -1982,19 +2071,34 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(config->doh_url) my_setopt_str(curl, CURLOPT_DOH_URL, config->doh_url); - if(config->cipher_list) - my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); - - if(config->proxy_cipher_list) - my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, - config->proxy_cipher_list); - - if(config->cipher13_list) - my_setopt_str(curl, CURLOPT_TLS13_CIPHERS, config->cipher13_list); - - if(config->proxy_cipher13_list) - my_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, - config->proxy_cipher13_list); + if(config->cipher_list) { + result = res_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, + config->cipher_list); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--ciphers", ssl_ver); + } + if(config->proxy_cipher_list) { + result = res_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, + config->proxy_cipher_list); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--proxy-ciphers", ssl_ver); + } + if(config->cipher13_list) { + result = res_setopt_str(curl, CURLOPT_TLS13_CIPHERS, + config->cipher13_list); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--tls13-ciphers", ssl_ver); + } + if(config->proxy_cipher13_list) { + result = res_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, + config->proxy_cipher13_list); + if(result == CURLE_NOT_BUILT_IN) + warnf(global, "ignoring %s, not supported by libcurl with %s", + "--proxy-tls13-ciphers", ssl_ver); + } /* new in libcurl 7.9.2: */ if(config->disable_epsv) @@ -2389,6 +2493,10 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb); (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per); (void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L); +#ifdef DEBUGBUILD + if(getenv("CURL_FORBID_REUSE")) + (void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L); +#endif mcode = curl_multi_add_handle(multi, per->curl); if(mcode) { @@ -2413,136 +2521,386 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, return CURLE_OK; } -static CURLcode parallel_transfers(struct GlobalConfig *global, - CURLSH *share) -{ +struct parastate { + struct GlobalConfig *global; CURLM *multi; - CURLMcode mcode = CURLM_OK; - CURLcode result = CURLE_OK; - int still_running = 1; - struct timeval start = tvnow(); + CURLSH *share; + CURLMcode mcode; + CURLcode result; + int still_running; + struct timeval start; bool more_transfers; bool added_transfers; /* wrapitup is set TRUE after a critical error occurs to end all transfers */ - bool wrapitup = FALSE; + bool wrapitup; /* wrapitup_processed is set TRUE after the per transfer abort flag is set */ - bool wrapitup_processed = FALSE; - time_t tick = time(NULL); + bool wrapitup_processed; + time_t tick; +}; + +#if defined(DEBUGBUILD) && defined(USE_LIBUV) + +#define DEBUG_UV 0 + +/* object to pass to the callbacks */ +struct datauv { + uv_timer_t timeout; + uv_loop_t *loop; + struct parastate *s; +}; + +struct contextuv { + uv_poll_t poll_handle; + curl_socket_t sockfd; + struct datauv *uv; +}; + +static CURLcode check_finished(struct parastate *s); + +static void check_multi_info(struct datauv *uv) +{ + CURLcode result; + + result = check_finished(uv->s); + if(result && !uv->s->result) + uv->s->result = result; + + if(uv->s->more_transfers) { + result = add_parallel_transfers(uv->s->global, uv->s->multi, + uv->s->share, + &uv->s->more_transfers, + &uv->s->added_transfers); + if(result && !uv->s->result) + uv->s->result = result; + if(result) + uv_stop(uv->loop); + } +} + +/* callback from libuv on socket activity */ +static void on_uv_socket(uv_poll_t *req, int status, int events) +{ + int flags = 0; + struct contextuv *c = (struct contextuv *) req->data; + (void)status; + if(events & UV_READABLE) + flags |= CURL_CSELECT_IN; + if(events & UV_WRITABLE) + flags |= CURL_CSELECT_OUT; + + curl_multi_socket_action(c->uv->s->multi, c->sockfd, flags, + &c->uv->s->still_running); +} + +/* callback from libuv when timeout expires */ +static void on_uv_timeout(uv_timer_t *req) +{ + struct datauv *uv = (struct datauv *) req->data; +#if DEBUG_UV + fprintf(tool_stderr, "parallel_event: on_uv_timeout\n"); +#endif + if(uv && uv->s) { + curl_multi_socket_action(uv->s->multi, CURL_SOCKET_TIMEOUT, 0, + &uv->s->still_running); + check_multi_info(uv); + } +} + +/* callback from libcurl to update the timeout expiry */ +static int cb_timeout(CURLM *multi, long timeout_ms, + struct datauv *uv) +{ + (void)multi; +#if DEBUG_UV + fprintf(tool_stderr, "parallel_event: cb_timeout=%ld\n", timeout_ms); +#endif + if(timeout_ms < 0) + uv_timer_stop(&uv->timeout); + else { + if(timeout_ms == 0) + timeout_ms = 1; /* 0 means call curl_multi_socket_action asap but NOT + within the callback itself */ + uv_timer_start(&uv->timeout, on_uv_timeout, timeout_ms, + 0); /* do not repeat */ + } + return 0; +} + +static struct contextuv *create_context(curl_socket_t sockfd, + struct datauv *uv) +{ + struct contextuv *c; + + c = (struct contextuv *) malloc(sizeof(*c)); + + c->sockfd = sockfd; + c->uv = uv; + + uv_poll_init_socket(uv->loop, &c->poll_handle, sockfd); + c->poll_handle.data = c; + + return c; +} + +static void close_cb(uv_handle_t *handle) +{ + struct contextuv *c = (struct contextuv *) handle->data; + free(c); +} + +static void destroy_context(struct contextuv *c) +{ + uv_close((uv_handle_t *) &c->poll_handle, close_cb); +} + +/* callback from libcurl to update socket activity to wait for */ +static int cb_socket(CURL *easy, curl_socket_t s, int action, + struct datauv *uv, + void *socketp) +{ + struct contextuv *c; + int events = 0; + (void)easy; + + switch(action) { + case CURL_POLL_IN: + case CURL_POLL_OUT: + case CURL_POLL_INOUT: + c = socketp ? + (struct contextuv *) socketp : create_context(s, uv); + + curl_multi_assign(uv->s->multi, s, c); + + if(action != CURL_POLL_IN) + events |= UV_WRITABLE; + if(action != CURL_POLL_OUT) + events |= UV_READABLE; - multi = curl_multi_init(); - if(!multi) + uv_poll_start(&c->poll_handle, events, on_uv_socket); + break; + case CURL_POLL_REMOVE: + if(socketp) { + c = (struct contextuv *)socketp; + uv_poll_stop(&c->poll_handle); + destroy_context(c); + curl_multi_assign(uv->s->multi, s, NULL); + /* check if we can do more now */ + check_multi_info(uv); + } + break; + default: + abort(); + } + + return 0; +} + +static CURLcode parallel_event(struct parastate *s) +{ + CURLcode result = CURLE_OK; + struct datauv uv = { 0 }; + + s->result = CURLE_OK; + uv.s = s; + uv.loop = uv_default_loop(); + uv_timer_init(uv.loop, &uv.timeout); + uv.timeout.data = &uv; + + /* setup event callbacks */ + curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, cb_socket); + curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, &uv); + curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, cb_timeout); + curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, &uv); + + /* kickstart the thing */ + curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, + &s->still_running); + + while(!s->mcode && (s->still_running || s->more_transfers)) { +#if DEBUG_UV + fprintf(tool_stderr, "parallel_event: uv_run(), mcode=%d, %d running, " + "%d more\n", s->mcode, uv.s->still_running, s->more_transfers); +#endif + uv_run(uv.loop, UV_RUN_DEFAULT); +#if DEBUG_UV + fprintf(tool_stderr, "parallel_event: uv_run() returned\n"); +#endif + + result = check_finished(s); + if(result && !s->result) + s->result = result; + + /* early exit called */ + if(s->wrapitup) { + if(s->still_running && !s->wrapitup_processed) { + struct per_transfer *per; + for(per = transfers; per; per = per->next) { + if(per->added) + per->abort = TRUE; + } + s->wrapitup_processed = TRUE; + } + break; + } + + if(s->more_transfers) { + result = add_parallel_transfers(s->global, s->multi, s->share, + &s->more_transfers, &s->added_transfers); + if(result && !s->result) + s->result = result; + } + } + +#if DEBUG_UV + fprintf(tool_stderr, "DONE parallel_event -> %d, mcode=%d, %d running, " + "%d more\n", + s->result, s->mcode, uv.s->still_running, s->more_transfers); +#endif + return s->result; +} + +#endif + +static CURLcode check_finished(struct parastate *s) +{ + CURLcode result = CURLE_OK; + int rc; + CURLMsg *msg; + bool checkmore = FALSE; + struct GlobalConfig *global = s->global; + progress_meter(global, &s->start, FALSE); + do { + msg = curl_multi_info_read(s->multi, &rc); + if(msg) { + bool retry; + long delay; + struct per_transfer *ended; + CURL *easy = msg->easy_handle; + CURLcode tres = msg->data.result; + curl_easy_getinfo(easy, CURLINFO_PRIVATE, (void *)&ended); + curl_multi_remove_handle(s->multi, easy); + + if(ended->abort && (tres == CURLE_ABORTED_BY_CALLBACK) && + ended->errorbuffer) { + msnprintf(ended->errorbuffer, CURL_ERROR_SIZE, + "Transfer aborted due to critical error " + "in another transfer"); + } + tres = post_per_transfer(global, ended, tres, &retry, &delay); + progress_finalize(ended); /* before it goes away */ + all_added--; /* one fewer added */ + checkmore = TRUE; + if(retry) { + ended->added = FALSE; /* add it again */ + /* we delay retries in full integer seconds only */ + ended->startat = delay ? time(NULL) + delay/1000 : 0; + } + else { + /* result receives this transfer's error unless the transfer was + marked for abort due to a critical error in another transfer */ + if(tres && (!ended->abort || !result)) + result = tres; + if(is_fatal_error(result) || (result && global->fail_early)) + s->wrapitup = TRUE; + (void)del_per_transfer(ended); + } + } + } while(msg); + if(!s->wrapitup) { + if(!checkmore) { + time_t tock = time(NULL); + if(s->tick != tock) { + checkmore = TRUE; + s->tick = tock; + } + } + if(checkmore) { + /* one or more transfers completed, add more! */ + CURLcode tres = add_parallel_transfers(global, s->multi, s->share, + &s->more_transfers, + &s->added_transfers); + if(tres) + result = tres; + if(s->added_transfers) + /* we added new ones, make sure the loop does not exit yet */ + s->still_running = 1; + } + if(is_fatal_error(result) || (result && global->fail_early)) + s->wrapitup = TRUE; + } + return result; +} + +static CURLcode parallel_transfers(struct GlobalConfig *global, + CURLSH *share) +{ + CURLcode result; + struct parastate p; + struct parastate *s = &p; + s->share = share; + s->mcode = CURLM_OK; + s->result = CURLE_OK; + s->still_running = 1; + s->start = tvnow(); + s->wrapitup = FALSE; + s->wrapitup_processed = FALSE; + s->tick = time(NULL); + s->global = global; + s->multi = curl_multi_init(); + if(!s->multi) return CURLE_OUT_OF_MEMORY; - result = add_parallel_transfers(global, multi, share, - &more_transfers, &added_transfers); + result = add_parallel_transfers(global, s->multi, s->share, + &s->more_transfers, &s->added_transfers); if(result) { - curl_multi_cleanup(multi); + curl_multi_cleanup(s->multi); return result; } - while(!mcode && (still_running || more_transfers)) { +#ifdef DEBUGBUILD + if(global->test_event_based) +#ifdef USE_LIBUV + result = parallel_event(s); +#else + errorf(global, "Testing --parallel event-based requires libuv"); +#endif + else +#endif + while(!s->mcode && (s->still_running || s->more_transfers)) { /* If stopping prematurely (eg due to a --fail-early condition) then signal that any transfers in the multi should abort (via progress callback). */ - if(wrapitup) { - if(!still_running) + if(s->wrapitup) { + if(!s->still_running) break; - if(!wrapitup_processed) { + if(!s->wrapitup_processed) { struct per_transfer *per; for(per = transfers; per; per = per->next) { if(per->added) per->abort = TRUE; } - wrapitup_processed = TRUE; + s->wrapitup_processed = TRUE; } } - mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); - if(!mcode) - mcode = curl_multi_perform(multi, &still_running); - - progress_meter(global, &start, FALSE); - - if(!mcode) { - int rc; - CURLMsg *msg; - bool checkmore = FALSE; - do { - msg = curl_multi_info_read(multi, &rc); - if(msg) { - bool retry; - long delay; - struct per_transfer *ended; - CURL *easy = msg->easy_handle; - CURLcode tres = msg->data.result; - curl_easy_getinfo(easy, CURLINFO_PRIVATE, (void *)&ended); - curl_multi_remove_handle(multi, easy); - - if(ended->abort && (tres == CURLE_ABORTED_BY_CALLBACK) && - ended->errorbuffer) { - msnprintf(ended->errorbuffer, CURL_ERROR_SIZE, - "Transfer aborted due to critical error " - "in another transfer"); - } - tres = post_per_transfer(global, ended, tres, &retry, &delay); - progress_finalize(ended); /* before it goes away */ - all_added--; /* one fewer added */ - checkmore = TRUE; - if(retry) { - ended->added = FALSE; /* add it again */ - /* we delay retries in full integer seconds only */ - ended->startat = delay ? time(NULL) + delay/1000 : 0; - } - else { - /* result receives this transfer's error unless the transfer was - marked for abort due to a critical error in another transfer */ - if(tres && (!ended->abort || !result)) - result = tres; - if(is_fatal_error(result) || (result && global->fail_early)) - wrapitup = TRUE; - (void)del_per_transfer(ended); - } - } - } while(msg); - if(wrapitup) { - if(still_running) - continue; - else - break; - } - if(!checkmore) { - time_t tock = time(NULL); - if(tick != tock) { - checkmore = TRUE; - tick = tock; - } - } - if(checkmore) { - /* one or more transfers completed, add more! */ - CURLcode tres = add_parallel_transfers(global, multi, share, - &more_transfers, - &added_transfers); - if(tres) - result = tres; - if(added_transfers) - /* we added new ones, make sure the loop does not exit yet */ - still_running = 1; - } - if(is_fatal_error(result) || (result && global->fail_early)) - wrapitup = TRUE; - } + s->mcode = curl_multi_poll(s->multi, NULL, 0, 1000, NULL); + if(!s->mcode) + s->mcode = curl_multi_perform(s->multi, &s->still_running); + + if(!s->mcode) + result = check_finished(s); } - (void)progress_meter(global, &start, TRUE); + (void)progress_meter(global, &s->start, TRUE); /* Make sure to return some kind of error if there was a multi problem */ - if(mcode) { - result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : + if(s->mcode) { + result = (s->mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : /* The other multi errors should never happen, so return something suitably generic */ CURLE_BAD_FUNCTION_ARGUMENT; } - curl_multi_cleanup(multi); + curl_multi_cleanup(s->multi); return result; } @@ -2567,25 +2925,29 @@ static CURLcode serial_transfers(struct GlobalConfig *global, long delay_ms; bool bailout = FALSE; struct timeval start; - result = pre_transfer(global, per); - if(result) - break; - if(global->libcurl) { - result = easysrc_perform(); + start = tvnow(); + if(!per->skip) { + result = pre_transfer(global, per); if(result) break; - } - start = tvnow(); + + if(global->libcurl) { + result = easysrc_perform(); + if(result) + break; + } + #ifdef DEBUGBUILD - if(getenv("CURL_FORBID_REUSE")) - (void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L); + if(getenv("CURL_FORBID_REUSE")) + (void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L); - if(global->test_event_based) - result = curl_easy_perform_ev(per->curl); - else + if(global->test_event_based) + result = curl_easy_perform_ev(per->curl); + else #endif - result = curl_easy_perform(per->curl); + result = curl_easy_perform(per->curl); + } returncode = post_per_transfer(global, per, result, &retry, &delay_ms); if(retry) { @@ -2648,10 +3010,10 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, return CURLE_FAILED_INIT; } - /* On WIN32 we cannot set the path to curl-ca-bundle.crt at compile time. We - * look for the file in two ways: + /* On Windows we cannot set the path to curl-ca-bundle.crt at compile time. + * We look for the file in two ways: * 1: look at the environment variable CURL_CA_BUNDLE for a path - * 2: if #1 is not found, use the windows API function SearchPath() + * 2: if #1 is not found, use the Windows API function SearchPath() * to find it along the app's path (includes app's dir and CWD) * * We support the environment variable thing for non-Windows platforms @@ -2842,6 +3204,12 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) /* Check if we were asked to list the SSL engines */ else if(res == PARAM_ENGINES_REQUESTED) tool_list_engines(); + /* Check if we were asked to dump the embedded CA bundle */ + else if(res == PARAM_CA_EMBED_REQUESTED) { +#ifdef CURL_CA_EMBED + printf("%s", curl_ca_embed); +#endif + } else if(res == PARAM_LIBCURL_UNSUPPORTED_PROTOCOL) result = CURLE_UNSUPPORTED_PROTOCOL; else if(res == PARAM_READ_ERROR) diff --git a/src/tool_operate.h b/src/tool_operate.h index 820ac1395..a2bd83b10 100644 --- a/src/tool_operate.h +++ b/src/tool_operate.h @@ -44,25 +44,16 @@ struct per_transfer { char *this_url; unsigned int urlnum; /* the index of the given URL */ char *outfile; - bool infdopen; /* TRUE if infd needs closing */ int infd; - bool noprogress; struct ProgressData progressbar; struct OutStruct outs; struct OutStruct heads; struct OutStruct etag_save; struct HdrCbData hdrcbdata; long num_headers; - bool was_last_header_empty; - - bool added; /* set TRUE when added to the multi handle */ time_t startat; /* when doing parallel transfers, this is a retry transfer that has been set to sleep until this time before it should get started (again) */ - bool abort; /* when doing parallel transfers and this is TRUE then a critical - error (eg --fail-early) has occurred in another transfer and - this transfer will be aborted in the progress callback */ - /* for parallel progress bar */ curl_off_t dltotal; curl_off_t dlnow; @@ -77,6 +68,15 @@ struct per_transfer { char *uploadfile; char *errorbuffer; /* allocated and assigned while this is used for a transfer */ + bool infdopen; /* TRUE if infd needs closing */ + bool noprogress; + bool was_last_header_empty; + + bool added; /* set TRUE when added to the multi handle */ + bool abort; /* when doing parallel transfers and this is TRUE then a critical + error (eg --fail-early) has occurred in another transfer and + this transfer will be aborted in the progress callback */ + bool skip; /* considered already done */ }; CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]); diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index e2e2d4c3c..7dce5ff0c 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -26,8 +26,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -182,7 +180,6 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) */ CURLcode get_url_file_name(char **filename, const char *url) { - const char *pc, *pc2; CURLU *uh = curl_url(); char *path = NULL; CURLUcode uerr; @@ -195,20 +192,29 @@ CURLcode get_url_file_name(char **filename, const char *url) uerr = curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME); if(!uerr) { uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0); + curl_url_cleanup(uh); + uh = NULL; if(!uerr) { - curl_url_cleanup(uh); - - pc = strrchr(path, '/'); - pc2 = strrchr(pc ? pc + 1 : path, '\\'); - if(pc2) - pc = pc2; + int i; + char *pc = NULL, *pc2 = NULL; + for(i = 0; i < 2; i++) { + pc = strrchr(path, '/'); + pc2 = strrchr(pc ? pc + 1 : path, '\\'); + if(pc2) + pc = pc2; + if(pc && !pc[1] && !i) { + /* if the path ends with slash, try removing the trailing one + and get the last directory part */ + *pc = 0; + } + } if(pc) /* duplicate the string beyond the slash */ pc++; else /* no slash => empty string */ - pc = ""; + pc = (char *)""; *filename = strdup(pc); curl_free(path); diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index 82c0041d4..d4024e134 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -25,8 +25,6 @@ #include "strcase.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -90,12 +88,11 @@ static size_t memcrlf(char *orig, return total; /* no delimiter found */ } -#define MAX_FILE2STRING (256*1024*1024) /* big enough ? */ +#define MAX_FILE2STRING MAX_FILE2MEMORY ParameterError file2string(char **bufp, FILE *file) { struct curlx_dynbuf dyn; - DEBUGASSERT(MAX_FILE2STRING < INT_MAX); /* needs to fit in an int later */ curlx_dyn_init(&dyn, MAX_FILE2STRING); if(file) { do { @@ -133,7 +130,6 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file) size_t nread; struct curlx_dynbuf dyn; /* The size needs to fit in an int later */ - DEBUGASSERT(MAX_FILE2MEMORY < INT_MAX); curlx_dyn_init(&dyn, MAX_FILE2MEMORY); do { char buffer[4096]; @@ -561,13 +557,13 @@ static CURLcode checkpasswd(const char *kind, /* for what purpose */ /* build a nice-looking prompt */ if(!i && last) - curlx_msnprintf(prompt, sizeof(prompt), - "Enter %s password for user '%s':", - kind, *userpwd); + msnprintf(prompt, sizeof(prompt), + "Enter %s password for user '%s':", + kind, *userpwd); else - curlx_msnprintf(prompt, sizeof(prompt), - "Enter %s password for user '%s' on URL #%zu:", - kind, *userpwd, i + 1); + msnprintf(prompt, sizeof(prompt), + "Enter %s password for user '%s' on URL #%zu:", + kind, *userpwd, i + 1); /* get password */ getpass_r(prompt, passwd, sizeof(passwd)); diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h index 96c49ac59..bd703afc8 100644 --- a/src/tool_paramhlp.h +++ b/src/tool_paramhlp.h @@ -30,7 +30,11 @@ struct getout *new_getout(struct OperationConfig *config); ParameterError file2string(char **bufp, FILE *file); -#define MAX_FILE2MEMORY (1024*1024*1024) /* big enough ? */ +#if SIZEOF_SIZE_T > 4 +#define MAX_FILE2MEMORY (16LL*1024*1024*1024) +#else +#define MAX_FILE2MEMORY (INT_MAX) +#endif ParameterError file2memory(char **bufp, size_t *size, FILE *file); diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index d0a3159f5..6da5a9250 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" @@ -262,7 +260,8 @@ int parseconfig(const char *filename, struct GlobalConfig *global) if(res != PARAM_HELP_REQUESTED && res != PARAM_MANUAL_REQUESTED && res != PARAM_VERSION_INFO_REQUESTED && - res != PARAM_ENGINES_REQUESTED) { + res != PARAM_ENGINES_REQUESTED && + res != PARAM_CA_EMBED_REQUESTED) { const char *reason = param2text(res); errorf(operation->global, "%s:%d: '%s' %s", filename, lineno, option, reason); diff --git a/src/tool_progress.c b/src/tool_progress.c index cf3e4c2f6..3fac70a70 100644 --- a/src/tool_progress.c +++ b/src/tool_progress.c @@ -26,8 +26,6 @@ #include "tool_progress.h" #include "tool_util.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" /* The point of this function would be to return a string of the input data, diff --git a/src/tool_sdecls.h b/src/tool_sdecls.h index 2d83adb8f..2dee9d314 100644 --- a/src/tool_sdecls.h +++ b/src/tool_sdecls.h @@ -114,12 +114,12 @@ typedef enum { */ typedef enum { - HTTPREQ_UNSPEC, /* first in list */ - HTTPREQ_GET, - HTTPREQ_HEAD, - HTTPREQ_MIMEPOST, - HTTPREQ_SIMPLEPOST, - HTTPREQ_PUT + TOOL_HTTPREQ_UNSPEC, /* first in list */ + TOOL_HTTPREQ_GET, + TOOL_HTTPREQ_HEAD, + TOOL_HTTPREQ_MIMEPOST, + TOOL_HTTPREQ_SIMPLEPOST, + TOOL_HTTPREQ_PUT } HttpReq; diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 4ec101657..52ae0f960 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -25,8 +25,6 @@ #ifndef CURL_DISABLE_LIBCURL_OPTION -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 7c43b26c3..35f472d4f 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_doswin.h" diff --git a/src/tool_version.h b/src/tool_version.h index 4eb24e3af..db3b8dba5 100644 --- a/src/tool_version.h +++ b/src/tool_version.h @@ -27,7 +27,7 @@ #define CURL_NAME "curl" #define CURL_COPYRIGHT LIBCURL_COPYRIGHT -#define CURL_VERSION "8.9.1" +#define CURL_VERSION "8.10.0" #define CURL_VERSION_MAJOR LIBCURL_VERSION_MAJOR #define CURL_VERSION_MINOR LIBCURL_VERSION_MINOR #define CURL_VERSION_PATCH LIBCURL_VERSION_PATCH diff --git a/src/tool_vms.c b/src/tool_vms.c index 7fc23e77e..8ac9fc409 100644 --- a/src/tool_vms.c +++ b/src/tool_vms.c @@ -30,7 +30,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF #include "curlx.h" #include "curlmsg_vms.h" @@ -94,7 +93,7 @@ void vms_special_exit(int code, int vms_show) { int vms_code; - /* The Posix exit mode is only available after VMS 7.0 */ + /* The POSIX exit mode is only available after VMS 7.0 */ #if __CRTL_VER >= 70000000 if(is_vms_shell() == 0) { decc$__posix_exit(code); diff --git a/src/tool_writeout.c b/src/tool_writeout.c index 20945cf48..141178c33 100644 --- a/src/tool_writeout.c +++ b/src/tool_writeout.c @@ -22,8 +22,7 @@ * ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ + #include "curlx.h" #include "tool_cfgable.h" #include "tool_writeout.h" @@ -119,6 +118,8 @@ static const struct writeoutvar variables[] = { {"time_connect", VAR_CONNECT_TIME, CURLINFO_CONNECT_TIME_T, writeTime}, {"time_namelookup", VAR_NAMELOOKUP_TIME, CURLINFO_NAMELOOKUP_TIME_T, writeTime}, + {"time_posttransfer", VAR_POSTTRANSFER_TIME, CURLINFO_POSTTRANSFER_TIME_T, + writeTime}, {"time_pretransfer", VAR_PRETRANSFER_TIME, CURLINFO_PRETRANSFER_TIME_T, writeTime}, {"time_redirect", VAR_REDIRECT_TIME, CURLINFO_REDIRECT_TIME_T, writeTime}, @@ -198,7 +199,7 @@ static int urlpart(struct per_transfer *per, writeoutid vid, char *part = NULL; const char *url = NULL; - if(vid >= VAR_INPUT_URLEHOST) { + if(vid >= VAR_INPUT_URLESCHEME) { if(curl_easy_getinfo(per->curl, CURLINFO_EFFECTIVE_URL, &url)) rc = 5; } diff --git a/src/tool_writeout.h b/src/tool_writeout.h index 36b218cc4..7b3ca7bd0 100644 --- a/src/tool_writeout.h +++ b/src/tool_writeout.h @@ -57,7 +57,7 @@ typedef enum { VAR_INPUT_URLFRAGMENT, VAR_INPUT_URLZONEID, /* the same ones again for url *effective* */ - VAR_INPUT_URLESCHEME, + VAR_INPUT_URLESCHEME, /* keep this the first URLE* variable */ VAR_INPUT_URLEUSER, VAR_INPUT_URLEPASSWORD, VAR_INPUT_URLEOPTIONS, @@ -77,6 +77,7 @@ typedef enum { VAR_NUM_RETRY, VAR_ONERROR, VAR_PRETRANSFER_TIME, + VAR_POSTTRANSFER_TIME, VAR_PRIMARY_IP, VAR_PRIMARY_PORT, VAR_PROXY_SSL_VERIFY_RESULT, diff --git a/src/tool_writeout_json.c b/src/tool_writeout_json.c index feb791da9..205b702ae 100644 --- a/src/tool_writeout_json.c +++ b/src/tool_writeout_json.c @@ -23,9 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF - -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" #include "tool_writeout_json.h" diff --git a/src/var.c b/src/var.c index fb028667d..dbcef3c11 100644 --- a/src/var.c +++ b/src/var.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "tool_setup.h" -#define ENABLE_CURLX_PRINTF -/* use our own printf() functions */ #include "curlx.h" #include "tool_cfgable.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 53e39e01b..ce9861434 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,22 +23,32 @@ ########################################################################### set(CMAKE_UNITY_BUILD OFF) +find_program(TEST_NGHTTPX "nghttpx") +if(NOT TEST_NGHTTPX) + set(TEST_NGHTTPX "nghttpx") +endif() +mark_as_advanced(TEST_NGHTTPX) +# Consumed variables: TEST_NGHTTPX +configure_file("config.in" "${CMAKE_CURRENT_BINARY_DIR}/config" @ONLY) + add_custom_target(testdeps) -add_subdirectory(data) -add_subdirectory(libtest) +add_subdirectory(http) +add_subdirectory(http/clients) add_subdirectory(server) +add_subdirectory(libtest) add_subdirectory(unit) +add_subdirectory(certs EXCLUDE_FROM_ALL) -function(add_runtests targetname test_flags) +function(add_runtests _targetname _test_flags) # Use a special '$TFLAGS' placeholder as last argument which will be # replaced by the contents of the environment variable in runtests.pl. # This is a workaround for CMake's limitation where commands executed by # 'make' or 'ninja' cannot portably reference environment variables. - string(REPLACE " " ";" test_flags_list "${test_flags}") - add_custom_target(${targetname} + string(REPLACE " " ";" _test_flags_list "${_test_flags}") + add_custom_target(${_targetname} COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runtests.pl" - ${test_flags_list} + ${_test_flags_list} "\$TFLAGS" DEPENDS testdeps VERBATIM USES_TERMINAL @@ -48,7 +58,7 @@ endfunction() # Create configurehelp.pm, used by tests needing to run the C preprocessor. if(MSVC OR CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") set(_cpp_cmd "\"${CMAKE_C_COMPILER}\" -E") - if(APPLE AND NOT CMAKE_OSX_SYSROOT STREQUAL "") + if(APPLE AND CMAKE_OSX_SYSROOT) set(_cpp_cmd "${_cpp_cmd} -isysroot ${CMAKE_OSX_SYSROOT}") endif() # Add header directories, like autotools builds do. @@ -84,11 +94,30 @@ use vars qw( 1; ") +# Save build info for test runner to pick up and log +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/buildinfo.txt" "# This is a generated file. Do not edit. +configure.tool: cmake +configure.command: ${CMAKE_COMMAND} +configure.version: ${CMAKE_VERSION} +configure.os: ${CMAKE_SYSTEM} +configure.args:${_cmake_args} +configure.generator: ${CMAKE_GENERATOR} +configure.make: ${CMAKE_MAKE_PROGRAM} +host.os: ${CMAKE_HOST_SYSTEM_NAME} +host.cpu: ${CMAKE_HOST_SYSTEM_PROCESSOR} +target: ${CMAKE_C_COMPILER_TARGET} +target.os: ${CMAKE_SYSTEM_NAME} +target.cpu: ${CMAKE_SYSTEM_PROCESSOR} +target.flags:${_target_flags} +compiler: ${CMAKE_C_COMPILER_ID} +compiler.version: ${CMAKE_C_COMPILER_VERSION} +") + add_runtests(test-quiet "-a -s") add_runtests(test-am "-a -am") add_runtests(test-full "-a -p -r") -# ~flaky means that it'll ignore results of tests using the flaky keyword +# ~flaky means that it ignores results of tests using the flaky keyword add_runtests(test-nonflaky "-a -p ~flaky ~timing-dependent") -add_runtests(test-ci "-a -p ~flaky ~timing-dependent -r -rm") +add_runtests(test-ci "-a -p ~flaky ~timing-dependent -r -rm -j2") add_runtests(test-torture "-a -t") add_runtests(test-event "-a -e") diff --git a/tests/FILEFORMAT.md b/tests/FILEFORMAT.md index 2c36a91cd..a9ae97ff0 100644 --- a/tests/FILEFORMAT.md +++ b/tests/FILEFORMAT.md @@ -23,9 +23,9 @@ with a `testcase` tag, which encompasses the remainder of the file. # Preprocessing When a test is to be executed, the source file is first preprocessed and -variables are substituted by their respective contents and the output -version of the test file is stored as `%LOGDIR/testNUM`. That version is what -will be read and used by the test servers. +variables are substituted by their respective contents and the output version +of the test file is stored as `%LOGDIR/testNUM`. That version is what is read +and used by the test servers. ## Base64 Encoding @@ -80,7 +80,7 @@ This instruction allows a test case to include another file. It is helpful to remember that the ordinary variables are expanded before the include happens so `%LOGDIR` and the others can be used in the include line. -The file name cannot contain `%` as that letter is used to end the name for +The filename cannot contain `%` as that letter is used to end the name for the include instruction: %include filename% @@ -89,7 +89,7 @@ the include instruction: Lines in the test file can be made to appear conditionally on a specific feature (see the "features" section below) being set or not set. If the -specific feature is present, the following lines will be output, otherwise it +specific feature is present, the following lines are output, otherwise it outputs nothing, until a following else or `endif` clause. Like this: %if brotli @@ -116,7 +116,7 @@ Nested conditions are supported. # Variables -When the test is preprocessed, a range of "variables" in the test file will be +When the test is preprocessed, a range of "variables" in the test file is replaced by their content at that time. Available substitute variables include: @@ -152,7 +152,7 @@ Available substitute variables include: - `%NOLISTENPORT` - Port number where no service is listening - `%POP36PORT` - IPv6 port number of the POP3 server - `%POP3PORT` - Port number of the POP3 server -- `%POSIX_PWD` - Current directory somewhat mingw friendly +- `%POSIX_PWD` - Current directory somewhat MinGW friendly - `%PROXYPORT` - Port number of the HTTP proxy - `%PWD` - Current directory - `%RTSP6PORT` - IPv6 port number of the RTSP server @@ -193,13 +193,13 @@ requests curl sends been run ended up correct Each main section has a number of available subsections that can be specified, -that will be checked/used if specified. +that are checked/used if specified. ## `` ### `` A newline-separated list of keywords describing what this test case uses and -tests. Try to use already used keywords. These keywords will be used for +tests. Try to use already used keywords. These keywords are used for statistical/informational purposes and for choosing or skipping classes of tests. Keywords must begin with an alphabetic character, `-`, `[` or `{` and may actually consist of multiple words separated by spaces which are treated @@ -229,24 +229,24 @@ arrived safely. Set `nocheck="yes"` to prevent the test script from verifying the arrival of this data. If the data contains `swsclose` anywhere within the start and end tag, and -this is an HTTP test, then the connection will be closed by the server after -this response is sent. If not, the connection will be kept persistent. +this is an HTTP test, then the connection is closed by the server after this +response is sent. If not, the connection is kept persistent. If the data contains `swsbounce` anywhere within the start and end tag, the -HTTP server will detect if this is a second request using the same test and -part number and will then increase the part number with one. This is useful -for auth tests and similar. +HTTP server detects if this is a second request using the same test and part +number and then increases the part number with one. This is useful for auth +tests and similar. -`sendzero=yes` means that the (FTP) server will "send" the data even if the -size is zero bytes. Used to verify curl's behavior on zero bytes transfers. +`sendzero=yes` means that the (FTP) server "sends" the data even if the size +is zero bytes. Used to verify curl's behavior on zero bytes transfers. `base64=yes` means that the data provided in the test-file is a chunk of data encoded with base64. It is the only way a test case can contain binary -data. (This attribute can in fact be used on any section, but it doesn't make +data. (This attribute can in fact be used on any section, but it does not make much sense for other sections than "data"). -`hex=yes` means that the data is a sequence of hex pairs. It will get decoded -and used as "raw" data. +`hex=yes` means that the data is a sequence of hex pairs. It gets decoded and +used as "raw" data. `nonewline=yes` means that the last byte (the trailing newline character) should be cut off from the data before sending or comparing it. @@ -255,10 +255,10 @@ should be cut off from the data before sending or comparing it. the source file. Note that this makes runtests.pl parse and "guess" what is a header and what is not in order to apply the CRLF line endings appropriately. -For FTP file listings, the `` section will be used *only* if you make -sure that there has been a CWD done first to a directory named `test-[NUM]` -where `NUM` is the test case number. Otherwise the ftp server can't know from -which test file to load the list content. +For FTP file listings, the `` section is be used *only* if you make sure +that there has been a CWD done first to a directory named `test-[NUM]` where +`NUM` is the test case number. Otherwise the ftp server cannot know from which +test file to load the list content. ### `` @@ -289,8 +289,8 @@ Address type and address details as logged by the SOCKS proxy. ### `` if the data is sent but this is what should be checked afterwards. If -`nonewline=yes` is set, runtests will cut off the trailing newline from the -data before comparing with the one actually received by the client. +`nonewline=yes` is set, runtests cuts off the trailing newline from the data +before comparing with the one actually received by the client. Use the `mode="text"` attribute if the output is in text mode on platforms that have a text/binary difference. @@ -300,11 +300,11 @@ The contents of numbered `datacheck` sections are appended to the non-numbered one. ### `` -number to return on a ftp SIZE command (set to -1 to make this command fail) +number to return on an ftp SIZE command (set to -1 to make this command fail) ### `` what to send back if the client sends a (FTP) `MDTM` command, set to -1 to -have it return that the file doesn't exist +have it return that the file does not exist ### `` special purpose server-command to control its behavior *after* the @@ -316,15 +316,15 @@ For HTTP/HTTPS, these are supported: ### `` Special-commands for the server. -The first line of this file will always be set to `Testnum [number]` by the -test script, to allow servers to read that to know what test the client is -about to issue. +The first line of this file is always set to `Testnum [number]` by the test +script, to allow servers to read that to know what test the client is about to +issue. #### For FTP/SMTP/POP/IMAP - `REPLY [command] [return value] [response string]` - Changes how the server responds to the [command]. [response string] is evaluated as a perl string, - so it can contain embedded \r\n, for example. There's a special [command] + so it can contain embedded \r\n, for example. There is a special [command] named "welcome" (without quotes) which is the string sent immediately on connect as a welcome. - `REPLYLF` (like above but sends the response terminated with LF-only and not @@ -335,10 +335,10 @@ about to issue. time - `RETRWEIRDO` - Enable the "weirdo" RETR case when multiple response lines appear at once when a file is transferred -- `RETRNOSIZE` - Make sure the RETR response doesn't contain the size of the +- `RETRNOSIZE` - Make sure the RETR response does not contain the size of the file - `RETRSIZE [size]` - Force RETR response to contain the specified size -- `NOSAVE` - Don't actually save what is received +- `NOSAVE` - Do not actually save what is received - `SLOWDOWN` - Send FTP responses with 0.01 sec delay between each byte - `PASVBADIP` - makes PASV send back an illegal IP in its 227 response - `CAPA [capabilities]` - Enables support for and specifies a list of space @@ -351,7 +351,7 @@ about to issue. #### For HTTP/HTTPS - `auth_required` if this is set and a POST/PUT is made without auth, the - server will NOT wait for the full request body to get sent + server does NOT wait for the full request body to get sent - `delay: [msecs]` - delay this amount after connection - `idle` - do nothing after receiving the request, just "sit idle" - `stream` - continuously send data to the client, never-ending @@ -360,12 +360,12 @@ about to issue. a PUT or POST request - `rtp: part [num] channel [num] size [num]` - stream a fake RTP packet for the given part on a chosen channel with the given payload size -- `connection-monitor` - When used, this will log `[DISCONNECT]` to the +- `connection-monitor` - When used, this logs `[DISCONNECT]` to the `server.input` log when the connection is disconnected. -- `upgrade` - when an HTTP upgrade header is found, the server will upgrade to +- `upgrade` - when an HTTP upgrade header is found, the server upgrades to http2 - `swsclose` - instruct server to close connection after response -- `no-expect` - don't read the request body if Expect: is present +- `no-expect` - do not read the request body if Expect: is present #### For TFTP `writedelay: [secs]` delay this amount between reply packets (each packet @@ -411,21 +411,20 @@ What server(s) this test case requires/uses. Available servers: Give only one per line. This subsection is mandatory (use `none` if no servers are required). Servers that require a special server certificate can have the -PEM certificate file name (found in the `certs` directory) appended to the +PEM certificate filename (found in the `certs` directory) appended to the server name separated by a space. ### `` A list of features that MUST be present in the client/library for this test to -be able to run. If a required feature is not present then the test will be -SKIPPED. +be able to run. If a required feature is not present then the test is SKIPPED. Alternatively a feature can be prefixed with an exclamation mark to indicate a -feature is NOT required. If the feature is present then the test will be -SKIPPED. +feature is NOT required. If the feature is present then the test is SKIPPED. Features testable here are: - `alt-svc` +- `AppleIDN` - `bearssl` - `brotli` - `c-ares` @@ -449,7 +448,7 @@ Features testable here are: - `IPv6` - `Kerberos` - `Largefile` -- `large-time` (time_t is larger than 32 bit) +- `large-time` (time_t is larger than 32-bit) - `ld_preload` - `libssh2` - `libssh` @@ -487,6 +486,7 @@ Features testable here are: - `verbose-strings` - `wakeup` - `win32` +- `WinIDN` - `wolfssh` - `wolfssl` - `xattr` @@ -505,13 +505,12 @@ restart servers. ### `` A command line that if set gets run by the test script before the test. If an output is displayed by the command or if the return code is non-zero, the test -will be skipped and the (single-line) output will be displayed as reason for -not running the test. +is skipped and the (single-line) output is displayed as reason for not running +the test. ### `` -A command line that if set gets run by the test script after the test. If -the command exists with a non-zero status code, the test will be considered -to have failed. +A command line that if set gets run by the test script after the test. If the +command exists with a non-zero status code, the test is considered failed. ### `` Name of tool to invoke instead of "curl". This tool must be built and exist @@ -538,21 +537,21 @@ Command line to run. Note that the URL that gets passed to the server actually controls what data that is returned. The last slash in the URL must be followed by a number. That -number (N) will be used by the test-server to load test case N and return the -data that is defined within the `` section. +number (N) is used by the test-server to load test case N and return the data +that is defined within the `` section. -If there's no test number found above, the HTTP test server will use the -number following the last dot in the given hostname (made so that a CONNECT -can still pass on test number) so that "foo.bar.123" gets treated as test case +If there is no test number found above, the HTTP test server uses the number +following the last dot in the given hostname (made so that a CONNECT can still +pass on test number) so that "foo.bar.123" gets treated as test case 123. Alternatively, if an IPv6 address is provided to CONNECT, the last -hexadecimal group in the address will be used as the test number! For example -the address "[1234::ff]" would be treated as test case 255. +hexadecimal group in the address is used as the test number! For example the +address "[1234::ff]" would be treated as test case 255. Set `type="perl"` to write the test case as a perl script. It implies that -there's no memory debugging and valgrind gets shut off for this test. +there is no memory debugging and valgrind gets shut off for this test. Set `type="shell"` to write the test case as a shell script. It implies that -there's no memory debugging and valgrind gets shut off for this test. +there is no memory debugging and valgrind gets shut off for this test. Set `option="no-output"` to prevent the test script to slap on the `--output` argument that directs the output to a file. The `--output` is also not added @@ -584,12 +583,12 @@ parameter is the not negative integer number of seconds for the delay. This 'delay' attribute is intended for specific test cases, and normally not needed. -### `` +### `` This creates the named file with this content before the test case is run, which is useful if the test case needs a file to act on. -If `nonewline="yes"` is used, the created file will have the final newline -stripped off. +If `nonewline="yes"` is used, the created file gets the final newline stripped +off. ### `` 1 to 4 can be appended to 'file' to create more files. @@ -603,7 +602,7 @@ stripped off. ### `` Pass this given data on stdin to the tool. -If `nonewline` is set, we will cut off the trailing newline of this given data +If `nonewline` is set, we cut off the trailing newline of this given data before comparing with the one actually received by the client ## `` @@ -623,8 +622,8 @@ advanced. Example: `s/^EPRT .*/EPRT stripped/`. ### `` -the protocol dump curl should transmit, if `nonewline` is set, we will cut off -the trailing newline of this given data before comparing with the one actually +the protocol dump curl should transmit, if `nonewline` is set, we cut off the +trailing newline of this given data before comparing with the one actually sent by the client The `` and `` rules are applied before comparisons are made. @@ -634,9 +633,9 @@ test. ### `` The protocol dump curl should transmit to an HTTP proxy (when the http-proxy -server is used), if `nonewline` is set, we will cut off the trailing newline -of this given data before comparing with the one actually sent by the client -The `` and `` rules are applied before comparisons are made. +server is used), if `nonewline` is set, we cut off the trailing newline of +this given data before comparing with the one actually sent by the client The +`` and `` rules are applied before comparisons are made. ### `` This verifies that this data was passed to stderr. @@ -647,7 +646,7 @@ have a text/binary difference. `crlf=yes` forces the newlines to become CRLF even if not written so in the test. -If `nonewline` is set, we will cut off the trailing newline of this given data +If `nonewline` is set, we cut off the trailing newline of this given data before comparing with the one actually received by the client ### `` @@ -656,7 +655,7 @@ This verifies that this data was passed to stdout. Use the mode="text" attribute if the output is in text mode on platforms that have a text/binary difference. -If `nonewline` is set, we will cut off the trailing newline of this given data +If `nonewline` is set, we cut off the trailing newline of this given data before comparing with the one actually received by the client `crlf=yes` forces the newlines to become CRLF even if not written so in the @@ -664,7 +663,7 @@ test. `loadfile="filename"` makes loading the data from an external file. -### `` +### `` The file's contents must be identical to this after the test is complete. Use the mode="text" attribute if the output is in text mode on platforms that have a text/binary difference. @@ -693,8 +692,11 @@ content ### `` -### `` +### `` the contents of the upload data curl should have sent +`crlf=yes` forces *upload* newlines to become CRLF even if not written so in +the source file. + ### `` disable - disables the valgrind log check for this test diff --git a/tests/Makefile.am b/tests/Makefile.am index f3e0f87e3..178aefb6c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,7 +22,14 @@ # ########################################################################### -MANDISTPAGES = runtests.1.dist testcurl.1.dist +if BUILD_DOCS +# if we disable man page building, ignore these +RUNTESTS_DOCS = runtests.1 +TESTCURL_DOCS = testcurl.1 +MANFILES = $(RUNTESTS_DOCS) $(TESTCURL_DOCS) +endif + +CURLPAGES = runtests.md testcurl.md # scripts used in test cases TESTSCRIPTS = \ @@ -43,6 +50,7 @@ TESTSCRIPTS = \ test1486.pl \ test1488.pl \ test1544.pl \ + test1707.pl \ test971.pl EXTRA_DIST = \ @@ -51,7 +59,6 @@ EXTRA_DIST = \ README.md \ appveyor.pm \ azure.pm \ - conftest.py \ devtest.pl \ dictserver.py \ directories.pm \ @@ -71,7 +78,6 @@ EXTRA_DIST = \ requirements.txt \ rtspserver.pl \ runner.pm \ - runtests.1 \ runtests.pl \ secureserver.pl \ serverhelp.pm \ @@ -80,14 +86,14 @@ EXTRA_DIST = \ sshhelp.pm \ sshserver.pl \ stunnel.pem \ - testcurl.1 \ testcurl.pl \ testutil.pm \ tftpserver.pl \ util.py \ valgrind.pm \ valgrind.supp \ - $(TESTSCRIPTS) + $(TESTSCRIPTS) \ + $(CURLPAGES) DISTCLEANFILES = configurehelp.pm @@ -127,9 +133,16 @@ TEST_E = -a -e TEST_NF = -a -p ~flaky ~timing-dependent # special CI target derived from nonflaky with CI-specific flags -TEST_CI = $(TEST_NF) -r -rm +TEST_CI = $(TEST_NF) -r -rm -j2 endif +CD2NROFF = $(top_srcdir)/scripts/cd2nroff $< >$@ + +SUFFIXES = .1 .md + +.md.1: + $(CD2)$(CD2NROFF) + # make sure that PERL is pointing to an executable perlcheck: @if ! test -x "$(PERL)"; then echo "No perl!"; exit 2; fi @@ -164,7 +177,7 @@ checksrc: (cd server && $(MAKE) checksrc) (cd http && $(MAKE) checksrc) -if DEBUGBUILD -# for debug builds, we scan the sources on all regular make invokes -all-local: checksrc -endif +all-local: $(MANFILES) + +distclean: + rm -f $(MANFILES) diff --git a/tests/Makefile.in b/tests/Makefile.in index 5a792ca6a..ab287a7cf 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -245,11 +245,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -295,7 +295,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -311,8 +310,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -345,10 +346,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -359,6 +358,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -367,6 +367,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -450,7 +451,12 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -MANDISTPAGES = runtests.1.dist testcurl.1.dist + +# if we disable man page building, ignore these +@BUILD_DOCS_TRUE@RUNTESTS_DOCS = runtests.1 +@BUILD_DOCS_TRUE@TESTCURL_DOCS = testcurl.1 +@BUILD_DOCS_TRUE@MANFILES = $(RUNTESTS_DOCS) $(TESTCURL_DOCS) +CURLPAGES = runtests.md testcurl.md # scripts used in test cases TESTSCRIPTS = \ @@ -471,6 +477,7 @@ TESTSCRIPTS = \ test1486.pl \ test1488.pl \ test1544.pl \ + test1707.pl \ test971.pl EXTRA_DIST = \ @@ -479,7 +486,6 @@ EXTRA_DIST = \ README.md \ appveyor.pm \ azure.pm \ - conftest.py \ devtest.pl \ dictserver.py \ directories.pm \ @@ -499,7 +505,6 @@ EXTRA_DIST = \ requirements.txt \ rtspserver.pl \ runner.pm \ - runtests.1 \ runtests.pl \ secureserver.pl \ serverhelp.pm \ @@ -508,14 +513,14 @@ EXTRA_DIST = \ sshhelp.pm \ sshserver.pl \ stunnel.pem \ - testcurl.1 \ testcurl.pl \ testutil.pm \ tftpserver.pl \ util.py \ valgrind.pm \ valgrind.supp \ - $(TESTSCRIPTS) + $(TESTSCRIPTS) \ + $(CURLPAGES) DISTCLEANFILES = configurehelp.pm @BUILD_UNITTESTS_FALSE@BUILD_UNIT = @@ -543,10 +548,13 @@ CLEANFILES = .http.pid .https.pid .ftp.pid .ftps.pid $(MANDISTPAGES) @CROSSCOMPILING_FALSE@TEST_NF = -a -p ~flaky ~timing-dependent # special CI target derived from nonflaky with CI-specific flags -@CROSSCOMPILING_FALSE@TEST_CI = $(TEST_NF) -r -rm +@CROSSCOMPILING_FALSE@TEST_CI = $(TEST_NF) -r -rm -j2 +CD2NROFF = $(top_srcdir)/scripts/cd2nroff $< >$@ +SUFFIXES = .1 .md all: all-recursive .SUFFIXES: +.SUFFIXES: .1 .md $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -743,7 +751,6 @@ distdir-am: $(DISTFILES) done check-am: all-am check: check-recursive -@DEBUGBUILD_FALSE@all-local: all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: @@ -783,8 +790,6 @@ clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am -distclean: distclean-recursive - -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive @@ -866,6 +871,9 @@ uninstall-am: curl: @cd $(top_builddir) && $(MAKE) +.md.1: + $(CD2)$(CD2NROFF) + # make sure that PERL is pointing to an executable perlcheck: @if ! test -x "$(PERL)"; then echo "No perl!"; exit 2; fi @@ -900,8 +908,10 @@ checksrc: (cd server && $(MAKE) checksrc) (cd http && $(MAKE) checksrc) -# for debug builds, we scan the sources on all regular make invokes -@DEBUGBUILD_TRUE@all-local: checksrc +all-local: $(MANFILES) + +distclean: + rm -f $(MANFILES) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/tests/README.md b/tests/README.md index d758d9763..54fb6b3e9 100644 --- a/tests/README.md +++ b/tests/README.md @@ -29,7 +29,7 @@ SPDX-License-Identifier: curl When you run tests via make, the flags `-a` and `-s` are passed, meaning to continue running tests even after one fails, and to emit short output. - If you'd like to not use those flags, you can run 'runtests.pl' directly. + If you would like to not use those flags, you can run 'runtests.pl' directly. You must `chdir` into the tests directory, then you can run it like so: ./runtests.pl 303 410 @@ -45,8 +45,8 @@ SPDX-License-Identifier: curl ## Requires to run - - perl (and a unix-style shell) - - python (and a unix-style shell, for SMB and TELNET tests) + - perl (and a Unix-style shell) + - python (and a Unix-style shell, for SMB and TELNET tests) - python-impacket (for SMB tests) - diff (when a test fails, a diff is shown) - stunnel (for HTTPS and FTPS tests) @@ -54,31 +54,37 @@ SPDX-License-Identifier: curl - nghttpx (for HTTP/2 and HTTP/3 tests) - An available `en_US.UTF-8` locale -### Installation of python-impacket +### Installation of impacket - The Python-based test servers support both recent Python 2 and 3. - You can figure out your default Python interpreter with python -V + The Python-based test servers support Python 3. Please install python-impacket in the correct Python environment. You can use pip or your OS' package manager to install 'impacket'. - On Debian/Ubuntu the package names are: + On Debian/Ubuntu the package name is 'python3-impacket' - - Python 2: 'python-impacket' - - Python 3: 'python3-impacket' + On FreeBSD the package name is 'py311-impacket' - On FreeBSD the package names are: + On any system where pip is available: 'python3 -m pip install impacket' - - Python 2: 'py27-impacket' - - Python 3: 'py37-impacket' + You may also need to manually install the Python package 'six' + as that may be a missing requirement for impacket. - On any system where pip is available: +## Event-based - - Python 2: 'pip2 install impacket' - - Python 3: 'pip3 install impacket' + If curl is built with `Debug` enabled (see below), then the `runtests.pl` + script offers a `-e` option that makes it perform *event-based*. Such tests + invokes the curl tool with `--test-event`, a debug-only option made for this + purpose. - You may also need to manually install the Python package 'six' - as that may be a missing requirement for impacket on Python 3. + Performing event-based means that the curl tool uses the + `curl_multi_socket_action()` API call to drive the transfer(s), instead of + the otherwise "normal" functions it would use. This allows us to test drive + the socket_action API. Transfers done this way should work exactly the same + as with the non-event based API. + + To be able to use `--test-event` together with `--parallel`, curl requires + *libuv* to be present and enabled in the build: `configure --enable-libuv` ### Port numbers used by test servers @@ -125,13 +131,13 @@ SPDX-License-Identifier: curl ### Memory test - The test script will check that all allocated memory is freed properly IF - curl has been built with the `CURLDEBUG` define set. The script will - automatically detect if that is the case, and it will use the - `memanalyze.pl` script to analyze the memory debugging output. + The test script checks that all allocated memory is freed properly IF curl + has been built with the `CURLDEBUG` define set. The script automatically + detects if that is the case, and it uses the `memanalyze.pl` script to + analyze the memory debugging output. - Also, if you run tests on a machine where valgrind is found, the script will - use valgrind to run the test with (unless you use `-n`) to further verify + Also, if you run tests on a machine where valgrind is found, the script uses + valgrind to run the test with (unless you use `-n`) to further verify correctness. The `runtests.pl` `-t` option enables torture testing mode. It runs each @@ -167,7 +173,7 @@ SPDX-License-Identifier: curl CURL_DEBUG=ssl curl -v https://curl.se - will make the `ssl` connection filter log more details. One may do that for + makes the `ssl` connection filter log more details. One may do that for every filter type and also use a combination of names, separated by `,` or space. @@ -205,7 +211,7 @@ SPDX-License-Identifier: curl ggcov -r lib src - The text mode tool `gcov` may also be used, but it doesn't handle object + The text mode tool `gcov` may also be used, but it does not handle object files in more than one directory correctly. ### Remote testing @@ -222,7 +228,7 @@ SPDX-License-Identifier: curl up. Subsets of tests can now be selected by passing keywords to the runtests.pl script via the make `TFLAGS` variable. - New tests are added by finding a free number in `tests/data/Makefile.inc`. + New tests are added by finding a free number in `tests/data/Makefile.am`. ## Write tests @@ -256,7 +262,7 @@ SPDX-License-Identifier: curl ### unit tests - Unit tests are placed in `tests/unit`. There's a tests/unit/README + Unit tests are placed in `tests/unit`. There is a tests/unit/README describing the specific set of checks and macros that may be used when writing tests that verify behaviors of specific individual functions. diff --git a/tests/certs/CMakeLists.txt b/tests/certs/CMakeLists.txt new file mode 100644 index 000000000..f9011b13f --- /dev/null +++ b/tests/certs/CMakeLists.txt @@ -0,0 +1,48 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +find_program(SH_EXECUTABLE "sh") +mark_as_advanced(SH_EXECUTABLE) +if(SH_EXECUTABLE) + # Get 'CERTCONFIGS', 'GENERATEDCERTS', 'SRPFILES' variables + transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + + add_custom_target(clean-certs + COMMAND ${CMAKE_COMMAND} -E remove ${GENERATEDCERTS} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + + add_custom_target(build-certs + DEPENDS ${CERTCONFIGS} ${SRPFILES} + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genroot.sh" EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" Server-localhost EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" Server-localhost.nn EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" Server-localhost0h EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" Server-localhost-firstSAN EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" Server-localhost-lastSAN EdelCurlRoot + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scripts/genserv.sh" stunnel EdelCurlRoot + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/stunnel-sv.pem" "${CMAKE_CURRENT_SOURCE_DIR}/../stunnel.pem" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() diff --git a/tests/certs/Makefile.am b/tests/certs/Makefile.am index dc7deb818..a2b45885a 100644 --- a/tests/certs/Makefile.am +++ b/tests/certs/Makefile.am @@ -25,89 +25,9 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = scripts -CERTCONFIGS = \ - EdelCurlRoot-ca.prm \ - EdelCurlRoot-ca.cnf \ - Server-localhost-sv.prm \ - Server-localhost.nn-sv.prm \ - Server-localhost0h-sv.prm \ - Server-localhost-firstSAN-sv.prm \ - Server-localhost-lastSAN-sv.prm \ - stunnel-sv.prm +include Makefile.inc -GENERATEDCERTS = \ - EdelCurlRoot-ca.cacert \ - EdelCurlRoot-ca.crt \ - EdelCurlRoot-ca.csr \ - EdelCurlRoot-ca.der \ - EdelCurlRoot-ca.key \ - Server-localhost-sv.crl \ - Server-localhost-sv.crt \ - Server-localhost-sv.csr \ - Server-localhost-sv.der \ - Server-localhost-sv.dhp \ - Server-localhost-sv.key \ - Server-localhost-sv.pem \ - Server-localhost-sv.pub.der \ - Server-localhost-sv.pub.pem \ - Server-localhost-sv.pubkey-pinned \ - Server-localhost.nn-sv.crl \ - Server-localhost.nn-sv.crt \ - Server-localhost.nn-sv.csr \ - Server-localhost.nn-sv.der \ - Server-localhost.nn-sv.dhp \ - Server-localhost.nn-sv.key \ - Server-localhost.nn-sv.pem \ - Server-localhost.nn-sv.pub.der \ - Server-localhost.nn-sv.pub.pem \ - Server-localhost.nn-sv.pubkey-pinned \ - Server-localhost0h-sv.crl \ - Server-localhost0h-sv.crt \ - Server-localhost0h-sv.csr \ - Server-localhost0h-sv.der \ - Server-localhost0h-sv.dhp \ - Server-localhost0h-sv.key \ - Server-localhost0h-sv.pem \ - Server-localhost0h-sv.pub.der \ - Server-localhost0h-sv.pub.pem \ - Server-localhost0h-sv.pubkey-pinned \ - Server-localhost-firstSAN-sv.crl \ - Server-localhost-firstSAN-sv.crt \ - Server-localhost-firstSAN-sv.csr \ - Server-localhost-firstSAN-sv.der \ - Server-localhost-firstSAN-sv.dhp \ - Server-localhost-firstSAN-sv.key \ - Server-localhost-firstSAN-sv.pem \ - Server-localhost-firstSAN-sv.pub.der \ - Server-localhost-firstSAN-sv.pub.pem \ - Server-localhost-firstSAN-sv.pubkey-pinned \ - Server-localhost-lastSAN-sv.crl \ - Server-localhost-lastSAN-sv.crt \ - Server-localhost-lastSAN-sv.csr \ - Server-localhost-lastSAN-sv.der \ - Server-localhost-lastSAN-sv.dhp \ - Server-localhost-lastSAN-sv.key \ - Server-localhost-lastSAN-sv.pem \ - Server-localhost-lastSAN-sv.pub.der \ - Server-localhost-lastSAN-sv.pub.pem \ - Server-localhost-lastSAN-sv.pubkey-pinned \ - stunnel-sv.crl \ - stunnel-sv.crt \ - stunnel-sv.csr \ - stunnel-sv.der \ - stunnel-sv.dhp \ - stunnel-sv.key \ - stunnel-sv.pem \ - stunnel-sv.der \ - stunnel-sv.pub.der \ - stunnel-sv.pub.pem \ - stunnel-sv.pubkey-pinned - -SRPFILES = \ - srp-verifier-conf \ - srp-verifier-db - -EXTRA_DIST = $(CERTCONFIGS) $(GENERATEDCERTS) $(SRPFILES) +EXTRA_DIST = $(CERTCONFIGS) $(GENERATEDCERTS) $(SRPFILES) CMakeLists.txt # Rebuild the certificates @@ -117,7 +37,7 @@ clean-certs: build-certs: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/Server-localhost-sv.pem \ $(srcdir)/Server-localhost.nn-sv.pem $(srcdir)/Server-localhost0h-sv.pem \ $(srcdir)/Server-localhost-firstSAN-sv.pem $(srcdir)/Server-localhost-lastSAN-sv.pem \ - $(srcdir)/stunnel-sv.pem ../stunnel.pem + $(srcdir)/stunnel-sv.pem $(srcdir)/../stunnel.pem $(srcdir)/EdelCurlRoot-ca.cacert: cd $(srcdir); scripts/genroot.sh EdelCurlRoot @@ -140,5 +60,5 @@ $(srcdir)/Server-localhost-lastSAN-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/stunnel-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert cd $(srcdir); scripts/genserv.sh stunnel EdelCurlRoot -../stunnel.pem: $(srcdir)/stunnel-sv.pem + $(srcdir)/../stunnel.pem: $(srcdir)/stunnel-sv.pem cp $< $@ diff --git a/tests/certs/Makefile.in b/tests/certs/Makefile.in index b333aff08..8699bbefc 100644 --- a/tests/certs/Makefile.in +++ b/tests/certs/Makefile.in @@ -174,7 +174,7 @@ am__define_uniq_tagged_files = \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/Makefile.in +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -222,11 +222,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -272,7 +272,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -288,8 +287,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -322,10 +323,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -336,6 +335,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -344,6 +344,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -453,6 +454,30 @@ top_srcdir = @top_srcdir@ ########################################################################### AUTOMAKE_OPTIONS = foreign SUBDIRS = scripts + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### CERTCONFIGS = \ EdelCurlRoot-ca.prm \ EdelCurlRoot-ca.cnf \ @@ -535,11 +560,11 @@ SRPFILES = \ srp-verifier-conf \ srp-verifier-db -EXTRA_DIST = $(CERTCONFIGS) $(GENERATEDCERTS) $(SRPFILES) +EXTRA_DIST = $(CERTCONFIGS) $(GENERATEDCERTS) $(SRPFILES) CMakeLists.txt all: all-recursive .SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -559,6 +584,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; +$(srcdir)/Makefile.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -858,7 +884,7 @@ clean-certs: build-certs: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/Server-localhost-sv.pem \ $(srcdir)/Server-localhost.nn-sv.pem $(srcdir)/Server-localhost0h-sv.pem \ $(srcdir)/Server-localhost-firstSAN-sv.pem $(srcdir)/Server-localhost-lastSAN-sv.pem \ - $(srcdir)/stunnel-sv.pem ../stunnel.pem + $(srcdir)/stunnel-sv.pem $(srcdir)/../stunnel.pem $(srcdir)/EdelCurlRoot-ca.cacert: cd $(srcdir); scripts/genroot.sh EdelCurlRoot @@ -881,7 +907,7 @@ $(srcdir)/Server-localhost-lastSAN-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/stunnel-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert cd $(srcdir); scripts/genserv.sh stunnel EdelCurlRoot -../stunnel.pem: $(srcdir)/stunnel-sv.pem + $(srcdir)/../stunnel.pem: $(srcdir)/stunnel-sv.pem cp $< $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/tests/certs/Makefile.inc b/tests/certs/Makefile.inc new file mode 100644 index 000000000..032baec24 --- /dev/null +++ b/tests/certs/Makefile.inc @@ -0,0 +1,104 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +CERTCONFIGS = \ + EdelCurlRoot-ca.prm \ + EdelCurlRoot-ca.cnf \ + Server-localhost-sv.prm \ + Server-localhost.nn-sv.prm \ + Server-localhost0h-sv.prm \ + Server-localhost-firstSAN-sv.prm \ + Server-localhost-lastSAN-sv.prm \ + stunnel-sv.prm + +GENERATEDCERTS = \ + EdelCurlRoot-ca.cacert \ + EdelCurlRoot-ca.crt \ + EdelCurlRoot-ca.csr \ + EdelCurlRoot-ca.der \ + EdelCurlRoot-ca.key \ + Server-localhost-sv.crl \ + Server-localhost-sv.crt \ + Server-localhost-sv.csr \ + Server-localhost-sv.der \ + Server-localhost-sv.dhp \ + Server-localhost-sv.key \ + Server-localhost-sv.pem \ + Server-localhost-sv.pub.der \ + Server-localhost-sv.pub.pem \ + Server-localhost-sv.pubkey-pinned \ + Server-localhost.nn-sv.crl \ + Server-localhost.nn-sv.crt \ + Server-localhost.nn-sv.csr \ + Server-localhost.nn-sv.der \ + Server-localhost.nn-sv.dhp \ + Server-localhost.nn-sv.key \ + Server-localhost.nn-sv.pem \ + Server-localhost.nn-sv.pub.der \ + Server-localhost.nn-sv.pub.pem \ + Server-localhost.nn-sv.pubkey-pinned \ + Server-localhost0h-sv.crl \ + Server-localhost0h-sv.crt \ + Server-localhost0h-sv.csr \ + Server-localhost0h-sv.der \ + Server-localhost0h-sv.dhp \ + Server-localhost0h-sv.key \ + Server-localhost0h-sv.pem \ + Server-localhost0h-sv.pub.der \ + Server-localhost0h-sv.pub.pem \ + Server-localhost0h-sv.pubkey-pinned \ + Server-localhost-firstSAN-sv.crl \ + Server-localhost-firstSAN-sv.crt \ + Server-localhost-firstSAN-sv.csr \ + Server-localhost-firstSAN-sv.der \ + Server-localhost-firstSAN-sv.dhp \ + Server-localhost-firstSAN-sv.key \ + Server-localhost-firstSAN-sv.pem \ + Server-localhost-firstSAN-sv.pub.der \ + Server-localhost-firstSAN-sv.pub.pem \ + Server-localhost-firstSAN-sv.pubkey-pinned \ + Server-localhost-lastSAN-sv.crl \ + Server-localhost-lastSAN-sv.crt \ + Server-localhost-lastSAN-sv.csr \ + Server-localhost-lastSAN-sv.der \ + Server-localhost-lastSAN-sv.dhp \ + Server-localhost-lastSAN-sv.key \ + Server-localhost-lastSAN-sv.pem \ + Server-localhost-lastSAN-sv.pub.der \ + Server-localhost-lastSAN-sv.pub.pem \ + Server-localhost-lastSAN-sv.pubkey-pinned \ + stunnel-sv.crl \ + stunnel-sv.crt \ + stunnel-sv.csr \ + stunnel-sv.der \ + stunnel-sv.dhp \ + stunnel-sv.key \ + stunnel-sv.pem \ + stunnel-sv.der \ + stunnel-sv.pub.der \ + stunnel-sv.pub.pem \ + stunnel-sv.pubkey-pinned + +SRPFILES = \ + srp-verifier-conf \ + srp-verifier-db diff --git a/tests/certs/scripts/Makefile.in b/tests/certs/scripts/Makefile.in index df8df0bef..f3ceeca9c 100644 --- a/tests/certs/scripts/Makefile.in +++ b/tests/certs/scripts/Makefile.in @@ -164,11 +164,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -214,7 +214,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -230,8 +229,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -264,10 +265,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -278,6 +277,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -286,6 +286,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ diff --git a/tests/certs/scripts/genserv.sh b/tests/certs/scripts/genserv.sh index ce184e937..d1303e2fe 100755 --- a/tests/certs/scripts/genserv.sh +++ b/tests/certs/scripts/genserv.sh @@ -37,7 +37,7 @@ HOME=$(pwd) cd "$HOME" KEYSIZE=2048 -DURATION=3000 +DURATION=300 # The -sha256 option was introduced in OpenSSL 1.0.1 DIGESTALGO=-sha256 diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index b22a70d35..000000000 --- a/tests/conftest.py +++ /dev/null @@ -1,64 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -# SPDX-License-Identifier: curl -# -########################################################################### -# -import sys, os - -sys.path.append(os.path.join(os.path.dirname(__file__), 'http')) - -from testenv import Env - - -def pytest_report_header(config): - # Env inits its base properties only once, we can report them here - env = Env() - report = [ - f'Testing curl {env.curl_version()}', - f' httpd: {env.httpd_version()}, http:{env.http_port} https:{env.https_port}', - f' httpd-proxy: {env.httpd_version()}, http:{env.proxy_port} https:{env.proxys_port}' - ] - if env.have_h3(): - report.extend([ - f' nghttpx: {env.nghttpx_version()}, h3:{env.https_port}' - ]) - if env.has_caddy(): - report.extend([ - f' Caddy: {env.caddy_version()}, http:{env.caddy_http_port} https:{env.caddy_https_port}' - ]) - if env.has_vsftpd(): - report.extend([ - f' VsFTPD: {env.vsftpd_version()}, ftp:{env.ftp_port}, ftps:{env.ftps_port}' - ]) - return '\n'.join(report) - - -def pytest_addoption(parser): - parser.addoption("--repeat", action="store", type=int, default=1, - help='Number of times to repeat each test') - - -def pytest_generate_tests(metafunc): - if "repeat" in metafunc.fixturenames: - count = int(metafunc.config.getoption("repeat")) - metafunc.fixturenames.append('tmp_ct') - metafunc.parametrize('repeat', range(count)) diff --git a/tests/data/DISABLED b/tests/data/DISABLED index 2d8ede4f9..bf7274344 100644 --- a/tests/data/DISABLED +++ b/tests/data/DISABLED @@ -46,11 +46,11 @@ # fnmatch differences are just too common to make testing them sensible 1307 1316 -# test 1510 causes problems on the CI on github +# test 1510 causes problems on the CI on GitHub # example: https://travis-ci.org/curl/curl/builds/81633600 1510 1512 -# test 1801 causes problems on Mac OS X and github +# test 1801 causes problems on macOS and GitHub # https://github.com/curl/curl/issues/380 1801 # test 2086 causes issues on Windows only @@ -68,6 +68,7 @@ # 1591, 1943. See https://github.com/hyperium/hyper/issues/2699 for details. %if hyper 266 +500 579 587 # 1021 re-added here due to flakiness @@ -85,27 +86,6 @@ 2307 %endif 2043 -# The CRL test (313) doesn't work with rustls because rustls doesn't support -# CRLs. -# Tests that rely on connecting to an IP address over TLS don't work because -# rustls doesn't support IP address certificates yet. That's the 400 series of -# tests listed here, plus 1112 and 1272 -%if rustls -313 -400 -401 -403 -404 -406 -407 -408 -409 -987 -988 -989 -1112 -1272 -%endif # The CRL test doesn't work with wolfSSL %if wolfssl 313 @@ -114,3 +94,18 @@ %if bearssl 313 %endif +%if WinIDN +165 +%endif +# Windows non-Unicode builds fail to receive Unicode text via the command-line +%if win32 +%if !Unicode +%if libidn2 +165 +1560 +%endif +1448 +2046 +2047 +%endif +%endif diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 68148c1f9..7cce30f91 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -21,11 +21,253 @@ # SPDX-License-Identifier: curl # ########################################################################### -iall: +all: install: test: -# TESTCASES are taken from Makefile.inc -include Makefile.inc +# this list is in numerical order +TESTCASES = test1 test2 test3 test4 test5 test6 test7 test8 test9 \ +test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \ +test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \ +test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \ +test40 test41 test42 test43 test44 test45 test46 test47 test48 test49 \ +test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \ +test60 test61 test62 test63 test64 test65 test66 test67 test68 test69 \ +test70 test71 test72 test73 test74 test75 test77 test78 test79 \ +test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \ +test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \ +test100 test101 test102 test103 test104 test105 test106 test107 test108 \ +test109 test110 test111 test112 test113 test114 test115 test116 test117 \ +test118 test119 test120 test121 test122 test123 test124 test125 test126 \ +test127 test128 test129 test130 test131 test132 test133 test134 test135 \ +test136 test137 test138 test139 test140 test141 test142 test143 test144 \ +test145 test146 test147 test148 test149 test150 test151 test152 test153 \ +test154 test155 test156 test157 test158 test159 test160 test161 test162 \ +test163 test164 test165 test166 test167 test168 test169 test170 test171 \ +test172 test173 test174 test175 test176 test177 test178 test179 test180 \ +test181 test182 test183 test184 test185 test186 test187 test188 test189 \ +test190 test191 test192 test193 test194 test195 test196 test197 test198 \ +test199 test200 test201 test202 test203 test204 test205 test206 test207 \ +test208 test209 test210 test211 test212 test213 test214 test215 test216 \ +test217 test218 test219 test220 test221 test222 test223 test224 test225 \ +test226 test227 test228 test229 test230 test231 test232 test233 test234 \ +test235 test236 test237 test238 test239 test240 test241 test242 test243 \ +test244 test245 test246 test247 test248 test249 test250 test251 test252 \ +test253 test254 test255 test256 test257 test258 test259 test260 test261 \ +test262 test263 test264 test265 test266 test267 test268 test269 test270 \ +test271 test272 test273 test274 test275 test276 test277 test278 test279 \ +test280 test281 test282 test283 test284 test285 test286 test287 test288 \ +test289 test290 test291 test292 test293 test294 test295 test296 test297 \ +test298 test299 test300 test301 test302 test303 test304 test305 test306 \ +test307 test308 test309 test310 test311 test312 test313 test314 test315 \ +test316 test317 test318 test319 test320 test321 test322 test323 test324 \ +test325 test326 test327 test328 test329 test330 test331 test332 test333 \ +test334 test335 test336 test337 test338 test339 test340 test341 test342 \ +test343 test344 test345 test346 test347 test348 test349 test350 test351 \ +test352 test353 test354 test355 test356 test357 test358 test359 test360 \ +test361 test362 test363 test364 test365 test366 test367 test368 test369 \ +test370 test371 test372 test373 test374 test375 test376 test378 test379 \ +test380 test381 test383 test384 test385 test386 test387 test388 test389 \ +test390 test391 test392 test393 test394 test395 test396 test397 test398 \ +test399 test400 test401 test402 test403 test404 test405 test406 test407 \ +test408 test409 test410 test411 test412 test413 test414 test415 test416 \ +test417 test418 test419 test420 test421 test422 test423 test424 test425 \ +test426 test427 test428 test429 test430 test431 test432 test433 test434 \ +test435 test436 test437 test438 test439 test440 test441 test442 test443 \ +test444 test445 test446 test447 test448 test449 test450 test451 test452 \ +test453 test454 test455 test456 test457 test458 test459 test460 test461 \ +test462 test463 test467 test468 test469 test470 test471 test472 test473 \ +test474 test475 test476 \ +\ +test490 test491 test492 test493 test494 test495 test496 test497 test498 \ +test499 test500 test501 test502 test503 test504 test505 test506 test507 \ +test508 test509 test510 test511 test512 test513 test514 test515 test516 \ +test517 test518 test519 test520 test521 test522 test523 test524 test525 \ +test526 test527 test528 test529 test530 test531 test532 test533 test534 \ +test535 test536 test537 test538 test539 test540 test541 test542 test543 \ +test544 test545 test546 test547 test548 test549 test550 test551 test552 \ +test553 test554 test555 test556 test557 test558 test559 test560 test561 \ +test562 test563 test564 test565 test566 test567 test568 test569 test570 \ +test571 test572 test573 test574 test575 test576 test577 test578 test579 \ +test580 test581 test582 test583 test584 test585 test586 test587 test588 \ +test589 test590 test591 test592 test593 test594 test595 test596 test597 \ +test598 test599 test600 test601 test602 test603 test604 test605 test606 \ +test607 test608 test609 test610 test611 test612 test613 test614 test615 \ +test616 test617 test618 test619 test620 test621 test622 test623 test624 \ +test625 test626 test627 test628 test629 test630 test631 test632 test633 \ +test634 test635 test636 test637 test638 test639 test640 test641 test642 \ +test643 test644 test645 test646 test647 test648 test649 test650 test651 \ +test652 test653 test654 test655 test656 test658 test659 test660 test661 \ +test662 test663 test664 test665 test666 test667 test668 test669 test670 \ +test671 test672 test673 test674 test675 test676 test677 test678 test679 \ +test680 test681 test682 test683 test684 test685 test686 test687 test688 \ +test689 test690 test691 \ +\ +test700 test701 test702 test703 test704 test705 test706 test707 test708 \ +test709 test710 test711 test712 test713 test714 test715 test716 test717 \ +test718 test719 test720 test721 test722 test723 test724 test725 test726 \ +test727 test728 test729 test730 test731 test732 test733 test734 test735 \ +test736 test737 test738 test739 test740 test741 test742 \ +\ +test799 test800 test801 test802 test803 test804 test805 test806 test807 \ +test808 test809 test810 test811 test812 test813 test814 test815 test816 \ +test817 test818 test819 test820 test821 test822 test823 test824 test825 \ +test826 test827 test828 test829 test830 test831 test832 test833 test834 \ +test835 test836 test837 test838 test839 test840 test841 test842 test843 \ +test844 test845 test846 test847 test848 test849 test850 test851 test852 \ +test853 test854 test855 test856 test857 test858 test859 test860 test861 \ +test862 test863 test864 test865 test866 test867 test868 test869 test870 \ +test871 test872 test873 test874 test875 test876 test877 test878 test879 \ +test880 test881 test882 test883 test884 test885 test886 test887 test888 \ +test889 test890 test891 test892 test893 test894 test895 test896 test897 \ +test898 test899 test900 test901 test902 test903 test904 test905 test906 \ +test907 test908 test909 test910 test911 test912 test913 test914 test915 \ +test916 test917 test918 test919 test920 test921 test922 test923 test924 \ +test925 test926 test927 test928 test929 test930 test931 test932 test933 \ +test934 test935 test936 test937 test938 test939 test940 test941 test942 \ +test943 test944 test945 test946 test947 test948 test949 test950 test951 \ +test952 test953 test954 test955 test956 test957 test958 test959 test960 \ +test961 test962 test963 test964 test965 test966 test967 test968 test969 \ +test970 test971 test972 test973 test974 test975 test976 test977 test978 \ +test979 test980 test981 test982 test983 test984 test985 test986 test987 \ +test988 test989 test990 test991 test992 test993 test994 test995 test996 \ +test997 \ +test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ +test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ +test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ +test1024 test1025 test1026 test1027 test1028 test1029 test1030 test1031 \ +test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 \ +test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 \ +test1048 test1049 test1050 test1051 test1052 test1053 test1054 test1055 \ +test1056 test1057 test1058 test1059 test1060 test1061 test1062 test1063 \ +test1064 test1065 test1066 test1067 test1068 test1069 test1070 test1071 \ +test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \ +test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 \ +test1088 test1089 test1090 test1091 test1092 test1093 test1094 test1095 \ +test1096 test1097 test1098 test1099 test1100 test1101 test1102 test1103 \ +test1104 test1105 test1106 test1107 test1108 test1109 test1110 test1111 \ +test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 \ +test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \ +test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \ +test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \ +test1144 test1145 test1146 test1147 test1148 test1149 test1150 test1151 \ +test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \ +test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 \ +test1168 test1169 test1170 test1171 test1172 test1173 test1174 test1175 \ +test1176 test1177 test1178 test1179 test1180 test1181 test1182 test1183 \ +test1184 test1185 test1186 test1187 test1188 test1189 test1190 test1190 \ +test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 \ +test1199 test1200 test1201 test1202 test1203 test1204 test1205 test1206 \ +test1207 test1208 test1209 test1210 test1211 test1212 test1213 test1214 \ +test1215 test1216 test1217 test1218 test1219 test1220 test1221 test1222 \ +test1223 test1224 test1225 test1226 test1227 test1228 test1229 test1230 \ +test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 \ +test1239 test1240 test1241 test1242 test1243 test1244 test1245 test1246 \ +test1247 test1248 test1249 test1250 test1251 test1252 test1253 test1254 \ +test1255 test1256 test1257 test1258 test1259 test1260 test1261 test1262 \ +test1263 test1264 test1265 test1266 test1267 test1268 test1269 test1270 \ +test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 \ +test1279 test1280 test1281 test1282 test1283 test1284 test1285 test1286 \ +test1287 test1288 test1289 test1290 test1291 test1292 test1293 test1294 \ +test1295 test1296 test1297 test1298 test1299 test1300 test1301 test1302 \ +test1303 test1304 test1305 test1306 test1307 test1308 test1309 \ +test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 \ +test1319 test1320 test1321 test1322 test1323 test1324 test1325 test1326 \ +test1327 test1328 test1329 test1330 test1331 test1332 test1333 test1334 \ +test1335 test1336 test1337 test1338 test1339 test1340 test1341 test1342 \ +test1343 test1344 test1345 test1346 test1347 test1348 test1349 test1350 \ +test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 \ +test1359 test1360 test1361 test1362 test1363 test1364 test1365 test1366 \ +test1367 test1368 test1369 test1370 test1371 test1372 test1373 test1374 \ +test1375 test1376 test1377 test1378 test1379 test1380 test1381 test1382 \ +test1383 test1384 test1385 test1386 test1387 test1388 test1389 test1390 \ +test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 \ +test1399 test1400 test1401 test1402 test1403 test1404 test1405 test1406 \ +test1407 test1408 test1409 test1410 test1411 test1412 test1413 test1414 \ +test1415 test1416 test1417 test1418 test1419 test1420 test1421 test1422 \ +test1423 test1424 test1425 test1426 test1427 test1428 test1429 test1430 \ +test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 \ +test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ +test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \ +test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ +test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ +test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \ +test1479 test1480 test1481 test1482 test1483 test1484 test1485 test1486 \ +test1487 test1488 test1489 \ +\ +test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ +test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ +test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \ +test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \ +test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \ +test1540 test1541 test1542 test1543 test1544 test1545 test1546 \ +\ +test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ +test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \ +test1566 test1567 test1568 test1569 test1570 \ +\ +test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ +test1598 \ +test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \ +test1608 test1609 test1610 test1611 test1612 test1613 test1614 test1615 \ +test1616 \ +test1620 test1621 \ +\ +test1630 test1631 test1632 test1633 test1634 test1635 \ +\ +test1650 test1651 test1652 test1653 test1654 test1655 test1656 \ +test1660 test1661 test1662 test1663 \ +\ +test1670 test1671 \ +\ +test1680 test1681 test1682 test1683 \ +\ +test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \ +test1708 test1709 test1710 \ +\ +test1800 test1801 \ +\ +test1900 test1901 test1903 test1904 test1905 test1906 test1907 \ +test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ +test1916 test1917 test1918 test1919 \ +\ +test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ +test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ +test1955 test1956 test1957 test1958 test1959 test1960 test1964 \ +test1970 test1971 test1972 test1973 test1974 test1975 test1976 \ +\ +test2000 test2001 test2002 test2003 test2004 \ +\ + test2023 \ +test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ +test2032 test2033 test2034 test2035 test2037 test2038 test2039 \ +test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \ +test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ +test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ +test2064 test2065 test2066 test2067 test2068 test2069 test2070 test2071 \ +test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \ +test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \ +\ +test2100 \ +\ +test2200 test2201 test2202 test2203 test2204 test2205 \ +\ +test2300 test2301 test2302 test2303 test2304 test2305 test2306 test2307 \ +test2308 \ +\ +test2400 test2401 test2402 test2403 test2404 test2405 test2406 \ +\ +test2500 test2501 test2502 test2503 \ +\ +test2600 test2601 test2602 test2603 test2604 \ +\ +test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \ +test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015 \ +test3016 test3017 test3018 test3019 test3020 test3021 test3022 test3023 \ +test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ +\ +test3100 test3101 test3102 test3103 \ +test3200 \ +test3201 test3202 test3203 test3204 test3205 test3207 -EXTRA_DIST = $(TESTCASES) DISABLED CMakeLists.txt +EXTRA_DIST = $(TESTCASES) DISABLED diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in index 6da99e391..ee6d97507 100644 --- a/tests/data/Makefile.in +++ b/tests/data/Makefile.in @@ -13,30 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -# SPDX-License-Identifier: curl -# -########################################################################### VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -165,7 +141,7 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -188,11 +164,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -238,7 +214,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -254,8 +229,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -288,10 +265,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -302,6 +277,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -310,6 +286,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -402,7 +379,7 @@ test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \ test40 test41 test42 test43 test44 test45 test46 test47 test48 test49 \ test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \ test60 test61 test62 test63 test64 test65 test66 test67 test68 test69 \ -test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \ +test70 test71 test72 test73 test74 test75 test77 test78 test79 \ test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \ test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \ test100 test101 test102 test103 test104 test105 test106 test107 test108 \ @@ -446,6 +423,7 @@ test435 test436 test437 test438 test439 test440 test441 test442 test443 \ test444 test445 test446 test447 test448 test449 test450 test451 test452 \ test453 test454 test455 test456 test457 test458 test459 test460 test461 \ test462 test463 test467 test468 test469 test470 test471 test472 test473 \ +test474 test475 test476 \ \ test490 test491 test492 test493 test494 test495 test496 test497 test498 \ test499 test500 test501 test502 test503 test504 test505 test506 test507 \ @@ -469,7 +447,7 @@ test652 test653 test654 test655 test656 test658 test659 test660 test661 \ test662 test663 test664 test665 test666 test667 test668 test669 test670 \ test671 test672 test673 test674 test675 test676 test677 test678 test679 \ test680 test681 test682 test683 test684 test685 test686 test687 test688 \ -test689 \ +test689 test690 test691 \ \ test700 test701 test702 test703 test704 test705 test706 test707 test708 \ test709 test710 test711 test712 test713 test714 test715 test716 test717 \ @@ -498,8 +476,8 @@ test952 test953 test954 test955 test956 test957 test958 test959 test960 \ test961 test962 test963 test964 test965 test966 test967 test968 test969 \ test970 test971 test972 test973 test974 test975 test976 test977 test978 \ test979 test980 test981 test982 test983 test984 test985 test986 test987 \ -test988 test989 test990 test991 test992 test993 \ -\ +test988 test989 test990 test991 test992 test993 test994 test995 test996 \ +test997 \ test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ @@ -538,7 +516,7 @@ test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 \ test1279 test1280 test1281 test1282 test1283 test1284 test1285 test1286 \ test1287 test1288 test1289 test1290 test1291 test1292 test1293 test1294 \ test1295 test1296 test1297 test1298 test1299 test1300 test1301 test1302 \ -test1303 test1304 test1305 test1306 test1307 test1308 test1309 test1310 \ +test1303 test1304 test1305 test1306 test1307 test1308 test1309 \ test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 \ test1319 test1320 test1321 test1322 test1323 test1324 test1325 test1326 \ test1327 test1328 test1329 test1330 test1331 test1332 test1333 test1334 \ @@ -561,7 +539,7 @@ test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \ test1479 test1480 test1481 test1482 test1483 test1484 test1485 test1486 \ -test1487 test1488 \ +test1487 test1488 test1489 \ \ test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ @@ -590,7 +568,8 @@ test1670 test1671 \ \ test1680 test1681 test1682 test1683 \ \ -test1700 test1701 test1702 test1703 test1704 test1705 test1706 \ +test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \ +test1708 test1709 test1710 \ \ test1800 test1801 \ \ @@ -601,13 +580,13 @@ test1916 test1917 test1918 test1919 \ test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ test1955 test1956 test1957 test1958 test1959 test1960 test1964 \ -test1970 test1971 test1972 test1973 test1974 test1975 \ +test1970 test1971 test1972 test1973 test1974 test1975 test1976 \ \ test2000 test2001 test2002 test2003 test2004 \ \ test2023 \ test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ -test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \ +test2032 test2033 test2034 test2035 test2037 test2038 test2039 \ test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \ test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ @@ -635,15 +614,13 @@ test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ \ test3100 test3101 test3102 test3103 \ test3200 \ -test3201 test3202 test3203 test3204 test3205 - +test3201 test3202 test3203 test3204 test3205 test3207 -# TESTCASES are taken from Makefile.inc -EXTRA_DIST = $(TESTCASES) DISABLED CMakeLists.txt +EXTRA_DIST = $(TESTCASES) DISABLED all: all-am .SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -663,7 +640,6 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; -$(srcdir)/Makefile.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -857,7 +833,7 @@ uninstall-am: # SPDX-License-Identifier: curl # ########################################################################### -iall: +all: install: test: diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc deleted file mode 100644 index 792cb16ee..000000000 --- a/tests/data/Makefile.inc +++ /dev/null @@ -1,266 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -# SPDX-License-Identifier: curl -# -########################################################################### - -# this list is in numerical order -TESTCASES = test1 test2 test3 test4 test5 test6 test7 test8 test9 \ -test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \ -test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \ -test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \ -test40 test41 test42 test43 test44 test45 test46 test47 test48 test49 \ -test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \ -test60 test61 test62 test63 test64 test65 test66 test67 test68 test69 \ -test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \ -test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \ -test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \ -test100 test101 test102 test103 test104 test105 test106 test107 test108 \ -test109 test110 test111 test112 test113 test114 test115 test116 test117 \ -test118 test119 test120 test121 test122 test123 test124 test125 test126 \ -test127 test128 test129 test130 test131 test132 test133 test134 test135 \ -test136 test137 test138 test139 test140 test141 test142 test143 test144 \ -test145 test146 test147 test148 test149 test150 test151 test152 test153 \ -test154 test155 test156 test157 test158 test159 test160 test161 test162 \ -test163 test164 test165 test166 test167 test168 test169 test170 test171 \ -test172 test173 test174 test175 test176 test177 test178 test179 test180 \ -test181 test182 test183 test184 test185 test186 test187 test188 test189 \ -test190 test191 test192 test193 test194 test195 test196 test197 test198 \ -test199 test200 test201 test202 test203 test204 test205 test206 test207 \ -test208 test209 test210 test211 test212 test213 test214 test215 test216 \ -test217 test218 test219 test220 test221 test222 test223 test224 test225 \ -test226 test227 test228 test229 test230 test231 test232 test233 test234 \ -test235 test236 test237 test238 test239 test240 test241 test242 test243 \ -test244 test245 test246 test247 test248 test249 test250 test251 test252 \ -test253 test254 test255 test256 test257 test258 test259 test260 test261 \ -test262 test263 test264 test265 test266 test267 test268 test269 test270 \ -test271 test272 test273 test274 test275 test276 test277 test278 test279 \ -test280 test281 test282 test283 test284 test285 test286 test287 test288 \ -test289 test290 test291 test292 test293 test294 test295 test296 test297 \ -test298 test299 test300 test301 test302 test303 test304 test305 test306 \ -test307 test308 test309 test310 test311 test312 test313 test314 test315 \ -test316 test317 test318 test319 test320 test321 test322 test323 test324 \ -test325 test326 test327 test328 test329 test330 test331 test332 test333 \ -test334 test335 test336 test337 test338 test339 test340 test341 test342 \ -test343 test344 test345 test346 test347 test348 test349 test350 test351 \ -test352 test353 test354 test355 test356 test357 test358 test359 test360 \ -test361 test362 test363 test364 test365 test366 test367 test368 test369 \ -test370 test371 test372 test373 test374 test375 test376 test378 test379 \ -test380 test381 test383 test384 test385 test386 test387 test388 test389 \ -test390 test391 test392 test393 test394 test395 test396 test397 test398 \ -test399 test400 test401 test402 test403 test404 test405 test406 test407 \ -test408 test409 test410 test411 test412 test413 test414 test415 test416 \ -test417 test418 test419 test420 test421 test422 test423 test424 test425 \ -test426 test427 test428 test429 test430 test431 test432 test433 test434 \ -test435 test436 test437 test438 test439 test440 test441 test442 test443 \ -test444 test445 test446 test447 test448 test449 test450 test451 test452 \ -test453 test454 test455 test456 test457 test458 test459 test460 test461 \ -test462 test463 test467 test468 test469 test470 test471 test472 test473 \ -\ -test490 test491 test492 test493 test494 test495 test496 test497 test498 \ -test499 test500 test501 test502 test503 test504 test505 test506 test507 \ -test508 test509 test510 test511 test512 test513 test514 test515 test516 \ -test517 test518 test519 test520 test521 test522 test523 test524 test525 \ -test526 test527 test528 test529 test530 test531 test532 test533 test534 \ -test535 test536 test537 test538 test539 test540 test541 test542 test543 \ -test544 test545 test546 test547 test548 test549 test550 test551 test552 \ -test553 test554 test555 test556 test557 test558 test559 test560 test561 \ -test562 test563 test564 test565 test566 test567 test568 test569 test570 \ -test571 test572 test573 test574 test575 test576 test577 test578 test579 \ -test580 test581 test582 test583 test584 test585 test586 test587 test588 \ -test589 test590 test591 test592 test593 test594 test595 test596 test597 \ -test598 test599 test600 test601 test602 test603 test604 test605 test606 \ -test607 test608 test609 test610 test611 test612 test613 test614 test615 \ -test616 test617 test618 test619 test620 test621 test622 test623 test624 \ -test625 test626 test627 test628 test629 test630 test631 test632 test633 \ -test634 test635 test636 test637 test638 test639 test640 test641 test642 \ -test643 test644 test645 test646 test647 test648 test649 test650 test651 \ -test652 test653 test654 test655 test656 test658 test659 test660 test661 \ -test662 test663 test664 test665 test666 test667 test668 test669 test670 \ -test671 test672 test673 test674 test675 test676 test677 test678 test679 \ -test680 test681 test682 test683 test684 test685 test686 test687 test688 \ -test689 \ -\ -test700 test701 test702 test703 test704 test705 test706 test707 test708 \ -test709 test710 test711 test712 test713 test714 test715 test716 test717 \ -test718 test719 test720 test721 test722 test723 test724 test725 test726 \ -test727 test728 test729 test730 test731 test732 test733 test734 test735 \ -test736 test737 test738 test739 test740 test741 test742 \ -\ -test799 test800 test801 test802 test803 test804 test805 test806 test807 \ -test808 test809 test810 test811 test812 test813 test814 test815 test816 \ -test817 test818 test819 test820 test821 test822 test823 test824 test825 \ -test826 test827 test828 test829 test830 test831 test832 test833 test834 \ -test835 test836 test837 test838 test839 test840 test841 test842 test843 \ -test844 test845 test846 test847 test848 test849 test850 test851 test852 \ -test853 test854 test855 test856 test857 test858 test859 test860 test861 \ -test862 test863 test864 test865 test866 test867 test868 test869 test870 \ -test871 test872 test873 test874 test875 test876 test877 test878 test879 \ -test880 test881 test882 test883 test884 test885 test886 test887 test888 \ -test889 test890 test891 test892 test893 test894 test895 test896 test897 \ -test898 test899 test900 test901 test902 test903 test904 test905 test906 \ -test907 test908 test909 test910 test911 test912 test913 test914 test915 \ -test916 test917 test918 test919 test920 test921 test922 test923 test924 \ -test925 test926 test927 test928 test929 test930 test931 test932 test933 \ -test934 test935 test936 test937 test938 test939 test940 test941 test942 \ -test943 test944 test945 test946 test947 test948 test949 test950 test951 \ -test952 test953 test954 test955 test956 test957 test958 test959 test960 \ -test961 test962 test963 test964 test965 test966 test967 test968 test969 \ -test970 test971 test972 test973 test974 test975 test976 test977 test978 \ -test979 test980 test981 test982 test983 test984 test985 test986 test987 \ -test988 test989 test990 test991 test992 test993 \ -\ -test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ -test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ -test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ -test1024 test1025 test1026 test1027 test1028 test1029 test1030 test1031 \ -test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 \ -test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 \ -test1048 test1049 test1050 test1051 test1052 test1053 test1054 test1055 \ -test1056 test1057 test1058 test1059 test1060 test1061 test1062 test1063 \ -test1064 test1065 test1066 test1067 test1068 test1069 test1070 test1071 \ -test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \ -test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 \ -test1088 test1089 test1090 test1091 test1092 test1093 test1094 test1095 \ -test1096 test1097 test1098 test1099 test1100 test1101 test1102 test1103 \ -test1104 test1105 test1106 test1107 test1108 test1109 test1110 test1111 \ -test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 \ -test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \ -test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \ -test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \ -test1144 test1145 test1146 test1147 test1148 test1149 test1150 test1151 \ -test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \ -test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 \ -test1168 test1169 test1170 test1171 test1172 test1173 test1174 test1175 \ -test1176 test1177 test1178 test1179 test1180 test1181 test1182 test1183 \ -test1184 test1185 test1186 test1187 test1188 test1189 test1190 test1190 \ -test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 \ -test1199 test1200 test1201 test1202 test1203 test1204 test1205 test1206 \ -test1207 test1208 test1209 test1210 test1211 test1212 test1213 test1214 \ -test1215 test1216 test1217 test1218 test1219 test1220 test1221 test1222 \ -test1223 test1224 test1225 test1226 test1227 test1228 test1229 test1230 \ -test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 \ -test1239 test1240 test1241 test1242 test1243 test1244 test1245 test1246 \ -test1247 test1248 test1249 test1250 test1251 test1252 test1253 test1254 \ -test1255 test1256 test1257 test1258 test1259 test1260 test1261 test1262 \ -test1263 test1264 test1265 test1266 test1267 test1268 test1269 test1270 \ -test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 \ -test1279 test1280 test1281 test1282 test1283 test1284 test1285 test1286 \ -test1287 test1288 test1289 test1290 test1291 test1292 test1293 test1294 \ -test1295 test1296 test1297 test1298 test1299 test1300 test1301 test1302 \ -test1303 test1304 test1305 test1306 test1307 test1308 test1309 test1310 \ -test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 \ -test1319 test1320 test1321 test1322 test1323 test1324 test1325 test1326 \ -test1327 test1328 test1329 test1330 test1331 test1332 test1333 test1334 \ -test1335 test1336 test1337 test1338 test1339 test1340 test1341 test1342 \ -test1343 test1344 test1345 test1346 test1347 test1348 test1349 test1350 \ -test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 \ -test1359 test1360 test1361 test1362 test1363 test1364 test1365 test1366 \ -test1367 test1368 test1369 test1370 test1371 test1372 test1373 test1374 \ -test1375 test1376 test1377 test1378 test1379 test1380 test1381 test1382 \ -test1383 test1384 test1385 test1386 test1387 test1388 test1389 test1390 \ -test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 \ -test1399 test1400 test1401 test1402 test1403 test1404 test1405 test1406 \ -test1407 test1408 test1409 test1410 test1411 test1412 test1413 test1414 \ -test1415 test1416 test1417 test1418 test1419 test1420 test1421 test1422 \ -test1423 test1424 test1425 test1426 test1427 test1428 test1429 test1430 \ -test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 \ -test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ -test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \ -test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ -test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ -test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \ -test1479 test1480 test1481 test1482 test1483 test1484 test1485 test1486 \ -test1487 test1488 \ -\ -test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ -test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ -test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \ -test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \ -test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \ -test1540 test1541 test1542 test1543 test1544 test1545 test1546 \ -\ -test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ -test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \ -test1566 test1567 test1568 test1569 test1570 \ -\ -test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ -test1598 \ -test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \ -test1608 test1609 test1610 test1611 test1612 test1613 test1614 test1615 \ -test1616 \ -test1620 test1621 \ -\ -test1630 test1631 test1632 test1633 test1634 test1635 \ -\ -test1650 test1651 test1652 test1653 test1654 test1655 test1656 \ -test1660 test1661 test1662 test1663 \ -\ -test1670 test1671 \ -\ -test1680 test1681 test1682 test1683 \ -\ -test1700 test1701 test1702 test1703 test1704 test1705 test1706 \ -\ -test1800 test1801 \ -\ -test1900 test1901 test1903 test1904 test1905 test1906 test1907 \ -test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ -test1916 test1917 test1918 test1919 \ -\ -test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ -test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ -test1955 test1956 test1957 test1958 test1959 test1960 test1964 \ -test1970 test1971 test1972 test1973 test1974 test1975 \ -\ -test2000 test2001 test2002 test2003 test2004 \ -\ - test2023 \ -test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ -test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \ -test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \ -test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ -test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ -test2064 test2065 test2066 test2067 test2068 test2069 test2070 test2071 \ -test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \ -test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \ -\ -test2100 \ -\ -test2200 test2201 test2202 test2203 test2204 test2205 \ -\ -test2300 test2301 test2302 test2303 test2304 test2305 test2306 test2307 \ -test2308 \ -\ -test2400 test2401 test2402 test2403 test2404 test2405 test2406 \ -\ -test2500 test2501 test2502 test2503 \ -\ -test2600 test2601 test2602 test2603 test2604 \ -\ -test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \ -test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015 \ -test3016 test3017 test3018 test3019 test3020 test3021 test3022 test3023 \ -test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ -\ -test3100 test3101 test3102 test3103 \ -test3200 \ -test3201 test3202 test3203 test3204 test3205 diff --git a/tests/data/test100 b/tests/data/test100 index b7554383e..54d31744b 100644 --- a/tests/data/test100 +++ b/tests/data/test100 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT/test-%TESTNUMBER/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1000 b/tests/data/test1000 index fe94010ac..e102a006e 100644 --- a/tests/data/test1000 +++ b/tests/data/test1000 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER/ -I # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1003 b/tests/data/test1003 index 06cfbb61b..4947d1dfb 100644 --- a/tests/data/test1003 +++ b/tests/data/test1003 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1005 b/tests/data/test1005 index 28af85f40..8a036bb60 100644 --- a/tests/data/test1005 +++ b/tests/data/test1005 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1006 b/tests/data/test1006 index 394b5563b..004598ff1 100644 --- a/tests/data/test1006 +++ b/tests/data/test1006 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test101 b/tests/data/test101 index 3febc5e72..8acbd21f7 100644 --- a/tests/data/test101 +++ b/tests/data/test101 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/ -P %CLIENTIP # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1010 b/tests/data/test1010 index d45efdc8a..cd0337293 100644 --- a/tests/data/test1010 +++ b/tests/data/test1010 @@ -42,6 +42,9 @@ ftp://%HOSTIP:%FTPPORT//list/this/path/%TESTNUMBER/ ftp://%HOSTIP:%FTPPORT//list # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test102 b/tests/data/test102 index 7037986f4..151dd8025 100644 --- a/tests/data/test102 +++ b/tests/data/test102 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1028 b/tests/data/test1028 index 3e3659732..9592fb66f 100644 --- a/tests/data/test1028 +++ b/tests/data/test1028 @@ -52,6 +52,9 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER0001 -L # # Verify data after the test has been "shot" + +QUIT + GET /%TESTNUMBER0001 HTTP/1.1 Host: %HOSTIP:%HTTPPORT diff --git a/tests/data/test103 b/tests/data/test103 index 52e5645bc..66705310c 100644 --- a/tests/data/test103 +++ b/tests/data/test103 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER -P - # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1036 b/tests/data/test1036 index f777a6ff7..1343a8b7c 100644 --- a/tests/data/test1036 +++ b/tests/data/test1036 @@ -40,6 +40,9 @@ This is the start!! # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1037 b/tests/data/test1037 index 18c9e5266..967561b3b 100644 --- a/tests/data/test1037 +++ b/tests/data/test1037 @@ -39,6 +39,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -C - # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1038 b/tests/data/test1038 index c2e60a0a4..102d35615 100644 --- a/tests/data/test1038 +++ b/tests/data/test1038 @@ -34,6 +34,9 @@ worx? # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1039 b/tests/data/test1039 index a032c2f9a..342290459 100644 --- a/tests/data/test1039 +++ b/tests/data/test1039 @@ -34,6 +34,9 @@ worx? # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test104 b/tests/data/test104 index 3674f1da0..f8d3d3eac 100644 --- a/tests/data/test104 +++ b/tests/data/test104 @@ -27,6 +27,9 @@ ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER --head # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1044 b/tests/data/test1044 index 471f099a3..a0705d331 100644 --- a/tests/data/test1044 +++ b/tests/data/test1044 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/%TESTNUMBER -I # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1047 b/tests/data/test1047 index b863bd006..b7d17275b 100644 --- a/tests/data/test1047 +++ b/tests/data/test1047 @@ -43,6 +43,9 @@ ftp://%HOSTIP:%FTPPORT/ --interface %CLIENTIP # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1048 b/tests/data/test1048 index 600e11faf..d2d2317bc 100644 --- a/tests/data/test1048 +++ b/tests/data/test1048 @@ -52,6 +52,9 @@ perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test105 b/tests/data/test105 index 2a26ac7ec..7f3052990 100644 --- a/tests/data/test105 +++ b/tests/data/test105 @@ -37,6 +37,9 @@ ftp://userdude:passfellow@%HOSTIP:%FTPPORT/%TESTNUMBER --use-ascii # Verify data after the test has been "shot" + +QUIT + USER userdude PASS passfellow diff --git a/tests/data/test1050 b/tests/data/test1050 index e6dd82a32..5c3e9a007 100644 --- a/tests/data/test1050 +++ b/tests/data/test1050 @@ -2,6 +2,7 @@ # Similar to test 253 +FTP FTP-ipv6 IPv6 EPRT @@ -47,6 +48,9 @@ perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of EPRT that curl can send s/^(EPRT \|2\|::1\|)(.*)/$1/ diff --git a/tests/data/test1055 b/tests/data/test1055 index 2d1c604b4..0624a969a 100644 --- a/tests/data/test1055 +++ b/tests/data/test1055 @@ -54,6 +54,9 @@ the # # Verify data after the test has been "shot" + +QUIT + PUT /%TESTNUMBER HTTP/1.1 Host: %HOSTIP:%HTTPPORT diff --git a/tests/data/test1057 b/tests/data/test1057 index a7cb3bc61..e211dd7da 100644 --- a/tests/data/test1057 +++ b/tests/data/test1057 @@ -36,6 +36,9 @@ FTP retrieve a byte-range relative to end of file # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test106 b/tests/data/test106 index b5e1e6929..2fec63478 100644 --- a/tests/data/test106 +++ b/tests/data/test106 @@ -35,6 +35,9 @@ FTP GET with type=A style ASCII URL using %20 codes # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1062 b/tests/data/test1062 index 31a27a947..36b726af8 100644 --- a/tests/data/test1062 +++ b/tests/data/test1062 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test107 b/tests/data/test107 index a741b7667..a92a635f8 100644 --- a/tests/data/test107 +++ b/tests/data/test107 @@ -30,6 +30,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt # Verify data after the test has been "shot" + +QUIT + data to diff --git a/tests/data/test108 b/tests/data/test108 index 20ef6577e..ceea4d4b2 100644 --- a/tests/data/test108 +++ b/tests/data/test108 @@ -31,6 +31,9 @@ Moooooooooooo # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test109 b/tests/data/test109 index d466437f2..63d1bc6b6 100644 --- a/tests/data/test109 +++ b/tests/data/test109 @@ -31,6 +31,9 @@ Moooooooooooo # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1091 b/tests/data/test1091 index 445d31655..b5006c6bc 100644 --- a/tests/data/test1091 +++ b/tests/data/test1091 @@ -30,6 +30,9 @@ FTP URL with type=i # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1096 b/tests/data/test1096 index e7b163924..f8eb1d4fb 100644 --- a/tests/data/test1096 +++ b/tests/data/test1096 @@ -30,6 +30,9 @@ ftp://%HOSTIP:%FTPPORT/dir/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/dir/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + 78 diff --git a/tests/data/test110 b/tests/data/test110 index e53fcd137..c3c3d04bf 100644 --- a/tests/data/test110 +++ b/tests/data/test110 @@ -36,6 +36,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -C 20 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1100 b/tests/data/test1100 index 268f367f2..13eaeb317 100644 --- a/tests/data/test1100 +++ b/tests/data/test1100 @@ -73,18 +73,9 @@ http HTTP POST with NTLM authorization and following a 302 redirect - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER -u testuser:testpass --ntlm -L -d "stuff to send away" - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test1102 b/tests/data/test1102 index 16994d953..12822b95a 100644 --- a/tests/data/test1102 +++ b/tests/data/test1102 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1103 b/tests/data/test1103 index a53b504bd..2ceb89de0 100644 --- a/tests/data/test1103 +++ b/tests/data/test1103 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1107 b/tests/data/test1107 index 8b31c76f8..de8b7d76e 100644 --- a/tests/data/test1107 +++ b/tests/data/test1107 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --ftp-pret # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test111 b/tests/data/test111 index a46f7aef1..a7cd3c3d2 100644 --- a/tests/data/test111 +++ b/tests/data/test111 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -C 2000 # Verify data after the test has been "shot" + +QUIT + 36 diff --git a/tests/data/test1113 b/tests/data/test1113 index 8d10975ea..c0e1230c3 100644 --- a/tests/data/test1113 +++ b/tests/data/test1113 @@ -36,6 +36,9 @@ FTP wildcard download - changed fnmatch, 2x perform (DOS LIST response) ############################################ # Verify data after the test has been "shot" + +QUIT + 0 diff --git a/tests/data/test112 b/tests/data/test112 index 41bbc025d..231f3452f 100644 --- a/tests/data/test112 +++ b/tests/data/test112 @@ -31,6 +31,9 @@ worx? # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1137 b/tests/data/test1137 index cb20aee31..4e8f24f09 100644 --- a/tests/data/test1137 +++ b/tests/data/test1137 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --ignore-content-length # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1149 b/tests/data/test1149 index d4e97d540..4b3ba376e 100644 --- a/tests/data/test1149 +++ b/tests/data/test1149 @@ -42,6 +42,9 @@ ftp://%HOSTIP:%FTPPORT/list/this/path/%TESTNUMBER/ --ftp-method multicwd --next # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test115 b/tests/data/test115 index 22f75c0b6..e4da7ea1f 100644 --- a/tests/data/test115 +++ b/tests/data/test115 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + 13 diff --git a/tests/data/test1152 b/tests/data/test1152 index 1823bab4a..6052b70b5 100644 --- a/tests/data/test1152 +++ b/tests/data/test1152 @@ -45,6 +45,9 @@ ftp://%HOSTIP:%FTPPORT/test-%TESTNUMBER/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1153 b/tests/data/test1153 index a74b1838c..56ed84005 100644 --- a/tests/data/test1153 +++ b/tests/data/test1153 @@ -45,6 +45,9 @@ ftp://%HOSTIP:%FTPPORT/test-%TESTNUMBER/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test116 b/tests/data/test116 index 0ab00aae9..cab67ad57 100644 --- a/tests/data/test116 +++ b/tests/data/test116 @@ -35,6 +35,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -P 1.2.3.4 # Verify data after the test has been "shot" + +QUIT + 30 diff --git a/tests/data/test1162 b/tests/data/test1162 index b6b394139..5aa706b7f 100644 --- a/tests/data/test1162 +++ b/tests/data/test1162 @@ -37,6 +37,9 @@ MSYS2_ARG_CONV_EXCL=ftp:// + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1163 b/tests/data/test1163 index a109b511b..09ede0cb8 100644 --- a/tests/data/test1163 +++ b/tests/data/test1163 @@ -33,6 +33,9 @@ FTP wildcard with pattern ending with an open-bracket + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test117 b/tests/data/test117 index 3bd5cb57f..c292af730 100644 --- a/tests/data/test117 +++ b/tests/data/test117 @@ -28,6 +28,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + 17 diff --git a/tests/data/test118 b/tests/data/test118 index 9b5b8708e..de7012140 100644 --- a/tests/data/test118 +++ b/tests/data/test118 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + 19 diff --git a/tests/data/test119 b/tests/data/test119 index 4426def0b..2b36051f9 100644 --- a/tests/data/test119 +++ b/tests/data/test119 @@ -30,6 +30,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -P - # Verify data after the test has been "shot" + +QUIT + 19 diff --git a/tests/data/test120 b/tests/data/test120 index 64628b659..6e285b433 100644 --- a/tests/data/test120 +++ b/tests/data/test120 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -Q "-DELE file" # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1206 b/tests/data/test1206 index 228df4adb..6abb0c596 100644 --- a/tests/data/test1206 +++ b/tests/data/test1206 @@ -33,6 +33,9 @@ FTP PORT and 425 on download # Verify data after the test has been "shot" + +QUIT + s/^EPRT \|1\|(.*)/EPRT \|1\|/ diff --git a/tests/data/test1207 b/tests/data/test1207 index 612c42b0d..e192e425e 100644 --- a/tests/data/test1207 +++ b/tests/data/test1207 @@ -33,6 +33,9 @@ FTP PORT and 421 on download # Verify data after the test has been "shot" + +QUIT + s/^EPRT \|1\|(.*)/EPRT \|1\|/ diff --git a/tests/data/test121 b/tests/data/test121 index 3625d0e3e..d9dfe2794 100644 --- a/tests/data/test121 +++ b/tests/data/test121 @@ -35,6 +35,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -Q "-DELE after_transfer" -Q "DELE before_tra # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1217 b/tests/data/test1217 index 691c88e73..47059b247 100644 --- a/tests/data/test1217 +++ b/tests/data/test1217 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/get/file/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/get/file/agai # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1219 b/tests/data/test1219 index 454654399..b28077dce 100644 --- a/tests/data/test1219 +++ b/tests/data/test1219 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + PWD EPSV diff --git a/tests/data/test122 b/tests/data/test122 index 1f007c1ce..0566b2407 100644 --- a/tests/data/test122 +++ b/tests/data/test122 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -C 5 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1224 b/tests/data/test1224 index 64ba4482c..61036cd08 100644 --- a/tests/data/test1224 +++ b/tests/data/test1224 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT//%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1225 b/tests/data/test1225 index b20363c3e..39abfcb91 100644 --- a/tests/data/test1225 +++ b/tests/data/test1225 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT//foo/%TESTNUMBER ftp://%HOSTIP:%FTPPORT//foo/bar/%TESTNUM # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1226 b/tests/data/test1226 index 08e706b9b..4ae0e6aff 100644 --- a/tests/data/test1226 +++ b/tests/data/test1226 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT//%TESTNUMBER --ftp-method singlecwd # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1227 b/tests/data/test1227 index 30477a46a..f8246fa46 100644 --- a/tests/data/test1227 +++ b/tests/data/test1227 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT//%TESTNUMBER --ftp-method nocwd # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test123 b/tests/data/test123 index 8ccd69cf6..1d29c8668 100644 --- a/tests/data/test123 +++ b/tests/data/test123 @@ -28,6 +28,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/upload%TESTNUMBER -C 51 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1233 b/tests/data/test1233 index 79e641d36..0ca5eed97 100644 --- a/tests/data/test1233 +++ b/tests/data/test1233 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test124 b/tests/data/test124 index d2717949c..2dfc96bb8 100644 --- a/tests/data/test124 +++ b/tests/data/test124 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test125 b/tests/data/test125 index 8de97c14e..a615d092f 100644 --- a/tests/data/test125 +++ b/tests/data/test125 @@ -27,6 +27,9 @@ ftp://%HOSTIP:%FTPPORT/path/to/file/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + 9 diff --git a/tests/data/test126 b/tests/data/test126 index b830fc778..285618f11 100644 --- a/tests/data/test126 +++ b/tests/data/test126 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/lululul/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1262 b/tests/data/test1262 index 0a7046ce9..2cb5d8857 100644 --- a/tests/data/test1262 +++ b/tests/data/test1262 @@ -28,6 +28,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/%TESTNUMBER -z "-1 jan 2001" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test127 b/tests/data/test127 index ebf122d01..6871e0dc4 100644 --- a/tests/data/test127 +++ b/tests/data/test127 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/path/to/file/%TESTNUMBER --disable-epsv # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1279 b/tests/data/test1279 index 041f5449b..4b9ce2f19 100644 --- a/tests/data/test1279 +++ b/tests/data/test1279 @@ -24,7 +24,7 @@ Verify libcurl.def against CURL_EXTERN declarations - + diff --git a/tests/data/test128 b/tests/data/test128 index d1a5d2acf..d46f454ef 100644 --- a/tests/data/test128 +++ b/tests/data/test128 @@ -24,7 +24,7 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/upload%TESTNUMBER --crlf file -with unix newlines +with Unix newlines meant to be converted with @@ -35,6 +35,9 @@ the # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com @@ -46,7 +49,7 @@ QUIT file -with unix newlines +with Unix newlines meant to be converted with diff --git a/tests/data/test130 b/tests/data/test130 index 2c4dfe85e..a0673dd8f 100644 --- a/tests/data/test130 +++ b/tests/data/test130 @@ -50,6 +50,9 @@ default login userdef password passwddef # # Verify data after the test has been "shot" + +QUIT + USER user1 PASS passwd1 diff --git a/tests/data/test131 b/tests/data/test131 index 4a73de285..0511520f7 100644 --- a/tests/data/test131 +++ b/tests/data/test131 @@ -47,6 +47,9 @@ machine %HOSTIP login user2 password passwd2 # # Verify data after the test has been "shot" + +QUIT + USER user2 PASS passwd2 diff --git a/tests/data/test1310 b/tests/data/test1310 deleted file mode 100644 index f3c1cfa3d..000000000 --- a/tests/data/test1310 +++ /dev/null @@ -1,124 +0,0 @@ - - - -HTTP -HTTP GET -HTTP NTLM auth - - -# Server-side - - - - - -HTTP/1.1 401 Now gimme that second request of crap -Server: Microsoft-IIS/5.0 -Content-Type: text/html; charset=iso-8859-1 -Content-Length: 34 -WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA== - -This is not the real page either! - - -# This is supposed to be returned when the server gets the second -# Authorization: NTLM line passed-in from the client - -HTTP/1.1 200 Things are fine in server land swsclose -Server: Microsoft-IIS/5.0 -Content-Type: text/html; charset=iso-8859-1 -Content-Length: 32 - -Finally, this is the real page! - - - -HTTP/1.1 401 Now gimme that second request of crap -Server: Microsoft-IIS/5.0 -Content-Type: text/html; charset=iso-8859-1 -Content-Length: 34 -WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA== - -HTTP/1.1 200 Things are fine in server land swsclose -Server: Microsoft-IIS/5.0 -Content-Type: text/html; charset=iso-8859-1 -Content-Length: 32 - -Finally, this is the real page! - - - - -# Client-side - - -NTLM_WB -Debug - - -http - - -HTTP with NTLM delegation to winbind helper - - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so -# set path to fake_auth instead of real ntlm_auth to generate NTLM type1 and type 3 messages -CURL_NTLM_WB_FILE=%PWD/server/fake_ntlm -# set source directory so fake_ntlm can find the test files -CURL_NTLM_AUTH_SRCDIR=%SRCDIR -# set source directory so fake_ntlm can find the test and log files -CURL_NTLM_LOGDIR=%LOGDIR -# set the test number -CURL_NTLM_AUTH_TESTNUM=%TESTNUMBER - - -http://%HOSTIP:%HTTPPORT/%TESTNUMBER -u testuser:anypasswd --ntlm-wb - - -chkhostname curlhost - - - -# Verify data after the test has been "shot" - - -GET /%TESTNUMBER HTTP/1.1 -Host: %HOSTIP:%HTTPPORT -Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA -User-Agent: curl/%VERSION -Accept: */* - -GET /%TESTNUMBER HTTP/1.1 -Host: %HOSTIP:%HTTPPORT -Authorization: NTLM TlRMTVNTUAADAAAAGAAYAE8AAAAYABgAZwAAAAAAAABAAAAACAAIAEAAAAAHAAcASAAAAAAAAAAAAAAAggEAAHRlc3R1c2VyVU5LTk9XTlpkQwKRCZFMhjj0tw47wEjKHRHlvzfxQamFcheMuv8v+xeqphEO5V41xRd7R9deOQ== -User-Agent: curl/%VERSION -Accept: */* - - - -# Input and output (type 1 message) for fake_ntlm - - -YR - - -YR TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA - - -# Input and output (type 3 message) for fake_ntlm - - -TT TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA== - - -KK TlRMTVNTUAADAAAAGAAYAE8AAAAYABgAZwAAAAAAAABAAAAACAAIAEAAAAAHAAcASAAAAAAAAAAAAAAAggEAAHRlc3R1c2VyVU5LTk9XTlpkQwKRCZFMhjj0tw47wEjKHRHlvzfxQamFcheMuv8v+xeqphEO5V41xRd7R9deOQ== - - - diff --git a/tests/data/test1316 b/tests/data/test1316 index 2218b6e14..c3f70878a 100644 --- a/tests/data/test1316 +++ b/tests/data/test1316 @@ -60,6 +60,9 @@ ftp://ftp.%TESTNUMBER:%FTPPORT/ -p -x %HOSTIP:%PROXYPORT # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test132 b/tests/data/test132 index 77d47c8fd..47748494b 100644 --- a/tests/data/test132 +++ b/tests/data/test132 @@ -47,6 +47,9 @@ machine %HOSTIP login user2 password passwd2 # # Verify data after the test has been "shot" + +QUIT + USER mary PASS mark diff --git a/tests/data/test133 b/tests/data/test133 index 4a2c46cde..f80d840ab 100644 --- a/tests/data/test133 +++ b/tests/data/test133 @@ -47,6 +47,9 @@ machine %HOSTIP login mary password drfrank # # Verify data after the test has been "shot" + +QUIT + USER mary PASS drfrank diff --git a/tests/data/test134 b/tests/data/test134 index 207e4f5d4..aa104bf15 100644 --- a/tests/data/test134 +++ b/tests/data/test134 @@ -49,6 +49,9 @@ machine %HOSTIP login user2 password passwd2 # # Verify data after the test has been "shot" + +QUIT + USER romulus PASS rhemus diff --git a/tests/data/test1348 b/tests/data/test1348 index 73cb473d9..e922246d0 100644 --- a/tests/data/test1348 +++ b/tests/data/test1348 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1349 b/tests/data/test1349 index 4451dc37e..48f6f8b29 100644 --- a/tests/data/test1349 +++ b/tests/data/test1349 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -D %LOGDIR/heads%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test135 b/tests/data/test135 index 3dc1d531f..cdb548362 100644 --- a/tests/data/test135 +++ b/tests/data/test135 @@ -38,6 +38,9 @@ FTP retrieve a byte-range # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1350 b/tests/data/test1350 index 7f4b5a60f..2ba80bd7a 100644 --- a/tests/data/test1350 +++ b/tests/data/test1350 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -D - # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1351 b/tests/data/test1351 index b876bbd35..c7adcc8d7 100644 --- a/tests/data/test1351 +++ b/tests/data/test1351 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -J -D %LOGDIR/heads%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1352 b/tests/data/test1352 index 53689b6a7..10fa85d81 100644 --- a/tests/data/test1352 +++ b/tests/data/test1352 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -J -D - # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1353 b/tests/data/test1353 index be501618c..c1764b7fe 100644 --- a/tests/data/test1353 +++ b/tests/data/test1353 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -i -D %LOGDIR/heads%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1354 b/tests/data/test1354 index ba5cba780..42b7449a5 100644 --- a/tests/data/test1354 +++ b/tests/data/test1354 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -i -D - # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1355 b/tests/data/test1355 index 32c9d8baf..677dc839d 100644 --- a/tests/data/test1355 +++ b/tests/data/test1355 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/file%TESTNUMBER -O -i # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1356 b/tests/data/test1356 index 2a156628d..b5f28bee5 100644 --- a/tests/data/test1356 +++ b/tests/data/test1356 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1357 b/tests/data/test1357 index 371d8c619..c27308570 100644 --- a/tests/data/test1357 +++ b/tests/data/test1357 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1358 b/tests/data/test1358 index bd0b382a8..495d93961 100644 --- a/tests/data/test1358 +++ b/tests/data/test1358 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1359 b/tests/data/test1359 index bc29dd8c8..38ebef013 100644 --- a/tests/data/test1359 +++ b/tests/data/test1359 @@ -49,6 +49,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test136 b/tests/data/test136 index ef0b2c49a..f71f4b36a 100644 --- a/tests/data/test136 +++ b/tests/data/test136 @@ -28,6 +28,9 @@ FTP with user and no password # Verify data after the test has been "shot" + +QUIT + USER user PASS diff --git a/tests/data/test1360 b/tests/data/test1360 index 70e8053ba..a1e6b3ec1 100644 --- a/tests/data/test1360 +++ b/tests/data/test1360 @@ -49,6 +49,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1361 b/tests/data/test1361 index 6b9c566a7..20a014143 100644 --- a/tests/data/test1361 +++ b/tests/data/test1361 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1362 b/tests/data/test1362 index 41f7b4dfa..0e4689da4 100644 --- a/tests/data/test1362 +++ b/tests/data/test1362 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1363 b/tests/data/test1363 index e5344f045..dc1046d00 100644 --- a/tests/data/test1363 +++ b/tests/data/test1363 @@ -48,6 +48,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/name%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test137 b/tests/data/test137 index 33b93589e..8154af88d 100644 --- a/tests/data/test137 +++ b/tests/data/test137 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/lululul/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1378 b/tests/data/test1378 index 7348a3f17..81c18731d 100644 --- a/tests/data/test1378 +++ b/tests/data/test1378 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1379 b/tests/data/test1379 index 0b8d20ae0..c11dfe84c 100644 --- a/tests/data/test1379 +++ b/tests/data/test1379 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test138 b/tests/data/test138 index db3b6ec7d..e00c3110c 100644 --- a/tests/data/test138 +++ b/tests/data/test138 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/lululul/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1380 b/tests/data/test1380 index 187dd8cdb..2016b4558 100644 --- a/tests/data/test1380 +++ b/tests/data/test1380 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1381 b/tests/data/test1381 index 4ba20eb3e..404a03d0d 100644 --- a/tests/data/test1381 +++ b/tests/data/test1381 @@ -33,6 +33,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1382 b/tests/data/test1382 index 26ff7acbe..d0b04904d 100644 --- a/tests/data/test1382 +++ b/tests/data/test1382 @@ -33,6 +33,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1383 b/tests/data/test1383 index d4c5c8285..f0c9cd68e 100644 --- a/tests/data/test1383 +++ b/tests/data/test1383 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1384 b/tests/data/test1384 index af7afdf76..4d2fed963 100644 --- a/tests/data/test1384 +++ b/tests/data/test1384 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1385 b/tests/data/test1385 index d2038ee92..f0904607a 100644 --- a/tests/data/test1385 +++ b/tests/data/test1385 @@ -32,6 +32,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1386 b/tests/data/test1386 index 0aaf66419..2e3d73a92 100644 --- a/tests/data/test1386 +++ b/tests/data/test1386 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1387 b/tests/data/test1387 index 0f124d870..2965acea4 100644 --- a/tests/data/test1387 +++ b/tests/data/test1387 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1388 b/tests/data/test1388 index d78844e77..0078916be 100644 --- a/tests/data/test1388 +++ b/tests/data/test1388 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1389 b/tests/data/test1389 index 0863a4013..3ce9acf11 100644 --- a/tests/data/test1389 +++ b/tests/data/test1389 @@ -41,6 +41,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test139 b/tests/data/test139 index 160f628e2..61a0da601 100644 --- a/tests/data/test139 +++ b/tests/data/test139 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/%TESTNUMBER -z "1 jan 1989" # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1390 b/tests/data/test1390 index a856d1e8d..09dafdd7b 100644 --- a/tests/data/test1390 +++ b/tests/data/test1390 @@ -41,6 +41,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1391 b/tests/data/test1391 index ae1495eec..4f612f99e 100644 --- a/tests/data/test1391 +++ b/tests/data/test1391 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1392 b/tests/data/test1392 index f715fe8b3..656f03c55 100644 --- a/tests/data/test1392 +++ b/tests/data/test1392 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1393 b/tests/data/test1393 index dc7a6f934..4d6d348fe 100644 --- a/tests/data/test1393 +++ b/tests/data/test1393 @@ -40,6 +40,9 @@ perl %SRCDIR/libtest/notexists.pl %LOGDIR/file%TESTNUMBER %LOGDIR/name%TESTNUMBE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test140 b/tests/data/test140 index 5e29f5c7c..cacef2ae2 100644 --- a/tests/data/test140 +++ b/tests/data/test140 @@ -30,6 +30,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/%TESTNUMBER -z "1 jan 2004" # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1405 b/tests/data/test1405 index 8a13a688a..5ca006a13 100644 --- a/tests/data/test1405 +++ b/tests/data/test1405 @@ -42,6 +42,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -Q "NOOP 1" -Q "+NOOP 2" -Q "-NOOP 3" -Q "*FA # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test141 b/tests/data/test141 index 425a98f2a..5ffbc4523 100644 --- a/tests/data/test141 +++ b/tests/data/test141 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/blalbla/%TESTNUMBER -I # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1414 b/tests/data/test1414 index 4be9b5422..9fc2a56ff 100644 --- a/tests/data/test1414 +++ b/tests/data/test1414 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -P - # Verify data after the test has been "shot" + +QUIT + s/^(EPRT \|1\|)(.*)/$1/ s/^(PORT)(.*)/$1/ diff --git a/tests/data/test142 b/tests/data/test142 index c4ad11a6d..db17e3074 100644 --- a/tests/data/test142 +++ b/tests/data/test142 @@ -26,6 +26,9 @@ ftp://%HOSTIP:%FTPPORT/part1/part2/part3/part4/part5/part6/part7/part8/part9/par # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test143 b/tests/data/test143 index ed89e70de..8984a3f1f 100644 --- a/tests/data/test143 +++ b/tests/data/test143 @@ -28,6 +28,9 @@ FTP URL with type=a # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test144 b/tests/data/test144 index be2ca5c8c..e7a983bca 100644 --- a/tests/data/test144 +++ b/tests/data/test144 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/ -P - -l # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1444 b/tests/data/test1444 index 61b3a29f4..f50c734f0 100644 --- a/tests/data/test1444 +++ b/tests/data/test1444 @@ -37,6 +37,9 @@ perl -e 'exit((stat("%LOGDIR/curl%TESTNUMBER.out"))[9] != 1234567890)' # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1449 b/tests/data/test1449 index 0b9de0192..d761f3c0e 100644 --- a/tests/data/test1449 +++ b/tests/data/test1449 @@ -27,6 +27,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -r 36893488147419103232- # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test145 b/tests/data/test145 index 53f3f631d..7f12b36f3 100644 --- a/tests/data/test145 +++ b/tests/data/test145 @@ -30,6 +30,9 @@ ftp://%HOSTIP:%FTPPORT/ -P - -l # Verify data after the test has been "shot" + +QUIT + 19 diff --git a/tests/data/test1451 b/tests/data/test1451 index 9fdd68a61..be4240118 100644 --- a/tests/data/test1451 +++ b/tests/data/test1451 @@ -28,9 +28,6 @@ Basic SMB request -u 'curltest:curltest' smb://%HOSTIP:%SMBPORT/TESTS/%TESTNUMBER - -python3 -c "__import__('pkgutil').find_loader('impacket') or (__import__('sys').stdout.write('Test only works if Python package impacket is installed\n'), __import__('sys').exit(1))" - # diff --git a/tests/data/test146 b/tests/data/test146 index 803fbfc4d..c7586573e 100644 --- a/tests/data/test146 +++ b/tests/data/test146 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/first/dir/here/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/%TESTNU # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1461 b/tests/data/test1461 index 669e5fbf4..f1c481ec6 100644 --- a/tests/data/test1461 +++ b/tests/data/test1461 @@ -13,6 +13,9 @@ # # Client-side + +manual + none @@ -34,10 +37,10 @@ curl important --help Usage: curl [options...] -d, --data HTTP POST data -f, --fail Fail fast with no output on HTTP errors - -h, --help Get help for commands - -i, --include Include response headers in output + -h, --help Get help for commands -o, --output Write to file instead of stdout -O, --remote-name Write output to file named as remote file + -i, --show-headers Show response headers in output -s, --silent Silent mode -T, --upload-file Transfer local FILE to destination -u, --user Server user and password @@ -50,7 +53,8 @@ Use "--help category" to get an overview of all categories, which are: auth, connection, curl, deprecated, dns, file, ftp, global, http, imap, ldap, output, pop3, post, proxy, scp, sftp, smtp, ssh, telnet, tftp, timeout, tls, upload, verbose. -For all options use the manual or "--help all". +Use "--help all" to list all options +Use "--help [option]" to view documentation for a given option diff --git a/tests/data/test1462 b/tests/data/test1462 index 572b1dd4b..a3cc46e31 100644 --- a/tests/data/test1462 +++ b/tests/data/test1462 @@ -31,7 +31,6 @@ curl invalid category --help 0 -Usage: curl [options...] Unknown category provided, here is a list of all categories: auth Authentication methods diff --git a/tests/data/test1463 b/tests/data/test1463 index a916cb4df..9fd527f78 100644 --- a/tests/data/test1463 +++ b/tests/data/test1463 @@ -35,7 +35,6 @@ curl file category --help 0 -Usage: curl [options...] file: FILE protocol --create-file-mode File mode for created files -I, --head Show document info only diff --git a/tests/data/test1464 b/tests/data/test1464 index ccdb56d1a..59f58dfc5 100644 --- a/tests/data/test1464 +++ b/tests/data/test1464 @@ -35,7 +35,6 @@ curl file category --help with lower/upper mix 0 -Usage: curl [options...] file: FILE protocol --create-file-mode File mode for created files -I, --head Show document info only diff --git a/tests/data/test1467 b/tests/data/test1467 index e160a1625..568670a71 100644 --- a/tests/data/test1467 +++ b/tests/data/test1467 @@ -39,7 +39,7 @@ http socks5unix -HTTP GET via SOCKS5 proxy via unix sockets +HTTP GET via SOCKS5 proxy via Unix sockets --socks5 localhost%SOCKSUNIXPATH http://%HOSTIP:%HTTPPORT/%TESTNUMBER diff --git a/tests/data/test1468 b/tests/data/test1468 index 49748d119..9836434d4 100644 --- a/tests/data/test1468 +++ b/tests/data/test1468 @@ -40,7 +40,7 @@ http socks5unix -HTTP GET with host name using SOCKS5h via unix sockets +HTTP GET with host name using SOCKS5h via Unix sockets http://this.is.a.host.name:%HTTPPORT/%TESTNUMBER --proxy socks5h://localhost%SOCKSUNIXPATH diff --git a/tests/data/test147 b/tests/data/test147 index 769043d48..b2772f607 100644 --- a/tests/data/test147 +++ b/tests/data/test147 @@ -31,6 +31,9 @@ ftp://%HOSTIP:%FTPPORT/first/dir/here/%TESTNUMBER --ftp-create-dirs # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1470 b/tests/data/test1470 index c5d74ae65..1c9389a4c 100644 --- a/tests/data/test1470 +++ b/tests/data/test1470 @@ -41,7 +41,7 @@ https socks5unix -HTTPS GET with host name using SOCKS5h via unix sockets +HTTPS GET with host name using SOCKS5h via Unix sockets https://this.is.a.host.name:%HTTPSPORT/%TESTNUMBER -k --proxy socks5h://localhost%SOCKSUNIXPATH diff --git a/tests/data/test148 b/tests/data/test148 index 051d31a9d..c8ec7a6d1 100644 --- a/tests/data/test148 +++ b/tests/data/test148 @@ -28,6 +28,9 @@ ftp://%HOSTIP:%FTPPORT/attempt/to/get/this/%TESTNUMBER --ftp-create-dirs # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1489 b/tests/data/test1489 new file mode 100644 index 000000000..e1460bf5c --- /dev/null +++ b/tests/data/test1489 @@ -0,0 +1,66 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +-D sent to stderr + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -D % -s + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + + + + diff --git a/tests/data/test149 b/tests/data/test149 index 404922b29..60d9089ae 100644 --- a/tests/data/test149 +++ b/tests/data/test149 @@ -27,6 +27,9 @@ send away this contents # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test1501 b/tests/data/test1501 index 195c17998..070ff7d97 100644 --- a/tests/data/test1501 +++ b/tests/data/test1501 @@ -39,6 +39,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER/ # Verify data after the test has been "shot" + +QUIT + 0 diff --git a/tests/data/test1521 b/tests/data/test1521 index 21d51fdca..f62f58c5f 100644 --- a/tests/data/test1521 +++ b/tests/data/test1521 @@ -26,5 +26,8 @@ unused # # Verify data after the test has been "shot" + +ok + diff --git a/tests/data/test1541 b/tests/data/test1541 index 5094c3513..9b29f4353 100644 --- a/tests/data/test1541 +++ b/tests/data/test1541 @@ -36,6 +36,7 @@ Transfer-Encoding: chunked datad474 CURLINFO_CONNECT_TIME_T on done is OK CURLINFO_PRETRANSFER_TIME_T on done is OK +CURLINFO_POSTTRANSFER_TIME_T on done is OK CURLINFO_STARTTRANSFER_TIME_T on done is OK CURLINFO_APPCONNECT_TIME_T on done is OK CURLINFO_SPEED_DOWNLOAD_T on done is OK diff --git a/tests/data/test1554 b/tests/data/test1554 index c16195c17..8dc248b98 100644 --- a/tests/data/test1554 +++ b/tests/data/test1554 @@ -19,67 +19,57 @@ Content-Length: 29 run 1: foobar and so on fun! --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT run 1: foobar and so on fun! --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT run 1: foobar and so on fun! --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT run 1: foobar and so on fun! --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock --> Mutex lock -<- Mutex unlock +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +-> Mutex lock SHARE +<- Mutex unlock SHARE +-> Mutex lock SHARE +-> Mutex lock CONNECT +<- Mutex unlock CONNECT +<- Mutex unlock SHARE diff --git a/tests/data/test1569 b/tests/data/test1569 index 159a81391..24f16ee78 100644 --- a/tests/data/test1569 +++ b/tests/data/test1569 @@ -40,6 +40,9 @@ lib%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test1570 b/tests/data/test1570 index 713ab5ea7..e558b9bc3 100644 --- a/tests/data/test1570 +++ b/tests/data/test1570 @@ -40,6 +40,9 @@ lib1569 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test159 b/tests/data/test159 index 887c4795f..cc183855a 100644 --- a/tests/data/test159 +++ b/tests/data/test159 @@ -53,18 +53,9 @@ http HTTP with NTLM authorization when talking HTTP/1.0 (known to fail) - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER -u testuser:testpass --ntlm -0 - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test1604 b/tests/data/test1604 index 33e4e26c4..c8d19f548 100644 --- a/tests/data/test1604 +++ b/tests/data/test1604 @@ -15,7 +15,7 @@ none unittest -Test WIN32/MSDOS filename sanitization +Test Windows/MS-DOS filename sanitization diff --git a/tests/data/test1631 b/tests/data/test1631 index 83bc83e42..f624c4142 100644 --- a/tests/data/test1631 +++ b/tests/data/test1631 @@ -53,6 +53,9 @@ proxy # Verify data after the test has been "shot" + +QUIT + # The second CONNECT will be made to the dynamic port number the FTP server # opens for us, so we can't compare with a known pre-existing number! diff --git a/tests/data/test1632 b/tests/data/test1632 index 18674d21b..919f2c528 100644 --- a/tests/data/test1632 +++ b/tests/data/test1632 @@ -62,6 +62,9 @@ proxy # Verify data after the test has been "shot" + +QUIT + # The second and third CONNECT will be made to the dynamic port number the FTP # server opens for us, so we can't compare with known pre-existing numbers! diff --git a/tests/data/test1655 b/tests/data/test1655 index c5ec09129..6e7917031 100644 --- a/tests/data/test1655 +++ b/tests/data/test1655 @@ -17,7 +17,7 @@ unittest DoH -unit test for doh_encode +unit test for doh_req_encode diff --git a/tests/data/test1704 b/tests/data/test1704 index a8f285eea..a8740187f 100644 --- a/tests/data/test1704 +++ b/tests/data/test1704 @@ -54,7 +54,7 @@ User-Agent: curl/%VERSION Accept: */* Connection: Upgrade, HTTP2-Settings Upgrade: h2c -HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA +HTTP2-Settings: AAMAAABkAAQAAQAAAAIAAAAA diff --git a/tests/data/test1705 b/tests/data/test1705 index af2263da3..6736d928c 100644 --- a/tests/data/test1705 +++ b/tests/data/test1705 @@ -222,8 +222,8 @@ sensitive data, including usernames, credentials or secret data content. Be aware and be careful when sharing trace logs with others. End with a quote -.nf +.nf hello .fi @@ -234,7 +234,7 @@ Disable it again with \-\-no-fakeitreal. Example: .nf - curl --verbose https://example.com +curl --verbose https://example.com .fi This option is mutually exclusive with \fI\-\-trace\fP and \fI\-\-trace\-ascii\fP. @@ -272,7 +272,7 @@ If --proto is provided several times, the last set value is used. Example: .nf - curl --proto =http,https,sftp https://example.com +curl --proto =http,https,sftp https://example.com .fi See also \fI-v, \-\-fakeitreal\fP and \fI\-\-proto\-default\fP. diff --git a/tests/data/test1707 b/tests/data/test1707 new file mode 100644 index 000000000..f18749068 --- /dev/null +++ b/tests/data/test1707 @@ -0,0 +1,27 @@ + + + +curl + + + +# +# Client-side + + +manual + + +none + + + +Verify curl -h --insecure + + + +%SRCDIR/test1707.pl %CURL --insecure %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt + + + + diff --git a/tests/data/test1708 b/tests/data/test1708 new file mode 100644 index 000000000..ab59e71fa --- /dev/null +++ b/tests/data/test1708 @@ -0,0 +1,27 @@ + + + +curl + + + +# +# Client-side + + +manual + + +none + + + +Verify curl -h -F + + + +%SRCDIR/test1707.pl %CURL -F %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt + + + + diff --git a/tests/data/test1709 b/tests/data/test1709 new file mode 100644 index 000000000..8482ba49a --- /dev/null +++ b/tests/data/test1709 @@ -0,0 +1,32 @@ + + + +curl + + + +# +# Client-side + + +manual + + +none + + + +Verify curl -h --badone + + + +-h --badone + + + + + +Incorrect option name to show help for, see curl -h + + + diff --git a/tests/data/test1710 b/tests/data/test1710 new file mode 100644 index 000000000..7356355e4 --- /dev/null +++ b/tests/data/test1710 @@ -0,0 +1,27 @@ + + + +curl + + + +# +# Client-side + + +manual + + +none + + + +Verify curl -h --no-clobber + + + +%SRCDIR/test1707.pl %CURL --no-clobber %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt + + + + diff --git a/tests/data/test1800 b/tests/data/test1800 index de315d063..b1fd8021a 100644 --- a/tests/data/test1800 +++ b/tests/data/test1800 @@ -49,7 +49,7 @@ User-Agent: curl/%VERSION Accept: */* Connection: Upgrade, HTTP2-Settings Upgrade: %H2CVER -HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA +HTTP2-Settings: AAMAAABkAAQAAQAAAAIAAAAA diff --git a/tests/data/test182 b/tests/data/test182 index cb1e4f0c2..b49f10f85 100644 --- a/tests/data/test182 +++ b/tests/data/test182 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test191 b/tests/data/test191 index 029369363..749a34ec9 100644 --- a/tests/data/test191 +++ b/tests/data/test191 @@ -27,6 +27,9 @@ FTP URL with ?-letters in username and password # Verify data after the test has been "shot" + +QUIT + USER use?r PASS pass?word diff --git a/tests/data/test1976 b/tests/data/test1976 new file mode 100644 index 000000000..7c04bc655 --- /dev/null +++ b/tests/data/test1976 @@ -0,0 +1,60 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 + + + + +# Client-side + + +http + + +SSL +Debug +crypto + + +HTTP AWS_SIGV4 canonical request header sorting test + + +-X PUT -H "X-Amz-Meta-Test-Two: test2" -H "x-amz-meta-test: test" --aws-sigv4 "aws:amz:us-east-1:s3" -u "xxx:yyy" http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Length:.* +^Accept:.* + + +# Strip the actual signature. We only care about header order in this test +s/Signature=[a-f0-9]{64}/Signature=stripped/ + + +PUT /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-meta-test;x-amz-meta-test-two, Signature=stripped +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +X-Amz-Meta-Test-Two: test2 +x-amz-meta-test: test + + + + diff --git a/tests/data/test2000 b/tests/data/test2000 index 032bf5b1b..ee2e50734 100644 --- a/tests/data/test2000 +++ b/tests/data/test2000 @@ -46,6 +46,9 @@ moo # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test2001 b/tests/data/test2001 index de1673531..39eb1ff9d 100644 --- a/tests/data/test2001 +++ b/tests/data/test2001 @@ -63,6 +63,9 @@ moo # # Verify data after the test has been "shot" + +QUIT + GET /%TESTNUMBER0001 HTTP/1.1 Host: %HOSTIP:%HTTPPORT diff --git a/tests/data/test2002 b/tests/data/test2002 index 4b2b4fef6..7a581a5cb 100644 --- a/tests/data/test2002 +++ b/tests/data/test2002 @@ -73,6 +73,9 @@ moo # Verify data after the test has been "shot" +QUIT + + ^timeout = [5-6]$ diff --git a/tests/data/test2003 b/tests/data/test2003 index dcd862178..2475bbe32 100644 --- a/tests/data/test2003 +++ b/tests/data/test2003 @@ -73,6 +73,9 @@ moo # Verify data after the test has been "shot" +QUIT + + ^timeout = [5-6]$ diff --git a/tests/data/test2023 b/tests/data/test2023 index e395ece9d..759e68280 100644 --- a/tests/data/test2023 +++ b/tests/data/test2023 @@ -112,18 +112,9 @@ libauthretry HTTP authorization retry (Basic) - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER basic basic - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test2024 b/tests/data/test2024 index 07bf931a2..915f76919 100644 --- a/tests/data/test2024 +++ b/tests/data/test2024 @@ -126,18 +126,9 @@ libauthretry HTTP authorization retry (Basic switching to Digest) - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER basic digest - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test2026 b/tests/data/test2026 index 81d252a30..96e2ad496 100644 --- a/tests/data/test2026 +++ b/tests/data/test2026 @@ -162,18 +162,9 @@ libauthretry HTTP authorization retry (Digest switching to Basic) - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER digest basic - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test2027 b/tests/data/test2027 index 0a9338777..45baa64bc 100644 --- a/tests/data/test2027 +++ b/tests/data/test2027 @@ -185,18 +185,9 @@ libauthretry HTTP authorization retry (Digest) - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - http://%HOSTIP:%HTTPPORT/%TESTNUMBER digest digest - -chkhostname curlhost - # Verify data after the test has been "shot" diff --git a/tests/data/test2036 b/tests/data/test2036 deleted file mode 100644 index 9fd89a2ac..000000000 --- a/tests/data/test2036 +++ /dev/null @@ -1,36 +0,0 @@ - - - -FAILURE - - -# -# Server-side - - - -# -# Client-side - - -none - - -http - - -HTTP, -O with no slash at all in the URL - - -%HOSTIP:%NOLISTENPORT -O - - - -# -# Verify data after the test has been "shot" - - -23 - - - diff --git a/tests/data/test2039 b/tests/data/test2039 index 7cab984ce..05f23ab74 100644 --- a/tests/data/test2039 +++ b/tests/data/test2039 @@ -48,6 +48,9 @@ machine %HOSTIP login user2 password passwd2 # # Verify data after the test has been "shot" + +QUIT + USER userdef PASS passwddef diff --git a/tests/data/test2041 b/tests/data/test2041 index b7b461e0d..f7d060064 100644 --- a/tests/data/test2041 +++ b/tests/data/test2041 @@ -35,7 +35,7 @@ https Server-localhost-sv.pem simple HTTPS GET with base64-sha256 public key pinning ---cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//AAUDLk4c98xcFUDvA9i/MnA9HuO03IPi15r+Cx9OXnc= https://localhost:%HTTPSPORT/%TESTNUMBER +--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//%sha256b64file[%SRCDIR/certs/Server-localhost-sv.pub.der]sha256b64file% https://localhost:%HTTPSPORT/%TESTNUMBER # Ensure that we're running on localhost because we're checking the host name diff --git a/tests/data/test2057 b/tests/data/test2057 index 1e7568c6e..5cbb94590 100644 --- a/tests/data/test2057 +++ b/tests/data/test2057 @@ -51,7 +51,7 @@ Nice auth sir! http -HTTP Negotiate authentication (stub ntlm) +HTTP Negotiate authentication (stub NTLM) GSS-API diff --git a/tests/data/test2072 b/tests/data/test2072 index 50cb4b60a..caa8c75c2 100644 --- a/tests/data/test2072 +++ b/tests/data/test2072 @@ -21,13 +21,13 @@ moo file -file:// with unix path resolution behavior for the case of extra slashes +file:// with Unix path resolution behavior for the case of extra slashes file:////%PWD/%LOGDIR/test%TESTNUMBER.txt -perl -e "print 'Test requires a unix system' if ( $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'dos' || $^O eq 'msys');" +perl -e "print 'Test requires a Unix system' if ( $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'dos' || $^O eq 'msys');" foo diff --git a/tests/data/test2087 b/tests/data/test2087 index eb8d3bad8..13efe48b6 100644 --- a/tests/data/test2087 +++ b/tests/data/test2087 @@ -39,7 +39,7 @@ simple HTTPS GET with base64-sha256 public key pinning (Schannel variant) CURL_SSL_BACKEND=schannel ---cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//AAUDLk4c98xcFUDvA9i/MnA9HuO03IPi15r+Cx9OXnc= --ssl-revoke-best-effort https://localhost:%HTTPSPORT/%TESTNUMBER +--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//%sha256b64file[%SRCDIR/certs/Server-localhost-sv.pub.der]sha256b64file% --ssl-revoke-best-effort https://localhost:%HTTPSPORT/%TESTNUMBER # Ensure that we're running on localhost because we're checking the host name diff --git a/tests/data/test210 b/tests/data/test210 index 1ee313d76..c4ccb6b2c 100644 --- a/tests/data/test210 +++ b/tests/data/test210 @@ -33,6 +33,9 @@ data blobb # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test211 b/tests/data/test211 index 6830727ab..01dcad0ee 100644 --- a/tests/data/test211 +++ b/tests/data/test211 @@ -34,6 +34,9 @@ data blobb # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test212 b/tests/data/test212 index 045ad3769..a16bf4211 100644 --- a/tests/data/test212 +++ b/tests/data/test212 @@ -39,6 +39,9 @@ data blobb # Verify data after the test has been "shot" + +QUIT + # Strip the addresses and port number but leave the rest s/^(EPRT \|1\|)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\|\d{1,5}\|/$1/ diff --git a/tests/data/test215 b/tests/data/test215 index 058639f27..d2ba2c702 100644 --- a/tests/data/test215 +++ b/tests/data/test215 @@ -38,6 +38,9 @@ ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER/ ftp://%HOSTIP:%FTPPORT/a/path/%TESTNU # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test216 b/tests/data/test216 index 1be87c0d1..a0ec72be1 100644 --- a/tests/data/test216 +++ b/tests/data/test216 @@ -27,6 +27,9 @@ upload this file twice # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test227 b/tests/data/test227 index f7b445185..bf55fdd6c 100644 --- a/tests/data/test227 +++ b/tests/data/test227 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -Q "NOOP 1" -Q "+NOOP 2" -Q "-NOOP 3" -Q "*FA # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test228 b/tests/data/test228 index 8e7d73ff0..ae19b534b 100644 --- a/tests/data/test228 +++ b/tests/data/test228 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --ftp-account "one count" # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test235 b/tests/data/test235 index 4bfe7497e..485be98ec 100644 --- a/tests/data/test235 +++ b/tests/data/test235 @@ -32,6 +32,9 @@ worx? # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test236 b/tests/data/test236 index a66fa046d..13493f26a 100644 --- a/tests/data/test236 +++ b/tests/data/test236 @@ -33,6 +33,9 @@ Test data # Verify data after the test has been "shot" + +QUIT + USER anonymous diff --git a/tests/data/test238 b/tests/data/test238 index 3c0db0441..71b46ddc3 100644 --- a/tests/data/test238 +++ b/tests/data/test238 @@ -27,6 +27,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + # 13 = CURLE_FTP_WEIRD_PASV_REPLY 13 diff --git a/tests/data/test244 b/tests/data/test244 index 782be2be4..ad9cf4fe2 100644 --- a/tests/data/test244 +++ b/tests/data/test244 @@ -41,6 +41,9 @@ FTP dir listing with nocwd and URL encoded path # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test247 b/tests/data/test247 index 40f42e7d0..5eade37b3 100644 --- a/tests/data/test247 +++ b/tests/data/test247 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt -z "apr 1 2005 # Verify data after the test has been "shot" + +QUIT + diff --git a/tests/data/test248 b/tests/data/test248 index 097e1e583..2d5c845ba 100644 --- a/tests/data/test248 +++ b/tests/data/test248 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt -z "apr 1 2005 # Verify data after the test has been "shot" + +QUIT + data to diff --git a/tests/data/test250 b/tests/data/test250 index 4f01ea79a..59f7fa311 100644 --- a/tests/data/test250 +++ b/tests/data/test250 @@ -46,6 +46,9 @@ ftp://%HOSTIP:%FTPPORT/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test251 b/tests/data/test251 index 9ed8c9488..6de2003c8 100644 --- a/tests/data/test251 +++ b/tests/data/test251 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT/ -P %CLIENTIP # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test252 b/tests/data/test252 index 1480ee1ec..35c3014a0 100644 --- a/tests/data/test252 +++ b/tests/data/test252 @@ -45,6 +45,9 @@ FTP IPv6 dir list PASV # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test253 b/tests/data/test253 index 01ec416ac..8f7192d21 100644 --- a/tests/data/test253 +++ b/tests/data/test253 @@ -45,6 +45,9 @@ FTP IPv6 dir list with EPRT # # Verify data after the test has been "shot" + +QUIT + s/^(EPRT \|2\|::1\|)(.*)/$1/ diff --git a/tests/data/test254 b/tests/data/test254 index 90b58a0b3..ede445355 100644 --- a/tests/data/test254 +++ b/tests/data/test254 @@ -46,6 +46,9 @@ FTP IPv6 dir list PASV and --disable-epsv # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test255 b/tests/data/test255 index 1a1526a10..190908e35 100644 --- a/tests/data/test255 +++ b/tests/data/test255 @@ -46,6 +46,9 @@ FTP IPv6 dir list with EPRT and --disable-eprt # # Verify data after the test has been "shot" + +QUIT + s/^(EPRT \|2\|::1\|)(.*)/$1/ diff --git a/tests/data/test261 b/tests/data/test261 index d5f940372..192b2bcd7 100644 --- a/tests/data/test261 +++ b/tests/data/test261 @@ -34,6 +34,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test268 b/tests/data/test268 index 3a1ab6a9b..0d205fe73 100644 --- a/tests/data/test268 +++ b/tests/data/test268 @@ -32,7 +32,7 @@ Funny-head: yesyes http -JSON encoding of unicode string +JSON encoding of Unicode string %hex[%e2%80%9c]hex% diff --git a/tests/data/test270 b/tests/data/test270 index efa183f15..f4f5a0231 100644 --- a/tests/data/test270 +++ b/tests/data/test270 @@ -36,6 +36,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --ftp-skip-pasv-ip --disable-epsv # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test272 b/tests/data/test272 index 2857c3eac..5607a1081 100644 --- a/tests/data/test272 +++ b/tests/data/test272 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -z "2004 jan 1 12:12:12 UTC" # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test280 b/tests/data/test280 index 1aee4b517..dbe809e1d 100644 --- a/tests/data/test280 +++ b/tests/data/test280 @@ -46,6 +46,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER/ --ftp-alternative-to-user "USER replacement" # # Verify data after the test has been "shot" + +QUIT + USER anonymous USER replacement diff --git a/tests/data/test290 b/tests/data/test290 index e7048a538..6ffa9a726 100644 --- a/tests/data/test290 +++ b/tests/data/test290 @@ -27,6 +27,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --max-filesize 30 # Verify data after the test has been "shot" + +QUIT + 63 diff --git a/tests/data/test291 b/tests/data/test291 index 05cc2b444..2385f7db4 100644 --- a/tests/data/test291 +++ b/tests/data/test291 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --max-filesize 100 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test294 b/tests/data/test294 index 67108aedb..4e2e9857d 100644 --- a/tests/data/test294 +++ b/tests/data/test294 @@ -47,6 +47,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER/ --ftp-account "data for acct" # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test296 b/tests/data/test296 index c88ec99bf..d4b87dfa4 100644 --- a/tests/data/test296 +++ b/tests/data/test296 @@ -31,6 +31,9 @@ FTP CWD with --ftp-method multicwd # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test297 b/tests/data/test297 index 99c10d3e1..d982a3b7f 100644 --- a/tests/data/test297 +++ b/tests/data/test297 @@ -31,6 +31,9 @@ FTP CWD with --ftp-method singlecwd # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test298 b/tests/data/test298 index 5188c8547..3880a6073 100644 --- a/tests/data/test298 +++ b/tests/data/test298 @@ -31,6 +31,9 @@ FTP CWD with --ftp-method nocwd # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test3017 b/tests/data/test3017 index 4d907b39f..209babf20 100644 --- a/tests/data/test3017 +++ b/tests/data/test3017 @@ -47,7 +47,7 @@ mqtt://%HOSTIP:%MQTTPORT/%TESTNUMBER -m 3 s/^(.* 00044d5154540402003c000c6375726c).*/$1/ -# on windows the disconnect is never seen - no idea why +# on Windows the disconnect is never seen - no idea why ^server DISCONNECT 0 e000 diff --git a/tests/data/test3018 b/tests/data/test3018 index 71e06b593..d58daf41a 100644 --- a/tests/data/test3018 +++ b/tests/data/test3018 @@ -45,7 +45,7 @@ mqtt://%HOSTIP:%MQTTPORT/%TESTNUMBER --max-filesize 11 s/^(.* 00044d5154540402003c000c6375726c).*/$1/ -# on windows the disconnect is never seen - no idea why +# on Windows the disconnect is never seen - no idea why ^server DISCONNECT 0 e000 diff --git a/tests/data/test3027 b/tests/data/test3027 index 05a811f4e..416c0079d 100644 --- a/tests/data/test3027 +++ b/tests/data/test3027 @@ -40,6 +40,9 @@ data blobb # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test3207 b/tests/data/test3207 new file mode 100644 index 000000000..01b3353a3 --- /dev/null +++ b/tests/data/test3207 @@ -0,0 +1,175 @@ + + + +HTTPS + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 29 + +run 1: foobar and so on fun! + + +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! +run 1: foobar and so on fun! + + + +# Client-side + + +SSL +OpenSSL + + +https + + +concurrent HTTPS GET using shared ssl session cache + + +lib%TESTNUMBER + +# provide URL and ca-cert + +https://localhost:%HTTPSPORT/%TESTNUMBER %SRCDIR/certs/EdelCurlRoot-ca.crt + + + +# Verify data after the test has been "shot" + + + diff --git a/tests/data/test336 b/tests/data/test336 index f50b42adb..4e881379a 100644 --- a/tests/data/test336 +++ b/tests/data/test336 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --range 3-6 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test337 b/tests/data/test337 index d44a712fb..b82f94786 100644 --- a/tests/data/test337 +++ b/tests/data/test337 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --range 3-6 # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test348 b/tests/data/test348 index 55e9d608d..988e5bd04 100644 --- a/tests/data/test348 +++ b/tests/data/test348 @@ -36,6 +36,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt # Verify data after the test has been "shot" + +QUIT + data to diff --git a/tests/data/test350 b/tests/data/test350 index 3eb8b80aa..7342275d4 100644 --- a/tests/data/test350 +++ b/tests/data/test350 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT// --ftp-method multicwd # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test351 b/tests/data/test351 index ffa93e3e2..31c07fa3c 100644 --- a/tests/data/test351 +++ b/tests/data/test351 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT// --ftp-method nocwd # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test352 b/tests/data/test352 index 0cc4d69fd..d54ab60eb 100644 --- a/tests/data/test352 +++ b/tests/data/test352 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT// --ftp-method singlecwd # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test353 b/tests/data/test353 index a94828bd6..dedd06960 100644 --- a/tests/data/test353 +++ b/tests/data/test353 @@ -41,6 +41,9 @@ ftp://%HOSTIP:%FTPPORT/ --ftp-method singlecwd # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test354 b/tests/data/test354 index dc6d732d8..9a40d49c6 100644 --- a/tests/data/test354 +++ b/tests/data/test354 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PWD diff --git a/tests/data/test362 b/tests/data/test362 index e8ce9731e..d259593fd 100644 --- a/tests/data/test362 +++ b/tests/data/test362 @@ -29,6 +29,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt --continue-at + +QUIT + data to diff --git a/tests/data/test380 b/tests/data/test380 index f9ccafdab..47676e3dd 100644 --- a/tests/data/test380 +++ b/tests/data/test380 @@ -48,6 +48,9 @@ machine %HOSTIP login mary password yram # # Verify data after the test has been "shot" + +QUIT + USER mary PASS yram diff --git a/tests/data/test381 b/tests/data/test381 index 41b9eb779..bf2877302 100644 --- a/tests/data/test381 +++ b/tests/data/test381 @@ -52,6 +52,9 @@ machine %HOSTIP login mary password yram # # Verify data after the test has been "shot" + +QUIT + USER mary PASS drfrank diff --git a/tests/data/test416 b/tests/data/test416 index b6b10b3df..f50ad70dd 100644 --- a/tests/data/test416 +++ b/tests/data/test416 @@ -38,6 +38,9 @@ FTP growing file support # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test417 b/tests/data/test417 index 9061f8332..50f4b479b 100644 --- a/tests/data/test417 +++ b/tests/data/test417 @@ -51,31 +51,7 @@ s/^(.*):(.*)[\r\n]*// nomnom ------BEGIN CERTIFICATE----- -MIIERDCCAyygAwIBAgIGDzR1UZ/TMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYT -Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo -IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe -Fw0yMjEyMjMxMjIxMzlaFw0zMTAzMTExMjIxMzlaMFQxCzAJBgNVBAYTAk5OMTEw -LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk -MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCrCrAD0Hb+Xs4V3mHV45FvfNa7yiaOeL4mNdGmWfHVPFU+CSzsoNSvDjxa -orWweFGVYoCAcchOn1lZk0ASsqnOss0Xi58n8+PPI3gG0gYjX5sg7EJ3Zq2kXoK0 -TZRy6hNkcvzLgyzXoYv1LkzTwYiyyJgZX++Y/GKAs2fMHyP8XzjNgm4tltk1k/4p -omllwN9Fqz+sFxgAgEq3ybq4Xym7xKwWl8xXNBDJNmVsPtiJRcilQoR8Xs0a6PE+ -VbMhD9A2E/LEL7lzQfqHqtxE1mSW5FpQ+Uqf4KLnafStWs86IOWnCeLP6BmhAK6o -uyICNFyzz7UkTHa/renxuNOGun2TAgMBAAGjggEGMIIBAjAUBgNVHREEDTALggls -b2NhbGhvc3QwCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0GA1Ud -DgQWBBScl7A9s1Cx9tRx4uvLgOqTfJjMcjAfBgNVHSMEGDAWgBSHy7EzLsFnfnHj -5StMTaSzbtJbqTAJBgNVHRMEAjAAMEMGCCsGAQUFBwEBBDcwNTAzBggrBgEFBQcw -AoYnaHR0cDovL3Rlc3QuY3VybC5zZS9jYS9FZGVsQ3VybFJvb3QuY2VyMDgGA1Ud -HwQxMC8wLaAroCmGJ2h0dHA6Ly90ZXN0LmN1cmwuc2UvY2EvRWRlbEN1cmxSb290 -LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAC4rtaof6cRWIJViFG0oJv0MANZN4DXIU -MFHik4Oh2hsvqTGut8dMcsJeMiTxlpNw1T+1hYATdTLPDvhdxKIphEMsdYEmEmqg -y3tXwZJ4hQj6ZFDCe4MCTXkTvGFkTbhr1fGEaxJcaZCtQEfA7d3qimZ+h4UZqonT -PAhyCKFNY2BbmxeeABKhAFLKeAGIGMftW8fk2eu9P6+SUz/+WFcN/PR7e6JP6blc -taRSULRWWkSO2dDt3o9+rBxYdluoecmVq4Ud20wTgkqlQRsp9dOW34DRHgB9ujWU -V4HhCCqBaxwwUDcBGg4mT2vtyVAXNyszP2j+xvAhjOeyeVXyQr0vsA== ------END CERTIFICATE----- +%strippemfile[%SRCDIR/certs/stunnel-sv.crt]strippemfile% diff --git a/tests/data/test424 b/tests/data/test424 index 36ba8c4b7..9ae6b1fab 100644 --- a/tests/data/test424 +++ b/tests/data/test424 @@ -59,10 +59,10 @@ http # Verify data after the test has been "shot" -anotherhost.example+/%TESTNUMBER0002+http+uuuu+pppp+2023+moo.html+ -hello2000+/%TESTNUMBER+h55p+++1+qqqq+ffff +anotherhost.example+/4240002+http+++2023+moo.html+ +hello2000+/424+h55p+++1+qqqq+ffff +++++++ -anotherhost.example+/%TESTNUMBER0002+http+u22u+p22p+2023+moo.html+ +anotherhost.example+/4240002+http+++2023+moo.html+ diff --git a/tests/data/test433 b/tests/data/test433 index f6505d032..f1c405634 100644 --- a/tests/data/test433 +++ b/tests/data/test433 @@ -20,7 +20,7 @@ Content-Type: text/1 # # Client-side - + --next header = "a: a" data = "curlrc read" @@ -34,7 +34,7 @@ HOME= CURL_HOME= -Verify XDG_CONFIG_HOME use to find .curlrc +Verify XDG_CONFIG_HOME use to find curlrc %HOSTIP:%HTTPPORT/%TESTNUMBER diff --git a/tests/data/test469 b/tests/data/test469 index 9bcdc5980..81d341cd8 100644 --- a/tests/data/test469 +++ b/tests/data/test469 @@ -35,7 +35,7 @@ Funny-head: yesyes http -warn about unicode quote character +warn about Unicode quote character -H “host: %HOSTIP:%HTTPPORT/” -s @@ -46,7 +46,7 @@ warn about unicode quote character # Verify data after the test has been "shot" -%hex[Warning: The argument '%e2%80%9chost:' starts with a unicode quote where maybe an ]hex% +%hex[Warning: The argument '%e2%80%9chost:' starts with a Unicode quote where maybe an ]hex% Warning: ASCII " was intended? diff --git a/tests/data/test470 b/tests/data/test470 index 30dd9a82e..70e50e621 100644 --- a/tests/data/test470 +++ b/tests/data/test470 @@ -35,7 +35,7 @@ Funny-head: yesyes http -warn about unicode quote character read from config file +warn about Unicode quote character read from config file -H “host:fake” @@ -49,7 +49,7 @@ warn about unicode quote character read from config file # Verify data after the test has been "shot" -%hex[Warning: The argument '%e2%80%9chost:fake%e2%80%9d' starts with a unicode quote where ]hex% +%hex[Warning: The argument '%e2%80%9chost:fake%e2%80%9d' starts with a Unicode quote where ]hex% Warning: maybe an ASCII " was intended? diff --git a/tests/data/test474 b/tests/data/test474 new file mode 100644 index 000000000..37e0805b5 --- /dev/null +++ b/tests/data/test474 @@ -0,0 +1,52 @@ + + + +-w +--write-out + + + +# +# Server-side + + +HTTP/1.1 301 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: https://%HOSTIP:%HTTPSPORT/%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 0 +Connection: close + + + + +# +# Client-side + + +http +https + + +-w urle.scheme after HTTP to HTTPS redirect + + +-k -L http://%HOSTIP:%HTTPPORT/%TESTNUMBER -w "%{num_redirects} %{url_effective} %{urle.scheme}\n" + + + +# +# Verify data after the test has been "shot" + + +1 https://%HOSTIP:%HTTPSPORT/%TESTNUMBER0002 https + + + diff --git a/tests/data/test475 b/tests/data/test475 new file mode 100644 index 000000000..b0e4c2ca4 --- /dev/null +++ b/tests/data/test475 @@ -0,0 +1,45 @@ + + + +FTP +EPSV +STOR +TYPE A + + + +# Client-side + + +ftp + + +FTP PASV upload ASCII file + + +%repeat[1750 x a line of text used for verifying this !%0a]% + + +"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt + + + +# Verify data after the test has been "shot" + + +QUIT + + +%repeat[1750 x a line of text used for verifying this !%0a]% + + +USER anonymous +PASS ftp@example.com +PWD +EPSV +TYPE A +STOR %TESTNUMBER +QUIT + + + diff --git a/tests/data/test476 b/tests/data/test476 new file mode 100644 index 000000000..00aed7c44 --- /dev/null +++ b/tests/data/test476 @@ -0,0 +1,45 @@ + + + +FTP +EPSV +STOR +TYPE A + + + +# Client-side + + +ftp + + +FTP PASV upload ASCII file already using CRLF + + +%repeat[1750 x a line of text used for verifying this !%0a]% + + +"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt + + + +# Verify data after the test has been "shot" + + +QUIT + + +%repeat[1750 x a line of text used for verifying this !%0a]% + + +USER anonymous +PASS ftp@example.com +PWD +EPSV +TYPE A +STOR %TESTNUMBER +QUIT + + + diff --git a/tests/data/test494 b/tests/data/test494 index 648318729..c089d75c7 100644 --- a/tests/data/test494 +++ b/tests/data/test494 @@ -46,6 +46,9 @@ machine %HOSTIP login user1 password passwd1 # # Verify data after the test has been "shot" + +QUIT + USER user1 PASS passwd1 diff --git a/tests/data/test505 b/tests/data/test505 index 6eba48936..aa26ccb5f 100644 --- a/tests/data/test505 +++ b/tests/data/test505 @@ -40,6 +40,9 @@ works? # Verify data after the test has been "shot" + +QUIT + Contents of diff --git a/tests/data/test511 b/tests/data/test511 index adcabe8bd..7637dcede 100644 --- a/tests/data/test511 +++ b/tests/data/test511 @@ -35,6 +35,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" + +QUIT + # CURLE_REMOTE_FILE_NOT_FOUND 78 diff --git a/tests/data/test520 b/tests/data/test520 index 6a27bb3f8..17d89199b 100644 --- a/tests/data/test520 +++ b/tests/data/test520 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/520 # # Verify data after the test has been "shot" + +QUIT + USER anonymous diff --git a/tests/data/test521 b/tests/data/test521 index 90473b33a..eaeb040d3 100644 --- a/tests/data/test521 +++ b/tests/data/test521 @@ -44,6 +44,9 @@ ftp://%HOSTIP/%TESTNUMBER/ %FTPPORT # # Verify data after the test has been "shot" + +QUIT + USER xxx PASS yyy diff --git a/tests/data/test525 b/tests/data/test525 index 2b96a7fd9..82a85276f 100644 --- a/tests/data/test525 +++ b/tests/data/test525 @@ -36,6 +36,9 @@ Moooooooooooo # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test526 b/tests/data/test526 index 85b24d5db..3a303e9a0 100644 --- a/tests/data/test526 +++ b/tests/data/test526 @@ -39,6 +39,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test527 b/tests/data/test527 index 85b24d5db..3a303e9a0 100644 --- a/tests/data/test527 +++ b/tests/data/test527 @@ -39,6 +39,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test529 b/tests/data/test529 index 737e5018f..c92b377ef 100644 --- a/tests/data/test529 +++ b/tests/data/test529 @@ -36,6 +36,9 @@ Moooooooooooo # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test531 b/tests/data/test531 index 59501d5ea..33739ea7e 100644 --- a/tests/data/test531 +++ b/tests/data/test531 @@ -39,6 +39,9 @@ don't upload this # Verify data after the test has been "shot" + +QUIT + # Strip all valid kinds of PORT and EPRT that curl can send ^PORT \d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3},\d{1,3} diff --git a/tests/data/test532 b/tests/data/test532 index c1d3b0b0c..128b2d880 100644 --- a/tests/data/test532 +++ b/tests/data/test532 @@ -39,6 +39,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test533 b/tests/data/test533 index 1dbceb6dd..f6467acaa 100644 --- a/tests/data/test533 +++ b/tests/data/test533 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test534 b/tests/data/test534 index 0e0f35abd..87b98b5e7 100644 --- a/tests/data/test534 +++ b/tests/data/test534 @@ -38,6 +38,9 @@ ftp://non-existing-host.haxx.se/path/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/path/%TE # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test539 b/tests/data/test539 index 7985a5234..b774ead0b 100644 --- a/tests/data/test539 +++ b/tests/data/test539 @@ -43,6 +43,9 @@ ftp://%HOSTIP:%FTPPORT/path/to/the/file/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/path/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test541 b/tests/data/test541 index c0677d8ea..9492d0854 100644 --- a/tests/data/test541 +++ b/tests/data/test541 @@ -40,6 +40,9 @@ works? # Verify data after the test has been "shot" + +QUIT + diff --git a/tests/data/test542 b/tests/data/test542 index b39b1b30d..4a412c8bf 100644 --- a/tests/data/test542 +++ b/tests/data/test542 @@ -44,6 +44,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # There's no MTDM in the protocol here since this code doesn't ask for the # time/date of the file + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test546 b/tests/data/test546 index f8f01641a..6021b6758 100644 --- a/tests/data/test546 +++ b/tests/data/test546 @@ -44,6 +44,9 @@ ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER ftp://%HOSTIP:%FTPPORT/path/%TESTNUMBER # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test562 b/tests/data/test562 index d1793891d..c2cf2546c 100644 --- a/tests/data/test562 +++ b/tests/data/test562 @@ -39,6 +39,9 @@ FTP a type=A URL and CURLOPT_PORT set # There's no MTDM in the protocol here since this code doesn't ask for the # time/date of the file + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test564 b/tests/data/test564 index 96a6f9b1a..3b0a2ae1e 100644 --- a/tests/data/test564 +++ b/tests/data/test564 @@ -45,6 +45,9 @@ proxy # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test574 b/tests/data/test574 index 3c151286c..50d2120f0 100644 --- a/tests/data/test574 +++ b/tests/data/test574 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/fully_simulated/UNIX/*.txt ############################################ # Verify data after the test has been "shot" + +QUIT + 0 diff --git a/tests/data/test575 b/tests/data/test575 index d51c5a08d..35b65a3d6 100644 --- a/tests/data/test575 +++ b/tests/data/test575 @@ -32,6 +32,9 @@ ftp://%HOSTIP:%FTPPORT/fully_simulated/UNIX/* # Verify data after the test has been "shot" + +QUIT + 0 diff --git a/tests/data/test579 b/tests/data/test579 index 68fce50d4..eaee6e323 100644 --- a/tests/data/test579 +++ b/tests/data/test579 @@ -76,14 +76,10 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER %LOGDIR/ip%TESTNUMBER # Verify data after the test has been "shot" -Progress callback called with UL 0 out of 0 -Progress callback called with UL 5 out of 0 -Progress callback called with UL 0 out of 0 -Progress callback called with UL 8 out of 0 -Progress callback called with UL 16 out of 0 -Progress callback called with UL 26 out of 0 -Progress callback called with UL 61 out of 0 -Progress callback called with UL 66 out of 0 +Progress: start UL 0/0 +Progress: end UL 5/0 +Progress: start UL 0/0 +Progress: end UL 66/0 diff --git a/tests/data/test586 b/tests/data/test586 index b17a702a6..a708f3b59 100644 --- a/tests/data/test586 +++ b/tests/data/test586 @@ -45,6 +45,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test587 b/tests/data/test587 index 541df4546..c896a5b6b 100644 --- a/tests/data/test587 +++ b/tests/data/test587 @@ -41,21 +41,6 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" - -s/^--------------------------[A-Za-z0-9]*/------------------------------/ -s/boundary=------------------------[A-Za-z0-9]*/boundary=----------------------------/ - - -POST /%TESTNUMBER HTTP/1.1 -Host: %HOSTIP:%HTTPPORT -Accept: */* -Content-Length: 780 -Content-Type: multipart/form-data; boundary=---------------------------- - ------------------------------- -Content-Disposition: form-data; name="sendfile"; filename="postit2.c" - - # CURLE_ABORTED_BY_CALLBACK (42) 42 diff --git a/tests/data/test588 b/tests/data/test588 index 9c8c5f320..d41131c42 100644 --- a/tests/data/test588 +++ b/tests/data/test588 @@ -45,6 +45,9 @@ Moooooooooooo # Verify data after the test has been "shot" + +QUIT + # Strip off parts of the PORT and EPRT commands that might differ s/^PORT (.*)/PORT/ diff --git a/tests/data/test591 b/tests/data/test591 index d1cbf082a..10d12ca26 100644 --- a/tests/data/test591 +++ b/tests/data/test591 @@ -47,6 +47,9 @@ Moooooooooooo for %TESTNUMBER # Verify data after the test has been "shot" + +QUIT + # Strip off parts of the PORT and EPRT commands that might differ s/^PORT (.*)/PORT/ diff --git a/tests/data/test592 b/tests/data/test592 index f77eb9a87..a6fbaf72b 100644 --- a/tests/data/test592 +++ b/tests/data/test592 @@ -47,6 +47,9 @@ Moooooooooooo for %TESTNUMBER # Verify data after the test has been "shot" + +QUIT + # Strip off parts of the PORT and EPRT commands that might differ s/^PORT (.*)/PORT/ diff --git a/tests/data/test593 b/tests/data/test593 index 9a15a5184..5c3bdf35f 100644 --- a/tests/data/test593 +++ b/tests/data/test593 @@ -47,6 +47,9 @@ Moooooooooooo for %TESTNUMBER # Verify data after the test has been "shot" + +QUIT + # Strip off parts of the PORT and EPRT commands that might differ s/^PORT (.*)/PORT/ diff --git a/tests/data/test594 b/tests/data/test594 index cd98f0b9d..e0dfc56e3 100644 --- a/tests/data/test594 +++ b/tests/data/test594 @@ -49,6 +49,9 @@ Moooooooooooo for %TESTNUMBER # Verify data after the test has been "shot" + +QUIT + # Strip off parts of the PORT and EPRT commands that might differ s/^PORT (.*)/PORT/ diff --git a/tests/data/test595 b/tests/data/test595 index 40ace13d5..13d6bb927 100644 --- a/tests/data/test595 +++ b/tests/data/test595 @@ -43,6 +43,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER %LOGDIR/ip%TESTNUMBER # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test596 b/tests/data/test596 index 7175c63f8..30e401df7 100644 --- a/tests/data/test596 +++ b/tests/data/test596 @@ -43,6 +43,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER %LOGDIR/ip%TESTNUMBER activeftp # # Verify data after the test has been "shot" + +QUIT + s/^(EPRT \|1\|)(.*)/$1/ diff --git a/tests/data/test649 b/tests/data/test649 index 7751e38f1..502e16ea5 100644 --- a/tests/data/test649 +++ b/tests/data/test649 @@ -42,32 +42,12 @@ It contains at least an 8-bit byte value. # # Verify data after the test has been "shot" - -s/^--------------------------[A-Za-z0-9]*/------------------------------/ -s/boundary=------------------------[A-Za-z0-9]*/boundary=----------------------------/ - EHLO %TESTNUMBER MAIL FROM: RCPT TO: DATA - -Content-Type: multipart/mixed; boundary=---------------------------- -Mime-Version: 1.0 -From: different -To: another - ------------------------------- -Content-Transfer-Encoding: 7bit - -This is valid ------------------------------- -Content-Disposition: attachment; filename="test%TESTNUMBER.txt" -Content-Transfer-Encoding: 7bit - -This is an attached file (in french: pi - 26 diff --git a/tests/data/test661 b/tests/data/test661 index 5965bd8ae..799d51e2d 100644 --- a/tests/data/test661 +++ b/tests/data/test661 @@ -33,6 +33,9 @@ ftp://%HOSTIP:%FTPPORT/ # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test690 b/tests/data/test690 new file mode 100644 index 000000000..6f333381c --- /dev/null +++ b/tests/data/test690 @@ -0,0 +1,67 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +-O with URL without path using trailing slash + + +http://%HOSTIP:%HTTPPORT/ -O --output-dir %LOGDIR + + + +# +# Verify data after the test has been "shot" + + +GET / HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + diff --git a/tests/data/test691 b/tests/data/test691 new file mode 100644 index 000000000..b8a9a08af --- /dev/null +++ b/tests/data/test691 @@ -0,0 +1,67 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +-O with URL with path using trailing slash + + +http://%HOSTIP:%HTTPPORT/path/to/here/ -O --output-dir %LOGDIR + + + +# +# Verify data after the test has been "shot" + + +GET /path/to/here/ HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + diff --git a/tests/data/test706 b/tests/data/test706 index faafd9038..8fbb24ba5 100644 --- a/tests/data/test706 +++ b/tests/data/test706 @@ -47,6 +47,9 @@ FTP dir list PASV via SOCKS4 # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test707 b/tests/data/test707 index 2c41dfea7..f22b2010e 100644 --- a/tests/data/test707 +++ b/tests/data/test707 @@ -47,6 +47,9 @@ FTP dir list PASV via SOCKS5 # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test711 b/tests/data/test711 index 355ca0e51..288fcc1df 100644 --- a/tests/data/test711 +++ b/tests/data/test711 @@ -43,6 +43,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test712 b/tests/data/test712 index 7bcc2a1bb..ef64b3f5b 100644 --- a/tests/data/test712 +++ b/tests/data/test712 @@ -37,6 +37,9 @@ ftp://%HOSTIP:%FTPPORT/%TESTNUMBER --proxy socks5://%HOSTIP:%SOCKSPORT # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test713 b/tests/data/test713 index 44820a78f..81374027f 100644 --- a/tests/data/test713 +++ b/tests/data/test713 @@ -38,6 +38,9 @@ ftp://ftp.example.com/%TESTNUMBER --connect-to ::%HOSTIP:%FTPPORT --proxy socks5 # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test714 b/tests/data/test714 index a38400bb8..6414188e6 100644 --- a/tests/data/test714 +++ b/tests/data/test714 @@ -57,6 +57,9 @@ ftp://ftp.example.com.%TESTNUMBER/%TESTNUMBER --connect-to ::connect.example.com # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test715 b/tests/data/test715 index 6f9670af5..e931e0d60 100644 --- a/tests/data/test715 +++ b/tests/data/test715 @@ -59,6 +59,9 @@ ftp://ftp.example.com.%TESTNUMBER/%TESTNUMBER --connect-to ::connect.example.com # # Verify data after the test has been "shot" + +QUIT + USER anonymous PASS ftp@example.com diff --git a/tests/data/test76 b/tests/data/test76 deleted file mode 100644 index 4c83566dd..000000000 --- a/tests/data/test76 +++ /dev/null @@ -1,36 +0,0 @@ - - - -FAILURE - - -# -# Server-side - - - -# -# Client-side - - -none - - -http - - -HTTP, -O with no file name part in the URL - - -http://%HOSTIP:%NOLISTENPORT/%TESTNUMBER/ -O - - - -# -# Verify data after the test has been "shot" - - -23 - - - diff --git a/tests/data/test831 b/tests/data/test831 index 382432368..1ef3d45c4 100644 --- a/tests/data/test831 +++ b/tests/data/test831 @@ -34,18 +34,9 @@ SSL IMAP NTLM graceful cancellation - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - 'imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/;MAILINDEX=1' -u testuser:testpass - -chkhostname curlhost - # diff --git a/tests/data/test834 b/tests/data/test834 index e142ca219..ccdf0d1fd 100644 --- a/tests/data/test834 +++ b/tests/data/test834 @@ -45,18 +45,9 @@ SSL IMAP NTLM authentication with SASL downgrade - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - 'imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/;MAILINDEX=1' -u user:secret - -chkhostname curlhost - # diff --git a/tests/data/test877 b/tests/data/test877 index 250237062..e2cb4b376 100644 --- a/tests/data/test877 +++ b/tests/data/test877 @@ -35,18 +35,9 @@ SSL POP3 NTLM graceful cancellation - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u testuser:testpass - -chkhostname curlhost - # diff --git a/tests/data/test880 b/tests/data/test880 index dfa2e688c..21536d81f 100644 --- a/tests/data/test880 +++ b/tests/data/test880 @@ -47,18 +47,9 @@ SSL POP3 NTLM authentication with SASL downgrade - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret - -chkhostname curlhost - # diff --git a/tests/data/test933 b/tests/data/test933 index 71f389300..3c25ffa5c 100644 --- a/tests/data/test933 +++ b/tests/data/test933 @@ -34,18 +34,9 @@ SSL SMTP NTLM graceful cancellation - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u testuser:testpass -T - - -chkhostname curlhost - # diff --git a/tests/data/test936 b/tests/data/test936 index f57f63ec8..723cebca3 100644 --- a/tests/data/test936 +++ b/tests/data/test936 @@ -40,18 +40,9 @@ SMTP NTLM authentication with SASL downgrade mail body - -# we force our own host name, in order to make the test machine independent -CURL_GETHOSTNAME=curlhost -# we try to use the LD_PRELOAD hack, if not a debug build -LD_PRELOAD=%PWD/libtest/.libs/libhostname.so - smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret -T - - -chkhostname curlhost - # diff --git a/tests/data/test941 b/tests/data/test941 index 79f88a674..7b7669fdd 100644 --- a/tests/data/test941 +++ b/tests/data/test941 @@ -26,7 +26,7 @@ To: another email headers and body -with unix newlines +with Unix newlines meant to be converted with @@ -55,7 +55,7 @@ To: another email headers and body -with unix newlines +with Unix newlines meant to be converted with diff --git a/tests/data/test970 b/tests/data/test970 index bf1235da5..989979738 100644 --- a/tests/data/test970 +++ b/tests/data/test970 @@ -59,7 +59,7 @@ Accept: */* -{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"} +{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_posttransfer":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"} diff --git a/tests/data/test972 b/tests/data/test972 index c6def2986..01bd2ed5f 100644 --- a/tests/data/test972 +++ b/tests/data/test972 @@ -60,7 +60,7 @@ Accept: */* -{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"} +{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"num_retries":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_posttransfer":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"} diff --git a/tests/data/test973 b/tests/data/test973 index 17748ea73..2961ce7c3 100644 --- a/tests/data/test973 +++ b/tests/data/test973 @@ -66,6 +66,9 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER -L -u joe:secret # # Verify data after the test has been "shot" + +QUIT + GET /%TESTNUMBER HTTP/1.1 Host: %HOSTIP:%HTTPPORT diff --git a/tests/data/test975 b/tests/data/test975 index 33f2559c6..ea4405263 100644 --- a/tests/data/test975 +++ b/tests/data/test975 @@ -66,6 +66,9 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER --location-trusted -u joe:secret # # Verify data after the test has been "shot" + +QUIT + GET /%TESTNUMBER HTTP/1.1 Host: %HOSTIP:%HTTPPORT diff --git a/tests/data/test994 b/tests/data/test994 new file mode 100644 index 000000000..e19d8c010 --- /dev/null +++ b/tests/data/test994 @@ -0,0 +1,42 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + + +# +# Client-side + + +http + + +--skip-existing with globbing + + +-o "%LOGDIR/#1" "http://%HOSTIP:%HTTPPORT/%TESTNUMBER/{hey,ho}" --skip-existing + + +content + + +content + + + +# +# Verify data after the test has been "shot" + + +Note: skips transfer, "%LOGDIR/hey" exists locally +Note: skips transfer, "%LOGDIR/ho" exists locally + + + diff --git a/tests/data/test995 b/tests/data/test995 new file mode 100644 index 000000000..f2ec85ea7 --- /dev/null +++ b/tests/data/test995 @@ -0,0 +1,56 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +--skip-existing without file present + + +-o %LOGDIR/there http://%HOSTIP:%HTTPPORT/%TESTNUMBER --skip-existing + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +-foo- + + + diff --git a/tests/data/test996 b/tests/data/test996 new file mode 100644 index 000000000..7c5e63901 --- /dev/null +++ b/tests/data/test996 @@ -0,0 +1,41 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + + +# +# Client-side + + +http + + +--skip-existing with file present + + +-o %LOGDIR/there http://%HOSTIP:%HTTPPORT/%TESTNUMBER --skip-existing + + +content + + + +# +# Verify data after the test has been "shot" + + +Note: skips transfer, "%LOGDIR/there" exists locally + + +content + + + diff --git a/tests/data/test997 b/tests/data/test997 new file mode 100644 index 000000000..2883330f8 --- /dev/null +++ b/tests/data/test997 @@ -0,0 +1,47 @@ + + + +POP3 +Clear Text +STAT +CUSTOMREQUEST +RFC2449 + + + +# +# Server-side + + +CAPA TOP USER + + + + + +# +# Client-side + + +pop3 + + +POP3 retrieve STAT (CUSTOMREQUEST) + + +pop3://%HOSTIP:%POP3PORT -u user:secret -X 'STAT' + + + +# +# Verify data after the test has been "shot" + + +CAPA +USER user +PASS secret +STAT +QUIT + + + diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl index 0b552e074..de3436b96 100755 --- a/tests/ftpserver.pl +++ b/tests/ftpserver.pl @@ -226,7 +226,7 @@ sub ftpmsg { # use this, open->print->close system only to make the file # open as little as possible, to make the test suite run - # better on windows/cygwin + # better on Windows/Cygwin } #********************************************************************** diff --git a/tests/getpart.pm b/tests/getpart.pm index ed60feca5..afc1f0621 100644 --- a/tests/getpart.pm +++ b/tests/getpart.pm @@ -316,7 +316,7 @@ sub compareparts { # NOTE: this no longer strips off carriage returns from the arrays. Is that # really necessary? It ruins the testing of newlines. I believe it was once - # added to enable tests on win32. + # added to enable tests on Windows. if($first ne $second) { return 1; @@ -332,7 +332,7 @@ sub writearray { my ($filename, $arrayref)=@_; open(my $temp, ">", "$filename") || die "Failure writing file"; - binmode($temp,":raw"); # cygwin fix by Kevin Roth + binmode($temp,":raw"); # Cygwin fix by Kevin Roth for(@$arrayref) { print $temp $_; } diff --git a/tests/http/CMakeLists.txt b/tests/http/CMakeLists.txt new file mode 100644 index 000000000..aeedad094 --- /dev/null +++ b/tests/http/CMakeLists.txt @@ -0,0 +1,62 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +find_program(CADDY "caddy") # /usr/bin/caddy +if(NOT CADDY) + set(CADDY "") +endif() +mark_as_advanced(CADDY) + +find_program(VSFTPD "vsftpd") # /usr/sbin/vsftpd +if(NOT VSFTPD) + set(VSFTPD "") +endif() +mark_as_advanced(VSFTPD) + +find_program(HTTPD "apache2") # /usr/sbin/apache2 +if(NOT HTTPD) + set(HTTPD "") +endif() +mark_as_advanced(HTTPD) + +find_program(APACHECTL "apache2ctl") # /usr/sbin/apache2ctl +if(NOT APACHECTL) + set(APACHECTL "") +endif() +mark_as_advanced(APACHECTL) + +find_program(APXS "apxs") +if(NOT APXS) + set(APXS "") +endif() +mark_as_advanced(APXS) + +find_program(HTTPD_NGHTTPX "nghttpx" PATHS "/usr/bin" "/usr/local/bin") +if(NOT HTTPD_NGHTTPX) + set(HTTPD_NGHTTPX "") +endif() +mark_as_advanced(HTTPD_NGHTTPX) + +# Consumed variables: APACHECTL, APXS, CADDY, HTTPD, HTTPD_NGHTTPX, VSFTPD +configure_file("config.ini.in" "${CMAKE_CURRENT_BINARY_DIR}/config.ini" @ONLY) diff --git a/tests/http/Makefile.am b/tests/http/Makefile.am index d9ab29686..47066f386 100644 --- a/tests/http/Makefile.am +++ b/tests/http/Makefile.am @@ -39,6 +39,7 @@ testenv/vsftpd.py \ testenv/ws_echo_server.py EXTRA_DIST = \ +CMakeLists.txt \ config.ini.in \ conftest.py \ requirements.txt \ @@ -58,7 +59,13 @@ test_12_reuse.py \ test_13_proxy_auth.py \ test_14_auth.py \ test_15_tracing.py \ +test_16_info.py \ +test_17_ssl_use.py \ +test_18_methods.py \ +test_19_shutdown.py \ test_20_websockets.py \ +test_30_vsftpd.py \ +test_31_vsftpds.py \ $(TESTENV) clean-local: diff --git a/tests/http/Makefile.in b/tests/http/Makefile.in index 0bdf7f07c..32433fefb 100644 --- a/tests/http/Makefile.in +++ b/tests/http/Makefile.in @@ -247,11 +247,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -297,7 +297,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -313,8 +312,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -347,10 +348,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -361,6 +360,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -369,6 +369,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -468,6 +469,7 @@ testenv/vsftpd.py \ testenv/ws_echo_server.py EXTRA_DIST = \ +CMakeLists.txt \ config.ini.in \ conftest.py \ requirements.txt \ @@ -487,7 +489,13 @@ test_12_reuse.py \ test_13_proxy_auth.py \ test_14_auth.py \ test_15_tracing.py \ +test_16_info.py \ +test_17_ssl_use.py \ +test_18_methods.py \ +test_19_shutdown.py \ test_20_websockets.py \ +test_30_vsftpd.py \ +test_31_vsftpds.py \ $(TESTENV) all: all-recursive diff --git a/tests/http/README.md b/tests/http/README.md index a5282adfa..7a0dc187a 100644 --- a/tests/http/README.md +++ b/tests/http/README.md @@ -13,7 +13,7 @@ This is an additional test suite using a combination of Apache httpd and nghttpx The test cases and necessary files are in `tests/http`. You can invoke `pytest` from there or from the top level curl checkout and it will find all tests. ``` -curl> pytest +curl> pytest test/http platform darwin -- Python 3.9.15, pytest-6.2.0, py-1.10.0, pluggy-0.13.1 rootdir: /Users/sei/projects/curl collected 5 items @@ -24,7 +24,7 @@ tests/http/test_01_basic.py ..... Pytest takes arguments. `-v` increases its verbosity and can be used several times. `-k ` can be used to run only matching test cases. The `expr` can be something resembling a python test or just a string that needs to match test cases in their names. ``` -curl> pytest -vv -k test_01_02 +curl/tests/http> pytest -vv -k test_01_02 ``` runs all test cases that have `test_01_02` in their name. This does not have to be the start of the name. @@ -54,10 +54,10 @@ Via curl's `configure` script you may specify: Several test cases are parameterized, for example with the HTTP version to use. If you want to run a test with a particular protocol only, use a command line like: ``` -curl> pytest -k "test_02_06 and h2" +curl/tests/http> pytest -k "test_02_06 and h2" ``` -Several test cases can be repeated, they all have the `repeat` parameter (install `pytest-repeat` module). To make this work, you have to start `pytest` in the test directory itself (for some unknown reason). Like in: +Test cases can be repeated, with the `pytest-repeat` module (`pip install pytest-repeat`). Like in: ``` curl/tests/http> pytest -k "test_02_06 and h2" --count=100 diff --git a/tests/http/clients/CMakeLists.txt b/tests/http/clients/CMakeLists.txt new file mode 100644 index 000000000..44af35ed3 --- /dev/null +++ b/tests/http/clients/CMakeLists.txt @@ -0,0 +1,45 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +# Get 'check_PROGRAMS' variable +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +foreach(_target IN LISTS check_PROGRAMS) + set(_target_name "curlt-client-${_target}") + add_executable(${_target_name} EXCLUDE_FROM_ALL "${_target}.c") + add_dependencies(testdeps ${_target_name}) + target_include_directories(${_target_name} PRIVATE + "${CURL_BINARY_DIR}/lib" # for "curl_config.h" + "${CURL_SOURCE_DIR}/lib" # for "curl_setup.h" + ) + target_link_libraries(${_target_name} ${LIB_SELECTED} ${CURL_LIBS}) + target_compile_definitions(${_target_name} PRIVATE "CURL_NO_OLDIES") + if(LIB_SELECTED STREQUAL LIB_STATIC AND WIN32) + set_property(TARGET ${_target_name} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") + endif() + set_target_properties(${_target_name} PROPERTIES + OUTPUT_NAME "${_target}" UNITY_BUILD OFF + PROJECT_LABEL "Test client ${_target}") +endforeach() diff --git a/tests/http/clients/Makefile.am b/tests/http/clients/Makefile.am index 8fdc190b9..007de3c87 100644 --- a/tests/http/clients/Makefile.am +++ b/tests/http/clients/Makefile.am @@ -24,6 +24,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc +EXTRA_DIST = CMakeLists.txt # Specify our include paths here, and do it relative to $(top_srcdir) and # $(top_builddir), to ensure that these paths which belong to the library @@ -50,16 +51,12 @@ endif LIBS = $(BLANK_AT_MAKETIME) # Dependencies -if USE_EXPLICIT_LIB_DEPS -LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@ -else -LDADD = $(LIBDIR)/libcurl.la -endif +LDADD = $(LIBDIR)/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # This might hold -Werror CFLAGS += @CURL_CFLAG_EXTRAS@ -# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines +# Makefile.inc provides the check_PROGRAMS define include Makefile.inc all: $(check_PROGRAMS) diff --git a/tests/http/clients/Makefile.in b/tests/http/clients/Makefile.in index 9eb45a0ba..8272fdf7b 100644 --- a/tests/http/clients/Makefile.in +++ b/tests/http/clients/Makefile.in @@ -136,10 +136,10 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_1 = -DCURL_STATICLIB -check_PROGRAMS = h2-serverpush$(EXEEXT) h2-download$(EXEEXT) \ - ws-data$(EXEEXT) ws-pingpong$(EXEEXT) \ - h2-upgrade-extreme$(EXEEXT) tls-session-reuse$(EXEEXT) \ - h2-pausing$(EXEEXT) upload-pausing$(EXEEXT) +check_PROGRAMS = h2-download$(EXEEXT) h2-pausing$(EXEEXT) \ + h2-serverpush$(EXEEXT) h2-upgrade-extreme$(EXEEXT) \ + tls-session-reuse$(EXEEXT) upload-pausing$(EXEEXT) \ + ws-data$(EXEEXT) ws-pingpong$(EXEEXT) subdir = tests/http/clients ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/curl-amissl.m4 \ @@ -177,10 +177,7 @@ CONFIG_CLEAN_VPATH_FILES = h2_download_SOURCES = h2-download.c h2_download_OBJECTS = h2-download.$(OBJEXT) h2_download_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@h2_download_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@h2_download_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +h2_download_DEPENDENCIES = $(LIBDIR)/libcurl.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -188,52 +185,31 @@ am__v_lt_1 = h2_pausing_SOURCES = h2-pausing.c h2_pausing_OBJECTS = h2-pausing.$(OBJEXT) h2_pausing_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@h2_pausing_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@h2_pausing_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +h2_pausing_DEPENDENCIES = $(LIBDIR)/libcurl.la h2_serverpush_SOURCES = h2-serverpush.c h2_serverpush_OBJECTS = h2-serverpush.$(OBJEXT) h2_serverpush_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@h2_serverpush_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@h2_serverpush_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +h2_serverpush_DEPENDENCIES = $(LIBDIR)/libcurl.la h2_upgrade_extreme_SOURCES = h2-upgrade-extreme.c h2_upgrade_extreme_OBJECTS = h2-upgrade-extreme.$(OBJEXT) h2_upgrade_extreme_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@h2_upgrade_extreme_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@h2_upgrade_extreme_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +h2_upgrade_extreme_DEPENDENCIES = $(LIBDIR)/libcurl.la tls_session_reuse_SOURCES = tls-session-reuse.c tls_session_reuse_OBJECTS = tls-session-reuse.$(OBJEXT) tls_session_reuse_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@tls_session_reuse_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@tls_session_reuse_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +tls_session_reuse_DEPENDENCIES = $(LIBDIR)/libcurl.la upload_pausing_SOURCES = upload-pausing.c upload_pausing_OBJECTS = upload-pausing.$(OBJEXT) upload_pausing_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@upload_pausing_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@upload_pausing_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +upload_pausing_DEPENDENCIES = $(LIBDIR)/libcurl.la ws_data_SOURCES = ws-data.c ws_data_OBJECTS = ws-data.$(OBJEXT) ws_data_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ws_data_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ws_data_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ws_data_DEPENDENCIES = $(LIBDIR)/libcurl.la ws_pingpong_SOURCES = ws-pingpong.c ws_pingpong_OBJECTS = ws-pingpong.$(OBJEXT) ws_pingpong_LDADD = $(LDADD) -@USE_EXPLICIT_LIB_DEPS_FALSE@ws_pingpong_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(LIBDIR)/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@ws_pingpong_DEPENDENCIES = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(LIBDIR)/libcurl.la +ws_pingpong_DEPENDENCIES = $(LIBDIR)/libcurl.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -327,11 +303,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -377,7 +353,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -393,8 +368,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -429,10 +406,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -443,6 +418,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -451,6 +427,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -535,6 +512,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign nostdinc +EXTRA_DIST = CMakeLists.txt # Specify our include paths here, and do it relative to $(top_srcdir) and # $(top_builddir), to ensure that these paths which belong to the library @@ -548,10 +526,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ -I$(top_srcdir)/lib -DCURL_DISABLE_DEPRECATION \ -DCURL_NO_OLDIES $(am__append_1) LIBDIR = $(top_builddir)/lib -@USE_EXPLICIT_LIB_DEPS_FALSE@LDADD = $(LIBDIR)/libcurl.la # Dependencies -@USE_EXPLICIT_LIB_DEPS_TRUE@LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@ +LDADD = $(LIBDIR)/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; CS_1 = @@ -906,7 +883,7 @@ uninstall-am: .PRECIOUS: Makefile -# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines +# Makefile.inc provides the check_PROGRAMS define all: $(check_PROGRAMS) diff --git a/tests/http/clients/Makefile.inc b/tests/http/clients/Makefile.inc index 07b6ae4aa..e2ab2143b 100644 --- a/tests/http/clients/Makefile.inc +++ b/tests/http/clients/Makefile.inc @@ -24,11 +24,11 @@ # These are all libcurl example programs to be test compiled check_PROGRAMS = \ - h2-serverpush \ h2-download \ - ws-data \ - ws-pingpong \ + h2-pausing \ + h2-serverpush \ h2-upgrade-extreme \ tls-session-reuse \ - h2-pausing \ - upload-pausing + upload-pausing \ + ws-data \ + ws-pingpong diff --git a/tests/http/clients/h2-download.c b/tests/http/clients/h2-download.c index 719839889..505a3864a 100644 --- a/tests/http/clients/h2-download.c +++ b/tests/http/clients/h2-download.c @@ -25,23 +25,23 @@ * HTTP/2 server push * */ - /* curl stuff */ #include -#include #include #include #include -/* somewhat unix-specific */ -#include -#include +#ifndef _MSC_VER +/* somewhat Unix-specific */ +#include /* getopt() */ +#endif #ifndef CURLPIPE_MULTIPLEX #error "too old libcurl, cannot do HTTP/2 server push!" #endif +#ifndef _MSC_VER static int verbose = 1; static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) @@ -80,9 +80,9 @@ static int debug_cb(CURL *handle, curl_infotype type, if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && - conn_id >= 0) { - curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, - xfer_id, conn_id); + conn_id >= 0) { + curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, + conn_id); } else { curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); @@ -272,12 +272,14 @@ static void usage(const char *msg) " -V http_version (http/1.1, h2, h3) http version to use\n" ); } +#endif /* !_MSC_VER */ /* * Download a file over HTTP/2, take care of server push. */ int main(int argc, char *argv[]) { +#ifndef _MSC_VER CURLM *multi_handle; struct CURLMsg *m; const char *url; @@ -477,4 +479,10 @@ int main(int argc, char *argv[]) curl_multi_cleanup(multi_handle); return 0; +#else + (void)argc; + (void)argv; + fprintf(stderr, "Not supported with this compiler.\n"); + return 1; +#endif /* !_MSC_VER */ } diff --git a/tests/http/clients/h2-pausing.c b/tests/http/clients/h2-pausing.c index c12e8fab0..8281f4ded 100644 --- a/tests/http/clients/h2-pausing.c +++ b/tests/http/clients/h2-pausing.c @@ -25,17 +25,21 @@ * HTTP/2 download pausing * */ -/* This is based on the poc client of issue #11982 +/* This is based on the PoC client of issue #11982 */ +#include + #include #include #include -#include -#include #include -#include -#include +#ifndef _MSC_VER +/* somewhat Unix-specific */ +#include /* getopt() */ +#endif + +#ifndef _MSC_VER #define HANDLECOUNT 2 static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) @@ -75,8 +79,8 @@ static int debug_cb(CURL *handle, curl_infotype type, if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && conn_id >= 0) { - curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, - xfer_id, conn_id); + curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, + conn_id); } else { curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); @@ -192,9 +196,11 @@ static size_t cb(void *data, size_t size, size_t nmemb, void *clientp) handle->idx, (long)realsize); return realsize; } +#endif /* !_MSC_VER */ int main(int argc, char *argv[]) { +#ifndef _MSC_VER struct handle handles[HANDLECOUNT]; CURLM *multi_handle; int i, still_running = 1, msgs_left, numfds; @@ -263,8 +269,8 @@ int main(int argc, char *argv[]) exit(1); } memset(&resolve, 0, sizeof(resolve)); - curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, - "%s:%s:127.0.0.1", host, port); + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); resolve = curl_slist_append(resolve, resolve_buf); for(i = 0; imsg == CURLMSG_DONE) { for(i = 0; ieasy_handle == handles[i].h) { @@ -394,4 +401,10 @@ int main(int argc, char *argv[]) curl_global_cleanup(); return rc; +#else + (void)argc; + (void)argv; + fprintf(stderr, "Not supported with this compiler.\n"); + return 1; +#endif /* !_MSC_VER */ } diff --git a/tests/http/clients/h2-serverpush.c b/tests/http/clients/h2-serverpush.c index 13f804aa2..9f54d6acd 100644 --- a/tests/http/clients/h2-serverpush.c +++ b/tests/http/clients/h2-serverpush.c @@ -25,19 +25,13 @@ * HTTP/2 server push * */ - /* curl stuff */ #include -#include #include #include #include -/* somewhat unix-specific */ -#include -#include - #ifndef CURLPIPE_MULTIPLEX #error "too old libcurl, cannot do HTTP/2 server push!" #endif diff --git a/tests/http/clients/h2-upgrade-extreme.c b/tests/http/clients/h2-upgrade-extreme.c index e15e34ce0..e6e39c170 100644 --- a/tests/http/clients/h2-upgrade-extreme.c +++ b/tests/http/clients/h2-upgrade-extreme.c @@ -25,15 +25,12 @@ * HTTP/2 Upgrade test * */ +#include + #include #include -#include -#include /* #include */ #include -#include -#include - static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) { @@ -72,8 +69,8 @@ static int debug_cb(CURL *handle, curl_infotype type, if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && conn_id >= 0) { - curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, - xfer_id, conn_id); + curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, + conn_id); } else { curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); @@ -181,8 +178,11 @@ int main(int argc, char *argv[]) curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(easy, CURLOPT_WRITEDATA, NULL); curl_easy_setopt(easy, CURLOPT_HTTPGET, 1L); - curl_msnprintf(range, sizeof(range), "%" PRIu64 "-%" PRIu64, - UINT64_C(0), UINT64_C(16384)); + curl_msnprintf(range, sizeof(range), + "%" CURL_FORMAT_CURL_OFF_TU "-" + "%" CURL_FORMAT_CURL_OFF_TU, + (curl_off_t)0, + (curl_off_t)16384); curl_easy_setopt(easy, CURLOPT_RANGE, range); mc = curl_multi_add_handle(multi, easy); @@ -211,7 +211,8 @@ int main(int argc, char *argv[]) } /* Check for finished handles and remove. */ - while((msg = curl_multi_info_read(multi, &msgs_in_queue))) { + /* !checksrc! disable EQUALSNULL 1 */ + while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) { if(msg->msg == CURLMSG_DONE) { long status = 0; curl_off_t xfer_id; diff --git a/tests/http/clients/tls-session-reuse.c b/tests/http/clients/tls-session-reuse.c index 2750ba777..8e8d63559 100644 --- a/tests/http/clients/tls-session-reuse.c +++ b/tests/http/clients/tls-session-reuse.c @@ -25,16 +25,13 @@ * TLS session reuse * */ +#include + #include #include -#include #include -#include /* #include */ #include -#include -#include - static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) { @@ -73,8 +70,8 @@ static int debug_cb(CURL *handle, curl_infotype type, if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && conn_id >= 0) { - curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, - xfer_id, conn_id); + curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, + conn_id); } else { curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); @@ -222,9 +219,9 @@ int main(int argc, char *argv[]) exit(1); } - memset(&resolve, 0, sizeof(resolve)); - curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, - "%s:%s:127.0.0.1", host, port); + memset(&resolve, 0, sizeof(resolve)); + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); curl_slist_append(&resolve, resolve_buf); multi = curl_multi_init(); @@ -274,7 +271,8 @@ int main(int argc, char *argv[]) } /* Check for finished handles and remove. */ - while((msg = curl_multi_info_read(multi, &msgs_in_queue))) { + /* !checksrc! disable EQUALSNULL 1 */ + while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) { if(msg->msg == CURLMSG_DONE) { long status = 0; curl_off_t xfer_id; diff --git a/tests/http/clients/upload-pausing.c b/tests/http/clients/upload-pausing.c index f5b1b4014..272d4157f 100644 --- a/tests/http/clients/upload-pausing.c +++ b/tests/http/clients/upload-pausing.c @@ -25,16 +25,20 @@ * upload pausing * */ -/* This is based on the poc client of issue #11769 +/* This is based on the PoC client of issue #11769 */ +#include + #include #include -#include -#include #include -#include -#include +#ifndef _MSC_VER +/* somewhat Unix-specific */ +#include /* getopt() */ +#endif + +#ifndef _MSC_VER static void log_line_start(FILE *log, const char *idsbuf, curl_infotype type) { /* @@ -72,8 +76,8 @@ static int debug_cb(CURL *handle, curl_infotype type, if(!curl_easy_getinfo(handle, CURLINFO_XFER_ID, &xfer_id) && xfer_id >= 0) { if(!curl_easy_getinfo(handle, CURLINFO_CONN_ID, &conn_id) && conn_id >= 0) { - curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, - xfer_id, conn_id); + curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_2, xfer_id, + conn_id); } else { curl_msnprintf(idsbuf, sizeof(idsbuf), TRC_IDS_FORMAT_IDS_1, xfer_id); @@ -182,22 +186,58 @@ static int err(void) exit(2); } - +static void usage(const char *msg) +{ + if(msg) + fprintf(stderr, "%s\n", msg); + fprintf(stderr, + "usage: [options] url\n" + " upload and pause, options:\n" + " -V http_version (http/1.1, h2, h3) http version to use\n" + ); +} +#endif /* !_MSC_VER */ int main(int argc, char *argv[]) { +#ifndef _MSC_VER CURL *curl; CURLcode rc = CURLE_OK; CURLU *cu; struct curl_slist *resolve = NULL; char resolve_buf[1024]; char *url, *host = NULL, *port = NULL; + int http_version = CURL_HTTP_VERSION_1_1; + int ch; - if(argc != 2) { - fprintf(stderr, "ERROR: need URL as argument\n"); + while((ch = getopt(argc, argv, "V:")) != -1) { + switch(ch) { + case 'V': { + if(!strcmp("http/1.1", optarg)) + http_version = CURL_HTTP_VERSION_1_1; + else if(!strcmp("h2", optarg)) + http_version = CURL_HTTP_VERSION_2_0; + else if(!strcmp("h3", optarg)) + http_version = CURL_HTTP_VERSION_3ONLY; + else { + usage("invalid http version"); + return 1; + } + break; + } + default: + usage("invalid option"); + return 1; + } + } + argc -= optind; + argv += optind; + + if(argc != 1) { + usage("not enough arguments"); return 2; } - url = argv[1]; + url = argv[0]; curl_global_init(CURL_GLOBAL_DEFAULT); curl_global_trace("ids,time"); @@ -220,8 +260,8 @@ int main(int argc, char *argv[]) exit(1); } memset(&resolve, 0, sizeof(resolve)); - curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, - "%s:%s:127.0.0.1", host, port); + curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", + host, port); resolve = curl_slist_append(resolve, resolve_buf); curl = curl_easy_init(); @@ -247,6 +287,9 @@ int main(int argc, char *argv[]) curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + if(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) != CURLE_OK || curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_cb) != CURLE_OK || @@ -254,6 +297,8 @@ int main(int argc, char *argv[]) err(); curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version); + rc = curl_easy_perform(curl); if(curl) { @@ -267,4 +312,10 @@ int main(int argc, char *argv[]) curl_global_cleanup(); return (int)rc; +#else + (void)argc; + (void)argv; + fprintf(stderr, "Not supported with this compiler.\n"); + return 1; +#endif /* !_MSC_VER */ } diff --git a/tests/http/clients/ws-data.c b/tests/http/clients/ws-data.c index e7d52756e..ee067dd96 100644 --- a/tests/http/clients/ws-data.c +++ b/tests/http/clients/ws-data.c @@ -22,10 +22,9 @@ * ***************************************************************************/ /* - * Websockets data echos + * WebSockets data echos * */ - /* curl stuff */ #include "curl_setup.h" #include @@ -34,12 +33,17 @@ #include #include -/* somewhat unix-specific */ -#include -#include - #ifdef USE_WEBSOCKETS +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#endif + static void dump(const char *text, unsigned char *ptr, size_t size, char nohex) @@ -112,7 +116,11 @@ static CURLcode recv_binary(CURL *curl, char *exp_data, size_t exp_len) result = curl_ws_recv(curl, recvbuf, sizeof(recvbuf), &nread, &frame); if(result == CURLE_AGAIN) { fprintf(stderr, "EAGAIN, sleep, try again\n"); +#ifdef _WIN32 + Sleep(100); +#else usleep(100*1000); +#endif continue; } fprintf(stderr, "ws: curl_ws_recv(offset=%ld, len=%ld) -> %d, %ld\n", @@ -257,7 +265,7 @@ int main(int argc, char *argv[]) #else /* USE_WEBSOCKETS */ (void)argc; (void)argv; - fprintf(stderr, "websockets not enabled in libcurl\n"); + fprintf(stderr, "WebSockets not enabled in libcurl\n"); return 1; #endif /* !USE_WEBSOCKETS */ } diff --git a/tests/http/clients/ws-pingpong.c b/tests/http/clients/ws-pingpong.c index dc36d4548..4b57e21e8 100644 --- a/tests/http/clients/ws-pingpong.c +++ b/tests/http/clients/ws-pingpong.c @@ -22,10 +22,9 @@ * ***************************************************************************/ /* - * Websockets pingpong + * WebSockets pingpong * */ - /* curl stuff */ #include "curl_setup.h" #include @@ -34,9 +33,14 @@ #include #include -/* somewhat unix-specific */ +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else #include -#include +#endif #ifdef USE_WEBSOCKETS @@ -102,7 +106,11 @@ static CURLcode pingpong(CURL *curl, const char *payload) fprintf(stderr, "Receive pong\n"); res = recv_pong(curl, payload); if(res == CURLE_AGAIN) { +#ifdef _WIN32 + Sleep(100); +#else usleep(100*1000); +#endif continue; } websocket_close(curl); @@ -152,7 +160,7 @@ int main(int argc, char *argv[]) #else /* USE_WEBSOCKETS */ (void)argc; (void)argv; - fprintf(stderr, "websockets not enabled in libcurl\n"); + fprintf(stderr, "WebSockets not enabled in libcurl\n"); return 1; #endif /* !USE_WEBSOCKETS */ } diff --git a/tests/http/conftest.py b/tests/http/conftest.py index 3aca42e66..c5ac74544 100644 --- a/tests/http/conftest.py +++ b/tests/http/conftest.py @@ -33,6 +33,33 @@ from testenv import Env, Nghttpx, Httpd, NghttpxQuic, NghttpxFwd +def pytest_report_header(config): + # Env inits its base properties only once, we can report them here + env = Env() + report = [ + f'Testing curl {env.curl_version()}', + f' httpd: {env.httpd_version()}, http:{env.http_port} https:{env.https_port}', + f' httpd-proxy: {env.httpd_version()}, http:{env.proxy_port} https:{env.proxys_port}' + ] + if env.have_h3(): + report.extend([ + f' nghttpx: {env.nghttpx_version()}, h3:{env.https_port}' + ]) + if env.has_caddy(): + report.extend([ + f' Caddy: {env.caddy_version()}, http:{env.caddy_http_port} https:{env.caddy_https_port}' + ]) + if env.has_vsftpd(): + report.extend([ + f' VsFTPD: {env.vsftpd_version()}, ftp:{env.ftp_port}, ftps:{env.ftps_port}' + ]) + return '\n'.join(report) + +# TODO: remove this and repeat argument everywhere, pytest-repeat can be used to repeat tests +def pytest_generate_tests(metafunc): + if "repeat" in metafunc.fixturenames: + metafunc.parametrize('repeat', [0]) + @pytest.fixture(scope="package") def env(pytestconfig) -> Env: env = Env(pytestconfig=pytestconfig) diff --git a/tests/http/scorecard.py b/tests/http/scorecard.py index 4e4c2c8cb..6d0891325 100644 --- a/tests/http/scorecard.py +++ b/tests/http/scorecard.py @@ -425,21 +425,30 @@ def do_requests(self, url: str, proto: str, count: int, errors = [] profiles = [] url = f'{url}?[0-{count - 1}]' - extra_args = ['--parallel', '--parallel-max', str(max_parallel)] \ - if max_parallel > 1 else [] + extra_args = [ + '-w', '%{response_code},\\n', + ] + if max_parallel > 1: + extra_args.extend([ + '--parallel', '--parallel-max', str(max_parallel) + ]) self.info(f'{max_parallel}...') for i in range(sample_size): curl = CurlClient(env=self.env, silent=self._silent_curl) r = curl.http_download(urls=[url], alpn_proto=proto, no_save=True, with_headers=False, with_profile=True, - extra_args=extra_args) - err = self._check_downloads(r, count) - if err: - errors.append(err) + with_stats=False, extra_args=extra_args) + if r.exit_code != 0: + errors.append(f'exit={r.exit_code}') else: - for _ in r.stats: - samples.append(count / r.duration.total_seconds()) - profiles.append(r.profile) + samples.append(count / r.duration.total_seconds()) + non_200s = 0 + for l in r.stdout.splitlines(): + if not l.startswith('200,'): + non_200s += 1 + if non_200s > 0: + errors.append(f'responses != 200: {non_200s}') + profiles.append(r.profile) return { 'count': count, 'samples': sample_size, @@ -450,17 +459,11 @@ def do_requests(self, url: str, proto: str, count: int, def requests_url(self, url: str, proto: str, count: int): self.info(f' {url}: ') - props = { - '1': self.do_requests(url=url, proto=proto, count=count), - '6': self.do_requests(url=url, proto=proto, count=count, - max_parallel=6), - '25': self.do_requests(url=url, proto=proto, count=count, - max_parallel=25), - '50': self.do_requests(url=url, proto=proto, count=count, - max_parallel=50), - '100': self.do_requests(url=url, proto=proto, count=count, - max_parallel=100), - } + props = {} + # 300 is max in curl, see tool_main.h + for m in [1, 6, 25, 50, 100, 300]: + props[str(m)] = self.do_requests(url=url, proto=proto, count=count, + max_parallel=m) self.info(f'ok.\n') return props diff --git a/tests/http/test_01_basic.py b/tests/http/test_01_basic.py index 54e7dd4a7..e2320f10c 100644 --- a/tests/http/test_01_basic.py +++ b/tests/http/test_01_basic.py @@ -94,6 +94,48 @@ def test_01_06_timings(self, env: Env, httpd, nghttpx, repeat, proto): curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/data.json' r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True) - r.check_stats(http_status=200, count=1) + r.check_stats(http_status=200, count=1, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') assert r.stats[0]['time_connect'] > 0, f'{r.stats[0]}' assert r.stats[0]['time_appconnect'] > 0, f'{r.stats[0]}' + + # simple https: HEAD + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") + def test_01_07_head(self, env: Env, httpd, nghttpx, repeat, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json' + r = curl.http_download(urls=[url], with_stats=True, with_headers=True, + extra_args=['-I']) + r.check_stats(http_status=200, count=1, exitcode=0, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') + # got the Conten-Length: header, but did not download anything + assert r.responses[0]['header']['content-length'] == '30', f'{r.responses[0]}' + assert r.stats[0]['size_download'] == 0, f'{r.stats[0]}' + + # http: GET for HTTP/2, see Upgrade:, 101 switch + def test_01_08_h2_upgrade(self, env: Env, httpd): + curl = CurlClient(env=env) + url = f'http://{env.domain1}:{env.http_port}/data.json' + r = curl.http_get(url=url, extra_args=['--http2']) + r.check_exit_code(0) + assert len(r.responses) == 2, f'{r.responses}' + assert r.responses[0]['status'] == 101, f'{r.responses[0]}' + assert r.responses[1]['status'] == 200, f'{r.responses[1]}' + assert r.responses[1]['protocol'] == 'HTTP/2', f'{r.responses[1]}' + assert r.json['server'] == env.domain1 + + # http: GET for HTTP/2 with prior knowledge + def test_01_09_h2_prior_knowledge(self, env: Env, httpd): + curl = CurlClient(env=env) + url = f'http://{env.domain1}:{env.http_port}/data.json' + r = curl.http_get(url=url, extra_args=['--http2-prior-knowledge']) + r.check_exit_code(0) + assert len(r.responses) == 1, f'{r.responses}' + assert r.response['status'] == 200, f'{r.responsw}' + assert r.response['protocol'] == 'HTTP/2', f'{r.response}' + assert r.json['server'] == env.domain1 diff --git a/tests/http/test_02_download.py b/tests/http/test_02_download.py index ff6a0bd14..c678e0588 100644 --- a/tests/http/test_02_download.py +++ b/tests/http/test_02_download.py @@ -27,6 +27,7 @@ import difflib import filecmp import logging +import math import os from datetime import timedelta import pytest @@ -77,28 +78,30 @@ def test_02_02_download_2(self, env: Env, httpd, nghttpx, repeat, proto): # download 100 files sequentially @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) - def test_02_03_download_100_sequential(self, env: Env, - httpd, nghttpx, repeat, proto): + def test_02_03_download_sequential(self, env: Env, + httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") + count = 10 curl = CurlClient(env=env) - urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-99]' + urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]' r = curl.http_download(urls=[urln], alpn_proto=proto) - r.check_response(http_status=200, count=100, connect_count=1) + r.check_response(http_status=200, count=count, connect_count=1) # download 100 files parallel - @pytest.mark.parametrize("proto", ['h2', 'h3']) - def test_02_04_download_100_parallel(self, env: Env, - httpd, nghttpx, repeat, proto): + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_02_04_download_parallel(self, env: Env, + httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - max_parallel = 50 + count = 10 + max_parallel = 5 curl = CurlClient(env=env) - urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-99]' + urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]' r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ '--parallel', '--parallel-max', f'{max_parallel}' ]) - r.check_response(http_status=200, count=100) + r.check_response(http_status=200, count=count) if proto == 'http/1.1': # http/1.1 parallel transfers will open multiple connections assert r.total_connects > 1, r.dump_logs() @@ -182,7 +185,7 @@ def test_02_08_1MB_serial(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 20 + count = 5 urln = f'https://{env.authority_for(env.domain1, proto)}/data-1m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto) @@ -193,7 +196,7 @@ def test_02_09_1MB_parallel(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 20 + count = 5 urln = f'https://{env.authority_for(env.domain1, proto)}/data-1m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -208,7 +211,7 @@ def test_02_10_10MB_serial(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 10 + count = 3 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto) @@ -223,7 +226,7 @@ def test_02_11_10MB_parallel(self, env: Env, pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") - count = 10 + count = 3 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -236,7 +239,7 @@ def test_02_12_head_serial_https(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 50 + count = 5 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -249,7 +252,7 @@ def test_02_13_head_serial_h2c(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 50 + count = 5 urln = f'http://{env.domain1}:{env.http_port}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -263,13 +266,15 @@ def test_02_14_not_found(self, env: Env, httpd, nghttpx, repeat, proto): pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") - count = 10 + count = 5 urln = f'https://{env.authority_for(env.domain1, proto)}/not-found?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ '--parallel' ]) - r.check_stats(count=count, http_status=404, exitcode=0) + r.check_stats(count=count, http_status=404, exitcode=0, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') @pytest.mark.parametrize("proto", ['h2', 'h3']) def test_02_15_fail_not_found(self, env: Env, httpd, nghttpx, repeat, proto): @@ -277,13 +282,15 @@ def test_02_15_fail_not_found(self, env: Env, httpd, nghttpx, repeat, proto): pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") - count = 10 + count = 5 urln = f'https://{env.authority_for(env.domain1, proto)}/not-found?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ '--fail' ]) - r.check_stats(count=count, http_status=404, exitcode=22) + r.check_stats(count=count, http_status=404, exitcode=22, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') @pytest.mark.skipif(condition=Env().slow_network, reason="not suitable for slow network tests") @pytest.mark.skipif(condition=Env().ci_run, reason="not suitable for CI runs") @@ -305,7 +312,7 @@ def test_02_20_h2_small_frames(self, env: Env, httpd, repeat): # ok, make 100 downloads with 2 parallel running and they # are expected to stumble into the issue when using `lib/http2.c` # from curl 7.88.0 - count = 100 + count = 5 urln = f'https://{env.authority_for(env.domain1, "h2")}/data-1m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto="h2", extra_args=[ @@ -325,7 +332,7 @@ def test_02_20_h2_small_frames(self, env: Env, httpd, repeat): def test_02_21_lib_serial(self, env: Env, httpd, nghttpx, proto, pause_offset, repeat): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 2 if proto == 'http/1.1' else 10 + count = 2 docname = 'data-10m' url = f'https://localhost:{env.https_port}/{docname}' client = LocalClient(name='h2-download', env=env) @@ -344,7 +351,7 @@ def test_02_21_lib_serial(self, env: Env, httpd, nghttpx, proto, pause_offset, r def test_02_22_lib_parallel_resume(self, env: Env, httpd, nghttpx, proto, pause_offset, repeat): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 2 if proto == 'http/1.1' else 10 + count = 2 max_parallel = 5 docname = 'data-10m' url = f'https://localhost:{env.https_port}/{docname}' @@ -368,13 +375,11 @@ def test_02_23a_lib_abort_paused(self, env: Env, httpd, nghttpx, proto, repeat): pytest.skip('OpenSSL QUIC fails here') if proto == 'h3' and env.ci_run and env.curl_uses_lib('quiche'): pytest.skip("fails in CI, but works locally for unknown reasons") + count = 10 + max_parallel = 5 if proto in ['h2', 'h3']: - count = 200 - max_parallel = 100 pause_offset = 64 * 1024 else: - count = 10 - max_parallel = 5 pause_offset = 12 * 1024 docname = 'data-1m' url = f'https://localhost:{env.https_port}/{docname}' @@ -399,13 +404,11 @@ def test_02_23b_lib_abort_offset(self, env: Env, httpd, nghttpx, proto, repeat): pytest.skip('OpenSSL QUIC fails here') if proto == 'h3' and env.ci_run and env.curl_uses_lib('quiche'): pytest.skip("fails in CI, but works locally for unknown reasons") + count = 10 + max_parallel = 5 if proto in ['h2', 'h3']: - count = 200 - max_parallel = 100 abort_offset = 64 * 1024 else: - count = 10 - max_parallel = 5 abort_offset = 12 * 1024 docname = 'data-1m' url = f'https://localhost:{env.https_port}/{docname}' @@ -430,13 +433,11 @@ def test_02_23c_lib_fail_offset(self, env: Env, httpd, nghttpx, proto, repeat): pytest.skip('OpenSSL QUIC fails here') if proto == 'h3' and env.ci_run and env.curl_uses_lib('quiche'): pytest.skip("fails in CI, but works locally for unknown reasons") + count = 10 + max_parallel = 5 if proto in ['h2', 'h3']: - count = 200 - max_parallel = 100 fail_offset = 64 * 1024 else: - count = 10 - max_parallel = 5 fail_offset = 12 * 1024 docname = 'data-1m' url = f'https://localhost:{env.https_port}/{docname}' @@ -453,19 +454,22 @@ def test_02_23c_lib_fail_offset(self, env: Env, httpd, nghttpx, proto, repeat): self.check_downloads(client, srcfile, count, complete=False) # speed limited download - @pytest.mark.parametrize("proto", ['h2', 'h3']) + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) def test_02_24_speed_limit(self, env: Env, httpd, nghttpx, proto, repeat): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") count = 1 url = f'https://{env.authority_for(env.domain1, proto)}/data-1m' curl = CurlClient(env=env) + speed_limit = 384 * 1024 + min_duration = math.floor((1024 * 1024)/speed_limit) r = curl.http_download(urls=[url], alpn_proto=proto, extra_args=[ - '--limit-rate', f'{196 * 1024}' + '--limit-rate', f'{speed_limit}' ]) r.check_response(count=count, http_status=200) - assert r.duration > timedelta(seconds=4), \ - f'rate limited transfer should take more than 4s, not {r.duration}' + assert r.duration > timedelta(seconds=min_duration), \ + f'rate limited transfer should take more than {min_duration}s, '\ + f'not {r.duration}' # make extreme parallel h2 upgrades, check invalid conn reuse # before protocol switch has happened @@ -551,7 +555,7 @@ def check_downloads(self, client, srcfile: str, count: int, @pytest.mark.parametrize("pause_offset", [0, 10*1024, 100*1023, 640000]) @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) def test_02_29_h2_lib_serial(self, env: Env, httpd, nghttpx, proto, pause_offset, repeat): - count = 2 if proto == 'http/1.1' else 10 + count = 2 docname = 'data-10m' url = f'https://localhost:{env.https_port}/{docname}' client = LocalClient(name='h2-download', env=env) @@ -563,3 +567,27 @@ def test_02_29_h2_lib_serial(self, env: Env, httpd, nghttpx, proto, pause_offset r.check_exit_code(0) srcfile = os.path.join(httpd.docs_dir, docname) self.check_downloads(client, srcfile, count) + + # download parallel with prior knowledge + def test_02_30_parallel_prior_knowledge(self, env: Env, httpd): + count = 3 + curl = CurlClient(env=env) + urln = f'http://{env.domain1}:{env.http_port}/data.json?[0-{count-1}]' + r = curl.http_download(urls=[urln], extra_args=[ + '--parallel', '--http2-prior-knowledge' + ]) + r.check_response(http_status=200, count=count) + assert r.total_connects == 1, r.dump_logs() + + # download parallel with h2 "Upgrade:" + def test_02_31_parallel_upgrade(self, env: Env, httpd): + count = 3 + curl = CurlClient(env=env) + urln = f'http://{env.domain1}:{env.http_port}/data.json?[0-{count-1}]' + r = curl.http_download(urls=[urln], extra_args=[ + '--parallel', '--http2' + ]) + r.check_response(http_status=200, count=count) + # we see 3 connections, because Apache only every serves a single + # request via Upgrade: and then closed the connection. + assert r.total_connects == 3, r.dump_logs() diff --git a/tests/http/test_07_upload.py b/tests/http/test_07_upload.py index 95703d352..8dc06d45d 100644 --- a/tests/http/test_07_upload.py +++ b/tests/http/test_07_upload.py @@ -89,7 +89,7 @@ def test_07_10_upload_sequential(self, env: Env, httpd, nghttpx, repeat, proto): pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") - count = 50 + count = 20 data = '0123456789' curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' @@ -107,7 +107,7 @@ def test_07_11_upload_parallel(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") # limit since we use a separate connection in h1 - count = 50 + count = 20 data = '0123456789' curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' @@ -126,7 +126,7 @@ def test_07_12_upload_seq_large(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") fdata = os.path.join(env.gen_dir, 'data-100k') - count = 20 + count = 10 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto) @@ -163,7 +163,7 @@ def test_07_20_upload_parallel(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") # limit since we use a separate connection in h1 - count = 20 + count = 10 data = '0123456789' curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' @@ -183,7 +183,7 @@ def test_07_21_upload_parallel_large(self, env: Env, httpd, nghttpx, repeat, pro pytest.skip("msh3 stalls here") fdata = os.path.join(env.gen_dir, 'data-100k') # limit since we use a separate connection in h1 - count = 20 + count = 10 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, @@ -199,7 +199,7 @@ def test_07_22_upload_parallel_fail(self, env: Env, httpd, nghttpx, repeat, prot if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") fdata = os.path.join(env.gen_dir, 'data-10m') - count = 100 + count = 20 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}'\ f'/curltest/tweak?status=400&delay=5ms&chunks=1&body_error=reset&id=[0-{count-1}]' @@ -475,9 +475,14 @@ def test_07_42a_upload_disconnect(self, env: Env, httpd, nghttpx, repeat, proto) client = LocalClient(name='upload-pausing', env=env, timeout=60) if not client.exists(): pytest.skip(f'example client not built: {client.name}') - url = f'http://{env.domain1}:{env.http_port}/curltest/echo?id=[0-0]&die_after=0' - r = client.run([url]) - r.check_exit_code(18) # PARTIAL_FILE + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-0]&die_after=0' + r = client.run(['-V', proto, url]) + exp_code = 18 # PARTIAL_FILE + if proto == 'h2': + exp_code = 92 # CURLE_HTTP2_STREAM + elif proto == 'h3': + exp_code = 95 # CURLE_HTTP3 + r.check_exit_code(exp_code) # upload data, pause, let connection die without any response at all @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) @@ -489,9 +494,12 @@ def test_07_42b_upload_disconnect(self, env: Env, httpd, nghttpx, repeat, proto) client = LocalClient(name='upload-pausing', env=env, timeout=60) if not client.exists(): pytest.skip(f'example client not built: {client.name}') - url = f'http://{env.domain1}:{env.http_port}/curltest/echo?id=[0-0]&just_die=1' - r = client.run([url]) - r.check_exit_code(52) # GOT_NOTHING + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-0]&just_die=1' + r = client.run(['-V', proto, url]) + exp_code = 52 # GOT_NOTHING + if proto == 'h2' or proto == 'h3': + exp_code = 0 # we get a 500 from the server + r.check_exit_code(exp_code) # GOT_NOTHING # upload data, pause, let connection die after 100 continue @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) @@ -503,9 +511,12 @@ def test_07_42c_upload_disconnect(self, env: Env, httpd, nghttpx, repeat, proto) client = LocalClient(name='upload-pausing', env=env, timeout=60) if not client.exists(): pytest.skip(f'example client not built: {client.name}') - url = f'http://{env.domain1}:{env.http_port}/curltest/echo?id=[0-0]&die_after_100=1' - r = client.run([url]) - r.check_exit_code(52) # GOT_NOTHING + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-0]&die_after_100=1' + r = client.run(['-V', proto, url]) + exp_code = 52 # GOT_NOTHING + if proto == 'h2' or proto == 'h3': + exp_code = 0 # we get a 500 from the server + r.check_exit_code(exp_code) # GOT_NOTHING # speed limited on put handler @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) @@ -515,7 +526,7 @@ def test_07_50_put_speed_limit(self, env: Env, httpd, nghttpx, proto, repeat): count = 1 fdata = os.path.join(env.gen_dir, 'data-100k') up_len = 100 * 1024 - speed_limit = 20 * 1024 + speed_limit = 50 * 1024 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/put?id=[0-0]' r = curl.http_put(urls=[url], fdata=fdata, alpn_proto=proto, @@ -534,7 +545,7 @@ def test_07_51_echo_speed_limit(self, env: Env, httpd, nghttpx, proto, repeat): pytest.skip("h3 not supported") count = 1 fdata = os.path.join(env.gen_dir, 'data-100k') - speed_limit = 20 * 1024 + speed_limit = 50 * 1024 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-0]' r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, diff --git a/tests/http/test_10_proxy.py b/tests/http/test_10_proxy.py index 1be8d3501..dcc454e0d 100644 --- a/tests/http/test_10_proxy.py +++ b/tests/http/test_10_proxy.py @@ -221,7 +221,7 @@ def test_10_08_upload_seq_large(self, env: Env, httpd, nghttpx, proto, indata = open(srcfile).readlines() for i in range(count): respdata = open(curl.response_file(i)).readlines() - assert respdata == indata + assert respdata == indata, f'resonse {i} differs' assert r.total_connects == 1, r.dump_logs() @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") @@ -291,7 +291,7 @@ def test_10_11_noreuse_proxy_https(self, env: Env, httpd, nghttpx_fwd, tunnel, r x2_args = r1.args[1:] x2_args.append('--next') x2_args.extend(proxy_args) - x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_256_GCM_SHA384']) r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, extra_args=x2_args) r2.check_response(count=2, http_status=200) @@ -317,7 +317,7 @@ def test_10_12_noreuse_proxy_http(self, env: Env, httpd, nghttpx_fwd, tunnel, re x2_args = r1.args[1:] x2_args.append('--next') x2_args.extend(proxy_args) - x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_256_GCM_SHA384']) r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, extra_args=x2_args) r2.check_response(count=2, http_status=200) @@ -343,7 +343,7 @@ def test_10_13_noreuse_https(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat) x2_args = r1.args[1:] x2_args.append('--next') x2_args.extend(proxy_args) - x2_args.extend(['--tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + x2_args.extend(['--tls13-ciphers', 'TLS_AES_256_GCM_SHA384']) r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, extra_args=x2_args) r2.check_response(count=2, http_status=200) diff --git a/tests/http/test_11_unix.py b/tests/http/test_11_unix.py index 2df23f4ad..d800601b3 100644 --- a/tests/http/test_11_unix.py +++ b/tests/http/test_11_unix.py @@ -95,7 +95,7 @@ def uds_faker(self, env: Env) -> UDSFaker: yield faker faker.stop() - # download http: via unix socket + # download http: via Unix socket def test_11_01_unix_connect_http(self, env: Env, httpd, uds_faker, repeat): curl = CurlClient(env=env) url = f'http://{env.domain1}:{env.http_port}/data.json' @@ -105,7 +105,7 @@ def test_11_01_unix_connect_http(self, env: Env, httpd, uds_faker, repeat): ]) r.check_response(count=1, http_status=200) - # download https: via unix socket + # download https: via Unix socket @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") def test_11_02_unix_connect_http(self, env: Env, httpd, uds_faker, repeat): curl = CurlClient(env=env) @@ -116,7 +116,7 @@ def test_11_02_unix_connect_http(self, env: Env, httpd, uds_faker, repeat): ]) r.check_response(exitcode=35, http_status=None) - # download HTTP/3 via unix socket + # download HTTP/3 via Unix socket @pytest.mark.skipif(condition=not Env.have_h3(), reason='h3 not supported') def test_11_03_unix_connect_quic(self, env: Env, httpd, uds_faker, repeat): curl = CurlClient(env=env) diff --git a/tests/http/test_16_info.py b/tests/http/test_16_info.py new file mode 100644 index 000000000..570619af3 --- /dev/null +++ b/tests/http/test_16_info.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import logging +import os +from datetime import timedelta +import pytest + +from testenv import Env, CurlClient, LocalClient, ExecResult + + +log = logging.getLogger(__name__) + + +class TestInfo: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, httpd, nghttpx): + if env.have_h3(): + nghttpx.start_if_needed() + httpd.clear_extra_configs() + httpd.reload() + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, httpd): + indir = httpd.docs_dir + env.make_data_file(indir=indir, fname="data-10k", fsize=10*1024) + env.make_data_file(indir=indir, fname="data-100k", fsize=100*1024) + env.make_data_file(indir=indir, fname="data-1m", fsize=1024*1024) + + # download plain file + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_16_01_info_download(self, env: Env, httpd, nghttpx, repeat, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + count = 2 + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True) + r.check_stats(count=count, http_status=200, exitcode=0, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') + for idx, s in enumerate(r.stats): + self.check_stat(idx, s, r, dl_size=30, ul_size=0) + + # download plain file with a 302 redirect + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_16_02_info_302_download(self, env: Env, httpd, nghttpx, repeat, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + count = 2 + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json.302?[0-{count-1}]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True, extra_args=[ + '--location' + ]) + r.check_stats(count=count, http_status=200, exitcode=0, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') + for idx, s in enumerate(r.stats): + self.check_stat(idx, s, r, dl_size=30, ul_size=0) + + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_16_03_info_upload(self, env: Env, httpd, nghttpx, proto, repeat): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + count = 2 + fdata = os.path.join(env.gen_dir, 'data-100k') + fsize = 100 * 1024 + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' + r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, + with_headers=True, extra_args=[ + '--trace-config', 'http/2,http/3' + ]) + r.check_response(count=count, http_status=200) + r.check_stats(count=count, http_status=200, exitcode=0, + remote_port=env.port_for(alpn_proto=proto), + remote_ip='127.0.0.1') + for idx, s in enumerate(r.stats): + self.check_stat(idx, s, r, dl_size=fsize, ul_size=fsize) + + # download plain file via http: ('time_appconnect' is 0) + @pytest.mark.parametrize("proto", ['http/1.1']) + def test_16_04_info_http_download(self, env: Env, httpd, nghttpx, repeat, proto): + count = 2 + curl = CurlClient(env=env) + url = f'http://{env.domain1}:{env.http_port}/data.json?[0-{count-1}]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True) + r.check_stats(count=count, http_status=200, exitcode=0, + remote_port=env.http_port, remote_ip='127.0.0.1') + for idx, s in enumerate(r.stats): + self.check_stat(idx, s, r, dl_size=30, ul_size=0) + + def check_stat(self, idx, s, r, dl_size=None, ul_size=None): + self.check_stat_times(s, idx) + # we always send something + self.check_stat_positive(s, idx, 'size_request') + # we always receive response headers + self.check_stat_positive(s, idx, 'size_header') + if ul_size is not None: + assert s['size_upload'] == ul_size, f'stat #{idx}\n{r.dump_logs()}' # the file we sent + assert s['size_request'] >= s['size_upload'], \ + f'stat #{idx}, "size_request" smaller than "size_upload", {s}\n{r.dump_logs()}' + if dl_size is not None: + assert s['size_download'] == dl_size, f'stat #{idx}\n{r.dump_logs()}' # the file we received + + def check_stat_positive(self, s, idx, key): + assert key in s, f'stat #{idx} "{key}" missing: {s}' + assert s[key] > 0, f'stat #{idx} "{key}" not positive: {s}' + + def check_stat_zero(self, s, key): + assert key in s, f'stat "{key}" missing: {s}' + assert s[key] == 0, f'stat "{key}" not zero: {s}' + + def check_stat_times(self, s, idx): + # check timings reported on a transfer for consistency + url = s['url_effective'] + # all stat keys which reporting timings + all_keys = set([ + 'time_appconnect', 'time_connect', 'time_redirect', + 'time_pretransfer', 'time_starttransfer', 'time_total' + ]) + # stat keys where we expect a positive value + pos_keys = set(['time_pretransfer', 'time_starttransfer', 'time_total']) + if s['num_connects'] > 0: + pos_keys.add('time_connect') + if url.startswith('https:'): + pos_keys.add('time_appconnect') + if s['num_redirects'] > 0: + pos_keys.add('time_redirect') + zero_keys = all_keys - pos_keys + # assert all zeros are zeros and the others are positive + for key in zero_keys: + self.check_stat_zero(s, key) + for key in pos_keys: + self.check_stat_positive(s, idx, key) + # assert that all timers before "time_pretransfer" are less or equal + for key in ['time_appconnect', 'time_connect', 'time_namelookup']: + assert s[key] < s['time_pretransfer'], f'time "{key}" larger than' \ + f'"time_pretransfer": {s}' + # assert transfer start is after pretransfer + assert s['time_pretransfer'] <= s['time_starttransfer'], f'"time_pretransfer" '\ + f'greater than "time_starttransfer", {s}' + # assert that transfer start is before total + assert s['time_starttransfer'] <= s['time_total'], f'"time_starttransfer" '\ + f'greater than "time_total", {s}' diff --git a/tests/http/test_17_ssl_use.py b/tests/http/test_17_ssl_use.py new file mode 100644 index 000000000..c7dc2ad5f --- /dev/null +++ b/tests/http/test_17_ssl_use.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import json +import logging +import os +from datetime import timedelta +import pytest + +from testenv import Env, CurlClient, LocalClient, ExecResult + + +log = logging.getLogger(__name__) + + +class TestSSLUse: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, nghttpx): + if env.have_h3(): + nghttpx.start_if_needed() + + @pytest.fixture(autouse=True, scope='function') + def _function_scope(self, request, env, httpd): + httpd.clear_extra_configs() + if 'httpd' not in request.node._fixtureinfo.argnames: + httpd.reload_if_config_changed() + + def test_17_01_sslinfo_plain(self, env: Env, nghttpx, repeat): + proto = 'http/1.1' + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo' + r = curl.http_get(url=url, alpn_proto=proto) + assert r.json['HTTPS'] == 'on', f'{r.json}' + assert 'SSL_SESSION_ID' in r.json, f'{r.json}' + assert 'SSL_SESSION_RESUMED' in r.json, f'{r.json}' + assert r.json['SSL_SESSION_RESUMED'] == 'Initial', f'{r.json}' + + @pytest.mark.parametrize("tls_max", ['1.2', '1.3']) + def test_17_02_sslinfo_reconnect(self, env: Env, tls_max): + proto = 'http/1.1' + count = 3 + exp_resumed = 'Resumed' + xargs = ['--sessionid', '--tls-max', tls_max, f'--tlsv{tls_max}'] + if env.curl_uses_lib('gnutls'): + if tls_max == '1.3': + exp_resumed = 'Initial' # 1.2 works in GnuTLS, but 1.3 does not, TODO + if env.curl_uses_lib('libressl'): + if tls_max == '1.3': + exp_resumed = 'Initial' # 1.2 works in LibreSSL, but 1.3 does not, TODO + if env.curl_uses_lib('wolfssl'): + if tls_max == '1.3': + exp_resumed = 'Initial' # 1.2 works in wolfSSL, but 1.3 does not, TODO + if env.curl_uses_lib('rustls-ffi'): + exp_resumed = 'Initial' # Rustls does not support sessions, TODO + if env.curl_uses_lib('bearssl') and tls_max == '1.3': + pytest.skip('BearSSL does not support TLSv1.3') + if env.curl_uses_lib('mbedtls') and tls_max == '1.3': + pytest.skip('mbedtls TLSv1.3 session resume not working in 3.6.0') + + curl = CurlClient(env=env) + # tell the server to close the connection after each request + urln = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo?'\ + f'id=[0-{count-1}]&close' + r = curl.http_download(urls=[urln], alpn_proto=proto, with_stats=True, + extra_args=xargs) + r.check_response(count=count, http_status=200) + # should have used one connection for each request, sessions after + # first should have been resumed + assert r.total_connects == count, r.dump_logs() + for i in range(count): + dfile = curl.download_file(i) + assert os.path.exists(dfile) + with open(dfile) as f: + djson = json.load(f) + assert djson['HTTPS'] == 'on', f'{i}: {djson}' + if i == 0: + assert djson['SSL_SESSION_RESUMED'] == 'Initial', f'{i}: {djson}' + else: + assert djson['SSL_SESSION_RESUMED'] == exp_resumed, f'{i}: {djson}' + + # use host name with trailing dot, verify handshake + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_17_03_trailing_dot(self, env: Env, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + curl = CurlClient(env=env) + domain = f'{env.domain1}.' + url = f'https://{env.authority_for(domain, proto)}/curltest/sslinfo' + r = curl.http_get(url=url, alpn_proto=proto) + assert r.exit_code == 0, f'{r}' + assert r.json, f'{r}' + if proto != 'h3': # we proxy h3 + # the SNI the server received is without trailing dot + assert r.json['SSL_TLS_SNI'] == env.domain1, f'{r.json}' + + # use host name with double trailing dot, verify handshake + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_17_04_double_dot(self, env: Env, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + if proto == 'h3' and env.curl_uses_lib('wolfssl'): + pytest.skip("wolfSSL HTTP/3 peer verification does not properly check") + curl = CurlClient(env=env) + domain = f'{env.domain1}..' + url = f'https://{env.authority_for(domain, proto)}/curltest/sslinfo' + r = curl.http_get(url=url, alpn_proto=proto, extra_args=[ + '-H', f'Host: {env.domain1}', + ]) + if r.exit_code == 0: + assert r.json, f'{r.stdout}' + # the SNI the server received is without trailing dot + if proto != 'h3': # we proxy h3 + assert r.json['SSL_TLS_SNI'] == env.domain1, f'{r.json}' + assert False, f'should not have succeeded: {r.json}' + # 7 - Rustls rejects a servername with .. during setup + # 35 - LibreSSL rejects setting an SNI name with trailing dot + # 60 - peer name matching failed against certificate + assert r.exit_code in [7, 35, 60], f'{r}' + + # use ip address for connect + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_17_05_ip_addr(self, env: Env, proto): + if env.curl_uses_lib('bearssl'): + pytest.skip("BearSSL does not support cert verification with IP addresses") + if env.curl_uses_lib('mbedtls'): + pytest.skip("mbedTLS does not support cert verification with IP addresses") + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + curl = CurlClient(env=env) + domain = f'127.0.0.1' + url = f'https://{env.authority_for(domain, proto)}/curltest/sslinfo' + r = curl.http_get(url=url, alpn_proto=proto) + assert r.exit_code == 0, f'{r}' + assert r.json, f'{r}' + if proto != 'h3': # we proxy h3 + # the SNI should not have been used + assert 'SSL_TLS_SNI' not in r.json, f'{r.json}' + + # use localhost for connect + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_17_06_localhost(self, env: Env, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + curl = CurlClient(env=env) + domain = f'localhost' + url = f'https://{env.authority_for(domain, proto)}/curltest/sslinfo' + r = curl.http_get(url=url, alpn_proto=proto) + assert r.exit_code == 0, f'{r}' + assert r.json, f'{r}' + if proto != 'h3': # we proxy h3 + assert r.json['SSL_TLS_SNI'] == domain, f'{r.json}' + + @staticmethod + def gen_test_17_07_list(): + tls13_tests = [ + [None, True], + [['TLS_AES_128_GCM_SHA256'], True], + [['TLS_AES_256_GCM_SHA384'], False], + [['TLS_CHACHA20_POLY1305_SHA256'], True], + [['TLS_AES_256_GCM_SHA384', + 'TLS_CHACHA20_POLY1305_SHA256'], True], + ] + tls12_tests = [ + [None, True], + [['ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256'], True], + [['ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384'], False], + [['ECDHE-ECDSA-CHACHA20-POLY1305', 'ECDHE-RSA-CHACHA20-POLY1305'], True], + [['ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', + 'ECDHE-ECDSA-CHACHA20-POLY1305', 'ECDHE-RSA-CHACHA20-POLY1305'], True], + ] + ret = [] + for tls_proto in ['TLSv1.3 +TLSv1.2', 'TLSv1.3', 'TLSv1.2']: + for [ciphers13, succeed13] in tls13_tests: + for [ciphers12, succeed12] in tls12_tests: + ret.append([tls_proto, ciphers13, ciphers12, succeed13, succeed12]) + return ret + + @pytest.mark.parametrize("tls_proto, ciphers13, ciphers12, succeed13, succeed12", gen_test_17_07_list()) + def test_17_07_ssl_ciphers(self, env: Env, httpd, tls_proto, ciphers13, ciphers12, succeed13, succeed12): + # to test setting cipher suites, the AES 256 ciphers are disabled in the test server + httpd.set_extra_config('base', [ + 'SSLCipherSuite SSL' + ' ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' + ':ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305', + 'SSLCipherSuite TLSv1.3' + ' TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256', + f'SSLProtocol {tls_proto}' + ]) + httpd.reload_if_config_changed() + proto = 'http/1.1' + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo' + # SSL backend specifics + if env.curl_uses_lib('gnutls'): + pytest.skip('GnuTLS does not support setting ciphers') + elif env.curl_uses_lib('boringssl'): + if ciphers13 is not None: + pytest.skip('BoringSSL does not support setting TLSv1.3 ciphers') + elif env.curl_uses_lib('schannel'): # not in CI, so untested + if ciphers12 is not None: + pytest.skip('Schannel does not support setting TLSv1.2 ciphers by name') + elif env.curl_uses_lib('bearssl'): + if tls_proto == 'TLSv1.3': + pytest.skip('BearSSL does not support TLSv1.3') + tls_proto = 'TLSv1.2' + elif env.curl_uses_lib('sectransp'): # not in CI, so untested + if tls_proto == 'TLSv1.3': + pytest.skip('SecureTransport does not support TLSv1.3') + tls_proto = 'TLSv1.2' + # test + extra_args = ['--tls13-ciphers', ':'.join(ciphers13)] if ciphers13 else [] + extra_args += ['--ciphers', ':'.join(ciphers12)] if ciphers12 else [] + r = curl.http_get(url=url, alpn_proto=proto, extra_args=extra_args) + if tls_proto != 'TLSv1.2' and succeed13: + assert r.exit_code == 0, r.dump_logs() + assert r.json['HTTPS'] == 'on', r.dump_logs() + assert r.json['SSL_PROTOCOL'] == 'TLSv1.3', r.dump_logs() + assert ciphers13 is None or r.json['SSL_CIPHER'] in ciphers13, r.dump_logs() + elif tls_proto == 'TLSv1.2' and succeed12: + assert r.exit_code == 0, r.dump_logs() + assert r.json['HTTPS'] == 'on', r.dump_logs() + assert r.json['SSL_PROTOCOL'] == 'TLSv1.2', r.dump_logs() + assert ciphers12 is None or r.json['SSL_CIPHER'] in ciphers12, r.dump_logs() + else: + assert r.exit_code != 0, r.dump_logs() + + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_17_08_cert_status(self, env: Env, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + if not env.curl_uses_lib('openssl') and \ + not env.curl_uses_lib('gnutls') and \ + not env.curl_uses_lib('quictls'): + pytest.skip("TLS library does not support --cert-status") + curl = CurlClient(env=env) + domain = f'localhost' + url = f'https://{env.authority_for(domain, proto)}/' + r = curl.http_get(url=url, alpn_proto=proto, extra_args=[ + '--cert-status' + ]) + # CURLE_SSL_INVALIDCERTSTATUS, our certs have no OCSP info + assert r.exit_code == 91, f'{r}' + + @staticmethod + def gen_test_17_09_list(): + ret = [] + for tls_proto in ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']: + for max_ver in range(0, 5): + for min_ver in range(-2, 4): + ret.append([tls_proto, max_ver, min_ver]) + return ret + + @pytest.mark.parametrize("tls_proto, max_ver, min_ver", gen_test_17_09_list()) + def test_17_09_ssl_min_max(self, env: Env, httpd, tls_proto, max_ver, min_ver): + httpd.set_extra_config('base', [ + f'SSLProtocol {tls_proto}', + 'SSLCipherSuite ALL:@SECLEVEL=0', + ]) + httpd.reload_if_config_changed() + proto = 'http/1.1' + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo' + # SSL backend specifics + if env.curl_uses_lib('bearssl'): + supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', None] + elif env.curl_uses_lib('sectransp'): # not in CI, so untested + supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', None] + elif env.curl_uses_lib('gnutls'): + supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'] + elif env.curl_uses_lib('quiche'): + supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'] + else: # most SSL backends dropped support for TLSv1.0, TLSv1.1 + supported = [None, None, 'TLSv1.2', 'TLSv1.3'] + # test + extra_args = [[], ['--tlsv1'], ['--tlsv1.0'], ['--tlsv1.1'], ['--tlsv1.2'], ['--tlsv1.3']][min_ver+2] + \ + [['--tls-max', '1.0'], ['--tls-max', '1.1'], ['--tls-max', '1.2'], ['--tls-max', '1.3'], []][max_ver] + r = curl.http_get(url=url, alpn_proto=proto, extra_args=extra_args) + if max_ver >= min_ver and tls_proto in supported[max(0, min_ver):min(max_ver, 3)+1]: + assert r.exit_code == 0 , r.dump_logs() + assert r.json['HTTPS'] == 'on', r.dump_logs() + assert r.json['SSL_PROTOCOL'] == tls_proto, r.dump_logs() + else: + assert r.exit_code != 0, r.dump_logs() diff --git a/tests/http/test_18_methods.py b/tests/http/test_18_methods.py new file mode 100644 index 000000000..ed9f47729 --- /dev/null +++ b/tests/http/test_18_methods.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import logging +import os +from datetime import timedelta +import pytest + +from testenv import Env, CurlClient, LocalClient + + +log = logging.getLogger(__name__) + + +class TestMethods: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, httpd, nghttpx): + if env.have_h3(): + nghttpx.start_if_needed() + httpd.clear_extra_configs() + httpd.reload_if_config_changed() + indir = httpd.docs_dir + env.make_data_file(indir=indir, fname="data-10k", fsize=10*1024) + env.make_data_file(indir=indir, fname="data-100k", fsize=100*1024) + env.make_data_file(indir=indir, fname="data-1m", fsize=1024*1024) + + # download 1 file + @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) + def test_18_01_delete(self, env: Env, httpd, nghttpx, repeat, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + count = 1 + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/tweak?id=[0-{count-1}]' + r = curl.http_delete(urls=[url], alpn_proto=proto) + r.check_stats(count=count, http_status=204, exitcode=0) + + # make HTTP/2 in the server send + # - HEADER frame with 204 and eos=0 + # - 10ms later DATA frame length=0 and eos=1 + # should be accepted + def test_18_02_delete_h2_special(self, env: Env, httpd, nghttpx, repeat): + proto = 'h2' + count = 1 + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/tweak?id=[0-{count-1}]'\ + '&chunks=1&chunk_size=0&chunk_delay=10ms' + r = curl.http_delete(urls=[url], alpn_proto=proto) + r.check_stats(count=count, http_status=204, exitcode=0) diff --git a/tests/http/test_19_shutdown.py b/tests/http/test_19_shutdown.py new file mode 100644 index 000000000..21ddc1ad2 --- /dev/null +++ b/tests/http/test_19_shutdown.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import logging +import os +import re +from datetime import timedelta +import pytest + +from testenv import Env, CurlClient, LocalClient + + +log = logging.getLogger(__name__) + + +class TestShutdown: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, httpd, nghttpx): + if env.have_h3(): + nghttpx.start_if_needed() + httpd.clear_extra_configs() + httpd.reload() + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, httpd): + indir = httpd.docs_dir + env.make_data_file(indir=indir, fname="data-10k", fsize=10*1024) + env.make_data_file(indir=indir, fname="data-100k", fsize=100*1024) + env.make_data_file(indir=indir, fname="data-1m", fsize=1024*1024) + + # check with `tcpdump` that we see curl TCP RST packets + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + @pytest.mark.parametrize("proto", ['http/1.1']) + def test_19_01_check_tcp_rst(self, env: Env, httpd, repeat, proto): + if env.ci_run: + pytest.skip("seems not to work in CI") + curl = CurlClient(env=env) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-1]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_tcpdump=True, extra_args=[ + '--parallel' + ]) + r.check_response(http_status=200, count=2) + assert r.tcpdump + assert len(r.tcpdump.stats) != 0, f'Expected TCP RSTs packets: {r.tcpdump.stderr}' + + # check with `tcpdump` that we do NOT see TCP RST when CURL_GRACEFUL_SHUTDOWN set + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + @pytest.mark.parametrize("proto", ['http/1.1', 'h2']) + def test_19_02_check_shutdown(self, env: Env, httpd, repeat, proto): + if not env.curl_is_debug(): + pytest.skip('only works for curl debug builds') + curl = CurlClient(env=env, run_env={ + 'CURL_GRACEFUL_SHUTDOWN': '2000', + 'CURL_DEBUG': 'ssl' + }) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-1]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_tcpdump=True, extra_args=[ + '--parallel' + ]) + r.check_response(http_status=200, count=2) + assert r.tcpdump + assert len(r.tcpdump.stats) == 0, f'Unexpected TCP RSTs packets' + + # run downloads where the server closes the connection after each request + @pytest.mark.parametrize("proto", ['http/1.1']) + def test_19_03_shutdown_by_server(self, env: Env, httpd, repeat, proto): + if not env.curl_is_debug(): + pytest.skip('only works for curl debug builds') + count = 10 + curl = CurlClient(env=env, run_env={ + 'CURL_GRACEFUL_SHUTDOWN': '2000', + 'CURL_DEBUG': 'ssl' + }) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/tweak/?'\ + f'id=[0-{count-1}]&with_cl&close' + r = curl.http_download(urls=[url], alpn_proto=proto) + r.check_response(http_status=200, count=count) + shutdowns = [l for l in r.trace_lines if re.match(r'.*CCACHE\] shutdown #\d+, done=1', l)] + assert len(shutdowns) == count, f'{shutdowns}' + + # run downloads with CURLOPT_FORBID_REUSE set, meaning *we* close + # the connection after each request + @pytest.mark.parametrize("proto", ['http/1.1']) + def test_19_04_shutdown_by_curl(self, env: Env, httpd, proto, repeat): + if not env.curl_is_debug(): + pytest.skip('only works for curl debug builds') + count = 10 + docname = 'data.json' + url = f'https://localhost:{env.https_port}/{docname}' + client = LocalClient(name='h2-download', env=env, run_env={ + 'CURL_GRACEFUL_SHUTDOWN': '2000', + 'CURL_DEBUG': 'ssl' + }) + if not client.exists(): + pytest.skip(f'example client not built: {client.name}') + r = client.run(args=[ + '-n', f'{count}', '-f', '-V', proto, url + ]) + r.check_exit_code(0) + shutdowns = [l for l in r.trace_lines if re.match(r'.*CCACHE\] shutdown #\d+, done=1', l)] + assert len(shutdowns) == count, f'{shutdowns}' + + # run event-based downloads with CURLOPT_FORBID_REUSE set, meaning *we* close + # the connection after each request + @pytest.mark.parametrize("proto", ['http/1.1']) + def test_19_05_event_shutdown_by_server(self, env: Env, httpd, proto, repeat): + if not env.curl_is_debug(): + pytest.skip('only works for curl debug builds') + count = 10 + curl = CurlClient(env=env, run_env={ + # forbid connection reuse to trigger shutdowns after transfer + 'CURL_FORBID_REUSE': '1', + # make socket receives block 50% of the time to delay shutdown + 'CURL_DBG_SOCK_RBLOCK': '50', + 'CURL_DEBUG': 'ssl' + }) + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/tweak/?'\ + f'id=[0-{count-1}]&with_cl&' + r = curl.http_download(urls=[url], alpn_proto=proto, extra_args=[ + '--test-event' + ]) + r.check_response(http_status=200, count=count) + # check that we closed all connections + closings = [l for l in r.trace_lines if re.match(r'.*CCACHE\] closing #\d+', l)] + assert len(closings) == count, f'{closings}' + # check that all connection sockets were removed from event + removes = [l for l in r.trace_lines if re.match(r'.*socket cb: socket \d+ REMOVED', l)] + assert len(removes) == count, f'{removes}' + + # check graceful shutdown on multiplexed http + @pytest.mark.parametrize("proto", ['h2', 'h3']) + def test_19_06_check_shutdown(self, env: Env, httpd, nghttpx, repeat, proto): + if proto == 'h3' and not env.have_h3(): + pytest.skip("h3 not supported") + if not env.curl_is_debug(): + pytest.skip('only works for curl debug builds') + curl = CurlClient(env=env, run_env={ + 'CURL_GRACEFUL_SHUTDOWN': '2000', + 'CURL_DEBUG': 'all' + }) + url = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-1]' + r = curl.http_download(urls=[url], alpn_proto=proto, with_tcpdump=True, extra_args=[ + '--parallel' + ]) + r.check_response(http_status=200, count=2) + # check connection cache closings + shutdowns = [l for l in r.trace_lines if re.match(r'.*CCACHE\] shutdown #\d+, done=1', l)] + assert len(shutdowns) == 1, f'{shutdowns}' diff --git a/tests/http/test_30_vsftpd.py b/tests/http/test_30_vsftpd.py new file mode 100644 index 000000000..d90f84611 --- /dev/null +++ b/tests/http/test_30_vsftpd.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import logging +import os +import shutil +import pytest + +from testenv import Env, CurlClient, VsFTPD + + +log = logging.getLogger(__name__) + + +@pytest.mark.skipif(condition=not Env.has_vsftpd(), reason=f"missing vsftpd") +class TestVsFTPD: + + @pytest.fixture(autouse=True, scope='class') + def vsftpd(self, env): + vsftpd = VsFTPD(env=env) + assert vsftpd.start() + yield vsftpd + vsftpd.stop() + + def _make_docs_file(self, docs_dir: str, fname: str, fsize: int): + fpath = os.path.join(docs_dir, fname) + data1k = 1024*'x' + flen = 0 + with open(fpath, 'w') as fd: + while flen < fsize: + fd.write(data1k) + flen += len(data1k) + return flen + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, vsftpd): + if os.path.exists(vsftpd.docs_dir): + shutil.rmtree(vsftpd.docs_dir) + if not os.path.exists(vsftpd.docs_dir): + os.makedirs(vsftpd.docs_dir) + self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-1k', fsize=1024) + self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-10k', fsize=10*1024) + self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-1m', fsize=1024*1024) + self._make_docs_file(docs_dir=vsftpd.docs_dir, fname='data-10m', fsize=10*1024*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1k", fsize=1024) + env.make_data_file(indir=env.gen_dir, fname="upload-100k", fsize=100*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1m", fsize=1024*1024) + + def test_30_01_list_dir(self, env: Env, vsftpd: VsFTPD, repeat): + curl = CurlClient(env=env) + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_get(urls=[url], with_stats=True) + r.check_stats(count=1, http_status=226) + lines = open(os.path.join(curl.run_dir, 'download_#1.data')).readlines() + assert len(lines) == 4, f'list: {lines}' + + # download 1 file, no SSL + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_30_02_download_1(self, env: Env, vsftpd: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpd.docs_dir, f'{docname}') + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/{docname}?[0-{count-1}]' + r = curl.ftp_get(urls=[url], with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_30_03_download_10_serial(self, env: Env, vsftpd: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpd.docs_dir, f'{docname}') + count = 10 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/{docname}?[0-{count-1}]' + r = curl.ftp_get(urls=[url], with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_30_04_download_10_parallel(self, env: Env, vsftpd: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpd.docs_dir, f'{docname}') + count = 10 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/{docname}?[0-{count-1}]' + r = curl.ftp_get(urls=[url], with_stats=True, extra_args=[ + '--parallel' + ]) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'upload-1k', 'upload-100k', 'upload-1m' + ]) + def test_30_05_upload_1(self, env: Env, vsftpd: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_upload(urls=[url], fupload=f'{srcfile}', with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpd, docname=docname) + + def _rmf(self, path): + if os.path.exists(path): + return os.remove(path) + + # check with `tcpdump` if curl causes any TCP RST packets + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + def test_30_06_shutdownh_download(self, env: Env, vsftpd: VsFTPD, repeat): + docname = 'data-1k' + curl = CurlClient(env=env) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/{docname}?[0-{count-1}]' + r = curl.ftp_get(urls=[url], with_stats=True, with_tcpdump=True) + r.check_stats(count=count, http_status=226) + assert r.tcpdump + assert len(r.tcpdump.stats) == 0, f'Unexpected TCP RSTs packets' + + # check with `tcpdump` if curl causes any TCP RST packets + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + def test_30_07_shutdownh_upload(self, env: Env, vsftpd: VsFTPD, repeat): + docname = 'upload-1k' + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, with_tcpdump=True) + r.check_stats(count=count, http_status=226) + assert r.tcpdump + assert len(r.tcpdump.stats) == 0, f'Unexpected TCP RSTs packets' + + def test_30_08_active_download(self, env: Env, vsftpd: VsFTPD): + docname = 'data-10k' + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpd.docs_dir, f'{docname}') + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/{docname}?[0-{count-1}]' + r = curl.ftp_get(urls=[url], with_stats=True, extra_args=[ + '--ftp-port', '127.0.0.1' + ]) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + def test_30_09_active_upload(self, env: Env, vsftpd: VsFTPD): + docname = 'upload-1k' + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, extra_args=[ + '--ftp-port', '127.0.0.1' + ]) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpd, docname=docname) + + def check_downloads(self, client, srcfile: str, count: int, + complete: bool = True): + for i in range(count): + dfile = client.download_file(i) + assert os.path.exists(dfile) + if complete and not filecmp.cmp(srcfile, dfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dfile).readlines(), + fromfile=srcfile, + tofile=dfile, + n=1)) + assert False, f'download {dfile} differs:\n{diff}' + + def check_upload(self, env, vsftpd: VsFTPD, docname): + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + assert os.path.exists(srcfile) + assert os.path.exists(dstfile) + if not filecmp.cmp(srcfile, dstfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dstfile).readlines(), + fromfile=srcfile, + tofile=dstfile, + n=1)) + assert False, f'upload {dstfile} differs:\n{diff}' diff --git a/tests/http/test_31_vsftpds.py b/tests/http/test_31_vsftpds.py new file mode 100644 index 000000000..95f3957ca --- /dev/null +++ b/tests/http/test_31_vsftpds.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +import difflib +import filecmp +import logging +import os +import shutil +import pytest + +from testenv import Env, CurlClient, VsFTPD + + +log = logging.getLogger(__name__) + + +@pytest.mark.skipif(condition=not Env.has_vsftpd(), reason=f"missing vsftpd") +class TestVsFTPD: + + SUPPORTS_SSL = True + + @pytest.fixture(autouse=True, scope='class') + def vsftpds(self, env): + if not TestVsFTPD.SUPPORTS_SSL: + pytest.skip('vsftpd does not seem to support SSL') + vsftpds = VsFTPD(env=env, with_ssl=True) + if not vsftpds.start(): + vsftpds.stop() + TestVsFTPD.SUPPORTS_SSL = False + pytest.skip('vsftpd does not seem to support SSL') + yield vsftpds + vsftpds.stop() + + def _make_docs_file(self, docs_dir: str, fname: str, fsize: int): + fpath = os.path.join(docs_dir, fname) + data1k = 1024*'x' + flen = 0 + with open(fpath, 'w') as fd: + while flen < fsize: + fd.write(data1k) + flen += len(data1k) + return flen + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env, vsftpds): + if os.path.exists(vsftpds.docs_dir): + shutil.rmtree(vsftpds.docs_dir) + if not os.path.exists(vsftpds.docs_dir): + os.makedirs(vsftpds.docs_dir) + self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-1k', fsize=1024) + self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-10k', fsize=10*1024) + self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-1m', fsize=1024*1024) + self._make_docs_file(docs_dir=vsftpds.docs_dir, fname='data-10m', fsize=10*1024*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1k", fsize=1024) + env.make_data_file(indir=env.gen_dir, fname="upload-100k", fsize=100*1024) + env.make_data_file(indir=env.gen_dir, fname="upload-1m", fsize=1024*1024) + + def test_31_01_list_dir(self, env: Env, vsftpds: VsFTPD, repeat): + curl = CurlClient(env=env) + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_get(urls=[url], with_stats=True) + r.check_stats(count=1, http_status=226) + lines = open(os.path.join(curl.run_dir, 'download_#1.data')).readlines() + assert len(lines) == 4, f'list: {lines}' + + # download 1 file, no SSL + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_31_02_download_1(self, env: Env, vsftpds: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpds.docs_dir, f'{docname}') + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/{docname}?[0-{count-1}]' + r = curl.ftp_ssl_get(urls=[url], with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_31_03_download_10_serial(self, env: Env, vsftpds: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpds.docs_dir, f'{docname}') + count = 10 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/{docname}?[0-{count-1}]' + r = curl.ftp_ssl_get(urls=[url], with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'data-1k', 'data-1m', 'data-10m' + ]) + def test_31_04_download_10_parallel(self, env: Env, vsftpds: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpds.docs_dir, f'{docname}') + count = 10 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/{docname}?[0-{count-1}]' + r = curl.ftp_ssl_get(urls=[url], with_stats=True, extra_args=[ + '--parallel' + ]) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + @pytest.mark.parametrize("docname", [ + 'upload-1k', 'upload-100k', 'upload-1m' + ]) + def test_31_05_upload_1(self, env: Env, vsftpds: VsFTPD, docname, repeat): + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpds.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_upload(urls=[url], fupload=f'{srcfile}', with_stats=True) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpds, docname=docname) + + def _rmf(self, path): + if os.path.exists(path): + return os.remove(path) + + # check with `tcpdump` if curl causes any TCP RST packets + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + def test_31_06_shutdownh_download(self, env: Env, vsftpds: VsFTPD, repeat): + docname = 'data-1k' + curl = CurlClient(env=env) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/{docname}?[0-{count-1}]' + r = curl.ftp_ssl_get(urls=[url], with_stats=True, with_tcpdump=True) + r.check_stats(count=count, http_status=226) + # vsftp closes control connection without niceties, + # disregard RST packets it sent from its port to curl + assert len(r.tcpdump.stats_excluding(src_port=env.ftps_port)) == 0, f'Unexpected TCP RSTs packets' + + # check with `tcpdump` if curl causes any TCP RST packets + @pytest.mark.skipif(condition=not Env.tcpdump(), reason="tcpdump not available") + def test_31_07_shutdownh_upload(self, env: Env, vsftpds: VsFTPD, repeat): + docname = 'upload-1k' + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpds.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, with_tcpdump=True) + r.check_stats(count=count, http_status=226) + # vsftp closes control connection without niceties, + # disregard RST packets it sent from its port to curl + assert len(r.tcpdump.stats_excluding(src_port=env.ftps_port)) == 0, f'Unexpected TCP RSTs packets' + + def test_31_08_upload_ascii(self, env: Env, vsftpds: VsFTPD): + docname = 'upload-ascii' + line_length = 21 + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpds.docs_dir, docname) + env.make_data_file(indir=env.gen_dir, fname=docname, fsize=100*1024, + line_length=line_length) + srcsize = os.path.getsize(srcfile) + self._rmf(dstfile) + count = 1 + curl = CurlClient(env=env) + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, + extra_args=['--use-ascii']) + r.check_stats(count=count, http_status=226) + # expect the uploaded file to be number of converted newlines larger + dstsize = os.path.getsize(dstfile) + newlines = len(open(srcfile).readlines()) + assert (srcsize + newlines) == dstsize, \ + f'expected source with {newlines} lines to be that much larger,'\ + f'instead srcsize={srcsize}, upload size={dstsize}, diff={dstsize-srcsize}' + + def test_31_08_active_download(self, env: Env, vsftpds: VsFTPD): + docname = 'data-10k' + curl = CurlClient(env=env) + srcfile = os.path.join(vsftpds.docs_dir, f'{docname}') + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/{docname}?[0-{count-1}]' + r = curl.ftp_ssl_get(urls=[url], with_stats=True, extra_args=[ + '--ftp-port', '127.0.0.1' + ]) + r.check_stats(count=count, http_status=226) + self.check_downloads(curl, srcfile, count) + + def test_31_09_active_upload(self, env: Env, vsftpds: VsFTPD): + docname = 'upload-1k' + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpds.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpds.port}/' + r = curl.ftp_ssl_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, extra_args=[ + '--ftp-port', '127.0.0.1' + ]) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpds, docname=docname) + + def check_downloads(self, client, srcfile: str, count: int, + complete: bool = True): + for i in range(count): + dfile = client.download_file(i) + assert os.path.exists(dfile) + if complete and not filecmp.cmp(srcfile, dfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dfile).readlines(), + fromfile=srcfile, + tofile=dfile, + n=1)) + assert False, f'download {dfile} differs:\n{diff}' + + def check_upload(self, env, vsftpd: VsFTPD, docname): + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + assert os.path.exists(srcfile) + assert os.path.exists(dstfile) + if not filecmp.cmp(srcfile, dstfile, shallow=False): + diff = "".join(difflib.unified_diff(a=open(srcfile).readlines(), + b=open(dstfile).readlines(), + fromfile=srcfile, + tofile=dstfile, + n=1)) + assert False, f'upload {dstfile} differs:\n{diff}' diff --git a/tests/http/testenv/client.py b/tests/http/testenv/client.py index e8ffb040a..0a0030c75 100644 --- a/tests/http/testenv/client.py +++ b/tests/http/testenv/client.py @@ -50,7 +50,7 @@ def __init__(self, name: str, env: Env, run_dir: Optional[str] = None, self.name = name self.path = os.path.join(env.project_dir, f'tests/http/clients/{name}') self.env = env - self._run_env= run_env + self._run_env = run_env self._timeout = timeout if timeout else env.test_timeout self._curl = os.environ['CURL'] if 'CURL' in os.environ else env.curl self._run_dir = run_dir if run_dir else os.path.join(env.gen_dir, name) @@ -92,12 +92,18 @@ def run(self, args): exception = None myargs = [self.path] myargs.extend(args) + run_env = None + if self._run_env: + run_env = self._run_env.copy() + for key in ['CURL_DEBUG']: + if key in os.environ and key not in run_env: + run_env[key] = os.environ[key] try: with open(self._stdoutfile, 'w') as cout: with open(self._stderrfile, 'w') as cerr: p = subprocess.run(myargs, stderr=cerr, stdout=cout, cwd=self._run_dir, shell=False, - input=None, env=self._run_env, + input=None, env=run_env, timeout=self._timeout) exitcode = p.returncode except subprocess.TimeoutExpired: diff --git a/tests/http/testenv/curl.py b/tests/http/testenv/curl.py index f89b2c9a8..65caeb784 100644 --- a/tests/http/testenv/curl.py +++ b/tests/http/testenv/curl.py @@ -390,7 +390,9 @@ def check_response(self, http_status: Optional[int] = 200, f'were made\n{self.dump_logs()}' def check_stats(self, count: int, http_status: Optional[int] = None, - exitcode: Optional[int] = None): + exitcode: Optional[int] = None, + remote_port: Optional[int] = None, + remote_ip: Optional[str] = None): if exitcode is None: self.check_exit_code(0) assert len(self.stats) == count, \ @@ -408,6 +410,18 @@ def check_stats(self, count: int, http_status: Optional[int] = None, assert x['exitcode'] == exitcode, \ f'status #{idx} exitcode: expected {exitcode}, '\ f'got {x["exitcode"]}\n{self.dump_stat(x)}' + if remote_port is not None: + for idx, x in enumerate(self.stats): + assert 'remote_port' in x, f'remote_port missing\n{self.dump_stat(x)}' + assert x['remote_port'] == remote_port, \ + f'status #{idx} remote_port: expected {remote_port}, '\ + f'got {x["remote_port"]}\n{self.dump_stat(x)}' + if remote_ip is not None: + for idx, x in enumerate(self.stats): + assert 'remote_ip' in x, f'remote_ip missing\n{self.dump_stat(x)}' + assert x['remote_ip'] == remote_ip, \ + f'status #{idx} remote_ip: expected {remote_ip}, '\ + f'got {x["remote_ip"]}\n{self.dump_stat(x)}' def dump_logs(self): lines = ['>>--stdout ----------------------------------------------\n'] @@ -824,6 +838,9 @@ def _complete_args(self, urls, timeout=None, options=None, urls = [urls] args = [self._curl, "-s", "--path-as-is"] + if 'CURL_TEST_EVENT' in os.environ: + args.append('--test-event') + if with_headers: args.extend(["-D", self._headerfile]) if def_tracing is not False and not self._silent: diff --git a/tests/http/testenv/env.py b/tests/http/testenv/env.py index 2cd643236..be15ea4c6 100644 --- a/tests/http/testenv/env.py +++ b/tests/http/testenv/env.py @@ -552,26 +552,32 @@ def slow_network(self) -> bool: def ci_run(self) -> bool: return "CURL_CI" in os.environ - def authority_for(self, domain: str, alpn_proto: Optional[str] = None): + def port_for(self, alpn_proto: Optional[str] = None): if alpn_proto is None or \ alpn_proto in ['h2', 'http/1.1', 'http/1.0', 'http/0.9']: - return f'{domain}:{self.https_port}' + return self.https_port if alpn_proto in ['h3']: - return f'{domain}:{self.h3_port}' - return f'{domain}:{self.http_port}' + return self.h3_port + return self.http_port + + def authority_for(self, domain: str, alpn_proto: Optional[str] = None): + return f'{domain}:{self.port_for(alpn_proto=alpn_proto)}' - def make_data_file(self, indir: str, fname: str, fsize: int) -> str: + def make_data_file(self, indir: str, fname: str, fsize: int, + line_length: int = 1024) -> str: + if line_length < 11: + raise 'line_length less than 11 not supported' fpath = os.path.join(indir, fname) s10 = "0123456789" - s = (101 * s10) + s10[0:3] + s = round((line_length / 10) + 1) * s10 + s = s[0:line_length-11] with open(fpath, 'w') as fd: - for i in range(int(fsize / 1024)): + for i in range(int(fsize / line_length)): fd.write(f"{i:09d}-{s}\n") - remain = int(fsize % 1024) + remain = int(fsize % line_length) if remain != 0: - i = int(fsize / 1024) + 1 - s = f"{i:09d}-{s}\n" - fd.write(s[0:remain]) + i = int(fsize / line_length) + 1 + fd.write(f"{i:09d}-{s}"[0:remain-1] + "\n") return fpath def make_clients(self): diff --git a/tests/http/testenv/httpd.py b/tests/http/testenv/httpd.py index 4771ea360..d5ed551be 100644 --- a/tests/http/testenv/httpd.py +++ b/tests/http/testenv/httpd.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -#!/usr/bin/env python3 # -*- coding: utf-8 -*- #*************************************************************************** # _ _ ____ _ @@ -33,6 +32,7 @@ from json import JSONEncoder import time from typing import List, Union, Optional +import copy from .curl import CurlClient, ExecResult from .env import Env @@ -79,6 +79,7 @@ def __init__(self, env: Env, proxy_auth: bool = False): self._auth_digest = True self._proxy_auth_basic = proxy_auth self._extra_configs = {} + self._loaded_extra_configs = None assert env.apxs p = subprocess.run(args=[env.apxs, '-q', 'libexecdir'], capture_output=True, text=True) @@ -152,10 +153,12 @@ def start(self): if r.exit_code != 0: log.error(f'failed to start httpd: {r}') return False + self._loaded_extra_configs = copy.deepcopy(self._extra_configs) return self.wait_live(timeout=timedelta(seconds=5)) def stop(self): r = self._apachectl('stop') + self._loaded_extra_configs = None if r.exit_code == 0: return self.wait_dead(timeout=timedelta(seconds=5)) log.fatal(f'stopping httpd failed: {r}') @@ -168,10 +171,17 @@ def restart(self): def reload(self): self._write_config() r = self._apachectl("graceful") + self._loaded_extra_configs = None if r.exit_code != 0: log.error(f'failed to reload httpd: {r}') + self._loaded_extra_configs = copy.deepcopy(self._extra_configs) return self.wait_live(timeout=timedelta(seconds=5)) + def reload_if_config_changed(self): + if self._loaded_extra_configs == self._extra_configs: + return True + return self.reload() + def wait_dead(self, timeout: timedelta): curl = CurlClient(env=self.env, run_dir=self._tmp_dir) try_until = datetime.now() + timeout @@ -250,20 +260,12 @@ def _write_config(self): f'ReadBufferSize 16000', f'H2MinWorkers 16', f'H2MaxWorkers 256', - f'H2Direct on', f'Listen {self.env.http_port}', f'Listen {self.env.https_port}', f'Listen {self.env.proxy_port}', f'Listen {self.env.proxys_port}', f'TypesConfig "{self._conf_dir}/mime.types', f'SSLSessionCache "shmcb:ssl_gcache_data(32000)"', - (f'SSLCipherSuite SSL' - f' ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' - f':ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305' - ), - (f'SSLCipherSuite TLSv1.3' - f' TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256' - ), ] if 'base' in self._extra_configs: conf.extend(self._extra_configs['base']) @@ -273,6 +275,7 @@ def _write_config(self): f' ServerAlias localhost', f' DocumentRoot "{self._docs_dir}"', f' Protocols h2c http/1.1', + f' H2Direct on', ]) conf.extend(self._curltest_conf(domain1)) conf.extend([ diff --git a/tests/http/testenv/mod_curltest/mod_curltest.c b/tests/http/testenv/mod_curltest/mod_curltest.c index 58b952563..af9c4f2a2 100644 --- a/tests/http/testenv/mod_curltest/mod_curltest.c +++ b/tests/http/testenv/mod_curltest/mod_curltest.c @@ -42,7 +42,8 @@ static int curltest_tweak_handler(request_rec *r); static int curltest_1_1_required(request_rec *r); static int curltest_sslinfo_handler(request_rec *r); -AP_DECLARE_MODULE(curltest) = { +AP_DECLARE_MODULE(curltest) = +{ STANDARD20_MODULE_STUFF, NULL, /* func to create per dir config */ NULL, /* func to merge per dir config */ @@ -95,8 +96,8 @@ static void curltest_hooks(apr_pool_t *pool) #define SECS_PER_HOUR (60*60) #define SECS_PER_DAY (24*SECS_PER_HOUR) -static apr_status_t duration_parse(apr_interval_time_t *ptimeout, const char *value, - const char *def_unit) +static apr_status_t duration_parse(apr_interval_time_t *ptimeout, + const char *value, const char *def_unit) { char *endp; apr_int64_t n; @@ -106,7 +107,8 @@ static apr_status_t duration_parse(apr_interval_time_t *ptimeout, const char *va return errno; } if(!endp || !*endp) { - if (!def_unit) def_unit = "s"; + if(!def_unit) + def_unit = "s"; } else if(endp == value) { return APR_EINVAL; @@ -202,7 +204,7 @@ static int curltest_echo_handler(request_rec *r) int i; args = apr_cstr_split(r->args, "&", 1, r->pool); for(i = 0; i < args->nelts; ++i) { - char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*); + char *s, *val, *arg = APR_ARRAY_IDX(args, i, char *); s = strchr(arg, '='); if(s) { *s = '\0'; @@ -254,7 +256,9 @@ static int curltest_echo_handler(request_rec *r) bb = apr_brigade_create(r->pool, c->bucket_alloc); /* copy any request body into the response */ - if((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) goto cleanup; + rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); + if(rv) + goto cleanup; if(die_after_100) { ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "echo_handler: dying after 100-continue"); @@ -278,9 +282,11 @@ static int curltest_echo_handler(request_rec *r) ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: copying %ld bytes from request body", l); rv = apr_brigade_write(bb, NULL, NULL, buffer, l); - if (APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; rv = ap_pass_brigade(r->output_filters, bb); - if (APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "echo_handler: passed %ld bytes from request body", l); } @@ -344,7 +350,7 @@ static int curltest_tweak_handler(request_rec *r) if(r->args) { args = apr_cstr_split(r->args, "&", 1, r->pool); for(i = 0; i < args->nelts; ++i) { - char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*); + char *s, *val, *arg = APR_ARRAY_IDX(args, i, char *); s = strchr(arg, '='); if(s) { *s = '\0'; @@ -434,7 +440,7 @@ static int curltest_tweak_handler(request_rec *r) "request, %s", r->args? r->args : "(no args)"); r->status = http_status; r->clength = with_cl? (chunks * chunk_size) : -1; - r->chunked = (r->proto_num >= HTTP_VERSION(1,1)) && !with_cl; + r->chunked = (r->proto_num >= HTTP_VERSION(1, 1)) && !with_cl; apr_table_setn(r->headers_out, "request-id", request_id); if(r->clength >= 0) { apr_table_set(r->headers_out, "Content-Length", @@ -460,7 +466,8 @@ static int curltest_tweak_handler(request_rec *r) b = apr_bucket_flush_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); rv = ap_pass_brigade(r->output_filters, bb); - if (APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; memset(buffer, 'X', sizeof(buffer)); for(i = 0; i < chunks; ++i) { @@ -468,9 +475,11 @@ static int curltest_tweak_handler(request_rec *r) apr_sleep(chunk_delay); } rv = apr_brigade_write(bb, NULL, NULL, buffer, chunk_size); - if(APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; rv = ap_pass_brigade(r->output_filters, bb); - if(APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "error_handler: passed %lu bytes as response body", (unsigned long)chunk_size); @@ -542,7 +551,7 @@ static int curltest_put_handler(request_rec *r) if(r->args) { args = apr_cstr_split(r->args, "&", 1, r->pool); for(i = 0; i < args->nelts; ++i) { - char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*); + char *s, *val, *arg = APR_ARRAY_IDX(args, i, char *); s = strchr(arg, '='); if(s) { *s = '\0'; @@ -591,7 +600,9 @@ static int curltest_put_handler(request_rec *r) } bb = apr_brigade_create(r->pool, c->bucket_alloc); /* copy any request body into the response */ - if((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) goto cleanup; + rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); + if(rv) + goto cleanup; if(ap_should_client_block(r)) { while(0 < (l = ap_get_client_block(r, &buffer[0], sizeof(buffer)))) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, @@ -606,7 +617,8 @@ static int curltest_put_handler(request_rec *r) s_rbody_len = apr_psprintf(r->pool, "%"APR_OFF_T_FMT, rbody_len); apr_table_setn(r->headers_out, "Received-Length", s_rbody_len); rv = apr_brigade_puts(bb, NULL, NULL, s_rbody_len); - if(APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "put_handler: request read"); @@ -646,7 +658,7 @@ static int curltest_1_1_required(request_rec *r) return DECLINED; } - if (HTTP_VERSION_MAJOR(r->proto_num) > 1) { + if(HTTP_VERSION_MAJOR(r->proto_num) > 1) { apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "1"); ap_die(HTTP_FORBIDDEN, r); return OK; @@ -670,11 +682,13 @@ static int curltest_1_1_required(request_rec *r) b = apr_bucket_flush_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); rv = ap_pass_brigade(r->output_filters, bb); - if (APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; /* we are done */ rv = apr_brigade_printf(bb, NULL, NULL, "well done!"); - if(APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "1_1_handler: request read"); @@ -728,7 +742,7 @@ static int curltest_sslinfo_handler(request_rec *r) if(r->args) { apr_array_header_t *args = apr_cstr_split(r->args, "&", 1, r->pool); for(i = 0; i < args->nelts; ++i) { - char *s, *val, *arg = APR_ARRAY_IDX(args, i, char*); + char *s, *val, *arg = APR_ARRAY_IDX(args, i, char *); s = strchr(arg, '='); if(s) { *s = '\0'; @@ -781,7 +795,8 @@ static int curltest_sslinfo_handler(request_rec *r) b = apr_bucket_flush_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); rv = ap_pass_brigade(r->output_filters, bb); - if (APR_SUCCESS != rv) goto cleanup; + if(APR_SUCCESS != rv) + goto cleanup; /* we are done */ b = apr_bucket_eos_create(c->bucket_alloc); diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt index b2a352046..965e3dffe 100644 --- a/tests/libtest/CMakeLists.txt +++ b/tests/libtest/CMakeLists.txt @@ -21,67 +21,42 @@ # SPDX-License-Identifier: curl # ########################################################################### -set(TARGET_LABEL_PREFIX "Test ") - -function(setup_test TEST_NAME) # ARGN are the files in the test - - if(LIB_SELECTED STREQUAL LIB_STATIC) - # These are part of the libcurl static lib. Do not compile/link them again. - list(REMOVE_ITEM ARGN ${WARNLESS} ${MULTIBYTE} ${TIMEDIFF}) - endif() - - add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN}) - add_dependencies(testdeps ${TEST_NAME}) - string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME) - - include_directories( - ${CURL_SOURCE_DIR}/lib # for "curl_setup_once.h" - ${CURL_BINARY_DIR}/lib # for "curl_config.h" - ${CURL_BINARY_DIR}/include # for "curl/curl.h" - ${CURL_SOURCE_DIR}/tests/libtest # to be able to build generated tests - ) - if(USE_ARES) - include_directories(${CARES_INCLUDE_DIR}) - endif() - - target_link_libraries(${TEST_NAME} ${LIB_SELECTED} ${CURL_LIBS}) - - set_target_properties(${TEST_NAME} - PROPERTIES COMPILE_DEFINITIONS ${UPPER_TEST_NAME}) - set_target_properties(${TEST_NAME} - PROPERTIES PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}") -endfunction() - +# Get 'noinst_PROGRAMS', '*_SOURCES', WARNLESS, MULTIBYTE, TIMEDIFF variables transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -foreach(TEST_NAME ${noinst_PROGRAMS}) - if(DEFINED ${TEST_NAME}_SOURCES) - setup_test(${TEST_NAME} ${${TEST_NAME}_SOURCES}) +foreach(_target IN LISTS noinst_PROGRAMS) + if(DEFINED ${_target}_SOURCES) + set(_sources ${${_target}_SOURCES}) else() - setup_test(${TEST_NAME} ${nodist_${TEST_NAME}_SOURCES}) + set(_sources ${nodist_${_target}_SOURCES}) endif() -endforeach() -# Allows for hostname override to make tests machine independent. -# TODO this cmake build assumes a shared build, detect static linking here! -if(NOT WIN32) - add_library(hostname MODULE EXCLUDE_FROM_ALL sethostname.c) - add_dependencies(testdeps hostname) - # Output to .libs for compatibility with autotools, the test data expects a - # library at (tests)/libtest/.libs/libhostname.so - set_target_properties(hostname PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.libs) - if(HIDES_CURL_PRIVATE_SYMBOLS) - set_property(TARGET hostname APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") - set_property(TARGET hostname APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE}) + if(LIB_SELECTED STREQUAL LIB_STATIC) + # These are part of the libcurl static lib. Do not compile/link them again. + list(REMOVE_ITEM _sources ${WARNLESS} ${MULTIBYTE} ${TIMEDIFF} ${THREADS}) endif() -endif() + + string(TOUPPER ${_target} _upper_target) + set(_target_name "${_target}") + add_executable(${_target_name} EXCLUDE_FROM_ALL ${_sources}) + add_dependencies(testdeps ${_target_name}) + target_link_libraries(${_target_name} ${LIB_SELECTED} ${CURL_LIBS}) + target_include_directories(${_target_name} PRIVATE + "${CURL_BINARY_DIR}/lib" # for "curl_config.h" + "${CURL_SOURCE_DIR}/lib" # for "curl_setup.h" + "${CURL_SOURCE_DIR}/tests/libtest" # to be able to build generated tests + ) + set_target_properties(${_target_name} PROPERTIES + COMPILE_DEFINITIONS ${_upper_target} + OUTPUT_NAME "${_target}" + PROJECT_LABEL "Test libtest ${_target}") +endforeach() add_custom_command( - OUTPUT lib1521.c - COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/mk-lib1521.pl < ${CURL_SOURCE_DIR}/include/curl/curl.h > lib1521.c + OUTPUT "lib1521.c" + COMMAND ${PERL_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/mk-lib1521.pl" < "${CURL_SOURCE_DIR}/include/curl/curl.h" > "lib1521.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/mk-lib1521.pl" "${CURL_SOURCE_DIR}/include/curl/curl.h" diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am index eed916eeb..2e360cad4 100644 --- a/tests/libtest/Makefile.am +++ b/tests/libtest/Makefile.am @@ -37,7 +37,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ -I$(top_srcdir)/lib EXTRA_DIST = test307.pl test610.pl test613.pl test1013.pl test1022.pl \ - Makefile.inc notexists.pl CMakeLists.txt mk-lib1521.pl .checksrc + notexists.pl CMakeLists.txt mk-lib1521.pl .checksrc CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ @@ -48,13 +48,8 @@ CLEANFILES = lib1521.c # Prevent LIBS from being used for all link targets LIBS = $(BLANK_AT_MAKETIME) -if USE_EXPLICIT_LIB_DEPS -SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ -TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ -else -SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ -TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ -endif +SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ +TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # Dependencies (may need to be overridden) LDADD = $(SUPPORTFILES_LIBS) @@ -63,14 +58,7 @@ LDADD = $(SUPPORTFILES_LIBS) # noinst_PROGRAMS, lib*_SOURCES, and lib*_CFLAGS) include Makefile.inc -# Preloading of libhostname allows host name overriding, -# this is used to make some tests machine independent. - -if BUILD_LIBHOSTNAME -noinst_LTLIBRARIES = libhostname.la -else noinst_LTLIBRARIES = -endif if USE_CPPFLAG_CURL_STATICLIB AM_CPPFLAGS += -DCURL_STATICLIB @@ -79,35 +67,12 @@ endif AM_LDFLAGS = AM_CFLAGS = -libhostname_la_CPPFLAGS_EXTRA = -libhostname_la_LDFLAGS_EXTRA = -module -avoid-version -rpath /nowhere -libhostname_la_CFLAGS_EXTRA = - libstubgss_la_LDFLAGS_EXTRA = if CURL_LT_SHLIB_USE_NO_UNDEFINED -libhostname_la_LDFLAGS_EXTRA += -no-undefined libstubgss_la_LDFLAGS_EXTRA += -no-undefined endif -if CURL_LT_SHLIB_USE_MIMPURE_TEXT -libhostname_la_LDFLAGS_EXTRA += -mimpure-text -endif - -if DOING_CURL_SYMBOL_HIDING -libhostname_la_CPPFLAGS_EXTRA += -DCURL_HIDDEN_SYMBOLS -libhostname_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING) -endif - -libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) $(libhostname_la_CPPFLAGS_EXTRA) -libhostname_la_LDFLAGS = $(AM_LDFLAGS) $(libhostname_la_LDFLAGS_EXTRA) -libhostname_la_CFLAGS = $(AM_CFLAGS) $(libhostname_la_CFLAGS_EXTRA) - -libhostname_la_SOURCES = sethostname.c - -libhostname_la_LIBADD = -libhostname_la_DEPENDENCIES = - # Build a stub gssapi implementation for testing if BUILD_STUB_GSS noinst_LTLIBRARIES += libstubgss.la diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in index 45221cd78..b419a94fb 100644 --- a/tests/libtest/Makefile.in +++ b/tests/libtest/Makefile.in @@ -89,94 +89,90 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -noinst_PROGRAMS = chkhostname$(EXEEXT) libauthretry$(EXEEXT) \ - libntlmconnect$(EXEEXT) libprereq$(EXEEXT) lib500$(EXEEXT) \ - lib501$(EXEEXT) lib502$(EXEEXT) lib503$(EXEEXT) \ - lib504$(EXEEXT) lib505$(EXEEXT) lib506$(EXEEXT) \ - lib507$(EXEEXT) lib508$(EXEEXT) lib509$(EXEEXT) \ - lib510$(EXEEXT) lib511$(EXEEXT) lib512$(EXEEXT) \ - lib513$(EXEEXT) lib514$(EXEEXT) lib515$(EXEEXT) \ - lib516$(EXEEXT) lib517$(EXEEXT) lib518$(EXEEXT) \ - lib519$(EXEEXT) lib520$(EXEEXT) lib521$(EXEEXT) \ - lib523$(EXEEXT) lib524$(EXEEXT) lib525$(EXEEXT) \ - lib526$(EXEEXT) lib527$(EXEEXT) lib529$(EXEEXT) \ - lib530$(EXEEXT) lib532$(EXEEXT) lib533$(EXEEXT) \ - lib536$(EXEEXT) lib537$(EXEEXT) lib539$(EXEEXT) \ - lib540$(EXEEXT) lib541$(EXEEXT) lib542$(EXEEXT) \ - lib543$(EXEEXT) lib544$(EXEEXT) lib545$(EXEEXT) \ - lib547$(EXEEXT) lib548$(EXEEXT) lib549$(EXEEXT) \ - lib552$(EXEEXT) lib553$(EXEEXT) lib554$(EXEEXT) \ - lib555$(EXEEXT) lib556$(EXEEXT) lib557$(EXEEXT) \ - lib558$(EXEEXT) lib559$(EXEEXT) lib560$(EXEEXT) \ - lib562$(EXEEXT) lib564$(EXEEXT) lib565$(EXEEXT) \ - lib566$(EXEEXT) lib567$(EXEEXT) lib568$(EXEEXT) \ - lib569$(EXEEXT) lib570$(EXEEXT) lib571$(EXEEXT) \ - lib572$(EXEEXT) lib573$(EXEEXT) lib574$(EXEEXT) \ - lib575$(EXEEXT) lib576$(EXEEXT) lib578$(EXEEXT) \ - lib579$(EXEEXT) lib582$(EXEEXT) lib583$(EXEEXT) \ - lib584$(EXEEXT) lib585$(EXEEXT) lib586$(EXEEXT) \ - lib587$(EXEEXT) lib589$(EXEEXT) lib590$(EXEEXT) \ - lib591$(EXEEXT) lib597$(EXEEXT) lib598$(EXEEXT) \ - lib599$(EXEEXT) lib643$(EXEEXT) lib645$(EXEEXT) \ - lib650$(EXEEXT) lib651$(EXEEXT) lib652$(EXEEXT) \ - lib653$(EXEEXT) lib654$(EXEEXT) lib655$(EXEEXT) \ - lib658$(EXEEXT) lib659$(EXEEXT) lib661$(EXEEXT) \ - lib666$(EXEEXT) lib667$(EXEEXT) lib668$(EXEEXT) \ - lib670$(EXEEXT) lib671$(EXEEXT) lib672$(EXEEXT) \ - lib673$(EXEEXT) lib674$(EXEEXT) lib676$(EXEEXT) \ - lib677$(EXEEXT) lib678$(EXEEXT) lib1156$(EXEEXT) \ - lib1301$(EXEEXT) lib1485$(EXEEXT) lib1500$(EXEEXT) \ - lib1501$(EXEEXT) lib1502$(EXEEXT) lib1503$(EXEEXT) \ - lib1504$(EXEEXT) lib1505$(EXEEXT) lib1506$(EXEEXT) \ - lib1507$(EXEEXT) lib1508$(EXEEXT) lib1509$(EXEEXT) \ - lib1510$(EXEEXT) lib1511$(EXEEXT) lib1512$(EXEEXT) \ - lib1513$(EXEEXT) lib1514$(EXEEXT) lib1515$(EXEEXT) \ - lib1517$(EXEEXT) lib1518$(EXEEXT) lib1520$(EXEEXT) \ - lib1521$(EXEEXT) lib1522$(EXEEXT) lib1523$(EXEEXT) \ - lib1525$(EXEEXT) lib1526$(EXEEXT) lib1527$(EXEEXT) \ - lib1528$(EXEEXT) lib1529$(EXEEXT) lib1530$(EXEEXT) \ - lib1531$(EXEEXT) lib1532$(EXEEXT) lib1533$(EXEEXT) \ - lib1534$(EXEEXT) lib1535$(EXEEXT) lib1536$(EXEEXT) \ - lib1537$(EXEEXT) lib1538$(EXEEXT) lib1539$(EXEEXT) \ - lib1540$(EXEEXT) lib1541$(EXEEXT) lib1542$(EXEEXT) \ - lib1543$(EXEEXT) lib1545$(EXEEXT) lib1550$(EXEEXT) \ - lib1551$(EXEEXT) lib1552$(EXEEXT) lib1553$(EXEEXT) \ - lib1554$(EXEEXT) lib1555$(EXEEXT) lib1556$(EXEEXT) \ - lib1557$(EXEEXT) lib1558$(EXEEXT) lib1559$(EXEEXT) \ - lib1560$(EXEEXT) lib1564$(EXEEXT) lib1565$(EXEEXT) \ - lib1567$(EXEEXT) lib1568$(EXEEXT) lib1569$(EXEEXT) \ - lib1591$(EXEEXT) lib1592$(EXEEXT) lib1593$(EXEEXT) \ - lib1594$(EXEEXT) lib1596$(EXEEXT) lib1597$(EXEEXT) \ - lib1598$(EXEEXT) lib1662$(EXEEXT) lib1900$(EXEEXT) \ - lib1901$(EXEEXT) lib1903$(EXEEXT) lib1905$(EXEEXT) \ - lib1906$(EXEEXT) lib1907$(EXEEXT) lib1908$(EXEEXT) \ - lib1910$(EXEEXT) lib1911$(EXEEXT) lib1912$(EXEEXT) \ - lib1913$(EXEEXT) lib1915$(EXEEXT) lib1916$(EXEEXT) \ - lib1917$(EXEEXT) lib1918$(EXEEXT) lib1919$(EXEEXT) \ - lib1933$(EXEEXT) lib1934$(EXEEXT) lib1935$(EXEEXT) \ - lib1936$(EXEEXT) lib1937$(EXEEXT) lib1938$(EXEEXT) \ - lib1939$(EXEEXT) lib1940$(EXEEXT) lib1945$(EXEEXT) \ - lib1946$(EXEEXT) lib1947$(EXEEXT) lib1948$(EXEEXT) \ - lib1955$(EXEEXT) lib1956$(EXEEXT) lib1957$(EXEEXT) \ - lib1958$(EXEEXT) lib1959$(EXEEXT) lib1960$(EXEEXT) \ - lib1964$(EXEEXT) lib1970$(EXEEXT) lib1971$(EXEEXT) \ - lib1972$(EXEEXT) lib1973$(EXEEXT) lib1974$(EXEEXT) \ - lib1975$(EXEEXT) lib2301$(EXEEXT) lib2302$(EXEEXT) \ - lib2304$(EXEEXT) lib2305$(EXEEXT) lib2306$(EXEEXT) \ - lib2308$(EXEEXT) lib2402$(EXEEXT) lib2404$(EXEEXT) \ - lib2405$(EXEEXT) lib2502$(EXEEXT) lib3010$(EXEEXT) \ - lib3025$(EXEEXT) lib3026$(EXEEXT) lib3027$(EXEEXT) \ - lib3100$(EXEEXT) lib3101$(EXEEXT) lib3102$(EXEEXT) \ - lib3103$(EXEEXT) +noinst_PROGRAMS = libauthretry$(EXEEXT) libntlmconnect$(EXEEXT) \ + libprereq$(EXEEXT) lib500$(EXEEXT) lib501$(EXEEXT) \ + lib502$(EXEEXT) lib503$(EXEEXT) lib504$(EXEEXT) \ + lib505$(EXEEXT) lib506$(EXEEXT) lib507$(EXEEXT) \ + lib508$(EXEEXT) lib509$(EXEEXT) lib510$(EXEEXT) \ + lib511$(EXEEXT) lib512$(EXEEXT) lib513$(EXEEXT) \ + lib514$(EXEEXT) lib515$(EXEEXT) lib516$(EXEEXT) \ + lib517$(EXEEXT) lib518$(EXEEXT) lib519$(EXEEXT) \ + lib520$(EXEEXT) lib521$(EXEEXT) lib523$(EXEEXT) \ + lib524$(EXEEXT) lib525$(EXEEXT) lib526$(EXEEXT) \ + lib527$(EXEEXT) lib529$(EXEEXT) lib530$(EXEEXT) \ + lib532$(EXEEXT) lib533$(EXEEXT) lib536$(EXEEXT) \ + lib537$(EXEEXT) lib539$(EXEEXT) lib540$(EXEEXT) \ + lib541$(EXEEXT) lib542$(EXEEXT) lib543$(EXEEXT) \ + lib544$(EXEEXT) lib545$(EXEEXT) lib547$(EXEEXT) \ + lib548$(EXEEXT) lib549$(EXEEXT) lib552$(EXEEXT) \ + lib553$(EXEEXT) lib554$(EXEEXT) lib555$(EXEEXT) \ + lib556$(EXEEXT) lib557$(EXEEXT) lib558$(EXEEXT) \ + lib559$(EXEEXT) lib560$(EXEEXT) lib562$(EXEEXT) \ + lib564$(EXEEXT) lib565$(EXEEXT) lib566$(EXEEXT) \ + lib567$(EXEEXT) lib568$(EXEEXT) lib569$(EXEEXT) \ + lib570$(EXEEXT) lib571$(EXEEXT) lib572$(EXEEXT) \ + lib573$(EXEEXT) lib574$(EXEEXT) lib575$(EXEEXT) \ + lib576$(EXEEXT) lib578$(EXEEXT) lib579$(EXEEXT) \ + lib582$(EXEEXT) lib583$(EXEEXT) lib584$(EXEEXT) \ + lib585$(EXEEXT) lib586$(EXEEXT) lib587$(EXEEXT) \ + lib589$(EXEEXT) lib590$(EXEEXT) lib591$(EXEEXT) \ + lib597$(EXEEXT) lib598$(EXEEXT) lib599$(EXEEXT) \ + lib643$(EXEEXT) lib645$(EXEEXT) lib650$(EXEEXT) \ + lib651$(EXEEXT) lib652$(EXEEXT) lib653$(EXEEXT) \ + lib654$(EXEEXT) lib655$(EXEEXT) lib658$(EXEEXT) \ + lib659$(EXEEXT) lib661$(EXEEXT) lib666$(EXEEXT) \ + lib667$(EXEEXT) lib668$(EXEEXT) lib670$(EXEEXT) \ + lib671$(EXEEXT) lib672$(EXEEXT) lib673$(EXEEXT) \ + lib674$(EXEEXT) lib676$(EXEEXT) lib677$(EXEEXT) \ + lib678$(EXEEXT) lib1156$(EXEEXT) lib1301$(EXEEXT) \ + lib1485$(EXEEXT) lib1500$(EXEEXT) lib1501$(EXEEXT) \ + lib1502$(EXEEXT) lib1503$(EXEEXT) lib1504$(EXEEXT) \ + lib1505$(EXEEXT) lib1506$(EXEEXT) lib1507$(EXEEXT) \ + lib1508$(EXEEXT) lib1509$(EXEEXT) lib1510$(EXEEXT) \ + lib1511$(EXEEXT) lib1512$(EXEEXT) lib1513$(EXEEXT) \ + lib1514$(EXEEXT) lib1515$(EXEEXT) lib1517$(EXEEXT) \ + lib1518$(EXEEXT) lib1520$(EXEEXT) lib1521$(EXEEXT) \ + lib1522$(EXEEXT) lib1523$(EXEEXT) lib1525$(EXEEXT) \ + lib1526$(EXEEXT) lib1527$(EXEEXT) lib1528$(EXEEXT) \ + lib1529$(EXEEXT) lib1530$(EXEEXT) lib1531$(EXEEXT) \ + lib1532$(EXEEXT) lib1533$(EXEEXT) lib1534$(EXEEXT) \ + lib1535$(EXEEXT) lib1536$(EXEEXT) lib1537$(EXEEXT) \ + lib1538$(EXEEXT) lib1539$(EXEEXT) lib1540$(EXEEXT) \ + lib1541$(EXEEXT) lib1542$(EXEEXT) lib1543$(EXEEXT) \ + lib1545$(EXEEXT) lib1550$(EXEEXT) lib1551$(EXEEXT) \ + lib1552$(EXEEXT) lib1553$(EXEEXT) lib1554$(EXEEXT) \ + lib1555$(EXEEXT) lib1556$(EXEEXT) lib1557$(EXEEXT) \ + lib1558$(EXEEXT) lib1559$(EXEEXT) lib1560$(EXEEXT) \ + lib1564$(EXEEXT) lib1565$(EXEEXT) lib1567$(EXEEXT) \ + lib1568$(EXEEXT) lib1569$(EXEEXT) lib1591$(EXEEXT) \ + lib1592$(EXEEXT) lib1593$(EXEEXT) lib1594$(EXEEXT) \ + lib1596$(EXEEXT) lib1597$(EXEEXT) lib1598$(EXEEXT) \ + lib1662$(EXEEXT) lib1900$(EXEEXT) lib1901$(EXEEXT) \ + lib1903$(EXEEXT) lib1905$(EXEEXT) lib1906$(EXEEXT) \ + lib1907$(EXEEXT) lib1908$(EXEEXT) lib1910$(EXEEXT) \ + lib1911$(EXEEXT) lib1912$(EXEEXT) lib1913$(EXEEXT) \ + lib1915$(EXEEXT) lib1916$(EXEEXT) lib1917$(EXEEXT) \ + lib1918$(EXEEXT) lib1919$(EXEEXT) lib1933$(EXEEXT) \ + lib1934$(EXEEXT) lib1935$(EXEEXT) lib1936$(EXEEXT) \ + lib1937$(EXEEXT) lib1938$(EXEEXT) lib1939$(EXEEXT) \ + lib1940$(EXEEXT) lib1945$(EXEEXT) lib1946$(EXEEXT) \ + lib1947$(EXEEXT) lib1948$(EXEEXT) lib1955$(EXEEXT) \ + lib1956$(EXEEXT) lib1957$(EXEEXT) lib1958$(EXEEXT) \ + lib1959$(EXEEXT) lib1960$(EXEEXT) lib1964$(EXEEXT) \ + lib1970$(EXEEXT) lib1971$(EXEEXT) lib1972$(EXEEXT) \ + lib1973$(EXEEXT) lib1974$(EXEEXT) lib1975$(EXEEXT) \ + lib2301$(EXEEXT) lib2302$(EXEEXT) lib2304$(EXEEXT) \ + lib2305$(EXEEXT) lib2306$(EXEEXT) lib2308$(EXEEXT) \ + lib2402$(EXEEXT) lib2404$(EXEEXT) lib2405$(EXEEXT) \ + lib2502$(EXEEXT) lib3010$(EXEEXT) lib3025$(EXEEXT) \ + lib3026$(EXEEXT) lib3027$(EXEEXT) lib3100$(EXEEXT) \ + lib3101$(EXEEXT) lib3102$(EXEEXT) lib3103$(EXEEXT) \ + lib3207$(EXEEXT) @USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_1 = -DCURL_STATICLIB @CURL_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_2 = -no-undefined -@CURL_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_3 = -no-undefined -@CURL_LT_SHLIB_USE_MIMPURE_TEXT_TRUE@am__append_4 = -mimpure-text -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_5 = -DCURL_HIDDEN_SYMBOLS -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_6 = $(CFLAG_CURL_SYMBOL_HIDING) # Build a stub gssapi implementation for testing -@BUILD_STUB_GSS_TRUE@am__append_7 = libstubgss.la +@BUILD_STUB_GSS_TRUE@am__append_3 = libstubgss.la @BUILD_STUB_GSS_FALSE@libstubgss_la_DEPENDENCIES = subdir = tests/libtest ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -214,30 +210,19 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) -am_libhostname_la_OBJECTS = libhostname_la-sethostname.lo -libhostname_la_OBJECTS = $(am_libhostname_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libhostname_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libhostname_la_CFLAGS) $(CFLAGS) $(libhostname_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -@BUILD_LIBHOSTNAME_TRUE@am_libhostname_la_rpath = am__libstubgss_la_SOURCES_DIST = stub_gssapi.c stub_gssapi.h @BUILD_STUB_GSS_TRUE@am_libstubgss_la_OBJECTS = \ @BUILD_STUB_GSS_TRUE@ libstubgss_la-stub_gssapi.lo libstubgss_la_OBJECTS = $(am_libstubgss_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = libstubgss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libstubgss_la_CFLAGS) \ $(CFLAGS) $(libstubgss_la_LDFLAGS) $(LDFLAGS) -o $@ -@BUILD_LIBHOSTNAME_FALSE@@BUILD_STUB_GSS_TRUE@am_libstubgss_la_rpath = -@BUILD_LIBHOSTNAME_TRUE@@BUILD_STUB_GSS_TRUE@am_libstubgss_la_rpath = +@BUILD_STUB_GSS_TRUE@am_libstubgss_la_rpath = am__dirstamp = $(am__leading_dot)dirstamp -am_chkhostname_OBJECTS = chkhostname.$(OBJEXT) \ - ../../lib/curl_gethostname.$(OBJEXT) -chkhostname_OBJECTS = $(am_chkhostname_OBJECTS) am__objects_1 = ../../lib/timediff.$(OBJEXT) am__objects_2 = $(am__objects_1) first.$(OBJEXT) am__objects_3 = testutil.$(OBJEXT) @@ -245,10 +230,7 @@ am__objects_4 = ../../lib/warnless.$(OBJEXT) am_lib1156_OBJECTS = lib1156.$(OBJEXT) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) lib1156_OBJECTS = $(am_lib1156_OBJECTS) -@USE_EXPLICIT_LIB_DEPS_FALSE@am__DEPENDENCIES_1 = \ -@USE_EXPLICIT_LIB_DEPS_FALSE@ $(top_builddir)/lib/libcurl.la -@USE_EXPLICIT_LIB_DEPS_TRUE@am__DEPENDENCIES_1 = \ -@USE_EXPLICIT_LIB_DEPS_TRUE@ $(top_builddir)/lib/libcurl.la +am__DEPENDENCIES_1 = $(top_builddir)/lib/libcurl.la lib1156_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib1301_OBJECTS = lib1301.$(OBJEXT) $(am__objects_2) \ $(am__objects_3) @@ -784,6 +766,12 @@ lib3102_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib3103_OBJECTS = lib3103.$(OBJEXT) $(am__objects_2) lib3103_OBJECTS = $(am_lib3103_OBJECTS) lib3103_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_42 = ../../lib/curl_threads.$(OBJEXT) +am_lib3207_OBJECTS = lib3207.$(OBJEXT) $(am__objects_2) \ + $(am__objects_3) $(am__objects_42) $(am__objects_4) \ + $(am__objects_41) +lib3207_OBJECTS = $(am_lib3207_OBJECTS) +lib3207_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib500_OBJECTS = lib500.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ $(am__objects_23) $(am__objects_41) lib500_OBJECTS = $(am_lib500_OBJECTS) @@ -886,41 +874,41 @@ am_lib525_OBJECTS = lib525.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_41) lib525_OBJECTS = $(am_lib525_OBJECTS) lib525_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_42 = ../../lib/lib526-timediff.$(OBJEXT) -am__objects_43 = $(am__objects_42) lib526-first.$(OBJEXT) -am__objects_44 = lib526-testutil.$(OBJEXT) -am__objects_45 = ../../lib/lib526-warnless.$(OBJEXT) -am_lib526_OBJECTS = lib526-lib526.$(OBJEXT) $(am__objects_43) \ - $(am__objects_44) $(am__objects_45) +am__objects_43 = ../../lib/lib526-timediff.$(OBJEXT) +am__objects_44 = $(am__objects_43) lib526-first.$(OBJEXT) +am__objects_45 = lib526-testutil.$(OBJEXT) +am__objects_46 = ../../lib/lib526-warnless.$(OBJEXT) +am_lib526_OBJECTS = lib526-lib526.$(OBJEXT) $(am__objects_44) \ + $(am__objects_45) $(am__objects_46) lib526_OBJECTS = $(am_lib526_OBJECTS) lib526_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_46 = ../../lib/lib527-timediff.$(OBJEXT) -am__objects_47 = $(am__objects_46) lib527-first.$(OBJEXT) -am__objects_48 = lib527-testutil.$(OBJEXT) -am__objects_49 = ../../lib/lib527-warnless.$(OBJEXT) -am_lib527_OBJECTS = lib527-lib526.$(OBJEXT) $(am__objects_47) \ - $(am__objects_48) $(am__objects_49) +am__objects_47 = ../../lib/lib527-timediff.$(OBJEXT) +am__objects_48 = $(am__objects_47) lib527-first.$(OBJEXT) +am__objects_49 = lib527-testutil.$(OBJEXT) +am__objects_50 = ../../lib/lib527-warnless.$(OBJEXT) +am_lib527_OBJECTS = lib527-lib526.$(OBJEXT) $(am__objects_48) \ + $(am__objects_49) $(am__objects_50) lib527_OBJECTS = $(am_lib527_OBJECTS) lib527_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_50 = ../../lib/lib529-timediff.$(OBJEXT) -am__objects_51 = $(am__objects_50) lib529-first.$(OBJEXT) -am__objects_52 = lib529-testutil.$(OBJEXT) -am__objects_53 = ../../lib/lib529-warnless.$(OBJEXT) -am__objects_54 = ../../lib/lib529-curl_multibyte.$(OBJEXT) -am_lib529_OBJECTS = lib529-lib525.$(OBJEXT) $(am__objects_51) \ - $(am__objects_52) $(am__objects_53) $(am__objects_54) +am__objects_51 = ../../lib/lib529-timediff.$(OBJEXT) +am__objects_52 = $(am__objects_51) lib529-first.$(OBJEXT) +am__objects_53 = lib529-testutil.$(OBJEXT) +am__objects_54 = ../../lib/lib529-warnless.$(OBJEXT) +am__objects_55 = ../../lib/lib529-curl_multibyte.$(OBJEXT) +am_lib529_OBJECTS = lib529-lib525.$(OBJEXT) $(am__objects_52) \ + $(am__objects_53) $(am__objects_54) $(am__objects_55) lib529_OBJECTS = $(am_lib529_OBJECTS) lib529_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib530_OBJECTS = lib530.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) lib530_OBJECTS = $(am_lib530_OBJECTS) lib530_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_55 = ../../lib/lib532-timediff.$(OBJEXT) -am__objects_56 = $(am__objects_55) lib532-first.$(OBJEXT) -am__objects_57 = lib532-testutil.$(OBJEXT) -am__objects_58 = ../../lib/lib532-warnless.$(OBJEXT) -am_lib532_OBJECTS = lib532-lib526.$(OBJEXT) $(am__objects_56) \ - $(am__objects_57) $(am__objects_58) +am__objects_56 = ../../lib/lib532-timediff.$(OBJEXT) +am__objects_57 = $(am__objects_56) lib532-first.$(OBJEXT) +am__objects_58 = lib532-testutil.$(OBJEXT) +am__objects_59 = ../../lib/lib532-warnless.$(OBJEXT) +am_lib532_OBJECTS = lib532-lib526.$(OBJEXT) $(am__objects_57) \ + $(am__objects_58) $(am__objects_59) lib532_OBJECTS = $(am_lib532_OBJECTS) lib532_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib533_OBJECTS = lib533.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ @@ -961,9 +949,9 @@ am_lib544_OBJECTS = lib544.$(OBJEXT) $(am__objects_2) lib544_OBJECTS = $(am_lib544_OBJECTS) lib544_LDADD = $(LDADD) lib544_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_59 = ../../lib/lib545-timediff.$(OBJEXT) -am__objects_60 = $(am__objects_59) lib545-first.$(OBJEXT) -am_lib545_OBJECTS = lib545-lib544.$(OBJEXT) $(am__objects_60) +am__objects_60 = ../../lib/lib545-timediff.$(OBJEXT) +am__objects_61 = $(am__objects_60) lib545-first.$(OBJEXT) +am_lib545_OBJECTS = lib545-lib544.$(OBJEXT) $(am__objects_61) lib545_OBJECTS = $(am_lib545_OBJECTS) lib545_LDADD = $(LDADD) lib545_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -971,9 +959,9 @@ am_lib547_OBJECTS = lib547.$(OBJEXT) $(am__objects_2) lib547_OBJECTS = $(am_lib547_OBJECTS) lib547_LDADD = $(LDADD) lib547_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_61 = ../../lib/lib548-timediff.$(OBJEXT) -am__objects_62 = $(am__objects_61) lib548-first.$(OBJEXT) -am_lib548_OBJECTS = lib548-lib547.$(OBJEXT) $(am__objects_62) +am__objects_62 = ../../lib/lib548-timediff.$(OBJEXT) +am__objects_63 = $(am__objects_62) lib548-first.$(OBJEXT) +am_lib548_OBJECTS = lib548-lib547.$(OBJEXT) $(am__objects_63) lib548_OBJECTS = $(am_lib548_OBJECTS) lib548_LDADD = $(LDADD) lib548_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -1025,9 +1013,9 @@ am_lib564_OBJECTS = lib564.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) lib564_OBJECTS = $(am_lib564_OBJECTS) lib564_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_63 = ../../lib/lib565-timediff.$(OBJEXT) -am__objects_64 = $(am__objects_63) lib565-first.$(OBJEXT) -am_lib565_OBJECTS = lib565-lib510.$(OBJEXT) $(am__objects_64) +am__objects_64 = ../../lib/lib565-timediff.$(OBJEXT) +am__objects_65 = $(am__objects_64) lib565-first.$(OBJEXT) +am_lib565_OBJECTS = lib565-lib510.$(OBJEXT) $(am__objects_65) lib565_OBJECTS = $(am_lib565_OBJECTS) lib565_LDADD = $(LDADD) lib565_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -1098,28 +1086,28 @@ am_lib583_OBJECTS = lib583.$(OBJEXT) $(am__objects_2) lib583_OBJECTS = $(am_lib583_OBJECTS) lib583_LDADD = $(LDADD) lib583_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_65 = ../../lib/lib584-timediff.$(OBJEXT) -am__objects_66 = $(am__objects_65) lib584-first.$(OBJEXT) -am_lib584_OBJECTS = lib584-lib589.$(OBJEXT) $(am__objects_66) +am__objects_66 = ../../lib/lib584-timediff.$(OBJEXT) +am__objects_67 = $(am__objects_66) lib584-first.$(OBJEXT) +am_lib584_OBJECTS = lib584-lib589.$(OBJEXT) $(am__objects_67) lib584_OBJECTS = $(am_lib584_OBJECTS) lib584_LDADD = $(LDADD) lib584_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_67 = ../../lib/lib585-timediff.$(OBJEXT) -am__objects_68 = $(am__objects_67) lib585-first.$(OBJEXT) -am__objects_69 = lib585-testutil.$(OBJEXT) -am__objects_70 = lib585-testtrace.$(OBJEXT) -am__objects_71 = ../../lib/lib585-curl_multibyte.$(OBJEXT) -am_lib585_OBJECTS = lib585-lib500.$(OBJEXT) $(am__objects_68) \ - $(am__objects_69) $(am__objects_70) $(am__objects_71) +am__objects_68 = ../../lib/lib585-timediff.$(OBJEXT) +am__objects_69 = $(am__objects_68) lib585-first.$(OBJEXT) +am__objects_70 = lib585-testutil.$(OBJEXT) +am__objects_71 = lib585-testtrace.$(OBJEXT) +am__objects_72 = ../../lib/lib585-curl_multibyte.$(OBJEXT) +am_lib585_OBJECTS = lib585-lib500.$(OBJEXT) $(am__objects_69) \ + $(am__objects_70) $(am__objects_71) $(am__objects_72) lib585_OBJECTS = $(am_lib585_OBJECTS) lib585_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib586_OBJECTS = lib586.$(OBJEXT) $(am__objects_2) lib586_OBJECTS = $(am_lib586_OBJECTS) lib586_LDADD = $(LDADD) lib586_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_72 = ../../lib/lib587-timediff.$(OBJEXT) -am__objects_73 = $(am__objects_72) lib587-first.$(OBJEXT) -am_lib587_OBJECTS = lib587-lib554.$(OBJEXT) $(am__objects_73) +am__objects_73 = ../../lib/lib587-timediff.$(OBJEXT) +am__objects_74 = $(am__objects_73) lib587-first.$(OBJEXT) +am_lib587_OBJECTS = lib587-lib554.$(OBJEXT) $(am__objects_74) lib587_OBJECTS = $(am_lib587_OBJECTS) lib587_LDADD = $(LDADD) lib587_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -1152,9 +1140,9 @@ am_lib643_OBJECTS = lib643.$(OBJEXT) $(am__objects_2) lib643_OBJECTS = $(am_lib643_OBJECTS) lib643_LDADD = $(LDADD) lib643_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_74 = ../../lib/lib645-timediff.$(OBJEXT) -am__objects_75 = $(am__objects_74) lib645-first.$(OBJEXT) -am_lib645_OBJECTS = lib645-lib643.$(OBJEXT) $(am__objects_75) +am__objects_75 = ../../lib/lib645-timediff.$(OBJEXT) +am__objects_76 = $(am__objects_75) lib645-first.$(OBJEXT) +am_lib645_OBJECTS = lib645-lib643.$(OBJEXT) $(am__objects_76) lib645_OBJECTS = $(am_lib645_OBJECTS) lib645_LDADD = $(LDADD) lib645_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -1206,28 +1194,28 @@ am_lib668_OBJECTS = lib668.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) lib668_OBJECTS = $(am_lib668_OBJECTS) lib668_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_76 = ../../lib/lib670-timediff.$(OBJEXT) -am__objects_77 = $(am__objects_76) lib670-first.$(OBJEXT) -am__objects_78 = lib670-testutil.$(OBJEXT) -am__objects_79 = ../../lib/lib670-warnless.$(OBJEXT) -am_lib670_OBJECTS = lib670-lib670.$(OBJEXT) $(am__objects_77) \ - $(am__objects_78) $(am__objects_79) +am__objects_77 = ../../lib/lib670-timediff.$(OBJEXT) +am__objects_78 = $(am__objects_77) lib670-first.$(OBJEXT) +am__objects_79 = lib670-testutil.$(OBJEXT) +am__objects_80 = ../../lib/lib670-warnless.$(OBJEXT) +am_lib670_OBJECTS = lib670-lib670.$(OBJEXT) $(am__objects_78) \ + $(am__objects_79) $(am__objects_80) lib670_OBJECTS = $(am_lib670_OBJECTS) lib670_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_80 = ../../lib/lib671-timediff.$(OBJEXT) -am__objects_81 = $(am__objects_80) lib671-first.$(OBJEXT) -am__objects_82 = lib671-testutil.$(OBJEXT) -am__objects_83 = ../../lib/lib671-warnless.$(OBJEXT) -am_lib671_OBJECTS = lib671-lib670.$(OBJEXT) $(am__objects_81) \ - $(am__objects_82) $(am__objects_83) +am__objects_81 = ../../lib/lib671-timediff.$(OBJEXT) +am__objects_82 = $(am__objects_81) lib671-first.$(OBJEXT) +am__objects_83 = lib671-testutil.$(OBJEXT) +am__objects_84 = ../../lib/lib671-warnless.$(OBJEXT) +am_lib671_OBJECTS = lib671-lib670.$(OBJEXT) $(am__objects_82) \ + $(am__objects_83) $(am__objects_84) lib671_OBJECTS = $(am_lib671_OBJECTS) lib671_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__objects_84 = ../../lib/lib672-timediff.$(OBJEXT) -am__objects_85 = $(am__objects_84) lib672-first.$(OBJEXT) -am__objects_86 = lib672-testutil.$(OBJEXT) -am__objects_87 = ../../lib/lib672-warnless.$(OBJEXT) -am_lib672_OBJECTS = lib672-lib670.$(OBJEXT) $(am__objects_85) \ - $(am__objects_86) $(am__objects_87) +am__objects_85 = ../../lib/lib672-timediff.$(OBJEXT) +am__objects_86 = $(am__objects_85) lib672-first.$(OBJEXT) +am__objects_87 = lib672-testutil.$(OBJEXT) +am__objects_88 = ../../lib/lib672-warnless.$(OBJEXT) +am_lib672_OBJECTS = lib672-lib670.$(OBJEXT) $(am__objects_86) \ + $(am__objects_87) $(am__objects_88) lib672_OBJECTS = $(am_lib672_OBJECTS) lib672_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lib673_OBJECTS = lib670.$(OBJEXT) $(am__objects_2) $(am__objects_3) \ @@ -1252,7 +1240,6 @@ lib678_OBJECTS = $(am_lib678_OBJECTS) lib678_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libauthretry_OBJECTS = libauthretry.$(OBJEXT) $(am__objects_2) libauthretry_OBJECTS = $(am_libauthretry_OBJECTS) -libauthretry_LDADD = $(LDADD) libauthretry_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libntlmconnect_OBJECTS = libntlmconnect.$(OBJEXT) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) @@ -1277,8 +1264,8 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ../../lib/$(DEPDIR)/curl_gethostname.Po \ - ../../lib/$(DEPDIR)/curl_multibyte.Po \ +am__depfiles_remade = ../../lib/$(DEPDIR)/curl_multibyte.Po \ + ../../lib/$(DEPDIR)/curl_threads.Po \ ../../lib/$(DEPDIR)/lib1502-timediff.Po \ ../../lib/$(DEPDIR)/lib1502-warnless.Po \ ../../lib/$(DEPDIR)/lib1503-timediff.Po \ @@ -1321,80 +1308,80 @@ am__depfiles_remade = ../../lib/$(DEPDIR)/curl_gethostname.Po \ ../../lib/$(DEPDIR)/lib672-timediff.Po \ ../../lib/$(DEPDIR)/lib672-warnless.Po \ ../../lib/$(DEPDIR)/timediff.Po \ - ../../lib/$(DEPDIR)/warnless.Po ./$(DEPDIR)/chkhostname.Po \ - ./$(DEPDIR)/first.Po ./$(DEPDIR)/lib1156.Po \ - ./$(DEPDIR)/lib1301.Po ./$(DEPDIR)/lib1485.Po \ - ./$(DEPDIR)/lib1500.Po ./$(DEPDIR)/lib1501.Po \ - ./$(DEPDIR)/lib1502-first.Po ./$(DEPDIR)/lib1502-lib1502.Po \ - ./$(DEPDIR)/lib1502-testutil.Po ./$(DEPDIR)/lib1503-first.Po \ - ./$(DEPDIR)/lib1503-lib1502.Po ./$(DEPDIR)/lib1503-testutil.Po \ - ./$(DEPDIR)/lib1504-first.Po ./$(DEPDIR)/lib1504-lib1502.Po \ - ./$(DEPDIR)/lib1504-testutil.Po ./$(DEPDIR)/lib1505-first.Po \ - ./$(DEPDIR)/lib1505-lib1502.Po ./$(DEPDIR)/lib1505-testutil.Po \ - ./$(DEPDIR)/lib1506.Po ./$(DEPDIR)/lib1507.Po \ - ./$(DEPDIR)/lib1508.Po ./$(DEPDIR)/lib1509.Po \ - ./$(DEPDIR)/lib1510.Po ./$(DEPDIR)/lib1511.Po \ - ./$(DEPDIR)/lib1512.Po ./$(DEPDIR)/lib1513.Po \ - ./$(DEPDIR)/lib1514.Po ./$(DEPDIR)/lib1515.Po \ - ./$(DEPDIR)/lib1517.Po ./$(DEPDIR)/lib1518.Po \ - ./$(DEPDIR)/lib1520.Po ./$(DEPDIR)/lib1521-first.Po \ - ./$(DEPDIR)/lib1521-lib1521.Po ./$(DEPDIR)/lib1522.Po \ - ./$(DEPDIR)/lib1523.Po ./$(DEPDIR)/lib1525.Po \ - ./$(DEPDIR)/lib1526.Po ./$(DEPDIR)/lib1527.Po \ - ./$(DEPDIR)/lib1528.Po ./$(DEPDIR)/lib1529.Po \ - ./$(DEPDIR)/lib1530.Po ./$(DEPDIR)/lib1531.Po \ - ./$(DEPDIR)/lib1532.Po ./$(DEPDIR)/lib1533.Po \ - ./$(DEPDIR)/lib1534.Po ./$(DEPDIR)/lib1535.Po \ - ./$(DEPDIR)/lib1536.Po ./$(DEPDIR)/lib1537.Po \ - ./$(DEPDIR)/lib1538.Po ./$(DEPDIR)/lib1539-first.Po \ - ./$(DEPDIR)/lib1539-lib1514.Po ./$(DEPDIR)/lib1539-testutil.Po \ - ./$(DEPDIR)/lib1540.Po ./$(DEPDIR)/lib1541.Po \ - ./$(DEPDIR)/lib1542.Po ./$(DEPDIR)/lib1543-first.Po \ - ./$(DEPDIR)/lib1543-lib1518.Po ./$(DEPDIR)/lib1545-first.Po \ - ./$(DEPDIR)/lib1545-lib1545.Po ./$(DEPDIR)/lib1550.Po \ - ./$(DEPDIR)/lib1551.Po ./$(DEPDIR)/lib1552.Po \ - ./$(DEPDIR)/lib1553.Po ./$(DEPDIR)/lib1554.Po \ - ./$(DEPDIR)/lib1555.Po ./$(DEPDIR)/lib1556.Po \ - ./$(DEPDIR)/lib1557.Po ./$(DEPDIR)/lib1558.Po \ - ./$(DEPDIR)/lib1559.Po ./$(DEPDIR)/lib1560.Po \ - ./$(DEPDIR)/lib1564.Po ./$(DEPDIR)/lib1565.Po \ - ./$(DEPDIR)/lib1567.Po ./$(DEPDIR)/lib1568.Po \ - ./$(DEPDIR)/lib1569.Po ./$(DEPDIR)/lib1591.Po \ - ./$(DEPDIR)/lib1592.Po ./$(DEPDIR)/lib1593.Po \ - ./$(DEPDIR)/lib1594.Po ./$(DEPDIR)/lib1596-first.Po \ - ./$(DEPDIR)/lib1596-lib1594.Po ./$(DEPDIR)/lib1596-testutil.Po \ - ./$(DEPDIR)/lib1597.Po ./$(DEPDIR)/lib1598.Po \ - ./$(DEPDIR)/lib1662.Po ./$(DEPDIR)/lib1900.Po \ - ./$(DEPDIR)/lib1901.Po ./$(DEPDIR)/lib1903.Po \ - ./$(DEPDIR)/lib1905.Po ./$(DEPDIR)/lib1906.Po \ - ./$(DEPDIR)/lib1907.Po ./$(DEPDIR)/lib1908.Po \ - ./$(DEPDIR)/lib1910.Po ./$(DEPDIR)/lib1911.Po \ - ./$(DEPDIR)/lib1912.Po ./$(DEPDIR)/lib1913.Po \ - ./$(DEPDIR)/lib1915.Po ./$(DEPDIR)/lib1916.Po \ - ./$(DEPDIR)/lib1917-first.Po ./$(DEPDIR)/lib1917-lib1916.Po \ - ./$(DEPDIR)/lib1918.Po ./$(DEPDIR)/lib1919.Po \ - ./$(DEPDIR)/lib1933.Po ./$(DEPDIR)/lib1934.Po \ - ./$(DEPDIR)/lib1935.Po ./$(DEPDIR)/lib1936.Po \ - ./$(DEPDIR)/lib1937.Po ./$(DEPDIR)/lib1938.Po \ - ./$(DEPDIR)/lib1939.Po ./$(DEPDIR)/lib1940.Po \ - ./$(DEPDIR)/lib1945.Po ./$(DEPDIR)/lib1946-first.Po \ - ./$(DEPDIR)/lib1946-lib1940.Po ./$(DEPDIR)/lib1947.Po \ - ./$(DEPDIR)/lib1948.Po ./$(DEPDIR)/lib1955.Po \ - ./$(DEPDIR)/lib1956.Po ./$(DEPDIR)/lib1957.Po \ - ./$(DEPDIR)/lib1958.Po ./$(DEPDIR)/lib1959.Po \ - ./$(DEPDIR)/lib1960.Po ./$(DEPDIR)/lib1964.Po \ - ./$(DEPDIR)/lib1970.Po ./$(DEPDIR)/lib1971.Po \ - ./$(DEPDIR)/lib1972.Po ./$(DEPDIR)/lib1973.Po \ - ./$(DEPDIR)/lib1974.Po ./$(DEPDIR)/lib1975.Po \ - ./$(DEPDIR)/lib2301.Po ./$(DEPDIR)/lib2302.Po \ - ./$(DEPDIR)/lib2304.Po ./$(DEPDIR)/lib2305.Po \ - ./$(DEPDIR)/lib2306.Po ./$(DEPDIR)/lib2308.Po \ - ./$(DEPDIR)/lib2402.Po ./$(DEPDIR)/lib2404.Po \ - ./$(DEPDIR)/lib2405.Po ./$(DEPDIR)/lib2502.Po \ - ./$(DEPDIR)/lib3010.Po ./$(DEPDIR)/lib3025.Po \ - ./$(DEPDIR)/lib3026.Po ./$(DEPDIR)/lib3027.Po \ - ./$(DEPDIR)/lib3100.Po ./$(DEPDIR)/lib3101.Po \ - ./$(DEPDIR)/lib3102.Po ./$(DEPDIR)/lib3103.Po \ + ../../lib/$(DEPDIR)/warnless.Po ./$(DEPDIR)/first.Po \ + ./$(DEPDIR)/lib1156.Po ./$(DEPDIR)/lib1301.Po \ + ./$(DEPDIR)/lib1485.Po ./$(DEPDIR)/lib1500.Po \ + ./$(DEPDIR)/lib1501.Po ./$(DEPDIR)/lib1502-first.Po \ + ./$(DEPDIR)/lib1502-lib1502.Po ./$(DEPDIR)/lib1502-testutil.Po \ + ./$(DEPDIR)/lib1503-first.Po ./$(DEPDIR)/lib1503-lib1502.Po \ + ./$(DEPDIR)/lib1503-testutil.Po ./$(DEPDIR)/lib1504-first.Po \ + ./$(DEPDIR)/lib1504-lib1502.Po ./$(DEPDIR)/lib1504-testutil.Po \ + ./$(DEPDIR)/lib1505-first.Po ./$(DEPDIR)/lib1505-lib1502.Po \ + ./$(DEPDIR)/lib1505-testutil.Po ./$(DEPDIR)/lib1506.Po \ + ./$(DEPDIR)/lib1507.Po ./$(DEPDIR)/lib1508.Po \ + ./$(DEPDIR)/lib1509.Po ./$(DEPDIR)/lib1510.Po \ + ./$(DEPDIR)/lib1511.Po ./$(DEPDIR)/lib1512.Po \ + ./$(DEPDIR)/lib1513.Po ./$(DEPDIR)/lib1514.Po \ + ./$(DEPDIR)/lib1515.Po ./$(DEPDIR)/lib1517.Po \ + ./$(DEPDIR)/lib1518.Po ./$(DEPDIR)/lib1520.Po \ + ./$(DEPDIR)/lib1521-first.Po ./$(DEPDIR)/lib1521-lib1521.Po \ + ./$(DEPDIR)/lib1522.Po ./$(DEPDIR)/lib1523.Po \ + ./$(DEPDIR)/lib1525.Po ./$(DEPDIR)/lib1526.Po \ + ./$(DEPDIR)/lib1527.Po ./$(DEPDIR)/lib1528.Po \ + ./$(DEPDIR)/lib1529.Po ./$(DEPDIR)/lib1530.Po \ + ./$(DEPDIR)/lib1531.Po ./$(DEPDIR)/lib1532.Po \ + ./$(DEPDIR)/lib1533.Po ./$(DEPDIR)/lib1534.Po \ + ./$(DEPDIR)/lib1535.Po ./$(DEPDIR)/lib1536.Po \ + ./$(DEPDIR)/lib1537.Po ./$(DEPDIR)/lib1538.Po \ + ./$(DEPDIR)/lib1539-first.Po ./$(DEPDIR)/lib1539-lib1514.Po \ + ./$(DEPDIR)/lib1539-testutil.Po ./$(DEPDIR)/lib1540.Po \ + ./$(DEPDIR)/lib1541.Po ./$(DEPDIR)/lib1542.Po \ + ./$(DEPDIR)/lib1543-first.Po ./$(DEPDIR)/lib1543-lib1518.Po \ + ./$(DEPDIR)/lib1545-first.Po ./$(DEPDIR)/lib1545-lib1545.Po \ + ./$(DEPDIR)/lib1550.Po ./$(DEPDIR)/lib1551.Po \ + ./$(DEPDIR)/lib1552.Po ./$(DEPDIR)/lib1553.Po \ + ./$(DEPDIR)/lib1554.Po ./$(DEPDIR)/lib1555.Po \ + ./$(DEPDIR)/lib1556.Po ./$(DEPDIR)/lib1557.Po \ + ./$(DEPDIR)/lib1558.Po ./$(DEPDIR)/lib1559.Po \ + ./$(DEPDIR)/lib1560.Po ./$(DEPDIR)/lib1564.Po \ + ./$(DEPDIR)/lib1565.Po ./$(DEPDIR)/lib1567.Po \ + ./$(DEPDIR)/lib1568.Po ./$(DEPDIR)/lib1569.Po \ + ./$(DEPDIR)/lib1591.Po ./$(DEPDIR)/lib1592.Po \ + ./$(DEPDIR)/lib1593.Po ./$(DEPDIR)/lib1594.Po \ + ./$(DEPDIR)/lib1596-first.Po ./$(DEPDIR)/lib1596-lib1594.Po \ + ./$(DEPDIR)/lib1596-testutil.Po ./$(DEPDIR)/lib1597.Po \ + ./$(DEPDIR)/lib1598.Po ./$(DEPDIR)/lib1662.Po \ + ./$(DEPDIR)/lib1900.Po ./$(DEPDIR)/lib1901.Po \ + ./$(DEPDIR)/lib1903.Po ./$(DEPDIR)/lib1905.Po \ + ./$(DEPDIR)/lib1906.Po ./$(DEPDIR)/lib1907.Po \ + ./$(DEPDIR)/lib1908.Po ./$(DEPDIR)/lib1910.Po \ + ./$(DEPDIR)/lib1911.Po ./$(DEPDIR)/lib1912.Po \ + ./$(DEPDIR)/lib1913.Po ./$(DEPDIR)/lib1915.Po \ + ./$(DEPDIR)/lib1916.Po ./$(DEPDIR)/lib1917-first.Po \ + ./$(DEPDIR)/lib1917-lib1916.Po ./$(DEPDIR)/lib1918.Po \ + ./$(DEPDIR)/lib1919.Po ./$(DEPDIR)/lib1933.Po \ + ./$(DEPDIR)/lib1934.Po ./$(DEPDIR)/lib1935.Po \ + ./$(DEPDIR)/lib1936.Po ./$(DEPDIR)/lib1937.Po \ + ./$(DEPDIR)/lib1938.Po ./$(DEPDIR)/lib1939.Po \ + ./$(DEPDIR)/lib1940.Po ./$(DEPDIR)/lib1945.Po \ + ./$(DEPDIR)/lib1946-first.Po ./$(DEPDIR)/lib1946-lib1940.Po \ + ./$(DEPDIR)/lib1947.Po ./$(DEPDIR)/lib1948.Po \ + ./$(DEPDIR)/lib1955.Po ./$(DEPDIR)/lib1956.Po \ + ./$(DEPDIR)/lib1957.Po ./$(DEPDIR)/lib1958.Po \ + ./$(DEPDIR)/lib1959.Po ./$(DEPDIR)/lib1960.Po \ + ./$(DEPDIR)/lib1964.Po ./$(DEPDIR)/lib1970.Po \ + ./$(DEPDIR)/lib1971.Po ./$(DEPDIR)/lib1972.Po \ + ./$(DEPDIR)/lib1973.Po ./$(DEPDIR)/lib1974.Po \ + ./$(DEPDIR)/lib1975.Po ./$(DEPDIR)/lib2301.Po \ + ./$(DEPDIR)/lib2302.Po ./$(DEPDIR)/lib2304.Po \ + ./$(DEPDIR)/lib2305.Po ./$(DEPDIR)/lib2306.Po \ + ./$(DEPDIR)/lib2308.Po ./$(DEPDIR)/lib2402.Po \ + ./$(DEPDIR)/lib2404.Po ./$(DEPDIR)/lib2405.Po \ + ./$(DEPDIR)/lib2502.Po ./$(DEPDIR)/lib3010.Po \ + ./$(DEPDIR)/lib3025.Po ./$(DEPDIR)/lib3026.Po \ + ./$(DEPDIR)/lib3027.Po ./$(DEPDIR)/lib3100.Po \ + ./$(DEPDIR)/lib3101.Po ./$(DEPDIR)/lib3102.Po \ + ./$(DEPDIR)/lib3103.Po ./$(DEPDIR)/lib3207.Po \ ./$(DEPDIR)/lib500.Po ./$(DEPDIR)/lib501.Po \ ./$(DEPDIR)/lib502.Po ./$(DEPDIR)/lib503.Po \ ./$(DEPDIR)/lib504.Po ./$(DEPDIR)/lib505.Po \ @@ -1458,7 +1445,6 @@ am__depfiles_remade = ../../lib/$(DEPDIR)/curl_gethostname.Po \ ./$(DEPDIR)/lib672-testutil.Po ./$(DEPDIR)/lib674.Po \ ./$(DEPDIR)/lib676.Po ./$(DEPDIR)/lib677.Po \ ./$(DEPDIR)/lib678.Po ./$(DEPDIR)/libauthretry.Po \ - ./$(DEPDIR)/libhostname_la-sethostname.Plo \ ./$(DEPDIR)/libntlmconnect.Po ./$(DEPDIR)/libprereq.Po \ ./$(DEPDIR)/libstubgss_la-stub_gssapi.Plo \ ./$(DEPDIR)/testtrace.Po ./$(DEPDIR)/testutil.Po @@ -1481,15 +1467,14 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libhostname_la_SOURCES) $(libstubgss_la_SOURCES) \ - $(chkhostname_SOURCES) $(lib1156_SOURCES) $(lib1301_SOURCES) \ - $(lib1485_SOURCES) $(lib1500_SOURCES) $(lib1501_SOURCES) \ - $(lib1502_SOURCES) $(lib1503_SOURCES) $(lib1504_SOURCES) \ - $(lib1505_SOURCES) $(lib1506_SOURCES) $(lib1507_SOURCES) \ - $(lib1508_SOURCES) $(lib1509_SOURCES) $(lib1510_SOURCES) \ - $(lib1511_SOURCES) $(lib1512_SOURCES) $(lib1513_SOURCES) \ - $(lib1514_SOURCES) $(lib1515_SOURCES) $(lib1517_SOURCES) \ - $(lib1518_SOURCES) $(lib1520_SOURCES) \ +SOURCES = $(libstubgss_la_SOURCES) $(lib1156_SOURCES) \ + $(lib1301_SOURCES) $(lib1485_SOURCES) $(lib1500_SOURCES) \ + $(lib1501_SOURCES) $(lib1502_SOURCES) $(lib1503_SOURCES) \ + $(lib1504_SOURCES) $(lib1505_SOURCES) $(lib1506_SOURCES) \ + $(lib1507_SOURCES) $(lib1508_SOURCES) $(lib1509_SOURCES) \ + $(lib1510_SOURCES) $(lib1511_SOURCES) $(lib1512_SOURCES) \ + $(lib1513_SOURCES) $(lib1514_SOURCES) $(lib1515_SOURCES) \ + $(lib1517_SOURCES) $(lib1518_SOURCES) $(lib1520_SOURCES) \ $(nodist_lib1521_SOURCES) $(lib1522_SOURCES) \ $(lib1523_SOURCES) $(lib1525_SOURCES) $(lib1526_SOURCES) \ $(lib1527_SOURCES) $(lib1528_SOURCES) $(lib1529_SOURCES) \ @@ -1525,87 +1510,87 @@ SOURCES = $(libhostname_la_SOURCES) $(libstubgss_la_SOURCES) \ $(lib2404_SOURCES) $(lib2405_SOURCES) $(lib2502_SOURCES) \ $(lib3010_SOURCES) $(lib3025_SOURCES) $(lib3026_SOURCES) \ $(lib3027_SOURCES) $(lib3100_SOURCES) $(lib3101_SOURCES) \ - $(lib3102_SOURCES) $(lib3103_SOURCES) $(lib500_SOURCES) \ - $(lib501_SOURCES) $(lib502_SOURCES) $(lib503_SOURCES) \ - $(lib504_SOURCES) $(lib505_SOURCES) $(lib506_SOURCES) \ - $(lib507_SOURCES) $(lib508_SOURCES) $(lib509_SOURCES) \ - $(lib510_SOURCES) $(lib511_SOURCES) $(lib512_SOURCES) \ - $(lib513_SOURCES) $(lib514_SOURCES) $(lib515_SOURCES) \ - $(lib516_SOURCES) $(lib517_SOURCES) $(lib518_SOURCES) \ - $(lib519_SOURCES) $(lib520_SOURCES) $(lib521_SOURCES) \ - $(lib523_SOURCES) $(lib524_SOURCES) $(lib525_SOURCES) \ - $(lib526_SOURCES) $(lib527_SOURCES) $(lib529_SOURCES) \ - $(lib530_SOURCES) $(lib532_SOURCES) $(lib533_SOURCES) \ - $(lib536_SOURCES) $(lib537_SOURCES) $(lib539_SOURCES) \ - $(lib540_SOURCES) $(lib541_SOURCES) $(lib542_SOURCES) \ - $(lib543_SOURCES) $(lib544_SOURCES) $(lib545_SOURCES) \ - $(lib547_SOURCES) $(lib548_SOURCES) $(lib549_SOURCES) \ - $(lib552_SOURCES) $(lib553_SOURCES) $(lib554_SOURCES) \ - $(lib555_SOURCES) $(lib556_SOURCES) $(lib557_SOURCES) \ - $(lib558_SOURCES) $(lib559_SOURCES) $(lib560_SOURCES) \ - $(lib562_SOURCES) $(lib564_SOURCES) $(lib565_SOURCES) \ - $(lib566_SOURCES) $(lib567_SOURCES) $(lib568_SOURCES) \ - $(lib569_SOURCES) $(lib570_SOURCES) $(lib571_SOURCES) \ - $(lib572_SOURCES) $(lib573_SOURCES) $(lib574_SOURCES) \ - $(lib575_SOURCES) $(lib576_SOURCES) $(lib578_SOURCES) \ - $(lib579_SOURCES) $(lib582_SOURCES) $(lib583_SOURCES) \ - $(lib584_SOURCES) $(lib585_SOURCES) $(lib586_SOURCES) \ - $(lib587_SOURCES) $(lib589_SOURCES) $(lib590_SOURCES) \ - $(lib591_SOURCES) $(lib597_SOURCES) $(lib598_SOURCES) \ - $(lib599_SOURCES) $(lib643_SOURCES) $(lib645_SOURCES) \ - $(lib650_SOURCES) $(lib651_SOURCES) $(lib652_SOURCES) \ - $(lib653_SOURCES) $(lib654_SOURCES) $(lib655_SOURCES) \ - $(lib658_SOURCES) $(lib659_SOURCES) $(lib661_SOURCES) \ - $(lib666_SOURCES) $(lib667_SOURCES) $(lib668_SOURCES) \ - $(lib670_SOURCES) $(lib671_SOURCES) $(lib672_SOURCES) \ - $(lib673_SOURCES) $(lib674_SOURCES) $(lib676_SOURCES) \ - $(lib677_SOURCES) $(lib678_SOURCES) $(libauthretry_SOURCES) \ - $(libntlmconnect_SOURCES) $(libprereq_SOURCES) -DIST_SOURCES = $(libhostname_la_SOURCES) \ - $(am__libstubgss_la_SOURCES_DIST) $(chkhostname_SOURCES) \ - $(lib1156_SOURCES) $(lib1301_SOURCES) $(lib1485_SOURCES) \ - $(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \ - $(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \ - $(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \ - $(lib1509_SOURCES) $(lib1510_SOURCES) $(lib1511_SOURCES) \ - $(lib1512_SOURCES) $(lib1513_SOURCES) $(lib1514_SOURCES) \ - $(lib1515_SOURCES) $(lib1517_SOURCES) $(lib1518_SOURCES) \ - $(lib1520_SOURCES) $(lib1522_SOURCES) $(lib1523_SOURCES) \ - $(lib1525_SOURCES) $(lib1526_SOURCES) $(lib1527_SOURCES) \ - $(lib1528_SOURCES) $(lib1529_SOURCES) $(lib1530_SOURCES) \ - $(lib1531_SOURCES) $(lib1532_SOURCES) $(lib1533_SOURCES) \ - $(lib1534_SOURCES) $(lib1535_SOURCES) $(lib1536_SOURCES) \ - $(lib1537_SOURCES) $(lib1538_SOURCES) $(lib1539_SOURCES) \ - $(lib1540_SOURCES) $(lib1541_SOURCES) $(lib1542_SOURCES) \ - $(lib1543_SOURCES) $(lib1545_SOURCES) $(lib1550_SOURCES) \ - $(lib1551_SOURCES) $(lib1552_SOURCES) $(lib1553_SOURCES) \ - $(lib1554_SOURCES) $(lib1555_SOURCES) $(lib1556_SOURCES) \ - $(lib1557_SOURCES) $(lib1558_SOURCES) $(lib1559_SOURCES) \ - $(lib1560_SOURCES) $(lib1564_SOURCES) $(lib1565_SOURCES) \ - $(lib1567_SOURCES) $(lib1568_SOURCES) $(lib1569_SOURCES) \ - $(lib1591_SOURCES) $(lib1592_SOURCES) $(lib1593_SOURCES) \ - $(lib1594_SOURCES) $(lib1596_SOURCES) $(lib1597_SOURCES) \ - $(lib1598_SOURCES) $(lib1662_SOURCES) $(lib1900_SOURCES) \ - $(lib1901_SOURCES) $(lib1903_SOURCES) $(lib1905_SOURCES) \ - $(lib1906_SOURCES) $(lib1907_SOURCES) $(lib1908_SOURCES) \ - $(lib1910_SOURCES) $(lib1911_SOURCES) $(lib1912_SOURCES) \ - $(lib1913_SOURCES) $(lib1915_SOURCES) $(lib1916_SOURCES) \ - $(lib1917_SOURCES) $(lib1918_SOURCES) $(lib1919_SOURCES) \ - $(lib1933_SOURCES) $(lib1934_SOURCES) $(lib1935_SOURCES) \ - $(lib1936_SOURCES) $(lib1937_SOURCES) $(lib1938_SOURCES) \ - $(lib1939_SOURCES) $(lib1940_SOURCES) $(lib1945_SOURCES) \ - $(lib1946_SOURCES) $(lib1947_SOURCES) $(lib1948_SOURCES) \ - $(lib1955_SOURCES) $(lib1956_SOURCES) $(lib1957_SOURCES) \ - $(lib1958_SOURCES) $(lib1959_SOURCES) $(lib1960_SOURCES) \ - $(lib1964_SOURCES) $(lib1970_SOURCES) $(lib1971_SOURCES) \ - $(lib1972_SOURCES) $(lib1973_SOURCES) $(lib1974_SOURCES) \ - $(lib1975_SOURCES) $(lib2301_SOURCES) $(lib2302_SOURCES) \ - $(lib2304_SOURCES) $(lib2305_SOURCES) $(lib2306_SOURCES) \ - $(lib2308_SOURCES) $(lib2402_SOURCES) $(lib2404_SOURCES) \ - $(lib2405_SOURCES) $(lib2502_SOURCES) $(lib3010_SOURCES) \ - $(lib3025_SOURCES) $(lib3026_SOURCES) $(lib3027_SOURCES) \ - $(lib3100_SOURCES) $(lib3101_SOURCES) $(lib3102_SOURCES) \ - $(lib3103_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \ + $(lib3102_SOURCES) $(lib3103_SOURCES) $(lib3207_SOURCES) \ + $(lib500_SOURCES) $(lib501_SOURCES) $(lib502_SOURCES) \ + $(lib503_SOURCES) $(lib504_SOURCES) $(lib505_SOURCES) \ + $(lib506_SOURCES) $(lib507_SOURCES) $(lib508_SOURCES) \ + $(lib509_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \ + $(lib512_SOURCES) $(lib513_SOURCES) $(lib514_SOURCES) \ + $(lib515_SOURCES) $(lib516_SOURCES) $(lib517_SOURCES) \ + $(lib518_SOURCES) $(lib519_SOURCES) $(lib520_SOURCES) \ + $(lib521_SOURCES) $(lib523_SOURCES) $(lib524_SOURCES) \ + $(lib525_SOURCES) $(lib526_SOURCES) $(lib527_SOURCES) \ + $(lib529_SOURCES) $(lib530_SOURCES) $(lib532_SOURCES) \ + $(lib533_SOURCES) $(lib536_SOURCES) $(lib537_SOURCES) \ + $(lib539_SOURCES) $(lib540_SOURCES) $(lib541_SOURCES) \ + $(lib542_SOURCES) $(lib543_SOURCES) $(lib544_SOURCES) \ + $(lib545_SOURCES) $(lib547_SOURCES) $(lib548_SOURCES) \ + $(lib549_SOURCES) $(lib552_SOURCES) $(lib553_SOURCES) \ + $(lib554_SOURCES) $(lib555_SOURCES) $(lib556_SOURCES) \ + $(lib557_SOURCES) $(lib558_SOURCES) $(lib559_SOURCES) \ + $(lib560_SOURCES) $(lib562_SOURCES) $(lib564_SOURCES) \ + $(lib565_SOURCES) $(lib566_SOURCES) $(lib567_SOURCES) \ + $(lib568_SOURCES) $(lib569_SOURCES) $(lib570_SOURCES) \ + $(lib571_SOURCES) $(lib572_SOURCES) $(lib573_SOURCES) \ + $(lib574_SOURCES) $(lib575_SOURCES) $(lib576_SOURCES) \ + $(lib578_SOURCES) $(lib579_SOURCES) $(lib582_SOURCES) \ + $(lib583_SOURCES) $(lib584_SOURCES) $(lib585_SOURCES) \ + $(lib586_SOURCES) $(lib587_SOURCES) $(lib589_SOURCES) \ + $(lib590_SOURCES) $(lib591_SOURCES) $(lib597_SOURCES) \ + $(lib598_SOURCES) $(lib599_SOURCES) $(lib643_SOURCES) \ + $(lib645_SOURCES) $(lib650_SOURCES) $(lib651_SOURCES) \ + $(lib652_SOURCES) $(lib653_SOURCES) $(lib654_SOURCES) \ + $(lib655_SOURCES) $(lib658_SOURCES) $(lib659_SOURCES) \ + $(lib661_SOURCES) $(lib666_SOURCES) $(lib667_SOURCES) \ + $(lib668_SOURCES) $(lib670_SOURCES) $(lib671_SOURCES) \ + $(lib672_SOURCES) $(lib673_SOURCES) $(lib674_SOURCES) \ + $(lib676_SOURCES) $(lib677_SOURCES) $(lib678_SOURCES) \ + $(libauthretry_SOURCES) $(libntlmconnect_SOURCES) \ + $(libprereq_SOURCES) +DIST_SOURCES = $(am__libstubgss_la_SOURCES_DIST) $(lib1156_SOURCES) \ + $(lib1301_SOURCES) $(lib1485_SOURCES) $(lib1500_SOURCES) \ + $(lib1501_SOURCES) $(lib1502_SOURCES) $(lib1503_SOURCES) \ + $(lib1504_SOURCES) $(lib1505_SOURCES) $(lib1506_SOURCES) \ + $(lib1507_SOURCES) $(lib1508_SOURCES) $(lib1509_SOURCES) \ + $(lib1510_SOURCES) $(lib1511_SOURCES) $(lib1512_SOURCES) \ + $(lib1513_SOURCES) $(lib1514_SOURCES) $(lib1515_SOURCES) \ + $(lib1517_SOURCES) $(lib1518_SOURCES) $(lib1520_SOURCES) \ + $(lib1522_SOURCES) $(lib1523_SOURCES) $(lib1525_SOURCES) \ + $(lib1526_SOURCES) $(lib1527_SOURCES) $(lib1528_SOURCES) \ + $(lib1529_SOURCES) $(lib1530_SOURCES) $(lib1531_SOURCES) \ + $(lib1532_SOURCES) $(lib1533_SOURCES) $(lib1534_SOURCES) \ + $(lib1535_SOURCES) $(lib1536_SOURCES) $(lib1537_SOURCES) \ + $(lib1538_SOURCES) $(lib1539_SOURCES) $(lib1540_SOURCES) \ + $(lib1541_SOURCES) $(lib1542_SOURCES) $(lib1543_SOURCES) \ + $(lib1545_SOURCES) $(lib1550_SOURCES) $(lib1551_SOURCES) \ + $(lib1552_SOURCES) $(lib1553_SOURCES) $(lib1554_SOURCES) \ + $(lib1555_SOURCES) $(lib1556_SOURCES) $(lib1557_SOURCES) \ + $(lib1558_SOURCES) $(lib1559_SOURCES) $(lib1560_SOURCES) \ + $(lib1564_SOURCES) $(lib1565_SOURCES) $(lib1567_SOURCES) \ + $(lib1568_SOURCES) $(lib1569_SOURCES) $(lib1591_SOURCES) \ + $(lib1592_SOURCES) $(lib1593_SOURCES) $(lib1594_SOURCES) \ + $(lib1596_SOURCES) $(lib1597_SOURCES) $(lib1598_SOURCES) \ + $(lib1662_SOURCES) $(lib1900_SOURCES) $(lib1901_SOURCES) \ + $(lib1903_SOURCES) $(lib1905_SOURCES) $(lib1906_SOURCES) \ + $(lib1907_SOURCES) $(lib1908_SOURCES) $(lib1910_SOURCES) \ + $(lib1911_SOURCES) $(lib1912_SOURCES) $(lib1913_SOURCES) \ + $(lib1915_SOURCES) $(lib1916_SOURCES) $(lib1917_SOURCES) \ + $(lib1918_SOURCES) $(lib1919_SOURCES) $(lib1933_SOURCES) \ + $(lib1934_SOURCES) $(lib1935_SOURCES) $(lib1936_SOURCES) \ + $(lib1937_SOURCES) $(lib1938_SOURCES) $(lib1939_SOURCES) \ + $(lib1940_SOURCES) $(lib1945_SOURCES) $(lib1946_SOURCES) \ + $(lib1947_SOURCES) $(lib1948_SOURCES) $(lib1955_SOURCES) \ + $(lib1956_SOURCES) $(lib1957_SOURCES) $(lib1958_SOURCES) \ + $(lib1959_SOURCES) $(lib1960_SOURCES) $(lib1964_SOURCES) \ + $(lib1970_SOURCES) $(lib1971_SOURCES) $(lib1972_SOURCES) \ + $(lib1973_SOURCES) $(lib1974_SOURCES) $(lib1975_SOURCES) \ + $(lib2301_SOURCES) $(lib2302_SOURCES) $(lib2304_SOURCES) \ + $(lib2305_SOURCES) $(lib2306_SOURCES) $(lib2308_SOURCES) \ + $(lib2402_SOURCES) $(lib2404_SOURCES) $(lib2405_SOURCES) \ + $(lib2502_SOURCES) $(lib3010_SOURCES) $(lib3025_SOURCES) \ + $(lib3026_SOURCES) $(lib3027_SOURCES) $(lib3100_SOURCES) \ + $(lib3101_SOURCES) $(lib3102_SOURCES) $(lib3103_SOURCES) \ + $(lib3207_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \ $(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \ $(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \ $(lib508_SOURCES) $(lib509_SOURCES) $(lib510_SOURCES) \ @@ -1687,11 +1672,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -1737,7 +1722,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -1753,8 +1737,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -1789,10 +1775,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -1803,6 +1787,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -1811,6 +1796,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -1931,13 +1917,11 @@ AUTOMAKE_OPTIONS = foreign nostdinc AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ -I$(top_srcdir)/lib $(am__append_1) EXTRA_DIST = test307.pl test610.pl test613.pl test1013.pl test1022.pl \ - Makefile.inc notexists.pl CMakeLists.txt mk-lib1521.pl .checksrc + notexists.pl CMakeLists.txt mk-lib1521.pl .checksrc CLEANFILES = lib1521.c -@USE_EXPLICIT_LIB_DEPS_FALSE@SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ -@USE_EXPLICIT_LIB_DEPS_TRUE@SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ -@USE_EXPLICIT_LIB_DEPS_FALSE@TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ -@USE_EXPLICIT_LIB_DEPS_TRUE@TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ +SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ +TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ # Dependencies (may need to be overridden) LDADD = $(SUPPORTFILES_LIBS) @@ -1980,12 +1964,11 @@ MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h # these files are used in every single test program below TIMEDIFF = ../../lib/timediff.c ../../lib/timediff.h SUPPORTFILES = $(TIMEDIFF) first.c test.h -chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c -chkhostname_LDADD = @CURL_NETWORK_LIBS@ -chkhostname_DEPENDENCIES = +THREADS = ../../lib/curl_threads.c ../../lib/curl_threads.h libntlmconnect_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) libntlmconnect_LDADD = $(TESTUTIL_LIBS) libauthretry_SOURCES = libauthretry.c $(SUPPORTFILES) +libauthretry_LDADD = $(TESTUTIL_LIBS) libprereq_SOURCES = libprereq.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) libprereq_LDADD = $(TESTUTIL_LIBS) lib500_SOURCES = lib500.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) $(MULTIBYTE) @@ -2386,28 +2369,15 @@ lib3102_SOURCES = lib3102.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib3102_LDADD = $(TESTUTIL_LIBS) lib3103_SOURCES = lib3103.c $(SUPPORTFILES) lib3103_LDADD = $(TESTUTIL_LIBS) -@BUILD_LIBHOSTNAME_FALSE@noinst_LTLIBRARIES = $(am__append_7) +lib3207_SOURCES = lib3207.c $(SUPPORTFILES) $(TESTUTIL) $(THREADS) $(WARNLESS) $(MULTIBYTE) +lib3207_LDADD = $(TESTUTIL_LIBS) # Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES, # noinst_PROGRAMS, lib*_SOURCES, and lib*_CFLAGS) - -# Preloading of libhostname allows host name overriding, -# this is used to make some tests machine independent. -@BUILD_LIBHOSTNAME_TRUE@noinst_LTLIBRARIES = libhostname.la \ -@BUILD_LIBHOSTNAME_TRUE@ $(am__append_7) +noinst_LTLIBRARIES = $(am__append_3) AM_LDFLAGS = AM_CFLAGS = -libhostname_la_CPPFLAGS_EXTRA = $(am__append_5) -libhostname_la_LDFLAGS_EXTRA = -module -avoid-version -rpath /nowhere \ - $(am__append_2) $(am__append_4) -libhostname_la_CFLAGS_EXTRA = $(am__append_6) -libstubgss_la_LDFLAGS_EXTRA = $(am__append_3) -libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) $(libhostname_la_CPPFLAGS_EXTRA) -libhostname_la_LDFLAGS = $(AM_LDFLAGS) $(libhostname_la_LDFLAGS_EXTRA) -libhostname_la_CFLAGS = $(AM_CFLAGS) $(libhostname_la_CFLAGS_EXTRA) -libhostname_la_SOURCES = sethostname.c -libhostname_la_LIBADD = -libhostname_la_DEPENDENCIES = +libstubgss_la_LDFLAGS_EXTRA = $(am__append_2) @BUILD_STUB_GSS_TRUE@libstubgss_la_CPPFLAGS = $(AM_CPPFLAGS) @BUILD_STUB_GSS_TRUE@libstubgss_la_LDFLAGS = $(AM_LDFLAGS) $(libstubgss_la_LDFLAGS_EXTRA) -avoid-version -rpath /nowhere @BUILD_STUB_GSS_TRUE@libstubgss_la_CFLAGS = $(AM_CFLAGS) -g @@ -2473,9 +2443,6 @@ clean-noinstLTLIBRARIES: rm -f $${locs}; \ } -libhostname.la: $(libhostname_la_OBJECTS) $(libhostname_la_DEPENDENCIES) $(EXTRA_libhostname_la_DEPENDENCIES) - $(AM_V_CCLD)$(libhostname_la_LINK) $(am_libhostname_la_rpath) $(libhostname_la_OBJECTS) $(libhostname_la_LIBADD) $(LIBS) - libstubgss.la: $(libstubgss_la_OBJECTS) $(libstubgss_la_DEPENDENCIES) $(EXTRA_libstubgss_la_DEPENDENCIES) $(AM_V_CCLD)$(libstubgss_la_LINK) $(am_libstubgss_la_rpath) $(libstubgss_la_OBJECTS) $(libstubgss_la_LIBADD) $(LIBS) ../../lib/$(am__dirstamp): @@ -2484,12 +2451,6 @@ libstubgss.la: $(libstubgss_la_OBJECTS) $(libstubgss_la_DEPENDENCIES) $(EXTRA_li ../../lib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../lib/$(DEPDIR) @: > ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/curl_gethostname.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) - -chkhostname$(EXEEXT): $(chkhostname_OBJECTS) $(chkhostname_DEPENDENCIES) $(EXTRA_chkhostname_DEPENDENCIES) - @rm -f chkhostname$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(chkhostname_OBJECTS) $(chkhostname_LDADD) $(LIBS) ../../lib/timediff.$(OBJEXT): ../../lib/$(am__dirstamp) \ ../../lib/$(DEPDIR)/$(am__dirstamp) ../../lib/warnless.$(OBJEXT): ../../lib/$(am__dirstamp) \ @@ -3044,6 +3005,12 @@ lib3102$(EXEEXT): $(lib3102_OBJECTS) $(lib3102_DEPENDENCIES) $(EXTRA_lib3102_DEP lib3103$(EXEEXT): $(lib3103_OBJECTS) $(lib3103_DEPENDENCIES) $(EXTRA_lib3103_DEPENDENCIES) @rm -f lib3103$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lib3103_OBJECTS) $(lib3103_LDADD) $(LIBS) +../../lib/curl_threads.$(OBJEXT): ../../lib/$(am__dirstamp) \ + ../../lib/$(DEPDIR)/$(am__dirstamp) + +lib3207$(EXEEXT): $(lib3207_OBJECTS) $(lib3207_DEPENDENCIES) $(EXTRA_lib3207_DEPENDENCIES) + @rm -f lib3207$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lib3207_OBJECTS) $(lib3207_LDADD) $(LIBS) lib500$(EXEEXT): $(lib500_OBJECTS) $(lib500_DEPENDENCIES) $(EXTRA_lib500_DEPENDENCIES) @rm -f lib500$(EXEEXT) @@ -3518,8 +3485,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/curl_gethostname.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/curl_multibyte.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/curl_threads.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/lib1502-timediff.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/lib1502-warnless.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/lib1503-timediff.Po@am__quote@ # am--include-marker @@ -3563,7 +3530,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/lib672-warnless.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/timediff.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/warnless.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chkhostname.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/first.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1156.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1301.Po@am__quote@ # am--include-marker @@ -3710,6 +3676,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3101.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3102.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3103.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3207.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib501.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib502.Po@am__quote@ # am--include-marker @@ -3836,7 +3803,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib677.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib678.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libauthretry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhostname_la-sethostname.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libntlmconnect.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libprereq.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstubgss_la-stub_gssapi.Plo@am__quote@ # am--include-marker @@ -3873,13 +3839,6 @@ am--depfiles: $(am__depfiles_remade) @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libhostname_la-sethostname.lo: sethostname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhostname_la_CPPFLAGS) $(CPPFLAGS) $(libhostname_la_CFLAGS) $(CFLAGS) -MT libhostname_la-sethostname.lo -MD -MP -MF $(DEPDIR)/libhostname_la-sethostname.Tpo -c -o libhostname_la-sethostname.lo `test -f 'sethostname.c' || echo '$(srcdir)/'`sethostname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhostname_la-sethostname.Tpo $(DEPDIR)/libhostname_la-sethostname.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sethostname.c' object='libhostname_la-sethostname.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhostname_la_CPPFLAGS) $(CPPFLAGS) $(libhostname_la_CFLAGS) $(CFLAGS) -c -o libhostname_la-sethostname.lo `test -f 'sethostname.c' || echo '$(srcdir)/'`sethostname.c - libstubgss_la-stub_gssapi.lo: stub_gssapi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstubgss_la_CPPFLAGS) $(CPPFLAGS) $(libstubgss_la_CFLAGS) $(CFLAGS) -MT libstubgss_la-stub_gssapi.lo -MD -MP -MF $(DEPDIR)/libstubgss_la-stub_gssapi.Tpo -c -o libstubgss_la-stub_gssapi.lo `test -f 'stub_gssapi.c' || echo '$(srcdir)/'`stub_gssapi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstubgss_la-stub_gssapi.Tpo $(DEPDIR)/libstubgss_la-stub_gssapi.Plo @@ -5505,8 +5464,8 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ../../lib/$(DEPDIR)/curl_gethostname.Po - -rm -f ../../lib/$(DEPDIR)/curl_multibyte.Po + -rm -f ../../lib/$(DEPDIR)/curl_multibyte.Po + -rm -f ../../lib/$(DEPDIR)/curl_threads.Po -rm -f ../../lib/$(DEPDIR)/lib1502-timediff.Po -rm -f ../../lib/$(DEPDIR)/lib1502-warnless.Po -rm -f ../../lib/$(DEPDIR)/lib1503-timediff.Po @@ -5550,7 +5509,6 @@ distclean: distclean-am -rm -f ../../lib/$(DEPDIR)/lib672-warnless.Po -rm -f ../../lib/$(DEPDIR)/timediff.Po -rm -f ../../lib/$(DEPDIR)/warnless.Po - -rm -f ./$(DEPDIR)/chkhostname.Po -rm -f ./$(DEPDIR)/first.Po -rm -f ./$(DEPDIR)/lib1156.Po -rm -f ./$(DEPDIR)/lib1301.Po @@ -5697,6 +5655,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/lib3101.Po -rm -f ./$(DEPDIR)/lib3102.Po -rm -f ./$(DEPDIR)/lib3103.Po + -rm -f ./$(DEPDIR)/lib3207.Po -rm -f ./$(DEPDIR)/lib500.Po -rm -f ./$(DEPDIR)/lib501.Po -rm -f ./$(DEPDIR)/lib502.Po @@ -5823,7 +5782,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/lib677.Po -rm -f ./$(DEPDIR)/lib678.Po -rm -f ./$(DEPDIR)/libauthretry.Po - -rm -f ./$(DEPDIR)/libhostname_la-sethostname.Plo -rm -f ./$(DEPDIR)/libntlmconnect.Po -rm -f ./$(DEPDIR)/libprereq.Po -rm -f ./$(DEPDIR)/libstubgss_la-stub_gssapi.Plo @@ -5874,8 +5832,8 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ../../lib/$(DEPDIR)/curl_gethostname.Po - -rm -f ../../lib/$(DEPDIR)/curl_multibyte.Po + -rm -f ../../lib/$(DEPDIR)/curl_multibyte.Po + -rm -f ../../lib/$(DEPDIR)/curl_threads.Po -rm -f ../../lib/$(DEPDIR)/lib1502-timediff.Po -rm -f ../../lib/$(DEPDIR)/lib1502-warnless.Po -rm -f ../../lib/$(DEPDIR)/lib1503-timediff.Po @@ -5919,7 +5877,6 @@ maintainer-clean: maintainer-clean-am -rm -f ../../lib/$(DEPDIR)/lib672-warnless.Po -rm -f ../../lib/$(DEPDIR)/timediff.Po -rm -f ../../lib/$(DEPDIR)/warnless.Po - -rm -f ./$(DEPDIR)/chkhostname.Po -rm -f ./$(DEPDIR)/first.Po -rm -f ./$(DEPDIR)/lib1156.Po -rm -f ./$(DEPDIR)/lib1301.Po @@ -6066,6 +6023,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/lib3101.Po -rm -f ./$(DEPDIR)/lib3102.Po -rm -f ./$(DEPDIR)/lib3103.Po + -rm -f ./$(DEPDIR)/lib3207.Po -rm -f ./$(DEPDIR)/lib500.Po -rm -f ./$(DEPDIR)/lib501.Po -rm -f ./$(DEPDIR)/lib502.Po @@ -6192,7 +6150,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/lib677.Po -rm -f ./$(DEPDIR)/lib678.Po -rm -f ./$(DEPDIR)/libauthretry.Po - -rm -f ./$(DEPDIR)/libhostname_la-sethostname.Plo -rm -f ./$(DEPDIR)/libntlmconnect.Po -rm -f ./$(DEPDIR)/libprereq.Po -rm -f ./$(DEPDIR)/libstubgss_la-stub_gssapi.Plo diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 371f26656..d84b17643 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -37,8 +37,10 @@ MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h TIMEDIFF = ../../lib/timediff.c ../../lib/timediff.h SUPPORTFILES = $(TIMEDIFF) first.c test.h +THREADS = ../../lib/curl_threads.c ../../lib/curl_threads.h + # These are all libcurl test programs -noinst_PROGRAMS = chkhostname libauthretry libntlmconnect libprereq \ +noinst_PROGRAMS = libauthretry libntlmconnect libprereq \ lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 lib508 lib509 \ lib510 lib511 lib512 lib513 lib514 lib515 lib516 lib517 lib518 lib519 \ lib520 lib521 lib523 lib524 lib525 lib526 lib527 lib529 lib530 lib532 \ @@ -78,16 +80,13 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect libprereq \ lib2402 lib2404 lib2405 \ lib2502 \ lib3010 lib3025 lib3026 lib3027 \ - lib3100 lib3101 lib3102 lib3103 - -chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c -chkhostname_LDADD = @CURL_NETWORK_LIBS@ -chkhostname_DEPENDENCIES = + lib3100 lib3101 lib3102 lib3103 lib3207 libntlmconnect_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) libntlmconnect_LDADD = $(TESTUTIL_LIBS) libauthretry_SOURCES = libauthretry.c $(SUPPORTFILES) +libauthretry_LDADD = $(TESTUTIL_LIBS) libprereq_SOURCES = libprereq.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) libprereq_LDADD = $(TESTUTIL_LIBS) @@ -719,3 +718,6 @@ lib3102_LDADD = $(TESTUTIL_LIBS) lib3103_SOURCES = lib3103.c $(SUPPORTFILES) lib3103_LDADD = $(TESTUTIL_LIBS) + +lib3207_SOURCES = lib3207.c $(SUPPORTFILES) $(TESTUTIL) $(THREADS) $(WARNLESS) $(MULTIBYTE) +lib3207_LDADD = $(TESTUTIL_LIBS) diff --git a/tests/libtest/chkhostname.c b/tests/libtest/chkhostname.c deleted file mode 100644 index e49da133c..000000000 --- a/tests/libtest/chkhostname.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_gethostname.h" - -#define HOSTNAME_MAX 1024 - -int main(int argc, char *argv[]) -{ - char buff[HOSTNAME_MAX]; - if(argc != 2) { - printf("Usage: %s EXPECTED_HOSTNAME\n", argv[0]); - return 1; - } - - if(Curl_gethostname(buff, HOSTNAME_MAX)) { - printf("Curl_gethostname() failed\n"); - return 1; - } - - /* compare the name returned by Curl_gethostname() with the expected one */ - if(strncmp(buff, argv[1], HOSTNAME_MAX)) { - printf("got unexpected host name back, LD_PRELOAD failed\n"); - return 1; - } - return 0; -} diff --git a/tests/libtest/lib1541.c b/tests/libtest/lib1541.c index f326211d4..640a2f169 100644 --- a/tests/libtest/lib1541.c +++ b/tests/libtest/lib1541.c @@ -137,6 +137,7 @@ CURLcode test(char *URL) check_time(curls, KN(CURLINFO_CONNECT_TIME_T), "done"); check_time(curls, KN(CURLINFO_PRETRANSFER_TIME_T), "done"); + check_time(curls, KN(CURLINFO_POSTTRANSFER_TIME_T), "done"); check_time(curls, KN(CURLINFO_STARTTRANSFER_TIME_T), "done"); /* no SSL, must be 0 */ check_time0(curls, KN(CURLINFO_APPCONNECT_TIME_T), "done"); diff --git a/tests/libtest/lib1554.c b/tests/libtest/lib1554.c index 4b4d8e4c8..a8439b08e 100644 --- a/tests/libtest/lib1554.c +++ b/tests/libtest/lib1554.c @@ -24,6 +24,18 @@ #include "test.h" #include "memdebug.h" +static const char *ldata_names[] = { + "NONE", + "SHARE", + "COOKIE", + "DNS", + "SESSION", + "CONNECT", + "PSL", + "HSTS", + "NULL", +}; + static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, void *useptr) { @@ -31,7 +43,7 @@ static void my_lock(CURL *handle, curl_lock_data data, (void)data; (void)laccess; (void)useptr; - printf("-> Mutex lock\n"); + printf("-> Mutex lock %s\n", ldata_names[data]); } static void my_unlock(CURL *handle, curl_lock_data data, void *useptr) @@ -39,7 +51,7 @@ static void my_unlock(CURL *handle, curl_lock_data data, void *useptr) (void)handle; (void)data; (void)useptr; - printf("<- Mutex unlock\n"); + printf("<- Mutex unlock %s\n", ldata_names[data]); } /* test function */ diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index 0109d6edd..2956ce9b5 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -838,6 +838,14 @@ static const struct setgetcase setget_parts_list[] = { /* !checksrc! disable SPACEBEFORECOMMA 1 */ static const struct setcase set_parts_list[] = { + {"https://example.com/", + "host=%43url.se,", + "https://%43url.se/", + 0, 0, CURLUE_OK, CURLUE_OK}, + {"https://example.com/", + "host=%25url.se,", + "", + 0, 0, CURLUE_OK, CURLUE_BAD_HOSTNAME}, {"https://example.com/?param=value", "query=\"\",", "https://example.com/", diff --git a/tests/libtest/lib2301.c b/tests/libtest/lib2301.c index 377228ab3..cd3120770 100644 --- a/tests/libtest/lib2301.c +++ b/tests/libtest/lib2301.c @@ -149,6 +149,6 @@ CURLcode test(char *URL) return res; } -#else /* no websockets */ +#else /* no WebSockets */ NO_SUPPORT_BUILT_IN #endif diff --git a/tests/libtest/lib3207.c b/tests/libtest/lib3207.c new file mode 100644 index 000000000..669526f98 --- /dev/null +++ b/tests/libtest/lib3207.c @@ -0,0 +1,231 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" +#include "testutil.h" +#include "memdebug.h" + +#include + +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +#if defined(USE_THREADS_POSIX) +#include +#endif +#include "curl_threads.h" +#endif + +#define CAINFO libtest_arg2 +#define THREAD_SIZE 16 +#define PER_THREAD_SIZE 8 + +struct Ctx +{ + const char *URL; + CURLSH *share; + int result; + int thread_id; + struct curl_slist *contents; +}; + +static size_t write_memory_callback(void *contents, size_t size, + size_t nmemb, void *userp) { + /* append the data to contents */ + size_t realsize = size * nmemb; + struct Ctx *mem = (struct Ctx *)userp; + char *data = (char *)malloc(realsize + 1); + struct curl_slist *item_append = NULL; + if(!data) { + printf("not enough memory (malloc returned NULL)\n"); + return 0; + } + memcpy(data, contents, realsize); + data[realsize] = '\0'; + item_append = curl_slist_append(mem->contents, data); + free(data); + if(item_append) { + mem->contents = item_append; + } + else { + printf("not enough memory (curl_slist_append returned NULL)\n"); + return 0; + } + return realsize; +} + +static +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) +DWORD +#else +unsigned int +#endif +CURL_STDCALL +#else +unsigned int +#endif +test_thread(void *ptr) +{ + struct Ctx *ctx = (struct Ctx *)ptr; + CURLcode res = CURLE_OK; + + int i; + + /* Loop the transfer and cleanup the handle properly every lap. This will + still reuse ssl session since the pool is in the shared object! */ + for(i = 0; i < PER_THREAD_SIZE; i++) { + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, (char *)ctx->URL); + + /* use the share object */ + curl_easy_setopt(curl, CURLOPT_SHARE, ctx->share); + curl_easy_setopt(curl, CURLOPT_CAINFO, CAINFO); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + /* Check for errors */ + if(res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + goto test_cleanup; + } + } + } + +test_cleanup: + ctx->result = (int)res; + return 0; +} + +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) + +static void my_lock(CURL *handle, curl_lock_data data, + curl_lock_access laccess, void *useptr) +{ + curl_mutex_t *mutexes = (curl_mutex_t*) useptr; + (void)handle; + (void)laccess; + Curl_mutex_acquire(&mutexes[data]); +} + +static void my_unlock(CURL *handle, curl_lock_data data, void *useptr) +{ + curl_mutex_t *mutexes = (curl_mutex_t*) useptr; + (void)handle; + Curl_mutex_release(&mutexes[data]); +} + +static void execute(struct Curl_share *share, struct Ctx *ctx) +{ + int i; + curl_mutex_t mutexes[CURL_LOCK_DATA_LAST - 1]; + curl_thread_t thread[THREAD_SIZE]; + for(i = 0; i < CURL_LOCK_DATA_LAST - 1; i++) { + Curl_mutex_init(&mutexes[i]); + } + curl_share_setopt(share, CURLSHOPT_LOCKFUNC, my_lock); + curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, my_unlock); + curl_share_setopt(share, CURLSHOPT_USERDATA, (void *)mutexes); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + + for(i = 0; i < THREAD_SIZE; i++) { + thread[i] = Curl_thread_create(test_thread, (void *)&ctx[i]); + } + for(i = 0; i < THREAD_SIZE; i++) { + if(thread[i]) { + Curl_thread_join(&thread[i]); + Curl_thread_destroy(thread[i]); + } + } + curl_share_setopt(share, CURLSHOPT_LOCKFUNC, NULL); + curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, NULL); + for(i = 0; i < CURL_LOCK_DATA_LAST - 1; i++) { + Curl_mutex_destroy(&mutexes[i]); + } +} + +#else /* without pthread, run serially */ + +static void execute(struct Curl_share *share, struct Ctx *ctx) +{ + int i; + (void) share; + for(i = 0; i < THREAD_SIZE; i++) { + test_thread((void *)&ctx[i]); + } +} + +#endif + +CURLcode test(char *URL) +{ + int res = 0; + int i; + CURLSH* share; + struct Ctx ctx[THREAD_SIZE]; + + curl_global_init(CURL_GLOBAL_ALL); + + share = curl_share_init(); + if(!share) { + fprintf(stderr, "curl_share_init() failed\n"); + goto test_cleanup; + } + + for(i = 0; i < THREAD_SIZE; i++) { + ctx[i].share = share; + ctx[i].URL = URL; + ctx[i].thread_id = i; + ctx[i].result = 0; + ctx[i].contents = NULL; + } + + execute(share, ctx); + + for(i = 0; i < THREAD_SIZE; i++) { + if(ctx[i].result) { + res = ctx[i].result; + } + else { + struct curl_slist *item = ctx[i].contents; + while(item) { + printf("%s", item->data); + item = item->next; + } + } + curl_slist_free_all(ctx[i].contents); + } + +test_cleanup: + if(share) + curl_share_cleanup(share); + curl_global_cleanup(); + return (CURLcode)res; +} diff --git a/tests/libtest/lib500.c b/tests/libtest/lib500.c index b11786290..8b27aef04 100644 --- a/tests/libtest/lib500.c +++ b/tests/libtest/lib500.c @@ -101,6 +101,7 @@ CURLcode test(char *URL) curl_off_t time_namelookup; curl_off_t time_connect; curl_off_t time_pretransfer; + curl_off_t time_posttransfer; curl_off_t time_starttransfer; curl_off_t time_total; fprintf(moo, "IP %s\n", ipstr); @@ -108,6 +109,8 @@ CURLcode test(char *URL) curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME_T, &time_connect); curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME_T, &time_pretransfer); + curl_easy_getinfo(curl, CURLINFO_POSTTRANSFER_TIME_T, + &time_posttransfer); curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME_T, &time_starttransfer); curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &time_total); @@ -128,6 +131,14 @@ CURLcode test(char *URL) (time_pretransfer / 1000000), (long)(time_pretransfer % 1000000)); } + if(time_pretransfer > time_posttransfer) { + fprintf(moo, "pretransfer vs posttransfer: %" CURL_FORMAT_CURL_OFF_T + ".%06ld %" CURL_FORMAT_CURL_OFF_T ".%06ld\n", + (time_pretransfer / 1000000), + (long)(time_pretransfer % 1000000), + (time_posttransfer / 1000000), + (long)(time_posttransfer % 1000000)); + } if(time_pretransfer > time_starttransfer) { fprintf(moo, "pretransfer vs starttransfer: %" CURL_FORMAT_CURL_OFF_T ".%06ld %" CURL_FORMAT_CURL_OFF_T ".%06ld\n", @@ -143,6 +154,13 @@ CURLcode test(char *URL) (long)(time_starttransfer % 1000000), (time_total / 1000000), (long)(time_total % 1000000)); } + if(time_posttransfer > time_total) { + fprintf(moo, "posttransfer vs total: %" CURL_FORMAT_CURL_OFF_T + ".%06ld %" CURL_FORMAT_CURL_OFF_T ".%06ld\n", + (time_posttransfer / 1000000), + (long)(time_posttransfer % 1000000), + (time_total / 1000000), (long)(time_total % 1000000)); + } fclose(moo); } diff --git a/tests/libtest/lib549.c b/tests/libtest/lib549.c index aac8cb395..7bd67093f 100644 --- a/tests/libtest/lib549.c +++ b/tests/libtest/lib549.c @@ -52,7 +52,7 @@ CURLcode test(char *URL) test_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L); test_setopt(curl, CURLOPT_VERBOSE, 1L); if(libtest_arg3) { - /* enable ascii/text mode */ + /* enable ASCII/text mode */ test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); } diff --git a/tests/libtest/lib552.c b/tests/libtest/lib552.c index 0ecc0d62e..c0d30d68c 100644 --- a/tests/libtest/lib552.c +++ b/tests/libtest/lib552.c @@ -174,7 +174,7 @@ CURLcode test(char *URL) size_t i; static const char fill[] = "test data"; - config.trace_ascii = 1; /* enable ascii tracing */ + config.trace_ascii = 1; /* enable ASCII tracing */ global_init(CURL_GLOBAL_ALL); easy_init(curl); diff --git a/tests/libtest/lib556.c b/tests/libtest/lib556.c index 5e5c54ed3..06532c616 100644 --- a/tests/libtest/lib556.c +++ b/tests/libtest/lib556.c @@ -65,28 +65,35 @@ CURLcode test(char *URL) const char *request = "GET /556 HTTP/1.1\r\n" "Host: ninja\r\n\r\n"; - size_t iolen = 0; - - res = curl_easy_send(curl, request, strlen(request), &iolen); - - if(!res) { - /* we assume that sending always work */ + const char *sbuf = request; + size_t sblen = strlen(request); + size_t nwritten = 0, nread = 0; + + do { + char buf[1024]; + + if(sblen) { + res = curl_easy_send(curl, sbuf, sblen, &nwritten); + if(res && res != CURLE_AGAIN) + break; + if(nwritten > 0) { + sbuf += nwritten; + sblen -= nwritten; + } + } - do { - char buf[1024]; - /* busy-read like crazy */ - res = curl_easy_recv(curl, buf, sizeof(buf), &iolen); + /* busy-read like crazy */ + res = curl_easy_recv(curl, buf, sizeof(buf), &nread); - if(iolen) { - /* send received stuff to stdout */ - if(!write(STDOUT_FILENO, buf, iolen)) - break; - } + if(nread) { + /* send received stuff to stdout */ + if(!write(STDOUT_FILENO, buf, nread)) + break; + } - } while((res == CURLE_OK && iolen) || (res == CURLE_AGAIN)); - } + } while((res == CURLE_OK && nread) || (res == CURLE_AGAIN)); - if(iolen) + if(res && res != CURLE_AGAIN) res = TEST_ERR_FAILURE; } diff --git a/tests/libtest/lib579.c b/tests/libtest/lib579.c index 8b46e29d3..7e314c308 100644 --- a/tests/libtest/lib579.c +++ b/tests/libtest/lib579.c @@ -38,31 +38,38 @@ struct WriteThis { int counter; }; +static bool started = FALSE; +static size_t last_ul = 0; +static size_t last_ul_total = 0; + +static void progress_final_report(void) +{ + FILE *moo = fopen(libtest_arg2, "ab"); + fprintf(moo, "Progress: end UL %zu/%zu\n", last_ul, last_ul_total); + started = FALSE; + fclose(moo); +} + static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { - static int prev_ultotal = -1; - static int prev_ulnow = -1; (void)clientp; /* UNUSED */ (void)dltotal; /* UNUSED */ (void)dlnow; /* UNUSED */ - /* to avoid depending on timing, which will cause this progress function to - get called a different number of times depending on circumstances, we - only log these lines if the numbers are different from the previous - invoke */ - if((prev_ultotal != (int)ultotal) || - (prev_ulnow != (int)ulnow)) { + if(started && ulnow <= 0.0 && last_ul) { + progress_final_report(); + } + last_ul = (size_t)ulnow; + last_ul_total = (size_t)ultotal; + if(!started) { FILE *moo = fopen(libtest_arg2, "ab"); - if(moo) { - fprintf(moo, "Progress callback called with UL %d out of %d\n", - (int)ulnow, (int)ultotal); - fclose(moo); - } - prev_ulnow = (int) ulnow; - prev_ultotal = (int) ultotal; + fprintf(moo, "Progress: start UL %zu/%zu\n", last_ul, last_ul_total); + started = TRUE; + fclose(moo); } + return 0; } @@ -146,6 +153,8 @@ CURLcode test(char *URL) /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); + progress_final_report(); + test_cleanup: /* clean up the headers list */ diff --git a/tests/libtest/lib677.c b/tests/libtest/lib677.c index 68ac75c1c..5864924fc 100644 --- a/tests/libtest/lib677.c +++ b/tests/libtest/lib677.c @@ -75,7 +75,7 @@ CURLcode test(char *URL) curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sock); waitfd.fd = sock; } - curl_multi_wait(mcurl, &waitfd, sock == CURL_SOCKET_BAD ? 0 : 1, 500, + curl_multi_wait(mcurl, &waitfd, sock == CURL_SOCKET_BAD ? 0 : 1, 50, &mrun); if((sock != CURL_SOCKET_BAD) && (waitfd.revents & waitfd.events)) { size_t len = 0; @@ -83,7 +83,10 @@ CURLcode test(char *URL) if(!state) { CURLcode ec; ec = curl_easy_send(curl, cmd + pos, sizeof(cmd) - 1 - pos, &len); - if(ec != CURLE_OK) { + if(ec == CURLE_AGAIN) { + continue; + } + else if(ec) { fprintf(stderr, "curl_easy_send() failed, with code %d (%s)\n", (int)ec, curl_easy_strerror(ec)); res = ec; @@ -101,7 +104,10 @@ CURLcode test(char *URL) else if(pos < (ssize_t)sizeof(buf)) { CURLcode ec; ec = curl_easy_recv(curl, buf + pos, sizeof(buf) - pos, &len); - if(ec != CURLE_OK) { + if(ec == CURLE_AGAIN) { + continue; + } + else if(ec) { fprintf(stderr, "curl_easy_recv() failed, with code %d (%s)\n", (int)ec, curl_easy_strerror(ec)); res = ec; diff --git a/tests/libtest/mk-lib1521.pl b/tests/libtest/mk-lib1521.pl index 6fd332240..4b3921d77 100755 --- a/tests/libtest/mk-lib1521.pl +++ b/tests/libtest/mk-lib1521.pl @@ -29,11 +29,148 @@ # minimum and maximum long signed values my $minlong = "LONG_MIN"; my $maxlong = "LONG_MAX"; -# maximum long unsigned value -my $maxulong = "ULONG_MAX"; +# maximum curl_off_t +my $maxofft = "CURL_OFF_T_MAX"; my $line = ""; my $incomment = 0; +# Options allowed to return CURLE_BAD_FUNCTION_ARGUMENT if given a string they +# do not recognize as valid +my @bad_function_argument = ( + 'CURLOPT_DNS_LOCAL_IP4', + 'CURLOPT_DNS_LOCAL_IP6', + 'CURLOPT_DNS_SERVERS', + 'CURLOPT_PROXY_TLSAUTH_TYPE', + 'CURLOPT_SSLENGINE', + 'CURLOPT_TLSAUTH_TYPE', +); + +# Options allowed to return CURLE_UNSUPPORTED_PROTOCOL if given a string they +# do not recognize as valid +my @unsupported_protocol = ( + 'CURLOPT_PROTOCOLS_STR', + 'CURLOPT_REDIR_PROTOCOLS_STR', + ); + +# Options allowed to return CURLE_SSL_ENGINE_NOTFOUND if given a string they +# do not recognize as valid +my @ssl_engine_notfound = ( + 'CURLOPT_SSLENGINE', + ); + +# Options allowed to return CURLE_UNSUPPORTED_PROTOCOL if given a bad +# numerical input they do not recognize as valid +my @unsupported_protocol_num = ( + 'CURLOPT_HTTP_VERSION', + ); + +# Options allowed to return CURLE_NOT_BUILT_IN if given a bad +# numerical input they do not recognize as valid +my @not_built_in_num = ( + 'CURLOPT_HTTPAUTH', + 'CURLOPT_PROXYAUTH', + 'CURLOPT_SOCKS5_AUTH', + ); + + +# +# Generate a set of string checks +# + +my $allowedstringerrors = <, et al. + * Copyright (C) Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -72,23 +209,9 @@ #define LO $minlong #define HI $maxlong #define OFF_LO (curl_off_t) LO -#define OFF_HI (curl_off_t) $maxulong +#define OFF_HI (curl_off_t) $maxofft #define OFF_NO (curl_off_t) 0 -/* Unexpected error. - CURLE_NOT_BUILT_IN - means disabled at build - CURLE_UNKNOWN_OPTION - means no such option (anymore?) - CURLE_SSL_ENGINE_NOTFOUND - set unknown ssl engine - CURLE_UNSUPPORTED_PROTOCOL - set bad HTTP version - CURLE_BAD_FUNCTION_ARGUMENT - unsupported value - */ -#define UNEX(x) ((x) && \\ - ((x) != CURLE_NOT_BUILT_IN) && \\ - ((x) != CURLE_UNKNOWN_OPTION) && \\ - ((x) != CURLE_SSL_ENGINE_NOTFOUND) && \\ - ((x) != CURLE_UNSUPPORTED_PROTOCOL) && \\ - ((x) != CURLE_BAD_FUNCTION_ARGUMENT) ) - static size_t writecb(char *buffer, size_t size, size_t nitems, void *outstream) { @@ -111,18 +234,44 @@ return 0; } -static int err(const char *name, CURLcode val, int lineno) +static void errlongzero(const char *name, CURLcode code, int lineno) +{ + printf("%s set to 0 returned %d, \\"%s\\" on line %d\\n", + name, code, curl_easy_strerror(code), lineno); +} + +static void errlong(const char *name, CURLcode code, int lineno) +{ +$allowednumerrors + printf("%s set to non-zero returned %d, \\"%s\\" on line %d\\n", + name, code, curl_easy_strerror(code), lineno); +} + +static void errstring(const char *name, CURLcode code, int lineno) +{ + /* allow this set of options to return CURLE_BAD_FUNCTION_ARGUMENT + when given a strange string input */ +$allowedstringerrors + printf("%s set to a string returned %d, \\"%s\\" on line %d\\n", + name, code, curl_easy_strerror(code), lineno); +} + +static void err(const char *name, CURLcode val, int lineno) +{ + printf("%s returned %d, \\"%s\\" on line %d\\n", + name, val, curl_easy_strerror(val), lineno); +} + +static void errnull(const char *name, CURLcode val, int lineno) { - printf("CURLOPT_%s returned %d, \\"%s\\" on line %d\\n", + printf("%s set to NULL returned %d, \\"%s\\" on line %d\\n", name, val, curl_easy_strerror(val), lineno); - return (int)val; } -static int geterr(const char *name, CURLcode val, int lineno) +static void geterr(const char *name, CURLcode val, int lineno) { printf("CURLINFO_%s returned %d, \\"%s\\" on line %d\\n", name, val, curl_easy_strerror(val), lineno); - return (int)val; } static curl_progress_callback progresscb; @@ -146,6 +295,29 @@ static curl_resolver_start_callback resolver_start_cb; static curl_prereq_callback prereqcb; +/* long options that are okay to return + CURLE_BAD_FUNCTION_ARGUMENT */ +static bool bad_long(CURLcode res, int check) +{ + if(res != CURLE_BAD_FUNCTION_ARGUMENT) + return 0; /* not okay */ + + if(check < CURLOPTTYPE_OBJECTPOINT) { + /* LONG */ + return 1; + } + else if((check >= CURLOPTTYPE_OFF_T) && + (check < CURLOPTTYPE_BLOB)) { + /* OFF_T */ + return 1; + } + return 0; +} + +/* macro to check the first setopt of an option which then is allowed to get a + non-existing function return code back */ +#define present(x) ((x != CURLE_NOT_BUILT_IN) && (x != CURLE_UNKNOWN_OPTION)) + CURLcode test(char *URL) { CURL *curl = NULL; @@ -180,7 +352,6 @@ res = CURLE_OUT_OF_MEMORY; goto test_cleanup; } - HEADER ; @@ -235,78 +406,136 @@ if($_ =~ /^CURLOPT(?:DEPRECATED)?\(([^ ]*), ([^ ]*), (\d*)[,)]/) { my ($name, $type, $val)=($1, $2, $3); my $w=" "; - my $pref = "${w}res = curl_easy_setopt(curl, $name,"; - my $i = ' ' x (length($w) + 23); - my $check = " if(UNEX(res)) {\n err(\"$name\", res, __LINE__);\n goto test_cleanup;\n }\n"; + my $w2="$w$w"; + my $w3="$w$w$w"; + my $opt = $name; + $opt =~ s/^CURLOPT_//; + my $exists = "${w}{\n"; + # the first check for an option + my $fpref = "${exists}${w2}CURLcode first =\n${w3}curl_easy_setopt(curl, $name,"; + my $ifpresent = "${w2}if(present(first)) {\n"; + my $pref = "${w3}res = curl_easy_setopt(curl, $name,"; + my $i = ' ' x (length($w) + 25); + my $fcheck = <, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * we force our own host name, in order to make some tests machine independent - */ - -int gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) -{ - const char *force_hostname = getenv("CURL_GETHOSTNAME"); - if(force_hostname) { - strncpy(name, force_hostname, namelen); - name[namelen-1] = '\0'; - return 0; - } - - /* LD_PRELOAD used, but no hostname set, we'll just return a failure */ - return -1; -} diff --git a/tests/libtest/test1013.pl b/tests/libtest/test1013.pl index 9ae7723a2..6d10a3223 100755 --- a/tests/libtest/test1013.pl +++ b/tests/libtest/test1013.pl @@ -37,14 +37,13 @@ open(CURL, "$ARGV[1]") || die "Can't get curl $what list\n"; while( ) { - $curl_protocols = lc($_) if ( /$what:/i ); + $curl_protocols = $_ if ( /$what:/i ); } close CURL; $curl_protocols =~ s/\r//; $curl_protocols =~ /\w+: (.*)$/; @curl = split / /,$1; -@curl = sort @curl; # Read the output of curl-config my @curl_config; @@ -52,12 +51,16 @@ while( ) { chomp; - # ignore curl-config --features not in curl's feature list - push @curl_config, lc($_); + $_ = lc($_) if($what eq "protocols"); # accept uppercase protocols in curl-config + push @curl_config, $_; } close CURLCONFIG; -@curl_config = sort @curl_config; +# allow order mismatch to handle autotools builds with no 'sort -f' available +if($what eq "features") { + @curl = sort @curl; + @curl_config = sort @curl_config; +} my $curlproto = join ' ', @curl; my $curlconfigproto = join ' ', @curl_config; diff --git a/tests/pathhelp.pm b/tests/pathhelp.pm index 3afc5dacb..31de8ff4e 100644 --- a/tests/pathhelp.pm +++ b/tests/pathhelp.pm @@ -23,20 +23,20 @@ ########################################################################### # This Perl package helps with path transforming when running curl tests on -# Win32 platform with Msys or Cygwin. +# Windows platform with MSYS or Cygwin. # Three main functions 'sys_native_abs_path', 'sys_native_path' and # 'build_sys_abs_path' autodetect format of given pathnames. Following formats # are supported: # (1) /some/path - absolute path in Unix-style -# (2) D:/some/path - absolute path in Win32-style +# (2) D:/some/path - absolute path in Windows-style # (3) some/path - relative path -# (4) D:some/path - path relative to current directory on Win32 drive (paths -# like 'D:' are treated as 'D:./') (*) -# (5) \some/path - path from root directory on current Win32 drive (*) +# (4) D:some/path - path relative to current directory on Windows drive +# (paths like 'D:' are treated as 'D:./') (*) +# (5) \some/path - path from root directory on current Windows drive (*) # All forward '/' and back '\' slashes are treated identically except leading # slash in forms (1) and (5). # Forward slashes are simpler processed in Perl, do not require extra escaping -# for shell (unlike back slashes) and accepted by Win32 native programs, so +# for shell (unlike back slashes) and accepted by Windows native programs, so # all functions return paths with only forward slashes except # 'sys_native_path' which returns paths with first forward slash for form (5). # All returned paths don't contain any duplicated slashes, only single slashes @@ -46,8 +46,9 @@ # so all functions can be unconditionally used on all platforms. # # (*) CAUTION! Forms (4) and (5) are not recommended to use as they can be -# interpreted incorrectly in Perl and Msys/Cygwin environment have low -# control on Win32 current drive and Win32 current path on specific drive. +# interpreted incorrectly in Perl and MSYS/Cygwin environment have low +# control on Windows current drive and Windows current path on specific +# drive. package pathhelp; @@ -88,7 +89,7 @@ BEGIN { # Cached static variable, Perl 5.0-compatible. my $cygdrive_present; - # Returns boolean true if Win32 drives mounted with '/cygdrive/' prefix. + # Returns boolean true if Windows drives mounted with '/cygdrive/' prefix. sub drives_mounted_on_cygdrive { return $cygdrive_present if defined $cygdrive_present; $cygdrive_present = ((-e '/cygdrive/') && (-d '/cygdrive/')) ? 1 : 0; @@ -96,7 +97,7 @@ BEGIN { } } -my $use_cygpath; # Only for Win32: +my $use_cygpath; # Only for Windows: # undef - autodetect # 0 - do not use cygpath # 1 - use cygpath @@ -123,17 +124,17 @@ sub should_use_cygpath { sub normalize_path; ####################################################################### -# Returns current working directory in Win32 format on Windows. +# Returns current working directory in Windows format on Windows. # sub sys_native_current_path { return Cwd::getcwd() if !os_is_win(); my $cur_dir; if($^O eq 'msys') { - # MSys shell has built-in command. + # MSYS shell has built-in command. chomp($cur_dir = `bash -c 'pwd -W'`); if($? != 0) { - warn "Can't determine Win32 current directory.\n"; + warn "Can't determine Windows current directory.\n"; return undef; } # Add final slash if required. @@ -143,7 +144,7 @@ sub sys_native_current_path { # Do not use 'cygpath' - it falsely succeed on paths like '/cygdrive'. $cur_dir = `cmd "/c;" echo %__CD__%`; if($? != 0 || substr($cur_dir, 0, 1) eq '%') { - warn "Can't determine Win32 current directory.\n"; + warn "Can't determine Windows current directory.\n"; return undef; } # Remove both '\r' and '\n'. @@ -156,30 +157,30 @@ sub sys_native_current_path { } ####################################################################### -# Returns Win32 current drive letter with colon. +# Returns Windows current drive letter with colon. # sub get_win32_current_drive { - # Notice parameter "/c;" - it's required to turn off Msys's + # Notice parameter "/c;" - it's required to turn off MSYS's # transformation of '/c' and compatible with Cygwin. my $drive_letter = `cmd "/c;" echo %__CD__:~0,2%`; if($? != 0 || substr($drive_letter, 1, 1) ne ':') { - warn "Can't determine current Win32 drive letter.\n"; + warn "Can't determine current Windows drive letter.\n"; return undef; } return substr($drive_letter, 0, 2); } -# Internal function. Converts path by using Msys's built-in transformation. +# Internal function. Converts path by using MSYS's built-in transformation. # Returned path may contain duplicated and back slashes. sub do_msys_transform; # Internal function. Gets two parameters: first parameter must be single # drive letter ('c'), second optional parameter is path relative to drive's -# current working directory. Returns Win32 absolute normalized path. +# current working directory. Returns Windows absolute normalized path. sub get_abs_path_on_win32_drive; -# Internal function. Tries to find or guess Win32 version of given +# Internal function. Tries to find or guess Windows version of given # absolute Unix-style path. Other types of paths are not supported. # Returned paths contain only single forward slashes (no back and # duplicated slashes). @@ -187,7 +188,7 @@ sub get_abs_path_on_win32_drive; sub do_dumb_guessed_transform; ####################################################################### -# Converts given path to system native format, i.e. to Win32 format on +# Converts given path to system native format, i.e. to Windows format on # Windows platform. Relative paths converted to relative, absolute # paths converted to absolute. # @@ -210,12 +211,12 @@ sub sys_native_path { return $path; } elsif($path =~ m{^\\} || $path =~ m{^[a-zA-Z]:[^/\\]}) { - # Path is a directory or filename on Win32 current drive or relative - # path on current directory on specific Win32 drive. + # Path is a directory or filename on Windows current drive or relative + # path on current directory on specific Windows drive. # ('\path' or 'D:path') - # First type of paths is not processed by Msys transformation and + # First type of paths is not processed by MSYS transformation and # resolved to absolute path by 'cygpath'. - # Second type is not processed by Msys transformation and may be + # Second type is not processed by MSYS transformation and may be # incorrectly processed by 'cygpath' (for paths like 'D:..\../.\') my $first_char = ucfirst(substr($path, 0, 1)); @@ -224,7 +225,7 @@ sub sys_native_path { $path =~ s{[\\/]+}{/}g; # Convert leading slash back to forward slash to indicate - # directory on Win32 current drive or capitalize drive letter. + # directory on Windows current drive or capitalize drive letter. substr($path, 0, 1, $first_char); return $path; } @@ -237,7 +238,7 @@ sub sys_native_path { my $has_final_slash = ($path =~ m{[/\\]$}); - # Use 'cygpath', '-m' means Win32 path with forward slashes. + # Use 'cygpath', '-m' means Windows path with forward slashes. chomp($path = `cygpath -m '$path'`); if ($? != 0) { warn "Can't convert path by \"cygpath\".\n"; @@ -254,13 +255,13 @@ sub sys_native_path { return $path; } elsif($^O eq 'msys') { - # Msys transforms automatically path to Windows native form in staring - # program parameters if program is not Msys-based. + # MSYS transforms automatically path to Windows native form in staring + # program parameters if program is not MSYS-based. $path = do_msys_transform($path); return undef if !defined $path; - # Capitalize drive letter for Win32 paths. + # Capitalize drive letter for Windows paths. $path =~ s{^([a-z]:)}{\u$1}; # Replace any back and duplicated slashes with single forward slashes. @@ -268,7 +269,7 @@ sub sys_native_path { return $path; } elsif($path =~ s{^([a-zA-Z]):[/\\]}{\u$1:/}) { - # Path is already in Win32 form. ('C:\path') + # Path is already in Windows form. ('C:\path') # Replace any back and duplicated slashes with single forward slashes. $path =~ s{[\\/]+}{/}g; @@ -282,13 +283,13 @@ sub sys_native_path { return $path; } - # OS is Windows, but not Msys, path is absolute, path is not in Win32 + # OS is Windows, but not MSYS, path is absolute, path is not in Windows # form and 'cygpath' is not available. return do_dumb_guessed_transform($path); } ####################################################################### -# Converts given path to system native absolute path, i.e. to Win32 +# Converts given path to system native absolute path, i.e. to Windows # absolute format on Windows platform. Both relative and absolute # formats are supported for input. # @@ -304,7 +305,7 @@ sub sys_native_abs_path { } if($path =~ m{^([a-zA-Z]):($|[^/\\].*$)}) { - # Path is single drive with colon or relative path on Win32 drive. + # Path is single drive with colon or relative path on Windows drive. # ('C:' or 'C:path') # This kind of relative path is not processed correctly by 'cygpath'. # Get specified drive letter @@ -326,7 +327,7 @@ sub sys_native_abs_path { $path =~ s{^([\\/])[\\/]+}{$1}g; print "Inter result: \"$path\"\n"; - # Use 'cygpath', '-m' means Win32 path with forward slashes, + # Use 'cygpath', '-m' means Windows path with forward slashes, # '-a' means absolute path chomp($path = `cygpath -m -a '$path'`); if($? != 0) { @@ -344,14 +345,14 @@ sub sys_native_abs_path { return $path } elsif($path =~ s{^([a-zA-Z]):[/\\]}{\u$1:/}) { - # Path is already in Win32 form. ('C:\path') + # Path is already in Windows form. ('C:\path') # Replace any possible back slashes with forward slashes, # remove any duplicated slashes, resolve relative dirs. return normalize_path($path); } elsif(substr($path, 0, 1) eq '\\' ) { - # Path is directory or filename on Win32 current drive. ('\Windows') + # Path is directory or filename on Windows current drive. ('\Windows') my $w32drive = get_win32_current_drive(); return undef if !defined $w32drive; @@ -364,11 +365,11 @@ sub sys_native_abs_path { if(substr($path, 0, 1) ne '/') { # Path is in relative form. Resolve relative directories in Unix form - # *BEFORE* converting to Win32 form otherwise paths like + # *BEFORE* converting to Windows form otherwise paths like # '../../../cygdrive/c/windows' will not be resolved. my $cur_dir; - # MSys shell has built-in command. + # MSYS shell has built-in command. if($^O eq 'msys') { $cur_dir = `bash -c 'pwd -L'`; } @@ -389,8 +390,8 @@ sub sys_native_abs_path { return undef unless defined $path; if($^O eq 'msys') { - # Msys transforms automatically path to Windows native form in staring - # program parameters if program is not Msys-based. + # MSYS transforms automatically path to Windows native form in staring + # program parameters if program is not MSYS-based. $path = do_msys_transform($path); return undef if !defined $path; @@ -398,18 +399,18 @@ sub sys_native_abs_path { $path =~ s{[\\/]+}{/}g; return $path; } - # OS is Windows, but not Msys, path is absolute, path is not in Win32 + # OS is Windows, but not MSYS, path is absolute, path is not in Windows # form and 'cygpath' is not available. return do_dumb_guessed_transform($path); } -# Internal function. Converts given Unix-style absolute path to Win32 format. +# Internal function. Converts given Unix-style absolute path to Windows format. sub simple_transform_win32_to_unix; ####################################################################### # Converts given path to build system format absolute path, i.e. to -# Msys/Cygwin Unix-style absolute format on Windows platform. Both +# MSYS/Cygwin Unix-style absolute format on Windows platform. Both # relative and absolute formats are supported for input. # sub build_sys_abs_path { @@ -424,12 +425,12 @@ sub build_sys_abs_path { } if($path =~ m{^([a-zA-Z]):($|[^/\\].*$)}) { - # Path is single drive with colon or relative path on Win32 drive. + # Path is single drive with colon or relative path on Windows drive. # ('C:' or 'C:path') # This kind of relative path is not processed correctly by 'cygpath'. # Get specified drive letter - # Resolve relative dirs in Win32-style path or paths like 'D:/../c/' + # Resolve relative dirs in Windows-style path or paths like 'D:/../c/' # will be resolved incorrectly. # Replace any possible back slashes with forward slashes, # remove any duplicated slashes. @@ -442,7 +443,7 @@ sub build_sys_abs_path { # Path is empty string. Return current directory. # Empty string processed correctly by 'cygpath'. - # MSys shell has built-in command. + # MSYS shell has built-in command. if($^O eq 'msys') { chomp($path = `bash -c 'pwd -L'`); } @@ -477,7 +478,7 @@ sub build_sys_abs_path { return undef; } - # 'cygpath' removes last slash if path is root dir on Win32 drive. + # 'cygpath' removes last slash if path is root dir on Windows drive. # Restore it. $path .= '/' if($has_final_slash && substr($path, length($path) - 1, 1) ne '/'); @@ -485,9 +486,9 @@ sub build_sys_abs_path { return $path } elsif($path =~ m{^[a-zA-Z]:[/\\]}) { - # Path is already in Win32 form. ('C:\path') + # Path is already in Windows form. ('C:\path') - # Resolve relative dirs in Win32-style path otherwise paths + # Resolve relative dirs in Windows-style path otherwise paths # like 'D:/../c/' will be resolved incorrectly. # Replace any possible back slashes with forward slashes, # remove any duplicated slashes. @@ -497,13 +498,13 @@ sub build_sys_abs_path { return simple_transform_win32_to_unix($path); } elsif(substr($path, 0, 1) eq '\\') { - # Path is directory or filename on Win32 current drive. ('\Windows') + # Path is directory or filename on Windows current drive. ('\Windows') my $w32drive = get_win32_current_drive(); return undef if !defined $w32drive; # Combine drive and path. - # Resolve relative dirs in Win32-style path or paths like 'D:/../c/' + # Resolve relative dirs in Windows-style path or paths like 'D:/../c/' # will be resolved incorrectly. # Replace any possible back slashes with forward slashes, # remove any duplicated slashes. @@ -513,14 +514,14 @@ sub build_sys_abs_path { return simple_transform_win32_to_unix($path); } - # Path is not in any Win32 form. + # Path is not in any Windows form. if(substr($path, 0, 1) ne '/') { # Path in relative form. Resolve relative directories in Unix form - # *BEFORE* converting to Win32 form otherwise paths like + # *BEFORE* converting to Windows form otherwise paths like # '../../../cygdrive/c/windows' will not be resolved. my $cur_dir; - # MSys shell has built-in command. + # MSYS shell has built-in command. if($^O eq 'msys') { $cur_dir = `bash -c 'pwd -L'`; } @@ -566,7 +567,7 @@ sub normalize_path { my $prefix; my $have_root = 0; - # Check whether path starts from Win32 drive. ('C:path' or 'C:\path') + # Check whether path starts from Windows drive. ('C:path' or 'C:\path') if($path =~ m{^([a-zA-Z]:(/|\\)?)(.*$)}) { $prefix = $1; $have_root = 1 if defined $2; @@ -611,23 +612,23 @@ sub normalize_path { return $ret; } -# Internal function. Converts path by using Msys's built-in +# Internal function. Converts path by using MSYS's built-in # transformation. sub do_msys_transform { my ($path) = @_; return undef if $^O ne 'msys'; return $path if $path eq ''; - # Remove leading double forward slashes, as they turn off Msys + # Remove leading double forward slashes, as they turn off MSYS # transforming. $path =~ s{^/[/\\]+}{/}; - # Msys transforms automatically path to Windows native form in staring - # program parameters if program is not Msys-based. + # MSYS transforms automatically path to Windows native form in staring + # program parameters if program is not MSYS-based. # Note: already checked that $path is non-empty. $path = `cmd //c echo '$path'`; if($? != 0) { - warn "Can't transform path into Win32 form by using Msys" . + warn "Can't transform path into Windows form by using MSYS" . "internal transformation.\n"; return undef; } @@ -641,16 +642,16 @@ sub do_msys_transform { # Internal function. Gets two parameters: first parameter must be single # drive letter ('c'), second optional parameter is path relative to drive's -# current working directory. Returns Win32 absolute normalized path. +# current working directory. Returns Windows absolute normalized path. sub get_abs_path_on_win32_drive { my ($drv, $rel_path) = @_; my $res; # Get current directory on specified drive. - # "/c;" is compatible with both Msys and Cygwin. + # "/c;" is compatible with both MSYS and Cygwin. my $cur_dir_on_drv = `cmd "/c;" echo %=$drv:%`; if($? != 0) { - warn "Can't determine Win32 current directory on drive $drv:.\n"; + warn "Can't determine Windows current directory on drive $drv:.\n"; return undef; } @@ -675,7 +676,7 @@ sub get_abs_path_on_win32_drive { return normalize_path($res); } -# Internal function. Tries to find or guess Win32 version of given +# Internal function. Tries to find or guess Windows version of given # absolute Unix-style path. Other types of paths are not supported. # Returned paths contain only single forward slashes (no back and # duplicated slashes). @@ -690,13 +691,13 @@ sub do_dumb_guessed_transform { # Empty path is not valid. return undef if (length($path) == 0); - # RE to find Win32 drive letter + # RE to find Windows drive letter my $drv_ltr_re = drives_mounted_on_cygdrive() ? qr{^/cygdrive/([a-zA-Z])($|/.*$)} : qr{^/([a-zA-Z])($|/.*$)}; - # Check path whether path is Win32 directly mapped drive and try to - # transform it assuming that drive letter is matched to Win32 drive letter. + # Check path whether path is Windows directly mapped drive and try to + # transform it assuming that drive letter is matched to Windows drive letter. if($path =~ m{$drv_ltr_re}) { return ucfirst($1) . ':/' if(length($2) == 0); return ucfirst($1) . ':' . $2; @@ -736,14 +737,14 @@ sub do_dumb_guessed_transform { else { # Shouldn't happens as root '/' directory should always # be resolvable. - warn "Can't determine Win32 directory for path \"$path\".\n"; + warn "Can't determine Windows directory for path \"$path\".\n"; return undef; } } } -# Internal function. Converts given Unix-style absolute path to Win32 format. +# Internal function. Converts given Unix-style absolute path to Windows format. sub simple_transform_win32_to_unix { my ($path) = @_; @@ -752,12 +753,12 @@ sub simple_transform_win32_to_unix { my $res; chomp($res = `cygpath -a -u '$path'`); if($? != 0) { - warn "Can't determine Unix-style directory for Win32 " . + warn "Can't determine Unix-style directory for Windows " . "directory \"$path\".\n"; return undef; } - # 'cygpath' removes last slash if path is root dir on Win32 drive. + # 'cygpath' removes last slash if path is root dir on Windows drive. $res .= '/' if(substr($res, length($res) - 1, 1) ne '/' && $path =~ m{[/\\]$}); return $res; @@ -765,7 +766,7 @@ sub simple_transform_win32_to_unix { # 'cygpath' is not available, use guessed transformation. if($path !~ s{^([a-zA-Z]):(?:/|\\)}{/\l$1/}) { - warn "Can't determine Unix-style directory for Win32 " . + warn "Can't determine Unix-style directory for Windows " . "directory \"$path\".\n"; return undef; } diff --git a/tests/processhelp.pm b/tests/processhelp.pm index 170863f2f..48f385040 100644 --- a/tests/processhelp.pm +++ b/tests/processhelp.pm @@ -48,7 +48,7 @@ BEGIN { no warnings "all"; require Time::HiRes; }; - # portable sleeping falls back to native Sleep on Win32 + # portable sleeping falls back to native Sleep on Windows eval { no warnings "all"; require Win32; @@ -104,6 +104,22 @@ sub pidfromfile { return $pid; } +####################################################################### +# return Cygwin pid from virtual pid +# +sub winpid_to_pid { + my $vpid = $_[0]; + if(($^O eq 'cygwin' || $^O eq 'msys') && $vpid > 65536) { + my $pid = Cygwin::winpid_to_pid($vpid - 65536); + if($pid) { + return $pid; + } else { + return $vpid + } + } + return $vpid; +} + ####################################################################### # pidexists checks if a process with a given pid exists and is alive. # This will return the positive pid if the process exists and is alive. @@ -115,6 +131,7 @@ sub pidexists { if($pid > 0) { # verify if currently existing Windows process + $pid = winpid_to_pid($pid); if ($pid > 65536 && os_is_win()) { $pid -= 65536; if($^O ne 'MSWin32') { @@ -144,6 +161,7 @@ sub pidterm { if($pid > 0) { # request the process to quit + $pid = winpid_to_pid($pid); if ($pid > 65536 && os_is_win()) { $pid -= 65536; if($^O ne 'MSWin32') { @@ -169,13 +187,14 @@ sub pidkill { if($pid > 0) { # request the process to quit + $pid = winpid_to_pid($pid); if ($pid > 65536 && os_is_win()) { $pid -= 65536; if($^O ne 'MSWin32') { my $filter = "PID eq $pid"; my $result = `tasklist -fi \"$filter\" 2>nul`; if(index($result, "$pid") != -1) { - system("taskkill -f -fi \"$filter\" >nul 2>&1"); + system("taskkill -f -t -fi \"$filter\" >nul 2>&1"); # Windows XP Home compatibility system("tskill $pid >nul 2>&1"); } @@ -195,6 +214,7 @@ sub pidwait { my $pid = $_[0]; my $flags = $_[1]; + $pid = winpid_to_pid($pid); # check if the process exists if ($pid > 65536 && os_is_win()) { if($flags == &WNOHANG) { diff --git a/tests/runner.pm b/tests/runner.pm index 22ca0c7fd..105009d99 100644 --- a/tests/runner.pm +++ b/tests/runner.pm @@ -103,6 +103,8 @@ use testutil qw( runclient shell_quote subbase64 + subsha256base64file + substrippemfile subnewlines ); use valgrind; @@ -307,7 +309,7 @@ sub prepro { for my $s (@entiretest) { my $f = $s; $line++; - if($s =~ /^ *%if (.*)/) { + if($s =~ /^ *%if ([A-Za-z0-9!_-]*)/) { my $cond = $1; my $rev = 0; @@ -364,6 +366,8 @@ sub prepro { } subvariables(\$s, $testnum, "%"); subbase64(\$s); + subsha256base64file(\$s); + substrippemfile(\$s); subnewlines(0, \$s) if($data_crlf); push @out, $s; } @@ -401,6 +405,32 @@ sub logslocked { return @locks; } +####################################################################### +# Wait log locks to be unlocked +# +sub waitlockunlock { + # If a server logs advisor read lock file exists, it is an indication + # that the server has not yet finished writing out all its log files, + # including server request log files used for protocol verification. + # So, if the lock file exists the script waits here a certain amount + # of time until the server removes it, or the given time expires. + my $serverlogslocktimeout = shift; + + if($serverlogslocktimeout) { + my $lockretry = $serverlogslocktimeout * 20; + my @locks; + while((@locks = logslocked()) && $lockretry--) { + portable_sleep(0.05); + } + if(($lockretry < 0) && + ($serverlogslocktimeout >= $defserverlogslocktimeout)) { + logmsg "Warning: server logs lock timeout ", + "($serverlogslocktimeout seconds) expired (locks: " . + join(", ", @locks) . ")\n"; + } + } +} + ####################################################################### # Memory allocation test and failure torture testing. # @@ -1027,11 +1057,6 @@ sub singletest_clean { } } - # If a server logs advisor read lock file exists, it is an indication - # that the server has not yet finished writing out all its log files, - # including server request log files used for protocol verification. - # So, if the lock file exists the script waits here a certain amount - # of time until the server removes it, or the given time expires. my $serverlogslocktimeout = $defserverlogslocktimeout; my %cmdhash = getpartattr("client", "command"); if($cmdhash{'timeout'}) { @@ -1040,19 +1065,8 @@ sub singletest_clean { $serverlogslocktimeout = $1 if($1 >= 0); } } - if($serverlogslocktimeout) { - my $lockretry = $serverlogslocktimeout * 20; - my @locks; - while((@locks = logslocked()) && $lockretry--) { - portable_sleep(0.05); - } - if(($lockretry < 0) && - ($serverlogslocktimeout >= $defserverlogslocktimeout)) { - logmsg "Warning: server logs lock timeout ", - "($serverlogslocktimeout seconds) expired (locks: " . - join(", ", @locks) . ")\n"; - } - } + + waitlockunlock($serverlogslocktimeout); # Test harness ssh server does not have this synchronization mechanism, # this implies that some ssh server based tests might need a small delay @@ -1148,6 +1162,9 @@ sub runner_test_preprocess { # Start the servers needed to run this test case my ($why, $error) = singletest_startservers($testnum, \%testtimings); + # make sure no locks left for responsive test + waitlockunlock($defserverlogslocktimeout); + if(!$why) { ############################################################### diff --git a/tests/runtests.1 b/tests/runtests.1 deleted file mode 100644 index 01d490b2c..000000000 --- a/tests/runtests.1 +++ /dev/null @@ -1,230 +0,0 @@ -.\" ************************************************************************** -.\" * _ _ ____ _ -.\" * Project ___| | | | _ \| | -.\" * / __| | | | |_) | | -.\" * | (__| |_| | _ <| |___ -.\" * \___|\___/|_| \_\_____| -.\" * -.\" * Copyright (C) Daniel Stenberg, , et al. -.\" * -.\" * This software is licensed as described in the file COPYING, which -.\" * you should have received as part of this distribution. The terms -.\" * are also available at https://curl.se/docs/copyright.html. -.\" * -.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell -.\" * copies of the Software, and permit persons to whom the Software is -.\" * furnished to do so, under the terms of the COPYING file. -.\" * -.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -.\" * KIND, either express or implied. -.\" * -.\" * SPDX-License-Identifier: curl -.\" * -.\" ************************************************************************** -.\" -.TH runtests.pl 1 "06 Jun 2023" runtests runtests -.SH NAME -runtests.pl \- run one or more test cases -.SH SYNOPSIS -.B runtests.pl [options] [tests] -.SH DESCRIPTION -\fIruntests.pl\fP runs one, several or all the existing test cases in curl's -test suite. It is often called from the root Makefile of the curl package with -\&'make test'. -.SH "TESTS" -Specify which test(s) to run by specifying test numbers or keywords. - -If no test number or keyword is given, all existing tests that the script can -find will be considered for running. You can specify single test cases to run -by specifying test numbers space-separated, like "1 3 5 7 11", and you can -specify a range of tests like "45 to 67". - -Specify tests to not run with a leading exclamation point, like "!66", which -runs all available tests except number 66. - -Prefix a test number with a tilde (~) to still run it, but ignore the results. - -It is also possible to specify tests based on a keyword describing the test(s) -to run, like "FTPS". The keywords are strings used in the individual tests. - -You can also specify keywords with a leading exclamation point and the keyword -or phrase, like "!HTTP NTLM auth" to run all tests \fBexcept\fP those using -this keyword. Remember that the exclamation marks and spaces will need to be -quoted somehow when entered at many command shells. - -Prefix a keyword with a tilde (~) to still run it, but ignore the results. - -.SH "OUTPUT" - -When running without -s (short output), for instance when running runtests.pl -directly rather than via make, each test will emits a pair of lines like this: - -Test 0045...[simple HTTP Location: without protocol in initial URL] ---pd---e-v- OK (45 out of 1427, remaining: 16:08, took 6.188s, duration: 00:31) - -the first line contains the test number and a description. On the second line, -the characters at the beginning are flags indicating which aspects of curl's -behavior were checked by the test: - - s stdout - r stderr - p protocol - d data - u upload - P proxy - o output - e exit code - m memory - v valgrind - E the test was run event-based - -The remainder of the second line contains the test result, current test sequence, -total number of tests to be run and an estimated amount of time to complete the -test run. - -.SH OPTIONS -.IP "-a" -Continue running the rest of the test cases even if one test fails. By -default, the test script stops as soon as an error is detected. -.IP "-ac " -Provide a path to a curl binary to talk to APIs (currently only CI test APIs). -.IP "-am" -Display test results in automake style output (PASS/FAIL: [number] [name]). -.IP "-c " -Provide a path to a custom curl binary to run the tests with. Default is the -curl executable in the build tree. -.IP "-d" -Enable protocol debug: have the servers display protocol output. If used in -conjunction with parallel testing, it will be difficult to associate the logs -with the test being run. -.IP "-E " -Load the \fBexclude_file\fP with additional reasons why certain tests -should be skipped. Useful when testing with external HTTP proxies in -which case some of the tests aren't appropriate. -The file contains colon-delimited lines. The first field contains the -type of exclusion, the second field contains a pattern and the final -field contains the reason why matching tests should be skipped. -The exclusion types are \fkeyword\fP, \ftest\fP, and \ftool\fP. -.IP "-e" -Run the test event-based (if possible). This will make runtests invoke curl -with --test-event option. This option only works if both curl and libcurl were -built debug-enabled. -.IP "-f" -Force the test to run even if mentioned in DISABLED. -.IP "-g" -Run the given test(s) with gdb. This is best used on a single test case and -curl built --disable-shared. This then fires up gdb with command line set to -run the specified test case. Simply (set a break-point and) type 'run' to -start. -.IP "-gl" -Run the given test(s) with lldb. This is best used on a single test case and -curl built --disable-shared. This then fires up lldb with command line set to -run the specified test case. Simply (set a break-point and) type 'run' to -start. -.IP "-gw" -Run the given test(s) with gdb as a windowed application. -.IP "-h, --help" -Displays a help text about this program's command line options. -.IP "-j[num]" -Spawn num processes to run tests. This defaults to 0 to run tests serially -within a single process. Using a number greater than one allows multiple tests -to run in parallel, speeding up a test run. The optimum number is dependent on -the system and set of tests to run, but 7*number of CPU cores is a good figure -to start with, or 1.3*number of CPU cores if Valgrind is in use. Enabling -parallel tests is not recommended in conjunction with the \-g option. -.IP "-k" -Keep output and log files in log/ after a test run, even if no error was -detected. Useful for debugging. -.IP "-L " -Load and execute the specified file which should contain perl code. -This option allows one to change \fIruntests.pl\fP behaviour by overwriting -functions and variables and is useful when testing external proxies -using curl's regression test suite. -.IP "-l" -Lists all test case names. -.IP "-n" -Disable the check for and use of valgrind. -.IP "--no-debuginfod" -Delete the DEBUGINFOD_URLS variable if that is defined. Makes valgrind, gdb -etc not able to use this functionality. -.IP "-o " -Overwrite the specified internal \fBvariable\fP with \fBvalue\fP. -Useful to change variables that didn't get a dedicated flag to change them. -Check the source to see which variables are available. -.IP "-P " -Use the specified HTTP proxy when executing tests, even if the tests -themselves don't specify a proxy. This option allows one to test external -proxies using curl's regression test suite. -.IP "-p" -Prints out all files in "log/" to stdout when a test case fails. Very -practical when used in the automated and distributed tests since then the -people checking the failures and the reasons for them might not have physical -access to the machine and logs. -.IP "-R" -Run the tests in a scrambled, or randomized, order instead of sequentially. - -The random seed initially set for this is fixed per month and can be set with -\fI--seed\fP. -.IP "-r" -Display run time statistics. (Requires Perl Time::HiRes module) -.IP "-rf" -Display full run time statistics. (Requires Perl Time::HiRes module) -.IP "-rm" -Force removal of files by killing locking processes. (Windows only, -requires Sysinternals handle[64].exe to be on PATH) -.IP "--repeat=[num]" -This will repeat the given set of test numbers this many times. If no test -numbers are given, it will repeat ALL tests this many times. It iteratively -adds the new sequence at the end of the initially given one. - -If \fB-R\fP is also used, the scrambling is done after the repeats have -extended the test sequence. -.IP "-s" -Shorter output. Speaks less than default. -.IP "--seed=[num]" -When using \fI--shallow\fP or \fI-R\fP that randomize certain aspects of the -behavior, this option can set the initial seed. If not set, the random seed -will be set based on the currently set local year and month and the first line -of the "curl -V" output. -.IP "--shallow=[num]" -Used together with \fB-t\fP. This limits the number of tests to fail in -torture mode to no more than 'num' per test case. If this reduces the amount, -the script will randomly discard entries to fail until the amount is 'num'. - -The random seed initially set for this is fixed per month and can be set with -\fI--seed\fP. -.IP "-t[num]" -Selects a \fBtorture\fP test for the given tests. This makes runtests.pl first -run the tests once and count the number of memory allocations made. It then -reruns the test that number of times, each time forcing one of the allocations -to fail until all allocs have been tested. By setting \fInum\fP you can force -the allocation with that number to be set to fail at once instead of looping -through everyone, which is very handy when debugging and then often in -combination with \fI-g\fP. -.IP "-u" -Error instead of warning on server unexpectedly alive. -.IP "-v" -Enable verbose output. Speaks more than by default. If used in conjunction with -parallel testing, it will be difficult to associate the logs with the test -being run. -.IP "-vc " -Provide a path to a custom curl binary to run when verifying that the servers -running are indeed our test servers. Default is the curl executable in the -build tree. -.SH "RUNNING TESTS" -Many tests have conditions that must be met before the test case can run -fine. They could depend on built-in features in libcurl or features present in -the operating system or even in third-party libraries that curl may or may not -use. -.P -The test script checks most of these by itself to determine when it is -safe to attempt to run each test. Those which cannot be run due to -failed requirements will simply be skipped and listed at the completion -of all test cases. In some unusual configurations, the test script -cannot make the correct determination for all tests. In these cases, -the problematic tests can be skipped using the "!keyword" skip feature -documented earlier. -.SH "WRITING TESTS" -The simplest way to write test cases is to start with a similar existing test, -save it with a new number and then adjust it to fit. There's an attempt to -document the test case file format in the tests/FILEFORMAT.md. diff --git a/tests/runtests.md b/tests/runtests.md new file mode 100644 index 000000000..bfffc5818 --- /dev/null +++ b/tests/runtests.md @@ -0,0 +1,295 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Title: runtests.pl +Section: 1 +Source: runtests +See-also: + - runtests.pl +Added-in: 7.5 +--- + +# NAME + +runtests.pl - run one or more test cases + +# SYNOPSIS + +**runtests.pl [options] [tests]** + +# DESCRIPTION + +*runtests.pl* runs one, several or all the existing test cases in curl's +test suite. It is often called from the root Makefile of the curl package with +'make test'. + +# TESTS + +Specify which test(s) to run by specifying test numbers or keywords. + +If no test number or keyword is given, all existing tests that the script can +find are considered for running. You can specify single test cases to run by +specifying test numbers space-separated, like `1 3 5 7 11`, and you can +specify a range of tests like `45 to 67`. + +Specify tests to not run with a leading exclamation point, like `!66`, which +runs all available tests except number 66. + +Prefix a test number with a tilde (~) to still run it, but ignore the results. + +It is also possible to specify tests based on a keyword describing the test(s) +to run, like `FTPS`. The keywords are strings used in the individual tests. + +You can also specify keywords with a leading exclamation point and the keyword +or phrase, like "!HTTP NTLM auth" to run all tests **except** those using this +keyword. Remember that the exclamation marks and spaces need to be quoted +somehow when entered at many command shells. + +Prefix a keyword with a tilde (~) to still run it, but ignore the results. + +# OUTPUT + +When running without `-s` (short output), for instance when running +runtests.pl directly rather than via make, each test emits a pair of lines +like this: + + Test 0045...[simple HTTP Location: without protocol in initial URL] + --pd---e-v- OK (45 out of 1427, remaining: 16:08, took 6.188s, duration: 00:31) + +the first line contains the test number and a description. On the second line, +the characters at the beginning are flags indicating which aspects of curl's +behavior were checked by the test: + + s stdout + r stderr + p protocol + d data + u upload + P proxy + o output + e exit code + m memory + v valgrind + E the test was run event-based + +The remainder of the second line contains the test result, current test sequence, +total number of tests to be run and an estimated amount of time to complete the +test run. + +# OPTIONS + +## `-a` + +Continue running the rest of the test cases even if one test fails. By +default, the test script stops as soon as an error is detected. + +## `-ac \` + +Provide a path to a curl binary to talk to APIs (currently only CI test APIs). + +## `-am` + +Display test results in automake style output (`PASS/FAIL: [number] [name]`). + +## `-c\` + +Provide a path to a custom curl binary to run the tests with. Default is the +curl executable in the build tree. + +## `-d` + +Enable protocol debug: have the servers display protocol output. If used in +conjunction with parallel testing, it is difficult to associate the logs with +the specific test being run. + +## `-E \` + +Load the **exclude_file** with additional reasons why certain tests should be +skipped. Useful when testing with external HTTP proxies in which case some of +the tests are not appropriate. + +The file contains colon-delimited lines. The first field contains the type of +exclusion, the second field contains a pattern and the final field contains +the reason why matching tests should be skipped. The exclusion types are +*keyword*, *test*, and *tool*. + +## `-e` + +Run the test event-based (if possible). This makes runtests invoke curl with +--test-event option. This option only works if both curl and libcurl were +built debug-enabled. + +## `-f` + +Force the test to run even if mentioned in DISABLED. + +## `-g` + +Run the given test(s) with gdb. This is best used on a single test case and +curl built --disable-shared. This then fires up gdb with command line set to +run the specified test case. Simply (set a break-point and) type 'run' to +start. + +## `-gl` + +Run the given test(s) with lldb. This is best used on a single test case and +curl built --disable-shared. This then fires up lldb with command line set to +run the specified test case. Simply (set a break-point and) type 'run' to +start. + +## `-gw` + +Run the given test(s) with gdb as a windowed application. + +## `-h, --help` + +Displays a help text about this program's command line options. + +## `-j[num]` + +Spawn the given number of processes to run tests in. This defaults to 0 to run +tests serially within a single process. Using a number greater than one allows +multiple tests to run in parallel, speeding up a test run. The optimum number +is dependent on the system and set of tests to run, but 7 times number of CPU +cores is a good figure to start with, or 1.3 times number of CPU cores if +Valgrind is in use. Enabling parallel tests is not recommended in conjunction +with the -g option. + +## `-k` + +Keep output and log files in log/ after a test run, even if no error was +detected. Useful for debugging. + +## `-L \` + +Load and execute the specified file which should contain perl code. This +option allows one to change *runtests.pl* behavior by overwriting functions +and variables and is useful when testing external proxies using curl's +regression test suite. + +## `-l` + +Lists all test case names. + +## `-n` + +Disable the check for and use of valgrind. + +## `--no-debuginfod` + +Delete the `DEBUGINFOD_URLS` variable if that is defined. Makes valgrind, gdb +etc not able to use this functionality. + +## `-o \` + +Overwrite the specified internal **variable** with **value**. Useful to change +variables that did not get a dedicated flag to change them. Check the source to +see which variables are available. + +## `-P \` + +Use the specified HTTP proxy when executing tests, even if the tests +themselves do not specify a proxy. This option allows one to test external +proxies using curl's regression test suite. + +## `-p` + +Prints out all files in the log directory to stdout when a test case fails. +Practical when used in the automated and distributed tests since then the +people checking the failures and the reasons for them might not have physical +access to the machine and logs. + +## `-R` + +Run the tests in a scrambled, or randomized, order instead of sequentially. + +The random seed initially set for this is fixed per month and can be set with +*--seed*. + +## `-r` + +Display run time statistics. (Requires the `Perl Time::HiRes` module) + +## `-rf` + +Display full run time statistics. (Requires the `Perl Time::HiRes` module) + +## `-rm` + +Force removal of files by killing locking processes. (Windows only, requires +the **Sysinternals** `handle[64].exe` to be on PATH) + +## `--repeat=[num]` + +This repeats the given set of test numbers this many times. If no test numbers +are given, it repeats ALL tests this many times. It adds the new repeated +sequence at the end of the initially given one. + +If **-R** option is also used, the scrambling is done after the repeats have +extended the test sequence. + +## `-s` + +Shorter output. Speaks less than default. + +## `--seed=[num]` + +When using *--shallow* or *-R* that randomize certain aspects of the behavior, +this option can set the initial seed. If not set, the random seed is set based +on the currently set local year and month and the first line of the "curl -V" +output. + +## `--shallow=[num]` + +Used together with **-t**. This limits the number of tests to fail in torture +mode to no more than **num** per test case. If this reduces the amount, the +script randomly discards entries to fail until the amount is **num**. + +The random seed initially set for this is fixed per month and can be set with +*--seed*. + +## `-t[num]` + +Selects a **torture** test for the given tests. This makes runtests.pl first +run the tests once and count the number of memory allocations made. It then +reruns the test that number of times, each time forcing one of the allocations +to fail until all allocations have been tested. By setting *num* you can force +the allocation with that number to be set to fail at once instead of looping +through everyone, which is handy when debugging and then often in combination +with *-g*. + +## `-u` + +Error instead of warning on server unexpectedly alive. + +## `-v` + +Enable verbose output. Speaks more than by default. If used in conjunction +with parallel testing, it is difficult to associate the logs with the specific +test being run. + +## `-vc \` + +Provide a path to a custom curl binary to run when verifying that the servers +running are indeed our test servers. Default is the curl executable in the +build tree. + +# RUNNING TESTS + +Many tests have conditions that must be met before the test case can run fine. +They could depend on built-in features in libcurl or features present in the +operating system or even in third-party libraries that curl may or may not +use. + +The test script checks most of these by itself to determine when it is safe to +attempt to run each test. Those which cannot be run due to failed requirements +are simply skipped and listed at the completion of all test cases. In some +unusual configurations, the test script cannot make the correct determination +for all tests. In these cases, the problematic tests can be skipped using the +"!keyword" skip feature documented earlier. + +# WRITING TESTS + +The simplest way to write test cases is to start with a similar existing test, +save it with a new number and then adjust it to fit. There is an attempt to +document the test case file format in **tests/FILEFORMAT.md**. diff --git a/tests/runtests.pl b/tests/runtests.pl index e5d8e3da0..07802ad37 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -132,9 +132,6 @@ BEGIN my $resolver; # name of the resolver backend (for human presentation) -my $has_textaware; # set if running on a system that has a text mode concept - # on files. Windows for example - my %skipped; # skipped{reason}=counter, reasons for skip my @teststat; # teststat[testnum]=reason, reasons for skip my %disabled_keywords; # key words of tests to skip @@ -144,6 +141,8 @@ BEGIN my %ignored; # ignored results of test cases my %ignoretestcodes; # if test results are to be ignored +my $passedign; # tests passed with results ignored + my $timestats; # time stamping and stats generation my $fullstats; # show time stats for every single test my %timeprepini; # timestamp for each test preparation start @@ -329,8 +328,8 @@ sub catch_usr1 { my $disttests = ""; sub get_disttests { # If a non-default $TESTDIR is being used there may not be any - # Makefile.inc in which case there's nothing to do. - open(my $dh, "<", "$TESTDIR/Makefile.inc") or return; + # Makefile.am in which case there's nothing to do. + open(my $dh, "<", "$TESTDIR/Makefile.am") or return; while(<$dh>) { chomp $_; if(($_ =~ /^#/) ||($_ !~ /test/)) { @@ -535,9 +534,8 @@ sub checksystemfeatures { } if($curl =~ /win32|Windows|mingw(32|64)/) { # This is a Windows MinGW build or native build, we need to use - # Win32-style path. + # Windows-style path. $pwd = sys_native_current_path(); - $has_textaware = 1; $feature{"win32"} = 1; # set if built with MinGW (as opposed to MinGW-w64) $feature{"MinGW"} = 1 if ($curl =~ /-pc-mingw32/); @@ -593,6 +591,15 @@ sub checksystemfeatures { # nghttp2 supports h2c, hyper does not $feature{"h2c"} = 1; } + if ($libcurl =~ /AppleIDN/) { + $feature{"AppleIDN"} = 1; + } + if ($libcurl =~ /WinIDN/) { + $feature{"WinIDN"} = 1; + } + if ($libcurl =~ /libidn2/) { + $feature{"libidn2"} = 1; + } if ($libcurl =~ /libssh2/i) { $feature{"libssh2"} = 1; } @@ -682,7 +689,7 @@ sub checksystemfeatures { # 'https-proxy' is used as "server" so consider it a protocol push @protocols, 'https-proxy'; } - # UNICODE support + # Unicode support $feature{"Unicode"} = $feat =~ /Unicode/i; # Thread-safe init $feature{"threadsafe"} = $feat =~ /threadsafe/i; @@ -826,7 +833,9 @@ sub checksystemfeatures { } my $hostname=join(' ', runclientoutput("hostname")); + chomp $hostname; my $hosttype=join(' ', runclientoutput("uname -a")); + chomp $hosttype; my $hostos=$^O; # display summary information about curl and the test host @@ -835,8 +844,8 @@ sub checksystemfeatures { "* $libcurl\n", "* Features: $feat\n", "* Disabled: $dis\n", - "* Host: $hostname", - "* System: $hosttype", + "* Host: $hostname\n", + "* System: $hosttype\n", "* OS: $hostos\n"); if($jobs) { @@ -1034,7 +1043,7 @@ sub singletest_shouldrun { my @what; # what features are needed if($disttests !~ /test$testnum(\W|\z)/ ) { - logmsg "Warning: test$testnum not present in tests/data/Makefile.inc\n"; + logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n"; } if($disabled{$testnum}) { if(!$run_disabled) { @@ -1186,6 +1195,12 @@ sub singletest_count { return 0; } +# Make sure all line endings in the array are the same: CRLF +sub normalize_text { + my ($ref) = @_; + s/\r\n/\n/g for @$ref; + s/\n/\r\n/g for @$ref; +} ####################################################################### # Verify test succeeded @@ -1244,12 +1259,9 @@ sub singletest_check { # get the mode attribute my $filemode=$hash{'mode'}; - if($filemode && ($filemode eq "text") && $has_textaware) { - # text mode when running on windows: fix line endings - s/\r\n/\n/g for @validstdout; - s/\n/\r\n/g for @validstdout; - s/\r\n/\n/g for @actual; - s/\n/\r\n/g for @actual; + if($filemode && ($filemode eq "text")) { + normalize_text(\@validstdout); + normalize_text(\@actual); } if($hash{'nonewline'}) { @@ -1302,12 +1314,11 @@ sub singletest_check { # text mode check in hyper-mode. Sometimes necessary if the stderr # data *looks* like HTTP and thus has gotten CRLF newlines # mistakenly - s/\r\n/\n/g for @validstderr; + normalize_text(\@validstderr); } - if($filemode && ($filemode eq "text") && $has_textaware) { - # text mode when running on windows: fix line endings - s/\r\n/\n/g for @validstderr; - s/\n/\r\n/g for @validstderr; + if($filemode && ($filemode eq "text")) { + normalize_text(\@validstderr); + normalize_text(\@actual); } if($hash{'nonewline'}) { @@ -1399,10 +1410,8 @@ sub singletest_check { my %replycheckpartattr = getpartattr("reply", "datacheck".$partsuffix); # get the mode attribute my $filemode=$replycheckpartattr{'mode'}; - if($filemode && ($filemode eq "text") && $has_textaware) { - # text mode when running on windows: fix line endings - s/\r\n/\n/g for @replycheckpart; - s/\n/\r\n/g for @replycheckpart; + if($filemode && ($filemode eq "text")) { + normalize_text(\@replycheckpart); } if($replycheckpartattr{'nonewline'}) { # Yes, we must cut off the final newline from the final line @@ -1429,10 +1438,8 @@ sub singletest_check { } # get the mode attribute my $filemode=$replyattr{'mode'}; - if($filemode && ($filemode eq "text") && $has_textaware) { - # text mode when running on windows: fix line endings - s/\r\n/\n/g for @reply; - s/\n/\r\n/g for @reply; + if($filemode && ($filemode eq "text")) { + normalize_text(\@reply); } if($replyattr{'crlf'} || ($feature{"hyper"} && ($keywords{"HTTP"} @@ -1444,6 +1451,12 @@ sub singletest_check { if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) { # verify the received data my @out = loadarray($CURLOUT); + + # get the mode attribute + my $filemode=$replyattr{'mode'}; + if($filemode && ($filemode eq "text")) { + normalize_text(\@out); + } $res = compare($runnerid, $testnum, $testname, "data", \@out, \@reply); if ($res) { return -1; @@ -1464,6 +1477,8 @@ sub singletest_check { } for my $line (@upload) { subbase64(\$line); + subsha256base64file(\$line); + substrippemfile(\$line); } # verify uploaded data @@ -1474,6 +1489,9 @@ sub singletest_check { eval $strip; } } + if($hash{'crlf'}) { + subnewlines(1, \$_) for @upload; + } $res = compare($runnerid, $testnum, $testname, "upload", \@out, \@upload); if ($res) { @@ -1568,10 +1586,9 @@ sub singletest_check { my @stripfilepar = getpart("verify", "stripfile".$partsuffix); my $filemode=$hash{'mode'}; - if($filemode && ($filemode eq "text") && $has_textaware) { - # text mode when running on windows: fix line endings - s/\r\n/\n/g for @outfile; - s/\n/\r\n/g for @outfile; + if($filemode && ($filemode eq "text")) { + normalize_text(\@outfile); + normalize_text(\@generated); } if($hash{'crlf'} || ($feature{"hyper"} && ($keywords{"HTTP"} @@ -1765,6 +1782,8 @@ sub singletest_success { } if($errorreturncode==2) { + # ignored test success + $passedign .= "$testnum "; logmsg "Warning: test$testnum result is ignored, but passed!\n"; } } @@ -2564,6 +2583,21 @@ sub pickrunner { checksystemfeatures(); } +####################################################################### +# Output information about the curl build +# +if(!$listonly) { + if(open(my $fd, "<", "buildinfo.txt")) { + while(my $line = <$fd>) { + chomp $line; + if($line && $line !~ /^#/) { + logmsg("* buildinfo.$line\n"); + } + } + close($fd); + } +} + ####################################################################### # initialize configuration needed to set up servers # TODO: rearrange things so this can be called only in runner_init() @@ -2616,6 +2650,10 @@ sub disabledtests { } } } + else { + print STDERR "Cannot open $file, exiting\n"; + exit 3; + } } ####################################################################### @@ -3064,10 +3102,18 @@ sub testnumdetails { } if($total) { + if($passedign) { + my $sorted = numsortwords($passedign); + logmsg "::group::Passed Ignored Test details\n"; + testnumdetails("PASSED-IGNORED", $sorted); + logmsg "IGNORED: passed tests: $sorted\n"; + logmsg "::endgroup::\n"; + } + if($failedign) { - my $failedignsorted = numsortwords($failedign); - testnumdetails("FAIL-IGNORED", $failedignsorted); - logmsg "IGNORED: failed tests: $failedignsorted\n"; + my $sorted = numsortwords($failedign); + testnumdetails("FAIL-IGNORED", $sorted); + logmsg "IGNORED: failed tests: $sorted\n"; } logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n", $ok/$total*100); diff --git a/tests/secureserver.pl b/tests/secureserver.pl index 1b71c36c7..087764155 100755 --- a/tests/secureserver.pl +++ b/tests/secureserver.pl @@ -243,7 +243,7 @@ sub exit_signal_handler { if($stunnel =~ /tstunnel(\.exe)?$/) { $tstunnel_windows = 1; - # convert Cygwin/MinGW paths to Win32 format + # convert Cygwin/MinGW paths to Windows format $capath = pathhelp::sys_native_abs_path($capath); $certfile = pathhelp::sys_native_abs_path($certfile); } diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt index b84a0498a..e7e79fb76 100644 --- a/tests/server/CMakeLists.txt +++ b/tests/server/CMakeLists.txt @@ -21,62 +21,31 @@ # SPDX-License-Identifier: curl # ########################################################################### -set(TARGET_LABEL_PREFIX "Test server ") - -if(MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4306") -endif() - -function(SETUP_EXECUTABLE TEST_NAME) # ARGN are the files in the test - add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN}) - add_dependencies(testdeps ${TEST_NAME}) - string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME) - - include_directories( - ${CURL_SOURCE_DIR}/lib # for "curl_setup_once.h" - ${CURL_BINARY_DIR}/lib # for "curl_config.h" - ${CURL_BINARY_DIR}/include # for "curl/curl.h" - ${CURL_SOURCE_DIR}/src # for "tool_xattr.h" - ) - if(USE_ARES) - include_directories(${CARES_INCLUDE_DIR}) - endif() - - target_link_libraries(${TEST_NAME} ${CURL_LIBS}) +# Get 'noinst_PROGRAMS', '_SOURCES' variables +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") + +foreach(_target IN LISTS noinst_PROGRAMS) + set(_target_name "${_target}") + add_executable(${_target_name} EXCLUDE_FROM_ALL ${${_target}_SOURCES}) + add_dependencies(testdeps ${_target_name}) + target_include_directories(${_target_name} PRIVATE + "${CURL_BINARY_DIR}/lib" # for "curl_config.h" + "${CURL_SOURCE_DIR}/lib" # for "curl_setup.h" + "${CURL_SOURCE_DIR}/src" # for "tool_xattr.h" in disabled_SOURCES + ) + target_link_libraries(${_target_name} ${CURL_LIBS}) # Test servers simply are standalone programs that do not use libcurl # library. For convenience and to ease portability of these servers, # some source code files from the libcurl subdirectory are also used # to build the servers. In order to achieve proper linkage of these - # files on Win32 targets it is necessary to build the test servers + # files on Windows targets it is necessary to build the test servers # with CURL_STATICLIB defined, independently of how libcurl is built. - set_target_properties(${TEST_NAME} PROPERTIES - COMPILE_DEFINITIONS CURL_STATICLIB) # ${UPPER_TEST_NAME} - set_target_properties(${TEST_NAME} PROPERTIES - PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}") -endfunction() - - -transform_makefile_inc("Makefile.inc" - "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) - -foreach(EXECUTABLE_NAME ${noinst_PROGRAMS}) - setup_executable(${EXECUTABLE_NAME} ${${EXECUTABLE_NAME}_SOURCES}) + if(WIN32) + set_property(TARGET ${_target_name} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") + endif() + set_target_properties(${_target_name} PROPERTIES + OUTPUT_NAME "${_target}" + PROJECT_LABEL "Test server ${_target}") endforeach() - - -# set(useful -# getpart.c getpart.h -# ${CURL_SOURCE_DIR}/lib/strequal.c -# ${CURL_SOURCE_DIR}/lib/base64.c -# ${CURL_SOURCE_DIR}/lib/mprintf.c -# ${CURL_SOURCE_DIR}/lib/memdebug.c -# ${CURL_SOURCE_DIR}/lib/timeval.c -# ) - -# setup_executable(sws sws.c util.c util.h ${useful}) -# setup_executable(resolve resolve.c util.c util.h ${useful}) -# setup_executable(sockfilt sockfilt.c util.c util.h ${useful} ${CURL_SOURCE_DIR}/lib/inet_pton.c) -# setup_executable(getpart testpart.c ${useful}) -# setup_executable(tftpd tftpd.c util.c util.h ${useful} tftp.h) diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am index dda121377..9f279b81e 100644 --- a/tests/server/Makefile.am +++ b/tests/server/Makefile.am @@ -49,7 +49,7 @@ endif # Makefile.inc provides neat definitions include Makefile.inc -EXTRA_DIST = base64.pl Makefile.inc CMakeLists.txt +EXTRA_DIST = base64.pl CMakeLists.txt CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; diff --git a/tests/server/Makefile.in b/tests/server/Makefile.in index 87569ca67..e1b5dbfe5 100644 --- a/tests/server/Makefile.in +++ b/tests/server/Makefile.in @@ -114,9 +114,8 @@ build_triplet = @build@ host_triplet = @host@ @DOING_NATIVE_WINDOWS_TRUE@am__append_1 = -DCURL_STATICLIB noinst_PROGRAMS = getpart$(EXEEXT) resolve$(EXEEXT) rtspd$(EXEEXT) \ - sockfilt$(EXEEXT) sws$(EXEEXT) tftpd$(EXEEXT) \ - fake_ntlm$(EXEEXT) socksd$(EXEEXT) disabled$(EXEEXT) \ - mqttd$(EXEEXT) + sockfilt$(EXEEXT) sws$(EXEEXT) tftpd$(EXEEXT) socksd$(EXEEXT) \ + disabled$(EXEEXT) mqttd$(EXEEXT) subdir = tests/server ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/curl-amissl.m4 \ @@ -160,29 +159,7 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = ../../lib/fake_ntlm-mprintf.$(OBJEXT) \ - ../../lib/fake_ntlm-nonblock.$(OBJEXT) \ - ../../lib/fake_ntlm-strtoofft.$(OBJEXT) \ - ../../lib/fake_ntlm-warnless.$(OBJEXT) \ - ../../lib/fake_ntlm-timediff.$(OBJEXT) \ - ../../lib/fake_ntlm-dynbuf.$(OBJEXT) \ - ../../lib/fake_ntlm-strdup.$(OBJEXT) \ - ../../lib/fake_ntlm-strcase.$(OBJEXT) \ - ../../lib/fake_ntlm-curl_multibyte.$(OBJEXT) -am__objects_2 = -am__objects_3 = fake_ntlm-getpart.$(OBJEXT) \ - ../../lib/fake_ntlm-base64.$(OBJEXT) \ - ../../lib/fake_ntlm-memdebug.$(OBJEXT) -am__objects_4 = fake_ntlm-util.$(OBJEXT) -am_fake_ntlm_OBJECTS = $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) \ - fake_ntlm-fake_ntlm.$(OBJEXT) -fake_ntlm_OBJECTS = $(am_fake_ntlm_OBJECTS) -fake_ntlm_DEPENDENCIES = -fake_ntlm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(fake_ntlm_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_5 = ../../lib/getpart-mprintf.$(OBJEXT) \ +am__objects_1 = ../../lib/getpart-mprintf.$(OBJEXT) \ ../../lib/getpart-nonblock.$(OBJEXT) \ ../../lib/getpart-strtoofft.$(OBJEXT) \ ../../lib/getpart-warnless.$(OBJEXT) \ @@ -191,17 +168,18 @@ am__objects_5 = ../../lib/getpart-mprintf.$(OBJEXT) \ ../../lib/getpart-strdup.$(OBJEXT) \ ../../lib/getpart-strcase.$(OBJEXT) \ ../../lib/getpart-curl_multibyte.$(OBJEXT) -am__objects_6 = getpart-getpart.$(OBJEXT) \ +am__objects_2 = +am__objects_3 = getpart-getpart.$(OBJEXT) \ ../../lib/getpart-base64.$(OBJEXT) \ ../../lib/getpart-memdebug.$(OBJEXT) -am_getpart_OBJECTS = $(am__objects_5) $(am__objects_2) \ - $(am__objects_6) getpart-testpart.$(OBJEXT) +am_getpart_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) getpart-testpart.$(OBJEXT) getpart_OBJECTS = $(am_getpart_OBJECTS) getpart_DEPENDENCIES = getpart_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(getpart_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_7 = ../../lib/mqttd-mprintf.$(OBJEXT) \ +am__objects_4 = ../../lib/mqttd-mprintf.$(OBJEXT) \ ../../lib/mqttd-nonblock.$(OBJEXT) \ ../../lib/mqttd-strtoofft.$(OBJEXT) \ ../../lib/mqttd-warnless.$(OBJEXT) \ @@ -210,19 +188,19 @@ am__objects_7 = ../../lib/mqttd-mprintf.$(OBJEXT) \ ../../lib/mqttd-strdup.$(OBJEXT) \ ../../lib/mqttd-strcase.$(OBJEXT) \ ../../lib/mqttd-curl_multibyte.$(OBJEXT) -am__objects_8 = mqttd-getpart.$(OBJEXT) \ +am__objects_5 = mqttd-getpart.$(OBJEXT) \ ../../lib/mqttd-base64.$(OBJEXT) \ ../../lib/mqttd-memdebug.$(OBJEXT) -am__objects_9 = mqttd-util.$(OBJEXT) -am_mqttd_OBJECTS = $(am__objects_7) $(am__objects_2) $(am__objects_8) \ - $(am__objects_9) mqttd-mqttd.$(OBJEXT) \ +am__objects_6 = mqttd-util.$(OBJEXT) +am_mqttd_OBJECTS = $(am__objects_4) $(am__objects_2) $(am__objects_5) \ + $(am__objects_6) mqttd-mqttd.$(OBJEXT) \ ../../lib/mqttd-inet_pton.$(OBJEXT) mqttd_OBJECTS = $(am_mqttd_OBJECTS) mqttd_DEPENDENCIES = mqttd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mqttd_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_10 = ../../lib/resolve-mprintf.$(OBJEXT) \ +am__objects_7 = ../../lib/resolve-mprintf.$(OBJEXT) \ ../../lib/resolve-nonblock.$(OBJEXT) \ ../../lib/resolve-strtoofft.$(OBJEXT) \ ../../lib/resolve-warnless.$(OBJEXT) \ @@ -231,18 +209,18 @@ am__objects_10 = ../../lib/resolve-mprintf.$(OBJEXT) \ ../../lib/resolve-strdup.$(OBJEXT) \ ../../lib/resolve-strcase.$(OBJEXT) \ ../../lib/resolve-curl_multibyte.$(OBJEXT) -am__objects_11 = resolve-getpart.$(OBJEXT) \ +am__objects_8 = resolve-getpart.$(OBJEXT) \ ../../lib/resolve-base64.$(OBJEXT) \ ../../lib/resolve-memdebug.$(OBJEXT) -am__objects_12 = resolve-util.$(OBJEXT) -am_resolve_OBJECTS = $(am__objects_10) $(am__objects_2) \ - $(am__objects_11) $(am__objects_12) resolve-resolve.$(OBJEXT) +am__objects_9 = resolve-util.$(OBJEXT) +am_resolve_OBJECTS = $(am__objects_7) $(am__objects_2) \ + $(am__objects_8) $(am__objects_9) resolve-resolve.$(OBJEXT) resolve_OBJECTS = $(am_resolve_OBJECTS) resolve_DEPENDENCIES = resolve_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(resolve_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_13 = ../../lib/rtspd-mprintf.$(OBJEXT) \ +am__objects_10 = ../../lib/rtspd-mprintf.$(OBJEXT) \ ../../lib/rtspd-nonblock.$(OBJEXT) \ ../../lib/rtspd-strtoofft.$(OBJEXT) \ ../../lib/rtspd-warnless.$(OBJEXT) \ @@ -251,18 +229,18 @@ am__objects_13 = ../../lib/rtspd-mprintf.$(OBJEXT) \ ../../lib/rtspd-strdup.$(OBJEXT) \ ../../lib/rtspd-strcase.$(OBJEXT) \ ../../lib/rtspd-curl_multibyte.$(OBJEXT) -am__objects_14 = rtspd-getpart.$(OBJEXT) \ +am__objects_11 = rtspd-getpart.$(OBJEXT) \ ../../lib/rtspd-base64.$(OBJEXT) \ ../../lib/rtspd-memdebug.$(OBJEXT) -am__objects_15 = rtspd-util.$(OBJEXT) -am_rtspd_OBJECTS = $(am__objects_13) $(am__objects_2) \ - $(am__objects_14) $(am__objects_15) rtspd-rtspd.$(OBJEXT) +am__objects_12 = rtspd-util.$(OBJEXT) +am_rtspd_OBJECTS = $(am__objects_10) $(am__objects_2) \ + $(am__objects_11) $(am__objects_12) rtspd-rtspd.$(OBJEXT) rtspd_OBJECTS = $(am_rtspd_OBJECTS) rtspd_DEPENDENCIES = rtspd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rtspd_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_16 = ../../lib/sockfilt-mprintf.$(OBJEXT) \ +am__objects_13 = ../../lib/sockfilt-mprintf.$(OBJEXT) \ ../../lib/sockfilt-nonblock.$(OBJEXT) \ ../../lib/sockfilt-strtoofft.$(OBJEXT) \ ../../lib/sockfilt-warnless.$(OBJEXT) \ @@ -271,12 +249,12 @@ am__objects_16 = ../../lib/sockfilt-mprintf.$(OBJEXT) \ ../../lib/sockfilt-strdup.$(OBJEXT) \ ../../lib/sockfilt-strcase.$(OBJEXT) \ ../../lib/sockfilt-curl_multibyte.$(OBJEXT) -am__objects_17 = sockfilt-getpart.$(OBJEXT) \ +am__objects_14 = sockfilt-getpart.$(OBJEXT) \ ../../lib/sockfilt-base64.$(OBJEXT) \ ../../lib/sockfilt-memdebug.$(OBJEXT) -am__objects_18 = sockfilt-util.$(OBJEXT) -am_sockfilt_OBJECTS = $(am__objects_16) $(am__objects_2) \ - $(am__objects_17) $(am__objects_18) \ +am__objects_15 = sockfilt-util.$(OBJEXT) +am_sockfilt_OBJECTS = $(am__objects_13) $(am__objects_2) \ + $(am__objects_14) $(am__objects_15) \ sockfilt-sockfilt.$(OBJEXT) \ ../../lib/sockfilt-inet_pton.$(OBJEXT) sockfilt_OBJECTS = $(am_sockfilt_OBJECTS) @@ -284,7 +262,7 @@ sockfilt_DEPENDENCIES = sockfilt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sockfilt_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_19 = ../../lib/socksd-mprintf.$(OBJEXT) \ +am__objects_16 = ../../lib/socksd-mprintf.$(OBJEXT) \ ../../lib/socksd-nonblock.$(OBJEXT) \ ../../lib/socksd-strtoofft.$(OBJEXT) \ ../../lib/socksd-warnless.$(OBJEXT) \ @@ -293,19 +271,19 @@ am__objects_19 = ../../lib/socksd-mprintf.$(OBJEXT) \ ../../lib/socksd-strdup.$(OBJEXT) \ ../../lib/socksd-strcase.$(OBJEXT) \ ../../lib/socksd-curl_multibyte.$(OBJEXT) -am__objects_20 = socksd-getpart.$(OBJEXT) \ +am__objects_17 = socksd-getpart.$(OBJEXT) \ ../../lib/socksd-base64.$(OBJEXT) \ ../../lib/socksd-memdebug.$(OBJEXT) -am__objects_21 = socksd-util.$(OBJEXT) -am_socksd_OBJECTS = $(am__objects_19) $(am__objects_2) \ - $(am__objects_20) $(am__objects_21) socksd-socksd.$(OBJEXT) \ +am__objects_18 = socksd-util.$(OBJEXT) +am_socksd_OBJECTS = $(am__objects_16) $(am__objects_2) \ + $(am__objects_17) $(am__objects_18) socksd-socksd.$(OBJEXT) \ ../../lib/socksd-inet_pton.$(OBJEXT) socksd_OBJECTS = $(am_socksd_OBJECTS) socksd_DEPENDENCIES = socksd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(socksd_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_22 = ../../lib/sws-mprintf.$(OBJEXT) \ +am__objects_19 = ../../lib/sws-mprintf.$(OBJEXT) \ ../../lib/sws-nonblock.$(OBJEXT) \ ../../lib/sws-strtoofft.$(OBJEXT) \ ../../lib/sws-warnless.$(OBJEXT) \ @@ -313,18 +291,18 @@ am__objects_22 = ../../lib/sws-mprintf.$(OBJEXT) \ ../../lib/sws-dynbuf.$(OBJEXT) ../../lib/sws-strdup.$(OBJEXT) \ ../../lib/sws-strcase.$(OBJEXT) \ ../../lib/sws-curl_multibyte.$(OBJEXT) -am__objects_23 = sws-getpart.$(OBJEXT) ../../lib/sws-base64.$(OBJEXT) \ +am__objects_20 = sws-getpart.$(OBJEXT) ../../lib/sws-base64.$(OBJEXT) \ ../../lib/sws-memdebug.$(OBJEXT) -am__objects_24 = sws-util.$(OBJEXT) -am_sws_OBJECTS = $(am__objects_22) $(am__objects_2) $(am__objects_23) \ - $(am__objects_24) sws-sws.$(OBJEXT) \ +am__objects_21 = sws-util.$(OBJEXT) +am_sws_OBJECTS = $(am__objects_19) $(am__objects_2) $(am__objects_20) \ + $(am__objects_21) sws-sws.$(OBJEXT) \ ../../lib/sws-inet_pton.$(OBJEXT) sws_OBJECTS = $(am_sws_OBJECTS) sws_DEPENDENCIES = sws_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sws_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_25 = ../../lib/tftpd-mprintf.$(OBJEXT) \ +am__objects_22 = ../../lib/tftpd-mprintf.$(OBJEXT) \ ../../lib/tftpd-nonblock.$(OBJEXT) \ ../../lib/tftpd-strtoofft.$(OBJEXT) \ ../../lib/tftpd-warnless.$(OBJEXT) \ @@ -333,12 +311,12 @@ am__objects_25 = ../../lib/tftpd-mprintf.$(OBJEXT) \ ../../lib/tftpd-strdup.$(OBJEXT) \ ../../lib/tftpd-strcase.$(OBJEXT) \ ../../lib/tftpd-curl_multibyte.$(OBJEXT) -am__objects_26 = tftpd-getpart.$(OBJEXT) \ +am__objects_23 = tftpd-getpart.$(OBJEXT) \ ../../lib/tftpd-base64.$(OBJEXT) \ ../../lib/tftpd-memdebug.$(OBJEXT) -am__objects_27 = tftpd-util.$(OBJEXT) -am_tftpd_OBJECTS = $(am__objects_25) $(am__objects_2) \ - $(am__objects_26) $(am__objects_27) tftpd-tftpd.$(OBJEXT) +am__objects_24 = tftpd-util.$(OBJEXT) +am_tftpd_OBJECTS = $(am__objects_22) $(am__objects_2) \ + $(am__objects_23) $(am__objects_24) tftpd-tftpd.$(OBJEXT) tftpd_OBJECTS = $(am_tftpd_OBJECTS) tftpd_DEPENDENCIES = tftpd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -359,18 +337,7 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ../../lib/$(DEPDIR)/fake_ntlm-base64.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-strcase.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-strdup.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-timediff.Po \ - ../../lib/$(DEPDIR)/fake_ntlm-warnless.Po \ - ../../lib/$(DEPDIR)/getpart-base64.Po \ +am__depfiles_remade = ../../lib/$(DEPDIR)/getpart-base64.Po \ ../../lib/$(DEPDIR)/getpart-curl_multibyte.Po \ ../../lib/$(DEPDIR)/getpart-dynbuf.Po \ ../../lib/$(DEPDIR)/getpart-memdebug.Po \ @@ -463,8 +430,6 @@ am__depfiles_remade = ../../lib/$(DEPDIR)/fake_ntlm-base64.Po \ ../../lib/$(DEPDIR)/tftpd-timediff.Po \ ../../lib/$(DEPDIR)/tftpd-warnless.Po \ ./$(DEPDIR)/disabled-disabled.Po \ - ./$(DEPDIR)/fake_ntlm-fake_ntlm.Po \ - ./$(DEPDIR)/fake_ntlm-getpart.Po ./$(DEPDIR)/fake_ntlm-util.Po \ ./$(DEPDIR)/getpart-getpart.Po ./$(DEPDIR)/getpart-testpart.Po \ ./$(DEPDIR)/mqttd-getpart.Po ./$(DEPDIR)/mqttd-mqttd.Po \ ./$(DEPDIR)/mqttd-util.Po ./$(DEPDIR)/resolve-getpart.Po \ @@ -496,14 +461,12 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(disabled_SOURCES) $(fake_ntlm_SOURCES) $(getpart_SOURCES) \ - $(mqttd_SOURCES) $(resolve_SOURCES) $(rtspd_SOURCES) \ - $(sockfilt_SOURCES) $(socksd_SOURCES) $(sws_SOURCES) \ - $(tftpd_SOURCES) -DIST_SOURCES = $(disabled_SOURCES) $(fake_ntlm_SOURCES) \ - $(getpart_SOURCES) $(mqttd_SOURCES) $(resolve_SOURCES) \ - $(rtspd_SOURCES) $(sockfilt_SOURCES) $(socksd_SOURCES) \ - $(sws_SOURCES) $(tftpd_SOURCES) +SOURCES = $(disabled_SOURCES) $(getpart_SOURCES) $(mqttd_SOURCES) \ + $(resolve_SOURCES) $(rtspd_SOURCES) $(sockfilt_SOURCES) \ + $(socksd_SOURCES) $(sws_SOURCES) $(tftpd_SOURCES) +DIST_SOURCES = $(disabled_SOURCES) $(getpart_SOURCES) $(mqttd_SOURCES) \ + $(resolve_SOURCES) $(rtspd_SOURCES) $(sockfilt_SOURCES) \ + $(socksd_SOURCES) $(sws_SOURCES) $(tftpd_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -550,11 +513,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -600,7 +563,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -616,8 +578,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -652,10 +616,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -666,6 +628,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -674,6 +637,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -880,15 +844,10 @@ tftpd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \ tftpd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@ tftpd_CFLAGS = $(AM_CFLAGS) -fake_ntlm_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \ - fake_ntlm.c - -fake_ntlm_LDADD = @CURL_NETWORK_AND_TIME_LIBS@ -fake_ntlm_CFLAGS = $(AM_CFLAGS) disabled_SOURCES = disabled.c # Makefile.inc provides neat definitions -EXTRA_DIST = base64.pl Makefile.inc CMakeLists.txt +EXTRA_DIST = base64.pl CMakeLists.txt CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; CS_1 = @@ -946,32 +905,6 @@ disabled$(EXEEXT): $(disabled_OBJECTS) $(disabled_DEPENDENCIES) $(EXTRA_disabled ../../lib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../lib/$(DEPDIR) @: > ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-mprintf.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-nonblock.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-strtoofft.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-warnless.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-timediff.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-dynbuf.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-strdup.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-strcase.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-curl_multibyte.$(OBJEXT): \ - ../../lib/$(am__dirstamp) ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-base64.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) -../../lib/fake_ntlm-memdebug.$(OBJEXT): ../../lib/$(am__dirstamp) \ - ../../lib/$(DEPDIR)/$(am__dirstamp) - -fake_ntlm$(EXEEXT): $(fake_ntlm_OBJECTS) $(fake_ntlm_DEPENDENCIES) $(EXTRA_fake_ntlm_DEPENDENCIES) - @rm -f fake_ntlm$(EXEEXT) - $(AM_V_CCLD)$(fake_ntlm_LINK) $(fake_ntlm_OBJECTS) $(fake_ntlm_LDADD) $(LIBS) ../../lib/getpart-mprintf.$(OBJEXT): ../../lib/$(am__dirstamp) \ ../../lib/$(DEPDIR)/$(am__dirstamp) ../../lib/getpart-nonblock.$(OBJEXT): ../../lib/$(am__dirstamp) \ @@ -1196,17 +1129,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-base64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-strcase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-strdup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-timediff.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/fake_ntlm-warnless.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/getpart-base64.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/getpart-curl_multibyte.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/getpart-dynbuf.Po@am__quote@ # am--include-marker @@ -1300,9 +1222,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/tftpd-timediff.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../../lib/$(DEPDIR)/tftpd-warnless.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disabled-disabled.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake_ntlm-fake_ntlm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake_ntlm-getpart.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake_ntlm-util.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpart-getpart.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpart-testpart.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mqttd-getpart.Po@am__quote@ # am--include-marker @@ -1371,202 +1290,6 @@ disabled-disabled.obj: disabled.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(disabled_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o disabled-disabled.obj `if test -f 'disabled.c'; then $(CYGPATH_W) 'disabled.c'; else $(CYGPATH_W) '$(srcdir)/disabled.c'; fi` -../../lib/fake_ntlm-mprintf.o: ../../lib/mprintf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-mprintf.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Tpo -c -o ../../lib/fake_ntlm-mprintf.o `test -f '../../lib/mprintf.c' || echo '$(srcdir)/'`../../lib/mprintf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Tpo ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/mprintf.c' object='../../lib/fake_ntlm-mprintf.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-mprintf.o `test -f '../../lib/mprintf.c' || echo '$(srcdir)/'`../../lib/mprintf.c - -../../lib/fake_ntlm-mprintf.obj: ../../lib/mprintf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-mprintf.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Tpo -c -o ../../lib/fake_ntlm-mprintf.obj `if test -f '../../lib/mprintf.c'; then $(CYGPATH_W) '../../lib/mprintf.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/mprintf.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Tpo ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/mprintf.c' object='../../lib/fake_ntlm-mprintf.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-mprintf.obj `if test -f '../../lib/mprintf.c'; then $(CYGPATH_W) '../../lib/mprintf.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/mprintf.c'; fi` - -../../lib/fake_ntlm-nonblock.o: ../../lib/nonblock.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-nonblock.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Tpo -c -o ../../lib/fake_ntlm-nonblock.o `test -f '../../lib/nonblock.c' || echo '$(srcdir)/'`../../lib/nonblock.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Tpo ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/nonblock.c' object='../../lib/fake_ntlm-nonblock.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-nonblock.o `test -f '../../lib/nonblock.c' || echo '$(srcdir)/'`../../lib/nonblock.c - -../../lib/fake_ntlm-nonblock.obj: ../../lib/nonblock.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-nonblock.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Tpo -c -o ../../lib/fake_ntlm-nonblock.obj `if test -f '../../lib/nonblock.c'; then $(CYGPATH_W) '../../lib/nonblock.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/nonblock.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Tpo ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/nonblock.c' object='../../lib/fake_ntlm-nonblock.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-nonblock.obj `if test -f '../../lib/nonblock.c'; then $(CYGPATH_W) '../../lib/nonblock.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/nonblock.c'; fi` - -../../lib/fake_ntlm-strtoofft.o: ../../lib/strtoofft.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strtoofft.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Tpo -c -o ../../lib/fake_ntlm-strtoofft.o `test -f '../../lib/strtoofft.c' || echo '$(srcdir)/'`../../lib/strtoofft.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strtoofft.c' object='../../lib/fake_ntlm-strtoofft.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strtoofft.o `test -f '../../lib/strtoofft.c' || echo '$(srcdir)/'`../../lib/strtoofft.c - -../../lib/fake_ntlm-strtoofft.obj: ../../lib/strtoofft.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strtoofft.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Tpo -c -o ../../lib/fake_ntlm-strtoofft.obj `if test -f '../../lib/strtoofft.c'; then $(CYGPATH_W) '../../lib/strtoofft.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strtoofft.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strtoofft.c' object='../../lib/fake_ntlm-strtoofft.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strtoofft.obj `if test -f '../../lib/strtoofft.c'; then $(CYGPATH_W) '../../lib/strtoofft.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strtoofft.c'; fi` - -../../lib/fake_ntlm-warnless.o: ../../lib/warnless.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-warnless.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-warnless.Tpo -c -o ../../lib/fake_ntlm-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-warnless.Tpo ../../lib/$(DEPDIR)/fake_ntlm-warnless.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/warnless.c' object='../../lib/fake_ntlm-warnless.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c - -../../lib/fake_ntlm-warnless.obj: ../../lib/warnless.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-warnless.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-warnless.Tpo -c -o ../../lib/fake_ntlm-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-warnless.Tpo ../../lib/$(DEPDIR)/fake_ntlm-warnless.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/warnless.c' object='../../lib/fake_ntlm-warnless.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi` - -../../lib/fake_ntlm-timediff.o: ../../lib/timediff.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-timediff.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-timediff.Tpo -c -o ../../lib/fake_ntlm-timediff.o `test -f '../../lib/timediff.c' || echo '$(srcdir)/'`../../lib/timediff.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-timediff.Tpo ../../lib/$(DEPDIR)/fake_ntlm-timediff.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/timediff.c' object='../../lib/fake_ntlm-timediff.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-timediff.o `test -f '../../lib/timediff.c' || echo '$(srcdir)/'`../../lib/timediff.c - -../../lib/fake_ntlm-timediff.obj: ../../lib/timediff.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-timediff.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-timediff.Tpo -c -o ../../lib/fake_ntlm-timediff.obj `if test -f '../../lib/timediff.c'; then $(CYGPATH_W) '../../lib/timediff.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/timediff.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-timediff.Tpo ../../lib/$(DEPDIR)/fake_ntlm-timediff.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/timediff.c' object='../../lib/fake_ntlm-timediff.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-timediff.obj `if test -f '../../lib/timediff.c'; then $(CYGPATH_W) '../../lib/timediff.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/timediff.c'; fi` - -../../lib/fake_ntlm-dynbuf.o: ../../lib/dynbuf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-dynbuf.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Tpo -c -o ../../lib/fake_ntlm-dynbuf.o `test -f '../../lib/dynbuf.c' || echo '$(srcdir)/'`../../lib/dynbuf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Tpo ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/dynbuf.c' object='../../lib/fake_ntlm-dynbuf.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-dynbuf.o `test -f '../../lib/dynbuf.c' || echo '$(srcdir)/'`../../lib/dynbuf.c - -../../lib/fake_ntlm-dynbuf.obj: ../../lib/dynbuf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-dynbuf.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Tpo -c -o ../../lib/fake_ntlm-dynbuf.obj `if test -f '../../lib/dynbuf.c'; then $(CYGPATH_W) '../../lib/dynbuf.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/dynbuf.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Tpo ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/dynbuf.c' object='../../lib/fake_ntlm-dynbuf.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-dynbuf.obj `if test -f '../../lib/dynbuf.c'; then $(CYGPATH_W) '../../lib/dynbuf.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/dynbuf.c'; fi` - -../../lib/fake_ntlm-strdup.o: ../../lib/strdup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strdup.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strdup.Tpo -c -o ../../lib/fake_ntlm-strdup.o `test -f '../../lib/strdup.c' || echo '$(srcdir)/'`../../lib/strdup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strdup.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strdup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strdup.c' object='../../lib/fake_ntlm-strdup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strdup.o `test -f '../../lib/strdup.c' || echo '$(srcdir)/'`../../lib/strdup.c - -../../lib/fake_ntlm-strdup.obj: ../../lib/strdup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strdup.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strdup.Tpo -c -o ../../lib/fake_ntlm-strdup.obj `if test -f '../../lib/strdup.c'; then $(CYGPATH_W) '../../lib/strdup.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strdup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strdup.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strdup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strdup.c' object='../../lib/fake_ntlm-strdup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strdup.obj `if test -f '../../lib/strdup.c'; then $(CYGPATH_W) '../../lib/strdup.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strdup.c'; fi` - -../../lib/fake_ntlm-strcase.o: ../../lib/strcase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strcase.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strcase.Tpo -c -o ../../lib/fake_ntlm-strcase.o `test -f '../../lib/strcase.c' || echo '$(srcdir)/'`../../lib/strcase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strcase.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strcase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strcase.c' object='../../lib/fake_ntlm-strcase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strcase.o `test -f '../../lib/strcase.c' || echo '$(srcdir)/'`../../lib/strcase.c - -../../lib/fake_ntlm-strcase.obj: ../../lib/strcase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-strcase.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-strcase.Tpo -c -o ../../lib/fake_ntlm-strcase.obj `if test -f '../../lib/strcase.c'; then $(CYGPATH_W) '../../lib/strcase.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strcase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-strcase.Tpo ../../lib/$(DEPDIR)/fake_ntlm-strcase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/strcase.c' object='../../lib/fake_ntlm-strcase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-strcase.obj `if test -f '../../lib/strcase.c'; then $(CYGPATH_W) '../../lib/strcase.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/strcase.c'; fi` - -../../lib/fake_ntlm-curl_multibyte.o: ../../lib/curl_multibyte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-curl_multibyte.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Tpo -c -o ../../lib/fake_ntlm-curl_multibyte.o `test -f '../../lib/curl_multibyte.c' || echo '$(srcdir)/'`../../lib/curl_multibyte.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Tpo ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/curl_multibyte.c' object='../../lib/fake_ntlm-curl_multibyte.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-curl_multibyte.o `test -f '../../lib/curl_multibyte.c' || echo '$(srcdir)/'`../../lib/curl_multibyte.c - -../../lib/fake_ntlm-curl_multibyte.obj: ../../lib/curl_multibyte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-curl_multibyte.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Tpo -c -o ../../lib/fake_ntlm-curl_multibyte.obj `if test -f '../../lib/curl_multibyte.c'; then $(CYGPATH_W) '../../lib/curl_multibyte.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/curl_multibyte.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Tpo ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/curl_multibyte.c' object='../../lib/fake_ntlm-curl_multibyte.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-curl_multibyte.obj `if test -f '../../lib/curl_multibyte.c'; then $(CYGPATH_W) '../../lib/curl_multibyte.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/curl_multibyte.c'; fi` - -fake_ntlm-getpart.o: getpart.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-getpart.o -MD -MP -MF $(DEPDIR)/fake_ntlm-getpart.Tpo -c -o fake_ntlm-getpart.o `test -f 'getpart.c' || echo '$(srcdir)/'`getpart.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-getpart.Tpo $(DEPDIR)/fake_ntlm-getpart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpart.c' object='fake_ntlm-getpart.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-getpart.o `test -f 'getpart.c' || echo '$(srcdir)/'`getpart.c - -fake_ntlm-getpart.obj: getpart.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-getpart.obj -MD -MP -MF $(DEPDIR)/fake_ntlm-getpart.Tpo -c -o fake_ntlm-getpart.obj `if test -f 'getpart.c'; then $(CYGPATH_W) 'getpart.c'; else $(CYGPATH_W) '$(srcdir)/getpart.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-getpart.Tpo $(DEPDIR)/fake_ntlm-getpart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpart.c' object='fake_ntlm-getpart.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-getpart.obj `if test -f 'getpart.c'; then $(CYGPATH_W) 'getpart.c'; else $(CYGPATH_W) '$(srcdir)/getpart.c'; fi` - -../../lib/fake_ntlm-base64.o: ../../lib/base64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-base64.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-base64.Tpo -c -o ../../lib/fake_ntlm-base64.o `test -f '../../lib/base64.c' || echo '$(srcdir)/'`../../lib/base64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-base64.Tpo ../../lib/$(DEPDIR)/fake_ntlm-base64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/base64.c' object='../../lib/fake_ntlm-base64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-base64.o `test -f '../../lib/base64.c' || echo '$(srcdir)/'`../../lib/base64.c - -../../lib/fake_ntlm-base64.obj: ../../lib/base64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-base64.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-base64.Tpo -c -o ../../lib/fake_ntlm-base64.obj `if test -f '../../lib/base64.c'; then $(CYGPATH_W) '../../lib/base64.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/base64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-base64.Tpo ../../lib/$(DEPDIR)/fake_ntlm-base64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/base64.c' object='../../lib/fake_ntlm-base64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-base64.obj `if test -f '../../lib/base64.c'; then $(CYGPATH_W) '../../lib/base64.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/base64.c'; fi` - -../../lib/fake_ntlm-memdebug.o: ../../lib/memdebug.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-memdebug.o -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Tpo -c -o ../../lib/fake_ntlm-memdebug.o `test -f '../../lib/memdebug.c' || echo '$(srcdir)/'`../../lib/memdebug.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Tpo ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/memdebug.c' object='../../lib/fake_ntlm-memdebug.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-memdebug.o `test -f '../../lib/memdebug.c' || echo '$(srcdir)/'`../../lib/memdebug.c - -../../lib/fake_ntlm-memdebug.obj: ../../lib/memdebug.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT ../../lib/fake_ntlm-memdebug.obj -MD -MP -MF ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Tpo -c -o ../../lib/fake_ntlm-memdebug.obj `if test -f '../../lib/memdebug.c'; then $(CYGPATH_W) '../../lib/memdebug.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/memdebug.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Tpo ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/memdebug.c' object='../../lib/fake_ntlm-memdebug.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o ../../lib/fake_ntlm-memdebug.obj `if test -f '../../lib/memdebug.c'; then $(CYGPATH_W) '../../lib/memdebug.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/memdebug.c'; fi` - -fake_ntlm-util.o: util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-util.o -MD -MP -MF $(DEPDIR)/fake_ntlm-util.Tpo -c -o fake_ntlm-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-util.Tpo $(DEPDIR)/fake_ntlm-util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='fake_ntlm-util.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c - -fake_ntlm-util.obj: util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-util.obj -MD -MP -MF $(DEPDIR)/fake_ntlm-util.Tpo -c -o fake_ntlm-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-util.Tpo $(DEPDIR)/fake_ntlm-util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='fake_ntlm-util.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi` - -fake_ntlm-fake_ntlm.o: fake_ntlm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-fake_ntlm.o -MD -MP -MF $(DEPDIR)/fake_ntlm-fake_ntlm.Tpo -c -o fake_ntlm-fake_ntlm.o `test -f 'fake_ntlm.c' || echo '$(srcdir)/'`fake_ntlm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-fake_ntlm.Tpo $(DEPDIR)/fake_ntlm-fake_ntlm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fake_ntlm.c' object='fake_ntlm-fake_ntlm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-fake_ntlm.o `test -f 'fake_ntlm.c' || echo '$(srcdir)/'`fake_ntlm.c - -fake_ntlm-fake_ntlm.obj: fake_ntlm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -MT fake_ntlm-fake_ntlm.obj -MD -MP -MF $(DEPDIR)/fake_ntlm-fake_ntlm.Tpo -c -o fake_ntlm-fake_ntlm.obj `if test -f 'fake_ntlm.c'; then $(CYGPATH_W) 'fake_ntlm.c'; else $(CYGPATH_W) '$(srcdir)/fake_ntlm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fake_ntlm-fake_ntlm.Tpo $(DEPDIR)/fake_ntlm-fake_ntlm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fake_ntlm.c' object='fake_ntlm-fake_ntlm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fake_ntlm_CFLAGS) $(CFLAGS) -c -o fake_ntlm-fake_ntlm.obj `if test -f 'fake_ntlm.c'; then $(CYGPATH_W) 'fake_ntlm.c'; else $(CYGPATH_W) '$(srcdir)/fake_ntlm.c'; fi` - ../../lib/getpart-mprintf.o: ../../lib/mprintf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(getpart_CFLAGS) $(CFLAGS) -MT ../../lib/getpart-mprintf.o -MD -MP -MF ../../lib/$(DEPDIR)/getpart-mprintf.Tpo -c -o ../../lib/getpart-mprintf.o `test -f '../../lib/mprintf.c' || echo '$(srcdir)/'`../../lib/mprintf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/getpart-mprintf.Tpo ../../lib/$(DEPDIR)/getpart-mprintf.Po @@ -3310,18 +3033,7 @@ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-base64.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strcase.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strdup.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-timediff.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-warnless.Po - -rm -f ../../lib/$(DEPDIR)/getpart-base64.Po + -rm -f ../../lib/$(DEPDIR)/getpart-base64.Po -rm -f ../../lib/$(DEPDIR)/getpart-curl_multibyte.Po -rm -f ../../lib/$(DEPDIR)/getpart-dynbuf.Po -rm -f ../../lib/$(DEPDIR)/getpart-memdebug.Po @@ -3414,9 +3126,6 @@ distclean: distclean-am -rm -f ../../lib/$(DEPDIR)/tftpd-timediff.Po -rm -f ../../lib/$(DEPDIR)/tftpd-warnless.Po -rm -f ./$(DEPDIR)/disabled-disabled.Po - -rm -f ./$(DEPDIR)/fake_ntlm-fake_ntlm.Po - -rm -f ./$(DEPDIR)/fake_ntlm-getpart.Po - -rm -f ./$(DEPDIR)/fake_ntlm-util.Po -rm -f ./$(DEPDIR)/getpart-getpart.Po -rm -f ./$(DEPDIR)/getpart-testpart.Po -rm -f ./$(DEPDIR)/mqttd-getpart.Po @@ -3485,18 +3194,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-base64.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-curl_multibyte.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-dynbuf.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-memdebug.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-mprintf.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-nonblock.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strcase.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strdup.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-strtoofft.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-timediff.Po - -rm -f ../../lib/$(DEPDIR)/fake_ntlm-warnless.Po - -rm -f ../../lib/$(DEPDIR)/getpart-base64.Po + -rm -f ../../lib/$(DEPDIR)/getpart-base64.Po -rm -f ../../lib/$(DEPDIR)/getpart-curl_multibyte.Po -rm -f ../../lib/$(DEPDIR)/getpart-dynbuf.Po -rm -f ../../lib/$(DEPDIR)/getpart-memdebug.Po @@ -3589,9 +3287,6 @@ maintainer-clean: maintainer-clean-am -rm -f ../../lib/$(DEPDIR)/tftpd-timediff.Po -rm -f ../../lib/$(DEPDIR)/tftpd-warnless.Po -rm -f ./$(DEPDIR)/disabled-disabled.Po - -rm -f ./$(DEPDIR)/fake_ntlm-fake_ntlm.Po - -rm -f ./$(DEPDIR)/fake_ntlm-getpart.Po - -rm -f ./$(DEPDIR)/fake_ntlm-util.Po -rm -f ./$(DEPDIR)/getpart-getpart.Po -rm -f ./$(DEPDIR)/getpart-testpart.Po -rm -f ./$(DEPDIR)/mqttd-getpart.Po diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc index efd2fa05e..575a4d121 100644 --- a/tests/server/Makefile.inc +++ b/tests/server/Makefile.inc @@ -22,7 +22,7 @@ # ########################################################################### -noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd fake_ntlm \ +noinst_PROGRAMS = getpart resolve rtspd sockfilt sws tftpd \ socksd disabled mqttd CURLX_SRCS = \ @@ -109,9 +109,4 @@ tftpd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \ tftpd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@ tftpd_CFLAGS = $(AM_CFLAGS) -fake_ntlm_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \ - fake_ntlm.c -fake_ntlm_LDADD = @CURL_NETWORK_AND_TIME_LIBS@ -fake_ntlm_CFLAGS = $(AM_CFLAGS) - disabled_SOURCES = disabled.c diff --git a/tests/server/fake_ntlm.c b/tests/server/fake_ntlm.c deleted file mode 100644 index 669345035..000000000 --- a/tests/server/fake_ntlm.c +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Mandy Wu, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "server_setup.h" - -/* - * This is a fake ntlm_auth, which is used for testing NTLM single-sign-on. - * When DEBUGBUILD is defined, libcurl invoke this tool instead of real winbind - * daemon helper /usr/bin/ntlm_auth. This tool will accept commands and - * responses with a pre-written string saved in test case test2005. - */ - -#define ENABLE_CURLX_PRINTF -#include "curlx.h" /* from the private lib dir */ -#include "getpart.h" -#include "util.h" - -/* include memdebug.h last */ -#include "memdebug.h" - -#define LOGFILE "%s/fake_ntlm%ld.log" -static const char *logdir = "log"; - -const char *serverlogfile; - -/* - * Returns an allocated buffer with printable representation of input - * buffer contents or returns NULL on out of memory condition. - */ -static char *printable(char *inbuf, size_t inlength) -{ - char *outbuf; - char *newbuf; - size_t newsize; - size_t outsize; - size_t outincr = 0; - size_t i, o = 0; - -#define HEX_FMT_STR "[0x%02X]" -#define HEX_STR_LEN 6 -#define NOTHING_STR "[NOTHING]" -#define NOTHING_LEN 9 - - if(!inlength) - inlength = strlen(inbuf); - - if(inlength) { - outincr = ((inlength/2) < (HEX_STR_LEN + 1)) ? - HEX_STR_LEN + 1 : inlength/2; - outsize = inlength + outincr; - } - else - outsize = NOTHING_LEN + 1; - - outbuf = malloc(outsize); - if(!outbuf) - return NULL; - - if(!inlength) { - msnprintf(&outbuf[0], outsize, "%s", NOTHING_STR); - return outbuf; - } - - for(i = 0; i outsize - (HEX_STR_LEN + 1)) { - newsize = outsize + outincr; - newbuf = realloc(outbuf, newsize); - if(!newbuf) { - free(outbuf); - return NULL; - } - outbuf = newbuf; - outsize = newsize; - } - - if((inbuf[i] > 0x20) && (inbuf[i] < 0x7F)) { - outbuf[o] = inbuf[i]; - o++; - } - else { - msnprintf(&outbuf[o], outsize - o, HEX_FMT_STR, inbuf[i]); - o += HEX_STR_LEN; - } - - } - outbuf[o] = '\0'; - - return outbuf; -} - -int main(int argc, char *argv[]) -{ - char buf[1024]; - char logfilename[256]; - FILE *stream; - int error; - char *type1_input = NULL, *type3_input = NULL; - char *type1_output = NULL, *type3_output = NULL; - size_t size = 0; - long testnum; - const char *env; - int arg = 1; - const char *helper_user = "unknown"; - const char *helper_proto = "unknown"; - const char *helper_domain = "unknown"; - bool use_cached_creds = FALSE; - char *msgbuf; - - buf[0] = '\0'; - - while(argc > arg) { - if(!strcmp("--use-cached-creds", argv[arg])) { - use_cached_creds = TRUE; - arg++; - } - else if(!strcmp("--helper-protocol", argv[arg])) { - arg++; - if(argc > arg) - helper_proto = argv[arg++]; - } - else if(!strcmp("--username", argv[arg])) { - arg++; - if(argc > arg) - helper_user = argv[arg++]; - } - else if(!strcmp("--domain", argv[arg])) { - arg++; - if(argc > arg) - helper_domain = argv[arg++]; - } - else { - puts("Usage: fake_ntlm [option]\n" - " --use-cached-creds\n" - " --helper-protocol [protocol]\n" - " --username [username]\n" - " --domain [domain]"); - exit(1); - } - } - - env = getenv("CURL_NTLM_LOGDIR"); - if(env) { - logdir = env; - } - - env = getenv("CURL_NTLM_AUTH_TESTNUM"); - if(env) { - char *endptr; - long lnum = strtol(env, &endptr, 10); - if((endptr != env + strlen(env)) || (lnum < 1L)) { - fprintf(stderr, "Test number not valid in CURL_NTLM_AUTH_TESTNUM"); - exit(1); - } - testnum = lnum; - } - else { - fprintf(stderr, "Test number not specified in CURL_NTLM_AUTH_TESTNUM"); - exit(1); - } - - /* logmsg cannot be used until this file name is set */ - msnprintf(logfilename, sizeof(logfilename), LOGFILE, logdir, testnum); - serverlogfile = logfilename; - - logmsg("fake_ntlm (user: %s) (proto: %s) (domain: %s) (cached creds: %s)", - helper_user, helper_proto, helper_domain, - (use_cached_creds) ? "yes" : "no"); - - env = getenv("CURL_NTLM_AUTH_SRCDIR"); - if(env) { - path = env; - } - - stream = test2fopen(testnum, logdir); - if(!stream) { - error = errno; - logmsg("fopen() failed with error: %d %s", error, strerror(error)); - logmsg("Couldn't open test file %ld", testnum); - exit(1); - } - else { - /* get the ntlm_auth input/output */ - error = getpart(&type1_input, &size, "ntlm_auth_type1", "input", stream); - fclose(stream); - if(error || size == 0) { - logmsg("getpart() type 1 input failed with error: %d", error); - exit(1); - } - } - - stream = test2fopen(testnum, logdir); - if(!stream) { - error = errno; - logmsg("fopen() failed with error: %d %s", error, strerror(error)); - logmsg("Couldn't open test file %ld", testnum); - } - else { - size = 0; - error = getpart(&type3_input, &size, "ntlm_auth_type3", "input", stream); - fclose(stream); - if(error || size == 0) { - logmsg("getpart() type 3 input failed with error: %d", error); - exit(1); - } - } - - while(fgets(buf, sizeof(buf), stdin)) { - if(strcmp(buf, type1_input) == 0) { - stream = test2fopen(testnum, logdir); - if(!stream) { - error = errno; - logmsg("fopen() failed with error: %d %s", error, strerror(error)); - logmsg("Couldn't open test file %ld", testnum); - exit(1); - } - else { - size = 0; - error = getpart(&type1_output, &size, "ntlm_auth_type1", "output", - stream); - fclose(stream); - if(error || size == 0) { - logmsg("getpart() type 1 output failed with error: %d", error); - exit(1); - } - } - printf("%s", type1_output); - fflush(stdout); - } - else if(strncmp(buf, type3_input, strlen(type3_input)) == 0) { - stream = test2fopen(testnum, logdir); - if(!stream) { - error = errno; - logmsg("fopen() failed with error: %d %s", error, strerror(error)); - logmsg("Couldn't open test file %ld", testnum); - exit(1); - } - else { - size = 0; - error = getpart(&type3_output, &size, "ntlm_auth_type3", "output", - stream); - fclose(stream); - if(error || size == 0) { - logmsg("getpart() type 3 output failed with error: %d", error); - exit(1); - } - } - printf("%s", type3_output); - fflush(stdout); - } - else { - printf("Unknown request\n"); - msgbuf = printable(buf, 0); - if(msgbuf) { - logmsg("invalid input: '%s'\n", msgbuf); - free(msgbuf); - } - else - logmsg("OOM formatting invalid input: '%s'\n", buf); - exit(1); - } - } - logmsg("Exit"); - return 1; -} diff --git a/tests/server/getpart.c b/tests/server/getpart.c index 9ab9e88d5..5bfaad588 100644 --- a/tests/server/getpart.c +++ b/tests/server/getpart.c @@ -25,16 +25,8 @@ #include "getpart.h" -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ -/* just to please curl_base64.h we create a fake struct */ -struct Curl_easy { - int fake; -}; - #include "curl_base64.h" #include "curl_memory.h" @@ -52,6 +44,7 @@ struct Curl_easy { #endif #if defined(_MSC_VER) && defined(_DLL) +# pragma warning(push) # pragma warning(disable:4232) /* MSVC extension, dllimport identity */ #endif @@ -65,38 +58,10 @@ curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; #endif #if defined(_MSC_VER) && defined(_DLL) -# pragma warning(default:4232) /* MSVC extension, dllimport identity */ +# pragma warning(pop) #endif -/* - * Curl_convert_clone() returns a malloced copy of the source string (if - * returning CURLE_OK), with the data converted to network format. This - * function is used by base64 code in libcurl built to support data - * conversion. This is a DUMMY VERSION that returns data unmodified - for - * use by the test server only. - */ -CURLcode Curl_convert_clone(struct Curl_easy *data, - const char *indata, - size_t insize, - char **outbuf); -CURLcode Curl_convert_clone(struct Curl_easy *data, - const char *indata, - size_t insize, - char **outbuf) -{ - char *convbuf; - (void)data; - - convbuf = malloc(insize); - if(!convbuf) - return CURLE_OUT_OF_MEMORY; - - memcpy(convbuf, indata, insize); - *outbuf = convbuf; - return CURLE_OK; -} - /* * line_length() * diff --git a/tests/server/mqttd.c b/tests/server/mqttd.c index 6e24f5cc2..04382fb93 100644 --- a/tests/server/mqttd.c +++ b/tests/server/mqttd.c @@ -54,9 +54,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "inet_pton.h" @@ -769,11 +766,11 @@ static bool incoming(curl_socket_t listenfd) curl_socket_t newfd = accept(sockfd, NULL, NULL); if(CURL_SOCKET_BAD == newfd) { error = SOCKERRNO; - logmsg("accept(%" CURL_FORMAT_SOCKET_T ", NULL, NULL) " + logmsg("accept(%" FMT_SOCKET_T ", NULL, NULL) " "failed with error: (%d) %s", sockfd, error, sstrerror(error)); } else { - logmsg("====> Client connect, fd %" CURL_FORMAT_SOCKET_T ". " + logmsg("====> Client connect, fd %" FMT_SOCKET_T ". " "Read config from %s", newfd, configfile); set_advisor_read_lock(loglockfile); (void)mqttit(newfd); /* until done */ @@ -912,7 +909,7 @@ static curl_socket_t sockdaemon(curl_socket_t sock, rc = listen(sock, 5); if(0 != rc) { error = SOCKERRNO; - logmsg("listen(%" CURL_FORMAT_SOCKET_T ", 5) failed with error: (%d) %s", + logmsg("listen(%" FMT_SOCKET_T ", 5) failed with error: (%d) %s", sock, error, sstrerror(error)); sclose(sock); return CURL_SOCKET_BAD; diff --git a/tests/server/resolve.c b/tests/server/resolve.c index 8ae31bc59..cf59d48ea 100644 --- a/tests/server/resolve.c +++ b/tests/server/resolve.c @@ -38,16 +38,13 @@ #include #endif #ifdef _XOPEN_SOURCE_EXTENDED -/* This define is "almost" required to build on HPUX 11 */ +/* This define is "almost" required to build on HP-UX 11 */ #include #endif #ifdef HAVE_NETDB_H #include #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "util.h" diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c index ba6d158ed..5868c3438 100644 --- a/tests/server/rtspd.c +++ b/tests/server/rtspd.c @@ -46,9 +46,6 @@ #include /* for TCP_NODELAY */ #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "util.h" @@ -106,7 +103,7 @@ struct httprequest { bool auth; /* Authorization header present in the incoming request */ size_t cl; /* Content-Length of the incoming request */ bool digest; /* Authorization digest header found */ - bool ntlm; /* Authorization ntlm header found */ + bool ntlm; /* Authorization NTLM header found */ int pipe; /* if non-zero, expect this many requests to do a "piped" request/response */ int skip; /* if non-zero, the server is instructed to not read this diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index 4e5cb7e4b..8450a1189 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -99,9 +99,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "inet_pton.h" @@ -422,11 +419,11 @@ static bool read_data_block(unsigned char *buffer, ssize_t maxlen, #if defined(USE_WINSOCK) && !defined(CURL_WINDOWS_APP) /* - * WinSock select() does not support standard file descriptors, + * Winsock select() does not support standard file descriptors, * it can only check SOCKETs. The following function is an attempt * to re-create a select() function with support for other handle types. * - * select() function with support for WINSOCK2 sockets and all + * select() function with support for Winsock2 sockets and all * other handle types supported by WaitForMultipleObjectsEx() as * well as disk files, anonymous and names pipes, and character input. * @@ -683,7 +680,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, /* loop over the handles in the input descriptor sets */ nfd = 0; /* number of handled file descriptors */ nth = 0; /* number of internal waiting threads */ - nws = 0; /* number of handled WINSOCK sockets */ + nws = 0; /* number of handled Winsock sockets */ for(fd = 0; fd < nfds; fd++) { wsasock = curlx_sitosk(fd); wsaevents.lNetworkEvents = 0; @@ -829,7 +826,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds, FD_CLR(wsasock, exceptfds); } else { - /* try to handle the event with the WINSOCK2 functions */ + /* try to handle the event with the Winsock2 functions */ wsaevents.lNetworkEvents = 0; error = WSAEnumNetworkEvents(wsasock, handle, &wsaevents); if(error != SOCKET_ERROR) { @@ -1158,7 +1155,7 @@ static bool juggle(curl_socket_t *sockfdp, curl_socket_t newfd = accept(sockfd, NULL, NULL); if(CURL_SOCKET_BAD == newfd) { error = SOCKERRNO; - logmsg("accept(%" CURL_FORMAT_SOCKET_T ", NULL, NULL) " + logmsg("accept(%" FMT_SOCKET_T ", NULL, NULL) " "failed with error: (%d) %s", sockfd, error, sstrerror(error)); } else { @@ -1334,7 +1331,7 @@ static curl_socket_t sockdaemon(curl_socket_t sock, rc = listen(sock, 5); if(0 != rc) { error = SOCKERRNO; - logmsg("listen(%" CURL_FORMAT_SOCKET_T ", 5) failed with error: (%d) %s", + logmsg("listen(%" FMT_SOCKET_T ", 5) failed with error: (%d) %s", sock, error, sstrerror(error)); sclose(sock); return CURL_SOCKET_BAD; diff --git a/tests/server/socksd.c b/tests/server/socksd.c index 6fd647faa..f6d5889d4 100644 --- a/tests/server/socksd.c +++ b/tests/server/socksd.c @@ -71,9 +71,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "inet_pton.h" @@ -754,13 +751,13 @@ static bool incoming(curl_socket_t listenfd) curl_socket_t newfd = accept(sockfd, NULL, NULL); if(CURL_SOCKET_BAD == newfd) { error = SOCKERRNO; - logmsg("accept(%" CURL_FORMAT_SOCKET_T ", NULL, NULL) " + logmsg("accept(%" FMT_SOCKET_T ", NULL, NULL) " "failed with error: (%d) %s", sockfd, error, sstrerror(error)); } else { curl_socket_t remotefd; - logmsg("====> Client connect, fd %" CURL_FORMAT_SOCKET_T ". " + logmsg("====> Client connect, fd %" FMT_SOCKET_T ". " "Read config from %s", newfd, configfile); remotefd = sockit(newfd); /* SOCKS until done */ if(remotefd == CURL_SOCKET_BAD) { @@ -944,7 +941,7 @@ static curl_socket_t sockdaemon(curl_socket_t sock, rc = listen(sock, 5); if(0 != rc) { error = SOCKERRNO; - logmsg("listen(%" CURL_FORMAT_SOCKET_T ", 5) failed with error: (%d) %s", + logmsg("listen(%" FMT_SOCKET_T ", 5) failed with error: (%d) %s", sock, error, sstrerror(error)); sclose(sock); return CURL_SOCKET_BAD; @@ -1117,7 +1114,7 @@ int main(int argc, char *argv[]) #ifdef USE_UNIX_SOCKETS if(socket_domain == AF_UNIX) - logmsg("Listening on unix socket %s", unix_socket); + logmsg("Listening on Unix socket %s", unix_socket); else #endif logmsg("Listening on port %hu", port); diff --git a/tests/server/sws.c b/tests/server/sws.c index 53add587d..c8e9fde68 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -47,9 +47,6 @@ #include /* for TCP_NODELAY */ #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "inet_pton.h" @@ -109,7 +106,7 @@ struct httprequest { bool auth; /* Authorization header present in the incoming request */ size_t cl; /* Content-Length of the incoming request */ bool digest; /* Authorization digest header found */ - bool ntlm; /* Authorization ntlm header found */ + bool ntlm; /* Authorization NTLM header found */ int delay; /* if non-zero, delay this number of msec after connect */ int writedelay; /* if non-zero, delay this number of milliseconds between writes in the response */ @@ -2243,7 +2240,7 @@ int main(int argc, char *argv[]) protocol_type, socket_type, location_str); /* start accepting connections */ - rc = listen(sock, 5); + rc = listen(sock, 50); if(0 != rc) { error = SOCKERRNO; logmsg("listen() failed with error: (%d) %s", error, sstrerror(error)); @@ -2334,8 +2331,8 @@ int main(int argc, char *argv[]) curl_socket_t msgsock; do { msgsock = accept_connection(sock); - logmsg("accept_connection %" CURL_FORMAT_SOCKET_T - " returned %" CURL_FORMAT_SOCKET_T, sock, msgsock); + logmsg("accept_connection %" FMT_SOCKET_T + " returned %" FMT_SOCKET_T, sock, msgsock); if(CURL_SOCKET_BAD == msgsock) goto sws_cleanup; if(req->delay) diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c index afef684a4..3961ce22c 100644 --- a/tests/server/tftpd.c +++ b/tests/server/tftpd.c @@ -81,9 +81,6 @@ #include -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "util.h" @@ -343,7 +340,7 @@ static struct tftphdr *r_init(void) Free it and return next buffer filled with data. */ static int readit(struct testcase *test, struct tftphdr **dpp, - int convert /* if true, convert to ascii */) + int convert /* if true, convert to ASCII */) { struct bf *b; @@ -359,11 +356,11 @@ static int readit(struct testcase *test, struct tftphdr **dpp, } /* - * fill the input buffer, doing ascii conversions if requested + * fill the input buffer, doing ASCII conversions if requested * conversions are lf -> cr, lf and cr -> cr, nul */ static void read_ahead(struct testcase *test, - int convert /* if true, convert to ascii */) + int convert /* if true, convert to ASCII */) { int i; char *p; diff --git a/tests/server/util.c b/tests/server/util.c index eed305d15..a5cbd9cc7 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -28,7 +28,7 @@ #include #endif #ifdef _XOPEN_SOURCE_EXTENDED -/* This define is "almost" required to build on HPUX 11 */ +/* This define is "almost" required to build on HP-UX 11 */ #include #endif #ifdef HAVE_NETDB_H @@ -40,9 +40,6 @@ #include #endif -#define ENABLE_CURLX_PRINTF -/* make the curlx header define all printf() functions to use the curlx_* - versions instead */ #include "curlx.h" /* from the private lib dir */ #include "getpart.h" #include "util.h" @@ -143,7 +140,7 @@ static const char *win32_strerror(int err, char *buf, size_t buflen) return buf; } -/* use instead of perror() on generic windows */ +/* use instead of perror() on generic Windows */ void win32_perror(const char *msg) { char buf[512]; @@ -166,7 +163,7 @@ void win32_init(void) if(err) { perror("Winsock init failed"); - logmsg("Error initialising winsock -- aborting"); + logmsg("Error initialising Winsock -- aborting"); exit(1); } @@ -190,7 +187,7 @@ void win32_cleanup(void) _flushall(); } -/* socket-safe strerror (works on WinSock errors, too */ +/* socket-safe strerror (works on Winsock errors, too */ const char *sstrerror(int err) { static char buf[512]; @@ -469,6 +466,13 @@ long timediff(struct timeval newer, struct timeval older) typedef void (*SIGHANDLER_T)(int); +#if defined(_MSC_VER) && _MSC_VER == 1600 +/* Workaround for warning C4306: + 'type cast' : conversion from 'int' to 'void (__cdecl *)(int)' */ +#undef SIG_ERR +#define SIG_ERR ((SIGHANDLER_T)(size_t)-1) +#endif + #ifdef SIGHUP static SIGHANDLER_T old_sighup_handler = SIG_ERR; #endif @@ -550,7 +554,7 @@ static void exit_signal_handler(int signum) * They are included for ANSI compatibility. Therefore, you can set * signal handlers for these signals by using signal, and you can also * explicitly generate these signals by calling raise. Source: - * https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/signal + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal */ static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType) { @@ -690,7 +694,7 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, void install_signal_handlers(bool keep_sigalrm) { #ifdef _WIN32 - /* setup windows exit event before any signal can trigger */ + /* setup Windows exit event before any signal can trigger */ exit_event = CreateEvent(NULL, TRUE, FALSE, NULL); if(!exit_event) logmsg("cannot create exit event"); diff --git a/tests/servers.pm b/tests/servers.pm index d2c60aa6c..887cf271a 100644 --- a/tests/servers.pm +++ b/tests/servers.pm @@ -501,18 +501,6 @@ sub stopserver { my $result = 0; foreach my $server (@killservers) { my $pidfile = $serverpidfile{$server}; - my $pid = processexists($pidfile); - if($pid > 0) { - if($err_unexpected) { - logmsg "ERROR: "; - $result = -1; - } - else { - logmsg "Warning: "; - } - logmsg "$server server unexpectedly alive\n"; - killpid($verbose, $pid); - } unlink($pidfile) if(-f $pidfile); } @@ -2323,7 +2311,7 @@ sub responsive_httptls_server { sub startservers { my @what = @_; my ($pid, $pid2); - my $serr; # error while starting a server (as as the return enumerations) + my $serr; # error while starting a server (as of the return enumerations) for(@what) { my (@whatlist) = split(/\s+/,$_); my $what = lc($whatlist[0]); @@ -2432,8 +2420,9 @@ sub startservers { } } elsif($what eq "http") { - if($torture && $run{'http'} && + if($run{'http'} && !responsive_http_server("http", $verbose, 0, protoport('http'))) { + logmsg "* restarting unresponsive HTTP server\n"; if(stopserver('http')) { return ("failed stopping unresponsive HTTP server", 3); } diff --git a/tests/smbserver.py b/tests/smbserver.py index 3de8d69c0..17f0162ce 100755 --- a/tests/smbserver.py +++ b/tests/smbserver.py @@ -46,8 +46,9 @@ try: import impacket except ImportError: - sys.stderr.write('Python package impacket needs to be installed!\n') - sys.stderr.write('Use pip or your package manager to install it.\n') + sys.stderr.write( + 'Warning: Python package impacket is required for smb testing; ' + 'use pip or your package manager to install it\n') sys.exit(1) from impacket import smb as imp_smb from impacket import smbserver as imp_smbserver diff --git a/tests/sshserver.pl b/tests/sshserver.pl index 20939f0da..fcfe90a62 100755 --- a/tests/sshserver.pl +++ b/tests/sshserver.pl @@ -437,7 +437,7 @@ sub pp { #*************************************************************************** -# Convert paths for curl's tests running on Windows with Cygwin/Msys OpenSSH +# Convert paths for curl's tests running on Windows with Cygwin/MSYS OpenSSH # my $clipubkeyf_config; my $hstprvkeyf_config; diff --git a/tests/test1139.pl b/tests/test1139.pl index 421af70b8..6ecab78ec 100755 --- a/tests/test1139.pl +++ b/tests/test1139.pl @@ -177,6 +177,7 @@ sub scanmdpage { '--krb4' => 6, '--ftp-ssl' => 6, '--ftp-ssl-reqd' => 6, + '--include' => 6, # for tests and debug only, can remain hidden '--test-event' => 6, diff --git a/tests/test1165.pl b/tests/test1165.pl index 4045ef59b..621a93537 100755 --- a/tests/test1165.pl +++ b/tests/test1165.pl @@ -31,6 +31,8 @@ my %disable; # the DISABLE options that can be set by CMakeLists.txt my %disable_cmake; +# the DISABLE options propagated via curl_config.h.cmake +my %disable_cmake_config_h; # the DISABLE options that are used in C files my %file; # the DISABLE options that are documented @@ -64,13 +66,13 @@ sub scan_configure { } sub scanconf_cmake { - my ($f)=@_; + my ($hashr, $f)=@_; open S, "<$f"; while() { if(/(CURL_DISABLE_[A-Z0-9_]+)/g) { my ($sym)=($1); if(not $sym =~ /^(CURL_DISABLE_INSTALL|CURL_DISABLE_TESTS|CURL_DISABLE_SRP)$/) { - $disable_cmake{$sym} = 1; + $hashr->{$sym} = 1; } } } @@ -78,7 +80,11 @@ sub scanconf_cmake { } sub scan_cmake { - scanconf_cmake("$root/CMakeLists.txt"); + scanconf_cmake(\%disable_cmake, "$root/CMakeLists.txt"); +} + +sub scan_cmake_config_h { + scanconf_cmake(\%disable_cmake_config_h, "$root/lib/curl_config.h.cmake"); } sub scan_file { @@ -87,9 +93,7 @@ sub scan_file { while() { while(s/(CURL_DISABLE_[A-Z0-9_]+)//) { my ($sym)=($1); - if(not $sym =~ /^(CURL_DISABLE_SHA512_256)/) { # Skip this symbol, to be implemented - $file{$sym} = $source; - } + $file{$sym} = $source; } } close F; @@ -127,6 +131,7 @@ sub scan_docs { scan_configure(); scan_cmake(); +scan_cmake_config_h(); scan_sources(); scan_docs(); @@ -156,6 +161,14 @@ sub scan_docs { } } +# Check the CMakeLists.txt symbols for use in curl_config.h.cmake +for my $s (sort keys %disable_cmake) { + if(!$disable_cmake_config_h{$s}) { + printf "Present in CMakeLists.txt, not propagated via curl_config.h.cmake: %s\n", $s; + $error++; + } +} + # Check the code symbols for use in configure for my $s (sort keys %file) { if(!$disable{$s}) { diff --git a/tests/test1275.pl b/tests/test1275.pl index 353391d2f..e5f54c627 100755 --- a/tests/test1275.pl +++ b/tests/test1275.pl @@ -32,7 +32,9 @@ my %accepted=('curl' => 1, 'libcurl' => 1, 'macOS' => 1, + 'wolfSSL' => 1, 'mbedTLS' => 1, + 'rustls' => 1, 'c-ares' => 1); sub checkfile { diff --git a/tests/test1707.pl b/tests/test1707.pl new file mode 100644 index 000000000..d9090d4f9 --- /dev/null +++ b/tests/test1707.pl @@ -0,0 +1,135 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### +# +# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi +# a late evening in the #curl IRC channel. +# + +use strict; +use warnings; + +my $curl = shift @ARGV; +my $opt = shift @ARGV; +my $output = shift @ARGV; +my $txt = shift @ARGV; + +my $longopt; +my $shortopt; +if($opt =~ /^--/) { + $longopt = $opt; +} +else { + $shortopt = $opt; +} + +# first run the help command +system("$curl -h $opt > $output"); +my @curlout; +open(O, "<$output"); +push @curlout, ; +close(O); + +# figure out the short+long option combo using -h all*/ +open(C, "$curl -h all|"); +if($shortopt) { + while() { + if(/^ +$opt, ([^ ]*)/) { + $longopt = $1; + last; + } + } +} +else { + while() { + my $f = $_; + if(/ $opt /) { + if($f =~ /^ *(-(.)), $longopt/) { + $shortopt = $1; + } + last; + } + } +} +close(C); + +my $fullopt; +if($shortopt) { + $fullopt = "$shortopt, $longopt"; +} +else { + $fullopt = $longopt; +} + +open(R, "<$txt"); +my $show = 0; +my @txtout; +while() { + if(/^ $fullopt/) { + $show = 1; + } + elsif(/^ -/ && $show) { + last; + } + if($show) { + push @txtout, $_; + } +} +close(R); + +my $error; +if(scalar(@curlout) != scalar(@txtout)) { + printf "curl -h $opt is %d lines, $txt says %d lines\n", + scalar(@curlout), scalar(@txtout); + $error++; +} +else { + # same size, compare line by line + for my $i (0 .. $#curlout) { + # trim CRLF from the data + $curlout[$i] =~ s/[\r\n]//g; + $txtout[$i] =~ s/[\r\n]//g; + if($curlout[$i] ne $txtout[$i]) { + printf "Line %d\n", $i; + printf "-h : %s (%d bytes)\n", $curlout[$i], + length($curlout[$i]); + printf "file : %s (%d bytes)\n", $txtout[$i], + length($txtout[$i]); + + if(length($curlout[$i]) == length($txtout[$i])) { + my $l = length($curlout[$i]); + for my $c (0 .. $l) { + my $o = substr($curlout[$i], $c, 1); + my $t = substr($txtout[$i], $c, 1); + if($o ne $t) { + print "-h col %d: %02x\n", $c, ord($o); + print "file col %d: %02x\n", $c, ord($t); + } + } + } + $error++; + } + } +} +exit $error; diff --git a/tests/testcurl.1 b/tests/testcurl.1 deleted file mode 100644 index c88b27570..000000000 --- a/tests/testcurl.1 +++ /dev/null @@ -1,126 +0,0 @@ -.\" ************************************************************************** -.\" * _ _ ____ _ -.\" * Project ___| | | | _ \| | -.\" * / __| | | | |_) | | -.\" * | (__| |_| | _ <| |___ -.\" * \___|\___/|_| \_\_____| -.\" * -.\" * Copyright (C) Daniel Stenberg, , et al. -.\" * -.\" * This software is licensed as described in the file COPYING, which -.\" * you should have received as part of this distribution. The terms -.\" * are also available at https://curl.se/docs/copyright.html. -.\" * -.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell -.\" * copies of the Software, and permit persons to whom the Software is -.\" * furnished to do so, under the terms of the COPYING file. -.\" * -.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -.\" * KIND, either express or implied. -.\" * -.\" * SPDX-License-Identifier: curl -.\" * -.\" ************************************************************************** -.\" -.TH testcurl.pl 1 "24 Mar 2010" testcurl testcurl -.SH NAME -testcurl.pl \- (automatically) test curl -.SH SYNOPSIS -.B testcurl.pl [options] [dir] > output -.SH DESCRIPTION -\fItestcurl.pl\fP is the master script to use for automatic testing of curl -off git or daily snapshots. It is written for the purpose of being run from a -crontab job or similar at a regular interval. The output is suitable to be -mailed to curl-autocompile@haxx.se to be dealt with automatically (make sure -the subject includes the word "autobuild" as the mail gets silently discarded -otherwise). The most current build status (with a reasonable backlog) will be -published on the curl site, at https://curl.se/dev/builds.html - -\fIoptions\fP may be omitted. See \fI--setup\fP for what happens then. - -\fIdir\fP is a curl source dir, possibly a daily snapshot one. Using this will -make testcurl.pl skip the 'buildconf' stage and thus it removes the dependency -on automake, autoconf, libtool, GNU m4 and possibly a few other things. - -testcurl.pl will run 'buildconf' (or similar), run configure, build curl and -libcurl in a separate build directory and then run 'make test' to test the -fresh build. -.SH OPTIONS -.IP "--configure=[options]" -Configure options passed to configure. -.IP "--crosscompile" -This is a cross-compile. Makes \fItestcurl.pl\fP skip a few things. -.IP "--desc=[desc]" -Description of your test system. Displayed on the build summary page on the -weba site. -.IP "--email=[email]" -Set email address to report as. Displayed in the build logs on the site. -.IP "--mktarball=[command]" -Generic command to run after completed test. -.IP "--name=[name]" -Set name to report as. Displayed in the build summary on the site. -.IP "--nobuildconf" -Don't run buildconf. Useful when many builds use the same source tree, as then -only one need to do this. Also, if multiple processes run tests simultaneously -on the same source tree (like several hosts on a NFS mounted dir), -simultaneous buildconf invokes may cause problems. (Added in 7.14.1) -.IP "--nogitpull" -Don't update from git even though it is a git tree. Useful to still be able to -test even though your network is down, or similar. -.IP "--runtestopts=[options]" -Options that is passed to the runtests.pl script. Useful for disabling valgrind -by force, and similar. -.IP "--setup=[file name]" -File name to read setup from (deprecated). The old style of providing info. -If info is missing when testcurl.pl is started, it will prompt you and then -store the info in a 'setup' file, which it will look for on each invoke. Use -\fI--name\fP, \fI--email\fP, \fI--configure\fP and \fI--desc\fP instead. -.IP "--target=[your os]" -Specify your target environment. Recognized strings include 'vc', 'mingw32', -and \&'borland'. -.SH "INITIAL SETUP" -First you make a checkout from git (or you write a script that downloads daily -snapshots automatically, find inspiration in -https://curl.se/dev/autocurl.txt ): - -.nf - $ mkdir daily-curl - $ cd daily-curl - $ git clone https://github.com/curl/curl.git -.fi - -With the curl sources checked out, or downloaded, you can start testing right -away. If you want to use \fItestcurl.pl\fP without command line arguments and -to have it store and remember the config in its 'setup' file, then start it -manually now and fill in the answers to the questions it prompts you for: - -.nf - $ ./curl/tests/testcurl.pl -.fi - -Now you are ready to go. If you let the script run, it will perform a full -cycle and spit out lots of output. Mail us that output as described above. -.SH "CRONTAB EXAMPLE" -The crontab could include something like this: - -.nf -\# autobuild curl: -0 4 * * * cd daily-curl && ./testit.sh -.fi - -Where testit.sh is a shell script that could look similar to this: - -.nf -mail="mail -s autobuild curl-autocompile@haxx.se" -name="--name=whoami" -email="--email=iamme@nowhere" -desc='"--desc=supermachine Turbo 2000"' -testprog="perl ./curl/tests/testcurl.pl $name $email $desc" -opts1="--configure=--enable-debug" -opts2="--configure=--enable-ipv6" - -# run first test -$testprog $opts1 | $mail - -# run second test -$testprog $opts2 | $mail diff --git a/tests/testcurl.md b/tests/testcurl.md new file mode 100644 index 000000000..217f61fae --- /dev/null +++ b/tests/testcurl.md @@ -0,0 +1,138 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Title: testcurl.pl +Section: 1 +Source: testcurl +See-also: + - runtests.pl +Added-in: 7.11.2 +--- + +# NAME + +testcurl.pl - (automatically) test curl + +# SYNOPSIS + +**testcurl.pl [options] [dir] \> output** + +# DESCRIPTION + +*testcurl* is the master script to use for automatic distributed testing of +curl from git or daily snapshots. It is written for the purpose of being run +from a crontab job or similar at a regular interval. The output is suitable to +be mailed to **curl-autocompile@haxx.se** to be dealt with automatically (make +sure the subject includes the word "autobuild" as the mail gets silently +discarded otherwise). The most current build status (with a reasonable +backlog) is published on the curl site, at https://curl.se/dev/builds.html + +*options* may be omitted. See *--setup* for what happens then. + +*dir* is a curl source directory, possibly a daily snapshot one. Using this +makes *testcurl* skip the *autoreconf* stage and thus it removes the +dependency on automake, autoconf, libtool, GNU m4 and possibly a few other +things. + +*testcurl* runs `autoreconf` (or similar), configure, builds curl and libcurl +in a separate build directory and then runs `make test` to test the fresh +build. + +# OPTIONS + +## `--configure=[options]` + +Configure options passed to configure. + +## `--crosscompile` +`` +This is a cross-compile. Makes *testcurl* skip a few things. + +## `--desc=[desc]` + +Description of your test system. Displayed on the build summary page on the +website. + +## `--email=[email]` + +Set email address to report as. Displayed in the build logs on the site. + +## `--mktarball=[command]` + +Generic command to run after completed test. + +## `--name=[name]` + +Set name to report as. Displayed in the build summary on the site. + +## `--nobuildconf` + +Do not run autoreconf. Useful when many builds use the same source tree, as +then only one need to do this. Also, if multiple processes run tests +simultaneously on the same source tree (like several hosts on a NFS mounted +directory), simultaneous autoreconf invokes may cause problems. (Added in +7.14.1) + +## `--nogitpull` + +Do not update from git even though it is a git tree. Useful to still be able +to test even though your network is down, or similar. + +## `--runtestopts=[options]` + +Options that is passed to the runtests script. Useful for disabling valgrind +by force, and similar. + +## `--setup=[filename]` + +filename to read setup from (deprecated). The old style of providing info. If +info is missing when *testcurl* is started, it prompts you and then stores the +info in a 'setup' file, which it looks for on each invoke. Use *--name*, +*--email*, *--configure* and *--desc* instead. + +## `--target=[your os]` + +Specify your target environment. Recognized strings include `vc`, `mingw32`, +and `borland`. + +# INITIAL SETUP + +First, make a checkout from git (or you write a script that downloads daily +snapshots automatically): + + $ mkdir curl-testing + $ cd curl-testing + $ git clone https://github.com/curl/curl.git + +With the curl sources checked out, or downloaded, you can start testing right +away. If you want to use *testcurl* without command line arguments and to have +it store and remember the config in its 'setup' file, then start it manually +now and fill in the answers to the questions it prompts you for: + + $ ./curl/tests/testcurl + +Now you are ready to go. If you let the script run, it performs a full cycle +and spit out lots of output. Mail us that output as described above. + +# CRONTAB EXAMPLE + +The crontab could include something like this: + + # autobuild curl: + 0 4 * * * cd curl-testing && ./testit.sh + +Where `testit.sh` is a shell script that could look similar to this: + + mail="mail -s autobuild curl-autocompile@haxx.se" + name="--name=whoami" + email="--email=iamme@nowhere" + desc='"--desc=supermachine Turbo 2000"' + testprog="perl ./curl/tests/testcurl.pl $name $email $desc" + opts1="--configure=--enable-debug" + opts2="--configure=--enable-ipv6" + + # run first test + $testprog $opts1 | $mail + + # run second test + $testprog $opts2 | $mail diff --git a/tests/testcurl.pl b/tests/testcurl.pl index 09b0d98b1..dfb0c1976 100755 --- a/tests/testcurl.pl +++ b/tests/testcurl.pl @@ -51,7 +51,7 @@ # --notes=[notes] More human-readable information about this configuration # --nocvsup Don't pull from git even though it is a git tree # --nogitpull Don't pull from git even though it is a git tree -# --nobuildconf Don't run buildconf +# --nobuildconf Don't run autoreconf -fi # --noconfigure Don't run configure # --runtestopts=[options] Options to pass to runtests.pl # --setup=[file name] File name to read setup from (deprecated) @@ -77,7 +77,7 @@ $timestamp $notes); # version of this script -$version='2023-03-28'; +$version='2024-08-07'; $fixed=0; # Determine if we're running from git or a canned copy of curl, @@ -150,7 +150,7 @@ $libext = '.la'; # .la since both libcurl and libcares are made with libtool if ($^O eq 'MSWin32' || $targetos) { if (!$targetos) { - # If no target defined on Win32 lets assume vc + # If no target defined on Windows, let's assume vc $targetos = 'vc'; } if ($targetos =~ /vc/ || $targetos =~ /borland/) { @@ -460,7 +460,7 @@ sub get_host_triplet { } if($nobuildconf) { - logit "told to not run buildconf"; + logit "told to not run autoreconf -fi"; } elsif ($configurebuild) { # remove possible left-overs from the past @@ -479,11 +479,21 @@ sub get_host_triplet { close($f); close($log); - logit "buildconf was successful"; + logit "autoreconf -fi was successful"; } else { - logit "buildconf was successful (dummy message)"; + logit "autoreconf -fi was successful (dummy message)"; } + +} else { + # Show snapshot git commit when available + if (open (my $f, '<', "docs/tarball-commit.txt")) { + my $commit = <$f>; + chomp $commit; + logit "The most recent curl git commits:"; + logit " $commit"; + close($f); + } } # Set timestamp to the one in curlver.h if this isn't a git test build. @@ -683,7 +693,7 @@ sub findinpath { my $cmd = ($extvercmd ne '' ? $extvercmd.' ' : '')."./src/curl${binext} --version|"; open($f, "<", $cmd); while(<$f>) { - # strip CR from output on non-win32 platforms (wine on Linux) + # strip CR from output on non-Windows platforms (WINE on Linux) s/\r// if ($^O ne 'MSWin32'); print; } diff --git a/tests/testutil.pm b/tests/testutil.pm index 36bbe513c..4d68c5d28 100644 --- a/tests/testutil.pm +++ b/tests/testutil.pm @@ -40,6 +40,8 @@ BEGIN { shell_quote subbase64 subnewlines + subsha256base64file + substrippemfile ); our @EXPORT_OK = qw( @@ -48,6 +50,7 @@ BEGIN { ); } +use Digest::SHA qw(sha256); use MIME::Base64; use globalconfig qw( @@ -215,4 +218,41 @@ sub shell_quote { return $s; } +sub get_sha256_base64 { + my ($file_path) = @_; + return encode_base64(sha256(do { local $/; open my $fh, '<:raw', $file_path or die $!; <$fh> }), ""); +} + +sub subsha256base64file { + my ($thing) = @_; + + # SHA-256 base64 + while ($$thing =~ s/%sha256b64file\[(.*?)\]sha256b64file%/%%SHA256B64FILE%%/i) { + my $file_path = $1; + $file_path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; + my $hash_b64 = get_sha256_base64($file_path); + $$thing =~ s/%%SHA256B64FILE%%/$hash_b64/; + } +} + +sub get_file_content { + my ($file_path) = @_; + my $content = do { local $/; open my $fh, '<', $file_path or die $!; <$fh> }; + $content =~ s/(^|-----END .*?-----[\r\n]?)(.*?)(-----BEGIN .*?-----|$)/$1$3/gs; + $content =~ s/\r\n/\n/g; + chomp($content); + return $content; +} + +sub substrippemfile { + my ($thing) = @_; + + # File content substitution + while ($$thing =~ s/%strippemfile\[(.*?)\]strippemfile%/%%FILE%%/i) { + my $file_path = $1; + $file_path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; + my $file_content = get_file_content($file_path); + $$thing =~ s/%%FILE%%/$file_content/; + } +} 1; diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 07421220a..1e04b9959 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -22,19 +22,22 @@ # ########################################################################### +# Get 'UNITPROGS', 'UNITFILES' variables transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) +include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -include_directories( - ${CURL_SOURCE_DIR}/lib # for "curl_setup_once.h" - ${CURL_SOURCE_DIR}/tests/libtest - ${CURL_SOURCE_DIR}/src - ${CURL_BINARY_DIR}/lib # for "curl_config.h" - ${CURL_BINARY_DIR}/include # for "curl/curl.h" -) - -foreach(_testfile ${UNITPROGS}) - add_executable(${_testfile} EXCLUDE_FROM_ALL ${_testfile}.c ${UNITFILES}) - add_dependencies(testdeps ${_testfile}) - target_link_libraries(${_testfile} curltool curlu) +foreach(_target IN LISTS UNITPROGS) + set(_target_name "${_target}") + add_executable(${_target_name} EXCLUDE_FROM_ALL "${_target}.c" ${UNITFILES}) + add_dependencies(testdeps ${_target_name}) + target_link_libraries(${_target_name} curltool curlu) + target_include_directories(${_target_name} PRIVATE + "${CURL_BINARY_DIR}/lib" # for "curl_config.h" + "${CURL_SOURCE_DIR}/lib" # for "curl_setup.h" + "${CURL_SOURCE_DIR}/src" + "${CURL_SOURCE_DIR}/tests/libtest" + ) + set_target_properties(${_target_name} PROPERTIES + OUTPUT_NAME "${_target}" + PROJECT_LABEL "Test unit ${_target}") endforeach() diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index dc10b890e..ff05e1d5a 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -38,7 +38,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ -I$(top_srcdir)/src \ -I$(top_srcdir)/tests/libtest -EXTRA_DIST = Makefile.inc CMakeLists.txt README.md +EXTRA_DIST = CMakeLists.txt README.md CFLAGS += @CURL_CFLAG_EXTRAS@ @@ -47,7 +47,7 @@ LIBS = $(BLANK_AT_MAKETIME) LDADD = $(top_builddir)/src/libcurltool.la \ $(top_builddir)/lib/libcurlu.la \ - @LDFLAGS@ @LIBCURL_LIBS@ + @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@ AM_CPPFLAGS += -DCURL_STATICLIB -DUNITTESTS diff --git a/tests/unit/Makefile.in b/tests/unit/Makefile.in index 97bccd245..a8fd8b18a 100644 --- a/tests/unit/Makefile.in +++ b/tests/unit/Makefile.in @@ -570,11 +570,11 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURLVERSION = @CURLVERSION@ CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CA_EMBED = @CURL_CA_EMBED@ CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ @@ -620,7 +620,6 @@ HAVE_BROTLI = @HAVE_BROTLI@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_QUIC = @HAVE_OPENSSL_QUIC@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ HAVE_ZSTD = @HAVE_ZSTD@ @@ -636,8 +635,10 @@ IPV6_ENABLED = @IPV6_ENABLED@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@ +LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@ +LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@ +LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@ +LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@ LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@ LIBCURL_PC_REQUIRES_PRIVATE = @LIBCURL_PC_REQUIRES_PRIVATE@ LIBOBJS = @LIBOBJS@ @@ -672,10 +673,8 @@ PKGADD_NAME = @PKGADD_NAME@ PKGADD_PKG = @PKGADD_PKG@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ RC = @RC@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -686,6 +685,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ TEST_NGHTTPX = @TEST_NGHTTPX@ +USE_APPLE_IDN = @USE_APPLE_IDN@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ @@ -694,6 +694,7 @@ USE_LIBPSL = @USE_LIBPSL@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ +USE_LIBUV = @USE_LIBUV@ USE_MBEDTLS = @USE_MBEDTLS@ USE_MSH3 = @USE_MSH3@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -814,10 +815,10 @@ AUTOMAKE_OPTIONS = foreign nostdinc AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ -I$(top_srcdir)/lib -I$(top_srcdir)/src \ -I$(top_srcdir)/tests/libtest -DCURL_STATICLIB -DUNITTESTS -EXTRA_DIST = Makefile.inc CMakeLists.txt README.md +EXTRA_DIST = CMakeLists.txt README.md LDADD = $(top_builddir)/src/libcurltool.la \ $(top_builddir)/lib/libcurlu.la \ - @LDFLAGS@ @LIBCURL_LIBS@ + @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@ CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; diff --git a/tests/unit/README.md b/tests/unit/README.md index f11119005..38462902d 100644 --- a/tests/unit/README.md +++ b/tests/unit/README.md @@ -37,7 +37,7 @@ source file. The source file should be named `unitNNNN.c` where `NNNN` is a previously unused number. Add your test to `tests/unit/Makefile.inc` (if it is a unit test). Add your -test data file name to `tests/data/Makefile.inc` +test data file name to `tests/data/Makefile.am` You also need a separate file called `tests/data/testNNNN` (using the same number) that describes your test case. See the test1300 file for inspiration diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c index d94cfe178..60a0a0e1b 100644 --- a/tests/unit/unit1300.c +++ b/tests/unit/unit1300.c @@ -52,14 +52,14 @@ UNITTEST_START int unusedData_case1 = 1; int unusedData_case2 = 2; int unusedData_case3 = 3; - struct Curl_llist_element case1_list; - struct Curl_llist_element case2_list; - struct Curl_llist_element case3_list; - struct Curl_llist_element case4_list; - struct Curl_llist_element *head; - struct Curl_llist_element *element_next; - struct Curl_llist_element *element_prev; - struct Curl_llist_element *to_remove; + struct Curl_llist_node case1_list; + struct Curl_llist_node case2_list; + struct Curl_llist_node case3_list; + struct Curl_llist_node case4_list; + struct Curl_llist_node *head; + struct Curl_llist_node *element_next; + struct Curl_llist_node *element_prev; + struct Curl_llist_node *to_remove; size_t llist_size = Curl_llist_count(&llist); /** @@ -73,11 +73,12 @@ UNITTEST_START * 4: list dtor will be NULL */ - fail_unless(llist.size == 0, "list initial size should be zero"); - fail_unless(llist.head == NULL, "list head should initiate to NULL"); - fail_unless(llist.tail == NULL, "list tail should initiate to NULL"); - fail_unless(llist.dtor == test_Curl_llist_dtor, - "list dtor should initiate to test_Curl_llist_dtor"); + fail_unless(Curl_llist_count(&llist) == 0, + "list initial size should be zero"); + fail_unless(Curl_llist_head(&llist) == NULL, + "list head should initiate to NULL"); + fail_unless(Curl_llist_tail(&llist) == NULL, + "list tail should initiate to NULL"); /** * testing Curl_llist_insert_next @@ -89,15 +90,16 @@ UNITTEST_START * 3: list tail will be the same as list head */ - Curl_llist_insert_next(&llist, llist.head, &unusedData_case1, &case1_list); + Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case1, + &case1_list); fail_unless(Curl_llist_count(&llist) == 1, "List size should be 1 after adding a new element"); /* test that the list head data holds my unusedData */ - fail_unless(llist.head->ptr == &unusedData_case1, + fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1, "head ptr should be first entry"); /* same goes for the list tail */ - fail_unless(llist.tail == llist.head, + fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist), "tail and head should be the same"); /** @@ -109,11 +111,12 @@ UNITTEST_START * 2: the list tail should be our newly created element */ - Curl_llist_insert_next(&llist, llist.head, + Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case3, &case3_list); - fail_unless(llist.head->next->ptr == &unusedData_case3, + fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == + &unusedData_case3, "the node next to head is not getting set correctly"); - fail_unless(llist.tail->ptr == &unusedData_case3, + fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3, "the list tail is not getting set correctly"); /** @@ -125,15 +128,16 @@ UNITTEST_START * 2: the list tail should different from newly created element */ - Curl_llist_insert_next(&llist, llist.head, + Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case2, &case2_list); - fail_unless(llist.head->next->ptr == &unusedData_case2, + fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == + &unusedData_case2, "the node next to head is not getting set correctly"); /* better safe than sorry, check that the tail isn't corrupted */ - fail_unless(llist.tail->ptr != &unusedData_case2, + fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) != &unusedData_case2, "the list tail is not getting set correctly"); - /* unit tests for Curl_llist_remove */ + /* unit tests for Curl_node_remove */ /** * case 1: @@ -144,19 +148,19 @@ UNITTEST_START * 3: "new" head's previous will be NULL */ - head = llist.head; + head = Curl_llist_head(&llist); abort_unless(head, "llist.head is NULL"); - element_next = head->next; + element_next = Curl_node_next(head); llist_size = Curl_llist_count(&llist); - Curl_llist_remove(&llist, llist.head, NULL); + Curl_node_remove(Curl_llist_head(&llist)); fail_unless(Curl_llist_count(&llist) == (llist_size-1), - "llist size not decremented as expected"); - fail_unless(llist.head == element_next, - "llist new head not modified properly"); - abort_unless(llist.head, "llist.head is NULL"); - fail_unless(llist.head->prev == NULL, + "llist size not decremented as expected"); + fail_unless(Curl_llist_head(&llist) == element_next, + "llist new head not modified properly"); + abort_unless(Curl_llist_head(&llist), "llist.head is NULL"); + fail_unless(Curl_node_prev(Curl_llist_head(&llist)) == NULL, "new head previous not set to null"); /** @@ -169,20 +173,20 @@ UNITTEST_START * 2: element->previous->next will be element->next * 3: element->next->previous will be element->previous */ - Curl_llist_insert_next(&llist, llist.head, &unusedData_case3, + Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case3, &case4_list); llist_size = Curl_llist_count(&llist); fail_unless(llist_size == 3, "should be 3 list members"); - to_remove = llist.head->next; + to_remove = Curl_node_next(Curl_llist_head(&llist)); abort_unless(to_remove, "to_remove is NULL"); - element_next = to_remove->next; - element_prev = to_remove->prev; - Curl_llist_remove(&llist, to_remove, NULL); - fail_unless(element_prev->next == element_next, + element_next = Curl_node_next(to_remove); + element_prev = Curl_node_prev(to_remove); + Curl_node_uremove(to_remove, NULL); + fail_unless(Curl_node_next(element_prev) == element_next, "element previous->next is not being adjusted"); abort_unless(element_next, "element_next is NULL"); - fail_unless(element_next->prev == element_prev, + fail_unless(Curl_node_prev(element_next) == element_prev, "element next->previous is not being adjusted"); /** @@ -195,10 +199,10 @@ UNITTEST_START * 4: list->tail will be tail->previous */ - to_remove = llist.tail; - element_prev = to_remove->prev; - Curl_llist_remove(&llist, to_remove, NULL); - fail_unless(llist.tail == element_prev, + to_remove = Curl_llist_tail(&llist); + element_prev = Curl_node_prev(to_remove); + Curl_node_remove(to_remove); + fail_unless(Curl_llist_tail(&llist) == element_prev, "llist tail is not being adjusted when removing tail"); /** @@ -210,11 +214,11 @@ UNITTEST_START * 3: list tail will be null */ - to_remove = llist.head; - Curl_llist_remove(&llist, to_remove, NULL); - fail_unless(llist.head == NULL, + to_remove = Curl_llist_head(&llist); + Curl_node_remove(to_remove); + fail_unless(Curl_llist_head(&llist) == NULL, "llist head is not NULL while the llist is empty"); - fail_unless(llist.tail == NULL, + fail_unless(Curl_llist_tail(&llist) == NULL, "llist tail is not NULL while the llist is empty"); /** @@ -229,10 +233,10 @@ UNITTEST_START fail_unless(Curl_llist_count(&llist) == 1, "List size should be 1 after appending a new element"); /* test that the list head data holds my unusedData */ - fail_unless(llist.head->ptr == &unusedData_case1, + fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1, "head ptr should be first entry"); /* same goes for the list tail */ - fail_unless(llist.tail == llist.head, + fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist), "tail and head should be the same"); /** @@ -244,9 +248,10 @@ UNITTEST_START * 2: the list tail should be the newly created element */ Curl_llist_append(&llist, &unusedData_case2, &case2_list); - fail_unless(llist.head->next->ptr == &unusedData_case2, + fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == + &unusedData_case2, "the node next to head is not getting set correctly"); - fail_unless(llist.tail->ptr == &unusedData_case2, + fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case2, "the list tail is not getting set correctly"); /** @@ -258,13 +263,12 @@ UNITTEST_START * 2: the list tail should be the newly created element */ Curl_llist_append(&llist, &unusedData_case3, &case3_list); - fail_unless(llist.head->next->ptr == &unusedData_case2, + fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == + &unusedData_case2, "the node next to head did not stay the same"); - fail_unless(llist.tail->ptr == &unusedData_case3, + fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3, "the list tail is not getting set correctly"); - - Curl_llist_destroy(&llist, NULL); Curl_llist_destroy(&llist_destination, NULL); } diff --git a/tests/unit/unit1305.c b/tests/unit/unit1305.c index 19cc62c44..ad8c85c44 100644 --- a/tests/unit/unit1305.c +++ b/tests/unit/unit1305.c @@ -33,7 +33,6 @@ # include #endif -#define ENABLE_CURLX_PRINTF #include "curlx.h" #include "hash.h" @@ -122,7 +121,7 @@ UNITTEST_START abort_unless(rc == CURLE_OK, "data node creation failed"); key_len = strlen(data_key); - data_node->inuse = 1; /* hash will hold the reference */ + data_node->refcount = 1; /* hash will hold the reference */ nodep = Curl_hash_add(&hp, data_key, key_len + 1, data_node); abort_unless(nodep, "insertion into hash failed"); /* Freeing will now be done by Curl_hash_destroy */ diff --git a/tests/unit/unit1309.c b/tests/unit/unit1309.c index 5c5801abd..0ae71205b 100644 --- a/tests/unit/unit1309.c +++ b/tests/unit/unit1309.c @@ -88,7 +88,7 @@ UNITTEST_START key.tv_sec = 0; key.tv_usec = (541*i)%1023; storage[i] = key.tv_usec; - nodes[i].payload = &storage[i]; + Curl_splayset(&nodes[i], &storage[i]); root = Curl_splayinsert(key, root, &nodes[i]); } @@ -100,7 +100,7 @@ UNITTEST_START printf("Tree look:\n"); splayprint(root, 0, 1); printf("remove pointer %d, payload %zu\n", rem, - *(size_t *)nodes[rem].payload); + *(size_t *)Curl_splayget(&nodes[rem])); rc = Curl_splayremove(root, &nodes[rem], &root); if(rc) { /* failed! */ @@ -121,7 +121,7 @@ UNITTEST_START /* add some nodes with the same key */ for(j = 0; j <= i % 3; j++) { storage[i * 3 + j] = key.tv_usec*10 + j; - nodes[i * 3 + j].payload = &storage[i * 3 + j]; + Curl_splayset(&nodes[i * 3 + j], &storage[i * 3 + j]); root = Curl_splayinsert(key, root, &nodes[i * 3 + j]); } } @@ -133,8 +133,8 @@ UNITTEST_START root = Curl_splaygetbest(tv_now, root, &removed); while(removed) { printf("removed payload %zu[%zu]\n", - (*(size_t *)removed->payload) / 10, - (*(size_t *)removed->payload) % 10); + *(size_t *)Curl_splayget(removed) / 10, + *(size_t *)Curl_splayget(removed) % 10); root = Curl_splaygetbest(tv_now, root, &removed); } } diff --git a/tests/unit/unit1398.c b/tests/unit/unit1398.c index 4283a8d1b..696eb023b 100644 --- a/tests/unit/unit1398.c +++ b/tests/unit/unit1398.c @@ -25,8 +25,6 @@ #include "curlcheck.h" -#include "curl/mprintf.h" - static CURLcode unit_setup(void) {return CURLE_OK;} static void unit_stop(void) {} @@ -36,7 +34,7 @@ int rc; char buf[3] = {'b', 'u', 'g'}; const char *str = "bug"; int width = 3; -char output[24]; +char output[130]; /*#define curl_msnprintf snprintf */ @@ -95,4 +93,92 @@ fail_unless(!strcmp(output, " 1234 567"), "wrong output"); rc = curl_msnprintf(output, 24, "%2$.*1$.99d", 3, 5678); fail_unless(rc == 0, "return code should be 0"); +/* 129 input % flags */ +rc = curl_msnprintf(output, 130, + "%s%s%s%s%s%s%s%s%s%s" /* 10 */ + "%s%s%s%s%s%s%s%s%s%s" /* 20 */ + "%s%s%s%s%s%s%s%s%s%s" /* 30 */ + "%s%s%s%s%s%s%s%s%s%s" /* 40 */ + "%s%s%s%s%s%s%s%s%s%s" /* 50 */ + "%s%s%s%s%s%s%s%s%s%s" /* 60 */ + "%s%s%s%s%s%s%s%s%s%s" /* 70 */ + "%s%s%s%s%s%s%s%s%s%s" /* 80 */ + "%s%s%s%s%s%s%s%s%s%s" /* 90 */ + "%s%s%s%s%s%s%s%s%s%s" /* 100 */ + "%s%s%s%s%s%s%s%s%s%s" /* 110 */ + "%s%s%s%s%s%s%s%s%s%s" /* 120 */ + "%s%s%s%s%s%s%s%s%s", /* 129 */ + + "a", "", "", "", "", "", "", "", "", "", /* 10 */ + "b", "", "", "", "", "", "", "", "", "", /* 20 */ + "c", "", "", "", "", "", "", "", "", "", /* 30 */ + "d", "", "", "", "", "", "", "", "", "", /* 40 */ + "e", "", "", "", "", "", "", "", "", "", /* 50 */ + "f", "", "", "", "", "", "", "", "", "", /* 60 */ + "g", "", "", "", "", "", "", "", "", "", /* 70 */ + "h", "", "", "", "", "", "", "", "", "", /* 80 */ + "i", "", "", "", "", "", "", "", "", "", /* 90 */ + "j", "", "", "", "", "", "", "", "", "", /* 100 */ + "k", "", "", "", "", "", "", "", "", "", /* 110 */ + "l", "", "", "", "", "", "", "", "", "", /* 120 */ + "m", "", "", "", "", "", "", "", "" /* 129 */ + ); +fail_unless(rc == 0, "return code should be 0"); + +/* 128 input % flags */ +rc = curl_msnprintf(output, 130, + "%s%s%s%s%s%s%s%s%s%s" /* 10 */ + "%s%s%s%s%s%s%s%s%s%s" /* 20 */ + "%s%s%s%s%s%s%s%s%s%s" /* 30 */ + "%s%s%s%s%s%s%s%s%s%s" /* 40 */ + "%s%s%s%s%s%s%s%s%s%s" /* 50 */ + "%s%s%s%s%s%s%s%s%s%s" /* 60 */ + "%s%s%s%s%s%s%s%s%s%s" /* 70 */ + "%s%s%s%s%s%s%s%s%s%s" /* 80 */ + "%s%s%s%s%s%s%s%s%s%s" /* 90 */ + "%s%s%s%s%s%s%s%s%s%s" /* 100 */ + "%s%s%s%s%s%s%s%s%s%s" /* 110 */ + "%s%s%s%s%s%s%s%s%s%s" /* 120 */ + "%s%s%s%s%s%s%s%s", /* 128 */ + + "a", "", "", "", "", "", "", "", "", "", /* 10 */ + "b", "", "", "", "", "", "", "", "", "", /* 20 */ + "c", "", "", "", "", "", "", "", "", "", /* 30 */ + "d", "", "", "", "", "", "", "", "", "", /* 40 */ + "e", "", "", "", "", "", "", "", "", "", /* 50 */ + "f", "", "", "", "", "", "", "", "", "", /* 60 */ + "g", "", "", "", "", "", "", "", "", "", /* 70 */ + "h", "", "", "", "", "", "", "", "", "", /* 80 */ + "i", "", "", "", "", "", "", "", "", "", /* 90 */ + "j", "", "", "", "", "", "", "", "", "", /* 100 */ + "k", "", "", "", "", "", "", "", "", "", /* 110 */ + "l", "", "", "", "", "", "", "", "", "", /* 120 */ + "m", "", "", "", "", "", "", "" /* 128 */ + ); +fail_unless(rc == 13, "return code should be 13"); + +/* 129 output segments */ +rc = curl_msnprintf(output, 130, + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ + "%%%%%%%%%%%%%%%%%%" /* 129 */ + ); +fail_unless(rc == 0, "return code should be 0"); + +/* 128 output segments */ +rc = curl_msnprintf(output, 129, + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 20 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 40 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 60 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 80 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 100 */ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" /* 120 */ + "%%%%%%%%%%%%%%%%" /* 128 */ + ); +fail_unless(rc == 128, "return code should be 128"); + UNITTEST_STOP diff --git a/tests/unit/unit1602.c b/tests/unit/unit1602.c index f7dc4a212..4c7b794ab 100644 --- a/tests/unit/unit1602.c +++ b/tests/unit/unit1602.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "curlcheck.h" -#define ENABLE_CURLX_PRINTF #include "curlx.h" #include "hash.h" diff --git a/tests/unit/unit1603.c b/tests/unit/unit1603.c index 44f9b880a..46492424c 100644 --- a/tests/unit/unit1603.c +++ b/tests/unit/unit1603.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "curlcheck.h" -#define ENABLE_CURLX_PRINTF #include "curlx.h" #include "hash.h" diff --git a/tests/unit/unit1604.c b/tests/unit/unit1604.c index cba3dfcf6..e518e40a1 100644 --- a/tests/unit/unit1604.c +++ b/tests/unit/unit1604.c @@ -201,9 +201,9 @@ UNITTEST_START { "COM56", 0, "COM56", SANITIZE_ERR_OK }, - /* At the moment we expect a maximum path length of 259. I assume MSDOS + /* At the moment we expect a maximum path length of 259. I assume MS-DOS has variable max path lengths depending on compiler that are shorter - so currently these "good" truncate tests won't run on MSDOS */ + so currently these "good" truncate tests will not run on MS-DOS */ #ifndef MSDOS { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c index 19c59ada3..c902243f5 100644 --- a/tests/unit/unit1609.c +++ b/tests/unit/unit1609.c @@ -200,7 +200,6 @@ UNITTEST_START curl_easy_cleanup(easy); easy = NULL; - Curl_hash_destroy(&multi->hostcache); curl_multi_cleanup(multi); multi = NULL; curl_slist_free_all(list); diff --git a/tests/unit/unit1610.c b/tests/unit/unit1610.c index b4c6ef4d3..b9d6117a7 100644 --- a/tests/unit/unit1610.c +++ b/tests/unit/unit1610.c @@ -44,7 +44,7 @@ UNITTEST_START const char string1[] = "1"; const char string2[] = "hello-you-fool"; - unsigned char output[SHA256_DIGEST_LENGTH]; + unsigned char output[CURL_SHA256_DIGEST_LENGTH]; unsigned char *testp = output; Curl_sha256it(output, (const unsigned char *) string1, strlen(string1)); @@ -52,14 +52,14 @@ UNITTEST_START verify_memory(testp, "\x6b\x86\xb2\x73\xff\x34\xfc\xe1\x9d\x6b\x80\x4e\xff\x5a\x3f" "\x57\x47\xad\xa4\xea\xa2\x2f\x1d\x49\xc0\x1e\x52\xdd\xb7\x87" - "\x5b\x4b", SHA256_DIGEST_LENGTH); + "\x5b\x4b", CURL_SHA256_DIGEST_LENGTH); Curl_sha256it(output, (const unsigned char *) string2, strlen(string2)); verify_memory(testp, "\xcb\xb1\x6a\x8a\xb9\xcb\xb9\x35\xa8\xcb\xa0\x2e\x28\xc0\x26" "\x30\xd1\x19\x9c\x1f\x02\x17\xf4\x7c\x96\x20\xf3\xef\xe8\x27" - "\x15\xae", SHA256_DIGEST_LENGTH); + "\x15\xae", CURL_SHA256_DIGEST_LENGTH); #endif diff --git a/tests/unit/unit1615.c b/tests/unit/unit1615.c index 444985b2a..72b751c3b 100644 --- a/tests/unit/unit1615.c +++ b/tests/unit/unit1615.c @@ -41,25 +41,25 @@ UNITTEST_START #ifdef CURL_HAVE_SHA512_256 static const char test_str1[] = "1"; - static const unsigned char precomp_hash1[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash1[CURL_SHA512_256_DIGEST_LENGTH] = { 0x18, 0xd2, 0x75, 0x66, 0xbd, 0x1a, 0xc6, 0x6b, 0x23, 0x32, 0xd8, 0xc5, 0x4a, 0xd4, 0x3f, 0x7b, 0xb2, 0x20, 0x79, 0xc9, 0x06, 0xd0, 0x5f, 0x49, 0x1f, 0x3f, 0x07, 0xa2, 0x8d, 0x5c, 0x69, 0x90 }; static const char test_str2[] = "hello-you-fool"; - static const unsigned char precomp_hash2[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash2[CURL_SHA512_256_DIGEST_LENGTH] = { 0xaf, 0x6f, 0xb4, 0xb0, 0x13, 0x9b, 0xee, 0x13, 0xd1, 0x95, 0x3c, 0xb8, 0xc7, 0xcd, 0x5b, 0x19, 0xf9, 0xcd, 0xcd, 0x21, 0xef, 0xdf, 0xa7, 0x42, 0x5c, 0x07, 0x13, 0xea, 0xcc, 0x1a, 0x39, 0x76 }; static const char test_str3[] = "abc"; - static const unsigned char precomp_hash3[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash3[CURL_SHA512_256_DIGEST_LENGTH] = { 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, 0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB, 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46, 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23 }; static const char test_str4[] = ""; /* empty, zero size input */ - static const unsigned char precomp_hash4[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash4[CURL_SHA512_256_DIGEST_LENGTH] = { 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28, 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06, 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74, 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a @@ -67,7 +67,7 @@ UNITTEST_START static const char test_str5[] = "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \ "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"; - static const unsigned char precomp_hash5[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash5[CURL_SHA512_256_DIGEST_LENGTH] = { 0xad, 0xe9, 0x5d, 0x55, 0x3b, 0x9e, 0x45, 0x69, 0xdb, 0x53, 0xa4, 0x04, 0x92, 0xe7, 0x87, 0x94, 0xff, 0xc9, 0x98, 0x5f, 0x93, 0x03, 0x86, 0x45, 0xe1, 0x97, 0x17, 0x72, 0x7c, 0xbc, 0x31, 0x15 @@ -80,13 +80,13 @@ UNITTEST_START "/long/long/long/long/long/long/long/long/long/long/long" \ "/long/long/long/long/long/long/long/long/long/long/long" \ "/long/long/long/long/path?with%20some=parameters"; - static const unsigned char precomp_hash6[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash6[CURL_SHA512_256_DIGEST_LENGTH] = { 0xbc, 0xab, 0xc6, 0x2c, 0x0a, 0x22, 0xd5, 0xcb, 0xac, 0xac, 0xe9, 0x25, 0xcf, 0xce, 0xaa, 0xaf, 0x0e, 0xa1, 0xed, 0x42, 0x46, 0x8a, 0xe2, 0x01, 0xee, 0x2f, 0xdb, 0x39, 0x75, 0x47, 0x73, 0xf1 }; static const char test_str7[] = "Simple string."; - static const unsigned char precomp_hash7[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash7[CURL_SHA512_256_DIGEST_LENGTH] = { 0xde, 0xcb, 0x3c, 0x81, 0x65, 0x4b, 0xa0, 0xf5, 0xf0, 0x45, 0x6b, 0x7e, 0x61, 0xf5, 0x0d, 0xf5, 0x38, 0xa4, 0xfc, 0xb1, 0x8a, 0x95, 0xff, 0x59, 0xbc, 0x04, 0x82, 0xcf, 0x23, 0xb2, 0x32, 0x56 @@ -109,13 +109,13 @@ UNITTEST_START 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; /* 255..1 sequence */ - static const unsigned char precomp_hash8[SHA512_256_DIGEST_LENGTH] = { + static const unsigned char precomp_hash8[CURL_SHA512_256_DIGEST_LENGTH] = { 0x22, 0x31, 0xf2, 0xa1, 0xb4, 0x89, 0xb2, 0x44, 0xf7, 0x66, 0xa0, 0xb8, 0x31, 0xed, 0xb7, 0x73, 0x8a, 0x34, 0xdc, 0x11, 0xc8, 0x2c, 0xf2, 0xb5, 0x88, 0x60, 0x39, 0x6b, 0x5c, 0x06, 0x70, 0x37 }; - unsigned char output_buf[SHA512_256_DIGEST_LENGTH]; + unsigned char output_buf[CURL_SHA512_256_DIGEST_LENGTH]; unsigned char *computed_hash; /* Just to mute compiler warning */ /* Mute compiler warnings in 'verify_memory' macros below */ @@ -123,35 +123,35 @@ UNITTEST_START Curl_sha512_256it(output_buf, (const unsigned char *) test_str1, (sizeof(test_str1) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash1, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash1, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str2, (sizeof(test_str2) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash2, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash2, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str3, (sizeof(test_str3) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash3, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash3, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str4, (sizeof(test_str4) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash4, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash4, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str5, (sizeof(test_str5) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash5, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash5, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str6, (sizeof(test_str6) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash6, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash6, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, (const unsigned char *) test_str7, (sizeof(test_str7) / sizeof(char)) - 1); - verify_memory(computed_hash, precomp_hash7, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash7, CURL_SHA512_256_DIGEST_LENGTH); Curl_sha512_256it(output_buf, test_seq8, sizeof(test_seq8) / sizeof(unsigned char)); - verify_memory(computed_hash, precomp_hash8, SHA512_256_DIGEST_LENGTH); + verify_memory(computed_hash, precomp_hash8, CURL_SHA512_256_DIGEST_LENGTH); #endif /* CURL_HAVE_SHA512_256 */ diff --git a/tests/unit/unit1616.c b/tests/unit/unit1616.c index 8f988657a..6bccdb9ca 100644 --- a/tests/unit/unit1616.c +++ b/tests/unit/unit1616.c @@ -23,7 +23,6 @@ ***************************************************************************/ #include "curlcheck.h" -#define ENABLE_CURLX_PRINTF #include "curlx.h" #include "hash.h" diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c index 58f8be51a..6d6261e1c 100644 --- a/tests/unit/unit1650.c +++ b/tests/unit/unit1650.c @@ -161,8 +161,8 @@ UNITTEST_START unsigned char *p; for(i = 0; i < sizeof(req) / sizeof(req[0]); i++) { - DOHcode rc = doh_encode(req[i].name, req[i].type, - buffer, sizeof(buffer), &size); + DOHcode rc = doh_req_encode(req[i].name, req[i].type, + buffer, sizeof(buffer), &size); if(rc != req[i].rc) { fprintf(stderr, "req %zu: Expected return code %d got %d\n", i, req[i].rc, rc); @@ -190,8 +190,8 @@ UNITTEST_START size_t len; int u; de_init(&d); - rc = doh_decode((const unsigned char *)resp[i].packet, resp[i].size, - resp[i].type, &d); + rc = doh_resp_decode((const unsigned char *)resp[i].packet, resp[i].size, + resp[i].type, &d); if(rc != resp[i].rc) { fprintf(stderr, "resp %zu: Expected return code %d got %d\n", i, resp[i].rc, rc); @@ -245,7 +245,7 @@ UNITTEST_START struct dohentry d; DOHcode rc; memset(&d, 0, sizeof(d)); - rc = doh_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d); + rc = doh_resp_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d); if(!rc) { /* none of them should work */ fprintf(stderr, "%zu: %d\n", i, rc); @@ -258,8 +258,8 @@ UNITTEST_START struct dohentry d; DOHcode rc; memset(&d, 0, sizeof(d)); - rc = doh_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1, - DNS_TYPE_A, &d); + rc = doh_resp_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1, + DNS_TYPE_A, &d); if(!rc) { /* none of them should work */ fprintf(stderr, "2 %zu: %d\n", i, rc); @@ -272,8 +272,8 @@ UNITTEST_START struct dohentry d; struct dohaddr *a; memset(&d, 0, sizeof(d)); - rc = doh_decode((const unsigned char *)full49, sizeof(full49)-1, - DNS_TYPE_A, &d); + rc = doh_resp_decode((const unsigned char *)full49, sizeof(full49)-1, + DNS_TYPE_A, &d); fail_if(d.numaddr != 1, "missing address"); a = &d.addr[0]; p = &a->ip.v4[0]; diff --git a/tests/unit/unit1652.c b/tests/unit/unit1652.c index 68ddec3ea..8c39957a1 100644 --- a/tests/unit/unit1652.c +++ b/tests/unit/unit1652.c @@ -119,24 +119,24 @@ fail_unless(verify(result, input) == 0, "No truncation of infof input"); fail_unless(result[sizeof(result) - 1] == '\0', "No truncation of infof input"); -/* Just over the limit for truncation without newline */ +/* Just over the limit without newline for truncation via '...' */ memset(input + 2047, 'A', 4); Curl_infof(data, "%s", input); -fail_unless(strlen(result) == 2048, "Truncation of infof input 1"); +fail_unless(strlen(result) == 2051, "Truncation of infof input 1"); fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 1"); -/* Just over the limit for truncation with newline */ +/* Just over the limit with newline for truncation via '...' */ memset(input + 2047, 'A', 4); memset(input + 2047 + 4, '\n', 1); Curl_infof(data, "%s", input); -fail_unless(strlen(result) == 2048, "Truncation of infof input 2"); +fail_unless(strlen(result) == 2051, "Truncation of infof input 2"); fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 2"); -/* Way over the limit for truncation with newline */ +/* Way over the limit for truncation via '...' */ memset(input, '\0', sizeof(input)); memset(input, 'A', sizeof(input) - 1); Curl_infof(data, "%s", input); -fail_unless(strlen(result) == 2048, "Truncation of infof input 3"); +fail_unless(strlen(result) == 2051, "Truncation of infof input 3"); fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 3"); diff --git a/tests/unit/unit1654.c b/tests/unit/unit1654.c index f7ca3911b..2f5d1bcc8 100644 --- a/tests/unit/unit1654.c +++ b/tests/unit/unit1654.c @@ -57,51 +57,51 @@ UNITTEST_START fail_if(!curl, "curl_easy_init"); goto fail; } - fail_unless(asi->list.size == 4, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 4, "wrong number of entries"); msnprintf(outname, sizeof(outname), "%s-out", arg); result = Curl_altsvc_parse(curl, asi, "h2=\"example.com:8080\"\r\n", ALPN_h1, "example.org", 8080); fail_if(result, "Curl_altsvc_parse() failed!"); - fail_unless(asi->list.size == 5, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 5, "wrong number of entries"); result = Curl_altsvc_parse(curl, asi, "h3=\":8080\"\r\n", ALPN_h1, "2.example.org", 8080); fail_if(result, "Curl_altsvc_parse(2) failed!"); - fail_unless(asi->list.size == 6, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 6, "wrong number of entries"); result = Curl_altsvc_parse(curl, asi, "h2=\"example.com:8080\", h3=\"yesyes.com\"\r\n", ALPN_h1, "3.example.org", 8080); fail_if(result, "Curl_altsvc_parse(3) failed!"); /* that one should make two entries */ - fail_unless(asi->list.size == 8, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 8, "wrong number of entries"); result = Curl_altsvc_parse(curl, asi, "h2=\"example.com:443\"; ma = 120;\r\n", ALPN_h2, "example.org", 80); fail_if(result, "Curl_altsvc_parse(4) failed!"); - fail_unless(asi->list.size == 9, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 9, "wrong number of entries"); /* quoted 'ma' value */ result = Curl_altsvc_parse(curl, asi, "h2=\"example.net:443\"; ma=\"180\";\r\n", ALPN_h2, "example.net", 80); fail_if(result, "Curl_altsvc_parse(4) failed!"); - fail_unless(asi->list.size == 10, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 10, "wrong number of entries"); result = Curl_altsvc_parse(curl, asi, "h2=\":443\", h3=\":443\"; ma = 120; persist = 1\r\n", ALPN_h1, "curl.se", 80); fail_if(result, "Curl_altsvc_parse(5) failed!"); - fail_unless(asi->list.size == 12, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 12, "wrong number of entries"); /* clear that one again and decrease the counter */ result = Curl_altsvc_parse(curl, asi, "clear;\r\n", ALPN_h1, "curl.se", 80); fail_if(result, "Curl_altsvc_parse(6) failed!"); - fail_unless(asi->list.size == 10, "wrong number of entries"); + fail_unless(Curl_llist_count(&asi->list) == 10, "wrong number of entries"); Curl_altsvc_save(curl, asi, outname); diff --git a/tests/unit/unit1655.c b/tests/unit/unit1655.c index ca88f7150..6c9298de3 100644 --- a/tests/unit/unit1655.c +++ b/tests/unit/unit1655.c @@ -108,9 +108,9 @@ do { victim.canary1 = 87; /* magic numbers, arbitrarily picked */ victim.canary2 = 35; victim.canary3 = 41; - d = doh_encode(name, DNS_TYPE_A, victim.dohbuffer, - sizeof(struct demo), /* allow room for overflow */ - &olen); + d = doh_req_encode(name, DNS_TYPE_A, victim.dohbuffer, + sizeof(struct demo), /* allow room for overflow */ + &olen); fail_unless(d == playlist[i].expected_result, "result returned was not as expected"); @@ -151,31 +151,31 @@ do { DOHcode ret2; size_t olen; - DOHcode ret = doh_encode(sunshine1, dnstype, buffer, buflen, &olen1); + DOHcode ret = doh_req_encode(sunshine1, dnstype, buffer, buflen, &olen1); fail_unless(ret == DOH_OK, "sunshine case 1 should pass fine"); fail_if(olen1 == magic1, "olen has not been assigned properly"); fail_unless(olen1 > strlen(sunshine1), "bad out length"); /* with a trailing dot, the response should have the same length */ olen2 = magic1; - ret2 = doh_encode(dotshine1, dnstype, buffer, buflen, &olen2); + ret2 = doh_req_encode(dotshine1, dnstype, buffer, buflen, &olen2); fail_unless(ret2 == DOH_OK, "dotshine case should pass fine"); fail_if(olen2 == magic1, "olen has not been assigned properly"); fail_unless(olen1 == olen2, "olen should not grow for a trailing dot"); /* add one letter, the response should be one longer */ olen2 = magic1; - ret2 = doh_encode(sunshine2, dnstype, buffer, buflen, &olen2); + ret2 = doh_req_encode(sunshine2, dnstype, buffer, buflen, &olen2); fail_unless(ret2 == DOH_OK, "sunshine case 2 should pass fine"); fail_if(olen2 == magic1, "olen has not been assigned properly"); fail_unless(olen1 + 1 == olen2, "olen should grow with the hostname"); /* pass a short buffer, should fail */ - ret = doh_encode(sunshine1, dnstype, buffer, olen1 - 1, &olen); + ret = doh_req_encode(sunshine1, dnstype, buffer, olen1 - 1, &olen); fail_if(ret == DOH_OK, "short buffer should have been noticed"); /* pass a minimum buffer, should succeed */ - ret = doh_encode(sunshine1, dnstype, buffer, olen1, &olen); + ret = doh_req_encode(sunshine1, dnstype, buffer, olen1, &olen); fail_unless(ret == DOH_OK, "minimal length buffer should be long enough"); fail_unless(olen == olen1, "bad buffer length"); } while(0); diff --git a/tests/unit/unit1660.c b/tests/unit/unit1660.c index 5a126fbc5..e14944592 100644 --- a/tests/unit/unit1660.c +++ b/tests/unit/unit1660.c @@ -118,6 +118,7 @@ static void showsts(struct stsentry *e, const char *chost) } UNITTEST_START +{ CURLcode result; struct stsentry *e; struct hsts *h = Curl_hsts_init(); @@ -159,7 +160,7 @@ UNITTEST_START showsts(e, chost); } - printf("Number of entries: %zu\n", h->list.size); + printf("Number of entries: %zu\n", Curl_llist_count(&h->list)); /* verify that it is exists for 7 seconds */ chost = "expire.example"; @@ -174,6 +175,6 @@ UNITTEST_START Curl_hsts_cleanup(&h); curl_easy_cleanup(easy); curl_global_cleanup(); - +} UNITTEST_STOP #endif diff --git a/tests/unit/unit1663.c b/tests/unit/unit1663.c index f4801fe5c..e7fe62166 100644 --- a/tests/unit/unit1663.c +++ b/tests/unit/unit1663.c @@ -58,8 +58,7 @@ static void test_parse( char *dev = NULL; char *iface = NULL; char *host = NULL; - CURLcode rc = Curl_parse_interface( - input, strlen(input), &dev, &iface, &host); + CURLcode rc = Curl_parse_interface(input, &dev, &iface, &host); fail_unless(rc == exp_rc, "Curl_parse_interface() failed"); fail_unless(!!exp_dev == !!dev, "dev expectation failed."); diff --git a/tests/unit/unit2600.c b/tests/unit/unit2600.c index 5a3def407..bcc53c08b 100644 --- a/tests/unit/unit2600.c +++ b/tests/unit/unit2600.c @@ -377,8 +377,8 @@ static struct test_case TEST_CASES[] = { /* 2 ipv6, fails after ~400ms, reports COULDNT_CONNECT */ { 5, TURL, "test.com:123:192.0.2.1,::1", CURL_IPRESOLVE_WHATEVER, - CNCT_TMOT, 150, 200, 200, 1, 1, 350, TC_TMOT, R_FAIL, "v4" }, - /* mixed ip4+6, v4 starts, v6 kicks in on HE, fails after ~350ms */ + CNCT_TMOT, 150, 200, 200, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, + /* mixed ip4+6, v6 always first, v4 kicks in on HE, fails after ~350ms */ { 6, TURL, "test.com:123:::1,192.0.2.1", CURL_IPRESOLVE_WHATEVER, CNCT_TMOT, 150, 200, 200, 1, 1, 350, TC_TMOT, R_FAIL, "v6" }, /* mixed ip6+4, v6 starts, v4 never starts due to high HE, TIMEOUT */ diff --git a/tests/unit/unit3205.c b/tests/unit/unit3205.c index 6b75c2856..4a2423e6b 100644 --- a/tests/unit/unit3205.c +++ b/tests/unit/unit3205.c @@ -34,7 +34,8 @@ static void unit_stop(void) { } -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ + defined(USE_BEARSSL) || defined(USE_RUSTLS) struct test_cs_entry { uint16_t id; @@ -42,6 +43,31 @@ struct test_cs_entry { const char *openssl; }; static const struct test_cs_entry test_cs_list[] = { +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) + { 0x1301, "TLS_AES_128_GCM_SHA256", + NULL }, + { 0x1302, "TLS_AES_256_GCM_SHA384", + NULL }, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", + NULL }, + { 0x1304, "TLS_AES_128_CCM_SHA256", + NULL }, + { 0x1305, "TLS_AES_128_CCM_8_SHA256", + NULL }, +#endif + { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "ECDHE-ECDSA-AES128-GCM-SHA256" }, + { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "ECDHE-ECDSA-AES256-GCM-SHA384" }, + { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "ECDHE-RSA-AES128-GCM-SHA256" }, + { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "ECDHE-RSA-AES256-GCM-SHA384" }, + { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-RSA-CHACHA20-POLY1305" }, + { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" }, +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA" }, { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", @@ -86,26 +112,15 @@ static const struct test_cs_entry test_cs_list[] = { "ECDH-RSA-AES128-SHA256" }, { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384" }, - { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "ECDHE-ECDSA-AES128-GCM-SHA256" }, - { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "ECDHE-ECDSA-AES256-GCM-SHA384" }, { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256" }, { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384" }, - { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "ECDHE-RSA-AES128-GCM-SHA256" }, - { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "ECDHE-RSA-AES256-GCM-SHA384" }, { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256" }, { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384" }, - { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "ECDHE-RSA-CHACHA20-POLY1305" }, - { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" }, +#endif #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) { 0x0001, "TLS_RSA_WITH_NULL_MD5", "NULL-MD5" }, @@ -179,16 +194,6 @@ static const struct test_cs_entry test_cs_list[] = { "RSA-PSK-NULL-SHA256" }, { 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384", "RSA-PSK-NULL-SHA384" }, - { 0x1301, "TLS_AES_128_GCM_SHA256", - NULL }, - { 0x1302, "TLS_AES_256_GCM_SHA384", - NULL }, - { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", - NULL }, - { 0x1304, "TLS_AES_128_CCM_SHA256", - NULL }, - { 0x1305, "TLS_AES_128_CCM_8_SHA256", - NULL }, { 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA" }, { 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", @@ -604,7 +609,7 @@ struct test_str_entry { const char *str; }; static const struct test_str_entry test_str_list[] = { -#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_RUSTLS) { 0x1301, "TLS_AES_128_GCM_SHA256"}, { 0x1302, "TLS_AES_256_GCM_SHA384"}, { 0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, @@ -631,6 +636,7 @@ static const struct test_str_entry test_str_list[] = { #else { 0x0000, "DHE-RSA-CHACHA20-POLY1305"}, #endif +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) { 0xC023, "ECDHE-ECDSA-AES128-SHA256" }, { 0xC027, "ECDHE-RSA-AES128-SHA256" }, { 0xC009, "ECDHE-ECDSA-AES128-SHA" }, @@ -639,6 +645,16 @@ static const struct test_str_entry test_str_list[] = { { 0xC028, "ECDHE-RSA-AES256-SHA384" }, { 0xC00A, "ECDHE-ECDSA-AES256-SHA" }, { 0xC014, "ECDHE-RSA-AES256-SHA" }, +#else + { 0x0000, "ECDHE-ECDSA-AES128-SHA256" }, + { 0x0000, "ECDHE-RSA-AES128-SHA256" }, + { 0x0000, "ECDHE-ECDSA-AES128-SHA" }, + { 0x0000, "ECDHE-RSA-AES128-SHA" }, + { 0x0000, "ECDHE-ECDSA-AES256-SHA384" }, + { 0x0000, "ECDHE-RSA-AES256-SHA384" }, + { 0x0000, "ECDHE-ECDSA-AES256-SHA" }, + { 0x0000, "ECDHE-RSA-AES256-SHA" }, +#endif #if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) { 0x0067, "DHE-RSA-AES128-SHA256" }, { 0x006B, "DHE-RSA-AES256-SHA256" }, @@ -646,12 +662,21 @@ static const struct test_str_entry test_str_list[] = { { 0x0000, "DHE-RSA-AES128-SHA256" }, { 0x0000, "DHE-RSA-AES256-SHA256" }, #endif +#if defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || defined(USE_BEARSSL) { 0x009C, "AES128-GCM-SHA256" }, { 0x009D, "AES256-GCM-SHA384" }, { 0x003C, "AES128-SHA256" }, { 0x003D, "AES256-SHA256" }, { 0x002F, "AES128-SHA" }, { 0x0035, "AES256-SHA" }, +#else + { 0x0000, "AES128-GCM-SHA256" }, + { 0x0000, "AES256-GCM-SHA384" }, + { 0x0000, "AES128-SHA256" }, + { 0x0000, "AES256-SHA256" }, + { 0x0000, "AES128-SHA" }, + { 0x0000, "AES256-SHA" }, +#endif #if defined(USE_SECTRANSP) || defined(USE_BEARSSL) { 0x000A, "DES-CBC3-SHA" }, #else @@ -769,4 +794,4 @@ UNITTEST_START UNITTEST_STOP #endif /* defined(USE_SECTRANSP) || defined(USE_MBEDTLS) || \ - defined(USE_BEARSSL) */ + defined(USE_BEARSSL) || defined(USE_RUSTLS) */ diff --git a/tests/valgrind.supp b/tests/valgrind.supp index 6e570b1bf..422dadf71 100644 --- a/tests/valgrind.supp +++ b/tests/valgrind.supp @@ -14,7 +14,7 @@ fun:zstd_unencode_write fun:Curl_unencode_write fun:readwrite_data - fun:Curl_readwrite + fun:Curl_sendrecv fun:multi_runsingle fun:curl_multi_perform fun:easy_transfer @@ -31,7 +31,7 @@ Memcheck:Cond fun:ZSTD_decompressStream fun:zstd_unencode_write - fun:Curl_readwrite + fun:Curl_sendrecv fun:multi_runsingle fun:curl_multi_perform fun:curl_easy_perform diff --git a/winbuild/README.md b/winbuild/README.md index 1ab5f5825..f35c11796 100644 --- a/winbuild/README.md +++ b/winbuild/README.md @@ -100,7 +100,7 @@ where `` is one or many of: - `ENABLE_OPENSSL_AUTO_LOAD_CONFIG=` - Enable loading OpenSSL configuration automatically, defaults to yes - - `ENABLE_UNICODE=` - Enable UNICODE support, defaults to no + - `ENABLE_UNICODE=` - Enable Unicode support, defaults to no - `ENABLE_WEBSOCKETS=` - Enable Web Socket support, defaults to no - `GEN_PDB=` - Generate External Program Database (debug symbols for release build)