Search in sources :

Example 1 with BufferedWebResponse

use of org.apache.wicket.protocol.http.BufferedWebResponse in project wicket by apache.

the class WebPageRenderer method renderPage.

/**
 * Renders page to a {@link BufferedWebResponse}. All URLs in page will be rendered relative to
 * <code>targetUrl</code>
 *
 * @param targetUrl
 * @param requestCycle
 * @return BufferedWebResponse containing page body
 */
protected BufferedWebResponse renderPage(Url targetUrl, RequestCycle requestCycle) {
    // get the page before checking for a scheduled request handler because
    // the page may call setResponsePage in its constructor
    IRequestablePage requestablePage = getPage();
    IRequestHandler scheduled = requestCycle.getRequestHandlerScheduledAfterCurrent();
    if (scheduled != null) {
        // no need to render
        return null;
    }
    // keep the original response
    final WebResponse originalResponse = (WebResponse) requestCycle.getResponse();
    // buffered web response for page
    BufferedWebResponse response = new BufferedWebResponse(originalResponse);
    // keep the original base URL
    Url originalBaseUrl = requestCycle.getUrlRenderer().setBaseUrl(targetUrl);
    try {
        requestCycle.setResponse(response);
        requestablePage.renderPage();
        if (requestCycle.getRequestHandlerScheduledAfterCurrent() != null) {
            // This is a special case.
            // During page render another request handler got scheduled and will want to
            // overwrite the response, so we need to let it.
            // Just preserve the meta data headers. Clear the initial actions because they are
            // already copied into the new response's actions
            originalResponse.reset();
            response.writeMetaData(originalResponse);
            return null;
        } else {
            return response;
        }
    } finally {
        // restore original response and base URL
        requestCycle.setResponse(originalResponse);
        requestCycle.getUrlRenderer().setBaseUrl(originalBaseUrl);
    }
}
Also used : BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) WebResponse(org.apache.wicket.request.http.WebResponse) IRequestHandler(org.apache.wicket.request.IRequestHandler) IRequestablePage(org.apache.wicket.request.component.IRequestablePage) Url(org.apache.wicket.request.Url)

Example 2 with BufferedWebResponse

use of org.apache.wicket.protocol.http.BufferedWebResponse in project wicket by apache.

the class WebPageRenderer method respond.

/*
	 * TODO: simplify the code below. See WICKET-3347
	 */
@Override
public void respond(RequestCycle requestCycle) {
    Url currentUrl = requestCycle.getUrlRenderer().getBaseUrl();
    Url targetUrl = requestCycle.mapUrlFor(getRenderPageRequestHandler());
    if (shouldRenderPageAndWriteResponse(requestCycle, currentUrl, targetUrl)) {
        BufferedWebResponse response = renderPage(currentUrl, requestCycle);
        if (response != null) {
            response.writeTo((WebResponse) requestCycle.getResponse());
        }
    } else if (shouldRedirectToTargetUrl(requestCycle, currentUrl, targetUrl)) {
        redirectTo(targetUrl, requestCycle);
    // note: if we had session here we would render the page to buffer and then
    // redirect to URL generated *after* page has been rendered (the statelessness
    // may change during render). this would save one redirect because now we have
    // to render to URL generated *before* page is rendered, render the page, get
    // URL after render and if the URL is different (meaning page is not stateless),
    // save the buffer and redirect again (which is pretty much what the next step
    // does)
    } else {
        if (isRedirectToBuffer() == false && logger.isDebugEnabled()) {
            String details = String.format("redirect strategy: '%s', isAjax: '%s', redirect policy: '%s', " + "current url: '%s', target url: '%s', is new: '%s', is stateless: '%s', is temporary: '%s'", Application.get().getRequestCycleSettings().getRenderStrategy(), isAjax(requestCycle), getRedirectPolicy(), currentUrl, targetUrl, isNewPageInstance(), isPageStateless(), isSessionTemporary());
            logger.debug("Falling back to Redirect_To_Buffer render strategy because none of the conditions " + "matched. Details: " + details);
        }
        // force creation of possible stateful page to get the final target url
        getPage();
        Url beforeRenderUrl = requestCycle.mapUrlFor(getRenderPageRequestHandler());
        // redirect to buffer
        BufferedWebResponse response = renderPage(beforeRenderUrl, requestCycle);
        if (response == null) {
            return;
        }
        // the url might have changed after page has been rendered (e.g. the
        // stateless flag might have changed because stateful components
        // were added)
        final Url afterRenderUrl = requestCycle.mapUrlFor(getRenderPageRequestHandler());
        if (beforeRenderUrl.getSegments().equals(afterRenderUrl.getSegments()) == false) {
            // the amount of segments is different - generated relative URLs
            // will not work, we need to rerender the page. This can happen
            // with IRequestHandlers that produce different URLs with
            // different amount of segments for stateless and stateful pages
            response = renderPage(afterRenderUrl, requestCycle);
        }
        if (currentUrl.equals(afterRenderUrl)) {
            // no need to redirect when both urls are exactly the same
            response.writeTo((WebResponse) requestCycle.getResponse());
        } else // if page is still stateless after render
        if (isPageStateless() && !enableRedirectForStatelessPage()) {
            // we don't want the redirect to happen for stateless page
            // example:
            // when a normal mounted stateful page is hit at /mount/point
            // wicket renders the page to buffer and redirects to /mount/point?12
            // but for stateless page the redirect is not necessary
            // also for request listeners on stateful page we want to redirect
            // after the listener is invoked, but on stateless page the user
            // must ask for redirect explicitly
            response.writeTo((WebResponse) requestCycle.getResponse());
        } else {
            storeBufferedResponse(afterRenderUrl, response);
            redirectTo(afterRenderUrl, requestCycle);
        }
    }
}
Also used : BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) WebResponse(org.apache.wicket.request.http.WebResponse) Url(org.apache.wicket.request.Url)

Example 3 with BufferedWebResponse

use of org.apache.wicket.protocol.http.BufferedWebResponse in project wicket by apache.

the class WebPageRendererTest method testOnePassRenderDifferentProtocols.

/**
 * Tests that when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#ONE_PASS_RENDER}
 * is configured there will be a redirect issued if the protocols of the current and target urls
 * are different
 *
 * https://issues.apache.org/jira/browse/WICKET-5522
 */
@Test
public void testOnePassRenderDifferentProtocols() {
    final AtomicBoolean responseBuffered = new AtomicBoolean(false);
    PageRenderer renderer = new TestPageRenderer(handler) {

        @Override
        protected boolean isOnePassRender() {
            return true;
        }

        @Override
        protected void storeBufferedResponse(Url url, BufferedWebResponse response) {
            responseBuffered.set(true);
        }
    };
    // uses HTTPS
    when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("https://host/base"));
    when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("http://host/base/a"));
    when(request.shouldPreserveClientUrl()).thenReturn(false);
    renderer.respond(requestCycle);
    verify(response, never()).write(any(byte[].class));
    verify(response).sendRedirect(isNull());
    assertTrue(responseBuffered.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) Url(org.apache.wicket.request.Url) Test(org.junit.Test)

Example 4 with BufferedWebResponse

use of org.apache.wicket.protocol.http.BufferedWebResponse in project wicket by apache.

the class WebPageRendererTest method testRedirectToBufferNoPageToRender.

/**
 * Tests that when during page render another request handler got scheduled. The handler will
 * want to overwrite the response, so we need to let it
 */
@Test
public void testRedirectToBufferNoPageToRender() {
    final AtomicBoolean stored = new AtomicBoolean(false);
    TestPageRenderer renderer = new TestPageRenderer(handler) {

        @Override
        protected BufferedWebResponse renderPage(Url targetUrl, RequestCycle requestCycle) {
            return null;
        }

        @Override
        protected void storeBufferedResponse(Url url, BufferedWebResponse response) {
            stored.set(true);
        }
    };
    renderer.redirectToBuffer = true;
    // needed for earlier checks
    when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a"));
    when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b"));
    renderer.respond(requestCycle);
    verify(response, never()).write(any(byte[].class));
    verify(response, never()).write(any(CharSequence.class));
    verify(response, never()).sendRedirect(anyString());
    Assert.assertFalse(stored.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) RequestCycle(org.apache.wicket.request.cycle.RequestCycle) Url(org.apache.wicket.request.Url) Test(org.junit.Test)

Example 5 with BufferedWebResponse

use of org.apache.wicket.protocol.http.BufferedWebResponse in project wicket by apache.

the class WebPageRendererTest method testRedirectToBufferStatelessPageAndRedirectIsEsabled.

/**
 * Tests that when the page is stateless and redirect for stateless pages is enabled then there
 * should be a redirect
 */
@Test
public void testRedirectToBufferStatelessPageAndRedirectIsEsabled() {
    final AtomicBoolean stored = new AtomicBoolean(false);
    PageRenderer renderer = new TestPageRenderer(handler) {

        @Override
        protected boolean isRedirectToBuffer() {
            return true;
        }

        @Override
        protected void storeBufferedResponse(Url url, BufferedWebResponse response) {
            stored.set(true);
        }
    };
    when(page.isPageStateless()).thenReturn(true);
    // needed for earlier checks
    when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a"));
    when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b"));
    renderer.respond(requestCycle);
    verify(response, never()).write(any(byte[].class));
    verify(response).sendRedirect(isNull());
    Assert.assertTrue(stored.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) BufferedWebResponse(org.apache.wicket.protocol.http.BufferedWebResponse) Url(org.apache.wicket.request.Url) Test(org.junit.Test)

Aggregations

BufferedWebResponse (org.apache.wicket.protocol.http.BufferedWebResponse)17 Url (org.apache.wicket.request.Url)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 Test (org.junit.Test)7 RequestCycle (org.apache.wicket.request.cycle.RequestCycle)6 WebResponse (org.apache.wicket.request.http.WebResponse)4 Application (org.apache.wicket.Application)1 MarkupContainer (org.apache.wicket.MarkupContainer)1 Page (org.apache.wicket.Page)1 WicketRuntimeException (org.apache.wicket.WicketRuntimeException)1 BufferedResponseRequestHandler (org.apache.wicket.core.request.handler.BufferedResponseRequestHandler)1 MockApplication (org.apache.wicket.mock.MockApplication)1 MockWebRequest (org.apache.wicket.mock.MockWebRequest)1 WebApplication (org.apache.wicket.protocol.http.WebApplication)1 IRequestHandler (org.apache.wicket.request.IRequestHandler)1 Request (org.apache.wicket.request.Request)1 Response (org.apache.wicket.request.Response)1 IRequestablePage (org.apache.wicket.request.component.IRequestablePage)1