Leaked source code of windows server 2003
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.
 
 
 
 
 
 

3118 lines
74 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
http.hxx
Abstract:
Contains the client-side HTTP handle class
Author:
Richard L Firth (rfirth) 03-Jan-1996
Revision History:
03-Jan-1996 rfirth
Created
--*/
#pragma warning(disable: 4296)
//
// prototype for glue to urlmon security manager
//
DWORD GetCredPolicy (LPSTR pszUrl);
DWORD GetCookieUrlAction(BOOL fIsSessionCookie, BOOL fIs3rdPartyCookie);
DWORD GetCookiePolicy (LPCSTR pszUrl, DWORD dwUrlAction, BOOL fRestricted = FALSE);
VOID SetStopWarning (LPCSTR pszUrl, DWORD dwPolicy, DWORD dwUrlAction);
DWORD GetClientCertPromptPolicy (LPCSTR pszUrl, BOOL fRestricted = FALSE);
extern "C" DWORD GetZoneFromUrl(LPCSTR pszUrl);
//
// manifests
//
#define INITIAL_HEADERS_COUNT 16
#define HEADERS_INCREMENT 4
#define INVALID_HEADER_INDEX 0xff
#define INVALID_HEADER_SLOT 0xFFFFFFFF
#define HTTPREQ_STATE_ANYTHING_OK 0x8000 // for debug purposes
#define HTTPREQ_STATE_CLOSE_OK 0x4000
#define HTTPREQ_STATE_ADD_OK 0x2000
#define HTTPREQ_STATE_SEND_OK 0x1000
#define HTTPREQ_STATE_READ_OK 0x0800
#define HTTPREQ_STATE_QUERY_REQUEST_OK 0x0400
#define HTTPREQ_STATE_QUERY_RESPONSE_OK 0x0200
#define HTTPREQ_STATE_REUSE_OK 0x0100
#define HTTPREQ_STATE_WRITE_OK 0x0010
//
// macros
//
#define IS_VALID_HTTP_STATE(p, api, ref) \
(p)->CheckState(HTTPREQ_STATE_ ## api ## _OK)
#define IsValidHttpState(api) \
CheckState(HTTPREQ_STATE_ ## api ## _OK)
//
// STRESS_BUG_DEBUG - used to catch a specific stress fault,
// where we have a corrupted crit sec.
//
#define CLEAR_DEBUG_CRIT(x)
#define IS_DEBUG_CRIT_OK(x)
//
// types
//
typedef enum {
HTTP_HEADER_TYPE_UNKNOWN = 0,
HTTP_HEADER_TYPE_ACCEPT
} HTTP_HEADER_TYPE;
typedef enum {
HTTP_METHOD_TYPE_UNKNOWN = -1,
HTTP_METHOD_TYPE_FIRST = 0,
HTTP_METHOD_TYPE_GET= HTTP_METHOD_TYPE_FIRST,
HTTP_METHOD_TYPE_HEAD,
HTTP_METHOD_TYPE_POST,
HTTP_METHOD_TYPE_PUT,
HTTP_METHOD_TYPE_PROPFIND,
HTTP_METHOD_TYPE_PROPPATCH,
HTTP_METHOD_TYPE_LOCK,
HTTP_METHOD_TYPE_UNLOCK,
HTTP_METHOD_TYPE_COPY,
HTTP_METHOD_TYPE_MOVE,
HTTP_METHOD_TYPE_MKCOL,
HTTP_METHOD_TYPE_CONNECT,
HTTP_METHOD_TYPE_DELETE,
HTTP_METHOD_TYPE_LINK,
HTTP_METHOD_TYPE_UNLINK,
HTTP_METHOD_TYPE_BMOVE,
HTTP_METHOD_TYPE_BCOPY,
HTTP_METHOD_TYPE_BPROPFIND,
HTTP_METHOD_TYPE_BPROPPATCH,
HTTP_METHOD_TYPE_BDELETE,
HTTP_METHOD_TYPE_SUBSCRIBE,
HTTP_METHOD_TYPE_UNSUBSCRIBE,
HTTP_METHOD_TYPE_NOTIFY,
HTTP_METHOD_TYPE_POLL,
HTTP_METHOD_TYPE_CHECKIN,
HTTP_METHOD_TYPE_CHECKOUT,
HTTP_METHOD_TYPE_INVOKE,
HTTP_METHOD_TYPE_SEARCH,
HTTP_METHOD_TYPE_PIN,
HTTP_METHOD_TYPE_MPOST,
HTTP_METHOD_TYPE_LAST = HTTP_METHOD_TYPE_MPOST
} HTTP_METHOD_TYPE;
typedef enum {
//
// The request handle is in the process of being created
//
HttpRequestStateCreating = 0 | HTTPREQ_STATE_ANYTHING_OK,
//
// The request handle is open, but the request has not been sent to the
// server
//
HttpRequestStateOpen = 1 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_ADD_OK
| HTTPREQ_STATE_SEND_OK
| HTTPREQ_STATE_READ_OK
| HTTPREQ_STATE_QUERY_REQUEST_OK
| HTTPREQ_STATE_QUERY_RESPONSE_OK
| HTTPREQ_STATE_REUSE_OK
| HTTPREQ_STATE_ANYTHING_OK,
//
// The request has been sent to the server, but the response headers have
// not been received
//
HttpRequestStateRequest = 2 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_QUERY_REQUEST_OK
| HTTPREQ_STATE_WRITE_OK
| HTTPREQ_STATE_ANYTHING_OK,
//
// The response headers are being received, but not yet completed
//
HttpRequestStateResponse = 3 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_WRITE_OK
| HTTPREQ_STATE_ANYTHING_OK,
//
// The response headers have been received, and there is object data
// available to read
//
//
// QFE 3576: It's possible that we're init'ing a new request,
// but the previous request hasn't been drained yet.
// Since we know it will always be drained, the lowest
// impact change is to allow headers to be replaced
// if we're in a state with potential data left to receive.
HttpRequestStateObjectData = 4 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_ADD_OK
| HTTPREQ_STATE_READ_OK
| HTTPREQ_STATE_QUERY_REQUEST_OK
| HTTPREQ_STATE_QUERY_RESPONSE_OK
| HTTPREQ_STATE_REUSE_OK
| HTTPREQ_STATE_ANYTHING_OK,
//
// A fatal error occurred
//
HttpRequestStateError = 5 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_ANYTHING_OK,
//
// The request is closing
//
HttpRequestStateClosing = 6 | HTTPREQ_STATE_ANYTHING_OK,
//
// the data has been drained from the request object and it can be re-used
//
HttpRequestStateReopen = 7 | HTTPREQ_STATE_CLOSE_OK
| HTTPREQ_STATE_ADD_OK
| HTTPREQ_STATE_READ_OK
| HTTPREQ_STATE_QUERY_REQUEST_OK
| HTTPREQ_STATE_QUERY_RESPONSE_OK
| HTTPREQ_STATE_REUSE_OK
| HTTPREQ_STATE_ANYTHING_OK
} HTTPREQ_STATE, FAR * LPHTTPREQ_STATE;
//
// general prototypes
//
HTTP_METHOD_TYPE
MapHttpRequestMethod(
IN LPCSTR lpszVerb
);
DWORD
MapHttpMethodType(
IN HTTP_METHOD_TYPE tMethod,
OUT LPCSTR * lplpcszName
);
DWORD
CreateEscapedUrlPath(
IN LPSTR lpszUrlPath,
OUT LPSTR * lplpszEncodedUrlPath
);
#if INET_DEBUG
LPSTR
MapHttpMethodType(
IN HTTP_METHOD_TYPE tMethod
);
#endif
//
// forward references
//
class CFsm_HttpSendRequest;
class CFsm_MakeConnection;
class CFsm_OpenConnection;
class CFsm_OpenProxyTunnel;
class CFsm_SendRequest;
class CFsm_ReceiveResponse;
class CFsm_HttpReadData;
class CFsm_HttpWriteData;
class CFsm_ReadData;
class CFsm_HttpQueryAvailable;
class CFsm_DrainResponse;
class CFsm_Redirect;
class CFsm_ReadLoop;
struct P3PCookieState;
//
// classes
//
//
// HEADER_STRING - extension of ICSTRING so we can perform hashing on strings.
// Note that we only care about the header value
//
class HEADER_STRING : public ICSTRING {
private:
DWORD m_Hash;
public:
HEADER_STRING() {
SetHash(0);
}
~HEADER_STRING() {
}
VOID SetHash(DWORD dwHash) {
m_Hash = dwHash;
}
VOID SetNextKnownIndex(BYTE bNextKnown) {
_Union.Bytes.ExtraByte1 = bNextKnown;
}
BYTE * GetNextKnownIndexPtr() {
return &_Union.Bytes.ExtraByte1;
}
DWORD GetNextKnownIndex() {
return ((DWORD)_Union.Bytes.ExtraByte1);
}
DWORD GetHash(VOID) {
return m_Hash;
}
VOID CreateHash(LPSTR lpszBase);
int HashStrnicmp(LPSTR lpBase, LPSTR lpszString, DWORD dwLength, DWORD dwHash)
{
int RetVal = -1;
if ((m_Hash == 0) || (m_Hash == dwHash))
{
if ( Strnicmp(lpBase, lpszString, dwLength) == 0 )
{
LPSTR value;
value = StringAddress(lpBase) + dwLength;
//
// the input string could be a substring of a different header
//
if (*value == ':')
{
RetVal = 0; // success, we have a match here!
}
}
}
return RetVal;
}
HEADER_STRING & operator=(LPSTR String) {
SetHash(0);
return (HEADER_STRING &)ICSTRING::operator=(String);
}
};
//
// HTTP_HEADERS - array of pointers to general HTTP header strings. Headers are
// stored without line termination. _HeadersLength maintains the cumulative
// amount of buffer space required to store all the headers. Accounts for the
// missing line termination sequence
//
#define HTTP_HEADER_SIGNATURE 0x64616548 // "Head"
class HTTP_HEADERS {
public:
//
// _bKnownHeaders - array of bytes which index into lpHeaders
// the 0 column is an error catcher, so all indexes need to be biased by 1 (++'ed)
//
BYTE _bKnownHeaders[HTTP_QUERY_MAX+2];
private:
#if INET_DEBUG
DWORD _Signature;
#endif
//
// _lpHeaders - (growable) array of pointers to headers added by app
//
HEADER_STRING * _lpHeaders;
//
// _TotalSlots - number of pointers in (i.e. size of) _lpHeaders
//
DWORD _TotalSlots;
//
// _NextOpenSlot - offset where the next array is open for allocation
//
DWORD _NextOpenSlot;
//
// _FreeSlots - number of available headers in _lpHeaders
//
DWORD _FreeSlots;
//
// _HeadersLength - the amount of buffer space required to store the headers.
// For each header, includes +2 for the line termination that must be added
// when the header buffer is generated, or when the headers are queried
//
DWORD _HeadersLength;
//
// _IsRequestHeaders - TRUE if this HTTP_HEADERS object describes the
// request headers
//
BOOL _IsRequestHeaders;
//
// _lpszVerb etc. - in the case of request headers, we maintain these
// pointers and corresponding lengths to make modifying the request line
// easier in the case of a redirect
//
// N.B. The pointers are just offsets into the request line AND MUST NOT BE
// FREED
//
LPSTR _lpszVerb;
DWORD _dwVerbLength;
LPSTR _lpszObjectName;
DWORD _dwObjectNameLength;
LPSTR _lpszVersion;
DWORD _dwVersionLength;
DWORD _RequestVersionMajor;
DWORD _RequestVersionMinor;
//
// _Error - status code if error
//
DWORD _Error;
//
// _CritSec - acquire this when accessing header structure - stops multiple
// threads clashing while modifying headers
//
CRITICAL_SECTION _CritSec;
//
// private methods
//
DWORD
AllocateHeaders(
IN DWORD dwNumberOfHeaders
);
public:
HTTP_HEADERS() {
#if INET_DEBUG
_Signature = HTTP_HEADER_SIGNATURE;
#endif
CLEAR_DEBUG_CRIT(_szCritSecBefore);
CLEAR_DEBUG_CRIT(_szCritSecAfter);
InitializeCriticalSection(&_CritSec);
Initialize();
}
~HTTP_HEADERS() {
DEBUG_ENTER((DBG_OBJECTS,
None,
"~HTTP_HEADERS",
"%#x",
this
));
#if INET_DEBUG
INET_ASSERT(_Signature == HTTP_HEADER_SIGNATURE);
#endif
FreeHeaders();
DeleteCriticalSection(&_CritSec);
DEBUG_LEAVE(0);
}
VOID Initialize(VOID) {
_lpHeaders = NULL;
_TotalSlots = 0;
_FreeSlots = 0;
_HeadersLength = 0;
_lpszVerb = NULL;
_dwVerbLength = 0;
_lpszObjectName = NULL;
_dwObjectNameLength = 0;
_lpszVersion = NULL;
_dwVersionLength = 0;
_RequestVersionMajor = 0;
_RequestVersionMinor = 0;
_NextOpenSlot = 0;
memset((void *) _bKnownHeaders, INVALID_HEADER_SLOT, ARRAY_ELEMENTS(_bKnownHeaders));
_Error = AllocateHeaders(INITIAL_HEADERS_COUNT);
}
BOOL IsHeaderPresent(DWORD dwQueryIndex) const {
return (_bKnownHeaders[dwQueryIndex] != INVALID_HEADER_INDEX) ? TRUE : FALSE ;
}
VOID LockHeaders(VOID) {
EnterCriticalSection(&_CritSec);
}
VOID UnlockHeaders(VOID) {
LeaveCriticalSection(&_CritSec);
}
VOID
FreeHeaders(
VOID
);
VOID
CopyHeaders(
IN OUT LPSTR * lpBuffer,
IN LPSTR lpszObjectName,
IN DWORD dwObjectNameLength
);
#ifdef COMPRESSED_HEADERS
VOID
CopyCompressedHeaders(
IN OUT LPSTR * lpBuffer
);
#endif //COMPRESSED_HEADERS
HEADER_STRING *
FASTCALL
FindFreeSlot(
DWORD* piSlot
);
HEADER_STRING *
GetSlot(
DWORD iSlot
)
{
return &_lpHeaders[iSlot];
}
LPSTR GetHeaderPointer (LPBYTE pbBase, DWORD iSlot)
{
INET_ASSERT (iSlot < _TotalSlots);
return _lpHeaders[iSlot].StringAddress((LPSTR) pbBase);
}
VOID
ShrinkHeader(
LPBYTE pbBase,
DWORD iSlot,
DWORD dwOldQueryIndex,
DWORD dwNewQueryIndex,
DWORD cbNewSize
);
DWORD
inline
FastFind(
IN DWORD dwQueryIndex,
IN DWORD dwIndex
);
DWORD
inline
FastNukeFind(
IN DWORD dwQueryIndex,
IN DWORD dwIndex,
OUT BYTE **lplpbPrevIndex
);
DWORD
inline
SlowFind(
IN LPSTR lpBase,
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN DWORD dwIndex,
IN DWORD dwHash,
OUT DWORD *lpdwQueryIndex,
OUT BYTE **lplpbPrevIndex
);
BYTE
inline
FastAdd(
IN DWORD dwQueryIndex,
IN DWORD dwSlot
);
BOOL
inline
HeaderMatch(
IN DWORD dwHash,
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
OUT DWORD *lpdwQueryIndex
);
VOID
RemoveAllByIndex(
IN DWORD dwQueryIndex
);
VOID RemoveHeader(IN DWORD dwIndex, IN DWORD dwQueryIndex, IN BYTE *pbPrevByte) {
INET_ASSERT(dwIndex < _TotalSlots);
INET_ASSERT(dwIndex != 0);
// INET_ASSERT(_HeadersLength > 2);
INET_ASSERT(_lpHeaders[dwIndex].StringLength() > 2);
INET_ASSERT(_FreeSlots <= _TotalSlots);
//
// remove the length of the header + 2 for CR-LF from the total headers
// length
//
if (_HeadersLength) {
_HeadersLength -= _lpHeaders[dwIndex].StringLength()
+ (sizeof("\r\n") - 1)
;
}
//
// Update the cached known headers, if this is one.
//
if ( dwQueryIndex < INVALID_HEADER_INDEX )
{
*pbPrevByte = (BYTE) _lpHeaders[dwIndex].GetNextKnownIndex();
}
//
// set the header string to NULL. Frees the header buffer
//
_lpHeaders[dwIndex] = (LPSTR)NULL;
//
// we have freed a slot in the headers array
//
if ( _FreeSlots == 0 )
{
_NextOpenSlot = dwIndex;
}
++_FreeSlots;
INET_ASSERT(_FreeSlots <= _TotalSlots);
}
DWORD GetSlotsInUse (void) {
return _TotalSlots - _FreeSlots;
}
DWORD HeadersLength(VOID) const {
return _HeadersLength;
}
DWORD ObjectNameLength(VOID) const {
return _dwObjectNameLength;
}
LPSTR ObjectName(VOID) const {
return _lpszObjectName;
}
DWORD
AddHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
);
DWORD
AddHeader(
IN DWORD dwQueryIndex,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
);
DWORD
ReplaceHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
);
DWORD
ReplaceHeader(
IN DWORD dwQueryIndex,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
);
DWORD
FindHeader(
IN LPSTR lpBase,
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN DWORD dwModifiers,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT LPDWORD lpdwIndex
);
DWORD
FindHeader(
IN LPSTR lpBase,
IN DWORD dwQueryIndex,
IN DWORD dwModifiers,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT LPDWORD lpdwIndex
);
DWORD
FastFindHeader(
IN LPSTR lpBase,
IN DWORD dwQueryIndex,
OUT LPVOID *lplpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT DWORD dwIndex
);
DWORD
QueryRawHeaders(
IN LPSTR lpBase,
IN BOOL bCrLfTerminated,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
DWORD
QueryFilteredRawHeaders(
IN LPSTR lpBase,
IN LPSTR *lplpFilterList,
IN DWORD cListElements,
IN BOOL fExclude,
IN BOOL fSkipVerb,
IN BOOL bCrLfTerminated,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
DWORD
AddRequest(
IN LPSTR lpszVerb,
IN LPSTR lpszObjectName,
IN LPSTR lpszVersion
);
DWORD
ModifyRequest(
IN HTTP_METHOD_TYPE tMethod,
IN LPSTR lpszObjectName,
IN DWORD dwObjectNameLength,
IN LPSTR lpszVersion OPTIONAL,
IN DWORD dwVersionLength
);
HEADER_STRING * GetFirstHeader(VOID) const {
INET_ASSERT(_lpHeaders != NULL);
return _lpHeaders;
}
HEADER_STRING * GetEmptyHeader(VOID) const {
for (DWORD i = 0; i < _TotalSlots; ++i) {
if (_lpHeaders[i].HaveString() && _lpHeaders[i].StringLength() == 0) {
return &_lpHeaders[i];
}
}
return NULL;
}
VOID SetIsRequestHeaders(BOOL bRequestHeaders) {
_IsRequestHeaders = bRequestHeaders;
}
DWORD GetError(VOID) const {
return _Error;
}
LPSTR GetVerb(LPDWORD lpdwVerbLength) const {
*lpdwVerbLength = _dwVerbLength;
return _lpszVerb;
}
//VOID SetRequestVersion(DWORD dwMajor, DWORD dwMinor) {
// _RequestVersionMajor = dwMajor;
// _RequestVersionMinor = dwMinor;
//}
VOID
SetRequestVersion(
VOID
);
DWORD MajorVersion(VOID) const {
return _RequestVersionMajor;
}
DWORD MinorVersion(VOID) const {
return _RequestVersionMinor;
}
DWORD QueryRequestVersion(
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
};
// class HTTP_HEADER_PARSER
//
// Retrieves HTTP headers from string containing server response headers.
//
class HTTP_HEADER_PARSER : public HTTP_HEADERS
{
public:
HTTP_HEADER_PARSER(
LPSTR lpszHeaders,
DWORD cbHeaders
);
HTTP_HEADER_PARSER()
: HTTP_HEADERS() {}
DWORD
ParseHeaders(
IN LPSTR lpHeaderBase,
IN DWORD dwBufferLength,
IN BOOL fEof,
IN OUT DWORD *lpdwBufferLengthScanned,
OUT LPBOOL pfFoundCompleteLine,
OUT LPBOOL pfFoundEndOfHeaders
);
DWORD
ParseStatusLine(
IN LPSTR lpHeaderBase,
IN DWORD dwBufferLength,
IN BOOL fEof,
IN OUT DWORD *lpdwBufferLengthScanned,
OUT BOOL *lpfNeedMoreBuffer,
OUT DWORD *lpdwStatusCode,
OUT DWORD *lpdwMajorVersion,
OUT DWORD *lpdwMinorVersion
);
};
//
// flags for AddHeader
//
#define CLEAN_HEADER 0x00000001 // if set, header should be cleaned up
#define ADD_HEADER_IF_NEW HTTP_ADDREQ_FLAG_ADD_IF_NEW // only add the header if it doesn't already exist
#define ADD_HEADER HTTP_ADDREQ_FLAG_ADD // if replacing and header not found, add it
#define COALESCE_HEADER_WITH_COMMA HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA // headers of the same name will be coalesced
#define COALESCE_HEADER_WITH_SEMICOLON HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON // headers of the same name will be coalesced
#define REPLACE_HEADER HTTP_ADDREQ_FLAG_REPLACE // not currently used internally
/*++
Class Description:
This class defines the HTTP_REQUEST_HANDLE_OBJECT.
Private Member functions:
None.
Public Member functions:
GetHandle : Virtual function that gets the service handle value from
the generic object handle.
--*/
class HTTP_REQUEST_HANDLE_OBJECT : public INTERNET_CONNECT_HANDLE_OBJECT {
friend class PASSPORT_CTX;
private:
DWORD m_AuthFlag;
BOOL m_fPPAbortSend;
LIST_ENTRY m_PipelineList;
//
// m_lPriority - relative priority used to determine which request gets the
// next available connection
//
LONG m_lPriority;
//
// _Socket - this is the socket we are using for this request. It may be a
// pre-existing keep-alive connection or a new connection (not necessarily
// keep-alive)
//
ICSocket * _Socket;
//
// _bKeepAliveConnection - if TRUE, _Socket is keep-alive, else we must
// really close it
//
BOOL _bKeepAliveConnection;
//
// _bNoLongerKeepAlive - if this ever gets set to TRUE its because we began
// with a keep-alive connection which reverted to non-keep-alive when the
// server responded with no "(Proxy-)Connection: Keep-Alive" header
//
BOOL _bNoLongerKeepAlive;
//
// _QueryBuffer - buffer used to query socket data available
//
LPVOID _QueryBuffer;
//
// _QueryBufferLength - length of _QueryBuffer
//
DWORD _QueryBufferLength;
//
// _QueryOffset - offset of next read from _QueryBuffer
//
DWORD _QueryOffset;
//
// _QueryBytesAvailable - number of bytes we think are available for this
// socket in the query buffer
//
DWORD _QueryBytesAvailable;
//
// _OpenFlags - flags specified in HttpOpenRequest()
//
DWORD _OpenFlags;
//
// _State - the HTTP request/response state
//
HTTPREQ_STATE _State;
//
// HTTP request information
//
//
// _RequestHeaders - collection of request headers, including the request
// line
//
HTTP_HEADERS _RequestHeaders;
//
// _RequestMethod - (known) method used to make HTTP request
//
HTTP_METHOD_TYPE _RequestMethod;
//
// Values for optional data saved offin handle when in negotiate stage.
//
DWORD _dwOptionalSaved;
LPVOID _lpOptionalSaved;
BOOL _fOptionalSaved;
//
// HTTP response information
//
//
// _ResponseHeaders - collection of response headers, including the status
// line
//
HTTP_HEADER_PARSER _ResponseHeaders;
//
// In the case of response headers, remember slot number for
// Content-Length and Content-Range in case we need to fix up
// a 206 partial content response.
//
DWORD _iSlotContentLength;
DWORD _iSlotContentRange;
//
// _StatusCode - return status from the server
//
DWORD _StatusCode;
//
// _ResponseBuffer - pointer to the buffer containing part or all of
// response, starting with headers (if >= HTTP/1.0, i.e. if IsUpLevel)
//
LPBYTE _ResponseBuffer;
//
// _ResponseBufferLength - length of _ResponseBuffer
//
DWORD _ResponseBufferLength;
//
// _BytesReceived - number of bytes received into _ResponseBuffer
//
DWORD _BytesReceived;
//
// _ResponseScanned - amount of response buffers scanned for eof headers
//
DWORD _ResponseScanned;
//
// _ResponseBufferDataReadyToRead - special length of response buffer,
// set if we've parsed it from a chunk-transfer stream, this will be
// the correct length
//
DWORD _ResponseBufferDataReadyToRead;
//
// _DataOffset - the offset in _ResponseBuffer at which the response data
// starts (data after headers)
//
DWORD _DataOffset;
//
// _BytesRemaining - number of _ContentLength bytes remaining to be read by
// application
//
DWORD _BytesRemaining;
//
// _ContentLength - as parsed from the response headers
//
DWORD _ContentLength;
//
// _BytesInSocket - if content-length, the number of bytes we have yet to
// receive from the socket
//
DWORD _BytesInSocket;
//
// time stamps parsed from response
//
FILETIME _ftLastModified;
FILETIME _ftExpires;
FILETIME _ftPostCheck;
//
// to use when committing to cache
//
DWORD _dwCacheEntryType;
//
// cache lookup struct
//
CACHE_ENTRY_INFOEX* _pCacheEntryInfo;
//
// _ctChunkInfo - Chunk Info for tracking a chunk stream.
//
CHUNK_TRANSFER _ctChunkInfo;
//
// _fTalkingToSecureServerViaProxy - We're talking SSL, but
// actually we're connected through a proxy so things
// need to be carefully watched. Don't send a Proxy
// Username and Password to the the secure sever.
//
BOOL _fTalkingToSecureServerViaProxy;
//
// _fRequestUsingProxy - TRUE if we're actually using the proxy
// to reach the server. Needed to keep track of whether
// we're using the proxy or not.
//
BOOL _fRequestUsingProxy;
//
// _bWantKeepAlive - TRUE if we want a keep-alive connection
//
BOOL _bWantKeepAlive;
//
// _bRefresh - TRUE if the response contains a "Refresh" header
//
BOOL _bRefresh;
//
// _RefreshHeader - value from the "Refresh" header, if it exists
//
HEADER_STRING _RefreshHeader;
//
// _dwQuerySetCookieHeader - Passed to HttpQueryInfo to track what
// cookie header we're parsing.
//
DWORD _dwQuerySetCookieHeader;
//
// _Union - get at flags individually, or as DWORD so they can be zapped
//
union {
//
// Flags - several bits of information gleaned from the response, such
// as whether the server responded with a "connection: keep-alive", etc.
//
struct {
DWORD Eof : 1; // we have received all response
DWORD DownLevel : 1; // response is HTTP/0.9
DWORD UpLevel : 1; // response is HTTP/1.0 or greater
DWORD Http1_1Response : 1; // response is HTTP/1.1 or greater
DWORD MustRevalidate : 1; // response contains cache-control: must-revalidate
DWORD KeepAlive : 1; // response contains keep-alive header
DWORD ConnCloseResponse : 1; // response contains connection: close header
DWORD PersistServer : 1; // have persistent connection to server
DWORD PersistProxy : 1; // have persistent connection to proxy
DWORD Data : 1; // set if we have got to the data part
DWORD ContentLength : 1; // set if we have parsed Content-Length
DWORD ChunkEncoding : 1; // set if we have parsed a Transfer-Encoding: chunked
DWORD AutoSync : 1; // set when synchronizing due to sync-mode
DWORD BadNSServer : 1; // set when server is bogus NS 1.1
DWORD ConnCloseChecked : 1; // set when we have checked for Connection: Close
DWORD ConnCloseReq : 1; // set if Connection: Close in request headers
DWORD ProxyConnCloseReq : 1; // set if Proxy-Connection: Close in request headers
//DWORD CookieUI : 1; // set if we're doing Cookie UI
} Flags;
//
// Dword - used in initialization and ReuseObject
//
DWORD Dword;
} _Union;
//
// Filter, authentication related members.
//
AUTHCTX* _pAuthCtx; // authentication context
AUTHCTX* _pTunnelAuthCtx; // context for nested request
PWC* _pPWC; // PWC* for Basic, Digest authctxt
LPVOID _lpBlockingFilter; // filter that requested UI
DWORD _dwCredPolicy; // zone policy on use of credentials
union {
struct {
// AuthState: none, negotiate, challenge, or need tunnel.
DWORD AuthState : 2;
// TRUE if KA socket should be flushed with password cache.
DWORD IsAuthorized : 1;
// TRUE if request has been processed once.
DWORD FirstSendProcessed : 1;
// TRUE if client added header that implies no caching.
DWORD CacheReadDisabled : 1;
// TRUE if this handle should ignore general proxy settings,
// and use the proxy found in this object
DWORD OverrideProxyMode : 1;
// TRUE, if we are using a proxy to create a tunnel.
DWORD IsTunnel : 1;
// TRUE, if the object was originally "/"
DWORD IsObjectRoot : 1;
// TRUE, if a method body is to be transmitted.
DWORD MethodBody : 1;
// TRUE, if NTLM preauth is to be disabled.
DWORD DisableNTLMPreauth : 1;
} Flags;
//
// Dword - used in initialization ONLY, do NOT use ELSEWHERE !
//
DWORD Dword;
} _NoResetBits;
//
// Proxy, and Socks Proxy Information, used to decide if need to go through
// a proxy, a socks proxy, or no proxy at all (NULLs).
//
LPSTR _ProxyHostName;
DWORD _ProxyHostNameLength;
INTERNET_PORT _ProxyPort;
LPSTR _SocksProxyHostName;
DWORD _SocksProxyHostNameLength;
INTERNET_PORT _SocksProxyPort;
//
// _ProxySchemeType - Used to determine the proxy scheme, in proxy override mode.
//
//INTERNET_SCHEME _ProxySchemeType;
//
// InternetReadFileEx data
//
#ifndef unix
DWORD _ReadFileExData;
#else
BYTE _ReadFileExData;
#endif /* unix */
BOOL _HaveReadFileExData;
INTERNET_BUFFERS _BuffersOut;
//
// _redirectCount - The number of times we've redirected on this request
//
DWORD _redirectCount;
//
// _redirectCountedOut - TRUE if we redirected too many times.
//
BOOL _redirectCountedOut;
//
// _AddCRLFToPost - TRUE if we need to add a CRLF to the POST.
//
BOOL _AddCRLFToPOST;
//
// info we used to keep in the secure socket object
//
SECURITY_CACHE_LIST_ENTRY *m_pSecurityInfo;
// To support authentication of proxy auto config scripts,
// each request should only be able to try fetching the script
// just once.
BOOL _fAutoProxyChecked;
//
// _RTT - round-trip time for this request
//
DWORD _RTT;
//
// _CP - code page to use for char width conversions
//
UINT _CP;
//
// _fIgnore Offline - ignore global offline (enable loopback)
//
BOOL _fIgnoreOffline;
//
// _f3rdPartyCookies - treat cookies as 3rd party, that is as originating
// from a host other than the 'root', downloaded seperately
//
BOOL _f3rdPartyCookies;
// Is the current request blocked on prompt?
BOOL _fBlockedOnPrompt;
// _fSendUTF8ServerNameToProxy - app always sends MBCS to wininet for servername.
// If app. wants wininet to convert this to UTF8 for the proxy.
BOOL _fSendUTF8ServerNameToProxy;
// Security-zone for this request
DWORD _dwSecurityZone;
// SocketSendBufferLength
DWORD _dwSocketSendBufferLength;
//
// private response functions
//
PRIVATE
BOOL
FindEndOfHeader(
IN OUT LPSTR * lpszResponse,
IN LPSTR lpszEnd,
OUT LPDWORD lpdwHeaderLength
);
PRIVATE
VOID
CheckForWellKnownHeader(
IN LPSTR lpszHeader,
IN DWORD dwHeaderLength,
IN DWORD iSlot
);
PRIVATE
VOID
CheckWellKnownHeaders(
VOID
);
HANDLE GetDownloadFileReadHandle (VOID) {
if (_CacheFileHandleRead == INVALID_HANDLE_VALUE) {
_CacheFileHandleRead = CreateFile( _CacheFileName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
}
return _CacheFileHandleRead;
}
VOID ZapFlags(VOID) {
//
// clear out all bits
//
_Union.Dword = 0;
}
public:
HTTP_REQUEST_HANDLE_OBJECT(
INTERNET_CONNECT_HANDLE_OBJECT *Parent,
HINTERNET Child,
CLOSE_HANDLE_FUNC wCloseFunc,
DWORD dwFlags,
DWORD_PTR dwContext
);
virtual ~HTTP_REQUEST_HANDLE_OBJECT(VOID);
virtual HINTERNET GetHandle(VOID);
virtual HINTERNET_HANDLE_TYPE GetHandleType(VOID) {
return TypeHttpRequestHandle;
}
//
// request headers functions
//
DWORD
AddRequest(
IN LPSTR lpszVerb,
IN LPSTR lpszObjectName,
IN LPSTR lpszVersion
) {
return _RequestHeaders.AddRequest(lpszVerb,
lpszObjectName,
lpszVersion
);
}
DWORD
ModifyRequest(
IN HTTP_METHOD_TYPE tMethod,
IN LPSTR lpszObjectName,
IN DWORD dwObjectNameLength,
IN LPSTR lpszVersion OPTIONAL,
IN DWORD dwVersionLength
) {
DWORD error;
error = _RequestHeaders.ModifyRequest(tMethod,
lpszObjectName,
dwObjectNameLength,
lpszVersion,
dwVersionLength
);
if (error == ERROR_SUCCESS) {
SetMethodType(tMethod);
}
return error;
}
BOOL PPAbort(void) const {
return m_fPPAbortSend;
}
VOID SetPPAbort(BOOL fToAbort) {
m_fPPAbortSend = fToAbort;
}
VOID SetMethodType(IN LPCSTR lpszVerb) {
_RequestMethod = MapHttpRequestMethod(lpszVerb);
}
VOID SetMethodType(IN HTTP_METHOD_TYPE tMethod) {
_RequestMethod = tMethod;
}
HTTP_METHOD_TYPE GetMethodType(VOID) const {
return _RequestMethod;
}
LPSTR
CreateRequestBuffer(
OUT LPDWORD lpdwRequestLength,
IN LPVOID lpOptional,
IN DWORD dwOptionalLength,
IN BOOL bExtraCrLf,
IN DWORD dwMaxPacketLength,
OUT LPBOOL lpbCombinedData
);
DWORD
AddRequestHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
) {
return _RequestHeaders.AddHeader(lpszHeaderName,
dwHeaderNameLength,
lpszHeaderValue,
dwHeaderValueLength,
dwIndex,
dwFlags
);
}
DWORD
AddRequestHeader(
IN DWORD dwQueryIndex,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
) {
return _RequestHeaders.AddHeader(dwQueryIndex,
lpszHeaderValue,
dwHeaderValueLength,
dwIndex,
dwFlags
);
}
DWORD
ReplaceRequestHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
) {
return _RequestHeaders.ReplaceHeader(lpszHeaderName,
dwHeaderNameLength,
lpszHeaderValue,
dwHeaderValueLength,
dwIndex,
dwFlags
);
}
DWORD
ReplaceRequestHeader(
IN DWORD dwQueryIndex,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags
) {
return _RequestHeaders.ReplaceHeader(dwQueryIndex,
lpszHeaderValue,
dwHeaderValueLength,
dwIndex,
dwFlags
);
}
DWORD
QueryRequestHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN DWORD dwModifiers,
IN OUT LPDWORD lpdwIndex
);
DWORD
QueryRequestHeader(
IN DWORD dwQueryIndex,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN DWORD dwModifiers,
IN OUT LPDWORD lpdwIndex
);
//
// response headers functions
//
DWORD
ReplaceResponseHeader(
IN DWORD dwQueryIndex,
IN LPSTR lpszHeaderValue,
IN DWORD dwHeaderValueLength,
IN DWORD dwIndex,
IN DWORD dwFlags)
{
return _ResponseHeaders.ReplaceHeader(dwQueryIndex,
lpszHeaderValue,
dwHeaderValueLength,
dwIndex,
dwFlags
);
}
DWORD
AddInternalResponseHeader(
IN DWORD dwHeaderIndex,
IN LPSTR lpszHeader,
IN DWORD dwHeaderLength
);
DWORD
UpdateResponseHeaders(
IN OUT LPBOOL lpbEof
);
DWORD
CreateResponseHeaders(
IN OUT LPSTR* ppszBuffer,
IN DWORD dwBufferLength
);
DWORD
FindResponseHeader(
IN LPSTR lpszHeaderName,
OUT LPSTR lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
DWORD
QueryResponseVersionDword(
IN OUT LPDWORD lpdwVersionMajor,
IN OUT LPDWORD lpdwVersionMinor
);
DWORD
QueryResponseVersion(
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
DWORD
QueryStatusCode(
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN DWORD dwModifiers
);
DWORD
QueryStatusText(
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
DWORD
FastQueryResponseHeader(
IN DWORD dwQueryIndex,
OUT LPVOID *lplpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT DWORD dwIndex
)
{
return _ResponseHeaders.FastFindHeader(
(LPSTR)_ResponseBuffer,
dwQueryIndex,
lplpBuffer,
lpdwBufferLength,
dwIndex
);
}
DWORD
FastQueryRequestHeader(
IN DWORD dwQueryIndex,
OUT LPVOID *lplpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT DWORD dwIndex
)
{
return _RequestHeaders.FastFindHeader(
(LPSTR)_ResponseBuffer,
dwQueryIndex,
lplpBuffer,
lpdwBufferLength,
dwIndex
);
}
DWORD
QueryResponseHeader(
IN LPSTR lpszHeaderName,
IN DWORD dwHeaderNameLength,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN DWORD dwModifiers,
IN OUT LPDWORD lpdwIndex
)
{
//
// this is the slow manner for finding a header, avoid doing this by calling
// the faster method
//
return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
lpszHeaderName,
dwHeaderNameLength,
dwModifiers,
lpBuffer,
lpdwBufferLength,
lpdwIndex
);
}
DWORD
QueryResponseHeader(
IN DWORD dwQueryIndex,
IN LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN DWORD dwModifiers,
IN OUT LPDWORD lpdwIndex
)
{
return _ResponseHeaders.FindHeader((LPSTR)_ResponseBuffer,
dwQueryIndex,
dwModifiers,
lpBuffer,
lpdwBufferLength,
lpdwIndex
);
}
BOOL IsResponseHeaderPresent(DWORD dwQueryIndex) const {
return _ResponseHeaders.IsHeaderPresent(dwQueryIndex);
}
BOOL IsRequestHeaderPresent(DWORD dwQueryIndex) const {
return _RequestHeaders.IsHeaderPresent(dwQueryIndex);
}
DWORD
QueryRawResponseHeaders(
IN BOOL bCrLfTerminated,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
HEADER_STRING * GetStatusLine(VOID) const {
//
// _StatusLine is just a reference for the first response header
//
return _ResponseHeaders.GetFirstHeader();
}
//
// general headers methods
//
DWORD
QueryInfo(
IN DWORD dwInfoLevel,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength,
IN OUT LPDWORD lpdwIndex
);
DWORD
QueryFilteredRawResponseHeaders(
LPSTR *lplpFilterList,
DWORD cListElements,
BOOL fExclude,
BOOL fSkipVerb,
BOOL bCrLfTerminated,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
)
{
return (_ResponseHeaders.QueryFilteredRawHeaders(
(LPSTR)_ResponseBuffer,
lplpFilterList,
cListElements,
fExclude,
fSkipVerb,
bCrLfTerminated,
lpBuffer,
lpdwBufferLength));
};
DWORD
QueryRequestHeadersWithEcho(
BOOL bCrLfTerminated,
OUT LPVOID lpBuffer,
IN OUT LPDWORD lpdwBufferLength
);
//
// connection-oriented methods
//
DWORD
InitBeginSendRequest(
IN LPCSTR lpszHeaders OPTIONAL,
IN DWORD dwHeadersLength,
IN LPVOID *lplpOptional,
IN LPDWORD lpdwOptionalLength,
IN DWORD dwOptionalLengthTotal,
OUT LPBOOL pfGoneOffline
);
DWORD
QueueAsyncSendRequest(
IN LPVOID lpOptional OPTIONAL,
IN DWORD dwOptionalLength,
IN AR_TYPE arRequest,
IN FARPROC lpfpAsyncCallback
);
DWORD
HttpBeginSendRequest(
IN LPVOID lpOptional OPTIONAL,
IN DWORD dwOptionalLength
);
DWORD
HttpEndSendRequest(
VOID
);
DWORD
SockConnect(
IN LPSTR TargetServer,
IN INTERNET_PORT TcpipPort,
IN LPSTR SocksHostName,
IN INTERNET_PORT SocksPort
);
DWORD
OpenConnection(
IN BOOL NoKeepAlive,
IN BOOL fNoCreate = FALSE
);
DWORD
OpenConnection_Fsm(
IN CFsm_OpenConnection * Fsm
);
DWORD
CloseConnection(
IN BOOL ForceClosed
);
VOID
ReleaseConnection(
IN BOOL bClose,
IN BOOL bIndicate,
IN BOOL bDelete
);
DWORD
AbortConnection(
IN BOOL bForce
);
DWORD
OpenProxyTunnel(
VOID
);
DWORD
OpenProxyTunnel_Fsm(
IN CFsm_OpenProxyTunnel * Fsm
);
DWORD
CloneResponseBuffer(
IN HTTP_REQUEST_HANDLE_OBJECT *pChildRequestObj
);
DWORD
CloneResponseBuffer(
IN LPBYTE pBuffer,
IN DWORD dwBufferLen
);
DWORD
HttpReadData_Fsm(
IN CFsm_HttpReadData * Fsm
);
DWORD
HttpWriteData_Fsm(
IN CFsm_HttpWriteData * Fsm
);
DWORD
ReadResponse(
VOID
);
DWORD
ReadData(
OUT LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToRead,
OUT LPDWORD lpdwNumberOfBytesRead,
IN BOOL fNoAsync,
IN DWORD dwSocketFlags
);
DWORD
ReadData_Fsm(
IN CFsm_ReadData * Fsm
);
DWORD
WriteData(
OUT LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToWrite,
OUT LPDWORD lpdwNumberOfBytesWritten
);
DWORD
QueryDataAvailable(
OUT LPDWORD lpdwNumberOfBytesAvailable
);
DWORD
QueryAvailable_Fsm(
IN CFsm_HttpQueryAvailable * Fsm
);
DWORD
DrainResponse(
OUT LPBOOL lpbDrained
);
DWORD
DrainResponse_Fsm(
IN CFsm_DrainResponse * Fsm
);
DWORD
LocalEndCacheWrite(
IN BOOL fNormal
);
VOID
GetTimeStampsForCache(
OUT LPFILETIME lpftExpiryTime,
OUT LPFILETIME lpftLastModTime,
OUT LPFILETIME lpftPostCheckTime,
OUT LPBOOL lpfHasExpiry,
OUT LPBOOL lpfHasLastModTime,
OUT LPBOOL lpfHasPostCheck
);
BOOL IsPartialResponseCacheable (void);
DWORD
Redirect(
IN HTTP_METHOD_TYPE tMethod,
IN BOOL fRedirectToProxy
);
DWORD
Redirect_Fsm(
IN CFsm_Redirect * Fsm
);
DWORD
BuildProxyMessage(
IN CFsm_HttpSendRequest * Fsm,
AUTO_PROXY_ASYNC_MSG * pProxyMsg,
IN OUT URL_COMPONENTS * pUrlComponents
);
DWORD
QueryProxySettings(
IN CFsm_HttpSendRequest * Fsm,
INTERNET_HANDLE_OBJECT * pInternet,
IN OUT URL_COMPONENTS * pUrlComponents
);
DWORD
CheckForCachedProxySettings(
IN AUTO_PROXY_ASYNC_MSG *pProxyMsg,
OUT CServerInfo **ppProxyServerInfo
);
DWORD
ProcessProxySettings(
IN CFsm_HttpSendRequest * Fsm,
IN INTERNET_CONNECT_HANDLE_OBJECT * pConnect,
IN OUT URL_COMPONENTS * pUrlComponents,
OUT LPSTR * lplpszRequestObject,
OUT DWORD * lpdwRequestObjectSize
);
DWORD
UpdateRequestInfo(
IN CFsm_HttpSendRequest * Fsm,
IN LPSTR lpszObject,
IN DWORD dwcbObject,
IN OUT URL_COMPONENTS * pUrlComponents,
IN OUT CServerInfo **ppProxyServerInfo
);
DWORD
UpdateProxyInfo(
IN CFsm_HttpSendRequest * Fsm,
IN BOOL fCallback
);
BOOL
FindConnCloseRequestHeader(
IN DWORD dwHeaderIndex
);
VOID
RemoveGzipDeflateEncHeader(
VOID
);
VOID
RemoveAllRequestHeadersByName(
IN DWORD dwQueryIndex
);
//
// response buffer/data methods
//
BOOL IsBufferedData(VOID) {
BOOL fIsBufferedData;
//INET_ASSERT(IsData());
fIsBufferedData = (_DataOffset < _BytesReceived) ? TRUE : FALSE;
if ( fIsBufferedData &&
IsChunkEncoding() &&
_ResponseBufferDataReadyToRead == 0 )
{
fIsBufferedData = FALSE;
}
return (fIsBufferedData);
}
DWORD BufferedDataLength(VOID) {
return (DWORD)(_BytesReceived - _DataOffset);
}
DWORD BufferDataAvailToRead(VOID) {
return ( IsChunkEncoding() ) ? _ResponseBufferDataReadyToRead : BufferedDataLength() ;
}
VOID ReduceDataAvailToRead(DWORD dwReduceBy)
{
if ( IsChunkEncoding() )
{
_ResponseBufferDataReadyToRead -= dwReduceBy;
}
//else
//{
_DataOffset += dwReduceBy;
//}
}
LPVOID BufferedDataStart(VOID) {
return (LPVOID)(_ResponseBuffer + _DataOffset);
}
VOID SetCookieQuery(DWORD QueryIndex) {
_dwQuerySetCookieHeader = QueryIndex;
}
DWORD GetCookieQuery(VOID) const {
return _dwQuerySetCookieHeader;
}
VOID SetContentLength(DWORD ContentLength) {
_ContentLength = ContentLength;
}
DWORD GetContentLength(VOID) const {
return _ContentLength;
}
DWORD GetBytesInSocket(VOID) const {
return _BytesInSocket;
}
DWORD GetBytesRemaining(VOID) const {
return _BytesRemaining;
}
DWORD GetStatusCode(VOID) const {
return _StatusCode;
}
void SetStatusCode(DWORD StatusCode) {
_StatusCode = StatusCode;
}
VOID SetRefreshHeader(LPSTR Header, DWORD Length) {
_RefreshHeader.MakeCopy(Header, Length);
}
HEADER_STRING & GetRefreshHeader(VOID) {
return _RefreshHeader;
}
VOID FreeResponseBuffer(VOID) {
if (_ResponseBuffer != NULL) {
_ResponseBuffer = (LPBYTE)FREE_MEMORY((HLOCAL)_ResponseBuffer);
INET_ASSERT(_ResponseBuffer == NULL);
}
_ResponseBufferLength = 0;
_BytesReceived = 0;
_DataOffset = 0;
}
VOID FreeQueryBuffer(VOID) {
if (_QueryBuffer != NULL) {
_QueryBuffer = (LPVOID)FREE_MEMORY((HLOCAL)_QueryBuffer);
INET_ASSERT(_QueryBuffer == NULL);
_QueryBuffer = NULL;
_QueryBufferLength = 0;
_QueryOffset = 0;
_QueryBytesAvailable = 0;
}
}
BOOL HaveQueryData(VOID) {
return (_QueryBytesAvailable != 0) ? TRUE : FALSE;
}
DWORD CopyQueriedData(LPVOID lpBuffer, DWORD dwBufferLength) {
INET_ASSERT(lpBuffer != NULL);
INET_ASSERT(dwBufferLength != 0);
DWORD len = min(_QueryBytesAvailable, dwBufferLength);
if (len != 0) {
memcpy(lpBuffer,
(LPVOID)((LPBYTE)_QueryBuffer + _QueryOffset),
len
);
_QueryOffset += len;
_QueryBytesAvailable -= len;
}
return len;
}
VOID ResetResponseVariables(VOID) {
_StatusCode = 0;
_BytesReceived = 0;
_ResponseScanned = 0;
_iSlotContentLength = 0;
_iSlotContentRange = 0;
_ResponseBufferDataReadyToRead = 0;
_DataOffset = 0;
_BytesRemaining = 0;
_ContentLength = 0;
_BytesInSocket = 0;
ZapFlags();
_ftLastModified.dwLowDateTime = 0;
_ftLastModified.dwHighDateTime = 0;
_ftExpires.dwLowDateTime = 0;
_ftExpires.dwHighDateTime = 0;
_ftPostCheck.dwLowDateTime = 0;
_ftPostCheck.dwHighDateTime = 0;
}
//
// flags methods
//
VOID SetEof(BOOL Value) {
_Union.Flags.Eof = Value ? 1 : 0;
}
BOOL IsEof(VOID) const {
return _Union.Flags.Eof;
}
VOID SetDownLevel(BOOL Value) {
_Union.Flags.DownLevel = Value ? 1 : 0;
}
BOOL IsDownLevel(VOID) const {
return _Union.Flags.DownLevel;
}
BOOL IsRequestHttp1_1() {
return (_RequestHeaders.MajorVersion() > 1)
? TRUE
: (((_RequestHeaders.MajorVersion() == 1)
&& (_RequestHeaders.MinorVersion() >= 1))
? TRUE
: FALSE);
}
BOOL IsRequestHttp1_0() {
return ((_RequestHeaders.MajorVersion() == 1)
&& (_RequestHeaders.MinorVersion() == 0));
}
VOID SetResponseHttp1_1(BOOL Value) {
_Union.Flags.Http1_1Response = Value ? 1 : 0;
}
BOOL IsResponseHttp1_1(VOID) const {
return _Union.Flags.Http1_1Response;
}
VOID SetMustRevalidate (VOID) {
_Union.Flags.MustRevalidate = 1;
}
BOOL IsMustRevalidate (VOID) const {
return _Union.Flags.MustRevalidate;
}
VOID SetUpLevel(BOOL Value) {
_Union.Flags.UpLevel = Value ? 1 : 0;
}
BOOL IsUpLevel(VOID) const {
return _Union.Flags.UpLevel;
}
VOID SetKeepAlive(BOOL Value) {
_Union.Flags.KeepAlive = Value ? 1 : 0;
}
BOOL IsKeepAlive(VOID) const {
return _Union.Flags.KeepAlive;
}
VOID SetConnCloseResponse(BOOL Value) {
_Union.Flags.ConnCloseResponse = Value ? 1 : 0;
}
BOOL IsConnCloseResponse(VOID) const {
return _Union.Flags.ConnCloseResponse;
}
VOID SetData(BOOL Value) {
_Union.Flags.Data = Value ? 1 : 0;
}
BOOL IsData(VOID) const {
return _Union.Flags.Data;
}
VOID SetOpenFlags(DWORD OpenFlags) {
_OpenFlags = OpenFlags;
}
DWORD GetOpenFlags(VOID) {
return _OpenFlags;
}
//VOID SetCookieUI(BOOL Value)
//{
// _Union.Flags.CookieUI = (Value) ? TRUE : FALSE;
//}
//BOOL IsCookieUI() const
//{
// return _Union.Flags.CookieUI;
//}
VOID SetHaveChunkEncoding(BOOL Value) {
_Union.Flags.ChunkEncoding = Value ? 1 : 0;
}
BOOL IsChunkEncoding(VOID) const {
return _Union.Flags.ChunkEncoding;
}
VOID SetHaveContentLength(BOOL Value) {
_Union.Flags.ContentLength = Value ? 1 : 0;
}
BOOL IsContentLength(VOID) const {
return _Union.Flags.ContentLength;
}
VOID SetAutoSync(VOID) {
_Union.Flags.AutoSync = 1;
}
BOOL IsAutoSync(VOID) {
return _Union.Flags.AutoSync == 1;
}
VOID SetBadNSServer(BOOL Value) {
_Union.Flags.BadNSServer = Value ? 1 : 0;
}
BOOL IsBadNSServer(VOID) const {
return _Union.Flags.BadNSServer ? TRUE : FALSE;
}
VOID SetCheckedConnCloseRequest(BOOL bProxy, BOOL bFound) {
_Union.Flags.ConnCloseChecked = 1;
if (bProxy) {
_Union.Flags.ProxyConnCloseReq = bFound ? 1 : 0;
} else {
_Union.Flags.ConnCloseReq = bFound ? 1 : 0;
}
}
BOOL CheckedConnCloseRequest(VOID) {
return (_Union.Flags.ConnCloseChecked == 1) ? TRUE : FALSE;
}
BOOL IsConnCloseRequest(BOOL bProxyHeader) {
return bProxyHeader
? (_Union.Flags.ProxyConnCloseReq == 1)
: (_Union.Flags.ConnCloseReq == 1);
}
VOID
SetBadNSReceiveTimeout(
VOID
);
BOOL IsChunkedEncodingFinished(VOID) {
return _ctChunkInfo.IsFinished();
}
VOID CheckClientRequestHeaders (VOID);
VOID SetFirstSendProcessed() {
_NoResetBits.Flags.FirstSendProcessed = 1;
}
BOOL IsFirstSendProcessed() const {
return _NoResetBits.Flags.FirstSendProcessed;
}
VOID SetObjectRoot() {
_NoResetBits.Flags.IsObjectRoot = 1;
}
BOOL IsObjectRoot() {
return _NoResetBits.Flags.IsObjectRoot;
}
VOID SetOverrideProxyMode(BOOL Value) {
_NoResetBits.Flags.OverrideProxyMode = (Value ? TRUE : FALSE );
}
BOOL IsOverrideProxyMode() const {
return _NoResetBits.Flags.OverrideProxyMode;
}
VOID SetCacheReadDisabled (VOID) {
_NoResetBits.Flags.CacheReadDisabled = 1;
}
BOOL IsCacheReadDisabled (VOID) const {
return _NoResetBits.Flags.CacheReadDisabled;
}
VOID SetWantKeepAlive(BOOL Value) {
_bWantKeepAlive = Value;
}
BOOL IsWantKeepAlive(VOID) const {
return _bWantKeepAlive;
}
VOID SetRefresh(BOOL Value) {
_bRefresh = Value;
}
BOOL IsRefresh(VOID) const {
return _bRefresh;
}
VOID SetAddCRLF(BOOL Value) {
_AddCRLFToPOST = Value;
}
//
// Bit to distinguish nested request for establishing a tunnel.
//
VOID SetTunnel (VOID) {
_NoResetBits.Flags.IsTunnel = 1;
}
BOOL IsTunnel(VOID) const {
return (BOOL) _NoResetBits.Flags.IsTunnel;
}
//
// secure (socket) methods
//
VOID SetSecureFlags(DWORD Flags) {
if(m_pSecurityInfo)
{
m_pSecurityInfo->SetSecureFlags(Flags);
}
}
DWORD GetSecureFlags(VOID) {
if(m_pSecurityInfo)
{
return m_pSecurityInfo->GetSecureFlags();
}
return 0;
}
VOID LockHeaders(VOID) {
//EnterCriticalSection(&_CritSec);
_RequestHeaders.LockHeaders();
}
VOID UnlockHeaders(VOID) {
//LeaveCriticalSection(&_CritSec);
_RequestHeaders.UnlockHeaders();
}
VOID SetIgnoreOffline(VOID) {
_fIgnoreOffline = TRUE;
}
//
// GetCertChainList (and)
// SetCertChainList -
// Sets and Gets Client Authentication Cert Chains.
//
CERT_CONTEXT_ARRAY* GetCertContextArray(VOID) {
if(m_pSecurityInfo)
{
return m_pSecurityInfo->GetCertContextArray();
}
return NULL;
}
VOID SetCertContextArray(CERT_CONTEXT_ARRAY* pNewCertContextArray) {
if(m_pSecurityInfo)
{
m_pSecurityInfo->SetCertContextArray(pNewCertContextArray);
}
}
//
// function to get SSL Certificate Information
//
DWORD GetSecurityInfo(LPINTERNET_SECURITY_INFO pInfo) {
if(m_pSecurityInfo)
{
m_pSecurityInfo->CopyOut(*pInfo);
return ERROR_SUCCESS;
}
else
{
return ERROR_INTERNET_INTERNAL_ERROR;
}
}
/* Function for determining zone-mapping
This is a reverse-dependency between WININET and URLMON */
DWORD GetSecurityZone(BOOL fRevalidate=FALSE) {
/* already found out which zone this request lives in? */
if (!fRevalidate &&
_dwSecurityZone>=URLZONE_PREDEFINED_MIN &&
_dwSecurityZone<=URLZONE_PREDEFINED_MAX)
return _dwSecurityZone;
/* otherwise map the zone and save result on this object */
if (GetOpenFlags() & INTERNET_FLAG_RESTRICTED_ZONE)
_dwSecurityZone = URLZONE_UNTRUSTED;
else
_dwSecurityZone = GetZoneFromUrl(GetURL());
return _dwSecurityZone;
}
//
// authentication related methods
//
VOID SetAuthCtx (AUTHCTX *pAuthCtx) {
_pAuthCtx = pAuthCtx;
}
AUTHCTX* GetAuthCtx (VOID) {
return _pAuthCtx;
}
VOID SetPWC (PWC *pPWC) {
_pPWC = pPWC;
}
PWC* GetPWC (VOID) {
return _pPWC;
}
AUTHCTX* GetTunnelAuthCtx (VOID) {
return _pTunnelAuthCtx;
}
DWORD GetCredPolicy (VOID)
{
if (_dwCredPolicy == 0xFFFFFFFF)
{
LPSTR pszUrl;
if (GetOpenFlags() & INTERNET_FLAG_RESTRICTED_ZONE)
pszUrl = NULL;
else
pszUrl = GetURL();
_dwCredPolicy = ::GetCredPolicy (pszUrl);
}
return _dwCredPolicy;
}
DWORD GetAuthState (void) {
return _NoResetBits.Flags.AuthState;
}
void SetAuthState (DWORD dw) {
INET_ASSERT( dw <= AUTHSTATE_LAST );
_NoResetBits.Flags.AuthState = dw;
DEBUG_PRINT(
HTTP,
INFO,
("authstate on request %#x set to %#x [%s]\n", this, dw, InternetMapAuthState(dw))
);
}
void SetAuthorized (void) {
_NoResetBits.Flags.IsAuthorized = 1;
}
BOOL IsAuthorized (void) {
return _NoResetBits.Flags.IsAuthorized;
}
void SetMethodBody (void) {
_NoResetBits.Flags.MethodBody = 1;
}
BOOL IsMethodBody (void) {
return _NoResetBits.Flags.MethodBody;
}
void SetDisableNTLMPreauth (BOOL fVal) {
_NoResetBits.Flags.DisableNTLMPreauth = (DWORD) (fVal ? TRUE : FALSE);
}
BOOL IsDisableNTLMPreauth (void) {
return _NoResetBits.Flags.DisableNTLMPreauth;
}
LPVOID GetBlockingFilter (void) {
return _lpBlockingFilter;
}
void SetBlockingFilter (LPVOID lpFilter) {
_lpBlockingFilter = lpFilter;
}
void SetAuthFlag(DWORD AuthFlag) {
m_AuthFlag = AuthFlag;
}
DWORD GetAuthFlag(void) {
return m_AuthFlag;
}
//
// proxy methods
//
BOOL IsTalkingToSecureServerViaProxy(VOID) const {
return _fTalkingToSecureServerViaProxy;
}
VOID SetIsTalkingToSecureServerViaProxy(BOOL fTalkingToSecureServerViaProxy) {
_fTalkingToSecureServerViaProxy = fTalkingToSecureServerViaProxy;
}
VOID SetRequestUsingProxy(BOOL fRequestUsingProxy) {
_fRequestUsingProxy = fRequestUsingProxy;
}
BOOL IsRequestUsingProxy(VOID) const {
return _fRequestUsingProxy;
}
VOID
GetProxyName(
OUT LPSTR* lplpszProxyHostName,
OUT LPDWORD lpdwProxyHostNameLength,
OUT LPINTERNET_PORT lpProxyPort
);
VOID
SetProxyName(
IN LPSTR lpszProxyHostName,
IN DWORD dwProxyHostNameLength,
IN INTERNET_PORT ProxyPort
);
VOID
GetSocksProxyName(
LPSTR *lplpszProxyHostName,
DWORD *lpdwProxyHostNameLength,
LPINTERNET_PORT lpProxyPort
)
{
*lplpszProxyHostName = _SocksProxyHostName;
*lpdwProxyHostNameLength = _SocksProxyHostNameLength;
*lpProxyPort = _SocksProxyPort;
}
VOID
SetSocksProxyName(
LPSTR lpszProxyHostName,
DWORD dwProxyHostNameLength,
INTERNET_PORT ProxyPort
)
{
_SocksProxyHostName = lpszProxyHostName;
_SocksProxyHostNameLength = dwProxyHostNameLength;
_SocksProxyPort = ProxyPort;
}
VOID ClearPersistentConnection (VOID) {
_Union.Flags.PersistProxy = 0;
_Union.Flags.PersistServer = 0;
}
VOID SetPersistentConnection (BOOL fProxy) {
if (fProxy) {
_Union.Flags.PersistProxy = 1;
} else {
_Union.Flags.PersistServer = 1;
}
}
BOOL IsPersistentConnection (BOOL fProxy) {
return fProxy ?
_Union.Flags.PersistProxy : _Union.Flags.PersistServer;
}
//
// functions to get/set state
//
VOID SetState(HTTPREQ_STATE NewState) {
DEBUG_PRINT(HTTP,
INFO,
("SetState(): current state %#x [%s], new state %#x [%s]\n",
_State,
InternetMapHttpState(_State),
NewState,
InternetMapHttpState(NewState)
));
_State = NewState;
}
BOOL CheckState(DWORD Flag) {
DEBUG_PRINT(HTTP,
INFO,
("CheckState(): current state %#x [%s], checking %#x [%s] - %B\n",
_State,
InternetMapHttpState(_State),
Flag,
InternetMapHttpStateFlag(Flag),
(_State & Flag) ? TRUE : FALSE
));
return (_State & Flag) ? TRUE : FALSE;
}
VOID
ReuseObject(
VOID
);
DWORD
ResetObject(
IN BOOL bForce,
IN BOOL bFreeRequestHeaders
);
DWORD SetStreamPointer (LONG lDistanceToMove, DWORD dwMoveMethod);
BOOL AttemptReadFromFile (LPVOID lpBuf, DWORD cbBuf, DWORD *pcbRead);
VOID AdvanceReadPosition (DWORD cbRead)
{
_dwCurrentStreamPosition += cbRead;
if (IsKeepAlive() && IsContentLength())
{
_BytesRemaining -= cbRead;
INET_ASSERT (_BytesRemaining + _dwCurrentStreamPosition
== _ContentLength);
}
}
BOOL IsReadRequest (void)
{
return (IsCacheWriteInProgress() &&
_dwCurrentStreamPosition != _VirtualCacheFileSize);
}
DWORD
ReadLoop_Fsm(
IN CFsm_ReadLoop * Fsm
);
DWORD WriteResponseBufferToCache (VOID);
DWORD WriteQueryBufferToCache (VOID);
VOID SetNoLongerKeepAlive(VOID) {
_bNoLongerKeepAlive = TRUE;
}
BOOL IsNoLongerKeepAlive(VOID) const {
return _bNoLongerKeepAlive;
}
//
// send.cxx methods
//
DWORD
HttpSendRequest_Start(
IN CFsm_HttpSendRequest * Fsm
);
DWORD
HttpSendRequest_Finish(
IN CFsm_HttpSendRequest * Fsm
);
DWORD
MakeConnection_Fsm(
IN CFsm_MakeConnection * Fsm
);
DWORD
SendRequest_Fsm(
IN CFsm_SendRequest * Fsm
);
DWORD
ReceiveResponse_Fsm(
IN CFsm_ReceiveResponse * Fsm
);
BOOL
FCanWriteToCache(
VOID
);
BOOL
FAddIfModifiedSinceHeader(
IN LPCACHE_ENTRY_INFO lpCei
);
BOOL AddHeaderIfEtagFound (IN LPCACHE_ENTRY_INFO lpCei);
DWORD
FHttpBeginCacheRetrieval(
IN BOOL bReset,
IN BOOL bOffline,
IN BOOL bNoRetrieveIfExist = FALSE
);
DWORD UrlCacheRetrieve (BOOL fOffline)
{
INET_ASSERT (!_hCacheStream && !_pCacheEntryInfo);
return ::UrlCacheRetrieve
(_CacheUrlName, fOffline, &_hCacheStream, &_pCacheEntryInfo);
}
VOID UrlCacheUnlock (VOID);
BOOL FHttpBeginCacheWrite(VOID);
DWORD ResumePartialDownload (VOID);
DWORD
GetFromCachePreNetIO(
VOID
);
DWORD
GetFromCachePostNetIO(
IN DWORD statusCode,
IN BOOL fVariation = FALSE
);
DWORD
AddTimestampsFromCacheToResponseHeaders(
IN LPCACHE_ENTRY_INFO lpCacheEntryInfo
);
DWORD
AddTimeHeader(
IN FILETIME fTime,
IN DWORD dwHeaderIndex
);
LPINTERNET_BUFFERS SetReadFileEx(VOID) {
_BuffersOut.lpvBuffer = (LPVOID)&_ReadFileExData;
//
// receive ONE byte
//
_BuffersOut.dwBufferLength = 1;
return &_BuffersOut;
}
VOID SetReadFileExData(VOID) {
_HaveReadFileExData = TRUE;
}
VOID ResetReadFileExData(VOID) {
_HaveReadFileExData = FALSE;
}
BOOL HaveReadFileExData(VOID) {
return _HaveReadFileExData;
}
BYTE GetReadFileExData(VOID) {
ResetReadFileExData();
return (BYTE)_ReadFileExData;
}
//
// cookie.cxx methods
//
DWORD
CreateCookieHeaderIfNeeded(
int *pcCookie
);
DWORD
ExtractSetCookieHeaders(
LPDWORD lpdwHeaderIndex
);
LPCACHE_ENTRY_INFO GetCacheEntryInfo(VOID){
return _pCacheEntryInfo;
}
BOOL IsInCache(VOID) {
return _pCacheEntryInfo != NULL;
}
DWORD GetCacheEntryType (void){
return _dwCacheEntryType;
}
void AddCacheEntryType (DWORD dw){
_dwCacheEntryType |= dw;
}
BOOL CanRetrieveFromCache(BOOL fCheckCache = TRUE) {
return ((fCheckCache && IsInCache()) || !fCheckCache)
&& !IsAutoSync()
&& !(_OpenFlags
& (INTERNET_FLAG_RELOAD | INTERNET_FLAG_RESYNCHRONIZE));
}
//
// priority methods
//
LONG GetPriority(VOID) const {
return m_lPriority;
}
VOID SetPriority(LONG lPriority) {
m_lPriority = lPriority;
}
BOOL IsAutoProxyChecked(VOID) const {
return _fAutoProxyChecked;
}
VOID SetAutoProxyChecked(BOOL fValue) {
_fAutoProxyChecked = fValue;
}
//
// Round Trip Time methods
//
VOID StartRTT(VOID) {
_RTT = GetTickCountWrap();
}
VOID UpdateRTT(VOID) {
_RTT = (GetTickCountWrap() - _RTT);
CServerInfo * pServerInfo = GetOriginServer();
if (pServerInfo != NULL) {
pServerInfo->UpdateRTT(_RTT);
}
}
DWORD GetRTT(VOID) const {
return _RTT;
}
VOID SetCodePage(UINT dwCodePage) {
_CP = dwCodePage;
}
UINT GetCodePage(VOID) const {
return _CP;
}
VOID SetAuthenticated();
BOOL IsAuthenticated();
//
// diagnostic info
//
SOCKET GetSocket(VOID) {
return (_Socket != NULL) ? _Socket->GetSocket() : INVALID_SOCKET;
}
DWORD GetSourcePort(VOID) {
return (_Socket != NULL) ? _Socket->GetSourcePort() : 0;
}
DWORD GetDestPort(VOID) {
return (_Socket != NULL) ? _Socket->GetPort() : 0;
}
BOOL FromKeepAlivePool(VOID) const {
return _bKeepAliveConnection;
}
BOOL IsSecure(VOID) {
return (_Socket != NULL) ? _Socket->IsSecure() : FALSE;
}
BOOL IsBlockedOnUserInput(VOID) {
DEBUG_PRINT(THRDINFO,
INFO,
("HTTP_REQUEST_HANDLE_OBJECT[%#x]::IsBlockedOnUserInput() = %B\n",
this,
_dwUiBlocked
));
return (BOOL) _dwUiBlocked;
}
VOID BlockOnUserInput(DWORD_PTR dwBlockId) {
DEBUG_PRINT(THRDINFO,
INFO,
("HTTP_REQUEST_HANDLE_OBJECT[%#x]::BlockOnUserInput(dwBlockId=%#x)\n",
this,
dwBlockId
));
INET_ASSERT(!_dwUiBlocked);
_dwUiBlocked = TRUE;
_dwBlockId = dwBlockId;
}
DWORD_PTR GetBlockId(VOID) {
DEBUG_PRINT(THRDINFO,
INFO,
("HTTP_REQUEST_HANDLE_OBJECT[%#x]::GetBlockId() = %#x\n",
this,
_dwBlockId
));
INET_ASSERT(_dwUiBlocked);
return _dwBlockId;
}
VOID UnBlockOnUserInput(VOID) {
DEBUG_PRINT(THRDINFO,
INFO,
("HTTP_REQUEST_HANDLE_OBJECT[%#x]::UnBlockOnUserInput()\n",
this
));
INET_ASSERT(_dwUiBlocked);
_dwUiBlocked = FALSE;
}
VOID Set3rdPartyCookies(BOOL f3rdParty)
{
_f3rdPartyCookies = f3rdParty;
}
BOOL Is3rdPartyCookies(VOID)
{
return _f3rdPartyCookies;
}
VOID SetSendUTF8ServerNameToProxy(DWORD dwSetVal)
{
_fSendUTF8ServerNameToProxy = dwSetVal ? TRUE : FALSE;
}
BOOL ShouldSendUTF8ServerNameToProxy()
{
return _fSendUTF8ServerNameToProxy;
}
VOID SetSocketSendBufferLength(DWORD dwLength)
{
_dwSocketSendBufferLength = dwLength;
}
DWORD GetSocketSendBufferLength()
{
return _dwSocketSendBufferLength;
}
};
//
// prototypes
//
BOOL
IsCorrectUser(
IN LPSTR lpszHeaderInfo,
IN DWORD dwHeaderSize
);
//
// Support for handling cookie policy
//
typedef struct _COOKIE_DLG_INFO {
LPWSTR pszServer;
PINTERNET_COOKIE pic;
DWORD dwStopWarning;
INT cx;
INT cy;
LPWSTR pszHeader;
DWORD dwOperation;
} COOKIE_DLG_INFO, *PCOOKIE_DLG_INFO;
// values for dwOperation member
#define COOKIE_OP_SET 0x01
#define COOKIE_OP_MODIFY 0x02
#define COOKIE_OP_GET 0x04
#define COOKIE_OP_SESSION 0x08
#define COOKIE_OP_PERSISTENT 0x10
#define COOKIE_OP_3RD_PARTY 0x20
DWORD
ConfirmCookie(
IN HWND hwnd,
IN HTTP_REQUEST_HANDLE_OBJECT *pRequest,
IN COOKIE_DLG_INFO *pInfo
);