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

455 lines
19 KiB
C++

// acallsmp.cpp
//
// simple response handlers (everything except PROPFIND and PROPPATCH)
#include <assert.h>
#include "asynccall.h"
#include "qxml.h"
#include "strutil.h"
#include "regexp.h"
#include "mischlpr.h"
///////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleGET(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR pwszContentType,
DWORD UNREF_PARAM(cbSent),
LPBYTE pbResponse,
DWORD cbResponse)
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_GET;
// parse the response as if it were a DAV GET command
if (SUCCEEDED(pdavResponse->hrResult))
{
pdavResponse->rGet.fTotalKnown = TRUE;
pdavResponse->rGet.cbIncrement = 0;
pdavResponse->rGet.cbCurrent = cbResponse;
pdavResponse->rGet.cbTotal = cbResponse;
pdavResponse->rGet.pvBody = pbResponse;
pdavResponse->rGet.pwszContentType = pwszContentType;
}
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleHEAD(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD cchHeaders,
LPWSTR pwszHeaders,
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_HEAD;
// parse the response as if it were a DAV HEAD command
pdavResponse->command = DAV_HEAD;
pdavResponse->rHead.cchRawHeaders = cchHeaders;
pdavResponse->rHead.pwszRawHeaders = pwszHeaders;
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
void AddVerbToVector (DWORD* pdw,
LPWSTR pwszText,
UINT cch)
{
if (LStrCmpN(pwszText, L"GET", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_GET;
}
else if (LStrCmpN(pwszText, L"HEAD", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_HEAD;
}
else if (LStrCmpN(pwszText, L"OPTIONS", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_OPTIONS;
}
else if (LStrCmpN(pwszText, L"PUT", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_PUT;
}
else if (LStrCmpN(pwszText, L"POST", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_POST;
}
else if (LStrCmpN(pwszText, L"DELETE", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_DELETE;
}
else if (LStrCmpN(pwszText, L"MKCOL", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_MKCOL;
}
else if (LStrCmpN(pwszText, L"COPY", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_COPY;
}
else if (LStrCmpN(pwszText, L"MOVE", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_MOVE;
}
else if (LStrCmpN(pwszText, L"PROPFIND", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_PROPFIND;
}
else if (LStrCmpN(pwszText, L"PROPPATCH", cch) == 0)
{
*pdw = *pdw | DAVOPTIONS_DAVVERB_PROPPATCH;
}
}
void CAsyncWntCallbackImpl::_ParseDAVVerbs (LPWSTR pwsz,
DWORD* pdw)
{
LPWSTR pwszTemp = pwsz;
LPWSTR pwszTemp2;
LPWSTR pwszDavMethodsSupported = NULL;
pwszTemp2 = LStrStr(pwszTemp, L"\n");
if (pwszTemp2 != NULL)
{
assert((pwszTemp2 - pwszTemp) > 0);
pwszDavMethodsSupported = AllocateStringW(pwszTemp2 - pwszTemp);
lstrcpyn(pwszDavMethodsSupported, pwszTemp, pwszTemp2 - pwszTemp);
pwszTemp = pwszDavMethodsSupported;
pwszTemp2 = pwszDavMethodsSupported;
while (*pwszTemp != NULL)
{
if ((*pwszTemp2)==',')
{
AddVerbToVector(pdw, pwszTemp, pwszTemp2 - pwszTemp);
pwszTemp=pwszTemp2;
while (*pwszTemp == ' ' || *pwszTemp == ',')
{
pwszTemp++;
}
pwszTemp2 = pwszTemp;
}
else if ((*pwszTemp2) == NULL)
{
AddVerbToVector(pdw, pwszTemp, pwszTemp2 - pwszTemp - 1);
pwszTemp=pwszTemp2;
}
else
{
pwszTemp2++;
}
}
}
if (pwszDavMethodsSupported != NULL)
{
free(pwszDavMethodsSupported);
}
}
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleOPTIONS(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD cchHeaders,
LPWSTR pwszHeaders,
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
LPWSTR pwszTemp;
LPWSTR pwszTemp2;
WCHAR wszDavSupported[10];
// parse the response as if it were a DAV OPTIONS command
pdavResponse->command = DAV_OPTIONS;
pdavResponse->rOptions.cchRawHeaders = cchHeaders;
pdavResponse->rOptions.pwszRawHeaders = pwszHeaders;
// determine support for DAV: 1, 2, both, or none at all
pdavResponse->rOptions.bDavSupport = 0;
pwszTemp = LStrStrI(pwszHeaders, L"DAV: ");
if (pwszTemp != NULL)
{
pwszTemp += 5;
pwszTemp2 = LStrStr(pwszTemp, L"\n");
if (pwszTemp2 != NULL)
{
if ((pwszTemp2 - pwszTemp) < 20)
{
lstrcpyn(wszDavSupported, pwszTemp, pwszTemp2 - pwszTemp);
// now we have a string of the format "1, 2" or "1" or "2" or something.
// WARNING: this assumes can only be single digit
if (LStrStr(wszDavSupported, L"1") != NULL)
{
pdavResponse->rOptions.bDavSupport = (BYTE)(pdavResponse->rOptions.bDavSupport | DAVOPTIONS_DAVSUPPORT_1);
}
if (LStrStr(wszDavSupported, L"2") != NULL)
{
pdavResponse->rOptions.bDavSupport = (BYTE)(pdavResponse->rOptions.bDavSupport | DAVOPTIONS_DAVSUPPORT_2);
}
}
}
}
// determine support for each DAV method for this URL
pdavResponse->rOptions.dwDavMethodsAllow = 0;
pwszTemp = LStrStr(pwszHeaders, L"Allow: ");
if (pwszTemp == NULL)
{
pwszTemp = LStrStr(pwszHeaders, L"ALLOW: ");
}
if (pwszTemp != NULL)
{
pwszTemp += 7;
this->_ParseDAVVerbs(pwszTemp, &pdavResponse->rOptions.dwDavMethodsAllow);
}
// determine support for each DAV method for the server entire
pdavResponse->rOptions.dwDavMethodsPublic = 0;
pwszTemp = LStrStr(pwszHeaders, L"Public: ");
if (pwszTemp == NULL)
{
pwszTemp = LStrStr(pwszHeaders, L"PUBLIC: ");
}
if (pwszTemp != NULL)
{
pwszTemp += 8;
this->_ParseDAVVerbs(pwszTemp, &pdavResponse->rOptions.dwDavMethodsPublic);
}
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandlePUTPOST(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR pwszPath,
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD cbSent,
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->rPut.pwszLocation = pwszPath;
pdavResponse->rPost.fResend = FALSE;
pdavResponse->rPost.cbIncrement = 0;
if (SUCCEEDED(pdavResponse->hrResult))
{
// we PUT ok, so return data about it
pdavResponse->rPut.cbCurrent = cbSent;
pdavResponse->rPut.cbTotal = cbSent;
}
else
{
// we failed to PUT, so say so
pdavResponse->rPost.cbCurrent = 0;
pdavResponse->rPost.cbTotal = 0;
}
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandlePUT(DAVRESPONSE* pdavResponse,
LPWSTR pwszVerb,
LPWSTR pwszPath,
DWORD cchHeaders,
LPWSTR pwszHeaders,
DWORD dwStatusCode,
LPWSTR pwszStatusCode,
LPWSTR pwszContentType,
DWORD cbSent,
LPBYTE pbResponse,
DWORD cbResponse)
{
pdavResponse->command = DAV_PUT;
return this->_RespondHandlePUTPOST(pdavResponse,
pwszVerb,
pwszPath,
cchHeaders,
pwszHeaders,
dwStatusCode,
pwszStatusCode,
pwszContentType,
cbSent,
pbResponse,
cbResponse);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandlePOST(DAVRESPONSE* pdavResponse,
LPWSTR pwszVerb,
LPWSTR pwszPath,
DWORD cchHeaders,
LPWSTR pwszHeaders,
DWORD dwStatusCode,
LPWSTR pwszStatusCode,
LPWSTR pwszContentType,
DWORD cbSent,
LPBYTE pbResponse,
DWORD cbResponse)
{
pdavResponse->command = DAV_POST;
return this->_RespondHandlePUTPOST(pdavResponse,
pwszVerb,
pwszPath,
cchHeaders,
pwszHeaders,
dwStatusCode,
pwszStatusCode,
pwszContentType,
cbSent,
pbResponse,
cbResponse);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleDELETE(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_DELETE;
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleMKCOL(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_MKCOL;
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleCOPY(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_COPY;
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CAsyncWntCallbackImpl::_RespondHandleMOVE(DAVRESPONSE* pdavResponse,
LPWSTR UNREF_PARAM(pwszVerb),
LPWSTR UNREF_PARAM(pwszPath),
DWORD UNREF_PARAM(cchHeaders),
LPWSTR UNREF_PARAM(pwszHeaders),
DWORD UNREF_PARAM(dwStatusCode),
LPWSTR UNREF_PARAM(pwszStatusCode),
LPWSTR UNREF_PARAM(pwszContentType),
DWORD UNREF_PARAM(cbSent),
LPBYTE UNREF_PARAM(pbResponse),
DWORD UNREF_PARAM(cbResponse))
{
HRESULT hres = S_OK;
pdavResponse->command = DAV_MOVE;
hres = _pcallback->OnResponse(pdavResponse);
return hres;
}