curl.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #pragma once
  2. #include <sstream>
  3. #include <string_view>
  4. #include <curl/curl.h>
  5. #include <jvalidate/adapter.h>
  6. #include <jvalidate/compat/expected.h>
  7. #include <jvalidate/forward.h>
  8. #include <jvalidate/uri.h>
  9. namespace jvalidate {
  10. inline size_t transfer_to_buffer(char * data, size_t size, size_t nmemb, void * userdata) {
  11. std::stringstream & ss = *reinterpret_cast<std::stringstream *>(userdata);
  12. size_t actual_size = size * nmemb;
  13. ss << std::string_view(data, actual_size);
  14. return actual_size;
  15. }
  16. template <typename JSON>
  17. auto curl_get(jvalidate::URI const & uri, JSON & out) noexcept
  18. -> detail::expected<void, std::string> {
  19. using jvalidate::adapter::load_file;
  20. using jvalidate::adapter::load_stream;
  21. if (uri.scheme().starts_with("http")) {
  22. std::stringstream ss;
  23. if (CURL * curl = curl_easy_init(); curl) {
  24. curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
  25. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  26. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ss);
  27. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &transfer_to_buffer);
  28. CURLcode res = curl_easy_perform(curl);
  29. curl_easy_cleanup(curl);
  30. if (res == CURLE_OK) {
  31. return load_stream(ss, out);
  32. }
  33. }
  34. return detail::unexpected("curl error");
  35. } else if (uri.scheme() == "file") {
  36. return load_file(uri.resource(), out);
  37. } else {
  38. return detail::unexpected("unknown scheme");
  39. }
  40. }
  41. }