/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
redirect.cpp
Abstract:
Redirect is a sample ISAPI extension to demonstrate redirecting
a request. It redirects requests to a URL specified on the
query string.
--*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <httpext.h>
#include <stdio.h>
#define BUFF_SIZE 2048
//
// local prototypes
//
DWORD SendInstructionPage( EXTENSION_CONTROL_BLOCK * pECB );
BOOL WINAPI
GetExtensionVersion(
OUT HSE_VERSION_INFO * pVer
)
/*++
Purpose:
This is required ISAPI Extension DLL entry point.
Arguments:
pVer - poins to extension version info structure
Returns:
always returns TRUE
--*/
{
pVer->dwExtensionVersion =
MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR );
lstrcpyn(
pVer->lpszExtensionDesc,
"Redirect ISAPI Sample",
HSE_MAX_EXT_DLL_NAME_LEN );
return TRUE;
}
DWORD WINAPI
HttpExtensionProc(
IN EXTENSION_CONTROL_BLOCK * pECB
)
/*++
Purpose:
If no query string is present, or if the query
string is not identified as a legal target for redirection,
Redirect.dll will return a page to the client with brief
instructions for its use.
Redirections to a resource on the same server as the dll will
be handled by IIS and will be transparent to the browser
(HSE_REQ_SEND_URL).
Redirections to a resource on a different server will result
in an HTTP 302 response instructing the browser to obtain the
resource from another location (HSE_REQ_SEND_URL_REDIRECT_RESP).
Arguments:
pECB - pointer to the extenstion control block
Returns:
HSE_STATUS_SUCCESS on successful completion
HSE_STATUS_ERROR on failure
--*/
{
//
// If no query string is present, return the instruction page
//
if ( !strlen( pECB->lpszQueryString ) ) {
return SendInstructionPage( pECB );
}
//
// Check to see if the redirect URL is on another server. If it is, use
// HSE_REQ_SEND_URL_REDIRECT_RESP. If it's on this local server, use
// HSE_REQ_SEND_URL to return the specified URL without using an HTTP 302
// status code.
//
DWORD dwBuffSize = strlen( pECB->lpszQueryString );
if ( !strnicmp( pECB->lpszQueryString, "http://", 7 ) ) {
pECB->ServerSupportFunction(
pECB->ConnID,
HSE_REQ_SEND_URL_REDIRECT_RESP,
pECB->lpszQueryString,
&dwBuffSize,
NULL
);
} else {
//
// Check to make sure that query string begins with a '/'.
//
if ( *( pECB->lpszQueryString ) != '/' ) {
return SendInstructionPage( pECB );
}
pECB->ServerSupportFunction(
pECB->ConnID,
HSE_REQ_SEND_URL,
pECB->lpszQueryString,
&dwBuffSize,
NULL
);
}
return HSE_STATUS_SUCCESS;
}
DWORD
SendInstructionPage(
IN EXTENSION_CONTROL_BLOCK * pECB
)
/*++
Purpose:
Send short http usage description to the user.
Arguments:
pECB - pointer to the extenstion control block
Returns:
HSE_STATUS_SUCCESS on successful completion
HSE_STATUS_ERROR on failure
--*/
{
char szStatus[] = "200 OK";
char szContent[] =
"<html>"
"<head><title>Redirect URL</title></head>"
"<body>"
"<h1>Redirect.dll</h1>\r\n<hr>\r\n"
"Redirect.dll returns the resource specified on the query string.<br>\r\n<br>\r\n"
"To specify a resource on the same server as Redirect.dll, use the following form:<br>\r\n<br>\r\n"
"<code> http://server/scripts/Redirect.dll?/virtualdir/file.htm </code><br>\r\n<br>\r\n"
"To specify a resource on another server, use the following form:<br>\r\n<br>\r\n"
"<code> http://server/scripts/Redirect.dll?http://server/virtualdir/file.htm </code>"
"</body>"
"</html>";
char szHeaderBase[] = "Content-Length: %lu\r\nContent-type: text/html\r\n\r\n";
char szHeader[BUFF_SIZE];
//
// fill in byte count in Content-Length header
//
DWORD cchContent = strlen( szContent );
sprintf( szHeader, szHeaderBase, cchContent );
//
// Populate SendHeaderExInfo struct
//
HSE_SEND_HEADER_EX_INFO SendHeaderExInfo;
SendHeaderExInfo.pszStatus = szStatus;
SendHeaderExInfo.pszHeader = szHeader;
SendHeaderExInfo.cchStatus = strlen( szStatus );
SendHeaderExInfo.cchHeader = strlen( szHeader );
SendHeaderExInfo.fKeepConn = FALSE;
//
// Send header
//
if ( !pECB->ServerSupportFunction(
pECB->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER_EX,
&SendHeaderExInfo,
NULL,
NULL
) ) {
return HSE_STATUS_ERROR;
}
//
// Send content
//
if ( !pECB->WriteClient( pECB->ConnID, szContent, &cchContent, 0 ) ) {
return HSE_STATUS_ERROR;
}
return HSE_STATUS_SUCCESS;
}
BOOL WINAPI
TerminateExtension(
IN DWORD dwFlags
)
/*++
Routine Description:
This function is called when the WWW service is shutdown
Arguments:
dwFlags - HSE_TERM_ADVISORY_UNLOAD or HSE_TERM_MUST_UNLOAD
Return Value:
TRUE if extension is ready to be unloaded,
FALSE otherwise
--*/
{
return TRUE;
}