home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / source / chap15 / lst15_01 / lst15_01.cpp next >
Encoding:
C/C++ Source or Header  |  1996-11-19  |  6.3 KB  |  258 lines

  1. // LST15_01.CPP - Implementation file for your Internet Server
  2. //    lst15_01 Filter
  3.  
  4. #include <afx.h>
  5. #include <afxwin.h>
  6. #include <afxisapi.h>
  7. #include "resource.h"
  8. #include "lst17_01.h"
  9.  
  10.  
  11. ///////////////////////////////////////////////////////////////////////
  12. // The one and only CLst15_01Filter object
  13.  
  14. CLst15_01Filter theFilter;
  15. CWinApp BugFix;
  16.  
  17. ///////////////////////////////////////////////////////////////////////
  18. // CLst15_01Filter implementation
  19.  
  20. CLst15_01Filter::CLst15_01Filter()
  21. {
  22.     m_lpcsFlag=new CRITICAL_SECTION;
  23.     InitializeCriticalSection(m_lpcsFlag);
  24.  
  25.     // Hard Coded Datasource, login, and password
  26.     m_csDSN="TrafficLog";
  27.     m_csUser="sa";
  28.     m_csPassword="";
  29.  
  30.     Connect();
  31. }
  32.  
  33. CLst15_01Filter::~CLst15_01Filter()
  34. {
  35.     Disconnect();
  36.     
  37.     DeleteCriticalSection(m_lpcsFlag);
  38.     delete m_lpcsFlag;
  39. }
  40.  
  41. BOOL CLst15_01Filter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
  42. {
  43.     // Call default implementation for initialization
  44.     CHttpFilter::GetFilterVersion(pVer);
  45.  
  46.     // Clear the flags set by base class
  47.     pVer->dwFlags &= ~SF_NOTIFY_ORDER_MASK;
  48.  
  49.     // Set the flags we are interested in
  50.     pVer->dwFlags |= SF_NOTIFY_ORDER_LOW | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT
  51.              | SF_NOTIFY_SEND_RAW_DATA | SF_NOTIFY_END_OF_NET_SESSION;
  52.  
  53.     // Load description string
  54.     TCHAR sz[SF_MAX_FILTER_DESC_LEN+1];
  55.     ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
  56.             IDS_FILTER, sz, SF_MAX_FILTER_DESC_LEN));
  57.     _tcscpy(pVer->lpszFilterDesc, sz);
  58.     return TRUE;
  59. }
  60.  
  61. DWORD CLst15_01Filter::OnSendRawData(CHttpFilterContext* pCtxt,
  62.     PHTTP_FILTER_RAW_DATA pRawData)
  63. {
  64.     DWORD cbInData=pRawData->cbInData;
  65.     LPTSTR lpszURL;
  66.  
  67.     if (lpszURL=GetServerVariable(pCtxt,"URL"))
  68.     {
  69.         Log(lpszURL,cbInData);
  70.         delete lpszURL;
  71.     }
  72.  
  73.     // TODO: React to this notification accordingly and
  74.     // return the appropriate status code
  75.     return SF_STATUS_REQ_NEXT_NOTIFICATION;
  76. }
  77.  
  78. DWORD CLst15_01Filter::OnEndOfNetSession(CHttpFilterContext* pCtxt)
  79. {
  80.     // TODO: React to this notification accordingly and
  81.     // return the appropriate status code
  82.     return SF_STATUS_REQ_NEXT_NOTIFICATION;
  83. }
  84.  
  85. ///////////////////////////////////////////////////////////////////////
  86. // If your extension will not use MFC, you'll need this code to make
  87. // sure the extension objects can find the resource handle for the
  88. // module.  If you convert your extension to not be dependent on MFC,
  89. // remove the comments arounn the following AfxGetResourceHandle()
  90. // and DllMain() functions, as well as the g_hInstance global.
  91.  
  92. /****
  93.  
  94. static HINSTANCE g_hInstance;
  95.  
  96. HINSTANCE AFXISAPI AfxGetResourceHandle()
  97. {
  98.     return g_hInstance;
  99. }
  100.  
  101. BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason,
  102.                     LPVOID lpReserved)
  103. {
  104.     if (ulReason == DLL_PROCESS_ATTACH)
  105.     {
  106.         g_hInstance = hInst;
  107.     }
  108.  
  109.     return TRUE;
  110. }
  111.  
  112. ****/
  113.  
  114. void CLst15_01Filter::Connect()
  115. {
  116.     RETCODE rc;
  117.  
  118.     rc=SQLAllocEnv(&m_henv);
  119.     if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  120.             ODBCError(SQL_NULL_HSTMT);
  121.  
  122.     rc=SQLAllocConnect(m_henv, &m_hdbc);
  123.     if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  124.             ODBCError(SQL_NULL_HSTMT);
  125.  
  126.     rc=SQLConnect(m_hdbc, (UCHAR FAR *)(LPCTSTR) m_csDSN, SQL_NTS, (UCHAR FAR *)(LPCTSTR) m_csUser , m_csUser.GetLength(), (UCHAR FAR *)(LPCTSTR) m_csPassword, m_csPassword.GetLength());
  127.     if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  128.             ODBCError(SQL_NULL_HSTMT);
  129. };
  130.  
  131. void CLst15_01Filter::Disconnect()
  132. {
  133.     SQLDisconnect(m_hdbc);
  134.     SQLFreeConnect(m_hdbc);
  135.     SQLFreeEnv(m_henv);
  136. }
  137.  
  138. void CLst15_01Filter::ODBCError (HSTMT hstmt)
  139. {
  140.     UCHAR FAR szSqlState[5];
  141.     UCHAR FAR szErrorMsg[80];
  142.     SWORD cbErrorMsgMax=80;
  143.     SWORD FAR *pcbErrorMsg= new SWORD;
  144.     SDWORD FAR *pfNativeError= new SDWORD; 
  145.     RETCODE rc;
  146.  
  147.     rc=SQLError(m_henv, m_hdbc, hstmt, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
  148.     
  149.     if (!_tcscmp((char*)szSqlState,"08S01"))
  150.     {
  151.         // Bad Connection Let's try to recover!
  152.         ISAPITRACE("Bad Connection\n");
  153.         EnterCriticalSection(m_lpcsFlag);
  154.         Disconnect();
  155.          Connect();
  156.         LeaveCriticalSection(m_lpcsFlag);
  157.     }
  158.  
  159.     ISAPITRACE1("SQL Error: %s\n",szErrorMsg);
  160.  
  161.     delete pfNativeError;
  162.     delete pcbErrorMsg;
  163. };
  164.  
  165. HSTMT CLst15_01Filter::GetStatement()
  166. {
  167.     // The only reason that we are entering a critical section here
  168.     // is because the connection could be bad and we are trying to reconnect
  169.     // otherwise this isn't needed since ODBC is thread proof.
  170.     EnterCriticalSection(m_lpcsFlag);
  171.     HSTMT hstmt;
  172.      RETCODE rc;
  173.  
  174.     rc=SQLAllocStmt(m_hdbc, &hstmt);
  175.     if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  176.     {
  177.         // Bad Connection Let's try to recover!
  178.         // The CriticalSection Prevents other threads
  179.         // From trying to get a statement with a bad connection
  180.         ISAPITRACE("Bad Connection\n");
  181.         EnterCriticalSection(m_lpcsFlag);
  182.         Disconnect();
  183.          Connect();
  184.         LeaveCriticalSection(m_lpcsFlag);
  185.  
  186.         //Try Again
  187.         rc=SQLAllocStmt(m_hdbc, &hstmt);
  188.         if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  189.         {
  190.             // Only try to reconnect once
  191.             // Otherwise it is beyond our control
  192.             return(NULL);
  193.         }
  194.     }
  195.  
  196.     LeaveCriticalSection(m_lpcsFlag);
  197.  
  198.     return(hstmt);
  199. }
  200.  
  201. void CLst15_01Filter::FreeStatement(HSTMT hstmt)
  202. {
  203.     SQLFreeStmt(hstmt, SQL_DROP);
  204. };
  205.  
  206. // The Caller must delete the memory, unless error in which case returns NULL
  207. LPTSTR CLst15_01Filter::GetServerVariable(CHttpFilterContext* pCtxt, LPCTSTR pszVariableName)
  208. {
  209.     LPVOID lpvBuffer=NULL;
  210.     DWORD dwSize=0;
  211.  
  212.     pCtxt->GetServerVariable((LPTSTR)pszVariableName,NULL,(LPDWORD)&dwSize);
  213.  
  214.     // Check to see if variable exists
  215.     if(dwSize==0)
  216.         return(NULL);
  217.  
  218.     lpvBuffer=(LPVOID)new TCHAR[dwSize+1];
  219.  
  220.     if (!(pCtxt->GetServerVariable((LPTSTR)pszVariableName,lpvBuffer,(LPDWORD)&dwSize)))
  221.     {
  222.          delete lpvBuffer;
  223.         return(NULL);
  224.     }
  225.  
  226.     if(dwSize==0)
  227.     {
  228.          delete lpvBuffer;
  229.         return(NULL);
  230.     }
  231.  
  232.     return((LPTSTR)lpvBuffer);
  233. };
  234.  
  235. void CLst15_01Filter::Log(LPCTSTR lpszURL, DWORD dwSize)
  236. {
  237.     HSTMT hstmt;
  238.     RETCODE rc;
  239.      CString SQLScript;
  240.  
  241.     if((hstmt=GetStatement())==NULL)
  242.     {
  243.         return;
  244.     }
  245.  
  246.     SQLScript.Format("INSERT TrafficLog (TrafficLog_Size,TrafficLog_URL) VALUES (%d,'%s')",dwSize,lpszURL);
  247.  
  248.     rc=SQLExecDirect(hstmt, (UCHAR FAR *) (LPCTSTR) SQLScript, SQL_NTS);
  249.     if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  250.     {
  251.         ODBCError(hstmt);
  252.         goto End;
  253.     }
  254.     
  255. End:
  256.     FreeStatement(hstmt);
  257.     return;
  258. }