예제 #1
0
        public void RangeHeader_Reports_Syntactically_Invalid_Byte_Ranges()
        {
            Assert.IsFalse(RangeHeader.IsValid(CreateHeadersWithRange("")));
            Assert.IsFalse(RangeHeader.IsValid(CreateHeadersWithRange("foobar")));
            Assert.IsFalse(RangeHeader.IsValid(CreateHeadersWithRange("furlongs=123-456")));
            Assert.IsFalse(RangeHeader.IsValid(CreateHeadersWithRange("bytes=")));
            Assert.IsFalse(RangeHeader.IsValid(CreateHeadersWithRange("")));

            // A range of non-positive length is syntactically invalid and ignored:
            Assert.IsNull(CreateByteRanges("bytes=123,456", 500));
            Assert.IsNull(CreateByteRanges("bytes=456-123", 500));
            Assert.IsNull(CreateByteRanges("bytes=456-455", 500));
        }
예제 #2
0
        private Task Serve(IDictionary <string, object> env)
        {
            Request  request  = new Request(env);
            Response response = new Response(env);

            var fileInfo = new FileInfo(path);
            var size     = fileInfo.Length;

            if (!RangeHeader.IsValid(request.Headers))
            {
                response.StatusCode = OK;
                range = new Tuple <long, long>(0, size - 1);
            }
            else
            {
                var ranges = RangeHeader.Parse(request.Headers, size);

                if (ranges == null)
                {
                    // Unsatisfiable.  Return error and file size.
                    return(Fail(
                               RequestedRangeNotSatisfiable,
                               "Byte range unsatisfiable",
                               "Content-Range", "bytes */" + size)
                           .Invoke(env));
                }

                if (ranges.Count() > 1)
                {
                    // TODO: Support multiple byte ranges.
                    response.StatusCode = OK;
                    range = new Tuple <long, long>(0, size - 1);
                }
                else
                {
                    // Partial content
                    range = ranges.First();
                    response.StatusCode = PartialContent;
                    response.Headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size);
                    size = range.Item2 - range.Item1 + 1;
                }
            }

            response.Headers
            .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString())
            .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain"))
            .SetHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture));

            return(new FileBody(path, range).Start(response.OutputStream));
        }
예제 #3
0
파일: FileServer.cs 프로젝트: hanishi/gate
        private Task Serve(IDictionary <string, object> env, string path)
        {
            Request  request  = new Request(env);
            Response response = new Response(env);

            var fileInfo = new FileInfo(path);
            var size     = fileInfo.Length;
            Tuple <long, long> range;

            if (!RangeHeader.IsValid(request.Headers))
            {
                response.StatusCode = OK;
                range = new Tuple <long, long>(0, size - 1);
            }
            else
            {
                var ranges = RangeHeader.Parse(request.Headers, size);

                if (ranges == null)
                {
                    // Unsatisfiable.  Return error and file size.
                    return(Fail(
                               RequestedRangeNotSatisfiable,
                               "Byte range unsatisfiable",
                               "Content-Range", "bytes */" + size)
                           .Invoke(env));
                }

                if (ranges.Count() > 1)
                {
                    // TODO: Support multiple byte ranges.
                    response.StatusCode = OK;
                    range = new Tuple <long, long>(0, size - 1);
                }
                else
                {
                    // Partial content
                    range = ranges.First();
                    response.StatusCode = PartialContent;
                    response.Headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size);
                    size = range.Item2 - range.Item1 + 1;
                }
            }

            response.Headers
            .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString())
            .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain"))
            .SetHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture));

            if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase))
            {
                // Suppress the body.
                return(TaskHelpers.Completed());
            }

            FileBody body = new FileBody(path, range);

            //TODO: update for current send file spec
            //var req = new Request(env);
            //SendFileFunc sendFile = env.Get<SendFileFunc>("sendfile.Func");
            //if (sendFile != null)
            //{
            //    return body.Start(sendFile);
            //}

            return(body.Start(response.OutputStream));
        }