/// <summary> /// Action a job /// </summary> public AjaxReturn JobAction(int id) { AjaxReturn ret = new AjaxReturn(); Schedule job = Database.Get <Schedule>(id); Utils.Check(job.idSchedule != null, "Job {0} not found", id); if (!string.IsNullOrWhiteSpace(job.Url)) { // Job actually does something if (job.Post) { // It posts a record string methodName = job.Url; string moduleName = Utils.NextToken(ref methodName, "/"); Type type = AppModule.GetModule(moduleName); Utils.Check(type != null, "Invalid schedule job {0}", job.Url); AppModule module = (AppModule)Activator.CreateInstance(type); module.Context = Context; module.OriginalModule = module.Module = moduleName.ToLower(); module.OriginalMethod = module.Method = (string.IsNullOrEmpty(methodName) ? "default" : Path.GetFileNameWithoutExtension(methodName)).ToLower(); module.GetParameters = new NameValueCollection(); module.Parameters["json"] = job.Parameters; module.Parameters["date"] = job.ActionDate; MethodInfo method; object o = module.CallMethod(out method); if (method == null) { ret.error = "Job url not found " + job.Url; } else if (method.ReturnType == typeof(AjaxReturn)) { ret = o as AjaxReturn; if (ret.error == null && ret.redirect != null) { ret.redirect += "&from=" + HttpUtility.UrlEncode(Parameters.AsString("from")); } ret.id = null; } else { throw new CheckException("Unexpected return type {0}", method.ReturnType.Name); } } else { // It just redirects somewhere ret.redirect = Path.ChangeExtension(job.Url, ".html") + "?id=" + id; } } if (string.IsNullOrEmpty(ret.error)) { // Update job to say it is done switch ((RepeatType)job.RepeatType) { case RepeatType.None: // No repeat - delete job Database.Delete(job); ret.message = "Job deleted"; return(ret); case RepeatType.Daily: job.ActionDate = job.ActionDate.AddDays(job.RepeatFrequency); while (job.ActionDate.DayOfWeek == DayOfWeek.Saturday || job.ActionDate.DayOfWeek == DayOfWeek.Sunday) { job.ActionDate = job.ActionDate.AddDays(1); } break; case RepeatType.Weekly: job.ActionDate = job.ActionDate.AddDays(7 * job.RepeatFrequency); break; case RepeatType.Monthly: job.ActionDate = job.ActionDate.AddMonths(job.RepeatFrequency); break; case RepeatType.Quarterly: job.ActionDate = job.ActionDate.AddMonths(3 * job.RepeatFrequency); break; case RepeatType.Yearly: job.ActionDate = job.ActionDate.AddYears(job.RepeatFrequency); break; default: throw new CheckException("Invalid repeat type {0}", job.RepeatType); } Database.Update(job); } ret.id = job.idSchedule; return(ret); }
/// <summary> /// Process a single request /// </summary> /// <param name="listenerContext"></param> void ProcessRequest(object listenerContext) { DateTime started = DateTime.Now; // For timing response HttpListenerContext context = null; AppModule module = null; StringBuilder log = new StringBuilder(); // Session log writes to here, and it is displayed at the end try { context = (HttpListenerContext)listenerContext; log.AppendFormat("{0} {1}:{2}:[ms]:", context.Request.RemoteEndPoint.Address, context.Request.Headers["X-Forwarded-For"], context.Request.RawUrl); Session session = null; string filename = HttpUtility.UrlDecode(context.Request.Url.AbsolutePath).Substring(1); if (filename == "") { filename = "company"; // Default page is Company } string moduleName = null; string methodName = null; string baseName = filename.Replace(".html", ""); // Ignore .html - treat as a program request if (baseName.IndexOf(".") < 0) { // Urls of the form /ModuleName[/MethodName][.html] call a C# AppModule string[] parts = baseName.Split('/'); if (parts.Length <= 2) { Type type = AppModule.GetModule(parts[0]); if (type != null) { // The AppModule exists - create the object module = (AppModule)Activator.CreateInstance(type); moduleName = parts[0]; if (parts.Length == 2) { methodName = parts[1]; } } } } if (moduleName == null) { // No AppModule found - treat url as a file request moduleName = "FileSender"; module = new FileSender(filename); } // AppModule found - retrieve or create a session for it Cookie cookie = context.Request.Cookies["session"]; if (cookie != null) { _sessions.TryGetValue(cookie.Value, out session); if (AppSettings.Default.SessionLogging) { log.AppendFormat("[{0}{1}]", cookie.Value, session == null ? " not found" : ""); } } if (session == null) { if (moduleName == "FileSender") { session = new Session(null); } else { session = new Session(this); cookie = new Cookie("session", session.Cookie, "/"); if (AppSettings.Default.SessionLogging) { log.AppendFormat("[{0} new session]", cookie.Value); } } } if (cookie != null) { context.Response.Cookies.Add(cookie); cookie.Expires = session.Expires = Utils.Now.AddHours(1); } // Set up module module.Session = session; module.LogString = log; if (moduleName.EndsWith("Module")) { moduleName = moduleName.Substring(0, moduleName.Length - 6); } using (module) { // Call method module.Call(context, moduleName, methodName); } } catch (Exception ex) { while (ex is TargetInvocationException) { ex = ex.InnerException; } if (ex is System.Net.Sockets.SocketException) { log.AppendFormat("Request error: {0}\r\n", ex.Message); } else { log.AppendFormat("Request error: {0}\r\n", ex); if (module == null || !module.ResponseSent) { try { module = new AppModule(); module.Session = _empty; module.LogString = log; module.Context = context; module.Module = "exception"; module.Method = "default"; module.Title = "Exception"; module.Exception = ex; module.WriteResponse(module.Template("exception", module), "text/html", HttpStatusCode.InternalServerError); } catch (Exception ex1) { log.AppendFormat("Error displaying exception: {0}\r\n", ex1); if (module == null || !module.ResponseSent) { try { module.WriteResponse("Error displaying exception:" + ex.Message, "text/plain", HttpStatusCode.InternalServerError); } catch { } } } } } } if (context != null) { try { context.Response.Close(); } catch { } } try { Log(log.ToString().Replace(":[ms]:", ":" + Math.Round((DateTime.Now - started).TotalMilliseconds, 0) + " ms:")); } catch { } }