Szontágh Ferenc
2025-03-12 77bc7063534ab317a2ef96249a4f78198d01ef01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#ifndef CURL_HTTPS_HANDLER_H
#define CURL_HTTPS_HANDLER_H
 
#include <curl/curl.h>
#include <iostream>
#include <map>
#include <wx/filesys.h>
#include <wx/log.h>
#include <wx/mstream.h>
#include <wx/webview.h>
 
class CurlHttpsHandler : public wxWebViewHandler {
public:
  CurlHttpsHandler() : wxWebViewHandler("phttps") {}
 
  wxFSFile *GetFile(const wxString &url) override {
    wxString uri = url.SubString(1, url.length() - 1);
 
    std::cout << "CurlHttpsHandler::GetFile called with uri: " << uri
              << std::endl;
 
    // Check cache first
    if (cache.find(uri) != cache.end()) {
      return new wxFSFile(
          new wxMemoryInputStream(cache[uri].data(), cache[uri].size()), uri,
          "text/html", wxEmptyString, wxDateTime::Now());
      new wxMemoryInputStream(cache[uri].data(), cache[uri].size()), uri,
          "text/html";
    }
 
    // Fetch content using curl
    std::pair<std::string, std::string> response = FetchURL(uri.ToStdString());
    if (response.second.empty()) {
      wxLogError("Failed to load %s", response.first);
      return nullptr;
    }
    auto content = response.second;
    std::string finalUrl = response.first;
    uri = wxString::FromUTF8(finalUrl.c_str());
 
    // Cache the response
    std::vector<char> buffer(content.begin(), content.end());
    cache[uri] = buffer;
 
    return new wxFSFile(
        new wxMemoryInputStream(cache[uri].data(), cache[uri].size()), uri,
        "text/html", wxEmptyString, wxDateTime::Now());
  }
 
private:
  static size_t WriteCallback(void *contents, size_t size, size_t nmemb,
                              std::string *output) {
    size_t totalSize = size * nmemb;
    output->append((char *)contents, totalSize);
    return totalSize;
  }
 
  std::pair<std::string, std::string> FetchURL(const std::string &url) {
    CURL *curl = curl_easy_init();
    std::string response;
    std::string finalUrl;
 
    if (curl) {
      curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
                       1L);
 
      if (curl_easy_perform(curl) == CURLE_OK) {
        char *effectiveUrl = nullptr;
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effectiveUrl);
        if (effectiveUrl) {
          finalUrl = effectiveUrl;
        }
      }
 
      curl_easy_cleanup(curl);
    }
 
    return {finalUrl, response};
  }
 
  std::map<wxString, std::vector<char>> cache;
};
 
#endif // CURL_HTTPS_HANDLER_H