protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                Connections.Remove(NativeId);
                XHR_Release(NativeId);

                Stream = null;
            }
        }
        private void EncodePackets(System.Collections.Generic.List <OutgoingPacket> packets, HTTPRequest request)
        {
            sendBuilder.Length = 0;

            for (int i = 0; i < packets.Count; ++i)
            {
                var packet = packets[i];

                if (packet.IsBinary)
                {
                    sendBuilder.Append('b');
                    sendBuilder.Append(Convert.ToBase64String(packet.PayloadData.Data, packet.PayloadData.Offset, packet.PayloadData.Count));
                }
                else
                {
                    sendBuilder.Append(packet.Payload);
                }

                if (packet.Attachements != null)
                {
                    for (int cv = 0; cv < packet.Attachements.Count; ++cv)
                    {
                        sendBuilder.Append((char)0x1E);
                        sendBuilder.Append('b');

                        sendBuilder.Append(Convert.ToBase64String(packet.Attachements[cv]));
                    }
                }

                if (i < packets.Count - 1)
                {
                    sendBuilder.Append((char)0x1E);
                }
            }

            string result = sendBuilder.ToString();
            var    length = System.Text.Encoding.UTF8.GetByteCount(result);
            var    buffer = BufferPool.Get(length, true);

            System.Text.Encoding.UTF8.GetBytes(result, 0, result.Length, buffer, 0);

            var stream = new BufferSegmentStream();

            stream.Write(new BufferSegment(buffer, 0, length));

            request.UploadStream = stream;
            request.SetHeader("Content-Type", "text/plain; charset=UTF-8");
        }
        void OnResponse(int httpStatus, BufferSegment payload)
        {
            HTTPConnectionStates proposedConnectionState = HTTPConnectionStates.Processing;
            bool resendRequest = false;

            try
            {
                if (this.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                using (var ms = new BufferSegmentStream())
                {
                    Stream = ms;

                    XHR_GetStatusLine(NativeId, OnBufferCallback);
                    XHR_GetResponseHeaders(NativeId, OnBufferCallback);

                    if (payload != BufferSegment.Empty)
                    {
                        ms.Write(payload);
                    }

                    SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler;
                    CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, ms, CurrentRequest.UseStreaming, false);

                    CurrentRequest.Response.Receive(payload != BufferSegment.Empty && payload.Count > 0 ? (int)payload.Count : -1, true);

                    KeepAliveHeader keepAlive = null;
                    ConnectionHelper.HandleResponse(this.ToString(), this.CurrentRequest, out resendRequest, out proposedConnectionState, ref keepAlive);
                }
            }
            catch (Exception e)
            {
                HTTPManager.Logger.Exception(this.NativeId + " WebGLConnection", "OnResponse", e, this.Context);

                if (this.ShutdownType == ShutdownTypes.Immediate)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                if (this.CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(this.CurrentRequest.CurrentUri);
                }
#endif

                // Something gone bad, Response must be null!
                this.CurrentRequest.Response = null;

                if (!this.CurrentRequest.IsCancellationRequested)
                {
                    this.CurrentRequest.Exception = e;
                    this.CurrentRequest.State     = HTTPRequestStates.Error;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            finally
            {
                // Exit ASAP
                if (this.ShutdownType != ShutdownTypes.Immediate)
                {
                    if (this.CurrentRequest.IsCancellationRequested)
                    {
                        // we don't know what stage the request is cancelled, we can't safely reuse the tcp channel.
                        proposedConnectionState = HTTPConnectionStates.Closed;

                        this.CurrentRequest.Response = null;

                        this.CurrentRequest.State = this.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                    }
                    else if (resendRequest)
                    {
                        RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.CurrentRequest, RequestEvents.Resend));
                    }
                    else if (this.CurrentRequest.Response != null && this.CurrentRequest.Response.IsUpgraded)
                    {
                        proposedConnectionState = HTTPConnectionStates.WaitForProtocolShutdown;
                    }
                    else if (this.CurrentRequest.State == HTTPRequestStates.Processing)
                    {
                        if (this.CurrentRequest.Response != null)
                        {
                            this.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        else
                        {
                            this.CurrentRequest.Exception = new Exception(string.Format("[{0}] Remote server closed the connection before sending response header! Previous request state: {1}. Connection state: {2}",
                                                                                        this.ToString(),
                                                                                        this.CurrentRequest.State.ToString(),
                                                                                        this.State.ToString()));
                            this.CurrentRequest.State = HTTPRequestStates.Error;

                            proposedConnectionState = HTTPConnectionStates.Closed;
                        }
                    }

                    this.CurrentRequest = null;

                    if (proposedConnectionState == HTTPConnectionStates.Processing)
                    {
                        proposedConnectionState = HTTPConnectionStates.Closed;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, proposedConnectionState));
                }
            }
        }