예제 #1
0
        private void WriteOutput(string contentType, ref Stream outputStream, bool sendAsCompressed)
        {
            this.Context.Response.Header.AddOrUpdate("Content-Type", contentType);

            if (sendAsCompressed)
            {
                Stream gzippedStream = null;
                try
                {
                    Xeora.CompressUnsafe(ref outputStream, out gzippedStream);

                    if (gzippedStream != null && gzippedStream.Length < outputStream.Length)
                    {
                        this.Context.Response.Header.AddOrUpdate("Content-Encoding", "gzip");
                        this.WriteToSocketUnsafe(ref gzippedStream);

                        return;
                    }
                }
                finally
                {
                    gzippedStream?.Close();
                }
            }

            this.Context.Response.Header.AddOrUpdate("Content-Encoding", "identity");
            this.WriteToSocketUnsafe(ref outputStream);
        }
예제 #2
0
        public Basics.IHandler Create(ref IHttpContext context)
        {
            Monitor.Enter(this._RefreshLock);
            try
            {
                Basics.IHandler handler =
                    new Xeora(ref context, this._Refresh);
                this._Refresh = false;

                this._Handlers.TryAdd(handler.HandlerId, new Container(ref handler));

                return(handler);
            }
            finally
            {
                Monitor.Exit(this._RefreshLock);
            }
        }
예제 #3
0
        private void PostRequestedStaticFileToClient()
        {
            string requestFilePath =
                string.Concat(
                    Configurations.Xeora.Application.Main.PhysicalRoot,
                    this.Context.Request.Header.Url.RelativePath
                    );

            requestFilePath = Path.GetFullPath(requestFilePath);

            string contentType =
                MimeType.GetMime(Path.GetExtension(requestFilePath));

            if (!File.Exists(requestFilePath) ||
                File.Exists(requestFilePath) && Xeora.IsRequestedStaticFileBanned(requestFilePath))
            {
                this.Context.Response.Header.AddOrUpdate("Content-Type", contentType);
                this.Context.Response.Header.Status.Code = 404;
                this.Context.AddOrUpdate("RedirectLocation", null);

                return;
            }

            string range            = this.Context.Request.Header["Range"];
            bool   isPartialRequest = !string.IsNullOrEmpty(range);

            Stream requestFileStream = null;

            if (!isPartialRequest)
            {
                this.Context.Response.Header.AddOrUpdate("Accept-Ranges", "bytes");

                try
                {
                    requestFileStream = new FileStream(requestFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                    this.Context.Response.Header.AddOrUpdate("Content-Length", requestFileStream.Length.ToString());

                    this.WriteOutput(contentType, ref requestFileStream, false);
                }
                finally
                {
                    requestFileStream?.Close();
                }

                this.Context.AddOrUpdate("RedirectLocation", null);

                return;
            }

            long beginRange = 0, endRange = -1;

            if (range.IndexOf("bytes=", StringComparison.InvariantCulture) == 0)
            {
                range = range.Remove(0, "bytes=".Length);
                try
                {
                    if (!long.TryParse(range.Split('-')[0], out beginRange))
                    {
                        beginRange = 0;
                    }
                    if (!long.TryParse(range.Split('-')[1], out endRange))
                    {
                        endRange = -1;
                    }
                }
                catch (Exception)
                {
                    this.Context.Response.Header.Status.Code = 416;
                    this.Context.AddOrUpdate("RedirectLocation", null);

                    return;
                }
            }

            try
            {
                requestFileStream =
                    new FileStream(requestFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                if (endRange == -1)
                {
                    endRange = requestFileStream.Length - 1;
                }

                long requestingLength = endRange - beginRange + 1;

                if (endRange > requestFileStream.Length - 1 || beginRange > endRange)
                {
                    this.Context.Response.Header.Status.Code = 416;
                    this.Context.AddOrUpdate("RedirectLocation", null);

                    return;
                }

                this.Context.Response.Header.Status.Code = 206;
                this.Context.Response.Header.AddOrUpdate("Content-Type", contentType);
                this.Context.Response.Header.AddOrUpdate("Content-Encoding", "identity");
                this.Context.Response.Header.AddOrUpdate("Content-Range",
                                                         $"bytes {beginRange}-{endRange}/{requestFileStream.Length}");
                this.Context.Response.Header.AddOrUpdate("Content-Length", requestingLength.ToString());

                requestFileStream.Seek(beginRange, SeekOrigin.Begin);

                byte[] buffer = new byte[102400];
                int    bR;
                do
                {
                    bR = requestFileStream.Read(buffer, 0, buffer.Length);

                    if (requestingLength < bR)
                    {
                        bR = (int)requestingLength;
                    }

                    this.Context.Response.Write(buffer, 0, bR);

                    requestingLength -= bR;
                } while (requestingLength != 0 && bR != 0);
            }
            finally
            {
                requestFileStream?.Close();
            }

            this.Context.AddOrUpdate("RedirectLocation", null);
        }