一个基于ASP.NET MVC的git服务端。
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

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
}
}