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);
            }
        }
Beispiel #2
0
        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);
        }