Ejemplo n.º 1
0
        static void fromStream(HttpListenerRequest request, HttpListenerResponse response, Stream stream, string mime)
        {
            if (request.Headers.AllKeys.Count(x => x == BYTES_RANGE_HEADER) > 1)
            {
                throw new NotSupportedException("Multiple 'Range' headers are not supported.");
            }

            int start = 0, end = (int)stream.Length - 1;

            //partial stream response support
            var rangeStr = request.Headers[BYTES_RANGE_HEADER];

            if (rangeStr != null)
            {
                var range = rangeStr.Replace("bytes=", String.Empty)
                            .Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries)
                            .Select(x => Int32.Parse(x))
                            .ToArray();

                start = (range.Length > 0) ? range[0] : 0;
                end   = (range.Length > 1) ? range[1] : (int)(stream.Length - 1);

                response.WithHeader("Accept-Ranges", "bytes")
                .WithHeader("Content-Range", "bytes " + start + "-" + end + "/" + stream.Length)
                .WithCode(HttpStatusCode.PartialContent);

                response.KeepAlive = true;
            }

            //common properties
            response.WithContentType(mime);
            response.ContentLength64 = (end - start + 1);

            //data delivery
            try
            {
                stream.Position = start;
                stream.CopyTo(response.OutputStream, Math.Min(MAX_BUFFER_SIZE, end - start + 1));
            }
            catch (Exception ex) when(ex is HttpListenerException)  //request canceled
            {
                response.StatusCode = (int)HttpStatusCode.NoContent;
            }
            finally
            {
                stream.Close();
                response.Close();
            }
        }