void createWindowForRequest(const FrameLoadRequest& request, Frame* openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer) { if (openerFrame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; if (openerFrame->document() && openerFrame->document()->isSandboxed(SandboxPopups)) return; if (!DOMWindow::allowPopUp(openerFrame)) return; if (policy == NavigationPolicyCurrentTab) policy = NavigationPolicyNewForegroundTab; WindowFeatures features; bool created; Frame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created); if (!newFrame) return; newFrame->page()->setOpenedByDOM(); if (shouldSendReferrer == MaybeSendReferrer) { newFrame->loader().setOpener(openerFrame); newFrame->document()->setReferrerPolicy(openerFrame->document()->referrerPolicy()); } FrameLoadRequest newRequest(0, request.resourceRequest()); newRequest.setFormState(request.formState()); newFrame->loader().load(newRequest); }
NPError PluginView::load(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData) { ASSERT(frameLoadRequest.resourceRequest().httpMethod() == "GET" || frameLoadRequest.resourceRequest().httpMethod() == "POST"); KURL url = frameLoadRequest.resourceRequest().url(); if (url.isEmpty()) return NPERR_INVALID_URL; // Don't allow requests to be made when the document loader is stopping all loaders. if (m_parentFrame->loader()->documentLoader()->isStopping()) return NPERR_GENERIC_ERROR; const String& targetFrameName = frameLoadRequest.frameName(); String jsString = scriptStringIfJavaScriptURL(url); if (!jsString.isNull()) { Settings* settings = m_parentFrame->settings(); // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does. if (!settings || !settings->isJavaScriptEnabled()) return NPERR_GENERIC_ERROR; // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. if (!targetFrameName.isNull() && m_parentFrame->tree()->find(targetFrameName) != m_parentFrame) return NPERR_INVALID_PARAM; } else if (!FrameLoader::canLoad(url, String(), m_parentFrame->document())) { return NPERR_GENERIC_ERROR; } PluginRequest* request = new PluginRequest(frameLoadRequest, sendNotification, notifyData, arePopupsAllowed()); scheduleRequest(request); return NPERR_NO_ERROR; }
void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy) { ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document() && openerFrame.document()->url().isEmpty())); if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups)) return; if (!LocalDOMWindow::allowPopUp(openerFrame)) return; if (policy == NavigationPolicyCurrentTab) policy = NavigationPolicyNewForegroundTab; WindowFeatures features; features.noopener = request.getShouldSetOpener() == NeverSetOpener; bool created; Frame* newFrame = createWindowHelper(openerFrame, openerFrame, openerFrame, request, features, policy, created); if (!newFrame) return; if (request.getShouldSendReferrer() == MaybeSendReferrer) { // TODO(japhet): Does ReferrerPolicy need to be proagated for RemoteFrames? if (newFrame->isLocalFrame()) toLocalFrame(newFrame)->document()->setReferrerPolicy(openerFrame.document()->getReferrerPolicy()); } // TODO(japhet): Form submissions on RemoteFrames don't work yet. FrameLoadRequest newRequest(0, request.resourceRequest()); newRequest.setForm(request.form()); if (newFrame->isLocalFrame()) toLocalFrame(newFrame)->loader().load(newRequest); }
bool PluginView::start() { if (m_isStarted) return false; PluginMainThreadScheduler::scheduler().registerPlugin(m_instance); ASSERT(m_plugin); ASSERT(m_plugin->pluginFuncs()->newp); NPError npErr; { PluginView::setCurrentPluginView(this); JSC::JSLock::DropAllLocks dropAllLocks(false); setCallingPlugin(true); npErr = m_plugin->pluginFuncs()->newp((NPMIMEType)m_mimeType.data(), m_instance, m_mode, m_paramCount, m_paramNames, m_paramValues, NULL); setCallingPlugin(false); LOG_NPERROR(npErr); PluginView::setCurrentPluginView(0); } if (npErr != NPERR_NO_ERROR) return false; m_isStarted = true; if (!m_url.isEmpty() && !m_loadManually) { FrameLoadRequest frameLoadRequest; frameLoadRequest.resourceRequest().setHTTPMethod("GET"); frameLoadRequest.resourceRequest().setURL(m_url); load(frameLoadRequest, false, 0); } return true; }
NPError PluginView::getURL(const char* url, const char* target) { FrameLoadRequest frameLoadRequest; frameLoadRequest.setFrameName(target); frameLoadRequest.resourceRequest().setHTTPMethod("GET"); frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url)); return load(frameLoadRequest, false, 0); }
NPError PluginView::getURLNotify(const char* url, const char* target, void* notifyData) { FrameLoadRequest frameLoadRequest; frameLoadRequest.setFrameName(target); frameLoadRequest.resourceRequest().setHTTPMethod("GET"); frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url)); return load(frameLoadRequest, true, notifyData); }
void fire(LocalFrame* frame) override { OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); ResourceRequest resourceRequest = frame->loader().resourceRequestForReload(FrameLoadTypeReload, KURL(), ClientRedirect); if (resourceRequest.isNull()) return; FrameLoadRequest request = FrameLoadRequest(nullptr, resourceRequest); request.setClientRedirect(ClientRedirect); frame->loader().load(request, FrameLoadTypeReload); }
void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest) { if (!m_target.isEmpty()) frameRequest.setFrameName(m_target); if (!m_referrer.isEmpty()) frameRequest.resourceRequest().setHTTPReferrer(m_referrer); if (m_method == FormSubmission::PostMethod) { frameRequest.resourceRequest().setHTTPMethod("POST"); frameRequest.resourceRequest().setHTTPBody(m_formData); // construct some user headers if necessary if (m_contentType.isNull() || m_contentType == "application/x-www-form-urlencoded") { frameRequest.resourceRequest().setHTTPContentType(m_contentType); } else { // contentType must be "multipart/form-data" frameRequest.resourceRequest().setHTTPContentType(m_contentType + "; boundary=" + m_boundary); } } frameRequest.resourceRequest().setURL(requestURL()); FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), m_origin); }
void LocalFrame::reload(FrameLoadType loadType, ClientRedirectPolicy clientRedirectPolicy) { DCHECK(isReloadLoadType(loadType)); if (clientRedirectPolicy == ClientRedirectPolicy::NotClientRedirect) { if (!m_loader.currentItem()) return; FrameLoadRequest request = FrameLoadRequest(nullptr, m_loader.resourceRequestForReload( loadType, KURL(), clientRedirectPolicy)); request.setClientRedirect(clientRedirectPolicy); m_loader.load(request, loadType); } else { DCHECK_EQ(FrameLoadTypeReload, loadType); m_navigationScheduler->scheduleReload(); } }
ScheduledFormSubmission(const FrameLoadRequest& frameRequest, bool lockHistory, bool lockBackForwardList, PassRefPtr<Event> event, PassRefPtr<FormState> formState, bool duringLoad) : ScheduledNavigation(0, lockHistory, lockBackForwardList, duringLoad) , m_frameRequest(frameRequest) , m_event(event) , m_formState(formState) , m_wasProcessingUserGesture(UserGestureIndicator::processingUserGesture()) { ASSERT(!frameRequest.isEmpty()); ASSERT(m_formState); }
NPError PluginView::handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders) { if (!url || !len || !buf) return NPERR_INVALID_PARAM; FrameLoadRequest frameLoadRequest; HTTPHeaderMap headerFields; Vector<char> buffer; if (file) { NPError readResult = handlePostReadFile(buffer, len, buf); if(readResult != NPERR_NO_ERROR) return readResult; } else { buffer.resize(len); memcpy(buffer.data(), buf, len); } const char* postData = buffer.data(); int postDataLength = buffer.size(); if (allowHeaders) { if (startsWithBlankLine(buffer)) { postData++; postDataLength--; } else { int location = locationAfterFirstBlankLine(buffer); if (location != -1) { // If the blank line is somewhere in the middle of the buffer, everything before is the header headerFields = parseRFC822HeaderFields(buffer, location); unsigned dataLength = buffer.size() - location; // Sometimes plugins like to set Content-Length themselves when they post, // but WebFoundation does not like that. So we will remove the header // and instead truncate the data to the requested length. String contentLength = headerFields.get("Content-Length"); if (!contentLength.isNull()) dataLength = min(contentLength.toInt(), (int)dataLength); headerFields.remove("Content-Length"); postData += location; postDataLength = dataLength; } } } frameLoadRequest.resourceRequest().setHTTPMethod("POST"); frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url)); frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(postData, postDataLength)); frameLoadRequest.setFrameName(target); return load(frameLoadRequest, sendNotification, notifyData); }
void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest) { if (!m_target.isEmpty()) frameRequest.setFrameName(m_target); if (!m_referrer.isEmpty()) frameRequest.resourceRequest().setHTTPReferrer(m_referrer); if (m_method == FormSubmission::PostMethod) { frameRequest.resourceRequest().setHTTPMethod("POST"); frameRequest.resourceRequest().setHTTPBody(m_formData.copyRef()); // construct some user headers if necessary if (m_boundary.isEmpty()) frameRequest.resourceRequest().setHTTPContentType(m_contentType); else frameRequest.resourceRequest().setHTTPContentType(m_contentType + "; boundary=" + m_boundary); } frameRequest.resourceRequest().setURL(requestURL()); FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), m_origin); FrameLoader::addHTTPUpgradeInsecureRequestsIfNeeded(frameRequest.resourceRequest()); }
void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<char>& httpBody, bool allowPopups) { FrameLoadRequest frameLoadRequest; frameLoadRequest.setFrameName(target); frameLoadRequest.resourceRequest().setHTTPMethod(method); frameLoadRequest.resourceRequest().setURL(m_pluginElement->document()->completeURL(urlString)); frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size())); m_pendingURLRequests.append(URLRequest::create(requestID, frameLoadRequest, allowPopups)); m_pendingURLRequestsTimer.startOneShot(0); }
ScheduledRedirection(const FrameLoadRequest& frameRequest, bool lockHistory, bool lockBackForwardList, PassRefPtr<Event> event, PassRefPtr<FormState> formState, bool duringLoad) : type(formSubmission) , delay(0) , frameRequest(frameRequest) , event(event) , formState(formState) , historySteps(0) , lockHistory(lockHistory) , lockBackForwardList(lockBackForwardList) , wasUserGesture(false) , wasRefresh(false) , wasDuringLoad(duringLoad) , toldClient(false) { ASSERT(!frameRequest.isEmpty()); ASSERT(this->formState); }
void RedirectScheduler::scheduleFormSubmission(const FrameLoadRequest& frameRequest, bool lockHistory, PassRefPtr<Event> event, PassRefPtr<FormState> formState) { ASSERT(m_frame->page()); ASSERT(!frameRequest.isEmpty()); // FIXME: Do we need special handling for form submissions where the URL is the same // as the current one except for the fragment part? See scheduleLocationChange above. // Handle a location change of a page with no document as a special case. // This may happen when a frame changes the location of another frame. bool duringLoad = !m_frame->loader()->committedFirstRealDocumentLoad(); // If this is a child frame and the form submission was triggered by a script, lock the back/forward list // to match IE and Opera. // See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this. bool lockBackForwardList = mustLockBackForwardList(m_frame) || (formState->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent()); schedule(new ScheduledFormSubmission(frameRequest, lockHistory, lockBackForwardList, event, formState, duringLoad)); }
void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest) { if (!m_target.isEmpty()) frameRequest.setFrameName(m_target); if (m_method == FormSubmission::PostMethod) { frameRequest.resourceRequest().setHTTPMethod("POST"); frameRequest.resourceRequest().setHTTPBody(m_formData); // construct some user headers if necessary if (m_boundary.isEmpty()) frameRequest.resourceRequest().setHTTPContentType(m_contentType); else frameRequest.resourceRequest().setHTTPContentType(m_contentType + "; boundary=" + m_boundary); } frameRequest.resourceRequest().setURL(requestURL()); }
void RemoteFrame::navigate(const FrameLoadRequest& passedRequest) { UserGestureStatus gesture = UserGestureIndicator::processingUserGesture() ? UserGestureStatus::Active : UserGestureStatus::None; navigate(*passedRequest.originDocument(), passedRequest.resourceRequest().url(), passedRequest.replacesCurrentItem(), gesture); }
static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, bool& created) { ASSERT(!features.dialog || request.frameName().isEmpty()); if (!request.frameName().isEmpty() && request.frameName() != "_blank") { if (Frame* frame = lookupFrame->loader()->findFrameForNavigation(request.frameName(), openerFrame->document())) { if (request.frameName() != "_self") { if (Page* page = frame->page()) page->chrome().focus(); } created = false; return frame; } } // Sandboxed frames cannot open new auxiliary browsing contexts. if (openerFrame->document()->isSandboxed(SandboxPopups)) { // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists. openerFrame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set."); return 0; } // FIXME: Setting the referrer should be the caller's responsibility. FrameLoadRequest requestWithReferrer = request; String referrer = SecurityPolicy::generateReferrerHeader(openerFrame->document()->referrerPolicy(), request.resourceRequest().url(), openerFrame->loader()->outgoingReferrer()); if (!referrer.isEmpty()) requestWithReferrer.resourceRequest().setHTTPReferrer(referrer); FrameLoader::addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), openerFrame->loader()->outgoingOrigin()); if (openerFrame->settings() && !openerFrame->settings()->supportsMultipleWindows()) { created = false; return openerFrame->tree()->top(); } Page* oldPage = openerFrame->page(); if (!oldPage) return 0; NavigationAction action(requestWithReferrer.resourceRequest()); Page* page = oldPage->chrome().client()->createWindow(openerFrame, requestWithReferrer, features, action); if (!page) return 0; Frame* frame = page->mainFrame(); frame->loader()->forceSandboxFlags(openerFrame->document()->sandboxFlags()); if (request.frameName() != "_blank") frame->tree()->setName(request.frameName()); page->chrome().setWindowFeatures(features); // 'x' and 'y' specify the location of the window, while 'width' and 'height' // specify the size of the viewport. We can only resize the window, so adjust // for the difference between the window size and the viewport size. FloatRect windowRect = page->chrome().windowRect(); FloatSize viewportSize = page->chrome().pageRect().size(); if (features.xSet) windowRect.setX(features.x); if (features.ySet) windowRect.setY(features.y); if (features.widthSet) windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width())); if (features.heightSet) windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height())); // Ensure non-NaN values, minimum size as well as being within valid screen area. FloatRect newWindowRect = DOMWindow::adjustWindowRect(page, windowRect); page->chrome().setWindowRect(newWindowRect); page->chrome().show(); created = true; return frame; }