Compare commits

..

553 Commits

Author SHA1 Message Date
yhirose fc9b223acc Updated copyright year 2021-06-11 14:45:35 -04:00
CncGpp ba824089d7 Fix code err code 401 when the password is empty in base_auth. (#958) 2021-06-11 14:39:33 -04:00
Andrea Pappacoda 1a2faf09e0 Add header-only Meson support (#955)
* Add header-only Meson support
This allows users to call `dependency('httplib')` and have the include
directory automatically configured

* Rename `httplib` to `cpp-httplib`
2021-06-05 16:45:00 -04:00
yhirose 5a43bb8149 Implemented #946 in a different way 2021-06-02 13:45:47 -04:00
yhirose 0104614656 Code refactoring 2021-06-02 08:11:31 -04:00
yhirose 77a77f6d2d Added set_default_headers on Server 2021-05-23 19:06:28 -04:00
Mathias Laurin 089b9daa1c Fix virtual call in ClientImpl::~ClientImpl() (#942)
* Fix virtual call in ClientImpl::~ClientImpl()

This fixes a warning in clang tidy:

> Call to virtual method 'ClientImpl::shutdown_ssl' during
> destruction bypasses virtual dispatch

ClientImpl::~ClientImpl() calls lock_socket_and_shutdown_and_close()
that itself calls shutdown_ssl().  However, shutdown_ssl() is virtual
and C++ does not perform virtual dispatch in destructors, which results
in the wrong overload being called.

This change adds a non-virtual shutdown_ssl_impl() function that is
called from ~SSLClient().  We also inline sock_socket_and_shutdown_and_close()
and removes the virtual call in ~ClientImpl().

* Inline and remove lock_socket_and_shutdown_and_close()

The function only has one caller.
2021-05-22 20:15:20 -04:00
yhirose ba34ea4ee8 Fix #944 2021-05-22 19:24:50 -04:00
Baruch Nissenbaum 2917b8a005 Explicit cast from size_t to uInt (#941)
* Explicit cast from size_t to uInt

* static_cast<uInt> instead of C style cast
2021-05-19 18:03:59 -04:00
Joseph Huang dcf24d45a2 fix ssesvr use of deleted function (#938) 2021-05-18 23:19:15 -04:00
yhirose 75fdb06696 Added a missing member in copy_settings. 2021-05-15 09:14:44 -04:00
Alex Hornung e00ad37580 Add option to bypass URL encode of path (#934) 2021-05-15 08:48:25 -04:00
Vincent Stumpf 5cfb70c2b4 Fix some shadowed variable warnings (#935) 2021-05-15 08:46:16 -04:00
Alessio Pollero 2a70c45697 Fix client.cc code, since res.error() without operator overloading… (#921)
* Fix client.cc code, since res.error() without operator overloading causing error in Xcode

* Add unit test to check new error to string with operator overloading

* Add inline as requested in code review comment
2021-05-01 13:29:23 -04:00
Aswin Raj Kharel c58b00580e reserving before encoding (#912) 2021-04-24 16:19:14 -04:00
Ken Schalk 7c60e69c33 Remove redunant call to close_socket (#911) 2021-04-23 17:07:19 -04:00
yhirose 33e94891ee Updated test.cc 2021-04-22 08:04:46 -04:00
yhirose 73e0729f63 Change sink.write() to return boolean 2021-04-22 07:14:08 -04:00
yhirose 21c529229c Fixed timeout issues 2021-04-22 07:14:08 -04:00
yhirose 63643e6386 Code format 2021-04-13 20:52:49 -04:00
yhirose 6cc2edce99 Added set_address_family 2021-04-13 20:49:52 -04:00
yhirose d122ff3ca8 Code formatting 2021-04-13 12:38:45 -04:00
James Young 14c6d526b4 Use newer version-flexible TLS/SSL method (#904) 2021-04-13 09:11:38 -04:00
Philipp Hasper 28e07bca16 Fixed minor code smells (#901) 2021-04-09 14:55:21 -04:00
yhirose faa5f1d802 Additional changes for #889 2021-04-05 16:13:41 -04:00
yhirose 9d3365df54 Fix #889 2021-04-05 11:40:53 -04:00
yhirose 6ff84d34d1 Another simpler implementation of #890 (#891) 2021-04-02 18:25:04 -04:00
yhirose b845425cd0 Fix #878 2021-03-16 19:42:44 -04:00
yhirose 89519c88e2 Fix #874 2021-03-10 15:57:56 -05:00
yhirose ff813bf99d Fix #863 2021-02-17 15:36:56 -05:00
yhirose cf475bcb50 Fix #860 2021-02-12 12:21:43 -05:00
yhirose bc80d7c789 Fixed ClientStop test problem 2021-02-06 20:12:30 -05:00
yhirose b7566f6961 Resolve #852 2021-02-02 22:09:35 -05:00
Nikolas 0542fdb8e4 Add exception handler (#845)
* Add exception handler

* revert content reader changes

* Add test for and fix exception handler

* Fix warning in test

* Readd exception test, improve readme note, don't rethrow errors, remove exception handler response
2021-01-28 17:19:11 -05:00
yhirose 78c474c744 Update README 2021-01-27 11:59:42 -05:00
yhirose 88411a1f52 Fix #846 2021-01-27 14:35:32 +00:00
yhirose ae6cf70bc4 Updated README 2021-01-26 08:38:28 -05:00
yhirose 68d1281759 Resolve #839 2021-01-23 13:33:27 -05:00
yhirose 0308d60cb2 Resolve #831 (#835) 2021-01-23 12:23:06 -05:00
yhirose 59f5fdbb33 Resolve #840 2021-01-23 11:43:01 -05:00
Anonymous 13184f5f80 Return Server& from handler setters (#836)
* Update httplib.h

* Update httplib.h

* Update httplib.h

* Update httplib.h
2021-01-22 09:20:21 -05:00
Eric Lee 8d9a477edb No content check (#823)
* No content check

* unit test for no content

* fixing merge conflict break

* oops during manual merge conflict
2021-01-13 17:51:40 -05:00
yhirose 85b4abbf16 Updated the simple example 2021-01-07 19:56:33 -05:00
yhirose e42a358da8 Updated README 2021-01-07 19:00:24 -05:00
yhirose f008fe4539 Added middleware support (#816) 2021-01-07 18:40:52 -05:00
yhirose ddf41d29ef Added const *char and size_t interface 2021-01-06 22:39:58 -05:00
yhirose 3f88a46c4a Code format 2020-12-31 18:14:28 -05:00
yhirose 242706ea34 Fix #820 2020-12-31 18:14:05 -05:00
yhirose a9f5f8683f Fixed warnings on Visual C++ 2020-12-31 11:35:11 -05:00
yhirose 60c2213893 Fix #817 2020-12-31 10:58:44 -05:00
yhirose eb2d28bca2 Code cleanup 2020-12-31 10:37:06 -05:00
Yuri Santos 86f637a246 Added encode_uri_param tests with UTF-8 characters (#818)
Remove additional lines between tests
2020-12-30 23:06:36 -05:00
yhirose 2c07ec4600 Code cleanup 2020-12-29 09:39:19 -05:00
yhirose 871d8d67b0 Made Request paramater const in handle_file_request 2020-12-28 22:03:44 -05:00
Anonymous 7299713195 Fix readme Response::set_chunked_content_provider (#811)
`Response::set_chunked_content_provider` has formal parameters, not one.
2020-12-25 19:55:57 -05:00
yhirose 96afa7e108 Updated README 2020-12-21 13:40:32 -05:00
yhirose 55f57af0b9 Update README 2020-12-21 09:27:36 -05:00
yhirose 6b35cd0116 Updated README 2020-12-21 08:15:06 -05:00
yhirose 99f2229e48 Updated README 2020-12-19 22:43:31 -05:00
yhirose b9641048fc Switch to hghttp2.org/httpbin for redirect test. (#538) 2020-12-19 20:27:52 -05:00
yhirose e9c6c6e609 Code format 2020-12-19 20:14:53 -05:00
yhirose 40db42108f Fixed problem with invalid requests including spaces in URL path 2020-12-19 12:03:08 -05:00
Anonymous 24bb1387d6 Update README.md (#806) 2020-12-19 11:12:44 -05:00
Jeremie Rahm d0bd4afb0b Ensure socket is closed after processing in SSLServer (#804) 2020-12-18 19:29:36 -05:00
Yuri Santos 78ea786abd [PR] Special function to encode query params (#801)
* Special function to encode query params

* Fix #include <iomanip>

* Added unescaped charsets to encode_query_param

* Unit tests for encode_query_param
2020-12-18 17:51:11 -05:00
Miosame 9cac2c9ceb typo: specitic => specific (#802) 2020-12-18 15:12:21 -05:00
Anonymous 0cff3245df Extend built-in extension MIME mapping (#799)
* Update README.md

* Update httplib.h

* Update httplib.h

* Update httplib.h

* Update httplib.h

* Remove duplicate cases

Someone left a bunch of duplicate cases, idiot, couldn't have been me.

* Reformat

Modify spacing and whatnot

* Update README.md
2020-12-18 09:32:19 -05:00
yhirose 0e3925db3f Fixed build error 2020-12-18 00:07:48 +00:00
yhirose c9a13d214b Changed not to use string_view 2020-12-17 18:48:27 -05:00
yhirose 0954af2d4c Use user-defined literals for file extention match 2020-12-17 18:27:04 -05:00
yhirose 7c1c952f5a Don't allow invalid status code format (It sould be a three-digit code.) 2020-12-15 20:25:24 -05:00
yhirose a6edfc730a Added a unit test for static file with range 2020-12-15 18:47:51 -05:00
yhirose c1264bfedc Fix problem with mp4 w/ Range header 2020-12-14 22:41:05 -05:00
yhirose 90a5b6ceb0 Updated README 2020-12-04 19:39:39 -05:00
yhirose eb240ad2e5 Code cleanup 2020-12-03 16:03:12 -05:00
yhirose 88c961f37e Removed std::atomic<Error> error_ 2020-12-01 15:17:34 +00:00
yhirose b952376968 Fixed warning 2020-12-01 03:50:55 +00:00
yhirose 5dd605d3a2 Fix #762 2020-11-30 21:49:31 -05:00
Seunghwan Hong 9c0c98b1ed Add keep_alive_timeout guide on README.md (#778) 2020-11-30 07:11:22 -05:00
yhirose 615867322d Fixed build errors and apply clangformat 2020-11-29 12:29:18 -05:00
David Wu 02d3cd5909 Fix multiple threading bugs including #699 and #697 2020-11-29 12:29:15 -05:00
yhirose 47e5af15ea Updated README 2020-11-22 09:22:40 -05:00
yhirose a5c239c174 Fix #765 2020-11-21 16:35:31 -05:00
yhirose c2afc5ca44 Added chunked content provider support on client 2020-11-21 08:46:50 -05:00
yhirose cee062d4c9 Fixed unit tests due to the change in #763 2020-11-19 21:04:46 -05:00
Unkorunk b21dc8cbe0 Fix incorrect content_encoding for Brotli (#763) 2020-11-19 12:39:20 -05:00
372046933 e1133a2dcb std::tolower is undefined if the argument's value is neither representable as unsigned char nor equal to EOF (#761)
Co-authored-by: taoxu <taoxu@bilibili.com>
2020-11-19 09:21:40 -05:00
yhirose e273fec93c Fixed Visual Studio setup 2020-11-19 09:17:59 -05:00
yhirose 95d0b073bd Fix #754 2020-11-15 08:13:08 -05:00
vawen 9c7d841b37 Fix: #746 Compile error under VS2015 (#747)
Co-authored-by: jigarcia@vaxtor.es <jigarcia@vaxtor.es>
2020-11-10 08:41:53 -05:00
yhirose f086bf5310 Fix #738 2020-11-08 18:16:23 -05:00
yhirose 6613d7b7ad Fixed warnings 2020-11-08 17:59:11 -05:00
yhirose 6adf130bf3 Fix #739 2020-11-07 21:54:47 -05:00
miketsts b6b2eaf5bc Add unit test SSLConnectTimeout (#741)
Add unit test for issue #682 fixed in PR #728, which does not contain
the test of its own.

The test creates a fake SSL server, inherited from SSLServer, which
does not create an SSL context. When an SSL client attempts to send it
a request, it gets a timeout error. Prior to PR #728, the client would
wait indefinitely

Co-authored-by: Michael Tseitlin <michael.tseitlin@concertio.com>
2020-11-07 09:41:20 -05:00
yhirose eb4b7c70a9 Fix #737 2020-11-07 09:33:22 -05:00
yhirose 84661ea6ed Refactoring 2020-11-05 07:06:53 -05:00
yhirose 041122908c Fix problem with invalid range 2020-11-05 00:20:59 -05:00
yhirose 401de608df Fixed debug option problem. 2020-11-05 00:20:59 -05:00
yhirose 726c64cf10 Code format 2020-11-05 00:20:59 -05:00
Omkar Jadhav e1f781a21a [oss-fuzz] Enable msan for fuzz tests (#734)
* Disable openssl as we're not using it in fuzz tests

* Increase timeout in ClientStop test
2020-11-04 11:30:56 -05:00
Omkar Jadhav 72b81badad Fix issues reported by oss-fuzz (#729)
* Fix oss-fuzz issue #26529

* Add test for oss-fuzz issue  #26598

* Fix oss-fuzz issue  #26632

* Revert change and add new test cases
2020-11-03 11:36:02 -05:00
yhirose 17428a8fbf Fixed warning 2020-11-03 09:16:28 -05:00
Daniel Ottiger 6e1879dfae ssl-verify-host: fix verifying ip addresses containing zero's (#732)
* ssl-verify-host: fix verifying ip addresses containing zero's

If the subject alternate name contained an ip address with an zero
(like 10.42.0.1) it could not successfully verify.
It is because in c++ strings are null-terminated
and therefore strlen(name) would return a wrong result.
As I can not see why we can not trust the length returned by openssl,
lets drop this check.

* ssl-verify-host: add test case

lets try to validate against 127.0.0.1

Co-authored-by: Daniel Ottiger <daniel.ottiger@ch.schindler.com>
2020-11-02 20:27:34 -05:00
miketsts eb1d2e04bc SSL_connect and SSL_accept in non-blocking mode (#728)
SSL connection is performed in two steps:
First, a regular socket connection is established.
Then, SSL_connect/SSL_accept is called to establish SSL handshake.

If a network problem occurs during the second stage, SSL_connect on
the client may hang indefinitely.

The non-blocking mode solves this problem.

Co-authored-by: Michael Tseitlin <michael.tseitlin@concertio.com>
2020-11-02 17:05:08 -05:00
yhirose c909ffa758 Fix #731 2020-11-01 21:03:47 -05:00
yhirose ff5677ad19 Updated README 2020-10-27 20:35:56 -04:00
yhirose 8b1b31ac20 Fix #723 2020-10-27 20:32:19 -04:00
yhirose 953600c177 Fixed compiler error for old compiler. 2020-10-27 12:23:37 -04:00
yhirose 536e7eb7f2 Revert "Fix #697". (It broke unit test...)
This reverts commit 6d66721ba1.
2020-10-25 20:22:39 -04:00
yhirose 6d66721ba1 Fix #697 2020-10-25 16:55:54 -04:00
yhirose 3b29cd0bdc Fix #698 2020-10-25 12:14:54 -04:00
yhirose 109b624dfe Fix #708 (#713)
* Fix #708

* Rename ContentReceiver2 to ContentReceiverWithProgress
2020-10-22 11:48:43 -04:00
yhirose 0ed70c4d9f Fixed unit test errors 2020-10-21 14:34:27 -04:00
yhirose a50b7591ca Fix #714 2020-10-21 13:02:33 -04:00
yhirose bf8fc11b53 Code cleanup 2020-10-20 21:24:47 -04:00
Omkar Jadhav bc4a613b6d Fix suffix-byte-range issue (#711) 2020-10-20 11:11:27 -04:00
yhirose 4bb001351c Fix #705 2020-10-19 22:13:24 -04:00
yhirose e155ba44bb Fix #706 2020-10-19 15:23:35 -04:00
Muchamad Arifin Dwi P a4a9637738 Fix #700 null pointer exception (#702) 2020-10-16 20:44:14 -04:00
Omkar Jadhav 5292142046 Add cpp-httplib to oss-fuzz (#684)
* *Add server fuzzer target  and seed corpus
* Add fuzz_test option to Makefile

* Fix #685

* Try to fix Github actions on Ubuntu

* Added ReadTimeoutSSL test

* Comment out `-fsanitize=address`

* Rebase upstream changes

* remove address sanitizer temporarily

* Add separate Makefile for fuzzing

* 1. Remove special char from dictionary
2. Clean fuzzing/Makefile

* Use specific path to avoid accidently linking openssl version brought in by oss-fuzz

* remove addition of flags

* Refactor Makefile

* Add missing newline

* Add fuzztest to github workflow

* Fix

Co-authored-by: yhirose <yuji.hirose.bug@gmail.com>
2020-10-15 08:11:40 -04:00
Snape3058 cc5147ad72 Replace shared_ptr with unique_ptr for better performance (#695)
* Backport std::make_unique from C++14.

* Replace shared_ptr with unique_ptr for better performance.

Co-authored-by: Ella <maxutong16@otcaix.iscas.ac.cn>
2020-10-15 08:09:11 -04:00
Andrew Gasparovic fffbf1a669 Use move semantics instead of copy for functions (#692)
* Use move semantics instead of copy for functions

In some cases, a few more copies could be prevented by changing function definitions to accept parameters by const-ref, rather than by value, but I didn't want to change public signatures.

* Fix two use-after-move errors
2020-10-11 19:00:36 -04:00
lightvector d37bc0fb4d Allow client to specify boundary and use more entropy by default (#691) (#694) 2020-10-11 15:34:54 -04:00
Andrew Gasparovic 6d60dc8839 Add cache_control parameter to set_mount_point (#688)
* Add `cache_control` parameter to `set_mount_point`

Specifies the Cache-Control header value to return when specified. For example:

```
svr.set_mount_point("/assets", "public/assets", "public, max-age=604800, immutable");
```

* Add default for cache_control

Default to "no-cache", which is implicitly what is happening today.

* Change set_mount_point to accept Headers

* Don't use C++17 destructuring
2020-10-10 20:46:08 -04:00
Wang Gao b713a3a651 fix MSVC2015 error: std::tolower to ::lower (#689) 2020-10-10 12:02:50 -04:00
yhirose 7e8db1dc68 Comment out -fsanitize=address 2020-10-08 23:14:53 -04:00
yhirose 316add860b Added ReadTimeoutSSL test 2020-10-08 22:55:09 -04:00
yhirose 79ce6f1745 Try to fix Github actions on Ubuntu 2020-10-08 21:49:47 -04:00
yhirose 09fdf4eacd Fix #685 2020-10-08 21:37:42 -04:00
Omkar Jadhav 143b2dd15a Fix memory leak due caused due to X509_STORE (#671)
* Fix memory leak due caused due to X509_STORE

* Add test for repro and address sanitizer to compiler flags

* Add comment

* Sync

* Associate ca_store with ssl context within set_ca_cert_store()

* Split SlowPost test

* Fix #674

Co-authored-by: yhirose <yuji.hirose.bug@gmail.com>
2020-10-02 13:17:37 -04:00
yhirose e2c4e9d95c Fix #674 2020-09-29 19:22:28 -04:00
yhirose d87082f04b Split SlowPost test 2020-09-29 19:17:34 -04:00
yhirose cc14855ba0 Fix #661 2020-09-26 04:50:09 -04:00
yhirose 56c418745f Fixed conction close problem with HTTP 1.0 client 2020-09-25 20:58:49 -04:00
yhirose 4ce9911837 Add <sstream> 2020-09-25 18:17:32 -04:00
yhirose 559c407552 Adjusted SlowRequest test 2020-09-25 18:13:10 -04:00
yhirose a2f4e29a7b Add set_keep_alive_timeout 2020-09-25 17:57:33 -04:00
mi01 b8cf739d27 Add cctype header (#656) 2020-09-16 16:32:49 -04:00
yhirose aec2f9521d Updated documentation 2020-09-15 10:11:46 -04:00
yhirose 7b55ecdc59 Fixed #650 2020-09-12 16:11:14 -04:00
tmahring e9575bcb78 don't replace plus with space in headers (#649)
* don't replace plus with space in headers

* fixed forward handling with changed header parsing

* add test for boundaries containing plus chars
2020-09-10 20:27:01 -04:00
Jonas Minnberg 308aeb187b Undefined if2ip() also on Android since getifaddrs() does not exist. (#648)
Co-authored-by: Jonas Minnberg <jonas@minnberg.se>
2020-09-10 07:52:01 -04:00
Jodi the Tigger 05d18f2bc5 Fix -D build flags containing escaped quotes (#645)
Fixes #638

Done by removed unneeded quotes from cmake's add_compiler_definitions()
2020-09-08 21:35:50 -04:00
Ivan Fefer 3da4a0ac69 Add compression buffer size customization (#644)
* add compression buffer size customization and small brotli refactor

* allocat brotli buffer once

* add init to brotli decoder buffer
2020-09-08 12:18:14 -04:00
yhirose 9d12b3f20e Fixed warnings and refactoring 2020-09-03 20:33:30 -04:00
Omkar Jadhav 852a374748 Fix server crash caused due to regex complexity while matching headers. (#632)
* Fix parsing to parse query string with single space char.

When passed ' ' as a query string, the server crashes cause of illegal memory access done in httplib::detail::split. Have added checks to make sure the split function has a valid string with length > 0.

* Fix parsing to parse query string with single space char.

* Fix server crash caused due to regex complexity while matching headers.

While parsing content-type header in multipart form request the server crashes due to the exhaustion of max iterations performed while matching the input string with content-type regex.
Have removed the regex which might use backtracking while matching and replaced it with manual string processing. Have added tests as well.

* Remove magic number

Co-authored-by: Ivan Fefer <fefer.ivan@gmail.com>

Co-authored-by: yhirose <yhirose@users.noreply.github.com>
Co-authored-by: Ivan Fefer <fefer.ivan@gmail.com>
2020-09-03 13:17:52 -04:00
Ivan Fefer 3b5bab3308 Fix gzip_decompressor in case of one chunk being exactly equal to buffer size (#636)
* add larget chunks test

* revert test

* Fix gzip decoder in case of chunk being equal to buffer size

* add test
2020-09-03 12:20:02 -04:00
yhirose 69e75f4a67 Fix #635. HTTPS request stucked with proxy (#637) 2020-09-03 12:17:53 -04:00
Omkar Jadhav b0fd4befb1 Fix query parsing issues (#629)
* Fix parsing to parse query string with single space char.

When passed ' ' as a query string, the server crashes cause of illegal memory access done in httplib::detail::split. Have added checks to make sure the split function has a valid string with length > 0.

* Fix parsing to parse query string with single space char.
2020-08-28 09:43:28 -04:00
yhirose 3e80666a74 Fix #628 2020-08-27 19:45:28 -04:00
yhirose 3e4567bae8 Updated Repl.it examples 2020-08-27 14:16:35 -04:00
yhirose db075d8cf9 Added Repl.it examples 2020-08-27 14:06:57 -04:00
yhirose 16df0ef37e Code cleanup 2020-08-26 12:18:49 -04:00
Ivan Fefer f1a2ac5108 Avoid copying of content provider if possible (#627) 2020-08-26 08:56:51 -04:00
yhirose e5743b358d Updated README 2020-08-25 20:26:53 -04:00
Ivan Fefer 1184bbe4cb Fix typo in README (#625) 2020-08-25 06:38:16 -04:00
Felix Kästner 9dcffda7ae Fix cmake execute_process working directory (#622)
Correct the working directory of the execute_process call, to get the version from git tags.
The working directory should be the the directory of this libary. Otherwise, if you include httplib
as a git submodule and call add_subdirectory, the execute_process command will be run in a wrong
directory leading to error.
2020-08-24 17:23:01 -04:00
yhirose e5903635e2 Fix #619 2020-08-22 12:54:43 -04:00
yhirose 510b4eaaae Fix #613 2020-08-17 13:40:06 -04:00
yhirose d7e63b4316 Update README 2020-08-16 20:49:54 -04:00
yhirose e5dd410256 Added set_content_provider without content length 2020-08-15 05:53:49 -04:00
yhirose 951e46929e Fix #609 2020-08-14 15:01:09 -04:00
yhirose c8adac30f4 Fix #564 again 2020-08-13 08:07:25 -04:00
yhirose b2b4f7635f Fix #608 2020-08-11 12:11:05 -04:00
R Edgar 649b1d2172 Fix nullptr_t issue (#605)
Clang complains that `nullptr_t` should be `std::nullptr_t
2020-08-09 16:45:53 -04:00
yhirose dc5f9ba164 Better error handling on client (#601) 2020-08-08 20:50:24 -04:00
yhirose cf084e1db1 Fixed example build errors 2020-08-08 00:10:08 -04:00
KTGH e0e5898601 Overhaul FindBrotli to fix weird issues (#604)
Should get rid of the issue about not being able to create an ALIAS on
MinGW, as well as the "No REQUIRED_VARS" issue.

Fixes #603 (hopefully)
2020-08-06 07:08:29 -04:00
yhirose dfec2de5b5 Update README 2020-08-03 23:37:05 -04:00
yhirose 04002d57bd Added set_default_headers (Fix #600) 2020-08-03 22:05:37 -04:00
yhirose 38a7706c8b Removed old Keep-Alive functions 2020-08-03 22:04:40 -04:00
KTGH abaf875c42 Fix FindBrotli when no Brotli installed (#598)
Woops.

Ref https://github.com/yhirose/cpp-httplib/issues/582#issuecomment-667537002
2020-08-01 17:08:49 -04:00
PixlRainbow 5f76cb01c7 fix #592 -- add check for static-linked OpenSSL (#595) 2020-08-01 08:10:42 -04:00
yhirose ae54e833ea Code cleanup 2020-07-31 23:48:42 -04:00
yhirose 0dd3659de5 Updated README 2020-07-31 18:54:53 -04:00
KTGH 999f6abd2c Fix for Cmake on systems without Git (#594)
If you didn't have Git installed, execute_process never declared the
error variable, which led to it never parsing the header for a version.
So if Git wasn't installed, the version variable never got declared,
which caused errors.

This fixes that.
2020-07-31 13:46:12 -04:00
KTGH 48da75dd35 Fix FindBrotli for static libs (#593)
It wasn't linking them.
2020-07-31 13:45:21 -04:00
yhirose 4f84eeb298 Bearer Token auth support. Fix #484 2020-07-31 12:37:14 -04:00
yhirose a5b4cfadb9 Brotli suport on server. Fix #578 2020-07-31 10:23:57 -04:00
yhirose 3e906a9b8c Fix #591 2020-07-30 18:26:18 -04:00
yhirose 110393eadb Class name change 2020-07-30 17:27:07 -04:00
yhirose 98caa8c058 Updated README 2020-07-30 17:21:49 -04:00
yhirose ef65f09608 OpenSSL support on Visual Studio project 2020-07-30 17:19:12 -04:00
ThePiso e130cf3a3b The piso patch 1 (#590)
* Update httplib.h

When you disconnect and reconnect from the network, your network stack rewrites and updates /etc/resolv.conf accordingly. This configuration file is needed by the DNS resolver in the C library. The C library reads the DNS configuration from /etc/resolv.conf the first time, and caches it. It doesn't check, with every lookup, if the contents of /etc/resolv.conf have changed.
the solution is to add a call to res_init(), defined in resolv.h

* Update httplib.h
2020-07-30 10:11:02 -04:00
yhirose 8a348f17fd Resolved #192 2020-07-30 01:47:54 -04:00
yhirose 797d1f27e8 Fix #357 2020-07-29 23:12:05 -04:00
yhirose 6cde600922 Simplified simplecli.cc 2020-07-29 16:04:28 -04:00
KTGH 342c3ab293 Add Brotli Cmake support (#584)
Had to create a custom FindBrotli package, as not all users have
PkgConfig installed (which Brotli uses). This file gets installed
alongside httplibConfig.cmake for the end-users convenience.

Set BROTLI_USE_STATIC_LIBS to ON if you want to find the static libs
instead of default shared.

Adds the HTTPLIB_REQUIRE_BROTLI (default off) and HTTPLIB_USE_BROTLI_IF_AVAILABLE
(default on) options, which work in the same manner as the other optional/required
dependency options.

Moved the scattered linking and definitions to a single call.

Updated some documentation about the new options.

Improved the in-tree support by setting the HTTPLIB_IS_USING_XYZ
variables in the main CMakeLists (as well as having them in the
httplibConfig.cmake file).

Fixes #582
2020-07-28 17:04:29 -04:00
yhirose 6cce7951fc Fixed build error on non Windows environments with OpenSSL 2020-07-27 22:34:35 -04:00
yhirose e9058e5639 Fixed build error on Windows with OpenSSL 2020-07-27 22:32:31 -04:00
yhirose 2538a85486 Fix #581 2020-07-27 22:07:04 -04:00
KTGH 8c501022b3 Fix Cmake build for MinGW (#580)
Seems certain targets/hosts failed without these, as "_MSC_VER" is
undefined on MinGW, which caused the 'pragma comment(lib "libname")' to
fail.

Fixes #575
2020-07-26 12:27:03 -04:00
yhirose 9f5db2d1aa Updated README 2020-07-25 20:53:38 -04:00
yhirose 12540fe8d3 Brotli support on client 2020-07-25 20:44:02 -04:00
yhirose 29a06f852a Update README 2020-07-25 11:24:06 -04:00
yhirose 0e9cfd9f49 SSE client example 2020-07-25 11:20:57 -04:00
yhirose 90da199aba Disable compression when content-type is text/event-stream 2020-07-25 10:46:52 -04:00
yhirose 366d073490 Fixed build errors 2020-07-25 09:40:35 -04:00
yhirose 9ca1fa8b18 Fix #576 2020-07-25 09:37:57 -04:00
yhirose 15c4106a36 Added a unit test 2020-07-22 08:07:59 -04:00
yhirose 72ce293fed Removed set_timeout_sec and left set_base_dir 2020-07-20 17:15:16 -04:00
yhirose b476b55771 Fix #557 2020-07-20 17:04:50 -04:00
yhirose 0db9d21eb0 Fix #571 2020-07-19 18:40:55 -04:00
yhirose 5ddaf949d0 Fixed build error on Windows 2020-07-19 18:32:28 -04:00
yhirose 457a5a7501 Added compressor class 2020-07-19 17:44:45 -04:00
Daniel Ottiger 2ce080c2cb include <wincrypt.h> as otherwise CertOpenSystemStoreW can not be found (#568)
- visual studio 2019, version 16.6.3
- 64 bit target
2020-07-15 10:17:18 -04:00
yhirose 6ad25b6cf0 Fix #566 2020-07-12 20:41:02 -04:00
yhirose 3dff60eb16 Fix #565 2020-07-10 08:18:28 -04:00
yhirose 5038314b21 Fix #564 2020-07-08 13:56:06 -04:00
yhirose 6e1297cab0 Fix #150 (#556) 2020-07-07 18:55:46 -04:00
yhirose 7de743c962 Code format 2020-07-04 00:11:32 -04:00
Umiade 964fb5e5ca Fix: regex can't match when proxy was set to some web debugger(e.g. Fiddler) (#553)
Co-authored-by: Umiade <hanyuchao@corp.netease.com>
2020-07-03 07:17:04 -04:00
yhirose c4f3f9529b Fix #534 (#546) 2020-07-02 21:57:50 -04:00
Ilya Tsybulsky 887def9490 Fix logger never called when write_content_with_provider returns false (#549) 2020-07-01 17:09:43 -04:00
Ilya Tsybulsky bad6b2d22f fix-the-code-won't compile-with-sdl-checks-on (#550) 2020-07-01 17:09:19 -04:00
rundong08 3d47a51430 Fixed comparison of integers of different signs. (#544) 2020-06-29 21:19:56 -04:00
Ron Klein 0a2cb20223 fix documentation typo (#539)
fix "adress" --> "address"
2020-06-22 18:12:22 -04:00
yhirose ce502a73e1 Fix #531 2020-06-22 14:56:18 -04:00
yhirose 010e4479f4 Fixed test errors due to httpbin.org 2020-06-22 14:53:20 -04:00
Ahmet Karaahmetoğlu 70e193374a Fix #530 (#535) 2020-06-21 15:08:40 -04:00
yhirose 6b22409217 Code format 2020-06-18 23:33:07 -04:00
yhirose 969cccd52a Use && for parameter of boundary 2020-06-18 23:32:09 -04:00
yhirose 4a9c048bbc Fixed problem with set_socket_options 2020-06-18 23:31:41 -04:00
yhirose bfabbec8c7 Fix #528 2020-06-18 12:20:01 -04:00
yhirose 3e9c06cf79 Fixed #527 2020-06-18 12:18:43 -04:00
yhirose 29677540ae Removed unnecessary yeid. 2020-06-16 21:33:10 -04:00
yhirose 71fcfeb912 Removed unnecessary code 2020-06-16 21:21:03 -04:00
yhirose c7d22e451f Fixed timeout calculation bugs 2020-06-16 21:20:47 -04:00
yhirose 42f9f9107f Updated version in the User Agent string 2020-06-16 17:53:15 -04:00
yhirose 7cd25fbd63 Fix #499 2020-06-16 17:46:23 -04:00
yhirose 3dfb4ecac2 Fix #522 2020-06-15 23:09:46 -04:00
yhirose 144114f316 Fixed warnings on Windows 2020-06-13 23:20:21 -04:00
yhirose 0cc108d45e Updated ClientStop test 2020-06-13 23:18:59 -04:00
yhirose 0743d78c9b Fixed ClientStop test error. 2020-06-14 03:01:41 +00:00
yhirose e022b8b80b Refactoring to make it ready for KeepAlive connection on Client 2020-06-13 21:42:23 -04:00
yhirose 34282c79a9 Changd thread count in ClientStop 2020-06-13 01:45:08 -04:00
yhirose f80b6bd980 Added Endpoint structure in Client 2020-06-13 01:26:57 -04:00
yhirose 5af7222217 Fixed Client::stop problem with more than one requests on threads 2020-06-12 11:04:37 -04:00
KTGH ec00fe5d5b Use git to get full project version (#519)
This gets us the full version (aka with the patch version), instead of
just major and minor version from user agent.

Falls back to the user agent if it fails.
2020-06-10 18:23:45 -04:00
yhirose 24bdb736f0 Fix #506 2020-06-09 19:58:01 -04:00
yhirose d0dc200633 Code format 2020-06-09 19:17:58 -04:00
Nicolas Schneider 919a51091f replace usage of [[deprecated]] with CPPHTTPLIB_DEPRECATED (#513) 2020-06-03 13:12:31 -04:00
Nicolas Schneider 05e8b22989 fix cast warning (#512) 2020-06-03 07:44:16 -04:00
Nicolas Schneider 00dcd6b004 check for [[deprecated]] support via feature test macro (#511)
The [[deprecated]] specifier is a C++14 feature, so it might not always
be available on a C++11 compiler.
2020-06-03 07:43:56 -04:00
yhirose a42c6b99d3 Code cleanup 2020-06-02 19:06:16 -04:00
Wang Gao 812cb5bc3d fix get value function (#509) 2020-06-02 19:05:04 -04:00
yhirose aea60feb85 Code cleanup 2020-06-01 13:22:02 -04:00
yhirose b3a4045300 Fix #503 2020-05-28 19:19:18 -04:00
KTGH 5fcd8f7795 Add automatic versioning to Cmake (#505)
It pulls the version from the user-agent string in the header, so it
will not need to be manually adjusted. This version file is installed so
that you can check for a specific version with find_package(httplib)

Also added HTTPLIB_INCLUDE_DIR (root path without header name), and
HTTPLIB_LIBRARY (only if compiled).

Added HTTPLIB_VERSION, and HTTPLIB_FOUND (although it's recommended
to check if the target exists).

Updated CMakeLists documentation for all this.
2020-05-28 17:09:20 -04:00
yhirose d9fe3fa020 Fix #504 2020-05-28 17:08:05 -04:00
yhirose d8612ac02d Fixed build error... 2020-05-28 12:51:52 -04:00
yhirose 83ee6007da Fix #500 2020-05-28 12:06:11 -04:00
yhirose 3eaa769a2d Fix #481, #483, #487 2020-05-26 18:34:32 -04:00
yhirose b91540514d Fix #494 2020-05-25 10:50:24 -04:00
yhirose ab563ff52c Fix #496 2020-05-25 10:38:47 -04:00
KTGH 8cad160c0a Add HTTPLIB_COMPILE option to Cmake (#493)
This option (default OFF) automatically splits the file (with split.py)
into a header & source file, then compiles it as a shared/static
library. This requires an installed Python v3 executable to work.

This also adds a HTTPLIB_IS_COMPILED boolean that's available after a
finfind_package(httplib) call.

Note that the minimum Cmake version increased to 3.12 because of FindPython3.
Hopefully this isn't a problem, as it's already 3 years old at this point.
2020-05-24 16:07:44 -04:00
yhirose be7962f140 Fix #489 2020-05-24 15:18:34 -04:00
yhirose 509b8570b0 Updated README 2020-05-23 19:08:17 -04:00
yhirose 630f3465a9 Deprecated set_timeout_sec, added set_connection_timeout. 2020-05-23 18:00:24 -04:00
yhirose 9af1a4a08f Fixed problem with stop on windows 2020-05-23 13:49:49 -04:00
yhirose 0654e5dab4 Changed CPPHTTPLIB_IDLE_INTERVAL_USECOND to 0 2020-05-23 08:44:03 -04:00
yhirose 62e036f253 Fixed #488 again 2020-05-22 18:24:01 -04:00
yhirose f0adfb2e0c Fix #488 2020-05-22 12:18:07 -04:00
yhirose 139c816c16 Fixed the location of Client2 2020-05-19 21:02:58 -04:00
KTGH 9505a76491 Bringing Cmake back (#470)
* Revert "Removed CMakeLists.txt. (Fix #421)"

This reverts commit 8674555b88.

* Fail if cmake version too old

Previous behaviour is just a warning.

* Improve CMakeLists

Adds automatic dependency finding (if they were used).
Adds a way to require a specific version in the find_package(httplib) call.

You should link against the httplib::httplib IMPORTED target, which is
created automatically.

Add options to allow for strictly requiring OpenSSL/ZLIB

HTTPLIB_REQUIRE_OPENSSL & HTTPLIB_REQUIRE_ZLIB require the libs be found, or the build fails.

HTTPLIB_USE_OPENSSL_IF_AVAILABLE & HTTPLIB_USE_ZLIB_IF_AVAILABLE silently search for the libs.
If they aren't found, the build still continues, but shuts off support for those features.

* Add documentation to CMakeLists.txt

Has info on all the available options and what targets are produced.

Also put some things about installation on certain platforms.
2020-05-19 19:07:18 -04:00
yhirose 29fd136afd Code cleanup and format 2020-05-16 17:35:04 -04:00
yhirose f5598237b2 Fixed many redirects problem on Proxy 2020-05-16 17:34:03 -04:00
Daniel Ottiger 01058659ab make write timeout configurable (like the read timeout already is) (#477)
In case we want to send a lot of data,
and the receiver is slower than the sender.

This will first fill up the receivers queues and after this
eventually also the senders queues,
until the socket is temporarily unable to accept more data to send.

select_write is done with an timeout of zero,
which makes the select call used always return immediately:
(see http://man7.org/linux/man-pages/man2/select.2.html)

This means that every marginal unavailability will make it return false
for is_writable and therefore httplib will immediately abort the transfer.

Therefore make this values configurable in the same way
as the read timeout already is.

Set the default write timeout to 5 seconds,
the same default value used for the read timeout.
2020-05-16 17:31:46 -04:00
yhirose 66f698fab6 Fixed build errors with some examples 2020-05-16 00:50:52 -04:00
yhirose b9a9df4d73 Fixed problem with writing large data 2020-05-15 22:21:58 -04:00
yhirose 25aa3ca982 Added std::ostream os in DataSink. 2020-05-15 21:26:13 -04:00
yhirose 2d67211183 Added more unit tests for the simple interface 2020-05-14 18:25:18 -04:00
yhirose f4c5d94d74 Updated version in the User Agent string 2020-05-14 18:07:02 -04:00
yhirose 63a96aeb20 Improved Client2 interface 2020-05-14 12:51:34 -04:00
yhirose bbb83d12c1 Removed default parameter values in Client and SSLClient constructors 2020-05-14 08:51:32 -04:00
yhirose 2d4b42b70b Removed url 2020-05-14 01:43:06 -04:00
yhirose 1919d08f71 Added Client2 2020-05-14 01:36:56 -04:00
yhirose 824c02fcd3 Code cleanup 2020-05-14 01:08:36 -04:00
yhirose 2c0613f211 Fix #472 2020-05-13 21:48:14 -04:00
Saika Fatih be45ff1ff1 A detail about Gzip support (#475)
* Typos fixed

* README.md edited.libz should be linked for GZIP support.
2020-05-12 17:38:51 -04:00
Saika Fatih 803ebe1e20 Typos fixed (#474) 2020-05-12 13:18:58 -04:00
yhirose ba685dbe48 Fixed potential infinite loop with content receiver 2020-05-10 20:45:57 -04:00
yhirose 49c4c2f9c1 Fix #459 2020-05-10 20:39:16 -04:00
yhirose 58909f5917 Fix #466 2020-05-10 15:58:53 -04:00
yhirose 5982b5c360 Fix #471 2020-05-10 14:18:03 -04:00
yhirose eb1fe5b191 Fixed warnings 2020-05-09 15:08:49 -04:00
yhirose 5e01587ed6 Fixed problem created in the previous commit 2020-05-09 13:43:06 -04:00
yhirose 5935d9fa59 Commented out the unit test for digest auth. 2020-05-09 13:32:51 -04:00
PixlRainbow 5bb4c12c6b Fix #465 (#467)
update digest header username to use username parameter instead of "hello" test value
2020-05-09 08:29:08 -04:00
yhirose 85637844c9 Updated README 2020-05-07 21:13:45 -04:00
Daniel Ottiger d043b18097 keepalive: support multiple post using content provider (#461) 2020-05-07 08:31:14 -04:00
yhirose 31bb13abd2 Removed TravisCI badge from README 2020-05-04 22:19:17 -04:00
yhirose 8728db7477 Apply IPV6_V6ONLY only when socket is AF_INET6 2020-05-04 22:16:43 -04:00
yhirose 1c50ac3667 Stop using TravisCI anymore due to IPv6 issue 2020-05-04 22:14:03 -04:00
yhirose cf386f97fd Merge branch 'master' of https://github.com/yhirose/cpp-httplib 2020-05-04 22:13:17 -04:00
Daniel Ottiger b2203bb05a server: support dual-stack server socket (#450)
According to RFC 3493 the socket option IPV6_V6ONLY
should be off by default, see
https://tools.ietf.org/html/rfc3493#page-22 (chapter 5.3).

However this does not seem to be the case on all systems.
For instance on any Windows OS, the option is on by default.

Therefore clear this option in order to allow
an server socket which can support IPv6 and IPv4 at the same time.
2020-05-04 22:13:12 -04:00
yhirose f5b806d995 Added a test case for #396. 2020-05-04 21:26:14 -04:00
yhirose 3895210f19 Code format 2020-05-04 21:25:59 -04:00
yhirose d45250fd88 Appled HANDLE_EINTR to send and select system calls 2020-05-01 21:38:23 -04:00
yhirose 528cacdc0d Changed CPPHTTPLIB_THREAD_POOL_COUNT back to 8. (#454) 2020-05-01 21:23:02 -04:00
Matthew DeVore ed1b6afa10 Fix crash caused by header field regex complexity (#457) 2020-05-01 12:44:13 -04:00
yhirose 08fc7085e5 Fixed #456 2020-04-30 19:40:23 -04:00
yhirose 8333340e2c Chagned to use inline function instead of macro 2020-04-27 12:36:39 -04:00
yhirose 98a0887571 Merge branch 'je-ik-sketch-eintr-handling' 2020-04-27 12:33:21 -04:00
Jan Lukavsky b0a189e50e Sketch handling EINTR errors 2020-04-27 17:36:44 +02:00
yhirose 776b3ffbf9 Code format 2020-04-25 18:01:48 -04:00
yhirose a061b97677 Adjust appveyor.yml 2020-04-25 18:01:12 -04:00
yhirose d359e3a5f7 Renave queue_adjust to on_idle (#442) 2020-04-25 17:56:55 -04:00
evg82 5928e0af1a TaskQueue method to internal size adjust (#442)
I use a custom TaskQueue, with variable number of workers, adding workers on demand is an easy task when new connection arrive (in enqueue function) however i need another funtion to be called even (or better) went no new connections arrives to reduce workers count. I only added a new virtual method in TaskQueue class to allow custom class to adjust workers size over time. Even if this methods is called frequenlty custom class can keep a "last_update" counter to check if need to adjust worker count or any other internal task. Without this function i need an external thread to make this adjust task.
2020-04-25 17:55:20 -04:00
yhirose a5005789ff Fixed Visual Studio compiler warnings with x64 platform (Resolve #440 and #446) (#448) 2020-04-25 17:13:14 -04:00
yhirose fae30af47d Updated appveyor.yml 2020-04-25 15:48:19 -04:00
Hoa Thiên Vũ 2feea0c9ab Fixed error: ‘ULONG_MAX’ was not declared in this scope on line 1921 (#445)
* Fixed error:
ULONG_MAX is defined in the limits.h header file. Putting #include <climits>
```
httplib.h: In function ‘bool httplib::detail::read_content_chunked(httplib::Stream&, httplib::ContentReceiver)’:
httplib.h:1921:22: error: ‘ULONG_MAX’ was not declared in this scope
     if (chunk_len == ULONG_MAX) { return false; }
                      ^~~~~~~~~
httplib.h:1921:22: note: suggested alternative: ‘_SC_ULONG_MAX’
     if (chunk_len == ULONG_MAX) { return false; }
                      ^~~~~~~~~
                      _SC_ULONG_MAX
```

* Move #include <climits> to after #include <cassert>
2020-04-24 12:02:19 -04:00
yhirose a2e4af54b7 Fix #399 2020-04-23 23:09:04 -04:00
yhirose d0b123be26 Support remote_addr and remote_port REMOTE_PORT header in client Request (#433) 2020-04-23 22:12:12 -04:00
Matthew DeVore df138366e4 Fail to read a chunk if its length is >= ULONG_MAX (#444)
We cannot trivially support such large chunks, and the maximum value
std::strtoul can parse accurately is ULONG_MAX-1. Error out early if the
length is longer than that.
2020-04-23 10:59:15 -04:00
Matthew DeVore c49441ae64 Do not throw exceptions when parsing request chunks (#441)
detail::read_content_chunked was using std::stoul to parse the
hexadecimal chunk lengths for "Transfer-Encoding: chunked" requests.
This throws an exception if the string does not begin with any valid
digits. read_content_chunked is not called in the context of a try block
so this caused the process to terminate.

Rather than use exceptions, I opted for std::stroul, which is similar to
std::stoul but does not throw exceptions. Since malformed user input is
not particularly exceptional, and some projects are compiled without
exception support, this approach seems both more portable and more
correct.
2020-04-23 09:05:45 -04:00
yhirose e1506fa186 Code cleanup 2020-04-22 21:43:16 -04:00
yhirose ad9fd3bd93 Fix #436 2020-04-22 21:42:58 -04:00
yhirose 05e0253195 Fixed test error 2020-04-21 23:07:51 -04:00
yhirose da26b517a3 Added url::Get interface 2020-04-21 23:00:39 -04:00
yhirose 2b7a968468 Added a unit test for URL interface 2020-04-21 21:21:31 -04:00
yhirose 240cc85ccb Fixed regex problem for recirect location 2020-04-21 21:18:29 -04:00
yhirose 129e2f00b8 Removed unnecessary noexcept 2020-04-20 19:42:05 -04:00
Daniel Ottiger da746c6e67 SSLClient::set_ca_cert_store: mark as inline (#435) 2020-04-20 12:53:39 -04:00
yhirose 3451da940d Code format 2020-04-19 22:05:04 -04:00
yhirose 38a6b3e69f Fixed warning 2020-04-19 22:04:29 -04:00
yhirose d1037ee9fd Close #433 2020-04-18 16:38:15 -04:00
Daniel Ottiger 2ece5f116b Pass certs and keys from memory (#432)
* SSLServer: add constructor to pass ssl-certificates and key from memory

* SSLClient: add constructor to pass ssl-certificates and key from memory

* add TestCase for passing certificates from memory to SSLClient/SSLServer
2020-04-18 16:26:06 -04:00
yhirose c2b6e4ac04 Fix #431 2020-04-17 21:48:16 -04:00
yhirose 8674555b88 Removed CMakeLists.txt. (Fix #421) 2020-04-13 20:56:21 -04:00
yhirose 85327e19ae Fix #425 2020-04-12 15:33:08 -04:00
Alexandre Taillefer ed8efea98b Added support for DELETE request body (#418)
* Added support for DELETE request body

* Fixed DELETE request body test case typo

Co-authored-by: Alexandre Taillefer <alexandre.taillefer@pwc.ca>
2020-04-07 15:51:52 -04:00
Max 1ccddd1b0b SSL_shutdown() only if not already closed by remote (#413) 2020-04-06 10:30:21 -04:00
yhirose 992f3dc690 Code cleanup 2020-04-03 09:33:29 -04:00
yhirose 402d47e2cd Fix #407 2020-03-31 19:42:53 -04:00
yhirose 171fc2e353 Fix #403. Added more status codes based on MDN document 2020-03-26 20:50:40 -04:00
SoenkeHeeren ced4160d05 add http status code 201 to show the right status message in return headers (#402) 2020-03-26 12:20:32 -04:00
yhirose 5b51aa6851 Revert "Add 1000-concurrency-result report"
This reverts commit b0af78e340.
2020-03-24 17:30:32 -04:00
Igor [hyperxor] dc13cde820 Minor improvements in httplib classes (#395) 2020-03-23 06:54:13 -04:00
yhirose b0af78e340 Add 1000-concurrency-result report 2020-03-21 15:49:26 +00:00
Andrew Gasparovic 914c8860e8 Accept content by value to allow moving
Previously, calling set_content always resulted in 's' being copied. With this change, there will still be the same number of copies made (1) when doing `set_content(my_value, ...)`, but there will be no copies if a caller elects to do `set_content(std::move(value), ...)` or `set_content(some_function_that_returns_a_temporary(), ...)` instead.
2020-03-21 00:39:07 -04:00
yhirose dc6a72a0fd Fix #387 2020-03-17 18:03:52 -04:00
yhirose 685533ba50 Fixed warnings on Windows due to max/min macro 2020-03-16 13:58:09 -04:00
yhirose 6e46ccb37c Updated README 2020-03-15 12:05:12 -04:00
Aristo Chen ac18b70a0f Update calculation formula for progress percentage (#386) 2020-03-15 08:29:27 -04:00
yhirose e1acb949e7 Fix #382 2020-03-13 18:43:29 -04:00
yhirose ab96f49766 Fixed problem that line end char is missing on start messagein simple
server example
2020-03-13 16:36:33 -04:00
Oleg Vorobiov 7b3cea5317 Prevent an implicit capture of 'this' via '[=]' (#381) 2020-03-12 12:31:22 -04:00
yhirose 26deffe0c6 Not to send 'EXCEPTION_WHAT' header to client 2020-03-10 17:44:36 -04:00
Rafael Leira e07c5fec01 simplest way to catch handler exceptions 2020-03-10 17:44:36 -04:00
miketsts 6e473a7c5c Fix conversion to ‘int’ from ‘long int’ warning (#377)
Co-authored-by: Michael Tseitlin <michael.tseitlin@concertio.com>
2020-03-10 14:48:14 -04:00
yhirose c74129a1c2 Fix #372 (#374) 2020-03-09 23:59:00 -04:00
yhirose 18e750b4e7 Code cleanup 2020-03-09 19:47:28 -04:00
Matthew DeVore bf7700d192 Fix exception that occurs with libc++ regex engine (#368)
The regex that parses header lines potentially causes an unlimited
amount of backtracking, which can cause an exception in the libc++ regex
engine.

The exception that occurs looks like this and is identical to the
message of the exception fixed in
https://github.com/yhirose/cpp-httplib/pull/280:

	libc++abi.dylib: terminating with uncaught exception of type
	std::__1::regex_error: The complexity of an attempted match
	against a regular expression exceeded a pre-set level.

This commit eliminates the problematic backtracking.
2020-02-28 06:31:39 -05:00
yhirose 3da925d6fe Adjusted a unit test. 2020-02-25 08:29:29 -05:00
yhirose 319417f26d Updated README 2020-02-24 21:50:07 -05:00
yhirose 4c3b119dde Code format 2020-02-24 21:17:02 -05:00
yhirose 6de8684328 Merge branch 'hyperxor-remove_code_duplication_in_getting_query' 2020-02-24 21:15:01 -05:00
hyperxor ccc9a9b3f4 Remove code duplication in converting params to query 2020-02-25 02:30:34 +03:00
rymis f2bb9c45d6 Support for deflate compression (#360) 2020-02-24 11:48:00 -05:00
yhirose 9a663aa94e Added a unit test. 2020-02-21 11:48:47 -05:00
yhirose d0d744d520 Fixed compiler warning with Visual C++. Close #358 2020-02-20 17:30:04 -05:00
yhirose fce8e6fefd Merge pull request #356 from samhocevar/fix-shadow-declarations
Fix a few shadowed variable compilation warnings.
2020-02-17 09:01:47 -05:00
Sam Hocevar 180aa32ebf Fix a few shadowed variable compilation warnings. 2020-02-17 06:58:30 +01:00
yhirose fe01fa760b Update README 2020-02-14 22:07:39 -05:00
yhirose d61d63dd97 Added unit tests for SSLServer::bind_to_any_port 2020-02-14 21:59:37 -05:00
yhirose 3fe13ecc91 Updated README 2020-02-14 21:49:09 -05:00
yhirose 064cc6810e Fix #352 2020-02-13 17:40:06 -05:00
yhirose 464cc89b77 Fix #351 2020-02-12 22:35:52 -05:00
yhirose ca5a50d2c9 Fix #349 2020-02-11 00:26:15 -05:00
yhirose b251668522 Fixed build problem. 2020-02-03 22:45:50 -05:00
yhirose 9ee740fe8f Updated README 2020-02-02 20:57:29 -05:00
yhirose 851edaf77f Code format 2020-02-02 20:02:16 -05:00
yhirose 1a2a6e2b01 Updated README 2020-02-01 09:24:42 -05:00
yhirose ac7742bb32 Changed the order of parameters of set_mounting_point. 2020-02-01 09:18:24 -05:00
yhirose 82c11168c1 Merge pull request #342 from yhirose/remove_mount_point
Fix #341
2020-01-31 20:41:39 -05:00
yhirose 7c5197c86c Updated README 2020-01-31 20:40:33 -05:00
yhirose 8801e51138 Fix #341 2020-01-31 20:35:20 -05:00
yhirose 89740a808d Added a contributor to README 2020-01-28 06:34:10 -05:00
yhirose 2377a20e0b Merge pull request #340 from vitalyster/head_static
HEAD support for static file server
2020-01-28 06:32:32 -05:00
Vitaly Takmazov 5e43680486 HEAD support for static file server 2020-01-28 12:00:27 +03:00
yhirose 79df842cc5 Updated README 2020-01-26 18:34:50 -05:00
yhirose 48a4a5812e Merge pull request #338 from TheMaverickProgrammer/master
fixed missing import
2020-01-25 20:44:59 -05:00
TheMaverickProgrammer a7a6df49a4 Update split.py 2020-01-25 17:19:15 -06:00
TheMaverickProgrammer e932c7e1ec Update split.py
now works with legacy Python ( < 3.0)
2020-01-25 17:17:34 -06:00
yhirose f94c3f1dc9 Updated README 2020-01-21 23:45:21 -05:00
yhirose 4d545cb932 Fix #335 2020-01-21 09:09:05 -05:00
yhirose f5e19faae7 Updated README 2020-01-17 23:21:42 -05:00
yhirose 2e360f9dd6 Improved Stream interface 2020-01-16 23:28:11 -05:00
yhirose e5ca863de5 Merge pull request #334 from vvanelslande/add_503
Add status message: 503 Service Unavailable
2020-01-16 06:59:31 -05:00
Valentin Vanelslande 126f1d177e Add status message: 503 Service Unavailable 2020-01-16 00:59:24 -05:00
yhirose b557ac9328 Code format 2020-01-14 17:04:51 -05:00
yhirose f6db19959f Merge pull request #333 from stupedama/master
std::thread::hardware_concurrency
2020-01-14 17:04:17 -05:00
yhirose 6b4df41b30 Fix #330 2020-01-14 17:02:25 -05:00
yhirose 0d81e20129 Fix #332 2020-01-14 14:59:20 -05:00
Fredrik Fjeldvær 26cb83ed6c if std::thread::hardware_concurrency() is 0 use 2 threads. also -1 thread because we already have one thread from the main function 2020-01-14 17:48:51 +01:00
yhirose b4f808da74 Updated example/upload.cc 2020-01-10 18:38:38 -05:00
yhirose 7fbb8bb3fd Merge pull request #326 from vvanelslande/add_202
Add status message for 202 Accepted
2020-01-10 18:37:38 -05:00
Valentin Vanelslande db27812198 Add status message for 202 Accepted 2020-01-10 17:50:37 -05:00
yhirose 6fe6fd5dbe Fixed build errors 2020-01-10 09:40:26 -05:00
yhirose 0ee9660f3d Code format 2020-01-10 09:35:07 -05:00
yhirose a15d16a9de Moved Stream concrete classes into detail namespace 2020-01-10 09:33:14 -05:00
yhirose dfebfd9033 Merge pull request #325 from rockwotj/master
Properly implement BufferStream::read
2020-01-10 07:54:15 -05:00
Tyler Rockwood fcdaa24fc5 Properly implement BufferStream::read
The existing implementation did not advance the buffer at all.
2020-01-09 22:05:59 -06:00
yhirose 7f749740f7 Merge pull request #324 from hyperxor/use_cpp_11_for_delays
Use sleep_for and chrono for delays in tests
2020-01-09 17:08:44 -05:00
hyperxor 7b4494748e fix indentation 2020-01-10 00:17:40 +03:00
hyperxor 7e1c107029 Use sleep_for and chrono for delays in tests 2020-01-10 00:15:18 +03:00
yhirose db7ae0ec21 Merge pull request #322 from hyperxor/fix_response_move
Fix suppressed Response class objects moving
2020-01-08 22:09:17 -05:00
hyperxor b16905ec8b Fix Response move 2020-01-08 23:13:04 +03:00
yhirose 2f72845008 Fix #319 2020-01-07 23:40:11 -05:00
yhirose 68aeb4a06a Merge pull request #317 from hyperxor/tiny_improvement_in_data_sink
Tiny improvement in DataSink class
2020-01-07 07:03:38 -05:00
hyperxor 568fda62b4 Tiny improvement in DataSink class 2020-01-07 13:25:04 +03:00
yhirose 04957c0f08 Fix #315 2020-01-06 17:13:31 -05:00
yhirose 96e9ec0663 Improved DataSink interface 2020-01-05 23:59:54 -05:00
yhirose c58fca5dba Added more tests 2020-01-03 07:57:40 -05:00
yhirose d2fae4031c Fixed build errors 2020-01-03 01:36:59 -05:00
yhirose de844e67ef Proxy support for Keep-Alive requests 2020-01-03 01:24:07 -05:00
yhirose 6c0e021554 Fixed socket leak 2020-01-02 17:01:02 -05:00
yhirose e8d33a77e0 Updated README 2020-01-02 13:08:40 -05:00
yhirose aa630e3062 Fix #311 2020-01-02 13:02:05 -05:00
yhirose 301a419c02 Updated README 2019-12-26 19:50:51 -05:00
yhirose fcbcbd53bd Fix #306 2019-12-26 18:48:22 -05:00
yhirose 1bf616d653 Fix #303 2019-12-26 17:50:53 -05:00
yhirose ba7c7dc4a3 Added linux to .travis.yaml 2019-12-24 22:46:32 -05:00
yhirose aa543240db Added test for post request with query string and body 2019-12-24 21:55:29 -05:00
yhirose 5675cad407 Added proxy test in Makefile 2019-12-22 21:07:26 -05:00
yhirose 079d3605ea Changed to use docker-compose for squid 2019-12-22 19:11:02 -05:00
yhirose 2c6da365d9 Merge pull request #300 from vvanelslande/accpet
Change Accpet-Encoding to Accept-Encoding
2019-12-22 15:39:47 -05:00
yhirose 38adeaf02c Fixed problem with proxy support and added unit tests 2019-12-22 15:37:01 -05:00
Valentin Vanelslande b3814b2b80 Change Accpet-Encoding to Accept-Encoding 2019-12-22 13:02:20 -05:00
yhirose a444b612af V0.5.0 2019-12-22 12:52:08 -05:00
yhirose ed6d949f42 Fix #299 2019-12-22 12:50:25 -05:00
yhirose d28cd3f937 Code cleanup 2019-12-21 23:20:30 -05:00
yhirose 8cc3e6c434 Merge pull request #296 from yhirose/connect
CONNECT method support on client
2019-12-21 23:09:10 -05:00
yhirose 26fbc1b7c0 Merge pull request #297 from hyperxor/fix_progress_redundant_copying
Fix redundant Progress copy in Get methods
2019-12-21 07:43:45 -05:00
hyperxor 0dc653f45a Fix redundant Progress copy in Get methods 2019-12-21 10:57:06 +03:00
yhirose 7a58c0a430 Updated README regarding regex issue in g++ 4.8 and below 2019-12-20 23:16:05 -05:00
yhirose dabaa51a7d Updated README 2019-12-20 23:12:24 -05:00
yhirose a1cfc0f377 Fixed problem with redirect 2019-12-20 13:25:11 -05:00
yhirose eb4fcb5003 CONNECT method support on client 2019-12-20 06:59:59 -05:00
yhirose ae43c96984 Merge pull request #295 from yhirose/timeout
Fix #294
2019-12-18 17:57:23 -05:00
yhirose 9c81693801 Fix #294 2019-12-18 17:47:36 -05:00
yhirose 80202c9f62 Merge pull request #292 from Bendr0id/fix_socket_create_on_older_windows_systems
Adds workaround for socket creation on older Windows variants
2019-12-18 07:09:48 -05:00
Ben Gräf 094a6a614a Adds workaround for socket creation on older Windows variants
Since the WSA_FLAG_NO_HANDLE_INHERIT is only supported on Windows 7 SP1 and above the socket creation fails on older Windows Systems.
     
Let's try to create a socket the old way in this case.
     
Reference:
https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa
     
WSA_FLAG_NO_HANDLE_INHERIT:
This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
2019-12-18 07:49:36 +01:00
yhirose 39c7bba7b9 Code cleanup 2019-12-17 13:05:08 -05:00
yhirose f2476f21fc Fixed URL encoding problem when sending a request to proxy 2019-12-17 12:58:25 -05:00
yhirose c776454c84 Updated README 2019-12-15 20:31:36 -05:00
yhirose 82a5ac735f Merge pull request #290 from yhirose/interface
Fix #285. Added set_interface method on client
2019-12-15 18:02:51 -05:00
yhirose 08bf806e92 Updated README 2019-12-15 17:55:08 -05:00
yhirose 9a41b16cbb Fix #285. Added set_interface method on client 2019-12-15 17:44:00 -05:00
yhirose 10759f0a38 Updated README 2019-12-15 00:21:32 -05:00
yhirose 58b2814fda Format code 2019-12-14 23:50:53 -05:00
yhirose 260422b7d7 Format code 2019-12-14 23:46:11 -05:00
yhirose d2c7b447d5 Fix #289: Fixed build problem with Visual C++ 2019-12-13 09:12:50 -05:00
yhirose 72b20c08da Better API names 2019-12-13 06:56:00 -05:00
yhirose afd6d5f9dc Removed compress parameter and added compress method on client 2019-12-12 23:09:59 -05:00
yhirose e5827ad16f Fixed build error 2019-12-12 23:09:34 -05:00
yhirose 5324b3d661 Improved multipart form data interface 2019-12-12 22:48:09 -05:00
yhirose 151ccba57e Code cleanup 2019-12-12 21:50:12 -05:00
yhirose 69a28d50f6 Fix #287 2019-12-12 12:50:45 -05:00
Yuji Hirose 048f31109f Updated README 2019-12-10 13:14:23 -05:00
Yuji Hirose d064fb7ff2 Fixed warning 2019-12-10 13:08:07 -05:00
Yuji Hirose 3c2736bb2a Fixed regex syntax error 2019-12-10 13:07:49 -05:00
Yuji Hirose fd4e1b4112 Fix #266 2019-12-10 12:10:14 -05:00
yhirose f6a2365ca5 Fix #282 2019-12-06 12:21:15 -05:00
yhirose df1ff7510b Made code more readable 2019-12-06 12:02:08 -05:00
yhirose 379905bd34 Merge branch 'whitespace-and-libcxx-compat' of https://github.com/matvore/cpp-httplib 2019-12-06 09:51:21 -05:00
yhirose 66719ae3d4 Merge pull request #283 from barryam3/noexcept
Remove use of exceptions.
2019-12-05 21:32:06 -05:00
Matthew DeVore bc9251ea49 Work around incompatibility in <regex> in libc++
libc++ (the implementation of the C++ standard library usually used by
Clang) throws an exception for the regex used by parse_headers before
this patch for certain strings. Work around this by simplifying the
regex and parsing the header lines "by hand" partially. I have repro'd
this problem with Xcode 11.1 which I believe uses libc++ version 8.

This may be a bug in libc++ as I can't see why the regex would result in
asymptotic run-time complexity for any strings. However, it may take a
while for libc++ to be fixed and for everyone to migrate to it, so it
makes sense to work around it in this codebase for now.
2019-12-05 17:14:16 -08:00
Matthew DeVore a9e942d755 Properly trim whitespace from headers
HTTP Whitespace and regex whitespace are not the same, so we can't use
\s in regexes when parsing HTTP headers. Instead, explicitly specify
what is considered whitespace in the regex.
2019-12-05 17:14:16 -08:00
Barry McNamara e1785d6723 Remove use of exceptions. 2019-12-05 15:56:55 -08:00
yhirose b9539b8921 Fixed build errors 2019-12-03 10:30:07 -05:00
yhirose 4c93b973ff Fixed typo in README 2019-12-02 09:50:52 -05:00
yhirose 033bc35723 Improve multipart content reader interface 2019-12-02 07:11:12 -05:00
yhirose d910bfc303 Merge pull request #279 from yhirose/multipart
Content receiver support for multipart content (Fix #241)
2019-12-01 22:12:29 -05:00
yhirose b69c0a1dcb Content receiver support for multipart content (Fix #241) 2019-12-01 22:04:26 -05:00
yhirose 5e37e38398 Updated README 2019-11-29 23:33:19 -05:00
yhirose 295e4d58aa Fix #276 2019-11-29 17:07:51 -05:00
yhirose 448de6a9c6 Added upload example 2019-11-28 18:51:05 -05:00
yhirose 6f58dc728f Fixed problem with requests with no content 2019-11-28 08:28:01 -05:00
yhirose 905f2d84f4 Updated README 2019-11-27 22:53:06 -05:00
yhirose 880f7fa62b Fix #273 2019-11-27 12:54:01 -05:00
yhirose 8f3dbf7f21 Code cleanup 2019-11-27 08:01:25 -05:00
yhirose 924a557fa3 Changed to use 'using' instead of 'typedef' 2019-11-27 07:03:17 -05:00
yhirose d8da740597 Fix #270 2019-11-26 08:48:17 -05:00
yhirose d45676b064 Added NoThread task queue 2019-11-25 13:00:37 -05:00
Hirose Family 94d13e88a5 Fixed regex problem with Apple LLVM version 8.0.0 2019-11-03 19:27:12 -05:00
yhirose 4f9d04cb8e Merge pull request #257 from danielzehe/master
Update README.md
2019-11-01 07:07:30 -04:00
Daniel Zehe 9fb11986a5 Update README.md
added return true to the content provider get example, doesn't compile without it
2019-11-01 14:35:17 +08:00
yhirose 55d04ee354 Merge pull request #256 from Zefz/modernize-code-2
Modernize code 2
2019-10-31 21:17:35 -04:00
Johan Jansen a62a48a7b5 Modernize some additional code 2019-10-31 21:49:04 +01:00
Johan Jansen c652919954 Do not use shared_ptr where not required 2019-10-31 21:48:48 +01:00
Johan Jansen 58753ba33c Fix some virtual override warnings 2019-10-31 21:38:37 +01:00
yhirose 5706828d2c Replace C-style arrays and fix static-code analysis warnings 2019-10-31 21:32:07 +01:00
yhirose e743b8cd57 Fix #254 2019-10-30 08:21:59 -04:00
yhirose 9d57899352 Simplified ContentReceiver interface 2019-10-27 23:38:56 -04:00
yhirose d03937e144 Content receiver support on server 2019-10-27 23:20:56 -04:00
yhirose 8fb37a449d Fix #251 2019-10-27 17:27:57 -04:00
yhirose f0b1b5dbfd Added set_read_timeout. Fix #248. 2019-10-27 14:57:22 -04:00
yhirose 5f32c424c2 Content provider support on client 2019-10-25 18:39:04 -04:00
yhirose f0683f2301 Fixed build errors 2019-10-25 13:11:49 -04:00
yhirose 0d527e2b83 Code formatting 2019-10-25 12:09:26 -04:00
yhirose bea3ebd7af Added 'compress' option to POST, PUT and PATCH. 2019-10-25 11:46:12 -04:00
yhirose 380f725713 Code format 2019-10-24 22:20:42 -04:00
yhirose a106bd314c Merge branch 'master' of https://github.com/yhirose/cpp-httplib 2019-10-23 08:30:49 -04:00
yhirose e4fd9f19ca Updated Makefile 2019-10-23 08:28:15 -04:00
yhirose dfc01338eb Merge branch 'master' of https://github.com/yhirose/cpp-httplib 2019-10-23 08:15:59 -04:00
yhirose c4ebc31345 Merge pull request #246 from BastienDurel/htm
html files may be .htm
2019-10-23 07:06:28 -04:00
Bastien Durel d1abf96581 html files may be .htm 2019-10-23 09:52:21 +02:00
yhirose 001b8a5529 Added unit tests 2019-10-22 23:32:14 -04:00
yhirose 7a3abd2768 Merge pull request #243 from Sil3ntStorm/patch1
Allow use of OpenSSL 1.1.1, fix compile errors
2019-10-20 10:12:14 -04:00
yhirose 4a52524f47 Merge pull request #244 from aaronalbers/aa_bind_to_port_
Added bind_to_port()
2019-10-19 22:19:25 -04:00
Aaron Albers 89e1e9b8fe Added bind_to_port()
- This compliments the existing `bind_to_any_port()`
  where you can determine if the bind succeeded prior
  to calling `listen_after_bind()` but allows you to
  specify the port.
2019-10-19 10:41:19 -06:00
Sil3ntStorm 98d16eb836 Allow use of OpenSSL 1.1.1, fix compile errors 2019-10-19 16:40:06 +02:00
yhirose bcf0c32245 Updated README.md. (FIx #239 and #240) 2019-10-15 10:24:47 -04:00
yhirose dcdb0d047b Fixed PRI request problem 2019-10-03 13:44:18 -04:00
yhirose 1f86e41d97 Changed back to select as default 2019-10-03 13:44:18 -04:00
yhirose 6d8302313c Fixed warning 2019-10-03 13:44:18 -04:00
yhirose 89440ec322 Merge pull request #232 from sux2mfgj/fix_the_invalidhost_test
Fix a test, ConnectionErrorTest::InvalidPort.
2019-10-03 13:43:48 -04:00
yhirose 5edf455d72 Merge pull request #231 from sux2mfgj/fix_the_sample
Fix a sample code of multipart/form-data POST data in the README.md.
2019-10-03 13:42:31 -04:00
Shunsuke Mie 5f49c13f95 Fix a test, ConnectionErrorTest::InvalidPort. currently, the abcde.com is valid, so I change it. The first byte doesn't permit a hyphen. 2019-10-03 21:49:11 +09:00
Shunsuke Mie 760bccc3ad fix a sample code of multipart/form-data POST data in README.md. 2019-10-03 21:23:10 +09:00
yhirose a99e02aeb3 Add HTTP/2 Connection Preface check test 2019-10-01 06:28:45 -04:00
yhirose 4aae1dcc42 Merge pull request #224 from Zefz/configuration
Allow configuration to be overriden without source editing
2019-09-30 17:07:21 -04:00
Johan Jansen f23f9a06a9 Allow configuration to be overriden without source editing 2019-09-30 22:00:17 +02:00
yhirose 46466b1e28 Merge pull request #227 from ha11owed/master
Don't exit if accept fails due to no more file descriptors
2019-09-30 07:47:27 -04:00
Alin Gherman 224119a60a Retry in case of too many sockets opened instead of stopping the server. 2019-09-30 11:48:02 +02:00
yhirose c02849e269 Removed CPPHTTPLIB_USE_POLL, added CPPHTTPLIB_USE_SELECT 2019-09-29 19:43:22 -04:00
yhirose 71979b1e88 Merge pull request #226 from Zefz/mingw-compile-fix
Fix compilation on Mingw-64
2019-09-27 17:29:33 -04:00
yhirose a62d1f79f4 Merge pull request #225 from TangHuaiZhe/master
Fix compile error in android ndk
2019-09-27 17:29:07 -04:00
zefz b14b7b0f8f Fix compilation on Mingw-64 2019-09-27 20:23:16 +02:00
Tang Huaizhe 9dbe0d855c Fix compile error in android ndk 2019-09-27 13:32:23 +08:00
yhirose 2cef8df6ae Merge pull request #223 from Zefz/cpp-style-cast
Fix several -Wold-style-cast warnings in Clang-9
2019-09-26 19:00:45 -04:00
Johan Jansen 94fc229c44 Add missing explicit const_cast 2019-09-26 22:20:33 +02:00
Johan Jansen a7052cba22 Fix several -Wold-style-cast warnings in Clang-9 2019-09-26 22:03:18 +02:00
yhirose c47c6b3910 Updated test.vcxproj 2019-09-26 13:20:53 -04:00
yhirose c946eb7699 Fixed warnings on Windows 2019-09-26 08:13:20 -04:00
yhirose 1f99ad5d6e Updated vcxproj for test 2019-09-25 08:16:15 -04:00
yhirose 96e372bad2 Changed test.yaml to use actions/checkout@v1 2019-09-20 01:07:09 -04:00
yhirose fc56f39d17 Fixed Github Actions badge problem 2019-09-20 00:43:02 -04:00
yhirose 5844432a7b Add badge for Github Actions 2019-09-20 00:31:26 -04:00
yhirose b97420f363 Add test.yaml 2019-09-20 00:01:05 -04:00
yhirose 81610ee080 Merge pull request #218 from p0lloloco/master
Add ssl_context member function to SSLClient
2019-09-18 23:08:14 -04:00
PolloLoco c7f8561472 Added ssl_context member function to SSLClient in
order to allow access to the SSL_CTX struct, for
example to load the windows cert store
2019-09-18 15:10:15 +02:00
yhirose 47bc7456d2 Merge pull request #217 from yhirose/poll
Use 'poll' instead of 'select'
2019-09-18 08:46:20 -04:00
yhirose 4ab9270660 Use 'poll' as default instead of select (Fix #215) 2019-09-18 08:42:18 -04:00
yhirose d599a36c2a Format code 2019-09-16 17:48:17 -04:00
yhirose 6f8f51496d Merge branch 'gulrak-feature-response-handler-with-content-receiver' 2019-09-15 09:17:26 -04:00
yhirose 0c293887d0 Fixed problem with redirect 2019-09-15 09:15:21 -04:00
Steffen Schuemann 7e92ffec48 Added new Client::Get variant that combines a ContentReceiver with a new ResponseHandler
While trying to implement streaming of internet radio, where a ContentReceiver is needed to handle the audio data, I had the problem, that important information about the stream data is part of the HTTP header (e.g. size of audio chunks between meta data), so I added a ResponseHandler and a new Get variant, to gain access to the header before handling the first chunk of data.

The ResponseHandler can abort the request by returning false, in the same way as the ContentReceiver.

A test case was also added.
2019-09-14 14:55:12 +02:00
yhirose 531708816a Update README 2019-09-06 18:29:22 -04:00
yhirose bfec81998b Code cleanup 2019-09-06 18:16:42 -04:00
yhirose c9238434e1 Added redirect support (Fix #211) 2019-09-06 18:07:35 -04:00
48 changed files with 11175 additions and 2069 deletions
+5
View File
@@ -0,0 +1,5 @@
BasedOnStyle: LLVM
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
Cpp11BracedListStyle: true
+41
View File
@@ -0,0 +1,41 @@
name: test
on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macOS-latest, ubuntu-latest, windows-latest]
steps:
- name: prepare git for checkout on windows
if: matrix.os == 'windows-latest'
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: checkout
uses: actions/checkout@v2
- name: install brotli library on ubuntu
if: matrix.os == 'ubuntu-latest'
run: sudo apt update && sudo apt-get install -y libbrotli-dev
- name: install brotli library on macOS
if: matrix.os == 'macOS-latest'
run: brew install brotli
- name: make
if: matrix.os != 'windows-latest'
run: cd test && make
- name: check fuzz test target
if: matrix.os == 'ubuntu-latest'
run: cd test && make -f Makefile.fuzz_test
- name: setup msbuild on windows
if: matrix.os == 'windows-latest'
uses: microsoft/setup-msbuild@v1.0.2
- name: make-windows
if: matrix.os == 'windows-latest'
run: |
cd test
msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64"
x64\Release\test.exe
+4
View File
@@ -3,11 +3,15 @@ tags
example/server
example/client
example/hello
example/simplecli
example/simplesvr
example/benchmark
example/redirect
example/sse*
example/upload
example/*.pem
test/test
test/test_proxy
test/test.xcodeproj/xcuser*
test/test.xcodeproj/*/xcuser*
test/*.pem
-13
View File
@@ -1,13 +0,0 @@
# Environment
language: cpp
os:
- osx
# Compiler selection
compiler:
- clang
# Build/test steps
script:
- cd ${TRAVIS_BUILD_DIR}/test
- make all
+299 -19
View File
@@ -1,29 +1,309 @@
cmake_minimum_required(VERSION 3.7.0)
project(httplib)
#[[
Build options:
* BUILD_SHARED_LIBS (default off) builds as a shared library (if HTTPLIB_COMPILE is ON)
* HTTPLIB_USE_OPENSSL_IF_AVAILABLE (default on)
* HTTPLIB_USE_ZLIB_IF_AVAILABLE (default on)
* HTTPLIB_REQUIRE_OPENSSL (default off)
* HTTPLIB_REQUIRE_ZLIB (default off)
* HTTPLIB_USE_BROTLI_IF_AVAILABLE (default on)
* HTTPLIB_REQUIRE_BROTLI (default off)
* HTTPLIB_COMPILE (default off)
* BROTLI_USE_STATIC_LIBS - tells Cmake to use the static Brotli libs (only works if you have them installed).
* OPENSSL_USE_STATIC_LIBS - tells Cmake to use the static OpenSSL libs (only works if you have them installed).
set(CMAKE_CXX_STANDARD 11)
-------------------------------------------------------------------------------
# Include
After installation with Cmake, a find_package(httplib) is available.
This creates a httplib::httplib target (if found).
It can be linked like so:
target_link_libraries(your_exe httplib::httplib)
The following will build & install for later use.
Linux/macOS:
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo cmake --build . --target install
Windows:
mkdir build
cd build
cmake ..
runas /user:Administrator "cmake --build . --config Release --target install"
-------------------------------------------------------------------------------
These variables are available after you run find_package(httplib)
* HTTPLIB_HEADER_PATH - this is the full path to the installed header (e.g. /usr/include/httplib.h).
* HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled.
* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
* HTTPLIB_IS_USING_BROTLI - a bool for if Brotli support is enabled.
* HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only.
* HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include).
* HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so).
* httplib_VERSION or HTTPLIB_VERSION - the project's version string.
* HTTPLIB_FOUND - a bool for if the target was found.
Want to use precompiled headers (Cmake feature since v3.16)?
It's as simple as doing the following (before linking):
target_precompile_headers(httplib::httplib INTERFACE "${HTTPLIB_HEADER_PATH}")
-------------------------------------------------------------------------------
FindPython3 requires Cmake v3.12
ARCH_INDEPENDENT option of write_basic_package_version_file() requires Cmake v3.14
]]
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
# On systems without Git installed, there were errors since execute_process seemed to not throw an error without it?
find_package(Git QUIET)
if(Git_FOUND)
# Gets the latest tag as a string like "v0.6.6"
# Can silently fail if git isn't on the system
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE _raw_version_string
ERROR_VARIABLE _git_tag_error
)
endif()
# execute_process can fail silenty, so check for an error
# if there was an error, just use the user agent as a version
if(_git_tag_error OR NOT Git_FOUND)
message(WARNING "cpp-httplib failed to find the latest Git tag, falling back to using user agent as the version.")
# Get the user agent and use it as a version
# This gets the string with the user agent from the header.
# This is so the maintainer doesn't actually need to update this manually.
file(STRINGS httplib.h _raw_version_string REGEX "User\-Agent.*cpp\-httplib/([0-9]+\.?)+")
endif()
# Needed since git tags have "v" prefixing them.
# Also used if the fallback to user agent string is being used.
string(REGEX MATCH "([0-9]+\\.?)+" _httplib_version "${_raw_version_string}")
project(httplib VERSION ${_httplib_version} LANGUAGES CXX)
# Change as needed to set an OpenSSL minimum version.
# This is used in the installed Cmake config file.
set(_HTTPLIB_OPENSSL_MIN_VER "1.1.1")
# Allow for a build to require OpenSSL to pass, instead of just being optional
option(HTTPLIB_REQUIRE_OPENSSL "Requires OpenSSL to be found & linked, or fails build." OFF)
option(HTTPLIB_REQUIRE_ZLIB "Requires ZLIB to be found & linked, or fails build." OFF)
# Allow for a build to casually enable OpenSSL/ZLIB support, but silenty continue if not found.
# Make these options so their automatic use can be specifically disabled (as needed)
option(HTTPLIB_USE_OPENSSL_IF_AVAILABLE "Uses OpenSSL (if available) to enable HTTPS support." ON)
option(HTTPLIB_USE_ZLIB_IF_AVAILABLE "Uses ZLIB (if available) to enable Zlib compression support." ON)
# Lets you compile the program as a regular library instead of header-only
option(HTTPLIB_COMPILE "If ON, uses a Python script to split the header into a compilable header & source file (requires Python v3)." OFF)
# Just setting this variable here for people building in-tree
if(HTTPLIB_COMPILE)
set(HTTPLIB_IS_COMPILED TRUE)
endif()
option(HTTPLIB_REQUIRE_BROTLI "Requires Brotli to be found & linked, or fails build." OFF)
option(HTTPLIB_USE_BROTLI_IF_AVAILABLE "Uses Brotli (if available) to enable Brotli decompression support." ON)
# Defaults to static library
option(BUILD_SHARED_LIBS "Build the library as a shared library instead of static. Has no effect if using header-only." OFF)
if (BUILD_SHARED_LIBS AND WIN32 AND HTTPLIB_COMPILE)
# Necessary for Windows if building shared libs
# See https://stackoverflow.com/a/40743080
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
find_package(Threads REQUIRED)
# Since Cmake v3.11, Crypto & SSL became optional when not specified as COMPONENTS.
if(HTTPLIB_REQUIRE_OPENSSL)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL REQUIRED)
elseif(HTTPLIB_USE_OPENSSL_IF_AVAILABLE)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL QUIET)
endif()
# Just setting this variable here for people building in-tree
if(OPENSSL_FOUND)
set(HTTPLIB_IS_USING_OPENSSL TRUE)
endif()
if(HTTPLIB_REQUIRE_ZLIB)
find_package(ZLIB REQUIRED)
elseif(HTTPLIB_USE_ZLIB_IF_AVAILABLE)
find_package(ZLIB QUIET)
endif()
# Just setting this variable here for people building in-tree
# FindZLIB doesn't have a ZLIB_FOUND variable, so check the target.
if(TARGET ZLIB::ZLIB)
set(HTTPLIB_IS_USING_ZLIB TRUE)
endif()
# Adds our cmake folder to the search path for find_package
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(HTTPLIB_REQUIRE_BROTLI)
find_package(Brotli COMPONENTS encoder decoder common REQUIRED)
elseif(HTTPLIB_USE_BROTLI_IF_AVAILABLE)
find_package(Brotli COMPONENTS encoder decoder common QUIET)
endif()
# Just setting this variable here for people building in-tree
if(Brotli_FOUND)
set(HTTPLIB_IS_USING_BROTLI TRUE)
endif()
# Used for default, common dirs that the end-user can change (if needed)
# like CMAKE_INSTALL_INCLUDEDIR or CMAKE_INSTALL_DATADIR
include(GNUInstallDirs)
include(ExternalProject)
add_library(${PROJECT_NAME} INTERFACE)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11)
if(HTTPLIB_COMPILE)
# Put the split script into the build dir
configure_file(split.py "${CMAKE_CURRENT_BINARY_DIR}/split.py"
COPYONLY
)
# Needs to be in the same dir as the python script
configure_file(httplib.h "${CMAKE_CURRENT_BINARY_DIR}/httplib.h"
COPYONLY
)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
# Used outside of this if-else
set(_INTERFACE_OR_PUBLIC PUBLIC)
# Brings in the Python3_EXECUTABLE path we can use.
find_package(Python3 REQUIRED)
# Actually split the file
# Keeps the output in the build dir to not pollute the main dir
execute_process(COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/split.py"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ERROR_VARIABLE _httplib_split_error
)
if(_httplib_split_error)
message(FATAL_ERROR "Failed when trying to split Cpp-httplib with the Python script.\n${_httplib_split_error}")
endif()
install(TARGETS ${PROJECT_NAME} EXPORT httplibConfig
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
# split.py puts output in "out"
set(_httplib_build_includedir "${CMAKE_CURRENT_BINARY_DIR}/out")
# This will automatically be either static or shared based on the value of BUILD_SHARED_LIBS
add_library(${PROJECT_NAME} "${_httplib_build_includedir}/httplib.cc")
target_sources(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${_httplib_build_includedir}/httplib.h>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/httplib.h>
)
else()
# This is for header-only.
set(_INTERFACE_OR_PUBLIC INTERFACE)
add_library(${PROJECT_NAME} INTERFACE)
set(_httplib_build_includedir "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
# Lets you address the target with httplib::httplib
# Only useful if building in-tree, versus using it from an installation.
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
install(FILES httplib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
# Might be missing some, but this list is somewhat comprehensive
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
cxx_std_11
cxx_nullptr
cxx_lambdas
cxx_override
cxx_defaulted_functions
cxx_attribute_deprecated
cxx_auto_type
cxx_decltype
cxx_deleted_functions
cxx_range_for
cxx_sizeof_member
)
install(EXPORT httplibConfig DESTINATION share/httplib/cmake)
target_include_directories(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
$<BUILD_INTERFACE:${_httplib_build_includedir}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
export(TARGETS ${PROJECT_NAME} FILE httplibConfig.cmake)
# Always require threads
target_link_libraries(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
Threads::Threads
# Needed for Windows libs on Mingw, as the pragma comment(lib, "xyz") aren't triggered.
$<$<PLATFORM_ID:Windows>:ws2_32>
$<$<PLATFORM_ID:Windows>:crypt32>
$<$<PLATFORM_ID:Windows>:cryptui>
# Can't put multiple targets in a single generator expression or it bugs out.
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::common>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::encoder>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::decoder>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:ZLIB::ZLIB>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::SSL>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::Crypto>
)
#add_subdirectory(example)
#add_subdirectory(test)
# Set the definitions to enable optional features
target_compile_definitions(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:CPPHTTPLIB_BROTLI_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:CPPHTTPLIB_ZLIB_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:CPPHTTPLIB_OPENSSL_SUPPORT>
)
# Cmake's find_package search path is different based on the system
# See https://cmake.org/cmake/help/latest/command/find_package.html for the list
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/cmake/${PROJECT_NAME}")
else()
# On Non-Windows, it should be /usr/lib/cmake/<name>/<name>Config.cmake
# NOTE: This may or may not work for macOS...
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
endif()
include(CMakePackageConfigHelpers)
# Configures the meta-file httplibConfig.cmake.in to replace variables with paths/values/etc.
configure_package_config_file("${PROJECT_NAME}Config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${_TARGET_INSTALL_CMAKEDIR}"
# Passes the includedir install path
PATH_VARS CMAKE_INSTALL_FULL_INCLUDEDIR
# There aren't any components, so don't use the macro
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
if(HTTPLIB_COMPILE)
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5 and <= 1.0 is accepted
COMPATIBILITY SameMajorVersion
)
else()
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5 and <= 1.0 is accepted
COMPATIBILITY SameMajorVersion
# Tells Cmake that it's a header-only lib
# Mildly useful for end-users :)
ARCH_INDEPENDENT
)
endif()
# Creates the export httplibTargets.cmake
# This is strictly what holds compilation requirements
# and linkage information (doesn't find deps though).
install(TARGETS ${PROJECT_NAME}
EXPORT httplibTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES "${_httplib_build_includedir}/httplib.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
# Install it so it can be used later by the httplibConfig.cmake file.
# Put it in the same dir as our config file instead of a global path so we don't potentially stomp on other packages.
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindBrotli.cmake"
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
# NOTE: This path changes depending on if it's on Windows or Linux
install(EXPORT httplibTargets
# Puts the targets into the httplib namespace
# So this makes httplib::httplib linkable after doing find_package(httplib)
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
+542 -126
View File
@@ -1,39 +1,94 @@
cpp-httplib
===========
[![Build Status](https://travis-ci.org/yhirose/cpp-httplib.svg?branch=master)](https://travis-ci.org/yhirose/cpp-httplib)
[![Bulid Status](https://ci.appveyor.com/api/projects/status/github/yhirose/cpp-httplib?branch=master&svg=true)](https://ci.appveyor.com/project/yhirose/cpp-httplib)
[![](https://github.com/yhirose/cpp-httplib/workflows/test/badge.svg)](https://github.com/yhirose/cpp-httplib/actions)
A C++ single-file header-only cross platform HTTP/HTTPS library.
A C++11 single-file header-only cross platform HTTP/HTTPS library.
It's extremely easy to setup. Just include **httplib.h** file in your code!
It's extremely easy to setup. Just include the **httplib.h** file in your code!
Server Example
--------------
NOTE: This is a multi-threaded 'blocking' HTTP library. If you are looking for a 'non-blocking' library, this is not the one that you want.
Simple examples
---------------
#### Server
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Server svr;
// HTTPS
httplib::SSLServer svr;
svr.Get("/hi", [](const httplib::Request &, httplib::Response &res) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("0.0.0.0", 8080);
```
#### Client
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Client cli("http://cpp-httplib-server.yhirose.repl.co");
// HTTPS
httplib::Client cli("https://cpp-httplib-server.yhirose.repl.co");
auto res = cli.Get("/hi");
res->status;
res->body;
```
### Try out the examples on Repl.it!
1. Run server at https://repl.it/@yhirose/cpp-httplib-server
2. Run client at https://repl.it/@yhirose/cpp-httplib-client
Server
------
```c++
#include <httplib.h>
int main(void)
{
using namespace httplib;
using namespace httplib;
Server svr;
Server svr;
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
svr.Get("/body-header-param", [](const Request& req, Response& res) {
if (req.has_header("Content-Length")) {
auto val = req.get_header_value("Content-Length");
}
if (req.has_param("key")) {
auto val = req.get_param_value("key");
}
res.set_content(req.body, "text/plain");
});
svr.listen("localhost", 1234);
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
svr.listen("localhost", 1234);
}
```
@@ -49,25 +104,109 @@ svr.listen_after_bind();
### Static File Server
```cpp
svr.set_base_dir("./www");
// Mount / to ./www directory
auto ret = svr.set_mount_point("/", "./www");
if (!ret) {
// The specified base directory doesn't exist...
}
// Mount /public to ./www directory
ret = svr.set_mount_point("/public", "./www");
// Mount /public to ./www1 and ./www2 directories
ret = svr.set_mount_point("/public", "./www1"); // 1st order to search
ret = svr.set_mount_point("/public", "./www2"); // 2nd order to search
// Remove mount /
ret = svr.remove_mount_point("/");
// Remove mount /public
ret = svr.remove_mount_point("/public");
```
```cpp
// User defined file extension and MIME type mappings
svr.set_file_extension_and_mimetype_mapping("cc", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("cpp", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("hh", "text/x-h");
```
The followings are built-in mappings:
| Extension | MIME Type | Extension | MIME Type |
| :--------- | :-------------------------- | :--------- | :-------------------------- |
| css | text/css | mpga | audio/mpeg |
| csv | text/csv | weba | audio/webm |
| txt | text/plain | wav | audio/wave |
| vtt | text/vtt | otf | font/otf |
| html, htm | text/html | ttf | font/ttf |
| apng | image/apng | woff | font/woff |
| avif | image/avif | woff2 | font/woff2 |
| bmp | image/bmp | 7z | application/x-7z-compressed |
| gif | image/gif | atom | application/atom+xml |
| png | image/png | pdf | application/pdf |
| svg | image/svg+xml | mjs, js | application/javascript |
| webp | image/webp | json | application/json |
| ico | image/x-icon | rss | application/rss+xml |
| tif | image/tiff | tar | application/x-tar |
| tiff | image/tiff | xhtml, xht | application/xhtml+xml |
| jpeg, jpg | image/jpeg | xslt | application/xslt+xml |
| mp4 | video/mp4 | xml | application/xml |
| mpeg | video/mpeg | gz | application/gzip |
| webm | video/webm | zip | application/zip |
| mp3 | audio/mp3 | wasm | application/wasm |
NOTE: These static file server methods are not thread-safe.
### Logging
```cpp
svr.set_logger([](const auto& req, const auto& res) {
your_logger(req, res);
your_logger(req, res);
});
```
### Error Handler
### Error handler
```cpp
svr.set_error_handler([](const auto& req, auto& res) {
const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
auto fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
```
### Exception handler
The exception handler gets called if a user routing handler throws an error.
```cpp
svr.set_exception_handler([](const auto& req, auto& res, std::exception &e) {
res.status = 500;
auto fmt = "<h1>Error 500</h1><p>%s</p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, e.what());
res.set_content(buf, "text/html");
});
```
### Pre routing handler
```cpp
svr.set_pre_routing_handler([](const auto& req, auto& res) -> bool {
if (req.path == "/hello") {
res.set_content("world", "text/html");
return Server::HandlerResponse::Handled;
}
return Server::HandlerResponse::Unhandled;
});
```
### Post routing handler
```cpp
svr.set_post_routing_handler([](const auto& req, auto& res) {
res.set_header("ADDITIONAL_HEADER", "value");
});
```
@@ -75,30 +214,78 @@ svr.set_error_handler([](const auto& req, auto& res) {
```cpp
svr.Post("/multipart", [&](const auto& req, auto& res) {
auto size = req.files.size();
auto ret = req.has_file("name1"));
const auto& file = req.get_file_value("name1");
// file.filename;
// file.content_type;
auto body = req.body.substr(file.offset, file.length));
})
auto size = req.files.size();
auto ret = req.has_file("name1");
const auto& file = req.get_file_value("name1");
// file.filename;
// file.content_type;
// file.content;
});
```
### Stream content with Content provider
### Receive content with a content receiver
```cpp
const uint64_t DATA_CHUNK_SIZE = 4;
svr.Post("/content_receiver",
[&](const Request &req, Response &res, const ContentReader &content_reader) {
if (req.is_multipart_form_data()) {
MultipartFormDataItems files;
content_reader(
[&](const MultipartFormData &file) {
files.push_back(file);
return true;
},
[&](const char *data, size_t data_length) {
files.back().content.append(data, data_length);
return true;
});
} else {
std::string body;
content_reader([&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
res.set_content(body, "text/plain");
}
});
```
### Send content with the content provider
```cpp
const size_t DATA_CHUNK_SIZE = 4;
svr.Get("/stream", [&](const Request &req, Response &res) {
auto data = new std::string("abcdefg");
res.set_content_provider(
data->size(), // Content length
[data](uint64_t offset, uint64_t length, Out out) {
"text/plain", // Content type
[data](size_t offset, size_t length, DataSink &sink) {
const auto &d = *data;
out(&d[offset], std::min(length, DATA_CHUNK_SIZE));
sink.write(&d[offset], std::min(length, DATA_CHUNK_SIZE));
return true; // return 'false' if you want to cancel the process.
},
[data] { delete data; });
[data](bool success) { delete data; });
});
```
Without content length:
```cpp
svr.Get("/stream", [&](const Request &req, Response &res) {
res.set_content_provider(
"text/plain", // Content type
[&](size_t offset, size_t length, DataSink &sink) {
if (/* there is still data */) {
std::vector<char> data;
// prepare data...
sink.write(data.data(), data.size());
} else {
sink.done(); // No more data
}
return true; // return 'false' if you want to cancel the process.
});
});
```
@@ -107,32 +294,75 @@ svr.Get("/stream", [&](const Request &req, Response &res) {
```cpp
svr.Get("/chunked", [&](const Request& req, Response& res) {
res.set_chunked_content_provider(
[](uint64_t offset, Out out, Done done) {
out("123", 3);
out("345", 3);
out("789", 3);
done();
"text/plain",
[](size_t offset, DataSink &sink) {
sink.write("123", 3);
sink.write("345", 3);
sink.write("789", 3);
sink.done(); // No more data
return true; // return 'false' if you want to cancel the process.
}
);
});
```
### Default thread pool supporet
### 'Expect: 100-continue' handler
Set thread count to 8:
By default, the server sends a `100 Continue` response for an `Expect: 100-continue` header.
```cpp
#define CPPHTTPLIB_THREAD_POOL_COUNT 8
// Send a '417 Expectation Failed' response.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return 417;
});
```
Disable the default thread pool:
```cpp
// Send a final status without reading the message body.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return res.status = 401;
});
```
### Keep-Alive connection
```cpp
#define CPPHTTPLIB_THREAD_POOL_COUNT 0
svr.set_keep_alive_max_count(2); // Default is 5
svr.set_keep_alive_timeout(10); // Default is 5
```
### Timeout
```c++
svr.set_read_timeout(5, 0); // 5 seconds
svr.set_write_timeout(5, 0); // 5 seconds
svr.set_idle_interval(0, 100000); // 100 milliseconds
```
### Set maximum payload length for reading a request body
```c++
svr.set_payload_max_length(1024 * 1024 * 512); // 512MB
```
### Server-Sent Events
Please see [Server example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssesvr.cc) and [Client example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssecli.cc).
### Default thread pool support
`ThreadPool` is used as a **default** task queue, and the default thread count is 8, or `std::thread::hardware_concurrency()`. You can change it with `CPPHTTPLIB_THREAD_POOL_COUNT`.
If you want to set the thread count at runtime, there is no convenient way... But here is how.
```cpp
svr.new_task_queue = [] { return new ThreadPool(12); };
```
### Override the default thread pool with yours
You can supply your own thread pool implementation according to your need.
```cpp
class YourThreadPoolTaskQueue : public TaskQueue {
public:
@@ -157,10 +387,8 @@ svr.new_task_queue = [] {
};
```
Client Example
--------------
### GET
Client
------
```c++
#include <httplib.h>
@@ -168,35 +396,65 @@ Client Example
int main(void)
{
httplib::Client cli("localhost", 1234);
httplib::Client cli("localhost", 1234);
auto res = cli.Get("/hi");
if (res && res->status == 200) {
std::cout << res->body << std::endl;
if (auto res = cli.Get("/hi")) {
if (res->status == 200) {
std::cout << res->body << std::endl;
}
} else {
auto err = res.error();
...
}
}
```
NOTE: Constructor with scheme-host-port string is now supported!
```c++
httplib::Client cli("localhost");
httplib::Client cli("localhost:8080");
httplib::Client cli("http://localhost");
httplib::Client cli("http://localhost:8080");
httplib::Client cli("https://localhost");
httplib::SSLClient cli("localhost");
```
### Error code
Here is the list of errors from `Result::error()`.
```c++
enum Error {
Success = 0,
Unknown,
Connection,
BindIPAddress,
Read,
Write,
ExceedRedirectCount,
Canceled,
SSLConnection,
SSLLoadingCerts,
SSLServerVerification,
UnsupportedMultipartBoundaryChars
};
```
### GET with HTTP headers
```c++
httplib::Headers headers = {
{ "Accept-Encoding", "gzip, deflate" }
};
auto res = cli.Get("/hi", headers);
httplib::Headers headers = {
{ "Accept-Encoding", "gzip, deflate" }
};
auto res = cli.Get("/hi", headers);
```
### GET with Content Receiver
or
```c++
std::string body;
auto res = cli.Get("/large-data",
[&](const char *data, uint64_t data_length, uint64_t offset, uint64_t content_length) {
body.append(data, data_length);
});
assert(res->body.empty());
cli.set_default_headers({
{ "Accept-Encoding", "gzip, deflate" }
});
auto res = cli.Get("/hi");
```
### POST
@@ -229,15 +487,15 @@ auto res = cli.Post("/post", params);
### POST with Multipart Form Data
```c++
httplib::MultipartFormDataItems items = {
{ "text1", "text default", "", "" },
{ "text2", "aωb", "", "" },
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
{ "file3", "", "", "application/octet-stream" },
};
httplib::MultipartFormDataItems items = {
{ "text1", "text default", "", "" },
{ "text2", "aωb", "", "" },
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
{ "file3", "", "", "application/octet-stream" },
};
auto res = cli.Post("/multipart", items);
auto res = cli.Post("/multipart", items);
```
### PUT
@@ -259,43 +517,119 @@ res = cli.Options("*");
res = cli.Options("/resource/foo");
```
### Connection Timeout
### Timeout
```c++
httplib::Client cli("localhost", 8080, 5); // timeouts in 5 seconds
cli.set_connection_timeout(0, 300000); // 300 milliseconds
cli.set_read_timeout(5, 0); // 5 seconds
cli.set_write_timeout(5, 0); // 5 seconds
```
### Receive content with a content receiver
```c++
std::string body;
auto res = cli.Get("/large-data",
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
```
```cpp
std::string body;
auto res = cli.Get(
"/stream", Headers(),
[&](const Response &response) {
EXPECT_EQ(200, response.status);
return true; // return 'false' if you want to cancel the request.
},
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true; // return 'false' if you want to cancel the request.
});
```
### Send content with a content provider
```cpp
std::string body = ...;
auto res = cli.Post(
"/stream", body.size(),
[](size_t offset, size_t length, DataSink &sink) {
sink.write(body.data() + offset, length);
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### Chunked transfer encoding
```cpp
auto res = cli.Post(
"/stream",
[](size_t offset, DataSink &sink) {
sink.os << "chunked data 1";
sink.os << "chunked data 2";
sink.os << "chunked data 3";
sink.done();
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### With Progress Callback
```cpp
httplib::Client client(url, port);
// prints: 0 / 000 bytes => 50% complete
std::shared_ptr<httplib::Response> res =
cli.Get("/", [](uint64_t len, uint64_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)((len/total)*100));
return true; // return 'false' if you want to cancel the request.
}
auto res = cli.Get("/", [](uint64_t len, uint64_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)(len*100/total));
return true; // return 'false' if you want to cancel the request.
}
);
```
![progress](https://user-images.githubusercontent.com/236374/33138910-495c4ecc-cf86-11e7-8693-2fc6d09615c4.gif)
This feature was contributed by [underscorediscovery](https://github.com/yhirose/cpp-httplib/pull/23).
### Basic Authentication
### Authentication
```cpp
httplib::Client cli("httplib.org");
// Basic Authentication
cli.set_basic_auth("user", "pass");
auto res = cli.Get("/basic-auth/hello/world", {
httplib::make_basic_authentication_header("hello", "world")
});
// res->status should be 200
// res->body should be "{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n".
// Digest Authentication
cli.set_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_bearer_token_auth("token");
```
NOTE: OpenSSL is required for Digest Authentication.
### Proxy server support
```cpp
cli.set_proxy("host", port);
// Basic Authentication
cli.set_proxy_basic_auth("user", "pass");
// Digest Authentication
cli.set_proxy_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_proxy_bearer_token_auth("pass");
```
NOTE: OpenSSL is required for Digest Authentication.
### Range
```cpp
@@ -317,57 +651,139 @@ httplib::make_range_header({{0, 0}, {-1, 1}}) // 'Range: bytes=0-0, -1'
### Keep-Alive connection
```cpp
cli.set_keep_alive_max_count(2); // Default is 5
httplib::Client cli("localhost", 1234);
std::vector<Request> requests;
Get(requests, "/get-request1");
Get(requests, "/get-request2");
Post(requests, "/post-request1", "text", "text/plain");
Post(requests, "/post-request2", "text", "text/plain");
cli.Get("/hello"); // with "Connection: close"
std::vector<Response> responses;
if (cli.send(requests, responses)) {
for (const auto& res: responses) {
...
}
}
cli.set_keep_alive(true);
cli.Get("/world");
cli.set_keep_alive(false);
cli.Get("/last-request"); // with "Connection: close"
```
OpenSSL Support
---------------
### Redirect
SSL support is available with `CPPHTTPLIB_OPENSSL_SUPPORT`. `libssl` and `libcrypto` should be linked.
```cpp
httplib::Client cli("yahoo.com");
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
auto res = cli.Get("/");
res->status; // 301
SSLServer svr("./cert.pem", "./key.pem");
SSLClient cli("localhost", 8080);
cli.set_ca_cert_path("./ca-bundle.crt");
cli.enable_server_certificate_verification(true);
cli.set_follow_location(true);
res = cli.Get("/");
res->status; // 200
```
Zlib Support
------------
### Use a specific network interface
'gzip' compression is available with `CPPHTTPLIB_ZLIB_SUPPORT`.
NOTE: This feature is not available on Windows, yet.
The server applies gzip compression to the following MIME type contents:
```cpp
cli.set_interface("eth0"); // Interface name, IP address or host name
```
* all text types
Compression
-----------
The server can apply compression to the following MIME type contents:
* all text types except text/event-stream
* image/svg+xml
* application/javascript
* application/json
* application/xml
* application/xhtml+xml
### Zlib Support
'gzip' compression is available with `CPPHTTPLIB_ZLIB_SUPPORT`. `libz` should be linked.
### Brotli Support
Brotli compression is available with `CPPHTTPLIB_BROTLI_SUPPORT`. Necessary libraries should be linked.
Please see https://github.com/google/brotli for more detail.
### Compress request body on client
```c++
cli.set_compress(true);
res = cli.Post("/resource/foo", "...", "text/plain");
```
### Compress response body on client
```c++
cli.set_decompress(false);
res = cli.Get("/resource/foo", {{"Accept-Encoding", "gzip, deflate, br"}});
res->body; // Compressed data
```
SSL Support
-----------
SSL support is available with `CPPHTTPLIB_OPENSSL_SUPPORT`. `libssl` and `libcrypto` should be linked.
NOTE: cpp-httplib currently supports only version 1.1.1.
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// Server
httplib::SSLServer svr("./cert.pem", "./key.pem");
// Client
httplib::Client cli("https://localhost:1234");
// Use your CA bundle
cli.set_ca_cert_path("./ca-bundle.crt");
// Disable cert verification
cli.enable_server_certificate_verification(false);
```
Note: When using SSL, it seems impossible to avoid SIGPIPE in all cases, since on some operating systems, SIGPIPE can only be suppressed on a per-message basis, but there is no way to make the OpenSSL library do so for its internal communications. If your program needs to avoid being terminated on SIGPIPE, the only fully general way might be to set up a signal handler for SIGPIPE to handle or ignore it yourself.
Split httplib.h into .h and .cc
-------------------------------
```bash
> python3 split.py
> ls out
httplib.h httplib.cc
```
NOTE
----
g++ 4.8 cannot build this library since `<regex>` in g++4.8 is [broken](https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions).
### g++
g++ 4.8 and below cannot build this library since `<regex>` in the versions are [broken](https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions).
### Windows
Include `httplib.h` before `Windows.h` or include `Windows.h` by defining `WIN32_LEAN_AND_MEAN` beforehand.
```cpp
#include <httplib.h>
#include <Windows.h>
```
```cpp
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <httplib.h>
```
Note: Windows 8 or lower and Cygwin on Windows are not supported.
License
-------
MIT license (© 2019 Yuji Hirose)
MIT license (© 2021 Yuji Hirose)
Special Thanks To
-----------------
[These folks](https://github.com/yhirose/cpp-httplib/graphs/contributors) made great contributions to polish this library to totally another level from a simple toy!
-9
View File
@@ -1,9 +0,0 @@
version: 1.0.{build}
image: Visual Studio 2017
build_script:
- cmd: >-
cd test
msbuild.exe test.sln /verbosity:minimal /t:Build /p:Configuration=Debug;Platform=Win32
test_script:
- cmd: Debug\test.exe
+178
View File
@@ -0,0 +1,178 @@
# A simple FindBrotli package for Cmake's find_package function.
# Note: This find package doesn't have version support, as the version file doesn't seem to be installed on most systems.
#
# If you want to find the static packages instead of shared (the default), define BROTLI_USE_STATIC_LIBS as TRUE.
# The targets will have the same names, but it will use the static libs.
#
# Valid find_package COMPONENTS names: "decoder", "encoder", and "common"
# Note that if you're requiring "decoder" or "encoder", then "common" will be automatically added as required.
#
# Defines the libraries (if found): Brotli::decoder, Brotli::encoder, Brotli::common
# and the includes path variable: Brotli_INCLUDE_DIR
#
# If it's failing to find the libraries, try setting BROTLI_ROOT_DIR to the folder containing your library & include dir.
# If they asked for a specific version, warn/fail since we don't support it.
# TODO: if they start distributing the version somewhere, implement finding it.
# But currently there's a version header that doesn't seem to get installed.
if(Brotli_FIND_VERSION)
set(_brotli_version_error_msg "FindBrotli.cmake doesn't have version support!")
# If the package is required, throw a fatal error
# Otherwise, if not running quietly, we throw a warning
if(Brotli_FIND_REQUIRED)
message(FATAL_ERROR "${_brotli_version_error_msg}")
elseif(NOT Brotli_FIND_QUIETLY)
message(WARNING "${_brotli_version_error_msg}")
endif()
endif()
# Since both decoder & encoder require the common lib, force its requirement..
# if the user is requiring either of those other libs.
if(Brotli_FIND_REQUIRED_decoder OR Brotli_FIND_REQUIRED_encoder)
set(Brotli_FIND_REQUIRED_common TRUE)
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
# Credit to FindOpenSSL.cmake for this
if(BROTLI_USE_STATIC_LIBS)
set(_brotli_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
endif()
# Make PkgConfig optional, since some users (mainly Windows) don't have it.
# But it's a lot more clean than manually using find_library.
find_package(PkgConfig QUIET)
# Only used if the PkgConfig libraries aren't used.
find_path(Brotli_INCLUDE_DIR
NAMES
"brotli/decode.h"
"brotli/encode.h"
HINTS
${BROTLI_ROOT_DIR}
PATH_SUFFIXES
"include"
"includes"
DOC "The path to Brotli's include directory."
)
# Hides this var from the GUI
mark_as_advanced(Brotli_INCLUDE_DIR)
# Just used for PkgConfig stuff in the loop below
set(_brotli_stat_str "")
if(BROTLI_USE_STATIC_LIBS)
set(_brotli_stat_str "_STATIC")
endif()
# Lets us know we are using the PkgConfig libraries
# Will be set false if any non-pkgconf vars are used
set(_brotli_using_pkgconf TRUE)
# Each string here is "ComponentName;LiteralName" (the semi-colon is a delimiter)
foreach(_listvar "common;common" "decoder;dec" "encoder;enc")
# Split the component name and literal library name from the listvar
list(GET _listvar 0 _component_name)
list(GET _listvar 1 _libname)
if(PKG_CONFIG_FOUND)
# These need to be GLOBAL for MinGW when making ALIAS libraries against them.
if(BROTLI_USE_STATIC_LIBS)
# Have to use _STATIC to tell PkgConfig to find the static libs.
pkg_check_modules(Brotli_${_component_name}_STATIC QUIET GLOBAL IMPORTED_TARGET libbrotli${_libname})
else()
pkg_check_modules(Brotli_${_component_name} QUIET GLOBAL IMPORTED_TARGET libbrotli${_libname})
endif()
endif()
# Check if the target was already found by Pkgconf
if(TARGET PkgConfig::Brotli_${_component_name} OR TARGET PkgConfig::Brotli_${_component_name}_STATIC)
# Can't use generators for ALIAS targets, so you get this jank
add_library(Brotli::${_component_name} ALIAS PkgConfig::Brotli_${_component_name}${_brotli_stat_str})
# Tells HANDLE_COMPONENTS we found the component
set(Brotli_${_component_name}_FOUND TRUE)
if(Brotli_FIND_REQUIRED_${_component_name})
# If the lib is required, we can add its literal path as a required var for FindPackageHandleStandardArgs
# Since it won't accept the PkgConfig targets
if(BROTLI_USE_STATIC_LIBS)
list(APPEND _brotli_req_vars "Brotli_${_component_name}_STATIC_LIBRARIES")
else()
list(APPEND _brotli_req_vars "Brotli_${_component_name}_LINK_LIBRARIES")
endif()
endif()
# Skip searching for the libs with find_library since it was already found by Pkgconf
continue()
endif()
# Lets us know we aren't using the PkgConfig libraries
set(_brotli_using_pkgconf FALSE)
if(Brotli_FIND_REQUIRED_${_component_name})
# If it's required, we can set the name used in find_library as a required var for FindPackageHandleStandardArgs
list(APPEND _brotli_req_vars "Brotli_${_component_name}")
endif()
if(BROTLI_USE_STATIC_LIBS)
list(APPEND _brotli_lib_names
"brotli${_libname}-static"
"libbrotli${_libname}-static"
)
else()
list(APPEND _brotli_lib_names
"brotli${_libname}"
"libbrotli${_libname}"
)
endif()
find_library(Brotli_${_component_name}
NAMES ${_brotli_lib_names}
HINTS ${BROTLI_ROOT_DIR}
PATH_SUFFIXES
"lib"
"lib64"
"libs"
"libs64"
"lib/x86_64-linux-gnu"
)
# Hide the library variable from the Cmake GUI
mark_as_advanced(Brotli_${_component_name})
# Unset since otherwise it'll stick around for the next loop and break things
unset(_brotli_lib_names)
# Check if find_library found the library
if(Brotli_${_component_name})
# Tells HANDLE_COMPONENTS we found the component
set(Brotli_${_component_name}_FOUND TRUE)
add_library("Brotli::${_component_name}" UNKNOWN IMPORTED)
# Attach the literal library and include dir to the IMPORTED target for the end-user
set_target_properties("Brotli::${_component_name}" PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}"
IMPORTED_LOCATION "${Brotli_${_component_name}}"
)
else()
# Tells HANDLE_COMPONENTS we found the component
set(Brotli_${_component_name}_FOUND FALSE)
endif()
endforeach()
include(FindPackageHandleStandardArgs)
# Sets Brotli_FOUND, and fails the find_package(Brotli) call if it was REQUIRED but missing libs.
find_package_handle_standard_args(Brotli
FOUND_VAR
Brotli_FOUND
REQUIRED_VARS
Brotli_INCLUDE_DIR
${_brotli_required_targets}
HANDLE_COMPONENTS
)
# Restore the original find library ordering
if(BROTLI_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_brotli_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
+28 -10
View File
@@ -1,32 +1,50 @@
#CXX = clang++
CXXFLAGS = -std=c++14 -I.. -Wall -Wextra -pthread
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
CXXFLAGS = -std=c++11 -I.. -Wall -Wextra -pthread
OPENSSL_DIR = /usr/local/opt/openssl
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
all: server client hello simplesvr redirect benchmark
BROTLI_DIR = /usr/local/opt/brotli
# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon-static -lbrotlienc-static -lbrotlidec-static
all: server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark
server : server.cc ../httplib.h Makefile
$(CXX) -o server $(CXXFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o server $(CXXFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
client : client.cc ../httplib.h Makefile
$(CXX) -o client $(CXXFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o client $(CXXFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
hello : hello.cc ../httplib.h Makefile
$(CXX) -o hello $(CXXFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o hello $(CXXFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
simplecli : simplecli.cc ../httplib.h Makefile
$(CXX) -o simplecli $(CXXFLAGS) simplecli.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
simplesvr : simplesvr.cc ../httplib.h Makefile
$(CXX) -o simplesvr $(CXXFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o simplesvr $(CXXFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
upload : upload.cc ../httplib.h Makefile
$(CXX) -o upload $(CXXFLAGS) upload.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
redirect : redirect.cc ../httplib.h Makefile
$(CXX) -o redirect $(CXXFLAGS) redirect.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o redirect $(CXXFLAGS) redirect.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
ssesvr : ssesvr.cc ../httplib.h Makefile
$(CXX) -o ssesvr $(CXXFLAGS) ssesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
ssecli : ssecli.cc ../httplib.h Makefile
$(CXX) -o ssecli $(CXXFLAGS) ssecli.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
benchmark : benchmark.cc ../httplib.h Makefile
$(CXX) -o benchmark $(CXXFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT)
$(CXX) -o benchmark $(CXXFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
pem:
openssl genrsa 2048 > key.pem
openssl req -new -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
clean:
rm server client hello simplesvr redirect *.pem
rm server client hello simplecli simplesvr upload redirect ssesvr sselci benchmark *.pem
+2 -2
View File
@@ -23,12 +23,12 @@ int main(void) {
httplib::Client cli("localhost", 8080);
#endif
auto res = cli.Get("/hi");
if (res) {
if (auto res = cli.Get("/hi")) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
} else {
cout << "error code: " << res.error() << std::endl;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result) {
+1 -1
View File
@@ -15,5 +15,5 @@ int main(void) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("localhost", 1234);
svr.listen("localhost", 8080);
}
+2 -6
View File
@@ -44,14 +44,10 @@ int main(void) {
#endif
// Run servers
auto httpThread = std::thread([&]() {
http.listen("localhost", 8080);
});
auto httpThread = std::thread([&]() { http.listen("localhost", 8080); });
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto httpsThread = std::thread([&]() {
https.listen("localhost", 8081);
});
auto httpsThread = std::thread([&]() { https.listen("localhost", 8081); });
#endif
httpThread.join();
+29
View File
@@ -0,0 +1,29 @@
//
// simplecli.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
#include <iostream>
using namespace std;
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto scheme_host_port = "https://localhost:8080";
#else
auto scheme_host_port = "http://localhost:8080";
#endif
if (auto res = httplib::Client(scheme_host_port).Get("/hi")) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
} else {
cout << res.error() << endl;
}
return 0;
}
+7 -7
View File
@@ -27,7 +27,7 @@ string dump_headers(const Headers &headers) {
return s;
}
string dump_multipart_files(const MultipartFiles &files) {
string dump_multipart_files(const MultipartFormDataMap &files) {
string s;
char buf[BUFSIZ];
@@ -46,10 +46,7 @@ string dump_multipart_files(const MultipartFiles &files) {
snprintf(buf, sizeof(buf), "content type: %s\n", file.content_type.c_str());
s += buf;
snprintf(buf, sizeof(buf), "text offset: %lu\n", file.offset);
s += buf;
snprintf(buf, sizeof(buf), "text length: %lu\n", file.length);
snprintf(buf, sizeof(buf), "text length: %zu\n", file.content.size());
s += buf;
s += "----------------\n";
@@ -125,9 +122,12 @@ int main(int argc, const char **argv) {
auto base_dir = "./";
if (argc > 2) { base_dir = argv[2]; }
svr.set_base_dir(base_dir);
if (!svr.set_mount_point("/", base_dir)) {
cout << "The specified base directory doesn't exist...";
return 1;
}
cout << "The server started at port " << port << "...";
cout << "The server started at port " << port << "..." << endl;
svr.listen("localhost", port);
+21
View File
@@ -0,0 +1,21 @@
//
// ssecli.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
#include <iostream>
using namespace std;
int main(void) {
httplib::Client("http://localhost:1234")
.Get("/event1", [&](const char *data, size_t data_length) {
std::cout << string(data, data_length);
return true;
});
return 0;
}
+102
View File
@@ -0,0 +1,102 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <httplib.h>
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
using namespace httplib;
using namespace std;
class EventDispatcher {
public:
EventDispatcher() {
}
void wait_event(DataSink *sink) {
unique_lock<mutex> lk(m_);
int id = id_;
cv_.wait(lk, [&] { return cid_ == id; });
if (sink->is_writable()) { sink->write(message_.data(), message_.size()); }
}
void send_event(const string &message) {
lock_guard<mutex> lk(m_);
cid_ = id_++;
message_ = message;
cv_.notify_all();
}
private:
mutex m_;
condition_variable cv_;
atomic_int id_{0};
atomic_int cid_{-1};
string message_;
};
const auto html = R"(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE demo</title>
</head>
<body>
<script>
const ev1 = new EventSource("event1");
ev1.onmessage = function(e) {
console.log('ev1', e.data);
}
const ev2 = new EventSource("event2");
ev2.onmessage = function(e) {
console.log('ev2', e.data);
}
</script>
</body>
</html>
)";
int main(void) {
EventDispatcher ed;
Server svr;
svr.Get("/", [&](const Request & /*req*/, Response &res) {
res.set_content(html, "text/html");
});
svr.Get("/event1", [&](const Request & /*req*/, Response &res) {
cout << "connected to event1..." << endl;
res.set_chunked_content_provider("text/event-stream",
[&](size_t /*offset*/, DataSink &sink) {
ed.wait_event(&sink);
return true;
});
});
svr.Get("/event2", [&](const Request & /*req*/, Response &res) {
cout << "connected to event2..." << endl;
res.set_chunked_content_provider("text/event-stream",
[&](size_t /*offset*/, DataSink &sink) {
ed.wait_event(&sink);
return true;
});
});
thread t([&] {
int id = 0;
while (true) {
this_thread::sleep_for(chrono::seconds(1));
cout << "send event: " << id << std::endl;
std::stringstream ss;
ss << "data: " << id << "\n\n";
ed.send_event(ss.str());
id++;
}
});
svr.listen("localhost", 1234);
}
+61
View File
@@ -0,0 +1,61 @@
//
// upload.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <fstream>
#include <httplib.h>
#include <iostream>
using namespace httplib;
using namespace std;
const char *html = R"(
<form id="formElem">
<input type="file" name="image_file" accept="image/*">
<input type="file" name="text_file" accept="text/*">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault();
let res = await fetch('/post', {
method: 'POST',
body: new FormData(formElem)
});
console.log(await res.text());
};
</script>
)";
int main(void) {
Server svr;
svr.Get("/", [](const Request & /*req*/, Response &res) {
res.set_content(html, "text/html");
});
svr.Post("/post", [](const Request &req, Response &res) {
auto image_file = req.get_file_value("image_file");
auto text_file = req.get_file_value("text_file");
cout << "image file length: " << image_file.content.length() << endl
<< "image file name: " << image_file.filename << endl
<< "text file length: " << text_file.content.length() << endl
<< "text file name: " << text_file.filename << endl;
{
ofstream ofs(image_file.filename, ios::binary);
ofs << image_file.content;
}
{
ofstream ofs(text_file.filename);
ofs << text_file.content;
}
res.set_content("done", "text/plain");
});
svr.listen("localhost", 1234);
}
+5763 -1547
View File
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
# Generates a macro to auto-configure everything
@PACKAGE_INIT@
# Setting these here so they're accessible after install.
# Might be useful for some users to check which settings were used.
set(HTTPLIB_IS_USING_OPENSSL @HTTPLIB_IS_USING_OPENSSL@)
set(HTTPLIB_IS_USING_ZLIB @HTTPLIB_IS_USING_ZLIB@)
set(HTTPLIB_IS_COMPILED @HTTPLIB_COMPILE@)
set(HTTPLIB_IS_USING_BROTLI @HTTPLIB_IS_USING_BROTLI@)
set(HTTPLIB_VERSION @PROJECT_VERSION@)
include(CMakeFindDependencyMacro)
# We add find_dependency calls here to not make the end-user have to call them.
find_dependency(Threads REQUIRED)
if(@HTTPLIB_IS_USING_OPENSSL@)
# OpenSSL COMPONENTS were added in Cmake v3.11
if(CMAKE_VERSION VERSION_LESS "3.11")
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@ REQUIRED)
else()
# Once the COMPONENTS were added, they were made optional when not specified.
# Since we use both, we need to search for both.
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@ COMPONENTS Crypto SSL REQUIRED)
endif()
endif()
if(@HTTPLIB_IS_USING_ZLIB@)
find_dependency(ZLIB REQUIRED)
endif()
if(@HTTPLIB_IS_USING_BROTLI@)
# Needed so we can use our own FindBrotli.cmake in this file.
# Note that the FindBrotli.cmake file is installed in the same dir as this file.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
set(BROTLI_USE_STATIC_LIBS @BROTLI_USE_STATIC_LIBS@)
find_dependency(Brotli COMPONENTS common encoder decoder REQUIRED)
endif()
# Mildly useful for end-users
# Not really recommended to be used though
set_and_check(HTTPLIB_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@")
# Lets the end-user find the header path with the header appended
# This is helpful if you're using Cmake's pre-compiled header feature
set_and_check(HTTPLIB_HEADER_PATH "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/httplib.h")
# Brings in the target library
include("${CMAKE_CURRENT_LIST_DIR}/httplibTargets.cmake")
# Ouputs a "found httplib /usr/include/httplib.h" message when using find_package(httplib)
include(FindPackageMessage)
if(TARGET httplib::httplib)
set(HTTPLIB_FOUND TRUE)
# Since the compiled version has a lib, show that in the message
if(@HTTPLIB_COMPILE@)
# The list of configurations is most likely just 1 unless they installed a debug & release
get_target_property(_httplib_configs httplib::httplib "IMPORTED_CONFIGURATIONS")
# Need to loop since the "IMPORTED_LOCATION" property isn't want we want.
# Instead, we need to find the IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG which has the lib path.
foreach(_httplib_conf "${_httplib_configs}")
# Grab the path to the lib and sets it to HTTPLIB_LIBRARY
get_target_property(HTTPLIB_LIBRARY httplib::httplib "IMPORTED_LOCATION_${_httplib_conf}")
# Check if we found it
if(HTTPLIB_LIBRARY)
break()
endif()
endforeach()
unset(_httplib_configs)
unset(_httplib_conf)
find_package_message(httplib "Found httplib: ${HTTPLIB_LIBRARY} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_LIBRARY}][${HTTPLIB_HEADER_PATH}]")
else()
find_package_message(httplib "Found httplib: ${HTTPLIB_HEADER_PATH} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_HEADER_PATH}]")
endif()
endif()
+7
View File
@@ -0,0 +1,7 @@
project('cpp-httplib', 'cpp', license: 'MIT')
cpp_httplib_dep = declare_dependency(include_directories: include_directories('.'))
if meson.version().version_compare('>=0.54.0')
meson.override_dependency('cpp-httplib', cpp_httplib_dep)
endif
+32
View File
@@ -0,0 +1,32 @@
import os
import sys
border = '// ----------------------------------------------------------------------------'
PythonVersion = sys.version_info[0];
with open('httplib.h') as f:
lines = f.readlines()
inImplementation = False
if PythonVersion < 3:
os.makedirs('out')
else:
os.makedirs('out', exist_ok=True)
with open('out/httplib.h', 'w') as fh:
with open('out/httplib.cc', 'w') as fc:
fc.write('#include "httplib.h"\n')
fc.write('namespace httplib {\n')
for line in lines:
isBorderLine = border in line
if isBorderLine:
inImplementation = not inImplementation
else:
if inImplementation:
fc.write(line.replace('inline ', ''))
pass
else:
fh.write(line)
pass
fc.write('} // namespace httplib\n')
+17 -5
View File
@@ -1,18 +1,30 @@
#CXX = clang++
CXXFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto
CXXFLAGS = -g -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits -Wconversion #-fsanitize=address
OPENSSL_DIR = /usr/local/opt/openssl@1.1
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
BROTLI_DIR = /usr/local/opt/brotli
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
all : test
./test
proxy : test_proxy
./test_proxy
test : test.cc ../httplib.h Makefile cert.pem
$(CXX) -o test $(CXXFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) -pthread
$(CXX) -o test $(CXXFLAGS) test.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
test_proxy : test_proxy.cc ../httplib.h Makefile cert.pem
$(CXX) -o test_proxy $(CXXFLAGS) test_proxy.cc gtest/gtest-all.cc gtest/gtest_main.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) -pthread
cert.pem:
openssl genrsa 2048 > key.pem
openssl req -new -batch -config test.conf -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
openssl req -x509 -config test.conf -key key.pem -sha256 -days 3650 -nodes -out cert2.pem -extensions SAN
openssl genrsa 2048 > rootCA.key.pem
openssl req -x509 -new -batch -config test.rootCA.conf -key rootCA.key.pem -days 1024 > rootCA.cert.pem
openssl genrsa 2048 > client.key.pem
@@ -20,4 +32,4 @@ cert.pem:
#c_rehash .
clean:
rm -f test *.pem *.0 *.1 *.srl
rm -f test test_proxy pem *.0 *.1 *.srl
+36
View File
@@ -0,0 +1,36 @@
#CXX = clang++
CXXFLAGS += -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits -Wconversion
OPENSSL_DIR = /usr/local/opt/openssl@1.1
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
BROTLI_DIR = /usr/local/opt/brotli
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
# By default, use standalone_fuzz_target_runner.
# This runner does no fuzzing, but simply executes the inputs
# provided via parameters.
# Run e.g. "make all LIB_FUZZING_ENGINE=/path/to/libFuzzer.a"
# to link the fuzzer(s) against a real fuzzing engine.
# OSS-Fuzz will define its own value for LIB_FUZZING_ENGINE.
LIB_FUZZING_ENGINE ?= standalone_fuzz_target_runner.o
# Runs server_fuzzer.cc based on value of $(LIB_FUZZING_ENGINE).
# Usage: make fuzz_test LIB_FUZZING_ENGINE=/path/to/libFuzzer
all fuzz_test: server_fuzzer
./server_fuzzer fuzzing/corpus/*
# Fuzz target, so that you can choose which $(LIB_FUZZING_ENGINE) to use.
server_fuzzer : fuzzing/server_fuzzer.cc ../httplib.h standalone_fuzz_target_runner.o
$(CXX) $(CXXFLAGS) -o $@ $< $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread
# Standalone fuzz runner, which just reads inputs from fuzzing/corpus/ dir and
# feeds it to server_fuzzer.
standalone_fuzz_target_runner.o : fuzzing/standalone_fuzz_target_runner.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
rm -f server_fuzzer pem *.0 *.o *.1 *.srl *.zip
+27
View File
@@ -0,0 +1,27 @@
#CXX = clang++
# Do not add default sanitizer flags here as OSS-fuzz adds its own sanitizer flags.
CXXFLAGS += -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I../.. -I. -Wall -Wextra -Wtype-limits -Wconversion
OPENSSL_DIR = /usr/local/opt/openssl@1.1
# Using full path to libssl and libcrypto to avoid accidentally picking openssl libs brought in by msan.
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -I$(OPENSSL_DIR)/lib /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
BROTLI_DIR = /usr/local/opt/brotli
# BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
# Runs all the tests and also fuzz tests against seed corpus.
all : server_fuzzer
./server_fuzzer corpus/*
# Fuzz target, so that you can choose which $(LIB_FUZZING_ENGINE) to use.
server_fuzzer : server_fuzzer.cc ../../httplib.h
# $(CXX) $(CXXFLAGS) -o $@ $< -Wl,-Bstatic $(OPENSSL_SUPPORT) -Wl,-Bdynamic -ldl $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread
$(CXX) $(CXXFLAGS) -o $@ $< $(ZLIB_SUPPORT) $(LIB_FUZZING_ENGINE) -pthread
zip -q -r server_fuzzer_seed_corpus.zip corpus
clean:
rm -f server_fuzzer pem *.0 *.o *.1 *.srl *.zip
+1
View File
@@ -0,0 +1 @@
PUT /search/sample?a=12 HTTP/1.1
+5
View File
@@ -0,0 +1,5 @@
GET /hello.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
+88
View File
@@ -0,0 +1,88 @@
#include <httplib.h>
#include <memory>
class FuzzedStream : public httplib::Stream {
public:
FuzzedStream(const uint8_t *data, size_t size)
: data_(data), size_(size), read_pos_(0) {}
ssize_t read(char *ptr, size_t size) override {
if (size + read_pos_ > size_) { size = size_ - read_pos_; }
memcpy(ptr, data_ + read_pos_, size);
read_pos_ += size;
return static_cast<ssize_t>(size);
}
ssize_t write(const char *ptr, size_t size) override {
response_.append(ptr, size);
return static_cast<int>(size);
}
ssize_t write(const char *ptr) { return write(ptr, strlen(ptr)); }
ssize_t write(const std::string &s) { return write(s.data(), s.size()); }
std::string get_remote_addr() const { return ""; }
bool is_readable() const override { return true; }
bool is_writable() const override { return true; }
void get_remote_ip_and_port(std::string &ip, int &port) const override {
ip = "127.0.0.1";
port = 8080;
}
socket_t socket() const override { return 0; }
private:
const uint8_t *data_;
size_t size_;
size_t read_pos_;
std::string response_;
};
class FuzzableServer : public httplib::Server {
public:
void ProcessFuzzedRequest(FuzzedStream &stream) {
bool connection_close = false;
process_request(stream, /*last_connection=*/false, connection_close,
nullptr);
}
};
static FuzzableServer g_server;
extern "C" int LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/) {
g_server.Get(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Post(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Put(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Patch(R"(.*)",
[&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Delete(
R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
g_server.Options(
R"(.*)", [&](const httplib::Request & /*req*/, httplib::Response &res) {
res.set_content("response content", "text/plain");
});
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedStream stream{data, size};
g_server.ProcessFuzzedRequest(stream);
return 0;
}
+224
View File
@@ -0,0 +1,224 @@
# Sources: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
# misc
"HTTP/1.1"
# verbs
"CONNECT"
"DELETE"
"GET"
"HEAD"
"OPTIONS"
"PATCH"
"POST"
"PUT"
"TRACE"
# Webdav/caldav verbs
"ACL"
"BASELINE-CONTROL"
"BIND"
"CHECKIN"
"CHECKOUT"
"COPY"
"LABEL"
"LINK"
"LOCK"
"MERGE"
"MKACTIVITY"
"MKCALENDAR"
"MKCOL"
"MKREDIRECTREF"
"MKWORKSPACE"
"MOVE"
"ORDERPATCH"
"PRI"
"PROPFIND"
"PROPPATCH"
"REBIND"
"REPORT"
"SEARCH"
"UNBIND"
"UNCHECKOUT"
"UNLINK"
"UNLOCK"
"UPDATE"
"UPDATEREDIRECTREF"
"VERSION-CONTROL"
# Fields
"A-IM"
"Accept"
"Accept-Charset"
"Accept-Datetime"
"Accept-Encoding"
"Accept-Language"
"Accept-Patch"
"Accept-Ranges"
"Access-Control-Allow-Credentials"
"Access-Control-Allow-Headers"
"Access-Control-Allow-Methods"
"Access-Control-Allow-Origin"
"Access-Control-Expose-Headers"
"Access-Control-Max-Age"
"Access-Control-Request-Headers"
"Access-Control-Request-Method"
"Age"
"Allow"
"Alt-Svc"
"Authorization"
"Cache-Control"
"Connection"
"Connection:"
"Content-Disposition"
"Content-Encoding"
"Content-Language"
"Content-Length"
"Content-Location"
"Content-MD5"
"Content-Range"
"Content-Security-Policy"
"Content-Type"
"Cookie"
"DNT"
"Date"
"Delta-Base"
"ETag"
"Expect"
"Expires"
"Forwarded"
"From"
"Front-End-Https"
"HTTP2-Settings"
"Host"
"IM"
"If-Match"
"If-Modified-Since"
"If-None-Match"
"If-Range"
"If-Unmodified-Since"
"Last-Modified"
"Link"
"Location"
"Max-Forwards"
"Origin"
"P3P"
"Pragma"
"Proxy-Authenticate"
"Proxy-Authorization"
"Proxy-Connection"
"Public-Key-Pins"
"Range"
"Referer"
"Refresh"
"Retry-After"
"Save-Data"
"Server"
"Set-Cookie"
"Status"
"Strict-Transport-Security"
"TE"
"Timing-Allow-Origin"
"Tk"
"Trailer"
"Transfer-Encoding"
"Upgrade"
"Upgrade-Insecure-Requests"
"User-Agent"
"Vary"
"Via"
"WWW-Authenticate"
"Warning"
"X-ATT-DeviceId"
"X-Content-Duration"
"X-Content-Security-Policy"
"X-Content-Type-Options"
"X-Correlation-ID"
"X-Csrf-Token"
"X-Forwarded-For"
"X-Forwarded-Host"
"X-Forwarded-Proto"
"X-Frame-Options"
"X-Http-Method-Override"
"X-Powered-By"
"X-Request-ID"
"X-Requested-With"
"X-UA-Compatible"
"X-UIDH"
"X-Wap-Profile"
"X-WebKit-CSP"
"X-XSS-Protection"
# Source: string and character literals in httplib.h
" "
"&"
", "
"-"
"--"
"."
".."
":"
"="
" = = "
"0123456789abcdef"
"%02X"
"%0A"
"\\x0a\\x0d"
"%0D"
"%20"
"%27"
"%2B"
"%2C"
"%3A"
"%3B"
"application/javascript"
"application/json"
"application/pdf"
"application/xhtml+xml"
"application/xml"
"application/x-www-form-urlencoded"
"Bad Request"
"boundary="
"bytes="
"chunked"
"close"
"CONNECT"
"css"
"Forbidden"
"Found"
"gif"
"gzip"
"html"
"ico"
"image/gif"
"image/jpg"
"image/png"
"image/svg+xml"
"image/x-icon"
"index.html"
"Internal Server Error"
"jpeg"
"js"
"json"
"Location"
"Moved Permanently"
"multipart/form-data"
"Not Found"
"Not Modified"
"OK"
"pdf"
"png"
"Range"
"REMOTE_ADDR"
"See Other"
"svg"
"text/"
"text/css"
"text/html"
"text/plain"
"txt"
"Unsupported Media Type"
"xhtml"
"xml"
@@ -0,0 +1,35 @@
// Copyright 2017 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// This runner does not do any fuzzing, but allows us to run the fuzz target
// on the test corpus or on a single file,
// e.g. the one that comes from a bug report.
#include <cassert>
#include <iostream>
#include <fstream>
#include <vector>
// Forward declare the "fuzz target" interface.
// We deliberately keep this inteface simple and header-free.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
// It reads all files passed as parameters and feeds their contents
// one by one into the fuzz target (LLVMFuzzerTestOneInput).
int main(int argc, char **argv) {
for (int i = 1; i < argc; i++) {
std::ifstream in(argv[i]);
in.seekg(0, in.end);
size_t length = in.tellg();
in.seekg (0, in.beg);
std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl;
// Allocate exactly length bytes so that we reliably catch buffer overflows.
std::vector<char> bytes(length);
in.read(bytes.data(), bytes.size());
LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()),
bytes.size());
std::cout << "Execution successful" << std::endl;
}
std::cout << "Execution finished" << std::endl;
return 0;
}
+15 -1
View File
@@ -38,6 +38,15 @@
// when it's fused.
#include "gtest/gtest.h"
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
#elif __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#endif
// The following lines pull in the real gtest *.cc files.
// Copyright 2005, Google Inc.
// All rights reserved.
@@ -9039,7 +9048,6 @@ void HasNewFatalFailureHelper::ReportTestPartResult(
//
// Author: wan@google.com (Zhanyong Wan)
namespace testing {
namespace internal {
@@ -9116,3 +9124,9 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
} // namespace internal
} // namespace testing
#if __clang__
#pragma clang diagnostic pop
#elif __GNUC__
#pragma GCC diagnostic pop
#endif
+19 -4
View File
@@ -59,6 +59,15 @@
#pragma warning(disable : 4996)
#endif
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#elif __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wconversion"
#endif
// Copyright 2005, Google Inc.
// All rights reserved.
//
@@ -7311,7 +7320,7 @@ inline const char* SkipComma(const char* str) {
// the entire string if it contains no comma.
inline String GetPrefixUntilComma(const char* str) {
const char* comma = strchr(str, ',');
return comma == NULL ? String(str) : String(str, comma - str);
return comma == NULL ? String(str) : String(str, static_cast<size_t>(comma - str));
}
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
@@ -18345,8 +18354,8 @@ AssertionResult CmpHelperEQ(const char* expected_expression,
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#elif __GNUC__
#pragma gcc diagnostic push
#pragma gcc diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
#endif
if (expected == actual) {
@@ -18358,7 +18367,7 @@ AssertionResult CmpHelperEQ(const char* expected_expression,
#elif __clang__
#pragma clang diagnostic pop
#elif __GNUC__
#pragma gcc diagnostic pop
#pragma GCC diagnostic pop
#endif
return EqFailure(expected_expression,
@@ -19553,4 +19562,10 @@ bool StaticAssertTypeEq() {
#pragma warning( pop )
#endif
#if __clang__
#pragma clang diagnostic pop
#elif __GNUC__
#pragma GCC diagnostic pop
#endif
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
+13
View File
@@ -0,0 +1,13 @@
FROM centos:7
ARG auth="basic"
ARG port="3128"
RUN yum install -y squid
COPY ./${auth}_squid.conf /etc/squid/squid.conf
COPY ./${auth}_passwd /etc/squid/passwd
EXPOSE ${port}
CMD ["/usr/sbin/squid", "-N"]
+1
View File
@@ -0,0 +1 @@
hello:$apr1$O6S28OBL$8dr3ixl4Mohf97hgsYvLy/
+81
View File
@@ -0,0 +1,81 @@
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3128
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid
#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
+1
View File
@@ -0,0 +1 @@
hello:world
+81
View File
@@ -0,0 +1,81 @@
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
auth_param digest program /usr/lib64/squid/digest_file_auth /etc/squid/passwd
auth_param digest realm proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3129
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid
#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
+22
View File
@@ -0,0 +1,22 @@
version: '2'
services:
squid_basic:
image: squid_basic
restart: always
ports:
- "3128:3128"
build:
context: ./
args:
auth: basic
squid_digest:
image: squid_digest
restart: always
ports:
- "3129:3129"
build:
context: ./
args:
auth: digest
+1
View File
@@ -0,0 +1 @@
docker-compose down --rmi all
+1
View File
@@ -0,0 +1 @@
docker-compose up -d
+2968 -309
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -16,3 +16,6 @@ emailAddress = test@email.address
[req_attributes]
challengePassword = 1234
[SAN]
subjectAltName=IP:127.0.0.1
+30 -10
View File
@@ -22,32 +22,32 @@
<ProjectGuid>{6B3E6769-052D-4BC0-9D2C-E9127C3DBB26}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>test</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -69,24 +69,35 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -98,10 +109,13 @@
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -111,7 +125,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
@@ -119,6 +133,9 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -130,7 +147,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
@@ -138,6 +155,9 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>./;../</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -155,4 +175,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+288
View File
@@ -0,0 +1,288 @@
#include <future>
#include <gtest/gtest.h>
#include <httplib.h>
using namespace std;
using namespace httplib;
template <typename T>
void ProxyTest(T& cli, bool basic) {
cli.set_proxy("localhost", basic ? 3128 : 3129);
auto res = cli.Get("/httpbin/get");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(407, res->status);
}
TEST(ProxyTest, NoSSLBasic) {
Client cli("nghttp2.org");
ProxyTest(cli, true);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(ProxyTest, SSLBasic) {
SSLClient cli("nghttp2.org");
ProxyTest(cli, true);
}
TEST(ProxyTest, NoSSLDigest) {
Client cli("nghttp2.org");
ProxyTest(cli, false);
}
TEST(ProxyTest, SSLDigest) {
SSLClient cli("nghttp2.org");
ProxyTest(cli, false);
}
#endif
// ----------------------------------------------------------------------------
template <typename T>
void RedirectProxyText(T& cli, const char *path, bool basic) {
cli.set_proxy("localhost", basic ? 3128 : 3129);
if (basic) {
cli.set_proxy_basic_auth("hello", "world");
} else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli.set_proxy_digest_auth("hello", "world");
#endif
}
cli.set_follow_location(true);
auto res = cli.Get(path);
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status);
}
TEST(RedirectTest, HTTPBinNoSSLBasic) {
Client cli("nghttp2.org");
RedirectProxyText(cli, "/httpbin/redirect/2", true);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(RedirectTest, HTTPBinNoSSLDigest) {
Client cli("nghttp2.org");
RedirectProxyText(cli, "/httpbin/redirect/2", false);
}
TEST(RedirectTest, HTTPBinSSLBasic) {
SSLClient cli("nghttp2.org");
RedirectProxyText(cli, "/httpbin/redirect/2", true);
}
TEST(RedirectTest, HTTPBinSSLDigest) {
SSLClient cli("nghttp2.org");
RedirectProxyText(cli, "/httpbin/redirect/2", false);
}
#endif
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(RedirectTest, YouTubeNoSSLBasic) {
Client cli("youtube.com");
RedirectProxyText(cli, "/", true);
}
TEST(RedirectTest, YouTubeNoSSLDigest) {
Client cli("youtube.com");
RedirectProxyText(cli, "/", false);
}
TEST(RedirectTest, YouTubeSSLBasic) {
SSLClient cli("youtube.com");
RedirectProxyText(cli, "/", true);
}
TEST(RedirectTest, YouTubeSSLDigest) {
SSLClient cli("youtube.com");
RedirectProxyText(cli, "/", false);
}
#endif
// ----------------------------------------------------------------------------
template <typename T>
void BaseAuthTestFromHTTPWatch(T& cli) {
cli.set_proxy("localhost", 3128);
cli.set_proxy_basic_auth("hello", "world");
{
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
}
{
auto res =
cli.Get("/basic-auth/hello/world",
{make_basic_authentication_header("hello", "world")});
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
}
{
cli.set_basic_auth("hello", "world");
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
}
{
cli.set_basic_auth("hello", "bad");
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
}
{
cli.set_basic_auth("bad", "world");
auto res = cli.Get("/basic-auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
}
}
TEST(BaseAuthTest, NoSSL) {
Client cli("httpbin.org");
BaseAuthTestFromHTTPWatch(cli);
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(BaseAuthTest, SSL) {
SSLClient cli("httpbin.org");
BaseAuthTestFromHTTPWatch(cli);
}
#endif
// ----------------------------------------------------------------------------
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
template <typename T>
void DigestAuthTestFromHTTPWatch(T& cli) {
cli.set_proxy("localhost", 3129);
cli.set_proxy_digest_auth("hello", "world");
{
auto res = cli.Get("/digest-auth/auth/hello/world");
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
}
{
std::vector<std::string> paths = {
"/digest-auth/auth/hello/world/MD5",
"/digest-auth/auth/hello/world/SHA-256",
"/digest-auth/auth/hello/world/SHA-512",
"/digest-auth/auth-int/hello/world/MD5",
};
cli.set_digest_auth("hello", "world");
for (auto path : paths) {
auto res = cli.Get(path.c_str());
ASSERT_TRUE(res != nullptr);
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
}
cli.set_digest_auth("hello", "bad");
for (auto path : paths) {
auto res = cli.Get(path.c_str());
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(401, res->status);
}
// NOTE: Until httpbin.org fixes issue #46, the following test is commented
// out. Plese see https://httpbin.org/digest-auth/auth/hello/world
// cli.set_digest_auth("bad", "world");
// for (auto path : paths) {
// auto res = cli.Get(path.c_str());
// ASSERT_TRUE(res != nullptr);
// EXPECT_EQ(401, res->status);
// }
}
}
TEST(DigestAuthTest, SSL) {
SSLClient cli("httpbin.org");
DigestAuthTestFromHTTPWatch(cli);
}
TEST(DigestAuthTest, NoSSL) {
Client cli("httpbin.org");
DigestAuthTestFromHTTPWatch(cli);
}
#endif
// ----------------------------------------------------------------------------
template <typename T>
void KeepAliveTest(T& cli, bool basic) {
cli.set_proxy("localhost", basic ? 3128 : 3129);
if (basic) {
cli.set_proxy_basic_auth("hello", "world");
} else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli.set_proxy_digest_auth("hello", "world");
#endif
}
cli.set_follow_location(true);
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli.set_digest_auth("hello", "world");
#endif
{
auto res = cli.Get("/httpbin/get");
EXPECT_EQ(200, res->status);
}
{
auto res = cli.Get("/httpbin/redirect/2");
EXPECT_EQ(200, res->status);
}
{
std::vector<std::string> paths = {
"/httpbin/digest-auth/auth/hello/world/MD5",
"/httpbin/digest-auth/auth/hello/world/SHA-256",
"/httpbin/digest-auth/auth/hello/world/SHA-512",
"/httpbin/digest-auth/auth-int/hello/world/MD5",
};
for (auto path: paths) {
auto res = cli.Get(path.c_str());
EXPECT_EQ("{\n \"authenticated\": true, \n \"user\": \"hello\"\n}\n", res->body);
EXPECT_EQ(200, res->status);
}
}
{
int count = 10;
while (count--) {
auto res = cli.Get("/httpbin/get");
EXPECT_EQ(200, res->status);
}
}
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(KeepAliveTest, NoSSLWithBasic) {
Client cli("nghttp2.org");
KeepAliveTest(cli, true);
}
TEST(KeepAliveTest, SSLWithBasic) {
SSLClient cli("nghttp2.org");
KeepAliveTest(cli, true);
}
TEST(KeepAliveTest, NoSSLWithDigest) {
Client cli("nghttp2.org");
KeepAliveTest(cli, false);
}
TEST(KeepAliveTest, SSLWithDigest) {
SSLClient cli("nghttp2.org");
KeepAliveTest(cli, false);
}
#endif
+1
View File
@@ -0,0 +1 @@
abcde
+8
View File
@@ -0,0 +1,8 @@
<html>
<head>
</head>
<body>
<a href="/dir/test.html">Test</a>
<a href="/hi">hi</a>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
test.html
+8
View File
@@ -0,0 +1,8 @@
<html>
<head>
</head>
<body>
<a href="/dir/test.html">Test</a>
<a href="/hi">hi</a>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
test.html