You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
316 lines
8.0 KiB
316 lines
8.0 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1996.
|
|
//
|
|
// File: HTTPNEG.CXX
|
|
//
|
|
// Contents: Code to handle multiplexing multiple concurrent
|
|
// IHttpNegotiate interfaces.
|
|
//
|
|
// Classes: CHttpNegHolder
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 01-30-96 JoeS (Joe Souza) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <urlint.h>
|
|
#include <urlmon.hxx>
|
|
#include "httpneg.hxx"
|
|
|
|
CHttpNegHolder::CHttpNegHolder(void) : _CRefs()
|
|
{
|
|
_pCHttpNegNode = NULL;
|
|
_cElements = 0;
|
|
}
|
|
|
|
STDMETHODIMP CHttpNegHolder::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
VDATEPTROUT(ppvObj, void *);
|
|
VDATETHIS(this);
|
|
HRESULT hr = NOERROR;
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::QueryInterface\n", this));
|
|
|
|
*ppvObj = NULL;
|
|
if (riid == IID_IHttpNegotiate)
|
|
{
|
|
*ppvObj = this;
|
|
AddRef();
|
|
}
|
|
else
|
|
{
|
|
hr = E_NOINTERFACE;
|
|
CHttpNegNode *pNode;
|
|
|
|
pNode = _pCHttpNegNode;
|
|
|
|
while (pNode)
|
|
{
|
|
hr = pNode->GetHttpNegotiate()->QueryInterface(riid, ppvObj);
|
|
|
|
if (hr == NOERROR)
|
|
{
|
|
pNode = NULL;
|
|
}
|
|
else
|
|
{
|
|
pNode = pNode->GetNextNode();
|
|
}
|
|
}
|
|
}
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::QueryInterface (hr:%lx\n", this,hr));
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CHttpNegHolder::AddRef(void)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddRef\n", this));
|
|
|
|
LONG lRet = ++_CRefs;
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddRef (cRefs:%ld)\n", this,lRet));
|
|
return lRet;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CHttpNegHolder::Release(void)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::Release\n", this));
|
|
UrlMkAssert((_CRefs > 0));
|
|
|
|
LONG lRet = --_CRefs;
|
|
|
|
if (_CRefs == 0)
|
|
{
|
|
RemoveAllNodes();
|
|
delete this;
|
|
}
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::Release (cRefs:%ld)\n",this,lRet));
|
|
return lRet;
|
|
}
|
|
|
|
HRESULT CHttpNegHolder::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders,
|
|
DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::BeginningTransaction (szURL:%ws, szHeaders:%ws)\n", this, szURL, szHeaders));
|
|
VDATETHIS(this);
|
|
HRESULT hr = NOERROR;
|
|
CHttpNegNode *pNode;
|
|
LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL;
|
|
|
|
pNode = _pCHttpNegNode;
|
|
|
|
while (pNode)
|
|
{
|
|
hr = pNode->GetHttpNegotiate()->BeginningTransaction(szURL, szHeaders, dwReserved, &szNew);
|
|
UrlMkDebugOut((DEB_BINDING, "%p === CHttpNegHolder::BeginningTransaction (szNew:%ws )\n", this, szNew));
|
|
|
|
if (hr == NOERROR && szNew != NULL && szRunning != NULL)
|
|
{
|
|
szTmp = szRunning;
|
|
szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1];
|
|
if (szRunning)
|
|
{
|
|
if (szTmp)
|
|
{
|
|
wcscpy(szRunning, szTmp);
|
|
wcscat(szRunning, szNew);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(szRunning, szNew);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
delete szTmp;
|
|
delete szNew;
|
|
|
|
if (hr != NOERROR)
|
|
{
|
|
goto BegTransExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szRunning = szNew;
|
|
}
|
|
|
|
pNode = pNode->GetNextNode();
|
|
}
|
|
|
|
*pszAdditionalHeaders = szRunning;
|
|
|
|
BegTransExit:
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::BeginningTransaction (pszAdditionalHeaders:%ws )\n", this, *pszAdditionalHeaders));
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CHttpNegHolder::OnResponse(DWORD dwResponseCode,LPCWSTR szResponseHeaders,
|
|
LPCWSTR szRequestHeaders,LPWSTR *pszAdditionalRequestHeaders)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::OnError\n", this));
|
|
VDATETHIS(this);
|
|
HRESULT hr = NOERROR;
|
|
CHttpNegNode *pNode;
|
|
LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL;
|
|
|
|
pNode = _pCHttpNegNode;
|
|
|
|
while (pNode)
|
|
{
|
|
hr = pNode->GetHttpNegotiate()->OnResponse(dwResponseCode, szResponseHeaders, szRequestHeaders, &szNew);
|
|
if (hr == NOERROR && szNew != NULL && szRunning != NULL)
|
|
{
|
|
szTmp = szRunning;
|
|
szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1];
|
|
if (szRunning)
|
|
{
|
|
if (szTmp)
|
|
{
|
|
wcscpy(szRunning, szTmp);
|
|
wcscat(szRunning, szNew);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(szRunning, szNew);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
delete szTmp;
|
|
delete szNew;
|
|
|
|
if (hr != NOERROR)
|
|
{
|
|
goto OnErrorExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szRunning = szNew;
|
|
}
|
|
|
|
pNode = pNode->GetNextNode();
|
|
}
|
|
|
|
*pszAdditionalRequestHeaders = szRunning;
|
|
|
|
if (hr == E_NOTIMPL)
|
|
{
|
|
hr = NOERROR;
|
|
}
|
|
|
|
OnErrorExit:
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::OnError\n", this));
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CHttpNegHolder::AddNode
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [pIHttpNeg] --
|
|
//
|
|
// Returns:
|
|
//
|
|
// History:
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CHttpNegHolder::AddNode(IHttpNegotiate *pIHttpNeg)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddNode \n", this));
|
|
HRESULT hr = NOERROR;
|
|
|
|
CHttpNegNode *pFirstNode = _pCHttpNegNode;
|
|
CHttpNegNode *pNode;
|
|
|
|
// Allocate memory for new pNode member.
|
|
|
|
pNode = new CHttpNegNode(pIHttpNeg);
|
|
|
|
if (!pNode)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p IN CHttpNegHolder::AddNode (New Node:%p, IHttpNeg:%p) \n",
|
|
this, pNode,pNode->GetHttpNegotiate() ));
|
|
|
|
// if a node is already
|
|
if (pFirstNode)
|
|
{
|
|
pNode->SetNextNode(pFirstNode);
|
|
}
|
|
|
|
// the new node is the first node
|
|
_pCHttpNegNode = pNode;
|
|
_cElements++;
|
|
}
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddNode (NewNode:%p, hr:%lx) \n", this, pNode, hr));
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CHttpNegHolder::RemoveAllNodes
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History:
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CHttpNegHolder::RemoveAllNodes(void)
|
|
{
|
|
UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::RemoveAllNodes\n", this));
|
|
HRESULT hr = S_OK;
|
|
|
|
CHttpNegNode *pNode = _pCHttpNegNode;
|
|
CHttpNegNode *pNextNode = NULL;
|
|
|
|
while (pNode)
|
|
{
|
|
pNextNode = pNode->GetNextNode();
|
|
|
|
// release the object
|
|
pNode->GetHttpNegotiate()->Release();
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (Delete Node:%p, IHttpNeg:%p) \n",
|
|
this, pNode, pNode->GetHttpNegotiate()));
|
|
delete pNode;
|
|
_cElements--;
|
|
|
|
pNode = pNextNode;
|
|
}
|
|
|
|
_pCHttpNegNode = NULL;
|
|
UrlMkAssert((_cElements == 0));
|
|
|
|
UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (hr:%lx) \n", this, hr));
|
|
return hr;
|
|
}
|
|
|
|
|