From 7e5ee5a454ec396b5dc2f00e89adeca84d6ef683 Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 18 Jul 2011 18:10:34 -0400 Subject: [PATCH] Allow specification of forward-slash character in urls (issue 11) --- distrib/gitblit.properties | 16 +++- docs/00_index.mkd | 1 + docs/02_faq.mkd | 3 + docs/04_releases.mkd | 1 + src/com/gitblit/GitBlit.java | 14 ++++ src/com/gitblit/IStoredSettings.java | 20 +++++ src/com/gitblit/wicket/GitBlitWebApp.java | 2 +- .../wicket/GitblitParamUrlCodingStrategy.java | 83 +++++++++++++++++++ 8 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 src/com/gitblit/wicket/GitblitParamUrlCodingStrategy.java diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties index 2ae3d011..73a1747c 100644 --- a/distrib/gitblit.properties +++ b/distrib/gitblit.properties @@ -135,13 +135,25 @@ web.datetimestampLongFormat = EEEE, MMMM d, yyyy h:mm a z # Mount URL parameters # This setting controls if pretty or parameter URLs are used. # i.e. -# if true: http://localhost/commit/myrepo/abcdef -# if false: http://localhost/commit/?r=myrepo&h=abcdef +# if true: +# http://localhost/commit/myrepo/abcdef +# if false: +# http://localhost/commit/?r=myrepo&h=abcdef # # SINCE 0.5.0 # RESTART REQUIRED web.mountParameters = true +# Some servlet containers (e.g. Tomcat >= 6.0.10) disallow '/' (%2F) encoding +# in URLs as a security precaution for proxies. This setting tells Gitblit +# to preemptively replace '/' with '*' or '!' for url string parameters. +# +# +# +# +# SINCE 0.5.2 +web.forwardSlashCharacter = / + # Show other URLs on the summary page for accessing your git repositories # Use spaces to separate urls. {0} is the token for the repository name. # e.g. diff --git a/docs/00_index.mkd b/docs/00_index.mkd index edb058d8..a2f83132 100644 --- a/docs/00_index.mkd +++ b/docs/00_index.mkd @@ -23,6 +23,7 @@ Gitblit requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit **%VERSION%** ([go](http://code.google.com/p/gitblit/downloads/detail?name=%GO%)|[war](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%)) based on [%JGIT%][jgit]   *released %BUILDDATE%* +- forward-slashes ('/', %2F) can be encoded using a custom character to workaround some servlet container default security measures for proxy servers
**New:** *web.forwardSlashCharacter = /* - optionally display repository on-disk size on repositories page
**New:** *web.showRepositorySizes = true* - tone-down repository group header color diff --git a/docs/02_faq.mkd b/docs/02_faq.mkd index e160773d..a1fcf139 100644 --- a/docs/02_faq.mkd +++ b/docs/02_faq.mkd @@ -36,6 +36,9 @@ Run the server as *root* (security concern) or change the ports you are serving ### Gitblit WAR will not authenticate any users?! Confirm that the <context-param> *realm.userService* value in your `web.xml` file actually points to a `users.properties` file. +### Gitblit won't open my grouped repository (/group/myrepo.git) or browse my branch/tag/ref?! +This is likely an url encoding/decoding problem. In `gitblit.properties` or `web.xml`, try setting *web.mountParameters* to *false*. + ## General Interest Questions ### Gitblit? What kind of name is that? diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd index 94aaa1a1..559b1327 100644 --- a/docs/04_releases.mkd +++ b/docs/04_releases.mkd @@ -3,6 +3,7 @@ ### Current Release **%VERSION%** ([go](http://code.google.com/p/gitblit/downloads/detail?name=%GO%)|[war](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%)) based on [%JGIT%][jgit]   *released %BUILDDATE%* +- forward-slashes ('/', %2F) can be encoded using a custom character to workaround some servlet container default security measures for proxy servers
**New:** *web.forwardSlashCharacter = /* - optionally display repository on-disk size on repositories page
**New:** *web.showRepositorySizes = true* - tone-down repository group header color diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 968034de..e570e7bc 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -128,6 +128,20 @@ public class GitBlit implements ServletContextListener { return self().settings.getInteger(key, defaultValue); } + /** + * Returns the char value for the specified key. If the key does not exist + * or the value for the key can not be interpreted as a character, the + * defaultValue is returned. + * + * @see IStoredSettings.getChar(String key, char defaultValue) + * @param key + * @param defaultValue + * @return key value or defaultValue + */ + public static char getChar(String key, char defaultValue) { + return self().settings.getChar(key, defaultValue); + } + /** * Returns the string value for the specified key. If the key does not exist * or the value for the key can not be interpreted as a string, the diff --git a/src/com/gitblit/IStoredSettings.java b/src/com/gitblit/IStoredSettings.java index b380c638..0cc4bb46 100644 --- a/src/com/gitblit/IStoredSettings.java +++ b/src/com/gitblit/IStoredSettings.java @@ -116,6 +116,26 @@ public abstract class IStoredSettings { } return defaultValue; } + + /** + * Returns the char value for the specified key. If the key does not exist + * or the value for the key can not be interpreted as a char, the + * defaultValue is returned. + * + * @param key + * @param defaultValue + * @return key value or defaultValue + */ + public char getChar(String name, char defaultValue) { + Properties props = getSettings(); + if (props.containsKey(name)) { + String value = props.getProperty(name); + if (!StringUtils.isEmpty(value)) { + return value.charAt(0); + } + } + return defaultValue; + } /** * Returns the string value for the specified key. If the key does not exist diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java index 1b13ea38..4b5e6604 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/com/gitblit/wicket/GitBlitWebApp.java @@ -110,7 +110,7 @@ public class GitBlitWebApp extends WebApplication { if (!GitBlit.getBoolean(Keys.web.mountParameters, true)) { parameters = new String[] {}; } - mount(new MixedParamUrlCodingStrategy(location, clazz, parameters)); + mount(new GitblitParamUrlCodingStrategy(location, clazz, parameters)); } @Override diff --git a/src/com/gitblit/wicket/GitblitParamUrlCodingStrategy.java b/src/com/gitblit/wicket/GitblitParamUrlCodingStrategy.java new file mode 100644 index 00000000..c30b9c30 --- /dev/null +++ b/src/com/gitblit/wicket/GitblitParamUrlCodingStrategy.java @@ -0,0 +1,83 @@ +/* + * Copyright 2011 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.Page; +import org.apache.wicket.protocol.http.WicketURLDecoder; +import org.apache.wicket.protocol.http.WicketURLEncoder; +import org.apache.wicket.request.target.coding.MixedParamUrlCodingStrategy; + +import com.gitblit.GitBlit; +import com.gitblit.Keys; + +/** + * Simple subclass of mixed parameter url coding strategy that works around the + * encoded forward-slash issue that is present in some servlet containers. + * + * https://issues.apache.org/jira/browse/WICKET-1303 + * http://tomcat.apache.org/security-6.html + * + * @author James Moger + * + */ +public class GitblitParamUrlCodingStrategy extends MixedParamUrlCodingStrategy { + + /** + * Construct. + * + * @param + * @param mountPath + * mount path (not empty) + * @param bookmarkablePageClass + * class of mounted page (not null) + * @param parameterNames + * the parameter names (not null) + */ + public GitblitParamUrlCodingStrategy(String mountPath, + Class bookmarkablePageClass, String[] parameterNames) { + super(mountPath, bookmarkablePageClass, parameterNames); + } + + /** + * Url encodes a string that is mean for a URL path (e.g., between slashes) + * + * @param string + * string to be encoded + * @return encoded string + */ + protected String urlEncodePathComponent(String string) { + char altChar = GitBlit.getChar(Keys.web.forwardSlashCharacter, '/'); + if (altChar != '/') { + string = string.replace('/', altChar); + } + return super.urlEncodePathComponent(string); + } + + /** + * Returns a decoded value of the given value (taken from a URL path + * section) + * + * @param value + * @return Decodes the value + */ + protected String urlDecodePathComponent(String value) { + char altChar = GitBlit.getChar(Keys.web.forwardSlashCharacter, '/'); + if (altChar != '/') { + value = value.replace(altChar, '/'); + } + return super.urlDecodePathComponent(value); + } +} \ No newline at end of file -- 2.39.5