HTTPDOC.CPP
上传用户:btxinjin
上传日期:2007-01-04
资源大小:83k
文件大小:8k
源码类别:

Web服务器

开发平台:

Visual C++

  1. // HttpDoc.cpp : implementation of the CHttpSvrDoc class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1997-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "HttpSvr.h"
  14. #include "HttpDoc.h"
  15. #include "Request.h"
  16. #include "GenPage.h"
  17. #include "NamePage.h"
  18. #include "RootPage.h"
  19. #include "Listen.h"
  20. #include "mainfrm.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CHttpSvrDoc
  28. IMPLEMENT_DYNCREATE(CHttpSvrDoc, CDocument)
  29. BEGIN_MESSAGE_MAP(CHttpSvrDoc, CDocument)
  30. //{{AFX_MSG_MAP(CHttpSvrDoc)
  31. ON_COMMAND(IDM_SVR_OPTIONS, OnSvrOptions)
  32. ON_COMMAND(ID_FILE_RESTART, OnFileRestart)
  33. //}}AFX_MSG_MAP
  34. END_MESSAGE_MAP()
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CHttpSvrDoc construction/destruction
  37. CHttpSvrDoc::CHttpSvrDoc()
  38. {
  39. m_pListen = NULL;
  40. }
  41. CHttpSvrDoc::~CHttpSvrDoc()
  42. {
  43. // get rid of any lingering requests, JIC.....
  44. while ( !m_reqList.IsEmpty() )
  45. {
  46. CRequest* pRequest = (CRequest*)(m_reqList.RemoveTail());
  47. pRequest->Release();
  48. }
  49. }
  50. BOOL CHttpSvrDoc::OnNewDocument()
  51. {
  52. CDocument::OnNewDocument();
  53. // zero the hits counter....
  54. m_nTotalHits = 0;
  55. // assign default values....
  56. m_strServer = ((CHttpSvrApp*)AfxGetApp())->m_strDefSvr;
  57. m_uPort = PORT_HTTP;
  58. m_nSvrName = 0;
  59. m_bLoggingOn = TRUE;
  60. m_bAllowListing = TRUE;
  61. m_bListIcon = TRUE;
  62. // get the default root path....
  63. m_strRoot.LoadString( IDS_DEF_ROOT );
  64. m_strRoot = SEPCHAR + m_strRoot;
  65. // ensure no final separator character....
  66. if ( m_strRoot[m_strRoot.GetLength()-1] == SEPCHAR )
  67. m_strRoot = m_strRoot.Left( m_strRoot.GetLength()-1 );
  68. // make into a full path string....
  69. GetFullPathName( m_strRoot, MAX_PATH,
  70. m_strRoot.GetBuffer(MAX_PATH), NULL);
  71. m_strRoot.ReleaseBuffer();
  72. // see if we need to automatically disable the icons
  73. // in folder listings....
  74. CString strAdmin = m_strRoot + SEPCHAR + "SvrAdmin";
  75. DWORD dwAttr = GetFileAttributes( strAdmin );
  76. if ( dwAttr == (DWORD)(-1) || (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  77. m_bListIcon = FALSE; // don't allow icons
  78. StartListening();
  79. SetTitle( NULL );
  80. return TRUE;
  81. }
  82. BOOL CHttpSvrDoc::OnOpenDocument(LPCTSTR lpszPathName)
  83. {
  84. BOOL bOk = FALSE;
  85. if ( CDocument::OnOpenDocument(lpszPathName) )
  86. {
  87. if ( (bOk = StartListening()) == FALSE )
  88. SetModifiedFlag( TRUE );
  89. }
  90. return bOk;
  91. }
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CHttpSvrDoc serialization
  94. void CHttpSvrDoc::Serialize(CArchive& ar)
  95. {
  96. if (ar.IsStoring())
  97. {
  98. ar << m_strRoot;
  99. ar << m_strServer;
  100. ar << m_timeStarted;
  101. ar << m_uPort;
  102. ar << m_nSvrName;
  103. ar << m_bLoggingOn;
  104. ar << m_bListIcon;
  105. ar << m_bAllowListing;
  106. }
  107. else
  108. {
  109. ar >> m_strRoot;
  110. ar >> m_strServer;
  111. ar >> m_timeStarted;
  112. ar >> m_uPort;
  113. ar >> m_nSvrName;
  114. ar >> m_bLoggingOn;
  115. ar >> m_bListIcon;
  116. ar >> m_bAllowListing;
  117. if ( m_nSvrName == 0 )
  118. m_strServer = ((CHttpSvrApp*)AfxGetApp())->m_strDefSvr;
  119. }
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. // CHttpSvrDoc diagnostics
  123. #ifdef _DEBUG
  124. void CHttpSvrDoc::AssertValid() const
  125. {
  126. CDocument::AssertValid();
  127. }
  128. void CHttpSvrDoc::Dump(CDumpContext& dc) const
  129. {
  130. CDocument::Dump(dc);
  131. }
  132. #endif //_DEBUG
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CHttpSvrDoc commands
  135. void CHttpSvrDoc::DocHit( CRequest* pRequest )
  136. {
  137. // save the request object....
  138. pRequest->AddRef();
  139. m_reqList.AddTail( pRequest );
  140. // increment the total hit count....
  141. ++m_nTotalHits;
  142. // tell the view we got a new doc hit....
  143. UpdateAllViews( NULL, HINT_DOCHIT, pRequest );
  144. }
  145. BOOL CHttpSvrDoc::IdleProc( LONG lCount )
  146. {
  147. BOOL bMore = FALSE;
  148. // if there's still requests in the list....
  149. if ( !m_reqList.IsEmpty() )
  150. {
  151. // pull off the first item....
  152. CRequest* pRequest = (CRequest*)(m_reqList.RemoveHead());
  153. // if it's done....
  154. if ( pRequest->m_bDone )
  155. {
  156. // process it for the stats....
  157. ExtractStats( pRequest );
  158. // done with it....
  159. pRequest->Release();
  160. // more idle needed if not empty....
  161. bMore = !m_reqList.IsEmpty();
  162. }
  163. else
  164. {
  165. // move to end of list....
  166. m_reqList.AddTail( pRequest );
  167. // still need to come back....
  168. bMore = TRUE;
  169. }
  170. }
  171. return bMore;
  172. }
  173. void CHttpSvrDoc::ExtractStats( CRequest* pRequest )
  174. {
  175. // increment the status' group count....
  176. if ( pRequest->m_uStatus >= 100 && pRequest->m_uStatus < 600 )
  177. ++m_aReStats[ pRequest->m_uStatus/100 - 1 ];
  178. else
  179. ++m_aReStats[ STATUS_SERVERERR ]; // JIC
  180. // see if we want to write entry in log file....
  181. if ( m_bLoggingOn )
  182. {
  183. CString strLog;
  184. strLog.Format( IDS_STATUSFMT, pRequest->m_uStatus );
  185. strLog += pRequest->m_strHost + 't'
  186. + pRequest->m_timeReq.Format( IDS_TIMEFORMAT ) + 't'
  187. + pRequest->m_strURL + ' ';
  188. if ( !pRequest->m_strArgs.IsEmpty() )
  189. strLog += CString("? ") + pRequest->m_strArgs;
  190. strLog += 'n';
  191. CString strLogName = m_strTitleBase + pRequest->m_timeReq.Format(IDS_LOGFILEFMT);
  192. CStdioFile fileLog( strLogName,
  193. CFile::modeWrite | CFile::modeCreate |
  194. CFile::modeNoTruncate | CFile::shareExclusive );
  195. // see if file is new and we need to write the header....
  196. if ( fileLog.SeekToEnd() == 0 )
  197. {
  198. // write page header.....
  199. CString strHeader;
  200. strHeader.Format( IDS_LOG_HEADER, pRequest->m_timeReq.Format(IDS_LONG_DATE) );
  201. fileLog.Write( strHeader, strHeader.GetLength() );
  202. }
  203. fileLog.Write( strLog, strLog.GetLength() );
  204. fileLog.Close();
  205. }
  206. }
  207. void CHttpSvrDoc::OnCloseDocument()
  208. {
  209. StopListening();
  210. CDocument::OnCloseDocument();
  211. }
  212. void CHttpSvrDoc::SetTitle(LPCTSTR lpszTitle)
  213. {
  214. CString strTitle;
  215. if ( lpszTitle != NULL )
  216. m_strTitleBase = lpszTitle;
  217. if ( m_strServer.IsEmpty() )
  218. strTitle = m_strTitleBase;
  219. else if ( m_pListen == NULL )
  220. strTitle.Format( IDS_INVALID, m_strTitleBase );
  221. else
  222. {
  223. if ( m_uPort != PORT_HTTP )
  224. strTitle.Format( IDS_DOCTITLE, m_strTitleBase, m_strServer, m_uPort );
  225. else
  226. strTitle.Format( IDS_DOCTITLE_NOPORT, m_strTitleBase, m_strServer );
  227. }
  228. CDocument::SetTitle( strTitle );
  229. }
  230. void CHttpSvrDoc::OnSvrOptions()
  231. {
  232. // add and initialize the general page....
  233. CPropertySheet propOptions( IDS_OPTIONS );
  234. CGenPage genPage( this );
  235. genPage.m_bListIcon = m_bListIcon;
  236. genPage.m_bAllowListing = m_bAllowListing;
  237. genPage.m_bLoggingOn = m_bLoggingOn;
  238. propOptions.AddPage( &genPage );
  239. // add and initialize the root dir page....
  240. CRootPage rootPage( this );
  241. rootPage.m_strRoot = m_strRoot;
  242. propOptions.AddPage( &rootPage );
  243. // add and initialize the name page....
  244. CNamePage namePage( this );
  245. namePage.m_nNameSetting = m_nSvrName;
  246. namePage.m_uPort = m_uPort;
  247. if ( m_nSvrName )
  248. namePage.m_strName = m_strServer;
  249. propOptions.AddPage( &namePage );
  250. m_bResetListen = FALSE;
  251. propOptions.DoModal();
  252. if ( m_bResetListen )
  253. {
  254. StartListening();
  255. SetTitle( NULL );
  256. }
  257. }
  258. void CHttpSvrDoc::StopListening( void )
  259. {
  260. if ( m_pListen != NULL )
  261. {
  262. m_pListen->Close();
  263. delete m_pListen;
  264. m_pListen = NULL;
  265. }
  266. }
  267. BOOL CHttpSvrDoc::StartListening( void )
  268. {
  269. BOOL bOk = FALSE;
  270. StopListening();
  271. m_pListen = new CListenSocket( this );
  272. if ( m_pListen )
  273. {
  274. if ( m_pListen->Create( m_uPort, SOCK_STREAM, FD_ACCEPT ) )
  275. bOk = m_pListen->Listen();
  276. if ( !bOk )
  277. {
  278. CString strMsg;
  279. int nErr = m_pListen->GetLastError();
  280. if ( nErr == WSAEADDRINUSE )
  281. strMsg.Format( IDS_LISTEN_INUSE, m_uPort );
  282. else
  283. strMsg.Format( IDS_LISTEN_ERROR, m_uPort );
  284. AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
  285. m_pListen->Close();
  286. delete m_pListen;
  287. m_pListen = NULL;
  288. }
  289. }
  290. else
  291. AfxMessageBox( IDS_CANT_LISTEN, MB_OK|MB_ICONSTOP );
  292. m_timeStarted = CTime::GetCurrentTime();
  293. return bOk;
  294. }
  295. void CHttpSvrDoc::OnFileRestart()
  296. {
  297. // this will close the connection if it's already open
  298. // before starting again....
  299. StartListening();
  300. }