OLD | NEW |
(Empty) | |
| 1 # Passthrough APP (Asynchronous Pluggable Protocol) |
| 2 |
| 3 ## Motivation and History |
| 4 |
| 5 Internet Explorer takes a complex and challenging [approach to extensibility](ht
tp://msdn.microsoft.com/en-us/library/hh772401.aspx) based on [Window's Componen
t Object Model (COM)](https://www.microsoft.com/com/default.mspx). If you are an
experienced and skilled C++ developer, you can create add-ons for IE that offer
similar functionality to that of equivalents for other popular browsers like Ch
rome and Firefox. |
| 6 |
| 7 However, there are striking gaps in the capabilities of the official APIs that m
ake certain types of add-ons impossible. One significant example is the processi
ng of network requests. The web browser control used by IE handles a few events
that are triggered before navigating to a page, when navigation completes, when
document loading completes, etc. However, these events are only triggered for pa
ge and frame loads (not for subordinate requests like images and stylesheets). T
heir behavior when a page is refreshed is counterintuitive. And they provide lit
tle or no features for viewing and modifying web requests and traffic (e.g. addi
ng new headers to a request or redirecting it to a different URL). |
| 8 |
| 9 Igor Tandetnik's Passthrough APP is an attempt to bridge these gaps in an ingeni
ous way: by replacing IE's implementation of the HTTP and HTTPS protocols with a
new one that does nothing more than delegate to the default implementation. In
this way, we are able to spy on and influence the interactions that occur. If a
request is made for a URL, we can add headers to the request,for example, before
passing it on to the built-in protocol handler. |
| 10 |
| 11 As the Passthrough APP is no longer actively maintained, this Github project is
an attempt to provide a canonical location where the source code can be download
ed, bugfixes and improvements can be proposed, issues can be filed, etc. We have
updated the "Passthrough APP beta" sources written by Igor Tandetnik to work wi
th the latest versions of Internet Explorer (versions 8 and 9 at the time of thi
s writing). |
| 12 |
| 13 ## User Guide |
| 14 |
| 15 ### Customizing the protocol sink |
| 16 |
| 17 The Passthrough APP is designed for us in a [Browser Helper Object](http://msdn.
microsoft.com/en-us/library/bb250436). If you are using it, you presumably want
to customize some of the behavior of the protocol (used to start requests) and/o
r sink (used to receive notifications about requests). |
| 18 |
| 19 In the simplest case you can customize the sink so that you can monitor the prog
ress of requests and modify them (e.g. by changing headers). To do so, create a
source file to implement your new sink class: |
| 20 |
| 21 ```c++ |
| 22 class CMyProtocolSink : |
| 23 public PassthroughAPP::CInternetProtocolSinkWithSP<CMyProtocolSink>, |
| 24 public IHttpNegotiate |
| 25 { |
| 26 typedef PassthroughAPP::CInternetProtocolSinkWithSP<CMyProtocolSink> BaseClass
; |
| 27 |
| 28 public: |
| 29 BEGIN_COM_MAP(CMyProtocolSink) |
| 30 COM_INTERFACE_ENTRY(IHttpNegotiate) |
| 31 COM_INTERFACE_ENTRY_CHAIN(BaseClass) |
| 32 END_COM_MAP() |
| 33 |
| 34 BEGIN_SERVICE_MAP(CMyProtocolSink) |
| 35 SERVICE_ENTRY(IID_IHttpNegotiate) |
| 36 END_SERVICE_MAP() |
| 37 |
| 38 // IHttpNegotiate |
| 39 STDMETHODIMP BeginningTransaction( |
| 40 /* [in] */ LPCWSTR szURL, |
| 41 /* [in] */ LPCWSTR szHeaders, |
| 42 /* [in] */ DWORD dwReserved, |
| 43 /* [out] */ LPWSTR *pszAdditionalHeaders); |
| 44 |
| 45 STDMETHODIMP OnResponse( |
| 46 /* [in] */ DWORD dwResponseCode, |
| 47 /* [in] */ LPCWSTR szResponseHeaders, |
| 48 /* [in] */ LPCWSTR szRequestHeaders, |
| 49 /* [out] */ LPWSTR *pszAdditionalRequestHeaders); |
| 50 |
| 51 STDMETHODIMP ReportProgress( |
| 52 /* [in] */ ULONG ulStatusCode, |
| 53 /* [in] */ LPCWSTR szStatusText); |
| 54 }; |
| 55 ``` |
| 56 |
| 57 In this case we are implementing a sink that overrides the functionality of the
`IHttpNegotiate` interface. You can override any of the interfaces implemented b
y the Passthrough APP sink class (`IInternetProtocolSinkImpl`) in a similar mann
er. |
| 58 |
| 59 ### Creating the APP |
| 60 |
| 61 In addition to a sink, you also need to create a class that implements the APP i
tself. This class takes a "start policy" class as a template parameter. The Pass
through APP toolkit provides two built-in start policy classes: `NoSinkStartPoli
cy`, which simply starts the request using the default sink, and `CustomSinkStar
tPolicy`, which uses your custom sink (see previous section). |
| 62 |
| 63 The latter is used as follows: |
| 64 |
| 65 ```c++ |
| 66 class CMyAPP; |
| 67 typedef PassthroughAPP::CustomSinkStartPolicy<CMyAPP, CMyProtocolSink> MyStartPo
licy; |
| 68 |
| 69 class CMyAPP : |
| 70 public PassthroughAPP::CInternetProtocol<MyStartPolicy> |
| 71 { |
| 72 }; |
| 73 ``` |
| 74 |
| 75 ### Registering the class factory |
| 76 |
| 77 In order for your Passthrough APP to be used, you need to register the class fac
tory used by Internet Explorer to instantiate handlers for the HTTP and HTTPS pr
otocols. First, define your factory using the templated `CMetaFactory` class inc
luded in the toolkit: |
| 78 |
| 79 ```c++ |
| 80 #include "ProtocolCF.h" |
| 81 #include "MyProtocolSink.h" |
| 82 |
| 83 typedef PassthroughAPP::CMetaFactory<PassthroughAPP::CComClassFactoryProtocol, |
| 84 CTrustedAdsProtocolAPP> MetaFactory; |
| 85 ``` |
| 86 |
| 87 Add two new members to your BHO's class: |
| 88 |
| 89 ```c++ |
| 90 CComPtr<IClassFactory> m_CFHTTP; |
| 91 CComPtr<IClassFactory> m_CFHTTPS; |
| 92 ``` |
| 93 |
| 94 Then add this code to your BHO's `SetSite` method to register the class factory: |
| 95 |
| 96 ```c++ |
| 97 CComPtr<IInternetSession> pInternetSession; |
| 98 CoInternetGetSession(0, &pInternetSession, 0); |
| 99 |
| 100 MetaFactory::CreateInstance(CLSID_HttpProtocol, &m_CFHTTP); |
| 101 pInternetSession->RegisterNameSpace(m_CFHTTP, CLSID_NULL, L"http", 0, 0, 0); |
| 102 |
| 103 MetaFactory::CreateInstance(CLSID_HttpSProtocol, &m_CFHTTPS); |
| 104 pInternetSession->RegisterNameSpace(m_CFHTTPS, CLSID_NULL, L"https", 0, 0, 0); |
| 105 ``` |
| 106 |
| 107 You can unregister the factories using the `UnregisterNameSpace` methods of `IIn
ternetSession` if you no longer want your Passthrough APP to be used. |
OLD | NEW |