Http Monitor for Webbrowser Control
Introduction
There are various tools available to monitor Http traffic that is being sent and received from different processes. Fiddler is one such good example. All these programs open a port and filter Http traffic based on process id. But if an C# app consists of multiple browsers they fail to tell which request was sent by which browser.The C# browser control only provides Navigating and Navigated events and does not give any idea about the requests that it sends (e.g. loading of images etc.).
This article provides an ATL COM Dll that can monitor Http traffic from individual browsers.
Background
While working on a project which required the same, I stumbled upon PassThruApp by Igor Tandetnik.
csExWBDLMan.dll ("csExWBDLMan COM library" from The most complete C# Webbrowser wrapper control) is one implementation of PassThru App that provides the requests but does not provide information of redirections and data received in the requests. So, I decided to write a custom code just for monitoring Http traffic based on both PassThru App and csExWBDLMan.dll.
About PassThru App
"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...) 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" - Igor Tandetnik
The Code
The code extends classes provided by PassThru App. There are two main classes
- MonitorSink - MonitorSink extends PassthroughAPP::CInternetProtocolSinkWithSP that implements IInternetProtocolSink
- CTestAPP - CTestAPP extends PassthroughAPP::CInternetProtocol that implements IInternetProtocol
class MonitorSink : public PassthroughAPP::CInternetProtocolSinkWithSP<MonitorSink>, public IHttpNegotiate {..
class CTestAPP : public PassthroughAPP::CInternetProtocol<TestStartPolicy> {..
Now we can intercept requests using
- Request - MonitorSink::BeginningTransaction
- Response - MonitorSink::OnResponse
- Redirection - MonitorSink::ReportProgress when ulStatusCode from IInternetProtocolSink->ReportProgress(ulStatusCode.. is BINDSTATUS_REDIRECTING
- Data received - CTestAPP::Read
But the problem is that we are using Asynchronous Pluggable Protocol and all the requests are done asynchronously. So we get all, but cannot say which response belonged to which request. Moreover the data is received asynchronously in chunks.
The best solution is that if we get unique id for a transaction(i.e. unique id attached request, response and data received) then we will be able to weave the async calls back together. Here we get lucky
- IInternetBindInfo for a request is most of the times unique and is available in all the methods. But sometimes it is reused by the Browser.
- The Url to which request is made is also most likely to be unique.
Using the code
When you attach your browser with HttpMonitor.dll, on each request, response etc. an event is fired with all the required arguments. There are four events available
- OnRequest(int id, string url, string headers, string method, object postData)
- OnRedirect(int id, int redirectedId, string url, string redirectedUrl, string responseHeaders, string requestHeaders)
- OnDataRecieved(int id, string url, object data, int status)
- OnResponse(int id, string url, int responseCode, string headers)
if (monitor == null) { monitor = new HttpMonitorLib.HttpMonClass(); monitor.IEWindow = GetTopWindow(GetTopWindow(GetTopWindow(webBrowser1.Handle))).ToInt32(); monitor.OnRequest += new HttpMonitorLib._IHttpMonEvents_OnRequestEventHandler(monitor_OnRequest); . .
For example, the following function will be executed whenever the browser sends a request.
private void monitor_OnRequest(int id, string url, string headers, string method, object postData) { //code here }
The id specifies unique id associated with that particular Http transaction.
Post Comment
I will immediately take hold of your rss as I can at to find your email subscription hyperlink or e-newsletter service. Do you ave any? Please let me realize so that I could subscribe. Thanks.
Thanks again for the blog article.Really looking forward to read more. Will read on
It is really a nice and useful piece of information. I am glad that you shared this useful info with us. Please keep us informed like this. Thanks for sharing.
Very neat blog post.Really looking forward to read more.
Whats Happening i am new to this, I stumbled upon this I have found It absolutely helpful and it has aided me out loads. I hope to give a contribution & help other users like its aided me. Good job.
Spot on with this write-up, I actually believe this web site needs a lot more attention.
Very good post.Really looking forward to read more. Will read on
I truly appreciate this blog article.Much thanks again. Really Cool.
it for him lol. So let me reword this. Thanks for the meal!!
This is a topic that is close to my heart Cheers! Where are your contact details though?
I really liked your article.Much thanks again. Really Cool.
Really appreciate you sharing this article.Really thank you! Fantastic.
This particular blog is obviously educating and also factual. I have found many helpful things out of this amazing blog. I ad love to go back every once in a while. Thanks a bunch!
I really liked your post.Really looking forward to read more. Much obliged.
This can be a set of phrases, not an essay. that you are incompetent
Saved as a favorite, I really like your website!
Some really select content on this site, saved to my bookmarks.
It as nearly impossible to find experienced people about this topic, however, you sound like you know what you are talking about! Thanks
What are the laws as to using company logos in blog posts?
What type of digicam was used? That is definitely a really good good quality.
You made some clear points there. I looked on the internet for the subject matter and found most guys will agree with your blog.
Thanks for sharing, this is a fantastic post.Really thank you! Cool.
That is a great tip especially to those fresh to the blogosphere. Simple but very accurate information Thanks for sharing this one. A must read post!
Thanks for taking the time to talk about this, I feel fervently about this and I take pleasure in learning about this topic. Please, as you gain
My brother recommended I might like this blog. He was entirely right. This post actually made my day. You cann at imagine just how much time I had spent for this information! Thanks!
Lovely blog! I am loving it!! Will come back again. I am taking your feeds also
J0Ls5c I really liked your article. Really Cool.
I think this is a real great blog post.Thanks Again. Fantastic. ventolin
Say, you got a nice article post.Much thanks again. Will read on
Spot on with this write-up, I really think this amazing site needs much
I value the blog post.Thanks Again. Fantastic.
There as noticeably a bundle to find out about this. I assume you made sure nice factors in options also.
that may be the finish of this write-up. Here you
Really informative blog.Thanks Again. Great.
I savour, cause I discovered exactly what I was taking a look for. You ave ended my four day long hunt! God Bless you man. Have a nice day. Bye
Lovely website! I am loving it!! Will come back again. I am taking your feeds also.
Im no professional, but I think you just made the best point. You obviously comprehend what youre talking about, and I can definitely get behind that. Thanks for staying so upfront and so truthful.
You are my inspiration , I have few blogs and occasionally run out from to brand.
Very informative article post.Really thank you! Fantastic.
Say, you got a nice blog post.Much thanks again. Really Cool.
It as best to participate in a contest for the most effective blogs on the web. I all recommend this site!
Pretty! This has been an extremely wonderful article. Thank you for supplying these details.
What a funny blog! I actually loved watching this humorous video with my relatives as well as with my colleagues.
This is very interesting, You are a very skilled blogger. I have joined your feed and look forward to seeking more of your magnificent post. Also, I ave shared your website in my social networks!
Wow, wonderful blog structure! How lengthy have you ever been blogging for? you made blogging look easy. The total glance of your website is great, let alone the content material!
I was reading through some of your content on this internet site and I believe this web site is very informative ! Continue posting.
You made a number of good points there. I did a search on the matter and found nearly all people will agree with your blog.
Im thankful for the article.Much thanks again. Want more.
Thank you, I ave just been looking for info about this subject for ages and yours is the greatest I have discovered so far. But, what about the conclusion? Are you sure about the source?
This very blog is without a doubt entertaining as well as amusing. I have picked up many helpful advices out of this amazing blog. I ad love to go back again soon. Thanks!