/// <summary> /// Ensures that current <see cref="RequestContext"/> associted with the thread is not a <B>null</B> reference. /// </summary> /// <param name="context">The current request context.</param> /// <returns>Whether the request context is available.</returns> /// <exception cref="PhpException">Web server variables are not available (Warning).</exception> internal static bool EnsureRequestContext(out RequestContext context) { context = RequestContext.CurrentContext; if (context == null) { PhpException.Throw(PhpError.Warning, LibResources.GetString("web_server_not_available")); return false; } return true; }
internal WebServerCompilerManager/*!*/ GetWebServerCompilerManager(RequestContext/*!*/ requestContext) { Debug.Assert(requestContext != null && HttpContext.Current != null); if (webServerCompilerManager == null) { lock (webServerCompilerManagerMutex) { if (webServerCompilerManager == null) webServerCompilerManager = new WebServerCompilerManager(this); } } return webServerCompilerManager; }
/// <summary> /// Compiles a script. /// Called when the script cannot be loaded from pre-compiled assembly and it should be compiled. /// </summary> /// <returns>The compiled script type.</returns> private ScriptInfo CompileScriptNoLock(string ns, PhpSourceFile/*!*/ sourceFile, RequestContext requestContext) { Debug.Assert(sourceFile != null); CompilerConfiguration config = new CompilerConfiguration(Configuration.Application); WebCompilationContext context = new WebCompilationContext(applicationContext, this, config, sourceFile.Directory, (requestContext != null) ? requestContext.HttpContext.Timestamp : DateTime.UtcNow); try { CacheEntry cache_entry; if (ScriptAssemblyBuilder.CompileScripts(new PhpSourceFile[] { sourceFile }, context)) { // assembly should be already added into the cache by Persist() method if (TryGetCachedEntry(ns, out cache_entry)) return cache_entry.ScriptInfo; } return null; } catch (CompilerException) { return null; } catch (Exception) { // record stack info to the message if the manager resides in a dedicated domain: throw; } }
/// <summary> /// Retrives a compiled script. /// /// The method check scripts in following order: /// 1. Script Library database. /// 2. Modified source file on the file system. /// 3. Unmodified source file in precompiled WebPages.dll. /// </summary> /// <param name="sourceFile">Script source file.</param> /// <param name="requestContext">The current HTTP context. Can be <c>null</c> in case of desktop app.</param> /// <returns>The script type or a <B>null</B> reference on failure.</returns> /// <remarks>The method do check the script library database.</remarks> public ScriptInfo GetCompiledScript(PhpSourceFile/*!*/ sourceFile, RequestContext requestContext) { Debug.Assert(sourceFile != null); // try to get the script from precompiled script library first var scriptLibraryModule = applicationContext.ScriptLibraryDatabase.GetScriptModule(sourceFile.FullPath); if (scriptLibraryModule != null) return scriptLibraryModule.ScriptInfo; // loads precompiled assembly if exists and not loaded yet: GetPrecompiledAssembly(); // enables source code watcher if not enabled yet: if (watcher != null && !watcher.EnableRaisingEvents) { Debug.WriteLine("WSSM", "Source code watcher is starting."); watcher.EnableRaisingEvents = true; } string ns = ScriptModule.GetSubnamespace(sourceFile.RelativePath, false); CacheEntry cache_entry; if (Configuration.Application.Compiler.OnlyPrecompiledCode) { // Load script from cache (WebPages.dll) if (TryGetCachedEntry(ns, out cache_entry)) return cache_entry.ScriptInfo; else return null; } else { // Load script from cache or from ASP.NET Temporary files if (TryLoadCachedEntry(ns, sourceFile, out cache_entry)) return cache_entry.ScriptInfo; lock (this) { // double checked lock, CompileScript should not be called on more threads if (TryGetCachedEntry(ns, out cache_entry)) return cache_entry.ScriptInfo; Debug.WriteLine("WSSM", "Compile script '{0}'.", sourceFile.ToString()); return CompileScriptNoLock(ns, sourceFile, requestContext); } } }
void FinallyDispose() { DeleteTemporaryFiles(); // updates session cookie expiration stamp: UpdateSessionCookieExpiration(); this.httpContext = null; currentContext = null; }
/// <summary> /// Creates and initializes request and script contexts associated with the current thread. /// </summary> /// <param name="appContext">Application context.</param> /// <param name="context">Current HTTP context.</param> /// <returns>The initialized request context.</returns> /// <remarks> /// <para> /// Request context provides PHP with the web server environment. /// It should be initialized before any PHP code is invoked within web server and finalized (disposed) /// at the end of the request. This method can be called for multiple times, however it creates and /// initializes a new request context only once per HTTP request. /// </para> /// <para> /// The following steps take place during the initialization (in this order): /// <list type="number"> /// <term>Configuration is loaded (if not loaded yet).</term> /// <term>A new instance of <see cref="RequestContext"/> is created and bound to the current thread.</term> /// <term>A new instance of <see cref="ScriptContext"/> is created and initialized.</term> /// <term>Event <see cref="RequestBegin"/> is fired.</term> /// <term>Session is started if session auto-start confgiuration option is switched on.</term> /// </list> /// </para> /// <para> /// The request context can be accessed via the returned instance or via <see cref="CurrentContext"/> /// thread static field anytime between the initialization and disposal. /// </para> /// </remarks> public static RequestContext/*!*/ Initialize(ApplicationContext/*!*/ appContext, HttpContext/*!*/ context) { if (appContext == null) throw new ArgumentNullException("appContext"); if (context == null) throw new ArgumentNullException("context"); RequestContext req_context = currentContext; // already initialized within the current request: if (req_context != null && req_context.httpContext.Timestamp == context.Timestamp) return req_context; Debug.WriteLine("REQUEST", "-- started ----------------------"); req_context = new RequestContext(context); currentContext = req_context; req_context.Initialize(appContext); return req_context; }
/// <summary> /// Gets the cookie created for the session by ASP.NET server. /// </summary> private static bool GetCookie(out HttpCookie cookie, out RequestContext context) { if (!Web.EnsureRequestContext(out context)) { context = null; cookie = null; return false; } cookie = AspNetSessionHandler.GetCookie(context.HttpContext); return cookie != null; }
/// <summary> /// Set new SessionId string. Resets the Session object. /// </summary> /// <param name="request_context">Current RequestContext. Cannot be null.</param> /// <param name="session_id">New SessionId string.</param> internal static void SetNewSessionId(RequestContext/*!*/request_context, string session_id) { Debug.Assert(request_context != null); // currently this method does not work properly with ASP.NET handler, because // there is already created InProcDataStore associated with old SessionId, // this old SessionId is saved in private field SessionStateModule._rqId (and others) // and an attempt to store the data at the end of the request by ASP runtime with // new SessionId will silently fail (probably). // // Need to implement own SessionStateModule ? //Debug.Assert(request_context.ScriptContext.Config.Session.Handler.Name != AspNetSessionHandler.Default.Name); // NOTE: // When using ASP.NET session handler, following process drops all the session data // created during this request ... so next request starts with all new session state. if (!Manager.Validate(session_id)) throw new ArgumentException(null, "session_id"); var session = request_context.HttpContext.Session; //var x = HttpRuntime.CacheInternal.Get("j" + session.SessionID); // drop previous HttpContext.Session System.Web.SessionState.SessionStateUtility.RemoveHttpSessionStateFromContext( request_context.HttpContext); // assign new HttpContext.Session System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext( request_context.HttpContext, new System.Web.SessionState.HttpSessionStateContainer( session_id, CloneSessionStateCollection(session), // in PHP, session variables are not cleaned when new SessionId has been set session.StaticObjects,// new HttpStaticObjectsCollection(), session.Timeout, true, session.CookieMode, session.Mode, false) ); // save session id cookie, update SID //request_context.HttpContext.Response.Cookies[] SessionId.Manager.RemoveSessionID(request_context.HttpContext); bool redirected, cookieAdded; SessionId.Manager.SaveSessionID(request_context.HttpContext, session_id, out redirected, out cookieAdded); // set new SID constant request_context.UpdateSID(); }
/// <summary> /// Sets new session name. /// </summary> /// <param name="request">Valid request context.</param> /// <param name="name">New session name.</param> /// <returns>Whether session name was changed successfully.</returns> public virtual bool SetSessionName(RequestContext/*!*/request, string name) { PhpException.FunctionNotSupported(PhpError.Notice); return false; }
/// <summary> /// Gets current session name. /// </summary> /// <param name="request">Valid request context.</param> /// <returns>Session name.</returns> public virtual string GetSessionName(RequestContext/*!*/request) { return AspNetSessionHandler.AspNetSessionName; }