📄 w3mfc.cpp
字号:
/*
Module : W3Mfc.cpp
Purpose: Implementation for a simple MFC class encapsulation of a HTTP server
Created: PJN / 22-04-1999
History: PJN / 24-06-1999 1. Implemented support for "HEAD" command
2. Sample provided now also displays the HTTP verb used
3. Sample provided now also displays the date and time of each request
4. Now fully supports multiple virtual directories
5. Now fully supports URL's with encoded characters
6. Implemented support for "DELETE" command
7. Now returns an "Allow:" HTTP header
8. Timeout for requests is now 90 seconds if built for debug
9. Now supports directory listing
10. User name is now displayed in the log window
PJN / 29-02-2000 1. Fixed a number of VC 6 level 4 warnings
2. Now empties the username and password once they are used
3. Now implements W3C Common Logfile logging to the console window
PJN / 15-04-2001 1. Updated copyright information
2. A new generalised thread pool wrapper class is now included which can
be used in other projects.
3. A new generalised sockets wrapper class is now included which can be
used in other winsock projects
PJN / 23-04-2001 1. Fixed a stack overwrite issue in CHttpResponseHeader::DateToStr
2. Fixed a bug in CHttpClient::TransmitFile which was causing "304 Not Modified"
headers to never be returned
PJN / 25-07-2001 1. Code now uses Winsock 2 functionality, namely "WSAEventSelect" to avoid a busy loop
in the listening socket thread. This means that you will have to have Winsock 2
downloaded and installed if running on Windows 95 which did not ship with
Winsock 2 built in.
PJN / 23-08-2001 1. Added support for CGI v1.1 (has been verfied with perl scripts and batch files)
2. Added support for reverse DNS lookups
3. Now fully supports POST HTTP method.
4. Following values have been added to CHttpRequest:
m_pszRawRequest, m_pszRawEntity, m_sRemoteHost and m_sContentType
5. Improved the robustness of the code by making sure exceptions are caught
PJN / 30-09-2001 1. Fixed a bug in CWSocket::Receive which can occur when a disconnection occurs
while a receive is in progress
2. Fixed a bug where entities sent i.e. m_pszRawEntity did not correctly handle the
case where it had enbedded NULL's e.g. a file upload. Thanks to Christian Hett for
spotting this problem.
3. Removed some unnecessary memcpy's from CHttpClient::ParseRequest
4. Made the main program configurable via an ini file instead of hard coding all the
settings.
5. Fixed a resource leak on an anonymous pipe handle in CHttpClient::TransmitCGIResponse.
PJN / 03-11-2001 1. Fixed an issue where socket sends would sometimes throw the exception WSAEWOULDBLOCK.
The httpsocket class now includes a "SendWithRetry" method which handles this case.
PJN / 27-12-2001 1. Fixed an exception memory leak in the method CHttpSocket::SendWithRetry. Thanks
to Olivier Meyer for spotting this problem.
2. Removed an unreferrenced variable from CHttpSocket::ReadResponse
3. Added a flag to TransmitFile to allow the transmission of an "Expires: " header
4. Added CHttpDirectory parameter to all transmit methods. Allows derived classes
more control over the response procedure.
5. Added optional Non-NT authentication to the web server at the virtual directory
level.
6. Reviewed TRACE statements throughtout W3MFC for completeness and validity
7. Addition of a CHttpClient::TransmitBuffer method to allow for easy transmission of
in-memory generated responses. Thanks to "Golden Crater" for most of those suggestions.
8. W3MFC now takes advantage of the MS Winsock extension API "TransmitFile". This
should improve the performance of the code by avoiding inordinate kernel transitions
on NT based operating systems.
9. Includes a new error reporting mechanism via the CHttpServer::OnError method
10. Now includes a nice icon for the generated binary
11. Version info resource is now included in the generated binary
12. Modified "Return..." functions to return body length sent
13. Check all PostLog calls to ensure indicated parameter size is correct
14. W3MFC now takes advantage of the MS Winsock extension API "TransmitPackets". This
should improve the performance of the code by avoiding inordinate kernel transitions
on Windows XP or later. Please note that I have been unable to test this feature so
feeback on this would be appreciated.
PJN / 08-01-2002 1. Code only uses TransmitFile and TransmitPackets APIs if running on NT/2000/XP/.Net Server
2. Provided a virtual CHttpClient::TransmitFile and CHttpClient::TransmitBuffer functions.
The default implemenations just pass the buck to the _W3MFC_DATA function pointers if
available.
3. Made CHttpClient::HandleClient function virtual.
4. Fixed an issue in CHttpClient::TransmitDirectory where created URL's could sometimes forget
to put in directory separators in the URL.
5. Updated copyright messages to be 2002.
6. Provided a virtual CHttpClient::ParseRequestLine to allow derived classes to easily pull
out any additional http headers e.g. "User-Agent" or "Accept-Language" etc.
7. Provided a virtual CHttpClient::FormCGIEnvironment to allow derived classes to easily change
the environment variables sent to CGI processes.
8. Fixed a serious bug in CHttpResponseHeader::GetData while code was compiled for UNICODE
9. Addition of a very handy new "CW32Handle" class which implements a "Smart Pointer" class
for Win32 Handles. For one thing it looks after calling CloseHandle in the destructor. The class
turns out to be very handy when you are implementing CGI in this web server as you have to
create loads of Win32 handles such as anonymous pipes etc.
10. Improved the error reporting in CHttpClient::TransmitCGIResponse
11. Rewrote the CGI handling code in CHttpClient::TransmitCGIResponse to use the information
provided by MS Knowledge base article "Q190351".
PJN / 26-01-2002 1. CIOCP9x clas: added an additional semaphore as I have forgotten that we need to synchronise
the removal of items from the queue in addition to synchronising the addition of items to the
queue.
2. Fixed a level 4 warning in the CHttpClient class.
3. Only now uses TransmitPackets and TransmitFile if running 2000 / XP or .Net Server. Thanks
to Olivier Meyer for spotting this problem on NT 4.
PJN / 21-02-2002 1. Fixed an issue in CHttpClient::GetCGICommandLine where the code was using RegQueryValue
instead of RegQueryValueEx which is the recommended way of doing registry queries in Win32.
Thanks to Josh Clarke for spotting this problem.
2. CGI command line is now expanded with any environment variables it may contain. Again
thanks goes to Josh Clarke for this nice update.
PJN / 23-03-2002 1. W3MFC ships with a sample CGI app "TestCGI.exe"
2. CHttpClient::GetCGICommandLine function now defaults to the local file path if a registry
entry cannot be found for it. Thanks to Gilad Novik for this suggestion.
PJN / 23-05-2002 1. Now fully supports SSL via the OpenSSL open source Library.
2. Removed IOCP9x module from project as not required.
3. Fixed a bug in CHttpServer::ListenSocketFunction which was causing the thread pool to initialize
incorrectly.
PJN / 24-05-2002 1. Fixed a bug in the SSL code path which was causing a crash in CHttpClient::TransmitBuffer.
2. Provision of wrapper classes for OpenSSL C type variables used by W3MFC
3. Tidied up the SSL code in CHttpClient::HandleClient
PJN / 25-05-2002 1. Improved the performance of CHttpClient::URLDecode method
2. Improved the performance of CHttpClient::TransmitDirectory. Thanks to "Jim" for this fix.
3. URL's transmitedd down to client in CHttpClient::TransmitDirectory are now URL encoded.
4. Fixed a crash which was occurring for some requests in CHttpClient::ParseRequest where the code
ended up parsing into the entity body instead of stopping when it reached the separator after the
http header. Thanks to Harold B Johns for spotting this.
PJN / 29-05-2002 1. Environment variables for CGI processes now includes all the environment variables which W3MFC
itself has. These missing environment variables were causing CGI programs to fail in calls to
CoInitialize if they were using COM. Thanks to Harold B Johns for spotting this.
PJN / 30-05-2002 1. Fixed a #include issue when doing a non SSL build. Thanks to Harold B Johns for spotting this.
2. Fixed an issue where a request for a non existent CGI file caused the web server to become
unresponsive. Thanks to Harold B Johns for spotting this.
3. Fixed an issue in the CGI code when SSL is enabled. Thanks to Gilad Novik for reporting this
problem.
PJN / 14-06-2002 1. Fixed a problem in CHttpClient::FindNextTerminatorFromRequest which was parsing out header
details incorrectly. Thanks to Gilad Novik for reporting this problem.
PJN / 28-07-2002 1. Now CHttpMimeManager can be replaced at runtime. This allows the mime map to be easily configured
or replaced with a custom implementation.
2. Mime map as used by the sample app is now configured from the W3MFC ini file instead of from
the system registry. In addition the shipped W3MFC ini file now includes a fully fleshed out mime
section
3. You can now improve the robustness of the SSL behaviour by initializing the OpenSSL PRNG (Pseudo
Random Number generator) with the contents of a file as specified via
CHttpServerSettings::m_sSSLRandomnessFile.
4. A fresh default web site is now shown using the default ini settings, instead of expecting a web
site to be configured at c:\inetpub\wwwroot
5. Improved the performance of looking up mime types by implementing a hash table for storage
PJN / 18-08-2002 1. Now uses v1.09 of the CThreadPoolServer class.
2. Sample app now allows you to decide via a ini value whether or not to use the CIOCPThreadPoolQueue
class instead of the CDirectedThreadPoolQueue class. While I was at it, I avoiding an issue with
leaving an item on the Q if updating the "Get" semaphores failed.
PJN / 17-10-2002 1. Fixed a bug in CHttpClient::HexToInt which was causing it to not work for upper case characters.
Thanks to Frank Schmidt for spotting this problem.
Failure to setup thread pool recycling is now reported as an error.
PJN / 16-11-2002 1. Class now supports the use of the "Connection: Keep-Alive" Header.
2. Removed the StringReplace method and replaced it with CString::Replace.
3. Fixed some Log message's text to correctly reflect the function they are used in.
4. Code now makes the call to CHttpClient::AllowThisConnection before the incoming request is parsed.
5. Fixed a typo in the name of the CHttpClient::HandleDirectoryAuthorization function
6. Made the operation of the delivery of the "Expires" header contingent on a configurable setting
7. CHttpResponseHeader::AddW3MfcAllowFields now returns that it can handle POST requests
8. The "DELETE" verb support is now contingent on a configurable setting.
9. Fixed a typo in the creation of the "SERVER_PROTOCOL" CGI environment variable
10. Updated the sample CGI app to also send a Content-Length HTTP header. This allows the sample
app to work correctly when it is used in conjuction with HTTP Keep Alives
PJN / 17-11-2002 1. Optimized the use of the Keep Alives variables in the function CHttpClient::HandleClient
2. Implemented code to find whether CGI programs send Keep Alives.
PJN / 18-11-2002 1. Now allows anonymous access to be enabled / disabled
2. Now allows Basic authentication to be enabled / disabled.
3. Reworked the Base64 class to be based on the ATL Server Base64 routines in ATL Server in VC.Net
4. Renamed and Reworked the CHttpClient::ReturnUnauthorizedMessage method.
5. Impersonation handle used during Basic authentication now is a CW32Handle instance instead of a
raw SDK handle
6. Now fully supports NTLM Authentication via the SSPI interface. The code is enabled for support
for Kerberos, "Negotiate" and Digest authentication which will be added in a future release. The use
of SSPI support can be changed via the compile time define "W3MFC_NO_SSPI_SUPPORT". Thanks to
Harold B Johns for suggesting this.
7. Fixed a problem in CHttpClient::ParseRequest which was causing failures to parse a certain line
to be overwritten upon successfull parsing of subsequent lines.
8. test CGI app now is implemented without MFC support and deliberatly does not use a Content-Length
or Keep-Alive header for testing purposes.
9. Tidied up the importing of various header files throughout W3MFC and also the associated
#pragma messages which these something display.
PJN / 18-11-2002 1. CHttpSocket::ReadResponse now uses waitable timers (if it can) instead of a loop which has calls
to Sleep. This should improve the scalabilty of the code under heavy load. Please note that if you
want to compile the code, then you will need to download the CWaitableTimer source code separately
from my web site and copy in the wtimer.h & wtimer.cpp into your W3MFC's source code directory.
2. Added code to protect against NTFS alternate streams being accessed by client browsers.
3. Improved the robustness of parsing the authorization header fields.
PJN / 20-11-2002 1. Fixed a number of level 4 warnings about unreferrenced variables. Thanks to Harold Johns for
reporting these.
2. Updated the documentation to refer to the fact that you will need an up to date Platform SDK
to be installed to compile W3MFC with SSPI support.
3. Fixed a memory leak of CHttpRequest objects which can occur when you shutdown the web server and
you are using a directed thread pool queue and there are outstanding items in the queue which are
not shutdown requests
PJN / 03-02-2003 1. W3MFC now compares HTTP headers without regard to case. Thanks to Gilad Novik and Frank Hahn for
reporting these problems.
2. Tidied up inclusion of afxpriv.h throughout W3MFC modules.
PJN / 21-02-2003 1. Made the m_Directories member of CHttpServerSettings a pointer array. This allows client code
to add their own derived instances of CHttpDirectory to the array. This allows per directory
customisation of the web server. This change also necessitated changing the settings class of the
CHttpServer to be a pointer also. Thanks to "Edgar" for this update.
2. Remove the digest authentication boolean from the settings class as Digest authentication is
currently not supported.
3. Made the CHttpClient::LoadHTMLResource method virtual
4. Moved a lot of the CHttpClient implementation code to CHttpDirectory. This allows more additional
complex client customisation of the code.
5. Split off the CHttpDirectory class into its own module.
6. Implemented a virtual CHttpDirectory::HandleClient. This allows customisation of per directory
responses. Thanks to "Edgar" for this suggestion.
PJN / 22-02-2003 1. Fixed a bug in the parsing of SSL requests which was causing heap corruption problems on
subsequent reads of SSL requests on the same thread.
2. Reworked the CHttpClient::HandleClient to avoid having to call various functions when the code
needs to exit prematurely
3. Added a member variable "m_bResponseKeepAlive" to avoid having to pass a keep alive variable
throughout all the CHttpClient code.
4. Fixed a deadlock bug in CHttpServer::Stop. Thanks to "Edgar" for reporting this problem.
5. modified the Mime manager class method "GetMimeType" to be sent the full request rather than just
the extension of the URL when it is called to determine the mime type.
6. Addition of a string version of the HTTP verb to CHttpRequest. This speeds up the CGI and
ISAPI implementations somewhat.
7. Addition of a hash table in the request structure which contains all the HTTP request headers. These
values are now available via CGI or ISAPI
8. Split of the CGI implementation into its own module and made it optional via a preprocessor directive
9. Split of the ISAPI implementation into its own module and made it optional via a preprocessor directive
10. W3MFC now uses Win32 TransmitFile API in SSL configuration and only falls back to user mode sockets
if SSL is actively being used.
11. W3MFC now supports PATH_INFO information in URL's
12. Optimized loading of error pages which W3MFC uses
PJN / 02-03-2002 1. Removed the function CHttpDirectory::SetClient as it can lead to thread synchronisation problems.
Thanks to "Edgar" for reporting this problem.
PJN / 03-03-2202 1. Added a few defines to allow the W3MFC to compile if you do not have the latest version of the Platform
SDK installed. Thanks to "Edgar" for reporting this.
2. Fixed a copy and paste gremlin in CHttpServer::Start which was causing a critical section to not be
acquired. Thanks to "Edgar" for reporting this.
3. Removed the use of "friend classes" entirely throughout the W3MFC codebase. This avoids potential
compilation problems in any derived classes used by client code of W3MFC.
4. Addition of a number of preprocessor defines, namely W3MFC_EXT_CLASS, THRDPOOL_EXT_CLASS and
SOCKMFC_EXT_CLASS. This allows the classes to easily be added and exported from a MFC extension dll.
PJN / 12-09-2003 1. Removed double definition of SCRIPT_NAME from CGI environment. Thanks to Dave Horner for reporting
this.
2. SCRIPT_NAME CGI environment variable now uses forward slashes rather than back slashes as
directory separators. Thanks to Dave Horner for reporting this problem.
3. Added a "REQUEST_URI" CGI environment variable. Thanks to Dave Horner for reporting this.
4. CGI implementation now returns a HTTP return code line if one if the CGI script does not provide one.
Again thanks to Dave Horner for reporting this issue.
5. CGI implementation now returns immedately from CHttpCGI::ReadFromClientStdout from a socket error is
detected. Again thanks to Dave Horner for reporting this issue.
6. "PATH_TRANSLATED" CGI and ISAPI environment variable is now reported as an absolute path. Again thanks
to Dave Horner for reporting this issue.
7. "SCRIPT_NAME" CGI and ISAPI environment variable now includes an initial "/". Again thanks to Dave
Horner for reporting this issue.
8. CGI now uses pClient->m_Request.m_dwRawEntitySize variable when determining when W3MFC needs to
write to the CGI child process.
9. ISAPI implementation now sends just the HTTP body to client ISAPI dlls instead of the whole HTTP
request. Thanks to Michael St. Laurent for reporting this problem.
PJN / 03-11-2003 1. Simplified the code in CHttpSocket::ReadResponse. Thanks to Clarke Brunt for reporting this issue.
PJN / 10-11-2003 1. URL Encoded spaces as "+" are now correctly handled. Thanks to Dan Baker for reporting this issue.
2. CHttpRequest now includes a m_sRawURL member variable which provides access to the raw URL
before it is URL decoded. Thanks to Dan Baker for suggesting this addition.
3. Shipped binary for W3MFC is now linked with the OpenSSL 0.9.6l which is the latest version currently.
PJN / 30-03-2004 1. Tidied up the interaction of the various classes by removing all friend classes
PJN / 25-08-2004 1. The binaries included in the download now link against OpenSSL 0.9.7d.
2. Per thread cleanup is now done for OpenSSL. Again thanks to Leandro Gustavo Biss Becker for reporting
this problem.
3. OpenSSL is now configured by the W3MFC sample app to operate in a thread safe manner. Again thanks
to Leandro Gustavo Biss Becker for reporting this problem.
4. Application initialization of OpenSSL has been taken out of W3MFC and is now the responsibility of
your application. See the sample W3MFC application code in main.cpp for an example on how to correctly
initialize and terminate OpenSSL.
5. CSSL::Close() now calls SSL_shutdown to ensure SSL connections are properly terminated. Thanks to
to Leandro Gustavo Biss Becker for reporting this problem.
6. W3MFC now correctly handles UTF8 encoded URL requests. Thanks to Huang Wei for reporting this problem
and providing the fix.
PJN / 15-10-2004 1. Removed an unnecessary ASSERT from CHttpClient::MapURLToLocalFilename. Thanks to Jan Bares for
reporting this problem.
2. Changed the behaviour of the code in CHttpClient::MapURLToLocalFilename as follows:
Before Change
Requesting the URL "/name" would return the file "name" in the root directory of the web server even if
a "/name" virtual directory existed. If "name" did not exist in the root directory then a 404 error
would be returned
After Change
Requesting the URL "/name" will return the virtual directory "/name" if such a virtual directory exists.
If not then the file "name" in the root directory will be returned.
Thanks to Jan Bares for pointing out this behaviour which is inconsistent with other Web Server implementations.
3. URLs which include "@" now are parsed correctly. Previously the code was parsing the URI
expecting it to contain username and password in the URL itself. Instead when the URI arrives at the
server it is not in the URI itself but is represented in the HTTP request headers. Thanks to Jan Bares for
pointing out this problem.
4. Passthrough authentication can now be disabled via a new CHttpServerSettings::m_bPerformPassthroughAuthentication
setting. This is useful where you want to setup per directory protection using a username / password pair but
you do not want to use these credentials in an attempt to impersonate that user by calling the SDK function
"LogonUser". Again thanks to Jan Bares for this suggestion.
PJN / 11-11-2004 1. Added a m_sRawExtra variable to CHttpRequest. This value is now passed to CGI and ISAPI instead of m_sExtra.
This allows apps to correctly parse form parameters. Thanks to Jan Bares for reporting this problem.
PJN / 19-02-2004 1. Fixed a bug when directory lists were displayed by W3MFC. It incorrectly always dropped the last entry from
the listing. Thanks to Pablo Romero for reporting this bug.
Copyright (c) 1999 - 2005 by PJ Naughter. (Web: www.naughter.com, Email: pjna@naughter.com)
All rights reserved.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -