/// <summary> /// Requests the remote HTML. /// </summary> /// <param name="cacheProvider">Strategy for caching the remote HTML.</param> /// <param name="selectedSection">The selected section.</param> private void RequestRemoteHtml(RemoteMasterPageCacheProviderBase cacheProvider, string selectedSection) { try { // Get the URL to request the cached control from. // Include text size so that header knows which links to apply var textSize = new TextSize(HttpContext.Current.Request.Cookies, HttpContext.Current.Request.QueryString); Uri urlToRequest = new Uri(HttpContext.Current.Request.Url, String.Format(CultureInfo.CurrentCulture, config["MasterPageControlUrl"], this.Control)); var applicationPath = HttpUtility.UrlEncode(HttpRuntime.AppDomainAppVirtualPath.ToLower(CultureInfo.CurrentCulture).TrimEnd('/')); var query = HttpUtility.ParseQueryString(urlToRequest.Query); query.Add("section", selectedSection); query.Add("host", Page.Request.Url.Host); query.Add("textsize", textSize.CurrentTextSize().ToString(CultureInfo.InvariantCulture)); query.Add("path", applicationPath); urlToRequest = new Uri(urlToRequest.Scheme + "://" + urlToRequest.Authority + urlToRequest.AbsolutePath + "?" + query); // Create the request. Pass current user-agent so that library catalogue PCs can be detected by the remote script. var webRequest = (HttpWebRequest)WebRequest.Create(urlToRequest); webRequest.UseDefaultCredentials = true; webRequest.UserAgent = Page.Request.UserAgent; webRequest.Proxy = new ConfigurationProxyProvider().CreateProxy(); webRequest.Timeout = 4000; if (!String.IsNullOrEmpty(this.config["Timeout"])) { int timeout; if (Int32.TryParse(this.config["Timeout"], out timeout)) { webRequest.Timeout = timeout; } } #if DEBUG // Turn off SSL check in debug mode as it will always fail against a self-signed certificate used for development webRequest.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; #endif // Prepare the information we'll need when the response comes back var state = new RequestState(); state.Request = webRequest; state.CacheProvider = cacheProvider; // Kick off the request and, only if there's nothing already cached which we can use, wait for it to come back if (cacheProvider.SupportsAsync) { RequestRemoteHtmlAsynchronous(cacheProvider, webRequest, state); } else { RequestRemoteHtmlSynchronous(cacheProvider, webRequest); } } catch (UriFormatException ex) { throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, config["MasterPageControlUrl"], this.Control) + " is not a valid absolute URL", ex); } }
private static void RequestRemoteHtmlSynchronous(RemoteMasterPageCacheProviderBase cacheProvider, HttpWebRequest webRequest) { try { using (var response = webRequest.GetResponse()) { using (var responseStream = response.GetResponseStream()) { cacheProvider.SaveRemoteHtmlToCache(responseStream); } } } catch (WebException ex) { // Publish exception, otherwise it just disappears as async method has no calling code to throw to. ex.Data.Add("URL which failed", webRequest.RequestUri); ex.ToExceptionless().Submit(); } }
private void RequestRemoteHtmlAsynchronous(RemoteMasterPageCacheProviderBase cacheProvider, HttpWebRequest webRequest, RequestState state) { // Only wait for the response if there's nothing there at all. // If there is a cached version use that, but set the update running in the background. if (!cacheProvider.CachedVersionExists) { if (waitFor == null) { waitFor = new Dictionary <string, ManualResetEvent>(); } waitFor[this.Control] = new ManualResetEvent(false); state.WaitForResponse = waitFor[this.Control]; } webRequest.BeginGetResponse(new AsyncCallback(Response_Callback), state); if (!cacheProvider.CachedVersionExists) { waitFor[this.Control].WaitOne(new TimeSpan(0, 0, 10)); } }