22#include <wx/webview.h>
25#include <wx/filename.h>
34#if !defined(__MINGW32__)
35 #include <wrl/client.h>
36 #include <wrl/event.h>
39using Microsoft::WRL::ComPtr;
40using Microsoft::WRL::Callback;
46bool SaveCookies( wxWebView* aWebView,
const wxString& aTargetFile )
51 void* nativeBackend = aWebView->GetNativeBackend();
55#if defined(__MINGW32__)
59 ICoreWebView2* coreWebView =
static_cast<ICoreWebView2*
>( nativeBackend );
62 ComPtr<ICoreWebView2_2> webView2;
64 if( FAILED( coreWebView->QueryInterface( IID_PPV_ARGS( &webView2 ) ) ) )
66 wxLogDebug(
"Failed to get ICoreWebView2_2 interface. WebView2 runtime might be too old." );
70 ComPtr<ICoreWebView2CookieManager> cookieManager;
72 if( FAILED( webView2->get_CookieManager( &cookieManager ) ) )
74 wxLogDebug(
"Failed to get cookie manager" );
78 nlohmann::json cookieArray = nlohmann::json::array();
79 bool callbackFinished =
false;
82 HRESULT hr = cookieManager->GetCookies(
84 Callback<ICoreWebView2GetCookiesCompletedHandler>(
85 [&]( HRESULT
result, ICoreWebView2CookieList* list ) -> HRESULT
87 if( FAILED(
result ) || !list )
89 wxLogDebug(
"GetCookies failed or returned null list" );
90 callbackFinished =
true;
95 list->get_Count( &count );
97 for( UINT i = 0; i < count; ++i )
99 ComPtr<ICoreWebView2Cookie> cookie;
100 if( FAILED( list->GetValueAtIndex( i, &cookie ) ) )
103 nlohmann::json cookieObj;
105 LPWSTR
name =
nullptr;
106 cookie->get_Name( &
name );
110 cookieObj[
"name"] = std::string( wxString(
name ).ToUTF8() );
111 CoTaskMemFree(
name );
114 LPWSTR value =
nullptr;
115 cookie->get_Value( &value );
119 cookieObj[
"value"] = std::string( wxString( value ).ToUTF8() );
120 CoTaskMemFree( value );
123 LPWSTR domain =
nullptr;
124 cookie->get_Domain( &domain );
128 cookieObj[
"domain"] = std::string( wxString( domain ).ToUTF8() );
129 CoTaskMemFree( domain );
132 LPWSTR
path =
nullptr;
133 cookie->get_Path( &
path );
137 cookieObj[
"path"] = std::string( wxString(
path ).ToUTF8() );
138 CoTaskMemFree(
path );
142 cookie->get_Expires( &expires );
143 cookieObj[
"expires"] =
static_cast<int64_t
>( expires );
146 cookie->get_IsSecure( &secure );
147 cookieObj[
"secure"] = ( secure == TRUE );
149 BOOL httpOnly = FALSE;
150 cookie->get_IsHttpOnly( &httpOnly );
151 cookieObj[
"httpOnly"] = ( httpOnly == TRUE );
153 cookieArray.push_back( cookieObj );
157 callbackFinished =
true;
163 wxLogDebug(
"Failed to initiate GetCookies" );
169 long long startTime = wxGetLocalTimeMillis().GetValue();
171 while( !callbackFinished )
175 if( ( wxGetLocalTimeMillis().GetValue() - startTime ) > 5000 )
177 wxLogDebug(
"Timeout waiting for GetCookies callback" );
189 wxFFile file( aTargetFile,
"wb" );
191 if( !file.IsOpened() )
193 wxLogDebug(
"Failed to open cookie file for writing: %s", aTargetFile );
197 std::string jsonStr = cookieArray.dump( 2 );
198 file.Write( jsonStr.c_str(), jsonStr.size() );
205bool LoadCookies( wxWebView* aWebView,
const wxString& aSourceFile )
210 if( !wxFileName::FileExists( aSourceFile ) )
213 void* nativeBackend = aWebView->GetNativeBackend();
218#if defined(__MINGW32__)
222 ICoreWebView2* coreWebView =
static_cast<ICoreWebView2*
>( nativeBackend );
224 ComPtr<ICoreWebView2_2> webView2;
225 if( FAILED( coreWebView->QueryInterface( IID_PPV_ARGS( &webView2 ) ) ) )
227 wxLogDebug(
"Failed to get ICoreWebView2_2 interface" );
231 ComPtr<ICoreWebView2CookieManager> cookieManager;
233 if( FAILED( webView2->get_CookieManager( &cookieManager ) ) )
235 wxLogDebug(
"Failed to get cookie manager" );
240 wxFFile file( aSourceFile,
"rb" );
242 if( !file.IsOpened() )
244 wxLogDebug(
"Failed to open cookie file for reading: %s", aSourceFile );
248 wxFileOffset len = file.Length();
253 jsonStr.resize( len );
255 if( file.Read( &jsonStr[0], len ) != len )
257 wxLogDebug(
"Failed to read cookie file" );
261 nlohmann::json cookieArray;
265 cookieArray = nlohmann::json::parse( jsonStr );
267 catch(
const nlohmann::json::exception& e )
269 wxLogDebug(
"Failed to parse cookie JSON: %s", e.what() );
273 for(
const auto& cookieObj : cookieArray )
275 std::string
name = cookieObj.value(
"name",
"" );
276 std::string value = cookieObj.value(
"value",
"" );
277 std::string domain = cookieObj.value(
"domain",
"" );
278 std::string
path = cookieObj.value(
"path",
"/" );
279 bool secure = cookieObj.value(
"secure",
false );
280 bool httpOnly = cookieObj.value(
"httpOnly",
false );
281 int64_t expires = cookieObj.value(
"expires", 0 );
283 ComPtr<ICoreWebView2Cookie> cookie;
284 if( FAILED( cookieManager->CreateCookie(
285 wxString::FromUTF8(
name.c_str() ).wc_str(),
286 wxString::FromUTF8( value.c_str() ).wc_str(),
287 wxString::FromUTF8( domain.c_str() ).wc_str(),
288 wxString::FromUTF8(
path.c_str() ).wc_str(),
294 cookie->put_Expires(
static_cast<double>( expires ) );
295 cookie->put_IsSecure( secure ? TRUE : FALSE );
296 cookie->put_IsHttpOnly( httpOnly ? TRUE : FALSE );
298 cookieManager->AddOrUpdateCookie( cookie.Get() );
310 void* nativeBackend = aWebView->GetNativeBackend();
314#if defined(__MINGW32__)
318 ICoreWebView2* coreWebView =
static_cast<ICoreWebView2*
>( nativeBackend );
320 ComPtr<ICoreWebView2_2> webView2;
322 if( FAILED( coreWebView->QueryInterface( IID_PPV_ARGS( &webView2 ) ) ) )
324 wxLogDebug(
"Failed to get ICoreWebView2_2 interface. WebView2 runtime might be too old." );
328 ComPtr<ICoreWebView2CookieManager> cookieManager;
330 if( FAILED( webView2->get_CookieManager( &cookieManager ) ) )
332 wxLogDebug(
"Failed to get cookie manager" );
336 if( FAILED( cookieManager->DeleteAllCookies() ) )
338 wxLogDebug(
"Failed to delete all cookies" );
wxString result
Test unit parsing edge cases and error handling.