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.

595 lines
14 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name :
  4. tdict.cxx
  5. Abstract:
  6. This is a test module for the dictionary objects
  7. Author:
  8. Murali R. Krishnan ( MuraliK ) 8-Nov-1996
  9. Environment:
  10. User Mode - Win32
  11. Project:
  12. Internet Server DLL
  13. Functions Exported:
  14. Revision History:
  15. --*/
  16. /************************************************************
  17. * Include Headers
  18. ************************************************************/
  19. # include "httphdr.hxx"
  20. #define DEFAULT_TRACE_FLAGS ((DEBUG_ERROR | DEBUG_PARSING | DEBUG_INIT_CLEAN)
  21. # include "dbgutil.h"
  22. # include <stdio.h>
  23. # include <stdlib.h>
  24. /************************************************************
  25. * Functions
  26. ************************************************************/
  27. # define INPUT_HEADER_LENGTH_LIMIT (100000)
  28. DECLARE_DEBUG_PRINTS_OBJECT();
  29. #ifndef _NO_TRACING_
  30. #include <initguid.h>
  31. DEFINE_GUID(IisTDictGuid,
  32. 0x784d8926, 0xaa8c, 0x11d2, 0x92, 0x5e, 0x00, 0xc0, 0x4f, 0x72, 0xd9, 0x0e);
  33. #else
  34. DECLARE_DEBUG_VARIABLE();
  35. #endif
  36. CHAR g_rgchUsage[] =
  37. " Usage: %s [header <header-sequence> | mapper]\n"
  38. " mapper tests the HTTP_HEADER_MAPPER object which maps HTTP headers\n"
  39. " to the ordinals\n"
  40. " header loads headers and tests the dictionary functions (HTTP_HEADERS)\n"
  41. " input headers are limited to 100K characters\n"
  42. " <header-sequence> is a sequence of test vector numbers [0..6] of standard\n"
  43. " headers built in. Use \'-\' to make it read headers from stdin\n"
  44. "\n"
  45. ;
  46. CHAR * g_pszHttpHeader1 =
  47. "GET / HTTP/1.0\r\n"
  48. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  49. "Accept-Language: en\r\n"
  50. "UA-pixels: 1152x882\r\n"
  51. "UA-color: color8\r\n"
  52. "UA-OS: Windows NT\r\n"
  53. "UA-CPU: x86\r\n"
  54. "If-Modified-Since: Fri, 20 Sep 1996 23:36:42 GMT; length=4051\r\n"
  55. "User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; AK; Windows.NT\r\n"
  56. "Host: muralik\r\n"
  57. "Connection: Keep-Alive\r\n"
  58. "\r\n"
  59. ;
  60. // check if and non-fast map header works
  61. CHAR * g_pszHttpHeader2 =
  62. "GET /samples/images/background.gif HTTP/1.0\r\n"
  63. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  64. "Referer: http://muralik0/\r\n"
  65. "Accept-Language: en\r\n"
  66. "UA-pixels: 1152x882\r\n"
  67. "UA-color: color8\r\n"
  68. "UA-OS: Windows NT\r\n"
  69. "UA-CPU: x86\r\n"
  70. "If-Modified-Since: Fri, 20 Sep 1996 23:36:47 GMT; length=10282\r\n"
  71. "User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; AK; Windows.NT\r\n"
  72. "Host: muralik\r\n"
  73. "Connection: Keep-Alive\r\n"
  74. "MyHeader1: MyValue1\r\n"
  75. "MyHeader2: MyValue2\r\n"
  76. "\r\n"
  77. ;
  78. // Checks if concatenation of headers work
  79. CHAR * g_pszHttpHeader3 =
  80. "GET / HTTP/1.0\r\n"
  81. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  82. "Accept-Language: en\r\n"
  83. "Accept-Language: es\r\n"
  84. "UA-pixels: 1152x882\r\n"
  85. "UA-color: color8\r\n"
  86. "UA-OS: Windows NT\r\n"
  87. "UA-CPU: x86\r\n"
  88. "If-Modified-Since: Fri, 20 Sep 1996 23:36:42 GMT; length=4051\r\n"
  89. "User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; AK; Windows.NT\r\n"
  90. "Host: muralik\r\n"
  91. "Connection: Keep-Alive\r\n"
  92. "Connection: 5m\r\n"
  93. "Accept: Testing it \r\n"
  94. "\r\n"
  95. ;
  96. // check if and non-fast map header works with concatenation
  97. CHAR * g_pszHttpHeader4 =
  98. "GET /samples/images/background.gif HTTP/1.0\r\n"
  99. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  100. "Referer: http://muralik0/\r\n"
  101. "Accept-Language: en\r\n"
  102. "UA-pixels: 1152x882\r\n"
  103. "UA-color: color8\r\n"
  104. "UA-OS: Windows NT\r\n"
  105. "UA-CPU: x86\r\n"
  106. "If-Modified-Since: Fri, 20 Sep 1996 23:36:47 GMT; length=10282\r\n"
  107. "User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; AK; Windows.NT\r\n"
  108. "Host: muralik\r\n"
  109. "Connection: Keep-Alive\r\n"
  110. "MyHeader1: MyValue1\r\n"
  111. "MyHeader2: MyValue2\r\n"
  112. "MyHeader1: MyValue1_2\r\n"
  113. "\r\n"
  114. ;
  115. // check if and non-fast map header works with concatenation and
  116. // different length aux headers
  117. CHAR * g_pszHttpHeader5 =
  118. "GET /samples/images/background.gif HTTP/1.0\r\n"
  119. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  120. "Referer: http://muralik0/\r\n"
  121. "Accept-Language: en\r\n"
  122. "UA-pixels: 1152x882\r\n"
  123. "UA-color: color8\r\n"
  124. "UA-OS: Windows NT\r\n"
  125. "UA-CPU: x86\r\n"
  126. "If-Modified-Since: Fri, 20 Sep 1996 23:36:47 GMT; length=10282\r\n"
  127. "User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; AK; Windows.NT\r\n"
  128. "Host: muralik\r\n"
  129. "Connection: Keep-Alive\r\n"
  130. "MyHead2: MyValue2\r\n"
  131. "MyHeader1: MyValue1\r\n"
  132. "MyHeader1: MyValue1_2\r\n"
  133. "\r\n"
  134. ;
  135. /*
  136. Headers Sent by Netscape 3.0 client --
  137. note No CACHE because of this being the first-request :(
  138. */
  139. CHAR * g_pszHttpHeader6 =
  140. "GET /scripts/asp/test.asp HTTP/1.0\r\n"
  141. "Connection: Keep-Alive\r\n"
  142. "User-Agent: Mozilla/3.0.(WinNT; I)\r\n"
  143. "Pragma: no-cache\r\n"
  144. "Host: phillich1\r\n"
  145. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  146. "\r\n";
  147. /*
  148. Headers Sent by Netscape 3.0 client --
  149. note No CACHE because of this being the first-request :(
  150. */
  151. CHAR * g_pszHttpHeader7 =
  152. "GET /scripts/asp/test.asp HTTP/1.0\r\n"
  153. "Connection: Keep-Alive\r\n"
  154. "User-Agent: Mozilla/3.0 (WinNT; I)\r\n"
  155. "Pragma: no-cache\r\n"
  156. "Host: phillich1\r\n"
  157. "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"
  158. "Cookie: ASPSESSIONID=PVZQGHUMEAYFNRFK\r\n"
  159. "\r\n";
  160. CHAR * g_ppHeaders[] = {
  161. g_pszHttpHeader1,
  162. g_pszHttpHeader2,
  163. g_pszHttpHeader3,
  164. g_pszHttpHeader4,
  165. g_pszHttpHeader5,
  166. g_pszHttpHeader6,
  167. g_pszHttpHeader7
  168. };
  169. # define MAX_TEST_HEADERS ( sizeof( g_ppHeaders) / sizeof( g_ppHeaders[0]))
  170. /************************************************************
  171. * Functions
  172. ************************************************************/
  173. VOID PrintUsage( char * pszProgram)
  174. {
  175. fprintf( stderr, g_rgchUsage, pszProgram);
  176. return;
  177. } // PrintUsage()
  178. VOID
  179. TestMapper( int argc, char * argv[])
  180. {
  181. int argSeen;
  182. const DICTIONARY_MAPPER * pdm = HTTP_HEADERS::QueryHHMapper();
  183. for( argSeen = 0; argSeen < argc; argSeen++) {
  184. DWORD dwOrdinal = 0;
  185. if ( pdm->FindOrdinal( argv[argSeen], strlen( argv[argSeen]),
  186. & dwOrdinal)
  187. ) {
  188. DBGPRINTF(( DBG_CONTEXT, "\nFindOrdinal(%d, %s) => %d\n",
  189. argSeen, argv[argSeen], dwOrdinal));
  190. LPCSTR pszHeader = pdm->FindName( dwOrdinal);
  191. DBGPRINTF(( DBG_CONTEXT, "FindOrdinal( %d) => %s\n",
  192. dwOrdinal,
  193. ( NULL == pszHeader) ? "not found" : pszHeader
  194. ));
  195. } else {
  196. DBGPRINTF(( DBG_CONTEXT, "\nFindOrdinal( %d, %s) returns failure\n",
  197. argSeen, argv[argSeen]));
  198. }
  199. } // for
  200. CHAR pchBuffer[20000];
  201. DWORD cch = sizeof( pchBuffer);
  202. pdm->PrintToBuffer( pchBuffer, &cch);
  203. DBG_ASSERT( cch < sizeof(pchBuffer));
  204. fprintf( stdout, "Header Mapper is: size=%d\n", cch);
  205. fwrite( pchBuffer, 1, cch, stdout);
  206. return;
  207. } // TestMapper()
  208. VOID
  209. ThPrint( IN HTTP_HEADERS * phd)
  210. {
  211. // Test Header PrintToBuffer()
  212. CHAR pchBuffer[20000];
  213. DWORD cch;
  214. cch = sizeof( pchBuffer);
  215. phd->PrintToBuffer( pchBuffer, &cch);
  216. DBG_ASSERT( cch < sizeof(pchBuffer));
  217. fwrite( pchBuffer, 1, cch, stdout);
  218. return;
  219. } // ThPrint()
  220. VOID
  221. ThIterator( IN HTTP_HEADERS * phd)
  222. {
  223. HH_ITERATOR hhi;
  224. NAME_VALUE_PAIR * pnp;
  225. int i;
  226. printf( "\t---- Test Iterator on all headers\n");
  227. phd->InitIterator( &hhi);
  228. for( i = 0; phd->NextPair( &hhi, &pnp); i++) {
  229. // dump the header-value pairs
  230. printf( "\n [%d] ", i);
  231. fwrite( pnp->pchName, 1, pnp->cchName, stdout);
  232. fputc('\t', stdout);
  233. fwrite( pnp->pchValue, 1, pnp->cchValue, stdout);
  234. } // for
  235. printf( "\nTotal of %d headers found. Error = %d\n", i, GetLastError());
  236. return;
  237. } // ThIterator()
  238. CHAR * pTh1 = "TestHeader1";
  239. CHAR * pTv1 = "TestVal1";
  240. CHAR * pTh2 = "Accept:";
  241. CHAR * pTv2 = "TestVal2";
  242. VOID ThStoreHeader( IN HTTP_HEADERS * phd)
  243. {
  244. BOOL fRet;
  245. printf( "\n\t---- Test StoreHeader \n");
  246. fRet = phd->StoreHeader( pTh1, strlen( pTh1),
  247. pTv1, strlen( pTv1)
  248. );
  249. printf( "%08x::StoreHeader( %s, %s) return %d\n",
  250. phd, pTh1, pTv1, fRet);
  251. fRet = phd->StoreHeader( pTh2, strlen( pTh2),
  252. pTv2, strlen( pTv2)
  253. );
  254. printf( "%08x::StoreHeader( %s, %s) return %d\n",
  255. phd, pTh2, pTv2, fRet);
  256. // print the headers to test this out.
  257. ThPrint( phd);
  258. return;
  259. } // ThStoreHeader()
  260. VOID ThFindValue( IN HTTP_HEADERS * phd)
  261. {
  262. LPCSTR pszVal;
  263. DWORD cchVal;
  264. printf( "\n\t---- Test FindHeader \n");
  265. pszVal = phd->FindValue( pTh1, &cchVal);
  266. printf( "%08x::FindValue( %s, %08x) returns %08x [size=%d] %s\n",
  267. phd, pTh1, &cchVal, pszVal, cchVal, pszVal);
  268. cchVal = 0;
  269. pszVal = phd->FindValue( pTh2);
  270. printf( "%08x::FindValue( %s, NULL) returns %08x [size=%d] %s\n",
  271. phd, pTh2, pszVal, cchVal, pszVal);
  272. // Ask non-existent header
  273. cchVal = 10000;
  274. pszVal = phd->FindValue( "random", &cchVal);
  275. printf( "%08x::FindValue( %s, %08x) returns %08x [size=%d] %s\n",
  276. phd, "random", &cchVal, pszVal, cchVal, pszVal);
  277. return;
  278. } // ThFindValue()
  279. VOID ThCancelHeader( IN HTTP_HEADERS * phd)
  280. {
  281. LPCSTR pszVal;
  282. printf( "\n\t---- Test CancelHeader \n");
  283. phd->CancelHeader( pTh1);
  284. printf( "%08x::CancelHeader( %s) done \n", phd, pTh1);
  285. phd->CancelHeader( pTh2);
  286. printf( "%08x::CancelHeader( %s) done \n", phd, pTh2);
  287. ThPrint( phd);
  288. return;
  289. } // ThCancelHeader()
  290. VOID ThFmStore( IN HTTP_HEADERS * phd)
  291. {
  292. BOOL fRet;
  293. printf( "\n\t---- Test FastMap Store \n");
  294. phd->FastMapStore( HM_ACC, "text/plain");
  295. printf( "%08x::FastMapStore( %d, %s) done\n",
  296. phd, HM_ACC, "text/plain");
  297. fRet = phd->FastMapStoreWithConcat( HM_ACC, "*/*", 3);
  298. printf( "%08x::FastMapStoreWithConcat( %d, %s) returns %d\n",
  299. phd, HM_ACC, "*/*", fRet);
  300. ThPrint( phd);
  301. } // ThFmStore()
  302. BOOL
  303. TestHeaderFuncs( IN HTTP_HEADERS * phd)
  304. {
  305. DBG_ASSERT( phd);
  306. ThPrint( phd);
  307. ThIterator(phd);
  308. ThStoreHeader( phd);
  309. ThFindValue( phd);
  310. ThCancelHeader( phd);
  311. ThFmStore(phd);
  312. ThIterator(phd);
  313. return ( TRUE);
  314. } // TestHeaderFuncs()
  315. BOOL
  316. TestHeader( IN HTTP_HEADERS * phd,
  317. IN const CHAR * pszHeader,
  318. IN DWORD cchHeader)
  319. {
  320. DWORD cbExtra = 0;
  321. phd->Reset();
  322. phd->Print();
  323. if ( phd->ParseInput( pszHeader, cchHeader, &cbExtra)) {
  324. DBGPRINTF(( DBG_CONTEXT, " Parsed Header \n%s\n was successful. "
  325. " Extra bytes = %d\n",
  326. pszHeader, cbExtra));
  327. fprintf( stdout, "Successfully parsed Header @ %08x (size=%d)\n",
  328. pszHeader, cchHeader);
  329. return ( TestHeaderFuncs( phd));
  330. } else {
  331. fprintf( stderr, " Parsing Header \n%s\n failed. Error = %d\n",
  332. pszHeader, GetLastError());
  333. return ( FALSE);
  334. }
  335. return (FALSE);
  336. } // TestHeader()
  337. BOOL
  338. GetInputHeader(IN CHAR * pchBuffer, IN OUT LPDWORD pcbHeader)
  339. {
  340. DWORD cb, cbRead;
  341. // read the header given in the input - one line at a time
  342. for ( cb = 0, cbRead = 0;
  343. (fgets( pchBuffer + cb, *pcbHeader - cb, stdin) != NULL);
  344. cb += cbRead
  345. ){
  346. if ( pchBuffer[cb] == ';') {
  347. // This is a comment line. Skip and continue.
  348. cbRead = 0;
  349. continue;
  350. }
  351. cbRead = strlen( pchBuffer + cb);
  352. // check for endof line marker
  353. if ( !strcmp( pchBuffer + cb, "\r\n") ||
  354. !strcmp( pchBuffer + cb, "\n")
  355. ){
  356. // we are done. exit now.
  357. *pcbHeader = (cb + cbRead);
  358. pchBuffer[ cb + cbRead] = '\0';
  359. return ( TRUE);
  360. }
  361. } // for
  362. return ( FALSE);
  363. } // GetInputHeader()
  364. VOID
  365. TestDictionary( int argc, char * argv[])
  366. {
  367. HTTP_HEADERS * phd;
  368. phd = new HTTP_HEADERS();
  369. if ( NULL == phd) {
  370. fprintf( stderr, " Unable to create the dictionary. \n");
  371. exit( 1);
  372. }
  373. for ( int i = 0; i < argc; i++) {
  374. if ( argv[i][0] == '-') {
  375. CHAR pchBuffer[INPUT_HEADER_LENGTH_LIMIT + 2];
  376. for ( ; ; ) {
  377. DWORD cchBuffer = sizeof( pchBuffer);
  378. if (!GetInputHeader( pchBuffer, &cchBuffer)) {
  379. break;
  380. }
  381. fprintf( stdout,
  382. "\n ------------ Header from input -----------\n"
  383. );
  384. TestHeader( phd, pchBuffer, cchBuffer);
  385. fprintf( stdout,
  386. "\n --------------------------------------------\n");
  387. } // for - as long as there is input
  388. } else {
  389. int iHeader = atoi( argv[i]);
  390. if ( iHeader < MAX_TEST_HEADERS) {
  391. fprintf( stdout,
  392. "\n ------------ [%4d] = Header %4d -----------\n",
  393. i, iHeader);
  394. TestHeader( phd, g_ppHeaders[iHeader],
  395. strlen( g_ppHeaders[iHeader]));
  396. fprintf( stdout,
  397. "\n --------------------------------------------\n");
  398. }
  399. }
  400. } // for
  401. delete phd;
  402. return;
  403. } // TestDictionary()
  404. int __cdecl
  405. main(int argc, char * argv[])
  406. {
  407. int argSeen = 1;
  408. #ifndef _NO_TRACING_
  409. CREATE_DEBUG_PRINT_OBJECT( argv[0], IisTDictGuid);
  410. CREATE_INITIALIZE_DEBUG();
  411. #else
  412. CREATE_DEBUG_PRINT_OBJECT( argv[0]);
  413. SET_DEBUG_FLAGS( DEBUG_ERROR | DEBUG_PARSING | DEBUG_INIT_CLEAN);
  414. #endif
  415. if ( argc < 2) {
  416. PrintUsage( argv[0]);
  417. exit(1);
  418. }
  419. fprintf( stdout,
  420. " sizeof( HTTP_HEADERS) = %d\t sizeof(HTTP_HEADER_MAPPER) = %d\n",
  421. sizeof( HTTP_HEADERS), sizeof(HTTP_HEADER_MAPPER));
  422. if ( !HTTP_HEADERS::Initialize()) {
  423. fprintf( stderr, " Initialization failed\n");
  424. exit (1);
  425. }
  426. if ( !strcmp( argv[1], "mapper") ) {
  427. TestMapper( argc-2, argv+2);
  428. } else if ( !strcmp( argv[1], "header")) {
  429. TestDictionary( argc-2, argv+2);
  430. } else {
  431. PrintUsage( argv[0]);
  432. }
  433. HTTP_HEADERS::Cleanup();
  434. DELETE_DEBUG_PRINT_OBJECT();
  435. return (1);
  436. } // main()
  437. /************************ End of File ***********************/