async Task Initialize(BufferOffsetSize buffer, CancellationToken cancellationToken) { WebConnection.Debug($"{ME} INIT: status={(int)StatusCode} bos={buffer.Offset}/{buffer.Size}"); string contentType = Headers["Transfer-Encoding"]; bool chunkedRead = (contentType != null && contentType.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); string clength = Headers["Content-Length"]; if (!chunkedRead && !string.IsNullOrEmpty(clength)) { if (!long.TryParse(clength, out contentLength)) { contentLength = Int64.MaxValue; } } else { contentLength = Int64.MaxValue; } if (Version == HttpVersion.Version11 && RequestStream.KeepAlive) { KeepAlive = true; var cncHeader = Headers[ServicePoint.UsesProxy ? "Proxy-Connection" : "Connection"]; if (cncHeader != null) { cncHeader = cncHeader.ToLower(); KeepAlive = cncHeader.IndexOf("keep-alive", StringComparison.Ordinal) != -1; if (cncHeader.IndexOf("close", StringComparison.Ordinal) != -1) { KeepAlive = false; } } } // Negative numbers? if (!Int32.TryParse(clength, out stream_length)) { stream_length = -1; } string me = "WebResponseStream.Initialize()"; string tencoding = null; if (ExpectContent) { tencoding = Headers["Transfer-Encoding"]; } ChunkedRead = (tencoding != null && tencoding.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); if (!ChunkedRead) { readBuffer = buffer; try { if (contentLength > 0 && readBuffer.Size >= contentLength) { if (!IsNtlmAuth()) { await ReadAllAsync(false, cancellationToken).ConfigureAwait(false); } } } catch (Exception e) { throw GetReadException(WebExceptionStatus.ReceiveFailure, e, me); } } else if (ChunkStream == null) { try { ChunkStream = new MonoChunkStream(buffer.Buffer, buffer.Offset, buffer.Offset + buffer.Size, Headers); } catch (Exception e) { throw GetReadException(WebExceptionStatus.ServerProtocolViolation, e, me); } } else { ChunkStream.ResetBuffer(); try { ChunkStream.Write(buffer.Buffer, buffer.Offset, buffer.Size); } catch (Exception e) { throw GetReadException(WebExceptionStatus.ServerProtocolViolation, e, me); } } WebConnection.Debug($"{ME} INIT #1: - {ExpectContent} {closed} {nextReadCalled}"); if (!ExpectContent) { if (!closed && !nextReadCalled) { if (contentLength == Int64.MaxValue) { contentLength = 0; } nextReadCalled = true; } Operation.Finish(true); } }
void ReadDone(IAsyncResult result) { WebConnectionData data = Data; Stream ns = nstream; if (ns == null) { Close(true); return; } int nread = -1; try { nread = ns.EndRead(result); } catch (ObjectDisposedException) { return; } catch (Exception e) { if (e.InnerException is ObjectDisposedException) { return; } HandleError(WebExceptionStatus.ReceiveFailure, e, "ReadDone1"); return; } if (nread == 0) { HandleError(WebExceptionStatus.ReceiveFailure, null, "ReadDone2"); return; } if (nread < 0) { HandleError(WebExceptionStatus.ServerProtocolViolation, null, "ReadDone3"); return; } int pos = -1; nread += position; if (data.ReadState == ReadState.None) { Exception exc = null; try { pos = GetResponse(data, sPoint, buffer, nread); } catch (Exception e) { exc = e; } if (exc != null || pos == -1) { HandleError(WebExceptionStatus.ServerProtocolViolation, exc, "ReadDone4"); return; } } if (data.ReadState == ReadState.Aborted) { HandleError(WebExceptionStatus.RequestCanceled, null, "ReadDone"); return; } if (data.ReadState != ReadState.Content) { int est = nread * 2; int max = (est < buffer.Length) ? buffer.Length : est; byte [] newBuffer = new byte [max]; Buffer.BlockCopy(buffer, 0, newBuffer, 0, nread); buffer = newBuffer; position = nread; data.ReadState = ReadState.None; InitRead(); return; } position = 0; WebConnectionStream stream = new WebConnectionStream(this, data); bool expect_content = ExpectContent(data.StatusCode, data.request.Method); string tencoding = null; if (expect_content) { tencoding = data.Headers ["Transfer-Encoding"]; } chunkedRead = (tencoding != null && tencoding.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); if (!chunkedRead) { stream.ReadBuffer = buffer; stream.ReadBufferOffset = pos; stream.ReadBufferSize = nread; try { stream.CheckResponseInBuffer(); } catch (Exception e) { HandleError(WebExceptionStatus.ReceiveFailure, e, "ReadDone7"); } } else if (chunkStream == null) { try { chunkStream = new ChunkStream(buffer, pos, nread, data.Headers); } catch (Exception e) { HandleError(WebExceptionStatus.ServerProtocolViolation, e, "ReadDone5"); return; } } else { chunkStream.ResetBuffer(); try { chunkStream.Write(buffer, pos, nread); } catch (Exception e) { HandleError(WebExceptionStatus.ServerProtocolViolation, e, "ReadDone6"); return; } } data.stream = stream; if (!expect_content) { stream.ForceCompletion(); } data.request.SetResponseData(data); }