Exemplo n.º 1
0
        // Constructors

        HttpWebResponse(Uri uri, string method, WebConnectionData data, CookieContainer container)
        {
            _uri = uri;
            _method = method;
            _webHeaders = data.Headers;
            _version = data.Version;
            _statusCode = (HttpStatusCode)data.StatusCode;
            _statusDescription = data.StatusDescription;
            _stream = data.Stream;
            _contentLength = -1;

            try
            {
                var cl = _webHeaders["Content-Length"];
                if (String.IsNullOrEmpty(cl) || !Int64.TryParse(cl, out _contentLength))
                    _contentLength = -1;
            }
            catch (Exception)
            {
                _contentLength = -1;
            }

            if (container != null)
            {
                _cookieContainer = container;
                //FillCookiesAsync();
            }

#if false
            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);
#endif
        }
Exemplo n.º 2
0
        internal static async Task<HttpWebResponse> CreateAsync(Uri uri, string method, WebConnectionData data, CookieContainer container)
        {
            var response = new HttpWebResponse(uri, method, data, container);

            if (null != container)
                await response.FillCookiesAsync().ConfigureAwait(false);

            return response;
        }
Exemplo n.º 3
0
        async Task InitConnectionAsync(HttpWebRequest request)
        {
            request.WebConnection = this;
            if (request.ReuseConnection)
                request.StoredConnection = this;

            if (request.Aborted)
                return;

            _keepAlive = request.KeepAlive;
            Data = new WebConnectionData(request);
        retry:
            await ConnectAsync(request).ConfigureAwait(false);

            if (request.Aborted)
                return;

            if (_status != WebExceptionStatus.Success)
            {
                if (!request.Aborted)
                {
                    request.SetWriteStreamError(_status, _connectException);
                    Close(true);
                }
                return;
            }

            if (!await CreateStreamAsync(request).ConfigureAwait(false))
            {
                if (request.Aborted)
                    return;

                var st = _status;
                if (Data.Challenge != null)
                    goto retry;

                var cncExc = _connectException;
                _connectException = null;
                request.SetWriteStreamError(st, cncExc);
                Close(true);
                return;
            }

            await request.SetWriteStreamAsync(new WebConnectionStream(this, request)).ConfigureAwait(false);
        }
Exemplo n.º 4
0
        static async Task<int> GetResponseAsync(StreamSocketStream nstream, WebConnectionData data, ServicePoint sPoint)
        {
            var isContinue = false;
            var emptyFirstLine = false;

            using (var lineReader = new HttpLineReader(nstream))
            {
                do
                {
                    if (data.ReadState == ReadState.Aborted)
                        return -1;

                    if (data.ReadState == ReadState.None)
                    {
                        var line = await lineReader.ReadLineAsync(CancellationToken.None).ConfigureAwait(false);

                        if (null == line)
                        {
                            data.ReadState = ReadState.Aborted;
                            return 0;
                        }

                        if (string.IsNullOrEmpty(line))
                        {
                            emptyFirstLine = true;
                            continue;
                        }

                        emptyFirstLine = false;
                        data.ReadState = ReadState.Status;

                        var parts = line.Split(' ');
                        if (parts.Length < 2)
                            return -1;

                        if (string.Compare(parts[0], "HTTP/1.1", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            data.Version = HttpVersion.Version11;
                            sPoint.SetVersion(HttpVersion.Version11);
                        }
                        else
                        {
                            data.Version = HttpVersion.Version10;
                            sPoint.SetVersion(HttpVersion.Version10);
                        }

                        data.StatusCode = (int)UInt32.Parse(parts[1]);
                        if (parts.Length >= 3)
                            data.StatusDescription = string.Join(" ", parts, 2, parts.Length - 2);
                        else
                            data.StatusDescription = "";
                    }

                    emptyFirstLine = false;
                    if (data.ReadState == ReadState.Status)
                    {
                        data.ReadState = ReadState.Headers;
                        data.Headers = new WebHeaderCollection();
                        var headers = new List<string>();

                        var finished = false;

                        while (!finished)
                        {
                            var line = await lineReader.ReadLineAsync(CancellationToken.None).ConfigureAwait(false);

                            if (null == line)
                                break;

                            if (string.IsNullOrEmpty(line))
                            {
                                // Empty line: end of headers
                                finished = true;
                                continue;
                            }

                            if (line.Length > 0 && (line[0] == ' ' || line[0] == '\t'))
                            {
                                var count = headers.Count - 1;
                                if (count < 0)
                                    break;

                                var prev = headers[count] + line;
                                headers[count] = prev;
                            }
                            else
                                headers.Add(line);
                        }

                        if (!finished)
                            return 0;

                        lineReader.SyncStream();

                        foreach (var s in headers)
                            data.Headers.SetInternal(s);

                        if (data.StatusCode == (int)HttpStatusCode.Continue)
                        {
                            sPoint.SendContinue = true;

                            if (data.Request.ExpectContinue)
                            {
                                data.Request.DoContinueDelegate(data.StatusCode, data.Headers);
                                // Prevent double calls when getting the
                                // headers in several packets.
                                data.Request.ExpectContinue = false;
                            }

                            data.ReadState = ReadState.None;
                            isContinue = true;
                        }
                        else
                        {
                            data.ReadState = ReadState.Content;
                            return 1;
                        }
                    }
                } while (emptyFirstLine || isContinue);
            }

            return -1;
        }
Exemplo n.º 5
0
        void HandleError(WebExceptionStatus st, Exception e, string where)
        {
            _status = st;
            lock (this)
            {
                if (st == WebExceptionStatus.RequestCanceled)
                    Data = new WebConnectionData();
            }

            if (e == null)
            {
                // At least we now where it comes from
                try
                {
#if TARGET_JVM
                    throw new Exception ();
#else
                    throw new Exception(new StackTrace().ToString());
#endif
                }
                catch (Exception e2)
                {
                    e = e2;
                }
            }

            HttpWebRequest req = null;
            if (Data != null && Data.Request != null)
                req = Data.Request;

            Close(true);
            if (req != null)
            {
                req.FinishedReading = true;
                req.SetResponseError(st, e, where);
            }
        }
Exemplo n.º 6
0
        //internal IAsyncResult BeginWrite(HttpWebRequest request, byte[] buffer, int offset, int size, AsyncCallback cb, object state)
        //{
        //    Stream s = null;
        //    lock (this)
        //    {
        //        if (Data.Request != request)
        //            throw new ObjectDisposedException(typeof (StreamSocketStream).FullName);
        //        if (_nstream == null)
        //            return null;
        //        s = _nstream;
        //    }

        //    IAsyncResult result = null;
        //    try
        //    {
        //        result = s.BeginWrite(buffer, offset, size, cb, state);
        //        var x = s.WriteAsync(buffer, offset, size).ConfigureAwait(false)
        //    }
        //    catch (Exception)
        //    {
        //        _status = WebExceptionStatus.SendFailure;
        //        throw;
        //    }

        //    return result;
        //}

        //internal bool EndWrite(HttpWebRequest request, bool throwOnError, IAsyncResult result)
        //{
        //    if (request.FinishedReading)
        //        return true;

        //    Stream s = null;
        //    lock (this)
        //    {
        //        if (Data.Request != request)
        //            throw new ObjectDisposedException(typeof(StreamSocketStream).FullName);
        //        if (_nstream == null)
        //            throw new ObjectDisposedException(typeof(StreamSocketStream).FullName);
        //        s = _nstream;
        //    }

        //    try
        //    {
        //        s.EndWrite(result);
        //        return true;
        //    }
        //    catch (Exception exc)
        //    {
        //        _status = WebExceptionStatus.SendFailure;
        //        if (throwOnError && exc.InnerException != null)
        //            throw exc.InnerException;
        //        return false;
        //    }
        //}

        //internal int Read(HttpWebRequest request, byte[] buffer, int offset, int size)
        //{
        //    Stream s = null;
        //    lock (this)
        //    {
        //        if (Data.Request != request)
        //            throw new ObjectDisposedException(typeof(StreamSocketStream).FullName);
        //        if (_nstream == null)
        //            return 0;
        //        s = _nstream;
        //    }

        //    var result = 0;
        //    try
        //    {
        //        var done = false;
        //        if (!_chunkedRead)
        //        {
        //            result = s.Read(buffer, offset, size);
        //            done = (result == 0);
        //        }

        //        if (_chunkedRead)
        //        {
        //            try
        //            {
        //                _chunkStream.WriteAndReadBack(buffer, offset, size, ref result);
        //                if (!done && result == 0 && _chunkStream.WantMore)
        //                    result = EnsureReadAsync(buffer, offset, size);
        //            }
        //            catch (Exception e)
        //            {
        //                HandleError(WebExceptionStatus.ReceiveFailure, e, "chunked Read1");
        //                throw;
        //            }

        //            if ((done || result == 0) && _chunkStream.WantMore)
        //            {
        //                HandleError(WebExceptionStatus.ReceiveFailure, null, "chunked Read2");
        //                throw new WebException("Read error", null, WebExceptionStatus.ReceiveFailure, null);
        //            }
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        HandleError(WebExceptionStatus.ReceiveFailure, e, "Read");
        //    }

        //    return result;
        //}

        internal bool Write(HttpWebRequest request, byte[] buffer, int offset, int size, ref string err_msg)
        {
            err_msg = null;
            Stream s = null;
            lock (this)
            {
                if (Data.Request != request)
                    throw new ObjectDisposedException(typeof(StreamSocketStream).FullName);
                s = _nstream;
                if (s == null)
                    return false;
            }

            try
            {
                s.Write(buffer, offset, size);
                // here SSL handshake should have been done
                if (_ssl && !_certsAvailable)
                    GetCertificates(s);
            }
            catch (Exception e)
            {
                err_msg = e.Message;
                var wes = WebExceptionStatus.SendFailure;
                var msg = "Write: " + err_msg;
                if (e is WebException)
                {
                    HandleError(wes, e, msg);
                    return false;
                }

                // if SSL is in use then check for TrustFailure
                if (_ssl)
                {
#if SECURITY_DEP && MONOTOUCH
                    HttpsClientStream https = (s as HttpsClientStream);
                    if (https.TrustFailure) {
#else
                    if ((bool)_piTrustFailure.GetValue(s, null))
                    {
#endif
                        wes = WebExceptionStatus.TrustFailure;
                        msg = "Trust failure";
                    }
                }

                HandleError(wes, e, msg);
                return false;
            }
            return true;
        }

        internal void Close(bool sendNext)
        {
            lock (this)
            {
                if (Data != null && Data.Request != null && Data.Request.ReuseConnection)
                {
                    Data.Request.ReuseConnection = false;
                    return;
                }

                if (_nstream != null)
                {
                    try
                    {
                        _nstream.Close();
                    }
                    catch
                    { }
                    _nstream = null;
                }

                if (_socket != null)
                {
                    try
                    {
                        _socket.Dispose();
                    }
                    catch
                    { }
                    _socket = null;
                }

                if (_ntlmAuthenticated)
                    ResetNtlm();
                if (Data != null)
                {
                    lock (Data)
                    {
                        Data.ReadState = ReadState.Aborted;
                    }
                }
                _state.SetIdle();
                Data = new WebConnectionData();
                if (sendNext)
                    SendNext();

                _connectRequest = null;
                _connectNtlmAuthState = NtlmAuthState.None;
            }
        }

        void Abort(object sender, EventArgs args)
        {
            lock (this)
            {
                lock (_queue)
                {
                    var req = (HttpWebRequest)sender;
                    if (Data.Request == req || Data.Request == null)
                    {
                        if (!req.FinishedReading)
                        {
                            _status = WebExceptionStatus.RequestCanceled;
                            Close(false);
                            if (_queue.Count > 0)
                            {
                                Data.Request = _queue.Dequeue();
                                SendRequest(Data.Request);
                            }
                        }
                        return;
                    }

                    req.FinishedReading = true;
                    req.SetResponseError(WebExceptionStatus.RequestCanceled, null, "User aborted");
                    if (_queue.Count > 0 && _queue.Peek() == sender)
                        _queue.Dequeue();
                    else if (_queue.Count > 0)
                    {
                        var old = _queue.ToArray();
                        _queue.Clear();
                        for (var i = old.Length - 1; i >= 0; i--)
                        {
                            if (old[i] != sender)
                                _queue.Enqueue(old[i]);
                        }
                    }
                }
            }
        }
Exemplo n.º 7
0
        //internal ChunkStream ChunkStream
        //{
        //    get { return _chunkStream; }
        //}

        public WebConnection(IWebConnectionState wcs, ServicePoint sPoint)
        {
            _state = wcs;
            _sPoint = sPoint;
            _buffer = new byte[4096];
            Data = new WebConnectionData();
            _queue = wcs.Group.Queue;
            abortHelper = new AbortHelper
            {
                Connection = this
            };
            _abortHandler = abortHelper.Abort;
        }