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.
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.
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.
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.
* 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
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.
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.
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.
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.
This commit modifies the signature of the `Progress` callback
so that its return value will indicate whether the request shall
continue to be processed by returning `true`, or if it shall
be aborted by returning `false`. Such modification will allow
one to cancel an ongoing request before it has completed.
When migrating, developers should modify there `Progress`
callbacks to always return `true` by default in case there
do not want to benefit from the cancelation feature.
A few unit tests use cases were provided, but anyone should feel
free to provide additional uses cases that they find relevant.
This fixes#46 by allowing the user to separate the port bind from the
blocking listen(). Two new API functions bind_to_any_port() (which
returns the system-assigned port) and listen_after_bind() are equivalent
to the existing listen().