private void ReceivePack(ControllerContext context, Stream input, HttpResponseBase response) { var capabilities = new HashSet <string>(Capabilities.Split(' ')); var requests = ProtocolUtils.ParseUpdateRequests(input, capabilities).ToList(); if (requests.Count == 0) { response.BinaryWrite(ProtocolUtils.EndMarker); return; } var reportStatus = capabilities.Contains("report-status"); var useSideBand = capabilities.Contains("side-band-64k"); var reportBand = useSideBand ? ProtocolUtils.PrimaryBand : (int?)null; var failureBand = reportStatus ? reportBand : ProtocolUtils.ErrorBand; try { ProtocolUtils.UpdateRequest source; ProtocolUtils.UpdateRequest destination; var errors = ReadRequests(requests, out source, out destination); if (errors.Any(e => e.Value != null) || source == null || destination == null) { if (reportStatus || useSideBand) { ReportFailure(response, failureBand, errors, "expected source and destination branches to be pushed"); } return; } var refPrefix = Guid.NewGuid().ToString(); source = new ProtocolUtils.UpdateRequest( source.SourceIdentifier, source.TargetIdentifier, RepoFormat.FormatSourceRef(refPrefix, 1)); destination = new ProtocolUtils.UpdateRequest( destination.SourceIdentifier, destination.TargetIdentifier, RepoFormat.FormatDestinationRef(refPrefix, 1)); var output = this.ReadPack(new[] { source, destination }, capabilities, input); var line = ProtocolUtils.ReadPacketLine(output).TrimEnd('\n'); if (line != "unpack ok") { line = line.Substring("unpack ".Length); if (reportStatus || useSideBand) { ReportFailure(response, failureBand, errors, line); } return; } string id; try { using (var ctx = new ReviewContext()) { using (new NoSyncScope()) { id = ctx.GetNextReviewId().Result; } ctx.Reviews.Add(new Review { Id = id, RefPrefix = refPrefix, }); ctx.SaveChanges(); } } catch (DbUpdateException ex) { ReportFailure(response, failureBand, errors, ex.GetBaseException().Message); throw; } if (useSideBand) { var url = new UrlHelper(context.RequestContext).Action("Index", "Home", null, context.HttpContext.Request.Url.Scheme) + "#/" + id; var message = string.Format("code review created:\n\n\t{0}\n\n", url); response.BinaryWrite(ProtocolUtils.Band(ProtocolUtils.MessageBand, Encoding.UTF8.GetBytes(message))); } if (reportStatus) { ReportSuccess(response, reportBand); } } finally { if (useSideBand) { response.BinaryWrite(ProtocolUtils.EndMarker); } } }
private static Dictionary <ProtocolUtils.UpdateRequest, string> ReadRequests(List <ProtocolUtils.UpdateRequest> requests, out ProtocolUtils.UpdateRequest source, out ProtocolUtils.UpdateRequest destination) { var errors = requests.ToDictionary(r => r, r => { if (r.TargetIdentifier == null) { return("delete unsupported"); } else if (r.SourceIdentifier != null) { return("update unsupported"); } else if (r.CanonicalName != SourceRefName && r.CanonicalName != DestinationRefName) { return("ref unsupported"); } return(null); }); if (requests.Count == 2) { source = requests.FirstOrDefault(r => r.CanonicalName == SourceRefName); destination = requests.FirstOrDefault(r => r.CanonicalName == DestinationRefName); } else { source = null; destination = null; } return(errors); }
private void ReceivePack(ControllerContext context, Stream input, HttpResponseBase response) { var capabilities = new HashSet<string>(Capabilities.Split(' ')); var requests = ProtocolUtils.ParseUpdateRequests(input, capabilities).ToList(); if (requests.Count == 0) { response.BinaryWrite(ProtocolUtils.EndMarker); return; } var reportStatus = capabilities.Contains("report-status"); var useSideBand = capabilities.Contains("side-band-64k"); var reportBand = useSideBand ? ProtocolUtils.PrimaryBand : (int?)null; var failureBand = reportStatus ? reportBand : ProtocolUtils.ErrorBand; try { ProtocolUtils.UpdateRequest source; ProtocolUtils.UpdateRequest destination; var errors = ReadRequests(requests, out source, out destination); if (errors.Any(e => e.Value != null) || source == null || destination == null) { if (reportStatus || useSideBand) { ReportFailure(response, failureBand, errors, "expected source and destination branches to be pushed"); } return; } var refPrefix = Guid.NewGuid().ToString(); source = new ProtocolUtils.UpdateRequest( source.SourceIdentifier, source.TargetIdentifier, RepoFormat.FormatSourceRef(refPrefix, 1)); destination = new ProtocolUtils.UpdateRequest( destination.SourceIdentifier, destination.TargetIdentifier, RepoFormat.FormatDestinationRef(refPrefix, 1)); var output = this.ReadPack(new[] { source, destination }, capabilities, input); var line = ProtocolUtils.ReadPacketLine(output).TrimEnd('\n'); if (line != "unpack ok") { line = line.Substring("unpack ".Length); if (reportStatus || useSideBand) { ReportFailure(response, failureBand, errors, line); } return; } string id; try { using (var ctx = new ReviewContext()) { using (new NoSyncScope()) { id = ctx.GetNextReviewId().Result; } ctx.Reviews.Add(new Review { Id = id, RefPrefix = refPrefix, }); ctx.SaveChanges(); } } catch (DbUpdateException ex) { ReportFailure(response, failureBand, errors, ex.GetBaseException().Message); throw; } if (useSideBand) { var url = new UrlHelper(context.RequestContext).Action("Index", "Home", null, context.HttpContext.Request.Url.Scheme) + "#/" + id; var message = string.Format("code review created:\n\n\t{0}\n\n", url); response.BinaryWrite(ProtocolUtils.Band(ProtocolUtils.MessageBand, Encoding.UTF8.GetBytes(message))); } if (reportStatus) { ReportSuccess(response, reportBand); } } finally { if (useSideBand) { response.BinaryWrite(ProtocolUtils.EndMarker); } } }