using System;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Text;
using Microsoft.Uddi;
using Microsoft.Uddi.Authentication;
using Microsoft.Uddi.VersionSupport;
namespace Microsoft.Uddi.Web
{
///
/// UddiWebResponse allows us to return our own Stream object.
///
internal class UddiWebResponse : WebResponse
{
private WebResponse innerWebResponse;
private UddiResponseStream uddiResponseStream;
private UddiVersion uddiVersion;
///
/// Constructor
///
/// This object should come from the WebResponse created by HttpSoapClientProtocol.
public UddiWebResponse( WebResponse innerWebResponse )
{
this.innerWebResponse = innerWebResponse;
this.uddiVersion = uddiVersion;
}
///
/// Return our response stream (UddiResponseStream) instead of the Stream associated with our inner response.
///
///
public override Stream GetResponseStream()
{
if( null == uddiResponseStream )
{
uddiResponseStream = new UddiResponseStream( innerWebResponse.GetResponseStream() );
}
return uddiResponseStream;
}
///
/// Delegates to the inner web response.
///
public override void Close()
{
innerWebResponse.Close();
}
///
/// Delegates to the inner web response.
///
public override long ContentLength
{
get { return innerWebResponse.ContentLength; }
set { innerWebResponse.ContentLength = value; }
}
///
/// Delegates to the inner web response.
///
public override string ContentType
{
get { return innerWebResponse.ContentType; }
set { innerWebResponse.ContentType = value; }
}
///
/// Delegates to the inner web response.
///
public override Uri ResponseUri
{
get { return innerWebResponse.ResponseUri; }
}
///
/// Delegates to the inner web response.
///
public override WebHeaderCollection Headers
{
get { return innerWebResponse.Headers; }
}
}
///
/// UddiResponseStream allows us to manipulate the XML sent back from the web service.
///
internal class UddiResponseStream : MemoryStream
{
//
// TODO: at some point it may be necessary to pass in the current version as a parameter if the transforms become
// more complicated.
//
///
/// Constructor. We read all the XML sent from the server, do our version manipulation, then write the new XML
/// into our inner responseStream object.
///
/// This object should be the responseStream from a WebResponse object.
public UddiResponseStream( Stream responseStream )
{
try
{
//
// Get the XML the server sent to us.
//
StreamReader reader = new StreamReader( responseStream );
string responseXml = reader.ReadToEnd();
reader.Close();
//
// TODO: Consider making this class more generic, ie. have a IUddiResponseHandler interface:
// IUddiResponseHandler
// string HandleResponse( string xml );
//
//
// Translate the incoming XML into the current version.
//
string transformedXml = UddiVersionSupport.Translate( responseXml, UddiVersionSupport.CurrentVersion );
//
// Write this transformed XML into the 'real' stream.
//
StreamUtility.WriteStringToStream( this, transformedXml );
}
finally
{
this.Position = 0;
}
}
}
///
/// UddiWebRequest allows us to return our own request and response objects.
///
internal class UddiWebRequest : WebRequest
{
private WebRequest innerWebRequest;
private UddiRequestStream uddiRequestStream;
private UddiWebResponse uddiWebResponse;
private UddiVersion uddiVersion;
///
/// Constructor
///
/// Uri to the web service we are calling
/// Uddi version to use for requests
public UddiWebRequest( WebRequest innerWebRequest, UddiVersion uddiVersion )
{
this.innerWebRequest = innerWebRequest;
this.uddiVersion = uddiVersion;
}
///
/// Return a UddiRequestStream object instead of the default one.
///
/// UddiRequestStream object
public override Stream GetRequestStream()
{
if( null == uddiRequestStream )
{
uddiRequestStream = new UddiRequestStream( innerWebRequest.GetRequestStream(), uddiVersion );
}
return uddiRequestStream;
}
///
/// Return a UddiWebRequest object instead of the default one.
///
/// UddiWebResponse object
public override WebResponse GetResponse()
{
if( null == uddiWebResponse )
{
uddiWebResponse = new UddiWebResponse( innerWebRequest.GetResponse() );
}
return uddiWebResponse;
}
///
/// Delegates to our inner WebRequest
///
public override string Method
{
get { return innerWebRequest.Method; }
set { innerWebRequest.Method = value; }
}
///
/// Delegates to our inner WebRequest
///
public override Uri RequestUri
{
get { return innerWebRequest.RequestUri; }
}
///
/// Delegates to our inner WebRequest
///
public override string ConnectionGroupName
{
get { return innerWebRequest.ConnectionGroupName; }
set { innerWebRequest.ConnectionGroupName = value; }
}
///
/// Delegates to our inner WebRequest
///
public override WebHeaderCollection Headers
{
get { return innerWebRequest.Headers; }
set { innerWebRequest.Headers = value; }
}
///
/// Delegates to our inner WebRequest
///
public override long ContentLength
{
get { return innerWebRequest.ContentLength; }
set { innerWebRequest.ContentLength = value; }
}
///
/// Delegates to our inner WebRequest
///
public override string ContentType
{
get { return innerWebRequest.ContentType; }
set { innerWebRequest.ContentType = value; }
}
///
/// Delegates to our inner WebRequest
///
public override ICredentials Credentials
{
get { return innerWebRequest.Credentials; }
set { innerWebRequest.Credentials = value; }
}
///
/// Delegates to our inner WebRequest
///
public override IWebProxy Proxy
{
get { return innerWebRequest.Proxy; }
set { innerWebRequest.Proxy = value; }
}
///
/// Delegates to our inner WebRequest
///
public override bool PreAuthenticate
{
get { return innerWebRequest.PreAuthenticate; }
set { innerWebRequest.PreAuthenticate = value; }
}
///
/// Delegates to our inner WebRequest
///
public override int Timeout
{
get { return innerWebRequest.Timeout; }
set { innerWebRequest.Timeout = value; }
}
///
/// Delegates to our inner WebRequest
///
public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
{
return innerWebRequest.BeginGetResponse( callback, state );
}
///
/// Delegates to our inner WebRequest
///
public override WebResponse EndGetResponse(IAsyncResult asyncResult)
{
return innerWebRequest.EndGetResponse( asyncResult );
}
///
/// Delegates to our inner WebRequest
///
public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, Object state)
{
return innerWebRequest.BeginGetRequestStream( callback, state );
}
///
/// Delegates to our inner WebRequest
///
public override Stream EndGetRequestStream(IAsyncResult asyncResult)
{
return innerWebRequest.EndGetRequestStream( asyncResult );
}
///
/// Delegates to our inner WebRequest
///
public override void Abort()
{
innerWebRequest.Abort();
}
}
///
/// UddiRequestStream allows us to manipulate the XML before we send it to the client. This class will accept all data that
/// is written to it from the ASP.NET web service framework. When the framework closes the stream (ie. wants to send the data), we
/// will manipulate this XML so that it has the right Uddi version, then send it out using our innerStream object.
///
internal class UddiRequestStream : MemoryStream
{
private Stream innerStream;
private UddiVersion uddiVersion;
///
/// Constructor
///
/// Should be from a WebRequest object.
/// The UDD version we should use to send to the server
public UddiRequestStream( Stream innerStream, UddiVersion uddiVersion )
{
this.innerStream = innerStream;
this.uddiVersion = uddiVersion;
}
///
/// Before we actually close the request stream, we want to manipulate the XML.
///
public override void Close()
{
try
{
//
// Rewind ourselves.
//
this.Position = 0;
//
// Read the XML that was written; this is the XML request that will be sent to the Uddi server.
//
StreamReader reader = new StreamReader( this );
string requestXml = reader.ReadToEnd();
//
// TODO: Consider making this class more generic, ie. have a IUddiRequestHandler interface:
// IUddiResponseHandler
// string HandleRequest( string xml );
//
//
// Transform the content to a correct version on the server if we are not using the current version.
//
string transformedXml = requestXml;
if( uddiVersion != UddiVersionSupport.CurrentVersion )
{
transformedXml = UddiVersionSupport.Translate( requestXml, uddiVersion );
}
//
// Write the transformed data to the 'real' stream.
//
StreamUtility.WriteStringToStream( innerStream, transformedXml );
}
finally
{
//
// Make sure we clean up properly.
//
innerStream.Close();
base.Close();
}
}
}
///
/// Simple utility class to help us write string data to Stream objects.
///
internal sealed class StreamUtility
{
public static void WriteStringToStream( Stream stream, string stringToWrite )
{
for ( int i = 0; i < stringToWrite.Length; i++ )
{
stream.WriteByte( Convert.ToByte( stringToWrite[ i ] ) );
}
}
private StreamUtility()
{
//
// Don't let anyone instantiate this class
//
}
}
}