Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        public async Task SendAsync()
        {
            ApplyResponseHeaders(Constants.Status200Ok);

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

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

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

            await copyOperation.Start();

            readStream.Close();
        }