📄 response.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: response.cpp
Abstract: Implements Response script object.
--*/
#include "aspmain.h"
/////////////////////////////////////////////////////////////////////////////
// CResponse
// FILETIME (100-ns intervals) to minutes (10 x 1000 x 1000 x 60)
#define FILETIME_TO_MINUTES ((__int64)600000000L)
CResponse::CResponse()
{
m_pASPState = (CASPState *) TlsGetValue(g_dwTlsSlot);
DEBUGCHK(m_pASPState);
if ( c_fUseCollections )
{
m_pCookie = CreateCRequestDictionary(RESPONSE_COOKIE_TYPE,m_pASPState,NULL);
if (! m_pCookie)
return ;
m_pASPState->m_pResponseCookie = m_pCookie;
m_pCookie->AddRef();
}
else
{
m_pCookie = NULL;
}
}
CResponse::~CResponse()
{
if (m_pCookie)
m_pCookie->Release();
}
STDMETHODIMP CResponse::get_Cookies(IRequestDictionary **ppDictReturn)
{
DEBUGMSG(ZONE_REQUEST,(L"ASP: In CResponse::get_Cookies!!\r\n"));
// DebugBreak();
if (m_pCookie)
return m_pCookie->QueryInterface(IID_IRequestDictionary,(void **) ppDictReturn);
return E_NOTIMPL;
}
// NOTE: We store a copy of fBufferedResponse in both ASP and httpd, the only
// variable we do this with. We do this because the Write fcns in ASP need access
// to it, as do the write fcns that are buried deep with calls to httpd
STDMETHODIMP CResponse::get_Buffer(VARIANT_BOOL *pVal)
{
if (m_pASPState->m_fBufferedResponse)
*pVal = 1;
else
*pVal = 0;
return S_OK;
}
// Note: If user wants to have a buffered response, the line that sets this
// needs to be the 1st or right after the preproc directives (though spaces are OK).
// Otherwise the default is no buffering, and data will have been sent by the
// time this call is made. This is like IIS 4.0.
STDMETHODIMP CResponse::put_Buffer(VARIANT_BOOL newVal)
{
if (m_pASPState->m_fSentHeaders == TRUE)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
// Should never die, this is only an accessor.
if ( ! m_pASPState->m_pACB->SetBuffer(m_pASPState->m_pACB->ConnID, newVal))
{
ASP_ERR(IDS_E_HTTPD);
return DISP_E_EXCEPTION;
}
m_pASPState->m_fBufferedResponse = newVal;
return S_OK;
}
STDMETHODIMP CResponse::get_Expires(VARIANT * pvarExpiresTimeRet)
{
SYSTEMTIME st;
__int64 ft;
// no expires time set
if (0 == m_pASPState->m_iExpires)
{
V_VT(pvarExpiresTimeRet) = VT_EMPTY;
return S_OK;
}
GetSystemTime(&st);
SystemTimeToFileTime(&st, (FILETIME*) &ft);
ft = (m_pASPState->m_iExpires - ft) / FILETIME_TO_MINUTES;
if (ft < 0)
ft = 0;
V_VT(pvarExpiresTimeRet) = VT_I4;
V_I4(pvarExpiresTimeRet) = (long) ft;
return S_OK;
}
STDMETHODIMP CResponse::put_Expires(long lExpiresMinutes)
{
SYSTEMTIME st;
__int64 ft;
if (m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
// Treat 0 and negative values like "Expires now"
if (lExpiresMinutes < 0)
lExpiresMinutes = 0;
GetSystemTime(&st);
SystemTimeToFileTime(&st, (FILETIME*)&ft);
ft += FILETIME_TO_MINUTES * lExpiresMinutes;
// If there are multiple calls to this and/or ExpiresAbsolute, we use the
// time that comes nearest in the future
if ( ft < m_pASPState->m_iExpires || m_pASPState->m_iExpires == 0 )
m_pASPState->m_iExpires = ft;
return S_OK;
}
STDMETHODIMP CResponse::get_ExpiresAbsolute(VARIANT *pvarTimeRet)
{
SYSTEMTIME st;
OLECHAR wszDate[100];
DWORD cbDate = 100;
int i;
DWORD dw = 0;
V_VT(pvarTimeRet) = VT_DATE;
// no expires time set
if (0 == m_pASPState->m_iExpires)
{
return S_OK;
}
FileTimeToSystemTime( (FILETIME*) &m_pASPState->m_iExpires, &st);
// Note: Docs require 1st parameter ignrored, docs want LOCALE_SYSTEM_DEFAULT there
// This format is for Variant conversion, has nothing to do with httpd headers
i = GetDateFormat(LOCALE_SYSTEM_DEFAULT , 0, &st, L"M'/'d'/'yyyy' '",wszDate, cbDate);
dw = GetLastError();
cbDate -= i;
i += GetTimeFormat(LOCALE_SYSTEM_DEFAULT , 0,&st, L"h':'mm':'ss tt",
wszDate + i - 1, cbDate);
VarDateFromStr(wszDate,LOCALE_SYSTEM_DEFAULT,0, &V_DATE(pvarTimeRet));
return S_OK;
}
// Notes: DATE is made up of 2 adjacent doubles. In bottom 32 bits there's the date,
// top 32 bits specify the time. It's possible for script writer to leave one of these
// blank, ie only set the date or time to expire.
// If no date is specified, we assume expires today.
// If no time is specified, we assume expires midnight of the date set.
STDMETHODIMP CResponse::put_ExpiresAbsolute(DATE dtExpires)
{
HRESULT hr = DISP_E_EXCEPTION;
SYSTEMTIME st;
__int64 ft;
if (m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
VariantTimeToSystemTime(dtExpires,&st);
// time specified but no date (assume today)
if (int(dtExpires) == 0)
{
SYSTEMTIME stToday;
GetSystemTime(&stToday);
// set the date of the original structure
st.wYear = stToday.wYear;
st.wMonth = stToday.wMonth;
st.wDayOfWeek = stToday.wDayOfWeek;
st.wDay = stToday.wDay;
}
// If the is date specified, time=0 would be midnight. No changes needed.
SystemTimeToFileTime(&st, (FILETIME*)&ft);
// If there are multiple calls to this and/or Expires, we use the
// time that comes nearest in the future
if ( ft < m_pASPState->m_iExpires || m_pASPState->m_iExpires == 0)
m_pASPState->m_iExpires = ft;
return S_OK;
}
STDMETHODIMP CResponse::get_Status(BSTR *pVal)
{
// they've set a custom string, use it
if (NULL != m_pASPState->m_bstrResponseStatus)
{
*pVal = SysAllocString(m_pASPState->m_bstrResponseStatus);
if (NULL == *pVal)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
// if no custom val set then we send a 200 by default, like IIS ASP.
*pVal = SysAllocString(L"200 OK");
if (NULL == *pVal)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
STDMETHODIMP CResponse::put_Status(BSTR newVal)
{
if (NULL == newVal)
return S_OK;
if (TRUE == m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
if (m_pASPState->m_bstrResponseStatus)
SysFreeString(m_pASPState->m_bstrResponseStatus);
m_pASPState->m_bstrResponseStatus = SysAllocString(newVal);
if (NULL == m_pASPState->m_bstrResponseStatus)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
STDMETHODIMP CResponse::get_ContentType(BSTR *pVal)
{
// they've set a custom string, use it
if (NULL != m_pASPState->m_bstrContentType)
{
*pVal = SysAllocString(m_pASPState->m_bstrContentType);
if (NULL == *pVal)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
}
else // Use the default content type
{
if (FAILED (SysAllocStringFromSz((PSTR)cszTextHTML,0,pVal,CP_ACP)))
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
}
return S_OK;
}
STDMETHODIMP CResponse::put_ContentType(BSTR newVal)
{
if (NULL == newVal)
return S_OK;
if (TRUE == m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
if (m_pASPState->m_bstrContentType)
SysFreeString(m_pASPState->m_bstrContentType);
m_pASPState->m_bstrContentType = SysAllocString(newVal);
if (NULL == m_pASPState->m_bstrContentType)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
STDMETHODIMP CResponse::get_Charset(BSTR *pVal)
{
// they've set a custom string, use it
if (NULL != m_pASPState->m_bstrCharSet)
{
*pVal = SysAllocString(m_pASPState->m_bstrCharSet);
if (NULL == *pVal)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
}
return S_OK;
}
STDMETHODIMP CResponse::put_Charset(BSTR newVal)
{
if (NULL == newVal)
return S_OK;
if (m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
return DISP_E_EXCEPTION;
}
if (m_pASPState->m_bstrCharSet)
SysFreeString(m_pASPState->m_bstrCharSet);
m_pASPState->m_bstrCharSet = SysAllocString(newVal);
if (NULL == m_pASPState->m_bstrCharSet)
{
ASP_ERR(IDS_E_NOMEM);
return DISP_E_EXCEPTION;
}
return S_OK;
}
STDMETHODIMP CResponse::AddHeader(BSTR bstrName, BSTR bstrValue)
{
DEBUG_CODE_INIT;
PSTR pszName = NULL;
PSTR pszValue = NULL;
DWORD ret = DISP_E_EXCEPTION;
if (!bstrName || !bstrValue)
myretleave(S_OK,152);
if (m_pASPState->m_fSentHeaders)
{
ASP_ERR(IDS_E_SENT_HEADERS);
myleave(154);
}
// Codepage note: Since this is an http header, we convert to ANSI string
pszName = MySzDupWtoA(bstrName);
pszValue = MySzDupWtoA(bstrValue);
if (NULL == pszName ||
NULL == pszValue)
{
ASP_ERR(IDS_E_NOMEM);
myleave(151);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -