Source code of Windows XP (NT5)
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.

208 lines
8.2 KiB

  1. Random thoughts, miscellaneous ramblings -- keithmo, 11/30/98
  2. 1. The user-mode interface to the open-file-handle-cache is problematic,
  3. especially regarding thread security context (impersonation). We can't
  4. use the IIS-style "match-the-thread-token-handle" technique, as the
  5. cache is accessible from multiple processes which may (probably will)
  6. have different handle values for the same security token. I suspect that
  7. we'd need to actually snapshot the security token whenever an new entry
  8. is inserted into the cache, then compare that snapshot with the incoming
  9. token when testing for a cache hit. Ugh.
  10. I say we yank the user-mode interface.
  11. 2. The current thinking for the response-cache has "weak" references to
  12. the open-file-handle-cache. This allows open-file-handle-cache entries
  13. to come & go independently of the response-cache. I think we could
  14. simplify the implementation somewhat by "strengthening" this reference
  15. so that a response-cache entry becomes invalidated whenever any of
  16. the referenced open-file-handle-cache entries are invalidated. This
  17. could be useful as a cheap & easy filesystem "change notify" mechanism
  18. for user-mode worker processes. (See below.)
  19. 3. Along the same lines as #2, it may be useful to allow "zero-length"
  20. byte ranges in UL_HTTP_RESPONSE structures. This would allow user-mode
  21. code to establish a relationship between a response-cache entry and
  22. an open-file-handle-cache entry solely for the purposes of invalidation.
  23. Imagine a response-cache entry representing the dynamic output from a
  24. .XSP file. The UL_HTTP_RESPONSE structure representing this response
  25. could contain a zero-length byte range referring to the source .XSP
  26. file. If the .XSP file was flushed from the open-file-handle-cache
  27. (say, due to an oplock break) then the user-mode process would receive
  28. a "normal" cache miss notification.
  29. 4. It may be useful to provide a "notification type" value in the
  30. UL_HTTP_REQUEST returned by the UlReceiveHttpRequest() API. This
  31. value would give a "hint" indication for the reason the request
  32. was passed up to user-mode. Possible reasons include:
  33. response-cache miss - The incoming URL was *not* present in
  34. the response-cache.
  35. open-file-handle-cache miss - The incoming URL *was* present
  36. in the response-cache, but one or more of the referenced
  37. files were *not* present in the open-file-handle-cache.
  38. cache policy miss - The incoming URL *was* present in the
  39. response-cache, but the cache-control information set on
  40. the cache entry was incompatible with the incoming request.
  41. security - The incoming URL *was* present in the response-cache,
  42. but the cache entry is configured for a security provider
  43. requring user-mode intervention.
  44. etc, etc, etc
  45. 5. Need to add a UlSendHttpResponseFromCache() API. This should take a
  46. UL_HTTP_REQUEST structure as returned by UlReceiveHttpRequest(), hit
  47. the response-cache, and send the cached response if successful. If
  48. the URL is not in the response-cache, then API fails with a
  49. distinguished error value.
  50. 6. Probably need a UlReceiveEntityBody() API to read the "leftover" part
  51. of the entity body that could not fit into the original request
  52. buffer.
  53. 7. User-mode worker processes issue one or more UlReceiveHttpRequest()
  54. APIs that pend if necessary, waiting for incoming requests. What
  55. happens if the supplied buffer is too small for the incoming request
  56. header?
  57. For each *process*, UL needs a separate queue of pending requests. This
  58. queue represents the set of requests for which either a) an attempt was
  59. made to deliver the request to user-mode but the supplied request buffer
  60. was too small, or b) unread entity body data is remaining.
  61. 8. Need a mechanism to notify user-mode whenever an established connection
  62. is disconnected. This is especially useful for worker-processes that
  63. support the old ISAPI filter mechanism.
  64. Unfortunately, we cannot leverage the existing UlReadHttpRequest()
  65. API for these notifications. Consider a Web Garden in which multiple
  66. processes receive requests for a single connection. Which process
  67. gets the notification? The first? The last? All of them?
  68. We'll probably need a separate API for disconnect notifications.
  69. 9. With the new handle-based app pool open/creation APIs, UL needs
  70. a reliable way to distinguish three separate open modes:
  71. 1. Open a control channel
  72. 2. Create a new app pool
  73. 3. Open an existing app pool
  74. The "control channel" cases can be distinguished from the "app pool"
  75. cases by the presence of the filename buffer in the FILE_OBJECT. If
  76. there is a name, it's an app pool, if not, it's a control channel.
  77. Distinguishing app pool "create" from "open" is a bit trickier. Some
  78. spelunking uncovered a way: The Disposition parameter to NtCreateFile()
  79. is propagated in the IRP_MJ_CREATE IRP, stuffed into the high byte of
  80. IO_STACK_LOCATION.Parameters.Create.Options.
  81. The creation becomes:
  82. if (pIrpSp->FileObject->FileName.Buffer == NULL)
  83. {
  84. //
  85. // Open a control channel.
  86. //
  87. status = UlpOpenControlChannel( pIrp, pIrpSp );
  88. }
  89. else
  90. {
  91. //
  92. // IO passes the creation disposition in the high byte of
  93. // the Options field. Extract & decode it.
  94. //
  95. switch ((pIrpSp->Parameters.Create.Options >> 24) & 0xFF)
  96. {
  97. case FILE_CREATE:
  98. //
  99. // Create a new app pool. This will fail if the app pool
  100. // already exists.
  101. //
  102. status = UlpCreateAppPool( pIrp, pIrpSp );
  103. break;
  104. case FILE_OPEN:
  105. //
  106. // Open an existing app pool. This will fail if the app
  107. // pool does not already exist.
  108. //
  109. status = UlpOpenAppPool( pIrp, pIrpSp );
  110. break;
  111. default:
  112. //
  113. // No need to be flexible here. Fail the request.
  114. //
  115. status = STATUS_INVALID_PARAMETER;
  116. break;
  117. }
  118. }
  119. 10. We still need to think carefully through the whole URL canonicalization
  120. mess. How do we canonicalize an incoming URL if there's no host
  121. header in the request?
  122. Henry has suggested a separate IP-address-to-host-name lookaside
  123. table in UL, configured by user-mode (probably the application
  124. manager).
  125. 11. We still need to define the exact contents of the UL_CACHE_POLICY
  126. structure (the one that defines the caching characteristis of
  127. a specific HTTP response).
  128. 12. The opaque ID package needs refinement. See objtable.c for one
  129. proposed solution.
  130. 13. UL needs a ton of bug fixes on its disconnect logic. The logic is
  131. related to the HTTP protocol version, the transfer encoding, and
  132. whether or not the data is streamed from user-mode:
  133. Version Chunked Non-Chunked
  134. ~~~~~~~ ~~~~~~~ Non-Streamed Streamed
  135. ~~~~~~~~~~~~ ~~~~~~~~
  136. 0.9 N/A CLOSE CLOSE
  137. 1.0 N/A CLOSE IF !PC CLOSE
  138. 1.1 SEND EMPTY CHUNK, CLOSE IF !PC CLOSE
  139. CLOSE IF !PC
  140. 14. We currently use Named Pipes (and MCourage's most-excellent IPM
  141. wrapper) for IPC between WAS and WP. This works great under NT,
  142. but Named Pipes are not supported on Win9x or WinCE.
  143. We could use anonymous pipes (via the CreatePipe() API). However,
  144. while anonymous pipes ARE supported under WinNT and Win9x, they're
  145. NOT supported under WinCE. This may not be a big deal (we probably
  146. won't have a robust process model under WinCE anyway). A bigger
  147. drawback to anonymous pipes is that they are synchronous only
  148. (no overlapped I/O). Yuck.
  149. After further investigation, it appears that we're almost totally
  150. hozed when it comes to IPC on WinCE. As near as I can tell, the
  151. only reasonable IPC mechanism available in WinCE is sockets...