@@ -531,52 +531,21 @@ struct Client final {
531
531
const CurlHeaderCallback &curl_header_callback,
532
532
const CurlSetupCallback &curl_setup_callback,
533
533
const Predicate<HttpStatusCode> &successPredicate) {
534
- std::string body_buffer;
535
- std::string header_buffer;
536
- long rawStatusCode = 0 ;
537
-
538
- CURL *curl = curl_easy_init ();
539
- if (curl) {
540
- struct curl_slist *chunk = nullptr ;
541
-
542
- curl_easy_setopt (curl, CURLOPT_URL, url.value ().c_str ());
543
- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_callback);
544
- curl_easy_setopt (curl, CURLOPT_WRITEDATA, &body_buffer);
545
- curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_header_callback (chunk));
546
- curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, write_callback);
547
- curl_easy_setopt (curl, CURLOPT_HEADERDATA, &header_buffer);
548
- curl_easy_setopt (curl, CURLOPT_VERBOSE, debug_);
549
- curl_setup_callback (curl);
550
-
551
- if (url.protocol ().value () == " https" ) {
552
- verify_
553
- ? curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1L )
554
- : curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L );
555
- }
534
+ CurlWrapper curlWrapper{successPredicate, error_callback_};
556
535
557
- CURLcode res = curl_easy_perform (curl);
558
- if (res != CURLE_OK) {
559
- error_callback_ (curl_easy_strerror (res));
560
- curl_easy_cleanup (curl);
561
- curl_slist_free_all (chunk);
562
- return std::nullopt;
563
- }
536
+ curlWrapper.execute_header_callback (curl_header_callback);
537
+ curlWrapper.add_option (CURLOPT_URL, url.value ().c_str ());
538
+ curlWrapper.add_option (CURLOPT_VERBOSE, debug_);
564
539
565
- curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &rawStatusCode);
566
- curl_easy_cleanup (curl);
567
- curl_slist_free_all (chunk);
540
+ if (url.protocol ().value () == " https" ) {
541
+ verify_
542
+ ? curlWrapper.add_option (CURLOPT_SSL_VERIFYPEER, 1L )
543
+ : curlWrapper.add_option (CURLOPT_SSL_VERIFYPEER, 0L );
568
544
}
569
545
570
- HttpStatusCode status{rawStatusCode};
571
- if (successPredicate (status)) {
572
- return std::optional<HttpResponse>({
573
- status,
574
- HttpResponseHeaders{header_buffer},
575
- HttpResponseBody{body_buffer}
576
- });
577
- } else {
578
- return std::nullopt;
579
- }
546
+ curlWrapper.execute_setup_callback (curl_setup_callback);
547
+
548
+ return curlWrapper.execute ();
580
549
}
581
550
582
551
private:
@@ -600,5 +569,69 @@ struct Client final {
600
569
return chunk;
601
570
};
602
571
}
572
+
573
+ struct CurlWrapper final {
574
+ CurlWrapper (const Predicate<HttpStatusCode> &success_predicate, ErrorCallback error_callback)
575
+ : curl_(curl_easy_init())
576
+ , slist_(nullptr )
577
+ , success_predicate_(success_predicate)
578
+ , error_callback_(std::move(error_callback))
579
+ { }
580
+
581
+ ~CurlWrapper () {
582
+ curl_easy_cleanup (curl_);
583
+ curl_slist_free_all (slist_);
584
+ }
585
+
586
+ template <class A >
587
+ void add_option (const CURLoption option, A value) {
588
+ curl_easy_setopt (curl_, option, value);
589
+ }
590
+
591
+ void execute_header_callback (const CurlHeaderCallback &header_callback) {
592
+ slist_ = header_callback (slist_);
593
+ }
594
+
595
+ void execute_setup_callback (const CurlSetupCallback &setup_callback) {
596
+ setup_callback (curl_);
597
+ }
598
+
599
+ [[nodiscard]]
600
+ std::optional<HttpResponse> execute () {
601
+ std::string body_buffer;
602
+ std::string header_buffer;
603
+
604
+ curl_easy_setopt (curl_, CURLOPT_WRITEFUNCTION, write_callback);
605
+ curl_easy_setopt (curl_, CURLOPT_WRITEDATA, &body_buffer);
606
+ curl_easy_setopt (curl_, CURLOPT_HTTPHEADER, slist_);
607
+ curl_easy_setopt (curl_, CURLOPT_HEADERDATA, &header_buffer);
608
+
609
+ CURLcode res = curl_easy_perform (curl_);
610
+ if (res != CURLE_OK) {
611
+ error_callback_ (curl_easy_strerror (res));
612
+ return std::nullopt;
613
+ }
614
+
615
+ long status_code = 0 ;
616
+ curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &status_code);
617
+
618
+ HttpStatusCode status{status_code};
619
+ if (success_predicate_ (status)) {
620
+ return std::optional<HttpResponse>({
621
+ status,
622
+ HttpResponseHeaders{header_buffer},
623
+ HttpResponseBody{body_buffer}
624
+ });
625
+ } else {
626
+ return std::nullopt;
627
+ }
628
+ }
629
+
630
+ private:
631
+ CURL *curl_;
632
+ curl_slist *slist_;
633
+ Predicate<HttpStatusCode> success_predicate_;
634
+ ErrorCallback error_callback_;
635
+ };
603
636
};
604
637
} // namespace SimpleHttp
0 commit comments