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

ANN: Passthrough APP development toolkit [bug fix]

317 views
Skip to first unread message

Igor Tandetnik

unread,
Feb 2, 2004, 11:11:03 AM2/2/04
to
A diligent reader, Grzegorz Aksamit, discovered a serious problem in
Passthrough APP. Essentially, under IE5 only the main HTML file loaded
successfully, but no associated files (images, CSS and such). To fix the
issue, I had to change the design of the class factory. The new code is
not backward compatible - see the sample for proper incantations to
instantiate a class factory. No more than a couple lines of code should
be affected.

I also improved the sample somewhat by not relying on
IInternetBindInfo::GetBindString(BINDSTRING_URL) to get the request URL
when logging response headers - this also failed on IE5. Now I'm caching
the original URL from the request, and also following redirects by
watching IInternetProtocolSink::ReportProgress(BINDSTATUS_REDIRECTING).

The code is available at

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

I'd like to thank everybody who expressed interest and support of the
project.
--
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:...
> 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://home.nyc.rr.com/itandetnik/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
>
>


msnews.microsoft.com

unread,
Feb 11, 2004, 8:41:45 PM2/11/04
to
Hi Igor,

Thanks for the toolkit. I am trying to use it to in a horizontal explorer
band for IE. I am displaying the http request and response details in the
band. Is there a way to only display the http info for the browser instance
the explorer band resides in? Currently the explorer band in the first open
IE instance is displaying http info for all subsequent open browser
instances.

Thanks,

Justin

"Igor Tandetnik" <itand...@mvps.org> wrote in message

news:u0bu6ca6...@TK2MSFTNGP09.phx.gbl...

Igor Tandetnik

unread,
Feb 12, 2004, 10:33:41 AM2/12/04
to
"msnews.microsoft.com" <jecht...@hotmail.com> wrote in message
news:ud%23KjlQ8...@TK2MSFTNGP12.phx.gbl...

> Thanks for the toolkit. I am trying to use it to in a horizontal
explorer
> band for IE. I am displaying the http request and response details in
the
> band. Is there a way to only display the http info for the browser
instance
> the explorer band resides in? Currently the explorer band in the
first open
> IE instance is displaying http info for all subsequent open browser
> instances.

Here's the situation. IInternetSession reisters the temporary APP on a
per-process basis (totally disregarding COM threading models in grand
URLMon tradition). On some systems, all IE instances run in different
threads of the same process. Even on systems where independently started
IE instances reside in separate processes, Ctrl-N (or File | New |
Window) always starts a new instance in the same process.

This means that, once you register your APP, it gets requests from all
instances running in the same process. I guess you use a global variable
or something to let the APP discover and communicate with the band.
Obviously, that's not going to work, because you may have multiple band
instances open in the same process.

I'm about to tackle this problem myself soon. The two approaches I'm
about to try are 1) TLS and 2) IWindowForBindingUI approach described
here:

http://groups.google.com/groups?threadm=uxV8Yn61DHA.2000%40TK2MSFTNGP11.phx.gbl

0 new messages