/// <summary> /// Begin Async And Chunk Write, You Need Invoke EndWrite /// </summary> /// <exception cref="InvalidOperationException">Has been invoked</exception> public void BeginWrite() { if (this.chunkWriteEvent != null) { throw new InvalidOperationException("Has been invoked"); } this.chunkWriteEvent = new ManualResetEvent(false); this.chunkWriteStatus = HttpServerChunkStatus.Writing; if (this.acceptGzip && this.gzipThreshold != 0) { this.chunkStream = new MemoryStream(); this.chunkGzipStream = new GZipStream(this.chunkStream, CompressionMode.Compress, true); } this.Response(HttpStatusCode.OK); }
/// <summary> /// initialize new instance /// </summary> /// <param name="socket"></param> /// <param name="header"></param> /// <param name="server"></param> /// <param name="url"></param> /// <param name="method"></param> /// <param name="protocol"></param> /// <param name="maxRequestContentLength"></param> /// <param name="fileHandler"></param> internal HttpServerContext(Socket socket, NameValueCollection header, HttpServer server, string url, string method, string protocol, int maxRequestContentLength, IHttpServerFileHandler fileHandler) : base(header, server, url, method, protocol) { var version = 0d; try { double.TryParse(protocol.Split('/')[1], out version); } catch { } //Connection: keep-alive var keepAlive = header["Connection"] ?? string.Empty; if ("POST".Equals(method, StringComparison.OrdinalIgnoreCase)) { this.keepAlive = false; } else if ("keep-alive".Equals(keepAlive, StringComparison.OrdinalIgnoreCase)) { this.keepAlive = true; } else if ("close".Equals(keepAlive, StringComparison.OrdinalIgnoreCase)) { this.keepAlive = false; } else if (version > 1.0) { this.keepAlive = true; } //this.ResponseHeader.Add("Date", DateTime.Now.ToString("r")); //this.ResponseHeader.Add("Connection", this.KeepAlive ? "keep-alive" : "Close"); this.ResponseHeader.Add("Content-Type", "text/html"); this.socket = socket; this.contentBuffer = null; this.chunkWriteStatus = HttpServerChunkStatus.NoBegin; base.RequestType = HttpServerRequestType.Http; this.maxRequestContentLength = maxRequestContentLength; this.FileHandler = fileHandler; this.isRequestHead = method.Equals("HEAD", StringComparison.OrdinalIgnoreCase); this.acceptGzip = this.isRequestHead == false && (header["Accept-Encoding"] ?? "").IndexOf("gzip", StringComparison.OrdinalIgnoreCase) != -1; // var authorization = header["Authorization"]; if (string.IsNullOrEmpty(authorization) == false && authorization.StartsWith("Basic ") && authorization.Length > 6) { this.ParseAuthorize(authorization); } }
/// <summary> /// End Write /// </summary> /// <exception cref="InvalidOperationException">No Invoke BeginWrite / Has Been Invoked EndWrite</exception> public void EndWrite() { lock (this.chunkWriteEvent) { if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin) { throw new InvalidOperationException("No Invoke BeginWrite"); } if (this.chunkWriteStatus == HttpServerChunkStatus.End) { throw new InvalidOperationException("Has Been Invoked EndWrite"); } if (this.chunkWriteStatus == HttpServerChunkStatus.Writing) { this.chunkWriteStatus = HttpServerChunkStatus.End; try { //gzip if (this.acceptGzip && this.gzipThreshold != 0) { this.CloseChunkGzip(); } if (this.isRequestHead == false) { var crlfBuffer = this.Encoding.GetBytes("\r\n"); var buffers = new ArraySegment <byte> [3]; using (var m = new MemoryStream(512)) { //len var lenBuffer = this.Encoding.GetBytes("0"); buffers[0] = new ArraySegment <byte>(lenBuffer); buffers[1] = new ArraySegment <byte>(crlfBuffer); //content buffers[2] = new ArraySegment <byte>(crlfBuffer); } // try { this.socket.Send(buffers); } catch { SocketHelper.TryClose(this.socket); throw; } finally { StreamHelper.TryClose(this.chunkGzipStream); StreamHelper.TryClose(this.chunkStream); this.chunkWriteEvent.Set(); } } else { this.chunkWriteEvent.Set(); } } catch (Exception exception) { throw new InvalidOperationException("End check write failure", exception); } } } }