windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/ul/misc/ideas.txt

209 lines
8.2 KiB
Plaintext
Raw Normal View History

2020-09-26 03:20:57 -05:00
Random thoughts, miscellaneous ramblings -- keithmo, 11/30/98
1. The user-mode interface to the open-file-handle-cache is problematic,
especially regarding thread security context (impersonation). We can't
use the IIS-style "match-the-thread-token-handle" technique, as the
cache is accessible from multiple processes which may (probably will)
have different handle values for the same security token. I suspect that
we'd need to actually snapshot the security token whenever an new entry
is inserted into the cache, then compare that snapshot with the incoming
token when testing for a cache hit. Ugh.
I say we yank the user-mode interface.
2. The current thinking for the response-cache has "weak" references to
the open-file-handle-cache. This allows open-file-handle-cache entries
to come & go independently of the response-cache. I think we could
simplify the implementation somewhat by "strengthening" this reference
so that a response-cache entry becomes invalidated whenever any of
the referenced open-file-handle-cache entries are invalidated. This
could be useful as a cheap & easy filesystem "change notify" mechanism
for user-mode worker processes. (See below.)
3. Along the same lines as #2, it may be useful to allow "zero-length"
byte ranges in UL_HTTP_RESPONSE structures. This would allow user-mode
code to establish a relationship between a response-cache entry and
an open-file-handle-cache entry solely for the purposes of invalidation.
Imagine a response-cache entry representing the dynamic output from a
.XSP file. The UL_HTTP_RESPONSE structure representing this response
could contain a zero-length byte range referring to the source .XSP
file. If the .XSP file was flushed from the open-file-handle-cache
(say, due to an oplock break) then the user-mode process would receive
a "normal" cache miss notification.
4. It may be useful to provide a "notification type" value in the
UL_HTTP_REQUEST returned by the UlReceiveHttpRequest() API. This
value would give a "hint" indication for the reason the request
was passed up to user-mode. Possible reasons include:
response-cache miss - The incoming URL was *not* present in
the response-cache.
open-file-handle-cache miss - The incoming URL *was* present
in the response-cache, but one or more of the referenced
files were *not* present in the open-file-handle-cache.
cache policy miss - The incoming URL *was* present in the
response-cache, but the cache-control information set on
the cache entry was incompatible with the incoming request.
security - The incoming URL *was* present in the response-cache,
but the cache entry is configured for a security provider
requring user-mode intervention.
etc, etc, etc
5. Need to add a UlSendHttpResponseFromCache() API. This should take a
UL_HTTP_REQUEST structure as returned by UlReceiveHttpRequest(), hit
the response-cache, and send the cached response if successful. If
the URL is not in the response-cache, then API fails with a
distinguished error value.
6. Probably need a UlReceiveEntityBody() API to read the "leftover" part
of the entity body that could not fit into the original request
buffer.
7. User-mode worker processes issue one or more UlReceiveHttpRequest()
APIs that pend if necessary, waiting for incoming requests. What
happens if the supplied buffer is too small for the incoming request
header?
For each *process*, UL needs a separate queue of pending requests. This
queue represents the set of requests for which either a) an attempt was
made to deliver the request to user-mode but the supplied request buffer
was too small, or b) unread entity body data is remaining.
8. Need a mechanism to notify user-mode whenever an established connection
is disconnected. This is especially useful for worker-processes that
support the old ISAPI filter mechanism.
Unfortunately, we cannot leverage the existing UlReadHttpRequest()
API for these notifications. Consider a Web Garden in which multiple
processes receive requests for a single connection. Which process
gets the notification? The first? The last? All of them?
We'll probably need a separate API for disconnect notifications.
9. With the new handle-based app pool open/creation APIs, UL needs
a reliable way to distinguish three separate open modes:
1. Open a control channel
2. Create a new app pool
3. Open an existing app pool
The "control channel" cases can be distinguished from the "app pool"
cases by the presence of the filename buffer in the FILE_OBJECT. If
there is a name, it's an app pool, if not, it's a control channel.
Distinguishing app pool "create" from "open" is a bit trickier. Some
spelunking uncovered a way: The Disposition parameter to NtCreateFile()
is propagated in the IRP_MJ_CREATE IRP, stuffed into the high byte of
IO_STACK_LOCATION.Parameters.Create.Options.
The creation becomes:
if (pIrpSp->FileObject->FileName.Buffer == NULL)
{
//
// Open a control channel.
//
status = UlpOpenControlChannel( pIrp, pIrpSp );
}
else
{
//
// IO passes the creation disposition in the high byte of
// the Options field. Extract & decode it.
//
switch ((pIrpSp->Parameters.Create.Options >> 24) & 0xFF)
{
case FILE_CREATE:
//
// Create a new app pool. This will fail if the app pool
// already exists.
//
status = UlpCreateAppPool( pIrp, pIrpSp );
break;
case FILE_OPEN:
//
// Open an existing app pool. This will fail if the app
// pool does not already exist.
//
status = UlpOpenAppPool( pIrp, pIrpSp );
break;
default:
//
// No need to be flexible here. Fail the request.
//
status = STATUS_INVALID_PARAMETER;
break;
}
}
10. We still need to think carefully through the whole URL canonicalization
mess. How do we canonicalize an incoming URL if there's no host
header in the request?
Henry has suggested a separate IP-address-to-host-name lookaside
table in UL, configured by user-mode (probably the application
manager).
11. We still need to define the exact contents of the UL_CACHE_POLICY
structure (the one that defines the caching characteristis of
a specific HTTP response).
12. The opaque ID package needs refinement. See objtable.c for one
proposed solution.
13. UL needs a ton of bug fixes on its disconnect logic. The logic is
related to the HTTP protocol version, the transfer encoding, and
whether or not the data is streamed from user-mode:
Version Chunked Non-Chunked
~~~~~~~ ~~~~~~~ Non-Streamed Streamed
~~~~~~~~~~~~ ~~~~~~~~
0.9 N/A CLOSE CLOSE
1.0 N/A CLOSE IF !PC CLOSE
1.1 SEND EMPTY CHUNK, CLOSE IF !PC CLOSE
CLOSE IF !PC
14. We currently use Named Pipes (and MCourage's most-excellent IPM
wrapper) for IPC between WAS and WP. This works great under NT,
but Named Pipes are not supported on Win9x or WinCE.
We could use anonymous pipes (via the CreatePipe() API). However,
while anonymous pipes ARE supported under WinNT and Win9x, they're
NOT supported under WinCE. This may not be a big deal (we probably
won't have a robust process model under WinCE anyway). A bigger
drawback to anonymous pipes is that they are synchronous only
(no overlapped I/O). Yuck.
After further investigation, it appears that we're almost totally
hozed when it comes to IPC on WinCE. As near as I can tell, the
only reasonable IPC mechanism available in WinCE is sockets...