tsJensen

A quest for software excellence...

HttpWebRequest, ServicePoint and BindIPEndPointDelegate

I've spent months fighting with 3rd party components and my own hand rolled code that would allow me to achieve essentially the same thing you can with the HttpWebRequest class with one additional feature: binding a specific end point (IP address) to the object so that a remote server would recognize the call as coming from that specific IP address.

I looked through the description of each of the HttpWebRequest's members in the MSDN documentation. I searched the internet high and low. I banged my head against buggy third party components. And in desperation attempted to roll my own. All efforts resulted in a thorougly disappointing result.

Bring on the Delegates

Two days ago, I was chatting with a friend and I expressed my desperation. I told him I'd drive to his house and give him a fifty dollar bill if he could tell me how to use the HttpWebRequest object and assign or "bind" the local IP. He started digging. And I tried one last Google search using HttpWebRequest and IPEndPoint, I think it was, in the search. And I found this little gem about 5 seconds before my friend suggested taking a look at the HttpWebRequest's ServicePoint member and the ServicePoint's BindIPEndPointDelegate member.

Glory Hallelujah!

One of my new best friends is someone I don't know: Malar Chinnusamy. Thanks a million, Malar.

So to the point of the title of this little rant. It is the delegate stupid. The lesson learned is when you can't figure out how to do something with the .NET Framework, check out the delegates. And the delegates of the object's members. And so on...

public delegate IPEndPoint BindIPEndPoint(ServicePoint servicePoint,
  IPEndPoint remoteEndPoint, int retryCount);

That little gem is a beautiful thing. It lead to this:

private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint,
  IPEndPoint remoteEndPoint, int retryCount)
{
    if(retryCount < 3)
        return new IPEndPoint(IPAddress.Parse("192.168.10.60"), 0);
    else
        return new IPEndPoint(IPAddress.Any, 0);
}

and...

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.ServicePoint.BindIPEndPointDelegate =
  new BindIPEndPoint(BindIPEndPointCallback);

I told my friend that I wish I knew and understood everything in the framework. He said that he wished I knew it all too. So, when there's a shortage of helps and great blog posts out there, don't give up. Follow the delegates and you won't look as stupid as I felt once I found my new friend's post.