curl/Handler: disallow OnData() to throw
This eliminates some complexity from class CurlRequest.
This commit is contained in:
parent
1e3089ffb7
commit
1f312b2e42
|
@ -59,7 +59,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Response body data has been received.
|
* Response body data has been received.
|
||||||
*
|
*
|
||||||
* May throw #Pause.
|
* May throw #Pause (but nothing else).
|
||||||
*/
|
*/
|
||||||
virtual void OnData(ConstBuffer<void> data) = 0;
|
virtual void OnData(ConstBuffer<void> data) = 0;
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,7 @@
|
||||||
|
|
||||||
CurlRequest::CurlRequest(CurlGlobal &_global,
|
CurlRequest::CurlRequest(CurlGlobal &_global,
|
||||||
CurlResponseHandler &_handler)
|
CurlResponseHandler &_handler)
|
||||||
:global(_global), handler(_handler),
|
:global(_global), handler(_handler)
|
||||||
postpone_error_event(global.GetEventLoop(),
|
|
||||||
BIND_THIS_METHOD(OnPostponeError))
|
|
||||||
{
|
{
|
||||||
error_buffer[0] = 0;
|
error_buffer[0] = 0;
|
||||||
|
|
||||||
|
@ -243,13 +241,6 @@ CurlRequest::DataReceived(const void *ptr, size_t received_size) noexcept
|
||||||
return received_size;
|
return received_size;
|
||||||
} catch (CurlResponseHandler::Pause) {
|
} catch (CurlResponseHandler::Pause) {
|
||||||
return CURL_WRITEFUNC_PAUSE;
|
return CURL_WRITEFUNC_PAUSE;
|
||||||
} catch (...) {
|
|
||||||
state = State::CLOSED;
|
|
||||||
/* move the CurlResponseHandler::OnError() call into a
|
|
||||||
"safe" stack frame */
|
|
||||||
postponed_error = std::current_exception();
|
|
||||||
postpone_error_event.Schedule();
|
|
||||||
return CURL_WRITEFUNC_PAUSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -266,11 +257,3 @@ CurlRequest::WriteFunction(char *ptr, size_t size, size_t nmemb,
|
||||||
|
|
||||||
return c.DataReceived(ptr, size);
|
return c.DataReceived(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CurlRequest::OnPostponeError() noexcept
|
|
||||||
{
|
|
||||||
assert(postponed_error);
|
|
||||||
|
|
||||||
handler.OnError(postponed_error);
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,11 +31,9 @@
|
||||||
#define CURL_REQUEST_HXX
|
#define CURL_REQUEST_HXX
|
||||||
|
|
||||||
#include "Easy.hxx"
|
#include "Easy.hxx"
|
||||||
#include "event/DeferEvent.hxx"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
struct StringView;
|
struct StringView;
|
||||||
class CurlGlobal;
|
class CurlGlobal;
|
||||||
|
@ -57,18 +55,6 @@ class CurlRequest final {
|
||||||
|
|
||||||
std::multimap<std::string, std::string> headers;
|
std::multimap<std::string, std::string> headers;
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception caught by DataReceived(), which will be
|
|
||||||
* forwarded into a "safe" stack frame by
|
|
||||||
* #postpone_error_event. This works around the
|
|
||||||
* problem that libcurl crashes if you call
|
|
||||||
* curl_multi_remove_handle() from within the WRITEFUNCTION
|
|
||||||
* (i.e. DataReceived()).
|
|
||||||
*/
|
|
||||||
std::exception_ptr postponed_error;
|
|
||||||
|
|
||||||
DeferEvent postpone_error_event;
|
|
||||||
|
|
||||||
/** error message provided by libcurl */
|
/** error message provided by libcurl */
|
||||||
char error_buffer[CURL_ERROR_SIZE];
|
char error_buffer[CURL_ERROR_SIZE];
|
||||||
|
|
||||||
|
@ -167,8 +153,6 @@ private:
|
||||||
|
|
||||||
void HeaderFunction(StringView s) noexcept;
|
void HeaderFunction(StringView s) noexcept;
|
||||||
|
|
||||||
void OnPostponeError() noexcept;
|
|
||||||
|
|
||||||
/** called by curl when new data is available */
|
/** called by curl when new data is available */
|
||||||
static size_t _HeaderFunction(char *ptr, size_t size, size_t nmemb,
|
static size_t _HeaderFunction(char *ptr, size_t size, size_t nmemb,
|
||||||
void *stream) noexcept;
|
void *stream) noexcept;
|
||||||
|
|
|
@ -50,8 +50,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnData(ConstBuffer<void> data) override {
|
void OnData(ConstBuffer<void> data) override {
|
||||||
if (fwrite(data.data, data.size, 1, stdout) != 1)
|
try {
|
||||||
throw std::runtime_error("Failed to write");
|
if (fwrite(data.data, data.size, 1, stdout) != 1)
|
||||||
|
throw std::runtime_error("Failed to write");
|
||||||
|
} catch (...) {
|
||||||
|
OnError(std::current_exception());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEnd() override {
|
void OnEnd() override {
|
||||||
|
|
Loading…
Reference in New Issue