Search in sources :

Example 1 with PageDenied

use of com.gargoylesoftware.htmlunit.html.FrameWindow.PageDenied in project htmlunit by HtmlUnit.

the class WebClient method loadWebResponseInto.

/**
 * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
 *
 * <p>Creates a page based on the specified response and inserts it into the specified window. All page
 * initialization and event notification is handled here.</p>
 *
 * <p>Note that if the page created is an attachment page, and an {@link AttachmentHandler} has been
 * registered with this client, the page is <b>not</b> loaded into the specified window; in this case,
 * the page is loaded into a new window, and attachment handling is delegated to the registered
 * <tt>AttachmentHandler</tt>.</p>
 *
 * @param webResponse the response that will be used to create the new page
 * @param webWindow the window that the new page will be placed within
 * @param forceAttachment handle this as attachment (is set to true if the call was triggered from
 * anchor with download property set).
 * @throws IOException if an IO error occurs
 * @throws FailingHttpStatusCodeException if the server returns a failing status code AND the property
 *         {@link WebClientOptions#setThrowExceptionOnFailingStatusCode(boolean)} is set to true
 * @return the newly created page
 * @see #setAttachmentHandler(AttachmentHandler)
 */
public Page loadWebResponseInto(final WebResponse webResponse, final WebWindow webWindow, final boolean forceAttachment) throws IOException, FailingHttpStatusCodeException {
    WebAssert.notNull("webResponse", webResponse);
    WebAssert.notNull("webWindow", webWindow);
    if (webResponse.getStatusCode() == HttpStatus.SC_NO_CONTENT) {
        return webWindow.getEnclosedPage();
    }
    if (webStartHandler_ != null && "application/x-java-jnlp-file".equals(webResponse.getContentType())) {
        webStartHandler_.handleJnlpResponse(webResponse);
        return webWindow.getEnclosedPage();
    }
    if (attachmentHandler_ != null && (forceAttachment || attachmentHandler_.isAttachment(webResponse))) {
        if (attachmentHandler_.handleAttachment(webResponse)) {
            // do not open a new window
            return webWindow.getEnclosedPage();
        }
        final WebWindow w = openWindow(null, null, webWindow);
        final Page page = pageCreator_.createPage(webResponse, w);
        attachmentHandler_.handleAttachment(page);
        return page;
    }
    final Page oldPage = webWindow.getEnclosedPage();
    if (oldPage != null) {
        // Remove the old page before create new one.
        oldPage.cleanUp();
    }
    Page newPage = null;
    FrameWindow.PageDenied pageDenied = PageDenied.NONE;
    if (windows_.contains(webWindow) || getBrowserVersion().hasFeature(WINDOW_EXECUTE_EVENTS)) {
        if (webWindow instanceof FrameWindow) {
            final String contentSecurityPolicy = webResponse.getResponseHeaderValue(HttpHeader.CONTENT_SECURIRY_POLICY);
            if (StringUtils.isNotBlank(contentSecurityPolicy) && !getBrowserVersion().hasFeature(CONTENT_SECURITY_POLICY_IGNORED)) {
                final URL origin = UrlUtils.getUrlWithoutPathRefQuery(((FrameWindow) webWindow).getEnclosingPage().getUrl());
                final URL source = UrlUtils.getUrlWithoutPathRefQuery(webResponse.getWebRequest().getUrl());
                final Policy policy = Policy.parseSerializedCSP(contentSecurityPolicy, Policy.PolicyErrorConsumer.ignored);
                if (!policy.allowsFrameAncestor(Optional.of(URI.parseURI(source.toExternalForm()).orElse(null)), Optional.of(URI.parseURI(origin.toExternalForm()).orElse(null)))) {
                    pageDenied = PageDenied.BY_CONTENT_SECURIRY_POLICY;
                    if (LOG.isWarnEnabled()) {
                        LOG.warn("Load denied by Content-Security-Policy: '" + contentSecurityPolicy + "' - " + webResponse.getWebRequest().getUrl() + "' does not permit framing.");
                    }
                }
            }
            if (pageDenied == PageDenied.NONE) {
                final String xFrameOptions = webResponse.getResponseHeaderValue(HttpHeader.X_FRAME_OPTIONS);
                if ("DENY".equalsIgnoreCase(xFrameOptions)) {
                    pageDenied = PageDenied.BY_X_FRAME_OPTIONS;
                    if (LOG.isWarnEnabled()) {
                        LOG.warn("Load denied by X-Frame-Options: DENY; - '" + webResponse.getWebRequest().getUrl() + "' does not permit framing.");
                    }
                }
            }
        }
        if (pageDenied == PageDenied.NONE) {
            newPage = pageCreator_.createPage(webResponse, webWindow);
        } else {
            try {
                final WebResponse aboutBlank = loadWebResponse(WebRequest.newAboutBlankRequest());
                newPage = pageCreator_.createPage(aboutBlank, webWindow);
                // TODO - maybe we have to attach to original request/response to the page
                ((FrameWindow) webWindow).setPageDenied(pageDenied);
            } catch (final IOException e) {
            // ignore
            }
        }
        if (windows_.contains(webWindow)) {
            fireWindowContentChanged(new WebWindowEvent(webWindow, WebWindowEvent.CHANGE, oldPage, newPage));
            // The page being loaded may already have been replaced by another page via JavaScript code.
            if (webWindow.getEnclosedPage() == newPage) {
                newPage.initialize();
                // here is a hack to handle non HTML pages
                if (isJavaScriptEnabled() && webWindow instanceof FrameWindow && !newPage.isHtmlPage()) {
                    final FrameWindow fw = (FrameWindow) webWindow;
                    final BaseFrameElement frame = fw.getFrameElement();
                    if (frame.hasEventHandlers("onload")) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Executing onload handler for " + frame);
                        }
                        final Event event = new Event(frame, Event.TYPE_LOAD);
                        ((Node) frame.getScriptableObject()).executeEventLocally(event);
                    }
                }
            }
        }
    }
    return newPage;
}
Also used : Policy(com.shapesecurity.salvation2.Policy) BaseFrameElement(com.gargoylesoftware.htmlunit.html.BaseFrameElement) DomNode(com.gargoylesoftware.htmlunit.html.DomNode) Node(com.gargoylesoftware.htmlunit.javascript.host.dom.Node) XHtmlPage(com.gargoylesoftware.htmlunit.html.XHtmlPage) HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) IOException(java.io.IOException) FrameWindow(com.gargoylesoftware.htmlunit.html.FrameWindow) URL(java.net.URL) PageDenied(com.gargoylesoftware.htmlunit.html.FrameWindow.PageDenied) Event(com.gargoylesoftware.htmlunit.javascript.host.event.Event)

Aggregations

BaseFrameElement (com.gargoylesoftware.htmlunit.html.BaseFrameElement)1 DomNode (com.gargoylesoftware.htmlunit.html.DomNode)1 FrameWindow (com.gargoylesoftware.htmlunit.html.FrameWindow)1 PageDenied (com.gargoylesoftware.htmlunit.html.FrameWindow.PageDenied)1 HtmlPage (com.gargoylesoftware.htmlunit.html.HtmlPage)1 XHtmlPage (com.gargoylesoftware.htmlunit.html.XHtmlPage)1 Node (com.gargoylesoftware.htmlunit.javascript.host.dom.Node)1 Event (com.gargoylesoftware.htmlunit.javascript.host.event.Event)1 Policy (com.shapesecurity.salvation2.Policy)1 IOException (java.io.IOException)1 URL (java.net.URL)1