5,545,925 members and growing! (17,482 online)
Email Password   helpLost your password?
Web Development » Web Services » General     Intermediate License: The Code Project Open License (CPOL)

SOAP Relay Proxy

By Michael B. Hansen

Bypass firewall content restrictions by wrapping SOAP messages as ordinary HTTP Post with 1 line of code
C# 1.0, C# 2.0, C#, Windows, .NET, .NET 1.1, .NET 2.0, ASP.NET, VS.NET2003, VS2005, Visual Studio, Dev

Posted: 5 Mar 2007
Updated: 19 Dec 2007
Views: 15,197
Bookmarked: 10 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
5 votes for this Article.
Popularity: 2.51 Rating: 3.59 out of 5
1 vote, 20.0%
1
0 votes, 0.0%
2
1 vote, 20.0%
3
0 votes, 0.0%
4
3 votes, 60.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

Visual Studio makes programming webservices a breeze. However, if you as me offer programs for download that uses webservices you will notice that various content filtering devices like firewalls and proxy servers sometimes block the webservice calls. Ordinary HTTP traffic is almost always allowed, but some firewalls and proxy servers are (mis)configured to block various content-types - in regards to webservices, the content-type "text/xml".

This article describes an easy, 1 line solution how to bypass content-filtering blockages of SOAP messages.

Background

When you develop systems to the business and/or consumer market - it is imperative that the system works without the need for the user to take special actions in order to get the system to work. As a developer of server based shareware that communicate through the use of webservice calls to a centralized database - I sometimes got comments from users that couldn't get the system to work. During the installation I already tested whether or not HTTP communication was allowed - but this was shown to be inadequate. One could have switched to another communication protocol than SOAP - but then the strongly typed interfaces would disappear. As ordinary HTTP communication is almost always allowed, I needed to find a way to make SOAP messages appear as ordinary HTTP traffic to bypass the content filtering mechanisms.

The solution I chose was to use the Pluggable Protocol interface found in the System.Net namespace.

Through the use of Reflector and Ethereal I got a pretty clear picture of how webservice calls are done in the .NET framework - however, it was this Microsoft article that gave me the idea for the solution.

The article How To Write Pluggable Protocol to Support FTP in Managed Classes by Using Visual C# .NET describes how you can create your own webprotocol. The idea behind this is to wrap the logic needed to support a given protocol in a black box - and let the higher levels of the system communicate indifferent of the actual protocol used.

Design of SOAP Relay Protocol

The protocol designed takes a SOAP request, encodes it as an ordinary HTTP Post as if it was a standard HTML form that was posted. The content is sent to a proxy page located in the DMZ - which then unwraps the message and relays the message to the desired end-point. Empirical tests has shown that encoding isn't necessary for the SOAP response why it is returned in raw form.

The following 3 properties have been identified as necessary for the protocol to work:

Url of the webservice to call
The SOAP body
SOAPAction

Using the code

To use the code, include the code and register the protocol prefix in the framework and the location of the proxy page which you have put on a server in the DMZ.

...
WebRequest.RegisterPrefix("SOAPPROXY:",
  new ZinoLib.Net.SOAP.SOAPRelayProxyCreator("http://myserver/soaprelayproxy.aspx");
...

Whereever you want to relay SOAP calls through the proxy, just replace "HTTP:" with the protocol prefix "SOAPPROXY:"

using( MyWebservice.TestWebService websvc = new MyWebservice.TestWebService() )
{
   bool cont = true;
   bool usesSoapProxy = false;
   websvc.Url = "HTTP://myserver2/MyWebservice.asmx";
   while( cont )
   {
      try
      {
         return websvc.TestMethod("string1", "string2");
      }
      catch(Exception e)
      {
         //Oh my god - our webservice request failed 
         //- let's try the SOAP proxy instead and resubmit the request
         if( !usesSoapProxy )
         {
            websvc.Url = websrv.Url.Replace("HTTP:", "SOAPPROXY:");
            usesSoapProxy = true;
         }
         else
            cont = false;
      }
   }
}

The code presented in this article has support for both .NET framework 1.1 and .NET framework 2.0 - but because of changes to the HttpWebRequest interface, remember to define the "Conditional Compilation Constant" NET20 if you are going to use it with .NET framework 2.0.

Points of Interest

The SOAP Relay Protocol encodes the destination url, the SOAPACTION header and the actual SOAP body as HEX in order to send it as a payload in a standard HTTP Post. Because of the use of HEX, the request will double in size.

If you log the IP address on the destination url, please be aware that this will be that of the proxy page and not the source client.

The framework for the SOAP Relay Protocol is derived from the source code presented in the Microsoft article How To Write Pluggable Protocol to Support FTP in Managed Classes by Using Visual C# .NET but has been modified quite a bit.

One hurdle was how to create a HttpWebRequest from scratch. Paulo Morgado shows how to do this in his article HTTP compression in the .NET Framework 1.1 - and based on his ideas I have made some small modifications in order to make it fit the SOAP Relay Protocol.

The real "magic" is done in the class ProxyWebRequest. It is derived from HttpWebRequest and maintain a MemoryStream (embedded as the class ProxyStream) to which the SOAP request is written by the .NET framework. The SOAP request is encoded and sent when the .NET framework calls GetRequestStream() which encodes the request, sends it, and returns the response back to the .NET framework.

License

You are free to use this code in any way you wish - both in freeware and commercial programs - free of charge. A small link in an About box etc. will be appreciated - but it is not required.

History

  • 2007-03-06: Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Michael B. Hansen


I hold a Bsc in computer science, organizational theory and economics, and work as lead developer on SPAMfighter Exchange Module in SPAMfighter, Europe's leading Anti Spam Filter developer.
Occupation: Systems Engineer
Location: Denmark Denmark

Other popular Web Services articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 9 of 9 (Total in Forum: 9) (Refresh)FirstPrevNext
Subject  Author Date 
Generalim having problems installing thismemberSwelborn18:06 7 Jan '08  
GeneralRe: im having problems installing thismemberMichael B. Hansen21:20 7 Jan '08  
QuestionDMZmember12:14 6 Mar '07  
AnswerRe: DMZmemberMichael B. Hansen20:30 6 Mar '07  
GeneralHey,memberBradml23:23 5 Mar '07  
GeneralRe: Hey,memberMichael B. Hansen23:43 5 Mar '07  
GeneralRe: Hey,memberBradml23:54 5 Mar '07  
GeneralRe: Hey,memberMichael B. Hansen0:15 6 Mar '07  
GeneralRe: Hey,memberBradml0:24 6 Mar '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 19 Dec 2007
Editor:
Copyright 2007 by Michael B. Hansen
Everything else Copyright © CodeProject, 1999-2008
Web13 | Advertise on the Code Project