Click here to Skip to main content
11,640,445 members (63,234 online)
Click here to Skip to main content
Add your own
alternative version

Secure Web Services via TCP/IP

, 30 May 2003 158.7K 5.2K 89
Describes an approach for delivery of Soap Messages serialised using ASP.NET Web Client Services over TCP/IP
wsaltroute2.zip
ArgosAPIExtensions
Bin
Client
ArgosAPIExtensions.dll
WSAltRouteTest.exe
WSIPTransports.dll
Server
WebServices
WSAltRouteArgos
bin
ArgosAPIExtensions.dll
ArgosAPIExtensions.pdb
WSAltRouteArgos.dll
WSAltRouteArgos.pdb
Global.asax
WSAltRouteArgos.csproj.webinfo
WSAltRouteArgos.vsdisco
WSAltRouteBEFake.exe
WSAltRouteTest
App.ico
Web References
ArgosTrinketService
Reference.map
Service1.disco
Service1.wsdl
WSAltRouteBEFake
App.ico
WSAltTransports2
WSQTransports.dll
AsyncHelper.dll
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Web.Services.Protocols;


namespace WSAltTransports
{

	/// <summary>WSAltTransports.QueueTransportErrors</summary>
    /// <remarks>
    /// This enumeration is used in the case where a WebException of status
    /// ProtocolError has occured  - in this case we need to provide some
    /// extra information for the caller to react to.  The stub is left here
    /// for now, and the only type of error we can't map into something sensible
    /// is an unexpected one.
    /// </remarks>
	/// <values>
	/// 		UnexpectedFailure : An error not specifically covered as a Send,
	/// 							Receive, Timeout, Name Resolution error.
	/// </values>
    public enum QueueTransportErrors
	{
		UnexpectedFailure = 500
	}

	/// <summary>WSAltTransports.MySoapStream</summary>
    /// <author>Simon G</author>
    /// <date>18 February 2003</date>
    /// <remarks>
    /// Derived Stream to handle the delaying of the stream Close(),
    /// and subsequent InternalClose() which really does close the stream.
    /// </remarks>
    public class MySoapStream : Stream 
	{
		private Stream m_Stream;

		internal MySoapStream() 
		{
			m_Stream = null;
		}

		internal MySoapStream(
			Stream stream, 
			bool canread, 
			bool canwrite, 
			bool canseek) 
		{
			m_Stream = stream;
		}


		// Impementations of Inherited abstract members
		// Unfortunately we have to define all of the possible methods and properties,
		// even though 98% of them simply passthrough to the aggregated stream object

		public override bool CanRead 
		{
			get { return m_Stream.CanRead; }
		}


		public override bool CanWrite 
		{
			get { return m_Stream.CanWrite; }
		}


		public override bool CanSeek 
		{
			get { return m_Stream.CanSeek; }
		}


		public override long Length
		{
			get 
			{
				return m_Stream.Length;
			}
		}


		public override long Position 
		{
			get 
			{
				return m_Stream.Position;
			}
			set 
			{
				m_Stream.Position = value;
			}
		}


		public override long Seek(
			long offset, 
			SeekOrigin origin) 
		{
			return m_Stream.Seek(offset, origin);
		}


		public override void Flush() 
		{
			m_Stream.Flush();
		}


		public override void
			SetLength(long value) 
		{
			m_Stream.SetLength(value);
		}
        

		public override void Write(
			Byte [] buffer, 
			int offset, 
			int length) 
		{
			m_Stream.Write(buffer,offset,length);
		}


		public override int Read(
			Byte [] buffer, 
			int offset, 
			int length) 
		{
			return m_Stream.Read(buffer,offset,length);
		}

	

		/// <summary>WSAltTransports.MySoapStream.Close</summary>
        /// <author>Simon G</author>
        /// <date>18 February 2003</date>
        /// <remarks>Supress the actual close of the underlying stream</remarks>
        /// <preconditions>Valid open, seekable Stream exists</preconditions>
        /// <postconditions>Underlying stream is rewound</postconditions>
        public override void Close() 
		{
			// DON'T CLOSE! BUT REWIND!
			m_Stream.Position = 0;
		}


		// Our new Close method, which should be called explicitely by
		// our pluggable protocol framework
		
		
		/// <summary>WSAltTransports.MySoapStream.InternalClose</summary>
        /// <author>Simon G</author>
        /// <date>18 February 2003</date>
        /// <remarks>Do the actual close of the underlying stream</remarks>
        /// <preconditions>Valid open Stream exists</preconditions>
        /// <postconditions>Underlying stream is closed</postconditions>
        internal void InternalClose() 
		{
			// If the Stream needs closing do so...this is best assessed
			// using the CanSeek property, knowing that an open MySoapStream
			// is always seekable
			if (this.CanSeek == true)
				m_Stream.Close();
		}
	}


	/// <summary>WSAltTransports.MyBaseWebRequest</summary>
    /// <author>SGregory</author>
    /// <date>16 January 2003</date>
    /// <remarks>Encapsulates the request processing common to MQ and MSMQ implementations</remarks>
    public abstract class MyBaseWebRequest : WebRequest
	{
		// Public exposure of response Uri
		public Uri ResponseUri
		{
			get
			{
				return m_ResponseUri;
			}
			set
			{
				// Safety value in case we ever get here for an http request which should not happen
				if (m_RequestUri.AbsoluteUri.ToLower().IndexOf("http") == 0)
					throw new NotSupportedException("ResponseUri may not be used for http transports.");
				m_ResponseUri = value;
			}
		}


		// Abstract custom methods

		// Force MQ and MSMQ implementations to derive a default response Queue name
		// from the supplied request name
		protected abstract void SetResponseUriFromRequestUri(Uri requestUri);


		// Overriden methods / properties of WebRequest


		public override WebHeaderCollection Headers
		{
			get
			{
				// Return an empty header collection to the infrastructure
				return new WebHeaderCollection();
			}
			set
			{
				base.Headers = value;
			}
		}

		public override String Method
		{
			get 
			{
				return m_szMethod;
			}
			set 
			{
				// Check see if method is supported
				m_szMethod=value;
			}
		}

		public override bool PreAuthenticate
		{
			/* override */ get { return false; }
			/* override */ set { /* reserved for future use */ }
		}

		public override ICredentials Credentials 
		{
			/* override */ get { return null; }
			/* override */ set { /* reserved for future use */ }
		}

		public override string ConnectionGroupName 
		{
			/* override */ get { return string.Empty; }
			/* override */ set { /* reserved for future use */ }
		}

		public  override long ContentLength 
		{
			/* override */ get { return m_lngContentLength; }
			/* override */ set { m_lngContentLength = value; }
		}

		public  override string ContentType 
		{
			/* override */ get { return m_szContentType; }
			/* override */ set { m_szContentType = value; }
		}

		public  override int Timeout
		{
			/* override */ get { return m_intTimeout; }
			/* override */ set { m_intTimeout = value; }
		}
	
		public override IWebProxy Proxy 
		{
			/* override */ get { throw new NotSupportedException(); }
			/* override */ set { throw new NotSupportedException(); }
		}


		/// <summary>WSAltTransports.MyBaseWebRequest.GetRequestStream</summary>
        /// <author>SGregory</author>
        /// <date>16 January 2003</date>
        /// <remarks>
        /// Creates a new stream when called by the infrastructure,
        /// which places the serialised Soap stram into it
        /// </remarks>
        /// <returns type="System.IO.Stream">Stream to return</returns>
        /// <preconditions>Stream not already set (can only be done once per request)</preconditions>
        /// <postconditions>Stream data memeber initialised</postconditions>
        public override Stream GetRequestStream()
		{	
			if (m_RequestStream == null)
				m_RequestStream = new MySoapStream(new MemoryStream(), true, true, true);	
			else
				throw new InvalidOperationException("Request stream already retrieved.");

			return m_RequestStream;		
		}


		/// <summary>WSAltTransports.MyBaseWebRequest.GetResponse</summary>
        /// <author>SGregory</author>
        /// <date>16 January 2003</date>
        /// <remarks>
        /// This normally initiates the communciations protocol.
        /// This one should never actually execute as the MQ or MSMQ derived version should be running.
        /// </remarks>
        /// <returns type="System.Net.WebResponse">N/a - see derived class</returns>
        public override WebResponse GetResponse() 
		{
			throw new ApplicationException("Should be calling a derived classes GetResponse!");
		}


		// Private member data
		protected MySoapStream			m_RequestStream;		// Request stream

		protected long					m_lngContentLength;		// Message length
		protected string				m_szContentType;		// e.g. text/xml
		protected int					m_intTimeout = 5000;	// Timeout

		protected Uri					m_RequestUri;			// URI endpoint
		protected Uri					m_ResponseUri = null;	// URI endpoint for response
		protected bool					m_ResponseRequired = true;	// Do we even want a response?
	
		protected string				m_szMethod;				// Method (for HTTP style calls)
	}


	/// <summary>WSAltTransports.MyBaseWebResponse</summary>
    /// <author>Simon G</author>
    /// <date>18 February 2003</date>
    /// <remarks>Encapsulates the response processing common to MQ and MSMQ implementations</remarks>
    public class MyBaseWebResponse : WebResponse
	{
		/// <summary>WSAltTransports.MyBaseWebResponse.MyBaseWebResponse</summary>
        /// <author>Simon G</author>
        /// <date>24 February 2003</date>
        /// <remarks>Default constructor - this sets up a "good" response</remarks>
        internal MyBaseWebResponse()
		{
			m_lngContentLength = 0;
			m_strContentType = "text/xml";
			m_intStatusCode = -1;
			m_strStatusDescription = null;
			m_ResponseStream = null;
			m_strLog = null;
		}
	

		/// <summary>WSAltTransports.MyBaseWebResponse.SetErrorInformation</summary>
        /// <author>Simon G</author>
        /// <date>24 February 2003</date>
        /// <remarks>Allows setup of error information</remarks>
        /// <param name="vintStatusCode" type="int">WebResponse Code e.g. 500</param>
        /// <param name="vstrStatusDescription" type="string">WebResponse Error description</param>
        /// <param name="vstrLog" type="string">Associated stack trace or similar</param>
        /// <postconditions>Error information set up</postconditions>
        internal void SetErrorInformation(
			int vintStatusCode, 
			string vstrStatusDescription, 
			string vstrLog)
		{
			// Store the passed values
			m_intStatusCode = vintStatusCode;
			m_strStatusDescription = vstrStatusDescription;
			m_strLog = vstrLog;

			// Explicitely indicate no response stream is available
			m_ResponseStream = Stream.Null;
		}


		// Overriden methods / properties of WebRequest


		public override WebHeaderCollection Headers
		{
			get
			{
				return new WebHeaderCollection();
			}
		}	

		public override long ContentLength
		{
			get	{ return m_lngContentLength; } 
			set { throw new NotSupportedException("This property cannot be set"); }
		}
	
		public override String ContentType 
		{
			get	{ return m_strContentType; } 
			set { throw new NotSupportedException("This property cannot be set"); }
		}
	
		public override Stream GetResponseStream()
		{
			if(m_ResponseStream == null)
				throw new ApplicationException("No response stream for this kind of method");

			return m_ResponseStream;	
		}	
	
		public int Status	
		{
			get { return m_intStatusCode; }
		}	
	
		public String StatusDescription 
		{
			get 
			{ 
				return m_strStatusDescription;
			}
		}	


		/// <summary>WSAltTransports.MyBaseWebResponse.SetDownloadStream</summary>
        /// <author>Simon G</author>
        /// <date>24 February 2003</date>
        /// <remarks>Sets up the response stream </remarks>
        /// <param name="vobjResponseStream" type="System.IO.Stream"></param>
        /// <preconditions>Response stream parameter represents a valid derived stream instance</preconditions>
        /// <postconditions>Stream is stored and other member data set up</postconditions>
        internal void SetDownloadStream(
			Stream vobjResponseStream)
		{
			// Store the stream reference
			m_ResponseStream = vobjResponseStream;		

			// Rewind the stream
			m_ResponseStream.Position = 0;

			// Record the size of the stream
			m_lngContentLength = m_ResponseStream.Length;
		}


		// Private data members
		private long	m_lngContentLength;		// Message length
		private string  m_strContentType;		// e.g. text/xml

		private int 	m_intStatusCode;		// WebResponse status code
		private String 	m_strStatusDescription;	// WebResponse status description
		private String  m_strLog;				// WebResponse status trace

		private Stream 	m_ResponseStream;		// Response stream
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Simon Gregory
Web Developer
United Kingdom United Kingdom
I am the Technical Director for Myphones.com, which specialises in developing integrated VoIP products and services for the consumer and SME markets. Technology-wise, we are heavily into the 2nd generation WS stack atop .NET, and basically most things Microsoft, as well as C++ on Linux.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150731.1 | Last Updated 31 May 2003
Article Copyright 2003 by Simon Gregory
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid