e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
356 lines
12 KiB
C#
356 lines
12 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
namespace System.ServiceModel.Channels
|
|
{
|
|
using System.Globalization;
|
|
using System.Net;
|
|
using System.ServiceModel;
|
|
using System.Text;
|
|
|
|
static class MsmqUri
|
|
{
|
|
static IAddressTranslator netMsmqAddressTranslator;
|
|
static IAddressTranslator activeDirectoryAddressTranslator;
|
|
static IAddressTranslator deadLetterQueueAddressTranslator;
|
|
static IAddressTranslator srmpAddressTranslator;
|
|
static IAddressTranslator srmpsAddressTranslator;
|
|
static IAddressTranslator formatnameAddressTranslator;
|
|
|
|
public static IAddressTranslator NetMsmqAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == netMsmqAddressTranslator)
|
|
netMsmqAddressTranslator = new MsmqUri.NetMsmq();
|
|
return netMsmqAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static IAddressTranslator ActiveDirectoryAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == activeDirectoryAddressTranslator)
|
|
activeDirectoryAddressTranslator = new MsmqUri.ActiveDirectory();
|
|
return activeDirectoryAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static IAddressTranslator DeadLetterQueueAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == deadLetterQueueAddressTranslator)
|
|
deadLetterQueueAddressTranslator = new MsmqUri.Dlq();
|
|
return deadLetterQueueAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static IAddressTranslator SrmpAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == srmpAddressTranslator)
|
|
srmpAddressTranslator = new MsmqUri.Srmp();
|
|
return srmpAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static IAddressTranslator SrmpsAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == srmpsAddressTranslator)
|
|
srmpsAddressTranslator = new MsmqUri.SrmpSecure();
|
|
return srmpsAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static IAddressTranslator FormatNameAddressTranslator
|
|
{
|
|
get
|
|
{
|
|
if (null == formatnameAddressTranslator)
|
|
formatnameAddressTranslator = new MsmqUri.FormatName();
|
|
return formatnameAddressTranslator;
|
|
}
|
|
}
|
|
|
|
public static string UriToFormatNameByScheme(Uri uri)
|
|
{
|
|
if (uri.Scheme == NetMsmqAddressTranslator.Scheme)
|
|
{
|
|
return NetMsmqAddressTranslator.UriToFormatName(uri);
|
|
}
|
|
else if (uri.Scheme == FormatNameAddressTranslator.Scheme)
|
|
{
|
|
return FormatNameAddressTranslator.UriToFormatName(uri);
|
|
}
|
|
else
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("uri");
|
|
}
|
|
}
|
|
|
|
static void AppendQueueName(StringBuilder builder, string relativePath, string slash)
|
|
{
|
|
const string privatePart = "/private";
|
|
|
|
if (relativePath.StartsWith("/private$", StringComparison.OrdinalIgnoreCase))
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqWrongPrivateQueueSyntax)));
|
|
|
|
if (relativePath.StartsWith(privatePart, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
if (privatePart.Length == relativePath.Length)
|
|
{
|
|
builder.Append("private$");
|
|
builder.Append(slash);
|
|
relativePath = "/";
|
|
}
|
|
else if ('/' == relativePath[privatePart.Length])
|
|
{
|
|
builder.Append("private$");
|
|
builder.Append(slash);
|
|
relativePath = relativePath.Substring(privatePart.Length);
|
|
}
|
|
}
|
|
builder.Append(relativePath.Substring(1));
|
|
}
|
|
|
|
internal interface IAddressTranslator
|
|
{
|
|
string Scheme { get; }
|
|
string UriToFormatName(Uri uri);
|
|
Uri CreateUri(string host, string name, bool isPrivate);
|
|
}
|
|
|
|
class NetMsmq : IAddressTranslator
|
|
{
|
|
public string Scheme
|
|
{
|
|
get { return "net.msmq"; }
|
|
}
|
|
|
|
public string UriToFormatName(Uri uri)
|
|
{
|
|
if (null == uri)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("uri"));
|
|
if (uri.Scheme != this.Scheme)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidScheme), "uri"));
|
|
if (String.IsNullOrEmpty(uri.Host))
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.MsmqWrongUri));
|
|
if (-1 != uri.Port)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.MsmqUnexpectedPort));
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.Append("DIRECT=");
|
|
if (0 == String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
|
|
builder.Append("OS:.");
|
|
else
|
|
{
|
|
IPAddress address = null;
|
|
if (IPAddress.TryParse(uri.Host, out address))
|
|
builder.Append("TCP:");
|
|
else
|
|
builder.Append("OS:");
|
|
|
|
builder.Append(uri.Host);
|
|
}
|
|
builder.Append("\\");
|
|
MsmqUri.AppendQueueName(builder, Uri.UnescapeDataString(uri.PathAndQuery), "\\");
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
public Uri CreateUri(string host, string name, bool isPrivate)
|
|
{
|
|
string path = "/" + name;
|
|
if (isPrivate)
|
|
{
|
|
path = "/private" + path;
|
|
}
|
|
|
|
return (new UriBuilder(Scheme, host, -1, path)).Uri;
|
|
}
|
|
}
|
|
|
|
class PathName : IAddressTranslator
|
|
{
|
|
public string Scheme
|
|
{
|
|
get { return "net.msmq"; }
|
|
}
|
|
|
|
public virtual string UriToFormatName(Uri uri)
|
|
{
|
|
if (null == uri)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("uri"));
|
|
if (uri.Scheme != this.Scheme)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidScheme), "uri"));
|
|
if (String.IsNullOrEmpty(uri.Host))
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.MsmqWrongUri));
|
|
if (-1 != uri.Port)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.MsmqUnexpectedPort));
|
|
|
|
uri = PostVerify(uri);
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
if (0 == String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
|
|
builder.Append(".");
|
|
else
|
|
builder.Append(uri.Host);
|
|
|
|
builder.Append("\\");
|
|
MsmqUri.AppendQueueName(builder, Uri.UnescapeDataString(uri.PathAndQuery), "\\");
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
public Uri CreateUri(string host, string name, bool isPrivate)
|
|
{
|
|
string path = "/" + name;
|
|
if (isPrivate)
|
|
{
|
|
path = "/private" + path;
|
|
}
|
|
|
|
return (new UriBuilder(Scheme, host, -1, path)).Uri;
|
|
}
|
|
|
|
protected virtual Uri PostVerify(Uri uri)
|
|
{
|
|
return uri;
|
|
}
|
|
}
|
|
|
|
class ActiveDirectory : PathName
|
|
{
|
|
public override string UriToFormatName(Uri uri)
|
|
{
|
|
return MsmqFormatName.FromQueuePath(base.UriToFormatName(uri));
|
|
}
|
|
}
|
|
|
|
class Dlq : PathName
|
|
{
|
|
protected override Uri PostVerify(Uri uri)
|
|
{
|
|
if (0 == String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
|
|
return uri;
|
|
try
|
|
{
|
|
if (0 == String.Compare(DnsCache.MachineName, DnsCache.Resolve(uri).HostName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return new UriBuilder(Scheme, "localhost", -1, uri.PathAndQuery).Uri;
|
|
}
|
|
}
|
|
catch (EndpointNotFoundException ex)
|
|
{
|
|
MsmqDiagnostics.ExpectedException(ex);
|
|
}
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqDLQNotLocal), "uri"));
|
|
}
|
|
}
|
|
|
|
abstract class SrmpBase : IAddressTranslator
|
|
{
|
|
const string msmqPart = "/msmq/";
|
|
|
|
public string Scheme
|
|
{
|
|
get { return "net.msmq"; }
|
|
}
|
|
|
|
public string UriToFormatName(Uri uri)
|
|
{
|
|
if (null == uri)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("uri"));
|
|
if (uri.Scheme != this.Scheme)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidScheme), "uri"));
|
|
if (String.IsNullOrEmpty(uri.Host))
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.MsmqWrongUri));
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.Append("DIRECT=");
|
|
builder.Append(this.DirectScheme);
|
|
builder.Append(uri.Host);
|
|
if (-1 != uri.Port)
|
|
{
|
|
builder.Append(":");
|
|
builder.Append(uri.Port.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
|
|
string relativePath = Uri.UnescapeDataString(uri.PathAndQuery);
|
|
builder.Append(msmqPart);
|
|
MsmqUri.AppendQueueName(builder, relativePath, "/");
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
abstract protected string DirectScheme { get; }
|
|
|
|
public Uri CreateUri(string host, string name, bool isPrivate)
|
|
{
|
|
string path = "/" + name;
|
|
if (isPrivate)
|
|
{
|
|
path = "/private" + path;
|
|
}
|
|
|
|
return (new UriBuilder(Scheme, host, -1, path)).Uri;
|
|
}
|
|
}
|
|
|
|
class Srmp : SrmpBase
|
|
{
|
|
protected override string DirectScheme
|
|
{
|
|
get { return "http://"; }
|
|
}
|
|
}
|
|
|
|
class SrmpSecure : SrmpBase
|
|
{
|
|
protected override string DirectScheme
|
|
{
|
|
get { return "https://"; }
|
|
}
|
|
}
|
|
|
|
class FormatName : IAddressTranslator
|
|
{
|
|
public string Scheme
|
|
{
|
|
get { return "msmq.formatname"; }
|
|
}
|
|
|
|
public string UriToFormatName(Uri uri)
|
|
{
|
|
if (null == uri)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("uri"));
|
|
if (uri.Scheme != this.Scheme)
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidScheme), "uri"));
|
|
return Uri.UnescapeDataString(uri.AbsoluteUri.Substring(this.Scheme.Length + 1));
|
|
}
|
|
|
|
public Uri CreateUri(string host, string name, bool isPrivate)
|
|
{
|
|
string path;
|
|
if (isPrivate)
|
|
{
|
|
path = "PRIVATE$\\" + name;
|
|
}
|
|
else
|
|
{
|
|
path = name;
|
|
}
|
|
|
|
path = "DIRECT=OS:" + host + "\\" + path;
|
|
|
|
return new Uri(Scheme + ":" + path);
|
|
}
|
|
}
|
|
}
|
|
}
|