home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / source / chap13 / lst13_6.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-11  |  7.8 KB  |  341 lines

  1. // Lst15_10.cpp
  2.  
  3. #include <stdio.h>
  4. #include <afx.h>
  5.  
  6. // Global Cache for Post
  7. // You can only read from
  8. // Standard In Once
  9.  
  10. TCHAR *szCache=NULL;
  11.  
  12. TCHAR ConvertHex(TCHAR cHigh, TCHAR cLow)
  13. {
  14.     static const TCHAR szHex[] = _T("0123456789ABCDEF");
  15.     
  16.     LPCTSTR pszLow;
  17.     LPCTSTR pszHigh;
  18.     TCHAR cValue;
  19.  
  20.     // Find the Values in the Hex String
  21.     pszHigh = _tcschr(szHex, (TCHAR) _totupper(cHigh));
  22.     pszLow = _tcschr(szHex, (TCHAR) _totupper(cLow));
  23.     
  24.     // If both Values Exist Then Calculate the Value
  25.     // Based off of the string
  26.     if (pszHigh && pszLow)
  27.     {
  28.         cValue = (TCHAR) (((pszHigh - szHex) << 4) + (pszLow - szHex));
  29.         return (cValue);
  30.     }
  31.  
  32.     return('?');
  33. }
  34.  
  35. // Returns the String
  36. LPVOID TranslateCGI(LPTSTR pszString)
  37. {
  38.     LPTSTR pszIndex = pszString;
  39.     LPTSTR pszReturn = pszString;
  40.  
  41.     // unescape special characters
  42.  
  43.     while (*pszIndex)
  44.     {
  45.         // Translate '+' to Spaces
  46.         if (*pszIndex == _T('+'))
  47.             *pszReturn++ = _T(' ');
  48.         
  49.         // Translate Hex Strings to characters
  50.         else if (*pszIndex == _T('%'))
  51.         {
  52.             *pszReturn++=ConvertHex(pszIndex[1], pszIndex[2]);
  53.             pszIndex+=2;
  54.         }
  55.  
  56.         // or just copy the character
  57.         else
  58.             *pszReturn++ = *pszIndex;
  59.         pszIndex++;
  60.     }
  61.     
  62.     // Terminate the End
  63.     *pszReturn = '\0';
  64.  
  65.     return (LPVOID) pszString;
  66. }
  67.  
  68. DWORD GetValue(LPTSTR szCGI, LPTSTR szName, LPTSTR szValue, DWORD dwValueSize)
  69. {
  70.     LPTSTR    szIndex;
  71.     LPTSTR    szEnd;
  72.     DWORD    dwReturnSize=0;
  73.  
  74.     // Find The Name in the Query String
  75.     szIndex=_tcsstr(szCGI,szName);
  76.  
  77.     // Error: The Name part of the Name value pair doesn't exist
  78.     if (!szIndex)
  79.         return (0);
  80.     
  81.     // Increase the pointer passed the Name and Get to the Value
  82.     szIndex+=_tcslen(szName)+1;
  83.  
  84.     // Find the End of the Value by looking for the '&'
  85.     szEnd=_tcschr(szCGI,_T('&'));
  86.  
  87.     // if we find a '&' set it as the end
  88.     if (szEnd)
  89.         (*szEnd)='\0';
  90.  
  91.     // Remove the CGI Syntax
  92.     TranslateCGI(szIndex);
  93.  
  94.     // Calculate the Value Size
  95.     dwReturnSize=_tcslen(szIndex);
  96.  
  97.     // Chop the Value if bigger then the Allocation of Value
  98.     if (dwReturnSize>dwValueSize)
  99.         szIndex[dwValueSize]=_T('\0');
  100.  
  101.     // Assign the Value if there is allocated space
  102.     // if no space has been allocated then the caller
  103.     // is just looking for the string size
  104.     if (szValue)
  105.         _tcscpy(szValue,szIndex);
  106.  
  107.     // If we are going to return the size of
  108.     // Allocated space we new might as well
  109.     // include the Null
  110.     return (dwReturnSize+1);
  111. }
  112.  
  113. // Returns The Length of szValue on successful execution else returns 0
  114. DWORD GetMethod(LPTSTR szName, LPTSTR szValue, DWORD dwValueSize)
  115. {
  116.      DWORD    dwBufferSize=0;
  117.     DWORD    dwReturnSize=0;
  118.     LPTSTR    szQuery=NULL;
  119.  
  120.     // Call GetEnvironmentVariable To get the buffer size
  121.     dwBufferSize=GetEnvironmentVariable(_T("QUERY_STRING"),szQuery,dwBufferSize);
  122.  
  123.     // Error: QUERY_STRING doesn't exist
  124.     if (!dwBufferSize)
  125.         return(0);
  126.  
  127.     // Allocate the Need Space
  128.     szQuery = new TCHAR[dwBufferSize];
  129.  
  130.     // Call Again
  131.     dwBufferSize=GetEnvironmentVariable(_T("QUERY_STRING"),szQuery,dwBufferSize);
  132.  
  133.     // Get the Value From the Query String 
  134.     dwReturnSize=GetValue(szQuery,szName,szValue,dwValueSize);
  135.  
  136.     delete szQuery;
  137.  
  138.     return (dwReturnSize);
  139. }
  140.  
  141. // Returns The Content Length on successful execution else returns 0
  142. DWORD GetContentLength()
  143. {
  144.      DWORD    dwBufferSize=0;
  145.     LPTSTR    szContentLength=NULL;
  146.     DWORD    dwContentLength;
  147.  
  148.     // Call GetEnvironmentVariable to get the buffer size
  149.     dwBufferSize=GetEnvironmentVariable(_T("CONTENT_LENGTH"),szContentLength,dwBufferSize);
  150.  
  151.     // Error: CONTENT_LENGTH doesn't exist
  152.     if (!dwBufferSize)
  153.         return(0);
  154.  
  155.     // Allocate the Need Space
  156.     szContentLength = new TCHAR[dwBufferSize];
  157.  
  158.     // Call Again
  159.     dwBufferSize=GetEnvironmentVariable(_T("CONTENT_LENGTH"),szContentLength,dwBufferSize);
  160.  
  161.     // Change the String to a usable form
  162.     dwContentLength=(DWORD)_ttoi(szContentLength);
  163.  
  164.     delete szContentLength;
  165.  
  166.     return(dwContentLength);
  167. }
  168.  
  169. // Returns The Length of szValue on successful execution else returns 0
  170. DWORD PostMethod(LPTSTR szName, LPTSTR szValue, DWORD dwValueSize)
  171. {
  172.     DWORD    dwBufferSize;
  173.      LPTSTR    szContentType=NULL;
  174.        DWORD    dwContentTypeSize=0;
  175.     LPTSTR    szPost;
  176.     DWORD    dwReturnSize=0;
  177.     UINT    nCount;
  178.  
  179.     if (szCache)
  180.     {
  181.         dwBufferSize=_tcslen(szCache);
  182.         // Allocate Some Memory for szPost Plus the NULL
  183.         szPost=new TCHAR[dwBufferSize+1];
  184.         _tcscpy(szPost,szCache);
  185.     }
  186.     else
  187.     {
  188.         // Look at the CONTENT_TYPE to see if it is a POST
  189.  
  190.         // Call GetEnvironmentVariable to get the buffer size
  191.         dwContentTypeSize=GetEnvironmentVariable(_T("CONTENT_TYPE"),szContentType,dwContentTypeSize);
  192.  
  193.         // Error: CONTENT_TYPE doesn't exist
  194.         if (!dwContentTypeSize)
  195.             return(0);
  196.  
  197.         // Allocate the Need Space
  198.         szContentType = new TCHAR[dwContentTypeSize];
  199.  
  200.         // Call Again
  201.         GetEnvironmentVariable(_T("CONTENT_TYPE"),szContentType,dwContentTypeSize);
  202.  
  203.         if (!_tcscmp(szContentType,_T("application/x-www-form-urlencoded")))
  204.         {
  205.             // Figure out the Size of the String
  206.             dwBufferSize=GetContentLength();
  207.  
  208.             if (!dwBufferSize)
  209.                 return(0);
  210.  
  211.             // Declare the Memory for the String plus the NULL
  212.               szPost = new TCHAR[dwBufferSize+1];
  213.  
  214.             nCount=0;
  215.  
  216.             // Read the Standard In
  217.             while (!feof(stdin) && (nCount<dwBufferSize))
  218.             {    
  219.                 szPost[nCount++]=(TCHAR)_fgetchar();
  220.             }
  221.  
  222.             szPost[nCount]=_T('\0');
  223.             
  224.              // Cache the CGI String
  225.             szCache=new TCHAR[dwBufferSize+1];
  226.             _tcscpy(szCache,szPost);
  227.         }
  228.         else 
  229.         {
  230.             // Not a POST so return unsuccessfull
  231.             return(0);
  232.         }
  233.     }
  234.  
  235.     // We now have the CGI String, Lets Get the Value
  236.  
  237.     // Get the Value From the Post String 
  238.     dwReturnSize=GetValue(szPost,szName,szValue,dwValueSize);
  239.                         
  240.     delete szPost;
  241.  
  242.     // If we are going to return the size of
  243.     // Allocated space we new might as well
  244.     // include the Null
  245.     return (dwReturnSize);
  246.  
  247.     return(0);
  248. };
  249.  
  250. // Returns The Length of szValue on successful execution else returns 0
  251. DWORD GetParameter (LPTSTR szName, LPTSTR szValue, DWORD dwValueSize)
  252. {
  253.      DWORD    dwBufferSize=0;
  254.     LPTSTR    szRequestMethod=NULL;
  255.  
  256.     // Look at the enviorment variable REQUEST_METHOD
  257.  
  258.     // Call GetEnvironmentVariable to get the buffer size
  259.     dwBufferSize=GetEnvironmentVariable(_T("REQUEST_METHOD"),szRequestMethod,dwBufferSize);
  260.  
  261.     // Error: REQUEST_METHOD doesn't exist
  262.     if (!dwBufferSize)
  263.         return(0);
  264.  
  265.     // Allocate the Need Space
  266.     szRequestMethod = new TCHAR[dwBufferSize];
  267.  
  268.     // Call Again
  269.     dwBufferSize=GetEnvironmentVariable(_T("REQUEST_METHOD"),szRequestMethod,dwBufferSize);
  270.  
  271.     // It's has to be POST or GET
  272.     if (!_tcscmp(szRequestMethod,_T("GET")))
  273.     {
  274.          delete szRequestMethod;
  275.         return(GetMethod(szName,szValue,dwValueSize));
  276.     }
  277.  
  278.     if (!_tcscmp(szRequestMethod,_T("POST")))
  279.     {
  280.          delete szRequestMethod;
  281.         return(PostMethod(szName,szValue,dwValueSize));
  282.     }
  283.  
  284.     delete szRequestMethod;
  285.  
  286.     return(0);
  287. };
  288.  
  289. int main( int argc, char *argv[ ], char *envp[ ] )
  290. {
  291.  
  292.     DWORD  dwValueSize=0;
  293.     LPTSTR szValue=NULL;
  294.  
  295.     // Header
  296.     
  297.     _tprintf(_T("Status: 200\r\n"));
  298.     _tprintf(_T("Content-type: text/html\r\n"));
  299.      _tprintf(_T("\r\n"));
  300.  
  301.     // Body
  302.  
  303.     _tprintf(_T("<HTML><BODY>\n"));
  304.  
  305.     // Find out how big the name parameters is going to be
  306.     dwValueSize=GetParameter(_T("Name"),szValue,dwValueSize);
  307.  
  308.     // Allocate enough space for The Value of Name
  309.     szValue=new TCHAR[dwValueSize];
  310.  
  311.     // Get The Value Again this time with a big enough buffer
  312.        dwValueSize=GetParameter(_T("Name"),szValue,dwValueSize);
  313.  
  314.     // Display the Name
  315.     if (dwValueSize)
  316.         _tprintf(_T("Name : %s\n"),szValue);
  317.  
  318.     delete szValue;
  319.  
  320.     _tprintf(_T("<BR>\n"));
  321.  
  322.     // Do it all Again for Age
  323.     dwValueSize=GetParameter(_T("Age"),szValue,dwValueSize);
  324.     szValue=new TCHAR[dwValueSize];
  325.        dwValueSize=GetParameter(_T("Age"),szValue,dwValueSize);
  326.  
  327.     if (dwValueSize)
  328.         _tprintf(_T("Age : %s\n"),szValue);
  329.  
  330.     _tprintf(_T("</BODY></HTML>\n"));
  331.  
  332.     delete szValue;
  333.  
  334.     // Clean the Cache
  335.  
  336.     if (szCache)
  337.         delete     szCache;
  338.  
  339.     return(0);
  340. }
  341.