Leaked source code of windows server 2003
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.

2514 lines
64 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. servervar.cxx
  5. Abstract:
  6. Server Variable evaluation goo
  7. Author:
  8. Bilal Alam (balam) 20-Feb-2000
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. ULW3.DLL
  13. --*/
  14. #include "precomp.hxx"
  15. const DWORD MAX_IP_ADDRESS_CHARS = 15;
  16. HRESULT
  17. TranslateIpAddressToStr (
  18. DWORD dwAddress,
  19. STRA * pstraBuffer
  20. )
  21. /*++
  22. Routine Description:
  23. Convert DWORD representing IP address into a string in dotted format.
  24. based in inet_ntoa. TLS has been eliminated adding a little perf gain.
  25. Arguments:
  26. dwAddress - DWORD address is in reverse order
  27. pstraBuffer - static buffer containing the text address in standard ".''
  28. notation.
  29. Returns:
  30. HRESULT
  31. --*/
  32. {
  33. PUCHAR pAddress;
  34. PUCHAR pCurrentChar;
  35. HRESULT hr = E_FAIL;
  36. STACK_STRA( strBuff, 32 );
  37. static BYTE NToACharStrings[][4] = {
  38. '0', 'x', 'x', 1,
  39. '1', 'x', 'x', 1,
  40. '2', 'x', 'x', 1,
  41. '3', 'x', 'x', 1,
  42. '4', 'x', 'x', 1,
  43. '5', 'x', 'x', 1,
  44. '6', 'x', 'x', 1,
  45. '7', 'x', 'x', 1,
  46. '8', 'x', 'x', 1,
  47. '9', 'x', 'x', 1,
  48. '1', '0', 'x', 2,
  49. '1', '1', 'x', 2,
  50. '1', '2', 'x', 2,
  51. '1', '3', 'x', 2,
  52. '1', '4', 'x', 2,
  53. '1', '5', 'x', 2,
  54. '1', '6', 'x', 2,
  55. '1', '7', 'x', 2,
  56. '1', '8', 'x', 2,
  57. '1', '9', 'x', 2,
  58. '2', '0', 'x', 2,
  59. '2', '1', 'x', 2,
  60. '2', '2', 'x', 2,
  61. '2', '3', 'x', 2,
  62. '2', '4', 'x', 2,
  63. '2', '5', 'x', 2,
  64. '2', '6', 'x', 2,
  65. '2', '7', 'x', 2,
  66. '2', '8', 'x', 2,
  67. '2', '9', 'x', 2,
  68. '3', '0', 'x', 2,
  69. '3', '1', 'x', 2,
  70. '3', '2', 'x', 2,
  71. '3', '3', 'x', 2,
  72. '3', '4', 'x', 2,
  73. '3', '5', 'x', 2,
  74. '3', '6', 'x', 2,
  75. '3', '7', 'x', 2,
  76. '3', '8', 'x', 2,
  77. '3', '9', 'x', 2,
  78. '4', '0', 'x', 2,
  79. '4', '1', 'x', 2,
  80. '4', '2', 'x', 2,
  81. '4', '3', 'x', 2,
  82. '4', '4', 'x', 2,
  83. '4', '5', 'x', 2,
  84. '4', '6', 'x', 2,
  85. '4', '7', 'x', 2,
  86. '4', '8', 'x', 2,
  87. '4', '9', 'x', 2,
  88. '5', '0', 'x', 2,
  89. '5', '1', 'x', 2,
  90. '5', '2', 'x', 2,
  91. '5', '3', 'x', 2,
  92. '5', '4', 'x', 2,
  93. '5', '5', 'x', 2,
  94. '5', '6', 'x', 2,
  95. '5', '7', 'x', 2,
  96. '5', '8', 'x', 2,
  97. '5', '9', 'x', 2,
  98. '6', '0', 'x', 2,
  99. '6', '1', 'x', 2,
  100. '6', '2', 'x', 2,
  101. '6', '3', 'x', 2,
  102. '6', '4', 'x', 2,
  103. '6', '5', 'x', 2,
  104. '6', '6', 'x', 2,
  105. '6', '7', 'x', 2,
  106. '6', '8', 'x', 2,
  107. '6', '9', 'x', 2,
  108. '7', '0', 'x', 2,
  109. '7', '1', 'x', 2,
  110. '7', '2', 'x', 2,
  111. '7', '3', 'x', 2,
  112. '7', '4', 'x', 2,
  113. '7', '5', 'x', 2,
  114. '7', '6', 'x', 2,
  115. '7', '7', 'x', 2,
  116. '7', '8', 'x', 2,
  117. '7', '9', 'x', 2,
  118. '8', '0', 'x', 2,
  119. '8', '1', 'x', 2,
  120. '8', '2', 'x', 2,
  121. '8', '3', 'x', 2,
  122. '8', '4', 'x', 2,
  123. '8', '5', 'x', 2,
  124. '8', '6', 'x', 2,
  125. '8', '7', 'x', 2,
  126. '8', '8', 'x', 2,
  127. '8', '9', 'x', 2,
  128. '9', '0', 'x', 2,
  129. '9', '1', 'x', 2,
  130. '9', '2', 'x', 2,
  131. '9', '3', 'x', 2,
  132. '9', '4', 'x', 2,
  133. '9', '5', 'x', 2,
  134. '9', '6', 'x', 2,
  135. '9', '7', 'x', 2,
  136. '9', '8', 'x', 2,
  137. '9', '9', 'x', 2,
  138. '1', '0', '0', 3,
  139. '1', '0', '1', 3,
  140. '1', '0', '2', 3,
  141. '1', '0', '3', 3,
  142. '1', '0', '4', 3,
  143. '1', '0', '5', 3,
  144. '1', '0', '6', 3,
  145. '1', '0', '7', 3,
  146. '1', '0', '8', 3,
  147. '1', '0', '9', 3,
  148. '1', '1', '0', 3,
  149. '1', '1', '1', 3,
  150. '1', '1', '2', 3,
  151. '1', '1', '3', 3,
  152. '1', '1', '4', 3,
  153. '1', '1', '5', 3,
  154. '1', '1', '6', 3,
  155. '1', '1', '7', 3,
  156. '1', '1', '8', 3,
  157. '1', '1', '9', 3,
  158. '1', '2', '0', 3,
  159. '1', '2', '1', 3,
  160. '1', '2', '2', 3,
  161. '1', '2', '3', 3,
  162. '1', '2', '4', 3,
  163. '1', '2', '5', 3,
  164. '1', '2', '6', 3,
  165. '1', '2', '7', 3,
  166. '1', '2', '8', 3,
  167. '1', '2', '9', 3,
  168. '1', '3', '0', 3,
  169. '1', '3', '1', 3,
  170. '1', '3', '2', 3,
  171. '1', '3', '3', 3,
  172. '1', '3', '4', 3,
  173. '1', '3', '5', 3,
  174. '1', '3', '6', 3,
  175. '1', '3', '7', 3,
  176. '1', '3', '8', 3,
  177. '1', '3', '9', 3,
  178. '1', '4', '0', 3,
  179. '1', '4', '1', 3,
  180. '1', '4', '2', 3,
  181. '1', '4', '3', 3,
  182. '1', '4', '4', 3,
  183. '1', '4', '5', 3,
  184. '1', '4', '6', 3,
  185. '1', '4', '7', 3,
  186. '1', '4', '8', 3,
  187. '1', '4', '9', 3,
  188. '1', '5', '0', 3,
  189. '1', '5', '1', 3,
  190. '1', '5', '2', 3,
  191. '1', '5', '3', 3,
  192. '1', '5', '4', 3,
  193. '1', '5', '5', 3,
  194. '1', '5', '6', 3,
  195. '1', '5', '7', 3,
  196. '1', '5', '8', 3,
  197. '1', '5', '9', 3,
  198. '1', '6', '0', 3,
  199. '1', '6', '1', 3,
  200. '1', '6', '2', 3,
  201. '1', '6', '3', 3,
  202. '1', '6', '4', 3,
  203. '1', '6', '5', 3,
  204. '1', '6', '6', 3,
  205. '1', '6', '7', 3,
  206. '1', '6', '8', 3,
  207. '1', '6', '9', 3,
  208. '1', '7', '0', 3,
  209. '1', '7', '1', 3,
  210. '1', '7', '2', 3,
  211. '1', '7', '3', 3,
  212. '1', '7', '4', 3,
  213. '1', '7', '5', 3,
  214. '1', '7', '6', 3,
  215. '1', '7', '7', 3,
  216. '1', '7', '8', 3,
  217. '1', '7', '9', 3,
  218. '1', '8', '0', 3,
  219. '1', '8', '1', 3,
  220. '1', '8', '2', 3,
  221. '1', '8', '3', 3,
  222. '1', '8', '4', 3,
  223. '1', '8', '5', 3,
  224. '1', '8', '6', 3,
  225. '1', '8', '7', 3,
  226. '1', '8', '8', 3,
  227. '1', '8', '9', 3,
  228. '1', '9', '0', 3,
  229. '1', '9', '1', 3,
  230. '1', '9', '2', 3,
  231. '1', '9', '3', 3,
  232. '1', '9', '4', 3,
  233. '1', '9', '5', 3,
  234. '1', '9', '6', 3,
  235. '1', '9', '7', 3,
  236. '1', '9', '8', 3,
  237. '1', '9', '9', 3,
  238. '2', '0', '0', 3,
  239. '2', '0', '1', 3,
  240. '2', '0', '2', 3,
  241. '2', '0', '3', 3,
  242. '2', '0', '4', 3,
  243. '2', '0', '5', 3,
  244. '2', '0', '6', 3,
  245. '2', '0', '7', 3,
  246. '2', '0', '8', 3,
  247. '2', '0', '9', 3,
  248. '2', '1', '0', 3,
  249. '2', '1', '1', 3,
  250. '2', '1', '2', 3,
  251. '2', '1', '3', 3,
  252. '2', '1', '4', 3,
  253. '2', '1', '5', 3,
  254. '2', '1', '6', 3,
  255. '2', '1', '7', 3,
  256. '2', '1', '8', 3,
  257. '2', '1', '9', 3,
  258. '2', '2', '0', 3,
  259. '2', '2', '1', 3,
  260. '2', '2', '2', 3,
  261. '2', '2', '3', 3,
  262. '2', '2', '4', 3,
  263. '2', '2', '5', 3,
  264. '2', '2', '6', 3,
  265. '2', '2', '7', 3,
  266. '2', '2', '8', 3,
  267. '2', '2', '9', 3,
  268. '2', '3', '0', 3,
  269. '2', '3', '1', 3,
  270. '2', '3', '2', 3,
  271. '2', '3', '3', 3,
  272. '2', '3', '4', 3,
  273. '2', '3', '5', 3,
  274. '2', '3', '6', 3,
  275. '2', '3', '7', 3,
  276. '2', '3', '8', 3,
  277. '2', '3', '9', 3,
  278. '2', '4', '0', 3,
  279. '2', '4', '1', 3,
  280. '2', '4', '2', 3,
  281. '2', '4', '3', 3,
  282. '2', '4', '4', 3,
  283. '2', '4', '5', 3,
  284. '2', '4', '6', 3,
  285. '2', '4', '7', 3,
  286. '2', '4', '8', 3,
  287. '2', '4', '9', 3,
  288. '2', '5', '0', 3,
  289. '2', '5', '1', 3,
  290. '2', '5', '2', 3,
  291. '2', '5', '3', 3,
  292. '2', '5', '4', 3,
  293. '2', '5', '5', 3
  294. };
  295. hr = strBuff.Resize( MAX_IP_ADDRESS_CHARS + 1 ); // to assure buffer is big enough
  296. if ( FAILED( hr ) )
  297. {
  298. return hr;
  299. }
  300. PUCHAR pszBuffer = (PUCHAR) strBuff.QueryStr();
  301. pCurrentChar = pszBuffer;
  302. //
  303. // In an unrolled loop, calculate the string value for each of the four
  304. // bytes in an IP address. Note that for values less than 100 we will
  305. // do one or two extra assignments, but we save a test/jump with this
  306. // algorithm.
  307. //
  308. pAddress = (PUCHAR)&dwAddress;
  309. //
  310. // address is in reverse order
  311. //
  312. pAddress += 3;
  313. *pCurrentChar = NToACharStrings[*pAddress][0];
  314. *(pCurrentChar+1) = NToACharStrings[*pAddress][1];
  315. *(pCurrentChar+2) = NToACharStrings[*pAddress][2];
  316. pCurrentChar += NToACharStrings[*pAddress][3];
  317. *pCurrentChar++ = '.';
  318. pAddress--;
  319. *pCurrentChar = NToACharStrings[*pAddress][0];
  320. *(pCurrentChar+1) = NToACharStrings[*pAddress][1];
  321. *(pCurrentChar+2) = NToACharStrings[*pAddress][2];
  322. pCurrentChar += NToACharStrings[*pAddress][3];
  323. *pCurrentChar++ = '.';
  324. pAddress--;
  325. *pCurrentChar = NToACharStrings[*pAddress][0];
  326. *(pCurrentChar+1) = NToACharStrings[*pAddress][1];
  327. *(pCurrentChar+2) = NToACharStrings[*pAddress][2];
  328. pCurrentChar += NToACharStrings[*pAddress][3];
  329. *pCurrentChar++ = '.';
  330. pAddress--;
  331. *pCurrentChar = NToACharStrings[*pAddress][0];
  332. *(pCurrentChar+1) = NToACharStrings[*pAddress][1];
  333. *(pCurrentChar+2) = NToACharStrings[*pAddress][2];
  334. pCurrentChar += NToACharStrings[*pAddress][3];
  335. *pCurrentChar = '\0';
  336. return pstraBuffer->Copy( (CHAR*) pszBuffer );
  337. }
  338. //
  339. // Hash table mapping variable name to a PFN_SERVER_VARIABLE_ROUTINE
  340. //
  341. SERVER_VARIABLE_HASH * SERVER_VARIABLE_HASH::sm_pRequestHash;
  342. SERVER_VARIABLE_RECORD SERVER_VARIABLE_HASH::sm_rgServerRoutines[] =
  343. {
  344. { "ALL_HTTP", GetServerVariableAllHttp, NULL, NULL },
  345. { "ALL_RAW", GetServerVariableAllRaw, NULL, NULL },
  346. { "APPL_MD_PATH", GetServerVariableApplMdPath, GetServerVariableApplMdPathW, NULL },
  347. { "APPL_PHYSICAL_PATH", GetServerVariableApplPhysicalPath, GetServerVariableApplPhysicalPathW , NULL },
  348. { "APP_POOL_ID", GetServerVariableAppPoolId, GetServerVariableAppPoolIdW, NULL },
  349. { "AUTH_PASSWORD", GetServerVariableAuthPassword, NULL, NULL },
  350. { "AUTH_TYPE", GetServerVariableAuthType, NULL, NULL },
  351. { "AUTH_USER", GetServerVariableRemoteUser, GetServerVariableRemoteUserW, NULL },
  352. { "CACHE_URL", GetServerVariableOriginalUrl, GetServerVariableOriginalUrlW, NULL },
  353. { "CERT_COOKIE", GetServerVariableClientCertCookie, NULL, NULL },
  354. { "CERT_FLAGS", GetServerVariableClientCertFlags, NULL, NULL },
  355. { "CERT_ISSUER", GetServerVariableClientCertIssuer, NULL, NULL },
  356. { "CERT_KEYSIZE", GetServerVariableHttpsKeySize, NULL, NULL },
  357. { "CERT_SECRETKEYSIZE", GetServerVariableHttpsSecretKeySize, NULL, NULL },
  358. { "CERT_SERIALNUMBER", GetServerVariableClientCertSerialNumber, NULL, NULL },
  359. { "CERT_SERVER_ISSUER", GetServerVariableHttpsServerIssuer, NULL, NULL },
  360. { "CERT_SERVER_SUBJECT", GetServerVariableHttpsServerSubject, NULL, NULL },
  361. { "CERT_SUBJECT", GetServerVariableClientCertSubject, NULL, NULL },
  362. { "CONTENT_LENGTH", GetServerVariableContentLength, NULL, NULL },
  363. { "CONTENT_TYPE", GetServerVariableContentType, NULL, NULL },
  364. { "GATEWAY_INTERFACE", GetServerVariableGatewayInterface, NULL, NULL },
  365. { "HTTPS", GetServerVariableHttps, NULL, NULL },
  366. { "HTTPS_KEYSIZE", GetServerVariableHttpsKeySize, NULL, NULL },
  367. { "HTTPS_SECRETKEYSIZE", GetServerVariableHttpsSecretKeySize, NULL, NULL },
  368. { "HTTPS_SERVER_ISSUER", GetServerVariableHttpsServerIssuer, NULL, NULL },
  369. { "HTTPS_SERVER_SUBJECT", GetServerVariableHttpsServerSubject, NULL, NULL },
  370. { "HTTP_URL", GetServerVariableHttpUrl, NULL, NULL },
  371. { "HTTP_METHOD", GetServerVariableRequestMethod, NULL, NULL },
  372. { "HTTP_VERSION", GetServerVariableHttpVersion, NULL, NULL },
  373. { "INSTANCE_ID", GetServerVariableInstanceId, NULL, NULL },
  374. { "INSTANCE_META_PATH", GetServerVariableInstanceMetaPath, NULL, NULL },
  375. { "LOCAL_ADDR", GetServerVariableLocalAddr, NULL, NULL },
  376. { "LOGON_USER", GetServerVariableLogonUser, GetServerVariableLogonUserW, NULL },
  377. { "PATH_INFO", GetServerVariablePathInfo, GetServerVariablePathInfoW, NULL },
  378. { "PATH_TRANSLATED", GetServerVariablePathTranslated, GetServerVariablePathTranslatedW, NULL },
  379. { "QUERY_STRING", GetServerVariableQueryString, NULL, NULL },
  380. { "REMOTE_ADDR", GetServerVariableRemoteAddr, NULL, NULL },
  381. { "REMOTE_HOST", GetServerVariableRemoteHost, NULL, NULL },
  382. { "REMOTE_PORT", GetServerVariableRemotePort, NULL, NULL },
  383. { "REMOTE_USER", GetServerVariableRemoteUser, GetServerVariableRemoteUserW, NULL },
  384. { "REQUEST_METHOD", GetServerVariableRequestMethod, NULL, NULL },
  385. { "SCRIPT_NAME", GetServerVariableUrl, GetServerVariableUrlW, NULL },
  386. { "SCRIPT_TRANSLATED", GetServerVariableScriptTranslated, GetServerVariableScriptTranslatedW, NULL },
  387. { "SERVER_NAME", GetServerVariableServerName, GetServerVariableServerNameW, NULL },
  388. { "SERVER_PORT", GetServerVariableServerPort, NULL, NULL },
  389. { "SERVER_PORT_SECURE", GetServerVariableServerPortSecure, NULL, NULL },
  390. { "SERVER_PROTOCOL", GetServerVariableHttpVersion, NULL, NULL },
  391. { "SERVER_SOFTWARE", GetServerVariableServerSoftware, NULL, NULL },
  392. { "SSI_EXEC_DISABLED", GetServerVariableSsiExecDisabled, NULL, NULL },
  393. { "UNENCODED_URL", GetServerVariableUnencodedUrl, NULL, NULL },
  394. { "UNMAPPED_REMOTE_USER", GetServerVariableRemoteUser, GetServerVariableRemoteUserW, NULL },
  395. { "URL", GetServerVariableUrl, GetServerVariableUrlW, NULL },
  396. { NULL, NULL, NULL, NULL }
  397. };
  398. //static
  399. HRESULT
  400. SERVER_VARIABLE_HASH::Initialize(
  401. VOID
  402. )
  403. /*++
  404. Routine Description:
  405. Initialize global server variable hash table
  406. Arguments:
  407. None
  408. Return Value:
  409. HRESULT
  410. --*/
  411. {
  412. SERVER_VARIABLE_RECORD * pRecord;
  413. LK_RETCODE lkrc = LK_SUCCESS;
  414. sm_pRequestHash = new SERVER_VARIABLE_HASH;
  415. if ( sm_pRequestHash == NULL )
  416. {
  417. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  418. }
  419. //
  420. // Add every string->routine mapping
  421. //
  422. pRecord = sm_rgServerRoutines;
  423. while ( pRecord->_pszName != NULL )
  424. {
  425. sm_pRequestHash->InsertRecord( pRecord );
  426. pRecord++;
  427. }
  428. //
  429. // If any insert failed, then fail initialization
  430. //
  431. if ( lkrc != LK_SUCCESS )
  432. {
  433. delete sm_pRequestHash;
  434. sm_pRequestHash = NULL;
  435. return HRESULT_FROM_WIN32( lkrc ); // ARGH
  436. }
  437. else
  438. {
  439. return NO_ERROR;
  440. }
  441. }
  442. //static
  443. VOID
  444. SERVER_VARIABLE_HASH::Terminate(
  445. VOID
  446. )
  447. /*++
  448. Routine Description:
  449. Cleanup global server variable hash table
  450. Arguments:
  451. None
  452. Return Value:
  453. None
  454. --*/
  455. {
  456. if ( sm_pRequestHash != NULL )
  457. {
  458. delete sm_pRequestHash;
  459. sm_pRequestHash = NULL;
  460. }
  461. }
  462. //static
  463. HRESULT
  464. SERVER_VARIABLE_HASH::GetServerVariableRoutine(
  465. CHAR * pszName,
  466. PFN_SERVER_VARIABLE_ROUTINE * ppfnRoutine,
  467. PFN_SERVER_VARIABLE_ROUTINE_W * ppfnRoutineW
  468. )
  469. /*++
  470. Routine Description:
  471. Lookup the hash table for a routine to evaluate the given variable
  472. Arguments:
  473. pszName - Name of server variable
  474. ppfnRoutine - Set to the routine if successful
  475. Return Value:
  476. HRESULT
  477. --*/
  478. {
  479. SERVER_VARIABLE_RECORD* pServerVariableRecord = NULL;
  480. if ( pszName == NULL ||
  481. ppfnRoutine == NULL ||
  482. ppfnRoutineW == NULL )
  483. {
  484. DBG_ASSERT( FALSE );
  485. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  486. }
  487. DBG_ASSERT( sm_pRequestHash != NULL );
  488. pServerVariableRecord = sm_pRequestHash->FindKey( pszName );
  489. if ( pServerVariableRecord == NULL )
  490. {
  491. return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  492. }
  493. else
  494. {
  495. DBG_ASSERT( pServerVariableRecord != NULL );
  496. *ppfnRoutine = pServerVariableRecord->_pfnRoutine;
  497. *ppfnRoutineW = pServerVariableRecord->_pfnRoutineW;
  498. return NO_ERROR;
  499. }
  500. }
  501. //static
  502. HRESULT
  503. SERVER_VARIABLE_HASH::GetServerVariable(
  504. W3_CONTEXT * pW3Context,
  505. CHAR * pszVariableName,
  506. CHAR * pszBuffer,
  507. DWORD * pcbBuffer
  508. )
  509. /*++
  510. Routine Description:
  511. Get server variable
  512. Arguments:
  513. pW3Context - W3_CONTEXT with request state. Can be NULL if we are
  514. just determining whether the server variable requested is
  515. valid.
  516. pszVariable - Variable name to retrieve
  517. pszBuffer - Filled with variable on success
  518. pcbBuffer - On input, the size of input buffer. On out, the required size
  519. Return Value:
  520. HRESULT
  521. --*/
  522. {
  523. HRESULT hr;
  524. DWORD cbOriginalBuffer = *pcbBuffer;
  525. //
  526. // For performance sake, do some Kung Fu to minimize buffer copies
  527. // We'll initialize our string with the user's input buffer. If
  528. // it wasn't big enough, we'll handle it
  529. //
  530. if (pszVariableName[0] == 'U' &&
  531. strncmp(pszVariableName, "UNICODE_", 8) == 0)
  532. {
  533. WCHAR achBuffer[ 512 ];
  534. STRU strValW( *pcbBuffer ? (LPWSTR)pszBuffer : achBuffer,
  535. *pcbBuffer ? *pcbBuffer : sizeof( achBuffer ) );
  536. hr = GetServerVariableW( pW3Context,
  537. pszVariableName + 8,
  538. &strValW );
  539. if ( FAILED( hr ) )
  540. {
  541. return hr;
  542. }
  543. *pcbBuffer = strValW.QueryCB() + sizeof( WCHAR );
  544. //
  545. // Did we have to resize the buffer?
  546. //
  547. if ( strValW.QueryStr() != (LPWSTR) pszBuffer )
  548. {
  549. //
  550. // Still might have enough space in source buffer, if
  551. // ServerVariable routine resizes buffer to larger than
  552. // really needed (lame)
  553. //
  554. if ( *pcbBuffer <= cbOriginalBuffer )
  555. {
  556. memcpy( pszBuffer,
  557. strValW.QueryStr(),
  558. *pcbBuffer );
  559. return NO_ERROR;
  560. }
  561. else
  562. {
  563. //
  564. // User string wasn't big enough
  565. //
  566. return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
  567. }
  568. }
  569. else
  570. {
  571. return NO_ERROR;
  572. }
  573. }
  574. else
  575. {
  576. CHAR achBuffer[ 512 ];
  577. STRA strVal( *pcbBuffer ? pszBuffer : achBuffer,
  578. *pcbBuffer ? *pcbBuffer : sizeof( achBuffer ) );
  579. hr = GetServerVariable( pW3Context,
  580. pszVariableName,
  581. &strVal );
  582. if ( FAILED( hr ) )
  583. {
  584. return hr;
  585. }
  586. *pcbBuffer = strVal.QueryCB() + sizeof( CHAR );
  587. //
  588. // Did we have to resize the buffer?
  589. //
  590. if ( strVal.QueryStr() != pszBuffer )
  591. {
  592. //
  593. // Still might have enough space in source buffer, if
  594. // ServerVariable routine resizes buffer to larger than
  595. // really needed (lame)
  596. //
  597. if ( *pcbBuffer <= cbOriginalBuffer )
  598. {
  599. memcpy( pszBuffer,
  600. strVal.QueryStr(),
  601. *pcbBuffer );
  602. return NO_ERROR;
  603. }
  604. else
  605. {
  606. //
  607. // User string wasn't big enough
  608. //
  609. return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
  610. }
  611. }
  612. else
  613. {
  614. return NO_ERROR;
  615. }
  616. }
  617. }
  618. //static
  619. HRESULT
  620. SERVER_VARIABLE_HASH::GetServerVariable(
  621. W3_CONTEXT * pW3Context,
  622. CHAR * pszVariableName,
  623. STRA * pstrVal
  624. )
  625. /*++
  626. Routine Description:
  627. Get server variable
  628. Arguments:
  629. pW3Context - W3_CONTEXT with request state. Can be NULL if we are
  630. just determining whether the server variable requested is
  631. valid. If NULL, we will return an empty string (and success)
  632. if the variable requested is valid.
  633. pszVariable - Variable name to retrieve
  634. pstrVal - Filled with variable on success
  635. Return Value:
  636. HRESULT
  637. --*/
  638. {
  639. HRESULT hr = S_OK;
  640. PFN_SERVER_VARIABLE_ROUTINE pfnRoutine = NULL;
  641. PFN_SERVER_VARIABLE_ROUTINE_W pfnRoutineW = NULL;
  642. //
  643. // First: Is this a server variable we know about? If so handle it
  644. // by calling the appropriate server variable routine
  645. //
  646. hr = SERVER_VARIABLE_HASH::GetServerVariableRoutine( pszVariableName,
  647. &pfnRoutine,
  648. &pfnRoutineW );
  649. if ( SUCCEEDED(hr) )
  650. {
  651. DBG_ASSERT( pfnRoutine != NULL );
  652. if ( pW3Context != NULL )
  653. {
  654. return pfnRoutine( pW3Context, pstrVal );
  655. }
  656. else
  657. {
  658. //
  659. // Just return empty string to signify that the variable is
  660. // valid but we just don't know the value at this time
  661. //
  662. return pstrVal->Copy( "", 0 );
  663. }
  664. }
  665. //
  666. // Second: Is this a header name (prefixed with HTTP_)
  667. //
  668. if ( pW3Context != NULL &&
  669. pszVariableName[ 0 ] == 'H' &&
  670. !strncmp( pszVariableName, "HTTP_" , 5 ) )
  671. {
  672. STACK_STRA( strVariable, 256 );
  673. hr = strVariable.Copy( pszVariableName + 5 );
  674. if ( FAILED( hr ) )
  675. {
  676. return hr;
  677. }
  678. // Change '_' to '-'
  679. PCHAR pszCursor = strchr( strVariable.QueryStr(), '_' );
  680. while ( pszCursor != NULL )
  681. {
  682. *pszCursor++ = '-';
  683. pszCursor = strchr( pszCursor, '_' );
  684. }
  685. return pW3Context->QueryRequest()->GetHeader( strVariable,
  686. pstrVal );
  687. }
  688. //
  689. // Third: Is this an uncanonicalized header name (prefixed with HEADER_)
  690. //
  691. if ( pW3Context != NULL &&
  692. pszVariableName[ 0 ] == 'H' &&
  693. !strncmp( pszVariableName, "HEADER_" , 7 ) )
  694. {
  695. STACK_STRA( strVariable, 256 );
  696. hr = strVariable.Copy( pszVariableName + 7 );
  697. if ( FAILED( hr ) )
  698. {
  699. return hr;
  700. }
  701. return pW3Context->QueryRequest()->GetHeader( strVariable,
  702. pstrVal );
  703. }
  704. return HRESULT_FROM_WIN32( ERROR_INVALID_INDEX );
  705. }
  706. //static
  707. HRESULT
  708. SERVER_VARIABLE_HASH::GetServerVariableW(
  709. W3_CONTEXT * pW3Context,
  710. CHAR * pszVariableName,
  711. STRU * pstrVal
  712. )
  713. /*++
  714. Routine Description:
  715. Get server variable
  716. Arguments:
  717. pW3Context - W3_CONTEXT with request state. Can be NULL if we are
  718. just determining whether the server variable requested is
  719. valid. If NULL, we will return an empty string (and success)
  720. if the variable requested is valid.
  721. pszVariable - Variable name to retrieve
  722. pstrVal - Filled with variable on success
  723. Return Value:
  724. HRESULT
  725. --*/
  726. {
  727. HRESULT hr = S_OK;
  728. PFN_SERVER_VARIABLE_ROUTINE pfnRoutine = NULL;
  729. PFN_SERVER_VARIABLE_ROUTINE_W pfnRoutineW = NULL;
  730. hr = SERVER_VARIABLE_HASH::GetServerVariableRoutine( pszVariableName,
  731. &pfnRoutine,
  732. &pfnRoutineW );
  733. if ( SUCCEEDED(hr) )
  734. {
  735. if (pW3Context == NULL)
  736. {
  737. //
  738. // Just return empty string to signify that the variable is
  739. // valid but we just don't know the value at this time
  740. //
  741. return pstrVal->Copy( L"", 0 );
  742. }
  743. if (pfnRoutineW != NULL)
  744. {
  745. //
  746. // This server-variable contains real unicode data and there
  747. // is a unicode ServerVariable routine for this
  748. //
  749. return pfnRoutineW( pW3Context, pstrVal );
  750. }
  751. else
  752. {
  753. //
  754. // No unicode version, use the ANSI version and just wide'ize it
  755. //
  756. STACK_STRA( straVal, 256);
  757. DBG_ASSERT( pfnRoutine != NULL );
  758. if (FAILED(hr = pfnRoutine( pW3Context, &straVal )) ||
  759. FAILED(hr = pstrVal->CopyA( straVal.QueryStr(),
  760. straVal.QueryCCH() )))
  761. {
  762. return hr;
  763. }
  764. return S_OK;
  765. }
  766. }
  767. return HRESULT_FROM_WIN32( ERROR_INVALID_INDEX );
  768. }
  769. //
  770. // Server variable functions
  771. //
  772. HRESULT
  773. GetServerVariableQueryString(
  774. W3_CONTEXT *pW3Context,
  775. STRA *pstrVal
  776. )
  777. {
  778. DBG_ASSERT( pW3Context != NULL );
  779. return pW3Context->QueryRequest()->GetQueryStringA(pstrVal);
  780. }
  781. HRESULT
  782. GetServerVariableAllHttp(
  783. W3_CONTEXT *pW3Context,
  784. STRA *pstrVal
  785. )
  786. {
  787. DBG_ASSERT( pW3Context != NULL );
  788. return pW3Context->QueryRequest()->GetAllHeaders( pstrVal, TRUE );
  789. }
  790. HRESULT
  791. GetServerVariableAllRaw(
  792. W3_CONTEXT *pW3Context,
  793. STRA *pstrVal
  794. )
  795. {
  796. DBG_ASSERT( pW3Context != NULL );
  797. return pW3Context->QueryRequest()->GetAllHeaders( pstrVal, FALSE );
  798. }
  799. HRESULT
  800. GetServerVariableContentLength(
  801. W3_CONTEXT *pW3Context,
  802. STRA *pstrVal
  803. )
  804. {
  805. const CHAR * pszContentLength;
  806. DBG_ASSERT( pW3Context != NULL );
  807. if ( pW3Context->QueryRequest()->IsChunkedRequest() )
  808. {
  809. pszContentLength = "-1";
  810. }
  811. else
  812. {
  813. pszContentLength = pW3Context->QueryRequest()->GetHeader( HttpHeaderContentLength );
  814. if ( pszContentLength == NULL )
  815. {
  816. pszContentLength = "0";
  817. }
  818. }
  819. return pstrVal->Copy( pszContentLength );
  820. }
  821. HRESULT
  822. GetServerVariableContentType(
  823. W3_CONTEXT *pW3Context,
  824. STRA *pstrVal
  825. )
  826. {
  827. DBG_ASSERT( pW3Context != NULL );
  828. LPCSTR pszContentType = pW3Context->QueryRequest()->
  829. GetHeader( HttpHeaderContentType );
  830. if ( pszContentType == NULL )
  831. {
  832. pszContentType = "";
  833. }
  834. return pstrVal->Copy( pszContentType );
  835. }
  836. HRESULT
  837. GetServerVariableInstanceId(
  838. W3_CONTEXT *pW3Context,
  839. STRA *pstrVal
  840. )
  841. {
  842. DBG_ASSERT( pW3Context != NULL );
  843. CHAR pszId[16];
  844. _itoa( pW3Context->QueryRequest()->QuerySiteId(), pszId, 10 );
  845. return pstrVal->Copy( pszId );
  846. }
  847. HRESULT
  848. GetServerVariableRemoteHost(
  849. W3_CONTEXT *pW3Context,
  850. STRA *pstrVal
  851. )
  852. {
  853. HRESULT hr;
  854. DBG_ASSERT( pW3Context != NULL );
  855. //
  856. // If we have a resolved DNS name, then use it. Otherwise just
  857. // return the address
  858. //
  859. hr = pW3Context->QueryMainContext()->GetRemoteDNSName( pstrVal );
  860. if ( hr == HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ) )
  861. {
  862. hr = GetServerVariableRemoteAddr( pW3Context, pstrVal );
  863. }
  864. return hr;
  865. }
  866. HRESULT
  867. GetServerVariableRemoteAddr(
  868. W3_CONTEXT *pW3Context,
  869. STRA *pstrVal
  870. )
  871. {
  872. DBG_ASSERT( pW3Context != NULL );
  873. HRESULT hr = S_OK;
  874. W3_REQUEST * pW3Request = pW3Context->QueryRequest();
  875. DBG_ASSERT( pW3Request != NULL );
  876. if( pW3Request->QueryRemoteAddressType() == AF_INET )
  877. {
  878. DWORD dwAddr = ntohl( pW3Request->QueryIPv4RemoteAddress() );
  879. hr = TranslateIpAddressToStr( dwAddr, pstrVal );
  880. }
  881. else if( pW3Request->QueryRemoteAddressType() == AF_INET6 )
  882. {
  883. SOCKADDR_IN6 IPv6RemoteAddress;
  884. CHAR szNumericRemoteAddress[ NI_MAXHOST ];
  885. IPv6RemoteAddress.sin6_family = AF_INET6;
  886. IPv6RemoteAddress.sin6_port = pW3Request->QueryRemotePort();
  887. IPv6RemoteAddress.sin6_flowinfo = ( ( PSOCKADDR_IN6 )
  888. pW3Request->QueryRemoteSockAddress() )->sin6_flowinfo;
  889. IPv6RemoteAddress.sin6_addr =
  890. *pW3Request->QueryIPv6RemoteAddress();
  891. IPv6RemoteAddress.sin6_scope_id = ( ( PSOCKADDR_IN6 )
  892. pW3Request->QueryRemoteSockAddress() )->sin6_scope_id;
  893. if( getnameinfo( ( LPSOCKADDR )&IPv6RemoteAddress,
  894. sizeof( IPv6RemoteAddress ),
  895. szNumericRemoteAddress,
  896. sizeof( szNumericRemoteAddress ),
  897. NULL,
  898. 0,
  899. NI_NUMERICHOST ) != 0 )
  900. {
  901. hr = HRESULT_FROM_WIN32( WSAGetLastError() );
  902. }
  903. else
  904. {
  905. hr = pstrVal->Copy( szNumericRemoteAddress );
  906. }
  907. }
  908. else
  909. {
  910. DBG_ASSERT( FALSE );
  911. }
  912. return hr;
  913. }
  914. HRESULT
  915. GetServerVariableRemotePort(
  916. W3_CONTEXT *pW3Context,
  917. STRA *pstrVal
  918. )
  919. {
  920. DBG_ASSERT( pW3Context != NULL );
  921. W3_REQUEST * pW3Request = pW3Context->QueryRequest();
  922. CHAR szPort[33]; // 33 is max buffer used by _ultoa
  923. USHORT uPort;
  924. DBG_ASSERT( pW3Request != NULL );
  925. uPort = htons( pW3Request->QueryRemotePort() );
  926. _ultoa( uPort, szPort, 10 );
  927. return pstrVal->Copy( szPort );
  928. }
  929. HRESULT
  930. GetServerVariableServerName(
  931. W3_CONTEXT *pW3Context,
  932. STRA *pstrVal
  933. )
  934. {
  935. STACK_STRU( strValW, 32 );
  936. DBG_ASSERT( pW3Context != NULL );
  937. //
  938. // If the client sent a host name, use it.
  939. //
  940. HRESULT hr = pW3Context->QueryRequest()->GetHostAddr( &strValW );
  941. if ( FAILED( hr ))
  942. {
  943. return hr;
  944. }
  945. return pstrVal->CopyW( strValW.QueryStr() );
  946. }
  947. HRESULT
  948. GetServerVariableServerNameW(
  949. W3_CONTEXT *pW3Context,
  950. STRU *pstrVal
  951. )
  952. {
  953. DBG_ASSERT( pW3Context != NULL );
  954. //
  955. // If the client sent a host name, use it.
  956. //
  957. return pW3Context->QueryRequest()->GetHostAddr( pstrVal );
  958. }
  959. HRESULT
  960. GetServerVariableServerPort(
  961. W3_CONTEXT *pW3Context,
  962. STRA *pstrVal
  963. )
  964. {
  965. DBG_ASSERT( pW3Context != NULL );
  966. USHORT port;
  967. W3_REQUEST * pW3Request = pW3Context->QueryRequest();
  968. DBG_ASSERT( pW3Request != NULL );
  969. port = ntohs( pW3Request->QueryLocalPort() );
  970. CHAR szPort[8];
  971. _itoa( port, szPort, 10 );
  972. return pstrVal->Copy( szPort );
  973. }
  974. HRESULT
  975. GetServerVariablePathInfo(
  976. W3_CONTEXT *pW3Context,
  977. STRA *pstrVal
  978. )
  979. {
  980. DBG_ASSERT( pW3Context != NULL );
  981. URL_CONTEXT *pUrlContext;
  982. BOOL fDeleteHandler = FALSE;
  983. pUrlContext = pW3Context->QueryUrlContext();
  984. //
  985. // We might be called in an early filter where URL context isn't available
  986. //
  987. if ( pUrlContext == NULL )
  988. {
  989. pstrVal->Reset();
  990. return NO_ERROR;
  991. }
  992. W3_URL_INFO *pUrlInfo = pUrlContext->QueryUrlInfo();
  993. DBG_ASSERT( pUrlInfo != NULL );
  994. W3_SITE *pSite = pW3Context->QuerySite();
  995. DBG_ASSERT( pSite != NULL );
  996. W3_HANDLER *pHandler;
  997. pHandler = pW3Context->QueryHandler();
  998. HRESULT hr;
  999. //
  1000. // If we have no handler, yet we have a URL_CONTEXT, then this
  1001. // must be GetServerVariable() call before the handler state
  1002. // Determine the handler temporarily so we can make right call
  1003. // on variable. Only need to do this for ANSI variable since this
  1004. // problem only happens for filter calls
  1005. //
  1006. if ( pHandler == NULL )
  1007. {
  1008. hr = pW3Context->InternalDetermineHandler( &pHandler, FALSE );
  1009. if ( FAILED( hr ) )
  1010. {
  1011. goto Finished;
  1012. }
  1013. DBG_ASSERT( pHandler != NULL );
  1014. fDeleteHandler = TRUE;
  1015. }
  1016. //
  1017. // In the case of script maps, if AllowPathInfoForScriptMappings
  1018. // is not set for the site, we ignore path info, it is
  1019. // just the URL
  1020. //
  1021. if ( pHandler != NULL &&
  1022. pHandler->QueryScriptMapEntry() &&
  1023. !pSite->QueryAllowPathInfoForScriptMappings() )
  1024. {
  1025. STACK_STRU (strUrl, MAX_PATH);
  1026. if (FAILED(hr = pW3Context->QueryRequest()->GetUrl( &strUrl )) ||
  1027. FAILED(hr = pstrVal->CopyW( strUrl.QueryStr() )))
  1028. {
  1029. goto Finished;
  1030. }
  1031. }
  1032. else
  1033. {
  1034. hr = pstrVal->CopyW( pUrlInfo->QueryPathInfo()->QueryStr() );
  1035. }
  1036. Finished:
  1037. if ( fDeleteHandler )
  1038. {
  1039. delete pHandler;
  1040. pHandler = NULL;
  1041. }
  1042. return hr;
  1043. }
  1044. HRESULT
  1045. GetServerVariablePathInfoW(
  1046. W3_CONTEXT *pW3Context,
  1047. STRU *pstrVal
  1048. )
  1049. {
  1050. DBG_ASSERT( pW3Context != NULL );
  1051. URL_CONTEXT *pUrlContext;
  1052. pUrlContext = pW3Context->QueryUrlContext();
  1053. //
  1054. // We might be called in an early filter where URL context isn't available
  1055. //
  1056. if ( pUrlContext == NULL )
  1057. {
  1058. pstrVal->Reset();
  1059. return NO_ERROR;
  1060. }
  1061. W3_URL_INFO *pUrlInfo = pUrlContext->QueryUrlInfo();
  1062. DBG_ASSERT( pUrlInfo != NULL );
  1063. W3_SITE *pSite = pW3Context->QuerySite();
  1064. DBG_ASSERT( pSite != NULL );
  1065. W3_HANDLER *pHandler;
  1066. pHandler = pW3Context->QueryHandler();
  1067. //
  1068. // In the case of script maps, if AllowPathInfoForScriptMappings
  1069. // is not set for the site, we ignore path info, it is
  1070. // just the URL
  1071. //
  1072. if ( pHandler != NULL &&
  1073. pHandler->QueryScriptMapEntry() &&
  1074. !pSite->QueryAllowPathInfoForScriptMappings() )
  1075. {
  1076. return pW3Context->QueryRequest()->GetUrl( pstrVal );
  1077. }
  1078. else
  1079. {
  1080. return pstrVal->Copy( pUrlInfo->QueryPathInfo()->QueryStr() );
  1081. }
  1082. }
  1083. HRESULT
  1084. GetServerVariablePathTranslated(
  1085. W3_CONTEXT *pW3Context,
  1086. STRA *pstrVal
  1087. )
  1088. {
  1089. DBG_ASSERT( pW3Context != NULL );
  1090. HRESULT hr;
  1091. BOOL fDeleteHandler = FALSE;
  1092. URL_CONTEXT *pUrlContext;
  1093. pUrlContext = pW3Context->QueryUrlContext();
  1094. if ( pUrlContext == NULL )
  1095. {
  1096. return pstrVal->Copy( "" );
  1097. }
  1098. W3_URL_INFO *pUrlInfo = pUrlContext->QueryUrlInfo();
  1099. DBG_ASSERT(pUrlInfo != NULL);
  1100. W3_SITE *pSite = pW3Context->QuerySite();
  1101. DBG_ASSERT(pSite != NULL);
  1102. W3_HANDLER *pHandler;
  1103. pHandler = pW3Context->QueryHandler();
  1104. //
  1105. // If we have no handler, yet we have a URL_CONTEXT, then this
  1106. // must be GetServerVariable() call before the handler state
  1107. // Determine the handler temporarily so we can make right call
  1108. // on variable. Only need to do this for ANSI variable since this
  1109. // problem only happens for filter calls
  1110. //
  1111. if ( pHandler == NULL )
  1112. {
  1113. hr = pW3Context->InternalDetermineHandler( &pHandler, FALSE );
  1114. if ( FAILED( hr ) )
  1115. {
  1116. return hr;
  1117. }
  1118. DBG_ASSERT( pHandler != NULL );
  1119. fDeleteHandler = TRUE;
  1120. }
  1121. BOOL fUsePathInfo;
  1122. if ( pHandler != NULL &&
  1123. pHandler->QueryScriptMapEntry() &&
  1124. !pSite->QueryAllowPathInfoForScriptMappings() )
  1125. {
  1126. fUsePathInfo = FALSE;
  1127. }
  1128. else
  1129. {
  1130. fUsePathInfo = TRUE;
  1131. }
  1132. STACK_STRU (struPathTranslated, 256);
  1133. //
  1134. // This is a new virtual path to have filters map
  1135. //
  1136. hr = pUrlInfo->GetPathTranslated( pW3Context,
  1137. fUsePathInfo,
  1138. &struPathTranslated );
  1139. if (SUCCEEDED(hr))
  1140. {
  1141. hr = pstrVal->CopyW( struPathTranslated.QueryStr() );
  1142. }
  1143. if ( fDeleteHandler )
  1144. {
  1145. delete pHandler;
  1146. pHandler = NULL;
  1147. }
  1148. return hr;
  1149. }
  1150. HRESULT
  1151. GetServerVariablePathTranslatedW(
  1152. W3_CONTEXT *pW3Context,
  1153. STRU *pstrVal
  1154. )
  1155. {
  1156. DBG_ASSERT( pW3Context != NULL );
  1157. URL_CONTEXT *pUrlContext;
  1158. pUrlContext = pW3Context->QueryUrlContext();
  1159. if ( pUrlContext == NULL )
  1160. {
  1161. return pstrVal->Copy( L"" );
  1162. }
  1163. W3_URL_INFO *pUrlInfo = pUrlContext->QueryUrlInfo();
  1164. DBG_ASSERT(pUrlInfo != NULL);
  1165. W3_SITE *pSite = pW3Context->QuerySite();
  1166. DBG_ASSERT(pSite != NULL);
  1167. W3_HANDLER *pHandler;
  1168. pHandler = pW3Context->QueryHandler();
  1169. BOOL fUsePathInfo;
  1170. if ( pHandler != NULL &&
  1171. pHandler->QueryScriptMapEntry() &&
  1172. !pSite->QueryAllowPathInfoForScriptMappings() )
  1173. {
  1174. fUsePathInfo = FALSE;
  1175. }
  1176. else
  1177. {
  1178. fUsePathInfo = TRUE;
  1179. }
  1180. //
  1181. // This is a new virtual path to have filters map
  1182. //
  1183. return pUrlInfo->GetPathTranslated( pW3Context,
  1184. fUsePathInfo,
  1185. pstrVal );
  1186. }
  1187. HRESULT
  1188. GetServerVariableRequestMethod(
  1189. W3_CONTEXT *pW3Context,
  1190. STRA *pstrVal
  1191. )
  1192. {
  1193. DBG_ASSERT( pW3Context != NULL );
  1194. return pW3Context->QueryRequest()->GetVerbString( pstrVal );
  1195. }
  1196. HRESULT
  1197. GetServerVariableServerPortSecure(
  1198. W3_CONTEXT *pW3Context,
  1199. STRA *pstrVal
  1200. )
  1201. {
  1202. DBG_ASSERT( pW3Context != NULL );
  1203. if ( pW3Context->QueryRequest()->IsSecureRequest() )
  1204. {
  1205. return pstrVal->Copy("1", 1);
  1206. }
  1207. return pstrVal->Copy("0", 1);
  1208. }
  1209. HRESULT
  1210. GetServerVariableServerSoftware(
  1211. W3_CONTEXT *,
  1212. STRA *pstrVal
  1213. )
  1214. {
  1215. return pstrVal->Copy( SERVER_SOFTWARE_STRING );
  1216. }
  1217. HRESULT
  1218. GetServerVariableUrl(
  1219. W3_CONTEXT *pW3Context,
  1220. STRA *pstrVal
  1221. )
  1222. {
  1223. URL_CONTEXT * pUrlContext;
  1224. W3_URL_INFO * pUrlInfo;
  1225. STACK_STRU( strUrl, 256 );
  1226. HRESULT hr;
  1227. DBG_ASSERT( pW3Context != NULL );
  1228. //
  1229. // URL context can be NULL if an early filter is called GetServerVar()
  1230. //
  1231. pUrlContext = pW3Context->QueryUrlContext();
  1232. if ( pUrlContext != NULL )
  1233. {
  1234. pUrlInfo = pUrlContext->QueryUrlInfo();
  1235. DBG_ASSERT( pUrlInfo != NULL );
  1236. return pstrVal->CopyW( pUrlInfo->QueryProcessedUrl()->QueryStr() );
  1237. }
  1238. else
  1239. {
  1240. hr = pW3Context->QueryRequest()->GetUrl( &strUrl );
  1241. if ( FAILED( hr ) )
  1242. {
  1243. return hr;
  1244. }
  1245. return pstrVal->CopyW( strUrl.QueryStr() );
  1246. }
  1247. }
  1248. HRESULT
  1249. GetServerVariableUrlW(
  1250. W3_CONTEXT *pW3Context,
  1251. STRU *pstrVal
  1252. )
  1253. {
  1254. URL_CONTEXT * pUrlContext;
  1255. W3_URL_INFO * pUrlInfo;
  1256. DBG_ASSERT( pW3Context != NULL );
  1257. //
  1258. // URL context can be NULL if an early filter is called GetServerVar()
  1259. //
  1260. pUrlContext = pW3Context->QueryUrlContext();
  1261. if ( pUrlContext != NULL )
  1262. {
  1263. pUrlInfo = pUrlContext->QueryUrlInfo();
  1264. DBG_ASSERT( pUrlInfo != NULL );
  1265. return pstrVal->Copy( pUrlInfo->QueryProcessedUrl()->QueryStr() );
  1266. }
  1267. else
  1268. {
  1269. return pW3Context->QueryRequest()->GetUrl( pstrVal );
  1270. }
  1271. }
  1272. HRESULT
  1273. GetServerVariableInstanceMetaPath(
  1274. W3_CONTEXT *pW3Context,
  1275. STRA *pstrVal
  1276. )
  1277. {
  1278. DBG_ASSERT( pW3Context != NULL );
  1279. STRU *pstrMetaPath = pW3Context->QuerySite()->QueryMBPath();
  1280. DBG_ASSERT( pstrMetaPath );
  1281. return pstrVal->CopyW( pstrMetaPath->QueryStr() );
  1282. }
  1283. HRESULT
  1284. GetServerVariableLogonUser(
  1285. W3_CONTEXT *pW3Context,
  1286. STRA *pstrVal
  1287. )
  1288. {
  1289. DBG_ASSERT( pW3Context != NULL );
  1290. W3_USER_CONTEXT *pUserContext;
  1291. pUserContext = pW3Context->QueryUserContext();
  1292. if ( pUserContext == NULL )
  1293. {
  1294. return pW3Context->QueryRequest()->GetRequestUserName( pstrVal );
  1295. }
  1296. else
  1297. {
  1298. return pstrVal->CopyW( pUserContext->QueryUserName() );
  1299. }
  1300. }
  1301. HRESULT
  1302. GetServerVariableLogonUserW(
  1303. W3_CONTEXT *pW3Context,
  1304. STRU *pstrVal
  1305. )
  1306. {
  1307. DBG_ASSERT( pW3Context != NULL );
  1308. W3_USER_CONTEXT *pUserContext;
  1309. pUserContext = pW3Context->QueryUserContext();
  1310. if ( pUserContext == NULL )
  1311. {
  1312. return pstrVal->CopyA( pW3Context->QueryRequest()->QueryRequestUserName()->QueryStr() );
  1313. }
  1314. else
  1315. {
  1316. return pstrVal->Copy( pUserContext->QueryUserName() );
  1317. }
  1318. }
  1319. HRESULT
  1320. GetServerVariableRemoteUser(
  1321. W3_CONTEXT *pW3Context,
  1322. STRA *pstrVal
  1323. )
  1324. {
  1325. HRESULT hr;
  1326. DBG_ASSERT( pW3Context != NULL );
  1327. hr = pW3Context->QueryRequest()->GetRequestUserName( pstrVal );
  1328. if ( FAILED( hr ) )
  1329. {
  1330. return hr;
  1331. }
  1332. if ( pstrVal->IsEmpty() )
  1333. {
  1334. W3_USER_CONTEXT *pUserContext;
  1335. pUserContext = pW3Context->QueryUserContext();
  1336. if ( pUserContext != NULL )
  1337. {
  1338. hr = pstrVal->CopyW( pUserContext->QueryRemoteUserName() );
  1339. }
  1340. else
  1341. {
  1342. hr = NO_ERROR;
  1343. }
  1344. }
  1345. return hr;
  1346. }
  1347. HRESULT
  1348. GetServerVariableRemoteUserW(
  1349. W3_CONTEXT *pW3Context,
  1350. STRU *pstrVal
  1351. )
  1352. {
  1353. DBG_ASSERT( pW3Context != NULL );
  1354. STRA *pstrUserName = pW3Context->QueryRequest()->QueryRequestUserName();
  1355. if ( pstrUserName->IsEmpty() )
  1356. {
  1357. W3_USER_CONTEXT *pUserContext;
  1358. pUserContext = pW3Context->QueryUserContext();
  1359. if ( pUserContext != NULL )
  1360. {
  1361. return pstrVal->Copy( pUserContext->QueryRemoteUserName() );
  1362. }
  1363. }
  1364. else
  1365. {
  1366. return pstrVal->CopyA( pstrUserName->QueryStr() );
  1367. }
  1368. return S_OK;
  1369. }
  1370. HRESULT
  1371. GetServerVariableAuthType(
  1372. W3_CONTEXT *pW3Context,
  1373. STRA *pstrVal
  1374. )
  1375. {
  1376. DBG_ASSERT( pW3Context != NULL );
  1377. DBG_ASSERT( pstrVal != NULL );
  1378. HRESULT hr = S_OK;
  1379. W3_USER_CONTEXT *pUserContext = pW3Context->QueryUserContext();
  1380. if ( pUserContext != NULL )
  1381. {
  1382. if ( pUserContext->QueryAuthType() == MD_ACCESS_MAP_CERT )
  1383. {
  1384. hr = pstrVal->Copy( "SSL/PCT" );
  1385. }
  1386. else if ( pUserContext->QueryAuthType() == MD_AUTH_ANONYMOUS )
  1387. {
  1388. hr = pstrVal->Copy( "" );
  1389. }
  1390. else if ( pUserContext->QueryAuthType() == MD_AUTH_PASSPORT )
  1391. {
  1392. hr = pstrVal->Copy( "PASSPORT" );
  1393. }
  1394. else
  1395. {
  1396. hr = pW3Context->QueryRequest()->GetAuthType( pstrVal );
  1397. }
  1398. }
  1399. else
  1400. {
  1401. //
  1402. // If an filter checks this server variable in
  1403. // SF_NOTIFY_AUTHENTICATION, there won't be a pUserContext
  1404. // yet, but we need to give an answer based on the
  1405. // authorization header anyway to be compatible with
  1406. // legacy behavior.
  1407. //
  1408. hr = pW3Context->QueryRequest()->GetAuthType( pstrVal );
  1409. }
  1410. return hr;
  1411. }
  1412. HRESULT
  1413. GetServerVariableAuthPassword(
  1414. W3_CONTEXT *pW3Context,
  1415. STRA *pstrVal
  1416. )
  1417. {
  1418. HRESULT hr;
  1419. DBG_ASSERT( pW3Context != NULL );
  1420. hr = pW3Context->QueryRequest()->GetRequestPassword( pstrVal );
  1421. if ( FAILED( hr ) )
  1422. {
  1423. return hr;
  1424. }
  1425. if ( pstrVal->IsEmpty() )
  1426. {
  1427. W3_USER_CONTEXT * pUserContext;
  1428. pUserContext = pW3Context->QueryUserContext();
  1429. if ( pUserContext != NULL )
  1430. {
  1431. hr = pstrVal->CopyW( pUserContext->QueryPassword() );
  1432. }
  1433. else
  1434. {
  1435. hr = NO_ERROR;
  1436. }
  1437. }
  1438. return hr;
  1439. }
  1440. HRESULT
  1441. GetServerVariableApplMdPath(
  1442. W3_CONTEXT *pW3Context,
  1443. STRA *pstrVal
  1444. )
  1445. {
  1446. STRU * pstrAppMetaPath = NULL;
  1447. URL_CONTEXT * pUrlContext;
  1448. HRESULT hr;
  1449. DBG_ASSERT( pW3Context != NULL );
  1450. pUrlContext = pW3Context->QueryUrlContext();
  1451. if ( pUrlContext != NULL )
  1452. {
  1453. W3_METADATA *pMetaData = pUrlContext->QueryMetaData();
  1454. DBG_ASSERT( pMetaData != NULL );
  1455. pstrAppMetaPath = pMetaData->QueryAppMetaPath();
  1456. }
  1457. if( pstrAppMetaPath == NULL ||
  1458. pstrAppMetaPath->IsEmpty() )
  1459. {
  1460. //
  1461. // If we don't have APPL_MD_PATH, then the caller should
  1462. // get an empty string.
  1463. //
  1464. hr = pstrVal->Copy( "", 0 );
  1465. }
  1466. else
  1467. {
  1468. hr = pstrVal->CopyW( pstrAppMetaPath->QueryStr() );
  1469. }
  1470. return hr;
  1471. }
  1472. HRESULT
  1473. GetServerVariableApplMdPathW(
  1474. W3_CONTEXT *pW3Context,
  1475. STRU *pstrVal
  1476. )
  1477. {
  1478. STRU * pstrAppMetaPath = NULL;
  1479. URL_CONTEXT * pUrlContext;
  1480. HRESULT hr;
  1481. DBG_ASSERT( pW3Context != NULL );
  1482. pUrlContext = pW3Context->QueryUrlContext();
  1483. if ( pUrlContext != NULL )
  1484. {
  1485. W3_METADATA *pMetaData = pUrlContext->QueryMetaData();
  1486. DBG_ASSERT( pMetaData != NULL );
  1487. pstrAppMetaPath = pMetaData->QueryAppMetaPath();
  1488. }
  1489. if( pstrAppMetaPath == NULL ||
  1490. pstrAppMetaPath->IsEmpty() )
  1491. {
  1492. //
  1493. // If we don't have APPL_MD_PATH, then the caller should
  1494. // get an empty string.
  1495. //
  1496. hr = pstrVal->Copy( L"" );
  1497. }
  1498. else
  1499. {
  1500. hr = pstrVal->Copy( pstrAppMetaPath->QueryStr() );
  1501. }
  1502. return hr;
  1503. }
  1504. HRESULT
  1505. GetServerVariableApplPhysicalPath(
  1506. W3_CONTEXT *pW3Context,
  1507. STRA *pstrVal
  1508. )
  1509. {
  1510. DBG_ASSERT( pW3Context != NULL );
  1511. DBG_ASSERT( pstrVal );
  1512. STACK_STRA( strAppMetaPath, MAX_PATH );
  1513. STACK_STRU( strAppUrl, MAX_PATH );
  1514. HRESULT hr = E_FAIL;
  1515. hr = GetServerVariableApplMdPath( pW3Context, &strAppMetaPath );
  1516. if( SUCCEEDED(hr) )
  1517. {
  1518. //
  1519. // pstrAppMetaPath is a full metabase path:
  1520. // /LM/W3SVC/<site>/Root/...
  1521. //
  1522. // To convert it to a physical path we will use
  1523. // W3_STATE_URLINFO::MapPath, but this requires
  1524. // that we remove the metabase prefixes and build
  1525. // a Url string.
  1526. //
  1527. //
  1528. // Get the metabase path for the site root
  1529. //
  1530. W3_SITE *pSite = pW3Context->QuerySite();
  1531. DBG_ASSERT( pSite );
  1532. STRU *pstrSiteRoot = pSite->QueryMBRoot();
  1533. DBG_ASSERT( pstrSiteRoot );
  1534. //
  1535. // Make some assumptions about the site path and the AppMetaPath
  1536. // being well-formed. The AppMetaPath may not have a terminating
  1537. // /, but the site root will.
  1538. //
  1539. DBG_ASSERT( pstrSiteRoot->QueryCCH() >=
  1540. sizeof("/LM/W3SVC/1/Root/") - 1
  1541. );
  1542. if( strAppMetaPath.QueryCCH() < pstrSiteRoot->QueryCCH() - 1 )
  1543. {
  1544. //
  1545. // This indicates an invalid value for MD_APP_ROOT is sitting
  1546. // around. We need to bail if this is the case.
  1547. //
  1548. DBGPRINTF(( DBG_CONTEXT,
  1549. "Invalid MD_APP_ROOT detected (%s)\n",
  1550. strAppMetaPath.QueryStr()
  1551. ));
  1552. return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1553. }
  1554. DBG_ASSERT( strAppMetaPath.QueryCCH() >=
  1555. sizeof("/LM/W3SVC/1/Root/") - 2
  1556. );
  1557. //
  1558. // The AppUrl will be the metabase path -
  1559. // all the /LM/W3SVC/1/ROOT goo
  1560. //
  1561. CHAR * pszStartAppUrl = strAppMetaPath.QueryStr() +
  1562. (pstrSiteRoot->QueryCCH() - 1);
  1563. //
  1564. // The AppMetaPath may not have a terminating /, so if it is
  1565. // a site root pszStartAppUrl will be empty.
  1566. //
  1567. if( *pszStartAppUrl != '\0' )
  1568. {
  1569. if( *pszStartAppUrl != '/' )
  1570. {
  1571. DBGPRINTF(( DBG_CONTEXT,
  1572. "Invalid MD_APP_ROOT detected (%s)\n",
  1573. strAppMetaPath.QueryStr()
  1574. ));
  1575. return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1576. }
  1577. hr = strAppUrl.CopyA(
  1578. pszStartAppUrl,
  1579. strAppMetaPath.QueryCCH() - (pstrSiteRoot->QueryCCH() - 1)
  1580. );
  1581. }
  1582. else
  1583. {
  1584. hr = strAppUrl.Copy( L"/", 1 );
  1585. }
  1586. if( SUCCEEDED(hr) )
  1587. {
  1588. STACK_STRU (strAppPath, MAX_PATH);
  1589. //
  1590. // Convert to a physical path
  1591. //
  1592. hr = W3_STATE_URLINFO::MapPath( pW3Context,
  1593. strAppUrl,
  1594. &strAppPath,
  1595. FALSE,
  1596. NULL,
  1597. NULL,
  1598. NULL,
  1599. NULL,
  1600. NULL
  1601. );
  1602. if (SUCCEEDED(hr))
  1603. {
  1604. hr = pstrVal->CopyW(strAppPath.QueryStr());
  1605. //
  1606. // Ensure that the last character in the path
  1607. // is '\\'. There are legacy scripts that will
  1608. // concatenate filenames to this path, and many
  1609. // of them will break if we don't do this.
  1610. //
  1611. if ( SUCCEEDED( hr ) &&
  1612. *(pstrVal->QueryStr()+pstrVal->QueryCCH()-1) != '\\' )
  1613. {
  1614. hr = pstrVal->Append( "\\" );
  1615. }
  1616. }
  1617. }
  1618. }
  1619. return hr;
  1620. }
  1621. HRESULT
  1622. GetServerVariableApplPhysicalPathW(
  1623. W3_CONTEXT *pW3Context,
  1624. STRU *pstrVal
  1625. )
  1626. {
  1627. DBG_ASSERT( pW3Context != NULL );
  1628. DBG_ASSERT( pstrVal );
  1629. STACK_STRU( strAppMetaPath, MAX_PATH );
  1630. STACK_STRU( strAppUrl, MAX_PATH );
  1631. HRESULT hr = E_FAIL;
  1632. hr = GetServerVariableApplMdPathW( pW3Context, &strAppMetaPath );
  1633. if( SUCCEEDED(hr) )
  1634. {
  1635. //
  1636. // pstrAppMetaPath is a full metabase path:
  1637. // /LM/W3SVC/<site>/Root/...
  1638. //
  1639. // To convert it to a physical path we will use
  1640. // W3_STATE_URLINFO::MapPath, but this requires
  1641. // that we remove the metabase prefixes and build
  1642. // a Url string.
  1643. //
  1644. //
  1645. // Get the metabase path for the site root
  1646. //
  1647. W3_SITE *pSite = pW3Context->QuerySite();
  1648. DBG_ASSERT( pSite );
  1649. STRU *pstrSiteRoot = pSite->QueryMBRoot();
  1650. DBG_ASSERT( pstrSiteRoot );
  1651. //
  1652. // Make some assumptions about the site path and the AppMetaPath
  1653. // being well-formed. The AppMetaPath may not have a terminating
  1654. // /, but the site root will.
  1655. //
  1656. DBG_ASSERT( pstrSiteRoot->QueryCCH() >=
  1657. sizeof("/LM/W3SVC/1/Root/") - 1
  1658. );
  1659. if( strAppMetaPath.QueryCCH() < pstrSiteRoot->QueryCCH() - 1 )
  1660. {
  1661. //
  1662. // This indicates an invalid value for MD_APP_ROOT is sitting
  1663. // around. We need to bail if this is the case.
  1664. //
  1665. DBGPRINTF(( DBG_CONTEXT,
  1666. "Invalid MD_APP_ROOT detected (%S)\n",
  1667. strAppMetaPath.QueryStr()
  1668. ));
  1669. return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1670. }
  1671. DBG_ASSERT( strAppMetaPath.QueryCCH() >=
  1672. sizeof("/LM/W3SVC/1/Root/") - 2
  1673. );
  1674. //
  1675. // The AppUrl will be the metabase path -
  1676. // all the /LM/W3SVC/1/ROOT goo
  1677. //
  1678. WCHAR * pszStartAppUrl = strAppMetaPath.QueryStr() +
  1679. (pstrSiteRoot->QueryCCH() - 1);
  1680. //
  1681. // The AppMetaPath may not have a terminating /, so if it is
  1682. // a site root pszStartAppUrl will be empty.
  1683. //
  1684. if( *pszStartAppUrl != L'\0' )
  1685. {
  1686. if( *pszStartAppUrl != L'/' )
  1687. {
  1688. DBGPRINTF(( DBG_CONTEXT,
  1689. "Invalid MD_APP_ROOT detected (%s)\n",
  1690. strAppMetaPath.QueryStr()
  1691. ));
  1692. return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1693. }
  1694. hr = strAppUrl.Copy(
  1695. pszStartAppUrl,
  1696. strAppMetaPath.QueryCCH() - (pstrSiteRoot->QueryCCH() - 1)
  1697. );
  1698. }
  1699. else
  1700. {
  1701. hr = strAppUrl.Copy( L"/", 1 );
  1702. }
  1703. if( SUCCEEDED(hr) )
  1704. {
  1705. hr = W3_STATE_URLINFO::MapPath( pW3Context,
  1706. strAppUrl,
  1707. pstrVal,
  1708. FALSE,
  1709. NULL,
  1710. NULL,
  1711. NULL,
  1712. NULL,
  1713. NULL
  1714. );
  1715. //
  1716. // Ensure that the last character in the path
  1717. // is '\\'. There are legacy scripts that will
  1718. // concatenate filenames to this path, and many
  1719. // of them will break if we don't do this.
  1720. //
  1721. if ( SUCCEEDED( hr ) &&
  1722. *(pstrVal->QueryStr()+pstrVal->QueryCCH()-1) != L'\\' )
  1723. {
  1724. hr = pstrVal->Append( L"\\" );
  1725. }
  1726. }
  1727. }
  1728. return hr;
  1729. }
  1730. HRESULT
  1731. GetServerVariableGatewayInterface(
  1732. W3_CONTEXT *,
  1733. STRA *pstrVal
  1734. )
  1735. {
  1736. return pstrVal->Copy("CGI/1.1", 7);
  1737. }
  1738. HRESULT
  1739. GetServerVariableLocalAddr(
  1740. W3_CONTEXT *pW3Context,
  1741. STRA *pstrVal
  1742. )
  1743. {
  1744. DBG_ASSERT( pW3Context != NULL );
  1745. HRESULT hr = S_OK;
  1746. W3_REQUEST * pW3Request = pW3Context->QueryRequest();
  1747. DBG_ASSERT( pW3Request != NULL );
  1748. if( pW3Request->QueryLocalAddressType() == AF_INET )
  1749. {
  1750. DWORD dwAddr = ntohl( pW3Request->QueryIPv4LocalAddress() );
  1751. hr = TranslateIpAddressToStr( dwAddr, pstrVal );
  1752. }
  1753. else if( pW3Request->QueryLocalAddressType() == AF_INET6 )
  1754. {
  1755. SOCKADDR_IN6 IPv6LocalAddress;
  1756. CHAR szNumericLocalAddress[ NI_MAXHOST ];
  1757. IPv6LocalAddress.sin6_family = AF_INET6;
  1758. IPv6LocalAddress.sin6_port = pW3Request->QueryLocalPort();
  1759. IPv6LocalAddress.sin6_flowinfo = ( ( PSOCKADDR_IN6 )
  1760. pW3Request->QueryLocalSockAddress() )->sin6_flowinfo;
  1761. IPv6LocalAddress.sin6_addr =
  1762. *pW3Request->QueryIPv6LocalAddress();
  1763. IPv6LocalAddress.sin6_scope_id = ( ( PSOCKADDR_IN6 )
  1764. pW3Request->QueryLocalSockAddress() )->sin6_scope_id;
  1765. if( getnameinfo( ( LPSOCKADDR )&IPv6LocalAddress,
  1766. sizeof( IPv6LocalAddress ),
  1767. szNumericLocalAddress,
  1768. sizeof( szNumericLocalAddress ),
  1769. NULL,
  1770. 0,
  1771. NI_NUMERICHOST ) != 0 )
  1772. {
  1773. hr = HRESULT_FROM_WIN32( WSAGetLastError() );
  1774. }
  1775. else
  1776. {
  1777. hr = pstrVal->Copy( szNumericLocalAddress );
  1778. }
  1779. }
  1780. else
  1781. {
  1782. DBG_ASSERT( FALSE );
  1783. }
  1784. return hr;
  1785. }
  1786. HRESULT GetServerVariableHttps(
  1787. W3_CONTEXT *pW3Context,
  1788. STRA *pstrVal)
  1789. {
  1790. DBG_ASSERT( pW3Context != NULL );
  1791. if (pW3Context->QueryRequest()->IsSecureRequest())
  1792. {
  1793. return pstrVal->Copy("on", 2);
  1794. }
  1795. return pstrVal->Copy("off", 3);
  1796. }
  1797. HRESULT
  1798. GetServerVariableHttpsKeySize(
  1799. W3_CONTEXT * pW3Context,
  1800. STRA * pstrVal
  1801. )
  1802. {
  1803. HTTP_SSL_INFO * pSslInfo;
  1804. CHAR achNum[ 64 ];
  1805. pSslInfo = pW3Context->QueryRequest()->QuerySslInfo();
  1806. if ( pSslInfo == NULL )
  1807. {
  1808. achNum[ 0 ] = '\0';
  1809. }
  1810. else
  1811. {
  1812. _itoa( pSslInfo->ConnectionKeySize,
  1813. achNum,
  1814. 10 );
  1815. }
  1816. return pstrVal->Copy( achNum );
  1817. }
  1818. HRESULT
  1819. GetServerVariableClientCertIssuer(
  1820. W3_CONTEXT * pW3Context,
  1821. STRA * pstrVal
  1822. )
  1823. {
  1824. CERTIFICATE_CONTEXT * pCertContext;
  1825. pCertContext = pW3Context->QueryMainContext()->QueryCertificateContext();
  1826. if ( pCertContext == NULL )
  1827. {
  1828. return pstrVal->Copy( "", 0 );
  1829. }
  1830. else
  1831. {
  1832. return pCertContext->GetIssuer( pstrVal );
  1833. }
  1834. }
  1835. HRESULT
  1836. GetServerVariableClientCertSubject(
  1837. W3_CONTEXT * pW3Context,
  1838. STRA * pstrVal
  1839. )
  1840. {
  1841. CERTIFICATE_CONTEXT * pCertContext;
  1842. pCertContext = pW3Context->QueryMainContext()->QueryCertificateContext();
  1843. if ( pCertContext == NULL )
  1844. {
  1845. return pstrVal->Copy( "", 0 );
  1846. }
  1847. else
  1848. {
  1849. return pCertContext->GetSubject( pstrVal );
  1850. }
  1851. }
  1852. HRESULT
  1853. GetServerVariableClientCertCookie(
  1854. W3_CONTEXT * pW3Context,
  1855. STRA * pstrVal
  1856. )
  1857. {
  1858. CERTIFICATE_CONTEXT * pCertContext;
  1859. pCertContext = pW3Context->QueryMainContext()->QueryCertificateContext();
  1860. if ( pCertContext == NULL )
  1861. {
  1862. return pstrVal->Copy( "", 0 );
  1863. }
  1864. else
  1865. {
  1866. return pCertContext->GetCookie( pstrVal );
  1867. }
  1868. }
  1869. HRESULT
  1870. GetServerVariableClientCertSerialNumber(
  1871. W3_CONTEXT * pW3Context,
  1872. STRA * pstrVal
  1873. )
  1874. {
  1875. CERTIFICATE_CONTEXT * pCertContext;
  1876. pCertContext = pW3Context->QueryMainContext()->QueryCertificateContext();
  1877. if ( pCertContext == NULL )
  1878. {
  1879. return pstrVal->Copy( "", 0 );
  1880. }
  1881. else
  1882. {
  1883. return pCertContext->GetSerialNumber( pstrVal );
  1884. }
  1885. }
  1886. HRESULT
  1887. GetServerVariableClientCertFlags(
  1888. W3_CONTEXT * pW3Context,
  1889. STRA * pstrVal
  1890. )
  1891. {
  1892. CERTIFICATE_CONTEXT * pCertContext;
  1893. pCertContext = pW3Context->QueryMainContext()->QueryCertificateContext();
  1894. if ( pCertContext == NULL )
  1895. {
  1896. return pstrVal->Copy( "" );
  1897. }
  1898. else
  1899. {
  1900. // CertFlags - legacy value
  1901. // In IIS3 days client certificates were not verified by IIS
  1902. // so applications needed certificate flags to make
  1903. // their own decisions regarding trust
  1904. // Now only valid certificate allow access so value of 1 is
  1905. // the only one that is valid for post IIS3 versions of IIS
  1906. //
  1907. return pstrVal->Copy( "1" );
  1908. }
  1909. }
  1910. HRESULT
  1911. GetServerVariableHttpsSecretKeySize(
  1912. W3_CONTEXT * pW3Context,
  1913. STRA * pstrVal
  1914. )
  1915. {
  1916. HTTP_SSL_INFO * pSslInfo;
  1917. CHAR achNum[ 64 ];
  1918. pSslInfo = pW3Context->QueryRequest()->QuerySslInfo();
  1919. if ( pSslInfo == NULL )
  1920. {
  1921. achNum[ 0 ] = '\0';
  1922. }
  1923. else
  1924. {
  1925. _itoa( pSslInfo->ServerCertKeySize,
  1926. achNum,
  1927. 10 );
  1928. }
  1929. return pstrVal->Copy( achNum );
  1930. }
  1931. HRESULT
  1932. GetServerVariableHttpsServerIssuer(
  1933. W3_CONTEXT * pW3Context,
  1934. STRA * pstrVal
  1935. )
  1936. {
  1937. HTTP_SSL_INFO * pSslInfo;
  1938. LPCSTR pszVariable;
  1939. pSslInfo = pW3Context->QueryRequest()->QuerySslInfo();
  1940. if ( pSslInfo == NULL )
  1941. {
  1942. pszVariable = "";
  1943. }
  1944. else
  1945. {
  1946. DBG_ASSERT( pSslInfo->pServerCertIssuer != NULL );
  1947. pszVariable = pSslInfo->pServerCertIssuer;
  1948. }
  1949. return pstrVal->Copy( pszVariable );
  1950. }
  1951. HRESULT
  1952. GetServerVariableHttpsServerSubject(
  1953. W3_CONTEXT * pW3Context,
  1954. STRA * pstrVal
  1955. )
  1956. {
  1957. HTTP_SSL_INFO * pSslInfo;
  1958. LPCSTR pszVariable;
  1959. pSslInfo = pW3Context->QueryRequest()->QuerySslInfo();
  1960. if ( pSslInfo == NULL )
  1961. {
  1962. pszVariable = "";
  1963. }
  1964. else
  1965. {
  1966. DBG_ASSERT( pSslInfo->pServerCertSubject != NULL );
  1967. pszVariable = pSslInfo->pServerCertSubject;
  1968. }
  1969. return pstrVal->Copy( pszVariable );
  1970. }
  1971. HRESULT
  1972. GetServerVariableHttpUrl(
  1973. W3_CONTEXT * pW3Context,
  1974. STRA * pstrVal
  1975. )
  1976. {
  1977. //
  1978. // HTTP_URL gets the raw url for the request. If a filter has
  1979. // modified the url the request object handles redirecting the
  1980. // RawUrl variable
  1981. //
  1982. DBG_ASSERT( pW3Context != NULL );
  1983. return pW3Context->QueryRequest()->GetRawUrl( pstrVal );
  1984. }
  1985. HRESULT
  1986. GetServerVariableHttpVersion(
  1987. W3_CONTEXT * pW3Context,
  1988. STRA * pstrVal
  1989. )
  1990. {
  1991. //
  1992. // HTTP_VERSION returns the client version string
  1993. //
  1994. DBG_ASSERT( pW3Context != NULL );
  1995. return pW3Context->QueryRequest()->GetVersionString( pstrVal );
  1996. }
  1997. HRESULT
  1998. GetServerVariableAppPoolId(
  1999. W3_CONTEXT *,
  2000. STRA * pstrVal
  2001. )
  2002. {
  2003. //
  2004. // APP_POOL_ID returns the AppPoolId WAS started us with
  2005. //
  2006. return pstrVal->CopyW( (LPWSTR)UlAtqGetContextProperty(NULL,
  2007. ULATQ_PROPERTY_APP_POOL_ID) );
  2008. }
  2009. HRESULT
  2010. GetServerVariableAppPoolIdW(
  2011. W3_CONTEXT *,
  2012. STRU * pstrVal
  2013. )
  2014. {
  2015. //
  2016. // APP_POOL_ID returns the AppPoolId WAS started us with
  2017. //
  2018. return pstrVal->Copy( (LPWSTR)UlAtqGetContextProperty(NULL,
  2019. ULATQ_PROPERTY_APP_POOL_ID) );
  2020. }
  2021. HRESULT
  2022. GetServerVariableScriptTranslated(
  2023. W3_CONTEXT * pW3Context,
  2024. STRA * pstrVal
  2025. )
  2026. {
  2027. STACK_STRU( strCanonicalPath, MAX_PATH );
  2028. HRESULT hr = NOERROR;
  2029. DBG_ASSERT( pW3Context != NULL );
  2030. URL_CONTEXT *pUrlContext = pW3Context->QueryUrlContext();
  2031. DBG_ASSERT( pUrlContext != NULL );
  2032. hr = MakePathCanonicalizationProof( pUrlContext->QueryPhysicalPath()->QueryStr(),
  2033. &strCanonicalPath );
  2034. if ( FAILED( hr ) )
  2035. {
  2036. return hr;
  2037. }
  2038. return pstrVal->CopyW( strCanonicalPath.QueryStr() );
  2039. }
  2040. HRESULT
  2041. GetServerVariableScriptTranslatedW(
  2042. W3_CONTEXT * pW3Context,
  2043. STRU * pstrVal
  2044. )
  2045. {
  2046. DBG_ASSERT( pW3Context != NULL );
  2047. URL_CONTEXT *pUrlContext = pW3Context->QueryUrlContext();
  2048. DBG_ASSERT( pUrlContext != NULL );
  2049. return MakePathCanonicalizationProof( pUrlContext->QueryPhysicalPath()->QueryStr(),
  2050. pstrVal );
  2051. }
  2052. HRESULT
  2053. GetServerVariableUnencodedUrl(
  2054. W3_CONTEXT * pW3Context,
  2055. STRA * pstrVal
  2056. )
  2057. {
  2058. DBG_ASSERT( pW3Context != NULL );
  2059. W3_REQUEST *pW3Request = pW3Context->QueryRequest();
  2060. DBG_ASSERT( pW3Request != NULL );
  2061. return pW3Request->GetRawUrl(pstrVal);
  2062. }
  2063. HRESULT
  2064. GetServerVariableSsiExecDisabled(
  2065. W3_CONTEXT * pW3Context,
  2066. STRA * pstrVal
  2067. )
  2068. {
  2069. W3_METADATA * pMetaData = NULL;
  2070. CHAR * pszResponse = NULL;
  2071. DBG_ASSERT( pW3Context != NULL );
  2072. DBG_ASSERT( pstrVal != NULL );
  2073. pMetaData = pW3Context->QueryUrlContext()->QueryMetaData();
  2074. DBG_ASSERT( pMetaData != NULL );
  2075. pszResponse = ( pMetaData->QuerySSIExecDisabled() )? "1": "0";
  2076. return pstrVal->Copy( pszResponse );
  2077. }
  2078. HRESULT
  2079. GetServerVariableOriginalUrlW(
  2080. W3_CONTEXT * pW3Context,
  2081. STRU * pstrVal
  2082. )
  2083. {
  2084. DBG_ASSERT( pW3Context != NULL );
  2085. DBG_ASSERT( pstrVal != NULL );
  2086. return pW3Context->QueryMainContext()->QueryRequest()->GetOriginalFullUrl(pstrVal);
  2087. }
  2088. HRESULT
  2089. GetServerVariableOriginalUrl(
  2090. W3_CONTEXT * pW3Context,
  2091. STRA * pstrVal
  2092. )
  2093. {
  2094. STACK_STRU( struVal, 256);
  2095. HRESULT hr;
  2096. if (FAILED(hr = GetServerVariableOriginalUrlW(pW3Context, &struVal)) ||
  2097. FAILED(hr = pstrVal->CopyW(struVal.QueryStr())))
  2098. {
  2099. return hr;
  2100. }
  2101. return S_OK;
  2102. }