diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d71ceb1ef037..3e53a1ed172b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -10,9 +10,9 @@ How to contribute to curl Join the community ------------------ - 1. Click 'watch' on the GitHub repo +1. Click 'watch' on the GitHub repo - 2. Subscribe to the suitable [mailing lists](https://curl.se/mail/) +2. Subscribe to the suitable [mailing lists](https://curl.se/mail/) Read [CONTRIBUTE](/docs/CONTRIBUTE.md) --------------------------------------- @@ -20,10 +20,10 @@ Read [CONTRIBUTE](/docs/CONTRIBUTE.md) Send your suggestions using one of these methods: ------------------------------------------------- - 1. in a mail to the mailing list +1. in a mail to the mailing list - 2. as a [pull request](https://github.com/curl/curl/pulls) +2. as a [pull request](https://github.com/curl/curl/pulls) - 3. as an [issue](https://github.com/curl/curl/issues) +3. as an [issue](https://github.com/curl/curl/issues) / The curl team diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a5cbd27bb03e..401d5f088a2e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -185,12 +185,12 @@ jobs: tflags: '--min=910 951 to 9999' generate: -DENABLE_DEBUG=ON -DENABLE_THREADED_RESOLVER=OFF - - name: 'openssl intel' + - name: 'openssl intel C89' install_packages: libssh-dev install_steps: pytest configure: CFLAGS=-std=gnu89 --with-openssl --with-libssh --enable-debug - - name: 'openssl arm' + - name: 'openssl arm C89' image: ubuntu-24.04-arm install_steps: pytest configure: CFLAGS=-std=gnu89 --with-openssl --enable-debug --disable-verbose diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 054ba48245b3..754d9f6a2301 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -257,11 +257,11 @@ jobs: install: libressl install_steps: pytest generate: -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DCURL_DISABLE_LDAP=ON -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_USE_LIBSSH2=OFF - - name: 'OpenSSL 10.15' + - name: 'OpenSSL 10.15 C89' compiler: clang install: libnghttp3 libngtcp2 install_steps: pytest - generate: -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DUSE_NGTCP2=ON -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_USE_LIBSSH2=OFF + generate: -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DUSE_NGTCP2=ON -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_USE_LIBSSH2=OFF -DCMAKE_C_STANDARD=90 macos-version-min: '10.15' - name: 'OpenSSL SecTrust' compiler: clang diff --git a/CMake/PickyWarnings.cmake b/CMake/PickyWarnings.cmake index 36ce76b18fc4..980e017f3014 100644 --- a/CMake/PickyWarnings.cmake +++ b/CMake/PickyWarnings.cmake @@ -127,7 +127,6 @@ if(PICKY_COMPILER) -Wignored-qualifiers # clang 2.8 gcc 4.3 -Wmissing-field-initializers # clang 2.7 gcc 4.1 -Wmissing-noreturn # clang 2.7 gcc 4.1 - -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) -Wno-padded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs -Wno-sign-conversion # clang 2.9 gcc 4.3 -Wno-switch-default # clang 2.7 gcc 4.1 # Not used: Annoying to fix or silence @@ -436,6 +435,15 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC) endforeach() endif() +if(CMAKE_C_STANDARD STREQUAL 90 AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang") + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.2) + list(APPEND _picky "-Wno-c99-extensions") # Avoid: warning: '_Bool' is a C99 extension + endif() + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.1) + list(APPEND _picky "-Wno-comma") # Just silly + endif() +endif() + if(DOS AND CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) list(APPEND _picky "-Wno-arith-conversion") # Avoid warnings in DJGPP's built-in FD_SET() macro endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index c5bdd99e8d69..8103f98aec41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,9 @@ endif() if(CMAKE_CROSSCOMPILING) string(APPEND _target_flags " CROSS") endif() +if(CMAKE_C_STANDARD) + string(APPEND _target_flags " C${CMAKE_C_STANDARD}") +endif() message(STATUS "CMake platform flags:${_target_flags}") if(CMAKE_CROSSCOMPILING) diff --git a/configure.ac b/configure.ac index d4a1b641a845..114ba39d485c 100644 --- a/configure.ac +++ b/configure.ac @@ -331,7 +331,7 @@ dnl we would like an httpd as test server dnl HTTPD_ENABLED="maybe" AC_ARG_WITH(test-httpd, [AS_HELP_STRING([--with-test-httpd=PATH], - [where to find httpd/apache2 for testing])], + [where to find httpd/apache2 for testing])], [request_httpd=$withval], [request_httpd=check]) if test "x$request_httpd" = "xcheck" || test "x$request_httpd" = "xyes"; then if test -x "/usr/sbin/apache2"; then @@ -411,7 +411,7 @@ dnl we would like a sshd as test server dnl SSHD_ENABLED="maybe" AC_ARG_WITH(test-sshd, [AS_HELP_STRING([--with-test-sshd=PATH], - [where to find sshd for testing])], + [where to find sshd for testing])], [request_sshd=$withval], [request_sshd=check]) if test "x$request_sshd" = "xcheck" || test "x$request_sshd" = "xyes"; then if test -x "/usr/sbin/sshd"; then diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md index 56f0376b6415..9ee5f688a496 100644 --- a/docs/BINDINGS.md +++ b/docs/BINDINGS.md @@ -7,14 +7,14 @@ SPDX-License-Identifier: curl libcurl bindings ================ - Creative people have written bindings or interfaces for various environments - and programming languages. Using one of these allows you to take advantage of - curl powers from within your favourite language or system. +Creative people have written bindings or interfaces for various environments +and programming languages. Using one of these allows you to take advantage of +curl powers from within your favourite language or system. - This is a list of all known interfaces as of this writing. +This is a list of all known interfaces as of this writing. - The bindings listed below are not part of the curl/libcurl distribution - archives, but must be downloaded and installed separately. +The bindings listed below are not part of the curl/libcurl distribution +archives, but must be downloaded and installed separately. @@ -23,8 +23,8 @@ libcurl bindings [Basic](https://scriptbasic.com/) ScriptBasic bindings written by Peter Verhas C++: [curlpp](https://github.com/jpbarrette/curlpp) Written by Jean-Philippe Barrette-LaPierre, -[curlcpp](https://github.com/JosephP91/curlcpp) by Giuseppe Persico and [C++ -Requests](https://github.com/libcpr/cpr) by Huu Nguyen +[curlcpp](https://github.com/JosephP91/curlcpp) by Giuseppe Persico and +[C++ Requests](https://github.com/libcpr/cpr) by Huu Nguyen [Ch](https://chcurl.sourceforge.net/) Written by Stephen Nestinger and Jonathan Rogado diff --git a/docs/BUGS.md b/docs/BUGS.md index 68d7fc34794f..42273a83b852 100644 --- a/docs/BUGS.md +++ b/docs/BUGS.md @@ -8,263 +8,263 @@ SPDX-License-Identifier: curl ## There are still bugs - curl and libcurl keep being developed. Adding features and changing code - means that bugs sneak in, no matter how hard we try to keep them out. +curl and libcurl keep being developed. Adding features and changing code +means that bugs sneak in, no matter how hard we try to keep them out. - Of course there are lots of bugs left. Not to mention misfeatures. +Of course there are lots of bugs left. Not to mention misfeatures. - To help us make curl the stable and solid product we want it to be, we need - bug reports and bug fixes. +To help us make curl the stable and solid product we want it to be, we need +bug reports and bug fixes. ## Where to report - If you cannot fix a bug yourself and submit a fix for it, try to report an as - detailed report as possible to a curl mailing list to allow one of us to have - a go at a solution. You can optionally also submit your problem in [curl's - bug tracking system](https://github.com/curl/curl/issues). +If you cannot fix a bug yourself and submit a fix for it, try to report an as +detailed report as possible to a curl mailing list to allow one of us to have +a go at a solution. You can optionally also submit your problem in +[curl's bug tracking system](https://github.com/curl/curl/issues). - Please read the rest of this document below first before doing that. +Please read the rest of this document below first before doing that. - If you feel you need to ask around first, find a suitable [mailing - list](https://curl.se/mail/) and post your questions there. +If you feel you need to ask around first, find a suitable +[mailing list](https://curl.se/mail/) and post your questions there. ## Security bugs - If you find a bug or problem in curl or libcurl that you think has a security - impact, for example a bug that can put users in danger or make them - vulnerable if the bug becomes public knowledge, then please report that bug - using our security development process. +If you find a bug or problem in curl or libcurl that you think has a security +impact, for example a bug that can put users in danger or make them +vulnerable if the bug becomes public knowledge, then please report that bug +using our security development process. - Security related bugs or bugs that are suspected to have a security impact, - should be reported on the [curl security tracker at - HackerOne](https://hackerone.com/curl). +Security related bugs or bugs that are suspected to have a security impact, +should be reported on the +[curl security tracker at HackerOne](https://hackerone.com/curl). - This ensures that the report reaches the curl security team so that they - first can deal with the report away from the public to minimize the harm and - impact it has on existing users out there who might be using the vulnerable - versions. +This ensures that the report reaches the curl security team so that they +first can deal with the report away from the public to minimize the harm and +impact it has on existing users out there who might be using the vulnerable +versions. - The curl project's process for handling security related issues is - [documented separately](https://curl.se/dev/secprocess.html). +The curl project's process for handling security related issues is +[documented separately](https://curl.se/dev/secprocess.html). ## What to report - When reporting a bug, you should include all information to help us - understand what is wrong, what you expected to happen and how to repeat the - bad behavior. You therefore need to tell us: +When reporting a bug, you should include all information to help us +understand what is wrong, what you expected to happen and how to repeat the +bad behavior. You therefore need to tell us: - - your operating system's name and version number +- your operating system's name and version number - - what version of curl you are using (`curl -V` is fine) +- what version of curl you are using (`curl -V` is fine) - - versions of the used libraries that libcurl is built to use +- versions of the used libraries that libcurl is built to use - - what URL you were working with (if possible), at least which protocol +- what URL you were working with (if possible), at least which protocol - and anything and everything else you think matters. Tell us what you expected - to happen, tell us what did happen, tell us how you could make it work - another way. Dig around, try out, test. Then include all the tiny bits and - pieces in your report. You benefit from this yourself, as it enables us to - help you quicker and more accurately. +and anything and everything else you think matters. Tell us what you expected +to happen, tell us what did happen, tell us how you could make it work +another way. Dig around, try out, test. Then include all the tiny bits and +pieces in your report. You benefit from this yourself, as it enables us to +help you quicker and more accurately. - Since curl deals with networks, it often helps us if you include a protocol - debug dump with your bug report. The output you get by using the `-v` or - `--trace` options. +Since curl deals with networks, it often helps us if you include a protocol +debug dump with your bug report. The output you get by using the `-v` or +`--trace` options. - If curl crashed, causing a core dump (in Unix), there is hardly any use to - send that huge file to anyone of us. Unless we have the same system setup as - you, we cannot do much with it. Instead, we ask you to get a stack trace and - send that (much smaller) output to us instead. +If curl crashed, causing a core dump (in Unix), there is hardly any use to +send that huge file to anyone of us. Unless we have the same system setup as +you, we cannot do much with it. Instead, we ask you to get a stack trace and +send that (much smaller) output to us instead. - The address and how to subscribe to the mailing lists are detailed in the - `MANUAL.md` file. +The address and how to subscribe to the mailing lists are detailed in the +`MANUAL.md` file. ## libcurl problems - When you have written your own application with libcurl to perform transfers, - it is even more important to be specific and detailed when reporting bugs. +When you have written your own application with libcurl to perform transfers, +it is even more important to be specific and detailed when reporting bugs. - Tell us the libcurl version and your operating system. Tell us the name and - version of all relevant sub-components like for example the SSL library - you are using and what name resolving your libcurl uses. If you use SFTP or - SCP, the libssh2 version is relevant etc. +Tell us the libcurl version and your operating system. Tell us the name and +version of all relevant sub-components like for example the SSL library +you are using and what name resolving your libcurl uses. If you use SFTP or +SCP, the libssh2 version is relevant etc. - Showing us a real source code example repeating your problem is the best way - to get our attention and it greatly increases our chances to understand your - problem and to work on a fix (if we agree it truly is a problem). +Showing us a real source code example repeating your problem is the best way +to get our attention and it greatly increases our chances to understand your +problem and to work on a fix (if we agree it truly is a problem). - Lots of problems that appear to be libcurl problems are actually just abuses - of the libcurl API or other malfunctions in your applications. It is advised - that you run your problematic program using a memory debug tool like valgrind - or similar before you post memory-related or "crashing" problems to us. +Lots of problems that appear to be libcurl problems are actually just abuses +of the libcurl API or other malfunctions in your applications. It is advised +that you run your problematic program using a memory debug tool like valgrind +or similar before you post memory-related or "crashing" problems to us. ## Who fixes the problems - If the problems or bugs you describe are considered to be bugs, we want to - have the problems fixed. +If the problems or bugs you describe are considered to be bugs, we want to +have the problems fixed. - There are no developers in the curl project that are paid to work on bugs. - All developers that take on reported bugs do this on a voluntary basis. We do - it out of an ambition to keep curl and libcurl excellent products and out of - pride. +There are no developers in the curl project that are paid to work on bugs. +All developers that take on reported bugs do this on a voluntary basis. We do +it out of an ambition to keep curl and libcurl excellent products and out of +pride. - Please do not assume that you can just lump over something to us and it then - magically gets fixed after some given time. Most often we need feedback and - help to understand what you have experienced and how to repeat a problem. - Then we may only be able to assist YOU to debug the problem and to track down - the proper fix. +Please do not assume that you can just lump over something to us and it then +magically gets fixed after some given time. Most often we need feedback and +help to understand what you have experienced and how to repeat a problem. +Then we may only be able to assist YOU to debug the problem and to track down +the proper fix. - We get reports from many people every month and each report can take a - considerable amount of time to really go to the bottom with. +We get reports from many people every month and each report can take a +considerable amount of time to really go to the bottom with. ## How to get a stack trace - First, you must make sure that you compile all sources with `-g` and that you - do not 'strip' the final executable. Try to avoid optimizing the code as well, - remove `-O`, `-O2` etc from the compiler options. +First, you must make sure that you compile all sources with `-g` and that you +do not 'strip' the final executable. Try to avoid optimizing the code as well, +remove `-O`, `-O2` etc from the compiler options. - Run the program until it cores. +Run the program until it cores. - Run your debugger on the core file, like ` curl core`. `` - should be replaced with the name of your debugger, in most cases that is - `gdb`, but `dbx` and others also occur. +Run your debugger on the core file, like ` curl core`. `` +should be replaced with the name of your debugger, in most cases that is +`gdb`, but `dbx` and others also occur. - When the debugger has finished loading the core file and presents you a - prompt, enter `where` (without quotes) and press return. +When the debugger has finished loading the core file and presents you a +prompt, enter `where` (without quotes) and press return. - The list that is presented is the stack trace. If everything worked, it is - supposed to contain the chain of functions that were called when curl - crashed. Include the stack trace with your detailed bug report, it helps a - lot. +The list that is presented is the stack trace. If everything worked, it is +supposed to contain the chain of functions that were called when curl +crashed. Include the stack trace with your detailed bug report, it helps a +lot. ## Bugs in libcurl bindings - There are of course bugs in libcurl bindings. You should then primarily - approach the team that works on that particular binding and see what you can - do to help them fix the problem. +There are of course bugs in libcurl bindings. You should then primarily +approach the team that works on that particular binding and see what you can +do to help them fix the problem. - If you suspect that the problem exists in the underlying libcurl, then please - convert your program over to plain C and follow the steps outlined above. +If you suspect that the problem exists in the underlying libcurl, then please +convert your program over to plain C and follow the steps outlined above. ## Bugs in old versions - The curl project typically releases new versions every other month, and we - fix several hundred bugs per year. For a huge table of releases, number of - bug fixes and more, see: https://curl.se/docs/releases.html +The curl project typically releases new versions every other month, and we +fix several hundred bugs per year. For a huge table of releases, number of +bug fixes and more, see: https://curl.se/docs/releases.html - The developers in the curl project do not have bandwidth or energy enough to - maintain several branches or to spend much time on hunting down problems in - old versions when chances are we already fixed them or at least that they have - changed nature and appearance in later versions. +The developers in the curl project do not have bandwidth or energy enough to +maintain several branches or to spend much time on hunting down problems in +old versions when chances are we already fixed them or at least that they have +changed nature and appearance in later versions. - When you experience a problem and want to report it, you really SHOULD - include the version number of the curl you are using when you experience the - issue. If that version number shows us that you are using an out-of-date curl, - you should also try out a modern curl version to see if the problem persists - or how/if it has changed in appearance. +When you experience a problem and want to report it, you really SHOULD +include the version number of the curl you are using when you experience the +issue. If that version number shows us that you are using an out-of-date curl, +you should also try out a modern curl version to see if the problem persists +or how/if it has changed in appearance. - Even if you cannot immediately upgrade your application/system to run the - latest curl version, you can most often at least run a test version or - experimental build or similar, to get this confirmed or not. +Even if you cannot immediately upgrade your application/system to run the +latest curl version, you can most often at least run a test version or +experimental build or similar, to get this confirmed or not. - At times people insist that they cannot upgrade to a modern curl version, but - instead, they "just want the bug fixed". That is fine, just do not count on us - spending many cycles on trying to identify which single commit, if that is - even possible, that at some point in the past fixed the problem you are now - experiencing. +At times people insist that they cannot upgrade to a modern curl version, but +instead, they "just want the bug fixed". That is fine, just do not count on us +spending many cycles on trying to identify which single commit, if that is +even possible, that at some point in the past fixed the problem you are now +experiencing. - Security wise, it is almost always a bad idea to lag behind the current curl - versions by a lot. We keep discovering and reporting security problems - over time see you can see in [this - table](https://curl.se/docs/vulnerabilities.html) +Security wise, it is almost always a bad idea to lag behind the current curl +versions by a lot. We keep discovering and reporting security problems +over time see you can see in +[this table](https://curl.se/docs/vulnerabilities.html) # Bug fixing procedure ## What happens on first filing - When a new issue is posted in the issue tracker or on the mailing list, the - team of developers first needs to see the report. Maybe they took the day off, - maybe they are off in the woods hunting. Have patience. Allow at least a few - days before expecting someone to have responded. +When a new issue is posted in the issue tracker or on the mailing list, the +team of developers first needs to see the report. Maybe they took the day off, +maybe they are off in the woods hunting. Have patience. Allow at least a few +days before expecting someone to have responded. - In the issue tracker, you can expect that some labels are set on the issue to - help categorize it. +In the issue tracker, you can expect that some labels are set on the issue to +help categorize it. ## First response - If your issue/bug report was not perfect at once (and few are), chances are - that someone asks follow-up questions. Which version did you use? Which - options did you use? How often does the problem occur? How can we reproduce - this problem? Which protocols does it involve? Or perhaps much more specific - and deep diving questions. It all depends on your specific issue. +If your issue/bug report was not perfect at once (and few are), chances are +that someone asks follow-up questions. Which version did you use? Which +options did you use? How often does the problem occur? How can we reproduce +this problem? Which protocols does it involve? Or perhaps much more specific +and deep diving questions. It all depends on your specific issue. - You should then respond to these follow-up questions and provide more info - about the problem, so that we can help you figure it out. Or maybe you can - help us figure it out. An active back-and-forth communication is important - and the key for finding a cure and landing a fix. +You should then respond to these follow-up questions and provide more info +about the problem, so that we can help you figure it out. Or maybe you can +help us figure it out. An active back-and-forth communication is important +and the key for finding a cure and landing a fix. ## Not reproducible - We may require further work from you who actually see or experience the - problem if we cannot reproduce it and cannot understand it even after having - gotten all the info we need and having studied the source code over again. +We may require further work from you who actually see or experience the +problem if we cannot reproduce it and cannot understand it even after having +gotten all the info we need and having studied the source code over again. ## Unresponsive - If the problem have not been understood or reproduced, and there is nobody - responding to follow-up questions or questions asking for clarifications or - for discussing possible ways to move forward with the task, we take that as a - strong suggestion that the bug is unimportant. +If the problem have not been understood or reproduced, and there is nobody +responding to follow-up questions or questions asking for clarifications or +for discussing possible ways to move forward with the task, we take that as a +strong suggestion that the bug is unimportant. - Unimportant issues are closed as inactive sooner or later as they cannot be - fixed. The inactivity period (waiting for responses) should not be shorter - than two weeks but may extend months. +Unimportant issues are closed as inactive sooner or later as they cannot be +fixed. The inactivity period (waiting for responses) should not be shorter +than two weeks but may extend months. ## Lack of time/interest - Bugs that are filed and are understood can unfortunately end up in the - "nobody cares enough about it to work on it" category. Such bugs are - perfectly valid problems that *should* get fixed but apparently are not. We - try to mark such bugs as `KNOWN_BUGS material` after a time of inactivity and - if no activity is noticed after yet some time those bugs are added to the - `KNOWN_BUGS` document and are closed in the issue tracker. +Bugs that are filed and are understood can unfortunately end up in the +"nobody cares enough about it to work on it" category. Such bugs are +perfectly valid problems that *should* get fixed but apparently are not. We +try to mark such bugs as `KNOWN_BUGS material` after a time of inactivity and +if no activity is noticed after yet some time those bugs are added to the +`KNOWN_BUGS` document and are closed in the issue tracker. ## `KNOWN_BUGS` - This is a list of known bugs. Bugs we know exist and that have been pointed - out but that have not yet been fixed. The reasons for why they have not been - fixed can involve anything really, but the primary reason is that nobody has - considered these problems to be important enough to spend the necessary time - and effort to have them fixed. +This is a list of known bugs. Bugs we know exist and that have been pointed +out but that have not yet been fixed. The reasons for why they have not been +fixed can involve anything really, but the primary reason is that nobody has +considered these problems to be important enough to spend the necessary time +and effort to have them fixed. - The `KNOWN_BUGS` items are always up for grabs and we love the ones who bring - one of them back to life and offer solutions to them. +The `KNOWN_BUGS` items are always up for grabs and we love the ones who bring +one of them back to life and offer solutions to them. - The `KNOWN_BUGS` document has a sibling document known as `TODO`. +The `KNOWN_BUGS` document has a sibling document known as `TODO`. ## `TODO` - Issues that are filed or reported that are not really bugs but more missing - features or ideas for future improvements and so on are marked as - *enhancement* or *feature-request* and get added to the `TODO` document and - the issues are closed. We do not keep TODO items open in the issue tracker. +Issues that are filed or reported that are not really bugs but more missing +features or ideas for future improvements and so on are marked as +*enhancement* or *feature-request* and get added to the `TODO` document and +the issues are closed. We do not keep TODO items open in the issue tracker. - The `TODO` document is full of ideas and suggestions of what we can add or - fix one day. You are always encouraged and free to grab one of those items and - take up a discussion with the curl development team on how that could be - implemented or provided in the project so that you can work on ticking it odd - that document. +The `TODO` document is full of ideas and suggestions of what we can add or +fix one day. You are always encouraged and free to grab one of those items and +take up a discussion with the curl development team on how that could be +implemented or provided in the project so that you can work on ticking it odd +that document. - If an issue is rather a bug and not a missing feature or functionality, it is - listed in `KNOWN_BUGS` instead. +If an issue is rather a bug and not a missing feature or functionality, it is +listed in `KNOWN_BUGS` instead. ## Closing off stalled bugs - The [issue and pull request trackers](https://github.com/curl/curl) only hold - "active" entries open (using a non-precise definition of what active actually - is, but they are at least not completely dead). Those that are abandoned or - in other ways dormant are closed and sometimes added to `TODO` and - `KNOWN_BUGS` instead. +The [issue and pull request trackers](https://github.com/curl/curl) only hold +"active" entries open (using a non-precise definition of what active actually +is, but they are at least not completely dead). Those that are abandoned or +in other ways dormant are closed and sometimes added to `TODO` and +`KNOWN_BUGS` instead. - This way, we only have "active" issues open on GitHub. Irrelevant issues and - pull requests do not distract developers or casual visitors. +This way, we only have "active" issues open on GitHub. Irrelevant issues and +pull requests do not distract developers or casual visitors. diff --git a/docs/DEPRECATE.md b/docs/DEPRECATE.md index 6ad0b7ad0676..c8231c36b298 100644 --- a/docs/DEPRECATE.md +++ b/docs/DEPRECATE.md @@ -20,11 +20,11 @@ In March 2026, we drop support for all c-ares versions before 1.16.0. RTMP in curl is powered by the 3rd party library librtmp. - - RTMP is barely used by curl users (2.2% in the 2025 survey) - - librtmp has no test cases, makes no proper releases and has not had a single - commit within the last year - - librtmp parses the URL itself and requires non-compliant URLs for this - - we have no RTMP tests +- RTMP is barely used by curl users (2.2% in the 2025 survey) +- librtmp has no test cases, makes no proper releases and has not had a single + commit within the last year +- librtmp parses the URL itself and requires non-compliant URLs for this +- we have no RTMP tests Support for RTMP in libcurl gets removed in April 2026. @@ -36,24 +36,24 @@ CMake 3.18 was released on 2020-07-15. ## Past removals - - axTLS (removed in 7.63.0) - - Pipelining (removed in 7.65.0) - - PolarSSL (removed in 7.69.0) - - NPN (removed in 7.86.0) - - Support for systems without 64-bit data types (removed in 8.0.0) - - NSS (removed in 8.3.0) - - gskit (removed in 8.3.0) - - MinGW v1 (removed in 8.4.0) - - NTLM_WB (removed in 8.8.0) - - space-separated `NOPROXY` patterns (removed in 8.9.0) - - hyper (removed in 8.12.0) - - Support for Visual Studio 2005 and older (removed in 8.13.0) - - Secure Transport (removed in 8.15.0) - - BearSSL (removed in 8.15.0) - - msh3 (removed in 8.16.0) - - winbuild build system (removed in 8.17.0) - - Windows CE (removed in 8.18.0) - - Support for Visual Studio 2008 (removed in 8.18.0) - - OpenSSL 1.1.1 and older (removed in 8.18.0) - - Support for Windows XP (removed in 8.19.0) - - OpenSSL-QUIC (removed in 8.19.0) +- axTLS (removed in 7.63.0) +- Pipelining (removed in 7.65.0) +- PolarSSL (removed in 7.69.0) +- NPN (removed in 7.86.0) +- Support for systems without 64-bit data types (removed in 8.0.0) +- NSS (removed in 8.3.0) +- gskit (removed in 8.3.0) +- MinGW v1 (removed in 8.4.0) +- NTLM_WB (removed in 8.8.0) +- space-separated `NOPROXY` patterns (removed in 8.9.0) +- hyper (removed in 8.12.0) +- Support for Visual Studio 2005 and older (removed in 8.13.0) +- Secure Transport (removed in 8.15.0) +- BearSSL (removed in 8.15.0) +- msh3 (removed in 8.16.0) +- winbuild build system (removed in 8.17.0) +- Windows CE (removed in 8.18.0) +- Support for Visual Studio 2008 (removed in 8.18.0) +- OpenSSL 1.1.1 and older (removed in 8.18.0) +- Support for Windows XP (removed in 8.19.0) +- OpenSSL-QUIC (removed in 8.19.0) diff --git a/docs/EARLY-RELEASE.md b/docs/EARLY-RELEASE.md index e66dbbd444d9..f5efb3d442e2 100644 --- a/docs/EARLY-RELEASE.md +++ b/docs/EARLY-RELEASE.md @@ -31,10 +31,10 @@ big and we never release just a patch. There is only "release". ## Questions to ask - - Is there a security advisory rated high or critical? - - Is there a data corruption bug? - - Did the bug cause an API/ABI breakage? - - Does the problem annoy a significant share of the user population? +- Is there a security advisory rated high or critical? +- Is there a data corruption bug? +- Did the bug cause an API/ABI breakage? +- Does the problem annoy a significant share of the user population? If the answer is yes to one or more of the above, an early release might be warranted. @@ -42,25 +42,25 @@ warranted. More questions to ask ourselves when doing the assessment if the answers to the three ones above are all 'no'. - - Does the bug cause curl to prematurely terminate? - - How common is the affected buggy option/feature/protocol/platform to get - used? - - How large is the estimated impacted user base? - - Does the bug block something crucial for applications or other adoption of - curl "out there" ? - - Does the bug cause problems for curl developers or others on "the curl - team" ? - - Is the bug limited to the curl tool only? That might have a smaller impact - than a bug also present in libcurl. - - Is there a (decent) workaround? - - Is it a regression? Is the bug introduced in this release? - - Can the bug be fixed "easily" by applying a patch? - - Does the bug break the build? Most users do not build curl themselves. - - How long is it until the already scheduled next release? - - Can affected users safely rather revert to a former release until the next - scheduled release? - - Is it a performance regression with no functionality side-effects? If so it - has to be substantial. +- Does the bug cause curl to prematurely terminate? +- How common is the affected buggy option/feature/protocol/platform to get + used? +- How large is the estimated impacted user base? +- Does the bug block something crucial for applications or other adoption of + curl "out there" ? +- Does the bug cause problems for curl developers or others on "the curl + team" ? +- Is the bug limited to the curl tool only? That might have a smaller impact + than a bug also present in libcurl. +- Is there a (decent) workaround? +- Is it a regression? Is the bug introduced in this release? +- Can the bug be fixed "easily" by applying a patch? +- Does the bug break the build? Most users do not build curl themselves. +- How long is it until the already scheduled next release? +- Can affected users safely rather revert to a former release until the next + scheduled release? +- Is it a performance regression with no functionality side-effects? If so it + has to be substantial. ## If an early release is deemed necessary diff --git a/docs/FEATURES.md b/docs/FEATURES.md index f366154943a9..a7f184505629 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -8,242 +8,242 @@ SPDX-License-Identifier: curl ## curl tool - - config file support - - multiple URLs in a single command line - - range "globbing" support: [0-13], {one,two,three} - - multiple file upload on a single command line - - redirect stderr - - parallel transfers +- config file support +- multiple URLs in a single command line +- range "globbing" support: [0-13], {one,two,three} +- multiple file upload on a single command line +- redirect stderr +- parallel transfers ## libcurl - - URL RFC 3986 syntax - - custom maximum download time - - custom lowest download speed acceptable - - custom output result after completion - - guesses protocol from hostname unless specified - - supports .netrc - - progress bar with time statistics while downloading - - standard proxy environment variables support - - have run on 101 operating systems and 28 CPU architectures - - selectable network interface for outgoing traffic - - IPv6 support on Unix and Windows - - happy eyeballs dual-stack IPv4 + IPv6 connects - - persistent connections - - SOCKS 4 + 5 support, with or without local name resolving - - *pre-proxy* support, for *proxy chaining* - - supports username and password in proxy environment variables - - operations through HTTP proxy "tunnel" (using CONNECT) - - replaceable memory functions (malloc, free, realloc, etc) - - asynchronous name resolving - - both a push and a pull style interface - - international domain names (IDN) - - 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 - - DNS-over-HTTPS - - uses non-blocking name resolves - - selectable name resolver backend +- URL RFC 3986 syntax +- custom maximum download time +- custom lowest download speed acceptable +- custom output result after completion +- guesses protocol from hostname unless specified +- supports .netrc +- progress bar with time statistics while downloading +- standard proxy environment variables support +- have run on 101 operating systems and 28 CPU architectures +- selectable network interface for outgoing traffic +- IPv6 support on Unix and Windows +- happy eyeballs dual-stack IPv4 + IPv6 connects +- persistent connections +- SOCKS 4 + 5 support, with or without local name resolving +- *pre-proxy* support, for *proxy chaining* +- supports username and password in proxy environment variables +- operations through HTTP proxy "tunnel" (using CONNECT) +- replaceable memory functions (malloc, free, realloc, etc) +- asynchronous name resolving +- both a push and a pull style interface +- international domain names (IDN) +- 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 +- DNS-over-HTTPS +- uses non-blocking name resolves +- selectable name resolver backend ## URL API - - parses RFC 3986 URLs - - generates URLs from individual components - - manages "redirects" +- parses RFC 3986 URLs +- generates URLs from individual components +- manages "redirects" ## Header API - - easy access to HTTP response headers, from all contexts - - named headers - - iterate over headers +- easy access to HTTP response headers, from all contexts +- named headers +- iterate over headers ## TLS - - selectable TLS backend(s) - - TLS False Start - - TLS version control - - TLS session resumption - - key pinning - - mutual authentication - - Use dedicated CA cert bundle - - Use OS-provided CA store - - separate TLS options for HTTPS proxy +- selectable TLS backend(s) +- TLS False Start +- TLS version control +- TLS session resumption +- key pinning +- mutual authentication +- Use dedicated CA cert bundle +- Use OS-provided CA store +- separate TLS options for HTTPS proxy ## HTTP - - HTTP/0.9 responses are optionally accepted - - HTTP/1.0 - - HTTP/1.1 - - HTTP/2, including multiplexing and server push - - GET - - PUT - - HEAD - - POST - - multipart formpost (RFC 1867-style) - - authentication: Basic, Digest, NTLM (9) and Negotiate (SPNEGO) - to server and proxy - - resume transfers - - follow redirects - - maximum amount of redirects to follow - - custom HTTP request - - cookie get/send fully parsed - - reads/writes the Netscape cookie file format - - custom headers (replace/remove internally generated headers) - - custom user-agent string - - custom referrer string - - range - - proxy authentication - - time conditions - - via HTTP proxy, HTTPS proxy or SOCKS proxy - - HTTP/2 or HTTP/1.1 to HTTPS proxy - - retrieve file modification date - - Content-Encoding support for deflate, gzip, brotli and zstd - - "Transfer-Encoding: chunked" support in uploads - - HSTS - - alt-svc - - ETags - - HTTP/1.1 trailers, both sending and getting +- HTTP/0.9 responses are optionally accepted +- HTTP/1.0 +- HTTP/1.1 +- HTTP/2, including multiplexing and server push +- GET +- PUT +- HEAD +- POST +- multipart formpost (RFC 1867-style) +- authentication: Basic, Digest, NTLM (9) and Negotiate (SPNEGO) + to server and proxy +- resume transfers +- follow redirects +- maximum amount of redirects to follow +- custom HTTP request +- cookie get/send fully parsed +- reads/writes the Netscape cookie file format +- custom headers (replace/remove internally generated headers) +- custom user-agent string +- custom referrer string +- range +- proxy authentication +- time conditions +- via HTTP proxy, HTTPS proxy or SOCKS proxy +- HTTP/2 or HTTP/1.1 to HTTPS proxy +- retrieve file modification date +- Content-Encoding support for deflate, gzip, brotli and zstd +- "Transfer-Encoding: chunked" support in uploads +- HSTS +- alt-svc +- ETags +- HTTP/1.1 trailers, both sending and getting ## HTTPS - - HTTP/3 - - using client certificates - - verify server certificate - - via HTTP proxy, HTTPS proxy or SOCKS proxy - - select desired encryption - - select usage of a specific TLS version - - ECH +- HTTP/3 +- using client certificates +- verify server certificate +- via HTTP proxy, HTTPS proxy or SOCKS proxy +- select desired encryption +- select usage of a specific TLS version +- ECH ## FTP - - download - - authentication - - Kerberos 5 - - active/passive using PORT, EPRT, PASV or EPSV - - single file size information (compare to HTTP HEAD) - - 'type=' URL support - - directory listing - - directory listing names-only - - upload - - upload append - - upload via http-proxy as HTTP PUT - - download resume - - upload resume - - custom ftp commands (before and/or after the transfer) - - simple "range" support - - via HTTP proxy, HTTPS proxy or SOCKS proxy - - all operations can be tunneled through proxy - - customizable to retrieve file modification date - - no directory depth limit +- download +- authentication +- Kerberos 5 +- active/passive using PORT, EPRT, PASV or EPSV +- single file size information (compare to HTTP HEAD) +- 'type=' URL support +- directory listing +- directory listing names-only +- upload +- upload append +- upload via http-proxy as HTTP PUT +- download resume +- upload resume +- custom ftp commands (before and/or after the transfer) +- simple "range" support +- via HTTP proxy, HTTPS proxy or SOCKS proxy +- all operations can be tunneled through proxy +- customizable to retrieve file modification date +- no directory depth limit ## FTPS - - implicit `ftps://` support that use SSL on both connections - - explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain `ftp://` - connection to use SSL for both or one of the connections +- implicit `ftps://` support that use SSL on both connections +- explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain `ftp://` + connection to use SSL for both or one of the connections ## SSH (both SCP and SFTP) - - selectable SSH backend - - known hosts support - - public key fingerprinting - - both password and public key auth +- selectable SSH backend +- known hosts support +- public key fingerprinting +- both password and public key auth ## SFTP - - both password and public key auth - - with custom commands sent before/after the transfer - - directory listing +- both password and public key auth +- with custom commands sent before/after the transfer +- directory listing ## TFTP - - download - - upload +- download +- upload ## TELNET - - connection negotiation - - custom telnet options - - stdin/stdout I/O +- connection negotiation +- custom telnet options +- stdin/stdout I/O ## LDAP - - full LDAP URL support +- full LDAP URL support ## DICT - - extended DICT URL support +- extended DICT URL support ## FILE - - URL support - - upload - - resume +- URL support +- upload +- resume ## SMB - - SMBv1 over TCP and SSL - - download - - upload - - authentication with NTLMv1 +- SMBv1 over TCP and SSL +- download +- upload +- authentication with NTLMv1 ## SMTP - - authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, Kerberos 5 and - External - - send emails - - mail from support - - mail size support - - mail auth support for trusted server-to-server relaying - - multiple recipients - - via http-proxy +- authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, Kerberos 5 and + External +- send emails +- mail from support +- mail size support +- mail auth support for trusted server-to-server relaying +- multiple recipients +- via http-proxy ## SMTPS - - implicit `smtps://` support - - explicit "STARTTLS" usage to "upgrade" plain `smtp://` connections to use SSL - - via http-proxy +- implicit `smtps://` support +- explicit "STARTTLS" usage to "upgrade" plain `smtp://` connections to use SSL +- via http-proxy ## POP3 - - authentication: Clear Text, APOP and SASL - - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, - Kerberos 5 and External - - list emails - - retrieve emails - - enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via - custom requests - - via http-proxy +- authentication: Clear Text, APOP and SASL +- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, + Kerberos 5 and External +- list emails +- retrieve emails +- enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via + custom requests +- via http-proxy ## POP3S - - implicit `pop3s://` support - - explicit `STLS` usage to "upgrade" plain `pop3://` connections to use SSL - - via http-proxy +- implicit `pop3s://` support +- explicit `STLS` usage to "upgrade" plain `pop3://` connections to use SSL +- via http-proxy ## IMAP - - authentication: Clear Text and SASL - - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, - Kerberos 5 and External - - list the folders of a mailbox - - select a mailbox with support for verifying the `UIDVALIDITY` - - fetch emails with support for specifying the UID and SECTION - - upload emails via the append command - - enhanced command support for: EXAMINE, CREATE, DELETE, RENAME, STATUS, - STORE, COPY and UID via custom requests - - via http-proxy +- authentication: Clear Text and SASL +- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, + Kerberos 5 and External +- list the folders of a mailbox +- select a mailbox with support for verifying the `UIDVALIDITY` +- fetch emails with support for specifying the UID and SECTION +- upload emails via the append command +- enhanced command support for: EXAMINE, CREATE, DELETE, RENAME, STATUS, + STORE, COPY and UID via custom requests +- via http-proxy ## IMAPS - - implicit `imaps://` support - - explicit "STARTTLS" usage to "upgrade" plain `imap://` connections to use SSL - - via http-proxy +- implicit `imaps://` support +- explicit "STARTTLS" usage to "upgrade" plain `imap://` connections to use SSL +- via http-proxy ## MQTT - - Subscribe to and publish topics using URL scheme `mqtt://broker/topic` +- Subscribe to and publish topics using URL scheme `mqtt://broker/topic` diff --git a/docs/HISTORY.md b/docs/HISTORY.md index abbb2833a5ed..d2cff6209540 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -246,7 +246,7 @@ November: Known libcurl bindings: 37 Contributors: 683 - 145,000 unique visitors. >100 GB downloaded. +145,000 unique visitors. >100 GB downloaded. 2009 ---- @@ -282,7 +282,7 @@ August: Known libcurl bindings: 39 Contributors: 808 - Gopher support added (re-added actually, see January 2006) +Gopher support added (re-added actually, see January 2006) 2011 ---- @@ -294,146 +294,146 @@ April: added the cyassl backend (later renamed to wolfSSL) 2012 ---- - July: Added support for Schannel (native Windows TLS backend) and Darwin SSL - (Native Mac OS X and iOS TLS backend). +July: Added support for Schannel (native Windows TLS backend) and Darwin SSL +(Native Mac OS X and iOS TLS backend). - Supports Metalink +Supports Metalink - October: SSH-agent support. +October: SSH-agent support. 2013 ---- - February: Cleaned up internals to always uses the "multi" non-blocking - approach internally and only expose the blocking API with a wrapper. +February: Cleaned up internals to always uses the "multi" non-blocking +approach internally and only expose the blocking API with a wrapper. - September: First small steps on supporting HTTP/2 with nghttp2. +September: First small steps on supporting HTTP/2 with nghttp2. - October: Removed krb4 support. +October: Removed krb4 support. - December: Happy eyeballs. +December: Happy eyeballs. 2014 ---- - March: first real release supporting HTTP/2 +March: first real release supporting HTTP/2 - September: Website had 245,000 unique visitors and served 236GB data +September: Website had 245,000 unique visitors and served 236GB data - SMB and SMBS support +SMB and SMBS support 2015 ---- - June: support for multiplexing with HTTP/2 +June: support for multiplexing with HTTP/2 - August: support for HTTP/2 server push +August: support for HTTP/2 server push - September: started "everything curl". A separate stand-alone book documenting - curl and related info in perhaps a more tutorial style rather than just a - reference, +September: started "everything curl". A separate stand-alone book documenting +curl and related info in perhaps a more tutorial style rather than just a +reference, - December: Public Suffix List +December: Public Suffix List 2016 ---- - January: the curl tool defaults to HTTP/2 for HTTPS URLs +January: the curl tool defaults to HTTP/2 for HTTPS URLs - December: curl 7.52.0 introduced support for HTTPS-proxy +December: curl 7.52.0 introduced support for HTTPS-proxy - First TLS 1.3 support +First TLS 1.3 support 2017 ---- - May: Fastly starts hosting the curl website +May: Fastly starts hosting the curl website - July: OSS-Fuzz started fuzzing libcurl +July: OSS-Fuzz started fuzzing libcurl - September: Added MultiSSL support +September: Added MultiSSL support - The website serves 3100 GB/month +The website serves 3100 GB/month - Public curl releases: 169 - Command line options: 211 - curl_easy_setopt() options: 249 - Public functions in libcurl: 74 - Contributors: 1609 + Public curl releases: 169 + Command line options: 211 + curl_easy_setopt() options: 249 + Public functions in libcurl: 74 + Contributors: 1609 - October: SSLKEYLOGFILE support, new MIME API +October: SSLKEYLOGFILE support, new MIME API - October: Daniel received the Polhem Prize for his work on curl +October: Daniel received the Polhem Prize for his work on curl - November: brotli +November: brotli 2018 ---- - January: new SSH backend powered by libssh +January: new SSH backend powered by libssh - March: starting with the 1803 release of Windows 10, curl is shipped bundled - with Microsoft's operating system. +March: starting with the 1803 release of Windows 10, curl is shipped bundled +with Microsoft's operating system. - July: curl shows headers using bold type face +July: curl shows headers using bold type face - October: added DNS-over-HTTPS (DoH) and the URL API +October: added DNS-over-HTTPS (DoH) and the URL API - MesaLink is a new supported TLS backend +MesaLink is a new supported TLS backend - libcurl now does HTTP/2 (and multiplexing) by default on HTTPS URLs +libcurl now does HTTP/2 (and multiplexing) by default on HTTPS URLs - curl and libcurl are installed in an estimated 5 *billion* instances - world-wide. +curl and libcurl are installed in an estimated 5 *billion* instances +world-wide. - October 31: curl and libcurl 7.62.0 +October 31: curl and libcurl 7.62.0 - Public curl releases: 177 - Command line options: 219 - curl_easy_setopt() options: 261 - Public functions in libcurl: 80 - Contributors: 1808 + Public curl releases: 177 + Command line options: 219 + curl_easy_setopt() options: 261 + Public functions in libcurl: 80 + Contributors: 1808 - December: removed axTLS support +December: removed axTLS support 2019 ---- - January: Daniel started working full-time on curl, employed by wolfSSL +January: Daniel started working full-time on curl, employed by wolfSSL - March: added experimental alt-svc support +March: added experimental alt-svc support - August: the first HTTP/3 requests with curl. +August: the first HTTP/3 requests with curl. - September: 7.66.0 is released and the tool offers parallel downloads +September: 7.66.0 is released and the tool offers parallel downloads 2020 ---- - curl and libcurl are installed in an estimated 10 *billion* instances - world-wide. +curl and libcurl are installed in an estimated 10 *billion* instances +world-wide. - January: added BearSSL support +January: added BearSSL support - March: removed support for PolarSSL, added wolfSSH support. Created the first - dashboard on the website. +March: removed support for PolarSSL, added wolfSSH support. Created the first +dashboard on the website. - April: experimental MQTT support +April: experimental MQTT support - August: zstd support +August: zstd support - November: the website moves to curl.se. The website serves 10TB data monthly. +November: the website moves to curl.se. The website serves 10TB data monthly. - December: alt-svc support +December: alt-svc support 2021 ---- - February 3: curl 7.75.0 ships with support for Hyper as an HTTP backend +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 +July: HSTS is supported 2022 ---- @@ -446,8 +446,8 @@ March: added --json, removed mesalink support Public functions in libcurl: 86 Contributors: 2601 - The curl.se website serves 16,500 GB/month over 462M requests, the - official docker image has been pulled 4,098,015,431 times. +The curl.se website serves 16,500 GB/month over 462M requests, the +official docker image has been pulled 4,098,015,431 times. April: added support for msh3 as another HTTP/3 backend diff --git a/docs/HSTS.md b/docs/HSTS.md index 8d311c8e47e7..d7d37206881d 100644 --- a/docs/HSTS.md +++ b/docs/HSTS.md @@ -23,7 +23,7 @@ HTTP-only requests to a hostname present in the cache gets internally - `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) + (and possibly read from at startup) ## curl command line options diff --git a/docs/HTTP3.md b/docs/HTTP3.md index 53c200c0883d..ae5e557bc154 100644 --- a/docs/HTTP3.md +++ b/docs/HTTP3.md @@ -38,14 +38,16 @@ To fix before we remove the experimental label: # ngtcp2 version -Building curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3` and a QUIC supporting TLS library. The supported TLS libraries are covered below. +Building curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3` +and a QUIC supporting TLS library. The supported TLS libraries are covered +below. While any version of `ngtcp2` and `nghttp3` from v1.0.0 on are expected to work, using the latest versions often brings functional and performance improvements. -The build examples use `$NGHTTP3_VERSION` and `$NGTCP2_VERSION` as placeholders -for the version you build. +The build examples use `$NGHTTP3_VERSION` and `$NGTCP2_VERSION` as +placeholders for the version you build. ## Build with OpenSSL @@ -224,7 +226,9 @@ Build curl: quiche support is **EXPERIMENTAL** -Since the quiche build manages its dependencies, curl can be built against the latest version. You are *probably* able to build against their main branch, but in case of problems, we recommend their latest release tag. +Since the quiche build manages its dependencies, curl can be built against the +latest version. You are *probably* able to build against their main branch, +but in case of problems, we recommend their latest release tag. ## Build @@ -247,8 +251,8 @@ Build curl: % make % make install - If `make install` results in `Permission denied` error, you need to prepend - it with `sudo`. +If `make install` results in `Permission denied` error, you need to prepend +it with `sudo`. # `--http3` @@ -284,16 +288,17 @@ or HTTP/1.1. At half of that value - currently - is the **soft** timeout. The soft timeout fires, when there has been **no data at all** seen from the server on the HTTP/3 connection. -So, without you specifying anything, the hard timeout is 200ms and the soft is 100ms: +So, without you specifying anything, the hard timeout is 200ms and the soft is +100ms: - * Ideally, the whole QUIC handshake happens and curl has an HTTP/3 connection - in less than 100ms. - * When QUIC is not supported (or UDP does not work for this network path), no - reply is seen and the HTTP/2 TLS+TCP connection starts 100ms later. - * In the worst case, UDP replies start before 100ms, but drag on. This starts - the TLS+TCP connection after 200ms. - * When the QUIC handshake fails, the TLS+TCP connection is attempted right - away. For example, when the QUIC server presents the wrong certificate. +* Ideally, the whole QUIC handshake happens and curl has an HTTP/3 connection + in less than 100ms. +* When QUIC is not supported (or UDP does not work for this network path), no + reply is seen and the HTTP/2 TLS+TCP connection starts 100ms later. +* In the worst case, UDP replies start before 100ms, but drag on. This starts + the TLS+TCP connection after 200ms. +* When the QUIC handshake fails, the TLS+TCP connection is attempted right + away. For example, when the QUIC server presents the wrong certificate. The whole transfer only fails, when **both** QUIC and TLS+TCP fail to handshake or time out. @@ -354,8 +359,8 @@ that exists in curl's test dir. ### Caddy -[Install Caddy](https://caddyserver.com/docs/install). For easiest use, the binary -should be either in your PATH or your current directory. +[Install Caddy](https://caddyserver.com/docs/install). For easiest use, the +binary should be either in your PATH or your current directory. Create a `Caddyfile` with the following content: ~~~ @@ -368,7 +373,9 @@ Then run Caddy: % ./caddy start -Making requests to `https://localhost:7443` should tell you which protocol is being used. +Making requests to `https://localhost:7443` should tell you which protocol is +being used. -You can change the hard-coded response to something more useful by replacing `respond` -with `reverse_proxy` or `file_server`, for example: `reverse_proxy localhost:80` +You can change the hard-coded response to something more useful by replacing +`respond` with `reverse_proxy` or `file_server`, for example: `reverse_proxy +localhost:80` diff --git a/docs/INSTALL-CMAKE.md b/docs/INSTALL-CMAKE.md index fb1c6112071b..c446832544e0 100644 --- a/docs/INSTALL-CMAKE.md +++ b/docs/INSTALL-CMAKE.md @@ -79,18 +79,18 @@ generate the project. After the project is generated, you can run make. CMake also comes with a Qt based GUI called `cmake-gui`. To configure with `cmake-gui`, you run `cmake-gui` and follow these steps: - 1. Fill in the "Where is the source code" combo box with the path to - the curl source tree. - 2. Fill in the "Where to build the binaries" combo box with the path to - the directory for your build tree, ideally this should not be the same - as the source tree, but a parallel directory called curl-build or - something similar. - 3. Once the source and binary directories are specified, press the - "Configure" button. - 4. Select the native build tool that you want to use. - 5. At this point you can change any of the options presented in the GUI. - Once you have selected all the options you want, click the "Generate" - button. +1. Fill in the "Where is the source code" combo box with the path to + the curl source tree. +2. Fill in the "Where to build the binaries" combo box with the path to + the directory for your build tree, ideally this should not be the same + as the source tree, but a parallel directory called curl-build or + something similar. +3. Once the source and binary directories are specified, press the + "Configure" button. +4. Select the native build tool that you want to use. +5. At this point you can change any of the options presented in the GUI. + Once you have selected all the options you want, click the "Generate" + button. # Building @@ -345,7 +345,7 @@ target_link_libraries(my_target PRIVATE CURL::libcurl) - `CMAKE_INSTALL_PREFIX` (see CMake) - `CMAKE_STATIC_LIBRARY_SUFFIX` (see CMake) - `CMAKE_UNITY_BUILD_BATCH_SIZE`: Set the number of sources in a "unity" unit. Default: `0` (all) -- `CMAKE_UNITY_BUILD`: Enable "unity" (aka jumbo) builds. Default: `OFF` +- `CMAKE_UNITY_BUILD`: Enable "unity" (aka "jumbo") builds. Default: `OFF` Details via CMake [variables](https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html) and diff --git a/docs/INSTALL.md b/docs/INSTALL.md index df9095df7f38..2db659f3974f 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -270,8 +270,8 @@ Download the latest version of the `cygwin` packages required (*and suggested*) Once all the packages have been installed, begin the process of installing curl from the source code: -
- configure_options +
+ configure_options ``` --with-gnutls @@ -282,7 +282,7 @@ Once all the packages have been installed, begin the process of installing curl --without-ssl ``` -
+
1. `sh configure ` 2. `make` diff --git a/docs/SECURITY-ADVISORY.md b/docs/SECURITY-ADVISORY.md index efb0e049340f..14e7d96266cb 100644 --- a/docs/SECURITY-ADVISORY.md +++ b/docs/SECURITY-ADVISORY.md @@ -33,11 +33,11 @@ pipe character (`|`). The eleven fields for each CVE in `vuln.pm` are, in order: - HTML page name, first vulnerable version, last vulnerable version, name of - the issue, CVE Id, announce date (`YYYYMMDD`), report to the project date - (`YYYYMMDD`), CWE, awarded reward amount (USD), area (single word), C-issue - (`-` if not a C issue at all, `OVERFLOW` , `OVERREAD`, `DOUBLE_FREE`, - `USE_AFTER_FREE`, `NULL_MISTAKE`, `UNINIT`) +HTML page name, first vulnerable version, last vulnerable version, name of +the issue, CVE Id, announce date (`YYYYMMDD`), report to the project date +(`YYYYMMDD`), CWE, awarded reward amount (USD), area (single word), C-issue +(`-` if not a C issue at all, `OVERFLOW` , `OVERREAD`, `DOUBLE_FREE`, +`USE_AFTER_FREE`, `NULL_MISTAKE`, `UNINIT`) ### `Makefile` diff --git a/docs/TheArtOfHttpScripting.md b/docs/TheArtOfHttpScripting.md index 8af6efa6cb54..b6d530fc2952 100644 --- a/docs/TheArtOfHttpScripting.md +++ b/docs/TheArtOfHttpScripting.md @@ -8,214 +8,214 @@ SPDX-License-Identifier: curl ## Background - This document assumes that you are familiar with HTML and general networking. +This document assumes that you are familiar with HTML and general networking. - The increasing amount of applications moving to the web has made "HTTP - Scripting" more frequently requested and wanted. To be able to automatically - extract information from the web, to fake users, to post or upload data to - web servers are all important tasks today. +The increasing amount of applications moving to the web has made "HTTP +Scripting" more frequently requested and wanted. To be able to automatically +extract information from the web, to fake users, to post or upload data to +web servers are all important tasks today. - curl is a command line tool for doing all sorts of URL manipulations and - transfers, but this particular document focuses on how to use it when doing - HTTP requests for fun and profit. This documents assumes that you know how to - invoke `curl --help` or `curl --manual` to get basic information about it. +curl is a command line tool for doing all sorts of URL manipulations and +transfers, but this particular document focuses on how to use it when doing +HTTP requests for fun and profit. This documents assumes that you know how to +invoke `curl --help` or `curl --manual` to get basic information about it. - curl is not written to do everything for you. It makes the requests, it gets - the data, it sends data and it retrieves the information. You probably need - to glue everything together using some kind of script language or repeated - manual invokes. +curl is not written to do everything for you. It makes the requests, it gets +the data, it sends data and it retrieves the information. You probably need +to glue everything together using some kind of script language or repeated +manual invokes. ## The HTTP Protocol - HTTP is the protocol used to fetch data from web servers. It is a simple - protocol that is built upon TCP/IP. The protocol also allows information to - get sent to the server from the client using a few different methods, as is - shown here. +HTTP is the protocol used to fetch data from web servers. It is a simple +protocol that is built upon TCP/IP. The protocol also allows information to +get sent to the server from the client using a few different methods, as is +shown here. - HTTP is plain ASCII text lines being sent by the client to a server to - request a particular action, and then the server replies a few text lines - before the actual requested content is sent to the client. +HTTP is plain ASCII text lines being sent by the client to a server to +request a particular action, and then the server replies a few text lines +before the actual requested content is sent to the client. - The client, curl, sends an HTTP request. The request contains a method (like - GET, POST, HEAD etc), a number of request headers and sometimes a request - body. The HTTP server responds with a status line (indicating if things went - well), response headers and most often also a response body. The "body" part - is the plain data you requested, like the actual HTML or the image etc. +The client, curl, sends an HTTP request. The request contains a method (like +GET, POST, HEAD etc), a number of request headers and sometimes a request +body. The HTTP server responds with a status line (indicating if things went +well), response headers and most often also a response body. The "body" part +is the plain data you requested, like the actual HTML or the image etc. ## See the Protocol - Using curl's option [`--verbose`](https://curl.se/docs/manpage.html#-v) (`-v` - as a short option) displays what kind of commands curl sends to the server, - as well as a few other informational texts. +Using curl's option [`--verbose`](https://curl.se/docs/manpage.html#-v) (`-v` +as a short option) displays what kind of commands curl sends to the server, +as well as a few other informational texts. - `--verbose` is the single most useful option when it comes to debug or even - understand the curl<->server interaction. +`--verbose` is the single most useful option when it comes to debug or even +understand the curl<->server interaction. - Sometimes even `--verbose` is not enough. Then - [`--trace`](https://curl.se/docs/manpage.html#-trace) and - [`--trace-ascii`](https://curl.se/docs/manpage.html#--trace-ascii) - offer even more details as they show **everything** curl sends and - receives. Use it like this: +Sometimes even `--verbose` is not enough. Then +[`--trace`](https://curl.se/docs/manpage.html#-trace) and +[`--trace-ascii`](https://curl.se/docs/manpage.html#--trace-ascii) +offer even more details as they show **everything** curl sends and +receives. Use it like this: curl --trace-ascii debugdump.txt https://www.example.com/ ## See the Timing - Many times you may wonder what exactly is taking all the time, or you just - want to know the amount of milliseconds between two points in a transfer. For - those, and other similar situations, the - [`--trace-time`](https://curl.se/docs/manpage.html#--trace-time) option is - what you need. It prepends the time to each trace output line: +Many times you may wonder what exactly is taking all the time, or you just +want to know the amount of milliseconds between two points in a transfer. For +those, and other similar situations, the +[`--trace-time`](https://curl.se/docs/manpage.html#--trace-time) option is +what you need. It prepends the time to each trace output line: curl --trace-ascii d.txt --trace-time https://example.com/ ## See which Transfer - When doing parallel transfers, it is relevant to see which transfer is doing - what. When response headers are received (and logged) you need to know which - transfer these are for. - [`--trace-ids`](https://curl.se/docs/manpage.html#--trace-ids) option is what - you need. It prepends the transfer and connection identifier to each trace - output line: +When doing parallel transfers, it is relevant to see which transfer is doing +what. When response headers are received (and logged) you need to know which +transfer these are for. +[`--trace-ids`](https://curl.se/docs/manpage.html#--trace-ids) option is what +you need. It prepends the transfer and connection identifier to each trace +output line: curl --trace-ascii d.txt --trace-ids https://example.com/ ## See the Response - By default curl sends the response to stdout. You need to redirect it - somewhere to avoid that, most often that is done with `-o` or `-O`. +By default curl sends the response to stdout. You need to redirect it +somewhere to avoid that, most often that is done with `-o` or `-O`. # URL ## Spec - The Uniform Resource Locator format is how you specify the address of a - particular resource on the Internet. You know these, you have seen URLs like - https://curl.se/ or https://example.com/ a million times. RFC 3986 is the - canonical spec. The formal name is not URL, it is **URI**. +The Uniform Resource Locator format is how you specify the address of a +particular resource on the Internet. You know these, you have seen URLs like +https://curl.se/ or https://example.com/ a million times. RFC 3986 is the +canonical spec. The formal name is not URL, it is **URI**. ## Host - The hostname is usually resolved using DNS or your /etc/hosts file to an IP - address and that is what curl communicates with. Alternatively you specify - the IP address directly in the URL instead of a name. +The hostname is usually resolved using DNS or your /etc/hosts file to an IP +address and that is what curl communicates with. Alternatively you specify +the IP address directly in the URL instead of a name. - For development and other trying out situations, you can point to a different - IP address for a hostname than what would otherwise be used, by using curl's - [`--resolve`](https://curl.se/docs/manpage.html#--resolve) option: +For development and other trying out situations, you can point to a different +IP address for a hostname than what would otherwise be used, by using curl's +[`--resolve`](https://curl.se/docs/manpage.html#--resolve) option: curl --resolve www.example.org:80:127.0.0.1 https://www.example.org/ ## Port number - Each protocol curl supports operates on a default port number, be it over TCP - or in some cases UDP. Normally you do not have to take that into - consideration, but at times you run test servers on other ports or - similar. Then you can specify the port number in the URL with a colon and a - number immediately following the hostname. Like when doing HTTP to port - 1234: +Each protocol curl supports operates on a default port number, be it over TCP +or in some cases UDP. Normally you do not have to take that into +consideration, but at times you run test servers on other ports or +similar. Then you can specify the port number in the URL with a colon and a +number immediately following the hostname. Like when doing HTTP to port +1234: curl https://www.example.org:1234/ - The port number you specify in the URL is the number that the server uses to - offer its services. Sometimes you may use a proxy, and then you may - need to specify that proxy's port number separately from what curl needs to - connect to the server. Like when using an HTTP proxy on port 4321: +The port number you specify in the URL is the number that the server uses to +offer its services. Sometimes you may use a proxy, and then you may +need to specify that proxy's port number separately from what curl needs to +connect to the server. Like when using an HTTP proxy on port 4321: curl --proxy http://proxy.example.org:4321 https://remote.example.org/ ## Username and password - Some services are setup to require HTTP authentication and then you need to - provide name and password which is then transferred to the remote site in - various ways depending on the exact authentication protocol used. +Some services are setup to require HTTP authentication and then you need to +provide name and password which is then transferred to the remote site in +various ways depending on the exact authentication protocol used. - You can opt to either insert the user and password in the URL or you can - provide them separately: +You can opt to either insert the user and password in the URL or you can +provide them separately: curl https://user:password@example.org/ - or +or curl -u user:password https://example.org/ - You need to pay attention that this kind of HTTP authentication is not what - is usually done and requested by user-oriented websites these days. They tend - to use forms and cookies instead. +You need to pay attention that this kind of HTTP authentication is not what +is usually done and requested by user-oriented websites these days. They tend +to use forms and cookies instead. ## Path part - The path part is just sent off to the server to request that it sends back - the associated response. The path is what is to the right side of the slash - that follows the hostname and possibly port number. +The path part is just sent off to the server to request that it sends back +the associated response. The path is what is to the right side of the slash +that follows the hostname and possibly port number. # Fetch a page ## GET - The simplest and most common request/operation made using HTTP is to GET a - URL. The URL could itself refer to a webpage, an image or a file. The client - issues a GET request to the server and receives the document it asked for. - If you issue the command line +The simplest and most common request/operation made using HTTP is to GET a +URL. The URL could itself refer to a webpage, an image or a file. The client +issues a GET request to the server and receives the document it asked for. +If you issue the command line curl https://curl.se/ - you get a webpage returned in your terminal window. The entire HTML document - this URL identifies. +you get a webpage returned in your terminal window. The entire HTML document +this URL identifies. - All HTTP replies contain a set of response headers that are normally hidden, - use curl's [`--include`](https://curl.se/docs/manpage.html#-i) (`-i`) - option to display them as well as the rest of the document. +All HTTP replies contain a set of response headers that are normally hidden, +use curl's [`--include`](https://curl.se/docs/manpage.html#-i) (`-i`) +option to display them as well as the rest of the document. ## HEAD - You can ask the remote server for ONLY the headers by using the - [`--head`](https://curl.se/docs/manpage.html#-I) (`-I`) option which makes - curl issue a HEAD request. In some special cases servers deny the HEAD method - while others still work, which is a particular kind of annoyance. +You can ask the remote server for ONLY the headers by using the +[`--head`](https://curl.se/docs/manpage.html#-I) (`-I`) option which makes +curl issue a HEAD request. In some special cases servers deny the HEAD method +while others still work, which is a particular kind of annoyance. - The HEAD method is defined and made so that the server returns the headers - exactly the way it would do for a GET, but without a body. It means that you - may see a `Content-Length:` in the response headers, but there must not be an - actual body in the HEAD response. +The HEAD method is defined and made so that the server returns the headers +exactly the way it would do for a GET, but without a body. It means that you +may see a `Content-Length:` in the response headers, but there must not be an +actual body in the HEAD response. ## Multiple URLs in a single command line - A single curl command line may involve one or many URLs. The most common case - is probably to just use one, but you can specify any amount of URLs. Yes any. - No limits. You then get requests repeated over and over for all the given - URLs. +A single curl command line may involve one or many URLs. The most common case +is probably to just use one, but you can specify any amount of URLs. Yes any. +No limits. You then get requests repeated over and over for all the given +URLs. - Example, send two GET requests: +Example, send two GET requests: curl https://url1.example.com https://url2.example.com - If you use [`--data`](https://curl.se/docs/manpage.html#-d) to POST to - the URL, using multiple URLs means that you send that same POST to all the - given URLs. +If you use [`--data`](https://curl.se/docs/manpage.html#-d) to POST to +the URL, using multiple URLs means that you send that same POST to all the +given URLs. - Example, send two POSTs: +Example, send two POSTs: curl --data name=curl https://url1.example.com https://url2.example.com ## Multiple HTTP methods in a single command line - Sometimes you need to operate on several URLs in a single command line and do - different HTTP methods on each. For this, you might enjoy the - [`--next`](https://curl.se/docs/manpage.html#-:) option. It is basically a - separator that separates a bunch of options from the next. All the URLs - before `--next` get the same method and get all the POST data merged into - one. +Sometimes you need to operate on several URLs in a single command line and do +different HTTP methods on each. For this, you might enjoy the +[`--next`](https://curl.se/docs/manpage.html#-:) option. It is basically a +separator that separates a bunch of options from the next. All the URLs +before `--next` get the same method and get all the POST data merged into +one. - When curl reaches the `--next` on the command line, it resets the method and - the POST data and allow a new set. +When curl reaches the `--next` on the command line, it resets the method and +the POST data and allow a new set. - Perhaps this is best shown with a few examples. To send first a HEAD and then - a GET: +Perhaps this is best shown with a few examples. To send first a HEAD and then +a GET: curl -I https://example.com --next https://example.com - To first send a POST and then a GET: +To first send a POST and then a GET: curl -d score=10 https://example.com/post.cgi --next https://example.com/results.html @@ -223,20 +223,20 @@ SPDX-License-Identifier: curl ## Forms explained - Forms are the general way a website can present an HTML page with fields for - the user to enter data in, and then press some kind of 'OK' or 'Submit' - button to get that data sent to the server. The server then typically uses - the posted data to decide how to act. Like using the entered words to search - in a database, or to add the info in a bug tracking system, display the - entered address on a map or using the info as a login-prompt verifying that - the user is allowed to see what it is about to see. +Forms are the general way a website can present an HTML page with fields for +the user to enter data in, and then press some kind of 'OK' or 'Submit' +button to get that data sent to the server. The server then typically uses +the posted data to decide how to act. Like using the entered words to search +in a database, or to add the info in a bug tracking system, display the +entered address on a map or using the info as a login-prompt verifying that +the user is allowed to see what it is about to see. - Of course there has to be some kind of program on the server end to receive - the data you send. You cannot just invent something out of the air. +Of course there has to be some kind of program on the server end to receive +the data you send. You cannot just invent something out of the air. ## GET - A GET-form uses the method GET, as specified in HTML like: +A GET-form uses the method GET, as specified in HTML like: ```html
@@ -245,36 +245,36 @@ SPDX-License-Identifier: curl
``` - In your favorite browser, this form appears with a text box to fill in and a - press-button labeled "OK". If you fill in '1905' and press the OK button, - your browser then creates a new URL to get for you. The URL gets - `junk.cgi?birthyear=1905&press=OK` appended to the path part of the previous - URL. +In your favorite browser, this form appears with a text box to fill in and a +press-button labeled "OK". If you fill in '1905' and press the OK button, +your browser then creates a new URL to get for you. The URL gets +`junk.cgi?birthyear=1905&press=OK` appended to the path part of the previous +URL. - If the original form was seen on the page `www.example.com/when/birth.html`, - the second page you get becomes - `www.example.com/when/junk.cgi?birthyear=1905&press=OK`. +If the original form was seen on the page `www.example.com/when/birth.html`, +the second page you get becomes +`www.example.com/when/junk.cgi?birthyear=1905&press=OK`. - Most search engines work this way. +Most search engines work this way. - To make curl do the GET form post for you, just enter the expected created - URL: +To make curl do the GET form post for you, just enter the expected created +URL: curl "https://www.example.com/when/junk.cgi?birthyear=1905&press=OK" ## POST - The GET method makes all input field names get displayed in the URL field of - your browser. That is generally a good thing when you want to be able to - bookmark that page with your given data, but it is an obvious disadvantage if - you entered secret information in one of the fields or if there are a large - amount of fields creating a long and unreadable URL. +The GET method makes all input field names get displayed in the URL field of +your browser. That is generally a good thing when you want to be able to +bookmark that page with your given data, but it is an obvious disadvantage if +you entered secret information in one of the fields or if there are a large +amount of fields creating a long and unreadable URL. - The HTTP protocol then offers the POST method. This way the client sends the - data separated from the URL and thus you do not see any of it in the URL - address field. +The HTTP protocol then offers the POST method. This way the client sends the +data separated from the URL and thus you do not see any of it in the URL +address field. - The form would look similar to the previous one: +The form would look similar to the previous one: ```html
@@ -283,56 +283,56 @@ SPDX-License-Identifier: curl
``` - And to use curl to post this form with the same data filled in as before, we - could do it like: +To use curl to post this form with the same data filled in as before, we +could do it like: curl --data "birthyear=1905&press=%20OK%20" https://www.example.com/when/junk.cgi - This kind of POST uses the Content-Type `application/x-www-form-urlencoded` - and is the most widely used POST kind. +This kind of POST uses the Content-Type `application/x-www-form-urlencoded` +and is the most widely used POST kind. - The data you send to the server MUST already be properly encoded, curl does - not do that for you. For example, if you want the data to contain a space, - you need to replace that space with `%20`, etc. Failing to comply with this - most likely causes your data to be received wrongly and messed up. +The data you send to the server MUST already be properly encoded, curl does +not do that for you. For example, if you want the data to contain a space, +you need to replace that space with `%20`, etc. Failing to comply with this +most likely causes your data to be received wrongly and messed up. - Recent curl versions can in fact url-encode POST data for you, like this: +Recent curl versions can in fact url-encode POST data for you, like this: curl --data-urlencode "name=I am Daniel" https://www.example.com - If you repeat `--data` several times on the command line, curl concatenates - all the given data pieces - and put a `&` symbol between each data segment. +If you repeat `--data` several times on the command line, curl concatenates +all the given data pieces - and put a `&` symbol between each data segment. ## File Upload POST - Back in late 1995 they defined an additional way to post data over HTTP. It - is documented in the RFC 1867, why this method sometimes is referred to as - RFC 1867-posting. +Back in late 1995 they defined an additional way to post data over HTTP. It +is documented in the RFC 1867, why this method sometimes is referred to as +RFC 1867-posting. - This method is mainly designed to better support file uploads. A form that - allows a user to upload a file could be written like this in HTML: +This method is mainly designed to better support file uploads. A form that +allows a user to upload a file could be written like this in HTML:
- This clearly shows that the Content-Type about to be sent is - `multipart/form-data`. +This clearly shows that the Content-Type about to be sent is +`multipart/form-data`. - To post to a form like this with curl, you enter a command line like: +To post to a form like this with curl, you enter a command line like: curl --form upload=@localfilename --form press=OK [URL] ## Hidden Fields - A common way for HTML based applications to pass state information between - pages is to add hidden fields to the forms. Hidden fields are already filled - in, they are not displayed to the user and they get passed along just as all - the other fields. +A common way for HTML based applications to pass state information between +pages is to add hidden fields to the forms. Hidden fields are already filled +in, they are not displayed to the user and they get passed along just as all +the other fields. - A similar example form with one visible field, one hidden field and one - submit button could look like: +A similar example form with one visible field, one hidden field and one +submit button could look like: ```html
@@ -342,33 +342,33 @@ SPDX-License-Identifier: curl
``` - To POST this with curl, you do not have to think about if the fields are - hidden or not. To curl they are all the same: +To POST this with curl, you do not have to think about if the fields are +hidden or not. To curl they are all the same: curl --data "birthyear=1905&press=OK&person=daniel" [URL] ## Figure Out What A POST Looks Like - When you are about to fill in a form and send it to a server by using curl - instead of a browser, you are of course interested in sending a POST exactly - the way your browser does. +When you are about to fill in a form and send it to a server by using curl +instead of a browser, you are of course interested in sending a POST exactly +the way your browser does. - An easy way to get to see this, is to save the HTML page with the form on - your local disk, modify the 'method' to a GET, and press the submit button - (you could also change the action URL if you want to). +An easy way to get to see this, is to save the HTML page with the form on +your local disk, modify the 'method' to a GET, and press the submit button +(you could also change the action URL if you want to). - You then clearly see the data get appended to the URL, separated with a - `?`-letter as GET forms are supposed to. +You then clearly see the data get appended to the URL, separated with a +`?`-letter as GET forms are supposed to. # HTTP upload ## PUT - Perhaps the best way to upload data to an HTTP server is to use PUT. Then - again, this of course requires that someone put a program or script on the - server end that knows how to receive an HTTP PUT stream. +Perhaps the best way to upload data to an HTTP server is to use PUT. Then +again, this of course requires that someone put a program or script on the +server end that knows how to receive an HTTP PUT stream. - Put a file to an HTTP server with curl: +Put a file to an HTTP server with curl: curl --upload-file uploadfile https://www.example.com/receive.cgi @@ -376,92 +376,92 @@ SPDX-License-Identifier: curl ## Basic Authentication - HTTP Authentication is the ability to tell the server your username and - password so that it can verify that you are allowed to do the request you are - doing. The Basic authentication used in HTTP (which is the type curl uses by - default) is **plain text** based, which means it sends username and password - only slightly obfuscated, but still fully readable by anyone that sniffs on - the network between you and the remote server. +HTTP Authentication is the ability to tell the server your username and +password so that it can verify that you are allowed to do the request you are +doing. The Basic authentication used in HTTP (which is the type curl uses by +default) is **plain text** based, which means it sends username and password +only slightly obfuscated, but still fully readable by anyone that sniffs on +the network between you and the remote server. - To tell curl to use a user and password for authentication: +To tell curl to use a user and password for authentication: curl --user myname:password https://www.example.com ## Other Authentication - The site might require a different authentication method (check the headers - returned by the server), and then - [`--ntlm`](https://curl.se/docs/manpage.html#--ntlm), - [`--digest`](https://curl.se/docs/manpage.html#--digest), - [`--negotiate`](https://curl.se/docs/manpage.html#--negotiate) or even - [`--anyauth`](https://curl.se/docs/manpage.html#--anyauth) might be - options that suit you. +The site might require a different authentication method (check the headers +returned by the server), and then +[`--ntlm`](https://curl.se/docs/manpage.html#--ntlm), +[`--digest`](https://curl.se/docs/manpage.html#--digest), +[`--negotiate`](https://curl.se/docs/manpage.html#--negotiate) or even +[`--anyauth`](https://curl.se/docs/manpage.html#--anyauth) might be +options that suit you. ## Proxy Authentication - Sometimes your HTTP access is only available through the use of an HTTP - proxy. This seems to be especially common at various companies. An HTTP proxy - may require its own user and password to allow the client to get through to - the Internet. To specify those with curl, run something like: +Sometimes your HTTP access is only available through the use of an HTTP +proxy. This seems to be especially common at various companies. An HTTP proxy +may require its own user and password to allow the client to get through to +the Internet. To specify those with curl, run something like: curl --proxy-user proxyuser:proxypassword curl.se - If your proxy requires the authentication to be done using the NTLM method, - use [`--proxy-ntlm`](https://curl.se/docs/manpage.html#--proxy-ntlm), if - it requires Digest use - [`--proxy-digest`](https://curl.se/docs/manpage.html#--proxy-digest). +If your proxy requires the authentication to be done using the NTLM method, +use [`--proxy-ntlm`](https://curl.se/docs/manpage.html#--proxy-ntlm), if +it requires Digest use +[`--proxy-digest`](https://curl.se/docs/manpage.html#--proxy-digest). - If you use any one of these user+password options but leave out the password - part, curl prompts for the password interactively. +If you use any one of these user+password options but leave out the password +part, curl prompts for the password interactively. ## Hiding credentials - Do note that when a program is run, its parameters might be possible to see - when listing the running processes of the system. Thus, other users may be - able to watch your passwords if you pass them as plain command line - options. There are ways to circumvent this. +Do note that when a program is run, its parameters might be possible to see +when listing the running processes of the system. Thus, other users may be +able to watch your passwords if you pass them as plain command line +options. There are ways to circumvent this. - It is worth noting that while this is how HTTP Authentication works, many - websites do not use this concept when they provide logins etc. See the Web - Login chapter further below for more details on that. +It is worth noting that while this is how HTTP Authentication works, many +websites do not use this concept when they provide logins etc. See the Web +Login chapter further below for more details on that. # More HTTP Headers ## Referer - An HTTP request may include a 'referer' field (yes it is misspelled), which - can be used to tell from which URL the client got to this particular - resource. Some programs/scripts check the referer field of requests to verify - that this was not arriving from an external site or an unknown page. While - this is a stupid way to check something so easily forged, many scripts still - do it. Using curl, you can put anything you want in the referer-field and - thus more easily be able to fool the server into serving your request. +An HTTP request may include a 'referer' field (yes it is misspelled), which +can be used to tell from which URL the client got to this particular +resource. Some programs/scripts check the referer field of requests to verify +that this was not arriving from an external site or an unknown page. While +this is a stupid way to check something so easily forged, many scripts still +do it. Using curl, you can put anything you want in the referer-field and +thus more easily be able to fool the server into serving your request. - Use curl to set the referer field with: +Use curl to set the referer field with: curl --referer https://www.example.come https://www.example.com ## User Agent - Similar to the referer field, all HTTP requests may set the User-Agent - field. It names what user agent (client) that is being used. Many - applications use this information to decide how to display pages. Silly web - programmers try to make different pages for users of different browsers to - make them look the best possible for their particular browsers. They usually - also do different kinds of JavaScript etc. +Similar to the referer field, all HTTP requests may set the User-Agent +field. It names what user agent (client) that is being used. Many +applications use this information to decide how to display pages. Silly web +programmers try to make different pages for users of different browsers to +make them look the best possible for their particular browsers. They usually +also do different kinds of JavaScript etc. - At times, you may learn that getting a page with curl does not return the - same page that you see when getting the page with your browser. Then you know - it is time to set the User Agent field to fool the server into thinking you - are one of those browsers. +At times, you may learn that getting a page with curl does not return the +same page that you see when getting the page with your browser. Then you know +it is time to set the User Agent field to fool the server into thinking you +are one of those browsers. - By default, curl uses curl/VERSION, such as User-Agent: curl/8.11.0. +By default, curl uses curl/VERSION, such as User-Agent: curl/8.11.0. - To make curl look like Internet Explorer 5 on a Windows 2000 box: +To make curl look like Internet Explorer 5 on a Windows 2000 box: curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL] - Or why not look like you are using Netscape 4.73 on an old Linux box: +Or why not look like you are using Netscape 4.73 on an old Linux box: curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL] @@ -469,91 +469,91 @@ SPDX-License-Identifier: curl ## Location header - When a resource is requested from a server, the reply from the server may - include a hint about where the browser should go next to find this page, or a - new page keeping newly generated output. The header that tells the browser to - redirect is `Location:`. +When a resource is requested from a server, the reply from the server may +include a hint about where the browser should go next to find this page, or a +new page keeping newly generated output. The header that tells the browser to +redirect is `Location:`. - curl does not follow `Location:` headers by default, but simply displays such - pages in the same manner it displays all HTTP replies. It does however - feature an option that makes it attempt to follow the `Location:` pointers. +curl does not follow `Location:` headers by default, but simply displays such +pages in the same manner it displays all HTTP replies. It does however +feature an option that makes it attempt to follow the `Location:` pointers. - To tell curl to follow a Location: +To tell curl to follow a Location: curl --location https://www.example.com - If you use curl to POST to a site that immediately redirects you to another - page, you can safely use [`--location`](https://curl.se/docs/manpage.html#-L) - (`-L`) and `--data`/`--form` together. curl only uses POST in the first - request, and then revert to GET in the following operations. +If you use curl to POST to a site that immediately redirects you to another +page, you can safely use [`--location`](https://curl.se/docs/manpage.html#-L) +(`-L`) and `--data`/`--form` together. curl only uses POST in the first +request, and then revert to GET in the following operations. ## Other redirects - Browsers typically support at least two other ways of redirects that curl - does not: first the html may contain a meta refresh tag that asks the browser - to load a specific URL after a set number of seconds, or it may use - JavaScript to do it. +Browsers typically support at least two other ways of redirects that curl +does not: first the html may contain a meta refresh tag that asks the browser +to load a specific URL after a set number of seconds, or it may use +JavaScript to do it. # Cookies ## Cookie Basics - The way the web browsers do "client side state control" is by using - cookies. Cookies are just names with associated contents. The cookies are - sent to the client by the server. The server tells the client for what path - and hostname it wants the cookie sent back, and it also sends an expiration - date and a few more properties. +The way the web browsers do "client side state control" is by using +cookies. Cookies are just names with associated contents. The cookies are +sent to the client by the server. The server tells the client for what path +and hostname it wants the cookie sent back, and it also sends an expiration +date and a few more properties. - When a client communicates with a server with a name and path as previously - specified in a received cookie, the client sends back the cookies and their - contents to the server, unless of course they are expired. +When a client communicates with a server with a name and path as previously +specified in a received cookie, the client sends back the cookies and their +contents to the server, unless of course they are expired. - Many applications and servers use this method to connect a series of requests - into a single logical session. To be able to use curl in such occasions, we - must be able to record and send back cookies the way the web application - expects them. The same way browsers deal with them. +Many applications and servers use this method to connect a series of requests +into a single logical session. To be able to use curl in such occasions, we +must be able to record and send back cookies the way the web application +expects them. The same way browsers deal with them. ## Cookie options - The simplest way to send a few cookies to the server when getting a page with - curl is to add them on the command line like: +The simplest way to send a few cookies to the server when getting a page with +curl is to add them on the command line like: curl --cookie "name=Daniel" https://www.example.com - Cookies are sent as common HTTP headers. This is practical as it allows curl - to record cookies simply by recording headers. Record cookies with curl by - using the [`--dump-header`](https://curl.se/docs/manpage.html#-D) (`-D`) - option like: +Cookies are sent as common HTTP headers. This is practical as it allows curl +to record cookies simply by recording headers. Record cookies with curl by +using the [`--dump-header`](https://curl.se/docs/manpage.html#-D) (`-D`) +option like: curl --dump-header headers_and_cookies https://www.example.com - (Take note that the - [`--cookie-jar`](https://curl.se/docs/manpage.html#-c) option described - below is a better way to store cookies.) +(Take note that the +[`--cookie-jar`](https://curl.se/docs/manpage.html#-c) option described +below is a better way to store cookies.) - curl has a full blown cookie parsing engine built-in that comes in use if you - want to reconnect to a server and use cookies that were stored from a - previous connection (or hand-crafted manually to fool the server into - believing you had a previous connection). To use previously stored cookies, - you run curl like: +curl has a full blown cookie parsing engine built-in that comes in use if you +want to reconnect to a server and use cookies that were stored from a +previous connection (or hand-crafted manually to fool the server into +believing you had a previous connection). To use previously stored cookies, +you run curl like: curl --cookie stored_cookies_in_file https://www.example.com - curl's "cookie engine" gets enabled when you use the - [`--cookie`](https://curl.se/docs/manpage.html#-b) option. If you only - want curl to understand received cookies, use `--cookie` with a file that - does not exist. Example, if you want to let curl understand cookies from a - page and follow a location (and thus possibly send back cookies it received), - you can invoke it like: +curl's "cookie engine" gets enabled when you use the +[`--cookie`](https://curl.se/docs/manpage.html#-b) option. If you only +want curl to understand received cookies, use `--cookie` with a file that +does not exist. Example, if you want to let curl understand cookies from a +page and follow a location (and thus possibly send back cookies it received), +you can invoke it like: curl --cookie nada --location https://www.example.com - curl has the ability to read and write cookie files that use the same file - format that Netscape and Mozilla once used. It is a convenient way to share - cookies between scripts or invokes. The `--cookie` (`-b`) switch - automatically detects if a given file is such a cookie file and parses it, - and by using the `--cookie-jar` (`-c`) option you make curl write a new - cookie file at the end of an operation: +curl has the ability to read and write cookie files that use the same file +format that Netscape and Mozilla once used. It is a convenient way to share +cookies between scripts or invokes. The `--cookie` (`-b`) switch +automatically detects if a given file is such a cookie file and parses it, +and by using the `--cookie-jar` (`-c`) option you make curl write a new +cookie file at the end of an operation: curl --cookie cookies.txt --cookie-jar newcookies.txt \ https://www.example.com @@ -562,43 +562,43 @@ SPDX-License-Identifier: curl ## HTTPS is HTTP secure - There are a few ways to do secure HTTP transfers. By far the most common - protocol for doing this is what is generally known as HTTPS, HTTP over - SSL. SSL encrypts all the data that is sent and received over the network and - thus makes it harder for attackers to spy on sensitive information. +There are a few ways to do secure HTTP transfers. By far the most common +protocol for doing this is what is generally known as HTTPS, HTTP over +SSL. SSL encrypts all the data that is sent and received over the network and +thus makes it harder for attackers to spy on sensitive information. - SSL (or TLS as the current version of the standard is called) offers a set of - advanced features to do secure transfers over HTTP. +SSL (or TLS as the current version of the standard is called) offers a set of +advanced features to do secure transfers over HTTP. - curl supports encrypted fetches when built to use a TLS library and it can be - built to use one out of a fairly large set of libraries - `curl -V` shows - which one your curl was built to use (if any). To get a page from an HTTPS - server, simply run curl like: +curl supports encrypted fetches when built to use a TLS library and it can be +built to use one out of a fairly large set of libraries - `curl -V` shows +which one your curl was built to use (if any). To get a page from an HTTPS +server, simply run curl like: curl https://secure.example.com ## Certificates - In the HTTPS world, you use certificates to validate that you are the one you - claim to be, as an addition to normal passwords. curl supports client- side - certificates. All certificates are locked with a passphrase, which you need - to enter before the certificate can be used by curl. The passphrase can be - specified on the command line or if not, entered interactively when curl - queries for it. Use a certificate with curl on an HTTPS server like: +In the HTTPS world, you use certificates to validate that you are the one you +claim to be, as an addition to normal passwords. curl supports client- side +certificates. All certificates are locked with a passphrase, which you need +to enter before the certificate can be used by curl. The passphrase can be +specified on the command line or if not, entered interactively when curl +queries for it. Use a certificate with curl on an HTTPS server like: curl --cert mycert.pem https://secure.example.com - curl also tries to verify that the server is who it claims to be, by - verifying the server's certificate against a locally stored CA cert bundle. - Failing the verification causes curl to deny the connection. You must then - use [`--insecure`](https://curl.se/docs/manpage.html#-k) (`-k`) in case you - want to tell curl to ignore that the server cannot be verified. +curl also tries to verify that the server is who it claims to be, by +verifying the server's certificate against a locally stored CA cert bundle. +Failing the verification causes curl to deny the connection. You must then +use [`--insecure`](https://curl.se/docs/manpage.html#-k) (`-k`) in case you +want to tell curl to ignore that the server cannot be verified. - More about server certificate verification and ca cert bundles can be read in - the [`SSLCERTS` document](https://curl.se/docs/sslcerts.html). +More about server certificate verification and ca cert bundles can be read in +the [`SSLCERTS` document](https://curl.se/docs/sslcerts.html). - At times you may end up with your own CA cert store and then you can tell - curl to use that to verify the server's certificate: +At times you may end up with your own CA cert store and then you can tell +curl to use that to verify the server's certificate: curl --cacert ca-bundle.pem https://example.com/ @@ -606,106 +606,106 @@ SPDX-License-Identifier: curl ## Modify method and headers - Doing fancy stuff, you may need to add or change elements of a single curl - request. +Doing fancy stuff, you may need to add or change elements of a single curl +request. - For example, you can change the POST method to `PROPFIND` and send the data - as `Content-Type: text/xml` (instead of the default `Content-Type`) like - this: +For example, you can change the POST method to `PROPFIND` and send the data +as `Content-Type: text/xml` (instead of the default `Content-Type`) like +this: curl --data "" --header "Content-Type: text/xml" \ --request PROPFIND example.com - You can delete a default header by providing one without content. Like you - can ruin the request by chopping off the `Host:` header: +You can delete a default header by providing one without content. Like you +can ruin the request by chopping off the `Host:` header: curl --header "Host:" https://www.example.com - You can add headers the same way. Your server may want a `Destination:` - header, and you can add it: +You can add headers the same way. Your server may want a `Destination:` +header, and you can add it: curl --header "Destination: nowhere" https://example.com ## More on changed methods - It should be noted that curl selects which methods to use on its own - depending on what action to ask for. `-d` makes a POST, `-I` makes a HEAD and - so on. If you use the [`--request`](https://curl.se/docs/manpage.html#-X) / - `-X` option you can change the method keyword curl selects, but you do not - modify curl's behavior. This means that if you for example use -d "data" to - do a POST, you can modify the method to a `PROPFIND` with `-X` and curl still - thinks it sends a POST. You can change the normal GET to a POST method by - simply adding `-X POST` in a command line like: +It should be noted that curl selects which methods to use on its own +depending on what action to ask for. `-d` makes a POST, `-I` makes a HEAD and +so on. If you use the [`--request`](https://curl.se/docs/manpage.html#-X) / +`-X` option you can change the method keyword curl selects, but you do not +modify curl's behavior. This means that if you for example use -d "data" to +do a POST, you can modify the method to a `PROPFIND` with `-X` and curl still +thinks it sends a POST. You can change the normal GET to a POST method by +simply adding `-X POST` in a command line like: curl -X POST https://example.org/ - curl however still acts as if it sent a GET so it does not send any request - body etc. +curl however still acts as if it sent a GET so it does not send any request +body etc. # Web Login ## Some login tricks - While not strictly just HTTP related, it still causes a lot of people - problems so here's the executive run-down of how the vast majority of all - login forms work and how to login to them using curl. - - It can also be noted that to do this properly in an automated fashion, you - most certainly need to script things and do multiple curl invokes etc. - - First, servers mostly use cookies to track the logged-in status of the - client, so you need to capture the cookies you receive in the responses. - Then, many sites also set a special cookie on the login page (to make sure - you got there through their login page) so you should make a habit of first - getting the login-form page to capture the cookies set there. - - Some web-based login systems feature various amounts of JavaScript, and - sometimes they use such code to set or modify cookie contents. Possibly they - do that to prevent programmed logins, like this manual describes how to... - Anyway, if reading the code is not enough to let you repeat the behavior - manually, capturing the HTTP requests done by your browsers and analyzing the - sent cookies is usually a working method to work out how to shortcut the - JavaScript need. - - In the actual `
` tag for the login, lots of sites fill-in - random/session or otherwise secretly generated hidden tags and you may need - to first capture the HTML code for the login form and extract all the hidden - fields to be able to do a proper login POST. Remember that the contents need - to be URL encoded when sent in a normal POST. +While not strictly just HTTP related, it still causes a lot of people +problems so here's the executive run-down of how the vast majority of all +login forms work and how to login to them using curl. + +It can also be noted that to do this properly in an automated fashion, you +most certainly need to script things and do multiple curl invokes etc. + +First, servers mostly use cookies to track the logged-in status of the +client, so you need to capture the cookies you receive in the responses. +Then, many sites also set a special cookie on the login page (to make sure +you got there through their login page) so you should make a habit of first +getting the login-form page to capture the cookies set there. + +Some web-based login systems feature various amounts of JavaScript, and +sometimes they use such code to set or modify cookie contents. Possibly they +do that to prevent programmed logins, like this manual describes how to... +Anyway, if reading the code is not enough to let you repeat the behavior +manually, capturing the HTTP requests done by your browsers and analyzing the +sent cookies is usually a working method to work out how to shortcut the +JavaScript need. + +In the actual `` tag for the login, lots of sites fill-in +random/session or otherwise secretly generated hidden tags and you may need +to first capture the HTML code for the login form and extract all the hidden +fields to be able to do a proper login POST. Remember that the contents need +to be URL encoded when sent in a normal POST. # Debug ## Some debug tricks - Many times when you run curl on a site, you notice that the site does not - seem to respond the same way to your curl requests as it does to your - browser's. +Many times when you run curl on a site, you notice that the site does not +seem to respond the same way to your curl requests as it does to your +browser's. - Then you need to start making your curl requests more similar to your - browser's requests: +Then you need to start making your curl requests more similar to your +browser's requests: - - Use the `--trace-ascii` option to store fully detailed logs of the requests - for easier analyzing and better understanding +- Use the `--trace-ascii` option to store fully detailed logs of the requests + for easier analyzing and better understanding - - Make sure you check for and use cookies when needed (both reading with - `--cookie` and writing with `--cookie-jar`) +- Make sure you check for and use cookies when needed (both reading with + `--cookie` and writing with `--cookie-jar`) - - Set user-agent (with [`-A`](https://curl.se/docs/manpage.html#-A)) to - one like a recent popular browser does +- Set user-agent (with [`-A`](https://curl.se/docs/manpage.html#-A)) to + one like a recent popular browser does - - Set referer (with [`-E`](https://curl.se/docs/manpage.html#-E)) like - it is set by the browser +- Set referer (with [`-E`](https://curl.se/docs/manpage.html#-E)) like + it is set by the browser - - If you use POST, make sure you send all the fields and in the same order as - the browser does it. +- If you use POST, make sure you send all the fields and in the same order as + the browser does it. ## Check what the browsers do - A good helper to make sure you do this right, is the web browsers' developers - tools that let you view all headers you send and receive (even when using - HTTPS). +A good helper to make sure you do this right, is the web browsers' developers +tools that let you view all headers you send and receive (even when using +HTTPS). - A more raw approach is to capture the HTTP traffic on the network with tools - such as Wireshark or tcpdump and check what headers that were sent and - received by the browser. (HTTPS forces you to use `SSLKEYLOGFILE` to do - that.) +A more raw approach is to capture the HTTP traffic on the network with tools +such as Wireshark or tcpdump and check what headers that were sent and +received by the browser. (HTTPS forces you to use `SSLKEYLOGFILE` to do +that.) diff --git a/docs/VERSIONS.md b/docs/VERSIONS.md index b102b0720722..3b04cbc7714b 100644 --- a/docs/VERSIONS.md +++ b/docs/VERSIONS.md @@ -7,60 +7,60 @@ SPDX-License-Identifier: curl Version Numbers and Releases ============================ - The command line tool curl and the library libcurl are individually - versioned, but they usually follow each other closely. +The command line tool curl and the library libcurl are individually +versioned, but they usually follow each other closely. - The version numbering is always built up using the same system: +The version numbering is always built up using the same system: - X.Y.Z + X.Y.Z - - X is main version number - - Y is release number - - Z is patch number +- X is main version number +- Y is release number +- Z is patch number ## Bumping numbers - One of these numbers get bumped in each new release. The numbers to the right - of a bumped number are reset to zero. +One of these numbers get bumped in each new release. The numbers to the right +of a bumped number are reset to zero. - The main version number is bumped when *really* big, world colliding changes - are made. The release number is bumped when changes are performed or - things/features are added. The patch number is bumped when the changes are - mere bugfixes. +The main version number is bumped when *really* big, world colliding changes +are made. The release number is bumped when changes are performed or +things/features are added. The patch number is bumped when the changes are +mere bugfixes. - It means that after release 1.2.3, we can release 2.0.0 if something really - big has been made, 1.3.0 if not that big changes were made or 1.2.4 if only - bugs were fixed. +It means that after release 1.2.3, we can release 2.0.0 if something really +big has been made, 1.3.0 if not that big changes were made or 1.2.4 if only +bugs were fixed. - Bumping, as in increasing the number with 1, is unconditionally only - affecting one of the numbers (except the ones to the right of it, that may be - set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99 - becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100.0 might come. +Bumping, as in increasing the number with 1, is unconditionally only +affecting one of the numbers (except the ones to the right of it, that may be +set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99 +becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100.0 might come. - All original curl source release archives are named according to the libcurl - version (not according to the curl client version that, as said before, might - differ). +All original curl source release archives are named according to the libcurl +version (not according to the curl client version that, as said before, might +differ). - As a service to any application that might want to support new libcurl - features while still being able to build with older versions, all releases - have the libcurl version stored in the `curl/curlver.h` file using a static - numbering scheme that can be used for comparison. The version number is - defined as: +As a service to any application that might want to support new libcurl +features while still being able to build with older versions, all releases +have the libcurl version stored in the `curl/curlver.h` file using a static +numbering scheme that can be used for comparison. The version number is +defined as: ```c #define LIBCURL_VERSION_NUM 0xXXYYZZ ``` - Where `XX`, `YY` and `ZZ` are the main version, release and patch numbers in - hexadecimal. All three number fields are always represented using two digits - (eight bits each). 1.2 would appear as "0x010200" while version 9.11.7 - appears as `0x090b07`. +Where `XX`, `YY` and `ZZ` are the main version, release and patch numbers in +hexadecimal. All three number fields are always represented using two digits +(eight bits each). 1.2 would appear as "0x010200" while version 9.11.7 +appears as `0x090b07`. - This 6-digit hexadecimal number is always a greater number in a more recent - release. It makes comparisons with greater than and less than work. +This 6-digit hexadecimal number is always a greater number in a more recent +release. It makes comparisons with greater than and less than work. - This number is also available as three separate defines: - `LIBCURL_VERSION_MAJOR`, `LIBCURL_VERSION_MINOR` and `LIBCURL_VERSION_PATCH`. +This number is also available as three separate defines: +`LIBCURL_VERSION_MAJOR`, `LIBCURL_VERSION_MINOR` and `LIBCURL_VERSION_PATCH`. ## Past releases diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c index b068dabf69da..5f9362b83e69 100644 --- a/docs/examples/ephiperfifo.c +++ b/docs/examples/ephiperfifo.c @@ -32,31 +32,30 @@ * but this uses epoll and timerfd instead of libevent. * * Written by Jeff Pohlmeyer, converted to use epoll by Josh Bialkowski - -Requires a Linux system with epoll - -When running, the program creates the named pipe "hiper.fifo" - -Whenever there is input into the fifo, the program reads the input as a list -of URL's and creates some new easy handles to fetch each URL via the -curl_multi "hiper" API. - -Thus, you can try a single URL: - % echo http://www.yahoo.com > hiper.fifo - -Or a whole bunch of them: - % cat my-url-list > hiper.fifo - -The fifo buffer is handled almost instantly, so you can even add more URL's -while the previous requests are still being downloaded. - -Note: - For the sake of simplicity, URL length is limited to 1023 char's ! - -This is purely a demo app, all retrieved data is simply discarded by the write -callback. - -*/ + * + * Requires a Linux system with epoll + * + * When running, the program creates the named pipe "hiper.fifo" + * + * Whenever there is input into the fifo, the program reads the input as a list + * of URL's and creates some new easy handles to fetch each URL via the + * curl_multi "hiper" API. + * + * Thus, you can try a single URL: + * % echo http://www.yahoo.com > hiper.fifo + * + * Or a whole bunch of them: + * % cat my-url-list > hiper.fifo + * + * The fifo buffer is handled almost instantly, so you can even add more URL's + * while the previous requests are still being downloaded. + * + * Note: + * For the sake of simplicity, URL length is limited to 1023 chars. + * + * This is purely a demo app, all retrieved data is simply discarded by + * the write callback. + */ #include #include #include diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c index 79ce6d3973a6..565293d14079 100644 --- a/docs/examples/evhiperfifo.c +++ b/docs/examples/evhiperfifo.c @@ -32,34 +32,33 @@ * but this uses libev instead of libevent. * * Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter - -Requires libev and a (POSIX?) system that has mkfifo(). - -This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" -sample programs. - -When running, the program creates the named pipe "hiper.fifo" - -Whenever there is input into the fifo, the program reads the input as a list -of URL's and creates some new easy handles to fetch each URL via the -curl_multi "hiper" API. - -Thus, you can try a single URL: - % echo http://www.yahoo.com > hiper.fifo - -Or a whole bunch of them: - % cat my-url-list > hiper.fifo - -The fifo buffer is handled almost instantly, so you can even add more URL's -while the previous requests are still being downloaded. - -Note: - For the sake of simplicity, URL length is limited to 1023 char's ! - -This is purely a demo app, all retrieved data is simply discarded by the write -callback. - -*/ + * + * Requires libev and a (POSIX?) system that has mkfifo(). + * + * This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" + * sample programs. + * + * When running, the program creates the named pipe "hiper.fifo" + * + * Whenever there is input into the fifo, the program reads the input as a list + * of URL's and creates some new easy handles to fetch each URL via the + * curl_multi "hiper" API. + * + * Thus, you can try a single URL: + * % echo http://www.yahoo.com > hiper.fifo + * + * Or a whole bunch of them: + * % cat my-url-list > hiper.fifo + * + * The fifo buffer is handled almost instantly, so you can even add more URL's + * while the previous requests are still being downloaded. + * + * Note: + * For the sake of simplicity, URL length is limited to 1023 chars. + * + * This is purely a demo app, all retrieved data is simply discarded by + * the write callback. + */ #include #include #include diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c index 26545662477c..6a7c25aa8b10 100644 --- a/docs/examples/ghiper.c +++ b/docs/examples/ghiper.c @@ -22,38 +22,38 @@ * ***************************************************************************/ /* - * multi socket API usage with glib2 + * multi socket interface with glib2 * */ /* Example application source code using the multi socket interface to * download many files at once. * * Written by Jeff Pohlmeyer - - Requires glib-2.x and a (POSIX?) system that has mkfifo(). - - This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" - sample programs, adapted to use glib's g_io_channel in place of libevent. - - When running, the program creates the named pipe "hiper.fifo" - - Whenever there is input into the fifo, the program reads the input as a list - of URL's and creates some new easy handles to fetch each URL via the - curl_multi "hiper" API. - - Thus, you can try a single URL: - % echo http://www.yahoo.com > hiper.fifo - - Or a whole bunch of them: - % cat my-url-list > hiper.fifo - - The fifo buffer is handled almost instantly, so you can even add more URL's - while the previous requests are still being downloaded. - - This is purely a demo app, all retrieved data is simply discarded by the write - callback. - -*/ + * + * Requires glib-2.x and a (POSIX?) system that has mkfifo(). + * + * This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" + * sample programs, adapted to use glib's g_io_channel in place of libevent. + * + * When running, the program creates the named pipe "hiper.fifo" + * + * Whenever there is input into the fifo, the program reads the input as a list + * of URL's and creates some new easy handles to fetch each URL via the + * curl_multi "hiper" API. + * + * Thus, you can try a single URL: + * % echo http://www.yahoo.com > hiper.fifo + * + * Or a whole bunch of them: + * % cat my-url-list > hiper.fifo + * + * The fifo buffer is handled almost instantly, so you can even add more URL's + * while the previous requests are still being downloaded. + * + * This is purely a demo app, all retrieved data is simply discarded by + * the write callback. + * + */ #include #include diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c index 30bb8b8a6ab0..2331c086477a 100644 --- a/docs/examples/hiperfifo.c +++ b/docs/examples/hiperfifo.c @@ -22,41 +22,40 @@ * ***************************************************************************/ /* - * multi socket API usage with libevent 2 + * multi socket interface with libevent 2 * */ /* Example application source code using the multi socket interface to - download many files at once. - -Written by Jeff Pohlmeyer - -Requires libevent version 2 and a (POSIX?) system that has mkfifo(). - -This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" -sample programs. - -When running, the program creates the named pipe "hiper.fifo" - -Whenever there is input into the fifo, the program reads the input as a list -of URL's and creates some new easy handles to fetch each URL via the -curl_multi "hiper" API. - -Thus, you can try a single URL: - % echo http://www.yahoo.com > hiper.fifo - -Or a whole bunch of them: - % cat my-url-list > hiper.fifo - -The fifo buffer is handled almost instantly, so you can even add more URL's -while the previous requests are still being downloaded. - -Note: - For the sake of simplicity, URL length is limited to 1023 char's ! - -This is purely a demo app, all retrieved data is simply discarded by the write -callback. - -*/ + * download many files at once. + * + * Written by Jeff Pohlmeyer + * + * Requires libevent version 2 and a (POSIX?) system that has mkfifo(). + * + * This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" + * sample programs. + * + * When running, the program creates the named pipe "hiper.fifo" + * + * Whenever there is input into the fifo, the program reads the input as a list + * of URL's and creates some new easy handles to fetch each URL via the + * curl_multi "hiper" API. + * + * Thus, you can try a single URL: + * % echo http://www.yahoo.com > hiper.fifo + * + * Or a whole bunch of them: + * % cat my-url-list > hiper.fifo + * + * The fifo buffer is handled almost instantly, so you can even add more URL's + * while the previous requests are still being downloaded. + * + * Note: + * For the sake of simplicity, URL length is limited to 1023 chars. + * + * This is purely a demo app, all retrieved data is simply discarded by + * the write callback. + */ #include #include #include diff --git a/docs/examples/multi-uv.c b/docs/examples/multi-uv.c index dd0102c264c3..a59c5988d9fa 100644 --- a/docs/examples/multi-uv.c +++ b/docs/examples/multi-uv.c @@ -26,12 +26,12 @@ * */ /* Use the socket_action interface to download multiple files in parallel, - powered by libuv. - - Requires libuv and (of course) libcurl. - - See https://docs.libuv.org/en/v1.x/index.html libuv API documentation -*/ + * powered by libuv. + * + * Requires libuv and (of course) libcurl. + * + * See https://docs.libuv.org/en/v1.x/index.html libuv API documentation + */ /* Requires: USE_LIBUV */ diff --git a/docs/internals/WEBSOCKET.md b/docs/internals/WEBSOCKET.md index d42ab3cfe7d1..b38947581591 100644 --- a/docs/internals/WEBSOCKET.md +++ b/docs/internals/WEBSOCKET.md @@ -38,17 +38,17 @@ WebSocket with libcurl can be done two ways. The new options to `curl_easy_setopt()`: - `CURLOPT_WS_OPTIONS` - to control specific behavior. `CURLWS_RAW_MODE` makes - libcurl provide all WebSocket traffic raw in the callback. `CURLWS_NOAUTOPONG` - disables automatic `PONG` replies. +`CURLOPT_WS_OPTIONS` - to control specific behavior. `CURLWS_RAW_MODE` makes +libcurl provide all WebSocket traffic raw in the callback. `CURLWS_NOAUTOPONG` +disables automatic `PONG` replies. The new function calls: - `curl_ws_recv()` - receive a WebSocket frame +`curl_ws_recv()` - receive a WebSocket frame - `curl_ws_send()` - send a WebSocket frame +`curl_ws_send()` - send a WebSocket frame - `curl_ws_meta()` - return WebSocket metadata within a write callback +`curl_ws_meta()` - return WebSocket metadata within a write callback ## Max frame size diff --git a/docs/libcurl/ABI.md b/docs/libcurl/ABI.md index 0ec9928b9891..39e81bb9a7d7 100644 --- a/docs/libcurl/ABI.md +++ b/docs/libcurl/ABI.md @@ -7,62 +7,62 @@ SPDX-License-Identifier: curl ABI - Application Binary Interface ================================== - "ABI" describes the low-level interface between an application program and a - library. Calling conventions, function arguments, return values, struct - sizes/defines and more. +"ABI" describes the low-level interface between an application program and a +library. Calling conventions, function arguments, return values, struct +sizes/defines and more. - [Wikipedia has a longer description](https://en.wikipedia.org/wiki/Application_binary_interface) +[Wikipedia has a longer description](https://en.wikipedia.org/wiki/Application_binary_interface) ## Upgrades - A libcurl upgrade does not break the ABI or change established and documented - behavior. Your application can remain using libcurl just as before, only with - fewer bugs and possibly with added new features. +A libcurl upgrade does not break the ABI or change established and documented +behavior. Your application can remain using libcurl just as before, only with +fewer bugs and possibly with added new features. ## Version Numbers - In libcurl land, you cannot tell by the libcurl version number if that - libcurl is binary compatible or not with another libcurl version. As a rule, - we do not break the ABI so you can *always* upgrade to a later version without - any loss or change in functionality. +In libcurl land, you cannot tell by the libcurl version number if that +libcurl is binary compatible or not with another libcurl version. As a rule, +we do not break the ABI so you can *always* upgrade to a later version without +any loss or change in functionality. ## SONAME Bumps - Whenever there are changes done to the library that causes an ABI breakage, - that may require your application to get attention or possibly be changed to - adhere to new things, we bump the SONAME. Then the library gets a different - output name and thus can in fact be installed in parallel with an older - installed lib (on most systems). Thus, old applications built against the - previous ABI version remains working and using the older lib, while newer - applications build and use the newer one. +Whenever there are changes done to the library that causes an ABI breakage, +that may require your application to get attention or possibly be changed to +adhere to new things, we bump the SONAME. Then the library gets a different +output name and thus can in fact be installed in parallel with an older +installed lib (on most systems). Thus, old applications built against the +previous ABI version remains working and using the older lib, while newer +applications build and use the newer one. - During the first seven years of libcurl releases, there have only been four - ABI breakages. +During the first seven years of libcurl releases, there have only been four +ABI breakages. - We are determined to bump the SONAME as rarely as possible. Ideally, we never - do it again. +We are determined to bump the SONAME as rarely as possible. Ideally, we never +do it again. ## Downgrades - Going to an older libcurl version from one you are currently using can be a - tricky thing. Mostly we add features and options to newer libcurls as that - does not break ABI or hamper existing applications. This has the implication - that going backwards may get you in a situation where you pick a libcurl that - does not support the options your application needs. Or possibly you even - downgrade so far so you cross an ABI break border and thus a different - SONAME, and then your application may need to adapt to the modified ABI. +Going to an older libcurl version from one you are currently using can be a +tricky thing. Mostly we add features and options to newer libcurls as that +does not break ABI or hamper existing applications. This has the implication +that going backwards may get you in a situation where you pick a libcurl that +does not support the options your application needs. Or possibly you even +downgrade so far so you cross an ABI break border and thus a different +SONAME, and then your application may need to adapt to the modified ABI. ## History - The previous major library SONAME number bumps (breaking backwards - compatibility) happened the following times: +The previous major library SONAME number bumps (breaking backwards +compatibility) happened the following times: - 0 - libcurl 7.1, August 2000 +0 - libcurl 7.1, August 2000 - 1 - libcurl 7.5 December 2000 +1 - libcurl 7.5 December 2000 - 2 - libcurl 7.7 March 2001 +2 - libcurl 7.7 March 2001 - 3 - libcurl 7.12.0 June 2004 +3 - libcurl 7.12.0 June 2004 - 4 - libcurl 7.16.0 October 2006 +4 - libcurl 7.16.0 October 2006 diff --git a/docs/libcurl/curl_easy_getinfo.md b/docs/libcurl/curl_easy_getinfo.md index a7665f46ad60..5727d9ce115b 100644 --- a/docs/libcurl/curl_easy_getinfo.md +++ b/docs/libcurl/curl_easy_getinfo.md @@ -398,11 +398,11 @@ An overview of the time values available from curl_easy_getinfo(3) |--|--|--|--|--|--|--|--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_POSTTRANSFER_TIME_T(3), - CURLINFO_STARTTRANSFER_TIME_T(3), CURLINFO_TOTAL_TIME_T(3), - CURLINFO_REDIRECT_TIME_T(3) +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_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/libcurl-tutorial.md b/docs/libcurl/libcurl-tutorial.md index 6cfe354fc1af..696fb5489b83 100644 --- a/docs/libcurl/libcurl-tutorial.md +++ b/docs/libcurl/libcurl-tutorial.md @@ -46,7 +46,7 @@ Your compiler needs to know where the libcurl headers are located. Therefore you must set your compiler's include path to point to the directory where you installed them. The 'curl-config'[3] tool can be used to get this information: ~~~c - $ curl-config --cflags + $ curl-config --cflags ~~~ ## Linking the Program with libcurl @@ -58,7 +58,7 @@ OpenSSL libraries, but even some standard OS libraries may be needed on the command line. To figure out which flags to use, once again the 'curl-config' tool comes to the rescue: ~~~c - $ curl-config --libs + $ curl-config --libs ~~~ ## SSL or Not @@ -71,7 +71,7 @@ installed libcurl has been built with SSL support enabled, use *curl-config* like this: ~~~c - $ curl-config --feature + $ curl-config --feature ~~~ If SSL is supported, the keyword *SSL* is written to stdout, possibly together @@ -102,7 +102,7 @@ The program must initialize some of the libcurl functionality globally. That means it should be done exactly once, no matter how many times you intend to use the library. Once for your program's entire life time. This is done using ~~~c - curl_global_init() + curl_global_init() ~~~ and it takes one parameter which is a bit pattern that tells libcurl what to initialize. Using *CURL_GLOBAL_ALL* makes it initialize all known internal @@ -168,7 +168,7 @@ must never share the same handle in multiple threads. Get an easy handle with ~~~c - handle = curl_easy_init(); + handle = curl_easy_init(); ~~~ It returns an easy handle. Using that you proceed to the next step: setting up your preferred actions. A handle is just a logic entity for the upcoming @@ -194,7 +194,7 @@ One of the most basic properties to set in the handle is the URL. You set your preferred URL to transfer with CURLOPT_URL(3) in a manner similar to: ~~~c - curl_easy_setopt(handle, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(handle, CURLOPT_URL, "https://example.com/"); ~~~ Let's assume for a while that you want to receive data as the URL identifies a @@ -203,17 +203,17 @@ that needs this transfer, I assume that you would like to get the data passed to you directly instead of simply getting it passed to stdout. So, you write your own function that matches this prototype: ~~~c - size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); + size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); ~~~ You tell libcurl to pass all data to this function by issuing a function similar to this: ~~~c - curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data); ~~~ You can control what data your callback function gets in the fourth argument by setting another property: ~~~c - curl_easy_setopt(handle, CURLOPT_WRITEDATA, &internal_struct); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, &internal_struct); ~~~ Using that property, you can easily pass local data between your application and the function that gets invoked by libcurl. libcurl itself does not touch @@ -243,7 +243,7 @@ There are of course many more options you can set, and we get back to a few of them later. Let's instead continue to the actual transfer: ~~~c - success = curl_easy_perform(handle); + success = curl_easy_perform(handle); ~~~ curl_easy_perform(3) connects to the remote site, does the necessary commands @@ -319,7 +319,7 @@ data by asking us for it. To make it do that, we set the read callback and the custom pointer libcurl passes to our read callback. The read callback should have a prototype similar to: ~~~c - size_t function(char *bufptr, size_t size, size_t nitems, void *userp); + size_t function(char *bufptr, size_t size, size_t nitems, void *userp); ~~~ Where *bufptr* is the pointer to a buffer we fill in with data to upload and *nitems* is the size of the buffer and therefore also the maximum @@ -327,21 +327,21 @@ amount of data we can return to libcurl in this call. The *userp* pointer is the custom pointer we set to point to a struct of ours to pass private data between the application and the callback. ~~~c - curl_easy_setopt(handle, CURLOPT_READFUNCTION, read_function); + curl_easy_setopt(handle, CURLOPT_READFUNCTION, read_function); - curl_easy_setopt(handle, CURLOPT_READDATA, &filedata); + curl_easy_setopt(handle, CURLOPT_READDATA, &filedata); ~~~ Tell libcurl that we want to upload: ~~~c - curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L); ~~~ A few protocols do not behave properly when uploads are done without any prior knowledge of the expected file size. So, set the upload file size using the CURLOPT_INFILESIZE_LARGE(3) for all known file sizes like this[1]: ~~~c - /* in this example, file_size must be an curl_off_t variable */ - curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, file_size); + /* in this example, file_size must be an curl_off_t variable */ + curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, file_size); ~~~ When you call curl_easy_perform(3) this time, it performs all the @@ -361,7 +361,7 @@ Most protocols support that you specify the name and password in the URL itself. libcurl detects this and use them accordingly. This is written like this: ~~~c - protocol://user:password@example.com/path/ + protocol://user:password@example.com/path/ ~~~ If you need any odd letters in your username or password, you should enter them URL encoded, as %XX where XX is a two-digit hexadecimal number. @@ -372,7 +372,7 @@ CURLOPT_USERPWD(3) option. The argument passed to libcurl should be a char * to a string in the format "user:password". In a manner like this: ~~~c - curl_easy_setopt(handle, CURLOPT_USERPWD, "myname:thesecret"); + curl_easy_setopt(handle, CURLOPT_USERPWD, "myname:thesecret"); ~~~ Another case where name and password might be needed at times, is for those @@ -381,7 +381,7 @@ another option for this, the CURLOPT_PROXYUSERPWD(3). It is used quite similar to the CURLOPT_USERPWD(3) option like this: ~~~c - curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, "myname:thesecret"); + curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, "myname:thesecret"); ~~~ There is a long time Unix "standard" way of storing FTP usernames and @@ -396,15 +396,15 @@ non-FTP protocols such as HTTP. To make curl use this file, use the CURLOPT_NETRC(3) option: ~~~c - curl_easy_setopt(handle, CURLOPT_NETRC, 1L); + curl_easy_setopt(handle, CURLOPT_NETRC, 1L); ~~~ A basic example of how such a .netrc file may look like: ~~~c - machine myhost.mydomain.com - login userlogin - password secretword + machine myhost.mydomain.com + login userlogin + password secretword ~~~ All these examples have been cases where the password has been optional, or @@ -414,7 +414,7 @@ you are using an SSL private key for secure transfers. To pass the known private key password to libcurl: ~~~c - curl_easy_setopt(handle, CURLOPT_KEYPASSWD, "keypassword"); + curl_easy_setopt(handle, CURLOPT_KEYPASSWD, "keypassword"); ~~~ # HTTP Authentication @@ -431,15 +431,14 @@ Negotiate (SPNEGO). You can tell libcurl which one to use with CURLOPT_HTTPAUTH(3) as in: ~~~c - curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); - + curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); ~~~ When you send authentication to a proxy, you can also set authentication type the same way but instead with CURLOPT_PROXYAUTH(3): ~~~c - curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM); + curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM); ~~~ Both these options allow you to set multiple types (by ORing them together), @@ -448,7 +447,7 @@ claims to support. This method does however add a round-trip since libcurl must first ask the server what it supports: ~~~c - curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST | CURLAUTH_BASIC); + curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST | CURLAUTH_BASIC); ~~~ For convenience, you can use the *CURLAUTH_ANY* define (instead of a list with @@ -487,21 +486,21 @@ done in a generic way, by building a list of our own headers and then passing that list to libcurl. ~~~c - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: text/xml"); + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, "Content-Type: text/xml"); - /* post binary data */ - curl_easy_setopt(handle, CURLOPT_POSTFIELDS, binaryptr); + /* post binary data */ + curl_easy_setopt(handle, CURLOPT_POSTFIELDS, binaryptr); - /* set the size of the postfields data */ - curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, 23L); + /* set the size of the postfields data */ + curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, 23L); - /* pass our list of custom made headers */ - curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + /* pass our list of custom made headers */ + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); - curl_easy_perform(handle); /* post away! */ + curl_easy_perform(handle); /* post away! */ - curl_slist_free_all(headers); /* free the header list */ + curl_slist_free_all(headers); /* free the header list */ ~~~ While the simple examples above cover the majority of all cases where HTTP @@ -531,24 +530,24 @@ The following example sets two simple text parts with plain textual contents, and then a file with binary contents and uploads the whole thing. ~~~c - curl_mime *multipart = curl_mime_init(handle); - curl_mimepart *part = curl_mime_addpart(multipart); - curl_mime_name(part, "name"); - curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); - part = curl_mime_addpart(multipart); - curl_mime_name(part, "project"); - curl_mime_data(part, "curl", CURL_ZERO_TERMINATED); - part = curl_mime_addpart(multipart); - curl_mime_name(part, "logotype-image"); - curl_mime_filedata(part, "curl.png"); - - /* Set the form info */ - curl_easy_setopt(handle, CURLOPT_MIMEPOST, multipart); - - curl_easy_perform(handle); /* post away! */ - - /* free the post data again */ - curl_mime_free(multipart); + curl_mime *multipart = curl_mime_init(handle); + curl_mimepart *part = curl_mime_addpart(multipart); + curl_mime_name(part, "name"); + curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "project"); + curl_mime_data(part, "curl", CURL_ZERO_TERMINATED); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "logotype-image"); + curl_mime_filedata(part, "curl.png"); + + /* Set the form info */ + curl_easy_setopt(handle, CURLOPT_MIMEPOST, multipart); + + curl_easy_perform(handle); /* post away! */ + + /* free the post data again */ + curl_mime_free(multipart); ~~~ To post multiple files for a single form field, you must supply each file in @@ -559,8 +558,8 @@ multiple files posting is deprecated by RFC 7578, chapter 4.3. To set the data source from an already opened FILE pointer, use: ~~~c - curl_mime_data_cb(part, filesize, (curl_read_callback) fread, - (curl_seek_callback) fseek, NULL, filepointer); + curl_mime_data_cb(part, filesize, (curl_read_callback)fread, + (curl_seek_callback)fseek, NULL, filepointer); ~~~ A deprecated curl_formadd(3) function is still supported in libcurl. @@ -574,25 +573,25 @@ parts, you post the whole form. The MIME API example above is expressed as follows using this function: ~~~c - struct curl_httppost *post = NULL; - struct curl_httppost *last = NULL; - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "name", - CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "project", - CURLFORM_COPYCONTENTS, "curl", CURLFORM_END); - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "logotype-image", - CURLFORM_FILECONTENT, "curl.png", CURLFORM_END); - - /* Set the form info */ - curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); - - curl_easy_perform(handle); /* post away! */ - - /* free the post data again */ - curl_formfree(post); + struct curl_httppost *post = NULL; + struct curl_httppost *last = NULL; + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "name", + CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "project", + CURLFORM_COPYCONTENTS, "curl", CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "logotype-image", + CURLFORM_FILECONTENT, "curl.png", CURLFORM_END); + + /* Set the form info */ + curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); + + curl_easy_perform(handle); /* post away! */ + + /* free the post data again */ + curl_formfree(post); ~~~ Multipart formposts are chains of parts using MIME-style separators and @@ -605,19 +604,19 @@ shows how you set headers to one specific part when you add that to the post handle: ~~~c - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: text/xml"); + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, "Content-Type: text/xml"); - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "logotype-image", - CURLFORM_FILECONTENT, "curl.xml", - CURLFORM_CONTENTHEADER, headers, - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "logotype-image", + CURLFORM_FILECONTENT, "curl.xml", + CURLFORM_CONTENTHEADER, headers, + CURLFORM_END); - curl_easy_perform(handle); /* post away! */ + curl_easy_perform(handle); /* post away! */ - curl_formfree(post); /* free post */ - curl_slist_free_all(headers); /* free custom header list */ + curl_formfree(post); /* free post */ + curl_slist_free_all(headers); /* free custom header list */ ~~~ Since all options on an easy handle are "sticky", they remain the same until @@ -626,7 +625,7 @@ curl to go back to a plain GET request if you intend to do one as your next request. You force an easy handle to go back to GET by using the CURLOPT_HTTPGET(3) option: ~~~c - curl_easy_setopt(handle, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(handle, CURLOPT_HTTPGET, 1L); ~~~ Just setting CURLOPT_POSTFIELDS(3) to "" or NULL does *not* stop libcurl from doing a POST. It just makes it POST without any data to send! @@ -647,18 +646,18 @@ CURLOPT_MIMEPOST(3) instead of CURLOPT_HTTPPOST(3). Here are some example of *curl_formadd* calls to MIME API sequences: ~~~c - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "id", - CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); - CURLFORM_CONTENTHEADER, headers, - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "id", + CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END); + CURLFORM_CONTENTHEADER, headers, + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "id"); - curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); - curl_mime_headers(part, headers, FALSE); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "id"); + curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); + curl_mime_headers(part, headers, FALSE); ~~~ Setting the last curl_mime_headers(3) argument to TRUE would have caused @@ -666,16 +665,16 @@ the headers to be automatically released upon destroyed the multi-part, thus saving a clean-up call to curl_slist_free_all(3). ~~~c - curl_formadd(&post, &last, - CURLFORM_PTRNAME, "logotype-image", - CURLFORM_FILECONTENT, "-", - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_PTRNAME, "logotype-image", + CURLFORM_FILECONTENT, "-", + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "logotype-image"); - curl_mime_data_cb(part, (curl_off_t)-1, fread, fseek, NULL, stdin); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "logotype-image"); + curl_mime_data_cb(part, (curl_off_t)-1, fread, fseek, NULL, stdin); ~~~ curl_mime_name(3) always copies the field name. The special filename "-" is @@ -684,79 +683,79 @@ source using fread(). The transfer is be chunk-encoded since the data size is unknown. ~~~c - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "datafile[]", - CURLFORM_FILE, "file1", - CURLFORM_FILE, "file2", - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "datafile[]", + CURLFORM_FILE, "file1", + CURLFORM_FILE, "file2", + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "datafile[]"); - curl_mime_filedata(part, "file1"); - part = curl_mime_addpart(multipart); - curl_mime_name(part, "datafile[]"); - curl_mime_filedata(part, "file2"); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "datafile[]"); + curl_mime_filedata(part, "file1"); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "datafile[]"); + curl_mime_filedata(part, "file2"); ~~~ The deprecated multipart/mixed implementation of multiple files field is translated to two distinct parts with the same name. ~~~c - curl_easy_setopt(handle, CURLOPT_READFUNCTION, myreadfunc); - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "stream", - CURLFORM_STREAM, arg, - CURLFORM_CONTENTLEN, (curl_off_t) datasize, - CURLFORM_FILENAME, "archive.zip", - CURLFORM_CONTENTTYPE, "application/zip", - CURLFORM_END); + curl_easy_setopt(handle, CURLOPT_READFUNCTION, myreadfunc); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "stream", + CURLFORM_STREAM, arg, + CURLFORM_CONTENTLEN, (curl_off_t)datasize, + CURLFORM_FILENAME, "archive.zip", + CURLFORM_CONTENTTYPE, "application/zip", + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "stream"); - curl_mime_data_cb(part, (curl_off_t)datasize, - myreadfunc, NULL, NULL, arg); - curl_mime_filename(part, "archive.zip"); - curl_mime_type(part, "application/zip"); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "stream"); + curl_mime_data_cb(part, (curl_off_t)datasize, + myreadfunc, NULL, NULL, arg); + curl_mime_filename(part, "archive.zip"); + curl_mime_type(part, "application/zip"); ~~~ CURLOPT_READFUNCTION(3) callback is not used: it is replace by directly setting the part source data from the callback read function. ~~~c - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "memfile", - CURLFORM_BUFFER, "memfile.bin", - CURLFORM_BUFFERPTR, databuffer, - CURLFORM_BUFFERLENGTH, (long) sizeof databuffer, - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "memfile", + CURLFORM_BUFFER, "memfile.bin", + CURLFORM_BUFFERPTR, databuffer, + CURLFORM_BUFFERLENGTH, (long)sizeof(databuffer), + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "memfile"); - curl_mime_data(part, databuffer, (curl_off_t)sizeof(databuffer)); - curl_mime_filename(part, "memfile.bin"); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "memfile"); + curl_mime_data(part, databuffer, (curl_off_t)sizeof(databuffer)); + curl_mime_filename(part, "memfile.bin"); ~~~ curl_mime_data(3) always copies the initial data: data buffer is thus free for immediate reuse. ~~~c - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "message", - CURLFORM_FILECONTENT, "msg.txt", - CURLFORM_END); + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "message", + CURLFORM_FILECONTENT, "msg.txt", + CURLFORM_END); ~~~ becomes: ~~~c - part = curl_mime_addpart(multipart); - curl_mime_name(part, "message"); - curl_mime_filedata(part, "msg.txt"); - curl_mime_filename(part, NULL); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "message"); + curl_mime_filedata(part, "msg.txt"); + curl_mime_filename(part, NULL); ~~~ Use of curl_mime_filedata(3) sets the remote filename as a side effect: it is @@ -780,11 +779,11 @@ Set the progress callback by using CURLOPT_PROGRESSFUNCTION(3). Pass a pointer to a function that matches this prototype: ~~~c - int progress_callback(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); + int progress_callback(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); ~~~ If any of the input arguments is unknown, a 0 is provided. The first argument, @@ -801,13 +800,13 @@ The callbacks CANNOT be non-static class member functions Example C++ code: ~~~c -class AClass { - static size_t write_data(void *ptr, size_t size, size_t nmemb, - void *ourpointer) - { - /* do what you want with the data */ - } -} + class AClass { + static size_t write_data(void *ptr, size_t size, size_t nmemb, + void *ourpointer) + { + /* do what you want with the data */ + } + } ~~~ # Proxies @@ -840,12 +839,12 @@ commands or even proper FTP directory listings. To tell libcurl to use a proxy at a given port number: ~~~c - curl_easy_setopt(handle, CURLOPT_PROXY, "proxy-host.com:8080"); + curl_easy_setopt(handle, CURLOPT_PROXY, "proxy-host.com:8080"); ~~~ Some proxies require user authentication before allowing a request, and you pass that information similar to this: ~~~c - curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, "user:password"); + curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, "user:password"); ~~~ If you want to, you can specify the hostname only in the CURLOPT_PROXY(3) option, and set the port number separately with @@ -854,7 +853,7 @@ CURLOPT_PROXYPORT(3). Tell libcurl what kind of proxy it is with CURLOPT_PROXYTYPE(3) (if not, it defaults to assuming an HTTP proxy): ~~~c - curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); + curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); ~~~ ## Environment Variables @@ -921,7 +920,7 @@ rarely allowed. Tell libcurl to use proxy tunneling like this: ~~~c - curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1L); + curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1L); ~~~ In fact, there might even be times when you want to do plain HTTP operations using a tunnel like this, as it then enables you to operate on the remote @@ -1031,7 +1030,7 @@ GET, HEAD or POST is not good enough for you, CURLOPT_CUSTOMREQUEST(3) is there for you. It is simple to use: ~~~c -curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST"); + curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST"); ~~~ When using the custom request, you change the request keyword of the actual @@ -1046,17 +1045,17 @@ request, and you are free to pass any amount of extra headers that you think fit. Adding headers is this easy: ~~~c -struct curl_slist *headers = NULL; /* init to NULL is important */ + struct curl_slist *headers = NULL; /* init to NULL is important */ -headers = curl_slist_append(headers, "Hey-server-hey: how are you?"); -headers = curl_slist_append(headers, "X-silly-content: yes"); + headers = curl_slist_append(headers, "Hey-server-hey: how are you?"); + headers = curl_slist_append(headers, "X-silly-content: yes"); -/* pass our list of custom made headers */ -curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + /* pass our list of custom made headers */ + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); -curl_easy_perform(handle); /* transfer http */ + curl_easy_perform(handle); /* transfer http */ -curl_slist_free_all(headers); /* free the header list */ + curl_slist_free_all(headers); /* free the header list */ ~~~ ... and if you think some of the internally generated headers, such as Accept: @@ -1064,8 +1063,8 @@ or Host: do not contain the data you want them to contain, you can replace them by simply setting them too: ~~~c -headers = curl_slist_append(headers, "Accept: Agent-007"); -headers = curl_slist_append(headers, "Host: munged.host.line"); + headers = curl_slist_append(headers, "Accept: Agent-007"); + headers = curl_slist_append(headers, "Host: munged.host.line"); ~~~ ## Delete Headers @@ -1075,7 +1074,9 @@ header from being sent. For instance, if you want to completely prevent the "Accept:" header from being sent, you can disable it with code similar to this: - headers = curl_slist_append(headers, "Accept:"); +~~~c + headers = curl_slist_append(headers, "Accept:"); +~~~ Both replacing and canceling internal headers should be done with careful consideration and you should be aware that you may violate the HTTP protocol @@ -1096,7 +1097,9 @@ we support. libcurl speaks HTTP 1.1 by default. Some old servers do not like getting 1.1-requests and when dealing with stubborn old things like that, you can tell libcurl to use 1.0 instead by doing something like this: - curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); +~~~c + curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); +~~~ ## FTP Custom Commands @@ -1116,14 +1119,14 @@ correct remote directory. A little example that deletes a given file before an operation: ~~~c - headers = curl_slist_append(headers, "DELE file-to-remove"); + headers = curl_slist_append(headers, "DELE file-to-remove"); - /* pass the list of custom commands to the handle */ - curl_easy_setopt(handle, CURLOPT_QUOTE, headers); + /* pass the list of custom commands to the handle */ + curl_easy_setopt(handle, CURLOPT_QUOTE, headers); - curl_easy_perform(handle); /* transfer ftp data! */ + curl_easy_perform(handle); /* transfer ftp data! */ - curl_slist_free_all(headers); /* free the header list */ + curl_slist_free_all(headers); /* free the header list */ ~~~ If you would instead want this operation (or chain of operations) to happen @@ -1171,7 +1174,7 @@ To just send whatever cookie you want to a server, you can use CURLOPT_COOKIE(3) to set a cookie string like this: ~~~c - curl_easy_setopt(handle, CURLOPT_COOKIE, "name1=var1; name2=var2;"); + curl_easy_setopt(handle, CURLOPT_COOKIE, "name1=var1; name2=var2;"); ~~~ In many cases, that is not enough. You might want to dynamically save whatever @@ -1271,43 +1274,43 @@ Here is an example building an email message with an inline plain/html text alternative and a file attachment encoded in base64: ~~~c - curl_mime *message = curl_mime_init(handle); - - /* The inline part is an alternative proposing the html and the text - versions of the email. */ - curl_mime *alt = curl_mime_init(handle); - - /* HTML message. */ - curl_mimepart *part = curl_mime_addpart(alt); - curl_mime_data(part, "

This is HTML

", - CURL_ZERO_TERMINATED); - curl_mime_type(part, "text/html"); - - /* Text message. */ - part = curl_mime_addpart(alt); - curl_mime_data(part, "This is plain text message", - CURL_ZERO_TERMINATED); - - /* Create the inline part. */ - part = curl_mime_addpart(message); - curl_mime_subparts(part, alt); - curl_mime_type(part, "multipart/alternative"); - struct curl_slist *headers = curl_slist_append(NULL, - "Content-Disposition: inline"); - curl_mime_headers(part, headers, TRUE); - - /* Add the attachment. */ - part = curl_mime_addpart(message); - curl_mime_filedata(part, "manual.pdf"); - curl_mime_encoder(part, "base64"); - - /* Build the mail headers. */ - headers = curl_slist_append(NULL, "From: me@example.com"); - headers = curl_slist_append(headers, "To: you@example.com"); - - /* Set these into the easy handle. */ - curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(handle, CURLOPT_MIMEPOST, mime); + curl_mime *message = curl_mime_init(handle); + + /* The inline part is an alternative proposing the html and the text + versions of the email. */ + curl_mime *alt = curl_mime_init(handle); + + /* HTML message. */ + curl_mimepart *part = curl_mime_addpart(alt); + curl_mime_data(part, "

This is HTML

", + CURL_ZERO_TERMINATED); + curl_mime_type(part, "text/html"); + + /* Text message. */ + part = curl_mime_addpart(alt); + curl_mime_data(part, "This is plain text message", + CURL_ZERO_TERMINATED); + + /* Create the inline part. */ + part = curl_mime_addpart(message); + curl_mime_subparts(part, alt); + curl_mime_type(part, "multipart/alternative"); + struct curl_slist *headers = curl_slist_append(NULL, + "Content-Disposition: inline"); + curl_mime_headers(part, headers, TRUE); + + /* Add the attachment. */ + part = curl_mime_addpart(message); + curl_mime_filedata(part, "manual.pdf"); + curl_mime_encoder(part, "base64"); + + /* Build the mail headers. */ + headers = curl_slist_append(NULL, "From: me@example.com"); + headers = curl_slist_append(headers, "To: you@example.com"); + + /* Set these into the easy handle. */ + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(handle, CURLOPT_MIMEPOST, mime); ~~~ It should be noted that appending a message to an IMAP directory requires @@ -1412,7 +1415,7 @@ to figure out success on each individual transfer. # SSL, Certificates and Other Tricks - [ seeding, passwords, keys, certificates, ENGINE, ca certs ] +[ seeding, passwords, keys, certificates, ENGINE, ca certs ] # Sharing Data Between Easy Handles diff --git a/docs/libcurl/opts/CURLINFO_COOKIELIST.md b/docs/libcurl/opts/CURLINFO_COOKIELIST.md index d3c4a6590e7d..7d0925500ded 100644 --- a/docs/libcurl/opts/CURLINFO_COOKIELIST.md +++ b/docs/libcurl/opts/CURLINFO_COOKIELIST.md @@ -34,8 +34,8 @@ curl_slist_free_all(3) on the list after it has been used. If there are no cookies (cookies for the handle have not been enabled or simply none have been received) the 'struct curl_slist *' is made a NULL pointer. -Since 7.43.0 cookies that were imported in the Set-Cookie format without a -domain name are not exported by this option. +Cookies that were imported in the Set-Cookie format without a domain name are +not exported by this option. # %PROTOCOLS% diff --git a/docs/libcurl/opts/CURLINFO_LASTSOCKET.md b/docs/libcurl/opts/CURLINFO_LASTSOCKET.md index 8aa80f9fc5e8..62bc425125cd 100644 --- a/docs/libcurl/opts/CURLINFO_LASTSOCKET.md +++ b/docs/libcurl/opts/CURLINFO_LASTSOCKET.md @@ -28,7 +28,7 @@ CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_LASTSOCKET, long *socket); # DESCRIPTION -Deprecated since 7.45.0. Use CURLINFO_ACTIVESOCKET(3) instead. +Deprecated. Use CURLINFO_ACTIVESOCKET(3) instead. Pass a pointer to a long to receive the last socket used by this curl session. If the socket is no longer valid, -1 is returned. When you finish @@ -74,6 +74,10 @@ int main(void) } ~~~ +# DEPRECATED + +Deprecated since 7.45.0. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLINFO_REDIRECT_URL.md b/docs/libcurl/opts/CURLINFO_REDIRECT_URL.md index 32ec6c3355d9..6d25a66e76f9 100644 --- a/docs/libcurl/opts/CURLINFO_REDIRECT_URL.md +++ b/docs/libcurl/opts/CURLINFO_REDIRECT_URL.md @@ -36,7 +36,7 @@ but you would still prefer to avoid implementing all the magic of figuring out the new URL. This URL is also set if the CURLOPT_MAXREDIRS(3) limit prevented a redirect to -happen (since 7.54.1). +happen. # %PROTOCOLS% diff --git a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.md b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.md index db1a41325bbe..75016a421ab1 100644 --- a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.md +++ b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.md @@ -68,8 +68,6 @@ the active ("in use") SSL connection, with the following underlying types: CURLINFO_TLS_SESSION(3): **SSL_CTX *** CURLINFO_TLS_SSL_PTR(3): **SSL *** -Since 7.48.0 the *internals* member can point to these other SSL backends -as well: ## mbedTLS @@ -161,6 +159,8 @@ int main(int argc, char **argv) This option supersedes CURLINFO_TLS_SESSION(3) which was added in 7.34.0. This option is exactly the same as that option except in the case of OpenSSL. +Non-OpenSSL support was added in 7.48.0. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.md b/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.md index 765e0de2323a..a3c1833bd19c 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.md +++ b/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.md @@ -38,10 +38,9 @@ curl_easy_getinfo(3) as the library can set up the connection and then the application can obtain the most recently used socket for special data transfers. -Since 7.86.0, this option can be set to '2' and if WebSocket is used, -libcurl performs the request and reads all response headers before handing -over control to the application. For other protocols the behavior of '2' -is undefined. +This option can be set to '2' and if WebSocket is used, libcurl performs the +request and reads all response headers before handing over control to the +application. For other protocols the behavior of '2' is undefined. Transfers marked connect only do not reuse any existing connections and connections marked connect only are not allowed to get reused. diff --git a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md index 6083662aac48..497a8fab8ba4 100644 --- a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md +++ b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.md @@ -40,10 +40,8 @@ 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. -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. +libcurl initializes the contents of the error buffer to an empty string before +performing a transfer. Do not attempt to set the contents of the buffer yourself, including in any callbacks you write that may be called by libcurl. The library may overwrite @@ -100,6 +98,11 @@ int main(void) } ~~~ +# HISTORY + +Before curl 7.60.0, if an error code was returned but there was no error +detail the buffer was untouched: not initialized. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.md b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.md index 0f529b25d67a..97e6ff6611ed 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.md +++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.md @@ -41,7 +41,7 @@ This option has no effect if PORT, EPRT or EPSV is used instead of PASV. # DEFAULT -1 since 7.74.0, was 0 before then. +1, enabled. # %PROTOCOLS% @@ -64,6 +64,10 @@ int main(void) } ~~~ +# HISTORY + +Before curl 7.74.0, this option was disabled by default. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_NOPROXY.md b/docs/libcurl/opts/CURLOPT_NOPROXY.md index 8c0b45edcd7f..5e8fdb1959be 100644 --- a/docs/libcurl/opts/CURLOPT_NOPROXY.md +++ b/docs/libcurl/opts/CURLOPT_NOPROXY.md @@ -43,10 +43,10 @@ brackets: "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" -out of the address to use in the comparison. For example "192.168.0.0/16" -would match all addresses starting with "192.168". +IP addresses specified to this option can be provided using CIDR notation: an +appended slash and number specifies the number of "network bits" out of the +address to use in the comparison. For example "192.168.0.0/16" would match all +addresses starting with "192.168". The application does not have to keep the string around after setting this option. @@ -84,6 +84,10 @@ int main(void) } ~~~ +# HISTORY + +CIDR format support was added in 7.86.0. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_POST.md b/docs/libcurl/opts/CURLOPT_POST.md index 1678b50e6bfb..4012e1f5eaf0 100644 --- a/docs/libcurl/opts/CURLOPT_POST.md +++ b/docs/libcurl/opts/CURLOPT_POST.md @@ -52,10 +52,10 @@ You can disable this header with CURLOPT_HTTPHEADER(3) as usual. If you use POST to an HTTP 1.1 server, you can send data without knowing the size before starting the POST if you use chunked encoding. You enable this by -adding a header like "Transfer-Encoding: chunked" with -CURLOPT_HTTPHEADER(3). With HTTP 1.0 or without chunked transfer, you -must specify the size in the request. (Since 7.66.0, libcurl automatically -uses chunked encoding for POSTs if the size is unknown.) +adding a header like "Transfer-Encoding: chunked" with CURLOPT_HTTPHEADER(3). +With HTTP 1.0 or without chunked transfer, you must specify the size in the +request. libcurl automatically uses chunked encoding for POSTs if the size is +unknown. When setting CURLOPT_POST(3) to 1, libcurl automatically sets CURLOPT_NOBODY(3) and CURLOPT_HTTPGET(3) to 0. diff --git a/docs/libcurl/opts/CURLOPT_PROXY.md b/docs/libcurl/opts/CURLOPT_PROXY.md index 2d9d456dba9f..dd42878debd1 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY.md +++ b/docs/libcurl/opts/CURLOPT_PROXY.md @@ -53,8 +53,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 mbedTLS, Rustls, Schannel and wolfSSL.) +HTTPS Proxy. (with OpenSSL, GnuTLS, mbedTLS, Rustls, Schannel or wolfSSL.) This uses HTTP/1 by default. Setting CURLOPT_PROXYTYPE(3) to **CURLPROXY_HTTPS2** allows libcurl to negotiate using HTTP/2 with proxy. @@ -154,6 +153,11 @@ Since 7.21.7 the proxy string supports the socks protocols as "schemes". Since 7.50.2, unsupported schemes in proxy strings cause libcurl to return error. +Since 7.52.0, it supports HTTPS proxy for OpenSSL. + +Since 7.87.0, it supports HTTPS proxy for GnuTLS, for mbedTLS, Rustls, +Schannel and wolfSSL. + # %AVAILABILITY% # RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md index fcafb3058831..b7340b00c208 100644 --- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md +++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md @@ -81,10 +81,7 @@ CURLPROTO_TFTP # DEFAULT -HTTP, HTTPS, FTP and FTPS (Added in 7.65.2). - -Older versions defaulted to all protocols except FILE, SCP and since 7.40.0 -SMB and SMBS. +HTTP, HTTPS, FTP and FTPS # %PROTOCOLS% diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md index c2d8db8bb2c9..2323829408cf 100644 --- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md +++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md @@ -64,10 +64,7 @@ option. # DEFAULT -HTTP, HTTPS, FTP and FTPS (Added in 7.65.2). - -Older versions defaulted to all protocols except FILE, SCP and since 7.40.0 -SMB and SMBS. +HTTP, HTTPS, FTP and FTPS # %PROTOCOLS% diff --git a/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.md b/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.md index b20a387b1205..c73bdcadf91b 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.md +++ b/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.md @@ -50,9 +50,9 @@ been created, but before the connect call to allow applications to change specific socket options. The callback's *purpose* argument identifies the exact purpose for this particular socket: -*CURLSOCKTYPE_IPCXN* for actively created connections or since 7.28.0 -*CURLSOCKTYPE_ACCEPT* for FTP when the connection was setup with PORT/EPSV -(in earlier versions these sockets were not passed to this callback). +*CURLSOCKTYPE_IPCXN* for actively created connections or *CURLSOCKTYPE_ACCEPT* +for FTP when the connection was setup with PORT/EPSV (in earlier versions +these sockets were not passed to this callback). Future versions of libcurl may support more purposes. libcurl passes the newly created socket descriptor to the callback in the *curlfd* parameter so diff --git a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.md b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.md index 673112cf3233..51ae347a2d45 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.md +++ b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.md @@ -27,7 +27,7 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SOCKS5_GSSAPI_SERVICE, # DESCRIPTION -Deprecated since 7.49.0. Use CURLOPT_PROXY_SERVICE_NAME(3) instead. +Deprecated. Use CURLOPT_PROXY_SERVICE_NAME(3) instead. Pass a char pointer as parameter to a string holding the *name* of the service. The default service name for a SOCKS5 server is *rcmd*. This option diff --git a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.md b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.md index 46b8c9dbb4e3..849791e9e3ee 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.md +++ b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.md @@ -28,7 +28,7 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_ENABLE_NPN, long npn); # DESCRIPTION -Deprecated since 7.86.0 Setting this option has no function. +Deprecated. Setting this option has no function. Pass a long as parameter, 0 or 1 where 1 is for enable and 0 for disable. This option enables/disables NPN in the SSL handshake (if the SSL backend libcurl diff --git a/docs/libcurl/opts/CURLOPT_URL.md b/docs/libcurl/opts/CURLOPT_URL.md index d167fa972eda..cc1f5366c9fa 100644 --- a/docs/libcurl/opts/CURLOPT_URL.md +++ b/docs/libcurl/opts/CURLOPT_URL.md @@ -33,23 +33,22 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_URL, char *URL); # DESCRIPTION -Pass in a pointer to the *URL* to work with. The parameter should be a -char * to a null-terminated string which must be URL-encoded in the following -format: +Pass in a pointer to the *URL* to work with. The parameter should be a char * +to a null-terminated string which must be URL-encoded in the following format: scheme://host:port/path For a greater explanation of the format please see RFC 3986. libcurl does not validate the syntax or use the URL until the transfer is -started. Even if you set a crazy value here, curl_easy_setopt(3) might -still return *CURLE_OK*. +started. Even if you set a crazy value here, curl_easy_setopt(3) might still +return *CURLE_OK*. If the given URL is missing a scheme name (such as "http://" or "ftp://" etc) then libcurl guesses based on the host. If the outermost subdomain name matches DICT, FTP, IMAP, LDAP, POP3 or SMTP then that protocol gets used, -otherwise HTTP is used. Since 7.45.0 guessing can be disabled by setting a -default protocol, see CURLOPT_DEFAULT_PROTOCOL(3) for details. +otherwise HTTP is used. Scheme guessing can be disabled by setting a default +protocol, see CURLOPT_DEFAULT_PROTOCOL(3) for details. Should the protocol, either as specified by the URL scheme or deduced by libcurl from the hostname, not be supported by libcurl then @@ -58,15 +57,15 @@ or curl_multi_perform(3) functions when you call them. Use curl_version_info(3) for detailed information of which protocols are supported by the build of libcurl you are using. -CURLOPT_PROTOCOLS_STR(3) can be used to limit what protocols libcurl may -use for this transfer, independent of what libcurl has been compiled to -support. That may be useful if you accept the URL from an external source and -want to limit the accessibility. +CURLOPT_PROTOCOLS_STR(3) can be used to limit what protocols libcurl may use +for this transfer, independent of what libcurl has been compiled to support. +That may be useful if you accept the URL from an external source and want to +limit the accessibility. The CURLOPT_URL(3) string is ignored if CURLOPT_CURLU(3) is set. -Either CURLOPT_URL(3) or CURLOPT_CURLU(3) must be set before a -transfer is started. +Either CURLOPT_URL(3) or CURLOPT_CURLU(3) must be set before a transfer is +started. The application does not have to keep the string around after setting this option. @@ -75,13 +74,13 @@ 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. +The parser used for handling the URL set with CURLOPT_URL(3) is the same that +curl_url_set(3) uses. # ENCODING -The string pointed to in the CURLOPT_URL(3) argument is generally -expected to be a sequence of characters using an ASCII compatible encoding. +The string pointed to in the CURLOPT_URL(3) argument is generally 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 diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 36befa325053..d5c55dff6e5b 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -23,43 +23,43 @@ ########################################################################### # Shared between CMakeLists.txt and Makefile.am -LIB_CURLX_CFILES = \ - curlx/base64.c \ - curlx/dynbuf.c \ - curlx/fopen.c \ - curlx/inet_ntop.c \ - curlx/inet_pton.c \ - curlx/multibyte.c \ - curlx/nonblock.c \ - curlx/strcopy.c \ - curlx/strerr.c \ - curlx/strparse.c \ - curlx/timediff.c \ - curlx/timeval.c \ +LIB_CURLX_CFILES = \ + curlx/base64.c \ + curlx/dynbuf.c \ + curlx/fopen.c \ + curlx/inet_ntop.c \ + curlx/inet_pton.c \ + curlx/multibyte.c \ + curlx/nonblock.c \ + curlx/strcopy.c \ + curlx/strerr.c \ + curlx/strparse.c \ + curlx/timediff.c \ + curlx/timeval.c \ curlx/version_win32.c \ - curlx/wait.c \ - curlx/warnless.c \ + curlx/wait.c \ + curlx/warnless.c \ curlx/winapi.c -LIB_CURLX_HFILES = \ - curlx/binmode.h \ - curlx/base64.h \ - curlx/curlx.h \ - curlx/dynbuf.h \ - curlx/fopen.h \ - curlx/inet_ntop.h \ - curlx/inet_pton.h \ - curlx/multibyte.h \ - curlx/nonblock.h \ - curlx/snprintf.h \ - curlx/strcopy.h \ - curlx/strerr.h \ - curlx/strparse.h \ - curlx/timediff.h \ - curlx/timeval.h \ +LIB_CURLX_HFILES = \ + curlx/binmode.h \ + curlx/base64.h \ + curlx/curlx.h \ + curlx/dynbuf.h \ + curlx/fopen.h \ + curlx/inet_ntop.h \ + curlx/inet_pton.h \ + curlx/multibyte.h \ + curlx/nonblock.h \ + curlx/snprintf.h \ + curlx/strcopy.h \ + curlx/strerr.h \ + curlx/strparse.h \ + curlx/timediff.h \ + curlx/timeval.h \ curlx/version_win32.h \ - curlx/wait.h \ - curlx/warnless.h \ + curlx/wait.h \ + curlx/warnless.h \ curlx/winapi.h LIB_VAUTH_CFILES = \ @@ -116,22 +116,22 @@ LIB_VTLS_HFILES = \ vtls/wolfssl.h \ vtls/x509asn1.h -LIB_VQUIC_CFILES = \ +LIB_VQUIC_CFILES = \ vquic/curl_ngtcp2.c \ vquic/curl_quiche.c \ - vquic/vquic.c \ + vquic/vquic.c \ vquic/vquic-tls.c -LIB_VQUIC_HFILES = \ +LIB_VQUIC_HFILES = \ vquic/curl_ngtcp2.h \ vquic/curl_quiche.h \ - vquic/vquic.h \ - vquic/vquic_int.h \ + vquic/vquic.h \ + vquic/vquic_int.h \ vquic/vquic-tls.h -LIB_VSSH_CFILES = \ - vssh/libssh.c \ - vssh/libssh2.c \ +LIB_VSSH_CFILES = \ + vssh/libssh.c \ + vssh/libssh2.c \ vssh/vssh.c LIB_VSSH_HFILES = \ diff --git a/lib/curl_config-cmake.h.in b/lib/curl_config-cmake.h.in index 1f5d9399e3a0..74d9d714da48 100644 --- a/lib/curl_config-cmake.h.in +++ b/lib/curl_config-cmake.h.in @@ -626,12 +626,12 @@ #cmakedefine CURL_OS ${CURL_OS} /* - Note: SIZEOF_* variables are fetched with CMake through check_type_size(). - As per CMake documentation on CheckTypeSize, C preprocessor code is - generated by CMake into SIZEOF_*_CODE. This is what we use in the - following statements. + Note: SIZEOF_* variables are fetched with CMake through check_type_size(). + As per CMake documentation on CheckTypeSize, C preprocessor code is + generated by CMake into SIZEOF_*_CODE. This is what we use in the + following statements. - Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html + Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html */ /* The size of `int', as computed by sizeof. */ diff --git a/lib/curlx/inet_pton.c b/lib/curlx/inet_pton.c index 448f1357c6e9..1767bf19af71 100644 --- a/lib/curlx/inet_pton.c +++ b/lib/curlx/inet_pton.c @@ -53,8 +53,7 @@ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -/* int - * inet_pton4(src, dst) +/* int inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. @@ -102,8 +101,7 @@ static int inet_pton4(const char *src, unsigned char *dst) return 1; } -/* int - * inet_pton6(src, dst) +/* int inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. @@ -192,8 +190,7 @@ static int inet_pton6(const char *src, unsigned char *dst) return 1; } -/* int - * inet_pton(af, src, dst) +/* int inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: diff --git a/lib/md4.c b/lib/md4.c index d2a905828954..845cdb6d7ed1 100644 --- a/lib/md4.c +++ b/lib/md4.c @@ -170,7 +170,7 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx) * MD4 Message-Digest Algorithm (RFC 1320). * * Homepage: - https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 + * https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 * * Author: * Alexander Peslyak, better known as Solar Designer @@ -179,8 +179,8 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx) * claimed, and the software is hereby placed in the public domain. In case * this attempt to disclaim copyright and place the software in the public * domain is deemed null and void, then the software is Copyright (c) 2001 - * Alexander Peslyak and it is hereby released to the general public under the - * following terms: + * Alexander Peslyak and it is hereby released to the general public under + * the following terms: * * Redistribution and use in source and binary forms, with or without * modification, are permitted. diff --git a/lib/md5.c b/lib/md5.c index f8b100d83dcf..1c5595ee19c5 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -256,17 +256,17 @@ static void my_md5_final(unsigned char *digest, void *in) * MD5 Message-Digest Algorithm (RFC 1321). * * Homepage: - https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 * * Author: * Alexander Peslyak, better known as Solar Designer * * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: + * claimed, and the software is hereby placed in the public domain. In case + * this attempt to disclaim copyright and place the software in the public + * domain is deemed null and void, then the software is Copyright (c) 2001 + * Alexander Peslyak and it is hereby released to the general public under + * the following terms: * * Redistribution and use in source and binary forms, with or without * modification, are permitted. diff --git a/lib/mprintf.c b/lib/mprintf.c index 34c3155d4e8a..8f81f033dcb0 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -673,16 +673,19 @@ static bool out_double(void *userp, *fptr = 0; /* and a final null-termination */ -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" -#endif /* NOTE NOTE NOTE!! Not all sprintf implementations return number of output characters */ #ifdef HAVE_SNPRINTF +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif /* !checksrc! disable LONGLINE */ /* NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) */ (snprintf)(work, BUFFSIZE, formatbuf, dnum); +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif #ifdef _WIN32 /* Old versions of the Windows CRT do not terminate the snprintf output buffer if it reaches the max size so we do that here. */ @@ -691,9 +694,6 @@ static bool out_double(void *userp, #else /* float and double outputs do not work without snprintf support */ work[0] = 0; -#endif -#ifdef __clang__ -#pragma clang diagnostic pop #endif DEBUGASSERT(strlen(work) < BUFFSIZE); while(*work) { diff --git a/lib/rtsp.c b/lib/rtsp.c index a36ea1cac46e..69bfb81c06b7 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -23,6 +23,7 @@ ***************************************************************************/ #include "curl_setup.h" #include "urldata.h" +#include "rtsp.h" #ifndef CURL_DISABLE_RTSP @@ -33,7 +34,6 @@ #include "http.h" #include "url.h" #include "progress.h" -#include "rtsp.h" #include "strcase.h" #include "select.h" #include "connect.h" diff --git a/lib/setopt.c b/lib/setopt.c index 713a6d2d7cd3..2fc90c25ec8e 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -1867,7 +1867,9 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set CRL file info for SSL connection. Specify filename of the CRL * to check certificates revocation */ - return Curl_setstropt(&s->str[STRING_SSL_CRLFILE], ptr); + if(Curl_ssl_supports(data, SSLSUPP_CRLFILE)) + return Curl_setstropt(&s->str[STRING_SSL_CRLFILE], ptr); + return CURLE_NOT_BUILT_IN; case CURLOPT_SSL_CIPHER_LIST: if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) /* set a list of cipher we want to use in the SSL connection */ @@ -2265,7 +2267,9 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set Issuer certificate file * to check certificates issuer */ - return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT], ptr); + if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT)) + return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT], ptr); + return CURLE_NOT_BUILT_IN; case CURLOPT_PRIVATE: /* * Set private data pointer. @@ -2278,7 +2282,9 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Set accepted curves in SSL connection setup. * Specify colon-delimited list of curve algorithm names. */ - return Curl_setstropt(&s->str[STRING_SSL_EC_CURVES], ptr); + if(Curl_ssl_supports(data, SSLSUPP_SSL_EC_CURVES)) + return Curl_setstropt(&s->str[STRING_SSL_EC_CURVES], ptr); + return CURLE_NOT_BUILT_IN; case CURLOPT_SSL_SIGNATURE_ALGORITHMS: /* * Set accepted signature algorithms. @@ -2885,7 +2891,9 @@ static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, /* * Blob that holds Issuer certificate to check certificates issuer */ - return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT], blob); + if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT_BLOB)) + return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT], blob); + return CURLE_NOT_BUILT_IN; default: return CURLE_UNKNOWN_OPTION; diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index ae9e0e82b758..a1a56f5c6ae9 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -2296,7 +2296,9 @@ const struct Curl_ssl Curl_ssl_gnutls = { SSLSUPP_HTTPS_PROXY | SSLSUPP_CAINFO_BLOB | SSLSUPP_CIPHER_LIST | - SSLSUPP_CA_CACHE, + SSLSUPP_CA_CACHE | + SSLSUPP_ISSUERCERT | + SSLSUPP_CRLFILE, sizeof(struct gtls_ssl_backend_data), diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 43ac96897768..c6a014478e68 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -1526,7 +1526,11 @@ const struct Curl_ssl Curl_ssl_mbedtls = { SSLSUPP_TLS13_CIPHERSUITES | #endif SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST, + SSLSUPP_CIPHER_LIST | +#ifdef MBEDTLS_X509_CRL_PARSE_C + SSLSUPP_CRLFILE | +#endif + 0, sizeof(struct mbed_ssl_backend_data), diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index bab1b9a3a1f6..09dfe17db500 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -1022,8 +1022,8 @@ static int enginecheck(struct Curl_easy *data, SSL_CTX* ctx, const char *key_file, const char *key_passwd) -#ifdef USE_OPENSSL_ENGINE { +#ifdef USE_OPENSSL_ENGINE EVP_PKEY *priv_key = NULL; /* Implicitly use pkcs11 engine if none was provided and the @@ -1066,22 +1066,20 @@ static int enginecheck(struct Curl_easy *data, return 0; } return 1; -} #else -{ (void)ctx; (void)key_file; (void)key_passwd; failf(data, "SSL_FILETYPE_ENGINE not supported for private key"); return 0; -} #endif +} static int providercheck(struct Curl_easy *data, SSL_CTX* ctx, const char *key_file) -#ifdef OPENSSL_HAS_PROVIDERS { +#ifdef OPENSSL_HAS_PROVIDERS char error_buffer[256]; /* Implicitly use pkcs11 provider if none was provided and the * key_file is a PKCS#11 URI */ @@ -1155,22 +1153,20 @@ static int providercheck(struct Curl_easy *data, return 0; } return 1; -} #else -{ (void)ctx; (void)key_file; failf(data, "SSL_FILETYPE_PROVIDER not supported for private key"); return 0; -} #endif +} static int engineload(struct Curl_easy *data, SSL_CTX* ctx, const char *cert_file) +{ /* ENGINE_CTRL_GET_CMD_FROM_NAME supported by OpenSSL, LibreSSL <=3.8.3 */ #if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) -{ char error_buffer[256]; /* Implicitly use pkcs11 engine if none was provided and the * cert_file is a PKCS#11 URI */ @@ -1228,21 +1224,19 @@ static int engineload(struct Curl_easy *data, return 0; } return 1; -} #else -{ (void)ctx; (void)cert_file; failf(data, "SSL_FILETYPE_ENGINE not supported for certificate"); return 0; -} #endif +} static int providerload(struct Curl_easy *data, SSL_CTX* ctx, const char *cert_file) -#ifdef OPENSSL_HAS_PROVIDERS { +#ifdef OPENSSL_HAS_PROVIDERS char error_buffer[256]; /* Implicitly use pkcs11 provider if none was provided and the * cert_file is a PKCS#11 URI */ @@ -1306,15 +1300,13 @@ static int providerload(struct Curl_easy *data, return 0; } return 1; -} #else -{ (void)ctx; (void)cert_file; failf(data, "SSL_FILETYPE_PROVIDER not supported for certificate"); return 0; -} #endif +} static int pkcs12load(struct Curl_easy *data, SSL_CTX* ctx, @@ -5415,7 +5407,11 @@ const struct Curl_ssl Curl_ssl_openssl = { #endif SSLSUPP_CA_CACHE | SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST, + SSLSUPP_CIPHER_LIST | + SSLSUPP_ISSUERCERT | + SSLSUPP_ISSUERCERT_BLOB | + SSLSUPP_SSL_EC_CURVES | + SSLSUPP_CRLFILE, sizeof(struct ossl_ctx), diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index b7793ebdb7a7..552f153b6535 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -1399,7 +1399,8 @@ const struct Curl_ssl Curl_ssl_rustls = { SSLSUPP_CIPHER_LIST | SSLSUPP_TLS13_CIPHERSUITES | SSLSUPP_CERTINFO | - SSLSUPP_ECH, + SSLSUPP_ECH | + SSLSUPP_CRLFILE, sizeof(struct rustls_ssl_backend_data), NULL, /* init */ diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index 273c6cce3fee..bf19572fc625 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -43,6 +43,10 @@ struct dynbuf; #define SSLSUPP_CA_CACHE (1 << 8) #define SSLSUPP_CIPHER_LIST (1 << 9) /* supports TLS 1.0-1.2 ciphersuites */ #define SSLSUPP_SIGNATURE_ALGORITHMS (1 << 10) /* supports TLS sigalgs */ +#define SSLSUPP_ISSUERCERT (1 << 11) /* supports CURLOPT_ISSUERCERT */ +#define SSLSUPP_SSL_EC_CURVES (1 << 12) /* supports CURLOPT_SSL_EC_CURVES */ +#define SSLSUPP_CRLFILE (1 << 13) /* supports CURLOPT_CRLFILE */ +#define SSLSUPP_ISSUERCERT_BLOB (1 << 14) /* CURLOPT_ISSUERCERT_BLOB */ #ifdef USE_ECH # include "../curlx/base64.h" diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 5f9baed35861..b820ee06cf83 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -2283,7 +2283,8 @@ const struct Curl_ssl Curl_ssl_wolfssl = { SSLSUPP_TLS13_CIPHERSUITES | #endif SSLSUPP_CA_CACHE | - SSLSUPP_CIPHER_LIST, + SSLSUPP_CIPHER_LIST | + SSLSUPP_SSL_EC_CURVES, sizeof(struct wssl_ctx), diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4 index ff43f67f9914..43e6549094f6 100644 --- a/m4/curl-compilers.m4 +++ b/m4/curl-compilers.m4 @@ -812,7 +812,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare]) tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef]) - tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [declaration-after-statement]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align]) @@ -1028,11 +1027,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef]) fi # - dnl Only gcc 2.97 or later - if test "$compiler_num" -ge "297"; then - tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral" - fi - # dnl Only gcc 3.0 or later if test "$compiler_num" -ge "300"; then dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on diff --git a/projects/vms/readme b/projects/vms/readme index 372b219fc86b..661dc9b471d3 100644 --- a/projects/vms/readme +++ b/projects/vms/readme @@ -7,7 +7,7 @@ History: - 9-MAR-2004, Created this readme. file. Marty Kuhrt (MSK). +09-MAR-2004, Created this readme. file. Marty Kuhrt (MSK). 15-MAR-2004, MSK, Updated to reflect the new files in this directory. 14-FEB-2005, MSK, removed config-vms.h_with* file comments 10-FEB-2010, SMS. General update. diff --git a/src/config2setopts.c b/src/config2setopts.c index 5e1722c3eed7..a023287834cd 100644 --- a/src/config2setopts.c +++ b/src/config2setopts.c @@ -486,12 +486,14 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) /* only called for HTTP transfers */ static CURLcode http_setopts(struct OperationConfig *config, CURL *curl) { - CURLcode result; + CURLcode result = CURLE_OK; long postRedir = 0; my_setopt_long(curl, CURLOPT_FOLLOWLOCATION, config->followlocation); my_setopt_long(curl, CURLOPT_UNRESTRICTED_AUTH, config->unrestricted_auth); +#ifndef CURL_DISABLE_AWS MY_SETOPT_STR(curl, CURLOPT_AWS_SIGV4, config->aws_sigv4); +#endif my_setopt_long(curl, CURLOPT_AUTOREFERER, config->autoreferer); if(config->proxyheaders) { diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 5074ab67b469..375daad9fa99 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -207,13 +207,13 @@ int tool_progress_cb(void *clientp, memset(line, '#', num); line[num] = '\0'; curl_msnprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth); -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif curl_mfprintf(bar->out, format, line, percent); -#ifdef __clang__ -#pragma clang diagnostic pop +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop #endif } fflush(bar->out); diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 54b209869dbc..a66f04479997 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -381,10 +381,9 @@ static const struct LongShort aliases[]= { * * Unit test 1394 */ -UNITTEST -ParameterError parse_cert_parameter(const char *cert_parameter, - char **certname, - char **passphrase) +UNITTEST ParameterError parse_cert_parameter(const char *cert_parameter, + char **certname, + char **passphrase) { size_t param_length = strlen(cert_parameter); size_t span; @@ -3059,8 +3058,7 @@ ParameterError parse_args(int argc, argv_item_t argv[]) ParameterError result = PARAM_OK; struct OperationConfig *config = global->first; - stillflags = TRUE; - for(i = 1; i < argc && !result; i++) { + for(i = 1, stillflags = TRUE; i < argc && !result; i++) { orig_opt = convert_tchar_to_UTF8(argv[i]); if(!orig_opt) return PARAM_NO_MEM; diff --git a/src/tool_getparam.h b/src/tool_getparam.h index 0ff0a78182d8..4d345413931d 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -372,9 +372,9 @@ ParameterError getparameter(const char *flag, const char *nextarg, int max_recursive); #ifdef UNITTESTS -ParameterError parse_cert_parameter(const char *cert_parameter, - char **certname, - char **passphrase); +UNITTEST ParameterError parse_cert_parameter(const char *cert_parameter, + char **certname, + char **passphrase); UNITTEST ParameterError GetSizeParameter(const char *arg, curl_off_t *out); #endif diff --git a/src/tool_writeout.c b/src/tool_writeout.c index 2ade080a1813..f4de98a2077c 100644 --- a/src/tool_writeout.c +++ b/src/tool_writeout.c @@ -579,9 +579,16 @@ static const char *outtime(const char *ptr, /* %time{ ... */ if(!result) { struct tm utc; result = curlx_gmtime(secs, &utc); +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif if(curlx_dyn_len(&format) && !result && strftime(output, sizeof(output), curlx_dyn_ptr(&format), &utc)) fputs(output, stream); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif curlx_dyn_free(&format); } ptr = end + 1; diff --git a/tests/data/test1525 b/tests/data/test1525 index 30788adefe97..c090feb5d3bb 100644 --- a/tests/data/test1525 +++ b/tests/data/test1525 @@ -50,7 +50,7 @@ lib%TESTNUMBER CURLOPT_PROXYHEADER is ignored CURLHEADER_UNIFIED - http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT +http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT proxy diff --git a/tests/data/test1526 b/tests/data/test1526 index e86486ae99e0..6c78989fa36d 100644 --- a/tests/data/test1526 +++ b/tests/data/test1526 @@ -52,7 +52,7 @@ lib%TESTNUMBER CURLOPT_PROXYHEADER: separate host/proxy headers - http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT +http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT proxy diff --git a/tests/data/test1527 b/tests/data/test1527 index 547133044961..731aea2ac91e 100644 --- a/tests/data/test1527 +++ b/tests/data/test1527 @@ -51,7 +51,7 @@ lib%TESTNUMBER Same headers with CURLOPT_HEADEROPT == CURLHEADER_UNIFIED - http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT +http://the.old.moo.%TESTNUMBER:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT proxy diff --git a/tests/data/test1528 b/tests/data/test1528 index 0fc0356c5771..a2994988bd28 100644 --- a/tests/data/test1528 +++ b/tests/data/test1528 @@ -42,7 +42,7 @@ lib%TESTNUMBER Separately specified proxy/server headers sent in a proxy GET - http://the.old.moo:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT +http://the.old.moo:%HTTPPORT/%TESTNUMBER %HOSTIP:%PROXYPORT proxy diff --git a/tests/data/test1529 b/tests/data/test1529 index fc545f5accd2..f31f70fb4491 100644 --- a/tests/data/test1529 +++ b/tests/data/test1529 @@ -30,7 +30,7 @@ lib%TESTNUMBER HTTP request-injection in URL sent over proxy - "http://the.old.moo:%HTTPPORT/%TESTNUMBER" %HOSTIP:%PROXYPORT +"http://the.old.moo:%HTTPPORT/%TESTNUMBER" %HOSTIP:%PROXYPORT proxy diff --git a/tests/data/test2027 b/tests/data/test2027 index bdc21bd5a12c..2a5fa6e3db15 100644 --- a/tests/data/test2027 +++ b/tests/data/test2027 @@ -12,12 +12,12 @@ HTTP Digest auth diff --git a/tests/data/test2030 b/tests/data/test2030 index 1297515a9b94..dae4c3e15a80 100644 --- a/tests/data/test2030 +++ b/tests/data/test2030 @@ -17,12 +17,12 @@ ensure that the order does not matter. --> diff --git a/tests/data/test3206 b/tests/data/test3206 index 8665e6207fc0..5fed82a07cc6 100644 --- a/tests/data/test3206 +++ b/tests/data/test3206 @@ -30,7 +30,7 @@ IMAP custom FETCH with larger literal response (~7KB) # The quoted string contains {50} which must not be parsed as a literal - imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/ -u user:secret -X 'FETCH 456 ("fake {50}" BODY[TEXT])' +imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/ -u user:secret -X 'FETCH 456 ("fake {50}" BODY[TEXT])' diff --git a/tests/data/test379 b/tests/data/test379 index 310bf520ea25..9405639d7e11 100644 --- a/tests/data/test379 +++ b/tests/data/test379 @@ -36,7 +36,7 @@ http --remove-on-error with --no-clobber and an added number - + http://%HOSTIP:%HTTPPORT/%TESTNUMBER -o %LOGDIR/save --remove-on-error --no-clobber diff --git a/tests/data/test841 b/tests/data/test841 index 002a9f429875..71d8fed29956 100644 --- a/tests/data/test841 +++ b/tests/data/test841 @@ -37,7 +37,7 @@ imap IMAP custom request does not check continuation data - imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/ -u user:secret -X 'FETCH 123 BODY[1]' +imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/ -u user:secret -X 'FETCH 123 BODY[1]' diff --git a/tests/server/util.c b/tests/server/util.c index e1cc138d184e..da959f3ed992 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -111,7 +111,15 @@ void logmsg(const char *msg, ...) now.tm_hour, now.tm_min, now.tm_sec, (long)tv.tv_usec); va_start(ap, msg); +/* Suppress for builds where CURL_PRINTF() is not set */ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif vsnprintf(buffer, sizeof(buffer), msg, ap); +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif va_end(ap); do { diff --git a/tests/tunit/tool1622.c b/tests/tunit/tool1622.c index e33ba5dbea45..fd380ed60c96 100644 --- a/tests/tunit/tool1622.c +++ b/tests/tunit/tool1622.c @@ -28,48 +28,48 @@ static CURLcode test_tool1622(const char *arg) { UNITTEST_BEGIN_SIMPLE - { - char buffer[9]; - curl_off_t secs; - int i; - static const curl_off_t check[] = { - /* bytes to check */ - 131072, - 12645826, - 1073741824, - 12938588979, - 1099445657078333, - 0 /* end of list */ - }; - puts("time2str"); - for(i = 0, secs = 0; i < 63; i++) { - time2str(buffer, sizeof(buffer), secs); - curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); - if(strlen(buffer) != 8) { - curl_mprintf("^^ was too long!\n"); - } - secs *= 2; - secs++; + char buffer[9]; + curl_off_t secs; + int i; + static const curl_off_t check[] = { + /* bytes to check */ + 131072, + 12645826, + 1073741824, + 12938588979, + 1099445657078333, + 0 /* end of list */ + }; + + puts("time2str"); + for(i = 0, secs = 0; i < 63; i++) { + time2str(buffer, sizeof(buffer), secs); + curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); + if(strlen(buffer) != 8) { + curl_mprintf("^^ was too long!\n"); } - puts("max5data"); - for(i = 0, secs = 0; i < 63; i++) { - max5data(secs, buffer, sizeof(buffer)); - curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); - if(strlen(buffer) != 5) { - curl_mprintf("^^ was too long!\n"); - } - secs *= 2; - secs++; + secs *= 2; + secs++; + } + puts("max5data"); + for(i = 0, secs = 0; i < 63; i++) { + max5data(secs, buffer, sizeof(buffer)); + curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); + if(strlen(buffer) != 5) { + curl_mprintf("^^ was too long!\n"); } - for(i = 0; check[i]; i++) { - secs = check[i]; - max5data(secs, buffer, sizeof(buffer)); - curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); - if(strlen(buffer) != 5) { - curl_mprintf("^^ was too long!\n"); - } + secs *= 2; + secs++; + } + for(i = 0; check[i]; i++) { + secs = check[i]; + max5data(secs, buffer, sizeof(buffer)); + curl_mprintf("%20" FMT_OFF_T " - %s\n", secs, buffer); + if(strlen(buffer) != 5) { + curl_mprintf("^^ was too long!\n"); } } + UNITTEST_END_SIMPLE } diff --git a/tests/tunit/tool1623.c b/tests/tunit/tool1623.c index 9fcc0b49cf7e..2d94c8cebbcc 100644 --- a/tests/tunit/tool1623.c +++ b/tests/tunit/tool1623.c @@ -34,94 +34,93 @@ struct check1623 { static CURLcode test_tool1623(const char *arg) { UNITTEST_BEGIN_SIMPLE - { - int i; - static const struct check1623 check[] = { - { "0", 0, PARAM_OK}, - { "00", 0, PARAM_OK}, - { "000", 0, PARAM_OK}, - { "1", 1, PARAM_OK}, - { "1b", 1, PARAM_OK}, - { "99B", 99, PARAM_OK}, - { "2", 2, PARAM_OK}, - { "3", 3, PARAM_OK}, - { "4", 4, PARAM_OK}, - { "5", 5, PARAM_OK}, - { "6", 6, PARAM_OK}, - { "7", 7, PARAM_OK}, - { "77", 77, PARAM_OK}, - { "8", 8, PARAM_OK}, - { "9", 9, PARAM_OK}, - { "10", 10, PARAM_OK}, - { "010", 10, PARAM_OK}, - { "000000000000000000000000000000000010", 10, PARAM_OK}, - { "1k", 1024, PARAM_OK}, - { "2K", 2048, PARAM_OK}, - { "3k", 3072, PARAM_OK}, - { "4K", 4096, PARAM_OK}, - { "5k", 5120, PARAM_OK}, - { "6K", 6144, PARAM_OK}, - { "7k", 7168, PARAM_OK}, - { "8K", 8192, PARAM_OK}, - { "9k", 9216, PARAM_OK}, - { "10K", 10240, PARAM_OK}, - { "20M", 20971520, PARAM_OK}, - { "30G", 32212254720, PARAM_OK}, - { "40T", 43980465111040, PARAM_OK}, - { "50P", 56294995342131200, PARAM_OK}, - { "1.1k", 1126, PARAM_OK}, - { "1.01k", 1034, PARAM_OK}, - { "1.001k", 1025, PARAM_OK}, - { "1.0001k", 1024, PARAM_OK}, - { "22.1m", 23173529, PARAM_OK}, - { "22.01m", 23079157, PARAM_OK}, - { "22.001m", 23069720, PARAM_OK}, - { "22.0001m", 23068776, PARAM_OK}, - { "22.00001m", 23068682, PARAM_OK}, - { "22.000001m", 23068673, PARAM_OK}, - { "22.0000001m", 23068672, PARAM_OK}, - { "22.000000001m", 23068672, PARAM_OK}, - { "3.4", 0, PARAM_BAD_USE}, - { "3.14b", 0, PARAM_BAD_USE}, - { "5000.9P", 5630512844129278361, PARAM_OK}, - { "5000.99P", 5630614175120894197, PARAM_OK}, - { "5000.999P", 5630624308220055781, PARAM_OK}, - { "5000.9999P", 5630625321529969316, PARAM_OK}, - { "8191P", 9222246136947933184, PARAM_OK}, - { "8191.9999999P", 9223372036735343194, PARAM_OK}, - { "8192P", 0, PARAM_NUMBER_TOO_LARGE}, - { "9223372036854775807", 9223372036854775807, PARAM_OK}, - { "9223372036854775808", 0, PARAM_NUMBER_TOO_LARGE}, - { "a", 0, PARAM_BAD_NUMERIC}, - { "-2", 0, PARAM_BAD_NUMERIC}, - { "+2", 0, PARAM_BAD_NUMERIC}, - { "2,2k", 0, PARAM_BAD_USE}, - { NULL, 0, PARAM_OK } /* end of list */ - }; - for(i = 0; check[i].input; i++) { - bool ok = FALSE; - curl_off_t output = 0; - ParameterError err = - GetSizeParameter(check[i].input, &output); - if(err != check[i].err) - curl_mprintf("'%s' unexpectedly returned %d \n", - check[i].input, err); - else if(check[i].amount != output) - curl_mprintf("'%s' unexpectedly gave %" FMT_OFF_T "\n", - check[i].input, output); - else { + int i; + static const struct check1623 check[] = { + { "0", 0, PARAM_OK }, + { "00", 0, PARAM_OK }, + { "000", 0, PARAM_OK }, + { "1", 1, PARAM_OK }, + { "1b", 1, PARAM_OK }, + { "99B", 99, PARAM_OK }, + { "2", 2, PARAM_OK }, + { "3", 3, PARAM_OK }, + { "4", 4, PARAM_OK }, + { "5", 5, PARAM_OK }, + { "6", 6, PARAM_OK }, + { "7", 7, PARAM_OK }, + { "77", 77, PARAM_OK }, + { "8", 8, PARAM_OK }, + { "9", 9, PARAM_OK }, + { "10", 10, PARAM_OK }, + { "010", 10, PARAM_OK }, + { "000000000000000000000000000000000010", 10, PARAM_OK }, + { "1k", 1024, PARAM_OK }, + { "2K", 2048, PARAM_OK }, + { "3k", 3072, PARAM_OK }, + { "4K", 4096, PARAM_OK }, + { "5k", 5120, PARAM_OK }, + { "6K", 6144, PARAM_OK }, + { "7k", 7168, PARAM_OK }, + { "8K", 8192, PARAM_OK }, + { "9k", 9216, PARAM_OK }, + { "10K", 10240, PARAM_OK }, + { "20M", 20971520, PARAM_OK }, + { "30G", 32212254720, PARAM_OK }, + { "40T", 43980465111040, PARAM_OK }, + { "50P", 56294995342131200, PARAM_OK }, + { "1.1k", 1126, PARAM_OK }, + { "1.01k", 1034, PARAM_OK }, + { "1.001k", 1025, PARAM_OK }, + { "1.0001k", 1024, PARAM_OK }, + { "22.1m", 23173529, PARAM_OK }, + { "22.01m", 23079157, PARAM_OK }, + { "22.001m", 23069720, PARAM_OK }, + { "22.0001m", 23068776, PARAM_OK }, + { "22.00001m", 23068682, PARAM_OK }, + { "22.000001m", 23068673, PARAM_OK }, + { "22.0000001m", 23068672, PARAM_OK }, + { "22.000000001m", 23068672, PARAM_OK }, + { "3.4", 0, PARAM_BAD_USE }, + { "3.14b", 0, PARAM_BAD_USE }, + { "5000.9P", 5630512844129278361, PARAM_OK }, + { "5000.99P", 5630614175120894197, PARAM_OK }, + { "5000.999P", 5630624308220055781, PARAM_OK }, + { "5000.9999P", 5630625321529969316, PARAM_OK }, + { "8191P", 9222246136947933184, PARAM_OK }, + { "8191.9999999P", 9223372036735343194, PARAM_OK }, + { "8192P", 0, PARAM_NUMBER_TOO_LARGE }, + { "9223372036854775807", 9223372036854775807, PARAM_OK }, + { "9223372036854775808", 0, PARAM_NUMBER_TOO_LARGE }, + { "a", 0, PARAM_BAD_NUMERIC }, + { "-2", 0, PARAM_BAD_NUMERIC }, + { "+2", 0, PARAM_BAD_NUMERIC }, + { "2,2k", 0, PARAM_BAD_USE }, + { NULL, 0, PARAM_OK } /* end of list */ + }; + + for(i = 0; check[i].input; i++) { + bool ok = FALSE; + curl_off_t output = 0; + ParameterError err = GetSizeParameter(check[i].input, &output); + if(err != check[i].err) + curl_mprintf("'%s' unexpectedly returned %d \n", + check[i].input, err); + else if(check[i].amount != output) + curl_mprintf("'%s' unexpectedly gave %" FMT_OFF_T "\n", + check[i].input, output); + else { #if 0 /* enable for debugging */ - if(err) - curl_mprintf("'%s' returned %d\n", check[i].input, err); - else - curl_mprintf("'%s' == %" FMT_OFF_T "\n", check[i].input, output); + if(err) + curl_mprintf("'%s' returned %d\n", check[i].input, err); + else + curl_mprintf("'%s' == %" FMT_OFF_T "\n", check[i].input, output); #endif - ok = TRUE; - } - if(!ok) - unitfail++; + ok = TRUE; } + if(!ok) + unitfail++; } + UNITTEST_END_SIMPLE }