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); }
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); } }
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); }