home *** CD-ROM | disk | FTP | other *** search
/ Mastering MFC Development / MMD.ISO / labs / c14 / lab02 / ex03 / echo.cpp next >
Encoding:
C/C++ Source or Header  |  1997-02-20  |  6.8 KB  |  215 lines

  1. // ECHO.CPP - Implementation file for your Internet Server
  2. //    Echo ISAPI App
  3.  
  4. #include <afx.h>
  5. #include <afxwin.h>
  6. #include <afxisapi.h>
  7. #include "resource.h"
  8. #include "Echo.h"
  9.  
  10. // Do not edit the following lines, which are needed by ClassWizard.
  11. #if 0
  12. BEGIN_MESSAGE_MAP(CEchoExtension, CHttpServer)
  13.     //{{AFX_MSG_MAP(CEchoExtension)
  14.     //}}AFX_MSG_MAP
  15. END_MESSAGE_MAP()
  16. #endif    // 0
  17.  
  18. ///////////////////////////////////////////////////////////////////////
  19. // command-parsing map
  20. BEGIN_PARSE_MAP(CEchoExtension, CHttpServer)
  21.     ON_PARSE_COMMAND(EchoRequest, CEchoExtension, ITS_PSTR)
  22.     ON_PARSE_COMMAND_PARAMS("option=full")
  23.     ON_PARSE_COMMAND(Default, CEchoExtension, ITS_EMPTY)
  24.     DEFAULT_PARSE_COMMAND(Default, CEchoExtension)
  25. END_PARSE_MAP(CEchoExtension)
  26.  
  27. ///////////////////////////////////////////////////////////////////////
  28. // The one and only CEchoExtension object
  29. CEchoExtension theExtension;
  30.  
  31. ///////////////////////////////////////////////////////////////////////
  32. // CEchoExtension implementation
  33. CEchoExtension::CEchoExtension()
  34. {
  35. }
  36.  
  37. CEchoExtension::~CEchoExtension()
  38. {
  39. }
  40.  
  41. BOOL CEchoExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
  42. {
  43.     // Call default implementation for initialization
  44.     CHttpServer::GetExtensionVersion(pVer);
  45.  
  46.     // Load description string
  47.     TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
  48.     ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
  49.             IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
  50.     _tcscpy(pVer->lpszExtensionDesc, sz);
  51.     return TRUE;
  52. }
  53.  
  54. ///////////////////////////////////////////////////////////////////////
  55. // CEchoExtension command handlers
  56. void CEchoExtension::Default(CHttpServerContext* pCtxt)
  57. {
  58.     StartContent(pCtxt);
  59.     WriteTitle(pCtxt);
  60.  
  61.     *pCtxt << "<P><H1>Help for Echo.dll</H1><P><HR>";
  62.     *pCtxt << "You have called the Echo ISAPI application without supplying "
  63.            << "a method and an argument.";
  64.     EchoHelp(pCtxt);
  65.     *pCtxt << "\r\n";
  66.  
  67.     EndContent(pCtxt);
  68. }
  69.  
  70. void CEchoExtension::EchoRequest(CHttpServerContext* pCtxt, LPCTSTR pstrOption)
  71. {
  72.     pCtxt->m_pECB->dwHttpStatusCode = 200;
  73.     StartContent(pCtxt);
  74.     WriteTitle(pCtxt);
  75.  
  76.     *pCtxt << "<P><H1>Echo.dll</H1><P><HR>";
  77.  
  78.     if ( _stricmp(pstrOption, "full") == 0)
  79.     {
  80.         EchoHead(pCtxt);
  81.         *pCtxt << "<BR>";
  82.         EchoBody(pCtxt);
  83.     }
  84.     else if ( _stricmp(pstrOption, "header") == 0)
  85.     {
  86.         EchoHead(pCtxt);
  87.     }
  88.     else if ( _stricmp(pstrOption, "body") == 0)
  89.     {
  90.         EchoBody(pCtxt);
  91.     }
  92.     else
  93.         BadSyntax(pCtxt);
  94.  
  95.     EndContent(pCtxt);
  96. }
  97.  
  98. ///////////////////////////////////////////////////////////////////////
  99. // Implementation member functions
  100. void CEchoExtension::EchoBody(CHttpServerContext* pCtxt)
  101. {
  102.     *pCtxt << "<P><H3>Request Body Information</H3><BR>";
  103.  
  104.     DWORD dwContentLength = pCtxt->m_pECB->cbTotalBytes;
  105.     //If there is no HTTP body, then don't process.
  106.     if ( dwContentLength == 0)
  107.     {
  108.         *pCtxt << "<I>No Request Body Present.</I>";
  109.         return;
  110.     }
  111.  
  112.     //Else, allocate stack buffer, read in, then write out.
  113.     char pstrBuffer[4000];
  114.     DWORD dwSize = sizeof(pstrBuffer);
  115.     BOOL b = pCtxt->ReadClient(pstrBuffer, &dwSize);
  116.     if (b == TRUE)
  117.     {
  118.         *pCtxt << "<I>Request Body, First " << (long int)dwSize
  119.                << " of " << (long int)dwContentLength 
  120.                << " Total Bytes Follows:</I> <BR>";
  121.         *pCtxt << pstrBuffer;
  122.     }
  123.     else  //report error back and set status code
  124.     {
  125.         *pCtxt << "<I>Error in Reading Request Body!</I>";
  126.         pCtxt->m_pECB->dwHttpStatusCode = 500;
  127.     }
  128. }
  129.  
  130. //EchoHead actually picks off the typical information from the
  131. //HTTP header after it is parsed by the Web server; it is not a
  132. //true echo.
  133. void CEchoExtension::EchoHead(CHttpServerContext* pCtxt)
  134. {
  135.     char pstrBuffer[1000];
  136.     DWORD dwSize = sizeof(pstrBuffer);
  137.     #define MECB  pCtxt->m_pECB
  138.  
  139.     *pCtxt << "<P><H3>Request Header Information</H3>";
  140.     *pCtxt << "<BR>Request method: " << MECB->lpszMethod;
  141.     *pCtxt << "<BR>Tranlsated path: " << MECB->lpszPathTranslated;
  142.     
  143.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  144.     pCtxt->GetServerVariable("QUERY_STRING", pstrBuffer, &dwSize);
  145.     *pCtxt << "<BR>Query String: " << pstrBuffer;
  146.  
  147.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  148.     pCtxt->GetServerVariable("REMOTE_USER", pstrBuffer, &dwSize);
  149.     *pCtxt << "<P>Client User name: " 
  150.            << (pstrBuffer[0]==0?"Anonymous":pstrBuffer);
  151.  
  152.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  153.     pCtxt->GetServerVariable("REMOTE_HOST", pstrBuffer, &dwSize);
  154.     *pCtxt << "<BR>Client host name: " << pstrBuffer;
  155.  
  156.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  157.     pCtxt->GetServerVariable("REMOTE_ADDR", pstrBuffer, &dwSize);
  158.     *pCtxt << "<BR>Client IP address: " << pstrBuffer;
  159.  
  160.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  161.     pCtxt->GetServerVariable("HTTP_ACCEPT", pstrBuffer, &dwSize);
  162.     *pCtxt << "<P>Accept fields: " << pstrBuffer;
  163.  
  164.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  165.     pCtxt->GetServerVariable("CONTENT_TYPE", pstrBuffer, &dwSize);
  166.     *pCtxt << "<BR>Content type (POST): " << pstrBuffer;
  167.  
  168.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  169.     pCtxt->GetServerVariable("CONTENT_LENGTH", pstrBuffer, &dwSize);
  170.     *pCtxt << "<BR>Content length: " << pstrBuffer;
  171.  
  172.     *pCtxt << "<P><B>Gratuitous Server Information</B>";
  173.  
  174.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  175.     pCtxt->GetServerVariable("SERVER_PROTOCOL", pstrBuffer, &dwSize);
  176.     *pCtxt << "<BR>Service protocol: " << pstrBuffer;
  177.  
  178.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  179.     pCtxt->GetServerVariable("SERVER_NAME", pstrBuffer, &dwSize);
  180.     *pCtxt << "<BR>Server Name: " << pstrBuffer;
  181.  
  182.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  183.     pCtxt->GetServerVariable("SERVER_SOFTWARE", pstrBuffer, &dwSize);
  184.     *pCtxt << "<BR>Server Software: " << pstrBuffer;
  185.  
  186.     dwSize = sizeof(pstrBuffer); pstrBuffer[0] = 0;
  187.     *pCtxt << "<P>";
  188.  
  189.     #undef MECB  //pCtxt->m_pECB
  190. }
  191.  
  192. void CEchoExtension::BadSyntax(CHttpServerContext* pCtxt)
  193. {
  194.     *pCtxt << "<H3>Bad Syntax Error!</H3><P>";
  195.     *pCtxt << "You have called the Echo ISAPI application without supplying "
  196.            << "the proper argument. You must specify a method and a single" 
  197.            << " argument.";
  198.     EchoHelp(pCtxt);
  199. }
  200.  
  201. void CEchoExtension::EchoHelp(CHttpServerContext* pCtxt)
  202. {
  203.     *pCtxt << "<P><I>Supported method:</I>";
  204.     *pCtxt << "<BR><B><TT>EchoRequest</TT></B> - currently the only method supported."
  205.            << " Dynamically creates an HTML page containing HTTP request information.";
  206.     *pCtxt << "<P><I>Supported arguments:</I>";
  207.     *pCtxt << "<BR><B><TT>Full</TT></B> - echo back the entire HTTP request message.";
  208.     *pCtxt << "<BR><B><TT>Body</TT></B> - echo back only the HTTP request message body.";
  209.     *pCtxt << "<BR><B><TT>Header</TT></B> - echo back only the HTTP request message head.";
  210.     *pCtxt << "<P>For example, if you have installed Echo.dll on the server \"WebSvr\"" 
  211.            << "then the following URL would display information on the HTTP request "
  212.            << "message header and body:";
  213.     *pCtxt << "<BR><B><TT>http://WebSvr/Scripts/Echo.dll?EchoRequest&Full</TT></B>";
  214. }
  215.