Microsoft KB Archive/279497

= How To Get Protocol Headers in a Pluggable Protocol Handler =

Article ID: 279497

Article Last Modified on 5/24/2007

-

APPLIES TO


 * Microsoft Internet Explorer 4.0 128-Bit Edition
 * Microsoft Internet Explorer 4.01 Service Pack 2
 * Microsoft Internet Explorer 4.01 Service Pack 1
 * Microsoft Internet Explorer 4.01 Service Pack 2
 * Microsoft Internet Explorer 5.0
 * Microsoft Internet Explorer 5.01
 * Microsoft Internet Explorer (Programming) 5.01 SP1
 * Microsoft Internet Explorer 5.5

-



This article was previously published under Q279497



SUMMARY
This article outlines how an asynchronous pluggable protocol handler (APPH) can obtain headers, such as Accept-Language or User-Agent, that a client of the URL moniker might wish to add to a request.



MORE INFORMATION
There are two mechanisms by which an APPH can obtain header information:  A URL moniker client can optionally implement the IHttpNegotiate interface. This interface has a BeginningTransaction method that the protocol handler can call at the beginning of a URL navigation. This method allows the client to add headers, such as Accept-Language, or User-Agent, to the request.

A specific example is MSHTML as an URL moniker host. MSHTML asks the WebBrowser, and the WebBrowser in turn asks its host, for a new user agent by way of the DISPID_AMBIENT_USERAGENT property when navigating to clicked hyperlinks. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

183412 PRB: WebBrowser Control Clients Share Global Settings

MSHTML returns this user agent string when its implementation of IHttpNegotiate::BeginningTransaction is called. The advantage of this method is that headers can be fine-tuned on a per-instance basis (as opposed to a process-global basis). A client can use the ::UrlMkSetSessionOption function to communicate headers to the APPH. This function sets options on a process-global basis.

To obtain headers by way of an APPH, follow these steps:   QueryService the IInternetProtocolSink obtained from IInternetProtocol::Start for IHttpNegotiate. Then call the BeginningTransaction method to get the headers.

For instance, within IInternetProtocol::Start IHttpNegotiate *pHttpNeg; hr = IUnknown_QueryService(pIProtSink, IID_IHttpNegotiate, IID_IHttpNegotiate, (void**)&pHttpNeg);

if(SUCCEEDED(hr)) {       LPWSTR pwzAddHeaders = NULL; hr = pHttpNeg->BeginningTransaction(szUrl, NULL, NULL, &pwzAddHeaders);

// pwzAddHeaders now contains headers. // The headers have the same form as they // would in an HTTP request. That is, // of the form: // &quot;Header-Name: Header-Value\r\n2nd-Header-Name: 2nd-Header-Value\r\n&quot; // and so on. .       .        .        pHttpNeg->Release; } Where the IUnknown_QueryService function resembles the following: HRESULT IUnknown_QueryService(IUnknown* punk, REFGUID rsid, REFIID riid, void ** ppvObj) {   HRESULT hr = E_NOINTERFACE;

*ppvObj = 0;

if (punk) {       IServiceProvider *pSrvPrv; hr = punk->QueryInterface(IID_IServiceProvider, (void **) &pSrvPrv); if (hr == NOERROR) {           hr = pSrvPrv->QueryService(rsid,riid, ppvObj); pSrvPrv->Release; }   }

return hr; }

  Retrieve per-process settings for values that you didn't obtain from the above method, by using ::UrlMkGetSessionOption. For instance, to retrieve the &quot;User-Agent&quot; header: char cUAStr[_MAX_PATH]; DWORD nUAStrLen = sizeof(cUAStr)/sizeof(cUAStr[0]) - 1; ::UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, cUAStr, nUAStrLen, &nUAStrLen, 0);

// Alternatively, for &quot;User-Agent&quot;, this API can be used: // ::ObtainUserAgentString (0, cUAStr, &nUAStrLen); 

