SERWEVW.CPP
上传用户:areilwang
上传日期:2007-01-04
资源大小:375k
文件大小:28k
源码类别:

Web服务器

开发平台:

WINDOWS

  1. // serwevw.cpp : implementation of the CSerwebView class
  2. //
  3. #include "stdafx.h"
  4. #include "serweb.h"
  5. #include "serwedoc.h"
  6. #include "serwevw.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char BASED_CODE THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CSerwebView
  13. IMPLEMENT_DYNCREATE(CSerwebView, CScrollView)
  14. BEGIN_MESSAGE_MAP(CSerwebView, CScrollView)
  15. //{{AFX_MSG_MAP(CSerwebView)
  16.   ON_MESSAGE(CLIENT_MSG, OnWWWClientMsg) 
  17.      ON_MESSAGE(INCOMING_MSG, OnWWWServerMsg) 
  18. ON_COMMAND(ID_PERIOD_OK, OnPeriodOk)
  19. ON_COMMAND(ID_SERVER_INACT, OnServerInact)
  20. ON_COMMAND(ID_UPDATE_STAT, OnUpdateStat)
  21. ON_WM_TIMER()
  22. //}}AFX_MSG_MAP
  23. END_MESSAGE_MAP()
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CSerwebView construction/destruction
  26. CSerwebView::CSerwebView()
  27. {
  28. // TODO: add construction code here
  29. }
  30. CSerwebView::~CSerwebView()
  31. {
  32.   int Loop;
  33.     // Close the listening server first ....                      
  34.     if (WWWServer != INVALID_SOCKET)
  35.       if (closesocket(WWWServer) == SOCKET_ERROR)
  36.         {
  37.            sprintf(buf, "Windows Socket error %d:  Couldn't close the server socket.", WSAGetLastError());
  38.        MessageBox( buf,  AfxGetAppName(), MB_OK);
  39.         }
  40.                                             
  41.     // Close any outstanding connections .....                                        
  42.     for (Loop = 0; Loop < HowManyClients; Loop++)
  43.        if (WWWConv[Loop].State != SOCK_FREE)
  44.          if (closesocket(WWWConv[Loop].CliSock) == SOCKET_ERROR)
  45.            {
  46.               sprintf(buf, "Windows Socket error %d:  Couldn't close a client socket.", WSAGetLastError());
  47.           MessageBox( buf,  AfxGetAppName(), MB_OK);
  48.            } 
  49.            
  50.     // Kill the timer ...
  51.     KillTimer(IdEv);
  52.     
  53. }    
  54. //////////////////////////////////////////////////////////////////////////////
  55. void CSerwebView::OnInitialUpdate()
  56. {                           
  57.     int err, Loop;
  58.     CClientDC dc(this);
  59.     TEXTMETRIC tm;
  60.     CRect MyWin;
  61.  
  62.   CWnd* pParent = GetParent();
  63.   CMenu* pMenu = pParent->GetMenu();                   
  64.        
  65.     // ************ Set the proper options here ......
  66.     
  67.     WWWPort = AfxGetApp()->GetProfileInt("SERWEB", "PortNumber",80);
  68.     HowManyClients = AfxGetApp()->GetProfileInt("SERWEB", "HowManyClients",5);
  69.     if (HowManyClients > MAX_CLIENTS)     // Can't have more than we have storage for .....
  70.       {
  71.          HowManyClients = MAX_CLIENTS;
  72.          PrintSt("  Requested more than 10 clients.  Resetting to 10.n");
  73.       }
  74.     if (AfxGetApp()->GetProfileInt("SERWEB", "ClosedServer",0) == 1)
  75.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_CHECKED);
  76.     else
  77.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_UNCHECKED);
  78.     if (AfxGetApp()->GetProfileInt("SERWEB", "PeriodAllowed",1) == 0)
  79.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_CHECKED);
  80.     else
  81.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_UNCHECKED);
  82.     if (AfxGetApp()->GetProfileInt("SERWEB", "PrintOut",1) == 1)
  83.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_CHECKED);
  84.     else
  85.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_UNCHECKED);
  86.     SendDir          = AfxGetApp()->GetProfileString("SERWEB", "SendDir","C:\SERWEB");
  87.     FileNotExistMsg  = AfxGetApp()->GetProfileString("SERWEB", "FileNotExistMsg","C:\SERWEB\nofile.htm");
  88.     ClosedServerMsg  = AfxGetApp()->GetProfileString("SERWEB", "ClosedServerMsg","C:\SERWEB\closed.htm");
  89.     PeriodAllowedMsg = AfxGetApp()->GetProfileString("SERWEB", "PeriodAllowedMsg","C:\SERWEB\period.htm");
  90.     // SIze the frame window to a normal size and set the scrollers ....
  91.     
  92.     dc.GetTextMetrics(&tm);                        
  93.     SetScrollSizes( MM_TEXT, CSize(0,0), CSize(0,(MAX_LINES*tm.tmHeight)), CSize(0, tm.tmHeight)); 
  94.     
  95.     GetWindowRect( MyWin );
  96.     GetParentFrame()->MoveWindow( MyWin.left, MyWin.top, (COLUMN_MAX*tm.tmAveCharWidth), (24*tm.tmHeight), FALSE);
  97.     // Initialize WinSocket code here ......
  98.     
  99.     WWWServer = INVALID_SOCKET;              // The server is not connected yet ....
  100.      // and set all sockets structures to not used ....
  101.      for (Loop = 0; Loop < HowManyClients; Loop++)
  102.        WWWConv[Loop].State = SOCK_FREE;
  103.     PrintSt("n");
  104.     WWWServer = socket(AF_INET, SOCK_STREAM, 0);
  105.     if (WWWServer == INVALID_SOCKET)
  106.       {
  107.          sprintf(buf, "Windows Socket error %d:  Couldnot create server socket.", WSAGetLastError());
  108.          PrintSt("  Initialization incorrect nn  Please correct the problem and restart.n");
  109.      MessageBox( buf,  AfxGetAppName(), MB_OK);
  110.      return;   
  111.        }
  112.      
  113.     srv_addr.sin_family = AF_INET;
  114.     srv_addr.sin_addr.s_addr = INADDR_ANY;   
  115.     srv_addr.sin_port = htons(WWWPort);
  116.     
  117.     if (bind(WWWServer, (LPSOCKADDR)&srv_addr, sizeof(srv_addr)) == SOCKET_ERROR)
  118.        {
  119.          sprintf(buf, "Windows Socket error %d:  Couldn't bind the server socket.", WSAGetLastError());
  120.          PrintSt("  Initialization incorrect nn  Please correct the problem and restart.n");
  121.      MessageBox( buf,  AfxGetAppName(), MB_OK);
  122.      return;   
  123.        }
  124.          
  125.       err = WSAAsyncSelect(WWWServer, m_hWnd, INCOMING_MSG, FD_ACCEPT);
  126.       if (err == SOCKET_ERROR) 
  127.        {
  128.          sprintf(buf, "Windows Socket error %d:  WSAAsyncSelect code did not work for the server.", WSAGetLastError());
  129.          PrintSt("  Initialization incorrect nn  Please correct the problem and restart.n");
  130.      MessageBox( buf,  AfxGetAppName(), MB_OK);
  131.      return;   
  132.        }
  133.     if (listen(WWWServer,2) == SOCKET_ERROR)
  134.       {
  135.          sprintf(buf, "Windows Socket error %d:  Couldn't setup the server to listen for clients.", WSAGetLastError());
  136.          PrintSt("  Initialization incorrect nn  Please correct the problem and restart.n");
  137.      MessageBox( buf,  AfxGetAppName(), MB_OK);
  138.      return;   
  139.        }
  140.      
  141.      
  142.      PrintSt("  Initialization was OK n  Waiting for connectionsn");  
  143.      SetTimer(IdEv, TIME_TO_CHECK, NULL);
  144. return;
  145. }
  146. /////////////////////////////////////////////////////////////////////////////
  147. // CSerwebView drawing
  148. void CSerwebView::OnDraw(CDC* pDC)
  149. {
  150. CSerwebDoc* pDoc = GetDocument();
  151.     TEXTMETRIC tm;
  152.     int yval;
  153.     CSize PositionHold;
  154.     
  155.     pDC->GetTextMetrics(&tm);
  156.     yval = 0;
  157.     for (int loop_index = 0; loop_index <= pDoc->line_number; loop_index++)
  158.       {
  159.         pDC->TextOut(0,yval,pDoc->data_string[loop_index], pDoc->data_string[loop_index].GetLength());
  160.         yval += tm.tmHeight;
  161.       }
  162.      
  163. /*     // Display cursor    ..........
  164.      PositionHold = pDC->GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  165.      pDC->BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  166. */
  167.      SetScrollSizes( MM_TEXT, CSize(0, ((int) pDoc->line_number+1) * tm.tmHeight));
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. // CSerwebView diagnostics
  171. #ifdef _DEBUG
  172. void CSerwebView::AssertValid() const
  173. {
  174. CView::AssertValid();
  175. }
  176. void CSerwebView::Dump(CDumpContext& dc) const
  177. {
  178. CView::Dump(dc);
  179. }
  180. CSerwebDoc* CSerwebView::GetDocument() // non-debug version is inline
  181. {
  182. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSerwebDoc)));
  183. return (CSerwebDoc*) m_pDocument;
  184. }
  185. #endif //_DEBUG
  186. /////////////////////////////////////////////////////////////////////////////
  187. // CSerwebView message handlers
  188.  
  189. void CSerwebView::PrintChar(char nChar, char OutputIt)
  190. {
  191.   CSerwebDoc* pDoc = GetDocument();                 
  192.   CClientDC dc(this);
  193.   TEXTMETRIC tm;
  194.   CPoint Position, Origin;
  195.   CSize PositionHold;
  196.   CRect MyWindowSize;
  197.   CWnd* pParent = GetParent();
  198.   CMenu* pMenu = pParent->GetMenu();                   
  199.        
  200.    // No need to update the stuff .............................
  201.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  202.      return;
  203.      
  204.   OnPrepareDC(&dc);       
  205.   dc.GetTextMetrics(&tm);                        
  206. /*  if (OutputIt != 'n')
  207.    {
  208.      PositionHold = dc.GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  209.      dc.BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  210.    }                                                                 
  211. */
  212.   if (nChar =='n')
  213.     {  
  214.       pDoc->column_number = 0;          // we are on the left now
  215.       if (pDoc->line_number == (MAX_LINES-1))
  216.         {
  217.           for (int loop_index=0; loop_index < MAX_LINES; loop_index++)
  218.             {
  219.               pDoc->data_string[loop_index] = pDoc->data_string[loop_index+1];
  220.             }
  221.           pDoc->data_string[loop_index].Empty;
  222.           pDoc->UpdateAllViews(this, 0L, 0);
  223.         }
  224.       else
  225.         pDoc->line_number++;
  226.       SetScrollSizes( MM_TEXT, CSize(0, ((int) pDoc->line_number+1) * tm.tmHeight));
  227.     }
  228.   else
  229.     {
  230.       if (pDoc->column_number++ >= COLUMN_MAX)
  231.         {
  232.            pDoc->column_number = 1;
  233.            if (pDoc->line_number == (MAX_LINES-1))
  234.              {
  235.                for (int loop_index=0; loop_index < MAX_LINES; loop_index++)
  236.                  {
  237.                     pDoc->data_string[loop_index] = pDoc->data_string[loop_index+1];
  238.                  }
  239.                pDoc->data_string[loop_index].Empty;
  240.                pDoc->UpdateAllViews(this, 0L, 0);
  241.              }
  242.            else
  243.              pDoc->line_number++;
  244.         }   
  245.       pDoc->data_string[pDoc->line_number] += nChar;
  246.       if (OutputIt != 'n')
  247.         dc.TextOut(0, (int) pDoc->line_number * tm.tmHeight,
  248.                    pDoc->data_string[pDoc->line_number],
  249.                    pDoc->data_string[pDoc->line_number].GetLength());
  250.                    
  251.     }                             
  252.     
  253.   // Scroll so user can see the line just outputted ...........
  254.   
  255.   if (OutputIt != 'n')
  256.    {
  257.     Position = GetScrollPosition(); 
  258.     if ((int) pDoc->line_number * tm.tmHeight < Position.y)
  259.       {
  260.         Position.y = (int) pDoc->line_number * tm.tmHeight;
  261.         ScrollToPosition( Position );
  262.       }
  263.     else
  264.       {
  265.         CScrollView::GetClientRect( MyWindowSize);                            
  266.         if ( (( (int) pDoc->line_number * tm.tmHeight) + tm.tmHeight) > MyWindowSize.bottom)
  267.           {                
  268.             Origin = dc.GetViewportOrg();  
  269.             Position.x = Origin.x;
  270.             Position.y = ((int) pDoc->line_number * tm.tmHeight) + tm.tmHeight - MyWindowSize.bottom;
  271.             ScrollToPosition( Position );
  272.            }
  273.         }    
  274. /*      // Draw the cursor now ....
  275.       PositionHold = dc.GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  276.       dc.BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  277. */    }
  278.     
  279. }
  280.                                                         
  281. ////////////////////////////////////////////////////////////////////////////////////////
  282. void CSerwebView::PrintSt( CString StToPrint)
  283. {
  284.   CSerwebDoc* pDoc = GetDocument();                 
  285.  
  286.   int Loop=0;  
  287.   CWnd* pParent = GetParent();
  288.   CMenu* pMenu = pParent->GetMenu();                   
  289.        
  290.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  291.      return;
  292.      
  293.    
  294.    if (StToPrint.GetLength() == 0)
  295.      return;
  296.    for ( Loop = 0; Loop < (StToPrint.GetLength()-1); Loop++)
  297.       PrintChar( StToPrint[Loop], 'n');
  298.    PrintChar( StToPrint[Loop], 'y');
  299.    pDoc->UpdateAllViews(NULL, 0L, 0);
  300. }
  301. void CSerwebView::PrintSt( char* AString)
  302. {
  303.   CSerwebDoc* pDoc = GetDocument();                 
  304.  
  305.   int Loop;  
  306.   CWnd* pParent = GetParent();
  307.   CMenu* pMenu = pParent->GetMenu();                   
  308.        
  309.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  310.      return;
  311.      
  312.    if (AString == NULL)
  313.      return;
  314.    for ( Loop = 0; AString[Loop+1] != NULL; Loop++)
  315.       PrintChar( AString[Loop], 'n');
  316.    PrintChar( AString[Loop], 'y');
  317.    pDoc->UpdateAllViews(NULL, 0L, 0);
  318. }
  319. ////////////////////////////////////////////////////////////////////////////////////////
  320. void CSerwebView::OnUpdate(CView*, LPARAM, CObject*)
  321. {                                              
  322.   Invalidate();
  323. }
  324.                                                         
  325. ////////////////////////////////////////////////////////////////////////////////////////
  326. void CSerwebView::KillConn(int SockNumber)
  327. {             
  328.    
  329.    WWWConv[SockNumber].State = SOCK_FREE; 
  330.    closesocket( WWWConv[SockNumber].CliSock );
  331.    if (WWWConv[SockNumber].SendFile.m_hFile != (UINT)CFile::hFileNull)
  332.       WWWConv[SockNumber].SendFile.Close();            // If there are problems, just ignore <-- Is this OK?
  333.    PrintSt("  Connection closed.n");
  334. }
  335. ////////////////////////////////////////////////////////////////////////////////////////
  336. void CSerwebView::SendBlockOfData(int SockNumber)
  337. {           
  338.    int err;                                   
  339.   
  340.    while (1==1)
  341.     {
  342.       if (WWWConv[SockNumber].HowManyInSendBuf == 0)
  343.         {
  344.           WWWConv[SockNumber].HowManyInSendBuf = WWWConv[SockNumber].SendFile.Read(WWWConv[SockNumber].SendBuf, SEND_BUF_LEN);
  345.           WWWConv[SockNumber].OffsetToSend = 0;
  346.         } 
  347.         
  348.                 
  349.      WWWConv[SockNumber].LastTime = CTime::GetCurrentTime();        // Update time of last action ..
  350.       if (WWWConv[SockNumber].HowManyInSendBuf == 0)                                  // Lets guess that this is EOF for now.
  351.         {
  352.            PrintSt("  File sent OK -Terminating connectionn");
  353.            KillConn( SockNumber);
  354.            return;                                    // <--- ONE of 3 ways to get out
  355.         }          
  356.       else
  357.         {
  358.           err = send( WWWConv[SockNumber].CliSock, WWWConv[SockNumber].SendBuf+WWWConv[SockNumber].OffsetToSend, WWWConv[SockNumber].HowManyInSendBuf,0);    
  359.              
  360.           if (err == SOCKET_ERROR)
  361.             {                    
  362.               if (WSAGetLastError() == WSAEWOULDBLOCK)
  363.                 {         
  364.                    #ifdef _DEBUG
  365.                      PrintSt("  *** Can't send all of the data at once - Pausing nown");
  366.                    #endif
  367.                    return;                            // <--- second way to get out ..
  368.                 } 
  369.               else
  370.                {         
  371.                
  372.                   PrintSt("  *** Error while sending to the client some data.n");
  373.                   KillConn( SockNumber );
  374.                   return;                                    // <--- last of 3 ways to get out
  375.                 }
  376.              }
  377.           if (err != WWWConv[SockNumber].HowManyInSendBuf)
  378.             {
  379.               #ifdef _DEBUG
  380.                  PrintSt("  Did not send all datan");
  381.               #endif
  382.               WWWConv[SockNumber].OffsetToSend = WWWConv[SockNumber].OffsetToSend + err;
  383.               WWWConv[SockNumber].HowManyInSendBuf = WWWConv[SockNumber].HowManyInSendBuf - err;
  384.             }
  385.            else
  386.              {
  387.                WWWConv[SockNumber].HowManyInSendBuf = 0;     // So we can get more data..
  388.                WWWConv[SockNumber].OffsetToSend = 0;         // Not needed (TRACE IT AND SEE WHY) but JIC (Just In Case)
  389.              }
  390.         }
  391.      }
  392. }    
  393.                                                         
  394. ////////////////////////////////////////////////////////////////////////////////////////
  395. CString CSerwebView::GetFirstString(CString TheString, int WrdToGet)
  396. {
  397.    int Count, StPos,EndPos;
  398.    
  399.    if (TheString.GetLength() == 0)
  400.      return CString("");
  401.    EndPos = -1;                // Just follow the logic.  TRUST ME !
  402.    Count = 0;
  403.    while (Count < WrdToGet)
  404.    {  
  405.      StPos=EndPos+1;
  406.      while ((StPos < TheString.GetLength()) && ((TheString[StPos]==' ') ||(TheString[StPos]=='t'))) 
  407.        StPos++;
  408.      if (StPos == TheString.GetLength())
  409.        return CString("");
  410.      EndPos = StPos;
  411.      while ((EndPos < TheString.GetLength()) && (TheString[EndPos]!=' ') && (TheString[EndPos]!='t')) 
  412.        EndPos++;
  413.      Count++;
  414.     }
  415.    return TheString.Mid(StPos, (EndPos-StPos));
  416. }
  417. ////////////////////////////////////////////////////////////////////////////////////////
  418. void CSerwebView::ProcessRequest(int SockNumber)
  419. {
  420.    CString Testing;
  421.    int Count = 1, Loop, err;
  422.    CWnd* pParent = GetParent();
  423.    CMenu* pMenu = pParent->GetMenu();                   
  424.                       
  425.    // Get the first word ......
  426.    
  427.    Testing = GetFirstString( WWWConv[SockNumber].InBuf, 1);
  428.    
  429.    if ( Testing.CompareNoCase("GET") == 0)
  430.      {
  431.        Testing = GetFirstString( WWWConv[SockNumber].InBuf, 2);
  432.        // Lets ensure the slash is OK for DOS  - Just in case
  433.        for (Loop = 0; Loop < Testing.GetLength(); Loop++)
  434.          if (Testing[Loop] == '/')
  435.             Testing.SetAt(Loop,'\');
  436.        
  437.        if (Testing[0] != '\')
  438.          Testing = SendDir + CString("\")+ Testing;
  439.        else
  440.          Testing = SendDir + Testing;
  441.        // See if we are closed and send a message.
  442.        if (pMenu->GetMenuState(ID_SERVER_INACT, MF_BYCOMMAND) == MF_CHECKED) 
  443.          { 
  444.            PrintSt("  Telling client server is off.n");
  445.            Testing = ClosedServerMsg;
  446.           }
  447.           
  448.        // They want a file with .. - check to see if we allow ?
  449.        if (pMenu->GetMenuState(ID_PERIOD_OK, MF_BYCOMMAND) == MF_UNCHECKED)
  450.          if (Testing.Find("..") > -1)              // Found them ....
  451.            {  
  452.              PrintSt("  Telling server we do not allow .. on the URI.n");
  453.              Testing = PeriodAllowedMsg;
  454.            }
  455.         PrintSt("  Trying to send file - ");
  456.         PrintSt(Testing);
  457.         PrintSt("n");
  458.        
  459.        // Lets try to open the file now ......
  460.        if (!WWWConv[SockNumber].SendFile.Open(Testing, CFile::modeRead | CFile::typeBinary))
  461.          {
  462.              // We could not send the file ......
  463.              PrintSt("  File does not exist - Sending Messagen");
  464.              if (!WWWConv[SockNumber].SendFile.Open(FileNotExistMsg, CFile::modeRead | CFile::typeBinary))
  465.                 {
  466.                    // DAMM, That file dows not exist either ...
  467.                    err = send( WWWConv[SockNumber].CliSock, "HTTP/1.0 404 The file requested was not foundn",46,0);    
  468.                    if (err == SOCKET_ERROR)
  469.                       PrintSt("  Error while sending to the client the 404 msg.n");
  470.                    #ifdef _DEBUG
  471.                      PrintSt("  *** Socket will be closed now ....n");
  472.                    #endif
  473.                    
  474.                    KillConn( SockNumber );  
  475.                  }
  476.                else
  477.                  {
  478.                     WWWConv[SockNumber].HowManyInSendBuf = 0;               // We have not sent any chars ....
  479.                     SendBlockOfData(SockNumber);
  480.                  }
  481.           }
  482.        else    
  483.         {           
  484.           WWWConv[SockNumber].HowManyInSendBuf = 0;               // We have not sent any chars ....
  485.           SendBlockOfData(SockNumber);
  486.          }
  487.       }
  488.   else
  489.     {
  490.        PrintSt("  Unrecognized method: ");
  491.        PrintSt(WWWConv[SockNumber].InBuf);
  492.        PrintSt("n");
  493.        
  494.        err = send( WWWConv[SockNumber].CliSock, "HTTP/1.0 599 Unrecognized method requestn",41,0);    
  495.        if (err == SOCKET_ERROR)
  496.           PrintSt("  Error while sending to the client the 599 msg.n");
  497.        
  498.        #ifdef _DEBUG
  499.          PrintSt("  *** Socket will be closed now ....n");
  500.        #endif
  501.         
  502.        KillConn( SockNumber ); 
  503.      }
  504. }
  505. ////////////////////////////////////////////////////////////////////////////////////////
  506. void CSerwebView::ProcessRead(int SockNumber)
  507. {
  508.  int err, RdLoop;
  509.  u_long ulBytesToRead = 0L;
  510.  char Buf[200];
  511.    
  512.    if (WWWConv[SockNumber].State != WAITING)
  513.      {    
  514.        #ifdef _DEBUG
  515.           PrintSt("  *** The socket is trying to send information while we are in send mode. n");
  516.        #endif
  517.        return;
  518.       }       
  519.    #ifdef _DEBUG   
  520.       PrintSt("  *** I am able read from the client now n");
  521.    #endif
  522.           
  523.    ioctlsocket( WWWConv[SockNumber].CliSock, FIONREAD, &ulBytesToRead);
  524.           
  525.    while ((ulBytesToRead > 0L) && (WWWConv[SockNumber].State == WAITING))
  526.       {
  527.          // Just in case a nut desides to crash the thing ....
  528.          if (ulBytesToRead > 199)
  529.            ulBytesToRead = 200;                               
  530.           
  531.          err = recv( WWWConv[SockNumber].CliSock, Buf, (int) ulBytesToRead, 0);
  532.     
  533.          if (err == SOCKET_ERROR)
  534.                 {
  535.                    PrintSt("  An error ocurred when reading from the client n");
  536.                    return;
  537.                 }        
  538.               RdLoop = 0;
  539.               while (RdLoop < err)
  540.                 if ((Buf[RdLoop] == 'n') ||(Buf[RdLoop] == 'r') ||(Buf[RdLoop] == 0x0D) || (Buf[RdLoop] == 0x0A))
  541.                   {                                
  542.                     WWWConv[SockNumber].State = SENDING;
  543.                     break;
  544.                   }
  545.                 else            
  546.                   {
  547.                      WWWConv[SockNumber].InBuf += Buf[RdLoop]; 
  548.                      RdLoop++;
  549.                   }
  550.               ioctlsocket( WWWConv[SockNumber].CliSock, FIONREAD, &ulBytesToRead);
  551.             }
  552.            
  553.         // If we received the request, lets address it .....
  554.           
  555.            #ifdef _DEBUG
  556.               PrintSt("  *** Got the following so far ->");
  557.               PrintSt(WWWConv[SockNumber].InBuf);
  558.               PrintSt("<---n");
  559.            #endif
  560.            
  561.            if (WWWConv[SockNumber].State == SENDING)
  562.               {
  563.                 ProcessRequest(SockNumber);
  564.               } 
  565. }
  566. ////////////////////////////////////////////////////////////////////////////////////////
  567. LRESULT CSerwebView::OnWWWClientMsg(WPARAM wParam, LPARAM lParam)
  568. {
  569. // int err, Loop, RdLoop;
  570.  int Loop;
  571.  u_long ulBytesToRead = 0L;
  572. // char Buf[200];
  573.  
  574.  
  575.  if (WSAGETSELECTERROR(lParam) == 00)
  576.    {
  577.     // Lets get the socket that cried for help .....
  578.     
  579.      for (Loop = 0; Loop < HowManyClients; Loop++)
  580.          if (WWWConv[Loop].CliSock == (SOCKET) wParam)
  581.              break;
  582.     // Just in case .....
  583.      if (Loop == HowManyClients)
  584.        {  
  585.           #ifdef _DEBUG
  586.              PrintSt("  *** A socket has cried but is not ours ????n");
  587.           #endif
  588.           return 0L;
  589.        }
  590.      if (WWWConv[Loop].State == SOCK_FREE)
  591.        {  
  592.           #ifdef _DEBUG
  593.              PrintSt("  *** A socket has cried but it is closed ????n");
  594.           #endif
  595.           return 0L;
  596.        }
  597.      
  598.      WWWConv[ Loop ].LastTime = CTime::GetCurrentTime();        // Update time of last action ..
  599.      if (WSAGETSELECTEVENT(lParam) == FD_READ)
  600.        {                                       
  601.          ProcessRead( Loop );
  602.          return 0L;     
  603.             
  604.        }
  605.      if (WSAGETSELECTEVENT(lParam) == FD_WRITE)
  606.        {      
  607.           #ifdef _DEBUG                                 
  608.              PrintSt("  *** I am able to write to the client now.n");
  609.           #endif
  610.           if (WWWConv[Loop].State == SENDING)
  611.             {
  612.               SendBlockOfData(Loop);
  613.             }
  614.           return 0L;
  615.        }
  616.      if (WSAGETSELECTEVENT(lParam) == FD_CLOSE)
  617.        {
  618.           PrintSt("  Connection terminated by client.n");
  619.           KillConn( Loop );
  620.           
  621.       return 0L;   
  622.        }
  623.    }                           
  624.  
  625.  return 0L;
  626. }
  627. ////////////////////////////////////////////////////////////////////////////////////////
  628. LRESULT CSerwebView::OnWWWServerMsg(WPARAM wParam, LPARAM lParam)
  629. {
  630.  WORD err;
  631.  int Loop;                        
  632.  SOCKADDR sad;      // Accept socket variables ......
  633.  int len = sizeof(sad);
  634.  SOCKET TempSock;                       
  635.  CFile  QFile;
  636.  
  637.  if (WSAGETSELECTERROR(lParam) == 0)
  638.    {
  639.      if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT)
  640.        {
  641.           PrintSt("  Connection has arrivedn");
  642.           for (Loop = 0; Loop < HowManyClients; Loop++)
  643.              if (WWWConv[Loop].State == SOCK_FREE)
  644.                break;
  645.           if (Loop == HowManyClients)
  646.             {
  647.               PrintSt("  Maximun number of incoming connections reached.n  Notifying request to try on a few seconds.n");
  648.               
  649.               TempSock = accept(WWWServer, &sad, &len);
  650.               if (TempSock == INVALID_SOCKET)
  651.                 {
  652.                   PrintSt("  Could not accept the temporary socket.n");
  653.                   return 0L;
  654.                 }
  655.               WSAAsyncSelect(TempSock, m_hWnd, 0, 0);       // Lets go raw !!! & pray (????)
  656.               err = send( TempSock, "HTTP/1.0 400 Unable to satisfy request now - TRY IN A FEW SECONDS !!!n",69,0);    
  657.               if (err == SOCKET_ERROR)
  658.                 PrintSt("  Error while sending notice to temporary socket.n");
  659.               closesocket( TempSock );
  660.              
  661.               return 0L;          // Get out ....
  662.             }
  663.            WWWConv[Loop].InBuf = "";
  664.           WWWConv[Loop].State = WAITING;
  665.           WWWConv[Loop].CliSock = accept(WWWServer, &sad, &len);
  666.           if (WWWConv[Loop].CliSock == INVALID_SOCKET)
  667.              {
  668.                PrintSt("  Could not accept the incoming connection.n");
  669.                WWWConv[Loop].State = SOCK_FREE;
  670.                return 0L;
  671.              }
  672.           err = WSAAsyncSelect(WWWConv[Loop].CliSock, m_hWnd, CLIENT_MSG, FD_READ | FD_WRITE | FD_CLOSE);
  673.           if (err == SOCKET_ERROR) 
  674.              {
  675.                sprintf(buf, "  Windows Socket error %d:  WSAAsyncSelect code did not work while accepting connectionn", WSAGetLastError());
  676.                PrintSt(buf); 
  677.                KillConn( Loop );
  678.                return 0L;
  679.              } 
  680.           
  681.           //  Important ..   
  682.           ProcessRead(Loop);         // <---- WHY IS THIS NEEDED ???? SOME TIMES I DON'T RECEIVE FD_READ MSG (GUS)
  683.           
  684.           #ifdef _DEBUG
  685.              PrintSt("  *** Waiting for input from the client now.n");
  686.           #endif
  687.          
  688.          
  689.          }  
  690.     }
  691.  
  692.  return 0L;
  693. }
  694. // Menu updates below .................................................
  695. void CSerwebView::OnPeriodOk()
  696. {
  697.   CWnd* pParent = GetParent();
  698.   CMenu* pMenu = pParent->GetMenu();                   
  699.        
  700.    if (pMenu->GetMenuState(ID_PERIOD_OK, MF_BYCOMMAND) == MF_UNCHECKED) 
  701.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_CHECKED);
  702.    else
  703.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_UNCHECKED);
  704. }
  705. void CSerwebView::OnServerInact()
  706. {
  707.   CWnd* pParent = GetParent();
  708.   CMenu* pMenu = pParent->GetMenu();                   
  709.        
  710.    if (pMenu->GetMenuState(ID_SERVER_INACT, MF_BYCOMMAND) == MF_UNCHECKED) 
  711.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_CHECKED);
  712.    else
  713.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_UNCHECKED);
  714. }
  715. void CSerwebView::OnUpdateStat()
  716. {
  717.   CWnd* pParent = GetParent();
  718.   CMenu* pMenu = pParent->GetMenu();                   
  719.        
  720.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  721.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_CHECKED);
  722.    else
  723.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_UNCHECKED);
  724. }
  725. ///////////////////////////////////////////////////////////////////////////////////////
  726. void CSerwebView::OnTimer(UINT nIDEvent)
  727. {
  728.   int Loop; 
  729.   CTimeSpan TimeDiff; 
  730.   CTime     TheTimeNow;
  731.     
  732.     #ifdef _DEBUG
  733.       PrintSt("  *** Servicing the timer nown");
  734.     #endif
  735.     for (Loop = 0; Loop < HowManyClients; Loop++) 
  736.       {
  737.        if (WWWConv[Loop].State != SOCK_FREE)
  738.          {
  739.             TimeDiff = CTime::GetCurrentTime() - WWWConv[Loop].LastTime;
  740.             #ifdef _DEBUG
  741.                afxDump << "Time now - " << TheTimeNow << " Lats time - " << WWWConv[Loop].LastTime << " Time diff - " << TimeDiff.GetTotalMinutes() << "n";
  742.             #endif
  743.             if ((int) TimeDiff.GetTotalMinutes() > INACTIVE)
  744.               {
  745.                  PrintSt("  Connections has not responded for the last 3 minutes.n");
  746.                  KillConn( Loop );                                                    
  747.               }
  748.          }
  749.       } 
  750. }