GET /hello
-> IIS URL Rewrite rule "WscMvc-Hello" (^hello/?$)
-> /Default.asp?route=/hello
-> Server.CreateObject("WscMvc.RequestContext"); ctx.Initialize path, httpMethod, logDir
-> Server.CreateObject("WscMvc.Application")
-> Application.Run(ctx, statusLine, contentType, body) [Framework/Application.wsc]
-> CreateObject("WscMvc.HomeController")
-> HomeController.Hello(body) [Controllers/HomeController.wsc]
-> LogOutcome ctx, statusLine (best-effort append to logs/app.log)
-> Default.asp sets Response.Status/ContentType, writes body
Default.asp is the only file that touches ASP intrinsic objects (Request, Response, Server). It contains no business logic — only reading the route query parameter and REQUEST_METHOD, resolving logs/'s physical path via Server.MapPath, invoking WscMvc.RequestContext and WscMvc.Application, and writing the response.Framework/RequestContext.wsc, Framework/Application.wsc, and Controllers/HomeController.wsc never reference Request/Response/Server/Session. All data crosses the ASP-to-WSC and WSC-to-WSC boundaries as either VBScript scalars (strings) or our own RequestContext COM object (not an ASP intrinsic) — never an ASP host object. See docs/DECISIONS.md for why the original SPEC §15 open question about passing ASP intrinsics into a WSC never needed a direct experiment: the architecture never crosses that boundary by design.<method> entries backed by ordinary Sub/Function procedures, never <property>/Property Get. VBScript's Property Get/Let/Set requires a Class...End Class block and cannot appear at a WSC's top-level script scope — confirmed experimentally (see docs/DECISIONS.md), not assumed from general WSC documentation.If path = "/hello" check inside Application.Run. This is intentionally minimal and will be replaced by the explicit allowlisted route table in M3 (Router.wsc); do not extend it ad hoc before that milestone.Application.Run is the single central point that decides expected (404, ordinary control flow) vs. unexpected (COM/method failure, 500) outcomes, and the single point that logs every outcome. Default.asp still independently guards its own three sequential calls (RequestContext creation, Initialize, Application creation, Run) since a WSC failing to even instantiate happens outside Application.Run's reach.RequestContext and Application are both created fresh per request via Server.CreateObject in Default.asp and dropped (Set ... = Nothing) at the end of the page; neither is ever cached in ASP Session/Application scope, per SPEC §10.RequestContext.Initialize generates a correlation id from Fix(Timer) plus Scripting.FileSystemObject.GetTempName() — not Randomize/Rnd(), which was tried first and shown experimentally to collide when two contexts are created within the same clock tick (see docs/DECISIONS.md).Application.LogOutcome appends one line per request (timestamp, correlation id, method, path, status line, elapsed ms) to logs/app.log, guarded end-to-end by On Error Resume Next so a logging failure can never affect the HTTP response. Concurrent writers are serialized with a manual lock-file mutex (logs/app.log.lock, via CreateTextFile(..., OverwriteExisting:=False)) since no ASP intrinsic locking primitive (Application.Lock) is available to code that must not reference ASP intrinsics. The retry budget is deliberately short (see docs/DECISIONS.md): logging is explicitly best-effort and may drop lines under heavy concurrency without affecting correctness of the response.| Component | ProgID | CLSID |
|---|---|---|
Framework/RequestContext.wsc |
WscMvc.RequestContext |
{1C36FA55-34DF-4974-94B9-D657389362B2} |
Framework/Application.wsc |
WscMvc.Application |
{851C7763-1638-42FE-A166-BF3DD3A96A88} |
Controllers/HomeController.wsc |
WscMvc.HomeController |
{87488446-60BE-4068-8368-0B709BB68F3F} |
CLSIDs are fixed at creation and must never be recycled for a different component (AGENTS.md). Application's public Run signature changed between M1 and M2 (added a leading ctx parameter) under the same CLSID; acceptable because this is active pre-release (v0.1) development with exactly one caller (Default.asp, updated in lockstep) — not a claim that live interface changes are safe for a published/external client.
WscMvc, binding *:8090, physical path C:\Projects\wsc-mvc.WscMvc, 64-bit, no managed code. Anonymous authentication identity: IUSR.web.config hides Framework/, Controllers/, tests/, tools/, docs/, logs/ (path-segment based, anywhere in the tree) and denies .wsc/.vbs/.ps1/.md by extension.logs/ has an explicit, scoped icacls ... /grant "IIS_IUSRS:(OI)(CI)M" so classic ASP (impersonating IUSR for anonymous requests) can write app.log. No other project directory grants IUSR/IIS_IUSRS write access — verified with a recursive icacls /T scan, see docs/DECISIONS.md.Default.asp; /hello is served via a rewrite rule, not the default document.Per SPEC §3 non-goals and IMPLEMENTATION_PLAN M3+: explicit route table, HTML views/templates, ADODB, auth. A more robust logging mechanism (if complete coverage under concurrent load is ever required) is deferred to M6 — see the concurrency finding in docs/DECISIONS.md.
Powered by TurnKey Linux.