Example #1
0
            // Not safe for overlapped writes.
            internal Task SendAsync(string fileName, long offset, long?length, CancellationToken cancel)
            {
                cancel.ThrowIfCancellationRequested();

                if (string.IsNullOrWhiteSpace(fileName))
                {
                    throw new ArgumentNullException("fileName");
                }
                if (!File.Exists(fileName))
                {
                    throw new FileNotFoundException(string.Empty, fileName);
                }

                var fileInfo = new FileInfo(fileName);

                if (offset < 0 || offset > fileInfo.Length)
                {
                    throw new ArgumentOutOfRangeException("offset", offset, string.Empty);
                }

                if (length.HasValue &&
                    (length.Value < 0 || length.Value > fileInfo.Length - offset))
                {
                    throw new ArgumentOutOfRangeException("length", length, string.Empty);
                }

                Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1024 * 64,
                                                   FileOptions.Asynchronous | FileOptions.SequentialScan);

                try
                {
                    fileStream.Seek(offset, SeekOrigin.Begin);
                    var copyOperation = new StreamCopyOperation(fileStream, _output, length, cancel);
                    return(copyOperation.Start()
                           .ContinueWith(resultTask =>
                    {
                        fileStream.Close();
                        resultTask.Wait();     // Throw exceptions, etc.
                    }, TaskContinuationOptions.ExecuteSynchronously));
                }
                catch (Exception)
                {
                    fileStream.Close();
                    throw;
                }
            }
Example #2
0
        // When there is only a single range the bytes are sent directly in the body.
        internal Task SendRangeAsync()
        {
            bool rangeNotSatisfiable = false;

            if (_ranges.Count == 0)
            {
                rangeNotSatisfiable = true;
            }

            if (rangeNotSatisfiable)
            {
                // 14.16 Content-Range - A server sending a response with status code 416 (Requested range not satisfiable)
                // SHOULD include a Content-Range field with a byte-range-resp-spec of "*". The instance-length specifies
                // the current length of the selected resource.  e.g. */length
                _response.Headers[Constants.ContentRange] = "bytes */" + _length.ToString(CultureInfo.InvariantCulture);
                ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
                return(Constants.CompletedTask);
            }

            // Multi-range is not supported.
            Debug.Assert(_ranges.Count == 1);

            long start, length;

            _response.Headers[Constants.ContentRange] = ComputeContentRange(_ranges[0], out start, out length);
            _response.ContentLength = length;
            ApplyResponseHeaders(Constants.Status206PartialContent);

            string       physicalPath = _fileInfo.PhysicalPath;
            SendFileFunc sendFile     = _response.Get <SendFileFunc>(Constants.SendFileAsyncKey);

            if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
            {
                return(sendFile(physicalPath, start, length, _request.CallCancelled));
            }

            Stream readStream = _fileInfo.CreateReadStream();

            readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
            var  copyOperation = new StreamCopyOperation(readStream, _response.Body, length, _request.CallCancelled);
            Task task          = copyOperation.Start();

            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return(task);
        }
Example #3
0
        public Task SendAsync()
        {
            ApplyResponseHeaders(Constants.Status200Ok);

            string       physicalPath = _fileInfo.PhysicalPath;
            SendFileFunc sendFile     = _response.Get <SendFileFunc>(Constants.SendFileAsyncKey);

            if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
            {
                return(sendFile(physicalPath, 0, _length, _request.CallCancelled));
            }

            Stream readStream    = _fileInfo.CreateReadStream();
            var    copyOperation = new StreamCopyOperation(readStream, _response.Body, _length, _request.CallCancelled);
            Task   task          = copyOperation.Start();

            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return(task);
        }
        public Task SendAsync(int statusCode)
        {
            _response.StatusCode = statusCode;
            _response.SetHeader(Constants.ContentLength, _length.ToString(CultureInfo.InvariantCulture));

            string physicalPath = _fileInfo.PhysicalPath;

            if (_response.CanSendFile && !string.IsNullOrEmpty(physicalPath))
            {
                return(_response.SendFileAsync(physicalPath, 0, _length, _request.CallCancelled));
            }

            Stream readStream    = _fileInfo.CreateReadStream();
            var    copyOperation = new StreamCopyOperation(readStream, _response.Body, _length, _request.CallCancelled);
            Task   task          = copyOperation.Start();

            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return(task);
        }
            // Not safe for overlapped writes.
            internal Task SendAsync(string fileName, long offset, long? length, CancellationToken cancel)
            {
                cancel.ThrowIfCancellationRequested();

                if (string.IsNullOrWhiteSpace(fileName))
                {
                    throw new ArgumentNullException("fileName");
                }
                if (!File.Exists(fileName))
                {
                    throw new FileNotFoundException(string.Empty, fileName);
                }

                var fileInfo = new FileInfo(fileName);
                if (offset < 0 || offset > fileInfo.Length)
                {
                    throw new ArgumentOutOfRangeException("offset", offset, string.Empty);
                }

                if (length.HasValue &&
                    (length.Value < 0 || length.Value > fileInfo.Length - offset))
                {
                    throw new ArgumentOutOfRangeException("length", length, string.Empty);
                }

                Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1024 * 64,
                    FileOptions.Asynchronous | FileOptions.SequentialScan);
                try
                {
                    fileStream.Seek(offset, SeekOrigin.Begin);
                    var copyOperation = new StreamCopyOperation(fileStream, _output, length, cancel);
                    return copyOperation.Start()
                        .ContinueWith(resultTask =>
                        {
                            fileStream.Close();
                            resultTask.Wait(); // Throw exceptions, etc.
                        }, TaskContinuationOptions.ExecuteSynchronously);
                }
                catch (Exception)
                {
                    fileStream.Close();
                    throw;
                }
            }
Example #6
0
        public Task SendAsync(int statusCode)
        {
            _response.StatusCode = statusCode;
            _response.SetHeader(Constants.ContentLength, _length.ToString(CultureInfo.InvariantCulture));

            string physicalPath = _fileInfo.PhysicalPath;
            if (_response.CanSendFile && !string.IsNullOrEmpty(physicalPath))
            {
                return _response.SendFileAsync(physicalPath, 0, _length, _request.CallCancelled);
            }

            Stream readStream = _fileInfo.CreateReadStream();
            var copyOperation = new StreamCopyOperation(readStream, _response.Body, _length, _request.CallCancelled);
            Task task = copyOperation.Start();
            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return task;
        }
        // When there is only a single range the bytes are sent directly in the body.
        internal Task SendRangeAsync()
        {
            bool rangeNotSatisfiable = false;
            if (_ranges.Count == 0)
            {
                rangeNotSatisfiable = true;
            }

            if (rangeNotSatisfiable)
            {
                // 14.16 Content-Range - A server sending a response with status code 416 (Requested range not satisfiable)
                // SHOULD include a Content-Range field with a byte-range-resp-spec of "*". The instance-length specifies
                // the current length of the selected resource.  e.g. */length
                _response.Headers[Constants.ContentRange] = "bytes */" + _length.ToString(CultureInfo.InvariantCulture);
                ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
                return Constants.CompletedTask;
            }

            // Multi-range is not supported.
            Debug.Assert(_ranges.Count == 1);

            long start, length;
            _response.Headers[Constants.ContentRange] = ComputeContentRange(_ranges[0], out start, out length);
            _response.ContentLength = length;
            ApplyResponseHeaders(Constants.Status206PartialContent);

            string physicalPath = _fileInfo.PhysicalPath;
            SendFileFunc sendFile = _response.Get<SendFileFunc>(Constants.SendFileAsyncKey);
            if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
            {
                return sendFile(physicalPath, start, length, _request.CallCancelled);
            }

            Stream readStream = _fileInfo.CreateReadStream();
            readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
            var copyOperation = new StreamCopyOperation(readStream, _response.Body, length, _request.CallCancelled);
            Task task = copyOperation.Start();
            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return task;
        }
        public Task SendAsync()
        {
            ApplyResponseHeaders(Constants.Status200Ok);

            string physicalPath = _fileInfo.PhysicalPath;
            SendFileFunc sendFile = _response.Get<SendFileFunc>(Constants.SendFileAsyncKey);
            if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
            {
                return sendFile(physicalPath, 0, _length, _request.CallCancelled);
            }

            Stream readStream = _fileInfo.CreateReadStream();
            var copyOperation = new StreamCopyOperation(readStream, _response.Body, _length, _request.CallCancelled);
            Task task = copyOperation.Start();
            task.ContinueWith(resultTask => readStream.Close(), TaskContinuationOptions.ExecuteSynchronously);
            return task;
        }