示例#1
0
        public ChunkedInputStream(HttpListenerContext context, Stream stream,
                                  byte [] buffer, int offset, int length)
            : base(stream, buffer, offset, length)
        {
            this.context = context;
            WebHeaderCollection coll = (WebHeaderCollection)context.Request.Headers;

            decoder = new MonoChunkStream(coll);
        }
        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);
            }
        }
示例#3
0
        void Initialize(BufferOffsetSize buffer)
        {
            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 tencoding = null;

            if (ExpectContent)
            {
                tencoding = Headers["Transfer-Encoding"];
            }

            ChunkedRead = (tencoding != null && tencoding.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1);

            if (ChunkedRead)
            {
                innerStreamWrapper = innerChunkStream = new MonoChunkStream(
                    Operation, CreateStreamWrapper(buffer), Headers);
            }
            else if (!IsNtlmAuth() && contentLength > 0 && buffer.Size >= contentLength)
            {
                innerStreamWrapper = new BufferedReadStream(Operation, null, buffer);
            }
            else
            {
                innerStreamWrapper = CreateStreamWrapper(buffer);
            }

            string content_encoding = Headers["Content-Encoding"];

            if (content_encoding == "gzip" && (Request.AutomaticDecompression & DecompressionMethods.GZip) != 0)
            {
                innerStreamWrapper = new GZipStream(innerStreamWrapper, CompressionMode.Decompress);
                Headers.Remove(HttpRequestHeader.ContentEncoding);
            }
            else if (content_encoding == "deflate" && (Request.AutomaticDecompression & DecompressionMethods.Deflate) != 0)
            {
                innerStreamWrapper = new DeflateStream(innerStreamWrapper, CompressionMode.Decompress);
                Headers.Remove(HttpRequestHeader.ContentEncoding);
            }

            WebConnection.Debug($"{ME} INIT #1: - {ExpectContent} {closed} {nextReadCalled}");

            if (!ExpectContent)
            {
                if (!closed && !nextReadCalled)
                {
                    if (contentLength == Int64.MaxValue)
                    {
                        contentLength = 0;
                    }
                    nextReadCalled = true;
                }
                Operation.CompleteResponseRead(true);
            }
        }
示例#4
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 MonoChunkStream(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);
        }
示例#5
0
        void Connect(HttpWebRequest request)
        {
            lock (socketLock) {
                if (socket != null && socket.Connected && status == WebExceptionStatus.Success)
                {
                    // Take the chunked stream to the expected state (State.None)
                    if (CanReuse() && CompleteChunkedRead())
                    {
                        reused = true;
                        return;
                    }
                }

                reused = false;
                if (socket != null)
                {
                    socket.Close();
                    socket = null;
                }

                chunkStream = null;
                IPHostEntry hostEntry = sPoint.HostEntry;

                if (hostEntry == null)
                {
#if MONOTOUCH && !MONOTOUCH_TV && !MONOTOUCH_WATCH
                    xamarin_start_wwan(sPoint.Address.ToString());
                    hostEntry = sPoint.HostEntry;
                    if (hostEntry == null)
                    {
#endif
                    status = sPoint.UsesProxy ? WebExceptionStatus.ProxyNameResolutionFailure :
                             WebExceptionStatus.NameResolutionFailure;
                    return;

#if MONOTOUCH && !MONOTOUCH_TV && !MONOTOUCH_WATCH
                }
#endif
                }

                //WebConnectionData data = Data;
                foreach (IPAddress address in hostEntry.AddressList)
                {
                    try {
                        socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    }
                    catch (Exception se) {
                        // The Socket ctor can throw if we run out of FD's
                        if (!request.Aborted)
                        {
                            status = WebExceptionStatus.ConnectFailure;
                        }
                        connect_exception = se;
                        return;
                    }
                    IPEndPoint remote = new IPEndPoint(address, sPoint.Address.Port);
                    socket.NoDelay = !sPoint.UseNagleAlgorithm;
                    try {
                        sPoint.KeepAliveSetup(socket);
                    } catch {
                        // Ignore. Not supported in all platforms.
                    }

                    if (!sPoint.CallEndPointDelegate(socket, remote))
                    {
                        socket.Close();
                        socket = null;
                        status = WebExceptionStatus.ConnectFailure;
                    }
                    else
                    {
                        try {
                            if (request.Aborted)
                            {
                                return;
                            }
                            socket.Connect(remote);
                            status = WebExceptionStatus.Success;
                            break;
                        } catch (ThreadAbortException) {
                            // program exiting...
                            Socket s = socket;
                            socket = null;
                            if (s != null)
                            {
                                s.Close();
                            }
                            return;
                        } catch (ObjectDisposedException) {
                            // socket closed from another thread
                            return;
                        } catch (Exception exc) {
                            Socket s = socket;
                            socket = null;
                            if (s != null)
                            {
                                s.Close();
                            }
                            if (!request.Aborted)
                            {
                                status = WebExceptionStatus.ConnectFailure;
                            }
                            connect_exception = exc;
                        }
                    }
                }
            }
        }