public WebConnectionStream(WebConnection cnc, WebConnectionData data)
        {
            if (data == null)
                throw new InvalidOperationException("data was not initialized");
            if (data.Headers == null)
                throw new InvalidOperationException("data.Headers was not initialized");
            if (data.Request == null)
                throw new InvalidOperationException("data.request was not initialized");
            _isRead = true;
            _pending = new ManualResetEvent(true);
            _request = data.Request;
            _readTimeout = _request.ReadWriteTimeout;
            _writeTimeout = _readTimeout;
            _cnc = cnc;
            var contentType = data.Headers["Transfer-Encoding"];
            var chunkedRead = (contentType != null && contentType.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1);
            var clength = data.Headers["Content-Length"];

            // Negative numbers?
            if (!long.TryParse(clength, out _streamLength))
                _streamLength = -1;

            if (!chunkedRead && _streamLength >= 0)
            {
                _contentLength = _streamLength;

                if (_contentLength == 0 && !IsNtlmAuth())
                    ReadAllAsync().Wait(); // TODO: Don't block.
            }
            else
                _contentLength = long.MaxValue;
        }
Exemple #2
0
        public WebConnectionStream(WebConnection cnc, WebConnectionData data)
        {
            if (data == null)
            {
                throw new InvalidOperationException("data was not initialized");
            }
            if (data.Headers == null)
            {
                throw new InvalidOperationException("data.Headers was not initialized");
            }
            if (data.request == null)
            {
                throw new InvalidOperationException("data.request was not initialized");
            }
            isRead        = true;
            cb_wrapper    = new AsyncCallback(ReadCallbackWrapper);
            pending       = new ManualResetEvent(true);
            this.request  = data.request;
            read_timeout  = request.ReadWriteTimeout;
            write_timeout = read_timeout;
            this.cnc      = cnc;
            string contentType = data.Headers["Transfer-Encoding"];
            bool   chunkedRead = (contentType != null && contentType.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1);
            string clength     = data.Headers["Content-Length"];

            if (!chunkedRead && clength != null && clength != "")
            {
                try
                {
                    contentLength = Int32.Parse(clength);
                    if (contentLength == 0 && !IsNtlmAuth())
                    {
                        ReadAll();
                    }
                }
                catch
                {
                    contentLength = Int32.MaxValue;
                }
            }
            else
            {
                contentLength = Int32.MaxValue;
            }

            // Negative numbers?
#if SSHARP
            if (!TryParsers.Int32TryParse(clength, out stream_length))
#else
            if (!Int32.TryParse(clength, out stream_length))
#endif
            { stream_length = -1; }
        }
Exemple #3
0
        // Constructors

        internal HttpWebResponse(Uri uri, string method, WebConnectionData data, CookieContainer container)
        {
            this.uri          = uri;
            this.method       = method;
            webHeaders        = data.Headers;
            version           = data.Version;
            statusCode        = (HttpStatusCode)data.StatusCode;
            statusDescription = data.StatusDescription;
            stream            = data.stream;
            contentLength     = -1;

            try
            {
                string cl = webHeaders["Content-Length"];
#if SSHARP
                if (String.IsNullOrEmpty(cl) || !TryParsers.Int64TryParse(cl, out contentLength))
#else
                if (String.IsNullOrEmpty(cl) || !Int64.TryParse(cl, out contentLength))
#endif
                { contentLength = -1; }
            }
            catch (Exception)
            {
                contentLength = -1;
            }

            if (container != null)
            {
                this.cookie_container = container;
                FillCookies();
            }

            string content_encoding = webHeaders["Content-Encoding"];
            if (content_encoding == "gzip" && (data.request.AutomaticDecompression & DecompressionMethods.GZip) != 0)
            {
                stream = new GZipStream(stream, CompressionMode.Decompress);
            }
            else if (content_encoding == "deflate" && (data.request.AutomaticDecompression & DecompressionMethods.Deflate) != 0)
            {
                stream = new DeflateStream(stream, CompressionMode.Decompress);
            }
        }
        internal async Task SetResponseDataAsync(WebConnectionData data)
        {
            var isLocked = false;
            var closeStream = default(Stream);

            try
            {
                Monitor.Enter(_locker, ref isLocked);

                if (Aborted)
                {
                    closeStream = data.Stream;

                    return;
                }

                _previousWebResponse = _webResponse;

                WebException wexc = null;
                try
                {
                    var createTask = HttpWebResponse.CreateAsync(Address, _method, data, CookieContainer);

                    if (createTask.IsCompleted)
                        _webResponse = createTask.Result;
                    else
                    {
                        try
                        {
                            Monitor.Exit(_locker);
                            isLocked = false;

                            _webResponse = await createTask.ConfigureAwait(false);
                        }
                        finally
                        {
                            Monitor.Enter(_locker, ref isLocked);
                        }
                    }
                }
                catch (Exception e)
                {
                    wexc = new WebException(e.Message, e, WebExceptionStatus.ProtocolError, null);
                    closeStream = data.Stream;
                }

                if (wexc == null && (_method == "POST" || _method == "PUT"))
                {
                    await CheckSendErrorAsync(data).ConfigureAwait(false);
                    if (_savedExc != null)
                        wexc = (WebException)_savedExc;
                }
            }
            finally
            {
                if (isLocked)
                    Monitor.Exit(_locker);

                if (null != closeStream)
                    closeStream.Close();
            }

            isLocked = false;
            try
            {
                Monitor.TryEnter(_locker, ref isLocked);

                if (Aborted)
                {
                    if (data.Stream != null)
                        data.Stream.Close();

                    return;
                }

                WebException wexc = null;

                var r = _asyncRead;

                var forced = false;
                if (r == null && _webResponse != null)
                {
                    // This is a forced completion (302, 204)...
                    forced = true;
                    r = new TaskCompletionSource<HttpWebResponse>();
                    r.TrySetResult(_webResponse);
                }

                if (r != null)
                {
                    if (wexc != null)
                    {
                        _haveResponse = true;
                        if (!r.Task.IsCompleted)
                            r.TrySetException(wexc);
                        return;
                    }

                    var isProxy = ProxyQuery && !_proxy.IsBypassed(Address);

                    try
                    {
                        var redirected = await CheckFinalStatusAsync().ConfigureAwait(false);

                        if (!redirected)
                        {
                            if ((isProxy ? _proxyAuthState.IsNtlmAuthenticated : _authState.IsNtlmAuthenticated) &&
                                _webResponse != null && (int)_webResponse.StatusCode < 400)
                            {
                                var wce = _webResponse.GetResponseStream() as WebConnectionStream;
                                if (wce != null)
                                {
                                    var cnc = wce.Connection;
                                    cnc.NtlmAuthenticated = true;
                                }
                            }

                            // clear internal buffer so that it does not
                            // hold possible big buffer (bug #397627)
                            if (_writeStream != null)
                                _writeStream.KillBuffer();

                            _haveResponse = true;
                            r.TrySetResult(_webResponse);
                        }
                        else
                        {
                            if (_webResponse != null)
                            {
                                if (await HandleNtlmAuthAsync(r.Task).ConfigureAwait(false))
                                    return;
                                _webResponse.Close();
                            }
                            FinishedReading = false;
                            _haveResponse = false;
                            _webResponse = null;
                            //r.Reset();
                            _servicePoint = GetServicePoint();
                            _abortHandler = _servicePoint.SendRequest(this, _connectionGroup);
                        }
                    }
                    catch (WebException wexc2)
                    {
                        if (forced)
                        {
                            _savedExc = wexc2;
                            _haveResponse = true;
                        }
                        r.TrySetException(wexc2);
                    }
                    catch (Exception ex)
                    {
                        wexc = new WebException(ex.Message, ex, WebExceptionStatus.ProtocolError, null);
                        if (forced)
                        {
                            _savedExc = wexc;
                            _haveResponse = true;
                        }
                        r.TrySetException(wexc);
                    }
                }
            }
            finally
            {
                if (isLocked)
                    Monitor.Exit(_locker);
            }
        }
        async Task CheckSendErrorAsync(WebConnectionData data)
        {
            // Got here, but no one called GetResponse
            var status = data.StatusCode;
            if (status < 400 || status == 401 || status == 407)
                return;

            if (_writeStream != null && _asyncRead == null && !_writeStream.CompleteRequestWritten)
            {
                // The request has not been completely sent and we got here!
                // We should probably just close and cause an error in any case,
                _savedExc = new WebException(data.StatusDescription, null, WebExceptionStatus.ProtocolError, _webResponse);
                if (AllowWriteStreamBuffering || _sendChunked || _writeStream.TotalWritten >= _contentLength)
                    await _webResponse.ReadAllAsync().ConfigureAwait(false);
                else
                    _writeStream.IgnoreIoErrors = true;
            }
        }