public async Task PutFileContent()
        {
            _service.EnsureAccess(_file.Path, FileAccess.Write);

            int start, finish, outOf;
            var etag = ETag.Create(_file);

            ValidateIfMatch();
            ValidateIfNoneMatch(etag);
            ValidateIfUnmodifiedSince();
            ValidateContentRange(out start, out finish, out outOf);

            string tempFilePath = CreateTempFile(_file.Path);

            try {
                using (var temp = _service.GetFileStream(tempFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) {
                    //
                    // Write to temp file
                    await _context.Request.Body.CopyToAsync(temp);

                    temp.Flush();
                    temp.Seek(0, SeekOrigin.Begin);

                    //
                    // Copy from temp
                    using (var real = TryOpenFile(_file.Path, FileMode.Open, FileAccess.Write, FileShare.Read)) {
                        if (start >= 0)
                        {
                            //
                            // Range request

                            int length = finish - start + 1;
                            real.Seek(start, SeekOrigin.Begin);
                        }

                        await temp.CopyToAsync(real);

                        if (finish > 0 && finish == outOf - 1)
                        {
                            real.SetLength(outOf);
                        }

                        //
                        // https://github.com/dotnet/corefx/blob/ec2a6190efa743ab600317f44d757433e44e859b/src/System.IO.FileSystem/src/System/IO/FileStream.Win32.cs#L1687
                        // Unlike Flush(), FlushAsync() always flushes to disk. This is intentional.
                        real.Flush();
                    }
                }
            }
            catch (IndexOutOfRangeException) {
                throw new ApiArgumentException(HeaderNames.ContentLength);
            }
            finally {
                _service.Delete(tempFilePath);
            }

            _context.Response.StatusCode = (int)HttpStatusCode.OK;
        }
Ejemplo n.º 2
0
        public MoveOperation Move(IFileInfo source, string dest, bool copy)
        {
            _fileService.EnsureAccess(source.Path, copy ? FileAccess.Read : FileAccess.ReadWrite);
            _fileService.EnsureAccess(dest, FileAccess.Write);

            IFileInfo destination = null;

            if (source.Type == FileType.File)
            {
                destination = _fileService.GetFile(dest);
                return(MoveFile(source, destination, copy));
            }
            else if (source.Type == FileType.Directory)
            {
                destination = _fileService.GetDirectory(dest);
                return(MoveDirectory(source, destination, copy));
            }

            throw new InvalidOperationException();
        }