[ 
https://issues.apache.org/jira/browse/WICKET-6111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15396516#comment-15396516
 ] 

Miklos Krivan edited comment on WICKET-6111 at 7/27/16 10:26 PM:
-----------------------------------------------------------------

Unfortunately it did not resolved not in 7.3.0 and 7.4.0 as well at least 
working with Glassfish 3.1.2.2. Maybe the problem is a little bit different but 
it appeared in version 7.3.0 first. It was good with 7.1.0 and 7.0.0. With 
7.2.0 was something strange as well.
When an application mounted at root point, all of the first try to access the 
root point will be failed using IE11. It works with Chrome and Firefox. I did 
deep investigation and I have found that the redirect location looks something 
like http://localhost:port;jsessionid=abcd. If this happens 403 status occurs. 
But if return with http://localhost:port/;jsessionid=abcd everything works 
perfect. The solution is based on Thorsten Schöning comment but a little bit 
modified:

{noformat}
        public class WicketApplication extends WebApplication
        {
                ...

                @Override
                public Class<? extends BasePage> getHomePage() {
                        return IndexPage.class; // it has no mount mapping 
point defined because it is the root HomePage class
                }
                
                @Override
                protected WebResponse newWebResponse(WebRequest webRequest, 
HttpServletResponse httpServletResponse) {
                        return new MyWebResponse((ServletWebRequest) 
webRequest, httpServletResponse);
                }
        }

        import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
        import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
        import org.apache.wicket.request.Url;
        import org.apache.wicket.request.UrlRenderer;

        public class MyWebResponse extends ServletWebResponse {

                private final static Pattern URL_PATTERN = 
Pattern.compile("^(?:(https?)://)?([A-Za-z0-9\\-\\.]+)(?::([0-9]+))?(/)?(.*)$");
                private final ServletWebRequest servletWebRequest;
                private final HttpServletResponse httpServletResponse;

                public MyWebResponse(ServletWebRequest servletWebRequest, 
HttpServletResponse httpServletResponse) {
                        super(servletWebRequest, httpServletResponse);
                        this.servletWebRequest = servletWebRequest;
                        this.httpServletResponse = httpServletResponse;
                }

                private String ifNull(String o, String nullValue) {
                        return o == null ? nullValue : o;
                }
                
                private String addMissingRootToUrl(String url) { // this is the 
correction util for missing root path (/)
                        if (StringUtils.isBlank(url)) {
                                return url;
                        }
                        Matcher m = URL_PATTERN.matcher(url);
                        if (m.find()) {
                                String protocol = ifNull(m.group(1), "");
                                String host = ifNull(m.group(2), "");
                                String port = ifNull(m.group(3), "");
                                String root = ifNull(m.group(4), "/");
                                String remaining = ifNull(m.group(5), "");
                                StringBuilder resultUrl = new StringBuilder();
                                if (StringUtils.isNotBlank(protocol)) {
                                        
resultUrl.append(protocol).append("://");
                                }
                                if (StringUtils.isNotBlank(host)) {
                                        resultUrl.append(host);
                                }
                                if (StringUtils.isNotBlank(port)) {
                                        resultUrl.append(":").append(port);
                                }
                                if (StringUtils.isNotBlank(root)) {
                                        resultUrl.append(root);
                                }
                                resultUrl.append(remaining);
                                return resultUrl.toString();
                        } else {
                                return url;
                        }
                }

                @Override
                public String encodeRedirectURL(CharSequence url) {
                        String retVal = super.encodeRedirectURL(url); // this 
generates the problem for app root access in IE11
                        if (!retVal.startsWith("./")) {
                                return retVal;
                        }
                        UrlRenderer urlRenderer = new 
UrlRenderer(servletWebRequest);
                        Url originalUrl = Url.parse(url);
                        String fullUrlStr = 
urlRenderer.renderFullUrl(originalUrl);
                        retVal = 
httpServletResponse.encodeRedirectURL(fullUrlStr);
                        retVal = addMissingRootToUrl(retVal); // finally this 
is the corrected absolute path for 302 status message Location part
                        return retVal; // this way IE11 works properly in 
Wicket 7.3.0 and 7.4.0 as well
                }
        }
{noformat}

Using this approach the Wicket is working again with IE11.
I know that it should be nicer approach but I could only solve this way.
I hope this helps to you.


was (Author: mkrivan):
Unfortunately it did not resolved not in 7.3.0 and 7.4.0 as well at least 
working with Glassfish 3.1.2.2. Maybe the problem is a little bit different but 
it appeared in version 7.3.0 first. It was good with 7.1.0 and 7.0.0. With 
7.2.0 was something strange as well.
When an application mounted at root point, all of the first try to access the 
root point will be failed using IE11. It works with Chrome and Firefox. I did 
deep investigation and I have found that the redirect location looks something 
like http://localhost:port;jsessionid=abcd. If this happens 403 status occurs. 
But if return with http://localhost:port/;jsessionid=abcd everything works 
perfect. The solution is based on Thorsten Shöning comment but a little bit 
modified:

{noformat}
        public class WicketApplication extends WebApplication
        {
                ...

                @Override
                public Class<? extends BasePage> getHomePage() {
                        return IndexPage.class; // it has no mount mapping 
point defined because it is the root HomePage class
                }
                
                @Override
                protected WebResponse newWebResponse(WebRequest webRequest, 
HttpServletResponse httpServletResponse) {
                        return new MyWebResponse((ServletWebRequest) 
webRequest, httpServletResponse);
                }
        }

        import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
        import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
        import org.apache.wicket.request.Url;
        import org.apache.wicket.request.UrlRenderer;

        public class MyWebResponse extends ServletWebResponse {

                private final static Pattern URL_PATTERN = 
Pattern.compile("^(?:(https?)://)?([A-Za-z0-9\\-\\.]+)(?::([0-9]+))?(/)?(.*)$");
                private final ServletWebRequest servletWebRequest;
                private final HttpServletResponse httpServletResponse;

                public MyWebResponse(ServletWebRequest servletWebRequest, 
HttpServletResponse httpServletResponse) {
                        super(servletWebRequest, httpServletResponse);
                        this.servletWebRequest = servletWebRequest;
                        this.httpServletResponse = httpServletResponse;
                }

                private String ifNull(String o, String nullValue) {
                        return o == null ? nullValue : o;
                }
                
                private String addMissingRootToUrl(String url) { // this is the 
correction util for missing root path (/)
                        if (StringUtils.isBlank(url)) {
                                return url;
                        }
                        Matcher m = URL_PATTERN.matcher(url);
                        if (m.find()) {
                                String protocol = ifNull(m.group(1), "");
                                String host = ifNull(m.group(2), "");
                                String port = ifNull(m.group(3), "");
                                String root = ifNull(m.group(4), "/");
                                String remaining = ifNull(m.group(5), "");
                                StringBuilder resultUrl = new StringBuilder();
                                if (StringUtils.isNotBlank(protocol)) {
                                        
resultUrl.append(protocol).append("://");
                                }
                                if (StringUtils.isNotBlank(host)) {
                                        resultUrl.append(host);
                                }
                                if (StringUtils.isNotBlank(port)) {
                                        resultUrl.append(":").append(port);
                                }
                                if (StringUtils.isNotBlank(root)) {
                                        resultUrl.append(root);
                                }
                                resultUrl.append(remaining);
                                return resultUrl.toString();
                        } else {
                                return url;
                        }
                }

                @Override
                public String encodeRedirectURL(CharSequence url) {
                        String retVal = super.encodeRedirectURL(url); // this 
generates the problem for app root access in IE11
                        if (!retVal.startsWith("./")) {
                                return retVal;
                        }
                        UrlRenderer urlRenderer = new 
UrlRenderer(servletWebRequest);
                        Url originalUrl = Url.parse(url);
                        String fullUrlStr = 
urlRenderer.renderFullUrl(originalUrl);
                        retVal = 
httpServletResponse.encodeRedirectURL(fullUrlStr);
                        retVal = addMissingRootToUrl(retVal); // finally this 
is the corrected absolute path for 302 status message Location part
                        return retVal; // this way IE11 works properly in 
Wicket 7.3.0 and 7.4.0 as well
                }
        }
{noformat}

Using this approach the Wicket is working again with IE11.
I know that it should be nicer approach but I could only solve this way.
I hope this helps to you.

> Empty redirect on redirect to home page if home page already shown
> ------------------------------------------------------------------
>
>                 Key: WICKET-6111
>                 URL: https://issues.apache.org/jira/browse/WICKET-6111
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 7.2.0
>         Environment: Windows 8.1 x86-64, Tomcat 7.0.67
>            Reporter: Thorsten Schöning
>            Assignee: Martin Grigorov
>             Fix For: 7.3.0, 8.0.0-M1, 6.23.0
>
>         Attachments: empty_redirect.zip
>
>
> Wicket seems to produce an empty redirect if a user already opened the home 
> page of an app and gets redirected to the same page by e.g. clicking a link 
> containing the following line:
> {CODE}
> RequestCycle.get().setResponsePage(Application.get().getHomePage(), ...);
> {CODE}
> In my case the purpose of the link is to sign out and redirect all users to a 
> well known page afterwards. Involved URLs:
> {CODE}
> http://localhost:8080/org.example.frontend/?0
> http://localhost:8080/org.example.frontend/?0-1.ILinkListener-home.signOut
> {CODE}
> In this case Wicket creates an empty target URL for a redirect and sends that 
> to my Tomcat 7, which seem to just forward it to the browser, which does 
> nothing. The result is that the user sits on a white page and needs to 
> refresh manually using e.g. F5. In contrast with a qucikstart containing and 
> embedded Jetty, Wicket generates the exact same empty target URL but Jetty 
> seem to resolve it internally to a absolut URL and therefore the requests 
> succeeds now.
> Example from the browser using Tomcat 7:
> {CODE}
> Request 
> URL:http://localhost:8081/org.example.frontend/?3-1.ILinkListener-html-body-pnNav-home.signOut
> Request Method:GET
> Status Code:302 Found
> Remote Address:127.0.0.1:8081
> Cache-Control:no-cache, no-store
> Content-Length:0
> Date:Sun, 06 Mar 2016 19:34:40 GMT
> Expires:Thu, 01 Jan 1970 00:00:00 GMT
> Location:
> Pragma:no-cache
> Server:Apache-Coyote/1.1
> Set-Cookie:JSESSIONID=[...]; Path=/org.example.frontend/; HttpOnly
> {CODE}
> And from Jetty:
> {CODE}
> Request 
> URL:http://localhost:8080/org.example.frontend/?0-1.ILinkListener-home.signOut
> Request Method:GET
> Status Code:302 Found
> Remote Address:[::1]:8080
> Response Headers
> view source
> Cache-Control:no-cache, no-store
> Content-Length:0
> Date:Mon, 07 Mar 2016 15:12:40 GMT
> Expires:Thu, 01 Jan 1970 00:00:00 GMT
> Location:http://localhost:8080/org.example.frontend/
> Pragma:no-cache
> Server:Jetty(9.2.13.v20150730)
> {CODE}
> Debugging lead to 
> org.apache.wicket.protocol.http.servlet.ServletWebResponse#encodeRedirectURL 
> and #sendRedirect:
> This function behaves (nearly) the same for my URLs, the only difference is 
> the following line:
> {CODE}
> Url originalUrl = Url.parse(url);
> {CODE}
> In my Tomcat I get a completely empty object, NOT null though, in the 
> quickstart with Jetty I get an object containing ".". But in the end that 
> doesn't seem to make any difference, both requests go through the following:
> {CODE}
> if (fullUrl.equals(encodedFullUrl))
> {
>         // no encoding happened so just reuse the original url
>         encodedUrl = url.toString();
> }
> {CODE}
> encodedUrl is "./" using Tomcat and Jetty as well, while "fullUrl" contains 
> an absolute URL in both cases:
> {CODE}
> http://localhost:8080/org.example.frontend/
> {CODE}
> "./" is returned to ServletWebResponse.sendRedirect and runs into the 
> following:
> {CODE}
> if (url.startsWith("./"))
> {
>         /*
>          * WICKET-4260 Tomcat does not canonalize urls, which leads to 
> problems with IE
>          * when url is relative and starts with a dot
>          */
>         url = url.substring(2);
> }
> {CODE}
> And that empties my URL and forwards it to the servlet container, where Jetty 
> instead of Tomcat seems to provide some magic to respond with an absolute URL 
> in the end. But my debugger says that in both cases
> {CODE}
> httpServletResponse.sendRedirect(url);
> {CODE}
> gets called with an empty string.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to