(refs #1101)Store LFS files under GITBUCKET_HOME/repositories/<owner>/<name>/lfs

This commit is contained in:
Naoki Takezoe
2017-01-04 20:31:22 +09:00
parent d460185317
commit eb50b74b4a
5 changed files with 59 additions and 55 deletions

View File

@@ -257,7 +257,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
getPathObjectId(git, path, revCommit).map { objectId =>
responseRawFile(git, objectId, path)
responseRawFile(git, objectId, path, repository)
} getOrElse NotFound()
}
})
@@ -273,7 +273,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
getPathObjectId(git, path, revCommit).map { objectId =>
if(raw){
// Download (This route is left for backword compatibility)
responseRawFile(git, objectId, path)
responseRawFile(git, objectId, path, repository)
} else {
html.blob(id, repository, path.split("/").toList,
JGitUtil.getContentInfo(git, path, objectId),
@@ -296,7 +296,8 @@ trait RepositoryViewerControllerBase extends ControllerBase {
}.getOrElse(false)
}
private def responseRawFile(git: Git, objectId: ObjectId, path: String): Unit = {
private def responseRawFile(git: Git, objectId: ObjectId, path: String,
repository: RepositoryService.RepositoryInfo): Unit = {
JGitUtil.getObjectLoaderFromId(git, objectId){ loader =>
contentType = FileUtil.getMimeType(path)
@@ -317,7 +318,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
response.setContentLength(attrs("size").toInt)
val oid = attrs("oid").split(":")(1)
using(new FileInputStream(FileUtil.getLfsFilePath(oid))){ in =>
using(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))){ in =>
IOUtils.copy(in, response.getOutputStream)
}
} else {

View File

@@ -22,9 +22,9 @@ class GitLfsTransferServlet extends HttpServlet {
override protected def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit = {
for {
oid <- getObjectId(req, res) if checkToken(req, oid)
(owner, name, oid) <- getPathInfo(req, res) if checkToken(req, oid)
} yield {
val file = new File(FileUtil.getLfsFilePath(oid))
val file = new File(FileUtil.getLfsFilePath(owner, name, oid))
if(file.exists()){
res.setStatus(HttpStatus.SC_OK)
res.setContentType("application/octet-stream")
@@ -42,9 +42,9 @@ class GitLfsTransferServlet extends HttpServlet {
override protected def doPut(req: HttpServletRequest, res: HttpServletResponse): Unit = {
for {
oid <- getObjectId(req, res) if checkToken(req, oid)
(owner, name, oid) <- getPathInfo(req, res) if checkToken(req, oid)
} yield {
val file = new File(FileUtil.getLfsFilePath(oid))
val file = new File(FileUtil.getLfsFilePath(owner, name, oid))
FileUtils.forceMkdir(file.getParentFile)
using(req.getInputStream, new FileOutputStream(file)){ (in, out) =>
IOUtils.copy(in, out)
@@ -63,15 +63,10 @@ class GitLfsTransferServlet extends HttpServlet {
}
}
private def getObjectId(req: HttpServletRequest, rsp: HttpServletResponse): Option[String] = {
val info: String = req.getPathInfo
val length: Int = 1 + LongObjectIdStringLength
if (info.length != length) {
sendError(rsp, HttpStatus.SC_UNPROCESSABLE_ENTITY,
MessageFormat.format("Invalid pathInfo ''{0}'' does not match ''/'{'SHA-256'}'''", info))
None
} else {
Some(info.substring(1, length))
private def getPathInfo(req: HttpServletRequest, res: HttpServletResponse): Option[(String, String, String)] = {
req.getRequestURI.substring(1).split("/") match {
case Array(_, owner, name, oid) => Some((owner, name, oid))
case _ => None
}
}

View File

@@ -70,43 +70,48 @@ class GitRepositoryServlet extends GitServlet with SystemSettingsService {
val settings = loadSystemSettings()
settings.baseUrl match {
case None =>
case None => {
throw new IllegalStateException("lfs.server_url is not configured.")
}
case Some(baseUrl) => {
req.getRequestURI.substring(1).replace(".git/", "/").split("/") match {
case Array(_, owner, name, _*) => {
val timeout = System.currentTimeMillis + (60000 * 10) // 10 min.
val batchResponse = batchRequest.operation match {
case "upload" =>
GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
GitLfs.Actions(
upload = Some(GitLfs.Action(
href = baseUrl + "/git-lfs/" + owner + "/" + name + "/" + requestObject.oid,
header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
expires_at = new Date(timeout)
))
)
)
})
case "download" =>
GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
GitLfs.Actions(
download = Some(GitLfs.Action(
href = baseUrl + "/git-lfs/" + owner + "/" + name + "/" + requestObject.oid,
header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
expires_at = new Date(timeout)
))
)
)
})
}
case Some(baseUrl) =>
val timeout = System.currentTimeMillis + (60000 * 10) // 10 min.
val batchResponse = batchRequest.operation match {
case "upload" =>
GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
GitLfs.Actions(
upload = Some(GitLfs.Action(
href = baseUrl + "/git-lfs/" + requestObject.oid,
header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
expires_at = new Date(timeout)
))
)
)
})
case "download" =>
GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
GitLfs.Actions(
download = Some(GitLfs.Action(
href = baseUrl + "/git-lfs/" + requestObject.oid,
header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
expires_at = new Date(timeout)
))
)
)
})
}
res.setContentType("application/vnd.git-lfs+json")
using(res.getWriter){ out =>
out.print(write(batchResponse))
out.flush()
res.setContentType("application/vnd.git-lfs+json")
using(res.getWriter){ out =>
out.print(write(batchResponse))
out.flush()
}
}
}
}
}
}
}

View File

@@ -36,8 +36,6 @@ object Directory {
val TemporaryHome = s"${GitBucketHome}/tmp"
val LfsHome = s"${GitBucketHome}/lfs"
/**
* Substance directory of the repository.
*/
@@ -50,6 +48,12 @@ object Directory {
def getAttachedDir(owner: String, repository: String): File =
new File(s"${RepositoryHome}/${owner}/${repository}/comments")
/**
* Directory for files which are attached to issue.
*/
def getLfsDir(owner: String, repository: String): File =
new File(s"${RepositoryHome}/${owner}/${repository}/lfs")
/**
* Directory for uploaded files by the specified user.
*/

View File

@@ -63,7 +63,6 @@ object FileUtil {
"image/png",
"text/plain")
def getLfsFilePath(oid: String): String =
Directory.LfsHome + "/" + oid.substring(0, 2) + "/" + oid.substring(2, 4) + "/" + oid
def getLfsFilePath(owner: String, name: String, oid: String): String = Directory.getLfsDir(owner, name) + "/" + oid
}