示例#1
0
        public virtual string WriteLooseObject(Stream responseStream, string sha, bool overwriteExistingObject, byte[] bufToCopyWith)
        {
            try
            {
                LooseObjectToWrite toWrite = this.GetLooseObjectDestination(sha);

                using (Stream fileStream = this.OpenTempLooseObjectStream(toWrite.TempFile))
                {
                    StreamUtil.CopyToWithBuffer(responseStream, fileStream, bufToCopyWith);
                }

                this.FinalizeTempFile(sha, toWrite, overwriteExistingObject);

                return(toWrite.ActualFile);
            }
            catch (IOException e)
            {
                throw new RetryableException("IOException while writing loose object. See inner exception for details.", e);
            }
            catch (UnauthorizedAccessException e)
            {
                throw new RetryableException("UnauthorizedAccessException while writing loose object. See inner exception for details.", e);
            }
            catch (Win32Exception e)
            {
                throw new RetryableException("Win32Exception while writing loose object. See inner exception for details.", e);
            }
        }
示例#2
0
        private void FinalizeTempFile(string sha, LooseObjectToWrite toWrite)
        {
            try
            {
                // Checking for existence reduces warning outputs when a streamed download tries.
                if (!File.Exists(toWrite.ActualFile))
                {
                    this.ValidateTempFile(toWrite.TempFile, sha);

                    try
                    {
                        File.Move(toWrite.TempFile, toWrite.ActualFile);
                    }
                    catch (IOException ex)
                    {
                        // IOExceptions happen when someone else is writing to our object.
                        // That implies they are doing what we're doing, which should be a success
                        EventMetadata info = new EventMetadata();
                        info.Add("Message", "Exception moving temp file");
                        info.Add("file", toWrite.ActualFile);
                        info.Add("Exception", ex.Message);
                        this.Tracer.RelatedEvent(EventLevel.Warning, "Warning", info);
                    }
                }
            }
            finally
            {
                this.CleanupTempFile(this.Tracer, toWrite.TempFile);
            }
        }
示例#3
0
        public virtual string WriteLooseObject(Stream responseStream, string sha, byte[] bufToCopyWith)
        {
            LooseObjectToWrite toWrite = this.GetLooseObjectDestination(sha);

            using (Stream fileStream = OpenTempLooseObjectStream(toWrite.TempFile, async: false))
            {
                StreamUtil.CopyToWithBuffer(responseStream, fileStream, bufToCopyWith);
            }

            this.FinalizeTempFile(sha, toWrite);

            return(toWrite.ActualFile);
        }
示例#4
0
        private void FinalizeTempFile(string sha, LooseObjectToWrite toWrite, bool overwriteExistingObject)
        {
            try
            {
                // Checking for existence reduces warning outputs when a streamed download tries.
                if (this.fileSystem.FileExists(toWrite.ActualFile))
                {
                    if (overwriteExistingObject)
                    {
                        EventMetadata metadata = CreateEventMetadata();
                        metadata.Add("file", toWrite.ActualFile);
                        metadata.Add("tempFile", toWrite.TempFile);
                        metadata.Add(TracingConstants.MessageKey.InfoMessage, $"{nameof(this.FinalizeTempFile)}: Overwriting existing loose object");
                        this.Tracer.RelatedEvent(EventLevel.Informational, $"{nameof(this.FinalizeTempFile)}_OverwriteExistingObject", metadata);

                        this.ValidateTempFile(toWrite.TempFile, sha);
                        this.fileSystem.MoveAndOverwriteFile(toWrite.TempFile, toWrite.ActualFile);
                    }
                }
                else
                {
                    this.ValidateTempFile(toWrite.TempFile, sha);

                    try
                    {
                        this.fileSystem.MoveFile(toWrite.TempFile, toWrite.ActualFile);
                    }
                    catch (IOException ex)
                    {
                        // IOExceptions happen when someone else is writing to our object.
                        // That implies they are doing what we're doing, which should be a success
                        EventMetadata info = CreateEventMetadata(ex);
                        info.Add("file", toWrite.ActualFile);
                        this.Tracer.RelatedWarning(info, $"{nameof(this.FinalizeTempFile)}: Exception moving temp file");
                    }
                }
            }
            finally
            {
                this.CleanupTempFile(this.Tracer, toWrite.TempFile);
            }
        }
示例#5
0
        public virtual string WriteLooseObject(string repoRoot, Stream responseStream, string sha, byte[] bufToCopyWith = null)
        {
            LooseObjectToWrite toWrite = GetLooseObjectDestination(repoRoot, sha);

            using (Stream fileStream = OpenTempLooseObjectStream(toWrite.TempFile, async: false))
            {
                if (bufToCopyWith != null)
                {
                    StreamUtil.CopyToWithBuffer(responseStream, fileStream, bufToCopyWith);
                }
                else
                {
                    responseStream.CopyTo(fileStream);
                }
            }

            this.FinalizeTempFile(sha, toWrite);

            return(toWrite.ActualFile);
        }
示例#6
0
        private void FinalizeTempFile(string sha, LooseObjectToWrite toWrite)
        {
            try
            {
                // Checking for existence reduces warning outputs when a streamed download tries.
                if (!File.Exists(toWrite.ActualFile))
                {
                    this.ValidateTempFile(toWrite.TempFile, sha);

                    File.Move(toWrite.TempFile, toWrite.ActualFile);
                }
            }
            catch (IOException)
            {
                // IOExceptions happen when someone else is writing to our object.
                // That implies they are doing what we're doing, which should be a success
            }
            finally
            {
                this.CleanupTempFile(this.Tracer, toWrite.TempFile);
            }
        }
示例#7
0
        public virtual string WriteLooseObject(Stream responseStream, string sha, bool overwriteExistingObject, byte[] bufToCopyWith)
        {
            try
            {
                LooseObjectToWrite toWrite = this.GetLooseObjectDestination(sha);

                if (this.checkData)
                {
                    try
                    {
                        using (Stream fileStream = this.OpenTempLooseObjectStream(toWrite.TempFile))
                            using (SideChannelStream sideChannel = new SideChannelStream(from: responseStream, to: fileStream))
                                using (InflaterInputStream inflate = new InflaterInputStream(sideChannel))
                                    using (HashingStream hashing = new HashingStream(inflate))
                                        using (NoOpStream devNull = new NoOpStream())
                                        {
                                            hashing.CopyTo(devNull);

                                            string actualSha = SHA1Util.HexStringFromBytes(hashing.Hash);

                                            if (!sha.Equals(actualSha, StringComparison.OrdinalIgnoreCase))
                                            {
                                                string message = $"Requested object with hash {sha} but received object with hash {actualSha}.";
                                                message += $"\nFind the incorrect data at '{toWrite.TempFile}'";
                                                this.Tracer.RelatedError(message);
                                                throw new SecurityException(message);
                                            }
                                        }
                    }
                    catch (SharpZipBaseException)
                    {
                        string message = $"Requested object with hash {sha} but received data that failed decompression.";
                        message += $"\nFind the incorrect data at '{toWrite.TempFile}'";
                        this.Tracer.RelatedError(message);
                        throw new RetryableException(message);
                    }
                }
                else
                {
                    using (Stream fileStream = this.OpenTempLooseObjectStream(toWrite.TempFile))
                    {
                        StreamUtil.CopyToWithBuffer(responseStream, fileStream, bufToCopyWith);
                        fileStream.Flush();
                    }
                }

                this.FinalizeTempFile(sha, toWrite, overwriteExistingObject);

                return(toWrite.ActualFile);
            }
            catch (IOException e)
            {
                throw new RetryableException("IOException while writing loose object. See inner exception for details.", e);
            }
            catch (UnauthorizedAccessException e)
            {
                throw new RetryableException("UnauthorizedAccessException while writing loose object. See inner exception for details.", e);
            }
            catch (Win32Exception e)
            {
                throw new RetryableException("Win32Exception while writing loose object. See inner exception for details.", e);
            }
        }