internal void ResetAll()
        {
            headerStBuilder.Length = 0;
            StatusCode             = 200;

            isSend                  = false;
            TransferEncoding        = ResponseTransferEncoding.Identity;
            writeContentState       = WriteContentState.HttpHead;
            ContentType             = WebResponseContentType.TextPlain;//reset content type
            ContentEncoding         = ContentEncoding.Plain;
            this.ContentTypeCharSet = TextCharSet.Utf8;
            AllowCrossOriginPolicy  = null;
            headers.Clear();
            ResetWritingBuffer();
        }
        public void ActualEnd()
        {
            switch (_writeContentState)
            {
            //generate head
            case WriteContentState.HttpHead:
            {
                _headerStBuilder.Length = 0;
                _headerStBuilder.Append("HTTP/1.1 ");
                HeaderAppendStatusCode(_headerStBuilder, StatusCode);
                HeaderAppendConnectionType(_headerStBuilder, this.KeepAlive);
                //--------------------------------------------------------------------------------------------------------
                _headerStBuilder.Append("Content-Type: " + GetContentType(this.ContentType));
                switch (ContentTypeCharSet)
                {
                case TextCharSet.Utf8:
                    _headerStBuilder.Append(" ; charset=utf-8\r\n");
                    break;

                case TextCharSet.Ascii:
                    _headerStBuilder.Append("\r\n");
                    break;

                default:
                    throw new NotSupportedException();
                }
                if (_headers.Count > 0)
                {
                    foreach (var kv in _headers)
                    {
                        _headerStBuilder.Append(kv.Key);
                        _headerStBuilder.Append(": ");
                        _headerStBuilder.Append(kv.Value);
                        _headerStBuilder.Append("\r\n");
                    }
                }

                //--------------------------------------------------------------------------------------------------------
                switch (ContentEncoding)
                {
                case ContentEncoding.Plain:
                    //nothing
                    break;

                case ContentEncoding.Gzip:
                    _headerStBuilder.Append("Content-Encoding: gzip\r\n");
                    break;

                default:
                    throw new NotSupportedException();
                }
                //--------------------------------------------------------------------------------------------------------
                //Access-Control-Allow-Origin
                if (AllowCrossOriginPolicy != null)
                {
                    AllowCrossOriginPolicy.WriteHeader(_headerStBuilder);
                }
                //--------------------------------------------------------------------------------------------------------
                switch (this.TransferEncoding)
                {
                default:
                case ResponseTransferEncoding.Identity:
                {
                    _headerStBuilder.Append("Content-Length: ");
                    _headerStBuilder.Append(_contentByteCount);
                    _headerStBuilder.Append("\r\n");
                    //-----------------------------------------------------------------
                    _headerStBuilder.Append("\r\n");                //end header part
                    _writeContentState = WriteContentState.HttpBody;
                    //-----------------------------------------------------------------
                    //switch transfer encoding method of the body***
                    byte[] headBuffer = Encoding.UTF8.GetBytes(_headerStBuilder.ToString().ToCharArray());
                    byte[] dataToSend = new byte[headBuffer.Length + _contentByteCount];
                    Buffer.BlockCopy(headBuffer, 0, dataToSend, 0, headBuffer.Length);
                    var pos = _bodyMs.Position;
                    _bodyMs.Position = 0;
                    _bodyMs.Read(dataToSend, headBuffer.Length, _contentByteCount);
                    //----------------------------------------------------
                    //copy data to send buffer

                    _sendIO.EnqueueSendingData(dataToSend, dataToSend.Length);
                    //----------------------------------------------------
                    ResetAll();
                }
                break;

                case ResponseTransferEncoding.Chunked:
                {
                    _headerStBuilder.Append("Transfer-Encoding: " + GetTransferEncoding(TransferEncoding) + "\r\n");
                    _headerStBuilder.Append("\r\n");
                    _writeContentState = WriteContentState.HttpBody;

                    //chunked transfer
                    byte[] headBuffer = Encoding.UTF8.GetBytes(_headerStBuilder.ToString().ToCharArray());

                    _sendIO.EnqueueSendingData(headBuffer, headBuffer.Length);
                    WriteContentBodyInChunkMode();
                    ResetAll();
                }
                break;
                }
            }
            break;

            //==============================
            case WriteContentState.HttpBody:
            {
                //in chunked case,
                WriteContentBodyInChunkMode();
                ResetAll();
            }
            break;

            default:
            {
                throw new NotSupportedException();
            }
            }

            //-----------------------
            //send
            StartSend();
        }
        public void End()
        {
            switch (writeContentState)
            {
                //generate head 
                case WriteContentState.HttpHead:
                    {
                        headerStBuilder.Length = 0;
                        headerStBuilder.Append("HTTP/1.1 ");
                        HeaderAppendStatusCode(headerStBuilder, StatusCode);
                        HeaderAppendConnectionType(headerStBuilder, this.context.KeepAlive);
                        //--------------------------------------------------------------------------------------------------------
                        headerStBuilder.Append("Content-Type: " + GetContentType(this.ContentType));
                        switch (ContentTypeCharSet)
                        {
                            case TextCharSet.Utf8:
                                headerStBuilder.Append(" ; charset=utf-8\r\n");
                                break;
                            case TextCharSet.Ascii:
                                headerStBuilder.Append("\r\n");
                                break;
                            default:
                                throw new NotSupportedException();
                        }
                        //--------------------------------------------------------------------------------------------------------
                        switch (ContentEncoding)
                        {
                            case WebServers.ContentEncoding.Plain:
                                //nothing
                                break;
                            case WebServers.ContentEncoding.Gzip:
                                headerStBuilder.Append("Content-Encoding: gzip\r\n");
                                break;
                            default:
                                throw new NotSupportedException();
                        }
                        //--------------------------------------------------------------------------------------------------------
                        //Access-Control-Allow-Origin
                        if (AllowCrossOriginPolicy != null)
                        {
                            AllowCrossOriginPolicy.WriteHeader(headerStBuilder);
                        }
                        //--------------------------------------------------------------------------------------------------------
                        switch (this.TransferEncoding)
                        {
                            default:
                            case ResponseTransferEncoding.Identity:
                                {
                                    headerStBuilder.Append("Content-Length: ");
                                    headerStBuilder.Append(contentByteCount);
                                    headerStBuilder.Append("\r\n");
                                    //-----------------------------------------------------------------                                    
                                    headerStBuilder.Append("\r\n");//end header part                                     
                                    writeContentState = WriteContentState.HttpBody;
                                    //-----------------------------------------------------------------
                                    //switch transfer encoding method of the body***
                                    var headBuffer = Encoding.UTF8.GetBytes(headerStBuilder.ToString().ToCharArray());
                                    byte[] dataToSend = new byte[headBuffer.Length + contentByteCount];
                                    Buffer.BlockCopy(headBuffer, 0, dataToSend, 0, headBuffer.Length);
                                    var pos = bodyMs.Position;
                                    bodyMs.Position = 0;
                                    bodyMs.Read(dataToSend, headBuffer.Length, contentByteCount);
                                    //----------------------------------------------------
                                    //copy data to send buffer
                                    sendIO.EnqueueOutputData(dataToSend, dataToSend.Length);

                                    //---------------------------------------------------- 
                                    ResetAll();
                                }
                                break;
                            case ResponseTransferEncoding.Chunked:
                                {
                                    headerStBuilder.Append("Transfer-Encoding: " + GetTransferEncoding(TransferEncoding) + "\r\n");
                                    headerStBuilder.Append("\r\n");
                                    writeContentState = WriteContentState.HttpBody;

                                    //chunked transfer
                                    var headBuffer = Encoding.UTF8.GetBytes(headerStBuilder.ToString().ToCharArray());
                                    sendIO.EnqueueOutputData(headBuffer, headBuffer.Length);
                                    WriteContentBodyInChunkMode();
                                    ResetAll();
                                }
                                break;
                        }
                    }
                    break;
                //==============================
                case WriteContentState.HttpBody:
                    {
                        //in chunked case, 
                        WriteContentBodyInChunkMode();
                        ResetAll();
                    }
                    break;
                default:
                    {
                        throw new NotSupportedException();
                    }
            }

            //-----------------------
            //send 

            StartSend();
        }
        internal void ResetAll()
        {
            headerStBuilder.Length = 0;
            StatusCode = 200;

            isSend = false;
            TransferEncoding = ResponseTransferEncoding.Identity;
            writeContentState = WriteContentState.HttpHead;
            ContentType = WebResponseContentType.TextPlain;//reset content type
            ContentEncoding = ContentEncoding.Plain;
            this.ContentTypeCharSet = TextCharSet.Utf8;
            AllowCrossOriginPolicy = null;
            headers.Clear();
            ResetWritingBuffer();
        }