protected override object GetSecondArgument(IWebConnectionContent webConnectionContent) { JsonReader jsonReader = new JsonReader(webConnectionContent.AsStream()); return jsonReader; }
/// <summary> /// Returns the correct value from the webConnectionContent /// </summary> /// <param name="webConnectionContent"></param> /// <returns></returns> protected abstract object GetSecondArgument(IWebConnectionContent webConnectionContent);
/// <summary> /// Entry-point to handle the connection that's established on the socket /// </summary> /// <param name="state"></param> public virtual void HandleConnection(IWebConnectionContent content) { Thread thread = Thread.CurrentThread; // Signal that this was the abort to catch bool abortedHere = false; bool completed = false; TimerCallback timerCallback = delegate(object state) { if (completed) return; if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); else { log.Warn(thread.Name + " is blocked, aborting, ThreadID: " + thread.ManagedThreadId.ToString()); try { abortedHere = true; thread.Abort(); } catch { } } }; try { using (var timer = new Timer(timerCallback, null, 10000, System.Threading.Timeout.Infinite)) HandleConnectionInt(content); completed = true; } catch (ThreadAbortException tae) { if (abortedHere) { log.Warn("Thread was aborted", tae); Thread.ResetAbort(); } } }
/// <summary> /// Entry-point to handle the connection that's established on the socket /// </summary> /// <param name="state"></param> private void HandleConnectionInt(IWebConnectionContent content) { _Content = content; DateTime startTime = DateTime.UtcNow; // Decode POST parameters if they are present TryDecodePostParameters(); ILoggerFactoryAdapter loggerFactoryAdapter = LogManager.Adapter; if (loggerFactoryAdapter is IObjectCloudLoggingFactoryAdapter) ((IObjectCloudLoggingFactoryAdapter)loggerFactoryAdapter).RemoteEndPoint = RemoteEndPoint; Interlocked.Increment(ref NumActiveConnections); try { try { if (log.IsDebugEnabled) log.Debug("File Requested : " + _RequestedFile + "\n===================\n"); // Load the session object or create a new one LoadSession(); // Try to support some caching if (WebMethod.GET == Method && WebServer.CachingEnabled && 0 == GetParameters.Count && Headers.ContainsKey("IF-MODIFIED-SINCE")) if (WebServer.FileHandlerFactoryLocator.FileSystemResolver.ResolveFile(RequestedFile).LoadPermission(Session.User.Id) >= FilePermissionEnum.Read) { HashSet<IFileContainer> touchedFiles = Session.GetFilesTouchedForUrl(RequestedFile); if (null != touchedFiles) { DateTime ifModifiedSince = DateTime.Parse(Headers["IF-MODIFIED-SINCE"]); bool useCached = true; foreach (IFileContainer fileContainer in touchedFiles) if (WebServer.FileHandlerFactoryLocator.SessionManagerHandler.FileContainer != fileContainer) if (fileContainer.LastModified > ifModifiedSince) { useCached = false; break; } if (useCached) { SendResults(WebResults.From(Status._304_Not_Modified)); return; } } } IWebResults webResults = null; try { if (WebServer.FileHandlerFactoryLocator.HostnameAndPort.Equals(RequestedHost)) { // Generate the results for the client. The action taken can vary, depending on file name and arguments DateTime generateResultsStartTime = DateTime.UtcNow; webResults = GenerateResultsForClient(); if (log.IsDebugEnabled) log.Debug(string.Format("GenerateResultsForClient() handled in time: {0}", DateTime.UtcNow - generateResultsStartTime)); } else { // The user requested the wrong host; redirect string redirectUrl = "http://" + WebServer.FileHandlerFactoryLocator.HostnameAndPort + RequestedFile; if (GetParameters.Count > 0) if (redirectUrl.Contains("?")) redirectUrl += "&" + GetParameters.ToURLEncodedString(); else redirectUrl += "?" + GetParameters.ToURLEncodedString(); webResults = WebResults.Redirect(redirectUrl); } } catch (WebResultsOverrideException wroe) { webResults = wroe.WebResults; } catch (Exception e) { log.Error("Exception occured while handling a web request", e); webResults = WebResults.From(Status._500_Internal_Server_Error, "An unhandled error occured"); } if (log.IsDebugEnabled) log.Debug(string.Format("Request handled in time: {0}", DateTime.UtcNow - startTime)); // Finally, send the resuts to the browser if (null != webResults) { // For static information, include information that supports caching if (WebMethod.GET == Method && 0 == GetParameters.Count && WebServer.CachingEnabled) if ((!webResults.Headers.ContainsKey("Expires")) && (!webResults.Headers.ContainsKey("Cache-Control"))) { Session.SetFilesTouchedForUrl(RequestedFile, TouchedFiles); // Figure out the most recent file touched DateTime mostRecentChange = DateTime.MinValue; foreach (IFileContainer fileContainer in TouchedFiles) if (fileContainer.LastModified > mostRecentChange) mostRecentChange = fileContainer.LastModified; webResults.Headers["Last-Modified"] = mostRecentChange.ToString("r"); webResults.Headers["Cache-Control"] = "private, must-revalidate"; } SendResults(webResults); } } catch (WebResultsOverrideException wroe) { log.Error("WebResultsOverrideException exception while handling a web connection", wroe); using (TimedLock.Lock(_Connected)) if (_Connected.Value) SendResults(wroe.WebResults); } catch (NotImplementedException ne) { log.Error("NotImplementedUnhandled exception while handling a web connection", ne); using (TimedLock.Lock(_Connected)) if (_Connected.Value) SendResults(WebResults.From(Status._501_Not_Implemented)); } catch (Exception e) { log.Error("Unhandled exception while handling a web connection", e); using (TimedLock.Lock(_Connected)) if (_Connected.Value) SendResults(WebResults.From(Status._500_Internal_Server_Error, "An unhandled error occured")); } } finally { _Content = null; // Do cleanup in case the object is reused CookiesToSet.Clear(); _MimeReader = null; // Make sure that the logger doesn't hold the session _Session = null; if (loggerFactoryAdapter is IObjectCloudLoggingFactoryAdapter) ((IObjectCloudLoggingFactoryAdapter)loggerFactoryAdapter).Session = null; if (loggerFactoryAdapter is IObjectCloudLoggingFactoryAdapter) ((IObjectCloudLoggingFactoryAdapter)loggerFactoryAdapter).RemoteEndPoint = null; // Decrement the number of active connections int numActiveConnections = Interlocked.Decrement(ref NumActiveConnections); // If there are no running web connections and we've hit the MinRequestsBeforeGarbageCollection threshold, force a garbage collection // Else, if we've hit the MaxRequestsBeforeGarbageCollection threshold, force a garbage collection int numRequestsSinceLastGC = NumRequestsSinceLastGC; if (((0 == numActiveConnections) && (numRequestsSinceLastGC > WebServer.MinRequestsBeforeGarbageCollection)) || (numRequestsSinceLastGC > WebServer.MaxRequestsBeforeGarbageCollection)) { // Interlocked makes sure that we only schedule the GC if this is the thread that sets NumRequestsSinceLastGC if (numRequestsSinceLastGC == Interlocked.CompareExchange(ref NumRequestsSinceLastGC, 0, numRequestsSinceLastGC)) GC.Collect(); } else Interlocked.Increment(ref NumRequestsSinceLastGC); } }
protected override object GetSecondArgument(IWebConnectionContent webConnectionContent) { return webConnectionContent.AsBytes(); }