1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "config.h" 27 28 #include "FrameLoaderClientJava.h" 29 30 #include "NotImplemented.h" 31 #include "AuthenticationChallenge.h" 32 #include "WebPage.h" 33 #include "FrameNetworkingContextJava.h" 34 35 #include "Chrome.h" 36 #include "DocumentLoader.h" 37 #include "DNS.h" 38 #include "FormState.h" 39 #include "FrameLoadRequest.h" 40 #include "FrameTree.h" 41 #include "FrameView.h" 42 #include "MainFrame.h" 43 #include "HistoryItem.h" 44 #include "HTMLFormElement.h" 45 #include "MIMETypeRegistry.h" 46 #include "Page.h" 47 #include "PolicyChecker.h" 48 #include "ProgressTracker.h" 49 #include "ScriptController.h" 50 #include "Settings.h" 51 #include "WindowFeatures.h" 52 53 #include <JavaScriptCore/APICast.h> 54 #include <JavaScriptCore/JavaScript.h> 55 56 #include "com_sun_webkit_LoadListenerClient.h" 57 58 59 namespace WebCore { 60 61 namespace FrameLoaderClientJavaInternal { 62 63 static JGClass webPageClass; 64 static JGClass networkContextClass; 65 66 static jmethodID setRequestURLMID; 67 static jmethodID removeRequestURLMID; 68 69 static jmethodID fireLoadEventMID; 70 static jmethodID fireResourceLoadEventMID; 71 static jmethodID canHandleURLMID; 72 73 static jmethodID permitNavigateActionMID; 74 static jmethodID permitRedirectActionMID; 75 static jmethodID permitAcceptResourceActionMID; 76 static jmethodID permitSubmitDataActionMID; 77 static jmethodID permitEnableScriptsActionMID; 78 static jmethodID permitNewWindowActionMID; 79 80 static jmethodID didClearWindowObjectMID; 81 82 static jmethodID frameCreatedMID; 83 static jmethodID frameDestroyedMID; 84 85 static void initRefs(JNIEnv* env) 86 { 87 if (!webPageClass) { 88 webPageClass = JLClass(env->FindClass( 89 "com/sun/webkit/WebPage")); 90 ASSERT(webPageClass); 91 92 setRequestURLMID = env->GetMethodID(webPageClass, "fwkSetRequestURL", "(JILjava/lang/String;)V"); 93 ASSERT(setRequestURLMID); 94 removeRequestURLMID = env->GetMethodID(webPageClass, "fwkRemoveRequestURL", "(JI)V"); 95 ASSERT(removeRequestURLMID); 96 97 fireLoadEventMID = env->GetMethodID(webPageClass, "fwkFireLoadEvent", 98 "(JILjava/lang/String;Ljava/lang/String;DI)V"); 99 ASSERT(fireLoadEventMID); 100 fireResourceLoadEventMID = env->GetMethodID(webPageClass, "fwkFireResourceLoadEvent", 101 "(JIILjava/lang/String;DI)V"); 102 ASSERT(fireResourceLoadEventMID); 103 104 permitNavigateActionMID = env->GetMethodID(webPageClass, "fwkPermitNavigateAction", 105 "(JLjava/lang/String;)Z"); 106 ASSERT(permitNavigateActionMID); 107 108 permitRedirectActionMID = env->GetMethodID(webPageClass, "fwkPermitRedirectAction", 109 "(JLjava/lang/String;)Z"); 110 ASSERT(permitRedirectActionMID); 111 112 permitAcceptResourceActionMID = env->GetMethodID(webPageClass, "fwkPermitAcceptResourceAction", 113 "(JLjava/lang/String;)Z"); 114 ASSERT(permitAcceptResourceActionMID); 115 116 permitSubmitDataActionMID = env->GetMethodID(webPageClass, "fwkPermitSubmitDataAction", 117 "(JLjava/lang/String;Ljava/lang/String;Z)Z"); 118 ASSERT(permitSubmitDataActionMID); 119 120 permitEnableScriptsActionMID = env->GetMethodID(webPageClass, "fwkPermitEnableScriptsAction", 121 "(JLjava/lang/String;)Z"); 122 ASSERT(permitEnableScriptsActionMID); 123 124 permitNewWindowActionMID = env->GetMethodID(webPageClass, "fwkPermitNewWindowAction", 125 "(JLjava/lang/String;)Z"); 126 ASSERT(permitNewWindowActionMID); 127 128 didClearWindowObjectMID = env->GetMethodID(webPageClass, "fwkDidClearWindowObject", "(JJ)V"); 129 ASSERT(didClearWindowObjectMID); 130 131 frameCreatedMID = env->GetMethodID(webPageClass, "fwkFrameCreated", "(J)V"); 132 ASSERT(frameCreatedMID); 133 134 frameDestroyedMID = env->GetMethodID(webPageClass, "fwkFrameDestroyed", "(J)V"); 135 ASSERT(frameDestroyedMID); 136 } 137 if (!networkContextClass) { 138 networkContextClass = JLClass(env->FindClass("com/sun/webkit/network/NetworkContext")); 139 ASSERT(networkContextClass); 140 141 canHandleURLMID = env->GetStaticMethodID(networkContextClass, "canHandleURL", "(Ljava/lang/String;)Z"); 142 ASSERT(canHandleURLMID); 143 } 144 } 145 // This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h". 146 enum { 147 WebKitErrorCannotShowMIMEType = 100, 148 WebKitErrorCannotShowURL = 101, 149 WebKitErrorFrameLoadInterruptedByPolicyChange = 102, 150 WebKitErrorCannotUseRestrictedPort = 103, 151 WebKitErrorCannotFindPlugIn = 200, 152 WebKitErrorCannotLoadPlugIn = 201, 153 WebKitErrorJavaUnavailable = 202, 154 WebKitErrorPluginWillHandleLoad = 203 155 }; 156 157 enum ContentDispositionType { 158 ContentDispositionNone, 159 ContentDispositionInline, 160 ContentDispositionAttachment, 161 ContentDispositionOther 162 }; 163 164 // Below function was removed after https://bugs.webkit.org/show_bug.cgi?id=163095 165 // from HTTPParser.h. 166 ContentDispositionType contentDispositionType(const String& contentDisposition) 167 { 168 if (contentDisposition.isEmpty()) 169 return ContentDispositionNone; 170 171 Vector<String> parameters; 172 contentDisposition.split(';', parameters); 173 174 String dispositionType = parameters[0]; 175 dispositionType.stripWhiteSpace(); 176 177 if (equalLettersIgnoringASCIICase(dispositionType, "inline")) 178 return ContentDispositionInline; 179 180 // Some broken sites just send bogus headers like 181 // 182 // Content-Disposition: ; filename="file" 183 // Content-Disposition: filename="file" 184 // Content-Disposition: name="file" 185 // 186 // without a disposition token... screen those out. 187 if (!isValidHTTPToken(dispositionType)) 188 return ContentDispositionNone; 189 190 // We have a content-disposition of "attachment" or unknown. 191 // RFC 2183, section 2.8 says that an unknown disposition 192 // value should be treated as "attachment" 193 return ContentDispositionAttachment; 194 } 195 } // namespace 196 197 FrameLoaderClientJava::FrameLoaderClientJava(const JLObject &webPage) 198 : m_page(nullptr) 199 , m_frame(nullptr) 200 , m_isPageRedirected(false) 201 , m_hasRepresentation(false) 202 , m_webPage(webPage) 203 { 204 } 205 206 void FrameLoaderClientJava::dispatchDidNavigateWithinPage() 207 { 208 postLoadEvent(frame(), 209 com_sun_webkit_LoadListenerClient_PAGE_REPLACED, 210 frame()->document()->url(), 211 frame()->loader().documentLoader()->responseMIMEType(), 212 1.0 /* progress */); 213 } 214 215 void FrameLoaderClientJava::frameLoaderDestroyed() 216 { 217 using namespace FrameLoaderClientJavaInternal; 218 WC_GETJAVAENV_CHKRET(env); 219 initRefs(env); 220 221 ASSERT(m_webPage); 222 ASSERT(m_frame); 223 env->CallVoidMethod(m_webPage, frameDestroyedMID, ptr_to_jlong(m_frame)); 224 CheckAndClearException(env); 225 226 m_page = 0; 227 m_frame = 0; 228 229 delete this; 230 } 231 232 Page* FrameLoaderClientJava::page() 233 { 234 if (!m_page) { 235 m_page = WebPage::pageFromJObject(m_webPage); 236 ASSERT(m_page); 237 } 238 return m_page; 239 } 240 241 Frame* FrameLoaderClientJava::frame() 242 { 243 return m_frame; 244 } 245 246 void FrameLoaderClientJava::setFrame(Frame* frame) 247 { 248 ASSERT(frame); 249 m_frame = frame; 250 } 251 252 void FrameLoaderClientJava::setRequestURL(Frame* f, int identifier, String url) 253 { 254 using namespace FrameLoaderClientJavaInternal; 255 JNIEnv* env = WebCore_GetJavaEnv(); 256 initRefs(env); 257 258 JLString urlJavaString(url.toJavaString(env)); 259 env->CallVoidMethod(m_webPage, setRequestURLMID, ptr_to_jlong(f), identifier, (jstring)urlJavaString); 260 CheckAndClearException(env); 261 } 262 263 void FrameLoaderClientJava::removeRequestURL(Frame* f, int identifier) 264 { 265 using namespace FrameLoaderClientJavaInternal; 266 JNIEnv* env = WebCore_GetJavaEnv(); 267 initRefs(env); 268 269 env->CallVoidMethod(m_webPage, removeRequestURLMID, ptr_to_jlong(f), identifier); 270 CheckAndClearException(env); 271 } 272 273 void FrameLoaderClientJava::postLoadEvent(Frame* f, int state, 274 String url, String contentType, 275 double progress, int errorCode) 276 { 277 using namespace FrameLoaderClientJavaInternal; 278 JNIEnv* env = WebCore_GetJavaEnv(); 279 initRefs(env); 280 281 JLString urlJavaString(url.toJavaString(env)); 282 JLString contentTypeJavaString(contentType.toJavaString(env)); 283 284 // First, notify SharedBufferManager, so users can get the full source 285 // in CONTENT_RECEIVED handler 286 if (state == com_sun_webkit_LoadListenerClient_PAGE_STARTED || 287 state == com_sun_webkit_LoadListenerClient_PROGRESS_CHANGED || 288 state == com_sun_webkit_LoadListenerClient_CONTENT_RECEIVED) 289 { 290 DocumentLoader* dl = f->loader().activeDocumentLoader(); 291 if (dl && dl->mainResourceData()) { 292 dl->mainResourceData()->size(); // TODO-java: recheck 293 } 294 } 295 296 // Second, send a load event 297 env->CallVoidMethod(m_webPage, fireLoadEventMID, 298 ptr_to_jlong(f), state, (jstring)urlJavaString, 299 (jstring)contentTypeJavaString, progress, errorCode); 300 CheckAndClearException(env); 301 } 302 303 void FrameLoaderClientJava::postResourceLoadEvent(Frame* f, int state, 304 int id, String contentType, 305 double progress, int errorCode) 306 { 307 using namespace FrameLoaderClientJavaInternal; 308 JNIEnv* env = WebCore_GetJavaEnv(); 309 initRefs(env); 310 311 JLString contentTypeJavaString(contentType.toJavaString(env)); 312 // notification for resource event listeners 313 env->CallVoidMethod(m_webPage, fireResourceLoadEventMID, 314 ptr_to_jlong(f), state, id, 315 (jstring)contentTypeJavaString, progress, errorCode); 316 CheckAndClearException(env); 317 } 318 319 String FrameLoaderClientJava::userAgent(const URL&) 320 { 321 return page()->settings().userAgent(); 322 } 323 324 void FrameLoaderClientJava::savePlatformDataToCachedFrame(CachedFrame*) 325 { 326 notImplemented(); 327 } 328 329 void FrameLoaderClientJava::transitionToCommittedFromCachedFrame(CachedFrame*) 330 { 331 notImplemented(); 332 } 333 334 void FrameLoaderClientJava::transitionToCommittedForNewPage() 335 { 336 FloatRect pageRect = frame()->page()->chrome().pageRect(); 337 Color bkColor(Color::white); 338 bool isTransparent = false; 339 FrameView* fv = frame()->view(); 340 if (fv) { 341 bkColor = fv->baseBackgroundColor(); 342 isTransparent = fv->isTransparent(); 343 } 344 frame()->createView(IntRect(pageRect).size(), bkColor, isTransparent, /* fixedLayoutSize */ { }, /* fixedVisibleContentRect */ { }); 345 } 346 347 WTF::Ref<WebCore::DocumentLoader> FrameLoaderClientJava::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData) 348 { 349 return DocumentLoader::create(request, substituteData); 350 } 351 352 void FrameLoaderClientJava::dispatchWillSubmitForm(FormState&, WTF::Function<void(void)>&& policyFunction) 353 { 354 // FIXME: This is surely too simple 355 ASSERT(frame() && policyFunction); 356 if (!frame() || !policyFunction) { 357 return; 358 } 359 policyFunction(); 360 } 361 362 void FrameLoaderClientJava::committedLoad(DocumentLoader* loader, const char* data, int length) 363 { 364 //uta: for m_pluginWidget we need to do something different 365 loader->commitData(data, length); 366 } 367 368 void FrameLoaderClientJava::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest&, FramePolicyFunction&& policyFunction) 369 { 370 using namespace FrameLoaderClientJavaInternal; 371 PolicyAction action; 372 373 int statusCode = response.httpStatusCode(); 374 if (statusCode == 204 || statusCode == 205) { 375 // The server does not want us to replace the page contents. 376 action = PolicyAction::Ignore; 377 } else if (contentDispositionType(response.httpHeaderField(HTTPHeaderName::ContentDisposition)) == ContentDispositionAttachment) { 378 // The server wants us to download instead of replacing the page contents. 379 // Downloading is handled by the embedder, but we still get the initial 380 // response so that we can ignore it and clean up properly. 381 action = PolicyAction::Ignore; 382 } else if (!canShowMIMEType(response.mimeType())) { 383 // Make sure that we can actually handle this type internally. 384 action = PolicyAction::Ignore; 385 } else { 386 // OK, we will render this page. 387 action = PolicyAction::Use; 388 } 389 390 // NOTE: PolicyChangeError will be generated when action is not PolicyUse. 391 policyFunction(action); 392 } 393 394 void FrameLoaderClientJava::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response) 395 { 396 m_response = response; 397 398 if (identifier == m_mainResourceRequestID) { 399 double progress = page()->progress().estimatedProgress(); 400 postLoadEvent(frame(), 401 com_sun_webkit_LoadListenerClient_CONTENTTYPE_RECEIVED, 402 response.url().string(), 403 response.mimeType(), 404 progress); 405 } 406 } 407 408 void FrameLoaderClientJava::dispatchDecidePolicyForNewWindowAction(const NavigationAction&, 409 const ResourceRequest& req, 410 FormState*, 411 const String&, 412 FramePolicyFunction&& policyFunction) 413 { 414 using namespace FrameLoaderClientJavaInternal; 415 JNIEnv* env = WebCore_GetJavaEnv(); 416 initRefs(env); 417 418 ASSERT(frame() && policyFunction); 419 if (!frame() || !policyFunction) { 420 return; 421 } 422 423 JLString urlString(req.url().string().toJavaString(env)); 424 bool permit = jbool_to_bool(env->CallBooleanMethod(m_webPage, permitNewWindowActionMID, 425 ptr_to_jlong(frame()), (jstring)urlString)); 426 CheckAndClearException(env); 427 428 // FIXME: I think Qt version marshals this to another thread so when we 429 // have multi-threaded download, we might need to do the same 430 policyFunction(permit ? PolicyAction::Use : PolicyAction::Ignore); 431 } 432 433 void FrameLoaderClientJava::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, 434 const ResourceRequest& req, 435 bool /*didReceiveRedirectResponse*/, 436 FormState*, 437 FramePolicyFunction&& policyFunction) 438 { 439 using namespace FrameLoaderClientJavaInternal; 440 JNIEnv* env = WebCore_GetJavaEnv(); 441 initRefs(env); 442 443 ASSERT(frame() && policyFunction); 444 if (!frame() || !policyFunction) { 445 return; 446 } 447 448 bool permit = true; 449 450 JLString urlJavaString(req.url().string().toJavaString(env)); 451 452 // 1. Submitting/resubmitting data. 453 if (action.type() == NavigationType::FormSubmitted || 454 action.type() == NavigationType::FormResubmitted) 455 { 456 JLString httpMethodString(req.httpMethod().toJavaString(env)); 457 permit = env->CallBooleanMethod(m_webPage, permitSubmitDataActionMID, 458 ptr_to_jlong(frame()), (jstring)urlJavaString, 459 (jstring)httpMethodString, 460 bool_to_jbool(action.type() == NavigationType::FormSubmitted)); 461 CheckAndClearException(env); 462 // 2. Redirecting page. 463 } else if (m_isPageRedirected) { 464 permit = env->CallBooleanMethod(m_webPage, permitRedirectActionMID, 465 ptr_to_jlong(frame()), (jstring)urlJavaString); 466 CheckAndClearException(env); 467 m_isPageRedirected = false; 468 // 3. Loading document. 469 } else { 470 permit = env->CallBooleanMethod(m_webPage, permitNavigateActionMID, 471 ptr_to_jlong(frame()), (jstring)urlJavaString); 472 CheckAndClearException(env); 473 } 474 475 policyFunction(permit ? PolicyAction::Use : PolicyAction::Ignore); 476 } 477 478 RefPtr<Widget> FrameLoaderClientJava::createPlugin(const IntSize& intSize, HTMLPlugInElement& element, const URL& url, 479 const Vector<String>& paramNames, const Vector<String>& paramValues, 480 const String& mimeType, bool) 481 { 482 return adoptRef(new PluginWidgetJava( 483 m_webPage, 484 &element, 485 intSize, 486 url.string(), 487 mimeType, 488 paramNames, 489 paramValues)); 490 } 491 492 RefPtr<Frame> FrameLoaderClientJava::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement& ownerElement, 493 const String& referrer, bool, int, int) 494 { 495 using namespace FrameLoaderClientJavaInternal; 496 JNIEnv* env = WebCore_GetJavaEnv(); 497 initRefs(env); 498 499 FrameLoaderClientJava* frameLoaderClient = new FrameLoaderClientJava(m_webPage); 500 RefPtr<Frame> childFrame(Frame::create(page(), &ownerElement, frameLoaderClient)); 501 frameLoaderClient->setFrame(childFrame.get()); 502 503 childFrame->tree().setName(name); 504 m_frame->tree().appendChild(*childFrame); 505 506 childFrame->init(); 507 508 // gtk: The creation of the frame may have run arbitrary JS that removed it from the page already. 509 if (!childFrame->page()) { 510 return 0; 511 } 512 513 m_frame->loader().loadURLIntoChildFrame(url, referrer, childFrame.get()); 514 515 // gtk: The frame's onload handler may have removed it from the document. 516 if (!childFrame->tree().parent()) { 517 return 0; 518 } 519 520 env->CallVoidMethod(m_webPage, frameCreatedMID, ptr_to_jlong(childFrame.get())); 521 CheckAndClearException(env); 522 523 return childFrame; 524 } 525 526 void FrameLoaderClientJava::redirectDataToPlugin(Widget&) 527 { 528 /* 529 ASSERT(!m_pluginWidget); 530 m_pluginWidget = static_cast<PluginWidgetJava*>(pluginWidget); 531 */ 532 notImplemented(); 533 } 534 535 RefPtr<Widget> FrameLoaderClientJava::createJavaAppletWidget(const IntSize&, HTMLAppletElement&, const URL&, 536 const Vector<String>&, const Vector<String>&) 537 { 538 notImplemented(); 539 return nullptr; 540 } 541 542 ObjectContentType FrameLoaderClientJava::objectContentType(const URL& url, const String& mimeType) 543 { 544 //copied from FrameLoaderClientEfl.cpp 545 546 // FIXME: once plugin support is enabled, this method needs to correctly handle the 'shouldPreferPlugInsForImages' flag. See 547 // WebCore::FrameLoader::defaultObjectContentType() for an example. 548 549 if (url.isEmpty() && mimeType.isEmpty()) 550 return ObjectContentType::None; 551 552 // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure 553 String type = mimeType; 554 if (type.isEmpty()) 555 type = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1)); 556 557 if (type.isEmpty()) 558 return ObjectContentType::Frame; 559 560 if (MIMETypeRegistry::isSupportedImageMIMEType(type)) 561 return ObjectContentType::Image; 562 563 #if 0 // PluginDatabase is disabled until we have Plugin system done. 564 if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) 565 return ObjectContentNetscapePlugin; 566 #endif 567 568 if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) 569 return ObjectContentType::Frame; 570 571 if (url.protocol() == "about") 572 return ObjectContentType::Frame; 573 574 return ObjectContentType::None; 575 } 576 577 String FrameLoaderClientJava::overrideMediaType() const 578 { 579 notImplemented(); 580 return String(); 581 } 582 583 void FrameLoaderClientJava::setMainFrameDocumentReady(bool) 584 { 585 // this is only interesting once we provide an external API for the DOM 586 } 587 588 bool FrameLoaderClientJava::hasWebView() const 589 { 590 notImplemented(); 591 return true; 592 } 593 594 void FrameLoaderClientJava::assignIdentifierToInitialRequest(unsigned long, DocumentLoader*, const ResourceRequest&) 595 { 596 notImplemented(); 597 } 598 599 void FrameLoaderClientJava::willReplaceMultipartContent() 600 { 601 notImplemented(); // TODO-java: recheck 602 } 603 604 void FrameLoaderClientJava::didReplaceMultipartContent() 605 { 606 notImplemented(); // TODO-java: recheck 607 } 608 609 void FrameLoaderClientJava::updateCachedDocumentLoader(DocumentLoader&) 610 { 611 notImplemented(); // TODO-java: recheck 612 } 613 614 void FrameLoaderClientJava::dispatchDidStartProvisionalLoad() 615 { 616 m_mainResourceRequestID = 0; 617 } 618 619 void FrameLoaderClientJava::dispatchWillSendRequest(DocumentLoader* l, unsigned long identifier, ResourceRequest& req, const ResourceResponse& res) 620 { 621 using namespace FrameLoaderClientJavaInternal; 622 JNIEnv* env = WebCore_GetJavaEnv(); 623 initRefs(env); 624 625 Frame* f = l->frame(); 626 if (!f) { 627 f = frame(); 628 } 629 630 double progress = 0.0; 631 progress = page()->progress().estimatedProgress(); 632 633 if (m_mainResourceRequestID == 0) { 634 m_mainResourceRequestID = identifier; 635 postLoadEvent(f, 636 com_sun_webkit_LoadListenerClient_PAGE_STARTED, 637 req.url().string(), 638 res.mimeType(), 639 progress); 640 } else if (m_mainResourceRequestID == identifier) { // serever-side redirection 641 m_isPageRedirected = true; 642 postLoadEvent(f, 643 com_sun_webkit_LoadListenerClient_PAGE_REDIRECTED, 644 req.url().string(), 645 res.mimeType(), 646 progress); 647 } else { 648 // Check resource policy. 649 JLString urlJavaString(req.url().string().toJavaString(env)); 650 bool permit = jbool_to_bool(env->CallBooleanMethod(m_webPage, permitAcceptResourceActionMID, 651 ptr_to_jlong(f), (jstring)urlJavaString)); 652 CheckAndClearException(env); 653 if (!permit) { 654 /* 655 req.setURL(NULL); // will cancel loading 656 */ 657 req.setURL(URL()); 658 } else { 659 setRequestURL(f, identifier, req.url().string()); 660 postResourceLoadEvent(f, 661 com_sun_webkit_LoadListenerClient_RESOURCE_STARTED, 662 identifier, 663 res.mimeType(), 664 0.0 /* progress */); 665 } 666 } 667 } 668 669 void FrameLoaderClientJava::dispatchDidFailLoading(DocumentLoader* dl, unsigned long identifier, const ResourceError& error) 670 { 671 Frame* f = dl->frame(); 672 if (!f) { 673 f = frame(); 674 } 675 postResourceLoadEvent(f, 676 com_sun_webkit_LoadListenerClient_RESOURCE_FAILED, 677 identifier, 678 dl->responseMIMEType(), 679 0.0 /* progress */, 680 error.errorCode()); 681 removeRequestURL(f, identifier); 682 } 683 684 void FrameLoaderClientJava::dispatchDidFailProvisionalLoad(const ResourceError& error) 685 { 686 ASSERT(frame()); 687 if (!frame()) { 688 return; 689 } 690 DocumentLoader* dl = frame()->loader().activeDocumentLoader(); 691 if (!dl) { 692 return; 693 } 694 695 double progress = page()->progress().estimatedProgress(); 696 int state = error.isCancellation() 697 ? com_sun_webkit_LoadListenerClient_LOAD_STOPPED 698 : com_sun_webkit_LoadListenerClient_LOAD_FAILED; 699 postLoadEvent(frame(), state, 700 dl->url().string(), 701 dl->responseMIMEType(), 702 progress, 703 error.errorCode()); 704 } 705 706 void FrameLoaderClientJava::dispatchDidFailLoad(const ResourceError& error) 707 { 708 dispatchDidFailProvisionalLoad(error); 709 } 710 711 // client-side redirection 712 void FrameLoaderClientJava::dispatchWillPerformClientRedirect(const URL&, double, WallTime) 713 { 714 } 715 716 void FrameLoaderClientJava::dispatchDidReceiveTitle(const StringWithDirection&) 717 { 718 double progress = page()->progress().estimatedProgress(); 719 postLoadEvent(frame(), 720 com_sun_webkit_LoadListenerClient_TITLE_RECEIVED, 721 frame()->document()->url(), 722 frame()->loader().documentLoader()->responseMIMEType(), 723 progress); 724 } 725 726 void FrameLoaderClientJava::dispatchDidReceiveIcon() 727 { 728 // not called without IconDatabase support, so sending the notification 729 // from dispatchDidLoadMainResource() 730 /* 731 Frame* f = page()->mainFrame(); 732 if (!f->loader() || !f->document()) { 733 return; 734 } 735 736 double progress = page()->progress()->estimatedProgress(); 737 postLoadEvent(com_sun_webkit_LoadListenerClient_ICON_RECEIVED, 738 0, // request id 739 f->document()->url(), 740 f->loader()->documentLoader()->responseMIMEType(), 741 progress); 742 */ 743 } 744 745 void FrameLoaderClientJava::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long, int) 746 { 747 notImplemented(); 748 } 749 750 void FrameLoaderClientJava::dispatchDidFinishDocumentLoad() 751 { 752 if (!frame()->isMainFrame()) { 753 // send the notification for the main frame only 754 return; 755 } 756 757 double progress = page()->progress().estimatedProgress(); 758 postLoadEvent(frame(), 759 com_sun_webkit_LoadListenerClient_DOCUMENT_AVAILABLE, 760 frame()->document()->url(), 761 frame()->loader().documentLoader()->responseMIMEType(), 762 progress); 763 } 764 765 void FrameLoaderClientJava::dispatchDidLoadMainResource(DocumentLoader* l) 766 { 767 double progress = page()->progress().estimatedProgress(); 768 // send ICON_RECEIVED here instead of dispatchDidReceiveIcon(), 769 // see comments in the method for details 770 postLoadEvent(frame(), 771 com_sun_webkit_LoadListenerClient_ICON_RECEIVED, 772 frame()->document()->url(), 773 l->responseMIMEType(), 774 progress); 775 postLoadEvent(frame(), 776 com_sun_webkit_LoadListenerClient_CONTENT_RECEIVED, 777 l->responseURL().string(), 778 l->responseMIMEType(), 779 progress); 780 } 781 782 void FrameLoaderClientJava::dispatchDidFinishLoading(DocumentLoader* l, unsigned long identifier) 783 { 784 postResourceLoadEvent(frame(), 785 com_sun_webkit_LoadListenerClient_RESOURCE_FINISHED, 786 identifier, 787 l->responseMIMEType(), 788 1.0 /* progress */); 789 removeRequestURL(frame(), identifier); 790 } 791 792 void FrameLoaderClientJava::dispatchDidFinishLoad() 793 { 794 double progress = page()->progress().estimatedProgress(); 795 postLoadEvent(frame(), 796 com_sun_webkit_LoadListenerClient_PAGE_FINISHED, 797 frame()->document()->url(), 798 frame()->loader().documentLoader()->responseMIMEType(), 799 progress); 800 } 801 802 void FrameLoaderClientJava::finishedLoading(DocumentLoader* dl) 803 { 804 // This is necessary to create an empty document. See bug 634004. 805 // However, we only want to do this if makeRepresentation has been called, to 806 // match the behavior on the Mac. 807 if (m_hasRepresentation) 808 dl->writer().setEncoding("", false); 809 } 810 811 void FrameLoaderClientJava::frameLoadCompleted() 812 { 813 notImplemented(); 814 } 815 816 void FrameLoaderClientJava::saveViewStateToItem(HistoryItem&) 817 { 818 notImplemented(); 819 } 820 821 void FrameLoaderClientJava::restoreViewState() 822 { 823 notImplemented(); 824 } 825 826 Frame* FrameLoaderClientJava::dispatchCreatePage(const NavigationAction& action) 827 { 828 struct WindowFeatures features {}; 829 Page* newPage = frame()->page()->chrome().createWindow( 830 *frame(), 831 FrameLoadRequest(*frame()->document(), 832 frame()->document()->securityOrigin(), 833 action.resourceRequest(), 834 {}, 835 LockHistory::No, 836 LockBackForwardList::No, 837 ShouldSendReferrer::MaybeSendReferrer, 838 AllowNavigationToInvalidURL::Yes, 839 NewFrameOpenerPolicy::Allow, // TODO-java: check params 840 action.shouldOpenExternalURLsPolicy(), 841 action.initiatedByMainFrame()), 842 features, 843 action); 844 845 // createWindow can return null (e.g., popup blocker denies the window). 846 if (!newPage) 847 return 0; 848 849 return &newPage->mainFrame(); 850 } 851 852 bool FrameLoaderClientJava::shouldGoToHistoryItem(HistoryItem* item) const 853 { 854 // FIXME: This is a very simple implementation. More sophisticated 855 // implementation would delegate the decision to a PolicyDelegate. 856 // See mac implementation for example. 857 return item != 0; 858 } 859 860 void FrameLoaderClientJava::didDisplayInsecureContent() 861 { 862 notImplemented(); 863 } 864 865 void FrameLoaderClientJava::didRunInsecureContent(SecurityOrigin&, const URL&) 866 { 867 notImplemented(); 868 } 869 870 void FrameLoaderClientJava::didDetectXSS(const URL&, bool) 871 { 872 notImplemented(); 873 } 874 875 void FrameLoaderClientJava::makeRepresentation(DocumentLoader*) 876 { 877 m_hasRepresentation = true; 878 } 879 880 void FrameLoaderClientJava::forceLayoutForNonHTML() { notImplemented(); } 881 void FrameLoaderClientJava::setCopiesOnScroll() { notImplemented(); } 882 void FrameLoaderClientJava::detachedFromParent2() { notImplemented(); } 883 void FrameLoaderClientJava::detachedFromParent3() { notImplemented(); } 884 885 void FrameLoaderClientJava::dispatchDidPushStateWithinPage() 886 { 887 dispatchDidNavigateWithinPage(); 888 } 889 890 void FrameLoaderClientJava::dispatchDidReplaceStateWithinPage() 891 { 892 dispatchDidNavigateWithinPage(); 893 } 894 895 void FrameLoaderClientJava::dispatchDidDispatchOnloadEvents() {notImplemented(); } 896 void FrameLoaderClientJava::dispatchDidPopStateWithinPage() { notImplemented(); } 897 void FrameLoaderClientJava::dispatchDidReceiveServerRedirectForProvisionalLoad() { notImplemented(); } 898 void FrameLoaderClientJava::dispatchDidCancelClientRedirect() { notImplemented(); } 899 void FrameLoaderClientJava::dispatchDidChangeLocationWithinPage() { notImplemented(); } 900 void FrameLoaderClientJava::dispatchWillClose() { notImplemented(); } 901 void FrameLoaderClientJava::dispatchDidCommitLoad(std::optional<HasInsecureContent>) 902 { 903 // TODO: Look at GTK version 904 notImplemented(); 905 } 906 907 void FrameLoaderClientJava::dispatchShow() { notImplemented(); } 908 void FrameLoaderClientJava::cancelPolicyCheck() { notImplemented(); } 909 void FrameLoaderClientJava::revertToProvisionalState(DocumentLoader*) { notImplemented(); } 910 void FrameLoaderClientJava::willChangeTitle(DocumentLoader*) { notImplemented(); } 911 void FrameLoaderClientJava::didChangeTitle(DocumentLoader *l) { setTitle(l->title(), l->url()); } 912 913 bool FrameLoaderClientJava::canHandleRequest(const ResourceRequest& req) const 914 { 915 using namespace FrameLoaderClientJavaInternal; 916 JNIEnv* env = WebCore_GetJavaEnv(); 917 initRefs(env); 918 919 JLString urlJavaString(req.url().string().toJavaString(env)); 920 jboolean ret = env->CallStaticBooleanMethod(networkContextClass, canHandleURLMID, (jstring)urlJavaString); 921 CheckAndClearException(env); 922 923 return jbool_to_bool(ret); 924 } 925 926 bool FrameLoaderClientJava::canShowMIMEType(const String& mimeType) const 927 { 928 //copy from QT implementation 929 String type = mimeType.convertToLowercaseWithoutLocale(); 930 if (MIMETypeRegistry::isSupportedImageMIMEType(type)) 931 return true; 932 933 if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) 934 return true; 935 936 if (MIMETypeRegistry::isSupportedMediaMIMEType(type)) 937 return true; 938 939 #if 0 // PluginDatabase is disabled until we have Plugin system done. 940 if (m_frame && m_frame->settings().arePluginsEnabled() 941 && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type)) 942 return true; 943 #endif 944 945 return false; 946 } 947 948 bool FrameLoaderClientJava::canShowMIMETypeAsHTML(const String&) const 949 { 950 notImplemented(); 951 return false; 952 } 953 954 955 bool FrameLoaderClientJava::representationExistsForURLScheme(const String&) const 956 { 957 notImplemented(); 958 return false; 959 } 960 961 String FrameLoaderClientJava::generatedMIMETypeForURLScheme(const String&) const 962 { 963 notImplemented(); 964 return String(); 965 } 966 967 void FrameLoaderClientJava::provisionalLoadStarted() 968 { 969 notImplemented(); 970 } 971 972 void FrameLoaderClientJava::didFinishLoad() 973 { 974 notImplemented(); 975 } 976 977 void FrameLoaderClientJava::prepareForDataSourceReplacement() 978 { 979 notImplemented(); 980 } 981 982 void FrameLoaderClientJava::setTitle(const StringWithDirection&, const URL&) 983 { 984 notImplemented(); 985 } 986 987 bool FrameLoaderClientJava::dispatchDidLoadResourceFromMemoryCache( 988 DocumentLoader*, 989 const ResourceRequest&, 990 const ResourceResponse&, 991 int) 992 { 993 notImplemented(); 994 return false; 995 } 996 997 ResourceError FrameLoaderClientJava::cancelledError(const ResourceRequest& request) 998 { 999 return ResourceError("Error", -999, request.url(), "Request cancelled"); 1000 } 1001 1002 ResourceError FrameLoaderClientJava::blockedError(const ResourceRequest& request) 1003 { 1004 using namespace FrameLoaderClientJavaInternal; 1005 return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url(), 1006 "Request blocked"); 1007 } 1008 1009 ResourceError FrameLoaderClientJava::blockedByContentBlockerError(const ResourceRequest& request) 1010 { 1011 using namespace FrameLoaderClientJavaInternal; 1012 RELEASE_ASSERT_NOT_REACHED(); // Content Blockers are not enabled for WK1. 1013 return ResourceError("Error", WebKitErrorCannotShowURL, request.url(), 1014 "Cannot show URL"); 1015 } 1016 1017 ResourceError FrameLoaderClientJava::cannotShowURLError(const ResourceRequest& request) 1018 { 1019 using namespace FrameLoaderClientJavaInternal; 1020 return ResourceError("Error", WebKitErrorCannotShowURL, request.url(), 1021 "Cannot show URL"); 1022 } 1023 1024 ResourceError FrameLoaderClientJava::interruptedForPolicyChangeError(const ResourceRequest& request) 1025 { 1026 using namespace FrameLoaderClientJavaInternal; 1027 return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, 1028 request.url(), "Frame load interrupted by policy change"); 1029 } 1030 1031 ResourceError FrameLoaderClientJava::cannotShowMIMETypeError(const ResourceResponse& response) 1032 { 1033 using namespace FrameLoaderClientJavaInternal; 1034 return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url(), 1035 "Cannot show mimetype"); 1036 } 1037 1038 ResourceError FrameLoaderClientJava::fileDoesNotExistError(const ResourceResponse& response) 1039 { 1040 return ResourceError("Error", -998 /* ### */, response.url(), 1041 "File does not exist"); 1042 } 1043 1044 ResourceError FrameLoaderClientJava::pluginWillHandleLoadError(const ResourceResponse& response) 1045 { 1046 using namespace FrameLoaderClientJavaInternal; 1047 return ResourceError("Error", WebKitErrorPluginWillHandleLoad, response.url(), "Loading is handled by the media engine"); 1048 } 1049 1050 bool FrameLoaderClientJava::shouldFallBack(const ResourceError& error) 1051 { 1052 using namespace FrameLoaderClientJavaInternal; 1053 //Font fallback supported by Java Fonts internaly 1054 return !(error.isCancellation() || (error.errorCode() == WebKitErrorFrameLoadInterruptedByPolicyChange)); 1055 } 1056 1057 bool FrameLoaderClientJava::canCachePage() const 1058 { 1059 return true; 1060 } 1061 1062 void FrameLoaderClientJava::didSaveToPageCache() 1063 { 1064 } 1065 1066 void FrameLoaderClientJava::didRestoreFromPageCache() 1067 { 1068 } 1069 1070 void FrameLoaderClientJava::dispatchUnableToImplementPolicy(const ResourceError&) 1071 { 1072 notImplemented(); 1073 } 1074 1075 void FrameLoaderClientJava::dispatchDidBecomeFrameset(bool) 1076 { 1077 notImplemented(); 1078 } 1079 1080 1081 void FrameLoaderClientJava::setMainDocumentError( 1082 DocumentLoader*, 1083 const ResourceError&) 1084 { 1085 // if (m_pluginWidget) { 1086 // m_pluginWidget = 0; 1087 // } 1088 notImplemented(); 1089 } 1090 1091 void FrameLoaderClientJava::startDownload(const ResourceRequest&, const String&) 1092 { 1093 notImplemented(); 1094 } 1095 1096 void FrameLoaderClientJava::updateGlobalHistory() 1097 { 1098 notImplemented(); 1099 } 1100 1101 void FrameLoaderClientJava::updateGlobalHistoryRedirectLinks() 1102 { 1103 notImplemented(); 1104 } 1105 1106 void FrameLoaderClientJava::dispatchDidClearWindowObjectInWorld( 1107 DOMWrapperWorld& world) 1108 { 1109 using namespace FrameLoaderClientJavaInternal; 1110 JNIEnv* env = WebCore_GetJavaEnv(); 1111 initRefs(env); 1112 1113 if (&world != &mainThreadNormalWorld()) { 1114 return; 1115 } 1116 1117 JSGlobalContextRef context = toGlobalRef(frame()->script().globalObject( 1118 mainThreadNormalWorld())->globalExec()); 1119 JSObjectRef windowObject = JSContextGetGlobalObject(context); 1120 1121 env->CallVoidMethod(m_webPage, didClearWindowObjectMID, 1122 ptr_to_jlong(context), ptr_to_jlong(windowObject)); 1123 CheckAndClearException(env); 1124 } 1125 1126 void FrameLoaderClientJava::registerForIconNotification() 1127 { 1128 //notImplemented(); 1129 } 1130 1131 void FrameLoaderClientJava::convertMainResourceLoadToDownload(DocumentLoader*, PAL::SessionID, const ResourceRequest&, const ResourceResponse&) 1132 { 1133 //notImplemented(); 1134 } 1135 1136 Ref<FrameNetworkingContext> FrameLoaderClientJava::createNetworkingContext() 1137 { 1138 return FrameNetworkingContextJava::create(frame()); 1139 } 1140 1141 1142 bool FrameLoaderClientJava::shouldUseCredentialStorage( 1143 DocumentLoader*, 1144 unsigned long) 1145 { 1146 notImplemented(); 1147 return false; 1148 } 1149 1150 void FrameLoaderClientJava::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge) 1151 { 1152 notImplemented(); 1153 // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle 1154 // to continue without credential - this is the best approximation of Mac behavior 1155 challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); 1156 } 1157 1158 void FrameLoaderClientJava::prefetchDNS(const String& hostname) 1159 { 1160 WebCore::prefetchDNS(hostname); 1161 } 1162 1163 std::optional<uint64_t> FrameLoaderClientJava::pageID() const 1164 { 1165 return std::nullopt; 1166 } 1167 1168 std::optional<uint64_t> FrameLoaderClientJava::frameID() const 1169 { 1170 return std::nullopt; 1171 } 1172 1173 PAL::SessionID FrameLoaderClientJava::sessionID() const 1174 { 1175 RELEASE_ASSERT_NOT_REACHED(); 1176 return PAL::SessionID::defaultSessionID(); 1177 } 1178 1179 1180 }