Exemple #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);
            }
        }
Exemple #2
0
        private GitProcess.Result TryAddPackFile(Stream contents, bool unpackObjects)
        {
            Debug.Assert(contents != null, "contents should not be null");

            GitProcess.Result result;

            if (unpackObjects)
            {
                result = new GitProcess(this.Enlistment).UnpackObjects(contents);
            }
            else
            {
                string packfilePath = GetRandomPackName(this.Enlistment.GitPackRoot);
                using (FileStream fileStream = File.OpenWrite(packfilePath))
                {
                    StreamUtil.CopyToWithBuffer(contents, fileStream);
                }

                this.ValidateTempFile(packfilePath, packfilePath);

                result = new GitProcess(this.Enlistment).IndexPack(packfilePath);
            }

            return(result);
        }
Exemple #3
0
        private GitProcess.Result TryAddPackFile(Stream contents, bool unpackObjects)
        {
            GitProcess.Result result;

            this.fileSystem.CreateDirectory(this.Enlistment.GitPackRoot);

            if (unpackObjects)
            {
                result = new GitProcess(this.Enlistment).UnpackObjects(contents);
            }
            else
            {
                string packfilePath = GetRandomPackName(this.Enlistment.GitPackRoot);
                using (Stream fileStream = this.fileSystem.OpenFileStream(packfilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
                {
                    StreamUtil.CopyToWithBuffer(contents, fileStream);
                }

                this.ValidateTempFile(packfilePath, packfilePath);

                result = new GitProcess(this.Enlistment).IndexPack(packfilePath);
            }

            return(result);
        }
Exemple #4
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);
        }
Exemple #5
0
        public virtual bool TryWriteNamedPackOrIdx(
            ITracer tracer,
            Stream source,
            string targetFullPath,
            out long fileLength,
            bool throwOnError = false)
        {
            // It is important to write temp files then rename so that git
            // does not mistake a half-written file for an invalid one.
            string tempPath = targetFullPath + "temp";

            fileLength = 0;

            try
            {
                using (Stream fileStream = this.fileSystem.OpenFileStream(tempPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                {
                    StreamUtil.CopyToWithBuffer(source, fileStream);
                    fileLength = fileStream.Length;
                }

                this.ValidateTempFile(tempPath, targetFullPath);
                this.fileSystem.MoveFile(tempPath, targetFullPath);
            }
            catch (Exception ex)
            {
                this.CleanupTempFile(this.Tracer, tempPath);

                if (tracer != null)
                {
                    EventMetadata metadata = new EventMetadata();
                    metadata.Add("Exception", ex.ToString());
                    metadata.Add("TargetFullPath", targetFullPath);
                    tracer.RelatedWarning(metadata, "Exception caught while writing pack or index", Keywords.Telemetry);
                }

                if (throwOnError)
                {
                    throw;
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
        public virtual bool TryWriteNamedPackOrIdx(
            ITracer tracer,
            Stream source,
            string targetFullPath,
            bool throwOnError = false)
        {
            // It is important to write temp files then rename so that git
            // does not mistake a half-written file for an invalid one.
            string tempPath = targetFullPath + "temp";

            try
            {
                using (Stream fileStream = File.OpenWrite(tempPath))
                {
                    StreamUtil.CopyToWithBuffer(source, fileStream);
                }

                this.ValidateTempFile(tempPath, targetFullPath);
                File.Move(tempPath, targetFullPath);
            }
            catch (Exception ex)
            {
                this.CleanupTempFile(this.Tracer, tempPath);

                if (tracer != null)
                {
                    EventMetadata metadata = new EventMetadata();
                    metadata.Add("Exception", ex.ToString());
                    metadata.Add("ErrorMessage", "Exception caught while writing pack or index");
                    metadata.Add("TargetFullPath", targetFullPath);
                    tracer.RelatedError(metadata);
                }

                if (throwOnError)
                {
                    throw;
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #7
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);
        }
Exemple #8
0
        public virtual bool TryWriteTempFile(
            ITracer tracer,
            Stream source,
            string tempFilePath,
            out long fileLength,
            out Task flushTask,
            bool throwOnError = false)
        {
            fileLength = 0;
            flushTask  = null;
            try
            {
                Stream fileStream = null;

                try
                {
                    fileStream = this.fileSystem.OpenFileStream(
                        tempFilePath,
                        FileMode.OpenOrCreate,
                        FileAccess.Write,
                        FileShare.Read,
                        callFlushFileBuffers: false); // Any flushing to disk will be done asynchronously

                    StreamUtil.CopyToWithBuffer(source, fileStream);
                    fileLength = fileStream.Length;

                    if (this.Enlistment.FlushFileBuffersForPacks)
                    {
                        // Flush any data buffered in FileStream to the file system
                        fileStream.Flush();

                        // FlushFileBuffers using FlushAsync
                        // Do this last to ensure that the stream is not being accessed after it's been disposed
                        flushTask = fileStream.FlushAsync().ContinueWith((result) => fileStream.Dispose());
                    }
                }
                finally
                {
                    if (flushTask == null && fileStream != null)
                    {
                        fileStream.Dispose();
                    }
                }

                this.ValidateTempFile(tempFilePath, tempFilePath);
            }
            catch (Exception ex)
            {
                if (flushTask != null)
                {
                    flushTask.Wait();
                    flushTask = null;
                }

                this.CleanupTempFile(this.Tracer, tempFilePath);

                if (tracer != null)
                {
                    EventMetadata metadata = CreateEventMetadata(ex);
                    metadata.Add("tempFilePath", tempFilePath);
                    tracer.RelatedWarning(metadata, $"{nameof(this.TryWriteTempFile)}: Exception caught while writing temp file", Keywords.Telemetry);
                }

                if (throwOnError)
                {
                    throw;
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #9
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);
            }
        }