private void CloseChunkGzip() { var crlfBuffer = this.Encoding.GetBytes("\r\n"); var buffers = new ArraySegment <byte> [4]; // //gzip this.chunkGzipStream.Close(); var contentLength = (int)this.chunkStream.Length; this.chunkStream.Position = 0; contentBuffer = StreamHelper.Receive(this.chunkStream, contentLength); this.chunkStream.SetLength(0); //len var lenBuffer = this.Encoding.GetBytes(contentLength.ToString("x")); buffers[0] = new ArraySegment <byte>(lenBuffer); buffers[1] = new ArraySegment <byte>(crlfBuffer); //content buffers[2] = new ArraySegment <byte>(contentBuffer); buffers[3] = new ArraySegment <byte>(crlfBuffer); // try { this.socket.Send(buffers); } catch { SocketHelper.TryClose(this.socket); StreamHelper.TryClose(this.chunkGzipStream); StreamHelper.TryClose(this.chunkStream); this.chunkWriteEvent.Set(); throw; } }
private void NewAccept(IAsyncResult ar) { Socket socket = null; try { socket = this.listenSocket.EndAccept(ar); } catch { } //new accept try { this.listenSocket.BeginAccept(this.NewAccept, null); } catch (ObjectDisposedException) { } // if (socket != null) { try { ConnectionState connectionState; //keep alive while (true) { connectionState = this.NewConnection(socket); if (connectionState == ConnectionState.KeepAlive) { //next request } else if (connectionState == ConnectionState.Closed) { //close and exit SocketHelper.TryClose(socket); break; } else if (connectionState == ConnectionState.KeepConnection) { //keep connection & exit break; } } } catch (SocketException) { SocketHelper.TryClose(socket); } catch (Exception exception) { SocketHelper.TryClose(socket); this.OnError(exception); } } }
/// <summary> /// Write Chunk Content /// </summary> /// <param name="contentBuffer"></param> private void Chunk(byte[] contentBuffer) { lock (this.chunkWriteEvent) { var crlfBuffer = this.Encoding.GetBytes("\r\n"); var buffers = new ArraySegment <byte> [4]; // int contentLength = contentBuffer.Length; //gzip if (this.acceptGzip && this.gzipThreshold != 0) { this.chunkGzipStream.Write(contentBuffer, 0, contentBuffer.Length); contentLength = (int)this.chunkStream.Length; if (contentLength < 256) { //小字节退出,待下次压缩或关闭压缩 return; } this.chunkStream.Position = 0; contentBuffer = StreamHelper.Receive(this.chunkStream, contentLength); this.chunkStream.SetLength(0); } //len var lenBuffer = this.Encoding.GetBytes(contentLength.ToString("x")); buffers[0] = new ArraySegment <byte>(lenBuffer); buffers[1] = new ArraySegment <byte>(crlfBuffer); //content buffers[2] = new ArraySegment <byte>(contentBuffer); buffers[3] = new ArraySegment <byte>(crlfBuffer); // try { this.socket.Send(buffers); } catch { SocketHelper.TryClose(this.socket); StreamHelper.TryClose(this.chunkGzipStream); StreamHelper.TryClose(this.chunkStream); this.chunkWriteEvent.Set(); throw; } } }
/// <summary> /// connect to host /// </summary> /// <param name="socket"></param> /// <param name="timeout"></param> /// <param name="host"></param> /// <param name="port"></param> /// <exception cref="System.TimeoutException">connect timeout</exception> public static void Connect(Socket socket, string host, int port, int timeout) { using (var eventHandle = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset)) { socket.BeginConnect(host, port, ar2 => { try { socket.EndConnect(ar2); // eventHandle.Set(); } catch { } }, null); // if (eventHandle.WaitOne(timeout) == false) { SocketHelper.TryClose(socket); throw new TimeoutException("Connect to " + host + ":" + port + " timeout."); } } }
/// <summary> /// 响应客户端 /// </summary> /// <param name="build"></param> /// <param name="status"></param> protected override void Response(StringBuilder build, HttpStatusCode status) { byte[] contentBuffer = null; byte[] headerBuffer = null; //header if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin) { if (this.contentBuffer != null) { contentBuffer = this.contentBuffer; } else if (!string.IsNullOrEmpty(this.content)) { contentBuffer = this.Encoding.GetBytes(this.content); } else { contentBuffer = new byte[0]; } //gzip if (this.acceptGzip && this.gzipThreshold != 0 && contentBuffer.Length > this.gzipThreshold) { build.AppendLine("Content-Encoding: gzip"); using (var m = new MemoryStream()) using (var stream = new GZipStream(m, CompressionMode.Compress, true)) { stream.Write(contentBuffer, 0, contentBuffer.Length); stream.Close(); //content contentBuffer = m.ToArray(); } } build.AppendLine(string.Concat("Content-Length: ", contentBuffer.Length)); build.AppendLine(); } else { if (this.acceptGzip && this.gzipThreshold != 0) { build.AppendLine("Content-Encoding: gzip"); } build.AppendLine("Transfer-Encoding: chunked"); build.AppendLine(); } headerBuffer = Encoding.ASCII.GetBytes(build.ToString()); // if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin) { if (this.isRequestHead == false && contentBuffer != null && contentBuffer.Length > 0) { var buffers = new ArraySegment <byte> [2]; //header buffers[0] = new ArraySegment <byte>(headerBuffer); //content buffers[1] = new ArraySegment <byte>(contentBuffer); //send this.socket.Send(buffers); } else { this.socket.Send(headerBuffer); } } else { try { this.socket.Send(headerBuffer); } catch { SocketHelper.TryClose(this.socket); StreamHelper.TryClose(this.chunkGzipStream); StreamHelper.TryClose(this.chunkStream); throw; } } }
/// <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); } } } }