/* | |
* 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.pages; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLEncoder; | |
import java.text.MessageFormat; | |
import java.util.HashMap; | |
import java.util.Map; | |
import javax.servlet.http.HttpServletResponse; | |
import org.apache.wicket.IRequestTarget; | |
import org.apache.wicket.PageParameters; | |
import org.apache.wicket.RequestCycle; | |
import org.apache.wicket.protocol.http.WebRequest; | |
import org.apache.wicket.protocol.http.WebResponse; | |
import org.apache.wicket.protocol.http.servlet.AbortWithWebErrorCodeException; | |
import org.eclipse.jgit.lib.Repository; | |
import org.eclipse.jgit.revwalk.RevCommit; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import com.gitblit.Keys; | |
import com.gitblit.models.RepositoryModel; | |
import com.gitblit.models.UserModel; | |
import com.gitblit.utils.JGitUtils; | |
import com.gitblit.utils.StringUtils; | |
import com.gitblit.wicket.GitBlitWebSession; | |
import com.gitblit.wicket.WicketUtils; | |
public class RawPage extends SessionPage { | |
private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName()); | |
String contentType; | |
public RawPage(final PageParameters params) { | |
super(params); | |
if (!params.containsKey("r")) { | |
error(getString("gb.repositoryNotSpecified")); | |
redirectToInterceptPage(new RepositoriesPage()); | |
} | |
getRequestCycle().setRequestTarget(new IRequestTarget() { | |
@Override | |
public void detach(RequestCycle requestCycle) { | |
} | |
@Override | |
public void respond(RequestCycle requestCycle) { | |
WebResponse response = (WebResponse) requestCycle.getResponse(); | |
final String repositoryName = WicketUtils.getRepositoryName(params); | |
final String objectId = WicketUtils.getObject(params); | |
final String blobPath = WicketUtils.getPath(params); | |
String[] encodings = getEncodings(); | |
GitBlitWebSession session = GitBlitWebSession.get(); | |
UserModel user = session.getUser(); | |
RepositoryModel model = app().repositories().getRepositoryModel(user, repositoryName); | |
if (model == null) { | |
// user does not have permission | |
error(getString("gb.canNotLoadRepository") + " " + repositoryName); | |
redirectToInterceptPage(new RepositoriesPage()); | |
return; | |
} | |
Repository r = app().repositories().getRepository(repositoryName); | |
if (r == null) { | |
error(getString("gb.canNotLoadRepository") + " " + repositoryName); | |
redirectToInterceptPage(new RepositoriesPage()); | |
return; | |
} | |
if (StringUtils.isEmpty(blobPath)) { | |
// objectid referenced raw view | |
byte [] binary = JGitUtils.getByteContent(r, objectId); | |
if (binary == null) { | |
final String objectNotFound = MessageFormat.format("Raw page failed to find object {0} in {1}", | |
objectId, repositoryName); | |
logger.error(objectNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, objectNotFound); | |
} | |
contentType = "application/octet-stream"; | |
response.setContentType(contentType); | |
response.setContentLength(binary.length); | |
try { | |
response.getOutputStream().write(binary); | |
} catch (Exception e) { | |
logger.error("Failed to write binary response", e); | |
} | |
} else { | |
// standard raw blob view | |
RevCommit commit = JGitUtils.getCommit(r, objectId); | |
if (commit == null) { | |
final String commitNotFound = MessageFormat.format("Raw page failed to find commit {0} in {1}", | |
objectId, repositoryName); | |
logger.error(commitNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, commitNotFound); | |
} | |
String filename = blobPath; | |
if (blobPath.indexOf('/') > -1) { | |
filename = blobPath.substring(blobPath.lastIndexOf('/') + 1); | |
} | |
String extension = null; | |
if (blobPath.lastIndexOf('.') > -1) { | |
extension = blobPath.substring(blobPath.lastIndexOf('.') + 1); | |
} | |
// Map the extensions to types | |
Map<String, Integer> map = new HashMap<String, Integer>(); | |
for (String ext : app().settings().getStrings(Keys.web.imageExtensions)) { | |
map.put(ext.toLowerCase(), 2); | |
} | |
for (String ext : app().settings().getStrings(Keys.web.binaryExtensions)) { | |
map.put(ext.toLowerCase(), 3); | |
} | |
final String blobNotFound = MessageFormat.format("Raw page failed to find blob {0} in {1} @ {2}", | |
blobPath, repositoryName, objectId); | |
if (extension != null) { | |
int type = 0; | |
if (map.containsKey(extension)) { | |
type = map.get(extension); | |
} | |
switch (type) { | |
case 2: | |
// image blobs | |
byte[] image = JGitUtils.getByteContent(r, commit.getTree(), blobPath, true); | |
if (image == null) { | |
logger.error(blobNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, blobNotFound); | |
} | |
contentType = "image/" + extension.toLowerCase(); | |
response.setContentType(contentType); | |
response.setContentLength(image.length); | |
try { | |
response.getOutputStream().write(image); | |
} catch (IOException e) { | |
logger.error("Failed to write image response", e); | |
} | |
break; | |
case 3: | |
// binary blobs (download) | |
byte[] binary = JGitUtils.getByteContent(r, commit.getTree(), blobPath, true); | |
if (binary == null) { | |
logger.error(blobNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, blobNotFound); | |
} | |
contentType = "application/octet-stream"; | |
response.setContentLength(binary.length); | |
response.setContentType(contentType); | |
try { | |
WebRequest request = (WebRequest) requestCycle.getRequest(); | |
String userAgent = request.getHttpServletRequest().getHeader("User-Agent"); | |
if (userAgent != null && userAgent.indexOf("MSIE 5.5") > -1) { | |
response.setHeader("Content-Disposition", "filename=\"" | |
+ URLEncoder.encode(filename, "UTF-8") + "\""); | |
} else if (userAgent != null && userAgent.indexOf("MSIE") > -1) { | |
response.setHeader("Content-Disposition", "attachment; filename=\"" | |
+ URLEncoder.encode(filename, "UTF-8") + "\""); | |
} else { | |
response.setHeader("Content-Disposition", "attachment; filename=\"" | |
+ new String(filename.getBytes("UTF-8"), "latin1") + "\""); | |
} | |
} | |
catch (UnsupportedEncodingException e) { | |
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); | |
} | |
try { | |
response.getOutputStream().write(binary); | |
} catch (IOException e) { | |
logger.error("Failed to write binary response", e); | |
} | |
break; | |
default: | |
// plain text | |
String content = JGitUtils.getStringContent(r, commit.getTree(), | |
blobPath, encodings); | |
if (content == null) { | |
logger.error(blobNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, blobNotFound); | |
} | |
contentType = "text/plain; charset=UTF-8"; | |
response.setContentType(contentType); | |
try { | |
response.getOutputStream().write(content.getBytes("UTF-8")); | |
} catch (Exception e) { | |
logger.error("Failed to write text response", e); | |
} | |
} | |
} else { | |
// plain text | |
String content = JGitUtils.getStringContent(r, commit.getTree(), blobPath, | |
encodings); | |
if (content == null) { | |
logger.error(blobNotFound); | |
throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_NOT_FOUND, blobNotFound); | |
} | |
contentType = "text/plain; charset=UTF-8"; | |
response.setContentType(contentType); | |
try { | |
response.getOutputStream().write(content.getBytes("UTF-8")); | |
} catch (Exception e) { | |
logger.error("Failed to write text response", e); | |
} | |
} | |
} | |
r.close(); | |
} | |
}); | |
} | |
@Override | |
protected void setHeaders(WebResponse response) { | |
super.setHeaders(response); | |
if (!StringUtils.isEmpty(contentType)) { | |
response.setContentType(contentType); | |
} | |
} | |
} |