コード例 #1
0
        private void RequestAsynch( Object parameters )
        {
            RequestParameters requestParameters = (RequestParameters) parameters;

            RequestState state = new RequestState()
            {
                PostBytes = requestParameters.PostBytes,
                Uri = requestParameters.Uri,
                Verb = requestParameters.Verb,
            };

            DateTime dtMetric = DateTime.UtcNow;

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create( state.Uri );

            request.Method = requestParameters.Verb; // Post, Put, Delete
            request.ContentType = requestParameters.ContentType;

#if !SILVERLIGHT && !MONO
            request.ContentLength = requestParameters.PostBytes.Length;
            request.AutomaticDecompression = DecompressionMethods.Deflate;
            request.KeepAlive = false;
#endif

            // To-Do: Refactor this central storage of header values to inject into an abstract network object.
            // inject request headers from iApp object.
            if ( requestParameters.Headers != null && requestParameters.Headers.Count() > 0 )
            {
                foreach ( string key in requestParameters.Headers.Keys )
                {
                    request.Headers[key] = requestParameters.Headers[key];
                }
            }

            state.Request = request;

            // Start the asynchronous request.
            IAsyncResult result = request.BeginGetRequestStream( new AsyncCallback( GetRequestStreamCallback ), state );

            if ( !allDone.WaitOne( DefaultTimeout ) )
            {
                OnError( state );
                return;
            }

        }
コード例 #2
0
        private void PostRequest_OnError( RequestState state )
        {
            Exception exc = new Exception( "PosterAsynch call to RequestAsynch threw an exception", state.Exception );
            MXDevice.Log.Error( exc );

            PostNetworkResponse.StatusCode = state.StatusCode;
            PostNetworkResponse.Message = exc.Message;
            PostNetworkResponse.Exception = exc;
            PostNetworkResponse.URI = state.Uri;
            PostNetworkResponse.Verb = state.Verb;

            MXDevice.PostNetworkResponse(PostNetworkResponse);
        }
コード例 #3
0
        private void PostRequest_OnComplete( RequestState state )
        {
            PostNetworkResponse.StatusCode = state.StatusCode;
            PostNetworkResponse.URI = state.Uri;
            PostNetworkResponse.Verb = state.Verb;
            PostNetworkResponse.ResponseString = state.ResponseString;
            PostNetworkResponse.ResponseBytes = state.ResponseBytes;
            PostNetworkResponse.Expiration = state.Expiration;
            PostNetworkResponse.Message = state.ErrorMessage;

            switch ( PostNetworkResponse.StatusCode )
            {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.Accepted:
                    // things are ok, no event required
                    break;

                case HttpStatusCode.NoContent:           // return when an object is not found
                case HttpStatusCode.Unauthorized:        // return when session expires
                case HttpStatusCode.InternalServerError: // return when an exception happens
                case HttpStatusCode.ServiceUnavailable:  // return when the database or siteminder are unavailable
                    PostNetworkResponse.Message = String.Format( "Network Service responded with status code {0}", state.StatusCode );
                    MXDevice.PostNetworkResponse(PostNetworkResponse);
                    break;
                default:
                    PostNetworkResponse.Message = String.Format( "PosterAsynch completed but received HTTP {0}", state.StatusCode );
                    // Application.Log.Error( PostNetworkResponse.Message );
                    MXDevice.PostNetworkResponse(PostNetworkResponse);
                    return;
            }
        }
コード例 #4
0
        private void FetchAsynch( Object parameters )
        {
            FetchParameters fetchParameters = (FetchParameters) parameters;

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create( fetchParameters.Uri );
            request.Method = "GET";
            //request.Proxy = null;

#if !SILVERLIGHT && !MONO
            request.AutomaticDecompression = DecompressionMethods.GZip;
#endif
			
            if ( fetchParameters.Headers != null && fetchParameters.Headers.Count() > 0 )
            {
                foreach ( string key in fetchParameters.Headers.Keys )
                {
                    request.Headers[key] = fetchParameters.Headers[key];
                }
            }

            RequestState state = new RequestState()
            {
                Request = request,
                AbsoluteUri = fetchParameters.Uri,
                FileName = fetchParameters.FileName
            };

            // Start the asynchronous request.
            IAsyncResult result = request.BeginGetResponse( new AsyncCallback( ResponseCallback ), state );
            if ( !allDone.WaitOne( DefaultTimeout ) )
            {
                OnError( state );
                return;
            }
        }
コード例 #5
0
        // Define other methods and classes here
        private void ResponseCallback(IAsyncResult result)
        {
            // Get and fill the RequestState
            RequestState state = (RequestState)result.AsyncState;

            try
            {
                HttpWebRequest request = state.Request;

                // End the Asynchronous response and get the actual response object
                state.Response = (HttpWebResponse)request.EndGetResponse(result);

                state.Expiration = state.Response.Headers["Expires"].TryParseDateTimeUtc();

                // apply web response headers to data collection.
                // To-Do: evaluate which headers are actually needed and skip those that aren't. So, what's our logic for "needed headers" ?
                foreach (string key in state.Response.Headers.AllKeys)
                {
                    state.Data[key] = state.Response.Headers[key];
                }

                state.StatusCode = state.Response.StatusCode;

                switch (state.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.Accepted:
                    break;

                case HttpStatusCode.NoContent:
                    state.ErrorMessage = String.Format("No Content returned: Result {0} for {1}", state.StatusCode, request.RequestUri);
                    MXDevice.Log.Warn(state.ErrorMessage);
                    state.Expiration = DateTime.UtcNow;
                    OnDownloadComplete(state);
                    return;

                default:
                    state.ErrorMessage = String.Format("Get failed. Received HTTP {0} for {1}", state.StatusCode, request.RequestUri);
                    MXDevice.Log.Error(state.ErrorMessage);
                    state.Expiration = DateTime.UtcNow;
                    OnDownloadComplete(state);

                    return;
                }

                // extract response into bytes and string.
                WebResponse webResponse = NetworkUtils.ExtractResponse(state.Response, state.FileName);
                state.ResponseBytes  = webResponse.ResponseBytes;
                state.ResponseString = webResponse.ResponseString;

                OnDownloadComplete(state);
            }
            catch (WebException ex)
            {
                ex.Data.Add("Uri", state.Request.RequestUri);
                ex.Data.Add("Verb", state.Request.Method);

                state.StatusCode = ((HttpWebResponse)ex.Response).StatusCode;
                ex.Data.Add("StatusCode", state.StatusCode);
                ex.Data.Add("StatusDescription", ((HttpWebResponse)ex.Response).StatusDescription);

                state.ErrorMessage = string.Format("Call to {0} had a Webexception. {1}   Status: {2}   Desc: {3}", state.Request.RequestUri, ex.Message, ex.Status, ((HttpWebResponse)ex.Response).StatusDescription);
                state.Exception    = ex;
                state.Expiration   = DateTime.UtcNow;

                MXDevice.Log.Error(state.ErrorMessage);
                MXDevice.Log.Error(ex);

                OnError(state);
            }
            catch (Exception ex)
            {
                ex.Data.Add("Uri", state.Request.RequestUri);
                ex.Data.Add("Verb", state.Request.Method);

                state.ErrorMessage = string.Format("Call to {0} had an Exception. {1}", state.Request.RequestUri, ex.Message);
                state.Exception    = ex;
                state.StatusCode   = (HttpStatusCode)(-1);
                state.Expiration   = DateTime.UtcNow;

                MXDevice.Log.Error(state.ErrorMessage);
                MXDevice.Log.Error(ex);
                OnError(state);
            }
            finally
            {
                if (state.Response != null)
                {
                    state.Response.Close();
                }
                state.Request = null;

                allDone.Set();
            }
        }
コード例 #6
0
ファイル: PosterAsynch.cs プロジェクト: Zebra/iFactr-iOS
        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            // Get and fill the RequestState
            RequestState state = (RequestState)asynchronousResult.AsyncState;

            HttpWebRequest  request  = state.Request;
            HttpWebResponse response = null;

            try
            {
                // End the Asynchronous response and get the actual response object
                response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);

                state.StatusCode = response.StatusCode;

                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.Accepted:
                    break;

                case HttpStatusCode.NoContent:
                    Device.Log.Info("Empty payload returned in PosterAsynch: Result {0} for {1}", state.StatusCode, request.RequestUri);
                    break;

                default:
                    state.ErrorMessage = String.Format("{0} failed. Received HTTP {1} for {2}", state.Verb, response.StatusCode, state.Uri);
                    Device.Log.Error(state.ErrorMessage);
                    state.Expiration       = DateTime.UtcNow;
                    state.AttemptToRefresh = DateTime.UtcNow;
                    OnComplete(state);

                    return;
                }

                // extract response into bytes and string.
                WebResponse webResponse = NetworkUtils.ExtractResponse(response);
                state.ResponseBytes   = webResponse.ResponseBytes;
                state.ResponseString  = webResponse.ResponseString;
                state.ResponseHeaders = webResponse.ResponseHeaders;
#if !NETCF
                state.Expiration       = response.Headers["Expires"].TryParseDateTimeUtc();
                state.AttemptToRefresh = response.Headers["MonoCross-Attempt-Refresh"].TryParseDateTimeUtc();
#endif
                OnComplete(state);
            }
            catch (WebException ex)
            {
                string StatusDescription = string.Empty;
                string message           = string.Format("Call to {0} had a Webexception. {1}   Status: {2}", state.Request.RequestUri, ex.Message, ex.Status);
#if !NETCF
                ex.Data.Add("WebException.StatusCode", ex.Status);
                ex.Data.Add("Uri", state.Uri);
                ex.Data.Add("Verb", state.Verb);

                ex.Data.Add("StatusCode", state.StatusCode);
#endif
                if (ex.Response != null)
                {
                    state.StatusCode      = ((HttpWebResponse)ex.Response).StatusCode;
                    StatusDescription     = ((HttpWebResponse)ex.Response).StatusDescription;
                    state.ResponseHeaders = ex.Response.Headers;
                }
                else if (ex.Message.ToLower().Contains("request was aborted"))
                {
                    state.StatusCode  = HttpStatusCode.RequestTimeout;
                    StatusDescription = "Request cancelled by client because the server did not respond within timeout";
                }
                else
                {
                    state.StatusCode = (HttpStatusCode)(-2);
                }
                state.WebExceptionStatusCode = ex.Status;
#if !NETCF
                ex.Data.Add("WebException.Status", ex.Status);
                ex.Data.Add("StatusDescription", StatusDescription);
#endif
                state.ErrorMessage     = message;
                state.Exception        = ex;
                state.Expiration       = DateTime.UtcNow;
                state.AttemptToRefresh = DateTime.UtcNow;

                OnError(state);
            }
            catch (Exception ex)
            {
                // TODO: Consider adding custom post exceptions...
                string    message = string.Format("Call to {0} had an Exception. {1}", state.Request.RequestUri, ex.Message);
                Exception qexc    = new Exception(message, ex);
#if !NETCF
                qexc.Data.Add("Uri", state.Uri);
                qexc.Data.Add("Verb", state.Verb);
#endif
                state.ErrorMessage           = message;
                state.Exception              = qexc;
                state.Expiration             = DateTime.UtcNow;
                state.AttemptToRefresh       = DateTime.UtcNow;
                state.StatusCode             = (HttpStatusCode)(-1);
                state.WebExceptionStatusCode = (WebExceptionStatus)(-1);

                OnError(state);
            }
            finally
            {
                // Release the HttpWebResponse
                if (response != null)
                {
                    ((IDisposable)response).Dispose();
                }
                state.Request = null;

                allDone.Set();
            }
        }
コード例 #7
0
        private void FetcherAsynch_OnError( RequestState state )
        {
            Exception exc = new Exception( "FetcherAsynch call to FetchAsynch threw an exception", state.Exception );
            MXDevice.Log.Error( exc );

            PostNetworkResponse.StatusCode = state.StatusCode;
            PostNetworkResponse.Message = exc.Message;
            PostNetworkResponse.Exception = exc;
            PostNetworkResponse.URI = state.AbsoluteUri;
            PostNetworkResponse.Verb = state.Verb;
            PostNetworkResponse.ResponseString = null;
            PostNetworkResponse.ResponseBytes = null;

            MXDevice.PostNetworkResponse(PostNetworkResponse);
        }
コード例 #8
0
ファイル: PosterAsynch.cs プロジェクト: Zebra/iFactr-iOS
        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            // Get and fill the RequestState
            RequestState   state   = (RequestState)asynchronousResult.AsyncState;
            HttpWebRequest request = state.Request;

            string errorMsg = "PosterAsynch.GetRequestStreamCallback encountered WebException";

            try
            {
                // End the operation
                Stream postStream = request.EndGetRequestStream(asynchronousResult);

                // Write to the request stream.
                if (state.PostBytes == null)
                {
                    state.PostBytes = new byte[0];
                }
                postStream.Write(state.PostBytes, 0, state.PostBytes.Length);
                postStream.Close();
                postStream.Dispose();

                // Start the asynchronous operation to get the response
                IAsyncResult result = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), state);
            }
            catch (WebException ex)
            {
                string StatusDescription = string.Empty;
#if !NETCF
                ex.Data.Add("Uri", state.Uri);
                ex.Data.Add("Verb", state.Verb);
                ex.Data.Add("WebException.Status", ex.Status);
#endif
                state.ErrorMessage           = errorMsg;
                state.Exception              = ex;
                state.WebExceptionStatusCode = ex.Status;

                if (ex.Response != null)
                {
                    state.StatusCode = ((HttpWebResponse)ex.Response).StatusCode;
                }
                else if (ex.Message.ToLower().Contains("request was aborted"))
                {
                    state.StatusCode  = HttpStatusCode.RequestTimeout;
                    StatusDescription = "Request cancelled by client because the server did not respond within timeout";
                }
                else
                {
                    state.StatusCode = (HttpStatusCode)(-2);
                }
#if !NETCF
                ex.Data.Add("StatusCode", state.StatusCode);
                ex.Data.Add("StatusDescription", StatusDescription);
#endif
                OnError(state);
                allDone.Set();
            }
            catch (Exception ex)
            {
#if !NETCF
                ex.Data.Add("Uri", state.Uri);
                ex.Data.Add("Verb", state.Verb);
#endif
                state.ErrorMessage = errorMsg;
                state.Exception    = ex;
                state.StatusCode   = (HttpStatusCode)(-2);
                OnError(state);
                allDone.Set();
            }
        }
コード例 #9
0
ファイル: PosterAsynch.cs プロジェクト: Zebra/iFactr-iOS
        private void PostAsynch(Object parameters)
        {
            RequestParameters requestParameters = (RequestParameters)parameters;

            RequestState state = new RequestState
            {
                PostBytes  = requestParameters.PostBytes,
                Uri        = requestParameters.Uri,
                Verb       = requestParameters.Verb,
                Downloaded = DateTime.UtcNow
            };

            DateTime dtMetric = DateTime.UtcNow;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(state.Uri);

            request.Method                 = requestParameters.Verb; // Post, Put, Delete
            request.ContentType            = requestParameters.ContentType;
            request.Timeout                = requestParameters.Timeout;
            request.ContentLength          = requestParameters.PostBytes.Length;
            request.AutomaticDecompression = DecompressionMethods.Deflate;
            request.KeepAlive              = false;

            if (requestParameters.Headers != null && requestParameters.Headers.Any())
            {
                foreach (string key in requestParameters.Headers.Keys)
                {
                    if (key.ToLower() == "accept")
                    {
                        request.Accept = requestParameters.Headers[key];
                    }
                    else if (key.ToLower() == "content-type")
                    {
                        request.ContentType = requestParameters.Headers[key];
                    }
                    else if (key.ToLower() == "host")
                    {
                        Exception ex;
#if NETCF
                        ex = new ArgumentException("Host header value cannot be set in Compact Frameword libraries.");
#else
                        //TODO: add the URL explaining PCL incompatibility
                        ex = new ArgumentException("Host header value cannot be set in PCL libraries.");
#endif
                        Device.Log.Error(ex);
                        throw ex;
                    }
                    else
                    {
                        request.Headers[key] = requestParameters.Headers[key];
                    }
                }
            }

            state.Request = request;

            try
            {
                // Start the asynchronous request.
                IAsyncResult result = request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), state);
#if NETCF
                if (!allDone.WaitOne(requestParameters.Timeout, false))
#else
                if (!allDone.WaitOne(requestParameters.Timeout))
#endif
                {
                    try { request.Abort(); } catch (Exception) { } // .Abort() always throws exception
                    return;
                }
            }
            catch (Exception exc)
            {
                Device.Log.Error("PosterAsynch.PostAsynch encountered exception", exc);
                autoEvent.Set();
            }
        }
コード例 #10
0
        // Define other methods and classes here
        private void ResponseCallback(IAsyncResult result)
        {
            // Get and fill the RequestState
            RequestState state = (RequestState)result.AsyncState;

            try
            {
                HttpWebRequest request = state.Request;

                // End the Asynchronous response and get the actual response object
                state.Response         = (HttpWebResponse)request.EndGetResponse(result);
                state.Expiration       = state.Response.Headers["Expires"].TryParseDateTimeUtc();
                state.AttemptToRefresh = state.Response.Headers["MonoCross-Attempt-Refresh"].TryParseDateTimeUtc();
                // apply web response headers to data collection.
                // TODO: evaluate which headers are actually needed and skip those that aren't. So, what's our logic for "needed headers" ?
                foreach (string key in state.Response.Headers.AllKeys)
                {
                    state.Data[key] = state.Response.Headers[key];
                }

                state.StatusCode = state.Response.StatusCode;

                switch (state.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.Accepted:
                    break;

                case HttpStatusCode.NoContent:
                    Device.Log.Info("Empty payload returned in FetcherAsynch: Result {0} for {1}", state.StatusCode, request.RequestUri);
                    break;

                default:
                    state.ErrorMessage = String.Format("Get failed. Received HTTP {0} for {1}", state.StatusCode, request.RequestUri);
                    Device.Log.Error(state.ErrorMessage);
                    state.Expiration       = DateTime.UtcNow;
                    state.AttemptToRefresh = DateTime.UtcNow;
                    state.Downloaded       = DateTime.UtcNow;
                    OnDownloadComplete(state);

                    return;
                }

                // extract response into bytes and string.
                WebResponse webResponse = NetworkUtils.ExtractResponse(state.Response, state.FileName);
                state.ResponseBytes   = webResponse.ResponseBytes;
                state.ResponseString  = webResponse.ResponseString;
                state.ResponseHeaders = webResponse.ResponseHeaders;

                OnDownloadComplete(state);
            }
            catch (WebException ex)
            {
                string StatusDescription = string.Empty;
                ex.Data.Add("Uri", state.Request.RequestUri);
                ex.Data.Add("Verb", state.Request.Method);
                if (ex.Response != null)
                {
                    state.StatusCode      = ((HttpWebResponse)ex.Response).StatusCode;
                    StatusDescription     = ((HttpWebResponse)ex.Response).StatusDescription;
                    state.ResponseHeaders = ex.Response.Headers;
                }
                else if (ex.Message.ToLower().Contains("request was aborted"))
                {
                    state.StatusCode  = HttpStatusCode.RequestTimeout;
                    StatusDescription = "Request cancelled by client because the server did not respond within timeout";
                }
                else
                {
                    state.StatusCode = (HttpStatusCode)(-2);
                }
                state.WebExceptionStatusCode = ex.Status;
                ex.Data.Add("StatusCode", state.StatusCode);
                ex.Data.Add("WebException.Status", ex.Status);
                ex.Data.Add("StatusDescription", StatusDescription);
                state.ErrorMessage     = string.Format("Call to {0} had a Webexception. {1}   Status: {2}   Desc: {3}", state.Request.RequestUri, ex.Message, ex.Status, StatusDescription);
                state.Exception        = ex;
                state.Expiration       = DateTime.UtcNow;
                state.AttemptToRefresh = DateTime.UtcNow;

                OnError(state);
            }
            catch (Exception ex)
            {
                ex.Data.Add("Uri", state.Request.RequestUri);
                ex.Data.Add("Verb", state.Request.Method);
                state.ErrorMessage           = string.Format("Call to {0} had an Exception. {1}", state.Request.RequestUri, ex.Message);
                state.Exception              = ex;
                state.StatusCode             = (HttpStatusCode)(-1);
                state.WebExceptionStatusCode = (WebExceptionStatus)(-1);
                state.Expiration             = DateTime.UtcNow;
                state.AttemptToRefresh       = DateTime.UtcNow;

                OnError(state);
            }
            finally
            {
                if (state.Response != null)
                {
                    ((IDisposable)state.Response).Dispose();
                }
                state.Request = null;

                allDone.Set();
            }
        }
コード例 #11
0
        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            // Get and fill the RequestState
            RequestState state = (RequestState)asynchronousResult.AsyncState;

            HttpWebRequest request = state.Request;

            HttpWebResponse response = null;

            Stream       streamResponse = null;
            StreamReader streamRead     = null;

            try
            {
                // End the Asynchronous response and get the actual response object
                //To-Do: This has the potential for cross-domain calls, which are tricky in SL. This line doesn't work in the MDT POC.
                response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);

                state.StatusCode = response.StatusCode;

                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.Accepted:
                    break;

                case HttpStatusCode.NoContent:
                    state.ErrorMessage = String.Format("No Content returned: Result {0} for {1}", state.StatusCode, state.Uri);
                    MXDevice.Log.Warn(state.ErrorMessage);
                    state.Expiration = DateTime.UtcNow;
                    OnComplete(state);
                    return;

                default:
                    state.ErrorMessage = String.Format("{0} failed. Received HTTP {1} for {2}", state.Verb, response.StatusCode, state.Uri);
                    MXDevice.Log.Error(state.ErrorMessage);
                    state.Expiration = DateTime.UtcNow;
                    OnComplete(state);

                    return;
                }

                // extract response into bytes and string.
                WebResponse webResponse = NetworkUtils.ExtractResponse(response);
                state.ResponseBytes  = webResponse.ResponseBytes;
                state.ResponseString = webResponse.ResponseString;

                state.Expiration = response.Headers["Expires"].TryParseDateTimeUtc();

                OnComplete(state);
            }
            catch (WebException ex)
            {
                // To-Do: Consider adding custom post exceptions...
                string message = string.Format("Call to {0} had a Webexception. {1}   Status: {2}", state.Request.RequestUri, ex.Message, ex.Status);
                ex.Data.Add("ResponseStatusCode", ex.Status);
                ex.Data.Add("Uri", state.Uri);
                ex.Data.Add("Verb", state.Verb);

                state.StatusCode = ((HttpWebResponse)ex.Response).StatusCode;
                ex.Data.Add("StatusCode", state.StatusCode);
                ex.Data.Add("StatusDescription", ((HttpWebResponse)ex.Response).StatusDescription);
                state.Exception = ex;

                OnError(state);
            }
            catch (Exception ex)
            {
                // To-Do: Consider adding custom post exceptions...
                string    message = string.Format("Call to {0} had an Exception. {1}", state.Request.RequestUri, ex.Message);
                Exception qexc    = new Exception(message, ex);
                qexc.Data.Add("Uri", state.Uri);
                qexc.Data.Add("Verb", state.Verb);
                state.Exception = qexc;

                OnError(state);
            }
            finally
            {
                // Close the stream object
                if (streamResponse != null)
                {
                    streamResponse.Close();
                }

                if (streamRead != null)
                {
                    streamRead.Close();
                }

                // Release the HttpWebResponse
                if (response != null)
                {
                    response.Close();
                }
                state.Request = null;

                allDone.Set();
            }
        }
コード例 #12
0
ファイル: FetcherAsynch.cs プロジェクト: Zebra/iFactr-iOS
        private void FetchAsynch(Object parameters)
        {
            FetchParameters fetchParameters = (FetchParameters)parameters;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fetchParameters.Uri);

            request.Method = "GET";
            request.AutomaticDecompression = DecompressionMethods.GZip;
            if (fetchParameters.Headers != null && fetchParameters.Headers.Any())
            {
                foreach (string key in fetchParameters.Headers.Keys)
                {
                    if (key.ToLower() == "accept")
                    {
                        request.Accept = fetchParameters.Headers[key];
                    }
                    else if (key.ToLower() == "content-type")
                    {
                        request.ContentType = fetchParameters.Headers[key];
                    }
                    else if (key.ToLower() == "host")
                    {
                        Exception ex;
#if NETCF
                        ex = new ArgumentException("Host header value cannot be set in Compact Frameword libraries.");
#else
                        ex = new ArgumentException("Host header value cannot be set in PCL libraries.");
#endif
                        Device.Log.Error(ex);
                        throw ex;
                    }
                    else
                    {
                        request.Headers[key] = fetchParameters.Headers[key];
                    }
                }
            }

            RequestState state = new RequestState()
            {
                Request     = request,
                AbsoluteUri = fetchParameters.Uri,
                FileName    = fetchParameters.FileName,
                Downloaded  = DateTime.UtcNow,
                StatusCode  = HttpStatusCode.RequestTimeout,
            };

            try
            {
                // Start the asynchronous request.
                IAsyncResult result = request.BeginGetResponse(new AsyncCallback(ResponseCallback), state);
#if NETCF
                if (!allDone.WaitOne(fetchParameters.Timeout, false))
#else
                if (!allDone.WaitOne(fetchParameters.Timeout))
#endif
                {
                    try { request.Abort(); } catch (Exception) { } // .Abort() always throws exception
                    return;
                }
            }
            catch (Exception exc)
            {
                Device.Log.Error("FetcherAsynch.FetchAsynch encountered exception", exc);
                autoEvent.Set();
            }
        }