James Moger
2012-10-02 9bdf88df00e9abf99442e14a33ed6215b32026b6
Use a custom redirect mechanism to workaround servlet container interference

This mechanism bypasses the standard Wicket redirect mechanism because it
turns out that the servlet container reencodes Wicket's relative redirect urls.
This results in another way that parameters with forward-slashes can be borked.

Bad, bad servlet container.

org.eclipse.jetty.server.Response#L447: String path=uri.getDecodedPath();
1 files added
3 files modified
69 ■■■■ changed files
src/com/gitblit/wicket/GitblitRedirectException.java 49 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/EmptyRepositoryPage.java 6 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/ProjectPage.java 8 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/UserPage.java 6 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitblitRedirectException.java
New file
@@ -0,0 +1,49 @@
/*
 * Copyright 2012 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket;
import org.apache.wicket.AbstractRestartResponseException;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.request.target.basic.RedirectRequestTarget;
/**
 * This exception bypasses the servlet container rewriting relative redirect
 * urls.  The container can and does decode the carefully crafted %2F path
 * separators on a redirect.  :(  Bad, bad servlet container.
 *
 * org.eclipse.jetty.server.Response#L447: String path=uri.getDecodedPath();
 *
 * @author James Moger
 */
public class GitblitRedirectException extends AbstractRestartResponseException {
    private static final long serialVersionUID = 1L;
    public <C extends Page> GitblitRedirectException(Class<C> pageClass) {
        this(pageClass, null);
    }
    public <C extends Page> GitblitRedirectException(Class<C> pageClass, PageParameters params) {
        RequestCycle cycle = RequestCycle.get();
        String relativeUrl = cycle.urlFor(pageClass, params).toString();
        String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
        cycle.setRequestTarget(new RedirectRequestTarget(absoluteUrl));
        cycle.setRedirect(true);
    }
}
src/com/gitblit/wicket/pages/EmptyRepositoryPage.java
@@ -20,13 +20,13 @@
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RedirectException;
import org.apache.wicket.markup.html.basic.Label;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RepositoryUrlPanel;
@@ -35,12 +35,14 @@
    public EmptyRepositoryPage(PageParameters params) {
        super(params);
        setVersioned(false);
        String repositoryName = WicketUtils.getRepositoryName(params);
        RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName);
        
        if (repository.hasCommits) {
            // redirect to the summary page if this repository is not empty
            throw new RedirectException(SummaryPage.class, params);
            throw new GitblitRedirectException(SummaryPage.class, params);
        }
        
        setupPage(repositoryName, getString("gb.emptyRepository"));
src/com/gitblit/wicket/pages/ProjectPage.java
@@ -31,7 +31,6 @@
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RedirectException;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.ExternalLink;
@@ -53,6 +52,7 @@
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
@@ -70,7 +70,7 @@
    public ProjectPage() {
        super();
        throw new RedirectException(GitBlitWebApp.get().getHomePage());
        throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
    }
    public ProjectPage(PageParameters params) {
@@ -94,12 +94,12 @@
        String projectName = WicketUtils.getProjectName(params);
        if (StringUtils.isEmpty(projectName)) {
            throw new RedirectException(GitBlitWebApp.get().getHomePage());
            throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
        }
        
        ProjectModel project = getProjectModel(projectName);
        if (project == null) {
            throw new RedirectException(GitBlitWebApp.get().getHomePage());
            throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
        }
        
        add(new Label("projectTitle", project.getDisplayName()));
src/com/gitblit/wicket/pages/UserPage.java
@@ -21,7 +21,6 @@
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RedirectException;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
@@ -36,6 +35,7 @@
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
@@ -50,7 +50,7 @@
    public UserPage() {
        super();
        throw new RedirectException(GitBlitWebApp.get().getHomePage());
        throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
    }
    public UserPage(PageParameters params) {
@@ -74,7 +74,7 @@
        String userName = WicketUtils.getUsername(params);
        if (StringUtils.isEmpty(userName)) {
            throw new RedirectException(GitBlitWebApp.get().getHomePage());
            throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
        }
        UserModel user = GitBlit.self().getUserModel(userName);