private async Task<CoreResponseData> ReadResponseAsync(Connection connection) { _readState = ReadState.Start; var requestDone = false; var bytesScanned = 0; var readBuffer = new ArraySegment<byte>(); var buffer_offset = connection.Buffer.Offset; var buffer_length = connection.Buffer.Length; while (!requestDone) { if (this.Aborted) { throw new OperationCanceledException("The request was canceled."); } readBuffer = await connection.ReadPooledBufferAsync(buffer_offset, buffer_length); var bytesRead = readBuffer.Count; if (bytesRead == 0) { //connection is closed by the remote host. break; } bytesScanned = 0; var parseStatus = this.ParseResponseData(readBuffer, ref bytesScanned, ref requestDone); if (parseStatus == DataParseStatus.Invalid || parseStatus == DataParseStatus.DataTooBig) { if (parseStatus == DataParseStatus.Invalid) { throw new HttpResponseException("Cannot correct to parse the server response.",WebExceptionStatus.ServerProtocolViolation); } else { throw new HttpResponseException("The server response buffer limit exceeded.", WebExceptionStatus.MessageLengthLimitExceeded); } } else if (parseStatus == DataParseStatus.NeedMoreData) { var unparsedDataSize = bytesRead - bytesScanned; if (unparsedDataSize > 0) { if (unparsedDataSize >= BufferPool.DefaultBufferLength) { throw new IOException("unparsed size exceeded the buffer length."); } Buffer.BlockCopy(connection.Buffer.Array, bytesScanned, connection.Buffer.Array, connection.Buffer.Offset, unparsedDataSize); buffer_offset = unparsedDataSize; buffer_length -= unparsedDataSize; } } else { buffer_length = connection.Buffer.Length; buffer_offset = connection.Buffer.Offset; } } //if (!requestDone) //{ // throw new HttpRequestException("The request not finished."); //} if (_cookieContainer != null) { _cookieContainer.SetCookies(_uri, _responseHeaders.SetCookie); } if (this.CheckRedirect((HttpStatusCode)_statusLineValues.StatusCode)) { if (_redirectedToDifferentHost) { var previous_connection = connection; connection = this.FindServicePoint(true).SubmitRequest(this); previous_connection.Close(true); } return await this.SendRequestAsync(connection); } var connectStream = this.CreateResponseStream(connection, readBuffer, bytesScanned); return new CoreResponseData(_statusLineValues, _responseHeaders, connectStream); }