System.Net.AutoWebProxyScriptEngine.DownloadAndCompile C# (CSharp) Method

DownloadAndCompile() private method

private DownloadAndCompile ( Uri location, AutoWebProxyScriptWrapper &newScriptInstance, int &syncStatus ) : AutoWebProxyState
location Uri
newScriptInstance AutoWebProxyScriptWrapper
syncStatus int
return AutoWebProxyState
        private AutoWebProxyState DownloadAndCompile(Uri location, out AutoWebProxyScriptWrapper newScriptInstance, ref int syncStatus)
        {
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() location:" + ValidationHelper.ToString(location));
            AutoWebProxyState newState = AutoWebProxyState.DownloadFailure;
            WebResponse response = null;
            TimerThread.Timer timer = null;
            newScriptInstance = null;

            // Can't assert this in declarative form (DCR?). This Assert() is needed to be able to create the request to download the proxy script.
            ExceptionHelper.WebPermissionUnrestricted.Assert();
            try {
                // here we have a reentrance issue due to config load.
                WebRequest request = WebRequest.Create(location);
                request.Timeout = Timeout.Infinite;
                request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
                request.ConnectionGroupName = "__WebProxyScript";
                
                // We have an opportunity here, if caching is disabled AppDomain-wide, to override it with a
                // custom, trivial cache-provider to get a similar semantic.
                //
                // We also want to have a backup caching key in the case when IE has locked an expired script response
                //
                if (request.CacheProtocol != null)
                {
                    GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Using backup caching.");
                    request.CacheProtocol = new RequestCacheProtocol(backupCache, request.CacheProtocol.Validator);
                }

                HttpWebRequest httpWebRequest = request as HttpWebRequest;
                if (httpWebRequest!=null)
                {
                    httpWebRequest.Accept = "*/*";
                    httpWebRequest.UserAgent = this.GetType().FullName + "/" + Environment.Version;
                    httpWebRequest.KeepAlive = false;
                    httpWebRequest.Pipelined = false;
                    httpWebRequest.InternalConnectionGroup = true;
                }
                else
                {
                    FtpWebRequest ftpWebRequest = request as FtpWebRequest;
                    if (ftpWebRequest!=null)
                    {
                        ftpWebRequest.KeepAlive = false;
                    }
                }

                // Use no proxy, default cache - initiate the download.
                request.Proxy = null;
                request.Credentials = webProxy.Credentials;

                // Set this up with the abortable lock to abort this too.
                LockRequest(request, ref syncStatus);
                if (syncStatus != SyncStatus.RequestOwner)
                {
                    throw new WebException(NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled);
                }

                // Use our own timeout timer so that it can encompass the whole request, not just the headers.
                if (s_TimerQueue == null)
                {
                    s_TimerQueue = TimerThread.GetOrCreateQueue(SettingsSectionInternal.Section.DownloadTimeout);
                }
                timer = s_TimerQueue.CreateTimer(s_TimerCallback, request);
                response = request.GetResponse();

                // Check Last Modified.
                DateTime lastModified = DateTime.MinValue;
                HttpWebResponse httpResponse = response as HttpWebResponse;
                if (httpResponse != null)
                {
                    lastModified = httpResponse.LastModified;
                }
                else
                {
                    FtpWebResponse ftpResponse = response as FtpWebResponse;
                    if (ftpResponse != null)
                    {
                        lastModified = ftpResponse.LastModified;
                    }
                }
                GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() lastModified:" + lastModified.ToString() + " (script):" + (scriptInstance == null ? "(null)" : scriptInstance.LastModified.ToString()));
                if (scriptInstance != null && lastModified != DateTime.MinValue && scriptInstance.LastModified == lastModified)
                {
                    newScriptInstance = scriptInstance;
                    newState = AutoWebProxyState.CompilationSuccess;
                }
                else
                {
                    string scriptBody = null;
                    byte[] scriptBuffer = null;
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        SingleItemRequestCache.ReadOnlyStream ros = responseStream as SingleItemRequestCache.ReadOnlyStream;
                        if (ros != null)
                        {
                            scriptBuffer = ros.Buffer;
                        }
                        if (scriptInstance != null && scriptBuffer != null && scriptBuffer == scriptInstance.Buffer)
                        {
                            scriptInstance.LastModified = lastModified;
                            newScriptInstance = scriptInstance;
                            newState = AutoWebProxyState.CompilationSuccess;
                            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Buffer matched - reusing engine.");
                        }
                        else
                        {
                            using (StreamReader streamReader = new StreamReader(responseStream))
                            {
                                scriptBody = streamReader.ReadToEnd();
                            }
                        }
                    }

                    WebResponse tempResponse = response;
                    response = null;
                    tempResponse.Close();
                    timer.Cancel();
                    timer = null;

                    if (newState != AutoWebProxyState.CompilationSuccess)
                    {
                        newState = AutoWebProxyState.DownloadSuccess;

                        GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() IsFromCache:" + tempResponse.IsFromCache.ToString() + " scriptInstance:" + ValidationHelper.HashString(scriptInstance));
                        if (scriptInstance != null && scriptBody == scriptInstance.ScriptBody)
                        {
                            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Script matched - using existing engine.");
                            scriptInstance.LastModified = lastModified;
                            if (scriptBuffer != null)
                            {
                                scriptInstance.Buffer = scriptBuffer;
                            }
                            newScriptInstance = scriptInstance;
                            newState = AutoWebProxyState.CompilationSuccess;
                        }
                        else
                        {
                            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Creating AutoWebProxyScriptWrapper.");
                            newScriptInstance = new AutoWebProxyScriptWrapper();
                            newScriptInstance.LastModified = lastModified;
                            newState = newScriptInstance.Compile(location, scriptBody, scriptBuffer);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                if (NclUtilities.IsFatal(exception)) throw;
                if(Logging.On)Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_script_download_compile_error, exception));
                GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Download() threw:" + ValidationHelper.ToString(exception));
            }
            finally
            {
                if (timer != null)
                {
                    timer.Cancel();
                }

                //                                                                                 
                try
                {
                    if (response != null)
                    {
                        response.Close();
                    }
                }
                finally
                {
                    WebPermission.RevertAssert();
                }
            }
            if (newState!=AutoWebProxyState.CompilationSuccess) {
                newScriptInstance = null;
            }
            GlobalLog.Print("AutoWebProxyScriptEngine#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() retuning newState:" + ValidationHelper.ToString(newState));
            return newState;
        }