/// <summary>
        /// Begins an asynchronous request
        /// </summary>
        /// <param name="useCache">true to use cache, otherwise false</param>
        /// <param name="timeOut">timeout, in milliseconds</param>
        public void StartRequest(CacheSettings cacheSettings, int timeOut)
        {
            requestRunning = true;

            // Check the cache
            if (cacheSettings != CacheSettings.NOCACHE)
            {
                Internet_Cache_Entry_Info cacheInfo;
                if (WinInet.GetUrlCacheEntryInfo(m_url, out cacheInfo))
                {
                    ResponseStream = new FileStream(cacheInfo.lpszLocalFileName, FileMode.Open, FileAccess.Read);
                    FireRequestComplete();
                }
            }

            // Make an async request
            if (ResponseStream == null && cacheSettings != CacheSettings.CACHEONLY)
            {
                try
                {
                    m_webRequest = HttpRequestHelper.CreateHttpWebRequest(m_url, true);
                }
                catch (InvalidCastException)
                {
                    m_webRequest = WebRequest.Create(m_url);
                }

                m_webRequest.Timeout = timeOut;

                m_webRequest.BeginGetResponse(new AsyncCallback(RequestCompleteHandler), new object());
            }
        }
        /// <summary>
        /// Synchronously retrieves a response stream for this request
        /// </summary>
        /// <param name="timeOut">timeout, in ms</param>
        /// <param name="useCache">true to use cache, otherwise false</param>
        /// <returns>The stream</returns>
        public Stream GetResponseStream(CacheSettings cacheSettings, int timeOut)
        {
            Stream stream = Stream.Null;

            // Check the cache
            if (cacheSettings != CacheSettings.NOCACHE)
            {
                Internet_Cache_Entry_Info cacheInfo;
                if (WinInet.GetUrlCacheEntryInfo(m_url, out cacheInfo))
                {
                    if (File.Exists(cacheInfo.lpszLocalFileName))
                    {
                        stream = new FileStream(cacheInfo.lpszLocalFileName, FileMode.Open, FileAccess.Read);
                    }
                }
            }


            // Make a synchronous request, if necessary
            if (stream == Stream.Null && cacheSettings != CacheSettings.CACHEONLY)
            {
                if (m_url == null)
                {
                    return(null);
                }



                if (WebRequest is HttpWebRequest)
                {
                    HttpWebRequest thisRequest = (HttpWebRequest)WebRequest;
                    thisRequest.Timeout = timeOut;
                }


                try
                {
                    stream = WebRequest.GetResponse().GetResponseStream();
                }
                catch (WebException)
                {
                }
            }
            return(stream);
        }
        /// <summary>
        /// Retrieve the resource with the specified timeout (in ms).
        /// </summary>
        /// <param name="timeoutMs">Timeout (in ms) for the request.</param>
        /// <returns>A stream representing the requested resource. Can return null
        /// if the CacheLevel is CacheOnly and the resource could not be found
        /// in the cache.</returns>
        public Stream GetResponse(int timeoutMs)
        {
            // always try to get the url from the cache first
            if (ReadFromCache)
            {
                Internet_Cache_Entry_Info cacheInfo;
                if (WinInet.GetUrlCacheEntryInfo(_requestUrl, out cacheInfo))
                {
                    if (File.Exists(cacheInfo.lpszLocalFileName))
                    {
                        return(new FileStream(cacheInfo.lpszLocalFileName, FileMode.Open, FileAccess.Read));
                    }
                }
            }

            // if that didn't succeed then try to get the file from
            // the web as long as the user has requested we do this
            if (MakeRequest)
            {
                HttpWebResponse response = HttpRequestHelper.SendRequest(_requestUrl, delegate(HttpWebRequest request)
                {
                    request.AllowAutoRedirect = AllowAutoRedirect;
                    request.Timeout           = timeoutMs;
                    request.ContentType       = ContentType;
                    if (PostData != null)
                    {
                        request.Method = "POST";
                        using (Stream requestStream = request.GetRequestStream())
                            StreamHelper.Transfer(new MemoryStream(PostData), requestStream);
                    }
                });

                try
                {
                    Stream responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        if (WriteToCache)
                        {
                            return(WriteResponseToCache(responseStream));
                        }
                        else
                        {
                            return(StreamHelper.CopyToMemoryStream(responseStream));
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                finally
                {
                    response.Close();
                }
            }
            else
            {
                // look only in the cache
                return(null);
            }
        }
        /// <summary>
        /// Looks up the content type in browser cache
        /// </summary>
        /// <param name="url">The url for which to check content type</param>
        /// <returns>The content type</returns>
        private static UrlContentTypeInfo GetContentTypeFromBrowserCache(string url)
        {
            UrlContentTypeInfo contentType = null;

            // throw out the query string and other bits of the url, if we can
            if (UrlHelper.IsUrl(url))
            {
                Uri uri = new Uri(url);
                // by using the absolute uri, we're more likely to hit the cache
                url = UrlHelper.SafeToAbsoluteUri(uri);
            }

            // Get the header for this URL out of the cache and see if we
            // can get the content type out of the header
            Internet_Cache_Entry_Info info;

            if (WinInet.GetUrlCacheEntryInfo(url, out info))
            {
                // Get the header string for the info struct
                string header = Marshal.PtrToStringAnsi(info.lpHeaderInfo);

                // scan through the lines until we find the content type line
                if (header != null)
                {
                    string contentTypeString     = null;
                    string contentLengthString   = null;
                    string contentEncodingString = null;

                    string[] lines = header.Split('\n');
                    foreach (string line in lines)
                    {
                        if (line.IndexOf(":", StringComparison.OrdinalIgnoreCase) > -1)
                        {
                            string[] parts = line.Split(':');
                            if (parts[0].ToUpperInvariant() == "CONTENT-TYPE")
                            {
                                // be aware the character encoding can be appended to the end of this line
                                // following a semicolon
                                if (parts[0].IndexOf(";", StringComparison.OrdinalIgnoreCase) > -1)
                                {
                                    string[] subParts = parts[0].Split(';');
                                    contentTypeString     = subParts[0].Trim();
                                    contentEncodingString = subParts[1].Trim();
                                }
                                else
                                {
                                    contentTypeString = parts[1].Trim();
                                }
                            }
                            else if (parts[0].ToUpperInvariant() == "CONTENT-LENGTH")
                            {
                                contentLengthString = parts[1].Trim();
                            }

                            if (contentTypeString != null && contentLengthString != null)
                            {
                                break;
                            }
                        }
                    }
                    contentType = new UrlContentTypeInfo(contentTypeString, contentEncodingString, url, int.Parse(contentLengthString, CultureInfo.InvariantCulture));
                }
            }
            return(contentType);
        }