25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
7.9KB

  1. <!--#include file="../app/Controllers/autoload_controllers.asp" -->
  2. <%
  3. ' Set cache expiration from configuration
  4. Dim cacheYear : cacheYear = GetAppSetting("CacheExpirationYear")
  5. If cacheYear = "nothing" Then cacheYear = "2030"
  6. Response.ExpiresAbsolute = "01/01/" & cacheYear
  7. Response.AddHeader "pragma", "no-cache"
  8. Response.AddHeader "cache-control", "private, no-cache, must-revalidate"
  9. ' Route parameters for the action being dispatched (referenced by the executed call string, never embedded in it)
  10. Dim MVC_RouteParams
  11. '=======================================================================================================================
  12. ' MVC Dispatcher
  13. '=======================================================================================================================
  14. Class MVC_Dispatcher_Class
  15. dim CurrentController
  16. Public Property Get ControllerName
  17. ControllerName = CurrentController
  18. end Property
  19. '---------------------------------------------------------------------------------------------------------------------
  20. ' Convenience method to resolve route and dispatch in one call
  21. ' method: HTTP method (GET, POST, etc.)
  22. ' path: Request path (already cleaned of query params)
  23. '---------------------------------------------------------------------------------------------------------------------
  24. Public Sub DispatchRequest(method, path)
  25. Dim routeArray
  26. routeArray = router.Resolve(method, path)
  27. Dispatch routeArray
  28. End Sub
  29. '---------------------------------------------------------------------------------------------------------------------
  30. ' Main dispatch method - executes a resolved route
  31. ' RouteArray: Array(controller, action, params) from router.Resolve()
  32. '---------------------------------------------------------------------------------------------------------------------
  33. Public Sub Dispatch(RouteArray)
  34. On Error Resume Next
  35. Dim controllerName, actionName, hasParams, paramsArray
  36. controllerName = RouteArray(0)
  37. actionName = RouteArray(1)
  38. ' Security: Validate controller and action names
  39. If Not ControllerRegistry.IsValidControllerFormat(controllerName) Then
  40. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  41. Response.Write "<strong>Security Error:</strong> Invalid controller name format."
  42. Response.Write "</div>"
  43. Exit Sub
  44. End If
  45. If Not ControllerRegistry.IsValidActionFormat(actionName) Then
  46. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  47. Response.Write "<strong>Security Error:</strong> Invalid action name format."
  48. Response.Write "</div>"
  49. Exit Sub
  50. End If
  51. ' Security: Check controller whitelist
  52. If Not ControllerRegistry.IsValidController(controllerName) Then
  53. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  54. Response.Write "<strong>Security Error:</strong> Controller '" & Server.HTMLEncode(controllerName) & "' is not registered."
  55. Response.Write "</div>"
  56. Exit Sub
  57. End If
  58. ' Initialize current controller
  59. Dim controllerAssignment : controllerAssignment = "Set CurrentController = " & controllerName & "()"
  60. Execute controllerAssignment
  61. ' Check if layout should be used
  62. hasParams = (UBound(RouteArray) >= 2)
  63. If eval(controllerName & ".useLayout") Then
  64. %> <!-- #include file="../app/views/Shared/Header.asp" --> <%
  65. End If
  66. ' Prepare parameters. They are passed to the action by reference to MVC_RouteParams (see
  67. ' ExecuteControllerAction) and are never concatenated into code, so a URL segment cannot inject script.
  68. If hasParams Then
  69. paramsArray = RouteArray(2)
  70. Else
  71. paramsArray = Empty
  72. End If
  73. ' Execute controller action
  74. ExecuteControllerAction controllerName, actionName, paramsArray
  75. ' Include footer if layout is used
  76. If eval(controllerName & ".useLayout") Then
  77. %> <!-- #include file="../app/views/Shared/Footer.asp" --> <%
  78. End If
  79. On Error GoTo 0
  80. End Sub
  81. ' Helper method to execute controller actions (eliminates code duplication)
  82. Private Sub ExecuteControllerAction(controllerName, actionName, paramsArray)
  83. On Error Resume Next
  84. Dim callString, argList, i
  85. ' Build the call string based on whether we have parameters. The string only ever contains the validated
  86. ' controller/action names and fixed MVC_RouteParams(n) references; the parameter values themselves are
  87. ' never part of the executed text.
  88. If Not IsEmpty(paramsArray) And IsArray(paramsArray) And UBound(paramsArray) >= 0 Then
  89. MVC_RouteParams = paramsArray
  90. argList = ""
  91. For i = 0 To UBound(paramsArray)
  92. If i > 0 Then argList = argList & ","
  93. argList = argList & "MVC_RouteParams(" & i & ")"
  94. Next
  95. callString = "Call " & controllerName & "." & actionName & "(" & argList & ")"
  96. Else
  97. callString = "Call " & controllerName & "." & actionName & "()"
  98. End If
  99. ' Execute the action
  100. Execute callString
  101. ' Handle errors
  102. If Err.Number <> 0 Then
  103. HandleDispatchError actionName, Err.Description, Err.Number
  104. Err.Clear
  105. End If
  106. On Error GoTo 0
  107. End Sub
  108. ' Centralized error handling for dispatch errors
  109. Private Sub HandleDispatchError(actionName, errorDesc, errorNum)
  110. Dim isDevelopment
  111. isDevelopment = (LCase(GetAppSetting("Environment")) = "development")
  112. If isDevelopment Then
  113. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  114. Response.Write "<strong>Controller Action Error</strong><br>"
  115. Response.Write "Action: <code>" & Server.HTMLEncode(actionName) & "</code><br>"
  116. Response.Write "Error: " & Server.HTMLEncode(errorDesc) & "<br>"
  117. Response.Write "Error Number: " & errorNum
  118. Response.Write "</div>"
  119. Else
  120. Response.Write "<div style='padding:15px; margin:10px; border:2px solid #dc3545; background:#f8d7da; color:#721c24; border-radius:4px;'>"
  121. Response.Write "<strong>An error occurred</strong><br>"
  122. Response.Write "Please contact the system administrator if the problem persists."
  123. Response.Write "</div>"
  124. End If
  125. End Sub
  126. Public Sub RequirePost
  127. If Request.Form.Count = 0 Then MVC.RedirectToExt "NotValid","",empty:End If
  128. End Sub
  129. ' Shortcut for RedirectToActionExt that does not require passing a parameters argument.
  130. Public Sub RedirectToAction(ByVal action_name)
  131. RedirectToActionExt action_name, empty
  132. End Sub
  133. Public Sub RedirectTo(controller_name, action_name)
  134. RedirectToExt controller_name, action_name, empty
  135. End Sub
  136. ' Redirects the browser to the specified action on the specified controller with the specified querystring parameters.
  137. ' params is a KVArray of querystring parameters.
  138. Public Sub RedirectToExt(controller_name, action_name, params)
  139. Response.Redirect Routes.UrlTo(controller_name, action_name, params)
  140. End Sub
  141. Public Sub RedirectToActionExt(ByVal action_name, ByVal params)
  142. RedirectToExt ControllerName, action_name, params
  143. End Sub
  144. End Class
  145. dim MVC_Dispatcher_Class__Singleton
  146. Function MVC()
  147. if IsEmpty(MVC_Dispatcher_Class__Singleton) then
  148. set MVC_Dispatcher_Class__Singleton = new MVC_Dispatcher_Class
  149. end if
  150. set MVC = MVC_Dispatcher_Class__Singleton
  151. End Function
  152. %>

Powered by TurnKey Linux.