Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ANN: Passthrough APP development toolkit

351 views
Skip to first unread message

Igor Tandetnik

unread,
Jun 27, 2003, 3:43:41 PM6/27/03
to
For some time now, I recommended using so called passthrough
Asynchronous Pluggable Protocol (APP) handlers to solve a certain class
of problems frequently coming up in these newsgroups. Unfortunately, I
could not point to any sample that would show how to implement one. So I
decided to put my money where my mouth is, and actually write one
myself. The result of this effort is not just a sample, but a complete
toolkit for implementing your own passthrough APPs. The code is
available here:

http://itandetnik.150m.com/PassthruAPP.zip

For now, there is no documentation beyond rather scarce comments in the
source code. I plan to comment the code better, write an article and
submit to CodeProject. Meanwhile, I thought I'd better get some feedback
from fellow newsgroup goers before I embarrass myself in front of a
larger audience :)

The toolkit is implemented in ATL. The interesting stuff, namely the
plumbing for the protocol and protocol sink wrapper objects, is in
ProtocolImpl.h and ProtocolImpl.inl. ProtocolCF.h and ProtocolCF.inl
implement a class factory - you need one to register a temporary APP
with IInternetSession. PassthroughObject.h declares a private interface
that a class factory uses to initialize the protocol wrapper. In a grand
ATL tradition, the toolkit does not attempt to hide or wrap the
underlying interfaces' complexity in any way, it just supplies all the
necessary plumbing. You can override any method on any interface, and
you don't need to implement any methods or interfaces for which you are
happy with default functionality. In fact, with this toolkit, a fully
functional transparent do-nothing passthrough APP takes about five lines
of code.

The rest of the files form the sample application. I provide the project
and workspace/solution files for VC6 and VC7.1. The sample registers a
passthrough APP for HTTP and HTTPS protocols. The main window hosts a
WebBrowser control. You type a URL into the address bar and hit the Go
button. The browser gets navigated, and HTTP request and responce
headers for every request, including secondary requests such as images,
frames, CSS and so on, are dumped into the edit box at the bottom. The
APP in the sample is implemented using the toolkit - see TestAPP.h and
TestAPP.cpp.

Please feel free to use the code in any way, to modify and adapt it to
your needs, or just borrow ideas. Any comments and suggestions are
welcome. It's better to reply in the groups so others can benefit from
your thoughts, but if for some reason you don't want to, e-mails are
welcome at itand...@mvps.org. Thank you for your interest.


BACKGROUND
I think I'd better explain what passthrough APPs are all about. There
are several technology layers that support the download and navigation
in Internet Explorer and WebBrowser control. At the top, there is
WebBrowser itself and MSHTML object that provides HTML parsing and
rendering. The client uses such interfaces as IWebBrowser2 and
IHTMLDocument2 to communicate with these high-level objects.

WebBrowser and MSHTML use URL Monikers library to perform actual
downloads. URLMon exposes its servives via IMoniker and IBinding
interfaces, and the client (say MSHTML) implements IBindStatusCallback
and a number of associated interfaces, e.g. IHttpNegotiate or
IAuthenticate.

Next down is an Asynchronous Pluggable Protocol handler. An APP
encapsulates the details of a particular protocol, such as http:, file:
or res:. APP exposes its services via IInternetProtocol and several
auxilliary interfaces such as IWinInetHttpInfo. URL Moniker provides
IInternetProtocolSink and IInternetBindInfo, and also makes interfaces
implemented on its client available via IServiceProvider.

An APP is the last COM-based layer. The next layer down is usually some
non-COM API - e.g. an HTTP handler would use WinInet, and a file:
handler would use CreateFile and ReadFile. Non-COM APIs are beyond the
scope of this work.

Most of the time, an application hosting a WebBrowser control (or a BHO
running inside IE) uses high-level services provided by WebBrowser and
MSHTML objects. However, somethimes these services are insufficient, and
a lower-level hook is required. E.g., when downloading an HTML page,
MSHTML only provides an overall progress of the operation, the download
of a page as a whole. Sometimes you would want to recognize an HTTP
request for every individually downloaded element on a page - images,
CSS stylesheets, scripts and so on. You may want to send custom headers
to the server, or process and act upon response headers, or modify the
content before it reaches the browser (though a MIME filter is better
suited for that), or simply log individual requests for debugging,
testing or profiling purposes. High-level objects don't allow you to do
any of that.

It would be nice to be able to hook into the communication sequence
between WebBrowser/MSHTML and URL Monikers. Unfortunately, there does
not seem to be any way to do that - at least, none that I know of. So,
we look at the next level - a communication between a URL moniker and an
APP.

Here we get lucky. An APP is supposed to encapsulate a particular
communication protocol. Microsoft realises that new protocols may emerge
after Internet Explorer is released, and some applications may involve
custom protocols. So it provides and documents an architecture [1]
whereby third party developers can create and install their own protocol
handlers, and Internet Explorer can immediately start using them. Such a
protocol may be registered permanently, under a well-known registry key
(but see [2]) or temporarily, within a single process and only while
this process is running.

Now, it is rarely necessary to implement a full-blown APP from scratch -
after all, how often do new protocols actually get defined? But for out
purposes, it is usefult to implement a so called passthrough APP (pAPP).
It is an object that implements both sides of URL moniker-to-APP
communication, that is, it implements both IInternetProtocol and
IInternetProtocolSink / IInternetBindInfo. We register it as a temporary
handler for a standard protocol, such as HTTP. Now whenever an HTTP
request needs to be sent, URL moniker will create an instance of our
pAPP and ask it to do the job. The pAPP then creates an instance of a
standard APP for the protocol in question (I call it a target APP, or
tAPP, but be aware that I've invented the terminology myself, it's not
widely accepted, suggestions for a better naming convention are welcome)
and acts as its client. At this point, our pAPP becomes a proverbial
man-in-the-middle. In the simplest case, any method call made by URL
Moniker on pAPP is forwarded to tAPP, and any method call made by tAPP
on pAPP is forwarded back to URL Moniker. The pAPP gets to observe, and
if desired modify, every bit of information relevant to this request
passing back and forth between the moniker and the tAPP. QED

It's also possible to register a pAPP as a permanent handler for some
custom protocol, say myhttp: (but not for a standard one, see [2]). Such
a protocol can behave almost like a standard protocol, by delegating
most of the work to a target APP handler. My toolkit allows one to do
that, though frankly I don't quite see where this feature might be
useful.

[1]
http://msdn.microsoft.com/workshop/networking/pluggable/pluggable.asp
[2] http://support.microsoft.com/?id=kb;en-us;303740

--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Ashley Godfrey

unread,
Jul 28, 2003, 2:11:34 AM7/28/03
to
Hi Igor

I must thank you for your tiresome effort on these groups. You've
helped me in the past (numerous times) with my BHO's and active
document servers, and I am but one of many.

With regard to the following statement:


> It would be nice to be able to hook into the communication sequence
> between WebBrowser/MSHTML and URL Monikers. Unfortunately, there does
> not seem to be any way to do that - at least, none that I know of.

In writing my own APPs for IE I ended up writing my own COM interface
broker to effectively subclass existing IE interfaces to find out what
was going on inside IE (and that's when things start making more
sense).

For anyone else who's interested these tools, Assist and ComSight,
they are available from my web site (http://www.evocorp.com).

ComSight is an interface browser that binds to existing interfaces at
run-time (so your BHO can bind to IWebBrowserApp, IShellBrowser,
IInternetProtocol etc.) and presents an explorer that identifies what
interfaces are created and queried for throughout the lifespan of IE.

Assist is the underlying COM interface brokering engine, enabling you
to subclass existing COM interfaces so that your implementation gets
called instead of the original interface. If you need to monitor how
IE talks to something (by getting your hands right into the
nitty-gritty), Assist is definitely worth a look.

Cheers All,
Ashley.


"Igor Tandetnik" <itand...@mvps.org> wrote in message news:<uq83qROP...@tk2msftngp13.phx.gbl>...

Igor Tandetnik

unread,
Jul 30, 2003, 9:41:04 AM7/30/03
to
It was brought to my attention that the provider I used to store the ZIP
file on does not work very well. A number of people tried to get the
file and could not.

The code for my Passthrough APP development toolkit is now available at

http://home.nyc.rr.com/itandetnik/PassthruAPP.zip

Let's hope this host works better. Sorry for the inconvenience.


--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken

"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:uq83qROP...@tk2msftngp13.phx.gbl...

0 new messages