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