You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
7.8KB

  1. <!--#include file="../app/Controllers/autoload_controllers.asp" -->
  2. <%
  3. ' Every response is dynamic and session-sensitive (CSRF tokens, flash messages), so tell
  4. ' every cache - browser, proxy, or antivirus web filter - not to store it at all.
  5. '
  6. ' Response.CacheControl is ASP's intrinsic property that actually governs the real
  7. ' Cache-Control header IIS sends, and it defaults to "private" (which explicitly PERMITS
  8. ' browser-local caching) if never set. Response.AddHeader "cache-control", ... does NOT
  9. ' touch that property - it adds a second, separate Cache-Control header alongside it, which
  10. ' a real proxy/cache can parse unpredictably (confirmed via debug logging: a response still
  11. ' reported Response.CacheControl = "private" even after AddHeader was called). Must set the
  12. ' CacheControl property directly for this to actually take effect.
  13. Response.ExpiresAbsolute = Now() - 1
  14. Response.CacheControl = "no-cache"
  15. Response.AddHeader "pragma", "no-cache"
  16. '=======================================================================================================================
  17. ' MVC Dispatcher
  18. '=======================================================================================================================
  19. Class MVC_Dispatcher_Class
  20. dim CurrentController
  21. Public Property Get ControllerName
  22. ControllerName = CurrentController
  23. end Property
  24. '---------------------------------------------------------------------------------------------------------------------
  25. ' Convenience method to resolve route and dispatch in one call
  26. ' method: HTTP method (GET, POST, etc.)
  27. ' path: Request path (already cleaned of query params)
  28. '---------------------------------------------------------------------------------------------------------------------
  29. Public Sub DispatchRequest(method, path)
  30. Dim routeArray
  31. routeArray = router.Resolve(method, path)
  32. Dispatch routeArray
  33. End Sub
  34. '---------------------------------------------------------------------------------------------------------------------
  35. ' Main dispatch method - executes a resolved route
  36. ' RouteArray: Array(controller, action, params) from router.Resolve()
  37. '---------------------------------------------------------------------------------------------------------------------
  38. Public Sub Dispatch(RouteArray)
  39. On Error Resume Next
  40. Dim controllerName, actionName, hasParams, paramsArray
  41. controllerName = RouteArray(0)
  42. actionName = RouteArray(1)
  43. ' Security: Validate controller and action names
  44. If Not ControllerRegistry.IsValidControllerFormat(controllerName) Then
  45. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  46. Response.Write "<strong>Security Error:</strong> Invalid controller name format."
  47. Response.Write "</div>"
  48. Exit Sub
  49. End If
  50. If Not ControllerRegistry.IsValidActionFormat(actionName) Then
  51. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  52. Response.Write "<strong>Security Error:</strong> Invalid action name format."
  53. Response.Write "</div>"
  54. Exit Sub
  55. End If
  56. ' Security: Check controller whitelist
  57. If Not ControllerRegistry.IsValidController(controllerName) Then
  58. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  59. Response.Write "<strong>Security Error:</strong> Controller '" & Server.HTMLEncode(controllerName) & "' is not registered."
  60. Response.Write "</div>"
  61. Exit Sub
  62. End If
  63. ' Initialize current controller
  64. Dim controllerAssignment : controllerAssignment = "Set CurrentController = " & controllerName & "()"
  65. Execute controllerAssignment
  66. ' Check if layout should be used
  67. hasParams = (UBound(RouteArray) >= 2)
  68. If eval(controllerName & ".useLayout") Then
  69. %> <!-- #include file="../app/views/Shared/Header.asp" --> <%
  70. End If
  71. ' Prepare parameters
  72. If hasParams Then
  73. paramsArray = SurroundStringInArray(RouteArray(2))
  74. Else
  75. paramsArray = Empty
  76. End If
  77. ' Execute controller action
  78. ExecuteControllerAction controllerName, actionName, paramsArray
  79. ' Include footer if layout is used
  80. If eval(controllerName & ".useLayout") Then
  81. %> <!-- #include file="../app/views/Shared/Footer.asp" --> <%
  82. End If
  83. On Error GoTo 0
  84. End Sub
  85. ' Helper method to execute controller actions (eliminates code duplication)
  86. Private Sub ExecuteControllerAction(controllerName, actionName, paramsArray)
  87. On Error Resume Next
  88. Dim callString
  89. ' Build the call string based on whether we have parameters
  90. If Not IsEmpty(paramsArray) And IsArray(paramsArray) And UBound(paramsArray) >= 0 Then
  91. callString = "Call " & controllerName & "." & actionName & "(" & Join(paramsArray, ",") & ")"
  92. Else
  93. callString = "Call " & controllerName & "." & actionName & "()"
  94. End If
  95. ' Execute the action
  96. Execute callString
  97. ' Handle errors
  98. If Err.Number <> 0 Then
  99. HandleDispatchError actionName, Err.Description, Err.Number
  100. Err.Clear
  101. End If
  102. On Error GoTo 0
  103. End Sub
  104. ' Centralized error handling for dispatch errors
  105. Private Sub HandleDispatchError(actionName, errorDesc, errorNum)
  106. Dim isDevelopment
  107. isDevelopment = (LCase(GetAppSetting("Environment")) = "development")
  108. If isDevelopment Then
  109. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  110. Response.Write "<strong>Controller Action Error</strong><br>"
  111. Response.Write "Action: <code>" & Server.HTMLEncode(actionName) & "</code><br>"
  112. Response.Write "Error: " & Server.HTMLEncode(errorDesc) & "<br>"
  113. Response.Write "Error Number: " & errorNum
  114. Response.Write "</div>"
  115. Else
  116. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  117. Response.Write "<strong>An error occurred</strong><br>"
  118. Response.Write "Please contact the system administrator if the problem persists."
  119. Response.Write "</div>"
  120. End If
  121. End Sub
  122. Public Sub RequirePost
  123. If Request.Form.Count = 0 Then MVC.RedirectToExt "NotValid","",empty:End If
  124. End Sub
  125. ' Shortcut for RedirectToActionExt that does not require passing a parameters argument.
  126. Public Sub RedirectToAction(ByVal action_name)
  127. RedirectToActionExt action_name, empty
  128. End Sub
  129. Public Sub RedirectTo(controller_name, action_name)
  130. RedirectToExt controller_name, action_name, empty
  131. End Sub
  132. ' Redirects the browser to the specified action on the specified controller with the specified querystring parameters.
  133. ' params is a KVArray of querystring parameters.
  134. Public Sub RedirectToExt(controller_name, action_name, params)
  135. Response.Redirect Routes.UrlTo(controller_name, action_name, params)
  136. End Sub
  137. Public Sub RedirectToActionExt(ByVal action_name, ByVal params)
  138. RedirectToExt ControllerName, action_name, params
  139. End Sub
  140. End Class
  141. dim MVC_Dispatcher_Class__Singleton
  142. Function MVC()
  143. if IsEmpty(MVC_Dispatcher_Class__Singleton) then
  144. set MVC_Dispatcher_Class__Singleton = new MVC_Dispatcher_Class
  145. end if
  146. set MVC = MVC_Dispatcher_Class__Singleton
  147. End Function
  148. %>

Powered by TurnKey Linux.