2025-04-27 07:49:33 -04:00

389 lines
9.4 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1995-1996 Microsoft Corporation
Module Name :
respobj.cpp
Abstract:
This module defines the functions for CIsaResponseObject
Author:
Murali R. Krishnan ( MuraliK ) 4-Nov-1996
Environment:
Win32 - User Mode
Project:
Internet Application Server DLL
Functions Exported:
Revision History:
--*/
/************************************************************
* Include Headers
************************************************************/
#include "stdafx.h"
#include "sobj.h"
#include "respobj.hxx"
#include <iisext.h>
# include "dbgutil.h"
# define DEFAULT_URL_SIZE (256)
/*----------------------------------------
IMPLEMENTATION Details:
4-Nov-1996:
CIsaResponseObject does not maintain any buffered
contents. All operations are write through. Need to revisit
and fix this in the future.
----------------------------------------*/
/************************************************************
* Functions
************************************************************/
CIsaResponseObject::CIsaResponseObject()
: m_pHttpRequest ( NULL),
m_fValid ( FALSE)
{
IF_DEBUG( OBJECT) {
DBGPRINTF(( DBG_CONTEXT, "Creating CIsaResponseObject() ==> %08x\n",
this));
}
} // CIsaResponseObject::CIsaResponseObject()
CIsaResponseObject::~CIsaResponseObject()
{
IF_DEBUG( OBJECT) {
DBGPRINTF(( DBG_CONTEXT, "deleting CIsaResponseObject() ==>%08x\n",
this));
}
} // CIsaResponseObject::~CIsaResponseObject()
VOID
CIsaResponseObject::Reset(VOID)
{
IF_DEBUG( OBJECT) {
DBGPRINTF(( DBG_CONTEXT, "[%08x]CIsaResponseObject::Reset()\n",
this));
}
m_fValid = FALSE;
return;
} // CIsaResponseObject::Reset()
STDMETHODIMP
CIsaResponseObject::SetHttpRequest(IN unsigned long dwpvHttpReq)
{
HRESULT hr = S_OK;
HTTP_REQUEST * pReq = (HTTP_REQUEST * ) dwpvHttpReq;
DBG_ASSERT( pReq != NULL);
if ( pReq == NULL) {
hr = ( E_POINTER);
} else {
m_pHttpRequest = pReq;
m_fValid = TRUE;
}
IF_DEBUG( OBJECT) {
DBGPRINTF(( DBG_CONTEXT, "%08x::SetHttpRequest(%08x) returns %08x\n",
this, pReq, hr));
}
return ( hr);
} // CIsaResponseObject::SetHttpRequest()
STDMETHODIMP
CIsaResponseObject::SendHeader(
IN unsigned char * pszStatus,
IN unsigned char * pszHeader
)
{
HRESULT hr = S_OK;
if ( (!m_fValid)
){
hr = E_INVALIDARG;
} else {
BOOL fKeepConn;
BOOL fSt;
//
// Build the typical server response headers for the extension DLL
//
//
// Temporarily turn off the KeepConn flag so the keep connection
// header won't be sent out. If the client wants the connection
// kept alive, they should supply the header themselves (ugly)
// NYI: We got to find a better way for this option :(
//
#if !(REG_DLL)
fKeepConn = m_pHttpRequest->IsKeepConnSet();
m_pHttpRequest->SetKeepConn( FALSE );
if ( (NULL != pszStatus) &&
!strncmp( (LPCSTR )pszStatus, "401 ", sizeof("401 ")-1 ) )
{
m_pHttpRequest->SetDeniedFlags( SF_DENIED_APPLICATION );
m_pHttpRequest->SetAuthenticationRequested( TRUE );
}
if ( NULL != pszHeader )
{
m_pHttpRequest->
CheckForBasicAuthenticationHeader( (LPSTR ) pszHeader );
}
BOOL fReturn, fFinished;
// NYI: UGLY: Why should we cast it to CHAR *. Fix the function.
fReturn = m_pHttpRequest->SendHeader( (CHAR *) pszStatus,
((CHAR *) pszHeader) ?
((CHAR *) pszHeader) : "\r\n",
IO_FLAG_SYNC,
&fFinished );
// - not fully implemented
DBG_ASSERT( !fFinished );
if ( !fReturn) {
hr = HRESULT_FROM_WIN32( GetLastError());
}
m_pHttpRequest->SetKeepConn( fKeepConn );
#else
hr = E_FAIL;
#endif
}
IF_DEBUG( API_EXIT) {
DBGPRINTF(( DBG_CONTEXT,
"%08x::SendHeader(%s, %s) => %08x\n",
this, pszStatus, pszHeader,
hr));
}
return ( hr);
} // CIsaResponseObject::SendHeader()
STDMETHODIMP
CIsaResponseObject::Redirect(
IN unsigned char * pszURL
)
{
HRESULT hr = S_OK;
if ( (!m_fValid)
){
hr = E_INVALIDARG;
} else {
#if !(REG_DLL)
CHAR tempURL[ DEFAULT_URL_SIZE];
STR strURL( tempURL, DEFAULT_URL_SIZE);
DWORD cb;
if ( !strURL.Copy( (CHAR *) pszURL ) ||
!m_pHttpRequest->
BuildURLMovedResponse( m_pHttpRequest->QueryRespBuf(),
&strURL )
) {
hr = HRESULT_FROM_WIN32( GetLastError());
} else {
//
// Send The new header using synchronous IO
//
if ( !m_pHttpRequest->
WriteFile( m_pHttpRequest->QueryRespBufPtr(),
m_pHttpRequest->QueryRespBufCB(),
&cb,
IO_FLAG_SYNC )
){
hr = HRESULT_FROM_WIN32( GetLastError());
}
}
# else
hr = E_FAIL;
# endif
}
IF_DEBUG( API_EXIT) {
DBGPRINTF(( DBG_CONTEXT,
"%08x::Redirect(%s) => %08x\n",
this, pszURL,
hr));
}
return ( hr);
} // CIsaResponseObject::Redirect()
STDMETHODIMP
CIsaResponseObject::SendURL(
IN unsigned char * pszURL
)
{
HRESULT hr = S_OK;
if ( (!m_fValid)
){
hr = E_INVALIDARG;
} else {
// NYI: We should migrate the send URL logic
// and avoid accessing SE_INFO object ....
#if !(REG_DLL)
SE_INFO * psei = (SE_INFO *) m_pHttpRequest->QueryISAPIConnID();
// Set this so that the Test ISAPI dll does not blow this connection
// prematurely before the Async IO completes
psei->_dwFlags |= SE_PRIV_FLAG_SENDING_URL;
if ( !m_pHttpRequest->ReprocessURL( (CHAR * ) pszURL,
HTV_GET )
) {
hr = HRESULT_FROM_WIN32( GetLastError());
// we failed to process the URL. Shut off the priv sending flag.
psei->_dwFlags &= ~SE_PRIV_FLAG_SENDING_URL;
}
# else
hr = E_FAIL;
# endif
}
IF_DEBUG( API_EXIT) {
DBGPRINTF(( DBG_CONTEXT,
"%08x::SendURL(%s) => %08x\n",
this, pszURL,
hr));
}
return ( hr);
} // CIsaResponseObject::SendURL()
STDMETHODIMP
CIsaResponseObject::WriteClient(
IN unsigned long cbSize,
IN unsigned char* pchBuf,
OUT unsigned long * pcbReturn
)
/*++
This function forwards all the calls to do the proper work for
writing out the buffer to the client which made the HttpRequest
Arguments:
cbSize - count of bytes to send to the client
pchBuf - pointer to Buffer containing data
pcbReturn - pointer to buffer containing the # of bytes successfully written
Returns:
HRESULT - indicating success/failure.
NOTE:
Only Synchronous IO is supported for now.
No BUFFERING is supported.
--*/
{
HRESULT hr = S_OK;
if ( (NULL == pchBuf) ||
(!m_fValid)
){
hr = E_INVALIDARG;
} else {
DBG_ASSERT( NULL != m_pHttpRequest);
#if !defined( REG_DLL)
DBG_ASSERT( m_pHttpRequest->QueryClientConn()->CheckSignature() );
if ( 0 != cbSize) {
// NYI: Avoid casts if possible. Modify the base functions
if ( !m_pHttpRequest->WriteFile( (LPVOID ) pchBuf,
(DWORD ) cbSize,
(DWORD * ) pcbReturn,
IO_FLAG_SYNC
)
) {
hr = HRESULT_FROM_WIN32( GetLastError());
}
} else {
DBG_ASSERT( SUCCEEDED( hr));
}
# else
hr = E_FAIL;
#endif // !defined( REG_DLL)
}
IF_DEBUG( API_EXIT) {
DBGPRINTF(( DBG_CONTEXT,
"%08x::WriteClient(%08x, cb=%d, %08x [%d]) => %08x\n",
this, pchBuf, cbSize,
pcbReturn, (NULL != pcbReturn) ? *pcbReturn : 0,
hr));
}
return (hr);
} // CIsaResponseObject::WriteClient()
/************************ End of File ***********************/