You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.8 KiB
115 lines
3.8 KiB
using System;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Net;
|
|
using System.Web;
|
|
using System.Web.Mvc;
|
|
using GitCandy.Data;
|
|
using GitCandy.Filters;
|
|
using GitCandy.Git;
|
|
using LibGit2Sharp;
|
|
|
|
namespace GitCandy.Controllers
|
|
{
|
|
public class GitController : CandyControllerBase
|
|
{
|
|
public RepositoryService RepositoryService { get; set; } = new RepositoryService();
|
|
|
|
[SmartGit]
|
|
public ActionResult Smart(string project, string service, string verb)
|
|
{
|
|
switch (verb)
|
|
{
|
|
case "info/refs":
|
|
return InfoRefs(project, service);
|
|
case "git-upload-pack":
|
|
return ExecutePack(project, "git-upload-pack");
|
|
case "git-receive-pack":
|
|
return ExecutePack(project, "git-receive-pack");
|
|
default:
|
|
return RedirectToAction("Tree", "Repository", new { Name = project });
|
|
}
|
|
}
|
|
|
|
protected ActionResult InfoRefs(string project, string service)
|
|
{
|
|
Response.Charset = "";
|
|
Response.ContentType = String.Format(CultureInfo.InvariantCulture, "application/x-{0}-advertisement", service);
|
|
SetNoCache();
|
|
Response.Write(FormatMessage(String.Format(CultureInfo.InvariantCulture, "# service={0}\n", service)));
|
|
Response.Write(FlushMessage());
|
|
|
|
try
|
|
{
|
|
using (var git = new GitService(project))
|
|
{
|
|
var svc = service.Substring(4);
|
|
git.InfoRefs(svc, GetInputStream(), Response.OutputStream);
|
|
}
|
|
return new EmptyResult();
|
|
}
|
|
catch (RepositoryNotFoundException e)
|
|
{
|
|
throw new HttpException((int)HttpStatusCode.NotFound, string.Empty, e);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new HttpException((int)HttpStatusCode.InternalServerError, string.Empty, e);
|
|
}
|
|
}
|
|
|
|
protected ActionResult ExecutePack(string project, string service)
|
|
{
|
|
Response.Charset = "";
|
|
Response.ContentType = String.Format(CultureInfo.InvariantCulture, "application/x-{0}-result", service);
|
|
SetNoCache();
|
|
|
|
try
|
|
{
|
|
using (var git = new GitService(project))
|
|
{
|
|
var svc = service.Substring(4);
|
|
git.ExecutePack(svc, GetInputStream(), Response.OutputStream);
|
|
}
|
|
return new EmptyResult();
|
|
}
|
|
catch (RepositoryNotFoundException e)
|
|
{
|
|
throw new HttpException((int)HttpStatusCode.NotFound, string.Empty, e);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new HttpException((int)HttpStatusCode.InternalServerError, string.Empty, e);
|
|
}
|
|
}
|
|
|
|
#region GitController Extension
|
|
private void SetNoCache()
|
|
{
|
|
Response.AddHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
|
|
Response.AddHeader("Pragma", "no-cache");
|
|
Response.AddHeader("Cache-Control", "no-cache, max-age=0, must-revalidate");
|
|
}
|
|
|
|
private Stream GetInputStream()
|
|
{
|
|
if (Request.Headers["Content-Encoding"] == "gzip")
|
|
{
|
|
return new GZipStream(Request.GetBufferlessInputStream(true), CompressionMode.Decompress);
|
|
}
|
|
return Request.GetBufferlessInputStream(true);
|
|
}
|
|
|
|
private static string FormatMessage(string input)
|
|
{
|
|
return (input.Length + 4).ToString("X4", CultureInfo.InvariantCulture) + input;
|
|
}
|
|
|
|
private static string FlushMessage()
|
|
{
|
|
return "0000";
|
|
}
|
|
#endregion
|
|
}
|
|
}
|