home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / readcli.c < prev    next >
C/C++ Source or Header  |  1997-10-25  |  8KB  |  289 lines

  1. /*++
  2.  
  3. Copyright (c) 1997  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     readcli.c
  8.  
  9. Abstract:
  10.  
  11.     This module absorbs input from the client, and then returns
  12.     it to the client.
  13.  
  14. Revision History:
  15. --*/
  16. #define WIN32_LEAN_AND_MEAN
  17. #include <windows.h>
  18. #include <httpext.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21.  
  22. #define BUFFER_LENGTH 4096
  23. #define STRING_LENGTH 80
  24.  
  25. // Prototypes
  26. BOOL SendErrorToClient( LPEXTENSION_CONTROL_BLOCK pec, CHAR *szErrorText );
  27.  
  28. BOOL WINAPI 
  29. GetExtensionVersion( HSE_VERSION_INFO *Version )
  30. /*++
  31.  
  32. Routine Description:
  33.  
  34.     Sets the ISAPI extension version information.
  35.  
  36. Arguments:
  37.  
  38.     Version     pointer to HSE_VERSION_INFO structure
  39.  
  40. Return Value:
  41.  
  42.     TRUE
  43.  
  44. --*/
  45. {
  46.     Version->dwExtensionVersion = 
  47.         MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR );
  48.  
  49.     strcpy( Version->lpszExtensionDesc, "ReadClient Extension" );
  50.  
  51.     return TRUE;
  52. }
  53.  
  54.  
  55. DWORD WINAPI 
  56. HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK pec )
  57. /*++
  58.  
  59. Routine Description:
  60.  
  61.     This is the main routine for any ISAPI application.  We read in all
  62.     the data from the client, using the ReadClient function, and then
  63.     spit it all back out to the client using WriteClient.
  64.  
  65. Arguments:
  66.  
  67.     pec           pointer to ECB containing parameters related to the request.
  68.  
  69. Return Value:
  70.  
  71.     Either HSE_STATUS_SUCCESS or HSE_STATUS_ERROR
  72.  
  73. --*/
  74. {
  75.     BOOL bResult;
  76.     CHAR *szBuffer;
  77.     CHAR szTemp[BUFFER_LENGTH];
  78.     CHAR szTmpBuf[BUFFER_LENGTH];
  79.     DWORD dwBytesRead;
  80.     DWORD dwBytesWritten;
  81.     DWORD dwTotalRead;
  82.     DWORD dwTotalWritten;
  83.     DWORD dwContentLength;
  84.     DWORD dwBufferSize;
  85.     HSE_SEND_HEADER_EX_INFO SendHeaderExInfo;
  86.  
  87.     // Determine the amount of data available from the
  88.     // Content-Length header
  89.     dwBufferSize = sizeof( szTmpBuf ) - 1;
  90.     bResult = pec->GetServerVariable(
  91.         pec->ConnID,
  92.         "CONTENT_LENGTH",
  93.         szTmpBuf,
  94.         &dwBufferSize
  95.         );
  96.     if ( !bResult ) {
  97.         bResult = SendErrorToClient( pec, "Content-Length header not found" );
  98.         if ( !bResult ) {
  99.             return( HSE_STATUS_ERROR );
  100.         }
  101.         return( HSE_STATUS_SUCCESS );
  102.     }
  103.     dwContentLength = atol( szTmpBuf );
  104.  
  105.     // Allocate the buffer based on the Content-Length
  106.     szBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwContentLength + 5 );
  107.     if ( szBuffer == NULL ) {
  108.         sprintf(
  109.             szTemp,
  110.             "Unable to allocate %ld bytes of memory for buffer",
  111.             dwContentLength + 5
  112.             );
  113.         bResult = SendErrorToClient( pec, szTemp );
  114.         if ( !bResult ) {
  115.             return( HSE_STATUS_ERROR );
  116.         }
  117.         return( HSE_STATUS_SUCCESS );
  118.     }
  119.  
  120.     // If the client didn't post anything, return and create a nice form
  121.     // for them
  122.     if ( pec->cbAvailable == 0 ) {
  123.         bResult = SendErrorToClient( pec, "Your request did not contain any data" );
  124.         if ( !bResult ) {
  125.             return( HSE_STATUS_ERROR );
  126.         }
  127.         return( HSE_STATUS_SUCCESS );
  128.     }
  129.  
  130.  
  131.     // Initialize variables before reading in the data
  132.     dwTotalWritten = 0;
  133.     dwTotalRead = pec->cbAvailable;
  134.  
  135.     // Copy the first chunk of the data into the buffer
  136.     strncpy( szBuffer, pec->lpbData, dwTotalRead );
  137.     szBuffer[dwTotalRead] = 0;
  138.  
  139.     // Loop to read in the rest of the data from the client
  140.     while ( dwTotalRead < pec->cbTotalBytes ) {
  141.         // Set the size of our temporary buffer
  142.         dwBytesRead = sizeof( szTmpBuf ) - 1;
  143.         if ( (dwTotalRead + dwBytesRead) > pec->cbTotalBytes ) {
  144.             dwBytesRead = pec->cbTotalBytes - dwTotalRead;
  145.         }
  146.  
  147.         // Read the data into the temporary buffer
  148.         bResult = pec->ReadClient(
  149.             pec->ConnID,
  150.             szTmpBuf,
  151.             &dwBytesRead
  152.             );
  153.         if ( !bResult ) {
  154.             HeapFree( GetProcessHeap(), 0, szBuffer );
  155.             return( HSE_STATUS_ERROR );
  156.         }
  157.         // NULL-Terminate the temporary buffer
  158.         szTmpBuf[dwBytesRead] = 0;
  159.  
  160.         // Append the temporary buffer to the real buffer
  161.         if ( dwBytesRead != 0 ) {
  162.             strcat( szBuffer + dwTotalRead, szTmpBuf );
  163.         }
  164.         dwTotalRead += dwBytesRead;
  165.     } // while ( dwTotalRead < pec->cbTotalBytes )
  166.  
  167.     // All the data has been read in and stored in our buffer
  168.     // Now send the data back to the client
  169.     SendHeaderExInfo.pszStatus = "200 OK";
  170.     SendHeaderExInfo.pszHeader = "Content-Type: text/html\r\n\r\n";
  171.     SendHeaderExInfo.cchStatus = lstrlen( SendHeaderExInfo.pszStatus );
  172.     SendHeaderExInfo.cchHeader = lstrlen( SendHeaderExInfo.pszHeader );
  173.     SendHeaderExInfo.fKeepConn = FALSE;
  174.  
  175.     bResult = pec->ServerSupportFunction(
  176.         pec->ConnID,
  177.         HSE_REQ_SEND_RESPONSE_HEADER_EX,
  178.         &SendHeaderExInfo,
  179.         NULL,
  180.         NULL
  181.         );
  182.     if ( !bResult ) {
  183.         HeapFree( GetProcessHeap(), 0, szBuffer );
  184.         return( HSE_STATUS_ERROR );
  185.     }
  186.     dwBytesWritten = dwTotalRead;
  187.     bResult = pec->WriteClient(
  188.         pec->ConnID,
  189.         szBuffer,
  190.         &dwBytesWritten,
  191.         0
  192.         );
  193.     if ( !bResult ) {
  194.         HeapFree( GetProcessHeap(), 0, szBuffer );
  195.         return( HSE_STATUS_ERROR );
  196.     }
  197.     HeapFree( GetProcessHeap(), 0, szBuffer );
  198.     return( HSE_STATUS_SUCCESS );
  199. }
  200.  
  201.  
  202.  
  203.  
  204. BOOL WINAPI
  205. TerminateExtension( DWORD dwFlags )
  206. /*++
  207.  
  208. Routine Description:
  209.  
  210.     This function is called when the WWW service is shutdown
  211.  
  212. Arguments:
  213.  
  214.     dwFlags - HSE_TERM_ADVISORY_UNLOAD or HSE_TERM_MUST_UNLOAD
  215.  
  216. Return Value:
  217.  
  218.     TRUE if extension is ready to be unloaded,
  219.     FALSE otherwise
  220.  
  221. --*/
  222. {
  223.     return TRUE;
  224. }
  225.  
  226.  
  227. BOOL SendErrorToClient( LPEXTENSION_CONTROL_BLOCK pec, CHAR *szErrorText )
  228. /*++
  229.  
  230. Routine Description:
  231.  
  232.     This function sends any error messages and usage information
  233.     to the client.  It also creates a nice little form which can
  234.     be used to post data.
  235.  
  236. Arguments:
  237.  
  238.     pec - pointer to ECB containing parameters related to the request
  239.     szErrorText - Helpful error text to send to the client
  240.  
  241. Return Value:
  242.  
  243.     TRUE or FALSE, depending on the success of WriteClient
  244.  
  245. --*/
  246. {
  247.     BOOL bResult;
  248.     CHAR szTemp[BUFFER_LENGTH];
  249.     DWORD dwBytesWritten;
  250.     HSE_SEND_HEADER_EX_INFO SendHeaderExInfo;
  251.  
  252.     SendHeaderExInfo.pszStatus = "200 OK";
  253.     SendHeaderExInfo.pszHeader = "Content-Type: text/html\r\n\r\n";
  254.     SendHeaderExInfo.cchStatus = lstrlen( SendHeaderExInfo.pszStatus );
  255.     SendHeaderExInfo.cchHeader = lstrlen( SendHeaderExInfo.pszHeader );
  256.     SendHeaderExInfo.fKeepConn = FALSE;
  257.  
  258.     bResult = pec->ServerSupportFunction(
  259.         pec->ConnID,
  260.         HSE_REQ_SEND_RESPONSE_HEADER_EX,
  261.         &SendHeaderExInfo,
  262.         NULL,
  263.         NULL
  264.         );
  265.     if ( !bResult ) {
  266.         return FALSE;
  267.     }
  268.  
  269.     dwBytesWritten = sprintf( 
  270.         szTemp, 
  271.         "<h3>Error: %s</h3><p>\r\n\r\n"
  272.         "Usage: readcli.dll<p>\r\n\r\n"
  273.         "Request must be a POST request, with extra data<p>\r\n"
  274.         "<h2>Sample Form</h2>\r\n"
  275.         "Enter data below:<br>\r\n"
  276.         "<form method=POST action=\"readcli.dll\">\r\n"
  277.         "<input type=text name=test size=80><br>\r\n"
  278.         "<input type=submit>\r\n",
  279.         szErrorText
  280.         );
  281.     bResult = pec->WriteClient(
  282.         pec->ConnID,
  283.         szTemp,
  284.         &dwBytesWritten,
  285.         0
  286.         );
  287.     return( bResult );
  288. }
  289.