Merge changes from topic 'gitweb-cleanup'

* changes:
  Use consistent lowercase for "gitweb"
  GitWebConfig: Minor cleanup
  Move logic from GitWebType to GitWebConfig
  Extract CGI configuration from GitWebConfig
  GitWebConfig: Fix check for set-to-empty-string
This commit is contained in:
Dave Borowitz 2015-06-12 18:46:54 +00:00 committed by Gerrit Code Review
commit b3f83e2ec6
31 changed files with 684 additions and 656 deletions

View File

@ -1763,7 +1763,7 @@ Whether or not Gerrit should encode the generated viewer URL.
+ +
Gerrit composes the viewer URL using information about the project, branch, file Gerrit composes the viewer URL using information about the project, branch, file
or commit of the target object to be displayed. Typically viewers such as CGit or commit of the target object to be displayed. Typically viewers such as CGit
and GitWeb do need those parts to be encoded, including the '/' in project's name, and gitweb do need those parts to be encoded, including the '/' in project's name,
for being correctly parsed. for being correctly parsed.
However other viewers could instead require an unencoded URL (e.g. GitHub web However other viewers could instead require an unencoded URL (e.g. GitHub web
based viewer) based viewer)

View File

@ -67,12 +67,12 @@ able to read the gitweb info for any of the branches in that project.
For the external configuration, gitweb runs under the control of an For the external configuration, gitweb runs under the control of an
external web server, and Gerrit access controls are not enforced. Gerrit external web server, and Gerrit access controls are not enforced. Gerrit
provides configuration parameters for integration with GitWeb. provides configuration parameters for integration with gitweb.
[[linuxGitWeb]] [[linuxGitWeb]]
==== Linux Installation ==== Linux Installation
===== Install GitWeb ===== Install Gitweb
On Ubuntu: On Ubuntu:
@ -86,7 +86,7 @@ With Yum:
$ yum install gitweb $ yum install gitweb
==== ====
===== Configure GitWeb ===== Configure Gitweb
Update `/etc/gitweb.conf`, add the public GIT repositories: Update `/etc/gitweb.conf`, add the public GIT repositories:
@ -161,7 +161,7 @@ link:http://localhost/gitweb[http://localhost/gitweb]
[[WindowsGitWeb]] [[WindowsGitWeb]]
==== Windows Installation ==== Windows Installation
Instructions are available for installing the GitWeb module distributed with Instructions are available for installing the gitweb module distributed with
MsysGit: MsysGit:
link:https://github.com/msysgit/msysgit/wiki/GitWeb[GitWeb] link:https://github.com/msysgit/msysgit/wiki/GitWeb[GitWeb]
@ -176,7 +176,7 @@ If you're still having difficulty setting up permissions, you may find this
tech note useful for configuring Apache Service to run under another account. tech note useful for configuring Apache Service to run under another account.
You must grant the new account link:http://technet.microsoft.com/en-us/library/cc794944(WS.10).aspx["run as service"] permission: You must grant the new account link:http://technet.microsoft.com/en-us/library/cc794944(WS.10).aspx["run as service"] permission:
The GitWeb version in msysgit is missing several important and required The gitweb version in msysgit is missing several important and required
perl modules, including CGI.pm. The perl included with the msysgit distro 1.7.8 perl modules, including CGI.pm. The perl included with the msysgit distro 1.7.8
is broken.. The link:http://groups.google.com/group/msysgit/browse_thread/thread/ba3501f1f0ed95af[unicore folder is missing along with utf8_heavy.pl and CGI.pm]. You can is broken.. The link:http://groups.google.com/group/msysgit/browse_thread/thread/ba3501f1f0ed95af[unicore folder is missing along with utf8_heavy.pl and CGI.pm]. You can
verify by checking for perl modules. From an msys console, execute the verify by checking for perl modules. From an msys console, execute the
@ -207,7 +207,7 @@ contents: `bin/` `lib/` `site/`
copy the contents of lib into `msysgit/lib/perl5/5.8.8` and overwrite existing files. copy the contents of lib into `msysgit/lib/perl5/5.8.8` and overwrite existing files.
==== Enable GitWeb Integration ==== Enable Gitweb Integration
To enable the external gitweb integration, set To enable the external gitweb integration, set
link:config-gerrit.html#gitweb.url[gitweb.url] with the URL of your link:config-gerrit.html#gitweb.url[gitweb.url] with the URL of your

View File

@ -166,7 +166,7 @@ Project]
This plugin allows the rendering of Git repository branch network in a This plugin allows the rendering of Git repository branch network in a
graphical HTML5 Canvas. It is mainly intended to be used as a graphical HTML5 Canvas. It is mainly intended to be used as a
"project link" in a GitWeb configuration or by other Gerrit GWT UI "project link" in a gitweb configuration or by other Gerrit GWT UI
plugins to be plugged elsewhere in Gerrit. plugins to be plugged elsewhere in Gerrit.
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/branch-network[ link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/branch-network[

View File

@ -63,7 +63,7 @@ always see how the access rights were changed and by whom. If a good
commit message is provided you can also see from the history why the commit message is provided you can also see from the history why the
access rights were modified. access rights were modified.
If a Git browser such as GitWeb is configured for the Gerrit server you If a Git browser such as gitweb is configured for the Gerrit server you
can find a link to the history of the `project.config` file in the can find a link to the history of the `project.config` file in the
Web UI. Otherwise you may inspect the history locally. If you have Web UI. Otherwise you may inspect the history locally. If you have
cloned the repository you can do this by executing the following cloned the repository you can do this by executing the following

View File

@ -1165,48 +1165,48 @@ bugs link].
|================================= |=================================
[[git-web-info]] [[git-web-info]]
=== GitWebInfo === GitwebInfo
The `GitWebInfo` entity contains information about the The `GitwebInfo` entity contains information about the
link:config-gerrit.html#gitweb[GitWeb] configuration. link:config-gerrit.html#gitweb[gitweb] configuration.
[options="header",cols="1,6"] [options="header",cols="1,6"]
|======================= |=======================
|Field Name |Description |Field Name |Description
|`url` | |`url` |
The link:config-gerrit.html#gitweb.url[GitWeb base URL]. The link:config-gerrit.html#gitweb.url[gitweb base URL].
|`type` | |`type` |
The link:config-gerrit.html#gitweb.type[GitWeb type] as The link:config-gerrit.html#gitweb.type[gitweb type] as
link:#git-web-type-info[GitWebTypeInfo] entity. link:#git-web-type-info[GitwebTypeInfo] entity.
|======================= |=======================
[[git-web-type-info]] [[git-web-type-info]]
=== GitWebTypeInfo === GitwebTypeInfo
The `GitWebTypeInfo` entity contains information about the The `GitwebTypeInfo` entity contains information about the
link:config-gerrit.html#gitweb[GitWeb] configuration. link:config-gerrit.html#gitweb[gitweb] configuration.
[options="header",cols="1,^1,5"] [options="header",cols="1,^1,5"]
|============================= |=============================
|Field Name ||Description |Field Name ||Description
|`name` || |`name` ||
The link:config-gerrit.html#gitweb.linkname[GitWeb link name]. The link:config-gerrit.html#gitweb.linkname[gitweb link name].
|`revision` |optional| |`revision` |optional|
The link:config-gerrit.html#gitweb.revision[GitWeb revision pattern]. The link:config-gerrit.html#gitweb.revision[gitweb revision pattern].
|`project` |optional| |`project` |optional|
The link:config-gerrit.html#gitweb.project[GitWeb project pattern]. The link:config-gerrit.html#gitweb.project[gitweb project pattern].
|`branch` |optional| |`branch` |optional|
The link:config-gerrit.html#gitweb.branch[GitWeb branch pattern]. The link:config-gerrit.html#gitweb.branch[gitweb branch pattern].
|`root_tree` |optional| |`root_tree` |optional|
The link:config-gerrit.html#gitweb.roottree[GitWeb root tree pattern]. The link:config-gerrit.html#gitweb.roottree[gitweb root tree pattern].
|`file` |optional| |`file` |optional|
The link:config-gerrit.html#gitweb.file[GitWeb file pattern]. The link:config-gerrit.html#gitweb.file[gitweb file pattern].
|`file_history` |optional| |`file_history` |optional|
The link:config-gerrit.html#gitweb.filehistory[GitWeb file history The link:config-gerrit.html#gitweb.filehistory[gitweb file history
pattern]. pattern].
|`path_separator`|| |`path_separator`||
The link:config-gerrit.html#gitweb.pathSeparator[GitWeb path separator]. The link:config-gerrit.html#gitweb.pathSeparator[gitweb path separator].
|`link_drafts` |optional| |`link_drafts` |optional|
link:config-gerrit.html#gitweb.linkDrafts[Whether Gerrit should provide link:config-gerrit.html#gitweb.linkDrafts[Whether Gerrit should provide
links to GitWeb on draft patch set.] links to gitweb on draft patch set.]
|`url_encode` |optional| |`url_encode` |optional|
link:config-gerrit.html#gitweb.urlEncode[Whether Gerrit should encode link:config-gerrit.html#gitweb.urlEncode[Whether Gerrit should encode
the generated viewer URL.] the generated viewer URL.]
@ -1300,9 +1300,9 @@ information about Gerrit
Information about the configuration from the Information about the configuration from the
link:config-gerrit.html#gerrit[gerrit] section as link:#gerrit-info[ link:config-gerrit.html#gerrit[gerrit] section as link:#gerrit-info[
GerritInfo] entity. GerritInfo] entity.
|`git_web` |optional| |`gitweb ` |optional|
Information about the link:config-gerrit.html#gitweb[GitWeb] Information about the link:config-gerrit.html#gitweb[gitweb]
configuration as link:#git-web-info[GitWebInfo] entity. configuration as link:#git-web-info[GitwebInfo] entity.
|`sshd` |optional| |`sshd` |optional|
Information about the configuration from the Information about the configuration from the
link:config-gerrit.html#sshd[sshd] section as link:#sshd-info[SshdInfo] link:config-gerrit.html#sshd[sshd] section as link:#sshd-info[SshdInfo]

View File

@ -94,7 +94,7 @@ The commit ID, the parent commit(s) and the link:user-changeid.html[Change-Id] a
displayed with a copy-to-clipboard icon that allows the ID to be copied displayed with a copy-to-clipboard icon that allows the ID to be copied
into the clipboard. into the clipboard.
If a Git web browser, such as GitWeb or Gitiles, is configured, there If a Git web browser, such as gitweb or Gitiles, is configured, there
is also a link to the commit in the Git web browser. is also a link to the commit in the Git web browser.
image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"] image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"]

View File

@ -108,7 +108,7 @@ public class ServerInfoIT extends AbstractDaemonTest {
assertThat(i.gerrit.reportBugText).isEqualTo("REPORT BUG"); assertThat(i.gerrit.reportBugText).isEqualTo("REPORT BUG");
// gitweb // gitweb
assertThat(i.gitWeb).isNull(); assertThat(i.gitweb).isNull();
// sshd // sshd
assertThat(i.sshd).isNotNull(); assertThat(i.sshd).isNotNull();
@ -161,7 +161,7 @@ public class ServerInfoIT extends AbstractDaemonTest {
assertThat(i.gerrit.reportBugText).isNull(); assertThat(i.gerrit.reportBugText).isNull();
// gitweb // gitweb
assertThat(i.gitWeb).isNull(); assertThat(i.gitweb).isNull();
// sshd // sshd
assertThat(i.sshd).isNotNull(); assertThat(i.sshd).isNotNull();

View File

@ -1,275 +0,0 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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.google.gerrit.common.data;
/** Class to store information about different gitweb types. */
public class GitWebType {
/**
* Get a GitWebType based on the given name.
*
* @param name Name to look for.
* @return GitWebType from the given name, else null if not found.
*/
public static GitWebType fromName(final String name) {
final GitWebType type;
if (name == null || name.isEmpty() || name.equalsIgnoreCase("gitweb")) {
type = new GitWebType();
type.setLinkName("gitweb");
type.setProject("?p=${project}.git;a=summary");
type.setRevision("?p=${project}.git;a=commit;h=${commit}");
type.setBranch("?p=${project}.git;a=shortlog;h=${branch}");
type.setRootTree("?p=${project}.git;a=tree;hb=${commit}");
type.setFile("?p=${project}.git;hb=${commit};f=${file}");
type.setFileHistory("?p=${project}.git;a=history;hb=${branch};f=${file}");
} else if (name.equalsIgnoreCase("cgit")) {
type = new GitWebType();
type.setLinkName("cgit");
type.setProject("${project}.git/summary");
type.setRevision("${project}.git/commit/?id=${commit}");
type.setBranch("${project}.git/log/?h=${branch}");
type.setRootTree("${project}.git/tree/?h=${commit}");
type.setFile("${project}.git/tree/${file}?h=${commit}");
type.setFileHistory("${project}.git/log/${file}?h=${branch}");
} else if (name.equalsIgnoreCase("custom")) {
type = new GitWebType();
// The custom name is not defined, let's keep the old style of using GitWeb
type.setLinkName("gitweb");
} else {
type = null;
}
return type;
}
/** name of the type. */
private String name;
/** String for revision view url. */
private String revision;
/** ParameterizedString for project view url. */
private String project;
/** ParameterizedString for branch view url. */
private String branch;
/** ParameterizedString for root tree view url. */
private String rootTree;
/** ParameterizedString for file view url. */
private String file;
/** ParameterizedString for file history view url. */
private String fileHistory;
/** Character to substitute the standard path separator '/' in branch and
* project names */
private char pathSeparator = '/';
/** Whether to include links to draft patch sets */
private boolean linkDrafts;
/** Whether to encode URL segments */
private boolean urlEncode;
/** Private default constructor for gson. */
protected GitWebType() {
}
/**
* Get the String for branch view.
*
* @return The String for branch view
*/
public String getBranch() {
return branch;
}
/**
* Get the String for link-name of the type.
*
* @return The String for link-name of the type
*/
public String getLinkName() {
return name;
}
/**
* Get the String for project view.
*
* @return The String for project view
*/
public String getProject() {
return project;
}
/**
* Get the String for revision view.
*
* @return The String for revision view
*/
public String getRevision() {
return revision;
}
/**
* Get the String for root tree view.
*
* @return The String for root tree view
*/
public String getRootTree() {
return rootTree;
}
/**
* Get the String for file view.
*
* @return The String for file view
*/
public String getFile() {
return file;
}
/**
* Get the String for file history view.
*
* @return The String for file history view
*/
public String getFileHistory() {
return fileHistory;
}
/**
* Get whether to link to draft patch sets
*
* @return True to link
*/
public boolean getLinkDrafts() {
return linkDrafts;
}
/**
* Set the pattern for branch view.
*
* @param pattern The pattern for branch view
*/
public void setBranch(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
branch = pattern;
}
}
/**
* Set the pattern for link-name type.
*
* @param name The link-name type
*/
public void setLinkName(final String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
}
}
/**
* Set the pattern for project view.
*
* @param pattern The pattern for project view
*/
public void setProject(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
project = pattern;
}
}
/**
* Set the pattern for revision view.
*
* @param pattern The pattern for revision view
*/
public void setRevision(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
revision = pattern;
}
}
/**
* Set the pattern for root tree view.
*
* @param pattern The pattern for root tree view
*/
public void setRootTree(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
rootTree = pattern;
}
}
/**
* Set the pattern for file view.
*
* @param pattern The pattern for file view
*/
public void setFile(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
file = pattern;
}
}
/**
* Set the pattern for file history view.
*
* @param pattern The pattern for file history view
*/
public void setFileHistory(final String pattern) {
if (pattern != null && !pattern.isEmpty()) {
fileHistory = pattern;
}
}
/**
* Replace the standard path separator ('/') in a branch name or project
* name with a custom path separator configured by the property
* gitweb.pathSeparator.
* @param urlSegment The branch or project to replace the path separator in
* @return the urlSegment with the standard path separator replaced by the
* custom path separator
*/
public String replacePathSeparator(String urlSegment) {
if ('/' != pathSeparator) {
return urlSegment.replace('/', pathSeparator);
}
return urlSegment;
}
/**
* Set the custom path separator
* @param separator The custom path separator
*/
public void setPathSeparator(char separator) {
this.pathSeparator = separator;
}
public void setLinkDrafts(boolean linkDrafts) {
this.linkDrafts = linkDrafts;
}
public boolean isUrlEncode() {
return urlEncode;
}
public void setUrlEncode(boolean urlEncode) {
this.urlEncode = urlEncode;
}
}

View File

@ -0,0 +1,186 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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.google.gerrit.common.data;
/** Class to store information about different source browser types. */
public class GitwebType {
private String name;
private String branch;
private String file;
private String fileHistory;
private String project;
private String revision;
private String rootTree;
private char pathSeparator = '/';
private boolean linkDrafts = true;
private boolean urlEncode = true;
/** @return name displayed in links. */
public String getLinkName() {
return name;
}
/**
* Set the name displayed in links.
*
* @param name new name.
*/
public void setLinkName(String name) {
this.name = name;
}
/** @return parameterized string for the branch URL. */
public String getBranch() {
return branch;
}
/**
* Set the parameterized string for the branch URL.
*
* @param str new string.
*/
public void setBranch(String str) {
branch = str;
}
/** @return parameterized string for the file URL. */
public String getFile() {
return file;
}
/**
* Set the parameterized string for the file URL.
*
* @param str new string.
*/
public void setFile(String str) {
file = str;
}
/** @return parameterized string for the file history URL. */
public String getFileHistory() {
return fileHistory;
}
/**
* Set the parameterized string for the file history URL.
*
* @param str new string.
*/
public void setFileHistory(String str) {
fileHistory = str;
}
/** @return parameterized string for the project URL. */
public String getProject() {
return project;
}
/**
* Set the parameterized string for the project URL.
*
* @param str new string.
*/
public void setProject(String str) {
project = str;
}
/** @return parameterized string for the revision URL. */
public String getRevision() {
return revision;
}
/**
* Set the parameterized string for the revision URL.
*
* @param str new string.
*/
public void setRevision(String str) {
revision = str;
}
/** @return parameterized string for the root tree URL. */
public String getRootTree() {
return rootTree;
}
/**
* Set the parameterized string for the root tree URL.
*
* @param str new string.
*/
public void setRootTree(String str) {
rootTree = str;
}
/** @return path separator used for branch and project names. */
public char getPathSeparator() {
return pathSeparator;
}
/**
* Set the custom path separator.
*
* @param separator new separator.
*/
public void setPathSeparator(char separator) {
this.pathSeparator = separator;
}
/** @return whether to generate links to draft patch sets. */
public boolean getLinkDrafts() {
return linkDrafts;
}
/**
* Set whether to generate links to draft patch sets.
*
* @param linkDrafts new value.
*/
public void setLinkDrafts(boolean linkDrafts) {
this.linkDrafts = linkDrafts;
}
/** @return whether to URL encode path segments. */
public boolean getUrlEncode() {
return urlEncode;
}
/**
* Set whether to URL encode path segments.
*
* @param urlEncode new value.
*/
public void setUrlEncode(boolean urlEncode) {
this.urlEncode = urlEncode;
}
/**
* Replace standard path separator with custom configured path separator.
*
* @param urlSegment URL segment (e.g. branch or project name) in which to
* replace the path separator.
* @return the segment with the standard path separator replaced by the custom
* {@link #getPathSeparator()}.
*/
public String replacePathSeparator(String urlSegment) {
if ('/' != pathSeparator) {
return urlSegment.replace('/', pathSeparator);
}
return urlSegment;
}
}

View File

@ -19,22 +19,16 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test; import org.junit.Test;
public class EncodePathSeparatorTest { public class EncodePathSeparatorTest {
@Test @Test
public void testDefaultBehaviour() { public void testDefaultBehaviour() {
assertEquals("a/b", new GitwebType().replacePathSeparator("a/b"));
GitWebType gitWebType = GitWebType.fromName(null);
assertEquals("a/b", gitWebType.replacePathSeparator("a/b"));
} }
@Test @Test
public void testExclamationMark() { public void testExclamationMark() {
GitwebType gitwebType = new GitwebType();
GitWebType gitWebType = GitWebType.fromName(null); gitwebType.setPathSeparator('!');
gitWebType.setPathSeparator('!'); assertEquals("a!b", gitwebType.replacePathSeparator("a/b"));
assertEquals("a!b", gitWebType.replacePathSeparator("a/b"));
} }
} }

View File

@ -16,7 +16,7 @@ package com.google.gerrit.client.admin;
import com.google.gerrit.client.Dispatcher; import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.client.ui.Hyperlink; import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.ParentProjectBox; import com.google.gerrit.client.ui.ParentProjectBox;
import com.google.gerrit.common.data.AccessSection; import com.google.gerrit.common.data.AccessSection;
@ -121,7 +121,7 @@ public class ProjectAccessEditor extends Composite implements
inheritsFrom.getStyle().setDisplay(Display.NONE); inheritsFrom.getStyle().setDisplay(Display.NONE);
} }
GitWebInfo c = Gerrit.info().gitWeb(); GitwebInfo c = Gerrit.info().gitweb();
if (value.isConfigVisible() && c != null) { if (value.isConfigVisible() && c != null) {
history.getStyle().setDisplay(Display.BLOCK); history.getStyle().setDisplay(Display.BLOCK);
gitweb.setText(c.getLinkName()); gitweb.setText(c.getLinkName());

View File

@ -26,7 +26,7 @@ import com.google.gerrit.client.access.AccessMap;
import com.google.gerrit.client.access.ProjectAccessInfo; import com.google.gerrit.client.access.ProjectAccessInfo;
import com.google.gerrit.client.actions.ActionButton; import com.google.gerrit.client.actions.ActionButton;
import com.google.gerrit.client.actions.ActionInfo; import com.google.gerrit.client.actions.ActionInfo;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.client.projects.BranchInfo; import com.google.gerrit.client.projects.BranchInfo;
import com.google.gerrit.client.projects.ProjectApi; import com.google.gerrit.client.projects.ProjectApi;
import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.GerritCallback;
@ -457,7 +457,7 @@ public class ProjectBranchesScreen extends ProjectScreen {
} }
void populate(int row, BranchInfo k) { void populate(int row, BranchInfo k) {
GitWebInfo c = Gerrit.info().gitWeb(); GitwebInfo c = Gerrit.info().gitweb();
if (k.canDelete()) { if (k.canDelete()) {
CheckBox sel = new CheckBox(); CheckBox sel = new CheckBox();

View File

@ -19,7 +19,7 @@ import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
import com.google.gerrit.client.Dispatcher; import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.WebLinkInfo; import com.google.gerrit.client.WebLinkInfo;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.client.projects.ProjectInfo; import com.google.gerrit.client.projects.ProjectInfo;
import com.google.gerrit.client.projects.ProjectMap; import com.google.gerrit.client.projects.ProjectMap;
import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.GerritCallback;
@ -185,16 +185,16 @@ public class ProjectListScreen extends Screen {
} }
private void addWebLinks(int row, ProjectInfo k) { private void addWebLinks(int row, ProjectInfo k) {
GitWebInfo gitWebLink = Gerrit.info().gitWeb(); GitwebInfo gitwebLink = Gerrit.info().gitweb();
List<WebLinkInfo> webLinks = Natives.asList(k.webLinks()); List<WebLinkInfo> webLinks = Natives.asList(k.webLinks());
if (gitWebLink != null || (webLinks != null && !webLinks.isEmpty())) { if (gitwebLink != null || (webLinks != null && !webLinks.isEmpty())) {
FlowPanel p = new FlowPanel(); FlowPanel p = new FlowPanel();
table.setWidget(row, ProjectsTable.C_REPO_BROWSER, p); table.setWidget(row, ProjectsTable.C_REPO_BROWSER, p);
if (gitWebLink != null) { if (gitwebLink != null) {
Anchor a = new Anchor(); Anchor a = new Anchor();
a.setText(gitWebLink.getLinkName()); a.setText(gitwebLink.getLinkName());
a.setHref(gitWebLink.toProject(k.name_key())); a.setHref(gitwebLink.toProject(k.name_key()));
p.add(a); p.add(a);
} }
if (webLinks != null) { if (webLinks != null) {

View File

@ -23,7 +23,7 @@ import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo; import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
import com.google.gerrit.client.changes.ChangeInfo.GitPerson; import com.google.gerrit.client.changes.ChangeInfo.GitPerson;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo; import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.client.rpc.Natives; import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.CommentLinkProcessor; import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.InlineHyperlink; import com.google.gerrit.client.ui.InlineHyperlink;
@ -135,7 +135,7 @@ class CommitBox extends Composite {
private void setWebLinks(ChangeInfo change, String revision, private void setWebLinks(ChangeInfo change, String revision,
RevisionInfo revInfo) { RevisionInfo revInfo) {
GitWebInfo gw = Gerrit.info().gitWeb(); GitwebInfo gw = Gerrit.info().gitweb();
if (gw != null && gw.canLink(revInfo)) { if (gw != null && gw.canLink(revInfo)) {
toAnchor(gw.toRevision(change.project(), revision), toAnchor(gw.toRevision(change.project(), revision),
gw.getLinkName()); gw.getLinkName());
@ -184,7 +184,7 @@ class CommitBox extends Composite {
} }
private void addLinks(String project, CommitInfo c, FlowPanel panel) { private void addLinks(String project, CommitInfo c, FlowPanel panel) {
GitWebInfo gw = Gerrit.info().gitWeb(); GitwebInfo gw = Gerrit.info().gitweb();
if (gw != null) { if (gw != null) {
Anchor a = Anchor a =
new Anchor(gw.getLinkName(), gw.toRevision(project, c.commit())); new Anchor(gw.getLinkName(), gw.toRevision(project, c.commit()));

View File

@ -18,7 +18,7 @@ import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit; import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit;
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo; import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
import com.google.gerrit.client.changes.Util; import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.common.PageLinks; import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
@ -301,7 +301,7 @@ class RelatedChangesTab implements IsWidget {
sb.closeSpan(); sb.closeSpan();
sb.openSpan(); sb.openSpan();
GitWebInfo gw = Gerrit.info().gitWeb(); GitwebInfo gw = Gerrit.info().gitweb();
if (gw != null && (!info.hasChangeNumber() || !info.hasRevisionNumber())) { if (gw != null && (!info.hasChangeNumber() || !info.hasRevisionNumber())) {
sb.setStyleName(RelatedChanges.R.css().gitweb()); sb.setStyleName(RelatedChanges.R.css().gitweb());
sb.setAttribute("title", gw.getLinkName()); sb.setAttribute("title", gw.getLinkName());
@ -335,7 +335,7 @@ class RelatedChangesTab implements IsWidget {
id.getId()); id.getId());
} }
GitWebInfo gw = Gerrit.info().gitWeb(); GitwebInfo gw = Gerrit.info().gitweb();
if (gw != null && project != null) { if (gw != null && project != null) {
return gw.toRevision(project, info.commit().commit()); return gw.toRevision(project, info.commit().commit());
} }

View File

@ -25,9 +25,9 @@ import com.google.gwt.http.client.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class GitWebInfo extends JavaScriptObject { public class GitwebInfo extends JavaScriptObject {
public final native String url() /*-{ return this.url; }-*/; public final native String url() /*-{ return this.url; }-*/;
public final native GitWebTypeInfo type() /*-{ return this.type; }-*/; public final native GitwebTypeInfo type() /*-{ return this.type; }-*/;
/** /**
* Checks whether the given patch set can be linked. * Checks whether the given patch set can be linked.
@ -56,20 +56,20 @@ public class GitWebInfo extends JavaScriptObject {
} }
/** /**
* Returns the name for GitWeb links. * Returns the name for gitweb links.
* *
* @return the name for GitWeb links * @return the name for gitweb links
*/ */
public final String getLinkName() { public final String getLinkName() {
return "(" + type().name() + ")"; return "(" + type().name() + ")";
} }
/** /**
* Returns the GitWeb link to a revision. * Returns the gitweb link to a revision.
* *
* @param project the name of the project * @param project the name of the project
* @param commit the commit ID * @param commit the commit ID
* @return GitWeb link to a revision * @return gitweb link to a revision
*/ */
public final String toRevision(String project, String commit) { public final String toRevision(String project, String commit) {
ParameterizedString pattern = new ParameterizedString(type().revision()); ParameterizedString pattern = new ParameterizedString(type().revision());
@ -80,21 +80,21 @@ public class GitWebInfo extends JavaScriptObject {
} }
/** /**
* Returns the GitWeb link to a revision. * Returns the gitweb link to a revision.
* *
* @param project the name of the project * @param project the name of the project
* @param ps the patch set * @param ps the patch set
* @return GitWeb link to a revision * @return gitweb link to a revision
*/ */
public final String toRevision(Project.NameKey project, PatchSet ps) { public final String toRevision(Project.NameKey project, PatchSet ps) {
return toRevision(project.get(), ps.getRevision().get()); return toRevision(project.get(), ps.getRevision().get());
} }
/** /**
* Returns the GitWeb link to a project. * Returns the gitweb link to a project.
* *
* @param project the project name key * @param project the project name key
* @return GitWeb link to a project * @return gitweb link to a project
*/ */
public final String toProject(Project.NameKey project) { public final String toProject(Project.NameKey project) {
ParameterizedString pattern = new ParameterizedString(type().project()); ParameterizedString pattern = new ParameterizedString(type().project());
@ -105,10 +105,10 @@ public class GitWebInfo extends JavaScriptObject {
} }
/** /**
* Returns the GitWeb link to a branch. * Returns the gitweb link to a branch.
* *
* @param branch the branch name key * @param branch the branch name key
* @return GitWeb link to a branch * @return gitweb link to a branch
*/ */
public final String toBranch(Branch.NameKey branch) { public final String toBranch(Branch.NameKey branch) {
ParameterizedString pattern = new ParameterizedString(type().branch()); ParameterizedString pattern = new ParameterizedString(type().branch());
@ -120,12 +120,12 @@ public class GitWebInfo extends JavaScriptObject {
} }
/** /**
* Returns the GitWeb link to a file. * Returns the gitweb link to a file.
* *
* @param project the branch name key * @param project the branch name key
* @param commit the commit ID * @param commit the commit ID
* @param file the path of the file * @param file the path of the file
* @return GitWeb link to a file * @return gitweb link to a file
*/ */
public final String toFile(String project, String commit, String file) { public final String toFile(String project, String commit, String file) {
Map<String, String> p = new HashMap<>(); Map<String, String> p = new HashMap<>();
@ -140,11 +140,11 @@ public class GitWebInfo extends JavaScriptObject {
} }
/** /**
* Returns the GitWeb link to a file history. * Returns the gitweb link to a file history.
* *
* @param branch the branch name key * @param branch the branch name key
* @param file the path of the file * @param file the path of the file
* @return GitWeb link to a file history * @return gitweb link to a file history
*/ */
public final String toFileHistory(Branch.NameKey branch, String file) { public final String toFileHistory(Branch.NameKey branch, String file) {
ParameterizedString pattern = new ParameterizedString(type().fileHistory()); ParameterizedString pattern = new ParameterizedString(type().fileHistory());
@ -164,6 +164,6 @@ public class GitWebInfo extends JavaScriptObject {
} }
} }
protected GitWebInfo() { protected GitwebInfo() {
} }
} }

View File

@ -16,7 +16,7 @@ package com.google.gerrit.client.config;
import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
public class GitWebTypeInfo extends JavaScriptObject { public class GitwebTypeInfo extends JavaScriptObject {
/** /**
* Replace the standard path separator ('/') in a branch name or project * Replace the standard path separator ('/') in a branch name or project
* name with a custom path separator configured by the property * name with a custom path separator configured by the property
@ -43,6 +43,6 @@ public class GitWebTypeInfo extends JavaScriptObject {
public final native boolean linkDrafts() /*-{ return this.link_drafts || false; }-*/; public final native boolean linkDrafts() /*-{ return this.link_drafts || false; }-*/;
public final native boolean urlEncode() /*-{ return this.url_encode || false; }-*/; public final native boolean urlEncode() /*-{ return this.url_encode || false; }-*/;
protected GitWebTypeInfo() { protected GitwebTypeInfo() {
} }
} }

View File

@ -22,7 +22,7 @@ public class ServerInfo extends JavaScriptObject {
public final native ContactStoreInfo contactStore() /*-{ return this.contact_store; }-*/; public final native ContactStoreInfo contactStore() /*-{ return this.contact_store; }-*/;
public final native DownloadInfo download() /*-{ return this.download; }-*/; public final native DownloadInfo download() /*-{ return this.download; }-*/;
public final native GerritInfo gerrit() /*-{ return this.gerrit; }-*/; public final native GerritInfo gerrit() /*-{ return this.gerrit; }-*/;
public final native GitWebInfo gitWeb() /*-{ return this.git_web; }-*/; public final native GitwebInfo gitweb() /*-{ return this.gitweb; }-*/;
public final native SshdInfo sshd() /*-{ return this.sshd; }-*/; public final native SshdInfo sshd() /*-{ return this.sshd; }-*/;
public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/; public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/;
public final native UserConfigInfo user() /*-{ return this.user; }-*/; public final native UserConfigInfo user() /*-{ return this.user; }-*/;

View File

@ -22,7 +22,7 @@ import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo; import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.changes.ReviewInfo; import com.google.gerrit.client.changes.ReviewInfo;
import com.google.gerrit.client.changes.Util; import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.config.GitWebInfo; import com.google.gerrit.client.config.GitwebInfo;
import com.google.gerrit.client.diff.DiffInfo.Region; import com.google.gerrit.client.diff.DiffInfo.Region;
import com.google.gerrit.client.patches.PatchUtil; import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.CallbackGroup; import com.google.gerrit.client.rpc.CallbackGroup;
@ -115,8 +115,8 @@ public class Header extends Composite {
return b.append(Util.C.commitMessage()); return b.append(Util.C.commitMessage());
} }
GitWebInfo gw = (project != null && commit != null) GitwebInfo gw = (project != null && commit != null)
? Gerrit.info().gitWeb() : null; ? Gerrit.info().gitweb() : null;
int s = path.lastIndexOf('/') + 1; int s = path.lastIndexOf('/') + 1;
if (gw != null && s > 0) { if (gw != null && s > 0) {
String base = path.substring(0, s - 1); String base = path.substring(0, s - 1);
@ -193,7 +193,7 @@ public class Header extends Composite {
} }
void setChangeInfo(ChangeInfo info) { void setChangeInfo(ChangeInfo info) {
GitWebInfo gw = Gerrit.info().gitWeb(); GitwebInfo gw = Gerrit.info().gitweb();
if (gw != null) { if (gw != null) {
for (RevisionInfo rev : Natives.asList(info.revisions().values())) { for (RevisionInfo rev : Natives.asList(info.revisions().values())) {
if (patchSetId.getId().equals(rev.id())) { if (patchSetId.getId().equals(rev.id())) {

View File

@ -23,14 +23,14 @@ import com.google.gerrit.httpd.auth.become.BecomeAnyAccountModule;
import com.google.gerrit.httpd.auth.container.HttpAuthModule; import com.google.gerrit.httpd.auth.container.HttpAuthModule;
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule; import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
import com.google.gerrit.httpd.auth.ldap.LdapAuthModule; import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
import com.google.gerrit.httpd.gitweb.GitWebModule; import com.google.gerrit.httpd.gitweb.GitwebModule;
import com.google.gerrit.httpd.rpc.UiRpcModule; import com.google.gerrit.httpd.rpc.UiRpcModule;
import com.google.gerrit.lifecycle.LifecycleModule; import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.RemotePeer; import com.google.gerrit.server.RemotePeer;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritRequestModule; import com.google.gerrit.server.config.GerritRequestModule;
import com.google.gerrit.server.config.GitWebConfig; import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gerrit.server.git.AsyncReceiveCommits; import com.google.gerrit.server.git.AsyncReceiveCommits;
import com.google.gerrit.server.util.GuiceRequestScopePropagator; import com.google.gerrit.server.util.GuiceRequestScopePropagator;
import com.google.gerrit.server.util.RequestScopePropagator; import com.google.gerrit.server.util.RequestScopePropagator;
@ -43,18 +43,18 @@ import java.net.SocketAddress;
public class WebModule extends LifecycleModule { public class WebModule extends LifecycleModule {
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final boolean wantSSL; private final boolean wantSSL;
private final GitWebConfig gitWebConfig; private final GitwebCgiConfig gitwebCgiConfig;
private final GerritOptions options; private final GerritOptions options;
@Inject @Inject
WebModule(AuthConfig authConfig, WebModule(AuthConfig authConfig,
@CanonicalWebUrl @Nullable String canonicalUrl, @CanonicalWebUrl @Nullable String canonicalUrl,
GerritOptions options, GerritOptions options,
GitWebConfig gitWebConfig) { GitwebCgiConfig gitwebCgiConfig) {
this.authConfig = authConfig; this.authConfig = authConfig;
this.wantSSL = canonicalUrl != null && canonicalUrl.startsWith("https:"); this.wantSSL = canonicalUrl != null && canonicalUrl.startsWith("https:");
this.options = options; this.options = options;
this.gitWebConfig = gitWebConfig; this.gitwebCgiConfig = gitwebCgiConfig;
} }
@Override @Override
@ -75,8 +75,8 @@ public class WebModule extends LifecycleModule {
install(new GerritRequestModule()); install(new GerritRequestModule());
install(new GitOverHttpServlet.Module(options.enableMasterFeatures())); install(new GitOverHttpServlet.Module(options.enableMasterFeatures()));
if (gitWebConfig.getGitwebCGI() != null) { if (gitwebCgiConfig.getGitwebCgi() != null) {
install(new GitWebModule()); install(new GitwebModule());
} }
DynamicSet.setOf(binder(), WebUiPlugin.class); DynamicSet.setOf(binder(), WebUiPlugin.class);

View File

@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
import static com.google.gerrit.common.FileUtil.lastModified; import static com.google.gerrit.common.FileUtil.lastModified;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.google.gerrit.server.config.GitWebConfig; import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gwtexpui.server.CacheHeaders; import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -41,9 +41,9 @@ class GitLogoServlet extends HttpServlet {
private final byte[] raw; private final byte[] raw;
@Inject @Inject
GitLogoServlet(GitWebConfig gitWebConfig) throws IOException { GitLogoServlet(GitwebCgiConfig cfg) throws IOException {
byte[] png; byte[] png;
Path src = gitWebConfig.getGitLogoPNG(); Path src = cfg.getGitLogoPng();
if (src != null) { if (src != null) {
try (InputStream in = Files.newInputStream(src)) { try (InputStream in = Files.newInputStream(src)) {
png = ByteStreams.toByteArray(in); png = ByteStreams.toByteArray(in);

View File

@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
import static com.google.gerrit.common.FileUtil.lastModified; import static com.google.gerrit.common.FileUtil.lastModified;
import com.google.gerrit.httpd.HtmlDomUtil; import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.server.config.GitWebConfig; import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gwtexpui.server.CacheHeaders; import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils; import com.google.gwtjsonrpc.server.RPCServletUtils;
@ -34,9 +34,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial") @SuppressWarnings("serial")
abstract class GitWebCssServlet extends HttpServlet { abstract class GitwebCssServlet extends HttpServlet {
@Singleton @Singleton
static class Site extends GitWebCssServlet { static class Site extends GitwebCssServlet {
@Inject @Inject
Site(SitePaths paths) throws IOException { Site(SitePaths paths) throws IOException {
super(paths.site_css); super(paths.site_css);
@ -44,10 +44,10 @@ abstract class GitWebCssServlet extends HttpServlet {
} }
@Singleton @Singleton
static class Default extends GitWebCssServlet { static class Default extends GitwebCssServlet {
@Inject @Inject
Default(GitWebConfig gwc) throws IOException { Default(GitwebCgiConfig gwcc) throws IOException {
super(gwc.getGitwebCSS()); super(gwcc.getGitwebCss());
} }
} }
@ -57,7 +57,7 @@ abstract class GitWebCssServlet extends HttpServlet {
private final byte[] raw_css; private final byte[] raw_css;
private final byte[] gz_css; private final byte[] gz_css;
GitWebCssServlet(final Path src) GitwebCssServlet(final Path src)
throws IOException { throws IOException {
if (src != null) { if (src != null) {
final Path dir = src.getParent(); final Path dir = src.getParent();

View File

@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
import static com.google.gerrit.common.FileUtil.lastModified; import static com.google.gerrit.common.FileUtil.lastModified;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.google.gerrit.server.config.GitWebConfig; import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gwtexpui.server.CacheHeaders; import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -36,14 +36,14 @@ import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Singleton @Singleton
class GitWebJavaScriptServlet extends HttpServlet { class GitwebJavaScriptServlet extends HttpServlet {
private final long modified; private final long modified;
private final byte[] raw; private final byte[] raw;
@Inject @Inject
GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException { GitwebJavaScriptServlet(GitwebCgiConfig gitwebCgiConfig) throws IOException {
byte[] png; byte[] png;
Path src = gitWebConfig.getGitwebJS(); Path src = gitwebCgiConfig.getGitwebJs();
if (src != null) { if (src != null) {
try (InputStream in = Files.newInputStream(src)) { try (InputStream in = Files.newInputStream(src)) {
png = ByteStreams.toByteArray(in); png = ByteStreams.toByteArray(in);

View File

@ -16,13 +16,13 @@ package com.google.gerrit.httpd.gitweb;
import com.google.inject.servlet.ServletModule; import com.google.inject.servlet.ServletModule;
public class GitWebModule extends ServletModule { public class GitwebModule extends ServletModule {
@Override @Override
protected void configureServlets() { protected void configureServlets() {
serve("/gitweb").with(GitWebServlet.class); serve("/gitweb").with(GitwebServlet.class);
serve("/gitweb-logo.png").with(GitLogoServlet.class); serve("/gitweb-logo.png").with(GitLogoServlet.class);
serve("/gitweb.js").with(GitWebJavaScriptServlet.class); serve("/gitweb.js").with(GitwebJavaScriptServlet.class);
serve("/gitweb-default.css").with(GitWebCssServlet.Default.class); serve("/gitweb-default.css").with(GitwebCssServlet.Default.class);
serve("/gitweb-site.css").with(GitWebCssServlet.Site.class); serve("/gitweb-site.css").with(GitwebCssServlet.Site.class);
} }
} }

View File

@ -38,7 +38,8 @@ import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GitWebConfig; import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gerrit.server.config.GitwebConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.LocalDiskRepositoryManager; import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
@ -81,9 +82,9 @@ import javax.servlet.http.HttpServletResponse;
/** Invokes {@code gitweb.cgi} for the project given in {@code p}. */ /** Invokes {@code gitweb.cgi} for the project given in {@code p}. */
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Singleton @Singleton
class GitWebServlet extends HttpServlet { class GitwebServlet extends HttpServlet {
private static final Logger log = private static final Logger log =
LoggerFactory.getLogger(GitWebServlet.class); LoggerFactory.getLogger(GitwebServlet.class);
private static final String PROJECT_LIST_ACTION = "project_list"; private static final String PROJECT_LIST_ACTION = "project_list";
@ -98,23 +99,24 @@ class GitWebServlet extends HttpServlet {
private final EnvList _env; private final EnvList _env;
@Inject @Inject
GitWebServlet(LocalDiskRepositoryManager repoManager, GitwebServlet(LocalDiskRepositoryManager repoManager,
ProjectControl.Factory projectControl, ProjectControl.Factory projectControl,
Provider<AnonymousUser> anonymousUserProvider, Provider<AnonymousUser> anonymousUserProvider,
Provider<CurrentUser> userProvider, Provider<CurrentUser> userProvider,
SitePaths site, SitePaths site,
@GerritServerConfig Config cfg, @GerritServerConfig Config cfg,
SshInfo sshInfo, SshInfo sshInfo,
GitWebConfig gitWebConfig) GitwebConfig gitwebConfig,
GitwebCgiConfig gitwebCgiConfig)
throws IOException { throws IOException {
this.repoManager = repoManager; this.repoManager = repoManager;
this.projectControl = projectControl; this.projectControl = projectControl;
this.anonymousUserProvider = anonymousUserProvider; this.anonymousUserProvider = anonymousUserProvider;
this.userProvider = userProvider; this.userProvider = userProvider;
this.gitwebCgi = gitWebConfig.getGitwebCGI(); this.gitwebCgi = gitwebCgiConfig.getGitwebCgi();
this.deniedActions = new HashSet<>(); this.deniedActions = new HashSet<>();
final String url = gitWebConfig.getUrl(); final String url = gitwebConfig.getUrl();
if ((url != null) && (!url.equals("gitweb"))) { if ((url != null) && (!url.equals("gitweb"))) {
URI uri = null; URI uri = null;
try { try {
@ -267,7 +269,7 @@ class GitWebServlet extends HttpServlet {
} }
// Link back to Gerrit (when possible, to matching review record). // Link back to Gerrit (when possible, to matching review record).
// Supported Gitweb's hash values are: // Supported gitweb's hash values are:
// - (missing), // - (missing),
// - HEAD, // - HEAD,
// - refs/heads/<branch>, // - refs/heads/<branch>,
@ -577,7 +579,7 @@ class GitWebServlet extends HttpServlet {
env.set("REMOTE_USER", remoteUser); env.set("REMOTE_USER", remoteUser);
// Override CGI settings using alternative URI provided by gitweb.url. // Override CGI settings using alternative URI provided by gitweb.url.
// This is required to trick Gitweb into thinking that it's served under // This is required to trick gitweb into thinking that it's served under
// different URL. Setting just $my_uri on the perl's side isn't enough, // different URL. Setting just $my_uri on the perl's side isn't enough,
// because few actions (atom, blobdiff_plain, commitdiff_plain) rely on // because few actions (atom, blobdiff_plain, commitdiff_plain) rely on
// URL returned by $cgi->self_url(). // URL returned by $cgi->self_url().
@ -642,7 +644,7 @@ class GitWebServlet extends HttpServlet {
log.debug("Unexpected error copying input to CGI", e); log.debug("Unexpected error copying input to CGI", e);
} }
} }
}, "GitWeb-InputFeeder").start(); }, "Gitweb-InputFeeder").start();
} }
private void copyStderrToLog(final InputStream in) { private void copyStderrToLog(final InputStream in) {
@ -664,7 +666,7 @@ class GitWebServlet extends HttpServlet {
log.debug("Unexpected error copying stderr from CGI", e); log.debug("Unexpected error copying stderr from CGI", e);
} }
} }
}, "GitWeb-ErrorLogger").start(); }, "Gitweb-ErrorLogger").start();
} }
private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) { private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) {

View File

@ -216,7 +216,7 @@ public class GerritGlobalModule extends FactoryModule {
bind(ToolsCatalog.class); bind(ToolsCatalog.class);
bind(EventFactory.class); bind(EventFactory.class);
bind(TransferConfig.class); bind(TransferConfig.class);
bind(GitWebConfig.class); bind(GitwebConfig.class);
bind(GcConfig.class); bind(GcConfig.class);

View File

@ -18,7 +18,7 @@ import com.google.common.base.Function;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GitWebType; import com.google.gerrit.common.data.GitwebType;
import com.google.gerrit.extensions.config.CloneCommand; import com.google.gerrit.extensions.config.CloneCommand;
import com.google.gerrit.extensions.config.DownloadCommand; import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme; import com.google.gerrit.extensions.config.DownloadScheme;
@ -51,7 +51,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
private final AllProjectsName allProjectsName; private final AllProjectsName allProjectsName;
private final AllUsersName allUsersName; private final AllUsersName allUsersName;
private final String anonymousCowardName; private final String anonymousCowardName;
private final GitWebConfig gitWebConfig; private final GitwebConfig gitwebConfig;
@Inject @Inject
public GetServerInfo( public GetServerInfo(
@ -65,7 +65,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
AllProjectsName allProjectsName, AllProjectsName allProjectsName,
AllUsersName allUsersName, AllUsersName allUsersName,
@AnonymousCowardName String anonymousCowardName, @AnonymousCowardName String anonymousCowardName,
GitWebConfig gitWebConfig) { GitwebConfig gitwebConfig) {
this.config = config; this.config = config;
this.authConfig = authConfig; this.authConfig = authConfig;
this.realm = realm; this.realm = realm;
@ -76,7 +76,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
this.allProjectsName = allProjectsName; this.allProjectsName = allProjectsName;
this.allUsersName = allUsersName; this.allUsersName = allUsersName;
this.anonymousCowardName = anonymousCowardName; this.anonymousCowardName = anonymousCowardName;
this.gitWebConfig = gitWebConfig; this.gitwebConfig = gitwebConfig;
} }
@Override @Override
@ -89,7 +89,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
getDownloadInfo(downloadSchemes, downloadCommands, cloneCommands, getDownloadInfo(downloadSchemes, downloadCommands, cloneCommands,
archiveFormats); archiveFormats);
info.gerrit = getGerritInfo(config, allProjectsName, allUsersName); info.gerrit = getGerritInfo(config, allProjectsName, allUsersName);
info.gitWeb = getGitWebInfo(gitWebConfig); info.gitweb = getGitwebInfo(gitwebConfig);
info.sshd = getSshdInfo(config); info.sshd = getSshdInfo(config);
info.suggest = getSuggestInfo(config); info.suggest = getSuggestInfo(config);
info.user = getUserInfo(anonymousCowardName); info.user = getUserInfo(anonymousCowardName);
@ -227,14 +227,14 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
return info; return info;
} }
private GitWebInfo getGitWebInfo(GitWebConfig cfg) { private GitwebInfo getGitwebInfo(GitwebConfig cfg) {
if (cfg.getUrl() == null || cfg.getGitWebType() == null) { if (cfg.getUrl() == null || cfg.getGitwebType() == null) {
return null; return null;
} }
GitWebInfo info = new GitWebInfo(); GitwebInfo info = new GitwebInfo();
info.url = cfg.getUrl(); info.url = cfg.getUrl();
info.type = cfg.getGitWebType(); info.type = cfg.getGitwebType();
return info; return info;
} }
@ -274,7 +274,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
public ContactStoreInfo contactStore; public ContactStoreInfo contactStore;
public DownloadInfo download; public DownloadInfo download;
public GerritInfo gerrit; public GerritInfo gerrit;
public GitWebInfo gitWeb; public GitwebInfo gitweb;
public SshdInfo sshd; public SshdInfo sshd;
public SuggestInfo suggest; public SuggestInfo suggest;
public UserConfigInfo user; public UserConfigInfo user;
@ -326,9 +326,9 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
public String reportBugText; public String reportBugText;
} }
public static class GitWebInfo { public static class GitwebInfo {
public String url; public String url;
public GitWebType type; public GitwebType type;
} }
public static class SshdInfo { public static class SshdInfo {

View File

@ -1,243 +0,0 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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.google.gerrit.server.config;
import static java.nio.file.Files.isExecutable;
import static java.nio.file.Files.isRegularFile;
import com.google.gerrit.common.data.GitWebType;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
public class GitWebConfig {
private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class);
private final String url;
private final Path gitweb_cgi;
private final Path gitweb_css;
private final Path gitweb_js;
private final Path git_logo_png;
private GitWebType type;
@Inject
GitWebConfig(final SitePaths sitePaths, @GerritServerConfig final Config cfg) {
final String cfgUrl = cfg.getString("gitweb", null, "url");
final String cfgCgi = cfg.getString("gitweb", null, "cgi");
type = GitWebType.fromName(cfg.getString("gitweb", null, "type"));
if (type == null) {
url = null;
gitweb_cgi = null;
gitweb_css = null;
gitweb_js = null;
git_logo_png = null;
return;
}
type.setLinkName(cfg.getString("gitweb", null, "linkname"));
type.setBranch(cfg.getString("gitweb", null, "branch"));
type.setProject(cfg.getString("gitweb", null, "project"));
type.setRevision(cfg.getString("gitweb", null, "revision"));
type.setRootTree(cfg.getString("gitweb", null, "roottree"));
type.setFile(cfg.getString("gitweb", null, "file"));
type.setFileHistory(cfg.getString("gitweb", null, "filehistory"));
type.setLinkDrafts(cfg.getBoolean("gitweb", null, "linkdrafts", true));
type.setUrlEncode(cfg.getBoolean("gitweb", null, "urlencode", true));
String pathSeparator = cfg.getString("gitweb", null, "pathSeparator");
if (pathSeparator != null) {
if (pathSeparator.length() == 1) {
char c = pathSeparator.charAt(0);
if (isValidPathSeparator(c)) {
type.setPathSeparator(c);
} else {
log.warn("Invalid value specified for gitweb.pathSeparator: " + c);
}
} else {
log.warn("Value specified for gitweb.pathSeparator is not a single character:" + pathSeparator);
}
}
if (type.getBranch() == null) {
log.warn("No Pattern specified for gitweb.branch, disabling.");
type = null;
} else if (type.getProject() == null) {
log.warn("No Pattern specified for gitweb.project, disabling.");
type = null;
} else if (type.getRevision() == null) {
log.warn("No Pattern specified for gitweb.revision, disabling.");
type = null;
} else if (type.getRootTree() == null) {
log.warn("No Pattern specified for gitweb.roottree, disabling.");
type = null;
} else if (type.getFile() == null) {
log.warn("No Pattern specified for gitweb.file, disabling.");
type = null;
} else if (type.getFileHistory() == null) {
log.warn("No Pattern specified for gitweb.filehistory, disabling.");
type = null;
}
if ((cfgUrl != null && cfgUrl.isEmpty())
|| (cfgCgi != null && cfgCgi.isEmpty())) {
// Either setting was explicitly set to the empty string disabling
// gitweb for this server. Disable the configuration.
//
url = null;
gitweb_cgi = null;
gitweb_css = null;
gitweb_js = null;
git_logo_png = null;
return;
}
if ((cfgUrl != null) && (cfgCgi == null || cfgCgi.isEmpty())) {
// Use an externally managed gitweb instance, and not an internal one.
//
url = cfgUrl;
gitweb_cgi = null;
gitweb_css = null;
gitweb_js = null;
git_logo_png = null;
return;
}
final Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
"/var/www/static", "/var/www"};
Path cgi;
if (cfgCgi != null) {
// Use the CGI script configured by the administrator, failing if it
// cannot be used as specified.
//
cgi = sitePaths.resolve(cfgCgi);
if (!isRegularFile(cgi)) {
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
}
if (!isExecutable(cgi)) {
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
}
if (!cgi.equals(pkgCgi)) {
// Assume the administrator pointed us to the distribution,
// which also has the corresponding CSS and logo file.
//
String absPath = cgi.getParent().toAbsolutePath().toString();
resourcePaths = new String[] {absPath + "/static", absPath};
}
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
// Use the OS packaged CGI.
//
log.debug("Assuming gitweb at " + pkgCgi);
cgi = pkgCgi;
} else {
log.warn("gitweb not installed (no " + pkgCgi + " found)");
cgi = null;
resourcePaths = new String[] {};
}
Path css = null;
Path js = null;
Path logo = null;
for (String path : resourcePaths) {
Path dir = Paths.get(path);
css = dir.resolve("gitweb.css");
js = dir.resolve("gitweb.js");
logo = dir.resolve("git-logo.png");
if (isRegularFile(css) && isRegularFile(logo)) {
break;
}
}
if (cfgUrl == null || cfgUrl.isEmpty()) {
url = cgi != null ? "gitweb" : null;
} else {
url = cgi != null ? cfgUrl : null;
}
gitweb_cgi = cgi;
gitweb_css = css;
gitweb_js = js;
git_logo_png = logo;
}
/** @return GitWebType for gitweb viewer. */
public GitWebType getGitWebType() {
return type;
}
/**
* @return URL of the entry point into gitweb. This URL may be relative to our
* context if gitweb is hosted by ourselves; or absolute if its hosted
* elsewhere; or null if gitweb has not been configured.
*/
public String getUrl() {
return url;
}
/** @return local path to the CGI executable; null if we shouldn't execute. */
public Path getGitwebCGI() {
return gitweb_cgi;
}
/** @return local path of the {@code gitweb.css} matching the CGI. */
public Path getGitwebCSS() {
return gitweb_css;
}
/** @return local path of the {@code gitweb.js} for the CGI. */
public Path getGitwebJS() {
return gitweb_js;
}
/** @return local path of the {@code git-logo.png} for the CGI. */
public Path getGitLogoPNG() {
return git_logo_png;
}
/**
* Determines if a given character can be used unencoded in an URL as a
* replacement for the path separator '/'.
*
* Reasoning: http://www.ietf.org/rfc/rfc1738.txt § 2.2:
*
* ... only alphanumerics, the special characters "$-_.+!*'(),", and
* reserved characters used for their reserved purposes may be used
* unencoded within a URL.
*
* The following characters might occur in file names, however:
*
* alphanumeric characters,
*
* "$-_.+!',"
*/
static boolean isValidPathSeparator(char c) {
switch (c) {
case '*':
case '(':
case ')':
return true;
default:
return false;
}
}
}

View File

@ -0,0 +1,137 @@
// Copyright (C) 2015 The Android Open Source Project
//
// 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.google.gerrit.server.config;
import static java.nio.file.Files.isExecutable;
import static java.nio.file.Files.isRegularFile;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
@Singleton
public class GitwebCgiConfig {
private static final Logger log =
LoggerFactory.getLogger(GitwebCgiConfig.class);
public GitwebCgiConfig disabled() {
return new GitwebCgiConfig();
}
private final Path cgi;
private final Path css;
private final Path js;
private final Path logoPng;
@Inject
GitwebCgiConfig(SitePaths sitePaths, @GerritServerConfig Config cfg) {
if (GitwebConfig.isDisabled(cfg)) {
cgi = null;
css = null;
js = null;
logoPng = null;
return;
}
String cfgCgi = cfg.getString("gitweb", null, "cgi");
Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
"/var/www/static", "/var/www"};
Path cgi;
if (cfgCgi != null) {
// Use the CGI script configured by the administrator, failing if it
// cannot be used as specified.
//
cgi = sitePaths.resolve(cfgCgi);
if (!isRegularFile(cgi)) {
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
}
if (!isExecutable(cgi)) {
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
}
if (!cgi.equals(pkgCgi)) {
// Assume the administrator pointed us to the distribution,
// which also has the corresponding CSS and logo file.
//
String absPath = cgi.getParent().toAbsolutePath().toString();
resourcePaths = new String[] {absPath + "/static", absPath};
}
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
// Use the OS packaged CGI.
//
log.debug("Assuming gitweb at " + pkgCgi);
cgi = pkgCgi;
} else {
log.warn("gitweb not installed (no " + pkgCgi + " found)");
cgi = null;
resourcePaths = new String[] {};
}
Path css = null;
Path js = null;
Path logo = null;
for (String path : resourcePaths) {
Path dir = Paths.get(path);
css = dir.resolve("gitweb.css");
js = dir.resolve("gitweb.js");
logo = dir.resolve("git-logo.png");
if (isRegularFile(css) && isRegularFile(logo)) {
break;
}
}
this.cgi = cgi;
this.css = css;
this.js = js;
this.logoPng = logo;
}
private GitwebCgiConfig() {
this.cgi = null;
this.css = null;
this.js = null;
this.logoPng = null;
}
/** @return local path to the CGI executable; null if we shouldn't execute. */
public Path getGitwebCgi() {
return cgi;
}
/** @return local path of the {@code gitweb.css} matching the CGI. */
public Path getGitwebCss() {
return css;
}
/** @return local path of the {@code gitweb.js} for the CGI. */
public Path getGitwebJs() {
return js;
}
/** @return local path of the {@code git-logo.png} for the CGI. */
public Path getGitLogoPng() {
return logoPng;
}
}

View File

@ -0,0 +1,229 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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.google.gerrit.server.config;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.base.Strings.nullToEmpty;
import com.google.common.base.Strings;
import com.google.gerrit.common.data.GitwebType;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GitwebConfig {
private static final Logger log = LoggerFactory.getLogger(GitwebConfig.class);
public static boolean isDisabled(Config cfg) {
return isEmptyString(cfg, "gitweb", null, "url")
|| isEmptyString(cfg, "gitweb", null, "cgi");
}
private static boolean isEmptyString(Config cfg, String section,
String subsection, String name) {
// This is currently the only way to check for the empty string in a JGit
// config. Fun!
String[] values = cfg.getStringList(section, subsection, name);
return values.length > 0 && Strings.isNullOrEmpty(values[0]);
}
/**
* Get a GitwebType based on the given config.
*
* @param cfg Gerrit config.
* @return GitwebType from the given name, else null if not found.
*/
public static GitwebType typeFromConfig(Config cfg) {
GitwebType defaultType = defaultType(cfg.getString("gitweb", null, "type"));
if (defaultType == null) {
return null;
}
GitwebType type = new GitwebType();
type.setLinkName(firstNonNull(
cfg.getString("gitweb", null, "linkname"),
defaultType.getLinkName()));
type.setBranch(firstNonNull(
cfg.getString("gitweb", null, "branch"),
defaultType.getBranch()));
type.setProject(firstNonNull(
cfg.getString("gitweb", null, "project"),
defaultType.getProject()));
type.setRevision(firstNonNull(
cfg.getString("gitweb", null, "revision"),
defaultType.getRevision()));
type.setRootTree(firstNonNull(
cfg.getString("gitweb", null, "roottree"),
defaultType.getRootTree()));
type.setFile(firstNonNull(
cfg.getString("gitweb", null, "file"),
defaultType.getFile()));
type.setFileHistory(firstNonNull(
cfg.getString("gitweb", null, "filehistory"),
defaultType.getFileHistory()));
type.setLinkDrafts(
cfg.getBoolean("gitweb", null, "linkdrafts",
defaultType.getLinkDrafts()));
type.setUrlEncode(
cfg.getBoolean("gitweb", null, "urlencode",
defaultType.getUrlEncode()));
String pathSeparator = cfg.getString("gitweb", null, "pathSeparator");
if (pathSeparator != null) {
if (pathSeparator.length() == 1) {
char c = pathSeparator.charAt(0);
if (isValidPathSeparator(c)) {
type.setPathSeparator(
firstNonNull(c, defaultType.getPathSeparator()));
} else {
log.warn("Invalid gitweb.pathSeparator: " + c);
}
} else {
log.warn(
"gitweb.pathSeparator is not a single character: " + pathSeparator);
}
}
return type;
}
private static GitwebType defaultType(String typeName) {
GitwebType type = new GitwebType();
switch (nullToEmpty(typeName)) {
case "":
case "gitweb":
type.setLinkName("gitweb");
type.setProject("?p=${project}.git;a=summary");
type.setRevision("?p=${project}.git;a=commit;h=${commit}");
type.setBranch("?p=${project}.git;a=shortlog;h=${branch}");
type.setRootTree("?p=${project}.git;a=tree;hb=${commit}");
type.setFile("?p=${project}.git;hb=${commit};f=${file}");
type.setFileHistory(
"?p=${project}.git;a=history;hb=${branch};f=${file}");
break;
case "cgit":
type.setLinkName("cgit");
type.setProject("${project}.git/summary");
type.setRevision("${project}.git/commit/?id=${commit}");
type.setBranch("${project}.git/log/?h=${branch}");
type.setRootTree("${project}.git/tree/?h=${commit}");
type.setFile("${project}.git/tree/${file}?h=${commit}");
type.setFileHistory("${project}.git/log/${file}?h=${branch}");
break;
case "custom":
// For a custom type with no explicit link name, just reuse "gitweb".
type.setLinkName("gitweb");
type.setProject("");
type.setRevision("");
type.setBranch("");
type.setRootTree("");
type.setFile("");
type.setFileHistory("");
break;
default:
return null;
}
return type;
}
private final String url;
private final GitwebType type;
@Inject
GitwebConfig(GitwebCgiConfig cgiConfig, @GerritServerConfig Config cfg) {
if (isDisabled(cfg)) {
type = null;
url = null;
return;
}
String cfgUrl = cfg.getString("gitweb", null, "url");
GitwebType type = typeFromConfig(cfg);
if (type == null) {
this.type = null;
url = null;
return;
} else if (cgiConfig.getGitwebCgi() == null) {
// Use an externally managed gitweb instance, and not an internal one.
url = cfgUrl;
} else {
url = firstNonNull(cfgUrl, "gitweb");
}
if (isNullOrEmpty(type.getBranch())) {
log.warn("No Pattern specified for gitweb.branch, disabling.");
this.type = null;
} else if (isNullOrEmpty(type.getProject())) {
log.warn("No Pattern specified for gitweb.project, disabling.");
this.type = null;
} else if (isNullOrEmpty(type.getRevision())) {
log.warn("No Pattern specified for gitweb.revision, disabling.");
this.type = null;
} else if (isNullOrEmpty(type.getRootTree())) {
log.warn("No Pattern specified for gitweb.roottree, disabling.");
this.type = null;
} else if (isNullOrEmpty(type.getFile())) {
log.warn("No Pattern specified for gitweb.file, disabling.");
this.type = null;
} else if (isNullOrEmpty(type.getFileHistory())) {
log.warn("No Pattern specified for gitweb.filehistory, disabling.");
this.type = null;
} else {
this.type = type;
}
}
/** @return GitwebType for gitweb viewer. */
public GitwebType getGitwebType() {
return type;
}
/**
* @return URL of the entry point into gitweb. This URL may be relative to our
* context if gitweb is hosted by ourselves; or absolute if its hosted
* elsewhere; or null if gitweb has not been configured.
*/
public String getUrl() {
return url;
}
/**
* Determines if a given character can be used unencoded in an URL as a
* replacement for the path separator '/'.
*
* Reasoning: http://www.ietf.org/rfc/rfc1738.txt § 2.2:
*
* ... only alphanumerics, the special characters "$-_.+!*'(),", and
* reserved characters used for their reserved purposes may be used
* unencoded within a URL.
*
* The following characters might occur in file names, however:
*
* alphanumeric characters,
*
* "$-_.+!',"
*/
static boolean isValidPathSeparator(char c) {
switch (c) {
case '*':
case '(':
case ')':
return true;
default:
return false;
}
}
}

View File

@ -14,14 +14,12 @@
package com.google.gerrit.server.config; package com.google.gerrit.server.config;
import com.google.gerrit.server.config.GitWebConfig;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
public class GitWebConfigTest { public class GitwebConfigTest {
private static final String VALID_CHARACTERS = "*()"; private static final String VALID_CHARACTERS = "*()";
private static final String SOME_INVALID_CHARACTERS = "09AZaz$-_.+!',"; private static final String SOME_INVALID_CHARACTERS = "09AZaz$-_.+!',";
@ -29,14 +27,14 @@ public class GitWebConfigTest {
@Test @Test
public void testValidPathSeparator() { public void testValidPathSeparator() {
for(char c : VALID_CHARACTERS.toCharArray()) { for(char c : VALID_CHARACTERS.toCharArray()) {
assertTrue("valid character rejected: " + c, GitWebConfig.isValidPathSeparator(c)); assertTrue("valid character rejected: " + c, GitwebConfig.isValidPathSeparator(c));
} }
} }
@Test @Test
public void testInalidPathSeparator() { public void testInalidPathSeparator() {
for(char c : SOME_INVALID_CHARACTERS.toCharArray()) { for(char c : SOME_INVALID_CHARACTERS.toCharArray()) {
assertFalse("invalid character accepted: " + c, GitWebConfig.isValidPathSeparator(c)); assertFalse("invalid character accepted: " + c, GitwebConfig.isValidPathSeparator(c));
} }
} }
} }