2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file wrt-wk2-bundle.cpp
18 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
19 * @brief Implementation file for view logic for Webkit2
21 #include "wrt-wk2-bundle.h"
24 #include <WKBundleInitialize.h>
25 #include <WKBundlePage.h>
26 #include <WKBundleFrame.h>
27 #include <WKURLRequest.h>
32 #include <WKURLResponseEfl.h>
39 #include <openssl/sha.h>
40 #include <openssl/hmac.h>
41 #include <openssl/evp.h>
42 #include <openssl/bio.h>
43 #include <openssl/buffer.h>
45 #include <dpl/log/log.h>
46 #include <dpl/foreach.h>
47 #include <dpl/assert.h>
48 #include <dpl/wrt-dao-ro/WrtDatabase.h>
49 #include <dpl/localization/localization_utils.h>
50 #include <dpl/string.h>
51 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
52 #include <dpl/utils/mime_type_utils.h>
53 #include <dpl/localization/LanguageTagsProvider.h>
55 #include <wrt_plugin_module.h>
56 #include <profiling_util.h>
59 #include <appcore-efl.h>
61 #include "messages_names.h"
64 #include <scheme_action_map_type.h>
65 #include <scheme_action_map_data.h>
67 #include <js_overlay_types.h>
69 // URI localization on WebProcess side
70 #include "bundle_uri_handling.h"
73 const char * const uriChangedMessageName = "uri_changed_msg";
74 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
75 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
76 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
77 const char * const URICHANGE_BLOCKED_URL = "null";
78 const char * const SCHEME_HTTP = "http";
79 const char * const SCHEME_HTTPS = "https";
80 const char * const SCHEME_FILE = "file://";
81 const char * const DATA_STRING = "data:";
82 const char * const BASE64_STRING = ";base64,";
85 Bundle::Bundle(WKBundleRef bundle) :
93 m_widgetType(WrtDB::APP_TYPE_UNKNOWN)
95 LOG_PROFILE_START("Bundle attachToThread");
96 WrtDB::WrtDatabase::attachToThreadRO();
97 m_uriChangedMessage = WKStringCreateWithUTF8CString(uriChangedMessageName);
98 LOG_PROFILE_STOP("Bundle attachToThread");
103 WrtDB::WrtDatabase::detachFromThread();
105 if (!m_pagesList.empty())
107 LogError("There are not closed pages!");
110 WKRelease(m_uriChangedMessage);
114 void Bundle::didCreatePageCallback(
115 WKBundleRef /*bundle*/,
116 WKBundlePageRef page,
117 const void* clientInfo)
119 LOG_PROFILE_START("didCreatePageCallback");
120 LogDebug("didCreatePageCallback called");
121 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
122 This->didCreatePage(page);
123 LOG_PROFILE_STOP("didCreatePageCallback");
126 void Bundle::didReceiveMessageCallback(
127 WKBundleRef /*bundle*/,
128 WKStringRef messageName,
129 WKTypeRef messageBody,
130 const void *clientInfo)
132 LogDebug("didReceiveMessageCallback called");
133 Bundle* bundle = static_cast<Bundle*>(const_cast<void*>(clientInfo));
134 bundle->didReceiveMessage(messageName, messageBody);
137 void Bundle::willDestroyPageCallback(
138 WKBundleRef /*bundle*/,
139 WKBundlePageRef page,
140 const void* clientInfo)
142 LogDebug("willDestroyPageCallback called");
143 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
144 This->willDestroyPage(page);
147 void Bundle::didCreatePage(WKBundlePageRef page)
149 auto mainFrame = WKBundlePageGetMainFrame(page);
150 auto context = WKBundleFrameGetJavaScriptContext(mainFrame);
151 m_pagesList.push_back(page);
152 m_pageGlobalContext[page] = context;
153 LogDebug("created Page : " << page << " created JSContext : " << context);
155 WKBundlePageResourceLoadClient resourceLoadClient = {
156 kWKBundlePageResourceLoadClientCurrentVersion, /* version */
157 this, /* clientinfo */
158 0, /* didInitiateLoadForResource */
159 willSendRequestForFrameCallback, /* willSendRequestForFrame */
160 0, /* didReceiveResponseForResource */
161 0, /* didReceiveContentLengthForResource */
162 didFinishLoadForResourceCallback, /* didFinishLoadForResource */
163 0, /* didFailLoadForResource */
164 0, /* shouldCacheResponse */
165 0, /* shouldUseCredentialStorage */
167 WKBundlePageSetResourceLoadClient(page, &resourceLoadClient);
169 WKBundlePageLoaderClient loaderClient = {
170 kWKBundlePageLoaderClientCurrentVersion,
171 this, /* clientinfo */
172 didStartProvisionalLoadForFrameCallback, /* didStartProvisionalLoadForFrame */
173 0, /* didReceiveServerRedirectForProvisionalLoadForFrame */
174 0, /* didFailProvisionalLoadWithErrorForFrame */
175 didCommitLoadForFrameCallback, /* didCommitLoadForFrame */
176 0, /* didFinishDocumentLoadForFrame */
177 0, /* didFinishLoadForFrame */
178 0, /* didFailLoadWithErrorForFrame */
179 0, /* didSameDocumentNavigationForFrame */
180 0, /* didReceiveTitleForFrame */
181 0, /* didFirstLayoutForFrame */
182 0, /* didFirstVisuallyNonEmptyLayoutForFrame */
183 didRemoveFrameFromHierarchyCallback, /* didRemoveFrameFromHierarchy */
184 0, /* didDisplayInsecureContentForFrame */
185 0, /* didRunInsecureContentForFrame */
186 0, /* didClearWindowObjectForFrame */
187 0, /* didCancelClientRedirectForFrame */
188 0, /* willPerformClientRedirectForFrame */
189 0, /* didHandleOnloadEventsForFrame */
190 0, /* didLayoutForFrame */
191 0, /* didNewFirstVisuallyNonEmptyLayout */
192 0, /* didDetectXSSForFrame */
193 0, /* shouldGoToBackForwardListItem */
194 0, /* globalObjectIsAvailableForFrame */
195 0, /* willDisconnectDOMWindowExtensionFromGlobalObject */
196 0, /* didReconnectDOMWindowExtensionToGlobalObject */
197 0, /* willDestroyGlobalObjectForDOMWindowExtension */
198 0, /* didFinishProgress */
199 0, /* shouldForceUniversalAccessFromLocalURL */
200 0, /* didReceiveIntentForFrame */
201 0, /* registerIntentServiceForFrame */
203 WKBundlePageSetPageLoaderClient(page, &loaderClient);
206 WKBundlePagePolicyClient policyClient = {
207 kWKBundlePagePolicyClientCurrentVersion, /* version */
208 this, /* clientInfo */
209 pageDecidePolicyForNavigationActionCallback, /* decidePolicyForNavigationAction */
210 0, /* decidePolicyForNewWindowAction */
211 pageDecidePolicyForResponseCallback, /* decidePolicyForResponse */
212 0, /* unableToImplementPolicy */
214 WKBundlePageSetPolicyClient(page, &policyClient);
218 void Bundle::willDestroyPage(WKBundlePageRef page)
220 LogDebug("Destroyed page : " << page);
222 auto context = m_pageGlobalContext[page];
223 m_pagesList.remove(page);
224 m_pageGlobalContext.erase(page);
225 m_pageContext.erase(page);
227 PluginModule::stop(context);
230 void Bundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
232 LogDebug("got message type: " << toString(messageName).c_str());
233 if (WKStringIsEqualToUTF8CString(messageName,
234 BundleMessages::START))
236 if (!messageBody || WKStringGetTypeID() != WKGetTypeID(messageBody)) {
237 LogError("Wrong message format received, ignoring");
241 auto msgString = toString(static_cast<WKStringRef>(messageBody));
242 LogDebug("Got message text: " << msgString);
243 LogDebug("loading Page : " << m_pagesList.back() <<
244 " loading JSContext : " <<
245 m_pageGlobalContext[m_pagesList.back()]);
246 // set information from ui process
247 std::stringstream ssMsg(msgString);
248 std::string argScale;
249 std::string argEncodedBundle;
250 std::string argTheme;
252 ssMsg >> m_widgetHandle;
255 ssMsg >> argEncodedBundle;
257 ssMsg >> m_encrypted;
259 WrtDB::WidgetDAOReadOnly dao(m_widgetHandle);
260 /* This type of message is received when widget is restarting
261 * (proably in other situation too). Widget restart can be
262 * called after system language change so language tags have to
264 * Do NOT MOVE LanguageTags reset before m_widgetHandle initialization
266 // reset language tags (create new tags based on system locales)
267 LanguageTagsProviderSingleton::Instance().resetLanguageTags();
268 DPL::OptionalString defaultLocale = dao.getDefaultlocale();
269 LanguageTags tags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
270 // check if default widget language exists in language's list
271 if (!!defaultLocale &&
272 std::find(tags.begin(), tags.end(), *defaultLocale) == tags.end())
274 if (tags.size() < 2) {
275 tags.push_front(*defaultLocale);
277 LanguageTags::iterator placeToInsert = tags.end();
279 if (*placeToInsert != L"") { ++placeToInsert; }
280 tags.insert(placeToInsert, *defaultLocale);
283 LogDebug("Current widget locales (language tags):");
285 LogDebug("Locale: " << *it);
287 LanguageTagsProviderSingleton::Instance().setLanguageTags(tags);
288 // ** Language tags setting completed **
290 if (argScale != "null" && argScale[0] == '_')
292 argScale.erase(0, 1);
294 std::stringstream ssScale(argScale);
298 if (argEncodedBundle != "null" && argEncodedBundle[0] == '_')
300 argEncodedBundle.erase(0, 1);
302 m_encodedBundle = argEncodedBundle;
305 if (argTheme != "null" && argTheme[0] == '_')
307 argTheme.erase(0, 1);
312 m_widgetType = dao.getWidgetType();
313 LogDebug("m_widgetType : " << m_widgetType.getApptypeToString() <<
314 "(m_widgetHandle:" << m_widgetHandle << ")");
316 else if (WKStringIsEqualToUTF8CString(messageName,
317 BundleMessages::SHUTDOWN))
319 LogDebug("shutdown plugins");
320 if (m_pagesList.empty())
322 PluginModule::shutdown();
326 LogInfo("PluginModule shutdown ignored, there are still alive pages!");
329 else if (WKStringIsEqualToUTF8CString(messageName,
330 BundleMessages::SET_CUSTOM_PROPERTIES))
332 LogDebug("reset custom properties of window objects");
333 // set information from ui process
334 auto msgString = toString(static_cast<WKStringRef>(messageBody));
336 std::string argScale;
337 std::string argEncodedBundle;
338 std::string argTheme;
340 std::stringstream ssMsg(msgString);
342 ssMsg >> argEncodedBundle;
345 if(argScale != "null" && argScale[0] == '_')
347 argScale.erase(0, 1);
349 std::stringstream ssScale(argScale);
353 if(argEncodedBundle != "null" && argEncodedBundle[0] == '_')
355 argEncodedBundle.erase(0, 1);
357 m_encodedBundle = argEncodedBundle;
360 if(argTheme != "null" && argTheme[0] == '_')
362 argTheme.erase(0, 1);
367 //apply for each context
368 PageGlobalContext::iterator it = m_pageGlobalContext.begin();
369 for (; it != m_pageGlobalContext.end(); ++it)
371 PluginModule::setCustomProperties(it->second,
373 m_encodedBundle.c_str(),
377 else if (WKStringIsEqualToUTF8CString(
379 BundleMessages::DISPATCH_JAVASCRIPT_EVENT))
381 LogDebug("dispatch javascript event to created frames");
382 // set information from ui process
383 auto text = toString(static_cast<WKStringRef>(messageBody));
386 std::stringstream ss(text);
389 // set arguments to be sent to js handler of this custom event
392 //apply for each context
393 PageGlobalContext::iterator it = m_pageGlobalContext.begin();
394 for (; it != m_pageGlobalContext.end(); ++it)
396 PluginModule::dispatchJavaScriptEvent(
398 static_cast<WrtPlugins::W3C::CustomEventType>(eventType),
408 WKURLRequestRef Bundle::willSendRequestForFrameCallback(
409 WKBundlePageRef /*page*/,
410 WKBundleFrameRef /*frame*/,
411 uint64_t /*resourceIdentifier*/,
412 WKURLRequestRef request,
413 WKURLResponseRef /*response*/,
414 const void *clientInfo)
416 LogDebug("willSendRequestForFrameCallback called");
417 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
418 return This->willSendRequestForFrame(request);
421 void Bundle::didStartProvisionalLoadForFrameCallback(
422 WKBundlePageRef page,
423 WKBundleFrameRef frame,
424 WKTypeRef* /*userData*/,
425 const void *clientInfo)
427 LogDebug("didStartProvisionalLoadForFrameCallback called");
428 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
430 if (This->m_pageGlobalContext.count(page) == 0)
434 if (This->m_pageContext.count(page) == 0)
439 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
441 ContextSet::iterator i = This->m_pageContext[page].find(context);
443 if (i == This->m_pageContext[page].end())
445 LogDebug("Initially attached frame");
449 This->m_pageContext[page].erase(i);
451 PluginModule::unloadFrame(context);
454 void Bundle::didRemoveFrameFromHierarchyCallback(
455 WKBundlePageRef page,
456 WKBundleFrameRef frame,
457 WKTypeRef* /*userData*/,
458 const void *clientInfo)
460 LogDebug("didFinishLoadForResourceCallback called");
461 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
463 if (This->m_pageGlobalContext.count(page) == 0)
467 if (This->m_pageContext.count(page) == 0)
472 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
474 ContextSet::iterator i = This->m_pageContext[page].find(context);
476 if (i == This->m_pageContext[page].end())
478 LogWarning("Tried to unload frame which has never been loaded");
482 This->m_pageContext[page].erase(i);
484 PluginModule::unloadFrame(context);
487 void Bundle::didFinishLoadForResourceCallback(
488 WKBundlePageRef /*page*/,
489 WKBundleFrameRef frame,
490 uint64_t /*resourceIdentifier*/,
491 const void* clientInfo)
493 LogDebug("didFinishLoadForResourceCallback called");
494 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
496 WKURLRef url = WKBundleFrameCopyURL(frame);
497 WKTypeRef retVal = NULL;
499 // If url is NULL, this url has been already blocked by willsend
500 // So current page should be moved to previous page
503 if (WKBundleFrameIsMainFrame(frame))
505 LogInfo("url is NULL. Go back to previous view");
506 WKStringRef blockedURL =
507 WKStringCreateWithUTF8CString(URICHANGE_BLOCKED_URL);
508 WKBundlePostSynchronousMessage(This->m_bundle,
509 This->m_uriChangedMessage,
515 LogInfo("Blocked uri in IFrame.");
522 void Bundle::didCommitLoadForFrameCallback(
523 WKBundlePageRef page,
524 WKBundleFrameRef frame,
525 WKTypeRef* /*userData*/,
526 const void *clientInfo)
528 LogInfo("didCommitLoadForFrameCallback called");
529 LOG_PROFILE_START("didCommitLoadForFrameCallback");
530 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
532 WKURLRef url = WKBundleFrameCopyURL(frame);
533 WKTypeRef retVal = NULL;
536 LogInfo("url is NULL");
540 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
542 This->m_pageContext[page].insert(context);
544 if (!WKBundleFrameIsMainFrame(frame))
546 LogInfo("frame isn't main frame");
547 PluginModule::start(This->m_widgetHandle,
550 This->m_encodedBundle.c_str(),
551 This->m_theme.c_str());
552 PluginModule::loadFrame(context);
556 std::string scheme = getScheme(toString(url));
557 std::string result = URICHANGE_PLUGIN_RESTART;
559 if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS)
561 WKStringRef urlStr = WKURLCopyString(url);
562 WKBundlePostSynchronousMessage(This->m_bundle,
563 This->m_uriChangedMessage,
569 result = toString(static_cast<WKStringRef>(retVal));
571 LogInfo("result from UI process : " << result);
573 if (result == URICHANGE_PLUGIN_STOP_ONLY)
575 PluginModule::stop(context);
577 else if (result == URICHANGE_PLUGIN_RESTART)
579 PluginModule::stop(context);
580 This->m_pageGlobalContext[page] = context;
581 LOG_PROFILE_START("PluginModule start");
582 PluginModule::start(This->m_widgetHandle,
585 This->m_encodedBundle.c_str(),
586 This->m_theme.c_str() );
587 LOG_PROFILE_STOP("PluginModule start");
589 PluginModule::loadFrame(context);
591 LOG_PROFILE_STOP("didCommitLoadForFrameCallback");
594 WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationActionCallback(
595 WKBundlePageRef page,
596 WKBundleFrameRef frame,
597 WKBundleNavigationActionRef navigationAction,
598 WKURLRequestRef request,
600 const void* clientInfo)
602 LogDebug("pageDecidePolicyForNavigationActionCallback called");
604 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
606 return This->pageDecidePolicyForNavigationAction(page,
613 WKBundlePagePolicyAction Bundle::pageDecidePolicyForResponseCallback(
614 WKBundlePageRef /* page */,
615 WKBundleFrameRef /* frame */,
616 WKURLResponseRef response,
617 WKURLRequestRef /* request */,
618 WKTypeRef* /* userData */,
619 const void* /* clientInfo */)
621 LogDebug("pageDecidePolicyForResponseCallback called");
623 char const * const HTML_MIME = "text/html";
626 WKStringRef contentTypeRef = WKURLResponseEflCopyContentType(response);
628 std::string contentType = toString(contentTypeRef);
629 LogDebug("contentTypeRef : " << contentType);
630 WKRelease(contentTypeRef);
632 if (contentType == HTML_MIME)
634 LogDebug("Accepting HTML_MIME type");
636 return WKBundlePagePolicyActionUse;
639 return WKBundlePagePolicyActionPassThrough;
642 WKURLRequestRef Bundle::willSendRequestForFrame(WKURLRequestRef request)
644 LogDebug("willSendReq got " << toString(request).c_str());
645 WKURLRef url = WKURLRequestCopyURL(request);
646 WKStringRef urlStr = WKURLCopyString(url);
648 bool is_xhr = true; // Webkit should inform if it's XHR
649 DPL::String dplurl = DPL::FromUTF8String(toString(urlStr));
651 DPL::Optional<DPL::String> newurl = BundleURIHandling::processURI(dplurl,
652 is_xhr, m_widgetHandle, m_bundle);
654 if (newurl.IsNull()) {
655 LogDebug("URI is blocked");
659 LogDebug("URI processing result: " << *newurl );
660 std::string tmpUrlStr = DPL::ToUTF8String(*newurl);
661 if (tmpUrlStr.empty()) {
662 LogDebug("uri is blocked");
667 WKURLRef tmpUrl = WKURLCreateWithUTF8CString(tmpUrlStr.c_str());
668 std::string scheme = toString(WKURLCopyScheme(url));
670 // Return value must contain details information of input
671 // WKURLRequestRef. Current webkit2 doesn't support api that
672 // copy WKURLRequestRef or change url only. Before webkit2
673 // support api, callback return original WKURLRequestRef in the
674 // case of external scheme
676 // external scheme also need to send message to UI process for
677 // checking roaming and security
678 if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) {
679 LogDebug("external scheme return original WKURLRequestRef");
684 std::string checkUrl = toString(tmpUrl);
688 if(isEncryptedResource(checkUrl, getFileSize)) {
689 std::string decryptString = DecryptResource(checkUrl,
691 if (!decryptString.empty()) {
692 std::string destString = DATA_STRING;
694 std::string mimeString =
695 DPL::ToUTF8String(MimeTypeUtils::identifyFileMimeType(
696 DPL::FromUTF8String(checkUrl)));
698 destString += mimeString;
699 destString += BASE64_STRING;
701 decryptString.insert(0, destString);
704 WKURLCreateWithUTF8CString(decryptString.c_str());
706 WKURLRequestRef req = WKURLRequestCreateWithWKURL(destUrl);
708 LogDebug("return value " << decryptString << "]]");
713 WKURLRequestRef req = WKURLRequestCreateWithWKURL(tmpUrl);
715 LogDebug("return value " << toString(req).c_str());
721 WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationAction(
722 WKBundlePageRef /* page */,
723 WKBundleFrameRef frame,
724 WKBundleNavigationActionRef /* navigationAction */,
725 WKURLRequestRef request,
726 WKTypeRef* /* userData */)
728 using namespace ViewModule;
729 using namespace ViewModule::SchemeActionMap;
731 char const * const TIZEN_SCHEME = "tizen";
733 std::string request_uri = toString(request);
735 LogInfo("Uri being checked: " << request_uri);
738 std::string request_scheme = getScheme(request_uri);
741 if ( request_scheme == TIZEN_SCHEME )
743 return WKBundlePagePolicyActionPassThrough;
747 Scheme scheme(request_scheme);
748 LogDebug("Scheme: " << request_scheme);
750 Scheme::Type type = scheme.GetType();
751 if (type < Scheme::FILE || type >= Scheme::COUNT) {
752 LogError("Invalid scheme: " << request_scheme);
753 return WKBundlePagePolicyActionPassThrough;
756 bool mainFrame = WKBundleFrameIsMainFrame(frame);
757 NavigationContext ctx = mainFrame ? TOP_LEVEL : FRAME_LEVEL;
759 LogDebug("Scheme type: " << type);
760 LogDebug("Navigation context: " << ctx);
761 LogDebug("Application type: " << m_widgetType.getApptypeToString());
765 if (m_widgetType == WrtDB::APP_TYPE_WAC20)
767 action = g_wacActionMap[type][ctx];
769 else if (m_widgetType == WrtDB::APP_TYPE_TIZENWEBAPP)
771 action = g_tizenActionMap[type][ctx];
775 LogError("Unsupported application type: " << type);
776 return WKBundlePagePolicyActionPassThrough;
779 LogDebug("Uri action: " << action);
781 if (action == URI_ACTION_WRT)
783 return WKBundlePagePolicyActionUse;
786 return WKBundlePagePolicyActionPassThrough;
790 std::string Bundle::toString(WKStringRef str)
792 if (WKStringIsEmpty(str)) {
793 return std::string();
795 size_t size = WKStringGetMaximumUTF8CStringSize(str);
796 char buffer[size + 1];
797 WKStringGetUTF8CString(str, buffer, size + 1);
801 std::string Bundle::toString(WKURLRef url)
803 WKStringRef urlStr = WKURLCopyString(url);
804 std::string str = toString(urlStr);
809 std::string Bundle::toString(WKURLRequestRef req)
811 WKURLRef reqUrl = WKURLRequestCopyURL(req);
812 std::string str = toString(reqUrl);
817 std::string Bundle::toString(WKErrorRef err)
819 WKStringRef domErr = WKErrorCopyDomain(err);
820 WKStringRef desc = WKErrorCopyLocalizedDescription(err);
821 std::string str = toString(domErr) + "\n" + toString(desc);
827 std::string Bundle::getScheme(std::string uri)
829 std::size_t found = uri.find(':');
832 if (found != std::string::npos)
834 str = uri.substr(0, found);
840 bool Bundle::isEncryptedResource(std::string Url, int &size)
842 std::string filePath;
844 size_t pos = Url.find_first_not_of(SCHEME_FILE);
845 if ( std::string::npos != pos) {
846 filePath = Url.substr(pos-1);
849 if (m_encryptedFiles.empty()) {
850 WrtDB::WidgetDAOReadOnly(m_widgetHandle).
851 getEncryptedFileList(m_encryptedFiles);
854 WrtDB::EncryptedFileInfo info;
855 std::set<WrtDB::EncryptedFileInfo>::iterator it;
856 info.fileName = DPL::FromUTF8String(filePath);
858 if ((0 == strncmp(Url.c_str(), SCHEME_FILE, strlen(SCHEME_FILE))) &&
859 (m_encryptedFiles.end() != (it =
860 m_encryptedFiles.find(info)))) {
861 LogDebug(" info file name : " << it->fileName);
862 LogDebug(" info file size : " << it->fileSize);
869 std::string Bundle::DecryptResource(std::string resource, int size)
871 std::string filePath;
873 size_t pos = resource.find_first_not_of(SCHEME_FILE);
874 if ( std::string::npos != pos) {
875 filePath = resource.substr(pos-1);
879 if (0 == stat(filePath.c_str(), &buf)) {
880 if (NULL == m_resDec) {
881 using namespace WrtDB;
882 DPL::Optional<DPL::String> pkgName =
883 WidgetDAOReadOnly(m_widgetHandle).getPkgname();
885 WRTDecryptor::ResourceDecryptor(DPL::ToUTF8String(*pkgName));
886 WrtDB::WidgetDAOReadOnly(m_widgetHandle).
887 getEncryptedFileList(m_encryptedFiles);
889 size_t bufSize = buf.st_size;
890 unsigned char contents[bufSize];
891 memset(contents, 0, bufSize);
893 FILE* fp = fopen(filePath.c_str(), "rb");
895 LogDebug("Couldnot open file : " << filePath);
896 return std::string();
899 size_t ret = fread(contents, sizeof(unsigned char), buf.st_size, fp);
900 if (ret < static_cast<size_t>(buf.st_size) ){
901 LogDebug("Couldnot read file : " << filePath);
903 return std::string();
908 LogDebug("resource is encrypted. decrypting....");
909 unsigned char outDecBuf[bufSize];
910 memset(outDecBuf, 0, bufSize);
911 m_resDec->GetDecryptedChunk(contents, outDecBuf, bufSize);
912 memset(outDecBuf+size, '\n', bufSize - size);
914 LogDebug("resource need to encoding base64");
918 b64 = BIO_new(BIO_f_base64());
919 bmem = BIO_new(BIO_s_mem());
920 b64 = BIO_push(b64, bmem);
921 BIO_write(b64, outDecBuf, bufSize);
923 BIO_get_mem_ptr(b64, &bptr);
925 std::string base64Enc((char *)bptr->data, bptr->length-1);
930 return std::string();
937 void WKBundleInitialize(WKBundleRef bundle,
940 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-BUNDLE");
941 LogDebug("Bundle initialized");
943 static Bundle s_bundle = Bundle(bundle);
945 WKBundleClient client = {
946 kWKBundleClientCurrentVersion,
948 &Bundle::didCreatePageCallback,
949 &Bundle::willDestroyPageCallback,
950 0, /* didInitializePageGroup */
951 &Bundle::didReceiveMessageCallback
953 WKBundleSetClient(bundle, &client);